[
  {
    "path": ".browserslistrc",
    "content": "> 1%\nlast 2 versions\nnot dead\n"
  },
  {
    "path": ".dockerignore",
    "content": "# 依赖\nnode_modules\nnpm-debug.log\nyarn-error.log\nyarn-debug.log\npackage-lock.json\n\n# 构建产物\ndist\nbuild\n\n# 环境变量\n.env.local\n.env.*.local\n\n# IDE\n.vscode\n.idea\n*.swp\n*.swo\n.DS_Store\n\n# Git\n.git\n.gitignore\n.gitattributes\n\n# 文档\nREADME.md\n*.md\n\n# 测试\ncoverage\n.nyc_output\n\n# 其他\n*.log\ntemp\ntmp\n"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\nnode_modules\n/dist\n\n# 闲鱼日志文件\n/logs\n# 闲鱼数据库文件\n/data\n\n\n# local env files - ignore all .env files except .env.example\n.env\n.env.local\n.env.*.local\n.env.development\n.env.production\n.env.test\n\n# Log files\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\npnpm-debug.log*\n\n# Editor directories and files\n.idea\n.vscode\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n*.sw?\n"
  },
  {
    "path": "Dockerfile",
    "content": "# 多阶段构建 - 构建阶段\nFROM node:20-alpine AS builder\n\n# 设置工作目录\nWORKDIR /app\n\n# 安装 yarn\nRUN corepack enable && corepack prepare yarn@stable --activate\n\n# 复制 package.json 和 yarn.lock\nCOPY package.json yarn.lock ./\n\n# 安装依赖\nRUN yarn install --frozen-lockfile\n\n# 复制源代码\nCOPY . .\n\n# 构建生产环境代码\nRUN yarn build\n\n# 生产阶段 - 使用 nginx 托管静态文件\nFROM nginx:alpine\n\n# 复制 nginx 配置\nCOPY nginx.conf /etc/nginx/conf.d/default.conf\n\n# 从构建阶段复制构建产物\nCOPY --from=builder /app/dist /usr/share/nginx/html\n\n# 暴露端口\nEXPOSE 80\n\n# 启动 nginx\nCMD [\"nginx\", \"-g\", \"daemon off;\"]\n"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "<h1 align=\"center\">\n <p>ChattyPlay-Agent</p>\n <a href=\"https://trendshift.io/repositories/20110\" target=\"_blank\"><img src=\"https://trendshift.io/api/badge/repositories/13630\" alt=\"ChattyPlay-Agent | Trendshift\" style=\"width: 250px; height: 55px;\" width=\"250\" height=\"55\"/></a>\n <p>\n  <img alt=\"Github Stargazers\" src=\"https://img.shields.io/github/stars/P1Kaj1uu/ChattyPlay-Agent.svg?label=%e6%98%9f%e6%a0%87&logo=github&logoColor=white&labelColor=black&color=gold&style=for-the-badge&cacheSeconds=10\">\n  <img alt=\"Github Forks\" src=\"https://img.shields.io/github/forks/P1Kaj1uu/ChattyPlay-Agent?label=%e5%a4%8d%e5%88%bb&logo=github&logoColor=white&labelColor=black&color=grey&style=for-the-badge&cacheSeconds=10\">\n   <img alt=\"Github Licence\" src=\"https://img.shields.io/github/license/P1Kaj1uu/ChattyPlay-Agent?label=%e8%ae%b8%e5%8f%af&logo=github&logoColor=white&labelColor=black&color=grey&style=for-the-badge&cacheSeconds=10\">\n  <br />\n  <img src=\"https://img.shields.io/badge/支持平台-Windows_|_Mac_|_Linux_|_iPhone_|_Android-blueviolet.svg?style=for-the-badge\" alt=\"支持平台\">\n </p>\n</h1>\n\n## 📄 免责声明\n\n### 本项目提供音乐、影视解析下载、实时黄金及K线图、动漫漫画、Hugging Face论文、思维导图、闲鱼助手和ChatGPT相关服务，仅供学习使用，请勿用于任何商业用途。如你有更好的想法、建议、或不解的问题，欢迎提PR或Issues！如有侵权，请联系我！\n\n> License：ChattyPlay-Agent is licensed under the Apache-2.0 License. See the [LICENSE](https://github.com/P1kaj1uu/ChattyPlay-Agent/blob/master/LICENSE) file for more information.\n\n> 项目描述参考信息可跳转WiKi：https://github.com/P1kaj1uu/ChattyPlay-Agent/wiki/%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3\n\n> PC端、移动端均已适配\n\n## 🚀 在线体验\n\n- 体验地址：<a href=\"https://chatty-play-agent.vercel.app\" target=\"_blank\">在线体验</a>（需要科学上网工具访问）\n- 视频预览：<a href=\"https://www.bilibili.com/video/BV1DmFYzbEQp/?share_source=copy_web&vd_source=1c9f57ed1dd7f17c0142ea7c34926f1e\" target=\"_blank\">录频视频</a>\n- 备注：如使用ChatGPT服务，我的APIKey配额有限，希望大家能省点用谢谢！\n\n## 📖 版本迭代\n\n- v1.0版本已完成（2023.1.7凌晨）\n- v1.1版本优化观看页面的提示内容（2023.1.7上午）\n- v1.2版本优化解析接口（2023.1.8下午）\n- v1.3版本优化帮助内容页面（2023.1.8下午）\n- v1.4版本优化分离加载爱心跳动效果（2023.1.9上午）\n- v1.5版本增加多个能用的视频解析接口（2023.1.14晚上）\n- v1.6版本禁止F12查看源代码（2023.1.19上午）\n- v1.7版本增加并优化解析视频接口（2023.1.19下午）\n- v1.8版本浏览器兼容判断浏览器类型（2023.1.20晚上）\n- v2.0版本优化页面样式，增加首页听音乐功能（2023.4.22下午）\n- v2.1版本增加论文降重功能（2023.4.30全天）\n- v2.2版本接入ChatGPT服务，可无需再代理和APIkey（2023.5.1-2023.5.3）\n- v2.3版本优化ChatGPT服务，检测自动换行，并支持上下文对话（2023.5.6-2023.5.7）\n- v2.4版本代仓本地的部分接口隐藏不对外开放（2023.5.7晚上）\n- v2.5版本输出代码高亮显示，流式处理EventStream，并支持会话存储（2023.5.13-2023.5.14）\n- v2.6版本接入文心一言基础服务，增加语音聊天、语音朗读功能（2023.5.20-2023.5.21）\n- v2.7版本前端也做限流处理，增加验证功能，防止接口被恶意多次请求（2023.5.24晚上）\n- v2.8版本优化加载效果，增加网站访问次数统计和版本更新提醒用户功能（2023.5.26-2023.5.27）\n- v2.9版本整体优化代码，修复bug，并抽离封装部分函数和组件，降低复杂度，实现高内聚低耦合（2023.6.10-2023.6.20）\n- v3.0全新版本上线，优化markdown代码块格式，并接入文生图、亚马逊爬虫服务，发布浏览器插件（2023.7.24-2023.8.13）\n- v4.0重构项目完成，修改相关的bug，页面结构样式重新设计，增加实时黄金及k线图、动漫漫画和Hugging Face论文功能，优化用户体验，并完成移动端和PC端的适配，添加版本检测弹窗更新功能，接入SDK、MCP、Agent、谷歌和Github授权登录等服务，同时系统整体架构将Vue2替换为React + TypeScript + Hono + Vite + Tailwind CSS + i18n国际化 + live2d看板娘 + nginx + Docker容器化管理（2025.12.16-2026.2.10）\n- v4.1闲鱼助手，可自动回复、自动发货等（2026.2.26-2026.3.7）\n- v4.2思维导图和Markdown格式预览及编辑，导出图片。论文PDF预览及AI问答（2026.3.9-2026.3.11）\n- v4.3解析下载无水印1080P视频（2026.3.13-2026.3.14）\n- v4.4封装浏览器指纹SDK、GIF图片埋点SDK，接入Google Analytics分析工具（2026.3.15-2026.3.16）\n- v4.5优化注册登录功能，jwt token无感刷新token，redis存储用户信息，cloudflare托管vercel（2026.3.22-2026.3.26）\n- v4.6新增hcaptcha防机器人验证码（2026.4.12）\n- v4.7新增cloudflare turnstile防恶意请求和爬虫（2026.4.25-2026.4.27）\n- v4.8新增支付功能（2026.4.28-2026.4.29）\n- v4.9新增Latex编辑功能（2026.5.2-2026.5.8）\n\n## 最新版本V4.9（推荐）\n\n> 本地调试时，可注释掉限制调用控制台的代码。参照说明修改package.json、email.config.js、index.html、.env.development、.env.production和docker-compose.yml文件。\n\n## 🛠️ 系统架构\n\n<img width=\"1345\" height=\"750\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/c52fe4e9-a04c-4712-b635-a7191712cbf4\" />\n<img width=\"1345\" height=\"750\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/30aa8602-e8c0-4e0c-8165-0a4061f39d64\" />\n\n## 🔰 项目概述\n\n✅ 技术栈\n\n- Python + React + TypeScript + Vite + Tailwind CSS + i18n国际化 + live2d看板娘\n- 适配移动端和PC端\n- Three.js 3D 模型加载动画效果\n- MD5加密，验证码，网站访问次数统计\n- Markdown语法解析，highlight代码高亮显示\n- 处理EventStream流\n- 金融基金K线图\n- 实时版本检测更新\n- 限制终端控制台调用\n- 组件库使用Antd\n- 接入fundebug SDK和OPen AI SDK\n- Hugging Face今日论文和热搜论文、预览PDF及对PDF的AI解答\n- 接入MCP、Agent相关服务\n- 接入谷歌和Github授权登录\n- 闲鱼助手，可自动回复、自动发货等\n- 思维导图和Markdown格式预览及编辑，导出图片\n- 解析下载无水印1080P视频\n- 封装浏览器指纹SDK、GIF图片埋点SDK\n- 接入Google Analytics分析工具\n- jwt token无感刷新token\n- redis存储用户信息\n- cloudflare托管vercel\n- hcaptcha防机器人验证码\n- cloudflare turnstile防恶意请求和爬虫\n- 支付宝支付功能\n- Latex编辑，可替代overleaf使用\n\n✅ 音乐播放\n\n- 无需登录，可快速上手使用\n- 支持歌曲/歌手的模糊搜索，播放歌曲和查看热评\n- 支持歌曲倍速播放\n\n✅ 视频解析\n\n- 无需会员，可在线解析视频，解析速度快\n- 包含海量视频资源，提供多个可用的解析接口\n- 支持全屏、倍速播放，画质超清及以上\n- 解析下载无水印1080P视频\n\n✅ 实时黄金\n\n- 页面水印，版权认证\n- 实时获取黄内金价和国外金价数据\n- TradingView实时k线图数据波动\n- 支持切换日期范围选择、复制图片、下载图片\n\n✅ 论文文献\n\n- Hugging Face今日论文和热搜论文\n- 筛选论文，项目主页，代码地址，arXiv论文等\n- PC端和移动端适配预览论文PDF\n- 对论文PDF进行AI解答\n\n✅ Latex编辑\n\n- 支持overleaf的90%功能，编译不受限制\n- 编辑本地保存，不会上传到服务器，信息安全\n- 支持导出PDF文件\n- 支持自定义模板\n\n✅ 思维导图\n\n- 生成对应内容的思维导图和Markdown内容，可导出SVG图片和PNG图片\n- 支持拖拽、放大、缩小、全屏\n- 适配PC端和移动端\n\n✅ ChatGPT\n\n- 集成OpenAi API (DeepSeek V3.2模型)，无需再代理，可快速使用\n- 支持markdown格式，代码高亮，代码复制，公式和图表展示\n- 无限轮聊天 + 带上下文逻辑\n- 流式输出，可中断输出，实时会话存储管理，导出聊天记录\n- 语音聊天 + 语音播放\n\n✅ 文生图\n\n- 接入文生图模型（MidJourney / Stable Diffusion Model）\n- 支持大量多语言的AI绘图\n- 提供20+种生成的图片风格\n\n✅ 动漫漫画\n\n- 有13个热门榜单，上万本图漫，包括人气榜、新作榜、畅销榜、日漫榜、恋爱榜、剧情榜、投稿榜、完结榜、免费榜、等免榜、月票榜\n- 支持漫画名/漫画作者/漫画内容的模糊搜索，可快速切换漫画上一章、下一章\n\n## ➰ 效果展示\n\n- ### 关于我\n\n<img width=\"1470\" height=\"792\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/8e34e58f-ea63-47ce-9070-09f63fe6564d\" />\n<img width=\"1470\" height=\"792\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/0e293ff8-dedd-47a8-a51f-22f0211e944e\" />\n<img width=\"1470\" height=\"793\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/32c04cc5-4a05-4b8e-962b-fbedcf0af228\" />\n\n- ### 版本检测\n\n<img width=\"734\" height=\"674\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/e2bc2706-b137-47bd-b24a-46585f6a9349\" />\n<img width=\"1017\" height=\"677\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/464e4219-57ea-46bc-8267-8abbc90bc752\" />\n\n- ### 登录页面\n\n<img width=\"1214\" height=\"763\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/2a55a46d-af30-4122-b417-5425288ef3ac\" />\n<img width=\"1312\" height=\"791\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/2714de5f-471c-40f5-af41-dbe4b21a3813\" />\n<img width=\"1413\" height=\"708\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/19d1df96-4fad-4c22-b720-10d1deed48b3\" />\n<img width=\"1276\" height=\"659\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/9570cfd9-8189-4e5e-b3d0-9f3ab81b888e\" />\n\n- ### 爱心跳动\n\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/02b9367e-0b6e-4cde-8157-36b5731aa518)\n\n- ### 主页\n\n<img width=\"1470\" height=\"794\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/e745dfcf-e04d-49bf-b2dc-bb19cf66ded0\" />\n<img width=\"1470\" height=\"795\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/82a34ebe-00eb-4c37-8b90-82f53f604a44\" />\n<img width=\"667\" height=\"708\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/4711dbd6-4a24-4d28-a47e-db95f6934d3e\" />\n<img width=\"663\" height=\"694\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/90a5388e-2008-47d6-afcd-939277aa4086\" />\n\n- ### 观看页面\n\n<img width=\"1470\" height=\"794\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/d085b162-3bd2-4444-9dd7-ada732efd689\" />\n<img width=\"1467\" height=\"787\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/65b9e758-818d-4e49-9936-808070ab45c0\" />\n<img width=\"1470\" height=\"792\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/2153eb1a-3ae5-4ff9-9583-11329bde77e2\" />\n<img width=\"1470\" height=\"789\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/a7bf05d8-f5d3-419c-b0ee-0013e925b00e\" />\n<img width=\"1470\" height=\"789\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/54fdfd8b-35c7-4e8e-839e-0df12beb02ef\" />\n<img width=\"695\" height=\"776\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/956e3d33-c4b4-471f-b004-6beac7bc32a2\" />\n<img width=\"1470\" height=\"795\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/b26084b3-1a26-4b21-8fc5-e38b9ad50540\" />\n<img width=\"1470\" height=\"719\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/02f91f09-9d14-4cd3-a101-8d004ef1cebb\" />\n<img width=\"493\" height=\"720\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/e4b9f98a-b053-47bc-94a5-32cc615314ce\" />\n\n- ### 论文文献\n\n<img width=\"1470\" height=\"794\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/29a0ba7d-13de-425a-9de3-fe1d272a140f\" />\n<img width=\"1470\" height=\"793\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/26c8630a-4329-48d6-bad6-9846a708fcef\" />\n<img width=\"1470\" height=\"795\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/8d08a59c-b673-430e-99de-0230ed0db149\" />\n<img width=\"675\" height=\"779\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/ec888e37-8bb5-42ba-bbb6-10ef2123fd39\" />\n<img width=\"664\" height=\"721\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/0063a312-700c-46a8-ae34-f601b53fecf9\" />\n<img width=\"699\" height=\"709\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/ff1eeb84-337e-4b9d-87b7-a37e2ffa4125\" />\n\n- ### Latex编辑\n\n<img width=\"1470\" height=\"797\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/d81e4592-e9b9-4e0e-8e2b-17ea6625fe0e\" />\n<img width=\"495\" height=\"724\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/5c55ff60-53e4-40c3-8c1a-2148d78d2a00\" />\n\n- ### 思维导图\n\n<img width=\"1470\" height=\"794\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/0d3008fd-f418-4925-85c1-90d87928f850\" />\n<img width=\"1470\" height=\"797\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/fae232f3-1a1d-4092-ad2d-ab9eb99bb79f\" />\n<img width=\"495\" height=\"726\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/b6182a74-9197-4fd6-bca2-eeb23741b1af\" />\n<img width=\"498\" height=\"724\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/f40703e9-7f68-4aa5-88ba-3a07a29c02b0\" />\n\n- ### 动漫漫画\n\n<img width=\"1470\" height=\"790\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/b7f974aa-84ab-48a1-ab42-4fd7ebb5b0e0\" />\n<img width=\"1470\" height=\"790\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/1124277a-eb5b-4f6c-8b07-24ce7b672581\" />\n<img width=\"1470\" height=\"796\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/21caccf3-be96-4133-a992-81aabe5dfb32\" />\n<img width=\"696\" height=\"771\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/3cb4b72b-9806-40cd-a1d1-b7d24a4d7744\" />\n<img width=\"727\" height=\"773\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/a324e6d7-e8e5-48a6-a8c9-9585787d26eb\" />\n<img width=\"687\" height=\"780\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/a5cc1133-e29e-4d2f-bbda-af9c533378e8\" />\n\n- ### 实时黄金\n\n<img width=\"1470\" height=\"794\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/d3a8e9c0-adc1-40f1-9de9-f79c14f483a4\" />\n<img width=\"1470\" height=\"795\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/b17a1d6d-d8e8-48f6-96f6-a49968d4be71\" />\n<img width=\"660\" height=\"700\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/41da09a3-8c84-434c-a001-fc81b5624217\" />\n\n- ### ChatGPT页面\n\n<img width=\"1470\" height=\"794\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/d47c6638-b2e5-4b86-b973-61717c6c207a\" />\n<img width=\"1470\" height=\"791\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/7378bfbc-f23a-44d5-b575-1f44c3c477e0\" />\n<img width=\"1470\" height=\"795\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/56c03b75-1a42-4002-bc20-48c5661feec8\" />\n<img width=\"701\" height=\"770\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/fa617f4c-cd29-4902-ada4-10cdff51637f\" />\n\n- ### 音乐页面\n\n<img width=\"1470\" height=\"789\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/72f44648-1e81-435a-b4ea-98ce4f21f6c2\" />\n<img width=\"1470\" height=\"794\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/086ee166-1702-43bc-92b8-3a5baead925f\" />\n<img width=\"1470\" height=\"791\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/a243878b-838d-464a-8953-98342ed1c8b4\" />\n<img width=\"671\" height=\"791\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/004c7a1a-4f48-4e5d-a918-ad3168ef2170\" />\n\n- ### 闲鱼助手\n\n<img width=\"1470\" height=\"793\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/f2502814-f88b-44ee-94a3-47b0180b6e1e\" />\n<img width=\"487\" height=\"716\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/a4d1de7e-6375-4d4d-b10c-749c14b21449\" />\n\n- ### 文生图页面\n\n<img width=\"1470\" height=\"794\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/95ca9824-d33a-4d51-ab72-9c9df4f80df5\" />\n<img width=\"1470\" height=\"795\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/cae32b98-c081-4d46-a7e0-2c676727a668\" />\n\n- ### 降重页面\n\n<img width=\"1470\" height=\"716\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/7db6a99a-b7f6-4771-93a5-0a4bf6ebd68d\" />\n<img width=\"487\" height=\"724\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/a4cf7de6-5962-4e03-b77b-28944c584989\" />\n\n- ### Agent监工\n\n<img width=\"1470\" height=\"794\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/d17c4478-a912-4db5-8572-1ac021b05a3d\" />\n\n- ### 404页面\n\n<img width=\"1470\" height=\"792\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/efd0425b-1879-42a1-9c1e-eb71baea8bfe\" />\n\n## ⚡ 网站性能\n\n<img width=\"1470\" height=\"793\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/468c753d-5f3f-43ff-b3d0-e86a66064319\" />\n<img width=\"1373\" height=\"788\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/b159956b-599a-439a-a05c-33cd25def60a\" />\n<img width=\"1470\" height=\"755\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/746890e5-d67b-491f-af1f-957b0f832040\" />\n<img width=\"1276\" height=\"713\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/179ffd95-19a5-41aa-a389-89d7385410a9\" />\n<img width=\"1276\" height=\"720\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/7ca5f088-78d2-43b0-a5d8-9b39868f4da0\" />\n<img width=\"1276\" height=\"648\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/2ff7eb2b-2c7a-4138-b627-ca59f48493d2\" />\n\n<details>\n\n<summary>历史版本V3.0</summary>\n\n> 切换commit版本：bbcb9d9146edcb1230adb874d67c2bb38aac1e69\n\n## 🔰 项目概述\n\n✅ 技术栈\n\n- 前端：Vue2，Vuex，JQuery，Three.js，axios，fetch，路由前置全局守卫，MD5加密，验证码，网站访问次数统计，Markdown语法解析，highlight代码高亮显示，处理EventStream流，PC端屏幕适配，组件库使用ElementUI和Layui\n- 后端：Java，开发框架SpringBoot，数据库MySQL，中间件Redis，第三方API接入Openai-ChatGPT，接入文生图模型（MidJourney / Stable Diffusion Model），核心技术包含拦截器、过滤器、本地缓存Caffeine LoadingCache、算法（双端队列 + 滑动窗口 + 轮询负载均衡等）、Stream流、全局异常处理器、定时任务、锁机制、Swagger\n- 部署：Nginx，服务器开代理模式\n\n✅ 音乐播放\n\n- 无需登录，可快速上手使用\n- 支持歌曲/歌手的模糊搜索，播放歌曲和对应MV\n- 支持歌曲倍速播放，MV可下载\n\n✅ 视频解析\n\n- 无需会员，可在线解析视频，解析速度快\n- 包含海量视频资源，提供多个可用的解析接口\n- 支持全屏、倍速播放，画质超清及以上\n\n✅ ChatGPT\n\n- 集成OpenAi API (ChatGPT3.5)，无需再代理，可快速使用\n- 支持markdown格式，代码高亮，代码复制，公式和图表展示\n- 无限轮聊天 + 带上下文逻辑\n- 流式输出，会话存储管理\n- 语音聊天 + 语音播放\n\n✅ 文生图\n\n- 接入文生图模型（MidJourney / Stable Diffusion Model）\n- 支持大量多语言的AI绘图\n- 提供20+种生成的图片风格\n\n## ➰ 效果展示\n\n- ### 检测页面\n\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/47f44a74-6901-4c0a-bd28-a69ff2423dae)\n\n- ### 登录页面\n\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/9a994b55-b7af-4ee2-98b1-7ec3844be75b)\n\n- ### 404页面\n\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/8b1bc61b-a5ff-4dcb-80e8-4459680f8da7)\n\n- ### 爱心跳动\n\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/02b9367e-0b6e-4cde-8157-36b5731aa518)\n\n- ### 音乐页面\n\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/a02a52f6-15e8-4503-922b-2af207419c15)\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/1bbd4733-f5fa-43ed-bd4d-a2c30a5b8f52)\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/1321776c-1942-4ab4-b911-5569759b80d3)\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/0b7d8db6-d8ad-4e6e-a103-427e66deba33)\n\n- ### 观看页面\n\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/8d26a5d2-9cb9-4671-8612-a65e1dd1adda)\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/c02fafa0-2f08-4f09-bb92-bf4480dcf7e2)\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/2dc87edc-068e-48f4-8655-d7c05ff91086)\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/0464986a-b635-4114-9b41-84e7786fdabb)\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/43d7a201-0473-4d29-bc3c-d1fd03898e85)\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/3f77676f-fd12-497e-ba5b-857429a60dbb)\n\n- ### 降重页面\n\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/05dc42f5-15ed-49e7-9141-dead78fd5a5b)\n\n- ### ChatGPT页面\n\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/112e3eb6-158f-47e5-9bb4-7e104af38088)\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/f219dc3a-2540-4c87-8ac3-1d030ca88f7e)\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/d44844db-fd03-430c-8bc7-ebbbdf6abed2)\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/fe6d07d7-4564-458b-aa11-d05b1d7119ec)\n\n- ### 文生图页面\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/26a6ac68-a3c9-49f1-b53d-47582480b107)\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/fcf5de85-6a43-42a0-88e7-ca1bc2d8e6bb)\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/05f02f4a-836a-4d68-879d-5b2d7264bf02)\n  ![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/61f8d79d-13b6-4700-98e5-e316023c2e16)\n\n## ⚡ 网站性能\n\n![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/8bf28d51-e295-4eb7-bf81-d89ba65d2527)\n![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/f0300dc2-945c-4f49-8b62-083dd3d5911b)\n![image](https://github.com/P1kaj1uu/VIP-Video-Parsing/assets/94435057/f8ff05cf-c2f8-4967-a5f5-2975b2d729c0)\n\n</details>\n\n## 🖋 参与贡献\n\n<a href=\"https://github.com/P1Kaj1uu/VIP-Video-Parsing/graphs/contributors\"> <img src=\"https://contrib.rocks/image?repo=P1Kaj1uu/VIP-Video-Parsing\" /></a>\n\n## 🍺 赞助\n\n如果你认为我的项目对你很有帮助，而且情况允许的话，那么请考虑支持我的项目。我将非常感激任何的支持，哪怕只是一点点的资助，也能激励我持续开发和改进这个项目。\n\n您可以通过以下几种方式支持我的项目：\n\n- 赞助我：您可以通过贡献资金来支持我的项目，这将帮助我支付服务器、工具和其他开发成本。您可以在下方找到资助方式。\n\n- 分享项目：如果您不能贡献资金，但是您认为我的项目非常有价值，那么请考虑分享项目链接给您的朋友和同事。这将有助于我的项目得到更多的关注和支持。如果可以请给一个小小的star！\n\n- 提供反馈：您可以通过提交Issues或者Pull Requests来帮助改进我的项目。如果您发现了任何错误或者您认为我的项目可以改进的地方，欢迎随时向我提供反馈。\n\n总之，非常感谢您对我的项目的支持，我将努力不懈地改进和提高这个项目的质量，让它更好地为您和其他用户服务。\n\n<br />\n\n联系我（WeChat：Dveiklokk）：\n\n<img width=\"274\" height=\"381\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/16f145fa-af7f-4ef2-9e36-7051c619eaa9\" />\n\nWeChat Pay：\n\n<img width=\"263\" height=\"375\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/b3174698-024c-4be4-bd9b-7cc219503344\" />\n\n## ⏰ Star History\n\n[![Star History Chart](https://api.star-history.com/svg?repos=P1kaj1uu/ChattyPlay-Agent&type=Timeline)](https://star-history.com/#P1kaj1uu/ChattyPlay-Agent&Timeline)\n"
  },
  {
    "path": "api/index.ts",
    "content": "import { Hono } from 'hono'\nimport { cors } from 'hono/cors'\nimport CryptoJS from 'crypto-js'\n\nconst app = new Hono()\n\n// CORS\napp.use('/*', cors())\n\n// ============ 认证相关常量 ============\n\nconst JWT_SECRET = 'chattyplay-jwt-secret-2024'\nconst PASSWORD_SECRET = 'chattyplay-secret-key-2024'\nconst TOKEN_EXPIRY = 7 * 24 * 60 * 60 * 1000 // 7天\n\n// Redis 配置\nconst REDIS_REST_URL = process.env.UPSTASH_REDIS_REST_URL\nconst REDIS_REST_TOKEN = process.env.UPSTASH_REDIS_REST_TOKEN\n\n// 用户计数器 key\nconst USER_COUNTER_KEY = 'user:id_counter'\n// 用户 Hash key prefix\nconst USER_HASH_PREFIX = 'user:'\n// 用户名索引 key\nconst USERNAME_INDEX_KEY = 'user:username_index'\n\n// ============ Redis HTTP API 调用函数 ============\n\ninterface RedisResult {\n  result?: any\n  error?: string\n}\n\nasync function redisCommand(command: string[]): Promise<RedisResult> {\n  if (!REDIS_REST_URL || !REDIS_REST_TOKEN) {\n    return { error: 'Redis 未配置' }\n  }\n\n  try {\n    const response = await fetch(`${REDIS_REST_URL}`, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n        'Authorization': `Bearer ${REDIS_REST_TOKEN}`\n      },\n      body: JSON.stringify(command)\n    })\n\n    if (!response.ok) {\n      return { error: `Redis 请求失败: ${response.status}` }\n    }\n\n    const data = await response.json()\n    return { result: data.result }\n  } catch (error) {\n    return { error: `Redis 连接错误: ${error instanceof Error ? error.message : '未知错误'}` }\n  }\n}\n\n// Redis 操作函数\nasync function getNextUserId(): Promise<number | null> {\n  const { result, error } = await redisCommand(['INCR', USER_COUNTER_KEY])\n  if (error || result === null) return null\n  return result as number\n}\n\nasync function getUserById(id: number): Promise<User | null> {\n  const { result, error } = await redisCommand(['HGETALL', `${USER_HASH_PREFIX}${id}`])\n  if (error || !result || result.length === 0) return null\n\n  // HGETALL 返回 [key1, val1, key2, val2, ...] 格式\n  const user: any = {}\n  for (let i = 0; i < result.length; i += 2) {\n    user[result[i]] = result[i + 1]\n  }\n  user.id = Number(user.id)\n  return user as User\n}\n\nasync function getUserByUsername(username: string): Promise<User | null> {\n  // 从用户名索引获取用户 ID\n  const { result: userId, error } = await redisCommand(['HGET', USERNAME_INDEX_KEY, username])\n  if (error || !userId) return null\n  return getUserById(Number(userId))\n}\n\nasync function getUserByEmail(email: string): Promise<User | null> {\n  // 扫描查找邮箱匹配的用户（较慢但可行）\n  const { result: keys, error } = await redisCommand(['KEYS', `${USER_HASH_PREFIX}*`])\n  if (error || !keys || keys.length === 0) return null\n\n  for (const key of keys) {\n    const { result: emailVal, error: emailError } = await redisCommand(['HGET', key, 'email'])\n    if (!emailError && emailVal === email) {\n      return getUserById(Number(key.replace(USER_HASH_PREFIX, '')))\n    }\n  }\n  return null\n}\n\nasync function createUser(user: User): Promise<void> {\n  const { error } = await redisCommand([\n    'HMSET',\n    `${USER_HASH_PREFIX}${user.id}`,\n    'id', String(user.id),\n    'username', user.username,\n    'password', user.password,\n    'email', user.email || '',\n    'created_at', user.created_at\n  ])\n  if (error) throw new Error(error)\n\n  // 保存用户名索引\n  await redisCommand(['HSET', USERNAME_INDEX_KEY, user.username, String(user.id)])\n}\n\nasync function updateUserField(id: number, field: string, value: string): Promise<void> {\n  await redisCommand(['HSET', `${USER_HASH_PREFIX}${id}`, field, value])\n}\n\n// ============ 数据类型定义 ============\n\ninterface User {\n  id: number\n  username: string\n  password: string\n  email?: string\n  avatar?: string\n  created_at: string\n  last_login?: string\n}\n\ninterface UserWithoutPassword {\n  id: number\n  username: string\n  email?: string\n  avatar?: string\n  created_at: string\n  last_login?: string\n}\n\n// ============ 密码工具函数 ============\n\nfunction hashPassword(password: string): string {\n  return CryptoJS.SHA256(password + PASSWORD_SECRET).toString()\n}\n\nfunction verifyPassword(password: string, hashedPassword: string): boolean {\n  const hashed = hashPassword(password)\n  return hashed === hashedPassword\n}\n\n// ============ JWT Token 函数 ============\n\nfunction generateToken(payload: { userId: number; username: string }): string {\n  const tokenPayload = {\n    ...payload,\n    exp: Date.now() + TOKEN_EXPIRY\n  }\n\n  const header = {\n    alg: 'HS256',\n    typ: 'JWT'\n  }\n\n  const encodedHeader = base64UrlEncode(JSON.stringify(header))\n  const encodedPayload = base64UrlEncode(JSON.stringify(tokenPayload))\n  const signature = CryptoJS.HmacSHA256(`${encodedHeader}.${encodedPayload}`, JWT_SECRET).toString()\n  const encodedSignature = base64UrlEncode(signature)\n\n  return `${encodedHeader}.${encodedPayload}.${encodedSignature}`\n}\n\nfunction verifyToken(token: string): { userId: number; username: string } | null {\n  try {\n    const [encodedHeader, encodedPayload, encodedSignature] = token.split('.')\n\n    if (!encodedHeader || !encodedPayload || !encodedSignature) {\n      return null\n    }\n\n    const signature = CryptoJS.HmacSHA256(`${encodedHeader}.${encodedPayload}`, JWT_SECRET).toString()\n    const encodedSignatureCheck = base64UrlEncode(signature)\n\n    if (encodedSignature !== encodedSignatureCheck) {\n      return null\n    }\n\n    const payload = JSON.parse(base64UrlDecode(encodedPayload)) as { userId: number; username: string; exp?: number }\n\n    if (payload.exp && payload.exp < Date.now()) {\n      return null\n    }\n\n    return payload\n  } catch (error) {\n    console.error('Token verification failed:', error)\n    return null\n  }\n}\n\nfunction base64UrlEncode(str: string): string {\n  return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))\n    .replace(/\\+/g, '-')\n    .replace(/\\//g, '_')\n    .replace(/=/g, '')\n}\n\nfunction base64UrlDecode(str: string): string {\n  let base64 = str.replace(/-/g, '+').replace(/_/g, '/')\n  while (base64.length % 4) {\n    base64 += '='\n  }\n  return CryptoJS.enc.Base64.parse(base64).toString(CryptoJS.enc.Utf8)\n}\n\n// ============ 认证路由 ============\n\n/**\n * 用户注册\n * POST /api/auth/register\n */\napp.post('/api/auth/register', async (c) => {\n  try {\n    const body = await c.req.json()\n    const { username, password, email } = body\n\n    if (!username || !password) {\n      return c.json({\n        success: false,\n        message: '用户名和密码不能为空'\n      }, 400)\n    }\n\n    if (username.length < 3 || username.length > 20) {\n      return c.json({\n        success: false,\n        message: '用户名长度必须在3-20个字符之间'\n      }, 400)\n    }\n\n    if (password.length < 6 || password.length > 20) {\n      return c.json({\n        success: false,\n        message: '密码长度必须在6-20个字符之间'\n      }, 400)\n    }\n\n    if (email) {\n      const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n      if (!emailRegex.test(email)) {\n        return c.json({\n          success: false,\n          message: '邮箱格式不正确'\n        }, 400)\n      }\n    }\n\n    // 检查用户名是否已存在\n    const existingUser = await getUserByUsername(username)\n    if (existingUser) {\n      return c.json({\n        success: false,\n        message: '用户名已存在'\n      }, 400)\n    }\n\n    // 检查邮箱是否已存在\n    if (email) {\n      const existingEmail = await getUserByEmail(email)\n      if (existingEmail) {\n        return c.json({\n          success: false,\n          message: '邮箱已被注册'\n        }, 400)\n      }\n    }\n\n    // 创建用户\n    const userId = await getNextUserId()\n    if (userId === null) {\n      return c.json({\n        success: false,\n        message: '用户服务暂不可用，请检查 Redis 配置'\n      }, 500)\n    }\n\n    const hashedPassword = hashPassword(password)\n    const createdAt = new Date().toISOString()\n\n    const newUser: User = {\n      id: userId,\n      username,\n      password: hashedPassword,\n      email,\n      created_at: createdAt\n    }\n\n    await createUser(newUser)\n\n    // 生成 token\n    const token = generateToken({\n      userId: newUser.id,\n      username: newUser.username\n    })\n\n    const userWithoutPassword: UserWithoutPassword = {\n      id: newUser.id,\n      username: newUser.username,\n      email: newUser.email,\n      created_at: newUser.created_at\n    }\n\n    return c.json({\n      success: true,\n      message: '注册成功',\n      token,\n      user: userWithoutPassword\n    })\n  } catch (error) {\n    console.error('注册接口错误:', error)\n    return c.json({\n      success: false,\n      message: '服务器错误'\n    }, 500)\n  }\n})\n\n/**\n * 用户登录\n * POST /api/auth/login\n */\napp.post('/api/auth/login', async (c) => {\n  try {\n    const body = await c.req.json()\n    const { username, password } = body\n\n    if (!username || !password) {\n      return c.json({\n        success: false,\n        message: '用户名和密码不能为空'\n      }, 400)\n    }\n\n    // 查找用户\n    const user = await getUserByUsername(username)\n    if (!user) {\n      return c.json({\n        success: false,\n        message: '用户名或密码错误'\n      }, 400)\n    }\n\n    // 验证密码\n    const isPasswordValid = verifyPassword(password, user.password)\n    if (!isPasswordValid) {\n      return c.json({\n        success: false,\n        message: '用户名或密码错误'\n      }, 400)\n    }\n\n    // 更新最后登录时间\n    const lastLogin = new Date().toISOString()\n    await updateUserField(user.id, 'last_login', lastLogin)\n\n    // 生成 token\n    const token = generateToken({\n      userId: user.id,\n      username: user.username\n    })\n\n    const userWithoutPassword: UserWithoutPassword = {\n      id: user.id,\n      username: user.username,\n      email: user.email,\n      avatar: user.avatar,\n      created_at: user.created_at,\n      last_login: lastLogin\n    }\n\n    return c.json({\n      success: true,\n      message: '登录成功',\n      token,\n      user: userWithoutPassword\n    })\n  } catch (error) {\n    console.error('登录接口错误:', error)\n    return c.json({\n      success: false,\n      message: '服务器错误'\n    }, 500)\n  }\n})\n\n/**\n * 验证 token 并获取用户信息\n * GET /api/auth/me\n */\napp.get('/api/auth/me', async (c) => {\n  try {\n    const token = c.req.header('Authorization')?.replace('Bearer ', '')\n\n    if (!token) {\n      return c.json({\n        success: false,\n        message: '未提供认证令牌'\n      }, 401)\n    }\n\n    const payload = verifyToken(token)\n\n    if (!payload) {\n      return c.json({\n        success: false,\n        message: '无效的认证令牌'\n      }, 401)\n    }\n\n    // 查找用户\n    const user = await getUserById(payload.userId)\n    if (!user) {\n      return c.json({\n        success: false,\n        message: '用户不存在'\n      }, 401)\n    }\n\n    const userWithoutPassword: UserWithoutPassword = {\n      id: user.id,\n      username: user.username,\n      email: user.email,\n      avatar: user.avatar,\n      created_at: user.created_at,\n      last_login: user.last_login\n    }\n\n    return c.json({\n      success: true,\n      user: userWithoutPassword\n    })\n  } catch (error) {\n    console.error('获取用户信息接口错误:', error)\n    return c.json({\n      success: false,\n      message: '服务器错误'\n    }, 500)\n  }\n})\n\n// 简单的健康检查\napp.get('/api/health', (c) => c.json({ status: 'ok' }))\n\n// 视频下载代理端点\napp.post('/api/resolve', async (c) => {\n  const targetUrl = 'https://xiazaishipin.com/api/resolve'\n  const body = await c.req.json()\n\n  const response = await fetch(targetUrl, {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application/json',\n      'Referer': 'https://xiazaishipin.com/',\n      'Origin': 'https://xiazaishipin.com',\n      'Accept': 'application/json, text/plain, */*',\n      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',\n    },\n    body: JSON.stringify(body),\n  })\n\n  const responseData = await response.json()\n\n  if (responseData.thumbnail) {\n    responseData.thumbnail = `/api/image-proxy?url=${encodeURIComponent(responseData.thumbnail)}`\n  }\n\n  return c.json(responseData, response.status as any)\n})\n\n// 图片代理 - 绕过防盗链\napp.get('/api/image-proxy', async (c) => {\n  const imageUrl = c.req.query('url')\n\n  if (!imageUrl) {\n    return c.json({ error: 'Missing url parameter' }, 400)\n  }\n\n  try {\n    const response = await fetch(imageUrl, {\n      headers: {\n        'Referer': 'https://www.bilibili.com/',\n        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',\n      },\n    })\n\n    if (!response.ok) {\n      throw new Error(`Failed to fetch image: ${response.status}`)\n    }\n\n    const imageBuffer = await response.arrayBuffer()\n    const contentType = response.headers.get('Content-Type') || 'image/jpeg'\n\n    return new Response(imageBuffer, {\n      headers: {\n        'Content-Type': contentType,\n        'Cache-Control': 'public, max-age=86400',\n      },\n    })\n  } catch (error) {\n    return c.json({\n      error: 'Failed to proxy image',\n      message: error instanceof Error ? error.message : 'Unknown error'\n    }, 500)\n  }\n})\n\n// B站视频下载代理\napp.post('/api/bilibili-download', async (c) => {\n  const targetUrl = 'https://xiazaishipin.com/api/bilibili-download'\n  const body = await c.req.json()\n\n  const response = await fetch(targetUrl, {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application/json',\n      'Referer': 'https://xiazaishipin.com/',\n      'Origin': 'https://xiazaishipin.com',\n      'Accept': '*/*',\n      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',\n    },\n    body: JSON.stringify(body),\n  })\n\n  const contentType = response.headers.get('content-type') || ''\n\n  if (contentType.includes('application/json')) {\n    const jsonData = await response.json()\n    return c.json(jsonData)\n  } else {\n    const reader = response.body?.getReader()\n\n    if (!reader) {\n      throw new Error('无法获取响应流')\n    }\n\n    const stream = new ReadableStream({\n      async start(controller) {\n        try {\n          while (true) {\n            const { done, value } = await reader.read()\n            if (done) {\n              controller.close()\n              break\n            }\n            controller.enqueue(value)\n          }\n        } catch (error) {\n          controller.error(error)\n        } finally {\n          reader.releaseLock()\n        }\n      }\n    })\n\n    return new Response(stream, {\n      status: response.status,\n      headers: {\n        'Content-Type': contentType,\n        'Content-Disposition': response.headers.get('Content-Disposition') || `attachment; filename=\"video.mp4\"`,\n        'Content-Length': response.headers.get('Content-Length') || '',\n        'Cache-Control': 'no-cache',\n      },\n    })\n  }\n})\n\n// 抖音/其他视频下载代理\napp.post('/api/proxy-download', async (c) => {\n  const targetUrl = 'https://xiazaishipin.com/api/proxy-download'\n  const body = await c.req.json()\n\n  const response = await fetch(targetUrl, {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application/json',\n      'Referer': 'https://xiazaishipin.com/',\n      'Origin': 'https://xiazaishipin.com',\n      'Accept': '*/*',\n      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',\n    },\n    body: JSON.stringify(body),\n  })\n\n  const contentType = response.headers.get('content-type') || ''\n\n  if (contentType.includes('application/json')) {\n    const jsonData = await response.json()\n    return c.json(jsonData)\n  } else {\n    const reader = response.body?.getReader()\n\n    if (!reader) {\n      throw new Error('无法获取响应流')\n    }\n\n    const stream = new ReadableStream({\n      async start(controller) {\n        try {\n          while (true) {\n            const { done, value } = await reader.read()\n            if (done) {\n              controller.close()\n              break\n            }\n            controller.enqueue(value)\n          }\n        } catch (error) {\n          controller.error(error)\n        } finally {\n          reader.releaseLock()\n        }\n      }\n    })\n\n    return new Response(stream, {\n      status: response.status,\n      headers: {\n        'Content-Type': contentType,\n        'Content-Disposition': response.headers.get('Content-Disposition') || `attachment; filename=\"video.mp4\"`,\n        'Content-Length': response.headers.get('Content-Length') || '',\n        'Cache-Control': 'no-cache',\n      },\n    })\n  }\n})\n\n// ============ LaTeX 编译 API 代理 ============\n\n// LaTeX 编译 API 代理\napp.post('/api/latex/compile', async (c) => {\n  try {\n    const { code, compiler = 'xelatex', files = [] } = await c.req.json()\n\n    // 添加时间戳确保请求唯一性\n    const timestamp = new Date().toISOString()\n    console.log(`[${timestamp}] LaTeX 编译请求`)\n\n    if (!code || typeof code !== 'string') {\n      return c.json({\n        success: false,\n        error: '请提供有效的 LaTeX 代码'\n      }, 400)\n    }\n\n    console.log('LaTeX 编译请求:', {\n      compiler,\n      codeLength: code.length,\n      codePreview: code.substring(0, 100) + (code.length > 100 ? '...' : ''),\n      filesCount: files.length,\n      files: files.map((f: any) => ({ name: f.name, contentLength: f.content?.length }))\n    })\n\n    // 如果有图片文件，使用正确的 API 格式传递\n    const processedCode = code\n    if (files && files.length > 0) {\n      console.log('检测到图片文件，使用多文件资源格式')\n    }\n\n    // 检测是否包含中文字符\n    const hasChinese = /[一-龥]/.test(processedCode)\n    console.log('包含中文:', hasChinese)\n\n    // 如果包含中文，尝试使用专门处理中文的服务\n    if (hasChinese) {\n      console.log('检测到中文内容，使用特殊的中文处理方案')\n\n      // 方案1: 尝试使用 Overleaf-style API\n      try {\n        const overleafUrl = 'https://compile.overleaf.com/docs'\n\n        // 构建文件列表：主文件（图片已嵌入）\n        const requestFiles: any[] = [{\n          name: 'main.tex',\n          content: processedCode\n        }]\n\n        const response = await fetch(overleafUrl, {\n          method: 'POST',\n          headers: {\n            'Content-Type': 'application/json',\n          },\n          body: JSON.stringify({\n            compiler: compiler,\n            files: requestFiles,\n            options: {\n              timeout: 60\n            }\n          }),\n        })\n\n        if (response.ok) {\n          const data = await response.json()\n          if (data.pdfs && data.pdfs['main.pdf']) {\n            const pdfData = data.pdfs['main.pdf']\n            const pdfBuffer = Buffer.from(pdfData, 'base64')\n\n            return new Response(pdfBuffer, {\n              headers: {\n                'Content-Type': 'application/pdf',\n                'Content-Disposition': 'attachment; filename=\"document.pdf\"',\n                'Access-Control-Allow-Origin': '*',\n              },\n            })\n          }\n        }\n      } catch (error) {\n        console.error('Overleaf API 失败:', error)\n      }\n\n      // 方案2: 修改LaTeX代码以使用更通用的字体设置\n      console.log('尝试修改LaTeX代码以支持中文')\n      let modifiedCode = processedCode\n\n      // 如果代码中没有ctex相关包，添加中文支持\n      if (!processedCode.includes('ctex') && !processedCode.includes('CJK')) {\n        // 在documentclass后添加中文支持\n        modifiedCode = processedCode.replace(\n          /\\\\documentclass(\\[[^\\]]*\\])?\\{([^}]+)\\}/,\n          (match: string, options: string, docclass: string) => {\n            if (docclass === 'ctexart') {\n              return match\n            }\n            return `\\\\documentclass${options || ''}{${docclass}}\\n\\\\usepackage{CJKutf8}\\n\\\\usepackage{CJK}`\n          }\n        )\n\n        // 在document环境中添加CJK支持\n        if (modifiedCode.includes('\\\\begin{document}')) {\n          modifiedCode = modifiedCode.replace(\n            '\\\\begin{document}',\n            '\\\\begin{document}\\n\\\\begin{CJK*}{UTF8}{gbsn}'\n          )\n        }\n\n        if (modifiedCode.includes('\\\\end{document}')) {\n          modifiedCode = modifiedCode.replace(\n            '\\\\end{document}',\n            '\\\\end{CJK*}\\n\\\\end{document}'\n          )\n        }\n      }\n\n      console.log('修改后的代码预览:', modifiedCode.substring(0, 200) + '...')\n\n      // 使用修改后的代码尝试编译\n      const latexApiUrl = 'https://latex.ytotech.com/builds/sync'\n\n      // 构建请求数据 - 使用正确的 resources 格式\n      const resources: any[] = [{\n        main: true,\n        content: modifiedCode\n      }]\n\n      // 添加附加文件（图片等）- 使用正确的格式\n      if (files && files.length > 0) {\n        for (const file of files) {\n          if (file.name && file.content) {\n            let base64Data = file.content\n            if (base64Data.startsWith('data:')) {\n              base64Data = base64Data.split(',')[1] || base64Data\n            }\n\n            resources.push({\n              path: file.name,\n              file: base64Data\n            })\n\n            console.log(`添加图片资源（中文处理）: ${file.name}`)\n          }\n        }\n      }\n\n      const requestData = {\n        compiler: compiler,\n        resources: resources\n      }\n\n      console.log('发送到 LaTeX API 的请求（中文处理）:', {\n        compiler,\n        codeLength: modifiedCode.length,\n        资源数量: resources.length,\n        包含图片: files && files.length > 0\n      })\n\n      const response = await fetch(latexApiUrl, {\n        method: 'POST',\n        headers: {\n          'Content-Type': 'application/json',\n        },\n        body: JSON.stringify(requestData),\n      })\n\n      if (response.ok) {\n        const contentType = response.headers.get('content-type') || ''\n        if (contentType.includes('application/pdf')) {\n          const pdfBuffer = await response.arrayBuffer()\n          console.log('中文PDF生成成功，大小:', pdfBuffer.byteLength, '字节')\n\n          return new Response(pdfBuffer, {\n            headers: {\n              'Content-Type': 'application/pdf',\n              'Content-Disposition': 'attachment; filename=\"document.pdf\"',\n              'Access-Control-Allow-Origin': '*',\n            },\n          })\n        }\n      }\n    }\n\n    // 非中文内容或中文处理失败，使用标准流程\n    const latexApiUrl = 'https://latex.ytotech.com/builds/sync'\n\n    // 构建请求数据 - 使用正确的 resources 格式\n    const resources: any[] = [{\n      main: true,\n      content: processedCode\n    }]\n\n    // 添加附加文件（图片等）- 使用正确的格式\n    if (files && files.length > 0) {\n      for (const file of files) {\n        if (file.name && file.content) {\n          let base64Data = file.content\n          if (base64Data.startsWith('data:')) {\n            base64Data = base64Data.split(',')[1] || base64Data\n          }\n\n          resources.push({\n            path: file.name,\n            file: base64Data\n          })\n\n          console.log(`添加图片资源: ${file.name}`)\n        }\n      }\n    }\n\n    const requestData = {\n      compiler: compiler,\n      resources: resources\n    }\n\n    console.log('发送到 LaTeX API 的请求:', {\n      compiler,\n      codeLength: processedCode.length,\n      资源数量: resources.length,\n      包含图片: files && files.length > 0\n    })\n\n    const response = await fetch(latexApiUrl, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n      },\n      body: JSON.stringify(requestData),\n    })\n\n    console.log('API 响应状态:', response.status, response.statusText)\n\n    if (!response.ok) {\n      const errorText = await response.text()\n      console.error('LaTeX API 错误响应:', errorText)\n      console.error('请求体详情:', JSON.stringify(requestData, null, 2))\n      throw new Error(`LaTeX API 返回错误: ${response.status} ${response.statusText} - ${errorText}`)\n    }\n\n    const contentType = response.headers.get('content-type') || ''\n    console.log('响应内容类型:', contentType)\n\n    if (contentType.includes('application/pdf')) {\n      const pdfBuffer = await response.arrayBuffer()\n      console.log('PDF 生成成功，大小:', pdfBuffer.byteLength, '字节')\n\n      return new Response(pdfBuffer, {\n        headers: {\n          'Content-Type': 'application/pdf',\n          'Content-Disposition': 'attachment; filename=\"document.pdf\"',\n          'Access-Control-Allow-Origin': '*',\n          'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',\n          'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n        },\n      })\n    }\n\n    const errorText = await response.text()\n    console.error('非 PDF 响应:', errorText)\n    return c.json({\n      success: false,\n      error: `编译失败，服务器返回非 PDF 内容: ${errorText.substring(0, 200)}`\n    }, 500)\n\n  } catch (error) {\n    console.error('LaTeX 编译代理错误:', error)\n\n    const errorMessage = error instanceof Error ? error.message : '未知错误'\n    return c.json({\n      success: false,\n      error: `LaTeX 编译失败: ${errorMessage}`\n    }, 500)\n  }\n})\n\n// LaTeX 编译健康检查\napp.get('/api/latex/health', async (c) => {\n  try {\n    const testCode = '\\\\documentclass{article}\\\\begin{document}Hello World\\\\end{document}'\n    const response = await fetch(`https://latex.ytotech.com/builds/sync?content=${encodeURIComponent(testCode)}`, {\n      method: 'GET',\n    })\n\n    return c.json({\n      status: response.ok ? 'available' : 'unavailable',\n      statusCode: response.status,\n      timestamp: new Date().toISOString()\n    })\n  } catch (error) {\n    return c.json({\n      status: 'error',\n      error: error instanceof Error ? error.message : '未知错误',\n      timestamp: new Date().toISOString()\n    }, 503)\n  }\n})\n\nexport default app\n"
  },
  {
    "path": "deploy.sh",
    "content": "#!/bin/bash\n\n# 颜色定义\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nNC='\\033[0m' # No Color\n\n# 项目名称\nPROJECT_NAME=\"chattyplay-agent\"\nIMAGE_NAME=\"${PROJECT_NAME}:latest\"\nCONTAINER_NAME=\"${PROJECT_NAME}-web\"\n\necho -e \"${GREEN}======================================${NC}\"\necho -e \"${GREEN}  Docker 部署脚本${NC}\"\necho -e \"${GREEN}======================================${NC}\"\n\n# 检查 Docker 是否安装\nif ! command -v docker &> /dev/null; then\n    echo -e \"${RED}错误: Docker 未安装，请先安装 Docker${NC}\"\n    exit 1\nfi\n\n# 构建镜像\necho -e \"${YELLOW}步骤 1/4: 构建 Docker 镜像...${NC}\"\ndocker build -t $IMAGE_NAME .\nif [ $? -ne 0 ]; then\n    echo -e \"${RED}镜像构建失败${NC}\"\n    exit 1\nfi\necho -e \"${GREEN}✓ 镜像构建成功${NC}\"\n\n# 停止并删除旧容器\necho -e \"${YELLOW}步骤 2/4: 停止旧容器...${NC}\"\nif [ \"$(docker ps -aq -f name=$CONTAINER_NAME)\" ]; then\n    docker stop $CONTAINER_NAME 2>/dev/null\n    docker rm $CONTAINER_NAME 2>/dev/null\n    echo -e \"${GREEN}✓ 旧容器已删除${NC}\"\nelse\n    echo -e \"${GREEN}✓ 没有运行中的旧容器${NC}\"\nfi\n\n# 运行新容器\necho -e \"${YELLOW}步骤 3/4: 启动新容器...${NC}\"\ndocker run -d \\\n    --name $CONTAINER_NAME \\\n    -p 80:80 \\\n    --restart unless-stopped \\\n    $IMAGE_NAME\n\nif [ $? -ne 0 ]; then\n    echo -e \"${RED}容器启动失败${NC}\"\n    exit 1\nfi\necho -e \"${GREEN}✓ 容器启动成功${NC}\"\n\n# 查看容器状态\necho -e \"${YELLOW}步骤 4/4: 检查容器状态...${NC}\"\ndocker ps -f name=$CONTAINER_NAME\n\necho -e \"${GREEN}======================================${NC}\"\necho -e \"${GREEN}✓ 部署完成！${NC}\"\necho -e \"${GREEN}访问地址: http://localhost${NC}\"\necho -e \"${GREEN}======================================${NC}\"\n\n# 显示日志\necho -e \"${YELLOW}容器日志 (按 Ctrl+C 退出):${NC}\"\ndocker logs -f $CONTAINER_NAME\n"
  },
  {
    "path": "docker-compose.yml",
    "content": "version: '3.8'\n\nservices:\n  # 前端应用\n  web:\n    build:\n      context: .\n      dockerfile: Dockerfile\n    container_name: chattyplay-web\n    ports:\n      - \"80:80\"\n    environment:\n      - NODE_ENV=production\n    restart: unless-stopped\n    networks:\n      - app-network\n    healthcheck:\n      test: [\"CMD\", \"wget\", \"--quiet\", \"--tries=1\", \"--spider\", \"http://localhost/\"]\n      interval: 30s\n      timeout: 10s\n      retries: 3\n      start_period: 40s\n\nnetworks:\n  app-network:\n    driver: bridge\n"
  },
  {
    "path": "email.config.d.ts",
    "content": "export interface EmailConfig {\n  PUBLIC_KEY: string\n  SERVICE_ID: string\n  TEMPLATE_ID: string\n  fromName: string\n  fromEmail: string\n}\n\nexport const emailConfig: EmailConfig\n"
  },
  {
    "path": "email.config.js",
    "content": "/**\n * EmailJS 配置文件\n *\n * 使用说明：\n * 1. 访问 https://www.emailjs.com/ 注册账号\n * 2. 添加邮件服务（Email Service），支持：\n *    - Gmail\n *    - Outlook\n *    - Yahoo Mail\n *    - 或任何支持 SMTP 的邮件服务\n * 3. 创建邮件模板（Email Template）\n * 4. 获取以下配置信息并填入：\n *    - SERVICE_ID: 服务 ID\n *    - TEMPLATE_ID: 模板 ID\n *    - PUBLIC_KEY: 公钥\n *\n * 邮件模板示例：\n * 主题：ChattyPlay - 实时金价\n * 内容：\n * {{email}} 您好，\n * {{to_email}} 您好，\n *\n * 黄金价格实时通知：\n *\n * 国内金价：{{domestic_price}}\n * 国际金价：{{international_price}}\n * 当前时间：{{current_time}}\n *\n * --\n * ChattyPlay - 黄金价格实时监控\n */\n\nexport const emailConfig = {\n  // EmailJS 公钥（必填）\n  PUBLIC_KEY: import.meta.env.VITE_EMAILJS_PUBLIC_KEY || 'YOUR_PUBLIC_KEY_HERE',\n\n  // EmailJS 服务 ID（必填）\n  SERVICE_ID: import.meta.env.VITE_EMAILJS_SERVICE_ID || 'YOUR_SERVICE_ID_HERE',\n\n  // EmailJS 模板 ID（必填）\n  TEMPLATE_ID: import.meta.env.VITE_EMAILJS_TEMPLATE_ID || 'YOUR_TEMPLATE_ID_HERE',\n\n  // 发件人信息（可选）\n  fromName: import.meta.env.VITE_EMAILJS_FROM_NAME || 'ChattyPlay',\n  fromEmail: import.meta.env.VITE_EMAILJS_FROM_EMAIL || '891523233@qq.com',\n}\n\nexport default emailConfig\n"
  },
  {
    "path": "index.html",
    "content": "<!doctype html>\n<html lang=\"zh-CN\">\n<head>\n  <meta charset=\"UTF-8\" />\n  <link rel=\"icon\" type=\"image/svg+xml\" href=\"/public/icon.ico\" />\n  <link rel=\"preconnect\" href=\"https://challenges.cloudflare.com\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n  <title>ChattyPlay</title>\n  <style>\n    * {\n      margin: 0;\n      padding: 0;\n      box-sizing: border-box;\n    }\n  </style>\n\n  <!-- 用户行为分析和页面性能监控 -->\n  <script async src=\"https://www.googletagmanager.com/gtag/js?id=G-G81HHJ6B4C\"></script>\n  <script>\n    window.dataLayer = window.dataLayer || [];\n    function gtag() {\n      dataLayer.push(arguments);\n    }\n    gtag('js', new Date());\n    gtag('config', 'G-G81HHJ6B4C');\n  </script>\n\n  <script src=\"https://unpkg.com/d3@7.8.5/dist/d3.min.js\"></script>\n  <script src=\"https://unpkg.com/markmap-lib@0.15.3/dist/browser/index.js\"></script>\n  <script src=\"https://unpkg.com/markmap-view@0.15.3/dist/browser/index.js\"></script>\n</head>\n\n<body>\n  <div id=\"root\"></div>\n\n  <script>\n    (function () {\n      \"use strict\";\n\n      // 禁用常用快捷键\n      document.addEventListener(\"keydown\", function (e) {\n        // F12\n        if (e.keyCode === 123) {\n          e.preventDefault();\n          return false;\n        }\n\n        // Ctrl+U (查看源代码)\n        if (\n          e.ctrlKey &&\n          e.shiftKey &&\n          (e.keyCode === 73 || e.keyCode === 74 || e.keyCode === 67)\n        ) {\n          e.preventDefault();\n          return false;\n        }\n\n        // Ctrl+Shift+C (元素检查 - Mac)\n        if (e.metaKey && e.shiftKey && e.keyCode === 67) {\n          e.preventDefault();\n          return false;\n        }\n\n        // Ctrl+U (查看源代码)\n        if (e.ctrlKey && e.keyCode === 85) {\n          e.preventDefault();\n          return false;\n        }\n\n        // Mac Cmd+Option+I (开发者工具)\n        if (e.metaKey && e.altKey && e.keyCode === 73) {\n          e.preventDefault();\n          return false;\n        }\n      });\n\n      // 检测开发者工具 (通过窗口大小变化)\n      const devtools = {\n        open: false,\n        orientation: null,\n      };\n\n      const threshold = 160;\n\n      setInterval(function () {\n        const widthThreshold =\n          window.outerWidth - window.innerWidth > threshold;\n        const heightThreshold =\n          window.outerHeight - window.innerHeight > threshold;\n        const orientation = widthThreshold ? \"vertical\" : \"horizontal\";\n\n        if (\n          !(heightThreshold && widthThreshold) &&\n          ((window.Firebug &&\n            window.Firebug.chrome &&\n            window.Firebug.chrome.isInitialized) ||\n            widthThreshold ||\n            heightThreshold)\n        ) {\n          if (!devtools.open || devtools.orientation !== orientation) {\n            devtools.open = true;\n            devtools.orientation = orientation;\n          }\n        } else {\n          devtools.open = false;\n          devtools.orientation = null;\n        }\n      }, 500);\n\n      setInterval(function () {\n        const startTime = new Date().getTime();\n        debugger;\n        const endTime = new Date().getTime();\n        if (endTime - startTime > 100) {\n          // 刷新页面\n          window.location.reload();\n        }\n      }, 2000);\n\n      // 禁用拖拽\n      document.addEventListener(\"dragstart\", function (e) {\n        e.preventDefault();\n        return false;\n      });\n\n      console.log(\n        \"%cChattPlay\",\n        `padding: 10px 40px;\n        font-size: 24px;\n        font-weight: 600;\n        border-radius: 10px;\n        background-color:silver;\n        background-image:\n          radial-gradient(circle at 100% 150%, silver 24%, white 24%, white 28%, silver 28%, silver 36%, white 36%, white 40%, transparent 40%, transparent),\n          radial-gradient(circle at 0 150%, silver 24%, white 24%, white 28%, silver 28%, silver 36%, white 36%, white 40%, transparent 40%, transparent),\n          radial-gradient(circle at 50% 100%, white 10%, silver 10%, silver 23%, white 23%, white 30%, silver 30%, silver 43%, white 43%, white 50%, silver 50%, silver 63%, white 63%, white 71%, transparent 71%, transparent),\n          radial-gradient(circle at 100% 50%, white 5%, silver 5%, silver 15%, white 15%, white 20%, silver 20%, silver 29%, white 29%, white 34%, silver 34%, silver 44%, white 44%, white 49%, transparent 49%, transparent),\n          radial-gradient(circle at 0 50%, white 5%, silver 5%, silver 15%, white 15%, white 20%, silver 20%, silver 29%, white 29%, white 34%, silver 34%, silver 44%, white 44%, white 49%, transparent 49%, transparent);\n          background-size: 100px 50px;`,\n      );\n      console.log(\n        \"%c项目地址：https://github.com/P1kaj1uu/ChattyPlay-Agent\",\n        \"font-size: 16px; color: blue;\",\n      );\n      console.log(\n        \"%c欢迎大家提交 issue 和 PR，一起完善共建 ChattyPlay！\",\n        \"font-size: 16px; color: green;\",\n      );\n      console.log(\n        \"%c[Info] 作者：P1kaj1uu（微信号：Dveiklokk）\",\n        \"font-size: 16px; color: purple;\",\n      );\n    })();\n  </script>\n\n  <!-- Fundebug 错误监控 -->\n  <script async src=\"https://js.fundebug.cn/fundebug.2.8.8.min.js\"></script>\n\n  <!-- Cloudflare Turnstile 反机器人验证 -->\n  <script src=\"https://challenges.cloudflare.com/turnstile/v0/api.js\" async defer></script>\n  <!-- Fundebug 录屏插件 -->\n  <script async src=\"https://js.fundebug.cn/fundebug.revideo.0.8.0.min.js\"></script>\n  <script>\n    // 配置 Fundebug\n    fundebug.apikey =\n      \"fa-0aa5a027de384efbb4dc8a456c863526\";\n    fundebug.appversion = \"1.0.0\";\n\n    // 全局错误监听\n    // 监听未捕获的 Promise 错误\n    window.addEventListener(\"unhandledrejection\", function (event) {\n      fundebug.notifyError(event.reason, {\n        metaData: {\n          type: \"unhandledrejection\",\n        },\n      });\n    });\n\n    // 监听全局错误\n    window.addEventListener(\"error\", function (event) {\n      fundebug.notifyError(event.error || new Error(event.message), {\n        metaData: {\n          type: \"global error\",\n          filename: event.filename,\n          lineno: event.lineno,\n          colno: event.colno,\n        },\n      });\n    });\n  </script>\n\n  <script type=\"module\" src=\"/src/main.tsx\"></script>\n</body>\n\n</html>"
  },
  {
    "path": "jsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es5\",\n    \"module\": \"esnext\",\n    \"baseUrl\": \"./\",\n    \"moduleResolution\": \"node\",\n    \"paths\": {\n      \"@/*\": [\n        \"src/*\"\n      ]\n    },\n    \"lib\": [\n      \"esnext\",\n      \"dom\",\n      \"dom.iterable\",\n      \"scripthost\"\n    ]\n  }\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"chattyplay-agent\",\n  \"private\": true,\n  \"author\": {\n    \"name\": \"P1Kaj1uu\",\n    \"email\": \"891523233@qq.com\",\n    \"url\": \"https://github.com/P1Kaj1uu\"\n  },\n  \"version\": \"4.9.0\",\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"vite\",\n    \"dev:server\": \"tsx watch src/services/server.ts\",\n    \"build\": \"tsc && vite build\",\n    \"start\": \"tsx src/services/server.ts\",\n    \"lint\": \"eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0\",\n    \"preview\": \"vite preview\",\n    \"worker:dev\": \"wrangler dev src/services/worker.ts\",\n    \"worker:deploy\": \"wrangler deploy\",\n    \"worker:tail\": \"wrangler tail\"\n  },\n  \"dependencies\": {\n    \"@emailjs/browser\": \"^4.4.1\",\n    \"@hcaptcha/react-hcaptcha\": \"^2.0.2\",\n    \"@hono/node-server\": \"^1.19.9\",\n    \"@hono/node-ws\": \"^1.3.0\",\n    \"@monaco-editor/react\": \"^4.7.0\",\n    \"@react-oauth/google\": \"^0.13.4\",\n    \"@types/better-sqlite3\": \"^7.6.13\",\n    \"@types/three\": \"^0.182.0\",\n    \"@types/ws\": \"^8.18.1\",\n    \"@upstash/redis\": \"^1.37.0\",\n    \"@vercel/hono\": \"^0.2.51\",\n    \"antd\": \"^5.12.0\",\n    \"axios\": \"^1.6.0\",\n    \"better-sqlite3\": \"^12.6.2\",\n    \"crypto-js\": \"^4.2.0\",\n    \"echarts\": \"^6.0.0\",\n    \"echarts-for-react\": \"^3.0.6\",\n    \"fundebug-javascript\": \"^2.8.8\",\n    \"fundebug-revideo\": \"^0.8.0\",\n    \"gsap\": \"^3.14.2\",\n    \"highlight.js\": \"^11.9.0\",\n    \"hono\": \"^4.11.7\",\n    \"http-proxy-middleware\": \"^3.0.5\",\n    \"i18next\": \"^25.8.0\",\n    \"i18next-browser-languagedetector\": \"^8.2.0\",\n    \"marked\": \"^11.1.0\",\n    \"monaco-editor\": \"^0.55.1\",\n    \"nprogress\": \"^0.2.0\",\n    \"oh-my-live2d\": \"^0.19.3\",\n    \"openai\": \"^6.25.0\",\n    \"pdfjs-dist\": \"^5.6.205\",\n    \"react\": \"^18.2.0\",\n    \"react-dom\": \"^18.2.0\",\n    \"react-i18next\": \"^16.5.4\",\n    \"react-icons\": \"^5.5.0\",\n    \"react-pdf\": \"^10.4.1\",\n    \"react-router-dom\": \"^6.22.0\",\n    \"simplex-noise\": \"^4.0.3\",\n    \"styled-components\": \"^6.1.0\",\n    \"three\": \"^0.182.0\",\n    \"three-stdlib\": \"^2.36.1\",\n    \"vite-plugin-oh-my-live2d\": \"^0.19.3\",\n    \"ws\": \"^8.19.0\"\n  },\n  \"devDependencies\": {\n    \"@types/crypto-js\": \"^4.2.2\",\n    \"@types/node\": \"^25.2.1\",\n    \"@types/nprogress\": \"^0.2.3\",\n    \"@types/react\": \"^18.2.43\",\n    \"@types/react-dom\": \"^18.2.17\",\n    \"@types/styled-components\": \"^5.1.34\",\n    \"@typescript-eslint/eslint-plugin\": \"^6.14.0\",\n    \"@typescript-eslint/parser\": \"^6.14.0\",\n    \"@vitejs/plugin-react\": \"^4.2.1\",\n    \"autoprefixer\": \"^10.4.24\",\n    \"eslint\": \"^8.55.0\",\n    \"eslint-plugin-react-hooks\": \"^4.6.0\",\n    \"eslint-plugin-react-refresh\": \"^0.4.5\",\n    \"postcss\": \"^8.5.6\",\n    \"sass-embedded\": \"^1.97.3\",\n    \"tailwindcss\": \"^3.4.19\",\n    \"tsx\": \"^4.21.0\",\n    \"typescript\": \"^5.2.2\",\n    \"vite\": \"^5.0.8\",\n    \"wrangler\": \"^3.78.0\"\n  }\n}\n"
  },
  {
    "path": "postcss.config.js",
    "content": "export default {\n  plugins: {\n    tailwindcss: {},\n    autoprefixer: {},\n  },\n}\n"
  },
  {
    "path": "public/.htaccess",
    "content": "# Apache 配置文件 - 用于生产环境部署\n# 支持单页应用(SPA)路由和 API 代理\n\n# 启用代理模块\n<IfModule mod_proxy.c>\n  ProxyRequests Off\n  ProxyPreserveHost On\n\n  # API 代理到宝塔服务器 Hono 服务\n  ProxyPass /api http://123.60.91.107:3001/api\n  ProxyPassReverse /api http://123.60.91.107:3001/api\n</IfModule>\n\n# URL 重写规则\n<IfModule mod_rewrite.c>\n  RewriteEngine On\n\n  # API 请求代理到宝塔服务器（使用 RewriteRule 作为备用方案）\n  RewriteRule ^api/(.*)$ http://123.60.91.107:3001/api/$1 [P,L]\n\n  # SPA 路由支持 - 所有非文件、非API请求返回 index.html\n  RewriteCond %{REQUEST_FILENAME} !-f\n  RewriteCond %{REQUEST_FILENAME} !-d\n  RewriteCond %{REQUEST_URI} !^/api/\n  RewriteRule ^(.*)$ /index.html [L,QSA]\n</IfModule>\n\n# 缓存控制\n<IfModule mod_headers.c>\n  # 静态资源缓存\n  <FilesMatch \"\\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$\">\n    Header set Cache-Control \"max-age=31536000, public\"\n  </FilesMatch>\n\n  # HTML 文件不缓存\n  <FilesMatch \"\\.html$\">\n    Header set Cache-Control \"no-cache, no-store, must-revalidate\"\n  </FilesMatch>\n</IfModule>\n\n# Gzip 压缩\n<IfModule mod_deflate.c>\n  AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/json\n</IfModule>\n"
  },
  {
    "path": "public/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"\">\n  <head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\">\n    <link rel=\"icon\" href=\"<%= BASE_URL %>favicon.ico\">\n    <!-- <title><%= htmlWebpackPlugin.options.title %></title> -->\n    <link rel=\"stylesheet\" href=\"./layui/css/layui.css\">\n    <link rel=\"preconnect\" href=\"https://challenges.cloudflare.com\" />\n    <script src=\"./layui/layui.js\"></script>\n    <script src=\"./three/three.min.js\"></script>\n    <script src=\"./three/MeshSurfaceSampler.js\"></script>\n    <script src=\"./three/TrackballControls.js\"></script>\n    <script src=\"./three/simplex-noise.js\"></script>\n    <script src=\"./three/OBJLoader.js\"></script>\n    <script src=\"./three/gsap.min.js\"></script>\n    <script async src=\"https://unpkg.com/oh-my-live2d@latest\"></script>\n    <script async src=\"//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js\"></script>\n    <!-- Cloudflare Turnstile 反机器人验证 -->\n    <script src=\"https://challenges.cloudflare.com/turnstile/v0/api.js\" async defer></script>\n    <!-- Fundebug 错误监控 -->\n    <script async src=\"https://js.fundebug.cn/fundebug.2.8.8.min.js\"></script>\n    <!-- Fundebug 录屏插件 -->\n    <script async src=\"https://js.fundebug.cn/fundebug.revideo.0.8.0.min.js\"></script>\n    <title>不见水星记</title>\n  </head>\n  <body>\n    <noscript>\n      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>\n    </noscript>\n    <div id=\"app\"></div>\n    <!-- built files will be auto injected -->\n  </body>\n</html>\n"
  },
  {
    "path": "public/layui/css/layui.css",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n .layui-inline,img{display:inline-block;vertical-align:middle}.layui-rate,li{list-style:none}h1,h2,h3,h4,h5,h6{font-weight:400}.layui-edge,.layui-header,.layui-inline,.layui-main{position:relative}.layui-btn,.layui-edge,.layui-inline,img{vertical-align:middle}.layui-btn,.layui-disabled,.layui-icon,.layui-unselect{-webkit-user-select:none;-ms-user-select:none;-moz-user-select:none}blockquote,body,button,dd,div,dl,dt,form,h1,h2,h3,h4,h5,h6,input,li,ol,p,pre,td,textarea,th,ul{margin:0;padding:0;-webkit-tap-highlight-color:rgba(0,0,0,0)}a:active,a:hover{outline:0}img{border:none}table{border-collapse:collapse;border-spacing:0}h4,h5,h6{font-size:100%}button,input,optgroup,option,select,textarea{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;outline:0}pre{white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-word}body{line-height:24px;font:14px Helvetica Neue,Helvetica,PingFang SC,\\5FAE\\8F6F\\96C5\\9ED1,Tahoma,Arial,sans-serif}hr{height:1px;margin:10px 0;border:0;clear:both}a{color:#333;text-decoration:none}a:hover{color:#777}a cite{font-style:normal;*cursor:pointer}.layui-border-box,.layui-border-box *{box-sizing:border-box}.layui-box,.layui-box *{box-sizing:content-box}.layui-clear{clear:both;*zoom:1}.layui-clear:after{content:'\\20';clear:both;*zoom:1;display:block;height:0}.layui-inline{*display:inline;*zoom:1}.layui-edge{display:inline-block;width:0;height:0;border-width:6px;border-style:dashed;border-color:transparent;overflow:hidden}.layui-edge-top{top:-4px;border-bottom-color:#999;border-bottom-style:solid}.layui-edge-right{border-left-color:#999;border-left-style:solid}.layui-edge-bottom{top:2px;border-top-color:#999;border-top-style:solid}.layui-edge-left{border-right-color:#999;border-right-style:solid}.layui-elip{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-disabled,.layui-disabled:hover{color:#d2d2d2!important;cursor:not-allowed!important}.layui-circle{border-radius:100%}.layui-show{display:block!important}.layui-hide{display:none!important}@font-face{font-family:layui-icon;src:url(../font/iconfont.eot?v=230);src:url(../font/iconfont.eot?v=230#iefix) format('embedded-opentype'),url(../font/iconfont.svg?v=230#iconfont) format('svg'),url(../font/iconfont.woff?v=230) format('woff'),url(../font/iconfont.ttf?v=230) format('truetype')}.layui-icon{font-family:layui-icon!important;font-size:16px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.layui-icon-reply-fill:before{content:\"\\e611\"}.layui-icon-set-fill:before{content:\"\\e614\"}.layui-icon-menu-fill:before{content:\"\\e60f\"}.layui-icon-search:before{content:\"\\e615\"}.layui-icon-share:before{content:\"\\e641\"}.layui-icon-set-sm:before{content:\"\\e620\"}.layui-icon-engine:before{content:\"\\e628\"}.layui-icon-close:before{content:\"\\1006\"}.layui-icon-close-fill:before{content:\"\\1007\"}.layui-icon-chart-screen:before{content:\"\\e629\"}.layui-icon-star:before{content:\"\\e600\"}.layui-icon-circle-dot:before{content:\"\\e617\"}.layui-icon-chat:before{content:\"\\e606\"}.layui-icon-release:before{content:\"\\e609\"}.layui-icon-list:before{content:\"\\e60a\"}.layui-icon-chart:before{content:\"\\e62c\"}.layui-icon-ok-circle:before{content:\"\\1005\"}.layui-icon-layim-theme:before{content:\"\\e61b\"}.layui-icon-table:before{content:\"\\e62d\"}.layui-icon-right:before{content:\"\\e602\"}.layui-icon-left:before{content:\"\\e603\"}.layui-icon-cart-simple:before{content:\"\\e698\"}.layui-icon-face-cry:before{content:\"\\e69c\"}.layui-icon-face-smile:before{content:\"\\e6af\"}.layui-icon-survey:before{content:\"\\e6b2\"}.layui-icon-tree:before{content:\"\\e62e\"}.layui-icon-upload-circle:before{content:\"\\e62f\"}.layui-icon-add-circle:before{content:\"\\e61f\"}.layui-icon-download-circle:before{content:\"\\e601\"}.layui-icon-templeate-1:before{content:\"\\e630\"}.layui-icon-util:before{content:\"\\e631\"}.layui-icon-face-surprised:before{content:\"\\e664\"}.layui-icon-edit:before{content:\"\\e642\"}.layui-icon-speaker:before{content:\"\\e645\"}.layui-icon-down:before{content:\"\\e61a\"}.layui-icon-file:before{content:\"\\e621\"}.layui-icon-layouts:before{content:\"\\e632\"}.layui-icon-rate-half:before{content:\"\\e6c9\"}.layui-icon-add-circle-fine:before{content:\"\\e608\"}.layui-icon-prev-circle:before{content:\"\\e633\"}.layui-icon-read:before{content:\"\\e705\"}.layui-icon-404:before{content:\"\\e61c\"}.layui-icon-carousel:before{content:\"\\e634\"}.layui-icon-help:before{content:\"\\e607\"}.layui-icon-code-circle:before{content:\"\\e635\"}.layui-icon-water:before{content:\"\\e636\"}.layui-icon-username:before{content:\"\\e66f\"}.layui-icon-find-fill:before{content:\"\\e670\"}.layui-icon-about:before{content:\"\\e60b\"}.layui-icon-location:before{content:\"\\e715\"}.layui-icon-up:before{content:\"\\e619\"}.layui-icon-pause:before{content:\"\\e651\"}.layui-icon-date:before{content:\"\\e637\"}.layui-icon-layim-uploadfile:before{content:\"\\e61d\"}.layui-icon-delete:before{content:\"\\e640\"}.layui-icon-play:before{content:\"\\e652\"}.layui-icon-top:before{content:\"\\e604\"}.layui-icon-friends:before{content:\"\\e612\"}.layui-icon-refresh-3:before{content:\"\\e9aa\"}.layui-icon-ok:before{content:\"\\e605\"}.layui-icon-layer:before{content:\"\\e638\"}.layui-icon-face-smile-fine:before{content:\"\\e60c\"}.layui-icon-dollar:before{content:\"\\e659\"}.layui-icon-group:before{content:\"\\e613\"}.layui-icon-layim-download:before{content:\"\\e61e\"}.layui-icon-picture-fine:before{content:\"\\e60d\"}.layui-icon-link:before{content:\"\\e64c\"}.layui-icon-diamond:before{content:\"\\e735\"}.layui-icon-log:before{content:\"\\e60e\"}.layui-icon-rate-solid:before{content:\"\\e67a\"}.layui-icon-fonts-del:before{content:\"\\e64f\"}.layui-icon-unlink:before{content:\"\\e64d\"}.layui-icon-fonts-clear:before{content:\"\\e639\"}.layui-icon-triangle-r:before{content:\"\\e623\"}.layui-icon-circle:before{content:\"\\e63f\"}.layui-icon-radio:before{content:\"\\e643\"}.layui-icon-align-center:before{content:\"\\e647\"}.layui-icon-align-right:before{content:\"\\e648\"}.layui-icon-align-left:before{content:\"\\e649\"}.layui-icon-loading-1:before{content:\"\\e63e\"}.layui-icon-return:before{content:\"\\e65c\"}.layui-icon-fonts-strong:before{content:\"\\e62b\"}.layui-icon-upload:before{content:\"\\e67c\"}.layui-icon-dialogue:before{content:\"\\e63a\"}.layui-icon-video:before{content:\"\\e6ed\"}.layui-icon-headset:before{content:\"\\e6fc\"}.layui-icon-cellphone-fine:before{content:\"\\e63b\"}.layui-icon-add-1:before{content:\"\\e654\"}.layui-icon-face-smile-b:before{content:\"\\e650\"}.layui-icon-fonts-html:before{content:\"\\e64b\"}.layui-icon-form:before{content:\"\\e63c\"}.layui-icon-cart:before{content:\"\\e657\"}.layui-icon-camera-fill:before{content:\"\\e65d\"}.layui-icon-tabs:before{content:\"\\e62a\"}.layui-icon-fonts-code:before{content:\"\\e64e\"}.layui-icon-fire:before{content:\"\\e756\"}.layui-icon-set:before{content:\"\\e716\"}.layui-icon-fonts-u:before{content:\"\\e646\"}.layui-icon-triangle-d:before{content:\"\\e625\"}.layui-icon-tips:before{content:\"\\e702\"}.layui-icon-picture:before{content:\"\\e64a\"}.layui-icon-more-vertical:before{content:\"\\e671\"}.layui-icon-flag:before{content:\"\\e66c\"}.layui-icon-loading:before{content:\"\\e63d\"}.layui-icon-fonts-i:before{content:\"\\e644\"}.layui-icon-refresh-1:before{content:\"\\e666\"}.layui-icon-rmb:before{content:\"\\e65e\"}.layui-icon-home:before{content:\"\\e68e\"}.layui-icon-user:before{content:\"\\e770\"}.layui-icon-notice:before{content:\"\\e667\"}.layui-icon-login-weibo:before{content:\"\\e675\"}.layui-icon-voice:before{content:\"\\e688\"}.layui-icon-upload-drag:before{content:\"\\e681\"}.layui-icon-login-qq:before{content:\"\\e676\"}.layui-icon-snowflake:before{content:\"\\e6b1\"}.layui-icon-file-b:before{content:\"\\e655\"}.layui-icon-template:before{content:\"\\e663\"}.layui-icon-auz:before{content:\"\\e672\"}.layui-icon-console:before{content:\"\\e665\"}.layui-icon-app:before{content:\"\\e653\"}.layui-icon-prev:before{content:\"\\e65a\"}.layui-icon-website:before{content:\"\\e7ae\"}.layui-icon-next:before{content:\"\\e65b\"}.layui-icon-component:before{content:\"\\e857\"}.layui-icon-more:before{content:\"\\e65f\"}.layui-icon-login-wechat:before{content:\"\\e677\"}.layui-icon-shrink-right:before{content:\"\\e668\"}.layui-icon-spread-left:before{content:\"\\e66b\"}.layui-icon-camera:before{content:\"\\e660\"}.layui-icon-note:before{content:\"\\e66e\"}.layui-icon-refresh:before{content:\"\\e669\"}.layui-icon-female:before{content:\"\\e661\"}.layui-icon-male:before{content:\"\\e662\"}.layui-icon-password:before{content:\"\\e673\"}.layui-icon-senior:before{content:\"\\e674\"}.layui-icon-theme:before{content:\"\\e66a\"}.layui-icon-tread:before{content:\"\\e6c5\"}.layui-icon-praise:before{content:\"\\e6c6\"}.layui-icon-star-fill:before{content:\"\\e658\"}.layui-icon-rate:before{content:\"\\e67b\"}.layui-icon-template-1:before{content:\"\\e656\"}.layui-icon-vercode:before{content:\"\\e679\"}.layui-icon-cellphone:before{content:\"\\e678\"}.layui-icon-screen-full:before{content:\"\\e622\"}.layui-icon-screen-restore:before{content:\"\\e758\"}.layui-main{width:1140px;margin:0 auto}.layui-header{z-index:1000;height:60px}.layui-header a:hover{transition:all .5s;-webkit-transition:all .5s}.layui-side{position:fixed;left:0;top:0;bottom:0;z-index:999;width:200px;overflow-x:hidden}.layui-side-scroll{position:relative;width:220px;height:100%;overflow-x:hidden}.layui-body{position:absolute;left:200px;right:0;top:0;bottom:0;z-index:998;width:auto;overflow:hidden;overflow-y:auto;box-sizing:border-box}.layui-layout-body{overflow:hidden}.layui-layout-admin .layui-header{background-color:#23262E}.layui-layout-admin .layui-side{top:60px;width:200px;overflow-x:hidden}.layui-layout-admin .layui-body{top:60px;bottom:44px}.layui-layout-admin .layui-main{width:auto;margin:0 15px}.layui-layout-admin .layui-footer{position:fixed;left:200px;right:0;bottom:0;height:44px;line-height:44px;padding:0 15px;background-color:#eee}.layui-layout-admin .layui-logo{position:absolute;left:0;top:0;width:200px;height:100%;line-height:60px;text-align:center;color:#009688;font-size:16px}.layui-layout-admin .layui-header .layui-nav{background:0 0}.layui-layout-left{position:absolute!important;left:200px;top:0}.layui-layout-right{position:absolute!important;right:0;top:0}.layui-container{position:relative;margin:0 auto;padding:0 15px;box-sizing:border-box}.layui-fluid{position:relative;margin:0 auto;padding:0 15px}.layui-row:after,.layui-row:before{content:'';display:block;clear:both}.layui-col-lg1,.layui-col-lg10,.layui-col-lg11,.layui-col-lg12,.layui-col-lg2,.layui-col-lg3,.layui-col-lg4,.layui-col-lg5,.layui-col-lg6,.layui-col-lg7,.layui-col-lg8,.layui-col-lg9,.layui-col-md1,.layui-col-md10,.layui-col-md11,.layui-col-md12,.layui-col-md2,.layui-col-md3,.layui-col-md4,.layui-col-md5,.layui-col-md6,.layui-col-md7,.layui-col-md8,.layui-col-md9,.layui-col-sm1,.layui-col-sm10,.layui-col-sm11,.layui-col-sm12,.layui-col-sm2,.layui-col-sm3,.layui-col-sm4,.layui-col-sm5,.layui-col-sm6,.layui-col-sm7,.layui-col-sm8,.layui-col-sm9,.layui-col-xs1,.layui-col-xs10,.layui-col-xs11,.layui-col-xs12,.layui-col-xs2,.layui-col-xs3,.layui-col-xs4,.layui-col-xs5,.layui-col-xs6,.layui-col-xs7,.layui-col-xs8,.layui-col-xs9{position:relative;display:block;box-sizing:border-box}.layui-col-xs1,.layui-col-xs10,.layui-col-xs11,.layui-col-xs12,.layui-col-xs2,.layui-col-xs3,.layui-col-xs4,.layui-col-xs5,.layui-col-xs6,.layui-col-xs7,.layui-col-xs8,.layui-col-xs9{float:left}.layui-col-xs1{width:8.33333333%}.layui-col-xs2{width:16.66666667%}.layui-col-xs3{width:25%}.layui-col-xs4{width:33.33333333%}.layui-col-xs5{width:41.66666667%}.layui-col-xs6{width:50%}.layui-col-xs7{width:58.33333333%}.layui-col-xs8{width:66.66666667%}.layui-col-xs9{width:75%}.layui-col-xs10{width:83.33333333%}.layui-col-xs11{width:91.66666667%}.layui-col-xs12{width:100%}.layui-col-xs-offset1{margin-left:8.33333333%}.layui-col-xs-offset2{margin-left:16.66666667%}.layui-col-xs-offset3{margin-left:25%}.layui-col-xs-offset4{margin-left:33.33333333%}.layui-col-xs-offset5{margin-left:41.66666667%}.layui-col-xs-offset6{margin-left:50%}.layui-col-xs-offset7{margin-left:58.33333333%}.layui-col-xs-offset8{margin-left:66.66666667%}.layui-col-xs-offset9{margin-left:75%}.layui-col-xs-offset10{margin-left:83.33333333%}.layui-col-xs-offset11{margin-left:91.66666667%}.layui-col-xs-offset12{margin-left:100%}@media screen and (max-width:768px){.layui-hide-xs{display:none!important}.layui-show-xs-block{display:block!important}.layui-show-xs-inline{display:inline!important}.layui-show-xs-inline-block{display:inline-block!important}}@media screen and (min-width:768px){.layui-container{width:750px}.layui-hide-sm{display:none!important}.layui-show-sm-block{display:block!important}.layui-show-sm-inline{display:inline!important}.layui-show-sm-inline-block{display:inline-block!important}.layui-col-sm1,.layui-col-sm10,.layui-col-sm11,.layui-col-sm12,.layui-col-sm2,.layui-col-sm3,.layui-col-sm4,.layui-col-sm5,.layui-col-sm6,.layui-col-sm7,.layui-col-sm8,.layui-col-sm9{float:left}.layui-col-sm1{width:8.33333333%}.layui-col-sm2{width:16.66666667%}.layui-col-sm3{width:25%}.layui-col-sm4{width:33.33333333%}.layui-col-sm5{width:41.66666667%}.layui-col-sm6{width:50%}.layui-col-sm7{width:58.33333333%}.layui-col-sm8{width:66.66666667%}.layui-col-sm9{width:75%}.layui-col-sm10{width:83.33333333%}.layui-col-sm11{width:91.66666667%}.layui-col-sm12{width:100%}.layui-col-sm-offset1{margin-left:8.33333333%}.layui-col-sm-offset2{margin-left:16.66666667%}.layui-col-sm-offset3{margin-left:25%}.layui-col-sm-offset4{margin-left:33.33333333%}.layui-col-sm-offset5{margin-left:41.66666667%}.layui-col-sm-offset6{margin-left:50%}.layui-col-sm-offset7{margin-left:58.33333333%}.layui-col-sm-offset8{margin-left:66.66666667%}.layui-col-sm-offset9{margin-left:75%}.layui-col-sm-offset10{margin-left:83.33333333%}.layui-col-sm-offset11{margin-left:91.66666667%}.layui-col-sm-offset12{margin-left:100%}}@media screen and (min-width:992px){.layui-container{width:970px}.layui-hide-md{display:none!important}.layui-show-md-block{display:block!important}.layui-show-md-inline{display:inline!important}.layui-show-md-inline-block{display:inline-block!important}.layui-col-md1,.layui-col-md10,.layui-col-md11,.layui-col-md12,.layui-col-md2,.layui-col-md3,.layui-col-md4,.layui-col-md5,.layui-col-md6,.layui-col-md7,.layui-col-md8,.layui-col-md9{float:left}.layui-col-md1{width:8.33333333%}.layui-col-md2{width:16.66666667%}.layui-col-md3{width:25%}.layui-col-md4{width:33.33333333%}.layui-col-md5{width:41.66666667%}.layui-col-md6{width:50%}.layui-col-md7{width:58.33333333%}.layui-col-md8{width:66.66666667%}.layui-col-md9{width:75%}.layui-col-md10{width:83.33333333%}.layui-col-md11{width:91.66666667%}.layui-col-md12{width:100%}.layui-col-md-offset1{margin-left:8.33333333%}.layui-col-md-offset2{margin-left:16.66666667%}.layui-col-md-offset3{margin-left:25%}.layui-col-md-offset4{margin-left:33.33333333%}.layui-col-md-offset5{margin-left:41.66666667%}.layui-col-md-offset6{margin-left:50%}.layui-col-md-offset7{margin-left:58.33333333%}.layui-col-md-offset8{margin-left:66.66666667%}.layui-col-md-offset9{margin-left:75%}.layui-col-md-offset10{margin-left:83.33333333%}.layui-col-md-offset11{margin-left:91.66666667%}.layui-col-md-offset12{margin-left:100%}}@media screen and (min-width:1200px){.layui-container{width:1170px}.layui-hide-lg{display:none!important}.layui-show-lg-block{display:block!important}.layui-show-lg-inline{display:inline!important}.layui-show-lg-inline-block{display:inline-block!important}.layui-col-lg1,.layui-col-lg10,.layui-col-lg11,.layui-col-lg12,.layui-col-lg2,.layui-col-lg3,.layui-col-lg4,.layui-col-lg5,.layui-col-lg6,.layui-col-lg7,.layui-col-lg8,.layui-col-lg9{float:left}.layui-col-lg1{width:8.33333333%}.layui-col-lg2{width:16.66666667%}.layui-col-lg3{width:25%}.layui-col-lg4{width:33.33333333%}.layui-col-lg5{width:41.66666667%}.layui-col-lg6{width:50%}.layui-col-lg7{width:58.33333333%}.layui-col-lg8{width:66.66666667%}.layui-col-lg9{width:75%}.layui-col-lg10{width:83.33333333%}.layui-col-lg11{width:91.66666667%}.layui-col-lg12{width:100%}.layui-col-lg-offset1{margin-left:8.33333333%}.layui-col-lg-offset2{margin-left:16.66666667%}.layui-col-lg-offset3{margin-left:25%}.layui-col-lg-offset4{margin-left:33.33333333%}.layui-col-lg-offset5{margin-left:41.66666667%}.layui-col-lg-offset6{margin-left:50%}.layui-col-lg-offset7{margin-left:58.33333333%}.layui-col-lg-offset8{margin-left:66.66666667%}.layui-col-lg-offset9{margin-left:75%}.layui-col-lg-offset10{margin-left:83.33333333%}.layui-col-lg-offset11{margin-left:91.66666667%}.layui-col-lg-offset12{margin-left:100%}}.layui-col-space1{margin:-.5px}.layui-col-space1>*{padding:.5px}.layui-col-space3{margin:-1.5px}.layui-col-space3>*{padding:1.5px}.layui-col-space5{margin:-2.5px}.layui-col-space5>*{padding:2.5px}.layui-col-space8{margin:-3.5px}.layui-col-space8>*{padding:3.5px}.layui-col-space10{margin:-5px}.layui-col-space10>*{padding:5px}.layui-col-space12{margin:-6px}.layui-col-space12>*{padding:6px}.layui-col-space15{margin:-7.5px}.layui-col-space15>*{padding:7.5px}.layui-col-space18{margin:-9px}.layui-col-space18>*{padding:9px}.layui-col-space20{margin:-10px}.layui-col-space20>*{padding:10px}.layui-col-space22{margin:-11px}.layui-col-space22>*{padding:11px}.layui-col-space25{margin:-12.5px}.layui-col-space25>*{padding:12.5px}.layui-col-space30{margin:-15px}.layui-col-space30>*{padding:15px}.layui-btn,.layui-input,.layui-select,.layui-textarea,.layui-upload-button{outline:0;-webkit-appearance:none;transition:all .3s;-webkit-transition:all .3s;box-sizing:border-box}.layui-elem-quote{margin-bottom:10px;padding:15px;line-height:22px;border-left:5px solid #009688;border-radius:0 2px 2px 0;background-color:#f2f2f2}.layui-quote-nm{border-style:solid;border-width:1px 1px 1px 5px;background:0 0}.layui-elem-field{margin-bottom:10px;padding:0;border-width:1px;border-style:solid}.layui-elem-field legend{margin-left:20px;padding:0 10px;font-size:20px;font-weight:300}.layui-field-title{margin:10px 0 20px;border-width:1px 0 0}.layui-field-box{padding:10px 15px}.layui-field-title .layui-field-box{padding:10px 0}.layui-progress{position:relative;height:6px;border-radius:20px;background-color:#e2e2e2}.layui-progress-bar{position:absolute;left:0;top:0;width:0;max-width:100%;height:6px;border-radius:20px;text-align:right;background-color:#5FB878;transition:all .3s;-webkit-transition:all .3s}.layui-progress-big,.layui-progress-big .layui-progress-bar{height:18px;line-height:18px}.layui-progress-text{position:relative;top:-20px;line-height:18px;font-size:12px;color:#666}.layui-progress-big .layui-progress-text{position:static;padding:0 10px;color:#fff}.layui-collapse{border-width:1px;border-style:solid;border-radius:2px}.layui-colla-content,.layui-colla-item{border-top-width:1px;border-top-style:solid}.layui-colla-item:first-child{border-top:none}.layui-colla-title{position:relative;height:42px;line-height:42px;padding:0 15px 0 35px;color:#333;background-color:#f2f2f2;cursor:pointer;font-size:14px;overflow:hidden}.layui-colla-content{display:none;padding:10px 15px;line-height:22px;color:#666}.layui-colla-icon{position:absolute;left:15px;top:0;font-size:14px}.layui-card-body,.layui-card-header,.layui-form-label,.layui-form-mid,.layui-form-select,.layui-input-block,.layui-input-inline,.layui-textarea{position:relative}.layui-card{margin-bottom:15px;border-radius:2px;background-color:#fff;box-shadow:0 1px 2px 0 rgba(0,0,0,.05)}.layui-card:last-child{margin-bottom:0}.layui-card-header{height:42px;line-height:42px;padding:0 15px;border-bottom:1px solid #f6f6f6;color:#333;border-radius:2px 2px 0 0;font-size:14px}.layui-bg-black,.layui-bg-blue,.layui-bg-cyan,.layui-bg-green,.layui-bg-orange,.layui-bg-red{color:#fff!important}.layui-card-body{padding:10px 15px;line-height:24px}.layui-card-body[pad15]{padding:15px}.layui-card-body[pad20]{padding:20px}.layui-card-body .layui-table{margin:5px 0}.layui-card .layui-tab{margin:0}.layui-panel-window{position:relative;padding:15px;border-radius:0;border-top:5px solid #E6E6E6;background-color:#fff}.layui-bg-red{background-color:#FF5722!important}.layui-bg-orange{background-color:#FFB800!important}.layui-bg-green{background-color:#009688!important}.layui-bg-cyan{background-color:#2F4056!important}.layui-bg-blue{background-color:#1E9FFF!important}.layui-bg-black{background-color:#393D49!important}.layui-bg-gray{background-color:#eee!important;color:#666!important}.layui-badge-rim,.layui-colla-content,.layui-colla-item,.layui-collapse,.layui-elem-field,.layui-form-pane .layui-form-item[pane],.layui-form-pane .layui-form-label,.layui-input,.layui-layedit,.layui-layedit-tool,.layui-quote-nm,.layui-select,.layui-tab-bar,.layui-tab-card,.layui-tab-title,.layui-tab-title .layui-this:after,.layui-textarea{border-color:#e6e6e6}.layui-timeline-item:before,hr{background-color:#e6e6e6}.layui-text{line-height:22px;font-size:14px;color:#666}.layui-text h1,.layui-text h2,.layui-text h3{font-weight:500;color:#333}.layui-text h1{font-size:30px}.layui-text h2{font-size:24px}.layui-text h3{font-size:18px}.layui-text a:not(.layui-btn){color:#01AAED}.layui-text a:not(.layui-btn):hover{text-decoration:underline}.layui-text ul{padding:5px 0 5px 15px}.layui-text ul li{margin-top:5px;list-style-type:disc}.layui-text em,.layui-word-aux{color:#999!important;padding:0 5px!important}.layui-btn{display:inline-block;height:38px;line-height:38px;padding:0 18px;background-color:#009688;color:#fff;white-space:nowrap;text-align:center;font-size:14px;border:none;border-radius:2px;cursor:pointer}.layui-btn:hover{opacity:.8;filter:alpha(opacity=80);color:#fff}.layui-btn:active{opacity:1;filter:alpha(opacity=100)}.layui-btn+.layui-btn{margin-left:10px}.layui-btn-container{font-size:0}.layui-btn-container .layui-btn{margin-right:10px;margin-bottom:10px}.layui-btn-container .layui-btn+.layui-btn{margin-left:0}.layui-table .layui-btn-container .layui-btn{margin-bottom:9px}.layui-btn-radius{border-radius:100px}.layui-btn .layui-icon{margin-right:3px;font-size:18px;vertical-align:bottom;vertical-align:middle\\9}.layui-btn-primary{border:1px solid #C9C9C9;background-color:#fff;color:#555}.layui-btn-primary:hover{border-color:#009688;color:#333}.layui-btn-normal{background-color:#1E9FFF}.layui-btn-warm{background-color:#FFB800}.layui-btn-danger{background-color:#FF5722}.layui-btn-disabled,.layui-btn-disabled:active,.layui-btn-disabled:hover{border:1px solid #e6e6e6;background-color:#FBFBFB;color:#C9C9C9;cursor:not-allowed;opacity:1}.layui-btn-lg{height:44px;line-height:44px;padding:0 25px;font-size:16px}.layui-btn-sm{height:30px;line-height:30px;padding:0 10px;font-size:12px}.layui-btn-sm i{font-size:16px!important}.layui-btn-xs{height:22px;line-height:22px;padding:0 5px;font-size:12px}.layui-btn-xs i{font-size:14px!important}.layui-btn-group{display:inline-block;vertical-align:middle;font-size:0}.layui-btn-group .layui-btn{margin-left:0!important;margin-right:0!important;border-left:1px solid rgba(255,255,255,.5);border-radius:0}.layui-btn-group .layui-btn-primary{border-left:none}.layui-btn-group .layui-btn-primary:hover{border-color:#C9C9C9;color:#009688}.layui-btn-group .layui-btn:first-child{border-left:none;border-radius:2px 0 0 2px}.layui-btn-group .layui-btn-primary:first-child{border-left:1px solid #c9c9c9}.layui-btn-group .layui-btn:last-child{border-radius:0 2px 2px 0}.layui-btn-group .layui-btn+.layui-btn{margin-left:0}.layui-btn-group+.layui-btn-group{margin-left:10px}.layui-btn-fluid{width:100%}.layui-input,.layui-select,.layui-textarea{height:38px;line-height:1.3;line-height:38px\\9;border-width:1px;border-style:solid;background-color:#fff;border-radius:2px}.layui-input::-webkit-input-placeholder,.layui-select::-webkit-input-placeholder,.layui-textarea::-webkit-input-placeholder{line-height:1.3}.layui-input,.layui-textarea{display:block;width:100%;padding-left:10px}.layui-input:hover,.layui-textarea:hover{border-color:#D2D2D2!important}.layui-input:focus,.layui-textarea:focus{border-color:#C9C9C9!important}.layui-textarea{min-height:100px;height:auto;line-height:20px;padding:6px 10px;resize:vertical}.layui-select{padding:0 10px}.layui-form input[type=checkbox],.layui-form input[type=radio],.layui-form select{display:none}.layui-form [lay-ignore]{display:initial}.layui-form-item{margin-bottom:15px;clear:both;*zoom:1}.layui-form-item:after{content:'\\20';clear:both;*zoom:1;display:block;height:0}.layui-form-label{float:left;display:block;padding:9px 15px;width:80px;font-weight:400;line-height:20px;text-align:right}.layui-form-label-col{display:block;float:none;padding:9px 0;line-height:20px;text-align:left}.layui-form-item .layui-inline{margin-bottom:5px;margin-right:10px}.layui-input-block{margin-left:110px;min-height:36px}.layui-input-inline{display:inline-block;vertical-align:middle}.layui-form-item .layui-input-inline{float:left;width:190px;margin-right:10px}.layui-form-text .layui-input-inline{width:auto}.layui-form-mid{float:left;display:block;padding:9px 0!important;line-height:20px;margin-right:10px}.layui-form-danger+.layui-form-select .layui-input,.layui-form-danger:focus{border-color:#FF5722!important}.layui-form-select .layui-input{padding-right:30px;cursor:pointer}.layui-form-select .layui-edge{position:absolute;right:10px;top:50%;margin-top:-3px;cursor:pointer;border-width:6px;border-top-color:#c2c2c2;border-top-style:solid;transition:all .3s;-webkit-transition:all .3s}.layui-form-select dl{display:none;position:absolute;left:0;top:42px;padding:5px 0;z-index:999;min-width:100%;border:1px solid #d2d2d2;max-height:300px;overflow-y:auto;background-color:#fff;border-radius:2px;box-shadow:0 2px 4px rgba(0,0,0,.12);box-sizing:border-box}.layui-form-select dl dd,.layui-form-select dl dt{padding:0 10px;line-height:36px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.layui-form-select dl dt{font-size:12px;color:#999}.layui-form-select dl dd{cursor:pointer}.layui-form-select dl dd:hover{background-color:#f2f2f2}.layui-form-select .layui-select-group dd{padding-left:20px}.layui-form-select dl dd.layui-select-tips{padding-left:10px!important;color:#999}.layui-form-select dl dd.layui-this{background-color:#5FB878;color:#fff}.layui-form-checkbox,.layui-form-select dl dd.layui-disabled{background-color:#fff}.layui-form-selected dl{display:block}.layui-form-checkbox,.layui-form-checkbox *,.layui-form-switch{display:inline-block;vertical-align:middle}.layui-form-selected .layui-edge{margin-top:-9px;-webkit-transform:rotate(180deg);transform:rotate(180deg);margin-top:-3px\\9}:root .layui-form-selected .layui-edge{margin-top:-9px\\0/IE9}.layui-form-selectup dl{top:auto;bottom:42px}.layui-select-none{margin:5px 0;text-align:center;color:#999}.layui-select-disabled .layui-disabled{border-color:#eee!important}.layui-select-disabled .layui-edge{border-top-color:#d2d2d2}.layui-form-checkbox{position:relative;height:30px;line-height:30px;margin-right:10px;padding-right:30px;cursor:pointer;font-size:0;-webkit-transition:.1s linear;transition:.1s linear;box-sizing:border-box}.layui-form-checkbox span{padding:0 10px;height:100%;font-size:14px;border-radius:2px 0 0 2px;background-color:#d2d2d2;color:#fff;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.layui-form-checkbox:hover span{background-color:#c2c2c2}.layui-form-checkbox i{position:absolute;right:0;top:0;width:30px;height:28px;border:1px solid #d2d2d2;border-left:none;border-radius:0 2px 2px 0;color:#fff;font-size:20px;text-align:center}.layui-form-checkbox:hover i{border-color:#c2c2c2;color:#c2c2c2}.layui-form-checked,.layui-form-checked:hover{border-color:#5FB878}.layui-form-checked span,.layui-form-checked:hover span{background-color:#5FB878}.layui-form-checked i,.layui-form-checked:hover i{color:#5FB878}.layui-form-item .layui-form-checkbox{margin-top:4px}.layui-form-checkbox[lay-skin=primary]{height:auto!important;line-height:normal!important;border:none!important;margin-right:0;padding-right:0;background:0 0}.layui-form-checkbox[lay-skin=primary] span{float:right;padding-right:15px;line-height:18px;background:0 0;color:#666}.layui-form-checkbox[lay-skin=primary] i{position:relative;top:0;width:16px;height:16px;line-height:16px;border:1px solid #d2d2d2;font-size:12px;border-radius:2px;background-color:#fff;-webkit-transition:.1s linear;transition:.1s linear}.layui-form-checkbox[lay-skin=primary]:hover i{border-color:#5FB878;color:#fff}.layui-form-checked[lay-skin=primary] i{border-color:#5FB878;background-color:#5FB878;color:#fff}.layui-checkbox-disbaled[lay-skin=primary] span{background:0 0!important;color:#c2c2c2}.layui-checkbox-disbaled[lay-skin=primary]:hover i{border-color:#d2d2d2}.layui-form-item .layui-form-checkbox[lay-skin=primary]{margin-top:10px}.layui-form-switch{position:relative;height:22px;line-height:22px;min-width:35px;padding:0 5px;margin-top:8px;border:1px solid #d2d2d2;border-radius:20px;cursor:pointer;background-color:#fff;-webkit-transition:.1s linear;transition:.1s linear}.layui-form-switch i{position:absolute;left:5px;top:3px;width:16px;height:16px;border-radius:20px;background-color:#d2d2d2;-webkit-transition:.1s linear;transition:.1s linear}.layui-form-switch em{position:relative;top:0;width:25px;margin-left:21px;padding:0!important;text-align:center!important;color:#999!important;font-style:normal!important;font-size:12px}.layui-form-onswitch{border-color:#5FB878;background-color:#5FB878}.layui-checkbox-disbaled,.layui-checkbox-disbaled i{border-color:#e2e2e2!important}.layui-form-onswitch i{left:100%;margin-left:-21px;background-color:#fff}.layui-form-onswitch em{margin-left:5px;margin-right:21px;color:#fff!important}.layui-checkbox-disbaled span{background-color:#e2e2e2!important}.layui-checkbox-disbaled:hover i{color:#fff!important}[lay-radio]{display:none}.layui-form-radio,.layui-form-radio *{display:inline-block;vertical-align:middle}.layui-form-radio{line-height:28px;margin:6px 10px 0 0;padding-right:10px;cursor:pointer;font-size:0}.layui-form-radio *{font-size:14px}.layui-form-radio>i{margin-right:8px;font-size:22px;color:#c2c2c2}.layui-form-radio>i:hover,.layui-form-radioed>i{color:#5FB878}.layui-radio-disbaled>i{color:#e2e2e2!important}.layui-form-pane .layui-form-label{width:110px;padding:8px 15px;height:38px;line-height:20px;border-width:1px;border-style:solid;border-radius:2px 0 0 2px;text-align:center;background-color:#FBFBFB;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;box-sizing:border-box}.layui-form-pane .layui-input-inline{margin-left:-1px}.layui-form-pane .layui-input-block{margin-left:110px;left:-1px}.layui-form-pane .layui-input{border-radius:0 2px 2px 0}.layui-form-pane .layui-form-text .layui-form-label{float:none;width:100%;border-radius:2px;box-sizing:border-box;text-align:left}.layui-form-pane .layui-form-text .layui-input-inline{display:block;margin:0;top:-1px;clear:both}.layui-form-pane .layui-form-text .layui-input-block{margin:0;left:0;top:-1px}.layui-form-pane .layui-form-text .layui-textarea{min-height:100px;border-radius:0 0 2px 2px}.layui-form-pane .layui-form-checkbox{margin:4px 0 4px 10px}.layui-form-pane .layui-form-radio,.layui-form-pane .layui-form-switch{margin-top:6px;margin-left:10px}.layui-form-pane .layui-form-item[pane]{position:relative;border-width:1px;border-style:solid}.layui-form-pane .layui-form-item[pane] .layui-form-label{position:absolute;left:0;top:0;height:100%;border-width:0 1px 0 0}.layui-form-pane .layui-form-item[pane] .layui-input-inline{margin-left:110px}@media screen and (max-width:450px){.layui-form-item .layui-form-label{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-form-item .layui-inline{display:block;margin-right:0;margin-bottom:20px;clear:both}.layui-form-item .layui-inline:after{content:'\\20';clear:both;display:block;height:0}.layui-form-item .layui-input-inline{display:block;float:none;left:-3px;width:auto;margin:0 0 10px 112px}.layui-form-item .layui-input-inline+.layui-form-mid{margin-left:110px;top:-5px;padding:0}.layui-form-item .layui-form-checkbox{margin-right:5px;margin-bottom:5px}}.layui-layedit{border-width:1px;border-style:solid;border-radius:2px}.layui-layedit-tool{padding:3px 5px;border-bottom-width:1px;border-bottom-style:solid;font-size:0}.layedit-tool-fixed{position:fixed;top:0;border-top:1px solid #e2e2e2}.layui-layedit-tool .layedit-tool-mid,.layui-layedit-tool .layui-icon{display:inline-block;vertical-align:middle;text-align:center;font-size:14px}.layui-layedit-tool .layui-icon{position:relative;width:32px;height:30px;line-height:30px;margin:3px 5px;color:#777;cursor:pointer;border-radius:2px}.layui-layedit-tool .layui-icon:hover{color:#393D49}.layui-layedit-tool .layui-icon:active{color:#000}.layui-layedit-tool .layedit-tool-active{background-color:#e2e2e2;color:#000}.layui-layedit-tool .layui-disabled,.layui-layedit-tool .layui-disabled:hover{color:#d2d2d2;cursor:not-allowed}.layui-layedit-tool .layedit-tool-mid{width:1px;height:18px;margin:0 10px;background-color:#d2d2d2}.layedit-tool-html{width:50px!important;font-size:30px!important}.layedit-tool-b,.layedit-tool-code,.layedit-tool-help{font-size:16px!important}.layedit-tool-d,.layedit-tool-face,.layedit-tool-image,.layedit-tool-unlink{font-size:18px!important}.layedit-tool-image input{position:absolute;font-size:0;left:0;top:0;width:100%;height:100%;opacity:.01;filter:Alpha(opacity=1);cursor:pointer}.layui-layedit-iframe iframe{display:block;width:100%}#LAY_layedit_code{overflow:hidden}.layui-laypage{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;margin:10px 0;font-size:0}.layui-laypage>a:first-child,.layui-laypage>a:first-child em{border-radius:2px 0 0 2px}.layui-laypage>a:last-child,.layui-laypage>a:last-child em{border-radius:0 2px 2px 0}.layui-laypage>:first-child{margin-left:0!important}.layui-laypage>:last-child{margin-right:0!important}.layui-laypage a,.layui-laypage button,.layui-laypage input,.layui-laypage select,.layui-laypage span{border:1px solid #e2e2e2}.layui-laypage a,.layui-laypage span{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;padding:0 15px;height:28px;line-height:28px;margin:0 -1px 5px 0;background-color:#fff;color:#333;font-size:12px}.layui-laypage a:hover{color:#009688}.layui-laypage em{font-style:normal}.layui-laypage .layui-laypage-spr{color:#999;font-weight:700}.layui-laypage a{text-decoration:none}.layui-laypage .layui-laypage-curr{position:relative}.layui-laypage .layui-laypage-curr em{position:relative;color:#fff}.layui-laypage .layui-laypage-curr .layui-laypage-em{position:absolute;left:-1px;top:-1px;padding:1px;width:100%;height:100%;background-color:#009688}.layui-laypage-em{border-radius:2px}.layui-laypage-next em,.layui-laypage-prev em{font-family:Sim sun;font-size:16px}.layui-laypage .layui-laypage-count,.layui-laypage .layui-laypage-limits,.layui-laypage .layui-laypage-refresh,.layui-laypage .layui-laypage-skip{margin-left:10px;margin-right:10px;padding:0;border:none}.layui-laypage .layui-laypage-limits,.layui-laypage .layui-laypage-refresh{vertical-align:top}.layui-laypage .layui-laypage-refresh i{font-size:18px;cursor:pointer}.layui-laypage select{height:22px;padding:3px;border-radius:2px;cursor:pointer}.layui-laypage .layui-laypage-skip{height:30px;line-height:30px;color:#999}.layui-laypage button,.layui-laypage input{height:30px;line-height:30px;border-radius:2px;vertical-align:top;background-color:#fff;box-sizing:border-box}.layui-laypage input{display:inline-block;width:40px;margin:0 10px;padding:0 3px;text-align:center}.layui-laypage input:focus,.layui-laypage select:focus{border-color:#009688!important}.layui-laypage button{margin-left:10px;padding:0 10px;cursor:pointer}.layui-table,.layui-table-view{margin:10px 0}.layui-flow-more{margin:10px 0;text-align:center;color:#999;font-size:14px}.layui-flow-more a{height:32px;line-height:32px}.layui-flow-more a *{display:inline-block;vertical-align:top}.layui-flow-more a cite{padding:0 20px;border-radius:3px;background-color:#eee;color:#333;font-style:normal}.layui-flow-more a cite:hover{opacity:.8}.layui-flow-more a i{font-size:30px;color:#737383}.layui-table{width:100%;background-color:#fff;color:#666}.layui-table tr{transition:all .3s;-webkit-transition:all .3s}.layui-table th{text-align:left;font-weight:400}.layui-table tbody tr:hover,.layui-table thead tr,.layui-table-click,.layui-table-header,.layui-table-hover,.layui-table-mend,.layui-table-patch,.layui-table-tool,.layui-table[lay-even] tr:nth-child(even){background-color:#f2f2f2}.layui-table td,.layui-table th,.layui-table-fixed-r,.layui-table-header,.layui-table-page,.layui-table-tips-main,.layui-table-tool,.layui-table-view,.layui-table[lay-skin=line],.layui-table[lay-skin=row]{border-width:1px;border-style:solid;border-color:#e6e6e6}.layui-table td,.layui-table th{position:relative;padding:9px 15px;min-height:20px;line-height:20px;font-size:14px}.layui-table[lay-skin=line] td,.layui-table[lay-skin=line] th{border-width:0 0 1px}.layui-table[lay-skin=row] td,.layui-table[lay-skin=row] th{border-width:0 1px 0 0}.layui-table[lay-skin=nob] td,.layui-table[lay-skin=nob] th{border:none}.layui-table img{max-width:100px}.layui-table[lay-size=lg] td,.layui-table[lay-size=lg] th{padding:15px 30px}.layui-table-view .layui-table[lay-size=lg] .layui-table-cell{height:40px;line-height:40px}.layui-table[lay-size=sm] td,.layui-table[lay-size=sm] th{font-size:12px;padding:5px 10px}.layui-table-view .layui-table[lay-size=sm] .layui-table-cell{height:20px;line-height:20px}.layui-table[lay-data]{display:none}.layui-table-box,.layui-table-view{position:relative;overflow:hidden}.layui-table-view .layui-table{position:relative;width:auto;margin:0}.layui-table-body,.layui-table-header .layui-table,.layui-table-page{margin-bottom:-1px}.layui-table-view .layui-table[lay-skin=line]{border-width:0 1px 0 0}.layui-table-view .layui-table[lay-skin=row]{border-width:0 0 1px}.layui-table-view .layui-table td,.layui-table-view .layui-table th{padding:5px 0;border-top:none;border-left:none}.layui-table-view .layui-table td{cursor:default}.layui-table-view .layui-form-checkbox[lay-skin=primary] i{width:18px;height:18px}.layui-table-header{border-width:0 0 1px;overflow:hidden}.layui-table-sort{width:10px;height:20px;margin-left:5px;cursor:pointer!important}.layui-table-sort .layui-edge{position:absolute;left:5px;border-width:5px}.layui-table-sort .layui-table-sort-asc{top:4px;border-top:none;border-bottom-style:solid;border-bottom-color:#b2b2b2}.layui-table-sort .layui-table-sort-asc:hover{border-bottom-color:#666}.layui-table-sort .layui-table-sort-desc{bottom:4px;border-bottom:none;border-top-style:solid;border-top-color:#b2b2b2}.layui-table-sort .layui-table-sort-desc:hover{border-top-color:#666}.layui-table-sort[lay-sort=asc] .layui-table-sort-asc{border-bottom-color:#000}.layui-table-sort[lay-sort=desc] .layui-table-sort-desc{border-top-color:#000}.layui-table-cell{height:28px;line-height:28px;padding:0 15px;position:relative;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;box-sizing:border-box}.layui-table-cell .layui-form-checkbox[lay-skin=primary],.layui-table-cell .layui-form-radio[lay-skin=primary]{top:-1px;vertical-align:middle}.layui-table-cell .layui-form-radio{padding-right:0}.layui-table-cell .layui-form-radio>i{margin-right:0}.layui-table-cell .layui-table-link{color:#01AAED}.laytable-cell-checkbox,.laytable-cell-numbers,.laytable-cell-radio,.laytable-cell-space{padding:0;text-align:center}.layui-table-body{position:relative;overflow:auto;margin-right:-1px}.layui-table-body .layui-none{line-height:40px;text-align:center;color:#999}.layui-table-fixed{position:absolute;left:0;top:0}.layui-table-fixed .layui-table-body{overflow:hidden}.layui-table-fixed-l{box-shadow:0 -1px 8px rgba(0,0,0,.08)}.layui-table-fixed-r{left:auto;right:-1px;border-width:0 0 0 1px;box-shadow:-1px 0 8px rgba(0,0,0,.08)}.layui-table-fixed-r .layui-table-header{position:relative;overflow:visible}.layui-table-mend{position:absolute;right:-49px;top:0;height:100%;width:50px}.layui-table-tool{position:relative;width:100%;height:50px;line-height:30px;padding:10px 15px;border-width:0 0 1px}.layui-table-page{position:relative;width:100%;padding:7px 7px 0;border-width:1px 0 0;height:41px;font-size:12px}.layui-table-page>div{height:26px}.layui-table-page .layui-laypage{margin:0}.layui-table-page .layui-laypage a,.layui-table-page .layui-laypage span{height:26px;line-height:26px;margin-bottom:10px;border:none;background:0 0}.layui-table-page .layui-laypage a,.layui-table-page .layui-laypage span.layui-laypage-curr{padding:0 12px}.layui-table-page .layui-laypage span{margin-left:0;padding:0}.layui-table-page .layui-laypage .layui-laypage-prev{margin-left:-7px!important}.layui-table-page .layui-laypage .layui-laypage-curr .layui-laypage-em{left:0;top:0;padding:0}.layui-table-page .layui-laypage button,.layui-table-page .layui-laypage input{height:26px;line-height:26px}.layui-table-page .layui-laypage input{width:40px}.layui-table-page .layui-laypage button{padding:0 10px}.layui-table-page select{height:18px}.layui-table-view select[lay-ignore]{display:inline-block}.layui-table-patch .layui-table-cell{padding:0;width:30px}.layui-table-edit{position:absolute;left:0;top:0;width:100%;height:100%;padding:0 14px 1px;border-radius:0;box-shadow:1px 1px 20px rgba(0,0,0,.15)}.layui-table-edit:focus{border-color:#5FB878!important}select.layui-table-edit{padding:0 0 0 10px;border-color:#C9C9C9}.layui-table-view .layui-form-checkbox,.layui-table-view .layui-form-radio,.layui-table-view .layui-form-switch{top:0;margin:0;box-sizing:content-box}.layui-table-view .layui-form-checkbox{top:-1px;height:26px;line-height:26px}body .layui-table-tips .layui-layer-content{background:0 0;padding:0;box-shadow:0 1px 6px rgba(0,0,0,.1)}.layui-table-tips-main{margin:-44px 0 0 -1px;max-height:150px;padding:8px 15px;font-size:14px;overflow-y:scroll;background-color:#fff;color:#333}.layui-table-tips-c{position:absolute;right:-3px;top:-12px;width:18px;height:18px;padding:3px;text-align:center;font-weight:700;border-radius:100%;font-size:14px;cursor:pointer;background-color:#666}.layui-table-tips-c:hover{background-color:#999}.layui-upload-file{display:none!important;opacity:.01;filter:Alpha(opacity=1)}.layui-upload-drag,.layui-upload-form,.layui-upload-wrap{display:inline-block}.layui-upload-list{margin:10px 0}.layui-upload-choose{padding:0 10px;color:#999}.layui-upload-drag{position:relative;padding:30px;border:1px dashed #e2e2e2;background-color:#fff;text-align:center;cursor:pointer;color:#999}.layui-upload-drag .layui-icon{font-size:50px;color:#009688}.layui-upload-drag[lay-over]{border-color:#009688}.layui-upload-iframe{position:absolute;width:0;height:0;border:0;visibility:hidden}.layui-upload-wrap{position:relative;vertical-align:middle}.layui-upload-wrap .layui-upload-file{display:block!important;position:absolute;left:0;top:0;z-index:10;font-size:100px;width:100%;height:100%;opacity:.01;filter:Alpha(opacity=1);cursor:pointer}.layui-rate,.layui-rate *{display:inline-block;vertical-align:middle}.layui-rate{padding:10px 5px 10px 0;font-size:0}.layui-rate li i.layui-icon{font-size:20px;color:#FFB800;margin-right:5px;transition:all .3s;-webkit-transition:all .3s}.layui-rate li i:hover{cursor:pointer;transform:scale(1.12);-webkit-transform:scale(1.12)}.layui-rate[readonly] li i:hover{cursor:default;transform:scale(1)}.layui-code{position:relative;margin:10px 0;padding:15px;line-height:20px;border:1px solid #ddd;border-left-width:6px;background-color:#F2F2F2;color:#333;font-family:Courier New;font-size:12px}.layui-tree{line-height:26px}.layui-tree li{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-tree li .layui-tree-spread,.layui-tree li a{display:inline-block;vertical-align:top;height:26px;*display:inline;*zoom:1;cursor:pointer}.layui-tree li a{font-size:0}.layui-tree li a i{font-size:16px}.layui-tree li a cite{padding:0 6px;font-size:14px;font-style:normal}.layui-tree li i{padding-left:6px;color:#333;-moz-user-select:none}.layui-tree li .layui-tree-check{font-size:13px}.layui-tree li .layui-tree-check:hover{color:#009E94}.layui-tree li ul{display:none;margin-left:20px}.layui-tree li .layui-tree-enter{line-height:24px;border:1px dotted #000}.layui-tree-drag{display:none;position:absolute;left:-666px;top:-666px;background-color:#f2f2f2;padding:5px 10px;border:1px dotted #000;white-space:nowrap}.layui-tree-drag i{padding-right:5px}.layui-nav{position:relative;padding:0 20px;background-color:#393D49;color:#fff;border-radius:2px;font-size:0;box-sizing:border-box}.layui-nav *{font-size:14px}.layui-nav .layui-nav-item{position:relative;display:inline-block;*display:inline;*zoom:1;vertical-align:middle;line-height:60px}.layui-nav .layui-nav-item a{display:block;padding:0 20px;color:#fff;color:rgba(255,255,255,.7);transition:all .3s;-webkit-transition:all .3s}.layui-nav .layui-this:after,.layui-nav-bar,.layui-nav-tree .layui-nav-itemed:after{position:absolute;left:0;top:0;width:0;height:5px;background-color:#5FB878;transition:all .2s;-webkit-transition:all .2s}.layui-nav-bar{z-index:1000}.layui-nav .layui-nav-item a:hover,.layui-nav .layui-this a{color:#fff}.layui-nav .layui-this:after{content:'';top:auto;bottom:0;width:100%}.layui-nav-img{width:30px;height:30px;margin-right:10px;border-radius:50%}.layui-nav .layui-nav-more{content:'';width:0;height:0;border-style:solid dashed dashed;border-color:#fff transparent transparent;overflow:hidden;cursor:pointer;transition:all .2s;-webkit-transition:all .2s;position:absolute;top:50%;right:3px;margin-top:-3px;border-width:6px;border-top-color:rgba(255,255,255,.7)}.layui-nav .layui-nav-mored,.layui-nav-itemed>a .layui-nav-more{margin-top:-9px;border-style:dashed dashed solid;border-color:transparent transparent #fff}.layui-nav-child{display:none;position:absolute;left:0;top:65px;min-width:100%;line-height:36px;padding:5px 0;box-shadow:0 2px 4px rgba(0,0,0,.12);border:1px solid #d2d2d2;background-color:#fff;z-index:100;border-radius:2px;white-space:nowrap}.layui-nav .layui-nav-child a{color:#333}.layui-nav .layui-nav-child a:hover{background-color:#f2f2f2;color:#000}.layui-nav-child dd{position:relative}.layui-nav .layui-nav-child dd.layui-this a,.layui-nav-child dd.layui-this{background-color:#5FB878;color:#fff}.layui-nav-child dd.layui-this:after{display:none}.layui-nav-tree{width:200px;padding:0}.layui-nav-tree .layui-nav-item{display:block;width:100%;line-height:45px}.layui-nav-tree .layui-nav-item a{position:relative;height:45px;line-height:45px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-nav-tree .layui-nav-item a:hover{background-color:#4E5465}.layui-nav-tree .layui-nav-bar{width:5px;height:0;background-color:#009688}.layui-nav-tree .layui-nav-child dd.layui-this,.layui-nav-tree .layui-nav-child dd.layui-this a,.layui-nav-tree .layui-this,.layui-nav-tree .layui-this>a,.layui-nav-tree .layui-this>a:hover{background-color:#009688;color:#fff}.layui-nav-tree .layui-this:after{display:none}.layui-nav-itemed>a,.layui-nav-tree .layui-nav-title a,.layui-nav-tree .layui-nav-title a:hover{color:#fff!important}.layui-nav-tree .layui-nav-child{position:relative;z-index:0;top:0;border:none;box-shadow:none}.layui-nav-tree .layui-nav-child a{height:40px;line-height:40px;color:#fff;color:rgba(255,255,255,.7)}.layui-nav-tree .layui-nav-child,.layui-nav-tree .layui-nav-child a:hover{background:0 0;color:#fff}.layui-nav-tree .layui-nav-more{right:10px}.layui-nav-itemed>.layui-nav-child{display:block;padding:0;background-color:rgba(0,0,0,.3)!important}.layui-nav-itemed>.layui-nav-child>.layui-this>.layui-nav-child{display:block}.layui-nav-side{position:fixed;top:0;bottom:0;left:0;overflow-x:hidden;z-index:999}.layui-bg-blue .layui-nav-bar,.layui-bg-blue .layui-nav-itemed:after,.layui-bg-blue .layui-this:after{background-color:#93D1FF}.layui-bg-blue .layui-nav-child dd.layui-this{background-color:#1E9FFF}.layui-bg-blue .layui-nav-itemed>a,.layui-nav-tree.layui-bg-blue .layui-nav-title a,.layui-nav-tree.layui-bg-blue .layui-nav-title a:hover{background-color:#007DDB!important}.layui-breadcrumb{visibility:hidden;font-size:0}.layui-breadcrumb>*{font-size:14px}.layui-breadcrumb a{color:#999!important}.layui-breadcrumb a:hover{color:#5FB878!important}.layui-breadcrumb a cite{color:#666;font-style:normal}.layui-breadcrumb span[lay-separator]{margin:0 10px;color:#999}.layui-tab{margin:10px 0;text-align:left!important}.layui-tab[overflow]>.layui-tab-title{overflow:hidden}.layui-tab-title{position:relative;left:0;height:40px;white-space:nowrap;font-size:0;border-bottom-width:1px;border-bottom-style:solid;transition:all .2s;-webkit-transition:all .2s}.layui-tab-title li{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;font-size:14px;transition:all .2s;-webkit-transition:all .2s;position:relative;line-height:40px;min-width:65px;padding:0 15px;text-align:center;cursor:pointer}.layui-tab-title li a{display:block}.layui-tab-title .layui-this{color:#000}.layui-tab-title .layui-this:after{position:absolute;left:0;top:0;content:'';width:100%;height:41px;border-width:1px;border-style:solid;border-bottom-color:#fff;border-radius:2px 2px 0 0;box-sizing:border-box;pointer-events:none}.layui-tab-bar{position:absolute;right:0;top:0;z-index:10;width:30px;height:39px;line-height:39px;border-width:1px;border-style:solid;border-radius:2px;text-align:center;background-color:#fff;cursor:pointer}.layui-tab-bar .layui-icon{position:relative;display:inline-block;top:3px;transition:all .3s;-webkit-transition:all .3s}.layui-tab-item{display:none}.layui-tab-more{padding-right:30px;height:auto!important;white-space:normal!important}.layui-tab-more li.layui-this:after{border-bottom-color:#e2e2e2;border-radius:2px}.layui-tab-more .layui-tab-bar .layui-icon{top:-2px;top:3px\\9;-webkit-transform:rotate(180deg);transform:rotate(180deg)}:root .layui-tab-more .layui-tab-bar .layui-icon{top:-2px\\0/IE9}.layui-tab-content{padding:10px}.layui-tab-title li .layui-tab-close{position:relative;display:inline-block;width:18px;height:18px;line-height:20px;margin-left:8px;top:1px;text-align:center;font-size:14px;color:#c2c2c2;transition:all .2s;-webkit-transition:all .2s}.layui-tab-title li .layui-tab-close:hover{border-radius:2px;background-color:#FF5722;color:#fff}.layui-tab-brief>.layui-tab-title .layui-this{color:#009688}.layui-tab-brief>.layui-tab-more li.layui-this:after,.layui-tab-brief>.layui-tab-title .layui-this:after{border:none;border-radius:0;border-bottom:2px solid #5FB878}.layui-tab-brief[overflow]>.layui-tab-title .layui-this:after{top:-1px}.layui-tab-card{border-width:1px;border-style:solid;border-radius:2px;box-shadow:0 2px 5px 0 rgba(0,0,0,.1)}.layui-tab-card>.layui-tab-title{background-color:#f2f2f2}.layui-tab-card>.layui-tab-title li{margin-right:-1px;margin-left:-1px}.layui-tab-card>.layui-tab-title .layui-this{background-color:#fff}.layui-tab-card>.layui-tab-title .layui-this:after{border-top:none;border-width:1px;border-bottom-color:#fff}.layui-tab-card>.layui-tab-title .layui-tab-bar{height:40px;line-height:40px;border-radius:0;border-top:none;border-right:none}.layui-tab-card>.layui-tab-more .layui-this{background:0 0;color:#5FB878}.layui-tab-card>.layui-tab-more .layui-this:after{border:none}.layui-timeline{padding-left:5px}.layui-timeline-item{position:relative;padding-bottom:20px}.layui-timeline-axis{position:absolute;left:-5px;top:0;z-index:10;width:20px;height:20px;line-height:20px;background-color:#fff;color:#5FB878;border-radius:50%;text-align:center;cursor:pointer}.layui-timeline-axis:hover{color:#FF5722}.layui-timeline-item:before{content:'';position:absolute;left:5px;top:0;z-index:0;width:1px;height:100%}.layui-timeline-item:last-child:before{display:none}.layui-timeline-item:first-child:before{display:block}.layui-timeline-content{padding-left:25px}.layui-timeline-title{position:relative;margin-bottom:10px}.layui-badge,.layui-badge-dot,.layui-badge-rim{position:relative;display:inline-block;padding:0 6px;font-size:12px;text-align:center;background-color:#FF5722;color:#fff;border-radius:2px}.layui-badge{height:18px;line-height:18px}.layui-badge-dot{width:8px;height:8px;padding:0;border-radius:50%}.layui-badge-rim{height:18px;line-height:18px;border-width:1px;border-style:solid;background-color:#fff;color:#666}.layui-btn .layui-badge,.layui-btn .layui-badge-dot{margin-left:5px}.layui-nav .layui-badge,.layui-nav .layui-badge-dot{position:absolute;top:50%;margin:-8px 6px 0}.layui-tab-title .layui-badge,.layui-tab-title .layui-badge-dot{left:5px;top:-2px}.layui-carousel{position:relative;left:0;top:0;background-color:#f8f8f8}.layui-carousel>[carousel-item]{position:relative;width:100%;height:100%;overflow:hidden}.layui-carousel>[carousel-item]:before{position:absolute;content:'\\e63d';left:50%;top:50%;width:100px;line-height:20px;margin:-10px 0 0 -50px;text-align:center;color:#c2c2c2;font-family:layui-icon!important;font-size:30px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.layui-carousel>[carousel-item]>*{display:none;position:absolute;left:0;top:0;width:100%;height:100%;background-color:#f8f8f8;transition-duration:.3s;-webkit-transition-duration:.3s}.layui-carousel-updown>*{-webkit-transition:.3s ease-in-out up;transition:.3s ease-in-out up}.layui-carousel-arrow{display:none\\9;opacity:0;position:absolute;left:10px;top:50%;margin-top:-18px;width:36px;height:36px;line-height:36px;text-align:center;font-size:20px;border:0;border-radius:50%;background-color:rgba(0,0,0,.2);color:#fff;-webkit-transition-duration:.3s;transition-duration:.3s;cursor:pointer}.layui-carousel-arrow[lay-type=add]{left:auto!important;right:10px}.layui-carousel:hover .layui-carousel-arrow[lay-type=add],.layui-carousel[lay-arrow=always] .layui-carousel-arrow[lay-type=add]{right:20px}.layui-carousel[lay-arrow=always] .layui-carousel-arrow{opacity:1;left:20px}.layui-carousel[lay-arrow=none] .layui-carousel-arrow{display:none}.layui-carousel-arrow:hover,.layui-carousel-ind ul:hover{background-color:rgba(0,0,0,.35)}.layui-carousel:hover .layui-carousel-arrow{display:block\\9;opacity:1;left:20px}.layui-carousel-ind{position:relative;top:-35px;width:100%;line-height:0!important;text-align:center;font-size:0}.layui-carousel[lay-indicator=outside]{margin-bottom:30px}.layui-carousel[lay-indicator=outside] .layui-carousel-ind{top:10px}.layui-carousel[lay-indicator=outside] .layui-carousel-ind ul{background-color:rgba(0,0,0,.5)}.layui-carousel[lay-indicator=none] .layui-carousel-ind{display:none}.layui-carousel-ind ul{display:inline-block;padding:5px;background-color:rgba(0,0,0,.2);border-radius:10px;-webkit-transition-duration:.3s;transition-duration:.3s}.layui-carousel-ind li{display:inline-block;width:10px;height:10px;margin:0 3px;font-size:14px;background-color:#e2e2e2;background-color:rgba(255,255,255,.5);border-radius:50%;cursor:pointer;-webkit-transition-duration:.3s;transition-duration:.3s}.layui-carousel-ind li:hover{background-color:rgba(255,255,255,.7)}.layui-carousel-ind li.layui-this{background-color:#fff}.layui-carousel>[carousel-item]>.layui-carousel-next,.layui-carousel>[carousel-item]>.layui-carousel-prev,.layui-carousel>[carousel-item]>.layui-this{display:block}.layui-carousel>[carousel-item]>.layui-this{left:0}.layui-carousel>[carousel-item]>.layui-carousel-prev{left:-100%}.layui-carousel>[carousel-item]>.layui-carousel-next{left:100%}.layui-carousel>[carousel-item]>.layui-carousel-next.layui-carousel-left,.layui-carousel>[carousel-item]>.layui-carousel-prev.layui-carousel-right{left:0}.layui-carousel>[carousel-item]>.layui-this.layui-carousel-left{left:-100%}.layui-carousel>[carousel-item]>.layui-this.layui-carousel-right{left:100%}.layui-carousel[lay-anim=updown] .layui-carousel-arrow{left:50%!important;top:20px;margin:0 0 0 -18px}.layui-carousel[lay-anim=updown]>[carousel-item]>*,.layui-carousel[lay-anim=fade]>[carousel-item]>*{left:0!important}.layui-carousel[lay-anim=updown] .layui-carousel-arrow[lay-type=add]{top:auto!important;bottom:20px}.layui-carousel[lay-anim=updown] .layui-carousel-ind{position:absolute;top:50%;right:20px;width:auto;height:auto}.layui-carousel[lay-anim=updown] .layui-carousel-ind ul{padding:3px 5px}.layui-carousel[lay-anim=updown] .layui-carousel-ind li{display:block;margin:6px 0}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-this{top:0}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-carousel-prev{top:-100%}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-carousel-next{top:100%}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-carousel-next.layui-carousel-left,.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-carousel-prev.layui-carousel-right{top:0}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-this.layui-carousel-left{top:-100%}.layui-carousel[lay-anim=updown]>[carousel-item]>.layui-this.layui-carousel-right{top:100%}.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-carousel-next,.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-carousel-prev{opacity:0}.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-carousel-next.layui-carousel-left,.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-carousel-prev.layui-carousel-right{opacity:1}.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-this.layui-carousel-left,.layui-carousel[lay-anim=fade]>[carousel-item]>.layui-this.layui-carousel-right{opacity:0}.layui-fixbar{position:fixed;right:15px;bottom:15px;z-index:9999}.layui-fixbar li{width:50px;height:50px;line-height:50px;margin-bottom:1px;text-align:center;cursor:pointer;font-size:30px;background-color:#9F9F9F;color:#fff;border-radius:2px;opacity:.95}.layui-fixbar li:hover{opacity:.85}.layui-fixbar li:active{opacity:1}.layui-fixbar .layui-fixbar-top{display:none;font-size:40px}body .layui-util-face{border:none;background:0 0}body .layui-util-face .layui-layer-content{padding:0;background-color:#fff;color:#666;box-shadow:none}.layui-util-face .layui-layer-TipsG{display:none}.layui-util-face ul{position:relative;width:372px;padding:10px;border:1px solid #D9D9D9;background-color:#fff;box-shadow:0 0 20px rgba(0,0,0,.2)}.layui-util-face ul li{cursor:pointer;float:left;border:1px solid #e8e8e8;height:22px;width:26px;overflow:hidden;margin:-1px 0 0 -1px;padding:4px 2px;text-align:center}.layui-util-face ul li:hover{position:relative;z-index:2;border:1px solid #eb7350;background:#fff9ec}.layui-anim{-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.layui-anim.layui-icon{display:inline-block}.layui-anim-loop{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.layui-trans,.layui-trans a{transition:all .3s;-webkit-transition:all .3s}@-webkit-keyframes layui-rotate{from{-webkit-transform:rotate(0)}to{-webkit-transform:rotate(360deg)}}@keyframes layui-rotate{from{transform:rotate(0)}to{transform:rotate(360deg)}}.layui-anim-rotate{-webkit-animation-name:layui-rotate;animation-name:layui-rotate;-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-timing-function:linear;animation-timing-function:linear}@-webkit-keyframes layui-up{from{-webkit-transform:translate3d(0,100%,0);opacity:.3}to{-webkit-transform:translate3d(0,0,0);opacity:1}}@keyframes layui-up{from{transform:translate3d(0,100%,0);opacity:.3}to{transform:translate3d(0,0,0);opacity:1}}.layui-anim-up{-webkit-animation-name:layui-up;animation-name:layui-up}@-webkit-keyframes layui-upbit{from{-webkit-transform:translate3d(0,30px,0);opacity:.3}to{-webkit-transform:translate3d(0,0,0);opacity:1}}@keyframes layui-upbit{from{transform:translate3d(0,30px,0);opacity:.3}to{transform:translate3d(0,0,0);opacity:1}}.layui-anim-upbit{-webkit-animation-name:layui-upbit;animation-name:layui-upbit}@-webkit-keyframes layui-scale{0%{opacity:.3;-webkit-transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1)}}@keyframes layui-scale{0%{opacity:.3;-ms-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-ms-transform:scale(1);transform:scale(1)}}.layui-anim-scale{-webkit-animation-name:layui-scale;animation-name:layui-scale}@-webkit-keyframes layui-scale-spring{0%{opacity:.5;-webkit-transform:scale(.5)}80%{opacity:.8;-webkit-transform:scale(1.1)}100%{opacity:1;-webkit-transform:scale(1)}}@keyframes layui-scale-spring{0%{opacity:.5;transform:scale(.5)}80%{opacity:.8;transform:scale(1.1)}100%{opacity:1;transform:scale(1)}}.layui-anim-scaleSpring{-webkit-animation-name:layui-scale-spring;animation-name:layui-scale-spring}@-webkit-keyframes layui-fadein{0%{opacity:0}100%{opacity:1}}@keyframes layui-fadein{0%{opacity:0}100%{opacity:1}}.layui-anim-fadein{-webkit-animation-name:layui-fadein;animation-name:layui-fadein}@-webkit-keyframes layui-fadeout{0%{opacity:1}100%{opacity:0}}@keyframes layui-fadeout{0%{opacity:1}100%{opacity:0}}.layui-anim-fadeout{-webkit-animation-name:layui-fadeout;animation-name:layui-fadeout}"
  },
  {
    "path": "public/layui/css/layui.mobile.css",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n blockquote,body,button,dd,div,dl,dt,form,h1,h2,h3,h4,h5,h6,input,legend,li,ol,p,td,textarea,th,ul{margin:0;padding:0;-webkit-tap-highlight-color:rgba(0,0,0,0)}html{font:12px 'Helvetica Neue','PingFang SC',STHeitiSC-Light,Helvetica,Arial,sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}a,button,input{-webkit-tap-highlight-color:rgba(255,0,0,0)}a{text-decoration:none;background:0 0}a:active,a:hover{outline:0}table{border-collapse:collapse;border-spacing:0}li{list-style:none}b,strong{font-weight:700}h1,h2,h3,h4,h5,h6{font-weight:500}address,cite,dfn,em,var{font-style:normal}dfn{font-style:italic}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}img{border:0;vertical-align:bottom}.layui-inline,input,label{vertical-align:middle}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0;outline:0}button,select{text-transform:none}select{-webkit-appearance:none;border:none}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}@font-face{font-family:layui-icon;src:url(../font/iconfont.eot?v=1.0.7);src:url(../font/iconfont.eot?v=1.0.7#iefix) format('embedded-opentype'),url(../font/iconfont.woff?v=1.0.7) format('woff'),url(../font/iconfont.ttf?v=1.0.7) format('truetype'),url(../font/iconfont.svg?v=1.0.7#iconfont) format('svg')}.layui-icon{font-family:layui-icon!important;font-size:16px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.layui-box,.layui-box *{-webkit-box-sizing:content-box!important;-moz-box-sizing:content-box!important;box-sizing:content-box!important}.layui-border-box,.layui-border-box *{-webkit-box-sizing:border-box!important;-moz-box-sizing:border-box!important;box-sizing:border-box!important}.layui-inline{position:relative;display:inline-block;*display:inline;*zoom:1}.layui-edge,.layui-upload-iframe{position:absolute;width:0;height:0}.layui-edge{border-style:dashed;border-color:transparent;overflow:hidden}.layui-elip{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-unselect{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.layui-disabled,.layui-disabled:active{background-color:#d2d2d2!important;color:#fff!important;cursor:not-allowed!important}.layui-circle{border-radius:100%}.layui-show{display:block!important}.layui-hide{display:none!important}.layui-upload-iframe{border:0;visibility:hidden}.layui-upload-enter{border:1px solid #009E94;background-color:#009E94;color:#fff;-webkit-transform:scale(1.1);transform:scale(1.1)}@-webkit-keyframes layui-m-anim-scale{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes layui-m-anim-scale{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}.layui-m-anim-scale{animation-name:layui-m-anim-scale;-webkit-animation-name:layui-m-anim-scale}@-webkit-keyframes layui-m-anim-up{0%{opacity:0;-webkit-transform:translateY(800px);transform:translateY(800px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes layui-m-anim-up{0%{opacity:0;-webkit-transform:translateY(800px);transform:translateY(800px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}.layui-m-anim-up{-webkit-animation-name:layui-m-anim-up;animation-name:layui-m-anim-up}@-webkit-keyframes layui-m-anim-left{0%{-webkit-transform:translateX(100%);transform:translateX(100%)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes layui-m-anim-left{0%{-webkit-transform:translateX(100%);transform:translateX(100%)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}.layui-m-anim-left{-webkit-animation-name:layui-m-anim-left;animation-name:layui-m-anim-left}@-webkit-keyframes layui-m-anim-right{0%{-webkit-transform:translateX(-100%);transform:translateX(-100%)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes layui-m-anim-right{0%{-webkit-transform:translateX(-100%);transform:translateX(-100%)}100%{-webkit-transform:translateX(0);transform:translateX(0)}}.layui-m-anim-right{-webkit-animation-name:layui-m-anim-right;animation-name:layui-m-anim-right}@-webkit-keyframes layui-m-anim-lout{0%{-webkit-transform:translateX(0);transform:translateX(0)}100%{-webkit-transform:translateX(-100%);transform:translateX(-100%)}}@keyframes layui-m-anim-lout{0%{-webkit-transform:translateX(0);transform:translateX(0)}100%{-webkit-transform:translateX(-100%);transform:translateX(-100%)}}.layui-m-anim-lout{-webkit-animation-name:layui-m-anim-lout;animation-name:layui-m-anim-lout}@-webkit-keyframes layui-m-anim-rout{0%{-webkit-transform:translateX(0);transform:translateX(0)}100%{-webkit-transform:translateX(100%);transform:translateX(100%)}}@keyframes layui-m-anim-rout{0%{-webkit-transform:translateX(0);transform:translateX(0)}100%{-webkit-transform:translateX(100%);transform:translateX(100%)}}.layui-m-anim-rout{-webkit-animation-name:layui-m-anim-rout;animation-name:layui-m-anim-rout}.layui-m-layer{position:relative;z-index:19891014}.layui-m-layer *{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.layui-m-layermain,.layui-m-layershade{position:fixed;left:0;top:0;width:100%;height:100%}.layui-m-layershade{background-color:rgba(0,0,0,.7);pointer-events:auto}.layui-m-layermain{display:table;font-family:Helvetica,arial,sans-serif;pointer-events:none}.layui-m-layermain .layui-m-layersection{display:table-cell;vertical-align:middle;text-align:center}.layui-m-layerchild{position:relative;display:inline-block;text-align:left;background-color:#fff;font-size:14px;border-radius:5px;box-shadow:0 0 8px rgba(0,0,0,.1);pointer-events:auto;-webkit-overflow-scrolling:touch;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.2s;animation-duration:.2s}.layui-m-layer0 .layui-m-layerchild{width:90%;max-width:640px}.layui-m-layer1 .layui-m-layerchild{border:none;border-radius:0}.layui-m-layer2 .layui-m-layerchild{width:auto;max-width:260px;min-width:40px;border:none;background:0 0;box-shadow:none;color:#fff}.layui-m-layerchild h3{padding:0 10px;height:60px;line-height:60px;font-size:16px;font-weight:400;border-radius:5px 5px 0 0;text-align:center}.layui-m-layerbtn span,.layui-m-layerchild h3{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-m-layercont{padding:50px 30px;line-height:22px;text-align:center}.layui-m-layer1 .layui-m-layercont{padding:0;text-align:left}.layui-m-layer2 .layui-m-layercont{text-align:center;padding:0;line-height:0}.layui-m-layer2 .layui-m-layercont i{width:25px;height:25px;margin-left:8px;display:inline-block;background-color:#fff;border-radius:100%;-webkit-animation:layui-m-anim-loading 1.4s infinite ease-in-out;animation:layui-m-anim-loading 1.4s infinite ease-in-out;-webkit-animation-fill-mode:both;animation-fill-mode:both}.layui-m-layerbtn,.layui-m-layerbtn span{position:relative;text-align:center;border-radius:0 0 5px 5px}.layui-m-layer2 .layui-m-layercont p{margin-top:20px}@-webkit-keyframes layui-m-anim-loading{0%,100%,80%{transform:scale(0);-webkit-transform:scale(0)}40%{transform:scale(1);-webkit-transform:scale(1)}}@keyframes layui-m-anim-loading{0%,100%,80%{transform:scale(0);-webkit-transform:scale(0)}40%{transform:scale(1);-webkit-transform:scale(1)}}.layui-m-layer2 .layui-m-layercont i:first-child{margin-left:0;-webkit-animation-delay:-.32s;animation-delay:-.32s}.layui-m-layer2 .layui-m-layercont i.layui-m-layerload{-webkit-animation-delay:-.16s;animation-delay:-.16s}.layui-m-layer2 .layui-m-layercont>div{line-height:22px;padding-top:7px;margin-bottom:20px;font-size:14px}.layui-m-layerbtn{display:box;display:-moz-box;display:-webkit-box;width:100%;height:50px;line-height:50px;font-size:0;border-top:1px solid #D0D0D0;background-color:#F2F2F2}.layui-m-layerbtn span{display:block;-moz-box-flex:1;box-flex:1;-webkit-box-flex:1;font-size:14px;cursor:pointer}.layui-m-layerbtn span[yes]{color:#40AFFE}.layui-m-layerbtn span[no]{border-right:1px solid #D0D0D0;border-radius:0 0 0 5px}.layui-m-layerbtn span:active{background-color:#F6F6F6}.layui-m-layerend{position:absolute;right:7px;top:10px;width:30px;height:30px;border:0;font-weight:400;background:0 0;cursor:pointer;-webkit-appearance:none;font-size:30px}.layui-m-layerend::after,.layui-m-layerend::before{position:absolute;left:5px;top:15px;content:'';width:18px;height:1px;background-color:#999;transform:rotate(45deg);-webkit-transform:rotate(45deg);border-radius:3px}.layui-m-layerend::after{transform:rotate(-45deg);-webkit-transform:rotate(-45deg)}body .layui-m-layer .layui-m-layer-footer{position:fixed;width:95%;max-width:100%;margin:0 auto;left:0;right:0;bottom:10px;background:0 0}.layui-m-layer-footer .layui-m-layercont{padding:20px;border-radius:5px 5px 0 0;background-color:rgba(255,255,255,.8)}.layui-m-layer-footer .layui-m-layerbtn{display:block;height:auto;background:0 0;border-top:none}.layui-m-layer-footer .layui-m-layerbtn span{background-color:rgba(255,255,255,.8)}.layui-m-layer-footer .layui-m-layerbtn span[no]{color:#FD482C;border-top:1px solid #c2c2c2;border-radius:0 0 5px 5px}.layui-m-layer-footer .layui-m-layerbtn span[yes]{margin-top:10px;border-radius:5px}body .layui-m-layer .layui-m-layer-msg{width:auto;max-width:90%;margin:0 auto;bottom:-150px;background-color:rgba(0,0,0,.7);color:#fff}.layui-m-layer-msg .layui-m-layercont{padding:10px 20px}"
  },
  {
    "path": "public/layui/css/modules/code.css",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-h3,.layui-code-view{position:relative;font-size:12px}.layui-code-view{display:block;margin:10px 0;padding:0;border:1px solid #e2e2e2;border-left-width:6px;background-color:#F2F2F2;color:#333;font-family:Courier New}.layui-code-h3{padding:0 10px;height:32px;line-height:32px;border-bottom:1px solid #e2e2e2}.layui-code-h3 a{position:absolute;right:10px;top:0;color:#999}.layui-code-view .layui-code-ol{position:relative;overflow:auto}.layui-code-view .layui-code-ol li{position:relative;margin-left:45px;line-height:20px;padding:0 5px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view pre{margin:0}.layui-code-notepad{border:1px solid #0C0C0C;border-left-color:#3F3F3F;background-color:#0C0C0C;color:#C2BE9E}.layui-code-notepad .layui-code-h3{border-bottom:none}.layui-code-notepad .layui-code-ol li{background-color:#3F3F3F;border-left:none}"
  },
  {
    "path": "public/layui/css/modules/laydate/default/laydate.css",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n .laydate-set-ym,.layui-laydate,.layui-laydate *,.layui-laydate-list{box-sizing:border-box}html #layuicss-laydate{display:none;position:absolute;width:1989px}.layui-laydate *{margin:0;padding:0}.layui-laydate{position:absolute;z-index:66666666;margin:5px 0;border-radius:2px;font-size:14px;-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-name:laydate-upbit;animation-name:laydate-upbit}.layui-laydate-main{width:272px}.layui-laydate-content td,.layui-laydate-header *,.layui-laydate-list li{transition-duration:.3s;-webkit-transition-duration:.3s}@-webkit-keyframes laydate-upbit{from{-webkit-transform:translate3d(0,20px,0);opacity:.3}to{-webkit-transform:translate3d(0,0,0);opacity:1}}@keyframes laydate-upbit{from{transform:translate3d(0,20px,0);opacity:.3}to{transform:translate3d(0,0,0);opacity:1}}.layui-laydate-static{position:relative;z-index:0;display:inline-block;margin:0;-webkit-animation:none;animation:none}.laydate-ym-show .laydate-next-m,.laydate-ym-show .laydate-prev-m{display:none!important}.laydate-ym-show .laydate-next-y,.laydate-ym-show .laydate-prev-y{display:inline-block!important}.laydate-time-show .laydate-set-ym span[lay-type=month],.laydate-time-show .laydate-set-ym span[lay-type=year],.laydate-time-show .layui-laydate-header .layui-icon,.laydate-ym-show .laydate-set-ym span[lay-type=month]{display:none!important}.layui-laydate-header{position:relative;line-height:30px;padding:10px 70px 5px}.laydate-set-ym span,.layui-laydate-header i{padding:0 5px;cursor:pointer}.layui-laydate-header *{display:inline-block;vertical-align:bottom}.layui-laydate-header i{position:absolute;top:10px;color:#999;font-size:18px}.layui-laydate-header i.laydate-prev-y{left:15px}.layui-laydate-header i.laydate-prev-m{left:45px}.layui-laydate-header i.laydate-next-y{right:15px}.layui-laydate-header i.laydate-next-m{right:45px}.laydate-set-ym{width:100%;text-align:center;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.laydate-time-text{cursor:default!important}.layui-laydate-content{position:relative;padding:10px;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.layui-laydate-content table{border-collapse:collapse;border-spacing:0}.layui-laydate-content td,.layui-laydate-content th{width:36px;height:30px;padding:5px;text-align:center}.layui-laydate-content td{position:relative;cursor:pointer}.laydate-day-mark{position:absolute;left:0;top:0;width:100%;height:100%;line-height:30px;font-size:12px;overflow:hidden}.laydate-day-mark::after{position:absolute;content:'';right:2px;top:2px;width:5px;height:5px;border-radius:50%}.layui-laydate-footer{position:relative;height:46px;line-height:26px;padding:10px 20px}.layui-laydate-footer span{margin-right:15px;display:inline-block;cursor:pointer;font-size:12px}.layui-laydate-footer span:hover{color:#5FB878}.laydate-footer-btns{position:absolute;right:10px;top:10px}.laydate-footer-btns span{height:26px;line-height:26px;margin:0 0 0 -1px;padding:0 10px;border:1px solid #C9C9C9;background-color:#fff;white-space:nowrap;vertical-align:top;border-radius:2px}.layui-laydate-list>li,.layui-laydate-range .layui-laydate-main{display:inline-block;vertical-align:middle}.layui-laydate-list{position:absolute;left:0;top:0;width:100%;height:100%;padding:10px;background-color:#fff}.layui-laydate-list>li{position:relative;width:33.3%;height:36px;line-height:36px;margin:3px 0;text-align:center;cursor:pointer}.laydate-month-list>li{width:25%;margin:17px 0}.laydate-time-list>li{height:100%;margin:0;line-height:normal;cursor:default}.laydate-time-list p{position:relative;top:-4px;line-height:29px}.laydate-time-list ol{height:181px;overflow:hidden}.laydate-time-list>li:hover ol{overflow-y:auto}.laydate-time-list ol li{width:130%;padding-left:33px;line-height:30px;text-align:left;cursor:pointer}.layui-laydate-hint{position:absolute;top:115px;left:50%;width:250px;margin-left:-125px;line-height:20px;padding:15px;text-align:center;font-size:12px}.layui-laydate-range{width:546px}.layui-laydate-range .laydate-main-list-0 .laydate-next-m,.layui-laydate-range .laydate-main-list-0 .laydate-next-y,.layui-laydate-range .laydate-main-list-1 .laydate-prev-m,.layui-laydate-range .laydate-main-list-1 .laydate-prev-y{display:none}.layui-laydate-range .laydate-main-list-1 .layui-laydate-content{border-left:1px solid #e2e2e2}.layui-laydate,.layui-laydate-hint{border:1px solid #d2d2d2;box-shadow:0 2px 4px rgba(0,0,0,.12);background-color:#fff;color:#666}.layui-laydate-header{border-bottom:1px solid #e2e2e2}.layui-laydate-header i:hover,.layui-laydate-header span:hover{color:#5FB878}.layui-laydate-content{border-top:none 0;border-bottom:none 0}.layui-laydate-content th{font-weight:400;color:#333}.layui-laydate-content td{color:#666}.layui-laydate-content td.laydate-selected{background-color:#00F7DE}.laydate-selected:hover{background-color:#00F7DE!important}.layui-laydate-content td:hover,.layui-laydate-list li:hover{background-color:#eaeaea;color:#333}.laydate-time-list li ol{margin:0;padding:0;border:1px solid #e2e2e2;border-left-width:0}.laydate-time-list li:first-child ol{border-left-width:1px}.laydate-time-list>li:hover{background:0 0}.layui-laydate-content .laydate-day-next,.layui-laydate-content .laydate-day-prev{color:#d2d2d2}.laydate-selected.laydate-day-next,.laydate-selected.laydate-day-prev{background-color:#f8f8f8!important}.layui-laydate-footer{border-top:1px solid #e2e2e2}.layui-laydate-hint{color:#FF5722}.laydate-day-mark::after{background-color:#5FB878}.layui-laydate-content td.layui-this .laydate-day-mark::after{display:none}.layui-laydate-footer span[lay-type=date]{color:#5FB878}.layui-laydate .layui-this{background-color:#009688!important;color:#fff!important}.layui-laydate .laydate-disabled,.layui-laydate .laydate-disabled:hover{background:0 0!important;color:#d2d2d2!important;cursor:not-allowed!important;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.laydate-theme-molv{border:none}.laydate-theme-molv.layui-laydate-range{width:548px}.laydate-theme-molv .layui-laydate-main{width:274px}.laydate-theme-molv .layui-laydate-header{border:none;background-color:#009688}.laydate-theme-molv .layui-laydate-header i,.laydate-theme-molv .layui-laydate-header span{color:#f6f6f6}.laydate-theme-molv .layui-laydate-header i:hover,.laydate-theme-molv .layui-laydate-header span:hover{color:#fff}.laydate-theme-molv .layui-laydate-content{border:1px solid #e2e2e2;border-top:none;border-bottom:none}.laydate-theme-molv .laydate-main-list-1 .layui-laydate-content{border-left:none}.laydate-theme-grid .laydate-month-list>li,.laydate-theme-grid .laydate-year-list>li,.laydate-theme-grid .layui-laydate-content td,.laydate-theme-grid .layui-laydate-content thead,.laydate-theme-molv .layui-laydate-footer{border:1px solid #e2e2e2}.laydate-theme-grid .laydate-selected,.laydate-theme-grid .laydate-selected:hover{background-color:#f2f2f2!important;color:#009688!important}.laydate-theme-grid .laydate-selected.laydate-day-next,.laydate-theme-grid .laydate-selected.laydate-day-prev{color:#d2d2d2!important}.laydate-theme-grid .laydate-month-list,.laydate-theme-grid .laydate-year-list{margin:1px 0 0 1px}.laydate-theme-grid .laydate-month-list>li,.laydate-theme-grid .laydate-year-list>li{margin:0 -1px -1px 0}.laydate-theme-grid .laydate-year-list>li{height:43px;line-height:43px}.laydate-theme-grid .laydate-month-list>li{height:71px;line-height:71px}"
  },
  {
    "path": "public/layui/css/modules/layer/default/layer.css",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n .layui-layer-imgbar,.layui-layer-imgtit a,.layui-layer-tab .layui-layer-title span,.layui-layer-title{text-overflow:ellipsis;white-space:nowrap}html #layuicss-layer{display:none;position:absolute;width:1989px}.layui-layer,.layui-layer-shade{position:fixed;_position:absolute;pointer-events:auto}.layui-layer-shade{top:0;left:0;width:100%;height:100%;_height:expression(document.body.offsetHeight+\"px\")}.layui-layer{-webkit-overflow-scrolling:touch;top:150px;left:0;margin:0;padding:0;background-color:#fff;-webkit-background-clip:content;border-radius:2px;box-shadow:1px 1px 50px rgba(0,0,0,.3)}.layui-layer-close{position:absolute}.layui-layer-content{position:relative}.layui-layer-border{border:1px solid #B2B2B2;border:1px solid rgba(0,0,0,.1);box-shadow:1px 1px 5px rgba(0,0,0,.2)}.layui-layer-load{background:url(loading-1.gif) center center no-repeat #eee}.layui-layer-ico{background:url(icon.png) no-repeat}.layui-layer-btn a,.layui-layer-dialog .layui-layer-ico,.layui-layer-setwin a{display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-move{display:none;position:fixed;*position:absolute;left:0;top:0;width:100%;height:100%;cursor:move;opacity:0;filter:alpha(opacity=0);background-color:#fff;z-index:2147483647}.layui-layer-resize{position:absolute;width:15px;height:15px;right:0;bottom:0;cursor:se-resize}.layer-anim{-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.3s;animation-duration:.3s}@-webkit-keyframes layer-bounceIn{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes layer-bounceIn{0%{opacity:0;-webkit-transform:scale(.5);-ms-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-00{-webkit-animation-name:layer-bounceIn;animation-name:layer-bounceIn}@-webkit-keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);-ms-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);-ms-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-01{-webkit-animation-name:layer-zoomInDown;animation-name:layer-zoomInDown}@-webkit-keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.layer-anim-02{-webkit-animation-name:layer-fadeInUpBig;animation-name:layer-fadeInUpBig}@-webkit-keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);-ms-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);-ms-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-03{-webkit-animation-name:layer-zoomInLeft;animation-name:layer-zoomInLeft}@-webkit-keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}@keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);-ms-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);-ms-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}.layer-anim-04{-webkit-animation-name:layer-rollIn;animation-name:layer-rollIn}@keyframes layer-fadeIn{0%{opacity:0}100%{opacity:1}}.layer-anim-05{-webkit-animation-name:layer-fadeIn;animation-name:layer-fadeIn}@-webkit-keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.layer-anim-06{-webkit-animation-name:layer-shake;animation-name:layer-shake}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.layui-layer-title{padding:0 80px 0 20px;height:42px;line-height:42px;border-bottom:1px solid #eee;font-size:14px;color:#333;overflow:hidden;background-color:#F8F8F8;border-radius:2px 2px 0 0}.layui-layer-setwin{position:absolute;right:15px;*right:0;top:15px;font-size:0;line-height:initial}.layui-layer-setwin a{position:relative;width:16px;height:16px;margin-left:10px;font-size:12px;_overflow:hidden}.layui-layer-setwin .layui-layer-min cite{position:absolute;width:14px;height:2px;left:0;top:50%;margin-top:-1px;background-color:#2E2D3C;cursor:pointer;_overflow:hidden}.layui-layer-setwin .layui-layer-min:hover cite{background-color:#2D93CA}.layui-layer-setwin .layui-layer-max{background-position:-32px -40px}.layui-layer-setwin .layui-layer-max:hover{background-position:-16px -40px}.layui-layer-setwin .layui-layer-maxmin{background-position:-65px -40px}.layui-layer-setwin .layui-layer-maxmin:hover{background-position:-49px -40px}.layui-layer-setwin .layui-layer-close1{background-position:1px -40px;cursor:pointer}.layui-layer-setwin .layui-layer-close1:hover{opacity:.7}.layui-layer-setwin .layui-layer-close2{position:absolute;right:-28px;top:-28px;width:30px;height:30px;margin-left:0;background-position:-149px -31px;*right:-18px;_display:none}.layui-layer-setwin .layui-layer-close2:hover{background-position:-180px -31px}.layui-layer-btn{text-align:right;padding:0 15px 12px;pointer-events:auto;user-select:none;-webkit-user-select:none}.layui-layer-btn a{height:28px;line-height:28px;margin:5px 5px 0;padding:0 15px;border:1px solid #dedede;background-color:#fff;color:#333;border-radius:2px;font-weight:400;cursor:pointer;text-decoration:none}.layui-layer-btn a:hover{opacity:.9;text-decoration:none}.layui-layer-btn a:active{opacity:.8}.layui-layer-btn .layui-layer-btn0{border-color:#1E9FFF;background-color:#1E9FFF;color:#fff}.layui-layer-btn-l{text-align:left}.layui-layer-btn-c{text-align:center}.layui-layer-dialog{min-width:260px}.layui-layer-dialog .layui-layer-content{position:relative;padding:20px;line-height:24px;word-break:break-all;overflow:hidden;font-size:14px;overflow-x:hidden;overflow-y:auto}.layui-layer-dialog .layui-layer-content .layui-layer-ico{position:absolute;top:16px;left:15px;_left:-40px;width:30px;height:30px}.layui-layer-ico1{background-position:-30px 0}.layui-layer-ico2{background-position:-60px 0}.layui-layer-ico3{background-position:-90px 0}.layui-layer-ico4{background-position:-120px 0}.layui-layer-ico5{background-position:-150px 0}.layui-layer-ico6{background-position:-180px 0}.layui-layer-rim{border:6px solid #8D8D8D;border:6px solid rgba(0,0,0,.3);border-radius:5px;box-shadow:none}.layui-layer-msg{min-width:180px;border:1px solid #D3D4D3;box-shadow:none}.layui-layer-hui{min-width:100px;background-color:#000;filter:alpha(opacity=60);background-color:rgba(0,0,0,.6);color:#fff;border:none}.layui-layer-hui .layui-layer-content{padding:12px 25px;text-align:center}.layui-layer-dialog .layui-layer-padding{padding:20px 20px 20px 55px;text-align:left}.layui-layer-page .layui-layer-content{position:relative;overflow:auto}.layui-layer-iframe .layui-layer-btn,.layui-layer-page .layui-layer-btn{padding-top:10px}.layui-layer-nobg{background:0 0}.layui-layer-iframe iframe{display:block;width:100%}.layui-layer-loading{border-radius:100%;background:0 0;box-shadow:none;border:none}.layui-layer-loading .layui-layer-content{width:60px;height:24px;background:url(loading-0.gif) no-repeat}.layui-layer-loading .layui-layer-loading1{width:37px;height:37px;background:url(loading-1.gif) no-repeat}.layui-layer-ico16,.layui-layer-loading .layui-layer-loading2{width:32px;height:32px;background:url(loading-2.gif) no-repeat}.layui-layer-tips{background:0 0;box-shadow:none;border:none}.layui-layer-tips .layui-layer-content{position:relative;line-height:22px;min-width:12px;padding:8px 15px;font-size:12px;_float:left;border-radius:2px;box-shadow:1px 1px 3px rgba(0,0,0,.2);background-color:#000;color:#fff}.layui-layer-tips .layui-layer-close{right:-2px;top:-1px}.layui-layer-tips i.layui-layer-TipsG{position:absolute;width:0;height:0;border-width:8px;border-color:transparent;border-style:dashed;*overflow:hidden}.layui-layer-tips i.layui-layer-TipsB,.layui-layer-tips i.layui-layer-TipsT{left:5px;border-right-style:solid;border-right-color:#000}.layui-layer-tips i.layui-layer-TipsT{bottom:-8px}.layui-layer-tips i.layui-layer-TipsB{top:-8px}.layui-layer-tips i.layui-layer-TipsL,.layui-layer-tips i.layui-layer-TipsR{top:5px;border-bottom-style:solid;border-bottom-color:#000}.layui-layer-tips i.layui-layer-TipsR{left:-8px}.layui-layer-tips i.layui-layer-TipsL{right:-8px}.layui-layer-lan[type=dialog]{min-width:280px}.layui-layer-lan .layui-layer-title{background:#4476A7;color:#fff;border:none}.layui-layer-lan .layui-layer-btn{padding:5px 10px 10px;text-align:right;border-top:1px solid #E9E7E7}.layui-layer-lan .layui-layer-btn a{background:#fff;border-color:#E9E7E7;color:#333}.layui-layer-lan .layui-layer-btn .layui-layer-btn1{background:#C9C5C5}.layui-layer-molv .layui-layer-title{background:#009f95;color:#fff;border:none}.layui-layer-molv .layui-layer-btn a{background:#009f95;border-color:#009f95}.layui-layer-molv .layui-layer-btn .layui-layer-btn1{background:#92B8B1}.layui-layer-iconext{background:url(icon-ext.png) no-repeat}.layui-layer-prompt .layui-layer-input{display:block;width:230px;height:36px;margin:0 auto;line-height:30px;padding-left:10px;border:1px solid #e6e6e6;color:#333}.layui-layer-prompt textarea.layui-layer-input{width:300px;height:100px;line-height:20px;padding:6px 10px}.layui-layer-prompt .layui-layer-content{padding:20px}.layui-layer-prompt .layui-layer-btn{padding-top:0}.layui-layer-tab{box-shadow:1px 1px 50px rgba(0,0,0,.4)}.layui-layer-tab .layui-layer-title{padding-left:0;overflow:visible}.layui-layer-tab .layui-layer-title span{position:relative;float:left;min-width:80px;max-width:260px;padding:0 20px;text-align:center;overflow:hidden;cursor:pointer}.layui-layer-tab .layui-layer-title span.layui-this{height:43px;border-left:1px solid #eee;border-right:1px solid #eee;background-color:#fff;z-index:10}.layui-layer-tab .layui-layer-title span:first-child{border-left:none}.layui-layer-tabmain{line-height:24px;clear:both}.layui-layer-tabmain .layui-layer-tabli{display:none}.layui-layer-tabmain .layui-layer-tabli.layui-this{display:block}.layui-layer-photos{-webkit-animation-duration:.8s;animation-duration:.8s}.layui-layer-photos .layui-layer-content{overflow:hidden;text-align:center}.layui-layer-photos .layui-layer-phimg img{position:relative;width:100%;display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-imgbar,.layui-layer-imguide{display:none}.layui-layer-imgnext,.layui-layer-imgprev{position:absolute;top:50%;width:27px;_width:44px;height:44px;margin-top:-22px;outline:0;blr:expression(this.onFocus=this.blur())}.layui-layer-imgprev{left:10px;background-position:-5px -5px;_background-position:-70px -5px}.layui-layer-imgprev:hover{background-position:-33px -5px;_background-position:-120px -5px}.layui-layer-imgnext{right:10px;_right:8px;background-position:-5px -50px;_background-position:-70px -50px}.layui-layer-imgnext:hover{background-position:-33px -50px;_background-position:-120px -50px}.layui-layer-imgbar{position:absolute;left:0;bottom:0;width:100%;height:32px;line-height:32px;background-color:rgba(0,0,0,.8);background-color:#000\\9;filter:Alpha(opacity=80);color:#fff;overflow:hidden;font-size:0}.layui-layer-imgtit *{display:inline-block;*display:inline;*zoom:1;vertical-align:top;font-size:12px}.layui-layer-imgtit a{max-width:65%;overflow:hidden;color:#fff}.layui-layer-imgtit a:hover{color:#fff;text-decoration:underline}.layui-layer-imgtit em{padding-left:10px;font-style:normal}@-webkit-keyframes layer-bounceOut{100%{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes layer-bounceOut{100%{opacity:0;-webkit-transform:scale(.7);-ms-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);-ms-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-close{-webkit-animation-name:layer-bounceOut;animation-name:layer-bounceOut;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.2s;animation-duration:.2s}@media screen and (max-width:1100px){.layui-layer-iframe{overflow-y:auto;-webkit-overflow-scrolling:touch}}"
  },
  {
    "path": "public/layui/lay/modules/carousel.js",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n ;layui.define(\"jquery\",function(e){\"use strict\";var i=layui.$,n=(layui.hint(),layui.device(),{config:{},set:function(e){var n=this;return n.config=i.extend({},n.config,e),n},on:function(e,i){return layui.onevent.call(this,t,e,i)}}),t=\"carousel\",a=\"layui-this\",l=\">*[carousel-item]>*\",o=\"layui-carousel-left\",r=\"layui-carousel-right\",d=\"layui-carousel-prev\",s=\"layui-carousel-next\",u=\"layui-carousel-arrow\",c=\"layui-carousel-ind\",m=function(e){var t=this;t.config=i.extend({},t.config,n.config,e),t.render()};m.prototype.config={width:\"600px\",height:\"280px\",full:!1,arrow:\"hover\",indicator:\"inside\",autoplay:!0,interval:3e3,anim:\"\",trigger:\"click\",index:0},m.prototype.render=function(){var e=this,n=e.config;n.elem=i(n.elem),n.elem[0]&&(e.elemItem=n.elem.find(l),n.index<0&&(n.index=0),n.index>=e.elemItem.length&&(n.index=e.elemItem.length-1),n.interval<800&&(n.interval=800),n.full?n.elem.css({position:\"fixed\",width:\"100%\",height:\"100%\",zIndex:9999}):n.elem.css({width:n.width,height:n.height}),n.elem.attr(\"lay-anim\",n.anim),e.elemItem.eq(n.index).addClass(a),e.elemItem.length<=1||(e.indicator(),e.arrow(),e.autoplay(),e.events()))},m.prototype.reload=function(e){var n=this;clearInterval(n.timer),n.config=i.extend({},n.config,e),n.render()},m.prototype.prevIndex=function(){var e=this,i=e.config,n=i.index-1;return n<0&&(n=e.elemItem.length-1),n},m.prototype.nextIndex=function(){var e=this,i=e.config,n=i.index+1;return n>=e.elemItem.length&&(n=0),n},m.prototype.addIndex=function(e){var i=this,n=i.config;e=e||1,n.index=n.index+e,n.index>=i.elemItem.length&&(n.index=0)},m.prototype.subIndex=function(e){var i=this,n=i.config;e=e||1,n.index=n.index-e,n.index<0&&(n.index=i.elemItem.length-1)},m.prototype.autoplay=function(){var e=this,i=e.config;i.autoplay&&(e.timer=setInterval(function(){e.slide()},i.interval))},m.prototype.arrow=function(){var e=this,n=e.config,t=i(['<button class=\"layui-icon '+u+'\" lay-type=\"sub\">'+(\"updown\"===n.anim?\"&#xe619;\":\"&#xe603;\")+\"</button>\",'<button class=\"layui-icon '+u+'\" lay-type=\"add\">'+(\"updown\"===n.anim?\"&#xe61a;\":\"&#xe602;\")+\"</button>\"].join(\"\"));n.elem.attr(\"lay-arrow\",n.arrow),n.elem.find(\".\"+u)[0]&&n.elem.find(\".\"+u).remove(),n.elem.append(t),t.on(\"click\",function(){var n=i(this),t=n.attr(\"lay-type\");e.slide(t)})},m.prototype.indicator=function(){var e=this,n=e.config,t=e.elemInd=i(['<div class=\"'+c+'\"><ul>',function(){var i=[];return layui.each(e.elemItem,function(e){i.push(\"<li\"+(n.index===e?' class=\"layui-this\"':\"\")+\"></li>\")}),i.join(\"\")}(),\"</ul></div>\"].join(\"\"));n.elem.attr(\"lay-indicator\",n.indicator),n.elem.find(\".\"+c)[0]&&n.elem.find(\".\"+c).remove(),n.elem.append(t),\"updown\"===n.anim&&t.css(\"margin-top\",-(t.height()/2)),t.find(\"li\").on(\"hover\"===n.trigger?\"mouseover\":n.trigger,function(){var t=i(this),a=t.index();a>n.index?e.slide(\"add\",a-n.index):a<n.index&&e.slide(\"sub\",n.index-a)})},m.prototype.slide=function(e,i){var n=this,l=n.elemItem,u=n.config,c=u.index,m=u.elem.attr(\"lay-filter\");n.haveSlide||(\"sub\"===e?(n.subIndex(i),l.eq(u.index).addClass(d),setTimeout(function(){l.eq(c).addClass(r),l.eq(u.index).addClass(r)},50)):(n.addIndex(i),l.eq(u.index).addClass(s),setTimeout(function(){l.eq(c).addClass(o),l.eq(u.index).addClass(o)},50)),setTimeout(function(){l.removeClass(a+\" \"+d+\" \"+s+\" \"+o+\" \"+r),l.eq(u.index).addClass(a),n.haveSlide=!1},300),n.elemInd.find(\"li\").eq(u.index).addClass(a).siblings().removeClass(a),n.haveSlide=!0,layui.event.call(this,t,\"change(\"+m+\")\",{index:u.index,prevIndex:c,item:l.eq(u.index)}))},m.prototype.events=function(){var e=this,i=e.config;i.elem.data(\"haveEvents\")||(i.elem.on(\"mouseenter\",function(){clearInterval(e.timer)}).on(\"mouseleave\",function(){e.autoplay()}),i.elem.data(\"haveEvents\",!0))},n.render=function(e){var i=new m(e);return i},e(t,n)});"
  },
  {
    "path": "public/layui/lay/modules/code.js",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n ;layui.define(\"jquery\",function(e){\"use strict\";var a=layui.$,l=\"http://www.layui.com/doc/modules/code.html\";e(\"code\",function(e){var t=[];e=e||{},e.elem=a(e.elem||\".layui-code\"),e.about=!(\"about\"in e)||e.about,e.elem.each(function(){t.push(this)}),layui.each(t.reverse(),function(t,i){var c=a(i),o=c.html();(c.attr(\"lay-encode\")||e.encode)&&(o=o.replace(/&(?!#?[a-zA-Z0-9]+;)/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/'/g,\"&#39;\").replace(/\"/g,\"&quot;\")),c.html('<ol class=\"layui-code-ol\"><li>'+o.replace(/[\\r\\t\\n]+/g,\"</li><li>\")+\"</li></ol>\"),c.find(\">.layui-code-h3\")[0]||c.prepend('<h3 class=\"layui-code-h3\">'+(c.attr(\"lay-title\")||e.title||\"code\")+(e.about?'<a href=\"'+l+'\" target=\"_blank\">layui.code</a>':\"\")+\"</h3>\");var d=c.find(\">.layui-code-ol\");c.addClass(\"layui-box layui-code-view\"),(c.attr(\"lay-skin\")||e.skin)&&c.addClass(\"layui-code-\"+(c.attr(\"lay-skin\")||e.skin)),(d.find(\"li\").length/100|0)>0&&d.css(\"margin-left\",(d.find(\"li\").length/100|0)+\"px\"),(c.attr(\"lay-height\")||e.height)&&d.css(\"max-height\",c.attr(\"lay-height\")||e.height)})})}).addcss(\"modules/code.css\",\"skincodecss\");"
  },
  {
    "path": "public/layui/lay/modules/element.js",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n ;layui.define(\"jquery\",function(t){\"use strict\";var a=layui.$,i=(layui.hint(),layui.device()),e=\"element\",l=\"layui-this\",n=\"layui-show\",s=function(){this.config={}};s.prototype.set=function(t){var i=this;return a.extend(!0,i.config,t),i},s.prototype.on=function(t,a){return layui.onevent.call(this,e,t,a)},s.prototype.tabAdd=function(t,i){var e=\".layui-tab-title\",l=a(\".layui-tab[lay-filter=\"+t+\"]\"),n=l.children(e),s=n.children(\".layui-tab-bar\"),o=l.children(\".layui-tab-content\"),r='<li lay-id=\"'+(i.id||\"\")+'\"'+(i.attr?' lay-attr=\"'+i.attr+'\"':\"\")+\">\"+(i.title||\"unnaming\")+\"</li>\";return s[0]?s.before(r):n.append(r),o.append('<div class=\"layui-tab-item\">'+(i.content||\"\")+\"</div>\"),f.hideTabMore(!0),f.tabAuto(),this},s.prototype.tabDelete=function(t,i){var e=\".layui-tab-title\",l=a(\".layui-tab[lay-filter=\"+t+\"]\"),n=l.children(e),s=n.find('>li[lay-id=\"'+i+'\"]');return f.tabDelete(null,s),this},s.prototype.tabChange=function(t,i){var e=\".layui-tab-title\",l=a(\".layui-tab[lay-filter=\"+t+\"]\"),n=l.children(e),s=n.find('>li[lay-id=\"'+i+'\"]');return f.tabClick.call(s[0],null,null,s),this},s.prototype.tab=function(t){t=t||{},b.on(\"click\",t.headerElem,function(i){var e=a(this).index();f.tabClick.call(this,i,e,null,t)})},s.prototype.progress=function(t,i){var e=\"layui-progress\",l=a(\".\"+e+\"[lay-filter=\"+t+\"]\"),n=l.find(\".\"+e+\"-bar\"),s=n.find(\".\"+e+\"-text\");return n.css(\"width\",i),s.text(i),this};var o=\".layui-nav\",r=\"layui-nav-item\",c=\"layui-nav-bar\",u=\"layui-nav-tree\",d=\"layui-nav-child\",y=\"layui-nav-more\",h=\"layui-anim layui-anim-upbit\",f={tabClick:function(t,i,s,o){o=o||{};var r=s||a(this),i=i||r.parent().children(\"li\").index(r),c=o.headerElem?r.parent():r.parents(\".layui-tab\").eq(0),u=o.bodyElem?a(o.bodyElem):c.children(\".layui-tab-content\").children(\".layui-tab-item\"),d=r.find(\"a\"),y=c.attr(\"lay-filter\");\"javascript:;\"!==d.attr(\"href\")&&\"_blank\"===d.attr(\"target\")||(r.addClass(l).siblings().removeClass(l),u.eq(i).addClass(n).siblings().removeClass(n)),layui.event.call(this,e,\"tab(\"+y+\")\",{elem:c,index:i})},tabDelete:function(t,i){var n=i||a(this).parent(),s=n.index(),o=n.parents(\".layui-tab\").eq(0),r=o.children(\".layui-tab-content\").children(\".layui-tab-item\"),c=o.attr(\"lay-filter\");n.hasClass(l)&&(n.next()[0]?f.tabClick.call(n.next()[0],null,s+1):n.prev()[0]&&f.tabClick.call(n.prev()[0],null,s-1)),n.remove(),r.eq(s).remove(),setTimeout(function(){f.tabAuto()},50),layui.event.call(this,e,\"tabDelete(\"+c+\")\",{elem:o,index:s})},tabAuto:function(){var t=\"layui-tab-more\",e=\"layui-tab-bar\",l=\"layui-tab-close\",n=this;a(\".layui-tab\").each(function(){var s=a(this),o=s.children(\".layui-tab-title\"),r=(s.children(\".layui-tab-content\").children(\".layui-tab-item\"),'lay-stope=\"tabmore\"'),c=a('<span class=\"layui-unselect layui-tab-bar\" '+r+\"><i \"+r+' class=\"layui-icon\">&#xe61a;</i></span>');if(n===window&&8!=i.ie&&f.hideTabMore(!0),s.attr(\"lay-allowClose\")&&o.find(\"li\").each(function(){var t=a(this);if(!t.find(\".\"+l)[0]){var i=a('<i class=\"layui-icon layui-unselect '+l+'\">&#x1006;</i>');i.on(\"click\",f.tabDelete),t.append(i)}}),\"string\"!=typeof s.attr(\"lay-unauto\"))if(o.prop(\"scrollWidth\")>o.outerWidth()+1){if(o.find(\".\"+e)[0])return;o.append(c),s.attr(\"overflow\",\"\"),c.on(\"click\",function(a){o[this.title?\"removeClass\":\"addClass\"](t),this.title=this.title?\"\":\"收缩\"})}else o.find(\".\"+e).remove(),s.removeAttr(\"overflow\")})},hideTabMore:function(t){var i=a(\".layui-tab-title\");t!==!0&&\"tabmore\"===a(t.target).attr(\"lay-stope\")||(i.removeClass(\"layui-tab-more\"),i.find(\".layui-tab-bar\").attr(\"title\",\"\"))},clickThis:function(){var t=a(this),i=t.parents(o),n=i.attr(\"lay-filter\"),s=t.parent(),c=t.siblings(\".\"+d),y=\"string\"==typeof s.attr(\"lay-unselect\");\"javascript:;\"!==t.attr(\"href\")&&\"_blank\"===t.attr(\"target\")||y||c[0]||(i.find(\".\"+l).removeClass(l),s.addClass(l)),i.hasClass(u)&&(c.removeClass(h),c[0]&&(s[\"none\"===c.css(\"display\")?\"addClass\":\"removeClass\"](r+\"ed\"),\"all\"===i.attr(\"lay-shrink\")&&s.siblings().removeClass(r+\"ed\"))),layui.event.call(this,e,\"nav(\"+n+\")\",t)},collapse:function(){var t=a(this),i=t.find(\".layui-colla-icon\"),l=t.siblings(\".layui-colla-content\"),s=t.parents(\".layui-collapse\").eq(0),o=s.attr(\"lay-filter\"),r=\"none\"===l.css(\"display\");if(\"string\"==typeof s.attr(\"lay-accordion\")){var c=s.children(\".layui-colla-item\").children(\".\"+n);c.siblings(\".layui-colla-title\").children(\".layui-colla-icon\").html(\"&#xe602;\"),c.removeClass(n)}l[r?\"addClass\":\"removeClass\"](n),i.html(r?\"&#xe61a;\":\"&#xe602;\"),layui.event.call(this,e,\"collapse(\"+o+\")\",{title:t,content:l,show:r})}};s.prototype.init=function(t,e){var l=function(){return e?'[lay-filter=\"'+e+'\"]':\"\"}(),s={tab:function(){f.tabAuto.call({})},nav:function(){var t=200,e={},s={},p={},b=function(l,o,r){var c=a(this),f=c.find(\".\"+d);o.hasClass(u)?l.css({top:c.position().top,height:c.children(\"a\").outerHeight(),opacity:1}):(f.addClass(h),l.css({left:c.position().left+parseFloat(c.css(\"marginLeft\")),top:c.position().top+c.height()-l.height()}),e[r]=setTimeout(function(){l.css({width:c.width(),opacity:1})},i.ie&&i.ie<10?0:t),clearTimeout(p[r]),\"block\"===f.css(\"display\")&&clearTimeout(s[r]),s[r]=setTimeout(function(){f.addClass(n),c.find(\".\"+y).addClass(y+\"d\")},300))};a(o+l).each(function(i){var l=a(this),o=a('<span class=\"'+c+'\"></span>'),h=l.find(\".\"+r);l.find(\".\"+c)[0]||(l.append(o),h.on(\"mouseenter\",function(){b.call(this,o,l,i)}).on(\"mouseleave\",function(){l.hasClass(u)||(clearTimeout(s[i]),s[i]=setTimeout(function(){l.find(\".\"+d).removeClass(n),l.find(\".\"+y).removeClass(y+\"d\")},300))}),l.on(\"mouseleave\",function(){clearTimeout(e[i]),p[i]=setTimeout(function(){l.hasClass(u)?o.css({height:0,top:o.position().top+o.height()/2,opacity:0}):o.css({width:0,left:o.position().left+o.width()/2,opacity:0})},t)})),h.find(\"a\").each(function(){var t=a(this),i=(t.parent(),t.siblings(\".\"+d));i[0]&&!t.children(\".\"+y)[0]&&t.append('<span class=\"'+y+'\"></span>'),t.off(\"click\",f.clickThis).on(\"click\",f.clickThis)})})},breadcrumb:function(){var t=\".layui-breadcrumb\";a(t+l).each(function(){var t=a(this),i=\"lay-separator\",e=t.attr(i)||\"/\",l=t.find(\"a\");l.next(\"span[\"+i+\"]\")[0]||(l.each(function(t){t!==l.length-1&&a(this).after(\"<span \"+i+\">\"+e+\"</span>\")}),t.css(\"visibility\",\"visible\"))})},progress:function(){var t=\"layui-progress\";a(\".\"+t+l).each(function(){var i=a(this),e=i.find(\".layui-progress-bar\"),l=e.attr(\"lay-percent\");e.css(\"width\",function(){return/^.+\\/.+$/.test(l)?100*new Function(\"return \"+l)()+\"%\":l}()),i.attr(\"lay-showPercent\")&&setTimeout(function(){e.html('<span class=\"'+t+'-text\">'+l+\"</span>\")},350)})},collapse:function(){var t=\"layui-collapse\";a(\".\"+t+l).each(function(){var t=a(this).find(\".layui-colla-item\");t.each(function(){var t=a(this),i=t.find(\".layui-colla-title\"),e=t.find(\".layui-colla-content\"),l=\"none\"===e.css(\"display\");i.find(\".layui-colla-icon\").remove(),i.append('<i class=\"layui-icon layui-colla-icon\">'+(l?\"&#xe602;\":\"&#xe61a;\")+\"</i>\"),i.off(\"click\",f.collapse).on(\"click\",f.collapse)})})}};return s[t]?s[t]():layui.each(s,function(t,a){a()})},s.prototype.render=s.prototype.init;var p=new s,b=a(document);p.render();var v=\".layui-tab-title li\";b.on(\"click\",v,f.tabClick),b.on(\"click\",f.hideTabMore),a(window).on(\"resize\",f.tabAuto),t(e,p)});"
  },
  {
    "path": "public/layui/lay/modules/flow.js",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n ;layui.define(\"jquery\",function(e){\"use strict\";var l=layui.$,o=function(e){},t='<i class=\"layui-anim layui-anim-rotate layui-anim-loop layui-icon \">&#xe63e;</i>';o.prototype.load=function(e){var o,i,n,r,a=this,c=0;e=e||{};var f=l(e.elem);if(f[0]){var m=l(e.scrollElem||document),u=e.mb||50,s=!(\"isAuto\"in e)||e.isAuto,v=e.end||\"没有更多了\",y=e.scrollElem&&e.scrollElem!==document,d=\"<cite>加载更多</cite>\",h=l('<div class=\"layui-flow-more\"><a href=\"javascript:;\">'+d+\"</a></div>\");f.find(\".layui-flow-more\")[0]||f.append(h);var p=function(e,t){e=l(e),h.before(e),t=0==t||null,t?h.html(v):h.find(\"a\").html(d),i=t,o=null,n&&n()},g=function(){o=!0,h.find(\"a\").html(t),\"function\"==typeof e.done&&e.done(++c,p)};if(g(),h.find(\"a\").on(\"click\",function(){l(this);i||o||g()}),e.isLazyimg)var n=a.lazyimg({elem:e.elem+\" img\",scrollElem:e.scrollElem});return s?(m.on(\"scroll\",function(){var e=l(this),t=e.scrollTop();r&&clearTimeout(r),i||(r=setTimeout(function(){var i=y?e.height():l(window).height(),n=y?e.prop(\"scrollHeight\"):document.documentElement.scrollHeight;n-t-i<=u&&(o||g())},100))}),a):a}},o.prototype.lazyimg=function(e){var o,t=this,i=0;e=e||{};var n=l(e.scrollElem||document),r=e.elem||\"img\",a=e.scrollElem&&e.scrollElem!==document,c=function(e,l){var o=n.scrollTop(),r=o+l,c=a?function(){return e.offset().top-n.offset().top+o}():e.offset().top;if(c>=o&&c<=r&&!e.attr(\"src\")){var m=e.attr(\"lay-src\");layui.img(m,function(){var l=t.lazyimg.elem.eq(i);e.attr(\"src\",m).removeAttr(\"lay-src\"),l[0]&&f(l),i++})}},f=function(e,o){var f=a?(o||n).height():l(window).height(),m=n.scrollTop(),u=m+f;if(t.lazyimg.elem=l(r),e)c(e,f);else for(var s=0;s<t.lazyimg.elem.length;s++){var v=t.lazyimg.elem.eq(s),y=a?function(){return v.offset().top-n.offset().top+m}():v.offset().top;if(c(v,f),i=s,y>u)break}};if(f(),!o){var m;n.on(\"scroll\",function(){var e=l(this);m&&clearTimeout(m),m=setTimeout(function(){f(null,e)},50)}),o=!0}return f},e(\"flow\",new o)});"
  },
  {
    "path": "public/layui/lay/modules/form.js",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n ;layui.define(\"layer\",function(e){\"use strict\";var i=layui.$,t=layui.layer,a=layui.hint(),n=layui.device(),l=\"form\",r=\".layui-form\",s=\"layui-this\",o=\"layui-hide\",c=\"layui-disabled\",u=function(){this.config={verify:{required:[/[\\S]+/,\"必填项不能为空\"],phone:[/^1\\d{10}$/,\"请输入正确的手机号\"],email:[/^([a-zA-Z0-9_\\.\\-])+\\@(([a-zA-Z0-9\\-])+\\.)+([a-zA-Z0-9]{2,4})+$/,\"邮箱格式不正确\"],url:[/(^#)|(^http(s*):\\/\\/[^\\s]+\\.[^\\s]+)/,\"链接格式不正确\"],number:function(e){if(!e||isNaN(e))return\"只能填写数字\"},date:[/^(\\d{4})[-\\/](\\d{1}|0\\d{1}|1[0-2])([-\\/](\\d{1}|0\\d{1}|[1-2][0-9]|3[0-1]))*$/,\"日期格式不正确\"],identity:[/(^\\d{15}$)|(^\\d{17}(x|X|\\d)$)/,\"请输入正确的身份证号\"]}}};u.prototype.set=function(e){var t=this;return i.extend(!0,t.config,e),t},u.prototype.verify=function(e){var t=this;return i.extend(!0,t.config.verify,e),t},u.prototype.on=function(e,i){return layui.onevent.call(this,l,e,i)},u.prototype.val=function(e,t){var a=i(r+'[lay-filter=\"'+e+'\"]');a.each(function(e,a){var n=i(this);layui.each(t,function(e,i){var t,a=n.find('[name=\"'+e+'\"]');a[0]&&(t=a[0].type,\"checkbox\"===t?a[0].checked=i:\"radio\"===t?a.each(function(){this.value===i&&(this.checked=!0)}):a.val(i))})}),f.render(null,e)},u.prototype.render=function(e,t){var n=this,u=i(r+function(){return t?'[lay-filter=\"'+t+'\"]':\"\"}()),d={select:function(){var e,t=\"请选择\",a=\"layui-form-select\",n=\"layui-select-title\",r=\"layui-select-none\",d=\"\",f=u.find(\"select\"),v=function(t,l){i(t.target).parent().hasClass(n)&&!l||(i(\".\"+a).removeClass(a+\"ed \"+a+\"up\"),e&&d&&e.val(d)),e=null},y=function(t,u,f){var y,p=i(this),m=t.find(\".\"+n),k=m.find(\"input\"),g=t.find(\"dl\"),x=g.children(\"dd\"),b=this.selectedIndex;if(!u){var C=function(){var e=t.offset().top+t.outerHeight()+5-h.scrollTop(),i=g.outerHeight();b=p[0].selectedIndex,t.addClass(a+\"ed\"),x.removeClass(o),y=null,x.eq(b).addClass(s).siblings().removeClass(s),e+i>h.height()&&e>=i&&t.addClass(a+\"up\")},w=function(e){t.removeClass(a+\"ed \"+a+\"up\"),k.blur(),y=null,e||$(k.val(),function(e){e&&(d=g.find(\".\"+s).html(),k&&k.val(d))})};m.on(\"click\",function(e){t.hasClass(a+\"ed\")?w():(v(e,!0),C()),g.find(\".\"+r).remove()}),m.find(\".layui-edge\").on(\"click\",function(){k.focus()}),k.on(\"keyup\",function(e){var i=e.keyCode;9===i&&C()}).on(\"keydown\",function(e){var i=e.keyCode;9===i&&w();var t=function(i,a){var n,l;if(e.preventDefault(),a=function(){return a&&a[0]?a:y&&y[0]?y:x.eq(b)}(),l=a[i](),n=a[i](\"dd\"),l[0]){if(y=a[i](),!n[0]||n.hasClass(c))return t(i,y);n.addClass(s).siblings().removeClass(s);var r=g.children(\"dd.layui-this\"),o=r.position().top,u=g.height(),d=r.height();o>u&&g.scrollTop(o+g.scrollTop()-u+d-5),o<0&&g.scrollTop(o+g.scrollTop())}};38===i&&t(\"prev\"),40===i&&t(\"next\"),13===i&&(e.preventDefault(),g.children(\"dd.\"+s).trigger(\"click\"))});var $=function(e,t,a){var n=0;layui.each(x,function(){var t=i(this),l=t.text(),r=l.indexOf(e)===-1;(\"\"===e||\"blur\"===a?e!==l:r)&&n++,\"keyup\"===a&&t[r?\"addClass\":\"removeClass\"](o)});var l=n===x.length;return t(l),l},T=function(e){var i=this.value,t=e.keyCode;return 9!==t&&13!==t&&37!==t&&38!==t&&39!==t&&40!==t&&($(i,function(e){e?g.find(\".\"+r)[0]||g.append('<p class=\"'+r+'\">无匹配项</p>'):g.find(\".\"+r).remove()},\"keyup\"),void(\"\"===i&&g.find(\".\"+r).remove()))};f&&k.on(\"keyup\",T).on(\"blur\",function(t){var a=p[0].selectedIndex;e=k,d=i(p[0].options[a]).html(),setTimeout(function(){$(k.val(),function(e){d||k.val(\"\")},\"blur\")},200)}),x.on(\"click\",function(){var e=i(this),a=e.attr(\"lay-value\"),n=p.attr(\"lay-filter\");return!e.hasClass(c)&&(e.hasClass(\"layui-select-tips\")?k.val(\"\"):(k.val(e.text()),e.addClass(s)),e.siblings().removeClass(s),p.val(a).removeClass(\"layui-form-danger\"),layui.event.call(this,l,\"select(\"+n+\")\",{elem:p[0],value:a,othis:t}),w(!0),!1)}),t.find(\"dl>dt\").on(\"click\",function(e){return!1}),i(document).off(\"click\",v).on(\"click\",v)}};f.each(function(e,l){var r=i(this),o=r.next(\".\"+a),u=this.disabled,d=l.value,f=i(l.options[l.selectedIndex]),v=l.options[0];if(\"string\"==typeof r.attr(\"lay-ignore\"))return r.show();var h=\"string\"==typeof r.attr(\"lay-search\"),p=v?v.value?t:v.innerHTML||t:t,m=i(['<div class=\"'+(h?\"\":\"layui-unselect \")+a,(u?\" layui-select-disabled\":\"\")+'\">','<div class=\"'+n+'\">','<input type=\"text\" placeholder=\"'+p+'\" '+('value=\"'+(d?f.html():\"\")+'\"')+(h?\"\":\" readonly\")+' class=\"layui-input'+(h?\"\":\" layui-unselect\")+(u?\" \"+c:\"\")+'\">','<i class=\"layui-edge\"></i></div>','<dl class=\"layui-anim layui-anim-upbit'+(r.find(\"optgroup\")[0]?\" layui-select-group\":\"\")+'\">',function(e){var i=[];return layui.each(e,function(e,a){0!==e||a.value?\"optgroup\"===a.tagName.toLowerCase()?i.push(\"<dt>\"+a.label+\"</dt>\"):i.push('<dd lay-value=\"'+a.value+'\" class=\"'+(d===a.value?s:\"\")+(a.disabled?\" \"+c:\"\")+'\">'+a.innerHTML+\"</dd>\"):i.push('<dd lay-value=\"\" class=\"layui-select-tips\">'+(a.innerHTML||t)+\"</dd>\")}),0===i.length&&i.push('<dd lay-value=\"\" class=\"'+c+'\">没有选项</dd>'),i.join(\"\")}(r.find(\"*\"))+\"</dl>\",\"</div>\"].join(\"\"));o[0]&&o.remove(),r.after(m),y.call(this,m,u,h)})},checkbox:function(){var e={checkbox:[\"layui-form-checkbox\",\"layui-form-checked\",\"checkbox\"],_switch:[\"layui-form-switch\",\"layui-form-onswitch\",\"switch\"]},t=u.find(\"input[type=checkbox]\"),a=function(e,t){var a=i(this);e.on(\"click\",function(){var i=a.attr(\"lay-filter\"),n=(a.attr(\"lay-text\")||\"\").split(\"|\");a[0].disabled||(a[0].checked?(a[0].checked=!1,e.removeClass(t[1]).find(\"em\").text(n[1])):(a[0].checked=!0,e.addClass(t[1]).find(\"em\").text(n[0])),layui.event.call(a[0],l,t[2]+\"(\"+i+\")\",{elem:a[0],value:a[0].value,othis:e}))})};t.each(function(t,n){var l=i(this),r=l.attr(\"lay-skin\"),s=(l.attr(\"lay-text\")||\"\").split(\"|\"),o=this.disabled;\"switch\"===r&&(r=\"_\"+r);var u=e[r]||e.checkbox;if(\"string\"==typeof l.attr(\"lay-ignore\"))return l.show();var d=l.next(\".\"+u[0]),f=i(['<div class=\"layui-unselect '+u[0],n.checked?\" \"+u[1]:\"\",o?\" layui-checkbox-disbaled \"+c:\"\",'\"',r?' lay-skin=\"'+r+'\"':\"\",\">\",function(){var e=n.title.replace(/\\s/g,\"\"),i={checkbox:[e?\"<span>\"+n.title+\"</span>\":\"\",'<i class=\"layui-icon layui-icon-ok\"></i>'].join(\"\"),_switch:\"<em>\"+((n.checked?s[0]:s[1])||\"\")+\"</em><i></i>\"};return i[r]||i.checkbox}(),\"</div>\"].join(\"\"));d[0]&&d.remove(),l.after(f),a.call(this,f,u)})},radio:function(){var e=\"layui-form-radio\",t=[\"&#xe643;\",\"&#xe63f;\"],a=u.find(\"input[type=radio]\"),n=function(a){var n=i(this),s=\"layui-anim-scaleSpring\";a.on(\"click\",function(){var o=n[0].name,c=n.parents(r),u=n.attr(\"lay-filter\"),d=c.find(\"input[name=\"+o.replace(/(\\.|#|\\[|\\])/g,\"\\\\$1\")+\"]\");n[0].disabled||(layui.each(d,function(){var a=i(this).next(\".\"+e);this.checked=!1,a.removeClass(e+\"ed\"),a.find(\".layui-icon\").removeClass(s).html(t[1])}),n[0].checked=!0,a.addClass(e+\"ed\"),a.find(\".layui-icon\").addClass(s).html(t[0]),layui.event.call(n[0],l,\"radio(\"+u+\")\",{elem:n[0],value:n[0].value,othis:a}))})};a.each(function(a,l){var r=i(this),s=r.next(\".\"+e),o=this.disabled;if(\"string\"==typeof r.attr(\"lay-ignore\"))return r.show();s[0]&&s.remove();var u=i(['<div class=\"layui-unselect '+e,l.checked?\" \"+e+\"ed\":\"\",(o?\" layui-radio-disbaled \"+c:\"\")+'\">','<i class=\"layui-anim layui-icon\">'+t[l.checked?0:1]+\"</i>\",\"<div>\"+function(){var e=l.title||\"\";return\"string\"==typeof r.next().attr(\"lay-radio\")&&(e=r.next().html(),r.next().remove()),e}()+\"</div>\",\"</div>\"].join(\"\"));r.after(u),n.call(this,u)})}};return e?d[e]?d[e]():a.error(\"不支持的\"+e+\"表单渲染\"):layui.each(d,function(e,i){i()}),n};var d=function(){var e=i(this),a=f.config.verify,s=null,o=\"layui-form-danger\",c={},u=e.parents(r),d=u.find(\"*[lay-verify]\"),v=e.parents(\"form\")[0],h=u.find(\"input,select,textarea\"),y=e.attr(\"lay-filter\");if(layui.each(d,function(e,l){var r=i(this),c=r.attr(\"lay-verify\").split(\"|\"),u=r.attr(\"lay-verType\"),d=r.val();if(r.removeClass(o),layui.each(c,function(e,i){var c,f=\"\",v=\"function\"==typeof a[i];if(a[i]){var c=v?f=a[i](d,l):!a[i][0].test(d);if(f=f||a[i][1],c)return\"tips\"===u?t.tips(f,function(){return\"string\"==typeof r.attr(\"lay-ignore\")||\"select\"!==l.tagName.toLowerCase()&&!/^checkbox|radio$/.test(l.type)?r:r.next()}(),{tips:1}):\"alert\"===u?t.alert(f,{title:\"提示\",shadeClose:!0}):t.msg(f,{icon:5,shift:6}),n.android||n.ios||l.focus(),r.addClass(o),s=!0}}),s)return s}),s)return!1;var p={};return layui.each(h,function(e,i){if(i.name=(i.name||\"\").replace(/^\\s*|\\s*&/,\"\"),i.name){if(/^.*\\[\\]$/.test(i.name)){var t=i.name.match(/^(.*)\\[\\]$/g)[0];p[t]=0|p[t],i.name=i.name.replace(/^(.*)\\[\\]$/,\"$1[\"+p[t]++ +\"]\")}/^checkbox|radio$/.test(i.type)&&!i.checked||(c[i.name]=i.value)}}),layui.event.call(this,l,\"submit(\"+y+\")\",{elem:this,form:v,field:c})},f=new u,v=i(document),h=i(window);f.render(),v.on(\"reset\",r,function(){var e=i(this).attr(\"lay-filter\");setTimeout(function(){f.render(null,e)},50)}),v.on(\"submit\",r,d).on(\"click\",\"*[lay-submit]\",d),e(l,f)});"
  },
  {
    "path": "public/layui/lay/modules/jquery.js",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n ;!function(e,t){\"object\"==typeof module&&\"object\"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error(\"jQuery requires a window with a document\");return t(e)}:t(e)}(\"undefined\"!=typeof window?window:this,function(e,t){function n(e){var t=!!e&&\"length\"in e&&e.length,n=pe.type(e);return\"function\"!==n&&!pe.isWindow(e)&&(\"array\"===n||0===t||\"number\"==typeof t&&t>0&&t-1 in e)}function r(e,t,n){if(pe.isFunction(t))return pe.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return pe.grep(e,function(e){return e===t!==n});if(\"string\"==typeof t){if(Ce.test(t))return pe.filter(t,e,n);t=pe.filter(t,e)}return pe.grep(e,function(e){return pe.inArray(e,t)>-1!==n})}function i(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}function o(e){var t={};return pe.each(e.match(De)||[],function(e,n){t[n]=!0}),t}function a(){re.addEventListener?(re.removeEventListener(\"DOMContentLoaded\",s),e.removeEventListener(\"load\",s)):(re.detachEvent(\"onreadystatechange\",s),e.detachEvent(\"onload\",s))}function s(){(re.addEventListener||\"load\"===e.event.type||\"complete\"===re.readyState)&&(a(),pe.ready())}function u(e,t,n){if(void 0===n&&1===e.nodeType){var r=\"data-\"+t.replace(_e,\"-$1\").toLowerCase();if(n=e.getAttribute(r),\"string\"==typeof n){try{n=\"true\"===n||\"false\"!==n&&(\"null\"===n?null:+n+\"\"===n?+n:qe.test(n)?pe.parseJSON(n):n)}catch(i){}pe.data(e,t,n)}else n=void 0}return n}function l(e){var t;for(t in e)if((\"data\"!==t||!pe.isEmptyObject(e[t]))&&\"toJSON\"!==t)return!1;return!0}function c(e,t,n,r){if(He(e)){var i,o,a=pe.expando,s=e.nodeType,u=s?pe.cache:e,l=s?e[a]:e[a]&&a;if(l&&u[l]&&(r||u[l].data)||void 0!==n||\"string\"!=typeof t)return l||(l=s?e[a]=ne.pop()||pe.guid++:a),u[l]||(u[l]=s?{}:{toJSON:pe.noop}),\"object\"!=typeof t&&\"function\"!=typeof t||(r?u[l]=pe.extend(u[l],t):u[l].data=pe.extend(u[l].data,t)),o=u[l],r||(o.data||(o.data={}),o=o.data),void 0!==n&&(o[pe.camelCase(t)]=n),\"string\"==typeof t?(i=o[t],null==i&&(i=o[pe.camelCase(t)])):i=o,i}}function f(e,t,n){if(He(e)){var r,i,o=e.nodeType,a=o?pe.cache:e,s=o?e[pe.expando]:pe.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){pe.isArray(t)?t=t.concat(pe.map(t,pe.camelCase)):t in r?t=[t]:(t=pe.camelCase(t),t=t in r?[t]:t.split(\" \")),i=t.length;for(;i--;)delete r[t[i]];if(n?!l(r):!pe.isEmptyObject(r))return}(n||(delete a[s].data,l(a[s])))&&(o?pe.cleanData([e],!0):fe.deleteExpando||a!=a.window?delete a[s]:a[s]=void 0)}}}function d(e,t,n,r){var i,o=1,a=20,s=r?function(){return r.cur()}:function(){return pe.css(e,t,\"\")},u=s(),l=n&&n[3]||(pe.cssNumber[t]?\"\":\"px\"),c=(pe.cssNumber[t]||\"px\"!==l&&+u)&&Me.exec(pe.css(e,t));if(c&&c[3]!==l){l=l||c[3],n=n||[],c=+u||1;do o=o||\".5\",c/=o,pe.style(e,t,c+l);while(o!==(o=s()/u)&&1!==o&&--a)}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}function p(e){var t=ze.split(\"|\"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}function h(e,t){var n,r,i=0,o=\"undefined\"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||\"*\"):\"undefined\"!=typeof e.querySelectorAll?e.querySelectorAll(t||\"*\"):void 0;if(!o)for(o=[],n=e.childNodes||e;null!=(r=n[i]);i++)!t||pe.nodeName(r,t)?o.push(r):pe.merge(o,h(r,t));return void 0===t||t&&pe.nodeName(e,t)?pe.merge([e],o):o}function g(e,t){for(var n,r=0;null!=(n=e[r]);r++)pe._data(n,\"globalEval\",!t||pe._data(t[r],\"globalEval\"))}function m(e){Be.test(e.type)&&(e.defaultChecked=e.checked)}function y(e,t,n,r,i){for(var o,a,s,u,l,c,f,d=e.length,y=p(t),v=[],x=0;x<d;x++)if(a=e[x],a||0===a)if(\"object\"===pe.type(a))pe.merge(v,a.nodeType?[a]:a);else if(Ue.test(a)){for(u=u||y.appendChild(t.createElement(\"div\")),l=(We.exec(a)||[\"\",\"\"])[1].toLowerCase(),f=Xe[l]||Xe._default,u.innerHTML=f[1]+pe.htmlPrefilter(a)+f[2],o=f[0];o--;)u=u.lastChild;if(!fe.leadingWhitespace&&$e.test(a)&&v.push(t.createTextNode($e.exec(a)[0])),!fe.tbody)for(a=\"table\"!==l||Ve.test(a)?\"<table>\"!==f[1]||Ve.test(a)?0:u:u.firstChild,o=a&&a.childNodes.length;o--;)pe.nodeName(c=a.childNodes[o],\"tbody\")&&!c.childNodes.length&&a.removeChild(c);for(pe.merge(v,u.childNodes),u.textContent=\"\";u.firstChild;)u.removeChild(u.firstChild);u=y.lastChild}else v.push(t.createTextNode(a));for(u&&y.removeChild(u),fe.appendChecked||pe.grep(h(v,\"input\"),m),x=0;a=v[x++];)if(r&&pe.inArray(a,r)>-1)i&&i.push(a);else if(s=pe.contains(a.ownerDocument,a),u=h(y.appendChild(a),\"script\"),s&&g(u),n)for(o=0;a=u[o++];)Ie.test(a.type||\"\")&&n.push(a);return u=null,y}function v(){return!0}function x(){return!1}function b(){try{return re.activeElement}catch(e){}}function w(e,t,n,r,i,o){var a,s;if(\"object\"==typeof t){\"string\"!=typeof n&&(r=r||n,n=void 0);for(s in t)w(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&(\"string\"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),i===!1)i=x;else if(!i)return e;return 1===o&&(a=i,i=function(e){return pe().off(e),a.apply(this,arguments)},i.guid=a.guid||(a.guid=pe.guid++)),e.each(function(){pe.event.add(this,t,i,r,n)})}function T(e,t){return pe.nodeName(e,\"table\")&&pe.nodeName(11!==t.nodeType?t:t.firstChild,\"tr\")?e.getElementsByTagName(\"tbody\")[0]||e.appendChild(e.ownerDocument.createElement(\"tbody\")):e}function C(e){return e.type=(null!==pe.find.attr(e,\"type\"))+\"/\"+e.type,e}function E(e){var t=it.exec(e.type);return t?e.type=t[1]:e.removeAttribute(\"type\"),e}function N(e,t){if(1===t.nodeType&&pe.hasData(e)){var n,r,i,o=pe._data(e),a=pe._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;r<i;r++)pe.event.add(t,n,s[n][r])}a.data&&(a.data=pe.extend({},a.data))}}function k(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!fe.noCloneEvent&&t[pe.expando]){i=pe._data(t);for(r in i.events)pe.removeEvent(t,r,i.handle);t.removeAttribute(pe.expando)}\"script\"===n&&t.text!==e.text?(C(t).text=e.text,E(t)):\"object\"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),fe.html5Clone&&e.innerHTML&&!pe.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):\"input\"===n&&Be.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):\"option\"===n?t.defaultSelected=t.selected=e.defaultSelected:\"input\"!==n&&\"textarea\"!==n||(t.defaultValue=e.defaultValue)}}function S(e,t,n,r){t=oe.apply([],t);var i,o,a,s,u,l,c=0,f=e.length,d=f-1,p=t[0],g=pe.isFunction(p);if(g||f>1&&\"string\"==typeof p&&!fe.checkClone&&rt.test(p))return e.each(function(i){var o=e.eq(i);g&&(t[0]=p.call(this,i,o.html())),S(o,t,n,r)});if(f&&(l=y(t,e[0].ownerDocument,!1,e,r),i=l.firstChild,1===l.childNodes.length&&(l=i),i||r)){for(s=pe.map(h(l,\"script\"),C),a=s.length;c<f;c++)o=l,c!==d&&(o=pe.clone(o,!0,!0),a&&pe.merge(s,h(o,\"script\"))),n.call(e[c],o,c);if(a)for(u=s[s.length-1].ownerDocument,pe.map(s,E),c=0;c<a;c++)o=s[c],Ie.test(o.type||\"\")&&!pe._data(o,\"globalEval\")&&pe.contains(u,o)&&(o.src?pe._evalUrl&&pe._evalUrl(o.src):pe.globalEval((o.text||o.textContent||o.innerHTML||\"\").replace(ot,\"\")));l=i=null}return e}function A(e,t,n){for(var r,i=t?pe.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||pe.cleanData(h(r)),r.parentNode&&(n&&pe.contains(r.ownerDocument,r)&&g(h(r,\"script\")),r.parentNode.removeChild(r));return e}function D(e,t){var n=pe(t.createElement(e)).appendTo(t.body),r=pe.css(n[0],\"display\");return n.detach(),r}function j(e){var t=re,n=lt[e];return n||(n=D(e,t),\"none\"!==n&&n||(ut=(ut||pe(\"<iframe frameborder='0' width='0' height='0'/>\")).appendTo(t.documentElement),t=(ut[0].contentWindow||ut[0].contentDocument).document,t.write(),t.close(),n=D(e,t),ut.detach()),lt[e]=n),n}function L(e,t){return{get:function(){return e()?void delete this.get:(this.get=t).apply(this,arguments)}}}function H(e){if(e in Et)return e;for(var t=e.charAt(0).toUpperCase()+e.slice(1),n=Ct.length;n--;)if(e=Ct[n]+t,e in Et)return e}function q(e,t){for(var n,r,i,o=[],a=0,s=e.length;a<s;a++)r=e[a],r.style&&(o[a]=pe._data(r,\"olddisplay\"),n=r.style.display,t?(o[a]||\"none\"!==n||(r.style.display=\"\"),\"\"===r.style.display&&Re(r)&&(o[a]=pe._data(r,\"olddisplay\",j(r.nodeName)))):(i=Re(r),(n&&\"none\"!==n||!i)&&pe._data(r,\"olddisplay\",i?n:pe.css(r,\"display\"))));for(a=0;a<s;a++)r=e[a],r.style&&(t&&\"none\"!==r.style.display&&\"\"!==r.style.display||(r.style.display=t?o[a]||\"\":\"none\"));return e}function _(e,t,n){var r=bt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||\"px\"):t}function F(e,t,n,r,i){for(var o=n===(r?\"border\":\"content\")?4:\"width\"===t?1:0,a=0;o<4;o+=2)\"margin\"===n&&(a+=pe.css(e,n+Oe[o],!0,i)),r?(\"content\"===n&&(a-=pe.css(e,\"padding\"+Oe[o],!0,i)),\"margin\"!==n&&(a-=pe.css(e,\"border\"+Oe[o]+\"Width\",!0,i))):(a+=pe.css(e,\"padding\"+Oe[o],!0,i),\"padding\"!==n&&(a+=pe.css(e,\"border\"+Oe[o]+\"Width\",!0,i)));return a}function M(t,n,r){var i=!0,o=\"width\"===n?t.offsetWidth:t.offsetHeight,a=ht(t),s=fe.boxSizing&&\"border-box\"===pe.css(t,\"boxSizing\",!1,a);if(re.msFullscreenElement&&e.top!==e&&t.getClientRects().length&&(o=Math.round(100*t.getBoundingClientRect()[n])),o<=0||null==o){if(o=gt(t,n,a),(o<0||null==o)&&(o=t.style[n]),ft.test(o))return o;i=s&&(fe.boxSizingReliable()||o===t.style[n]),o=parseFloat(o)||0}return o+F(t,n,r||(s?\"border\":\"content\"),i,a)+\"px\"}function O(e,t,n,r,i){return new O.prototype.init(e,t,n,r,i)}function R(){return e.setTimeout(function(){Nt=void 0}),Nt=pe.now()}function P(e,t){var n,r={height:e},i=0;for(t=t?1:0;i<4;i+=2-t)n=Oe[i],r[\"margin\"+n]=r[\"padding\"+n]=e;return t&&(r.opacity=r.width=e),r}function B(e,t,n){for(var r,i=($.tweeners[t]||[]).concat($.tweeners[\"*\"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function W(e,t,n){var r,i,o,a,s,u,l,c,f=this,d={},p=e.style,h=e.nodeType&&Re(e),g=pe._data(e,\"fxshow\");n.queue||(s=pe._queueHooks(e,\"fx\"),null==s.unqueued&&(s.unqueued=0,u=s.empty.fire,s.empty.fire=function(){s.unqueued||u()}),s.unqueued++,f.always(function(){f.always(function(){s.unqueued--,pe.queue(e,\"fx\").length||s.empty.fire()})})),1===e.nodeType&&(\"height\"in t||\"width\"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],l=pe.css(e,\"display\"),c=\"none\"===l?pe._data(e,\"olddisplay\")||j(e.nodeName):l,\"inline\"===c&&\"none\"===pe.css(e,\"float\")&&(fe.inlineBlockNeedsLayout&&\"inline\"!==j(e.nodeName)?p.zoom=1:p.display=\"inline-block\")),n.overflow&&(p.overflow=\"hidden\",fe.shrinkWrapBlocks()||f.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],St.exec(i)){if(delete t[r],o=o||\"toggle\"===i,i===(h?\"hide\":\"show\")){if(\"show\"!==i||!g||void 0===g[r])continue;h=!0}d[r]=g&&g[r]||pe.style(e,r)}else l=void 0;if(pe.isEmptyObject(d))\"inline\"===(\"none\"===l?j(e.nodeName):l)&&(p.display=l);else{g?\"hidden\"in g&&(h=g.hidden):g=pe._data(e,\"fxshow\",{}),o&&(g.hidden=!h),h?pe(e).show():f.done(function(){pe(e).hide()}),f.done(function(){var t;pe._removeData(e,\"fxshow\");for(t in d)pe.style(e,t,d[t])});for(r in d)a=B(h?g[r]:0,r,f),r in g||(g[r]=a.start,h&&(a.end=a.start,a.start=\"width\"===r||\"height\"===r?1:0))}}function I(e,t){var n,r,i,o,a;for(n in e)if(r=pe.camelCase(n),i=t[r],o=e[n],pe.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),a=pe.cssHooks[r],a&&\"expand\"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}function $(e,t,n){var r,i,o=0,a=$.prefilters.length,s=pe.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;for(var t=Nt||R(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,o=1-r,a=0,u=l.tweens.length;a<u;a++)l.tweens[a].run(o);return s.notifyWith(e,[l,o,n]),o<1&&u?n:(s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:pe.extend({},t),opts:pe.extend(!0,{specialEasing:{},easing:pe.easing._default},n),originalProperties:t,originalOptions:n,startTime:Nt||R(),duration:n.duration,tweens:[],createTween:function(t,n){var r=pe.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;n<r;n++)l.tweens[n].run(1);return t?(s.notifyWith(e,[l,1,0]),s.resolveWith(e,[l,t])):s.rejectWith(e,[l,t]),this}}),c=l.props;for(I(c,l.opts.specialEasing);o<a;o++)if(r=$.prefilters[o].call(l,e,c,l.opts))return pe.isFunction(r.stop)&&(pe._queueHooks(l.elem,l.opts.queue).stop=pe.proxy(r.stop,r)),r;return pe.map(c,B,l),pe.isFunction(l.opts.start)&&l.opts.start.call(e,l),pe.fx.timer(pe.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function z(e){return pe.attr(e,\"class\")||\"\"}function X(e){return function(t,n){\"string\"!=typeof t&&(n=t,t=\"*\");var r,i=0,o=t.toLowerCase().match(De)||[];if(pe.isFunction(n))for(;r=o[i++];)\"+\"===r.charAt(0)?(r=r.slice(1)||\"*\",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function U(e,t,n,r){function i(s){var u;return o[s]=!0,pe.each(e[s]||[],function(e,s){var l=s(t,n,r);return\"string\"!=typeof l||a||o[l]?a?!(u=l):void 0:(t.dataTypes.unshift(l),i(l),!1)}),u}var o={},a=e===Qt;return i(t.dataTypes[0])||!o[\"*\"]&&i(\"*\")}function V(e,t){var n,r,i=pe.ajaxSettings.flatOptions||{};for(r in t)void 0!==t[r]&&((i[r]?e:n||(n={}))[r]=t[r]);return n&&pe.extend(!0,e,n),e}function Y(e,t,n){for(var r,i,o,a,s=e.contents,u=e.dataTypes;\"*\"===u[0];)u.shift(),void 0===i&&(i=e.mimeType||t.getResponseHeader(\"Content-Type\"));if(i)for(a in s)if(s[a]&&s[a].test(i)){u.unshift(a);break}if(u[0]in n)o=u[0];else{for(a in n){if(!u[0]||e.converters[a+\" \"+u[0]]){o=a;break}r||(r=a)}o=o||r}if(o)return o!==u[0]&&u.unshift(o),n[o]}function J(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];for(o=c.shift();o;)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if(\"*\"===o)o=u;else if(\"*\"!==u&&u!==o){if(a=l[u+\" \"+o]||l[\"* \"+o],!a)for(i in l)if(s=i.split(\" \"),s[1]===o&&(a=l[u+\" \"+s[0]]||l[\"* \"+s[0]])){a===!0?a=l[i]:l[i]!==!0&&(o=s[0],c.unshift(s[1]));break}if(a!==!0)if(a&&e[\"throws\"])t=a(t);else try{t=a(t)}catch(f){return{state:\"parsererror\",error:a?f:\"No conversion from \"+u+\" to \"+o}}}return{state:\"success\",data:t}}function G(e){return e.style&&e.style.display||pe.css(e,\"display\")}function K(e){for(;e&&1===e.nodeType;){if(\"none\"===G(e)||\"hidden\"===e.type)return!0;e=e.parentNode}return!1}function Q(e,t,n,r){var i;if(pe.isArray(t))pe.each(t,function(t,i){n||rn.test(e)?r(e,i):Q(e+\"[\"+(\"object\"==typeof i&&null!=i?t:\"\")+\"]\",i,n,r)});else if(n||\"object\"!==pe.type(t))r(e,t);else for(i in t)Q(e+\"[\"+i+\"]\",t[i],n,r)}function Z(){try{return new e.XMLHttpRequest}catch(t){}}function ee(){try{return new e.ActiveXObject(\"Microsoft.XMLHTTP\")}catch(t){}}function te(e){return pe.isWindow(e)?e:9===e.nodeType&&(e.defaultView||e.parentWindow)}var ne=[],re=e.document,ie=ne.slice,oe=ne.concat,ae=ne.push,se=ne.indexOf,ue={},le=ue.toString,ce=ue.hasOwnProperty,fe={},de=\"1.12.3\",pe=function(e,t){return new pe.fn.init(e,t)},he=/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,ge=/^-ms-/,me=/-([\\da-z])/gi,ye=function(e,t){return t.toUpperCase()};pe.fn=pe.prototype={jquery:de,constructor:pe,selector:\"\",length:0,toArray:function(){return ie.call(this)},get:function(e){return null!=e?e<0?this[e+this.length]:this[e]:ie.call(this)},pushStack:function(e){var t=pe.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e){return pe.each(this,e)},map:function(e){return this.pushStack(pe.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(ie.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:ae,sort:ne.sort,splice:ne.splice},pe.extend=pe.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for(\"boolean\"==typeof a&&(l=a,a=arguments[s]||{},s++),\"object\"==typeof a||pe.isFunction(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(i=arguments[s]))for(r in i)e=a[r],n=i[r],a!==n&&(l&&n&&(pe.isPlainObject(n)||(t=pe.isArray(n)))?(t?(t=!1,o=e&&pe.isArray(e)?e:[]):o=e&&pe.isPlainObject(e)?e:{},a[r]=pe.extend(l,o,n)):void 0!==n&&(a[r]=n));return a},pe.extend({expando:\"jQuery\"+(de+Math.random()).replace(/\\D/g,\"\"),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isFunction:function(e){return\"function\"===pe.type(e)},isArray:Array.isArray||function(e){return\"array\"===pe.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){var t=e&&e.toString();return!pe.isArray(e)&&t-parseFloat(t)+1>=0},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},isPlainObject:function(e){var t;if(!e||\"object\"!==pe.type(e)||e.nodeType||pe.isWindow(e))return!1;try{if(e.constructor&&!ce.call(e,\"constructor\")&&!ce.call(e.constructor.prototype,\"isPrototypeOf\"))return!1}catch(n){return!1}if(!fe.ownFirst)for(t in e)return ce.call(e,t);for(t in e);return void 0===t||ce.call(e,t)},type:function(e){return null==e?e+\"\":\"object\"==typeof e||\"function\"==typeof e?ue[le.call(e)]||\"object\":typeof e},globalEval:function(t){t&&pe.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(ge,\"ms-\").replace(me,ye)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t){var r,i=0;if(n(e))for(r=e.length;i<r&&t.call(e[i],i,e[i])!==!1;i++);else for(i in e)if(t.call(e[i],i,e[i])===!1)break;return e},trim:function(e){return null==e?\"\":(e+\"\").replace(he,\"\")},makeArray:function(e,t){var r=t||[];return null!=e&&(n(Object(e))?pe.merge(r,\"string\"==typeof e?[e]:e):ae.call(r,e)),r},inArray:function(e,t,n){var r;if(t){if(se)return se.call(t,e,n);for(r=t.length,n=n?n<0?Math.max(0,r+n):n:0;n<r;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;)e[i++]=t[r++];if(n!==n)for(;void 0!==t[r];)e[i++]=t[r++];return e.length=i,e},grep:function(e,t,n){for(var r,i=[],o=0,a=e.length,s=!n;o<a;o++)r=!t(e[o],o),r!==s&&i.push(e[o]);return i},map:function(e,t,r){var i,o,a=0,s=[];if(n(e))for(i=e.length;a<i;a++)o=t(e[a],a,r),null!=o&&s.push(o);else for(a in e)o=t(e[a],a,r),null!=o&&s.push(o);return oe.apply([],s)},guid:1,proxy:function(e,t){var n,r,i;if(\"string\"==typeof t&&(i=e[t],t=e,e=i),pe.isFunction(e))return n=ie.call(arguments,2),r=function(){return e.apply(t||this,n.concat(ie.call(arguments)))},r.guid=e.guid=e.guid||pe.guid++,r},now:function(){return+new Date},support:fe}),\"function\"==typeof Symbol&&(pe.fn[Symbol.iterator]=ne[Symbol.iterator]),pe.each(\"Boolean Number String Function Array Date RegExp Object Error Symbol\".split(\" \"),function(e,t){ue[\"[object \"+t+\"]\"]=t.toLowerCase()});var ve=function(e){function t(e,t,n,r){var i,o,a,s,u,l,f,p,h=t&&t.ownerDocument,g=t?t.nodeType:9;if(n=n||[],\"string\"!=typeof e||!e||1!==g&&9!==g&&11!==g)return n;if(!r&&((t?t.ownerDocument||t:B)!==H&&L(t),t=t||H,_)){if(11!==g&&(l=ye.exec(e)))if(i=l[1]){if(9===g){if(!(a=t.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(h&&(a=h.getElementById(i))&&R(t,a)&&a.id===i)return n.push(a),n}else{if(l[2])return Q.apply(n,t.getElementsByTagName(e)),n;if((i=l[3])&&w.getElementsByClassName&&t.getElementsByClassName)return Q.apply(n,t.getElementsByClassName(i)),n}if(w.qsa&&!X[e+\" \"]&&(!F||!F.test(e))){if(1!==g)h=t,p=e;else if(\"object\"!==t.nodeName.toLowerCase()){for((s=t.getAttribute(\"id\"))?s=s.replace(xe,\"\\\\$&\"):t.setAttribute(\"id\",s=P),f=N(e),o=f.length,u=de.test(s)?\"#\"+s:\"[id='\"+s+\"']\";o--;)f[o]=u+\" \"+d(f[o]);p=f.join(\",\"),h=ve.test(e)&&c(t.parentNode)||t}if(p)try{return Q.apply(n,h.querySelectorAll(p)),n}catch(m){}finally{s===P&&t.removeAttribute(\"id\")}}}return S(e.replace(se,\"$1\"),t,n,r)}function n(){function e(n,r){return t.push(n+\" \")>T.cacheLength&&delete e[t.shift()],e[n+\" \"]=r}var t=[];return e}function r(e){return e[P]=!0,e}function i(e){var t=H.createElement(\"div\");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function o(e,t){for(var n=e.split(\"|\"),r=n.length;r--;)T.attrHandle[n[r]]=t}function a(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||V)-(~e.sourceIndex||V);if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function s(e){return function(t){var n=t.nodeName.toLowerCase();return\"input\"===n&&t.type===e}}function u(e){return function(t){var n=t.nodeName.toLowerCase();return(\"input\"===n||\"button\"===n)&&t.type===e}}function l(e){return r(function(t){return t=+t,r(function(n,r){for(var i,o=e([],n.length,t),a=o.length;a--;)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function c(e){return e&&\"undefined\"!=typeof e.getElementsByTagName&&e}function f(){}function d(e){for(var t=0,n=e.length,r=\"\";t<n;t++)r+=e[t].value;return r}function p(e,t,n){var r=t.dir,i=n&&\"parentNode\"===r,o=I++;return t.first?function(t,n,o){for(;t=t[r];)if(1===t.nodeType||i)return e(t,n,o)}:function(t,n,a){var s,u,l,c=[W,o];if(a){for(;t=t[r];)if((1===t.nodeType||i)&&e(t,n,a))return!0}else for(;t=t[r];)if(1===t.nodeType||i){if(l=t[P]||(t[P]={}),u=l[t.uniqueID]||(l[t.uniqueID]={}),(s=u[r])&&s[0]===W&&s[1]===o)return c[2]=s[2];if(u[r]=c,c[2]=e(t,n,a))return!0}}}function h(e){return e.length>1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function g(e,n,r){for(var i=0,o=n.length;i<o;i++)t(e,n[i],r);return r}function m(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function y(e,t,n,i,o,a){return i&&!i[P]&&(i=y(i)),o&&!o[P]&&(o=y(o,a)),r(function(r,a,s,u){var l,c,f,d=[],p=[],h=a.length,y=r||g(t||\"*\",s.nodeType?[s]:s,[]),v=!e||!r&&t?y:m(y,d,e,s,u),x=n?o||(r?e:h||i)?[]:a:v;if(n&&n(v,x,s,u),i)for(l=m(x,p),i(l,[],s,u),c=l.length;c--;)(f=l[c])&&(x[p[c]]=!(v[p[c]]=f));if(r){if(o||e){if(o){for(l=[],c=x.length;c--;)(f=x[c])&&l.push(v[c]=f);o(null,x=[],l,u)}for(c=x.length;c--;)(f=x[c])&&(l=o?ee(r,f):d[c])>-1&&(r[l]=!(a[l]=f))}}else x=m(x===a?x.splice(h,x.length):x),o?o(null,a,x,u):Q.apply(a,x)})}function v(e){for(var t,n,r,i=e.length,o=T.relative[e[0].type],a=o||T.relative[\" \"],s=o?1:0,u=p(function(e){return e===t},a,!0),l=p(function(e){return ee(t,e)>-1},a,!0),c=[function(e,n,r){var i=!o&&(r||n!==A)||((t=n).nodeType?u(e,n,r):l(e,n,r));return t=null,i}];s<i;s++)if(n=T.relative[e[s].type])c=[p(h(c),n)];else{if(n=T.filter[e[s].type].apply(null,e[s].matches),n[P]){for(r=++s;r<i&&!T.relative[e[r].type];r++);return y(s>1&&h(c),s>1&&d(e.slice(0,s-1).concat({value:\" \"===e[s-2].type?\"*\":\"\"})).replace(se,\"$1\"),n,s<r&&v(e.slice(s,r)),r<i&&v(e=e.slice(r)),r<i&&d(e))}c.push(n)}return h(c)}function x(e,n){var i=n.length>0,o=e.length>0,a=function(r,a,s,u,l){var c,f,d,p=0,h=\"0\",g=r&&[],y=[],v=A,x=r||o&&T.find.TAG(\"*\",l),b=W+=null==v?1:Math.random()||.1,w=x.length;for(l&&(A=a===H||a||l);h!==w&&null!=(c=x[h]);h++){if(o&&c){for(f=0,a||c.ownerDocument===H||(L(c),s=!_);d=e[f++];)if(d(c,a||H,s)){u.push(c);break}l&&(W=b)}i&&((c=!d&&c)&&p--,r&&g.push(c))}if(p+=h,i&&h!==p){for(f=0;d=n[f++];)d(g,y,a,s);if(r){if(p>0)for(;h--;)g[h]||y[h]||(y[h]=G.call(u));y=m(y)}Q.apply(u,y),l&&!r&&y.length>0&&p+n.length>1&&t.uniqueSort(u)}return l&&(W=b,A=v),g};return i?r(a):a}var b,w,T,C,E,N,k,S,A,D,j,L,H,q,_,F,M,O,R,P=\"sizzle\"+1*new Date,B=e.document,W=0,I=0,$=n(),z=n(),X=n(),U=function(e,t){return e===t&&(j=!0),0},V=1<<31,Y={}.hasOwnProperty,J=[],G=J.pop,K=J.push,Q=J.push,Z=J.slice,ee=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},te=\"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",ne=\"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",re=\"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",ie=\"\\\\[\"+ne+\"*(\"+re+\")(?:\"+ne+\"*([*^$|!~]?=)\"+ne+\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\"+re+\"))|)\"+ne+\"*\\\\]\",oe=\":(\"+re+\")(?:\\\\((('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\"+ie+\")*)|.*)\\\\)|)\",ae=new RegExp(ne+\"+\",\"g\"),se=new RegExp(\"^\"+ne+\"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\"+ne+\"+$\",\"g\"),ue=new RegExp(\"^\"+ne+\"*,\"+ne+\"*\"),le=new RegExp(\"^\"+ne+\"*([>+~]|\"+ne+\")\"+ne+\"*\"),ce=new RegExp(\"=\"+ne+\"*([^\\\\]'\\\"]*?)\"+ne+\"*\\\\]\",\"g\"),fe=new RegExp(oe),de=new RegExp(\"^\"+re+\"$\"),pe={ID:new RegExp(\"^#(\"+re+\")\"),CLASS:new RegExp(\"^\\\\.(\"+re+\")\"),TAG:new RegExp(\"^(\"+re+\"|[*])\"),ATTR:new RegExp(\"^\"+ie),PSEUDO:new RegExp(\"^\"+oe),CHILD:new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\"+ne+\"*(even|odd|(([+-]|)(\\\\d*)n|)\"+ne+\"*(?:([+-]|)\"+ne+\"*(\\\\d+)|))\"+ne+\"*\\\\)|)\",\"i\"),bool:new RegExp(\"^(?:\"+te+\")$\",\"i\"),needsContext:new RegExp(\"^\"+ne+\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\"+ne+\"*((?:-\\\\d)?\\\\d*)\"+ne+\"*\\\\)|)(?=[^-]|$)\",\"i\")},he=/^(?:input|select|textarea|button)$/i,ge=/^h\\d$/i,me=/^[^{]+\\{\\s*\\[native \\w/,ye=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,ve=/[+~]/,xe=/'|\\\\/g,be=new RegExp(\"\\\\\\\\([\\\\da-f]{1,6}\"+ne+\"?|(\"+ne+\")|.)\",\"ig\"),we=function(e,t,n){var r=\"0x\"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},Te=function(){L()};try{Q.apply(J=Z.call(B.childNodes),B.childNodes),J[B.childNodes.length].nodeType}catch(Ce){Q={apply:J.length?function(e,t){K.apply(e,Z.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}w=t.support={},E=t.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&\"HTML\"!==t.nodeName},L=t.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:B;return r!==H&&9===r.nodeType&&r.documentElement?(H=r,q=H.documentElement,_=!E(H),(n=H.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener(\"unload\",Te,!1):n.attachEvent&&n.attachEvent(\"onunload\",Te)),w.attributes=i(function(e){return e.className=\"i\",!e.getAttribute(\"className\")}),w.getElementsByTagName=i(function(e){return e.appendChild(H.createComment(\"\")),!e.getElementsByTagName(\"*\").length}),w.getElementsByClassName=me.test(H.getElementsByClassName),w.getById=i(function(e){return q.appendChild(e).id=P,!H.getElementsByName||!H.getElementsByName(P).length}),w.getById?(T.find.ID=function(e,t){if(\"undefined\"!=typeof t.getElementById&&_){var n=t.getElementById(e);return n?[n]:[]}},T.filter.ID=function(e){var t=e.replace(be,we);return function(e){return e.getAttribute(\"id\")===t}}):(delete T.find.ID,T.filter.ID=function(e){var t=e.replace(be,we);return function(e){var n=\"undefined\"!=typeof e.getAttributeNode&&e.getAttributeNode(\"id\");return n&&n.value===t}}),T.find.TAG=w.getElementsByTagName?function(e,t){return\"undefined\"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):w.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if(\"*\"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},T.find.CLASS=w.getElementsByClassName&&function(e,t){if(\"undefined\"!=typeof t.getElementsByClassName&&_)return t.getElementsByClassName(e)},M=[],F=[],(w.qsa=me.test(H.querySelectorAll))&&(i(function(e){q.appendChild(e).innerHTML=\"<a id='\"+P+\"'></a><select id='\"+P+\"-\\r\\\\' msallowcapture=''><option selected=''></option></select>\",e.querySelectorAll(\"[msallowcapture^='']\").length&&F.push(\"[*^$]=\"+ne+\"*(?:''|\\\"\\\")\"),e.querySelectorAll(\"[selected]\").length||F.push(\"\\\\[\"+ne+\"*(?:value|\"+te+\")\"),e.querySelectorAll(\"[id~=\"+P+\"-]\").length||F.push(\"~=\"),e.querySelectorAll(\":checked\").length||F.push(\":checked\"),e.querySelectorAll(\"a#\"+P+\"+*\").length||F.push(\".#.+[+~]\")}),i(function(e){var t=H.createElement(\"input\");t.setAttribute(\"type\",\"hidden\"),e.appendChild(t).setAttribute(\"name\",\"D\"),e.querySelectorAll(\"[name=d]\").length&&F.push(\"name\"+ne+\"*[*^$|!~]?=\"),e.querySelectorAll(\":enabled\").length||F.push(\":enabled\",\":disabled\"),e.querySelectorAll(\"*,:x\"),F.push(\",.*:\")})),(w.matchesSelector=me.test(O=q.matches||q.webkitMatchesSelector||q.mozMatchesSelector||q.oMatchesSelector||q.msMatchesSelector))&&i(function(e){w.disconnectedMatch=O.call(e,\"div\"),O.call(e,\"[s!='']:x\"),M.push(\"!=\",oe)}),F=F.length&&new RegExp(F.join(\"|\")),M=M.length&&new RegExp(M.join(\"|\")),t=me.test(q.compareDocumentPosition),R=t||me.test(q.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},U=t?function(e,t){if(e===t)return j=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n?n:(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&n||!w.sortDetached&&t.compareDocumentPosition(e)===n?e===H||e.ownerDocument===B&&R(B,e)?-1:t===H||t.ownerDocument===B&&R(B,t)?1:D?ee(D,e)-ee(D,t):0:4&n?-1:1)}:function(e,t){if(e===t)return j=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,s=[e],u=[t];if(!i||!o)return e===H?-1:t===H?1:i?-1:o?1:D?ee(D,e)-ee(D,t):0;if(i===o)return a(e,t);for(n=e;n=n.parentNode;)s.unshift(n);for(n=t;n=n.parentNode;)u.unshift(n);for(;s[r]===u[r];)r++;return r?a(s[r],u[r]):s[r]===B?-1:u[r]===B?1:0},H):H},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==H&&L(e),n=n.replace(ce,\"='$1']\"),w.matchesSelector&&_&&!X[n+\" \"]&&(!M||!M.test(n))&&(!F||!F.test(n)))try{var r=O.call(e,n);if(r||w.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(i){}return t(n,H,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==H&&L(e),R(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==H&&L(e);var n=T.attrHandle[t.toLowerCase()],r=n&&Y.call(T.attrHandle,t.toLowerCase())?n(e,t,!_):void 0;return void 0!==r?r:w.attributes||!_?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},t.error=function(e){throw new Error(\"Syntax error, unrecognized expression: \"+e)},t.uniqueSort=function(e){var t,n=[],r=0,i=0;if(j=!w.detectDuplicates,D=!w.sortStable&&e.slice(0),e.sort(U),j){for(;t=e[i++];)t===e[i]&&(r=n.push(i));for(;r--;)e.splice(n[r],1)}return D=null,e},C=t.getText=function(e){var t,n=\"\",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if(\"string\"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=C(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r++];)n+=C(t);return n},T=t.selectors={cacheLength:50,createPseudo:r,match:pe,attrHandle:{},find:{},relative:{\">\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(be,we),e[3]=(e[3]||e[4]||e[5]||\"\").replace(be,we),\"~=\"===e[2]&&(e[3]=\" \"+e[3]+\" \"),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),\"nth\"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*(\"even\"===e[3]||\"odd\"===e[3])),e[5]=+(e[7]+e[8]||\"odd\"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return pe.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||\"\":n&&fe.test(n)&&(t=N(n,!0))&&(t=n.indexOf(\")\",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(be,we).toLowerCase();return\"*\"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=$[e+\" \"];return t||(t=new RegExp(\"(^|\"+ne+\")\"+e+\"(\"+ne+\"|$)\"))&&$(e,function(e){return t.test(\"string\"==typeof e.className&&e.className||\"undefined\"!=typeof e.getAttribute&&e.getAttribute(\"class\")||\"\")})},ATTR:function(e,n,r){return function(i){var o=t.attr(i,e);return null==o?\"!=\"===n:!n||(o+=\"\",\"=\"===n?o===r:\"!=\"===n?o!==r:\"^=\"===n?r&&0===o.indexOf(r):\"*=\"===n?r&&o.indexOf(r)>-1:\"$=\"===n?r&&o.slice(-r.length)===r:\"~=\"===n?(\" \"+o.replace(ae,\" \")+\" \").indexOf(r)>-1:\"|=\"===n&&(o===r||o.slice(0,r.length+1)===r+\"-\"))}},CHILD:function(e,t,n,r,i){var o=\"nth\"!==e.slice(0,3),a=\"last\"!==e.slice(-4),s=\"of-type\"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,d,p,h,g=o!==a?\"nextSibling\":\"previousSibling\",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!u&&!s,x=!1;if(m){if(o){for(;g;){for(d=t;d=d[g];)if(s?d.nodeName.toLowerCase()===y:1===d.nodeType)return!1;h=g=\"only\"===e&&!h&&\"nextSibling\"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){for(d=m,f=d[P]||(d[P]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),\nl=c[e]||[],p=l[0]===W&&l[1],x=p&&l[2],d=p&&m.childNodes[p];d=++p&&d&&d[g]||(x=p=0)||h.pop();)if(1===d.nodeType&&++x&&d===t){c[e]=[W,p,x];break}}else if(v&&(d=t,f=d[P]||(d[P]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),l=c[e]||[],p=l[0]===W&&l[1],x=p),x===!1)for(;(d=++p&&d&&d[g]||(x=p=0)||h.pop())&&((s?d.nodeName.toLowerCase()!==y:1!==d.nodeType)||!++x||(v&&(f=d[P]||(d[P]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),c[e]=[W,x]),d!==t)););return x-=i,x===r||x%r===0&&x/r>=0}}},PSEUDO:function(e,n){var i,o=T.pseudos[e]||T.setFilters[e.toLowerCase()]||t.error(\"unsupported pseudo: \"+e);return o[P]?o(n):o.length>1?(i=[e,e,\"\",n],T.setFilters.hasOwnProperty(e.toLowerCase())?r(function(e,t){for(var r,i=o(e,n),a=i.length;a--;)r=ee(e,i[a]),e[r]=!(t[r]=i[a])}):function(e){return o(e,0,i)}):o}},pseudos:{not:r(function(e){var t=[],n=[],i=k(e.replace(se,\"$1\"));return i[P]?r(function(e,t,n,r){for(var o,a=i(e,null,r,[]),s=e.length;s--;)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,r,o){return t[0]=e,i(t,null,o,n),t[0]=null,!n.pop()}}),has:r(function(e){return function(n){return t(e,n).length>0}}),contains:r(function(e){return e=e.replace(be,we),function(t){return(t.textContent||t.innerText||C(t)).indexOf(e)>-1}}),lang:r(function(e){return de.test(e||\"\")||t.error(\"unsupported lang: \"+e),e=e.replace(be,we).toLowerCase(),function(t){var n;do if(n=_?t.lang:t.getAttribute(\"xml:lang\")||t.getAttribute(\"lang\"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+\"-\");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===q},focus:function(e){return e===H.activeElement&&(!H.hasFocus||H.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&!!e.checked||\"option\"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!T.pseudos.empty(e)},header:function(e){return ge.test(e.nodeName)},input:function(e){return he.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&\"button\"===e.type||\"button\"===t},text:function(e){var t;return\"input\"===e.nodeName.toLowerCase()&&\"text\"===e.type&&(null==(t=e.getAttribute(\"type\"))||\"text\"===t.toLowerCase())},first:l(function(){return[0]}),last:l(function(e,t){return[t-1]}),eq:l(function(e,t,n){return[n<0?n+t:n]}),even:l(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:l(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:l(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:l(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}},T.pseudos.nth=T.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})T.pseudos[b]=s(b);for(b in{submit:!0,reset:!0})T.pseudos[b]=u(b);return f.prototype=T.filters=T.pseudos,T.setFilters=new f,N=t.tokenize=function(e,n){var r,i,o,a,s,u,l,c=z[e+\" \"];if(c)return n?0:c.slice(0);for(s=e,u=[],l=T.preFilter;s;){r&&!(i=ue.exec(s))||(i&&(s=s.slice(i[0].length)||s),u.push(o=[])),r=!1,(i=le.exec(s))&&(r=i.shift(),o.push({value:r,type:i[0].replace(se,\" \")}),s=s.slice(r.length));for(a in T.filter)!(i=pe[a].exec(s))||l[a]&&!(i=l[a](i))||(r=i.shift(),o.push({value:r,type:a,matches:i}),s=s.slice(r.length));if(!r)break}return n?s.length:s?t.error(e):z(e,u).slice(0)},k=t.compile=function(e,t){var n,r=[],i=[],o=X[e+\" \"];if(!o){for(t||(t=N(e)),n=t.length;n--;)o=v(t[n]),o[P]?r.push(o):i.push(o);o=X(e,x(i,r)),o.selector=e}return o},S=t.select=function(e,t,n,r){var i,o,a,s,u,l=\"function\"==typeof e&&e,f=!r&&N(e=l.selector||e);if(n=n||[],1===f.length){if(o=f[0]=f[0].slice(0),o.length>2&&\"ID\"===(a=o[0]).type&&w.getById&&9===t.nodeType&&_&&T.relative[o[1].type]){if(t=(T.find.ID(a.matches[0].replace(be,we),t)||[])[0],!t)return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}for(i=pe.needsContext.test(e)?0:o.length;i--&&(a=o[i],!T.relative[s=a.type]);)if((u=T.find[s])&&(r=u(a.matches[0].replace(be,we),ve.test(o[0].type)&&c(t.parentNode)||t))){if(o.splice(i,1),e=r.length&&d(o),!e)return Q.apply(n,r),n;break}}return(l||k(e,f))(r,t,!_,n,!t||ve.test(e)&&c(t.parentNode)||t),n},w.sortStable=P.split(\"\").sort(U).join(\"\")===P,w.detectDuplicates=!!j,L(),w.sortDetached=i(function(e){return 1&e.compareDocumentPosition(H.createElement(\"div\"))}),i(function(e){return e.innerHTML=\"<a href='#'></a>\",\"#\"===e.firstChild.getAttribute(\"href\")})||o(\"type|href|height|width\",function(e,t,n){if(!n)return e.getAttribute(t,\"type\"===t.toLowerCase()?1:2)}),w.attributes&&i(function(e){return e.innerHTML=\"<input/>\",e.firstChild.setAttribute(\"value\",\"\"),\"\"===e.firstChild.getAttribute(\"value\")})||o(\"value\",function(e,t,n){if(!n&&\"input\"===e.nodeName.toLowerCase())return e.defaultValue}),i(function(e){return null==e.getAttribute(\"disabled\")})||o(te,function(e,t,n){var r;if(!n)return e[t]===!0?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),t}(e);pe.find=ve,pe.expr=ve.selectors,pe.expr[\":\"]=pe.expr.pseudos,pe.uniqueSort=pe.unique=ve.uniqueSort,pe.text=ve.getText,pe.isXMLDoc=ve.isXML,pe.contains=ve.contains;var xe=function(e,t,n){for(var r=[],i=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&pe(e).is(n))break;r.push(e)}return r},be=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},we=pe.expr.match.needsContext,Te=/^<([\\w-]+)\\s*\\/?>(?:<\\/\\1>|)$/,Ce=/^.[^:#\\[\\.,]*$/;pe.filter=function(e,t,n){var r=t[0];return n&&(e=\":not(\"+e+\")\"),1===t.length&&1===r.nodeType?pe.find.matchesSelector(r,e)?[r]:[]:pe.find.matches(e,pe.grep(t,function(e){return 1===e.nodeType}))},pe.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if(\"string\"!=typeof e)return this.pushStack(pe(e).filter(function(){for(t=0;t<i;t++)if(pe.contains(r[t],this))return!0}));for(t=0;t<i;t++)pe.find(e,r[t],n);return n=this.pushStack(i>1?pe.unique(n):n),n.selector=this.selector?this.selector+\" \"+e:e,n},filter:function(e){return this.pushStack(r(this,e||[],!1))},not:function(e){return this.pushStack(r(this,e||[],!0))},is:function(e){return!!r(this,\"string\"==typeof e&&we.test(e)?pe(e):e||[],!1).length}});var Ee,Ne=/^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,ke=pe.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||Ee,\"string\"==typeof e){if(r=\"<\"===e.charAt(0)&&\">\"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:Ne.exec(e),!r||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof pe?t[0]:t,pe.merge(this,pe.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:re,!0)),Te.test(r[1])&&pe.isPlainObject(t))for(r in t)pe.isFunction(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}if(i=re.getElementById(r[2]),i&&i.parentNode){if(i.id!==r[2])return Ee.find(e);this.length=1,this[0]=i}return this.context=re,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):pe.isFunction(e)?\"undefined\"!=typeof n.ready?n.ready(e):e(pe):(void 0!==e.selector&&(this.selector=e.selector,this.context=e.context),pe.makeArray(e,this))};ke.prototype=pe.fn,Ee=pe(re);var Se=/^(?:parents|prev(?:Until|All))/,Ae={children:!0,contents:!0,next:!0,prev:!0};pe.fn.extend({has:function(e){var t,n=pe(e,this),r=n.length;return this.filter(function(){for(t=0;t<r;t++)if(pe.contains(this,n[t]))return!0})},closest:function(e,t){for(var n,r=0,i=this.length,o=[],a=we.test(e)||\"string\"!=typeof e?pe(e,t||this.context):0;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?a.index(n)>-1:1===n.nodeType&&pe.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?pe.uniqueSort(o):o)},index:function(e){return e?\"string\"==typeof e?pe.inArray(this[0],pe(e)):pe.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(pe.uniqueSort(pe.merge(this.get(),pe(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),pe.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return xe(e,\"parentNode\")},parentsUntil:function(e,t,n){return xe(e,\"parentNode\",n)},next:function(e){return i(e,\"nextSibling\")},prev:function(e){return i(e,\"previousSibling\")},nextAll:function(e){return xe(e,\"nextSibling\")},prevAll:function(e){return xe(e,\"previousSibling\")},nextUntil:function(e,t,n){return xe(e,\"nextSibling\",n)},prevUntil:function(e,t,n){return xe(e,\"previousSibling\",n)},siblings:function(e){return be((e.parentNode||{}).firstChild,e)},children:function(e){return be(e.firstChild)},contents:function(e){return pe.nodeName(e,\"iframe\")?e.contentDocument||e.contentWindow.document:pe.merge([],e.childNodes)}},function(e,t){pe.fn[e]=function(n,r){var i=pe.map(this,t,n);return\"Until\"!==e.slice(-5)&&(r=n),r&&\"string\"==typeof r&&(i=pe.filter(r,i)),this.length>1&&(Ae[e]||(i=pe.uniqueSort(i)),Se.test(e)&&(i=i.reverse())),this.pushStack(i)}});var De=/\\S+/g;pe.Callbacks=function(e){e=\"string\"==typeof e?o(e):pe.extend({},e);var t,n,r,i,a=[],s=[],u=-1,l=function(){for(i=e.once,r=t=!0;s.length;u=-1)for(n=s.shift();++u<a.length;)a[u].apply(n[0],n[1])===!1&&e.stopOnFalse&&(u=a.length,n=!1);e.memory||(n=!1),t=!1,i&&(a=n?[]:\"\")},c={add:function(){return a&&(n&&!t&&(u=a.length-1,s.push(n)),function r(t){pe.each(t,function(t,n){pe.isFunction(n)?e.unique&&c.has(n)||a.push(n):n&&n.length&&\"string\"!==pe.type(n)&&r(n)})}(arguments),n&&!t&&l()),this},remove:function(){return pe.each(arguments,function(e,t){for(var n;(n=pe.inArray(t,a,n))>-1;)a.splice(n,1),n<=u&&u--}),this},has:function(e){return e?pe.inArray(e,a)>-1:a.length>0},empty:function(){return a&&(a=[]),this},disable:function(){return i=s=[],a=n=\"\",this},disabled:function(){return!a},lock:function(){return i=!0,n||c.disable(),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=n||[],n=[e,n.slice?n.slice():n],s.push(n),t||l()),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},pe.extend({Deferred:function(e){var t=[[\"resolve\",\"done\",pe.Callbacks(\"once memory\"),\"resolved\"],[\"reject\",\"fail\",pe.Callbacks(\"once memory\"),\"rejected\"],[\"notify\",\"progress\",pe.Callbacks(\"memory\")]],n=\"pending\",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return pe.Deferred(function(n){pe.each(t,function(t,o){var a=pe.isFunction(e[t])&&e[t];i[o[1]](function(){var e=a&&a.apply(this,arguments);e&&pe.isFunction(e.promise)?e.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[o[0]+\"With\"](this===r?n.promise():this,a?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?pe.extend(e,r):r}},i={};return r.pipe=r.then,pe.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+\"With\"](this===i?r:this,arguments),this},i[o[0]+\"With\"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t,n,r,i=0,o=ie.call(arguments),a=o.length,s=1!==a||e&&pe.isFunction(e.promise)?a:0,u=1===s?e:pe.Deferred(),l=function(e,n,r){return function(i){n[e]=this,r[e]=arguments.length>1?ie.call(arguments):i,r===t?u.notifyWith(n,r):--s||u.resolveWith(n,r)}};if(a>1)for(t=new Array(a),n=new Array(a),r=new Array(a);i<a;i++)o[i]&&pe.isFunction(o[i].promise)?o[i].promise().progress(l(i,n,t)).done(l(i,r,o)).fail(u.reject):--s;return s||u.resolveWith(r,o),u.promise()}});var je;pe.fn.ready=function(e){return pe.ready.promise().done(e),this},pe.extend({isReady:!1,readyWait:1,holdReady:function(e){e?pe.readyWait++:pe.ready(!0)},ready:function(e){(e===!0?--pe.readyWait:pe.isReady)||(pe.isReady=!0,e!==!0&&--pe.readyWait>0||(je.resolveWith(re,[pe]),pe.fn.triggerHandler&&(pe(re).triggerHandler(\"ready\"),pe(re).off(\"ready\"))))}}),pe.ready.promise=function(t){if(!je)if(je=pe.Deferred(),\"complete\"===re.readyState||\"loading\"!==re.readyState&&!re.documentElement.doScroll)e.setTimeout(pe.ready);else if(re.addEventListener)re.addEventListener(\"DOMContentLoaded\",s),e.addEventListener(\"load\",s);else{re.attachEvent(\"onreadystatechange\",s),e.attachEvent(\"onload\",s);var n=!1;try{n=null==e.frameElement&&re.documentElement}catch(r){}n&&n.doScroll&&!function i(){if(!pe.isReady){try{n.doScroll(\"left\")}catch(t){return e.setTimeout(i,50)}a(),pe.ready()}}()}return je.promise(t)},pe.ready.promise();var Le;for(Le in pe(fe))break;fe.ownFirst=\"0\"===Le,fe.inlineBlockNeedsLayout=!1,pe(function(){var e,t,n,r;n=re.getElementsByTagName(\"body\")[0],n&&n.style&&(t=re.createElement(\"div\"),r=re.createElement(\"div\"),r.style.cssText=\"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\",n.appendChild(r).appendChild(t),\"undefined\"!=typeof t.style.zoom&&(t.style.cssText=\"display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1\",fe.inlineBlockNeedsLayout=e=3===t.offsetWidth,e&&(n.style.zoom=1)),n.removeChild(r))}),function(){var e=re.createElement(\"div\");fe.deleteExpando=!0;try{delete e.test}catch(t){fe.deleteExpando=!1}e=null}();var He=function(e){var t=pe.noData[(e.nodeName+\" \").toLowerCase()],n=+e.nodeType||1;return(1===n||9===n)&&(!t||t!==!0&&e.getAttribute(\"classid\")===t)},qe=/^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,_e=/([A-Z])/g;pe.extend({cache:{},noData:{\"applet \":!0,\"embed \":!0,\"object \":\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"},hasData:function(e){return e=e.nodeType?pe.cache[e[pe.expando]]:e[pe.expando],!!e&&!l(e)},data:function(e,t,n){return c(e,t,n)},removeData:function(e,t){return f(e,t)},_data:function(e,t,n){return c(e,t,n,!0)},_removeData:function(e,t){return f(e,t,!0)}}),pe.fn.extend({data:function(e,t){var n,r,i,o=this[0],a=o&&o.attributes;if(void 0===e){if(this.length&&(i=pe.data(o),1===o.nodeType&&!pe._data(o,\"parsedAttrs\"))){for(n=a.length;n--;)a[n]&&(r=a[n].name,0===r.indexOf(\"data-\")&&(r=pe.camelCase(r.slice(5)),u(o,r,i[r])));pe._data(o,\"parsedAttrs\",!0)}return i}return\"object\"==typeof e?this.each(function(){pe.data(this,e)}):arguments.length>1?this.each(function(){pe.data(this,e,t)}):o?u(o,e,pe.data(o,e)):void 0},removeData:function(e){return this.each(function(){pe.removeData(this,e)})}}),pe.extend({queue:function(e,t,n){var r;if(e)return t=(t||\"fx\")+\"queue\",r=pe._data(e,t),n&&(!r||pe.isArray(n)?r=pe._data(e,t,pe.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||\"fx\";var n=pe.queue(e,t),r=n.length,i=n.shift(),o=pe._queueHooks(e,t),a=function(){pe.dequeue(e,t)};\"inprogress\"===i&&(i=n.shift(),r--),i&&(\"fx\"===t&&n.unshift(\"inprogress\"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+\"queueHooks\";return pe._data(e,n)||pe._data(e,n,{empty:pe.Callbacks(\"once memory\").add(function(){pe._removeData(e,t+\"queue\"),pe._removeData(e,n)})})}}),pe.fn.extend({queue:function(e,t){var n=2;return\"string\"!=typeof e&&(t=e,e=\"fx\",n--),arguments.length<n?pe.queue(this[0],e):void 0===t?this:this.each(function(){var n=pe.queue(this,e,t);pe._queueHooks(this,e),\"fx\"===e&&\"inprogress\"!==n[0]&&pe.dequeue(this,e)})},dequeue:function(e){return this.each(function(){pe.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||\"fx\",[])},promise:function(e,t){var n,r=1,i=pe.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};for(\"string\"!=typeof e&&(t=e,e=void 0),e=e||\"fx\";a--;)n=pe._data(o[a],e+\"queueHooks\"),n&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}}),function(){var e;fe.shrinkWrapBlocks=function(){if(null!=e)return e;e=!1;var t,n,r;return n=re.getElementsByTagName(\"body\")[0],n&&n.style?(t=re.createElement(\"div\"),r=re.createElement(\"div\"),r.style.cssText=\"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\",n.appendChild(r).appendChild(t),\"undefined\"!=typeof t.style.zoom&&(t.style.cssText=\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1\",t.appendChild(re.createElement(\"div\")).style.width=\"5px\",e=3!==t.offsetWidth),n.removeChild(r),e):void 0}}();var Fe=/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source,Me=new RegExp(\"^(?:([+-])=|)(\"+Fe+\")([a-z%]*)$\",\"i\"),Oe=[\"Top\",\"Right\",\"Bottom\",\"Left\"],Re=function(e,t){return e=t||e,\"none\"===pe.css(e,\"display\")||!pe.contains(e.ownerDocument,e)},Pe=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if(\"object\"===pe.type(n)){i=!0;for(s in n)Pe(e,t,s,n[s],!0,o,a)}else if(void 0!==r&&(i=!0,pe.isFunction(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(pe(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},Be=/^(?:checkbox|radio)$/i,We=/<([\\w:-]+)/,Ie=/^$|\\/(?:java|ecma)script/i,$e=/^\\s+/,ze=\"abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video\";!function(){var e=re.createElement(\"div\"),t=re.createDocumentFragment(),n=re.createElement(\"input\");e.innerHTML=\"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\",fe.leadingWhitespace=3===e.firstChild.nodeType,fe.tbody=!e.getElementsByTagName(\"tbody\").length,fe.htmlSerialize=!!e.getElementsByTagName(\"link\").length,fe.html5Clone=\"<:nav></:nav>\"!==re.createElement(\"nav\").cloneNode(!0).outerHTML,n.type=\"checkbox\",n.checked=!0,t.appendChild(n),fe.appendChecked=n.checked,e.innerHTML=\"<textarea>x</textarea>\",fe.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue,t.appendChild(e),n=re.createElement(\"input\"),n.setAttribute(\"type\",\"radio\"),n.setAttribute(\"checked\",\"checked\"),n.setAttribute(\"name\",\"t\"),e.appendChild(n),fe.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,fe.noCloneEvent=!!e.addEventListener,e[pe.expando]=1,fe.attributes=!e.getAttribute(pe.expando)}();var Xe={option:[1,\"<select multiple='multiple'>\",\"</select>\"],legend:[1,\"<fieldset>\",\"</fieldset>\"],area:[1,\"<map>\",\"</map>\"],param:[1,\"<object>\",\"</object>\"],thead:[1,\"<table>\",\"</table>\"],tr:[2,\"<table><tbody>\",\"</tbody></table>\"],col:[2,\"<table><tbody></tbody><colgroup>\",\"</colgroup></table>\"],td:[3,\"<table><tbody><tr>\",\"</tr></tbody></table>\"],_default:fe.htmlSerialize?[0,\"\",\"\"]:[1,\"X<div>\",\"</div>\"]};Xe.optgroup=Xe.option,Xe.tbody=Xe.tfoot=Xe.colgroup=Xe.caption=Xe.thead,Xe.th=Xe.td;var Ue=/<|&#?\\w+;/,Ve=/<tbody/i;!function(){var t,n,r=re.createElement(\"div\");for(t in{submit:!0,change:!0,focusin:!0})n=\"on\"+t,(fe[t]=n in e)||(r.setAttribute(n,\"t\"),fe[t]=r.attributes[n].expando===!1);r=null}();var Ye=/^(?:input|select|textarea)$/i,Je=/^key/,Ge=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ke=/^(?:focusinfocus|focusoutblur)$/,Qe=/^([^.]*)(?:\\.(.+)|)/;pe.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,d,p,h,g,m=pe._data(e);if(m){for(n.handler&&(u=n,n=u.handler,i=u.selector),n.guid||(n.guid=pe.guid++),(a=m.events)||(a=m.events={}),(c=m.handle)||(c=m.handle=function(e){return\"undefined\"==typeof pe||e&&pe.event.triggered===e.type?void 0:pe.event.dispatch.apply(c.elem,arguments)},c.elem=e),t=(t||\"\").match(De)||[\"\"],s=t.length;s--;)o=Qe.exec(t[s])||[],p=g=o[1],h=(o[2]||\"\").split(\".\").sort(),p&&(l=pe.event.special[p]||{},p=(i?l.delegateType:l.bindType)||p,l=pe.event.special[p]||{},f=pe.extend({type:p,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&pe.expr.match.needsContext.test(i),namespace:h.join(\".\")},u),(d=a[p])||(d=a[p]=[],d.delegateCount=0,l.setup&&l.setup.call(e,r,h,c)!==!1||(e.addEventListener?e.addEventListener(p,c,!1):e.attachEvent&&e.attachEvent(\"on\"+p,c))),l.add&&(l.add.call(e,f),f.handler.guid||(f.handler.guid=n.guid)),i?d.splice(d.delegateCount++,0,f):d.push(f),pe.event.global[p]=!0);e=null}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,d,p,h,g,m=pe.hasData(e)&&pe._data(e);if(m&&(c=m.events)){for(t=(t||\"\").match(De)||[\"\"],l=t.length;l--;)if(s=Qe.exec(t[l])||[],p=g=s[1],h=(s[2]||\"\").split(\".\").sort(),p){for(f=pe.event.special[p]||{},p=(r?f.delegateType:f.bindType)||p,d=c[p]||[],s=s[2]&&new RegExp(\"(^|\\\\.)\"+h.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"),u=o=d.length;o--;)a=d[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&(\"**\"!==r||!a.selector)||(d.splice(o,1),a.selector&&d.delegateCount--,f.remove&&f.remove.call(e,a));u&&!d.length&&(f.teardown&&f.teardown.call(e,h,m.handle)!==!1||pe.removeEvent(e,p,m.handle),delete c[p])}else for(p in c)pe.event.remove(e,p+t[l],n,r,!0);pe.isEmptyObject(c)&&(delete m.handle,pe._removeData(e,\"events\"))}},trigger:function(t,n,r,i){var o,a,s,u,l,c,f,d=[r||re],p=ce.call(t,\"type\")?t.type:t,h=ce.call(t,\"namespace\")?t.namespace.split(\".\"):[];if(s=c=r=r||re,3!==r.nodeType&&8!==r.nodeType&&!Ke.test(p+pe.event.triggered)&&(p.indexOf(\".\")>-1&&(h=p.split(\".\"),p=h.shift(),h.sort()),a=p.indexOf(\":\")<0&&\"on\"+p,t=t[pe.expando]?t:new pe.Event(p,\"object\"==typeof t&&t),t.isTrigger=i?2:3,t.namespace=h.join(\".\"),t.rnamespace=t.namespace?new RegExp(\"(^|\\\\.)\"+h.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"):null,t.result=void 0,t.target||(t.target=r),n=null==n?[t]:pe.makeArray(n,[t]),l=pe.event.special[p]||{},i||!l.trigger||l.trigger.apply(r,n)!==!1)){if(!i&&!l.noBubble&&!pe.isWindow(r)){for(u=l.delegateType||p,Ke.test(u+p)||(s=s.parentNode);s;s=s.parentNode)d.push(s),c=s;c===(r.ownerDocument||re)&&d.push(c.defaultView||c.parentWindow||e)}for(f=0;(s=d[f++])&&!t.isPropagationStopped();)t.type=f>1?u:l.bindType||p,o=(pe._data(s,\"events\")||{})[t.type]&&pe._data(s,\"handle\"),o&&o.apply(s,n),o=a&&s[a],o&&o.apply&&He(s)&&(t.result=o.apply(s,n),t.result===!1&&t.preventDefault());if(t.type=p,!i&&!t.isDefaultPrevented()&&(!l._default||l._default.apply(d.pop(),n)===!1)&&He(r)&&a&&r[p]&&!pe.isWindow(r)){c=r[a],c&&(r[a]=null),pe.event.triggered=p;try{r[p]()}catch(g){}pe.event.triggered=void 0,c&&(r[a]=c)}return t.result}},dispatch:function(e){e=pe.event.fix(e);var t,n,r,i,o,a=[],s=ie.call(arguments),u=(pe._data(this,\"events\")||{})[e.type]||[],l=pe.event.special[e.type]||{};if(s[0]=e,e.delegateTarget=this,!l.preDispatch||l.preDispatch.call(this,e)!==!1){for(a=pe.event.handlers.call(this,e,u),t=0;(i=a[t++])&&!e.isPropagationStopped();)for(e.currentTarget=i.elem,n=0;(o=i.handlers[n++])&&!e.isImmediatePropagationStopped();)e.rnamespace&&!e.rnamespace.test(o.namespace)||(e.handleObj=o,e.data=o.data,r=((pe.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s),void 0!==r&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()));return l.postDispatch&&l.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,r,i,o,a=[],s=t.delegateCount,u=e.target;if(s&&u.nodeType&&(\"click\"!==e.type||isNaN(e.button)||e.button<1))for(;u!=this;u=u.parentNode||this)if(1===u.nodeType&&(u.disabled!==!0||\"click\"!==e.type)){for(r=[],n=0;n<s;n++)o=t[n],i=o.selector+\" \",void 0===r[i]&&(r[i]=o.needsContext?pe(i,this).index(u)>-1:pe.find(i,this,null,[u]).length),r[i]&&r.push(o);r.length&&a.push({elem:u,handlers:r})}return s<t.length&&a.push({elem:this,handlers:t.slice(s)}),a},fix:function(e){if(e[pe.expando])return e;var t,n,r,i=e.type,o=e,a=this.fixHooks[i];for(a||(this.fixHooks[i]=a=Ge.test(i)?this.mouseHooks:Je.test(i)?this.keyHooks:{}),r=a.props?this.props.concat(a.props):this.props,e=new pe.Event(o),t=r.length;t--;)n=r[t],e[n]=o[n];return e.target||(e.target=o.srcElement||re),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,a.filter?a.filter(e,o):e},props:\"altKey bubbles cancelable ctrlKey currentTarget detail eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),fixHooks:{},keyHooks:{props:\"char charCode key keyCode\".split(\" \"),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:\"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),filter:function(e,t){var n,r,i,o=t.button,a=t.fromElement;return null==e.pageX&&null!=t.clientX&&(r=e.target.ownerDocument||re,i=r.documentElement,n=r.body,e.pageX=t.clientX+(i&&i.scrollLeft||n&&n.scrollLeft||0)-(i&&i.clientLeft||n&&n.clientLeft||0),e.pageY=t.clientY+(i&&i.scrollTop||n&&n.scrollTop||0)-(i&&i.clientTop||n&&n.clientTop||0)),!e.relatedTarget&&a&&(e.relatedTarget=a===e.target?t.toElement:a),e.which||void 0===o||(e.which=1&o?1:2&o?3:4&o?2:0),e}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==b()&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:\"focusin\"},blur:{trigger:function(){if(this===b()&&this.blur)return this.blur(),!1},delegateType:\"focusout\"},click:{trigger:function(){if(pe.nodeName(this,\"input\")&&\"checkbox\"===this.type&&this.click)return this.click(),!1},_default:function(e){return pe.nodeName(e.target,\"a\")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n){var r=pe.extend(new pe.Event,n,{type:e,isSimulated:!0});pe.event.trigger(r,null,t),r.isDefaultPrevented()&&n.preventDefault()}},pe.removeEvent=re.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)}:function(e,t,n){var r=\"on\"+t;e.detachEvent&&(\"undefined\"==typeof e[r]&&(e[r]=null),e.detachEvent(r,n))},pe.Event=function(e,t){return this instanceof pe.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&e.returnValue===!1?v:x):this.type=e,t&&pe.extend(this,t),this.timeStamp=e&&e.timeStamp||pe.now(),void(this[pe.expando]=!0)):new pe.Event(e,t)},pe.Event.prototype={constructor:pe.Event,isDefaultPrevented:x,isPropagationStopped:x,isImmediatePropagationStopped:x,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=v,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=v,e&&!this.isSimulated&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=v,e&&e.stopImmediatePropagation&&e.stopImmediatePropagation(),this.stopPropagation()}},pe.each({mouseenter:\"mouseover\",mouseleave:\"mouseout\",pointerenter:\"pointerover\",pointerleave:\"pointerout\"},function(e,t){pe.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return i&&(i===r||pe.contains(r,i))||(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),fe.submit||(pe.event.special.submit={setup:function(){return!pe.nodeName(this,\"form\")&&void pe.event.add(this,\"click._submit keypress._submit\",function(e){var t=e.target,n=pe.nodeName(t,\"input\")||pe.nodeName(t,\"button\")?pe.prop(t,\"form\"):void 0;n&&!pe._data(n,\"submit\")&&(pe.event.add(n,\"submit._submit\",function(e){e._submitBubble=!0}),pe._data(n,\"submit\",!0))})},postDispatch:function(e){e._submitBubble&&(delete e._submitBubble,this.parentNode&&!e.isTrigger&&pe.event.simulate(\"submit\",this.parentNode,e))},teardown:function(){return!pe.nodeName(this,\"form\")&&void pe.event.remove(this,\"._submit\")}}),fe.change||(pe.event.special.change={setup:function(){return Ye.test(this.nodeName)?(\"checkbox\"!==this.type&&\"radio\"!==this.type||(pe.event.add(this,\"propertychange._change\",function(e){\"checked\"===e.originalEvent.propertyName&&(this._justChanged=!0)}),pe.event.add(this,\"click._change\",function(e){this._justChanged&&!e.isTrigger&&(this._justChanged=!1),pe.event.simulate(\"change\",this,e)})),!1):void pe.event.add(this,\"beforeactivate._change\",function(e){var t=e.target;Ye.test(t.nodeName)&&!pe._data(t,\"change\")&&(pe.event.add(t,\"change._change\",function(e){!this.parentNode||e.isSimulated||e.isTrigger||pe.event.simulate(\"change\",this.parentNode,e)}),pe._data(t,\"change\",!0))})},handle:function(e){var t=e.target;if(this!==t||e.isSimulated||e.isTrigger||\"radio\"!==t.type&&\"checkbox\"!==t.type)return e.handleObj.handler.apply(this,arguments)},teardown:function(){return pe.event.remove(this,\"._change\"),!Ye.test(this.nodeName)}}),fe.focusin||pe.each({focus:\"focusin\",blur:\"focusout\"},function(e,t){var n=function(e){pe.event.simulate(t,e.target,pe.event.fix(e))};pe.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=pe._data(r,t);i||r.addEventListener(e,n,!0),pe._data(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=pe._data(r,t)-1;i?pe._data(r,t,i):(r.removeEventListener(e,n,!0),pe._removeData(r,t))}}}),pe.fn.extend({on:function(e,t,n,r){return w(this,e,t,n,r)},one:function(e,t,n,r){return w(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,pe(e.delegateTarget).off(r.namespace?r.origType+\".\"+r.namespace:r.origType,r.selector,r.handler),this;if(\"object\"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return t!==!1&&\"function\"!=typeof t||(n=t,t=void 0),n===!1&&(n=x),this.each(function(){pe.event.remove(this,e,n,t)})},trigger:function(e,t){return this.each(function(){pe.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return pe.event.trigger(e,t,n,!0)}});var Ze=/ jQuery\\d+=\"(?:null|\\d+)\"/g,et=new RegExp(\"<(?:\"+ze+\")[\\\\s/>]\",\"i\"),tt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:-]+)[^>]*)\\/>/gi,nt=/<script|<style|<link/i,rt=/checked\\s*(?:[^=]|=\\s*.checked.)/i,it=/^true\\/(.*)/,ot=/^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g,at=p(re),st=at.appendChild(re.createElement(\"div\"));pe.extend({htmlPrefilter:function(e){return e.replace(tt,\"<$1></$2>\")},clone:function(e,t,n){var r,i,o,a,s,u=pe.contains(e.ownerDocument,e);if(fe.html5Clone||pe.isXMLDoc(e)||!et.test(\"<\"+e.nodeName+\">\")?o=e.cloneNode(!0):(st.innerHTML=e.outerHTML,st.removeChild(o=st.firstChild)),!(fe.noCloneEvent&&fe.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||pe.isXMLDoc(e)))for(r=h(o),s=h(e),a=0;null!=(i=s[a]);++a)r[a]&&k(i,r[a]);if(t)if(n)for(s=s||h(e),r=r||h(o),a=0;null!=(i=s[a]);a++)N(i,r[a]);else N(e,o);return r=h(o,\"script\"),r.length>0&&g(r,!u&&h(e,\"script\")),r=s=i=null,o},cleanData:function(e,t){for(var n,r,i,o,a=0,s=pe.expando,u=pe.cache,l=fe.attributes,c=pe.event.special;null!=(n=e[a]);a++)if((t||He(n))&&(i=n[s],o=i&&u[i])){if(o.events)for(r in o.events)c[r]?pe.event.remove(n,r):pe.removeEvent(n,r,o.handle);u[i]&&(delete u[i],l||\"undefined\"==typeof n.removeAttribute?n[s]=void 0:n.removeAttribute(s),ne.push(i))}}}),pe.fn.extend({domManip:S,detach:function(e){return A(this,e,!0)},remove:function(e){return A(this,e)},text:function(e){return Pe(this,function(e){return void 0===e?pe.text(this):this.empty().append((this[0]&&this[0].ownerDocument||re).createTextNode(e))},null,e,arguments.length)},append:function(){return S(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=T(this,e);t.appendChild(e)}})},prepend:function(){return S(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=T(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return S(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return S(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++){for(1===e.nodeType&&pe.cleanData(h(e,!1));e.firstChild;)e.removeChild(e.firstChild);e.options&&pe.nodeName(e,\"select\")&&(e.options.length=0)}return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return pe.clone(this,e,t)})},html:function(e){return Pe(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e)return 1===t.nodeType?t.innerHTML.replace(Ze,\"\"):void 0;if(\"string\"==typeof e&&!nt.test(e)&&(fe.htmlSerialize||!et.test(e))&&(fe.leadingWhitespace||!$e.test(e))&&!Xe[(We.exec(e)||[\"\",\"\"])[1].toLowerCase()]){e=pe.htmlPrefilter(e);try{for(;n<r;n++)t=this[n]||{},1===t.nodeType&&(pe.cleanData(h(t,!1)),t.innerHTML=e);t=0}catch(i){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=[];return S(this,arguments,function(t){var n=this.parentNode;pe.inArray(this,e)<0&&(pe.cleanData(h(this)),\nn&&n.replaceChild(t,this))},e)}}),pe.each({appendTo:\"append\",prependTo:\"prepend\",insertBefore:\"before\",insertAfter:\"after\",replaceAll:\"replaceWith\"},function(e,t){pe.fn[e]=function(e){for(var n,r=0,i=[],o=pe(e),a=o.length-1;r<=a;r++)n=r===a?this:this.clone(!0),pe(o[r])[t](n),ae.apply(i,n.get());return this.pushStack(i)}});var ut,lt={HTML:\"block\",BODY:\"block\"},ct=/^margin/,ft=new RegExp(\"^(\"+Fe+\")(?!px)[a-z%]+$\",\"i\"),dt=function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i},pt=re.documentElement;!function(){function t(){var t,c,f=re.documentElement;f.appendChild(u),l.style.cssText=\"-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%\",n=i=s=!1,r=a=!0,e.getComputedStyle&&(c=e.getComputedStyle(l),n=\"1%\"!==(c||{}).top,s=\"2px\"===(c||{}).marginLeft,i=\"4px\"===(c||{width:\"4px\"}).width,l.style.marginRight=\"50%\",r=\"4px\"===(c||{marginRight:\"4px\"}).marginRight,t=l.appendChild(re.createElement(\"div\")),t.style.cssText=l.style.cssText=\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0\",t.style.marginRight=t.style.width=\"0\",l.style.width=\"1px\",a=!parseFloat((e.getComputedStyle(t)||{}).marginRight),l.removeChild(t)),l.style.display=\"none\",o=0===l.getClientRects().length,o&&(l.style.display=\"\",l.innerHTML=\"<table><tr><td></td><td>t</td></tr></table>\",t=l.getElementsByTagName(\"td\"),t[0].style.cssText=\"margin:0;border:0;padding:0;display:none\",o=0===t[0].offsetHeight,o&&(t[0].style.display=\"\",t[1].style.display=\"none\",o=0===t[0].offsetHeight)),f.removeChild(u)}var n,r,i,o,a,s,u=re.createElement(\"div\"),l=re.createElement(\"div\");l.style&&(l.style.cssText=\"float:left;opacity:.5\",fe.opacity=\"0.5\"===l.style.opacity,fe.cssFloat=!!l.style.cssFloat,l.style.backgroundClip=\"content-box\",l.cloneNode(!0).style.backgroundClip=\"\",fe.clearCloneStyle=\"content-box\"===l.style.backgroundClip,u=re.createElement(\"div\"),u.style.cssText=\"border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute\",l.innerHTML=\"\",u.appendChild(l),fe.boxSizing=\"\"===l.style.boxSizing||\"\"===l.style.MozBoxSizing||\"\"===l.style.WebkitBoxSizing,pe.extend(fe,{reliableHiddenOffsets:function(){return null==n&&t(),o},boxSizingReliable:function(){return null==n&&t(),i},pixelMarginRight:function(){return null==n&&t(),r},pixelPosition:function(){return null==n&&t(),n},reliableMarginRight:function(){return null==n&&t(),a},reliableMarginLeft:function(){return null==n&&t(),s}}))}();var ht,gt,mt=/^(top|right|bottom|left)$/;e.getComputedStyle?(ht=function(t){var n=t.ownerDocument.defaultView;return n&&n.opener||(n=e),n.getComputedStyle(t)},gt=function(e,t,n){var r,i,o,a,s=e.style;return n=n||ht(e),a=n?n.getPropertyValue(t)||n[t]:void 0,\"\"!==a&&void 0!==a||pe.contains(e.ownerDocument,e)||(a=pe.style(e,t)),n&&!fe.pixelMarginRight()&&ft.test(a)&&ct.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o),void 0===a?a:a+\"\"}):pt.currentStyle&&(ht=function(e){return e.currentStyle},gt=function(e,t,n){var r,i,o,a,s=e.style;return n=n||ht(e),a=n?n[t]:void 0,null==a&&s&&s[t]&&(a=s[t]),ft.test(a)&&!mt.test(t)&&(r=s.left,i=e.runtimeStyle,o=i&&i.left,o&&(i.left=e.currentStyle.left),s.left=\"fontSize\"===t?\"1em\":a,a=s.pixelLeft+\"px\",s.left=r,o&&(i.left=o)),void 0===a?a:a+\"\"||\"auto\"});var yt=/alpha\\([^)]*\\)/i,vt=/opacity\\s*=\\s*([^)]*)/i,xt=/^(none|table(?!-c[ea]).+)/,bt=new RegExp(\"^(\"+Fe+\")(.*)$\",\"i\"),wt={position:\"absolute\",visibility:\"hidden\",display:\"block\"},Tt={letterSpacing:\"0\",fontWeight:\"400\"},Ct=[\"Webkit\",\"O\",\"Moz\",\"ms\"],Et=re.createElement(\"div\").style;pe.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=gt(e,\"opacity\");return\"\"===n?\"1\":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{\"float\":fe.cssFloat?\"cssFloat\":\"styleFloat\"},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=pe.camelCase(t),u=e.style;if(t=pe.cssProps[s]||(pe.cssProps[s]=H(s)||s),a=pe.cssHooks[t]||pe.cssHooks[s],void 0===n)return a&&\"get\"in a&&void 0!==(i=a.get(e,!1,r))?i:u[t];if(o=typeof n,\"string\"===o&&(i=Me.exec(n))&&i[1]&&(n=d(e,t,i),o=\"number\"),null!=n&&n===n&&(\"number\"===o&&(n+=i&&i[3]||(pe.cssNumber[s]?\"\":\"px\")),fe.clearCloneStyle||\"\"!==n||0!==t.indexOf(\"background\")||(u[t]=\"inherit\"),!(a&&\"set\"in a&&void 0===(n=a.set(e,n,r)))))try{u[t]=n}catch(l){}}},css:function(e,t,n,r){var i,o,a,s=pe.camelCase(t);return t=pe.cssProps[s]||(pe.cssProps[s]=H(s)||s),a=pe.cssHooks[t]||pe.cssHooks[s],a&&\"get\"in a&&(o=a.get(e,!0,n)),void 0===o&&(o=gt(e,t,r)),\"normal\"===o&&t in Tt&&(o=Tt[t]),\"\"===n||n?(i=parseFloat(o),n===!0||isFinite(i)?i||0:o):o}}),pe.each([\"height\",\"width\"],function(e,t){pe.cssHooks[t]={get:function(e,n,r){if(n)return xt.test(pe.css(e,\"display\"))&&0===e.offsetWidth?dt(e,wt,function(){return M(e,t,r)}):M(e,t,r)},set:function(e,n,r){var i=r&&ht(e);return _(e,n,r?F(e,t,r,fe.boxSizing&&\"border-box\"===pe.css(e,\"boxSizing\",!1,i),i):0)}}}),fe.opacity||(pe.cssHooks.opacity={get:function(e,t){return vt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||\"\")?.01*parseFloat(RegExp.$1)+\"\":t?\"1\":\"\"},set:function(e,t){var n=e.style,r=e.currentStyle,i=pe.isNumeric(t)?\"alpha(opacity=\"+100*t+\")\":\"\",o=r&&r.filter||n.filter||\"\";n.zoom=1,(t>=1||\"\"===t)&&\"\"===pe.trim(o.replace(yt,\"\"))&&n.removeAttribute&&(n.removeAttribute(\"filter\"),\"\"===t||r&&!r.filter)||(n.filter=yt.test(o)?o.replace(yt,i):o+\" \"+i)}}),pe.cssHooks.marginRight=L(fe.reliableMarginRight,function(e,t){if(t)return dt(e,{display:\"inline-block\"},gt,[e,\"marginRight\"])}),pe.cssHooks.marginLeft=L(fe.reliableMarginLeft,function(e,t){if(t)return(parseFloat(gt(e,\"marginLeft\"))||(pe.contains(e.ownerDocument,e)?e.getBoundingClientRect().left-dt(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}):0))+\"px\"}),pe.each({margin:\"\",padding:\"\",border:\"Width\"},function(e,t){pe.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o=\"string\"==typeof n?n.split(\" \"):[n];r<4;r++)i[e+Oe[r]+t]=o[r]||o[r-2]||o[0];return i}},ct.test(e)||(pe.cssHooks[e+t].set=_)}),pe.fn.extend({css:function(e,t){return Pe(this,function(e,t,n){var r,i,o={},a=0;if(pe.isArray(t)){for(r=ht(e),i=t.length;a<i;a++)o[t[a]]=pe.css(e,t[a],!1,r);return o}return void 0!==n?pe.style(e,t,n):pe.css(e,t)},e,t,arguments.length>1)},show:function(){return q(this,!0)},hide:function(){return q(this)},toggle:function(e){return\"boolean\"==typeof e?e?this.show():this.hide():this.each(function(){Re(this)?pe(this).show():pe(this).hide()})}}),pe.Tween=O,O.prototype={constructor:O,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||pe.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(pe.cssNumber[n]?\"\":\"px\")},cur:function(){var e=O.propHooks[this.prop];return e&&e.get?e.get(this):O.propHooks._default.get(this)},run:function(e){var t,n=O.propHooks[this.prop];return this.options.duration?this.pos=t=pe.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):O.propHooks._default.set(this),this}},O.prototype.init.prototype=O.prototype,O.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=pe.css(e.elem,e.prop,\"\"),t&&\"auto\"!==t?t:0)},set:function(e){pe.fx.step[e.prop]?pe.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[pe.cssProps[e.prop]]&&!pe.cssHooks[e.prop]?e.elem[e.prop]=e.now:pe.style(e.elem,e.prop,e.now+e.unit)}}},O.propHooks.scrollTop=O.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},pe.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:\"swing\"},pe.fx=O.prototype.init,pe.fx.step={};var Nt,kt,St=/^(?:toggle|show|hide)$/,At=/queueHooks$/;pe.Animation=pe.extend($,{tweeners:{\"*\":[function(e,t){var n=this.createTween(e,t);return d(n.elem,e,Me.exec(t),n),n}]},tweener:function(e,t){pe.isFunction(e)?(t=e,e=[\"*\"]):e=e.match(De);for(var n,r=0,i=e.length;r<i;r++)n=e[r],$.tweeners[n]=$.tweeners[n]||[],$.tweeners[n].unshift(t)},prefilters:[W],prefilter:function(e,t){t?$.prefilters.unshift(e):$.prefilters.push(e)}}),pe.speed=function(e,t,n){var r=e&&\"object\"==typeof e?pe.extend({},e):{complete:n||!n&&t||pe.isFunction(e)&&e,duration:e,easing:n&&t||t&&!pe.isFunction(t)&&t};return r.duration=pe.fx.off?0:\"number\"==typeof r.duration?r.duration:r.duration in pe.fx.speeds?pe.fx.speeds[r.duration]:pe.fx.speeds._default,null!=r.queue&&r.queue!==!0||(r.queue=\"fx\"),r.old=r.complete,r.complete=function(){pe.isFunction(r.old)&&r.old.call(this),r.queue&&pe.dequeue(this,r.queue)},r},pe.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Re).css(\"opacity\",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=pe.isEmptyObject(e),o=pe.speed(t,n,r),a=function(){var t=$(this,pe.extend({},e),o);(i||pe._data(this,\"finish\"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return\"string\"!=typeof e&&(n=t,t=e,e=void 0),t&&e!==!1&&this.queue(e||\"fx\",[]),this.each(function(){var t=!0,i=null!=e&&e+\"queueHooks\",o=pe.timers,a=pe._data(this);if(i)a[i]&&a[i].stop&&r(a[i]);else for(i in a)a[i]&&a[i].stop&&At.test(i)&&r(a[i]);for(i=o.length;i--;)o[i].elem!==this||null!=e&&o[i].queue!==e||(o[i].anim.stop(n),t=!1,o.splice(i,1));!t&&n||pe.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||\"fx\"),this.each(function(){var t,n=pe._data(this),r=n[e+\"queue\"],i=n[e+\"queueHooks\"],o=pe.timers,a=r?r.length:0;for(n.finish=!0,pe.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;t<a;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}}),pe.each([\"toggle\",\"show\",\"hide\"],function(e,t){var n=pe.fn[t];pe.fn[t]=function(e,r,i){return null==e||\"boolean\"==typeof e?n.apply(this,arguments):this.animate(P(t,!0),e,r,i)}}),pe.each({slideDown:P(\"show\"),slideUp:P(\"hide\"),slideToggle:P(\"toggle\"),fadeIn:{opacity:\"show\"},fadeOut:{opacity:\"hide\"},fadeToggle:{opacity:\"toggle\"}},function(e,t){pe.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),pe.timers=[],pe.fx.tick=function(){var e,t=pe.timers,n=0;for(Nt=pe.now();n<t.length;n++)e=t[n],e()||t[n]!==e||t.splice(n--,1);t.length||pe.fx.stop(),Nt=void 0},pe.fx.timer=function(e){pe.timers.push(e),e()?pe.fx.start():pe.timers.pop()},pe.fx.interval=13,pe.fx.start=function(){kt||(kt=e.setInterval(pe.fx.tick,pe.fx.interval))},pe.fx.stop=function(){e.clearInterval(kt),kt=null},pe.fx.speeds={slow:600,fast:200,_default:400},pe.fn.delay=function(t,n){return t=pe.fx?pe.fx.speeds[t]||t:t,n=n||\"fx\",this.queue(n,function(n,r){var i=e.setTimeout(n,t);r.stop=function(){e.clearTimeout(i)}})},function(){var e,t=re.createElement(\"input\"),n=re.createElement(\"div\"),r=re.createElement(\"select\"),i=r.appendChild(re.createElement(\"option\"));n=re.createElement(\"div\"),n.setAttribute(\"className\",\"t\"),n.innerHTML=\"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\",e=n.getElementsByTagName(\"a\")[0],t.setAttribute(\"type\",\"checkbox\"),n.appendChild(t),e=n.getElementsByTagName(\"a\")[0],e.style.cssText=\"top:1px\",fe.getSetAttribute=\"t\"!==n.className,fe.style=/top/.test(e.getAttribute(\"style\")),fe.hrefNormalized=\"/a\"===e.getAttribute(\"href\"),fe.checkOn=!!t.value,fe.optSelected=i.selected,fe.enctype=!!re.createElement(\"form\").enctype,r.disabled=!0,fe.optDisabled=!i.disabled,t=re.createElement(\"input\"),t.setAttribute(\"value\",\"\"),fe.input=\"\"===t.getAttribute(\"value\"),t.value=\"t\",t.setAttribute(\"type\",\"radio\"),fe.radioValue=\"t\"===t.value}();var Dt=/\\r/g,jt=/[\\x20\\t\\r\\n\\f]+/g;pe.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=pe.isFunction(e),this.each(function(n){var i;1===this.nodeType&&(i=r?e.call(this,n,pe(this).val()):e,null==i?i=\"\":\"number\"==typeof i?i+=\"\":pe.isArray(i)&&(i=pe.map(i,function(e){return null==e?\"\":e+\"\"})),t=pe.valHooks[this.type]||pe.valHooks[this.nodeName.toLowerCase()],t&&\"set\"in t&&void 0!==t.set(this,i,\"value\")||(this.value=i))});if(i)return t=pe.valHooks[i.type]||pe.valHooks[i.nodeName.toLowerCase()],t&&\"get\"in t&&void 0!==(n=t.get(i,\"value\"))?n:(n=i.value,\"string\"==typeof n?n.replace(Dt,\"\"):null==n?\"\":n)}}}),pe.extend({valHooks:{option:{get:function(e){var t=pe.find.attr(e,\"value\");return null!=t?t:pe.trim(pe.text(e)).replace(jt,\" \")}},select:{get:function(e){for(var t,n,r=e.options,i=e.selectedIndex,o=\"select-one\"===e.type||i<0,a=o?null:[],s=o?i+1:r.length,u=i<0?s:o?i:0;u<s;u++)if(n=r[u],(n.selected||u===i)&&(fe.optDisabled?!n.disabled:null===n.getAttribute(\"disabled\"))&&(!n.parentNode.disabled||!pe.nodeName(n.parentNode,\"optgroup\"))){if(t=pe(n).val(),o)return t;a.push(t)}return a},set:function(e,t){for(var n,r,i=e.options,o=pe.makeArray(t),a=i.length;a--;)if(r=i[a],pe.inArray(pe.valHooks.option.get(r),o)>-1)try{r.selected=n=!0}catch(s){r.scrollHeight}else r.selected=!1;return n||(e.selectedIndex=-1),i}}}}),pe.each([\"radio\",\"checkbox\"],function(){pe.valHooks[this]={set:function(e,t){if(pe.isArray(t))return e.checked=pe.inArray(pe(e).val(),t)>-1}},fe.checkOn||(pe.valHooks[this].get=function(e){return null===e.getAttribute(\"value\")?\"on\":e.value})});var Lt,Ht,qt=pe.expr.attrHandle,_t=/^(?:checked|selected)$/i,Ft=fe.getSetAttribute,Mt=fe.input;pe.fn.extend({attr:function(e,t){return Pe(this,pe.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){pe.removeAttr(this,e)})}}),pe.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return\"undefined\"==typeof e.getAttribute?pe.prop(e,t,n):(1===o&&pe.isXMLDoc(e)||(t=t.toLowerCase(),i=pe.attrHooks[t]||(pe.expr.match.bool.test(t)?Ht:Lt)),void 0!==n?null===n?void pe.removeAttr(e,t):i&&\"set\"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+\"\"),n):i&&\"get\"in i&&null!==(r=i.get(e,t))?r:(r=pe.find.attr(e,t),null==r?void 0:r))},attrHooks:{type:{set:function(e,t){if(!fe.radioValue&&\"radio\"===t&&pe.nodeName(e,\"input\")){var n=e.value;return e.setAttribute(\"type\",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(De);if(o&&1===e.nodeType)for(;n=o[i++];)r=pe.propFix[n]||n,pe.expr.match.bool.test(n)?Mt&&Ft||!_t.test(n)?e[r]=!1:e[pe.camelCase(\"default-\"+n)]=e[r]=!1:pe.attr(e,n,\"\"),e.removeAttribute(Ft?n:r)}}),Ht={set:function(e,t,n){return t===!1?pe.removeAttr(e,n):Mt&&Ft||!_t.test(n)?e.setAttribute(!Ft&&pe.propFix[n]||n,n):e[pe.camelCase(\"default-\"+n)]=e[n]=!0,n}},pe.each(pe.expr.match.bool.source.match(/\\w+/g),function(e,t){var n=qt[t]||pe.find.attr;Mt&&Ft||!_t.test(t)?qt[t]=function(e,t,r){var i,o;return r||(o=qt[t],qt[t]=i,i=null!=n(e,t,r)?t.toLowerCase():null,qt[t]=o),i}:qt[t]=function(e,t,n){if(!n)return e[pe.camelCase(\"default-\"+t)]?t.toLowerCase():null}}),Mt&&Ft||(pe.attrHooks.value={set:function(e,t,n){return pe.nodeName(e,\"input\")?void(e.defaultValue=t):Lt&&Lt.set(e,t,n)}}),Ft||(Lt={set:function(e,t,n){var r=e.getAttributeNode(n);if(r||e.setAttributeNode(r=e.ownerDocument.createAttribute(n)),r.value=t+=\"\",\"value\"===n||t===e.getAttribute(n))return t}},qt.id=qt.name=qt.coords=function(e,t,n){var r;if(!n)return(r=e.getAttributeNode(t))&&\"\"!==r.value?r.value:null},pe.valHooks.button={get:function(e,t){var n=e.getAttributeNode(t);if(n&&n.specified)return n.value},set:Lt.set},pe.attrHooks.contenteditable={set:function(e,t,n){Lt.set(e,\"\"!==t&&t,n)}},pe.each([\"width\",\"height\"],function(e,t){pe.attrHooks[t]={set:function(e,n){if(\"\"===n)return e.setAttribute(t,\"auto\"),n}}})),fe.style||(pe.attrHooks.style={get:function(e){return e.style.cssText||void 0},set:function(e,t){return e.style.cssText=t+\"\"}});var Ot=/^(?:input|select|textarea|button|object)$/i,Rt=/^(?:a|area)$/i;pe.fn.extend({prop:function(e,t){return Pe(this,pe.prop,e,t,arguments.length>1)},removeProp:function(e){return e=pe.propFix[e]||e,this.each(function(){try{this[e]=void 0,delete this[e]}catch(t){}})}}),pe.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&pe.isXMLDoc(e)||(t=pe.propFix[t]||t,i=pe.propHooks[t]),void 0!==n?i&&\"set\"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&\"get\"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=pe.find.attr(e,\"tabindex\");return t?parseInt(t,10):Ot.test(e.nodeName)||Rt.test(e.nodeName)&&e.href?0:-1}}},propFix:{\"for\":\"htmlFor\",\"class\":\"className\"}}),fe.hrefNormalized||pe.each([\"href\",\"src\"],function(e,t){pe.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}}),fe.optSelected||(pe.propHooks.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),pe.each([\"tabIndex\",\"readOnly\",\"maxLength\",\"cellSpacing\",\"cellPadding\",\"rowSpan\",\"colSpan\",\"useMap\",\"frameBorder\",\"contentEditable\"],function(){pe.propFix[this.toLowerCase()]=this}),fe.enctype||(pe.propFix.enctype=\"encoding\");var Pt=/[\\t\\r\\n\\f]/g;pe.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(pe.isFunction(e))return this.each(function(t){pe(this).addClass(e.call(this,t,z(this)))});if(\"string\"==typeof e&&e)for(t=e.match(De)||[];n=this[u++];)if(i=z(n),r=1===n.nodeType&&(\" \"+i+\" \").replace(Pt,\" \")){for(a=0;o=t[a++];)r.indexOf(\" \"+o+\" \")<0&&(r+=o+\" \");s=pe.trim(r),i!==s&&pe.attr(n,\"class\",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(pe.isFunction(e))return this.each(function(t){pe(this).removeClass(e.call(this,t,z(this)))});if(!arguments.length)return this.attr(\"class\",\"\");if(\"string\"==typeof e&&e)for(t=e.match(De)||[];n=this[u++];)if(i=z(n),r=1===n.nodeType&&(\" \"+i+\" \").replace(Pt,\" \")){for(a=0;o=t[a++];)for(;r.indexOf(\" \"+o+\" \")>-1;)r=r.replace(\" \"+o+\" \",\" \");s=pe.trim(r),i!==s&&pe.attr(n,\"class\",s)}return this},toggleClass:function(e,t){var n=typeof e;return\"boolean\"==typeof t&&\"string\"===n?t?this.addClass(e):this.removeClass(e):pe.isFunction(e)?this.each(function(n){pe(this).toggleClass(e.call(this,n,z(this),t),t)}):this.each(function(){var t,r,i,o;if(\"string\"===n)for(r=0,i=pe(this),o=e.match(De)||[];t=o[r++];)i.hasClass(t)?i.removeClass(t):i.addClass(t);else void 0!==e&&\"boolean\"!==n||(t=z(this),t&&pe._data(this,\"__className__\",t),pe.attr(this,\"class\",t||e===!1?\"\":pe._data(this,\"__className__\")||\"\"))})},hasClass:function(e){var t,n,r=0;for(t=\" \"+e+\" \";n=this[r++];)if(1===n.nodeType&&(\" \"+z(n)+\" \").replace(Pt,\" \").indexOf(t)>-1)return!0;return!1}}),pe.each(\"blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu\".split(\" \"),function(e,t){pe.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),pe.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}});var Bt=e.location,Wt=pe.now(),It=/\\?/,$t=/(,)|(\\[|{)|(}|])|\"(?:[^\"\\\\\\r\\n]|\\\\[\"\\\\\\/bfnrt]|\\\\u[\\da-fA-F]{4})*\"\\s*:?|true|false|null|-?(?!0\\d)\\d+(?:\\.\\d+|)(?:[eE][+-]?\\d+|)/g;pe.parseJSON=function(t){if(e.JSON&&e.JSON.parse)return e.JSON.parse(t+\"\");var n,r=null,i=pe.trim(t+\"\");return i&&!pe.trim(i.replace($t,function(e,t,i,o){return n&&t&&(r=0),0===r?e:(n=i||t,r+=!o-!i,\"\")}))?Function(\"return \"+i)():pe.error(\"Invalid JSON: \"+t)},pe.parseXML=function(t){var n,r;if(!t||\"string\"!=typeof t)return null;try{e.DOMParser?(r=new e.DOMParser,n=r.parseFromString(t,\"text/xml\")):(n=new e.ActiveXObject(\"Microsoft.XMLDOM\"),n.async=\"false\",n.loadXML(t))}catch(i){n=void 0}return n&&n.documentElement&&!n.getElementsByTagName(\"parsererror\").length||pe.error(\"Invalid XML: \"+t),n};var zt=/#.*$/,Xt=/([?&])_=[^&]*/,Ut=/^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/gm,Vt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Yt=/^(?:GET|HEAD)$/,Jt=/^\\/\\//,Gt=/^([\\w.+-]+:)(?:\\/\\/(?:[^\\/?#]*@|)([^\\/?#:]*)(?::(\\d+)|)|)/,Kt={},Qt={},Zt=\"*/\".concat(\"*\"),en=Bt.href,tn=Gt.exec(en.toLowerCase())||[];pe.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:en,type:\"GET\",isLocal:Vt.test(tn[1]),global:!0,processData:!0,async:!0,contentType:\"application/x-www-form-urlencoded; charset=UTF-8\",accepts:{\"*\":Zt,text:\"text/plain\",html:\"text/html\",xml:\"application/xml, text/xml\",json:\"application/json, text/javascript\"},contents:{xml:/\\bxml\\b/,html:/\\bhtml/,json:/\\bjson\\b/},responseFields:{xml:\"responseXML\",text:\"responseText\",json:\"responseJSON\"},converters:{\"* text\":String,\"text html\":!0,\"text json\":pe.parseJSON,\"text xml\":pe.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?V(V(e,pe.ajaxSettings),t):V(pe.ajaxSettings,e)},ajaxPrefilter:X(Kt),ajaxTransport:X(Qt),ajax:function(t,n){function r(t,n,r,i){var o,f,v,x,w,C=n;2!==b&&(b=2,u&&e.clearTimeout(u),c=void 0,s=i||\"\",T.readyState=t>0?4:0,o=t>=200&&t<300||304===t,r&&(x=Y(d,T,r)),x=J(d,x,T,o),o?(d.ifModified&&(w=T.getResponseHeader(\"Last-Modified\"),w&&(pe.lastModified[a]=w),w=T.getResponseHeader(\"etag\"),w&&(pe.etag[a]=w)),204===t||\"HEAD\"===d.type?C=\"nocontent\":304===t?C=\"notmodified\":(C=x.state,f=x.data,v=x.error,o=!v)):(v=C,!t&&C||(C=\"error\",t<0&&(t=0))),T.status=t,T.statusText=(n||C)+\"\",o?g.resolveWith(p,[f,C,T]):g.rejectWith(p,[T,C,v]),T.statusCode(y),y=void 0,l&&h.trigger(o?\"ajaxSuccess\":\"ajaxError\",[T,d,o?f:v]),m.fireWith(p,[T,C]),l&&(h.trigger(\"ajaxComplete\",[T,d]),--pe.active||pe.event.trigger(\"ajaxStop\")))}\"object\"==typeof t&&(n=t,t=void 0),n=n||{};var i,o,a,s,u,l,c,f,d=pe.ajaxSetup({},n),p=d.context||d,h=d.context&&(p.nodeType||p.jquery)?pe(p):pe.event,g=pe.Deferred(),m=pe.Callbacks(\"once memory\"),y=d.statusCode||{},v={},x={},b=0,w=\"canceled\",T={readyState:0,getResponseHeader:function(e){var t;if(2===b){if(!f)for(f={};t=Ut.exec(s);)f[t[1].toLowerCase()]=t[2];t=f[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===b?s:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return b||(e=x[n]=x[n]||e,v[e]=t),this},overrideMimeType:function(e){return b||(d.mimeType=e),this},statusCode:function(e){var t;if(e)if(b<2)for(t in e)y[t]=[y[t],e[t]];else T.always(e[T.status]);return this},abort:function(e){var t=e||w;return c&&c.abort(t),r(0,t),this}};if(g.promise(T).complete=m.add,T.success=T.done,T.error=T.fail,d.url=((t||d.url||en)+\"\").replace(zt,\"\").replace(Jt,tn[1]+\"//\"),d.type=n.method||n.type||d.method||d.type,d.dataTypes=pe.trim(d.dataType||\"*\").toLowerCase().match(De)||[\"\"],null==d.crossDomain&&(i=Gt.exec(d.url.toLowerCase()),d.crossDomain=!(!i||i[1]===tn[1]&&i[2]===tn[2]&&(i[3]||(\"http:\"===i[1]?\"80\":\"443\"))===(tn[3]||(\"http:\"===tn[1]?\"80\":\"443\")))),d.data&&d.processData&&\"string\"!=typeof d.data&&(d.data=pe.param(d.data,d.traditional)),U(Kt,d,n,T),2===b)return T;l=pe.event&&d.global,l&&0===pe.active++&&pe.event.trigger(\"ajaxStart\"),d.type=d.type.toUpperCase(),d.hasContent=!Yt.test(d.type),a=d.url,d.hasContent||(d.data&&(a=d.url+=(It.test(a)?\"&\":\"?\")+d.data,delete d.data),d.cache===!1&&(d.url=Xt.test(a)?a.replace(Xt,\"$1_=\"+Wt++):a+(It.test(a)?\"&\":\"?\")+\"_=\"+Wt++)),d.ifModified&&(pe.lastModified[a]&&T.setRequestHeader(\"If-Modified-Since\",pe.lastModified[a]),pe.etag[a]&&T.setRequestHeader(\"If-None-Match\",pe.etag[a])),(d.data&&d.hasContent&&d.contentType!==!1||n.contentType)&&T.setRequestHeader(\"Content-Type\",d.contentType),T.setRequestHeader(\"Accept\",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(\"*\"!==d.dataTypes[0]?\", \"+Zt+\"; q=0.01\":\"\"):d.accepts[\"*\"]);for(o in d.headers)T.setRequestHeader(o,d.headers[o]);if(d.beforeSend&&(d.beforeSend.call(p,T,d)===!1||2===b))return T.abort();w=\"abort\";for(o in{success:1,error:1,complete:1})T[o](d[o]);if(c=U(Qt,d,n,T)){if(T.readyState=1,l&&h.trigger(\"ajaxSend\",[T,d]),2===b)return T;d.async&&d.timeout>0&&(u=e.setTimeout(function(){T.abort(\"timeout\")},d.timeout));try{b=1,c.send(v,r)}catch(C){if(!(b<2))throw C;r(-1,C)}}else r(-1,\"No Transport\");return T},getJSON:function(e,t,n){return pe.get(e,t,n,\"json\")},getScript:function(e,t){return pe.get(e,void 0,t,\"script\")}}),pe.each([\"get\",\"post\"],function(e,t){pe[t]=function(e,n,r,i){return pe.isFunction(n)&&(i=i||r,r=n,n=void 0),pe.ajax(pe.extend({url:e,type:t,dataType:i,data:n,success:r},pe.isPlainObject(e)&&e))}}),pe._evalUrl=function(e){return pe.ajax({url:e,type:\"GET\",dataType:\"script\",cache:!0,async:!1,global:!1,\"throws\":!0})},pe.fn.extend({wrapAll:function(e){if(pe.isFunction(e))return this.each(function(t){pe(this).wrapAll(e.call(this,t))});if(this[0]){var t=pe(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstChild&&1===e.firstChild.nodeType;)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return pe.isFunction(e)?this.each(function(t){pe(this).wrapInner(e.call(this,t))}):this.each(function(){var t=pe(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=pe.isFunction(e);return this.each(function(n){pe(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){pe.nodeName(this,\"body\")||pe(this).replaceWith(this.childNodes)}).end()}}),pe.expr.filters.hidden=function(e){return fe.reliableHiddenOffsets()?e.offsetWidth<=0&&e.offsetHeight<=0&&!e.getClientRects().length:K(e)},pe.expr.filters.visible=function(e){return!pe.expr.filters.hidden(e)};var nn=/%20/g,rn=/\\[\\]$/,on=/\\r?\\n/g,an=/^(?:submit|button|image|reset|file)$/i,sn=/^(?:input|select|textarea|keygen)/i;pe.param=function(e,t){var n,r=[],i=function(e,t){t=pe.isFunction(t)?t():null==t?\"\":t,r[r.length]=encodeURIComponent(e)+\"=\"+encodeURIComponent(t)};if(void 0===t&&(t=pe.ajaxSettings&&pe.ajaxSettings.traditional),pe.isArray(e)||e.jquery&&!pe.isPlainObject(e))pe.each(e,function(){i(this.name,this.value)});else for(n in e)Q(n,e[n],t,i);return r.join(\"&\").replace(nn,\"+\")},pe.fn.extend({serialize:function(){return pe.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=pe.prop(this,\"elements\");return e?pe.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!pe(this).is(\":disabled\")&&sn.test(this.nodeName)&&!an.test(e)&&(this.checked||!Be.test(e))}).map(function(e,t){var n=pe(this).val();return null==n?null:pe.isArray(n)?pe.map(n,function(e){return{name:t.name,value:e.replace(on,\"\\r\\n\")}}):{name:t.name,value:n.replace(on,\"\\r\\n\")}}).get()}}),pe.ajaxSettings.xhr=void 0!==e.ActiveXObject?function(){return this.isLocal?ee():re.documentMode>8?Z():/^(get|post|head|put|delete|options)$/i.test(this.type)&&Z()||ee()}:Z;var un=0,ln={},cn=pe.ajaxSettings.xhr();e.attachEvent&&e.attachEvent(\"onunload\",function(){for(var e in ln)ln[e](void 0,!0)}),fe.cors=!!cn&&\"withCredentials\"in cn,cn=fe.ajax=!!cn,cn&&pe.ajaxTransport(function(t){if(!t.crossDomain||fe.cors){var n;return{send:function(r,i){var o,a=t.xhr(),s=++un;if(a.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(o in t.xhrFields)a[o]=t.xhrFields[o];t.mimeType&&a.overrideMimeType&&a.overrideMimeType(t.mimeType),t.crossDomain||r[\"X-Requested-With\"]||(r[\"X-Requested-With\"]=\"XMLHttpRequest\");for(o in r)void 0!==r[o]&&a.setRequestHeader(o,r[o]+\"\");a.send(t.hasContent&&t.data||null),n=function(e,r){var o,u,l;if(n&&(r||4===a.readyState))if(delete ln[s],n=void 0,a.onreadystatechange=pe.noop,r)4!==a.readyState&&a.abort();else{l={},o=a.status,\"string\"==typeof a.responseText&&(l.text=a.responseText);try{u=a.statusText}catch(c){u=\"\"}o||!t.isLocal||t.crossDomain?1223===o&&(o=204):o=l.text?200:404}l&&i(o,u,l,a.getAllResponseHeaders())},t.async?4===a.readyState?e.setTimeout(n):a.onreadystatechange=ln[s]=n:n()},abort:function(){n&&n(void 0,!0)}}}}),pe.ajaxSetup({accepts:{script:\"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"},contents:{script:/\\b(?:java|ecma)script\\b/},converters:{\"text script\":function(e){return pe.globalEval(e),e}}}),pe.ajaxPrefilter(\"script\",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type=\"GET\",e.global=!1)}),pe.ajaxTransport(\"script\",function(e){if(e.crossDomain){var t,n=re.head||pe(\"head\")[0]||re.documentElement;return{send:function(r,i){t=re.createElement(\"script\"),t.async=!0,e.scriptCharset&&(t.charset=e.scriptCharset),t.src=e.url,t.onload=t.onreadystatechange=function(e,n){(n||!t.readyState||/loaded|complete/.test(t.readyState))&&(t.onload=t.onreadystatechange=null,t.parentNode&&t.parentNode.removeChild(t),t=null,n||i(200,\"success\"))},n.insertBefore(t,n.firstChild)},abort:function(){t&&t.onload(void 0,!0)}}}});var fn=[],dn=/(=)\\?(?=&|$)|\\?\\?/;pe.ajaxSetup({jsonp:\"callback\",jsonpCallback:function(){var e=fn.pop()||pe.expando+\"_\"+Wt++;return this[e]=!0,e}}),pe.ajaxPrefilter(\"json jsonp\",function(t,n,r){var i,o,a,s=t.jsonp!==!1&&(dn.test(t.url)?\"url\":\"string\"==typeof t.data&&0===(t.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&dn.test(t.data)&&\"data\");if(s||\"jsonp\"===t.dataTypes[0])return i=t.jsonpCallback=pe.isFunction(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,s?t[s]=t[s].replace(dn,\"$1\"+i):t.jsonp!==!1&&(t.url+=(It.test(t.url)?\"&\":\"?\")+t.jsonp+\"=\"+i),t.converters[\"script json\"]=function(){return a||pe.error(i+\" was not called\"),a[0]},t.dataTypes[0]=\"json\",o=e[i],e[i]=function(){a=arguments},r.always(function(){void 0===o?pe(e).removeProp(i):e[i]=o,t[i]&&(t.jsonpCallback=n.jsonpCallback,fn.push(i)),a&&pe.isFunction(o)&&o(a[0]),a=o=void 0}),\"script\"}),pe.parseHTML=function(e,t,n){if(!e||\"string\"!=typeof e)return null;\"boolean\"==typeof t&&(n=t,t=!1),t=t||re;var r=Te.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=y([e],t,i),i&&i.length&&pe(i).remove(),pe.merge([],r.childNodes))};var pn=pe.fn.load;return pe.fn.load=function(e,t,n){if(\"string\"!=typeof e&&pn)return pn.apply(this,arguments);var r,i,o,a=this,s=e.indexOf(\" \");return s>-1&&(r=pe.trim(e.slice(s,e.length)),e=e.slice(0,s)),pe.isFunction(t)?(n=t,t=void 0):t&&\"object\"==typeof t&&(i=\"POST\"),a.length>0&&pe.ajax({url:e,type:i||\"GET\",dataType:\"html\",data:t}).done(function(e){o=arguments,a.html(r?pe(\"<div>\").append(pe.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},pe.each([\"ajaxStart\",\"ajaxStop\",\"ajaxComplete\",\"ajaxError\",\"ajaxSuccess\",\"ajaxSend\"],function(e,t){pe.fn[t]=function(e){return this.on(t,e)}}),pe.expr.filters.animated=function(e){return pe.grep(pe.timers,function(t){return e===t.elem}).length},pe.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l,c=pe.css(e,\"position\"),f=pe(e),d={};\"static\"===c&&(e.style.position=\"relative\"),s=f.offset(),o=pe.css(e,\"top\"),u=pe.css(e,\"left\"),l=(\"absolute\"===c||\"fixed\"===c)&&pe.inArray(\"auto\",[o,u])>-1,l?(r=f.position(),a=r.top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),pe.isFunction(t)&&(t=t.call(e,n,pe.extend({},s))),null!=t.top&&(d.top=t.top-s.top+a),null!=t.left&&(d.left=t.left-s.left+i),\"using\"in t?t.using.call(e,d):f.css(d)}},pe.fn.extend({offset:function(e){if(arguments.length)return void 0===e?this:this.each(function(t){pe.offset.setOffset(this,e,t)});var t,n,r={top:0,left:0},i=this[0],o=i&&i.ownerDocument;if(o)return t=o.documentElement,pe.contains(t,i)?(\"undefined\"!=typeof i.getBoundingClientRect&&(r=i.getBoundingClientRect()),n=te(o),{top:r.top+(n.pageYOffset||t.scrollTop)-(t.clientTop||0),left:r.left+(n.pageXOffset||t.scrollLeft)-(t.clientLeft||0)}):r},position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return\"fixed\"===pe.css(r,\"position\")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),pe.nodeName(e[0],\"html\")||(n=e.offset()),n.top+=pe.css(e[0],\"borderTopWidth\",!0),n.left+=pe.css(e[0],\"borderLeftWidth\",!0)),{top:t.top-n.top-pe.css(r,\"marginTop\",!0),left:t.left-n.left-pe.css(r,\"marginLeft\",!0)}}},offsetParent:function(){return this.map(function(){\nfor(var e=this.offsetParent;e&&!pe.nodeName(e,\"html\")&&\"static\"===pe.css(e,\"position\");)e=e.offsetParent;return e||pt})}}),pe.each({scrollLeft:\"pageXOffset\",scrollTop:\"pageYOffset\"},function(e,t){var n=/Y/.test(t);pe.fn[e]=function(r){return Pe(this,function(e,r,i){var o=te(e);return void 0===i?o?t in o?o[t]:o.document.documentElement[r]:e[r]:void(o?o.scrollTo(n?pe(o).scrollLeft():i,n?i:pe(o).scrollTop()):e[r]=i)},e,r,arguments.length,null)}}),pe.each([\"top\",\"left\"],function(e,t){pe.cssHooks[t]=L(fe.pixelPosition,function(e,n){if(n)return n=gt(e,t),ft.test(n)?pe(e).position()[t]+\"px\":n})}),pe.each({Height:\"height\",Width:\"width\"},function(e,t){pe.each({padding:\"inner\"+e,content:t,\"\":\"outer\"+e},function(n,r){pe.fn[r]=function(r,i){var o=arguments.length&&(n||\"boolean\"!=typeof r),a=n||(r===!0||i===!0?\"margin\":\"border\");return Pe(this,function(t,n,r){var i;return pe.isWindow(t)?t.document.documentElement[\"client\"+e]:9===t.nodeType?(i=t.documentElement,Math.max(t.body[\"scroll\"+e],i[\"scroll\"+e],t.body[\"offset\"+e],i[\"offset\"+e],i[\"client\"+e])):void 0===r?pe.css(t,n,a):pe.style(t,n,r,a)},t,o?r:void 0,o,null)}})}),pe.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,\"**\"):this.off(t,e||\"**\",n)}}),pe.fn.size=function(){return this.length},pe.fn.andSelf=pe.fn.addBack,layui.define(function(e){layui.$=pe,e(\"jquery\",pe)}),pe});"
  },
  {
    "path": "public/layui/lay/modules/laydate.js",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n ;!function(){\"use strict\";var e=window.layui&&layui.define,t={getPath:function(){var e=document.currentScript?document.currentScript.src:function(){for(var e,t=document.scripts,n=t.length-1,a=n;a>0;a--)if(\"interactive\"===t[a].readyState){e=t[a].src;break}return e||t[n].src}();return e.substring(0,e.lastIndexOf(\"/\")+1)}(),getStyle:function(e,t){var n=e.currentStyle?e.currentStyle:window.getComputedStyle(e,null);return n[n.getPropertyValue?\"getPropertyValue\":\"getAttribute\"](t)},link:function(e,a,i){if(n.path){var r=document.getElementsByTagName(\"head\")[0],o=document.createElement(\"link\");\"string\"==typeof a&&(i=a);var s=(i||e).replace(/\\.|\\//g,\"\"),l=\"layuicss-\"+s,d=0;o.rel=\"stylesheet\",o.href=n.path+e,o.id=l,document.getElementById(l)||r.appendChild(o),\"function\"==typeof a&&!function c(){return++d>80?window.console&&console.error(\"laydate.css: Invalid\"):void(1989===parseInt(t.getStyle(document.getElementById(l),\"width\"))?a():setTimeout(c,100))}()}}},n={v:\"5.0.9\",config:{},index:window.laydate&&window.laydate.v?1e5:0,path:t.getPath,set:function(e){var t=this;return t.config=w.extend({},t.config,e),t},ready:function(a){var i=\"laydate\",r=\"\",o=(e?\"modules/laydate/\":\"theme/\")+\"default/laydate.css?v=\"+n.v+r;return e?layui.addcss(o,a,i):t.link(o,a,i),this}},a=function(){var e=this;return{hint:function(t){e.hint.call(e,t)},config:e.config}},i=\"laydate\",r=\".layui-laydate\",o=\"layui-this\",s=\"laydate-disabled\",l=\"开始日期超出了结束日期<br>建议重新选择\",d=[100,2e5],c=\"layui-laydate-static\",m=\"layui-laydate-list\",u=\"laydate-selected\",h=\"layui-laydate-hint\",y=\"laydate-day-prev\",f=\"laydate-day-next\",p=\"layui-laydate-footer\",g=\".laydate-btns-confirm\",v=\"laydate-time-text\",D=\".laydate-btns-time\",T=function(e){var t=this;t.index=++n.index,t.config=w.extend({},t.config,n.config,e),n.ready(function(){t.init()})},w=function(e){return new C(e)},C=function(e){for(var t=0,n=\"object\"==typeof e?[e]:(this.selector=e,document.querySelectorAll(e||null));t<n.length;t++)this.push(n[t])};C.prototype=[],C.prototype.constructor=C,w.extend=function(){var e=1,t=arguments,n=function(e,t){e=e||(t.constructor===Array?[]:{});for(var a in t)e[a]=t[a]&&t[a].constructor===Object?n(e[a],t[a]):t[a];return e};for(t[0]=\"object\"==typeof t[0]?t[0]:{};e<t.length;e++)\"object\"==typeof t[e]&&n(t[0],t[e]);return t[0]},w.ie=function(){var e=navigator.userAgent.toLowerCase();return!!(window.ActiveXObject||\"ActiveXObject\"in window)&&((e.match(/msie\\s(\\d+)/)||[])[1]||\"11\")}(),w.stope=function(e){e=e||window.event,e.stopPropagation?e.stopPropagation():e.cancelBubble=!0},w.each=function(e,t){var n,a=this;if(\"function\"!=typeof t)return a;if(e=e||[],e.constructor===Object){for(n in e)if(t.call(e[n],n,e[n]))break}else for(n=0;n<e.length&&!t.call(e[n],n,e[n]);n++);return a},w.digit=function(e,t,n){var a=\"\";e=String(e),t=t||2;for(var i=e.length;i<t;i++)a+=\"0\";return e<Math.pow(10,t)?a+(0|e):e},w.elem=function(e,t){var n=document.createElement(e);return w.each(t||{},function(e,t){n.setAttribute(e,t)}),n},C.addStr=function(e,t){return e=e.replace(/\\s+/,\" \"),t=t.replace(/\\s+/,\" \").split(\" \"),w.each(t,function(t,n){new RegExp(\"\\\\b\"+n+\"\\\\b\").test(e)||(e=e+\" \"+n)}),e.replace(/^\\s|\\s$/,\"\")},C.removeStr=function(e,t){return e=e.replace(/\\s+/,\" \"),t=t.replace(/\\s+/,\" \").split(\" \"),w.each(t,function(t,n){var a=new RegExp(\"\\\\b\"+n+\"\\\\b\");a.test(e)&&(e=e.replace(a,\"\"))}),e.replace(/\\s+/,\" \").replace(/^\\s|\\s$/,\"\")},C.prototype.find=function(e){var t=this,n=0,a=[],i=\"object\"==typeof e;return this.each(function(r,o){for(var s=i?[e]:o.querySelectorAll(e||null);n<s.length;n++)a.push(s[n]);t.shift()}),i||(t.selector=(t.selector?t.selector+\" \":\"\")+e),w.each(a,function(e,n){t.push(n)}),t},C.prototype.each=function(e){return w.each.call(this,this,e)},C.prototype.addClass=function(e,t){return this.each(function(n,a){a.className=C[t?\"removeStr\":\"addStr\"](a.className,e)})},C.prototype.removeClass=function(e){return this.addClass(e,!0)},C.prototype.hasClass=function(e){var t=!1;return this.each(function(n,a){new RegExp(\"\\\\b\"+e+\"\\\\b\").test(a.className)&&(t=!0)}),t},C.prototype.attr=function(e,t){var n=this;return void 0===t?function(){if(n.length>0)return n[0].getAttribute(e)}():n.each(function(n,a){a.setAttribute(e,t)})},C.prototype.removeAttr=function(e){return this.each(function(t,n){n.removeAttribute(e)})},C.prototype.html=function(e){return this.each(function(t,n){n.innerHTML=e})},C.prototype.val=function(e){return this.each(function(t,n){n.value=e})},C.prototype.append=function(e){return this.each(function(t,n){\"object\"==typeof e?n.appendChild(e):n.innerHTML=n.innerHTML+e})},C.prototype.remove=function(e){return this.each(function(t,n){e?n.removeChild(e):n.parentNode.removeChild(n)})},C.prototype.on=function(e,t){return this.each(function(n,a){a.attachEvent?a.attachEvent(\"on\"+e,function(e){e.target=e.srcElement,t.call(a,e)}):a.addEventListener(e,t,!1)})},C.prototype.off=function(e,t){return this.each(function(n,a){a.detachEvent?a.detachEvent(\"on\"+e,t):a.removeEventListener(e,t,!1)})},T.isLeapYear=function(e){return e%4===0&&e%100!==0||e%400===0},T.prototype.config={type:\"date\",range:!1,format:\"yyyy-MM-dd\",value:null,isInitValue:!0,min:\"1900-1-1\",max:\"2099-12-31\",trigger:\"focus\",show:!1,showBottom:!0,btns:[\"clear\",\"now\",\"confirm\"],lang:\"cn\",theme:\"default\",position:null,calendar:!1,mark:{},zIndex:null,done:null,change:null},T.prototype.lang=function(){var e=this,t=e.config,n={cn:{weeks:[\"日\",\"一\",\"二\",\"三\",\"四\",\"五\",\"六\"],time:[\"时\",\"分\",\"秒\"],timeTips:\"选择时间\",startTime:\"开始时间\",endTime:\"结束时间\",dateTips:\"返回日期\",month:[\"一\",\"二\",\"三\",\"四\",\"五\",\"六\",\"七\",\"八\",\"九\",\"十\",\"十一\",\"十二\"],tools:{confirm:\"确定\",clear:\"清空\",now:\"现在\"}},en:{weeks:[\"Su\",\"Mo\",\"Tu\",\"We\",\"Th\",\"Fr\",\"Sa\"],time:[\"Hours\",\"Minutes\",\"Seconds\"],timeTips:\"Select Time\",startTime:\"Start Time\",endTime:\"End Time\",dateTips:\"Select Date\",month:[\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"],tools:{confirm:\"Confirm\",clear:\"Clear\",now:\"Now\"}}};return n[t.lang]||n.cn},T.prototype.init=function(){var e=this,t=e.config,n=\"yyyy|y|MM|M|dd|d|HH|H|mm|m|ss|s\",a=\"static\"===t.position,i={year:\"yyyy\",month:\"yyyy-MM\",date:\"yyyy-MM-dd\",time:\"HH:mm:ss\",datetime:\"yyyy-MM-dd HH:mm:ss\"};t.elem=w(t.elem),t.eventElem=w(t.eventElem),t.elem[0]&&(t.range===!0&&(t.range=\"-\"),t.format===i.date&&(t.format=i[t.type]),e.format=t.format.match(new RegExp(n+\"|.\",\"g\"))||[],e.EXP_IF=\"\",e.EXP_SPLIT=\"\",w.each(e.format,function(t,a){var i=new RegExp(n).test(a)?\"\\\\d{\"+function(){return new RegExp(n).test(e.format[0===t?t+1:t-1]||\"\")?/^yyyy|y$/.test(a)?4:a.length:/^yyyy$/.test(a)?\"1,4\":/^y$/.test(a)?\"1,308\":\"1,2\"}()+\"}\":\"\\\\\"+a;e.EXP_IF=e.EXP_IF+i,e.EXP_SPLIT=e.EXP_SPLIT+\"(\"+i+\")\"}),e.EXP_IF=new RegExp(\"^\"+(t.range?e.EXP_IF+\"\\\\s\\\\\"+t.range+\"\\\\s\"+e.EXP_IF:e.EXP_IF)+\"$\"),e.EXP_SPLIT=new RegExp(\"^\"+e.EXP_SPLIT+\"$\",\"\"),e.isInput(t.elem[0])||\"focus\"===t.trigger&&(t.trigger=\"click\"),t.elem.attr(\"lay-key\")||(t.elem.attr(\"lay-key\",e.index),t.eventElem.attr(\"lay-key\",e.index)),t.mark=w.extend({},t.calendar&&\"cn\"===t.lang?{\"0-1-1\":\"元旦\",\"0-2-14\":\"情人\",\"0-3-8\":\"妇女\",\"0-3-12\":\"植树\",\"0-4-1\":\"愚人\",\"0-5-1\":\"劳动\",\"0-5-4\":\"青年\",\"0-6-1\":\"儿童\",\"0-9-10\":\"教师\",\"0-9-18\":\"国耻\",\"0-10-1\":\"国庆\",\"0-12-25\":\"圣诞\"}:{},t.mark),w.each([\"min\",\"max\"],function(e,n){var a=[],i=[];if(\"number\"==typeof t[n]){var r=t[n],o=(new Date).getTime(),s=864e5,l=new Date(r?r<s?o+r*s:r:o);a=[l.getFullYear(),l.getMonth()+1,l.getDate()],r<s||(i=[l.getHours(),l.getMinutes(),l.getSeconds()])}else a=(t[n].match(/\\d+-\\d+-\\d+/)||[\"\"])[0].split(\"-\"),i=(t[n].match(/\\d+:\\d+:\\d+/)||[\"\"])[0].split(\":\");t[n]={year:0|a[0]||(new Date).getFullYear(),month:a[1]?(0|a[1])-1:(new Date).getMonth(),date:0|a[2]||(new Date).getDate(),hours:0|i[0],minutes:0|i[1],seconds:0|i[2]}}),e.elemID=\"layui-laydate\"+t.elem.attr(\"lay-key\"),(t.show||a)&&e.render(),a||e.events(),t.value&&t.isInitValue&&(t.value.constructor===Date?e.setValue(e.parse(0,e.systemDate(t.value))):e.setValue(t.value)))},T.prototype.render=function(){var e=this,t=e.config,n=e.lang(),a=\"static\"===t.position,i=e.elem=w.elem(\"div\",{id:e.elemID,\"class\":[\"layui-laydate\",t.range?\" layui-laydate-range\":\"\",a?\" \"+c:\"\",t.theme&&\"default\"!==t.theme&&!/^#/.test(t.theme)?\" laydate-theme-\"+t.theme:\"\"].join(\"\")}),r=e.elemMain=[],o=e.elemHeader=[],s=e.elemCont=[],l=e.table=[],d=e.footer=w.elem(\"div\",{\"class\":p});if(t.zIndex&&(i.style.zIndex=t.zIndex),w.each(new Array(2),function(e){if(!t.range&&e>0)return!0;var a=w.elem(\"div\",{\"class\":\"layui-laydate-header\"}),i=[function(){var e=w.elem(\"i\",{\"class\":\"layui-icon laydate-icon laydate-prev-y\"});return e.innerHTML=\"&#xe65a;\",e}(),function(){var e=w.elem(\"i\",{\"class\":\"layui-icon laydate-icon laydate-prev-m\"});return e.innerHTML=\"&#xe603;\",e}(),function(){var e=w.elem(\"div\",{\"class\":\"laydate-set-ym\"}),t=w.elem(\"span\"),n=w.elem(\"span\");return e.appendChild(t),e.appendChild(n),e}(),function(){var e=w.elem(\"i\",{\"class\":\"layui-icon laydate-icon laydate-next-m\"});return e.innerHTML=\"&#xe602;\",e}(),function(){var e=w.elem(\"i\",{\"class\":\"layui-icon laydate-icon laydate-next-y\"});return e.innerHTML=\"&#xe65b;\",e}()],d=w.elem(\"div\",{\"class\":\"layui-laydate-content\"}),c=w.elem(\"table\"),m=w.elem(\"thead\"),u=w.elem(\"tr\");w.each(i,function(e,t){a.appendChild(t)}),m.appendChild(u),w.each(new Array(6),function(e){var t=c.insertRow(0);w.each(new Array(7),function(a){if(0===e){var i=w.elem(\"th\");i.innerHTML=n.weeks[a],u.appendChild(i)}t.insertCell(a)})}),c.insertBefore(m,c.children[0]),d.appendChild(c),r[e]=w.elem(\"div\",{\"class\":\"layui-laydate-main laydate-main-list-\"+e}),r[e].appendChild(a),r[e].appendChild(d),o.push(i),s.push(d),l.push(c)}),w(d).html(function(){var e=[],i=[];return\"datetime\"===t.type&&e.push('<span lay-type=\"datetime\" class=\"laydate-btns-time\">'+n.timeTips+\"</span>\"),w.each(t.btns,function(e,r){var o=n.tools[r]||\"btn\";t.range&&\"now\"===r||(a&&\"clear\"===r&&(o=\"cn\"===t.lang?\"重置\":\"Reset\"),i.push('<span lay-type=\"'+r+'\" class=\"laydate-btns-'+r+'\">'+o+\"</span>\"))}),e.push('<div class=\"laydate-footer-btns\">'+i.join(\"\")+\"</div>\"),e.join(\"\")}()),w.each(r,function(e,t){i.appendChild(t)}),t.showBottom&&i.appendChild(d),/^#/.test(t.theme)){var m=w.elem(\"style\"),u=[\"#{{id}} .layui-laydate-header{background-color:{{theme}};}\",\"#{{id}} .layui-this{background-color:{{theme}} !important;}\"].join(\"\").replace(/{{id}}/g,e.elemID).replace(/{{theme}}/g,t.theme);\"styleSheet\"in m?(m.setAttribute(\"type\",\"text/css\"),m.styleSheet.cssText=u):m.innerHTML=u,w(i).addClass(\"laydate-theme-molv\"),i.appendChild(m)}e.remove(T.thisElemDate),a?t.elem.append(i):(document.body.appendChild(i),e.position()),e.checkDate().calendar(),e.changeEvent(),T.thisElemDate=e.elemID,\"function\"==typeof t.ready&&t.ready(w.extend({},t.dateTime,{month:t.dateTime.month+1}))},T.prototype.remove=function(e){var t=this,n=(t.config,w(\"#\"+(e||t.elemID)));return n.hasClass(c)||t.checkDate(function(){n.remove()}),t},T.prototype.position=function(){var e=this,t=e.config,n=e.bindElem||t.elem[0],a=n.getBoundingClientRect(),i=e.elem.offsetWidth,r=e.elem.offsetHeight,o=function(e){return e=e?\"scrollLeft\":\"scrollTop\",document.body[e]|document.documentElement[e]},s=function(e){return document.documentElement[e?\"clientWidth\":\"clientHeight\"]},l=5,d=a.left,c=a.bottom;d+i+l>s(\"width\")&&(d=s(\"width\")-i-l),c+r+l>s()&&(c=a.top>r?a.top-r:s()-r,c-=2*l),t.position&&(e.elem.style.position=t.position),e.elem.style.left=d+(\"fixed\"===t.position?0:o(1))+\"px\",e.elem.style.top=c+(\"fixed\"===t.position?0:o())+\"px\"},T.prototype.hint=function(e){var t=this,n=(t.config,w.elem(\"div\",{\"class\":h}));n.innerHTML=e||\"\",w(t.elem).find(\".\"+h).remove(),t.elem.appendChild(n),clearTimeout(t.hinTimer),t.hinTimer=setTimeout(function(){w(t.elem).find(\".\"+h).remove()},3e3)},T.prototype.getAsYM=function(e,t,n){return n?t--:t++,t<0&&(t=11,e--),t>11&&(t=0,e++),[e,t]},T.prototype.systemDate=function(e){var t=e||new Date;return{year:t.getFullYear(),month:t.getMonth(),date:t.getDate(),hours:e?e.getHours():0,minutes:e?e.getMinutes():0,seconds:e?e.getSeconds():0}},T.prototype.checkDate=function(e){var t,a,i=this,r=(new Date,i.config),o=r.dateTime=r.dateTime||i.systemDate(),s=i.bindElem||r.elem[0],l=(i.isInput(s)?\"val\":\"html\",i.isInput(s)?s.value:\"static\"===r.position?\"\":s.innerHTML),c=function(e){e.year>d[1]&&(e.year=d[1],a=!0),e.month>11&&(e.month=11,a=!0),e.hours>23&&(e.hours=0,a=!0),e.minutes>59&&(e.minutes=0,e.hours++,a=!0),e.seconds>59&&(e.seconds=0,e.minutes++,a=!0),t=n.getEndDate(e.month+1,e.year),e.date>t&&(e.date=t,a=!0)},m=function(e,t,n){var o=[\"startTime\",\"endTime\"];t=(t.match(i.EXP_SPLIT)||[]).slice(1),n=n||0,r.range&&(i[o[n]]=i[o[n]]||{}),w.each(i.format,function(s,l){var c=parseFloat(t[s]);t[s].length<l.length&&(a=!0),/yyyy|y/.test(l)?(c<d[0]&&(c=d[0],a=!0),e.year=c):/MM|M/.test(l)?(c<1&&(c=1,a=!0),e.month=c-1):/dd|d/.test(l)?(c<1&&(c=1,a=!0),e.date=c):/HH|H/.test(l)?(c<1&&(c=0,a=!0),e.hours=c,r.range&&(i[o[n]].hours=c)):/mm|m/.test(l)?(c<1&&(c=0,a=!0),e.minutes=c,r.range&&(i[o[n]].minutes=c)):/ss|s/.test(l)&&(c<1&&(c=0,a=!0),e.seconds=c,r.range&&(i[o[n]].seconds=c))}),c(e)};return\"limit\"===e?(c(o),i):(l=l||r.value,\"string\"==typeof l&&(l=l.replace(/\\s+/g,\" \").replace(/^\\s|\\s$/g,\"\")),i.startState&&!i.endState&&(delete i.startState,i.endState=!0),\"string\"==typeof l&&l?i.EXP_IF.test(l)?r.range?(l=l.split(\" \"+r.range+\" \"),i.startDate=i.startDate||i.systemDate(),i.endDate=i.endDate||i.systemDate(),r.dateTime=w.extend({},i.startDate),w.each([i.startDate,i.endDate],function(e,t){m(t,l[e],e)})):m(o,l):(i.hint(\"日期格式不合法<br>必须遵循下述格式：<br>\"+(r.range?r.format+\" \"+r.range+\" \"+r.format:r.format)+\"<br>已为你重置\"),a=!0):l&&l.constructor===Date?r.dateTime=i.systemDate(l):(r.dateTime=i.systemDate(),delete i.startState,delete i.endState,delete i.startDate,delete i.endDate,delete i.startTime,delete i.endTime),c(o),a&&l&&i.setValue(r.range?i.endDate?i.parse():\"\":i.parse()),e&&e(),i)},T.prototype.mark=function(e,t){var n,a=this,i=a.config;return w.each(i.mark,function(e,a){var i=e.split(\"-\");i[0]!=t[0]&&0!=i[0]||i[1]!=t[1]&&0!=i[1]||i[2]!=t[2]||(n=a||t[2])}),n&&e.html('<span class=\"laydate-day-mark\">'+n+\"</span>\"),a},T.prototype.limit=function(e,t,n,a){var i,r=this,o=r.config,l={},d=o[n>41?\"endDate\":\"dateTime\"],c=w.extend({},d,t||{});return w.each({now:c,min:o.min,max:o.max},function(e,t){l[e]=r.newDate(w.extend({year:t.year,month:t.month,date:t.date},function(){var e={};return w.each(a,function(n,a){e[a]=t[a]}),e}())).getTime()}),i=l.now<l.min||l.now>l.max,e&&e[i?\"addClass\":\"removeClass\"](s),i},T.prototype.calendar=function(e){var t,a,i,r=this,s=r.config,l=e||s.dateTime,c=new Date,m=r.lang(),u=\"date\"!==s.type&&\"datetime\"!==s.type,h=e?1:0,y=w(r.table[h]).find(\"td\"),f=w(r.elemHeader[h][2]).find(\"span\");if(l.year<d[0]&&(l.year=d[0],r.hint(\"最低只能支持到公元\"+d[0]+\"年\")),l.year>d[1]&&(l.year=d[1],r.hint(\"最高只能支持到公元\"+d[1]+\"年\")),r.firstDate||(r.firstDate=w.extend({},l)),c.setFullYear(l.year,l.month,1),t=c.getDay(),a=n.getEndDate(l.month||12,l.year),i=n.getEndDate(l.month+1,l.year),w.each(y,function(e,n){var d=[l.year,l.month],c=0;n=w(n),n.removeAttr(\"class\"),e<t?(c=a-t+e,n.addClass(\"laydate-day-prev\"),d=r.getAsYM(l.year,l.month,\"sub\")):e>=t&&e<i+t?(c=e-t,s.range||c+1===l.date&&n.addClass(o)):(c=e-i-t,n.addClass(\"laydate-day-next\"),d=r.getAsYM(l.year,l.month)),d[1]++,d[2]=c+1,n.attr(\"lay-ymd\",d.join(\"-\")).html(d[2]),r.mark(n,d).limit(n,{year:d[0],month:d[1]-1,date:d[2]},e)}),w(f[0]).attr(\"lay-ym\",l.year+\"-\"+(l.month+1)),w(f[1]).attr(\"lay-ym\",l.year+\"-\"+(l.month+1)),\"cn\"===s.lang?(w(f[0]).attr(\"lay-type\",\"year\").html(l.year+\"年\"),w(f[1]).attr(\"lay-type\",\"month\").html(l.month+1+\"月\")):(w(f[0]).attr(\"lay-type\",\"month\").html(m.month[l.month]),w(f[1]).attr(\"lay-type\",\"year\").html(l.year)),u&&(s.range&&(e?r.endDate=r.endDate||{year:l.year+(\"year\"===s.type?1:0),month:l.month+(\"month\"===s.type?0:-1)}:r.startDate=r.startDate||{year:l.year,month:l.month},e&&(r.listYM=[[r.startDate.year,r.startDate.month+1],[r.endDate.year,r.endDate.month+1]],r.list(s.type,0).list(s.type,1),\"time\"===s.type?r.setBtnStatus(\"时间\",w.extend({},r.systemDate(),r.startTime),w.extend({},r.systemDate(),r.endTime)):r.setBtnStatus(!0))),s.range||(r.listYM=[[l.year,l.month+1]],r.list(s.type,0))),s.range&&!e){var p=r.getAsYM(l.year,l.month);r.calendar(w.extend({},l,{year:p[0],month:p[1]}))}return s.range||r.limit(w(r.footer).find(g),null,0,[\"hours\",\"minutes\",\"seconds\"]),s.range&&e&&!u&&r.stampRange(),r},T.prototype.list=function(e,t){var n=this,a=n.config,i=a.dateTime,r=n.lang(),l=a.range&&\"date\"!==a.type&&\"datetime\"!==a.type,d=w.elem(\"ul\",{\"class\":m+\" \"+{year:\"laydate-year-list\",month:\"laydate-month-list\",time:\"laydate-time-list\"}[e]}),c=n.elemHeader[t],u=w(c[2]).find(\"span\"),h=n.elemCont[t||0],y=w(h).find(\".\"+m)[0],f=\"cn\"===a.lang,p=f?\"年\":\"\",T=n.listYM[t]||{},C=[\"hours\",\"minutes\",\"seconds\"],x=[\"startTime\",\"endTime\"][t];if(T[0]<1&&(T[0]=1),\"year\"===e){var M,b=M=T[0]-7;b<1&&(b=M=1),w.each(new Array(15),function(e){var i=w.elem(\"li\",{\"lay-ym\":M}),r={year:M};M==T[0]&&w(i).addClass(o),i.innerHTML=M+p,d.appendChild(i),M<n.firstDate.year?(r.month=a.min.month,r.date=a.min.date):M>=n.firstDate.year&&(r.month=a.max.month,r.date=a.max.date),n.limit(w(i),r,t),M++}),w(u[f?0:1]).attr(\"lay-ym\",M-8+\"-\"+T[1]).html(b+p+\" - \"+(M-1+p))}else if(\"month\"===e)w.each(new Array(12),function(e){var i=w.elem(\"li\",{\"lay-ym\":e}),s={year:T[0],month:e};e+1==T[1]&&w(i).addClass(o),i.innerHTML=r.month[e]+(f?\"月\":\"\"),d.appendChild(i),T[0]<n.firstDate.year?s.date=a.min.date:T[0]>=n.firstDate.year&&(s.date=a.max.date),n.limit(w(i),s,t)}),w(u[f?0:1]).attr(\"lay-ym\",T[0]+\"-\"+T[1]).html(T[0]+p);else if(\"time\"===e){var E=function(){w(d).find(\"ol\").each(function(e,a){w(a).find(\"li\").each(function(a,i){n.limit(w(i),[{hours:a},{hours:n[x].hours,minutes:a},{hours:n[x].hours,minutes:n[x].minutes,seconds:a}][e],t,[[\"hours\"],[\"hours\",\"minutes\"],[\"hours\",\"minutes\",\"seconds\"]][e])})}),a.range||n.limit(w(n.footer).find(g),n[x],0,[\"hours\",\"minutes\",\"seconds\"])};a.range?n[x]||(n[x]={hours:0,minutes:0,seconds:0}):n[x]=i,w.each([24,60,60],function(e,t){var a=w.elem(\"li\"),i=[\"<p>\"+r.time[e]+\"</p><ol>\"];w.each(new Array(t),function(t){i.push(\"<li\"+(n[x][C[e]]===t?' class=\"'+o+'\"':\"\")+\">\"+w.digit(t,2)+\"</li>\")}),a.innerHTML=i.join(\"\")+\"</ol>\",d.appendChild(a)}),E()}if(y&&h.removeChild(y),h.appendChild(d),\"year\"===e||\"month\"===e)w(n.elemMain[t]).addClass(\"laydate-ym-show\"),w(d).find(\"li\").on(\"click\",function(){var r=0|w(this).attr(\"lay-ym\");if(!w(this).hasClass(s)){if(0===t)i[e]=r,l&&(n.startDate[e]=r),n.limit(w(n.footer).find(g),null,0);else if(l)n.endDate[e]=r;else{var c=\"year\"===e?n.getAsYM(r,T[1]-1,\"sub\"):n.getAsYM(T[0],r,\"sub\");w.extend(i,{year:c[0],month:c[1]})}\"year\"===a.type||\"month\"===a.type?(w(d).find(\".\"+o).removeClass(o),w(this).addClass(o),\"month\"===a.type&&\"year\"===e&&(n.listYM[t][0]=r,l&&(n[[\"startDate\",\"endDate\"][t]].year=r),n.list(\"month\",t))):(n.checkDate(\"limit\").calendar(),n.closeList()),n.setBtnStatus(),a.range||n.done(null,\"change\"),w(n.footer).find(D).removeClass(s)}});else{var S=w.elem(\"span\",{\"class\":v}),k=function(){w(d).find(\"ol\").each(function(e){var t=this,a=w(t).find(\"li\");t.scrollTop=30*(n[x][C[e]]-2),t.scrollTop<=0&&a.each(function(e,n){if(!w(this).hasClass(s))return t.scrollTop=30*(e-2),!0})})},H=w(c[2]).find(\".\"+v);k(),S.innerHTML=a.range?[r.startTime,r.endTime][t]:r.timeTips,w(n.elemMain[t]).addClass(\"laydate-time-show\"),H[0]&&H.remove(),c[2].appendChild(S),w(d).find(\"ol\").each(function(e){var t=this;w(t).find(\"li\").on(\"click\",function(){var r=0|this.innerHTML;w(this).hasClass(s)||(a.range?n[x][C[e]]=r:i[C[e]]=r,w(t).find(\".\"+o).removeClass(o),w(this).addClass(o),E(),k(),(n.endDate||\"time\"===a.type)&&n.done(null,\"change\"),n.setBtnStatus())})})}return n},T.prototype.listYM=[],T.prototype.closeList=function(){var e=this;e.config;w.each(e.elemCont,function(t,n){w(this).find(\".\"+m).remove(),w(e.elemMain[t]).removeClass(\"laydate-ym-show laydate-time-show\")}),w(e.elem).find(\".\"+v).remove()},T.prototype.setBtnStatus=function(e,t,n){var a,i=this,r=i.config,o=w(i.footer).find(g),d=r.range&&\"date\"!==r.type&&\"time\"!==r.type;d&&(t=t||i.startDate,n=n||i.endDate,a=i.newDate(t).getTime()>i.newDate(n).getTime(),i.limit(null,t)||i.limit(null,n)?o.addClass(s):o[a?\"addClass\":\"removeClass\"](s),e&&a&&i.hint(\"string\"==typeof e?l.replace(/日期/g,e):l))},T.prototype.parse=function(e,t){var n=this,a=n.config,i=t||(e?w.extend({},n.endDate,n.endTime):a.range?w.extend({},n.startDate,n.startTime):a.dateTime),r=n.format.concat();return w.each(r,function(e,t){/yyyy|y/.test(t)?r[e]=w.digit(i.year,t.length):/MM|M/.test(t)?r[e]=w.digit(i.month+1,t.length):/dd|d/.test(t)?r[e]=w.digit(i.date,t.length):/HH|H/.test(t)?r[e]=w.digit(i.hours,t.length):/mm|m/.test(t)?r[e]=w.digit(i.minutes,t.length):/ss|s/.test(t)&&(r[e]=w.digit(i.seconds,t.length))}),a.range&&!e?r.join(\"\")+\" \"+a.range+\" \"+n.parse(1):r.join(\"\")},T.prototype.newDate=function(e){return e=e||{},new Date(e.year||1,e.month||0,e.date||1,e.hours||0,e.minutes||0,e.seconds||0)},T.prototype.setValue=function(e){var t=this,n=t.config,a=t.bindElem||n.elem[0],i=t.isInput(a)?\"val\":\"html\";return\"static\"===n.position||w(a)[i](e||\"\"),this},T.prototype.stampRange=function(){var e,t,n=this,a=n.config,i=w(n.elem).find(\"td\");if(a.range&&!n.endDate&&w(n.footer).find(g).addClass(s),n.endDate)return e=n.newDate({year:n.startDate.year,month:n.startDate.month,date:n.startDate.date}).getTime(),t=n.newDate({year:n.endDate.year,month:n.endDate.month,date:n.endDate.date}).getTime(),e>t?n.hint(l):void w.each(i,function(a,i){var r=w(i).attr(\"lay-ymd\").split(\"-\"),s=n.newDate({year:r[0],month:r[1]-1,date:r[2]}).getTime();w(i).removeClass(u+\" \"+o),s!==e&&s!==t||w(i).addClass(w(i).hasClass(y)||w(i).hasClass(f)?u:o),s>e&&s<t&&w(i).addClass(u)})},T.prototype.done=function(e,t){var n=this,a=n.config,i=w.extend({},n.startDate?w.extend(n.startDate,n.startTime):a.dateTime),r=w.extend({},w.extend(n.endDate,n.endTime));return w.each([i,r],function(e,t){\"month\"in t&&w.extend(t,{month:t.month+1})}),e=e||[n.parse(),i,r],\"function\"==typeof a[t||\"done\"]&&a[t||\"done\"].apply(a,e),n},T.prototype.choose=function(e){var t=this,n=t.config,a=n.dateTime,i=w(t.elem).find(\"td\"),r=e.attr(\"lay-ymd\").split(\"-\"),l=function(e){new Date;e&&w.extend(a,r),n.range&&(t.startDate?w.extend(t.startDate,r):t.startDate=w.extend({},r,t.startTime),t.startYMD=r)};if(r={year:0|r[0],month:(0|r[1])-1,date:0|r[2]},!e.hasClass(s))if(n.range){if(w.each([\"startTime\",\"endTime\"],function(e,n){t[n]=t[n]||{hours:0,minutes:0,seconds:0}}),t.endState)l(),delete t.endState,delete t.endDate,t.startState=!0,i.removeClass(o+\" \"+u),e.addClass(o);else if(t.startState){if(e.addClass(o),t.endDate?w.extend(t.endDate,r):t.endDate=w.extend({},r,t.endTime),t.newDate(r).getTime()<t.newDate(t.startYMD).getTime()){var d=w.extend({},t.endDate,{hours:t.startDate.hours,minutes:t.startDate.minutes,seconds:t.startDate.seconds});w.extend(t.endDate,t.startDate,{hours:t.endDate.hours,minutes:t.endDate.minutes,seconds:t.endDate.seconds}),t.startDate=d}n.showBottom||t.done(),t.stampRange(),t.endState=!0,t.done(null,\"change\")}else e.addClass(o),l(),t.startState=!0;w(t.footer).find(g)[t.endDate?\"removeClass\":\"addClass\"](s)}else\"static\"===n.position?(l(!0),t.calendar().done().done(null,\"change\")):\"date\"===n.type?(l(!0),t.setValue(t.parse()).remove().done()):\"datetime\"===n.type&&(l(!0),t.calendar().done(null,\"change\"))},T.prototype.tool=function(e,t){var n=this,a=n.config,i=a.dateTime,r=\"static\"===a.position,o={datetime:function(){w(e).hasClass(s)||(n.list(\"time\",0),a.range&&n.list(\"time\",1),w(e).attr(\"lay-type\",\"date\").html(n.lang().dateTips))},date:function(){n.closeList(),w(e).attr(\"lay-type\",\"datetime\").html(n.lang().timeTips)},clear:function(){n.setValue(\"\").remove(),r&&(w.extend(i,n.firstDate),n.calendar()),a.range&&(delete n.startState,delete n.endState,delete n.endDate,delete n.startTime,delete n.endTime),n.done([\"\",{},{}])},now:function(){var e=new Date;w.extend(i,n.systemDate(),{hours:e.getHours(),minutes:e.getMinutes(),seconds:e.getSeconds()}),n.setValue(n.parse()).remove(),r&&n.calendar(),n.done()},confirm:function(){if(a.range){if(!n.endDate)return n.hint(\"请先选择日期范围\");if(w(e).hasClass(s))return n.hint(\"time\"===a.type?l.replace(/日期/g,\"时间\"):l)}else if(w(e).hasClass(s))return n.hint(\"不在有效日期或时间范围内\");n.done(),n.setValue(n.parse()).remove()}};o[t]&&o[t]()},T.prototype.change=function(e){var t=this,n=t.config,a=n.dateTime,i=n.range&&(\"year\"===n.type||\"month\"===n.type),r=t.elemCont[e||0],o=t.listYM[e],s=function(s){var l=[\"startDate\",\"endDate\"][e],d=w(r).find(\".laydate-year-list\")[0],c=w(r).find(\".laydate-month-list\")[0];return d&&(o[0]=s?o[0]-15:o[0]+15,t.list(\"year\",e)),c&&(s?o[0]--:o[0]++,t.list(\"month\",e)),(d||c)&&(w.extend(a,{year:o[0]}),i&&(t[l].year=o[0]),n.range||t.done(null,\"change\"),t.setBtnStatus(),n.range||t.limit(w(t.footer).find(g),{year:o[0]})),d||c};return{prevYear:function(){s(\"sub\")||(a.year--,t.checkDate(\"limit\").calendar(),n.range||t.done(null,\"change\"))},prevMonth:function(){var e=t.getAsYM(a.year,a.month,\"sub\");w.extend(a,{year:e[0],month:e[1]}),t.checkDate(\"limit\").calendar(),n.range||t.done(null,\"change\")},nextMonth:function(){var e=t.getAsYM(a.year,a.month);w.extend(a,{year:e[0],month:e[1]}),t.checkDate(\"limit\").calendar(),n.range||t.done(null,\"change\")},nextYear:function(){s()||(a.year++,t.checkDate(\"limit\").calendar(),n.range||t.done(null,\"change\"))}}},T.prototype.changeEvent=function(){var e=this;e.config;w(e.elem).on(\"click\",function(e){w.stope(e)}),w.each(e.elemHeader,function(t,n){w(n[0]).on(\"click\",function(n){e.change(t).prevYear()}),w(n[1]).on(\"click\",function(n){e.change(t).prevMonth()}),w(n[2]).find(\"span\").on(\"click\",function(n){var a=w(this),i=a.attr(\"lay-ym\"),r=a.attr(\"lay-type\");i&&(i=i.split(\"-\"),e.listYM[t]=[0|i[0],0|i[1]],e.list(r,t),w(e.footer).find(D).addClass(s))}),w(n[3]).on(\"click\",function(n){e.change(t).nextMonth()}),w(n[4]).on(\"click\",function(n){e.change(t).nextYear()})}),w.each(e.table,function(t,n){var a=w(n).find(\"td\");a.on(\"click\",function(){e.choose(w(this))})}),w(e.footer).find(\"span\").on(\"click\",function(){var t=w(this).attr(\"lay-type\");e.tool(this,t)})},T.prototype.isInput=function(e){return/input|textarea/.test(e.tagName.toLocaleLowerCase())},T.prototype.events=function(){var e=this,t=e.config,n=function(n,a){n.on(t.trigger,function(){a&&(e.bindElem=this),e.render()})};t.elem[0]&&!t.elem[0].eventHandler&&(n(t.elem,\"bind\"),n(t.eventElem),w(document).on(\"click\",function(n){n.target!==t.elem[0]&&n.target!==t.eventElem[0]&&n.target!==w(t.closeStop)[0]&&e.remove()}).on(\"keydown\",function(t){13===t.keyCode&&w(\"#\"+e.elemID)[0]&&e.elemID===T.thisElem&&(t.preventDefault(),w(e.footer).find(g)[0].click())}),w(window).on(\"resize\",function(){return!(!e.elem||!w(r)[0])&&void e.position()}),t.elem[0].eventHandler=!0)},n.render=function(e){var t=new T(e);return a.call(t)},n.getEndDate=function(e,t){var n=new Date;return n.setFullYear(t||n.getFullYear(),e||n.getMonth()+1,1),new Date(n.getTime()-864e5).getDate()},window.lay=window.lay||w,e?(n.ready(),layui.define(function(e){n.path=layui.cache.dir,e(i,n)})):\"function\"==typeof define&&define.amd?define(function(){return n}):function(){n.ready(),window.laydate=n}()}();"
  },
  {
    "path": "public/layui/lay/modules/layedit.js",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n ;layui.define([\"layer\",\"form\"],function(t){\"use strict\";var e=layui.$,i=layui.layer,a=layui.form,l=(layui.hint(),layui.device()),n=\"layedit\",o=\"layui-show\",r=\"layui-disabled\",c=function(){var t=this;t.index=0,t.config={tool:[\"strong\",\"italic\",\"underline\",\"del\",\"|\",\"left\",\"center\",\"right\",\"|\",\"link\",\"unlink\",\"face\",\"image\"],hideTool:[],height:280}};c.prototype.set=function(t){var i=this;return e.extend(!0,i.config,t),i},c.prototype.on=function(t,e){return layui.onevent(n,t,e)},c.prototype.build=function(t,i){i=i||{};var a=this,n=a.config,r=\"layui-layedit\",c=e(\"string\"==typeof t?\"#\"+t:t),u=\"LAY_layedit_\"+ ++a.index,d=c.next(\".\"+r),y=e.extend({},n,i),f=function(){var t=[],e={};return layui.each(y.hideTool,function(t,i){e[i]=!0}),layui.each(y.tool,function(i,a){C[a]&&!e[a]&&t.push(C[a])}),t.join(\"\")}(),m=e(['<div class=\"'+r+'\">','<div class=\"layui-unselect layui-layedit-tool\">'+f+\"</div>\",'<div class=\"layui-layedit-iframe\">','<iframe id=\"'+u+'\" name=\"'+u+'\" textarea=\"'+t+'\" frameborder=\"0\"></iframe>',\"</div>\",\"</div>\"].join(\"\"));return l.ie&&l.ie<8?c.removeClass(\"layui-hide\").addClass(o):(d[0]&&d.remove(),s.call(a,m,c[0],y),c.addClass(\"layui-hide\").after(m),a.index)},c.prototype.getContent=function(t){var e=u(t);if(e[0])return d(e[0].document.body.innerHTML)},c.prototype.getText=function(t){var i=u(t);if(i[0])return e(i[0].document.body).text()},c.prototype.setContent=function(t,i,a){var l=u(t);l[0]&&(a?e(l[0].document.body).append(i):e(l[0].document.body).html(i),layedit.sync(t))},c.prototype.sync=function(t){var i=u(t);if(i[0]){var a=e(\"#\"+i[1].attr(\"textarea\"));a.val(d(i[0].document.body.innerHTML))}},c.prototype.getSelection=function(t){var e=u(t);if(e[0]){var i=m(e[0].document);return document.selection?i.text:i.toString()}};var s=function(t,i,a){var l=this,n=t.find(\"iframe\");n.css({height:a.height}).on(\"load\",function(){var o=n.contents(),r=n.prop(\"contentWindow\"),c=o.find(\"head\"),s=e([\"<style>\",\"*{margin: 0; padding: 0;}\",\"body{padding: 10px; line-height: 20px; overflow-x: hidden; word-wrap: break-word; font: 14px Helvetica Neue,Helvetica,PingFang SC,Microsoft YaHei,Tahoma,Arial,sans-serif; -webkit-box-sizing: border-box !important; -moz-box-sizing: border-box !important; box-sizing: border-box !important;}\",\"a{color:#01AAED; text-decoration:none;}a:hover{color:#c00}\",\"p{margin-bottom: 10px;}\",\"img{display: inline-block; border: none; vertical-align: middle;}\",\"pre{margin: 10px 0; padding: 10px; line-height: 20px; border: 1px solid #ddd; border-left-width: 6px; background-color: #F2F2F2; color: #333; font-family: Courier New; font-size: 12px;}\",\"</style>\"].join(\"\")),u=o.find(\"body\");c.append(s),u.attr(\"contenteditable\",\"true\").css({\"min-height\":a.height}).html(i.value||\"\"),y.apply(l,[r,n,i,a]),g.call(l,r,t,a)})},u=function(t){var i=e(\"#LAY_layedit_\"+t),a=i.prop(\"contentWindow\");return[a,i]},d=function(t){return 8==l.ie&&(t=t.replace(/<.+>/g,function(t){return t.toLowerCase()})),t},y=function(t,a,n,o){var r=t.document,c=e(r.body);c.on(\"keydown\",function(t){var e=t.keyCode;if(13===e){var a=m(r),l=p(a),n=l.parentNode;if(\"pre\"===n.tagName.toLowerCase()){if(t.shiftKey)return;return i.msg(\"请暂时用shift+enter\"),!1}r.execCommand(\"formatBlock\",!1,\"<p>\")}}),e(n).parents(\"form\").on(\"submit\",function(){var t=c.html();8==l.ie&&(t=t.replace(/<.+>/g,function(t){return t.toLowerCase()})),n.value=t}),c.on(\"paste\",function(e){r.execCommand(\"formatBlock\",!1,\"<p>\"),setTimeout(function(){f.call(t,c),n.value=c.html()},100)})},f=function(t){var i=this;i.document;t.find(\"*[style]\").each(function(){var t=this.style.textAlign;this.removeAttribute(\"style\"),e(this).css({\"text-align\":t||\"\"})}),t.find(\"table\").addClass(\"layui-table\"),t.find(\"script,link\").remove()},m=function(t){return t.selection?t.selection.createRange():t.getSelection().getRangeAt(0)},p=function(t){return t.endContainer||t.parentElement().childNodes[0]},v=function(t,i,a){var l=this.document,n=document.createElement(t);for(var o in i)n.setAttribute(o,i[o]);if(n.removeAttribute(\"text\"),l.selection){var r=a.text||i.text;if(\"a\"===t&&!r)return;r&&(n.innerHTML=r),a.pasteHTML(e(n).prop(\"outerHTML\")),a.select()}else{var r=a.toString()||i.text;if(\"a\"===t&&!r)return;r&&(n.innerHTML=r),a.deleteContents(),a.insertNode(n)}},h=function(t,i){var a=this.document,l=\"layedit-tool-active\",n=p(m(a)),o=function(e){return t.find(\".layedit-tool-\"+e)};i&&i[i.hasClass(l)?\"removeClass\":\"addClass\"](l),t.find(\">i\").removeClass(l),o(\"unlink\").addClass(r),e(n).parents().each(function(){var t=this.tagName.toLowerCase(),e=this.style.textAlign;\"b\"!==t&&\"strong\"!==t||o(\"b\").addClass(l),\"i\"!==t&&\"em\"!==t||o(\"i\").addClass(l),\"u\"===t&&o(\"u\").addClass(l),\"strike\"===t&&o(\"d\").addClass(l),\"p\"===t&&(\"center\"===e?o(\"center\").addClass(l):\"right\"===e?o(\"right\").addClass(l):o(\"left\").addClass(l)),\"a\"===t&&(o(\"link\").addClass(l),o(\"unlink\").removeClass(r))})},g=function(t,a,l){var n=t.document,o=e(n.body),c={link:function(i){var a=p(i),l=e(a).parent();b.call(o,{href:l.attr(\"href\"),target:l.attr(\"target\")},function(e){var a=l[0];\"A\"===a.tagName?a.href=e.url:v.call(t,\"a\",{target:e.target,href:e.url,text:e.url},i)})},unlink:function(t){n.execCommand(\"unlink\")},face:function(e){x.call(this,function(i){v.call(t,\"img\",{src:i.src,alt:i.alt},e)})},image:function(a){var n=this;layui.use(\"upload\",function(o){var r=l.uploadImage||{};o.render({url:r.url,method:r.type,elem:e(n).find(\"input\")[0],done:function(e){0==e.code?(e.data=e.data||{},v.call(t,\"img\",{src:e.data.src,alt:e.data.title},a)):i.msg(e.msg||\"上传失败\")}})})},code:function(e){k.call(o,function(i){v.call(t,\"pre\",{text:i.code,\"lay-lang\":i.lang},e)})},help:function(){i.open({type:2,title:\"帮助\",area:[\"600px\",\"380px\"],shadeClose:!0,shade:.1,skin:\"layui-layer-msg\",content:[\"http://www.layui.com/about/layedit/help.html\",\"no\"]})}},s=a.find(\".layui-layedit-tool\"),u=function(){var i=e(this),a=i.attr(\"layedit-event\"),l=i.attr(\"lay-command\");if(!i.hasClass(r)){o.focus();var u=m(n);u.commonAncestorContainer;l?(n.execCommand(l),/justifyLeft|justifyCenter|justifyRight/.test(l)&&n.execCommand(\"formatBlock\",!1,\"<p>\"),setTimeout(function(){o.focus()},10)):c[a]&&c[a].call(this,u),h.call(t,s,i)}},d=/image/;s.find(\">i\").on(\"mousedown\",function(){var t=e(this),i=t.attr(\"layedit-event\");d.test(i)||u.call(this)}).on(\"click\",function(){var t=e(this),i=t.attr(\"layedit-event\");d.test(i)&&u.call(this)}),o.on(\"click\",function(){h.call(t,s),i.close(x.index)})},b=function(t,e){var l=this,n=i.open({type:1,id:\"LAY_layedit_link\",area:\"350px\",shade:.05,shadeClose:!0,moveType:1,title:\"超链接\",skin:\"layui-layer-msg\",content:['<ul class=\"layui-form\" style=\"margin: 15px;\">','<li class=\"layui-form-item\">','<label class=\"layui-form-label\" style=\"width: 60px;\">URL</label>','<div class=\"layui-input-block\" style=\"margin-left: 90px\">','<input name=\"url\" lay-verify=\"url\" value=\"'+(t.href||\"\")+'\" autofocus=\"true\" autocomplete=\"off\" class=\"layui-input\">',\"</div>\",\"</li>\",'<li class=\"layui-form-item\">','<label class=\"layui-form-label\" style=\"width: 60px;\">打开方式</label>','<div class=\"layui-input-block\" style=\"margin-left: 90px\">','<input type=\"radio\" name=\"target\" value=\"_self\" class=\"layui-input\" title=\"当前窗口\"'+(\"_self\"!==t.target&&t.target?\"\":\"checked\")+\">\",'<input type=\"radio\" name=\"target\" value=\"_blank\" class=\"layui-input\" title=\"新窗口\" '+(\"_blank\"===t.target?\"checked\":\"\")+\">\",\"</div>\",\"</li>\",'<li class=\"layui-form-item\" style=\"text-align: center;\">','<button type=\"button\" lay-submit lay-filter=\"layedit-link-yes\" class=\"layui-btn\"> 确定 </button>','<button style=\"margin-left: 20px;\" type=\"button\" class=\"layui-btn layui-btn-primary\"> 取消 </button>',\"</li>\",\"</ul>\"].join(\"\"),success:function(t,n){var o=\"submit(layedit-link-yes)\";a.render(\"radio\"),t.find(\".layui-btn-primary\").on(\"click\",function(){i.close(n),l.focus()}),a.on(o,function(t){i.close(b.index),e&&e(t.field)})}});b.index=n},x=function(t){var a=function(){var t=[\"[微笑]\",\"[嘻嘻]\",\"[哈哈]\",\"[可爱]\",\"[可怜]\",\"[挖鼻]\",\"[吃惊]\",\"[害羞]\",\"[挤眼]\",\"[闭嘴]\",\"[鄙视]\",\"[爱你]\",\"[泪]\",\"[偷笑]\",\"[亲亲]\",\"[生病]\",\"[太开心]\",\"[白眼]\",\"[右哼哼]\",\"[左哼哼]\",\"[嘘]\",\"[衰]\",\"[委屈]\",\"[吐]\",\"[哈欠]\",\"[抱抱]\",\"[怒]\",\"[疑问]\",\"[馋嘴]\",\"[拜拜]\",\"[思考]\",\"[汗]\",\"[困]\",\"[睡]\",\"[钱]\",\"[失望]\",\"[酷]\",\"[色]\",\"[哼]\",\"[鼓掌]\",\"[晕]\",\"[悲伤]\",\"[抓狂]\",\"[黑线]\",\"[阴险]\",\"[怒骂]\",\"[互粉]\",\"[心]\",\"[伤心]\",\"[猪头]\",\"[熊猫]\",\"[兔子]\",\"[ok]\",\"[耶]\",\"[good]\",\"[NO]\",\"[赞]\",\"[来]\",\"[弱]\",\"[草泥马]\",\"[神马]\",\"[囧]\",\"[浮云]\",\"[给力]\",\"[围观]\",\"[威武]\",\"[奥特曼]\",\"[礼物]\",\"[钟]\",\"[话筒]\",\"[蜡烛]\",\"[蛋糕]\"],e={};return layui.each(t,function(t,i){e[i]=layui.cache.dir+\"images/face/\"+t+\".gif\"}),e}();return x.hide=x.hide||function(t){\"face\"!==e(t.target).attr(\"layedit-event\")&&i.close(x.index)},x.index=i.tips(function(){var t=[];return layui.each(a,function(e,i){t.push('<li title=\"'+e+'\"><img src=\"'+i+'\" alt=\"'+e+'\"></li>')}),'<ul class=\"layui-clear\">'+t.join(\"\")+\"</ul>\"}(),this,{tips:1,time:0,skin:\"layui-box layui-util-face\",maxWidth:500,success:function(l,n){l.css({marginTop:-4,marginLeft:-10}).find(\".layui-clear>li\").on(\"click\",function(){t&&t({src:a[this.title],alt:this.title}),i.close(n)}),e(document).off(\"click\",x.hide).on(\"click\",x.hide)}})},k=function(t){var e=this,l=i.open({type:1,id:\"LAY_layedit_code\",area:\"550px\",shade:.05,shadeClose:!0,moveType:1,title:\"插入代码\",skin:\"layui-layer-msg\",content:['<ul class=\"layui-form layui-form-pane\" style=\"margin: 15px;\">','<li class=\"layui-form-item\">','<label class=\"layui-form-label\">请选择语言</label>','<div class=\"layui-input-block\">','<select name=\"lang\">','<option value=\"JavaScript\">JavaScript</option>','<option value=\"HTML\">HTML</option>','<option value=\"CSS\">CSS</option>','<option value=\"Java\">Java</option>','<option value=\"PHP\">PHP</option>','<option value=\"C#\">C#</option>','<option value=\"Python\">Python</option>','<option value=\"Ruby\">Ruby</option>','<option value=\"Go\">Go</option>',\"</select>\",\"</div>\",\"</li>\",'<li class=\"layui-form-item layui-form-text\">','<label class=\"layui-form-label\">代码</label>','<div class=\"layui-input-block\">','<textarea name=\"code\" lay-verify=\"required\" autofocus=\"true\" class=\"layui-textarea\" style=\"height: 200px;\"></textarea>',\"</div>\",\"</li>\",'<li class=\"layui-form-item\" style=\"text-align: center;\">','<button type=\"button\" lay-submit lay-filter=\"layedit-code-yes\" class=\"layui-btn\"> 确定 </button>','<button style=\"margin-left: 20px;\" type=\"button\" class=\"layui-btn layui-btn-primary\"> 取消 </button>',\"</li>\",\"</ul>\"].join(\"\"),success:function(l,n){var o=\"submit(layedit-code-yes)\";a.render(\"select\"),l.find(\".layui-btn-primary\").on(\"click\",function(){i.close(n),e.focus()}),a.on(o,function(e){i.close(k.index),t&&t(e.field)})}});k.index=l},C={html:'<i class=\"layui-icon layedit-tool-html\" title=\"HTML源代码\" lay-command=\"html\" layedit-event=\"html\"\">&#xe64b;</i><span class=\"layedit-tool-mid\"></span>',strong:'<i class=\"layui-icon layedit-tool-b\" title=\"加粗\" lay-command=\"Bold\" layedit-event=\"b\"\">&#xe62b;</i>',italic:'<i class=\"layui-icon layedit-tool-i\" title=\"斜体\" lay-command=\"italic\" layedit-event=\"i\"\">&#xe644;</i>',underline:'<i class=\"layui-icon layedit-tool-u\" title=\"下划线\" lay-command=\"underline\" layedit-event=\"u\"\">&#xe646;</i>',del:'<i class=\"layui-icon layedit-tool-d\" title=\"删除线\" lay-command=\"strikeThrough\" layedit-event=\"d\"\">&#xe64f;</i>',\"|\":'<span class=\"layedit-tool-mid\"></span>',left:'<i class=\"layui-icon layedit-tool-left\" title=\"左对齐\" lay-command=\"justifyLeft\" layedit-event=\"left\"\">&#xe649;</i>',center:'<i class=\"layui-icon layedit-tool-center\" title=\"居中对齐\" lay-command=\"justifyCenter\" layedit-event=\"center\"\">&#xe647;</i>',right:'<i class=\"layui-icon layedit-tool-right\" title=\"右对齐\" lay-command=\"justifyRight\" layedit-event=\"right\"\">&#xe648;</i>',link:'<i class=\"layui-icon layedit-tool-link\" title=\"插入链接\" layedit-event=\"link\"\">&#xe64c;</i>',unlink:'<i class=\"layui-icon layedit-tool-unlink layui-disabled\" title=\"清除链接\" lay-command=\"unlink\" layedit-event=\"unlink\"\">&#xe64d;</i>',face:'<i class=\"layui-icon layedit-tool-face\" title=\"表情\" layedit-event=\"face\"\">&#xe650;</i>',image:'<i class=\"layui-icon layedit-tool-image\" title=\"图片\" layedit-event=\"image\">&#xe64a;<input type=\"file\" name=\"file\"></i>',code:'<i class=\"layui-icon layedit-tool-code\" title=\"插入代码\" layedit-event=\"code\">&#xe64e;</i>',help:'<i class=\"layui-icon layedit-tool-help\" title=\"帮助\" layedit-event=\"help\">&#xe607;</i>'},w=new c;t(n,w)});"
  },
  {
    "path": "public/layui/lay/modules/layer.js",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n ;!function(e,t){\"use strict\";var i,n,a=e.layui&&layui.define,o={getPath:function(){var e=document.currentScript?document.currentScript.src:function(){for(var e,t=document.scripts,i=t.length-1,n=i;n>0;n--)if(\"interactive\"===t[n].readyState){e=t[n].src;break}return e||t[i].src}();return e.substring(0,e.lastIndexOf(\"/\")+1)}(),config:{},end:{},minIndex:0,minLeft:[],btn:[\"&#x786E;&#x5B9A;\",\"&#x53D6;&#x6D88;\"],type:[\"dialog\",\"page\",\"iframe\",\"loading\",\"tips\"],getStyle:function(t,i){var n=t.currentStyle?t.currentStyle:e.getComputedStyle(t,null);return n[n.getPropertyValue?\"getPropertyValue\":\"getAttribute\"](i)},link:function(t,i,n){if(r.path){var a=document.getElementsByTagName(\"head\")[0],s=document.createElement(\"link\");\"string\"==typeof i&&(n=i);var l=(n||t).replace(/\\.|\\//g,\"\"),f=\"layuicss-\"+l,c=0;s.rel=\"stylesheet\",s.href=r.path+t,s.id=f,document.getElementById(f)||a.appendChild(s),\"function\"==typeof i&&!function u(){return++c>80?e.console&&console.error(\"layer.css: Invalid\"):void(1989===parseInt(o.getStyle(document.getElementById(f),\"width\"))?i():setTimeout(u,100))}()}}},r={v:\"3.1.1\",ie:function(){var t=navigator.userAgent.toLowerCase();return!!(e.ActiveXObject||\"ActiveXObject\"in e)&&((t.match(/msie\\s(\\d+)/)||[])[1]||\"11\")}(),index:e.layer&&e.layer.v?1e5:0,path:o.getPath,config:function(e,t){return e=e||{},r.cache=o.config=i.extend({},o.config,e),r.path=o.config.path||r.path,\"string\"==typeof e.extend&&(e.extend=[e.extend]),o.config.path&&r.ready(),e.extend?(a?layui.addcss(\"modules/layer/\"+e.extend):o.link(\"theme/\"+e.extend),this):this},ready:function(e){var t=\"layer\",i=\"\",n=(a?\"modules/layer/\":\"theme/\")+\"default/layer.css?v=\"+r.v+i;return a?layui.addcss(n,e,t):o.link(n,e,t),this},alert:function(e,t,n){var a=\"function\"==typeof t;return a&&(n=t),r.open(i.extend({content:e,yes:n},a?{}:t))},confirm:function(e,t,n,a){var s=\"function\"==typeof t;return s&&(a=n,n=t),r.open(i.extend({content:e,btn:o.btn,yes:n,btn2:a},s?{}:t))},msg:function(e,n,a){var s=\"function\"==typeof n,f=o.config.skin,c=(f?f+\" \"+f+\"-msg\":\"\")||\"layui-layer-msg\",u=l.anim.length-1;return s&&(a=n),r.open(i.extend({content:e,time:3e3,shade:!1,skin:c,title:!1,closeBtn:!1,btn:!1,resize:!1,end:a},s&&!o.config.skin?{skin:c+\" layui-layer-hui\",anim:u}:function(){return n=n||{},(n.icon===-1||n.icon===t&&!o.config.skin)&&(n.skin=c+\" \"+(n.skin||\"layui-layer-hui\")),n}()))},load:function(e,t){return r.open(i.extend({type:3,icon:e||0,resize:!1,shade:.01},t))},tips:function(e,t,n){return r.open(i.extend({type:4,content:[e,t],closeBtn:!1,time:3e3,shade:!1,resize:!1,fixed:!1,maxWidth:210},n))}},s=function(e){var t=this;t.index=++r.index,t.config=i.extend({},t.config,o.config,e),document.body?t.creat():setTimeout(function(){t.creat()},30)};s.pt=s.prototype;var l=[\"layui-layer\",\".layui-layer-title\",\".layui-layer-main\",\".layui-layer-dialog\",\"layui-layer-iframe\",\"layui-layer-content\",\"layui-layer-btn\",\"layui-layer-close\"];l.anim=[\"layer-anim-00\",\"layer-anim-01\",\"layer-anim-02\",\"layer-anim-03\",\"layer-anim-04\",\"layer-anim-05\",\"layer-anim-06\"],s.pt.config={type:0,shade:.3,fixed:!0,move:l[1],title:\"&#x4FE1;&#x606F;\",offset:\"auto\",area:\"auto\",closeBtn:1,time:0,zIndex:19891014,maxWidth:360,anim:0,isOutAnim:!0,icon:-1,moveType:1,resize:!0,scrollbar:!0,tips:2},s.pt.vessel=function(e,t){var n=this,a=n.index,r=n.config,s=r.zIndex+a,f=\"object\"==typeof r.title,c=r.maxmin&&(1===r.type||2===r.type),u=r.title?'<div class=\"layui-layer-title\" style=\"'+(f?r.title[1]:\"\")+'\">'+(f?r.title[0]:r.title)+\"</div>\":\"\";return r.zIndex=s,t([r.shade?'<div class=\"layui-layer-shade\" id=\"layui-layer-shade'+a+'\" times=\"'+a+'\" style=\"'+(\"z-index:\"+(s-1)+\"; \")+'\"></div>':\"\",'<div class=\"'+l[0]+(\" layui-layer-\"+o.type[r.type])+(0!=r.type&&2!=r.type||r.shade?\"\":\" layui-layer-border\")+\" \"+(r.skin||\"\")+'\" id=\"'+l[0]+a+'\" type=\"'+o.type[r.type]+'\" times=\"'+a+'\" showtime=\"'+r.time+'\" conType=\"'+(e?\"object\":\"string\")+'\" style=\"z-index: '+s+\"; width:\"+r.area[0]+\";height:\"+r.area[1]+(r.fixed?\"\":\";position:absolute;\")+'\">'+(e&&2!=r.type?\"\":u)+'<div id=\"'+(r.id||\"\")+'\" class=\"layui-layer-content'+(0==r.type&&r.icon!==-1?\" layui-layer-padding\":\"\")+(3==r.type?\" layui-layer-loading\"+r.icon:\"\")+'\">'+(0==r.type&&r.icon!==-1?'<i class=\"layui-layer-ico layui-layer-ico'+r.icon+'\"></i>':\"\")+(1==r.type&&e?\"\":r.content||\"\")+'</div><span class=\"layui-layer-setwin\">'+function(){var e=c?'<a class=\"layui-layer-min\" href=\"javascript:;\"><cite></cite></a><a class=\"layui-layer-ico layui-layer-max\" href=\"javascript:;\"></a>':\"\";return r.closeBtn&&(e+='<a class=\"layui-layer-ico '+l[7]+\" \"+l[7]+(r.title?r.closeBtn:4==r.type?\"1\":\"2\")+'\" href=\"javascript:;\"></a>'),e}()+\"</span>\"+(r.btn?function(){var e=\"\";\"string\"==typeof r.btn&&(r.btn=[r.btn]);for(var t=0,i=r.btn.length;t<i;t++)e+='<a class=\"'+l[6]+t+'\">'+r.btn[t]+\"</a>\";return'<div class=\"'+l[6]+\" layui-layer-btn-\"+(r.btnAlign||\"\")+'\">'+e+\"</div>\"}():\"\")+(r.resize?'<span class=\"layui-layer-resize\"></span>':\"\")+\"</div>\"],u,i('<div class=\"layui-layer-move\"></div>')),n},s.pt.creat=function(){var e=this,t=e.config,a=e.index,s=t.content,f=\"object\"==typeof s,c=i(\"body\");if(!t.id||!i(\"#\"+t.id)[0]){switch(\"string\"==typeof t.area&&(t.area=\"auto\"===t.area?[\"\",\"\"]:[t.area,\"\"]),t.shift&&(t.anim=t.shift),6==r.ie&&(t.fixed=!1),t.type){case 0:t.btn=\"btn\"in t?t.btn:o.btn[0],r.closeAll(\"dialog\");break;case 2:var s=t.content=f?t.content:[t.content||\"http://layer.layui.com\",\"auto\"];t.content='<iframe scrolling=\"'+(t.content[1]||\"auto\")+'\" allowtransparency=\"true\" id=\"'+l[4]+a+'\" name=\"'+l[4]+a+'\" onload=\"this.className=\\'\\';\" class=\"layui-layer-load\" frameborder=\"0\" src=\"'+t.content[0]+'\"></iframe>';break;case 3:delete t.title,delete t.closeBtn,t.icon===-1&&0===t.icon,r.closeAll(\"loading\");break;case 4:f||(t.content=[t.content,\"body\"]),t.follow=t.content[1],t.content=t.content[0]+'<i class=\"layui-layer-TipsG\"></i>',delete t.title,t.tips=\"object\"==typeof t.tips?t.tips:[t.tips,!0],t.tipsMore||r.closeAll(\"tips\")}if(e.vessel(f,function(n,r,u){c.append(n[0]),f?function(){2==t.type||4==t.type?function(){i(\"body\").append(n[1])}():function(){s.parents(\".\"+l[0])[0]||(s.data(\"display\",s.css(\"display\")).show().addClass(\"layui-layer-wrap\").wrap(n[1]),i(\"#\"+l[0]+a).find(\".\"+l[5]).before(r))}()}():c.append(n[1]),i(\".layui-layer-move\")[0]||c.append(o.moveElem=u),e.layero=i(\"#\"+l[0]+a),t.scrollbar||l.html.css(\"overflow\",\"hidden\").attr(\"layer-full\",a)}).auto(a),i(\"#layui-layer-shade\"+e.index).css({\"background-color\":t.shade[1]||\"#000\",opacity:t.shade[0]||t.shade}),2==t.type&&6==r.ie&&e.layero.find(\"iframe\").attr(\"src\",s[0]),4==t.type?e.tips():e.offset(),t.fixed&&n.on(\"resize\",function(){e.offset(),(/^\\d+%$/.test(t.area[0])||/^\\d+%$/.test(t.area[1]))&&e.auto(a),4==t.type&&e.tips()}),t.time<=0||setTimeout(function(){r.close(e.index)},t.time),e.move().callback(),l.anim[t.anim]){var u=\"layer-anim \"+l.anim[t.anim];e.layero.addClass(u).one(\"webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend\",function(){i(this).removeClass(u)})}t.isOutAnim&&e.layero.data(\"isOutAnim\",!0)}},s.pt.auto=function(e){var t=this,a=t.config,o=i(\"#\"+l[0]+e);\"\"===a.area[0]&&a.maxWidth>0&&(r.ie&&r.ie<8&&a.btn&&o.width(o.innerWidth()),o.outerWidth()>a.maxWidth&&o.width(a.maxWidth));var s=[o.innerWidth(),o.innerHeight()],f=o.find(l[1]).outerHeight()||0,c=o.find(\".\"+l[6]).outerHeight()||0,u=function(e){e=o.find(e),e.height(s[1]-f-c-2*(0|parseFloat(e.css(\"padding-top\"))))};switch(a.type){case 2:u(\"iframe\");break;default:\"\"===a.area[1]?a.maxHeight>0&&o.outerHeight()>a.maxHeight?(s[1]=a.maxHeight,u(\".\"+l[5])):a.fixed&&s[1]>=n.height()&&(s[1]=n.height(),u(\".\"+l[5])):u(\".\"+l[5])}return t},s.pt.offset=function(){var e=this,t=e.config,i=e.layero,a=[i.outerWidth(),i.outerHeight()],o=\"object\"==typeof t.offset;e.offsetTop=(n.height()-a[1])/2,e.offsetLeft=(n.width()-a[0])/2,o?(e.offsetTop=t.offset[0],e.offsetLeft=t.offset[1]||e.offsetLeft):\"auto\"!==t.offset&&(\"t\"===t.offset?e.offsetTop=0:\"r\"===t.offset?e.offsetLeft=n.width()-a[0]:\"b\"===t.offset?e.offsetTop=n.height()-a[1]:\"l\"===t.offset?e.offsetLeft=0:\"lt\"===t.offset?(e.offsetTop=0,e.offsetLeft=0):\"lb\"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=0):\"rt\"===t.offset?(e.offsetTop=0,e.offsetLeft=n.width()-a[0]):\"rb\"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=n.width()-a[0]):e.offsetTop=t.offset),t.fixed||(e.offsetTop=/%$/.test(e.offsetTop)?n.height()*parseFloat(e.offsetTop)/100:parseFloat(e.offsetTop),e.offsetLeft=/%$/.test(e.offsetLeft)?n.width()*parseFloat(e.offsetLeft)/100:parseFloat(e.offsetLeft),e.offsetTop+=n.scrollTop(),e.offsetLeft+=n.scrollLeft()),i.attr(\"minLeft\")&&(e.offsetTop=n.height()-(i.find(l[1]).outerHeight()||0),e.offsetLeft=i.css(\"left\")),i.css({top:e.offsetTop,left:e.offsetLeft})},s.pt.tips=function(){var e=this,t=e.config,a=e.layero,o=[a.outerWidth(),a.outerHeight()],r=i(t.follow);r[0]||(r=i(\"body\"));var s={width:r.outerWidth(),height:r.outerHeight(),top:r.offset().top,left:r.offset().left},f=a.find(\".layui-layer-TipsG\"),c=t.tips[0];t.tips[1]||f.remove(),s.autoLeft=function(){s.left+o[0]-n.width()>0?(s.tipLeft=s.left+s.width-o[0],f.css({right:12,left:\"auto\"})):s.tipLeft=s.left},s.where=[function(){s.autoLeft(),s.tipTop=s.top-o[1]-10,f.removeClass(\"layui-layer-TipsB\").addClass(\"layui-layer-TipsT\").css(\"border-right-color\",t.tips[1])},function(){s.tipLeft=s.left+s.width+10,s.tipTop=s.top,f.removeClass(\"layui-layer-TipsL\").addClass(\"layui-layer-TipsR\").css(\"border-bottom-color\",t.tips[1])},function(){s.autoLeft(),s.tipTop=s.top+s.height+10,f.removeClass(\"layui-layer-TipsT\").addClass(\"layui-layer-TipsB\").css(\"border-right-color\",t.tips[1])},function(){s.tipLeft=s.left-o[0]-10,s.tipTop=s.top,f.removeClass(\"layui-layer-TipsR\").addClass(\"layui-layer-TipsL\").css(\"border-bottom-color\",t.tips[1])}],s.where[c-1](),1===c?s.top-(n.scrollTop()+o[1]+16)<0&&s.where[2]():2===c?n.width()-(s.left+s.width+o[0]+16)>0||s.where[3]():3===c?s.top-n.scrollTop()+s.height+o[1]+16-n.height()>0&&s.where[0]():4===c&&o[0]+16-s.left>0&&s.where[1](),a.find(\".\"+l[5]).css({\"background-color\":t.tips[1],\"padding-right\":t.closeBtn?\"30px\":\"\"}),a.css({left:s.tipLeft-(t.fixed?n.scrollLeft():0),top:s.tipTop-(t.fixed?n.scrollTop():0)})},s.pt.move=function(){var e=this,t=e.config,a=i(document),s=e.layero,l=s.find(t.move),f=s.find(\".layui-layer-resize\"),c={};return t.move&&l.css(\"cursor\",\"move\"),l.on(\"mousedown\",function(e){e.preventDefault(),t.move&&(c.moveStart=!0,c.offset=[e.clientX-parseFloat(s.css(\"left\")),e.clientY-parseFloat(s.css(\"top\"))],o.moveElem.css(\"cursor\",\"move\").show())}),f.on(\"mousedown\",function(e){e.preventDefault(),c.resizeStart=!0,c.offset=[e.clientX,e.clientY],c.area=[s.outerWidth(),s.outerHeight()],o.moveElem.css(\"cursor\",\"se-resize\").show()}),a.on(\"mousemove\",function(i){if(c.moveStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1],l=\"fixed\"===s.css(\"position\");if(i.preventDefault(),c.stX=l?0:n.scrollLeft(),c.stY=l?0:n.scrollTop(),!t.moveOut){var f=n.width()-s.outerWidth()+c.stX,u=n.height()-s.outerHeight()+c.stY;a<c.stX&&(a=c.stX),a>f&&(a=f),o<c.stY&&(o=c.stY),o>u&&(o=u)}s.css({left:a,top:o})}if(t.resize&&c.resizeStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1];i.preventDefault(),r.style(e.index,{width:c.area[0]+a,height:c.area[1]+o}),c.isResize=!0,t.resizing&&t.resizing(s)}}).on(\"mouseup\",function(e){c.moveStart&&(delete c.moveStart,o.moveElem.hide(),t.moveEnd&&t.moveEnd(s)),c.resizeStart&&(delete c.resizeStart,o.moveElem.hide())}),e},s.pt.callback=function(){function e(){var e=a.cancel&&a.cancel(t.index,n);e===!1||r.close(t.index)}var t=this,n=t.layero,a=t.config;t.openLayer(),a.success&&(2==a.type?n.find(\"iframe\").on(\"load\",function(){a.success(n,t.index)}):a.success(n,t.index)),6==r.ie&&t.IE6(n),n.find(\".\"+l[6]).children(\"a\").on(\"click\",function(){var e=i(this).index();if(0===e)a.yes?a.yes(t.index,n):a.btn1?a.btn1(t.index,n):r.close(t.index);else{var o=a[\"btn\"+(e+1)]&&a[\"btn\"+(e+1)](t.index,n);o===!1||r.close(t.index)}}),n.find(\".\"+l[7]).on(\"click\",e),a.shadeClose&&i(\"#layui-layer-shade\"+t.index).on(\"click\",function(){r.close(t.index)}),n.find(\".layui-layer-min\").on(\"click\",function(){var e=a.min&&a.min(n);e===!1||r.min(t.index,a)}),n.find(\".layui-layer-max\").on(\"click\",function(){i(this).hasClass(\"layui-layer-maxmin\")?(r.restore(t.index),a.restore&&a.restore(n)):(r.full(t.index,a),setTimeout(function(){a.full&&a.full(n)},100))}),a.end&&(o.end[t.index]=a.end)},o.reselect=function(){i.each(i(\"select\"),function(e,t){var n=i(this);n.parents(\".\"+l[0])[0]||1==n.attr(\"layer\")&&i(\".\"+l[0]).length<1&&n.removeAttr(\"layer\").show(),n=null})},s.pt.IE6=function(e){i(\"select\").each(function(e,t){var n=i(this);n.parents(\".\"+l[0])[0]||\"none\"===n.css(\"display\")||n.attr({layer:\"1\"}).hide(),n=null})},s.pt.openLayer=function(){var e=this;r.zIndex=e.config.zIndex,r.setTop=function(e){var t=function(){r.zIndex++,e.css(\"z-index\",r.zIndex+1)};return r.zIndex=parseInt(e[0].style.zIndex),e.on(\"mousedown\",t),r.zIndex}},o.record=function(e){var t=[e.width(),e.height(),e.position().top,e.position().left+parseFloat(e.css(\"margin-left\"))];e.find(\".layui-layer-max\").addClass(\"layui-layer-maxmin\"),e.attr({area:t})},o.rescollbar=function(e){l.html.attr(\"layer-full\")==e&&(l.html[0].style.removeProperty?l.html[0].style.removeProperty(\"overflow\"):l.html[0].style.removeAttribute(\"overflow\"),l.html.removeAttr(\"layer-full\"))},e.layer=r,r.getChildFrame=function(e,t){return t=t||i(\".\"+l[4]).attr(\"times\"),i(\"#\"+l[0]+t).find(\"iframe\").contents().find(e)},r.getFrameIndex=function(e){return i(\"#\"+e).parents(\".\"+l[4]).attr(\"times\")},r.iframeAuto=function(e){if(e){var t=r.getChildFrame(\"html\",e).outerHeight(),n=i(\"#\"+l[0]+e),a=n.find(l[1]).outerHeight()||0,o=n.find(\".\"+l[6]).outerHeight()||0;n.css({height:t+a+o}),n.find(\"iframe\").css({height:t})}},r.iframeSrc=function(e,t){i(\"#\"+l[0]+e).find(\"iframe\").attr(\"src\",t)},r.style=function(e,t,n){var a=i(\"#\"+l[0]+e),r=a.find(\".layui-layer-content\"),s=a.attr(\"type\"),f=a.find(l[1]).outerHeight()||0,c=a.find(\".\"+l[6]).outerHeight()||0;a.attr(\"minLeft\");s!==o.type[3]&&s!==o.type[4]&&(n||(parseFloat(t.width)<=260&&(t.width=260),parseFloat(t.height)-f-c<=64&&(t.height=64+f+c)),a.css(t),c=a.find(\".\"+l[6]).outerHeight(),s===o.type[2]?a.find(\"iframe\").css({height:parseFloat(t.height)-f-c}):r.css({height:parseFloat(t.height)-f-c-parseFloat(r.css(\"padding-top\"))-parseFloat(r.css(\"padding-bottom\"))}))},r.min=function(e,t){var a=i(\"#\"+l[0]+e),s=a.find(l[1]).outerHeight()||0,f=a.attr(\"minLeft\")||181*o.minIndex+\"px\",c=a.css(\"position\");o.record(a),o.minLeft[0]&&(f=o.minLeft[0],o.minLeft.shift()),a.attr(\"position\",c),r.style(e,{width:180,height:s,left:f,top:n.height()-s,position:\"fixed\",overflow:\"hidden\"},!0),a.find(\".layui-layer-min\").hide(),\"page\"===a.attr(\"type\")&&a.find(l[4]).hide(),o.rescollbar(e),a.attr(\"minLeft\")||o.minIndex++,a.attr(\"minLeft\",f)},r.restore=function(e){var t=i(\"#\"+l[0]+e),n=t.attr(\"area\").split(\",\");t.attr(\"type\");r.style(e,{width:parseFloat(n[0]),height:parseFloat(n[1]),top:parseFloat(n[2]),left:parseFloat(n[3]),position:t.attr(\"position\"),overflow:\"visible\"},!0),t.find(\".layui-layer-max\").removeClass(\"layui-layer-maxmin\"),t.find(\".layui-layer-min\").show(),\"page\"===t.attr(\"type\")&&t.find(l[4]).show(),o.rescollbar(e)},r.full=function(e){var t,a=i(\"#\"+l[0]+e);o.record(a),l.html.attr(\"layer-full\")||l.html.css(\"overflow\",\"hidden\").attr(\"layer-full\",e),clearTimeout(t),t=setTimeout(function(){var t=\"fixed\"===a.css(\"position\");r.style(e,{top:t?0:n.scrollTop(),left:t?0:n.scrollLeft(),width:n.width(),height:n.height()},!0),a.find(\".layui-layer-min\").hide()},100)},r.title=function(e,t){var n=i(\"#\"+l[0]+(t||r.index)).find(l[1]);n.html(e)},r.close=function(e){var t=i(\"#\"+l[0]+e),n=t.attr(\"type\"),a=\"layer-anim-close\";if(t[0]){var s=\"layui-layer-wrap\",f=function(){if(n===o.type[1]&&\"object\"===t.attr(\"conType\")){t.children(\":not(.\"+l[5]+\")\").remove();for(var a=t.find(\".\"+s),r=0;r<2;r++)a.unwrap();a.css(\"display\",a.data(\"display\")).removeClass(s)}else{if(n===o.type[2])try{var f=i(\"#\"+l[4]+e)[0];f.contentWindow.document.write(\"\"),f.contentWindow.close(),t.find(\".\"+l[5])[0].removeChild(f)}catch(c){}t[0].innerHTML=\"\",t.remove()}\"function\"==typeof o.end[e]&&o.end[e](),delete o.end[e]};t.data(\"isOutAnim\")&&t.addClass(\"layer-anim \"+a),i(\"#layui-layer-moves, #layui-layer-shade\"+e).remove(),6==r.ie&&o.reselect(),o.rescollbar(e),t.attr(\"minLeft\")&&(o.minIndex--,o.minLeft.push(t.attr(\"minLeft\"))),r.ie&&r.ie<10||!t.data(\"isOutAnim\")?f():setTimeout(function(){f()},200)}},r.closeAll=function(e){i.each(i(\".\"+l[0]),function(){var t=i(this),n=e?t.attr(\"type\")===e:1;n&&r.close(t.attr(\"times\")),n=null})};var f=r.cache||{},c=function(e){return f.skin?\" \"+f.skin+\" \"+f.skin+\"-\"+e:\"\"};r.prompt=function(e,t){var a=\"\";if(e=e||{},\"function\"==typeof e&&(t=e),e.area){var o=e.area;a='style=\"width: '+o[0]+\"; height: \"+o[1]+';\"',delete e.area}var s,l=2==e.formType?'<textarea class=\"layui-layer-input\"'+a+\"></textarea>\":function(){return'<input type=\"'+(1==e.formType?\"password\":\"text\")+'\" class=\"layui-layer-input\">'}(),f=e.success;return delete e.success,r.open(i.extend({type:1,btn:[\"&#x786E;&#x5B9A;\",\"&#x53D6;&#x6D88;\"],content:l,skin:\"layui-layer-prompt\"+c(\"prompt\"),maxWidth:n.width(),success:function(t){s=t.find(\".layui-layer-input\"),s.val(e.value||\"\").focus(),\"function\"==typeof f&&f(t)},resize:!1,yes:function(i){var n=s.val();\"\"===n?s.focus():n.length>(e.maxlength||500)?r.tips(\"&#x6700;&#x591A;&#x8F93;&#x5165;\"+(e.maxlength||500)+\"&#x4E2A;&#x5B57;&#x6570;\",s,{tips:1}):t&&t(n,i,s)}},e))},r.tab=function(e){e=e||{};var t=e.tab||{},n=\"layui-this\",a=e.success;return delete e.success,r.open(i.extend({type:1,skin:\"layui-layer-tab\"+c(\"tab\"),resize:!1,title:function(){var e=t.length,i=1,a=\"\";if(e>0)for(a='<span class=\"'+n+'\">'+t[0].title+\"</span>\";i<e;i++)a+=\"<span>\"+t[i].title+\"</span>\";return a}(),content:'<ul class=\"layui-layer-tabmain\">'+function(){var e=t.length,i=1,a=\"\";if(e>0)for(a='<li class=\"layui-layer-tabli '+n+'\">'+(t[0].content||\"no content\")+\"</li>\";i<e;i++)a+='<li class=\"layui-layer-tabli\">'+(t[i].content||\"no  content\")+\"</li>\";return a}()+\"</ul>\",success:function(t){var o=t.find(\".layui-layer-title\").children(),r=t.find(\".layui-layer-tabmain\").children();o.on(\"mousedown\",function(t){t.stopPropagation?t.stopPropagation():t.cancelBubble=!0;var a=i(this),o=a.index();a.addClass(n).siblings().removeClass(n),r.eq(o).show().siblings().hide(),\"function\"==typeof e.change&&e.change(o)}),\"function\"==typeof a&&a(t)}},e))},r.photos=function(t,n,a){function o(e,t,i){var n=new Image;return n.src=e,n.complete?t(n):(n.onload=function(){n.onload=null,t(n)},void(n.onerror=function(e){n.onerror=null,i(e)}))}var s={};if(t=t||{},t.photos){var l=t.photos.constructor===Object,f=l?t.photos:{},u=f.data||[],d=f.start||0;s.imgIndex=(0|d)+1,t.img=t.img||\"img\";var y=t.success;if(delete t.success,l){if(0===u.length)return r.msg(\"&#x6CA1;&#x6709;&#x56FE;&#x7247;\")}else{var p=i(t.photos),h=function(){u=[],p.find(t.img).each(function(e){var t=i(this);t.attr(\"layer-index\",e),u.push({alt:t.attr(\"alt\"),pid:t.attr(\"layer-pid\"),src:t.attr(\"layer-src\")||t.attr(\"src\"),thumb:t.attr(\"src\")})})};if(h(),0===u.length)return;if(n||p.on(\"click\",t.img,function(){var e=i(this),n=e.attr(\"layer-index\");r.photos(i.extend(t,{photos:{start:n,data:u,tab:t.tab},full:t.full}),!0),h()}),!n)return}s.imgprev=function(e){s.imgIndex--,s.imgIndex<1&&(s.imgIndex=u.length),s.tabimg(e)},s.imgnext=function(e,t){s.imgIndex++,s.imgIndex>u.length&&(s.imgIndex=1,t)||s.tabimg(e)},s.keyup=function(e){if(!s.end){var t=e.keyCode;e.preventDefault(),37===t?s.imgprev(!0):39===t?s.imgnext(!0):27===t&&r.close(s.index)}},s.tabimg=function(e){if(!(u.length<=1))return f.start=s.imgIndex-1,r.close(s.index),r.photos(t,!0,e)},s.event=function(){s.bigimg.hover(function(){s.imgsee.show()},function(){s.imgsee.hide()}),s.bigimg.find(\".layui-layer-imgprev\").on(\"click\",function(e){e.preventDefault(),s.imgprev()}),s.bigimg.find(\".layui-layer-imgnext\").on(\"click\",function(e){e.preventDefault(),s.imgnext()}),i(document).on(\"keyup\",s.keyup)},s.loadi=r.load(1,{shade:!(\"shade\"in t)&&.9,scrollbar:!1}),o(u[d].src,function(n){r.close(s.loadi),s.index=r.open(i.extend({type:1,id:\"layui-layer-photos\",area:function(){var a=[n.width,n.height],o=[i(e).width()-100,i(e).height()-100];if(!t.full&&(a[0]>o[0]||a[1]>o[1])){var r=[a[0]/o[0],a[1]/o[1]];r[0]>r[1]?(a[0]=a[0]/r[0],a[1]=a[1]/r[0]):r[0]<r[1]&&(a[0]=a[0]/r[1],a[1]=a[1]/r[1])}return[a[0]+\"px\",a[1]+\"px\"]}(),title:!1,shade:.9,shadeClose:!0,closeBtn:!1,move:\".layui-layer-phimg img\",moveType:1,scrollbar:!1,moveOut:!0,isOutAnim:!1,skin:\"layui-layer-photos\"+c(\"photos\"),content:'<div class=\"layui-layer-phimg\"><img src=\"'+u[d].src+'\" alt=\"'+(u[d].alt||\"\")+'\" layer-pid=\"'+u[d].pid+'\"><div class=\"layui-layer-imgsee\">'+(u.length>1?'<span class=\"layui-layer-imguide\"><a href=\"javascript:;\" class=\"layui-layer-iconext layui-layer-imgprev\"></a><a href=\"javascript:;\" class=\"layui-layer-iconext layui-layer-imgnext\"></a></span>':\"\")+'<div class=\"layui-layer-imgbar\" style=\"display:'+(a?\"block\":\"\")+'\"><span class=\"layui-layer-imgtit\"><a href=\"javascript:;\">'+(u[d].alt||\"\")+\"</a><em>\"+s.imgIndex+\"/\"+u.length+\"</em></span></div></div></div>\",success:function(e,i){s.bigimg=e.find(\".layui-layer-phimg\"),s.imgsee=e.find(\".layui-layer-imguide,.layui-layer-imgbar\"),s.event(e),t.tab&&t.tab(u[d],e),\"function\"==typeof y&&y(e)},end:function(){s.end=!0,i(document).off(\"keyup\",s.keyup)}},t))},function(){r.close(s.loadi),r.msg(\"&#x5F53;&#x524D;&#x56FE;&#x7247;&#x5730;&#x5740;&#x5F02;&#x5E38;<br>&#x662F;&#x5426;&#x7EE7;&#x7EED;&#x67E5;&#x770B;&#x4E0B;&#x4E00;&#x5F20;&#xFF1F;\",{time:3e4,btn:[\"&#x4E0B;&#x4E00;&#x5F20;\",\"&#x4E0D;&#x770B;&#x4E86;\"],yes:function(){u.length>1&&s.imgnext(!0,!0)}})})}},o.run=function(t){i=t,n=i(e),l.html=i(\"html\"),r.open=function(e){var t=new s(e);return t.index}},e.layui&&layui.define?(r.ready(),layui.define(\"jquery\",function(t){r.path=layui.cache.dir,o.run(layui.$),e.layer=r,t(\"layer\",r)})):\"function\"==typeof define&&define.amd?define([\"jquery\"],function(){return o.run(e.jQuery),r}):function(){o.run(e.jQuery),r.ready()}()}(window);"
  },
  {
    "path": "public/layui/lay/modules/laypage.js",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n ;layui.define(function(e){\"use strict\";var a=document,t=\"getElementById\",n=\"getElementsByTagName\",i=\"laypage\",r=\"layui-disabled\",u=function(e){var a=this;a.config=e||{},a.config.index=++s.index,a.render(!0)};u.prototype.type=function(){var e=this.config;if(\"object\"==typeof e.elem)return void 0===e.elem.length?2:3},u.prototype.view=function(){var e=this,a=e.config,t=a.groups=\"groups\"in a?0|a.groups:5;a.layout=\"object\"==typeof a.layout?a.layout:[\"prev\",\"page\",\"next\"],a.count=0|a.count,a.curr=0|a.curr||1,a.limits=\"object\"==typeof a.limits?a.limits:[10,20,30,40,50],a.limit=0|a.limit||10,a.pages=Math.ceil(a.count/a.limit)||1,a.curr>a.pages&&(a.curr=a.pages),t<0?t=1:t>a.pages&&(t=a.pages),a.prev=\"prev\"in a?a.prev:\"&#x4E0A;&#x4E00;&#x9875;\",a.next=\"next\"in a?a.next:\"&#x4E0B;&#x4E00;&#x9875;\";var n=a.pages>t?Math.ceil((a.curr+(t>1?1:0))/(t>0?t:1)):1,i={prev:function(){return a.prev?'<a href=\"javascript:;\" class=\"layui-laypage-prev'+(1==a.curr?\" \"+r:\"\")+'\" data-page=\"'+(a.curr-1)+'\">'+a.prev+\"</a>\":\"\"}(),page:function(){var e=[];if(a.count<1)return\"\";n>1&&a.first!==!1&&0!==t&&e.push('<a href=\"javascript:;\" class=\"layui-laypage-first\" data-page=\"1\"  title=\"&#x9996;&#x9875;\">'+(a.first||1)+\"</a>\");var i=Math.floor((t-1)/2),r=n>1?a.curr-i:1,u=n>1?function(){var e=a.curr+(t-i-1);return e>a.pages?a.pages:e}():t;for(u-r<t-1&&(r=u-t+1),a.first!==!1&&r>2&&e.push('<span class=\"layui-laypage-spr\">&#x2026;</span>');r<=u;r++)r===a.curr?e.push('<span class=\"layui-laypage-curr\"><em class=\"layui-laypage-em\" '+(/^#/.test(a.theme)?'style=\"background-color:'+a.theme+';\"':\"\")+\"></em><em>\"+r+\"</em></span>\"):e.push('<a href=\"javascript:;\" data-page=\"'+r+'\">'+r+\"</a>\");return a.pages>t&&a.pages>u&&a.last!==!1&&(u+1<a.pages&&e.push('<span class=\"layui-laypage-spr\">&#x2026;</span>'),0!==t&&e.push('<a href=\"javascript:;\" class=\"layui-laypage-last\" title=\"&#x5C3E;&#x9875;\"  data-page=\"'+a.pages+'\">'+(a.last||a.pages)+\"</a>\")),e.join(\"\")}(),next:function(){return a.next?'<a href=\"javascript:;\" class=\"layui-laypage-next'+(a.curr==a.pages?\" \"+r:\"\")+'\" data-page=\"'+(a.curr+1)+'\">'+a.next+\"</a>\":\"\"}(),count:'<span class=\"layui-laypage-count\">共 '+a.count+\" 条</span>\",limit:function(){var e=['<span class=\"layui-laypage-limits\"><select lay-ignore>'];return layui.each(a.limits,function(t,n){e.push('<option value=\"'+n+'\"'+(n===a.limit?\"selected\":\"\")+\">\"+n+\" 条/页</option>\")}),e.join(\"\")+\"</select></span>\"}(),refresh:['<a href=\"javascript:;\" data-page=\"'+a.curr+'\" class=\"layui-laypage-refresh\">','<i class=\"layui-icon layui-icon-refresh\"></i>',\"</a>\"].join(\"\"),skip:function(){return['<span class=\"layui-laypage-skip\">&#x5230;&#x7B2C;','<input type=\"text\" min=\"1\" value=\"'+a.curr+'\" class=\"layui-input\">','&#x9875;<button type=\"button\" class=\"layui-laypage-btn\">&#x786e;&#x5b9a;</button>',\"</span>\"].join(\"\")}()};return['<div class=\"layui-box layui-laypage layui-laypage-'+(a.theme?/^#/.test(a.theme)?\"molv\":a.theme:\"default\")+'\" id=\"layui-laypage-'+a.index+'\">',function(){var e=[];return layui.each(a.layout,function(a,t){i[t]&&e.push(i[t])}),e.join(\"\")}(),\"</div>\"].join(\"\")},u.prototype.jump=function(e,a){if(e){var t=this,i=t.config,r=e.children,u=e[n](\"button\")[0],l=e[n](\"input\")[0],p=e[n](\"select\")[0],c=function(){var e=0|l.value.replace(/\\s|\\D/g,\"\");e&&(i.curr=e,t.render())};if(a)return c();for(var o=0,y=r.length;o<y;o++)\"a\"===r[o].nodeName.toLowerCase()&&s.on(r[o],\"click\",function(){var e=0|this.getAttribute(\"data-page\");e<1||e>i.pages||(i.curr=e,t.render())});p&&s.on(p,\"change\",function(){var e=this.value;i.curr*e>i.count&&(i.curr=Math.ceil(i.count/e)),i.limit=e,t.render()}),u&&s.on(u,\"click\",function(){c()})}},u.prototype.skip=function(e){if(e){var a=this,t=e[n](\"input\")[0];t&&s.on(t,\"keyup\",function(t){var n=this.value,i=t.keyCode;/^(37|38|39|40)$/.test(i)||(/\\D/.test(n)&&(this.value=n.replace(/\\D/,\"\")),13===i&&a.jump(e,!0))})}},u.prototype.render=function(e){var n=this,i=n.config,r=n.type(),u=n.view();2===r?i.elem&&(i.elem.innerHTML=u):3===r?i.elem.html(u):a[t](i.elem)&&(a[t](i.elem).innerHTML=u),i.jump&&i.jump(i,e);var s=a[t](\"layui-laypage-\"+i.index);n.jump(s),i.hash&&!e&&(location.hash=\"!\"+i.hash+\"=\"+i.curr),n.skip(s)};var s={render:function(e){var a=new u(e);return a.index},index:layui.laypage?layui.laypage.index+1e4:0,on:function(e,a,t){return e.attachEvent?e.attachEvent(\"on\"+a,function(a){a.target=a.srcElement,t.call(e,a)}):e.addEventListener(a,t,!1),this}};e(i,s)});"
  },
  {
    "path": "public/layui/lay/modules/laytpl.js",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n ;layui.define(function(e){\"use strict\";var r={open:\"{{\",close:\"}}\"},c={exp:function(e){return new RegExp(e,\"g\")},query:function(e,c,t){var o=[\"#([\\\\s\\\\S])+?\",\"([^{#}])*?\"][e||0];return n((c||\"\")+r.open+o+r.close+(t||\"\"))},escape:function(e){return String(e||\"\").replace(/&(?!#?[a-zA-Z0-9]+;)/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/'/g,\"&#39;\").replace(/\"/g,\"&quot;\")},error:function(e,r){var c=\"Laytpl Error：\";return\"object\"==typeof console&&console.error(c+e+\"\\n\"+(r||\"\")),c+e}},n=c.exp,t=function(e){this.tpl=e};t.pt=t.prototype,window.errors=0,t.pt.parse=function(e,t){var o=this,p=e,a=n(\"^\"+r.open+\"#\",\"\"),l=n(r.close+\"$\",\"\");e=e.replace(/\\s+|\\r|\\t|\\n/g,\" \").replace(n(r.open+\"#\"),r.open+\"# \").replace(n(r.close+\"}\"),\"} \"+r.close).replace(/\\\\/g,\"\\\\\\\\\").replace(n(r.open+\"!(.+?)!\"+r.close),function(e){return e=e.replace(n(\"^\"+r.open+\"!\"),\"\").replace(n(\"!\"+r.close),\"\").replace(n(r.open+\"|\"+r.close),function(e){return e.replace(/(.)/g,\"\\\\$1\")})}).replace(/(?=\"|')/g,\"\\\\\").replace(c.query(),function(e){return e=e.replace(a,\"\").replace(l,\"\"),'\";'+e.replace(/\\\\/g,\"\")+';view+=\"'}).replace(c.query(1),function(e){var c='\"+(';return e.replace(/\\s/g,\"\")===r.open+r.close?\"\":(e=e.replace(n(r.open+\"|\"+r.close),\"\"),/^=/.test(e)&&(e=e.replace(/^=/,\"\"),c='\"+_escape_('),c+e.replace(/\\\\/g,\"\")+')+\"')}),e='\"use strict\";var view = \"'+e+'\";return view;';try{return o.cache=e=new Function(\"d, _escape_\",e),e(t,c.escape)}catch(u){return delete o.cache,c.error(u,p)}},t.pt.render=function(e,r){var n,t=this;return e?(n=t.cache?t.cache(e,c.escape):t.parse(t.tpl,e),r?void r(n):n):c.error(\"no data\")};var o=function(e){return\"string\"!=typeof e?c.error(\"Template not found\"):new t(e)};o.config=function(e){e=e||{};for(var c in e)r[c]=e[c]},o.v=\"1.2.0\",e(\"laytpl\",o)});"
  },
  {
    "path": "public/layui/lay/modules/mobile.js",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n ;layui.define(function(i){i(\"layui.mobile\",layui.v)});layui.define(function(e){\"use strict\";var r={open:\"{{\",close:\"}}\"},c={exp:function(e){return new RegExp(e,\"g\")},query:function(e,c,t){var o=[\"#([\\\\s\\\\S])+?\",\"([^{#}])*?\"][e||0];return n((c||\"\")+r.open+o+r.close+(t||\"\"))},escape:function(e){return String(e||\"\").replace(/&(?!#?[a-zA-Z0-9]+;)/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/'/g,\"&#39;\").replace(/\"/g,\"&quot;\")},error:function(e,r){var c=\"Laytpl Error：\";return\"object\"==typeof console&&console.error(c+e+\"\\n\"+(r||\"\")),c+e}},n=c.exp,t=function(e){this.tpl=e};t.pt=t.prototype,window.errors=0,t.pt.parse=function(e,t){var o=this,p=e,a=n(\"^\"+r.open+\"#\",\"\"),l=n(r.close+\"$\",\"\");e=e.replace(/\\s+|\\r|\\t|\\n/g,\" \").replace(n(r.open+\"#\"),r.open+\"# \").replace(n(r.close+\"}\"),\"} \"+r.close).replace(/\\\\/g,\"\\\\\\\\\").replace(n(r.open+\"!(.+?)!\"+r.close),function(e){return e=e.replace(n(\"^\"+r.open+\"!\"),\"\").replace(n(\"!\"+r.close),\"\").replace(n(r.open+\"|\"+r.close),function(e){return e.replace(/(.)/g,\"\\\\$1\")})}).replace(/(?=\"|')/g,\"\\\\\").replace(c.query(),function(e){return e=e.replace(a,\"\").replace(l,\"\"),'\";'+e.replace(/\\\\/g,\"\")+';view+=\"'}).replace(c.query(1),function(e){var c='\"+(';return e.replace(/\\s/g,\"\")===r.open+r.close?\"\":(e=e.replace(n(r.open+\"|\"+r.close),\"\"),/^=/.test(e)&&(e=e.replace(/^=/,\"\"),c='\"+_escape_('),c+e.replace(/\\\\/g,\"\")+')+\"')}),e='\"use strict\";var view = \"'+e+'\";return view;';try{return o.cache=e=new Function(\"d, _escape_\",e),e(t,c.escape)}catch(u){return delete o.cache,c.error(u,p)}},t.pt.render=function(e,r){var n,t=this;return e?(n=t.cache?t.cache(e,c.escape):t.parse(t.tpl,e),r?void r(n):n):c.error(\"no data\")};var o=function(e){return\"string\"!=typeof e?c.error(\"Template not found\"):new t(e)};o.config=function(e){e=e||{};for(var c in e)r[c]=e[c]},o.v=\"1.2.0\",e(\"laytpl\",o)});layui.define(function(e){\"use strict\";var t=(window,document),i=\"querySelectorAll\",n=\"getElementsByClassName\",a=function(e){return t[i](e)},s={type:0,shade:!0,shadeClose:!0,fixed:!0,anim:\"scale\"},l={extend:function(e){var t=JSON.parse(JSON.stringify(s));for(var i in e)t[i]=e[i];return t},timer:{},end:{}};l.touch=function(e,t){e.addEventListener(\"click\",function(e){t.call(this,e)},!1)};var o=0,r=[\"layui-m-layer\"],d=function(e){var t=this;t.config=l.extend(e),t.view()};d.prototype.view=function(){var e=this,i=e.config,s=t.createElement(\"div\");e.id=s.id=r[0]+o,s.setAttribute(\"class\",r[0]+\" \"+r[0]+(i.type||0)),s.setAttribute(\"index\",o);var l=function(){var e=\"object\"==typeof i.title;return i.title?'<h3 style=\"'+(e?i.title[1]:\"\")+'\">'+(e?i.title[0]:i.title)+\"</h3>\":\"\"}(),d=function(){\"string\"==typeof i.btn&&(i.btn=[i.btn]);var e,t=(i.btn||[]).length;return 0!==t&&i.btn?(e='<span yes type=\"1\">'+i.btn[0]+\"</span>\",2===t&&(e='<span no type=\"0\">'+i.btn[1]+\"</span>\"+e),'<div class=\"layui-m-layerbtn\">'+e+\"</div>\"):\"\"}();if(i.fixed||(i.top=i.hasOwnProperty(\"top\")?i.top:100,i.style=i.style||\"\",i.style+=\" top:\"+(t.body.scrollTop+i.top)+\"px\"),2===i.type&&(i.content='<i></i><i class=\"layui-m-layerload\"></i><i></i><p>'+(i.content||\"\")+\"</p>\"),i.skin&&(i.anim=\"up\"),\"msg\"===i.skin&&(i.shade=!1),s.innerHTML=(i.shade?\"<div \"+(\"string\"==typeof i.shade?'style=\"'+i.shade+'\"':\"\")+' class=\"layui-m-layershade\"></div>':\"\")+'<div class=\"layui-m-layermain\" '+(i.fixed?\"\":'style=\"position:static;\"')+'><div class=\"layui-m-layersection\"><div class=\"layui-m-layerchild '+(i.skin?\"layui-m-layer-\"+i.skin+\" \":\"\")+(i.className?i.className:\"\")+\" \"+(i.anim?\"layui-m-anim-\"+i.anim:\"\")+'\" '+(i.style?'style=\"'+i.style+'\"':\"\")+\">\"+l+'<div class=\"layui-m-layercont\">'+i.content+\"</div>\"+d+\"</div></div></div>\",!i.type||2===i.type){var y=t[n](r[0]+i.type),u=y.length;u>=1&&c.close(y[0].getAttribute(\"index\"))}document.body.appendChild(s);var m=e.elem=a(\"#\"+e.id)[0];i.success&&i.success(m),e.index=o++,e.action(i,m)},d.prototype.action=function(e,t){var i=this;e.time&&(l.timer[i.index]=setTimeout(function(){c.close(i.index)},1e3*e.time));var a=function(){var t=this.getAttribute(\"type\");0==t?(e.no&&e.no(),c.close(i.index)):e.yes?e.yes(i.index):c.close(i.index)};if(e.btn)for(var s=t[n](\"layui-m-layerbtn\")[0].children,o=s.length,r=0;r<o;r++)l.touch(s[r],a);if(e.shade&&e.shadeClose){var d=t[n](\"layui-m-layershade\")[0];l.touch(d,function(){c.close(i.index,e.end)})}e.end&&(l.end[i.index]=e.end)};var c={v:\"2.0 m\",index:o,open:function(e){var t=new d(e||{});return t.index},close:function(e){var i=a(\"#\"+r[0]+e)[0];i&&(i.innerHTML=\"\",t.body.removeChild(i),clearTimeout(l.timer[e]),delete l.timer[e],\"function\"==typeof l.end[e]&&l.end[e](),delete l.end[e])},closeAll:function(){for(var e=t[n](r[0]),i=0,a=e.length;i<a;i++)c.close(0|e[0].getAttribute(\"index\"))}};e(\"layer-mobile\",c)});layui.define(function(t){var e=function(){function t(t){return null==t?String(t):J[W.call(t)]||\"object\"}function e(e){return\"function\"==t(e)}function n(t){return null!=t&&t==t.window}function r(t){return null!=t&&t.nodeType==t.DOCUMENT_NODE}function i(e){return\"object\"==t(e)}function o(t){return i(t)&&!n(t)&&Object.getPrototypeOf(t)==Object.prototype}function a(t){var e=!!t&&\"length\"in t&&t.length,r=T.type(t);return\"function\"!=r&&!n(t)&&(\"array\"==r||0===e||\"number\"==typeof e&&e>0&&e-1 in t)}function s(t){return A.call(t,function(t){return null!=t})}function u(t){return t.length>0?T.fn.concat.apply([],t):t}function c(t){return t.replace(/::/g,\"/\").replace(/([A-Z]+)([A-Z][a-z])/g,\"$1_$2\").replace(/([a-z\\d])([A-Z])/g,\"$1_$2\").replace(/_/g,\"-\").toLowerCase()}function l(t){return t in F?F[t]:F[t]=new RegExp(\"(^|\\\\s)\"+t+\"(\\\\s|$)\")}function f(t,e){return\"number\"!=typeof e||k[c(t)]?e:e+\"px\"}function h(t){var e,n;return $[t]||(e=L.createElement(t),L.body.appendChild(e),n=getComputedStyle(e,\"\").getPropertyValue(\"display\"),e.parentNode.removeChild(e),\"none\"==n&&(n=\"block\"),$[t]=n),$[t]}function p(t){return\"children\"in t?D.call(t.children):T.map(t.childNodes,function(t){if(1==t.nodeType)return t})}function d(t,e){var n,r=t?t.length:0;for(n=0;n<r;n++)this[n]=t[n];this.length=r,this.selector=e||\"\"}function m(t,e,n){for(j in e)n&&(o(e[j])||Q(e[j]))?(o(e[j])&&!o(t[j])&&(t[j]={}),Q(e[j])&&!Q(t[j])&&(t[j]=[]),m(t[j],e[j],n)):e[j]!==E&&(t[j]=e[j])}function v(t,e){return null==e?T(t):T(t).filter(e)}function g(t,n,r,i){return e(n)?n.call(t,r,i):n}function y(t,e,n){null==n?t.removeAttribute(e):t.setAttribute(e,n)}function x(t,e){var n=t.className||\"\",r=n&&n.baseVal!==E;return e===E?r?n.baseVal:n:void(r?n.baseVal=e:t.className=e)}function b(t){try{return t?\"true\"==t||\"false\"!=t&&(\"null\"==t?null:+t+\"\"==t?+t:/^[\\[\\{]/.test(t)?T.parseJSON(t):t):t}catch(e){return t}}function w(t,e){e(t);for(var n=0,r=t.childNodes.length;n<r;n++)w(t.childNodes[n],e)}var E,j,T,S,C,N,O=[],P=O.concat,A=O.filter,D=O.slice,L=window.document,$={},F={},k={\"column-count\":1,columns:1,\"font-weight\":1,\"line-height\":1,opacity:1,\"z-index\":1,zoom:1},M=/^\\s*<(\\w+|!)[^>]*>/,R=/^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/,z=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,Z=/^(?:body|html)$/i,q=/([A-Z])/g,H=[\"val\",\"css\",\"html\",\"text\",\"data\",\"width\",\"height\",\"offset\"],I=[\"after\",\"prepend\",\"before\",\"append\"],V=L.createElement(\"table\"),_=L.createElement(\"tr\"),B={tr:L.createElement(\"tbody\"),tbody:V,thead:V,tfoot:V,td:_,th:_,\"*\":L.createElement(\"div\")},U=/complete|loaded|interactive/,X=/^[\\w-]*$/,J={},W=J.toString,Y={},G=L.createElement(\"div\"),K={tabindex:\"tabIndex\",readonly:\"readOnly\",\"for\":\"htmlFor\",\"class\":\"className\",maxlength:\"maxLength\",cellspacing:\"cellSpacing\",cellpadding:\"cellPadding\",rowspan:\"rowSpan\",colspan:\"colSpan\",usemap:\"useMap\",frameborder:\"frameBorder\",contenteditable:\"contentEditable\"},Q=Array.isArray||function(t){return t instanceof Array};return Y.matches=function(t,e){if(!e||!t||1!==t.nodeType)return!1;var n=t.matches||t.webkitMatchesSelector||t.mozMatchesSelector||t.oMatchesSelector||t.matchesSelector;if(n)return n.call(t,e);var r,i=t.parentNode,o=!i;return o&&(i=G).appendChild(t),r=~Y.qsa(i,e).indexOf(t),o&&G.removeChild(t),r},C=function(t){return t.replace(/-+(.)?/g,function(t,e){return e?e.toUpperCase():\"\"})},N=function(t){return A.call(t,function(e,n){return t.indexOf(e)==n})},Y.fragment=function(t,e,n){var r,i,a;return R.test(t)&&(r=T(L.createElement(RegExp.$1))),r||(t.replace&&(t=t.replace(z,\"<$1></$2>\")),e===E&&(e=M.test(t)&&RegExp.$1),e in B||(e=\"*\"),a=B[e],a.innerHTML=\"\"+t,r=T.each(D.call(a.childNodes),function(){a.removeChild(this)})),o(n)&&(i=T(r),T.each(n,function(t,e){H.indexOf(t)>-1?i[t](e):i.attr(t,e)})),r},Y.Z=function(t,e){return new d(t,e)},Y.isZ=function(t){return t instanceof Y.Z},Y.init=function(t,n){var r;if(!t)return Y.Z();if(\"string\"==typeof t)if(t=t.trim(),\"<\"==t[0]&&M.test(t))r=Y.fragment(t,RegExp.$1,n),t=null;else{if(n!==E)return T(n).find(t);r=Y.qsa(L,t)}else{if(e(t))return T(L).ready(t);if(Y.isZ(t))return t;if(Q(t))r=s(t);else if(i(t))r=[t],t=null;else if(M.test(t))r=Y.fragment(t.trim(),RegExp.$1,n),t=null;else{if(n!==E)return T(n).find(t);r=Y.qsa(L,t)}}return Y.Z(r,t)},T=function(t,e){return Y.init(t,e)},T.extend=function(t){var e,n=D.call(arguments,1);return\"boolean\"==typeof t&&(e=t,t=n.shift()),n.forEach(function(n){m(t,n,e)}),t},Y.qsa=function(t,e){var n,r=\"#\"==e[0],i=!r&&\".\"==e[0],o=r||i?e.slice(1):e,a=X.test(o);return t.getElementById&&a&&r?(n=t.getElementById(o))?[n]:[]:1!==t.nodeType&&9!==t.nodeType&&11!==t.nodeType?[]:D.call(a&&!r&&t.getElementsByClassName?i?t.getElementsByClassName(o):t.getElementsByTagName(e):t.querySelectorAll(e))},T.contains=L.documentElement.contains?function(t,e){return t!==e&&t.contains(e)}:function(t,e){for(;e&&(e=e.parentNode);)if(e===t)return!0;return!1},T.type=t,T.isFunction=e,T.isWindow=n,T.isArray=Q,T.isPlainObject=o,T.isEmptyObject=function(t){var e;for(e in t)return!1;return!0},T.isNumeric=function(t){var e=Number(t),n=typeof t;return null!=t&&\"boolean\"!=n&&(\"string\"!=n||t.length)&&!isNaN(e)&&isFinite(e)||!1},T.inArray=function(t,e,n){return O.indexOf.call(e,t,n)},T.camelCase=C,T.trim=function(t){return null==t?\"\":String.prototype.trim.call(t)},T.uuid=0,T.support={},T.expr={},T.noop=function(){},T.map=function(t,e){var n,r,i,o=[];if(a(t))for(r=0;r<t.length;r++)n=e(t[r],r),null!=n&&o.push(n);else for(i in t)n=e(t[i],i),null!=n&&o.push(n);return u(o)},T.each=function(t,e){var n,r;if(a(t)){for(n=0;n<t.length;n++)if(e.call(t[n],n,t[n])===!1)return t}else for(r in t)if(e.call(t[r],r,t[r])===!1)return t;return t},T.grep=function(t,e){return A.call(t,e)},window.JSON&&(T.parseJSON=JSON.parse),T.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"),function(t,e){J[\"[object \"+e+\"]\"]=e.toLowerCase()}),T.fn={constructor:Y.Z,length:0,forEach:O.forEach,reduce:O.reduce,push:O.push,sort:O.sort,splice:O.splice,indexOf:O.indexOf,concat:function(){var t,e,n=[];for(t=0;t<arguments.length;t++)e=arguments[t],n[t]=Y.isZ(e)?e.toArray():e;return P.apply(Y.isZ(this)?this.toArray():this,n)},map:function(t){return T(T.map(this,function(e,n){return t.call(e,n,e)}))},slice:function(){return T(D.apply(this,arguments))},ready:function(t){return U.test(L.readyState)&&L.body?t(T):L.addEventListener(\"DOMContentLoaded\",function(){t(T)},!1),this},get:function(t){return t===E?D.call(this):this[t>=0?t:t+this.length]},toArray:function(){return this.get()},size:function(){return this.length},remove:function(){return this.each(function(){null!=this.parentNode&&this.parentNode.removeChild(this)})},each:function(t){return O.every.call(this,function(e,n){return t.call(e,n,e)!==!1}),this},filter:function(t){return e(t)?this.not(this.not(t)):T(A.call(this,function(e){return Y.matches(e,t)}))},add:function(t,e){return T(N(this.concat(T(t,e))))},is:function(t){return this.length>0&&Y.matches(this[0],t)},not:function(t){var n=[];if(e(t)&&t.call!==E)this.each(function(e){t.call(this,e)||n.push(this)});else{var r=\"string\"==typeof t?this.filter(t):a(t)&&e(t.item)?D.call(t):T(t);this.forEach(function(t){r.indexOf(t)<0&&n.push(t)})}return T(n)},has:function(t){return this.filter(function(){return i(t)?T.contains(this,t):T(this).find(t).size()})},eq:function(t){return t===-1?this.slice(t):this.slice(t,+t+1)},first:function(){var t=this[0];return t&&!i(t)?t:T(t)},last:function(){var t=this[this.length-1];return t&&!i(t)?t:T(t)},find:function(t){var e,n=this;return e=t?\"object\"==typeof t?T(t).filter(function(){var t=this;return O.some.call(n,function(e){return T.contains(e,t)})}):1==this.length?T(Y.qsa(this[0],t)):this.map(function(){return Y.qsa(this,t)}):T()},closest:function(t,e){var n=[],i=\"object\"==typeof t&&T(t);return this.each(function(o,a){for(;a&&!(i?i.indexOf(a)>=0:Y.matches(a,t));)a=a!==e&&!r(a)&&a.parentNode;a&&n.indexOf(a)<0&&n.push(a)}),T(n)},parents:function(t){for(var e=[],n=this;n.length>0;)n=T.map(n,function(t){if((t=t.parentNode)&&!r(t)&&e.indexOf(t)<0)return e.push(t),t});return v(e,t)},parent:function(t){return v(N(this.pluck(\"parentNode\")),t)},children:function(t){return v(this.map(function(){return p(this)}),t)},contents:function(){return this.map(function(){return this.contentDocument||D.call(this.childNodes)})},siblings:function(t){return v(this.map(function(t,e){return A.call(p(e.parentNode),function(t){return t!==e})}),t)},empty:function(){return this.each(function(){this.innerHTML=\"\"})},pluck:function(t){return T.map(this,function(e){return e[t]})},show:function(){return this.each(function(){\"none\"==this.style.display&&(this.style.display=\"\"),\"none\"==getComputedStyle(this,\"\").getPropertyValue(\"display\")&&(this.style.display=h(this.nodeName))})},replaceWith:function(t){return this.before(t).remove()},wrap:function(t){var n=e(t);if(this[0]&&!n)var r=T(t).get(0),i=r.parentNode||this.length>1;return this.each(function(e){T(this).wrapAll(n?t.call(this,e):i?r.cloneNode(!0):r)})},wrapAll:function(t){if(this[0]){T(this[0]).before(t=T(t));for(var e;(e=t.children()).length;)t=e.first();T(t).append(this)}return this},wrapInner:function(t){var n=e(t);return this.each(function(e){var r=T(this),i=r.contents(),o=n?t.call(this,e):t;i.length?i.wrapAll(o):r.append(o)})},unwrap:function(){return this.parent().each(function(){T(this).replaceWith(T(this).children())}),this},clone:function(){return this.map(function(){return this.cloneNode(!0)})},hide:function(){return this.css(\"display\",\"none\")},toggle:function(t){return this.each(function(){var e=T(this);(t===E?\"none\"==e.css(\"display\"):t)?e.show():e.hide()})},prev:function(t){return T(this.pluck(\"previousElementSibling\")).filter(t||\"*\")},next:function(t){return T(this.pluck(\"nextElementSibling\")).filter(t||\"*\")},html:function(t){return 0 in arguments?this.each(function(e){var n=this.innerHTML;T(this).empty().append(g(this,t,e,n))}):0 in this?this[0].innerHTML:null},text:function(t){return 0 in arguments?this.each(function(e){var n=g(this,t,e,this.textContent);this.textContent=null==n?\"\":\"\"+n}):0 in this?this.pluck(\"textContent\").join(\"\"):null},attr:function(t,e){var n;return\"string\"!=typeof t||1 in arguments?this.each(function(n){if(1===this.nodeType)if(i(t))for(j in t)y(this,j,t[j]);else y(this,t,g(this,e,n,this.getAttribute(t)))}):0 in this&&1==this[0].nodeType&&null!=(n=this[0].getAttribute(t))?n:E},removeAttr:function(t){return this.each(function(){1===this.nodeType&&t.split(\" \").forEach(function(t){y(this,t)},this)})},prop:function(t,e){return t=K[t]||t,1 in arguments?this.each(function(n){this[t]=g(this,e,n,this[t])}):this[0]&&this[0][t]},removeProp:function(t){return t=K[t]||t,this.each(function(){delete this[t]})},data:function(t,e){var n=\"data-\"+t.replace(q,\"-$1\").toLowerCase(),r=1 in arguments?this.attr(n,e):this.attr(n);return null!==r?b(r):E},val:function(t){return 0 in arguments?(null==t&&(t=\"\"),this.each(function(e){this.value=g(this,t,e,this.value)})):this[0]&&(this[0].multiple?T(this[0]).find(\"option\").filter(function(){return this.selected}).pluck(\"value\"):this[0].value)},offset:function(t){if(t)return this.each(function(e){var n=T(this),r=g(this,t,e,n.offset()),i=n.offsetParent().offset(),o={top:r.top-i.top,left:r.left-i.left};\"static\"==n.css(\"position\")&&(o.position=\"relative\"),n.css(o)});if(!this.length)return null;if(L.documentElement!==this[0]&&!T.contains(L.documentElement,this[0]))return{top:0,left:0};var e=this[0].getBoundingClientRect();return{left:e.left+window.pageXOffset,top:e.top+window.pageYOffset,width:Math.round(e.width),height:Math.round(e.height)}},css:function(e,n){if(arguments.length<2){var r=this[0];if(\"string\"==typeof e){if(!r)return;return r.style[C(e)]||getComputedStyle(r,\"\").getPropertyValue(e)}if(Q(e)){if(!r)return;var i={},o=getComputedStyle(r,\"\");return T.each(e,function(t,e){i[e]=r.style[C(e)]||o.getPropertyValue(e)}),i}}var a=\"\";if(\"string\"==t(e))n||0===n?a=c(e)+\":\"+f(e,n):this.each(function(){this.style.removeProperty(c(e))});else for(j in e)e[j]||0===e[j]?a+=c(j)+\":\"+f(j,e[j])+\";\":this.each(function(){this.style.removeProperty(c(j))});return this.each(function(){this.style.cssText+=\";\"+a})},index:function(t){return t?this.indexOf(T(t)[0]):this.parent().children().indexOf(this[0])},hasClass:function(t){return!!t&&O.some.call(this,function(t){return this.test(x(t))},l(t))},addClass:function(t){return t?this.each(function(e){if(\"className\"in this){S=[];var n=x(this),r=g(this,t,e,n);r.split(/\\s+/g).forEach(function(t){T(this).hasClass(t)||S.push(t)},this),S.length&&x(this,n+(n?\" \":\"\")+S.join(\" \"))}}):this},removeClass:function(t){return this.each(function(e){if(\"className\"in this){if(t===E)return x(this,\"\");S=x(this),g(this,t,e,S).split(/\\s+/g).forEach(function(t){S=S.replace(l(t),\" \")}),x(this,S.trim())}})},toggleClass:function(t,e){return t?this.each(function(n){var r=T(this),i=g(this,t,n,x(this));i.split(/\\s+/g).forEach(function(t){(e===E?!r.hasClass(t):e)?r.addClass(t):r.removeClass(t)})}):this},scrollTop:function(t){if(this.length){var e=\"scrollTop\"in this[0];return t===E?e?this[0].scrollTop:this[0].pageYOffset:this.each(e?function(){this.scrollTop=t}:function(){this.scrollTo(this.scrollX,t)})}},scrollLeft:function(t){if(this.length){var e=\"scrollLeft\"in this[0];return t===E?e?this[0].scrollLeft:this[0].pageXOffset:this.each(e?function(){this.scrollLeft=t}:function(){this.scrollTo(t,this.scrollY)})}},position:function(){if(this.length){var t=this[0],e=this.offsetParent(),n=this.offset(),r=Z.test(e[0].nodeName)?{top:0,left:0}:e.offset();return n.top-=parseFloat(T(t).css(\"margin-top\"))||0,n.left-=parseFloat(T(t).css(\"margin-left\"))||0,r.top+=parseFloat(T(e[0]).css(\"border-top-width\"))||0,r.left+=parseFloat(T(e[0]).css(\"border-left-width\"))||0,{top:n.top-r.top,left:n.left-r.left}}},offsetParent:function(){return this.map(function(){for(var t=this.offsetParent||L.body;t&&!Z.test(t.nodeName)&&\"static\"==T(t).css(\"position\");)t=t.offsetParent;return t})}},T.fn.detach=T.fn.remove,[\"width\",\"height\"].forEach(function(t){var e=t.replace(/./,function(t){return t[0].toUpperCase()});T.fn[t]=function(i){var o,a=this[0];return i===E?n(a)?a[\"inner\"+e]:r(a)?a.documentElement[\"scroll\"+e]:(o=this.offset())&&o[t]:this.each(function(e){a=T(this),a.css(t,g(this,i,e,a[t]()))})}}),I.forEach(function(e,n){var r=n%2;T.fn[e]=function(){var e,i,o=T.map(arguments,function(n){var r=[];return e=t(n),\"array\"==e?(n.forEach(function(t){return t.nodeType!==E?r.push(t):T.zepto.isZ(t)?r=r.concat(t.get()):void(r=r.concat(Y.fragment(t)))}),r):\"object\"==e||null==n?n:Y.fragment(n)}),a=this.length>1;return o.length<1?this:this.each(function(t,e){i=r?e:e.parentNode,e=0==n?e.nextSibling:1==n?e.firstChild:2==n?e:null;var s=T.contains(L.documentElement,i);o.forEach(function(t){if(a)t=t.cloneNode(!0);else if(!i)return T(t).remove();i.insertBefore(t,e),s&&w(t,function(t){if(!(null==t.nodeName||\"SCRIPT\"!==t.nodeName.toUpperCase()||t.type&&\"text/javascript\"!==t.type||t.src)){var e=t.ownerDocument?t.ownerDocument.defaultView:window;e.eval.call(e,t.innerHTML)}})})})},T.fn[r?e+\"To\":\"insert\"+(n?\"Before\":\"After\")]=function(t){return T(t)[e](this),this}}),Y.Z.prototype=d.prototype=T.fn,Y.uniq=N,Y.deserializeValue=b,T.zepto=Y,T}();!function(t){function e(t){return t._zid||(t._zid=h++)}function n(t,n,o,a){if(n=r(n),n.ns)var s=i(n.ns);return(v[e(t)]||[]).filter(function(t){return t&&(!n.e||t.e==n.e)&&(!n.ns||s.test(t.ns))&&(!o||e(t.fn)===e(o))&&(!a||t.sel==a)})}function r(t){var e=(\"\"+t).split(\".\");return{e:e[0],ns:e.slice(1).sort().join(\" \")}}function i(t){return new RegExp(\"(?:^| )\"+t.replace(\" \",\" .* ?\")+\"(?: |$)\")}function o(t,e){return t.del&&!y&&t.e in x||!!e}function a(t){return b[t]||y&&x[t]||t}function s(n,i,s,u,l,h,p){var d=e(n),m=v[d]||(v[d]=[]);i.split(/\\s/).forEach(function(e){if(\"ready\"==e)return t(document).ready(s);var i=r(e);i.fn=s,i.sel=l,i.e in b&&(s=function(e){var n=e.relatedTarget;if(!n||n!==this&&!t.contains(this,n))return i.fn.apply(this,arguments)}),i.del=h;var d=h||s;i.proxy=function(t){if(t=c(t),!t.isImmediatePropagationStopped()){t.data=u;var e=d.apply(n,t._args==f?[t]:[t].concat(t._args));return e===!1&&(t.preventDefault(),t.stopPropagation()),e}},i.i=m.length,m.push(i),\"addEventListener\"in n&&n.addEventListener(a(i.e),i.proxy,o(i,p))})}function u(t,r,i,s,u){var c=e(t);(r||\"\").split(/\\s/).forEach(function(e){n(t,e,i,s).forEach(function(e){delete v[c][e.i],\"removeEventListener\"in t&&t.removeEventListener(a(e.e),e.proxy,o(e,u))})})}function c(e,n){return!n&&e.isDefaultPrevented||(n||(n=e),t.each(T,function(t,r){var i=n[t];e[t]=function(){return this[r]=w,i&&i.apply(n,arguments)},e[r]=E}),e.timeStamp||(e.timeStamp=Date.now()),(n.defaultPrevented!==f?n.defaultPrevented:\"returnValue\"in n?n.returnValue===!1:n.getPreventDefault&&n.getPreventDefault())&&(e.isDefaultPrevented=w)),e}function l(t){var e,n={originalEvent:t};for(e in t)j.test(e)||t[e]===f||(n[e]=t[e]);return c(n,t)}var f,h=1,p=Array.prototype.slice,d=t.isFunction,m=function(t){return\"string\"==typeof t},v={},g={},y=\"onfocusin\"in window,x={focus:\"focusin\",blur:\"focusout\"},b={mouseenter:\"mouseover\",mouseleave:\"mouseout\"};g.click=g.mousedown=g.mouseup=g.mousemove=\"MouseEvents\",t.event={add:s,remove:u},t.proxy=function(n,r){var i=2 in arguments&&p.call(arguments,2);if(d(n)){var o=function(){return n.apply(r,i?i.concat(p.call(arguments)):arguments)};return o._zid=e(n),o}if(m(r))return i?(i.unshift(n[r],n),t.proxy.apply(null,i)):t.proxy(n[r],n);throw new TypeError(\"expected function\")},t.fn.bind=function(t,e,n){return this.on(t,e,n)},t.fn.unbind=function(t,e){return this.off(t,e)},t.fn.one=function(t,e,n,r){return this.on(t,e,n,r,1)};var w=function(){return!0},E=function(){return!1},j=/^([A-Z]|returnValue$|layer[XY]$|webkitMovement[XY]$)/,T={preventDefault:\"isDefaultPrevented\",stopImmediatePropagation:\"isImmediatePropagationStopped\",stopPropagation:\"isPropagationStopped\"};t.fn.delegate=function(t,e,n){return this.on(e,t,n)},t.fn.undelegate=function(t,e,n){return this.off(e,t,n)},t.fn.live=function(e,n){return t(document.body).delegate(this.selector,e,n),this},t.fn.die=function(e,n){return t(document.body).undelegate(this.selector,e,n),this},t.fn.on=function(e,n,r,i,o){var a,c,h=this;return e&&!m(e)?(t.each(e,function(t,e){h.on(t,n,r,e,o)}),h):(m(n)||d(i)||i===!1||(i=r,r=n,n=f),i!==f&&r!==!1||(i=r,r=f),i===!1&&(i=E),h.each(function(f,h){o&&(a=function(t){return u(h,t.type,i),i.apply(this,arguments)}),n&&(c=function(e){var r,o=t(e.target).closest(n,h).get(0);if(o&&o!==h)return r=t.extend(l(e),{currentTarget:o,liveFired:h}),(a||i).apply(o,[r].concat(p.call(arguments,1)))}),s(h,e,i,r,n,c||a)}))},t.fn.off=function(e,n,r){var i=this;return e&&!m(e)?(t.each(e,function(t,e){i.off(t,n,e)}),i):(m(n)||d(r)||r===!1||(r=n,n=f),r===!1&&(r=E),i.each(function(){u(this,e,r,n)}))},t.fn.trigger=function(e,n){return e=m(e)||t.isPlainObject(e)?t.Event(e):c(e),e._args=n,this.each(function(){e.type in x&&\"function\"==typeof this[e.type]?this[e.type]():\"dispatchEvent\"in this?this.dispatchEvent(e):t(this).triggerHandler(e,n)})},t.fn.triggerHandler=function(e,r){var i,o;return this.each(function(a,s){i=l(m(e)?t.Event(e):e),i._args=r,i.target=s,t.each(n(s,e.type||e),function(t,e){if(o=e.proxy(i),i.isImmediatePropagationStopped())return!1})}),o},\"focusin focusout focus blur load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select keydown keypress keyup error\".split(\" \").forEach(function(e){t.fn[e]=function(t){return 0 in arguments?this.bind(e,t):this.trigger(e)}}),t.Event=function(t,e){m(t)||(e=t,t=e.type);var n=document.createEvent(g[t]||\"Events\"),r=!0;if(e)for(var i in e)\"bubbles\"==i?r=!!e[i]:n[i]=e[i];return n.initEvent(t,r,!0),c(n)}}(e),function(t){function e(e,n,r){var i=t.Event(n);return t(e).trigger(i,r),!i.isDefaultPrevented()}function n(t,n,r,i){if(t.global)return e(n||x,r,i)}function r(e){e.global&&0===t.active++&&n(e,null,\"ajaxStart\")}function i(e){e.global&&!--t.active&&n(e,null,\"ajaxStop\")}function o(t,e){var r=e.context;return e.beforeSend.call(r,t,e)!==!1&&n(e,r,\"ajaxBeforeSend\",[t,e])!==!1&&void n(e,r,\"ajaxSend\",[t,e])}function a(t,e,r,i){var o=r.context,a=\"success\";r.success.call(o,t,a,e),i&&i.resolveWith(o,[t,a,e]),n(r,o,\"ajaxSuccess\",[e,r,t]),u(a,e,r)}function s(t,e,r,i,o){var a=i.context;i.error.call(a,r,e,t),o&&o.rejectWith(a,[r,e,t]),n(i,a,\"ajaxError\",[r,i,t||e]),u(e,r,i)}function u(t,e,r){var o=r.context;r.complete.call(o,e,t),n(r,o,\"ajaxComplete\",[e,r]),i(r)}function c(t,e,n){if(n.dataFilter==l)return t;var r=n.context;return n.dataFilter.call(r,t,e)}function l(){}function f(t){return t&&(t=t.split(\";\",2)[0]),t&&(t==T?\"html\":t==j?\"json\":w.test(t)?\"script\":E.test(t)&&\"xml\")||\"text\"}function h(t,e){return\"\"==e?t:(t+\"&\"+e).replace(/[&?]{1,2}/,\"?\")}function p(e){e.processData&&e.data&&\"string\"!=t.type(e.data)&&(e.data=t.param(e.data,e.traditional)),!e.data||e.type&&\"GET\"!=e.type.toUpperCase()&&\"jsonp\"!=e.dataType||(e.url=h(e.url,e.data),e.data=void 0)}function d(e,n,r,i){return t.isFunction(n)&&(i=r,r=n,n=void 0),t.isFunction(r)||(i=r,r=void 0),{url:e,data:n,success:r,dataType:i}}function m(e,n,r,i){var o,a=t.isArray(n),s=t.isPlainObject(n);t.each(n,function(n,u){o=t.type(u),i&&(n=r?i:i+\"[\"+(s||\"object\"==o||\"array\"==o?n:\"\")+\"]\"),!i&&a?e.add(u.name,u.value):\"array\"==o||!r&&\"object\"==o?m(e,u,r,n):e.add(n,u)})}var v,g,y=+new Date,x=window.document,b=/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi,w=/^(?:text|application)\\/javascript/i,E=/^(?:text|application)\\/xml/i,j=\"application/json\",T=\"text/html\",S=/^\\s*$/,C=x.createElement(\"a\");C.href=window.location.href,t.active=0,t.ajaxJSONP=function(e,n){if(!(\"type\"in e))return t.ajax(e);var r,i,u=e.jsonpCallback,c=(t.isFunction(u)?u():u)||\"Zepto\"+y++,l=x.createElement(\"script\"),f=window[c],h=function(e){t(l).triggerHandler(\"error\",e||\"abort\")},p={abort:h};return n&&n.promise(p),t(l).on(\"load error\",function(o,u){clearTimeout(i),t(l).off().remove(),\"error\"!=o.type&&r?a(r[0],p,e,n):s(null,u||\"error\",p,e,n),window[c]=f,r&&t.isFunction(f)&&f(r[0]),f=r=void 0}),o(p,e)===!1?(h(\"abort\"),p):(window[c]=function(){r=arguments},l.src=e.url.replace(/\\?(.+)=\\?/,\"?$1=\"+c),x.head.appendChild(l),e.timeout>0&&(i=setTimeout(function(){h(\"timeout\")},e.timeout)),p)},t.ajaxSettings={type:\"GET\",beforeSend:l,success:l,error:l,complete:l,context:null,global:!0,xhr:function(){return new window.XMLHttpRequest},accepts:{script:\"text/javascript, application/javascript, application/x-javascript\",json:j,xml:\"application/xml, text/xml\",html:T,text:\"text/plain\"},crossDomain:!1,timeout:0,processData:!0,cache:!0,dataFilter:l},t.ajax=function(e){var n,i,u=t.extend({},e||{}),d=t.Deferred&&t.Deferred();for(v in t.ajaxSettings)void 0===u[v]&&(u[v]=t.ajaxSettings[v]);r(u),u.crossDomain||(n=x.createElement(\"a\"),n.href=u.url,n.href=n.href,u.crossDomain=C.protocol+\"//\"+C.host!=n.protocol+\"//\"+n.host),u.url||(u.url=window.location.toString()),(i=u.url.indexOf(\"#\"))>-1&&(u.url=u.url.slice(0,i)),p(u);var m=u.dataType,y=/\\?.+=\\?/.test(u.url);if(y&&(m=\"jsonp\"),u.cache!==!1&&(e&&e.cache===!0||\"script\"!=m&&\"jsonp\"!=m)||(u.url=h(u.url,\"_=\"+Date.now())),\"jsonp\"==m)return y||(u.url=h(u.url,u.jsonp?u.jsonp+\"=?\":u.jsonp===!1?\"\":\"callback=?\")),t.ajaxJSONP(u,d);var b,w=u.accepts[m],E={},j=function(t,e){E[t.toLowerCase()]=[t,e]},T=/^([\\w-]+:)\\/\\//.test(u.url)?RegExp.$1:window.location.protocol,N=u.xhr(),O=N.setRequestHeader;if(d&&d.promise(N),u.crossDomain||j(\"X-Requested-With\",\"XMLHttpRequest\"),j(\"Accept\",w||\"*/*\"),(w=u.mimeType||w)&&(w.indexOf(\",\")>-1&&(w=w.split(\",\",2)[0]),N.overrideMimeType&&N.overrideMimeType(w)),(u.contentType||u.contentType!==!1&&u.data&&\"GET\"!=u.type.toUpperCase())&&j(\"Content-Type\",u.contentType||\"application/x-www-form-urlencoded\"),u.headers)for(g in u.headers)j(g,u.headers[g]);if(N.setRequestHeader=j,N.onreadystatechange=function(){if(4==N.readyState){N.onreadystatechange=l,clearTimeout(b);var e,n=!1;if(N.status>=200&&N.status<300||304==N.status||0==N.status&&\"file:\"==T){if(m=m||f(u.mimeType||N.getResponseHeader(\"content-type\")),\"arraybuffer\"==N.responseType||\"blob\"==N.responseType)e=N.response;else{e=N.responseText;try{e=c(e,m,u),\"script\"==m?(0,eval)(e):\"xml\"==m?e=N.responseXML:\"json\"==m&&(e=S.test(e)?null:t.parseJSON(e))}catch(r){n=r}if(n)return s(n,\"parsererror\",N,u,d)}a(e,N,u,d)}else s(N.statusText||null,N.status?\"error\":\"abort\",N,u,d)}},o(N,u)===!1)return N.abort(),s(null,\"abort\",N,u,d),N;var P=!(\"async\"in u)||u.async;if(N.open(u.type,u.url,P,u.username,u.password),u.xhrFields)for(g in u.xhrFields)N[g]=u.xhrFields[g];for(g in E)O.apply(N,E[g]);return u.timeout>0&&(b=setTimeout(function(){N.onreadystatechange=l,N.abort(),s(null,\"timeout\",N,u,d)},u.timeout)),N.send(u.data?u.data:null),N},t.get=function(){return t.ajax(d.apply(null,arguments))},t.post=function(){var e=d.apply(null,arguments);return e.type=\"POST\",t.ajax(e)},t.getJSON=function(){var e=d.apply(null,arguments);return e.dataType=\"json\",t.ajax(e)},t.fn.load=function(e,n,r){if(!this.length)return this;var i,o=this,a=e.split(/\\s/),s=d(e,n,r),u=s.success;return a.length>1&&(s.url=a[0],i=a[1]),s.success=function(e){o.html(i?t(\"<div>\").html(e.replace(b,\"\")).find(i):e),u&&u.apply(o,arguments)},t.ajax(s),this};var N=encodeURIComponent;t.param=function(e,n){var r=[];return r.add=function(e,n){t.isFunction(n)&&(n=n()),null==n&&(n=\"\"),this.push(N(e)+\"=\"+N(n))},m(r,e,n),r.join(\"&\").replace(/%20/g,\"+\")}}(e),function(t){t.fn.serializeArray=function(){var e,n,r=[],i=function(t){return t.forEach?t.forEach(i):void r.push({name:e,value:t})};return this[0]&&t.each(this[0].elements,function(r,o){n=o.type,e=o.name,e&&\"fieldset\"!=o.nodeName.toLowerCase()&&!o.disabled&&\"submit\"!=n&&\"reset\"!=n&&\"button\"!=n&&\"file\"!=n&&(\"radio\"!=n&&\"checkbox\"!=n||o.checked)&&i(t(o).val())}),r},t.fn.serialize=function(){var t=[];return this.serializeArray().forEach(function(e){t.push(encodeURIComponent(e.name)+\"=\"+encodeURIComponent(e.value))}),t.join(\"&\")},t.fn.submit=function(e){if(0 in arguments)this.bind(\"submit\",e);else if(this.length){var n=t.Event(\"submit\");this.eq(0).trigger(n),n.isDefaultPrevented()||this.get(0).submit()}return this}}(e),function(){try{getComputedStyle(void 0)}catch(t){var e=getComputedStyle;window.getComputedStyle=function(t,n){try{return e(t,n)}catch(r){return null}}}}(),t(\"zepto\",e)});layui.define([\"layer-mobile\",\"zepto\"],function(e){\"use strict\";var t=layui.zepto,a=layui[\"layer-mobile\"],i=(layui.device(),\"layui-upload-enter\"),n=\"layui-upload-iframe\",r={icon:2,shift:6},o={file:\"文件\",video:\"视频\",audio:\"音频\"};a.msg=function(e){return a.open({content:e||\"\",skin:\"msg\",time:2})};var s=function(e){this.options=e};s.prototype.init=function(){var e=this,a=e.options,r=t(\"body\"),s=t(a.elem||\".layui-upload-file\"),u=t('<iframe id=\"'+n+'\" class=\"'+n+'\" name=\"'+n+'\"></iframe>');return t(\"#\"+n)[0]||r.append(u),s.each(function(r,s){s=t(s);var u='<form target=\"'+n+'\" method=\"'+(a.method||\"post\")+'\" key=\"set-mine\" enctype=\"multipart/form-data\" action=\"'+(a.url||\"\")+'\"></form>',l=s.attr(\"lay-type\")||a.type;a.unwrap||(u='<div class=\"layui-box layui-upload-button\">'+u+'<span class=\"layui-upload-icon\"><i class=\"layui-icon\">&#xe608;</i>'+(s.attr(\"lay-title\")||a.title||\"上传\"+(o[l]||\"图片\"))+\"</span></div>\"),u=t(u),a.unwrap||u.on(\"dragover\",function(e){e.preventDefault(),t(this).addClass(i)}).on(\"dragleave\",function(){t(this).removeClass(i)}).on(\"drop\",function(){t(this).removeClass(i)}),s.parent(\"form\").attr(\"target\")===n&&(a.unwrap?s.unwrap():(s.parent().next().remove(),s.unwrap().unwrap())),s.wrap(u),s.off(\"change\").on(\"change\",function(){e.action(this,l)})})},s.prototype.action=function(e,i){var o=this,s=o.options,u=e.value,l=t(e),p=l.attr(\"lay-ext\")||s.ext||\"\";if(u){switch(i){case\"file\":if(p&&!RegExp(\"\\\\w\\\\.(\"+p+\")$\",\"i\").test(escape(u)))return a.msg(\"不支持该文件格式\",r),e.value=\"\";break;case\"video\":if(!RegExp(\"\\\\w\\\\.(\"+(p||\"avi|mp4|wma|rmvb|rm|flash|3gp|flv\")+\")$\",\"i\").test(escape(u)))return a.msg(\"不支持该视频格式\",r),e.value=\"\";break;case\"audio\":if(!RegExp(\"\\\\w\\\\.(\"+(p||\"mp3|wav|mid\")+\")$\",\"i\").test(escape(u)))return a.msg(\"不支持该音频格式\",r),e.value=\"\";break;default:if(!RegExp(\"\\\\w\\\\.(\"+(p||\"jpg|png|gif|bmp|jpeg\")+\")$\",\"i\").test(escape(u)))return a.msg(\"不支持该图片格式\",r),e.value=\"\"}s.before&&s.before(e),l.parent().submit();var c=t(\"#\"+n),f=setInterval(function(){var t;try{t=c.contents().find(\"body\").text()}catch(i){a.msg(\"上传接口存在跨域\",r),clearInterval(f)}if(t){clearInterval(f),c.contents().find(\"body\").html(\"\");try{t=JSON.parse(t)}catch(i){return t={},a.msg(\"请对上传接口返回JSON字符\",r)}\"function\"==typeof s.success&&s.success(t,e)}},30);e.value=\"\"}},e(\"upload-mobile\",function(e){var t=new s(e=e||{});t.init()})});layui.define(function(i){i(\"layim-mobile\",layui.v)});layui[\"layui.mobile\"]||layui.config({base:layui.cache.dir+\"lay/modules/mobile/\"}).extend({\"layer-mobile\":\"layer-mobile\",zepto:\"zepto\",\"upload-mobile\":\"upload-mobile\",\"layim-mobile\":\"layim-mobile\"}),layui.define([\"layer-mobile\",\"zepto\",\"layim-mobile\"],function(l){l(\"mobile\",{layer:layui[\"layer-mobile\"],layim:layui[\"layim-mobile\"]})});"
  },
  {
    "path": "public/layui/lay/modules/rate.js",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n ;layui.define(\"jquery\",function(e){\"use strict\";var a=layui.jquery,i={config:{},index:layui.rate?layui.rate.index+1e4:0,set:function(e){var i=this;return i.config=a.extend({},i.config,e),i},on:function(e,a){return layui.onevent.call(this,n,e,a)}},l=function(){var e=this,a=e.config;return{setvalue:function(a){e.setvalue.call(e,a)},config:a}},n=\"rate\",t=\"layui-rate\",o=\"layui-icon-rate\",s=\"layui-icon-rate-solid\",u=\"layui-icon-rate-half\",r=\"layui-icon-rate-solid layui-icon-rate-half\",c=\"layui-icon-rate-solid layui-icon-rate\",f=\"layui-icon-rate layui-icon-rate-half\",v=function(e){var l=this;l.index=++i.index,l.config=a.extend({},l.config,i.config,e),l.render()};v.prototype.config={length:5,text:!1,readonly:!1,half:!1,value:0,theme:\"\"},v.prototype.render=function(){var e=this,i=e.config,l=i.theme?'style=\"color: '+i.theme+';\"':\"\";i.elem=a(i.elem),parseInt(i.value)!==i.value&&(i.half||(i.value=Math.ceil(i.value)-i.value<.5?Math.ceil(i.value):Math.floor(i.value)));for(var n='<ul class=\"layui-rate\" '+(i.readonly?\"readonly\":\"\")+\">\",u=1;u<=i.length;u++){var r='<li class=\"layui-inline\"><i class=\"layui-icon '+(u>Math.floor(i.value)?o:s)+'\" '+l+\"></i></li>\";i.half&&parseInt(i.value)!==i.value&&u==Math.ceil(i.value)?n=n+'<li><i class=\"layui-icon layui-icon-rate-half\" '+l+\"></i></li>\":n+=r}n+=\"</ul>\"+(i.text?'<span class=\"layui-inline\">'+i.value+\"星\":\"\")+\"</span>\";var c=i.elem,f=c.next(\".\"+t);f[0]&&f.remove(),e.elemTemp=a(n),i.span=e.elemTemp.next(\"span\"),i.setText&&i.setText(i.value),c.html(e.elemTemp),c.addClass(\"layui-inline\"),i.readonly||e.action()},v.prototype.setvalue=function(e){var a=this,i=a.config;i.value=e,a.render()},v.prototype.action=function(){var e=this,i=e.config,l=e.elemTemp,n=l.find(\"i\").width();l.children(\"li\").each(function(e){var t=e+1,v=a(this);v.on(\"click\",function(e){if(i.value=t,i.half){var o=e.pageX-a(this).offset().left;o<=n/2&&(i.value=i.value-.5)}i.text&&l.next(\"span\").text(i.value+\"星\"),i.choose&&i.choose(i.value),i.setText&&i.setText(i.value)}),v.on(\"mousemove\",function(e){if(l.find(\"i\").each(function(){a(this).addClass(o).removeClass(r)}),l.find(\"i:lt(\"+t+\")\").each(function(){a(this).addClass(s).removeClass(f)}),i.half){var c=e.pageX-a(this).offset().left;c<=n/2&&v.children(\"i\").addClass(u).removeClass(s)}}),v.on(\"mouseleave\",function(){l.find(\"i\").each(function(){a(this).addClass(o).removeClass(r)}),l.find(\"i:lt(\"+Math.floor(i.value)+\")\").each(function(){a(this).addClass(s).removeClass(f)}),i.half&&parseInt(i.value)!==i.value&&l.children(\"li:eq(\"+Math.floor(i.value)+\")\").children(\"i\").addClass(u).removeClass(c)})})},v.prototype.events=function(){var e=this;e.config},i.render=function(e){var a=new v(e);return l.call(a)},e(n,i)});"
  },
  {
    "path": "public/layui/lay/modules/table.js",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n ;layui.define([\"laytpl\",\"laypage\",\"layer\",\"form\"],function(e){\"use strict\";var t=layui.$,i=layui.laytpl,a=layui.laypage,l=layui.layer,n=layui.form,o=layui.hint(),r=layui.device(),d={config:{checkName:\"LAY_CHECKED\",indexName:\"LAY_TABLE_INDEX\"},cache:{},index:layui.table?layui.table.index+1e4:0,set:function(e){var i=this;return i.config=t.extend({},i.config,e),i},on:function(e,t){return layui.onevent.call(this,s,e,t)}},c=function(){var e=this,t=e.config,i=t.id;return i&&(c.config[i]=t),{reload:function(t){e.reload.call(e,t)},config:t}},s=\"table\",u=\".layui-table\",h=\"layui-hide\",f=\"layui-none\",y=\"layui-table-view\",p=\".layui-table-header\",m=\".layui-table-body\",v=\".layui-table-main\",g=\".layui-table-fixed\",x=\".layui-table-fixed-l\",b=\".layui-table-fixed-r\",k=\".layui-table-tool\",C=\".layui-table-page\",w=\".layui-table-sort\",N=\"layui-table-edit\",T=\"layui-table-hover\",F=function(e){var t='{{#if(item2.colspan){}} colspan=\"{{item2.colspan}}\"{{#} if(item2.rowspan){}} rowspan=\"{{item2.rowspan}}\"{{#}}}';return e=e||{},['<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" class=\"layui-table\" ','{{# if(d.data.skin){ }}lay-skin=\"{{d.data.skin}}\"{{# } }} {{# if(d.data.size){ }}lay-size=\"{{d.data.size}}\"{{# } }} {{# if(d.data.even){ }}lay-even{{# } }}>',\"<thead>\",\"{{# layui.each(d.data.cols, function(i1, item1){ }}\",\"<tr>\",\"{{# layui.each(item1, function(i2, item2){ }}\",'{{# if(item2.fixed && item2.fixed !== \"right\"){ left = true; } }}','{{# if(item2.fixed === \"right\"){ right = true; } }}',function(){return e.fixed&&\"right\"!==e.fixed?'{{# if(item2.fixed && item2.fixed !== \"right\"){ }}':\"right\"===e.fixed?'{{# if(item2.fixed === \"right\"){ }}':\"\"}(),'<th data-field=\"{{ item2.field||i2 }}\" {{# if(item2.minWidth){ }}data-minwidth=\"{{item2.minWidth}}\"{{# } }} '+t+' {{# if(item2.unresize){ }}data-unresize=\"true\"{{# } }}>','<div class=\"layui-table-cell laytable-cell-',\"{{# if(item2.colspan > 1){ }}\",\"group\",\"{{# } else { }}\",\"{{d.index}}-{{item2.field || i2}}\",'{{# if(item2.type !== \"normal\"){ }}',\" laytable-cell-{{ item2.type }}\",\"{{# } }}\",\"{{# } }}\",'\" {{#if(item2.align){}}align=\"{{item2.align}}\"{{#}}}>','{{# if(item2.type === \"checkbox\"){ }}','<input type=\"checkbox\" name=\"layTableCheckbox\" lay-skin=\"primary\" lay-filter=\"layTableAllChoose\" {{# if(item2[d.data.checkName]){ }}checked{{# }; }}>',\"{{# } else { }}\",'<span>{{item2.title||\"\"}}</span>',\"{{# if(!(item2.colspan > 1) && item2.sort){ }}\",'<span class=\"layui-table-sort layui-inline\"><i class=\"layui-edge layui-table-sort-asc\"></i><i class=\"layui-edge layui-table-sort-desc\"></i></span>',\"{{# } }}\",\"{{# } }}\",\"</div>\",\"</th>\",e.fixed?\"{{# }; }}\":\"\",\"{{# }); }}\",\"</tr>\",\"{{# }); }}\",\"</thead>\",\"</table>\"].join(\"\")},W=['<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" class=\"layui-table\" ','{{# if(d.data.skin){ }}lay-skin=\"{{d.data.skin}}\"{{# } }} {{# if(d.data.size){ }}lay-size=\"{{d.data.size}}\"{{# } }} {{# if(d.data.even){ }}lay-even{{# } }}>',\"<tbody></tbody>\",\"</table>\"].join(\"\"),z=['<div class=\"layui-form layui-border-box {{d.VIEW_CLASS}}\" lay-filter=\"LAY-table-{{d.index}}\" style=\"{{# if(d.data.width){ }}width:{{d.data.width}}px;{{# } }} {{# if(d.data.height){ }}height:{{d.data.height}}px;{{# } }}\">',\"{{# if(d.data.toolbar){ }}\",'<div class=\"layui-table-tool\"></div>',\"{{# } }}\",'<div class=\"layui-table-box\">',\"{{# var left, right; }}\",'<div class=\"layui-table-header\">',F(),\"</div>\",'<div class=\"layui-table-body layui-table-main\">',W,\"</div>\",\"{{# if(left){ }}\",'<div class=\"layui-table-fixed layui-table-fixed-l\">','<div class=\"layui-table-header\">',F({fixed:!0}),\"</div>\",'<div class=\"layui-table-body\">',W,\"</div>\",\"</div>\",\"{{# }; }}\",\"{{# if(right){ }}\",'<div class=\"layui-table-fixed layui-table-fixed-r\">','<div class=\"layui-table-header\">',F({fixed:\"right\"}),'<div class=\"layui-table-mend\"></div>',\"</div>\",'<div class=\"layui-table-body\">',W,\"</div>\",\"</div>\",\"{{# }; }}\",\"</div>\",\"{{# if(d.data.page){ }}\",'<div class=\"layui-table-page\">','<div id=\"layui-table-page{{d.index}}\"></div>',\"</div>\",\"{{# } }}\",\"<style>\",\"{{# layui.each(d.data.cols, function(i1, item1){\",\"layui.each(item1, function(i2, item2){ }}\",\".laytable-cell-{{d.index}}-{{item2.field||i2}}{ \",\"{{# if(item2.width){ }}\",\"width: {{item2.width}}px;\",\"{{# } }}\",\" }\",\"{{# });\",\"}); }}\",\"</style>\",\"</div>\"].join(\"\"),A=t(window),S=t(document),M=function(e){var i=this;i.index=++d.index,i.config=t.extend({},i.config,d.config,e),i.render()};M.prototype.config={limit:10,loading:!0,cellMinWidth:60,text:{none:\"无数据\"}},M.prototype.render=function(){var e=this,a=e.config;if(a.elem=t(a.elem),a.where=a.where||{},a.id=a.id||a.elem.attr(\"id\"),a.request=t.extend({pageName:\"page\",limitName:\"limit\"},a.request),a.response=t.extend({statusName:\"code\",statusCode:0,msgName:\"msg\",dataName:\"data\",countName:\"count\"},a.response),\"object\"==typeof a.page&&(a.limit=a.page.limit||a.limit,a.limits=a.page.limits||a.limits,e.page=a.page.curr=a.page.curr||1,delete a.page.elem,delete a.page.jump),!a.elem[0])return e;e.setArea();var l=a.elem,n=l.next(\".\"+y),o=e.elem=t(i(z).render({VIEW_CLASS:y,data:a,index:e.index}));if(a.index=e.index,n[0]&&n.remove(),l.after(o),e.layHeader=o.find(p),e.layMain=o.find(v),e.layBody=o.find(m),e.layFixed=o.find(g),e.layFixLeft=o.find(x),e.layFixRight=o.find(b),e.layTool=o.find(k),e.layPage=o.find(C),e.layTool.html(i(t(a.toolbar).html()||\"\").render(a)),a.height&&e.fullSize(),a.cols.length>1){var r=e.layFixed.find(p).find(\"th\");r.height(e.layHeader.height()-1-parseFloat(r.css(\"padding-top\"))-parseFloat(r.css(\"padding-bottom\")))}e.pullData(e.page),e.events()},M.prototype.initOpts=function(e){var t=this,i=(t.config,{checkbox:48,space:15,numbers:40});e.checkbox&&(e.type=\"checkbox\"),e.space&&(e.type=\"space\"),e.type||(e.type=\"normal\"),\"normal\"!==e.type&&(e.unresize=!0,e.width=e.width||i[e.type])},M.prototype.setArea=function(){var e=this,t=e.config,i=0,a=0,l=0,n=0,o=t.width||function(){var e=function(i){var a,l;i=i||t.elem.parent(),a=i.width();try{l=\"none\"===i.css(\"display\")}catch(n){}return!i[0]||a&&!l?a:e(i.parent())};return e()}();e.eachCols(function(){i++}),o-=function(){return\"line\"===t.skin||\"nob\"===t.skin?2:i+1}(),layui.each(t.cols,function(t,i){layui.each(i,function(t,l){var r;return l?(e.initOpts(l),r=l.width||0,void(l.colspan>1||(/\\d+%$/.test(r)?l.width=r=Math.floor(parseFloat(r)/100*o):r||(l.width=r=0,a++),n+=r))):void i.splice(t,1)})}),e.autoColNums=a,o>n&&a&&(l=(o-n)/a),layui.each(t.cols,function(e,i){layui.each(i,function(e,i){var a=i.minWidth||t.cellMinWidth;i.colspan>1||0===i.width&&(i.width=Math.floor(l>=a?l:a))})}),t.height&&/^full-\\d+$/.test(t.height)&&(e.fullHeightGap=t.height.split(\"-\")[1],t.height=A.height()-e.fullHeightGap)},M.prototype.reload=function(e){var i=this;i.config.data&&i.config.data.constructor===Array&&delete i.config.data,i.config=t.extend({},i.config,e),i.render()},M.prototype.page=1,M.prototype.pullData=function(e,i){var a=this,n=a.config,o=n.request,r=n.response,d=function(){\"object\"==typeof n.initSort&&a.sort(n.initSort.field,n.initSort.type)};if(a.startTime=(new Date).getTime(),n.url){var c={};c[o.pageName]=e,c[o.limitName]=n.limit;var s=t.extend(c,n.where);n.contentType&&0==n.contentType.indexOf(\"application/json\")&&(s=JSON.stringify(s)),t.ajax({type:n.method||\"get\",url:n.url,contentType:n.contentType,data:s,dataType:\"json\",headers:n.headers||{},success:function(t){t[r.statusName]!=r.statusCode?(a.renderForm(),a.layMain.html('<div class=\"'+f+'\">'+(t[r.msgName]||\"返回的数据状态异常\")+\"</div>\")):(a.renderData(t,e,t[r.countName]),d(),n.time=(new Date).getTime()-a.startTime+\" ms\"),i&&l.close(i),\"function\"==typeof n.done&&n.done(t,e,t[r.countName])},error:function(e,t){a.layMain.html('<div class=\"'+f+'\">数据接口请求异常</div>'),a.renderForm(),i&&l.close(i)}})}else if(n.data&&n.data.constructor===Array){var u={},h=e*n.limit-n.limit;u[r.dataName]=n.data.concat().splice(h,n.limit),u[r.countName]=n.data.length,a.renderData(u,e,n.data.length),d(),\"function\"==typeof n.done&&n.done(u,e,u[r.countName])}},M.prototype.eachCols=function(e){var i=t.extend(!0,[],this.config.cols),a=[],l=0;layui.each(i,function(e,t){layui.each(t,function(t,n){if(n.colspan>1){var o=0;l++,n.CHILD_COLS=[],layui.each(i[e+1],function(e,t){t.PARENT_COL||o==n.colspan||(t.PARENT_COL=l,n.CHILD_COLS.push(t),o+=t.colspan>1?t.colspan:1)})}n.PARENT_COL||a.push(n)})});var n=function(t){layui.each(t||a,function(t,i){return i.CHILD_COLS?n(i.CHILD_COLS):void e(t,i)})};n()},M.prototype.renderData=function(e,n,o,r){var c=this,s=c.config,u=e[s.response.dataName]||[],y=[],p=[],m=[],v=function(){return!r&&c.sortKey?c.sort(c.sortKey.field,c.sortKey.sort,!0):(layui.each(u,function(e,a){var l=[],o=[],u=[],h=e+s.limit*(n-1)+1;0!==a.length&&(r||(a[d.config.indexName]=e),c.eachCols(function(e,n){var r=n.field||e,f=a[r];c.getColElem(c.layHeader,r);if(void 0!==f&&null!==f||(f=\"\"),!(n.colspan>1)){var y=['<td data-field=\"'+r+'\" '+function(){var e=[];return n.edit&&e.push('data-edit=\"'+n.edit+'\"'),n.align&&e.push('align=\"'+n.align+'\"'),n.templet&&e.push('data-content=\"'+f+'\"'),n.toolbar&&e.push('data-off=\"true\"'),n.event&&e.push('lay-event=\"'+n.event+'\"'),n.style&&e.push('style=\"'+n.style+'\"'),n.minWidth&&e.push('data-minwidth=\"'+n.minWidth+'\"'),e.join(\" \")}()+\">\",'<div class=\"layui-table-cell laytable-cell-'+function(){var e=s.index+\"-\"+r;return\"normal\"===n.type?e:e+\" laytable-cell-\"+n.type}()+'\">'+function(){var e=t.extend(!0,{LAY_INDEX:h},a);return\"checkbox\"===n.type?'<input type=\"checkbox\" name=\"layTableCheckbox\" lay-skin=\"primary\" '+function(){var t=d.config.checkName;return n[t]?(a[t]=n[t],n[t]?\"checked\":\"\"):e[t]?\"checked\":\"\"}()+\">\":\"numbers\"===n.type?h:n.toolbar?i(t(n.toolbar).html()||\"\").render(e):n.templet?function(){return\"function\"==typeof n.templet?n.templet(e):i(t(n.templet).html()||String(f)).render(e)}():f}(),\"</div></td>\"].join(\"\");l.push(y),n.fixed&&\"right\"!==n.fixed&&o.push(y),\"right\"===n.fixed&&u.push(y)}}),y.push('<tr data-index=\"'+e+'\">'+l.join(\"\")+\"</tr>\"),p.push('<tr data-index=\"'+e+'\">'+o.join(\"\")+\"</tr>\"),m.push('<tr data-index=\"'+e+'\">'+u.join(\"\")+\"</tr>\"))}),c.layBody.scrollTop(0),c.layMain.find(\".\"+f).remove(),c.layMain.find(\"tbody\").html(y.join(\"\")),c.layFixLeft.find(\"tbody\").html(p.join(\"\")),c.layFixRight.find(\"tbody\").html(m.join(\"\")),c.renderForm(),c.syncCheckAll(),c.haveInit?c.scrollPatch():setTimeout(function(){c.scrollPatch()},50),c.haveInit=!0,void l.close(c.tipsIndex))};return c.key=s.id||s.index,d.cache[c.key]=u,c.layPage[0===u.length&&1==n?\"addClass\":\"removeClass\"](h),r?v():0===u.length?(c.renderForm(),c.layFixed.remove(),c.layMain.find(\"tbody\").html(\"\"),c.layMain.find(\".\"+f).remove(),c.layMain.append('<div class=\"'+f+'\">'+s.text.none+\"</div>\")):(v(),void(s.page&&(s.page=t.extend({elem:\"layui-table-page\"+s.index,count:o,limit:s.limit,limits:s.limits||[10,20,30,40,50,60,70,80,90],groups:3,layout:[\"prev\",\"page\",\"next\",\"skip\",\"count\",\"limit\"],prev:'<i class=\"layui-icon\">&#xe603;</i>',next:'<i class=\"layui-icon\">&#xe602;</i>',jump:function(e,t){t||(c.page=e.curr,s.limit=e.limit,c.pullData(e.curr,c.loading()))}},s.page),s.page.count=o,a.render(s.page))))},M.prototype.getColElem=function(e,t){var i=this,a=i.config;return e.eq(0).find(\".laytable-cell-\"+(a.index+\"-\"+t)+\":eq(0)\")},M.prototype.renderForm=function(e){n.render(e,\"LAY-table-\"+this.index)},M.prototype.sort=function(e,i,a,l){var n,r,c=this,u={},h=c.config,f=h.elem.attr(\"lay-filter\"),y=d.cache[c.key];\"string\"==typeof e&&c.layHeader.find(\"th\").each(function(i,a){var l=t(this),o=l.data(\"field\");if(o===e)return e=l,n=o,!1});try{var n=n||e.data(\"field\");if(c.sortKey&&!a&&n===c.sortKey.field&&i===c.sortKey.sort)return;var p=c.layHeader.find(\"th .laytable-cell-\"+h.index+\"-\"+n).find(w);c.layHeader.find(\"th\").find(w).removeAttr(\"lay-sort\"),p.attr(\"lay-sort\",i||null),c.layFixed.find(\"th\")}catch(m){return o.error(\"Table modules: Did not match to field\")}c.sortKey={field:n,sort:i},\"asc\"===i?r=layui.sort(y,n):\"desc\"===i?r=layui.sort(y,n,!0):(r=layui.sort(y,d.config.indexName),delete c.sortKey),u[h.response.dataName]=r,c.renderData(u,c.page,c.count,!0),l&&layui.event.call(e,s,\"sort(\"+f+\")\",{field:n,type:i})},M.prototype.loading=function(){var e=this,t=e.config;if(t.loading&&t.url)return l.msg(\"数据请求中\",{icon:16,offset:[e.elem.offset().top+e.elem.height()/2-35-A.scrollTop()+\"px\",e.elem.offset().left+e.elem.width()/2-90-A.scrollLeft()+\"px\"],time:-1,anim:-1,fixed:!1})},M.prototype.setCheckData=function(e,t){var i=this,a=i.config,l=d.cache[i.key];l[e]&&l[e].constructor!==Array&&(l[e][a.checkName]=t)},M.prototype.syncCheckAll=function(){var e=this,t=e.config,i=e.layHeader.find('input[name=\"layTableCheckbox\"]'),a=function(i){return e.eachCols(function(e,a){\"checkbox\"===a.type&&(a[t.checkName]=i)}),i};i[0]&&(d.checkStatus(e.key).isAll?(i[0].checked||(i.prop(\"checked\",!0),e.renderForm(\"checkbox\")),a(!0)):(i[0].checked&&(i.prop(\"checked\",!1),e.renderForm(\"checkbox\")),a(!1)))},M.prototype.getCssRule=function(e,t){var i=this,a=i.elem.find(\"style\")[0],l=a.sheet||a.styleSheet||{},n=l.cssRules||l.rules;layui.each(n,function(a,l){if(l.selectorText===\".laytable-cell-\"+i.index+\"-\"+e)return t(l),!0})},M.prototype.fullSize=function(){var e,t=this,i=t.config,a=i.height;t.fullHeightGap&&(a=A.height()-t.fullHeightGap,a<135&&(a=135),t.elem.css(\"height\",a)),e=parseFloat(a)-parseFloat(t.layHeader.height())-1,i.toolbar&&(e-=t.layTool.outerHeight()),i.page&&(e=e-t.layPage.outerHeight()-1),t.layMain.css(\"height\",e)},M.prototype.getScrollWidth=function(e){var t=0;return e?t=e.offsetWidth-e.clientWidth:(e=document.createElement(\"div\"),e.style.width=\"100px\",e.style.height=\"100px\",e.style.overflowY=\"scroll\",document.body.appendChild(e),t=e.offsetWidth-e.clientWidth,document.body.removeChild(e)),t},M.prototype.scrollPatch=function(){var e=this,i=e.layMain.children(\"table\"),a=e.layMain.width()-e.layMain.prop(\"clientWidth\"),l=e.layMain.height()-e.layMain.prop(\"clientHeight\"),n=e.getScrollWidth(e.layMain[0]),o=i.outerWidth()-e.layMain.width();if(e.autoColNums&&o<5&&!e.scrollPatchWStatus){var r=e.layHeader.eq(0).find(\"thead th:last-child\"),d=r.data(\"field\");e.getCssRule(d,function(t){var i=t.style.width||r.outerWidth();t.style.width=parseFloat(i)-n-o+\"px\",e.layMain.height()-e.layMain.prop(\"clientHeight\")>0&&(t.style.width=parseFloat(t.style.width)-1+\"px\"),e.scrollPatchWStatus=!0})}if(a&&l){if(!e.elem.find(\".layui-table-patch\")[0]){var c=t('<th class=\"layui-table-patch\"><div class=\"layui-table-cell\"></div></th>');c.find(\"div\").css({width:a}),e.layHeader.eq(0).find(\"thead tr\").append(c)}}else e.layHeader.eq(0).find(\".layui-table-patch\").remove();var s=e.layMain.height(),u=s-l;e.layFixed.find(m).css(\"height\",i.height()>u?u:\"auto\"),e.layFixRight[o>0?\"removeClass\":\"addClass\"](h),e.layFixRight.css(\"right\",a-1)},M.prototype.events=function(){var e,a=this,n=a.config,o=t(\"body\"),c={},u=a.layHeader.find(\"th\"),h=\".layui-table-cell\",f=n.elem.attr(\"lay-filter\");u.on(\"mousemove\",function(e){var i=t(this),a=i.offset().left,l=e.clientX-a;i.attr(\"colspan\")>1||i.data(\"unresize\")||c.resizeStart||(c.allowResize=i.width()-l<=10,o.css(\"cursor\",c.allowResize?\"col-resize\":\"\"))}).on(\"mouseleave\",function(){t(this);c.resizeStart||o.css(\"cursor\",\"\")}).on(\"mousedown\",function(e){var i=t(this);if(c.allowResize){var l=i.data(\"field\");e.preventDefault(),c.resizeStart=!0,c.offset=[e.clientX,e.clientY],a.getCssRule(l,function(e){var t=e.style.width||i.outerWidth();c.rule=e,c.ruleWidth=parseFloat(t),c.minWidth=i.data(\"minwidth\")||n.cellMinWidth})}}),S.on(\"mousemove\",function(t){if(c.resizeStart){if(t.preventDefault(),c.rule){var i=c.ruleWidth+t.clientX-c.offset[0];i<c.minWidth&&(i=c.minWidth),c.rule.style.width=i+\"px\",l.close(a.tipsIndex)}e=1}}).on(\"mouseup\",function(t){c.resizeStart&&(c={},o.css(\"cursor\",\"\"),a.scrollPatch()),2===e&&(e=null)}),u.on(\"click\",function(){var i,l=t(this),n=l.find(w),o=n.attr(\"lay-sort\");return n[0]&&1!==e?(i=\"asc\"===o?\"desc\":\"desc\"===o?null:\"asc\",void a.sort(l,i,null,!0)):e=2}).find(w+\" .layui-edge \").on(\"click\",function(e){var i=t(this),l=i.index(),n=i.parents(\"th\").eq(0).data(\"field\");layui.stope(e),0===l?a.sort(n,\"asc\",null,!0):a.sort(n,\"desc\",null,!0)}),a.elem.on(\"click\",'input[name=\"layTableCheckbox\"]+',function(){var e=t(this).prev(),i=a.layBody.find('input[name=\"layTableCheckbox\"]'),l=e.parents(\"tr\").eq(0).data(\"index\"),n=e[0].checked,o=\"layTableAllChoose\"===e.attr(\"lay-filter\");o?(i.each(function(e,t){t.checked=n,a.setCheckData(e,n)}),a.syncCheckAll(),a.renderForm(\"checkbox\")):(a.setCheckData(l,n),a.syncCheckAll()),layui.event.call(this,s,\"checkbox(\"+f+\")\",{checked:n,data:d.cache[a.key]?d.cache[a.key][l]||{}:{},type:o?\"all\":\"one\"})}),a.layBody.on(\"mouseenter\",\"tr\",function(){var e=t(this),i=e.index();a.layBody.find(\"tr:eq(\"+i+\")\").addClass(T)}).on(\"mouseleave\",\"tr\",function(){var e=t(this),i=e.index();a.layBody.find(\"tr:eq(\"+i+\")\").removeClass(T)}),a.layBody.on(\"change\",\".\"+N,function(){var e=t(this),i=this.value,l=e.parent().data(\"field\"),n=e.parents(\"tr\").eq(0).data(\"index\"),o=d.cache[a.key][n];o[l]=i,layui.event.call(this,s,\"edit(\"+f+\")\",{value:i,data:o,field:l})}).on(\"blur\",\".\"+N,function(){var e,l=t(this),n=l.parent().data(\"field\"),o=l.parents(\"tr\").eq(0).data(\"index\"),r=d.cache[a.key][o];a.eachCols(function(t,i){i.field==n&&i.templet&&(e=i.templet)}),l.siblings(h).html(e?i(t(e).html()||this.value).render(r):this.value),l.parent().data(\"content\",this.value),l.remove()}),a.layBody.on(\"click\",\"td\",function(){var e=t(this),i=(e.data(\"field\"),e.data(\"edit\")),o=e.children(h);if(l.close(a.tipsIndex),!e.data(\"off\"))if(i)if(\"select\"===i);else{var d=t('<input class=\"layui-input '+N+'\">');d[0].value=e.data(\"content\")||o.text(),e.find(\".\"+N)[0]||e.append(d),d.focus()}else o.find(\".layui-form-switch,.layui-form-checkbox\")[0]||Math.round(o.prop(\"scrollWidth\"))>Math.round(o.outerWidth())&&(a.tipsIndex=l.tips(['<div class=\"layui-table-tips-main\" style=\"margin-top: -'+(o.height()+16)+\"px;\"+function(){return\"sm\"===n.size?\"padding: 4px 15px; font-size: 12px;\":\"lg\"===n.size?\"padding: 14px 15px;\":\"\"}()+'\">',o.html(),\"</div>\",'<i class=\"layui-icon layui-table-tips-c\">&#x1006;</i>'].join(\"\"),o[0],{tips:[3,\"\"],time:-1,anim:-1,maxWidth:r.ios||r.android?300:600,isOutAnim:!1,skin:\"layui-table-tips\",success:function(e,t){e.find(\".layui-table-tips-c\").on(\"click\",function(){l.close(t)})}}))}),a.layBody.on(\"click\",\"*[lay-event]\",function(){var e=t(this),l=e.parents(\"tr\").eq(0).data(\"index\"),n=a.layBody.find('tr[data-index=\"'+l+'\"]'),o=\"layui-table-click\",r=d.cache[a.key][l];layui.event.call(this,s,\"tool(\"+f+\")\",{data:d.clearCacheKey(r),event:e.attr(\"lay-event\"),tr:n,del:function(){d.cache[a.key][l]=[],n.remove(),a.scrollPatch()},update:function(e){e=e||{},layui.each(e,function(e,l){if(e in r){var o,d=n.children('td[data-field=\"'+e+'\"]');r[e]=l,a.eachCols(function(t,i){i.field==e&&i.templet&&(o=i.templet)}),d.children(h).html(o?i(t(o).html()||l).render(r):l),d.data(\"content\",l)}})}}),n.addClass(o).siblings(\"tr\").removeClass(o)}),a.layMain.on(\"scroll\",function(){var e=t(this),i=e.scrollLeft(),n=e.scrollTop();a.layHeader.scrollLeft(i),a.layFixed.find(m).scrollTop(n),l.close(a.tipsIndex)}),A.on(\"resize\",function(){a.fullSize(),a.scrollPatch()})},d.init=function(e,i){i=i||{};var a=this,l=t(e?'table[lay-filter=\"'+e+'\"]':u+\"[lay-data]\"),n=\"Table element property lay-data configuration item has a syntax error: \";return l.each(function(){var a=t(this),l=a.attr(\"lay-data\");try{l=new Function(\"return \"+l)()}catch(r){o.error(n+l)}var c=[],s=t.extend({elem:this,cols:[],data:[],skin:a.attr(\"lay-skin\"),size:a.attr(\"lay-size\"),even:\"string\"==typeof a.attr(\"lay-even\")},d.config,i,l);e&&a.hide(),a.find(\"thead>tr\").each(function(e){s.cols[e]=[],t(this).children().each(function(i){var a=t(this),l=a.attr(\"lay-data\");try{l=new Function(\"return \"+l)()}catch(r){return o.error(n+l)}var d=t.extend({title:a.text(),colspan:a.attr(\"colspan\")||0,rowspan:a.attr(\"rowspan\")||0},l);d.colspan<2&&c.push(d),s.cols[e].push(d)})}),a.find(\"tbody>tr\").each(function(e){var i=t(this),a={};i.children(\"td\").each(function(e,i){var l=t(this),n=l.data(\"field\");if(n)return a[n]=l.html()}),layui.each(c,function(e,t){var l=i.children(\"td\").eq(e);a[t.field]=l.html()}),s.data[e]=a}),d.render(s)}),a},d.checkStatus=function(e){var t=0,i=0,a=[],l=d.cache[e]||[];return layui.each(l,function(e,l){return l.constructor===Array?void i++:void(l[d.config.checkName]&&(t++,a.push(d.clearCacheKey(l))))}),{data:a,isAll:!!l.length&&t===l.length-i}},c.config={},d.reload=function(e,i){var a=c.config[e];return i=i||{},a?(i.data&&i.data.constructor===Array&&delete a.data,d.render(t.extend(!0,{},a,i))):o.error(\"The ID option was not found in the table instance\")},d.render=function(e){var t=new M(e);return c.call(t)},d.clearCacheKey=function(e){return e=t.extend({},e),delete e[d.config.checkName],delete e[d.config.indexName],e},d.init(),e(s,d)});"
  },
  {
    "path": "public/layui/lay/modules/tree.js",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n ;layui.define(\"jquery\",function(e){\"use strict\";var o=layui.$,a=layui.hint(),i=\"layui-tree-enter\",r=function(e){this.options=e},t={arrow:[\"&#xe623;\",\"&#xe625;\"],checkbox:[\"&#xe626;\",\"&#xe627;\"],radio:[\"&#xe62b;\",\"&#xe62a;\"],branch:[\"&#xe622;\",\"&#xe624;\"],leaf:\"&#xe621;\"};r.prototype.init=function(e){var o=this;e.addClass(\"layui-box layui-tree\"),o.options.skin&&e.addClass(\"layui-tree-skin-\"+o.options.skin),o.tree(e),o.on(e)},r.prototype.tree=function(e,a){var i=this,r=i.options,n=a||r.nodes;layui.each(n,function(a,n){var l=n.children&&n.children.length>0,c=o('<ul class=\"'+(n.spread?\"layui-show\":\"\")+'\"></ul>'),s=o([\"<li \"+(n.spread?'data-spread=\"'+n.spread+'\"':\"\")+\">\",function(){return l?'<i class=\"layui-icon layui-tree-spread\">'+(n.spread?t.arrow[1]:t.arrow[0])+\"</i>\":\"\"}(),function(){return r.check?'<i class=\"layui-icon layui-tree-check\">'+(\"checkbox\"===r.check?t.checkbox[0]:\"radio\"===r.check?t.radio[0]:\"\")+\"</i>\":\"\"}(),function(){return'<a href=\"'+(n.href||\"javascript:;\")+'\" '+(r.target&&n.href?'target=\"'+r.target+'\"':\"\")+\">\"+('<i class=\"layui-icon layui-tree-'+(l?\"branch\":\"leaf\")+'\">'+(l?n.spread?t.branch[1]:t.branch[0]:t.leaf)+\"</i>\")+(\"<cite>\"+(n.name||\"未命名\")+\"</cite></a>\")}(),\"</li>\"].join(\"\"));l&&(s.append(c),i.tree(c,n.children)),e.append(s),\"function\"==typeof r.click&&i.click(s,n),i.spread(s,n),r.drag&&i.drag(s,n)})},r.prototype.click=function(e,o){var a=this,i=a.options;e.children(\"a\").on(\"click\",function(e){layui.stope(e),i.click(o)})},r.prototype.spread=function(e,o){var a=this,i=(a.options,e.children(\".layui-tree-spread\")),r=e.children(\"ul\"),n=e.children(\"a\"),l=function(){e.data(\"spread\")?(e.data(\"spread\",null),r.removeClass(\"layui-show\"),i.html(t.arrow[0]),n.find(\".layui-icon\").html(t.branch[0])):(e.data(\"spread\",!0),r.addClass(\"layui-show\"),i.html(t.arrow[1]),n.find(\".layui-icon\").html(t.branch[1]))};r[0]&&(i.on(\"click\",l),n.on(\"dblclick\",l))},r.prototype.on=function(e){var a=this,r=a.options,t=\"layui-tree-drag\";e.find(\"i\").on(\"selectstart\",function(e){return!1}),r.drag&&o(document).on(\"mousemove\",function(e){var i=a.move;if(i.from){var r=(i.to,o('<div class=\"layui-box '+t+'\"></div>'));e.preventDefault(),o(\".\"+t)[0]||o(\"body\").append(r);var n=o(\".\"+t)[0]?o(\".\"+t):r;n.addClass(\"layui-show\").html(i.from.elem.children(\"a\").html()),n.css({left:e.pageX+10,top:e.pageY+10})}}).on(\"mouseup\",function(){var e=a.move;e.from&&(e.from.elem.children(\"a\").removeClass(i),e.to&&e.to.elem.children(\"a\").removeClass(i),a.move={},o(\".\"+t).remove())})},r.prototype.move={},r.prototype.drag=function(e,a){var r=this,t=(r.options,e.children(\"a\")),n=function(){var t=o(this),n=r.move;n.from&&(n.to={item:a,elem:e},t.addClass(i))};t.on(\"mousedown\",function(){var o=r.move;o.from={item:a,elem:e}}),t.on(\"mouseenter\",n).on(\"mousemove\",n).on(\"mouseleave\",function(){var e=o(this),a=r.move;a.from&&(delete a.to,e.removeClass(i))})},e(\"tree\",function(e){var i=new r(e=e||{}),t=o(e.elem);return t[0]?void i.init(t):a.error(\"layui.tree 没有找到\"+e.elem+\"元素\")})});"
  },
  {
    "path": "public/layui/lay/modules/upload.js",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n ;layui.define(\"layer\",function(e){\"use strict\";var i=layui.$,t=layui.layer,n=layui.hint(),a=layui.device(),o={config:{},set:function(e){var t=this;return t.config=i.extend({},t.config,e),t},on:function(e,i){return layui.onevent.call(this,r,e,i)}},l=function(){var e=this;return{upload:function(i){e.upload.call(e,i)},config:e.config}},r=\"upload\",u=\"layui-upload-file\",c=\"layui-upload-form\",f=\"layui-upload-iframe\",s=\"layui-upload-choose\",p=function(e){var t=this;t.config=i.extend({},t.config,o.config,e),t.render()};p.prototype.config={accept:\"images\",exts:\"\",auto:!0,bindAction:\"\",url:\"\",field:\"file\",method:\"post\",data:{},drag:!0,size:0,number:0,multiple:!1},p.prototype.render=function(e){var t=this,e=t.config;e.elem=i(e.elem),e.bindAction=i(e.bindAction),t.file(),t.events()},p.prototype.file=function(){var e=this,t=e.config,n=e.elemFile=i(['<input class=\"'+u+'\" type=\"file\" accept=\"'+t.acceptMime+'\" name=\"'+t.field+'\"',t.multiple?\" multiple\":\"\",\">\"].join(\"\")),o=t.elem.next();(o.hasClass(u)||o.hasClass(c))&&o.remove(),a.ie&&a.ie<10&&t.elem.wrap('<div class=\"layui-upload-wrap\"></div>'),e.isFile()?(e.elemFile=t.elem,t.field=t.elem[0].name):t.elem.after(n),a.ie&&a.ie<10&&e.initIE()},p.prototype.initIE=function(){var e=this,t=e.config,n=i('<iframe id=\"'+f+'\" class=\"'+f+'\" name=\"'+f+'\" frameborder=\"0\"></iframe>'),a=i(['<form target=\"'+f+'\" class=\"'+c+'\" method=\"'+t.method,'\" key=\"set-mine\" enctype=\"multipart/form-data\" action=\"'+t.url+'\">',\"</form>\"].join(\"\"));i(\"#\"+f)[0]||i(\"body\").append(n),t.elem.next().hasClass(c)||(e.elemFile.wrap(a),t.elem.next(\".\"+c).append(function(){var e=[];return layui.each(t.data,function(i,t){t=\"function\"==typeof t?t():t,e.push('<input type=\"hidden\" name=\"'+i+'\" value=\"'+t+'\">')}),e.join(\"\")}()))},p.prototype.msg=function(e){return t.msg(e,{icon:2,shift:6})},p.prototype.isFile=function(){var e=this.config.elem[0];if(e)return\"input\"===e.tagName.toLocaleLowerCase()&&\"file\"===e.type},p.prototype.preview=function(e){var i=this;window.FileReader&&layui.each(i.chooseFiles,function(i,t){var n=new FileReader;n.readAsDataURL(t),n.onload=function(){e&&e(i,t,this.result)}})},p.prototype.upload=function(e,t){var n,o=this,l=o.config,r=o.elemFile[0],u=function(){var t=0,n=0,a=e||o.files||o.chooseFiles||r.files,u=function(){l.multiple&&t+n===o.fileLength&&\"function\"==typeof l.allDone&&l.allDone({total:o.fileLength,successful:t,aborted:n})};layui.each(a,function(e,a){var r=new FormData;r.append(l.field,a),layui.each(l.data,function(e,i){i=\"function\"==typeof i?i():i,r.append(e,i)}),i.ajax({url:l.url,type:l.method,data:r,contentType:!1,processData:!1,dataType:\"json\",headers:l.headers||{},success:function(i){t++,d(e,i),u()},error:function(){n++,o.msg(\"请求上传接口出现异常\"),m(e),u()}})})},c=function(){var e=i(\"#\"+f);o.elemFile.parent().submit(),clearInterval(p.timer),p.timer=setInterval(function(){var i,t=e.contents().find(\"body\");try{i=t.text()}catch(n){o.msg(\"获取上传后的响应信息出现异常\"),clearInterval(p.timer),m()}i&&(clearInterval(p.timer),t.html(\"\"),d(0,i))},30)},d=function(e,i){if(o.elemFile.next(\".\"+s).remove(),r.value=\"\",\"object\"!=typeof i)try{i=JSON.parse(i)}catch(t){return i={},o.msg(\"请对上传接口返回有效JSON\")}\"function\"==typeof l.done&&l.done(i,e||0,function(e){o.upload(e)})},m=function(e){l.auto&&(r.value=\"\"),\"function\"==typeof l.error&&l.error(e||0,function(e){o.upload(e)})},h=l.exts,v=function(){var i=[];return layui.each(e||o.chooseFiles,function(e,t){i.push(t.name)}),i}(),g={preview:function(e){o.preview(e)},upload:function(e,i){var t={};t[e]=i,o.upload(t)},pushFile:function(){return o.files=o.files||{},layui.each(o.chooseFiles,function(e,i){o.files[e]=i}),o.files},resetFile:function(e,i,t){var n=new File([i],t);o.files=o.files||{},o.files[e]=n}},y=function(){if(\"choose\"!==t&&!l.auto||(l.choose&&l.choose(g),\"choose\"!==t))return l.before&&l.before(g),a.ie?a.ie>9?u():c():void u()};if(v=0===v.length?r.value.match(/[^\\/\\\\]+\\..+/g)||[]||\"\":v,0!==v.length){switch(l.accept){case\"file\":if(h&&!RegExp(\"\\\\w\\\\.(\"+h+\")$\",\"i\").test(escape(v)))return o.msg(\"选择的文件中包含不支持的格式\"),r.value=\"\";break;case\"video\":if(!RegExp(\"\\\\w\\\\.(\"+(h||\"avi|mp4|wma|rmvb|rm|flash|3gp|flv\")+\")$\",\"i\").test(escape(v)))return o.msg(\"选择的视频中包含不支持的格式\"),r.value=\"\";break;case\"audio\":if(!RegExp(\"\\\\w\\\\.(\"+(h||\"mp3|wav|mid\")+\")$\",\"i\").test(escape(v)))return o.msg(\"选择的音频中包含不支持的格式\"),r.value=\"\";break;default:if(layui.each(v,function(e,i){RegExp(\"\\\\w\\\\.(\"+(h||\"jpg|png|gif|bmp|jpeg$\")+\")\",\"i\").test(escape(i))||(n=!0)}),n)return o.msg(\"选择的图片中包含不支持的格式\"),r.value=\"\"}if(o.fileLength=function(){var i=0,t=e||o.files||o.chooseFiles||r.files;return layui.each(t,function(){i++}),i}(),l.number&&o.fileLength>l.number)return o.msg(\"同时最多只能上传的数量为：\"+l.number);if(l.size>0&&!(a.ie&&a.ie<10)){var F;if(layui.each(o.chooseFiles,function(e,i){if(i.size>1024*l.size){var t=l.size/1024;t=t>=1?t.toFixed(2)+\"MB\":l.size+\"KB\",r.value=\"\",F=t}}),F)return o.msg(\"文件不能超过\"+F)}y()}},p.prototype.events=function(){var e=this,t=e.config,o=function(i){e.chooseFiles={},layui.each(i,function(i,t){var n=(new Date).getTime();e.chooseFiles[n+\"-\"+i]=t})},l=function(i,n){var a=e.elemFile,o=i.length>1?i.length+\"个文件\":(i[0]||{}).name||a[0].value.match(/[^\\/\\\\]+\\..+/g)||[]||\"\";a.next().hasClass(s)&&a.next().remove(),e.upload(null,\"choose\"),e.isFile()||t.choose||a.after('<span class=\"layui-inline '+s+'\">'+o+\"</span>\")};t.elem.off(\"upload.start\").on(\"upload.start\",function(){var a=i(this),o=a.attr(\"lay-data\");if(o)try{o=new Function(\"return \"+o)(),e.config=i.extend({},t,o)}catch(l){n.error(\"Upload element property lay-data configuration item has a syntax error: \"+o)}e.config.item=a,e.elemFile[0].click()}),a.ie&&a.ie<10||t.elem.off(\"upload.over\").on(\"upload.over\",function(){var e=i(this);e.attr(\"lay-over\",\"\")}).off(\"upload.leave\").on(\"upload.leave\",function(){var e=i(this);e.removeAttr(\"lay-over\")}).off(\"upload.drop\").on(\"upload.drop\",function(n,a){var r=i(this),u=a.originalEvent.dataTransfer.files||[];r.removeAttr(\"lay-over\"),o(u),t.auto?e.upload(u):l(u)}),e.elemFile.off(\"upload.change\").on(\"upload.change\",function(){var i=this.files||[];o(i),t.auto?e.upload():l(i)}),t.bindAction.off(\"upload.action\").on(\"upload.action\",function(){e.upload()}),t.elem.data(\"haveEvents\")||(e.elemFile.on(\"change\",function(){i(this).trigger(\"upload.change\")}),t.elem.on(\"click\",function(){e.isFile()||i(this).trigger(\"upload.start\")}),t.drag&&t.elem.on(\"dragover\",function(e){e.preventDefault(),i(this).trigger(\"upload.over\")}).on(\"dragleave\",function(e){i(this).trigger(\"upload.leave\")}).on(\"drop\",function(e){e.preventDefault(),i(this).trigger(\"upload.drop\",e)}),t.bindAction.on(\"click\",function(){i(this).trigger(\"upload.action\")}),t.elem.data(\"haveEvents\",!0))},o.render=function(e){var i=new p(e);return l.call(i)},e(r,o)});"
  },
  {
    "path": "public/layui/lay/modules/util.js",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n ;layui.define(\"jquery\",function(e){\"use strict\";var t=layui.$,i={fixbar:function(e){var i,a,o=\"layui-fixbar\",r=\"layui-fixbar-top\",l=t(document),n=t(\"body\");e=t.extend({showHeight:200},e),e.bar1=e.bar1===!0?\"&#xe606;\":e.bar1,e.bar2=e.bar2===!0?\"&#xe607;\":e.bar2,e.bgcolor=e.bgcolor?\"background-color:\"+e.bgcolor:\"\";var c=[e.bar1,e.bar2,\"&#xe604;\"],g=t(['<ul class=\"'+o+'\">',e.bar1?'<li class=\"layui-icon\" lay-type=\"bar1\" style=\"'+e.bgcolor+'\">'+c[0]+\"</li>\":\"\",e.bar2?'<li class=\"layui-icon\" lay-type=\"bar2\" style=\"'+e.bgcolor+'\">'+c[1]+\"</li>\":\"\",'<li class=\"layui-icon '+r+'\" lay-type=\"top\" style=\"'+e.bgcolor+'\">'+c[2]+\"</li>\",\"</ul>\"].join(\"\")),u=g.find(\".\"+r),s=function(){var t=l.scrollTop();t>=e.showHeight?i||(u.show(),i=1):i&&(u.hide(),i=0)};t(\".\"+o)[0]||(\"object\"==typeof e.css&&g.css(e.css),n.append(g),s(),g.find(\"li\").on(\"click\",function(){var i=t(this),a=i.attr(\"lay-type\");\"top\"===a&&t(\"html,body\").animate({scrollTop:0},200),e.click&&e.click.call(this,a)}),l.on(\"scroll\",function(){clearTimeout(a),a=setTimeout(function(){s()},100)}))},countdown:function(e,t,i){var a=this,o=\"function\"==typeof t,r=new Date(e).getTime(),l=new Date(!t||o?(new Date).getTime():t).getTime(),n=r-l,c=[Math.floor(n/864e5),Math.floor(n/36e5)%24,Math.floor(n/6e4)%60,Math.floor(n/1e3)%60];o&&(i=t);var g=setTimeout(function(){a.countdown(e,l+1e3,i)},1e3);return i&&i(n>0?c:[0,0,0,0],t,g),n<=0&&clearTimeout(g),g},timeAgo:function(e,t){var i=this,a=[[],[]],o=(new Date).getTime()-new Date(e).getTime();return o>6912e5?(o=new Date(e),a[0][0]=i.digit(o.getFullYear(),4),a[0][1]=i.digit(o.getMonth()+1),a[0][2]=i.digit(o.getDate()),t||(a[1][0]=i.digit(o.getHours()),a[1][1]=i.digit(o.getMinutes()),a[1][2]=i.digit(o.getSeconds())),a[0].join(\"-\")+\" \"+a[1].join(\":\")):o>=864e5?(o/1e3/60/60/24|0)+\"天前\":o>=36e5?(o/1e3/60/60|0)+\"小时前\":o>=12e4?(o/1e3/60|0)+\"分钟前\":o<0?\"未来\":\"刚刚\"},digit:function(e,t){var i=\"\";e=String(e),t=t||2;for(var a=e.length;a<t;a++)i+=\"0\";return e<Math.pow(10,t)?i+(0|e):e},toDateString:function(e,t){var i=this,a=new Date(e||new Date),o=[i.digit(a.getFullYear(),4),i.digit(a.getMonth()+1),i.digit(a.getDate())],r=[i.digit(a.getHours()),i.digit(a.getMinutes()),i.digit(a.getSeconds())];return t=t||\"yyyy-MM-dd HH:mm:ss\",t.replace(/yyyy/g,o[0]).replace(/MM/g,o[1]).replace(/dd/g,o[2]).replace(/HH/g,r[0]).replace(/mm/g,r[1]).replace(/ss/g,r[2])},escape:function(e){return String(e||\"\").replace(/&(?!#?[a-zA-Z0-9]+;)/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/'/g,\"&#39;\").replace(/\"/g,\"&quot;\")}};e(\"util\",i)});"
  },
  {
    "path": "public/layui/layui.all.js",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n ;!function(e){\"use strict\";var t=document,n={modules:{},status:{},timeout:10,event:{}},o=function(){this.v=\"2.3.0\"},r=function(){var e=t.currentScript?t.currentScript.src:function(){for(var e,n=t.scripts,o=n.length-1,r=o;r>0;r--)if(\"interactive\"===n[r].readyState){e=n[r].src;break}return e||n[o].src}();return e.substring(0,e.lastIndexOf(\"/\")+1)}(),a=function(t){e.console&&console.error&&console.error(\"Layui hint: \"+t)},i=\"undefined\"!=typeof opera&&\"[object Opera]\"===opera.toString(),u={layer:\"modules/layer\",laydate:\"modules/laydate\",laypage:\"modules/laypage\",laytpl:\"modules/laytpl\",layim:\"modules/layim\",layedit:\"modules/layedit\",form:\"modules/form\",upload:\"modules/upload\",tree:\"modules/tree\",table:\"modules/table\",element:\"modules/element\",rate:\"modules/rate\",carousel:\"modules/carousel\",flow:\"modules/flow\",util:\"modules/util\",code:\"modules/code\",jquery:\"modules/jquery\",mobile:\"modules/mobile\",\"layui.all\":\"../layui.all\"};o.prototype.cache=n,o.prototype.define=function(e,t){var o=this,r=\"function\"==typeof e,a=function(){var e=function(e,t){layui[e]=t,n.status[e]=!0};return\"function\"==typeof t&&t(function(o,r){e(o,r),n.callback[o]=function(){t(e)}}),this};return r&&(t=e,e=[]),layui[\"layui.all\"]||!layui[\"layui.all\"]&&layui[\"layui.mobile\"]?a.call(o):(o.use(e,a),o)},o.prototype.use=function(e,o,l){function s(e,t){var o=\"PLaySTATION 3\"===navigator.platform?/^complete$/:/^(complete|loaded)$/;(\"load\"===e.type||o.test((e.currentTarget||e.srcElement).readyState))&&(n.modules[d]=t,f.removeChild(v),function r(){return++m>1e3*n.timeout/4?a(d+\" is not a valid module\"):void(n.status[d]?c():setTimeout(r,4))}())}function c(){l.push(layui[d]),e.length>1?y.use(e.slice(1),o,l):\"function\"==typeof o&&o.apply(layui,l)}var y=this,p=n.dir=n.dir?n.dir:r,f=t.getElementsByTagName(\"head\")[0];e=\"string\"==typeof e?[e]:e,window.jQuery&&jQuery.fn.on&&(y.each(e,function(t,n){\"jquery\"===n&&e.splice(t,1)}),layui.jquery=layui.$=jQuery);var d=e[0],m=0;if(l=l||[],n.host=n.host||(p.match(/\\/\\/([\\s\\S]+?)\\//)||[\"//\"+location.host+\"/\"])[0],0===e.length||layui[\"layui.all\"]&&u[d]||!layui[\"layui.all\"]&&layui[\"layui.mobile\"]&&u[d])return c(),y;if(n.modules[d])!function g(){return++m>1e3*n.timeout/4?a(d+\" is not a valid module\"):void(\"string\"==typeof n.modules[d]&&n.status[d]?c():setTimeout(g,4))}();else{var v=t.createElement(\"script\"),h=(u[d]?p+\"lay/\":/^\\{\\/\\}/.test(y.modules[d])?\"\":n.base||\"\")+(y.modules[d]||d)+\".js\";h=h.replace(/^\\{\\/\\}/,\"\"),v.async=!0,v.charset=\"utf-8\",v.src=h+function(){var e=n.version===!0?n.v||(new Date).getTime():n.version||\"\";return e?\"?v=\"+e:\"\"}(),f.appendChild(v),!v.attachEvent||v.attachEvent.toString&&v.attachEvent.toString().indexOf(\"[native code\")<0||i?v.addEventListener(\"load\",function(e){s(e,h)},!1):v.attachEvent(\"onreadystatechange\",function(e){s(e,h)}),n.modules[d]=h}return y},o.prototype.getStyle=function(t,n){var o=t.currentStyle?t.currentStyle:e.getComputedStyle(t,null);return o[o.getPropertyValue?\"getPropertyValue\":\"getAttribute\"](n)},o.prototype.link=function(e,o,r){var i=this,u=t.createElement(\"link\"),l=t.getElementsByTagName(\"head\")[0];\"string\"==typeof o&&(r=o);var s=(r||e).replace(/\\.|\\//g,\"\"),c=u.id=\"layuicss-\"+s,y=0;return u.rel=\"stylesheet\",u.href=e+(n.debug?\"?v=\"+(new Date).getTime():\"\"),u.media=\"all\",t.getElementById(c)||l.appendChild(u),\"function\"!=typeof o?i:(function p(){return++y>1e3*n.timeout/100?a(e+\" timeout\"):void(1989===parseInt(i.getStyle(t.getElementById(c),\"width\"))?function(){o()}():setTimeout(p,100))}(),i)},n.callback={},o.prototype.factory=function(e){if(layui[e])return\"function\"==typeof n.callback[e]?n.callback[e]:null},o.prototype.addcss=function(e,t,o){return layui.link(n.dir+\"css/\"+e,t,o)},o.prototype.img=function(e,t,n){var o=new Image;return o.src=e,o.complete?t(o):(o.onload=function(){o.onload=null,\"function\"==typeof t&&t(o)},void(o.onerror=function(e){o.onerror=null,\"function\"==typeof n&&n(e)}))},o.prototype.config=function(e){e=e||{};for(var t in e)n[t]=e[t];return this},o.prototype.modules=function(){var e={};for(var t in u)e[t]=u[t];return e}(),o.prototype.extend=function(e){var t=this;e=e||{};for(var n in e)t[n]||t.modules[n]?a(\"模块名 \"+n+\" 已被占用\"):t.modules[n]=e[n];return t},o.prototype.router=function(e){var t=this,e=e||location.hash,n={path:[],search:{},hash:(e.match(/[^#](#.*$)/)||[])[1]||\"\"};return/^#\\//.test(e)?(e=e.replace(/^#\\//,\"\"),n.href=\"/\"+e,e=e.replace(/([^#])(#.*$)/,\"$1\").split(\"/\")||[],t.each(e,function(e,t){/^\\w+=/.test(t)?function(){t=t.split(\"=\"),n.search[t[0]]=t[1]}():n.path.push(t)}),n):n},o.prototype.data=function(t,n,o){if(t=t||\"layui\",o=o||localStorage,e.JSON&&e.JSON.parse){if(null===n)return delete o[t];n=\"object\"==typeof n?n:{key:n};try{var r=JSON.parse(o[t])}catch(a){var r={}}return\"value\"in n&&(r[n.key]=n.value),n.remove&&delete r[n.key],o[t]=JSON.stringify(r),n.key?r[n.key]:r}},o.prototype.sessionData=function(e,t){return this.data(e,t,sessionStorage)},o.prototype.device=function(t){var n=navigator.userAgent.toLowerCase(),o=function(e){var t=new RegExp(e+\"/([^\\\\s\\\\_\\\\-]+)\");return e=(n.match(t)||[])[1],e||!1},r={os:function(){return/windows/.test(n)?\"windows\":/linux/.test(n)?\"linux\":/iphone|ipod|ipad|ios/.test(n)?\"ios\":/mac/.test(n)?\"mac\":void 0}(),ie:function(){return!!(e.ActiveXObject||\"ActiveXObject\"in e)&&((n.match(/msie\\s(\\d+)/)||[])[1]||\"11\")}(),weixin:o(\"micromessenger\")};return t&&!r[t]&&(r[t]=o(t)),r.android=/android/.test(n),r.ios=\"ios\"===r.os,r},o.prototype.hint=function(){return{error:a}},o.prototype.each=function(e,t){var n,o=this;if(\"function\"!=typeof t)return o;if(e=e||[],e.constructor===Object){for(n in e)if(t.call(e[n],n,e[n]))break}else for(n=0;n<e.length&&!t.call(e[n],n,e[n]);n++);return o},o.prototype.sort=function(e,t,n){var o=JSON.parse(JSON.stringify(e||[]));return t?(o.sort(function(e,n){var o=/^-?\\d+$/,r=e[t],a=n[t];return o.test(r)&&(r=parseFloat(r)),o.test(a)&&(a=parseFloat(a)),r&&!a?1:!r&&a?-1:r>a?1:r<a?-1:0}),n&&o.reverse(),o):o},o.prototype.stope=function(t){t=t||e.event;try{t.stopPropagation()}catch(n){t.cancelBubble=!0}},o.prototype.onevent=function(e,t,n){return\"string\"!=typeof e||\"function\"!=typeof n?this:o.event(e,t,null,n)},o.prototype.event=o.event=function(e,t,o,r){var a=this,i=null,u=t.match(/\\((.*)\\)$/)||[],l=(e+\".\"+t).replace(u[0],\"\"),s=u[1]||\"\",c=function(e,t){var n=t&&t.call(a,o);n===!1&&null===i&&(i=!1)};return r?(n.event[l]=n.event[l]||{},n.event[l][s]=[r],this):(layui.each(n.event[l],function(e,t){return\"{*}\"===s?void layui.each(t,c):(\"\"===e&&layui.each(t,c),void(e===s&&layui.each(t,c)))}),i)},e.layui=new o}(window);layui.define(function(a){var i=layui.cache;layui.config({dir:i.dir.replace(/lay\\/dest\\/$/,\"\")}),a(\"layui.all\",layui.v)});layui.define(function(e){\"use strict\";var r={open:\"{{\",close:\"}}\"},c={exp:function(e){return new RegExp(e,\"g\")},query:function(e,c,t){var o=[\"#([\\\\s\\\\S])+?\",\"([^{#}])*?\"][e||0];return n((c||\"\")+r.open+o+r.close+(t||\"\"))},escape:function(e){return String(e||\"\").replace(/&(?!#?[a-zA-Z0-9]+;)/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/'/g,\"&#39;\").replace(/\"/g,\"&quot;\")},error:function(e,r){var c=\"Laytpl Error：\";return\"object\"==typeof console&&console.error(c+e+\"\\n\"+(r||\"\")),c+e}},n=c.exp,t=function(e){this.tpl=e};t.pt=t.prototype,window.errors=0,t.pt.parse=function(e,t){var o=this,p=e,a=n(\"^\"+r.open+\"#\",\"\"),l=n(r.close+\"$\",\"\");e=e.replace(/\\s+|\\r|\\t|\\n/g,\" \").replace(n(r.open+\"#\"),r.open+\"# \").replace(n(r.close+\"}\"),\"} \"+r.close).replace(/\\\\/g,\"\\\\\\\\\").replace(n(r.open+\"!(.+?)!\"+r.close),function(e){return e=e.replace(n(\"^\"+r.open+\"!\"),\"\").replace(n(\"!\"+r.close),\"\").replace(n(r.open+\"|\"+r.close),function(e){return e.replace(/(.)/g,\"\\\\$1\")})}).replace(/(?=\"|')/g,\"\\\\\").replace(c.query(),function(e){return e=e.replace(a,\"\").replace(l,\"\"),'\";'+e.replace(/\\\\/g,\"\")+';view+=\"'}).replace(c.query(1),function(e){var c='\"+(';return e.replace(/\\s/g,\"\")===r.open+r.close?\"\":(e=e.replace(n(r.open+\"|\"+r.close),\"\"),/^=/.test(e)&&(e=e.replace(/^=/,\"\"),c='\"+_escape_('),c+e.replace(/\\\\/g,\"\")+')+\"')}),e='\"use strict\";var view = \"'+e+'\";return view;';try{return o.cache=e=new Function(\"d, _escape_\",e),e(t,c.escape)}catch(u){return delete o.cache,c.error(u,p)}},t.pt.render=function(e,r){var n,t=this;return e?(n=t.cache?t.cache(e,c.escape):t.parse(t.tpl,e),r?void r(n):n):c.error(\"no data\")};var o=function(e){return\"string\"!=typeof e?c.error(\"Template not found\"):new t(e)};o.config=function(e){e=e||{};for(var c in e)r[c]=e[c]},o.v=\"1.2.0\",e(\"laytpl\",o)});layui.define(function(e){\"use strict\";var a=document,t=\"getElementById\",n=\"getElementsByTagName\",i=\"laypage\",r=\"layui-disabled\",u=function(e){var a=this;a.config=e||{},a.config.index=++s.index,a.render(!0)};u.prototype.type=function(){var e=this.config;if(\"object\"==typeof e.elem)return void 0===e.elem.length?2:3},u.prototype.view=function(){var e=this,a=e.config,t=a.groups=\"groups\"in a?0|a.groups:5;a.layout=\"object\"==typeof a.layout?a.layout:[\"prev\",\"page\",\"next\"],a.count=0|a.count,a.curr=0|a.curr||1,a.limits=\"object\"==typeof a.limits?a.limits:[10,20,30,40,50],a.limit=0|a.limit||10,a.pages=Math.ceil(a.count/a.limit)||1,a.curr>a.pages&&(a.curr=a.pages),t<0?t=1:t>a.pages&&(t=a.pages),a.prev=\"prev\"in a?a.prev:\"&#x4E0A;&#x4E00;&#x9875;\",a.next=\"next\"in a?a.next:\"&#x4E0B;&#x4E00;&#x9875;\";var n=a.pages>t?Math.ceil((a.curr+(t>1?1:0))/(t>0?t:1)):1,i={prev:function(){return a.prev?'<a href=\"javascript:;\" class=\"layui-laypage-prev'+(1==a.curr?\" \"+r:\"\")+'\" data-page=\"'+(a.curr-1)+'\">'+a.prev+\"</a>\":\"\"}(),page:function(){var e=[];if(a.count<1)return\"\";n>1&&a.first!==!1&&0!==t&&e.push('<a href=\"javascript:;\" class=\"layui-laypage-first\" data-page=\"1\"  title=\"&#x9996;&#x9875;\">'+(a.first||1)+\"</a>\");var i=Math.floor((t-1)/2),r=n>1?a.curr-i:1,u=n>1?function(){var e=a.curr+(t-i-1);return e>a.pages?a.pages:e}():t;for(u-r<t-1&&(r=u-t+1),a.first!==!1&&r>2&&e.push('<span class=\"layui-laypage-spr\">&#x2026;</span>');r<=u;r++)r===a.curr?e.push('<span class=\"layui-laypage-curr\"><em class=\"layui-laypage-em\" '+(/^#/.test(a.theme)?'style=\"background-color:'+a.theme+';\"':\"\")+\"></em><em>\"+r+\"</em></span>\"):e.push('<a href=\"javascript:;\" data-page=\"'+r+'\">'+r+\"</a>\");return a.pages>t&&a.pages>u&&a.last!==!1&&(u+1<a.pages&&e.push('<span class=\"layui-laypage-spr\">&#x2026;</span>'),0!==t&&e.push('<a href=\"javascript:;\" class=\"layui-laypage-last\" title=\"&#x5C3E;&#x9875;\"  data-page=\"'+a.pages+'\">'+(a.last||a.pages)+\"</a>\")),e.join(\"\")}(),next:function(){return a.next?'<a href=\"javascript:;\" class=\"layui-laypage-next'+(a.curr==a.pages?\" \"+r:\"\")+'\" data-page=\"'+(a.curr+1)+'\">'+a.next+\"</a>\":\"\"}(),count:'<span class=\"layui-laypage-count\">共 '+a.count+\" 条</span>\",limit:function(){var e=['<span class=\"layui-laypage-limits\"><select lay-ignore>'];return layui.each(a.limits,function(t,n){e.push('<option value=\"'+n+'\"'+(n===a.limit?\"selected\":\"\")+\">\"+n+\" 条/页</option>\")}),e.join(\"\")+\"</select></span>\"}(),refresh:['<a href=\"javascript:;\" data-page=\"'+a.curr+'\" class=\"layui-laypage-refresh\">','<i class=\"layui-icon layui-icon-refresh\"></i>',\"</a>\"].join(\"\"),skip:function(){return['<span class=\"layui-laypage-skip\">&#x5230;&#x7B2C;','<input type=\"text\" min=\"1\" value=\"'+a.curr+'\" class=\"layui-input\">','&#x9875;<button type=\"button\" class=\"layui-laypage-btn\">&#x786e;&#x5b9a;</button>',\"</span>\"].join(\"\")}()};return['<div class=\"layui-box layui-laypage layui-laypage-'+(a.theme?/^#/.test(a.theme)?\"molv\":a.theme:\"default\")+'\" id=\"layui-laypage-'+a.index+'\">',function(){var e=[];return layui.each(a.layout,function(a,t){i[t]&&e.push(i[t])}),e.join(\"\")}(),\"</div>\"].join(\"\")},u.prototype.jump=function(e,a){if(e){var t=this,i=t.config,r=e.children,u=e[n](\"button\")[0],l=e[n](\"input\")[0],p=e[n](\"select\")[0],c=function(){var e=0|l.value.replace(/\\s|\\D/g,\"\");e&&(i.curr=e,t.render())};if(a)return c();for(var o=0,y=r.length;o<y;o++)\"a\"===r[o].nodeName.toLowerCase()&&s.on(r[o],\"click\",function(){var e=0|this.getAttribute(\"data-page\");e<1||e>i.pages||(i.curr=e,t.render())});p&&s.on(p,\"change\",function(){var e=this.value;i.curr*e>i.count&&(i.curr=Math.ceil(i.count/e)),i.limit=e,t.render()}),u&&s.on(u,\"click\",function(){c()})}},u.prototype.skip=function(e){if(e){var a=this,t=e[n](\"input\")[0];t&&s.on(t,\"keyup\",function(t){var n=this.value,i=t.keyCode;/^(37|38|39|40)$/.test(i)||(/\\D/.test(n)&&(this.value=n.replace(/\\D/,\"\")),13===i&&a.jump(e,!0))})}},u.prototype.render=function(e){var n=this,i=n.config,r=n.type(),u=n.view();2===r?i.elem&&(i.elem.innerHTML=u):3===r?i.elem.html(u):a[t](i.elem)&&(a[t](i.elem).innerHTML=u),i.jump&&i.jump(i,e);var s=a[t](\"layui-laypage-\"+i.index);n.jump(s),i.hash&&!e&&(location.hash=\"!\"+i.hash+\"=\"+i.curr),n.skip(s)};var s={render:function(e){var a=new u(e);return a.index},index:layui.laypage?layui.laypage.index+1e4:0,on:function(e,a,t){return e.attachEvent?e.attachEvent(\"on\"+a,function(a){a.target=a.srcElement,t.call(e,a)}):e.addEventListener(a,t,!1),this}};e(i,s)});!function(){\"use strict\";var e=window.layui&&layui.define,t={getPath:function(){var e=document.currentScript?document.currentScript.src:function(){for(var e,t=document.scripts,n=t.length-1,a=n;a>0;a--)if(\"interactive\"===t[a].readyState){e=t[a].src;break}return e||t[n].src}();return e.substring(0,e.lastIndexOf(\"/\")+1)}(),getStyle:function(e,t){var n=e.currentStyle?e.currentStyle:window.getComputedStyle(e,null);return n[n.getPropertyValue?\"getPropertyValue\":\"getAttribute\"](t)},link:function(e,a,i){if(n.path){var r=document.getElementsByTagName(\"head\")[0],o=document.createElement(\"link\");\"string\"==typeof a&&(i=a);var s=(i||e).replace(/\\.|\\//g,\"\"),l=\"layuicss-\"+s,d=0;o.rel=\"stylesheet\",o.href=n.path+e,o.id=l,document.getElementById(l)||r.appendChild(o),\"function\"==typeof a&&!function c(){return++d>80?window.console&&console.error(\"laydate.css: Invalid\"):void(1989===parseInt(t.getStyle(document.getElementById(l),\"width\"))?a():setTimeout(c,100))}()}}},n={v:\"5.0.9\",config:{},index:window.laydate&&window.laydate.v?1e5:0,path:t.getPath,set:function(e){var t=this;return t.config=w.extend({},t.config,e),t},ready:function(a){var i=\"laydate\",r=\"\",o=(e?\"modules/laydate/\":\"theme/\")+\"default/laydate.css?v=\"+n.v+r;return e?layui.addcss(o,a,i):t.link(o,a,i),this}},a=function(){var e=this;return{hint:function(t){e.hint.call(e,t)},config:e.config}},i=\"laydate\",r=\".layui-laydate\",o=\"layui-this\",s=\"laydate-disabled\",l=\"开始日期超出了结束日期<br>建议重新选择\",d=[100,2e5],c=\"layui-laydate-static\",m=\"layui-laydate-list\",u=\"laydate-selected\",h=\"layui-laydate-hint\",y=\"laydate-day-prev\",f=\"laydate-day-next\",p=\"layui-laydate-footer\",g=\".laydate-btns-confirm\",v=\"laydate-time-text\",D=\".laydate-btns-time\",T=function(e){var t=this;t.index=++n.index,t.config=w.extend({},t.config,n.config,e),n.ready(function(){t.init()})},w=function(e){return new C(e)},C=function(e){for(var t=0,n=\"object\"==typeof e?[e]:(this.selector=e,document.querySelectorAll(e||null));t<n.length;t++)this.push(n[t])};C.prototype=[],C.prototype.constructor=C,w.extend=function(){var e=1,t=arguments,n=function(e,t){e=e||(t.constructor===Array?[]:{});for(var a in t)e[a]=t[a]&&t[a].constructor===Object?n(e[a],t[a]):t[a];return e};for(t[0]=\"object\"==typeof t[0]?t[0]:{};e<t.length;e++)\"object\"==typeof t[e]&&n(t[0],t[e]);return t[0]},w.ie=function(){var e=navigator.userAgent.toLowerCase();return!!(window.ActiveXObject||\"ActiveXObject\"in window)&&((e.match(/msie\\s(\\d+)/)||[])[1]||\"11\")}(),w.stope=function(e){e=e||window.event,e.stopPropagation?e.stopPropagation():e.cancelBubble=!0},w.each=function(e,t){var n,a=this;if(\"function\"!=typeof t)return a;if(e=e||[],e.constructor===Object){for(n in e)if(t.call(e[n],n,e[n]))break}else for(n=0;n<e.length&&!t.call(e[n],n,e[n]);n++);return a},w.digit=function(e,t,n){var a=\"\";e=String(e),t=t||2;for(var i=e.length;i<t;i++)a+=\"0\";return e<Math.pow(10,t)?a+(0|e):e},w.elem=function(e,t){var n=document.createElement(e);return w.each(t||{},function(e,t){n.setAttribute(e,t)}),n},C.addStr=function(e,t){return e=e.replace(/\\s+/,\" \"),t=t.replace(/\\s+/,\" \").split(\" \"),w.each(t,function(t,n){new RegExp(\"\\\\b\"+n+\"\\\\b\").test(e)||(e=e+\" \"+n)}),e.replace(/^\\s|\\s$/,\"\")},C.removeStr=function(e,t){return e=e.replace(/\\s+/,\" \"),t=t.replace(/\\s+/,\" \").split(\" \"),w.each(t,function(t,n){var a=new RegExp(\"\\\\b\"+n+\"\\\\b\");a.test(e)&&(e=e.replace(a,\"\"))}),e.replace(/\\s+/,\" \").replace(/^\\s|\\s$/,\"\")},C.prototype.find=function(e){var t=this,n=0,a=[],i=\"object\"==typeof e;return this.each(function(r,o){for(var s=i?[e]:o.querySelectorAll(e||null);n<s.length;n++)a.push(s[n]);t.shift()}),i||(t.selector=(t.selector?t.selector+\" \":\"\")+e),w.each(a,function(e,n){t.push(n)}),t},C.prototype.each=function(e){return w.each.call(this,this,e)},C.prototype.addClass=function(e,t){return this.each(function(n,a){a.className=C[t?\"removeStr\":\"addStr\"](a.className,e)})},C.prototype.removeClass=function(e){return this.addClass(e,!0)},C.prototype.hasClass=function(e){var t=!1;return this.each(function(n,a){new RegExp(\"\\\\b\"+e+\"\\\\b\").test(a.className)&&(t=!0)}),t},C.prototype.attr=function(e,t){var n=this;return void 0===t?function(){if(n.length>0)return n[0].getAttribute(e)}():n.each(function(n,a){a.setAttribute(e,t)})},C.prototype.removeAttr=function(e){return this.each(function(t,n){n.removeAttribute(e)})},C.prototype.html=function(e){return this.each(function(t,n){n.innerHTML=e})},C.prototype.val=function(e){return this.each(function(t,n){n.value=e})},C.prototype.append=function(e){return this.each(function(t,n){\"object\"==typeof e?n.appendChild(e):n.innerHTML=n.innerHTML+e})},C.prototype.remove=function(e){return this.each(function(t,n){e?n.removeChild(e):n.parentNode.removeChild(n)})},C.prototype.on=function(e,t){return this.each(function(n,a){a.attachEvent?a.attachEvent(\"on\"+e,function(e){e.target=e.srcElement,t.call(a,e)}):a.addEventListener(e,t,!1)})},C.prototype.off=function(e,t){return this.each(function(n,a){a.detachEvent?a.detachEvent(\"on\"+e,t):a.removeEventListener(e,t,!1)})},T.isLeapYear=function(e){return e%4===0&&e%100!==0||e%400===0},T.prototype.config={type:\"date\",range:!1,format:\"yyyy-MM-dd\",value:null,isInitValue:!0,min:\"1900-1-1\",max:\"2099-12-31\",trigger:\"focus\",show:!1,showBottom:!0,btns:[\"clear\",\"now\",\"confirm\"],lang:\"cn\",theme:\"default\",position:null,calendar:!1,mark:{},zIndex:null,done:null,change:null},T.prototype.lang=function(){var e=this,t=e.config,n={cn:{weeks:[\"日\",\"一\",\"二\",\"三\",\"四\",\"五\",\"六\"],time:[\"时\",\"分\",\"秒\"],timeTips:\"选择时间\",startTime:\"开始时间\",endTime:\"结束时间\",dateTips:\"返回日期\",month:[\"一\",\"二\",\"三\",\"四\",\"五\",\"六\",\"七\",\"八\",\"九\",\"十\",\"十一\",\"十二\"],tools:{confirm:\"确定\",clear:\"清空\",now:\"现在\"}},en:{weeks:[\"Su\",\"Mo\",\"Tu\",\"We\",\"Th\",\"Fr\",\"Sa\"],time:[\"Hours\",\"Minutes\",\"Seconds\"],timeTips:\"Select Time\",startTime:\"Start Time\",endTime:\"End Time\",dateTips:\"Select Date\",month:[\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"],tools:{confirm:\"Confirm\",clear:\"Clear\",now:\"Now\"}}};return n[t.lang]||n.cn},T.prototype.init=function(){var e=this,t=e.config,n=\"yyyy|y|MM|M|dd|d|HH|H|mm|m|ss|s\",a=\"static\"===t.position,i={year:\"yyyy\",month:\"yyyy-MM\",date:\"yyyy-MM-dd\",time:\"HH:mm:ss\",datetime:\"yyyy-MM-dd HH:mm:ss\"};t.elem=w(t.elem),t.eventElem=w(t.eventElem),t.elem[0]&&(t.range===!0&&(t.range=\"-\"),t.format===i.date&&(t.format=i[t.type]),e.format=t.format.match(new RegExp(n+\"|.\",\"g\"))||[],e.EXP_IF=\"\",e.EXP_SPLIT=\"\",w.each(e.format,function(t,a){var i=new RegExp(n).test(a)?\"\\\\d{\"+function(){return new RegExp(n).test(e.format[0===t?t+1:t-1]||\"\")?/^yyyy|y$/.test(a)?4:a.length:/^yyyy$/.test(a)?\"1,4\":/^y$/.test(a)?\"1,308\":\"1,2\"}()+\"}\":\"\\\\\"+a;e.EXP_IF=e.EXP_IF+i,e.EXP_SPLIT=e.EXP_SPLIT+\"(\"+i+\")\"}),e.EXP_IF=new RegExp(\"^\"+(t.range?e.EXP_IF+\"\\\\s\\\\\"+t.range+\"\\\\s\"+e.EXP_IF:e.EXP_IF)+\"$\"),e.EXP_SPLIT=new RegExp(\"^\"+e.EXP_SPLIT+\"$\",\"\"),e.isInput(t.elem[0])||\"focus\"===t.trigger&&(t.trigger=\"click\"),t.elem.attr(\"lay-key\")||(t.elem.attr(\"lay-key\",e.index),t.eventElem.attr(\"lay-key\",e.index)),t.mark=w.extend({},t.calendar&&\"cn\"===t.lang?{\"0-1-1\":\"元旦\",\"0-2-14\":\"情人\",\"0-3-8\":\"妇女\",\"0-3-12\":\"植树\",\"0-4-1\":\"愚人\",\"0-5-1\":\"劳动\",\"0-5-4\":\"青年\",\"0-6-1\":\"儿童\",\"0-9-10\":\"教师\",\"0-9-18\":\"国耻\",\"0-10-1\":\"国庆\",\"0-12-25\":\"圣诞\"}:{},t.mark),w.each([\"min\",\"max\"],function(e,n){var a=[],i=[];if(\"number\"==typeof t[n]){var r=t[n],o=(new Date).getTime(),s=864e5,l=new Date(r?r<s?o+r*s:r:o);a=[l.getFullYear(),l.getMonth()+1,l.getDate()],r<s||(i=[l.getHours(),l.getMinutes(),l.getSeconds()])}else a=(t[n].match(/\\d+-\\d+-\\d+/)||[\"\"])[0].split(\"-\"),i=(t[n].match(/\\d+:\\d+:\\d+/)||[\"\"])[0].split(\":\");t[n]={year:0|a[0]||(new Date).getFullYear(),month:a[1]?(0|a[1])-1:(new Date).getMonth(),date:0|a[2]||(new Date).getDate(),hours:0|i[0],minutes:0|i[1],seconds:0|i[2]}}),e.elemID=\"layui-laydate\"+t.elem.attr(\"lay-key\"),(t.show||a)&&e.render(),a||e.events(),t.value&&t.isInitValue&&(t.value.constructor===Date?e.setValue(e.parse(0,e.systemDate(t.value))):e.setValue(t.value)))},T.prototype.render=function(){var e=this,t=e.config,n=e.lang(),a=\"static\"===t.position,i=e.elem=w.elem(\"div\",{id:e.elemID,\"class\":[\"layui-laydate\",t.range?\" layui-laydate-range\":\"\",a?\" \"+c:\"\",t.theme&&\"default\"!==t.theme&&!/^#/.test(t.theme)?\" laydate-theme-\"+t.theme:\"\"].join(\"\")}),r=e.elemMain=[],o=e.elemHeader=[],s=e.elemCont=[],l=e.table=[],d=e.footer=w.elem(\"div\",{\"class\":p});if(t.zIndex&&(i.style.zIndex=t.zIndex),w.each(new Array(2),function(e){if(!t.range&&e>0)return!0;var a=w.elem(\"div\",{\"class\":\"layui-laydate-header\"}),i=[function(){var e=w.elem(\"i\",{\"class\":\"layui-icon laydate-icon laydate-prev-y\"});return e.innerHTML=\"&#xe65a;\",e}(),function(){var e=w.elem(\"i\",{\"class\":\"layui-icon laydate-icon laydate-prev-m\"});return e.innerHTML=\"&#xe603;\",e}(),function(){var e=w.elem(\"div\",{\"class\":\"laydate-set-ym\"}),t=w.elem(\"span\"),n=w.elem(\"span\");return e.appendChild(t),e.appendChild(n),e}(),function(){var e=w.elem(\"i\",{\"class\":\"layui-icon laydate-icon laydate-next-m\"});return e.innerHTML=\"&#xe602;\",e}(),function(){var e=w.elem(\"i\",{\"class\":\"layui-icon laydate-icon laydate-next-y\"});return e.innerHTML=\"&#xe65b;\",e}()],d=w.elem(\"div\",{\"class\":\"layui-laydate-content\"}),c=w.elem(\"table\"),m=w.elem(\"thead\"),u=w.elem(\"tr\");w.each(i,function(e,t){a.appendChild(t)}),m.appendChild(u),w.each(new Array(6),function(e){var t=c.insertRow(0);w.each(new Array(7),function(a){if(0===e){var i=w.elem(\"th\");i.innerHTML=n.weeks[a],u.appendChild(i)}t.insertCell(a)})}),c.insertBefore(m,c.children[0]),d.appendChild(c),r[e]=w.elem(\"div\",{\"class\":\"layui-laydate-main laydate-main-list-\"+e}),r[e].appendChild(a),r[e].appendChild(d),o.push(i),s.push(d),l.push(c)}),w(d).html(function(){var e=[],i=[];return\"datetime\"===t.type&&e.push('<span lay-type=\"datetime\" class=\"laydate-btns-time\">'+n.timeTips+\"</span>\"),w.each(t.btns,function(e,r){var o=n.tools[r]||\"btn\";t.range&&\"now\"===r||(a&&\"clear\"===r&&(o=\"cn\"===t.lang?\"重置\":\"Reset\"),i.push('<span lay-type=\"'+r+'\" class=\"laydate-btns-'+r+'\">'+o+\"</span>\"))}),e.push('<div class=\"laydate-footer-btns\">'+i.join(\"\")+\"</div>\"),e.join(\"\")}()),w.each(r,function(e,t){i.appendChild(t)}),t.showBottom&&i.appendChild(d),/^#/.test(t.theme)){var m=w.elem(\"style\"),u=[\"#{{id}} .layui-laydate-header{background-color:{{theme}};}\",\"#{{id}} .layui-this{background-color:{{theme}} !important;}\"].join(\"\").replace(/{{id}}/g,e.elemID).replace(/{{theme}}/g,t.theme);\"styleSheet\"in m?(m.setAttribute(\"type\",\"text/css\"),m.styleSheet.cssText=u):m.innerHTML=u,w(i).addClass(\"laydate-theme-molv\"),i.appendChild(m)}e.remove(T.thisElemDate),a?t.elem.append(i):(document.body.appendChild(i),e.position()),e.checkDate().calendar(),e.changeEvent(),T.thisElemDate=e.elemID,\"function\"==typeof t.ready&&t.ready(w.extend({},t.dateTime,{month:t.dateTime.month+1}))},T.prototype.remove=function(e){var t=this,n=(t.config,w(\"#\"+(e||t.elemID)));return n.hasClass(c)||t.checkDate(function(){n.remove()}),t},T.prototype.position=function(){var e=this,t=e.config,n=e.bindElem||t.elem[0],a=n.getBoundingClientRect(),i=e.elem.offsetWidth,r=e.elem.offsetHeight,o=function(e){return e=e?\"scrollLeft\":\"scrollTop\",document.body[e]|document.documentElement[e]},s=function(e){return document.documentElement[e?\"clientWidth\":\"clientHeight\"]},l=5,d=a.left,c=a.bottom;d+i+l>s(\"width\")&&(d=s(\"width\")-i-l),c+r+l>s()&&(c=a.top>r?a.top-r:s()-r,c-=2*l),t.position&&(e.elem.style.position=t.position),e.elem.style.left=d+(\"fixed\"===t.position?0:o(1))+\"px\",e.elem.style.top=c+(\"fixed\"===t.position?0:o())+\"px\"},T.prototype.hint=function(e){var t=this,n=(t.config,w.elem(\"div\",{\"class\":h}));n.innerHTML=e||\"\",w(t.elem).find(\".\"+h).remove(),t.elem.appendChild(n),clearTimeout(t.hinTimer),t.hinTimer=setTimeout(function(){w(t.elem).find(\".\"+h).remove()},3e3)},T.prototype.getAsYM=function(e,t,n){return n?t--:t++,t<0&&(t=11,e--),t>11&&(t=0,e++),[e,t]},T.prototype.systemDate=function(e){var t=e||new Date;return{year:t.getFullYear(),month:t.getMonth(),date:t.getDate(),hours:e?e.getHours():0,minutes:e?e.getMinutes():0,seconds:e?e.getSeconds():0}},T.prototype.checkDate=function(e){var t,a,i=this,r=(new Date,i.config),o=r.dateTime=r.dateTime||i.systemDate(),s=i.bindElem||r.elem[0],l=(i.isInput(s)?\"val\":\"html\",i.isInput(s)?s.value:\"static\"===r.position?\"\":s.innerHTML),c=function(e){e.year>d[1]&&(e.year=d[1],a=!0),e.month>11&&(e.month=11,a=!0),e.hours>23&&(e.hours=0,a=!0),e.minutes>59&&(e.minutes=0,e.hours++,a=!0),e.seconds>59&&(e.seconds=0,e.minutes++,a=!0),t=n.getEndDate(e.month+1,e.year),e.date>t&&(e.date=t,a=!0)},m=function(e,t,n){var o=[\"startTime\",\"endTime\"];t=(t.match(i.EXP_SPLIT)||[]).slice(1),n=n||0,r.range&&(i[o[n]]=i[o[n]]||{}),w.each(i.format,function(s,l){var c=parseFloat(t[s]);t[s].length<l.length&&(a=!0),/yyyy|y/.test(l)?(c<d[0]&&(c=d[0],a=!0),e.year=c):/MM|M/.test(l)?(c<1&&(c=1,a=!0),e.month=c-1):/dd|d/.test(l)?(c<1&&(c=1,a=!0),e.date=c):/HH|H/.test(l)?(c<1&&(c=0,a=!0),e.hours=c,r.range&&(i[o[n]].hours=c)):/mm|m/.test(l)?(c<1&&(c=0,a=!0),e.minutes=c,r.range&&(i[o[n]].minutes=c)):/ss|s/.test(l)&&(c<1&&(c=0,a=!0),e.seconds=c,r.range&&(i[o[n]].seconds=c))}),c(e)};return\"limit\"===e?(c(o),i):(l=l||r.value,\"string\"==typeof l&&(l=l.replace(/\\s+/g,\" \").replace(/^\\s|\\s$/g,\"\")),i.startState&&!i.endState&&(delete i.startState,i.endState=!0),\"string\"==typeof l&&l?i.EXP_IF.test(l)?r.range?(l=l.split(\" \"+r.range+\" \"),i.startDate=i.startDate||i.systemDate(),i.endDate=i.endDate||i.systemDate(),r.dateTime=w.extend({},i.startDate),w.each([i.startDate,i.endDate],function(e,t){m(t,l[e],e)})):m(o,l):(i.hint(\"日期格式不合法<br>必须遵循下述格式：<br>\"+(r.range?r.format+\" \"+r.range+\" \"+r.format:r.format)+\"<br>已为你重置\"),a=!0):l&&l.constructor===Date?r.dateTime=i.systemDate(l):(r.dateTime=i.systemDate(),delete i.startState,delete i.endState,delete i.startDate,delete i.endDate,delete i.startTime,delete i.endTime),c(o),a&&l&&i.setValue(r.range?i.endDate?i.parse():\"\":i.parse()),e&&e(),i)},T.prototype.mark=function(e,t){var n,a=this,i=a.config;return w.each(i.mark,function(e,a){var i=e.split(\"-\");i[0]!=t[0]&&0!=i[0]||i[1]!=t[1]&&0!=i[1]||i[2]!=t[2]||(n=a||t[2])}),n&&e.html('<span class=\"laydate-day-mark\">'+n+\"</span>\"),a},T.prototype.limit=function(e,t,n,a){var i,r=this,o=r.config,l={},d=o[n>41?\"endDate\":\"dateTime\"],c=w.extend({},d,t||{});return w.each({now:c,min:o.min,max:o.max},function(e,t){l[e]=r.newDate(w.extend({year:t.year,month:t.month,date:t.date},function(){var e={};return w.each(a,function(n,a){e[a]=t[a]}),e}())).getTime()}),i=l.now<l.min||l.now>l.max,e&&e[i?\"addClass\":\"removeClass\"](s),i},T.prototype.calendar=function(e){var t,a,i,r=this,s=r.config,l=e||s.dateTime,c=new Date,m=r.lang(),u=\"date\"!==s.type&&\"datetime\"!==s.type,h=e?1:0,y=w(r.table[h]).find(\"td\"),f=w(r.elemHeader[h][2]).find(\"span\");if(l.year<d[0]&&(l.year=d[0],r.hint(\"最低只能支持到公元\"+d[0]+\"年\")),l.year>d[1]&&(l.year=d[1],r.hint(\"最高只能支持到公元\"+d[1]+\"年\")),r.firstDate||(r.firstDate=w.extend({},l)),c.setFullYear(l.year,l.month,1),t=c.getDay(),a=n.getEndDate(l.month||12,l.year),i=n.getEndDate(l.month+1,l.year),w.each(y,function(e,n){var d=[l.year,l.month],c=0;n=w(n),n.removeAttr(\"class\"),e<t?(c=a-t+e,n.addClass(\"laydate-day-prev\"),d=r.getAsYM(l.year,l.month,\"sub\")):e>=t&&e<i+t?(c=e-t,s.range||c+1===l.date&&n.addClass(o)):(c=e-i-t,n.addClass(\"laydate-day-next\"),d=r.getAsYM(l.year,l.month)),d[1]++,d[2]=c+1,n.attr(\"lay-ymd\",d.join(\"-\")).html(d[2]),r.mark(n,d).limit(n,{year:d[0],month:d[1]-1,date:d[2]},e)}),w(f[0]).attr(\"lay-ym\",l.year+\"-\"+(l.month+1)),w(f[1]).attr(\"lay-ym\",l.year+\"-\"+(l.month+1)),\"cn\"===s.lang?(w(f[0]).attr(\"lay-type\",\"year\").html(l.year+\"年\"),w(f[1]).attr(\"lay-type\",\"month\").html(l.month+1+\"月\")):(w(f[0]).attr(\"lay-type\",\"month\").html(m.month[l.month]),w(f[1]).attr(\"lay-type\",\"year\").html(l.year)),u&&(s.range&&(e?r.endDate=r.endDate||{year:l.year+(\"year\"===s.type?1:0),month:l.month+(\"month\"===s.type?0:-1)}:r.startDate=r.startDate||{year:l.year,month:l.month},e&&(r.listYM=[[r.startDate.year,r.startDate.month+1],[r.endDate.year,r.endDate.month+1]],r.list(s.type,0).list(s.type,1),\"time\"===s.type?r.setBtnStatus(\"时间\",w.extend({},r.systemDate(),r.startTime),w.extend({},r.systemDate(),r.endTime)):r.setBtnStatus(!0))),s.range||(r.listYM=[[l.year,l.month+1]],r.list(s.type,0))),s.range&&!e){var p=r.getAsYM(l.year,l.month);r.calendar(w.extend({},l,{year:p[0],month:p[1]}))}return s.range||r.limit(w(r.footer).find(g),null,0,[\"hours\",\"minutes\",\"seconds\"]),s.range&&e&&!u&&r.stampRange(),r},T.prototype.list=function(e,t){var n=this,a=n.config,i=a.dateTime,r=n.lang(),l=a.range&&\"date\"!==a.type&&\"datetime\"!==a.type,d=w.elem(\"ul\",{\"class\":m+\" \"+{year:\"laydate-year-list\",month:\"laydate-month-list\",time:\"laydate-time-list\"}[e]}),c=n.elemHeader[t],u=w(c[2]).find(\"span\"),h=n.elemCont[t||0],y=w(h).find(\".\"+m)[0],f=\"cn\"===a.lang,p=f?\"年\":\"\",T=n.listYM[t]||{},C=[\"hours\",\"minutes\",\"seconds\"],x=[\"startTime\",\"endTime\"][t];if(T[0]<1&&(T[0]=1),\"year\"===e){var M,b=M=T[0]-7;b<1&&(b=M=1),w.each(new Array(15),function(e){var i=w.elem(\"li\",{\"lay-ym\":M}),r={year:M};M==T[0]&&w(i).addClass(o),i.innerHTML=M+p,d.appendChild(i),M<n.firstDate.year?(r.month=a.min.month,r.date=a.min.date):M>=n.firstDate.year&&(r.month=a.max.month,r.date=a.max.date),n.limit(w(i),r,t),M++}),w(u[f?0:1]).attr(\"lay-ym\",M-8+\"-\"+T[1]).html(b+p+\" - \"+(M-1+p))}else if(\"month\"===e)w.each(new Array(12),function(e){var i=w.elem(\"li\",{\"lay-ym\":e}),s={year:T[0],month:e};e+1==T[1]&&w(i).addClass(o),i.innerHTML=r.month[e]+(f?\"月\":\"\"),d.appendChild(i),T[0]<n.firstDate.year?s.date=a.min.date:T[0]>=n.firstDate.year&&(s.date=a.max.date),n.limit(w(i),s,t)}),w(u[f?0:1]).attr(\"lay-ym\",T[0]+\"-\"+T[1]).html(T[0]+p);else if(\"time\"===e){var E=function(){w(d).find(\"ol\").each(function(e,a){w(a).find(\"li\").each(function(a,i){n.limit(w(i),[{hours:a},{hours:n[x].hours,minutes:a},{hours:n[x].hours,minutes:n[x].minutes,seconds:a}][e],t,[[\"hours\"],[\"hours\",\"minutes\"],[\"hours\",\"minutes\",\"seconds\"]][e])})}),a.range||n.limit(w(n.footer).find(g),n[x],0,[\"hours\",\"minutes\",\"seconds\"])};a.range?n[x]||(n[x]={hours:0,minutes:0,seconds:0}):n[x]=i,w.each([24,60,60],function(e,t){var a=w.elem(\"li\"),i=[\"<p>\"+r.time[e]+\"</p><ol>\"];w.each(new Array(t),function(t){i.push(\"<li\"+(n[x][C[e]]===t?' class=\"'+o+'\"':\"\")+\">\"+w.digit(t,2)+\"</li>\")}),a.innerHTML=i.join(\"\")+\"</ol>\",d.appendChild(a)}),E()}if(y&&h.removeChild(y),h.appendChild(d),\"year\"===e||\"month\"===e)w(n.elemMain[t]).addClass(\"laydate-ym-show\"),w(d).find(\"li\").on(\"click\",function(){var r=0|w(this).attr(\"lay-ym\");if(!w(this).hasClass(s)){if(0===t)i[e]=r,l&&(n.startDate[e]=r),n.limit(w(n.footer).find(g),null,0);else if(l)n.endDate[e]=r;else{var c=\"year\"===e?n.getAsYM(r,T[1]-1,\"sub\"):n.getAsYM(T[0],r,\"sub\");w.extend(i,{year:c[0],month:c[1]})}\"year\"===a.type||\"month\"===a.type?(w(d).find(\".\"+o).removeClass(o),w(this).addClass(o),\"month\"===a.type&&\"year\"===e&&(n.listYM[t][0]=r,l&&(n[[\"startDate\",\"endDate\"][t]].year=r),n.list(\"month\",t))):(n.checkDate(\"limit\").calendar(),n.closeList()),n.setBtnStatus(),a.range||n.done(null,\"change\"),w(n.footer).find(D).removeClass(s)}});else{var S=w.elem(\"span\",{\"class\":v}),k=function(){w(d).find(\"ol\").each(function(e){var t=this,a=w(t).find(\"li\");t.scrollTop=30*(n[x][C[e]]-2),t.scrollTop<=0&&a.each(function(e,n){if(!w(this).hasClass(s))return t.scrollTop=30*(e-2),!0})})},H=w(c[2]).find(\".\"+v);k(),S.innerHTML=a.range?[r.startTime,r.endTime][t]:r.timeTips,w(n.elemMain[t]).addClass(\"laydate-time-show\"),H[0]&&H.remove(),c[2].appendChild(S),w(d).find(\"ol\").each(function(e){var t=this;w(t).find(\"li\").on(\"click\",function(){var r=0|this.innerHTML;w(this).hasClass(s)||(a.range?n[x][C[e]]=r:i[C[e]]=r,w(t).find(\".\"+o).removeClass(o),w(this).addClass(o),E(),k(),(n.endDate||\"time\"===a.type)&&n.done(null,\"change\"),n.setBtnStatus())})})}return n},T.prototype.listYM=[],T.prototype.closeList=function(){var e=this;e.config;w.each(e.elemCont,function(t,n){w(this).find(\".\"+m).remove(),w(e.elemMain[t]).removeClass(\"laydate-ym-show laydate-time-show\")}),w(e.elem).find(\".\"+v).remove()},T.prototype.setBtnStatus=function(e,t,n){var a,i=this,r=i.config,o=w(i.footer).find(g),d=r.range&&\"date\"!==r.type&&\"time\"!==r.type;d&&(t=t||i.startDate,n=n||i.endDate,a=i.newDate(t).getTime()>i.newDate(n).getTime(),i.limit(null,t)||i.limit(null,n)?o.addClass(s):o[a?\"addClass\":\"removeClass\"](s),e&&a&&i.hint(\"string\"==typeof e?l.replace(/日期/g,e):l))},T.prototype.parse=function(e,t){var n=this,a=n.config,i=t||(e?w.extend({},n.endDate,n.endTime):a.range?w.extend({},n.startDate,n.startTime):a.dateTime),r=n.format.concat();return w.each(r,function(e,t){/yyyy|y/.test(t)?r[e]=w.digit(i.year,t.length):/MM|M/.test(t)?r[e]=w.digit(i.month+1,t.length):/dd|d/.test(t)?r[e]=w.digit(i.date,t.length):/HH|H/.test(t)?r[e]=w.digit(i.hours,t.length):/mm|m/.test(t)?r[e]=w.digit(i.minutes,t.length):/ss|s/.test(t)&&(r[e]=w.digit(i.seconds,t.length))}),a.range&&!e?r.join(\"\")+\" \"+a.range+\" \"+n.parse(1):r.join(\"\")},T.prototype.newDate=function(e){return e=e||{},new Date(e.year||1,e.month||0,e.date||1,e.hours||0,e.minutes||0,e.seconds||0)},T.prototype.setValue=function(e){var t=this,n=t.config,a=t.bindElem||n.elem[0],i=t.isInput(a)?\"val\":\"html\";return\"static\"===n.position||w(a)[i](e||\"\"),this},T.prototype.stampRange=function(){var e,t,n=this,a=n.config,i=w(n.elem).find(\"td\");if(a.range&&!n.endDate&&w(n.footer).find(g).addClass(s),n.endDate)return e=n.newDate({year:n.startDate.year,month:n.startDate.month,date:n.startDate.date}).getTime(),t=n.newDate({year:n.endDate.year,month:n.endDate.month,date:n.endDate.date}).getTime(),e>t?n.hint(l):void w.each(i,function(a,i){var r=w(i).attr(\"lay-ymd\").split(\"-\"),s=n.newDate({year:r[0],month:r[1]-1,date:r[2]}).getTime();w(i).removeClass(u+\" \"+o),s!==e&&s!==t||w(i).addClass(w(i).hasClass(y)||w(i).hasClass(f)?u:o),s>e&&s<t&&w(i).addClass(u)})},T.prototype.done=function(e,t){var n=this,a=n.config,i=w.extend({},n.startDate?w.extend(n.startDate,n.startTime):a.dateTime),r=w.extend({},w.extend(n.endDate,n.endTime));return w.each([i,r],function(e,t){\"month\"in t&&w.extend(t,{month:t.month+1})}),e=e||[n.parse(),i,r],\"function\"==typeof a[t||\"done\"]&&a[t||\"done\"].apply(a,e),n},T.prototype.choose=function(e){var t=this,n=t.config,a=n.dateTime,i=w(t.elem).find(\"td\"),r=e.attr(\"lay-ymd\").split(\"-\"),l=function(e){new Date;e&&w.extend(a,r),n.range&&(t.startDate?w.extend(t.startDate,r):t.startDate=w.extend({},r,t.startTime),t.startYMD=r)};if(r={year:0|r[0],month:(0|r[1])-1,date:0|r[2]},!e.hasClass(s))if(n.range){if(w.each([\"startTime\",\"endTime\"],function(e,n){t[n]=t[n]||{hours:0,minutes:0,seconds:0}}),t.endState)l(),delete t.endState,delete t.endDate,t.startState=!0,i.removeClass(o+\" \"+u),e.addClass(o);else if(t.startState){if(e.addClass(o),t.endDate?w.extend(t.endDate,r):t.endDate=w.extend({},r,t.endTime),t.newDate(r).getTime()<t.newDate(t.startYMD).getTime()){var d=w.extend({},t.endDate,{hours:t.startDate.hours,minutes:t.startDate.minutes,seconds:t.startDate.seconds});w.extend(t.endDate,t.startDate,{hours:t.endDate.hours,minutes:t.endDate.minutes,seconds:t.endDate.seconds}),t.startDate=d}n.showBottom||t.done(),t.stampRange(),t.endState=!0,t.done(null,\"change\")}else e.addClass(o),l(),t.startState=!0;w(t.footer).find(g)[t.endDate?\"removeClass\":\"addClass\"](s)}else\"static\"===n.position?(l(!0),t.calendar().done().done(null,\"change\")):\"date\"===n.type?(l(!0),t.setValue(t.parse()).remove().done()):\"datetime\"===n.type&&(l(!0),t.calendar().done(null,\"change\"))},T.prototype.tool=function(e,t){var n=this,a=n.config,i=a.dateTime,r=\"static\"===a.position,o={datetime:function(){w(e).hasClass(s)||(n.list(\"time\",0),a.range&&n.list(\"time\",1),w(e).attr(\"lay-type\",\"date\").html(n.lang().dateTips))},date:function(){n.closeList(),w(e).attr(\"lay-type\",\"datetime\").html(n.lang().timeTips)},clear:function(){n.setValue(\"\").remove(),r&&(w.extend(i,n.firstDate),n.calendar()),a.range&&(delete n.startState,delete n.endState,delete n.endDate,delete n.startTime,delete n.endTime),n.done([\"\",{},{}])},now:function(){var e=new Date;w.extend(i,n.systemDate(),{hours:e.getHours(),minutes:e.getMinutes(),seconds:e.getSeconds()}),n.setValue(n.parse()).remove(),r&&n.calendar(),n.done()},confirm:function(){if(a.range){if(!n.endDate)return n.hint(\"请先选择日期范围\");if(w(e).hasClass(s))return n.hint(\"time\"===a.type?l.replace(/日期/g,\"时间\"):l)}else if(w(e).hasClass(s))return n.hint(\"不在有效日期或时间范围内\");n.done(),n.setValue(n.parse()).remove()}};o[t]&&o[t]()},T.prototype.change=function(e){var t=this,n=t.config,a=n.dateTime,i=n.range&&(\"year\"===n.type||\"month\"===n.type),r=t.elemCont[e||0],o=t.listYM[e],s=function(s){var l=[\"startDate\",\"endDate\"][e],d=w(r).find(\".laydate-year-list\")[0],c=w(r).find(\".laydate-month-list\")[0];return d&&(o[0]=s?o[0]-15:o[0]+15,t.list(\"year\",e)),c&&(s?o[0]--:o[0]++,t.list(\"month\",e)),(d||c)&&(w.extend(a,{year:o[0]}),i&&(t[l].year=o[0]),n.range||t.done(null,\"change\"),t.setBtnStatus(),n.range||t.limit(w(t.footer).find(g),{year:o[0]})),d||c};return{prevYear:function(){s(\"sub\")||(a.year--,t.checkDate(\"limit\").calendar(),n.range||t.done(null,\"change\"))},prevMonth:function(){var e=t.getAsYM(a.year,a.month,\"sub\");w.extend(a,{year:e[0],month:e[1]}),t.checkDate(\"limit\").calendar(),n.range||t.done(null,\"change\")},nextMonth:function(){var e=t.getAsYM(a.year,a.month);w.extend(a,{year:e[0],month:e[1]}),t.checkDate(\"limit\").calendar(),n.range||t.done(null,\"change\")},nextYear:function(){s()||(a.year++,t.checkDate(\"limit\").calendar(),n.range||t.done(null,\"change\"))}}},T.prototype.changeEvent=function(){var e=this;e.config;w(e.elem).on(\"click\",function(e){w.stope(e)}),w.each(e.elemHeader,function(t,n){w(n[0]).on(\"click\",function(n){e.change(t).prevYear()}),w(n[1]).on(\"click\",function(n){e.change(t).prevMonth()}),w(n[2]).find(\"span\").on(\"click\",function(n){var a=w(this),i=a.attr(\"lay-ym\"),r=a.attr(\"lay-type\");i&&(i=i.split(\"-\"),e.listYM[t]=[0|i[0],0|i[1]],e.list(r,t),w(e.footer).find(D).addClass(s))}),w(n[3]).on(\"click\",function(n){e.change(t).nextMonth()}),w(n[4]).on(\"click\",function(n){e.change(t).nextYear()})}),w.each(e.table,function(t,n){var a=w(n).find(\"td\");a.on(\"click\",function(){e.choose(w(this))})}),w(e.footer).find(\"span\").on(\"click\",function(){var t=w(this).attr(\"lay-type\");e.tool(this,t)})},T.prototype.isInput=function(e){return/input|textarea/.test(e.tagName.toLocaleLowerCase())},T.prototype.events=function(){var e=this,t=e.config,n=function(n,a){n.on(t.trigger,function(){a&&(e.bindElem=this),e.render()})};t.elem[0]&&!t.elem[0].eventHandler&&(n(t.elem,\"bind\"),n(t.eventElem),w(document).on(\"click\",function(n){n.target!==t.elem[0]&&n.target!==t.eventElem[0]&&n.target!==w(t.closeStop)[0]&&e.remove()}).on(\"keydown\",function(t){13===t.keyCode&&w(\"#\"+e.elemID)[0]&&e.elemID===T.thisElem&&(t.preventDefault(),w(e.footer).find(g)[0].click())}),w(window).on(\"resize\",function(){return!(!e.elem||!w(r)[0])&&void e.position()}),t.elem[0].eventHandler=!0)},n.render=function(e){var t=new T(e);return a.call(t)},n.getEndDate=function(e,t){var n=new Date;return n.setFullYear(t||n.getFullYear(),e||n.getMonth()+1,1),new Date(n.getTime()-864e5).getDate()},window.lay=window.lay||w,e?(n.ready(),layui.define(function(e){n.path=layui.cache.dir,e(i,n)})):\"function\"==typeof define&&define.amd?define(function(){return n}):function(){n.ready(),window.laydate=n}()}();!function(e,t){\"object\"==typeof module&&\"object\"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error(\"jQuery requires a window with a document\");return t(e)}:t(e)}(\"undefined\"!=typeof window?window:this,function(e,t){function n(e){var t=!!e&&\"length\"in e&&e.length,n=pe.type(e);return\"function\"!==n&&!pe.isWindow(e)&&(\"array\"===n||0===t||\"number\"==typeof t&&t>0&&t-1 in e)}function r(e,t,n){if(pe.isFunction(t))return pe.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return pe.grep(e,function(e){return e===t!==n});if(\"string\"==typeof t){if(Ce.test(t))return pe.filter(t,e,n);t=pe.filter(t,e)}return pe.grep(e,function(e){return pe.inArray(e,t)>-1!==n})}function i(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}function o(e){var t={};return pe.each(e.match(De)||[],function(e,n){t[n]=!0}),t}function a(){re.addEventListener?(re.removeEventListener(\"DOMContentLoaded\",s),e.removeEventListener(\"load\",s)):(re.detachEvent(\"onreadystatechange\",s),e.detachEvent(\"onload\",s))}function s(){(re.addEventListener||\"load\"===e.event.type||\"complete\"===re.readyState)&&(a(),pe.ready())}function u(e,t,n){if(void 0===n&&1===e.nodeType){var r=\"data-\"+t.replace(_e,\"-$1\").toLowerCase();if(n=e.getAttribute(r),\"string\"==typeof n){try{n=\"true\"===n||\"false\"!==n&&(\"null\"===n?null:+n+\"\"===n?+n:qe.test(n)?pe.parseJSON(n):n)}catch(i){}pe.data(e,t,n)}else n=void 0}return n}function l(e){var t;for(t in e)if((\"data\"!==t||!pe.isEmptyObject(e[t]))&&\"toJSON\"!==t)return!1;return!0}function c(e,t,n,r){if(He(e)){var i,o,a=pe.expando,s=e.nodeType,u=s?pe.cache:e,l=s?e[a]:e[a]&&a;if(l&&u[l]&&(r||u[l].data)||void 0!==n||\"string\"!=typeof t)return l||(l=s?e[a]=ne.pop()||pe.guid++:a),u[l]||(u[l]=s?{}:{toJSON:pe.noop}),\"object\"!=typeof t&&\"function\"!=typeof t||(r?u[l]=pe.extend(u[l],t):u[l].data=pe.extend(u[l].data,t)),o=u[l],r||(o.data||(o.data={}),o=o.data),void 0!==n&&(o[pe.camelCase(t)]=n),\"string\"==typeof t?(i=o[t],null==i&&(i=o[pe.camelCase(t)])):i=o,i}}function f(e,t,n){if(He(e)){var r,i,o=e.nodeType,a=o?pe.cache:e,s=o?e[pe.expando]:pe.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){pe.isArray(t)?t=t.concat(pe.map(t,pe.camelCase)):t in r?t=[t]:(t=pe.camelCase(t),t=t in r?[t]:t.split(\" \")),i=t.length;for(;i--;)delete r[t[i]];if(n?!l(r):!pe.isEmptyObject(r))return}(n||(delete a[s].data,l(a[s])))&&(o?pe.cleanData([e],!0):fe.deleteExpando||a!=a.window?delete a[s]:a[s]=void 0)}}}function d(e,t,n,r){var i,o=1,a=20,s=r?function(){return r.cur()}:function(){return pe.css(e,t,\"\")},u=s(),l=n&&n[3]||(pe.cssNumber[t]?\"\":\"px\"),c=(pe.cssNumber[t]||\"px\"!==l&&+u)&&Me.exec(pe.css(e,t));if(c&&c[3]!==l){l=l||c[3],n=n||[],c=+u||1;do o=o||\".5\",c/=o,pe.style(e,t,c+l);while(o!==(o=s()/u)&&1!==o&&--a)}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}function p(e){var t=ze.split(\"|\"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}function h(e,t){var n,r,i=0,o=\"undefined\"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||\"*\"):\"undefined\"!=typeof e.querySelectorAll?e.querySelectorAll(t||\"*\"):void 0;if(!o)for(o=[],n=e.childNodes||e;null!=(r=n[i]);i++)!t||pe.nodeName(r,t)?o.push(r):pe.merge(o,h(r,t));return void 0===t||t&&pe.nodeName(e,t)?pe.merge([e],o):o}function g(e,t){for(var n,r=0;null!=(n=e[r]);r++)pe._data(n,\"globalEval\",!t||pe._data(t[r],\"globalEval\"))}function m(e){Be.test(e.type)&&(e.defaultChecked=e.checked)}function y(e,t,n,r,i){for(var o,a,s,u,l,c,f,d=e.length,y=p(t),v=[],x=0;x<d;x++)if(a=e[x],a||0===a)if(\"object\"===pe.type(a))pe.merge(v,a.nodeType?[a]:a);else if(Ue.test(a)){for(u=u||y.appendChild(t.createElement(\"div\")),l=(We.exec(a)||[\"\",\"\"])[1].toLowerCase(),f=Xe[l]||Xe._default,u.innerHTML=f[1]+pe.htmlPrefilter(a)+f[2],o=f[0];o--;)u=u.lastChild;if(!fe.leadingWhitespace&&$e.test(a)&&v.push(t.createTextNode($e.exec(a)[0])),!fe.tbody)for(a=\"table\"!==l||Ve.test(a)?\"<table>\"!==f[1]||Ve.test(a)?0:u:u.firstChild,o=a&&a.childNodes.length;o--;)pe.nodeName(c=a.childNodes[o],\"tbody\")&&!c.childNodes.length&&a.removeChild(c);for(pe.merge(v,u.childNodes),u.textContent=\"\";u.firstChild;)u.removeChild(u.firstChild);u=y.lastChild}else v.push(t.createTextNode(a));for(u&&y.removeChild(u),fe.appendChecked||pe.grep(h(v,\"input\"),m),x=0;a=v[x++];)if(r&&pe.inArray(a,r)>-1)i&&i.push(a);else if(s=pe.contains(a.ownerDocument,a),u=h(y.appendChild(a),\"script\"),s&&g(u),n)for(o=0;a=u[o++];)Ie.test(a.type||\"\")&&n.push(a);return u=null,y}function v(){return!0}function x(){return!1}function b(){try{return re.activeElement}catch(e){}}function w(e,t,n,r,i,o){var a,s;if(\"object\"==typeof t){\"string\"!=typeof n&&(r=r||n,n=void 0);for(s in t)w(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&(\"string\"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),i===!1)i=x;else if(!i)return e;return 1===o&&(a=i,i=function(e){return pe().off(e),a.apply(this,arguments)},i.guid=a.guid||(a.guid=pe.guid++)),e.each(function(){pe.event.add(this,t,i,r,n)})}function T(e,t){return pe.nodeName(e,\"table\")&&pe.nodeName(11!==t.nodeType?t:t.firstChild,\"tr\")?e.getElementsByTagName(\"tbody\")[0]||e.appendChild(e.ownerDocument.createElement(\"tbody\")):e}function C(e){return e.type=(null!==pe.find.attr(e,\"type\"))+\"/\"+e.type,e}function E(e){var t=it.exec(e.type);return t?e.type=t[1]:e.removeAttribute(\"type\"),e}function N(e,t){if(1===t.nodeType&&pe.hasData(e)){var n,r,i,o=pe._data(e),a=pe._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;r<i;r++)pe.event.add(t,n,s[n][r])}a.data&&(a.data=pe.extend({},a.data))}}function k(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!fe.noCloneEvent&&t[pe.expando]){i=pe._data(t);for(r in i.events)pe.removeEvent(t,r,i.handle);t.removeAttribute(pe.expando)}\"script\"===n&&t.text!==e.text?(C(t).text=e.text,E(t)):\"object\"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),fe.html5Clone&&e.innerHTML&&!pe.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):\"input\"===n&&Be.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):\"option\"===n?t.defaultSelected=t.selected=e.defaultSelected:\"input\"!==n&&\"textarea\"!==n||(t.defaultValue=e.defaultValue)}}function S(e,t,n,r){t=oe.apply([],t);var i,o,a,s,u,l,c=0,f=e.length,d=f-1,p=t[0],g=pe.isFunction(p);if(g||f>1&&\"string\"==typeof p&&!fe.checkClone&&rt.test(p))return e.each(function(i){var o=e.eq(i);g&&(t[0]=p.call(this,i,o.html())),S(o,t,n,r)});if(f&&(l=y(t,e[0].ownerDocument,!1,e,r),i=l.firstChild,1===l.childNodes.length&&(l=i),i||r)){for(s=pe.map(h(l,\"script\"),C),a=s.length;c<f;c++)o=l,c!==d&&(o=pe.clone(o,!0,!0),a&&pe.merge(s,h(o,\"script\"))),n.call(e[c],o,c);if(a)for(u=s[s.length-1].ownerDocument,pe.map(s,E),c=0;c<a;c++)o=s[c],Ie.test(o.type||\"\")&&!pe._data(o,\"globalEval\")&&pe.contains(u,o)&&(o.src?pe._evalUrl&&pe._evalUrl(o.src):pe.globalEval((o.text||o.textContent||o.innerHTML||\"\").replace(ot,\"\")));l=i=null}return e}function A(e,t,n){for(var r,i=t?pe.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||pe.cleanData(h(r)),r.parentNode&&(n&&pe.contains(r.ownerDocument,r)&&g(h(r,\"script\")),r.parentNode.removeChild(r));return e}function D(e,t){var n=pe(t.createElement(e)).appendTo(t.body),r=pe.css(n[0],\"display\");return n.detach(),r}function j(e){var t=re,n=lt[e];return n||(n=D(e,t),\"none\"!==n&&n||(ut=(ut||pe(\"<iframe frameborder='0' width='0' height='0'/>\")).appendTo(t.documentElement),t=(ut[0].contentWindow||ut[0].contentDocument).document,t.write(),t.close(),n=D(e,t),ut.detach()),lt[e]=n),n}function L(e,t){return{get:function(){return e()?void delete this.get:(this.get=t).apply(this,arguments)}}}function H(e){if(e in Et)return e;for(var t=e.charAt(0).toUpperCase()+e.slice(1),n=Ct.length;n--;)if(e=Ct[n]+t,e in Et)return e}function q(e,t){for(var n,r,i,o=[],a=0,s=e.length;a<s;a++)r=e[a],r.style&&(o[a]=pe._data(r,\"olddisplay\"),n=r.style.display,t?(o[a]||\"none\"!==n||(r.style.display=\"\"),\"\"===r.style.display&&Re(r)&&(o[a]=pe._data(r,\"olddisplay\",j(r.nodeName)))):(i=Re(r),(n&&\"none\"!==n||!i)&&pe._data(r,\"olddisplay\",i?n:pe.css(r,\"display\"))));for(a=0;a<s;a++)r=e[a],r.style&&(t&&\"none\"!==r.style.display&&\"\"!==r.style.display||(r.style.display=t?o[a]||\"\":\"none\"));return e}function _(e,t,n){var r=bt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||\"px\"):t}function F(e,t,n,r,i){for(var o=n===(r?\"border\":\"content\")?4:\"width\"===t?1:0,a=0;o<4;o+=2)\"margin\"===n&&(a+=pe.css(e,n+Oe[o],!0,i)),r?(\"content\"===n&&(a-=pe.css(e,\"padding\"+Oe[o],!0,i)),\"margin\"!==n&&(a-=pe.css(e,\"border\"+Oe[o]+\"Width\",!0,i))):(a+=pe.css(e,\"padding\"+Oe[o],!0,i),\"padding\"!==n&&(a+=pe.css(e,\"border\"+Oe[o]+\"Width\",!0,i)));return a}function M(t,n,r){var i=!0,o=\"width\"===n?t.offsetWidth:t.offsetHeight,a=ht(t),s=fe.boxSizing&&\"border-box\"===pe.css(t,\"boxSizing\",!1,a);if(re.msFullscreenElement&&e.top!==e&&t.getClientRects().length&&(o=Math.round(100*t.getBoundingClientRect()[n])),o<=0||null==o){if(o=gt(t,n,a),(o<0||null==o)&&(o=t.style[n]),ft.test(o))return o;i=s&&(fe.boxSizingReliable()||o===t.style[n]),o=parseFloat(o)||0}return o+F(t,n,r||(s?\"border\":\"content\"),i,a)+\"px\"}function O(e,t,n,r,i){return new O.prototype.init(e,t,n,r,i)}function R(){return e.setTimeout(function(){Nt=void 0}),Nt=pe.now()}function P(e,t){var n,r={height:e},i=0;for(t=t?1:0;i<4;i+=2-t)n=Oe[i],r[\"margin\"+n]=r[\"padding\"+n]=e;return t&&(r.opacity=r.width=e),r}function B(e,t,n){for(var r,i=($.tweeners[t]||[]).concat($.tweeners[\"*\"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function W(e,t,n){var r,i,o,a,s,u,l,c,f=this,d={},p=e.style,h=e.nodeType&&Re(e),g=pe._data(e,\"fxshow\");n.queue||(s=pe._queueHooks(e,\"fx\"),null==s.unqueued&&(s.unqueued=0,u=s.empty.fire,s.empty.fire=function(){s.unqueued||u()}),s.unqueued++,f.always(function(){f.always(function(){s.unqueued--,pe.queue(e,\"fx\").length||s.empty.fire()})})),1===e.nodeType&&(\"height\"in t||\"width\"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],l=pe.css(e,\"display\"),c=\"none\"===l?pe._data(e,\"olddisplay\")||j(e.nodeName):l,\"inline\"===c&&\"none\"===pe.css(e,\"float\")&&(fe.inlineBlockNeedsLayout&&\"inline\"!==j(e.nodeName)?p.zoom=1:p.display=\"inline-block\")),n.overflow&&(p.overflow=\"hidden\",fe.shrinkWrapBlocks()||f.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],St.exec(i)){if(delete t[r],o=o||\"toggle\"===i,i===(h?\"hide\":\"show\")){if(\"show\"!==i||!g||void 0===g[r])continue;h=!0}d[r]=g&&g[r]||pe.style(e,r)}else l=void 0;if(pe.isEmptyObject(d))\"inline\"===(\"none\"===l?j(e.nodeName):l)&&(p.display=l);else{g?\"hidden\"in g&&(h=g.hidden):g=pe._data(e,\"fxshow\",{}),o&&(g.hidden=!h),h?pe(e).show():f.done(function(){pe(e).hide()}),f.done(function(){var t;pe._removeData(e,\"fxshow\");for(t in d)pe.style(e,t,d[t])});for(r in d)a=B(h?g[r]:0,r,f),r in g||(g[r]=a.start,h&&(a.end=a.start,a.start=\"width\"===r||\"height\"===r?1:0))}}function I(e,t){var n,r,i,o,a;for(n in e)if(r=pe.camelCase(n),i=t[r],o=e[n],pe.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),a=pe.cssHooks[r],a&&\"expand\"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}function $(e,t,n){var r,i,o=0,a=$.prefilters.length,s=pe.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;for(var t=Nt||R(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,o=1-r,a=0,u=l.tweens.length;a<u;a++)l.tweens[a].run(o);return s.notifyWith(e,[l,o,n]),o<1&&u?n:(s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:pe.extend({},t),opts:pe.extend(!0,{specialEasing:{},easing:pe.easing._default},n),originalProperties:t,originalOptions:n,startTime:Nt||R(),duration:n.duration,tweens:[],createTween:function(t,n){var r=pe.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;n<r;n++)l.tweens[n].run(1);return t?(s.notifyWith(e,[l,1,0]),s.resolveWith(e,[l,t])):s.rejectWith(e,[l,t]),this}}),c=l.props;for(I(c,l.opts.specialEasing);o<a;o++)if(r=$.prefilters[o].call(l,e,c,l.opts))return pe.isFunction(r.stop)&&(pe._queueHooks(l.elem,l.opts.queue).stop=pe.proxy(r.stop,r)),r;return pe.map(c,B,l),pe.isFunction(l.opts.start)&&l.opts.start.call(e,l),pe.fx.timer(pe.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function z(e){return pe.attr(e,\"class\")||\"\"}function X(e){return function(t,n){\"string\"!=typeof t&&(n=t,t=\"*\");var r,i=0,o=t.toLowerCase().match(De)||[];if(pe.isFunction(n))for(;r=o[i++];)\"+\"===r.charAt(0)?(r=r.slice(1)||\"*\",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function U(e,t,n,r){function i(s){var u;return o[s]=!0,pe.each(e[s]||[],function(e,s){var l=s(t,n,r);return\"string\"!=typeof l||a||o[l]?a?!(u=l):void 0:(t.dataTypes.unshift(l),i(l),!1)}),u}var o={},a=e===Qt;return i(t.dataTypes[0])||!o[\"*\"]&&i(\"*\")}function V(e,t){var n,r,i=pe.ajaxSettings.flatOptions||{};for(r in t)void 0!==t[r]&&((i[r]?e:n||(n={}))[r]=t[r]);return n&&pe.extend(!0,e,n),e}function Y(e,t,n){for(var r,i,o,a,s=e.contents,u=e.dataTypes;\"*\"===u[0];)u.shift(),void 0===i&&(i=e.mimeType||t.getResponseHeader(\"Content-Type\"));if(i)for(a in s)if(s[a]&&s[a].test(i)){u.unshift(a);break}if(u[0]in n)o=u[0];else{for(a in n){if(!u[0]||e.converters[a+\" \"+u[0]]){o=a;break}r||(r=a)}o=o||r}if(o)return o!==u[0]&&u.unshift(o),n[o]}function J(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];for(o=c.shift();o;)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if(\"*\"===o)o=u;else if(\"*\"!==u&&u!==o){if(a=l[u+\" \"+o]||l[\"* \"+o],!a)for(i in l)if(s=i.split(\" \"),s[1]===o&&(a=l[u+\" \"+s[0]]||l[\"* \"+s[0]])){a===!0?a=l[i]:l[i]!==!0&&(o=s[0],c.unshift(s[1]));break}if(a!==!0)if(a&&e[\"throws\"])t=a(t);else try{t=a(t)}catch(f){return{state:\"parsererror\",error:a?f:\"No conversion from \"+u+\" to \"+o}}}return{state:\"success\",data:t}}function G(e){return e.style&&e.style.display||pe.css(e,\"display\")}function K(e){for(;e&&1===e.nodeType;){if(\"none\"===G(e)||\"hidden\"===e.type)return!0;e=e.parentNode}return!1}function Q(e,t,n,r){var i;if(pe.isArray(t))pe.each(t,function(t,i){n||rn.test(e)?r(e,i):Q(e+\"[\"+(\"object\"==typeof i&&null!=i?t:\"\")+\"]\",i,n,r)});else if(n||\"object\"!==pe.type(t))r(e,t);else for(i in t)Q(e+\"[\"+i+\"]\",t[i],n,r)}function Z(){try{return new e.XMLHttpRequest}catch(t){}}function ee(){try{return new e.ActiveXObject(\"Microsoft.XMLHTTP\")}catch(t){}}function te(e){return pe.isWindow(e)?e:9===e.nodeType&&(e.defaultView||e.parentWindow)}var ne=[],re=e.document,ie=ne.slice,oe=ne.concat,ae=ne.push,se=ne.indexOf,ue={},le=ue.toString,ce=ue.hasOwnProperty,fe={},de=\"1.12.3\",pe=function(e,t){return new pe.fn.init(e,t)},he=/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,ge=/^-ms-/,me=/-([\\da-z])/gi,ye=function(e,t){return t.toUpperCase()};pe.fn=pe.prototype={jquery:de,constructor:pe,selector:\"\",length:0,toArray:function(){return ie.call(this)},get:function(e){return null!=e?e<0?this[e+this.length]:this[e]:ie.call(this)},pushStack:function(e){var t=pe.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e){return pe.each(this,e)},map:function(e){return this.pushStack(pe.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(ie.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:ae,sort:ne.sort,splice:ne.splice},pe.extend=pe.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for(\"boolean\"==typeof a&&(l=a,a=arguments[s]||{},s++),\"object\"==typeof a||pe.isFunction(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(i=arguments[s]))for(r in i)e=a[r],n=i[r],a!==n&&(l&&n&&(pe.isPlainObject(n)||(t=pe.isArray(n)))?(t?(t=!1,o=e&&pe.isArray(e)?e:[]):o=e&&pe.isPlainObject(e)?e:{},a[r]=pe.extend(l,o,n)):void 0!==n&&(a[r]=n));return a},pe.extend({expando:\"jQuery\"+(de+Math.random()).replace(/\\D/g,\"\"),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isFunction:function(e){return\"function\"===pe.type(e)},isArray:Array.isArray||function(e){return\"array\"===pe.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){var t=e&&e.toString();return!pe.isArray(e)&&t-parseFloat(t)+1>=0},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},isPlainObject:function(e){var t;if(!e||\"object\"!==pe.type(e)||e.nodeType||pe.isWindow(e))return!1;try{if(e.constructor&&!ce.call(e,\"constructor\")&&!ce.call(e.constructor.prototype,\"isPrototypeOf\"))return!1}catch(n){return!1}if(!fe.ownFirst)for(t in e)return ce.call(e,t);for(t in e);return void 0===t||ce.call(e,t)},type:function(e){return null==e?e+\"\":\"object\"==typeof e||\"function\"==typeof e?ue[le.call(e)]||\"object\":typeof e},globalEval:function(t){t&&pe.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(ge,\"ms-\").replace(me,ye)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t){var r,i=0;if(n(e))for(r=e.length;i<r&&t.call(e[i],i,e[i])!==!1;i++);else for(i in e)if(t.call(e[i],i,e[i])===!1)break;return e},trim:function(e){return null==e?\"\":(e+\"\").replace(he,\"\")},makeArray:function(e,t){var r=t||[];return null!=e&&(n(Object(e))?pe.merge(r,\"string\"==typeof e?[e]:e):ae.call(r,e)),r},inArray:function(e,t,n){var r;if(t){if(se)return se.call(t,e,n);for(r=t.length,n=n?n<0?Math.max(0,r+n):n:0;n<r;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;)e[i++]=t[r++];if(n!==n)for(;void 0!==t[r];)e[i++]=t[r++];return e.length=i,e},grep:function(e,t,n){for(var r,i=[],o=0,a=e.length,s=!n;o<a;o++)r=!t(e[o],o),r!==s&&i.push(e[o]);return i},map:function(e,t,r){var i,o,a=0,s=[];if(n(e))for(i=e.length;a<i;a++)o=t(e[a],a,r),null!=o&&s.push(o);else for(a in e)o=t(e[a],a,r),null!=o&&s.push(o);return oe.apply([],s)},guid:1,proxy:function(e,t){var n,r,i;if(\"string\"==typeof t&&(i=e[t],t=e,e=i),pe.isFunction(e))return n=ie.call(arguments,2),r=function(){return e.apply(t||this,n.concat(ie.call(arguments)))},r.guid=e.guid=e.guid||pe.guid++,r},now:function(){return+new Date},support:fe}),\"function\"==typeof Symbol&&(pe.fn[Symbol.iterator]=ne[Symbol.iterator]),pe.each(\"Boolean Number String Function Array Date RegExp Object Error Symbol\".split(\" \"),function(e,t){ue[\"[object \"+t+\"]\"]=t.toLowerCase()});var ve=function(e){function t(e,t,n,r){var i,o,a,s,u,l,f,p,h=t&&t.ownerDocument,g=t?t.nodeType:9;if(n=n||[],\"string\"!=typeof e||!e||1!==g&&9!==g&&11!==g)return n;if(!r&&((t?t.ownerDocument||t:B)!==H&&L(t),t=t||H,_)){if(11!==g&&(l=ye.exec(e)))if(i=l[1]){if(9===g){if(!(a=t.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(h&&(a=h.getElementById(i))&&R(t,a)&&a.id===i)return n.push(a),n}else{if(l[2])return Q.apply(n,t.getElementsByTagName(e)),n;if((i=l[3])&&w.getElementsByClassName&&t.getElementsByClassName)return Q.apply(n,t.getElementsByClassName(i)),n}if(w.qsa&&!X[e+\" \"]&&(!F||!F.test(e))){if(1!==g)h=t,p=e;else if(\"object\"!==t.nodeName.toLowerCase()){for((s=t.getAttribute(\"id\"))?s=s.replace(xe,\"\\\\$&\"):t.setAttribute(\"id\",s=P),f=N(e),o=f.length,u=de.test(s)?\"#\"+s:\"[id='\"+s+\"']\";o--;)f[o]=u+\" \"+d(f[o]);p=f.join(\",\"),h=ve.test(e)&&c(t.parentNode)||t}if(p)try{return Q.apply(n,h.querySelectorAll(p)),n}catch(m){}finally{s===P&&t.removeAttribute(\"id\")}}}return S(e.replace(se,\"$1\"),t,n,r)}function n(){function e(n,r){return t.push(n+\" \")>T.cacheLength&&delete e[t.shift()],e[n+\" \"]=r}var t=[];return e}function r(e){return e[P]=!0,e}function i(e){var t=H.createElement(\"div\");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function o(e,t){for(var n=e.split(\"|\"),r=n.length;r--;)T.attrHandle[n[r]]=t}function a(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||V)-(~e.sourceIndex||V);if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function s(e){return function(t){var n=t.nodeName.toLowerCase();return\"input\"===n&&t.type===e}}function u(e){return function(t){var n=t.nodeName.toLowerCase();return(\"input\"===n||\"button\"===n)&&t.type===e}}function l(e){return r(function(t){return t=+t,r(function(n,r){for(var i,o=e([],n.length,t),a=o.length;a--;)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function c(e){return e&&\"undefined\"!=typeof e.getElementsByTagName&&e}function f(){}function d(e){for(var t=0,n=e.length,r=\"\";t<n;t++)r+=e[t].value;return r}function p(e,t,n){var r=t.dir,i=n&&\"parentNode\"===r,o=I++;return t.first?function(t,n,o){for(;t=t[r];)if(1===t.nodeType||i)return e(t,n,o)}:function(t,n,a){var s,u,l,c=[W,o];if(a){for(;t=t[r];)if((1===t.nodeType||i)&&e(t,n,a))return!0}else for(;t=t[r];)if(1===t.nodeType||i){if(l=t[P]||(t[P]={}),u=l[t.uniqueID]||(l[t.uniqueID]={}),(s=u[r])&&s[0]===W&&s[1]===o)return c[2]=s[2];if(u[r]=c,c[2]=e(t,n,a))return!0}}}function h(e){return e.length>1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function g(e,n,r){for(var i=0,o=n.length;i<o;i++)t(e,n[i],r);return r}function m(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function y(e,t,n,i,o,a){return i&&!i[P]&&(i=y(i)),o&&!o[P]&&(o=y(o,a)),r(function(r,a,s,u){var l,c,f,d=[],p=[],h=a.length,y=r||g(t||\"*\",s.nodeType?[s]:s,[]),v=!e||!r&&t?y:m(y,d,e,s,u),x=n?o||(r?e:h||i)?[]:a:v;if(n&&n(v,x,s,u),i)for(l=m(x,p),i(l,[],s,u),c=l.length;c--;)(f=l[c])&&(x[p[c]]=!(v[p[c]]=f));if(r){if(o||e){if(o){for(l=[],c=x.length;c--;)(f=x[c])&&l.push(v[c]=f);o(null,x=[],l,u)}for(c=x.length;c--;)(f=x[c])&&(l=o?ee(r,f):d[c])>-1&&(r[l]=!(a[l]=f))}}else x=m(x===a?x.splice(h,x.length):x),o?o(null,a,x,u):Q.apply(a,x)})}function v(e){for(var t,n,r,i=e.length,o=T.relative[e[0].type],a=o||T.relative[\" \"],s=o?1:0,u=p(function(e){return e===t},a,!0),l=p(function(e){return ee(t,e)>-1},a,!0),c=[function(e,n,r){var i=!o&&(r||n!==A)||((t=n).nodeType?u(e,n,r):l(e,n,r));return t=null,i}];s<i;s++)if(n=T.relative[e[s].type])c=[p(h(c),n)];else{if(n=T.filter[e[s].type].apply(null,e[s].matches),n[P]){for(r=++s;r<i&&!T.relative[e[r].type];r++);return y(s>1&&h(c),s>1&&d(e.slice(0,s-1).concat({value:\" \"===e[s-2].type?\"*\":\"\"})).replace(se,\"$1\"),n,s<r&&v(e.slice(s,r)),r<i&&v(e=e.slice(r)),r<i&&d(e))}c.push(n)}return h(c)}function x(e,n){var i=n.length>0,o=e.length>0,a=function(r,a,s,u,l){var c,f,d,p=0,h=\"0\",g=r&&[],y=[],v=A,x=r||o&&T.find.TAG(\"*\",l),b=W+=null==v?1:Math.random()||.1,w=x.length;for(l&&(A=a===H||a||l);h!==w&&null!=(c=x[h]);h++){if(o&&c){for(f=0,a||c.ownerDocument===H||(L(c),s=!_);d=e[f++];)if(d(c,a||H,s)){u.push(c);break}l&&(W=b)}i&&((c=!d&&c)&&p--,r&&g.push(c))}if(p+=h,i&&h!==p){for(f=0;d=n[f++];)d(g,y,a,s);if(r){if(p>0)for(;h--;)g[h]||y[h]||(y[h]=G.call(u));y=m(y)}Q.apply(u,y),l&&!r&&y.length>0&&p+n.length>1&&t.uniqueSort(u)}return l&&(W=b,A=v),g};return i?r(a):a}var b,w,T,C,E,N,k,S,A,D,j,L,H,q,_,F,M,O,R,P=\"sizzle\"+1*new Date,B=e.document,W=0,I=0,$=n(),z=n(),X=n(),U=function(e,t){return e===t&&(j=!0),0},V=1<<31,Y={}.hasOwnProperty,J=[],G=J.pop,K=J.push,Q=J.push,Z=J.slice,ee=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},te=\"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",ne=\"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",re=\"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",ie=\"\\\\[\"+ne+\"*(\"+re+\")(?:\"+ne+\"*([*^$|!~]?=)\"+ne+\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\"+re+\"))|)\"+ne+\"*\\\\]\",oe=\":(\"+re+\")(?:\\\\((('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\"+ie+\")*)|.*)\\\\)|)\",ae=new RegExp(ne+\"+\",\"g\"),se=new RegExp(\"^\"+ne+\"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\"+ne+\"+$\",\"g\"),ue=new RegExp(\"^\"+ne+\"*,\"+ne+\"*\"),le=new RegExp(\"^\"+ne+\"*([>+~]|\"+ne+\")\"+ne+\"*\"),ce=new RegExp(\"=\"+ne+\"*([^\\\\]'\\\"]*?)\"+ne+\"*\\\\]\",\"g\"),fe=new RegExp(oe),de=new RegExp(\"^\"+re+\"$\"),pe={ID:new RegExp(\"^#(\"+re+\")\"),CLASS:new RegExp(\"^\\\\.(\"+re+\")\"),TAG:new RegExp(\"^(\"+re+\"|[*])\"),ATTR:new RegExp(\"^\"+ie),PSEUDO:new RegExp(\"^\"+oe),CHILD:new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\"+ne+\"*(even|odd|(([+-]|)(\\\\d*)n|)\"+ne+\"*(?:([+-]|)\"+ne+\"*(\\\\d+)|))\"+ne+\"*\\\\)|)\",\"i\"),bool:new RegExp(\"^(?:\"+te+\")$\",\"i\"),needsContext:new RegExp(\"^\"+ne+\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\"+ne+\"*((?:-\\\\d)?\\\\d*)\"+ne+\"*\\\\)|)(?=[^-]|$)\",\"i\")},he=/^(?:input|select|textarea|button)$/i,ge=/^h\\d$/i,me=/^[^{]+\\{\\s*\\[native \\w/,ye=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,ve=/[+~]/,xe=/'|\\\\/g,be=new RegExp(\"\\\\\\\\([\\\\da-f]{1,6}\"+ne+\"?|(\"+ne+\")|.)\",\"ig\"),we=function(e,t,n){var r=\"0x\"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},Te=function(){L()};try{Q.apply(J=Z.call(B.childNodes),B.childNodes),J[B.childNodes.length].nodeType}catch(Ce){Q={apply:J.length?function(e,t){K.apply(e,Z.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}w=t.support={},E=t.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&\"HTML\"!==t.nodeName},L=t.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:B;return r!==H&&9===r.nodeType&&r.documentElement?(H=r,q=H.documentElement,_=!E(H),(n=H.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener(\"unload\",Te,!1):n.attachEvent&&n.attachEvent(\"onunload\",Te)),w.attributes=i(function(e){return e.className=\"i\",!e.getAttribute(\"className\")}),w.getElementsByTagName=i(function(e){return e.appendChild(H.createComment(\"\")),!e.getElementsByTagName(\"*\").length}),w.getElementsByClassName=me.test(H.getElementsByClassName),w.getById=i(function(e){return q.appendChild(e).id=P,!H.getElementsByName||!H.getElementsByName(P).length}),w.getById?(T.find.ID=function(e,t){if(\"undefined\"!=typeof t.getElementById&&_){var n=t.getElementById(e);return n?[n]:[]}},T.filter.ID=function(e){var t=e.replace(be,we);return function(e){return e.getAttribute(\"id\")===t}}):(delete T.find.ID,T.filter.ID=function(e){var t=e.replace(be,we);return function(e){var n=\"undefined\"!=typeof e.getAttributeNode&&e.getAttributeNode(\"id\");return n&&n.value===t}}),T.find.TAG=w.getElementsByTagName?function(e,t){return\"undefined\"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):w.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if(\"*\"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},T.find.CLASS=w.getElementsByClassName&&function(e,t){if(\"undefined\"!=typeof t.getElementsByClassName&&_)return t.getElementsByClassName(e)},M=[],F=[],(w.qsa=me.test(H.querySelectorAll))&&(i(function(e){q.appendChild(e).innerHTML=\"<a id='\"+P+\"'></a><select id='\"+P+\"-\\r\\\\' msallowcapture=''><option selected=''></option></select>\",e.querySelectorAll(\"[msallowcapture^='']\").length&&F.push(\"[*^$]=\"+ne+\"*(?:''|\\\"\\\")\"),e.querySelectorAll(\"[selected]\").length||F.push(\"\\\\[\"+ne+\"*(?:value|\"+te+\")\"),e.querySelectorAll(\"[id~=\"+P+\"-]\").length||F.push(\"~=\"),e.querySelectorAll(\":checked\").length||F.push(\":checked\"),e.querySelectorAll(\"a#\"+P+\"+*\").length||F.push(\".#.+[+~]\")}),i(function(e){var t=H.createElement(\"input\");t.setAttribute(\"type\",\"hidden\"),e.appendChild(t).setAttribute(\"name\",\"D\"),e.querySelectorAll(\"[name=d]\").length&&F.push(\"name\"+ne+\"*[*^$|!~]?=\"),e.querySelectorAll(\":enabled\").length||F.push(\":enabled\",\":disabled\"),e.querySelectorAll(\"*,:x\"),F.push(\",.*:\")})),(w.matchesSelector=me.test(O=q.matches||q.webkitMatchesSelector||q.mozMatchesSelector||q.oMatchesSelector||q.msMatchesSelector))&&i(function(e){w.disconnectedMatch=O.call(e,\"div\"),O.call(e,\"[s!='']:x\"),M.push(\"!=\",oe)}),F=F.length&&new RegExp(F.join(\"|\")),M=M.length&&new RegExp(M.join(\"|\")),t=me.test(q.compareDocumentPosition),R=t||me.test(q.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},U=t?function(e,t){if(e===t)return j=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n?n:(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&n||!w.sortDetached&&t.compareDocumentPosition(e)===n?e===H||e.ownerDocument===B&&R(B,e)?-1:t===H||t.ownerDocument===B&&R(B,t)?1:D?ee(D,e)-ee(D,t):0:4&n?-1:1)}:function(e,t){if(e===t)return j=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,s=[e],u=[t];if(!i||!o)return e===H?-1:t===H?1:i?-1:o?1:D?ee(D,e)-ee(D,t):0;if(i===o)return a(e,t);for(n=e;n=n.parentNode;)s.unshift(n);for(n=t;n=n.parentNode;)u.unshift(n);for(;s[r]===u[r];)r++;return r?a(s[r],u[r]):s[r]===B?-1:u[r]===B?1:0},H):H},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==H&&L(e),n=n.replace(ce,\"='$1']\"),w.matchesSelector&&_&&!X[n+\" \"]&&(!M||!M.test(n))&&(!F||!F.test(n)))try{var r=O.call(e,n);if(r||w.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(i){}return t(n,H,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==H&&L(e),R(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==H&&L(e);var n=T.attrHandle[t.toLowerCase()],r=n&&Y.call(T.attrHandle,t.toLowerCase())?n(e,t,!_):void 0;return void 0!==r?r:w.attributes||!_?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},t.error=function(e){throw new Error(\"Syntax error, unrecognized expression: \"+e)},t.uniqueSort=function(e){var t,n=[],r=0,i=0;if(j=!w.detectDuplicates,D=!w.sortStable&&e.slice(0),e.sort(U),j){for(;t=e[i++];)t===e[i]&&(r=n.push(i));for(;r--;)e.splice(n[r],1)}return D=null,e},C=t.getText=function(e){var t,n=\"\",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if(\"string\"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=C(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r++];)n+=C(t);return n},T=t.selectors={cacheLength:50,createPseudo:r,match:pe,attrHandle:{},find:{},relative:{\">\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(be,we),e[3]=(e[3]||e[4]||e[5]||\"\").replace(be,we),\"~=\"===e[2]&&(e[3]=\" \"+e[3]+\" \"),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),\"nth\"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*(\"even\"===e[3]||\"odd\"===e[3])),e[5]=+(e[7]+e[8]||\"odd\"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return pe.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||\"\":n&&fe.test(n)&&(t=N(n,!0))&&(t=n.indexOf(\")\",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(be,we).toLowerCase();return\"*\"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=$[e+\" \"];return t||(t=new RegExp(\"(^|\"+ne+\")\"+e+\"(\"+ne+\"|$)\"))&&$(e,function(e){return t.test(\"string\"==typeof e.className&&e.className||\"undefined\"!=typeof e.getAttribute&&e.getAttribute(\"class\")||\"\")})},ATTR:function(e,n,r){return function(i){var o=t.attr(i,e);return null==o?\"!=\"===n:!n||(o+=\"\",\"=\"===n?o===r:\"!=\"===n?o!==r:\"^=\"===n?r&&0===o.indexOf(r):\"*=\"===n?r&&o.indexOf(r)>-1:\"$=\"===n?r&&o.slice(-r.length)===r:\"~=\"===n?(\" \"+o.replace(ae,\" \")+\" \").indexOf(r)>-1:\"|=\"===n&&(o===r||o.slice(0,r.length+1)===r+\"-\"))}},CHILD:function(e,t,n,r,i){var o=\"nth\"!==e.slice(0,3),a=\"last\"!==e.slice(-4),s=\"of-type\"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,d,p,h,g=o!==a?\"nextSibling\":\"previousSibling\",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!u&&!s,x=!1;if(m){if(o){for(;g;){for(d=t;d=d[g];)if(s?d.nodeName.toLowerCase()===y:1===d.nodeType)return!1;h=g=\"only\"===e&&!h&&\"nextSibling\"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){for(d=m,f=d[P]||(d[P]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),\nl=c[e]||[],p=l[0]===W&&l[1],x=p&&l[2],d=p&&m.childNodes[p];d=++p&&d&&d[g]||(x=p=0)||h.pop();)if(1===d.nodeType&&++x&&d===t){c[e]=[W,p,x];break}}else if(v&&(d=t,f=d[P]||(d[P]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),l=c[e]||[],p=l[0]===W&&l[1],x=p),x===!1)for(;(d=++p&&d&&d[g]||(x=p=0)||h.pop())&&((s?d.nodeName.toLowerCase()!==y:1!==d.nodeType)||!++x||(v&&(f=d[P]||(d[P]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),c[e]=[W,x]),d!==t)););return x-=i,x===r||x%r===0&&x/r>=0}}},PSEUDO:function(e,n){var i,o=T.pseudos[e]||T.setFilters[e.toLowerCase()]||t.error(\"unsupported pseudo: \"+e);return o[P]?o(n):o.length>1?(i=[e,e,\"\",n],T.setFilters.hasOwnProperty(e.toLowerCase())?r(function(e,t){for(var r,i=o(e,n),a=i.length;a--;)r=ee(e,i[a]),e[r]=!(t[r]=i[a])}):function(e){return o(e,0,i)}):o}},pseudos:{not:r(function(e){var t=[],n=[],i=k(e.replace(se,\"$1\"));return i[P]?r(function(e,t,n,r){for(var o,a=i(e,null,r,[]),s=e.length;s--;)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,r,o){return t[0]=e,i(t,null,o,n),t[0]=null,!n.pop()}}),has:r(function(e){return function(n){return t(e,n).length>0}}),contains:r(function(e){return e=e.replace(be,we),function(t){return(t.textContent||t.innerText||C(t)).indexOf(e)>-1}}),lang:r(function(e){return de.test(e||\"\")||t.error(\"unsupported lang: \"+e),e=e.replace(be,we).toLowerCase(),function(t){var n;do if(n=_?t.lang:t.getAttribute(\"xml:lang\")||t.getAttribute(\"lang\"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+\"-\");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===q},focus:function(e){return e===H.activeElement&&(!H.hasFocus||H.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&!!e.checked||\"option\"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!T.pseudos.empty(e)},header:function(e){return ge.test(e.nodeName)},input:function(e){return he.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&\"button\"===e.type||\"button\"===t},text:function(e){var t;return\"input\"===e.nodeName.toLowerCase()&&\"text\"===e.type&&(null==(t=e.getAttribute(\"type\"))||\"text\"===t.toLowerCase())},first:l(function(){return[0]}),last:l(function(e,t){return[t-1]}),eq:l(function(e,t,n){return[n<0?n+t:n]}),even:l(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:l(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:l(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:l(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}},T.pseudos.nth=T.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})T.pseudos[b]=s(b);for(b in{submit:!0,reset:!0})T.pseudos[b]=u(b);return f.prototype=T.filters=T.pseudos,T.setFilters=new f,N=t.tokenize=function(e,n){var r,i,o,a,s,u,l,c=z[e+\" \"];if(c)return n?0:c.slice(0);for(s=e,u=[],l=T.preFilter;s;){r&&!(i=ue.exec(s))||(i&&(s=s.slice(i[0].length)||s),u.push(o=[])),r=!1,(i=le.exec(s))&&(r=i.shift(),o.push({value:r,type:i[0].replace(se,\" \")}),s=s.slice(r.length));for(a in T.filter)!(i=pe[a].exec(s))||l[a]&&!(i=l[a](i))||(r=i.shift(),o.push({value:r,type:a,matches:i}),s=s.slice(r.length));if(!r)break}return n?s.length:s?t.error(e):z(e,u).slice(0)},k=t.compile=function(e,t){var n,r=[],i=[],o=X[e+\" \"];if(!o){for(t||(t=N(e)),n=t.length;n--;)o=v(t[n]),o[P]?r.push(o):i.push(o);o=X(e,x(i,r)),o.selector=e}return o},S=t.select=function(e,t,n,r){var i,o,a,s,u,l=\"function\"==typeof e&&e,f=!r&&N(e=l.selector||e);if(n=n||[],1===f.length){if(o=f[0]=f[0].slice(0),o.length>2&&\"ID\"===(a=o[0]).type&&w.getById&&9===t.nodeType&&_&&T.relative[o[1].type]){if(t=(T.find.ID(a.matches[0].replace(be,we),t)||[])[0],!t)return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}for(i=pe.needsContext.test(e)?0:o.length;i--&&(a=o[i],!T.relative[s=a.type]);)if((u=T.find[s])&&(r=u(a.matches[0].replace(be,we),ve.test(o[0].type)&&c(t.parentNode)||t))){if(o.splice(i,1),e=r.length&&d(o),!e)return Q.apply(n,r),n;break}}return(l||k(e,f))(r,t,!_,n,!t||ve.test(e)&&c(t.parentNode)||t),n},w.sortStable=P.split(\"\").sort(U).join(\"\")===P,w.detectDuplicates=!!j,L(),w.sortDetached=i(function(e){return 1&e.compareDocumentPosition(H.createElement(\"div\"))}),i(function(e){return e.innerHTML=\"<a href='#'></a>\",\"#\"===e.firstChild.getAttribute(\"href\")})||o(\"type|href|height|width\",function(e,t,n){if(!n)return e.getAttribute(t,\"type\"===t.toLowerCase()?1:2)}),w.attributes&&i(function(e){return e.innerHTML=\"<input/>\",e.firstChild.setAttribute(\"value\",\"\"),\"\"===e.firstChild.getAttribute(\"value\")})||o(\"value\",function(e,t,n){if(!n&&\"input\"===e.nodeName.toLowerCase())return e.defaultValue}),i(function(e){return null==e.getAttribute(\"disabled\")})||o(te,function(e,t,n){var r;if(!n)return e[t]===!0?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),t}(e);pe.find=ve,pe.expr=ve.selectors,pe.expr[\":\"]=pe.expr.pseudos,pe.uniqueSort=pe.unique=ve.uniqueSort,pe.text=ve.getText,pe.isXMLDoc=ve.isXML,pe.contains=ve.contains;var xe=function(e,t,n){for(var r=[],i=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&pe(e).is(n))break;r.push(e)}return r},be=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},we=pe.expr.match.needsContext,Te=/^<([\\w-]+)\\s*\\/?>(?:<\\/\\1>|)$/,Ce=/^.[^:#\\[\\.,]*$/;pe.filter=function(e,t,n){var r=t[0];return n&&(e=\":not(\"+e+\")\"),1===t.length&&1===r.nodeType?pe.find.matchesSelector(r,e)?[r]:[]:pe.find.matches(e,pe.grep(t,function(e){return 1===e.nodeType}))},pe.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if(\"string\"!=typeof e)return this.pushStack(pe(e).filter(function(){for(t=0;t<i;t++)if(pe.contains(r[t],this))return!0}));for(t=0;t<i;t++)pe.find(e,r[t],n);return n=this.pushStack(i>1?pe.unique(n):n),n.selector=this.selector?this.selector+\" \"+e:e,n},filter:function(e){return this.pushStack(r(this,e||[],!1))},not:function(e){return this.pushStack(r(this,e||[],!0))},is:function(e){return!!r(this,\"string\"==typeof e&&we.test(e)?pe(e):e||[],!1).length}});var Ee,Ne=/^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,ke=pe.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||Ee,\"string\"==typeof e){if(r=\"<\"===e.charAt(0)&&\">\"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:Ne.exec(e),!r||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof pe?t[0]:t,pe.merge(this,pe.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:re,!0)),Te.test(r[1])&&pe.isPlainObject(t))for(r in t)pe.isFunction(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}if(i=re.getElementById(r[2]),i&&i.parentNode){if(i.id!==r[2])return Ee.find(e);this.length=1,this[0]=i}return this.context=re,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):pe.isFunction(e)?\"undefined\"!=typeof n.ready?n.ready(e):e(pe):(void 0!==e.selector&&(this.selector=e.selector,this.context=e.context),pe.makeArray(e,this))};ke.prototype=pe.fn,Ee=pe(re);var Se=/^(?:parents|prev(?:Until|All))/,Ae={children:!0,contents:!0,next:!0,prev:!0};pe.fn.extend({has:function(e){var t,n=pe(e,this),r=n.length;return this.filter(function(){for(t=0;t<r;t++)if(pe.contains(this,n[t]))return!0})},closest:function(e,t){for(var n,r=0,i=this.length,o=[],a=we.test(e)||\"string\"!=typeof e?pe(e,t||this.context):0;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?a.index(n)>-1:1===n.nodeType&&pe.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?pe.uniqueSort(o):o)},index:function(e){return e?\"string\"==typeof e?pe.inArray(this[0],pe(e)):pe.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(pe.uniqueSort(pe.merge(this.get(),pe(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),pe.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return xe(e,\"parentNode\")},parentsUntil:function(e,t,n){return xe(e,\"parentNode\",n)},next:function(e){return i(e,\"nextSibling\")},prev:function(e){return i(e,\"previousSibling\")},nextAll:function(e){return xe(e,\"nextSibling\")},prevAll:function(e){return xe(e,\"previousSibling\")},nextUntil:function(e,t,n){return xe(e,\"nextSibling\",n)},prevUntil:function(e,t,n){return xe(e,\"previousSibling\",n)},siblings:function(e){return be((e.parentNode||{}).firstChild,e)},children:function(e){return be(e.firstChild)},contents:function(e){return pe.nodeName(e,\"iframe\")?e.contentDocument||e.contentWindow.document:pe.merge([],e.childNodes)}},function(e,t){pe.fn[e]=function(n,r){var i=pe.map(this,t,n);return\"Until\"!==e.slice(-5)&&(r=n),r&&\"string\"==typeof r&&(i=pe.filter(r,i)),this.length>1&&(Ae[e]||(i=pe.uniqueSort(i)),Se.test(e)&&(i=i.reverse())),this.pushStack(i)}});var De=/\\S+/g;pe.Callbacks=function(e){e=\"string\"==typeof e?o(e):pe.extend({},e);var t,n,r,i,a=[],s=[],u=-1,l=function(){for(i=e.once,r=t=!0;s.length;u=-1)for(n=s.shift();++u<a.length;)a[u].apply(n[0],n[1])===!1&&e.stopOnFalse&&(u=a.length,n=!1);e.memory||(n=!1),t=!1,i&&(a=n?[]:\"\")},c={add:function(){return a&&(n&&!t&&(u=a.length-1,s.push(n)),function r(t){pe.each(t,function(t,n){pe.isFunction(n)?e.unique&&c.has(n)||a.push(n):n&&n.length&&\"string\"!==pe.type(n)&&r(n)})}(arguments),n&&!t&&l()),this},remove:function(){return pe.each(arguments,function(e,t){for(var n;(n=pe.inArray(t,a,n))>-1;)a.splice(n,1),n<=u&&u--}),this},has:function(e){return e?pe.inArray(e,a)>-1:a.length>0},empty:function(){return a&&(a=[]),this},disable:function(){return i=s=[],a=n=\"\",this},disabled:function(){return!a},lock:function(){return i=!0,n||c.disable(),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=n||[],n=[e,n.slice?n.slice():n],s.push(n),t||l()),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},pe.extend({Deferred:function(e){var t=[[\"resolve\",\"done\",pe.Callbacks(\"once memory\"),\"resolved\"],[\"reject\",\"fail\",pe.Callbacks(\"once memory\"),\"rejected\"],[\"notify\",\"progress\",pe.Callbacks(\"memory\")]],n=\"pending\",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return pe.Deferred(function(n){pe.each(t,function(t,o){var a=pe.isFunction(e[t])&&e[t];i[o[1]](function(){var e=a&&a.apply(this,arguments);e&&pe.isFunction(e.promise)?e.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[o[0]+\"With\"](this===r?n.promise():this,a?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?pe.extend(e,r):r}},i={};return r.pipe=r.then,pe.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+\"With\"](this===i?r:this,arguments),this},i[o[0]+\"With\"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t,n,r,i=0,o=ie.call(arguments),a=o.length,s=1!==a||e&&pe.isFunction(e.promise)?a:0,u=1===s?e:pe.Deferred(),l=function(e,n,r){return function(i){n[e]=this,r[e]=arguments.length>1?ie.call(arguments):i,r===t?u.notifyWith(n,r):--s||u.resolveWith(n,r)}};if(a>1)for(t=new Array(a),n=new Array(a),r=new Array(a);i<a;i++)o[i]&&pe.isFunction(o[i].promise)?o[i].promise().progress(l(i,n,t)).done(l(i,r,o)).fail(u.reject):--s;return s||u.resolveWith(r,o),u.promise()}});var je;pe.fn.ready=function(e){return pe.ready.promise().done(e),this},pe.extend({isReady:!1,readyWait:1,holdReady:function(e){e?pe.readyWait++:pe.ready(!0)},ready:function(e){(e===!0?--pe.readyWait:pe.isReady)||(pe.isReady=!0,e!==!0&&--pe.readyWait>0||(je.resolveWith(re,[pe]),pe.fn.triggerHandler&&(pe(re).triggerHandler(\"ready\"),pe(re).off(\"ready\"))))}}),pe.ready.promise=function(t){if(!je)if(je=pe.Deferred(),\"complete\"===re.readyState||\"loading\"!==re.readyState&&!re.documentElement.doScroll)e.setTimeout(pe.ready);else if(re.addEventListener)re.addEventListener(\"DOMContentLoaded\",s),e.addEventListener(\"load\",s);else{re.attachEvent(\"onreadystatechange\",s),e.attachEvent(\"onload\",s);var n=!1;try{n=null==e.frameElement&&re.documentElement}catch(r){}n&&n.doScroll&&!function i(){if(!pe.isReady){try{n.doScroll(\"left\")}catch(t){return e.setTimeout(i,50)}a(),pe.ready()}}()}return je.promise(t)},pe.ready.promise();var Le;for(Le in pe(fe))break;fe.ownFirst=\"0\"===Le,fe.inlineBlockNeedsLayout=!1,pe(function(){var e,t,n,r;n=re.getElementsByTagName(\"body\")[0],n&&n.style&&(t=re.createElement(\"div\"),r=re.createElement(\"div\"),r.style.cssText=\"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\",n.appendChild(r).appendChild(t),\"undefined\"!=typeof t.style.zoom&&(t.style.cssText=\"display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1\",fe.inlineBlockNeedsLayout=e=3===t.offsetWidth,e&&(n.style.zoom=1)),n.removeChild(r))}),function(){var e=re.createElement(\"div\");fe.deleteExpando=!0;try{delete e.test}catch(t){fe.deleteExpando=!1}e=null}();var He=function(e){var t=pe.noData[(e.nodeName+\" \").toLowerCase()],n=+e.nodeType||1;return(1===n||9===n)&&(!t||t!==!0&&e.getAttribute(\"classid\")===t)},qe=/^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,_e=/([A-Z])/g;pe.extend({cache:{},noData:{\"applet \":!0,\"embed \":!0,\"object \":\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"},hasData:function(e){return e=e.nodeType?pe.cache[e[pe.expando]]:e[pe.expando],!!e&&!l(e)},data:function(e,t,n){return c(e,t,n)},removeData:function(e,t){return f(e,t)},_data:function(e,t,n){return c(e,t,n,!0)},_removeData:function(e,t){return f(e,t,!0)}}),pe.fn.extend({data:function(e,t){var n,r,i,o=this[0],a=o&&o.attributes;if(void 0===e){if(this.length&&(i=pe.data(o),1===o.nodeType&&!pe._data(o,\"parsedAttrs\"))){for(n=a.length;n--;)a[n]&&(r=a[n].name,0===r.indexOf(\"data-\")&&(r=pe.camelCase(r.slice(5)),u(o,r,i[r])));pe._data(o,\"parsedAttrs\",!0)}return i}return\"object\"==typeof e?this.each(function(){pe.data(this,e)}):arguments.length>1?this.each(function(){pe.data(this,e,t)}):o?u(o,e,pe.data(o,e)):void 0},removeData:function(e){return this.each(function(){pe.removeData(this,e)})}}),pe.extend({queue:function(e,t,n){var r;if(e)return t=(t||\"fx\")+\"queue\",r=pe._data(e,t),n&&(!r||pe.isArray(n)?r=pe._data(e,t,pe.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||\"fx\";var n=pe.queue(e,t),r=n.length,i=n.shift(),o=pe._queueHooks(e,t),a=function(){pe.dequeue(e,t)};\"inprogress\"===i&&(i=n.shift(),r--),i&&(\"fx\"===t&&n.unshift(\"inprogress\"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+\"queueHooks\";return pe._data(e,n)||pe._data(e,n,{empty:pe.Callbacks(\"once memory\").add(function(){pe._removeData(e,t+\"queue\"),pe._removeData(e,n)})})}}),pe.fn.extend({queue:function(e,t){var n=2;return\"string\"!=typeof e&&(t=e,e=\"fx\",n--),arguments.length<n?pe.queue(this[0],e):void 0===t?this:this.each(function(){var n=pe.queue(this,e,t);pe._queueHooks(this,e),\"fx\"===e&&\"inprogress\"!==n[0]&&pe.dequeue(this,e)})},dequeue:function(e){return this.each(function(){pe.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||\"fx\",[])},promise:function(e,t){var n,r=1,i=pe.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};for(\"string\"!=typeof e&&(t=e,e=void 0),e=e||\"fx\";a--;)n=pe._data(o[a],e+\"queueHooks\"),n&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}}),function(){var e;fe.shrinkWrapBlocks=function(){if(null!=e)return e;e=!1;var t,n,r;return n=re.getElementsByTagName(\"body\")[0],n&&n.style?(t=re.createElement(\"div\"),r=re.createElement(\"div\"),r.style.cssText=\"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\",n.appendChild(r).appendChild(t),\"undefined\"!=typeof t.style.zoom&&(t.style.cssText=\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1\",t.appendChild(re.createElement(\"div\")).style.width=\"5px\",e=3!==t.offsetWidth),n.removeChild(r),e):void 0}}();var Fe=/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source,Me=new RegExp(\"^(?:([+-])=|)(\"+Fe+\")([a-z%]*)$\",\"i\"),Oe=[\"Top\",\"Right\",\"Bottom\",\"Left\"],Re=function(e,t){return e=t||e,\"none\"===pe.css(e,\"display\")||!pe.contains(e.ownerDocument,e)},Pe=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if(\"object\"===pe.type(n)){i=!0;for(s in n)Pe(e,t,s,n[s],!0,o,a)}else if(void 0!==r&&(i=!0,pe.isFunction(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(pe(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},Be=/^(?:checkbox|radio)$/i,We=/<([\\w:-]+)/,Ie=/^$|\\/(?:java|ecma)script/i,$e=/^\\s+/,ze=\"abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video\";!function(){var e=re.createElement(\"div\"),t=re.createDocumentFragment(),n=re.createElement(\"input\");e.innerHTML=\"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\",fe.leadingWhitespace=3===e.firstChild.nodeType,fe.tbody=!e.getElementsByTagName(\"tbody\").length,fe.htmlSerialize=!!e.getElementsByTagName(\"link\").length,fe.html5Clone=\"<:nav></:nav>\"!==re.createElement(\"nav\").cloneNode(!0).outerHTML,n.type=\"checkbox\",n.checked=!0,t.appendChild(n),fe.appendChecked=n.checked,e.innerHTML=\"<textarea>x</textarea>\",fe.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue,t.appendChild(e),n=re.createElement(\"input\"),n.setAttribute(\"type\",\"radio\"),n.setAttribute(\"checked\",\"checked\"),n.setAttribute(\"name\",\"t\"),e.appendChild(n),fe.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,fe.noCloneEvent=!!e.addEventListener,e[pe.expando]=1,fe.attributes=!e.getAttribute(pe.expando)}();var Xe={option:[1,\"<select multiple='multiple'>\",\"</select>\"],legend:[1,\"<fieldset>\",\"</fieldset>\"],area:[1,\"<map>\",\"</map>\"],param:[1,\"<object>\",\"</object>\"],thead:[1,\"<table>\",\"</table>\"],tr:[2,\"<table><tbody>\",\"</tbody></table>\"],col:[2,\"<table><tbody></tbody><colgroup>\",\"</colgroup></table>\"],td:[3,\"<table><tbody><tr>\",\"</tr></tbody></table>\"],_default:fe.htmlSerialize?[0,\"\",\"\"]:[1,\"X<div>\",\"</div>\"]};Xe.optgroup=Xe.option,Xe.tbody=Xe.tfoot=Xe.colgroup=Xe.caption=Xe.thead,Xe.th=Xe.td;var Ue=/<|&#?\\w+;/,Ve=/<tbody/i;!function(){var t,n,r=re.createElement(\"div\");for(t in{submit:!0,change:!0,focusin:!0})n=\"on\"+t,(fe[t]=n in e)||(r.setAttribute(n,\"t\"),fe[t]=r.attributes[n].expando===!1);r=null}();var Ye=/^(?:input|select|textarea)$/i,Je=/^key/,Ge=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ke=/^(?:focusinfocus|focusoutblur)$/,Qe=/^([^.]*)(?:\\.(.+)|)/;pe.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,d,p,h,g,m=pe._data(e);if(m){for(n.handler&&(u=n,n=u.handler,i=u.selector),n.guid||(n.guid=pe.guid++),(a=m.events)||(a=m.events={}),(c=m.handle)||(c=m.handle=function(e){return\"undefined\"==typeof pe||e&&pe.event.triggered===e.type?void 0:pe.event.dispatch.apply(c.elem,arguments)},c.elem=e),t=(t||\"\").match(De)||[\"\"],s=t.length;s--;)o=Qe.exec(t[s])||[],p=g=o[1],h=(o[2]||\"\").split(\".\").sort(),p&&(l=pe.event.special[p]||{},p=(i?l.delegateType:l.bindType)||p,l=pe.event.special[p]||{},f=pe.extend({type:p,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&pe.expr.match.needsContext.test(i),namespace:h.join(\".\")},u),(d=a[p])||(d=a[p]=[],d.delegateCount=0,l.setup&&l.setup.call(e,r,h,c)!==!1||(e.addEventListener?e.addEventListener(p,c,!1):e.attachEvent&&e.attachEvent(\"on\"+p,c))),l.add&&(l.add.call(e,f),f.handler.guid||(f.handler.guid=n.guid)),i?d.splice(d.delegateCount++,0,f):d.push(f),pe.event.global[p]=!0);e=null}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,d,p,h,g,m=pe.hasData(e)&&pe._data(e);if(m&&(c=m.events)){for(t=(t||\"\").match(De)||[\"\"],l=t.length;l--;)if(s=Qe.exec(t[l])||[],p=g=s[1],h=(s[2]||\"\").split(\".\").sort(),p){for(f=pe.event.special[p]||{},p=(r?f.delegateType:f.bindType)||p,d=c[p]||[],s=s[2]&&new RegExp(\"(^|\\\\.)\"+h.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"),u=o=d.length;o--;)a=d[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&(\"**\"!==r||!a.selector)||(d.splice(o,1),a.selector&&d.delegateCount--,f.remove&&f.remove.call(e,a));u&&!d.length&&(f.teardown&&f.teardown.call(e,h,m.handle)!==!1||pe.removeEvent(e,p,m.handle),delete c[p])}else for(p in c)pe.event.remove(e,p+t[l],n,r,!0);pe.isEmptyObject(c)&&(delete m.handle,pe._removeData(e,\"events\"))}},trigger:function(t,n,r,i){var o,a,s,u,l,c,f,d=[r||re],p=ce.call(t,\"type\")?t.type:t,h=ce.call(t,\"namespace\")?t.namespace.split(\".\"):[];if(s=c=r=r||re,3!==r.nodeType&&8!==r.nodeType&&!Ke.test(p+pe.event.triggered)&&(p.indexOf(\".\")>-1&&(h=p.split(\".\"),p=h.shift(),h.sort()),a=p.indexOf(\":\")<0&&\"on\"+p,t=t[pe.expando]?t:new pe.Event(p,\"object\"==typeof t&&t),t.isTrigger=i?2:3,t.namespace=h.join(\".\"),t.rnamespace=t.namespace?new RegExp(\"(^|\\\\.)\"+h.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"):null,t.result=void 0,t.target||(t.target=r),n=null==n?[t]:pe.makeArray(n,[t]),l=pe.event.special[p]||{},i||!l.trigger||l.trigger.apply(r,n)!==!1)){if(!i&&!l.noBubble&&!pe.isWindow(r)){for(u=l.delegateType||p,Ke.test(u+p)||(s=s.parentNode);s;s=s.parentNode)d.push(s),c=s;c===(r.ownerDocument||re)&&d.push(c.defaultView||c.parentWindow||e)}for(f=0;(s=d[f++])&&!t.isPropagationStopped();)t.type=f>1?u:l.bindType||p,o=(pe._data(s,\"events\")||{})[t.type]&&pe._data(s,\"handle\"),o&&o.apply(s,n),o=a&&s[a],o&&o.apply&&He(s)&&(t.result=o.apply(s,n),t.result===!1&&t.preventDefault());if(t.type=p,!i&&!t.isDefaultPrevented()&&(!l._default||l._default.apply(d.pop(),n)===!1)&&He(r)&&a&&r[p]&&!pe.isWindow(r)){c=r[a],c&&(r[a]=null),pe.event.triggered=p;try{r[p]()}catch(g){}pe.event.triggered=void 0,c&&(r[a]=c)}return t.result}},dispatch:function(e){e=pe.event.fix(e);var t,n,r,i,o,a=[],s=ie.call(arguments),u=(pe._data(this,\"events\")||{})[e.type]||[],l=pe.event.special[e.type]||{};if(s[0]=e,e.delegateTarget=this,!l.preDispatch||l.preDispatch.call(this,e)!==!1){for(a=pe.event.handlers.call(this,e,u),t=0;(i=a[t++])&&!e.isPropagationStopped();)for(e.currentTarget=i.elem,n=0;(o=i.handlers[n++])&&!e.isImmediatePropagationStopped();)e.rnamespace&&!e.rnamespace.test(o.namespace)||(e.handleObj=o,e.data=o.data,r=((pe.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s),void 0!==r&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()));return l.postDispatch&&l.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,r,i,o,a=[],s=t.delegateCount,u=e.target;if(s&&u.nodeType&&(\"click\"!==e.type||isNaN(e.button)||e.button<1))for(;u!=this;u=u.parentNode||this)if(1===u.nodeType&&(u.disabled!==!0||\"click\"!==e.type)){for(r=[],n=0;n<s;n++)o=t[n],i=o.selector+\" \",void 0===r[i]&&(r[i]=o.needsContext?pe(i,this).index(u)>-1:pe.find(i,this,null,[u]).length),r[i]&&r.push(o);r.length&&a.push({elem:u,handlers:r})}return s<t.length&&a.push({elem:this,handlers:t.slice(s)}),a},fix:function(e){if(e[pe.expando])return e;var t,n,r,i=e.type,o=e,a=this.fixHooks[i];for(a||(this.fixHooks[i]=a=Ge.test(i)?this.mouseHooks:Je.test(i)?this.keyHooks:{}),r=a.props?this.props.concat(a.props):this.props,e=new pe.Event(o),t=r.length;t--;)n=r[t],e[n]=o[n];return e.target||(e.target=o.srcElement||re),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,a.filter?a.filter(e,o):e},props:\"altKey bubbles cancelable ctrlKey currentTarget detail eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),fixHooks:{},keyHooks:{props:\"char charCode key keyCode\".split(\" \"),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:\"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),filter:function(e,t){var n,r,i,o=t.button,a=t.fromElement;return null==e.pageX&&null!=t.clientX&&(r=e.target.ownerDocument||re,i=r.documentElement,n=r.body,e.pageX=t.clientX+(i&&i.scrollLeft||n&&n.scrollLeft||0)-(i&&i.clientLeft||n&&n.clientLeft||0),e.pageY=t.clientY+(i&&i.scrollTop||n&&n.scrollTop||0)-(i&&i.clientTop||n&&n.clientTop||0)),!e.relatedTarget&&a&&(e.relatedTarget=a===e.target?t.toElement:a),e.which||void 0===o||(e.which=1&o?1:2&o?3:4&o?2:0),e}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==b()&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:\"focusin\"},blur:{trigger:function(){if(this===b()&&this.blur)return this.blur(),!1},delegateType:\"focusout\"},click:{trigger:function(){if(pe.nodeName(this,\"input\")&&\"checkbox\"===this.type&&this.click)return this.click(),!1},_default:function(e){return pe.nodeName(e.target,\"a\")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n){var r=pe.extend(new pe.Event,n,{type:e,isSimulated:!0});pe.event.trigger(r,null,t),r.isDefaultPrevented()&&n.preventDefault()}},pe.removeEvent=re.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)}:function(e,t,n){var r=\"on\"+t;e.detachEvent&&(\"undefined\"==typeof e[r]&&(e[r]=null),e.detachEvent(r,n))},pe.Event=function(e,t){return this instanceof pe.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&e.returnValue===!1?v:x):this.type=e,t&&pe.extend(this,t),this.timeStamp=e&&e.timeStamp||pe.now(),void(this[pe.expando]=!0)):new pe.Event(e,t)},pe.Event.prototype={constructor:pe.Event,isDefaultPrevented:x,isPropagationStopped:x,isImmediatePropagationStopped:x,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=v,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=v,e&&!this.isSimulated&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=v,e&&e.stopImmediatePropagation&&e.stopImmediatePropagation(),this.stopPropagation()}},pe.each({mouseenter:\"mouseover\",mouseleave:\"mouseout\",pointerenter:\"pointerover\",pointerleave:\"pointerout\"},function(e,t){pe.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return i&&(i===r||pe.contains(r,i))||(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),fe.submit||(pe.event.special.submit={setup:function(){return!pe.nodeName(this,\"form\")&&void pe.event.add(this,\"click._submit keypress._submit\",function(e){var t=e.target,n=pe.nodeName(t,\"input\")||pe.nodeName(t,\"button\")?pe.prop(t,\"form\"):void 0;n&&!pe._data(n,\"submit\")&&(pe.event.add(n,\"submit._submit\",function(e){e._submitBubble=!0}),pe._data(n,\"submit\",!0))})},postDispatch:function(e){e._submitBubble&&(delete e._submitBubble,this.parentNode&&!e.isTrigger&&pe.event.simulate(\"submit\",this.parentNode,e))},teardown:function(){return!pe.nodeName(this,\"form\")&&void pe.event.remove(this,\"._submit\")}}),fe.change||(pe.event.special.change={setup:function(){return Ye.test(this.nodeName)?(\"checkbox\"!==this.type&&\"radio\"!==this.type||(pe.event.add(this,\"propertychange._change\",function(e){\"checked\"===e.originalEvent.propertyName&&(this._justChanged=!0)}),pe.event.add(this,\"click._change\",function(e){this._justChanged&&!e.isTrigger&&(this._justChanged=!1),pe.event.simulate(\"change\",this,e)})),!1):void pe.event.add(this,\"beforeactivate._change\",function(e){var t=e.target;Ye.test(t.nodeName)&&!pe._data(t,\"change\")&&(pe.event.add(t,\"change._change\",function(e){!this.parentNode||e.isSimulated||e.isTrigger||pe.event.simulate(\"change\",this.parentNode,e)}),pe._data(t,\"change\",!0))})},handle:function(e){var t=e.target;if(this!==t||e.isSimulated||e.isTrigger||\"radio\"!==t.type&&\"checkbox\"!==t.type)return e.handleObj.handler.apply(this,arguments)},teardown:function(){return pe.event.remove(this,\"._change\"),!Ye.test(this.nodeName)}}),fe.focusin||pe.each({focus:\"focusin\",blur:\"focusout\"},function(e,t){var n=function(e){pe.event.simulate(t,e.target,pe.event.fix(e))};pe.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=pe._data(r,t);i||r.addEventListener(e,n,!0),pe._data(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=pe._data(r,t)-1;i?pe._data(r,t,i):(r.removeEventListener(e,n,!0),pe._removeData(r,t))}}}),pe.fn.extend({on:function(e,t,n,r){return w(this,e,t,n,r)},one:function(e,t,n,r){return w(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,pe(e.delegateTarget).off(r.namespace?r.origType+\".\"+r.namespace:r.origType,r.selector,r.handler),this;if(\"object\"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return t!==!1&&\"function\"!=typeof t||(n=t,t=void 0),n===!1&&(n=x),this.each(function(){pe.event.remove(this,e,n,t)})},trigger:function(e,t){return this.each(function(){pe.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return pe.event.trigger(e,t,n,!0)}});var Ze=/ jQuery\\d+=\"(?:null|\\d+)\"/g,et=new RegExp(\"<(?:\"+ze+\")[\\\\s/>]\",\"i\"),tt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:-]+)[^>]*)\\/>/gi,nt=/<script|<style|<link/i,rt=/checked\\s*(?:[^=]|=\\s*.checked.)/i,it=/^true\\/(.*)/,ot=/^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g,at=p(re),st=at.appendChild(re.createElement(\"div\"));pe.extend({htmlPrefilter:function(e){return e.replace(tt,\"<$1></$2>\")},clone:function(e,t,n){var r,i,o,a,s,u=pe.contains(e.ownerDocument,e);if(fe.html5Clone||pe.isXMLDoc(e)||!et.test(\"<\"+e.nodeName+\">\")?o=e.cloneNode(!0):(st.innerHTML=e.outerHTML,st.removeChild(o=st.firstChild)),!(fe.noCloneEvent&&fe.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||pe.isXMLDoc(e)))for(r=h(o),s=h(e),a=0;null!=(i=s[a]);++a)r[a]&&k(i,r[a]);if(t)if(n)for(s=s||h(e),r=r||h(o),a=0;null!=(i=s[a]);a++)N(i,r[a]);else N(e,o);return r=h(o,\"script\"),r.length>0&&g(r,!u&&h(e,\"script\")),r=s=i=null,o},cleanData:function(e,t){for(var n,r,i,o,a=0,s=pe.expando,u=pe.cache,l=fe.attributes,c=pe.event.special;null!=(n=e[a]);a++)if((t||He(n))&&(i=n[s],o=i&&u[i])){if(o.events)for(r in o.events)c[r]?pe.event.remove(n,r):pe.removeEvent(n,r,o.handle);u[i]&&(delete u[i],l||\"undefined\"==typeof n.removeAttribute?n[s]=void 0:n.removeAttribute(s),ne.push(i))}}}),pe.fn.extend({domManip:S,detach:function(e){return A(this,e,!0)},remove:function(e){return A(this,e)},text:function(e){return Pe(this,function(e){return void 0===e?pe.text(this):this.empty().append((this[0]&&this[0].ownerDocument||re).createTextNode(e))},null,e,arguments.length)},append:function(){return S(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=T(this,e);t.appendChild(e)}})},prepend:function(){return S(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=T(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return S(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return S(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++){for(1===e.nodeType&&pe.cleanData(h(e,!1));e.firstChild;)e.removeChild(e.firstChild);e.options&&pe.nodeName(e,\"select\")&&(e.options.length=0)}return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return pe.clone(this,e,t)})},html:function(e){return Pe(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e)return 1===t.nodeType?t.innerHTML.replace(Ze,\"\"):void 0;if(\"string\"==typeof e&&!nt.test(e)&&(fe.htmlSerialize||!et.test(e))&&(fe.leadingWhitespace||!$e.test(e))&&!Xe[(We.exec(e)||[\"\",\"\"])[1].toLowerCase()]){e=pe.htmlPrefilter(e);try{for(;n<r;n++)t=this[n]||{},1===t.nodeType&&(pe.cleanData(h(t,!1)),t.innerHTML=e);t=0}catch(i){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=[];return S(this,arguments,function(t){var n=this.parentNode;pe.inArray(this,e)<0&&(pe.cleanData(h(this)),\nn&&n.replaceChild(t,this))},e)}}),pe.each({appendTo:\"append\",prependTo:\"prepend\",insertBefore:\"before\",insertAfter:\"after\",replaceAll:\"replaceWith\"},function(e,t){pe.fn[e]=function(e){for(var n,r=0,i=[],o=pe(e),a=o.length-1;r<=a;r++)n=r===a?this:this.clone(!0),pe(o[r])[t](n),ae.apply(i,n.get());return this.pushStack(i)}});var ut,lt={HTML:\"block\",BODY:\"block\"},ct=/^margin/,ft=new RegExp(\"^(\"+Fe+\")(?!px)[a-z%]+$\",\"i\"),dt=function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i},pt=re.documentElement;!function(){function t(){var t,c,f=re.documentElement;f.appendChild(u),l.style.cssText=\"-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%\",n=i=s=!1,r=a=!0,e.getComputedStyle&&(c=e.getComputedStyle(l),n=\"1%\"!==(c||{}).top,s=\"2px\"===(c||{}).marginLeft,i=\"4px\"===(c||{width:\"4px\"}).width,l.style.marginRight=\"50%\",r=\"4px\"===(c||{marginRight:\"4px\"}).marginRight,t=l.appendChild(re.createElement(\"div\")),t.style.cssText=l.style.cssText=\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0\",t.style.marginRight=t.style.width=\"0\",l.style.width=\"1px\",a=!parseFloat((e.getComputedStyle(t)||{}).marginRight),l.removeChild(t)),l.style.display=\"none\",o=0===l.getClientRects().length,o&&(l.style.display=\"\",l.innerHTML=\"<table><tr><td></td><td>t</td></tr></table>\",t=l.getElementsByTagName(\"td\"),t[0].style.cssText=\"margin:0;border:0;padding:0;display:none\",o=0===t[0].offsetHeight,o&&(t[0].style.display=\"\",t[1].style.display=\"none\",o=0===t[0].offsetHeight)),f.removeChild(u)}var n,r,i,o,a,s,u=re.createElement(\"div\"),l=re.createElement(\"div\");l.style&&(l.style.cssText=\"float:left;opacity:.5\",fe.opacity=\"0.5\"===l.style.opacity,fe.cssFloat=!!l.style.cssFloat,l.style.backgroundClip=\"content-box\",l.cloneNode(!0).style.backgroundClip=\"\",fe.clearCloneStyle=\"content-box\"===l.style.backgroundClip,u=re.createElement(\"div\"),u.style.cssText=\"border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute\",l.innerHTML=\"\",u.appendChild(l),fe.boxSizing=\"\"===l.style.boxSizing||\"\"===l.style.MozBoxSizing||\"\"===l.style.WebkitBoxSizing,pe.extend(fe,{reliableHiddenOffsets:function(){return null==n&&t(),o},boxSizingReliable:function(){return null==n&&t(),i},pixelMarginRight:function(){return null==n&&t(),r},pixelPosition:function(){return null==n&&t(),n},reliableMarginRight:function(){return null==n&&t(),a},reliableMarginLeft:function(){return null==n&&t(),s}}))}();var ht,gt,mt=/^(top|right|bottom|left)$/;e.getComputedStyle?(ht=function(t){var n=t.ownerDocument.defaultView;return n&&n.opener||(n=e),n.getComputedStyle(t)},gt=function(e,t,n){var r,i,o,a,s=e.style;return n=n||ht(e),a=n?n.getPropertyValue(t)||n[t]:void 0,\"\"!==a&&void 0!==a||pe.contains(e.ownerDocument,e)||(a=pe.style(e,t)),n&&!fe.pixelMarginRight()&&ft.test(a)&&ct.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o),void 0===a?a:a+\"\"}):pt.currentStyle&&(ht=function(e){return e.currentStyle},gt=function(e,t,n){var r,i,o,a,s=e.style;return n=n||ht(e),a=n?n[t]:void 0,null==a&&s&&s[t]&&(a=s[t]),ft.test(a)&&!mt.test(t)&&(r=s.left,i=e.runtimeStyle,o=i&&i.left,o&&(i.left=e.currentStyle.left),s.left=\"fontSize\"===t?\"1em\":a,a=s.pixelLeft+\"px\",s.left=r,o&&(i.left=o)),void 0===a?a:a+\"\"||\"auto\"});var yt=/alpha\\([^)]*\\)/i,vt=/opacity\\s*=\\s*([^)]*)/i,xt=/^(none|table(?!-c[ea]).+)/,bt=new RegExp(\"^(\"+Fe+\")(.*)$\",\"i\"),wt={position:\"absolute\",visibility:\"hidden\",display:\"block\"},Tt={letterSpacing:\"0\",fontWeight:\"400\"},Ct=[\"Webkit\",\"O\",\"Moz\",\"ms\"],Et=re.createElement(\"div\").style;pe.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=gt(e,\"opacity\");return\"\"===n?\"1\":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{\"float\":fe.cssFloat?\"cssFloat\":\"styleFloat\"},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=pe.camelCase(t),u=e.style;if(t=pe.cssProps[s]||(pe.cssProps[s]=H(s)||s),a=pe.cssHooks[t]||pe.cssHooks[s],void 0===n)return a&&\"get\"in a&&void 0!==(i=a.get(e,!1,r))?i:u[t];if(o=typeof n,\"string\"===o&&(i=Me.exec(n))&&i[1]&&(n=d(e,t,i),o=\"number\"),null!=n&&n===n&&(\"number\"===o&&(n+=i&&i[3]||(pe.cssNumber[s]?\"\":\"px\")),fe.clearCloneStyle||\"\"!==n||0!==t.indexOf(\"background\")||(u[t]=\"inherit\"),!(a&&\"set\"in a&&void 0===(n=a.set(e,n,r)))))try{u[t]=n}catch(l){}}},css:function(e,t,n,r){var i,o,a,s=pe.camelCase(t);return t=pe.cssProps[s]||(pe.cssProps[s]=H(s)||s),a=pe.cssHooks[t]||pe.cssHooks[s],a&&\"get\"in a&&(o=a.get(e,!0,n)),void 0===o&&(o=gt(e,t,r)),\"normal\"===o&&t in Tt&&(o=Tt[t]),\"\"===n||n?(i=parseFloat(o),n===!0||isFinite(i)?i||0:o):o}}),pe.each([\"height\",\"width\"],function(e,t){pe.cssHooks[t]={get:function(e,n,r){if(n)return xt.test(pe.css(e,\"display\"))&&0===e.offsetWidth?dt(e,wt,function(){return M(e,t,r)}):M(e,t,r)},set:function(e,n,r){var i=r&&ht(e);return _(e,n,r?F(e,t,r,fe.boxSizing&&\"border-box\"===pe.css(e,\"boxSizing\",!1,i),i):0)}}}),fe.opacity||(pe.cssHooks.opacity={get:function(e,t){return vt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||\"\")?.01*parseFloat(RegExp.$1)+\"\":t?\"1\":\"\"},set:function(e,t){var n=e.style,r=e.currentStyle,i=pe.isNumeric(t)?\"alpha(opacity=\"+100*t+\")\":\"\",o=r&&r.filter||n.filter||\"\";n.zoom=1,(t>=1||\"\"===t)&&\"\"===pe.trim(o.replace(yt,\"\"))&&n.removeAttribute&&(n.removeAttribute(\"filter\"),\"\"===t||r&&!r.filter)||(n.filter=yt.test(o)?o.replace(yt,i):o+\" \"+i)}}),pe.cssHooks.marginRight=L(fe.reliableMarginRight,function(e,t){if(t)return dt(e,{display:\"inline-block\"},gt,[e,\"marginRight\"])}),pe.cssHooks.marginLeft=L(fe.reliableMarginLeft,function(e,t){if(t)return(parseFloat(gt(e,\"marginLeft\"))||(pe.contains(e.ownerDocument,e)?e.getBoundingClientRect().left-dt(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}):0))+\"px\"}),pe.each({margin:\"\",padding:\"\",border:\"Width\"},function(e,t){pe.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o=\"string\"==typeof n?n.split(\" \"):[n];r<4;r++)i[e+Oe[r]+t]=o[r]||o[r-2]||o[0];return i}},ct.test(e)||(pe.cssHooks[e+t].set=_)}),pe.fn.extend({css:function(e,t){return Pe(this,function(e,t,n){var r,i,o={},a=0;if(pe.isArray(t)){for(r=ht(e),i=t.length;a<i;a++)o[t[a]]=pe.css(e,t[a],!1,r);return o}return void 0!==n?pe.style(e,t,n):pe.css(e,t)},e,t,arguments.length>1)},show:function(){return q(this,!0)},hide:function(){return q(this)},toggle:function(e){return\"boolean\"==typeof e?e?this.show():this.hide():this.each(function(){Re(this)?pe(this).show():pe(this).hide()})}}),pe.Tween=O,O.prototype={constructor:O,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||pe.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(pe.cssNumber[n]?\"\":\"px\")},cur:function(){var e=O.propHooks[this.prop];return e&&e.get?e.get(this):O.propHooks._default.get(this)},run:function(e){var t,n=O.propHooks[this.prop];return this.options.duration?this.pos=t=pe.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):O.propHooks._default.set(this),this}},O.prototype.init.prototype=O.prototype,O.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=pe.css(e.elem,e.prop,\"\"),t&&\"auto\"!==t?t:0)},set:function(e){pe.fx.step[e.prop]?pe.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[pe.cssProps[e.prop]]&&!pe.cssHooks[e.prop]?e.elem[e.prop]=e.now:pe.style(e.elem,e.prop,e.now+e.unit)}}},O.propHooks.scrollTop=O.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},pe.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:\"swing\"},pe.fx=O.prototype.init,pe.fx.step={};var Nt,kt,St=/^(?:toggle|show|hide)$/,At=/queueHooks$/;pe.Animation=pe.extend($,{tweeners:{\"*\":[function(e,t){var n=this.createTween(e,t);return d(n.elem,e,Me.exec(t),n),n}]},tweener:function(e,t){pe.isFunction(e)?(t=e,e=[\"*\"]):e=e.match(De);for(var n,r=0,i=e.length;r<i;r++)n=e[r],$.tweeners[n]=$.tweeners[n]||[],$.tweeners[n].unshift(t)},prefilters:[W],prefilter:function(e,t){t?$.prefilters.unshift(e):$.prefilters.push(e)}}),pe.speed=function(e,t,n){var r=e&&\"object\"==typeof e?pe.extend({},e):{complete:n||!n&&t||pe.isFunction(e)&&e,duration:e,easing:n&&t||t&&!pe.isFunction(t)&&t};return r.duration=pe.fx.off?0:\"number\"==typeof r.duration?r.duration:r.duration in pe.fx.speeds?pe.fx.speeds[r.duration]:pe.fx.speeds._default,null!=r.queue&&r.queue!==!0||(r.queue=\"fx\"),r.old=r.complete,r.complete=function(){pe.isFunction(r.old)&&r.old.call(this),r.queue&&pe.dequeue(this,r.queue)},r},pe.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Re).css(\"opacity\",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=pe.isEmptyObject(e),o=pe.speed(t,n,r),a=function(){var t=$(this,pe.extend({},e),o);(i||pe._data(this,\"finish\"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return\"string\"!=typeof e&&(n=t,t=e,e=void 0),t&&e!==!1&&this.queue(e||\"fx\",[]),this.each(function(){var t=!0,i=null!=e&&e+\"queueHooks\",o=pe.timers,a=pe._data(this);if(i)a[i]&&a[i].stop&&r(a[i]);else for(i in a)a[i]&&a[i].stop&&At.test(i)&&r(a[i]);for(i=o.length;i--;)o[i].elem!==this||null!=e&&o[i].queue!==e||(o[i].anim.stop(n),t=!1,o.splice(i,1));!t&&n||pe.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||\"fx\"),this.each(function(){var t,n=pe._data(this),r=n[e+\"queue\"],i=n[e+\"queueHooks\"],o=pe.timers,a=r?r.length:0;for(n.finish=!0,pe.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;t<a;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}}),pe.each([\"toggle\",\"show\",\"hide\"],function(e,t){var n=pe.fn[t];pe.fn[t]=function(e,r,i){return null==e||\"boolean\"==typeof e?n.apply(this,arguments):this.animate(P(t,!0),e,r,i)}}),pe.each({slideDown:P(\"show\"),slideUp:P(\"hide\"),slideToggle:P(\"toggle\"),fadeIn:{opacity:\"show\"},fadeOut:{opacity:\"hide\"},fadeToggle:{opacity:\"toggle\"}},function(e,t){pe.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),pe.timers=[],pe.fx.tick=function(){var e,t=pe.timers,n=0;for(Nt=pe.now();n<t.length;n++)e=t[n],e()||t[n]!==e||t.splice(n--,1);t.length||pe.fx.stop(),Nt=void 0},pe.fx.timer=function(e){pe.timers.push(e),e()?pe.fx.start():pe.timers.pop()},pe.fx.interval=13,pe.fx.start=function(){kt||(kt=e.setInterval(pe.fx.tick,pe.fx.interval))},pe.fx.stop=function(){e.clearInterval(kt),kt=null},pe.fx.speeds={slow:600,fast:200,_default:400},pe.fn.delay=function(t,n){return t=pe.fx?pe.fx.speeds[t]||t:t,n=n||\"fx\",this.queue(n,function(n,r){var i=e.setTimeout(n,t);r.stop=function(){e.clearTimeout(i)}})},function(){var e,t=re.createElement(\"input\"),n=re.createElement(\"div\"),r=re.createElement(\"select\"),i=r.appendChild(re.createElement(\"option\"));n=re.createElement(\"div\"),n.setAttribute(\"className\",\"t\"),n.innerHTML=\"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\",e=n.getElementsByTagName(\"a\")[0],t.setAttribute(\"type\",\"checkbox\"),n.appendChild(t),e=n.getElementsByTagName(\"a\")[0],e.style.cssText=\"top:1px\",fe.getSetAttribute=\"t\"!==n.className,fe.style=/top/.test(e.getAttribute(\"style\")),fe.hrefNormalized=\"/a\"===e.getAttribute(\"href\"),fe.checkOn=!!t.value,fe.optSelected=i.selected,fe.enctype=!!re.createElement(\"form\").enctype,r.disabled=!0,fe.optDisabled=!i.disabled,t=re.createElement(\"input\"),t.setAttribute(\"value\",\"\"),fe.input=\"\"===t.getAttribute(\"value\"),t.value=\"t\",t.setAttribute(\"type\",\"radio\"),fe.radioValue=\"t\"===t.value}();var Dt=/\\r/g,jt=/[\\x20\\t\\r\\n\\f]+/g;pe.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=pe.isFunction(e),this.each(function(n){var i;1===this.nodeType&&(i=r?e.call(this,n,pe(this).val()):e,null==i?i=\"\":\"number\"==typeof i?i+=\"\":pe.isArray(i)&&(i=pe.map(i,function(e){return null==e?\"\":e+\"\"})),t=pe.valHooks[this.type]||pe.valHooks[this.nodeName.toLowerCase()],t&&\"set\"in t&&void 0!==t.set(this,i,\"value\")||(this.value=i))});if(i)return t=pe.valHooks[i.type]||pe.valHooks[i.nodeName.toLowerCase()],t&&\"get\"in t&&void 0!==(n=t.get(i,\"value\"))?n:(n=i.value,\"string\"==typeof n?n.replace(Dt,\"\"):null==n?\"\":n)}}}),pe.extend({valHooks:{option:{get:function(e){var t=pe.find.attr(e,\"value\");return null!=t?t:pe.trim(pe.text(e)).replace(jt,\" \")}},select:{get:function(e){for(var t,n,r=e.options,i=e.selectedIndex,o=\"select-one\"===e.type||i<0,a=o?null:[],s=o?i+1:r.length,u=i<0?s:o?i:0;u<s;u++)if(n=r[u],(n.selected||u===i)&&(fe.optDisabled?!n.disabled:null===n.getAttribute(\"disabled\"))&&(!n.parentNode.disabled||!pe.nodeName(n.parentNode,\"optgroup\"))){if(t=pe(n).val(),o)return t;a.push(t)}return a},set:function(e,t){for(var n,r,i=e.options,o=pe.makeArray(t),a=i.length;a--;)if(r=i[a],pe.inArray(pe.valHooks.option.get(r),o)>-1)try{r.selected=n=!0}catch(s){r.scrollHeight}else r.selected=!1;return n||(e.selectedIndex=-1),i}}}}),pe.each([\"radio\",\"checkbox\"],function(){pe.valHooks[this]={set:function(e,t){if(pe.isArray(t))return e.checked=pe.inArray(pe(e).val(),t)>-1}},fe.checkOn||(pe.valHooks[this].get=function(e){return null===e.getAttribute(\"value\")?\"on\":e.value})});var Lt,Ht,qt=pe.expr.attrHandle,_t=/^(?:checked|selected)$/i,Ft=fe.getSetAttribute,Mt=fe.input;pe.fn.extend({attr:function(e,t){return Pe(this,pe.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){pe.removeAttr(this,e)})}}),pe.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return\"undefined\"==typeof e.getAttribute?pe.prop(e,t,n):(1===o&&pe.isXMLDoc(e)||(t=t.toLowerCase(),i=pe.attrHooks[t]||(pe.expr.match.bool.test(t)?Ht:Lt)),void 0!==n?null===n?void pe.removeAttr(e,t):i&&\"set\"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+\"\"),n):i&&\"get\"in i&&null!==(r=i.get(e,t))?r:(r=pe.find.attr(e,t),null==r?void 0:r))},attrHooks:{type:{set:function(e,t){if(!fe.radioValue&&\"radio\"===t&&pe.nodeName(e,\"input\")){var n=e.value;return e.setAttribute(\"type\",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(De);if(o&&1===e.nodeType)for(;n=o[i++];)r=pe.propFix[n]||n,pe.expr.match.bool.test(n)?Mt&&Ft||!_t.test(n)?e[r]=!1:e[pe.camelCase(\"default-\"+n)]=e[r]=!1:pe.attr(e,n,\"\"),e.removeAttribute(Ft?n:r)}}),Ht={set:function(e,t,n){return t===!1?pe.removeAttr(e,n):Mt&&Ft||!_t.test(n)?e.setAttribute(!Ft&&pe.propFix[n]||n,n):e[pe.camelCase(\"default-\"+n)]=e[n]=!0,n}},pe.each(pe.expr.match.bool.source.match(/\\w+/g),function(e,t){var n=qt[t]||pe.find.attr;Mt&&Ft||!_t.test(t)?qt[t]=function(e,t,r){var i,o;return r||(o=qt[t],qt[t]=i,i=null!=n(e,t,r)?t.toLowerCase():null,qt[t]=o),i}:qt[t]=function(e,t,n){if(!n)return e[pe.camelCase(\"default-\"+t)]?t.toLowerCase():null}}),Mt&&Ft||(pe.attrHooks.value={set:function(e,t,n){return pe.nodeName(e,\"input\")?void(e.defaultValue=t):Lt&&Lt.set(e,t,n)}}),Ft||(Lt={set:function(e,t,n){var r=e.getAttributeNode(n);if(r||e.setAttributeNode(r=e.ownerDocument.createAttribute(n)),r.value=t+=\"\",\"value\"===n||t===e.getAttribute(n))return t}},qt.id=qt.name=qt.coords=function(e,t,n){var r;if(!n)return(r=e.getAttributeNode(t))&&\"\"!==r.value?r.value:null},pe.valHooks.button={get:function(e,t){var n=e.getAttributeNode(t);if(n&&n.specified)return n.value},set:Lt.set},pe.attrHooks.contenteditable={set:function(e,t,n){Lt.set(e,\"\"!==t&&t,n)}},pe.each([\"width\",\"height\"],function(e,t){pe.attrHooks[t]={set:function(e,n){if(\"\"===n)return e.setAttribute(t,\"auto\"),n}}})),fe.style||(pe.attrHooks.style={get:function(e){return e.style.cssText||void 0},set:function(e,t){return e.style.cssText=t+\"\"}});var Ot=/^(?:input|select|textarea|button|object)$/i,Rt=/^(?:a|area)$/i;pe.fn.extend({prop:function(e,t){return Pe(this,pe.prop,e,t,arguments.length>1)},removeProp:function(e){return e=pe.propFix[e]||e,this.each(function(){try{this[e]=void 0,delete this[e]}catch(t){}})}}),pe.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&pe.isXMLDoc(e)||(t=pe.propFix[t]||t,i=pe.propHooks[t]),void 0!==n?i&&\"set\"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&\"get\"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=pe.find.attr(e,\"tabindex\");return t?parseInt(t,10):Ot.test(e.nodeName)||Rt.test(e.nodeName)&&e.href?0:-1}}},propFix:{\"for\":\"htmlFor\",\"class\":\"className\"}}),fe.hrefNormalized||pe.each([\"href\",\"src\"],function(e,t){pe.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}}),fe.optSelected||(pe.propHooks.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),pe.each([\"tabIndex\",\"readOnly\",\"maxLength\",\"cellSpacing\",\"cellPadding\",\"rowSpan\",\"colSpan\",\"useMap\",\"frameBorder\",\"contentEditable\"],function(){pe.propFix[this.toLowerCase()]=this}),fe.enctype||(pe.propFix.enctype=\"encoding\");var Pt=/[\\t\\r\\n\\f]/g;pe.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(pe.isFunction(e))return this.each(function(t){pe(this).addClass(e.call(this,t,z(this)))});if(\"string\"==typeof e&&e)for(t=e.match(De)||[];n=this[u++];)if(i=z(n),r=1===n.nodeType&&(\" \"+i+\" \").replace(Pt,\" \")){for(a=0;o=t[a++];)r.indexOf(\" \"+o+\" \")<0&&(r+=o+\" \");s=pe.trim(r),i!==s&&pe.attr(n,\"class\",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(pe.isFunction(e))return this.each(function(t){pe(this).removeClass(e.call(this,t,z(this)))});if(!arguments.length)return this.attr(\"class\",\"\");if(\"string\"==typeof e&&e)for(t=e.match(De)||[];n=this[u++];)if(i=z(n),r=1===n.nodeType&&(\" \"+i+\" \").replace(Pt,\" \")){for(a=0;o=t[a++];)for(;r.indexOf(\" \"+o+\" \")>-1;)r=r.replace(\" \"+o+\" \",\" \");s=pe.trim(r),i!==s&&pe.attr(n,\"class\",s)}return this},toggleClass:function(e,t){var n=typeof e;return\"boolean\"==typeof t&&\"string\"===n?t?this.addClass(e):this.removeClass(e):pe.isFunction(e)?this.each(function(n){pe(this).toggleClass(e.call(this,n,z(this),t),t)}):this.each(function(){var t,r,i,o;if(\"string\"===n)for(r=0,i=pe(this),o=e.match(De)||[];t=o[r++];)i.hasClass(t)?i.removeClass(t):i.addClass(t);else void 0!==e&&\"boolean\"!==n||(t=z(this),t&&pe._data(this,\"__className__\",t),pe.attr(this,\"class\",t||e===!1?\"\":pe._data(this,\"__className__\")||\"\"))})},hasClass:function(e){var t,n,r=0;for(t=\" \"+e+\" \";n=this[r++];)if(1===n.nodeType&&(\" \"+z(n)+\" \").replace(Pt,\" \").indexOf(t)>-1)return!0;return!1}}),pe.each(\"blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu\".split(\" \"),function(e,t){pe.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),pe.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}});var Bt=e.location,Wt=pe.now(),It=/\\?/,$t=/(,)|(\\[|{)|(}|])|\"(?:[^\"\\\\\\r\\n]|\\\\[\"\\\\\\/bfnrt]|\\\\u[\\da-fA-F]{4})*\"\\s*:?|true|false|null|-?(?!0\\d)\\d+(?:\\.\\d+|)(?:[eE][+-]?\\d+|)/g;pe.parseJSON=function(t){if(e.JSON&&e.JSON.parse)return e.JSON.parse(t+\"\");var n,r=null,i=pe.trim(t+\"\");return i&&!pe.trim(i.replace($t,function(e,t,i,o){return n&&t&&(r=0),0===r?e:(n=i||t,r+=!o-!i,\"\")}))?Function(\"return \"+i)():pe.error(\"Invalid JSON: \"+t)},pe.parseXML=function(t){var n,r;if(!t||\"string\"!=typeof t)return null;try{e.DOMParser?(r=new e.DOMParser,n=r.parseFromString(t,\"text/xml\")):(n=new e.ActiveXObject(\"Microsoft.XMLDOM\"),n.async=\"false\",n.loadXML(t))}catch(i){n=void 0}return n&&n.documentElement&&!n.getElementsByTagName(\"parsererror\").length||pe.error(\"Invalid XML: \"+t),n};var zt=/#.*$/,Xt=/([?&])_=[^&]*/,Ut=/^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/gm,Vt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Yt=/^(?:GET|HEAD)$/,Jt=/^\\/\\//,Gt=/^([\\w.+-]+:)(?:\\/\\/(?:[^\\/?#]*@|)([^\\/?#:]*)(?::(\\d+)|)|)/,Kt={},Qt={},Zt=\"*/\".concat(\"*\"),en=Bt.href,tn=Gt.exec(en.toLowerCase())||[];pe.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:en,type:\"GET\",isLocal:Vt.test(tn[1]),global:!0,processData:!0,async:!0,contentType:\"application/x-www-form-urlencoded; charset=UTF-8\",accepts:{\"*\":Zt,text:\"text/plain\",html:\"text/html\",xml:\"application/xml, text/xml\",json:\"application/json, text/javascript\"},contents:{xml:/\\bxml\\b/,html:/\\bhtml/,json:/\\bjson\\b/},responseFields:{xml:\"responseXML\",text:\"responseText\",json:\"responseJSON\"},converters:{\"* text\":String,\"text html\":!0,\"text json\":pe.parseJSON,\"text xml\":pe.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?V(V(e,pe.ajaxSettings),t):V(pe.ajaxSettings,e)},ajaxPrefilter:X(Kt),ajaxTransport:X(Qt),ajax:function(t,n){function r(t,n,r,i){var o,f,v,x,w,C=n;2!==b&&(b=2,u&&e.clearTimeout(u),c=void 0,s=i||\"\",T.readyState=t>0?4:0,o=t>=200&&t<300||304===t,r&&(x=Y(d,T,r)),x=J(d,x,T,o),o?(d.ifModified&&(w=T.getResponseHeader(\"Last-Modified\"),w&&(pe.lastModified[a]=w),w=T.getResponseHeader(\"etag\"),w&&(pe.etag[a]=w)),204===t||\"HEAD\"===d.type?C=\"nocontent\":304===t?C=\"notmodified\":(C=x.state,f=x.data,v=x.error,o=!v)):(v=C,!t&&C||(C=\"error\",t<0&&(t=0))),T.status=t,T.statusText=(n||C)+\"\",o?g.resolveWith(p,[f,C,T]):g.rejectWith(p,[T,C,v]),T.statusCode(y),y=void 0,l&&h.trigger(o?\"ajaxSuccess\":\"ajaxError\",[T,d,o?f:v]),m.fireWith(p,[T,C]),l&&(h.trigger(\"ajaxComplete\",[T,d]),--pe.active||pe.event.trigger(\"ajaxStop\")))}\"object\"==typeof t&&(n=t,t=void 0),n=n||{};var i,o,a,s,u,l,c,f,d=pe.ajaxSetup({},n),p=d.context||d,h=d.context&&(p.nodeType||p.jquery)?pe(p):pe.event,g=pe.Deferred(),m=pe.Callbacks(\"once memory\"),y=d.statusCode||{},v={},x={},b=0,w=\"canceled\",T={readyState:0,getResponseHeader:function(e){var t;if(2===b){if(!f)for(f={};t=Ut.exec(s);)f[t[1].toLowerCase()]=t[2];t=f[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===b?s:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return b||(e=x[n]=x[n]||e,v[e]=t),this},overrideMimeType:function(e){return b||(d.mimeType=e),this},statusCode:function(e){var t;if(e)if(b<2)for(t in e)y[t]=[y[t],e[t]];else T.always(e[T.status]);return this},abort:function(e){var t=e||w;return c&&c.abort(t),r(0,t),this}};if(g.promise(T).complete=m.add,T.success=T.done,T.error=T.fail,d.url=((t||d.url||en)+\"\").replace(zt,\"\").replace(Jt,tn[1]+\"//\"),d.type=n.method||n.type||d.method||d.type,d.dataTypes=pe.trim(d.dataType||\"*\").toLowerCase().match(De)||[\"\"],null==d.crossDomain&&(i=Gt.exec(d.url.toLowerCase()),d.crossDomain=!(!i||i[1]===tn[1]&&i[2]===tn[2]&&(i[3]||(\"http:\"===i[1]?\"80\":\"443\"))===(tn[3]||(\"http:\"===tn[1]?\"80\":\"443\")))),d.data&&d.processData&&\"string\"!=typeof d.data&&(d.data=pe.param(d.data,d.traditional)),U(Kt,d,n,T),2===b)return T;l=pe.event&&d.global,l&&0===pe.active++&&pe.event.trigger(\"ajaxStart\"),d.type=d.type.toUpperCase(),d.hasContent=!Yt.test(d.type),a=d.url,d.hasContent||(d.data&&(a=d.url+=(It.test(a)?\"&\":\"?\")+d.data,delete d.data),d.cache===!1&&(d.url=Xt.test(a)?a.replace(Xt,\"$1_=\"+Wt++):a+(It.test(a)?\"&\":\"?\")+\"_=\"+Wt++)),d.ifModified&&(pe.lastModified[a]&&T.setRequestHeader(\"If-Modified-Since\",pe.lastModified[a]),pe.etag[a]&&T.setRequestHeader(\"If-None-Match\",pe.etag[a])),(d.data&&d.hasContent&&d.contentType!==!1||n.contentType)&&T.setRequestHeader(\"Content-Type\",d.contentType),T.setRequestHeader(\"Accept\",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(\"*\"!==d.dataTypes[0]?\", \"+Zt+\"; q=0.01\":\"\"):d.accepts[\"*\"]);for(o in d.headers)T.setRequestHeader(o,d.headers[o]);if(d.beforeSend&&(d.beforeSend.call(p,T,d)===!1||2===b))return T.abort();w=\"abort\";for(o in{success:1,error:1,complete:1})T[o](d[o]);if(c=U(Qt,d,n,T)){if(T.readyState=1,l&&h.trigger(\"ajaxSend\",[T,d]),2===b)return T;d.async&&d.timeout>0&&(u=e.setTimeout(function(){T.abort(\"timeout\")},d.timeout));try{b=1,c.send(v,r)}catch(C){if(!(b<2))throw C;r(-1,C)}}else r(-1,\"No Transport\");return T},getJSON:function(e,t,n){return pe.get(e,t,n,\"json\")},getScript:function(e,t){return pe.get(e,void 0,t,\"script\")}}),pe.each([\"get\",\"post\"],function(e,t){pe[t]=function(e,n,r,i){return pe.isFunction(n)&&(i=i||r,r=n,n=void 0),pe.ajax(pe.extend({url:e,type:t,dataType:i,data:n,success:r},pe.isPlainObject(e)&&e))}}),pe._evalUrl=function(e){return pe.ajax({url:e,type:\"GET\",dataType:\"script\",cache:!0,async:!1,global:!1,\"throws\":!0})},pe.fn.extend({wrapAll:function(e){if(pe.isFunction(e))return this.each(function(t){pe(this).wrapAll(e.call(this,t))});if(this[0]){var t=pe(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstChild&&1===e.firstChild.nodeType;)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return pe.isFunction(e)?this.each(function(t){pe(this).wrapInner(e.call(this,t))}):this.each(function(){var t=pe(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=pe.isFunction(e);return this.each(function(n){pe(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){pe.nodeName(this,\"body\")||pe(this).replaceWith(this.childNodes)}).end()}}),pe.expr.filters.hidden=function(e){return fe.reliableHiddenOffsets()?e.offsetWidth<=0&&e.offsetHeight<=0&&!e.getClientRects().length:K(e)},pe.expr.filters.visible=function(e){return!pe.expr.filters.hidden(e)};var nn=/%20/g,rn=/\\[\\]$/,on=/\\r?\\n/g,an=/^(?:submit|button|image|reset|file)$/i,sn=/^(?:input|select|textarea|keygen)/i;pe.param=function(e,t){var n,r=[],i=function(e,t){t=pe.isFunction(t)?t():null==t?\"\":t,r[r.length]=encodeURIComponent(e)+\"=\"+encodeURIComponent(t)};if(void 0===t&&(t=pe.ajaxSettings&&pe.ajaxSettings.traditional),pe.isArray(e)||e.jquery&&!pe.isPlainObject(e))pe.each(e,function(){i(this.name,this.value)});else for(n in e)Q(n,e[n],t,i);return r.join(\"&\").replace(nn,\"+\")},pe.fn.extend({serialize:function(){return pe.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=pe.prop(this,\"elements\");return e?pe.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!pe(this).is(\":disabled\")&&sn.test(this.nodeName)&&!an.test(e)&&(this.checked||!Be.test(e))}).map(function(e,t){var n=pe(this).val();return null==n?null:pe.isArray(n)?pe.map(n,function(e){return{name:t.name,value:e.replace(on,\"\\r\\n\")}}):{name:t.name,value:n.replace(on,\"\\r\\n\")}}).get()}}),pe.ajaxSettings.xhr=void 0!==e.ActiveXObject?function(){return this.isLocal?ee():re.documentMode>8?Z():/^(get|post|head|put|delete|options)$/i.test(this.type)&&Z()||ee()}:Z;var un=0,ln={},cn=pe.ajaxSettings.xhr();e.attachEvent&&e.attachEvent(\"onunload\",function(){for(var e in ln)ln[e](void 0,!0)}),fe.cors=!!cn&&\"withCredentials\"in cn,cn=fe.ajax=!!cn,cn&&pe.ajaxTransport(function(t){if(!t.crossDomain||fe.cors){var n;return{send:function(r,i){var o,a=t.xhr(),s=++un;if(a.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(o in t.xhrFields)a[o]=t.xhrFields[o];t.mimeType&&a.overrideMimeType&&a.overrideMimeType(t.mimeType),t.crossDomain||r[\"X-Requested-With\"]||(r[\"X-Requested-With\"]=\"XMLHttpRequest\");for(o in r)void 0!==r[o]&&a.setRequestHeader(o,r[o]+\"\");a.send(t.hasContent&&t.data||null),n=function(e,r){var o,u,l;if(n&&(r||4===a.readyState))if(delete ln[s],n=void 0,a.onreadystatechange=pe.noop,r)4!==a.readyState&&a.abort();else{l={},o=a.status,\"string\"==typeof a.responseText&&(l.text=a.responseText);try{u=a.statusText}catch(c){u=\"\"}o||!t.isLocal||t.crossDomain?1223===o&&(o=204):o=l.text?200:404}l&&i(o,u,l,a.getAllResponseHeaders())},t.async?4===a.readyState?e.setTimeout(n):a.onreadystatechange=ln[s]=n:n()},abort:function(){n&&n(void 0,!0)}}}}),pe.ajaxSetup({accepts:{script:\"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"},contents:{script:/\\b(?:java|ecma)script\\b/},converters:{\"text script\":function(e){return pe.globalEval(e),e}}}),pe.ajaxPrefilter(\"script\",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type=\"GET\",e.global=!1)}),pe.ajaxTransport(\"script\",function(e){if(e.crossDomain){var t,n=re.head||pe(\"head\")[0]||re.documentElement;return{send:function(r,i){t=re.createElement(\"script\"),t.async=!0,e.scriptCharset&&(t.charset=e.scriptCharset),t.src=e.url,t.onload=t.onreadystatechange=function(e,n){(n||!t.readyState||/loaded|complete/.test(t.readyState))&&(t.onload=t.onreadystatechange=null,t.parentNode&&t.parentNode.removeChild(t),t=null,n||i(200,\"success\"))},n.insertBefore(t,n.firstChild)},abort:function(){t&&t.onload(void 0,!0)}}}});var fn=[],dn=/(=)\\?(?=&|$)|\\?\\?/;pe.ajaxSetup({jsonp:\"callback\",jsonpCallback:function(){var e=fn.pop()||pe.expando+\"_\"+Wt++;return this[e]=!0,e}}),pe.ajaxPrefilter(\"json jsonp\",function(t,n,r){var i,o,a,s=t.jsonp!==!1&&(dn.test(t.url)?\"url\":\"string\"==typeof t.data&&0===(t.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&dn.test(t.data)&&\"data\");if(s||\"jsonp\"===t.dataTypes[0])return i=t.jsonpCallback=pe.isFunction(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,s?t[s]=t[s].replace(dn,\"$1\"+i):t.jsonp!==!1&&(t.url+=(It.test(t.url)?\"&\":\"?\")+t.jsonp+\"=\"+i),t.converters[\"script json\"]=function(){return a||pe.error(i+\" was not called\"),a[0]},t.dataTypes[0]=\"json\",o=e[i],e[i]=function(){a=arguments},r.always(function(){void 0===o?pe(e).removeProp(i):e[i]=o,t[i]&&(t.jsonpCallback=n.jsonpCallback,fn.push(i)),a&&pe.isFunction(o)&&o(a[0]),a=o=void 0}),\"script\"}),pe.parseHTML=function(e,t,n){if(!e||\"string\"!=typeof e)return null;\"boolean\"==typeof t&&(n=t,t=!1),t=t||re;var r=Te.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=y([e],t,i),i&&i.length&&pe(i).remove(),pe.merge([],r.childNodes))};var pn=pe.fn.load;return pe.fn.load=function(e,t,n){if(\"string\"!=typeof e&&pn)return pn.apply(this,arguments);var r,i,o,a=this,s=e.indexOf(\" \");return s>-1&&(r=pe.trim(e.slice(s,e.length)),e=e.slice(0,s)),pe.isFunction(t)?(n=t,t=void 0):t&&\"object\"==typeof t&&(i=\"POST\"),a.length>0&&pe.ajax({url:e,type:i||\"GET\",dataType:\"html\",data:t}).done(function(e){o=arguments,a.html(r?pe(\"<div>\").append(pe.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},pe.each([\"ajaxStart\",\"ajaxStop\",\"ajaxComplete\",\"ajaxError\",\"ajaxSuccess\",\"ajaxSend\"],function(e,t){pe.fn[t]=function(e){return this.on(t,e)}}),pe.expr.filters.animated=function(e){return pe.grep(pe.timers,function(t){return e===t.elem}).length},pe.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l,c=pe.css(e,\"position\"),f=pe(e),d={};\"static\"===c&&(e.style.position=\"relative\"),s=f.offset(),o=pe.css(e,\"top\"),u=pe.css(e,\"left\"),l=(\"absolute\"===c||\"fixed\"===c)&&pe.inArray(\"auto\",[o,u])>-1,l?(r=f.position(),a=r.top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),pe.isFunction(t)&&(t=t.call(e,n,pe.extend({},s))),null!=t.top&&(d.top=t.top-s.top+a),null!=t.left&&(d.left=t.left-s.left+i),\"using\"in t?t.using.call(e,d):f.css(d)}},pe.fn.extend({offset:function(e){if(arguments.length)return void 0===e?this:this.each(function(t){pe.offset.setOffset(this,e,t)});var t,n,r={top:0,left:0},i=this[0],o=i&&i.ownerDocument;if(o)return t=o.documentElement,pe.contains(t,i)?(\"undefined\"!=typeof i.getBoundingClientRect&&(r=i.getBoundingClientRect()),n=te(o),{top:r.top+(n.pageYOffset||t.scrollTop)-(t.clientTop||0),left:r.left+(n.pageXOffset||t.scrollLeft)-(t.clientLeft||0)}):r},position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return\"fixed\"===pe.css(r,\"position\")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),pe.nodeName(e[0],\"html\")||(n=e.offset()),n.top+=pe.css(e[0],\"borderTopWidth\",!0),n.left+=pe.css(e[0],\"borderLeftWidth\",!0)),{top:t.top-n.top-pe.css(r,\"marginTop\",!0),left:t.left-n.left-pe.css(r,\"marginLeft\",!0)}}},offsetParent:function(){return this.map(function(){\nfor(var e=this.offsetParent;e&&!pe.nodeName(e,\"html\")&&\"static\"===pe.css(e,\"position\");)e=e.offsetParent;return e||pt})}}),pe.each({scrollLeft:\"pageXOffset\",scrollTop:\"pageYOffset\"},function(e,t){var n=/Y/.test(t);pe.fn[e]=function(r){return Pe(this,function(e,r,i){var o=te(e);return void 0===i?o?t in o?o[t]:o.document.documentElement[r]:e[r]:void(o?o.scrollTo(n?pe(o).scrollLeft():i,n?i:pe(o).scrollTop()):e[r]=i)},e,r,arguments.length,null)}}),pe.each([\"top\",\"left\"],function(e,t){pe.cssHooks[t]=L(fe.pixelPosition,function(e,n){if(n)return n=gt(e,t),ft.test(n)?pe(e).position()[t]+\"px\":n})}),pe.each({Height:\"height\",Width:\"width\"},function(e,t){pe.each({padding:\"inner\"+e,content:t,\"\":\"outer\"+e},function(n,r){pe.fn[r]=function(r,i){var o=arguments.length&&(n||\"boolean\"!=typeof r),a=n||(r===!0||i===!0?\"margin\":\"border\");return Pe(this,function(t,n,r){var i;return pe.isWindow(t)?t.document.documentElement[\"client\"+e]:9===t.nodeType?(i=t.documentElement,Math.max(t.body[\"scroll\"+e],i[\"scroll\"+e],t.body[\"offset\"+e],i[\"offset\"+e],i[\"client\"+e])):void 0===r?pe.css(t,n,a):pe.style(t,n,r,a)},t,o?r:void 0,o,null)}})}),pe.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,\"**\"):this.off(t,e||\"**\",n)}}),pe.fn.size=function(){return this.length},pe.fn.andSelf=pe.fn.addBack,layui.define(function(e){layui.$=pe,e(\"jquery\",pe)}),pe});!function(e,t){\"use strict\";var i,n,a=e.layui&&layui.define,o={getPath:function(){var e=document.currentScript?document.currentScript.src:function(){for(var e,t=document.scripts,i=t.length-1,n=i;n>0;n--)if(\"interactive\"===t[n].readyState){e=t[n].src;break}return e||t[i].src}();return e.substring(0,e.lastIndexOf(\"/\")+1)}(),config:{},end:{},minIndex:0,minLeft:[],btn:[\"&#x786E;&#x5B9A;\",\"&#x53D6;&#x6D88;\"],type:[\"dialog\",\"page\",\"iframe\",\"loading\",\"tips\"],getStyle:function(t,i){var n=t.currentStyle?t.currentStyle:e.getComputedStyle(t,null);return n[n.getPropertyValue?\"getPropertyValue\":\"getAttribute\"](i)},link:function(t,i,n){if(r.path){var a=document.getElementsByTagName(\"head\")[0],s=document.createElement(\"link\");\"string\"==typeof i&&(n=i);var l=(n||t).replace(/\\.|\\//g,\"\"),f=\"layuicss-\"+l,c=0;s.rel=\"stylesheet\",s.href=r.path+t,s.id=f,document.getElementById(f)||a.appendChild(s),\"function\"==typeof i&&!function u(){return++c>80?e.console&&console.error(\"layer.css: Invalid\"):void(1989===parseInt(o.getStyle(document.getElementById(f),\"width\"))?i():setTimeout(u,100))}()}}},r={v:\"3.1.1\",ie:function(){var t=navigator.userAgent.toLowerCase();return!!(e.ActiveXObject||\"ActiveXObject\"in e)&&((t.match(/msie\\s(\\d+)/)||[])[1]||\"11\")}(),index:e.layer&&e.layer.v?1e5:0,path:o.getPath,config:function(e,t){return e=e||{},r.cache=o.config=i.extend({},o.config,e),r.path=o.config.path||r.path,\"string\"==typeof e.extend&&(e.extend=[e.extend]),o.config.path&&r.ready(),e.extend?(a?layui.addcss(\"modules/layer/\"+e.extend):o.link(\"theme/\"+e.extend),this):this},ready:function(e){var t=\"layer\",i=\"\",n=(a?\"modules/layer/\":\"theme/\")+\"default/layer.css?v=\"+r.v+i;return a?layui.addcss(n,e,t):o.link(n,e,t),this},alert:function(e,t,n){var a=\"function\"==typeof t;return a&&(n=t),r.open(i.extend({content:e,yes:n},a?{}:t))},confirm:function(e,t,n,a){var s=\"function\"==typeof t;return s&&(a=n,n=t),r.open(i.extend({content:e,btn:o.btn,yes:n,btn2:a},s?{}:t))},msg:function(e,n,a){var s=\"function\"==typeof n,f=o.config.skin,c=(f?f+\" \"+f+\"-msg\":\"\")||\"layui-layer-msg\",u=l.anim.length-1;return s&&(a=n),r.open(i.extend({content:e,time:3e3,shade:!1,skin:c,title:!1,closeBtn:!1,btn:!1,resize:!1,end:a},s&&!o.config.skin?{skin:c+\" layui-layer-hui\",anim:u}:function(){return n=n||{},(n.icon===-1||n.icon===t&&!o.config.skin)&&(n.skin=c+\" \"+(n.skin||\"layui-layer-hui\")),n}()))},load:function(e,t){return r.open(i.extend({type:3,icon:e||0,resize:!1,shade:.01},t))},tips:function(e,t,n){return r.open(i.extend({type:4,content:[e,t],closeBtn:!1,time:3e3,shade:!1,resize:!1,fixed:!1,maxWidth:210},n))}},s=function(e){var t=this;t.index=++r.index,t.config=i.extend({},t.config,o.config,e),document.body?t.creat():setTimeout(function(){t.creat()},30)};s.pt=s.prototype;var l=[\"layui-layer\",\".layui-layer-title\",\".layui-layer-main\",\".layui-layer-dialog\",\"layui-layer-iframe\",\"layui-layer-content\",\"layui-layer-btn\",\"layui-layer-close\"];l.anim=[\"layer-anim-00\",\"layer-anim-01\",\"layer-anim-02\",\"layer-anim-03\",\"layer-anim-04\",\"layer-anim-05\",\"layer-anim-06\"],s.pt.config={type:0,shade:.3,fixed:!0,move:l[1],title:\"&#x4FE1;&#x606F;\",offset:\"auto\",area:\"auto\",closeBtn:1,time:0,zIndex:19891014,maxWidth:360,anim:0,isOutAnim:!0,icon:-1,moveType:1,resize:!0,scrollbar:!0,tips:2},s.pt.vessel=function(e,t){var n=this,a=n.index,r=n.config,s=r.zIndex+a,f=\"object\"==typeof r.title,c=r.maxmin&&(1===r.type||2===r.type),u=r.title?'<div class=\"layui-layer-title\" style=\"'+(f?r.title[1]:\"\")+'\">'+(f?r.title[0]:r.title)+\"</div>\":\"\";return r.zIndex=s,t([r.shade?'<div class=\"layui-layer-shade\" id=\"layui-layer-shade'+a+'\" times=\"'+a+'\" style=\"'+(\"z-index:\"+(s-1)+\"; \")+'\"></div>':\"\",'<div class=\"'+l[0]+(\" layui-layer-\"+o.type[r.type])+(0!=r.type&&2!=r.type||r.shade?\"\":\" layui-layer-border\")+\" \"+(r.skin||\"\")+'\" id=\"'+l[0]+a+'\" type=\"'+o.type[r.type]+'\" times=\"'+a+'\" showtime=\"'+r.time+'\" conType=\"'+(e?\"object\":\"string\")+'\" style=\"z-index: '+s+\"; width:\"+r.area[0]+\";height:\"+r.area[1]+(r.fixed?\"\":\";position:absolute;\")+'\">'+(e&&2!=r.type?\"\":u)+'<div id=\"'+(r.id||\"\")+'\" class=\"layui-layer-content'+(0==r.type&&r.icon!==-1?\" layui-layer-padding\":\"\")+(3==r.type?\" layui-layer-loading\"+r.icon:\"\")+'\">'+(0==r.type&&r.icon!==-1?'<i class=\"layui-layer-ico layui-layer-ico'+r.icon+'\"></i>':\"\")+(1==r.type&&e?\"\":r.content||\"\")+'</div><span class=\"layui-layer-setwin\">'+function(){var e=c?'<a class=\"layui-layer-min\" href=\"javascript:;\"><cite></cite></a><a class=\"layui-layer-ico layui-layer-max\" href=\"javascript:;\"></a>':\"\";return r.closeBtn&&(e+='<a class=\"layui-layer-ico '+l[7]+\" \"+l[7]+(r.title?r.closeBtn:4==r.type?\"1\":\"2\")+'\" href=\"javascript:;\"></a>'),e}()+\"</span>\"+(r.btn?function(){var e=\"\";\"string\"==typeof r.btn&&(r.btn=[r.btn]);for(var t=0,i=r.btn.length;t<i;t++)e+='<a class=\"'+l[6]+t+'\">'+r.btn[t]+\"</a>\";return'<div class=\"'+l[6]+\" layui-layer-btn-\"+(r.btnAlign||\"\")+'\">'+e+\"</div>\"}():\"\")+(r.resize?'<span class=\"layui-layer-resize\"></span>':\"\")+\"</div>\"],u,i('<div class=\"layui-layer-move\"></div>')),n},s.pt.creat=function(){var e=this,t=e.config,a=e.index,s=t.content,f=\"object\"==typeof s,c=i(\"body\");if(!t.id||!i(\"#\"+t.id)[0]){switch(\"string\"==typeof t.area&&(t.area=\"auto\"===t.area?[\"\",\"\"]:[t.area,\"\"]),t.shift&&(t.anim=t.shift),6==r.ie&&(t.fixed=!1),t.type){case 0:t.btn=\"btn\"in t?t.btn:o.btn[0],r.closeAll(\"dialog\");break;case 2:var s=t.content=f?t.content:[t.content||\"http://layer.layui.com\",\"auto\"];t.content='<iframe scrolling=\"'+(t.content[1]||\"auto\")+'\" allowtransparency=\"true\" id=\"'+l[4]+a+'\" name=\"'+l[4]+a+'\" onload=\"this.className=\\'\\';\" class=\"layui-layer-load\" frameborder=\"0\" src=\"'+t.content[0]+'\"></iframe>';break;case 3:delete t.title,delete t.closeBtn,t.icon===-1&&0===t.icon,r.closeAll(\"loading\");break;case 4:f||(t.content=[t.content,\"body\"]),t.follow=t.content[1],t.content=t.content[0]+'<i class=\"layui-layer-TipsG\"></i>',delete t.title,t.tips=\"object\"==typeof t.tips?t.tips:[t.tips,!0],t.tipsMore||r.closeAll(\"tips\")}if(e.vessel(f,function(n,r,u){c.append(n[0]),f?function(){2==t.type||4==t.type?function(){i(\"body\").append(n[1])}():function(){s.parents(\".\"+l[0])[0]||(s.data(\"display\",s.css(\"display\")).show().addClass(\"layui-layer-wrap\").wrap(n[1]),i(\"#\"+l[0]+a).find(\".\"+l[5]).before(r))}()}():c.append(n[1]),i(\".layui-layer-move\")[0]||c.append(o.moveElem=u),e.layero=i(\"#\"+l[0]+a),t.scrollbar||l.html.css(\"overflow\",\"hidden\").attr(\"layer-full\",a)}).auto(a),i(\"#layui-layer-shade\"+e.index).css({\"background-color\":t.shade[1]||\"#000\",opacity:t.shade[0]||t.shade}),2==t.type&&6==r.ie&&e.layero.find(\"iframe\").attr(\"src\",s[0]),4==t.type?e.tips():e.offset(),t.fixed&&n.on(\"resize\",function(){e.offset(),(/^\\d+%$/.test(t.area[0])||/^\\d+%$/.test(t.area[1]))&&e.auto(a),4==t.type&&e.tips()}),t.time<=0||setTimeout(function(){r.close(e.index)},t.time),e.move().callback(),l.anim[t.anim]){var u=\"layer-anim \"+l.anim[t.anim];e.layero.addClass(u).one(\"webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend\",function(){i(this).removeClass(u)})}t.isOutAnim&&e.layero.data(\"isOutAnim\",!0)}},s.pt.auto=function(e){var t=this,a=t.config,o=i(\"#\"+l[0]+e);\"\"===a.area[0]&&a.maxWidth>0&&(r.ie&&r.ie<8&&a.btn&&o.width(o.innerWidth()),o.outerWidth()>a.maxWidth&&o.width(a.maxWidth));var s=[o.innerWidth(),o.innerHeight()],f=o.find(l[1]).outerHeight()||0,c=o.find(\".\"+l[6]).outerHeight()||0,u=function(e){e=o.find(e),e.height(s[1]-f-c-2*(0|parseFloat(e.css(\"padding-top\"))))};switch(a.type){case 2:u(\"iframe\");break;default:\"\"===a.area[1]?a.maxHeight>0&&o.outerHeight()>a.maxHeight?(s[1]=a.maxHeight,u(\".\"+l[5])):a.fixed&&s[1]>=n.height()&&(s[1]=n.height(),u(\".\"+l[5])):u(\".\"+l[5])}return t},s.pt.offset=function(){var e=this,t=e.config,i=e.layero,a=[i.outerWidth(),i.outerHeight()],o=\"object\"==typeof t.offset;e.offsetTop=(n.height()-a[1])/2,e.offsetLeft=(n.width()-a[0])/2,o?(e.offsetTop=t.offset[0],e.offsetLeft=t.offset[1]||e.offsetLeft):\"auto\"!==t.offset&&(\"t\"===t.offset?e.offsetTop=0:\"r\"===t.offset?e.offsetLeft=n.width()-a[0]:\"b\"===t.offset?e.offsetTop=n.height()-a[1]:\"l\"===t.offset?e.offsetLeft=0:\"lt\"===t.offset?(e.offsetTop=0,e.offsetLeft=0):\"lb\"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=0):\"rt\"===t.offset?(e.offsetTop=0,e.offsetLeft=n.width()-a[0]):\"rb\"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=n.width()-a[0]):e.offsetTop=t.offset),t.fixed||(e.offsetTop=/%$/.test(e.offsetTop)?n.height()*parseFloat(e.offsetTop)/100:parseFloat(e.offsetTop),e.offsetLeft=/%$/.test(e.offsetLeft)?n.width()*parseFloat(e.offsetLeft)/100:parseFloat(e.offsetLeft),e.offsetTop+=n.scrollTop(),e.offsetLeft+=n.scrollLeft()),i.attr(\"minLeft\")&&(e.offsetTop=n.height()-(i.find(l[1]).outerHeight()||0),e.offsetLeft=i.css(\"left\")),i.css({top:e.offsetTop,left:e.offsetLeft})},s.pt.tips=function(){var e=this,t=e.config,a=e.layero,o=[a.outerWidth(),a.outerHeight()],r=i(t.follow);r[0]||(r=i(\"body\"));var s={width:r.outerWidth(),height:r.outerHeight(),top:r.offset().top,left:r.offset().left},f=a.find(\".layui-layer-TipsG\"),c=t.tips[0];t.tips[1]||f.remove(),s.autoLeft=function(){s.left+o[0]-n.width()>0?(s.tipLeft=s.left+s.width-o[0],f.css({right:12,left:\"auto\"})):s.tipLeft=s.left},s.where=[function(){s.autoLeft(),s.tipTop=s.top-o[1]-10,f.removeClass(\"layui-layer-TipsB\").addClass(\"layui-layer-TipsT\").css(\"border-right-color\",t.tips[1])},function(){s.tipLeft=s.left+s.width+10,s.tipTop=s.top,f.removeClass(\"layui-layer-TipsL\").addClass(\"layui-layer-TipsR\").css(\"border-bottom-color\",t.tips[1])},function(){s.autoLeft(),s.tipTop=s.top+s.height+10,f.removeClass(\"layui-layer-TipsT\").addClass(\"layui-layer-TipsB\").css(\"border-right-color\",t.tips[1])},function(){s.tipLeft=s.left-o[0]-10,s.tipTop=s.top,f.removeClass(\"layui-layer-TipsR\").addClass(\"layui-layer-TipsL\").css(\"border-bottom-color\",t.tips[1])}],s.where[c-1](),1===c?s.top-(n.scrollTop()+o[1]+16)<0&&s.where[2]():2===c?n.width()-(s.left+s.width+o[0]+16)>0||s.where[3]():3===c?s.top-n.scrollTop()+s.height+o[1]+16-n.height()>0&&s.where[0]():4===c&&o[0]+16-s.left>0&&s.where[1](),a.find(\".\"+l[5]).css({\"background-color\":t.tips[1],\"padding-right\":t.closeBtn?\"30px\":\"\"}),a.css({left:s.tipLeft-(t.fixed?n.scrollLeft():0),top:s.tipTop-(t.fixed?n.scrollTop():0)})},s.pt.move=function(){var e=this,t=e.config,a=i(document),s=e.layero,l=s.find(t.move),f=s.find(\".layui-layer-resize\"),c={};return t.move&&l.css(\"cursor\",\"move\"),l.on(\"mousedown\",function(e){e.preventDefault(),t.move&&(c.moveStart=!0,c.offset=[e.clientX-parseFloat(s.css(\"left\")),e.clientY-parseFloat(s.css(\"top\"))],o.moveElem.css(\"cursor\",\"move\").show())}),f.on(\"mousedown\",function(e){e.preventDefault(),c.resizeStart=!0,c.offset=[e.clientX,e.clientY],c.area=[s.outerWidth(),s.outerHeight()],o.moveElem.css(\"cursor\",\"se-resize\").show()}),a.on(\"mousemove\",function(i){if(c.moveStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1],l=\"fixed\"===s.css(\"position\");if(i.preventDefault(),c.stX=l?0:n.scrollLeft(),c.stY=l?0:n.scrollTop(),!t.moveOut){var f=n.width()-s.outerWidth()+c.stX,u=n.height()-s.outerHeight()+c.stY;a<c.stX&&(a=c.stX),a>f&&(a=f),o<c.stY&&(o=c.stY),o>u&&(o=u)}s.css({left:a,top:o})}if(t.resize&&c.resizeStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1];i.preventDefault(),r.style(e.index,{width:c.area[0]+a,height:c.area[1]+o}),c.isResize=!0,t.resizing&&t.resizing(s)}}).on(\"mouseup\",function(e){c.moveStart&&(delete c.moveStart,o.moveElem.hide(),t.moveEnd&&t.moveEnd(s)),c.resizeStart&&(delete c.resizeStart,o.moveElem.hide())}),e},s.pt.callback=function(){function e(){var e=a.cancel&&a.cancel(t.index,n);e===!1||r.close(t.index)}var t=this,n=t.layero,a=t.config;t.openLayer(),a.success&&(2==a.type?n.find(\"iframe\").on(\"load\",function(){a.success(n,t.index)}):a.success(n,t.index)),6==r.ie&&t.IE6(n),n.find(\".\"+l[6]).children(\"a\").on(\"click\",function(){var e=i(this).index();if(0===e)a.yes?a.yes(t.index,n):a.btn1?a.btn1(t.index,n):r.close(t.index);else{var o=a[\"btn\"+(e+1)]&&a[\"btn\"+(e+1)](t.index,n);o===!1||r.close(t.index)}}),n.find(\".\"+l[7]).on(\"click\",e),a.shadeClose&&i(\"#layui-layer-shade\"+t.index).on(\"click\",function(){r.close(t.index)}),n.find(\".layui-layer-min\").on(\"click\",function(){var e=a.min&&a.min(n);e===!1||r.min(t.index,a)}),n.find(\".layui-layer-max\").on(\"click\",function(){i(this).hasClass(\"layui-layer-maxmin\")?(r.restore(t.index),a.restore&&a.restore(n)):(r.full(t.index,a),setTimeout(function(){a.full&&a.full(n)},100))}),a.end&&(o.end[t.index]=a.end)},o.reselect=function(){i.each(i(\"select\"),function(e,t){var n=i(this);n.parents(\".\"+l[0])[0]||1==n.attr(\"layer\")&&i(\".\"+l[0]).length<1&&n.removeAttr(\"layer\").show(),n=null})},s.pt.IE6=function(e){i(\"select\").each(function(e,t){var n=i(this);n.parents(\".\"+l[0])[0]||\"none\"===n.css(\"display\")||n.attr({layer:\"1\"}).hide(),n=null})},s.pt.openLayer=function(){var e=this;r.zIndex=e.config.zIndex,r.setTop=function(e){var t=function(){r.zIndex++,e.css(\"z-index\",r.zIndex+1)};return r.zIndex=parseInt(e[0].style.zIndex),e.on(\"mousedown\",t),r.zIndex}},o.record=function(e){var t=[e.width(),e.height(),e.position().top,e.position().left+parseFloat(e.css(\"margin-left\"))];e.find(\".layui-layer-max\").addClass(\"layui-layer-maxmin\"),e.attr({area:t})},o.rescollbar=function(e){l.html.attr(\"layer-full\")==e&&(l.html[0].style.removeProperty?l.html[0].style.removeProperty(\"overflow\"):l.html[0].style.removeAttribute(\"overflow\"),l.html.removeAttr(\"layer-full\"))},e.layer=r,r.getChildFrame=function(e,t){return t=t||i(\".\"+l[4]).attr(\"times\"),i(\"#\"+l[0]+t).find(\"iframe\").contents().find(e)},r.getFrameIndex=function(e){return i(\"#\"+e).parents(\".\"+l[4]).attr(\"times\")},r.iframeAuto=function(e){if(e){var t=r.getChildFrame(\"html\",e).outerHeight(),n=i(\"#\"+l[0]+e),a=n.find(l[1]).outerHeight()||0,o=n.find(\".\"+l[6]).outerHeight()||0;n.css({height:t+a+o}),n.find(\"iframe\").css({height:t})}},r.iframeSrc=function(e,t){i(\"#\"+l[0]+e).find(\"iframe\").attr(\"src\",t)},r.style=function(e,t,n){var a=i(\"#\"+l[0]+e),r=a.find(\".layui-layer-content\"),s=a.attr(\"type\"),f=a.find(l[1]).outerHeight()||0,c=a.find(\".\"+l[6]).outerHeight()||0;a.attr(\"minLeft\");s!==o.type[3]&&s!==o.type[4]&&(n||(parseFloat(t.width)<=260&&(t.width=260),parseFloat(t.height)-f-c<=64&&(t.height=64+f+c)),a.css(t),c=a.find(\".\"+l[6]).outerHeight(),s===o.type[2]?a.find(\"iframe\").css({height:parseFloat(t.height)-f-c}):r.css({height:parseFloat(t.height)-f-c-parseFloat(r.css(\"padding-top\"))-parseFloat(r.css(\"padding-bottom\"))}))},r.min=function(e,t){var a=i(\"#\"+l[0]+e),s=a.find(l[1]).outerHeight()||0,f=a.attr(\"minLeft\")||181*o.minIndex+\"px\",c=a.css(\"position\");o.record(a),o.minLeft[0]&&(f=o.minLeft[0],o.minLeft.shift()),a.attr(\"position\",c),r.style(e,{width:180,height:s,left:f,top:n.height()-s,position:\"fixed\",overflow:\"hidden\"},!0),a.find(\".layui-layer-min\").hide(),\"page\"===a.attr(\"type\")&&a.find(l[4]).hide(),o.rescollbar(e),a.attr(\"minLeft\")||o.minIndex++,a.attr(\"minLeft\",f)},r.restore=function(e){var t=i(\"#\"+l[0]+e),n=t.attr(\"area\").split(\",\");t.attr(\"type\");r.style(e,{width:parseFloat(n[0]),height:parseFloat(n[1]),top:parseFloat(n[2]),left:parseFloat(n[3]),position:t.attr(\"position\"),overflow:\"visible\"},!0),t.find(\".layui-layer-max\").removeClass(\"layui-layer-maxmin\"),t.find(\".layui-layer-min\").show(),\"page\"===t.attr(\"type\")&&t.find(l[4]).show(),o.rescollbar(e)},r.full=function(e){var t,a=i(\"#\"+l[0]+e);o.record(a),l.html.attr(\"layer-full\")||l.html.css(\"overflow\",\"hidden\").attr(\"layer-full\",e),clearTimeout(t),t=setTimeout(function(){var t=\"fixed\"===a.css(\"position\");r.style(e,{top:t?0:n.scrollTop(),left:t?0:n.scrollLeft(),width:n.width(),height:n.height()},!0),a.find(\".layui-layer-min\").hide()},100)},r.title=function(e,t){var n=i(\"#\"+l[0]+(t||r.index)).find(l[1]);n.html(e)},r.close=function(e){var t=i(\"#\"+l[0]+e),n=t.attr(\"type\"),a=\"layer-anim-close\";if(t[0]){var s=\"layui-layer-wrap\",f=function(){if(n===o.type[1]&&\"object\"===t.attr(\"conType\")){t.children(\":not(.\"+l[5]+\")\").remove();for(var a=t.find(\".\"+s),r=0;r<2;r++)a.unwrap();a.css(\"display\",a.data(\"display\")).removeClass(s)}else{if(n===o.type[2])try{var f=i(\"#\"+l[4]+e)[0];f.contentWindow.document.write(\"\"),f.contentWindow.close(),t.find(\".\"+l[5])[0].removeChild(f)}catch(c){}t[0].innerHTML=\"\",t.remove()}\"function\"==typeof o.end[e]&&o.end[e](),delete o.end[e]};t.data(\"isOutAnim\")&&t.addClass(\"layer-anim \"+a),i(\"#layui-layer-moves, #layui-layer-shade\"+e).remove(),6==r.ie&&o.reselect(),o.rescollbar(e),t.attr(\"minLeft\")&&(o.minIndex--,o.minLeft.push(t.attr(\"minLeft\"))),r.ie&&r.ie<10||!t.data(\"isOutAnim\")?f():setTimeout(function(){f()},200)}},r.closeAll=function(e){i.each(i(\".\"+l[0]),function(){var t=i(this),n=e?t.attr(\"type\")===e:1;n&&r.close(t.attr(\"times\")),n=null})};var f=r.cache||{},c=function(e){return f.skin?\" \"+f.skin+\" \"+f.skin+\"-\"+e:\"\"};r.prompt=function(e,t){var a=\"\";if(e=e||{},\"function\"==typeof e&&(t=e),e.area){var o=e.area;a='style=\"width: '+o[0]+\"; height: \"+o[1]+';\"',delete e.area}var s,l=2==e.formType?'<textarea class=\"layui-layer-input\"'+a+\"></textarea>\":function(){return'<input type=\"'+(1==e.formType?\"password\":\"text\")+'\" class=\"layui-layer-input\">'}(),f=e.success;return delete e.success,r.open(i.extend({type:1,btn:[\"&#x786E;&#x5B9A;\",\"&#x53D6;&#x6D88;\"],content:l,skin:\"layui-layer-prompt\"+c(\"prompt\"),maxWidth:n.width(),success:function(t){s=t.find(\".layui-layer-input\"),s.val(e.value||\"\").focus(),\"function\"==typeof f&&f(t)},resize:!1,yes:function(i){var n=s.val();\"\"===n?s.focus():n.length>(e.maxlength||500)?r.tips(\"&#x6700;&#x591A;&#x8F93;&#x5165;\"+(e.maxlength||500)+\"&#x4E2A;&#x5B57;&#x6570;\",s,{tips:1}):t&&t(n,i,s)}},e))},r.tab=function(e){e=e||{};var t=e.tab||{},n=\"layui-this\",a=e.success;return delete e.success,r.open(i.extend({type:1,skin:\"layui-layer-tab\"+c(\"tab\"),resize:!1,title:function(){var e=t.length,i=1,a=\"\";if(e>0)for(a='<span class=\"'+n+'\">'+t[0].title+\"</span>\";i<e;i++)a+=\"<span>\"+t[i].title+\"</span>\";return a}(),content:'<ul class=\"layui-layer-tabmain\">'+function(){var e=t.length,i=1,a=\"\";if(e>0)for(a='<li class=\"layui-layer-tabli '+n+'\">'+(t[0].content||\"no content\")+\"</li>\";i<e;i++)a+='<li class=\"layui-layer-tabli\">'+(t[i].content||\"no  content\")+\"</li>\";return a}()+\"</ul>\",success:function(t){var o=t.find(\".layui-layer-title\").children(),r=t.find(\".layui-layer-tabmain\").children();o.on(\"mousedown\",function(t){t.stopPropagation?t.stopPropagation():t.cancelBubble=!0;var a=i(this),o=a.index();a.addClass(n).siblings().removeClass(n),r.eq(o).show().siblings().hide(),\"function\"==typeof e.change&&e.change(o)}),\"function\"==typeof a&&a(t)}},e))},r.photos=function(t,n,a){function o(e,t,i){var n=new Image;return n.src=e,n.complete?t(n):(n.onload=function(){n.onload=null,t(n)},void(n.onerror=function(e){n.onerror=null,i(e)}))}var s={};if(t=t||{},t.photos){var l=t.photos.constructor===Object,f=l?t.photos:{},u=f.data||[],d=f.start||0;s.imgIndex=(0|d)+1,t.img=t.img||\"img\";var y=t.success;if(delete t.success,l){if(0===u.length)return r.msg(\"&#x6CA1;&#x6709;&#x56FE;&#x7247;\")}else{var p=i(t.photos),h=function(){u=[],p.find(t.img).each(function(e){var t=i(this);t.attr(\"layer-index\",e),u.push({alt:t.attr(\"alt\"),pid:t.attr(\"layer-pid\"),src:t.attr(\"layer-src\")||t.attr(\"src\"),thumb:t.attr(\"src\")})})};if(h(),0===u.length)return;if(n||p.on(\"click\",t.img,function(){var e=i(this),n=e.attr(\"layer-index\");r.photos(i.extend(t,{photos:{start:n,data:u,tab:t.tab},full:t.full}),!0),h()}),!n)return}s.imgprev=function(e){s.imgIndex--,s.imgIndex<1&&(s.imgIndex=u.length),s.tabimg(e)},s.imgnext=function(e,t){s.imgIndex++,s.imgIndex>u.length&&(s.imgIndex=1,t)||s.tabimg(e)},s.keyup=function(e){if(!s.end){var t=e.keyCode;e.preventDefault(),37===t?s.imgprev(!0):39===t?s.imgnext(!0):27===t&&r.close(s.index)}},s.tabimg=function(e){if(!(u.length<=1))return f.start=s.imgIndex-1,r.close(s.index),r.photos(t,!0,e)},s.event=function(){s.bigimg.hover(function(){s.imgsee.show()},function(){s.imgsee.hide()}),s.bigimg.find(\".layui-layer-imgprev\").on(\"click\",function(e){e.preventDefault(),s.imgprev()}),s.bigimg.find(\".layui-layer-imgnext\").on(\"click\",function(e){e.preventDefault(),s.imgnext()}),i(document).on(\"keyup\",s.keyup)},s.loadi=r.load(1,{shade:!(\"shade\"in t)&&.9,scrollbar:!1}),o(u[d].src,function(n){r.close(s.loadi),s.index=r.open(i.extend({type:1,id:\"layui-layer-photos\",area:function(){var a=[n.width,n.height],o=[i(e).width()-100,i(e).height()-100];if(!t.full&&(a[0]>o[0]||a[1]>o[1])){var r=[a[0]/o[0],a[1]/o[1]];r[0]>r[1]?(a[0]=a[0]/r[0],a[1]=a[1]/r[0]):r[0]<r[1]&&(a[0]=a[0]/r[1],a[1]=a[1]/r[1])}return[a[0]+\"px\",a[1]+\"px\"]}(),title:!1,shade:.9,shadeClose:!0,closeBtn:!1,move:\".layui-layer-phimg img\",moveType:1,scrollbar:!1,moveOut:!0,isOutAnim:!1,skin:\"layui-layer-photos\"+c(\"photos\"),content:'<div class=\"layui-layer-phimg\"><img src=\"'+u[d].src+'\" alt=\"'+(u[d].alt||\"\")+'\" layer-pid=\"'+u[d].pid+'\"><div class=\"layui-layer-imgsee\">'+(u.length>1?'<span class=\"layui-layer-imguide\"><a href=\"javascript:;\" class=\"layui-layer-iconext layui-layer-imgprev\"></a><a href=\"javascript:;\" class=\"layui-layer-iconext layui-layer-imgnext\"></a></span>':\"\")+'<div class=\"layui-layer-imgbar\" style=\"display:'+(a?\"block\":\"\")+'\"><span class=\"layui-layer-imgtit\"><a href=\"javascript:;\">'+(u[d].alt||\"\")+\"</a><em>\"+s.imgIndex+\"/\"+u.length+\"</em></span></div></div></div>\",success:function(e,i){s.bigimg=e.find(\".layui-layer-phimg\"),s.imgsee=e.find(\".layui-layer-imguide,.layui-layer-imgbar\"),s.event(e),t.tab&&t.tab(u[d],e),\"function\"==typeof y&&y(e)},end:function(){s.end=!0,i(document).off(\"keyup\",s.keyup)}},t))},function(){r.close(s.loadi),r.msg(\"&#x5F53;&#x524D;&#x56FE;&#x7247;&#x5730;&#x5740;&#x5F02;&#x5E38;<br>&#x662F;&#x5426;&#x7EE7;&#x7EED;&#x67E5;&#x770B;&#x4E0B;&#x4E00;&#x5F20;&#xFF1F;\",{time:3e4,btn:[\"&#x4E0B;&#x4E00;&#x5F20;\",\"&#x4E0D;&#x770B;&#x4E86;\"],yes:function(){u.length>1&&s.imgnext(!0,!0)}})})}},o.run=function(t){i=t,n=i(e),l.html=i(\"html\"),r.open=function(e){var t=new s(e);return t.index}},e.layui&&layui.define?(r.ready(),layui.define(\"jquery\",function(t){r.path=layui.cache.dir,o.run(layui.$),e.layer=r,t(\"layer\",r)})):\"function\"==typeof define&&define.amd?define([\"jquery\"],function(){return o.run(e.jQuery),r}):function(){o.run(e.jQuery),r.ready()}()}(window);layui.define(\"jquery\",function(t){\"use strict\";var a=layui.$,i=(layui.hint(),layui.device()),e=\"element\",l=\"layui-this\",n=\"layui-show\",s=function(){this.config={}};s.prototype.set=function(t){var i=this;return a.extend(!0,i.config,t),i},s.prototype.on=function(t,a){return layui.onevent.call(this,e,t,a)},s.prototype.tabAdd=function(t,i){var e=\".layui-tab-title\",l=a(\".layui-tab[lay-filter=\"+t+\"]\"),n=l.children(e),s=n.children(\".layui-tab-bar\"),o=l.children(\".layui-tab-content\"),r='<li lay-id=\"'+(i.id||\"\")+'\"'+(i.attr?' lay-attr=\"'+i.attr+'\"':\"\")+\">\"+(i.title||\"unnaming\")+\"</li>\";return s[0]?s.before(r):n.append(r),o.append('<div class=\"layui-tab-item\">'+(i.content||\"\")+\"</div>\"),f.hideTabMore(!0),f.tabAuto(),this},s.prototype.tabDelete=function(t,i){var e=\".layui-tab-title\",l=a(\".layui-tab[lay-filter=\"+t+\"]\"),n=l.children(e),s=n.find('>li[lay-id=\"'+i+'\"]');return f.tabDelete(null,s),this},s.prototype.tabChange=function(t,i){var e=\".layui-tab-title\",l=a(\".layui-tab[lay-filter=\"+t+\"]\"),n=l.children(e),s=n.find('>li[lay-id=\"'+i+'\"]');return f.tabClick.call(s[0],null,null,s),this},s.prototype.tab=function(t){t=t||{},b.on(\"click\",t.headerElem,function(i){var e=a(this).index();f.tabClick.call(this,i,e,null,t)})},s.prototype.progress=function(t,i){var e=\"layui-progress\",l=a(\".\"+e+\"[lay-filter=\"+t+\"]\"),n=l.find(\".\"+e+\"-bar\"),s=n.find(\".\"+e+\"-text\");return n.css(\"width\",i),s.text(i),this};var o=\".layui-nav\",r=\"layui-nav-item\",c=\"layui-nav-bar\",u=\"layui-nav-tree\",d=\"layui-nav-child\",y=\"layui-nav-more\",h=\"layui-anim layui-anim-upbit\",f={tabClick:function(t,i,s,o){o=o||{};var r=s||a(this),i=i||r.parent().children(\"li\").index(r),c=o.headerElem?r.parent():r.parents(\".layui-tab\").eq(0),u=o.bodyElem?a(o.bodyElem):c.children(\".layui-tab-content\").children(\".layui-tab-item\"),d=r.find(\"a\"),y=c.attr(\"lay-filter\");\"javascript:;\"!==d.attr(\"href\")&&\"_blank\"===d.attr(\"target\")||(r.addClass(l).siblings().removeClass(l),u.eq(i).addClass(n).siblings().removeClass(n)),layui.event.call(this,e,\"tab(\"+y+\")\",{elem:c,index:i})},tabDelete:function(t,i){var n=i||a(this).parent(),s=n.index(),o=n.parents(\".layui-tab\").eq(0),r=o.children(\".layui-tab-content\").children(\".layui-tab-item\"),c=o.attr(\"lay-filter\");n.hasClass(l)&&(n.next()[0]?f.tabClick.call(n.next()[0],null,s+1):n.prev()[0]&&f.tabClick.call(n.prev()[0],null,s-1)),n.remove(),r.eq(s).remove(),setTimeout(function(){f.tabAuto()},50),layui.event.call(this,e,\"tabDelete(\"+c+\")\",{elem:o,index:s})},tabAuto:function(){var t=\"layui-tab-more\",e=\"layui-tab-bar\",l=\"layui-tab-close\",n=this;a(\".layui-tab\").each(function(){var s=a(this),o=s.children(\".layui-tab-title\"),r=(s.children(\".layui-tab-content\").children(\".layui-tab-item\"),'lay-stope=\"tabmore\"'),c=a('<span class=\"layui-unselect layui-tab-bar\" '+r+\"><i \"+r+' class=\"layui-icon\">&#xe61a;</i></span>');if(n===window&&8!=i.ie&&f.hideTabMore(!0),s.attr(\"lay-allowClose\")&&o.find(\"li\").each(function(){var t=a(this);if(!t.find(\".\"+l)[0]){var i=a('<i class=\"layui-icon layui-unselect '+l+'\">&#x1006;</i>');i.on(\"click\",f.tabDelete),t.append(i)}}),\"string\"!=typeof s.attr(\"lay-unauto\"))if(o.prop(\"scrollWidth\")>o.outerWidth()+1){if(o.find(\".\"+e)[0])return;o.append(c),s.attr(\"overflow\",\"\"),c.on(\"click\",function(a){o[this.title?\"removeClass\":\"addClass\"](t),this.title=this.title?\"\":\"收缩\"})}else o.find(\".\"+e).remove(),s.removeAttr(\"overflow\")})},hideTabMore:function(t){var i=a(\".layui-tab-title\");t!==!0&&\"tabmore\"===a(t.target).attr(\"lay-stope\")||(i.removeClass(\"layui-tab-more\"),i.find(\".layui-tab-bar\").attr(\"title\",\"\"))},clickThis:function(){var t=a(this),i=t.parents(o),n=i.attr(\"lay-filter\"),s=t.parent(),c=t.siblings(\".\"+d),y=\"string\"==typeof s.attr(\"lay-unselect\");\"javascript:;\"!==t.attr(\"href\")&&\"_blank\"===t.attr(\"target\")||y||c[0]||(i.find(\".\"+l).removeClass(l),s.addClass(l)),i.hasClass(u)&&(c.removeClass(h),c[0]&&(s[\"none\"===c.css(\"display\")?\"addClass\":\"removeClass\"](r+\"ed\"),\"all\"===i.attr(\"lay-shrink\")&&s.siblings().removeClass(r+\"ed\"))),layui.event.call(this,e,\"nav(\"+n+\")\",t)},collapse:function(){var t=a(this),i=t.find(\".layui-colla-icon\"),l=t.siblings(\".layui-colla-content\"),s=t.parents(\".layui-collapse\").eq(0),o=s.attr(\"lay-filter\"),r=\"none\"===l.css(\"display\");if(\"string\"==typeof s.attr(\"lay-accordion\")){var c=s.children(\".layui-colla-item\").children(\".\"+n);c.siblings(\".layui-colla-title\").children(\".layui-colla-icon\").html(\"&#xe602;\"),c.removeClass(n)}l[r?\"addClass\":\"removeClass\"](n),i.html(r?\"&#xe61a;\":\"&#xe602;\"),layui.event.call(this,e,\"collapse(\"+o+\")\",{title:t,content:l,show:r})}};s.prototype.init=function(t,e){var l=function(){return e?'[lay-filter=\"'+e+'\"]':\"\"}(),s={tab:function(){f.tabAuto.call({})},nav:function(){var t=200,e={},s={},p={},b=function(l,o,r){var c=a(this),f=c.find(\".\"+d);o.hasClass(u)?l.css({top:c.position().top,height:c.children(\"a\").outerHeight(),opacity:1}):(f.addClass(h),l.css({left:c.position().left+parseFloat(c.css(\"marginLeft\")),top:c.position().top+c.height()-l.height()}),e[r]=setTimeout(function(){l.css({width:c.width(),opacity:1})},i.ie&&i.ie<10?0:t),clearTimeout(p[r]),\"block\"===f.css(\"display\")&&clearTimeout(s[r]),s[r]=setTimeout(function(){f.addClass(n),c.find(\".\"+y).addClass(y+\"d\")},300))};a(o+l).each(function(i){var l=a(this),o=a('<span class=\"'+c+'\"></span>'),h=l.find(\".\"+r);l.find(\".\"+c)[0]||(l.append(o),h.on(\"mouseenter\",function(){b.call(this,o,l,i)}).on(\"mouseleave\",function(){l.hasClass(u)||(clearTimeout(s[i]),s[i]=setTimeout(function(){l.find(\".\"+d).removeClass(n),l.find(\".\"+y).removeClass(y+\"d\")},300))}),l.on(\"mouseleave\",function(){clearTimeout(e[i]),p[i]=setTimeout(function(){l.hasClass(u)?o.css({height:0,top:o.position().top+o.height()/2,opacity:0}):o.css({width:0,left:o.position().left+o.width()/2,opacity:0})},t)})),h.find(\"a\").each(function(){var t=a(this),i=(t.parent(),t.siblings(\".\"+d));i[0]&&!t.children(\".\"+y)[0]&&t.append('<span class=\"'+y+'\"></span>'),t.off(\"click\",f.clickThis).on(\"click\",f.clickThis)})})},breadcrumb:function(){var t=\".layui-breadcrumb\";a(t+l).each(function(){var t=a(this),i=\"lay-separator\",e=t.attr(i)||\"/\",l=t.find(\"a\");l.next(\"span[\"+i+\"]\")[0]||(l.each(function(t){t!==l.length-1&&a(this).after(\"<span \"+i+\">\"+e+\"</span>\")}),t.css(\"visibility\",\"visible\"))})},progress:function(){var t=\"layui-progress\";a(\".\"+t+l).each(function(){var i=a(this),e=i.find(\".layui-progress-bar\"),l=e.attr(\"lay-percent\");e.css(\"width\",function(){return/^.+\\/.+$/.test(l)?100*new Function(\"return \"+l)()+\"%\":l}()),i.attr(\"lay-showPercent\")&&setTimeout(function(){e.html('<span class=\"'+t+'-text\">'+l+\"</span>\")},350)})},collapse:function(){var t=\"layui-collapse\";a(\".\"+t+l).each(function(){var t=a(this).find(\".layui-colla-item\");t.each(function(){var t=a(this),i=t.find(\".layui-colla-title\"),e=t.find(\".layui-colla-content\"),l=\"none\"===e.css(\"display\");i.find(\".layui-colla-icon\").remove(),i.append('<i class=\"layui-icon layui-colla-icon\">'+(l?\"&#xe602;\":\"&#xe61a;\")+\"</i>\"),i.off(\"click\",f.collapse).on(\"click\",f.collapse)})})}};return s[t]?s[t]():layui.each(s,function(t,a){a()})},s.prototype.render=s.prototype.init;var p=new s,b=a(document);p.render();var v=\".layui-tab-title li\";b.on(\"click\",v,f.tabClick),b.on(\"click\",f.hideTabMore),a(window).on(\"resize\",f.tabAuto),t(e,p)});layui.define(\"layer\",function(e){\"use strict\";var i=layui.$,t=layui.layer,n=layui.hint(),a=layui.device(),o={config:{},set:function(e){var t=this;return t.config=i.extend({},t.config,e),t},on:function(e,i){return layui.onevent.call(this,r,e,i)}},l=function(){var e=this;return{upload:function(i){e.upload.call(e,i)},config:e.config}},r=\"upload\",u=\"layui-upload-file\",c=\"layui-upload-form\",f=\"layui-upload-iframe\",s=\"layui-upload-choose\",p=function(e){var t=this;t.config=i.extend({},t.config,o.config,e),t.render()};p.prototype.config={accept:\"images\",exts:\"\",auto:!0,bindAction:\"\",url:\"\",field:\"file\",method:\"post\",data:{},drag:!0,size:0,number:0,multiple:!1},p.prototype.render=function(e){var t=this,e=t.config;e.elem=i(e.elem),e.bindAction=i(e.bindAction),t.file(),t.events()},p.prototype.file=function(){var e=this,t=e.config,n=e.elemFile=i(['<input class=\"'+u+'\" type=\"file\" accept=\"'+t.acceptMime+'\" name=\"'+t.field+'\"',t.multiple?\" multiple\":\"\",\">\"].join(\"\")),o=t.elem.next();(o.hasClass(u)||o.hasClass(c))&&o.remove(),a.ie&&a.ie<10&&t.elem.wrap('<div class=\"layui-upload-wrap\"></div>'),e.isFile()?(e.elemFile=t.elem,t.field=t.elem[0].name):t.elem.after(n),a.ie&&a.ie<10&&e.initIE()},p.prototype.initIE=function(){var e=this,t=e.config,n=i('<iframe id=\"'+f+'\" class=\"'+f+'\" name=\"'+f+'\" frameborder=\"0\"></iframe>'),a=i(['<form target=\"'+f+'\" class=\"'+c+'\" method=\"'+t.method,'\" key=\"set-mine\" enctype=\"multipart/form-data\" action=\"'+t.url+'\">',\"</form>\"].join(\"\"));i(\"#\"+f)[0]||i(\"body\").append(n),t.elem.next().hasClass(c)||(e.elemFile.wrap(a),t.elem.next(\".\"+c).append(function(){var e=[];return layui.each(t.data,function(i,t){t=\"function\"==typeof t?t():t,e.push('<input type=\"hidden\" name=\"'+i+'\" value=\"'+t+'\">')}),e.join(\"\")}()))},p.prototype.msg=function(e){return t.msg(e,{icon:2,shift:6})},p.prototype.isFile=function(){var e=this.config.elem[0];if(e)return\"input\"===e.tagName.toLocaleLowerCase()&&\"file\"===e.type},p.prototype.preview=function(e){var i=this;window.FileReader&&layui.each(i.chooseFiles,function(i,t){var n=new FileReader;n.readAsDataURL(t),n.onload=function(){e&&e(i,t,this.result)}})},p.prototype.upload=function(e,t){var n,o=this,l=o.config,r=o.elemFile[0],u=function(){var t=0,n=0,a=e||o.files||o.chooseFiles||r.files,u=function(){l.multiple&&t+n===o.fileLength&&\"function\"==typeof l.allDone&&l.allDone({total:o.fileLength,successful:t,aborted:n})};layui.each(a,function(e,a){var r=new FormData;r.append(l.field,a),layui.each(l.data,function(e,i){i=\"function\"==typeof i?i():i,r.append(e,i)}),i.ajax({url:l.url,type:l.method,data:r,contentType:!1,processData:!1,dataType:\"json\",headers:l.headers||{},success:function(i){t++,d(e,i),u()},error:function(){n++,o.msg(\"请求上传接口出现异常\"),m(e),u()}})})},c=function(){var e=i(\"#\"+f);o.elemFile.parent().submit(),clearInterval(p.timer),p.timer=setInterval(function(){var i,t=e.contents().find(\"body\");try{i=t.text()}catch(n){o.msg(\"获取上传后的响应信息出现异常\"),clearInterval(p.timer),m()}i&&(clearInterval(p.timer),t.html(\"\"),d(0,i))},30)},d=function(e,i){if(o.elemFile.next(\".\"+s).remove(),r.value=\"\",\"object\"!=typeof i)try{i=JSON.parse(i)}catch(t){return i={},o.msg(\"请对上传接口返回有效JSON\")}\"function\"==typeof l.done&&l.done(i,e||0,function(e){o.upload(e)})},m=function(e){l.auto&&(r.value=\"\"),\"function\"==typeof l.error&&l.error(e||0,function(e){o.upload(e)})},h=l.exts,v=function(){var i=[];return layui.each(e||o.chooseFiles,function(e,t){i.push(t.name)}),i}(),g={preview:function(e){o.preview(e)},upload:function(e,i){var t={};t[e]=i,o.upload(t)},pushFile:function(){return o.files=o.files||{},layui.each(o.chooseFiles,function(e,i){o.files[e]=i}),o.files},resetFile:function(e,i,t){var n=new File([i],t);o.files=o.files||{},o.files[e]=n}},y=function(){if(\"choose\"!==t&&!l.auto||(l.choose&&l.choose(g),\"choose\"!==t))return l.before&&l.before(g),a.ie?a.ie>9?u():c():void u()};if(v=0===v.length?r.value.match(/[^\\/\\\\]+\\..+/g)||[]||\"\":v,0!==v.length){switch(l.accept){case\"file\":if(h&&!RegExp(\"\\\\w\\\\.(\"+h+\")$\",\"i\").test(escape(v)))return o.msg(\"选择的文件中包含不支持的格式\"),r.value=\"\";break;case\"video\":if(!RegExp(\"\\\\w\\\\.(\"+(h||\"avi|mp4|wma|rmvb|rm|flash|3gp|flv\")+\")$\",\"i\").test(escape(v)))return o.msg(\"选择的视频中包含不支持的格式\"),r.value=\"\";break;case\"audio\":if(!RegExp(\"\\\\w\\\\.(\"+(h||\"mp3|wav|mid\")+\")$\",\"i\").test(escape(v)))return o.msg(\"选择的音频中包含不支持的格式\"),r.value=\"\";break;default:if(layui.each(v,function(e,i){RegExp(\"\\\\w\\\\.(\"+(h||\"jpg|png|gif|bmp|jpeg$\")+\")\",\"i\").test(escape(i))||(n=!0)}),n)return o.msg(\"选择的图片中包含不支持的格式\"),r.value=\"\"}if(o.fileLength=function(){var i=0,t=e||o.files||o.chooseFiles||r.files;return layui.each(t,function(){i++}),i}(),l.number&&o.fileLength>l.number)return o.msg(\"同时最多只能上传的数量为：\"+l.number);if(l.size>0&&!(a.ie&&a.ie<10)){var F;if(layui.each(o.chooseFiles,function(e,i){if(i.size>1024*l.size){var t=l.size/1024;t=t>=1?t.toFixed(2)+\"MB\":l.size+\"KB\",r.value=\"\",F=t}}),F)return o.msg(\"文件不能超过\"+F)}y()}},p.prototype.events=function(){var e=this,t=e.config,o=function(i){e.chooseFiles={},layui.each(i,function(i,t){var n=(new Date).getTime();e.chooseFiles[n+\"-\"+i]=t})},l=function(i,n){var a=e.elemFile,o=i.length>1?i.length+\"个文件\":(i[0]||{}).name||a[0].value.match(/[^\\/\\\\]+\\..+/g)||[]||\"\";a.next().hasClass(s)&&a.next().remove(),e.upload(null,\"choose\"),e.isFile()||t.choose||a.after('<span class=\"layui-inline '+s+'\">'+o+\"</span>\")};t.elem.off(\"upload.start\").on(\"upload.start\",function(){var a=i(this),o=a.attr(\"lay-data\");if(o)try{o=new Function(\"return \"+o)(),e.config=i.extend({},t,o)}catch(l){n.error(\"Upload element property lay-data configuration item has a syntax error: \"+o)}e.config.item=a,e.elemFile[0].click()}),a.ie&&a.ie<10||t.elem.off(\"upload.over\").on(\"upload.over\",function(){var e=i(this);e.attr(\"lay-over\",\"\")}).off(\"upload.leave\").on(\"upload.leave\",function(){var e=i(this);e.removeAttr(\"lay-over\")}).off(\"upload.drop\").on(\"upload.drop\",function(n,a){var r=i(this),u=a.originalEvent.dataTransfer.files||[];r.removeAttr(\"lay-over\"),o(u),t.auto?e.upload(u):l(u)}),e.elemFile.off(\"upload.change\").on(\"upload.change\",function(){var i=this.files||[];o(i),t.auto?e.upload():l(i)}),t.bindAction.off(\"upload.action\").on(\"upload.action\",function(){e.upload()}),t.elem.data(\"haveEvents\")||(e.elemFile.on(\"change\",function(){i(this).trigger(\"upload.change\")}),t.elem.on(\"click\",function(){e.isFile()||i(this).trigger(\"upload.start\")}),t.drag&&t.elem.on(\"dragover\",function(e){e.preventDefault(),i(this).trigger(\"upload.over\")}).on(\"dragleave\",function(e){i(this).trigger(\"upload.leave\")}).on(\"drop\",function(e){e.preventDefault(),i(this).trigger(\"upload.drop\",e)}),t.bindAction.on(\"click\",function(){i(this).trigger(\"upload.action\")}),t.elem.data(\"haveEvents\",!0))},o.render=function(e){var i=new p(e);return l.call(i)},e(r,o)});layui.define(\"layer\",function(e){\"use strict\";var i=layui.$,t=layui.layer,a=layui.hint(),n=layui.device(),l=\"form\",r=\".layui-form\",s=\"layui-this\",o=\"layui-hide\",c=\"layui-disabled\",u=function(){this.config={verify:{required:[/[\\S]+/,\"必填项不能为空\"],phone:[/^1\\d{10}$/,\"请输入正确的手机号\"],email:[/^([a-zA-Z0-9_\\.\\-])+\\@(([a-zA-Z0-9\\-])+\\.)+([a-zA-Z0-9]{2,4})+$/,\"邮箱格式不正确\"],url:[/(^#)|(^http(s*):\\/\\/[^\\s]+\\.[^\\s]+)/,\"链接格式不正确\"],number:function(e){if(!e||isNaN(e))return\"只能填写数字\"},date:[/^(\\d{4})[-\\/](\\d{1}|0\\d{1}|1[0-2])([-\\/](\\d{1}|0\\d{1}|[1-2][0-9]|3[0-1]))*$/,\"日期格式不正确\"],identity:[/(^\\d{15}$)|(^\\d{17}(x|X|\\d)$)/,\"请输入正确的身份证号\"]}}};u.prototype.set=function(e){var t=this;return i.extend(!0,t.config,e),t},u.prototype.verify=function(e){var t=this;return i.extend(!0,t.config.verify,e),t},u.prototype.on=function(e,i){return layui.onevent.call(this,l,e,i)},u.prototype.val=function(e,t){var a=i(r+'[lay-filter=\"'+e+'\"]');a.each(function(e,a){var n=i(this);layui.each(t,function(e,i){var t,a=n.find('[name=\"'+e+'\"]');a[0]&&(t=a[0].type,\"checkbox\"===t?a[0].checked=i:\"radio\"===t?a.each(function(){this.value===i&&(this.checked=!0)}):a.val(i))})}),f.render(null,e)},u.prototype.render=function(e,t){var n=this,u=i(r+function(){return t?'[lay-filter=\"'+t+'\"]':\"\"}()),d={select:function(){var e,t=\"请选择\",a=\"layui-form-select\",n=\"layui-select-title\",r=\"layui-select-none\",d=\"\",f=u.find(\"select\"),v=function(t,l){i(t.target).parent().hasClass(n)&&!l||(i(\".\"+a).removeClass(a+\"ed \"+a+\"up\"),e&&d&&e.val(d)),e=null},y=function(t,u,f){var y,p=i(this),m=t.find(\".\"+n),k=m.find(\"input\"),g=t.find(\"dl\"),x=g.children(\"dd\"),b=this.selectedIndex;if(!u){var C=function(){var e=t.offset().top+t.outerHeight()+5-h.scrollTop(),i=g.outerHeight();b=p[0].selectedIndex,t.addClass(a+\"ed\"),x.removeClass(o),y=null,x.eq(b).addClass(s).siblings().removeClass(s),e+i>h.height()&&e>=i&&t.addClass(a+\"up\")},w=function(e){t.removeClass(a+\"ed \"+a+\"up\"),k.blur(),y=null,e||$(k.val(),function(e){e&&(d=g.find(\".\"+s).html(),k&&k.val(d))})};m.on(\"click\",function(e){t.hasClass(a+\"ed\")?w():(v(e,!0),C()),g.find(\".\"+r).remove()}),m.find(\".layui-edge\").on(\"click\",function(){k.focus()}),k.on(\"keyup\",function(e){var i=e.keyCode;9===i&&C()}).on(\"keydown\",function(e){var i=e.keyCode;9===i&&w();var t=function(i,a){var n,l;if(e.preventDefault(),a=function(){return a&&a[0]?a:y&&y[0]?y:x.eq(b)}(),l=a[i](),n=a[i](\"dd\"),l[0]){if(y=a[i](),!n[0]||n.hasClass(c))return t(i,y);n.addClass(s).siblings().removeClass(s);var r=g.children(\"dd.layui-this\"),o=r.position().top,u=g.height(),d=r.height();o>u&&g.scrollTop(o+g.scrollTop()-u+d-5),o<0&&g.scrollTop(o+g.scrollTop())}};38===i&&t(\"prev\"),40===i&&t(\"next\"),13===i&&(e.preventDefault(),g.children(\"dd.\"+s).trigger(\"click\"))});var $=function(e,t,a){var n=0;layui.each(x,function(){var t=i(this),l=t.text(),r=l.indexOf(e)===-1;(\"\"===e||\"blur\"===a?e!==l:r)&&n++,\"keyup\"===a&&t[r?\"addClass\":\"removeClass\"](o)});var l=n===x.length;return t(l),l},T=function(e){var i=this.value,t=e.keyCode;return 9!==t&&13!==t&&37!==t&&38!==t&&39!==t&&40!==t&&($(i,function(e){e?g.find(\".\"+r)[0]||g.append('<p class=\"'+r+'\">无匹配项</p>'):g.find(\".\"+r).remove()},\"keyup\"),void(\"\"===i&&g.find(\".\"+r).remove()))};f&&k.on(\"keyup\",T).on(\"blur\",function(t){var a=p[0].selectedIndex;e=k,d=i(p[0].options[a]).html(),setTimeout(function(){$(k.val(),function(e){d||k.val(\"\")},\"blur\")},200)}),x.on(\"click\",function(){var e=i(this),a=e.attr(\"lay-value\"),n=p.attr(\"lay-filter\");return!e.hasClass(c)&&(e.hasClass(\"layui-select-tips\")?k.val(\"\"):(k.val(e.text()),e.addClass(s)),e.siblings().removeClass(s),p.val(a).removeClass(\"layui-form-danger\"),layui.event.call(this,l,\"select(\"+n+\")\",{elem:p[0],value:a,othis:t}),w(!0),!1)}),t.find(\"dl>dt\").on(\"click\",function(e){return!1}),i(document).off(\"click\",v).on(\"click\",v)}};f.each(function(e,l){var r=i(this),o=r.next(\".\"+a),u=this.disabled,d=l.value,f=i(l.options[l.selectedIndex]),v=l.options[0];if(\"string\"==typeof r.attr(\"lay-ignore\"))return r.show();var h=\"string\"==typeof r.attr(\"lay-search\"),p=v?v.value?t:v.innerHTML||t:t,m=i(['<div class=\"'+(h?\"\":\"layui-unselect \")+a,(u?\" layui-select-disabled\":\"\")+'\">','<div class=\"'+n+'\">','<input type=\"text\" placeholder=\"'+p+'\" '+('value=\"'+(d?f.html():\"\")+'\"')+(h?\"\":\" readonly\")+' class=\"layui-input'+(h?\"\":\" layui-unselect\")+(u?\" \"+c:\"\")+'\">','<i class=\"layui-edge\"></i></div>','<dl class=\"layui-anim layui-anim-upbit'+(r.find(\"optgroup\")[0]?\" layui-select-group\":\"\")+'\">',function(e){var i=[];return layui.each(e,function(e,a){0!==e||a.value?\"optgroup\"===a.tagName.toLowerCase()?i.push(\"<dt>\"+a.label+\"</dt>\"):i.push('<dd lay-value=\"'+a.value+'\" class=\"'+(d===a.value?s:\"\")+(a.disabled?\" \"+c:\"\")+'\">'+a.innerHTML+\"</dd>\"):i.push('<dd lay-value=\"\" class=\"layui-select-tips\">'+(a.innerHTML||t)+\"</dd>\")}),0===i.length&&i.push('<dd lay-value=\"\" class=\"'+c+'\">没有选项</dd>'),i.join(\"\")}(r.find(\"*\"))+\"</dl>\",\"</div>\"].join(\"\"));o[0]&&o.remove(),r.after(m),y.call(this,m,u,h)})},checkbox:function(){var e={checkbox:[\"layui-form-checkbox\",\"layui-form-checked\",\"checkbox\"],_switch:[\"layui-form-switch\",\"layui-form-onswitch\",\"switch\"]},t=u.find(\"input[type=checkbox]\"),a=function(e,t){var a=i(this);e.on(\"click\",function(){var i=a.attr(\"lay-filter\"),n=(a.attr(\"lay-text\")||\"\").split(\"|\");a[0].disabled||(a[0].checked?(a[0].checked=!1,e.removeClass(t[1]).find(\"em\").text(n[1])):(a[0].checked=!0,e.addClass(t[1]).find(\"em\").text(n[0])),layui.event.call(a[0],l,t[2]+\"(\"+i+\")\",{elem:a[0],value:a[0].value,othis:e}))})};t.each(function(t,n){var l=i(this),r=l.attr(\"lay-skin\"),s=(l.attr(\"lay-text\")||\"\").split(\"|\"),o=this.disabled;\"switch\"===r&&(r=\"_\"+r);var u=e[r]||e.checkbox;if(\"string\"==typeof l.attr(\"lay-ignore\"))return l.show();var d=l.next(\".\"+u[0]),f=i(['<div class=\"layui-unselect '+u[0],n.checked?\" \"+u[1]:\"\",o?\" layui-checkbox-disbaled \"+c:\"\",'\"',r?' lay-skin=\"'+r+'\"':\"\",\">\",function(){var e=n.title.replace(/\\s/g,\"\"),i={checkbox:[e?\"<span>\"+n.title+\"</span>\":\"\",'<i class=\"layui-icon layui-icon-ok\"></i>'].join(\"\"),_switch:\"<em>\"+((n.checked?s[0]:s[1])||\"\")+\"</em><i></i>\"};return i[r]||i.checkbox}(),\"</div>\"].join(\"\"));d[0]&&d.remove(),l.after(f),a.call(this,f,u)})},radio:function(){var e=\"layui-form-radio\",t=[\"&#xe643;\",\"&#xe63f;\"],a=u.find(\"input[type=radio]\"),n=function(a){var n=i(this),s=\"layui-anim-scaleSpring\";a.on(\"click\",function(){var o=n[0].name,c=n.parents(r),u=n.attr(\"lay-filter\"),d=c.find(\"input[name=\"+o.replace(/(\\.|#|\\[|\\])/g,\"\\\\$1\")+\"]\");n[0].disabled||(layui.each(d,function(){var a=i(this).next(\".\"+e);this.checked=!1,a.removeClass(e+\"ed\"),a.find(\".layui-icon\").removeClass(s).html(t[1])}),n[0].checked=!0,a.addClass(e+\"ed\"),a.find(\".layui-icon\").addClass(s).html(t[0]),layui.event.call(n[0],l,\"radio(\"+u+\")\",{elem:n[0],value:n[0].value,othis:a}))})};a.each(function(a,l){var r=i(this),s=r.next(\".\"+e),o=this.disabled;if(\"string\"==typeof r.attr(\"lay-ignore\"))return r.show();s[0]&&s.remove();var u=i(['<div class=\"layui-unselect '+e,l.checked?\" \"+e+\"ed\":\"\",(o?\" layui-radio-disbaled \"+c:\"\")+'\">','<i class=\"layui-anim layui-icon\">'+t[l.checked?0:1]+\"</i>\",\"<div>\"+function(){var e=l.title||\"\";return\"string\"==typeof r.next().attr(\"lay-radio\")&&(e=r.next().html(),r.next().remove()),e}()+\"</div>\",\"</div>\"].join(\"\"));r.after(u),n.call(this,u)})}};return e?d[e]?d[e]():a.error(\"不支持的\"+e+\"表单渲染\"):layui.each(d,function(e,i){i()}),n};var d=function(){var e=i(this),a=f.config.verify,s=null,o=\"layui-form-danger\",c={},u=e.parents(r),d=u.find(\"*[lay-verify]\"),v=e.parents(\"form\")[0],h=u.find(\"input,select,textarea\"),y=e.attr(\"lay-filter\");if(layui.each(d,function(e,l){var r=i(this),c=r.attr(\"lay-verify\").split(\"|\"),u=r.attr(\"lay-verType\"),d=r.val();if(r.removeClass(o),layui.each(c,function(e,i){var c,f=\"\",v=\"function\"==typeof a[i];if(a[i]){var c=v?f=a[i](d,l):!a[i][0].test(d);if(f=f||a[i][1],c)return\"tips\"===u?t.tips(f,function(){return\"string\"==typeof r.attr(\"lay-ignore\")||\"select\"!==l.tagName.toLowerCase()&&!/^checkbox|radio$/.test(l.type)?r:r.next()}(),{tips:1}):\"alert\"===u?t.alert(f,{title:\"提示\",shadeClose:!0}):t.msg(f,{icon:5,shift:6}),n.android||n.ios||l.focus(),r.addClass(o),s=!0}}),s)return s}),s)return!1;var p={};return layui.each(h,function(e,i){if(i.name=(i.name||\"\").replace(/^\\s*|\\s*&/,\"\"),i.name){if(/^.*\\[\\]$/.test(i.name)){var t=i.name.match(/^(.*)\\[\\]$/g)[0];p[t]=0|p[t],i.name=i.name.replace(/^(.*)\\[\\]$/,\"$1[\"+p[t]++ +\"]\")}/^checkbox|radio$/.test(i.type)&&!i.checked||(c[i.name]=i.value)}}),layui.event.call(this,l,\"submit(\"+y+\")\",{elem:this,form:v,field:c})},f=new u,v=i(document),h=i(window);f.render(),v.on(\"reset\",r,function(){var e=i(this).attr(\"lay-filter\");setTimeout(function(){f.render(null,e)},50)}),v.on(\"submit\",r,d).on(\"click\",\"*[lay-submit]\",d),e(l,f)});layui.define(\"jquery\",function(e){\"use strict\";var o=layui.$,a=layui.hint(),i=\"layui-tree-enter\",r=function(e){this.options=e},t={arrow:[\"&#xe623;\",\"&#xe625;\"],checkbox:[\"&#xe626;\",\"&#xe627;\"],radio:[\"&#xe62b;\",\"&#xe62a;\"],branch:[\"&#xe622;\",\"&#xe624;\"],leaf:\"&#xe621;\"};r.prototype.init=function(e){var o=this;e.addClass(\"layui-box layui-tree\"),o.options.skin&&e.addClass(\"layui-tree-skin-\"+o.options.skin),o.tree(e),o.on(e)},r.prototype.tree=function(e,a){var i=this,r=i.options,n=a||r.nodes;layui.each(n,function(a,n){var l=n.children&&n.children.length>0,c=o('<ul class=\"'+(n.spread?\"layui-show\":\"\")+'\"></ul>'),s=o([\"<li \"+(n.spread?'data-spread=\"'+n.spread+'\"':\"\")+\">\",function(){return l?'<i class=\"layui-icon layui-tree-spread\">'+(n.spread?t.arrow[1]:t.arrow[0])+\"</i>\":\"\"}(),function(){return r.check?'<i class=\"layui-icon layui-tree-check\">'+(\"checkbox\"===r.check?t.checkbox[0]:\"radio\"===r.check?t.radio[0]:\"\")+\"</i>\":\"\"}(),function(){return'<a href=\"'+(n.href||\"javascript:;\")+'\" '+(r.target&&n.href?'target=\"'+r.target+'\"':\"\")+\">\"+('<i class=\"layui-icon layui-tree-'+(l?\"branch\":\"leaf\")+'\">'+(l?n.spread?t.branch[1]:t.branch[0]:t.leaf)+\"</i>\")+(\"<cite>\"+(n.name||\"未命名\")+\"</cite></a>\")}(),\"</li>\"].join(\"\"));l&&(s.append(c),i.tree(c,n.children)),e.append(s),\"function\"==typeof r.click&&i.click(s,n),i.spread(s,n),r.drag&&i.drag(s,n)})},r.prototype.click=function(e,o){var a=this,i=a.options;e.children(\"a\").on(\"click\",function(e){layui.stope(e),i.click(o)})},r.prototype.spread=function(e,o){var a=this,i=(a.options,e.children(\".layui-tree-spread\")),r=e.children(\"ul\"),n=e.children(\"a\"),l=function(){e.data(\"spread\")?(e.data(\"spread\",null),r.removeClass(\"layui-show\"),i.html(t.arrow[0]),n.find(\".layui-icon\").html(t.branch[0])):(e.data(\"spread\",!0),r.addClass(\"layui-show\"),i.html(t.arrow[1]),n.find(\".layui-icon\").html(t.branch[1]))};r[0]&&(i.on(\"click\",l),n.on(\"dblclick\",l))},r.prototype.on=function(e){var a=this,r=a.options,t=\"layui-tree-drag\";e.find(\"i\").on(\"selectstart\",function(e){return!1}),r.drag&&o(document).on(\"mousemove\",function(e){var i=a.move;if(i.from){var r=(i.to,o('<div class=\"layui-box '+t+'\"></div>'));e.preventDefault(),o(\".\"+t)[0]||o(\"body\").append(r);var n=o(\".\"+t)[0]?o(\".\"+t):r;n.addClass(\"layui-show\").html(i.from.elem.children(\"a\").html()),n.css({left:e.pageX+10,top:e.pageY+10})}}).on(\"mouseup\",function(){var e=a.move;e.from&&(e.from.elem.children(\"a\").removeClass(i),e.to&&e.to.elem.children(\"a\").removeClass(i),a.move={},o(\".\"+t).remove())})},r.prototype.move={},r.prototype.drag=function(e,a){var r=this,t=(r.options,e.children(\"a\")),n=function(){var t=o(this),n=r.move;n.from&&(n.to={item:a,elem:e},t.addClass(i))};t.on(\"mousedown\",function(){var o=r.move;o.from={item:a,elem:e}}),t.on(\"mouseenter\",n).on(\"mousemove\",n).on(\"mouseleave\",function(){var e=o(this),a=r.move;a.from&&(delete a.to,e.removeClass(i))})},e(\"tree\",function(e){var i=new r(e=e||{}),t=o(e.elem);return t[0]?void i.init(t):a.error(\"layui.tree 没有找到\"+e.elem+\"元素\")})});layui.define([\"laytpl\",\"laypage\",\"layer\",\"form\"],function(e){\"use strict\";var t=layui.$,i=layui.laytpl,a=layui.laypage,l=layui.layer,n=layui.form,o=layui.hint(),r=layui.device(),d={config:{checkName:\"LAY_CHECKED\",indexName:\"LAY_TABLE_INDEX\"},cache:{},index:layui.table?layui.table.index+1e4:0,set:function(e){var i=this;return i.config=t.extend({},i.config,e),i},on:function(e,t){return layui.onevent.call(this,s,e,t)}},c=function(){var e=this,t=e.config,i=t.id;return i&&(c.config[i]=t),{reload:function(t){e.reload.call(e,t)},config:t}},s=\"table\",u=\".layui-table\",h=\"layui-hide\",f=\"layui-none\",y=\"layui-table-view\",p=\".layui-table-header\",m=\".layui-table-body\",v=\".layui-table-main\",g=\".layui-table-fixed\",x=\".layui-table-fixed-l\",b=\".layui-table-fixed-r\",k=\".layui-table-tool\",C=\".layui-table-page\",w=\".layui-table-sort\",N=\"layui-table-edit\",T=\"layui-table-hover\",F=function(e){var t='{{#if(item2.colspan){}} colspan=\"{{item2.colspan}}\"{{#} if(item2.rowspan){}} rowspan=\"{{item2.rowspan}}\"{{#}}}';return e=e||{},['<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" class=\"layui-table\" ','{{# if(d.data.skin){ }}lay-skin=\"{{d.data.skin}}\"{{# } }} {{# if(d.data.size){ }}lay-size=\"{{d.data.size}}\"{{# } }} {{# if(d.data.even){ }}lay-even{{# } }}>',\"<thead>\",\"{{# layui.each(d.data.cols, function(i1, item1){ }}\",\"<tr>\",\"{{# layui.each(item1, function(i2, item2){ }}\",'{{# if(item2.fixed && item2.fixed !== \"right\"){ left = true; } }}','{{# if(item2.fixed === \"right\"){ right = true; } }}',function(){return e.fixed&&\"right\"!==e.fixed?'{{# if(item2.fixed && item2.fixed !== \"right\"){ }}':\"right\"===e.fixed?'{{# if(item2.fixed === \"right\"){ }}':\"\"}(),'<th data-field=\"{{ item2.field||i2 }}\" {{# if(item2.minWidth){ }}data-minwidth=\"{{item2.minWidth}}\"{{# } }} '+t+' {{# if(item2.unresize){ }}data-unresize=\"true\"{{# } }}>','<div class=\"layui-table-cell laytable-cell-',\"{{# if(item2.colspan > 1){ }}\",\"group\",\"{{# } else { }}\",\"{{d.index}}-{{item2.field || i2}}\",'{{# if(item2.type !== \"normal\"){ }}',\" laytable-cell-{{ item2.type }}\",\"{{# } }}\",\"{{# } }}\",'\" {{#if(item2.align){}}align=\"{{item2.align}}\"{{#}}}>','{{# if(item2.type === \"checkbox\"){ }}','<input type=\"checkbox\" name=\"layTableCheckbox\" lay-skin=\"primary\" lay-filter=\"layTableAllChoose\" {{# if(item2[d.data.checkName]){ }}checked{{# }; }}>',\"{{# } else { }}\",'<span>{{item2.title||\"\"}}</span>',\"{{# if(!(item2.colspan > 1) && item2.sort){ }}\",'<span class=\"layui-table-sort layui-inline\"><i class=\"layui-edge layui-table-sort-asc\"></i><i class=\"layui-edge layui-table-sort-desc\"></i></span>',\"{{# } }}\",\"{{# } }}\",\"</div>\",\"</th>\",e.fixed?\"{{# }; }}\":\"\",\"{{# }); }}\",\"</tr>\",\"{{# }); }}\",\"</thead>\",\"</table>\"].join(\"\")},W=['<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" class=\"layui-table\" ','{{# if(d.data.skin){ }}lay-skin=\"{{d.data.skin}}\"{{# } }} {{# if(d.data.size){ }}lay-size=\"{{d.data.size}}\"{{# } }} {{# if(d.data.even){ }}lay-even{{# } }}>',\"<tbody></tbody>\",\"</table>\"].join(\"\"),z=['<div class=\"layui-form layui-border-box {{d.VIEW_CLASS}}\" lay-filter=\"LAY-table-{{d.index}}\" style=\"{{# if(d.data.width){ }}width:{{d.data.width}}px;{{# } }} {{# if(d.data.height){ }}height:{{d.data.height}}px;{{# } }}\">',\"{{# if(d.data.toolbar){ }}\",'<div class=\"layui-table-tool\"></div>',\"{{# } }}\",'<div class=\"layui-table-box\">',\"{{# var left, right; }}\",'<div class=\"layui-table-header\">',F(),\"</div>\",'<div class=\"layui-table-body layui-table-main\">',W,\"</div>\",\"{{# if(left){ }}\",'<div class=\"layui-table-fixed layui-table-fixed-l\">','<div class=\"layui-table-header\">',F({fixed:!0}),\"</div>\",'<div class=\"layui-table-body\">',W,\"</div>\",\"</div>\",\"{{# }; }}\",\"{{# if(right){ }}\",'<div class=\"layui-table-fixed layui-table-fixed-r\">','<div class=\"layui-table-header\">',F({fixed:\"right\"}),'<div class=\"layui-table-mend\"></div>',\"</div>\",'<div class=\"layui-table-body\">',W,\"</div>\",\"</div>\",\"{{# }; }}\",\"</div>\",\"{{# if(d.data.page){ }}\",'<div class=\"layui-table-page\">','<div id=\"layui-table-page{{d.index}}\"></div>',\"</div>\",\"{{# } }}\",\"<style>\",\"{{# layui.each(d.data.cols, function(i1, item1){\",\"layui.each(item1, function(i2, item2){ }}\",\".laytable-cell-{{d.index}}-{{item2.field||i2}}{ \",\"{{# if(item2.width){ }}\",\"width: {{item2.width}}px;\",\"{{# } }}\",\" }\",\"{{# });\",\"}); }}\",\"</style>\",\"</div>\"].join(\"\"),A=t(window),S=t(document),M=function(e){var i=this;i.index=++d.index,i.config=t.extend({},i.config,d.config,e),i.render()};M.prototype.config={limit:10,loading:!0,cellMinWidth:60,text:{none:\"无数据\"}},M.prototype.render=function(){var e=this,a=e.config;if(a.elem=t(a.elem),a.where=a.where||{},a.id=a.id||a.elem.attr(\"id\"),a.request=t.extend({pageName:\"page\",limitName:\"limit\"},a.request),a.response=t.extend({statusName:\"code\",statusCode:0,msgName:\"msg\",dataName:\"data\",countName:\"count\"},a.response),\"object\"==typeof a.page&&(a.limit=a.page.limit||a.limit,a.limits=a.page.limits||a.limits,e.page=a.page.curr=a.page.curr||1,delete a.page.elem,delete a.page.jump),!a.elem[0])return e;e.setArea();var l=a.elem,n=l.next(\".\"+y),o=e.elem=t(i(z).render({VIEW_CLASS:y,data:a,index:e.index}));if(a.index=e.index,n[0]&&n.remove(),l.after(o),e.layHeader=o.find(p),e.layMain=o.find(v),e.layBody=o.find(m),e.layFixed=o.find(g),e.layFixLeft=o.find(x),e.layFixRight=o.find(b),e.layTool=o.find(k),e.layPage=o.find(C),e.layTool.html(i(t(a.toolbar).html()||\"\").render(a)),a.height&&e.fullSize(),a.cols.length>1){var r=e.layFixed.find(p).find(\"th\");r.height(e.layHeader.height()-1-parseFloat(r.css(\"padding-top\"))-parseFloat(r.css(\"padding-bottom\")))}e.pullData(e.page),e.events()},M.prototype.initOpts=function(e){var t=this,i=(t.config,{checkbox:48,space:15,numbers:40});e.checkbox&&(e.type=\"checkbox\"),e.space&&(e.type=\"space\"),e.type||(e.type=\"normal\"),\"normal\"!==e.type&&(e.unresize=!0,e.width=e.width||i[e.type])},M.prototype.setArea=function(){var e=this,t=e.config,i=0,a=0,l=0,n=0,o=t.width||function(){var e=function(i){var a,l;i=i||t.elem.parent(),a=i.width();try{l=\"none\"===i.css(\"display\")}catch(n){}return!i[0]||a&&!l?a:e(i.parent())};return e()}();e.eachCols(function(){i++}),o-=function(){return\"line\"===t.skin||\"nob\"===t.skin?2:i+1}(),layui.each(t.cols,function(t,i){layui.each(i,function(t,l){var r;return l?(e.initOpts(l),r=l.width||0,void(l.colspan>1||(/\\d+%$/.test(r)?l.width=r=Math.floor(parseFloat(r)/100*o):r||(l.width=r=0,a++),n+=r))):void i.splice(t,1)})}),e.autoColNums=a,o>n&&a&&(l=(o-n)/a),layui.each(t.cols,function(e,i){layui.each(i,function(e,i){var a=i.minWidth||t.cellMinWidth;i.colspan>1||0===i.width&&(i.width=Math.floor(l>=a?l:a))})}),t.height&&/^full-\\d+$/.test(t.height)&&(e.fullHeightGap=t.height.split(\"-\")[1],t.height=A.height()-e.fullHeightGap)},M.prototype.reload=function(e){var i=this;i.config.data&&i.config.data.constructor===Array&&delete i.config.data,i.config=t.extend({},i.config,e),i.render()},M.prototype.page=1,M.prototype.pullData=function(e,i){var a=this,n=a.config,o=n.request,r=n.response,d=function(){\"object\"==typeof n.initSort&&a.sort(n.initSort.field,n.initSort.type)};if(a.startTime=(new Date).getTime(),n.url){var c={};c[o.pageName]=e,c[o.limitName]=n.limit;var s=t.extend(c,n.where);n.contentType&&0==n.contentType.indexOf(\"application/json\")&&(s=JSON.stringify(s)),t.ajax({type:n.method||\"get\",url:n.url,contentType:n.contentType,data:s,dataType:\"json\",headers:n.headers||{},success:function(t){t[r.statusName]!=r.statusCode?(a.renderForm(),a.layMain.html('<div class=\"'+f+'\">'+(t[r.msgName]||\"返回的数据状态异常\")+\"</div>\")):(a.renderData(t,e,t[r.countName]),d(),n.time=(new Date).getTime()-a.startTime+\" ms\"),i&&l.close(i),\"function\"==typeof n.done&&n.done(t,e,t[r.countName])},error:function(e,t){a.layMain.html('<div class=\"'+f+'\">数据接口请求异常</div>'),a.renderForm(),i&&l.close(i)}})}else if(n.data&&n.data.constructor===Array){var u={},h=e*n.limit-n.limit;u[r.dataName]=n.data.concat().splice(h,n.limit),u[r.countName]=n.data.length,a.renderData(u,e,n.data.length),d(),\"function\"==typeof n.done&&n.done(u,e,u[r.countName])}},M.prototype.eachCols=function(e){var i=t.extend(!0,[],this.config.cols),a=[],l=0;layui.each(i,function(e,t){layui.each(t,function(t,n){if(n.colspan>1){var o=0;l++,n.CHILD_COLS=[],layui.each(i[e+1],function(e,t){t.PARENT_COL||o==n.colspan||(t.PARENT_COL=l,n.CHILD_COLS.push(t),o+=t.colspan>1?t.colspan:1)})}n.PARENT_COL||a.push(n)})});var n=function(t){layui.each(t||a,function(t,i){return i.CHILD_COLS?n(i.CHILD_COLS):void e(t,i)})};n()},M.prototype.renderData=function(e,n,o,r){var c=this,s=c.config,u=e[s.response.dataName]||[],y=[],p=[],m=[],v=function(){return!r&&c.sortKey?c.sort(c.sortKey.field,c.sortKey.sort,!0):(layui.each(u,function(e,a){var l=[],o=[],u=[],h=e+s.limit*(n-1)+1;0!==a.length&&(r||(a[d.config.indexName]=e),c.eachCols(function(e,n){var r=n.field||e,f=a[r];c.getColElem(c.layHeader,r);if(void 0!==f&&null!==f||(f=\"\"),!(n.colspan>1)){var y=['<td data-field=\"'+r+'\" '+function(){var e=[];return n.edit&&e.push('data-edit=\"'+n.edit+'\"'),n.align&&e.push('align=\"'+n.align+'\"'),n.templet&&e.push('data-content=\"'+f+'\"'),n.toolbar&&e.push('data-off=\"true\"'),n.event&&e.push('lay-event=\"'+n.event+'\"'),n.style&&e.push('style=\"'+n.style+'\"'),n.minWidth&&e.push('data-minwidth=\"'+n.minWidth+'\"'),e.join(\" \")}()+\">\",'<div class=\"layui-table-cell laytable-cell-'+function(){var e=s.index+\"-\"+r;return\"normal\"===n.type?e:e+\" laytable-cell-\"+n.type}()+'\">'+function(){var e=t.extend(!0,{LAY_INDEX:h},a);return\"checkbox\"===n.type?'<input type=\"checkbox\" name=\"layTableCheckbox\" lay-skin=\"primary\" '+function(){var t=d.config.checkName;return n[t]?(a[t]=n[t],n[t]?\"checked\":\"\"):e[t]?\"checked\":\"\"}()+\">\":\"numbers\"===n.type?h:n.toolbar?i(t(n.toolbar).html()||\"\").render(e):n.templet?function(){return\"function\"==typeof n.templet?n.templet(e):i(t(n.templet).html()||String(f)).render(e)}():f}(),\"</div></td>\"].join(\"\");l.push(y),n.fixed&&\"right\"!==n.fixed&&o.push(y),\"right\"===n.fixed&&u.push(y)}}),y.push('<tr data-index=\"'+e+'\">'+l.join(\"\")+\"</tr>\"),p.push('<tr data-index=\"'+e+'\">'+o.join(\"\")+\"</tr>\"),m.push('<tr data-index=\"'+e+'\">'+u.join(\"\")+\"</tr>\"))}),c.layBody.scrollTop(0),c.layMain.find(\".\"+f).remove(),c.layMain.find(\"tbody\").html(y.join(\"\")),c.layFixLeft.find(\"tbody\").html(p.join(\"\")),c.layFixRight.find(\"tbody\").html(m.join(\"\")),c.renderForm(),c.syncCheckAll(),c.haveInit?c.scrollPatch():setTimeout(function(){c.scrollPatch()},50),c.haveInit=!0,void l.close(c.tipsIndex))};return c.key=s.id||s.index,d.cache[c.key]=u,c.layPage[0===u.length&&1==n?\"addClass\":\"removeClass\"](h),r?v():0===u.length?(c.renderForm(),c.layFixed.remove(),c.layMain.find(\"tbody\").html(\"\"),c.layMain.find(\".\"+f).remove(),c.layMain.append('<div class=\"'+f+'\">'+s.text.none+\"</div>\")):(v(),void(s.page&&(s.page=t.extend({elem:\"layui-table-page\"+s.index,count:o,limit:s.limit,limits:s.limits||[10,20,30,40,50,60,70,80,90],groups:3,layout:[\"prev\",\"page\",\"next\",\"skip\",\"count\",\"limit\"],prev:'<i class=\"layui-icon\">&#xe603;</i>',next:'<i class=\"layui-icon\">&#xe602;</i>',jump:function(e,t){t||(c.page=e.curr,s.limit=e.limit,c.pullData(e.curr,c.loading()))}},s.page),s.page.count=o,a.render(s.page))))},M.prototype.getColElem=function(e,t){var i=this,a=i.config;return e.eq(0).find(\".laytable-cell-\"+(a.index+\"-\"+t)+\":eq(0)\")},M.prototype.renderForm=function(e){n.render(e,\"LAY-table-\"+this.index)},M.prototype.sort=function(e,i,a,l){var n,r,c=this,u={},h=c.config,f=h.elem.attr(\"lay-filter\"),y=d.cache[c.key];\"string\"==typeof e&&c.layHeader.find(\"th\").each(function(i,a){var l=t(this),o=l.data(\"field\");if(o===e)return e=l,n=o,!1});try{var n=n||e.data(\"field\");if(c.sortKey&&!a&&n===c.sortKey.field&&i===c.sortKey.sort)return;var p=c.layHeader.find(\"th .laytable-cell-\"+h.index+\"-\"+n).find(w);c.layHeader.find(\"th\").find(w).removeAttr(\"lay-sort\"),p.attr(\"lay-sort\",i||null),c.layFixed.find(\"th\")}catch(m){return o.error(\"Table modules: Did not match to field\")}c.sortKey={field:n,sort:i},\"asc\"===i?r=layui.sort(y,n):\"desc\"===i?r=layui.sort(y,n,!0):(r=layui.sort(y,d.config.indexName),delete c.sortKey),u[h.response.dataName]=r,c.renderData(u,c.page,c.count,!0),l&&layui.event.call(e,s,\"sort(\"+f+\")\",{field:n,type:i})},M.prototype.loading=function(){var e=this,t=e.config;if(t.loading&&t.url)return l.msg(\"数据请求中\",{icon:16,offset:[e.elem.offset().top+e.elem.height()/2-35-A.scrollTop()+\"px\",e.elem.offset().left+e.elem.width()/2-90-A.scrollLeft()+\"px\"],time:-1,anim:-1,fixed:!1})},M.prototype.setCheckData=function(e,t){var i=this,a=i.config,l=d.cache[i.key];l[e]&&l[e].constructor!==Array&&(l[e][a.checkName]=t)},M.prototype.syncCheckAll=function(){var e=this,t=e.config,i=e.layHeader.find('input[name=\"layTableCheckbox\"]'),a=function(i){return e.eachCols(function(e,a){\"checkbox\"===a.type&&(a[t.checkName]=i)}),i};i[0]&&(d.checkStatus(e.key).isAll?(i[0].checked||(i.prop(\"checked\",!0),e.renderForm(\"checkbox\")),a(!0)):(i[0].checked&&(i.prop(\"checked\",!1),e.renderForm(\"checkbox\")),a(!1)))},M.prototype.getCssRule=function(e,t){var i=this,a=i.elem.find(\"style\")[0],l=a.sheet||a.styleSheet||{},n=l.cssRules||l.rules;layui.each(n,function(a,l){if(l.selectorText===\".laytable-cell-\"+i.index+\"-\"+e)return t(l),!0})},M.prototype.fullSize=function(){var e,t=this,i=t.config,a=i.height;t.fullHeightGap&&(a=A.height()-t.fullHeightGap,a<135&&(a=135),t.elem.css(\"height\",a)),e=parseFloat(a)-parseFloat(t.layHeader.height())-1,i.toolbar&&(e-=t.layTool.outerHeight()),i.page&&(e=e-t.layPage.outerHeight()-1),t.layMain.css(\"height\",e)},M.prototype.getScrollWidth=function(e){var t=0;return e?t=e.offsetWidth-e.clientWidth:(e=document.createElement(\"div\"),e.style.width=\"100px\",e.style.height=\"100px\",e.style.overflowY=\"scroll\",document.body.appendChild(e),t=e.offsetWidth-e.clientWidth,document.body.removeChild(e)),t},M.prototype.scrollPatch=function(){var e=this,i=e.layMain.children(\"table\"),a=e.layMain.width()-e.layMain.prop(\"clientWidth\"),l=e.layMain.height()-e.layMain.prop(\"clientHeight\"),n=e.getScrollWidth(e.layMain[0]),o=i.outerWidth()-e.layMain.width();if(e.autoColNums&&o<5&&!e.scrollPatchWStatus){var r=e.layHeader.eq(0).find(\"thead th:last-child\"),d=r.data(\"field\");e.getCssRule(d,function(t){var i=t.style.width||r.outerWidth();t.style.width=parseFloat(i)-n-o+\"px\",e.layMain.height()-e.layMain.prop(\"clientHeight\")>0&&(t.style.width=parseFloat(t.style.width)-1+\"px\"),e.scrollPatchWStatus=!0})}if(a&&l){if(!e.elem.find(\".layui-table-patch\")[0]){var c=t('<th class=\"layui-table-patch\"><div class=\"layui-table-cell\"></div></th>');c.find(\"div\").css({width:a}),e.layHeader.eq(0).find(\"thead tr\").append(c)}}else e.layHeader.eq(0).find(\".layui-table-patch\").remove();var s=e.layMain.height(),u=s-l;e.layFixed.find(m).css(\"height\",i.height()>u?u:\"auto\"),e.layFixRight[o>0?\"removeClass\":\"addClass\"](h),e.layFixRight.css(\"right\",a-1)},M.prototype.events=function(){var e,a=this,n=a.config,o=t(\"body\"),c={},u=a.layHeader.find(\"th\"),h=\".layui-table-cell\",f=n.elem.attr(\"lay-filter\");u.on(\"mousemove\",function(e){var i=t(this),a=i.offset().left,l=e.clientX-a;i.attr(\"colspan\")>1||i.data(\"unresize\")||c.resizeStart||(c.allowResize=i.width()-l<=10,o.css(\"cursor\",c.allowResize?\"col-resize\":\"\"))}).on(\"mouseleave\",function(){t(this);c.resizeStart||o.css(\"cursor\",\"\")}).on(\"mousedown\",function(e){var i=t(this);if(c.allowResize){var l=i.data(\"field\");e.preventDefault(),c.resizeStart=!0,c.offset=[e.clientX,e.clientY],a.getCssRule(l,function(e){var t=e.style.width||i.outerWidth();c.rule=e,c.ruleWidth=parseFloat(t),c.minWidth=i.data(\"minwidth\")||n.cellMinWidth})}}),S.on(\"mousemove\",function(t){if(c.resizeStart){if(t.preventDefault(),c.rule){var i=c.ruleWidth+t.clientX-c.offset[0];i<c.minWidth&&(i=c.minWidth),c.rule.style.width=i+\"px\",l.close(a.tipsIndex)}e=1}}).on(\"mouseup\",function(t){c.resizeStart&&(c={},o.css(\"cursor\",\"\"),a.scrollPatch()),2===e&&(e=null)}),u.on(\"click\",function(){var i,l=t(this),n=l.find(w),o=n.attr(\"lay-sort\");return n[0]&&1!==e?(i=\"asc\"===o?\"desc\":\"desc\"===o?null:\"asc\",void a.sort(l,i,null,!0)):e=2}).find(w+\" .layui-edge \").on(\"click\",function(e){var i=t(this),l=i.index(),n=i.parents(\"th\").eq(0).data(\"field\");layui.stope(e),0===l?a.sort(n,\"asc\",null,!0):a.sort(n,\"desc\",null,!0)}),a.elem.on(\"click\",'input[name=\"layTableCheckbox\"]+',function(){var e=t(this).prev(),i=a.layBody.find('input[name=\"layTableCheckbox\"]'),l=e.parents(\"tr\").eq(0).data(\"index\"),n=e[0].checked,o=\"layTableAllChoose\"===e.attr(\"lay-filter\");o?(i.each(function(e,t){t.checked=n,a.setCheckData(e,n)}),a.syncCheckAll(),a.renderForm(\"checkbox\")):(a.setCheckData(l,n),a.syncCheckAll()),layui.event.call(this,s,\"checkbox(\"+f+\")\",{checked:n,data:d.cache[a.key]?d.cache[a.key][l]||{}:{},type:o?\"all\":\"one\"})}),a.layBody.on(\"mouseenter\",\"tr\",function(){var e=t(this),i=e.index();a.layBody.find(\"tr:eq(\"+i+\")\").addClass(T)}).on(\"mouseleave\",\"tr\",function(){var e=t(this),i=e.index();a.layBody.find(\"tr:eq(\"+i+\")\").removeClass(T)}),a.layBody.on(\"change\",\".\"+N,function(){var e=t(this),i=this.value,l=e.parent().data(\"field\"),n=e.parents(\"tr\").eq(0).data(\"index\"),o=d.cache[a.key][n];o[l]=i,layui.event.call(this,s,\"edit(\"+f+\")\",{value:i,data:o,field:l})}).on(\"blur\",\".\"+N,function(){var e,l=t(this),n=l.parent().data(\"field\"),o=l.parents(\"tr\").eq(0).data(\"index\"),r=d.cache[a.key][o];a.eachCols(function(t,i){i.field==n&&i.templet&&(e=i.templet)}),l.siblings(h).html(e?i(t(e).html()||this.value).render(r):this.value),l.parent().data(\"content\",this.value),l.remove()}),a.layBody.on(\"click\",\"td\",function(){var e=t(this),i=(e.data(\"field\"),e.data(\"edit\")),o=e.children(h);if(l.close(a.tipsIndex),!e.data(\"off\"))if(i)if(\"select\"===i);else{var d=t('<input class=\"layui-input '+N+'\">');d[0].value=e.data(\"content\")||o.text(),e.find(\".\"+N)[0]||e.append(d),d.focus()}else o.find(\".layui-form-switch,.layui-form-checkbox\")[0]||Math.round(o.prop(\"scrollWidth\"))>Math.round(o.outerWidth())&&(a.tipsIndex=l.tips(['<div class=\"layui-table-tips-main\" style=\"margin-top: -'+(o.height()+16)+\"px;\"+function(){return\"sm\"===n.size?\"padding: 4px 15px; font-size: 12px;\":\"lg\"===n.size?\"padding: 14px 15px;\":\"\"}()+'\">',o.html(),\"</div>\",'<i class=\"layui-icon layui-table-tips-c\">&#x1006;</i>'].join(\"\"),o[0],{tips:[3,\"\"],time:-1,anim:-1,maxWidth:r.ios||r.android?300:600,isOutAnim:!1,skin:\"layui-table-tips\",success:function(e,t){e.find(\".layui-table-tips-c\").on(\"click\",function(){l.close(t)})}}))}),a.layBody.on(\"click\",\"*[lay-event]\",function(){var e=t(this),l=e.parents(\"tr\").eq(0).data(\"index\"),n=a.layBody.find('tr[data-index=\"'+l+'\"]'),o=\"layui-table-click\",r=d.cache[a.key][l];layui.event.call(this,s,\"tool(\"+f+\")\",{data:d.clearCacheKey(r),event:e.attr(\"lay-event\"),tr:n,del:function(){d.cache[a.key][l]=[],n.remove(),a.scrollPatch()},update:function(e){e=e||{},layui.each(e,function(e,l){if(e in r){var o,d=n.children('td[data-field=\"'+e+'\"]');r[e]=l,a.eachCols(function(t,i){i.field==e&&i.templet&&(o=i.templet)}),d.children(h).html(o?i(t(o).html()||l).render(r):l),d.data(\"content\",l)}})}}),n.addClass(o).siblings(\"tr\").removeClass(o)}),a.layMain.on(\"scroll\",function(){var e=t(this),i=e.scrollLeft(),n=e.scrollTop();a.layHeader.scrollLeft(i),a.layFixed.find(m).scrollTop(n),l.close(a.tipsIndex)}),A.on(\"resize\",function(){a.fullSize(),a.scrollPatch()})},d.init=function(e,i){i=i||{};var a=this,l=t(e?'table[lay-filter=\"'+e+'\"]':u+\"[lay-data]\"),n=\"Table element property lay-data configuration item has a syntax error: \";return l.each(function(){var a=t(this),l=a.attr(\"lay-data\");try{l=new Function(\"return \"+l)()}catch(r){o.error(n+l)}var c=[],s=t.extend({elem:this,cols:[],data:[],skin:a.attr(\"lay-skin\"),size:a.attr(\"lay-size\"),even:\"string\"==typeof a.attr(\"lay-even\")},d.config,i,l);e&&a.hide(),a.find(\"thead>tr\").each(function(e){s.cols[e]=[],t(this).children().each(function(i){var a=t(this),l=a.attr(\"lay-data\");try{l=new Function(\"return \"+l)()}catch(r){return o.error(n+l)}var d=t.extend({title:a.text(),colspan:a.attr(\"colspan\")||0,rowspan:a.attr(\"rowspan\")||0},l);d.colspan<2&&c.push(d),s.cols[e].push(d)})}),a.find(\"tbody>tr\").each(function(e){var i=t(this),a={};i.children(\"td\").each(function(e,i){var l=t(this),n=l.data(\"field\");if(n)return a[n]=l.html()}),layui.each(c,function(e,t){var l=i.children(\"td\").eq(e);a[t.field]=l.html()}),s.data[e]=a}),d.render(s)}),a},d.checkStatus=function(e){var t=0,i=0,a=[],l=d.cache[e]||[];return layui.each(l,function(e,l){return l.constructor===Array?void i++:void(l[d.config.checkName]&&(t++,a.push(d.clearCacheKey(l))))}),{data:a,isAll:!!l.length&&t===l.length-i}},c.config={},d.reload=function(e,i){var a=c.config[e];return i=i||{},a?(i.data&&i.data.constructor===Array&&delete a.data,d.render(t.extend(!0,{},a,i))):o.error(\"The ID option was not found in the table instance\")},d.render=function(e){var t=new M(e);return c.call(t)},d.clearCacheKey=function(e){return e=t.extend({},e),delete e[d.config.checkName],delete e[d.config.indexName],e},d.init(),e(s,d)});layui.define(\"jquery\",function(e){\"use strict\";var i=layui.$,n=(layui.hint(),layui.device(),{config:{},set:function(e){var n=this;return n.config=i.extend({},n.config,e),n},on:function(e,i){return layui.onevent.call(this,t,e,i)}}),t=\"carousel\",a=\"layui-this\",l=\">*[carousel-item]>*\",o=\"layui-carousel-left\",r=\"layui-carousel-right\",d=\"layui-carousel-prev\",s=\"layui-carousel-next\",u=\"layui-carousel-arrow\",c=\"layui-carousel-ind\",m=function(e){var t=this;t.config=i.extend({},t.config,n.config,e),t.render()};m.prototype.config={width:\"600px\",height:\"280px\",full:!1,arrow:\"hover\",indicator:\"inside\",autoplay:!0,interval:3e3,anim:\"\",trigger:\"click\",index:0},m.prototype.render=function(){var e=this,n=e.config;n.elem=i(n.elem),n.elem[0]&&(e.elemItem=n.elem.find(l),n.index<0&&(n.index=0),n.index>=e.elemItem.length&&(n.index=e.elemItem.length-1),n.interval<800&&(n.interval=800),n.full?n.elem.css({position:\"fixed\",width:\"100%\",height:\"100%\",zIndex:9999}):n.elem.css({width:n.width,height:n.height}),n.elem.attr(\"lay-anim\",n.anim),e.elemItem.eq(n.index).addClass(a),e.elemItem.length<=1||(e.indicator(),e.arrow(),e.autoplay(),e.events()))},m.prototype.reload=function(e){var n=this;clearInterval(n.timer),n.config=i.extend({},n.config,e),n.render()},m.prototype.prevIndex=function(){var e=this,i=e.config,n=i.index-1;return n<0&&(n=e.elemItem.length-1),n},m.prototype.nextIndex=function(){var e=this,i=e.config,n=i.index+1;return n>=e.elemItem.length&&(n=0),n},m.prototype.addIndex=function(e){var i=this,n=i.config;e=e||1,n.index=n.index+e,n.index>=i.elemItem.length&&(n.index=0)},m.prototype.subIndex=function(e){var i=this,n=i.config;e=e||1,n.index=n.index-e,n.index<0&&(n.index=i.elemItem.length-1)},m.prototype.autoplay=function(){var e=this,i=e.config;i.autoplay&&(e.timer=setInterval(function(){e.slide()},i.interval))},m.prototype.arrow=function(){var e=this,n=e.config,t=i(['<button class=\"layui-icon '+u+'\" lay-type=\"sub\">'+(\"updown\"===n.anim?\"&#xe619;\":\"&#xe603;\")+\"</button>\",'<button class=\"layui-icon '+u+'\" lay-type=\"add\">'+(\"updown\"===n.anim?\"&#xe61a;\":\"&#xe602;\")+\"</button>\"].join(\"\"));n.elem.attr(\"lay-arrow\",n.arrow),n.elem.find(\".\"+u)[0]&&n.elem.find(\".\"+u).remove(),n.elem.append(t),t.on(\"click\",function(){var n=i(this),t=n.attr(\"lay-type\");e.slide(t)})},m.prototype.indicator=function(){var e=this,n=e.config,t=e.elemInd=i(['<div class=\"'+c+'\"><ul>',function(){var i=[];return layui.each(e.elemItem,function(e){i.push(\"<li\"+(n.index===e?' class=\"layui-this\"':\"\")+\"></li>\")}),i.join(\"\")}(),\"</ul></div>\"].join(\"\"));n.elem.attr(\"lay-indicator\",n.indicator),n.elem.find(\".\"+c)[0]&&n.elem.find(\".\"+c).remove(),n.elem.append(t),\"updown\"===n.anim&&t.css(\"margin-top\",-(t.height()/2)),t.find(\"li\").on(\"hover\"===n.trigger?\"mouseover\":n.trigger,function(){var t=i(this),a=t.index();a>n.index?e.slide(\"add\",a-n.index):a<n.index&&e.slide(\"sub\",n.index-a)})},m.prototype.slide=function(e,i){var n=this,l=n.elemItem,u=n.config,c=u.index,m=u.elem.attr(\"lay-filter\");n.haveSlide||(\"sub\"===e?(n.subIndex(i),l.eq(u.index).addClass(d),setTimeout(function(){l.eq(c).addClass(r),l.eq(u.index).addClass(r)},50)):(n.addIndex(i),l.eq(u.index).addClass(s),setTimeout(function(){l.eq(c).addClass(o),l.eq(u.index).addClass(o)},50)),setTimeout(function(){l.removeClass(a+\" \"+d+\" \"+s+\" \"+o+\" \"+r),l.eq(u.index).addClass(a),n.haveSlide=!1},300),n.elemInd.find(\"li\").eq(u.index).addClass(a).siblings().removeClass(a),n.haveSlide=!0,layui.event.call(this,t,\"change(\"+m+\")\",{index:u.index,prevIndex:c,item:l.eq(u.index)}))},m.prototype.events=function(){var e=this,i=e.config;i.elem.data(\"haveEvents\")||(i.elem.on(\"mouseenter\",function(){clearInterval(e.timer)}).on(\"mouseleave\",function(){e.autoplay()}),i.elem.data(\"haveEvents\",!0))},n.render=function(e){var i=new m(e);return i},e(t,n)});layui.define(\"jquery\",function(e){\"use strict\";var a=layui.jquery,i={config:{},index:layui.rate?layui.rate.index+1e4:0,set:function(e){var i=this;return i.config=a.extend({},i.config,e),i},on:function(e,a){return layui.onevent.call(this,n,e,a)}},l=function(){var e=this,a=e.config;return{setvalue:function(a){e.setvalue.call(e,a)},config:a}},n=\"rate\",t=\"layui-rate\",o=\"layui-icon-rate\",s=\"layui-icon-rate-solid\",u=\"layui-icon-rate-half\",r=\"layui-icon-rate-solid layui-icon-rate-half\",c=\"layui-icon-rate-solid layui-icon-rate\",f=\"layui-icon-rate layui-icon-rate-half\",v=function(e){var l=this;l.index=++i.index,l.config=a.extend({},l.config,i.config,e),l.render()};v.prototype.config={length:5,text:!1,readonly:!1,half:!1,value:0,theme:\"\"},v.prototype.render=function(){var e=this,i=e.config,l=i.theme?'style=\"color: '+i.theme+';\"':\"\";i.elem=a(i.elem),parseInt(i.value)!==i.value&&(i.half||(i.value=Math.ceil(i.value)-i.value<.5?Math.ceil(i.value):Math.floor(i.value)));for(var n='<ul class=\"layui-rate\" '+(i.readonly?\"readonly\":\"\")+\">\",u=1;u<=i.length;u++){var r='<li class=\"layui-inline\"><i class=\"layui-icon '+(u>Math.floor(i.value)?o:s)+'\" '+l+\"></i></li>\";i.half&&parseInt(i.value)!==i.value&&u==Math.ceil(i.value)?n=n+'<li><i class=\"layui-icon layui-icon-rate-half\" '+l+\"></i></li>\":n+=r}n+=\"</ul>\"+(i.text?'<span class=\"layui-inline\">'+i.value+\"星\":\"\")+\"</span>\";var c=i.elem,f=c.next(\".\"+t);f[0]&&f.remove(),e.elemTemp=a(n),i.span=e.elemTemp.next(\"span\"),i.setText&&i.setText(i.value),c.html(e.elemTemp),c.addClass(\"layui-inline\"),i.readonly||e.action()},v.prototype.setvalue=function(e){var a=this,i=a.config;i.value=e,a.render()},v.prototype.action=function(){var e=this,i=e.config,l=e.elemTemp,n=l.find(\"i\").width();l.children(\"li\").each(function(e){var t=e+1,v=a(this);v.on(\"click\",function(e){if(i.value=t,i.half){var o=e.pageX-a(this).offset().left;o<=n/2&&(i.value=i.value-.5)}i.text&&l.next(\"span\").text(i.value+\"星\"),i.choose&&i.choose(i.value),i.setText&&i.setText(i.value)}),v.on(\"mousemove\",function(e){if(l.find(\"i\").each(function(){a(this).addClass(o).removeClass(r)}),l.find(\"i:lt(\"+t+\")\").each(function(){a(this).addClass(s).removeClass(f)}),i.half){var c=e.pageX-a(this).offset().left;c<=n/2&&v.children(\"i\").addClass(u).removeClass(s)}}),v.on(\"mouseleave\",function(){l.find(\"i\").each(function(){a(this).addClass(o).removeClass(r)}),l.find(\"i:lt(\"+Math.floor(i.value)+\")\").each(function(){a(this).addClass(s).removeClass(f)}),i.half&&parseInt(i.value)!==i.value&&l.children(\"li:eq(\"+Math.floor(i.value)+\")\").children(\"i\").addClass(u).removeClass(c)})})},v.prototype.events=function(){var e=this;e.config},i.render=function(e){var a=new v(e);return l.call(a)},e(n,i)});layui.define(\"jquery\",function(e){\"use strict\";var t=layui.$,i={fixbar:function(e){var i,a,o=\"layui-fixbar\",r=\"layui-fixbar-top\",l=t(document),n=t(\"body\");e=t.extend({showHeight:200},e),e.bar1=e.bar1===!0?\"&#xe606;\":e.bar1,e.bar2=e.bar2===!0?\"&#xe607;\":e.bar2,e.bgcolor=e.bgcolor?\"background-color:\"+e.bgcolor:\"\";var c=[e.bar1,e.bar2,\"&#xe604;\"],g=t(['<ul class=\"'+o+'\">',e.bar1?'<li class=\"layui-icon\" lay-type=\"bar1\" style=\"'+e.bgcolor+'\">'+c[0]+\"</li>\":\"\",e.bar2?'<li class=\"layui-icon\" lay-type=\"bar2\" style=\"'+e.bgcolor+'\">'+c[1]+\"</li>\":\"\",'<li class=\"layui-icon '+r+'\" lay-type=\"top\" style=\"'+e.bgcolor+'\">'+c[2]+\"</li>\",\"</ul>\"].join(\"\")),u=g.find(\".\"+r),s=function(){var t=l.scrollTop();t>=e.showHeight?i||(u.show(),i=1):i&&(u.hide(),i=0)};t(\".\"+o)[0]||(\"object\"==typeof e.css&&g.css(e.css),n.append(g),s(),g.find(\"li\").on(\"click\",function(){var i=t(this),a=i.attr(\"lay-type\");\"top\"===a&&t(\"html,body\").animate({scrollTop:0},200),e.click&&e.click.call(this,a)}),l.on(\"scroll\",function(){clearTimeout(a),a=setTimeout(function(){s()},100)}))},countdown:function(e,t,i){var a=this,o=\"function\"==typeof t,r=new Date(e).getTime(),l=new Date(!t||o?(new Date).getTime():t).getTime(),n=r-l,c=[Math.floor(n/864e5),Math.floor(n/36e5)%24,Math.floor(n/6e4)%60,Math.floor(n/1e3)%60];o&&(i=t);var g=setTimeout(function(){a.countdown(e,l+1e3,i)},1e3);return i&&i(n>0?c:[0,0,0,0],t,g),n<=0&&clearTimeout(g),g},timeAgo:function(e,t){var i=this,a=[[],[]],o=(new Date).getTime()-new Date(e).getTime();return o>6912e5?(o=new Date(e),a[0][0]=i.digit(o.getFullYear(),4),a[0][1]=i.digit(o.getMonth()+1),a[0][2]=i.digit(o.getDate()),t||(a[1][0]=i.digit(o.getHours()),a[1][1]=i.digit(o.getMinutes()),a[1][2]=i.digit(o.getSeconds())),a[0].join(\"-\")+\" \"+a[1].join(\":\")):o>=864e5?(o/1e3/60/60/24|0)+\"天前\":o>=36e5?(o/1e3/60/60|0)+\"小时前\":o>=12e4?(o/1e3/60|0)+\"分钟前\":o<0?\"未来\":\"刚刚\"},digit:function(e,t){var i=\"\";e=String(e),t=t||2;for(var a=e.length;a<t;a++)i+=\"0\";return e<Math.pow(10,t)?i+(0|e):e},toDateString:function(e,t){var i=this,a=new Date(e||new Date),o=[i.digit(a.getFullYear(),4),i.digit(a.getMonth()+1),i.digit(a.getDate())],r=[i.digit(a.getHours()),i.digit(a.getMinutes()),i.digit(a.getSeconds())];return t=t||\"yyyy-MM-dd HH:mm:ss\",t.replace(/yyyy/g,o[0]).replace(/MM/g,o[1]).replace(/dd/g,o[2]).replace(/HH/g,r[0]).replace(/mm/g,r[1]).replace(/ss/g,r[2])},escape:function(e){return String(e||\"\").replace(/&(?!#?[a-zA-Z0-9]+;)/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/'/g,\"&#39;\").replace(/\"/g,\"&quot;\")}};e(\"util\",i)});layui.define(\"jquery\",function(e){\"use strict\";var l=layui.$,o=function(e){},t='<i class=\"layui-anim layui-anim-rotate layui-anim-loop layui-icon \">&#xe63e;</i>';o.prototype.load=function(e){var o,i,n,r,a=this,c=0;e=e||{};var f=l(e.elem);if(f[0]){var m=l(e.scrollElem||document),u=e.mb||50,s=!(\"isAuto\"in e)||e.isAuto,v=e.end||\"没有更多了\",y=e.scrollElem&&e.scrollElem!==document,d=\"<cite>加载更多</cite>\",h=l('<div class=\"layui-flow-more\"><a href=\"javascript:;\">'+d+\"</a></div>\");f.find(\".layui-flow-more\")[0]||f.append(h);var p=function(e,t){e=l(e),h.before(e),t=0==t||null,t?h.html(v):h.find(\"a\").html(d),i=t,o=null,n&&n()},g=function(){o=!0,h.find(\"a\").html(t),\"function\"==typeof e.done&&e.done(++c,p)};if(g(),h.find(\"a\").on(\"click\",function(){l(this);i||o||g()}),e.isLazyimg)var n=a.lazyimg({elem:e.elem+\" img\",scrollElem:e.scrollElem});return s?(m.on(\"scroll\",function(){var e=l(this),t=e.scrollTop();r&&clearTimeout(r),i||(r=setTimeout(function(){var i=y?e.height():l(window).height(),n=y?e.prop(\"scrollHeight\"):document.documentElement.scrollHeight;n-t-i<=u&&(o||g())},100))}),a):a}},o.prototype.lazyimg=function(e){var o,t=this,i=0;e=e||{};var n=l(e.scrollElem||document),r=e.elem||\"img\",a=e.scrollElem&&e.scrollElem!==document,c=function(e,l){var o=n.scrollTop(),r=o+l,c=a?function(){return e.offset().top-n.offset().top+o}():e.offset().top;if(c>=o&&c<=r&&!e.attr(\"src\")){var m=e.attr(\"lay-src\");layui.img(m,function(){var l=t.lazyimg.elem.eq(i);e.attr(\"src\",m).removeAttr(\"lay-src\"),l[0]&&f(l),i++})}},f=function(e,o){var f=a?(o||n).height():l(window).height(),m=n.scrollTop(),u=m+f;if(t.lazyimg.elem=l(r),e)c(e,f);else for(var s=0;s<t.lazyimg.elem.length;s++){var v=t.lazyimg.elem.eq(s),y=a?function(){return v.offset().top-n.offset().top+m}():v.offset().top;if(c(v,f),i=s,y>u)break}};if(f(),!o){var m;n.on(\"scroll\",function(){var e=l(this);m&&clearTimeout(m),m=setTimeout(function(){f(null,e)},50)}),o=!0}return f},e(\"flow\",new o)});layui.define(\"jquery\",function(e){\"use strict\";var a=layui.$,l=\"http://www.layui.com/doc/modules/code.html\";e(\"code\",function(e){var t=[];e=e||{},e.elem=a(e.elem||\".layui-code\"),e.about=!(\"about\"in e)||e.about,e.elem.each(function(){t.push(this)}),layui.each(t.reverse(),function(t,i){var c=a(i),o=c.html();(c.attr(\"lay-encode\")||e.encode)&&(o=o.replace(/&(?!#?[a-zA-Z0-9]+;)/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/'/g,\"&#39;\").replace(/\"/g,\"&quot;\")),c.html('<ol class=\"layui-code-ol\"><li>'+o.replace(/[\\r\\t\\n]+/g,\"</li><li>\")+\"</li></ol>\"),c.find(\">.layui-code-h3\")[0]||c.prepend('<h3 class=\"layui-code-h3\">'+(c.attr(\"lay-title\")||e.title||\"code\")+(e.about?'<a href=\"'+l+'\" target=\"_blank\">layui.code</a>':\"\")+\"</h3>\");var d=c.find(\">.layui-code-ol\");c.addClass(\"layui-box layui-code-view\"),(c.attr(\"lay-skin\")||e.skin)&&c.addClass(\"layui-code-\"+(c.attr(\"lay-skin\")||e.skin)),(d.find(\"li\").length/100|0)>0&&d.css(\"margin-left\",(d.find(\"li\").length/100|0)+\"px\"),(c.attr(\"lay-height\")||e.height)&&d.css(\"max-height\",c.attr(\"lay-height\")||e.height)})})}).addcss(\"modules/code.css\",\"skincodecss\");layui.define([\"layer\",\"form\"],function(t){\"use strict\";var e=layui.$,i=layui.layer,a=layui.form,l=(layui.hint(),layui.device()),n=\"layedit\",o=\"layui-show\",r=\"layui-disabled\",c=function(){var t=this;t.index=0,t.config={tool:[\"strong\",\"italic\",\"underline\",\"del\",\"|\",\"left\",\"center\",\"right\",\"|\",\"link\",\"unlink\",\"face\",\"image\"],hideTool:[],height:280}};c.prototype.set=function(t){var i=this;return e.extend(!0,i.config,t),i},c.prototype.on=function(t,e){return layui.onevent(n,t,e)},c.prototype.build=function(t,i){i=i||{};var a=this,n=a.config,r=\"layui-layedit\",c=e(\"string\"==typeof t?\"#\"+t:t),u=\"LAY_layedit_\"+ ++a.index,d=c.next(\".\"+r),y=e.extend({},n,i),f=function(){var t=[],e={};return layui.each(y.hideTool,function(t,i){e[i]=!0}),layui.each(y.tool,function(i,a){C[a]&&!e[a]&&t.push(C[a])}),t.join(\"\")}(),m=e(['<div class=\"'+r+'\">','<div class=\"layui-unselect layui-layedit-tool\">'+f+\"</div>\",'<div class=\"layui-layedit-iframe\">','<iframe id=\"'+u+'\" name=\"'+u+'\" textarea=\"'+t+'\" frameborder=\"0\"></iframe>',\"</div>\",\"</div>\"].join(\"\"));return l.ie&&l.ie<8?c.removeClass(\"layui-hide\").addClass(o):(d[0]&&d.remove(),s.call(a,m,c[0],y),c.addClass(\"layui-hide\").after(m),a.index)},c.prototype.getContent=function(t){var e=u(t);if(e[0])return d(e[0].document.body.innerHTML)},c.prototype.getText=function(t){var i=u(t);if(i[0])return e(i[0].document.body).text()},c.prototype.setContent=function(t,i,a){var l=u(t);l[0]&&(a?e(l[0].document.body).append(i):e(l[0].document.body).html(i),layedit.sync(t))},c.prototype.sync=function(t){var i=u(t);if(i[0]){var a=e(\"#\"+i[1].attr(\"textarea\"));a.val(d(i[0].document.body.innerHTML))}},c.prototype.getSelection=function(t){var e=u(t);if(e[0]){var i=m(e[0].document);return document.selection?i.text:i.toString()}};var s=function(t,i,a){var l=this,n=t.find(\"iframe\");n.css({height:a.height}).on(\"load\",function(){var o=n.contents(),r=n.prop(\"contentWindow\"),c=o.find(\"head\"),s=e([\"<style>\",\"*{margin: 0; padding: 0;}\",\"body{padding: 10px; line-height: 20px; overflow-x: hidden; word-wrap: break-word; font: 14px Helvetica Neue,Helvetica,PingFang SC,Microsoft YaHei,Tahoma,Arial,sans-serif; -webkit-box-sizing: border-box !important; -moz-box-sizing: border-box !important; box-sizing: border-box !important;}\",\"a{color:#01AAED; text-decoration:none;}a:hover{color:#c00}\",\"p{margin-bottom: 10px;}\",\"img{display: inline-block; border: none; vertical-align: middle;}\",\"pre{margin: 10px 0; padding: 10px; line-height: 20px; border: 1px solid #ddd; border-left-width: 6px; background-color: #F2F2F2; color: #333; font-family: Courier New; font-size: 12px;}\",\"</style>\"].join(\"\")),u=o.find(\"body\");c.append(s),u.attr(\"contenteditable\",\"true\").css({\"min-height\":a.height}).html(i.value||\"\"),y.apply(l,[r,n,i,a]),g.call(l,r,t,a)})},u=function(t){var i=e(\"#LAY_layedit_\"+t),a=i.prop(\"contentWindow\");return[a,i]},d=function(t){return 8==l.ie&&(t=t.replace(/<.+>/g,function(t){return t.toLowerCase()})),t},y=function(t,a,n,o){var r=t.document,c=e(r.body);c.on(\"keydown\",function(t){var e=t.keyCode;if(13===e){var a=m(r),l=p(a),n=l.parentNode;if(\"pre\"===n.tagName.toLowerCase()){if(t.shiftKey)return;return i.msg(\"请暂时用shift+enter\"),!1}r.execCommand(\"formatBlock\",!1,\"<p>\")}}),e(n).parents(\"form\").on(\"submit\",function(){var t=c.html();8==l.ie&&(t=t.replace(/<.+>/g,function(t){return t.toLowerCase()})),n.value=t}),c.on(\"paste\",function(e){r.execCommand(\"formatBlock\",!1,\"<p>\"),setTimeout(function(){f.call(t,c),n.value=c.html()},100)})},f=function(t){var i=this;i.document;t.find(\"*[style]\").each(function(){var t=this.style.textAlign;this.removeAttribute(\"style\"),e(this).css({\"text-align\":t||\"\"})}),t.find(\"table\").addClass(\"layui-table\"),t.find(\"script,link\").remove()},m=function(t){return t.selection?t.selection.createRange():t.getSelection().getRangeAt(0)},p=function(t){return t.endContainer||t.parentElement().childNodes[0]},v=function(t,i,a){var l=this.document,n=document.createElement(t);for(var o in i)n.setAttribute(o,i[o]);if(n.removeAttribute(\"text\"),l.selection){var r=a.text||i.text;if(\"a\"===t&&!r)return;r&&(n.innerHTML=r),a.pasteHTML(e(n).prop(\"outerHTML\")),a.select()}else{var r=a.toString()||i.text;if(\"a\"===t&&!r)return;r&&(n.innerHTML=r),a.deleteContents(),a.insertNode(n)}},h=function(t,i){var a=this.document,l=\"layedit-tool-active\",n=p(m(a)),o=function(e){return t.find(\".layedit-tool-\"+e)};i&&i[i.hasClass(l)?\"removeClass\":\"addClass\"](l),t.find(\">i\").removeClass(l),o(\"unlink\").addClass(r),e(n).parents().each(function(){var t=this.tagName.toLowerCase(),e=this.style.textAlign;\"b\"!==t&&\"strong\"!==t||o(\"b\").addClass(l),\"i\"!==t&&\"em\"!==t||o(\"i\").addClass(l),\"u\"===t&&o(\"u\").addClass(l),\"strike\"===t&&o(\"d\").addClass(l),\"p\"===t&&(\"center\"===e?o(\"center\").addClass(l):\"right\"===e?o(\"right\").addClass(l):o(\"left\").addClass(l)),\"a\"===t&&(o(\"link\").addClass(l),o(\"unlink\").removeClass(r))})},g=function(t,a,l){var n=t.document,o=e(n.body),c={link:function(i){var a=p(i),l=e(a).parent();b.call(o,{href:l.attr(\"href\"),target:l.attr(\"target\")},function(e){var a=l[0];\"A\"===a.tagName?a.href=e.url:v.call(t,\"a\",{target:e.target,href:e.url,text:e.url},i)})},unlink:function(t){n.execCommand(\"unlink\")},face:function(e){x.call(this,function(i){v.call(t,\"img\",{src:i.src,alt:i.alt},e)})},image:function(a){var n=this;layui.use(\"upload\",function(o){var r=l.uploadImage||{};o.render({url:r.url,method:r.type,elem:e(n).find(\"input\")[0],done:function(e){0==e.code?(e.data=e.data||{},v.call(t,\"img\",{src:e.data.src,alt:e.data.title},a)):i.msg(e.msg||\"上传失败\")}})})},code:function(e){k.call(o,function(i){v.call(t,\"pre\",{text:i.code,\"lay-lang\":i.lang},e)})},help:function(){i.open({type:2,title:\"帮助\",area:[\"600px\",\"380px\"],shadeClose:!0,shade:.1,skin:\"layui-layer-msg\",content:[\"http://www.layui.com/about/layedit/help.html\",\"no\"]})}},s=a.find(\".layui-layedit-tool\"),u=function(){var i=e(this),a=i.attr(\"layedit-event\"),l=i.attr(\"lay-command\");if(!i.hasClass(r)){o.focus();var u=m(n);u.commonAncestorContainer;l?(n.execCommand(l),/justifyLeft|justifyCenter|justifyRight/.test(l)&&n.execCommand(\"formatBlock\",!1,\"<p>\"),setTimeout(function(){o.focus()},10)):c[a]&&c[a].call(this,u),h.call(t,s,i)}},d=/image/;s.find(\">i\").on(\"mousedown\",function(){var t=e(this),i=t.attr(\"layedit-event\");d.test(i)||u.call(this)}).on(\"click\",function(){var t=e(this),i=t.attr(\"layedit-event\");d.test(i)&&u.call(this)}),o.on(\"click\",function(){h.call(t,s),i.close(x.index)})},b=function(t,e){var l=this,n=i.open({type:1,id:\"LAY_layedit_link\",area:\"350px\",shade:.05,shadeClose:!0,moveType:1,title:\"超链接\",skin:\"layui-layer-msg\",content:['<ul class=\"layui-form\" style=\"margin: 15px;\">','<li class=\"layui-form-item\">','<label class=\"layui-form-label\" style=\"width: 60px;\">URL</label>','<div class=\"layui-input-block\" style=\"margin-left: 90px\">','<input name=\"url\" lay-verify=\"url\" value=\"'+(t.href||\"\")+'\" autofocus=\"true\" autocomplete=\"off\" class=\"layui-input\">',\"</div>\",\"</li>\",'<li class=\"layui-form-item\">','<label class=\"layui-form-label\" style=\"width: 60px;\">打开方式</label>','<div class=\"layui-input-block\" style=\"margin-left: 90px\">','<input type=\"radio\" name=\"target\" value=\"_self\" class=\"layui-input\" title=\"当前窗口\"'+(\"_self\"!==t.target&&t.target?\"\":\"checked\")+\">\",'<input type=\"radio\" name=\"target\" value=\"_blank\" class=\"layui-input\" title=\"新窗口\" '+(\"_blank\"===t.target?\"checked\":\"\")+\">\",\"</div>\",\"</li>\",'<li class=\"layui-form-item\" style=\"text-align: center;\">','<button type=\"button\" lay-submit lay-filter=\"layedit-link-yes\" class=\"layui-btn\"> 确定 </button>','<button style=\"margin-left: 20px;\" type=\"button\" class=\"layui-btn layui-btn-primary\"> 取消 </button>',\"</li>\",\"</ul>\"].join(\"\"),success:function(t,n){var o=\"submit(layedit-link-yes)\";a.render(\"radio\"),t.find(\".layui-btn-primary\").on(\"click\",function(){i.close(n),l.focus()}),a.on(o,function(t){i.close(b.index),e&&e(t.field)})}});b.index=n},x=function(t){var a=function(){var t=[\"[微笑]\",\"[嘻嘻]\",\"[哈哈]\",\"[可爱]\",\"[可怜]\",\"[挖鼻]\",\"[吃惊]\",\"[害羞]\",\"[挤眼]\",\"[闭嘴]\",\"[鄙视]\",\"[爱你]\",\"[泪]\",\"[偷笑]\",\"[亲亲]\",\"[生病]\",\"[太开心]\",\"[白眼]\",\"[右哼哼]\",\"[左哼哼]\",\"[嘘]\",\"[衰]\",\"[委屈]\",\"[吐]\",\"[哈欠]\",\"[抱抱]\",\"[怒]\",\"[疑问]\",\"[馋嘴]\",\"[拜拜]\",\"[思考]\",\"[汗]\",\"[困]\",\"[睡]\",\"[钱]\",\"[失望]\",\"[酷]\",\"[色]\",\"[哼]\",\"[鼓掌]\",\"[晕]\",\"[悲伤]\",\"[抓狂]\",\"[黑线]\",\"[阴险]\",\"[怒骂]\",\"[互粉]\",\"[心]\",\"[伤心]\",\"[猪头]\",\"[熊猫]\",\"[兔子]\",\"[ok]\",\"[耶]\",\"[good]\",\"[NO]\",\"[赞]\",\"[来]\",\"[弱]\",\"[草泥马]\",\"[神马]\",\"[囧]\",\"[浮云]\",\"[给力]\",\"[围观]\",\"[威武]\",\"[奥特曼]\",\"[礼物]\",\"[钟]\",\"[话筒]\",\"[蜡烛]\",\"[蛋糕]\"],e={};return layui.each(t,function(t,i){e[i]=layui.cache.dir+\"images/face/\"+t+\".gif\"}),e}();return x.hide=x.hide||function(t){\"face\"!==e(t.target).attr(\"layedit-event\")&&i.close(x.index)},x.index=i.tips(function(){var t=[];return layui.each(a,function(e,i){t.push('<li title=\"'+e+'\"><img src=\"'+i+'\" alt=\"'+e+'\"></li>')}),'<ul class=\"layui-clear\">'+t.join(\"\")+\"</ul>\"}(),this,{tips:1,time:0,skin:\"layui-box layui-util-face\",maxWidth:500,success:function(l,n){l.css({marginTop:-4,marginLeft:-10}).find(\".layui-clear>li\").on(\"click\",function(){t&&t({src:a[this.title],alt:this.title}),i.close(n)}),e(document).off(\"click\",x.hide).on(\"click\",x.hide)}})},k=function(t){var e=this,l=i.open({type:1,id:\"LAY_layedit_code\",area:\"550px\",shade:.05,shadeClose:!0,moveType:1,title:\"插入代码\",skin:\"layui-layer-msg\",content:['<ul class=\"layui-form layui-form-pane\" style=\"margin: 15px;\">','<li class=\"layui-form-item\">','<label class=\"layui-form-label\">请选择语言</label>','<div class=\"layui-input-block\">','<select name=\"lang\">','<option value=\"JavaScript\">JavaScript</option>','<option value=\"HTML\">HTML</option>','<option value=\"CSS\">CSS</option>','<option value=\"Java\">Java</option>','<option value=\"PHP\">PHP</option>','<option value=\"C#\">C#</option>','<option value=\"Python\">Python</option>','<option value=\"Ruby\">Ruby</option>','<option value=\"Go\">Go</option>',\"</select>\",\"</div>\",\"</li>\",'<li class=\"layui-form-item layui-form-text\">','<label class=\"layui-form-label\">代码</label>','<div class=\"layui-input-block\">','<textarea name=\"code\" lay-verify=\"required\" autofocus=\"true\" class=\"layui-textarea\" style=\"height: 200px;\"></textarea>',\"</div>\",\"</li>\",'<li class=\"layui-form-item\" style=\"text-align: center;\">','<button type=\"button\" lay-submit lay-filter=\"layedit-code-yes\" class=\"layui-btn\"> 确定 </button>','<button style=\"margin-left: 20px;\" type=\"button\" class=\"layui-btn layui-btn-primary\"> 取消 </button>',\"</li>\",\"</ul>\"].join(\"\"),success:function(l,n){var o=\"submit(layedit-code-yes)\";a.render(\"select\"),l.find(\".layui-btn-primary\").on(\"click\",function(){i.close(n),e.focus()}),a.on(o,function(e){i.close(k.index),t&&t(e.field)})}});k.index=l},C={html:'<i class=\"layui-icon layedit-tool-html\" title=\"HTML源代码\" lay-command=\"html\" layedit-event=\"html\"\">&#xe64b;</i><span class=\"layedit-tool-mid\"></span>',strong:'<i class=\"layui-icon layedit-tool-b\" title=\"加粗\" lay-command=\"Bold\" layedit-event=\"b\"\">&#xe62b;</i>',italic:'<i class=\"layui-icon layedit-tool-i\" title=\"斜体\" lay-command=\"italic\" layedit-event=\"i\"\">&#xe644;</i>',underline:'<i class=\"layui-icon layedit-tool-u\" title=\"下划线\" lay-command=\"underline\" layedit-event=\"u\"\">&#xe646;</i>',del:'<i class=\"layui-icon layedit-tool-d\" title=\"删除线\" lay-command=\"strikeThrough\" layedit-event=\"d\"\">&#xe64f;</i>',\"|\":'<span class=\"layedit-tool-mid\"></span>',left:'<i class=\"layui-icon layedit-tool-left\" title=\"左对齐\" lay-command=\"justifyLeft\" layedit-event=\"left\"\">&#xe649;</i>',center:'<i class=\"layui-icon layedit-tool-center\" title=\"居中对齐\" lay-command=\"justifyCenter\" layedit-event=\"center\"\">&#xe647;</i>',right:'<i class=\"layui-icon layedit-tool-right\" title=\"右对齐\" lay-command=\"justifyRight\" layedit-event=\"right\"\">&#xe648;</i>',link:'<i class=\"layui-icon layedit-tool-link\" title=\"插入链接\" layedit-event=\"link\"\">&#xe64c;</i>',unlink:'<i class=\"layui-icon layedit-tool-unlink layui-disabled\" title=\"清除链接\" lay-command=\"unlink\" layedit-event=\"unlink\"\">&#xe64d;</i>',face:'<i class=\"layui-icon layedit-tool-face\" title=\"表情\" layedit-event=\"face\"\">&#xe650;</i>',image:'<i class=\"layui-icon layedit-tool-image\" title=\"图片\" layedit-event=\"image\">&#xe64a;<input type=\"file\" name=\"file\"></i>',code:'<i class=\"layui-icon layedit-tool-code\" title=\"插入代码\" layedit-event=\"code\">&#xe64e;</i>',help:'<i class=\"layui-icon layedit-tool-help\" title=\"帮助\" layedit-event=\"help\">&#xe607;</i>'},w=new c;t(n,w)});"
  },
  {
    "path": "public/layui/layui.js",
    "content": "/** layui-v2.3.0 MIT License By https://www.layui.com */\n ;!function(e){\"use strict\";var t=document,n={modules:{},status:{},timeout:10,event:{}},o=function(){this.v=\"2.3.0\"},r=function(){var e=t.currentScript?t.currentScript.src:function(){for(var e,n=t.scripts,o=n.length-1,r=o;r>0;r--)if(\"interactive\"===n[r].readyState){e=n[r].src;break}return e||n[o].src}();return e.substring(0,e.lastIndexOf(\"/\")+1)}(),a=function(t){e.console&&console.error&&console.error(\"Layui hint: \"+t)},i=\"undefined\"!=typeof opera&&\"[object Opera]\"===opera.toString(),u={layer:\"modules/layer\",laydate:\"modules/laydate\",laypage:\"modules/laypage\",laytpl:\"modules/laytpl\",layim:\"modules/layim\",layedit:\"modules/layedit\",form:\"modules/form\",upload:\"modules/upload\",tree:\"modules/tree\",table:\"modules/table\",element:\"modules/element\",rate:\"modules/rate\",carousel:\"modules/carousel\",flow:\"modules/flow\",util:\"modules/util\",code:\"modules/code\",jquery:\"modules/jquery\",mobile:\"modules/mobile\",\"layui.all\":\"../layui.all\"};o.prototype.cache=n,o.prototype.define=function(e,t){var o=this,r=\"function\"==typeof e,a=function(){var e=function(e,t){layui[e]=t,n.status[e]=!0};return\"function\"==typeof t&&t(function(o,r){e(o,r),n.callback[o]=function(){t(e)}}),this};return r&&(t=e,e=[]),layui[\"layui.all\"]||!layui[\"layui.all\"]&&layui[\"layui.mobile\"]?a.call(o):(o.use(e,a),o)},o.prototype.use=function(e,o,l){function s(e,t){var o=\"PLaySTATION 3\"===navigator.platform?/^complete$/:/^(complete|loaded)$/;(\"load\"===e.type||o.test((e.currentTarget||e.srcElement).readyState))&&(n.modules[d]=t,f.removeChild(v),function r(){return++m>1e3*n.timeout/4?a(d+\" is not a valid module\"):void(n.status[d]?c():setTimeout(r,4))}())}function c(){l.push(layui[d]),e.length>1?y.use(e.slice(1),o,l):\"function\"==typeof o&&o.apply(layui,l)}var y=this,p=n.dir=n.dir?n.dir:r,f=t.getElementsByTagName(\"head\")[0];e=\"string\"==typeof e?[e]:e,window.jQuery&&jQuery.fn.on&&(y.each(e,function(t,n){\"jquery\"===n&&e.splice(t,1)}),layui.jquery=layui.$=jQuery);var d=e[0],m=0;if(l=l||[],n.host=n.host||(p.match(/\\/\\/([\\s\\S]+?)\\//)||[\"//\"+location.host+\"/\"])[0],0===e.length||layui[\"layui.all\"]&&u[d]||!layui[\"layui.all\"]&&layui[\"layui.mobile\"]&&u[d])return c(),y;if(n.modules[d])!function g(){return++m>1e3*n.timeout/4?a(d+\" is not a valid module\"):void(\"string\"==typeof n.modules[d]&&n.status[d]?c():setTimeout(g,4))}();else{var v=t.createElement(\"script\"),h=(u[d]?p+\"lay/\":/^\\{\\/\\}/.test(y.modules[d])?\"\":n.base||\"\")+(y.modules[d]||d)+\".js\";h=h.replace(/^\\{\\/\\}/,\"\"),v.async=!0,v.charset=\"utf-8\",v.src=h+function(){var e=n.version===!0?n.v||(new Date).getTime():n.version||\"\";return e?\"?v=\"+e:\"\"}(),f.appendChild(v),!v.attachEvent||v.attachEvent.toString&&v.attachEvent.toString().indexOf(\"[native code\")<0||i?v.addEventListener(\"load\",function(e){s(e,h)},!1):v.attachEvent(\"onreadystatechange\",function(e){s(e,h)}),n.modules[d]=h}return y},o.prototype.getStyle=function(t,n){var o=t.currentStyle?t.currentStyle:e.getComputedStyle(t,null);return o[o.getPropertyValue?\"getPropertyValue\":\"getAttribute\"](n)},o.prototype.link=function(e,o,r){var i=this,u=t.createElement(\"link\"),l=t.getElementsByTagName(\"head\")[0];\"string\"==typeof o&&(r=o);var s=(r||e).replace(/\\.|\\//g,\"\"),c=u.id=\"layuicss-\"+s,y=0;return u.rel=\"stylesheet\",u.href=e+(n.debug?\"?v=\"+(new Date).getTime():\"\"),u.media=\"all\",t.getElementById(c)||l.appendChild(u),\"function\"!=typeof o?i:(function p(){return++y>1e3*n.timeout/100?a(e+\" timeout\"):void(1989===parseInt(i.getStyle(t.getElementById(c),\"width\"))?function(){o()}():setTimeout(p,100))}(),i)},n.callback={},o.prototype.factory=function(e){if(layui[e])return\"function\"==typeof n.callback[e]?n.callback[e]:null},o.prototype.addcss=function(e,t,o){return layui.link(n.dir+\"css/\"+e,t,o)},o.prototype.img=function(e,t,n){var o=new Image;return o.src=e,o.complete?t(o):(o.onload=function(){o.onload=null,\"function\"==typeof t&&t(o)},void(o.onerror=function(e){o.onerror=null,\"function\"==typeof n&&n(e)}))},o.prototype.config=function(e){e=e||{};for(var t in e)n[t]=e[t];return this},o.prototype.modules=function(){var e={};for(var t in u)e[t]=u[t];return e}(),o.prototype.extend=function(e){var t=this;e=e||{};for(var n in e)t[n]||t.modules[n]?a(\"模块名 \"+n+\" 已被占用\"):t.modules[n]=e[n];return t},o.prototype.router=function(e){var t=this,e=e||location.hash,n={path:[],search:{},hash:(e.match(/[^#](#.*$)/)||[])[1]||\"\"};return/^#\\//.test(e)?(e=e.replace(/^#\\//,\"\"),n.href=\"/\"+e,e=e.replace(/([^#])(#.*$)/,\"$1\").split(\"/\")||[],t.each(e,function(e,t){/^\\w+=/.test(t)?function(){t=t.split(\"=\"),n.search[t[0]]=t[1]}():n.path.push(t)}),n):n},o.prototype.data=function(t,n,o){if(t=t||\"layui\",o=o||localStorage,e.JSON&&e.JSON.parse){if(null===n)return delete o[t];n=\"object\"==typeof n?n:{key:n};try{var r=JSON.parse(o[t])}catch(a){var r={}}return\"value\"in n&&(r[n.key]=n.value),n.remove&&delete r[n.key],o[t]=JSON.stringify(r),n.key?r[n.key]:r}},o.prototype.sessionData=function(e,t){return this.data(e,t,sessionStorage)},o.prototype.device=function(t){var n=navigator.userAgent.toLowerCase(),o=function(e){var t=new RegExp(e+\"/([^\\\\s\\\\_\\\\-]+)\");return e=(n.match(t)||[])[1],e||!1},r={os:function(){return/windows/.test(n)?\"windows\":/linux/.test(n)?\"linux\":/iphone|ipod|ipad|ios/.test(n)?\"ios\":/mac/.test(n)?\"mac\":void 0}(),ie:function(){return!!(e.ActiveXObject||\"ActiveXObject\"in e)&&((n.match(/msie\\s(\\d+)/)||[])[1]||\"11\")}(),weixin:o(\"micromessenger\")};return t&&!r[t]&&(r[t]=o(t)),r.android=/android/.test(n),r.ios=\"ios\"===r.os,r},o.prototype.hint=function(){return{error:a}},o.prototype.each=function(e,t){var n,o=this;if(\"function\"!=typeof t)return o;if(e=e||[],e.constructor===Object){for(n in e)if(t.call(e[n],n,e[n]))break}else for(n=0;n<e.length&&!t.call(e[n],n,e[n]);n++);return o},o.prototype.sort=function(e,t,n){var o=JSON.parse(JSON.stringify(e||[]));return t?(o.sort(function(e,n){var o=/^-?\\d+$/,r=e[t],a=n[t];return o.test(r)&&(r=parseFloat(r)),o.test(a)&&(a=parseFloat(a)),r&&!a?1:!r&&a?-1:r>a?1:r<a?-1:0}),n&&o.reverse(),o):o},o.prototype.stope=function(t){t=t||e.event;try{t.stopPropagation()}catch(n){t.cancelBubble=!0}},o.prototype.onevent=function(e,t,n){return\"string\"!=typeof e||\"function\"!=typeof n?this:o.event(e,t,null,n)},o.prototype.event=o.event=function(e,t,o,r){var a=this,i=null,u=t.match(/\\((.*)\\)$/)||[],l=(e+\".\"+t).replace(u[0],\"\"),s=u[1]||\"\",c=function(e,t){var n=t&&t.call(a,o);n===!1&&null===i&&(i=!1)};return r?(n.event[l]=n.event[l]||{},n.event[l][s]=[r],this):(layui.each(n.event[l],function(e,t){return\"{*}\"===s?void layui.each(t,c):(\"\"===e&&layui.each(t,c),void(e===s&&layui.each(t,c)))}),i)},e.layui=new o}(window);"
  },
  {
    "path": "public/model/heartBeat.obj",
    "content": "# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware\n# File Created: 05.12.2011 16:42:58\n\nmtllib 12190_Heart_v1_L3.mtl\n\n#\n# object Heart\n#\n\nv  -5.7868 -2.8897 6.9550\nv  -5.8939 -2.7443 6.7745\nv  -5.4647 -2.7112 6.3057\nv  -5.3747 -2.8576 6.5017\nv  -5.9984 -2.5943 6.6087\nv  -5.5531 -2.5606 6.1250\nv  -5.0930 -2.5268 5.6524\nv  -5.0205 -2.6784 5.8491\nv  -4.9477 -2.8262 6.0619\nv  -6.1979 -2.2803 6.3182\nv  -5.7241 -2.2463 5.8071\nv  -5.6397 -2.4057 5.9591\nv  -6.0999 -2.4397 6.4569\nv  -5.2354 -2.2115 5.3046\nv  -5.1648 -2.3711 5.4711\nv  -4.2430 -2.1425 4.3498\nv  -4.1989 -2.3035 4.5466\nv  -4.6821 -2.3368 4.9984\nv  -4.7391 -2.1766 4.8169\nv  -4.1556 -2.4613 4.7603\nv  -4.6249 -2.4935 5.1957\nv  -4.0729 -2.7673 5.2391\nv  -4.5117 -2.7960 5.6397\nv  -4.5680 -2.6465 5.4094\nv  -4.1136 -2.6159 4.9910\nv  -6.2921 -2.1159 6.1919\nv  -5.8058 -2.0824 5.6684\nv  -6.3821 -1.9465 6.0770\nv  -5.8845 -1.9139 5.5421\nv  -5.3717 -1.8799 5.0140\nv  -5.3044 -2.0478 5.1525\nv  -6.5476 -1.5917 5.8786\nv  -6.0310 -1.5624 5.3243\nv  -5.9597 -1.7406 5.4277\nv  -6.4674 -1.7718 5.9729\nv  -5.4990 -1.5315 4.7755\nv  -5.4367 -1.7078 4.8885\nv  -4.4226 -1.4681 3.7236\nv  -4.3778 -1.6412 3.8566\nv  -4.9066 -1.6744 4.3625\nv  -4.9601 -1.4998 4.2395\nv  -4.3327 -1.8113 4.0050\nv  -4.8517 -1.8454 4.4994\nv  -4.7958 -2.0128 4.6507\nv  -4.2877 -1.9784 4.1693\nv  -2.4568 -1.3596 2.0047\nv  -2.4405 -1.5278 2.1748\nv  -2.8815 -1.5515 2.5299\nv  -2.9037 -1.3824 2.3683\nv  -2.4270 -1.6955 2.3656\nv  -2.8618 -1.7196 2.7113\nv  -3.3297 -1.7475 3.1043\nv  -3.3569 -1.5788 2.9333\nv  -3.3859 -1.4086 2.7807\nv  -2.4090 -2.0284 2.8087\nv  -2.8299 -2.0520 3.1328\nv  -2.8445 -1.8865 2.9123\nv  -2.4165 -1.8625 2.5770\nv  -3.2809 -2.0794 3.5017\nv  -3.3043 -1.9144 3.2937\nv  -3.7879 -1.9453 3.7149\nv  -3.7544 -2.1098 3.9094\nv  -3.8227 -1.7784 3.5378\nv  -3.8950 -1.4375 3.2349\nv  -3.8584 -1.6090 3.3778\nv  -2.4046 -2.1929 3.0604\nv  -2.8180 -2.2157 3.3727\nv  -2.4035 -2.3558 3.3317\nv  -2.8091 -2.3775 3.6317\nv  -3.2409 -2.4027 3.9731\nv  -3.2597 -2.2422 3.7282\nv  -2.4112 -2.6752 3.9323\nv  -2.8005 -2.6941 4.2066\nv  -2.8032 -2.5370 3.9097\nv  -2.4056 -2.5167 3.6224\nv  -3.2112 -2.7160 4.5185\nv  -3.2247 -2.5607 4.2366\nv  -3.6636 -2.5871 4.5985\nv  -3.6374 -2.7405 4.8640\nv  -3.6920 -2.4308 4.3510\nv  -3.7224 -2.2717 4.1214\nv  -8.5188 -3.0812 14.6532\nv  -8.3736 -3.1414 14.8222\nv  -8.4663 -3.0581 15.0557\nv  -8.6327 -3.0066 14.7425\nv  -8.1557 -3.2222 15.0437\nv  -8.2430 -3.1298 15.3407\nv  -8.3571 -3.0145 15.5908\nv  -8.5961 -2.9480 15.2403\nv  -8.7831 -2.8967 14.8571\nv  -7.5863 -3.3994 15.5003\nv  -7.6582 -3.2946 15.8731\nv  -7.9713 -3.2103 15.6161\nv  -7.8909 -3.3097 15.2749\nv  -7.7467 -3.1692 16.2042\nv  -8.0721 -3.0898 15.9129\nv  -7.9530 -2.8620 16.7607\nv  -8.3082 -2.7911 16.4011\nv  -8.1867 -2.9496 16.1723\nv  -7.8466 -3.0245 16.4985\nv  -8.6228 -2.7239 16.0010\nv  -8.4865 -2.8786 15.8087\nv  -9.1079 -2.6131 15.0921\nv  -8.9442 -2.7645 14.9756\nv  -8.7407 -2.8155 15.4092\nv  -8.8912 -2.6634 15.5636\nv  -7.2490 -3.4866 15.7043\nv  -7.3107 -3.3773 16.1030\nv  -6.8848 -3.5694 15.8803\nv  -6.9349 -3.4565 16.2998\nv  -6.9968 -3.3235 16.6819\nv  -7.3861 -3.2479 16.4624\nv  -6.0984 -3.7143 16.1225\nv  -6.1228 -3.5951 16.5697\nv  -6.5370 -3.5298 16.4574\nv  -6.4994 -3.6460 16.0219\nv  -6.1561 -3.4564 16.9824\nv  -6.5847 -3.3938 16.8571\nv  -6.2408 -3.1234 17.7093\nv  -6.7005 -3.0663 17.5558\nv  -6.6401 -3.2390 17.2227\nv  -6.1962 -3.2988 17.3619\nv  -7.1431 -3.0021 17.3432\nv  -7.0672 -3.1717 17.0289\nv  -7.4714 -3.0994 16.7858\nv  -7.5626 -2.9331 17.0764\nv  -6.4231 -2.2604 18.8041\nv  -6.9415 -2.2165 18.5966\nv  -6.8865 -2.4509 18.3769\nv  -6.3812 -2.4986 18.5721\nv  -7.4412 -2.1670 18.3160\nv  -7.3734 -2.3971 18.1112\nv  -7.2992 -2.6136 17.8822\nv  -6.8263 -2.6713 18.1313\nv  -6.3355 -2.7224 18.3131\nv  -8.3588 -2.0592 17.5630\nv  -8.2669 -2.2800 17.3943\nv  -7.8356 -2.3394 17.7816\nv  -7.9158 -2.1139 17.9691\nv  -8.1665 -2.4883 17.2061\nv  -7.7479 -2.5519 17.5719\nv  -7.6558 -2.7502 17.3376\nv  -8.0607 -2.6828 16.9957\nv  -7.2214 -2.8157 17.6269\nv  -6.2880 -2.9310 18.0260\nv  -6.7635 -2.8768 17.8581\nv  -8.7637 -2.0051 17.1046\nv  -8.6610 -2.2212 16.9558\nv  -9.1241 -1.9534 16.6008\nv  -9.0117 -2.1652 16.4724\nv  -8.8886 -2.3653 16.3309\nv  -8.5487 -2.4253 16.7905\nv  -9.6853 -1.8659 15.4850\nv  -9.5573 -2.0703 15.3967\nv  -9.3125 -2.1141 15.9506\nv  -9.4334 -1.9064 16.0587\nv  -9.4168 -2.2642 15.3021\nv  -9.1800 -2.3108 15.8329\nv  -9.0386 -2.4946 15.7044\nv  -9.2662 -2.4457 15.2008\nv  -8.7579 -2.5522 16.1744\nv  -8.4300 -2.6158 16.6064\nv  -2.4203 -2.8312 4.2609\nv  -2.8011 -2.8484 4.5222\nv  -2.4332 -2.9841 4.6084\nv  -2.8056 -2.9996 4.8565\nv  -3.1942 -3.0174 5.1377\nv  -3.2007 -2.8684 4.8188\nv  -2.4720 -3.2791 5.3598\nv  -2.8294 -3.2905 5.5818\nv  -2.8148 -3.1471 5.2097\nv  -2.4503 -3.1336 4.9747\nv  -3.1970 -3.3031 5.8312\nv  -3.1926 -3.1625 5.4752\nv  -3.9430 -3.3316 6.4017\nv  -3.9675 -3.1983 6.0869\nv  -3.5785 -3.1795 5.7685\nv  -3.5698 -3.3168 6.1055\nv  -3.9983 -3.0593 5.7877\nv  -3.5935 -3.0373 5.4491\nv  -3.6136 -2.8908 5.1476\nv  -4.0340 -2.9153 5.5049\nv  -2.4986 -3.4203 5.7637\nv  -2.8500 -3.4293 5.9728\nv  -2.5305 -3.5567 6.1865\nv  -2.8772 -3.5629 6.3828\nv  -3.2281 -3.5688 6.5996\nv  -3.2084 -3.4387 6.2059\nv  -2.6116 -3.8135 7.0886\nv  -2.9545 -3.8131 7.2601\nv  -2.9119 -3.6910 6.8119\nv  -2.5681 -3.6879 6.6281\nv  -3.2971 -3.8107 7.4452\nv  -3.2573 -3.6929 7.0126\nv  -3.9599 -3.7975 7.8332\nv  -3.9312 -3.6916 7.4451\nv  -3.5989 -3.6933 7.2252\nv  -3.6341 -3.8057 7.6380\nv  -3.9212 -3.5785 7.0786\nv  -3.5779 -3.5741 6.8329\nv  -3.5689 -3.4484 6.4599\nv  -3.9263 -3.4584 6.7316\nv  -4.9681 -3.7413 8.4781\nv  -5.0384 -3.6887 8.3553\nv  -4.8073 -3.6805 8.1100\nv  -4.7961 -3.7552 8.3644\nv  -5.1329 -3.6110 8.1836\nv  -4.8624 -3.5949 7.8789\nv  -4.5680 -3.5866 7.5988\nv  -4.5434 -3.6832 7.8898\nv  -4.5514 -3.7713 8.2051\nv  -5.3456 -3.4109 7.7821\nv  -5.0170 -3.3863 7.4072\nv  -4.9344 -3.4964 7.6440\nv  -5.2367 -3.5177 7.9896\nv  -4.6708 -3.3655 7.0524\nv  -4.6128 -3.4807 7.3209\nv  -4.2755 -3.4686 7.0177\nv  -4.3114 -3.3476 6.7173\nv  -4.2527 -3.5819 7.3330\nv  -4.2691 -3.7857 8.0251\nv  -4.2487 -3.6876 7.6674\nv  -5.4561 -3.2930 7.5698\nv  -5.1036 -3.2658 7.1706\nv  -5.5670 -3.1658 7.3578\nv  -5.1929 -3.1364 6.9382\nv  -4.8033 -3.1089 6.5349\nv  -4.7348 -3.2411 6.7894\nv  -5.2837 -2.9998 6.7139\nv  -5.6775 -3.0308 7.1512\nv  -4.8747 -2.9701 6.2915\nv  -4.4563 -2.9419 5.8873\nv  -4.4033 -3.0831 6.1505\nv  -4.3545 -3.2187 6.4277\nv  -2.9783 -4.4564 11.3096\nv  -2.9889 -4.4662 11.8794\nv  -3.3738 -4.4357 11.9872\nv  -3.3597 -4.4271 11.4173\nv  -2.9872 -4.4566 12.4497\nv  -3.3743 -4.4257 12.5597\nv  -3.7637 -4.3903 12.6640\nv  -3.7600 -4.4003 12.0909\nv  -3.7418 -4.3925 11.5225\nv  -2.9518 -4.3796 13.5730\nv  -3.3415 -4.3501 13.6922\nv  -3.3630 -4.3972 13.1298\nv  -2.9744 -4.4277 13.0159\nv  -3.7354 -4.3171 13.8024\nv  -3.7548 -4.3626 13.2363\nv  -4.5274 -4.2374 13.9791\nv  -4.5394 -4.2785 13.4104\nv  -4.1477 -4.3233 13.3312\nv  -4.1315 -4.2798 13.8994\nv  -4.5405 -4.3032 12.8378\nv  -4.1531 -4.3497 12.7582\nv  -4.4994 -4.3050 11.7056\nv  -4.1224 -4.3520 11.6203\nv  -4.1455 -4.3592 12.1859\nv  -4.5281 -4.3118 12.2676\nv  -2.9207 -4.3126 14.1163\nv  -3.3112 -4.2845 14.2418\nv  -2.8824 -4.2268 14.6410\nv  -3.2739 -4.2006 14.7734\nv  -3.6726 -4.1720 14.8938\nv  -3.7074 -4.2536 14.3567\nv  -2.7895 -3.9997 15.6150\nv  -3.1844 -3.9778 15.7620\nv  -3.2311 -4.0983 15.2819\nv  -2.8383 -4.1225 15.1421\nv  -3.5907 -3.9544 15.8946\nv  -3.6331 -4.0724 15.4083\nv  -4.4256 -3.8984 16.0976\nv  -4.4537 -4.0103 15.6034\nv  -4.0415 -4.0434 15.5169\nv  -4.0055 -3.9284 16.0080\nv  -4.4819 -4.1038 15.0817\nv  -4.0761 -4.1401 14.9980\nv  -4.1068 -4.2189 14.4569\nv  -4.5073 -4.1793 14.5382\nv  -6.0849 -3.8128 15.6395\nv  -5.6852 -3.8743 15.6858\nv  -5.6874 -3.7724 16.1757\nv  -6.0780 -3.8922 15.1274\nv  -5.6880 -3.9572 15.1678\nv  -5.2903 -4.0134 15.1708\nv  -5.2783 -3.9269 15.6923\nv  -5.2696 -3.8217 16.1861\nv  -6.0662 -3.9988 14.0432\nv  -5.6926 -4.0705 14.0737\nv  -5.6918 -4.0222 14.6282\nv  -6.0732 -3.9538 14.5931\nv  -5.3102 -4.1336 14.0704\nv  -5.3021 -4.0820 14.6280\nv  -4.9065 -4.1340 14.5967\nv  -4.9211 -4.1889 14.0375\nv  -4.8874 -4.0619 15.1407\nv  -4.8480 -3.8632 16.1585\nv  -4.8669 -3.9719 15.6634\nv  -6.0525 -4.0287 13.4846\nv  -5.6865 -4.1032 13.5108\nv  -6.0277 -4.0447 12.9239\nv  -5.6695 -4.1215 12.9461\nv  -5.3008 -4.1897 12.9362\nv  -5.3109 -4.1692 13.5043\nv  -5.9272 -4.0407 11.8236\nv  -5.5866 -4.1194 11.8375\nv  -5.6375 -4.1265 12.3861\nv  -5.9874 -4.0482 12.3680\nv  -5.2336 -4.1893 11.8192\nv  -5.2762 -4.1961 12.3723\nv  -4.9057 -4.2577 12.3313\nv  -4.8705 -4.2510 11.7735\nv  -4.9238 -4.2501 12.8986\nv  -4.9279 -4.2274 13.4695\nv  -8.1561 -3.1072 10.9419\nv  -8.3060 -3.1199 11.4884\nv  -8.5367 -2.9716 11.3901\nv  -8.3775 -2.9588 10.8369\nv  -8.4206 -3.1277 12.0356\nv  -8.6581 -2.9804 11.9445\nv  -8.8817 -2.8264 11.8725\nv  -8.7543 -2.8170 11.3087\nv  -8.5869 -2.8043 10.7474\nv  -8.5514 -3.1281 13.0897\nv  -8.7916 -2.9872 13.0170\nv  -8.7428 -2.9854 12.4901\nv  -8.5018 -3.1305 12.5729\nv  -9.0170 -2.8389 12.9725\nv  -8.9692 -2.8335 12.4301\nv  -9.4252 -2.5185 12.9439\nv  -9.3793 -2.5079 12.3634\nv  -9.1814 -2.6744 12.3891\nv  -9.2280 -2.6828 12.9502\nv  -9.2871 -2.4982 11.7764\nv  -9.0914 -2.6658 11.8173\nv  -8.9687 -2.4763 10.6088\nv  -8.7840 -2.6435 10.6719\nv  -8.9587 -2.6559 11.2424\nv  -9.1498 -2.4882 11.1894\nv  -8.5715 -3.1205 13.5754\nv  -8.8055 -2.9858 13.5153\nv  -8.5677 -3.1088 14.0145\nv  -8.7858 -2.9847 13.9741\nv  -8.9909 -2.8513 13.9807\nv  -9.0249 -2.8434 13.4910\nv  -8.7337 -2.9869 14.3826\nv  -8.5459 -3.0944 14.3913\nv  -8.9125 -2.8668 14.4366\nv  -9.2671 -2.5762 14.5900\nv  -9.0917 -2.7294 14.5093\nv  -9.3715 -2.5499 14.0616\nv  -9.1861 -2.7066 14.0138\nv  -9.2306 -2.6923 13.4929\nv  -9.4234 -2.5316 13.5114\nv  -9.8732 -1.8341 14.8869\nv  -9.7398 -2.0359 14.8171\nv  -9.9994 -1.8096 14.2695\nv  -9.8621 -2.0094 14.2171\nv  -9.7108 -2.2002 14.1643\nv  -9.5931 -2.2279 14.7442\nv  -10.0749 -1.7772 12.9975\nv  -9.9341 -1.9745 12.9765\nv  -9.9262 -1.9894 13.6018\nv  -10.0659 -1.7911 13.6379\nv  -9.7786 -2.1640 12.9591\nv  -9.7720 -2.1795 13.5675\nv  -9.6041 -2.3604 13.5368\nv  -9.6089 -2.3454 12.9475\nv  -9.5468 -2.3808 14.1121\nv  -9.4349 -2.4085 14.6684\nv  -10.0287 -1.7666 12.3534\nv  -9.8881 -1.9630 12.3463\nv  -9.9294 -1.7579 11.7108\nv  -9.7901 -1.9536 11.7166\nv  -9.6366 -2.1422 11.7281\nv  -9.7329 -2.1521 12.3442\nv  -9.5800 -1.7411 10.4510\nv  -9.4466 -1.9351 10.4793\nv  -9.6423 -1.9448 11.0925\nv  -9.7791 -1.7499 11.0749\nv  -9.3001 -2.1222 10.5140\nv  -9.4917 -2.1328 11.1163\nv  -9.3275 -2.3139 11.1480\nv  -9.1408 -2.3026 10.5567\nv  -9.4689 -2.3237 11.7474\nv  -9.5632 -2.3337 12.3491\nv  -5.6986 -3.6503 16.6309\nv  -5.2678 -3.6966 16.6459\nv  -5.2719 -3.5525 17.0725\nv  -5.7172 -3.5088 17.0524\nv  -4.4002 -3.7676 16.5581\nv  -4.8339 -3.7353 16.6199\nv  -4.3775 -3.6183 16.9859\nv  -4.8240 -3.5886 17.0485\nv  -4.3400 -3.2669 17.7473\nv  -4.8147 -3.2414 17.8107\nv  -4.8178 -3.4237 17.4452\nv  -4.3575 -3.4513 17.3820\nv  -5.2930 -3.2098 17.8300\nv  -5.2807 -3.3900 17.4669\nv  -5.7416 -3.3488 17.4412\nv  -5.7700 -3.1708 17.7984\nv  -3.9703 -3.7948 16.4655\nv  -3.5475 -3.8182 16.3474\nv  -3.5042 -3.6641 16.7676\nv  -3.9363 -3.6431 16.8904\nv  -2.7373 -3.8586 16.0547\nv  -3.1354 -3.8390 16.2087\nv  -2.6833 -3.6998 16.4625\nv  -3.0853 -3.6826 16.6231\nv  -2.5749 -3.3311 17.1871\nv  -2.9863 -3.3183 17.3597\nv  -3.0352 -3.5088 17.0063\nv  -2.6287 -3.5238 16.8395\nv  -3.4208 -3.3042 17.5151\nv  -3.4617 -3.4926 17.1565\nv  -3.9040 -3.4738 17.2838\nv  -3.8737 -3.2874 17.6465\nv  -2.3953 -2.4038 18.3064\nv  -2.8253 -2.3984 18.4975\nv  -2.8580 -2.6511 18.2520\nv  -2.4321 -2.6580 18.0648\nv  -3.2895 -2.3911 18.6692\nv  -3.3158 -2.6424 18.4205\nv  -3.3471 -2.8786 18.1460\nv  -2.8965 -2.8890 17.9813\nv  -2.4752 -2.8977 17.7985\nv  -4.2942 -2.3673 18.9192\nv  -4.3021 -2.6155 18.6678\nv  -3.7993 -2.6308 18.5618\nv  -3.7813 -2.3810 18.8126\nv  -4.3124 -2.8484 18.3893\nv  -3.8210 -2.8654 18.2845\nv  -3.8459 -3.0845 17.9798\nv  -4.3249 -3.0658 18.0828\nv  -3.3823 -3.0994 17.8445\nv  -2.5233 -3.1222 17.5063\nv  -2.9397 -3.1116 17.6843\nv  -4.8215 -2.3493 18.9803\nv  -4.8180 -2.5955 18.7301\nv  -5.3565 -2.3259 18.9873\nv  -5.3407 -2.5700 18.7404\nv  -5.3242 -2.7991 18.4658\nv  -4.8154 -2.8267 18.4523\nv  -5.8639 -2.5380 18.6905\nv  -5.8926 -2.2966 18.9314\nv  -5.8328 -2.7647 18.4221\nv  -5.8010 -2.9759 18.1250\nv  -5.3079 -3.0126 18.1627\nv  -4.8141 -3.0422 18.1462\nv  -6.4746 -3.7413 15.5490\nv  -6.8496 -3.6613 15.4211\nv  -6.8237 -3.7339 14.9293\nv  -6.4578 -3.8174 15.0455\nv  -7.5359 -3.4824 15.0810\nv  -7.2049 -3.5745 15.2628\nv  -7.4992 -3.5458 14.6224\nv  -7.1721 -3.6429 14.7858\nv  -7.4348 -3.6230 13.6167\nv  -7.1144 -3.7291 13.7542\nv  -7.1440 -3.6938 14.2806\nv  -7.4681 -3.5919 14.1318\nv  -6.7785 -3.8275 13.8761\nv  -6.8018 -3.7887 14.4119\nv  -6.4441 -3.8756 14.5185\nv  -6.4286 -3.9176 13.9749\nv  -7.8377 -3.3865 14.8825\nv  -8.1068 -3.2895 14.6852\nv  -8.0792 -3.3368 14.2738\nv  -7.8014 -3.4436 14.4461\nv  -8.3399 -3.1937 14.5068\nv  -8.3334 -3.2257 14.1221\nv  -8.2961 -3.2623 13.1966\nv  -8.3220 -3.2482 13.6810\nv  -8.0252 -3.3895 13.3272\nv  -8.0558 -3.3692 13.8182\nv  -7.7716 -3.4837 13.9731\nv  -7.7382 -3.5098 13.4708\nv  -7.9227 -3.2495 11.0638\nv  -8.0623 -3.2618 11.6054\nv  -7.6770 -3.3853 11.1959\nv  -7.8055 -3.3971 11.7342\nv  -7.9039 -3.4024 12.2754\nv  -8.1691 -3.2685 12.1484\nv  -7.1475 -3.6358 11.4637\nv  -7.2526 -3.6462 11.9995\nv  -7.5357 -3.5254 11.8679\nv  -7.4187 -3.5142 11.3315\nv  -7.3321 -3.6486 12.5424\nv  -7.6249 -3.5293 12.4092\nv  -7.6908 -3.5245 12.9465\nv  -7.3911 -3.6414 13.0842\nv  -7.9758 -3.4002 12.8097\nv  -8.2461 -3.2688 12.6823\nv  -6.8631 -3.7496 11.5857\nv  -6.9563 -3.7593 12.1223\nv  -6.5651 -3.8554 11.6909\nv  -6.6467 -3.8643 12.2292\nv  -6.7061 -3.8637 12.7776\nv  -7.0258 -3.7602 12.6676\nv  -6.3238 -3.9607 12.3134\nv  -6.2532 -3.9525 11.7725\nv  -6.3733 -3.9586 12.8654\nv  -6.4066 -3.9448 13.4216\nv  -6.7483 -3.8520 13.3290\nv  -7.0767 -3.7507 13.2141\nv  -6.9033 -0.0108 5.4959\nv  -6.8964 -0.2157 5.5026\nv  -7.4180 -0.2196 6.0864\nv  -7.4253 -0.0108 6.0802\nv  -6.8766 -0.4198 5.5221\nv  -7.3970 -0.4276 6.1045\nv  -7.8894 -0.4345 6.6880\nv  -7.9115 -0.2231 6.6716\nv  -7.9192 -0.0108 6.6660\nv  -6.8029 -0.8233 5.5975\nv  -7.3181 -0.8385 6.1739\nv  -7.3634 -0.6342 6.1338\nv  -6.8451 -0.6226 5.5539\nv  -7.8055 -0.8520 6.7510\nv  -7.8537 -0.6444 6.7146\nv  -8.6849 -0.8745 7.9184\nv  -8.7384 -0.6615 7.8901\nv  -8.3131 -0.6535 7.2991\nv  -8.2621 -0.8640 7.3316\nv  -8.7777 -0.4460 7.8696\nv  -8.3507 -0.4407 7.2754\nv  -8.8104 -0.0108 7.8529\nv  -8.3820 -0.0108 7.2559\nv  -8.3739 -0.2261 7.2609\nv  -8.8020 -0.2288 7.8571\nv  -6.7510 -1.0213 5.6523\nv  -7.2621 -1.0398 6.2243\nv  -6.6904 -1.2158 5.7178\nv  -7.1965 -1.2374 6.2843\nv  -7.6752 -1.2569 6.8512\nv  -7.7457 -1.0564 6.7967\nv  -7.0402 -1.6186 6.4313\nv  -7.1222 -1.4306 6.3535\nv  -6.6223 -1.4062 5.7934\nv  -7.5060 -1.6430 6.9847\nv  -7.5950 -1.4527 6.9141\nv  -8.3460 -1.6847 8.1029\nv  -8.4477 -1.4901 8.0466\nv  -8.0378 -1.4725 7.4776\nv  -7.9422 -1.6650 7.5411\nv  -8.5387 -1.2896 7.9968\nv  -8.1236 -1.2743 7.4212\nv  -8.1987 -1.0711 7.3724\nv  -8.6180 -1.0841 7.9540\nv  -9.7003 -1.5401 10.4276\nv  -9.4510 -1.5305 9.8115\nv  -9.3343 -1.7302 9.8441\nv  -9.8066 -1.3330 10.4087\nv  -9.5544 -1.3247 9.7841\nv  -9.2570 -1.3147 9.1756\nv  -9.1572 -1.5190 9.2110\nv  -9.0449 -1.7172 9.2521\nv  -9.9751 -0.9039 10.3828\nv  -9.7188 -0.8983 9.7436\nv  -9.6439 -1.1137 9.7615\nv  -9.8984 -1.1206 10.3940\nv  -9.4162 -0.8916 9.1216\nv  -9.3436 -1.1053 9.1458\nv  -9.0007 -1.0955 8.5442\nv  -9.0706 -0.8837 8.5141\nv  -8.9175 -1.3031 8.5808\nv  -8.7145 -1.7021 8.6725\nv  -8.8218 -1.5055 8.6235\nv  -10.0359 -0.6837 10.3749\nv  -9.7782 -0.6795 9.7300\nv  -10.0801 -0.4609 10.3699\nv  -9.8217 -0.4580 9.7207\nv  -9.5163 -0.4546 9.0895\nv  -9.4741 -0.6744 9.1028\nv  -10.1165 -0.0108 10.3664\nv  -9.8574 -0.0108 9.7135\nv  -9.8483 -0.2349 9.7153\nv  -10.1072 -0.2363 10.3671\nv  -9.5512 -0.0108 9.0789\nv  -9.5423 -0.2332 9.0815\nv  -9.1925 -0.2312 8.4631\nv  -9.2012 -0.0108 8.4596\nv  -9.1673 -0.4506 8.4734\nv  -9.1264 -0.6684 8.4904\nv  -2.4091 -4.0213 15.4582\nv  -2.3568 -3.8782 15.8904\nv  -2.0413 -4.0422 15.2988\nv  -1.9917 -3.8971 15.7235\nv  -1.9394 -3.7338 16.1176\nv  -2.3022 -3.7171 16.2914\nv  -1.3367 -4.0788 15.0011\nv  -1.2986 -3.9307 15.4115\nv  -1.6396 -3.9148 15.5613\nv  -1.6845 -4.0615 15.1441\nv  -1.2581 -3.7636 15.7933\nv  -1.5922 -3.7495 15.9490\nv  -1.1751 -3.3762 16.4736\nv  -1.4952 -3.3665 16.6390\nv  -1.5436 -3.5665 16.3079\nv  -1.2166 -3.5785 16.1471\nv  -1.8329 -3.3555 16.8186\nv  -1.8859 -3.5530 16.4823\nv  -2.2466 -3.5387 16.6622\nv  -2.1916 -3.3436 17.0040\nv  -0.9962 -4.0933 14.8772\nv  -0.9663 -3.9441 15.2817\nv  -0.6611 -4.1045 14.7794\nv  -0.6405 -3.9545 15.1792\nv  -0.6186 -3.7847 15.5519\nv  -0.9344 -3.7755 15.6583\nv  0.0000 -4.1143 14.6911\nv  0.0000 -3.9636 15.0867\nv  -0.3192 -3.9612 15.1117\nv  -0.3296 -4.1117 14.7150\nv  0.0000 -3.7929 15.4558\nv  -0.3080 -3.7907 15.4818\nv  -0.0000 -3.3961 16.1158\nv  -0.2850 -3.3947 16.1433\nv  -0.2965 -3.6014 15.8255\nv  -0.0000 -3.6033 15.7988\nv  -0.5735 -3.3906 16.2175\nv  -0.5961 -3.5964 15.8979\nv  -0.9017 -3.5886 16.0077\nv  -0.8690 -3.3844 16.3303\nv  0.0000 -2.4169 17.1301\nv  -0.2457 -2.4169 17.1601\nv  -0.2538 -2.6815 16.9434\nv  0.0000 -2.6818 16.9141\nv  -0.4965 -2.4167 17.2412\nv  -0.5124 -2.6805 17.0227\nv  -0.5310 -2.9315 16.7796\nv  -0.2633 -2.9334 16.7019\nv  0.0000 -2.9341 16.6732\nv  -1.0339 -2.4151 17.5216\nv  -1.0631 -2.6763 17.2969\nv  -0.7806 -2.6788 17.1434\nv  -0.7575 -2.4162 17.3647\nv  -1.0972 -2.9242 17.0478\nv  -0.8075 -2.9284 16.8977\nv  -0.8373 -3.1640 16.6268\nv  -1.1349 -3.1578 16.7736\nv  -0.5516 -3.1686 16.5113\nv  -0.0000 -3.1726 16.4072\nv  -0.2738 -3.1716 16.4353\nv  -1.3308 -2.4135 17.7031\nv  -1.3648 -2.6731 17.4744\nv  -1.6532 -2.4112 17.9003\nv  -1.6903 -2.6689 17.6673\nv  -1.7335 -2.9127 17.4100\nv  -1.4044 -2.9189 17.2214\nv  -2.0445 -2.6640 17.8670\nv  -2.0064 -2.4080 18.1043\nv  -2.0890 -2.9056 17.6052\nv  -2.1386 -3.1323 17.3179\nv  -1.7816 -3.1418 17.1275\nv  -1.4483 -3.1503 16.9432\nv  -2.0495 -2.6598 3.6996\nv  -2.0640 -2.8169 4.0386\nv  -1.7119 -2.6474 3.5061\nv  -1.7293 -2.8053 3.8530\nv  -1.7499 -2.9602 4.2185\nv  -2.0822 -2.9710 4.3963\nv  -1.0953 -2.6307 3.2265\nv  -1.1119 -2.7891 3.5833\nv  -1.4129 -2.7961 3.7019\nv  -1.3950 -2.6378 3.3492\nv  -1.1309 -2.9447 3.9582\nv  -1.4337 -2.9515 4.0731\nv  -1.1753 -3.2462 4.7631\nv  -1.4833 -3.2525 4.8708\nv  -1.4572 -3.1037 4.4627\nv  -1.1521 -3.0971 4.3515\nv  -1.8009 -3.2601 5.0054\nv  -1.7738 -3.1119 4.6026\nv  -2.1041 -3.1219 4.7728\nv  -2.1298 -3.2690 5.1680\nv  -0.8094 -2.6257 3.1355\nv  -0.8232 -2.7842 3.4948\nv  -0.5339 -2.6225 3.0737\nv  -0.5437 -2.7809 3.4345\nv  -0.5547 -2.9363 3.8130\nv  -0.8388 -2.9397 3.8722\nv  0.0000 -2.6205 3.0277\nv  0.0000 -2.7787 3.3892\nv  -0.2703 -2.7792 3.4000\nv  -0.2652 -2.6209 3.0386\nv  -0.0000 -2.9338 3.7683\nv  -0.2760 -2.9344 3.7790\nv  0.0000 -3.2347 4.5802\nv  -0.2891 -3.2355 4.5909\nv  -0.2823 -3.0866 4.1759\nv  0.0000 -3.0859 4.1652\nv  -0.5801 -3.2376 4.6243\nv  -0.5669 -3.0886 4.2095\nv  -0.8561 -3.0921 4.2676\nv  -0.8748 -3.2412 4.6813\nv  0.0000 -3.7952 6.4269\nv  -0.3197 -3.7960 6.4376\nv  -0.3116 -3.6614 5.9475\nv  0.0000 -3.6605 5.9367\nv  -0.6400 -3.7980 6.4696\nv  -0.6242 -3.6635 5.9798\nv  -0.6088 -3.5252 5.5092\nv  -0.3038 -3.5230 5.4765\nv  0.0000 -3.5221 5.4657\nv  -1.2852 -3.8040 6.5957\nv  -1.2555 -3.6708 6.1094\nv  -0.9385 -3.6668 6.0338\nv  -0.9616 -3.8008 6.5223\nv  -1.2272 -3.5332 5.6420\nv  -0.9162 -3.5287 5.5643\nv  -0.8949 -3.3868 5.1135\nv  -1.2004 -3.3916 5.1933\nv  -0.5941 -3.3832 5.0574\nv  0.0000 -3.3802 5.0136\nv  -0.2963 -3.3810 5.0244\nv  -1.6113 -3.8073 6.6893\nv  -1.5760 -3.6752 6.2066\nv  -1.9407 -3.8102 6.8028\nv  -1.9011 -3.6797 6.3255\nv  -1.8646 -3.5443 5.8668\nv  -1.5429 -3.5385 5.7427\nv  -2.2315 -3.6841 6.4660\nv  -2.2739 -3.8124 6.9360\nv  -2.1934 -3.5505 6.0146\nv  -2.1595 -3.4120 5.5820\nv  -1.8312 -3.4043 5.4268\nv  -1.5119 -3.3975 5.2974\nv  -2.5998 -4.4810 11.2043\nv  -2.6076 -4.4923 11.7721\nv  -2.2237 -4.5012 11.1042\nv  -2.2294 -4.5143 11.6685\nv  -2.2253 -4.5067 12.2294\nv  -2.6044 -4.4836 12.3383\nv  -1.4777 -4.5299 10.9304\nv  -1.4804 -4.5465 11.4856\nv  -1.8538 -4.5322 11.5720\nv  -1.8498 -4.5174 11.0120\nv  -1.4764 -4.5419 12.0341\nv  -1.8495 -4.5261 12.1267\nv  -1.4499 -4.4697 13.0977\nv  -1.8185 -4.4519 13.2063\nv  -1.8375 -4.4993 12.6727\nv  -1.4660 -4.5162 12.5725\nv  -2.1911 -4.4308 13.3250\nv  -2.2123 -4.4788 12.7829\nv  -2.5910 -4.4549 12.8988\nv  -2.5686 -4.4066 13.4490\nv  -1.1070 -4.5390 10.8620\nv  -1.1088 -4.5571 11.4127\nv  -0.7374 -4.5450 10.8097\nv  -0.7384 -4.5645 11.3565\nv  -0.7360 -4.5625 11.8941\nv  -1.1054 -4.5540 11.9553\nv  0.0000 -4.5494 10.7641\nv  0.0000 -4.5701 11.3070\nv  -0.3690 -4.5687 11.3202\nv  -0.3685 -4.5484 10.7762\nv  0.0000 -4.5693 11.8398\nv  -0.3677 -4.5676 11.8543\nv  0.0000 -4.5033 12.8655\nv  -0.3605 -4.5011 12.8832\nv  -0.3649 -4.5450 12.3761\nv  0.0000 -4.5470 12.3601\nv  -0.7217 -4.4945 12.9311\nv  -0.7304 -4.5392 12.4198\nv  -1.0972 -4.5295 12.4867\nv  -1.0846 -4.4840 13.0043\nv  -0.3391 -4.2410 14.2913\nv  0.0000 -4.2436 14.2689\nv  -0.6797 -4.2336 14.3521\nv  -0.6962 -4.3417 13.8998\nv  -0.3475 -4.3490 13.8432\nv  0.0000 -4.3516 13.8223\nv  -1.3714 -4.2069 14.5613\nv  -1.0233 -4.2220 14.4443\nv  -1.4021 -4.3149 14.0953\nv  -1.0473 -4.3301 13.9859\nv  -1.0679 -4.4175 13.5050\nv  -1.4285 -4.4025 13.6063\nv  -0.7103 -4.4287 13.4253\nv  0.0000 -4.4382 13.3537\nv  -0.3546 -4.4357 13.3730\nv  -1.7254 -4.1888 14.6963\nv  -2.0869 -4.1683 14.8426\nv  -2.1276 -4.2753 14.3589\nv  -1.7618 -4.2964 14.2217\nv  -2.4574 -4.1460 14.9935\nv  -2.5008 -4.2519 14.5007\nv  -2.5382 -4.3388 13.9844\nv  -2.1626 -4.3628 13.8517\nv  -1.7931 -4.3842 13.7238\nv  -2.5821 -0.0108 1.3799\nv  -2.1576 -0.0108 1.0442\nv  -2.1545 -0.1767 1.0540\nv  -2.5785 -0.1796 1.3893\nv  -1.7738 -0.0108 0.7623\nv  -1.7711 -0.1744 0.7726\nv  -1.7640 -0.3380 0.8038\nv  -2.1462 -0.3426 1.0838\nv  -2.5690 -0.3484 1.4177\nv  -1.1050 -0.0108 0.3491\nv  -1.1032 -0.1713 0.3603\nv  -1.4226 -0.1726 0.5423\nv  -1.4249 -0.0108 0.5315\nv  -1.0985 -0.3320 0.3942\nv  -1.4168 -0.3345 0.5749\nv  -1.0837 -0.6544 0.5301\nv  -1.3979 -0.6592 0.7060\nv  -1.4082 -0.4967 0.6294\nv  -1.0918 -0.4930 0.4508\nv  -1.7411 -0.6659 0.9297\nv  -1.7537 -0.5018 0.8560\nv  -2.5372 -0.6858 1.5329\nv  -2.5548 -0.5171 1.4655\nv  -2.1339 -0.5086 1.1337\nv  -2.1189 -0.6747 1.2042\nv  -0.8084 -0.0108 0.2121\nv  -0.8071 -0.1704 0.2238\nv  -0.5293 -0.0108 0.1178\nv  -0.5283 -0.1699 0.1298\nv  -0.5260 -0.3292 0.1658\nv  -0.8036 -0.3303 0.2588\nv  0.0000 -0.0108 0.0463\nv  0.0000 -0.1696 0.0586\nv  -0.2613 -0.1696 0.0757\nv  -0.2617 -0.0108 0.0635\nv  0.0000 -0.3285 0.0954\nv  -0.2601 -0.3287 0.1123\nv  0.0000 -0.6478 0.2417\nv  -0.2565 -0.6481 0.2578\nv  -0.2584 -0.4881 0.1730\nv  0.0000 -0.4879 0.1565\nv  -0.5187 -0.6491 0.3091\nv  -0.5227 -0.4889 0.2256\nv  -0.7985 -0.4904 0.3172\nv  -0.7925 -0.6511 0.3988\nv  0.0000 -1.2973 0.8195\nv  -0.2496 -1.2977 0.8333\nv  -0.2507 -1.1335 0.6543\nv  0.0000 -1.1331 0.6399\nv  -0.5046 -1.2993 0.8784\nv  -0.5071 -1.1350 0.7010\nv  -0.5105 -0.9719 0.5469\nv  -0.2524 -0.9706 0.4986\nv  0.0000 -0.9702 0.4836\nv  -1.0530 -1.3080 1.0766\nv  -1.0589 -1.1431 0.9055\nv  -0.7746 -1.1380 0.7836\nv  -0.7706 -1.3026 0.9583\nv  -1.0665 -0.9793 0.7574\nv  -0.7800 -0.9747 0.6321\nv  -0.7861 -0.8125 0.5038\nv  -1.0750 -0.8165 0.6323\nv  -0.5145 -0.8100 0.4163\nv  0.0000 -0.8086 0.3508\nv  -0.2544 -0.8088 0.3663\nv  -1.3574 -1.3159 1.2369\nv  -1.3656 -1.1505 1.0701\nv  -1.6892 -1.3269 1.4426\nv  -1.7002 -1.1608 1.2811\nv  -1.7133 -0.9953 1.1419\nv  -1.3757 -0.9860 0.9262\nv  -2.4759 -1.1913 1.8558\nv  -2.0685 -1.1742 1.5418\nv  -2.0538 -1.3413 1.6973\nv  -2.4964 -1.0229 1.7277\nv  -2.0850 -1.0075 1.4080\nv  -2.1022 -0.8410 1.2956\nv  -2.5173 -0.8544 1.6202\nv  -1.7273 -0.8304 1.0249\nv  -1.3868 -0.8223 0.8049\nv  0.0000 -3.9261 6.9366\nv  -0.3279 -3.9268 6.9472\nv  0.0000 -4.0509 7.4624\nv  -0.3360 -4.0515 7.4729\nv  -0.6722 -4.0526 7.5036\nv  -0.6562 -3.9284 6.9785\nv  0.0000 -4.2736 8.5486\nv  -0.3508 -4.2738 8.5590\nv  -0.3437 -4.1679 8.0113\nv  0.0000 -4.1675 8.0009\nv  -0.7019 -4.2737 8.5889\nv  -0.6876 -4.1684 8.0415\nv  -1.4054 -4.2706 8.7017\nv  -1.3772 -4.1681 8.1566\nv  -1.0321 -4.1687 8.0903\nv  -1.0533 -4.2728 8.6369\nv  -1.3471 -4.0548 7.6221\nv  -1.0092 -4.0539 7.5536\nv  -0.9854 -3.9305 7.0299\nv  -1.3161 -3.9327 7.1008\nv  0.0000 -4.3671 9.1022\nv  -0.3571 -4.3670 9.1128\nv  0.0000 -4.4457 9.6583\nv  -0.3624 -4.4453 9.6691\nv  -0.7249 -4.4437 9.6996\nv  -0.7145 -4.3661 9.1427\nv  -0.3662 -4.5065 10.2247\nv  0.0000 -4.5072 10.2134\nv  -0.7328 -4.5040 10.2563\nv  -1.4678 -4.4919 10.3715\nv  -1.0999 -4.4993 10.3061\nv  -1.4518 -4.4346 9.8119\nv  -1.0880 -4.4402 9.7478\nv  -1.0722 -4.3640 9.1904\nv  -1.4306 -4.3601 9.2544\nv  -2.9540 -4.4270 10.7453\nv  -2.5797 -4.4494 10.6397\nv  -2.9186 -4.3796 10.1882\nv  -2.5496 -4.3992 10.0800\nv  -2.1824 -4.4146 9.9799\nv  -2.2075 -4.4673 10.5406\nv  -2.8242 -4.2378 9.1019\nv  -2.4675 -4.2507 8.9834\nv  -2.5115 -4.3324 9.5272\nv  -2.8745 -4.3160 9.6398\nv  -2.1123 -4.2601 8.8763\nv  -2.1501 -4.3448 9.4244\nv  -1.7898 -4.3539 9.3329\nv  -1.7584 -4.2666 8.7819\nv  -1.8165 -4.4262 9.8899\nv  -1.8369 -4.4814 10.4505\nv  -2.7703 -4.1468 8.5762\nv  -2.4197 -4.1560 8.4504\nv  -2.7152 -4.0446 8.0643\nv  -2.3701 -4.0502 7.9302\nv  -2.0272 -4.0534 7.8112\nv  -2.0708 -4.1623 8.3378\nv  -2.3208 -3.9350 7.4247\nv  -2.6615 -3.9329 7.5678\nv  -1.9833 -3.9354 7.2988\nv  -1.6485 -3.9345 7.1907\nv  -1.6863 -4.0548 7.7083\nv  -1.7234 -4.1662 8.2395\nv  -3.0059 -3.9286 7.7275\nv  -3.0630 -4.0361 8.2127\nv  -3.4090 -4.0241 8.3690\nv  -3.3489 -3.9215 7.8977\nv  -3.1826 -4.2209 9.2306\nv  -3.1229 -4.1341 8.7142\nv  -3.5395 -4.1993 9.3630\nv  -3.4738 -4.1171 8.8578\nv  -4.2370 -4.1385 9.6135\nv  -4.1556 -4.0673 9.1363\nv  -3.8192 -4.0951 9.0007\nv  -3.8920 -4.1721 9.4928\nv  -4.0782 -3.9862 8.6799\nv  -3.7489 -4.0077 8.5269\nv  -3.6856 -3.9108 8.0723\nv  -4.0109 -3.8960 8.2452\nv  -3.2390 -4.2952 9.7606\nv  -3.2894 -4.3553 10.3026\nv  -3.6597 -4.3257 10.4175\nv  -3.6026 -4.2692 9.8833\nv  -3.3306 -4.3998 10.8553\nv  -3.7072 -4.3672 10.9643\nv  -4.4517 -4.2833 11.1578\nv  -4.0817 -4.3286 11.0669\nv  -4.3893 -4.2475 10.6257\nv  -4.0271 -4.2900 10.5271\nv  -3.9626 -4.2374 10.0020\nv  -4.3163 -4.1989 10.1104\nv  -5.8426 -4.0233 11.2974\nv  -5.5128 -4.1013 11.3068\nv  -5.7378 -3.9971 10.7922\nv  -5.4204 -4.0732 10.7967\nv  -5.0883 -4.1399 10.7664\nv  -5.1695 -4.1702 11.2831\nv  -5.4835 -3.9223 9.8566\nv  -5.1974 -3.9909 9.8491\nv  -5.3138 -4.0361 10.3099\nv  -5.6168 -3.9631 10.3110\nv  -4.8925 -4.0491 9.8003\nv  -4.9944 -4.0992 10.2714\nv  -4.6611 -4.1531 10.2026\nv  -4.5714 -4.0979 9.7189\nv  -4.7438 -4.1977 10.7074\nv  -4.8151 -4.2307 11.2317\nv  -5.3422 -3.8757 9.4317\nv  -5.0756 -3.9387 9.4169\nv  -5.2010 -3.8268 9.0472\nv  -4.9583 -3.8814 9.0211\nv  -4.6875 -3.9245 8.9396\nv  -4.7869 -3.9906 9.3554\nv  -4.8558 -3.8212 8.6692\nv  -5.0682 -3.7787 8.7140\nv  -4.6042 -3.8516 8.5556\nv  -4.3198 -3.8764 8.4102\nv  -4.3926 -3.9590 8.8217\nv  -4.4792 -4.0330 9.2583\nv  -5.2346 -3.7174 8.6532\nv  -5.4113 -3.7575 8.9992\nv  -5.5987 -3.6747 8.8958\nv  -5.3767 -3.6391 8.5232\nv  -5.7480 -3.8421 9.8141\nv  -5.5837 -3.8003 9.3887\nv  -5.9936 -3.7510 9.7309\nv  -5.8042 -3.7130 9.2993\nv  -6.4390 -3.5388 9.4788\nv  -6.1994 -3.5060 9.0261\nv  -6.0080 -3.6147 9.1746\nv  -6.2230 -3.6497 9.6161\nv  -5.9372 -3.4725 8.5921\nv  -5.7726 -3.5794 8.7558\nv  -5.5157 -3.5462 8.3605\nv  -5.6525 -3.4403 8.1772\nv  -5.9007 -3.8793 10.2678\nv  -6.0382 -3.9107 10.7471\nv  -6.3225 -3.8148 10.6683\nv  -6.1673 -3.7853 10.1879\nv  -6.1568 -3.9355 11.2495\nv  -6.4560 -3.8385 11.1699\nv  -7.0117 -3.6188 10.9429\nv  -6.7408 -3.7328 11.0655\nv  -6.8470 -3.5962 10.4380\nv  -6.5917 -3.7098 10.5629\nv  -6.4184 -3.6817 10.0793\nv  -6.6555 -3.5692 9.9497\nv  -7.9689 -3.0898 10.4065\nv  -7.7474 -3.2320 10.5340\nv  -7.7466 -3.0683 9.8822\nv  -7.5383 -3.2102 10.0159\nv  -7.3194 -3.3459 10.1576\nv  -7.5144 -3.3679 10.6704\nv  -7.2045 -3.0157 8.8656\nv  -7.0261 -3.1566 9.0147\nv  -7.2972 -3.1848 9.5095\nv  -7.4911 -3.0434 9.3686\nv  -6.8396 -3.2914 9.1712\nv  -7.0939 -3.3201 9.6579\nv  -6.8803 -3.4484 9.8069\nv  -6.6442 -3.4191 9.3282\nv  -7.0893 -3.4747 10.3006\nv  -7.2693 -3.4970 10.8089\nv  -6.8887 -2.9859 8.3729\nv  -6.7267 -3.1264 8.5316\nv  -6.5458 -2.9545 7.8904\nv  -6.4009 -3.0948 8.0599\nv  -6.2512 -3.2288 8.2377\nv  -6.5581 -3.2606 8.6978\nv  -6.0505 -3.0627 7.5998\nv  -6.1778 -2.9222 7.4179\nv  -5.9203 -3.1969 7.7910\nv  -5.7874 -3.3233 7.9854\nv  -6.0967 -3.3552 8.4172\nv  -6.3826 -3.3876 8.8649\nv  -6.0981 -1.3793 5.2312\nv  -6.1599 -1.1919 5.1490\nv  -5.6137 -1.1664 4.5854\nv  -5.5585 -1.3508 4.6743\nv  -6.2630 -0.8065 5.0190\nv  -6.2152 -1.0007 5.0781\nv  -5.7073 -0.7884 4.4457\nv  -5.6637 -0.9788 4.5091\nv  -4.5838 -0.7510 3.3449\nv  -4.5487 -0.9333 3.4164\nv  -5.1053 -0.9561 3.9527\nv  -5.1446 -0.7697 3.8853\nv  -4.5093 -1.1139 3.5034\nv  -5.0606 -1.1402 4.0344\nv  -5.0118 -1.3215 4.1301\nv  -4.4668 -1.2923 3.6058\nv  -6.3021 -0.6097 4.9721\nv  -6.3314 -0.4111 4.9380\nv  -5.7704 -0.4018 4.3596\nv  -5.7432 -0.5959 4.3958\nv  -6.3565 -0.0108 4.9101\nv  -6.3499 -0.2113 4.9172\nv  -5.7937 -0.0108 4.3302\nv  -5.7876 -0.2066 4.3376\nv  -4.6561 -0.0108 3.2169\nv  -4.6508 -0.1967 3.2250\nv  -5.2182 -0.2017 3.7711\nv  -5.2239 -0.0108 3.7633\nv  -4.6361 -0.3823 3.2491\nv  -5.2023 -0.3921 3.7942\nv  -5.1773 -0.5816 3.8323\nv  -4.6134 -0.5672 3.2891\nv  -3.0491 -0.1832 1.7813\nv  -3.0531 -0.0108 1.7723\nv  -3.0383 -0.3555 1.8085\nv  -3.5452 -0.3638 2.2489\nv  -3.5573 -0.1874 2.2228\nv  -3.5618 -0.0108 2.2141\nv  -3.0016 -0.6995 1.9186\nv  -3.0221 -0.5276 1.8542\nv  -3.5035 -0.7153 2.3542\nv  -3.5269 -0.5398 2.2927\nv  -4.0603 -0.5531 2.7734\nv  -4.0339 -0.7326 2.8321\nv  -4.0808 -0.3728 2.7315\nv  -4.0990 -0.0108 2.6981\nv  -4.0942 -0.1919 2.7064\nv  -2.9783 -0.8710 2.0020\nv  -2.9533 -1.0420 2.1046\nv  -3.4469 -1.0640 2.5311\nv  -3.4764 -0.8901 2.4336\nv  -2.9280 -1.2125 2.2266\nv  -3.4163 -1.2369 2.6467\nv  -3.9321 -1.2638 3.1089\nv  -3.9685 -1.0882 2.9998\nv  -4.0028 -0.9111 2.9075\nv  -6.4590 -2.0087 19.0103\nv  -6.9887 -1.9692 18.7921\nv  -6.4892 -1.7452 19.1905\nv  -7.0284 -1.7105 18.9630\nv  -7.5490 -1.6713 18.6584\nv  -7.4996 -1.9246 18.4985\nv  -6.5335 -1.1896 19.4706\nv  -7.0870 -1.1656 19.2290\nv  -7.0611 -1.4421 19.1087\nv  -6.5139 -1.4716 19.3440\nv  -7.6223 -1.1384 18.9080\nv  -7.5898 -1.4087 18.7951\nv  -8.6094 -1.0793 18.0605\nv  -8.5636 -1.3361 17.9643\nv  -8.0930 -1.3729 18.4109\nv  -8.1322 -1.1093 18.5159\nv  -8.5068 -1.5859 17.8488\nv  -8.0441 -1.6292 18.2844\nv  -7.9852 -1.8767 18.1370\nv  -8.4386 -1.8274 17.7148\nv  -6.5482 -0.9008 19.5699\nv  -7.1066 -0.8825 19.3233\nv  -6.5584 -0.6069 19.6413\nv  -7.1201 -0.5947 19.3912\nv  -7.6641 -0.5808 19.0609\nv  -7.6470 -0.8619 18.9968\nv  -6.5661 -0.0108 19.6990\nv  -7.1304 -0.0108 19.4461\nv  -7.1279 -0.3036 19.4323\nv  -6.5642 -0.3097 19.6844\nv  -7.6772 -0.0108 19.1128\nv  -7.6740 -0.2966 19.0997\nv  -8.6884 -0.0108 18.2375\nv  -8.6836 -0.2814 18.2260\nv  -8.1951 -0.2891 18.6949\nv  -8.1991 -0.0108 18.7072\nv  -8.6691 -0.5506 18.1921\nv  -8.1829 -0.5659 18.6584\nv  -8.1620 -0.8398 18.5986\nv  -8.6445 -0.8170 18.1367\nv  -10.1689 -0.0108 15.8825\nv  -10.1613 -0.2540 15.8746\nv  -9.8784 -0.2598 16.5174\nv  -9.8854 -0.0108 16.5263\nv  -10.1386 -0.4962 15.8523\nv  -9.8574 -0.5076 16.4920\nv  -9.5138 -0.5209 17.1007\nv  -9.5328 -0.2664 17.1291\nv  -9.5391 -0.0108 17.1389\nv  -10.0476 -0.9729 15.7693\nv  -9.7731 -0.9952 16.3964\nv  -9.8223 -0.7531 16.4513\nv  -10.1007 -0.7362 15.8168\nv  -9.4371 -1.0212 16.9927\nv  -9.4820 -0.7728 17.0549\nv  -9.0869 -0.7944 17.6195\nv  -9.0468 -1.0496 17.5501\nv  -9.1152 -0.5354 17.6702\nv  -9.1376 -0.0108 17.7120\nv  -9.1320 -0.2737 17.7013\nv  -9.9796 -1.2053 15.7111\nv  -9.7097 -1.2327 16.3285\nv  -9.8965 -1.4324 15.6435\nv  -9.6319 -1.4645 16.2488\nv  -9.3076 -1.5019 16.8233\nv  -9.3790 -1.2646 16.9151\nv  -9.5399 -1.6895 16.1585\nv  -9.7984 -1.6529 15.5677\nv  -9.2227 -1.7320 16.7181\nv  -8.8533 -1.7785 17.2394\nv  -8.9302 -1.5429 17.3592\nv  -8.9946 -1.2995 17.4630\nv  -9.9914 -1.6242 14.9533\nv  -10.0943 -1.4070 15.0150\nv  -10.2278 -1.3874 14.3687\nv  -10.1213 -1.6020 14.3204\nv  -10.2535 -0.9553 15.1194\nv  -10.1817 -1.1837 15.0708\nv  -10.3931 -0.9417 14.4522\nv  -10.3184 -1.1670 14.4130\nv  -10.4832 -0.9236 13.0869\nv  -10.4052 -1.1448 13.0659\nv  -10.3921 -1.1543 13.7429\nv  -10.4689 -0.9313 13.7729\nv  -10.3108 -1.3615 13.0433\nv  -10.2992 -1.3726 13.7097\nv  -10.1903 -1.5852 13.6743\nv  -10.2006 -1.5726 13.0202\nv  -10.3096 -0.7228 15.1595\nv  -10.3498 -0.4872 15.1897\nv  -10.4936 -0.4802 14.5098\nv  -10.4516 -0.7124 14.4848\nv  -10.3822 -0.0108 15.2158\nv  -10.3741 -0.2495 15.2089\nv  -10.5276 -0.0108 14.5315\nv  -10.5191 -0.2460 14.5258\nv  -10.6250 -0.0108 13.1325\nv  -10.6159 -0.2413 13.1290\nv  -10.5988 -0.2433 13.8306\nv  -10.6077 -0.0108 13.8353\nv  -10.5890 -0.4709 13.1195\nv  -10.5725 -0.4749 13.8179\nv  -10.5291 -0.7045 13.7982\nv  -10.5446 -0.6986 13.1051\nv  -10.3160 -0.2375 11.0399\nv  -10.3253 -0.0108 11.0402\nv  -10.2886 -0.4632 11.0398\nv  -10.4445 -0.4654 11.7250\nv  -10.4720 -0.2386 11.7282\nv  -10.4813 -0.0108 11.7295\nv  -10.1821 -0.9085 11.0421\nv  -10.2438 -0.6872 11.0403\nv  -10.3374 -0.9129 11.7161\nv  -10.3995 -0.6905 11.7207\nv  -10.5006 -0.6941 12.4108\nv  -10.4386 -0.9177 12.3995\nv  -10.5455 -0.4679 12.4200\nv  -10.5821 -0.0108 12.4287\nv  -10.5728 -0.2398 12.4263\nv  -10.1042 -1.1264 11.0459\nv  -10.0107 -1.3398 11.0522\nv  -10.1643 -1.3461 11.7093\nv  -10.2588 -1.1317 11.7121\nv  -9.9021 -1.5479 11.0617\nv  -10.0543 -1.5551 11.7086\nv  -10.1545 -1.5630 12.3632\nv  -10.2651 -1.3530 12.3748\nv  -10.3600 -1.1376 12.3872\nv  -2.3663 -2.1355 18.5245\nv  -2.7994 -2.1314 18.7191\nv  -2.3440 -1.8548 18.7179\nv  -2.7797 -1.8518 18.9153\nv  -3.2531 -1.8469 19.0913\nv  -3.2688 -2.1253 18.8932\nv  -2.3163 -1.2636 19.0251\nv  -2.7553 -1.2620 19.2267\nv  -2.7653 -1.5614 19.0850\nv  -2.3276 -1.5636 18.8852\nv  -3.2340 -1.2591 19.4049\nv  -3.2417 -1.5575 19.2623\nv  -4.2814 -1.2474 19.6546\nv  -4.2825 -1.5429 19.5131\nv  -3.7499 -1.5515 19.4080\nv  -3.7451 -1.2543 19.5506\nv  -4.2847 -1.8292 19.3428\nv  -3.7571 -1.8396 19.2368\nv  -3.7675 -2.1167 19.0380\nv  -4.2885 -2.1047 19.1445\nv  -2.3091 -0.9566 19.1362\nv  -2.7490 -0.9555 19.3393\nv  -2.3050 -0.6443 19.2173\nv  -2.7456 -0.6436 19.4214\nv  -3.2267 -0.6422 19.6004\nv  -3.2292 -0.9534 19.5181\nv  -2.3031 -0.0108 19.2840\nv  -2.7440 -0.0108 19.4889\nv  -2.7442 -0.3281 19.4717\nv  -2.3033 -0.3284 19.2670\nv  -3.2256 -0.0108 19.6680\nv  -3.2257 -0.3274 19.6508\nv  -4.2822 -0.0108 19.9132\nv  -4.2819 -0.3245 19.8964\nv  -3.7407 -0.3263 19.7954\nv  -3.7408 -0.0108 19.8124\nv  -4.2815 -0.6364 19.8471\nv  -3.7411 -0.6399 19.7454\nv  -3.7424 -0.9498 19.6634\nv  -4.2812 -0.9446 19.7662\nv  -5.9905 -0.3148 19.8479\nv  -5.9919 -0.0108 19.8631\nv  -5.9864 -0.6170 19.8028\nv  -5.4114 -0.6252 19.8849\nv  -5.4141 -0.3189 19.9317\nv  -5.4150 -0.0108 19.9475\nv  -5.9689 -1.2093 19.6249\nv  -5.9792 -0.9158 19.7283\nv  -5.4005 -1.2253 19.7008\nv  -5.4069 -0.9279 19.8078\nv  -4.8385 -0.9374 19.8174\nv  -4.8356 -1.2378 19.7077\nv  -4.8407 -0.6316 19.8967\nv  -4.8427 -0.0108 19.9612\nv  -4.8421 -0.3221 19.9449\nv  -5.9552 -1.4959 19.4930\nv  -5.9381 -1.7738 19.3331\nv  -5.3823 -1.7970 19.4000\nv  -5.3923 -1.5156 19.5647\nv  -5.9172 -2.0413 19.1458\nv  -5.3703 -2.0677 19.2073\nv  -4.8251 -2.0886 19.2039\nv  -4.8288 -1.8152 19.4002\nv  -4.8323 -1.5311 19.5684\nv  -6.9514 -1.8006 6.5172\nv  -6.8564 -1.9768 6.6120\nv  -7.3049 -2.0049 7.1488\nv  -7.4091 -1.8270 7.0626\nv  -6.6493 -2.3126 6.8320\nv  -6.7556 -2.1474 6.7166\nv  -7.0756 -2.3432 7.3496\nv  -7.1936 -2.1769 7.2442\nv  -7.8434 -2.3979 8.4018\nv  -7.9827 -2.2290 8.3140\nv  -7.6035 -2.2041 7.7761\nv  -7.4745 -2.3717 7.8725\nv  -8.1131 -2.0539 8.2357\nv  -7.7247 -2.0306 7.6894\nv  -7.8377 -1.8510 7.6114\nv  -8.2343 -1.8726 8.1656\nv  -6.5379 -2.4725 6.9589\nv  -6.4220 -2.6273 7.0983\nv  -6.8215 -2.6592 7.5944\nv  -6.9515 -2.5039 7.4661\nv  -6.3018 -2.7771 7.2510\nv  -6.6862 -2.8093 7.7355\nv  -7.3758 -2.8696 8.7307\nv  -7.0449 -2.8403 8.2286\nv  -7.5396 -2.7180 8.6091\nv  -7.1949 -2.6896 8.0978\nv  -7.3382 -2.5334 7.9794\nv  -7.6956 -2.5609 8.4998\nv  -8.1797 -2.9417 10.2948\nv  -8.3794 -2.7877 10.1975\nv  -8.1342 -2.7675 9.6583\nv  -7.9454 -2.9208 9.7634\nv  -8.7449 -2.4611 10.0410\nv  -8.5679 -2.6275 10.1134\nv  -8.4811 -2.4429 9.4848\nv  -8.3129 -2.6082 9.5658\nv  -8.0213 -2.5859 9.0283\nv  -8.1798 -2.4217 8.9388\nv  -7.8535 -2.7441 9.1290\nv  -7.6767 -2.8966 9.2421\nv  -8.9103 -2.2883 9.9792\nv  -9.0638 -2.1090 9.9267\nv  -8.7854 -2.0932 9.3524\nv  -8.6387 -2.2712 9.4140\nv  -9.2052 -1.9230 9.8821\nv  -8.9209 -1.9086 9.2988\nv  -8.5963 -1.8918 8.7274\nv  -8.4676 -2.0748 8.7894\nv  -8.3287 -2.2514 8.8595\nv  0.0000 -2.1408 17.3214\nv  -0.2392 -2.1410 17.3522\nv  0.0000 -1.8548 17.4880\nv  -0.2342 -1.8551 17.5196\nv  -0.4741 -1.8558 17.6050\nv  -0.4838 -2.1413 17.4355\nv  0.0000 -1.2589 17.7459\nv  -0.2280 -1.2593 17.7791\nv  -0.2306 -1.5608 17.6620\nv  0.0000 -1.5604 17.6296\nv  -0.4618 -1.2601 17.8687\nv  -0.4669 -1.5616 17.7496\nv  -0.9705 -1.2624 18.1767\nv  -0.9798 -1.5637 18.0510\nv  -0.7147 -1.5626 17.8825\nv  -0.7074 -1.2612 18.0046\nv  -0.9929 -1.8573 17.8994\nv  -0.7251 -1.8566 17.7348\nv  -0.7392 -2.1416 17.5620\nv  -1.0107 -2.1416 17.7227\nv  0.0000 -0.9518 17.8367\nv  -0.2263 -0.9521 17.8706\nv  -0.0000 -0.6405 17.9018\nv  -0.2254 -0.6407 17.9363\nv  -0.4567 -0.6413 18.0292\nv  -0.4586 -0.9529 17.9620\nv  0.0000 -0.0108 17.9543\nv  -0.2249 -0.0108 17.9893\nv  -0.2250 -0.3265 17.9760\nv  0.0000 -0.3264 17.9411\nv  -0.4558 -0.0108 18.0834\nv  -0.4559 -0.3268 18.0698\nv  -0.9596 -0.0108 18.4059\nv  -0.9598 -0.3276 18.3911\nv  -0.6989 -0.3271 18.2118\nv  -0.6987 -0.0108 18.2259\nv  -0.9613 -0.6428 18.3475\nv  -0.7000 -0.6420 18.1698\nv  -0.7027 -0.9538 18.1005\nv  -0.9646 -0.9549 18.2758\nv  -1.9105 -0.3285 19.0458\nv  -1.9102 -0.0108 19.0625\nv  -1.9123 -0.6444 18.9973\nv  -1.5614 -0.6441 18.7719\nv  -1.5596 -0.3283 18.8190\nv  -1.5593 -0.0108 18.8350\nv  -1.9242 -1.2642 18.8092\nv  -1.9166 -0.9569 18.9179\nv  -1.5731 -1.2641 18.5891\nv  -1.5656 -0.9566 18.6949\nv  -1.2503 -0.9559 18.4773\nv  -1.2572 -1.2634 18.3749\nv  -1.2464 -0.6435 18.5517\nv  -1.2444 -0.0108 18.6126\nv  -1.2447 -0.3280 18.5971\nv  -1.9360 -1.5647 18.6722\nv  -1.9531 -1.8567 18.5082\nv  -1.6013 -1.8576 18.2956\nv  -1.5847 -1.5650 18.4556\nv  -1.9762 -2.1383 18.3185\nv  -1.6239 -2.1402 18.1101\nv  -1.3038 -2.1412 17.9085\nv  -1.2831 -1.8577 18.0895\nv  -1.2678 -1.5646 18.2453\nv  0.0000 -1.4631 1.0222\nv  -0.2491 -1.4635 1.0355\nv  -0.0000 -1.6299 1.2474\nv  -0.2493 -1.6303 1.2602\nv  -0.5037 -1.6319 1.3022\nv  -0.5035 -1.4651 1.0790\nv  -0.0000 -1.9643 1.7619\nv  -0.2518 -1.9646 1.7739\nv  -0.2502 -1.7975 1.5065\nv  0.0000 -1.7971 1.4942\nv  -0.5083 -1.9662 1.8130\nv  -0.5053 -1.7991 1.5471\nv  -1.0542 -1.9750 1.9866\nv  -1.0502 -1.8081 1.7266\nv  -0.7704 -1.8025 1.6193\nv  -0.7742 -1.9695 1.8828\nv  -1.0487 -1.6410 1.4878\nv  -0.7685 -1.6353 1.3769\nv  -0.7685 -1.4685 1.1563\nv  -1.0496 -1.4741 1.2710\nv  0.0000 -2.1307 2.0499\nv  -0.2541 -2.1311 2.0615\nv  -0.0000 -2.2959 2.3573\nv  -0.2571 -2.2963 2.3686\nv  -0.5184 -2.2979 2.4054\nv  -0.5127 -2.1327 2.0994\nv  -0.2608 -2.4598 2.6945\nv  0.0000 -2.4594 2.6835\nv  -0.5254 -2.4614 2.7304\nv  -1.0813 -2.4696 2.8878\nv  -0.7977 -2.4645 2.7939\nv  -1.0697 -2.3062 2.5679\nv  -0.7879 -2.3010 2.4709\nv  -0.7800 -2.1359 2.1669\nv  -1.0607 -2.1412 2.2672\nv  -2.0385 -2.5001 3.3794\nv  -2.0309 -2.3382 3.0784\nv  -1.6871 -2.3244 2.8686\nv  -1.6979 -2.4870 3.1778\nv  -2.0257 -2.0094 2.5354\nv  -2.0266 -2.1746 2.7969\nv  -1.6752 -1.9945 2.3095\nv  -1.6796 -2.1601 2.5790\nv  -1.3591 -2.1492 2.4035\nv  -1.3530 -1.9832 2.1277\nv  -1.3681 -2.3139 2.6994\nv  -1.3801 -2.4769 3.0148\nv  -2.0280 -1.8431 2.2943\nv  -2.0335 -1.6761 2.0740\nv  -1.6760 -1.6609 1.8329\nv  -1.6741 -1.8279 2.0606\nv  -2.0421 -1.5087 1.8749\nv  -1.6811 -1.4937 1.6267\nv  -1.3520 -1.4823 1.4266\nv  -1.3495 -1.6493 1.6387\nv  -1.3498 -1.8164 1.8726\nv  5.7868 -2.9039 6.9550\nv  5.3747 -2.8671 6.5017\nv  5.4647 -2.7209 6.3057\nv  5.8939 -2.7589 6.7745\nv  4.9477 -2.8321 6.0619\nv  5.0205 -2.6845 5.8491\nv  5.0930 -2.5329 5.6524\nv  5.5531 -2.5703 6.1250\nv  5.9984 -2.6089 6.6087\nv  4.0729 -2.7690 5.2391\nv  4.1136 -2.6177 4.9910\nv  4.5680 -2.6500 5.4094\nv  4.5117 -2.7994 5.6397\nv  4.1556 -2.4630 4.7603\nv  4.6249 -2.4970 5.1957\nv  4.2430 -2.1441 4.3498\nv  4.7391 -2.1799 4.8169\nv  4.6821 -2.3402 4.9984\nv  4.1989 -2.3051 4.5466\nv  5.2353 -2.2172 5.3046\nv  5.1648 -2.3771 5.4711\nv  6.1979 -2.2939 6.3182\nv  6.0999 -2.4539 6.4569\nv  5.6397 -2.4152 5.9591\nv  5.7241 -2.2554 5.8071\nv  3.6374 -2.7412 4.8640\nv  3.6636 -2.5878 4.5985\nv  3.2112 -2.7161 4.5185\nv  3.2247 -2.5608 4.2366\nv  3.2409 -2.4028 3.9731\nv  3.6920 -2.4315 4.3510\nv  2.4112 -2.6752 3.9323\nv  2.4056 -2.5167 3.6224\nv  2.8032 -2.5370 3.9097\nv  2.8005 -2.6941 4.2066\nv  2.4035 -2.3558 3.3317\nv  2.8091 -2.3775 3.6317\nv  2.4090 -2.0284 2.8087\nv  2.8299 -2.0520 3.1328\nv  2.8180 -2.2157 3.3727\nv  2.4046 -2.1929 3.0604\nv  3.2809 -2.0795 3.5017\nv  3.2597 -2.2424 3.7282\nv  3.7224 -2.2723 4.1214\nv  3.7544 -2.1104 3.9094\nv  2.4568 -1.3596 2.0047\nv  2.9037 -1.3824 2.3683\nv  2.8815 -1.5515 2.5299\nv  2.4405 -1.5278 2.1748\nv  3.3859 -1.4087 2.7807\nv  3.3569 -1.5790 2.9333\nv  3.3297 -1.7477 3.1043\nv  2.8618 -1.7196 2.7113\nv  2.4270 -1.6955 2.3656\nv  4.4226 -1.4693 3.7236\nv  4.3778 -1.6424 3.8566\nv  3.8584 -1.6095 3.3778\nv  3.8950 -1.4379 3.2349\nv  4.3327 -1.8127 4.0050\nv  3.8227 -1.7789 3.5378\nv  3.7879 -1.9459 3.7149\nv  4.2877 -1.9799 4.1693\nv  3.3043 -1.9146 3.2937\nv  2.4165 -1.8625 2.5770\nv  2.8445 -1.8865 2.9123\nv  4.9601 -1.5020 4.2395\nv  4.9066 -1.6769 4.3625\nv  5.4990 -1.5354 4.7755\nv  5.4367 -1.7123 4.8885\nv  5.3717 -1.8848 5.0140\nv  4.8517 -1.8482 4.4994\nv  6.5476 -1.6012 5.8786\nv  6.4674 -1.7824 5.9729\nv  5.9597 -1.7477 5.4277\nv  6.0310 -1.5687 5.3243\nv  6.3821 -1.9582 6.0770\nv  5.8845 -1.9217 5.5421\nv  5.8058 -2.0909 5.6684\nv  6.2921 -2.1287 6.1919\nv  5.3044 -2.0531 5.1525\nv  4.7958 -2.0159 4.6507\nv  8.5187 -3.1028 14.6532\nv  8.6327 -3.0268 14.7425\nv  8.4663 -3.0743 15.0557\nv  8.3736 -3.1607 14.8222\nv  8.7831 -2.9151 14.8571\nv  8.5961 -2.9620 15.2403\nv  8.3571 -3.0249 15.5908\nv  8.2430 -3.1428 15.3407\nv  8.1557 -3.2385 15.0437\nv  9.1079 -2.6279 15.0921\nv  8.8912 -2.6738 15.5636\nv  8.7407 -2.8275 15.4092\nv  8.9442 -2.7810 14.9756\nv  8.6228 -2.7308 16.0010\nv  8.4865 -2.8870 15.8087\nv  7.9530 -2.8646 16.7607\nv  7.8466 -3.0283 16.4985\nv  8.1867 -2.9553 16.1723\nv  8.3082 -2.7955 16.4011\nv  7.7467 -3.1746 16.2042\nv  8.0721 -3.0974 15.9129\nv  7.5863 -3.4099 15.5003\nv  7.8909 -3.3230 15.2749\nv  7.9713 -3.2204 15.6161\nv  7.6582 -3.3021 15.8731\nv  9.2662 -2.4590 15.2008\nv  9.0386 -2.5036 15.7044\nv  9.4168 -2.2761 15.3021\nv  9.1800 -2.3188 15.8329\nv  8.8886 -2.3704 16.3309\nv  8.7579 -2.5580 16.1744\nv  9.6853 -1.8754 15.4850\nv  9.4334 -1.9127 16.0587\nv  9.3125 -2.1212 15.9506\nv  9.5573 -2.0810 15.3967\nv  9.1241 -1.9574 16.6008\nv  9.0117 -2.1696 16.4724\nv  8.3588 -2.0604 17.5630\nv  8.2669 -2.2813 17.3943\nv  8.6610 -2.2237 16.9558\nv  8.7637 -2.0073 17.1046\nv  8.1665 -2.4898 17.2061\nv  8.5487 -2.4282 16.7905\nv  8.4300 -2.6193 16.6064\nv  8.0607 -2.6847 16.9957\nv  6.4231 -2.2604 18.8041\nv  6.3812 -2.4986 18.5721\nv  6.8865 -2.4509 18.3769\nv  6.9415 -2.2165 18.5966\nv  6.3355 -2.7224 18.3131\nv  6.8263 -2.6713 18.1313\nv  7.2992 -2.6139 17.8822\nv  7.3734 -2.3972 18.1112\nv  7.4412 -2.1671 18.3160\nv  6.2408 -3.1238 17.7093\nv  6.7005 -3.0668 17.5558\nv  6.7635 -2.8770 17.8581\nv  6.2880 -2.9311 18.0260\nv  7.1431 -3.0029 17.3432\nv  7.2214 -2.8161 17.6269\nv  7.6558 -2.7512 17.3376\nv  7.5626 -2.9346 17.0764\nv  7.7479 -2.5525 17.5719\nv  7.9158 -2.1143 17.9691\nv  7.8356 -2.3399 17.7816\nv  6.1962 -3.2996 17.3619\nv  6.6401 -3.2401 17.2227\nv  6.1561 -3.4577 16.9824\nv  6.5847 -3.3957 16.8571\nv  6.9968 -3.3262 16.6819\nv  7.0672 -3.1733 17.0289\nv  6.0984 -3.7174 16.1225\nv  6.4994 -3.6504 16.0219\nv  6.5370 -3.5327 16.4574\nv  6.1228 -3.5972 16.5697\nv  6.8848 -3.5755 15.8803\nv  6.9349 -3.4606 16.2998\nv  7.3107 -3.3830 16.1030\nv  7.2490 -3.4947 15.7043\nv  7.3861 -3.2516 16.4624\nv  7.4714 -3.1018 16.7858\nv  2.8011 -2.8484 4.5222\nv  2.4203 -2.8312 4.2609\nv  3.2007 -2.8685 4.8188\nv  3.1942 -3.0175 5.1377\nv  2.8056 -2.9996 4.8565\nv  2.4332 -2.9841 4.6084\nv  4.0340 -2.9169 5.5049\nv  3.6136 -2.8914 5.1476\nv  3.9983 -3.0607 5.7877\nv  3.5935 -3.0379 5.4491\nv  3.9430 -3.3328 6.4017\nv  3.5698 -3.3172 6.1055\nv  3.5785 -3.1801 5.7685\nv  3.9675 -3.1996 6.0869\nv  3.1970 -3.3032 5.8312\nv  3.1926 -3.1626 5.4752\nv  2.4720 -3.2791 5.3598\nv  2.4503 -3.1336 4.9747\nv  2.8148 -3.1471 5.2097\nv  2.8294 -3.2905 5.5818\nv  4.4563 -2.9451 5.8873\nv  4.8747 -2.9757 6.2915\nv  4.8033 -3.1140 6.5349\nv  4.4033 -3.0861 6.1505\nv  5.6775 -3.0442 7.1512\nv  5.2837 -3.0088 6.7139\nv  5.5670 -3.1781 7.3578\nv  5.1929 -3.1446 6.9382\nv  5.3456 -3.4203 7.7821\nv  5.0170 -3.3926 7.4072\nv  5.1036 -3.2730 7.1706\nv  5.4561 -3.3040 7.5698\nv  4.6708 -3.3694 7.0524\nv  4.7348 -3.2456 6.7894\nv  4.3545 -3.2213 6.4277\nv  4.3114 -3.3498 6.7173\nv  4.9681 -3.7460 8.4781\nv  4.7961 -3.7588 8.3644\nv  4.8073 -3.6843 8.1100\nv  5.0384 -3.6941 8.3553\nv  4.5514 -3.7736 8.2051\nv  4.5434 -3.6857 7.8898\nv  4.5680 -3.5895 7.5988\nv  4.8624 -3.5994 7.8789\nv  5.1329 -3.6176 8.1836\nv  3.9599 -3.7982 7.8332\nv  3.9312 -3.6924 7.4451\nv  4.2487 -3.6891 7.6674\nv  4.2691 -3.7871 8.0251\nv  3.9212 -3.5794 7.0786\nv  4.2527 -3.5836 7.3330\nv  4.2755 -3.4705 7.0177\nv  3.9263 -3.4594 6.7316\nv  4.6128 -3.4840 7.3209\nv  5.2367 -3.5256 7.9896\nv  4.9344 -3.5018 7.6440\nv  3.6341 -3.8059 7.6380\nv  3.5989 -3.6936 7.2252\nv  3.2971 -3.8107 7.4452\nv  3.2573 -3.6930 7.0126\nv  3.2281 -3.5689 6.5996\nv  3.5779 -3.5744 6.8329\nv  2.6116 -3.8135 7.0886\nv  2.5681 -3.6879 6.6281\nv  2.9119 -3.6910 6.8119\nv  2.9545 -3.8131 7.2601\nv  2.5305 -3.5567 6.1865\nv  2.8772 -3.5629 6.3828\nv  2.8500 -3.4293 5.9728\nv  2.4986 -3.4203 5.7637\nv  3.2084 -3.4388 6.2059\nv  3.5689 -3.4488 6.4599\nv  2.9783 -4.4564 11.3096\nv  3.3597 -4.4271 11.4173\nv  3.3738 -4.4357 11.9872\nv  2.9889 -4.4662 11.8794\nv  3.7418 -4.3927 11.5225\nv  3.7600 -4.4004 12.0909\nv  3.7637 -4.3905 12.6640\nv  3.3743 -4.4257 12.5597\nv  2.9872 -4.4566 12.4497\nv  4.4994 -4.3066 11.7056\nv  4.5281 -4.3133 12.2676\nv  4.1455 -4.3597 12.1859\nv  4.1224 -4.3526 11.6203\nv  4.5405 -4.3045 12.8378\nv  4.1531 -4.3502 12.7582\nv  4.5274 -4.2385 13.9791\nv  4.1315 -4.2803 13.8994\nv  4.1477 -4.3238 13.3312\nv  4.5394 -4.2798 13.4104\nv  3.7354 -4.3172 13.8024\nv  3.7548 -4.3628 13.2363\nv  2.9518 -4.3796 13.5730\nv  2.9744 -4.4277 13.0159\nv  3.3630 -4.3972 13.1298\nv  3.3415 -4.3501 13.6922\nv  4.8705 -4.2540 11.7735\nv  4.9057 -4.2607 12.3313\nv  5.2336 -4.1946 11.8192\nv  5.2762 -4.2013 12.3723\nv  5.3008 -4.1946 12.9362\nv  4.9238 -4.2528 12.8986\nv  5.9272 -4.0533 11.8236\nv  5.9874 -4.0606 12.3680\nv  5.6375 -4.1348 12.3861\nv  5.5866 -4.1279 11.8375\nv  6.0277 -4.0563 12.9239\nv  5.6695 -4.1293 12.9461\nv  6.0662 -4.0079 14.0432\nv  5.6926 -4.0766 14.0737\nv  5.6865 -4.1102 13.5108\nv  6.0525 -4.0391 13.4846\nv  5.3102 -4.1374 14.0704\nv  5.3109 -4.1736 13.5043\nv  4.9279 -4.2299 13.4695\nv  4.9211 -4.1911 14.0375\nv  5.6874 -3.7745 16.1757\nv  5.6852 -3.8773 15.6858\nv  6.0849 -3.8173 15.6395\nv  5.2696 -3.8229 16.1861\nv  5.2783 -3.9288 15.6923\nv  5.2903 -4.0159 15.1708\nv  5.6880 -3.9612 15.1678\nv  6.0780 -3.8982 15.1274\nv  4.4256 -3.8988 16.0976\nv  4.4537 -4.0108 15.6034\nv  4.8669 -3.9729 15.6634\nv  4.8480 -3.8640 16.1585\nv  4.4819 -4.1045 15.0817\nv  4.8874 -4.0633 15.1407\nv  4.9065 -4.1358 14.5967\nv  4.5073 -4.1802 14.5382\nv  5.3021 -4.0851 14.6280\nv  6.0732 -3.9613 14.5931\nv  5.6918 -4.0272 14.6282\nv  4.0055 -3.9285 16.0080\nv  4.0415 -4.0436 15.5169\nv  3.5907 -3.9545 15.8946\nv  3.6331 -4.0724 15.4083\nv  3.6726 -4.1721 14.8938\nv  4.0761 -4.1404 14.9980\nv  2.7895 -3.9997 15.6150\nv  2.8383 -4.1225 15.1421\nv  3.2311 -4.0983 15.2819\nv  3.1844 -3.9778 15.7620\nv  2.8824 -4.2268 14.6410\nv  3.2739 -4.2006 14.7734\nv  3.3112 -4.2845 14.2418\nv  2.9207 -4.3126 14.1163\nv  3.7074 -4.2537 14.3567\nv  4.1068 -4.2192 14.4569\nv  8.1561 -3.1655 10.9419\nv  8.3775 -3.0187 10.8369\nv  8.5367 -3.0301 11.3901\nv  8.3060 -3.1768 11.4884\nv  8.5869 -2.8641 10.7474\nv  8.7543 -2.8754 11.3087\nv  8.8817 -2.8813 11.8725\nv  8.6581 -3.0353 11.9445\nv  8.4206 -3.1812 12.0356\nv  8.9687 -2.5322 10.6088\nv  9.1498 -2.5428 11.1894\nv  8.9587 -2.7129 11.2424\nv  8.7840 -2.7019 10.6719\nv  9.2871 -2.5494 11.7764\nv  9.0914 -2.7193 11.8173\nv  9.4252 -2.5587 12.9439\nv  9.2280 -2.7250 12.9502\nv  9.1814 -2.7228 12.3891\nv  9.3793 -2.5541 12.3634\nv  9.0170 -2.8823 12.9725\nv  8.9693 -2.8831 12.4301\nv  8.5514 -3.1708 13.0897\nv  8.5018 -3.1790 12.5729\nv  8.7428 -3.0352 12.4901\nv  8.7916 -3.0308 13.0170\nv  9.1408 -2.3550 10.5567\nv  9.3275 -2.3651 11.1480\nv  9.3001 -2.1705 10.5140\nv  9.4917 -2.1799 11.1163\nv  9.6366 -2.1864 11.7281\nv  9.4689 -2.3717 11.7474\nv  9.5800 -1.7800 10.4510\nv  9.7791 -1.7878 11.0749\nv  9.6423 -1.9875 11.0925\nv  9.4466 -1.9788 10.4793\nv  9.9294 -1.7935 11.7108\nv  9.7901 -1.9936 11.7166\nv  10.0749 -1.8050 12.9975\nv  9.9341 -2.0057 12.9765\nv  9.8881 -1.9991 12.3463\nv  10.0287 -1.7987 12.3534\nv  9.7786 -2.1985 12.9591\nv  9.7329 -2.1919 12.3442\nv  9.5632 -2.3770 12.3491\nv  9.6089 -2.3830 12.9475\nv  9.7398 -2.0511 14.8171\nv  9.8732 -1.8477 14.8869\nv  9.5931 -2.2448 14.7442\nv  9.7108 -2.2229 14.1643\nv  9.8621 -2.0299 14.2171\nv  9.9994 -1.8278 14.2695\nv  9.2671 -2.5966 14.5900\nv  9.4349 -2.4272 14.6684\nv  9.3715 -2.5768 14.0616\nv  9.5468 -2.4056 14.1121\nv  9.6041 -2.3917 13.5368\nv  9.4234 -2.5652 13.5114\nv  9.7720 -2.2081 13.5675\nv  10.0659 -1.8142 13.6379\nv  9.9262 -2.0153 13.6018\nv  9.0917 -2.7517 14.5093\nv  8.9125 -2.8907 14.4366\nv  8.9909 -2.8815 13.9807\nv  9.1861 -2.7353 14.0138\nv  8.5459 -3.1197 14.3913\nv  8.7337 -3.0121 14.3826\nv  8.5677 -3.1394 14.0145\nv  8.7858 -3.0156 13.9741\nv  8.8055 -3.0231 13.5153\nv  8.5715 -3.1570 13.5754\nv  9.0249 -2.8803 13.4910\nv  9.2306 -2.7278 13.4929\nv  5.6986 -3.6517 16.6309\nv  5.7172 -3.5097 17.0524\nv  5.2719 -3.5530 17.0725\nv  5.2678 -3.6975 16.6459\nv  5.7700 -3.1711 17.7984\nv  5.7416 -3.3492 17.4412\nv  5.2930 -3.2099 17.8300\nv  5.2806 -3.3903 17.4669\nv  4.3400 -3.2669 17.7473\nv  4.3575 -3.4514 17.3820\nv  4.8178 -3.4239 17.4452\nv  4.8147 -3.2415 17.8107\nv  4.3775 -3.6185 16.9859\nv  4.8240 -3.5889 17.0485\nv  4.8339 -3.7358 16.6199\nv  4.4002 -3.7678 16.5581\nv  5.8010 -2.9760 18.1250\nv  5.8328 -2.7647 18.4221\nv  5.3242 -2.7991 18.4658\nv  5.3079 -3.0126 18.1627\nv  5.8926 -2.2966 18.9314\nv  5.8639 -2.5380 18.6905\nv  5.3565 -2.3259 18.9873\nv  5.3407 -2.5700 18.7404\nv  4.2942 -2.3673 18.9192\nv  4.3021 -2.6155 18.6678\nv  4.8180 -2.5955 18.7301\nv  4.8215 -2.3493 18.9803\nv  4.3124 -2.8485 18.3893\nv  4.8154 -2.8267 18.4523\nv  4.8141 -3.0422 18.1462\nv  4.3249 -3.0658 18.0828\nv  2.3953 -2.4038 18.3064\nv  2.4321 -2.6580 18.0648\nv  2.8580 -2.6511 18.2520\nv  2.8253 -2.3984 18.4975\nv  2.4752 -2.8977 17.7985\nv  2.8965 -2.8890 17.9813\nv  3.3471 -2.8786 18.1459\nv  3.3158 -2.6424 18.4205\nv  3.2895 -2.3911 18.6692\nv  2.5749 -3.3311 17.1871\nv  2.9863 -3.3183 17.3597\nv  2.9397 -3.1116 17.6843\nv  2.5233 -3.1222 17.5063\nv  3.4208 -3.3042 17.5151\nv  3.3823 -3.0994 17.8445\nv  3.8459 -3.0845 17.9798\nv  3.8737 -3.2875 17.6465\nv  3.8210 -2.8654 18.2845\nv  3.7813 -2.3810 18.8126\nv  3.7993 -2.6308 18.5618\nv  2.6287 -3.5238 16.8395\nv  3.0352 -3.5088 17.0063\nv  2.6833 -3.6998 16.4625\nv  3.0853 -3.6826 16.6231\nv  3.5042 -3.6641 16.7676\nv  3.4617 -3.4926 17.1565\nv  3.1354 -3.8390 16.2087\nv  2.7373 -3.8586 16.0547\nv  3.5475 -3.8182 16.3474\nv  3.9703 -3.7949 16.4655\nv  3.9363 -3.6431 16.8904\nv  3.9040 -3.4738 17.2838\nv  6.4746 -3.7476 15.5490\nv  6.4578 -3.8258 15.0455\nv  6.8237 -3.7453 14.9293\nv  6.8496 -3.6699 15.4211\nv  6.4286 -3.9305 13.9749\nv  6.4441 -3.8864 14.5185\nv  6.7785 -3.8449 13.8761\nv  6.8018 -3.8032 14.4119\nv  7.4348 -3.6503 13.6167\nv  7.4681 -3.6148 14.1318\nv  7.1440 -3.7124 14.2806\nv  7.1144 -3.7514 13.7542\nv  7.4992 -3.5642 14.6224\nv  7.1721 -3.6578 14.7858\nv  7.2049 -3.5857 15.2628\nv  7.5359 -3.4966 15.0810\nv  6.4066 -3.9597 13.4216\nv  6.3733 -3.9752 12.8654\nv  6.7061 -3.8860 12.7776\nv  6.7483 -3.8721 13.3290\nv  6.2532 -3.9706 11.7725\nv  6.3238 -3.9784 12.3134\nv  6.5651 -3.8797 11.6909\nv  6.6467 -3.8881 12.2292\nv  7.1475 -3.6737 11.4637\nv  7.2526 -3.6833 11.9995\nv  6.9563 -3.7897 12.1223\nv  6.8631 -3.7807 11.5857\nv  7.3321 -3.6834 12.5424\nv  7.0258 -3.7887 12.6676\nv  7.0767 -3.7764 13.2141\nv  7.3911 -3.6728 13.0842\nv  8.0623 -3.3155 11.6054\nv  7.9227 -3.3044 11.0638\nv  8.1691 -3.3189 12.1484\nv  7.9039 -3.4485 12.2754\nv  7.8055 -3.4462 11.7342\nv  7.6770 -3.4355 11.1959\nv  8.2961 -3.3025 13.1966\nv  8.2461 -3.3146 12.6823\nv  8.0252 -3.4261 13.3272\nv  7.9758 -3.4420 12.8097\nv  7.6908 -3.5613 12.9465\nv  7.7382 -3.5420 13.4708\nv  7.6248 -3.5700 12.4092\nv  7.4187 -3.5586 11.3315\nv  7.5357 -3.5687 11.8679\nv  8.3220 -3.2826 13.6810\nv  8.3334 -3.2544 14.1221\nv  8.0792 -3.3625 14.2738\nv  8.0558 -3.4004 13.8182\nv  8.3399 -3.2172 14.5068\nv  8.1068 -3.3102 14.6852\nv  7.8377 -3.4040 14.8825\nv  7.8014 -3.4658 14.4461\nv  7.7716 -3.5110 13.9731\nv  6.9033 -0.0124 5.4959\nv  7.4253 -0.0130 6.0802\nv  7.4180 -0.2228 6.0864\nv  6.8964 -0.2179 5.5026\nv  7.9192 -0.0138 6.6660\nv  7.9115 -0.2273 6.6716\nv  7.8894 -0.4403 6.6880\nv  7.3970 -0.4319 6.1045\nv  6.8766 -0.4229 5.5221\nv  8.8104 -0.0154 7.8529\nv  8.8020 -0.2354 7.8571\nv  8.3739 -0.2316 7.2609\nv  8.3820 -0.0146 7.2559\nv  8.7777 -0.4549 7.8696\nv  8.3507 -0.4480 7.2754\nv  8.6849 -0.8890 7.9184\nv  8.2621 -0.8760 7.3316\nv  8.3131 -0.6631 7.2991\nv  8.7384 -0.6730 7.8901\nv  7.8055 -0.8615 6.7510\nv  7.8537 -0.6520 6.7146\nv  6.8029 -0.8283 5.5975\nv  6.8451 -0.6265 5.5539\nv  7.3634 -0.6398 6.1338\nv  7.3181 -0.8455 6.1739\nv  9.2012 -0.0161 8.4596\nv  9.1925 -0.2387 8.4631\nv  9.5512 -0.0167 9.0789\nv  9.5423 -0.2415 9.0815\nv  9.5163 -0.4660 9.0895\nv  9.1673 -0.4609 8.4734\nv  10.1165 -0.0172 10.3664\nv  10.1072 -0.2454 10.3671\nv  9.8483 -0.2438 9.7153\nv  9.8574 -0.0171 9.7135\nv  10.0801 -0.4733 10.3699\nv  9.8217 -0.4701 9.7207\nv  9.9751 -0.9241 10.3828\nv  9.7188 -0.9180 9.7436\nv  9.7782 -0.6952 9.7300\nv  10.0359 -0.6998 10.3749\nv  9.4162 -0.9101 9.1216\nv  9.4741 -0.6892 9.1028\nv  9.1264 -0.6817 8.4904\nv  9.0706 -0.9004 8.5141\nv  9.3343 -1.7682 9.8441\nv  9.4510 -1.5637 9.8115\nv  9.7003 -1.5741 10.4276\nv  9.0449 -1.7528 9.2521\nv  9.1572 -1.5501 9.2110\nv  9.2570 -1.3415 9.1756\nv  9.5544 -1.3532 9.7841\nv  9.8066 -1.3622 10.4087\nv  8.3460 -1.7124 8.1029\nv  8.4477 -1.5144 8.0466\nv  8.8218 -1.5336 8.6235\nv  8.7145 -1.7341 8.6725\nv  8.5387 -1.3105 7.9968\nv  8.9175 -1.3272 8.5808\nv  9.0007 -1.1158 8.5442\nv  8.6180 -1.1018 7.9540\nv  9.3436 -1.1279 9.1458\nv  9.8984 -1.1453 10.3940\nv  9.6439 -1.1377 9.7615\nv  7.9422 -1.6880 7.5411\nv  8.0378 -1.4926 7.4776\nv  7.5060 -1.6611 6.9847\nv  7.5950 -1.4686 6.9141\nv  7.6752 -1.2706 6.8512\nv  8.1236 -1.2916 7.4212\nv  6.6223 -1.4145 5.7934\nv  7.1222 -1.4425 6.3535\nv  7.0402 -1.6321 6.4313\nv  6.6904 -1.2229 5.7178\nv  7.1965 -1.2476 6.2843\nv  7.2621 -1.0484 6.2243\nv  6.7510 -1.0273 5.6523\nv  7.7457 -1.0679 6.7967\nv  8.1987 -1.0858 7.3724\nv  2.3568 -3.8782 15.8904\nv  2.4091 -4.0213 15.4582\nv  2.3022 -3.7171 16.2914\nv  1.9394 -3.7338 16.1176\nv  1.9917 -3.8971 15.7235\nv  2.0413 -4.0422 15.2988\nv  2.1916 -3.3436 17.0040\nv  2.2466 -3.5387 16.6622\nv  1.8329 -3.3555 16.8186\nv  1.8859 -3.5530 16.4823\nv  1.1751 -3.3762 16.4736\nv  1.2166 -3.5785 16.1471\nv  1.5436 -3.5665 16.3079\nv  1.4952 -3.3665 16.6390\nv  1.2581 -3.7636 15.7933\nv  1.5922 -3.7495 15.9490\nv  1.3367 -4.0788 15.0011\nv  1.6845 -4.0615 15.1441\nv  1.6396 -3.9148 15.5613\nv  1.2986 -3.9307 15.4115\nv  2.1386 -3.1323 17.3179\nv  2.0890 -2.9056 17.6052\nv  1.7335 -2.9127 17.4100\nv  1.7816 -3.1418 17.1275\nv  2.0064 -2.4080 18.1043\nv  2.0445 -2.6640 17.8670\nv  1.6532 -2.4112 17.9003\nv  1.6903 -2.6689 17.6673\nv  1.0339 -2.4151 17.5216\nv  1.0631 -2.6763 17.2969\nv  1.3648 -2.6731 17.4744\nv  1.3308 -2.4135 17.7031\nv  1.0972 -2.9242 17.0478\nv  1.4044 -2.9189 17.2214\nv  1.4483 -3.1503 16.9432\nv  1.1349 -3.1578 16.7736\nv  0.2538 -2.6815 16.9434\nv  0.2457 -2.4169 17.1601\nv  0.2633 -2.9334 16.7019\nv  0.5310 -2.9315 16.7796\nv  0.5124 -2.6805 17.0227\nv  0.4965 -2.4167 17.2412\nv  0.2850 -3.3947 16.1433\nv  0.2738 -3.1716 16.4353\nv  0.5735 -3.3906 16.2175\nv  0.5516 -3.1686 16.5113\nv  0.8373 -3.1640 16.6268\nv  0.8690 -3.3844 16.3303\nv  0.8075 -2.9284 16.8977\nv  0.7575 -2.4162 17.3647\nv  0.7806 -2.6788 17.1434\nv  0.2965 -3.6014 15.8255\nv  0.3080 -3.7907 15.4818\nv  0.6186 -3.7847 15.5519\nv  0.5961 -3.5964 15.8979\nv  0.3296 -4.1117 14.7150\nv  0.3192 -3.9612 15.1117\nv  0.6611 -4.1045 14.7794\nv  0.6405 -3.9545 15.1792\nv  0.9663 -3.9441 15.2817\nv  0.9962 -4.0933 14.8772\nv  0.9344 -3.7755 15.6583\nv  0.9017 -3.5886 16.0077\nv  2.0640 -2.8169 4.0386\nv  2.0495 -2.6598 3.6996\nv  2.0822 -2.9710 4.3963\nv  1.7499 -2.9602 4.2185\nv  1.7293 -2.8053 3.8530\nv  1.7119 -2.6474 3.5061\nv  2.1298 -3.2690 5.1680\nv  2.1041 -3.1219 4.7728\nv  1.8009 -3.2601 5.0054\nv  1.7738 -3.1119 4.6026\nv  1.1753 -3.2462 4.7631\nv  1.1521 -3.0971 4.3515\nv  1.4572 -3.1037 4.4627\nv  1.4833 -3.2525 4.8708\nv  1.1309 -2.9447 3.9582\nv  1.4337 -2.9515 4.0731\nv  1.0953 -2.6307 3.2265\nv  1.3950 -2.6378 3.3492\nv  1.4129 -2.7961 3.7019\nv  1.1119 -2.7891 3.5833\nv  2.1595 -3.4120 5.5820\nv  2.1934 -3.5505 6.0146\nv  1.8646 -3.5443 5.8668\nv  1.8312 -3.4043 5.4268\nv  2.2739 -3.8124 6.9360\nv  2.2315 -3.6841 6.4660\nv  1.9407 -3.8102 6.8028\nv  1.9011 -3.6797 6.3255\nv  1.2852 -3.8040 6.5957\nv  1.2555 -3.6708 6.1094\nv  1.5760 -3.6752 6.2066\nv  1.6113 -3.8073 6.6893\nv  1.2272 -3.5332 5.6420\nv  1.5429 -3.5385 5.7427\nv  1.5119 -3.3975 5.2974\nv  1.2004 -3.3916 5.1933\nv  0.3116 -3.6614 5.9475\nv  0.3197 -3.7960 6.4376\nv  0.3038 -3.5230 5.4765\nv  0.6088 -3.5252 5.5092\nv  0.6242 -3.6635 5.9798\nv  0.6400 -3.7980 6.4696\nv  0.2891 -3.2355 4.5909\nv  0.2963 -3.3810 5.0244\nv  0.5801 -3.2376 4.6243\nv  0.5941 -3.3832 5.0574\nv  0.8949 -3.3868 5.1135\nv  0.8748 -3.2412 4.6813\nv  0.9162 -3.5287 5.5643\nv  0.9616 -3.8008 6.5223\nv  0.9385 -3.6668 6.0338\nv  0.2823 -3.0866 4.1759\nv  0.2760 -2.9344 3.7790\nv  0.5547 -2.9363 3.8130\nv  0.5669 -3.0886 4.2095\nv  0.2652 -2.6209 3.0386\nv  0.2703 -2.7792 3.4000\nv  0.5339 -2.6225 3.0737\nv  0.5437 -2.7809 3.4345\nv  0.8232 -2.7842 3.4948\nv  0.8094 -2.6257 3.1355\nv  0.8388 -2.9397 3.8722\nv  0.8561 -3.0921 4.2676\nv  2.6076 -4.4923 11.7721\nv  2.5998 -4.4810 11.2043\nv  2.6044 -4.4836 12.3383\nv  2.2253 -4.5067 12.2294\nv  2.2294 -4.5143 11.6685\nv  2.2237 -4.5012 11.1042\nv  2.5686 -4.4066 13.4490\nv  2.5910 -4.4549 12.8988\nv  2.1911 -4.4308 13.3250\nv  2.2123 -4.4788 12.7829\nv  1.4499 -4.4697 13.0977\nv  1.4660 -4.5162 12.5725\nv  1.8375 -4.4993 12.6727\nv  1.8185 -4.4519 13.2063\nv  1.4764 -4.5419 12.0341\nv  1.8495 -4.5261 12.1267\nv  1.4777 -4.5299 10.9304\nv  1.8498 -4.5174 11.0120\nv  1.8538 -4.5322 11.5720\nv  1.4804 -4.5465 11.4856\nv  2.5382 -4.3388 13.9844\nv  2.5008 -4.2519 14.5007\nv  2.1276 -4.2753 14.3589\nv  2.1626 -4.3628 13.8517\nv  2.4574 -4.1460 14.9935\nv  2.0869 -4.1683 14.8426\nv  1.3714 -4.2069 14.5613\nv  1.7254 -4.1888 14.6963\nv  1.4021 -4.3149 14.0953\nv  1.7618 -4.2964 14.2217\nv  1.7931 -4.3842 13.7238\nv  1.4285 -4.4025 13.6063\nv  0.3391 -4.2410 14.2913\nv  0.3475 -4.3490 13.8432\nv  0.6962 -4.3417 13.8998\nv  0.6797 -4.2336 14.3521\nv  0.3605 -4.5011 12.8832\nv  0.3546 -4.4357 13.3730\nv  0.7217 -4.4945 12.9311\nv  0.7103 -4.4287 13.4253\nv  1.0679 -4.4175 13.5050\nv  1.0846 -4.4840 13.0043\nv  1.0473 -4.3301 13.9859\nv  1.0233 -4.2220 14.4443\nv  0.3649 -4.5450 12.3761\nv  0.3677 -4.5676 11.8543\nv  0.7360 -4.5625 11.8941\nv  0.7304 -4.5392 12.4198\nv  0.3685 -4.5484 10.7762\nv  0.3690 -4.5687 11.3202\nv  0.7374 -4.5450 10.8097\nv  0.7384 -4.5645 11.3565\nv  1.1088 -4.5571 11.4127\nv  1.1070 -4.5390 10.8620\nv  1.1054 -4.5540 11.9553\nv  1.0972 -4.5295 12.4867\nv  2.5821 -0.0108 1.3799\nv  2.5785 -0.1796 1.3893\nv  2.1545 -0.1767 1.0540\nv  2.1576 -0.0108 1.0442\nv  2.5690 -0.3484 1.4177\nv  2.1462 -0.3426 1.0838\nv  1.7640 -0.3380 0.8038\nv  1.7711 -0.1744 0.7726\nv  1.7738 -0.0108 0.7623\nv  2.5372 -0.6858 1.5329\nv  2.1189 -0.6747 1.2042\nv  2.1339 -0.5086 1.1337\nv  2.5548 -0.5171 1.4655\nv  1.7411 -0.6659 0.9297\nv  1.7537 -0.5018 0.8560\nv  1.0837 -0.6544 0.5301\nv  1.0918 -0.4930 0.4508\nv  1.4082 -0.4967 0.6294\nv  1.3979 -0.6592 0.7060\nv  1.0985 -0.3320 0.3942\nv  1.4168 -0.3345 0.5749\nv  1.1050 -0.0108 0.3491\nv  1.4249 -0.0108 0.5315\nv  1.4226 -0.1726 0.5423\nv  1.1032 -0.1713 0.3603\nv  2.5173 -0.8544 1.6202\nv  2.1022 -0.8410 1.2956\nv  2.4964 -1.0229 1.7277\nv  2.0850 -1.0075 1.4080\nv  1.7133 -0.9953 1.1419\nv  1.7273 -0.8304 1.0249\nv  2.0538 -1.3413 1.6973\nv  2.0685 -1.1742 1.5418\nv  2.4759 -1.1913 1.8558\nv  1.6892 -1.3269 1.4426\nv  1.7002 -1.1608 1.2811\nv  1.0530 -1.3080 1.0766\nv  1.0589 -1.1431 0.9055\nv  1.3656 -1.1505 1.0701\nv  1.3574 -1.3159 1.2369\nv  1.0665 -0.9793 0.7574\nv  1.3757 -0.9860 0.9262\nv  1.3868 -0.8223 0.8049\nv  1.0750 -0.8165 0.6323\nv  0.2507 -1.1335 0.6543\nv  0.2496 -1.2977 0.8333\nv  0.2524 -0.9706 0.4986\nv  0.5105 -0.9719 0.5469\nv  0.5071 -1.1350 0.7010\nv  0.5046 -1.2993 0.8784\nv  0.2565 -0.6481 0.2578\nv  0.2544 -0.8088 0.3663\nv  0.5187 -0.6491 0.3091\nv  0.5145 -0.8100 0.4163\nv  0.7861 -0.8125 0.5038\nv  0.7925 -0.6511 0.3988\nv  0.7800 -0.9747 0.6321\nv  0.7706 -1.3026 0.9583\nv  0.7746 -1.1380 0.7836\nv  0.2584 -0.4881 0.1730\nv  0.2601 -0.3287 0.1123\nv  0.5260 -0.3292 0.1658\nv  0.5227 -0.4889 0.2256\nv  0.2617 -0.0108 0.0635\nv  0.2613 -0.1696 0.0757\nv  0.5293 -0.0108 0.1178\nv  0.5283 -0.1699 0.1298\nv  0.8071 -0.1704 0.2238\nv  0.8084 -0.0108 0.2121\nv  0.8036 -0.3303 0.2588\nv  0.7985 -0.4904 0.3172\nv  0.3279 -3.9268 6.9472\nv  0.6562 -3.9284 6.9785\nv  0.6722 -4.0526 7.5036\nv  0.3360 -4.0515 7.4729\nv  1.3161 -3.9327 7.1008\nv  0.9854 -3.9305 7.0299\nv  1.3471 -4.0548 7.6221\nv  1.0092 -4.0539 7.5536\nv  1.4054 -4.2706 8.7017\nv  1.0533 -4.2728 8.6369\nv  1.0321 -4.1687 8.0903\nv  1.3772 -4.1681 8.1566\nv  0.7019 -4.2737 8.5889\nv  0.6876 -4.1684 8.0415\nv  0.3437 -4.1679 8.0113\nv  0.3508 -4.2738 8.5590\nv  1.6485 -3.9345 7.1907\nv  1.9833 -3.9354 7.2988\nv  2.0272 -4.0534 7.8112\nv  1.6863 -4.0548 7.7083\nv  2.6615 -3.9329 7.5678\nv  2.3208 -3.9350 7.4247\nv  2.7152 -4.0446 8.0643\nv  2.3701 -4.0502 7.9302\nv  2.8242 -4.2378 9.1019\nv  2.4675 -4.2507 8.9834\nv  2.4197 -4.1560 8.4504\nv  2.7703 -4.1468 8.5762\nv  2.1123 -4.2601 8.8763\nv  2.0708 -4.1623 8.3378\nv  1.7234 -4.1662 8.2395\nv  1.7584 -4.2666 8.7819\nv  2.5797 -4.4494 10.6397\nv  2.9540 -4.4270 10.7453\nv  2.2075 -4.4673 10.5406\nv  2.1824 -4.4146 9.9799\nv  2.5496 -4.3992 10.0800\nv  2.9186 -4.3796 10.1882\nv  1.4678 -4.4919 10.3715\nv  1.8369 -4.4814 10.4505\nv  1.4518 -4.4346 9.8119\nv  1.8165 -4.4262 9.8899\nv  1.7898 -4.3539 9.3329\nv  1.4306 -4.3601 9.2544\nv  2.1501 -4.3448 9.4244\nv  2.8745 -4.3160 9.6398\nv  2.5115 -4.3324 9.5272\nv  1.0999 -4.4993 10.3061\nv  0.7328 -4.5040 10.2563\nv  0.7249 -4.4437 9.6996\nv  1.0880 -4.4402 9.7478\nv  0.3662 -4.5065 10.2247\nv  0.3624 -4.4453 9.6691\nv  0.3571 -4.3670 9.1128\nv  0.7145 -4.3661 9.1427\nv  1.0722 -4.3640 9.1904\nv  3.0059 -3.9286 7.7275\nv  3.3489 -3.9216 7.8977\nv  3.4090 -4.0242 8.3690\nv  3.0630 -4.0361 8.2127\nv  4.0109 -3.8968 8.2452\nv  3.6856 -3.9111 8.0723\nv  4.0782 -3.9871 8.6799\nv  3.7489 -4.0080 8.5269\nv  4.2370 -4.1396 9.6135\nv  3.8920 -4.1725 9.4928\nv  3.8192 -4.0955 9.0007\nv  4.1556 -4.0683 9.1363\nv  3.5395 -4.1994 9.3630\nv  3.4738 -4.1172 8.8578\nv  3.1229 -4.1341 8.7142\nv  3.1826 -4.2209 9.2306\nv  4.3198 -3.8778 8.4102\nv  4.6042 -3.8541 8.5556\nv  4.6875 -3.9274 8.9396\nv  4.3926 -3.9606 8.8217\nv  5.0682 -3.7841 8.7140\nv  4.8558 -3.8251 8.6692\nv  5.2010 -3.8333 9.0472\nv  4.9583 -3.8859 9.0211\nv  5.4835 -3.9315 9.8566\nv  5.1974 -3.9971 9.8491\nv  5.0756 -3.9440 9.4169\nv  5.3422 -3.8836 9.4317\nv  4.8925 -4.0530 9.8003\nv  4.7869 -3.9940 9.3555\nv  4.4792 -4.0349 9.2583\nv  4.5714 -4.1001 9.7189\nv  5.5128 -4.1096 11.3068\nv  5.8426 -4.0356 11.2974\nv  5.1695 -4.1754 11.2831\nv  5.0883 -4.1447 10.7664\nv  5.4204 -4.0810 10.7967\nv  5.7378 -4.0087 10.7922\nv  4.4517 -4.2847 11.1578\nv  4.8151 -4.2336 11.2317\nv  4.3893 -4.2489 10.6257\nv  4.7438 -4.2005 10.7074\nv  4.6611 -4.1557 10.2026\nv  4.3163 -4.2002 10.1104\nv  4.9944 -4.1036 10.2714\nv  5.6168 -3.9736 10.3110\nv  5.3138 -4.0431 10.3099\nv  4.0817 -4.3291 11.0669\nv  3.7072 -4.3674 10.9643\nv  3.6597 -4.3258 10.4175\nv  4.0271 -4.2905 10.5271\nv  3.3306 -4.3998 10.8553\nv  3.2894 -4.3553 10.3026\nv  3.2390 -4.2952 9.7606\nv  3.6026 -4.2694 9.8833\nv  3.9626 -4.2379 10.0020\nv  5.2346 -3.7245 8.6532\nv  5.3767 -3.6481 8.5232\nv  5.5987 -3.6864 8.8958\nv  5.4113 -3.7665 8.9992\nv  5.6525 -3.4536 8.1772\nv  5.5157 -3.5573 8.3605\nv  5.9372 -3.4904 8.5921\nv  5.7726 -3.5941 8.7558\nv  6.4390 -3.5659 9.4788\nv  6.2230 -3.6720 9.6161\nv  6.0080 -3.6333 9.1746\nv  6.1994 -3.5285 9.0261\nv  5.9936 -3.7685 9.7309\nv  5.8042 -3.7277 9.2993\nv  5.5837 -3.8113 9.3887\nv  5.7480 -3.8552 9.8141\nv  5.7874 -3.3388 7.9854\nv  5.9203 -3.2144 7.7910\nv  6.2512 -3.2523 8.2377\nv  6.0967 -3.3760 8.4172\nv  6.1778 -2.9426 7.4179\nv  6.0505 -3.0818 7.5998\nv  6.5458 -2.9818 7.8904\nv  6.4009 -3.1205 8.0599\nv  7.2045 -3.0574 8.8656\nv  7.0261 -3.1959 9.0147\nv  6.7267 -3.1590 8.5316\nv  6.8887 -3.0205 8.3729\nv  6.8396 -3.3273 9.1712\nv  6.5581 -3.2904 8.6978\nv  6.3826 -3.4139 8.8649\nv  6.6442 -3.4508 9.3282\nv  7.7474 -3.2857 10.5340\nv  7.9689 -3.1468 10.4065\nv  7.5144 -3.4169 10.6704\nv  7.3194 -3.3919 10.1576\nv  7.5383 -3.2606 10.0159\nv  7.7466 -3.1217 9.8822\nv  7.0117 -3.6558 10.9429\nv  7.2693 -3.5403 10.8089\nv  6.8470 -3.6309 10.4380\nv  7.0893 -3.5154 10.3006\nv  6.8803 -3.4851 9.8069\nv  6.6555 -3.6005 9.9497\nv  7.0939 -3.3615 9.6579\nv  7.4911 -3.0916 9.3686\nv  7.2972 -3.2302 9.5095\nv  6.7408 -3.7631 11.0655\nv  6.4560 -3.8623 11.1699\nv  6.3225 -3.8371 10.6683\nv  6.5917 -3.7383 10.5629\nv  6.1568 -3.9532 11.2495\nv  6.0382 -3.9273 10.7471\nv  5.9007 -3.8943 10.2678\nv  6.1673 -3.8054 10.1879\nv  6.4184 -3.7074 10.0793\nv  6.0981 -1.3849 5.2312\nv  5.5585 -1.3543 4.6743\nv  5.6137 -1.1694 4.5854\nv  6.1599 -1.1966 5.1490\nv  4.4668 -1.2932 3.6058\nv  5.0118 -1.3235 4.1301\nv  4.5093 -1.1147 3.5034\nv  5.0606 -1.1419 4.0344\nv  4.5838 -0.7515 3.3449\nv  5.1446 -0.7709 3.8853\nv  5.1053 -0.9575 3.9527\nv  4.5487 -0.9340 3.4164\nv  5.7073 -0.7905 4.4458\nv  5.6637 -0.9813 4.5091\nv  6.2152 -1.0047 5.0781\nv  6.2630 -0.8097 5.0190\nv  3.9321 -1.2642 3.1089\nv  3.4163 -1.2370 2.6467\nv  3.4469 -1.0641 2.5311\nv  3.9685 -1.0886 2.9998\nv  2.9280 -1.2125 2.2266\nv  2.9533 -1.0420 2.1046\nv  3.0016 -0.6995 1.9186\nv  2.9783 -0.8710 2.0020\nv  3.5035 -0.7154 2.3542\nv  3.4764 -0.8902 2.4336\nv  4.0028 -0.9114 2.9075\nv  4.0339 -0.7329 2.8321\nv  3.0531 -0.0108 1.7723\nv  3.0491 -0.1832 1.7813\nv  3.5618 -0.0108 2.2141\nv  3.5573 -0.1874 2.2228\nv  3.5452 -0.3638 2.2489\nv  3.0383 -0.3555 1.8085\nv  4.6561 -0.0110 3.2169\nv  4.6508 -0.1970 3.2250\nv  4.0942 -0.1920 2.7064\nv  4.0990 -0.0109 2.6981\nv  4.6361 -0.3827 3.2491\nv  4.0808 -0.3729 2.7315\nv  4.0603 -0.5533 2.7734\nv  4.6134 -0.5676 3.2891\nv  3.5269 -0.5398 2.2927\nv  3.0221 -0.5276 1.8542\nv  5.2239 -0.0112 3.7633\nv  5.2182 -0.2022 3.7711\nv  5.7937 -0.0115 4.3302\nv  5.7876 -0.2075 4.3376\nv  5.7704 -0.4030 4.3596\nv  5.2023 -0.3928 3.7942\nv  6.3499 -0.2128 4.9172\nv  6.3565 -0.0119 4.9101\nv  6.3314 -0.4131 4.9380\nv  6.3021 -0.6123 4.9721\nv  5.7432 -0.5975 4.3958\nv  5.1773 -0.5825 3.8323\nv  6.9887 -1.9692 18.7921\nv  6.4590 -2.0087 19.0103\nv  7.4996 -1.9247 18.4985\nv  7.5490 -1.6714 18.6584\nv  7.0284 -1.7105 18.9630\nv  6.4892 -1.7452 19.1904\nv  8.4386 -1.8284 17.7148\nv  7.9852 -1.8771 18.1370\nv  8.5068 -1.5867 17.8488\nv  8.0441 -1.6295 18.2844\nv  8.6094 -1.0799 18.0605\nv  8.1322 -1.1095 18.5159\nv  8.0930 -1.3732 18.4109\nv  8.5636 -1.3368 17.9643\nv  7.6223 -1.1385 18.9080\nv  7.5898 -1.4088 18.7951\nv  6.5335 -1.1896 19.4706\nv  6.5139 -1.4716 19.3440\nv  7.0611 -1.4421 19.1087\nv  7.0870 -1.1656 19.2290\nv  8.8533 -1.7805 17.2394\nv  9.2227 -1.7354 16.7181\nv  9.3076 -1.5049 16.8233\nv  8.9302 -1.5446 17.3592\nv  9.7984 -1.6612 15.5677\nv  9.5399 -1.6950 16.1585\nv  9.8965 -1.4395 15.6435\nv  9.6319 -1.4693 16.2488\nv  10.0476 -0.9778 15.7693\nv  9.7731 -0.9985 16.3964\nv  9.7097 -1.2368 16.3285\nv  9.9796 -1.2113 15.7111\nv  9.4371 -1.0232 16.9927\nv  9.3790 -1.2671 16.9151\nv  8.9946 -1.3009 17.4630\nv  9.0468 -1.0507 17.5501\nv  10.1689 -0.0124 15.8825\nv  9.8854 -0.0119 16.5263\nv  9.8784 -0.2613 16.5174\nv  10.1613 -0.2563 15.8746\nv  9.5391 -0.0115 17.1389\nv  9.5328 -0.2674 17.1291\nv  9.5138 -0.5221 17.1007\nv  9.8574 -0.5096 16.4920\nv  10.1386 -0.4992 15.8523\nv  8.6884 -0.0110 18.2375\nv  8.6836 -0.2817 18.2260\nv  9.1320 -0.2743 17.7013\nv  9.1376 -0.0112 17.7120\nv  8.6691 -0.5510 18.1921\nv  9.1152 -0.5361 17.6702\nv  9.0869 -0.7954 17.6195\nv  8.6445 -0.8175 18.1367\nv  9.4820 -0.7745 17.0549\nv  10.1007 -0.7401 15.8168\nv  9.8223 -0.7558 16.4513\nv  8.1991 -0.0109 18.7072\nv  8.1951 -0.2892 18.6949\nv  7.6772 -0.0108 19.1128\nv  7.6740 -0.2966 19.0997\nv  7.6641 -0.5808 19.0609\nv  8.1829 -0.5661 18.6584\nv  6.5661 -0.0108 19.6990\nv  6.5642 -0.3097 19.6844\nv  7.1279 -0.3036 19.4323\nv  7.1304 -0.0108 19.4461\nv  6.5584 -0.6069 19.6413\nv  7.1201 -0.5947 19.3912\nv  7.1066 -0.8825 19.3233\nv  6.5482 -0.9008 19.5699\nv  7.6470 -0.8620 18.9968\nv  8.1620 -0.8400 18.5986\nv  9.9914 -1.6360 14.9533\nv  10.1213 -1.6179 14.3204\nv  10.2278 -1.4011 14.3687\nv  10.0943 -1.4172 15.0150\nv  10.2006 -1.5969 13.0202\nv  10.1903 -1.6054 13.6743\nv  10.3108 -1.3824 13.0433\nv  10.2992 -1.3900 13.7097\nv  10.4832 -0.9380 13.0869\nv  10.4689 -0.9433 13.7729\nv  10.3921 -1.1689 13.7430\nv  10.4052 -1.1624 13.0659\nv  10.3931 -0.9511 14.4522\nv  10.3184 -1.1785 14.4130\nv  10.1817 -1.1923 15.0708\nv  10.2535 -0.9623 15.1194\nv  10.1545 -1.5910 12.3632\nv  10.0543 -1.5863 11.7086\nv  10.1643 -1.3729 11.7093\nv  10.2651 -1.3771 12.3748\nv  9.9021 -1.5812 11.0617\nv  10.0107 -1.3684 11.0522\nv  10.1821 -0.9283 11.0421\nv  10.1042 -1.1504 11.0459\nv  10.3374 -0.9314 11.7161\nv  10.2588 -1.1543 11.7121\nv  10.3600 -1.1579 12.3872\nv  10.4386 -0.9344 12.3995\nv  10.3253 -0.0171 11.0402\nv  10.3160 -0.2464 11.0399\nv  10.4813 -0.0167 11.7295\nv  10.4720 -0.2469 11.7282\nv  10.4445 -0.4768 11.7250\nv  10.2886 -0.4753 11.0398\nv  10.6250 -0.0154 13.1325\nv  10.6159 -0.2478 13.1290\nv  10.5728 -0.2473 12.4263\nv  10.5821 -0.0161 12.4287\nv  10.5890 -0.4798 13.1195\nv  10.5455 -0.4781 12.4200\nv  10.5006 -0.7074 12.4108\nv  10.5446 -0.7101 13.1051\nv  10.3995 -0.7053 11.7207\nv  10.2438 -0.7029 11.0403\nv  10.6077 -0.0146 13.8353\nv  10.5988 -0.2487 13.8306\nv  10.5276 -0.0138 14.5315\nv  10.5191 -0.2503 14.5258\nv  10.4936 -0.4860 14.5098\nv  10.5725 -0.4822 13.8179\nv  10.3741 -0.2527 15.2089\nv  10.3822 -0.0130 15.2158\nv  10.3498 -0.4915 15.1897\nv  10.3096 -0.7284 15.1595\nv  10.4516 -0.7199 14.4848\nv  10.5291 -0.7141 13.7982\nv  2.7994 -2.1314 18.7191\nv  2.3663 -2.1355 18.5245\nv  3.2688 -2.1253 18.8932\nv  3.2531 -1.8469 19.0913\nv  2.7797 -1.8518 18.9153\nv  2.3440 -1.8548 18.7179\nv  4.2885 -2.1047 19.1445\nv  3.7675 -2.1167 19.0380\nv  4.2847 -1.8292 19.3428\nv  3.7571 -1.8396 19.2368\nv  4.2814 -1.2474 19.6546\nv  3.7451 -1.2543 19.5506\nv  3.7499 -1.5515 19.4080\nv  4.2825 -1.5429 19.5131\nv  3.2340 -1.2591 19.4049\nv  3.2417 -1.5575 19.2623\nv  2.3163 -1.2636 19.0251\nv  2.3276 -1.5636 18.8852\nv  2.7653 -1.5614 19.0850\nv  2.7553 -1.2620 19.2267\nv  4.8251 -2.0886 19.2039\nv  5.3703 -2.0677 19.2073\nv  5.3823 -1.7970 19.4000\nv  4.8288 -1.8152 19.4002\nv  5.9172 -2.0413 19.1458\nv  5.9381 -1.7738 19.3331\nv  5.9689 -1.2093 19.6249\nv  5.9552 -1.4959 19.4930\nv  5.4005 -1.2253 19.7008\nv  5.3923 -1.5156 19.5647\nv  4.8323 -1.5311 19.5684\nv  4.8356 -1.2378 19.7077\nv  5.9919 -0.0108 19.8631\nv  5.9905 -0.3148 19.8479\nv  5.4150 -0.0108 19.9475\nv  5.4141 -0.3189 19.9317\nv  5.4114 -0.6252 19.8849\nv  5.9864 -0.6170 19.8028\nv  4.2822 -0.0108 19.9132\nv  4.2819 -0.3245 19.8964\nv  4.8421 -0.3221 19.9449\nv  4.8427 -0.0108 19.9612\nv  4.2815 -0.6364 19.8471\nv  4.8407 -0.6316 19.8967\nv  4.8385 -0.9374 19.8174\nv  4.2812 -0.9446 19.7662\nv  5.4069 -0.9279 19.8078\nv  5.9792 -0.9158 19.7283\nv  3.7408 -0.0108 19.8124\nv  3.7407 -0.3263 19.7954\nv  3.2256 -0.0108 19.6680\nv  3.2257 -0.3274 19.6508\nv  3.2267 -0.6422 19.6004\nv  3.7411 -0.6399 19.7454\nv  2.3031 -0.0108 19.2840\nv  2.3033 -0.3284 19.2670\nv  2.7442 -0.3281 19.4717\nv  2.7440 -0.0108 19.4889\nv  2.3050 -0.6443 19.2173\nv  2.7456 -0.6436 19.4214\nv  2.7490 -0.9555 19.3393\nv  2.3091 -0.9566 19.1362\nv  3.2292 -0.9534 19.5181\nv  3.7424 -0.9498 19.6634\nv  6.9514 -1.8158 6.5172\nv  7.4091 -1.8474 7.0626\nv  7.3049 -2.0275 7.1488\nv  6.8564 -1.9937 6.6120\nv  8.2343 -1.9038 8.1656\nv  7.8377 -1.8769 7.6114\nv  8.1131 -2.0885 8.2357\nv  7.7247 -2.0592 7.6894\nv  7.8434 -2.4379 8.4018\nv  7.4745 -2.4048 7.8725\nv  7.6035 -2.2352 7.7761\nv  7.9827 -2.2665 8.3140\nv  7.0756 -2.3693 7.3496\nv  7.1936 -2.2014 7.2442\nv  6.7556 -2.1657 6.7166\nv  6.6493 -2.3321 6.8320\nv  8.5963 -1.9278 8.7274\nv  8.9209 -1.9486 9.2988\nv  8.7854 -2.1374 9.3524\nv  8.4676 -2.1147 8.7894\nv  9.2052 -1.9657 9.8821\nv  9.0638 -2.1562 9.9267\nv  8.7449 -2.5157 10.0410\nv  8.9103 -2.3395 9.9792\nv  8.4811 -2.4940 9.4848\nv  8.6387 -2.3192 9.4140\nv  8.3287 -2.2947 8.8595\nv  8.1798 -2.4678 8.9388\nv  8.1797 -3.0002 10.2948\nv  7.9454 -2.9756 9.7634\nv  8.1342 -2.8223 9.6583\nv  8.3794 -2.8461 10.1975\nv  7.3758 -2.9124 8.7307\nv  7.6767 -2.9460 9.2421\nv  7.5396 -2.7608 8.6091\nv  7.8535 -2.7935 9.1290\nv  8.0213 -2.6341 9.0283\nv  7.6956 -2.6026 8.4998\nv  8.3129 -2.6617 9.5658\nv  8.5679 -2.6846 10.1134\nv  7.0449 -2.8758 8.2286\nv  6.6862 -2.8374 7.7355\nv  6.8215 -2.6872 7.5944\nv  7.1949 -2.7250 8.0978\nv  6.3018 -2.7980 7.2510\nv  6.4220 -2.6482 7.0983\nv  6.5379 -2.4929 6.9589\nv  6.9515 -2.5312 7.4661\nv  7.3382 -2.5680 7.9794\nv  0.2392 -2.1410 17.3522\nv  0.4838 -2.1413 17.4355\nv  0.4741 -1.8558 17.6050\nv  0.2342 -1.8551 17.5196\nv  1.0107 -2.1416 17.7227\nv  0.7392 -2.1416 17.5620\nv  0.9929 -1.8573 17.8994\nv  0.7251 -1.8566 17.7348\nv  0.9705 -1.2624 18.1767\nv  0.7074 -1.2612 18.0046\nv  0.7147 -1.5626 17.8825\nv  0.9798 -1.5637 18.0510\nv  0.4618 -1.2601 17.8687\nv  0.4669 -1.5616 17.7496\nv  0.2306 -1.5608 17.6620\nv  0.2280 -1.2593 17.7791\nv  1.3038 -2.1412 17.9085\nv  1.6239 -2.1402 18.1101\nv  1.6013 -1.8576 18.2956\nv  1.2831 -1.8577 18.0895\nv  1.9762 -2.1383 18.3185\nv  1.9531 -1.8567 18.5082\nv  1.9242 -1.2642 18.8092\nv  1.9360 -1.5647 18.6722\nv  1.5731 -1.2641 18.5891\nv  1.5847 -1.5650 18.4556\nv  1.2678 -1.5646 18.2453\nv  1.2572 -1.2634 18.3749\nv  1.9102 -0.0108 19.0625\nv  1.9105 -0.3285 19.0458\nv  1.5593 -0.0108 18.8350\nv  1.5596 -0.3283 18.8190\nv  1.5614 -0.6441 18.7719\nv  1.9123 -0.6444 18.9973\nv  0.9596 -0.0108 18.4059\nv  0.9598 -0.3276 18.3911\nv  1.2447 -0.3280 18.5971\nv  1.2444 -0.0108 18.6126\nv  0.9613 -0.6428 18.3475\nv  1.2464 -0.6435 18.5517\nv  1.2503 -0.9559 18.4773\nv  0.9646 -0.9549 18.2758\nv  1.5656 -0.9566 18.6949\nv  1.9166 -0.9569 18.9179\nv  0.6987 -0.0108 18.2259\nv  0.6989 -0.3271 18.2118\nv  0.4558 -0.0108 18.0834\nv  0.4559 -0.3268 18.0698\nv  0.4567 -0.6413 18.0292\nv  0.7000 -0.6420 18.1698\nv  0.2250 -0.3265 17.9760\nv  0.2249 -0.0108 17.9893\nv  0.2254 -0.6407 17.9363\nv  0.2263 -0.9521 17.8706\nv  0.4586 -0.9529 17.9620\nv  0.7027 -0.9538 18.1005\nv  0.2491 -1.4635 1.0355\nv  0.5035 -1.4651 1.0790\nv  0.5037 -1.6319 1.3022\nv  0.2493 -1.6303 1.2602\nv  1.0496 -1.4741 1.2710\nv  0.7685 -1.4685 1.1563\nv  1.0487 -1.6410 1.4878\nv  0.7685 -1.6353 1.3769\nv  1.0542 -1.9750 1.9866\nv  0.7742 -1.9695 1.8828\nv  0.7704 -1.8025 1.6193\nv  1.0502 -1.8081 1.7266\nv  0.5083 -1.9662 1.8130\nv  0.5053 -1.7991 1.5471\nv  0.2502 -1.7975 1.5065\nv  0.2518 -1.9646 1.7739\nv  1.3520 -1.4823 1.4266\nv  1.6811 -1.4937 1.6267\nv  1.6760 -1.6609 1.8329\nv  1.3495 -1.6493 1.6387\nv  2.0421 -1.5087 1.8749\nv  2.0335 -1.6761 2.0740\nv  2.0257 -2.0094 2.5354\nv  2.0280 -1.8431 2.2943\nv  1.6752 -1.9945 2.3095\nv  1.6741 -1.8279 2.0606\nv  1.3498 -1.8164 1.8726\nv  1.3530 -1.9832 2.1277\nv  2.0385 -2.5001 3.3794\nv  1.6979 -2.4870 3.1778\nv  1.6871 -2.3244 2.8686\nv  2.0309 -2.3382 3.0784\nv  1.0813 -2.4696 2.8878\nv  1.3801 -2.4769 3.0148\nv  1.0697 -2.3062 2.5679\nv  1.3681 -2.3139 2.6994\nv  1.3591 -2.1492 2.4035\nv  1.0607 -2.1412 2.2672\nv  1.6796 -2.1601 2.5790\nv  2.0266 -2.1745 2.7969\nv  0.7977 -2.4645 2.7939\nv  0.5254 -2.4614 2.7304\nv  0.5184 -2.2979 2.4054\nv  0.7879 -2.3010 2.4709\nv  0.2608 -2.4598 2.6945\nv  0.2571 -2.2963 2.3686\nv  0.2541 -2.1311 2.0615\nv  0.5127 -2.1327 2.0994\nv  0.7800 -2.1359 2.1669\nv  -5.7868 2.8690 6.9550\nv  -5.3747 2.8366 6.5017\nv  -5.4647 2.6900 6.3057\nv  -5.8939 2.7232 6.7745\nv  -4.9477 2.8050 6.0619\nv  -5.0205 2.6571 5.8491\nv  -5.0930 2.5053 5.6524\nv  -5.5531 2.5392 6.1250\nv  -5.9984 2.5731 6.6087\nv  -4.0729 2.7458 5.2391\nv  -4.1136 2.5944 4.9910\nv  -4.5680 2.6250 5.4094\nv  -4.5117 2.7746 5.6397\nv  -4.1556 2.4397 4.7603\nv  -4.6249 2.4719 5.1957\nv  -4.2430 2.1208 4.3498\nv  -4.7391 2.1550 4.8169\nv  -4.6821 2.3153 4.9984\nv  -4.1989 2.2818 4.5466\nv  -5.2353 2.1899 5.3046\nv  -5.1648 2.3496 5.4711\nv  -6.1979 2.2587 6.3182\nv  -6.0999 2.4183 6.4569\nv  -5.6397 2.3842 5.9591\nv  -5.7241 2.2247 5.8071\nv  -3.6374 2.7189 4.8640\nv  -3.6636 2.5655 4.5985\nv  -3.2112 2.6943 4.5185\nv  -3.2247 2.5390 4.2366\nv  -3.2409 2.3811 3.9731\nv  -3.6920 2.4092 4.3510\nv  -2.4112 2.6536 3.9323\nv  -2.4056 2.4950 3.6224\nv  -2.8032 2.5154 3.9097\nv  -2.8005 2.6724 4.2066\nv  -2.4035 2.3342 3.3317\nv  -2.8091 2.3558 3.6317\nv  -2.4090 2.0068 2.8087\nv  -2.8299 2.0304 3.1328\nv  -2.8180 2.1941 3.3727\nv  -2.4046 2.1713 3.0604\nv  -3.2809 2.0577 3.5017\nv  -3.2597 2.2206 3.7282\nv  -3.7224 2.2500 4.1214\nv  -3.7544 2.0882 3.9094\nv  -2.4568 1.3380 2.0047\nv  -2.9037 1.3607 2.3683\nv  -2.8815 1.5298 2.5299\nv  -2.4405 1.5062 2.1748\nv  -3.3859 1.3870 2.7807\nv  -3.3569 1.5572 2.9333\nv  -3.3297 1.7259 3.1043\nv  -2.8618 1.6980 2.7113\nv  -2.4270 1.6739 2.3656\nv  -4.4226 1.4465 3.7236\nv  -4.3778 1.6195 3.8566\nv  -3.8584 1.5874 3.3778\nv  -3.8950 1.4158 3.2349\nv  -4.3327 1.7896 4.0050\nv  -3.8227 1.7567 3.5378\nv  -3.7879 1.9237 3.7149\nv  -4.2877 1.9568 4.1693\nv  -3.3043 1.8928 3.2937\nv  -2.4165 1.8409 2.5770\nv  -2.8445 1.8649 2.9123\nv  -4.9601 1.4781 4.2395\nv  -4.9066 1.6528 4.3625\nv  -5.4990 1.5099 4.7755\nv  -5.4367 1.6862 4.8885\nv  -5.3717 1.8583 5.0140\nv  -4.8517 1.8238 4.4994\nv  -6.5476 1.5701 5.8786\nv  -6.4674 1.7501 5.9729\nv  -5.9597 1.7189 5.4277\nv  -6.0310 1.5408 5.3243\nv  -6.3821 1.9248 6.0770\nv  -5.8845 1.8922 5.5421\nv  -5.8058 2.0608 5.6684\nv  -6.2921 2.0943 6.1919\nv  -5.3044 2.0261 5.1525\nv  -4.7958 1.9912 4.6507\nv  -8.5187 3.0610 14.6532\nv  -8.6327 2.9861 14.7425\nv  -8.4663 3.0376 15.0557\nv  -8.3736 3.1214 14.8222\nv  -8.7831 2.8758 14.8571\nv  -8.5961 2.9272 15.2403\nv  -8.3571 2.9938 15.5908\nv  -8.2430 3.1095 15.3407\nv  -8.1557 3.2025 15.0437\nv  -9.1079 2.5917 15.0921\nv  -8.8912 2.6420 15.5636\nv  -8.7407 2.7943 15.4092\nv  -8.9442 2.7433 14.9756\nv  -8.6228 2.7025 16.0010\nv  -8.4865 2.8575 15.8087\nv  -7.9530 2.8407 16.7607\nv  -7.8466 3.0036 16.4985\nv  -8.1867 2.9286 16.1723\nv  -8.3082 2.7698 16.4011\nv  -7.7467 3.1488 16.2042\nv  -8.0721 3.0692 15.9129\nv  -7.5863 3.3806 15.5003\nv  -7.8909 3.2905 15.2749\nv  -7.9713 3.1903 15.6161\nv  -7.6582 3.2749 15.8731\nv  -9.2662 2.4242 15.2008\nv  -9.0386 2.4730 15.7044\nv  -9.4168 2.2426 15.3021\nv  -9.1800 2.2892 15.8329\nv  -8.8886 2.3437 16.3309\nv  -8.7579 2.5306 16.1744\nv  -9.6853 1.8443 15.4850\nv  -9.4334 1.8848 16.0587\nv  -9.3125 2.0925 15.9506\nv  -9.5573 2.0487 15.3967\nv  -9.1241 1.9318 16.6008\nv  -9.0117 2.1435 16.4724\nv  -8.3588 2.0376 17.5630\nv  -8.2669 2.2584 17.3943\nv  -8.6610 2.1996 16.9558\nv  -8.7637 1.9834 17.1046\nv  -8.1665 2.4667 17.2061\nv  -8.5487 2.4037 16.7905\nv  -8.4300 2.5943 16.6064\nv  -8.0607 2.6613 16.9957\nv  -6.4231 2.2388 18.8041\nv  -6.3812 2.4770 18.5721\nv  -6.8865 2.4292 18.3769\nv  -6.9415 2.1949 18.5966\nv  -6.3355 2.7008 18.3131\nv  -6.8263 2.6497 18.1313\nv  -7.2992 2.5921 17.8822\nv  -7.3734 2.3754 18.1112\nv  -7.4412 2.1454 18.3160\nv  -6.2408 3.1023 17.7093\nv  -6.7005 3.0452 17.5558\nv  -6.7635 2.8553 17.8581\nv  -6.2880 2.9096 18.0260\nv  -7.1431 2.9809 17.3432\nv  -7.2214 2.7942 17.6269\nv  -7.6558 2.7287 17.3376\nv  -7.5626 2.9119 17.0764\nv  -7.7479 2.5303 17.5719\nv  -7.9158 2.0923 17.9691\nv  -7.8356 2.3177 17.7816\nv  -6.1962 3.2783 17.3619\nv  -6.6401 3.2184 17.2227\nv  -6.1561 3.4367 16.9824\nv  -6.5847 3.3740 16.8571\nv  -6.9968 3.3035 16.6819\nv  -7.0672 3.1510 17.0289\nv  -6.0984 3.6974 16.1225\nv  -6.4994 3.6287 16.0219\nv  -6.5370 3.5111 16.4574\nv  -6.1228 3.5767 16.5697\nv  -6.8848 3.5517 15.8803\nv  -6.9349 3.4374 16.2998\nv  -7.3107 3.3580 16.1030\nv  -7.2490 3.4684 15.7043\nv  -7.3861 3.2277 16.4624\nv  -7.4714 3.0786 16.7858\nv  -2.8011 2.8268 4.5222\nv  -2.4203 2.8096 4.2609\nv  -3.2007 2.8468 4.8188\nv  -3.1942 2.9959 5.1377\nv  -2.8056 2.9781 4.8565\nv  -2.4332 2.9626 4.6084\nv  -4.0340 2.8939 5.5049\nv  -3.6136 2.8692 5.1476\nv  -3.9983 3.0379 5.7877\nv  -3.5935 3.0158 5.4491\nv  -3.9430 3.3110 6.4017\nv  -3.5698 3.2960 6.1055\nv  -3.5785 3.1583 5.7685\nv  -3.9675 3.1772 6.0869\nv  -3.1970 3.2821 5.8312\nv  -3.1926 3.1411 5.4752\nv  -2.4720 3.2582 5.3598\nv  -2.4503 3.1122 4.9747\nv  -2.8148 3.1258 5.2097\nv  -2.8294 3.2696 5.5818\nv  -4.4563 2.9206 5.8873\nv  -4.8747 2.9490 6.2915\nv  -4.8033 3.0880 6.5349\nv  -4.4033 3.0620 6.1505\nv  -5.6775 3.0105 7.1512\nv  -5.2837 2.9791 6.7139\nv  -5.5670 3.1460 7.3578\nv  -5.1929 3.1160 6.9382\nv  -5.3456 3.3925 7.7821\nv  -5.0170 3.3670 7.4072\nv  -5.1036 3.2459 7.1706\nv  -5.4561 3.2739 7.5698\nv  -4.6708 3.3456 7.0524\nv  -4.7348 3.2206 6.7894\nv  -4.3545 3.1979 6.4277\nv  -4.3114 3.3272 6.7173\nv  -4.9681 3.7269 8.4781\nv  -4.7961 3.7405 8.3644\nv  -4.8073 3.6643 8.1100\nv  -5.0384 3.6734 8.3553\nv  -4.5514 3.7562 8.2051\nv  -4.5434 3.6665 7.8898\nv  -4.5680 3.5685 7.5988\nv  -4.8624 3.5776 7.8789\nv  -5.1329 3.5947 8.1836\nv  -3.9599 3.7818 7.8332\nv  -3.9312 3.6741 7.4451\nv  -4.2487 3.6704 7.6674\nv  -4.2691 3.7703 8.0251\nv  -3.9212 3.5596 7.0786\nv  -4.2527 3.5633 7.3330\nv  -4.2755 3.4490 7.0177\nv  -3.9263 3.4385 6.7316\nv  -4.6128 3.4616 7.3209\nv  -5.2367 3.5003 7.9896\nv  -4.9344 3.4781 7.6440\nv  -3.6341 3.7898 7.6380\nv  -3.5989 3.6756 7.2252\nv  -3.2971 3.7947 7.4452\nv  -3.2573 3.6751 7.0126\nv  -3.2281 3.5496 6.5996\nv  -3.5779 3.5549 6.8329\nv  -2.6116 3.7975 7.0886\nv  -2.5681 3.6701 6.6281\nv  -2.9119 3.6732 6.8119\nv  -2.9545 3.7971 7.2601\nv  -2.5305 3.5375 6.1865\nv  -2.8772 3.5437 6.3828\nv  -2.8500 3.4090 5.9728\nv  -2.4986 3.4001 5.7637\nv  -3.2084 3.4184 6.2059\nv  -3.5689 3.4283 6.4599\nv  -2.9783 4.4581 11.3096\nv  -3.3597 4.4287 11.4173\nv  -3.3738 4.4368 11.9872\nv  -2.9889 4.4673 11.8794\nv  -3.7418 4.3941 11.5225\nv  -3.7600 4.4013 12.0909\nv  -3.7637 4.3899 12.6640\nv  -3.3743 4.4254 12.5597\nv  -2.9872 4.4563 12.4497\nv  -4.4994 4.3062 11.7056\nv  -4.5281 4.3125 12.2676\nv  -4.1455 4.3601 12.1859\nv  -4.1224 4.3535 11.6203\nv  -4.5405 4.3024 12.8378\nv  -4.1531 4.3492 12.7582\nv  -4.5274 4.2321 13.9791\nv  -4.1315 4.2747 13.8994\nv  -4.1477 4.3208 13.3312\nv  -4.5394 4.2757 13.4104\nv  -3.7354 4.3121 13.8024\nv  -3.7548 4.3602 13.2363\nv  -2.9518 4.3746 13.5730\nv  -2.9744 4.4252 13.0159\nv  -3.3630 4.3947 13.1298\nv  -3.3415 4.3451 13.6922\nv  -4.8705 4.2517 11.7735\nv  -4.9057 4.2579 12.3313\nv  -5.2336 4.1894 11.8192\nv  -5.2762 4.1957 12.3723\nv  -5.3008 4.1880 12.9362\nv  -4.9238 4.2489 12.8986\nv  -5.9272 4.0385 11.8236\nv  -5.9874 4.0456 12.3680\nv  -5.6375 4.1251 12.3861\nv  -5.5866 4.1185 11.8375\nv  -6.0277 4.0409 12.9239\nv  -5.6695 4.1188 12.9461\nv  -6.0662 3.9911 14.0432\nv  -5.6926 4.0637 14.0737\nv  -5.6865 4.0987 13.5108\nv  -6.0525 4.0231 13.4846\nv  -5.3102 4.1275 14.0704\nv  -5.3109 4.1655 13.5043\nv  -4.9279 4.2242 13.4695\nv  -4.9211 4.1833 14.0375\nv  -5.6874 3.7558 16.1757\nv  -5.6852 3.8599 15.6858\nv  -6.0849 3.7980 15.6395\nv  -5.2696 3.8053 16.1861\nv  -5.2783 3.9129 15.6923\nv  -5.2903 4.0019 15.1708\nv  -5.6880 3.9453 15.1678\nv  -6.0780 3.8797 15.1274\nv  -4.4256 3.8823 16.0976\nv  -4.4537 3.9966 15.6034\nv  -4.8669 3.9581 15.6634\nv  -4.8480 3.8471 16.1585\nv  -4.4819 4.0928 15.0817\nv  -4.8874 4.0507 15.1407\nv  -4.9065 4.1256 14.5967\nv  -4.5073 4.1712 14.5382\nv  -5.3021 4.0732 14.6280\nv  -6.0732 3.9437 14.5931\nv  -5.6918 4.0129 14.6282\nv  -4.0055 3.9124 16.0080\nv  -4.0415 4.0298 15.5169\nv  -3.5907 3.9385 15.8946\nv  -3.6331 4.0588 15.4083\nv  -3.6726 4.1613 14.8938\nv  -4.0761 4.1293 14.9980\nv  -2.7895 3.9837 15.6150\nv  -2.8383 4.1089 15.1421\nv  -3.2311 4.0848 15.2819\nv  -3.1844 3.9618 15.7620\nv  -2.8824 4.2161 14.6410\nv  -3.2739 4.1898 14.7734\nv  -3.3112 4.2767 14.2418\nv  -2.9207 4.3048 14.1163\nv  -3.7074 4.2457 14.3567\nv  -4.1068 4.2109 14.4569\nv  -8.1561 3.0894 10.9419\nv  -8.3775 2.9398 10.8369\nv  -8.5367 2.9525 11.3901\nv  -8.3060 3.1019 11.4884\nv  -8.5869 2.7843 10.7474\nv  -8.7543 2.7969 11.3087\nv  -8.8817 2.8063 11.8725\nv  -8.6581 2.9611 11.9445\nv  -8.4206 3.1095 12.0356\nv  -8.9687 2.4551 10.6088\nv  -9.1498 2.4670 11.1894\nv  -8.9587 2.6351 11.2424\nv  -8.7840 2.6228 10.6719\nv  -9.2871 2.4770 11.7764\nv  -9.0914 2.6450 11.8173\nv  -9.4252 2.4972 12.9439\nv  -9.2280 2.6619 12.9502\nv  -9.1814 2.6535 12.3891\nv  -9.3793 2.4866 12.3634\nv  -9.0170 2.8184 12.9725\nv  -8.9693 2.8132 12.4301\nv  -8.5514 3.1093 13.0897\nv  -8.5018 3.1120 12.5729\nv  -8.7428 2.9659 12.4901\nv  -8.7916 2.9674 13.0170\nv  -9.1408 2.2811 10.5567\nv  -9.3275 2.2924 11.1480\nv  -9.3001 2.1006 10.5140\nv  -9.4917 2.1112 11.1163\nv  -9.6366 2.1206 11.7281\nv  -9.4689 2.3023 11.7474\nv  -9.5800 1.7195 10.4510\nv  -9.7791 1.7283 11.0749\nv  -9.6423 1.9232 11.0925\nv  -9.4466 1.9135 10.4793\nv  -9.9294 1.7363 11.7108\nv  -9.7901 1.9320 11.7166\nv  -10.0749 1.7556 12.9975\nv  -9.9341 1.9528 12.9765\nv  -9.8881 1.9414 12.3463\nv  -10.0287 1.7450 12.3534\nv  -9.7786 2.1424 12.9591\nv  -9.7329 2.1305 12.3442\nv  -9.5632 2.3123 12.3491\nv  -9.6089 2.3240 12.9475\nv  -9.7398 2.0143 14.8171\nv  -9.8732 1.8125 14.8869\nv  -9.5931 2.2063 14.7442\nv  -9.7108 2.1786 14.1643\nv  -9.8621 1.9878 14.2171\nv  -9.9994 1.7880 14.2695\nv  -9.2671 2.5548 14.5900\nv  -9.4349 2.3870 14.6684\nv  -9.3715 2.5286 14.0616\nv  -9.5468 2.3592 14.1121\nv  -9.6041 2.3389 13.5368\nv  -9.4234 2.5103 13.5114\nv  -9.7720 2.1579 13.5675\nv  -10.0659 1.7695 13.6379\nv  -9.9262 1.9678 13.6018\nv  -9.0917 2.7082 14.5093\nv  -8.9125 2.8459 14.4366\nv  -8.9909 2.8305 13.9807\nv  -9.1861 2.6855 14.0138\nv  -8.5459 3.0744 14.3913\nv  -8.7337 2.9664 14.3826\nv  -8.5677 3.0891 14.0145\nv  -8.7858 2.9644 13.9741\nv  -8.8055 2.9658 13.5153\nv  -8.5715 3.1012 13.5754\nv  -9.0249 2.8228 13.4910\nv  -9.2306 2.6713 13.4929\nv  -5.6986 3.6321 16.6309\nv  -5.7172 3.4893 17.0524\nv  -5.2719 3.5331 17.0725\nv  -5.2678 3.6785 16.6459\nv  -5.7700 3.1498 17.7984\nv  -5.7416 3.3283 17.4412\nv  -5.2930 3.1888 17.8300\nv  -5.2806 3.3696 17.4669\nv  -4.3400 3.2459 17.7473\nv  -4.3575 3.4310 17.3820\nv  -4.8178 3.4034 17.4452\nv  -4.8147 3.2204 17.8107\nv  -4.3775 3.5990 16.9859\nv  -4.8240 3.5692 17.0485\nv  -4.8339 3.7173 16.6199\nv  -4.4002 3.7496 16.5581\nv  -5.8010 2.9545 18.1250\nv  -5.8328 2.7431 18.4221\nv  -5.3242 2.7775 18.4658\nv  -5.3079 2.9912 18.1627\nv  -5.8926 2.2750 18.9314\nv  -5.8639 2.5163 18.6905\nv  -5.3565 2.3043 18.9873\nv  -5.3407 2.5483 18.7404\nv  -4.2942 2.3457 18.9192\nv  -4.3021 2.5938 18.6678\nv  -4.8180 2.5739 18.7301\nv  -4.8215 2.3276 18.9803\nv  -4.3124 2.8269 18.3893\nv  -4.8154 2.8051 18.4523\nv  -4.8141 3.0208 18.1462\nv  -4.3249 3.0444 18.0828\nv  -2.3953 2.3822 18.3064\nv  -2.4321 2.6364 18.0648\nv  -2.8580 2.6295 18.2520\nv  -2.8253 2.3768 18.4975\nv  -2.4752 2.8761 17.7985\nv  -2.8965 2.8675 17.9813\nv  -3.3471 2.8570 18.1459\nv  -3.3158 2.6207 18.4205\nv  -3.2895 2.3695 18.6692\nv  -2.5749 3.3101 17.1871\nv  -2.9863 3.2974 17.3597\nv  -2.9397 3.0902 17.6843\nv  -2.5233 3.1008 17.5063\nv  -3.4208 3.2832 17.5151\nv  -3.3823 3.0780 17.8445\nv  -3.8459 3.0631 17.9798\nv  -3.8737 3.2665 17.6465\nv  -3.8210 2.8439 18.2845\nv  -3.7813 2.3594 18.8126\nv  -3.7993 2.6091 18.5618\nv  -2.6287 3.5035 16.8395\nv  -3.0352 3.4886 17.0063\nv  -2.6833 3.6805 16.4625\nv  -3.0853 3.6633 16.6231\nv  -3.5042 3.6448 16.7676\nv  -3.4617 3.4723 17.1565\nv  -3.1354 3.8212 16.2087\nv  -2.7373 3.8408 16.0547\nv  -3.5475 3.8003 16.3474\nv  -3.9703 3.7769 16.4655\nv  -3.9363 3.6238 16.8904\nv  -3.9040 3.4535 17.2838\nv  -6.4746 3.7259 15.5490\nv  -6.4578 3.8041 15.0455\nv  -6.8237 3.7197 14.9293\nv  -6.8496 3.6453 15.4211\nv  -6.4286 3.9087 13.9749\nv  -6.4441 3.8646 14.5185\nv  -6.7785 3.8172 13.8761\nv  -6.8018 3.7765 14.4119\nv  -7.4348 3.6097 13.6167\nv  -7.4681 3.5772 14.1318\nv  -7.1440 3.6804 14.2806\nv  -7.1144 3.7173 13.7542\nv  -7.4992 3.5296 14.6224\nv  -7.1721 3.6278 14.7858\nv  -7.2049 3.5577 15.2628\nv  -7.5359 3.4648 15.0810\nv  -6.4066 3.9378 13.4216\nv  -6.3733 3.9533 12.8654\nv  -6.7061 3.8566 12.7776\nv  -6.7483 3.8434 13.3290\nv  -6.2532 3.9487 11.7725\nv  -6.3238 3.9565 12.3134\nv  -6.5651 3.8496 11.6909\nv  -6.6467 3.8582 12.2292\nv  -7.1475 3.6258 11.4637\nv  -7.2526 3.6360 11.9995\nv  -6.9563 3.7512 12.1223\nv  -6.8631 3.7418 11.5857\nv  -7.3321 3.6376 12.5424\nv  -7.0258 3.7512 12.6676\nv  -7.0767 3.7405 13.2141\nv  -7.3911 3.6294 13.0842\nv  -8.0623 3.2455 11.6054\nv  -7.9227 3.2333 11.0638\nv  -8.1691 3.2518 12.1484\nv  -7.9039 3.3875 12.2754\nv  -7.8055 3.3827 11.7342\nv  -7.6770 3.3710 11.1959\nv  -8.2961 3.2446 13.1966\nv  -8.2461 3.2517 12.6823\nv  -8.0252 3.3732 13.3272\nv  -7.9758 3.3847 12.8097\nv  -7.6908 3.5107 12.9465\nv  -7.7382 3.4949 13.4708\nv  -7.6248 3.5163 12.4092\nv  -7.4187 3.5020 11.3315\nv  -7.5357 3.5130 11.8679\nv  -8.3220 3.2299 13.6810\nv  -8.3334 3.2067 14.1221\nv  -8.0792 3.3187 14.2738\nv  -8.0558 3.3520 13.8182\nv  -8.3399 3.1742 14.5068\nv  -8.1068 3.2706 14.6852\nv  -7.8377 3.3683 14.8825\nv  -7.8014 3.4265 14.4461\nv  -7.7716 3.4677 13.9731\nv  -7.4180 0.1980 6.0864\nv  -6.8964 0.1940 5.5026\nv  -7.9115 0.2014 6.6716\nv  -7.8894 0.4129 6.6880\nv  -7.3970 0.4060 6.1045\nv  -6.8766 0.3982 5.5221\nv  -8.8020 0.2072 7.8571\nv  -8.3739 0.2045 7.2609\nv  -8.7777 0.4244 7.8696\nv  -8.3507 0.4190 7.2754\nv  -8.6849 0.8529 7.9184\nv  -8.2621 0.8423 7.3316\nv  -8.3131 0.6319 7.2991\nv  -8.7384 0.6399 7.8901\nv  -7.8055 0.8304 6.7510\nv  -7.8537 0.6228 6.7146\nv  -6.8029 0.8017 5.5975\nv  -6.8451 0.6010 5.5539\nv  -7.3634 0.6125 6.1338\nv  -7.3181 0.8168 6.1739\nv  -9.1925 0.2095 8.4631\nv  -9.5423 0.2115 9.0815\nv  -9.5163 0.4330 9.0895\nv  -9.1673 0.4290 8.4734\nv  -10.1072 0.2146 10.3671\nv  -9.8483 0.2132 9.7153\nv  -10.0801 0.4392 10.3699\nv  -9.8217 0.4364 9.7207\nv  -9.9751 0.8823 10.3828\nv  -9.7188 0.8767 9.7436\nv  -9.7782 0.6578 9.7300\nv  -10.0359 0.6621 10.3749\nv  -9.4162 0.8699 9.1216\nv  -9.4741 0.6528 9.1028\nv  -9.1264 0.6468 8.4904\nv  -9.0706 0.8620 8.5141\nv  -9.3343 1.7086 9.8441\nv  -9.4510 1.5089 9.8115\nv  -9.7003 1.5185 10.4276\nv  -9.0449 1.6956 9.2521\nv  -9.1572 1.4974 9.2110\nv  -9.2570 1.2931 9.1756\nv  -9.5544 1.3030 9.7841\nv  -9.8066 1.3114 10.4087\nv  -8.3460 1.6630 8.1029\nv  -8.4477 1.4684 8.0466\nv  -8.8218 1.4839 8.6235\nv  -8.7145 1.6804 8.6725\nv  -8.5387 1.2680 7.9968\nv  -8.9175 1.2815 8.5808\nv  -9.0007 1.0739 8.5442\nv  -8.6180 1.0625 7.9540\nv  -9.3436 1.0837 9.1458\nv  -9.8984 1.0990 10.3940\nv  -9.6439 1.0920 9.7615\nv  -7.9422 1.6433 7.5411\nv  -8.0378 1.4508 7.4776\nv  -7.5060 1.6213 6.9847\nv  -7.5950 1.4310 6.9141\nv  -7.6752 1.2353 6.8512\nv  -8.1236 1.2526 7.4212\nv  -6.6223 1.3845 5.7934\nv  -7.1222 1.4090 6.3535\nv  -7.0402 1.5969 6.4313\nv  -6.6904 1.1942 5.7178\nv  -7.1965 1.2158 6.2843\nv  -7.2621 1.0182 6.2243\nv  -6.7510 0.9997 5.6523\nv  -7.7457 1.0348 6.7967\nv  -8.1987 1.0495 7.3724\nv  -2.3568 3.8603 15.8904\nv  -2.4091 4.0054 15.4582\nv  -2.3022 3.6978 16.2914\nv  -1.9394 3.7146 16.1176\nv  -1.9917 3.8793 15.7235\nv  -2.0413 4.0262 15.2988\nv  -2.1916 3.3226 17.0040\nv  -2.2466 3.5184 16.6622\nv  -1.8329 3.3345 16.8186\nv  -1.8859 3.5328 16.4823\nv  -1.1751 3.3552 16.4736\nv  -1.2166 3.5582 16.1470\nv  -1.5436 3.5462 16.3079\nv  -1.4952 3.3455 16.6390\nv  -1.2581 3.7443 15.7933\nv  -1.5922 3.7303 15.9490\nv  -1.3367 4.0628 15.0011\nv  -1.6845 4.0456 15.1441\nv  -1.6396 3.8970 15.5613\nv  -1.2986 3.9128 15.4115\nv  -2.1386 3.1110 17.3179\nv  -2.0890 2.8840 17.6052\nv  -1.7335 2.8911 17.4100\nv  -1.7816 3.1204 17.1275\nv  -2.0064 2.3864 18.1043\nv  -2.0445 2.6423 17.8670\nv  -1.6532 2.3896 17.9003\nv  -1.6903 2.6473 17.6673\nv  -1.0339 2.3935 17.5216\nv  -1.0631 2.6547 17.2969\nv  -1.3648 2.6514 17.4744\nv  -1.3308 2.3919 17.7031\nv  -1.0972 2.9026 17.0478\nv  -1.4044 2.8974 17.2214\nv  -1.4483 3.1290 16.9432\nv  -1.1349 3.1364 16.7736\nv  0.0000 2.3953 17.1301\nv  0.0000 2.6602 16.9141\nv  -0.2538 2.6598 16.9434\nv  -0.2457 2.3953 17.1601\nv  0.0000 2.9125 16.6732\nv  -0.2633 2.9119 16.7019\nv  -0.5310 2.9100 16.7796\nv  -0.5124 2.6589 17.0227\nv  -0.4965 2.3951 17.2412\nv  -0.0000 3.3752 16.1158\nv  -0.2850 3.3737 16.1433\nv  -0.2738 3.1502 16.4353\nv  -0.0000 3.1513 16.4072\nv  -0.5735 3.3697 16.2175\nv  -0.5516 3.1473 16.5113\nv  -0.8373 3.1426 16.6268\nv  -0.8690 3.3634 16.3303\nv  -0.8075 2.9068 16.8977\nv  -0.7575 2.3945 17.3647\nv  -0.7806 2.6571 17.1434\nv  -0.0000 3.5830 15.7988\nv  -0.2965 3.5812 15.8255\nv  -0.0000 3.7736 15.4558\nv  -0.3080 3.7714 15.4818\nv  -0.6186 3.7655 15.5519\nv  -0.5961 3.5761 15.8979\nv  0.0000 4.0984 14.6911\nv  -0.3296 4.0958 14.7150\nv  -0.3192 3.9434 15.1117\nv  0.0000 3.9458 15.0867\nv  -0.6611 4.0885 14.7794\nv  -0.6405 3.9366 15.1792\nv  -0.9663 3.9263 15.2817\nv  -0.9962 4.0774 14.8772\nv  -0.9344 3.7563 15.6583\nv  -0.9017 3.5683 16.0077\nv  -2.0640 2.7953 4.0386\nv  -2.0495 2.6381 3.6996\nv  -2.0822 2.9495 4.3963\nv  -1.7499 2.9387 4.2185\nv  -1.7293 2.7836 3.8530\nv  -1.7119 2.6258 3.5061\nv  -2.1298 3.2480 5.1680\nv  -2.1041 3.1005 4.7728\nv  -1.8009 3.2391 5.0054\nv  -1.7738 3.0906 4.6026\nv  -1.1753 3.2252 4.7631\nv  -1.1521 3.0758 4.3515\nv  -1.4572 3.0823 4.4627\nv  -1.4833 3.2315 4.8708\nv  -1.1309 2.9231 3.9582\nv  -1.4337 2.9299 4.0731\nv  -1.0953 2.6091 3.2265\nv  -1.3950 2.6162 3.3492\nv  -1.4129 2.7745 3.7019\nv  -1.1119 2.7675 3.5833\nv  -2.1595 3.3917 5.5820\nv  -2.1934 3.5312 6.0146\nv  -1.8646 3.5250 5.8668\nv  -1.8312 3.3840 5.4268\nv  -2.2739 3.7964 6.9360\nv  -2.2315 3.6662 6.4660\nv  -1.9407 3.7942 6.8028\nv  -1.9011 3.6619 6.3255\nv  -1.2852 3.7880 6.5957\nv  -1.2555 3.6529 6.1094\nv  -1.5760 3.6573 6.2066\nv  -1.6113 3.7913 6.6893\nv  -1.2272 3.5139 5.6420\nv  -1.5429 3.5192 5.7427\nv  -1.5119 3.3772 5.2974\nv  -1.2004 3.3713 5.1933\nv  0.0000 3.7793 6.4269\nv  0.0000 3.6427 5.9367\nv  -0.3116 3.6435 5.9475\nv  -0.3197 3.7801 6.4376\nv  0.0000 3.5029 5.4657\nv  -0.3038 3.5037 5.4765\nv  -0.6088 3.5060 5.5092\nv  -0.6242 3.6457 5.9798\nv  -0.6400 3.7820 6.4696\nv  0.0000 3.2138 4.5802\nv  -0.2891 3.2145 4.5909\nv  -0.2963 3.3607 5.0244\nv  0.0000 3.3599 5.0136\nv  -0.5801 3.2167 4.6243\nv  -0.5941 3.3629 5.0574\nv  -0.8949 3.3665 5.1135\nv  -0.8748 3.2202 4.6813\nv  -0.9162 3.5095 5.5643\nv  -0.9616 3.7848 6.5223\nv  -0.9385 3.6489 6.0338\nv  0.0000 3.0645 4.1652\nv  -0.2823 3.0652 4.1759\nv  0.0000 2.9123 3.7683\nv  -0.2760 2.9129 3.7790\nv  -0.5547 2.9148 3.8130\nv  -0.5669 3.0673 4.2095\nv  -0.0000 2.5988 3.0277\nv  -0.2652 2.5993 3.0386\nv  -0.2703 2.7575 3.4000\nv  0.0000 2.7570 3.3892\nv  -0.5339 2.6009 3.0737\nv  -0.5437 2.7593 3.4345\nv  -0.8232 2.7625 3.4948\nv  -0.8094 2.6041 3.1355\nv  -0.8388 2.9181 3.8722\nv  -0.8561 3.0707 4.2676\nv  -2.6076 4.4934 11.7721\nv  -2.5998 4.4826 11.2043\nv  -2.6044 4.4832 12.3383\nv  -2.2253 4.5064 12.2294\nv  -2.2294 4.5154 11.6685\nv  -2.2237 4.5029 11.1042\nv  -2.5686 4.4016 13.4490\nv  -2.5910 4.4525 12.8988\nv  -2.1911 4.4258 13.3250\nv  -2.2123 4.4764 12.7829\nv  -1.4499 4.4647 13.0977\nv  -1.4660 4.5138 12.5725\nv  -1.8375 4.4968 12.6727\nv  -1.8185 4.4469 13.2063\nv  -1.4764 4.5415 12.0341\nv  -1.8495 4.5258 12.1267\nv  -1.4777 4.5315 10.9304\nv  -1.8498 4.5190 11.0120\nv  -1.8538 4.5333 11.5720\nv  -1.4804 4.5475 11.4856\nv  -2.5382 4.3310 13.9844\nv  -2.5008 4.2411 14.5007\nv  -2.1276 4.2645 14.3589\nv  -2.1626 4.3550 13.8517\nv  -2.4574 4.1325 14.9935\nv  -2.0869 4.1548 14.8426\nv  -1.3714 4.1934 14.5613\nv  -1.7254 4.1753 14.6963\nv  -1.4021 4.3041 14.0953\nv  -1.7618 4.2857 14.2217\nv  -1.7931 4.3763 13.7238\nv  -1.4285 4.3947 13.6063\nv  0.0000 4.2301 14.2689\nv  -0.3391 4.2275 14.2913\nv  0.0000 4.3408 13.8223\nv  -0.3475 4.3382 13.8432\nv  -0.6962 4.3309 13.8998\nv  -0.6797 4.2201 14.3521\nv  0.0000 4.4983 12.8655\nv  -0.3605 4.4961 12.8832\nv  -0.3546 4.4279 13.3730\nv  0.0000 4.4303 13.3537\nv  -0.7217 4.4895 12.9311\nv  -0.7103 4.4208 13.4253\nv  -1.0679 4.4097 13.5050\nv  -1.0846 4.4790 13.0043\nv  -1.0473 4.3194 13.9859\nv  -1.0233 4.2085 14.4443\nv  0.0000 4.5446 12.3601\nv  -0.3649 4.5426 12.3761\nv  0.0000 4.5690 11.8398\nv  -0.3677 4.5673 11.8543\nv  -0.7360 4.5622 11.8941\nv  -0.7304 4.5368 12.4198\nv  0.0000 4.5510 10.7641\nv  -0.3685 4.5500 10.7762\nv  -0.3690 4.5698 11.3202\nv  0.0000 4.5712 11.3070\nv  -0.7374 4.5466 10.8097\nv  -0.7384 4.5656 11.3565\nv  -1.1088 4.5582 11.4127\nv  -1.1070 4.5406 10.8620\nv  -1.1054 4.5536 11.9553\nv  -1.0972 4.5271 12.4867\nv  -2.5785 0.1580 1.3893\nv  -2.1545 0.1550 1.0540\nv  -2.5690 0.3267 1.4177\nv  -2.1462 0.3209 1.0838\nv  -1.7640 0.3164 0.8038\nv  -1.7711 0.1527 0.7726\nv  -2.5372 0.6642 1.5329\nv  -2.1189 0.6530 1.2042\nv  -2.1339 0.4869 1.1337\nv  -2.5548 0.4955 1.4655\nv  -1.7411 0.6443 0.9297\nv  -1.7537 0.4802 0.8560\nv  -1.0837 0.6328 0.5301\nv  -1.0918 0.4713 0.4508\nv  -1.4082 0.4751 0.6294\nv  -1.3979 0.6376 0.7060\nv  -1.0985 0.3104 0.3942\nv  -1.4168 0.3129 0.5749\nv  -1.4226 0.1510 0.5423\nv  -1.1032 0.1497 0.3603\nv  -2.5173 0.8328 1.6202\nv  -2.1022 0.8193 1.2956\nv  -2.4964 1.0013 1.7277\nv  -2.0850 0.9858 1.4080\nv  -1.7133 0.9737 1.1419\nv  -1.7273 0.8087 1.0249\nv  -2.0538 1.3197 1.6973\nv  -2.0685 1.1526 1.5418\nv  -2.4759 1.1697 1.8558\nv  -1.6892 1.3052 1.4426\nv  -1.7002 1.1391 1.2811\nv  -1.0530 1.2863 1.0766\nv  -1.0589 1.1215 0.9055\nv  -1.3656 1.1289 1.0701\nv  -1.3574 1.2943 1.2369\nv  -1.0665 0.9577 0.7574\nv  -1.3757 0.9644 0.9262\nv  -1.3868 0.8007 0.8049\nv  -1.0750 0.7948 0.6323\nv  0.0000 1.2757 0.8195\nv  0.0000 1.1115 0.6399\nv  -0.2507 1.1118 0.6543\nv  -0.2496 1.2761 0.8333\nv  0.0000 0.9486 0.4836\nv  -0.2524 0.9489 0.4986\nv  -0.5105 0.9503 0.5469\nv  -0.5071 1.1133 0.7010\nv  -0.5046 1.2777 0.8784\nv  0.0000 0.6262 0.2417\nv  -0.2565 0.6265 0.2578\nv  -0.2544 0.7872 0.3663\nv  0.0000 0.7869 0.3508\nv  -0.5187 0.6274 0.3091\nv  -0.5145 0.7884 0.4163\nv  -0.7861 0.7908 0.5038\nv  -0.7925 0.6295 0.3988\nv  -0.7800 0.9531 0.6321\nv  -0.7706 1.2809 0.9583\nv  -0.7746 1.1164 0.7836\nv  0.0000 0.4663 0.1565\nv  -0.2584 0.4665 0.1730\nv  -0.0000 0.3069 0.0954\nv  -0.2601 0.3070 0.1123\nv  -0.5260 0.3076 0.1658\nv  -0.5227 0.4672 0.2256\nv  -0.2613 0.1480 0.0757\nv  0.0000 0.1480 0.0586\nv  -0.5283 0.1483 0.1298\nv  -0.8071 0.1488 0.2238\nv  -0.8036 0.3086 0.2588\nv  -0.7985 0.4688 0.3172\nv  -0.3279 3.9133 6.9472\nv  0.0000 3.9126 6.9366\nv  -0.6562 3.9149 6.9785\nv  -0.6722 4.0419 7.5036\nv  -0.3360 4.0407 7.4729\nv  0.0000 4.0402 7.4624\nv  -1.3161 3.9192 7.1008\nv  -0.9854 3.9170 7.0299\nv  -1.3471 4.0440 7.6221\nv  -1.0092 4.0432 7.5536\nv  -1.4054 4.2656 8.7017\nv  -1.0533 4.2678 8.6369\nv  -1.0321 4.1609 8.0903\nv  -1.3772 4.1603 8.1566\nv  -0.7019 4.2687 8.5889\nv  -0.6876 4.1606 8.0415\nv  0.0000 4.2686 8.5486\nv  0.0000 4.1597 8.0009\nv  -0.3437 4.1600 8.0113\nv  -0.3508 4.2688 8.5590\nv  -1.6485 3.9210 7.1907\nv  -1.9833 3.9219 7.2988\nv  -2.0272 4.0427 7.8112\nv  -1.6863 4.0441 7.7083\nv  -2.6615 3.9194 7.5678\nv  -2.3208 3.9215 7.4247\nv  -2.7152 4.0339 8.0643\nv  -2.3701 4.0395 7.9302\nv  -2.8242 4.2328 9.1019\nv  -2.4675 4.2457 8.9834\nv  -2.4197 4.1482 8.4504\nv  -2.7703 4.1390 8.5762\nv  -2.1123 4.2551 8.8763\nv  -2.0708 4.1545 8.3378\nv  -1.7234 4.1583 8.2395\nv  -1.7584 4.2616 8.7819\nv  -2.5797 4.4504 10.6397\nv  -2.9540 4.4281 10.7453\nv  -2.2075 4.4684 10.5406\nv  -2.1824 4.4142 9.9799\nv  -2.5496 4.3989 10.0800\nv  -2.9186 4.3793 10.1882\nv  -1.4678 4.4929 10.3715\nv  -1.8369 4.4824 10.4505\nv  -1.4518 4.4342 9.8119\nv  -1.8165 4.4259 9.8899\nv  -1.7898 4.3515 9.3329\nv  -1.4306 4.3577 9.2544\nv  -2.1501 4.3424 9.4244\nv  -2.8745 4.3136 9.6398\nv  -2.5115 4.3299 9.5272\nv  -1.0999 4.5003 10.3061\nv  -0.7328 4.5051 10.2563\nv  -0.7249 4.4433 9.6996\nv  -1.0880 4.4399 9.7478\nv  0.0000 4.5083 10.2134\nv  -0.3662 4.5076 10.2247\nv  0.0000 4.4453 9.6583\nv  -0.3624 4.4450 9.6691\nv  -0.3571 4.3646 9.1128\nv  0.0000 4.3647 9.1022\nv  -0.7145 4.3637 9.1427\nv  -1.0722 4.3616 9.1904\nv  -3.0059 3.9151 7.7275\nv  -3.3489 3.9080 7.8977\nv  -3.4090 4.0133 8.3690\nv  -3.0630 4.0254 8.2127\nv  -4.0109 3.8826 8.2452\nv  -3.6856 3.8974 8.0723\nv  -4.0782 3.9755 8.6799\nv  -3.7489 3.9969 8.5269\nv  -4.2370 4.1333 9.6135\nv  -3.8920 4.1670 9.4928\nv  -3.8192 4.0872 9.0007\nv  -4.1556 4.0594 9.1363\nv  -3.5395 4.1942 9.3630\nv  -3.4738 4.1093 8.8578\nv  -3.1229 4.1262 8.7142\nv  -3.1826 4.2159 9.2306\nv  -4.3198 3.8632 8.4102\nv  -4.6042 3.8385 8.5556\nv  -4.6875 3.9137 8.9396\nv  -4.3926 3.9483 8.8217\nv  -5.0682 3.7655 8.7140\nv  -4.8558 3.8082 8.6692\nv  -5.2010 3.8153 9.0472\nv  -4.9583 3.8705 9.0211\nv  -5.4835 3.9149 9.8566\nv  -5.1974 3.9844 9.8491\nv  -5.0756 3.9299 9.4169\nv  -5.3422 3.8663 9.4317\nv  -4.8925 4.0432 9.8003\nv  -4.7869 3.9823 9.3555\nv  -4.4792 4.0249 9.2583\nv  -4.5714 4.0924 9.7189\nv  -5.5128 4.0999 11.3068\nv  -5.8426 4.0206 11.2974\nv  -5.1695 4.1698 11.2831\nv  -5.0883 4.1381 10.7664\nv  -5.4204 4.0706 10.7967\nv  -5.7378 3.9933 10.7922\nv  -4.4517 4.2839 11.1578\nv  -4.8151 4.2309 11.2317\nv  -4.3893 4.2468 10.6257\nv  -4.7438 4.1966 10.7074\nv  -4.6611 4.1500 10.2026\nv  -4.3163 4.1962 10.1104\nv  -4.9944 4.0955 10.2714\nv  -5.6168 3.9576 10.3110\nv  -5.3138 4.0317 10.3099\nv  -4.0817 4.3295 11.0669\nv  -3.7072 4.3682 10.9643\nv  -3.6597 4.3253 10.4175\nv  -4.0271 4.2895 10.5271\nv  -3.3306 4.4009 10.8553\nv  -3.2894 4.3550 10.3026\nv  -3.2390 4.2928 9.7606\nv  -3.6026 4.2668 9.8833\nv  -3.9626 4.2348 10.0020\nv  -5.2346 3.7034 8.6532\nv  -5.3767 3.6241 8.5232\nv  -5.5987 3.6612 8.8958\nv  -5.4113 3.7452 8.9992\nv  -5.6525 3.4230 8.1772\nv  -5.5157 3.5300 8.3605\nv  -5.9372 3.4566 8.5921\nv  -5.7726 3.5647 8.7558\nv  -6.4390 3.5256 9.4788\nv  -6.2230 3.6381 9.6161\nv  -6.0080 3.6016 9.1746\nv  -6.1994 3.4914 9.0261\nv  -5.9936 3.7410 9.7309\nv  -5.8042 3.7013 9.2993\nv  -5.5837 3.7898 9.3887\nv  -5.7480 3.8335 9.8141\nv  -5.7874 3.3051 7.9854\nv  -5.9203 3.1779 7.7910\nv  -6.2512 3.2107 8.2377\nv  -6.0967 3.3381 8.4172\nv  -6.1778 2.9019 7.4179\nv  -6.0505 3.0429 7.5998\nv  -6.5458 2.9346 7.8904\nv  -6.4009 3.0757 8.0599\nv  -7.2045 2.9968 8.8656\nv  -7.0261 3.1389 9.0147\nv  -6.7267 3.1080 8.5316\nv  -6.8887 2.9665 8.3729\nv  -6.8396 3.2750 9.1712\nv  -6.5581 3.2434 8.6978\nv  -6.3826 3.3716 8.8649\nv  -6.6442 3.4042 9.3282\nv  -7.7474 3.2157 10.5340\nv  -7.9689 3.0719 10.4065\nv  -7.5144 3.3534 10.6704\nv  -7.3194 3.3310 10.1576\nv  -7.5383 3.1936 10.0159\nv  -7.7466 3.0502 9.8822\nv  -7.0117 3.6085 10.9429\nv  -7.2693 3.4846 10.8089\nv  -6.8470 3.5853 10.4380\nv  -7.0893 3.4618 10.3006\nv  -6.8803 3.4346 9.8069\nv  -6.6555 3.5572 9.9497\nv  -7.0939 3.3045 9.6579\nv  -7.4911 3.0249 9.3686\nv  -7.2972 3.1677 9.5095\nv  -6.7408 3.7246 11.0655\nv  -6.4560 3.8324 11.1699\nv  -6.3225 3.8077 10.6683\nv  -6.5917 3.7008 10.5629\nv  -6.1568 3.9313 11.2495\nv  -6.0382 3.9054 10.7471\nv  -5.9007 3.8724 10.2678\nv  -6.1673 3.7769 10.1879\nv  -6.4184 3.6715 10.0793\nv  -6.0981 1.3577 5.2312\nv  -5.5585 1.3292 4.6743\nv  -5.6137 1.1448 4.5854\nv  -6.1599 1.1702 5.1490\nv  -4.4668 1.2706 3.6058\nv  -5.0118 1.2999 4.1301\nv  -4.5093 1.0922 3.5034\nv  -5.0606 1.1185 4.0344\nv  -4.5838 0.7293 3.3449\nv  -5.1446 0.7481 3.8853\nv  -5.1053 0.9344 3.9527\nv  -4.5487 0.9117 3.4164\nv  -5.7073 0.7668 4.4458\nv  -5.6637 0.9571 4.5091\nv  -6.2152 0.9791 5.0781\nv  -6.2630 0.7848 5.0190\nv  -3.9321 1.2422 3.1089\nv  -3.4163 1.2153 2.6467\nv  -3.4469 1.0424 2.5311\nv  -3.9685 1.0666 2.9998\nv  -2.9280 1.1909 2.2266\nv  -2.9533 1.0204 2.1046\nv  -3.0016 0.6779 1.9186\nv  -2.9783 0.8494 2.0020\nv  -3.5035 0.6937 2.3542\nv  -3.4764 0.8685 2.4336\nv  -4.0028 0.8895 2.9075\nv  -4.0339 0.7110 2.8321\nv  -3.0491 0.1616 1.7813\nv  -3.5573 0.1657 2.2228\nv  -3.5452 0.3421 2.2489\nv  -3.0383 0.3339 1.8085\nv  -4.6508 0.1751 3.2250\nv  -4.0942 0.1703 2.7064\nv  -4.6361 0.3607 3.2491\nv  -4.0808 0.3512 2.7315\nv  -4.0603 0.5315 2.7734\nv  -4.6134 0.5455 3.2891\nv  -3.5269 0.5182 2.2927\nv  -3.0221 0.5060 1.8542\nv  -5.2182 0.1800 3.7711\nv  -5.7876 0.1849 4.3376\nv  -5.7704 0.3801 4.3596\nv  -5.2023 0.3704 3.7942\nv  -6.3499 0.1896 4.9172\nv  -6.3314 0.3895 4.9380\nv  -6.3021 0.5881 4.9721\nv  -5.7432 0.5743 4.3958\nv  -5.1773 0.5600 3.8323\nv  -6.9887 1.9475 18.7921\nv  -6.4590 1.9871 19.0103\nv  -7.4996 1.9029 18.4985\nv  -7.5490 1.6497 18.6584\nv  -7.0284 1.6889 18.9630\nv  -6.4892 1.7236 19.1904\nv  -8.4386 1.8058 17.7148\nv  -7.9852 1.8551 18.1370\nv  -8.5068 1.5643 17.8488\nv  -8.0441 1.6076 18.2844\nv  -8.6094 1.0577 18.0605\nv  -8.1322 1.0877 18.5159\nv  -8.0930 1.3513 18.4109\nv  -8.5636 1.3144 17.9643\nv  -7.6223 1.1168 18.9080\nv  -7.5898 1.3871 18.7951\nv  -6.5335 1.1679 19.4706\nv  -6.5139 1.4500 19.3440\nv  -7.0611 1.4204 19.1087\nv  -7.0870 1.1439 19.2290\nv  -8.8533 1.7569 17.2394\nv  -9.2227 1.7103 16.7181\nv  -9.3076 1.4803 16.8233\nv  -8.9302 1.5213 17.3592\nv  -9.7984 1.6313 15.5677\nv  -9.5399 1.6678 16.1585\nv  -9.8965 1.4107 15.6435\nv  -9.6319 1.4429 16.2488\nv  -10.0476 0.9513 15.7693\nv  -9.7731 0.9736 16.3964\nv  -9.7097 1.2111 16.3285\nv  -9.9796 1.1837 15.7111\nv  -9.4371 0.9995 16.9927\nv  -9.3790 1.2430 16.9151\nv  -8.9946 1.2779 17.4630\nv  -9.0468 1.0279 17.5501\nv  -9.8784 0.2382 16.5174\nv  -10.1613 0.2324 15.8746\nv  -9.5328 0.2448 17.1291\nv  -9.5138 0.4992 17.1007\nv  -9.8574 0.4860 16.4920\nv  -10.1386 0.4745 15.8523\nv  -8.6836 0.2598 18.2260\nv  -9.1320 0.2521 17.7013\nv  -8.6691 0.5290 18.1921\nv  -9.1152 0.5138 17.6702\nv  -9.0869 0.7728 17.6195\nv  -8.6445 0.7954 18.1367\nv  -9.4820 0.7512 17.0549\nv  -10.1007 0.7145 15.8168\nv  -9.8223 0.7315 16.4513\nv  -8.1951 0.2675 18.6949\nv  -7.6740 0.2750 19.0997\nv  -7.6641 0.5592 19.0609\nv  -8.1829 0.5443 18.6584\nv  -6.5642 0.2881 19.6844\nv  -7.1279 0.2819 19.4323\nv  -6.5584 0.5853 19.6413\nv  -7.1201 0.5730 19.3912\nv  -7.1066 0.8609 19.3233\nv  -6.5482 0.8792 19.5699\nv  -7.6470 0.8403 18.9968\nv  -8.1620 0.8182 18.5986\nv  -9.9914 1.6025 14.9533\nv  -10.1213 1.5803 14.3204\nv  -10.2278 1.3658 14.3687\nv  -10.0943 1.3854 15.0150\nv  -10.2006 1.5509 13.0202\nv  -10.1903 1.5636 13.6743\nv  -10.3108 1.3398 13.0433\nv  -10.2992 1.3510 13.7097\nv  -10.4832 0.9019 13.0869\nv  -10.4689 0.9097 13.7729\nv  -10.3921 1.1327 13.7430\nv  -10.4052 1.1232 13.0659\nv  -10.3931 0.9200 14.4522\nv  -10.3184 1.1454 14.4130\nv  -10.1817 1.1621 15.0708\nv  -10.2535 0.9337 15.1194\nv  -10.1545 1.5413 12.3632\nv  -10.0543 1.5335 11.7086\nv  -10.1643 1.3245 11.7093\nv  -10.2651 1.3314 12.3748\nv  -9.9021 1.5263 11.0617\nv  -10.0107 1.3182 11.0522\nv  -10.1821 0.8869 11.0421\nv  -10.1042 1.1047 11.0459\nv  -10.3374 0.8913 11.7161\nv  -10.2588 1.1101 11.7121\nv  -10.3600 1.1160 12.3872\nv  -10.4386 0.8960 12.3995\nv  -10.3160 0.2158 11.0399\nv  -10.4720 0.2169 11.7282\nv  -10.4445 0.4438 11.7250\nv  -10.2886 0.4416 11.0398\nv  -10.6159 0.2197 13.1290\nv  -10.5728 0.2182 12.4263\nv  -10.5890 0.4493 13.1195\nv  -10.5455 0.4462 12.4200\nv  -10.5006 0.6725 12.4108\nv  -10.5446 0.6770 13.1051\nv  -10.3995 0.6689 11.7207\nv  -10.2438 0.6656 11.0403\nv  -10.5988 0.2217 13.8306\nv  -10.5191 0.2244 14.5258\nv  -10.4936 0.4585 14.5098\nv  -10.5725 0.4532 13.8179\nv  -10.3741 0.2279 15.2089\nv  -10.3498 0.4655 15.1897\nv  -10.3096 0.7011 15.1595\nv  -10.4516 0.6908 14.4848\nv  -10.5291 0.6829 13.7982\nv  -2.7994 2.1097 18.7191\nv  -2.3663 2.1138 18.5245\nv  -3.2688 2.1037 18.8932\nv  -3.2531 1.8252 19.0913\nv  -2.7797 1.8301 18.9153\nv  -2.3440 1.8332 18.7179\nv  -4.2885 2.0830 19.1445\nv  -3.7675 2.0951 19.0380\nv  -4.2847 1.8076 19.3428\nv  -3.7571 1.8179 19.2368\nv  -4.2814 1.2257 19.6546\nv  -3.7451 1.2327 19.5506\nv  -3.7499 1.5299 19.4080\nv  -4.2825 1.5212 19.5131\nv  -3.2340 1.2374 19.4049\nv  -3.2417 1.5359 19.2623\nv  -2.3163 1.2420 19.0251\nv  -2.3276 1.5420 18.8852\nv  -2.7653 1.5397 19.0850\nv  -2.7553 1.2404 19.2267\nv  -4.8251 2.0669 19.2039\nv  -5.3703 2.0461 19.2073\nv  -5.3823 1.7753 19.4000\nv  -4.8288 1.7936 19.4002\nv  -5.9172 2.0197 19.1458\nv  -5.9381 1.7522 19.3331\nv  -5.9689 1.1877 19.6249\nv  -5.9552 1.4743 19.4930\nv  -5.4005 1.2037 19.7008\nv  -5.3923 1.4940 19.5647\nv  -4.8323 1.5094 19.5684\nv  -4.8356 1.2162 19.7077\nv  -5.9905 0.2932 19.8479\nv  -5.4141 0.2973 19.9317\nv  -5.4114 0.6035 19.8849\nv  -5.9864 0.5954 19.8028\nv  -4.2819 0.3029 19.8964\nv  -4.8421 0.3005 19.9449\nv  -4.2815 0.6148 19.8471\nv  -4.8407 0.6099 19.8967\nv  -4.8385 0.9158 19.8174\nv  -4.2812 0.9230 19.7662\nv  -5.4069 0.9063 19.8078\nv  -5.9792 0.8942 19.7283\nv  -3.7407 0.3046 19.7954\nv  -3.2257 0.3058 19.6508\nv  -3.2267 0.6206 19.6004\nv  -3.7411 0.6182 19.7454\nv  -2.3033 0.3068 19.2670\nv  -2.7442 0.3065 19.4717\nv  -2.3050 0.6226 19.2173\nv  -2.7456 0.6220 19.4214\nv  -2.7490 0.9339 19.3393\nv  -2.3091 0.9349 19.1362\nv  -3.2292 0.9317 19.5181\nv  -3.7424 0.9282 19.6634\nv  -6.9514 1.7789 6.5172\nv  -7.4091 1.8053 7.0626\nv  -7.3049 1.9833 7.1488\nv  -6.8564 1.9552 6.6120\nv  -8.2343 1.8509 8.1656\nv  -7.8377 1.8293 7.6114\nv  -8.1131 2.0324 8.2357\nv  -7.7247 2.0090 7.6894\nv  -7.8434 2.3766 8.4018\nv  -7.4745 2.3503 7.8725\nv  -7.6035 2.1826 7.7761\nv  -7.9827 2.2075 8.3140\nv  -7.0756 2.3217 7.3496\nv  -7.1936 2.1553 7.2442\nv  -6.7556 2.1259 6.7166\nv  -6.6493 2.2911 6.8320\nv  -8.5963 1.8701 8.7274\nv  -8.9209 1.8870 9.2988\nv  -8.7854 2.0716 9.3524\nv  -8.4676 2.0532 8.7894\nv  -9.2052 1.9014 9.8821\nv  -9.0638 2.0874 9.9267\nv  -8.7449 2.4400 10.0410\nv  -8.9103 2.2669 9.9792\nv  -8.4811 2.4217 9.4848\nv  -8.6387 2.2498 9.4140\nv  -8.3287 2.2299 8.8595\nv  -8.1798 2.4005 8.9388\nv  -8.1797 2.9226 10.2948\nv  -7.9454 2.9015 9.7634\nv  -8.1342 2.7473 9.6583\nv  -8.3794 2.7676 10.1975\nv  -7.3758 2.8498 8.7307\nv  -7.6767 2.8771 9.2421\nv  -7.5396 2.6975 8.6091\nv  -7.8535 2.7238 9.1290\nv  -8.0213 2.5650 9.0283\nv  -7.6956 2.5399 8.4998\nv  -8.3129 2.5874 9.5658\nv  -8.5679 2.6068 10.1134\nv  -7.0449 2.8202 8.2286\nv  -6.6862 2.7889 7.7355\nv  -6.8215 2.6383 7.5944\nv  -7.1949 2.6689 8.0978\nv  -6.3018 2.7564 7.2510\nv  -6.4220 2.6062 7.0983\nv  -6.5379 2.4512 6.9589\nv  -6.9515 2.4827 7.4661\nv  -7.3382 2.5123 7.9794\nv  -0.2392 2.1194 17.3522\nv  0.0000 2.1192 17.3214\nv  -0.4838 2.1197 17.4355\nv  -0.4741 1.8342 17.6050\nv  -0.2342 1.8335 17.5196\nv  0.0000 1.8332 17.4880\nv  -1.0107 2.1200 17.7227\nv  -0.7392 2.1200 17.5620\nv  -0.9929 1.8357 17.8994\nv  -0.7251 1.8350 17.7348\nv  -0.9705 1.2408 18.1767\nv  -0.7074 1.2396 18.0046\nv  -0.7147 1.5410 17.8825\nv  -0.9798 1.5421 18.0510\nv  -0.4618 1.2385 17.8687\nv  -0.4669 1.5400 17.7496\nv  0.0000 1.2373 17.7459\nv  0.0000 1.5388 17.6296\nv  -0.2306 1.5391 17.6620\nv  -0.2280 1.2377 17.7791\nv  -1.3038 2.1196 17.9085\nv  -1.6239 2.1186 18.1101\nv  -1.6013 1.8359 18.2956\nv  -1.2831 1.8361 18.0895\nv  -1.9762 2.1167 18.3185\nv  -1.9531 1.8351 18.5082\nv  -1.9242 1.2426 18.8092\nv  -1.9360 1.5431 18.6722\nv  -1.5731 1.2425 18.5891\nv  -1.5847 1.5434 18.4556\nv  -1.2678 1.5429 18.2453\nv  -1.2572 1.2418 18.3749\nv  -1.9105 0.3068 19.0458\nv  -1.5596 0.3067 18.8190\nv  -1.5614 0.6225 18.7719\nv  -1.9123 0.6228 18.9973\nv  -0.9598 0.3059 18.3911\nv  -1.2447 0.3063 18.5971\nv  -0.9613 0.6211 18.3475\nv  -1.2464 0.6219 18.5517\nv  -1.2503 0.9342 18.4773\nv  -0.9646 0.9333 18.2758\nv  -1.5656 0.9350 18.6949\nv  -1.9166 0.9353 18.9179\nv  -0.6989 0.3055 18.2118\nv  -0.4559 0.3051 18.0698\nv  -0.4567 0.6196 18.0292\nv  -0.7000 0.6204 18.1698\nv  0.0000 0.3047 17.9411\nv  -0.2250 0.3049 17.9760\nv  0.0000 0.6189 17.9018\nv  -0.2254 0.6191 17.9363\nv  -0.2263 0.9305 17.8706\nv  0.0000 0.9302 17.8367\nv  -0.4586 0.9312 17.9620\nv  -0.7027 0.9322 18.1005\nv  -0.2491 1.4419 1.0355\nv  0.0000 1.4415 1.0222\nv  -0.5035 1.4435 1.0790\nv  -0.5037 1.6103 1.3022\nv  -0.2493 1.6087 1.2602\nv  0.0000 1.6083 1.2474\nv  -1.0496 1.4524 1.2710\nv  -0.7685 1.4469 1.1563\nv  -1.0487 1.6193 1.4878\nv  -0.7685 1.6137 1.3769\nv  -1.0542 1.9534 1.9866\nv  -0.7742 1.9479 1.8828\nv  -0.7704 1.7809 1.6193\nv  -1.0502 1.7865 1.7266\nv  -0.5083 1.9446 1.8130\nv  -0.5053 1.7775 1.5471\nv  0.0000 1.9426 1.7619\nv  -0.0000 1.7755 1.4942\nv  -0.2502 1.7759 1.5065\nv  -0.2518 1.9430 1.7739\nv  -1.3520 1.4607 1.4266\nv  -1.6811 1.4721 1.6267\nv  -1.6760 1.6392 1.8329\nv  -1.3495 1.6277 1.6387\nv  -2.0421 1.4871 1.8749\nv  -2.0335 1.6545 2.0740\nv  -2.0257 1.9878 2.5354\nv  -2.0280 1.8215 2.2943\nv  -1.6752 1.9728 2.3095\nv  -1.6741 1.8063 2.0606\nv  -1.3498 1.7948 1.8726\nv  -1.3530 1.9616 2.1277\nv  -2.0385 2.4785 3.3794\nv  -1.6979 2.4654 3.1778\nv  -1.6871 2.3028 2.8686\nv  -2.0309 2.3166 3.0784\nv  -1.0813 2.4479 2.8878\nv  -1.3801 2.4553 3.0148\nv  -1.0697 2.2846 2.5679\nv  -1.3681 2.2923 2.6994\nv  -1.3591 2.1275 2.4035\nv  -1.0607 2.1196 2.2672\nv  -1.6796 2.1385 2.5790\nv  -2.0266 2.1529 2.7969\nv  -0.7977 2.4429 2.7939\nv  -0.5254 2.4397 2.7304\nv  -0.5184 2.2762 2.4054\nv  -0.7879 2.2794 2.4709\nv  0.0000 2.4377 2.6835\nv  -0.2608 2.4381 2.6945\nv  0.0000 2.2743 2.3573\nv  -0.2571 2.2747 2.3686\nv  -0.2541 2.1095 2.0615\nv  -0.0000 2.1091 2.0499\nv  -0.5127 2.1110 2.0994\nv  -0.7800 2.1143 2.1669\nv  5.7868 2.8690 6.9550\nv  5.8939 2.7232 6.7745\nv  5.4647 2.6900 6.3057\nv  5.3747 2.8366 6.5017\nv  5.9984 2.5731 6.6087\nv  5.5531 2.5392 6.1250\nv  5.0930 2.5053 5.6524\nv  5.0205 2.6571 5.8491\nv  4.9477 2.8050 6.0619\nv  6.1979 2.2587 6.3182\nv  5.7241 2.2247 5.8071\nv  5.6397 2.3842 5.9591\nv  6.0999 2.4183 6.4569\nv  5.2354 2.1899 5.3046\nv  5.1648 2.3496 5.4711\nv  4.2430 2.1208 4.3498\nv  4.1989 2.2818 4.5466\nv  4.6821 2.3153 4.9984\nv  4.7391 2.1550 4.8169\nv  4.1556 2.4397 4.7603\nv  4.6249 2.4719 5.1957\nv  4.0729 2.7458 5.2391\nv  4.5117 2.7746 5.6397\nv  4.5680 2.6250 5.4094\nv  4.1136 2.5944 4.9910\nv  6.2921 2.0943 6.1919\nv  5.8058 2.0608 5.6684\nv  6.3821 1.9248 6.0770\nv  5.8845 1.8922 5.5421\nv  5.3717 1.8583 5.0140\nv  5.3044 2.0261 5.1525\nv  6.5476 1.5701 5.8786\nv  6.0310 1.5408 5.3243\nv  5.9597 1.7189 5.4277\nv  6.4674 1.7501 5.9729\nv  5.4990 1.5099 4.7755\nv  5.4367 1.6862 4.8885\nv  4.4226 1.4465 3.7236\nv  4.3778 1.6195 3.8566\nv  4.9066 1.6528 4.3625\nv  4.9601 1.4781 4.2395\nv  4.3327 1.7896 4.0050\nv  4.8517 1.8238 4.4994\nv  4.7958 1.9912 4.6507\nv  4.2877 1.9568 4.1693\nv  2.4568 1.3380 2.0047\nv  2.4405 1.5062 2.1748\nv  2.8815 1.5298 2.5299\nv  2.9037 1.3607 2.3683\nv  2.4270 1.6739 2.3656\nv  2.8618 1.6980 2.7113\nv  3.3297 1.7259 3.1043\nv  3.3569 1.5572 2.9333\nv  3.3859 1.3870 2.7807\nv  2.4090 2.0068 2.8087\nv  2.8299 2.0304 3.1328\nv  2.8445 1.8649 2.9123\nv  2.4165 1.8409 2.5770\nv  3.2809 2.0577 3.5017\nv  3.3043 1.8928 3.2937\nv  3.7879 1.9237 3.7149\nv  3.7544 2.0882 3.9094\nv  3.8227 1.7567 3.5378\nv  3.8950 1.4158 3.2349\nv  3.8584 1.5874 3.3778\nv  2.4046 2.1713 3.0604\nv  2.8180 2.1941 3.3727\nv  2.4035 2.3342 3.3317\nv  2.8091 2.3558 3.6317\nv  3.2409 2.3811 3.9731\nv  3.2597 2.2206 3.7282\nv  2.4112 2.6536 3.9323\nv  2.8005 2.6724 4.2066\nv  2.8032 2.5154 3.9097\nv  2.4056 2.4950 3.6224\nv  3.2112 2.6943 4.5185\nv  3.2247 2.5390 4.2366\nv  3.6636 2.5655 4.5985\nv  3.6374 2.7189 4.8640\nv  3.6920 2.4092 4.3510\nv  3.7224 2.2500 4.1214\nv  8.5188 3.0610 14.6532\nv  8.3736 3.1214 14.8222\nv  8.4663 3.0376 15.0557\nv  8.6327 2.9861 14.7425\nv  8.1557 3.2025 15.0437\nv  8.2430 3.1095 15.3407\nv  8.3571 2.9938 15.5908\nv  8.5961 2.9272 15.2403\nv  8.7831 2.8758 14.8571\nv  7.5863 3.3806 15.5003\nv  7.6582 3.2749 15.8731\nv  7.9713 3.1903 15.6161\nv  7.8909 3.2905 15.2749\nv  7.7467 3.1488 16.2042\nv  8.0721 3.0692 15.9129\nv  7.9530 2.8407 16.7607\nv  8.3082 2.7698 16.4011\nv  8.1867 2.9286 16.1723\nv  7.8466 3.0036 16.4985\nv  8.6228 2.7025 16.0010\nv  8.4865 2.8575 15.8087\nv  9.1079 2.5917 15.0921\nv  8.9442 2.7433 14.9756\nv  8.7407 2.7943 15.4092\nv  8.8912 2.6420 15.5636\nv  7.2490 3.4684 15.7043\nv  7.3107 3.3580 16.1030\nv  6.8848 3.5517 15.8803\nv  6.9349 3.4374 16.2998\nv  6.9968 3.3035 16.6819\nv  7.3861 3.2277 16.4624\nv  6.0984 3.6974 16.1225\nv  6.1228 3.5767 16.5697\nv  6.5370 3.5111 16.4574\nv  6.4994 3.6287 16.0219\nv  6.1561 3.4367 16.9824\nv  6.5847 3.3740 16.8571\nv  6.2408 3.1023 17.7093\nv  6.7005 3.0452 17.5558\nv  6.6401 3.2184 17.2227\nv  6.1962 3.2783 17.3619\nv  7.1431 2.9809 17.3432\nv  7.0672 3.1510 17.0289\nv  7.4714 3.0786 16.7858\nv  7.5626 2.9119 17.0764\nv  6.4231 2.2388 18.8041\nv  6.9415 2.1949 18.5966\nv  6.8865 2.4292 18.3769\nv  6.3812 2.4770 18.5721\nv  7.4412 2.1454 18.3160\nv  7.3734 2.3754 18.1112\nv  7.2992 2.5921 17.8822\nv  6.8263 2.6497 18.1313\nv  6.3355 2.7008 18.3131\nv  8.3588 2.0376 17.5630\nv  8.2669 2.2584 17.3943\nv  7.8356 2.3177 17.7816\nv  7.9158 2.0923 17.9691\nv  8.1665 2.4667 17.2061\nv  7.7479 2.5303 17.5719\nv  7.6558 2.7287 17.3376\nv  8.0607 2.6613 16.9957\nv  7.2214 2.7942 17.6269\nv  6.2880 2.9096 18.0260\nv  6.7635 2.8553 17.8581\nv  8.7637 1.9834 17.1046\nv  8.6610 2.1996 16.9558\nv  9.1241 1.9318 16.6008\nv  9.0117 2.1435 16.4724\nv  8.8886 2.3437 16.3309\nv  8.5487 2.4037 16.7905\nv  9.6853 1.8443 15.4850\nv  9.5573 2.0487 15.3967\nv  9.3125 2.0925 15.9506\nv  9.4334 1.8848 16.0587\nv  9.4168 2.2426 15.3021\nv  9.1800 2.2892 15.8329\nv  9.0386 2.4730 15.7044\nv  9.2662 2.4242 15.2008\nv  8.7579 2.5306 16.1744\nv  8.4300 2.5943 16.6064\nv  2.4203 2.8096 4.2609\nv  2.8011 2.8268 4.5222\nv  2.4332 2.9626 4.6084\nv  2.8056 2.9781 4.8565\nv  3.1942 2.9959 5.1377\nv  3.2007 2.8468 4.8188\nv  2.4720 3.2582 5.3598\nv  2.8294 3.2696 5.5818\nv  2.8148 3.1258 5.2097\nv  2.4503 3.1122 4.9747\nv  3.1970 3.2821 5.8312\nv  3.1926 3.1411 5.4752\nv  3.9430 3.3110 6.4017\nv  3.9675 3.1772 6.0869\nv  3.5785 3.1583 5.7685\nv  3.5698 3.2960 6.1055\nv  3.9983 3.0379 5.7877\nv  3.5935 3.0158 5.4491\nv  3.6136 2.8692 5.1476\nv  4.0340 2.8939 5.5049\nv  2.4986 3.4001 5.7637\nv  2.8500 3.4090 5.9728\nv  2.5305 3.5375 6.1865\nv  2.8772 3.5437 6.3828\nv  3.2281 3.5496 6.5996\nv  3.2084 3.4184 6.2059\nv  2.6116 3.7975 7.0886\nv  2.9545 3.7971 7.2601\nv  2.9119 3.6732 6.8119\nv  2.5681 3.6701 6.6281\nv  3.2971 3.7947 7.4452\nv  3.2573 3.6751 7.0126\nv  3.9599 3.7818 7.8332\nv  3.9312 3.6741 7.4451\nv  3.5989 3.6756 7.2252\nv  3.6341 3.7898 7.6380\nv  3.9212 3.5596 7.0786\nv  3.5779 3.5549 6.8329\nv  3.5689 3.4283 6.4599\nv  3.9263 3.4385 6.7316\nv  4.9681 3.7269 8.4781\nv  5.0384 3.6734 8.3553\nv  4.8073 3.6643 8.1100\nv  4.7961 3.7405 8.3644\nv  5.1329 3.5947 8.1836\nv  4.8624 3.5776 7.8789\nv  4.5680 3.5685 7.5988\nv  4.5434 3.6665 7.8898\nv  4.5514 3.7562 8.2051\nv  5.3456 3.3925 7.7821\nv  5.0170 3.3670 7.4072\nv  4.9344 3.4781 7.6440\nv  5.2367 3.5003 7.9896\nv  4.6708 3.3456 7.0524\nv  4.6128 3.4616 7.3209\nv  4.2755 3.4490 7.0177\nv  4.3114 3.3272 6.7173\nv  4.2527 3.5633 7.3330\nv  4.2691 3.7703 8.0251\nv  4.2487 3.6704 7.6674\nv  5.4561 3.2739 7.5698\nv  5.1036 3.2459 7.1706\nv  5.5670 3.1460 7.3578\nv  5.1929 3.1160 6.9382\nv  4.8033 3.0880 6.5349\nv  4.7348 3.2206 6.7894\nv  5.2837 2.9791 6.7139\nv  5.6775 3.0105 7.1512\nv  4.8747 2.9490 6.2915\nv  4.4563 2.9206 5.8873\nv  4.4033 3.0620 6.1505\nv  4.3545 3.1979 6.4277\nv  2.9783 4.4581 11.3096\nv  2.9889 4.4673 11.8794\nv  3.3738 4.4368 11.9872\nv  3.3597 4.4287 11.4173\nv  2.9872 4.4562 12.4497\nv  3.3743 4.4254 12.5597\nv  3.7637 4.3899 12.6640\nv  3.7600 4.4013 12.0909\nv  3.7418 4.3941 11.5225\nv  2.9518 4.3746 13.5730\nv  3.3415 4.3451 13.6922\nv  3.3630 4.3947 13.1298\nv  2.9744 4.4252 13.0159\nv  3.7354 4.3121 13.8024\nv  3.7548 4.3602 13.2363\nv  4.5274 4.2321 13.9791\nv  4.5394 4.2757 13.4104\nv  4.1477 4.3208 13.3312\nv  4.1315 4.2747 13.8994\nv  4.5405 4.3024 12.8378\nv  4.1531 4.3492 12.7582\nv  4.4994 4.3062 11.7056\nv  4.1224 4.3535 11.6203\nv  4.1455 4.3601 12.1859\nv  4.5281 4.3125 12.2676\nv  2.9207 4.3048 14.1163\nv  3.3112 4.2767 14.2418\nv  2.8824 4.2161 14.6410\nv  3.2739 4.1898 14.7734\nv  3.6726 4.1613 14.8938\nv  3.7074 4.2457 14.3567\nv  2.7895 3.9837 15.6150\nv  3.1844 3.9618 15.7620\nv  3.2311 4.0848 15.2819\nv  2.8383 4.1089 15.1421\nv  3.5907 3.9385 15.8946\nv  3.6331 4.0588 15.4083\nv  4.4256 3.8823 16.0976\nv  4.4537 3.9966 15.6034\nv  4.0415 4.0298 15.5169\nv  4.0055 3.9124 16.0080\nv  4.4819 4.0928 15.0817\nv  4.0761 4.1293 14.9980\nv  4.1068 4.2109 14.4569\nv  4.5073 4.1712 14.5382\nv  6.0849 3.7980 15.6395\nv  5.6852 3.8599 15.6858\nv  5.6874 3.7558 16.1757\nv  6.0780 3.8797 15.1274\nv  5.6880 3.9453 15.1678\nv  5.2903 4.0019 15.1708\nv  5.2783 3.9129 15.6923\nv  5.2696 3.8053 16.1861\nv  6.0662 3.9911 14.0432\nv  5.6926 4.0637 14.0737\nv  5.6918 4.0129 14.6282\nv  6.0732 3.9437 14.5931\nv  5.3102 4.1275 14.0704\nv  5.3021 4.0732 14.6280\nv  4.9065 4.1256 14.5967\nv  4.9211 4.1833 14.0375\nv  4.8874 4.0507 15.1407\nv  4.8480 3.8471 16.1585\nv  4.8669 3.9581 15.6634\nv  6.0525 4.0231 13.4846\nv  5.6865 4.0987 13.5108\nv  6.0277 4.0409 12.9239\nv  5.6695 4.1188 12.9461\nv  5.3008 4.1880 12.9362\nv  5.3109 4.1655 13.5043\nv  5.9272 4.0385 11.8236\nv  5.5866 4.1185 11.8375\nv  5.6375 4.1251 12.3861\nv  5.9874 4.0456 12.3680\nv  5.2336 4.1894 11.8192\nv  5.2762 4.1957 12.3723\nv  4.9057 4.2579 12.3313\nv  4.8705 4.2517 11.7735\nv  4.9238 4.2489 12.8986\nv  4.9279 4.2242 13.4695\nv  8.1561 3.0894 10.9419\nv  8.3060 3.1019 11.4884\nv  8.5367 2.9525 11.3901\nv  8.3775 2.9398 10.8369\nv  8.4206 3.1095 12.0356\nv  8.6581 2.9611 11.9445\nv  8.8817 2.8063 11.8725\nv  8.7543 2.7969 11.3087\nv  8.5869 2.7843 10.7474\nv  8.5514 3.1093 13.0897\nv  8.7916 2.9674 13.0170\nv  8.7428 2.9659 12.4901\nv  8.5018 3.1120 12.5729\nv  9.0170 2.8184 12.9725\nv  8.9693 2.8132 12.4301\nv  9.4252 2.4972 12.9439\nv  9.3793 2.4866 12.3634\nv  9.1814 2.6535 12.3891\nv  9.2280 2.6619 12.9502\nv  9.2871 2.4770 11.7764\nv  9.0914 2.6450 11.8173\nv  8.9687 2.4551 10.6088\nv  8.7840 2.6228 10.6719\nv  8.9587 2.6351 11.2424\nv  9.1498 2.4670 11.1894\nv  8.5715 3.1012 13.5754\nv  8.8055 2.9658 13.5153\nv  8.5677 3.0891 14.0145\nv  8.7858 2.9644 13.9741\nv  8.9909 2.8305 13.9807\nv  9.0249 2.8228 13.4910\nv  8.7337 2.9664 14.3826\nv  8.5459 3.0744 14.3913\nv  8.9125 2.8459 14.4366\nv  9.2671 2.5548 14.5900\nv  9.0917 2.7082 14.5093\nv  9.3715 2.5286 14.0616\nv  9.1861 2.6855 14.0138\nv  9.2306 2.6713 13.4929\nv  9.4234 2.5103 13.5114\nv  9.8732 1.8125 14.8869\nv  9.7398 2.0143 14.8171\nv  9.9994 1.7880 14.2695\nv  9.8621 1.9878 14.2171\nv  9.7108 2.1786 14.1643\nv  9.5931 2.2063 14.7442\nv  10.0749 1.7556 12.9975\nv  9.9341 1.9528 12.9765\nv  9.9262 1.9678 13.6018\nv  10.0659 1.7695 13.6379\nv  9.7786 2.1424 12.9591\nv  9.7720 2.1579 13.5675\nv  9.6041 2.3389 13.5368\nv  9.6089 2.3240 12.9475\nv  9.5468 2.3592 14.1121\nv  9.4349 2.3870 14.6684\nv  10.0287 1.7450 12.3534\nv  9.8881 1.9414 12.3463\nv  9.9294 1.7363 11.7108\nv  9.7901 1.9320 11.7166\nv  9.6366 2.1206 11.7281\nv  9.7329 2.1305 12.3442\nv  9.5800 1.7195 10.4510\nv  9.4466 1.9135 10.4793\nv  9.6423 1.9232 11.0925\nv  9.7791 1.7283 11.0749\nv  9.3001 2.1006 10.5140\nv  9.4917 2.1112 11.1163\nv  9.3275 2.2924 11.1480\nv  9.1408 2.2811 10.5567\nv  9.4689 2.3023 11.7474\nv  9.5632 2.3123 12.3491\nv  5.6986 3.6321 16.6309\nv  5.2678 3.6785 16.6459\nv  5.2719 3.5331 17.0725\nv  5.7172 3.4893 17.0524\nv  4.4002 3.7496 16.5581\nv  4.8339 3.7173 16.6199\nv  4.3775 3.5990 16.9859\nv  4.8240 3.5692 17.0485\nv  4.3400 3.2459 17.7473\nv  4.8147 3.2204 17.8107\nv  4.8178 3.4034 17.4452\nv  4.3575 3.4310 17.3820\nv  5.2930 3.1888 17.8300\nv  5.2807 3.3696 17.4669\nv  5.7416 3.3283 17.4412\nv  5.7700 3.1498 17.7984\nv  3.9703 3.7769 16.4655\nv  3.5475 3.8003 16.3474\nv  3.5042 3.6448 16.7676\nv  3.9363 3.6238 16.8904\nv  2.7373 3.8408 16.0547\nv  3.1354 3.8212 16.2087\nv  2.6833 3.6805 16.4625\nv  3.0853 3.6633 16.6231\nv  2.5749 3.3101 17.1871\nv  2.9863 3.2974 17.3597\nv  3.0352 3.4886 17.0063\nv  2.6287 3.5035 16.8395\nv  3.4208 3.2832 17.5151\nv  3.4617 3.4723 17.1565\nv  3.9040 3.4535 17.2838\nv  3.8737 3.2665 17.6465\nv  2.3953 2.3822 18.3064\nv  2.8253 2.3768 18.4975\nv  2.8580 2.6295 18.2520\nv  2.4321 2.6364 18.0648\nv  3.2895 2.3695 18.6692\nv  3.3158 2.6207 18.4205\nv  3.3471 2.8570 18.1460\nv  2.8965 2.8675 17.9813\nv  2.4752 2.8761 17.7985\nv  4.2942 2.3457 18.9192\nv  4.3021 2.5938 18.6678\nv  3.7993 2.6091 18.5618\nv  3.7813 2.3594 18.8126\nv  4.3124 2.8269 18.3893\nv  3.8210 2.8439 18.2845\nv  3.8459 3.0631 17.9798\nv  4.3249 3.0444 18.0828\nv  3.3823 3.0780 17.8445\nv  2.5233 3.1008 17.5063\nv  2.9397 3.0902 17.6843\nv  4.8215 2.3276 18.9803\nv  4.8180 2.5739 18.7301\nv  5.3565 2.3043 18.9873\nv  5.3407 2.5483 18.7404\nv  5.3242 2.7775 18.4658\nv  4.8154 2.8051 18.4523\nv  5.8639 2.5163 18.6905\nv  5.8926 2.2750 18.9314\nv  5.8328 2.7431 18.4221\nv  5.8010 2.9545 18.1250\nv  5.3079 2.9912 18.1627\nv  4.8141 3.0208 18.1462\nv  6.4746 3.7259 15.5490\nv  6.8496 3.6453 15.4211\nv  6.8237 3.7197 14.9293\nv  6.4578 3.8041 15.0455\nv  7.5359 3.4648 15.0810\nv  7.2049 3.5577 15.2628\nv  7.4992 3.5296 14.6224\nv  7.1721 3.6278 14.7858\nv  7.4348 3.6097 13.6167\nv  7.1144 3.7173 13.7542\nv  7.1440 3.6804 14.2806\nv  7.4681 3.5772 14.1318\nv  6.7785 3.8172 13.8761\nv  6.8018 3.7765 14.4119\nv  6.4441 3.8646 14.5185\nv  6.4286 3.9087 13.9749\nv  7.8377 3.3683 14.8825\nv  8.1068 3.2706 14.6852\nv  8.0792 3.3187 14.2738\nv  7.8014 3.4265 14.4461\nv  8.3399 3.1742 14.5068\nv  8.3334 3.2067 14.1221\nv  8.2961 3.2446 13.1966\nv  8.3220 3.2299 13.6810\nv  8.0252 3.3732 13.3272\nv  8.0558 3.3520 13.8182\nv  7.7716 3.4677 13.9731\nv  7.7382 3.4949 13.4708\nv  7.9227 3.2333 11.0638\nv  8.0623 3.2455 11.6054\nv  7.6770 3.3710 11.1959\nv  7.8055 3.3827 11.7342\nv  7.9039 3.3875 12.2754\nv  8.1691 3.2518 12.1484\nv  7.1475 3.6258 11.4637\nv  7.2526 3.6360 11.9995\nv  7.5357 3.5130 11.8679\nv  7.4187 3.5020 11.3315\nv  7.3321 3.6376 12.5424\nv  7.6249 3.5163 12.4092\nv  7.6908 3.5107 12.9465\nv  7.3911 3.6294 13.0842\nv  7.9758 3.3847 12.8097\nv  8.2461 3.2517 12.6823\nv  6.8631 3.7418 11.5857\nv  6.9563 3.7512 12.1223\nv  6.5651 3.8496 11.6909\nv  6.6467 3.8582 12.2292\nv  6.7061 3.8566 12.7776\nv  7.0258 3.7512 12.6676\nv  6.3238 3.9565 12.3134\nv  6.2532 3.9487 11.7725\nv  6.3733 3.9533 12.8654\nv  6.4066 3.9378 13.4216\nv  6.7483 3.8434 13.3290\nv  7.0767 3.7405 13.2141\nv  6.8964 0.1930 5.5026\nv  7.4180 0.1965 6.0864\nv  6.8766 0.3975 5.5221\nv  7.3970 0.4051 6.1045\nv  7.8894 0.4117 6.6880\nv  7.9115 0.1994 6.6716\nv  6.8029 0.8015 5.5975\nv  7.3181 0.8166 6.1739\nv  7.3634 0.6120 6.1338\nv  6.8451 0.6006 5.5539\nv  7.8055 0.8300 6.7510\nv  7.8537 0.6221 6.7146\nv  8.6849 0.8523 7.9184\nv  8.7384 0.6388 7.8901\nv  8.3131 0.6310 7.2991\nv  8.2621 0.8419 7.3316\nv  8.7777 0.4225 7.8696\nv  8.3507 0.4174 7.2754\nv  8.3739 0.2020 7.2609\nv  8.8020 0.2042 7.8571\nv  6.7510 0.9996 5.6523\nv  7.2621 1.0181 6.2243\nv  6.6904 1.1941 5.7178\nv  7.1965 1.2158 6.2843\nv  7.6752 1.2352 6.8512\nv  7.7457 1.0346 6.7967\nv  7.0402 1.5969 6.4313\nv  7.1222 1.4090 6.3535\nv  6.6223 1.3845 5.7934\nv  7.5060 1.6213 6.9847\nv  7.5950 1.4310 6.9141\nv  8.3460 1.6630 8.1029\nv  8.4477 1.4684 8.0466\nv  8.0378 1.4508 7.4776\nv  7.9422 1.6433 7.5411\nv  8.5387 1.2679 7.9968\nv  8.1236 1.2526 7.4212\nv  8.1987 1.0493 7.3724\nv  8.6180 1.0623 7.9540\nv  9.7003 1.5185 10.4276\nv  9.4510 1.5089 9.8115\nv  9.3343 1.7086 9.8441\nv  9.8066 1.3113 10.4087\nv  9.5544 1.3030 9.7841\nv  9.2570 1.2930 9.1756\nv  9.1572 1.4974 9.2110\nv  9.0449 1.6956 9.2521\nv  9.9751 0.8815 10.3828\nv  9.7188 0.8759 9.7436\nv  9.6439 1.0917 9.7615\nv  9.8984 1.0987 10.3940\nv  9.4162 0.8692 9.1216\nv  9.3436 1.0834 9.1458\nv  9.0007 1.0736 8.5442\nv  9.0706 0.8614 8.5141\nv  8.9175 1.2814 8.5808\nv  8.7145 1.6804 8.6725\nv  8.8218 1.4839 8.6235\nv  10.0359 0.6606 10.3749\nv  9.7782 0.6563 9.7300\nv  10.0801 0.4366 10.3699\nv  9.8217 0.4338 9.7207\nv  9.5163 0.4306 9.0895\nv  9.4741 0.6514 9.1028\nv  9.8483 0.2091 9.7153\nv  10.1072 0.2104 10.3671\nv  9.5423 0.2076 9.0815\nv  9.1925 0.2060 8.4631\nv  9.1673 0.4268 8.4734\nv  9.1264 0.6456 8.4904\nv  2.4091 4.0054 15.4582\nv  2.3568 3.8603 15.8904\nv  2.0413 4.0262 15.2988\nv  1.9917 3.8793 15.7235\nv  1.9394 3.7146 16.1176\nv  2.3022 3.6978 16.2914\nv  1.3367 4.0628 15.0011\nv  1.2986 3.9128 15.4115\nv  1.6396 3.8970 15.5613\nv  1.6845 4.0456 15.1441\nv  1.2581 3.7443 15.7933\nv  1.5922 3.7303 15.9490\nv  1.1751 3.3552 16.4736\nv  1.4952 3.3455 16.6390\nv  1.5436 3.5462 16.3079\nv  1.2166 3.5582 16.1470\nv  1.8329 3.3345 16.8186\nv  1.8859 3.5328 16.4823\nv  2.2466 3.5184 16.6622\nv  2.1916 3.3226 17.0040\nv  0.9962 4.0774 14.8772\nv  0.9663 3.9263 15.2817\nv  0.6611 4.0885 14.7794\nv  0.6405 3.9366 15.1792\nv  0.6186 3.7655 15.5519\nv  0.9344 3.7563 15.6583\nv  0.3192 3.9434 15.1117\nv  0.3296 4.0958 14.7150\nv  0.3080 3.7714 15.4818\nv  0.2850 3.3737 16.1433\nv  0.2965 3.5812 15.8255\nv  0.5735 3.3697 16.2175\nv  0.5961 3.5761 15.8979\nv  0.9017 3.5683 16.0077\nv  0.8690 3.3634 16.3303\nv  0.2457 2.3953 17.1601\nv  0.2538 2.6598 16.9434\nv  0.4965 2.3951 17.2412\nv  0.5124 2.6589 17.0227\nv  0.5310 2.9099 16.7796\nv  0.2633 2.9119 16.7019\nv  1.0339 2.3935 17.5216\nv  1.0631 2.6547 17.2969\nv  0.7806 2.6571 17.1434\nv  0.7575 2.3945 17.3647\nv  1.0972 2.9026 17.0478\nv  0.8075 2.9068 16.8977\nv  0.8373 3.1426 16.6268\nv  1.1349 3.1364 16.7736\nv  0.5516 3.1473 16.5113\nv  0.2738 3.1502 16.4353\nv  1.3308 2.3919 17.7031\nv  1.3648 2.6514 17.4744\nv  1.6532 2.3896 17.9003\nv  1.6903 2.6473 17.6673\nv  1.7335 2.8911 17.4100\nv  1.4044 2.8974 17.2214\nv  2.0445 2.6423 17.8670\nv  2.0064 2.3864 18.1043\nv  2.0890 2.8840 17.6052\nv  2.1386 3.1110 17.3179\nv  1.7816 3.1204 17.1275\nv  1.4483 3.1290 16.9432\nv  2.0495 2.6381 3.6996\nv  2.0640 2.7953 4.0386\nv  1.7119 2.6258 3.5061\nv  1.7293 2.7836 3.8530\nv  1.7499 2.9387 4.2185\nv  2.0822 2.9495 4.3963\nv  1.0953 2.6091 3.2265\nv  1.1119 2.7675 3.5833\nv  1.4129 2.7745 3.7019\nv  1.3950 2.6162 3.3492\nv  1.1309 2.9231 3.9582\nv  1.4337 2.9299 4.0731\nv  1.1753 3.2252 4.7631\nv  1.4833 3.2315 4.8708\nv  1.4572 3.0823 4.4627\nv  1.1521 3.0758 4.3515\nv  1.8009 3.2391 5.0054\nv  1.7738 3.0906 4.6026\nv  2.1041 3.1005 4.7728\nv  2.1298 3.2480 5.1680\nv  0.8094 2.6041 3.1355\nv  0.8232 2.7625 3.4948\nv  0.5339 2.6009 3.0737\nv  0.5437 2.7593 3.4345\nv  0.5547 2.9148 3.8130\nv  0.8388 2.9181 3.8722\nv  0.2703 2.7575 3.4000\nv  0.2652 2.5993 3.0386\nv  0.2760 2.9129 3.7790\nv  0.2891 3.2145 4.5909\nv  0.2823 3.0652 4.1759\nv  0.5801 3.2167 4.6243\nv  0.5669 3.0673 4.2095\nv  0.8561 3.0707 4.2676\nv  0.8748 3.2202 4.6813\nv  0.3197 3.7801 6.4376\nv  0.3116 3.6435 5.9475\nv  0.6400 3.7820 6.4696\nv  0.6242 3.6457 5.9798\nv  0.6088 3.5060 5.5092\nv  0.3038 3.5037 5.4765\nv  1.2852 3.7880 6.5957\nv  1.2555 3.6529 6.1094\nv  0.9385 3.6489 6.0338\nv  0.9616 3.7848 6.5223\nv  1.2272 3.5139 5.6420\nv  0.9162 3.5095 5.5643\nv  0.8949 3.3665 5.1135\nv  1.2004 3.3713 5.1933\nv  0.5941 3.3629 5.0574\nv  0.2963 3.3607 5.0244\nv  1.6113 3.7913 6.6893\nv  1.5760 3.6573 6.2066\nv  1.9407 3.7942 6.8028\nv  1.9011 3.6619 6.3255\nv  1.8646 3.5250 5.8668\nv  1.5429 3.5192 5.7427\nv  2.2315 3.6662 6.4660\nv  2.2739 3.7964 6.9360\nv  2.1934 3.5312 6.0146\nv  2.1595 3.3917 5.5820\nv  1.8312 3.3840 5.4268\nv  1.5119 3.3772 5.2974\nv  2.5998 4.4826 11.2043\nv  2.6076 4.4934 11.7721\nv  2.2237 4.5029 11.1042\nv  2.2294 4.5154 11.6685\nv  2.2253 4.5064 12.2294\nv  2.6044 4.4832 12.3383\nv  1.4777 4.5315 10.9304\nv  1.4804 4.5475 11.4856\nv  1.8538 4.5333 11.5720\nv  1.8498 4.5190 11.0120\nv  1.4764 4.5415 12.0341\nv  1.8495 4.5258 12.1267\nv  1.4499 4.4647 13.0977\nv  1.8185 4.4469 13.2063\nv  1.8375 4.4968 12.6727\nv  1.4660 4.5138 12.5725\nv  2.1911 4.4258 13.3250\nv  2.2123 4.4764 12.7829\nv  2.5910 4.4525 12.8988\nv  2.5686 4.4016 13.4490\nv  1.1070 4.5406 10.8620\nv  1.1088 4.5582 11.4127\nv  0.7374 4.5466 10.8097\nv  0.7384 4.5656 11.3565\nv  0.7360 4.5622 11.8941\nv  1.1054 4.5536 11.9553\nv  0.3690 4.5698 11.3202\nv  0.3685 4.5500 10.7762\nv  0.3677 4.5673 11.8543\nv  0.3605 4.4961 12.8832\nv  0.3649 4.5426 12.3761\nv  0.7217 4.4895 12.9311\nv  0.7304 4.5368 12.4198\nv  1.0972 4.5271 12.4867\nv  1.0846 4.4790 13.0043\nv  0.3391 4.2275 14.2913\nv  0.6797 4.2201 14.3521\nv  0.6962 4.3309 13.8998\nv  0.3475 4.3382 13.8432\nv  1.3714 4.1934 14.5613\nv  1.0233 4.2085 14.4443\nv  1.4021 4.3041 14.0953\nv  1.0473 4.3194 13.9859\nv  1.0679 4.4097 13.5050\nv  1.4285 4.3947 13.6063\nv  0.7103 4.4208 13.4253\nv  0.3546 4.4279 13.3730\nv  1.7254 4.1753 14.6963\nv  2.0869 4.1548 14.8426\nv  2.1276 4.2645 14.3589\nv  1.7618 4.2857 14.2217\nv  2.4574 4.1325 14.9935\nv  2.5008 4.2411 14.5007\nv  2.5382 4.3310 13.9844\nv  2.1626 4.3550 13.8517\nv  1.7931 4.3763 13.7238\nv  2.1545 0.1550 1.0540\nv  2.5785 0.1580 1.3893\nv  1.7711 0.1527 0.7726\nv  1.7640 0.3164 0.8038\nv  2.1462 0.3209 1.0838\nv  2.5690 0.3267 1.4177\nv  1.1032 0.1497 0.3603\nv  1.4226 0.1510 0.5423\nv  1.0985 0.3104 0.3942\nv  1.4168 0.3129 0.5749\nv  1.0837 0.6328 0.5301\nv  1.3979 0.6376 0.7060\nv  1.4082 0.4751 0.6294\nv  1.0918 0.4713 0.4508\nv  1.7411 0.6443 0.9297\nv  1.7537 0.4802 0.8560\nv  2.5372 0.6642 1.5329\nv  2.5548 0.4955 1.4655\nv  2.1339 0.4869 1.1337\nv  2.1189 0.6530 1.2042\nv  0.8071 0.1488 0.2238\nv  0.5283 0.1483 0.1298\nv  0.5260 0.3076 0.1658\nv  0.8036 0.3086 0.2588\nv  0.2613 0.1480 0.0757\nv  0.2601 0.3070 0.1123\nv  0.2565 0.6265 0.2578\nv  0.2584 0.4665 0.1730\nv  0.5187 0.6274 0.3091\nv  0.5227 0.4672 0.2256\nv  0.7985 0.4688 0.3172\nv  0.7925 0.6295 0.3988\nv  0.2496 1.2761 0.8333\nv  0.2507 1.1118 0.6543\nv  0.5046 1.2777 0.8784\nv  0.5071 1.1133 0.7010\nv  0.5105 0.9503 0.5469\nv  0.2524 0.9489 0.4986\nv  1.0530 1.2863 1.0766\nv  1.0589 1.1215 0.9055\nv  0.7746 1.1164 0.7836\nv  0.7706 1.2809 0.9583\nv  1.0665 0.9577 0.7574\nv  0.7800 0.9531 0.6321\nv  0.7861 0.7908 0.5038\nv  1.0750 0.7948 0.6323\nv  0.5145 0.7884 0.4163\nv  0.2544 0.7872 0.3663\nv  1.3574 1.2943 1.2369\nv  1.3656 1.1289 1.0701\nv  1.6892 1.3052 1.4426\nv  1.7002 1.1391 1.2811\nv  1.7133 0.9737 1.1419\nv  1.3757 0.9644 0.9262\nv  2.4759 1.1697 1.8558\nv  2.0685 1.1526 1.5418\nv  2.0538 1.3197 1.6973\nv  2.4964 1.0013 1.7277\nv  2.0850 0.9858 1.4080\nv  2.1022 0.8193 1.2956\nv  2.5173 0.8328 1.6202\nv  1.7273 0.8087 1.0249\nv  1.3868 0.8007 0.8049\nv  0.3279 3.9133 6.9472\nv  0.3360 4.0407 7.4729\nv  0.6722 4.0419 7.5036\nv  0.6562 3.9149 6.9785\nv  0.3508 4.2688 8.5590\nv  0.3437 4.1600 8.0113\nv  0.7019 4.2687 8.5889\nv  0.6876 4.1606 8.0415\nv  1.4054 4.2656 8.7017\nv  1.3772 4.1603 8.1566\nv  1.0321 4.1609 8.0903\nv  1.0533 4.2678 8.6369\nv  1.3471 4.0440 7.6221\nv  1.0092 4.0432 7.5536\nv  0.9854 3.9170 7.0299\nv  1.3161 3.9192 7.1008\nv  0.3571 4.3646 9.1128\nv  0.3624 4.4450 9.6691\nv  0.7249 4.4433 9.6996\nv  0.7145 4.3637 9.1427\nv  0.3662 4.5076 10.2247\nv  0.7328 4.5051 10.2563\nv  1.4678 4.4929 10.3715\nv  1.0999 4.5003 10.3061\nv  1.4518 4.4342 9.8119\nv  1.0880 4.4399 9.7478\nv  1.0722 4.3616 9.1904\nv  1.4306 4.3577 9.2544\nv  2.9540 4.4281 10.7453\nv  2.5797 4.4504 10.6397\nv  2.9186 4.3793 10.1882\nv  2.5496 4.3989 10.0800\nv  2.1824 4.4142 9.9799\nv  2.2075 4.4684 10.5406\nv  2.8242 4.2328 9.1019\nv  2.4675 4.2457 8.9834\nv  2.5115 4.3299 9.5272\nv  2.8745 4.3136 9.6398\nv  2.1123 4.2551 8.8763\nv  2.1501 4.3424 9.4244\nv  1.7898 4.3515 9.3329\nv  1.7584 4.2616 8.7819\nv  1.8165 4.4259 9.8899\nv  1.8369 4.4824 10.4505\nv  2.7703 4.1390 8.5762\nv  2.4197 4.1482 8.4504\nv  2.7152 4.0339 8.0643\nv  2.3701 4.0395 7.9302\nv  2.0272 4.0427 7.8112\nv  2.0708 4.1545 8.3378\nv  2.3208 3.9215 7.4247\nv  2.6615 3.9194 7.5678\nv  1.9833 3.9219 7.2988\nv  1.6485 3.9210 7.1907\nv  1.6863 4.0441 7.7083\nv  1.7234 4.1583 8.2395\nv  3.0059 3.9151 7.7275\nv  3.0630 4.0254 8.2127\nv  3.4090 4.0133 8.3690\nv  3.3489 3.9080 7.8977\nv  3.1826 4.2159 9.2306\nv  3.1229 4.1262 8.7142\nv  3.5395 4.1942 9.3630\nv  3.4738 4.1093 8.8578\nv  4.2370 4.1333 9.6135\nv  4.1556 4.0594 9.1363\nv  3.8192 4.0872 9.0007\nv  3.8920 4.1670 9.4928\nv  4.0782 3.9755 8.6799\nv  3.7489 3.9969 8.5269\nv  3.6856 3.8974 8.0723\nv  4.0109 3.8826 8.2452\nv  3.2390 4.2928 9.7606\nv  3.2894 4.3550 10.3026\nv  3.6597 4.3253 10.4175\nv  3.6026 4.2668 9.8833\nv  3.3306 4.4009 10.8553\nv  3.7072 4.3682 10.9643\nv  4.4517 4.2839 11.1578\nv  4.0817 4.3295 11.0669\nv  4.3893 4.2468 10.6257\nv  4.0271 4.2895 10.5271\nv  3.9626 4.2348 10.0020\nv  4.3163 4.1962 10.1104\nv  5.8426 4.0206 11.2974\nv  5.5128 4.0999 11.3068\nv  5.7378 3.9933 10.7922\nv  5.4204 4.0706 10.7967\nv  5.0883 4.1381 10.7664\nv  5.1695 4.1698 11.2831\nv  5.4835 3.9149 9.8566\nv  5.1974 3.9844 9.8491\nv  5.3138 4.0317 10.3099\nv  5.6168 3.9576 10.3110\nv  4.8925 4.0432 9.8003\nv  4.9944 4.0955 10.2714\nv  4.6611 4.1500 10.2026\nv  4.5714 4.0924 9.7189\nv  4.7438 4.1966 10.7074\nv  4.8151 4.2309 11.2317\nv  5.3422 3.8663 9.4317\nv  5.0756 3.9299 9.4169\nv  5.2010 3.8153 9.0472\nv  4.9583 3.8705 9.0211\nv  4.6875 3.9137 8.9396\nv  4.7869 3.9823 9.3555\nv  4.8558 3.8082 8.6692\nv  5.0682 3.7655 8.7140\nv  4.6042 3.8385 8.5556\nv  4.3198 3.8632 8.4102\nv  4.3926 3.9483 8.8217\nv  4.4792 4.0249 9.2583\nv  5.2346 3.7034 8.6532\nv  5.4113 3.7452 8.9992\nv  5.5987 3.6612 8.8958\nv  5.3767 3.6241 8.5232\nv  5.7480 3.8335 9.8141\nv  5.5837 3.7898 9.3887\nv  5.9936 3.7410 9.7309\nv  5.8042 3.7013 9.2993\nv  6.4390 3.5256 9.4788\nv  6.1994 3.4914 9.0261\nv  6.0080 3.6016 9.1746\nv  6.2230 3.6381 9.6161\nv  5.9372 3.4566 8.5921\nv  5.7726 3.5647 8.7558\nv  5.5157 3.5300 8.3605\nv  5.6525 3.4230 8.1772\nv  5.9007 3.8724 10.2678\nv  6.0382 3.9054 10.7471\nv  6.3225 3.8077 10.6683\nv  6.1673 3.7769 10.1879\nv  6.1568 3.9313 11.2495\nv  6.4560 3.8324 11.1699\nv  7.0117 3.6085 10.9429\nv  6.7408 3.7246 11.0655\nv  6.8470 3.5853 10.4380\nv  6.5917 3.7008 10.5629\nv  6.4184 3.6715 10.0793\nv  6.6555 3.5572 9.9497\nv  7.9689 3.0719 10.4065\nv  7.7474 3.2157 10.5340\nv  7.7466 3.0502 9.8822\nv  7.5383 3.1936 10.0159\nv  7.3194 3.3310 10.1576\nv  7.5144 3.3534 10.6704\nv  7.2045 2.9968 8.8656\nv  7.0261 3.1389 9.0147\nv  7.2972 3.1677 9.5095\nv  7.4911 3.0249 9.3686\nv  6.8396 3.2750 9.1712\nv  7.0939 3.3045 9.6579\nv  6.8803 3.4346 9.8069\nv  6.6442 3.4042 9.3282\nv  7.0893 3.4618 10.3006\nv  7.2693 3.4846 10.8089\nv  6.8887 2.9665 8.3729\nv  6.7267 3.1080 8.5316\nv  6.5458 2.9346 7.8904\nv  6.4009 3.0757 8.0599\nv  6.2512 3.2107 8.2377\nv  6.5581 3.2434 8.6978\nv  6.0505 3.0429 7.5998\nv  6.1778 2.9019 7.4179\nv  5.9203 3.1779 7.7910\nv  5.7874 3.3051 7.9854\nv  6.0967 3.3381 8.4172\nv  6.3826 3.3716 8.8649\nv  6.0981 1.3577 5.2312\nv  6.1599 1.1702 5.1490\nv  5.6137 1.1448 4.5854\nv  5.5585 1.3292 4.6743\nv  6.2630 0.7847 5.0190\nv  6.2152 0.9790 5.0781\nv  5.7073 0.7667 4.4457\nv  5.6637 0.9571 4.5091\nv  4.5838 0.7293 3.3449\nv  4.5487 0.9117 3.4164\nv  5.1053 0.9344 3.9527\nv  5.1446 0.7481 3.8853\nv  4.5093 1.0922 3.5034\nv  5.0606 1.1185 4.0344\nv  5.0118 1.2999 4.1301\nv  4.4668 1.2706 3.6058\nv  6.3021 0.5878 4.9721\nv  6.3314 0.3891 4.9380\nv  5.7704 0.3799 4.3596\nv  5.7432 0.5741 4.3958\nv  6.3499 0.1890 4.9172\nv  5.7876 0.1845 4.3376\nv  4.6508 0.1750 3.2250\nv  5.2182 0.1798 3.7711\nv  4.6361 0.3606 3.2491\nv  5.2023 0.3703 3.7942\nv  5.1773 0.5599 3.8323\nv  4.6134 0.5455 3.2891\nv  3.0491 0.1616 1.7813\nv  3.0383 0.3339 1.8085\nv  3.5452 0.3421 2.2489\nv  3.5573 0.1657 2.2228\nv  3.0016 0.6779 1.9186\nv  3.0221 0.5060 1.8542\nv  3.5035 0.6937 2.3542\nv  3.5269 0.5182 2.2927\nv  4.0603 0.5315 2.7734\nv  4.0339 0.7110 2.8321\nv  4.0808 0.3511 2.7315\nv  4.0942 0.1703 2.7064\nv  2.9783 0.8494 2.0020\nv  2.9533 1.0204 2.1046\nv  3.4469 1.0424 2.5311\nv  3.4764 0.8685 2.4336\nv  2.9280 1.1909 2.2266\nv  3.4163 1.2153 2.6467\nv  3.9321 1.2422 3.1089\nv  3.9685 1.0666 2.9998\nv  4.0028 0.8895 2.9075\nv  6.4590 1.9871 19.0103\nv  6.9887 1.9475 18.7921\nv  6.4892 1.7236 19.1905\nv  7.0284 1.6889 18.9630\nv  7.5490 1.6497 18.6584\nv  7.4996 1.9029 18.4985\nv  6.5335 1.1679 19.4706\nv  7.0870 1.1439 19.2290\nv  7.0611 1.4204 19.1087\nv  6.5139 1.4500 19.3440\nv  7.6223 1.1168 18.9080\nv  7.5898 1.3871 18.7951\nv  8.6094 1.0577 18.0605\nv  8.5636 1.3144 17.9643\nv  8.0930 1.3513 18.4109\nv  8.1322 1.0877 18.5159\nv  8.5068 1.5643 17.8488\nv  8.0441 1.6076 18.2844\nv  7.9852 1.8551 18.1370\nv  8.4386 1.8058 17.7148\nv  6.5482 0.8792 19.5699\nv  7.1066 0.8609 19.3233\nv  6.5584 0.5853 19.6413\nv  7.1201 0.5730 19.3912\nv  7.6641 0.5592 19.0609\nv  7.6470 0.8403 18.9968\nv  7.1279 0.2819 19.4323\nv  6.5642 0.2881 19.6844\nv  7.6740 0.2749 19.0997\nv  8.6836 0.2596 18.2260\nv  8.1951 0.2674 18.6949\nv  8.6691 0.5289 18.1921\nv  8.1829 0.5443 18.6584\nv  8.1620 0.8182 18.5986\nv  8.6445 0.7954 18.1367\nv  10.1613 0.2314 15.8746\nv  9.8784 0.2375 16.5174\nv  10.1386 0.4739 15.8523\nv  9.8574 0.4855 16.4920\nv  9.5138 0.4990 17.1007\nv  9.5328 0.2444 17.1291\nv  10.0476 0.9511 15.7693\nv  9.7731 0.9735 16.3964\nv  9.8223 0.7313 16.4513\nv  10.1007 0.7142 15.8168\nv  9.4371 0.9994 16.9927\nv  9.4820 0.7511 17.0549\nv  9.0869 0.7727 17.6195\nv  9.0468 1.0279 17.5501\nv  9.1152 0.5136 17.6702\nv  9.1320 0.2519 17.7013\nv  9.9796 1.1836 15.7111\nv  9.7097 1.2111 16.3285\nv  9.8965 1.4107 15.6435\nv  9.6319 1.4429 16.2488\nv  9.3076 1.4803 16.8233\nv  9.3790 1.2429 16.9151\nv  9.5399 1.6678 16.1585\nv  9.7984 1.6313 15.5677\nv  9.2227 1.7103 16.7181\nv  8.8533 1.7569 17.2394\nv  8.9302 1.5213 17.3592\nv  8.9946 1.2778 17.4630\nv  9.9914 1.6025 14.9533\nv  10.0943 1.3854 15.0150\nv  10.2278 1.3658 14.3687\nv  10.1213 1.5803 14.3204\nv  10.2535 0.9334 15.1194\nv  10.1817 1.1620 15.0708\nv  10.3931 0.9197 14.4522\nv  10.3184 1.1452 14.4130\nv  10.4832 0.9014 13.0869\nv  10.4052 1.1230 13.0659\nv  10.3921 1.1325 13.7429\nv  10.4689 0.9093 13.7729\nv  10.3108 1.3398 13.0433\nv  10.2992 1.3509 13.7097\nv  10.1903 1.5636 13.6743\nv  10.2006 1.5509 13.0202\nv  10.3096 0.7006 15.1595\nv  10.3498 0.4646 15.1897\nv  10.4936 0.4573 14.5098\nv  10.4516 0.6901 14.4848\nv  10.3741 0.2264 15.2089\nv  10.5191 0.2224 14.5258\nv  10.6159 0.2166 13.1290\nv  10.5988 0.2192 13.8306\nv  10.5890 0.4474 13.1195\nv  10.5725 0.4517 13.8179\nv  10.5291 0.6820 13.7982\nv  10.5446 0.6759 13.1051\nv  10.3160 0.2117 11.0399\nv  10.2886 0.4390 11.0398\nv  10.4445 0.4413 11.7250\nv  10.4720 0.2130 11.7282\nv  10.1821 0.8862 11.0421\nv  10.2438 0.6641 11.0403\nv  10.3374 0.8906 11.7161\nv  10.3995 0.6675 11.7207\nv  10.5006 0.6712 12.4108\nv  10.4386 0.8954 12.3995\nv  10.5455 0.4440 12.4200\nv  10.5728 0.2146 12.4263\nv  10.1042 1.1044 11.0459\nv  10.0107 1.3181 11.0522\nv  10.1643 1.3244 11.7093\nv  10.2588 1.1098 11.7121\nv  9.9021 1.5263 11.0617\nv  10.0543 1.5335 11.7086\nv  10.1545 1.5413 12.3632\nv  10.2651 1.3313 12.3748\nv  10.3600 1.1157 12.3872\nv  2.3663 2.1138 18.5245\nv  2.7994 2.1097 18.7191\nv  2.3440 1.8332 18.7179\nv  2.7797 1.8301 18.9153\nv  3.2531 1.8252 19.0913\nv  3.2688 2.1037 18.8932\nv  2.3163 1.2420 19.0251\nv  2.7553 1.2404 19.2267\nv  2.7653 1.5397 19.0850\nv  2.3276 1.5420 18.8852\nv  3.2340 1.2374 19.4049\nv  3.2417 1.5359 19.2623\nv  4.2814 1.2257 19.6546\nv  4.2825 1.5212 19.5131\nv  3.7499 1.5299 19.4080\nv  3.7451 1.2327 19.5506\nv  4.2847 1.8076 19.3428\nv  3.7571 1.8179 19.2368\nv  3.7675 2.0951 19.0380\nv  4.2885 2.0830 19.1445\nv  2.3091 0.9349 19.1362\nv  2.7490 0.9339 19.3393\nv  2.3050 0.6226 19.2173\nv  2.7456 0.6220 19.4214\nv  3.2267 0.6206 19.6004\nv  3.2292 0.9317 19.5181\nv  2.7442 0.3065 19.4717\nv  2.3033 0.3068 19.2670\nv  3.2257 0.3058 19.6508\nv  4.2819 0.3029 19.8964\nv  3.7407 0.3046 19.7954\nv  4.2815 0.6148 19.8471\nv  3.7411 0.6182 19.7454\nv  3.7424 0.9282 19.6634\nv  4.2812 0.9230 19.7662\nv  5.9905 0.2932 19.8479\nv  5.9864 0.5954 19.8028\nv  5.4114 0.6035 19.8849\nv  5.4141 0.2973 19.9317\nv  5.9689 1.1877 19.6249\nv  5.9792 0.8942 19.7283\nv  5.4005 1.2037 19.7008\nv  5.4069 0.9063 19.8078\nv  4.8385 0.9158 19.8174\nv  4.8356 1.2162 19.7077\nv  4.8407 0.6099 19.8967\nv  4.8421 0.3005 19.9449\nv  5.9552 1.4743 19.4930\nv  5.9381 1.7522 19.3331\nv  5.3823 1.7753 19.4000\nv  5.3923 1.4940 19.5647\nv  5.9172 2.0197 19.1458\nv  5.3703 2.0461 19.2073\nv  4.8251 2.0669 19.2039\nv  4.8288 1.7936 19.4002\nv  4.8323 1.5094 19.5684\nv  6.9514 1.7789 6.5172\nv  6.8564 1.9552 6.6120\nv  7.3049 1.9833 7.1488\nv  7.4091 1.8053 7.0626\nv  6.6493 2.2911 6.8320\nv  6.7556 2.1259 6.7166\nv  7.0756 2.3217 7.3496\nv  7.1936 2.1553 7.2442\nv  7.8434 2.3766 8.4018\nv  7.9827 2.2075 8.3140\nv  7.6035 2.1826 7.7761\nv  7.4745 2.3503 7.8725\nv  8.1131 2.0324 8.2357\nv  7.7247 2.0090 7.6894\nv  7.8377 1.8293 7.6114\nv  8.2343 1.8509 8.1656\nv  6.5379 2.4512 6.9589\nv  6.4220 2.6062 7.0983\nv  6.8215 2.6383 7.5944\nv  6.9515 2.4827 7.4661\nv  6.3018 2.7564 7.2510\nv  6.6862 2.7889 7.7355\nv  7.3758 2.8498 8.7307\nv  7.0449 2.8202 8.2286\nv  7.5396 2.6975 8.6091\nv  7.1949 2.6689 8.0978\nv  7.3382 2.5123 7.9794\nv  7.6956 2.5399 8.4998\nv  8.1797 2.9226 10.2948\nv  8.3794 2.7676 10.1975\nv  8.1342 2.7473 9.6583\nv  7.9454 2.9015 9.7634\nv  8.7449 2.4400 10.0410\nv  8.5679 2.6068 10.1134\nv  8.4811 2.4217 9.4848\nv  8.3129 2.5874 9.5658\nv  8.0213 2.5650 9.0283\nv  8.1798 2.4005 8.9388\nv  7.8535 2.7238 9.1290\nv  7.6767 2.8771 9.2421\nv  8.9103 2.2669 9.9792\nv  9.0638 2.0874 9.9267\nv  8.7854 2.0716 9.3524\nv  8.6387 2.2498 9.4140\nv  9.2052 1.9014 9.8821\nv  8.9209 1.8870 9.2988\nv  8.5963 1.8701 8.7274\nv  8.4676 2.0532 8.7894\nv  8.3287 2.2299 8.8595\nv  0.2392 2.1194 17.3522\nv  0.2342 1.8335 17.5196\nv  0.4741 1.8342 17.6050\nv  0.4838 2.1197 17.4355\nv  0.2280 1.2377 17.7791\nv  0.2306 1.5391 17.6620\nv  0.4618 1.2385 17.8687\nv  0.4669 1.5400 17.7496\nv  0.9705 1.2408 18.1767\nv  0.9798 1.5421 18.0510\nv  0.7147 1.5410 17.8825\nv  0.7074 1.2396 18.0046\nv  0.9929 1.8357 17.8994\nv  0.7251 1.8350 17.7348\nv  0.7392 2.1200 17.5620\nv  1.0107 2.1200 17.7227\nv  0.2263 0.9305 17.8706\nv  0.2254 0.6191 17.9363\nv  0.4567 0.6196 18.0292\nv  0.4586 0.9312 17.9620\nv  0.2250 0.3049 17.9760\nv  0.4559 0.3051 18.0698\nv  0.9598 0.3059 18.3911\nv  0.6989 0.3055 18.2118\nv  0.9613 0.6211 18.3475\nv  0.7000 0.6204 18.1698\nv  0.7027 0.9322 18.1005\nv  0.9646 0.9333 18.2758\nv  1.9105 0.3068 19.0458\nv  1.9123 0.6228 18.9973\nv  1.5614 0.6225 18.7719\nv  1.5596 0.3067 18.8190\nv  1.9242 1.2426 18.8092\nv  1.9166 0.9353 18.9179\nv  1.5731 1.2425 18.5891\nv  1.5656 0.9350 18.6949\nv  1.2503 0.9342 18.4773\nv  1.2572 1.2418 18.3749\nv  1.2464 0.6219 18.5517\nv  1.2447 0.3063 18.5971\nv  1.9360 1.5431 18.6722\nv  1.9531 1.8351 18.5082\nv  1.6013 1.8359 18.2956\nv  1.5847 1.5434 18.4556\nv  1.9762 2.1167 18.3185\nv  1.6239 2.1186 18.1101\nv  1.3038 2.1196 17.9085\nv  1.2831 1.8361 18.0895\nv  1.2678 1.5429 18.2453\nv  0.2491 1.4419 1.0355\nv  0.2493 1.6087 1.2602\nv  0.5037 1.6103 1.3022\nv  0.5035 1.4435 1.0790\nv  0.2518 1.9430 1.7739\nv  0.2502 1.7759 1.5065\nv  0.5083 1.9446 1.8130\nv  0.5053 1.7775 1.5471\nv  1.0542 1.9534 1.9866\nv  1.0502 1.7865 1.7266\nv  0.7704 1.7809 1.6193\nv  0.7742 1.9479 1.8828\nv  1.0487 1.6193 1.4878\nv  0.7685 1.6137 1.3769\nv  0.7685 1.4469 1.1563\nv  1.0496 1.4524 1.2710\nv  0.2541 2.1095 2.0615\nv  0.2571 2.2747 2.3686\nv  0.5184 2.2762 2.4054\nv  0.5127 2.1110 2.0994\nv  0.2608 2.4381 2.6945\nv  0.5254 2.4397 2.7304\nv  1.0813 2.4479 2.8878\nv  0.7977 2.4429 2.7939\nv  1.0697 2.2846 2.5679\nv  0.7879 2.2794 2.4709\nv  0.7800 2.1143 2.1669\nv  1.0607 2.1196 2.2672\nv  2.0385 2.4785 3.3794\nv  2.0309 2.3166 3.0784\nv  1.6871 2.3028 2.8686\nv  1.6979 2.4654 3.1778\nv  2.0257 1.9878 2.5354\nv  2.0266 2.1529 2.7969\nv  1.6752 1.9728 2.3095\nv  1.6796 2.1385 2.5790\nv  1.3591 2.1275 2.4035\nv  1.3530 1.9616 2.1277\nv  1.3681 2.2923 2.6994\nv  1.3801 2.4553 3.0148\nv  2.0280 1.8215 2.2943\nv  2.0335 1.6545 2.0740\nv  1.6760 1.6392 1.8329\nv  1.6741 1.8063 2.0606\nv  2.0421 1.4871 1.8749\nv  1.6811 1.4721 1.6267\nv  1.3520 1.4607 1.4266\nv  1.3495 1.6277 1.6387\nv  1.3498 1.7948 1.8726\n# 5634 vertices\n\nvn -0.3934 -0.8264 -0.4029\nvn -0.4196 -0.8008 -0.4274\nvn -0.4058 -0.8012 -0.4397\nvn -0.3803 -0.8260 -0.4160\nvn -0.4466 -0.7725 -0.4514\nvn -0.4323 -0.7733 -0.4638\nvn -0.4169 -0.7766 -0.4724\nvn -0.3910 -0.8034 -0.4491\nvn -0.3660 -0.8277 -0.4254\nvn -0.5022 -0.7064 -0.4988\nvn -0.4869 -0.7088 -0.5105\nvn -0.4594 -0.7427 -0.4872\nvn -0.4744 -0.7408 -0.4756\nvn -0.4708 -0.7139 -0.5184\nvn -0.4437 -0.7465 -0.4958\nvn -0.4356 -0.7300 -0.5266\nvn -0.4089 -0.7606 -0.5042\nvn -0.4268 -0.7528 -0.5010\nvn -0.4538 -0.7209 -0.5238\nvn -0.3828 -0.7886 -0.4812\nvn -0.4005 -0.7816 -0.4783\nvn -0.3335 -0.8361 -0.4356\nvn -0.3504 -0.8310 -0.4320\nvn -0.3749 -0.8078 -0.4549\nvn -0.3576 -0.8135 -0.4586\nvn -0.5299 -0.6688 -0.5215\nvn -0.5141 -0.6724 -0.5325\nvn -0.5569 -0.6289 -0.5426\nvn -0.5409 -0.6331 -0.5538\nvn -0.5245 -0.6400 -0.5615\nvn -0.4979 -0.6781 -0.5406\nvn -0.6072 -0.5424 -0.5807\nvn -0.5911 -0.5482 -0.5918\nvn -0.5666 -0.5917 -0.5734\nvn -0.5827 -0.5864 -0.5627\nvn -0.5751 -0.5562 -0.6000\nvn -0.5505 -0.5990 -0.5815\nvn -0.5420 -0.5772 -0.6108\nvn -0.5164 -0.6196 -0.5911\nvn -0.5337 -0.6086 -0.5871\nvn -0.5590 -0.5657 -0.6063\nvn -0.4897 -0.6596 -0.5702\nvn -0.5077 -0.6487 -0.5670\nvn -0.4808 -0.6864 -0.5457\nvn -0.4628 -0.6961 -0.5489\nvn -0.4583 -0.6362 -0.6207\nvn -0.4299 -0.6779 -0.5963\nvn -0.4553 -0.6619 -0.5954\nvn -0.4835 -0.6192 -0.6187\nvn -0.4016 -0.7155 -0.5716\nvn -0.4275 -0.6998 -0.5723\nvn -0.4501 -0.6854 -0.5724\nvn -0.4778 -0.6464 -0.5948\nvn -0.5048 -0.6041 -0.6166\nvn -0.3474 -0.7780 -0.5236\nvn -0.3728 -0.7646 -0.5258\nvn -0.3998 -0.7342 -0.5488\nvn -0.3740 -0.7484 -0.5477\nvn -0.3955 -0.7522 -0.5271\nvn -0.4227 -0.7203 -0.5500\nvn -0.4434 -0.7078 -0.5499\nvn -0.4164 -0.7404 -0.5277\nvn -0.4708 -0.6716 -0.5721\nvn -0.5244 -0.5898 -0.6142\nvn -0.4977 -0.6326 -0.5934\nvn -0.3217 -0.8039 -0.5003\nvn -0.3467 -0.7920 -0.5025\nvn -0.2974 -0.8270 -0.4771\nvn -0.3216 -0.8163 -0.4799\nvn -0.3436 -0.8063 -0.4816\nvn -0.3691 -0.7805 -0.5045\nvn -0.2523 -0.8657 -0.4324\nvn -0.2751 -0.8572 -0.4353\nvn -0.2978 -0.8380 -0.4572\nvn -0.2740 -0.8474 -0.4547\nvn -0.2961 -0.8494 -0.4368\nvn -0.3192 -0.8290 -0.4593\nvn -0.3391 -0.8209 -0.4596\nvn -0.3155 -0.8421 -0.4374\nvn -0.3639 -0.7968 -0.4824\nvn -0.3897 -0.7702 -0.5049\nvn -0.4839 -0.8696 0.0987\nvn -0.4627 -0.8796 0.1104\nvn -0.4876 -0.8617 0.1401\nvn -0.5079 -0.8542 0.1112\nvn -0.4328 -0.8922 0.1288\nvn -0.4561 -0.8745 0.1647\nvn -0.4892 -0.8484 0.2022\nvn -0.5219 -0.8361 0.1688\nvn -0.5458 -0.8275 0.1314\nvn -0.3624 -0.9176 0.1632\nvn -0.3818 -0.9004 0.2088\nvn -0.4218 -0.8870 0.1878\nvn -0.3990 -0.9053 0.1455\nvn -0.4082 -0.8760 0.2568\nvn -0.4507 -0.8623 0.2310\nvn -0.4732 -0.8073 0.3526\nvn -0.5225 -0.7914 0.3171\nvn -0.4854 -0.8301 0.2745\nvn -0.4388 -0.8451 0.3055\nvn -0.5656 -0.7774 0.2752\nvn -0.5260 -0.8163 0.2388\nvn -0.6288 -0.7575 0.1752\nvn -0.5856 -0.7962 0.1522\nvn -0.5599 -0.8046 0.1979\nvn -0.6013 -0.7659 0.2277\nvn -0.3225 -0.9295 0.1788\nvn -0.3393 -0.9127 0.2278\nvn -0.2820 -0.9397 0.1934\nvn -0.2939 -0.9241 0.2440\nvn -0.3115 -0.9023 0.2980\nvn -0.3609 -0.8899 0.2790\nvn -0.1903 -0.9572 0.2181\nvn -0.1917 -0.9431 0.2718\nvn -0.2458 -0.9341 0.2589\nvn -0.2383 -0.9491 0.2061\nvn -0.1966 -0.9234 0.3295\nvn -0.2567 -0.9139 0.3146\nvn -0.2150 -0.8655 0.4524\nvn -0.2899 -0.8537 0.4326\nvn -0.2722 -0.8870 0.3730\nvn -0.2041 -0.8980 0.3898\nvn -0.3576 -0.8392 0.4096\nvn -0.3324 -0.8744 0.3535\nvn -0.3882 -0.8600 0.3312\nvn -0.4179 -0.8236 0.3834\nvn -0.2723 -0.6640 0.6964\nvn -0.3761 -0.6484 0.6619\nvn -0.3546 -0.7100 0.6084\nvn -0.2570 -0.7250 0.6390\nvn -0.4652 -0.6314 0.6205\nvn -0.4393 -0.6929 0.5718\nvn -0.4119 -0.7485 0.5197\nvn -0.3323 -0.7650 0.5516\nvn -0.2421 -0.7791 0.5783\nvn -0.6077 -0.5988 0.5216\nvn -0.5769 -0.6588 0.4829\nvn -0.5128 -0.6756 0.5298\nvn -0.5421 -0.6142 0.5735\nvn -0.5432 -0.7140 0.4418\nvn -0.4818 -0.7310 0.4833\nvn -0.4498 -0.7805 0.4341\nvn -0.5084 -0.7634 0.3985\nvn -0.3841 -0.7974 0.4655\nvn -0.2274 -0.8261 0.5155\nvn -0.3108 -0.8129 0.4926\nvn -0.6647 -0.5851 0.4645\nvn -0.6318 -0.6443 0.4309\nvn -0.7126 -0.5745 0.4026\nvn -0.6794 -0.6318 0.3732\nvn -0.6432 -0.6847 0.3427\nvn -0.5972 -0.6980 0.3952\nvn -0.7864 -0.5599 0.2607\nvn -0.7507 -0.6153 0.2404\nvn -0.7186 -0.6225 0.3100\nvn -0.7535 -0.5660 0.3345\nvn -0.7126 -0.6662 0.2199\nvn -0.6821 -0.6738 0.2841\nvn -0.6428 -0.7217 0.2570\nvn -0.6723 -0.7133 0.1980\nvn -0.6055 -0.7329 0.3103\nvn -0.5603 -0.7473 0.3572\nvn -0.2315 -0.8819 -0.4108\nvn -0.2538 -0.8746 -0.4132\nvn -0.2120 -0.8965 -0.3889\nvn -0.2334 -0.8900 -0.3917\nvn -0.2533 -0.8840 -0.3930\nvn -0.2742 -0.8675 -0.4151\nvn -0.1763 -0.9216 -0.3459\nvn -0.1961 -0.9167 -0.3482\nvn -0.2143 -0.9041 -0.3698\nvn -0.1934 -0.9097 -0.3675\nvn -0.2149 -0.9120 -0.3495\nvn -0.2336 -0.8986 -0.3714\nvn -0.2501 -0.9033 -0.3485\nvn -0.2696 -0.8890 -0.3702\nvn -0.2519 -0.8936 -0.3714\nvn -0.2328 -0.9074 -0.3499\nvn -0.2896 -0.8734 -0.3915\nvn -0.2721 -0.8782 -0.3933\nvn -0.2931 -0.8613 -0.4150\nvn -0.3110 -0.8557 -0.4135\nvn -0.1603 -0.9321 -0.3247\nvn -0.1796 -0.9280 -0.3265\nvn -0.1464 -0.9415 -0.3035\nvn -0.1644 -0.9380 -0.3050\nvn -0.1818 -0.9346 -0.3058\nvn -0.1975 -0.9239 -0.3278\nvn -0.1240 -0.9570 -0.2621\nvn -0.1404 -0.9547 -0.2624\nvn -0.1516 -0.9469 -0.2836\nvn -0.1339 -0.9498 -0.2827\nvn -0.1565 -0.9522 -0.2623\nvn -0.1678 -0.9440 -0.2840\nvn -0.1888 -0.9467 -0.2608\nvn -0.2006 -0.9380 -0.2826\nvn -0.1842 -0.9411 -0.2837\nvn -0.1721 -0.9497 -0.2617\nvn -0.2152 -0.9278 -0.3047\nvn -0.1984 -0.9312 -0.3059\nvn -0.2149 -0.9200 -0.3278\nvn -0.2319 -0.9162 -0.3268\nvn -0.2460 -0.9351 -0.2549\nvn -0.2576 -0.9291 -0.2653\nvn -0.2464 -0.9298 -0.2733\nvn -0.2360 -0.9374 -0.2561\nvn -0.2733 -0.9198 -0.2815\nvn -0.2622 -0.9199 -0.2915\nvn -0.2472 -0.9220 -0.2980\nvn -0.2321 -0.9323 -0.2775\nvn -0.2207 -0.9406 -0.2580\nvn -0.3089 -0.8964 -0.3179\nvn -0.2972 -0.8958 -0.3304\nvn -0.2784 -0.9089 -0.3104\nvn -0.2909 -0.9089 -0.2988\nvn -0.2826 -0.8972 -0.3394\nvn -0.2645 -0.9102 -0.3186\nvn -0.2484 -0.9129 -0.3238\nvn -0.2670 -0.8997 -0.3454\nvn -0.2316 -0.9247 -0.3022\nvn -0.2052 -0.9437 -0.2594\nvn -0.2169 -0.9350 -0.2806\nvn -0.3288 -0.8818 -0.3380\nvn -0.3160 -0.8815 -0.3509\nvn -0.3482 -0.8662 -0.3584\nvn -0.3360 -0.8655 -0.3716\nvn -0.3216 -0.8668 -0.3811\nvn -0.3021 -0.8825 -0.3604\nvn -0.3568 -0.8476 -0.3929\nvn -0.3696 -0.8480 -0.3799\nvn -0.3430 -0.8486 -0.4028\nvn -0.3274 -0.8516 -0.4093\nvn -0.3065 -0.8693 -0.3878\nvn -0.2861 -0.8853 -0.3665\nvn -0.0808 -0.9960 -0.0372\nvn -0.0739 -0.9973 -0.0008\nvn -0.0849 -0.9964 -0.0001\nvn -0.0932 -0.9950 -0.0353\nvn -0.0646 -0.9973 0.0345\nvn -0.0755 -0.9965 0.0344\nvn -0.0884 -0.9955 0.0330\nvn -0.0988 -0.9951 -0.0000\nvn -0.1067 -0.9937 -0.0344\nvn -0.0389 -0.9936 0.1058\nvn -0.0490 -0.9935 0.1032\nvn -0.0632 -0.9957 0.0683\nvn -0.0535 -0.9961 0.0701\nvn -0.0618 -0.9931 0.0994\nvn -0.0766 -0.9949 0.0661\nvn -0.0979 -0.9911 0.0901\nvn -0.1116 -0.9920 0.0587\nvn -0.0923 -0.9938 0.0626\nvn -0.0786 -0.9923 0.0953\nvn -0.1228 -0.9920 0.0276\nvn -0.1046 -0.9940 0.0310\nvn -0.1405 -0.9894 -0.0354\nvn -0.1228 -0.9918 -0.0342\nvn -0.1143 -0.9935 -0.0012\nvn -0.1329 -0.9911 -0.0031\nvn -0.0218 -0.9894 0.1433\nvn -0.0313 -0.9898 0.1390\nvn -0.0003 -0.9832 0.1826\nvn -0.0113 -0.9840 0.1776\nvn -0.0256 -0.9848 0.1720\nvn -0.0453 -0.9899 0.1346\nvn 0.0535 -0.9606 0.2729\nvn 0.0388 -0.9631 0.2665\nvn 0.0125 -0.9755 0.2194\nvn 0.0242 -0.9739 0.2256\nvn 0.0204 -0.9652 0.2606\nvn -0.0041 -0.9769 0.2136\nvn -0.0302 -0.9680 0.2492\nvn -0.0490 -0.9783 0.2014\nvn -0.0242 -0.9779 0.2075\nvn -0.0028 -0.9670 0.2549\nvn -0.0664 -0.9848 0.1602\nvn -0.0444 -0.9851 0.1664\nvn -0.0621 -0.9897 0.1293\nvn -0.0832 -0.9888 0.1238\nvn -0.1924 -0.9665 0.1701\nvn -0.1491 -0.9724 0.1796\nvn -0.1422 -0.9632 0.2279\nvn -0.1969 -0.9718 0.1297\nvn -0.1582 -0.9776 0.1386\nvn -0.1231 -0.9815 0.1465\nvn -0.1112 -0.9759 0.1877\nvn -0.0997 -0.9666 0.2362\nvn -0.2108 -0.9755 0.0624\nvn -0.1778 -0.9815 0.0708\nvn -0.1674 -0.9805 0.1028\nvn -0.2039 -0.9744 0.0943\nvn -0.1474 -0.9860 0.0780\nvn -0.1358 -0.9845 0.1106\nvn -0.1073 -0.9873 0.1174\nvn -0.1213 -0.9890 0.0846\nvn -0.0930 -0.9837 0.1537\nvn -0.0624 -0.9680 0.2431\nvn -0.0776 -0.9777 0.1949\nvn -0.2190 -0.9752 0.0330\nvn -0.1868 -0.9815 0.0407\nvn -0.2257 -0.9742 0.0040\nvn -0.1961 -0.9805 0.0121\nvn -0.1684 -0.9855 0.0182\nvn -0.1589 -0.9861 0.0478\nvn -0.2373 -0.9699 -0.0550\nvn -0.2099 -0.9766 -0.0469\nvn -0.2032 -0.9790 -0.0172\nvn -0.2327 -0.9723 -0.0245\nvn -0.1839 -0.9821 -0.0416\nvn -0.1774 -0.9841 -0.0109\nvn -0.1534 -0.9881 -0.0066\nvn -0.1614 -0.9862 -0.0375\nvn -0.1446 -0.9892 0.0237\nvn -0.1333 -0.9896 0.0535\nvn -0.4697 -0.8662 -0.1703\nvn -0.4742 -0.8706 -0.1310\nvn -0.5138 -0.8453 -0.1463\nvn -0.5073 -0.8409 -0.1884\nvn -0.4769 -0.8739 -0.0942\nvn -0.5175 -0.8489 -0.1076\nvn -0.5613 -0.8190 -0.1192\nvn -0.5551 -0.8160 -0.1615\nvn -0.5472 -0.8113 -0.2058\nvn -0.4797 -0.8771 -0.0240\nvn -0.5224 -0.8521 -0.0321\nvn -0.5208 -0.8508 -0.0696\nvn -0.4779 -0.8764 -0.0595\nvn -0.5687 -0.8217 -0.0369\nvn -0.5654 -0.8211 -0.0787\nvn -0.6632 -0.7473 -0.0405\nvn -0.6584 -0.7472 -0.0909\nvn -0.6121 -0.7862 -0.0852\nvn -0.6159 -0.7868 -0.0402\nvn -0.6515 -0.7457 -0.1396\nvn -0.6058 -0.7849 -0.1303\nvn -0.6300 -0.7387 -0.2394\nvn -0.5881 -0.7774 -0.2232\nvn -0.5984 -0.7817 -0.1755\nvn -0.6419 -0.7430 -0.1892\nvn -0.4801 -0.8771 0.0101\nvn -0.5234 -0.8520 0.0062\nvn -0.4820 -0.8751 0.0439\nvn -0.5223 -0.8517 0.0423\nvn -0.5675 -0.8220 0.0475\nvn -0.5691 -0.8222 0.0046\nvn -0.5194 -0.8508 0.0795\nvn -0.4819 -0.8730 0.0754\nvn -0.5606 -0.8232 0.0902\nvn -0.6484 -0.7518 0.1199\nvn -0.6034 -0.7906 0.1043\nvn -0.6598 -0.7487 0.0652\nvn -0.6132 -0.7880 0.0550\nvn -0.6169 -0.7870 0.0071\nvn -0.6641 -0.7475 0.0109\nvn -0.8111 -0.5553 0.1837\nvn -0.7738 -0.6106 0.1685\nvn -0.8265 -0.5524 0.1086\nvn -0.7882 -0.6076 0.0976\nvn -0.7478 -0.6583 0.0867\nvn -0.7347 -0.6610 0.1526\nvn -0.8351 -0.5490 -0.0345\nvn -0.7955 -0.6048 -0.0369\nvn -0.7950 -0.6059 0.0292\nvn -0.8341 -0.5505 0.0355\nvn -0.7535 -0.6563 -0.0387\nvn -0.7535 -0.6570 0.0226\nvn -0.7099 -0.7041 0.0167\nvn -0.7091 -0.7040 -0.0403\nvn -0.7051 -0.7051 0.0755\nvn -0.6930 -0.7079 0.1367\nvn -0.8303 -0.5479 -0.1022\nvn -0.7910 -0.6035 -0.1003\nvn -0.8206 -0.5465 -0.1672\nvn -0.7818 -0.6021 -0.1622\nvn -0.7403 -0.6540 -0.1556\nvn -0.7487 -0.6556 -0.0981\nvn -0.7870 -0.5430 -0.2929\nvn -0.7508 -0.5973 -0.2820\nvn -0.7686 -0.5999 -0.2222\nvn -0.8060 -0.5450 -0.2309\nvn -0.7123 -0.6483 -0.2690\nvn -0.7280 -0.6517 -0.2126\nvn -0.6857 -0.6995 -0.2012\nvn -0.6715 -0.6957 -0.2551\nvn -0.6963 -0.7022 -0.1484\nvn -0.7044 -0.7034 -0.0947\nvn -0.1378 -0.9493 0.2827\nvn -0.0898 -0.9526 0.2908\nvn -0.0817 -0.9334 0.3494\nvn -0.1356 -0.9302 0.3410\nvn -0.0114 -0.9531 0.3026\nvn -0.0478 -0.9536 0.2973\nvn 0.0069 -0.9331 0.3596\nvn -0.0342 -0.9342 0.3551\nvn 0.0414 -0.8754 0.4817\nvn -0.0107 -0.8774 0.4796\nvn -0.0220 -0.9090 0.4163\nvn 0.0246 -0.9075 0.4194\nvn -0.0709 -0.8770 0.4753\nvn -0.0753 -0.9085 0.4110\nvn -0.1363 -0.9051 0.4028\nvn -0.1387 -0.8735 0.4666\nvn 0.0198 -0.9513 0.3075\nvn 0.0460 -0.9489 0.3123\nvn 0.0726 -0.9274 0.3671\nvn 0.0423 -0.9308 0.3632\nvn 0.0852 -0.9423 0.3239\nvn 0.0681 -0.9457 0.3178\nvn 0.1197 -0.9185 0.3768\nvn 0.0980 -0.9234 0.3712\nvn 0.1909 -0.8532 0.4855\nvn 0.1604 -0.8607 0.4832\nvn 0.1293 -0.8950 0.4268\nvn 0.1546 -0.8892 0.4306\nvn 0.1262 -0.8667 0.4826\nvn 0.0993 -0.9003 0.4238\nvn 0.0648 -0.9044 0.4218\nvn 0.0868 -0.8718 0.4821\nvn 0.3250 -0.6464 0.6903\nvn 0.2755 -0.6589 0.7000\nvn 0.2495 -0.7179 0.6499\nvn 0.2940 -0.7073 0.6428\nvn 0.2224 -0.6679 0.7103\nvn 0.2010 -0.7269 0.6566\nvn 0.1774 -0.7798 0.6003\nvn 0.2212 -0.7721 0.5958\nvn 0.2613 -0.7619 0.5927\nvn 0.0967 -0.6795 0.7273\nvn 0.0853 -0.7383 0.6691\nvn 0.1467 -0.7334 0.6638\nvn 0.1636 -0.6751 0.7194\nvn 0.0719 -0.7907 0.6080\nvn 0.1282 -0.7863 0.6044\nvn 0.1080 -0.8323 0.5437\nvn 0.0574 -0.8366 0.5448\nvn 0.1523 -0.8268 0.5415\nvn 0.2263 -0.8111 0.5394\nvn 0.1915 -0.8195 0.5402\nvn 0.0206 -0.6817 0.7314\nvn 0.0146 -0.7404 0.6720\nvn -0.0667 -0.6803 0.7299\nvn -0.0657 -0.7399 0.6695\nvn -0.0663 -0.7927 0.6060\nvn 0.0077 -0.7932 0.6089\nvn -0.1569 -0.7350 0.6597\nvn -0.1646 -0.6749 0.7194\nvn -0.1494 -0.7886 0.5965\nvn -0.1436 -0.8346 0.5318\nvn -0.0676 -0.8386 0.5406\nvn -0.0010 -0.8388 0.5445\nvn -0.2355 -0.9587 0.1595\nvn -0.2751 -0.9500 0.1476\nvn -0.2730 -0.9559 0.1086\nvn -0.2368 -0.9642 0.1195\nvn -0.3494 -0.9291 0.1211\nvn -0.3125 -0.9403 0.1351\nvn -0.3425 -0.9357 0.0846\nvn -0.3079 -0.9465 0.0966\nvn -0.3400 -0.9402 0.0200\nvn -0.3091 -0.9505 0.0316\nvn -0.3071 -0.9496 0.0628\nvn -0.3398 -0.9391 0.0509\nvn -0.2775 -0.9598 0.0427\nvn -0.2746 -0.9587 0.0740\nvn -0.2400 -0.9671 0.0846\nvn -0.2456 -0.9679 0.0532\nvn -0.3850 -0.9166 0.1076\nvn -0.4178 -0.9037 0.0935\nvn -0.4104 -0.9099 0.0605\nvn -0.3765 -0.9236 0.0719\nvn -0.4515 -0.8884 0.0825\nvn -0.4444 -0.8944 0.0499\nvn -0.4401 -0.8978 -0.0145\nvn -0.4423 -0.8967 0.0184\nvn -0.4049 -0.9143 -0.0034\nvn -0.4062 -0.9133 0.0281\nvn -0.3728 -0.9271 0.0394\nvn -0.3716 -0.9284 0.0081\nvn -0.4351 -0.8874 -0.1525\nvn -0.4383 -0.8914 -0.1150\nvn -0.4040 -0.9047 -0.1354\nvn -0.4058 -0.9085 -0.0995\nvn -0.4056 -0.9116 -0.0666\nvn -0.4392 -0.8948 -0.0806\nvn -0.3477 -0.9318 -0.1037\nvn -0.3473 -0.9351 -0.0703\nvn -0.3756 -0.9229 -0.0847\nvn -0.3755 -0.9192 -0.1189\nvn -0.3447 -0.9379 -0.0397\nvn -0.3745 -0.9257 -0.0528\nvn -0.3727 -0.9277 -0.0224\nvn -0.3422 -0.9396 -0.0099\nvn -0.4047 -0.9138 -0.0351\nvn -0.4397 -0.8969 -0.0474\nvn -0.3213 -0.9428 -0.0890\nvn -0.3189 -0.9461 -0.0573\nvn -0.2936 -0.9529 -0.0763\nvn -0.2911 -0.9556 -0.0448\nvn -0.2865 -0.9580 -0.0157\nvn -0.3161 -0.9484 -0.0270\nvn -0.2618 -0.9645 -0.0343\nvn -0.2664 -0.9617 -0.0643\nvn -0.2571 -0.9664 -0.0049\nvn -0.2509 -0.9677 0.0235\nvn -0.2823 -0.9592 0.0134\nvn -0.3121 -0.9501 0.0020\nvn -0.7383 0.0000 -0.6745\nvn -0.7350 -0.0909 -0.6719\nvn -0.7518 -0.0889 -0.6534\nvn -0.7552 0.0000 -0.6555\nvn -0.7256 -0.1752 -0.6654\nvn -0.7428 -0.1716 -0.6472\nvn -0.7635 -0.1682 -0.6236\nvn -0.7725 -0.0869 -0.6290\nvn -0.7756 0.0000 -0.6312\nvn -0.6944 -0.3225 -0.6433\nvn -0.7120 -0.3172 -0.6265\nvn -0.7290 -0.2477 -0.6381\nvn -0.7118 -0.2524 -0.6555\nvn -0.7329 -0.3124 -0.6043\nvn -0.7500 -0.2433 -0.6150\nvn -0.7840 -0.3047 -0.5408\nvn -0.8014 -0.2359 -0.5497\nvn -0.7742 -0.2394 -0.5859\nvn -0.7571 -0.3083 -0.5760\nvn -0.8148 -0.1620 -0.5566\nvn -0.7878 -0.1650 -0.5935\nvn -0.8267 0.0000 -0.5626\nvn -0.7999 0.0000 -0.6002\nvn -0.7965 -0.0851 -0.5986\nvn -0.8237 -0.0833 -0.5609\nvn -0.6746 -0.3859 -0.6292\nvn -0.6923 -0.3804 -0.6132\nvn -0.6531 -0.4433 -0.6139\nvn -0.6708 -0.4379 -0.5985\nvn -0.6915 -0.4338 -0.5776\nvn -0.7132 -0.3757 -0.5918\nvn -0.6245 -0.5383 -0.5659\nvn -0.6481 -0.4904 -0.5826\nvn -0.6305 -0.4951 -0.5978\nvn -0.6441 -0.5362 -0.5455\nvn -0.6683 -0.4871 -0.5623\nvn -0.6893 -0.5359 -0.4875\nvn -0.7158 -0.4840 -0.5034\nvn -0.6911 -0.4850 -0.5359\nvn -0.6657 -0.5355 -0.5198\nvn -0.7408 -0.4284 -0.5174\nvn -0.7149 -0.4306 -0.5509\nvn -0.7372 -0.3719 -0.5642\nvn -0.7636 -0.3688 -0.5300\nvn -0.8199 -0.4860 -0.3027\nvn -0.7956 -0.4849 -0.3633\nvn -0.7640 -0.5410 -0.3517\nvn -0.8498 -0.4259 -0.3107\nvn -0.8241 -0.4258 -0.3735\nvn -0.7965 -0.4261 -0.4289\nvn -0.7691 -0.4842 -0.4173\nvn -0.7393 -0.5389 -0.4037\nvn -0.8988 -0.2964 -0.3230\nvn -0.8718 -0.2976 -0.3890\nvn -0.8497 -0.3634 -0.3820\nvn -0.8761 -0.3627 -0.3176\nvn -0.8427 -0.2994 -0.4476\nvn -0.8211 -0.3646 -0.4391\nvn -0.7920 -0.3664 -0.4883\nvn -0.8129 -0.3018 -0.4981\nvn -0.7682 -0.4270 -0.4770\nvn -0.7139 -0.5372 -0.4492\nvn -0.7422 -0.4838 -0.4638\nvn -0.9173 -0.2268 -0.3272\nvn -0.8900 -0.2282 -0.3946\nvn -0.9312 -0.1541 -0.3303\nvn -0.9039 -0.1554 -0.3985\nvn -0.8742 -0.1572 -0.4594\nvn -0.8606 -0.2303 -0.4543\nvn -0.9430 0.0000 -0.3327\nvn -0.9158 -0.0000 -0.4017\nvn -0.9126 -0.0792 -0.4012\nvn -0.9401 -0.0784 -0.3319\nvn -0.8860 -0.0000 -0.4637\nvn -0.8830 -0.0804 -0.4624\nvn -0.8528 -0.0817 -0.5158\nvn -0.8560 -0.0000 -0.5169\nvn -0.8441 -0.1595 -0.5119\nvn -0.8305 -0.2328 -0.5061\nvn 0.0639 -0.9579 0.2797\nvn 0.0991 -0.9384 0.3310\nvn 0.0720 -0.9552 0.2870\nvn 0.1079 -0.9345 0.3392\nvn 0.1480 -0.9080 0.3920\nvn 0.1361 -0.9135 0.3834\nvn 0.0736 -0.9503 0.3025\nvn 0.1083 -0.9273 0.3584\nvn 0.1120 -0.9306 0.3484\nvn 0.0750 -0.9526 0.2948\nvn 0.1473 -0.8984 0.4138\nvn 0.1519 -0.9028 0.4022\nvn 0.2330 -0.8211 0.5210\nvn 0.2397 -0.8280 0.5069\nvn 0.1952 -0.8686 0.4554\nvn 0.1891 -0.8630 0.4686\nvn 0.2331 -0.8362 0.4965\nvn 0.1895 -0.8755 0.4446\nvn 0.1758 -0.8823 0.4366\nvn 0.2155 -0.8451 0.4892\nvn 0.0655 -0.9484 0.3103\nvn 0.0964 -0.9248 0.3681\nvn 0.0507 -0.9473 0.3164\nvn 0.0745 -0.9230 0.3776\nvn 0.1011 -0.8935 0.4376\nvn 0.1310 -0.8949 0.4265\nvn -0.0000 -0.9466 0.3223\nvn -0.0000 -0.9222 0.3866\nvn 0.0419 -0.9227 0.3833\nvn 0.0287 -0.9465 0.3215\nvn 0.0000 -0.8934 0.4492\nvn 0.0574 -0.8926 0.4471\nvn 0.0000 -0.8182 0.5750\nvn 0.0928 -0.8160 0.5706\nvn 0.0739 -0.8579 0.5084\nvn -0.0000 -0.8577 0.5142\nvn 0.1623 -0.8157 0.5552\nvn 0.1311 -0.8572 0.4980\nvn 0.1685 -0.8592 0.4830\nvn 0.2088 -0.8166 0.5381\nvn -0.0000 -0.6048 0.7964\nvn 0.1730 -0.5980 0.7826\nvn 0.1521 -0.6610 0.7348\nvn -0.0000 -0.6632 0.7484\nvn 0.2961 -0.5917 0.7498\nvn 0.2641 -0.6542 0.7087\nvn 0.2295 -0.7140 0.6615\nvn 0.1325 -0.7167 0.6846\nvn -0.0000 -0.7211 0.6929\nvn 0.4065 -0.5932 0.6949\nvn 0.3658 -0.6581 0.6581\nvn 0.3320 -0.6535 0.6802\nvn 0.3715 -0.5885 0.7181\nvn 0.3223 -0.7182 0.6167\nvn 0.2918 -0.7132 0.6374\nvn 0.2497 -0.7682 0.5895\nvn 0.2779 -0.7727 0.5707\nvn 0.1963 -0.7670 0.6109\nvn 0.0000 -0.7708 0.6370\nvn 0.1116 -0.7702 0.6280\nvn 0.4131 -0.6036 0.6819\nvn 0.3727 -0.6677 0.6445\nvn 0.3984 -0.6171 0.6786\nvn 0.3598 -0.6807 0.6381\nvn 0.3191 -0.7383 0.5942\nvn 0.3296 -0.7272 0.6021\nvn 0.3327 -0.6939 0.6386\nvn 0.3675 -0.6326 0.6817\nvn 0.2949 -0.7508 0.5910\nvn 0.2560 -0.8009 0.5414\nvn 0.2762 -0.7907 0.5464\nvn 0.2850 -0.7806 0.5563\nvn -0.2265 -0.8743 -0.4293\nvn -0.2072 -0.8894 -0.4074\nvn -0.1984 -0.8828 -0.4258\nvn -0.1799 -0.8969 -0.4039\nvn -0.1632 -0.9095 -0.3822\nvn -0.1883 -0.9031 -0.3858\nvn -0.1345 -0.8978 -0.4193\nvn -0.1207 -0.9099 -0.3969\nvn -0.1514 -0.9038 -0.4003\nvn -0.1670 -0.8909 -0.4224\nvn -0.1087 -0.9205 -0.3754\nvn -0.1360 -0.9155 -0.3786\nvn -0.0868 -0.9386 -0.3339\nvn -0.1095 -0.9352 -0.3367\nvn -0.1225 -0.9258 -0.3575\nvn -0.0969 -0.9301 -0.3542\nvn -0.1327 -0.9310 -0.3400\nvn -0.1470 -0.9210 -0.3609\nvn -0.1712 -0.9154 -0.3643\nvn -0.1548 -0.9265 -0.3431\nvn -0.1000 -0.9037 -0.4164\nvn -0.0901 -0.9146 -0.3943\nvn -0.0658 -0.9076 -0.4147\nvn -0.0588 -0.9181 -0.3919\nvn -0.0527 -0.9273 -0.3705\nvn -0.0803 -0.9246 -0.3724\nvn 0.0000 -0.9107 -0.4130\nvn 0.0000 -0.9207 -0.3902\nvn -0.0287 -0.9200 -0.3909\nvn -0.0319 -0.9101 -0.4131\nvn 0.0000 -0.9295 -0.3688\nvn -0.0256 -0.9291 -0.3690\nvn -0.0000 -0.9446 -0.3283\nvn -0.0202 -0.9443 -0.3284\nvn -0.0229 -0.9370 -0.3485\nvn -0.0000 -0.9375 -0.3479\nvn -0.0417 -0.9432 -0.3297\nvn -0.0468 -0.9358 -0.3495\nvn -0.0719 -0.9334 -0.3517\nvn -0.0637 -0.9414 -0.3313\nvn 0.0000 -0.9664 -0.2570\nvn -0.0130 -0.9663 -0.2571\nvn -0.0144 -0.9617 -0.2738\nvn 0.0000 -0.9618 -0.2736\nvn -0.0269 -0.9659 -0.2574\nvn -0.0295 -0.9612 -0.2743\nvn -0.0330 -0.9558 -0.2921\nvn -0.0160 -0.9565 -0.2912\nvn -0.0000 -0.9567 -0.2911\nvn -0.0570 -0.9643 -0.2586\nvn -0.0623 -0.9590 -0.2764\nvn -0.0457 -0.9603 -0.2753\nvn -0.0414 -0.9653 -0.2579\nvn -0.0694 -0.9530 -0.2950\nvn -0.0507 -0.9547 -0.2932\nvn -0.0570 -0.9484 -0.3121\nvn -0.0772 -0.9463 -0.3140\nvn -0.0369 -0.9499 -0.3104\nvn -0.0000 -0.9510 -0.3091\nvn -0.0180 -0.9507 -0.3096\nvn -0.0729 -0.9630 -0.2595\nvn -0.0800 -0.9572 -0.2780\nvn -0.0898 -0.9613 -0.2605\nvn -0.0977 -0.9551 -0.2796\nvn -0.1079 -0.9480 -0.2993\nvn -0.0882 -0.9508 -0.2970\nvn -0.1161 -0.9526 -0.2813\nvn -0.1066 -0.9593 -0.2613\nvn -0.1270 -0.9450 -0.3015\nvn -0.1404 -0.9362 -0.3222\nvn -0.1192 -0.9401 -0.3194\nvn -0.0985 -0.9434 -0.3167\nvn -0.0700 -0.9968 -0.0397\nvn -0.0636 -0.9980 -0.0027\nvn -0.0592 -0.9973 -0.0428\nvn -0.0542 -0.9985 -0.0050\nvn -0.0469 -0.9984 0.0324\nvn -0.0558 -0.9979 0.0340\nvn -0.0389 -0.9980 -0.0494\nvn -0.0358 -0.9993 -0.0109\nvn -0.0447 -0.9990 -0.0079\nvn -0.0491 -0.9977 -0.0462\nvn -0.0306 -0.9991 0.0282\nvn -0.0389 -0.9988 0.0305\nvn -0.0130 -0.9939 0.1097\nvn -0.0186 -0.9938 0.1097\nvn -0.0301 -0.9971 0.0694\nvn -0.0237 -0.9974 0.0682\nvn -0.0243 -0.9937 0.1090\nvn -0.0376 -0.9968 0.0703\nvn -0.0450 -0.9965 0.0704\nvn -0.0316 -0.9937 0.1080\nvn -0.0291 -0.9982 -0.0526\nvn -0.0265 -0.9996 -0.0137\nvn -0.0191 -0.9983 -0.0549\nvn -0.0178 -0.9997 -0.0163\nvn -0.0151 -0.9996 0.0239\nvn -0.0231 -0.9994 0.0258\nvn 0.0000 -0.9984 -0.0572\nvn 0.0000 -0.9998 -0.0187\nvn -0.0087 -0.9998 -0.0177\nvn -0.0095 -0.9983 -0.0569\nvn 0.0000 -0.9998 0.0220\nvn -0.0076 -0.9997 0.0223\nvn 0.0000 -0.9941 0.1086\nvn -0.0022 -0.9941 0.1088\nvn -0.0053 -0.9979 0.0645\nvn 0.0000 -0.9980 0.0639\nvn -0.0049 -0.9940 0.1092\nvn -0.0113 -0.9978 0.0654\nvn -0.0170 -0.9976 0.0668\nvn -0.0089 -0.9939 0.1096\nvn 0.0177 -0.9651 0.2613\nvn -0.0000 -0.9649 0.2628\nvn 0.0309 -0.9654 0.2589\nvn 0.0156 -0.9786 0.2051\nvn 0.0090 -0.9783 0.2069\nvn -0.0000 -0.9783 0.2070\nvn 0.0435 -0.9675 0.2492\nvn 0.0398 -0.9663 0.2542\nvn 0.0200 -0.9797 0.1995\nvn 0.0189 -0.9790 0.2028\nvn 0.0033 -0.9880 0.1546\nvn 0.0008 -0.9882 0.1534\nvn 0.0035 -0.9878 0.1556\nvn 0.0000 -0.9877 0.1562\nvn 0.0026 -0.9878 0.1560\nvn 0.0438 -0.9689 0.2434\nvn 0.0397 -0.9706 0.2376\nvn 0.0138 -0.9813 0.1919\nvn 0.0176 -0.9804 0.1960\nvn 0.0335 -0.9723 0.2315\nvn 0.0071 -0.9822 0.1876\nvn -0.0139 -0.9891 0.1465\nvn -0.0079 -0.9887 0.1494\nvn -0.0024 -0.9885 0.1515\nvn -0.6299 -0.0000 -0.7767\nvn -0.6060 -0.0000 -0.7954\nvn -0.6011 -0.1147 -0.7909\nvn -0.6257 -0.1104 -0.7722\nvn -0.5713 -0.0000 -0.8207\nvn -0.5668 -0.1197 -0.8151\nvn -0.5528 -0.2325 -0.8002\nvn -0.5883 -0.2224 -0.7774\nvn -0.6130 -0.2142 -0.7605\nvn -0.4568 -0.0000 -0.8896\nvn -0.4524 -0.1323 -0.8819\nvn -0.5181 -0.1257 -0.8460\nvn -0.5235 -0.0000 -0.8520\nvn -0.4384 -0.2564 -0.8614\nvn -0.5046 -0.2437 -0.8282\nvn -0.3936 -0.4637 -0.7938\nvn -0.4580 -0.4436 -0.7704\nvn -0.4834 -0.3505 -0.8022\nvn -0.4185 -0.3674 -0.8306\nvn -0.5068 -0.4250 -0.7500\nvn -0.5326 -0.3345 -0.7775\nvn -0.5707 -0.3935 -0.7208\nvn -0.5945 -0.3087 -0.7425\nvn -0.5682 -0.3208 -0.7578\nvn -0.5439 -0.4078 -0.7334\nvn -0.3695 -0.0000 -0.9292\nvn -0.3647 -0.1392 -0.9207\nvn -0.2590 -0.0000 -0.9659\nvn -0.2560 -0.1454 -0.9557\nvn -0.2462 -0.2805 -0.9277\nvn -0.3528 -0.2691 -0.8962\nvn 0.0000 0.0000 -1.0000\nvn 0.0000 -0.1515 -0.9885\nvn -0.1301 -0.1497 -0.9801\nvn -0.1322 0.0000 -0.9912\nvn -0.0000 -0.2912 -0.9567\nvn -0.1251 -0.2887 -0.9492\nvn -0.0000 -0.5150 -0.8572\nvn -0.1084 -0.5116 -0.8524\nvn -0.1174 -0.4097 -0.9046\nvn -0.0000 -0.4138 -0.9104\nvn -0.2158 -0.4999 -0.8388\nvn -0.2324 -0.3997 -0.8867\nvn -0.3344 -0.3846 -0.8604\nvn -0.3126 -0.4833 -0.8178\nvn 0.0000 -0.7554 -0.6552\nvn -0.0729 -0.7530 -0.6539\nvn -0.0811 -0.7112 -0.6982\nvn 0.0000 -0.7150 -0.6991\nvn -0.1487 -0.7440 -0.6514\nvn -0.1637 -0.7020 -0.6931\nvn -0.1808 -0.6485 -0.7394\nvn -0.0896 -0.6596 -0.7463\nvn -0.0000 -0.6627 -0.7489\nvn -0.2865 -0.7129 -0.6401\nvn -0.3119 -0.6675 -0.6761\nvn -0.2426 -0.6864 -0.6856\nvn -0.2206 -0.7306 -0.6462\nvn -0.3392 -0.6121 -0.7144\nvn -0.2652 -0.6323 -0.7280\nvn -0.2891 -0.5651 -0.7727\nvn -0.3667 -0.5447 -0.7542\nvn -0.1980 -0.5825 -0.7883\nvn -0.0000 -0.5979 -0.8016\nvn -0.0991 -0.5934 -0.7988\nvn -0.3425 -0.6934 -0.6339\nvn -0.3709 -0.6468 -0.6664\nvn -0.3896 -0.6735 -0.6281\nvn -0.4189 -0.6257 -0.6580\nvn -0.4487 -0.5696 -0.6886\nvn -0.4001 -0.5905 -0.7009\nvn -0.4873 -0.5877 -0.6458\nvn -0.4570 -0.6062 -0.6509\nvn -0.4278 -0.6539 -0.6240\nvn -0.5160 -0.5322 -0.6712\nvn -0.4870 -0.5496 -0.6788\nvn -0.5159 -0.4843 -0.7066\nvn -0.5445 -0.4674 -0.6965\nvn -0.4787 -0.5027 -0.7198\nvn -0.4294 -0.5235 -0.7359\nvn 0.0000 -0.9708 -0.2400\nvn -0.0119 -0.9707 -0.2400\nvn 0.0000 -0.9752 -0.2214\nvn -0.0111 -0.9751 -0.2214\nvn -0.0231 -0.9750 -0.2211\nvn -0.0247 -0.9704 -0.2400\nvn 0.0000 -0.9840 -0.1784\nvn -0.0102 -0.9839 -0.1783\nvn -0.0105 -0.9796 -0.2008\nvn 0.0000 -0.9796 -0.2011\nvn -0.0211 -0.9839 -0.1772\nvn -0.0218 -0.9795 -0.2004\nvn -0.0447 -0.9837 -0.1744\nvn -0.0465 -0.9790 -0.1985\nvn -0.0339 -0.9793 -0.1994\nvn -0.0326 -0.9838 -0.1761\nvn -0.0492 -0.9742 -0.2203\nvn -0.0357 -0.9747 -0.2208\nvn -0.0383 -0.9700 -0.2401\nvn -0.0525 -0.9693 -0.2403\nvn -0.0000 -0.9882 -0.1535\nvn -0.0100 -0.9882 -0.1528\nvn 0.0000 -0.9922 -0.1250\nvn -0.0099 -0.9921 -0.1248\nvn -0.0203 -0.9922 -0.1231\nvn -0.0206 -0.9882 -0.1519\nvn -0.0098 -0.9957 -0.0926\nvn 0.0000 -0.9956 -0.0936\nvn -0.0200 -0.9956 -0.0913\nvn -0.0411 -0.9955 -0.0859\nvn -0.0304 -0.9956 -0.0887\nvn -0.0423 -0.9921 -0.1184\nvn -0.0312 -0.9921 -0.1212\nvn -0.0318 -0.9882 -0.1500\nvn -0.0434 -0.9880 -0.1480\nvn -0.0865 -0.9936 -0.0728\nvn -0.0745 -0.9943 -0.0759\nvn -0.0907 -0.9902 -0.1062\nvn -0.0780 -0.9910 -0.1092\nvn -0.0657 -0.9915 -0.1123\nvn -0.0631 -0.9949 -0.0792\nvn -0.0983 -0.9812 -0.1660\nvn -0.0841 -0.9822 -0.1682\nvn -0.0810 -0.9869 -0.1399\nvn -0.0944 -0.9860 -0.1371\nvn -0.0705 -0.9828 -0.1704\nvn -0.0679 -0.9874 -0.1427\nvn -0.0555 -0.9878 -0.1454\nvn -0.0573 -0.9833 -0.1726\nvn -0.0538 -0.9918 -0.1156\nvn -0.0519 -0.9952 -0.0825\nvn -0.1028 -0.9758 -0.1928\nvn -0.0881 -0.9770 -0.1944\nvn -0.1086 -0.9700 -0.2177\nvn -0.0929 -0.9714 -0.2185\nvn -0.0779 -0.9726 -0.2192\nvn -0.0736 -0.9779 -0.1959\nvn -0.0993 -0.9655 -0.2409\nvn -0.1155 -0.9637 -0.2408\nvn -0.0830 -0.9670 -0.2407\nvn -0.0677 -0.9683 -0.2405\nvn -0.0631 -0.9735 -0.2198\nvn -0.0599 -0.9785 -0.1972\nvn -0.1316 -0.9617 -0.2404\nvn -0.1238 -0.9684 -0.2165\nvn -0.1389 -0.9666 -0.2153\nvn -0.1468 -0.9597 -0.2396\nvn -0.1126 -0.9801 -0.1636\nvn -0.1178 -0.9745 -0.1910\nvn -0.1272 -0.9787 -0.1614\nvn -0.1323 -0.9730 -0.1890\nvn -0.1592 -0.9745 -0.1582\nvn -0.1638 -0.9688 -0.1860\nvn -0.1476 -0.9711 -0.1874\nvn -0.1424 -0.9769 -0.1593\nvn -0.1706 -0.9620 -0.2130\nvn -0.1539 -0.9647 -0.2138\nvn -0.1625 -0.9574 -0.2388\nvn -0.1787 -0.9547 -0.2378\nvn -0.1083 -0.9850 -0.1345\nvn -0.1040 -0.9892 -0.1034\nvn -0.1182 -0.9878 -0.1012\nvn -0.1227 -0.9836 -0.1320\nvn -0.0991 -0.9926 -0.0704\nvn -0.1134 -0.9912 -0.0685\nvn -0.1469 -0.9868 -0.0676\nvn -0.1289 -0.9893 -0.0676\nvn -0.1513 -0.9835 -0.0990\nvn -0.1340 -0.9860 -0.0995\nvn -0.1381 -0.9818 -0.1302\nvn -0.1552 -0.9794 -0.1289\nvn -0.2416 -0.9667 -0.0849\nvn -0.2141 -0.9737 -0.0777\nvn -0.2438 -0.9630 -0.1150\nvn -0.2177 -0.9702 -0.1068\nvn -0.1930 -0.9759 -0.1023\nvn -0.1895 -0.9792 -0.0721\nvn -0.2466 -0.9537 -0.1721\nvn -0.2218 -0.9612 -0.1639\nvn -0.2198 -0.9660 -0.1360\nvn -0.2460 -0.9586 -0.1431\nvn -0.1986 -0.9669 -0.1600\nvn -0.1959 -0.9718 -0.1310\nvn -0.1743 -0.9762 -0.1293\nvn -0.1775 -0.9714 -0.1579\nvn -0.1711 -0.9802 -0.0995\nvn -0.1667 -0.9836 -0.0692\nvn -0.2473 -0.9485 -0.1980\nvn -0.2238 -0.9557 -0.1914\nvn -0.2469 -0.9433 -0.2221\nvn -0.2258 -0.9500 -0.2155\nvn -0.2062 -0.9550 -0.2133\nvn -0.2017 -0.9614 -0.1871\nvn -0.2296 -0.9436 -0.2384\nvn -0.2468 -0.9384 -0.2418\nvn -0.2121 -0.9481 -0.2370\nvn -0.1958 -0.9515 -0.2374\nvn -0.1877 -0.9590 -0.2124\nvn -0.1821 -0.9655 -0.1861\nvn -0.2639 -0.9309 -0.2525\nvn -0.2689 -0.9347 -0.2326\nvn -0.2887 -0.9249 -0.2473\nvn -0.2829 -0.9213 -0.2669\nvn -0.2724 -0.9447 -0.1827\nvn -0.2704 -0.9396 -0.2097\nvn -0.2959 -0.9346 -0.1972\nvn -0.2939 -0.9293 -0.2235\nvn -0.3409 -0.9113 -0.2309\nvn -0.3364 -0.9058 -0.2577\nvn -0.3147 -0.9183 -0.2400\nvn -0.3197 -0.9233 -0.2130\nvn -0.3285 -0.9015 -0.2817\nvn -0.3093 -0.9137 -0.2636\nvn -0.3003 -0.9107 -0.2835\nvn -0.3201 -0.8980 -0.3018\nvn -0.2718 -0.9498 -0.1548\nvn -0.2713 -0.9543 -0.1252\nvn -0.2967 -0.9448 -0.1388\nvn -0.2977 -0.9397 -0.1681\nvn -0.2687 -0.9585 -0.0957\nvn -0.2961 -0.9491 -0.1076\nvn -0.3477 -0.9275 -0.1373\nvn -0.3215 -0.9390 -0.1221\nvn -0.3461 -0.9226 -0.1703\nvn -0.3223 -0.9341 -0.1534\nvn -0.3210 -0.9290 -0.1842\nvn -0.3448 -0.9169 -0.2013\nvn -0.4628 -0.8611 -0.2104\nvn -0.4300 -0.8824 -0.1907\nvn -0.4554 -0.8552 -0.2476\nvn -0.4243 -0.8767 -0.2267\nvn -0.3963 -0.8945 -0.2068\nvn -0.4007 -0.8999 -0.1719\nvn -0.4379 -0.8426 -0.3134\nvn -0.4101 -0.8644 -0.2908\nvn -0.4176 -0.8706 -0.2601\nvn -0.4470 -0.8489 -0.2822\nvn -0.3854 -0.8825 -0.2696\nvn -0.3917 -0.8884 -0.2394\nvn -0.3673 -0.9037 -0.2199\nvn -0.3632 -0.8976 -0.2496\nvn -0.3711 -0.9094 -0.1878\nvn -0.3732 -0.9148 -0.1543\nvn -0.4279 -0.8368 -0.3415\nvn -0.4014 -0.8588 -0.3183\nvn -0.4172 -0.8320 -0.3657\nvn -0.3919 -0.8538 -0.3426\nvn -0.3694 -0.8720 -0.3211\nvn -0.3784 -0.8767 -0.2970\nvn -0.3810 -0.8503 -0.3630\nvn -0.4057 -0.8283 -0.3865\nvn -0.3597 -0.8682 -0.3417\nvn -0.3393 -0.8841 -0.3214\nvn -0.3493 -0.8874 -0.3010\nvn -0.3566 -0.8923 -0.2769\nvn -0.6145 -0.5017 -0.6089\nvn -0.6373 -0.4499 -0.6256\nvn -0.6221 -0.4579 -0.6350\nvn -0.5989 -0.5096 -0.6177\nvn -0.6793 -0.3285 -0.6562\nvn -0.6591 -0.3925 -0.6415\nvn -0.6651 -0.3352 -0.6673\nvn -0.6445 -0.3999 -0.6516\nvn -0.6379 -0.3507 -0.6857\nvn -0.6159 -0.4178 -0.6679\nvn -0.6301 -0.4084 -0.6604\nvn -0.6516 -0.3425 -0.6768\nvn -0.5919 -0.4775 -0.6493\nvn -0.6073 -0.4670 -0.6427\nvn -0.5832 -0.5193 -0.6246\nvn -0.5673 -0.5302 -0.6301\nvn -0.6970 -0.2574 -0.6693\nvn -0.7113 -0.1789 -0.6797\nvn -0.6980 -0.1828 -0.6924\nvn -0.6834 -0.2629 -0.6810\nvn -0.7243 -0.0000 -0.6894\nvn -0.7207 -0.0929 -0.6870\nvn -0.7113 0.0000 -0.7029\nvn -0.7079 -0.0949 -0.6999\nvn -0.6873 0.0000 -0.7263\nvn -0.6837 -0.0991 -0.7230\nvn -0.6955 -0.0970 -0.7119\nvn -0.6993 0.0000 -0.7148\nvn -0.6731 -0.1912 -0.7144\nvn -0.6856 -0.1868 -0.7036\nvn -0.6703 -0.2688 -0.6917\nvn -0.6576 -0.2751 -0.7014\nvn -0.6434 -0.1070 -0.7580\nvn -0.6479 -0.0000 -0.7617\nvn -0.6319 -0.2071 -0.7469\nvn -0.6470 -0.2013 -0.7355\nvn -0.6584 -0.1040 -0.7454\nvn -0.6623 -0.0000 -0.7492\nvn -0.5917 -0.3806 -0.7107\nvn -0.6137 -0.2988 -0.7308\nvn -0.6086 -0.3696 -0.7021\nvn -0.6301 -0.2899 -0.7204\nvn -0.6442 -0.2822 -0.7109\nvn -0.6240 -0.3595 -0.6938\nvn -0.6607 -0.1960 -0.7247\nvn -0.6754 -0.0000 -0.7375\nvn -0.6713 -0.1015 -0.7342\nvn -0.5661 -0.4531 -0.6886\nvn -0.5393 -0.5161 -0.6654\nvn -0.5586 -0.5021 -0.6602\nvn -0.5847 -0.4399 -0.6816\nvn -0.5112 -0.5715 -0.6419\nvn -0.5321 -0.5562 -0.6384\nvn -0.5502 -0.5428 -0.6346\nvn -0.5761 -0.4890 -0.6549\nvn -0.6007 -0.4284 -0.6750\nvn -0.2866 -0.5969 0.7494\nvn -0.3957 -0.5813 0.7110\nvn -0.2999 -0.5244 0.7969\nvn -0.4134 -0.5090 0.7550\nvn -0.5093 -0.4935 0.7050\nvn -0.4889 -0.5644 0.6652\nvn -0.3222 -0.3643 0.8738\nvn -0.4416 -0.3515 0.8255\nvn -0.4286 -0.4325 0.7932\nvn -0.3119 -0.4465 0.8387\nvn -0.5415 -0.3398 0.7690\nvn -0.5271 -0.4182 0.7398\nvn -0.6969 -0.3212 0.6412\nvn -0.6803 -0.3951 0.6173\nvn -0.6098 -0.4058 0.6808\nvn -0.6257 -0.3293 0.7072\nvn -0.6597 -0.4664 0.5893\nvn -0.5908 -0.4787 0.6495\nvn -0.5679 -0.5486 0.6136\nvn -0.6358 -0.5341 0.5572\nvn -0.3307 -0.2775 0.9020\nvn -0.4516 -0.2676 0.8511\nvn -0.3369 -0.1877 0.9227\nvn -0.4591 -0.1803 0.8699\nvn -0.5610 -0.1740 0.8093\nvn -0.5529 -0.2580 0.7923\nvn -0.3421 0.0000 0.9397\nvn -0.4651 0.0000 0.8853\nvn -0.4636 -0.0910 0.8814\nvn -0.3409 -0.0947 0.9353\nvn -0.5676 0.0000 0.8233\nvn -0.5659 -0.0876 0.8198\nvn -0.7270 0.0000 0.6866\nvn -0.7250 -0.0832 0.6837\nvn -0.6520 -0.0851 0.7535\nvn -0.6535 0.0000 0.7569\nvn -0.7195 -0.1648 0.6747\nvn -0.6466 -0.1686 0.7440\nvn -0.6379 -0.2503 0.7283\nvn -0.7100 -0.2442 0.6605\nvn -0.9350 0.0000 0.3545\nvn -0.9322 -0.0801 0.3529\nvn -0.8914 -0.0808 0.4460\nvn -0.8937 0.0000 0.4487\nvn -0.9245 -0.1576 0.3471\nvn -0.8839 -0.1591 0.4397\nvn -0.8367 -0.1604 0.5237\nvn -0.8432 -0.0813 0.5314\nvn -0.8457 -0.0000 0.5337\nvn -0.8948 -0.3039 0.3271\nvn -0.8562 -0.3070 0.4154\nvn -0.8723 -0.2345 0.4291\nvn -0.9118 -0.2324 0.3386\nvn -0.8108 -0.3103 0.4963\nvn -0.8257 -0.2368 0.5120\nvn -0.7720 -0.2399 0.5886\nvn -0.7581 -0.3148 0.5711\nvn -0.7820 -0.1622 0.6018\nvn -0.7901 -0.0000 0.6129\nvn -0.7883 -0.0821 0.6098\nvn -0.8735 -0.3725 0.3133\nvn -0.8363 -0.3763 0.3988\nvn -0.8484 -0.4379 0.2975\nvn -0.8125 -0.4425 0.3795\nvn -0.7693 -0.4485 0.4550\nvn -0.7921 -0.3808 0.4771\nvn -0.7847 -0.5059 0.3582\nvn -0.8194 -0.5003 0.2797\nvn -0.7431 -0.5128 0.4298\nvn -0.6934 -0.5224 0.4962\nvn -0.7190 -0.4561 0.5245\nvn -0.7403 -0.3871 0.5497\nvn -0.8452 -0.4961 0.1987\nvn -0.8755 -0.4341 0.2122\nvn -0.8930 -0.4312 0.1289\nvn -0.8617 -0.4933 0.1189\nvn -0.9241 -0.3011 0.2354\nvn -0.9019 -0.3690 0.2246\nvn -0.9432 -0.2987 0.1456\nvn -0.9202 -0.3665 0.1378\nvn -0.9549 -0.2959 -0.0239\nvn -0.9312 -0.3634 -0.0265\nvn -0.9296 -0.3646 0.0539\nvn -0.9530 -0.2971 0.0592\nvn -0.9033 -0.4281 -0.0293\nvn -0.9018 -0.4294 0.0481\nvn -0.8700 -0.4913 0.0420\nvn -0.8711 -0.4900 -0.0321\nvn -0.9421 -0.2300 0.2442\nvn -0.9553 -0.1561 0.2512\nvn -0.9754 -0.1546 0.1571\nvn -0.9616 -0.2281 0.1523\nvn -0.9664 0.0000 0.2571\nvn -0.9636 -0.0792 0.2552\nvn -0.9869 -0.0000 0.1615\nvn -0.9839 -0.0785 0.1606\nvn -0.9998 -0.0000 -0.0181\nvn -0.9968 -0.0774 -0.0182\nvn -0.9946 -0.0778 0.0689\nvn -0.9975 -0.0000 0.0700\nvn -0.9881 -0.1527 -0.0197\nvn -0.9859 -0.1535 0.0670\nvn -0.9719 -0.2266 0.0634\nvn -0.9740 -0.2257 -0.0214\nvn -0.9629 -0.0777 -0.2582\nvn -0.9661 0.0000 -0.2583\nvn -0.9542 -0.1532 -0.2569\nvn -0.9715 -0.1526 -0.1813\nvn -0.9803 -0.0774 -0.1815\nvn -0.9833 0.0000 -0.1818\nvn -0.9214 -0.2956 -0.2523\nvn -0.9402 -0.2258 -0.2552\nvn -0.9385 -0.2952 -0.1793\nvn -0.9574 -0.2253 -0.1804\nvn -0.9689 -0.2252 -0.1028\nvn -0.9498 -0.2954 -0.1032\nvn -0.9830 -0.1525 -0.1021\nvn -0.9948 -0.0000 -0.1015\nvn -0.9918 -0.0773 -0.1020\nvn -0.8983 -0.3624 -0.2486\nvn -0.8711 -0.4262 -0.2439\nvn -0.8874 -0.4266 -0.1749\nvn -0.9150 -0.3624 -0.1774\nvn -0.8404 -0.4870 -0.2379\nvn -0.8558 -0.4881 -0.1717\nvn -0.8662 -0.4889 -0.1031\nvn -0.8982 -0.4273 -0.1036\nvn -0.9262 -0.3627 -0.1035\nvn 0.3529 -0.5816 0.7329\nvn 0.2992 -0.5940 0.7468\nvn 0.3784 -0.5109 0.7719\nvn 0.3203 -0.5247 0.7888\nvn 0.2587 -0.5341 0.8049\nvn 0.2417 -0.6041 0.7594\nvn 0.4195 -0.3568 0.8347\nvn 0.3546 -0.3695 0.8589\nvn 0.3389 -0.4492 0.8267\nvn 0.4005 -0.4366 0.8056\nvn 0.2858 -0.3777 0.8807\nvn 0.2735 -0.4591 0.8453\nvn 0.1262 -0.3858 0.9139\nvn 0.1212 -0.4685 0.8751\nvn 0.2016 -0.4650 0.8620\nvn 0.2105 -0.3835 0.8992\nvn 0.1145 -0.5448 0.8307\nvn 0.1910 -0.5411 0.8190\nvn 0.1781 -0.6108 0.7715\nvn 0.1066 -0.6153 0.7810\nvn 0.4350 -0.2737 0.8578\nvn 0.3673 -0.2837 0.8858\nvn 0.4463 -0.1857 0.8754\nvn 0.3769 -0.1937 0.9058\nvn 0.3031 -0.1987 0.9320\nvn 0.2958 -0.2913 0.9098\nvn 0.4558 -0.0000 0.8901\nvn 0.3848 -0.0000 0.9230\nvn 0.3827 -0.0986 0.9186\nvn 0.4537 -0.0946 0.8861\nvn 0.3092 -0.0000 0.9510\nvn 0.3076 -0.1016 0.9461\nvn 0.1344 0.0000 0.9909\nvn 0.1337 -0.1036 0.9856\nvn 0.2255 -0.1031 0.9688\nvn 0.2263 -0.0000 0.9741\nvn 0.1325 -0.2029 0.9702\nvn 0.2224 -0.2020 0.9538\nvn 0.2175 -0.2954 0.9303\nvn 0.1299 -0.2974 0.9459\nvn -0.2087 -0.0984 0.9730\nvn -0.2100 0.0000 0.9777\nvn -0.2059 -0.1942 0.9591\nvn -0.0818 -0.1992 0.9765\nvn -0.0838 -0.1012 0.9913\nvn -0.0840 0.0000 0.9965\nvn -0.1952 -0.3747 0.9064\nvn -0.2011 -0.2867 0.9367\nvn -0.0764 -0.3818 0.9211\nvn -0.0794 -0.2929 0.9528\nvn 0.0313 -0.2965 0.9545\nvn 0.0309 -0.3855 0.9222\nvn 0.0311 -0.2021 0.9789\nvn 0.0306 0.0000 0.9995\nvn 0.0311 -0.1029 0.9942\nvn -0.1883 -0.4581 0.8687\nvn -0.1806 -0.5360 0.8247\nvn -0.0707 -0.5430 0.8368\nvn -0.0734 -0.4653 0.8821\nvn -0.1728 -0.6084 0.7746\nvn -0.0681 -0.6147 0.7858\nvn 0.0247 -0.6166 0.7869\nvn 0.0280 -0.5457 0.8375\nvn 0.0298 -0.4685 0.8829\nvn -0.5997 -0.5836 -0.5475\nvn -0.5733 -0.6268 -0.5277\nvn -0.5911 -0.6271 -0.5072\nvn -0.6184 -0.5826 -0.5275\nvn -0.5175 -0.7061 -0.4833\nvn -0.5458 -0.6680 -0.5059\nvn -0.5332 -0.7083 -0.4627\nvn -0.5625 -0.6690 -0.4858\nvn -0.5658 -0.7168 -0.4075\nvn -0.5984 -0.6761 -0.4299\nvn -0.5802 -0.6720 -0.4602\nvn -0.5492 -0.7119 -0.4377\nvn -0.6303 -0.6321 -0.4507\nvn -0.6101 -0.6289 -0.4819\nvn -0.6389 -0.5833 -0.5016\nvn -0.6606 -0.5852 -0.4703\nvn -0.4889 -0.7416 -0.4594\nvn -0.4605 -0.7736 -0.4354\nvn -0.4740 -0.7768 -0.4146\nvn -0.5035 -0.7441 -0.4391\nvn -0.4325 -0.8026 -0.4107\nvn -0.4451 -0.8060 -0.3903\nvn -0.4684 -0.8167 -0.3372\nvn -0.4570 -0.8109 -0.3655\nvn -0.5002 -0.7872 -0.3608\nvn -0.4872 -0.7814 -0.3900\nvn -0.5182 -0.7485 -0.4139\nvn -0.5328 -0.7538 -0.3846\nvn -0.4989 -0.8355 -0.2302\nvn -0.5365 -0.8060 -0.2503\nvn -0.5251 -0.7998 -0.2908\nvn -0.4893 -0.8295 -0.2694\nvn -0.6150 -0.7338 -0.2886\nvn -0.5756 -0.7720 -0.2695\nvn -0.5992 -0.7282 -0.3329\nvn -0.5617 -0.7661 -0.3123\nvn -0.5475 -0.7599 -0.3504\nvn -0.5824 -0.7224 -0.3728\nvn -0.5128 -0.7934 -0.3280\nvn -0.4792 -0.8230 -0.3049\nvn -0.6546 -0.6911 -0.3063\nvn -0.6930 -0.6445 -0.3232\nvn -0.6725 -0.6402 -0.3714\nvn -0.6361 -0.6861 -0.3530\nvn -0.7298 -0.5942 -0.3381\nvn -0.7069 -0.5910 -0.3886\nvn -0.6837 -0.5879 -0.4324\nvn -0.6511 -0.6360 -0.4142\nvn -0.6173 -0.6810 -0.3939\nvn 0.0000 -0.5384 0.8427\nvn 0.1916 -0.5342 0.8233\nvn 0.0000 -0.4721 0.8815\nvn 0.2105 -0.4637 0.8606\nvn 0.3557 -0.4545 0.8166\nvn 0.3280 -0.5237 0.7862\nvn 0.0000 -0.3249 0.9458\nvn 0.2411 -0.3168 0.9173\nvn 0.2263 -0.3930 0.8913\nvn 0.0000 -0.3982 0.9173\nvn 0.4027 -0.3075 0.8622\nvn 0.3818 -0.3810 0.8420\nvn 0.5320 -0.3049 0.7899\nvn 0.5079 -0.3795 0.7733\nvn 0.4687 -0.3766 0.7991\nvn 0.4933 -0.3020 0.8157\nvn 0.4781 -0.4530 0.7525\nvn 0.4406 -0.4492 0.7773\nvn 0.4072 -0.5206 0.7504\nvn 0.4446 -0.5245 0.7262\nvn -0.0000 -0.2453 0.9694\nvn 0.2521 -0.2409 0.9372\nvn -0.0000 -0.1662 0.9861\nvn 0.2612 -0.1612 0.9517\nvn 0.4327 -0.1552 0.8881\nvn 0.4206 -0.2312 0.8773\nvn 0.0000 0.0000 1.0000\nvn 0.2683 0.0000 0.9633\nvn 0.2661 -0.0815 0.9605\nvn 0.0000 -0.0832 0.9965\nvn 0.4431 -0.0000 0.8964\nvn 0.4411 -0.0777 0.8941\nvn 0.5771 -0.0000 0.8167\nvn 0.5748 -0.0769 0.8147\nvn 0.5342 -0.0762 0.8419\nvn 0.5378 -0.0000 0.8431\nvn 0.5655 -0.1534 0.8103\nvn 0.5264 -0.1517 0.8366\nvn 0.5118 -0.2274 0.8284\nvn 0.5520 -0.2293 0.8017\nvn 0.5142 -0.0893 0.8530\nvn 0.5174 0.0000 0.8558\nvn 0.5065 -0.1765 0.8440\nvn 0.5484 -0.1668 0.8194\nvn 0.5574 -0.0842 0.8260\nvn 0.5597 0.0000 0.8287\nvn 0.4760 -0.3424 0.8101\nvn 0.4933 -0.2606 0.8299\nvn 0.5161 -0.3269 0.7916\nvn 0.5351 -0.2480 0.8076\nvn 0.5559 -0.2368 0.7968\nvn 0.5370 -0.3139 0.7830\nvn 0.5704 -0.1587 0.8059\nvn 0.5820 -0.0000 0.8132\nvn 0.5785 -0.0798 0.8118\nvn 0.4543 -0.4202 0.7855\nvn 0.4288 -0.4953 0.7555\nvn 0.4653 -0.4782 0.7449\nvn 0.4930 -0.4042 0.7705\nvn 0.4000 -0.5656 0.7212\nvn 0.4336 -0.5499 0.7139\nvn 0.4503 -0.5349 0.7149\nvn 0.4837 -0.4636 0.7424\nvn 0.5125 -0.3895 0.7653\nvn 0.0000 -0.7887 -0.6148\nvn -0.0660 -0.7858 -0.6149\nvn 0.0000 -0.8152 -0.5791\nvn -0.0593 -0.8135 -0.5786\nvn -0.1218 -0.8067 -0.5783\nvn -0.1342 -0.7787 -0.6129\nvn 0.0000 -0.8567 -0.5158\nvn -0.0483 -0.8555 -0.5156\nvn -0.0537 -0.8359 -0.5462\nvn 0.0000 -0.8380 -0.5457\nvn -0.0996 -0.8505 -0.5164\nvn -0.1097 -0.8307 -0.5458\nvn -0.1991 -0.8320 -0.5177\nvn -0.2181 -0.8092 -0.5455\nvn -0.1660 -0.8212 -0.5459\nvn -0.1501 -0.8429 -0.5167\nvn -0.2397 -0.7821 -0.5751\nvn -0.1824 -0.7964 -0.5767\nvn -0.2012 -0.7662 -0.6103\nvn -0.2619 -0.7506 -0.6066\nvn 0.0000 -0.8732 -0.4873\nvn -0.0438 -0.8718 -0.4880\nvn 0.0000 -0.8872 -0.4613\nvn -0.0394 -0.8863 -0.4614\nvn -0.0812 -0.8828 -0.4627\nvn -0.0896 -0.8680 -0.4884\nvn -0.0356 -0.8988 -0.4370\nvn 0.0000 -0.8998 -0.4363\nvn -0.0729 -0.8961 -0.4378\nvn -0.1484 -0.8846 -0.4421\nvn -0.1114 -0.8911 -0.4399\nvn -0.1643 -0.8692 -0.4663\nvn -0.1229 -0.8773 -0.4640\nvn -0.1364 -0.8611 -0.4899\nvn -0.1805 -0.8521 -0.4912\nvn -0.2476 -0.8573 -0.4514\nvn -0.2695 -0.8381 -0.4744\nvn -0.2382 -0.8492 -0.4714\nvn -0.2172 -0.8671 -0.4483\nvn -0.3177 -0.7917 -0.5218\nvn -0.2932 -0.8164 -0.4976\nvn -0.2834 -0.8058 -0.5200\nvn -0.2597 -0.8289 -0.4954\nvn -0.2226 -0.8410 -0.4932\nvn -0.2433 -0.8196 -0.5187\nvn -0.2024 -0.8599 -0.4686\nvn -0.1845 -0.8762 -0.4451\nvn -0.3439 -0.7638 -0.5463\nvn -0.3709 -0.7318 -0.5718\nvn -0.3341 -0.7490 -0.5721\nvn -0.3078 -0.7794 -0.5458\nvn -0.3990 -0.6957 -0.5974\nvn -0.3612 -0.7139 -0.5999\nvn -0.3159 -0.7327 -0.6028\nvn -0.2900 -0.7661 -0.5735\nvn -0.2663 -0.7947 -0.5454\nvn 0.3858 -0.8283 -0.4062\nvn 0.3744 -0.8276 -0.4182\nvn 0.4008 -0.8023 -0.4424\nvn 0.4133 -0.8019 -0.4314\nvn 0.3615 -0.8290 -0.4268\nvn 0.3871 -0.8043 -0.4508\nvn 0.4137 -0.7771 -0.4743\nvn 0.4282 -0.7737 -0.4669\nvn 0.4417 -0.7727 -0.4558\nvn 0.3314 -0.8367 -0.4361\nvn 0.3556 -0.8140 -0.4592\nvn 0.3720 -0.8085 -0.4560\nvn 0.3472 -0.8319 -0.4329\nvn 0.3811 -0.7890 -0.4819\nvn 0.3980 -0.7821 -0.4795\nvn 0.4344 -0.7302 -0.5273\nvn 0.4521 -0.7209 -0.5252\nvn 0.4248 -0.7531 -0.5024\nvn 0.4075 -0.7609 -0.5050\nvn 0.4687 -0.7137 -0.5205\nvn 0.4410 -0.7467 -0.4979\nvn 0.4994 -0.7052 -0.5033\nvn 0.4706 -0.7403 -0.4802\nvn 0.4562 -0.7425 -0.4904\nvn 0.4844 -0.7082 -0.5136\nvn 0.3142 -0.8425 -0.4376\nvn 0.3379 -0.8212 -0.4599\nvn 0.2955 -0.8496 -0.4369\nvn 0.3186 -0.8291 -0.4594\nvn 0.3431 -0.8064 -0.4817\nvn 0.3628 -0.7970 -0.4828\nvn 0.2523 -0.8657 -0.4324\nvn 0.2740 -0.8474 -0.4547\nvn 0.2976 -0.8381 -0.4572\nvn 0.2749 -0.8573 -0.4353\nvn 0.2974 -0.8270 -0.4771\nvn 0.3214 -0.8163 -0.4799\nvn 0.3474 -0.7780 -0.5236\nvn 0.3727 -0.7646 -0.5258\nvn 0.3466 -0.7921 -0.5025\nvn 0.3217 -0.8039 -0.5003\nvn 0.3951 -0.7523 -0.5272\nvn 0.3687 -0.7807 -0.5046\nvn 0.3888 -0.7704 -0.5053\nvn 0.4156 -0.7405 -0.5281\nvn 0.4583 -0.6362 -0.6207\nvn 0.4835 -0.6192 -0.6187\nvn 0.4553 -0.6619 -0.5955\nvn 0.4299 -0.6779 -0.5963\nvn 0.5047 -0.6041 -0.6167\nvn 0.4776 -0.6465 -0.5950\nvn 0.4498 -0.6854 -0.5726\nvn 0.4274 -0.6998 -0.5724\nvn 0.4016 -0.7155 -0.5716\nvn 0.5416 -0.5770 -0.6114\nvn 0.5158 -0.6195 -0.5917\nvn 0.4973 -0.6326 -0.5937\nvn 0.5241 -0.5897 -0.6145\nvn 0.4889 -0.6595 -0.5710\nvn 0.4703 -0.6717 -0.5724\nvn 0.4428 -0.7079 -0.5503\nvn 0.4618 -0.6962 -0.5496\nvn 0.4224 -0.7204 -0.5502\nvn 0.3740 -0.7484 -0.5477\nvn 0.3997 -0.7342 -0.5488\nvn 0.5584 -0.5652 -0.6072\nvn 0.5330 -0.6082 -0.5882\nvn 0.5744 -0.5553 -0.6014\nvn 0.5496 -0.5982 -0.5832\nvn 0.5234 -0.6393 -0.5634\nvn 0.5067 -0.6484 -0.5682\nvn 0.6065 -0.5400 -0.5836\nvn 0.5818 -0.5840 -0.5660\nvn 0.5657 -0.5902 -0.5758\nvn 0.5904 -0.5466 -0.5938\nvn 0.5555 -0.6267 -0.5465\nvn 0.5396 -0.6318 -0.5565\nvn 0.5123 -0.6714 -0.5355\nvn 0.5279 -0.6670 -0.5258\nvn 0.4963 -0.6777 -0.5426\nvn 0.4795 -0.6862 -0.5470\nvn 0.4836 -0.8683 0.1105\nvn 0.5080 -0.8526 0.1227\nvn 0.4872 -0.8603 0.1504\nvn 0.4620 -0.8785 0.1219\nvn 0.5461 -0.8256 0.1418\nvn 0.5216 -0.8344 0.1780\nvn 0.4885 -0.8469 0.2099\nvn 0.4553 -0.8732 0.1740\nvn 0.4313 -0.8914 0.1392\nvn 0.6290 -0.7555 0.1832\nvn 0.6007 -0.7644 0.2342\nvn 0.5595 -0.8029 0.2057\nvn 0.5859 -0.7941 0.1616\nvn 0.5648 -0.7762 0.2802\nvn 0.5253 -0.8148 0.2452\nvn 0.4724 -0.8065 0.3554\nvn 0.4381 -0.8441 0.3093\nvn 0.4846 -0.8289 0.2795\nvn 0.5217 -0.7905 0.3209\nvn 0.4072 -0.8750 0.2619\nvn 0.4498 -0.8610 0.2375\nvn 0.3600 -0.9171 0.1710\nvn 0.3970 -0.9046 0.1549\nvn 0.4205 -0.8860 0.1956\nvn 0.3804 -0.8994 0.2153\nvn 0.6723 -0.7114 0.2048\nvn 0.6421 -0.7203 0.2622\nvn 0.7125 -0.6644 0.2254\nvn 0.6814 -0.6727 0.2883\nvn 0.6423 -0.6840 0.3457\nvn 0.6046 -0.7320 0.3142\nvn 0.7865 -0.5582 0.2643\nvn 0.7531 -0.5650 0.3371\nvn 0.7181 -0.6214 0.3134\nvn 0.7506 -0.6136 0.2449\nvn 0.7120 -0.5740 0.4045\nvn 0.6786 -0.6312 0.3756\nvn 0.6072 -0.5988 0.5223\nvn 0.5762 -0.6587 0.4839\nvn 0.6310 -0.6440 0.4325\nvn 0.6640 -0.5849 0.4658\nvn 0.5425 -0.7137 0.4431\nvn 0.5963 -0.6976 0.3973\nvn 0.5594 -0.7466 0.3600\nvn 0.5076 -0.7629 0.4004\nvn 0.2723 -0.6640 0.6964\nvn 0.2570 -0.7250 0.6391\nvn 0.3546 -0.7100 0.6085\nvn 0.3760 -0.6484 0.6620\nvn 0.2421 -0.7790 0.5784\nvn 0.3323 -0.7649 0.5519\nvn 0.4117 -0.7483 0.5202\nvn 0.4391 -0.6928 0.5720\nvn 0.4650 -0.6314 0.6206\nvn 0.2149 -0.8652 0.4530\nvn 0.2898 -0.8533 0.4335\nvn 0.3107 -0.8126 0.4931\nvn 0.2274 -0.8260 0.5158\nvn 0.3573 -0.8387 0.4110\nvn 0.3838 -0.7970 0.4663\nvn 0.4493 -0.7801 0.4354\nvn 0.4174 -0.8230 0.3854\nvn 0.4813 -0.7308 0.4841\nvn 0.5418 -0.6142 0.5738\nvn 0.5123 -0.6755 0.5303\nvn 0.2037 -0.8976 0.3908\nvn 0.2718 -0.8865 0.3745\nvn 0.1958 -0.9231 0.3310\nvn 0.2560 -0.9133 0.3167\nvn 0.3106 -0.9016 0.3009\nvn 0.3320 -0.8737 0.3556\nvn 0.1880 -0.9571 0.2207\nvn 0.2358 -0.9489 0.2098\nvn 0.2443 -0.9337 0.2618\nvn 0.1903 -0.9428 0.2738\nvn 0.2794 -0.9395 0.1983\nvn 0.2924 -0.9236 0.2480\nvn 0.3378 -0.9119 0.2330\nvn 0.3200 -0.9291 0.1852\nvn 0.3600 -0.8890 0.2830\nvn 0.3876 -0.8592 0.3341\nvn 0.2536 -0.8746 -0.4132\nvn 0.2315 -0.8819 -0.4108\nvn 0.2735 -0.8677 -0.4151\nvn 0.2527 -0.8841 -0.3930\nvn 0.2332 -0.8901 -0.3917\nvn 0.2120 -0.8965 -0.3889\nvn 0.3087 -0.8564 -0.4138\nvn 0.2918 -0.8617 -0.4151\nvn 0.2872 -0.8741 -0.3917\nvn 0.2707 -0.8786 -0.3934\nvn 0.2478 -0.9040 -0.3484\nvn 0.2316 -0.9077 -0.3498\nvn 0.2506 -0.8940 -0.3715\nvn 0.2672 -0.8897 -0.3702\nvn 0.2144 -0.9121 -0.3495\nvn 0.2330 -0.8988 -0.3714\nvn 0.1763 -0.9216 -0.3459\nvn 0.1934 -0.9097 -0.3675\nvn 0.2141 -0.9041 -0.3698\nvn 0.1960 -0.9167 -0.3482\nvn 0.3239 -0.8527 -0.4099\nvn 0.3380 -0.8501 -0.4038\nvn 0.3164 -0.8684 -0.3817\nvn 0.3028 -0.8704 -0.3882\nvn 0.3609 -0.8506 -0.3824\nvn 0.3501 -0.8496 -0.3945\nvn 0.3387 -0.8693 -0.3600\nvn 0.3288 -0.8678 -0.3726\nvn 0.2991 -0.8996 -0.3183\nvn 0.2899 -0.8982 -0.3305\nvn 0.3086 -0.8839 -0.3514\nvn 0.3190 -0.8850 -0.3390\nvn 0.2773 -0.8989 -0.3393\nvn 0.2968 -0.8842 -0.3606\nvn 0.2824 -0.8865 -0.3666\nvn 0.2634 -0.9007 -0.3453\nvn 0.2390 -0.9370 -0.2549\nvn 0.2306 -0.9388 -0.2560\nvn 0.2405 -0.9315 -0.2729\nvn 0.2499 -0.9313 -0.2650\nvn 0.2166 -0.9416 -0.2579\nvn 0.2278 -0.9334 -0.2772\nvn 0.2425 -0.9234 -0.2977\nvn 0.2557 -0.9219 -0.2911\nvn 0.2644 -0.9225 -0.2812\nvn 0.1871 -0.9471 -0.2607\nvn 0.1988 -0.9384 -0.2825\nvn 0.2140 -0.9357 -0.2804\nvn 0.2025 -0.9443 -0.2593\nvn 0.2132 -0.9283 -0.3045\nvn 0.2285 -0.9255 -0.3019\nvn 0.2450 -0.9139 -0.3236\nvn 0.2298 -0.9168 -0.3267\nvn 0.2595 -0.9118 -0.3183\nvn 0.2815 -0.9119 -0.2987\nvn 0.2714 -0.9111 -0.3102\nvn 0.1712 -0.9499 -0.2616\nvn 0.1832 -0.9413 -0.2836\nvn 0.1561 -0.9523 -0.2623\nvn 0.1674 -0.9441 -0.2839\nvn 0.1814 -0.9347 -0.3058\nvn 0.1973 -0.9314 -0.3058\nvn 0.1240 -0.9570 -0.2621\nvn 0.1339 -0.9498 -0.2827\nvn 0.1515 -0.9469 -0.2836\nvn 0.1403 -0.9547 -0.2624\nvn 0.1464 -0.9415 -0.3035\nvn 0.1643 -0.9381 -0.3050\nvn 0.1795 -0.9280 -0.3265\nvn 0.1603 -0.9321 -0.3247\nvn 0.1969 -0.9240 -0.3277\nvn 0.2137 -0.9203 -0.3278\nvn 0.0808 -0.9960 -0.0372\nvn 0.0930 -0.9950 -0.0353\nvn 0.0848 -0.9964 -0.0001\nvn 0.0739 -0.9973 -0.0008\nvn 0.1059 -0.9938 -0.0343\nvn 0.0980 -0.9952 0.0000\nvn 0.0877 -0.9956 0.0330\nvn 0.0754 -0.9966 0.0344\nvn 0.0646 -0.9973 0.0345\nvn 0.1373 -0.9899 -0.0352\nvn 0.1299 -0.9915 -0.0029\nvn 0.1125 -0.9936 -0.0011\nvn 0.1211 -0.9921 -0.0341\nvn 0.1200 -0.9924 0.0279\nvn 0.1030 -0.9942 0.0311\nvn 0.0957 -0.9913 0.0904\nvn 0.0773 -0.9924 0.0954\nvn 0.0908 -0.9939 0.0627\nvn 0.1091 -0.9923 0.0589\nvn 0.0613 -0.9932 0.0994\nvn 0.0760 -0.9949 0.0661\nvn 0.0389 -0.9936 0.1058\nvn 0.0535 -0.9961 0.0701\nvn 0.0631 -0.9957 0.0683\nvn 0.0489 -0.9935 0.1032\nvn 0.1563 -0.9870 -0.0371\nvn 0.1486 -0.9889 -0.0061\nvn 0.1767 -0.9834 -0.0410\nvn 0.1704 -0.9853 -0.0101\nvn 0.1620 -0.9866 0.0192\nvn 0.1401 -0.9898 0.0242\nvn 0.2242 -0.9731 -0.0532\nvn 0.2202 -0.9752 -0.0224\nvn 0.1937 -0.9809 -0.0158\nvn 0.1999 -0.9787 -0.0458\nvn 0.2144 -0.9767 0.0065\nvn 0.1873 -0.9822 0.0136\nvn 0.2025 -0.9771 0.0654\nvn 0.1711 -0.9826 0.0727\nvn 0.1791 -0.9829 0.0425\nvn 0.2089 -0.9773 0.0356\nvn 0.1425 -0.9866 0.0791\nvn 0.1532 -0.9870 0.0488\nvn 0.1293 -0.9901 0.0541\nvn 0.1179 -0.9894 0.0852\nvn 0.1403 -0.9631 0.2295\nvn 0.1462 -0.9725 0.1815\nvn 0.1888 -0.9667 0.1730\nvn 0.0981 -0.9665 0.2372\nvn 0.1089 -0.9760 0.1888\nvn 0.1200 -0.9817 0.1477\nvn 0.1540 -0.9780 0.1405\nvn 0.1919 -0.9724 0.1328\nvn 0.0294 -0.9679 0.2495\nvn 0.0479 -0.9783 0.2017\nvn 0.0760 -0.9778 0.1955\nvn 0.0613 -0.9679 0.2436\nvn 0.0650 -0.9849 0.1605\nvn 0.0908 -0.9838 0.1544\nvn 0.1045 -0.9875 0.1181\nvn 0.0814 -0.9889 0.1240\nvn 0.1318 -0.9850 0.1118\nvn 0.1971 -0.9755 0.0973\nvn 0.1621 -0.9812 0.1048\nvn 0.0024 -0.9669 0.2550\nvn 0.0236 -0.9779 0.2077\nvn -0.0205 -0.9652 0.2606\nvn 0.0039 -0.9769 0.2136\nvn 0.0253 -0.9848 0.1720\nvn 0.0436 -0.9851 0.1665\nvn -0.0535 -0.9606 0.2729\nvn -0.0242 -0.9739 0.2256\nvn -0.0125 -0.9755 0.2195\nvn -0.0388 -0.9631 0.2665\nvn 0.0003 -0.9832 0.1826\nvn 0.0112 -0.9840 0.1776\nvn 0.0312 -0.9898 0.1390\nvn 0.0218 -0.9894 0.1433\nvn 0.0448 -0.9899 0.1346\nvn 0.0611 -0.9897 0.1294\nvn 0.4637 -0.8698 -0.1685\nvn 0.5055 -0.8421 -0.1878\nvn 0.5133 -0.8463 -0.1424\nvn 0.4696 -0.8738 -0.1261\nvn 0.5488 -0.8101 -0.2064\nvn 0.5579 -0.8146 -0.1587\nvn 0.5645 -0.8176 -0.1135\nvn 0.5179 -0.8495 -0.1009\nvn 0.4736 -0.8765 -0.0869\nvn 0.6360 -0.7330 -0.2413\nvn 0.6487 -0.7374 -0.1880\nvn 0.6036 -0.7781 -0.1736\nvn 0.5924 -0.7737 -0.2246\nvn 0.6583 -0.7405 -0.1356\nvn 0.6112 -0.7815 -0.1254\nvn 0.6685 -0.7430 -0.0326\nvn 0.6204 -0.7837 -0.0312\nvn 0.6172 -0.7829 -0.0780\nvn 0.6646 -0.7424 -0.0845\nvn 0.5718 -0.8199 -0.0272\nvn 0.5687 -0.8195 -0.0706\nvn 0.4780 -0.8782 -0.0135\nvn 0.4755 -0.8783 -0.0502\nvn 0.5216 -0.8510 -0.0608\nvn 0.5234 -0.8518 -0.0218\nvn 0.6784 -0.6881 -0.2574\nvn 0.6932 -0.6922 -0.2006\nvn 0.7192 -0.6396 -0.2713\nvn 0.7355 -0.6433 -0.2124\nvn 0.7476 -0.6463 -0.1531\nvn 0.7037 -0.6955 -0.1452\nvn 0.7925 -0.5339 -0.2948\nvn 0.8119 -0.5361 -0.2310\nvn 0.7755 -0.5910 -0.2222\nvn 0.7574 -0.5879 -0.2842\nvn 0.8263 -0.5383 -0.1657\nvn 0.7885 -0.5938 -0.1602\nvn 0.8392 -0.5429 -0.0307\nvn 0.8004 -0.5986 -0.0321\nvn 0.7970 -0.5962 -0.0968\nvn 0.8354 -0.5406 -0.0994\nvn 0.7589 -0.6504 -0.0328\nvn 0.7552 -0.6487 -0.0937\nvn 0.7111 -0.6974 -0.0894\nvn 0.7146 -0.6987 -0.0333\nvn 0.7747 -0.6079 0.1739\nvn 0.8119 -0.5527 0.1880\nvn 0.7356 -0.6584 0.1592\nvn 0.7502 -0.6546 0.0937\nvn 0.7904 -0.6039 0.1033\nvn 0.8284 -0.5486 0.1132\nvn 0.6496 -0.7492 0.1291\nvn 0.6941 -0.7053 0.1446\nvn 0.6624 -0.7454 0.0746\nvn 0.7077 -0.7016 0.0838\nvn 0.7140 -0.6997 0.0246\nvn 0.6682 -0.7437 0.0201\nvn 0.7575 -0.6522 0.0294\nvn 0.8371 -0.5455 0.0399\nvn 0.7986 -0.6009 0.0347\nvn 0.6047 -0.7882 0.1147\nvn 0.5617 -0.8211 0.1016\nvn 0.5695 -0.8199 0.0589\nvn 0.6157 -0.7852 0.0656\nvn 0.4816 -0.8720 0.0877\nvn 0.5200 -0.8493 0.0914\nvn 0.4813 -0.8748 0.0558\nvn 0.5233 -0.8504 0.0542\nvn 0.5245 -0.8512 0.0174\nvn 0.4790 -0.8775 0.0216\nvn 0.5717 -0.8203 0.0155\nvn 0.6205 -0.7840 0.0171\nvn 0.1365 -0.9491 0.2840\nvn 0.1349 -0.9300 0.3419\nvn 0.0811 -0.9332 0.3500\nvn 0.0888 -0.9524 0.2915\nvn 0.1385 -0.8734 0.4670\nvn 0.1359 -0.9048 0.4035\nvn 0.0707 -0.8768 0.4755\nvn 0.0749 -0.9084 0.4114\nvn -0.0415 -0.8753 0.4818\nvn -0.0247 -0.9074 0.4195\nvn 0.0217 -0.9089 0.4165\nvn 0.0106 -0.8773 0.4797\nvn -0.0072 -0.9330 0.3598\nvn 0.0338 -0.9341 0.3554\nvn 0.0471 -0.9535 0.2977\nvn 0.0110 -0.9530 0.3028\nvn 0.1435 -0.8345 0.5320\nvn 0.1494 -0.7885 0.5966\nvn 0.0662 -0.7926 0.6061\nvn 0.0675 -0.8385 0.5407\nvn 0.1646 -0.6749 0.7194\nvn 0.1569 -0.7350 0.6597\nvn 0.0667 -0.6803 0.7299\nvn 0.0657 -0.7399 0.6696\nvn -0.0967 -0.6795 0.7273\nvn -0.0853 -0.7383 0.6691\nvn -0.0146 -0.7404 0.6720\nvn -0.0206 -0.6817 0.7314\nvn -0.0719 -0.7907 0.6080\nvn -0.0077 -0.7932 0.6089\nvn 0.0010 -0.8387 0.5446\nvn -0.0574 -0.8366 0.5448\nvn -0.3250 -0.6464 0.6903\nvn -0.2940 -0.7073 0.6428\nvn -0.2495 -0.7179 0.6499\nvn -0.2755 -0.6589 0.7000\nvn -0.2613 -0.7619 0.5927\nvn -0.2212 -0.7721 0.5958\nvn -0.1774 -0.7798 0.6003\nvn -0.2010 -0.7269 0.6566\nvn -0.2224 -0.6679 0.7103\nvn -0.1909 -0.8532 0.4855\nvn -0.1604 -0.8607 0.4832\nvn -0.1915 -0.8195 0.5402\nvn -0.2263 -0.8111 0.5394\nvn -0.1262 -0.8667 0.4826\nvn -0.1523 -0.8268 0.5415\nvn -0.1080 -0.8323 0.5437\nvn -0.0868 -0.8718 0.4821\nvn -0.1282 -0.7863 0.6044\nvn -0.1636 -0.6751 0.7194\nvn -0.1467 -0.7334 0.6638\nvn -0.1546 -0.8892 0.4306\nvn -0.1294 -0.8950 0.4268\nvn -0.1197 -0.9185 0.3768\nvn -0.0981 -0.9234 0.3712\nvn -0.0727 -0.9273 0.3671\nvn -0.0994 -0.9003 0.4238\nvn -0.0681 -0.9457 0.3178\nvn -0.0852 -0.9423 0.3239\nvn -0.0461 -0.9489 0.3123\nvn -0.0200 -0.9513 0.3076\nvn -0.0424 -0.9307 0.3632\nvn -0.0648 -0.9043 0.4219\nvn 0.2316 -0.9589 0.1638\nvn 0.2310 -0.9650 0.1239\nvn 0.2670 -0.9569 0.1146\nvn 0.2710 -0.9503 0.1533\nvn 0.2357 -0.9701 0.0574\nvn 0.2323 -0.9686 0.0890\nvn 0.2671 -0.9625 0.0484\nvn 0.2663 -0.9606 0.0800\nvn 0.3302 -0.9435 0.0284\nvn 0.3321 -0.9414 0.0599\nvn 0.2989 -0.9517 0.0703\nvn 0.2986 -0.9536 0.0388\nvn 0.3369 -0.9369 0.0936\nvn 0.3019 -0.9476 0.1042\nvn 0.3085 -0.9405 0.1423\nvn 0.3456 -0.9293 0.1299\nvn 0.2391 -0.9706 0.0274\nvn 0.2435 -0.9699 -0.0015\nvn 0.2718 -0.9623 -0.0110\nvn 0.2695 -0.9628 0.0186\nvn 0.2505 -0.9661 -0.0619\nvn 0.2469 -0.9685 -0.0313\nvn 0.2761 -0.9583 -0.0732\nvn 0.2747 -0.9607 -0.0409\nvn 0.3301 -0.9386 -0.0998\nvn 0.3311 -0.9414 -0.0648\nvn 0.3021 -0.9518 -0.0525\nvn 0.3030 -0.9491 -0.0854\nvn 0.3306 -0.9432 -0.0330\nvn 0.3011 -0.9534 -0.0212\nvn 0.2993 -0.9541 0.0086\nvn 0.3301 -0.9439 -0.0021\nvn 0.4297 -0.8963 -0.1094\nvn 0.4248 -0.8929 -0.1496\nvn 0.4321 -0.8989 -0.0727\nvn 0.3954 -0.9166 -0.0588\nvn 0.3938 -0.9144 -0.0936\nvn 0.3903 -0.9112 -0.1318\nvn 0.4356 -0.9001 -0.0039\nvn 0.4340 -0.9001 -0.0380\nvn 0.3981 -0.9173 0.0068\nvn 0.3962 -0.9178 -0.0258\nvn 0.3620 -0.9321 -0.0138\nvn 0.3629 -0.9316 0.0176\nvn 0.3619 -0.9311 -0.0453\nvn 0.3592 -0.9261 -0.1149\nvn 0.3612 -0.9292 -0.0789\nvn 0.4389 -0.8980 0.0297\nvn 0.4420 -0.8949 0.0617\nvn 0.4065 -0.9108 0.0717\nvn 0.4009 -0.9153 0.0390\nvn 0.4499 -0.8881 0.0943\nvn 0.4153 -0.9036 0.1048\nvn 0.3817 -0.9168 0.1177\nvn 0.3715 -0.9248 0.0823\nvn 0.3660 -0.9293 0.0495\nvn 0.7383 0.0000 -0.6745\nvn 0.7552 0.0000 -0.6555\nvn 0.7517 -0.0884 -0.6535\nvn 0.7350 -0.0905 -0.6720\nvn 0.7756 0.0000 -0.6312\nvn 0.7725 -0.0864 -0.6291\nvn 0.7634 -0.1669 -0.6240\nvn 0.7427 -0.1706 -0.6475\nvn 0.7255 -0.1744 -0.6657\nvn 0.8267 0.0000 -0.5626\nvn 0.8237 -0.0825 -0.5610\nvn 0.7965 -0.0843 -0.5988\nvn 0.7999 0.0000 -0.6002\nvn 0.8149 -0.1602 -0.5571\nvn 0.7878 -0.1634 -0.5939\nvn 0.7845 -0.3007 -0.5423\nvn 0.7574 -0.3049 -0.5774\nvn 0.7743 -0.2369 -0.5868\nvn 0.8016 -0.2330 -0.5506\nvn 0.7330 -0.3097 -0.6057\nvn 0.7500 -0.2413 -0.6158\nvn 0.6943 -0.3210 -0.6442\nvn 0.7117 -0.2513 -0.6560\nvn 0.7290 -0.2461 -0.6388\nvn 0.7119 -0.3151 -0.6276\nvn 0.8560 0.0000 -0.5169\nvn 0.8528 -0.0808 -0.5160\nvn 0.8860 0.0000 -0.4637\nvn 0.8831 -0.0794 -0.4625\nvn 0.8744 -0.1550 -0.4598\nvn 0.8443 -0.1574 -0.5123\nvn 0.9430 0.0000 -0.3327\nvn 0.9401 -0.0773 -0.3319\nvn 0.9126 -0.0782 -0.4013\nvn 0.9158 0.0001 -0.4017\nvn 0.9316 -0.1517 -0.3304\nvn 0.9042 -0.1531 -0.3988\nvn 0.9003 -0.2912 -0.3235\nvn 0.8731 -0.2925 -0.3900\nvn 0.8907 -0.2245 -0.3952\nvn 0.9182 -0.2231 -0.3275\nvn 0.8437 -0.2945 -0.4488\nvn 0.8611 -0.2267 -0.4550\nvn 0.8309 -0.2295 -0.5069\nvn 0.8137 -0.2973 -0.4995\nvn 0.7688 -0.5318 -0.3551\nvn 0.7994 -0.4765 -0.3659\nvn 0.8244 -0.4774 -0.3042\nvn 0.7431 -0.5303 -0.4081\nvn 0.7722 -0.4761 -0.4208\nvn 0.7989 -0.4189 -0.4316\nvn 0.8271 -0.4182 -0.3755\nvn 0.8531 -0.4183 -0.3118\nvn 0.6910 -0.5290 -0.4927\nvn 0.7172 -0.4775 -0.5075\nvn 0.7445 -0.4764 -0.4678\nvn 0.7167 -0.5292 -0.4542\nvn 0.7419 -0.4226 -0.5205\nvn 0.7700 -0.4204 -0.4800\nvn 0.7932 -0.3608 -0.4905\nvn 0.7644 -0.3639 -0.5322\nvn 0.8228 -0.3585 -0.4410\nvn 0.8785 -0.3562 -0.3184\nvn 0.8518 -0.3570 -0.3834\nvn 0.6665 -0.5296 -0.5247\nvn 0.6918 -0.4796 -0.5398\nvn 0.6442 -0.5316 -0.5499\nvn 0.6685 -0.4827 -0.5658\nvn 0.6917 -0.4299 -0.5803\nvn 0.7155 -0.4258 -0.5539\nvn 0.6301 -0.4929 -0.6001\nvn 0.6479 -0.4872 -0.5856\nvn 0.6241 -0.5349 -0.5696\nvn 0.6528 -0.4412 -0.6157\nvn 0.6707 -0.4350 -0.6008\nvn 0.6922 -0.3779 -0.6149\nvn 0.6744 -0.3841 -0.6305\nvn 0.7133 -0.3724 -0.5937\nvn 0.7376 -0.3677 -0.5664\nvn -0.0991 -0.9384 0.3310\nvn -0.0639 -0.9579 0.2797\nvn -0.1361 -0.9135 0.3834\nvn -0.1480 -0.9080 0.3920\nvn -0.1079 -0.9345 0.3392\nvn -0.0720 -0.9552 0.2870\nvn -0.2155 -0.8451 0.4892\nvn -0.1758 -0.8823 0.4366\nvn -0.2331 -0.8362 0.4965\nvn -0.1895 -0.8755 0.4446\nvn -0.2330 -0.8211 0.5210\nvn -0.1891 -0.8630 0.4686\nvn -0.1952 -0.8686 0.4554\nvn -0.2397 -0.8280 0.5069\nvn -0.1473 -0.8984 0.4138\nvn -0.1519 -0.9028 0.4022\nvn -0.0736 -0.9503 0.3025\nvn -0.0750 -0.9526 0.2948\nvn -0.1120 -0.9306 0.3484\nvn -0.1083 -0.9273 0.3584\nvn -0.2560 -0.8009 0.5414\nvn -0.2949 -0.7508 0.5910\nvn -0.3191 -0.7383 0.5942\nvn -0.2762 -0.7907 0.5464\nvn -0.3675 -0.6326 0.6817\nvn -0.3327 -0.6939 0.6386\nvn -0.3984 -0.6171 0.6786\nvn -0.3598 -0.6807 0.6381\nvn -0.4065 -0.5932 0.6949\nvn -0.3658 -0.6581 0.6581\nvn -0.3727 -0.6677 0.6445\nvn -0.4131 -0.6036 0.6819\nvn -0.3223 -0.7182 0.6167\nvn -0.3296 -0.7272 0.6021\nvn -0.2850 -0.7806 0.5562\nvn -0.2779 -0.7727 0.5707\nvn -0.1521 -0.6610 0.7348\nvn -0.1730 -0.5980 0.7826\nvn -0.1325 -0.7167 0.6846\nvn -0.2295 -0.7140 0.6615\nvn -0.2641 -0.6542 0.7087\nvn -0.2961 -0.5917 0.7498\nvn -0.0928 -0.8160 0.5706\nvn -0.1116 -0.7702 0.6280\nvn -0.1623 -0.8157 0.5552\nvn -0.1963 -0.7670 0.6109\nvn -0.2497 -0.7682 0.5895\nvn -0.2088 -0.8166 0.5381\nvn -0.2918 -0.7132 0.6374\nvn -0.3715 -0.5885 0.7181\nvn -0.3320 -0.6535 0.6802\nvn -0.0739 -0.8579 0.5084\nvn -0.0574 -0.8926 0.4471\nvn -0.1011 -0.8935 0.4376\nvn -0.1311 -0.8572 0.4980\nvn -0.0287 -0.9465 0.3215\nvn -0.0419 -0.9227 0.3833\nvn -0.0507 -0.9473 0.3164\nvn -0.0745 -0.9230 0.3776\nvn -0.0964 -0.9248 0.3681\nvn -0.0655 -0.9484 0.3103\nvn -0.1310 -0.8949 0.4265\nvn -0.1685 -0.8592 0.4830\nvn 0.2072 -0.8894 -0.4074\nvn 0.2265 -0.8743 -0.4293\nvn 0.1883 -0.9031 -0.3858\nvn 0.1632 -0.9095 -0.3822\nvn 0.1799 -0.8969 -0.4039\nvn 0.1984 -0.8828 -0.4258\nvn 0.1548 -0.9265 -0.3431\nvn 0.1712 -0.9154 -0.3643\nvn 0.1327 -0.9310 -0.3400\nvn 0.1470 -0.9210 -0.3609\nvn 0.0868 -0.9386 -0.3339\nvn 0.0969 -0.9301 -0.3542\nvn 0.1225 -0.9258 -0.3575\nvn 0.1095 -0.9352 -0.3367\nvn 0.1087 -0.9205 -0.3754\nvn 0.1360 -0.9155 -0.3786\nvn 0.1345 -0.8978 -0.4193\nvn 0.1670 -0.8909 -0.4224\nvn 0.1514 -0.9038 -0.4003\nvn 0.1207 -0.9099 -0.3969\nvn 0.1404 -0.9362 -0.3221\nvn 0.1270 -0.9450 -0.3015\nvn 0.1079 -0.9480 -0.2993\nvn 0.1192 -0.9401 -0.3194\nvn 0.1066 -0.9593 -0.2613\nvn 0.1161 -0.9526 -0.2813\nvn 0.0898 -0.9613 -0.2605\nvn 0.0977 -0.9551 -0.2796\nvn 0.0570 -0.9643 -0.2586\nvn 0.0623 -0.9590 -0.2764\nvn 0.0800 -0.9572 -0.2780\nvn 0.0729 -0.9630 -0.2595\nvn 0.0694 -0.9530 -0.2950\nvn 0.0882 -0.9508 -0.2970\nvn 0.0985 -0.9434 -0.3167\nvn 0.0772 -0.9463 -0.3140\nvn 0.0144 -0.9617 -0.2738\nvn 0.0130 -0.9663 -0.2571\nvn 0.0160 -0.9565 -0.2912\nvn 0.0330 -0.9558 -0.2921\nvn 0.0295 -0.9612 -0.2743\nvn 0.0269 -0.9659 -0.2574\nvn 0.0202 -0.9443 -0.3284\nvn 0.0180 -0.9507 -0.3096\nvn 0.0417 -0.9432 -0.3297\nvn 0.0369 -0.9499 -0.3104\nvn 0.0570 -0.9484 -0.3121\nvn 0.0637 -0.9414 -0.3313\nvn 0.0507 -0.9547 -0.2932\nvn 0.0414 -0.9653 -0.2579\nvn 0.0457 -0.9603 -0.2753\nvn 0.0229 -0.9370 -0.3485\nvn 0.0256 -0.9291 -0.3690\nvn 0.0527 -0.9273 -0.3705\nvn 0.0468 -0.9358 -0.3495\nvn 0.0319 -0.9101 -0.4131\nvn 0.0287 -0.9200 -0.3909\nvn 0.0658 -0.9076 -0.4147\nvn 0.0588 -0.9181 -0.3919\nvn 0.0901 -0.9146 -0.3943\nvn 0.1000 -0.9037 -0.4164\nvn 0.0803 -0.9246 -0.3724\nvn 0.0719 -0.9334 -0.3517\nvn 0.0636 -0.9980 -0.0027\nvn 0.0700 -0.9968 -0.0397\nvn 0.0558 -0.9979 0.0340\nvn 0.0469 -0.9984 0.0324\nvn 0.0542 -0.9985 -0.0050\nvn 0.0592 -0.9973 -0.0428\nvn 0.0316 -0.9937 0.1080\nvn 0.0450 -0.9965 0.0704\nvn 0.0243 -0.9937 0.1090\nvn 0.0376 -0.9968 0.0703\nvn 0.0130 -0.9939 0.1097\nvn 0.0237 -0.9974 0.0682\nvn 0.0301 -0.9971 0.0694\nvn 0.0186 -0.9938 0.1097\nvn 0.0306 -0.9991 0.0282\nvn 0.0389 -0.9988 0.0305\nvn 0.0389 -0.9980 -0.0494\nvn 0.0491 -0.9977 -0.0462\nvn 0.0447 -0.9990 -0.0079\nvn 0.0358 -0.9993 -0.0109\nvn 0.0139 -0.9891 0.1465\nvn -0.0071 -0.9822 0.1876\nvn -0.0138 -0.9813 0.1919\nvn 0.0079 -0.9887 0.1494\nvn -0.0335 -0.9723 0.2315\nvn -0.0397 -0.9706 0.2376\nvn -0.0435 -0.9675 0.2492\nvn -0.0438 -0.9689 0.2434\nvn -0.0200 -0.9797 0.1995\nvn -0.0176 -0.9804 0.1960\nvn 0.0024 -0.9885 0.1515\nvn -0.0008 -0.9882 0.1534\nvn -0.0177 -0.9651 0.2613\nvn -0.0090 -0.9783 0.2069\nvn -0.0156 -0.9786 0.2051\nvn -0.0309 -0.9654 0.2589\nvn 0.0022 -0.9941 0.1088\nvn -0.0026 -0.9878 0.1560\nvn 0.0049 -0.9940 0.1092\nvn -0.0035 -0.9878 0.1556\nvn -0.0033 -0.9880 0.1546\nvn 0.0089 -0.9939 0.1096\nvn -0.0189 -0.9790 0.2028\nvn -0.0398 -0.9663 0.2542\nvn 0.0053 -0.9979 0.0645\nvn 0.0076 -0.9997 0.0223\nvn 0.0151 -0.9996 0.0239\nvn 0.0113 -0.9978 0.0654\nvn 0.0095 -0.9983 -0.0569\nvn 0.0087 -0.9998 -0.0177\nvn 0.0191 -0.9983 -0.0549\nvn 0.0178 -0.9997 -0.0163\nvn 0.0265 -0.9996 -0.0137\nvn 0.0291 -0.9982 -0.0526\nvn 0.0231 -0.9994 0.0258\nvn 0.0170 -0.9976 0.0668\nvn 0.6299 0.0000 -0.7767\nvn 0.6257 -0.1104 -0.7722\nvn 0.6011 -0.1147 -0.7909\nvn 0.6060 0.0000 -0.7954\nvn 0.6130 -0.2142 -0.7605\nvn 0.5883 -0.2224 -0.7774\nvn 0.5528 -0.2325 -0.8002\nvn 0.5668 -0.1197 -0.8151\nvn 0.5713 0.0000 -0.8207\nvn 0.5707 -0.3935 -0.7208\nvn 0.5439 -0.4078 -0.7334\nvn 0.5682 -0.3208 -0.7578\nvn 0.5945 -0.3087 -0.7425\nvn 0.5068 -0.4250 -0.7500\nvn 0.5326 -0.3345 -0.7775\nvn 0.3936 -0.4637 -0.7938\nvn 0.4185 -0.3674 -0.8306\nvn 0.4834 -0.3505 -0.8022\nvn 0.4580 -0.4436 -0.7704\nvn 0.4384 -0.2564 -0.8614\nvn 0.5046 -0.2437 -0.8282\nvn 0.4568 0.0000 -0.8896\nvn 0.5235 0.0000 -0.8520\nvn 0.5181 -0.1257 -0.8460\nvn 0.4524 -0.1323 -0.8819\nvn 0.5445 -0.4674 -0.6965\nvn 0.5159 -0.4843 -0.7066\nvn 0.5160 -0.5322 -0.6712\nvn 0.4870 -0.5496 -0.6788\nvn 0.4487 -0.5696 -0.6886\nvn 0.4787 -0.5027 -0.7198\nvn 0.4278 -0.6539 -0.6240\nvn 0.4570 -0.6062 -0.6509\nvn 0.4873 -0.5877 -0.6458\nvn 0.3896 -0.6735 -0.6281\nvn 0.4189 -0.6257 -0.6580\nvn 0.2865 -0.7129 -0.6401\nvn 0.3119 -0.6675 -0.6761\nvn 0.3709 -0.6468 -0.6664\nvn 0.3425 -0.6934 -0.6339\nvn 0.3392 -0.6121 -0.7144\nvn 0.4001 -0.5905 -0.7009\nvn 0.4294 -0.5235 -0.7359\nvn 0.3667 -0.5447 -0.7542\nvn 0.0811 -0.7112 -0.6982\nvn 0.0729 -0.7530 -0.6539\nvn 0.0896 -0.6596 -0.7463\nvn 0.1808 -0.6485 -0.7394\nvn 0.1637 -0.7020 -0.6931\nvn 0.1487 -0.7440 -0.6514\nvn 0.1084 -0.5116 -0.8524\nvn 0.0991 -0.5934 -0.7988\nvn 0.2158 -0.4999 -0.8388\nvn 0.1980 -0.5825 -0.7883\nvn 0.2891 -0.5651 -0.7727\nvn 0.3126 -0.4833 -0.8178\nvn 0.2652 -0.6323 -0.7280\nvn 0.2206 -0.7306 -0.6462\nvn 0.2426 -0.6864 -0.6856\nvn 0.1174 -0.4097 -0.9046\nvn 0.1251 -0.2887 -0.9492\nvn 0.2462 -0.2805 -0.9277\nvn 0.2324 -0.3997 -0.8867\nvn 0.1322 0.0000 -0.9912\nvn 0.1301 -0.1497 -0.9801\nvn 0.2590 0.0000 -0.9659\nvn 0.2560 -0.1454 -0.9557\nvn 0.3647 -0.1392 -0.9207\nvn 0.3695 0.0000 -0.9292\nvn 0.3528 -0.2691 -0.8962\nvn 0.3344 -0.3846 -0.8604\nvn 0.0119 -0.9707 -0.2400\nvn 0.0247 -0.9704 -0.2400\nvn 0.0231 -0.9750 -0.2211\nvn 0.0111 -0.9751 -0.2214\nvn 0.0525 -0.9693 -0.2403\nvn 0.0383 -0.9700 -0.2401\nvn 0.0492 -0.9742 -0.2203\nvn 0.0357 -0.9747 -0.2208\nvn 0.0447 -0.9837 -0.1744\nvn 0.0326 -0.9838 -0.1761\nvn 0.0339 -0.9793 -0.1994\nvn 0.0465 -0.9790 -0.1985\nvn 0.0211 -0.9839 -0.1772\nvn 0.0218 -0.9795 -0.2004\nvn 0.0105 -0.9796 -0.2008\nvn 0.0102 -0.9839 -0.1783\nvn 0.0677 -0.9683 -0.2405\nvn 0.0830 -0.9670 -0.2407\nvn 0.0779 -0.9726 -0.2192\nvn 0.0631 -0.9735 -0.2198\nvn 0.1155 -0.9637 -0.2408\nvn 0.0993 -0.9655 -0.2409\nvn 0.1086 -0.9700 -0.2177\nvn 0.0929 -0.9714 -0.2185\nvn 0.0983 -0.9812 -0.1660\nvn 0.0841 -0.9822 -0.1682\nvn 0.0881 -0.9770 -0.1944\nvn 0.1028 -0.9758 -0.1928\nvn 0.0705 -0.9828 -0.1704\nvn 0.0736 -0.9779 -0.1959\nvn 0.0599 -0.9785 -0.1972\nvn 0.0573 -0.9833 -0.1726\nvn 0.0745 -0.9943 -0.0759\nvn 0.0865 -0.9936 -0.0728\nvn 0.0631 -0.9949 -0.0792\nvn 0.0657 -0.9915 -0.1123\nvn 0.0780 -0.9910 -0.1092\nvn 0.0907 -0.9902 -0.1062\nvn 0.0411 -0.9955 -0.0859\nvn 0.0519 -0.9952 -0.0825\nvn 0.0423 -0.9921 -0.1184\nvn 0.0538 -0.9918 -0.1156\nvn 0.0555 -0.9878 -0.1454\nvn 0.0434 -0.9880 -0.1479\nvn 0.0679 -0.9874 -0.1427\nvn 0.0944 -0.9860 -0.1371\nvn 0.0810 -0.9869 -0.1399\nvn 0.0304 -0.9956 -0.0887\nvn 0.0200 -0.9956 -0.0913\nvn 0.0203 -0.9922 -0.1231\nvn 0.0312 -0.9921 -0.1212\nvn 0.0098 -0.9957 -0.0926\nvn 0.0099 -0.9921 -0.1248\nvn 0.0100 -0.9882 -0.1528\nvn 0.0206 -0.9882 -0.1519\nvn 0.0318 -0.9882 -0.1500\nvn 0.1315 -0.9617 -0.2404\nvn 0.1463 -0.9598 -0.2396\nvn 0.1385 -0.9667 -0.2152\nvn 0.1237 -0.9684 -0.2165\nvn 0.1770 -0.9550 -0.2378\nvn 0.1615 -0.9575 -0.2388\nvn 0.1687 -0.9624 -0.2130\nvn 0.1529 -0.9649 -0.2138\nvn 0.1566 -0.9749 -0.1582\nvn 0.1410 -0.9771 -0.1593\nvn 0.1464 -0.9713 -0.1874\nvn 0.1616 -0.9692 -0.1860\nvn 0.1266 -0.9787 -0.1613\nvn 0.1317 -0.9731 -0.1890\nvn 0.1176 -0.9745 -0.1910\nvn 0.1124 -0.9801 -0.1636\nvn 0.1930 -0.9520 -0.2375\nvn 0.2080 -0.9489 -0.2371\nvn 0.2015 -0.9559 -0.2135\nvn 0.1846 -0.9596 -0.2124\nvn 0.2392 -0.9403 -0.2419\nvn 0.2238 -0.9450 -0.2385\nvn 0.2379 -0.9455 -0.2223\nvn 0.2194 -0.9515 -0.2157\nvn 0.2353 -0.9566 -0.1718\nvn 0.2134 -0.9631 -0.1637\nvn 0.2164 -0.9573 -0.1915\nvn 0.2373 -0.9511 -0.1980\nvn 0.1927 -0.9681 -0.1600\nvn 0.1965 -0.9625 -0.1872\nvn 0.1785 -0.9662 -0.1861\nvn 0.1735 -0.9721 -0.1578\nvn 0.2041 -0.9759 -0.0769\nvn 0.2283 -0.9700 -0.0836\nvn 0.1822 -0.9806 -0.0716\nvn 0.1860 -0.9772 -0.1020\nvn 0.2079 -0.9724 -0.1062\nvn 0.2309 -0.9663 -0.1141\nvn 0.1438 -0.9873 -0.0674\nvn 0.1617 -0.9844 -0.0689\nvn 0.1483 -0.9840 -0.0988\nvn 0.1663 -0.9811 -0.0993\nvn 0.1699 -0.9770 -0.1292\nvn 0.1524 -0.9799 -0.1288\nvn 0.1893 -0.9732 -0.1308\nvn 0.2338 -0.9618 -0.1425\nvn 0.2107 -0.9681 -0.1357\nvn 0.1272 -0.9896 -0.0675\nvn 0.1126 -0.9913 -0.0685\nvn 0.1175 -0.9879 -0.1011\nvn 0.1323 -0.9862 -0.0994\nvn 0.0989 -0.9926 -0.0704\nvn 0.1039 -0.9892 -0.1034\nvn 0.1081 -0.9850 -0.1345\nvn 0.1220 -0.9837 -0.1320\nvn 0.1366 -0.9820 -0.1301\nvn 0.2541 -0.9337 -0.2524\nvn 0.2718 -0.9246 -0.2668\nvn 0.2756 -0.9289 -0.2473\nvn 0.2577 -0.9378 -0.2326\nvn 0.3077 -0.9021 -0.3025\nvn 0.2883 -0.9146 -0.2837\nvn 0.3141 -0.9064 -0.2826\nvn 0.2953 -0.9182 -0.2639\nvn 0.3234 -0.9176 -0.2314\nvn 0.3024 -0.9291 -0.2130\nvn 0.2988 -0.9236 -0.2402\nvn 0.3202 -0.9114 -0.2586\nvn 0.2798 -0.9397 -0.1969\nvn 0.2793 -0.9338 -0.2234\nvn 0.2576 -0.9433 -0.2096\nvn 0.2584 -0.9487 -0.1823\nvn 0.3271 -0.8881 -0.3229\nvn 0.3480 -0.8721 -0.3441\nvn 0.3560 -0.8766 -0.3238\nvn 0.3351 -0.8922 -0.3027\nvn 0.3966 -0.8306 -0.3909\nvn 0.3704 -0.8536 -0.3663\nvn 0.4073 -0.8346 -0.3709\nvn 0.3799 -0.8577 -0.3465\nvn 0.4277 -0.8458 -0.3189\nvn 0.3968 -0.8693 -0.2947\nvn 0.3885 -0.8632 -0.3224\nvn 0.4176 -0.8397 -0.3471\nvn 0.3698 -0.8884 -0.2720\nvn 0.3637 -0.8820 -0.2998\nvn 0.3408 -0.8979 -0.2786\nvn 0.3463 -0.9039 -0.2510\nvn 0.4183 -0.8881 -0.1905\nvn 0.4552 -0.8649 -0.2116\nvn 0.3856 -0.9067 -0.1707\nvn 0.3806 -0.9012 -0.2073\nvn 0.4115 -0.8823 -0.2284\nvn 0.4465 -0.8588 -0.2510\nvn 0.3290 -0.9346 -0.1350\nvn 0.3559 -0.9220 -0.1524\nvn 0.3273 -0.9296 -0.1692\nvn 0.3533 -0.9166 -0.1874\nvn 0.3497 -0.9105 -0.2205\nvn 0.3264 -0.9236 -0.2011\nvn 0.3757 -0.8948 -0.2411\nvn 0.4372 -0.8523 -0.2870\nvn 0.4043 -0.8759 -0.2632\nvn 0.3027 -0.9455 -0.1198\nvn 0.2780 -0.9548 -0.1054\nvn 0.2788 -0.9505 -0.1374\nvn 0.3034 -0.9406 -0.1520\nvn 0.2525 -0.9630 -0.0939\nvn 0.2554 -0.9589 -0.1239\nvn 0.2567 -0.9541 -0.1541\nvn 0.2806 -0.9451 -0.1673\nvn 0.3028 -0.9352 -0.1836\nvn 0.6140 -0.5002 -0.6106\nvn 0.5985 -0.5087 -0.6189\nvn 0.6218 -0.4570 -0.6359\nvn 0.6370 -0.4485 -0.6269\nvn 0.5670 -0.5300 -0.6306\nvn 0.5828 -0.5188 -0.6254\nvn 0.5917 -0.4773 -0.6497\nvn 0.6070 -0.4665 -0.6434\nvn 0.6378 -0.3505 -0.6859\nvn 0.6515 -0.3421 -0.6771\nvn 0.6300 -0.4080 -0.6608\nvn 0.6157 -0.4176 -0.6682\nvn 0.6650 -0.3345 -0.6677\nvn 0.6443 -0.3991 -0.6523\nvn 0.6589 -0.3913 -0.6425\nvn 0.6792 -0.3275 -0.6568\nvn 0.5500 -0.5427 -0.6348\nvn 0.5320 -0.5562 -0.6385\nvn 0.5585 -0.5021 -0.6603\nvn 0.5760 -0.4889 -0.6551\nvn 0.5112 -0.5716 -0.6419\nvn 0.5393 -0.5161 -0.6654\nvn 0.5916 -0.3806 -0.7107\nvn 0.5661 -0.4531 -0.6887\nvn 0.6086 -0.3696 -0.7022\nvn 0.5846 -0.4399 -0.6817\nvn 0.6006 -0.4283 -0.6751\nvn 0.6239 -0.3594 -0.6939\nvn 0.6479 0.0000 -0.7617\nvn 0.6434 -0.1070 -0.7580\nvn 0.6623 0.0000 -0.7492\nvn 0.6584 -0.1040 -0.7454\nvn 0.6469 -0.2013 -0.7355\nvn 0.6319 -0.2071 -0.7469\nvn 0.6873 0.0000 -0.7263\nvn 0.6837 -0.0991 -0.7230\nvn 0.6713 -0.1015 -0.7342\nvn 0.6754 0.0000 -0.7375\nvn 0.6731 -0.1911 -0.7145\nvn 0.6606 -0.1959 -0.7247\nvn 0.6441 -0.2822 -0.7110\nvn 0.6575 -0.2750 -0.7015\nvn 0.6301 -0.2899 -0.7204\nvn 0.6137 -0.2988 -0.7308\nvn 0.6993 0.0000 -0.7148\nvn 0.6955 -0.0969 -0.7120\nvn 0.7113 0.0000 -0.7029\nvn 0.7079 -0.0947 -0.7000\nvn 0.6979 -0.1824 -0.6926\nvn 0.6855 -0.1867 -0.7037\nvn 0.7207 -0.0926 -0.6870\nvn 0.7243 0.0000 -0.6894\nvn 0.7113 -0.1784 -0.6799\nvn 0.6969 -0.2567 -0.6697\nvn 0.6834 -0.2624 -0.6813\nvn 0.6702 -0.2685 -0.6919\nvn 0.3956 -0.5813 0.7110\nvn 0.2866 -0.5969 0.7494\nvn 0.4887 -0.5644 0.6653\nvn 0.5092 -0.4935 0.7051\nvn 0.4134 -0.5090 0.7550\nvn 0.2999 -0.5244 0.7969\nvn 0.6354 -0.5340 0.5577\nvn 0.5676 -0.5486 0.6139\nvn 0.6594 -0.4663 0.5897\nvn 0.5906 -0.4787 0.6497\nvn 0.6968 -0.3210 0.6414\nvn 0.6256 -0.3292 0.7073\nvn 0.6097 -0.4057 0.6809\nvn 0.6801 -0.3950 0.6176\nvn 0.5414 -0.3398 0.7690\nvn 0.5270 -0.4182 0.7399\nvn 0.3222 -0.3643 0.8738\nvn 0.3119 -0.4465 0.8387\nvn 0.4286 -0.4325 0.7932\nvn 0.4415 -0.3515 0.8255\nvn 0.6930 -0.5221 0.4971\nvn 0.7427 -0.5122 0.4313\nvn 0.7690 -0.4479 0.4561\nvn 0.7186 -0.4558 0.5252\nvn 0.8195 -0.4987 0.2824\nvn 0.7845 -0.5048 0.3603\nvn 0.8485 -0.4363 0.2996\nvn 0.8123 -0.4415 0.3810\nvn 0.8948 -0.3028 0.3281\nvn 0.8562 -0.3063 0.4161\nvn 0.8362 -0.3754 0.3999\nvn 0.8736 -0.3711 0.3147\nvn 0.8107 -0.3099 0.4968\nvn 0.7919 -0.3803 0.4778\nvn 0.7401 -0.3868 0.5502\nvn 0.7579 -0.3146 0.5715\nvn 0.9350 0.0000 0.3545\nvn 0.8937 0.0000 0.4487\nvn 0.8914 -0.0806 0.4461\nvn 0.9322 -0.0799 0.3530\nvn 0.8457 0.0000 0.5337\nvn 0.8432 -0.0812 0.5315\nvn 0.8366 -0.1602 0.5238\nvn 0.8839 -0.1588 0.4399\nvn 0.9245 -0.1571 0.3474\nvn 0.7270 0.0000 0.6866\nvn 0.7249 -0.0832 0.6838\nvn 0.7883 -0.0820 0.6098\nvn 0.7901 0.0000 0.6129\nvn 0.7194 -0.1648 0.6748\nvn 0.7820 -0.1620 0.6019\nvn 0.7719 -0.2397 0.5888\nvn 0.7099 -0.2441 0.6606\nvn 0.8256 -0.2365 0.5123\nvn 0.9118 -0.2316 0.3392\nvn 0.8722 -0.2340 0.4295\nvn 0.6535 0.0000 0.7569\nvn 0.6519 -0.0851 0.7535\nvn 0.5676 0.0000 0.8233\nvn 0.5659 -0.0876 0.8198\nvn 0.5610 -0.1740 0.8093\nvn 0.6466 -0.1686 0.7440\nvn 0.3421 -0.0000 0.9397\nvn 0.3409 -0.0947 0.9353\nvn 0.4636 -0.0910 0.8814\nvn 0.4651 -0.0000 0.8853\nvn 0.3369 -0.1877 0.9227\nvn 0.4591 -0.1803 0.8699\nvn 0.4516 -0.2676 0.8511\nvn 0.3307 -0.2775 0.9020\nvn 0.5529 -0.2580 0.7923\nvn 0.6378 -0.2503 0.7284\nvn 0.8459 -0.4936 0.2020\nvn 0.8632 -0.4897 0.1224\nvn 0.8942 -0.4280 0.1315\nvn 0.8761 -0.4318 0.2146\nvn 0.8744 -0.4842 -0.0292\nvn 0.8724 -0.4866 0.0455\nvn 0.9058 -0.4229 -0.0271\nvn 0.9037 -0.4252 0.0507\nvn 0.9560 -0.2923 -0.0229\nvn 0.9539 -0.2941 0.0603\nvn 0.9309 -0.3610 0.0557\nvn 0.9330 -0.3590 -0.0250\nvn 0.9437 -0.2964 0.1469\nvn 0.9210 -0.3637 0.1396\nvn 0.9023 -0.3670 0.2263\nvn 0.9243 -0.2995 0.2365\nvn 0.8703 -0.4822 -0.1009\nvn 0.8603 -0.4804 -0.1706\nvn 0.8908 -0.4198 -0.1741\nvn 0.9012 -0.4212 -0.1020\nvn 0.8451 -0.4788 -0.2380\nvn 0.8747 -0.4189 -0.2440\nvn 0.9230 -0.2907 -0.2523\nvn 0.9007 -0.3562 -0.2486\nvn 0.9400 -0.2906 -0.1789\nvn 0.9174 -0.3566 -0.1769\nvn 0.9283 -0.3575 -0.1024\nvn 0.9512 -0.2912 -0.1024\nvn 0.9661 0.0000 -0.2583\nvn 0.9630 -0.0767 -0.2582\nvn 0.9833 0.0000 -0.1818\nvn 0.9804 -0.0764 -0.1814\nvn 0.9719 -0.1505 -0.1812\nvn 0.9546 -0.1509 -0.2569\nvn 0.9998 0.0000 -0.0180\nvn 0.9969 -0.0767 -0.0181\nvn 0.9919 -0.0764 -0.1019\nvn 0.9948 0.0000 -0.1015\nvn 0.9883 -0.1511 -0.0194\nvn 0.9833 -0.1506 -0.1019\nvn 0.9696 -0.2222 -0.1023\nvn 0.9746 -0.2231 -0.0208\nvn 0.9583 -0.2220 -0.1802\nvn 0.9410 -0.2222 -0.2552\nvn 0.9975 0.0000 0.0700\nvn 0.9946 -0.0772 0.0691\nvn 0.9869 0.0000 0.1615\nvn 0.9839 -0.0780 0.1608\nvn 0.9755 -0.1535 0.1575\nvn 0.9861 -0.1522 0.0673\nvn 0.9636 -0.0789 0.2554\nvn 0.9664 0.0000 0.2571\nvn 0.9553 -0.1553 0.2515\nvn 0.9422 -0.2288 0.2449\nvn 0.9619 -0.2265 0.1530\nvn 0.9724 -0.2244 0.0641\nvn -0.2992 -0.5940 0.7468\nvn -0.3529 -0.5816 0.7329\nvn -0.2417 -0.6041 0.7594\nvn -0.2587 -0.5341 0.8049\nvn -0.3203 -0.5247 0.7888\nvn -0.3784 -0.5109 0.7719\nvn -0.1066 -0.6153 0.7810\nvn -0.1781 -0.6108 0.7715\nvn -0.1145 -0.5448 0.8307\nvn -0.1910 -0.5411 0.8190\nvn -0.1262 -0.3858 0.9139\nvn -0.2105 -0.3835 0.8992\nvn -0.2016 -0.4650 0.8620\nvn -0.1212 -0.4685 0.8751\nvn -0.2858 -0.3777 0.8807\nvn -0.2735 -0.4591 0.8453\nvn -0.4195 -0.3568 0.8347\nvn -0.4005 -0.4366 0.8056\nvn -0.3389 -0.4492 0.8267\nvn -0.3546 -0.3695 0.8589\nvn -0.0247 -0.6166 0.7869\nvn 0.0681 -0.6147 0.7858\nvn 0.0707 -0.5430 0.8368\nvn -0.0280 -0.5457 0.8375\nvn 0.1728 -0.6084 0.7746\nvn 0.1806 -0.5360 0.8247\nvn 0.1952 -0.3747 0.9064\nvn 0.1883 -0.4581 0.8687\nvn 0.0764 -0.3818 0.9211\nvn 0.0734 -0.4653 0.8821\nvn -0.0298 -0.4685 0.8829\nvn -0.0309 -0.3855 0.9222\nvn 0.2100 -0.0000 0.9777\nvn 0.2087 -0.0984 0.9730\nvn 0.0840 -0.0000 0.9965\nvn 0.0838 -0.1012 0.9913\nvn 0.0818 -0.1992 0.9765\nvn 0.2059 -0.1942 0.9591\nvn -0.1344 -0.0000 0.9909\nvn -0.1337 -0.1036 0.9856\nvn -0.0311 -0.1029 0.9942\nvn -0.0306 -0.0000 0.9995\nvn -0.1325 -0.2029 0.9702\nvn -0.0311 -0.2021 0.9789\nvn -0.0313 -0.2965 0.9545\nvn -0.1299 -0.2974 0.9459\nvn 0.0794 -0.2929 0.9528\nvn 0.2011 -0.2867 0.9367\nvn -0.2263 0.0000 0.9741\nvn -0.2255 -0.1031 0.9688\nvn -0.3092 0.0000 0.9510\nvn -0.3076 -0.1016 0.9461\nvn -0.3031 -0.1987 0.9320\nvn -0.2224 -0.2020 0.9538\nvn -0.4558 0.0000 0.8901\nvn -0.4537 -0.0946 0.8861\nvn -0.3827 -0.0986 0.9186\nvn -0.3848 0.0000 0.9230\nvn -0.4463 -0.1857 0.8754\nvn -0.3769 -0.1937 0.9058\nvn -0.3673 -0.2837 0.8858\nvn -0.4350 -0.2737 0.8578\nvn -0.2958 -0.2913 0.9098\nvn -0.2175 -0.2954 0.9303\nvn 0.5990 -0.5801 -0.5519\nvn 0.6182 -0.5779 -0.5328\nvn 0.5906 -0.6227 -0.5133\nvn 0.5721 -0.6236 -0.5327\nvn 0.6624 -0.5780 -0.4765\nvn 0.6396 -0.5773 -0.5075\nvn 0.6319 -0.6253 -0.4579\nvn 0.6104 -0.6233 -0.4888\nvn 0.5656 -0.7122 -0.4158\nvn 0.5478 -0.7080 -0.4457\nvn 0.5798 -0.6671 -0.4678\nvn 0.5993 -0.6701 -0.4379\nvn 0.5308 -0.7053 -0.4699\nvn 0.5612 -0.6652 -0.4926\nvn 0.5439 -0.6652 -0.5115\nvn 0.5146 -0.7041 -0.4893\nvn 0.6868 -0.5798 -0.4385\nvn 0.7113 -0.5821 -0.3940\nvn 0.6769 -0.6319 -0.3775\nvn 0.6541 -0.6283 -0.4212\nvn 0.7354 -0.5849 -0.3422\nvn 0.6989 -0.6357 -0.3278\nvn 0.6197 -0.7279 -0.2935\nvn 0.6603 -0.6835 -0.3112\nvn 0.6022 -0.7225 -0.3397\nvn 0.6402 -0.6788 -0.3597\nvn 0.6198 -0.6742 -0.4015\nvn 0.5838 -0.7171 -0.3808\nvn 0.4955 -0.8368 -0.2328\nvn 0.4845 -0.8307 -0.2743\nvn 0.5237 -0.7986 -0.2967\nvn 0.5366 -0.8047 -0.2540\nvn 0.4614 -0.8177 -0.3442\nvn 0.4732 -0.8242 -0.3111\nvn 0.4961 -0.7861 -0.3686\nvn 0.5099 -0.7922 -0.3353\nvn 0.5471 -0.7565 -0.3583\nvn 0.5309 -0.7508 -0.3929\nvn 0.5629 -0.7625 -0.3190\nvn 0.5784 -0.7683 -0.2740\nvn 0.4495 -0.8119 -0.3724\nvn 0.4374 -0.8071 -0.3966\nvn 0.4684 -0.7764 -0.4216\nvn 0.4821 -0.7806 -0.3977\nvn 0.4254 -0.8038 -0.4160\nvn 0.4549 -0.7736 -0.4412\nvn 0.4848 -0.7405 -0.4655\nvn 0.4997 -0.7423 -0.4464\nvn 0.5151 -0.7460 -0.4219\nvn -0.1916 -0.5342 0.8233\nvn -0.3280 -0.5237 0.7862\nvn -0.3557 -0.4545 0.8166\nvn -0.2105 -0.4637 0.8606\nvn -0.4446 -0.5245 0.7262\nvn -0.4072 -0.5206 0.7504\nvn -0.4781 -0.4530 0.7525\nvn -0.4406 -0.4492 0.7773\nvn -0.5320 -0.3049 0.7899\nvn -0.4933 -0.3020 0.8157\nvn -0.4687 -0.3766 0.7991\nvn -0.5079 -0.3795 0.7733\nvn -0.4027 -0.3075 0.8622\nvn -0.3818 -0.3810 0.8420\nvn -0.2263 -0.3930 0.8913\nvn -0.2411 -0.3168 0.9173\nvn -0.4503 -0.5349 0.7149\nvn -0.4336 -0.5499 0.7139\nvn -0.4653 -0.4782 0.7449\nvn -0.4837 -0.4636 0.7424\nvn -0.4000 -0.5656 0.7212\nvn -0.4288 -0.4953 0.7555\nvn -0.4760 -0.3424 0.8101\nvn -0.4543 -0.4202 0.7855\nvn -0.5161 -0.3269 0.7916\nvn -0.4930 -0.4042 0.7705\nvn -0.5124 -0.3895 0.7653\nvn -0.5370 -0.3139 0.7830\nvn -0.5174 -0.0000 0.8558\nvn -0.5142 -0.0893 0.8530\nvn -0.5597 -0.0000 0.8287\nvn -0.5573 -0.0842 0.8260\nvn -0.5484 -0.1668 0.8194\nvn -0.5065 -0.1764 0.8440\nvn -0.5771 0.0000 0.8167\nvn -0.5748 -0.0769 0.8147\nvn -0.5785 -0.0798 0.8118\nvn -0.5820 0.0000 0.8132\nvn -0.5655 -0.1534 0.8103\nvn -0.5704 -0.1587 0.8059\nvn -0.5559 -0.2368 0.7968\nvn -0.5520 -0.2293 0.8017\nvn -0.5351 -0.2480 0.8076\nvn -0.4933 -0.2606 0.8299\nvn -0.5378 0.0000 0.8431\nvn -0.5342 -0.0762 0.8419\nvn -0.4431 0.0000 0.8964\nvn -0.4411 -0.0777 0.8941\nvn -0.4327 -0.1552 0.8881\nvn -0.5264 -0.1517 0.8366\nvn -0.2661 -0.0815 0.9605\nvn -0.2683 0.0000 0.9633\nvn -0.2612 -0.1612 0.9517\nvn -0.2521 -0.2409 0.9372\nvn -0.4206 -0.2312 0.8773\nvn -0.5118 -0.2274 0.8284\nvn 0.0660 -0.7858 -0.6149\nvn 0.1342 -0.7787 -0.6129\nvn 0.1218 -0.8067 -0.5783\nvn 0.0593 -0.8135 -0.5786\nvn 0.2619 -0.7506 -0.6066\nvn 0.2012 -0.7662 -0.6103\nvn 0.2397 -0.7821 -0.5751\nvn 0.1824 -0.7964 -0.5767\nvn 0.1991 -0.8320 -0.5177\nvn 0.1501 -0.8429 -0.5167\nvn 0.1660 -0.8212 -0.5459\nvn 0.2181 -0.8092 -0.5455\nvn 0.0996 -0.8505 -0.5164\nvn 0.1097 -0.8307 -0.5458\nvn 0.0537 -0.8359 -0.5462\nvn 0.0483 -0.8555 -0.5156\nvn 0.3159 -0.7327 -0.6028\nvn 0.3612 -0.7139 -0.5999\nvn 0.3341 -0.7490 -0.5721\nvn 0.2900 -0.7661 -0.5735\nvn 0.3990 -0.6957 -0.5974\nvn 0.3709 -0.7318 -0.5718\nvn 0.3177 -0.7917 -0.5218\nvn 0.3439 -0.7638 -0.5463\nvn 0.2834 -0.8058 -0.5200\nvn 0.3078 -0.7794 -0.5458\nvn 0.2663 -0.7947 -0.5454\nvn 0.2433 -0.8196 -0.5187\nvn 0.2476 -0.8573 -0.4514\nvn 0.2172 -0.8671 -0.4483\nvn 0.2382 -0.8492 -0.4714\nvn 0.2695 -0.8381 -0.4744\nvn 0.1484 -0.8846 -0.4421\nvn 0.1845 -0.8762 -0.4451\nvn 0.1643 -0.8692 -0.4663\nvn 0.2024 -0.8599 -0.4686\nvn 0.2226 -0.8410 -0.4932\nvn 0.1805 -0.8521 -0.4912\nvn 0.2597 -0.8289 -0.4954\nvn 0.2932 -0.8164 -0.4976\nvn 0.1114 -0.8911 -0.4399\nvn 0.0729 -0.8961 -0.4378\nvn 0.0812 -0.8828 -0.4627\nvn 0.1229 -0.8773 -0.4640\nvn 0.0356 -0.8988 -0.4370\nvn 0.0394 -0.8863 -0.4614\nvn 0.0438 -0.8718 -0.4880\nvn 0.0896 -0.8680 -0.4884\nvn 0.1364 -0.8611 -0.4899\nvn -0.3937 0.8258 -0.4038\nvn -0.3805 0.8256 -0.4167\nvn -0.4059 0.8009 -0.4402\nvn -0.4199 0.8003 -0.4280\nvn -0.3660 0.8275 -0.4258\nvn -0.3910 0.8032 -0.4494\nvn -0.4170 0.7764 -0.4726\nvn -0.4325 0.7730 -0.4641\nvn -0.4469 0.7721 -0.4519\nvn -0.3335 0.8360 -0.4357\nvn -0.3576 0.8135 -0.4587\nvn -0.3749 0.8077 -0.4551\nvn -0.3504 0.8309 -0.4323\nvn -0.3828 0.7886 -0.4813\nvn -0.4005 0.7815 -0.4784\nvn -0.4356 0.7300 -0.5266\nvn -0.4538 0.7208 -0.5239\nvn -0.4269 0.7528 -0.5011\nvn -0.4089 0.7606 -0.5042\nvn -0.4708 0.7138 -0.5185\nvn -0.4438 0.7464 -0.4959\nvn -0.5024 0.7062 -0.4990\nvn -0.4746 0.7405 -0.4759\nvn -0.4595 0.7425 -0.4874\nvn -0.4870 0.7086 -0.5106\nvn -0.3154 0.8421 -0.4374\nvn -0.3390 0.8209 -0.4596\nvn -0.2960 0.8494 -0.4368\nvn -0.3192 0.8290 -0.4593\nvn -0.3436 0.8063 -0.4816\nvn -0.3639 0.7968 -0.4825\nvn -0.2523 0.8657 -0.4324\nvn -0.2740 0.8474 -0.4547\nvn -0.2978 0.8380 -0.4572\nvn -0.2751 0.8572 -0.4353\nvn -0.2974 0.8270 -0.4771\nvn -0.3216 0.8163 -0.4799\nvn -0.3474 0.7780 -0.5236\nvn -0.3728 0.7646 -0.5258\nvn -0.3467 0.7920 -0.5025\nvn -0.3217 0.8039 -0.5003\nvn -0.3955 0.7522 -0.5271\nvn -0.3691 0.7805 -0.5045\nvn -0.3897 0.7702 -0.5049\nvn -0.4164 0.7403 -0.5277\nvn -0.4583 0.6362 -0.6207\nvn -0.4835 0.6192 -0.6187\nvn -0.4553 0.6619 -0.5954\nvn -0.4299 0.6779 -0.5963\nvn -0.5048 0.6041 -0.6166\nvn -0.4778 0.6464 -0.5948\nvn -0.4501 0.6854 -0.5724\nvn -0.4275 0.6998 -0.5723\nvn -0.4016 0.7155 -0.5716\nvn -0.5420 0.5772 -0.6108\nvn -0.5164 0.6196 -0.5911\nvn -0.4977 0.6326 -0.5934\nvn -0.5244 0.5898 -0.6142\nvn -0.4897 0.6596 -0.5702\nvn -0.4708 0.6716 -0.5721\nvn -0.4434 0.7078 -0.5499\nvn -0.4628 0.6961 -0.5489\nvn -0.4227 0.7203 -0.5500\nvn -0.3740 0.7484 -0.5477\nvn -0.3998 0.7342 -0.5488\nvn -0.5590 0.5657 -0.6063\nvn -0.5337 0.6086 -0.5871\nvn -0.5751 0.5562 -0.6000\nvn -0.5505 0.5990 -0.5815\nvn -0.5246 0.6399 -0.5615\nvn -0.5077 0.6486 -0.5670\nvn -0.6072 0.5424 -0.5807\nvn -0.5828 0.5864 -0.5627\nvn -0.5666 0.5917 -0.5734\nvn -0.5911 0.5482 -0.5918\nvn -0.5569 0.6288 -0.5427\nvn -0.5409 0.6330 -0.5538\nvn -0.5142 0.6723 -0.5325\nvn -0.5300 0.6686 -0.5216\nvn -0.4979 0.6781 -0.5406\nvn -0.4808 0.6863 -0.5457\nvn -0.4856 0.8685 0.0995\nvn -0.5092 0.8534 0.1118\nvn -0.4890 0.8608 0.1408\nvn -0.4645 0.8786 0.1112\nvn -0.5467 0.8269 0.1318\nvn -0.5229 0.8354 0.1693\nvn -0.4903 0.8476 0.2028\nvn -0.4576 0.8736 0.1656\nvn -0.4349 0.8910 0.1300\nvn -0.6292 0.7572 0.1754\nvn -0.6016 0.7656 0.2279\nvn -0.5605 0.8041 0.1982\nvn -0.5862 0.7957 0.1525\nvn -0.5660 0.7770 0.2754\nvn -0.5267 0.8157 0.2392\nvn -0.4736 0.8069 0.3531\nvn -0.4396 0.8444 0.3061\nvn -0.4861 0.8295 0.2751\nvn -0.5229 0.7910 0.3175\nvn -0.4093 0.8752 0.2578\nvn -0.4518 0.8615 0.2318\nvn -0.3647 0.9164 0.1650\nvn -0.4013 0.9041 0.1470\nvn -0.4234 0.8860 0.1889\nvn -0.3835 0.8993 0.2102\nvn -0.6725 0.7131 0.1981\nvn -0.6429 0.7215 0.2571\nvn -0.7127 0.6662 0.2199\nvn -0.6821 0.6738 0.2841\nvn -0.6433 0.6846 0.3427\nvn -0.6057 0.7327 0.3104\nvn -0.7864 0.5599 0.2607\nvn -0.7535 0.5660 0.3345\nvn -0.7186 0.6225 0.3100\nvn -0.7507 0.6153 0.2404\nvn -0.7126 0.5745 0.4026\nvn -0.6794 0.6318 0.3732\nvn -0.6077 0.5988 0.5216\nvn -0.5769 0.6587 0.4829\nvn -0.6319 0.6443 0.4309\nvn -0.6647 0.5851 0.4645\nvn -0.5433 0.7139 0.4419\nvn -0.5973 0.6979 0.3952\nvn -0.5605 0.7471 0.3574\nvn -0.5086 0.7631 0.3987\nvn -0.2723 0.6640 0.6964\nvn -0.2570 0.7249 0.6391\nvn -0.3546 0.7100 0.6084\nvn -0.3761 0.6484 0.6619\nvn -0.2422 0.7789 0.5785\nvn -0.3324 0.7649 0.5518\nvn -0.4120 0.7483 0.5199\nvn -0.4393 0.6928 0.5718\nvn -0.4652 0.6314 0.6205\nvn -0.2153 0.8650 0.4532\nvn -0.2903 0.8532 0.4334\nvn -0.3110 0.8126 0.4930\nvn -0.2276 0.8258 0.5160\nvn -0.3580 0.8388 0.4103\nvn -0.3842 0.7971 0.4658\nvn -0.4501 0.7802 0.4344\nvn -0.4183 0.8232 0.3839\nvn -0.4819 0.7308 0.4834\nvn -0.5421 0.6142 0.5735\nvn -0.5128 0.6755 0.5298\nvn -0.2045 0.8973 0.3912\nvn -0.2728 0.8863 0.3742\nvn -0.1972 0.9226 0.3315\nvn -0.2576 0.9130 0.3163\nvn -0.3125 0.9015 0.2995\nvn -0.3331 0.8737 0.3545\nvn -0.1916 0.9561 0.2215\nvn -0.2401 0.9479 0.2092\nvn -0.2470 0.9331 0.2613\nvn -0.1926 0.9421 0.2745\nvn -0.2841 0.9385 0.1961\nvn -0.2954 0.9231 0.2461\nvn -0.3409 0.9116 0.2295\nvn -0.3247 0.9283 0.1810\nvn -0.3620 0.8890 0.2802\nvn -0.3889 0.8593 0.3321\nvn -0.2538 0.8745 -0.4133\nvn -0.2315 0.8818 -0.4109\nvn -0.2742 0.8675 -0.4151\nvn -0.2535 0.8838 -0.3933\nvn -0.2336 0.8898 -0.3919\nvn -0.2122 0.8964 -0.3892\nvn -0.3110 0.8557 -0.4137\nvn -0.2931 0.8613 -0.4151\nvn -0.2897 0.8732 -0.3920\nvn -0.2722 0.8780 -0.3937\nvn -0.2506 0.9027 -0.3498\nvn -0.2335 0.9068 -0.3511\nvn -0.2522 0.8933 -0.3721\nvn -0.2698 0.8886 -0.3710\nvn -0.2156 0.9114 -0.3506\nvn -0.2339 0.8982 -0.3721\nvn -0.1770 0.9210 -0.3470\nvn -0.1938 0.9094 -0.3681\nvn -0.2147 0.9037 -0.3704\nvn -0.1968 0.9161 -0.3493\nvn -0.3274 0.8514 -0.4097\nvn -0.3430 0.8483 -0.4034\nvn -0.3217 0.8664 -0.3820\nvn -0.3065 0.8690 -0.3885\nvn -0.3700 0.8473 -0.3811\nvn -0.3569 0.8471 -0.3938\nvn -0.3486 0.8654 -0.3600\nvn -0.3362 0.8649 -0.3728\nvn -0.3096 0.8952 -0.3207\nvn -0.2976 0.8949 -0.3326\nvn -0.3163 0.8807 -0.3525\nvn -0.3293 0.8808 -0.3402\nvn -0.2830 0.8964 -0.3412\nvn -0.3023 0.8819 -0.3617\nvn -0.2863 0.8849 -0.3675\nvn -0.2675 0.8989 -0.3469\nvn -0.2476 0.9333 -0.2600\nvn -0.2377 0.9356 -0.2611\nvn -0.2478 0.9282 -0.2775\nvn -0.2589 0.9274 -0.2699\nvn -0.2225 0.9388 -0.2629\nvn -0.2335 0.9307 -0.2815\nvn -0.2482 0.9207 -0.3012\nvn -0.2632 0.9185 -0.2950\nvn -0.2744 0.9182 -0.2856\nvn -0.1910 0.9450 -0.2655\nvn -0.2024 0.9365 -0.2863\nvn -0.2185 0.9335 -0.2844\nvn -0.2072 0.9419 -0.2642\nvn -0.2165 0.9266 -0.3074\nvn -0.2328 0.9234 -0.3051\nvn -0.2492 0.9119 -0.3259\nvn -0.2328 0.9153 -0.3288\nvn -0.2652 0.9092 -0.3210\nvn -0.2917 0.9075 -0.3022\nvn -0.2792 0.9077 -0.3133\nvn -0.1744 0.9480 -0.2662\nvn -0.1861 0.9396 -0.2872\nvn -0.1588 0.9506 -0.2667\nvn -0.1697 0.9427 -0.2874\nvn -0.1833 0.9335 -0.3083\nvn -0.1998 0.9300 -0.3085\nvn -0.1260 0.9556 -0.2663\nvn -0.1356 0.9486 -0.2859\nvn -0.1534 0.9456 -0.2869\nvn -0.1426 0.9532 -0.2667\nvn -0.1478 0.9405 -0.3059\nvn -0.1659 0.9370 -0.3075\nvn -0.1807 0.9272 -0.3282\nvn -0.1613 0.9314 -0.3264\nvn -0.1985 0.9230 -0.3295\nvn -0.2159 0.9191 -0.3297\nvn -0.0808 0.9960 -0.0372\nvn -0.0932 0.9950 -0.0353\nvn -0.0845 0.9964 0.0016\nvn -0.0734 0.9973 0.0009\nvn -0.1069 0.9937 -0.0344\nvn -0.0986 0.9951 0.0017\nvn -0.0878 0.9955 0.0360\nvn -0.0747 0.9965 0.0375\nvn -0.0637 0.9973 0.0376\nvn -0.1415 0.9893 -0.0355\nvn -0.1335 0.9910 -0.0015\nvn -0.1144 0.9934 0.0005\nvn -0.1234 0.9918 -0.0343\nvn -0.1231 0.9919 0.0306\nvn -0.1044 0.9940 0.0340\nvn -0.0977 0.9907 0.0947\nvn -0.0779 0.9919 0.1000\nvn -0.0918 0.9936 0.0666\nvn -0.1117 0.9918 0.0627\nvn -0.0607 0.9927 0.1041\nvn -0.0757 0.9947 0.0701\nvn -0.0374 0.9932 0.1105\nvn -0.0523 0.9959 0.0742\nvn -0.0621 0.9954 0.0724\nvn -0.0476 0.9930 0.1079\nvn -0.1629 0.9859 -0.0377\nvn -0.1546 0.9880 -0.0050\nvn -0.1861 0.9816 -0.0418\nvn -0.1794 0.9837 -0.0094\nvn -0.1702 0.9852 0.0210\nvn -0.1455 0.9890 0.0266\nvn -0.2412 0.9689 -0.0555\nvn -0.2366 0.9713 -0.0233\nvn -0.2061 0.9784 -0.0159\nvn -0.2129 0.9759 -0.0472\nvn -0.2294 0.9733 0.0063\nvn -0.1988 0.9799 0.0147\nvn -0.2139 0.9746 0.0662\nvn -0.1799 0.9808 0.0750\nvn -0.1892 0.9809 0.0442\nvn -0.2224 0.9743 0.0362\nvn -0.1486 0.9855 0.0824\nvn -0.1604 0.9857 0.0516\nvn -0.1340 0.9893 0.0574\nvn -0.1218 0.9885 0.0891\nvn -0.1430 0.9622 0.2316\nvn -0.1502 0.9714 0.1839\nvn -0.1942 0.9654 0.1741\nvn -0.0999 0.9656 0.2400\nvn -0.1117 0.9750 0.1922\nvn -0.1238 0.9807 0.1513\nvn -0.1596 0.9768 0.1431\nvn -0.1991 0.9708 0.1339\nvn -0.0296 0.9670 0.2532\nvn -0.0484 0.9773 0.2061\nvn -0.0775 0.9768 0.1995\nvn -0.0622 0.9670 0.2470\nvn -0.0659 0.9841 0.1652\nvn -0.0931 0.9829 0.1586\nvn -0.1075 0.9867 0.1222\nvn -0.0829 0.9882 0.1287\nvn -0.1368 0.9839 0.1153\nvn -0.2065 0.9735 0.0985\nvn -0.1692 0.9797 0.1073\nvn -0.0019 0.9659 0.2589\nvn -0.0232 0.9769 0.2122\nvn 0.0216 0.9641 0.2646\nvn -0.0028 0.9759 0.2183\nvn -0.0242 0.9839 0.1770\nvn -0.0434 0.9842 0.1714\nvn 0.0552 0.9593 0.2769\nvn 0.0260 0.9728 0.2303\nvn 0.0141 0.9744 0.2242\nvn 0.0402 0.9619 0.2705\nvn 0.0016 0.9822 0.1878\nvn -0.0097 0.9831 0.1827\nvn -0.0297 0.9891 0.1441\nvn -0.0200 0.9887 0.1484\nvn -0.0440 0.9892 0.1396\nvn -0.0612 0.9891 0.1343\nvn -0.4733 0.8641 -0.1714\nvn -0.5099 0.8391 -0.1892\nvn -0.5165 0.8436 -0.1468\nvn -0.4778 0.8686 -0.1316\nvn -0.5490 0.8099 -0.2064\nvn -0.5570 0.8146 -0.1619\nvn -0.5631 0.8177 -0.1193\nvn -0.5201 0.8473 -0.1077\nvn -0.4804 0.8719 -0.0944\nvn -0.6308 0.7380 -0.2396\nvn -0.6427 0.7424 -0.1893\nvn -0.5997 0.7807 -0.1758\nvn -0.5893 0.7763 -0.2236\nvn -0.6522 0.7450 -0.1397\nvn -0.6070 0.7839 -0.1305\nvn -0.6638 0.7468 -0.0405\nvn -0.6169 0.7860 -0.0401\nvn -0.6132 0.7853 -0.0852\nvn -0.6590 0.7466 -0.0909\nvn -0.5703 0.8206 -0.0367\nvn -0.5671 0.8199 -0.0787\nvn -0.4827 0.8755 -0.0235\nvn -0.4812 0.8746 -0.0594\nvn -0.5232 0.8494 -0.0695\nvn -0.5245 0.8508 -0.0318\nvn -0.6719 0.6953 -0.2552\nvn -0.6861 0.6991 -0.2013\nvn -0.7124 0.6481 -0.2690\nvn -0.7282 0.6516 -0.2127\nvn -0.7404 0.6539 -0.1556\nvn -0.6967 0.7019 -0.1484\nvn -0.7870 0.5430 -0.2929\nvn -0.8060 0.5450 -0.2309\nvn -0.7686 0.5999 -0.2222\nvn -0.7509 0.5972 -0.2820\nvn -0.8206 0.5465 -0.1672\nvn -0.7818 0.6020 -0.1622\nvn -0.8351 0.5490 -0.0345\nvn -0.7956 0.6047 -0.0369\nvn -0.7910 0.6035 -0.1003\nvn -0.8303 0.5479 -0.1022\nvn -0.7536 0.6562 -0.0387\nvn -0.7488 0.6555 -0.0981\nvn -0.7047 0.7031 -0.0947\nvn -0.7094 0.7037 -0.0403\nvn -0.7738 0.6106 0.1685\nvn -0.8111 0.5554 0.1837\nvn -0.7347 0.6610 0.1526\nvn -0.7479 0.6582 0.0868\nvn -0.7882 0.6076 0.0976\nvn -0.8265 0.5524 0.1086\nvn -0.6488 0.7514 0.1201\nvn -0.6932 0.7077 0.1368\nvn -0.6602 0.7483 0.0653\nvn -0.7053 0.7048 0.0756\nvn -0.7102 0.7038 0.0167\nvn -0.6646 0.7471 0.0110\nvn -0.7536 0.6569 0.0226\nvn -0.8341 0.5505 0.0355\nvn -0.7951 0.6058 0.0292\nvn -0.6040 0.7901 0.1046\nvn -0.5616 0.8225 0.0906\nvn -0.5687 0.8212 0.0479\nvn -0.6140 0.7874 0.0552\nvn -0.4837 0.8719 0.0762\nvn -0.5208 0.8499 0.0801\nvn -0.4842 0.8738 0.0447\nvn -0.5239 0.8507 0.0428\nvn -0.5254 0.8509 0.0067\nvn -0.4827 0.8757 0.0108\nvn -0.5704 0.8213 0.0049\nvn -0.6178 0.7863 0.0073\nvn -0.1383 0.9483 0.2855\nvn -0.1360 0.9294 0.3431\nvn -0.0818 0.9326 0.3516\nvn -0.0899 0.9516 0.2938\nvn -0.1388 0.8730 0.4675\nvn -0.1365 0.9044 0.4043\nvn -0.0709 0.8764 0.4763\nvn -0.0753 0.9078 0.4125\nvn 0.0416 0.8748 0.4827\nvn 0.0249 0.9067 0.4210\nvn -0.0219 0.9082 0.4179\nvn -0.0106 0.8769 0.4806\nvn 0.0073 0.9322 0.3619\nvn -0.0341 0.9333 0.3574\nvn -0.0476 0.9526 0.3004\nvn -0.0109 0.9521 0.3057\nvn -0.1437 0.8343 0.5323\nvn -0.1495 0.7884 0.5967\nvn -0.0663 0.7925 0.6063\nvn -0.0676 0.8382 0.5411\nvn -0.1646 0.6749 0.7194\nvn -0.1570 0.7349 0.6597\nvn -0.0667 0.6803 0.7299\nvn -0.0657 0.7398 0.6696\nvn 0.0967 0.6795 0.7273\nvn 0.0853 0.7382 0.6691\nvn 0.0146 0.7404 0.6720\nvn 0.0206 0.6817 0.7314\nvn 0.0720 0.7905 0.6082\nvn 0.0077 0.7930 0.6091\nvn -0.0010 0.8384 0.5450\nvn 0.0575 0.8363 0.5453\nvn 0.3250 0.6464 0.6903\nvn 0.2941 0.7073 0.6429\nvn 0.2496 0.7179 0.6499\nvn 0.2755 0.6589 0.7000\nvn 0.2614 0.7617 0.5929\nvn 0.2213 0.7719 0.5960\nvn 0.1775 0.7797 0.6005\nvn 0.2010 0.7269 0.6567\nvn 0.2224 0.6679 0.7103\nvn 0.1913 0.8525 0.4864\nvn 0.1608 0.8601 0.4841\nvn 0.1917 0.8191 0.5407\nvn 0.2265 0.8107 0.5399\nvn 0.1265 0.8661 0.4836\nvn 0.1525 0.8264 0.5420\nvn 0.1081 0.8320 0.5442\nvn 0.0870 0.8712 0.4831\nvn 0.1283 0.7861 0.6046\nvn 0.1636 0.6751 0.7194\nvn 0.1467 0.7334 0.6638\nvn 0.1553 0.8883 0.4321\nvn 0.1300 0.8942 0.4284\nvn 0.1207 0.9175 0.3790\nvn 0.0989 0.9223 0.3735\nvn 0.0734 0.9264 0.3694\nvn 0.0999 0.8995 0.4254\nvn 0.0692 0.9446 0.3209\nvn 0.0865 0.9411 0.3269\nvn 0.0470 0.9478 0.3154\nvn 0.0205 0.9503 0.3106\nvn 0.0429 0.9298 0.3655\nvn 0.0652 0.9036 0.4234\nvn -0.2379 0.9575 0.1631\nvn -0.2397 0.9630 0.1233\nvn -0.2764 0.9545 0.1119\nvn -0.2779 0.9487 0.1507\nvn -0.2495 0.9667 0.0566\nvn -0.2435 0.9659 0.0883\nvn -0.2821 0.9583 0.0457\nvn -0.2785 0.9573 0.0773\nvn -0.3449 0.9384 0.0219\nvn -0.3441 0.9374 0.0531\nvn -0.3113 0.9480 0.0655\nvn -0.3140 0.9488 0.0341\nvn -0.3462 0.9341 0.0869\nvn -0.3115 0.9450 0.0994\nvn -0.3154 0.9389 0.1378\nvn -0.3524 0.9277 0.1233\nvn -0.2552 0.9665 0.0263\nvn -0.2619 0.9651 -0.0029\nvn -0.2918 0.9564 -0.0141\nvn -0.2874 0.9577 0.0158\nvn -0.2712 0.9603 -0.0650\nvn -0.2666 0.9632 -0.0335\nvn -0.2989 0.9511 -0.0772\nvn -0.2966 0.9540 -0.0443\nvn -0.3534 0.9296 -0.1049\nvn -0.3532 0.9329 -0.0704\nvn -0.3247 0.9441 -0.0571\nvn -0.3270 0.9407 -0.0901\nvn -0.3504 0.9358 -0.0390\nvn -0.3218 0.9465 -0.0258\nvn -0.3174 0.9483 0.0039\nvn -0.3476 0.9376 -0.0084\nvn -0.4429 0.8891 -0.1156\nvn -0.4396 0.8850 -0.1537\nvn -0.4436 0.8926 -0.0806\nvn -0.4107 0.9094 -0.0665\nvn -0.4110 0.9061 -0.1001\nvn -0.4091 0.9022 -0.1367\nvn -0.4438 0.8960 -0.0138\nvn -0.4439 0.8949 -0.0470\nvn -0.4093 0.9124 -0.0023\nvn -0.4094 0.9117 -0.0344\nvn -0.3778 0.9256 -0.0214\nvn -0.3763 0.9264 0.0096\nvn -0.3800 0.9235 -0.0524\nvn -0.3810 0.9167 -0.1202\nvn -0.3813 0.9205 -0.0851\nvn -0.4456 0.8950 0.0194\nvn -0.4472 0.8930 0.0510\nvn -0.4137 0.9083 0.0620\nvn -0.4101 0.9116 0.0295\nvn -0.4539 0.8871 0.0836\nvn -0.4205 0.9023 0.0948\nvn -0.3879 0.9152 0.1094\nvn -0.3801 0.9220 0.0737\nvn -0.3770 0.9253 0.0412\nvn -0.7518 0.0889 -0.6534\nvn -0.7350 0.0909 -0.6719\nvn -0.7725 0.0869 -0.6290\nvn -0.7635 0.1682 -0.6236\nvn -0.7428 0.1716 -0.6472\nvn -0.7256 0.1752 -0.6654\nvn -0.8237 0.0833 -0.5609\nvn -0.7965 0.0851 -0.5986\nvn -0.8148 0.1620 -0.5566\nvn -0.7878 0.1650 -0.5935\nvn -0.7840 0.3047 -0.5408\nvn -0.7571 0.3083 -0.5760\nvn -0.7742 0.2394 -0.5859\nvn -0.8014 0.2359 -0.5497\nvn -0.7329 0.3124 -0.6043\nvn -0.7500 0.2433 -0.6150\nvn -0.6944 0.3225 -0.6433\nvn -0.7118 0.2524 -0.6555\nvn -0.7290 0.2477 -0.6381\nvn -0.7120 0.3172 -0.6265\nvn -0.8528 0.0817 -0.5158\nvn -0.8830 0.0804 -0.4624\nvn -0.8742 0.1572 -0.4594\nvn -0.8441 0.1595 -0.5119\nvn -0.9401 0.0784 -0.3319\nvn -0.9126 0.0792 -0.4012\nvn -0.9312 0.1541 -0.3303\nvn -0.9039 0.1554 -0.3985\nvn -0.8988 0.2964 -0.3230\nvn -0.8718 0.2976 -0.3890\nvn -0.8900 0.2282 -0.3946\nvn -0.9173 0.2268 -0.3272\nvn -0.8427 0.2994 -0.4476\nvn -0.8606 0.2303 -0.4543\nvn -0.8305 0.2328 -0.5061\nvn -0.8129 0.3018 -0.4981\nvn -0.7640 0.5410 -0.3517\nvn -0.7956 0.4849 -0.3633\nvn -0.8199 0.4860 -0.3027\nvn -0.7393 0.5389 -0.4037\nvn -0.7691 0.4842 -0.4173\nvn -0.7965 0.4261 -0.4289\nvn -0.8241 0.4258 -0.3735\nvn -0.8498 0.4259 -0.3107\nvn -0.6893 0.5359 -0.4875\nvn -0.7158 0.4840 -0.5034\nvn -0.7422 0.4838 -0.4638\nvn -0.7139 0.5372 -0.4492\nvn -0.7408 0.4284 -0.5174\nvn -0.7682 0.4270 -0.4770\nvn -0.7920 0.3664 -0.4883\nvn -0.7636 0.3688 -0.5300\nvn -0.8211 0.3646 -0.4391\nvn -0.8761 0.3627 -0.3176\nvn -0.8497 0.3634 -0.3820\nvn -0.6657 0.5355 -0.5198\nvn -0.6911 0.4850 -0.5359\nvn -0.6441 0.5362 -0.5455\nvn -0.6683 0.4871 -0.5623\nvn -0.6915 0.4338 -0.5776\nvn -0.7149 0.4306 -0.5509\nvn -0.6305 0.4951 -0.5978\nvn -0.6481 0.4904 -0.5826\nvn -0.6245 0.5383 -0.5659\nvn -0.6531 0.4433 -0.6139\nvn -0.6708 0.4379 -0.5985\nvn -0.6923 0.3804 -0.6132\nvn -0.6746 0.3859 -0.6292\nvn -0.7132 0.3757 -0.5918\nvn -0.7372 0.3719 -0.5642\nvn 0.1006 0.9372 0.3341\nvn 0.0657 0.9566 0.2838\nvn 0.1372 0.9124 0.3856\nvn 0.1491 0.9068 0.3942\nvn 0.1094 0.9332 0.3423\nvn 0.0738 0.9539 0.2911\nvn 0.2160 0.8445 0.4901\nvn 0.1765 0.8814 0.4381\nvn 0.2335 0.8355 0.4974\nvn 0.1903 0.8745 0.4461\nvn 0.2334 0.8204 0.5219\nvn 0.1898 0.8620 0.4701\nvn 0.1960 0.8677 0.4569\nvn 0.2401 0.8273 0.5078\nvn 0.1483 0.8971 0.4161\nvn 0.1531 0.9017 0.4045\nvn 0.0753 0.9488 0.3067\nvn 0.0768 0.9512 0.2989\nvn 0.1134 0.9293 0.3515\nvn 0.1097 0.9259 0.3616\nvn 0.2563 0.8005 0.5419\nvn 0.2950 0.7506 0.5912\nvn 0.3192 0.7381 0.5943\nvn 0.2764 0.7903 0.5468\nvn 0.3675 0.6326 0.6817\nvn 0.3327 0.6939 0.6386\nvn 0.3984 0.6171 0.6786\nvn 0.3598 0.6807 0.6381\nvn 0.4065 0.5932 0.6949\nvn 0.3658 0.6580 0.6582\nvn 0.3727 0.6676 0.6445\nvn 0.4131 0.6036 0.6819\nvn 0.3224 0.7180 0.6169\nvn 0.3297 0.7270 0.6023\nvn 0.2853 0.7802 0.5567\nvn 0.2781 0.7723 0.5712\nvn 0.0000 0.6048 0.7964\nvn 0.0000 0.6631 0.7485\nvn 0.1521 0.6609 0.7349\nvn 0.1730 0.5980 0.7826\nvn -0.0000 0.7209 0.6931\nvn 0.1325 0.7165 0.6848\nvn 0.2295 0.7138 0.6617\nvn 0.2642 0.6541 0.7088\nvn 0.2961 0.5917 0.7498\nvn -0.0000 0.8175 0.5759\nvn 0.0930 0.8153 0.5715\nvn 0.1117 0.7698 0.6285\nvn -0.0000 0.7704 0.6375\nvn 0.1626 0.8150 0.5561\nvn 0.1964 0.7665 0.6114\nvn 0.2499 0.7678 0.5900\nvn 0.2092 0.8159 0.5390\nvn 0.2919 0.7130 0.6376\nvn 0.3715 0.5885 0.7181\nvn 0.3320 0.6534 0.6803\nvn -0.0000 0.8567 0.5158\nvn 0.0742 0.8570 0.5100\nvn 0.0000 0.8922 0.4517\nvn 0.0578 0.8914 0.4496\nvn 0.1018 0.8922 0.4399\nvn 0.1316 0.8562 0.4996\nvn 0.0000 0.9451 0.3268\nvn 0.0293 0.9449 0.3260\nvn 0.0424 0.9212 0.3867\nvn 0.0000 0.9208 0.3900\nvn 0.0518 0.9457 0.3208\nvn 0.0754 0.9215 0.3809\nvn 0.0976 0.9233 0.3714\nvn 0.0670 0.9469 0.3146\nvn 0.1320 0.8937 0.4288\nvn 0.1692 0.8583 0.4845\nvn -0.2072 0.8894 -0.4075\nvn -0.2265 0.8743 -0.4293\nvn -0.1885 0.9030 -0.3861\nvn -0.1634 0.9094 -0.3825\nvn -0.1800 0.8969 -0.4039\nvn -0.1984 0.8828 -0.4258\nvn -0.1554 0.9260 -0.3442\nvn -0.1715 0.9151 -0.3649\nvn -0.1332 0.9306 -0.3410\nvn -0.1473 0.9207 -0.3615\nvn -0.0871 0.9382 -0.3350\nvn -0.0971 0.9299 -0.3548\nvn -0.1228 0.9256 -0.3581\nvn -0.1099 0.9348 -0.3378\nvn -0.1088 0.9204 -0.3757\nvn -0.1362 0.9154 -0.3788\nvn -0.1345 0.8978 -0.4193\nvn -0.1670 0.8909 -0.4224\nvn -0.1514 0.9037 -0.4004\nvn -0.1208 0.9099 -0.3969\nvn -0.1412 0.9355 -0.3238\nvn -0.1282 0.9440 -0.3039\nvn -0.1089 0.9472 -0.3017\nvn -0.1200 0.9394 -0.3210\nvn -0.1083 0.9580 -0.2655\nvn -0.1175 0.9515 -0.2845\nvn -0.0913 0.9600 -0.2645\nvn -0.0989 0.9541 -0.2827\nvn -0.0581 0.9632 -0.2626\nvn -0.0632 0.9581 -0.2795\nvn -0.0811 0.9562 -0.2811\nvn -0.0742 0.9618 -0.2635\nvn -0.0701 0.9522 -0.2973\nvn -0.0890 0.9500 -0.2993\nvn -0.0991 0.9428 -0.3183\nvn -0.0777 0.9457 -0.3157\nvn -0.0000 0.9654 -0.2609\nvn -0.0000 0.9610 -0.2766\nvn -0.0146 0.9608 -0.2769\nvn -0.0132 0.9653 -0.2609\nvn -0.0000 0.9560 -0.2934\nvn -0.0161 0.9558 -0.2935\nvn -0.0334 0.9551 -0.2944\nvn -0.0299 0.9603 -0.2774\nvn -0.0274 0.9649 -0.2613\nvn 0.0000 0.9442 -0.3293\nvn -0.0203 0.9439 -0.3295\nvn -0.0181 0.9502 -0.3112\nvn 0.0000 0.9505 -0.3107\nvn -0.0419 0.9428 -0.3308\nvn -0.0372 0.9494 -0.3120\nvn -0.0573 0.9478 -0.3137\nvn -0.0640 0.9410 -0.3324\nvn -0.0512 0.9540 -0.2955\nvn -0.0422 0.9642 -0.2618\nvn -0.0464 0.9594 -0.2784\nvn 0.0000 0.9373 -0.3485\nvn -0.0229 0.9368 -0.3491\nvn -0.0000 0.9294 -0.3691\nvn -0.0256 0.9290 -0.3693\nvn -0.0528 0.9272 -0.3708\nvn -0.0469 0.9355 -0.3501\nvn -0.0000 0.9107 -0.4130\nvn -0.0319 0.9101 -0.4131\nvn -0.0287 0.9200 -0.3909\nvn -0.0000 0.9207 -0.3903\nvn -0.0658 0.9076 -0.4147\nvn -0.0588 0.9181 -0.3920\nvn -0.0901 0.9145 -0.3943\nvn -0.1000 0.9037 -0.4164\nvn -0.0804 0.9245 -0.3727\nvn -0.0720 0.9331 -0.3523\nvn -0.0631 0.9980 -0.0009\nvn -0.0700 0.9968 -0.0397\nvn -0.0549 0.9978 0.0371\nvn -0.0460 0.9983 0.0355\nvn -0.0538 0.9985 -0.0033\nvn -0.0592 0.9973 -0.0428\nvn -0.0300 0.9932 0.1128\nvn -0.0437 0.9963 0.0746\nvn -0.0227 0.9932 0.1139\nvn -0.0363 0.9966 0.0745\nvn -0.0116 0.9933 0.1148\nvn -0.0226 0.9971 0.0725\nvn -0.0289 0.9969 0.0737\nvn -0.0171 0.9933 0.1147\nvn -0.0299 0.9991 0.0314\nvn -0.0381 0.9987 0.0336\nvn -0.0389 0.9980 -0.0494\nvn -0.0491 0.9977 -0.0462\nvn -0.0442 0.9990 -0.0061\nvn -0.0354 0.9993 -0.0092\nvn -0.0120 0.9884 0.1517\nvn 0.0091 0.9812 0.1928\nvn 0.0159 0.9803 0.1971\nvn -0.0060 0.9879 0.1547\nvn 0.0355 0.9710 0.2363\nvn 0.0417 0.9693 0.2424\nvn 0.0454 0.9661 0.2543\nvn 0.0459 0.9676 0.2483\nvn 0.0218 0.9785 0.2050\nvn 0.0196 0.9793 0.2014\nvn -0.0006 0.9876 0.1569\nvn 0.0025 0.9873 0.1589\nvn -0.0000 0.9634 0.2682\nvn 0.0183 0.9636 0.2666\nvn -0.0000 0.9771 0.2128\nvn 0.0097 0.9771 0.2126\nvn 0.0168 0.9774 0.2107\nvn 0.0322 0.9640 0.2641\nvn -0.0000 0.9935 0.1139\nvn -0.0017 0.9935 0.1141\nvn 0.0032 0.9868 0.1617\nvn 0.0000 0.9868 0.1619\nvn -0.0040 0.9934 0.1144\nvn 0.0046 0.9869 0.1613\nvn 0.0047 0.9871 0.1602\nvn -0.0077 0.9934 0.1147\nvn 0.0205 0.9778 0.2084\nvn 0.0414 0.9649 0.2594\nvn -0.0000 0.9977 0.0684\nvn -0.0050 0.9976 0.0690\nvn -0.0000 0.9997 0.0253\nvn -0.0073 0.9996 0.0256\nvn -0.0146 0.9995 0.0272\nvn -0.0106 0.9975 0.0699\nvn -0.0000 0.9984 -0.0572\nvn -0.0095 0.9983 -0.0570\nvn -0.0086 0.9998 -0.0159\nvn -0.0000 0.9999 -0.0169\nvn -0.0191 0.9983 -0.0549\nvn -0.0175 0.9997 -0.0145\nvn -0.0262 0.9996 -0.0119\nvn -0.0291 0.9982 -0.0526\nvn -0.0225 0.9993 0.0291\nvn -0.0161 0.9973 0.0712\nvn -0.6257 0.1104 -0.7722\nvn -0.6011 0.1147 -0.7909\nvn -0.6130 0.2142 -0.7605\nvn -0.5883 0.2224 -0.7774\nvn -0.5528 0.2325 -0.8002\nvn -0.5668 0.1197 -0.8151\nvn -0.5707 0.3935 -0.7208\nvn -0.5439 0.4078 -0.7334\nvn -0.5682 0.3208 -0.7578\nvn -0.5945 0.3087 -0.7425\nvn -0.5068 0.4250 -0.7500\nvn -0.5326 0.3345 -0.7775\nvn -0.3936 0.4637 -0.7938\nvn -0.4185 0.3674 -0.8306\nvn -0.4834 0.3505 -0.8022\nvn -0.4580 0.4436 -0.7704\nvn -0.4384 0.2564 -0.8614\nvn -0.5046 0.2437 -0.8282\nvn -0.5181 0.1257 -0.8460\nvn -0.4524 0.1323 -0.8819\nvn -0.5445 0.4674 -0.6965\nvn -0.5159 0.4843 -0.7066\nvn -0.5160 0.5322 -0.6712\nvn -0.4870 0.5496 -0.6788\nvn -0.4487 0.5696 -0.6886\nvn -0.4787 0.5027 -0.7198\nvn -0.4278 0.6539 -0.6240\nvn -0.4570 0.6062 -0.6509\nvn -0.4873 0.5877 -0.6458\nvn -0.3896 0.6735 -0.6281\nvn -0.4189 0.6257 -0.6580\nvn -0.2865 0.7129 -0.6401\nvn -0.3119 0.6675 -0.6761\nvn -0.3709 0.6468 -0.6664\nvn -0.3425 0.6934 -0.6339\nvn -0.3392 0.6121 -0.7144\nvn -0.4001 0.5905 -0.7009\nvn -0.4294 0.5235 -0.7359\nvn -0.3667 0.5447 -0.7542\nvn -0.0000 0.7554 -0.6552\nvn -0.0000 0.7150 -0.6991\nvn -0.0811 0.7112 -0.6982\nvn -0.0729 0.7530 -0.6539\nvn 0.0000 0.6627 -0.7489\nvn -0.0896 0.6596 -0.7463\nvn -0.1808 0.6485 -0.7394\nvn -0.1637 0.7020 -0.6931\nvn -0.1487 0.7440 -0.6514\nvn 0.0000 0.5150 -0.8572\nvn -0.1084 0.5116 -0.8524\nvn -0.0991 0.5934 -0.7988\nvn 0.0000 0.5978 -0.8016\nvn -0.2158 0.4999 -0.8388\nvn -0.1980 0.5825 -0.7883\nvn -0.2891 0.5651 -0.7727\nvn -0.3126 0.4833 -0.8178\nvn -0.2652 0.6323 -0.7280\nvn -0.2206 0.7306 -0.6462\nvn -0.2426 0.6864 -0.6856\nvn 0.0000 0.4138 -0.9104\nvn -0.1174 0.4097 -0.9046\nvn 0.0000 0.2912 -0.9567\nvn -0.1251 0.2887 -0.9492\nvn -0.2462 0.2805 -0.9277\nvn -0.2324 0.3997 -0.8867\nvn -0.1301 0.1497 -0.9801\nvn 0.0000 0.1515 -0.9885\nvn -0.2560 0.1454 -0.9557\nvn -0.3647 0.1392 -0.9207\nvn -0.3528 0.2691 -0.8962\nvn -0.3344 0.3846 -0.8604\nvn -0.0122 0.9696 -0.2446\nvn -0.0000 0.9696 -0.2446\nvn -0.0252 0.9693 -0.2447\nvn -0.0237 0.9738 -0.2260\nvn -0.0114 0.9740 -0.2263\nvn 0.0000 0.9741 -0.2263\nvn -0.0536 0.9680 -0.2450\nvn -0.0392 0.9688 -0.2448\nvn -0.0504 0.9730 -0.2253\nvn -0.0366 0.9735 -0.2258\nvn -0.0457 0.9828 -0.1791\nvn -0.0333 0.9830 -0.1808\nvn -0.0347 0.9783 -0.2045\nvn -0.0476 0.9779 -0.2035\nvn -0.0216 0.9831 -0.1819\nvn -0.0224 0.9784 -0.2053\nvn 0.0000 0.9831 -0.1830\nvn 0.0000 0.9785 -0.2061\nvn -0.0108 0.9785 -0.2057\nvn -0.0104 0.9831 -0.1829\nvn -0.0691 0.9670 -0.2452\nvn -0.0847 0.9657 -0.2455\nvn -0.0796 0.9712 -0.2244\nvn -0.0645 0.9722 -0.2249\nvn -0.1176 0.9622 -0.2458\nvn -0.1012 0.9640 -0.2457\nvn -0.1108 0.9685 -0.2231\nvn -0.0948 0.9700 -0.2238\nvn -0.1000 0.9802 -0.1710\nvn -0.0856 0.9812 -0.1731\nvn -0.0899 0.9757 -0.1996\nvn -0.1048 0.9746 -0.1981\nvn -0.0719 0.9819 -0.1753\nvn -0.0752 0.9767 -0.2010\nvn -0.0612 0.9774 -0.2023\nvn -0.0585 0.9824 -0.1773\nvn -0.0750 0.9942 -0.0776\nvn -0.0870 0.9934 -0.0746\nvn -0.0635 0.9947 -0.0809\nvn -0.0665 0.9911 -0.1155\nvn -0.0788 0.9905 -0.1123\nvn -0.0916 0.9898 -0.1094\nvn -0.0414 0.9953 -0.0877\nvn -0.0523 0.9951 -0.0843\nvn -0.0429 0.9917 -0.1215\nvn -0.0545 0.9914 -0.1187\nvn -0.0565 0.9872 -0.1495\nvn -0.0442 0.9874 -0.1520\nvn -0.0690 0.9867 -0.1469\nvn -0.0957 0.9853 -0.1414\nvn -0.0822 0.9861 -0.1441\nvn -0.0306 0.9954 -0.0904\nvn -0.0202 0.9955 -0.0931\nvn -0.0207 0.9918 -0.1262\nvn -0.0316 0.9917 -0.1243\nvn 0.0000 0.9954 -0.0954\nvn -0.0099 0.9955 -0.0944\nvn -0.0000 0.9918 -0.1281\nvn -0.0101 0.9917 -0.1279\nvn -0.0102 0.9876 -0.1568\nvn 0.0000 0.9875 -0.1575\nvn -0.0210 0.9875 -0.1559\nvn -0.0324 0.9875 -0.1540\nvn -0.1340 0.9601 -0.2456\nvn -0.1493 0.9580 -0.2449\nvn -0.1415 0.9650 -0.2209\nvn -0.1262 0.9668 -0.2221\nvn -0.1812 0.9529 -0.2434\nvn -0.1651 0.9556 -0.2442\nvn -0.1731 0.9603 -0.2189\nvn -0.1565 0.9630 -0.2196\nvn -0.1614 0.9732 -0.1636\nvn -0.1445 0.9757 -0.1647\nvn -0.1500 0.9696 -0.1931\nvn -0.1663 0.9672 -0.1918\nvn -0.1292 0.9775 -0.1666\nvn -0.1346 0.9716 -0.1947\nvn -0.1199 0.9731 -0.1965\nvn -0.1144 0.9790 -0.1687\nvn -0.1981 0.9496 -0.2430\nvn -0.2142 0.9462 -0.2426\nvn -0.2084 0.9532 -0.2191\nvn -0.1901 0.9572 -0.2183\nvn -0.2485 0.9366 -0.2471\nvn -0.2315 0.9418 -0.2439\nvn -0.2489 0.9414 -0.2276\nvn -0.2279 0.9482 -0.2212\nvn -0.2494 0.9521 -0.1771\nvn -0.2244 0.9597 -0.1691\nvn -0.2261 0.9540 -0.1970\nvn -0.2497 0.9467 -0.2033\nvn -0.2010 0.9655 -0.1653\nvn -0.2041 0.9598 -0.1929\nvn -0.1845 0.9639 -0.1919\nvn -0.1799 0.9701 -0.1632\nvn -0.2170 0.9729 -0.0798\nvn -0.2454 0.9655 -0.0870\nvn -0.1918 0.9786 -0.0741\nvn -0.1954 0.9750 -0.1057\nvn -0.2206 0.9691 -0.1102\nvn -0.2473 0.9617 -0.1185\nvn -0.1483 0.9865 -0.0695\nvn -0.1685 0.9831 -0.0711\nvn -0.1530 0.9829 -0.1023\nvn -0.1731 0.9795 -0.1029\nvn -0.1765 0.9752 -0.1338\nvn -0.1572 0.9785 -0.1335\nvn -0.1983 0.9707 -0.1356\nvn -0.2492 0.9571 -0.1476\nvn -0.2226 0.9647 -0.1405\nvn -0.1299 0.9891 -0.0695\nvn -0.1141 0.9910 -0.0703\nvn -0.1194 0.9873 -0.1044\nvn -0.1354 0.9854 -0.1028\nvn -0.0997 0.9924 -0.0722\nvn -0.1051 0.9887 -0.1066\nvn -0.1097 0.9842 -0.1388\nvn -0.1243 0.9828 -0.1365\nvn -0.1399 0.9810 -0.1346\nvn -0.2655 0.9291 -0.2575\nvn -0.2843 0.9195 -0.2714\nvn -0.2907 0.9230 -0.2520\nvn -0.2709 0.9328 -0.2377\nvn -0.3211 0.8966 -0.3051\nvn -0.3015 0.9091 -0.2874\nvn -0.3302 0.8997 -0.2854\nvn -0.3111 0.9118 -0.2678\nvn -0.3440 0.9092 -0.2348\nvn -0.3228 0.9212 -0.2173\nvn -0.3172 0.9163 -0.2444\nvn -0.3387 0.9038 -0.2617\nvn -0.2991 0.9326 -0.2018\nvn -0.2964 0.9274 -0.2283\nvn -0.2729 0.9378 -0.2148\nvn -0.2755 0.9428 -0.1876\nvn -0.3402 0.8827 -0.3241\nvn -0.3605 0.8671 -0.3438\nvn -0.3707 0.8705 -0.3236\nvn -0.3508 0.8857 -0.3041\nvn -0.4063 0.8274 -0.3877\nvn -0.3817 0.8493 -0.3647\nvn -0.4182 0.8308 -0.3673\nvn -0.3931 0.8525 -0.3446\nvn -0.4399 0.8409 -0.3153\nvn -0.4126 0.8624 -0.2932\nvn -0.4032 0.8571 -0.3206\nvn -0.4295 0.8353 -0.3433\nvn -0.3881 0.8804 -0.2725\nvn -0.3804 0.8749 -0.2998\nvn -0.3588 0.8903 -0.2803\nvn -0.3662 0.8955 -0.2531\nvn -0.4341 0.8800 -0.1925\nvn -0.4662 0.8590 -0.2119\nvn -0.4054 0.8974 -0.1740\nvn -0.4005 0.8921 -0.2094\nvn -0.4279 0.8744 -0.2289\nvn -0.4583 0.8531 -0.2494\nvn -0.3529 0.9252 -0.1397\nvn -0.3783 0.9123 -0.1565\nvn -0.3507 0.9203 -0.1734\nvn -0.3756 0.9070 -0.1907\nvn -0.3710 0.9014 -0.2232\nvn -0.3487 0.9146 -0.2049\nvn -0.3952 0.8861 -0.2423\nvn -0.4495 0.8469 -0.2841\nvn -0.4206 0.8684 -0.2625\nvn -0.3267 0.9369 -0.1245\nvn -0.3010 0.9473 -0.1099\nvn -0.3011 0.9429 -0.1422\nvn -0.3269 0.9320 -0.1567\nvn -0.2731 0.9570 -0.0980\nvn -0.2754 0.9527 -0.1286\nvn -0.2754 0.9481 -0.1592\nvn -0.3016 0.9378 -0.1723\nvn -0.3249 0.9268 -0.1882\nvn -0.6145 0.5017 -0.6089\nvn -0.5989 0.5096 -0.6177\nvn -0.6221 0.4579 -0.6350\nvn -0.6373 0.4499 -0.6256\nvn -0.5673 0.5302 -0.6301\nvn -0.5832 0.5193 -0.6246\nvn -0.5919 0.4775 -0.6493\nvn -0.6073 0.4670 -0.6427\nvn -0.6379 0.3507 -0.6857\nvn -0.6516 0.3425 -0.6768\nvn -0.6301 0.4084 -0.6604\nvn -0.6159 0.4178 -0.6679\nvn -0.6651 0.3352 -0.6673\nvn -0.6445 0.3999 -0.6516\nvn -0.6591 0.3925 -0.6415\nvn -0.6793 0.3285 -0.6562\nvn -0.5502 0.5428 -0.6346\nvn -0.5321 0.5562 -0.6384\nvn -0.5586 0.5021 -0.6602\nvn -0.5761 0.4890 -0.6549\nvn -0.5112 0.5715 -0.6419\nvn -0.5393 0.5161 -0.6654\nvn -0.5917 0.3806 -0.7107\nvn -0.5661 0.4531 -0.6886\nvn -0.6086 0.3696 -0.7021\nvn -0.5847 0.4399 -0.6816\nvn -0.6007 0.4284 -0.6750\nvn -0.6240 0.3595 -0.6938\nvn -0.6434 0.1070 -0.7580\nvn -0.6584 0.1040 -0.7454\nvn -0.6470 0.2013 -0.7355\nvn -0.6319 0.2071 -0.7469\nvn -0.6837 0.0991 -0.7230\nvn -0.6713 0.1015 -0.7342\nvn -0.6731 0.1912 -0.7144\nvn -0.6607 0.1960 -0.7247\nvn -0.6442 0.2822 -0.7109\nvn -0.6576 0.2751 -0.7014\nvn -0.6301 0.2899 -0.7204\nvn -0.6137 0.2988 -0.7308\nvn -0.6955 0.0970 -0.7119\nvn -0.7079 0.0949 -0.6999\nvn -0.6980 0.1828 -0.6924\nvn -0.6856 0.1868 -0.7036\nvn -0.7207 0.0929 -0.6870\nvn -0.7113 0.1789 -0.6797\nvn -0.6970 0.2574 -0.6693\nvn -0.6834 0.2629 -0.6810\nvn -0.6703 0.2688 -0.6917\nvn -0.3957 0.5813 0.7110\nvn -0.2866 0.5969 0.7494\nvn -0.4889 0.5644 0.6652\nvn -0.5093 0.4935 0.7051\nvn -0.4134 0.5090 0.7550\nvn -0.2999 0.5244 0.7969\nvn -0.6358 0.5341 0.5572\nvn -0.5679 0.5486 0.6136\nvn -0.6597 0.4664 0.5893\nvn -0.5908 0.4787 0.6495\nvn -0.6969 0.3212 0.6412\nvn -0.6257 0.3293 0.7072\nvn -0.6098 0.4058 0.6808\nvn -0.6803 0.3951 0.6173\nvn -0.5415 0.3398 0.7690\nvn -0.5271 0.4182 0.7398\nvn -0.3222 0.3643 0.8738\nvn -0.3119 0.4465 0.8387\nvn -0.4286 0.4325 0.7932\nvn -0.4416 0.3515 0.8255\nvn -0.6934 0.5224 0.4962\nvn -0.7431 0.5128 0.4298\nvn -0.7693 0.4485 0.4550\nvn -0.7190 0.4561 0.5245\nvn -0.8194 0.5003 0.2797\nvn -0.7847 0.5059 0.3582\nvn -0.8484 0.4379 0.2975\nvn -0.8125 0.4425 0.3795\nvn -0.8948 0.3039 0.3271\nvn -0.8562 0.3070 0.4154\nvn -0.8363 0.3763 0.3988\nvn -0.8735 0.3725 0.3133\nvn -0.8108 0.3103 0.4963\nvn -0.7921 0.3808 0.4771\nvn -0.7403 0.3871 0.5497\nvn -0.7581 0.3148 0.5711\nvn -0.8914 0.0808 0.4460\nvn -0.9322 0.0801 0.3529\nvn -0.8432 0.0813 0.5314\nvn -0.8367 0.1604 0.5237\nvn -0.8839 0.1591 0.4397\nvn -0.9245 0.1576 0.3471\nvn -0.7250 0.0832 0.6837\nvn -0.7883 0.0821 0.6098\nvn -0.7195 0.1648 0.6747\nvn -0.7820 0.1622 0.6018\nvn -0.7720 0.2399 0.5886\nvn -0.7100 0.2442 0.6605\nvn -0.8257 0.2368 0.5120\nvn -0.9118 0.2324 0.3386\nvn -0.8723 0.2345 0.4291\nvn -0.6520 0.0851 0.7535\nvn -0.5659 0.0876 0.8198\nvn -0.5610 0.1740 0.8093\nvn -0.6466 0.1686 0.7440\nvn -0.3409 0.0947 0.9353\nvn -0.4636 0.0910 0.8814\nvn -0.3369 0.1877 0.9227\nvn -0.4591 0.1803 0.8699\nvn -0.4516 0.2676 0.8511\nvn -0.3307 0.2775 0.9020\nvn -0.5529 0.2580 0.7923\nvn -0.6379 0.2503 0.7283\nvn -0.8452 0.4961 0.1987\nvn -0.8617 0.4933 0.1189\nvn -0.8930 0.4312 0.1289\nvn -0.8755 0.4341 0.2122\nvn -0.8711 0.4900 -0.0321\nvn -0.8700 0.4913 0.0420\nvn -0.9033 0.4281 -0.0293\nvn -0.9018 0.4294 0.0481\nvn -0.9549 0.2959 -0.0239\nvn -0.9530 0.2971 0.0592\nvn -0.9296 0.3646 0.0539\nvn -0.9312 0.3634 -0.0265\nvn -0.9432 0.2987 0.1456\nvn -0.9202 0.3665 0.1378\nvn -0.9019 0.3690 0.2246\nvn -0.9241 0.3011 0.2354\nvn -0.8662 0.4889 -0.1031\nvn -0.8558 0.4881 -0.1717\nvn -0.8874 0.4266 -0.1749\nvn -0.8982 0.4273 -0.1036\nvn -0.8404 0.4870 -0.2379\nvn -0.8711 0.4262 -0.2439\nvn -0.9214 0.2956 -0.2523\nvn -0.8983 0.3624 -0.2486\nvn -0.9385 0.2952 -0.1793\nvn -0.9150 0.3624 -0.1774\nvn -0.9262 0.3627 -0.1035\nvn -0.9498 0.2954 -0.1032\nvn -0.9629 0.0777 -0.2582\nvn -0.9803 0.0774 -0.1815\nvn -0.9715 0.1526 -0.1813\nvn -0.9542 0.1532 -0.2569\nvn -0.9968 0.0774 -0.0183\nvn -0.9918 0.0773 -0.1020\nvn -0.9881 0.1527 -0.0197\nvn -0.9830 0.1525 -0.1021\nvn -0.9689 0.2252 -0.1028\nvn -0.9740 0.2257 -0.0214\nvn -0.9574 0.2253 -0.1804\nvn -0.9402 0.2258 -0.2552\nvn -0.9946 0.0778 0.0689\nvn -0.9839 0.0785 0.1606\nvn -0.9754 0.1546 0.1571\nvn -0.9859 0.1535 0.0670\nvn -0.9636 0.0792 0.2552\nvn -0.9553 0.1561 0.2512\nvn -0.9421 0.2300 0.2442\nvn -0.9616 0.2281 0.1523\nvn -0.9719 0.2266 0.0634\nvn 0.2992 0.5940 0.7468\nvn 0.3529 0.5816 0.7329\nvn 0.2417 0.6041 0.7594\nvn 0.2587 0.5341 0.8049\nvn 0.3203 0.5247 0.7888\nvn 0.3784 0.5109 0.7719\nvn 0.1066 0.6153 0.7810\nvn 0.1781 0.6108 0.7715\nvn 0.1145 0.5448 0.8307\nvn 0.1910 0.5411 0.8190\nvn 0.1262 0.3858 0.9139\nvn 0.2105 0.3835 0.8992\nvn 0.2016 0.4650 0.8620\nvn 0.1212 0.4685 0.8751\nvn 0.2858 0.3777 0.8807\nvn 0.2735 0.4591 0.8453\nvn 0.4195 0.3568 0.8347\nvn 0.4005 0.4366 0.8056\nvn 0.3389 0.4492 0.8267\nvn 0.3546 0.3695 0.8589\nvn 0.0247 0.6166 0.7869\nvn -0.0681 0.6147 0.7858\nvn -0.0707 0.5430 0.8368\nvn 0.0280 0.5457 0.8375\nvn -0.1728 0.6084 0.7746\nvn -0.1806 0.5360 0.8247\nvn -0.1952 0.3747 0.9064\nvn -0.1883 0.4581 0.8687\nvn -0.0764 0.3818 0.9211\nvn -0.0734 0.4653 0.8821\nvn 0.0298 0.4685 0.8829\nvn 0.0309 0.3855 0.9222\nvn -0.2087 0.0984 0.9730\nvn -0.0838 0.1012 0.9913\nvn -0.0818 0.1992 0.9765\nvn -0.2059 0.1942 0.9591\nvn 0.1337 0.1036 0.9856\nvn 0.0311 0.1029 0.9942\nvn 0.1325 0.2029 0.9702\nvn 0.0311 0.2021 0.9789\nvn 0.0313 0.2965 0.9545\nvn 0.1299 0.2974 0.9459\nvn -0.0794 0.2929 0.9528\nvn -0.2011 0.2867 0.9367\nvn 0.2255 0.1031 0.9688\nvn 0.3076 0.1016 0.9461\nvn 0.3031 0.1987 0.9320\nvn 0.2224 0.2020 0.9538\nvn 0.4537 0.0946 0.8861\nvn 0.3827 0.0986 0.9186\nvn 0.4463 0.1857 0.8754\nvn 0.3769 0.1937 0.9058\nvn 0.3673 0.2837 0.8858\nvn 0.4350 0.2737 0.8578\nvn 0.2958 0.2913 0.9098\nvn 0.2175 0.2954 0.9303\nvn -0.5997 0.5836 -0.5475\nvn -0.6184 0.5825 -0.5275\nvn -0.5912 0.6270 -0.5073\nvn -0.5734 0.6267 -0.5277\nvn -0.6607 0.5851 -0.4703\nvn -0.6389 0.5833 -0.5016\nvn -0.6304 0.6320 -0.4508\nvn -0.6102 0.6288 -0.4820\nvn -0.5663 0.7163 -0.4078\nvn -0.5496 0.7114 -0.4380\nvn -0.5803 0.6717 -0.4604\nvn -0.5986 0.6758 -0.4301\nvn -0.5334 0.7079 -0.4630\nvn -0.5626 0.6688 -0.4859\nvn -0.5459 0.6678 -0.5060\nvn -0.5177 0.7058 -0.4835\nvn -0.6837 0.5878 -0.4324\nvn -0.7069 0.5909 -0.3887\nvn -0.6726 0.6401 -0.3714\nvn -0.6512 0.6358 -0.4142\nvn -0.7299 0.5941 -0.3381\nvn -0.6931 0.6443 -0.3233\nvn -0.6157 0.7331 -0.2890\nvn -0.6550 0.6907 -0.3064\nvn -0.5998 0.7275 -0.3332\nvn -0.6364 0.6858 -0.3532\nvn -0.6176 0.6806 -0.3941\nvn -0.5829 0.7217 -0.3732\nvn -0.5014 0.8337 -0.2313\nvn -0.4915 0.8277 -0.2707\nvn -0.5267 0.7985 -0.2917\nvn -0.5382 0.8045 -0.2511\nvn -0.4699 0.8152 -0.3386\nvn -0.4811 0.8214 -0.3063\nvn -0.5013 0.7860 -0.3617\nvn -0.5141 0.7921 -0.3289\nvn -0.5484 0.7590 -0.3511\nvn -0.5335 0.7530 -0.3852\nvn -0.5628 0.7651 -0.3129\nvn -0.5768 0.7710 -0.2701\nvn -0.4582 0.8097 -0.3668\nvn -0.4459 0.8050 -0.3914\nvn -0.4746 0.7761 -0.4154\nvn -0.4880 0.7804 -0.3908\nvn -0.4331 0.8019 -0.4116\nvn -0.4609 0.7730 -0.4360\nvn -0.4892 0.7411 -0.4598\nvn -0.5039 0.7435 -0.4396\nvn -0.5187 0.7478 -0.4145\nvn 0.1916 0.5342 0.8233\nvn 0.0000 0.5384 0.8427\nvn 0.3280 0.5237 0.7862\nvn 0.3557 0.4545 0.8166\nvn 0.2105 0.4637 0.8606\nvn -0.0000 0.4721 0.8815\nvn 0.4446 0.5245 0.7262\nvn 0.4072 0.5206 0.7504\nvn 0.4781 0.4530 0.7525\nvn 0.4406 0.4492 0.7773\nvn 0.5320 0.3049 0.7899\nvn 0.4933 0.3020 0.8157\nvn 0.4687 0.3766 0.7991\nvn 0.5079 0.3795 0.7733\nvn 0.4027 0.3075 0.8622\nvn 0.3818 0.3810 0.8420\nvn -0.0000 0.3249 0.9458\nvn -0.0000 0.3982 0.9173\nvn 0.2263 0.3930 0.8913\nvn 0.2411 0.3168 0.9173\nvn 0.4503 0.5349 0.7149\nvn 0.4336 0.5499 0.7139\nvn 0.4653 0.4782 0.7449\nvn 0.4837 0.4636 0.7424\nvn 0.4000 0.5656 0.7212\nvn 0.4288 0.4953 0.7555\nvn 0.4760 0.3424 0.8101\nvn 0.4543 0.4202 0.7855\nvn 0.5161 0.3269 0.7916\nvn 0.4930 0.4042 0.7705\nvn 0.5124 0.3895 0.7653\nvn 0.5370 0.3139 0.7830\nvn 0.5142 0.0893 0.8530\nvn 0.5573 0.0842 0.8260\nvn 0.5484 0.1668 0.8194\nvn 0.5065 0.1764 0.8440\nvn 0.5748 0.0769 0.8147\nvn 0.5785 0.0798 0.8118\nvn 0.5655 0.1534 0.8103\nvn 0.5704 0.1587 0.8059\nvn 0.5559 0.2368 0.7968\nvn 0.5520 0.2293 0.8017\nvn 0.5351 0.2480 0.8076\nvn 0.4933 0.2606 0.8299\nvn 0.5342 0.0762 0.8419\nvn 0.4411 0.0777 0.8941\nvn 0.4327 0.1552 0.8881\nvn 0.5264 0.1517 0.8366\nvn 0.0000 0.0832 0.9965\nvn 0.2661 0.0815 0.9605\nvn 0.0000 0.1662 0.9861\nvn 0.2612 0.1612 0.9517\nvn 0.2521 0.2409 0.9372\nvn 0.0000 0.2453 0.9694\nvn 0.4206 0.2312 0.8773\nvn 0.5118 0.2274 0.8284\nvn -0.0660 0.7858 -0.6149\nvn 0.0000 0.7887 -0.6148\nvn -0.1342 0.7787 -0.6129\nvn -0.1218 0.8067 -0.5783\nvn -0.0593 0.8135 -0.5786\nvn -0.0000 0.8152 -0.5791\nvn -0.2619 0.7506 -0.6066\nvn -0.2012 0.7662 -0.6103\nvn -0.2397 0.7821 -0.5751\nvn -0.1824 0.7964 -0.5767\nvn -0.1991 0.8320 -0.5177\nvn -0.1501 0.8429 -0.5167\nvn -0.1660 0.8212 -0.5459\nvn -0.2181 0.8092 -0.5455\nvn -0.0996 0.8505 -0.5164\nvn -0.1097 0.8307 -0.5458\nvn -0.0000 0.8567 -0.5158\nvn -0.0000 0.8380 -0.5457\nvn -0.0537 0.8359 -0.5462\nvn -0.0483 0.8555 -0.5156\nvn -0.3159 0.7327 -0.6028\nvn -0.3612 0.7139 -0.5999\nvn -0.3341 0.7490 -0.5721\nvn -0.2900 0.7661 -0.5735\nvn -0.3990 0.6957 -0.5974\nvn -0.3709 0.7318 -0.5718\nvn -0.3177 0.7917 -0.5218\nvn -0.3439 0.7638 -0.5463\nvn -0.2834 0.8058 -0.5200\nvn -0.3078 0.7794 -0.5458\nvn -0.2663 0.7947 -0.5454\nvn -0.2433 0.8196 -0.5187\nvn -0.2476 0.8573 -0.4514\nvn -0.2172 0.8671 -0.4483\nvn -0.2382 0.8492 -0.4714\nvn -0.2695 0.8381 -0.4744\nvn -0.1484 0.8846 -0.4421\nvn -0.1845 0.8762 -0.4451\nvn -0.1643 0.8692 -0.4663\nvn -0.2024 0.8599 -0.4686\nvn -0.2226 0.8410 -0.4932\nvn -0.1805 0.8521 -0.4912\nvn -0.2597 0.8289 -0.4954\nvn -0.2932 0.8164 -0.4976\nvn -0.1114 0.8911 -0.4399\nvn -0.0729 0.8961 -0.4378\nvn -0.0812 0.8828 -0.4627\nvn -0.1229 0.8773 -0.4640\nvn 0.0000 0.8998 -0.4363\nvn -0.0356 0.8988 -0.4370\nvn -0.0000 0.8872 -0.4613\nvn -0.0394 0.8863 -0.4614\nvn -0.0438 0.8718 -0.4880\nvn -0.0000 0.8732 -0.4873\nvn -0.0896 0.8680 -0.4884\nvn -0.1364 0.8611 -0.4899\nvn 0.3937 0.8258 -0.4038\nvn 0.4199 0.8003 -0.4280\nvn 0.4059 0.8009 -0.4402\nvn 0.3805 0.8256 -0.4167\nvn 0.4469 0.7721 -0.4519\nvn 0.4325 0.7730 -0.4641\nvn 0.4170 0.7764 -0.4726\nvn 0.3910 0.8032 -0.4494\nvn 0.3660 0.8275 -0.4258\nvn 0.5024 0.7062 -0.4990\nvn 0.4870 0.7086 -0.5106\nvn 0.4595 0.7425 -0.4874\nvn 0.4746 0.7405 -0.4759\nvn 0.4708 0.7138 -0.5185\nvn 0.4438 0.7464 -0.4959\nvn 0.4356 0.7300 -0.5266\nvn 0.4090 0.7606 -0.5042\nvn 0.4269 0.7528 -0.5011\nvn 0.4538 0.7208 -0.5239\nvn 0.3828 0.7886 -0.4813\nvn 0.4005 0.7815 -0.4784\nvn 0.3335 0.8360 -0.4357\nvn 0.3504 0.8309 -0.4323\nvn 0.3749 0.8077 -0.4551\nvn 0.3576 0.8135 -0.4587\nvn 0.5300 0.6686 -0.5216\nvn 0.5142 0.6723 -0.5325\nvn 0.5569 0.6288 -0.5427\nvn 0.5409 0.6330 -0.5538\nvn 0.5246 0.6399 -0.5615\nvn 0.4979 0.6781 -0.5406\nvn 0.6072 0.5424 -0.5807\nvn 0.5911 0.5482 -0.5918\nvn 0.5666 0.5917 -0.5734\nvn 0.5828 0.5864 -0.5627\nvn 0.5751 0.5562 -0.6000\nvn 0.5505 0.5990 -0.5815\nvn 0.5420 0.5772 -0.6108\nvn 0.5164 0.6196 -0.5911\nvn 0.5337 0.6086 -0.5871\nvn 0.5590 0.5657 -0.6063\nvn 0.4897 0.6596 -0.5702\nvn 0.5077 0.6486 -0.5670\nvn 0.4808 0.6863 -0.5457\nvn 0.4628 0.6961 -0.5489\nvn 0.4583 0.6362 -0.6207\nvn 0.4299 0.6779 -0.5963\nvn 0.4553 0.6619 -0.5954\nvn 0.4835 0.6192 -0.6187\nvn 0.4016 0.7155 -0.5716\nvn 0.4275 0.6998 -0.5723\nvn 0.4501 0.6854 -0.5724\nvn 0.4778 0.6464 -0.5948\nvn 0.5048 0.6041 -0.6166\nvn 0.3474 0.7780 -0.5236\nvn 0.3728 0.7646 -0.5258\nvn 0.3998 0.7342 -0.5488\nvn 0.3740 0.7484 -0.5477\nvn 0.3955 0.7522 -0.5271\nvn 0.4227 0.7203 -0.5500\nvn 0.4434 0.7078 -0.5499\nvn 0.4164 0.7403 -0.5277\nvn 0.4708 0.6716 -0.5721\nvn 0.5244 0.5898 -0.6142\nvn 0.4977 0.6326 -0.5934\nvn 0.3217 0.8039 -0.5003\nvn 0.3467 0.7920 -0.5025\nvn 0.2974 0.8270 -0.4771\nvn 0.3216 0.8163 -0.4799\nvn 0.3436 0.8063 -0.4816\nvn 0.3691 0.7805 -0.5045\nvn 0.2523 0.8657 -0.4324\nvn 0.2751 0.8572 -0.4353\nvn 0.2978 0.8380 -0.4572\nvn 0.2740 0.8474 -0.4547\nvn 0.2960 0.8494 -0.4368\nvn 0.3192 0.8290 -0.4593\nvn 0.3390 0.8209 -0.4596\nvn 0.3154 0.8421 -0.4374\nvn 0.3639 0.7968 -0.4825\nvn 0.3897 0.7702 -0.5049\nvn 0.4856 0.8685 0.0995\nvn 0.4645 0.8786 0.1113\nvn 0.4890 0.8608 0.1408\nvn 0.5092 0.8534 0.1118\nvn 0.4349 0.8910 0.1300\nvn 0.4576 0.8736 0.1656\nvn 0.4903 0.8476 0.2028\nvn 0.5228 0.8354 0.1693\nvn 0.5467 0.8269 0.1318\nvn 0.3647 0.9164 0.1650\nvn 0.3835 0.8993 0.2102\nvn 0.4234 0.8860 0.1889\nvn 0.4013 0.9041 0.1470\nvn 0.4093 0.8752 0.2578\nvn 0.4518 0.8615 0.2318\nvn 0.4736 0.8069 0.3531\nvn 0.5229 0.7910 0.3175\nvn 0.4861 0.8295 0.2751\nvn 0.4396 0.8444 0.3061\nvn 0.5660 0.7770 0.2754\nvn 0.5267 0.8157 0.2392\nvn 0.6292 0.7572 0.1754\nvn 0.5862 0.7957 0.1525\nvn 0.5605 0.8041 0.1982\nvn 0.6016 0.7656 0.2279\nvn 0.3247 0.9283 0.1810\nvn 0.3409 0.9116 0.2295\nvn 0.2841 0.9385 0.1961\nvn 0.2954 0.9231 0.2461\nvn 0.3125 0.9015 0.2995\nvn 0.3620 0.8890 0.2802\nvn 0.1916 0.9561 0.2215\nvn 0.1926 0.9421 0.2745\nvn 0.2470 0.9331 0.2613\nvn 0.2401 0.9479 0.2092\nvn 0.1972 0.9226 0.3315\nvn 0.2576 0.9130 0.3163\nvn 0.2153 0.8650 0.4532\nvn 0.2903 0.8532 0.4334\nvn 0.2728 0.8863 0.3742\nvn 0.2045 0.8973 0.3912\nvn 0.3580 0.8388 0.4103\nvn 0.3331 0.8737 0.3545\nvn 0.3889 0.8593 0.3321\nvn 0.4183 0.8232 0.3839\nvn 0.2723 0.6640 0.6964\nvn 0.3761 0.6484 0.6619\nvn 0.3546 0.7100 0.6084\nvn 0.2570 0.7249 0.6391\nvn 0.4652 0.6314 0.6205\nvn 0.4393 0.6928 0.5718\nvn 0.4120 0.7483 0.5199\nvn 0.3324 0.7649 0.5518\nvn 0.2422 0.7789 0.5785\nvn 0.6077 0.5988 0.5216\nvn 0.5769 0.6587 0.4829\nvn 0.5128 0.6755 0.5298\nvn 0.5421 0.6142 0.5735\nvn 0.5433 0.7139 0.4419\nvn 0.4819 0.7308 0.4834\nvn 0.4501 0.7802 0.4344\nvn 0.5086 0.7631 0.3987\nvn 0.3842 0.7971 0.4658\nvn 0.2276 0.8258 0.5160\nvn 0.3110 0.8126 0.4930\nvn 0.6647 0.5851 0.4645\nvn 0.6319 0.6443 0.4309\nvn 0.7126 0.5745 0.4026\nvn 0.6794 0.6318 0.3732\nvn 0.6433 0.6846 0.3427\nvn 0.5973 0.6979 0.3952\nvn 0.7864 0.5599 0.2607\nvn 0.7507 0.6153 0.2404\nvn 0.7186 0.6225 0.3100\nvn 0.7535 0.5660 0.3345\nvn 0.7127 0.6662 0.2199\nvn 0.6821 0.6738 0.2841\nvn 0.6429 0.7215 0.2571\nvn 0.6725 0.7131 0.1981\nvn 0.6057 0.7327 0.3104\nvn 0.5605 0.7471 0.3574\nvn 0.2315 0.8818 -0.4109\nvn 0.2538 0.8745 -0.4133\nvn 0.2122 0.8964 -0.3892\nvn 0.2336 0.8898 -0.3919\nvn 0.2535 0.8838 -0.3933\nvn 0.2742 0.8675 -0.4151\nvn 0.1770 0.9210 -0.3470\nvn 0.1968 0.9161 -0.3493\nvn 0.2147 0.9037 -0.3704\nvn 0.1938 0.9094 -0.3681\nvn 0.2156 0.9114 -0.3506\nvn 0.2339 0.8982 -0.3721\nvn 0.2506 0.9027 -0.3498\nvn 0.2698 0.8886 -0.3710\nvn 0.2522 0.8933 -0.3721\nvn 0.2335 0.9068 -0.3511\nvn 0.2897 0.8732 -0.3920\nvn 0.2722 0.8780 -0.3937\nvn 0.2931 0.8613 -0.4151\nvn 0.3110 0.8557 -0.4137\nvn 0.1613 0.9314 -0.3264\nvn 0.1807 0.9272 -0.3282\nvn 0.1478 0.9405 -0.3059\nvn 0.1659 0.9370 -0.3075\nvn 0.1833 0.9335 -0.3083\nvn 0.1985 0.9230 -0.3295\nvn 0.1260 0.9556 -0.2663\nvn 0.1426 0.9532 -0.2667\nvn 0.1534 0.9456 -0.2869\nvn 0.1356 0.9486 -0.2859\nvn 0.1588 0.9506 -0.2667\nvn 0.1697 0.9427 -0.2874\nvn 0.1910 0.9450 -0.2655\nvn 0.2024 0.9365 -0.2863\nvn 0.1861 0.9396 -0.2872\nvn 0.1744 0.9480 -0.2662\nvn 0.2165 0.9266 -0.3074\nvn 0.1998 0.9300 -0.3085\nvn 0.2159 0.9191 -0.3297\nvn 0.2328 0.9153 -0.3288\nvn 0.2476 0.9333 -0.2600\nvn 0.2589 0.9274 -0.2699\nvn 0.2478 0.9282 -0.2775\nvn 0.2377 0.9356 -0.2611\nvn 0.2744 0.9182 -0.2856\nvn 0.2632 0.9185 -0.2950\nvn 0.2482 0.9207 -0.3012\nvn 0.2335 0.9307 -0.2815\nvn 0.2225 0.9388 -0.2629\nvn 0.3096 0.8952 -0.3207\nvn 0.2976 0.8949 -0.3326\nvn 0.2792 0.9077 -0.3133\nvn 0.2917 0.9075 -0.3022\nvn 0.2830 0.8964 -0.3412\nvn 0.2652 0.9092 -0.3210\nvn 0.2492 0.9119 -0.3259\nvn 0.2675 0.8989 -0.3469\nvn 0.2328 0.9234 -0.3051\nvn 0.2072 0.9419 -0.2642\nvn 0.2185 0.9335 -0.2844\nvn 0.3293 0.8808 -0.3402\nvn 0.3163 0.8807 -0.3525\nvn 0.3486 0.8654 -0.3600\nvn 0.3362 0.8649 -0.3728\nvn 0.3217 0.8664 -0.3820\nvn 0.3023 0.8819 -0.3617\nvn 0.3569 0.8471 -0.3938\nvn 0.3700 0.8473 -0.3811\nvn 0.3430 0.8483 -0.4034\nvn 0.3274 0.8514 -0.4097\nvn 0.3065 0.8690 -0.3885\nvn 0.2863 0.8849 -0.3675\nvn 0.0808 0.9960 -0.0372\nvn 0.0734 0.9973 0.0009\nvn 0.0845 0.9964 0.0016\nvn 0.0932 0.9950 -0.0353\nvn 0.0637 0.9973 0.0376\nvn 0.0747 0.9965 0.0375\nvn 0.0878 0.9955 0.0360\nvn 0.0986 0.9951 0.0017\nvn 0.1069 0.9937 -0.0344\nvn 0.0374 0.9932 0.1105\nvn 0.0476 0.9930 0.1079\nvn 0.0621 0.9954 0.0724\nvn 0.0523 0.9959 0.0742\nvn 0.0607 0.9927 0.1041\nvn 0.0757 0.9947 0.0701\nvn 0.0977 0.9907 0.0947\nvn 0.1117 0.9918 0.0627\nvn 0.0918 0.9936 0.0666\nvn 0.0779 0.9919 0.1000\nvn 0.1231 0.9919 0.0306\nvn 0.1044 0.9940 0.0340\nvn 0.1415 0.9893 -0.0355\nvn 0.1234 0.9918 -0.0343\nvn 0.1144 0.9934 0.0005\nvn 0.1335 0.9910 -0.0015\nvn 0.0200 0.9887 0.1484\nvn 0.0297 0.9891 0.1441\nvn -0.0016 0.9822 0.1878\nvn 0.0097 0.9831 0.1827\nvn 0.0242 0.9839 0.1770\nvn 0.0440 0.9892 0.1396\nvn -0.0552 0.9593 0.2769\nvn -0.0402 0.9619 0.2705\nvn -0.0141 0.9744 0.2242\nvn -0.0260 0.9728 0.2303\nvn -0.0216 0.9641 0.2646\nvn 0.0028 0.9759 0.2183\nvn 0.0296 0.9670 0.2532\nvn 0.0484 0.9773 0.2061\nvn 0.0232 0.9769 0.2122\nvn 0.0019 0.9659 0.2589\nvn 0.0659 0.9841 0.1652\nvn 0.0434 0.9842 0.1714\nvn 0.0612 0.9891 0.1343\nvn 0.0829 0.9882 0.1287\nvn 0.1942 0.9654 0.1741\nvn 0.1502 0.9714 0.1839\nvn 0.1430 0.9622 0.2316\nvn 0.1991 0.9708 0.1339\nvn 0.1596 0.9768 0.1431\nvn 0.1238 0.9807 0.1513\nvn 0.1117 0.9750 0.1922\nvn 0.0999 0.9656 0.2400\nvn 0.2139 0.9746 0.0662\nvn 0.1799 0.9808 0.0750\nvn 0.1692 0.9797 0.1073\nvn 0.2065 0.9735 0.0985\nvn 0.1486 0.9855 0.0824\nvn 0.1368 0.9839 0.1153\nvn 0.1075 0.9867 0.1222\nvn 0.1218 0.9885 0.0891\nvn 0.0931 0.9829 0.1586\nvn 0.0622 0.9670 0.2470\nvn 0.0775 0.9768 0.1995\nvn 0.2224 0.9743 0.0362\nvn 0.1892 0.9809 0.0442\nvn 0.2294 0.9733 0.0063\nvn 0.1988 0.9799 0.0147\nvn 0.1702 0.9852 0.0210\nvn 0.1604 0.9857 0.0516\nvn 0.2412 0.9689 -0.0555\nvn 0.2129 0.9759 -0.0472\nvn 0.2061 0.9784 -0.0159\nvn 0.2366 0.9713 -0.0233\nvn 0.1861 0.9816 -0.0418\nvn 0.1794 0.9837 -0.0094\nvn 0.1546 0.9880 -0.0050\nvn 0.1629 0.9859 -0.0377\nvn 0.1455 0.9890 0.0266\nvn 0.1340 0.9893 0.0574\nvn 0.4733 0.8641 -0.1714\nvn 0.4778 0.8686 -0.1316\nvn 0.5165 0.8436 -0.1468\nvn 0.5099 0.8391 -0.1892\nvn 0.4804 0.8719 -0.0944\nvn 0.5201 0.8473 -0.1077\nvn 0.5631 0.8177 -0.1193\nvn 0.5570 0.8146 -0.1619\nvn 0.5490 0.8099 -0.2064\nvn 0.4827 0.8755 -0.0235\nvn 0.5245 0.8508 -0.0318\nvn 0.5232 0.8494 -0.0695\nvn 0.4812 0.8746 -0.0594\nvn 0.5703 0.8206 -0.0367\nvn 0.5671 0.8199 -0.0787\nvn 0.6638 0.7468 -0.0405\nvn 0.6590 0.7466 -0.0909\nvn 0.6132 0.7853 -0.0852\nvn 0.6169 0.7860 -0.0401\nvn 0.6522 0.7450 -0.1397\nvn 0.6070 0.7839 -0.1305\nvn 0.6308 0.7380 -0.2396\nvn 0.5893 0.7763 -0.2236\nvn 0.5997 0.7807 -0.1758\nvn 0.6427 0.7424 -0.1893\nvn 0.4827 0.8757 0.0108\nvn 0.5254 0.8509 0.0067\nvn 0.4842 0.8738 0.0447\nvn 0.5239 0.8507 0.0428\nvn 0.5687 0.8212 0.0479\nvn 0.5704 0.8213 0.0049\nvn 0.5208 0.8499 0.0801\nvn 0.4837 0.8719 0.0762\nvn 0.5616 0.8225 0.0906\nvn 0.6488 0.7514 0.1201\nvn 0.6040 0.7901 0.1046\nvn 0.6602 0.7483 0.0653\nvn 0.6140 0.7874 0.0552\nvn 0.6178 0.7863 0.0073\nvn 0.6646 0.7471 0.0110\nvn 0.8111 0.5553 0.1837\nvn 0.7738 0.6106 0.1685\nvn 0.8265 0.5524 0.1086\nvn 0.7882 0.6076 0.0976\nvn 0.7479 0.6582 0.0868\nvn 0.7347 0.6610 0.1526\nvn 0.8351 0.5490 -0.0345\nvn 0.7956 0.6047 -0.0369\nvn 0.7951 0.6058 0.0292\nvn 0.8341 0.5505 0.0355\nvn 0.7536 0.6562 -0.0387\nvn 0.7536 0.6569 0.0226\nvn 0.7102 0.7038 0.0167\nvn 0.7094 0.7037 -0.0403\nvn 0.7053 0.7048 0.0756\nvn 0.6932 0.7077 0.1368\nvn 0.8303 0.5479 -0.1022\nvn 0.7910 0.6035 -0.1003\nvn 0.8206 0.5465 -0.1672\nvn 0.7818 0.6020 -0.1622\nvn 0.7404 0.6539 -0.1556\nvn 0.7488 0.6555 -0.0981\nvn 0.7870 0.5430 -0.2929\nvn 0.7509 0.5972 -0.2820\nvn 0.7686 0.5999 -0.2222\nvn 0.8060 0.5450 -0.2309\nvn 0.7124 0.6481 -0.2690\nvn 0.7282 0.6516 -0.2127\nvn 0.6861 0.6991 -0.2013\nvn 0.6719 0.6953 -0.2552\nvn 0.6967 0.7019 -0.1484\nvn 0.7047 0.7031 -0.0947\nvn 0.1383 0.9483 0.2855\nvn 0.0899 0.9516 0.2938\nvn 0.0818 0.9326 0.3516\nvn 0.1360 0.9294 0.3431\nvn 0.0109 0.9521 0.3057\nvn 0.0476 0.9526 0.3004\nvn -0.0073 0.9322 0.3619\nvn 0.0341 0.9333 0.3574\nvn -0.0416 0.8748 0.4827\nvn 0.0106 0.8769 0.4806\nvn 0.0219 0.9082 0.4179\nvn -0.0249 0.9067 0.4210\nvn 0.0709 0.8764 0.4763\nvn 0.0753 0.9078 0.4125\nvn 0.1365 0.9044 0.4043\nvn 0.1388 0.8730 0.4675\nvn -0.0205 0.9503 0.3106\nvn -0.0470 0.9478 0.3154\nvn -0.0734 0.9264 0.3694\nvn -0.0428 0.9298 0.3655\nvn -0.0865 0.9411 0.3269\nvn -0.0692 0.9446 0.3209\nvn -0.1207 0.9175 0.3790\nvn -0.0989 0.9223 0.3735\nvn -0.1913 0.8525 0.4864\nvn -0.1608 0.8601 0.4841\nvn -0.1300 0.8942 0.4284\nvn -0.1553 0.8883 0.4321\nvn -0.1265 0.8661 0.4836\nvn -0.0999 0.8995 0.4254\nvn -0.0652 0.9036 0.4234\nvn -0.0870 0.8712 0.4831\nvn -0.3250 0.6464 0.6903\nvn -0.2755 0.6589 0.7000\nvn -0.2496 0.7179 0.6499\nvn -0.2941 0.7073 0.6429\nvn -0.2224 0.6679 0.7103\nvn -0.2010 0.7269 0.6567\nvn -0.1775 0.7797 0.6005\nvn -0.2213 0.7719 0.5960\nvn -0.2614 0.7617 0.5929\nvn -0.0967 0.6795 0.7273\nvn -0.0853 0.7382 0.6692\nvn -0.1467 0.7334 0.6638\nvn -0.1636 0.6751 0.7194\nvn -0.0720 0.7905 0.6082\nvn -0.1283 0.7861 0.6046\nvn -0.1081 0.8320 0.5442\nvn -0.0575 0.8363 0.5453\nvn -0.1525 0.8264 0.5420\nvn -0.2265 0.8107 0.5399\nvn -0.1917 0.8191 0.5407\nvn -0.0206 0.6817 0.7314\nvn -0.0146 0.7404 0.6720\nvn 0.0667 0.6803 0.7299\nvn 0.0657 0.7398 0.6696\nvn 0.0663 0.7925 0.6063\nvn -0.0077 0.7930 0.6091\nvn 0.1570 0.7349 0.6597\nvn 0.1646 0.6749 0.7194\nvn 0.1495 0.7884 0.5967\nvn 0.1437 0.8343 0.5323\nvn 0.0676 0.8382 0.5411\nvn 0.0010 0.8384 0.5450\nvn 0.2379 0.9575 0.1631\nvn 0.2779 0.9487 0.1507\nvn 0.2764 0.9545 0.1119\nvn 0.2397 0.9630 0.1233\nvn 0.3524 0.9277 0.1233\nvn 0.3154 0.9389 0.1378\nvn 0.3462 0.9341 0.0869\nvn 0.3115 0.9450 0.0994\nvn 0.3449 0.9384 0.0219\nvn 0.3140 0.9488 0.0341\nvn 0.3113 0.9480 0.0655\nvn 0.3441 0.9374 0.0531\nvn 0.2821 0.9583 0.0457\nvn 0.2785 0.9573 0.0773\nvn 0.2435 0.9659 0.0883\nvn 0.2495 0.9667 0.0566\nvn 0.3879 0.9152 0.1094\nvn 0.4205 0.9023 0.0948\nvn 0.4137 0.9083 0.0620\nvn 0.3801 0.9220 0.0737\nvn 0.4539 0.8871 0.0836\nvn 0.4472 0.8930 0.0510\nvn 0.4438 0.8960 -0.0138\nvn 0.4456 0.8950 0.0194\nvn 0.4093 0.9124 -0.0023\nvn 0.4101 0.9116 0.0295\nvn 0.3770 0.9253 0.0412\nvn 0.3763 0.9264 0.0096\nvn 0.4396 0.8850 -0.1537\nvn 0.4429 0.8891 -0.1156\nvn 0.4091 0.9022 -0.1367\nvn 0.4110 0.9061 -0.1001\nvn 0.4107 0.9094 -0.0665\nvn 0.4436 0.8926 -0.0806\nvn 0.3534 0.9296 -0.1049\nvn 0.3532 0.9329 -0.0704\nvn 0.3813 0.9205 -0.0851\nvn 0.3810 0.9167 -0.1202\nvn 0.3504 0.9358 -0.0390\nvn 0.3800 0.9235 -0.0524\nvn 0.3778 0.9256 -0.0214\nvn 0.3476 0.9376 -0.0084\nvn 0.4094 0.9117 -0.0344\nvn 0.4439 0.8949 -0.0470\nvn 0.3270 0.9407 -0.0901\nvn 0.3247 0.9441 -0.0571\nvn 0.2989 0.9511 -0.0772\nvn 0.2966 0.9540 -0.0443\nvn 0.2918 0.9564 -0.0141\nvn 0.3218 0.9465 -0.0258\nvn 0.2666 0.9632 -0.0335\nvn 0.2712 0.9603 -0.0650\nvn 0.2619 0.9651 -0.0029\nvn 0.2552 0.9665 0.0263\nvn 0.2874 0.9577 0.0158\nvn 0.3174 0.9483 0.0039\nvn 0.7351 0.0907 -0.6719\nvn 0.7518 0.0886 -0.6534\nvn 0.7257 0.1749 -0.6654\nvn 0.7429 0.1712 -0.6472\nvn 0.7636 0.1677 -0.6236\nvn 0.7726 0.0866 -0.6290\nvn 0.6945 0.3223 -0.6433\nvn 0.7121 0.3169 -0.6265\nvn 0.7291 0.2473 -0.6381\nvn 0.7119 0.2521 -0.6555\nvn 0.7330 0.3120 -0.6044\nvn 0.7501 0.2429 -0.6151\nvn 0.7842 0.3042 -0.5408\nvn 0.8015 0.2352 -0.5497\nvn 0.7744 0.2388 -0.5859\nvn 0.7573 0.3078 -0.5760\nvn 0.8149 0.1614 -0.5566\nvn 0.7879 0.1644 -0.5935\nvn 0.7966 0.0847 -0.5986\nvn 0.8238 0.0829 -0.5608\nvn 0.6747 0.3858 -0.6293\nvn 0.6924 0.3802 -0.6132\nvn 0.6531 0.4433 -0.6140\nvn 0.6708 0.4378 -0.5985\nvn 0.6916 0.4337 -0.5776\nvn 0.7133 0.3755 -0.5918\nvn 0.6245 0.5383 -0.5659\nvn 0.6481 0.4904 -0.5826\nvn 0.6305 0.4951 -0.5978\nvn 0.6441 0.5362 -0.5455\nvn 0.6683 0.4870 -0.5623\nvn 0.6893 0.5359 -0.4875\nvn 0.7158 0.4839 -0.5034\nvn 0.6911 0.4850 -0.5359\nvn 0.6657 0.5355 -0.5198\nvn 0.7409 0.4282 -0.5174\nvn 0.7150 0.4305 -0.5509\nvn 0.7373 0.3716 -0.5642\nvn 0.7638 0.3684 -0.5300\nvn 0.8199 0.4859 -0.3027\nvn 0.7956 0.4848 -0.3633\nvn 0.7640 0.5410 -0.3517\nvn 0.8499 0.4256 -0.3108\nvn 0.8242 0.4256 -0.3735\nvn 0.7966 0.4259 -0.4289\nvn 0.7691 0.4841 -0.4173\nvn 0.7393 0.5389 -0.4037\nvn 0.8990 0.2956 -0.3231\nvn 0.8720 0.2969 -0.3891\nvn 0.8499 0.3629 -0.3820\nvn 0.8763 0.3622 -0.3176\nvn 0.8429 0.2987 -0.4476\nvn 0.8213 0.3642 -0.4392\nvn 0.7922 0.3660 -0.4884\nvn 0.8131 0.3012 -0.4982\nvn 0.7683 0.4268 -0.4770\nvn 0.7139 0.5372 -0.4492\nvn 0.7423 0.4837 -0.4638\nvn 0.9175 0.2259 -0.3273\nvn 0.8902 0.2274 -0.3947\nvn 0.9313 0.1532 -0.3304\nvn 0.9040 0.1546 -0.3986\nvn 0.8743 0.1564 -0.4594\nvn 0.8608 0.2294 -0.4544\nvn 0.9126 0.0786 -0.4012\nvn 0.9401 0.0778 -0.3319\nvn 0.8831 0.0798 -0.4623\nvn 0.8528 0.0812 -0.5158\nvn 0.8442 0.1587 -0.5119\nvn 0.8307 0.2320 -0.5061\nvn -0.0657 0.9566 0.2838\nvn -0.1006 0.9372 0.3341\nvn -0.0738 0.9539 0.2911\nvn -0.1094 0.9332 0.3423\nvn -0.1491 0.9068 0.3942\nvn -0.1372 0.9124 0.3856\nvn -0.0753 0.9488 0.3067\nvn -0.1097 0.9259 0.3616\nvn -0.1134 0.9293 0.3515\nvn -0.0768 0.9512 0.2989\nvn -0.1483 0.8971 0.4161\nvn -0.1531 0.9017 0.4045\nvn -0.2334 0.8204 0.5219\nvn -0.2401 0.8273 0.5078\nvn -0.1960 0.8677 0.4569\nvn -0.1898 0.8620 0.4701\nvn -0.2335 0.8355 0.4974\nvn -0.1903 0.8745 0.4461\nvn -0.1765 0.8814 0.4381\nvn -0.2160 0.8445 0.4901\nvn -0.0670 0.9469 0.3146\nvn -0.0976 0.9233 0.3714\nvn -0.0518 0.9457 0.3208\nvn -0.0754 0.9215 0.3809\nvn -0.1018 0.8922 0.4399\nvn -0.1320 0.8937 0.4288\nvn -0.0424 0.9212 0.3867\nvn -0.0293 0.9449 0.3260\nvn -0.0578 0.8914 0.4496\nvn -0.0930 0.8153 0.5715\nvn -0.0742 0.8570 0.5100\nvn -0.1626 0.8150 0.5561\nvn -0.1316 0.8562 0.4996\nvn -0.1692 0.8583 0.4845\nvn -0.2092 0.8159 0.5390\nvn -0.1730 0.5980 0.7826\nvn -0.1521 0.6609 0.7349\nvn -0.2961 0.5917 0.7498\nvn -0.2642 0.6541 0.7088\nvn -0.2295 0.7138 0.6617\nvn -0.1325 0.7165 0.6848\nvn -0.4065 0.5932 0.6949\nvn -0.3658 0.6580 0.6582\nvn -0.3320 0.6534 0.6803\nvn -0.3715 0.5885 0.7181\nvn -0.3224 0.7180 0.6169\nvn -0.2918 0.7130 0.6376\nvn -0.2499 0.7678 0.5900\nvn -0.2781 0.7723 0.5712\nvn -0.1964 0.7665 0.6114\nvn -0.1117 0.7698 0.6285\nvn -0.4131 0.6036 0.6819\nvn -0.3727 0.6676 0.6445\nvn -0.3984 0.6171 0.6786\nvn -0.3598 0.6807 0.6381\nvn -0.3192 0.7381 0.5943\nvn -0.3297 0.7270 0.6023\nvn -0.3327 0.6939 0.6386\nvn -0.3675 0.6326 0.6817\nvn -0.2950 0.7506 0.5912\nvn -0.2563 0.8005 0.5419\nvn -0.2764 0.7903 0.5468\nvn -0.2853 0.7802 0.5567\nvn 0.2265 0.8743 -0.4293\nvn 0.2072 0.8894 -0.4075\nvn 0.1984 0.8828 -0.4258\nvn 0.1799 0.8969 -0.4039\nvn 0.1634 0.9094 -0.3825\nvn 0.1885 0.9030 -0.3861\nvn 0.1345 0.8978 -0.4193\nvn 0.1208 0.9099 -0.3969\nvn 0.1514 0.9037 -0.4004\nvn 0.1670 0.8909 -0.4224\nvn 0.1088 0.9204 -0.3757\nvn 0.1362 0.9154 -0.3788\nvn 0.0871 0.9382 -0.3350\nvn 0.1099 0.9348 -0.3378\nvn 0.1228 0.9256 -0.3581\nvn 0.0971 0.9299 -0.3548\nvn 0.1332 0.9306 -0.3410\nvn 0.1473 0.9207 -0.3615\nvn 0.1715 0.9151 -0.3649\nvn 0.1554 0.9260 -0.3442\nvn 0.1000 0.9037 -0.4164\nvn 0.0901 0.9145 -0.3943\nvn 0.0658 0.9076 -0.4147\nvn 0.0588 0.9181 -0.3920\nvn 0.0528 0.9272 -0.3708\nvn 0.0804 0.9245 -0.3727\nvn 0.0287 0.9200 -0.3909\nvn 0.0319 0.9101 -0.4131\nvn 0.0256 0.9290 -0.3693\nvn 0.0203 0.9439 -0.3295\nvn 0.0229 0.9368 -0.3491\nvn 0.0419 0.9428 -0.3308\nvn 0.0469 0.9355 -0.3501\nvn 0.0720 0.9331 -0.3523\nvn 0.0640 0.9410 -0.3324\nvn 0.0132 0.9653 -0.2609\nvn 0.0146 0.9608 -0.2769\nvn 0.0274 0.9649 -0.2613\nvn 0.0299 0.9603 -0.2774\nvn 0.0334 0.9551 -0.2944\nvn 0.0161 0.9558 -0.2935\nvn 0.0581 0.9632 -0.2626\nvn 0.0632 0.9581 -0.2795\nvn 0.0464 0.9594 -0.2784\nvn 0.0422 0.9642 -0.2618\nvn 0.0701 0.9522 -0.2973\nvn 0.0512 0.9540 -0.2955\nvn 0.0573 0.9478 -0.3137\nvn 0.0777 0.9457 -0.3157\nvn 0.0372 0.9494 -0.3120\nvn 0.0181 0.9502 -0.3112\nvn 0.0742 0.9618 -0.2635\nvn 0.0811 0.9562 -0.2811\nvn 0.0913 0.9600 -0.2645\nvn 0.0989 0.9541 -0.2827\nvn 0.1089 0.9472 -0.3017\nvn 0.0890 0.9500 -0.2993\nvn 0.1175 0.9515 -0.2845\nvn 0.1083 0.9580 -0.2655\nvn 0.1282 0.9440 -0.3039\nvn 0.1412 0.9355 -0.3238\nvn 0.1200 0.9394 -0.3210\nvn 0.0991 0.9428 -0.3183\nvn 0.0700 0.9968 -0.0397\nvn 0.0631 0.9980 -0.0009\nvn 0.0592 0.9973 -0.0428\nvn 0.0538 0.9985 -0.0033\nvn 0.0460 0.9983 0.0355\nvn 0.0549 0.9978 0.0371\nvn 0.0389 0.9980 -0.0494\nvn 0.0354 0.9993 -0.0092\nvn 0.0442 0.9990 -0.0061\nvn 0.0491 0.9977 -0.0462\nvn 0.0299 0.9991 0.0314\nvn 0.0381 0.9987 0.0336\nvn 0.0116 0.9933 0.1148\nvn 0.0171 0.9933 0.1147\nvn 0.0289 0.9969 0.0737\nvn 0.0226 0.9971 0.0725\nvn 0.0227 0.9932 0.1139\nvn 0.0363 0.9966 0.0745\nvn 0.0437 0.9963 0.0746\nvn 0.0300 0.9932 0.1128\nvn 0.0291 0.9982 -0.0526\nvn 0.0262 0.9996 -0.0119\nvn 0.0191 0.9983 -0.0549\nvn 0.0175 0.9997 -0.0145\nvn 0.0146 0.9995 0.0272\nvn 0.0225 0.9993 0.0291\nvn 0.0086 0.9998 -0.0159\nvn 0.0095 0.9983 -0.0570\nvn 0.0073 0.9996 0.0256\nvn 0.0017 0.9935 0.1141\nvn 0.0050 0.9976 0.0690\nvn 0.0040 0.9934 0.1144\nvn 0.0106 0.9975 0.0699\nvn 0.0161 0.9973 0.0712\nvn 0.0077 0.9934 0.1147\nvn -0.0183 0.9636 0.2666\nvn -0.0322 0.9640 0.2641\nvn -0.0168 0.9774 0.2107\nvn -0.0097 0.9771 0.2126\nvn -0.0454 0.9661 0.2543\nvn -0.0414 0.9649 0.2594\nvn -0.0218 0.9785 0.2050\nvn -0.0205 0.9778 0.2084\nvn -0.0047 0.9871 0.1602\nvn -0.0025 0.9873 0.1589\nvn -0.0046 0.9869 0.1613\nvn -0.0032 0.9868 0.1617\nvn -0.0459 0.9676 0.2483\nvn -0.0417 0.9693 0.2424\nvn -0.0159 0.9803 0.1971\nvn -0.0196 0.9793 0.2014\nvn -0.0355 0.9710 0.2363\nvn -0.0091 0.9812 0.1928\nvn 0.0120 0.9884 0.1517\nvn 0.0060 0.9879 0.1547\nvn 0.0006 0.9876 0.1569\nvn 0.6011 0.1147 -0.7909\nvn 0.6257 0.1104 -0.7722\nvn 0.5668 0.1197 -0.8151\nvn 0.5528 0.2325 -0.8002\nvn 0.5883 0.2224 -0.7774\nvn 0.6130 0.2142 -0.7605\nvn 0.4524 0.1323 -0.8819\nvn 0.5181 0.1257 -0.8460\nvn 0.4384 0.2564 -0.8614\nvn 0.5046 0.2437 -0.8282\nvn 0.3936 0.4637 -0.7938\nvn 0.4580 0.4436 -0.7704\nvn 0.4834 0.3505 -0.8022\nvn 0.4185 0.3674 -0.8306\nvn 0.5068 0.4250 -0.7500\nvn 0.5326 0.3345 -0.7775\nvn 0.5707 0.3935 -0.7208\nvn 0.5945 0.3087 -0.7425\nvn 0.5682 0.3208 -0.7578\nvn 0.5439 0.4078 -0.7334\nvn 0.3647 0.1392 -0.9207\nvn 0.2560 0.1454 -0.9557\nvn 0.2462 0.2805 -0.9277\nvn 0.3528 0.2691 -0.8962\nvn 0.1301 0.1497 -0.9801\nvn 0.1251 0.2887 -0.9492\nvn 0.1084 0.5116 -0.8524\nvn 0.1174 0.4097 -0.9046\nvn 0.2158 0.4999 -0.8388\nvn 0.2324 0.3997 -0.8867\nvn 0.3344 0.3846 -0.8604\nvn 0.3126 0.4833 -0.8178\nvn 0.0729 0.7530 -0.6539\nvn 0.0811 0.7112 -0.6982\nvn 0.1487 0.7440 -0.6514\nvn 0.1637 0.7020 -0.6931\nvn 0.1808 0.6485 -0.7394\nvn 0.0896 0.6596 -0.7463\nvn 0.2865 0.7129 -0.6401\nvn 0.3119 0.6675 -0.6761\nvn 0.2426 0.6864 -0.6856\nvn 0.2206 0.7306 -0.6462\nvn 0.3392 0.6121 -0.7144\nvn 0.2652 0.6323 -0.7280\nvn 0.2891 0.5651 -0.7727\nvn 0.3667 0.5447 -0.7542\nvn 0.1980 0.5825 -0.7883\nvn 0.0991 0.5934 -0.7988\nvn 0.3425 0.6934 -0.6339\nvn 0.3709 0.6468 -0.6664\nvn 0.3896 0.6735 -0.6281\nvn 0.4189 0.6257 -0.6580\nvn 0.4487 0.5696 -0.6886\nvn 0.4001 0.5905 -0.7009\nvn 0.4873 0.5877 -0.6458\nvn 0.4570 0.6062 -0.6509\nvn 0.4278 0.6539 -0.6240\nvn 0.5160 0.5322 -0.6712\nvn 0.4870 0.5496 -0.6788\nvn 0.5159 0.4843 -0.7066\nvn 0.5445 0.4674 -0.6965\nvn 0.4787 0.5027 -0.7198\nvn 0.4294 0.5235 -0.7359\nvn 0.0122 0.9696 -0.2446\nvn 0.0114 0.9740 -0.2263\nvn 0.0237 0.9738 -0.2260\nvn 0.0252 0.9693 -0.2447\nvn 0.0104 0.9831 -0.1829\nvn 0.0108 0.9785 -0.2057\nvn 0.0216 0.9831 -0.1819\nvn 0.0224 0.9784 -0.2053\nvn 0.0457 0.9828 -0.1791\nvn 0.0476 0.9779 -0.2035\nvn 0.0347 0.9783 -0.2045\nvn 0.0333 0.9830 -0.1808\nvn 0.0504 0.9730 -0.2253\nvn 0.0366 0.9735 -0.2258\nvn 0.0392 0.9688 -0.2448\nvn 0.0536 0.9680 -0.2450\nvn 0.0102 0.9876 -0.1568\nvn 0.0101 0.9917 -0.1279\nvn 0.0207 0.9918 -0.1262\nvn 0.0210 0.9875 -0.1559\nvn 0.0099 0.9955 -0.0944\nvn 0.0202 0.9955 -0.0931\nvn 0.0414 0.9953 -0.0877\nvn 0.0306 0.9954 -0.0904\nvn 0.0429 0.9917 -0.1215\nvn 0.0316 0.9917 -0.1243\nvn 0.0324 0.9875 -0.1540\nvn 0.0442 0.9874 -0.1520\nvn 0.0870 0.9934 -0.0746\nvn 0.0750 0.9942 -0.0776\nvn 0.0916 0.9898 -0.1094\nvn 0.0788 0.9905 -0.1123\nvn 0.0665 0.9911 -0.1155\nvn 0.0635 0.9947 -0.0809\nvn 0.1000 0.9802 -0.1710\nvn 0.0856 0.9812 -0.1731\nvn 0.0822 0.9861 -0.1441\nvn 0.0957 0.9853 -0.1414\nvn 0.0719 0.9819 -0.1753\nvn 0.0690 0.9867 -0.1469\nvn 0.0565 0.9872 -0.1495\nvn 0.0585 0.9824 -0.1773\nvn 0.0545 0.9914 -0.1187\nvn 0.0523 0.9951 -0.0843\nvn 0.1048 0.9746 -0.1981\nvn 0.0899 0.9757 -0.1996\nvn 0.1108 0.9685 -0.2231\nvn 0.0948 0.9700 -0.2238\nvn 0.0796 0.9712 -0.2244\nvn 0.0752 0.9767 -0.2010\nvn 0.1012 0.9640 -0.2457\nvn 0.1176 0.9622 -0.2458\nvn 0.0847 0.9657 -0.2455\nvn 0.0691 0.9670 -0.2452\nvn 0.0645 0.9722 -0.2249\nvn 0.0612 0.9774 -0.2023\nvn 0.1340 0.9601 -0.2456\nvn 0.1262 0.9668 -0.2221\nvn 0.1415 0.9650 -0.2209\nvn 0.1493 0.9580 -0.2449\nvn 0.1144 0.9790 -0.1687\nvn 0.1199 0.9731 -0.1965\nvn 0.1292 0.9775 -0.1666\nvn 0.1346 0.9716 -0.1947\nvn 0.1614 0.9732 -0.1636\nvn 0.1663 0.9672 -0.1918\nvn 0.1500 0.9696 -0.1931\nvn 0.1445 0.9757 -0.1647\nvn 0.1731 0.9603 -0.2189\nvn 0.1565 0.9630 -0.2196\nvn 0.1651 0.9556 -0.2442\nvn 0.1812 0.9529 -0.2434\nvn 0.1097 0.9842 -0.1388\nvn 0.1051 0.9887 -0.1066\nvn 0.1194 0.9873 -0.1044\nvn 0.1243 0.9828 -0.1365\nvn 0.0997 0.9924 -0.0722\nvn 0.1141 0.9910 -0.0703\nvn 0.1483 0.9865 -0.0695\nvn 0.1299 0.9891 -0.0695\nvn 0.1530 0.9829 -0.1023\nvn 0.1354 0.9854 -0.1028\nvn 0.1399 0.9810 -0.1346\nvn 0.1572 0.9785 -0.1335\nvn 0.2454 0.9655 -0.0870\nvn 0.2170 0.9729 -0.0798\nvn 0.2473 0.9617 -0.1185\nvn 0.2206 0.9691 -0.1102\nvn 0.1954 0.9750 -0.1057\nvn 0.1918 0.9786 -0.0741\nvn 0.2494 0.9521 -0.1771\nvn 0.2244 0.9597 -0.1691\nvn 0.2226 0.9647 -0.1405\nvn 0.2492 0.9571 -0.1476\nvn 0.2010 0.9655 -0.1653\nvn 0.1983 0.9707 -0.1356\nvn 0.1765 0.9752 -0.1338\nvn 0.1799 0.9701 -0.1632\nvn 0.1731 0.9795 -0.1029\nvn 0.1685 0.9831 -0.0711\nvn 0.2497 0.9467 -0.2033\nvn 0.2261 0.9540 -0.1970\nvn 0.2489 0.9414 -0.2276\nvn 0.2279 0.9482 -0.2212\nvn 0.2084 0.9532 -0.2191\nvn 0.2041 0.9598 -0.1929\nvn 0.2315 0.9418 -0.2439\nvn 0.2485 0.9366 -0.2471\nvn 0.2142 0.9462 -0.2426\nvn 0.1981 0.9496 -0.2430\nvn 0.1901 0.9572 -0.2183\nvn 0.1845 0.9639 -0.1919\nvn 0.2655 0.9291 -0.2575\nvn 0.2709 0.9328 -0.2377\nvn 0.2907 0.9230 -0.2520\nvn 0.2843 0.9195 -0.2714\nvn 0.2755 0.9428 -0.1876\nvn 0.2729 0.9378 -0.2148\nvn 0.2991 0.9326 -0.2018\nvn 0.2964 0.9274 -0.2283\nvn 0.3440 0.9092 -0.2348\nvn 0.3387 0.9038 -0.2617\nvn 0.3172 0.9163 -0.2444\nvn 0.3228 0.9212 -0.2173\nvn 0.3302 0.8997 -0.2854\nvn 0.3111 0.9118 -0.2678\nvn 0.3015 0.9091 -0.2874\nvn 0.3211 0.8966 -0.3051\nvn 0.2754 0.9481 -0.1592\nvn 0.2754 0.9527 -0.1286\nvn 0.3011 0.9429 -0.1422\nvn 0.3016 0.9378 -0.1723\nvn 0.2731 0.9570 -0.0980\nvn 0.3010 0.9473 -0.1099\nvn 0.3529 0.9252 -0.1397\nvn 0.3267 0.9369 -0.1245\nvn 0.3507 0.9203 -0.1734\nvn 0.3269 0.9320 -0.1567\nvn 0.3249 0.9268 -0.1882\nvn 0.3487 0.9146 -0.2049\nvn 0.4662 0.8590 -0.2119\nvn 0.4341 0.8800 -0.1925\nvn 0.4583 0.8531 -0.2494\nvn 0.4279 0.8744 -0.2289\nvn 0.4005 0.8921 -0.2094\nvn 0.4054 0.8974 -0.1740\nvn 0.4399 0.8409 -0.3153\nvn 0.4126 0.8624 -0.2932\nvn 0.4206 0.8684 -0.2625\nvn 0.4495 0.8469 -0.2841\nvn 0.3881 0.8804 -0.2725\nvn 0.3952 0.8861 -0.2423\nvn 0.3710 0.9014 -0.2232\nvn 0.3662 0.8955 -0.2531\nvn 0.3756 0.9070 -0.1907\nvn 0.3783 0.9123 -0.1565\nvn 0.4294 0.8353 -0.3433\nvn 0.4032 0.8571 -0.3206\nvn 0.4182 0.8308 -0.3673\nvn 0.3931 0.8525 -0.3446\nvn 0.3707 0.8705 -0.3236\nvn 0.3804 0.8749 -0.2998\nvn 0.3817 0.8493 -0.3647\nvn 0.4063 0.8274 -0.3877\nvn 0.3605 0.8671 -0.3438\nvn 0.3402 0.8827 -0.3241\nvn 0.3508 0.8857 -0.3041\nvn 0.3588 0.8903 -0.2803\nvn 0.6145 0.5016 -0.6089\nvn 0.6374 0.4499 -0.6256\nvn 0.6222 0.4579 -0.6350\nvn 0.5989 0.5096 -0.6177\nvn 0.6794 0.3283 -0.6562\nvn 0.6591 0.3924 -0.6415\nvn 0.6652 0.3351 -0.6673\nvn 0.6446 0.3999 -0.6517\nvn 0.6379 0.3506 -0.6857\nvn 0.6159 0.4178 -0.6679\nvn 0.6302 0.4084 -0.6604\nvn 0.6516 0.3424 -0.6768\nvn 0.5919 0.4775 -0.6493\nvn 0.6073 0.4670 -0.6428\nvn 0.5832 0.5193 -0.6246\nvn 0.5673 0.5302 -0.6301\nvn 0.6970 0.2573 -0.6693\nvn 0.7114 0.1787 -0.6797\nvn 0.6980 0.1827 -0.6924\nvn 0.6835 0.2628 -0.6810\nvn 0.7208 0.0927 -0.6870\nvn 0.7079 0.0948 -0.6999\nvn 0.6837 0.0991 -0.7230\nvn 0.6955 0.0969 -0.7119\nvn 0.6731 0.1912 -0.7144\nvn 0.6856 0.1868 -0.7036\nvn 0.6703 0.2687 -0.6917\nvn 0.6576 0.2751 -0.7014\nvn 0.6434 0.1070 -0.7580\nvn 0.6319 0.2071 -0.7469\nvn 0.6470 0.2013 -0.7355\nvn 0.6585 0.1040 -0.7454\nvn 0.5917 0.3806 -0.7107\nvn 0.6137 0.2988 -0.7308\nvn 0.6086 0.3696 -0.7021\nvn 0.6301 0.2899 -0.7204\nvn 0.6442 0.2822 -0.7109\nvn 0.6240 0.3595 -0.6938\nvn 0.6607 0.1959 -0.7247\nvn 0.6713 0.1015 -0.7342\nvn 0.5661 0.4531 -0.6886\nvn 0.5393 0.5161 -0.6654\nvn 0.5586 0.5021 -0.6602\nvn 0.5847 0.4399 -0.6816\nvn 0.5112 0.5715 -0.6419\nvn 0.5321 0.5562 -0.6384\nvn 0.5502 0.5428 -0.6346\nvn 0.5761 0.4890 -0.6549\nvn 0.6007 0.4284 -0.6750\nvn 0.2866 0.5969 0.7494\nvn 0.3957 0.5813 0.7110\nvn 0.2999 0.5244 0.7969\nvn 0.4134 0.5090 0.7550\nvn 0.5093 0.4935 0.7050\nvn 0.4889 0.5644 0.6652\nvn 0.3222 0.3643 0.8738\nvn 0.4416 0.3515 0.8255\nvn 0.4286 0.4325 0.7932\nvn 0.3119 0.4465 0.8387\nvn 0.5415 0.3398 0.7690\nvn 0.5271 0.4182 0.7398\nvn 0.6969 0.3211 0.6412\nvn 0.6803 0.3951 0.6173\nvn 0.6098 0.4058 0.6808\nvn 0.6257 0.3293 0.7072\nvn 0.6597 0.4664 0.5893\nvn 0.5908 0.4787 0.6495\nvn 0.5679 0.5486 0.6136\nvn 0.6358 0.5341 0.5572\nvn 0.3307 0.2775 0.9020\nvn 0.4516 0.2676 0.8511\nvn 0.3369 0.1877 0.9227\nvn 0.4591 0.1803 0.8699\nvn 0.5610 0.1740 0.8093\nvn 0.5529 0.2580 0.7923\nvn 0.4636 0.0910 0.8814\nvn 0.3409 0.0947 0.9353\nvn 0.5659 0.0876 0.8198\nvn 0.7250 0.0832 0.6837\nvn 0.6520 0.0851 0.7535\nvn 0.7195 0.1648 0.6747\nvn 0.6466 0.1686 0.7439\nvn 0.6379 0.2503 0.7283\nvn 0.7100 0.2441 0.6605\nvn 0.9322 0.0800 0.3529\nvn 0.8914 0.0807 0.4460\nvn 0.9245 0.1574 0.3471\nvn 0.8840 0.1590 0.4396\nvn 0.8367 0.1603 0.5237\nvn 0.8432 0.0813 0.5314\nvn 0.8948 0.3037 0.3271\nvn 0.8563 0.3069 0.4154\nvn 0.8723 0.2344 0.4291\nvn 0.9118 0.2322 0.3386\nvn 0.8108 0.3103 0.4963\nvn 0.8257 0.2367 0.5120\nvn 0.7721 0.2398 0.5886\nvn 0.7581 0.3148 0.5711\nvn 0.7820 0.1621 0.6018\nvn 0.7883 0.0820 0.6098\nvn 0.8736 0.3724 0.3133\nvn 0.8363 0.3762 0.3988\nvn 0.8484 0.4378 0.2975\nvn 0.8125 0.4425 0.3795\nvn 0.7694 0.4484 0.4550\nvn 0.7921 0.3808 0.4771\nvn 0.7847 0.5059 0.3582\nvn 0.8194 0.5003 0.2797\nvn 0.7431 0.5128 0.4298\nvn 0.6934 0.5224 0.4962\nvn 0.7190 0.4561 0.5245\nvn 0.7403 0.3870 0.5497\nvn 0.8452 0.4961 0.1987\nvn 0.8756 0.4340 0.2122\nvn 0.8930 0.4311 0.1289\nvn 0.8617 0.4932 0.1189\nvn 0.9242 0.3009 0.2354\nvn 0.9020 0.3688 0.2246\nvn 0.9433 0.2983 0.1456\nvn 0.9202 0.3663 0.1378\nvn 0.9551 0.2953 -0.0239\nvn 0.9314 0.3631 -0.0265\nvn 0.9297 0.3643 0.0539\nvn 0.9532 0.2966 0.0591\nvn 0.9034 0.4279 -0.0293\nvn 0.9019 0.4293 0.0482\nvn 0.8700 0.4912 0.0420\nvn 0.8711 0.4900 -0.0321\nvn 0.9421 0.2297 0.2442\nvn 0.9553 0.1558 0.2511\nvn 0.9755 0.1542 0.1571\nvn 0.9617 0.2277 0.1523\nvn 0.9637 0.0790 0.2552\nvn 0.9839 0.0782 0.1606\nvn 0.9969 0.0770 -0.0183\nvn 0.9946 0.0775 0.0689\nvn 0.9882 0.1521 -0.0198\nvn 0.9860 0.1530 0.0669\nvn 0.9721 0.2260 0.0634\nvn 0.9741 0.2251 -0.0215\nvn 0.9630 0.0772 -0.2583\nvn 0.9543 0.1523 -0.2570\nvn 0.9716 0.1518 -0.1814\nvn 0.9804 0.0769 -0.1815\nvn 0.9216 0.2949 -0.2524\nvn 0.9403 0.2250 -0.2552\nvn 0.9387 0.2946 -0.1793\nvn 0.9576 0.2245 -0.1805\nvn 0.9690 0.2245 -0.1029\nvn 0.9500 0.2948 -0.1032\nvn 0.9831 0.1518 -0.1022\nvn 0.9918 0.0768 -0.1020\nvn 0.8984 0.3619 -0.2486\nvn 0.8712 0.4260 -0.2439\nvn 0.8875 0.4264 -0.1749\nvn 0.9151 0.3620 -0.1775\nvn 0.8404 0.4870 -0.2379\nvn 0.8558 0.4880 -0.1717\nvn 0.8662 0.4889 -0.1031\nvn 0.8983 0.4271 -0.1036\nvn 0.9263 0.3623 -0.1036\nvn -0.3529 0.5816 0.7329\nvn -0.2992 0.5940 0.7468\nvn -0.3784 0.5109 0.7719\nvn -0.3203 0.5247 0.7888\nvn -0.2587 0.5341 0.8049\nvn -0.2417 0.6041 0.7594\nvn -0.4195 0.3568 0.8347\nvn -0.3546 0.3695 0.8589\nvn -0.3389 0.4492 0.8267\nvn -0.4005 0.4366 0.8056\nvn -0.2858 0.3777 0.8807\nvn -0.2735 0.4591 0.8453\nvn -0.1262 0.3858 0.9139\nvn -0.1212 0.4685 0.8751\nvn -0.2016 0.4650 0.8620\nvn -0.2105 0.3835 0.8992\nvn -0.1145 0.5448 0.8307\nvn -0.1910 0.5411 0.8190\nvn -0.1781 0.6108 0.7715\nvn -0.1066 0.6153 0.7810\nvn -0.4350 0.2737 0.8578\nvn -0.3673 0.2837 0.8858\nvn -0.4463 0.1857 0.8754\nvn -0.3769 0.1937 0.9058\nvn -0.3031 0.1987 0.9320\nvn -0.2958 0.2913 0.9098\nvn -0.3827 0.0986 0.9186\nvn -0.4537 0.0946 0.8861\nvn -0.3076 0.1016 0.9461\nvn -0.1337 0.1036 0.9856\nvn -0.2255 0.1031 0.9688\nvn -0.1325 0.2029 0.9702\nvn -0.2224 0.2020 0.9538\nvn -0.2175 0.2954 0.9303\nvn -0.1299 0.2974 0.9459\nvn 0.2087 0.0984 0.9730\nvn 0.2059 0.1942 0.9591\nvn 0.0818 0.1992 0.9765\nvn 0.0838 0.1012 0.9913\nvn 0.1952 0.3747 0.9064\nvn 0.2011 0.2867 0.9367\nvn 0.0764 0.3818 0.9211\nvn 0.0794 0.2929 0.9528\nvn -0.0313 0.2965 0.9545\nvn -0.0309 0.3855 0.9222\nvn -0.0311 0.2021 0.9789\nvn -0.0311 0.1029 0.9942\nvn 0.1883 0.4581 0.8687\nvn 0.1806 0.5360 0.8247\nvn 0.0707 0.5430 0.8368\nvn 0.0734 0.4653 0.8821\nvn 0.1728 0.6084 0.7746\nvn 0.0681 0.6147 0.7858\nvn -0.0247 0.6166 0.7869\nvn -0.0280 0.5457 0.8375\nvn -0.0298 0.4685 0.8829\nvn 0.5997 0.5836 -0.5475\nvn 0.5734 0.6267 -0.5277\nvn 0.5912 0.6270 -0.5073\nvn 0.6184 0.5825 -0.5275\nvn 0.5177 0.7058 -0.4835\nvn 0.5459 0.6678 -0.5060\nvn 0.5334 0.7079 -0.4630\nvn 0.5626 0.6688 -0.4859\nvn 0.5663 0.7163 -0.4078\nvn 0.5986 0.6758 -0.4301\nvn 0.5803 0.6717 -0.4604\nvn 0.5496 0.7114 -0.4380\nvn 0.6304 0.6320 -0.4508\nvn 0.6102 0.6288 -0.4820\nvn 0.6389 0.5833 -0.5016\nvn 0.6607 0.5851 -0.4703\nvn 0.4892 0.7411 -0.4598\nvn 0.4609 0.7730 -0.4360\nvn 0.4746 0.7761 -0.4154\nvn 0.5039 0.7435 -0.4396\nvn 0.4331 0.8019 -0.4116\nvn 0.4459 0.8050 -0.3914\nvn 0.4699 0.8152 -0.3386\nvn 0.4582 0.8097 -0.3668\nvn 0.5013 0.7860 -0.3617\nvn 0.4880 0.7804 -0.3908\nvn 0.5187 0.7478 -0.4144\nvn 0.5335 0.7530 -0.3852\nvn 0.5014 0.8337 -0.2313\nvn 0.5382 0.8045 -0.2511\nvn 0.5267 0.7985 -0.2917\nvn 0.4915 0.8277 -0.2707\nvn 0.6157 0.7331 -0.2890\nvn 0.5768 0.7710 -0.2701\nvn 0.5998 0.7275 -0.3332\nvn 0.5628 0.7651 -0.3129\nvn 0.5484 0.7590 -0.3511\nvn 0.5829 0.7217 -0.3732\nvn 0.5141 0.7921 -0.3289\nvn 0.4811 0.8214 -0.3063\nvn 0.6550 0.6907 -0.3064\nvn 0.6931 0.6443 -0.3233\nvn 0.6726 0.6401 -0.3714\nvn 0.6364 0.6857 -0.3532\nvn 0.7299 0.5941 -0.3381\nvn 0.7069 0.5909 -0.3887\nvn 0.6837 0.5878 -0.4324\nvn 0.6512 0.6358 -0.4142\nvn 0.6176 0.6806 -0.3941\nvn -0.1916 0.5342 0.8233\nvn -0.2105 0.4637 0.8606\nvn -0.3557 0.4545 0.8166\nvn -0.3280 0.5237 0.7862\nvn -0.2411 0.3168 0.9173\nvn -0.2263 0.3930 0.8913\nvn -0.4027 0.3075 0.8622\nvn -0.3818 0.3810 0.8420\nvn -0.5320 0.3049 0.7899\nvn -0.5079 0.3795 0.7733\nvn -0.4687 0.3766 0.7991\nvn -0.4933 0.3020 0.8157\nvn -0.4781 0.4530 0.7525\nvn -0.4406 0.4492 0.7773\nvn -0.4072 0.5206 0.7504\nvn -0.4446 0.5245 0.7262\nvn -0.2521 0.2409 0.9372\nvn -0.2612 0.1612 0.9517\nvn -0.4327 0.1552 0.8881\nvn -0.4206 0.2312 0.8773\nvn -0.2661 0.0815 0.9605\nvn -0.4411 0.0777 0.8941\nvn -0.5748 0.0769 0.8147\nvn -0.5342 0.0762 0.8419\nvn -0.5655 0.1534 0.8103\nvn -0.5264 0.1517 0.8366\nvn -0.5118 0.2274 0.8284\nvn -0.5520 0.2293 0.8017\nvn -0.5142 0.0893 0.8530\nvn -0.5065 0.1765 0.8440\nvn -0.5484 0.1668 0.8194\nvn -0.5574 0.0842 0.8260\nvn -0.4760 0.3424 0.8101\nvn -0.4933 0.2606 0.8299\nvn -0.5161 0.3269 0.7916\nvn -0.5351 0.2480 0.8076\nvn -0.5559 0.2368 0.7968\nvn -0.5370 0.3139 0.7830\nvn -0.5704 0.1587 0.8059\nvn -0.5785 0.0798 0.8118\nvn -0.4543 0.4202 0.7855\nvn -0.4288 0.4953 0.7555\nvn -0.4653 0.4782 0.7449\nvn -0.4930 0.4042 0.7705\nvn -0.4000 0.5656 0.7212\nvn -0.4336 0.5499 0.7139\nvn -0.4503 0.5349 0.7149\nvn -0.4837 0.4636 0.7424\nvn -0.5125 0.3895 0.7653\nvn 0.0660 0.7858 -0.6149\nvn 0.0593 0.8135 -0.5786\nvn 0.1218 0.8067 -0.5783\nvn 0.1342 0.7787 -0.6129\nvn 0.0483 0.8555 -0.5156\nvn 0.0537 0.8359 -0.5462\nvn 0.0996 0.8505 -0.5164\nvn 0.1097 0.8307 -0.5458\nvn 0.1991 0.8320 -0.5177\nvn 0.2181 0.8092 -0.5455\nvn 0.1660 0.8212 -0.5459\nvn 0.1501 0.8429 -0.5167\nvn 0.2397 0.7821 -0.5751\nvn 0.1824 0.7964 -0.5767\nvn 0.2012 0.7662 -0.6103\nvn 0.2619 0.7506 -0.6066\nvn 0.0438 0.8718 -0.4880\nvn 0.0394 0.8863 -0.4614\nvn 0.0812 0.8828 -0.4627\nvn 0.0896 0.8680 -0.4884\nvn 0.0356 0.8988 -0.4370\nvn 0.0729 0.8961 -0.4378\nvn 0.1484 0.8846 -0.4421\nvn 0.1114 0.8911 -0.4399\nvn 0.1643 0.8692 -0.4663\nvn 0.1229 0.8773 -0.4640\nvn 0.1364 0.8611 -0.4899\nvn 0.1805 0.8521 -0.4912\nvn 0.2476 0.8573 -0.4514\nvn 0.2695 0.8381 -0.4744\nvn 0.2382 0.8492 -0.4714\nvn 0.2172 0.8671 -0.4483\nvn 0.3177 0.7917 -0.5218\nvn 0.2932 0.8164 -0.4976\nvn 0.2834 0.8058 -0.5200\nvn 0.2597 0.8289 -0.4954\nvn 0.2226 0.8410 -0.4932\nvn 0.2433 0.8196 -0.5187\nvn 0.2024 0.8599 -0.4686\nvn 0.1845 0.8762 -0.4451\nvn 0.3439 0.7638 -0.5463\nvn 0.3709 0.7318 -0.5718\nvn 0.3341 0.7490 -0.5721\nvn 0.3078 0.7794 -0.5458\nvn 0.3990 0.6957 -0.5974\nvn 0.3612 0.7139 -0.5999\nvn 0.3159 0.7327 -0.6028\nvn 0.2900 0.7661 -0.5735\nvn 0.2663 0.7947 -0.5454\n# 5634 vertex normals\n\nvt 0.1020 0.1559 0.0000\nvt 0.0917 0.1400 0.0000\nvt 0.1404 0.0910 0.0000\nvt 0.1446 0.1132 0.0000\nvt 0.0812 0.1287 0.0000\nvt 0.1365 0.0728 0.0000\nvt 0.1878 0.0278 0.0000\nvt 0.1861 0.0527 0.0000\nvt 0.1860 0.0806 0.0000\nvt 0.0340 0.3475 0.0000\nvt 0.0572 0.3686 0.0000\nvt 0.4849 0.5853 0.0000\nvt 0.5487 0.5831 0.0000\nvt 0.5501 0.6019 0.0000\nvt 0.4942 0.6042 0.0000\nvt 0.6121 0.5822 0.0000\nvt 0.0583 0.6396 0.0000\nvt 0.0481 0.4000 0.0000\nvt 0.0154 0.3608 0.0000\nvt 0.0942 0.3841 0.0000\nvt 0.1072 0.8133 0.0000\nvt 0.0567 0.6676 0.0000\nvt 0.0907 0.4236 0.0000\nvt 0.0850 0.4575 0.0000\nvt 0.0348 0.4243 0.0000\nvt 0.0000 0.3700 0.0000\nvt 0.1845 0.1162 0.0000\nvt 0.1440 0.8133 0.0000\nvt 0.0019 0.6700 0.0000\nvt 0.1479 0.1421 0.0000\nvt 0.1810 0.1592 0.0000\nvt 0.1475 0.1777 0.0000\nvt 0.1224 0.1938 0.0000\nvt 0.1130 0.1765 0.0000\nvt 0.1445 0.8293 0.0000\nvt 0.1719 0.2643 0.0000\nvt 0.0081 0.6452 0.0000\nvt 0.6096 0.6011 0.0000\nvt 0.0559 0.6969 0.0000\nvt 0.1726 0.3206 0.0000\nvt 0.7354 0.5391 0.0000\nvt 0.1083 0.8301 0.0000\nvt 0.0000 0.6969 0.0000\nvt 0.1715 0.8133 0.0000\nvt 0.1333 0.3307 0.0000\nvt 0.1715 0.8292 0.0000\nvt 0.1715 0.8452 0.0000\nvt 0.1340 0.2741 0.0000\nvt 0.1766 0.3715 0.0000\nvt 0.1359 0.3835 0.0000\nvt 0.1628 0.6364 0.0000\nvt 0.0950 0.3323 0.0000\nvt 0.0985 0.2771 0.0000\nvt 0.0430 0.2551 0.0000\nvt 0.0332 0.3086 0.0000\nvt 0.0075 0.3049 0.0000\nvt 0.0193 0.2454 0.0000\nvt 0.1380 0.4245 0.0000\nvt 0.1819 0.4106 0.0000\nvt 0.1895 0.4405 0.0000\nvt 0.1402 0.4582 0.0000\nvt 0.0610 0.3217 0.0000\nvt 0.1963 0.4758 0.0000\nvt 0.1988 0.4954 0.0000\nvt 0.0681 0.2681 0.0000\nvt 0.1617 0.6657 0.0000\nvt 0.2128 0.3562 0.0000\nvt 0.2168 0.3928 0.0000\nvt 0.1354 0.4947 0.0000\nvt 0.2460 0.3485 0.0000\nvt 0.1368 0.4756 0.0000\nvt 0.2460 0.3839 0.0000\nvt 0.1128 0.6661 0.0000\nvt 0.2460 0.4070 0.0000\nvt 0.2220 0.4188 0.0000\nvt 0.2188 0.0631 0.0000\nvt 0.2168 0.1013 0.0000\nvt 0.1468 0.8453 0.0000\nvt 0.1133 0.8466 0.0000\nvt 0.0067 0.8532 0.0000\nvt 0.0716 0.4931 0.0000\nvt 0.1135 0.6370 0.0000\nvt 0.0808 0.4741 0.0000\nvt 0.3221 0.5394 0.0000\nvt 0.1620 0.6969 0.0000\nvt 0.2460 0.0581 0.0000\nvt 0.1128 0.6969 0.0000\nvt 0.2460 0.0968 0.0000\nvt 0.8980 0.1559 0.0000\nvt 0.0000 0.8338 0.0000\nvt 0.0577 0.8318 0.0000\nvt 0.8554 0.1132 0.0000\nvt 0.8596 0.0910 0.0000\nvt 0.9083 0.1400 0.0000\nvt 0.2194 0.6363 0.0000\nvt 0.8140 0.0806 0.0000\nvt 0.8139 0.0527 0.0000\nvt 0.8122 0.0278 0.0000\nvt 0.8635 0.0728 0.0000\nvt 0.9188 0.1287 0.0000\nvt 0.9660 0.3475 0.0000\nvt 0.9846 0.3608 0.0000\nvt 0.9519 0.4000 0.0000\nvt 0.9428 0.3686 0.0000\nvt 1.0000 0.3700 0.0000\nvt 0.9652 0.4243 0.0000\nvt 0.7335 0.5597 0.0000\nvt 0.6751 0.5606 0.0000\nvt 0.9150 0.4575 0.0000\nvt 0.2194 0.6658 0.0000\nvt 0.9093 0.4236 0.0000\nvt 0.9058 0.3841 0.0000\nvt 0.6768 0.5391 0.0000\nvt 0.8521 0.1421 0.0000\nvt 0.7263 0.5790 0.0000\nvt 0.8155 0.1162 0.0000\nvt 0.1952 0.6657 0.0000\nvt 0.8870 0.1765 0.0000\nvt 0.8776 0.1938 0.0000\nvt 0.8525 0.1777 0.0000\nvt 0.8190 0.1592 0.0000\nvt 0.0620 0.8497 0.0000\nvt 0.0556 0.8133 0.0000\nvt 0.2358 0.8133 0.0000\nvt 0.6714 0.5814 0.0000\nvt 0.1953 0.6362 0.0000\nvt 0.6138 0.5614 0.0000\nvt 0.6142 0.5391 0.0000\nvt 0.2194 0.6969 0.0000\nvt 0.8281 0.2643 0.0000\nvt 0.1955 0.6969 0.0000\nvt 0.8660 0.2741 0.0000\nvt 0.8667 0.3307 0.0000\nvt 0.8274 0.3206 0.0000\nvt 0.2346 0.8301 0.0000\nvt 0.1985 0.8293 0.0000\nvt 0.9015 0.2771 0.0000\nvt 0.9050 0.3323 0.0000\nvt 0.3804 0.6396 0.0000\nvt 0.8641 0.3835 0.0000\nvt 0.8234 0.3715 0.0000\nvt 0.9570 0.2551 0.0000\nvt 0.9807 0.2454 0.0000\nvt 0.9925 0.3049 0.0000\nvt 0.9668 0.3086 0.0000\nvt 0.8620 0.4245 0.0000\nvt 0.8598 0.4582 0.0000\nvt 0.8105 0.4405 0.0000\nvt 0.8181 0.4106 0.0000\nvt 0.2634 0.5393 0.0000\nvt 0.2618 0.5175 0.0000\nvt 0.9390 0.3217 0.0000\nvt 0.4306 0.6452 0.0000\nvt 0.9319 0.2681 0.0000\nvt 0.7832 0.3928 0.0000\nvt 0.7872 0.3562 0.0000\nvt 0.3201 0.5188 0.0000\nvt 0.2009 0.5393 0.0000\nvt 0.7780 0.4188 0.0000\nvt 0.4368 0.6700 0.0000\nvt 0.7540 0.4070 0.0000\nvt 0.7540 0.3839 0.0000\nvt 0.7540 0.3485 0.0000\nvt 0.7832 0.1013 0.0000\nvt 0.7812 0.0631 0.0000\nvt 0.1990 0.8133 0.0000\nvt 0.2297 0.8466 0.0000\nvt 0.1962 0.8453 0.0000\nvt 0.2004 0.5167 0.0000\nvt 0.2581 0.4965 0.0000\nvt 0.3820 0.6676 0.0000\nvt 0.3130 0.4994 0.0000\nvt 0.4387 0.6969 0.0000\nvt 0.7860 0.1469 0.0000\nvt 0.3828 0.6969 0.0000\nvt 0.7540 0.1427 0.0000\nvt 0.2460 0.1427 0.0000\nvt 0.2140 0.1469 0.0000\nvt 0.2092 0.2548 0.0000\nvt 0.2099 0.3088 0.0000\nvt 0.2460 0.2507 0.0000\nvt 0.2460 0.3030 0.0000\nvt 0.2460 0.1956 0.0000\nvt 0.7949 0.5391 0.0000\nvt 0.2110 0.1994 0.0000\nvt 0.1757 0.2093 0.0000\nvt 0.1406 0.2221 0.0000\nvt 0.3363 0.8534 0.0000\nvt 0.1095 0.2281 0.0000\nvt 0.0857 0.2187 0.0000\nvt 0.0667 0.2034 0.0000\nvt 0.2810 0.8497 0.0000\nvt 0.2759 0.6364 0.0000\nvt 0.7917 0.5576 0.0000\nvt 0.3252 0.6370 0.0000\nvt 0.0482 0.1908 0.0000\nvt 0.3259 0.6661 0.0000\nvt 0.0355 0.1836 0.0000\nvt 0.2460 0.0000 0.0000\nvt 0.2460 0.0266 0.0000\nvt 0.2198 0.0322 0.0000\nvt 0.2214 0.0055 0.0000\nvt 0.3901 0.1559 0.0000\nvt 0.3474 0.1132 0.0000\nvt 0.3516 0.0910 0.0000\nvt 0.3816 0.5394 0.0000\nvt 0.4003 0.1400 0.0000\nvt 0.3060 0.0806 0.0000\nvt 0.3060 0.0527 0.0000\nvt 0.2853 0.8318 0.0000\nvt 0.3042 0.0278 0.0000\nvt 0.3555 0.0728 0.0000\nvt 0.4109 0.1287 0.0000\nvt 0.3430 0.8339 0.0000\nvt 0.2770 0.6657 0.0000\nvt 0.3783 0.5209 0.0000\nvt 0.3260 0.6969 0.0000\nvt 0.4581 0.3475 0.0000\nvt 0.2767 0.6969 0.0000\nvt 0.4766 0.3608 0.0000\nvt 0.7540 0.0968 0.0000\nvt 0.7540 0.0581 0.0000\nvt 0.7901 0.3088 0.0000\nvt 0.7908 0.2548 0.0000\nvt 0.7540 0.3030 0.0000\nvt 0.7540 0.2507 0.0000\nvt 0.7890 0.1994 0.0000\nvt 0.4769 0.5391 0.0000\nvt 0.7540 0.1956 0.0000\nvt 0.8243 0.2093 0.0000\nvt 0.8594 0.2221 0.0000\nvt 0.2874 0.8133 0.0000\nvt 0.8905 0.2281 0.0000\nvt 0.9143 0.2187 0.0000\nvt 0.9333 0.2034 0.0000\nvt 0.1083 0.7965 0.0000\nvt 0.2434 0.6362 0.0000\nvt 0.4797 0.5631 0.0000\nvt 0.2435 0.6657 0.0000\nvt 0.9645 0.1836 0.0000\nvt 0.2432 0.6969 0.0000\nvt 0.9518 0.1908 0.0000\nvt 0.7540 0.0000 0.0000\nvt 0.7786 0.0055 0.0000\nvt 0.7802 0.0322 0.0000\nvt 0.7540 0.0266 0.0000\nvt 0.6099 0.1559 0.0000\nvt 0.5997 0.1400 0.0000\nvt 0.6484 0.0910 0.0000\nvt 0.0174 0.4878 0.0000\nvt 0.6526 0.1132 0.0000\nvt 0.5891 0.1287 0.0000\nvt 0.6445 0.0728 0.0000\nvt 0.1445 0.7973 0.0000\nvt 0.6958 0.0278 0.0000\nvt 0.6940 0.0527 0.0000\nvt 0.6940 0.0806 0.0000\nvt 0.1133 0.7800 0.0000\nvt 0.0583 0.7542 0.0000\nvt 0.0664 0.5153 0.0000\nvt 0.0081 0.7485 0.0000\nvt 0.5419 0.3475 0.0000\nvt 0.0019 0.7238 0.0000\nvt 0.5651 0.3686 0.0000\nvt 0.4440 0.4000 0.0000\nvt 0.4349 0.3686 0.0000\nvt 0.4921 0.3700 0.0000\nvt 0.4572 0.4243 0.0000\nvt 0.4071 0.4575 0.0000\nvt 0.4014 0.4236 0.0000\nvt 0.3978 0.3841 0.0000\nvt 0.3442 0.1421 0.0000\nvt 0.3076 0.1162 0.0000\nvt 0.3791 0.1765 0.0000\nvt 0.3697 0.1938 0.0000\nvt 0.3446 0.1777 0.0000\nvt 0.3110 0.1592 0.0000\nvt 0.3202 0.2643 0.0000\nvt 0.4180 0.5661 0.0000\nvt 0.1468 0.7813 0.0000\nvt 0.3580 0.2741 0.0000\nvt 0.3587 0.3307 0.0000\nvt 0.3195 0.3206 0.0000\nvt 0.3936 0.2771 0.0000\nvt 0.1715 0.7814 0.0000\nvt 0.3970 0.3323 0.0000\nvt 0.3562 0.3835 0.0000\nvt 0.3155 0.3715 0.0000\nvt 0.4491 0.2551 0.0000\nvt 0.4727 0.2454 0.0000\nvt 0.1715 0.7974 0.0000\nvt 0.0567 0.7262 0.0000\nvt 0.4133 0.5391 0.0000\nvt 0.1628 0.7574 0.0000\nvt 0.4846 0.3049 0.0000\nvt 0.4589 0.3086 0.0000\nvt 0.0067 0.7734 0.0000\nvt 0.1135 0.7568 0.0000\nvt 0.4307 0.5908 0.0000\nvt 0.1128 0.7277 0.0000\nvt 0.3541 0.4245 0.0000\nvt 0.1617 0.7281 0.0000\nvt 0.0620 0.7769 0.0000\nvt 0.3519 0.4582 0.0000\nvt 0.0577 0.7948 0.0000\nvt 0.3025 0.4405 0.0000\nvt 0.3101 0.4106 0.0000\nvt 0.4311 0.3217 0.0000\nvt 0.4239 0.2681 0.0000\nvt 0.2194 0.7575 0.0000\nvt 0.2753 0.3928 0.0000\nvt 0.2793 0.3562 0.0000\nvt 0.2701 0.4188 0.0000\nvt 0.2753 0.1013 0.0000\nvt 0.2733 0.0631 0.0000\nvt 0.2780 0.1469 0.0000\nvt 0.2821 0.3088 0.0000\nvt 0.2828 0.2548 0.0000\nvt 0.2810 0.1994 0.0000\nvt 0.0046 0.5125 0.0000\nvt 0.3163 0.2093 0.0000\nvt 0.3515 0.2221 0.0000\nvt 0.1953 0.7575 0.0000\nvt 0.3825 0.2281 0.0000\nvt 0.0000 0.7928 0.0000\nvt 0.4063 0.2187 0.0000\nvt 0.0635 0.5394 0.0000\nvt 0.4254 0.2034 0.0000\nvt 0.1952 0.7281 0.0000\nvt 0.4566 0.1836 0.0000\nvt 0.4438 0.1908 0.0000\nvt 0.2707 0.0055 0.0000\nvt 0.2723 0.0322 0.0000\nvt 0.2194 0.7280 0.0000\nvt 0.1985 0.7973 0.0000\nvt 0.2346 0.7965 0.0000\nvt 0.3804 0.7542 0.0000\nvt 0.3820 0.7262 0.0000\nvt 0.4368 0.7238 0.0000\nvt 0.4306 0.7485 0.0000\nvt 0.2759 0.7574 0.0000\nvt 0.0000 0.5394 0.0000\nvt 0.2770 0.7281 0.0000\nvt 0.3259 0.7277 0.0000\nvt 0.3252 0.7568 0.0000\nvt 0.5560 0.4000 0.0000\nvt 0.1962 0.7813 0.0000\nvt 0.5234 0.3608 0.0000\nvt 0.6022 0.3841 0.0000\nvt 0.5986 0.4236 0.0000\nvt 0.5929 0.4575 0.0000\nvt 0.2435 0.7281 0.0000\nvt 0.5428 0.4243 0.0000\nvt 0.5079 0.3700 0.0000\nvt 0.6924 0.1162 0.0000\nvt 0.6558 0.1421 0.0000\nvt 0.6890 0.1592 0.0000\nvt 0.6554 0.1777 0.0000\nvt 0.6303 0.1938 0.0000\nvt 0.6209 0.1765 0.0000\nvt 0.6798 0.2643 0.0000\nvt 0.5465 0.5619 0.0000\nvt 0.6805 0.3206 0.0000\nvt 0.6413 0.3307 0.0000\nvt 0.2434 0.7575 0.0000\nvt 0.6420 0.2741 0.0000\nvt 0.2297 0.7800 0.0000\nvt 0.6845 0.3715 0.0000\nvt 0.5453 0.5391 0.0000\nvt 0.6642 0.5991 0.0000\nvt 0.6438 0.3835 0.0000\nvt 0.6030 0.3323 0.0000\nvt 0.3363 0.7734 0.0000\nvt 0.6064 0.2771 0.0000\nvt 0.5509 0.2551 0.0000\nvt 0.5411 0.3086 0.0000\nvt 0.5154 0.3049 0.0000\nvt 0.5273 0.2454 0.0000\nvt 0.3430 0.7928 0.0000\nvt 0.2853 0.7948 0.0000\nvt 0.2810 0.7769 0.0000\nvt 0.6459 0.4245 0.0000\nvt 0.6899 0.4106 0.0000\nvt 0.6975 0.4405 0.0000\nvt 0.6481 0.4582 0.0000\nvt 0.6096 0.4772 0.0000\nvt 0.6121 0.4961 0.0000\nvt 0.5689 0.3217 0.0000\nvt 0.5761 0.2681 0.0000\nvt 0.7207 0.3562 0.0000\nvt 0.7247 0.3928 0.0000\nvt 0.7299 0.4188 0.0000\nvt 0.7267 0.0631 0.0000\nvt 0.7247 0.1013 0.0000\nvt 0.7220 0.1469 0.0000\nvt 0.7172 0.2548 0.0000\nvt 0.7179 0.3088 0.0000\nvt 0.7190 0.1994 0.0000\nvt 0.6837 0.2093 0.0000\nvt 0.6485 0.2221 0.0000\nvt 0.6175 0.2281 0.0000\nvt 0.5937 0.2187 0.0000\nvt 0.1331 0.5163 0.0000\nvt 0.5746 0.2034 0.0000\nvt 0.5562 0.1908 0.0000\nvt 0.5434 0.1836 0.0000\nvt 0.1320 0.5393 0.0000\nvt 0.2509 0.4784 0.0000\nvt 0.7277 0.0322 0.0000\nvt 0.7293 0.0055 0.0000\nvt 0.0716 0.5856 0.0000\nvt 0.1354 0.5834 0.0000\nvt 0.5487 0.4952 0.0000\nvt 0.5501 0.4764 0.0000\nvt 0.1368 0.6021 0.0000\nvt 0.0808 0.6045 0.0000\nvt 0.4849 0.4930 0.0000\nvt 0.4942 0.4741 0.0000\nvt 0.6751 0.5176 0.0000\nvt 0.7335 0.5186 0.0000\nvt 0.1988 0.5825 0.0000\nvt 0.1963 0.6014 0.0000\nvt 0.3201 0.5599 0.0000\nvt 0.2618 0.5609 0.0000\nvt 0.3130 0.5793 0.0000\nvt 0.2581 0.5816 0.0000\nvt 0.2004 0.5616 0.0000\nvt 0.3783 0.5579 0.0000\nvt 0.0664 0.5634 0.0000\nvt 0.0046 0.5663 0.0000\nvt 0.0174 0.5911 0.0000\nvt 0.1331 0.5621 0.0000\nvt 0.2509 0.5994 0.0000\nvt 0.6138 0.5169 0.0000\nvt 0.6714 0.4969 0.0000\nvt 0.7263 0.4993 0.0000\nvt 0.7917 0.5207 0.0000\nvt 0.4307 0.4875 0.0000\nvt 0.4797 0.5152 0.0000\nvt 0.4180 0.5122 0.0000\nvt 0.5465 0.5164 0.0000\nvt 0.6642 0.4792 0.0000\nvt 0.1192 0.1235 0.0000\nvt 0.1123 0.1075 0.0000\nvt 0.1632 0.0598 0.0000\nvt 0.1654 0.0817 0.0000\nvt 0.0380 0.3709 0.0000\nvt 0.0719 0.3980 0.0000\nvt 0.0642 0.4281 0.0000\nvt 0.0243 0.3896 0.0000\nvt 0.1665 0.1106 0.0000\nvt 0.1657 0.1470 0.0000\nvt 0.1323 0.1719 0.0000\nvt 0.1265 0.1454 0.0000\nvt 0.1523 0.2980 0.0000\nvt 0.1546 0.3535 0.0000\nvt 0.1143 0.3604 0.0000\nvt 0.1141 0.3048 0.0000\nvt 0.0248 0.2782 0.0000\nvt 0.0221 0.3308 0.0000\nvt 0.5195 0.5937 0.0000\nvt 0.5804 0.5922 0.0000\nvt 0.1148 0.4077 0.0000\nvt 0.1588 0.4001 0.0000\nvt 0.1628 0.4347 0.0000\nvt 0.1135 0.4427 0.0000\nvt 0.0762 0.3544 0.0000\nvt 0.0449 0.3381 0.0000\nvt 0.0493 0.2883 0.0000\nvt 0.0791 0.3008 0.0000\nvt 0.7058 0.5497 0.0000\nvt 0.7017 0.5702 0.0000\nvt 0.6438 0.5716 0.0000\nvt 0.6460 0.5502 0.0000\nvt 0.1978 0.3840 0.0000\nvt 0.2306 0.3699 0.0000\nvt 0.2328 0.4005 0.0000\nvt 0.2030 0.4163 0.0000\nvt 0.2025 0.0878 0.0000\nvt 0.2322 0.0777 0.0000\nvt 0.2309 0.1199 0.0000\nvt 0.1996 0.1288 0.0000\nvt 0.1906 0.2872 0.0000\nvt 0.2277 0.2788 0.0000\nvt 0.2287 0.3288 0.0000\nvt 0.1931 0.3402 0.0000\nvt 0.1276 0.8214 0.0000\nvt 0.1584 0.8212 0.0000\nvt 0.1588 0.8372 0.0000\nvt 0.1289 0.8378 0.0000\nvt 0.2293 0.1695 0.0000\nvt 0.2280 0.2242 0.0000\nvt 0.1917 0.2312 0.0000\nvt 0.1956 0.1772 0.0000\nvt 0.1612 0.1911 0.0000\nvt 0.1549 0.2421 0.0000\nvt 0.1194 0.2508 0.0000\nvt 0.1293 0.2053 0.0000\nvt 0.1067 0.2042 0.0000\nvt 0.0886 0.2483 0.0000\nvt 0.0638 0.2356 0.0000\nvt 0.0904 0.1878 0.0000\nvt 0.0315 0.8421 0.0000\nvt 0.7640 0.5489 0.0000\nvt 0.0833 0.8221 0.0000\nvt 0.0857 0.8395 0.0000\nvt 0.0311 0.6555 0.0000\nvt 0.0283 0.6827 0.0000\nvt 0.4462 0.5518 0.0000\nvt 0.4530 0.5763 0.0000\nvt 0.5145 0.5734 0.0000\nvt 0.5110 0.5508 0.0000\nvt 0.5804 0.5505 0.0000\nvt 0.5808 0.5724 0.0000\nvt 0.1385 0.6511 0.0000\nvt 0.1390 0.6812 0.0000\nvt 0.0847 0.6816 0.0000\nvt 0.0854 0.6523 0.0000\nvt 0.0639 0.1606 0.0000\nvt 0.0762 0.1718 0.0000\nvt 0.0434 0.2231 0.0000\nvt 0.6395 0.5910 0.0000\nvt 0.2076 0.6509 0.0000\nvt 0.2080 0.6812 0.0000\nvt 0.1805 0.6811 0.0000\nvt 0.1796 0.6508 0.0000\nvt 0.2335 0.0150 0.0000\nvt 0.2331 0.0426 0.0000\nvt 0.2040 0.0542 0.0000\nvt 0.2044 0.0282 0.0000\nvt 0.3728 0.1235 0.0000\nvt 0.3267 0.0817 0.0000\nvt 0.3289 0.0598 0.0000\nvt 0.3798 0.1075 0.0000\nvt 0.4541 0.3709 0.0000\nvt 0.4678 0.3896 0.0000\nvt 0.4278 0.4281 0.0000\nvt 0.4202 0.3980 0.0000\nvt 0.3255 0.1106 0.0000\nvt 0.3656 0.1454 0.0000\nvt 0.3597 0.1719 0.0000\nvt 0.3264 0.1470 0.0000\nvt 0.3397 0.2980 0.0000\nvt 0.3780 0.3048 0.0000\nvt 0.3777 0.3604 0.0000\nvt 0.3374 0.3535 0.0000\nvt 0.4673 0.2782 0.0000\nvt 0.1670 0.4852 0.0000\nvt 0.1062 0.4843 0.0000\nvt 0.4700 0.3308 0.0000\nvt 0.3773 0.4077 0.0000\nvt 0.3786 0.4427 0.0000\nvt 0.3293 0.4347 0.0000\nvt 0.3333 0.4001 0.0000\nvt 0.4159 0.3544 0.0000\nvt 0.4130 0.3008 0.0000\nvt 0.4428 0.2883 0.0000\nvt 0.4471 0.3381 0.0000\nvt 0.2924 0.5287 0.0000\nvt 0.2326 0.5281 0.0000\nvt 0.2305 0.5063 0.0000\nvt 0.2884 0.5080 0.0000\nvt 0.2943 0.3840 0.0000\nvt 0.2891 0.4163 0.0000\nvt 0.2592 0.4005 0.0000\nvt 0.2614 0.3699 0.0000\nvt 0.2896 0.0878 0.0000\nvt 0.2924 0.1288 0.0000\nvt 0.2612 0.1199 0.0000\nvt 0.2598 0.0777 0.0000\nvt 0.3014 0.2872 0.0000\nvt 0.2990 0.3402 0.0000\nvt 0.2634 0.3288 0.0000\nvt 0.2643 0.2788 0.0000\nvt 0.2154 0.8214 0.0000\nvt 0.2141 0.8378 0.0000\nvt 0.1842 0.8372 0.0000\nvt 0.1846 0.8212 0.0000\nvt 0.2628 0.1695 0.0000\nvt 0.2965 0.1772 0.0000\nvt 0.3004 0.2312 0.0000\nvt 0.2641 0.2242 0.0000\nvt 0.3309 0.1911 0.0000\nvt 0.3627 0.2053 0.0000\nvt 0.3727 0.2508 0.0000\nvt 0.3371 0.2421 0.0000\nvt 0.3854 0.2042 0.0000\nvt 0.4016 0.1878 0.0000\nvt 0.4282 0.2356 0.0000\nvt 0.4034 0.2483 0.0000\nvt 0.3114 0.8422 0.0000\nvt 0.2572 0.8395 0.0000\nvt 0.2597 0.8221 0.0000\nvt 0.3506 0.5296 0.0000\nvt 0.4076 0.6555 0.0000\nvt 0.0397 0.5022 0.0000\nvt 0.0328 0.5267 0.0000\nvt 0.4104 0.6827 0.0000\nvt 0.1012 0.5048 0.0000\nvt 0.1674 0.5055 0.0000\nvt 0.1670 0.5278 0.0000\nvt 0.0977 0.5276 0.0000\nvt 0.3003 0.6511 0.0000\nvt 0.3534 0.6523 0.0000\nvt 0.3541 0.6816 0.0000\nvt 0.2997 0.6812 0.0000\nvt 0.4282 0.1606 0.0000\nvt 0.2262 0.4864 0.0000\nvt 0.4486 0.2231 0.0000\nvt 0.4159 0.1718 0.0000\nvt 0.2311 0.6509 0.0000\nvt 0.2591 0.6508 0.0000\nvt 0.2582 0.6811 0.0000\nvt 0.2307 0.6812 0.0000\nvt 0.2585 0.0150 0.0000\nvt 0.2877 0.0282 0.0000\nvt 0.2880 0.0542 0.0000\nvt 0.2589 0.0426 0.0000\nvt 0.8808 0.1235 0.0000\nvt 0.8346 0.0817 0.0000\nvt 0.8368 0.0598 0.0000\nvt 0.8877 0.1075 0.0000\nvt 0.9620 0.3709 0.0000\nvt 0.9757 0.3896 0.0000\nvt 0.9358 0.4281 0.0000\nvt 0.9281 0.3980 0.0000\nvt 0.8335 0.1106 0.0000\nvt 0.8735 0.1454 0.0000\nvt 0.8677 0.1719 0.0000\nvt 0.8343 0.1470 0.0000\nvt 0.8477 0.2980 0.0000\nvt 0.8859 0.3048 0.0000\nvt 0.8857 0.3604 0.0000\nvt 0.8454 0.3535 0.0000\nvt 0.9752 0.2782 0.0000\nvt 0.5804 0.4860 0.0000\nvt 0.5195 0.4846 0.0000\nvt 0.9779 0.3308 0.0000\nvt 0.8852 0.4077 0.0000\nvt 0.8865 0.4427 0.0000\nvt 0.8372 0.4347 0.0000\nvt 0.8412 0.4001 0.0000\nvt 0.9238 0.3544 0.0000\nvt 0.9209 0.3008 0.0000\nvt 0.9507 0.2883 0.0000\nvt 0.9551 0.3381 0.0000\nvt 0.7058 0.5286 0.0000\nvt 0.6460 0.5281 0.0000\nvt 0.6438 0.5067 0.0000\nvt 0.7017 0.5081 0.0000\nvt 0.8022 0.3840 0.0000\nvt 0.7970 0.4163 0.0000\nvt 0.7672 0.4005 0.0000\nvt 0.7694 0.3699 0.0000\nvt 0.7975 0.0878 0.0000\nvt 0.8004 0.1288 0.0000\nvt 0.7691 0.1199 0.0000\nvt 0.7678 0.0777 0.0000\nvt 0.8094 0.2872 0.0000\nvt 0.8069 0.3402 0.0000\nvt 0.7713 0.3288 0.0000\nvt 0.7723 0.2788 0.0000\nvt 0.1276 0.8052 0.0000\nvt 0.1289 0.7888 0.0000\nvt 0.1588 0.7894 0.0000\nvt 0.1584 0.8054 0.0000\nvt 0.7707 0.1695 0.0000\nvt 0.8044 0.1772 0.0000\nvt 0.8083 0.2312 0.0000\nvt 0.7720 0.2242 0.0000\nvt 0.8388 0.1911 0.0000\nvt 0.8707 0.2053 0.0000\nvt 0.8806 0.2508 0.0000\nvt 0.8451 0.2421 0.0000\nvt 0.8933 0.2042 0.0000\nvt 0.9096 0.1878 0.0000\nvt 0.9362 0.2356 0.0000\nvt 0.9114 0.2483 0.0000\nvt 0.0315 0.7845 0.0000\nvt 0.0857 0.7871 0.0000\nvt 0.0833 0.8045 0.0000\nvt 0.7640 0.5294 0.0000\nvt 0.0311 0.7383 0.0000\nvt 0.4530 0.5020 0.0000\nvt 0.4462 0.5264 0.0000\nvt 0.0283 0.7111 0.0000\nvt 0.5145 0.5049 0.0000\nvt 0.5808 0.5059 0.0000\nvt 0.5804 0.5278 0.0000\nvt 0.5110 0.5275 0.0000\nvt 0.1385 0.7427 0.0000\nvt 0.0854 0.7415 0.0000\nvt 0.0847 0.7122 0.0000\nvt 0.1390 0.7126 0.0000\nvt 0.9361 0.1606 0.0000\nvt 0.6395 0.4872 0.0000\nvt 0.9566 0.2231 0.0000\nvt 0.9238 0.1718 0.0000\nvt 0.2076 0.7429 0.0000\nvt 0.1796 0.7430 0.0000\nvt 0.1805 0.7127 0.0000\nvt 0.2080 0.7126 0.0000\nvt 0.7665 0.0150 0.0000\nvt 0.7956 0.0282 0.0000\nvt 0.7960 0.0542 0.0000\nvt 0.7669 0.0426 0.0000\nvt 0.6272 0.1235 0.0000\nvt 0.6202 0.1075 0.0000\nvt 0.6711 0.0598 0.0000\nvt 0.6733 0.0817 0.0000\nvt 0.5459 0.3709 0.0000\nvt 0.5798 0.3980 0.0000\nvt 0.5722 0.4281 0.0000\nvt 0.5322 0.3896 0.0000\nvt 0.6745 0.1106 0.0000\nvt 0.6736 0.1470 0.0000\nvt 0.6403 0.1719 0.0000\nvt 0.6344 0.1454 0.0000\nvt 0.6603 0.2980 0.0000\nvt 0.6626 0.3535 0.0000\nvt 0.6223 0.3604 0.0000\nvt 0.6220 0.3048 0.0000\nvt 0.5327 0.2782 0.0000\nvt 0.5300 0.3308 0.0000\nvt 0.1062 0.5939 0.0000\nvt 0.1670 0.5925 0.0000\nvt 0.6227 0.4077 0.0000\nvt 0.6667 0.4001 0.0000\nvt 0.6707 0.4347 0.0000\nvt 0.6214 0.4427 0.0000\nvt 0.5841 0.3544 0.0000\nvt 0.5529 0.3381 0.0000\nvt 0.5572 0.2883 0.0000\nvt 0.5870 0.3008 0.0000\nvt 0.2924 0.5499 0.0000\nvt 0.2884 0.5705 0.0000\nvt 0.2305 0.5719 0.0000\nvt 0.2326 0.5504 0.0000\nvt 0.7057 0.3840 0.0000\nvt 0.7386 0.3699 0.0000\nvt 0.7408 0.4005 0.0000\nvt 0.7109 0.4163 0.0000\nvt 0.7104 0.0878 0.0000\nvt 0.7402 0.0777 0.0000\nvt 0.7388 0.1199 0.0000\nvt 0.7076 0.1288 0.0000\nvt 0.6986 0.2872 0.0000\nvt 0.7357 0.2788 0.0000\nvt 0.7366 0.3288 0.0000\nvt 0.7010 0.3402 0.0000\nvt 0.2154 0.8052 0.0000\nvt 0.1846 0.8054 0.0000\nvt 0.1842 0.7894 0.0000\nvt 0.2141 0.7888 0.0000\nvt 0.7372 0.1695 0.0000\nvt 0.7359 0.2242 0.0000\nvt 0.6996 0.2312 0.0000\nvt 0.7035 0.1772 0.0000\nvt 0.6691 0.1911 0.0000\nvt 0.6629 0.2421 0.0000\nvt 0.6273 0.2508 0.0000\nvt 0.6373 0.2053 0.0000\nvt 0.6146 0.2042 0.0000\nvt 0.5966 0.2483 0.0000\nvt 0.5718 0.2356 0.0000\nvt 0.5984 0.1878 0.0000\nvt 0.3114 0.7845 0.0000\nvt 0.3506 0.5491 0.0000\nvt 0.2597 0.8045 0.0000\nvt 0.2572 0.7871 0.0000\nvt 0.4076 0.7383 0.0000\nvt 0.4104 0.7111 0.0000\nvt 0.0328 0.5521 0.0000\nvt 0.0397 0.5766 0.0000\nvt 0.1012 0.5737 0.0000\nvt 0.0977 0.5511 0.0000\nvt 0.1670 0.5507 0.0000\nvt 0.1674 0.5726 0.0000\nvt 0.3003 0.7427 0.0000\nvt 0.2997 0.7126 0.0000\nvt 0.3541 0.7122 0.0000\nvt 0.3534 0.7415 0.0000\nvt 0.5718 0.1606 0.0000\nvt 0.5841 0.1718 0.0000\nvt 0.5514 0.2231 0.0000\nvt 0.2262 0.5913 0.0000\nvt 0.2311 0.7429 0.0000\nvt 0.2307 0.7126 0.0000\nvt 0.2582 0.7127 0.0000\nvt 0.2591 0.7430 0.0000\nvt 0.7415 0.0150 0.0000\nvt 0.7411 0.0426 0.0000\nvt 0.7120 0.0542 0.0000\nvt 0.7123 0.0282 0.0000\nvt 0.0967 0.1473 0.0000\nvt 0.1157 0.1148 0.0000\nvt 0.1426 0.1012 0.0000\nvt 0.1229 0.1337 0.0000\nvt 0.0870 0.1340 0.0000\nvt 0.1089 0.1007 0.0000\nvt 0.0343 0.8514 0.0000\nvt 0.1382 0.0822 0.0000\nvt 0.1858 0.0412 0.0000\nvt 0.1644 0.0699 0.0000\nvt 0.1622 0.0503 0.0000\nvt 0.0876 0.8481 0.0000\nvt 0.1862 0.0657 0.0000\nvt 0.1661 0.0952 0.0000\nvt 0.0430 0.3572 0.0000\nvt 0.0532 0.3861 0.0000\nvt 0.0310 0.3813 0.0000\nvt 0.0271 0.3528 0.0000\nvt 0.0746 0.3781 0.0000\nvt 0.0928 0.4055 0.0000\nvt 0.0682 0.4145 0.0000\nvt 0.0599 0.4409 0.0000\nvt 0.0332 0.6424 0.0000\nvt 0.0425 0.4114 0.0000\nvt 0.0882 0.4392 0.0000\nvt 0.0174 0.3972 0.0000\nvt 0.4578 0.5880 0.0000\nvt 0.0077 0.3654 0.0000\nvt 0.4896 0.5948 0.0000\nvt 0.1855 0.0975 0.0000\nvt 0.1664 0.1279 0.0000\nvt 0.1465 0.1268 0.0000\nvt 0.1830 0.1368 0.0000\nvt 0.1640 0.1681 0.0000\nvt 0.1484 0.1590 0.0000\nvt 0.1183 0.1865 0.0000\nvt 0.1298 0.1583 0.0000\nvt 0.1327 0.1870 0.0000\nvt 0.1075 0.1659 0.0000\nvt 0.1717 0.2927 0.0000\nvt 0.1530 0.3263 0.0000\nvt 0.1330 0.3023 0.0000\nvt 0.1529 0.2696 0.0000\nvt 0.1743 0.3472 0.0000\nvt 0.1566 0.3784 0.0000\nvt 0.1345 0.3582 0.0000\nvt 0.0947 0.3593 0.0000\nvt 0.1138 0.3330 0.0000\nvt 0.1149 0.3857 0.0000\nvt 0.0960 0.3045 0.0000\nvt 0.1157 0.2770 0.0000\nvt 0.0364 0.2824 0.0000\nvt 0.0213 0.3057 0.0000\nvt 0.0134 0.2751 0.0000\nvt 0.5798 0.6015 0.0000\nvt 0.0320 0.2502 0.0000\nvt 0.0328 0.3316 0.0000\nvt 0.0115 0.3329 0.0000\nvt 0.5221 0.6030 0.0000\nvt 0.5169 0.5839 0.0000\nvt 0.5497 0.5928 0.0000\nvt 0.5807 0.5826 0.0000\nvt 0.6106 0.5918 0.0000\nvt 0.1371 0.4056 0.0000\nvt 0.1143 0.4266 0.0000\nvt 0.1792 0.3925 0.0000\nvt 0.1609 0.4187 0.0000\nvt 0.1649 0.4494 0.0000\nvt 0.1382 0.6367 0.0000\nvt 0.1388 0.4409 0.0000\nvt 0.1847 0.4260 0.0000\nvt 0.1126 0.4579 0.0000\nvt 0.0859 0.6383 0.0000\nvt 0.0594 0.3467 0.0000\nvt 0.0773 0.3282 0.0000\nvt 0.0463 0.3145 0.0000\nvt 0.0549 0.2614 0.0000\nvt 0.0635 0.2950 0.0000\nvt 0.0826 0.2738 0.0000\nvt 0.7348 0.5493 0.0000\nvt 0.7042 0.5601 0.0000\nvt 0.6763 0.5500 0.0000\nvt 0.7063 0.5391 0.0000\nvt 0.7299 0.5693 0.0000\nvt 0.0033 0.8435 0.0000\nvt 0.6989 0.5802 0.0000\nvt 0.0583 0.1561 0.0000\nvt 0.6732 0.5710 0.0000\nvt 0.6131 0.5721 0.0000\nvt 0.6452 0.5611 0.0000\nvt 0.6420 0.5817 0.0000\nvt 0.6141 0.5503 0.0000\nvt 0.6462 0.5391 0.0000\nvt 0.1952 0.3636 0.0000\nvt 0.2147 0.3759 0.0000\nvt 0.2004 0.4014 0.0000\nvt 0.2296 0.3507 0.0000\nvt 0.2460 0.3675 0.0000\nvt 0.2318 0.3864 0.0000\nvt 0.2340 0.4129 0.0000\nvt 0.2073 0.6363 0.0000\nvt 0.2189 0.4071 0.0000\nvt 0.2460 0.3977 0.0000\nvt 0.2057 0.4297 0.0000\nvt 0.1791 0.6363 0.0000\nvt 0.2034 0.0700 0.0000\nvt 0.2179 0.0813 0.0000\nvt 0.2012 0.1074 0.0000\nvt 0.2327 0.0593 0.0000\nvt 0.2460 0.0766 0.0000\nvt 0.2316 0.0979 0.0000\nvt 0.2301 0.1438 0.0000\nvt 0.2155 0.1232 0.0000\nvt 0.2460 0.1188 0.0000\nvt 0.1977 0.1521 0.0000\nvt 0.1907 0.2592 0.0000\nvt 0.2093 0.2823 0.0000\nvt 0.1915 0.3144 0.0000\nvt 0.2277 0.2518 0.0000\nvt 0.2460 0.2775 0.0000\nvt 0.2281 0.3046 0.0000\nvt 0.2111 0.3336 0.0000\nvt 0.2460 0.3268 0.0000\nvt 0.1273 0.8133 0.0000\nvt 0.1441 0.8213 0.0000\nvt 0.1281 0.8296 0.0000\nvt 0.1075 0.8217 0.0000\nvt 0.1583 0.8133 0.0000\nvt 0.1715 0.8212 0.0000\nvt 0.1586 0.8292 0.0000\nvt 0.1591 0.8453 0.0000\nvt 0.2337 0.0027 0.0000\nvt 0.1451 0.8374 0.0000\nvt 0.1715 0.8372 0.0000\nvt 0.1300 0.8460 0.0000\nvt 0.2046 0.0166 0.0000\nvt 0.1096 0.8385 0.0000\nvt 0.2460 0.1685 0.0000\nvt 0.2286 0.1966 0.0000\nvt 0.2125 0.1725 0.0000\nvt 0.2460 0.2232 0.0000\nvt 0.2099 0.2270 0.0000\nvt 0.1734 0.2364 0.0000\nvt 0.1934 0.2037 0.0000\nvt 0.1784 0.1835 0.0000\nvt 0.1579 0.2158 0.0000\nvt 0.1445 0.1988 0.0000\nvt 0.1368 0.2473 0.0000\nvt 0.1032 0.2514 0.0000\nvt 0.1242 0.2267 0.0000\nvt 0.1166 0.2080 0.0000\nvt 0.0968 0.2250 0.0000\nvt 0.0982 0.1966 0.0000\nvt 0.0756 0.2426 0.0000\nvt 0.0532 0.2287 0.0000\nvt 0.0758 0.2110 0.0000\nvt 0.0831 0.1792 0.0000\nvt 0.0289 0.8328 0.0000\nvt 0.7626 0.5586 0.0000\nvt 0.0593 0.8408 0.0000\nvt 0.7647 0.5391 0.0000\nvt 0.7933 0.5484 0.0000\nvt 0.0567 0.8225 0.0000\nvt 0.0843 0.8308 0.0000\nvt 0.0828 0.8133 0.0000\nvt 0.0577 0.6536 0.0000\nvt 0.0293 0.6688 0.0000\nvt 0.0050 0.6576 0.0000\nvt 0.4243 0.5784 0.0000\nvt 0.0561 0.6821 0.0000\nvt 0.0280 0.6969 0.0000\nvt 0.0009 0.6834 0.0000\nvt 0.4156 0.5526 0.0000\nvt 0.4776 0.5512 0.0000\nvt 0.4488 0.5643 0.0000\nvt 0.4451 0.5391 0.0000\nvt 0.4827 0.5745 0.0000\nvt 0.5125 0.5623 0.0000\nvt 0.5475 0.5728 0.0000\nvt 0.5105 0.5391 0.0000\nvt 0.5457 0.5506 0.0000\nvt 0.5806 0.5616 0.0000\nvt 0.5803 0.5391 0.0000\nvt 0.1613 0.6509 0.0000\nvt 0.1389 0.6658 0.0000\nvt 0.1128 0.6515 0.0000\nvt 0.1620 0.6811 0.0000\nvt 0.1391 0.6969 0.0000\nvt 0.1128 0.6813 0.0000\nvt 0.0849 0.6667 0.0000\nvt 0.0846 0.6969 0.0000\nvt 0.0697 0.1656 0.0000\nvt 0.0418 0.1872 0.0000\nvt 0.6678 0.5902 0.0000\nvt 0.0581 0.1970 0.0000\nvt 0.0338 0.2181 0.0000\nvt 0.6369 0.6001 0.0000\nvt 0.2194 0.6509 0.0000\nvt 0.2079 0.6658 0.0000\nvt 0.1948 0.6509 0.0000\nvt 0.2194 0.6812 0.0000\nvt 0.2080 0.6969 0.0000\nvt 0.1954 0.6812 0.0000\nvt 0.1802 0.6657 0.0000\nvt 0.1805 0.6969 0.0000\nvt 0.2460 0.0135 0.0000\nvt 0.2334 0.0279 0.0000\nvt 0.2200 0.0194 0.0000\nvt 0.2460 0.0414 0.0000\nvt 0.2194 0.0467 0.0000\nvt 0.2043 0.0402 0.0000\nvt 0.3692 0.1337 0.0000\nvt 0.3495 0.1012 0.0000\nvt 0.3763 0.1148 0.0000\nvt 0.3953 0.1473 0.0000\nvt 0.3260 0.0952 0.0000\nvt 0.3059 0.0657 0.0000\nvt 0.3277 0.0699 0.0000\nvt 0.3299 0.0503 0.0000\nvt 0.2553 0.8481 0.0000\nvt 0.3538 0.0822 0.0000\nvt 0.3062 0.0412 0.0000\nvt 0.3832 0.1007 0.0000\nvt 0.3086 0.8515 0.0000\nvt 0.4050 0.1340 0.0000\nvt 0.4650 0.3528 0.0000\nvt 0.4610 0.3813 0.0000\nvt 0.4389 0.3861 0.0000\nvt 0.4490 0.3572 0.0000\nvt 0.4843 0.3654 0.0000\nvt 0.0762 0.4836 0.0000\nvt 0.4747 0.3972 0.0000\nvt 0.0445 0.4904 0.0000\nvt 0.4496 0.4114 0.0000\nvt 0.4038 0.4392 0.0000\nvt 0.4238 0.4145 0.0000\nvt 0.4322 0.4409 0.0000\nvt 0.4055 0.6424 0.0000\nvt 0.3993 0.4055 0.0000\nvt 0.4174 0.3781 0.0000\nvt 0.3456 0.1268 0.0000\nvt 0.3256 0.1279 0.0000\nvt 0.3066 0.0975 0.0000\nvt 0.3846 0.1659 0.0000\nvt 0.3623 0.1583 0.0000\nvt 0.3593 0.1870 0.0000\nvt 0.3436 0.1590 0.0000\nvt 0.3738 0.1865 0.0000\nvt 0.3281 0.1681 0.0000\nvt 0.3090 0.1368 0.0000\nvt 0.3392 0.2696 0.0000\nvt 0.3591 0.3023 0.0000\nvt 0.3390 0.3263 0.0000\nvt 0.3204 0.2927 0.0000\nvt 0.3763 0.2770 0.0000\nvt 0.3961 0.3045 0.0000\nvt 0.3782 0.3330 0.0000\nvt 0.3772 0.3857 0.0000\nvt 0.3576 0.3582 0.0000\nvt 0.3973 0.3593 0.0000\nvt 0.3354 0.3784 0.0000\nvt 0.3178 0.3472 0.0000\nvt 0.4601 0.2502 0.0000\nvt 0.4787 0.2751 0.0000\nvt 0.1665 0.4757 0.0000\nvt 0.4708 0.3057 0.0000\nvt 0.4556 0.2824 0.0000\nvt 0.1973 0.4856 0.0000\nvt 0.1674 0.4950 0.0000\nvt 0.1363 0.4849 0.0000\nvt 0.1088 0.4748 0.0000\nvt 0.4806 0.3329 0.0000\nvt 0.1035 0.4942 0.0000\nvt 0.4593 0.3316 0.0000\nvt 0.3778 0.4266 0.0000\nvt 0.3550 0.4056 0.0000\nvt 0.3795 0.4579 0.0000\nvt 0.3528 0.6383 0.0000\nvt 0.3533 0.4409 0.0000\nvt 0.3074 0.4260 0.0000\nvt 0.3312 0.4187 0.0000\nvt 0.3272 0.4494 0.0000\nvt 0.3005 0.6367 0.0000\nvt 0.3128 0.3925 0.0000\nvt 0.4148 0.3282 0.0000\nvt 0.4327 0.3467 0.0000\nvt 0.4095 0.2738 0.0000\nvt 0.4285 0.2950 0.0000\nvt 0.4458 0.3145 0.0000\nvt 0.4371 0.2614 0.0000\nvt 0.2930 0.5393 0.0000\nvt 0.2630 0.5284 0.0000\nvt 0.2909 0.5182 0.0000\nvt 0.3215 0.5291 0.0000\nvt 0.2329 0.5393 0.0000\nvt 0.2008 0.5279 0.0000\nvt 0.2318 0.5170 0.0000\nvt 0.2287 0.4960 0.0000\nvt 0.2599 0.5070 0.0000\nvt 0.1998 0.5058 0.0000\nvt 0.2855 0.4979 0.0000\nvt 0.4337 0.1561 0.0000\nvt 0.3166 0.5091 0.0000\nvt 0.3396 0.8436 0.0000\nvt 0.2917 0.4014 0.0000\nvt 0.2773 0.3759 0.0000\nvt 0.2968 0.3636 0.0000\nvt 0.2863 0.4297 0.0000\nvt 0.2596 0.6363 0.0000\nvt 0.2732 0.4071 0.0000\nvt 0.2603 0.3864 0.0000\nvt 0.2581 0.4129 0.0000\nvt 0.2314 0.6363 0.0000\nvt 0.2625 0.3507 0.0000\nvt 0.2909 0.1074 0.0000\nvt 0.2742 0.0813 0.0000\nvt 0.2886 0.0700 0.0000\nvt 0.2943 0.1521 0.0000\nvt 0.2766 0.1232 0.0000\nvt 0.2605 0.0979 0.0000\nvt 0.2620 0.1438 0.0000\nvt 0.2593 0.0593 0.0000\nvt 0.3006 0.3144 0.0000\nvt 0.2828 0.2823 0.0000\nvt 0.3014 0.2592 0.0000\nvt 0.2809 0.3336 0.0000\nvt 0.2640 0.3046 0.0000\nvt 0.2644 0.2518 0.0000\nvt 0.2354 0.8217 0.0000\nvt 0.2148 0.8296 0.0000\nvt 0.1988 0.8213 0.0000\nvt 0.2156 0.8133 0.0000\nvt 0.2334 0.8385 0.0000\nvt 0.2129 0.8460 0.0000\nvt 0.2875 0.0166 0.0000\nvt 0.1979 0.8374 0.0000\nvt 0.1844 0.8292 0.0000\nvt 0.1838 0.8453 0.0000\nvt 0.2584 0.0027 0.0000\nvt 0.1847 0.8133 0.0000\nvt 0.2796 0.1725 0.0000\nvt 0.2635 0.1966 0.0000\nvt 0.3136 0.1835 0.0000\nvt 0.2986 0.2037 0.0000\nvt 0.2822 0.2270 0.0000\nvt 0.3187 0.2364 0.0000\nvt 0.3475 0.1988 0.0000\nvt 0.3341 0.2158 0.0000\nvt 0.3755 0.2080 0.0000\nvt 0.3678 0.2267 0.0000\nvt 0.3553 0.2473 0.0000\nvt 0.3889 0.2514 0.0000\nvt 0.3938 0.1966 0.0000\nvt 0.3952 0.2250 0.0000\nvt 0.4090 0.1792 0.0000\nvt 0.4163 0.2110 0.0000\nvt 0.4165 0.2426 0.0000\nvt 0.4389 0.2287 0.0000\nvt 0.2837 0.8408 0.0000\nvt 0.3141 0.8328 0.0000\nvt 0.3492 0.5199 0.0000\nvt 0.2587 0.8308 0.0000\nvt 0.2601 0.8133 0.0000\nvt 0.2863 0.8225 0.0000\nvt 0.3799 0.5302 0.0000\nvt 0.3514 0.5394 0.0000\nvt 0.4337 0.6576 0.0000\nvt 0.0110 0.5001 0.0000\nvt 0.4094 0.6688 0.0000\nvt 0.3810 0.6536 0.0000\nvt 0.0694 0.5038 0.0000\nvt 0.0355 0.5142 0.0000\nvt 0.0318 0.5394 0.0000\nvt 0.0023 0.5259 0.0000\nvt 0.4378 0.6834 0.0000\nvt 0.0643 0.5273 0.0000\nvt 0.4108 0.6969 0.0000\nvt 0.3826 0.6821 0.0000\nvt 0.1342 0.5053 0.0000\nvt 0.0992 0.5160 0.0000\nvt 0.1673 0.5165 0.0000\nvt 0.1669 0.5393 0.0000\nvt 0.1323 0.5277 0.0000\nvt 0.0972 0.5393 0.0000\nvt 0.3259 0.6515 0.0000\nvt 0.2999 0.6658 0.0000\nvt 0.2775 0.6509 0.0000\nvt 0.3538 0.6667 0.0000\nvt 0.3542 0.6969 0.0000\nvt 0.3259 0.6813 0.0000\nvt 0.2997 0.6969 0.0000\nvt 0.2767 0.6811 0.0000\nvt 0.4502 0.1872 0.0000\nvt 0.2545 0.4874 0.0000\nvt 0.4224 0.1656 0.0000\nvt 0.2236 0.4771 0.0000\nvt 0.4583 0.2181 0.0000\nvt 0.4339 0.1970 0.0000\nvt 0.2439 0.6509 0.0000\nvt 0.2309 0.6658 0.0000\nvt 0.2585 0.6657 0.0000\nvt 0.2582 0.6969 0.0000\nvt 0.2433 0.6812 0.0000\nvt 0.2307 0.6969 0.0000\nvt 0.2720 0.0194 0.0000\nvt 0.2587 0.0279 0.0000\nvt 0.2877 0.0402 0.0000\nvt 0.2727 0.0467 0.0000\nvt 0.8771 0.1337 0.0000\nvt 0.8574 0.1012 0.0000\nvt 0.8843 0.1148 0.0000\nvt 0.9033 0.1473 0.0000\nvt 0.8339 0.0952 0.0000\nvt 0.8138 0.0657 0.0000\nvt 0.8356 0.0699 0.0000\nvt 0.8378 0.0503 0.0000\nvt 0.0876 0.7785 0.0000\nvt 0.8618 0.0822 0.0000\nvt 0.8142 0.0412 0.0000\nvt 0.8911 0.1007 0.0000\nvt 0.0343 0.7752 0.0000\nvt 0.9130 0.1340 0.0000\nvt 0.9729 0.3528 0.0000\nvt 0.9690 0.3813 0.0000\nvt 0.9468 0.3861 0.0000\nvt 0.9570 0.3572 0.0000\nvt 0.9923 0.3654 0.0000\nvt 0.4896 0.4835 0.0000\nvt 0.9826 0.3972 0.0000\nvt 0.4578 0.4902 0.0000\nvt 0.9575 0.4114 0.0000\nvt 0.9118 0.4392 0.0000\nvt 0.9318 0.4145 0.0000\nvt 0.9401 0.4409 0.0000\nvt 0.0332 0.7514 0.0000\nvt 0.9072 0.4055 0.0000\nvt 0.9254 0.3781 0.0000\nvt 0.8535 0.1268 0.0000\nvt 0.8336 0.1279 0.0000\nvt 0.8145 0.0975 0.0000\nvt 0.8925 0.1659 0.0000\nvt 0.8702 0.1583 0.0000\nvt 0.8673 0.1870 0.0000\nvt 0.8516 0.1590 0.0000\nvt 0.8817 0.1865 0.0000\nvt 0.8360 0.1681 0.0000\nvt 0.8170 0.1368 0.0000\nvt 0.8471 0.2696 0.0000\nvt 0.8670 0.3023 0.0000\nvt 0.8470 0.3263 0.0000\nvt 0.8283 0.2927 0.0000\nvt 0.8843 0.2770 0.0000\nvt 0.9040 0.3045 0.0000\nvt 0.8862 0.3330 0.0000\nvt 0.8851 0.3857 0.0000\nvt 0.8655 0.3582 0.0000\nvt 0.9053 0.3593 0.0000\nvt 0.8434 0.3784 0.0000\nvt 0.8257 0.3472 0.0000\nvt 0.9680 0.2502 0.0000\nvt 0.9866 0.2751 0.0000\nvt 0.5798 0.4768 0.0000\nvt 0.9787 0.3057 0.0000\nvt 0.9636 0.2824 0.0000\nvt 0.6106 0.4865 0.0000\nvt 0.5807 0.4956 0.0000\nvt 0.5497 0.4855 0.0000\nvt 0.5221 0.4753 0.0000\nvt 0.9885 0.3329 0.0000\nvt 0.5169 0.4944 0.0000\nvt 0.9672 0.3316 0.0000\nvt 0.8857 0.4266 0.0000\nvt 0.8629 0.4056 0.0000\nvt 0.8874 0.4579 0.0000\nvt 0.0859 0.7555 0.0000\nvt 0.8612 0.4409 0.0000\nvt 0.8153 0.4260 0.0000\nvt 0.8391 0.4187 0.0000\nvt 0.8351 0.4494 0.0000\nvt 0.1382 0.7571 0.0000\nvt 0.8208 0.3925 0.0000\nvt 0.9227 0.3282 0.0000\nvt 0.9406 0.3467 0.0000\nvt 0.9174 0.2738 0.0000\nvt 0.9365 0.2950 0.0000\nvt 0.9537 0.3145 0.0000\nvt 0.9451 0.2614 0.0000\nvt 0.6763 0.5283 0.0000\nvt 0.7042 0.5182 0.0000\nvt 0.7348 0.5289 0.0000\nvt 0.6141 0.5279 0.0000\nvt 0.6452 0.5172 0.0000\nvt 0.6420 0.4966 0.0000\nvt 0.6732 0.5073 0.0000\nvt 0.6131 0.5062 0.0000\nvt 0.6989 0.4981 0.0000\nvt 0.9417 0.1561 0.0000\nvt 0.7299 0.5089 0.0000\nvt 0.0033 0.7831 0.0000\nvt 0.7996 0.4014 0.0000\nvt 0.7853 0.3759 0.0000\nvt 0.8048 0.3636 0.0000\nvt 0.7943 0.4297 0.0000\nvt 0.1791 0.7575 0.0000\nvt 0.7811 0.4071 0.0000\nvt 0.7540 0.3977 0.0000\nvt 0.7682 0.3864 0.0000\nvt 0.7660 0.4129 0.0000\nvt 0.2073 0.7575 0.0000\nvt 0.7540 0.3675 0.0000\nvt 0.7704 0.3507 0.0000\nvt 0.7988 0.1074 0.0000\nvt 0.7821 0.0813 0.0000\nvt 0.7966 0.0700 0.0000\nvt 0.8023 0.1521 0.0000\nvt 0.7845 0.1232 0.0000\nvt 0.7540 0.1188 0.0000\nvt 0.7684 0.0979 0.0000\nvt 0.7699 0.1438 0.0000\nvt 0.7540 0.0766 0.0000\nvt 0.7673 0.0593 0.0000\nvt 0.8085 0.3144 0.0000\nvt 0.7907 0.2823 0.0000\nvt 0.8093 0.2592 0.0000\nvt 0.7889 0.3336 0.0000\nvt 0.7540 0.3268 0.0000\nvt 0.7719 0.3046 0.0000\nvt 0.7540 0.2775 0.0000\nvt 0.7723 0.2518 0.0000\nvt 0.1075 0.8049 0.0000\nvt 0.1281 0.7970 0.0000\nvt 0.1441 0.8053 0.0000\nvt 0.1096 0.7881 0.0000\nvt 0.1300 0.7806 0.0000\nvt 0.7954 0.0166 0.0000\nvt 0.1451 0.7892 0.0000\nvt 0.1715 0.7894 0.0000\nvt 0.1586 0.7974 0.0000\nvt 0.1591 0.7813 0.0000\nvt 0.7663 0.0027 0.0000\nvt 0.1715 0.8054 0.0000\nvt 0.7875 0.1725 0.0000\nvt 0.7714 0.1966 0.0000\nvt 0.7540 0.1685 0.0000\nvt 0.8216 0.1835 0.0000\nvt 0.8066 0.2037 0.0000\nvt 0.7901 0.2270 0.0000\nvt 0.8266 0.2364 0.0000\nvt 0.7540 0.2232 0.0000\nvt 0.8555 0.1988 0.0000\nvt 0.8421 0.2158 0.0000\nvt 0.8834 0.2080 0.0000\nvt 0.8758 0.2267 0.0000\nvt 0.8632 0.2473 0.0000\nvt 0.8968 0.2514 0.0000\nvt 0.9018 0.1966 0.0000\nvt 0.9032 0.2250 0.0000\nvt 0.9169 0.1792 0.0000\nvt 0.9242 0.2110 0.0000\nvt 0.9244 0.2426 0.0000\nvt 0.9468 0.2287 0.0000\nvt 0.0593 0.7858 0.0000\nvt 0.0289 0.7938 0.0000\nvt 0.7626 0.5196 0.0000\nvt 0.0843 0.7958 0.0000\nvt 0.0567 0.8041 0.0000\nvt 0.7933 0.5299 0.0000\nvt 0.0050 0.7362 0.0000\nvt 0.4243 0.4999 0.0000\nvt 0.0293 0.7250 0.0000\nvt 0.0577 0.7402 0.0000\nvt 0.4827 0.5037 0.0000\nvt 0.4488 0.5140 0.0000\nvt 0.4156 0.5257 0.0000\nvt 0.0009 0.7104 0.0000\nvt 0.4776 0.5271 0.0000\nvt 0.0561 0.7117 0.0000\nvt 0.5475 0.5055 0.0000\nvt 0.5125 0.5160 0.0000\nvt 0.5806 0.5167 0.0000\nvt 0.5457 0.5277 0.0000\nvt 0.1128 0.7423 0.0000\nvt 0.1389 0.7280 0.0000\nvt 0.1613 0.7429 0.0000\nvt 0.0849 0.7271 0.0000\nvt 0.1128 0.7125 0.0000\nvt 0.1620 0.7127 0.0000\nvt 0.9582 0.1872 0.0000\nvt 0.6678 0.4880 0.0000\nvt 0.9303 0.1656 0.0000\nvt 0.6369 0.4782 0.0000\nvt 0.9662 0.2181 0.0000\nvt 0.9419 0.1970 0.0000\nvt 0.1948 0.7429 0.0000\nvt 0.2079 0.7280 0.0000\nvt 0.2194 0.7429 0.0000\nvt 0.1802 0.7281 0.0000\nvt 0.1954 0.7126 0.0000\nvt 0.2194 0.7126 0.0000\nvt 0.7800 0.0194 0.0000\nvt 0.7666 0.0279 0.0000\nvt 0.7540 0.0135 0.0000\nvt 0.7957 0.0402 0.0000\nvt 0.7806 0.0467 0.0000\nvt 0.7540 0.0414 0.0000\nvt 0.6047 0.1473 0.0000\nvt 0.6237 0.1148 0.0000\nvt 0.6505 0.1012 0.0000\nvt 0.6308 0.1337 0.0000\nvt 0.5950 0.1340 0.0000\nvt 0.6168 0.1007 0.0000\nvt 0.3086 0.7752 0.0000\nvt 0.6462 0.0822 0.0000\nvt 0.6938 0.0412 0.0000\nvt 0.6723 0.0699 0.0000\nvt 0.6701 0.0503 0.0000\nvt 0.2553 0.7785 0.0000\nvt 0.6941 0.0657 0.0000\nvt 0.6740 0.0952 0.0000\nvt 0.5510 0.3572 0.0000\nvt 0.5611 0.3861 0.0000\nvt 0.5390 0.3813 0.0000\nvt 0.5350 0.3528 0.0000\nvt 0.5826 0.3781 0.0000\nvt 0.6007 0.4055 0.0000\nvt 0.5762 0.4145 0.0000\nvt 0.5678 0.4409 0.0000\nvt 0.4055 0.7514 0.0000\nvt 0.5504 0.4114 0.0000\nvt 0.5962 0.4392 0.0000\nvt 0.5253 0.3972 0.0000\nvt 0.0445 0.5883 0.0000\nvt 0.5157 0.3654 0.0000\nvt 0.0762 0.5950 0.0000\nvt 0.6934 0.0975 0.0000\nvt 0.6744 0.1279 0.0000\nvt 0.6544 0.1268 0.0000\nvt 0.6910 0.1368 0.0000\nvt 0.6719 0.1681 0.0000\nvt 0.6564 0.1590 0.0000\nvt 0.6262 0.1865 0.0000\nvt 0.6377 0.1583 0.0000\nvt 0.6407 0.1870 0.0000\nvt 0.6154 0.1659 0.0000\nvt 0.6796 0.2927 0.0000\nvt 0.6610 0.3263 0.0000\nvt 0.6409 0.3023 0.0000\nvt 0.6608 0.2696 0.0000\nvt 0.6822 0.3472 0.0000\nvt 0.6646 0.3784 0.0000\nvt 0.6424 0.3582 0.0000\nvt 0.6027 0.3593 0.0000\nvt 0.6218 0.3330 0.0000\nvt 0.6228 0.3857 0.0000\nvt 0.6039 0.3045 0.0000\nvt 0.6237 0.2770 0.0000\nvt 0.5444 0.2824 0.0000\nvt 0.5292 0.3057 0.0000\nvt 0.5213 0.2751 0.0000\nvt 0.1665 0.6018 0.0000\nvt 0.5399 0.2502 0.0000\nvt 0.5407 0.3316 0.0000\nvt 0.5194 0.3329 0.0000\nvt 0.1088 0.6033 0.0000\nvt 0.1035 0.5842 0.0000\nvt 0.1363 0.5930 0.0000\nvt 0.1674 0.5829 0.0000\nvt 0.1973 0.5920 0.0000\nvt 0.6450 0.4056 0.0000\nvt 0.6222 0.4266 0.0000\nvt 0.6872 0.3925 0.0000\nvt 0.6688 0.4187 0.0000\nvt 0.6728 0.4494 0.0000\nvt 0.3005 0.7571 0.0000\nvt 0.6467 0.4409 0.0000\nvt 0.6926 0.4260 0.0000\nvt 0.6205 0.4579 0.0000\nvt 0.3528 0.7555 0.0000\nvt 0.5673 0.3467 0.0000\nvt 0.5852 0.3282 0.0000\nvt 0.5542 0.3145 0.0000\nvt 0.5629 0.2614 0.0000\nvt 0.5715 0.2950 0.0000\nvt 0.5905 0.2738 0.0000\nvt 0.3215 0.5496 0.0000\nvt 0.2909 0.5604 0.0000\nvt 0.2630 0.5502 0.0000\nvt 0.3166 0.5696 0.0000\nvt 0.3396 0.7831 0.0000\nvt 0.2855 0.5805 0.0000\nvt 0.5663 0.1561 0.0000\nvt 0.2599 0.5713 0.0000\nvt 0.1998 0.5723 0.0000\nvt 0.2318 0.5613 0.0000\nvt 0.2287 0.5819 0.0000\nvt 0.2008 0.5505 0.0000\nvt 0.7032 0.3636 0.0000\nvt 0.7227 0.3759 0.0000\nvt 0.7083 0.4014 0.0000\nvt 0.7375 0.3507 0.0000\nvt 0.7397 0.3864 0.0000\nvt 0.7419 0.4129 0.0000\nvt 0.2314 0.7575 0.0000\nvt 0.7268 0.4071 0.0000\nvt 0.7137 0.4297 0.0000\nvt 0.2596 0.7575 0.0000\nvt 0.7114 0.0700 0.0000\nvt 0.7258 0.0813 0.0000\nvt 0.7091 0.1074 0.0000\nvt 0.7407 0.0593 0.0000\nvt 0.7395 0.0979 0.0000\nvt 0.7380 0.1438 0.0000\nvt 0.7234 0.1232 0.0000\nvt 0.7057 0.1521 0.0000\nvt 0.6986 0.2592 0.0000\nvt 0.7172 0.2823 0.0000\nvt 0.6994 0.3144 0.0000\nvt 0.7356 0.2518 0.0000\nvt 0.7360 0.3046 0.0000\nvt 0.7191 0.3336 0.0000\nvt 0.1988 0.8053 0.0000\nvt 0.2148 0.7970 0.0000\nvt 0.2354 0.8049 0.0000\nvt 0.1844 0.7974 0.0000\nvt 0.1838 0.7813 0.0000\nvt 0.7416 0.0027 0.0000\nvt 0.1979 0.7892 0.0000\nvt 0.2129 0.7806 0.0000\nvt 0.7125 0.0166 0.0000\nvt 0.2334 0.7881 0.0000\nvt 0.7365 0.1966 0.0000\nvt 0.7204 0.1725 0.0000\nvt 0.7178 0.2270 0.0000\nvt 0.6813 0.2364 0.0000\nvt 0.7014 0.2037 0.0000\nvt 0.6864 0.1835 0.0000\nvt 0.6659 0.2158 0.0000\nvt 0.6525 0.1988 0.0000\nvt 0.6447 0.2473 0.0000\nvt 0.6111 0.2514 0.0000\nvt 0.6322 0.2267 0.0000\nvt 0.6245 0.2080 0.0000\nvt 0.6048 0.2250 0.0000\nvt 0.6062 0.1966 0.0000\nvt 0.5835 0.2426 0.0000\nvt 0.5611 0.2287 0.0000\nvt 0.5837 0.2110 0.0000\nvt 0.5910 0.1792 0.0000\nvt 0.3141 0.7938 0.0000\nvt 0.3492 0.5589 0.0000\nvt 0.2837 0.7858 0.0000\nvt 0.3799 0.5487 0.0000\nvt 0.2863 0.8041 0.0000\nvt 0.2587 0.7958 0.0000\nvt 0.3810 0.7402 0.0000\nvt 0.4094 0.7250 0.0000\nvt 0.4337 0.7362 0.0000\nvt 0.0110 0.5787 0.0000\nvt 0.3826 0.7117 0.0000\nvt 0.4378 0.7104 0.0000\nvt 0.0023 0.5529 0.0000\nvt 0.0643 0.5515 0.0000\nvt 0.0355 0.5646 0.0000\nvt 0.0694 0.5748 0.0000\nvt 0.0992 0.5626 0.0000\nvt 0.1342 0.5730 0.0000\nvt 0.1323 0.5508 0.0000\nvt 0.1673 0.5618 0.0000\nvt 0.2775 0.7429 0.0000\nvt 0.2999 0.7280 0.0000\nvt 0.3259 0.7423 0.0000\nvt 0.2767 0.7127 0.0000\nvt 0.3259 0.7125 0.0000\nvt 0.3538 0.7271 0.0000\nvt 0.5776 0.1656 0.0000\nvt 0.5498 0.1872 0.0000\nvt 0.2545 0.5905 0.0000\nvt 0.5661 0.1970 0.0000\nvt 0.5417 0.2181 0.0000\nvt 0.2236 0.6004 0.0000\nvt 0.2309 0.7280 0.0000\nvt 0.2439 0.7429 0.0000\nvt 0.2433 0.7126 0.0000\nvt 0.2585 0.7281 0.0000\nvt 0.7413 0.0279 0.0000\nvt 0.7280 0.0194 0.0000\nvt 0.7273 0.0467 0.0000\nvt 0.7123 0.0402 0.0000\nvt 0.1100 0.1397 0.0000\nvt 0.1056 0.1311 0.0000\nvt 0.1295 0.1072 0.0000\nvt 0.1323 0.1174 0.0000\nvt 0.1015 0.1239 0.0000\nvt 0.0973 0.1176 0.0000\nvt 0.1240 0.0907 0.0000\nvt 0.1266 0.0985 0.0000\nvt 0.1749 0.0445 0.0000\nvt 0.1752 0.0552 0.0000\nvt 0.1517 0.0752 0.0000\nvt 0.1501 0.0661 0.0000\nvt 0.1759 0.0667 0.0000\nvt 0.1762 0.0801 0.0000\nvt 0.1548 0.0972 0.0000\nvt 0.1534 0.0853 0.0000\nvt 0.0353 0.3575 0.0000\nvt 0.0476 0.3715 0.0000\nvt 0.0422 0.3853 0.0000\nvt 0.0277 0.3668 0.0000\nvt 0.0640 0.3836 0.0000\nvt 0.0833 0.3924 0.0000\nvt 0.0807 0.4115 0.0000\nvt 0.0600 0.4006 0.0000\nvt 0.0743 0.4418 0.0000\nvt 0.0502 0.4265 0.0000\nvt 0.0555 0.4143 0.0000\nvt 0.0777 0.4273 0.0000\nvt 0.0296 0.4058 0.0000\nvt 0.0123 0.3806 0.0000\nvt 0.0195 0.3745 0.0000\nvt 0.0362 0.3961 0.0000\nvt 0.1763 0.0953 0.0000\nvt 0.1760 0.1124 0.0000\nvt 0.1570 0.1263 0.0000\nvt 0.1561 0.1109 0.0000\nvt 0.1751 0.1314 0.0000\nvt 0.1735 0.1523 0.0000\nvt 0.1564 0.1626 0.0000\nvt 0.1572 0.1436 0.0000\nvt 0.1264 0.1846 0.0000\nvt 0.1232 0.1730 0.0000\nvt 0.1396 0.1574 0.0000\nvt 0.1403 0.1736 0.0000\nvt 0.1190 0.1612 0.0000\nvt 0.1145 0.1499 0.0000\nvt 0.1351 0.1293 0.0000\nvt 0.1376 0.1428 0.0000\nvt 0.1620 0.2811 0.0000\nvt 0.1623 0.3096 0.0000\nvt 0.1428 0.3146 0.0000\nvt 0.1428 0.2861 0.0000\nvt 0.1636 0.3373 0.0000\nvt 0.1656 0.3632 0.0000\nvt 0.1454 0.3690 0.0000\nvt 0.1438 0.3426 0.0000\nvt 0.1045 0.3732 0.0000\nvt 0.1043 0.3469 0.0000\nvt 0.1239 0.3461 0.0000\nvt 0.1249 0.3727 0.0000\nvt 0.1045 0.3191 0.0000\nvt 0.1057 0.2911 0.0000\nvt 0.1239 0.2897 0.0000\nvt 0.1234 0.3180 0.0000\nvt 0.0335 0.2663 0.0000\nvt 0.0284 0.2937 0.0000\nvt 0.0165 0.2910 0.0000\nvt 0.0222 0.2622 0.0000\nvt 0.0268 0.3192 0.0000\nvt 0.0286 0.3408 0.0000\nvt 0.0188 0.3444 0.0000\nvt 0.0153 0.3186 0.0000\nvt 0.5027 0.5894 0.0000\nvt 0.5336 0.5884 0.0000\nvt 0.5353 0.5978 0.0000\nvt 0.5063 0.5989 0.0000\nvt 0.5649 0.5877 0.0000\nvt 0.5961 0.5873 0.0000\nvt 0.5952 0.5967 0.0000\nvt 0.5650 0.5971 0.0000\nvt 0.1042 0.3967 0.0000\nvt 0.1257 0.3965 0.0000\nvt 0.1261 0.4170 0.0000\nvt 0.1031 0.4169 0.0000\nvt 0.1472 0.3926 0.0000\nvt 0.1680 0.3862 0.0000\nvt 0.1705 0.4061 0.0000\nvt 0.1488 0.4130 0.0000\nvt 0.1756 0.4378 0.0000\nvt 0.1517 0.4460 0.0000\nvt 0.1503 0.4303 0.0000\nvt 0.1729 0.4230 0.0000\nvt 0.1263 0.4502 0.0000\nvt 0.0998 0.4497 0.0000\nvt 0.1016 0.4339 0.0000\nvt 0.1262 0.4345 0.0000\nvt 0.0849 0.3698 0.0000\nvt 0.0667 0.3627 0.0000\nvt 0.0682 0.3382 0.0000\nvt 0.0856 0.3442 0.0000\nvt 0.0509 0.3532 0.0000\nvt 0.0384 0.3439 0.0000\nvt 0.0389 0.3233 0.0000\nvt 0.0526 0.3306 0.0000\nvt 0.0453 0.2716 0.0000\nvt 0.0584 0.2782 0.0000\nvt 0.0546 0.3050 0.0000\nvt 0.0408 0.2984 0.0000\nvt 0.0729 0.2845 0.0000\nvt 0.0886 0.2893 0.0000\nvt 0.0866 0.3169 0.0000\nvt 0.0699 0.3117 0.0000\nvt 0.7207 0.5443 0.0000\nvt 0.7197 0.5547 0.0000\nvt 0.6905 0.5551 0.0000\nvt 0.6915 0.5445 0.0000\nvt 0.7174 0.5648 0.0000\nvt 0.7142 0.5747 0.0000\nvt 0.6864 0.5757 0.0000\nvt 0.6887 0.5655 0.0000\nvt 0.6280 0.5770 0.0000\nvt 0.6292 0.5666 0.0000\nvt 0.6595 0.5661 0.0000\nvt 0.6577 0.5765 0.0000\nvt 0.6300 0.5558 0.0000\nvt 0.6304 0.5447 0.0000\nvt 0.6616 0.5446 0.0000\nvt 0.6609 0.5555 0.0000\nvt 0.1874 0.3783 0.0000\nvt 0.2052 0.3701 0.0000\nvt 0.2076 0.3887 0.0000\nvt 0.1901 0.3975 0.0000\nvt 0.2220 0.3632 0.0000\nvt 0.2381 0.3589 0.0000\nvt 0.2386 0.3767 0.0000\nvt 0.2236 0.3812 0.0000\nvt 0.2398 0.4044 0.0000\nvt 0.2270 0.4098 0.0000\nvt 0.2252 0.3966 0.0000\nvt 0.2392 0.3919 0.0000\nvt 0.2125 0.4180 0.0000\nvt 0.1959 0.4282 0.0000\nvt 0.1928 0.4138 0.0000\nvt 0.2100 0.4045 0.0000\nvt 0.1946 0.0833 0.0000\nvt 0.2109 0.0749 0.0000\nvt 0.2098 0.0938 0.0000\nvt 0.1937 0.1016 0.0000\nvt 0.2255 0.0697 0.0000\nvt 0.2393 0.0674 0.0000\nvt 0.2390 0.0867 0.0000\nvt 0.2247 0.0890 0.0000\nvt 0.2383 0.1308 0.0000\nvt 0.2227 0.1330 0.0000\nvt 0.2238 0.1100 0.0000\nvt 0.2387 0.1078 0.0000\nvt 0.2068 0.1373 0.0000\nvt 0.1905 0.1437 0.0000\nvt 0.1923 0.1217 0.0000\nvt 0.2084 0.1146 0.0000\nvt 0.1811 0.2758 0.0000\nvt 0.1999 0.2708 0.0000\nvt 0.2003 0.2982 0.0000\nvt 0.1815 0.3038 0.0000\nvt 0.2184 0.2668 0.0000\nvt 0.2368 0.2645 0.0000\nvt 0.2369 0.2908 0.0000\nvt 0.2187 0.2936 0.0000\nvt 0.2376 0.3385 0.0000\nvt 0.2206 0.3423 0.0000\nvt 0.2194 0.3189 0.0000\nvt 0.2372 0.3156 0.0000\nvt 0.2031 0.3486 0.0000\nvt 0.1849 0.3560 0.0000\nvt 0.1828 0.3309 0.0000\nvt 0.2014 0.3244 0.0000\nvt 0.1179 0.8174 0.0000\nvt 0.1361 0.8173 0.0000\nvt 0.1364 0.8254 0.0000\nvt 0.1184 0.8257 0.0000\nvt 0.1514 0.8173 0.0000\nvt 0.1650 0.8173 0.0000\nvt 0.1651 0.8252 0.0000\nvt 0.1516 0.8252 0.0000\nvt 0.1653 0.8412 0.0000\nvt 0.1525 0.8413 0.0000\nvt 0.1519 0.8333 0.0000\nvt 0.1652 0.8332 0.0000\nvt 0.1378 0.8416 0.0000\nvt 0.1206 0.8422 0.0000\nvt 0.1192 0.8340 0.0000\nvt 0.1370 0.8335 0.0000\nvt 0.2379 0.1557 0.0000\nvt 0.2375 0.1822 0.0000\nvt 0.2203 0.1841 0.0000\nvt 0.2215 0.1577 0.0000\nvt 0.2371 0.2096 0.0000\nvt 0.2369 0.2373 0.0000\nvt 0.2187 0.2393 0.0000\nvt 0.2193 0.2115 0.0000\nvt 0.1818 0.2476 0.0000\nvt 0.1835 0.2199 0.0000\nvt 0.2015 0.2151 0.0000\nvt 0.2003 0.2429 0.0000\nvt 0.1858 0.1931 0.0000\nvt 0.1883 0.1676 0.0000\nvt 0.2050 0.1617 0.0000\nvt 0.2031 0.1879 0.0000\nvt 0.1712 0.1751 0.0000\nvt 0.1683 0.1997 0.0000\nvt 0.1510 0.2068 0.0000\nvt 0.1543 0.1837 0.0000\nvt 0.1654 0.2257 0.0000\nvt 0.1631 0.2530 0.0000\nvt 0.1444 0.2582 0.0000\nvt 0.1474 0.2317 0.0000\nvt 0.1088 0.2642 0.0000\nvt 0.1138 0.2394 0.0000\nvt 0.1300 0.2367 0.0000\nvt 0.1262 0.2623 0.0000\nvt 0.1197 0.2172 0.0000\nvt 0.1252 0.1986 0.0000\nvt 0.1385 0.1921 0.0000\nvt 0.1345 0.2132 0.0000\nvt 0.1157 0.1982 0.0000\nvt 0.1070 0.2165 0.0000\nvt 0.0965 0.2111 0.0000\nvt 0.1087 0.1909 0.0000\nvt 0.0991 0.2383 0.0000\nvt 0.0928 0.2628 0.0000\nvt 0.0782 0.2582 0.0000\nvt 0.0863 0.2337 0.0000\nvt 0.0532 0.2450 0.0000\nvt 0.0644 0.2195 0.0000\nvt 0.0748 0.2269 0.0000\nvt 0.0651 0.2518 0.0000\nvt 0.0786 0.1951 0.0000\nvt 0.0954 0.1719 0.0000\nvt 0.1020 0.1815 0.0000\nvt 0.0871 0.2034 0.0000\nvt 0.0190 0.8476 0.0000\nvt 0.0159 0.8381 0.0000\nvt 0.0444 0.8369 0.0000\nvt 0.0468 0.8460 0.0000\nvt 0.7487 0.5541 0.0000\nvt 0.7498 0.5441 0.0000\nvt 0.7792 0.5439 0.0000\nvt 0.7779 0.5534 0.0000\nvt 0.0956 0.8176 0.0000\nvt 0.0963 0.8262 0.0000\nvt 0.0706 0.8268 0.0000\nvt 0.0697 0.8178 0.0000\nvt 0.0973 0.8347 0.0000\nvt 0.0992 0.8432 0.0000\nvt 0.0737 0.8445 0.0000\nvt 0.0719 0.8357 0.0000\nvt 0.0450 0.6477 0.0000\nvt 0.0436 0.6613 0.0000\nvt 0.0168 0.6629 0.0000\nvt 0.0194 0.6502 0.0000\nvt 0.0425 0.6752 0.0000\nvt 0.0419 0.6896 0.0000\nvt 0.0142 0.6900 0.0000\nvt 0.0151 0.6762 0.0000\nvt 0.4611 0.5453 0.0000\nvt 0.4627 0.5576 0.0000\nvt 0.4320 0.5587 0.0000\nvt 0.4299 0.5457 0.0000\nvt 0.4658 0.5696 0.0000\nvt 0.4695 0.5810 0.0000\nvt 0.4414 0.5834 0.0000\nvt 0.4359 0.5713 0.0000\nvt 0.4996 0.5793 0.0000\nvt 0.4971 0.5683 0.0000\nvt 0.5301 0.5676 0.0000\nvt 0.5318 0.5783 0.0000\nvt 0.4949 0.5569 0.0000\nvt 0.4936 0.5451 0.0000\nvt 0.5280 0.5449 0.0000\nvt 0.5288 0.5564 0.0000\nvt 0.5974 0.5448 0.0000\nvt 0.5974 0.5560 0.0000\nvt 0.5633 0.5561 0.0000\nvt 0.5629 0.5448 0.0000\nvt 0.5973 0.5669 0.0000\nvt 0.5969 0.5774 0.0000\nvt 0.5645 0.5778 0.0000\nvt 0.5639 0.5672 0.0000\nvt 0.1504 0.6437 0.0000\nvt 0.1505 0.6583 0.0000\nvt 0.1260 0.6585 0.0000\nvt 0.1259 0.6441 0.0000\nvt 0.1509 0.6734 0.0000\nvt 0.1511 0.6890 0.0000\nvt 0.1262 0.6890 0.0000\nvt 0.1262 0.6735 0.0000\nvt 0.0702 0.6893 0.0000\nvt 0.0705 0.6744 0.0000\nvt 0.0989 0.6738 0.0000\nvt 0.0988 0.6891 0.0000\nvt 0.0711 0.6599 0.0000\nvt 0.0718 0.6459 0.0000\nvt 0.0994 0.6448 0.0000\nvt 0.0991 0.6591 0.0000\nvt 0.0725 0.1448 0.0000\nvt 0.0779 0.1499 0.0000\nvt 0.0558 0.1760 0.0000\nvt 0.0498 0.1719 0.0000\nvt 0.0833 0.1560 0.0000\nvt 0.0892 0.1632 0.0000\nvt 0.0707 0.1876 0.0000\nvt 0.0628 0.1812 0.0000\nvt 0.0424 0.2390 0.0000\nvt 0.0319 0.2341 0.0000\nvt 0.0457 0.2071 0.0000\nvt 0.0549 0.2128 0.0000\nvt 0.6242 0.5960 0.0000\nvt 0.6262 0.5867 0.0000\nvt 0.6552 0.5861 0.0000\nvt 0.6521 0.5951 0.0000\nvt 0.2134 0.6436 0.0000\nvt 0.2136 0.6583 0.0000\nvt 0.2016 0.6583 0.0000\nvt 0.2013 0.6436 0.0000\nvt 0.2137 0.6735 0.0000\nvt 0.2138 0.6890 0.0000\nvt 0.2020 0.6890 0.0000\nvt 0.2019 0.6734 0.0000\nvt 0.1718 0.6890 0.0000\nvt 0.1717 0.6733 0.0000\nvt 0.1882 0.6734 0.0000\nvt 0.1884 0.6890 0.0000\nvt 0.1712 0.6582 0.0000\nvt 0.1709 0.6436 0.0000\nvt 0.1873 0.6435 0.0000\nvt 0.1878 0.6582 0.0000\nvt 0.2398 0.0076 0.0000\nvt 0.2398 0.0203 0.0000\nvt 0.2269 0.0231 0.0000\nvt 0.2272 0.0104 0.0000\nvt 0.2397 0.0341 0.0000\nvt 0.2395 0.0498 0.0000\nvt 0.2262 0.0523 0.0000\nvt 0.2266 0.0367 0.0000\nvt 0.1953 0.0669 0.0000\nvt 0.1956 0.0524 0.0000\nvt 0.2122 0.0426 0.0000\nvt 0.2117 0.0578 0.0000\nvt 0.1955 0.0399 0.0000\nvt 0.1958 0.0282 0.0000\nvt 0.2127 0.0172 0.0000\nvt 0.2124 0.0294 0.0000\nvt 0.3821 0.1397 0.0000\nvt 0.3597 0.1174 0.0000\nvt 0.3626 0.1072 0.0000\nvt 0.3864 0.1311 0.0000\nvt 0.3372 0.0972 0.0000\nvt 0.3158 0.0801 0.0000\nvt 0.3162 0.0667 0.0000\nvt 0.3387 0.0853 0.0000\nvt 0.3171 0.0445 0.0000\nvt 0.3419 0.0661 0.0000\nvt 0.3403 0.0752 0.0000\nvt 0.3168 0.0552 0.0000\nvt 0.3681 0.0907 0.0000\nvt 0.3948 0.1176 0.0000\nvt 0.3905 0.1239 0.0000\nvt 0.3654 0.0985 0.0000\nvt 0.4568 0.3575 0.0000\nvt 0.4644 0.3668 0.0000\nvt 0.4498 0.3853 0.0000\nvt 0.4445 0.3715 0.0000\nvt 0.4725 0.3745 0.0000\nvt 0.4798 0.3806 0.0000\nvt 0.4624 0.4058 0.0000\nvt 0.4559 0.3961 0.0000\nvt 0.4178 0.4418 0.0000\nvt 0.4144 0.4273 0.0000\nvt 0.4366 0.4143 0.0000\nvt 0.4418 0.4265 0.0000\nvt 0.4113 0.4115 0.0000\nvt 0.4087 0.3924 0.0000\nvt 0.4280 0.3836 0.0000\nvt 0.4320 0.4006 0.0000\nvt 0.3158 0.0953 0.0000\nvt 0.3360 0.1109 0.0000\nvt 0.3351 0.1263 0.0000\nvt 0.3161 0.1124 0.0000\nvt 0.3570 0.1293 0.0000\nvt 0.3776 0.1499 0.0000\nvt 0.3731 0.1612 0.0000\nvt 0.3544 0.1428 0.0000\nvt 0.3657 0.1846 0.0000\nvt 0.3518 0.1736 0.0000\nvt 0.3525 0.1574 0.0000\nvt 0.3689 0.1730 0.0000\nvt 0.3356 0.1626 0.0000\nvt 0.3185 0.1523 0.0000\nvt 0.3170 0.1314 0.0000\nvt 0.3349 0.1436 0.0000\nvt 0.3300 0.2811 0.0000\nvt 0.3492 0.2861 0.0000\nvt 0.3493 0.3146 0.0000\nvt 0.3297 0.3096 0.0000\nvt 0.3681 0.2897 0.0000\nvt 0.3864 0.2911 0.0000\nvt 0.3876 0.3191 0.0000\nvt 0.3687 0.3180 0.0000\nvt 0.3875 0.3732 0.0000\nvt 0.3672 0.3727 0.0000\nvt 0.3682 0.3461 0.0000\nvt 0.3877 0.3469 0.0000\nvt 0.3466 0.3690 0.0000\nvt 0.3265 0.3632 0.0000\nvt 0.3285 0.3373 0.0000\nvt 0.3483 0.3426 0.0000\nvt 0.4585 0.2663 0.0000\nvt 0.4699 0.2622 0.0000\nvt 0.4755 0.2910 0.0000\nvt 0.4637 0.2937 0.0000\nvt 0.1818 0.4805 0.0000\nvt 0.1828 0.4902 0.0000\nvt 0.1516 0.4899 0.0000\nvt 0.1517 0.4803 0.0000\nvt 0.0894 0.4888 0.0000\nvt 0.0930 0.4792 0.0000\nvt 0.1220 0.4799 0.0000\nvt 0.1203 0.4895 0.0000\nvt 0.4732 0.3444 0.0000\nvt 0.4634 0.3408 0.0000\nvt 0.4652 0.3192 0.0000\nvt 0.4767 0.3186 0.0000\nvt 0.3879 0.3967 0.0000\nvt 0.3890 0.4169 0.0000\nvt 0.3660 0.4170 0.0000\nvt 0.3664 0.3965 0.0000\nvt 0.3904 0.4339 0.0000\nvt 0.3923 0.4497 0.0000\nvt 0.3658 0.4502 0.0000\nvt 0.3659 0.4345 0.0000\nvt 0.3165 0.4378 0.0000\nvt 0.3192 0.4230 0.0000\nvt 0.3418 0.4303 0.0000\nvt 0.3403 0.4460 0.0000\nvt 0.3216 0.4061 0.0000\nvt 0.3241 0.3862 0.0000\nvt 0.3449 0.3926 0.0000\nvt 0.3432 0.4130 0.0000\nvt 0.4072 0.3698 0.0000\nvt 0.4064 0.3442 0.0000\nvt 0.4239 0.3382 0.0000\nvt 0.4254 0.3627 0.0000\nvt 0.4055 0.3169 0.0000\nvt 0.4034 0.2893 0.0000\nvt 0.4192 0.2845 0.0000\nvt 0.4222 0.3117 0.0000\nvt 0.4467 0.2716 0.0000\nvt 0.4513 0.2984 0.0000\nvt 0.4375 0.3050 0.0000\nvt 0.4336 0.2782 0.0000\nvt 0.4532 0.3233 0.0000\nvt 0.4536 0.3439 0.0000\nvt 0.4411 0.3532 0.0000\nvt 0.4395 0.3306 0.0000\nvt 0.3074 0.5341 0.0000\nvt 0.2782 0.5339 0.0000\nvt 0.2772 0.5232 0.0000\nvt 0.3063 0.5237 0.0000\nvt 0.2482 0.5337 0.0000\nvt 0.2171 0.5336 0.0000\nvt 0.2167 0.5224 0.0000\nvt 0.2476 0.5227 0.0000\nvt 0.2147 0.5008 0.0000\nvt 0.2444 0.5014 0.0000\nvt 0.2462 0.5119 0.0000\nvt 0.2159 0.5114 0.0000\nvt 0.2730 0.5023 0.0000\nvt 0.3009 0.5036 0.0000\nvt 0.3040 0.5135 0.0000\nvt 0.2754 0.5127 0.0000\nvt 0.3047 0.3783 0.0000\nvt 0.3020 0.3975 0.0000\nvt 0.2845 0.3887 0.0000\nvt 0.2868 0.3701 0.0000\nvt 0.2993 0.4138 0.0000\nvt 0.2962 0.4282 0.0000\nvt 0.2796 0.4180 0.0000\nvt 0.2821 0.4045 0.0000\nvt 0.2523 0.4044 0.0000\nvt 0.2528 0.3919 0.0000\nvt 0.2669 0.3966 0.0000\nvt 0.2651 0.4098 0.0000\nvt 0.2534 0.3767 0.0000\nvt 0.2540 0.3589 0.0000\nvt 0.2701 0.3632 0.0000\nvt 0.2685 0.3812 0.0000\nvt 0.2974 0.0833 0.0000\nvt 0.2984 0.1016 0.0000\nvt 0.2823 0.0938 0.0000\nvt 0.2812 0.0749 0.0000\nvt 0.2998 0.1217 0.0000\nvt 0.3016 0.1437 0.0000\nvt 0.2853 0.1373 0.0000\nvt 0.2837 0.1146 0.0000\nvt 0.2538 0.1308 0.0000\nvt 0.2534 0.1078 0.0000\nvt 0.2683 0.1100 0.0000\nvt 0.2694 0.1330 0.0000\nvt 0.2531 0.0867 0.0000\nvt 0.2528 0.0674 0.0000\nvt 0.2665 0.0697 0.0000\nvt 0.2673 0.0890 0.0000\nvt 0.3109 0.2758 0.0000\nvt 0.3105 0.3038 0.0000\nvt 0.2918 0.2982 0.0000\nvt 0.2922 0.2708 0.0000\nvt 0.3092 0.3309 0.0000\nvt 0.3072 0.3560 0.0000\nvt 0.2890 0.3486 0.0000\nvt 0.2907 0.3244 0.0000\nvt 0.2545 0.3385 0.0000\nvt 0.2549 0.3156 0.0000\nvt 0.2726 0.3189 0.0000\nvt 0.2715 0.3423 0.0000\nvt 0.2551 0.2908 0.0000\nvt 0.2552 0.2645 0.0000\nvt 0.2736 0.2668 0.0000\nvt 0.2733 0.2936 0.0000\nvt 0.2251 0.8174 0.0000\nvt 0.2246 0.8257 0.0000\nvt 0.2065 0.8254 0.0000\nvt 0.2069 0.8173 0.0000\nvt 0.2238 0.8340 0.0000\nvt 0.2223 0.8422 0.0000\nvt 0.2051 0.8416 0.0000\nvt 0.2060 0.8335 0.0000\nvt 0.1777 0.8412 0.0000\nvt 0.1778 0.8332 0.0000\nvt 0.1911 0.8333 0.0000\nvt 0.1904 0.8413 0.0000\nvt 0.1779 0.8252 0.0000\nvt 0.1780 0.8173 0.0000\nvt 0.1916 0.8173 0.0000\nvt 0.1914 0.8252 0.0000\nvt 0.2542 0.1557 0.0000\nvt 0.2706 0.1577 0.0000\nvt 0.2717 0.1841 0.0000\nvt 0.2546 0.1822 0.0000\nvt 0.2871 0.1617 0.0000\nvt 0.3038 0.1676 0.0000\nvt 0.3063 0.1931 0.0000\nvt 0.2889 0.1879 0.0000\nvt 0.3102 0.2476 0.0000\nvt 0.2918 0.2429 0.0000\nvt 0.2906 0.2151 0.0000\nvt 0.3085 0.2199 0.0000\nvt 0.2734 0.2393 0.0000\nvt 0.2551 0.2373 0.0000\nvt 0.2549 0.2096 0.0000\nvt 0.2727 0.2115 0.0000\nvt 0.3209 0.1751 0.0000\nvt 0.3378 0.1837 0.0000\nvt 0.3411 0.2068 0.0000\nvt 0.3238 0.1997 0.0000\nvt 0.3536 0.1921 0.0000\nvt 0.3669 0.1986 0.0000\nvt 0.3724 0.2172 0.0000\nvt 0.3575 0.2132 0.0000\nvt 0.3833 0.2642 0.0000\nvt 0.3659 0.2623 0.0000\nvt 0.3621 0.2367 0.0000\nvt 0.3783 0.2394 0.0000\nvt 0.3476 0.2582 0.0000\nvt 0.3289 0.2530 0.0000\nvt 0.3267 0.2257 0.0000\nvt 0.3447 0.2317 0.0000\nvt 0.3763 0.1982 0.0000\nvt 0.3833 0.1909 0.0000\nvt 0.3956 0.2111 0.0000\nvt 0.3850 0.2165 0.0000\nvt 0.3901 0.1815 0.0000\nvt 0.3966 0.1719 0.0000\nvt 0.4135 0.1951 0.0000\nvt 0.4049 0.2034 0.0000\nvt 0.4389 0.2450 0.0000\nvt 0.4270 0.2518 0.0000\nvt 0.4173 0.2269 0.0000\nvt 0.4277 0.2195 0.0000\nvt 0.4138 0.2582 0.0000\nvt 0.3993 0.2628 0.0000\nvt 0.3929 0.2383 0.0000\nvt 0.4058 0.2337 0.0000\nvt 0.3240 0.8477 0.0000\nvt 0.2962 0.8461 0.0000\nvt 0.2986 0.8369 0.0000\nvt 0.3270 0.8381 0.0000\nvt 0.2692 0.8445 0.0000\nvt 0.2438 0.8432 0.0000\nvt 0.2456 0.8347 0.0000\nvt 0.2711 0.8357 0.0000\nvt 0.2474 0.8176 0.0000\nvt 0.2733 0.8178 0.0000\nvt 0.2724 0.8268 0.0000\nvt 0.2467 0.8262 0.0000\nvt 0.3659 0.5347 0.0000\nvt 0.3365 0.5344 0.0000\nvt 0.3354 0.5244 0.0000\nvt 0.3646 0.5251 0.0000\nvt 0.3937 0.6477 0.0000\nvt 0.4194 0.6502 0.0000\nvt 0.4219 0.6629 0.0000\nvt 0.3951 0.6613 0.0000\nvt 0.0281 0.4951 0.0000\nvt 0.0562 0.4974 0.0000\nvt 0.0524 0.5089 0.0000\nvt 0.0226 0.5072 0.0000\nvt 0.0477 0.5332 0.0000\nvt 0.0166 0.5329 0.0000\nvt 0.0187 0.5198 0.0000\nvt 0.0494 0.5209 0.0000\nvt 0.4245 0.6900 0.0000\nvt 0.3968 0.6896 0.0000\nvt 0.3963 0.6752 0.0000\nvt 0.4237 0.6762 0.0000\nvt 0.0863 0.4990 0.0000\nvt 0.1185 0.4997 0.0000\nvt 0.1168 0.5106 0.0000\nvt 0.0838 0.5100 0.0000\nvt 0.1512 0.5001 0.0000\nvt 0.1836 0.5003 0.0000\nvt 0.1839 0.5110 0.0000\nvt 0.1506 0.5109 0.0000\nvt 0.1841 0.5335 0.0000\nvt 0.1496 0.5335 0.0000\nvt 0.1500 0.5221 0.0000\nvt 0.1841 0.5222 0.0000\nvt 0.1146 0.5335 0.0000\nvt 0.0803 0.5334 0.0000\nvt 0.0815 0.5215 0.0000\nvt 0.1154 0.5219 0.0000\nvt 0.2883 0.6437 0.0000\nvt 0.3129 0.6441 0.0000\nvt 0.3127 0.6585 0.0000\nvt 0.2882 0.6583 0.0000\nvt 0.3393 0.6448 0.0000\nvt 0.3669 0.6459 0.0000\nvt 0.3676 0.6599 0.0000\nvt 0.3397 0.6591 0.0000\nvt 0.3685 0.6893 0.0000\nvt 0.3399 0.6891 0.0000\nvt 0.3398 0.6738 0.0000\nvt 0.3682 0.6744 0.0000\nvt 0.3125 0.6890 0.0000\nvt 0.2877 0.6890 0.0000\nvt 0.2878 0.6734 0.0000\nvt 0.3125 0.6735 0.0000\nvt 0.4195 0.1448 0.0000\nvt 0.4422 0.1719 0.0000\nvt 0.4362 0.1760 0.0000\nvt 0.4142 0.1499 0.0000\nvt 0.2419 0.4915 0.0000\nvt 0.2129 0.4907 0.0000\nvt 0.2109 0.4812 0.0000\nvt 0.2388 0.4823 0.0000\nvt 0.4496 0.2390 0.0000\nvt 0.4371 0.2128 0.0000\nvt 0.4463 0.2071 0.0000\nvt 0.4601 0.2341 0.0000\nvt 0.4214 0.1876 0.0000\nvt 0.4029 0.1632 0.0000\nvt 0.4088 0.1560 0.0000\nvt 0.4292 0.1812 0.0000\nvt 0.2253 0.6436 0.0000\nvt 0.2374 0.6436 0.0000\nvt 0.2372 0.6583 0.0000\nvt 0.2251 0.6583 0.0000\nvt 0.2514 0.6435 0.0000\nvt 0.2678 0.6436 0.0000\nvt 0.2676 0.6582 0.0000\nvt 0.2509 0.6582 0.0000\nvt 0.2669 0.6890 0.0000\nvt 0.2503 0.6890 0.0000\nvt 0.2505 0.6734 0.0000\nvt 0.2671 0.6733 0.0000\nvt 0.2368 0.6890 0.0000\nvt 0.2250 0.6890 0.0000\nvt 0.2250 0.6735 0.0000\nvt 0.2369 0.6734 0.0000\nvt 0.2522 0.0076 0.0000\nvt 0.2648 0.0104 0.0000\nvt 0.2652 0.0231 0.0000\nvt 0.2523 0.0203 0.0000\nvt 0.2793 0.0172 0.0000\nvt 0.2962 0.0282 0.0000\nvt 0.2965 0.0399 0.0000\nvt 0.2796 0.0294 0.0000\nvt 0.2968 0.0669 0.0000\nvt 0.2804 0.0578 0.0000\nvt 0.2799 0.0426 0.0000\nvt 0.2965 0.0524 0.0000\nvt 0.2659 0.0523 0.0000\nvt 0.2525 0.0498 0.0000\nvt 0.2524 0.0341 0.0000\nvt 0.2654 0.0367 0.0000\nvt 0.8900 0.1397 0.0000\nvt 0.8677 0.1174 0.0000\nvt 0.8705 0.1072 0.0000\nvt 0.8944 0.1311 0.0000\nvt 0.8452 0.0972 0.0000\nvt 0.8238 0.0801 0.0000\nvt 0.8241 0.0667 0.0000\nvt 0.8466 0.0853 0.0000\nvt 0.8251 0.0445 0.0000\nvt 0.8499 0.0661 0.0000\nvt 0.8483 0.0752 0.0000\nvt 0.8248 0.0552 0.0000\nvt 0.8760 0.0907 0.0000\nvt 0.9027 0.1176 0.0000\nvt 0.8985 0.1239 0.0000\nvt 0.8734 0.0985 0.0000\nvt 0.9647 0.3575 0.0000\nvt 0.9723 0.3668 0.0000\nvt 0.9578 0.3853 0.0000\nvt 0.9524 0.3715 0.0000\nvt 0.9805 0.3745 0.0000\nvt 0.9877 0.3806 0.0000\nvt 0.9704 0.4058 0.0000\nvt 0.9638 0.3961 0.0000\nvt 0.9257 0.4418 0.0000\nvt 0.9223 0.4273 0.0000\nvt 0.9445 0.4143 0.0000\nvt 0.9498 0.4265 0.0000\nvt 0.9193 0.4115 0.0000\nvt 0.9167 0.3924 0.0000\nvt 0.9360 0.3836 0.0000\nvt 0.9400 0.4006 0.0000\nvt 0.8237 0.0953 0.0000\nvt 0.8439 0.1109 0.0000\nvt 0.8430 0.1263 0.0000\nvt 0.8240 0.1124 0.0000\nvt 0.8649 0.1293 0.0000\nvt 0.8855 0.1499 0.0000\nvt 0.8810 0.1612 0.0000\nvt 0.8624 0.1428 0.0000\nvt 0.8736 0.1846 0.0000\nvt 0.8597 0.1736 0.0000\nvt 0.8604 0.1574 0.0000\nvt 0.8768 0.1730 0.0000\nvt 0.8436 0.1626 0.0000\nvt 0.8265 0.1523 0.0000\nvt 0.8249 0.1314 0.0000\nvt 0.8428 0.1436 0.0000\nvt 0.8380 0.2811 0.0000\nvt 0.8572 0.2861 0.0000\nvt 0.8572 0.3146 0.0000\nvt 0.8377 0.3096 0.0000\nvt 0.8761 0.2897 0.0000\nvt 0.8943 0.2911 0.0000\nvt 0.8955 0.3191 0.0000\nvt 0.8766 0.3180 0.0000\nvt 0.8955 0.3732 0.0000\nvt 0.8751 0.3727 0.0000\nvt 0.8761 0.3461 0.0000\nvt 0.8957 0.3469 0.0000\nvt 0.8546 0.3690 0.0000\nvt 0.8344 0.3632 0.0000\nvt 0.8364 0.3373 0.0000\nvt 0.8562 0.3426 0.0000\nvt 0.9665 0.2663 0.0000\nvt 0.9778 0.2622 0.0000\nvt 0.9835 0.2910 0.0000\nvt 0.9716 0.2937 0.0000\nvt 0.5952 0.4816 0.0000\nvt 0.5961 0.4910 0.0000\nvt 0.5649 0.4905 0.0000\nvt 0.5650 0.4812 0.0000\nvt 0.5027 0.4889 0.0000\nvt 0.5063 0.4794 0.0000\nvt 0.5353 0.4804 0.0000\nvt 0.5336 0.4899 0.0000\nvt 0.9812 0.3444 0.0000\nvt 0.9714 0.3408 0.0000\nvt 0.9732 0.3192 0.0000\nvt 0.9847 0.3186 0.0000\nvt 0.8958 0.3967 0.0000\nvt 0.8969 0.4169 0.0000\nvt 0.8739 0.4170 0.0000\nvt 0.8743 0.3965 0.0000\nvt 0.8984 0.4339 0.0000\nvt 0.9002 0.4497 0.0000\nvt 0.8737 0.4502 0.0000\nvt 0.8738 0.4345 0.0000\nvt 0.8244 0.4378 0.0000\nvt 0.8271 0.4230 0.0000\nvt 0.8497 0.4303 0.0000\nvt 0.8483 0.4460 0.0000\nvt 0.8295 0.4061 0.0000\nvt 0.8320 0.3862 0.0000\nvt 0.8528 0.3926 0.0000\nvt 0.8512 0.4130 0.0000\nvt 0.9151 0.3698 0.0000\nvt 0.9144 0.3442 0.0000\nvt 0.9318 0.3382 0.0000\nvt 0.9333 0.3627 0.0000\nvt 0.9134 0.3169 0.0000\nvt 0.9114 0.2893 0.0000\nvt 0.9271 0.2845 0.0000\nvt 0.9301 0.3117 0.0000\nvt 0.9547 0.2716 0.0000\nvt 0.9592 0.2984 0.0000\nvt 0.9454 0.3050 0.0000\nvt 0.9416 0.2782 0.0000\nvt 0.9611 0.3233 0.0000\nvt 0.9616 0.3439 0.0000\nvt 0.9491 0.3532 0.0000\nvt 0.9474 0.3306 0.0000\nvt 0.7207 0.5339 0.0000\nvt 0.6915 0.5338 0.0000\nvt 0.6905 0.5231 0.0000\nvt 0.7197 0.5236 0.0000\nvt 0.6616 0.5337 0.0000\nvt 0.6304 0.5336 0.0000\nvt 0.6300 0.5225 0.0000\nvt 0.6609 0.5228 0.0000\nvt 0.6280 0.5013 0.0000\nvt 0.6577 0.5018 0.0000\nvt 0.6595 0.5121 0.0000\nvt 0.6292 0.5117 0.0000\nvt 0.6864 0.5026 0.0000\nvt 0.7142 0.5036 0.0000\nvt 0.7174 0.5134 0.0000\nvt 0.6887 0.5127 0.0000\nvt 0.8126 0.3783 0.0000\nvt 0.8099 0.3975 0.0000\nvt 0.7924 0.3887 0.0000\nvt 0.7948 0.3701 0.0000\nvt 0.8072 0.4138 0.0000\nvt 0.8041 0.4282 0.0000\nvt 0.7875 0.4180 0.0000\nvt 0.7900 0.4045 0.0000\nvt 0.7602 0.4044 0.0000\nvt 0.7608 0.3919 0.0000\nvt 0.7748 0.3966 0.0000\nvt 0.7730 0.4098 0.0000\nvt 0.7614 0.3767 0.0000\nvt 0.7619 0.3589 0.0000\nvt 0.7780 0.3632 0.0000\nvt 0.7764 0.3812 0.0000\nvt 0.8054 0.0833 0.0000\nvt 0.8063 0.1016 0.0000\nvt 0.7902 0.0938 0.0000\nvt 0.7891 0.0749 0.0000\nvt 0.8077 0.1217 0.0000\nvt 0.8095 0.1437 0.0000\nvt 0.7932 0.1373 0.0000\nvt 0.7916 0.1146 0.0000\nvt 0.7617 0.1308 0.0000\nvt 0.7613 0.1078 0.0000\nvt 0.7762 0.1100 0.0000\nvt 0.7773 0.1330 0.0000\nvt 0.7610 0.0867 0.0000\nvt 0.7607 0.0674 0.0000\nvt 0.7745 0.0697 0.0000\nvt 0.7753 0.0890 0.0000\nvt 0.8189 0.2758 0.0000\nvt 0.8185 0.3038 0.0000\nvt 0.7997 0.2982 0.0000\nvt 0.8001 0.2708 0.0000\nvt 0.8172 0.3309 0.0000\nvt 0.8151 0.3560 0.0000\nvt 0.7969 0.3486 0.0000\nvt 0.7986 0.3244 0.0000\nvt 0.7624 0.3385 0.0000\nvt 0.7628 0.3156 0.0000\nvt 0.7806 0.3189 0.0000\nvt 0.7794 0.3423 0.0000\nvt 0.7631 0.2908 0.0000\nvt 0.7632 0.2645 0.0000\nvt 0.7816 0.2668 0.0000\nvt 0.7813 0.2936 0.0000\nvt 0.1179 0.8092 0.0000\nvt 0.1184 0.8009 0.0000\nvt 0.1364 0.8012 0.0000\nvt 0.1361 0.8093 0.0000\nvt 0.1192 0.7926 0.0000\nvt 0.1206 0.7844 0.0000\nvt 0.1378 0.7850 0.0000\nvt 0.1370 0.7931 0.0000\nvt 0.1653 0.7854 0.0000\nvt 0.1652 0.7934 0.0000\nvt 0.1519 0.7933 0.0000\nvt 0.1525 0.7853 0.0000\nvt 0.1651 0.8014 0.0000\nvt 0.1650 0.8093 0.0000\nvt 0.1514 0.8093 0.0000\nvt 0.1516 0.8014 0.0000\nvt 0.7621 0.1557 0.0000\nvt 0.7785 0.1577 0.0000\nvt 0.7797 0.1841 0.0000\nvt 0.7625 0.1822 0.0000\nvt 0.7950 0.1617 0.0000\nvt 0.8117 0.1676 0.0000\nvt 0.8142 0.1931 0.0000\nvt 0.7969 0.1879 0.0000\nvt 0.8182 0.2476 0.0000\nvt 0.7997 0.2429 0.0000\nvt 0.7985 0.2151 0.0000\nvt 0.8165 0.2199 0.0000\nvt 0.7813 0.2393 0.0000\nvt 0.7631 0.2373 0.0000\nvt 0.7629 0.2096 0.0000\nvt 0.7807 0.2115 0.0000\nvt 0.8288 0.1751 0.0000\nvt 0.8457 0.1837 0.0000\nvt 0.8490 0.2068 0.0000\nvt 0.8317 0.1997 0.0000\nvt 0.8615 0.1921 0.0000\nvt 0.8748 0.1986 0.0000\nvt 0.8803 0.2172 0.0000\nvt 0.8655 0.2132 0.0000\nvt 0.8912 0.2642 0.0000\nvt 0.8738 0.2623 0.0000\nvt 0.8700 0.2367 0.0000\nvt 0.8862 0.2394 0.0000\nvt 0.8556 0.2582 0.0000\nvt 0.8369 0.2530 0.0000\nvt 0.8346 0.2257 0.0000\nvt 0.8526 0.2317 0.0000\nvt 0.8843 0.1982 0.0000\nvt 0.8913 0.1909 0.0000\nvt 0.9035 0.2111 0.0000\nvt 0.8930 0.2165 0.0000\nvt 0.8980 0.1815 0.0000\nvt 0.9046 0.1719 0.0000\nvt 0.9214 0.1951 0.0000\nvt 0.9129 0.2034 0.0000\nvt 0.9468 0.2450 0.0000\nvt 0.9349 0.2518 0.0000\nvt 0.9252 0.2269 0.0000\nvt 0.9356 0.2195 0.0000\nvt 0.9218 0.2582 0.0000\nvt 0.9072 0.2628 0.0000\nvt 0.9009 0.2383 0.0000\nvt 0.9137 0.2337 0.0000\nvt 0.0190 0.7791 0.0000\nvt 0.0468 0.7806 0.0000\nvt 0.0444 0.7897 0.0000\nvt 0.0159 0.7885 0.0000\nvt 0.0737 0.7821 0.0000\nvt 0.0992 0.7834 0.0000\nvt 0.0973 0.7919 0.0000\nvt 0.0719 0.7909 0.0000\nvt 0.0956 0.8090 0.0000\nvt 0.0697 0.8088 0.0000\nvt 0.0706 0.7998 0.0000\nvt 0.0963 0.8004 0.0000\nvt 0.7792 0.5344 0.0000\nvt 0.7498 0.5342 0.0000\nvt 0.7487 0.5241 0.0000\nvt 0.7779 0.5249 0.0000\nvt 0.0450 0.7461 0.0000\nvt 0.0194 0.7436 0.0000\nvt 0.0168 0.7309 0.0000\nvt 0.0436 0.7325 0.0000\nvt 0.4414 0.4949 0.0000\nvt 0.4695 0.4972 0.0000\nvt 0.4658 0.5087 0.0000\nvt 0.4359 0.5070 0.0000\nvt 0.4611 0.5329 0.0000\nvt 0.4299 0.5326 0.0000\nvt 0.4320 0.5196 0.0000\nvt 0.4627 0.5207 0.0000\nvt 0.0142 0.7038 0.0000\nvt 0.0419 0.7042 0.0000\nvt 0.0425 0.7186 0.0000\nvt 0.0151 0.7176 0.0000\nvt 0.4996 0.4990 0.0000\nvt 0.5318 0.5000 0.0000\nvt 0.5301 0.5107 0.0000\nvt 0.4971 0.5099 0.0000\nvt 0.5645 0.5005 0.0000\nvt 0.5969 0.5009 0.0000\nvt 0.5973 0.5114 0.0000\nvt 0.5639 0.5111 0.0000\nvt 0.5974 0.5335 0.0000\nvt 0.5629 0.5334 0.0000\nvt 0.5633 0.5221 0.0000\nvt 0.5974 0.5223 0.0000\nvt 0.5280 0.5334 0.0000\nvt 0.4936 0.5332 0.0000\nvt 0.4949 0.5214 0.0000\nvt 0.5288 0.5219 0.0000\nvt 0.1504 0.7501 0.0000\nvt 0.1259 0.7497 0.0000\nvt 0.1260 0.7352 0.0000\nvt 0.1505 0.7355 0.0000\nvt 0.0994 0.7490 0.0000\nvt 0.0718 0.7479 0.0000\nvt 0.0711 0.7339 0.0000\nvt 0.0991 0.7347 0.0000\nvt 0.0702 0.7045 0.0000\nvt 0.0988 0.7046 0.0000\nvt 0.0989 0.7200 0.0000\nvt 0.0705 0.7194 0.0000\nvt 0.1262 0.7047 0.0000\nvt 0.1511 0.7048 0.0000\nvt 0.1509 0.7204 0.0000\nvt 0.1262 0.7203 0.0000\nvt 0.9275 0.1448 0.0000\nvt 0.9502 0.1719 0.0000\nvt 0.9442 0.1760 0.0000\nvt 0.9221 0.1499 0.0000\nvt 0.6552 0.4922 0.0000\nvt 0.6262 0.4915 0.0000\nvt 0.6242 0.4822 0.0000\nvt 0.6521 0.4832 0.0000\nvt 0.9576 0.2390 0.0000\nvt 0.9451 0.2128 0.0000\nvt 0.9543 0.2071 0.0000\nvt 0.9681 0.2341 0.0000\nvt 0.9293 0.1876 0.0000\nvt 0.9108 0.1632 0.0000\nvt 0.9167 0.1560 0.0000\nvt 0.9372 0.1812 0.0000\nvt 0.2134 0.7502 0.0000\nvt 0.2013 0.7502 0.0000\nvt 0.2016 0.7355 0.0000\nvt 0.2136 0.7355 0.0000\nvt 0.1873 0.7503 0.0000\nvt 0.1709 0.7502 0.0000\nvt 0.1712 0.7356 0.0000\nvt 0.1878 0.7356 0.0000\nvt 0.1718 0.7048 0.0000\nvt 0.1884 0.7048 0.0000\nvt 0.1882 0.7204 0.0000\nvt 0.1717 0.7204 0.0000\nvt 0.2020 0.7048 0.0000\nvt 0.2138 0.7048 0.0000\nvt 0.2137 0.7203 0.0000\nvt 0.2019 0.7204 0.0000\nvt 0.7602 0.0076 0.0000\nvt 0.7728 0.0104 0.0000\nvt 0.7731 0.0231 0.0000\nvt 0.7602 0.0203 0.0000\nvt 0.7873 0.0172 0.0000\nvt 0.8042 0.0282 0.0000\nvt 0.8045 0.0399 0.0000\nvt 0.7876 0.0294 0.0000\nvt 0.8047 0.0669 0.0000\nvt 0.7883 0.0578 0.0000\nvt 0.7878 0.0426 0.0000\nvt 0.8044 0.0524 0.0000\nvt 0.7738 0.0523 0.0000\nvt 0.7605 0.0498 0.0000\nvt 0.7603 0.0341 0.0000\nvt 0.7734 0.0367 0.0000\nvt 0.6179 0.1397 0.0000\nvt 0.6136 0.1311 0.0000\nvt 0.6374 0.1072 0.0000\nvt 0.6403 0.1174 0.0000\nvt 0.6095 0.1239 0.0000\nvt 0.6052 0.1176 0.0000\nvt 0.6319 0.0907 0.0000\nvt 0.6346 0.0985 0.0000\nvt 0.6829 0.0445 0.0000\nvt 0.6832 0.0552 0.0000\nvt 0.6597 0.0752 0.0000\nvt 0.6581 0.0661 0.0000\nvt 0.6838 0.0667 0.0000\nvt 0.6842 0.0801 0.0000\nvt 0.6628 0.0972 0.0000\nvt 0.6613 0.0853 0.0000\nvt 0.5432 0.3575 0.0000\nvt 0.5555 0.3715 0.0000\nvt 0.5502 0.3853 0.0000\nvt 0.5356 0.3668 0.0000\nvt 0.5720 0.3836 0.0000\nvt 0.5913 0.3924 0.0000\nvt 0.5887 0.4115 0.0000\nvt 0.5680 0.4006 0.0000\nvt 0.5822 0.4418 0.0000\nvt 0.5582 0.4265 0.0000\nvt 0.5634 0.4143 0.0000\nvt 0.5856 0.4273 0.0000\nvt 0.5376 0.4058 0.0000\nvt 0.5202 0.3806 0.0000\nvt 0.5275 0.3745 0.0000\nvt 0.5441 0.3961 0.0000\nvt 0.6842 0.0953 0.0000\nvt 0.6839 0.1124 0.0000\nvt 0.6649 0.1263 0.0000\nvt 0.6640 0.1109 0.0000\nvt 0.6830 0.1314 0.0000\nvt 0.6815 0.1523 0.0000\nvt 0.6644 0.1626 0.0000\nvt 0.6651 0.1436 0.0000\nvt 0.6343 0.1846 0.0000\nvt 0.6311 0.1730 0.0000\nvt 0.6475 0.1574 0.0000\nvt 0.6482 0.1736 0.0000\nvt 0.6269 0.1612 0.0000\nvt 0.6224 0.1499 0.0000\nvt 0.6430 0.1293 0.0000\nvt 0.6456 0.1428 0.0000\nvt 0.6700 0.2811 0.0000\nvt 0.6703 0.3096 0.0000\nvt 0.6507 0.3146 0.0000\nvt 0.6508 0.2861 0.0000\nvt 0.6715 0.3373 0.0000\nvt 0.6735 0.3632 0.0000\nvt 0.6534 0.3690 0.0000\nvt 0.6517 0.3426 0.0000\nvt 0.6125 0.3732 0.0000\nvt 0.6123 0.3469 0.0000\nvt 0.6318 0.3461 0.0000\nvt 0.6328 0.3727 0.0000\nvt 0.6124 0.3191 0.0000\nvt 0.6136 0.2911 0.0000\nvt 0.6319 0.2897 0.0000\nvt 0.6313 0.3180 0.0000\nvt 0.5415 0.2663 0.0000\nvt 0.5363 0.2937 0.0000\nvt 0.5245 0.2910 0.0000\nvt 0.5301 0.2622 0.0000\nvt 0.5348 0.3192 0.0000\nvt 0.5366 0.3408 0.0000\nvt 0.5268 0.3444 0.0000\nvt 0.5233 0.3186 0.0000\nvt 0.0894 0.5897 0.0000\nvt 0.1203 0.5887 0.0000\nvt 0.1220 0.5981 0.0000\nvt 0.0930 0.5992 0.0000\nvt 0.1516 0.5880 0.0000\nvt 0.1828 0.5876 0.0000\nvt 0.1818 0.5969 0.0000\nvt 0.1517 0.5974 0.0000\nvt 0.6121 0.3967 0.0000\nvt 0.6336 0.3965 0.0000\nvt 0.6340 0.4170 0.0000\nvt 0.6110 0.4169 0.0000\nvt 0.6551 0.3926 0.0000\nvt 0.6759 0.3862 0.0000\nvt 0.6784 0.4061 0.0000\nvt 0.6568 0.4130 0.0000\nvt 0.6835 0.4378 0.0000\nvt 0.6597 0.4460 0.0000\nvt 0.6582 0.4303 0.0000\nvt 0.6808 0.4230 0.0000\nvt 0.6342 0.4502 0.0000\nvt 0.6077 0.4497 0.0000\nvt 0.6096 0.4339 0.0000\nvt 0.6341 0.4345 0.0000\nvt 0.5928 0.3698 0.0000\nvt 0.5746 0.3627 0.0000\nvt 0.5761 0.3382 0.0000\nvt 0.5936 0.3442 0.0000\nvt 0.5589 0.3532 0.0000\nvt 0.5464 0.3439 0.0000\nvt 0.5468 0.3233 0.0000\nvt 0.5605 0.3306 0.0000\nvt 0.5533 0.2716 0.0000\nvt 0.5664 0.2782 0.0000\nvt 0.5625 0.3050 0.0000\nvt 0.5487 0.2984 0.0000\nvt 0.5808 0.2845 0.0000\nvt 0.5966 0.2893 0.0000\nvt 0.5945 0.3169 0.0000\nvt 0.5778 0.3117 0.0000\nvt 0.3074 0.5446 0.0000\nvt 0.3063 0.5550 0.0000\nvt 0.2772 0.5554 0.0000\nvt 0.2782 0.5447 0.0000\nvt 0.3040 0.5651 0.0000\nvt 0.3009 0.5750 0.0000\nvt 0.2730 0.5760 0.0000\nvt 0.2754 0.5658 0.0000\nvt 0.2147 0.5772 0.0000\nvt 0.2159 0.5669 0.0000\nvt 0.2462 0.5664 0.0000\nvt 0.2444 0.5767 0.0000\nvt 0.2167 0.5560 0.0000\nvt 0.2171 0.5449 0.0000\nvt 0.2482 0.5448 0.0000\nvt 0.2476 0.5557 0.0000\nvt 0.6953 0.3783 0.0000\nvt 0.7132 0.3701 0.0000\nvt 0.7155 0.3887 0.0000\nvt 0.6980 0.3975 0.0000\nvt 0.7299 0.3632 0.0000\nvt 0.7460 0.3589 0.0000\nvt 0.7466 0.3767 0.0000\nvt 0.7315 0.3812 0.0000\nvt 0.7477 0.4044 0.0000\nvt 0.7349 0.4098 0.0000\nvt 0.7331 0.3966 0.0000\nvt 0.7472 0.3919 0.0000\nvt 0.7204 0.4180 0.0000\nvt 0.7038 0.4282 0.0000\nvt 0.7007 0.4138 0.0000\nvt 0.7179 0.4045 0.0000\nvt 0.7026 0.0833 0.0000\nvt 0.7188 0.0749 0.0000\nvt 0.7177 0.0938 0.0000\nvt 0.7016 0.1016 0.0000\nvt 0.7335 0.0697 0.0000\nvt 0.7472 0.0674 0.0000\nvt 0.7469 0.0867 0.0000\nvt 0.7327 0.0890 0.0000\nvt 0.7462 0.1308 0.0000\nvt 0.7306 0.1330 0.0000\nvt 0.7317 0.1100 0.0000\nvt 0.7466 0.1078 0.0000\nvt 0.7147 0.1373 0.0000\nvt 0.6984 0.1437 0.0000\nvt 0.7002 0.1217 0.0000\nvt 0.7163 0.1146 0.0000\nvt 0.6891 0.2758 0.0000\nvt 0.7078 0.2708 0.0000\nvt 0.7082 0.2982 0.0000\nvt 0.6895 0.3038 0.0000\nvt 0.7264 0.2668 0.0000\nvt 0.7448 0.2645 0.0000\nvt 0.7449 0.2908 0.0000\nvt 0.7267 0.2936 0.0000\nvt 0.7455 0.3385 0.0000\nvt 0.7285 0.3423 0.0000\nvt 0.7274 0.3189 0.0000\nvt 0.7451 0.3156 0.0000\nvt 0.7110 0.3486 0.0000\nvt 0.6928 0.3560 0.0000\nvt 0.6908 0.3309 0.0000\nvt 0.7093 0.3244 0.0000\nvt 0.2251 0.8092 0.0000\nvt 0.2069 0.8093 0.0000\nvt 0.2065 0.8012 0.0000\nvt 0.2246 0.8009 0.0000\nvt 0.1916 0.8093 0.0000\nvt 0.1780 0.8093 0.0000\nvt 0.1779 0.8014 0.0000\nvt 0.1914 0.8014 0.0000\nvt 0.1777 0.7854 0.0000\nvt 0.1904 0.7853 0.0000\nvt 0.1911 0.7933 0.0000\nvt 0.1778 0.7934 0.0000\nvt 0.2051 0.7850 0.0000\nvt 0.2223 0.7844 0.0000\nvt 0.2238 0.7926 0.0000\nvt 0.2060 0.7931 0.0000\nvt 0.7458 0.1557 0.0000\nvt 0.7454 0.1822 0.0000\nvt 0.7283 0.1841 0.0000\nvt 0.7294 0.1577 0.0000\nvt 0.7451 0.2096 0.0000\nvt 0.7449 0.2373 0.0000\nvt 0.7266 0.2393 0.0000\nvt 0.7273 0.2115 0.0000\nvt 0.6898 0.2476 0.0000\nvt 0.6915 0.2199 0.0000\nvt 0.7094 0.2151 0.0000\nvt 0.7082 0.2429 0.0000\nvt 0.6937 0.1931 0.0000\nvt 0.6962 0.1676 0.0000\nvt 0.7129 0.1617 0.0000\nvt 0.7111 0.1879 0.0000\nvt 0.6791 0.1751 0.0000\nvt 0.6762 0.1997 0.0000\nvt 0.6589 0.2068 0.0000\nvt 0.6622 0.1837 0.0000\nvt 0.6733 0.2257 0.0000\nvt 0.6711 0.2530 0.0000\nvt 0.6524 0.2582 0.0000\nvt 0.6553 0.2317 0.0000\nvt 0.6167 0.2642 0.0000\nvt 0.6217 0.2394 0.0000\nvt 0.6379 0.2367 0.0000\nvt 0.6341 0.2623 0.0000\nvt 0.6276 0.2172 0.0000\nvt 0.6331 0.1986 0.0000\nvt 0.6464 0.1921 0.0000\nvt 0.6425 0.2132 0.0000\nvt 0.6237 0.1982 0.0000\nvt 0.6150 0.2165 0.0000\nvt 0.6044 0.2111 0.0000\nvt 0.6167 0.1909 0.0000\nvt 0.6071 0.2383 0.0000\nvt 0.6007 0.2628 0.0000\nvt 0.5862 0.2582 0.0000\nvt 0.5942 0.2337 0.0000\nvt 0.5611 0.2450 0.0000\nvt 0.5723 0.2195 0.0000\nvt 0.5827 0.2269 0.0000\nvt 0.5730 0.2518 0.0000\nvt 0.5865 0.1951 0.0000\nvt 0.6034 0.1719 0.0000\nvt 0.6099 0.1815 0.0000\nvt 0.5951 0.2034 0.0000\nvt 0.3240 0.7791 0.0000\nvt 0.3270 0.7885 0.0000\nvt 0.2986 0.7897 0.0000\nvt 0.2962 0.7806 0.0000\nvt 0.3354 0.5544 0.0000\nvt 0.3365 0.5444 0.0000\nvt 0.3659 0.5442 0.0000\nvt 0.3646 0.5537 0.0000\nvt 0.2474 0.8090 0.0000\nvt 0.2467 0.8004 0.0000\nvt 0.2724 0.7998 0.0000\nvt 0.2733 0.8088 0.0000\nvt 0.2456 0.7919 0.0000\nvt 0.2438 0.7834 0.0000\nvt 0.2692 0.7821 0.0000\nvt 0.2711 0.7909 0.0000\nvt 0.3937 0.7461 0.0000\nvt 0.3951 0.7325 0.0000\nvt 0.4219 0.7309 0.0000\nvt 0.4194 0.7436 0.0000\nvt 0.3963 0.7186 0.0000\nvt 0.3968 0.7042 0.0000\nvt 0.4245 0.7038 0.0000\nvt 0.4237 0.7176 0.0000\nvt 0.0477 0.5456 0.0000\nvt 0.0494 0.5579 0.0000\nvt 0.0187 0.5590 0.0000\nvt 0.0166 0.5459 0.0000\nvt 0.0524 0.5698 0.0000\nvt 0.0562 0.5813 0.0000\nvt 0.0281 0.5837 0.0000\nvt 0.0226 0.5715 0.0000\nvt 0.0863 0.5796 0.0000\nvt 0.0838 0.5686 0.0000\nvt 0.1168 0.5679 0.0000\nvt 0.1185 0.5786 0.0000\nvt 0.0815 0.5571 0.0000\nvt 0.0803 0.5453 0.0000\nvt 0.1146 0.5451 0.0000\nvt 0.1154 0.5567 0.0000\nvt 0.1841 0.5449 0.0000\nvt 0.1841 0.5562 0.0000\nvt 0.1500 0.5564 0.0000\nvt 0.1496 0.5450 0.0000\nvt 0.1839 0.5672 0.0000\nvt 0.1836 0.5777 0.0000\nvt 0.1512 0.5780 0.0000\nvt 0.1506 0.5675 0.0000\nvt 0.2883 0.7501 0.0000\nvt 0.2882 0.7355 0.0000\nvt 0.3127 0.7352 0.0000\nvt 0.3129 0.7497 0.0000\nvt 0.2878 0.7204 0.0000\nvt 0.2877 0.7048 0.0000\nvt 0.3125 0.7047 0.0000\nvt 0.3125 0.7203 0.0000\nvt 0.3685 0.7045 0.0000\nvt 0.3682 0.7194 0.0000\nvt 0.3398 0.7200 0.0000\nvt 0.3399 0.7046 0.0000\nvt 0.3676 0.7339 0.0000\nvt 0.3669 0.7479 0.0000\nvt 0.3393 0.7490 0.0000\nvt 0.3397 0.7347 0.0000\nvt 0.5805 0.1448 0.0000\nvt 0.5858 0.1499 0.0000\nvt 0.5638 0.1760 0.0000\nvt 0.5578 0.1719 0.0000\nvt 0.5912 0.1560 0.0000\nvt 0.5971 0.1632 0.0000\nvt 0.5786 0.1876 0.0000\nvt 0.5708 0.1812 0.0000\nvt 0.5504 0.2390 0.0000\nvt 0.5399 0.2341 0.0000\nvt 0.5537 0.2071 0.0000\nvt 0.5629 0.2128 0.0000\nvt 0.2109 0.5963 0.0000\nvt 0.2129 0.5870 0.0000\nvt 0.2419 0.5864 0.0000\nvt 0.2388 0.5954 0.0000\nvt 0.2253 0.7502 0.0000\nvt 0.2251 0.7355 0.0000\nvt 0.2372 0.7355 0.0000\nvt 0.2374 0.7502 0.0000\nvt 0.2250 0.7203 0.0000\nvt 0.2250 0.7048 0.0000\nvt 0.2368 0.7048 0.0000\nvt 0.2369 0.7204 0.0000\nvt 0.2669 0.7048 0.0000\nvt 0.2671 0.7204 0.0000\nvt 0.2505 0.7204 0.0000\nvt 0.2503 0.7048 0.0000\nvt 0.2676 0.7356 0.0000\nvt 0.2678 0.7502 0.0000\nvt 0.2514 0.7503 0.0000\nvt 0.2509 0.7356 0.0000\nvt 0.7478 0.0076 0.0000\nvt 0.7477 0.0203 0.0000\nvt 0.7348 0.0231 0.0000\nvt 0.7352 0.0104 0.0000\nvt 0.7476 0.0341 0.0000\nvt 0.7475 0.0498 0.0000\nvt 0.7341 0.0523 0.0000\nvt 0.7346 0.0367 0.0000\nvt 0.7032 0.0669 0.0000\nvt 0.7035 0.0524 0.0000\nvt 0.7201 0.0426 0.0000\nvt 0.7196 0.0578 0.0000\nvt 0.7035 0.0399 0.0000\nvt 0.7038 0.0282 0.0000\nvt 0.7207 0.0172 0.0000\nvt 0.7204 0.0294 0.0000\nvt 0.0993 0.1514 0.0000\nvt 0.1078 0.1352 0.0000\nvt 0.1211 0.1284 0.0000\nvt 0.1122 0.1446 0.0000\nvt 0.1035 0.1273 0.0000\nvt 0.1175 0.1189 0.0000\nvt 0.0942 0.1435 0.0000\nvt 0.1415 0.0959 0.0000\nvt 0.1309 0.1121 0.0000\nvt 0.1281 0.1027 0.0000\nvt 0.1337 0.1231 0.0000\nvt 0.1436 0.1070 0.0000\nvt 0.0894 0.1369 0.0000\nvt 0.0994 0.1207 0.0000\nvt 0.1140 0.1110 0.0000\nvt 0.0950 0.1147 0.0000\nvt 0.0205 0.8523 0.0000\nvt 0.1106 0.1041 0.0000\nvt 0.0845 0.1313 0.0000\nvt 0.1372 0.0779 0.0000\nvt 0.1253 0.0946 0.0000\nvt 0.1227 0.0868 0.0000\nvt 0.0482 0.8506 0.0000\nvt 0.1393 0.0865 0.0000\nvt 0.1862 0.0353 0.0000\nvt 0.1749 0.0499 0.0000\nvt 0.1627 0.0550 0.0000\nvt 0.1750 0.0390 0.0000\nvt 0.1005 0.8474 0.0000\nvt 0.1756 0.0607 0.0000\nvt 0.1638 0.0647 0.0000\nvt 0.1859 0.0469 0.0000\nvt 0.1509 0.0706 0.0000\nvt 0.1526 0.0801 0.0000\nvt 0.1494 0.0615 0.0000\nvt 0.0748 0.8489 0.0000\nvt 0.1862 0.0589 0.0000\nvt 0.1761 0.0732 0.0000\nvt 0.1649 0.0756 0.0000\nvt 0.1763 0.0875 0.0000\nvt 0.1658 0.0882 0.0000\nvt 0.1861 0.0729 0.0000\nvt 0.1541 0.0911 0.0000\nvt 0.1555 0.1038 0.0000\nvt 0.0376 0.3517 0.0000\nvt 0.0408 0.3646 0.0000\nvt 0.0319 0.3622 0.0000\nvt 0.0311 0.3497 0.0000\nvt 0.0554 0.3779 0.0000\nvt 0.0451 0.3789 0.0000\nvt 0.0496 0.3630 0.0000\nvt 0.0392 0.3910 0.0000\nvt 0.0346 0.3764 0.0000\nvt 0.0507 0.3934 0.0000\nvt 0.0222 0.3562 0.0000\nvt 0.0234 0.3710 0.0000\nvt 0.0656 0.3737 0.0000\nvt 0.0734 0.3885 0.0000\nvt 0.0622 0.3925 0.0000\nvt 0.0936 0.3952 0.0000\nvt 0.0821 0.4024 0.0000\nvt 0.0842 0.3816 0.0000\nvt 0.0792 0.4198 0.0000\nvt 0.0701 0.4066 0.0000\nvt 0.0918 0.4149 0.0000\nvt 0.0578 0.4078 0.0000\nvt 0.0724 0.4492 0.0000\nvt 0.0458 0.6410 0.0000\nvt 0.0621 0.4346 0.0000\nvt 0.0760 0.4345 0.0000\nvt 0.0868 0.4472 0.0000\nvt 0.0392 0.4171 0.0000\nvt 0.0530 0.4205 0.0000\nvt 0.0474 0.4326 0.0000\nvt 0.0207 0.6438 0.0000\nvt 0.0663 0.4215 0.0000\nvt 0.0454 0.4058 0.0000\nvt 0.0895 0.4315 0.0000\nvt 0.0261 0.4107 0.0000\nvt 0.4443 0.5894 0.0000\nvt 0.0209 0.3934 0.0000\nvt 0.0330 0.4010 0.0000\nvt 0.0039 0.3677 0.0000\nvt 0.4872 0.5900 0.0000\nvt 0.0159 0.3776 0.0000\nvt 0.0087 0.3836 0.0000\nvt 0.4714 0.5867 0.0000\nvt 0.0276 0.3856 0.0000\nvt 0.0116 0.3631 0.0000\nvt 0.4919 0.5995 0.0000\nvt 0.1858 0.0888 0.0000\nvt 0.1762 0.1036 0.0000\nvt 0.1664 0.1027 0.0000\nvt 0.1756 0.1217 0.0000\nvt 0.1666 0.1190 0.0000\nvt 0.1850 0.1066 0.0000\nvt 0.1473 0.1343 0.0000\nvt 0.1566 0.1184 0.0000\nvt 0.1572 0.1347 0.0000\nvt 0.1456 0.1198 0.0000\nvt 0.1838 0.1262 0.0000\nvt 0.1744 0.1416 0.0000\nvt 0.1662 0.1372 0.0000\nvt 0.1725 0.1635 0.0000\nvt 0.1649 0.1573 0.0000\nvt 0.1821 0.1477 0.0000\nvt 0.1482 0.1681 0.0000\nvt 0.1570 0.1528 0.0000\nvt 0.1556 0.1729 0.0000\nvt 0.1483 0.1503 0.0000\nvt 0.1206 0.1907 0.0000\nvt 0.1250 0.1789 0.0000\nvt 0.1329 0.1792 0.0000\nvt 0.1266 0.1910 0.0000\nvt 0.1211 0.1671 0.0000\nvt 0.1312 0.1650 0.0000\nvt 0.1157 0.1816 0.0000\nvt 0.1402 0.1653 0.0000\nvt 0.1387 0.1500 0.0000\nvt 0.1398 0.1825 0.0000\nvt 0.1102 0.1712 0.0000\nvt 0.1168 0.1555 0.0000\nvt 0.1282 0.1518 0.0000\nvt 0.1247 0.1394 0.0000\nvt 0.1047 0.1608 0.0000\nvt 0.1364 0.1359 0.0000\nvt 0.1716 0.2785 0.0000\nvt 0.1620 0.2954 0.0000\nvt 0.1524 0.2837 0.0000\nvt 0.1624 0.2670 0.0000\nvt 0.1629 0.3236 0.0000\nvt 0.1526 0.3122 0.0000\nvt 0.1720 0.3068 0.0000\nvt 0.1330 0.3166 0.0000\nvt 0.1426 0.3003 0.0000\nvt 0.1432 0.3287 0.0000\nvt 0.1434 0.2720 0.0000\nvt 0.1333 0.2881 0.0000\nvt 0.1733 0.3341 0.0000\nvt 0.1645 0.3505 0.0000\nvt 0.1537 0.3401 0.0000\nvt 0.1668 0.3751 0.0000\nvt 0.1556 0.3663 0.0000\nvt 0.1754 0.3597 0.0000\nvt 0.1352 0.3712 0.0000\nvt 0.1446 0.3561 0.0000\nvt 0.1463 0.3812 0.0000\nvt 0.1338 0.3446 0.0000\nvt 0.0946 0.3721 0.0000\nvt 0.1044 0.3603 0.0000\nvt 0.1146 0.3734 0.0000\nvt 0.1045 0.3854 0.0000\nvt 0.1043 0.3331 0.0000\nvt 0.1140 0.3469 0.0000\nvt 0.0949 0.3460 0.0000\nvt 0.1244 0.3596 0.0000\nvt 0.1235 0.3322 0.0000\nvt 0.1254 0.3850 0.0000\nvt 0.0954 0.3184 0.0000\nvt 0.1049 0.3050 0.0000\nvt 0.1138 0.3189 0.0000\nvt 0.1070 0.2774 0.0000\nvt 0.1147 0.2907 0.0000\nvt 0.0970 0.2906 0.0000\nvt 0.1235 0.3038 0.0000\nvt 0.1248 0.2758 0.0000\nvt 0.0393 0.2687 0.0000\nvt 0.0305 0.2801 0.0000\nvt 0.0279 0.2641 0.0000\nvt 0.0375 0.2525 0.0000\nvt 0.0272 0.3068 0.0000\nvt 0.0225 0.2921 0.0000\nvt 0.0344 0.2957 0.0000\nvt 0.0104 0.2900 0.0000\nvt 0.5650 0.6017 0.0000\nvt 0.0191 0.2766 0.0000\nvt 0.0151 0.3050 0.0000\nvt 0.0263 0.2479 0.0000\nvt 0.0164 0.2603 0.0000\nvt 0.5947 0.6013 0.0000\nvt 0.0327 0.3207 0.0000\nvt 0.0273 0.3306 0.0000\nvt 0.0211 0.3186 0.0000\nvt 0.0239 0.3422 0.0000\nvt 0.0333 0.3410 0.0000\nvt 0.0135 0.3468 0.0000\nvt 0.5081 0.6036 0.0000\nvt 0.0168 0.3316 0.0000\nvt 0.0095 0.3189 0.0000\nvt 0.5361 0.6024 0.0000\nvt 0.5010 0.5845 0.0000\nvt 0.5182 0.5889 0.0000\nvt 0.5045 0.5942 0.0000\nvt 0.5492 0.5880 0.0000\nvt 0.5345 0.5932 0.0000\nvt 0.5327 0.5835 0.0000\nvt 0.5208 0.5984 0.0000\nvt 0.5500 0.5974 0.0000\nvt 0.5647 0.5828 0.0000\nvt 0.5806 0.5875 0.0000\nvt 0.5650 0.5925 0.0000\nvt 0.6114 0.5870 0.0000\nvt 0.5956 0.5920 0.0000\nvt 0.5965 0.5824 0.0000\nvt 0.5801 0.5969 0.0000\nvt 0.6100 0.5964 0.0000\nvt 0.1149 0.3971 0.0000\nvt 0.1037 0.4072 0.0000\nvt 0.1365 0.3949 0.0000\nvt 0.1259 0.4071 0.0000\nvt 0.1262 0.4261 0.0000\nvt 0.1146 0.4176 0.0000\nvt 0.1376 0.4154 0.0000\nvt 0.1024 0.4258 0.0000\nvt 0.1577 0.3897 0.0000\nvt 0.1480 0.4032 0.0000\nvt 0.1779 0.3824 0.0000\nvt 0.1692 0.3965 0.0000\nvt 0.1717 0.4149 0.0000\nvt 0.1599 0.4098 0.0000\nvt 0.1806 0.4019 0.0000\nvt 0.1496 0.4220 0.0000\nvt 0.1772 0.4449 0.0000\nvt 0.1505 0.6365 0.0000\nvt 0.1638 0.4421 0.0000\nvt 0.1741 0.4305 0.0000\nvt 0.1865 0.4332 0.0000\nvt 0.1393 0.4490 0.0000\nvt 0.1510 0.4382 0.0000\nvt 0.1525 0.4538 0.0000\nvt 0.1259 0.6369 0.0000\nvt 0.1618 0.4269 0.0000\nvt 0.1384 0.4329 0.0000\nvt 0.1832 0.4185 0.0000\nvt 0.1264 0.4580 0.0000\nvt 0.0997 0.6377 0.0000\nvt 0.1130 0.4503 0.0000\nvt 0.1262 0.4424 0.0000\nvt 0.1008 0.4417 0.0000\nvt 0.0988 0.4577 0.0000\nvt 0.0721 0.6389 0.0000\nvt 0.1139 0.4349 0.0000\nvt 0.0755 0.3666 0.0000\nvt 0.0853 0.3573 0.0000\nvt 0.0584 0.3582 0.0000\nvt 0.0675 0.3508 0.0000\nvt 0.0689 0.3251 0.0000\nvt 0.0767 0.3415 0.0000\nvt 0.0601 0.3345 0.0000\nvt 0.0860 0.3306 0.0000\nvt 0.0442 0.3483 0.0000\nvt 0.0518 0.3424 0.0000\nvt 0.0386 0.3343 0.0000\nvt 0.0395 0.3113 0.0000\nvt 0.0455 0.3267 0.0000\nvt 0.0534 0.3181 0.0000\nvt 0.0488 0.2582 0.0000\nvt 0.0517 0.2748 0.0000\nvt 0.0427 0.2852 0.0000\nvt 0.0655 0.2815 0.0000\nvt 0.0562 0.2917 0.0000\nvt 0.0614 0.2648 0.0000\nvt 0.0475 0.3016 0.0000\nvt 0.0620 0.3085 0.0000\nvt 0.0752 0.2712 0.0000\nvt 0.0806 0.2872 0.0000\nvt 0.0711 0.2981 0.0000\nvt 0.0874 0.3030 0.0000\nvt 0.0904 0.2758 0.0000\nvt 0.0780 0.3145 0.0000\nvt 0.7353 0.5442 0.0000\nvt 0.7203 0.5495 0.0000\nvt 0.7062 0.5444 0.0000\nvt 0.7209 0.5391 0.0000\nvt 0.7187 0.5598 0.0000\nvt 0.7051 0.5549 0.0000\nvt 0.7342 0.5545 0.0000\nvt 0.6758 0.5553 0.0000\nvt 0.6911 0.5498 0.0000\nvt 0.6897 0.5604 0.0000\nvt 0.6916 0.5391 0.0000\nvt 0.6766 0.5446 0.0000\nvt 0.7317 0.5645 0.0000\nvt 0.0017 0.8387 0.0000\nvt 0.7158 0.5698 0.0000\nvt 0.7031 0.5652 0.0000\nvt 0.7126 0.5796 0.0000\nvt 0.0698 0.1424 0.0000\nvt 0.7003 0.5752 0.0000\nvt 0.7281 0.5742 0.0000\nvt 0.0050 0.8483 0.0000\nvt 0.6722 0.5762 0.0000\nvt 0.6876 0.5706 0.0000\nvt 0.6851 0.5808 0.0000\nvt 0.0469 0.1699 0.0000\nvt 0.6742 0.5659 0.0000\nvt 0.6127 0.5772 0.0000\nvt 0.6287 0.5718 0.0000\nvt 0.6430 0.5767 0.0000\nvt 0.6272 0.5819 0.0000\nvt 0.6297 0.5612 0.0000\nvt 0.6446 0.5664 0.0000\nvt 0.6135 0.5668 0.0000\nvt 0.6587 0.5713 0.0000\nvt 0.6603 0.5609 0.0000\nvt 0.6566 0.5814 0.0000\nvt 0.6140 0.5559 0.0000\nvt 0.6303 0.5503 0.0000\nvt 0.6456 0.5557 0.0000\nvt 0.6304 0.5391 0.0000\nvt 0.6462 0.5447 0.0000\nvt 0.6142 0.5448 0.0000\nvt 0.6613 0.5501 0.0000\nvt 0.6616 0.5391 0.0000\nvt 0.1861 0.3675 0.0000\nvt 0.1965 0.3742 0.0000\nvt 0.1887 0.3883 0.0000\nvt 0.2137 0.3664 0.0000\nvt 0.2064 0.3798 0.0000\nvt 0.2041 0.3597 0.0000\nvt 0.2088 0.3969 0.0000\nvt 0.1991 0.3930 0.0000\nvt 0.2157 0.3847 0.0000\nvt 0.1915 0.4060 0.0000\nvt 0.2212 0.3531 0.0000\nvt 0.2301 0.3606 0.0000\nvt 0.2228 0.3725 0.0000\nvt 0.2460 0.3583 0.0000\nvt 0.2384 0.3681 0.0000\nvt 0.2378 0.3490 0.0000\nvt 0.2389 0.3846 0.0000\nvt 0.2312 0.3785 0.0000\nvt 0.2460 0.3760 0.0000\nvt 0.2244 0.3893 0.0000\nvt 0.2400 0.4100 0.0000\nvt 0.2134 0.6363 0.0000\nvt 0.2334 0.4068 0.0000\nvt 0.2395 0.3985 0.0000\nvt 0.2460 0.4033 0.0000\nvt 0.2201 0.4134 0.0000\nvt 0.2260 0.4035 0.0000\nvt 0.2280 0.4159 0.0000\nvt 0.2013 0.6363 0.0000\nvt 0.2323 0.3938 0.0000\nvt 0.2178 0.4003 0.0000\nvt 0.2460 0.3912 0.0000\nvt 0.2139 0.4243 0.0000\nvt 0.1872 0.6363 0.0000\nvt 0.2043 0.4231 0.0000\nvt 0.2112 0.4115 0.0000\nvt 0.1942 0.4212 0.0000\nvt 0.1976 0.4351 0.0000\nvt 0.1710 0.6363 0.0000\nvt 0.2017 0.4091 0.0000\nvt 0.1950 0.0748 0.0000\nvt 0.2030 0.0787 0.0000\nvt 0.1942 0.0922 0.0000\nvt 0.2183 0.0720 0.0000\nvt 0.2103 0.0841 0.0000\nvt 0.2113 0.0661 0.0000\nvt 0.2091 0.1040 0.0000\nvt 0.2019 0.0973 0.0000\nvt 0.2174 0.0911 0.0000\nvt 0.1930 0.1114 0.0000\nvt 0.2259 0.0608 0.0000\nvt 0.2325 0.0682 0.0000\nvt 0.2251 0.0791 0.0000\nvt 0.2460 0.0671 0.0000\nvt 0.2392 0.0768 0.0000\nvt 0.2394 0.0584 0.0000\nvt 0.2388 0.0970 0.0000\nvt 0.2319 0.0875 0.0000\nvt 0.2460 0.0864 0.0000\nvt 0.2243 0.0993 0.0000\nvt 0.2381 0.1430 0.0000\nvt 0.2305 0.1316 0.0000\nvt 0.2385 0.1191 0.0000\nvt 0.2460 0.1305 0.0000\nvt 0.2148 0.1348 0.0000\nvt 0.2232 0.1213 0.0000\nvt 0.2221 0.1451 0.0000\nvt 0.2312 0.1086 0.0000\nvt 0.2161 0.1120 0.0000\nvt 0.2460 0.1076 0.0000\nvt 0.2059 0.1493 0.0000\nvt 0.1987 0.1402 0.0000\nvt 0.2076 0.1257 0.0000\nvt 0.1914 0.1325 0.0000\nvt 0.1894 0.1554 0.0000\nvt 0.2004 0.1178 0.0000\nvt 0.1813 0.2617 0.0000\nvt 0.1905 0.2732 0.0000\nvt 0.1812 0.2899 0.0000\nvt 0.2092 0.2687 0.0000\nvt 0.2000 0.2846 0.0000\nvt 0.2000 0.2569 0.0000\nvt 0.2008 0.3115 0.0000\nvt 0.1910 0.3010 0.0000\nvt 0.2095 0.2957 0.0000\nvt 0.1821 0.3175 0.0000\nvt 0.2185 0.2531 0.0000\nvt 0.2276 0.2654 0.0000\nvt 0.2185 0.2804 0.0000\nvt 0.2460 0.2642 0.0000\nvt 0.2369 0.2778 0.0000\nvt 0.2369 0.2510 0.0000\nvt 0.2371 0.3034 0.0000\nvt 0.2278 0.2919 0.0000\nvt 0.2460 0.2904 0.0000\nvt 0.2190 0.3065 0.0000\nvt 0.2291 0.3400 0.0000\nvt 0.2374 0.3273 0.0000\nvt 0.2460 0.3379 0.0000\nvt 0.2119 0.3452 0.0000\nvt 0.2200 0.3309 0.0000\nvt 0.2283 0.3169 0.0000\nvt 0.2105 0.3215 0.0000\nvt 0.2460 0.3152 0.0000\nvt 0.1941 0.3522 0.0000\nvt 0.2022 0.3368 0.0000\nvt 0.1838 0.3437 0.0000\nvt 0.1922 0.3276 0.0000\nvt 0.1178 0.8133 0.0000\nvt 0.1274 0.8174 0.0000\nvt 0.1181 0.8216 0.0000\nvt 0.1073 0.8175 0.0000\nvt 0.1440 0.8173 0.0000\nvt 0.1362 0.8214 0.0000\nvt 0.1360 0.8133 0.0000\nvt 0.1367 0.8294 0.0000\nvt 0.1278 0.8255 0.0000\nvt 0.1443 0.8253 0.0000\nvt 0.1079 0.8259 0.0000\nvt 0.1187 0.8298 0.0000\nvt 0.1514 0.8133 0.0000\nvt 0.1583 0.8173 0.0000\nvt 0.1515 0.8213 0.0000\nvt 0.1715 0.8173 0.0000\nvt 0.1650 0.8212 0.0000\nvt 0.1650 0.8133 0.0000\nvt 0.1651 0.8292 0.0000\nvt 0.1585 0.8252 0.0000\nvt 0.1715 0.8252 0.0000\nvt 0.1518 0.8292 0.0000\nvt 0.1653 0.8452 0.0000\nvt 0.2399 0.0014 0.0000\nvt 0.1590 0.8412 0.0000\nvt 0.1652 0.8372 0.0000\nvt 0.1715 0.8412 0.0000\nvt 0.1456 0.8414 0.0000\nvt 0.1522 0.8373 0.0000\nvt 0.1530 0.8453 0.0000\nvt 0.2275 0.0041 0.0000\nvt 0.1587 0.8332 0.0000\nvt 0.1447 0.8334 0.0000\nvt 0.1715 0.8332 0.0000\nvt 0.1384 0.8457 0.0000\nvt 0.2130 0.0111 0.0000\nvt 0.1294 0.8419 0.0000\nvt 0.1373 0.8376 0.0000\nvt 0.1108 0.8426 0.0000\nvt 0.1197 0.8381 0.0000\nvt 0.1217 0.8463 0.0000\nvt 0.1962 0.0222 0.0000\nvt 0.1285 0.8337 0.0000\nvt 0.1088 0.8343 0.0000\nvt 0.2460 0.1554 0.0000\nvt 0.2377 0.1688 0.0000\nvt 0.2297 0.1565 0.0000\nvt 0.2373 0.1958 0.0000\nvt 0.2289 0.1829 0.0000\nvt 0.2460 0.1819 0.0000\nvt 0.2117 0.1858 0.0000\nvt 0.2209 0.1708 0.0000\nvt 0.2198 0.1977 0.0000\nvt 0.2133 0.1595 0.0000\nvt 0.2460 0.2093 0.0000\nvt 0.2370 0.2234 0.0000\nvt 0.2282 0.2103 0.0000\nvt 0.2278 0.2381 0.0000\nvt 0.2460 0.2370 0.0000\nvt 0.2095 0.2409 0.0000\nvt 0.2189 0.2254 0.0000\nvt 0.2104 0.2131 0.0000\nvt 0.1725 0.2502 0.0000\nvt 0.1826 0.2337 0.0000\nvt 0.1911 0.2451 0.0000\nvt 0.1846 0.2064 0.0000\nvt 0.1925 0.2174 0.0000\nvt 0.1745 0.2227 0.0000\nvt 0.2008 0.2289 0.0000\nvt 0.2023 0.2014 0.0000\nvt 0.1771 0.1962 0.0000\nvt 0.1870 0.1802 0.0000\nvt 0.1945 0.1903 0.0000\nvt 0.1967 0.1644 0.0000\nvt 0.1798 0.1711 0.0000\nvt 0.2041 0.1746 0.0000\nvt 0.1698 0.1872 0.0000\nvt 0.1627 0.1793 0.0000\nvt 0.1668 0.2125 0.0000\nvt 0.1596 0.2032 0.0000\nvt 0.1426 0.2102 0.0000\nvt 0.1527 0.1950 0.0000\nvt 0.1491 0.2191 0.0000\nvt 0.1462 0.1880 0.0000\nvt 0.1641 0.2392 0.0000\nvt 0.1563 0.2288 0.0000\nvt 0.1537 0.2557 0.0000\nvt 0.1352 0.2605 0.0000\nvt 0.1458 0.2448 0.0000\nvt 0.1386 0.2344 0.0000\nvt 0.1006 0.2640 0.0000\nvt 0.1111 0.2515 0.0000\nvt 0.1173 0.2636 0.0000\nvt 0.1167 0.2279 0.0000\nvt 0.1217 0.2384 0.0000\nvt 0.1062 0.2394 0.0000\nvt 0.1279 0.2493 0.0000\nvt 0.1322 0.2247 0.0000\nvt 0.1130 0.2175 0.0000\nvt 0.1226 0.2073 0.0000\nvt 0.1269 0.2156 0.0000\nvt 0.1314 0.1957 0.0000\nvt 0.1199 0.1997 0.0000\nvt 0.1367 0.2023 0.0000\nvt 0.1113 0.2068 0.0000\nvt 0.1122 0.1949 0.0000\nvt 0.1029 0.2271 0.0000\nvt 0.1015 0.2142 0.0000\nvt 0.0917 0.2074 0.0000\nvt 0.1023 0.2007 0.0000\nvt 0.0911 0.2221 0.0000\nvt 0.1053 0.1863 0.0000\nvt 0.0957 0.2503 0.0000\nvt 0.0925 0.2364 0.0000\nvt 0.0853 0.2608 0.0000\nvt 0.0715 0.2552 0.0000\nvt 0.0819 0.2457 0.0000\nvt 0.0804 0.2304 0.0000\nvt 0.0477 0.2418 0.0000\nvt 0.0584 0.2321 0.0000\nvt 0.0590 0.2484 0.0000\nvt 0.0711 0.2072 0.0000\nvt 0.0694 0.2232 0.0000\nvt 0.0596 0.2160 0.0000\nvt 0.0696 0.2392 0.0000\nvt 0.0806 0.2150 0.0000\nvt 0.0746 0.1912 0.0000\nvt 0.0867 0.1834 0.0000\nvt 0.0828 0.1993 0.0000\nvt 0.0987 0.1767 0.0000\nvt 0.0922 0.1674 0.0000\nvt 0.0943 0.1923 0.0000\nvt 0.0175 0.8428 0.0000\nvt 0.0329 0.8468 0.0000\nvt 0.0144 0.8333 0.0000\nvt 0.7480 0.5591 0.0000\nvt 0.0302 0.8375 0.0000\nvt 0.0583 0.8363 0.0000\nvt 0.0455 0.8414 0.0000\nvt 0.0433 0.8323 0.0000\nvt 0.7771 0.5581 0.0000\nvt 0.0605 0.8453 0.0000\nvt 0.7494 0.5491 0.0000\nvt 0.7633 0.5538 0.0000\nvt 0.7500 0.5391 0.0000\nvt 0.7645 0.5440 0.0000\nvt 0.7941 0.5438 0.0000\nvt 0.0561 0.8179 0.0000\nvt 0.7786 0.5486 0.0000\nvt 0.7795 0.5391 0.0000\nvt 0.7925 0.5530 0.0000\nvt 0.0572 0.8272 0.0000\nvt 0.0959 0.8219 0.0000\nvt 0.0830 0.8177 0.0000\nvt 0.0955 0.8133 0.0000\nvt 0.0968 0.8304 0.0000\nvt 0.0837 0.8265 0.0000\nvt 0.0701 0.8223 0.0000\nvt 0.0712 0.8313 0.0000\nvt 0.0695 0.8133 0.0000\nvt 0.0981 0.8390 0.0000\nvt 0.0850 0.8352 0.0000\nvt 0.0867 0.8438 0.0000\nvt 0.0728 0.8401 0.0000\nvt 0.0582 0.6467 0.0000\nvt 0.0443 0.6545 0.0000\nvt 0.0322 0.6489 0.0000\nvt 0.0429 0.6682 0.0000\nvt 0.0302 0.6621 0.0000\nvt 0.0572 0.6605 0.0000\nvt 0.0035 0.6638 0.0000\nvt 0.4211 0.5722 0.0000\nvt 0.0180 0.6565 0.0000\nvt 0.0157 0.6695 0.0000\nvt 0.0066 0.6514 0.0000\nvt 0.4275 0.5846 0.0000\nvt 0.0564 0.6747 0.0000\nvt 0.0421 0.6824 0.0000\nvt 0.0287 0.6757 0.0000\nvt 0.0419 0.6969 0.0000\nvt 0.0281 0.6898 0.0000\nvt 0.0560 0.6895 0.0000\nvt 0.0005 0.6902 0.0000\nvt 0.4145 0.5459 0.0000\nvt 0.0146 0.6831 0.0000\nvt 0.0141 0.6969 0.0000\nvt 0.0014 0.6767 0.0000\nvt 0.4168 0.5593 0.0000\nvt 0.4771 0.5452 0.0000\nvt 0.4617 0.5515 0.0000\nvt 0.4454 0.5455 0.0000\nvt 0.4608 0.5391 0.0000\nvt 0.4641 0.5636 0.0000\nvt 0.4473 0.5581 0.0000\nvt 0.4785 0.5572 0.0000\nvt 0.4309 0.5522 0.0000\nvt 0.4336 0.5651 0.0000\nvt 0.4295 0.5391 0.0000\nvt 0.4811 0.5689 0.0000\nvt 0.4676 0.5754 0.0000\nvt 0.4508 0.5704 0.0000\nvt 0.4554 0.5822 0.0000\nvt 0.4841 0.5800 0.0000\nvt 0.4386 0.5774 0.0000\nvt 0.4984 0.5739 0.0000\nvt 0.5157 0.5787 0.0000\nvt 0.4959 0.5627 0.0000\nvt 0.5135 0.5679 0.0000\nvt 0.5470 0.5674 0.0000\nvt 0.5310 0.5730 0.0000\nvt 0.5294 0.5621 0.0000\nvt 0.5481 0.5780 0.0000\nvt 0.4941 0.5510 0.0000\nvt 0.5117 0.5566 0.0000\nvt 0.4935 0.5391 0.0000\nvt 0.5106 0.5450 0.0000\nvt 0.5454 0.5449 0.0000\nvt 0.5283 0.5507 0.0000\nvt 0.5278 0.5391 0.0000\nvt 0.5460 0.5563 0.0000\nvt 0.5974 0.5504 0.0000\nvt 0.5803 0.5448 0.0000\nvt 0.5974 0.5391 0.0000\nvt 0.5974 0.5615 0.0000\nvt 0.5805 0.5561 0.0000\nvt 0.5631 0.5505 0.0000\nvt 0.5636 0.5617 0.0000\nvt 0.5628 0.5391 0.0000\nvt 0.5971 0.5722 0.0000\nvt 0.5807 0.5670 0.0000\nvt 0.5808 0.5776 0.0000\nvt 0.5642 0.5726 0.0000\nvt 0.1614 0.6436 0.0000\nvt 0.1503 0.6510 0.0000\nvt 0.1383 0.6439 0.0000\nvt 0.1508 0.6658 0.0000\nvt 0.1387 0.6584 0.0000\nvt 0.1614 0.6582 0.0000\nvt 0.1128 0.6588 0.0000\nvt 0.1259 0.6513 0.0000\nvt 0.1261 0.6659 0.0000\nvt 0.1129 0.6443 0.0000\nvt 0.1619 0.6734 0.0000\nvt 0.1510 0.6811 0.0000\nvt 0.1390 0.6734 0.0000\nvt 0.1511 0.6969 0.0000\nvt 0.1391 0.6890 0.0000\nvt 0.1620 0.6890 0.0000\nvt 0.1128 0.6891 0.0000\nvt 0.1262 0.6812 0.0000\nvt 0.1262 0.6969 0.0000\nvt 0.1128 0.6737 0.0000\nvt 0.0703 0.6818 0.0000\nvt 0.0846 0.6892 0.0000\nvt 0.0702 0.6969 0.0000\nvt 0.0708 0.6671 0.0000\nvt 0.0848 0.6741 0.0000\nvt 0.0989 0.6814 0.0000\nvt 0.0990 0.6664 0.0000\nvt 0.0988 0.6969 0.0000\nvt 0.0715 0.6529 0.0000\nvt 0.0851 0.6594 0.0000\nvt 0.0856 0.6453 0.0000\nvt 0.0992 0.6519 0.0000\nvt 0.0752 0.1473 0.0000\nvt 0.0611 0.1583 0.0000\nvt 0.0805 0.1528 0.0000\nvt 0.0667 0.1630 0.0000\nvt 0.0450 0.1890 0.0000\nvt 0.6660 0.5947 0.0000\nvt 0.0528 0.1739 0.0000\nvt 0.0591 0.1784 0.0000\nvt 0.0386 0.1854 0.0000\nvt 0.6696 0.5858 0.0000\nvt 0.0862 0.1594 0.0000\nvt 0.0729 0.1685 0.0000\nvt 0.0796 0.1753 0.0000\nvt 0.0624 0.2001 0.0000\nvt 0.0668 0.1843 0.0000\nvt 0.0537 0.1940 0.0000\nvt 0.0372 0.2365 0.0000\nvt 0.0482 0.2258 0.0000\nvt 0.0266 0.2317 0.0000\nvt 0.6232 0.6006 0.0000\nvt 0.0386 0.2206 0.0000\nvt 0.0504 0.2099 0.0000\nvt 0.0410 0.2044 0.0000\nvt 0.6505 0.5996 0.0000\nvt 0.6252 0.5914 0.0000\nvt 0.6382 0.5956 0.0000\nvt 0.6408 0.5864 0.0000\nvt 0.6537 0.5906 0.0000\nvt 0.2194 0.6436 0.0000\nvt 0.2135 0.6509 0.0000\nvt 0.2075 0.6436 0.0000\nvt 0.2137 0.6658 0.0000\nvt 0.2077 0.6583 0.0000\nvt 0.2194 0.6583 0.0000\nvt 0.1950 0.6582 0.0000\nvt 0.2014 0.6509 0.0000\nvt 0.2018 0.6658 0.0000\nvt 0.1947 0.6435 0.0000\nvt 0.2194 0.6735 0.0000\nvt 0.2138 0.6812 0.0000\nvt 0.2079 0.6734 0.0000\nvt 0.2138 0.6969 0.0000\nvt 0.2080 0.6890 0.0000\nvt 0.2194 0.6890 0.0000\nvt 0.1955 0.6890 0.0000\nvt 0.2019 0.6812 0.0000\nvt 0.2020 0.6969 0.0000\nvt 0.1954 0.6734 0.0000\nvt 0.1718 0.6811 0.0000\nvt 0.1805 0.6890 0.0000\nvt 0.1718 0.6969 0.0000\nvt 0.1715 0.6657 0.0000\nvt 0.1804 0.6734 0.0000\nvt 0.1883 0.6811 0.0000\nvt 0.1881 0.6657 0.0000\nvt 0.1884 0.6969 0.0000\nvt 0.1709 0.6509 0.0000\nvt 0.1799 0.6582 0.0000\nvt 0.1793 0.6436 0.0000\nvt 0.1875 0.6508 0.0000\nvt 0.2460 0.0071 0.0000\nvt 0.2398 0.0139 0.0000\nvt 0.2336 0.0088 0.0000\nvt 0.2398 0.0269 0.0000\nvt 0.2334 0.0213 0.0000\nvt 0.2460 0.0199 0.0000\nvt 0.2199 0.0257 0.0000\nvt 0.2270 0.0168 0.0000\nvt 0.2268 0.0296 0.0000\nvt 0.2204 0.0130 0.0000\nvt 0.2460 0.0338 0.0000\nvt 0.2396 0.0417 0.0000\nvt 0.2333 0.0350 0.0000\nvt 0.2329 0.0507 0.0000\nvt 0.2460 0.0496 0.0000\nvt 0.2191 0.0546 0.0000\nvt 0.2264 0.0443 0.0000\nvt 0.2196 0.0392 0.0000\nvt 0.1955 0.0594 0.0000\nvt 0.2038 0.0619 0.0000\nvt 0.1956 0.0459 0.0000\nvt 0.2042 0.0470 0.0000\nvt 0.2120 0.0499 0.0000\nvt 0.2123 0.0357 0.0000\nvt 0.1956 0.0341 0.0000\nvt 0.2044 0.0340 0.0000\nvt 0.2045 0.0224 0.0000\nvt 0.2125 0.0233 0.0000\nvt 0.3798 0.1446 0.0000\nvt 0.3710 0.1284 0.0000\nvt 0.3843 0.1352 0.0000\nvt 0.3927 0.1514 0.0000\nvt 0.3484 0.1070 0.0000\nvt 0.3612 0.1121 0.0000\nvt 0.3583 0.1231 0.0000\nvt 0.3640 0.1027 0.0000\nvt 0.3746 0.1189 0.0000\nvt 0.3505 0.0959 0.0000\nvt 0.3979 0.1435 0.0000\nvt 0.3885 0.1273 0.0000\nvt 0.3366 0.1038 0.0000\nvt 0.3263 0.0882 0.0000\nvt 0.3379 0.0911 0.0000\nvt 0.3059 0.0729 0.0000\nvt 0.3160 0.0732 0.0000\nvt 0.3157 0.0875 0.0000\nvt 0.3165 0.0607 0.0000\nvt 0.3272 0.0756 0.0000\nvt 0.3059 0.0589 0.0000\nvt 0.3395 0.0801 0.0000\nvt 0.3171 0.0390 0.0000\nvt 0.2425 0.8474 0.0000\nvt 0.3294 0.0550 0.0000\nvt 0.3171 0.0499 0.0000\nvt 0.3059 0.0353 0.0000\nvt 0.3548 0.0779 0.0000\nvt 0.3411 0.0706 0.0000\nvt 0.3427 0.0615 0.0000\nvt 0.2682 0.8489 0.0000\nvt 0.3283 0.0647 0.0000\nvt 0.3528 0.0865 0.0000\nvt 0.3062 0.0469 0.0000\nvt 0.3693 0.0868 0.0000\nvt 0.2948 0.8506 0.0000\nvt 0.3815 0.1041 0.0000\nvt 0.3668 0.0946 0.0000\nvt 0.4076 0.1313 0.0000\nvt 0.3926 0.1207 0.0000\nvt 0.3970 0.1147 0.0000\nvt 0.3225 0.8524 0.0000\nvt 0.3781 0.1110 0.0000\nvt 0.4027 0.1369 0.0000\nvt 0.4609 0.3497 0.0000\nvt 0.4602 0.3622 0.0000\nvt 0.4512 0.3646 0.0000\nvt 0.4545 0.3517 0.0000\nvt 0.4687 0.3710 0.0000\nvt 0.4575 0.3764 0.0000\nvt 0.4699 0.3562 0.0000\nvt 0.4414 0.3934 0.0000\nvt 0.4470 0.3789 0.0000\nvt 0.4528 0.3910 0.0000\nvt 0.4425 0.3630 0.0000\nvt 0.4367 0.3779 0.0000\nvt 0.4805 0.3631 0.0000\nvt 0.0785 0.4788 0.0000\nvt 0.4762 0.3776 0.0000\nvt 0.4644 0.3856 0.0000\nvt 0.4834 0.3836 0.0000\nvt 0.0581 0.4917 0.0000\nvt 0.4712 0.3934 0.0000\nvt 0.4882 0.3677 0.0000\nvt 0.0739 0.4883 0.0000\nvt 0.4528 0.4171 0.0000\nvt 0.4590 0.4010 0.0000\nvt 0.4659 0.4107 0.0000\nvt 0.0309 0.4891 0.0000\nvt 0.4467 0.4058 0.0000\nvt 0.4053 0.4472 0.0000\nvt 0.4160 0.4345 0.0000\nvt 0.4300 0.4346 0.0000\nvt 0.4196 0.4492 0.0000\nvt 0.3930 0.6410 0.0000\nvt 0.4128 0.4198 0.0000\nvt 0.4258 0.4215 0.0000\nvt 0.4026 0.4315 0.0000\nvt 0.4391 0.4205 0.0000\nvt 0.4343 0.4078 0.0000\nvt 0.4447 0.4326 0.0000\nvt 0.4180 0.6438 0.0000\nvt 0.4003 0.4149 0.0000\nvt 0.4099 0.4024 0.0000\nvt 0.4219 0.4066 0.0000\nvt 0.4078 0.3816 0.0000\nvt 0.4187 0.3885 0.0000\nvt 0.3984 0.3952 0.0000\nvt 0.4299 0.3925 0.0000\nvt 0.4265 0.3737 0.0000\nvt 0.3257 0.1027 0.0000\nvt 0.3159 0.1036 0.0000\nvt 0.3063 0.0888 0.0000\nvt 0.3464 0.1198 0.0000\nvt 0.3355 0.1184 0.0000\nvt 0.3349 0.1347 0.0000\nvt 0.3255 0.1190 0.0000\nvt 0.3448 0.1343 0.0000\nvt 0.3070 0.1066 0.0000\nvt 0.3165 0.1217 0.0000\nvt 0.3674 0.1394 0.0000\nvt 0.3556 0.1359 0.0000\nvt 0.3874 0.1608 0.0000\nvt 0.3753 0.1555 0.0000\nvt 0.3709 0.1671 0.0000\nvt 0.3639 0.1518 0.0000\nvt 0.3818 0.1712 0.0000\nvt 0.3533 0.1500 0.0000\nvt 0.3654 0.1910 0.0000\nvt 0.3591 0.1792 0.0000\nvt 0.3671 0.1789 0.0000\nvt 0.3714 0.1907 0.0000\nvt 0.3439 0.1681 0.0000\nvt 0.3519 0.1653 0.0000\nvt 0.3523 0.1825 0.0000\nvt 0.3609 0.1650 0.0000\nvt 0.3438 0.1503 0.0000\nvt 0.3764 0.1816 0.0000\nvt 0.3365 0.1729 0.0000\nvt 0.3271 0.1573 0.0000\nvt 0.3351 0.1528 0.0000\nvt 0.3100 0.1477 0.0000\nvt 0.3177 0.1416 0.0000\nvt 0.3196 0.1635 0.0000\nvt 0.3259 0.1372 0.0000\nvt 0.3082 0.1262 0.0000\nvt 0.3297 0.2670 0.0000\nvt 0.3396 0.2837 0.0000\nvt 0.3300 0.2954 0.0000\nvt 0.3204 0.2785 0.0000\nvt 0.3587 0.2881 0.0000\nvt 0.3494 0.3003 0.0000\nvt 0.3486 0.2720 0.0000\nvt 0.3489 0.3287 0.0000\nvt 0.3395 0.3122 0.0000\nvt 0.3590 0.3166 0.0000\nvt 0.3201 0.3068 0.0000\nvt 0.3292 0.3236 0.0000\nvt 0.3673 0.2758 0.0000\nvt 0.3774 0.2907 0.0000\nvt 0.3686 0.3038 0.0000\nvt 0.3951 0.2906 0.0000\nvt 0.3872 0.3050 0.0000\nvt 0.3851 0.2774 0.0000\nvt 0.3877 0.3331 0.0000\nvt 0.3782 0.3189 0.0000\nvt 0.3967 0.3184 0.0000\nvt 0.3685 0.3322 0.0000\nvt 0.3876 0.3854 0.0000\nvt 0.3774 0.3734 0.0000\nvt 0.3876 0.3603 0.0000\nvt 0.3975 0.3721 0.0000\nvt 0.3569 0.3712 0.0000\nvt 0.3677 0.3596 0.0000\nvt 0.3667 0.3850 0.0000\nvt 0.3780 0.3469 0.0000\nvt 0.3582 0.3446 0.0000\nvt 0.3972 0.3460 0.0000\nvt 0.3457 0.3812 0.0000\nvt 0.3365 0.3663 0.0000\nvt 0.3475 0.3561 0.0000\nvt 0.3167 0.3597 0.0000\nvt 0.3275 0.3505 0.0000\nvt 0.3253 0.3751 0.0000\nvt 0.3383 0.3401 0.0000\nvt 0.3187 0.3341 0.0000\nvt 0.4546 0.2525 0.0000\nvt 0.4642 0.2641 0.0000\nvt 0.4616 0.2801 0.0000\nvt 0.4528 0.2687 0.0000\nvt 0.4757 0.2603 0.0000\nvt 0.1814 0.4758 0.0000\nvt 0.4730 0.2766 0.0000\nvt 0.4658 0.2479 0.0000\nvt 0.4770 0.3050 0.0000\nvt 0.4695 0.2921 0.0000\nvt 0.4816 0.2900 0.0000\nvt 0.1516 0.4757 0.0000\nvt 0.4577 0.2957 0.0000\nvt 0.4649 0.3068 0.0000\nvt 0.1966 0.4808 0.0000\nvt 0.1823 0.4853 0.0000\nvt 0.1668 0.4804 0.0000\nvt 0.1832 0.4952 0.0000\nvt 0.1672 0.4901 0.0000\nvt 0.1980 0.4904 0.0000\nvt 0.1359 0.4898 0.0000\nvt 0.1517 0.4851 0.0000\nvt 0.1514 0.4949 0.0000\nvt 0.1367 0.4802 0.0000\nvt 0.0912 0.4840 0.0000\nvt 0.1048 0.4892 0.0000\nvt 0.0877 0.4937 0.0000\nvt 0.0948 0.4745 0.0000\nvt 0.4786 0.3468 0.0000\nvt 0.1075 0.4796 0.0000\nvt 0.1212 0.4847 0.0000\nvt 0.1228 0.4752 0.0000\nvt 0.4826 0.3189 0.0000\nvt 0.1194 0.4945 0.0000\nvt 0.4681 0.3422 0.0000\nvt 0.4753 0.3316 0.0000\nvt 0.4588 0.3410 0.0000\nvt 0.4647 0.3306 0.0000\nvt 0.4709 0.3186 0.0000\nvt 0.4594 0.3207 0.0000\nvt 0.3883 0.4072 0.0000\nvt 0.3772 0.3971 0.0000\nvt 0.3897 0.4258 0.0000\nvt 0.3775 0.4176 0.0000\nvt 0.3545 0.4154 0.0000\nvt 0.3661 0.4071 0.0000\nvt 0.3659 0.4261 0.0000\nvt 0.3556 0.3949 0.0000\nvt 0.3913 0.4417 0.0000\nvt 0.3782 0.4349 0.0000\nvt 0.3933 0.4577 0.0000\nvt 0.3666 0.6389 0.0000\nvt 0.3790 0.4503 0.0000\nvt 0.3528 0.4490 0.0000\nvt 0.3658 0.4424 0.0000\nvt 0.3657 0.4580 0.0000\nvt 0.3390 0.6377 0.0000\nvt 0.3537 0.4329 0.0000\nvt 0.3056 0.4332 0.0000\nvt 0.3180 0.4305 0.0000\nvt 0.3282 0.4421 0.0000\nvt 0.3149 0.4449 0.0000\nvt 0.2882 0.6365 0.0000\nvt 0.3204 0.4149 0.0000\nvt 0.3302 0.4269 0.0000\nvt 0.3088 0.4185 0.0000\nvt 0.3411 0.4382 0.0000\nvt 0.3425 0.4220 0.0000\nvt 0.3395 0.4538 0.0000\nvt 0.3129 0.6369 0.0000\nvt 0.3115 0.4019 0.0000\nvt 0.3228 0.3965 0.0000\nvt 0.3322 0.4098 0.0000\nvt 0.3343 0.3897 0.0000\nvt 0.3142 0.3824 0.0000\nvt 0.3440 0.4032 0.0000\nvt 0.4068 0.3573 0.0000\nvt 0.4165 0.3666 0.0000\nvt 0.4061 0.3306 0.0000\nvt 0.4153 0.3415 0.0000\nvt 0.4319 0.3345 0.0000\nvt 0.4246 0.3508 0.0000\nvt 0.4231 0.3251 0.0000\nvt 0.4336 0.3582 0.0000\nvt 0.4047 0.3030 0.0000\nvt 0.4140 0.3145 0.0000\nvt 0.4017 0.2758 0.0000\nvt 0.4115 0.2872 0.0000\nvt 0.4266 0.2815 0.0000\nvt 0.4209 0.2981 0.0000\nvt 0.4169 0.2712 0.0000\nvt 0.4300 0.3085 0.0000\nvt 0.4494 0.2852 0.0000\nvt 0.4403 0.2748 0.0000\nvt 0.4432 0.2582 0.0000\nvt 0.4525 0.3113 0.0000\nvt 0.4446 0.3016 0.0000\nvt 0.4358 0.2917 0.0000\nvt 0.4387 0.3181 0.0000\nvt 0.4307 0.2648 0.0000\nvt 0.4535 0.3343 0.0000\nvt 0.4466 0.3267 0.0000\nvt 0.4478 0.3483 0.0000\nvt 0.4402 0.3424 0.0000\nvt 0.3076 0.5394 0.0000\nvt 0.2928 0.5340 0.0000\nvt 0.3070 0.5289 0.0000\nvt 0.3219 0.5343 0.0000\nvt 0.2633 0.5338 0.0000\nvt 0.2778 0.5285 0.0000\nvt 0.2783 0.5393 0.0000\nvt 0.2764 0.5179 0.0000\nvt 0.2918 0.5234 0.0000\nvt 0.2625 0.5229 0.0000\nvt 0.3209 0.5240 0.0000\nvt 0.3054 0.5185 0.0000\nvt 0.2483 0.5393 0.0000\nvt 0.2328 0.5337 0.0000\nvt 0.2480 0.5282 0.0000\nvt 0.2008 0.5336 0.0000\nvt 0.2169 0.5280 0.0000\nvt 0.2171 0.5393 0.0000\nvt 0.2164 0.5168 0.0000\nvt 0.2323 0.5225 0.0000\nvt 0.2006 0.5223 0.0000\nvt 0.2470 0.5173 0.0000\nvt 0.2139 0.4957 0.0000\nvt 0.2297 0.5011 0.0000\nvt 0.2154 0.5060 0.0000\nvt 0.1993 0.5005 0.0000\nvt 0.2589 0.5018 0.0000\nvt 0.2453 0.5066 0.0000\nvt 0.2433 0.4963 0.0000\nvt 0.2312 0.5116 0.0000\nvt 0.2609 0.5123 0.0000\nvt 0.2002 0.5112 0.0000\nvt 0.2718 0.4972 0.0000\nvt 0.4452 0.1699 0.0000\nvt 0.2870 0.5029 0.0000\nvt 0.2742 0.5075 0.0000\nvt 0.3148 0.5042 0.0000\nvt 0.3380 0.8485 0.0000\nvt 0.3025 0.5085 0.0000\nvt 0.2993 0.4986 0.0000\nvt 0.4223 0.1424 0.0000\nvt 0.2897 0.5131 0.0000\nvt 0.3183 0.5139 0.0000\nvt 0.3413 0.8388 0.0000\nvt 0.3033 0.3883 0.0000\nvt 0.2956 0.3742 0.0000\nvt 0.3060 0.3675 0.0000\nvt 0.3006 0.4060 0.0000\nvt 0.2930 0.3930 0.0000\nvt 0.2763 0.3847 0.0000\nvt 0.2857 0.3798 0.0000\nvt 0.2832 0.3969 0.0000\nvt 0.2880 0.3597 0.0000\nvt 0.2784 0.3664 0.0000\nvt 0.2978 0.4212 0.0000\nvt 0.2904 0.4091 0.0000\nvt 0.2944 0.4351 0.0000\nvt 0.2678 0.6363 0.0000\nvt 0.2877 0.4231 0.0000\nvt 0.2719 0.4134 0.0000\nvt 0.2809 0.4115 0.0000\nvt 0.2782 0.4243 0.0000\nvt 0.2515 0.6363 0.0000\nvt 0.2743 0.4003 0.0000\nvt 0.2526 0.3985 0.0000\nvt 0.2586 0.4068 0.0000\nvt 0.2520 0.4100 0.0000\nvt 0.2254 0.6363 0.0000\nvt 0.2531 0.3846 0.0000\nvt 0.2598 0.3938 0.0000\nvt 0.2660 0.4035 0.0000\nvt 0.2677 0.3893 0.0000\nvt 0.2641 0.4159 0.0000\nvt 0.2374 0.6363 0.0000\nvt 0.2537 0.3681 0.0000\nvt 0.2609 0.3785 0.0000\nvt 0.2542 0.3490 0.0000\nvt 0.2620 0.3606 0.0000\nvt 0.2693 0.3725 0.0000\nvt 0.2708 0.3531 0.0000\nvt 0.2979 0.0922 0.0000\nvt 0.2891 0.0787 0.0000\nvt 0.2970 0.0748 0.0000\nvt 0.2990 0.1114 0.0000\nvt 0.2902 0.0973 0.0000\nvt 0.2747 0.0911 0.0000\nvt 0.2817 0.0841 0.0000\nvt 0.2830 0.1040 0.0000\nvt 0.2808 0.0661 0.0000\nvt 0.2737 0.0720 0.0000\nvt 0.3006 0.1325 0.0000\nvt 0.2916 0.1178 0.0000\nvt 0.3026 0.1554 0.0000\nvt 0.2934 0.1402 0.0000\nvt 0.2773 0.1348 0.0000\nvt 0.2844 0.1257 0.0000\nvt 0.2861 0.1493 0.0000\nvt 0.2759 0.1120 0.0000\nvt 0.2536 0.1191 0.0000\nvt 0.2616 0.1316 0.0000\nvt 0.2540 0.1430 0.0000\nvt 0.2532 0.0970 0.0000\nvt 0.2608 0.1086 0.0000\nvt 0.2688 0.1213 0.0000\nvt 0.2678 0.0993 0.0000\nvt 0.2700 0.1451 0.0000\nvt 0.2529 0.0768 0.0000\nvt 0.2601 0.0875 0.0000\nvt 0.2526 0.0584 0.0000\nvt 0.2596 0.0682 0.0000\nvt 0.2669 0.0791 0.0000\nvt 0.2662 0.0608 0.0000\nvt 0.3109 0.2899 0.0000\nvt 0.3015 0.2732 0.0000\nvt 0.3107 0.2617 0.0000\nvt 0.3100 0.3175 0.0000\nvt 0.3011 0.3010 0.0000\nvt 0.2825 0.2957 0.0000\nvt 0.2921 0.2846 0.0000\nvt 0.2913 0.3115 0.0000\nvt 0.2921 0.2569 0.0000\nvt 0.2829 0.2687 0.0000\nvt 0.3083 0.3437 0.0000\nvt 0.2999 0.3276 0.0000\nvt 0.2980 0.3522 0.0000\nvt 0.2802 0.3452 0.0000\nvt 0.2899 0.3368 0.0000\nvt 0.2816 0.3215 0.0000\nvt 0.2547 0.3273 0.0000\nvt 0.2629 0.3400 0.0000\nvt 0.2550 0.3034 0.0000\nvt 0.2637 0.3169 0.0000\nvt 0.2721 0.3309 0.0000\nvt 0.2730 0.3065 0.0000\nvt 0.2552 0.2778 0.0000\nvt 0.2642 0.2919 0.0000\nvt 0.2552 0.2510 0.0000\nvt 0.2644 0.2654 0.0000\nvt 0.2735 0.2804 0.0000\nvt 0.2736 0.2531 0.0000\nvt 0.2357 0.8175 0.0000\nvt 0.2249 0.8216 0.0000\nvt 0.2156 0.8174 0.0000\nvt 0.2252 0.8133 0.0000\nvt 0.2242 0.8298 0.0000\nvt 0.2151 0.8255 0.0000\nvt 0.2351 0.8259 0.0000\nvt 0.1987 0.8253 0.0000\nvt 0.2068 0.8214 0.0000\nvt 0.2063 0.8294 0.0000\nvt 0.2070 0.8133 0.0000\nvt 0.1989 0.8173 0.0000\nvt 0.2341 0.8343 0.0000\nvt 0.2232 0.8381 0.0000\nvt 0.2145 0.8337 0.0000\nvt 0.2213 0.8463 0.0000\nvt 0.2959 0.0222 0.0000\nvt 0.2135 0.8419 0.0000\nvt 0.2322 0.8426 0.0000\nvt 0.1974 0.8414 0.0000\nvt 0.2056 0.8376 0.0000\nvt 0.2045 0.8457 0.0000\nvt 0.2791 0.0111 0.0000\nvt 0.1982 0.8334 0.0000\nvt 0.1778 0.8372 0.0000\nvt 0.1840 0.8412 0.0000\nvt 0.1777 0.8452 0.0000\nvt 0.2522 0.0014 0.0000\nvt 0.1779 0.8292 0.0000\nvt 0.1843 0.8332 0.0000\nvt 0.1908 0.8373 0.0000\nvt 0.1912 0.8292 0.0000\nvt 0.1900 0.8453 0.0000\nvt 0.2645 0.0041 0.0000\nvt 0.1780 0.8212 0.0000\nvt 0.1845 0.8252 0.0000\nvt 0.1780 0.8133 0.0000\nvt 0.1846 0.8173 0.0000\nvt 0.1915 0.8213 0.0000\nvt 0.1916 0.8133 0.0000\nvt 0.2624 0.1565 0.0000\nvt 0.2544 0.1688 0.0000\nvt 0.2788 0.1595 0.0000\nvt 0.2711 0.1708 0.0000\nvt 0.2722 0.1977 0.0000\nvt 0.2631 0.1829 0.0000\nvt 0.2803 0.1858 0.0000\nvt 0.2548 0.1958 0.0000\nvt 0.2954 0.1644 0.0000\nvt 0.2880 0.1746 0.0000\nvt 0.3123 0.1711 0.0000\nvt 0.3050 0.1802 0.0000\nvt 0.3075 0.2064 0.0000\nvt 0.2976 0.1903 0.0000\nvt 0.3150 0.1962 0.0000\nvt 0.2898 0.2014 0.0000\nvt 0.3010 0.2451 0.0000\nvt 0.3095 0.2337 0.0000\nvt 0.3196 0.2502 0.0000\nvt 0.2826 0.2409 0.0000\nvt 0.2912 0.2289 0.0000\nvt 0.2995 0.2174 0.0000\nvt 0.2816 0.2131 0.0000\nvt 0.3176 0.2227 0.0000\nvt 0.2643 0.2381 0.0000\nvt 0.2731 0.2254 0.0000\nvt 0.2550 0.2234 0.0000\nvt 0.2638 0.2103 0.0000\nvt 0.3294 0.1793 0.0000\nvt 0.3223 0.1872 0.0000\nvt 0.3459 0.1880 0.0000\nvt 0.3393 0.1950 0.0000\nvt 0.3429 0.2191 0.0000\nvt 0.3325 0.2032 0.0000\nvt 0.3495 0.2102 0.0000\nvt 0.3253 0.2125 0.0000\nvt 0.3606 0.1957 0.0000\nvt 0.3554 0.2023 0.0000\nvt 0.3722 0.1997 0.0000\nvt 0.3695 0.2073 0.0000\nvt 0.3754 0.2279 0.0000\nvt 0.3652 0.2156 0.0000\nvt 0.3790 0.2175 0.0000\nvt 0.3598 0.2247 0.0000\nvt 0.3747 0.2636 0.0000\nvt 0.3810 0.2515 0.0000\nvt 0.3915 0.2640 0.0000\nvt 0.3568 0.2605 0.0000\nvt 0.3641 0.2493 0.0000\nvt 0.3704 0.2384 0.0000\nvt 0.3535 0.2344 0.0000\nvt 0.3858 0.2394 0.0000\nvt 0.3383 0.2557 0.0000\nvt 0.3463 0.2448 0.0000\nvt 0.3279 0.2392 0.0000\nvt 0.3357 0.2288 0.0000\nvt 0.3799 0.1949 0.0000\nvt 0.3807 0.2068 0.0000\nvt 0.3867 0.1863 0.0000\nvt 0.3897 0.2007 0.0000\nvt 0.4009 0.2221 0.0000\nvt 0.3905 0.2142 0.0000\nvt 0.4003 0.2074 0.0000\nvt 0.3891 0.2271 0.0000\nvt 0.3934 0.1767 0.0000\nvt 0.3978 0.1923 0.0000\nvt 0.3998 0.1674 0.0000\nvt 0.4054 0.1834 0.0000\nvt 0.4209 0.2072 0.0000\nvt 0.4093 0.1993 0.0000\nvt 0.4175 0.1912 0.0000\nvt 0.4114 0.2150 0.0000\nvt 0.4331 0.2484 0.0000\nvt 0.4337 0.2321 0.0000\nvt 0.4444 0.2418 0.0000\nvt 0.4206 0.2552 0.0000\nvt 0.4225 0.2392 0.0000\nvt 0.4226 0.2232 0.0000\nvt 0.4117 0.2304 0.0000\nvt 0.4325 0.2160 0.0000\nvt 0.4067 0.2608 0.0000\nvt 0.4101 0.2457 0.0000\nvt 0.3963 0.2503 0.0000\nvt 0.3995 0.2364 0.0000\nvt 0.3100 0.8469 0.0000\nvt 0.3255 0.8429 0.0000\nvt 0.2825 0.8453 0.0000\nvt 0.2974 0.8415 0.0000\nvt 0.2997 0.8323 0.0000\nvt 0.3638 0.5204 0.0000\nvt 0.3128 0.8375 0.0000\nvt 0.2846 0.8363 0.0000\nvt 0.3285 0.8334 0.0000\nvt 0.3347 0.5193 0.0000\nvt 0.2563 0.8438 0.0000\nvt 0.2702 0.8401 0.0000\nvt 0.2448 0.8390 0.0000\nvt 0.2462 0.8304 0.0000\nvt 0.2580 0.8352 0.0000\nvt 0.2718 0.8313 0.0000\nvt 0.2475 0.8133 0.0000\nvt 0.2600 0.8177 0.0000\nvt 0.2471 0.8219 0.0000\nvt 0.2868 0.8179 0.0000\nvt 0.3807 0.5348 0.0000\nvt 0.2728 0.8223 0.0000\nvt 0.2734 0.8133 0.0000\nvt 0.2592 0.8265 0.0000\nvt 0.2858 0.8272 0.0000\nvt 0.3791 0.5255 0.0000\nvt 0.3662 0.5394 0.0000\nvt 0.3512 0.5345 0.0000\nvt 0.3653 0.5299 0.0000\nvt 0.3361 0.5294 0.0000\nvt 0.3367 0.5394 0.0000\nvt 0.3500 0.5248 0.0000\nvt 0.4066 0.6489 0.0000\nvt 0.3944 0.6545 0.0000\nvt 0.3805 0.6467 0.0000\nvt 0.4321 0.6514 0.0000\nvt 0.0142 0.4939 0.0000\nvt 0.4207 0.6565 0.0000\nvt 0.4230 0.6695 0.0000\nvt 0.4086 0.6621 0.0000\nvt 0.4353 0.6638 0.0000\nvt 0.0078 0.5063 0.0000\nvt 0.3815 0.6605 0.0000\nvt 0.3958 0.6682 0.0000\nvt 0.0421 0.4963 0.0000\nvt 0.0253 0.5012 0.0000\nvt 0.0708 0.4983 0.0000\nvt 0.0543 0.5031 0.0000\nvt 0.0508 0.5148 0.0000\nvt 0.0374 0.5081 0.0000\nvt 0.0678 0.5095 0.0000\nvt 0.0203 0.5134 0.0000\nvt 0.0475 0.5394 0.0000\nvt 0.0321 0.5330 0.0000\nvt 0.0484 0.5270 0.0000\nvt 0.0637 0.5333 0.0000\nvt 0.0012 0.5327 0.0000\nvt 0.4383 0.6902 0.0000\nvt 0.0175 0.5263 0.0000\nvt 0.0162 0.5394 0.0000\nvt 0.0340 0.5204 0.0000\nvt 0.0035 0.5192 0.0000\nvt 0.4373 0.6767 0.0000\nvt 0.0652 0.5213 0.0000\nvt 0.4246 0.6969 0.0000\nvt 0.4107 0.6898 0.0000\nvt 0.4241 0.6831 0.0000\nvt 0.3828 0.6895 0.0000\nvt 0.3966 0.6824 0.0000\nvt 0.3969 0.6969 0.0000\nvt 0.4100 0.6757 0.0000\nvt 0.3824 0.6747 0.0000\nvt 0.1023 0.4994 0.0000\nvt 0.0851 0.5044 0.0000\nvt 0.1348 0.4999 0.0000\nvt 0.1176 0.5051 0.0000\nvt 0.1161 0.5162 0.0000\nvt 0.1001 0.5103 0.0000\nvt 0.1337 0.5107 0.0000\nvt 0.0825 0.5157 0.0000\nvt 0.1674 0.5002 0.0000\nvt 0.1509 0.5054 0.0000\nvt 0.1838 0.5056 0.0000\nvt 0.1840 0.5166 0.0000\nvt 0.1674 0.5109 0.0000\nvt 0.1502 0.5164 0.0000\nvt 0.1841 0.5393 0.0000\nvt 0.1670 0.5335 0.0000\nvt 0.1841 0.5278 0.0000\nvt 0.1321 0.5335 0.0000\nvt 0.1497 0.5278 0.0000\nvt 0.1495 0.5393 0.0000\nvt 0.1671 0.5221 0.0000\nvt 0.1327 0.5220 0.0000\nvt 0.1145 0.5393 0.0000\nvt 0.0973 0.5334 0.0000\nvt 0.1149 0.5277 0.0000\nvt 0.0808 0.5274 0.0000\nvt 0.0801 0.5394 0.0000\nvt 0.0983 0.5218 0.0000\nvt 0.3004 0.6439 0.0000\nvt 0.2884 0.6510 0.0000\nvt 0.2773 0.6436 0.0000\nvt 0.3258 0.6443 0.0000\nvt 0.3128 0.6513 0.0000\nvt 0.3126 0.6659 0.0000\nvt 0.3001 0.6584 0.0000\nvt 0.3260 0.6588 0.0000\nvt 0.2773 0.6582 0.0000\nvt 0.2879 0.6658 0.0000\nvt 0.3531 0.6453 0.0000\nvt 0.3395 0.6519 0.0000\nvt 0.3672 0.6529 0.0000\nvt 0.3679 0.6671 0.0000\nvt 0.3536 0.6594 0.0000\nvt 0.3397 0.6664 0.0000\nvt 0.3685 0.6969 0.0000\nvt 0.3541 0.6892 0.0000\nvt 0.3684 0.6818 0.0000\nvt 0.3260 0.6891 0.0000\nvt 0.3399 0.6814 0.0000\nvt 0.3399 0.6969 0.0000\nvt 0.3540 0.6741 0.0000\nvt 0.3259 0.6737 0.0000\nvt 0.3125 0.6969 0.0000\nvt 0.2997 0.6890 0.0000\nvt 0.3125 0.6812 0.0000\nvt 0.2767 0.6890 0.0000\nvt 0.2877 0.6811 0.0000\nvt 0.2877 0.6969 0.0000\nvt 0.2997 0.6734 0.0000\nvt 0.2768 0.6734 0.0000\nvt 0.4309 0.1583 0.0000\nvt 0.4168 0.1473 0.0000\nvt 0.4534 0.1854 0.0000\nvt 0.2563 0.4919 0.0000\nvt 0.4392 0.1739 0.0000\nvt 0.4330 0.1784 0.0000\nvt 0.4253 0.1630 0.0000\nvt 0.4470 0.1890 0.0000\nvt 0.2527 0.4829 0.0000\nvt 0.4115 0.1528 0.0000\nvt 0.2275 0.4911 0.0000\nvt 0.2404 0.4869 0.0000\nvt 0.2119 0.4859 0.0000\nvt 0.2099 0.4765 0.0000\nvt 0.4655 0.2317 0.0000\nvt 0.2249 0.4817 0.0000\nvt 0.2372 0.4777 0.0000\nvt 0.4511 0.2044 0.0000\nvt 0.4438 0.2258 0.0000\nvt 0.4548 0.2365 0.0000\nvt 0.4296 0.2001 0.0000\nvt 0.4417 0.2099 0.0000\nvt 0.4535 0.2206 0.0000\nvt 0.4384 0.1940 0.0000\nvt 0.4125 0.1753 0.0000\nvt 0.4253 0.1843 0.0000\nvt 0.4059 0.1594 0.0000\nvt 0.4192 0.1685 0.0000\nvt 0.2313 0.6436 0.0000\nvt 0.2252 0.6509 0.0000\nvt 0.2440 0.6435 0.0000\nvt 0.2373 0.6509 0.0000\nvt 0.2370 0.6658 0.0000\nvt 0.2310 0.6583 0.0000\nvt 0.2438 0.6582 0.0000\nvt 0.2250 0.6658 0.0000\nvt 0.2594 0.6436 0.0000\nvt 0.2512 0.6508 0.0000\nvt 0.2678 0.6509 0.0000\nvt 0.2673 0.6657 0.0000\nvt 0.2588 0.6582 0.0000\nvt 0.2507 0.6657 0.0000\nvt 0.2669 0.6969 0.0000\nvt 0.2582 0.6890 0.0000\nvt 0.2670 0.6811 0.0000\nvt 0.2433 0.6890 0.0000\nvt 0.2504 0.6811 0.0000\nvt 0.2503 0.6969 0.0000\nvt 0.2583 0.6734 0.0000\nvt 0.2434 0.6734 0.0000\nvt 0.2368 0.6969 0.0000\nvt 0.2307 0.6890 0.0000\nvt 0.2368 0.6812 0.0000\nvt 0.2250 0.6812 0.0000\nvt 0.2250 0.6969 0.0000\nvt 0.2308 0.6734 0.0000\nvt 0.2585 0.0088 0.0000\nvt 0.2522 0.0139 0.0000\nvt 0.2717 0.0130 0.0000\nvt 0.2651 0.0168 0.0000\nvt 0.2653 0.0296 0.0000\nvt 0.2586 0.0213 0.0000\nvt 0.2722 0.0257 0.0000\nvt 0.2523 0.0269 0.0000\nvt 0.2876 0.0224 0.0000\nvt 0.2795 0.0233 0.0000\nvt 0.2965 0.0341 0.0000\nvt 0.2965 0.0459 0.0000\nvt 0.2877 0.0340 0.0000\nvt 0.2797 0.0357 0.0000\nvt 0.2883 0.0619 0.0000\nvt 0.2966 0.0594 0.0000\nvt 0.2729 0.0546 0.0000\nvt 0.2801 0.0499 0.0000\nvt 0.2878 0.0470 0.0000\nvt 0.2724 0.0392 0.0000\nvt 0.2591 0.0507 0.0000\nvt 0.2656 0.0443 0.0000\nvt 0.2524 0.0417 0.0000\nvt 0.2588 0.0350 0.0000\nvt 0.8878 0.1446 0.0000\nvt 0.8789 0.1284 0.0000\nvt 0.8922 0.1352 0.0000\nvt 0.9007 0.1514 0.0000\nvt 0.8564 0.1070 0.0000\nvt 0.8691 0.1121 0.0000\nvt 0.8663 0.1231 0.0000\nvt 0.8719 0.1027 0.0000\nvt 0.8825 0.1189 0.0000\nvt 0.8585 0.0959 0.0000\nvt 0.9058 0.1435 0.0000\nvt 0.8965 0.1273 0.0000\nvt 0.8445 0.1038 0.0000\nvt 0.8342 0.0882 0.0000\nvt 0.8459 0.0911 0.0000\nvt 0.8139 0.0729 0.0000\nvt 0.8239 0.0732 0.0000\nvt 0.8237 0.0875 0.0000\nvt 0.8244 0.0607 0.0000\nvt 0.8351 0.0756 0.0000\nvt 0.8138 0.0589 0.0000\nvt 0.8474 0.0801 0.0000\nvt 0.8250 0.0390 0.0000\nvt 0.1005 0.7792 0.0000\nvt 0.8373 0.0550 0.0000\nvt 0.8251 0.0499 0.0000\nvt 0.8138 0.0353 0.0000\nvt 0.8628 0.0779 0.0000\nvt 0.8491 0.0706 0.0000\nvt 0.8506 0.0615 0.0000\nvt 0.0748 0.7777 0.0000\nvt 0.8362 0.0647 0.0000\nvt 0.8607 0.0865 0.0000\nvt 0.8141 0.0469 0.0000\nvt 0.8773 0.0868 0.0000\nvt 0.0482 0.7760 0.0000\nvt 0.8894 0.1041 0.0000\nvt 0.8747 0.0946 0.0000\nvt 0.9155 0.1313 0.0000\nvt 0.9006 0.1207 0.0000\nvt 0.9050 0.1147 0.0000\nvt 0.0205 0.7743 0.0000\nvt 0.8860 0.1110 0.0000\nvt 0.9106 0.1369 0.0000\nvt 0.9689 0.3497 0.0000\nvt 0.9681 0.3622 0.0000\nvt 0.9592 0.3646 0.0000\nvt 0.9624 0.3517 0.0000\nvt 0.9766 0.3710 0.0000\nvt 0.9654 0.3764 0.0000\nvt 0.9778 0.3562 0.0000\nvt 0.9493 0.3934 0.0000\nvt 0.9549 0.3789 0.0000\nvt 0.9608 0.3910 0.0000\nvt 0.9504 0.3630 0.0000\nvt 0.9446 0.3779 0.0000\nvt 0.9884 0.3631 0.0000\nvt 0.4919 0.4788 0.0000\nvt 0.9841 0.3776 0.0000\nvt 0.9724 0.3856 0.0000\nvt 0.9913 0.3836 0.0000\nvt 0.4714 0.4916 0.0000\nvt 0.9791 0.3934 0.0000\nvt 0.9961 0.3677 0.0000\nvt 0.4872 0.4883 0.0000\nvt 0.9608 0.4171 0.0000\nvt 0.9670 0.4010 0.0000\nvt 0.9739 0.4107 0.0000\nvt 0.4443 0.4889 0.0000\nvt 0.9546 0.4058 0.0000\nvt 0.9132 0.4472 0.0000\nvt 0.9240 0.4345 0.0000\nvt 0.9379 0.4346 0.0000\nvt 0.9276 0.4492 0.0000\nvt 0.0458 0.7528 0.0000\nvt 0.9208 0.4198 0.0000\nvt 0.9337 0.4215 0.0000\nvt 0.9105 0.4315 0.0000\nvt 0.9470 0.4205 0.0000\nvt 0.9422 0.4078 0.0000\nvt 0.9526 0.4326 0.0000\nvt 0.0207 0.7500 0.0000\nvt 0.9082 0.4149 0.0000\nvt 0.9179 0.4024 0.0000\nvt 0.9299 0.4066 0.0000\nvt 0.9158 0.3816 0.0000\nvt 0.9266 0.3885 0.0000\nvt 0.9064 0.3952 0.0000\nvt 0.9378 0.3925 0.0000\nvt 0.9344 0.3737 0.0000\nvt 0.8336 0.1027 0.0000\nvt 0.8238 0.1036 0.0000\nvt 0.8142 0.0888 0.0000\nvt 0.8544 0.1198 0.0000\nvt 0.8434 0.1184 0.0000\nvt 0.8428 0.1347 0.0000\nvt 0.8334 0.1190 0.0000\nvt 0.8527 0.1343 0.0000\nvt 0.8150 0.1066 0.0000\nvt 0.8244 0.1217 0.0000\nvt 0.8753 0.1394 0.0000\nvt 0.8636 0.1359 0.0000\nvt 0.8953 0.1608 0.0000\nvt 0.8832 0.1555 0.0000\nvt 0.8789 0.1671 0.0000\nvt 0.8718 0.1518 0.0000\nvt 0.8898 0.1712 0.0000\nvt 0.8613 0.1500 0.0000\nvt 0.8734 0.1910 0.0000\nvt 0.8671 0.1792 0.0000\nvt 0.8750 0.1789 0.0000\nvt 0.8794 0.1907 0.0000\nvt 0.8518 0.1681 0.0000\nvt 0.8598 0.1653 0.0000\nvt 0.8602 0.1825 0.0000\nvt 0.8688 0.1650 0.0000\nvt 0.8517 0.1503 0.0000\nvt 0.8843 0.1816 0.0000\nvt 0.8444 0.1729 0.0000\nvt 0.8351 0.1573 0.0000\nvt 0.8430 0.1528 0.0000\nvt 0.8179 0.1477 0.0000\nvt 0.8256 0.1416 0.0000\nvt 0.8275 0.1635 0.0000\nvt 0.8338 0.1372 0.0000\nvt 0.8162 0.1262 0.0000\nvt 0.8376 0.2670 0.0000\nvt 0.8476 0.2837 0.0000\nvt 0.8380 0.2954 0.0000\nvt 0.8284 0.2785 0.0000\nvt 0.8667 0.2881 0.0000\nvt 0.8574 0.3003 0.0000\nvt 0.8566 0.2720 0.0000\nvt 0.8568 0.3287 0.0000\nvt 0.8474 0.3122 0.0000\nvt 0.8670 0.3166 0.0000\nvt 0.8280 0.3068 0.0000\nvt 0.8371 0.3236 0.0000\nvt 0.8752 0.2758 0.0000\nvt 0.8853 0.2907 0.0000\nvt 0.8765 0.3038 0.0000\nvt 0.9030 0.2906 0.0000\nvt 0.8951 0.3050 0.0000\nvt 0.8930 0.2774 0.0000\nvt 0.8957 0.3331 0.0000\nvt 0.8862 0.3189 0.0000\nvt 0.9046 0.3184 0.0000\nvt 0.8765 0.3322 0.0000\nvt 0.8955 0.3854 0.0000\nvt 0.8854 0.3734 0.0000\nvt 0.8956 0.3603 0.0000\nvt 0.9054 0.3721 0.0000\nvt 0.8648 0.3712 0.0000\nvt 0.8756 0.3596 0.0000\nvt 0.8746 0.3850 0.0000\nvt 0.8860 0.3469 0.0000\nvt 0.8662 0.3446 0.0000\nvt 0.9051 0.3460 0.0000\nvt 0.8537 0.3812 0.0000\nvt 0.8444 0.3663 0.0000\nvt 0.8554 0.3561 0.0000\nvt 0.8246 0.3597 0.0000\nvt 0.8355 0.3505 0.0000\nvt 0.8332 0.3751 0.0000\nvt 0.8463 0.3401 0.0000\nvt 0.8267 0.3341 0.0000\nvt 0.9625 0.2525 0.0000\nvt 0.9721 0.2641 0.0000\nvt 0.9695 0.2801 0.0000\nvt 0.9607 0.2687 0.0000\nvt 0.9836 0.2603 0.0000\nvt 0.5947 0.4770 0.0000\nvt 0.9809 0.2766 0.0000\nvt 0.9737 0.2479 0.0000\nvt 0.9849 0.3050 0.0000\nvt 0.9775 0.2921 0.0000\nvt 0.9896 0.2900 0.0000\nvt 0.5650 0.4766 0.0000\nvt 0.9656 0.2957 0.0000\nvt 0.9728 0.3068 0.0000\nvt 0.6100 0.4819 0.0000\nvt 0.5956 0.4863 0.0000\nvt 0.5801 0.4814 0.0000\nvt 0.5965 0.4959 0.0000\nvt 0.5806 0.4908 0.0000\nvt 0.6114 0.4912 0.0000\nvt 0.5492 0.4903 0.0000\nvt 0.5650 0.4858 0.0000\nvt 0.5647 0.4954 0.0000\nvt 0.5500 0.4809 0.0000\nvt 0.5045 0.4841 0.0000\nvt 0.5182 0.4894 0.0000\nvt 0.5010 0.4938 0.0000\nvt 0.5081 0.4747 0.0000\nvt 0.9865 0.3468 0.0000\nvt 0.5208 0.4799 0.0000\nvt 0.5345 0.4851 0.0000\nvt 0.5361 0.4758 0.0000\nvt 0.9905 0.3189 0.0000\nvt 0.5327 0.4948 0.0000\nvt 0.9761 0.3422 0.0000\nvt 0.9832 0.3316 0.0000\nvt 0.9667 0.3410 0.0000\nvt 0.9727 0.3306 0.0000\nvt 0.9789 0.3186 0.0000\nvt 0.9673 0.3207 0.0000\nvt 0.8963 0.4072 0.0000\nvt 0.8851 0.3971 0.0000\nvt 0.8976 0.4258 0.0000\nvt 0.8854 0.4176 0.0000\nvt 0.8624 0.4154 0.0000\nvt 0.8741 0.4071 0.0000\nvt 0.8738 0.4261 0.0000\nvt 0.8635 0.3949 0.0000\nvt 0.8992 0.4417 0.0000\nvt 0.8861 0.4349 0.0000\nvt 0.9012 0.4577 0.0000\nvt 0.0721 0.7549 0.0000\nvt 0.8870 0.4503 0.0000\nvt 0.8607 0.4490 0.0000\nvt 0.8738 0.4424 0.0000\nvt 0.8736 0.4580 0.0000\nvt 0.0997 0.7561 0.0000\nvt 0.8616 0.4329 0.0000\nvt 0.8135 0.4332 0.0000\nvt 0.8259 0.4305 0.0000\nvt 0.8362 0.4421 0.0000\nvt 0.8228 0.4449 0.0000\nvt 0.1505 0.7573 0.0000\nvt 0.8283 0.4149 0.0000\nvt 0.8382 0.4269 0.0000\nvt 0.8168 0.4185 0.0000\nvt 0.8490 0.4382 0.0000\nvt 0.8504 0.4220 0.0000\nvt 0.8475 0.4538 0.0000\nvt 0.1259 0.7569 0.0000\nvt 0.8194 0.4019 0.0000\nvt 0.8308 0.3965 0.0000\nvt 0.8401 0.4098 0.0000\nvt 0.8423 0.3897 0.0000\nvt 0.8221 0.3824 0.0000\nvt 0.8520 0.4032 0.0000\nvt 0.9147 0.3573 0.0000\nvt 0.9245 0.3666 0.0000\nvt 0.9140 0.3306 0.0000\nvt 0.9233 0.3415 0.0000\nvt 0.9399 0.3345 0.0000\nvt 0.9325 0.3508 0.0000\nvt 0.9311 0.3251 0.0000\nvt 0.9416 0.3582 0.0000\nvt 0.9126 0.3030 0.0000\nvt 0.9220 0.3145 0.0000\nvt 0.9096 0.2758 0.0000\nvt 0.9194 0.2872 0.0000\nvt 0.9345 0.2815 0.0000\nvt 0.9289 0.2981 0.0000\nvt 0.9248 0.2712 0.0000\nvt 0.9380 0.3085 0.0000\nvt 0.9573 0.2852 0.0000\nvt 0.9483 0.2748 0.0000\nvt 0.9512 0.2582 0.0000\nvt 0.9605 0.3113 0.0000\nvt 0.9525 0.3016 0.0000\nvt 0.9438 0.2917 0.0000\nvt 0.9466 0.3181 0.0000\nvt 0.9386 0.2648 0.0000\nvt 0.9614 0.3343 0.0000\nvt 0.9545 0.3267 0.0000\nvt 0.9558 0.3483 0.0000\nvt 0.9482 0.3424 0.0000\nvt 0.7062 0.5339 0.0000\nvt 0.7203 0.5288 0.0000\nvt 0.7353 0.5340 0.0000\nvt 0.6766 0.5337 0.0000\nvt 0.6911 0.5284 0.0000\nvt 0.6897 0.5179 0.0000\nvt 0.7051 0.5234 0.0000\nvt 0.6758 0.5229 0.0000\nvt 0.7342 0.5238 0.0000\nvt 0.7187 0.5184 0.0000\nvt 0.6462 0.5336 0.0000\nvt 0.6613 0.5282 0.0000\nvt 0.6142 0.5335 0.0000\nvt 0.6303 0.5280 0.0000\nvt 0.6297 0.5170 0.0000\nvt 0.6456 0.5226 0.0000\nvt 0.6140 0.5224 0.0000\nvt 0.6603 0.5174 0.0000\nvt 0.6272 0.4963 0.0000\nvt 0.6430 0.5016 0.0000\nvt 0.6287 0.5064 0.0000\nvt 0.6127 0.5011 0.0000\nvt 0.6722 0.5021 0.0000\nvt 0.6587 0.5069 0.0000\nvt 0.6566 0.4969 0.0000\nvt 0.6446 0.5119 0.0000\nvt 0.6742 0.5124 0.0000\nvt 0.6135 0.5115 0.0000\nvt 0.6851 0.4975 0.0000\nvt 0.9531 0.1699 0.0000\nvt 0.7003 0.5031 0.0000\nvt 0.6876 0.5076 0.0000\nvt 0.7281 0.5041 0.0000\nvt 0.0050 0.7783 0.0000\nvt 0.7158 0.5085 0.0000\nvt 0.7126 0.4987 0.0000\nvt 0.9302 0.1424 0.0000\nvt 0.7031 0.5131 0.0000\nvt 0.7317 0.5138 0.0000\nvt 0.0017 0.7880 0.0000\nvt 0.8113 0.3883 0.0000\nvt 0.8035 0.3742 0.0000\nvt 0.8139 0.3675 0.0000\nvt 0.8085 0.4060 0.0000\nvt 0.8009 0.3930 0.0000\nvt 0.7843 0.3847 0.0000\nvt 0.7936 0.3798 0.0000\nvt 0.7912 0.3969 0.0000\nvt 0.7959 0.3597 0.0000\nvt 0.7863 0.3664 0.0000\nvt 0.8058 0.4212 0.0000\nvt 0.7983 0.4091 0.0000\nvt 0.8024 0.4351 0.0000\nvt 0.1710 0.7575 0.0000\nvt 0.7957 0.4231 0.0000\nvt 0.7799 0.4134 0.0000\nvt 0.7888 0.4115 0.0000\nvt 0.7861 0.4243 0.0000\nvt 0.1872 0.7575 0.0000\nvt 0.7822 0.4003 0.0000\nvt 0.7540 0.4033 0.0000\nvt 0.7605 0.3985 0.0000\nvt 0.7666 0.4068 0.0000\nvt 0.7600 0.4100 0.0000\nvt 0.2134 0.7575 0.0000\nvt 0.7611 0.3846 0.0000\nvt 0.7677 0.3938 0.0000\nvt 0.7540 0.3912 0.0000\nvt 0.7740 0.4035 0.0000\nvt 0.7756 0.3893 0.0000\nvt 0.7720 0.4159 0.0000\nvt 0.2013 0.7575 0.0000\nvt 0.7540 0.3760 0.0000\nvt 0.7616 0.3681 0.0000\nvt 0.7688 0.3785 0.0000\nvt 0.7622 0.3490 0.0000\nvt 0.7699 0.3606 0.0000\nvt 0.7540 0.3583 0.0000\nvt 0.7772 0.3725 0.0000\nvt 0.7788 0.3531 0.0000\nvt 0.8058 0.0922 0.0000\nvt 0.7970 0.0787 0.0000\nvt 0.8050 0.0748 0.0000\nvt 0.8070 0.1114 0.0000\nvt 0.7981 0.0973 0.0000\nvt 0.7826 0.0911 0.0000\nvt 0.7897 0.0841 0.0000\nvt 0.7909 0.1040 0.0000\nvt 0.7887 0.0661 0.0000\nvt 0.7817 0.0720 0.0000\nvt 0.8086 0.1325 0.0000\nvt 0.7996 0.1178 0.0000\nvt 0.8106 0.1554 0.0000\nvt 0.8013 0.1402 0.0000\nvt 0.7852 0.1348 0.0000\nvt 0.7924 0.1257 0.0000\nvt 0.7941 0.1493 0.0000\nvt 0.7839 0.1120 0.0000\nvt 0.7540 0.1305 0.0000\nvt 0.7615 0.1191 0.0000\nvt 0.7695 0.1316 0.0000\nvt 0.7619 0.1430 0.0000\nvt 0.7612 0.0970 0.0000\nvt 0.7688 0.1086 0.0000\nvt 0.7540 0.1076 0.0000\nvt 0.7768 0.1213 0.0000\nvt 0.7757 0.0993 0.0000\nvt 0.7779 0.1451 0.0000\nvt 0.7540 0.0864 0.0000\nvt 0.7608 0.0768 0.0000\nvt 0.7681 0.0875 0.0000\nvt 0.7606 0.0584 0.0000\nvt 0.7675 0.0682 0.0000\nvt 0.7540 0.0671 0.0000\nvt 0.7749 0.0791 0.0000\nvt 0.7741 0.0608 0.0000\nvt 0.8188 0.2899 0.0000\nvt 0.8095 0.2732 0.0000\nvt 0.8187 0.2617 0.0000\nvt 0.8179 0.3175 0.0000\nvt 0.8090 0.3010 0.0000\nvt 0.7905 0.2957 0.0000\nvt 0.8000 0.2846 0.0000\nvt 0.7992 0.3115 0.0000\nvt 0.8000 0.2569 0.0000\nvt 0.7908 0.2687 0.0000\nvt 0.8162 0.3437 0.0000\nvt 0.8078 0.3276 0.0000\nvt 0.8059 0.3522 0.0000\nvt 0.7881 0.3452 0.0000\nvt 0.7978 0.3368 0.0000\nvt 0.7895 0.3215 0.0000\nvt 0.7540 0.3379 0.0000\nvt 0.7626 0.3273 0.0000\nvt 0.7709 0.3400 0.0000\nvt 0.7629 0.3034 0.0000\nvt 0.7717 0.3169 0.0000\nvt 0.7540 0.3152 0.0000\nvt 0.7800 0.3309 0.0000\nvt 0.7810 0.3065 0.0000\nvt 0.7540 0.2904 0.0000\nvt 0.7631 0.2778 0.0000\nvt 0.7722 0.2919 0.0000\nvt 0.7631 0.2510 0.0000\nvt 0.7724 0.2654 0.0000\nvt 0.7540 0.2642 0.0000\nvt 0.7815 0.2804 0.0000\nvt 0.7815 0.2531 0.0000\nvt 0.1073 0.8091 0.0000\nvt 0.1181 0.8050 0.0000\nvt 0.1274 0.8092 0.0000\nvt 0.1187 0.7968 0.0000\nvt 0.1278 0.8011 0.0000\nvt 0.1079 0.8007 0.0000\nvt 0.1443 0.8013 0.0000\nvt 0.1362 0.8052 0.0000\nvt 0.1367 0.7972 0.0000\nvt 0.1440 0.8093 0.0000\nvt 0.1088 0.7923 0.0000\nvt 0.1197 0.7885 0.0000\nvt 0.1285 0.7929 0.0000\nvt 0.1217 0.7803 0.0000\nvt 0.8038 0.0222 0.0000\nvt 0.1294 0.7847 0.0000\nvt 0.1108 0.7840 0.0000\nvt 0.1456 0.7852 0.0000\nvt 0.1373 0.7890 0.0000\nvt 0.1384 0.7809 0.0000\nvt 0.7870 0.0111 0.0000\nvt 0.1447 0.7932 0.0000\nvt 0.1715 0.7854 0.0000\nvt 0.1652 0.7894 0.0000\nvt 0.1590 0.7854 0.0000\nvt 0.1653 0.7814 0.0000\nvt 0.7601 0.0014 0.0000\nvt 0.1651 0.7974 0.0000\nvt 0.1587 0.7934 0.0000\nvt 0.1715 0.7934 0.0000\nvt 0.1522 0.7893 0.0000\nvt 0.1518 0.7974 0.0000\nvt 0.1530 0.7813 0.0000\nvt 0.7725 0.0041 0.0000\nvt 0.1715 0.8014 0.0000\nvt 0.1650 0.8054 0.0000\nvt 0.1585 0.8014 0.0000\nvt 0.1583 0.8093 0.0000\nvt 0.1715 0.8094 0.0000\nvt 0.1515 0.8054 0.0000\nvt 0.7703 0.1565 0.0000\nvt 0.7623 0.1688 0.0000\nvt 0.7540 0.1554 0.0000\nvt 0.7867 0.1595 0.0000\nvt 0.7791 0.1708 0.0000\nvt 0.7802 0.1977 0.0000\nvt 0.7711 0.1829 0.0000\nvt 0.7883 0.1858 0.0000\nvt 0.7540 0.1819 0.0000\nvt 0.7627 0.1958 0.0000\nvt 0.8033 0.1644 0.0000\nvt 0.7959 0.1746 0.0000\nvt 0.8202 0.1711 0.0000\nvt 0.8130 0.1802 0.0000\nvt 0.8154 0.2064 0.0000\nvt 0.8055 0.1903 0.0000\nvt 0.8229 0.1962 0.0000\nvt 0.7977 0.2014 0.0000\nvt 0.8089 0.2451 0.0000\nvt 0.8174 0.2337 0.0000\nvt 0.8275 0.2502 0.0000\nvt 0.7905 0.2409 0.0000\nvt 0.7992 0.2289 0.0000\nvt 0.8075 0.2174 0.0000\nvt 0.7896 0.2131 0.0000\nvt 0.8255 0.2227 0.0000\nvt 0.7722 0.2381 0.0000\nvt 0.7811 0.2254 0.0000\nvt 0.7540 0.2370 0.0000\nvt 0.7630 0.2234 0.0000\nvt 0.7718 0.2103 0.0000\nvt 0.7540 0.2093 0.0000\nvt 0.8373 0.1793 0.0000\nvt 0.8302 0.1872 0.0000\nvt 0.8538 0.1880 0.0000\nvt 0.8473 0.1950 0.0000\nvt 0.8509 0.2191 0.0000\nvt 0.8404 0.2032 0.0000\nvt 0.8574 0.2102 0.0000\nvt 0.8332 0.2125 0.0000\nvt 0.8686 0.1957 0.0000\nvt 0.8633 0.2023 0.0000\nvt 0.8801 0.1997 0.0000\nvt 0.8774 0.2073 0.0000\nvt 0.8833 0.2279 0.0000\nvt 0.8731 0.2156 0.0000\nvt 0.8870 0.2175 0.0000\nvt 0.8678 0.2247 0.0000\nvt 0.8827 0.2636 0.0000\nvt 0.8889 0.2515 0.0000\nvt 0.8994 0.2640 0.0000\nvt 0.8648 0.2605 0.0000\nvt 0.8721 0.2493 0.0000\nvt 0.8783 0.2384 0.0000\nvt 0.8614 0.2344 0.0000\nvt 0.8938 0.2394 0.0000\nvt 0.8463 0.2557 0.0000\nvt 0.8542 0.2448 0.0000\nvt 0.8359 0.2392 0.0000\nvt 0.8437 0.2288 0.0000\nvt 0.8878 0.1949 0.0000\nvt 0.8887 0.2068 0.0000\nvt 0.8947 0.1863 0.0000\nvt 0.8977 0.2007 0.0000\nvt 0.9089 0.2221 0.0000\nvt 0.8985 0.2142 0.0000\nvt 0.9083 0.2074 0.0000\nvt 0.8971 0.2271 0.0000\nvt 0.9013 0.1767 0.0000\nvt 0.9057 0.1923 0.0000\nvt 0.9078 0.1674 0.0000\nvt 0.9133 0.1834 0.0000\nvt 0.9289 0.2072 0.0000\nvt 0.9172 0.1993 0.0000\nvt 0.9254 0.1912 0.0000\nvt 0.9194 0.2150 0.0000\nvt 0.9410 0.2484 0.0000\nvt 0.9416 0.2321 0.0000\nvt 0.9523 0.2418 0.0000\nvt 0.9285 0.2552 0.0000\nvt 0.9304 0.2392 0.0000\nvt 0.9306 0.2232 0.0000\nvt 0.9196 0.2304 0.0000\nvt 0.9404 0.2160 0.0000\nvt 0.9147 0.2608 0.0000\nvt 0.9181 0.2457 0.0000\nvt 0.9043 0.2503 0.0000\nvt 0.9075 0.2364 0.0000\nvt 0.0329 0.7798 0.0000\nvt 0.0175 0.7838 0.0000\nvt 0.0605 0.7814 0.0000\nvt 0.0455 0.7852 0.0000\nvt 0.0433 0.7943 0.0000\nvt 0.7771 0.5201 0.0000\nvt 0.0302 0.7891 0.0000\nvt 0.0583 0.7903 0.0000\nvt 0.0144 0.7933 0.0000\nvt 0.7480 0.5191 0.0000\nvt 0.0867 0.7828 0.0000\nvt 0.0728 0.7865 0.0000\nvt 0.0981 0.7876 0.0000\nvt 0.0968 0.7962 0.0000\nvt 0.0850 0.7914 0.0000\nvt 0.0712 0.7953 0.0000\nvt 0.0830 0.8089 0.0000\nvt 0.0959 0.8047 0.0000\nvt 0.0561 0.8087 0.0000\nvt 0.7941 0.5345 0.0000\nvt 0.0701 0.8043 0.0000\nvt 0.0837 0.8001 0.0000\nvt 0.0572 0.7994 0.0000\nvt 0.7925 0.5253 0.0000\nvt 0.7645 0.5343 0.0000\nvt 0.7786 0.5296 0.0000\nvt 0.7494 0.5292 0.0000\nvt 0.7633 0.5245 0.0000\nvt 0.0322 0.7449 0.0000\nvt 0.0443 0.7393 0.0000\nvt 0.0582 0.7471 0.0000\nvt 0.0066 0.7424 0.0000\nvt 0.4275 0.4937 0.0000\nvt 0.0180 0.7373 0.0000\nvt 0.0157 0.7243 0.0000\nvt 0.0302 0.7317 0.0000\nvt 0.0035 0.7300 0.0000\nvt 0.4211 0.5060 0.0000\nvt 0.0572 0.7333 0.0000\nvt 0.0429 0.7256 0.0000\nvt 0.4554 0.4961 0.0000\nvt 0.4386 0.5009 0.0000\nvt 0.4841 0.4982 0.0000\nvt 0.4676 0.5029 0.0000\nvt 0.4641 0.5146 0.0000\nvt 0.4508 0.5079 0.0000\nvt 0.4811 0.5094 0.0000\nvt 0.4336 0.5132 0.0000\nvt 0.4454 0.5328 0.0000\nvt 0.4617 0.5268 0.0000\nvt 0.4771 0.5331 0.0000\nvt 0.4145 0.5324 0.0000\nvt 0.0005 0.7036 0.0000\nvt 0.4309 0.5261 0.0000\nvt 0.4473 0.5202 0.0000\nvt 0.4168 0.5189 0.0000\nvt 0.0014 0.7171 0.0000\nvt 0.4785 0.5211 0.0000\nvt 0.0281 0.7040 0.0000\nvt 0.0146 0.7107 0.0000\nvt 0.0560 0.7043 0.0000\nvt 0.0421 0.7114 0.0000\nvt 0.0287 0.7181 0.0000\nvt 0.0564 0.7191 0.0000\nvt 0.5157 0.4995 0.0000\nvt 0.4984 0.5044 0.0000\nvt 0.5481 0.5003 0.0000\nvt 0.5310 0.5052 0.0000\nvt 0.5294 0.5162 0.0000\nvt 0.5135 0.5104 0.0000\nvt 0.5470 0.5109 0.0000\nvt 0.4959 0.5156 0.0000\nvt 0.5808 0.5007 0.0000\nvt 0.5642 0.5057 0.0000\nvt 0.5971 0.5061 0.0000\nvt 0.5974 0.5168 0.0000\nvt 0.5807 0.5112 0.0000\nvt 0.5636 0.5166 0.0000\nvt 0.5803 0.5335 0.0000\nvt 0.5974 0.5279 0.0000\nvt 0.5454 0.5334 0.0000\nvt 0.5631 0.5278 0.0000\nvt 0.5805 0.5222 0.0000\nvt 0.5460 0.5220 0.0000\nvt 0.5106 0.5333 0.0000\nvt 0.5283 0.5276 0.0000\nvt 0.4941 0.5273 0.0000\nvt 0.5117 0.5217 0.0000\nvt 0.1383 0.7499 0.0000\nvt 0.1503 0.7428 0.0000\nvt 0.1614 0.7502 0.0000\nvt 0.1129 0.7495 0.0000\nvt 0.1259 0.7425 0.0000\nvt 0.1261 0.7279 0.0000\nvt 0.1387 0.7354 0.0000\nvt 0.1128 0.7350 0.0000\nvt 0.1614 0.7356 0.0000\nvt 0.1508 0.7280 0.0000\nvt 0.0856 0.7485 0.0000\nvt 0.0992 0.7419 0.0000\nvt 0.0715 0.7409 0.0000\nvt 0.0708 0.7267 0.0000\nvt 0.0851 0.7344 0.0000\nvt 0.0990 0.7274 0.0000\nvt 0.0846 0.7046 0.0000\nvt 0.0703 0.7120 0.0000\nvt 0.1128 0.7047 0.0000\nvt 0.0989 0.7123 0.0000\nvt 0.0848 0.7197 0.0000\nvt 0.1128 0.7201 0.0000\nvt 0.1391 0.7048 0.0000\nvt 0.1262 0.7126 0.0000\nvt 0.1620 0.7048 0.0000\nvt 0.1510 0.7126 0.0000\nvt 0.1390 0.7204 0.0000\nvt 0.1619 0.7204 0.0000\nvt 0.9389 0.1583 0.0000\nvt 0.9248 0.1473 0.0000\nvt 0.9614 0.1854 0.0000\nvt 0.6696 0.4925 0.0000\nvt 0.9472 0.1739 0.0000\nvt 0.9409 0.1784 0.0000\nvt 0.9333 0.1630 0.0000\nvt 0.9550 0.1890 0.0000\nvt 0.6660 0.4836 0.0000\nvt 0.9195 0.1528 0.0000\nvt 0.6408 0.4919 0.0000\nvt 0.6537 0.4876 0.0000\nvt 0.6252 0.4869 0.0000\nvt 0.6232 0.4777 0.0000\nvt 0.9734 0.2317 0.0000\nvt 0.6382 0.4827 0.0000\nvt 0.6505 0.4787 0.0000\nvt 0.9590 0.2044 0.0000\nvt 0.9518 0.2258 0.0000\nvt 0.9628 0.2365 0.0000\nvt 0.9376 0.2001 0.0000\nvt 0.9496 0.2099 0.0000\nvt 0.9614 0.2206 0.0000\nvt 0.9463 0.1940 0.0000\nvt 0.9204 0.1753 0.0000\nvt 0.9332 0.1843 0.0000\nvt 0.9138 0.1594 0.0000\nvt 0.9271 0.1685 0.0000\nvt 0.2075 0.7502 0.0000\nvt 0.2135 0.7429 0.0000\nvt 0.2194 0.7502 0.0000\nvt 0.1947 0.7503 0.0000\nvt 0.2014 0.7429 0.0000\nvt 0.2018 0.7280 0.0000\nvt 0.2077 0.7355 0.0000\nvt 0.1950 0.7356 0.0000\nvt 0.2194 0.7355 0.0000\nvt 0.2137 0.7280 0.0000\nvt 0.1793 0.7502 0.0000\nvt 0.1875 0.7430 0.0000\nvt 0.1709 0.7429 0.0000\nvt 0.1715 0.7281 0.0000\nvt 0.1799 0.7356 0.0000\nvt 0.1881 0.7281 0.0000\nvt 0.1805 0.7048 0.0000\nvt 0.1718 0.7127 0.0000\nvt 0.1955 0.7048 0.0000\nvt 0.1883 0.7126 0.0000\nvt 0.1804 0.7204 0.0000\nvt 0.1954 0.7204 0.0000\nvt 0.2080 0.7048 0.0000\nvt 0.2019 0.7126 0.0000\nvt 0.2194 0.7048 0.0000\nvt 0.2138 0.7126 0.0000\nvt 0.2079 0.7203 0.0000\nvt 0.2194 0.7203 0.0000\nvt 0.7664 0.0088 0.0000\nvt 0.7602 0.0139 0.0000\nvt 0.7540 0.0071 0.0000\nvt 0.7796 0.0130 0.0000\nvt 0.7730 0.0168 0.0000\nvt 0.7732 0.0296 0.0000\nvt 0.7666 0.0213 0.0000\nvt 0.7801 0.0257 0.0000\nvt 0.7540 0.0199 0.0000\nvt 0.7602 0.0269 0.0000\nvt 0.7955 0.0224 0.0000\nvt 0.7875 0.0233 0.0000\nvt 0.8044 0.0341 0.0000\nvt 0.8044 0.0459 0.0000\nvt 0.7956 0.0340 0.0000\nvt 0.7877 0.0357 0.0000\nvt 0.7962 0.0619 0.0000\nvt 0.8045 0.0594 0.0000\nvt 0.7809 0.0546 0.0000\nvt 0.7880 0.0499 0.0000\nvt 0.7958 0.0470 0.0000\nvt 0.7804 0.0392 0.0000\nvt 0.7671 0.0507 0.0000\nvt 0.7736 0.0443 0.0000\nvt 0.7540 0.0496 0.0000\nvt 0.7604 0.0417 0.0000\nvt 0.7667 0.0350 0.0000\nvt 0.7540 0.0338 0.0000\nvt 0.6073 0.1514 0.0000\nvt 0.6157 0.1352 0.0000\nvt 0.6290 0.1284 0.0000\nvt 0.6202 0.1446 0.0000\nvt 0.6115 0.1273 0.0000\nvt 0.6254 0.1189 0.0000\nvt 0.6021 0.1435 0.0000\nvt 0.6495 0.0959 0.0000\nvt 0.6388 0.1121 0.0000\nvt 0.6360 0.1027 0.0000\nvt 0.6417 0.1231 0.0000\nvt 0.6516 0.1070 0.0000\nvt 0.5973 0.1369 0.0000\nvt 0.6074 0.1207 0.0000\nvt 0.6219 0.1110 0.0000\nvt 0.6030 0.1147 0.0000\nvt 0.3225 0.7743 0.0000\nvt 0.6185 0.1041 0.0000\nvt 0.5924 0.1313 0.0000\nvt 0.6452 0.0779 0.0000\nvt 0.6332 0.0946 0.0000\nvt 0.6307 0.0868 0.0000\nvt 0.2948 0.7760 0.0000\nvt 0.6472 0.0865 0.0000\nvt 0.6941 0.0353 0.0000\nvt 0.6829 0.0499 0.0000\nvt 0.6706 0.0550 0.0000\nvt 0.6829 0.0390 0.0000\nvt 0.2425 0.7792 0.0000\nvt 0.6835 0.0607 0.0000\nvt 0.6717 0.0647 0.0000\nvt 0.6938 0.0469 0.0000\nvt 0.6589 0.0706 0.0000\nvt 0.6605 0.0801 0.0000\nvt 0.6573 0.0615 0.0000\nvt 0.2682 0.7777 0.0000\nvt 0.6941 0.0589 0.0000\nvt 0.6840 0.0732 0.0000\nvt 0.6728 0.0756 0.0000\nvt 0.6843 0.0875 0.0000\nvt 0.6737 0.0882 0.0000\nvt 0.6941 0.0729 0.0000\nvt 0.6621 0.0911 0.0000\nvt 0.6634 0.1038 0.0000\nvt 0.5455 0.3517 0.0000\nvt 0.5488 0.3646 0.0000\nvt 0.5398 0.3622 0.0000\nvt 0.5391 0.3497 0.0000\nvt 0.5633 0.3779 0.0000\nvt 0.5530 0.3789 0.0000\nvt 0.5575 0.3630 0.0000\nvt 0.5472 0.3910 0.0000\nvt 0.5425 0.3764 0.0000\nvt 0.5586 0.3934 0.0000\nvt 0.5301 0.3562 0.0000\nvt 0.5313 0.3710 0.0000\nvt 0.5735 0.3737 0.0000\nvt 0.5813 0.3885 0.0000\nvt 0.5701 0.3925 0.0000\nvt 0.6016 0.3952 0.0000\nvt 0.5901 0.4024 0.0000\nvt 0.5922 0.3816 0.0000\nvt 0.5872 0.4198 0.0000\nvt 0.5781 0.4066 0.0000\nvt 0.5997 0.4149 0.0000\nvt 0.5657 0.4078 0.0000\nvt 0.5804 0.4492 0.0000\nvt 0.3930 0.7528 0.0000\nvt 0.5700 0.4346 0.0000\nvt 0.5840 0.4345 0.0000\nvt 0.5947 0.4472 0.0000\nvt 0.5472 0.4171 0.0000\nvt 0.5609 0.4205 0.0000\nvt 0.5553 0.4326 0.0000\nvt 0.4180 0.7500 0.0000\nvt 0.5742 0.4215 0.0000\nvt 0.5533 0.4058 0.0000\nvt 0.5974 0.4315 0.0000\nvt 0.5341 0.4107 0.0000\nvt 0.0309 0.5897 0.0000\nvt 0.5288 0.3934 0.0000\nvt 0.5410 0.4010 0.0000\nvt 0.5118 0.3677 0.0000\nvt 0.0739 0.5903 0.0000\nvt 0.5238 0.3776 0.0000\nvt 0.5166 0.3836 0.0000\nvt 0.0581 0.5869 0.0000\nvt 0.5356 0.3856 0.0000\nvt 0.5195 0.3631 0.0000\nvt 0.0785 0.5997 0.0000\nvt 0.6937 0.0888 0.0000\nvt 0.6841 0.1036 0.0000\nvt 0.6743 0.1027 0.0000\nvt 0.6835 0.1217 0.0000\nvt 0.6745 0.1190 0.0000\nvt 0.6930 0.1066 0.0000\nvt 0.6552 0.1343 0.0000\nvt 0.6645 0.1184 0.0000\nvt 0.6651 0.1347 0.0000\nvt 0.6536 0.1198 0.0000\nvt 0.6918 0.1262 0.0000\nvt 0.6823 0.1416 0.0000\nvt 0.6741 0.1372 0.0000\nvt 0.6804 0.1635 0.0000\nvt 0.6729 0.1573 0.0000\nvt 0.6900 0.1477 0.0000\nvt 0.6561 0.1681 0.0000\nvt 0.6649 0.1528 0.0000\nvt 0.6635 0.1729 0.0000\nvt 0.6562 0.1503 0.0000\nvt 0.6286 0.1907 0.0000\nvt 0.6329 0.1789 0.0000\nvt 0.6409 0.1792 0.0000\nvt 0.6346 0.1910 0.0000\nvt 0.6291 0.1671 0.0000\nvt 0.6391 0.1650 0.0000\nvt 0.6236 0.1816 0.0000\nvt 0.6481 0.1653 0.0000\nvt 0.6467 0.1500 0.0000\nvt 0.6477 0.1825 0.0000\nvt 0.6182 0.1712 0.0000\nvt 0.6247 0.1555 0.0000\nvt 0.6361 0.1518 0.0000\nvt 0.6326 0.1394 0.0000\nvt 0.6126 0.1608 0.0000\nvt 0.6444 0.1359 0.0000\nvt 0.6796 0.2785 0.0000\nvt 0.6700 0.2954 0.0000\nvt 0.6604 0.2837 0.0000\nvt 0.6703 0.2670 0.0000\nvt 0.6708 0.3236 0.0000\nvt 0.6605 0.3122 0.0000\nvt 0.6799 0.3068 0.0000\nvt 0.6410 0.3166 0.0000\nvt 0.6506 0.3003 0.0000\nvt 0.6511 0.3287 0.0000\nvt 0.6514 0.2720 0.0000\nvt 0.6413 0.2881 0.0000\nvt 0.6813 0.3341 0.0000\nvt 0.6725 0.3505 0.0000\nvt 0.6617 0.3401 0.0000\nvt 0.6747 0.3751 0.0000\nvt 0.6635 0.3663 0.0000\nvt 0.6833 0.3597 0.0000\nvt 0.6431 0.3712 0.0000\nvt 0.6525 0.3561 0.0000\nvt 0.6543 0.3812 0.0000\nvt 0.6418 0.3446 0.0000\nvt 0.6025 0.3721 0.0000\nvt 0.6124 0.3603 0.0000\nvt 0.6226 0.3734 0.0000\nvt 0.6124 0.3854 0.0000\nvt 0.6123 0.3331 0.0000\nvt 0.6220 0.3469 0.0000\nvt 0.6028 0.3460 0.0000\nvt 0.6323 0.3596 0.0000\nvt 0.6315 0.3322 0.0000\nvt 0.6333 0.3850 0.0000\nvt 0.6033 0.3184 0.0000\nvt 0.6128 0.3050 0.0000\nvt 0.6218 0.3189 0.0000\nvt 0.6149 0.2774 0.0000\nvt 0.6226 0.2907 0.0000\nvt 0.6049 0.2906 0.0000\nvt 0.6314 0.3038 0.0000\nvt 0.6327 0.2758 0.0000\nvt 0.5472 0.2687 0.0000\nvt 0.5384 0.2801 0.0000\nvt 0.5358 0.2641 0.0000\nvt 0.5454 0.2525 0.0000\nvt 0.5351 0.3068 0.0000\nvt 0.5305 0.2921 0.0000\nvt 0.5423 0.2957 0.0000\nvt 0.5184 0.2900 0.0000\nvt 0.1516 0.6019 0.0000\nvt 0.5270 0.2766 0.0000\nvt 0.5230 0.3050 0.0000\nvt 0.5342 0.2479 0.0000\nvt 0.5243 0.2603 0.0000\nvt 0.1814 0.6016 0.0000\nvt 0.5406 0.3207 0.0000\nvt 0.5353 0.3306 0.0000\nvt 0.5291 0.3186 0.0000\nvt 0.5319 0.3422 0.0000\nvt 0.5412 0.3410 0.0000\nvt 0.5214 0.3468 0.0000\nvt 0.0948 0.6039 0.0000\nvt 0.5247 0.3316 0.0000\nvt 0.5174 0.3189 0.0000\nvt 0.1228 0.6027 0.0000\nvt 0.0877 0.5848 0.0000\nvt 0.1048 0.5891 0.0000\nvt 0.0912 0.5945 0.0000\nvt 0.1359 0.5883 0.0000\nvt 0.1212 0.5934 0.0000\nvt 0.1194 0.5837 0.0000\nvt 0.1075 0.5986 0.0000\nvt 0.1367 0.5977 0.0000\nvt 0.1514 0.5831 0.0000\nvt 0.1672 0.5878 0.0000\nvt 0.1517 0.5927 0.0000\nvt 0.1980 0.5873 0.0000\nvt 0.1823 0.5923 0.0000\nvt 0.1832 0.5827 0.0000\nvt 0.1668 0.5972 0.0000\nvt 0.1966 0.5967 0.0000\nvt 0.6228 0.3971 0.0000\nvt 0.6117 0.4072 0.0000\nvt 0.6444 0.3949 0.0000\nvt 0.6339 0.4071 0.0000\nvt 0.6341 0.4261 0.0000\nvt 0.6225 0.4176 0.0000\nvt 0.6455 0.4154 0.0000\nvt 0.6103 0.4258 0.0000\nvt 0.6657 0.3897 0.0000\nvt 0.6560 0.4032 0.0000\nvt 0.6858 0.3824 0.0000\nvt 0.6772 0.3965 0.0000\nvt 0.6796 0.4149 0.0000\nvt 0.6678 0.4098 0.0000\nvt 0.6885 0.4019 0.0000\nvt 0.6575 0.4220 0.0000\nvt 0.6851 0.4449 0.0000\nvt 0.2882 0.7573 0.0000\nvt 0.6718 0.4421 0.0000\nvt 0.6820 0.4305 0.0000\nvt 0.6944 0.4332 0.0000\nvt 0.6472 0.4490 0.0000\nvt 0.6589 0.4382 0.0000\nvt 0.6605 0.4538 0.0000\nvt 0.3129 0.7569 0.0000\nvt 0.6698 0.4269 0.0000\nvt 0.6463 0.4329 0.0000\nvt 0.6912 0.4185 0.0000\nvt 0.6343 0.4580 0.0000\nvt 0.3390 0.7561 0.0000\nvt 0.6210 0.4503 0.0000\nvt 0.6342 0.4424 0.0000\nvt 0.6087 0.4417 0.0000\nvt 0.6067 0.4577 0.0000\nvt 0.3666 0.7549 0.0000\nvt 0.6218 0.4349 0.0000\nvt 0.5835 0.3666 0.0000\nvt 0.5932 0.3573 0.0000\nvt 0.5664 0.3582 0.0000\nvt 0.5754 0.3508 0.0000\nvt 0.5769 0.3251 0.0000\nvt 0.5847 0.3415 0.0000\nvt 0.5681 0.3345 0.0000\nvt 0.5939 0.3306 0.0000\nvt 0.5522 0.3483 0.0000\nvt 0.5598 0.3424 0.0000\nvt 0.5465 0.3343 0.0000\nvt 0.5475 0.3113 0.0000\nvt 0.5534 0.3267 0.0000\nvt 0.5613 0.3181 0.0000\nvt 0.5568 0.2582 0.0000\nvt 0.5597 0.2748 0.0000\nvt 0.5506 0.2852 0.0000\nvt 0.5734 0.2815 0.0000\nvt 0.5642 0.2917 0.0000\nvt 0.5693 0.2648 0.0000\nvt 0.5554 0.3016 0.0000\nvt 0.5700 0.3085 0.0000\nvt 0.5831 0.2712 0.0000\nvt 0.5885 0.2872 0.0000\nvt 0.5791 0.2981 0.0000\nvt 0.5953 0.3030 0.0000\nvt 0.5983 0.2758 0.0000\nvt 0.5860 0.3145 0.0000\nvt 0.3219 0.5445 0.0000\nvt 0.3070 0.5498 0.0000\nvt 0.2928 0.5446 0.0000\nvt 0.3054 0.5601 0.0000\nvt 0.2918 0.5552 0.0000\nvt 0.3209 0.5547 0.0000\nvt 0.2625 0.5556 0.0000\nvt 0.2778 0.5501 0.0000\nvt 0.2764 0.5606 0.0000\nvt 0.2633 0.5448 0.0000\nvt 0.3183 0.5648 0.0000\nvt 0.3413 0.7880 0.0000\nvt 0.3025 0.5700 0.0000\nvt 0.2897 0.5655 0.0000\nvt 0.2993 0.5799 0.0000\nvt 0.5777 0.1424 0.0000\nvt 0.2870 0.5755 0.0000\nvt 0.3148 0.5744 0.0000\nvt 0.3380 0.7783 0.0000\nvt 0.2589 0.5764 0.0000\nvt 0.2742 0.5709 0.0000\nvt 0.2718 0.5811 0.0000\nvt 0.5548 0.1699 0.0000\nvt 0.2609 0.5661 0.0000\nvt 0.1993 0.5775 0.0000\nvt 0.2154 0.5721 0.0000\nvt 0.2297 0.5770 0.0000\nvt 0.2139 0.5822 0.0000\nvt 0.2164 0.5615 0.0000\nvt 0.2312 0.5666 0.0000\nvt 0.2002 0.5670 0.0000\nvt 0.2453 0.5716 0.0000\nvt 0.2470 0.5611 0.0000\nvt 0.2433 0.5817 0.0000\nvt 0.2006 0.5561 0.0000\nvt 0.2169 0.5505 0.0000\nvt 0.2323 0.5559 0.0000\nvt 0.2328 0.5448 0.0000\nvt 0.2008 0.5449 0.0000\nvt 0.2480 0.5503 0.0000\nvt 0.6940 0.3675 0.0000\nvt 0.7044 0.3742 0.0000\nvt 0.6967 0.3883 0.0000\nvt 0.7216 0.3664 0.0000\nvt 0.7143 0.3798 0.0000\nvt 0.7120 0.3597 0.0000\nvt 0.7168 0.3969 0.0000\nvt 0.7070 0.3930 0.0000\nvt 0.7237 0.3847 0.0000\nvt 0.6994 0.4060 0.0000\nvt 0.7292 0.3531 0.0000\nvt 0.7380 0.3606 0.0000\nvt 0.7307 0.3725 0.0000\nvt 0.7463 0.3681 0.0000\nvt 0.7458 0.3490 0.0000\nvt 0.7469 0.3846 0.0000\nvt 0.7391 0.3785 0.0000\nvt 0.7323 0.3893 0.0000\nvt 0.7480 0.4100 0.0000\nvt 0.2254 0.7575 0.0000\nvt 0.7414 0.4068 0.0000\nvt 0.7474 0.3985 0.0000\nvt 0.7281 0.4134 0.0000\nvt 0.7340 0.4035 0.0000\nvt 0.7359 0.4159 0.0000\nvt 0.2374 0.7575 0.0000\nvt 0.7402 0.3938 0.0000\nvt 0.7257 0.4003 0.0000\nvt 0.7218 0.4243 0.0000\nvt 0.2515 0.7575 0.0000\nvt 0.7123 0.4231 0.0000\nvt 0.7191 0.4115 0.0000\nvt 0.7022 0.4212 0.0000\nvt 0.7056 0.4351 0.0000\nvt 0.2678 0.7575 0.0000\nvt 0.7096 0.4091 0.0000\nvt 0.7030 0.0748 0.0000\nvt 0.7109 0.0787 0.0000\nvt 0.7021 0.0922 0.0000\nvt 0.7263 0.0720 0.0000\nvt 0.7183 0.0841 0.0000\nvt 0.7192 0.0661 0.0000\nvt 0.7170 0.1040 0.0000\nvt 0.7098 0.0973 0.0000\nvt 0.7253 0.0911 0.0000\nvt 0.7010 0.1114 0.0000\nvt 0.7338 0.0608 0.0000\nvt 0.7404 0.0682 0.0000\nvt 0.7331 0.0791 0.0000\nvt 0.7471 0.0768 0.0000\nvt 0.7474 0.0584 0.0000\nvt 0.7468 0.0970 0.0000\nvt 0.7399 0.0875 0.0000\nvt 0.7322 0.0993 0.0000\nvt 0.7460 0.1430 0.0000\nvt 0.7384 0.1316 0.0000\nvt 0.7464 0.1191 0.0000\nvt 0.7227 0.1348 0.0000\nvt 0.7312 0.1213 0.0000\nvt 0.7300 0.1451 0.0000\nvt 0.7392 0.1086 0.0000\nvt 0.7241 0.1120 0.0000\nvt 0.7139 0.1493 0.0000\nvt 0.7066 0.1402 0.0000\nvt 0.7156 0.1257 0.0000\nvt 0.6994 0.1325 0.0000\nvt 0.6974 0.1554 0.0000\nvt 0.7084 0.1178 0.0000\nvt 0.6893 0.2617 0.0000\nvt 0.6985 0.2732 0.0000\nvt 0.6891 0.2899 0.0000\nvt 0.7171 0.2687 0.0000\nvt 0.7079 0.2846 0.0000\nvt 0.7079 0.2569 0.0000\nvt 0.7087 0.3115 0.0000\nvt 0.6989 0.3010 0.0000\nvt 0.7175 0.2957 0.0000\nvt 0.6900 0.3175 0.0000\nvt 0.7264 0.2531 0.0000\nvt 0.7356 0.2654 0.0000\nvt 0.7265 0.2804 0.0000\nvt 0.7448 0.2778 0.0000\nvt 0.7448 0.2510 0.0000\nvt 0.7450 0.3034 0.0000\nvt 0.7358 0.2919 0.0000\nvt 0.7270 0.3065 0.0000\nvt 0.7371 0.3400 0.0000\nvt 0.7453 0.3273 0.0000\nvt 0.7198 0.3452 0.0000\nvt 0.7279 0.3309 0.0000\nvt 0.7363 0.3169 0.0000\nvt 0.7184 0.3215 0.0000\nvt 0.7020 0.3522 0.0000\nvt 0.7101 0.3368 0.0000\nvt 0.6917 0.3437 0.0000\nvt 0.7001 0.3276 0.0000\nvt 0.2156 0.8092 0.0000\nvt 0.2249 0.8050 0.0000\nvt 0.2357 0.8091 0.0000\nvt 0.1989 0.8093 0.0000\nvt 0.2068 0.8052 0.0000\nvt 0.2063 0.7972 0.0000\nvt 0.2151 0.8011 0.0000\nvt 0.1987 0.8013 0.0000\nvt 0.2351 0.8007 0.0000\nvt 0.2242 0.7968 0.0000\nvt 0.1846 0.8093 0.0000\nvt 0.1915 0.8054 0.0000\nvt 0.1780 0.8054 0.0000\nvt 0.1779 0.7974 0.0000\nvt 0.1845 0.8014 0.0000\nvt 0.1912 0.7974 0.0000\nvt 0.1777 0.7814 0.0000\nvt 0.7478 0.0014 0.0000\nvt 0.1840 0.7854 0.0000\nvt 0.1778 0.7894 0.0000\nvt 0.1974 0.7852 0.0000\nvt 0.1908 0.7893 0.0000\nvt 0.1900 0.7813 0.0000\nvt 0.7355 0.0041 0.0000\nvt 0.1843 0.7934 0.0000\nvt 0.1982 0.7932 0.0000\nvt 0.2045 0.7809 0.0000\nvt 0.7209 0.0111 0.0000\nvt 0.2135 0.7847 0.0000\nvt 0.2056 0.7890 0.0000\nvt 0.2322 0.7840 0.0000\nvt 0.2232 0.7885 0.0000\nvt 0.2213 0.7803 0.0000\nvt 0.7041 0.0222 0.0000\nvt 0.2145 0.7929 0.0000\nvt 0.2341 0.7923 0.0000\nvt 0.7456 0.1688 0.0000\nvt 0.7376 0.1565 0.0000\nvt 0.7452 0.1958 0.0000\nvt 0.7369 0.1829 0.0000\nvt 0.7197 0.1858 0.0000\nvt 0.7289 0.1708 0.0000\nvt 0.7278 0.1977 0.0000\nvt 0.7212 0.1595 0.0000\nvt 0.7450 0.2234 0.0000\nvt 0.7362 0.2103 0.0000\nvt 0.7357 0.2381 0.0000\nvt 0.7174 0.2409 0.0000\nvt 0.7269 0.2254 0.0000\nvt 0.7184 0.2131 0.0000\nvt 0.6804 0.2502 0.0000\nvt 0.6905 0.2337 0.0000\nvt 0.6990 0.2451 0.0000\nvt 0.6925 0.2064 0.0000\nvt 0.7005 0.2174 0.0000\nvt 0.6824 0.2227 0.0000\nvt 0.7088 0.2289 0.0000\nvt 0.7102 0.2014 0.0000\nvt 0.6850 0.1962 0.0000\nvt 0.6950 0.1802 0.0000\nvt 0.7024 0.1903 0.0000\nvt 0.7046 0.1644 0.0000\nvt 0.6877 0.1711 0.0000\nvt 0.7120 0.1746 0.0000\nvt 0.6777 0.1872 0.0000\nvt 0.6706 0.1793 0.0000\nvt 0.6747 0.2125 0.0000\nvt 0.6675 0.2032 0.0000\nvt 0.6505 0.2102 0.0000\nvt 0.6607 0.1950 0.0000\nvt 0.6571 0.2191 0.0000\nvt 0.6541 0.1880 0.0000\nvt 0.6721 0.2392 0.0000\nvt 0.6643 0.2288 0.0000\nvt 0.6617 0.2557 0.0000\nvt 0.6432 0.2605 0.0000\nvt 0.6537 0.2448 0.0000\nvt 0.6465 0.2344 0.0000\nvt 0.6085 0.2640 0.0000\nvt 0.6190 0.2515 0.0000\nvt 0.6253 0.2636 0.0000\nvt 0.6246 0.2279 0.0000\nvt 0.6296 0.2384 0.0000\nvt 0.6142 0.2394 0.0000\nvt 0.6359 0.2493 0.0000\nvt 0.6402 0.2247 0.0000\nvt 0.6210 0.2175 0.0000\nvt 0.6305 0.2073 0.0000\nvt 0.6348 0.2156 0.0000\nvt 0.6394 0.1957 0.0000\nvt 0.6278 0.1997 0.0000\nvt 0.6446 0.2023 0.0000\nvt 0.6193 0.2068 0.0000\nvt 0.6201 0.1949 0.0000\nvt 0.6109 0.2271 0.0000\nvt 0.6095 0.2142 0.0000\nvt 0.5997 0.2074 0.0000\nvt 0.6103 0.2007 0.0000\nvt 0.5991 0.2221 0.0000\nvt 0.6133 0.1863 0.0000\nvt 0.6037 0.2503 0.0000\nvt 0.6005 0.2364 0.0000\nvt 0.5933 0.2608 0.0000\nvt 0.5794 0.2552 0.0000\nvt 0.5899 0.2457 0.0000\nvt 0.5883 0.2304 0.0000\nvt 0.5556 0.2418 0.0000\nvt 0.5663 0.2321 0.0000\nvt 0.5669 0.2484 0.0000\nvt 0.5791 0.2072 0.0000\nvt 0.5774 0.2232 0.0000\nvt 0.5675 0.2160 0.0000\nvt 0.5775 0.2392 0.0000\nvt 0.5886 0.2150 0.0000\nvt 0.5825 0.1912 0.0000\nvt 0.5946 0.1834 0.0000\nvt 0.5907 0.1993 0.0000\nvt 0.6066 0.1767 0.0000\nvt 0.6002 0.1674 0.0000\nvt 0.6022 0.1923 0.0000\nvt 0.3255 0.7838 0.0000\nvt 0.3100 0.7798 0.0000\nvt 0.3285 0.7933 0.0000\nvt 0.3347 0.5594 0.0000\nvt 0.3128 0.7891 0.0000\nvt 0.2846 0.7903 0.0000\nvt 0.2974 0.7852 0.0000\nvt 0.2997 0.7943 0.0000\nvt 0.3638 0.5584 0.0000\nvt 0.2825 0.7814 0.0000\nvt 0.3361 0.5494 0.0000\nvt 0.3500 0.5540 0.0000\nvt 0.3512 0.5443 0.0000\nvt 0.3807 0.5440 0.0000\nvt 0.2868 0.8087 0.0000\nvt 0.3653 0.5489 0.0000\nvt 0.3791 0.5533 0.0000\nvt 0.2858 0.7994 0.0000\nvt 0.2471 0.8047 0.0000\nvt 0.2600 0.8089 0.0000\nvt 0.2462 0.7962 0.0000\nvt 0.2592 0.8001 0.0000\nvt 0.2728 0.8043 0.0000\nvt 0.2718 0.7953 0.0000\nvt 0.2448 0.7876 0.0000\nvt 0.2580 0.7914 0.0000\nvt 0.2563 0.7828 0.0000\nvt 0.2702 0.7865 0.0000\nvt 0.3805 0.7471 0.0000\nvt 0.3944 0.7393 0.0000\nvt 0.4066 0.7449 0.0000\nvt 0.3958 0.7256 0.0000\nvt 0.4086 0.7317 0.0000\nvt 0.3815 0.7333 0.0000\nvt 0.4353 0.7300 0.0000\nvt 0.0078 0.5725 0.0000\nvt 0.4207 0.7373 0.0000\nvt 0.4230 0.7243 0.0000\nvt 0.4321 0.7424 0.0000\nvt 0.0142 0.5849 0.0000\nvt 0.3824 0.7191 0.0000\nvt 0.3966 0.7114 0.0000\nvt 0.4100 0.7181 0.0000\nvt 0.4107 0.7040 0.0000\nvt 0.3828 0.7043 0.0000\nvt 0.4383 0.7036 0.0000\nvt 0.0012 0.5461 0.0000\nvt 0.4241 0.7107 0.0000\nvt 0.4373 0.7171 0.0000\nvt 0.0035 0.5596 0.0000\nvt 0.0637 0.5454 0.0000\nvt 0.0484 0.5518 0.0000\nvt 0.0321 0.5458 0.0000\nvt 0.0508 0.5639 0.0000\nvt 0.0340 0.5584 0.0000\nvt 0.0652 0.5575 0.0000\nvt 0.0175 0.5525 0.0000\nvt 0.0203 0.5654 0.0000\nvt 0.0678 0.5691 0.0000\nvt 0.0543 0.5756 0.0000\nvt 0.0374 0.5706 0.0000\nvt 0.0421 0.5825 0.0000\nvt 0.0708 0.5803 0.0000\nvt 0.0253 0.5776 0.0000\nvt 0.0851 0.5742 0.0000\nvt 0.1023 0.5790 0.0000\nvt 0.0825 0.5629 0.0000\nvt 0.1001 0.5682 0.0000\nvt 0.1337 0.5676 0.0000\nvt 0.1176 0.5733 0.0000\nvt 0.1161 0.5623 0.0000\nvt 0.1348 0.5783 0.0000\nvt 0.0808 0.5512 0.0000\nvt 0.0983 0.5569 0.0000\nvt 0.0973 0.5452 0.0000\nvt 0.1321 0.5451 0.0000\nvt 0.1149 0.5509 0.0000\nvt 0.1327 0.5565 0.0000\nvt 0.1841 0.5506 0.0000\nvt 0.1670 0.5450 0.0000\nvt 0.1840 0.5617 0.0000\nvt 0.1671 0.5563 0.0000\nvt 0.1497 0.5507 0.0000\nvt 0.1502 0.5620 0.0000\nvt 0.1838 0.5725 0.0000\nvt 0.1674 0.5673 0.0000\nvt 0.1674 0.5779 0.0000\nvt 0.1509 0.5728 0.0000\nvt 0.2773 0.7502 0.0000\nvt 0.2884 0.7428 0.0000\nvt 0.3004 0.7499 0.0000\nvt 0.2879 0.7280 0.0000\nvt 0.3001 0.7354 0.0000\nvt 0.2773 0.7356 0.0000\nvt 0.3260 0.7350 0.0000\nvt 0.3128 0.7425 0.0000\nvt 0.3126 0.7279 0.0000\nvt 0.3258 0.7495 0.0000\nvt 0.2768 0.7204 0.0000\nvt 0.2877 0.7126 0.0000\nvt 0.2997 0.7204 0.0000\nvt 0.2997 0.7048 0.0000\nvt 0.2767 0.7048 0.0000\nvt 0.3260 0.7047 0.0000\nvt 0.3125 0.7126 0.0000\nvt 0.3259 0.7201 0.0000\nvt 0.3684 0.7120 0.0000\nvt 0.3541 0.7046 0.0000\nvt 0.3679 0.7267 0.0000\nvt 0.3540 0.7197 0.0000\nvt 0.3399 0.7123 0.0000\nvt 0.3397 0.7274 0.0000\nvt 0.3672 0.7409 0.0000\nvt 0.3536 0.7344 0.0000\nvt 0.3531 0.7485 0.0000\nvt 0.3395 0.7419 0.0000\nvt 0.5832 0.1473 0.0000\nvt 0.5691 0.1583 0.0000\nvt 0.5885 0.1528 0.0000\nvt 0.5747 0.1630 0.0000\nvt 0.5530 0.1890 0.0000\nvt 0.2527 0.5949 0.0000\nvt 0.5608 0.1739 0.0000\nvt 0.5670 0.1784 0.0000\nvt 0.5466 0.1854 0.0000\nvt 0.2563 0.5861 0.0000\nvt 0.5941 0.1594 0.0000\nvt 0.5808 0.1685 0.0000\nvt 0.5875 0.1753 0.0000\nvt 0.5704 0.2001 0.0000\nvt 0.5747 0.1843 0.0000\nvt 0.5616 0.1940 0.0000\nvt 0.5452 0.2365 0.0000\nvt 0.5562 0.2258 0.0000\nvt 0.5345 0.2317 0.0000\nvt 0.2099 0.6009 0.0000\nvt 0.5465 0.2206 0.0000\nvt 0.5583 0.2099 0.0000\nvt 0.5489 0.2044 0.0000\nvt 0.2372 0.5999 0.0000\nvt 0.2119 0.5917 0.0000\nvt 0.2249 0.5959 0.0000\nvt 0.2275 0.5867 0.0000\nvt 0.2404 0.5909 0.0000\nvt 0.2252 0.7429 0.0000\nvt 0.2313 0.7502 0.0000\nvt 0.2250 0.7280 0.0000\nvt 0.2310 0.7355 0.0000\nvt 0.2438 0.7356 0.0000\nvt 0.2373 0.7429 0.0000\nvt 0.2370 0.7280 0.0000\nvt 0.2440 0.7503 0.0000\nvt 0.2250 0.7126 0.0000\nvt 0.2308 0.7203 0.0000\nvt 0.2307 0.7048 0.0000\nvt 0.2433 0.7048 0.0000\nvt 0.2368 0.7126 0.0000\nvt 0.2434 0.7204 0.0000\nvt 0.2670 0.7127 0.0000\nvt 0.2582 0.7048 0.0000\nvt 0.2673 0.7281 0.0000\nvt 0.2583 0.7204 0.0000\nvt 0.2504 0.7126 0.0000\nvt 0.2507 0.7281 0.0000\nvt 0.2678 0.7429 0.0000\nvt 0.2588 0.7356 0.0000\nvt 0.2594 0.7502 0.0000\nvt 0.2512 0.7430 0.0000\nvt 0.7478 0.0139 0.0000\nvt 0.7415 0.0088 0.0000\nvt 0.7477 0.0269 0.0000\nvt 0.7414 0.0213 0.0000\nvt 0.7278 0.0257 0.0000\nvt 0.7349 0.0168 0.0000\nvt 0.7347 0.0296 0.0000\nvt 0.7283 0.0130 0.0000\nvt 0.7476 0.0417 0.0000\nvt 0.7412 0.0350 0.0000\nvt 0.7409 0.0507 0.0000\nvt 0.7271 0.0546 0.0000\nvt 0.7344 0.0443 0.0000\nvt 0.7276 0.0392 0.0000\nvt 0.7034 0.0594 0.0000\nvt 0.7117 0.0619 0.0000\nvt 0.7035 0.0459 0.0000\nvt 0.7122 0.0470 0.0000\nvt 0.7199 0.0499 0.0000\nvt 0.7203 0.0357 0.0000\nvt 0.7035 0.0341 0.0000\nvt 0.7123 0.0340 0.0000\nvt 0.7124 0.0224 0.0000\nvt 0.7205 0.0233 0.0000\n# 5974 texture coords\n\ng Heart\nusemtl Heart\ns 1\nf 1/1/1 2/2991/2 3/1583/3 4/2994/4 \nf 5/795/5 6/2992/6 3/1583/3 2/2991/2 \nf 7/443/7 8/2993/8 3/1583/3 6/2992/6 \nf 9/798/9 4/2994/4 3/1583/3 8/2993/8 \nf 10/2/10 11/2995/11 12/1584/12 13/2997/13 \nf 14/796/14 15/2996/15 12/1584/12 11/2995/11 \nf 7/443/7 6/2992/6 12/1584/12 15/2996/15 \nf 5/795/5 13/2997/13 12/1584/12 6/2992/6 \nf 16/3/16 17/2998/17 18/1585/18 19/3000/19 \nf 20/797/20 21/2999/21 18/1585/18 17/2998/17 \nf 7/443/7 15/2996/15 18/1585/18 21/2999/21 \nf 14/796/14 19/3000/19 18/1585/18 15/2996/15 \nf 22/4/22 23/3001/23 24/1586/24 25/3002/25 \nf 9/798/9 8/2993/8 24/1586/24 23/3001/23 \nf 7/443/7 21/2999/21 24/1586/24 8/2993/8 \nf 20/797/20 25/3002/25 24/1586/24 21/2999/21 \nf 10/2/10 26/3003/26 27/1587/27 11/2995/11 \nf 28/799/28 29/3004/29 27/1587/27 26/3003/26 \nf 30/444/30 31/3005/31 27/1587/27 29/3004/29 \nf 14/796/14 11/2995/11 27/1587/27 31/3005/31 \nf 32/5/32 33/3006/33 34/1588/34 35/3009/35 \nf 36/800/36 37/3008/37 34/1588/34 33/3006/33 \nf 30/444/30 29/3004/29 34/1588/34 37/3008/37 \nf 28/799/28 35/3009/35 34/1588/34 29/3004/29 \nf 38/6/38 39/3010/39 40/1589/40 41/3012/41 \nf 42/802/42 43/3011/43 40/1589/40 39/3010/39 \nf 30/444/30 37/3008/37 40/1589/40 43/3011/43 \nf 36/800/36 41/3012/41 40/1589/40 37/3008/37 \nf 16/3/16 19/3000/19 44/1590/44 45/3014/45 \nf 14/796/14 31/3005/31 44/1590/44 19/3000/19 \nf 30/444/30 43/3011/43 44/1590/44 31/3005/31 \nf 42/802/42 45/3014/45 44/1590/44 43/3011/43 \nf 46/7/46 47/3015/47 48/1591/48 49/3018/49 \nf 50/803/50 51/3016/51 48/1591/48 47/3015/47 \nf 52/445/52 53/3017/53 48/1591/48 51/3016/51 \nf 54/805/54 49/3018/49 48/1591/48 53/3017/53 \nf 55/8/55 56/3020/56 57/1592/57 58/3022/58 \nf 59/804/59 60/3021/60 57/1592/57 56/3020/56 \nf 52/445/52 51/3016/51 57/1592/57 60/3021/60 \nf 50/803/50 58/3022/58 57/1592/57 51/3016/51 \nf 16/3/16 45/3014/45 61/1593/61 62/3024/62 \nf 42/802/42 63/3023/63 61/1593/61 45/3014/45 \nf 52/445/52 60/3021/60 61/1593/61 63/3023/63 \nf 59/804/59 62/3024/62 61/1593/61 60/3021/60 \nf 38/6/38 64/3025/64 65/1594/65 39/3010/39 \nf 54/805/54 53/3017/53 65/1594/65 64/3025/64 \nf 52/445/52 63/3023/63 65/1594/65 53/3017/53 \nf 42/802/42 39/3010/39 65/1594/65 63/3023/63 \nf 55/8/55 66/3027/66 67/1595/67 56/3020/56 \nf 68/807/68 69/3028/69 67/1595/67 66/3027/66 \nf 70/446/70 71/3029/71 67/1595/67 69/3028/69 \nf 59/804/59 56/3020/56 67/1595/67 71/3029/71 \nf 72/9/72 73/3030/73 74/1596/74 75/3032/75 \nf 76/808/76 77/3031/77 74/1596/74 73/3030/73 \nf 70/446/70 69/3028/69 74/1596/74 77/3031/77 \nf 68/807/68 75/3032/75 74/1596/74 69/3028/69 \nf 22/4/22 25/3002/25 78/1597/78 79/3034/79 \nf 20/797/20 80/3033/80 78/1597/78 25/3002/25 \nf 70/446/70 77/3031/77 78/1597/78 80/3033/80 \nf 76/808/76 79/3034/79 78/1597/78 77/3031/77 \nf 16/3/16 62/3024/62 81/1598/81 17/2998/17 \nf 59/804/59 71/3029/71 81/1598/81 62/3024/62 \nf 70/446/70 80/3033/80 81/1598/81 71/3029/71 \nf 20/797/20 17/2998/17 81/1598/81 80/3033/80 \nf 82/10/82 83/3035/83 84/1599/84 85/3038/85 \nf 86/809/86 87/3036/87 84/1599/84 83/3035/83 \nf 88/447/88 89/3037/89 84/1599/84 87/3036/87 \nf 90/812/90 85/3038/85 84/1599/84 89/3037/89 \nf 91/11/91 92/3039/92 93/1600/93 94/3041/94 \nf 95/810/95 96/3040/96 93/1600/93 92/3039/92 \nf 88/447/88 87/3036/87 93/1600/93 96/3040/96 \nf 86/809/86 94/3041/94 93/1600/93 87/3036/87 \nf 97/18/97 98/3042/98 99/1601/99 100/3044/100 \nf 101/811/101 102/3043/102 99/1601/99 98/3042/98 \nf 88/447/88 96/3040/96 99/1601/99 102/3043/102 \nf 95/810/95 100/3044/100 99/1601/99 96/3040/96 \nf 103/19/103 104/3045/104 105/1602/105 106/3046/106 \nf 90/812/90 89/3037/89 105/1602/105 104/3045/104 \nf 88/447/88 102/3043/102 105/1602/105 89/3037/89 \nf 101/811/101 106/3046/106 105/1602/105 102/3043/102 \nf 91/11/91 107/3047/107 108/1603/108 92/3039/92 \nf 109/813/109 110/3048/110 108/1603/108 107/3047/107 \nf 111/448/111 112/3049/112 108/1603/108 110/3048/110 \nf 95/810/95 92/3039/92 108/1603/108 112/3049/112 \nf 113/20/113 114/3050/114 115/1604/115 116/3052/116 \nf 117/814/117 118/3051/118 115/1604/115 114/3050/114 \nf 111/448/111 110/3048/110 115/1604/115 118/3051/118 \nf 109/813/109 116/3052/116 115/1604/115 110/3048/110 \nf 119/23/119 120/3053/120 121/1605/121 122/3055/122 \nf 123/815/123 124/3054/124 121/1605/121 120/3053/120 \nf 111/448/111 118/3051/118 121/1605/121 124/3054/124 \nf 117/814/117 122/3055/122 121/1605/121 118/3051/118 \nf 97/18/97 100/3044/100 125/1606/125 126/3056/126 \nf 95/810/95 112/3049/112 125/1606/125 100/3044/100 \nf 111/448/111 124/3054/124 125/1606/125 112/3049/112 \nf 123/815/123 126/3056/126 125/1606/125 124/3054/124 \nf 127/24/127 128/3057/128 129/1607/129 130/3061/130 \nf 131/816/131 132/3059/132 129/1607/129 128/3057/128 \nf 133/449/133 134/3060/134 129/1607/129 132/3059/132 \nf 135/819/135 130/3061/130 129/1607/129 134/3060/134 \nf 136/25/136 137/3062/137 138/1608/138 139/3064/139 \nf 140/818/140 141/3063/141 138/1608/138 137/3062/137 \nf 133/449/133 132/3059/132 138/1608/138 141/3063/141 \nf 131/816/131 139/3064/139 138/1608/138 132/3059/132 \nf 97/18/97 126/3056/126 142/1609/142 143/3067/143 \nf 123/815/123 144/3066/144 142/1609/142 126/3056/126 \nf 133/449/133 141/3063/141 142/1609/142 144/3066/144 \nf 140/818/140 143/3067/143 142/1609/142 141/3063/141 \nf 119/23/119 145/3068/145 146/1610/146 120/3053/120 \nf 135/819/135 134/3060/134 146/1610/146 145/3068/145 \nf 133/449/133 144/3066/144 146/1610/146 134/3060/134 \nf 123/815/123 120/3053/120 146/1610/146 144/3066/144 \nf 136/25/136 147/3069/147 148/1611/148 137/3062/137 \nf 149/820/149 150/3071/150 148/1611/148 147/3069/147 \nf 151/450/151 152/3072/152 148/1611/148 150/3071/150 \nf 140/818/140 137/3062/137 148/1611/148 152/3072/152 \nf 153/26/153 154/3073/154 155/1612/155 156/3076/156 \nf 157/822/157 158/3075/158 155/1612/155 154/3073/154 \nf 151/450/151 150/3071/150 155/1612/155 158/3075/158 \nf 149/820/149 156/3076/156 155/1612/155 150/3071/150 \nf 103/19/103 106/3046/106 159/1613/159 160/3079/160 \nf 101/811/101 161/3078/161 159/1613/159 106/3046/106 \nf 151/450/151 158/3075/158 159/1613/159 161/3078/161 \nf 157/822/157 160/3079/160 159/1613/159 158/3075/158 \nf 97/18/97 143/3067/143 162/1614/162 98/3042/98 \nf 140/818/140 152/3072/152 162/1614/162 143/3067/143 \nf 151/450/151 161/3078/161 162/1614/162 152/3072/152 \nf 101/811/101 98/3042/98 162/1614/162 161/3078/161 \nf 72/9/72 163/3081/163 164/1615/164 73/3030/73 \nf 165/824/165 166/3082/166 164/1615/164 163/3081/163 \nf 167/451/167 168/3083/168 164/1615/164 166/3082/166 \nf 76/808/76 73/3030/73 164/1615/164 168/3083/168 \nf 169/27/169 170/3084/170 171/1616/171 172/3086/172 \nf 173/825/173 174/3085/174 171/1616/171 170/3084/170 \nf 167/451/167 166/3082/166 171/1616/171 174/3085/174 \nf 165/824/165 172/3086/172 171/1616/171 166/3082/166 \nf 175/30/175 176/3087/176 177/1617/177 178/3089/178 \nf 179/826/179 180/3088/180 177/1617/177 176/3087/176 \nf 167/451/167 174/3085/174 177/1617/177 180/3088/180 \nf 173/825/173 178/3089/178 177/1617/177 174/3085/174 \nf 22/4/22 79/3034/79 181/1618/181 182/3090/182 \nf 76/808/76 168/3083/168 181/1618/181 79/3034/79 \nf 167/451/167 180/3088/180 181/1618/181 168/3083/168 \nf 179/826/179 182/3090/182 181/1618/181 180/3088/180 \nf 169/27/169 183/3091/183 184/1619/184 170/3084/170 \nf 185/827/185 186/3092/186 184/1619/184 183/3091/183 \nf 187/452/187 188/3093/188 184/1619/184 186/3092/186 \nf 173/825/173 170/3084/170 184/1619/184 188/3093/188 \nf 189/31/189 190/3094/190 191/1620/191 192/3096/192 \nf 193/828/193 194/3095/194 191/1620/191 190/3094/190 \nf 187/452/187 186/3092/186 191/1620/191 194/3095/194 \nf 185/827/185 192/3096/192 191/1620/191 186/3092/186 \nf 195/32/195 196/3097/196 197/1621/197 198/3099/198 \nf 199/829/199 200/3098/200 197/1621/197 196/3097/196 \nf 187/452/187 194/3095/194 197/1621/197 200/3098/200 \nf 193/828/193 198/3099/198 197/1621/197 194/3095/194 \nf 175/30/175 178/3089/178 201/1622/201 202/3100/202 \nf 173/825/173 188/3093/188 201/1622/201 178/3089/178 \nf 187/452/187 200/3098/200 201/1622/201 188/3093/188 \nf 199/829/199 202/3100/202 201/1622/201 200/3098/200 \nf 203/33/203 204/3101/204 205/1623/205 206/3104/206 \nf 207/830/207 208/3102/208 205/1623/205 204/3101/204 \nf 209/453/209 210/3103/210 205/1623/205 208/3102/208 \nf 211/832/211 206/3104/206 205/1623/205 210/3103/210 \nf 212/34/212 213/3105/213 214/1624/214 215/3107/215 \nf 216/831/216 217/3106/217 214/1624/214 213/3105/213 \nf 209/453/209 208/3102/208 214/1624/214 217/3106/217 \nf 207/830/207 215/3107/215 214/1624/214 208/3102/208 \nf 175/30/175 202/3100/202 218/1625/218 219/3109/219 \nf 199/829/199 220/3108/220 218/1625/218 202/3100/202 \nf 209/453/209 217/3106/217 218/1625/218 220/3108/220 \nf 216/831/216 219/3109/219 218/1625/218 217/3106/217 \nf 195/32/195 221/3110/221 222/1626/222 196/3097/196 \nf 211/832/211 210/3103/210 222/1626/222 221/3110/221 \nf 209/453/209 220/3108/220 222/1626/222 210/3103/210 \nf 199/829/199 196/3097/196 222/1626/222 220/3108/220 \nf 212/34/212 223/3111/223 224/1627/224 213/3105/213 \nf 225/833/225 226/3112/226 224/1627/224 223/3111/223 \nf 227/454/227 228/3113/228 224/1627/224 226/3112/226 \nf 216/831/216 213/3105/213 224/1627/224 228/3113/228 \nf 1/1/1 4/2994/4 229/1628/229 230/3115/230 \nf 9/798/9 231/3114/231 229/1628/229 4/2994/4 \nf 227/454/227 226/3112/226 229/1628/229 231/3114/231 \nf 225/833/225 230/3115/230 229/1628/229 226/3112/226 \nf 22/4/22 182/3090/182 232/1629/232 23/3001/23 \nf 179/826/179 233/3116/233 232/1629/232 182/3090/182 \nf 227/454/227 231/3114/231 232/1629/232 233/3116/233 \nf 9/798/9 23/3001/23 232/1629/232 231/3114/231 \nf 175/30/175 219/3109/219 234/1630/234 176/3087/176 \nf 216/831/216 228/3113/228 234/1630/234 219/3109/219 \nf 227/454/227 233/3116/233 234/1630/234 228/3113/228 \nf 179/826/179 176/3087/176 234/1630/234 233/3116/233 \nf 235/36/235 236/3117/236 237/1631/237 238/3120/238 \nf 239/834/239 240/3118/240 237/1631/237 236/3117/236 \nf 241/455/241 242/3119/242 237/1631/237 240/3118/240 \nf 243/837/243 238/3120/238 237/1631/237 242/3119/242 \nf 244/40/244 245/3121/245 246/1632/246 247/3123/247 \nf 248/835/248 249/3122/249 246/1632/246 245/3121/245 \nf 241/455/241 240/3118/240 246/1632/246 249/3122/249 \nf 239/834/239 247/3123/247 246/1632/246 240/3118/240 \nf 250/45/250 251/3124/251 252/1633/252 253/3126/253 \nf 254/836/254 255/3125/255 252/1633/252 251/3124/251 \nf 241/455/241 249/3122/249 252/1633/252 255/3125/255 \nf 248/835/248 253/3126/253 252/1633/252 249/3122/249 \nf 256/48/256 257/3127/257 258/1634/258 259/3128/259 \nf 243/837/243 242/3119/242 258/1634/258 257/3127/257 \nf 241/455/241 255/3125/255 258/1634/258 242/3119/242 \nf 254/836/254 259/3128/259 258/1634/258 255/3125/255 \nf 244/40/244 260/3129/260 261/1635/261 245/3121/245 \nf 262/838/262 263/3130/263 261/1635/261 260/3129/260 \nf 264/456/264 265/3131/265 261/1635/261 263/3130/263 \nf 248/835/248 245/3121/245 261/1635/261 265/3131/265 \nf 266/49/266 267/3132/267 268/1636/268 269/3134/269 \nf 270/839/270 271/3133/271 268/1636/268 267/3132/267 \nf 264/456/264 263/3130/263 268/1636/268 271/3133/271 \nf 262/838/262 269/3134/269 268/1636/268 263/3130/263 \nf 272/50/272 273/3135/273 274/1637/274 275/3137/275 \nf 276/840/276 277/3136/277 274/1637/274 273/3135/273 \nf 264/456/264 271/3133/271 274/1637/274 277/3136/277 \nf 270/839/270 275/3137/275 274/1637/274 271/3133/271 \nf 250/45/250 253/3126/253 278/1638/278 279/3138/279 \nf 248/835/248 265/3131/265 278/1638/278 253/3126/253 \nf 264/456/264 277/3136/277 278/1638/278 265/3131/265 \nf 276/840/276 279/3138/279 278/1638/278 277/3136/277 \nf 113/20/113 280/3139/280 281/1639/281 282/3142/282 \nf 283/841/283 284/3140/284 281/1639/281 280/3139/280 \nf 285/457/285 286/3141/286 281/1639/281 284/3140/284 \nf 287/843/287 282/3142/282 281/1639/281 286/3141/286 \nf 288/52/288 289/3143/289 290/1640/290 291/3145/291 \nf 292/842/292 293/3144/293 290/1640/290 289/3143/289 \nf 285/457/285 284/3140/284 290/1640/290 293/3144/293 \nf 283/841/283 291/3145/291 290/1640/290 284/3140/284 \nf 250/45/250 279/3138/279 294/1641/294 295/3147/295 \nf 276/840/276 296/3146/296 294/1641/294 279/3138/279 \nf 285/457/285 293/3144/293 294/1641/294 296/3146/296 \nf 292/842/292 295/3147/295 294/1641/294 293/3144/293 \nf 272/50/272 297/3148/297 298/1642/298 273/3135/273 \nf 287/843/287 286/3141/286 298/1642/298 297/3148/297 \nf 285/457/285 296/3146/296 298/1642/298 286/3141/286 \nf 276/840/276 273/3135/273 298/1642/298 296/3146/296 \nf 288/52/288 299/3149/299 300/1643/300 289/3143/289 \nf 301/844/301 302/3150/302 300/1643/300 299/3149/299 \nf 303/458/303 304/3151/304 300/1643/300 302/3150/302 \nf 292/842/292 289/3143/289 300/1643/300 304/3151/304 \nf 305/53/305 306/3152/306 307/1644/307 308/3154/308 \nf 309/845/309 310/3153/310 307/1644/307 306/3152/306 \nf 303/458/303 302/3150/302 307/1644/307 310/3153/310 \nf 301/844/301 308/3154/308 307/1644/307 302/3150/302 \nf 256/48/256 259/3128/259 311/1645/311 312/3156/312 \nf 254/836/254 313/3155/313 311/1645/311 259/3128/259 \nf 303/458/303 310/3153/310 311/1645/311 313/3155/313 \nf 309/845/309 312/3156/312 311/1645/311 310/3153/310 \nf 250/45/250 295/3147/295 314/1646/314 251/3124/251 \nf 292/842/292 304/3151/304 314/1646/314 295/3147/295 \nf 303/458/303 313/3155/313 314/1646/314 304/3151/304 \nf 254/836/254 251/3124/251 314/1646/314 313/3155/313 \nf 315/54/315 316/3157/316 317/1647/317 318/3160/318 \nf 319/846/319 320/3158/320 317/1647/317 316/3157/316 \nf 321/459/321 322/3159/322 317/1647/317 320/3158/320 \nf 323/850/323 318/3160/318 317/1647/317 322/3159/322 \nf 324/55/324 325/3161/325 326/1648/326 327/3163/327 \nf 328/847/328 329/3162/329 326/1648/326 325/3161/325 \nf 321/459/321 320/3158/320 326/1648/326 329/3162/329 \nf 319/846/319 327/3163/327 326/1648/326 320/3158/320 \nf 330/56/330 331/3164/331 332/1649/332 333/3167/333 \nf 334/848/334 335/3166/335 332/1649/332 331/3164/331 \nf 321/459/321 329/3162/329 332/1649/332 335/3166/335 \nf 328/847/328 333/3167/333 332/1649/332 329/3162/329 \nf 336/57/336 337/3168/337 338/1650/338 339/3169/339 \nf 323/850/323 322/3159/322 338/1650/338 337/3168/337 \nf 321/459/321 335/3166/335 338/1650/338 322/3159/322 \nf 334/848/334 339/3169/339 338/1650/338 335/3166/335 \nf 324/55/324 340/3171/340 341/1651/341 325/3161/325 \nf 342/851/342 343/3172/343 341/1651/341 340/3171/340 \nf 344/460/344 345/3173/345 341/1651/341 343/3172/343 \nf 328/847/328 325/3161/325 341/1651/341 345/3173/345 \nf 82/10/82 85/3038/85 346/1652/346 347/3175/347 \nf 90/812/90 348/3174/348 346/1652/346 85/3038/85 \nf 344/460/344 343/3172/343 346/1652/346 348/3174/348 \nf 342/851/342 347/3175/347 346/1652/346 343/3172/343 \nf 103/19/103 349/3176/349 350/1653/350 104/3045/104 \nf 351/852/351 352/3178/352 350/1653/350 349/3176/349 \nf 344/460/344 348/3174/348 350/1653/350 352/3178/352 \nf 90/812/90 104/3045/104 350/1653/350 348/3174/348 \nf 330/56/330 333/3167/333 353/1654/353 354/3179/354 \nf 328/847/328 345/3173/345 353/1654/353 333/3167/333 \nf 344/460/344 352/3178/352 353/1654/353 345/3173/345 \nf 351/852/351 354/3179/354 353/1654/353 352/3178/352 \nf 153/12/153 355/3181/355 356/1655/356 154/3074/154 \nf 357/854/357 358/3182/358 356/1655/356 355/3181/355 \nf 359/461/359 360/3183/360 356/1655/356 358/3182/358 \nf 157/823/157 154/3074/154 356/1655/356 360/3183/360 \nf 361/13/361 362/3184/362 363/1656/363 364/3186/364 \nf 365/855/365 366/3185/366 363/1656/363 362/3184/362 \nf 359/461/359 358/3182/358 363/1656/363 366/3185/366 \nf 357/854/357 364/3186/364 363/1656/363 358/3182/358 \nf 330/14/330 354/3180/354 367/1657/367 368/3188/368 \nf 351/853/351 369/3187/369 367/1657/367 354/3180/354 \nf 359/461/359 366/3185/366 367/1657/367 369/3187/369 \nf 365/855/365 368/3188/368 367/1657/367 366/3185/366 \nf 103/15/103 160/3080/160 370/1658/370 349/3177/349 \nf 157/823/157 360/3183/360 370/1658/370 160/3080/160 \nf 359/461/359 369/3187/369 370/1658/370 360/3183/360 \nf 351/853/351 349/3177/349 370/1658/370 369/3187/369 \nf 361/13/361 371/3189/371 372/1659/372 362/3184/362 \nf 373/856/373 374/3190/374 372/1659/372 371/3189/371 \nf 375/462/375 376/3191/376 372/1659/372 374/3190/374 \nf 365/855/365 362/3184/362 372/1659/372 376/3191/376 \nf 377/16/377 378/3192/378 379/1660/379 380/3194/380 \nf 381/857/381 382/3193/382 379/1660/379 378/3192/378 \nf 375/462/375 374/3190/374 379/1660/379 382/3193/382 \nf 373/856/373 380/3194/380 379/1660/379 374/3190/374 \nf 336/38/336 339/3170/339 383/1661/383 384/3196/384 \nf 334/849/334 385/3195/385 383/1661/383 339/3170/339 \nf 375/462/375 382/3193/382 383/1661/383 385/3195/385 \nf 381/857/381 384/3196/384 383/1661/383 382/3193/382 \nf 330/14/330 368/3188/368 386/1662/386 331/3165/331 \nf 365/855/365 376/3191/376 386/1662/386 368/3188/368 \nf 375/462/375 385/3195/385 386/1662/386 376/3191/376 \nf 334/849/334 331/3165/331 386/1662/386 385/3195/385 \nf 113/20/113 282/3142/282 387/1663/387 114/3050/114 \nf 287/843/287 388/3197/388 387/1663/387 282/3142/282 \nf 389/463/389 390/3198/390 387/1663/387 388/3197/388 \nf 117/814/117 114/3050/114 387/1663/387 390/3198/390 \nf 272/50/272 391/3199/391 392/1664/392 297/3148/297 \nf 393/858/393 394/3200/394 392/1664/392 391/3199/391 \nf 389/463/389 388/3197/388 392/1664/392 394/3200/394 \nf 287/843/287 297/3148/297 392/1664/392 388/3197/388 \nf 395/58/395 396/3201/396 397/1665/397 398/3203/398 \nf 399/859/399 400/3202/400 397/1665/397 396/3201/396 \nf 389/463/389 394/3200/394 397/1665/397 400/3202/400 \nf 393/858/393 398/3203/398 397/1665/397 394/3200/394 \nf 119/23/119 122/3055/122 401/1666/401 402/3204/402 \nf 117/814/117 390/3198/390 401/1666/401 122/3055/122 \nf 389/463/389 400/3202/400 401/1666/401 390/3198/390 \nf 399/859/399 402/3204/402 401/1666/401 400/3202/400 \nf 272/50/272 275/3137/275 403/1667/403 391/3199/391 \nf 270/839/270 404/3205/404 403/1667/403 275/3137/275 \nf 405/464/405 406/3206/406 403/1667/403 404/3205/404 \nf 393/858/393 391/3199/391 403/1667/403 406/3206/406 \nf 266/49/266 407/3207/407 408/1668/408 267/3132/267 \nf 409/860/409 410/3208/410 408/1668/408 407/3207/407 \nf 405/464/405 404/3205/404 408/1668/408 410/3208/410 \nf 270/839/270 267/3132/267 408/1668/408 404/3205/404 \nf 411/59/411 412/3209/412 413/1669/413 414/3211/414 \nf 415/861/415 416/3210/416 413/1669/413 412/3209/412 \nf 405/464/405 410/3208/410 413/1669/413 416/3210/416 \nf 409/860/409 414/3211/414 413/1669/413 410/3208/410 \nf 395/58/395 398/3203/398 417/1670/417 418/3212/418 \nf 393/858/393 406/3206/406 417/1670/417 398/3203/398 \nf 405/464/405 416/3210/416 417/1670/417 406/3206/406 \nf 415/861/415 418/3212/418 417/1670/417 416/3210/416 \nf 419/60/419 420/3213/420 421/1671/421 422/3217/422 \nf 423/862/423 424/3215/424 421/1671/421 420/3213/420 \nf 425/465/425 426/3216/426 421/1671/421 424/3215/424 \nf 427/865/427 422/3217/422 421/1671/421 426/3216/426 \nf 428/61/428 429/3218/429 430/1672/430 431/3220/431 \nf 432/864/432 433/3219/433 430/1672/430 429/3218/429 \nf 425/465/425 424/3215/424 430/1672/430 433/3219/433 \nf 423/862/423 431/3220/431 430/1672/430 424/3215/424 \nf 395/58/395 418/3212/418 434/1673/434 435/3223/435 \nf 415/861/415 436/3222/436 434/1673/434 418/3212/418 \nf 425/465/425 433/3219/433 434/1673/434 436/3222/436 \nf 432/864/432 435/3223/435 434/1673/434 433/3219/433 \nf 411/59/411 437/3224/437 438/1674/438 412/3209/412 \nf 427/865/427 426/3216/426 438/1674/438 437/3224/437 \nf 425/465/425 436/3222/436 438/1674/438 426/3216/426 \nf 415/861/415 412/3209/412 438/1674/438 436/3222/436 \nf 428/61/428 439/3225/439 440/1675/440 429/3218/429 \nf 441/866/441 442/3227/442 440/1675/440 439/3225/439 \nf 443/466/443 444/3228/444 440/1675/440 442/3227/442 \nf 432/864/432 429/3218/429 440/1675/440 444/3228/444 \nf 127/24/127 130/3061/130 445/1676/445 446/3230/446 \nf 135/819/135 447/3229/447 445/1676/445 130/3061/130 \nf 443/466/443 442/3227/442 445/1676/445 447/3229/447 \nf 441/866/441 446/3230/446 445/1676/445 442/3227/442 \nf 119/23/119 402/3204/402 448/1677/448 145/3068/145 \nf 399/859/399 449/3232/449 448/1677/448 402/3204/402 \nf 443/466/443 447/3229/447 448/1677/448 449/3232/449 \nf 135/819/135 145/3068/145 448/1677/448 447/3229/447 \nf 395/58/395 435/3223/435 450/1678/450 396/3201/396 \nf 432/864/432 444/3228/444 450/1678/450 435/3223/435 \nf 443/466/443 449/3232/449 450/1678/450 444/3228/444 \nf 399/859/399 396/3201/396 450/1678/450 449/3232/449 \nf 113/20/113 116/3052/116 451/1679/451 280/3139/280 \nf 109/813/109 452/3233/452 451/1679/451 116/3052/116 \nf 453/467/453 454/3234/454 451/1679/451 452/3233/452 \nf 283/841/283 280/3139/280 451/1679/451 454/3234/454 \nf 91/11/91 455/3235/455 456/1680/456 107/3047/107 \nf 457/868/457 458/3236/458 456/1680/456 455/3235/455 \nf 453/467/453 452/3233/452 456/1680/456 458/3236/458 \nf 109/813/109 107/3047/107 456/1680/456 452/3233/452 \nf 459/62/459 460/3237/460 461/1681/461 462/3239/462 \nf 463/869/463 464/3238/464 461/1681/461 460/3237/460 \nf 453/467/453 458/3236/458 461/1681/461 464/3238/464 \nf 457/868/457 462/3239/462 461/1681/461 458/3236/458 \nf 288/52/288 291/3145/291 465/1682/465 466/3240/466 \nf 283/841/283 454/3234/454 465/1682/465 291/3145/291 \nf 453/467/453 464/3238/464 465/1682/465 454/3234/454 \nf 463/869/463 466/3240/466 465/1682/465 464/3238/464 \nf 91/11/91 94/3041/94 467/1683/467 455/3235/455 \nf 86/809/86 468/3241/468 467/1683/467 94/3041/94 \nf 469/468/469 470/3242/470 467/1683/467 468/3241/468 \nf 457/868/457 455/3235/455 467/1683/467 470/3242/470 \nf 82/10/82 347/3175/347 471/1684/471 83/3035/83 \nf 342/851/342 472/3243/472 471/1684/471 347/3175/347 \nf 469/468/469 468/3241/468 471/1684/471 472/3243/472 \nf 86/809/86 83/3035/83 471/1684/471 468/3241/468 \nf 324/55/324 473/3244/473 474/1685/474 340/3171/340 \nf 475/870/475 476/3245/476 474/1685/474 473/3244/473 \nf 469/468/469 472/3243/472 474/1685/474 476/3245/476 \nf 342/851/342 340/3171/340 474/1685/474 472/3243/472 \nf 459/62/459 462/3239/462 477/1686/477 478/3246/478 \nf 457/868/457 470/3242/470 477/1686/477 462/3239/462 \nf 469/468/469 476/3245/476 477/1686/477 470/3242/470 \nf 475/870/475 478/3246/478 477/1686/477 476/3245/476 \nf 315/54/315 479/3247/479 480/1687/480 316/3157/316 \nf 481/871/481 482/3248/482 480/1687/480 479/3247/479 \nf 483/469/483 484/3249/484 480/1687/480 482/3248/482 \nf 319/846/319 316/3157/316 480/1687/480 484/3249/484 \nf 485/65/485 486/3250/486 487/1688/487 488/3252/488 \nf 489/872/489 490/3251/490 487/1688/487 486/3250/486 \nf 483/469/483 482/3248/482 487/1688/487 490/3251/490 \nf 481/871/481 488/3252/488 487/1688/487 482/3248/482 \nf 459/62/459 478/3246/478 491/1689/491 492/3254/492 \nf 475/870/475 493/3253/493 491/1689/491 478/3246/478 \nf 483/469/483 490/3251/490 491/1689/491 493/3253/493 \nf 489/872/489 492/3254/492 491/1689/491 490/3251/490 \nf 324/55/324 327/3163/327 494/1690/494 473/3244/473 \nf 319/846/319 484/3249/484 494/1690/494 327/3163/327 \nf 483/469/483 493/3253/493 494/1690/494 484/3249/484 \nf 475/870/475 473/3244/473 494/1690/494 493/3253/493 \nf 485/65/485 495/3255/495 496/1691/496 486/3250/486 \nf 497/873/497 498/3256/498 496/1691/496 495/3255/495 \nf 499/470/499 500/3257/500 496/1691/496 498/3256/498 \nf 489/872/489 486/3250/486 496/1691/496 500/3257/500 \nf 305/53/305 308/3154/308 501/1692/501 502/3259/502 \nf 301/844/301 503/3258/503 501/1692/501 308/3154/308 \nf 499/470/499 498/3256/498 501/1692/501 503/3258/503 \nf 497/873/497 502/3259/502 501/1692/501 498/3256/498 \nf 288/52/288 466/3240/466 504/1693/504 299/3149/299 \nf 463/869/463 505/3260/505 504/1693/504 466/3240/466 \nf 499/470/499 503/3258/503 504/1693/504 505/3260/505 \nf 301/844/301 299/3149/299 504/1693/504 503/3258/503 \nf 459/62/459 492/3254/492 506/1694/506 460/3237/460 \nf 489/872/489 500/3257/500 506/1694/506 492/3254/492 \nf 499/470/499 505/3260/505 506/1694/506 500/3257/500 \nf 463/869/463 460/3237/460 506/1694/506 505/3260/505 \nf 507/41/507 508/3261/508 509/1695/509 510/3264/510 \nf 511/874/511 512/3262/512 509/1695/509 508/3261/508 \nf 513/471/513 514/3263/514 509/1695/509 512/3262/512 \nf 515/877/515 510/3264/510 509/1695/509 514/3263/514 \nf 516/107/516 517/3265/517 518/1696/518 519/3267/519 \nf 520/875/520 521/3266/521 518/1696/518 517/3265/517 \nf 513/471/513 512/3262/512 518/1696/518 521/3266/521 \nf 511/874/511 519/3267/519 518/1696/518 512/3262/512 \nf 522/108/522 523/3268/523 524/1697/524 525/3270/525 \nf 526/876/526 527/3269/527 524/1697/524 523/3268/523 \nf 513/471/513 521/3266/521 524/1697/524 527/3269/527 \nf 520/875/520 525/3270/525 524/1697/524 521/3266/521 \nf 528/113/528 529/3271/529 530/1698/530 531/3272/531 \nf 515/877/515 514/3263/514 530/1698/530 529/3271/529 \nf 513/471/513 527/3269/527 530/1698/530 514/3263/514 \nf 526/876/526 531/3272/531 530/1698/530 527/3269/527 \nf 516/107/516 532/3273/532 533/1699/533 517/3265/517 \nf 534/878/534 535/3275/535 533/1699/533 532/3273/532 \nf 536/472/536 537/3276/537 533/1699/533 535/3275/535 \nf 520/875/520 517/3265/517 533/1699/533 537/3276/537 \nf 32/115/32 538/3277/538 539/1700/539 540/3280/540 \nf 541/880/541 542/3279/542 539/1700/539 538/3277/538 \nf 536/472/536 535/3275/535 539/1700/539 542/3279/542 \nf 534/878/534 540/3280/540 539/1700/539 535/3275/535 \nf 543/125/543 544/3282/544 545/1701/545 546/3284/546 \nf 547/882/547 548/3283/548 545/1701/545 544/3282/544 \nf 536/472/536 542/3279/542 545/1701/545 548/3283/548 \nf 541/880/541 546/3284/546 545/1701/545 542/3279/542 \nf 522/108/522 525/3270/525 549/1702/549 550/3286/550 \nf 520/875/520 537/3276/537 549/1702/549 525/3270/525 \nf 536/472/536 548/3283/548 549/1702/549 537/3276/537 \nf 547/882/547 550/3286/550 549/1702/549 548/3283/548 \nf 377/16/377 551/3287/551 552/1703/552 553/3290/553 \nf 554/883/554 555/3288/555 552/1703/552 551/3287/551 \nf 556/473/556 557/3289/557 552/1703/552 555/3288/555 \nf 558/885/558 553/3290/553 552/1703/552 557/3289/557 \nf 559/127/559 560/3291/560 561/1704/561 562/3293/562 \nf 563/884/563 564/3292/564 561/1704/561 560/3291/560 \nf 556/473/556 555/3288/555 561/1704/561 564/3292/564 \nf 554/883/554 562/3293/562 561/1704/561 555/3288/555 \nf 522/108/522 550/3286/550 565/1705/565 566/3295/566 \nf 547/882/547 567/3294/567 565/1705/565 550/3286/550 \nf 556/473/556 564/3292/564 565/1705/565 567/3294/567 \nf 563/884/563 566/3295/566 565/1705/565 564/3292/564 \nf 543/125/543 568/3296/568 569/1706/569 544/3282/544 \nf 558/885/558 557/3289/557 569/1706/569 568/3296/568 \nf 556/473/556 567/3294/567 569/1706/569 557/3289/557 \nf 547/882/547 544/3282/544 569/1706/569 567/3294/567 \nf 559/127/559 570/3297/570 571/1707/571 560/3291/560 \nf 572/886/572 573/3298/573 571/1707/571 570/3297/570 \nf 574/474/574 575/3299/575 571/1707/571 573/3298/573 \nf 563/884/563 560/3291/560 571/1707/571 575/3299/575 \nf 576/128/576 577/3300/577 578/1708/578 579/3302/579 \nf 580/887/580 581/3301/581 578/1708/578 577/3300/577 \nf 574/474/574 573/3298/573 578/1708/578 581/3301/581 \nf 572/886/572 579/3302/579 578/1708/578 573/3298/573 \nf 528/113/528 531/3272/531 582/1709/582 583/3304/583 \nf 526/876/526 584/3303/584 582/1709/582 531/3272/531 \nf 574/474/574 581/3301/581 582/1709/582 584/3303/584 \nf 580/887/580 583/3304/583 582/1709/582 581/3301/581 \nf 522/108/522 566/3295/566 585/1710/585 523/3268/523 \nf 563/884/563 575/3299/575 585/1710/585 566/3295/566 \nf 574/474/574 584/3303/584 585/1710/585 575/3299/575 \nf 526/876/526 523/3268/523 585/1710/585 584/3303/584 \nf 266/49/266 586/3305/586 587/1711/587 407/3207/407 \nf 588/888/588 589/3306/589 587/1711/587 586/3305/586 \nf 590/475/590 591/3307/591 587/1711/587 589/3306/589 \nf 409/860/409 407/3207/407 587/1711/587 591/3307/591 \nf 592/67/592 593/3308/593 594/1712/594 595/3310/595 \nf 596/889/596 597/3309/597 594/1712/594 593/3308/593 \nf 590/475/590 589/3306/589 594/1712/594 597/3309/597 \nf 588/888/588 595/3310/595 594/1712/594 589/3306/589 \nf 598/68/598 599/3311/599 600/1713/600 601/3313/601 \nf 602/890/602 603/3312/603 600/1713/600 599/3311/599 \nf 590/475/590 597/3309/597 600/1713/600 603/3312/603 \nf 596/889/596 601/3313/601 600/1713/600 597/3309/597 \nf 411/59/411 414/3211/414 604/1714/604 605/3314/605 \nf 409/860/409 591/3307/591 604/1714/604 414/3211/414 \nf 590/475/590 603/3312/603 604/1714/604 591/3307/591 \nf 602/890/602 605/3314/605 604/1714/604 603/3312/603 \nf 592/67/592 606/3315/606 607/1715/607 593/3308/593 \nf 608/891/608 609/3316/609 607/1715/607 606/3315/606 \nf 610/476/610 611/3317/611 607/1715/607 609/3316/609 \nf 596/889/596 593/3308/593 607/1715/607 611/3317/611 \nf 612/70/612 613/3318/613 614/1716/614 615/3320/615 \nf 616/892/616 617/3319/617 614/1716/614 613/3318/613 \nf 610/476/610 609/3316/609 614/1716/614 617/3319/617 \nf 608/891/608 615/3320/615 614/1716/614 609/3316/609 \nf 618/72/618 619/3321/619 620/1717/620 621/3323/621 \nf 622/893/622 623/3322/623 620/1717/620 619/3321/619 \nf 610/476/610 617/3319/617 620/1717/620 623/3322/623 \nf 616/892/616 621/3323/621 620/1717/620 617/3319/617 \nf 598/68/598 601/3313/601 624/1718/624 625/3324/625 \nf 596/889/596 611/3317/611 624/1718/624 601/3313/601 \nf 610/476/610 623/3322/623 624/1718/624 611/3317/611 \nf 622/893/622 625/3324/625 624/1718/624 623/3322/623 \nf 626/74/626 627/3325/627 628/1719/628 629/3329/629 \nf 630/894/630 631/3327/631 628/1719/628 627/3325/627 \nf 632/477/632 633/3328/633 628/1719/628 631/3327/631 \nf 634/897/634 629/3329/629 628/1719/628 633/3328/633 \nf 635/75/635 636/3330/636 637/1720/637 638/3332/638 \nf 639/896/639 640/3331/640 637/1720/637 636/3330/636 \nf 632/477/632 631/3327/631 637/1720/637 640/3331/640 \nf 630/894/630 638/3332/638 637/1720/637 631/3327/631 \nf 598/68/598 625/3324/625 641/1721/641 642/3335/642 \nf 622/893/622 643/3334/643 641/1721/641 625/3324/625 \nf 632/477/632 640/3331/640 641/1721/641 643/3334/643 \nf 639/896/639 642/3335/642 641/1721/641 640/3331/640 \nf 618/72/618 644/3336/644 645/1722/645 619/3321/619 \nf 634/897/634 633/3328/633 645/1722/645 644/3336/644 \nf 632/477/632 643/3334/643 645/1722/645 633/3328/633 \nf 622/893/622 619/3321/619 645/1722/645 643/3334/643 \nf 635/75/635 646/3337/646 647/1723/647 636/3330/636 \nf 648/898/648 649/3339/649 647/1723/647 646/3337/646 \nf 650/478/650 651/3340/651 647/1723/647 649/3339/649 \nf 639/896/639 636/3330/636 647/1723/647 651/3340/651 \nf 419/60/419 422/3217/422 652/1724/652 653/3342/653 \nf 427/865/427 654/3341/654 652/1724/652 422/3217/422 \nf 650/478/650 649/3339/649 652/1724/652 654/3341/654 \nf 648/898/648 653/3342/653 652/1724/652 649/3339/649 \nf 411/59/411 605/3314/605 655/1725/655 437/3224/437 \nf 602/890/602 656/3344/656 655/1725/655 605/3314/605 \nf 650/478/650 654/3341/654 655/1725/655 656/3344/656 \nf 427/865/427 437/3224/437 655/1725/655 654/3341/654 \nf 598/68/598 642/3335/642 657/1726/657 599/3311/599 \nf 639/896/639 651/3340/651 657/1726/657 642/3335/642 \nf 650/478/650 656/3344/656 657/1726/657 651/3340/651 \nf 602/890/602 599/3311/599 657/1726/657 656/3344/656 \nf 72/9/72 658/3345/658 659/1727/659 163/3081/163 \nf 660/900/660 661/3346/661 659/1727/659 658/3345/658 \nf 662/479/662 663/3347/663 659/1727/659 661/3346/661 \nf 165/824/165 163/3081/163 659/1727/659 663/3347/663 \nf 664/76/664 665/3348/665 666/1728/666 667/3350/667 \nf 668/901/668 669/3349/669 666/1728/666 665/3348/665 \nf 662/479/662 661/3346/661 666/1728/666 669/3349/669 \nf 660/900/660 667/3350/667 666/1728/666 661/3346/661 \nf 670/77/670 671/3351/671 672/1729/672 673/3353/673 \nf 674/902/674 675/3352/675 672/1729/672 671/3351/671 \nf 662/479/662 669/3349/669 672/1729/672 675/3352/675 \nf 668/901/668 673/3353/673 672/1729/672 669/3349/669 \nf 169/27/169 172/3086/172 676/1730/676 677/3354/677 \nf 165/824/165 663/3347/663 676/1730/676 172/3086/172 \nf 662/479/662 675/3352/675 676/1730/676 663/3347/663 \nf 674/902/674 677/3354/677 676/1730/676 675/3352/675 \nf 664/76/664 678/3355/678 679/1731/679 665/3348/665 \nf 680/903/680 681/3356/681 679/1731/679 678/3355/678 \nf 682/480/682 683/3357/683 679/1731/679 681/3356/681 \nf 668/901/668 665/3348/665 679/1731/679 683/3357/683 \nf 684/86/684 685/3358/685 686/1732/686 687/3360/687 \nf 688/904/688 689/3359/689 686/1732/686 685/3358/685 \nf 682/480/682 681/3356/681 686/1732/686 689/3359/689 \nf 680/903/680 687/3360/687 686/1732/686 681/3356/681 \nf 690/88/690 691/3361/691 692/1733/692 693/3363/693 \nf 694/905/694 695/3362/695 692/1733/692 691/3361/691 \nf 682/480/682 689/3359/689 692/1733/692 695/3362/695 \nf 688/904/688 693/3363/693 692/1733/692 689/3359/689 \nf 670/77/670 673/3353/673 696/1734/696 697/3364/697 \nf 668/901/668 683/3357/683 696/1734/696 673/3353/673 \nf 682/480/682 695/3362/695 696/1734/696 683/3357/683 \nf 694/905/694 697/3364/697 696/1734/696 695/3362/695 \nf 698/177/698 699/3365/699 700/1735/700 701/3368/701 \nf 702/906/702 703/3366/703 700/1735/700 699/3365/699 \nf 704/481/704 705/3367/705 700/1735/700 703/3366/703 \nf 706/908/706 701/3368/701 700/1735/700 705/3367/705 \nf 707/178/707 708/3369/708 709/1736/709 710/3371/710 \nf 711/907/711 712/3370/712 709/1736/709 708/3369/708 \nf 704/481/704 703/3366/703 709/1736/709 712/3370/712 \nf 702/906/702 710/3371/710 709/1736/709 703/3366/703 \nf 670/77/670 697/3364/697 713/1737/713 714/3373/714 \nf 694/905/694 715/3372/715 713/1737/713 697/3364/697 \nf 704/481/704 712/3370/712 713/1737/713 715/3372/715 \nf 711/907/711 714/3373/714 713/1737/713 712/3370/712 \nf 690/88/690 716/3374/716 717/1738/717 691/3361/691 \nf 706/908/706 705/3367/705 717/1738/717 716/3374/716 \nf 704/481/704 715/3372/715 717/1738/717 705/3367/705 \nf 694/905/694 691/3361/691 717/1738/717 715/3372/715 \nf 707/178/707 718/3375/718 719/1739/719 708/3369/708 \nf 720/909/720 721/3376/721 719/1739/719 718/3375/718 \nf 722/482/722 723/3377/723 719/1739/719 721/3376/721 \nf 711/907/711 708/3369/708 719/1739/719 723/3377/723 \nf 189/31/189 192/3096/192 724/1740/724 725/3379/725 \nf 185/827/185 726/3378/726 724/1740/724 192/3096/192 \nf 722/482/722 721/3376/721 724/1740/724 726/3378/726 \nf 720/909/720 725/3379/725 724/1740/724 721/3376/721 \nf 169/27/169 677/3354/677 727/1741/727 183/3091/183 \nf 674/902/674 728/3380/728 727/1741/727 677/3354/677 \nf 722/482/722 726/3378/726 727/1741/727 728/3380/728 \nf 185/827/185 183/3091/183 727/1741/727 726/3378/726 \nf 670/77/670 714/3373/714 729/1742/729 671/3351/671 \nf 711/907/711 723/3377/723 729/1742/729 714/3373/714 \nf 722/482/722 728/3380/728 729/1742/729 723/3377/723 \nf 674/902/674 671/3351/671 729/1742/729 728/3380/728 \nf 235/36/235 730/3381/730 731/1743/731 236/3117/236 \nf 732/910/732 733/3382/733 731/1743/731 730/3381/730 \nf 734/483/734 735/3383/735 731/1743/731 733/3382/733 \nf 239/834/239 236/3117/236 731/1743/731 735/3383/735 \nf 736/179/736 737/3384/737 738/1744/738 739/3386/739 \nf 740/911/740 741/3385/741 738/1744/738 737/3384/737 \nf 734/483/734 733/3382/733 738/1744/738 741/3385/741 \nf 732/910/732 739/3386/739 738/1744/738 733/3382/733 \nf 742/180/742 743/3387/743 744/1745/744 745/3389/745 \nf 746/912/746 747/3388/747 744/1745/744 743/3387/743 \nf 734/483/734 741/3385/741 744/1745/744 747/3388/747 \nf 740/911/740 745/3389/745 744/1745/744 741/3385/741 \nf 244/40/244 247/3123/247 748/1746/748 749/3390/749 \nf 239/834/239 735/3383/735 748/1746/748 247/3123/247 \nf 734/483/734 747/3388/747 748/1746/748 735/3383/735 \nf 746/912/746 749/3390/749 748/1746/748 747/3388/747 \nf 736/179/736 750/3391/750 751/1747/751 737/3384/737 \nf 752/913/752 753/3392/753 751/1747/751 750/3391/750 \nf 754/484/754 755/3393/755 751/1747/751 753/3392/753 \nf 740/911/740 737/3384/737 751/1747/751 755/3393/755 \nf 756/181/756 757/3394/757 758/1748/758 759/3396/759 \nf 760/914/760 761/3395/761 758/1748/758 757/3394/757 \nf 754/484/754 753/3392/753 758/1748/758 761/3395/761 \nf 752/913/752 759/3396/759 758/1748/758 753/3392/753 \nf 762/182/762 763/3397/763 764/1749/764 765/3399/765 \nf 766/915/766 767/3398/767 764/1749/764 763/3397/763 \nf 754/484/754 761/3395/761 764/1749/764 767/3398/767 \nf 760/914/760 765/3399/765 764/1749/764 761/3395/761 \nf 742/180/742 745/3389/745 768/1750/768 769/3400/769 \nf 740/911/740 755/3393/755 768/1750/768 745/3389/745 \nf 754/484/754 767/3398/767 768/1750/768 755/3393/755 \nf 766/915/766 769/3400/769 768/1750/768 767/3398/767 \nf 612/70/612 615/3320/615 770/1751/770 771/3403/771 \nf 608/891/608 772/3401/772 770/1751/770 615/3320/615 \nf 773/485/773 774/3402/774 770/1751/770 772/3401/772 \nf 775/917/775 771/3403/771 770/1751/770 774/3402/774 \nf 592/67/592 776/3404/776 777/1752/777 606/3315/606 \nf 778/916/778 779/3405/779 777/1752/777 776/3404/776 \nf 773/485/773 772/3401/772 777/1752/777 779/3405/779 \nf 608/891/608 606/3315/606 777/1752/777 772/3401/772 \nf 742/180/742 769/3400/769 780/1753/780 781/3407/781 \nf 766/915/766 782/3406/782 780/1753/780 769/3400/769 \nf 773/485/773 779/3405/779 780/1753/780 782/3406/782 \nf 778/916/778 781/3407/781 780/1753/780 779/3405/779 \nf 762/182/762 783/3408/783 784/1754/784 763/3397/763 \nf 775/917/775 774/3402/774 784/1754/784 783/3408/783 \nf 773/485/773 782/3406/782 784/1754/784 774/3402/774 \nf 766/915/766 763/3397/763 784/1754/784 782/3406/782 \nf 592/67/592 595/3310/595 785/1755/785 776/3404/776 \nf 588/888/588 786/3409/786 785/1755/785 595/3310/595 \nf 787/486/787 788/3410/788 785/1755/785 786/3409/786 \nf 778/916/778 776/3404/776 785/1755/785 788/3410/788 \nf 266/49/266 269/3134/269 789/1756/789 586/3305/586 \nf 262/838/262 790/3411/790 789/1756/789 269/3134/269 \nf 787/486/787 786/3409/786 789/1756/789 790/3411/790 \nf 588/888/588 586/3305/586 789/1756/789 786/3409/786 \nf 244/40/244 749/3390/749 791/1757/791 260/3129/260 \nf 746/912/746 792/3412/792 791/1757/791 749/3390/749 \nf 787/486/787 790/3411/790 791/1757/791 792/3412/792 \nf 262/838/262 260/3129/260 791/1757/791 790/3411/790 \nf 742/180/742 781/3407/781 793/1758/793 743/3387/743 \nf 778/916/778 788/3410/788 793/1758/793 781/3407/781 \nf 787/486/787 792/3412/792 793/1758/793 788/3410/788 \nf 746/912/746 743/3387/743 793/1758/793 792/3412/792 \nf 794/21/794 795/3413/795 796/1759/796 797/3416/797 \nf 798/918/798 799/3414/799 796/1759/796 795/3413/795 \nf 800/487/800 801/3415/801 796/1759/796 799/3414/799 \nf 802/921/802 797/3416/797 796/1759/796 801/3415/801 \nf 803/28/803 804/3417/804 805/1760/805 806/3419/806 \nf 807/919/807 808/3418/808 805/1760/805 804/3417/804 \nf 800/487/800 799/3414/799 805/1760/805 808/3418/808 \nf 798/918/798 806/3419/806 805/1760/805 799/3414/799 \nf 809/35/809 810/3420/810 811/1761/811 812/3422/812 \nf 813/920/813 814/3421/814 811/1761/811 810/3420/810 \nf 800/487/800 808/3418/808 811/1761/811 814/3421/814 \nf 807/919/807 812/3422/812 811/1761/811 808/3418/808 \nf 815/42/815 816/3423/816 817/1762/817 818/3424/818 \nf 802/921/802 801/3415/801 817/1762/817 816/3423/816 \nf 800/487/800 814/3421/814 817/1762/817 801/3415/801 \nf 813/920/813 818/3424/818 817/1762/817 814/3421/814 \nf 803/28/803 819/3425/819 820/1763/820 804/3417/804 \nf 821/922/821 822/3426/822 820/1763/820 819/3425/819 \nf 823/488/823 824/3427/824 820/1763/820 822/3426/822 \nf 807/919/807 804/3417/804 820/1763/820 824/3427/824 \nf 825/44/825 826/3428/826 827/1764/827 828/3430/828 \nf 829/923/829 830/3429/830 827/1764/827 826/3428/826 \nf 823/488/823 822/3426/822 827/1764/827 830/3429/830 \nf 821/922/821 828/3430/828 827/1764/827 822/3426/822 \nf 831/46/831 832/3431/832 833/1765/833 834/3433/834 \nf 835/924/835 836/3432/836 833/1765/833 832/3431/832 \nf 823/488/823 830/3429/830 833/1765/833 836/3432/836 \nf 829/923/829 834/3433/834 833/1765/833 830/3429/830 \nf 809/35/809 812/3422/812 837/1766/837 838/3434/838 \nf 807/919/807 824/3427/824 837/1766/837 812/3422/812 \nf 823/488/823 836/3432/836 837/1766/837 824/3427/824 \nf 835/924/835 838/3434/838 837/1766/837 836/3432/836 \nf 839/47/839 840/3435/840 841/1767/841 842/3439/842 \nf 843/925/843 844/3437/844 841/1767/841 840/3435/840 \nf 845/489/845 846/3438/846 841/1767/841 844/3437/844 \nf 847/928/847 842/3439/842 841/1767/841 846/3438/846 \nf 848/78/848 849/3440/849 850/1768/850 851/3442/851 \nf 852/927/852 853/3441/853 850/1768/850 849/3440/849 \nf 845/489/845 844/3437/844 850/1768/850 853/3441/853 \nf 843/925/843 851/3442/851 850/1768/850 844/3437/844 \nf 809/35/809 838/3434/838 854/1769/854 855/3445/855 \nf 835/924/835 856/3444/856 854/1769/854 838/3434/838 \nf 845/489/845 853/3441/853 854/1769/854 856/3444/856 \nf 852/927/852 855/3445/855 854/1769/854 853/3441/853 \nf 831/46/831 857/3446/857 858/1770/858 832/3431/832 \nf 847/928/847 846/3438/846 858/1770/858 857/3446/857 \nf 845/489/845 856/3444/856 858/1770/858 846/3438/846 \nf 835/924/835 832/3431/832 858/1770/858 856/3444/856 \nf 848/78/848 859/3447/859 860/1771/860 849/3440/849 \nf 861/929/861 862/3449/862 860/1771/860 859/3447/859 \nf 863/490/863 864/3450/864 860/1771/860 862/3449/862 \nf 852/927/852 849/3440/849 860/1771/860 864/3450/864 \nf 46/79/46 865/3451/865 866/1772/866 867/3453/867 \nf 868/931/868 869/3452/869 866/1772/866 865/3451/865 \nf 863/490/863 862/3449/862 866/1772/866 869/3452/869 \nf 861/929/861 867/3453/867 866/1772/866 862/3449/862 \nf 815/42/815 818/3424/818 870/1773/870 871/3456/871 \nf 813/920/813 872/3455/872 870/1773/870 818/3424/818 \nf 863/490/863 869/3452/869 870/1773/870 872/3455/872 \nf 868/931/868 871/3456/871 870/1773/870 869/3452/869 \nf 809/35/809 855/3445/855 873/1774/873 810/3420/810 \nf 852/927/852 864/3450/864 873/1774/873 855/3445/855 \nf 863/490/863 872/3455/872 873/1774/873 864/3450/864 \nf 813/920/813 810/3420/810 873/1774/873 872/3455/872 \nf 698/177/698 874/3457/874 875/1775/875 699/3365/699 \nf 876/932/876 877/3458/877 875/1775/875 874/3457/874 \nf 878/491/878 879/3459/879 875/1775/875 877/3458/877 \nf 702/906/702 699/3365/699 875/1775/875 879/3459/879 \nf 880/183/880 881/3460/881 882/1776/882 883/3462/883 \nf 884/933/884 885/3461/885 882/1776/882 881/3460/881 \nf 878/491/878 877/3458/877 882/1776/882 885/3461/885 \nf 876/932/876 883/3462/883 882/1776/882 877/3458/877 \nf 886/185/886 887/3463/887 888/1777/888 889/3465/889 \nf 890/934/890 891/3464/891 888/1777/888 887/3463/887 \nf 878/491/878 885/3461/885 888/1777/888 891/3464/891 \nf 884/933/884 889/3465/889 888/1777/888 885/3461/885 \nf 707/178/707 710/3371/710 892/1778/892 893/3466/893 \nf 702/906/702 879/3459/879 892/1778/892 710/3371/710 \nf 878/491/878 891/3464/891 892/1778/892 879/3459/879 \nf 890/934/890 893/3466/893 892/1778/892 891/3464/891 \nf 880/183/880 894/3467/894 895/1779/895 881/3460/881 \nf 896/935/896 897/3468/897 895/1779/895 894/3467/894 \nf 898/492/898 899/3469/899 895/1779/895 897/3468/897 \nf 884/933/884 881/3460/881 895/1779/895 899/3469/899 \nf 756/181/756 759/3396/759 900/1780/900 901/3471/901 \nf 752/913/752 902/3470/902 900/1780/900 759/3396/759 \nf 898/492/898 897/3468/897 900/1780/900 902/3470/902 \nf 896/935/896 901/3471/901 900/1780/900 897/3468/897 \nf 736/179/736 903/3472/903 904/1781/904 750/3391/750 \nf 905/936/905 906/3473/906 904/1781/904 903/3472/903 \nf 898/492/898 902/3470/902 904/1781/904 906/3473/906 \nf 752/913/752 750/3391/750 904/1781/904 902/3470/902 \nf 886/185/886 889/3465/889 907/1782/907 908/3474/908 \nf 884/933/884 899/3469/899 907/1782/907 889/3465/889 \nf 898/492/898 906/3473/906 907/1782/907 899/3469/899 \nf 905/936/905 908/3474/908 907/1782/907 906/3473/906 \nf 235/36/235 909/3475/909 910/1783/910 730/3381/730 \nf 911/937/911 912/3476/912 910/1783/910 909/3475/909 \nf 913/493/913 914/3477/914 910/1783/910 912/3476/912 \nf 732/910/732 730/3381/730 910/1783/910 914/3477/914 \nf 915/186/915 916/3478/916 917/1784/917 918/3480/918 \nf 919/938/919 920/3479/920 917/1784/917 916/3478/916 \nf 913/493/913 912/3476/912 917/1784/917 920/3479/920 \nf 911/937/911 918/3480/918 917/1784/917 912/3476/912 \nf 886/185/886 908/3474/908 921/1785/921 922/3482/922 \nf 905/936/905 923/3481/923 921/1785/921 908/3474/908 \nf 913/493/913 920/3479/920 921/1785/921 923/3481/923 \nf 919/938/919 922/3482/922 921/1785/921 920/3479/920 \nf 736/179/736 739/3386/739 924/1786/924 903/3472/903 \nf 732/910/732 914/3477/914 924/1786/924 739/3386/739 \nf 913/493/913 923/3481/923 924/1786/924 914/3477/914 \nf 905/936/905 903/3472/903 924/1786/924 923/3481/923 \nf 915/186/915 925/3483/925 926/1787/926 916/3478/916 \nf 927/939/927 928/3484/928 926/1787/926 925/3483/925 \nf 929/494/929 930/3485/930 926/1787/926 928/3484/928 \nf 919/938/919 916/3478/916 926/1787/926 930/3485/930 \nf 189/31/189 725/3379/725 931/1788/931 932/3487/932 \nf 720/909/720 933/3486/933 931/1788/931 725/3379/725 \nf 929/494/929 928/3484/928 931/1788/931 933/3486/933 \nf 927/939/927 932/3487/932 931/1788/931 928/3484/928 \nf 707/178/707 893/3466/893 934/1789/934 718/3375/718 \nf 890/934/890 935/3488/935 934/1789/934 893/3466/893 \nf 929/494/929 933/3486/933 934/1789/934 935/3488/935 \nf 720/909/720 718/3375/718 934/1789/934 933/3486/933 \nf 886/185/886 922/3482/922 936/1790/936 887/3463/887 \nf 919/938/919 930/3485/930 936/1790/936 922/3482/922 \nf 929/494/929 935/3488/935 936/1790/936 930/3485/930 \nf 890/934/890 887/3463/887 936/1790/936 935/3488/935 \nf 189/31/189 932/3487/932 937/1791/937 190/3094/190 \nf 927/939/927 938/3489/938 937/1791/937 932/3487/932 \nf 939/495/939 940/3490/940 937/1791/937 938/3489/938 \nf 193/828/193 190/3094/190 937/1791/937 940/3490/940 \nf 915/186/915 941/3491/941 942/1792/942 925/3483/925 \nf 943/940/943 944/3492/944 942/1792/942 941/3491/941 \nf 939/495/939 938/3489/938 942/1792/942 944/3492/944 \nf 927/939/927 925/3483/925 942/1792/942 938/3489/938 \nf 945/187/945 946/3493/946 947/1793/947 948/3495/948 \nf 949/941/949 950/3494/950 947/1793/947 946/3493/946 \nf 939/495/939 944/3492/944 947/1793/947 950/3494/950 \nf 943/940/943 948/3495/948 947/1793/947 944/3492/944 \nf 195/32/195 198/3099/198 951/1794/951 952/3496/952 \nf 193/828/193 940/3490/940 951/1794/951 198/3099/198 \nf 939/495/939 950/3494/950 951/1794/951 940/3490/940 \nf 949/941/949 952/3496/952 951/1794/951 950/3494/950 \nf 915/186/915 918/3480/918 953/1795/953 941/3491/941 \nf 911/937/911 954/3497/954 953/1795/953 918/3480/918 \nf 955/496/955 956/3498/956 953/1795/953 954/3497/954 \nf 943/940/943 941/3491/941 953/1795/953 956/3498/956 \nf 235/36/235 238/3120/238 957/1796/957 909/3475/909 \nf 243/837/243 958/3499/958 957/1796/957 238/3120/238 \nf 955/496/955 954/3497/954 957/1796/957 958/3499/958 \nf 911/937/911 909/3475/909 957/1796/957 954/3497/954 \nf 256/48/256 959/3500/959 960/1797/960 257/3127/257 \nf 961/942/961 962/3501/962 960/1797/960 959/3500/959 \nf 955/496/955 958/3499/958 960/1797/960 962/3501/962 \nf 243/837/243 257/3127/257 960/1797/960 958/3499/958 \nf 945/187/945 948/3495/948 963/1798/963 964/3502/964 \nf 943/940/943 956/3498/956 963/1798/963 948/3495/948 \nf 955/496/955 962/3501/962 963/1798/963 956/3498/956 \nf 961/942/961 964/3502/964 963/1798/963 962/3501/962 \nf 305/53/305 965/3503/965 966/1799/966 306/3152/306 \nf 967/943/967 968/3504/968 966/1799/966 965/3503/965 \nf 969/497/969 970/3505/970 966/1799/966 968/3504/968 \nf 309/845/309 306/3152/306 966/1799/966 970/3505/970 \nf 971/189/971 972/3506/972 973/1800/973 974/3508/974 \nf 975/944/975 976/3507/976 973/1800/973 972/3506/972 \nf 969/497/969 968/3504/968 973/1800/973 976/3507/976 \nf 967/943/967 974/3508/974 973/1800/973 968/3504/968 \nf 945/187/945 964/3502/964 977/1801/977 978/3510/978 \nf 961/942/961 979/3509/979 977/1801/977 964/3502/964 \nf 969/497/969 976/3507/976 977/1801/977 979/3509/979 \nf 975/944/975 978/3510/978 977/1801/977 976/3507/976 \nf 256/48/256 312/3156/312 980/1802/980 959/3500/959 \nf 309/845/309 970/3505/970 980/1802/980 312/3156/312 \nf 969/497/969 979/3509/979 980/1802/980 970/3505/970 \nf 961/942/961 959/3500/959 980/1802/980 979/3509/979 \nf 971/189/971 981/3511/981 982/1803/982 972/3506/972 \nf 983/945/983 984/3512/984 982/1803/982 981/3511/981 \nf 985/498/985 986/3513/986 982/1803/982 984/3512/984 \nf 975/944/975 972/3506/972 982/1803/982 986/3513/986 \nf 203/33/203 206/3104/206 987/1804/987 988/3515/988 \nf 211/832/211 989/3514/989 987/1804/987 206/3104/206 \nf 985/498/985 984/3512/984 987/1804/987 989/3514/989 \nf 983/945/983 988/3515/988 987/1804/987 984/3512/984 \nf 195/32/195 952/3496/952 990/1805/990 221/3110/221 \nf 949/941/949 991/3516/991 990/1805/990 952/3496/952 \nf 985/498/985 989/3514/989 990/1805/990 991/3516/991 \nf 211/832/211 221/3110/221 990/1805/990 989/3514/989 \nf 945/187/945 978/3510/978 992/1806/992 946/3493/946 \nf 975/944/975 986/3513/986 992/1806/992 978/3510/978 \nf 985/498/985 991/3516/991 992/1806/992 986/3513/986 \nf 949/941/949 946/3493/946 992/1806/992 991/3516/991 \nf 203/33/203 988/3515/988 993/1807/993 204/3101/204 \nf 983/945/983 994/3517/994 993/1807/993 988/3515/988 \nf 995/499/995 996/3518/996 993/1807/993 994/3517/994 \nf 207/830/207 204/3101/204 993/1807/993 996/3518/996 \nf 971/189/971 997/3519/997 998/1808/998 981/3511/981 \nf 999/946/999 1000/3520/1000 998/1808/998 997/3519/997 \nf 995/499/995 994/3517/994 998/1808/998 1000/3520/1000 \nf 983/945/983 981/3511/981 998/1808/998 994/3517/994 \nf 1001/190/1001 1002/3521/1002 1003/1809/1003 1004/3523/1004 \nf 1005/947/1005 1006/3522/1006 1003/1809/1003 1002/3521/1002 \nf 995/499/995 1000/3520/1000 1003/1809/1003 1006/3522/1006 \nf 999/946/999 1004/3523/1004 1003/1809/1003 1000/3520/1000 \nf 212/34/212 215/3107/215 1007/1810/1007 1008/3524/1008 \nf 207/830/207 996/3518/996 1007/1810/1007 215/3107/215 \nf 995/499/995 1006/3522/1006 1007/1810/1007 996/3518/996 \nf 1005/947/1005 1008/3524/1008 1007/1810/1007 1006/3522/1006 \nf 971/189/971 974/3508/974 1009/1811/1009 997/3519/997 \nf 967/943/967 1010/3525/1010 1009/1811/1009 974/3508/974 \nf 1011/500/1011 1012/3526/1012 1009/1811/1009 1010/3525/1010 \nf 999/946/999 997/3519/997 1009/1811/1009 1012/3526/1012 \nf 305/53/305 502/3259/502 1013/1812/1013 965/3503/965 \nf 497/873/497 1014/3527/1014 1013/1812/1013 502/3259/502 \nf 1011/500/1011 1010/3525/1010 1013/1812/1013 1014/3527/1014 \nf 967/943/967 965/3503/965 1013/1812/1013 1010/3525/1010 \nf 485/65/485 1015/3528/1015 1016/1813/1016 495/3255/495 \nf 1017/948/1017 1018/3529/1018 1016/1813/1016 1015/3528/1015 \nf 1011/500/1011 1014/3527/1014 1016/1813/1016 1018/3529/1018 \nf 497/873/497 495/3255/495 1016/1813/1016 1014/3527/1014 \nf 1001/190/1001 1004/3523/1004 1019/1814/1019 1020/3530/1020 \nf 999/946/999 1012/3526/1012 1019/1814/1019 1004/3523/1004 \nf 1011/500/1011 1018/3529/1018 1019/1814/1019 1012/3526/1012 \nf 1017/948/1017 1020/3530/1020 1019/1814/1019 1018/3529/1018 \nf 315/54/315 1021/3531/1021 1022/1815/1022 479/3247/479 \nf 1023/949/1023 1024/3532/1024 1022/1815/1022 1021/3531/1021 \nf 1025/501/1025 1026/3533/1026 1022/1815/1022 1024/3532/1024 \nf 481/871/481 479/3247/479 1022/1815/1022 1026/3533/1026 \nf 1027/191/1027 1028/3534/1028 1029/1816/1029 1030/3536/1030 \nf 1031/950/1031 1032/3535/1032 1029/1816/1029 1028/3534/1028 \nf 1025/501/1025 1024/3532/1024 1029/1816/1029 1032/3535/1032 \nf 1023/949/1023 1030/3536/1030 1029/1816/1029 1024/3532/1024 \nf 1001/190/1001 1020/3530/1020 1033/1817/1033 1034/3538/1034 \nf 1017/948/1017 1035/3537/1035 1033/1817/1033 1020/3530/1020 \nf 1025/501/1025 1032/3535/1032 1033/1817/1033 1035/3537/1035 \nf 1031/950/1031 1034/3538/1034 1033/1817/1033 1032/3535/1032 \nf 485/65/485 488/3252/488 1036/1818/1036 1015/3528/1015 \nf 481/871/481 1026/3533/1026 1036/1818/1036 488/3252/488 \nf 1025/501/1025 1035/3537/1035 1036/1818/1036 1026/3533/1026 \nf 1017/948/1017 1015/3528/1015 1036/1818/1036 1035/3537/1035 \nf 1027/191/1027 1037/3539/1037 1038/1819/1038 1028/3534/1028 \nf 1039/951/1039 1040/3540/1040 1038/1819/1038 1037/3539/1037 \nf 1041/502/1041 1042/3541/1042 1038/1819/1038 1040/3540/1040 \nf 1031/950/1031 1028/3534/1028 1038/1819/1038 1042/3541/1042 \nf 1/1/1 230/3115/230 1043/1820/1043 1044/3543/1044 \nf 225/833/225 1045/3542/1045 1043/1820/1043 230/3115/230 \nf 1041/502/1041 1040/3540/1040 1043/1820/1043 1045/3542/1045 \nf 1039/951/1039 1044/3543/1044 1043/1820/1043 1040/3540/1040 \nf 212/34/212 1008/3524/1008 1046/1821/1046 223/3111/223 \nf 1005/947/1005 1047/3544/1047 1046/1821/1046 1008/3524/1008 \nf 1041/502/1041 1045/3542/1045 1046/1821/1046 1047/3544/1047 \nf 225/833/225 223/3111/223 1046/1821/1046 1045/3542/1045 \nf 1001/190/1001 1034/3538/1034 1048/1822/1048 1002/3521/1002 \nf 1031/950/1031 1042/3541/1042 1048/1822/1048 1034/3538/1034 \nf 1041/502/1041 1047/3544/1047 1048/1822/1048 1042/3541/1042 \nf 1005/947/1005 1002/3521/1002 1048/1822/1048 1047/3544/1047 \nf 32/80/32 540/3281/540 1049/1823/1049 33/3007/33 \nf 534/879/534 1050/3545/1050 1049/1823/1049 540/3281/540 \nf 1051/503/1051 1052/3546/1052 1049/1823/1049 1050/3545/1050 \nf 36/801/36 33/3007/33 1049/1823/1049 1052/3546/1052 \nf 516/90/516 1053/3547/1053 1054/1824/1054 532/3274/532 \nf 1055/952/1055 1056/3549/1056 1054/1824/1054 1053/3547/1053 \nf 1051/503/1051 1050/3545/1050 1054/1824/1054 1056/3549/1056 \nf 534/879/534 532/3274/532 1054/1824/1054 1050/3545/1050 \nf 1057/91/1057 1058/3550/1058 1059/1825/1059 1060/3552/1060 \nf 1061/954/1061 1062/3551/1062 1059/1825/1059 1058/3550/1058 \nf 1051/503/1051 1056/3549/1056 1059/1825/1059 1062/3551/1062 \nf 1055/952/1055 1060/3552/1060 1059/1825/1059 1056/3549/1056 \nf 38/122/38 41/3013/41 1063/1826/1063 1064/3554/1064 \nf 36/801/36 1052/3546/1052 1063/1826/1063 41/3013/41 \nf 1051/503/1051 1062/3551/1062 1063/1826/1063 1052/3546/1052 \nf 1061/954/1061 1064/3554/1064 1063/1826/1063 1062/3551/1062 \nf 516/107/516 519/3267/519 1065/1827/1065 1053/3548/1053 \nf 511/874/511 1066/3555/1066 1065/1827/1065 519/3267/519 \nf 1067/504/1067 1068/3556/1068 1065/1827/1065 1066/3555/1066 \nf 1055/953/1055 1053/3548/1053 1065/1827/1065 1068/3556/1068 \nf 507/41/507 1069/3557/1069 1070/1828/1070 508/3261/508 \nf 1071/955/1071 1072/3558/1072 1070/1828/1070 1069/3557/1069 \nf 1067/504/1067 1066/3555/1066 1070/1828/1070 1072/3558/1072 \nf 511/874/511 508/3261/508 1070/1828/1070 1066/3555/1066 \nf 1073/184/1073 1074/3559/1074 1075/1829/1075 1076/3562/1076 \nf 1077/956/1077 1078/3561/1078 1075/1829/1075 1074/3559/1074 \nf 1067/504/1067 1072/3558/1072 1075/1829/1075 1078/3561/1078 \nf 1071/955/1071 1076/3562/1076 1075/1829/1075 1072/3558/1072 \nf 1057/194/1057 1060/3553/1060 1079/1830/1079 1080/3563/1080 \nf 1055/953/1055 1068/3556/1068 1079/1830/1079 1060/3553/1060 \nf 1067/504/1067 1078/3561/1078 1079/1830/1079 1068/3556/1068 \nf 1077/956/1077 1080/3563/1080 1079/1830/1079 1078/3561/1078 \nf 794/21/794 797/3416/797 1081/1831/1081 1082/3567/1082 \nf 802/921/802 1083/3565/1083 1081/1831/1081 797/3416/797 \nf 1084/505/1084 1085/3566/1085 1081/1831/1081 1083/3565/1083 \nf 1086/959/1086 1082/3567/1082 1081/1831/1081 1085/3566/1085 \nf 815/42/815 1087/3568/1087 1088/1832/1088 816/3423/816 \nf 1089/958/1089 1090/3569/1090 1088/1832/1088 1087/3568/1087 \nf 1084/505/1084 1083/3565/1083 1088/1832/1088 1090/3569/1090 \nf 802/921/802 816/3423/816 1088/1832/1088 1083/3565/1083 \nf 1057/91/1057 1080/3564/1080 1091/1833/1091 1092/3571/1092 \nf 1077/957/1077 1093/3570/1093 1091/1833/1091 1080/3564/1080 \nf 1084/505/1084 1090/3569/1090 1091/1833/1091 1093/3570/1093 \nf 1089/958/1089 1092/3571/1092 1091/1833/1091 1090/3569/1090 \nf 1073/123/1073 1094/3572/1094 1095/1834/1095 1074/3560/1074 \nf 1086/959/1086 1085/3566/1085 1095/1834/1095 1094/3572/1094 \nf 1084/505/1084 1093/3570/1093 1095/1834/1095 1085/3566/1085 \nf 1077/957/1077 1074/3560/1074 1095/1834/1095 1093/3570/1093 \nf 815/42/815 871/3456/871 1096/1835/1096 1087/3568/1087 \nf 868/931/868 1097/3573/1097 1096/1835/1096 871/3456/871 \nf 1098/506/1098 1099/3574/1099 1096/1835/1096 1097/3573/1097 \nf 1089/958/1089 1087/3568/1087 1096/1835/1096 1099/3574/1099 \nf 46/79/46 49/3019/49 1100/1836/1100 865/3451/865 \nf 54/806/54 1101/3575/1101 1100/1836/1100 49/3019/49 \nf 1098/506/1098 1097/3573/1097 1100/1836/1100 1101/3575/1101 \nf 868/931/868 865/3451/865 1100/1836/1100 1097/3573/1097 \nf 38/122/38 1064/3554/1064 1102/1837/1102 64/3026/64 \nf 1061/954/1061 1103/3576/1103 1102/1837/1102 1064/3554/1064 \nf 1098/506/1098 1101/3575/1101 1102/1837/1102 1103/3576/1103 \nf 54/806/54 64/3026/64 1102/1837/1102 1101/3575/1101 \nf 1057/91/1057 1092/3571/1092 1104/1838/1104 1058/3550/1058 \nf 1089/958/1089 1099/3574/1099 1104/1838/1104 1092/3571/1092 \nf 1098/506/1098 1103/3576/1103 1104/1838/1104 1099/3574/1099 \nf 1061/954/1061 1058/3550/1058 1104/1838/1104 1103/3576/1103 \nf 127/17/127 1105/3577/1105 1106/1839/1106 128/3058/128 \nf 1107/960/1107 1108/3578/1108 1106/1839/1106 1105/3577/1105 \nf 1109/507/1109 1110/3579/1110 1106/1839/1106 1108/3578/1108 \nf 131/817/131 128/3058/128 1106/1839/1106 1110/3579/1110 \nf 1111/22/1111 1112/3580/1112 1113/1840/1113 1114/3582/1114 \nf 1115/961/1115 1116/3581/1116 1113/1840/1113 1112/3580/1112 \nf 1109/507/1109 1108/3578/1108 1113/1840/1113 1116/3581/1116 \nf 1107/960/1107 1114/3582/1114 1113/1840/1113 1108/3578/1108 \nf 1117/29/1117 1118/3583/1118 1119/1841/1119 1120/3586/1120 \nf 1121/962/1121 1122/3585/1122 1119/1841/1119 1118/3583/1118 \nf 1109/507/1109 1116/3581/1116 1119/1841/1119 1122/3585/1122 \nf 1115/961/1115 1120/3586/1120 1119/1841/1119 1116/3581/1116 \nf 136/37/136 139/3065/139 1123/1842/1123 1124/3587/1124 \nf 131/817/131 1110/3579/1110 1123/1842/1123 139/3065/139 \nf 1109/507/1109 1122/3585/1122 1123/1842/1123 1110/3579/1110 \nf 1121/962/1121 1124/3587/1124 1123/1842/1123 1122/3585/1122 \nf 1111/22/1111 1125/3589/1125 1126/1843/1126 1112/3580/1112 \nf 1127/964/1127 1128/3590/1128 1126/1843/1126 1125/3589/1125 \nf 1129/508/1129 1130/3591/1130 1126/1843/1126 1128/3590/1128 \nf 1115/961/1115 1112/3580/1112 1126/1843/1126 1130/3591/1130 \nf 1131/39/1131 1132/3592/1132 1133/1844/1133 1134/3594/1134 \nf 1135/965/1135 1136/3593/1136 1133/1844/1133 1132/3592/1132 \nf 1129/508/1129 1128/3590/1128 1133/1844/1133 1136/3593/1136 \nf 1127/964/1127 1134/3594/1134 1133/1844/1133 1128/3590/1128 \nf 1137/43/1137 1138/3595/1138 1139/1845/1139 1140/3598/1140 \nf 1141/966/1141 1142/3597/1142 1139/1845/1139 1138/3595/1138 \nf 1129/508/1129 1136/3593/1136 1139/1845/1139 1142/3597/1142 \nf 1135/965/1135 1140/3598/1140 1139/1845/1139 1136/3593/1136 \nf 1117/29/1117 1120/3586/1120 1143/1846/1143 1144/3599/1144 \nf 1115/961/1115 1130/3591/1130 1143/1846/1143 1120/3586/1120 \nf 1129/508/1129 1142/3597/1142 1143/1846/1143 1130/3591/1130 \nf 1141/966/1141 1144/3599/1144 1143/1846/1143 1142/3597/1142 \nf 1145/228/1145 1146/3601/1146 1147/1847/1147 1148/3604/1148 \nf 1149/968/1149 1150/3602/1150 1147/1847/1147 1146/3601/1146 \nf 1151/509/1151 1152/3603/1152 1147/1847/1147 1150/3602/1150 \nf 1153/970/1153 1148/3604/1148 1147/1847/1147 1152/3603/1152 \nf 1154/238/1154 1155/3605/1155 1156/1848/1156 1157/3607/1157 \nf 1158/969/1158 1159/3606/1159 1156/1848/1156 1155/3605/1155 \nf 1151/509/1151 1150/3602/1150 1156/1848/1156 1159/3606/1159 \nf 1149/968/1149 1157/3607/1157 1156/1848/1156 1150/3602/1150 \nf 1117/279/1117 1144/3600/1144 1160/1849/1160 1161/3609/1161 \nf 1141/967/1141 1162/3608/1162 1160/1849/1160 1144/3600/1144 \nf 1151/509/1151 1159/3606/1159 1160/1849/1160 1162/3608/1162 \nf 1158/969/1158 1161/3609/1161 1160/1849/1160 1159/3606/1159 \nf 1137/293/1137 1163/3610/1163 1164/1850/1164 1138/3596/1138 \nf 1153/970/1153 1152/3603/1152 1164/1850/1164 1163/3610/1163 \nf 1151/509/1151 1162/3608/1162 1164/1850/1164 1152/3603/1152 \nf 1141/967/1141 1138/3596/1138 1164/1850/1164 1162/3608/1162 \nf 1154/238/1154 1165/3611/1165 1166/1851/1166 1155/3605/1155 \nf 1167/971/1167 1168/3612/1168 1166/1851/1166 1165/3611/1165 \nf 1169/510/1169 1170/3613/1170 1166/1851/1166 1168/3612/1168 \nf 1158/969/1158 1155/3605/1155 1166/1851/1166 1170/3613/1170 \nf 153/12/153 156/3077/156 1171/1852/1171 1172/3615/1172 \nf 149/821/149 1173/3614/1173 1171/1852/1171 156/3077/156 \nf 1169/510/1169 1168/3612/1168 1171/1852/1171 1173/3614/1173 \nf 1167/971/1167 1172/3615/1172 1171/1852/1171 1168/3612/1168 \nf 136/299/136 1124/3588/1124 1174/1853/1174 147/3070/147 \nf 1121/963/1121 1175/3616/1175 1174/1853/1174 1124/3588/1124 \nf 1169/510/1169 1173/3614/1173 1174/1853/1174 1175/3616/1175 \nf 149/821/149 147/3070/147 1174/1853/1174 1173/3614/1173 \nf 1117/279/1117 1161/3609/1161 1176/1854/1176 1118/3584/1118 \nf 1158/969/1158 1170/3613/1170 1176/1854/1176 1161/3609/1161 \nf 1169/510/1169 1175/3616/1175 1176/1854/1176 1170/3613/1170 \nf 1121/963/1121 1118/3584/1118 1176/1854/1176 1175/3616/1175 \nf 153/12/153 1172/3615/1172 1177/1855/1177 355/3181/355 \nf 1167/971/1167 1178/3617/1178 1177/1855/1177 1172/3615/1172 \nf 1179/511/1179 1180/3618/1180 1177/1855/1177 1178/3617/1178 \nf 357/854/357 355/3181/355 1177/1855/1177 1180/3618/1180 \nf 1154/238/1154 1181/3619/1181 1182/1856/1182 1165/3611/1165 \nf 1183/972/1183 1184/3620/1184 1182/1856/1182 1181/3619/1181 \nf 1179/511/1179 1178/3617/1178 1182/1856/1182 1184/3620/1184 \nf 1167/971/1167 1165/3611/1165 1182/1856/1182 1178/3617/1178 \nf 1185/362/1185 1186/3621/1186 1187/1857/1187 1188/3623/1188 \nf 1189/973/1189 1190/3622/1190 1187/1857/1187 1186/3621/1186 \nf 1179/511/1179 1184/3620/1184 1187/1857/1187 1190/3622/1190 \nf 1183/972/1183 1188/3623/1188 1187/1857/1187 1184/3620/1184 \nf 361/13/361 364/3186/364 1191/1858/1191 1192/3624/1192 \nf 357/854/357 1180/3618/1180 1191/1858/1191 364/3186/364 \nf 1179/511/1179 1190/3622/1190 1191/1858/1191 1180/3618/1180 \nf 1189/973/1189 1192/3624/1192 1191/1858/1191 1190/3622/1190 \nf 1154/238/1154 1157/3607/1157 1193/1859/1193 1181/3619/1181 \nf 1149/968/1149 1194/3625/1194 1193/1859/1193 1157/3607/1157 \nf 1195/512/1195 1196/3626/1196 1193/1859/1193 1194/3625/1194 \nf 1183/972/1183 1181/3619/1181 1193/1859/1193 1196/3626/1196 \nf 1145/228/1145 1197/3627/1197 1198/1860/1198 1146/3601/1146 \nf 1199/974/1199 1200/3628/1200 1198/1860/1198 1197/3627/1197 \nf 1195/512/1195 1194/3625/1194 1198/1860/1198 1200/3628/1200 \nf 1149/968/1149 1146/3601/1146 1198/1860/1198 1194/3625/1194 \nf 1201/369/1201 1202/3629/1202 1203/1861/1203 1204/3631/1204 \nf 1205/975/1205 1206/3630/1206 1203/1861/1203 1202/3629/1202 \nf 1195/512/1195 1200/3628/1200 1203/1861/1203 1206/3630/1206 \nf 1199/974/1199 1204/3631/1204 1203/1861/1203 1200/3628/1200 \nf 1185/362/1185 1188/3623/1188 1207/1862/1207 1208/3632/1208 \nf 1183/972/1183 1196/3626/1196 1207/1862/1207 1188/3623/1188 \nf 1195/512/1195 1206/3630/1206 1207/1862/1207 1196/3626/1196 \nf 1205/975/1205 1208/3632/1208 1207/1862/1207 1206/3630/1206 \nf 576/128/576 579/3302/579 1209/1863/1209 1210/3635/1210 \nf 572/886/572 1211/3633/1211 1209/1863/1209 579/3302/579 \nf 1212/513/1212 1213/3634/1213 1209/1863/1209 1211/3633/1211 \nf 1214/977/1214 1210/3635/1210 1209/1863/1209 1213/3634/1213 \nf 559/127/559 1215/3636/1215 1216/1864/1216 570/3297/570 \nf 1217/976/1217 1218/3637/1218 1216/1864/1216 1215/3636/1215 \nf 1212/513/1212 1211/3633/1211 1216/1864/1216 1218/3637/1218 \nf 572/886/572 570/3297/570 1216/1864/1216 1211/3633/1211 \nf 1185/362/1185 1208/3632/1208 1219/1865/1219 1220/3639/1220 \nf 1205/975/1205 1221/3638/1221 1219/1865/1219 1208/3632/1208 \nf 1212/513/1212 1218/3637/1218 1219/1865/1219 1221/3638/1221 \nf 1217/976/1217 1220/3639/1220 1219/1865/1219 1218/3637/1218 \nf 1201/369/1201 1222/3640/1222 1223/1866/1223 1202/3629/1202 \nf 1214/977/1214 1213/3634/1213 1223/1866/1223 1222/3640/1222 \nf 1212/513/1212 1221/3638/1221 1223/1866/1223 1213/3634/1213 \nf 1205/975/1205 1202/3629/1202 1223/1866/1223 1221/3638/1221 \nf 559/127/559 562/3293/562 1224/1867/1224 1215/3636/1215 \nf 554/883/554 1225/3641/1225 1224/1867/1224 562/3293/562 \nf 1226/514/1226 1227/3642/1227 1224/1867/1224 1225/3641/1225 \nf 1217/976/1217 1215/3636/1215 1224/1867/1224 1227/3642/1227 \nf 377/16/377 380/3194/380 1228/1868/1228 551/3287/551 \nf 373/856/373 1229/3643/1229 1228/1868/1228 380/3194/380 \nf 1226/514/1226 1225/3641/1225 1228/1868/1228 1229/3643/1229 \nf 554/883/554 551/3287/551 1228/1868/1228 1225/3641/1225 \nf 361/13/361 1192/3624/1192 1230/1869/1230 371/3189/371 \nf 1189/973/1189 1231/3644/1231 1230/1869/1230 1192/3624/1192 \nf 1226/514/1226 1229/3643/1229 1230/1869/1230 1231/3644/1231 \nf 373/856/373 371/3189/371 1230/1869/1230 1229/3643/1229 \nf 1185/362/1185 1220/3639/1220 1232/1870/1232 1186/3621/1186 \nf 1217/976/1217 1227/3642/1227 1232/1870/1232 1220/3639/1220 \nf 1226/514/1226 1231/3644/1231 1232/1870/1232 1227/3642/1227 \nf 1189/973/1189 1186/3621/1186 1232/1870/1232 1231/3644/1231 \nf 419/51/419 1233/3645/1233 1234/1871/1234 420/3214/420 \nf 1235/978/1235 1236/3646/1236 1234/1871/1234 1233/3645/1233 \nf 1237/515/1237 1238/3647/1238 1234/1871/1234 1236/3646/1236 \nf 423/863/423 420/3214/420 1234/1871/1234 1238/3647/1238 \nf 1239/66/1239 1240/3648/1240 1241/1872/1241 1242/3650/1242 \nf 1243/979/1243 1244/3649/1244 1241/1872/1241 1240/3648/1240 \nf 1237/515/1237 1236/3646/1236 1241/1872/1241 1244/3649/1244 \nf 1235/978/1235 1242/3650/1242 1241/1872/1241 1236/3646/1236 \nf 1245/73/1245 1246/3651/1246 1247/1873/1247 1248/3653/1248 \nf 1249/980/1249 1250/3652/1250 1247/1873/1247 1246/3651/1246 \nf 1237/515/1237 1244/3649/1244 1247/1873/1247 1250/3652/1250 \nf 1243/979/1243 1248/3653/1248 1247/1873/1247 1244/3649/1244 \nf 428/82/428 431/3221/431 1251/1874/1251 1252/3654/1252 \nf 423/863/423 1238/3647/1238 1251/1874/1251 431/3221/431 \nf 1237/515/1237 1250/3652/1250 1251/1874/1251 1238/3647/1238 \nf 1249/980/1249 1252/3654/1252 1251/1874/1251 1250/3652/1250 \nf 1239/66/1239 1253/3655/1253 1254/1875/1254 1240/3648/1240 \nf 1255/981/1255 1256/3656/1256 1254/1875/1254 1253/3655/1253 \nf 1257/516/1257 1258/3657/1258 1254/1875/1254 1256/3656/1256 \nf 1243/979/1243 1240/3648/1240 1254/1875/1254 1258/3657/1258 \nf 1259/85/1259 1260/3658/1260 1261/1876/1261 1262/3660/1262 \nf 1263/982/1263 1264/3659/1264 1261/1876/1261 1260/3658/1260 \nf 1257/516/1257 1256/3656/1256 1261/1876/1261 1264/3659/1264 \nf 1255/981/1255 1262/3660/1262 1261/1876/1261 1256/3656/1256 \nf 1265/87/1265 1266/3661/1266 1267/1877/1267 1268/3663/1268 \nf 1269/983/1269 1270/3662/1270 1267/1877/1267 1266/3661/1266 \nf 1257/516/1257 1264/3659/1264 1267/1877/1267 1270/3662/1270 \nf 1263/982/1263 1268/3663/1268 1267/1877/1267 1264/3659/1264 \nf 1245/73/1245 1248/3653/1248 1271/1878/1271 1272/3664/1272 \nf 1243/979/1243 1258/3657/1258 1271/1878/1271 1248/3653/1248 \nf 1257/516/1257 1270/3662/1270 1271/1878/1271 1258/3657/1258 \nf 1269/983/1269 1272/3664/1272 1271/1878/1271 1270/3662/1270 \nf 1131/39/1131 1134/3594/1134 1273/1879/1273 1274/3667/1274 \nf 1127/964/1127 1275/3665/1275 1273/1879/1273 1134/3594/1134 \nf 1276/517/1276 1277/3666/1277 1273/1879/1273 1275/3665/1275 \nf 1278/985/1278 1274/3667/1274 1273/1879/1273 1277/3666/1277 \nf 1111/22/1111 1279/3668/1279 1280/1880/1280 1125/3589/1125 \nf 1281/984/1281 1282/3669/1282 1280/1880/1280 1279/3668/1279 \nf 1276/517/1276 1275/3665/1275 1280/1880/1280 1282/3669/1282 \nf 1127/964/1127 1125/3589/1125 1280/1880/1280 1275/3665/1275 \nf 1245/73/1245 1272/3664/1272 1283/1881/1283 1284/3671/1284 \nf 1269/983/1269 1285/3670/1285 1283/1881/1283 1272/3664/1272 \nf 1276/517/1276 1282/3669/1282 1283/1881/1283 1285/3670/1285 \nf 1281/984/1281 1284/3671/1284 1283/1881/1283 1282/3669/1282 \nf 1265/87/1265 1286/3672/1286 1287/1882/1287 1266/3661/1266 \nf 1278/985/1278 1277/3666/1277 1287/1882/1287 1286/3672/1286 \nf 1276/517/1276 1285/3670/1285 1287/1882/1287 1277/3666/1277 \nf 1269/983/1269 1266/3661/1266 1287/1882/1287 1285/3670/1285 \nf 1111/22/1111 1114/3582/1114 1288/1883/1288 1279/3668/1279 \nf 1107/960/1107 1289/3673/1289 1288/1883/1288 1114/3582/1114 \nf 1290/518/1290 1291/3674/1291 1288/1883/1288 1289/3673/1289 \nf 1281/984/1281 1279/3668/1279 1288/1883/1288 1291/3674/1291 \nf 127/17/127 446/3231/446 1292/1884/1292 1105/3577/1105 \nf 441/867/441 1293/3675/1293 1292/1884/1292 446/3231/446 \nf 1290/518/1290 1289/3673/1289 1292/1884/1292 1293/3675/1293 \nf 1107/960/1107 1105/3577/1105 1292/1884/1292 1289/3673/1289 \nf 428/82/428 1252/3654/1252 1294/1885/1294 439/3226/439 \nf 1249/980/1249 1295/3676/1295 1294/1885/1294 1252/3654/1252 \nf 1290/518/1290 1293/3675/1293 1294/1885/1294 1295/3676/1295 \nf 441/867/441 439/3226/439 1294/1885/1294 1293/3675/1293 \nf 1245/73/1245 1284/3671/1284 1296/1886/1296 1246/3651/1246 \nf 1281/984/1281 1291/3674/1291 1296/1886/1296 1284/3671/1284 \nf 1290/518/1290 1295/3676/1295 1296/1886/1296 1291/3674/1291 \nf 1249/980/1249 1246/3651/1246 1296/1886/1296 1295/3676/1295 \nf 32/5/32 35/3009/35 1297/1887/1297 538/3278/538 \nf 28/799/28 1298/3677/1298 1297/1887/1297 35/3009/35 \nf 1299/519/1299 1300/3678/1300 1297/1887/1297 1298/3677/1298 \nf 541/881/541 538/3278/538 1297/1887/1297 1300/3678/1300 \nf 10/2/10 1301/3679/1301 1302/1888/1302 26/3003/26 \nf 1303/986/1303 1304/3680/1304 1302/1888/1302 1301/3679/1301 \nf 1299/519/1299 1298/3677/1298 1302/1888/1302 1304/3680/1304 \nf 28/799/28 26/3003/26 1302/1888/1302 1298/3677/1298 \nf 1305/196/1305 1306/3681/1306 1307/1889/1307 1308/3684/1308 \nf 1309/987/1309 1310/3683/1310 1307/1889/1307 1306/3681/1306 \nf 1299/519/1299 1304/3680/1304 1307/1889/1307 1310/3683/1310 \nf 1303/986/1303 1308/3684/1308 1307/1889/1307 1304/3680/1304 \nf 543/198/543 546/3285/546 1311/1890/1311 1312/3685/1312 \nf 541/881/541 1300/3678/1300 1311/1890/1311 546/3285/546 \nf 1299/519/1299 1310/3683/1310 1311/1890/1311 1300/3678/1300 \nf 1309/987/1309 1312/3685/1312 1311/1890/1311 1310/3683/1310 \nf 10/2/10 13/2997/13 1313/1891/1313 1301/3679/1301 \nf 5/795/5 1314/3687/1314 1313/1891/1313 13/2997/13 \nf 1315/520/1315 1316/3688/1316 1313/1891/1313 1314/3687/1314 \nf 1303/986/1303 1301/3679/1301 1313/1891/1313 1316/3688/1316 \nf 1/1/1 1044/3543/1044 1317/1892/1317 2/2991/2 \nf 1039/951/1039 1318/3689/1318 1317/1892/1317 1044/3543/1044 \nf 1315/520/1315 1314/3687/1314 1317/1892/1317 1318/3689/1318 \nf 5/795/5 2/2991/2 1317/1892/1317 1314/3687/1314 \nf 1027/191/1027 1319/3690/1319 1320/1893/1320 1037/3539/1037 \nf 1321/989/1321 1322/3691/1322 1320/1893/1320 1319/3690/1319 \nf 1315/520/1315 1318/3689/1318 1320/1893/1320 1322/3691/1322 \nf 1039/951/1039 1037/3539/1037 1320/1893/1320 1318/3689/1318 \nf 1305/196/1305 1308/3684/1308 1323/1894/1323 1324/3692/1324 \nf 1303/986/1303 1316/3688/1316 1323/1894/1323 1308/3684/1308 \nf 1315/520/1315 1322/3691/1322 1323/1894/1323 1316/3688/1316 \nf 1321/989/1321 1324/3692/1324 1323/1894/1323 1322/3691/1322 \nf 315/54/315 318/3160/318 1325/1895/1325 1021/3531/1021 \nf 323/850/323 1326/3693/1326 1325/1895/1325 318/3160/318 \nf 1327/521/1327 1328/3694/1328 1325/1895/1325 1326/3693/1326 \nf 1023/949/1023 1021/3531/1021 1325/1895/1325 1328/3694/1328 \nf 336/57/336 1329/3695/1329 1330/1896/1330 337/3168/337 \nf 1331/990/1331 1332/3697/1332 1330/1896/1330 1329/3695/1329 \nf 1327/521/1327 1326/3693/1326 1330/1896/1330 1332/3697/1332 \nf 323/850/323 337/3168/337 1330/1896/1330 1326/3693/1326 \nf 1305/196/1305 1324/3692/1324 1333/1897/1333 1334/3699/1334 \nf 1321/989/1321 1335/3698/1335 1333/1897/1333 1324/3692/1324 \nf 1327/521/1327 1332/3697/1332 1333/1897/1333 1335/3698/1335 \nf 1331/990/1331 1334/3699/1334 1333/1897/1333 1332/3697/1332 \nf 1027/191/1027 1030/3536/1030 1336/1898/1336 1319/3690/1319 \nf 1023/949/1023 1328/3694/1328 1336/1898/1336 1030/3536/1030 \nf 1327/521/1327 1335/3698/1335 1336/1898/1336 1328/3694/1328 \nf 1321/989/1321 1319/3690/1319 1336/1898/1336 1335/3698/1335 \nf 336/38/336 384/3196/384 1337/1899/1337 1329/3696/1329 \nf 381/857/381 1338/3701/1338 1337/1899/1337 384/3196/384 \nf 1339/522/1339 1340/3702/1340 1337/1899/1337 1338/3701/1338 \nf 1331/991/1331 1329/3696/1329 1337/1899/1337 1340/3702/1340 \nf 377/16/377 553/3290/553 1341/1900/1341 378/3192/378 \nf 558/885/558 1342/3703/1342 1341/1900/1341 553/3290/553 \nf 1339/522/1339 1338/3701/1338 1341/1900/1341 1342/3703/1342 \nf 381/857/381 378/3192/378 1341/1900/1341 1338/3701/1338 \nf 543/125/543 1312/3686/1312 1343/1901/1343 568/3296/568 \nf 1309/988/1309 1344/3704/1344 1343/1901/1343 1312/3686/1312 \nf 1339/522/1339 1342/3703/1342 1343/1901/1343 1344/3704/1344 \nf 558/885/558 568/3296/568 1343/1901/1343 1342/3703/1342 \nf 1305/370/1305 1334/3700/1334 1345/1902/1345 1306/3682/1306 \nf 1331/991/1331 1340/3702/1340 1345/1902/1345 1334/3700/1334 \nf 1339/522/1339 1344/3704/1344 1345/1902/1345 1340/3702/1340 \nf 1309/988/1309 1306/3682/1306 1345/1902/1345 1344/3704/1344 \nf 626/95/626 1346/3705/1346 1347/1903/1347 627/3326/627 \nf 1348/992/1348 1349/3706/1349 1347/1903/1347 1346/3705/1346 \nf 1350/523/1350 1351/3707/1351 1347/1903/1347 1349/3706/1349 \nf 630/895/630 627/3326/627 1347/1903/1347 1351/3707/1351 \nf 1352/110/1352 1353/3708/1353 1354/1904/1354 1355/3710/1355 \nf 1356/993/1356 1357/3709/1357 1354/1904/1354 1353/3708/1353 \nf 1350/523/1350 1349/3706/1349 1354/1904/1354 1357/3709/1357 \nf 1348/992/1348 1355/3710/1355 1354/1904/1354 1349/3706/1349 \nf 1358/117/1358 1359/3711/1359 1360/1905/1360 1361/3713/1361 \nf 1362/994/1362 1363/3712/1363 1360/1905/1360 1359/3711/1359 \nf 1350/523/1350 1357/3709/1357 1360/1905/1360 1363/3712/1363 \nf 1356/993/1356 1361/3713/1361 1360/1905/1360 1357/3709/1357 \nf 635/126/635 638/3333/638 1364/1906/1364 1365/3714/1365 \nf 630/895/630 1351/3707/1351 1364/1906/1364 638/3333/638 \nf 1350/523/1350 1363/3712/1363 1364/1906/1364 1351/3707/1351 \nf 1362/994/1362 1365/3714/1365 1364/1906/1364 1363/3712/1363 \nf 1352/110/1352 1366/3715/1366 1367/1907/1367 1353/3708/1353 \nf 1368/995/1368 1369/3716/1369 1367/1907/1367 1366/3715/1366 \nf 1370/524/1370 1371/3717/1371 1367/1907/1367 1369/3716/1369 \nf 1356/993/1356 1353/3708/1353 1367/1907/1367 1371/3717/1371 \nf 1372/129/1372 1373/3718/1373 1374/1908/1374 1375/3720/1375 \nf 1376/996/1376 1377/3719/1377 1374/1908/1374 1373/3718/1373 \nf 1370/524/1370 1369/3716/1369 1374/1908/1374 1377/3719/1377 \nf 1368/995/1368 1375/3720/1375 1374/1908/1374 1369/3716/1369 \nf 1378/131/1378 1379/3721/1379 1380/1909/1380 1381/3723/1381 \nf 1382/997/1382 1383/3722/1383 1380/1909/1380 1379/3721/1379 \nf 1370/524/1370 1377/3719/1377 1380/1909/1380 1383/3722/1383 \nf 1376/996/1376 1381/3723/1381 1380/1909/1380 1377/3719/1377 \nf 1358/117/1358 1361/3713/1361 1384/1910/1384 1385/3724/1385 \nf 1356/993/1356 1371/3717/1371 1384/1910/1384 1361/3713/1361 \nf 1370/524/1370 1383/3722/1383 1384/1910/1384 1371/3717/1371 \nf 1382/997/1382 1385/3724/1385 1384/1910/1384 1383/3722/1383 \nf 1259/85/1259 1262/3660/1262 1386/1911/1386 1387/3727/1387 \nf 1255/981/1255 1388/3725/1388 1386/1911/1386 1262/3660/1262 \nf 1389/525/1389 1390/3726/1390 1386/1911/1386 1388/3725/1388 \nf 1391/999/1391 1387/3727/1387 1386/1911/1386 1390/3726/1390 \nf 1239/66/1239 1392/3728/1392 1393/1912/1393 1253/3655/1253 \nf 1394/998/1394 1395/3729/1395 1393/1912/1393 1392/3728/1392 \nf 1389/525/1389 1388/3725/1388 1393/1912/1393 1395/3729/1395 \nf 1255/981/1255 1253/3655/1253 1393/1912/1393 1388/3725/1388 \nf 1358/117/1358 1385/3724/1385 1396/1913/1396 1397/3731/1397 \nf 1382/997/1382 1398/3730/1398 1396/1913/1396 1385/3724/1385 \nf 1389/525/1389 1395/3729/1395 1396/1913/1396 1398/3730/1398 \nf 1394/998/1394 1397/3731/1397 1396/1913/1396 1395/3729/1395 \nf 1378/131/1378 1399/3732/1399 1400/1914/1400 1379/3721/1379 \nf 1391/999/1391 1390/3726/1390 1400/1914/1400 1399/3732/1399 \nf 1389/525/1389 1398/3730/1398 1400/1914/1400 1390/3726/1390 \nf 1382/997/1382 1379/3721/1379 1400/1914/1400 1398/3730/1398 \nf 1239/66/1239 1242/3650/1242 1401/1915/1401 1392/3728/1392 \nf 1235/978/1235 1402/3733/1402 1401/1915/1401 1242/3650/1242 \nf 1403/526/1403 1404/3734/1404 1401/1915/1401 1402/3733/1402 \nf 1394/998/1394 1392/3728/1392 1401/1915/1401 1404/3734/1404 \nf 419/51/419 653/3343/653 1405/1916/1405 1233/3645/1233 \nf 648/899/648 1406/3735/1406 1405/1916/1405 653/3343/653 \nf 1403/526/1403 1402/3733/1402 1405/1916/1405 1406/3735/1406 \nf 1235/978/1235 1233/3645/1233 1405/1916/1405 1402/3733/1402 \nf 635/126/635 1365/3714/1365 1407/1917/1407 646/3338/646 \nf 1362/994/1362 1408/3736/1408 1407/1917/1407 1365/3714/1365 \nf 1403/526/1403 1406/3735/1406 1407/1917/1407 1408/3736/1408 \nf 648/899/648 646/3338/646 1407/1917/1407 1406/3735/1406 \nf 1358/117/1358 1397/3731/1397 1409/1918/1409 1359/3711/1359 \nf 1394/998/1394 1404/3734/1404 1409/1918/1409 1397/3731/1397 \nf 1403/526/1403 1408/3736/1408 1409/1918/1409 1404/3734/1404 \nf 1362/994/1362 1359/3711/1359 1409/1918/1409 1408/3736/1408 \nf 839/199/839 1410/3737/1410 1411/1919/1411 840/3436/840 \nf 1412/1000/1412 1413/3738/1413 1411/1919/1411 1410/3737/1410 \nf 1414/527/1414 1415/3739/1415 1411/1919/1411 1413/3738/1413 \nf 843/926/843 840/3436/840 1411/1919/1411 1415/3739/1415 \nf 1416/200/1416 1417/3740/1417 1418/1920/1418 1419/3742/1419 \nf 1420/1001/1420 1421/3741/1421 1418/1920/1418 1417/3740/1417 \nf 1414/527/1414 1413/3738/1413 1418/1920/1418 1421/3741/1421 \nf 1412/1000/1412 1419/3742/1419 1418/1920/1418 1413/3738/1413 \nf 1422/201/1422 1423/3743/1423 1424/1921/1424 1425/3745/1425 \nf 1426/1002/1426 1427/3744/1427 1424/1921/1424 1423/3743/1423 \nf 1414/527/1414 1421/3741/1421 1424/1921/1424 1427/3744/1427 \nf 1420/1001/1420 1425/3745/1425 1424/1921/1424 1421/3741/1421 \nf 848/202/848 851/3443/851 1428/1922/1428 1429/3746/1429 \nf 843/926/843 1415/3739/1415 1428/1922/1428 851/3443/851 \nf 1414/527/1414 1427/3744/1427 1428/1922/1428 1415/3739/1415 \nf 1426/1002/1426 1429/3746/1429 1428/1922/1428 1427/3744/1427 \nf 1416/200/1416 1430/3747/1430 1431/1923/1431 1417/3740/1417 \nf 1432/1003/1432 1433/3748/1433 1431/1923/1431 1430/3747/1430 \nf 1434/528/1434 1435/3749/1435 1431/1923/1431 1433/3748/1433 \nf 1420/1001/1420 1417/3740/1417 1431/1923/1431 1435/3749/1435 \nf 684/86/684 687/3360/687 1436/1924/1436 1437/3751/1437 \nf 680/903/680 1438/3750/1438 1436/1924/1436 687/3360/687 \nf 1434/528/1434 1433/3748/1433 1436/1924/1436 1438/3750/1438 \nf 1432/1003/1432 1437/3751/1437 1436/1924/1436 1433/3748/1433 \nf 664/76/664 1439/3752/1439 1440/1925/1440 678/3355/678 \nf 1441/1004/1441 1442/3753/1442 1440/1925/1440 1439/3752/1439 \nf 1434/528/1434 1438/3750/1438 1440/1925/1440 1442/3753/1442 \nf 680/903/680 678/3355/678 1440/1925/1440 1438/3750/1438 \nf 1422/201/1422 1425/3745/1425 1443/1926/1443 1444/3754/1444 \nf 1420/1001/1420 1435/3749/1435 1443/1926/1443 1425/3745/1425 \nf 1434/528/1434 1442/3753/1442 1443/1926/1443 1435/3749/1435 \nf 1441/1004/1441 1444/3754/1444 1443/1926/1443 1442/3753/1442 \nf 72/9/72 75/3032/75 1445/1927/1445 658/3345/658 \nf 68/807/68 1446/3755/1446 1445/1927/1445 75/3032/75 \nf 1447/529/1447 1448/3756/1448 1445/1927/1445 1446/3755/1446 \nf 660/900/660 658/3345/658 1445/1927/1445 1448/3756/1448 \nf 55/8/55 1449/3757/1449 1450/1928/1450 66/3027/66 \nf 1451/1005/1451 1452/3758/1452 1450/1928/1450 1449/3757/1449 \nf 1447/529/1447 1446/3755/1446 1450/1928/1450 1452/3758/1452 \nf 68/807/68 66/3027/66 1450/1928/1450 1446/3755/1446 \nf 1422/201/1422 1444/3754/1444 1453/1929/1453 1454/3760/1454 \nf 1441/1004/1441 1455/3759/1455 1453/1929/1453 1444/3754/1444 \nf 1447/529/1447 1452/3758/1452 1453/1929/1453 1455/3759/1455 \nf 1451/1005/1451 1454/3760/1454 1453/1929/1453 1452/3758/1452 \nf 664/76/664 667/3350/667 1456/1930/1456 1439/3752/1439 \nf 660/900/660 1448/3756/1448 1456/1930/1456 667/3350/667 \nf 1447/529/1447 1455/3759/1455 1456/1930/1456 1448/3756/1448 \nf 1441/1004/1441 1439/3752/1439 1456/1930/1456 1455/3759/1455 \nf 55/8/55 58/3022/58 1457/1931/1457 1449/3757/1449 \nf 50/803/50 1458/3761/1458 1457/1931/1457 58/3022/58 \nf 1459/530/1459 1460/3762/1460 1457/1931/1457 1458/3761/1458 \nf 1451/1005/1451 1449/3757/1449 1457/1931/1457 1460/3762/1460 \nf 46/7/46 867/3454/867 1461/1932/1461 47/3015/47 \nf 861/930/861 1462/3763/1462 1461/1932/1461 867/3454/867 \nf 1459/530/1459 1458/3761/1458 1461/1932/1461 1462/3763/1462 \nf 50/803/50 47/3015/47 1461/1932/1461 1458/3761/1458 \nf 848/202/848 1429/3746/1429 1463/1933/1463 859/3448/859 \nf 1426/1002/1426 1464/3764/1464 1463/1933/1463 1429/3746/1429 \nf 1459/530/1459 1462/3763/1462 1463/1933/1463 1464/3764/1464 \nf 861/930/861 859/3448/859 1463/1933/1463 1462/3763/1462 \nf 1422/201/1422 1454/3760/1454 1465/1934/1465 1423/3743/1423 \nf 1451/1005/1451 1460/3762/1460 1465/1934/1465 1454/3760/1454 \nf 1459/530/1459 1464/3764/1464 1465/1934/1465 1460/3762/1460 \nf 1426/1002/1426 1423/3743/1423 1465/1934/1465 1464/3764/1464 \nf 1466/203/1466 1467/3765/1467 1468/1935/1468 1469/3768/1469 \nf 1470/1006/1470 1471/3766/1471 1468/1935/1468 1467/3765/1467 \nf 1472/531/1472 1473/3767/1473 1468/1935/1468 1471/3766/1471 \nf 1474/1009/1474 1469/3768/1469 1468/1935/1468 1473/3767/1473 \nf 1475/204/1475 1476/3769/1476 1477/1936/1477 1478/3771/1478 \nf 1479/1007/1479 1480/3770/1480 1477/1936/1477 1476/3769/1476 \nf 1472/531/1472 1471/3766/1471 1477/1936/1477 1480/3770/1480 \nf 1470/1006/1470 1478/3771/1478 1477/1936/1477 1471/3766/1471 \nf 1481/205/1481 1482/3772/1482 1483/1937/1483 1484/3774/1484 \nf 1485/1008/1485 1486/3773/1486 1483/1937/1483 1482/3772/1482 \nf 1472/531/1472 1480/3770/1480 1483/1937/1483 1486/3773/1486 \nf 1479/1007/1479 1484/3774/1484 1483/1937/1483 1480/3770/1480 \nf 1487/207/1487 1488/3775/1488 1489/1938/1489 1490/3776/1490 \nf 1474/1009/1474 1473/3767/1473 1489/1938/1489 1488/3775/1488 \nf 1472/531/1472 1486/3773/1486 1489/1938/1489 1473/3767/1473 \nf 1485/1008/1485 1490/3776/1490 1489/1938/1489 1486/3773/1486 \nf 1475/204/1475 1491/3777/1491 1492/1939/1492 1476/3769/1476 \nf 1493/1010/1493 1494/3778/1494 1492/1939/1492 1491/3777/1491 \nf 1495/532/1495 1496/3779/1496 1492/1939/1492 1494/3778/1494 \nf 1479/1007/1479 1476/3769/1476 1492/1939/1492 1496/3779/1496 \nf 1497/208/1497 1498/3780/1498 1499/1940/1499 1500/3782/1500 \nf 1501/1011/1501 1502/3781/1502 1499/1940/1499 1498/3780/1498 \nf 1495/532/1495 1494/3778/1494 1499/1940/1499 1502/3781/1502 \nf 1493/1010/1493 1500/3782/1500 1499/1940/1499 1494/3778/1494 \nf 1503/209/1503 1504/3783/1504 1505/1941/1505 1506/3785/1506 \nf 1507/1012/1507 1508/3784/1508 1505/1941/1505 1504/3783/1504 \nf 1495/532/1495 1502/3781/1502 1505/1941/1505 1508/3784/1508 \nf 1501/1011/1501 1506/3785/1506 1505/1941/1505 1502/3781/1502 \nf 1481/205/1481 1484/3774/1484 1509/1942/1509 1510/3786/1510 \nf 1479/1007/1479 1496/3779/1496 1509/1942/1509 1484/3774/1484 \nf 1495/532/1495 1508/3784/1508 1509/1942/1509 1496/3779/1496 \nf 1507/1012/1507 1510/3786/1510 1509/1942/1509 1508/3784/1508 \nf 1511/211/1511 1512/3787/1512 1513/1943/1513 1514/3791/1514 \nf 1515/1013/1515 1516/3789/1516 1513/1943/1513 1512/3787/1512 \nf 1517/533/1517 1518/3790/1518 1513/1943/1513 1516/3789/1516 \nf 1519/1016/1519 1514/3791/1514 1513/1943/1513 1518/3790/1518 \nf 1520/212/1520 1521/3792/1521 1522/1944/1522 1523/3794/1523 \nf 1524/1015/1524 1525/3793/1525 1522/1944/1522 1521/3792/1521 \nf 1517/533/1517 1516/3789/1516 1522/1944/1522 1525/3793/1525 \nf 1515/1013/1515 1523/3794/1523 1522/1944/1522 1516/3789/1516 \nf 1481/205/1481 1510/3786/1510 1526/1945/1526 1527/3797/1527 \nf 1507/1012/1507 1528/3796/1528 1526/1945/1526 1510/3786/1510 \nf 1517/533/1517 1525/3793/1525 1526/1945/1526 1528/3796/1528 \nf 1524/1015/1524 1527/3797/1527 1526/1945/1526 1525/3793/1525 \nf 1503/209/1503 1529/3798/1529 1530/1946/1530 1504/3783/1504 \nf 1519/1016/1519 1518/3790/1518 1530/1946/1530 1529/3798/1529 \nf 1517/533/1517 1528/3796/1528 1530/1946/1530 1518/3790/1518 \nf 1507/1012/1507 1504/3783/1504 1530/1946/1530 1528/3796/1528 \nf 1520/212/1520 1531/3799/1531 1532/1947/1532 1521/3792/1521 \nf 1533/1017/1533 1534/3801/1534 1532/1947/1532 1531/3799/1531 \nf 1535/534/1535 1536/3802/1536 1532/1947/1532 1534/3801/1534 \nf 1524/1015/1524 1521/3792/1521 1532/1947/1532 1536/3802/1536 \nf 1537/213/1537 1538/3803/1538 1539/1948/1539 1540/3805/1540 \nf 1541/1019/1541 1542/3804/1542 1539/1948/1539 1538/3803/1538 \nf 1535/534/1535 1534/3801/1534 1539/1948/1539 1542/3804/1542 \nf 1533/1017/1533 1540/3805/1540 1539/1948/1539 1534/3801/1534 \nf 1487/207/1487 1490/3776/1490 1543/1949/1543 1544/3808/1544 \nf 1485/1008/1485 1545/3807/1545 1543/1949/1543 1490/3776/1490 \nf 1535/534/1535 1542/3804/1542 1543/1949/1543 1545/3807/1545 \nf 1541/1019/1541 1544/3808/1544 1543/1949/1543 1542/3804/1542 \nf 1481/205/1481 1527/3797/1527 1546/1950/1546 1482/3772/1482 \nf 1524/1015/1524 1536/3802/1536 1546/1950/1546 1527/3797/1527 \nf 1535/534/1535 1545/3807/1545 1546/1950/1546 1536/3802/1536 \nf 1485/1008/1485 1482/3772/1482 1546/1950/1546 1545/3807/1545 \nf 1547/218/1547 1548/3809/1548 1549/1951/1549 1550/3812/1550 \nf 1551/1020/1551 1552/3810/1552 1549/1951/1549 1548/3809/1548 \nf 1553/535/1553 1554/3811/1554 1549/1951/1549 1552/3810/1552 \nf 1555/1023/1555 1550/3812/1550 1549/1951/1549 1554/3811/1554 \nf 1556/220/1556 1557/3813/1557 1558/1952/1558 1559/3815/1559 \nf 1560/1021/1560 1561/3814/1561 1558/1952/1558 1557/3813/1557 \nf 1553/535/1553 1552/3810/1552 1558/1952/1558 1561/3814/1561 \nf 1551/1020/1551 1559/3815/1559 1558/1952/1558 1552/3810/1552 \nf 1562/265/1562 1563/3816/1563 1564/1953/1564 1565/3818/1565 \nf 1566/1022/1566 1567/3817/1567 1564/1953/1564 1563/3816/1563 \nf 1553/535/1553 1561/3814/1561 1564/1953/1564 1567/3817/1567 \nf 1560/1021/1560 1565/3818/1565 1564/1953/1564 1561/3814/1561 \nf 1568/266/1568 1569/3819/1569 1570/1954/1570 1571/3820/1571 \nf 1555/1023/1555 1554/3811/1554 1570/1954/1570 1569/3819/1569 \nf 1553/535/1553 1567/3817/1567 1570/1954/1570 1554/3811/1554 \nf 1566/1022/1566 1571/3820/1571 1570/1954/1570 1567/3817/1567 \nf 1556/220/1556 1572/3821/1572 1573/1955/1573 1557/3813/1557 \nf 1574/1024/1574 1575/3823/1575 1573/1955/1573 1572/3821/1572 \nf 1576/536/1576 1577/3824/1577 1573/1955/1573 1575/3823/1575 \nf 1560/1021/1560 1557/3813/1557 1573/1955/1573 1577/3824/1577 \nf 1578/267/1578 1579/3825/1579 1580/1956/1580 1581/3828/1581 \nf 1582/1026/1582 1583/3827/1583 1580/1956/1580 1579/3825/1579 \nf 1576/536/1576 1575/3823/1575 1580/1956/1580 1583/3827/1583 \nf 1574/1024/1574 1581/3828/1581 1580/1956/1580 1575/3823/1575 \nf 1584/268/1584 1585/3830/1585 1586/1957/1586 1587/3832/1587 \nf 1588/1028/1588 1589/3831/1589 1586/1957/1586 1585/3830/1585 \nf 1576/536/1576 1583/3827/1583 1586/1957/1586 1589/3831/1589 \nf 1582/1026/1582 1587/3832/1587 1586/1957/1586 1583/3827/1583 \nf 1562/265/1562 1565/3818/1565 1590/1958/1590 1591/3834/1591 \nf 1560/1021/1560 1577/3824/1577 1590/1958/1590 1565/3818/1565 \nf 1576/536/1576 1589/3831/1589 1590/1958/1590 1577/3824/1577 \nf 1588/1028/1588 1591/3834/1591 1590/1958/1590 1589/3831/1589 \nf 1592/269/1592 1593/3835/1593 1594/1959/1594 1595/3838/1595 \nf 1596/1029/1596 1597/3836/1597 1594/1959/1594 1593/3835/1593 \nf 1598/537/1598 1599/3837/1599 1594/1959/1594 1597/3836/1597 \nf 1600/1031/1600 1595/3838/1595 1594/1959/1594 1599/3837/1599 \nf 1601/270/1601 1602/3840/1602 1603/1960/1603 1604/3842/1604 \nf 1605/1030/1605 1606/3841/1606 1603/1960/1603 1602/3840/1602 \nf 1598/537/1598 1597/3836/1597 1603/1960/1603 1606/3841/1606 \nf 1596/1029/1596 1604/3842/1604 1603/1960/1603 1597/3836/1597 \nf 1562/265/1562 1591/3834/1591 1607/1961/1607 1608/3844/1608 \nf 1588/1028/1588 1609/3843/1609 1607/1961/1607 1591/3834/1591 \nf 1598/537/1598 1606/3841/1606 1607/1961/1607 1609/3843/1609 \nf 1605/1030/1605 1608/3844/1608 1607/1961/1607 1606/3841/1606 \nf 1584/268/1584 1610/3845/1610 1611/1962/1611 1585/3830/1585 \nf 1600/1031/1600 1599/3837/1599 1611/1962/1611 1610/3845/1610 \nf 1598/537/1598 1609/3843/1609 1611/1962/1611 1599/3837/1599 \nf 1588/1028/1588 1585/3830/1585 1611/1962/1611 1609/3843/1609 \nf 1601/270/1601 1612/3847/1612 1613/1963/1613 1602/3840/1602 \nf 1614/1033/1614 1615/3848/1615 1613/1963/1613 1612/3847/1612 \nf 1616/538/1616 1617/3849/1617 1613/1963/1613 1615/3848/1615 \nf 1605/1030/1605 1602/3840/1602 1613/1963/1613 1617/3849/1617 \nf 1618/271/1618 1619/3850/1619 1620/1964/1620 1621/3852/1621 \nf 1622/1034/1622 1623/3851/1623 1620/1964/1620 1619/3850/1619 \nf 1616/538/1616 1615/3848/1615 1620/1964/1620 1623/3851/1623 \nf 1614/1033/1614 1621/3852/1621 1620/1964/1620 1615/3848/1615 \nf 1568/266/1568 1571/3820/1571 1624/1965/1624 1625/3854/1625 \nf 1566/1022/1566 1626/3853/1626 1624/1965/1624 1571/3820/1571 \nf 1616/538/1616 1623/3851/1623 1624/1965/1624 1626/3853/1626 \nf 1622/1034/1622 1625/3854/1625 1624/1965/1624 1623/3851/1623 \nf 1562/265/1562 1608/3844/1608 1627/1966/1627 1563/3816/1563 \nf 1605/1030/1605 1617/3849/1617 1627/1966/1627 1608/3844/1608 \nf 1616/538/1616 1626/3853/1626 1627/1966/1627 1617/3849/1617 \nf 1566/1022/1566 1563/3816/1563 1627/1966/1627 1626/3853/1626 \nf 1497/208/1497 1500/3782/1500 1628/1967/1628 1629/3857/1629 \nf 1493/1010/1493 1630/3855/1630 1628/1967/1628 1500/3782/1500 \nf 1631/539/1631 1632/3856/1632 1628/1967/1628 1630/3855/1630 \nf 1633/1037/1633 1629/3857/1629 1628/1967/1628 1632/3856/1632 \nf 1475/204/1475 1634/3858/1634 1635/1968/1635 1491/3777/1491 \nf 1636/1035/1636 1637/3859/1637 1635/1968/1635 1634/3858/1634 \nf 1631/539/1631 1630/3855/1630 1635/1968/1635 1637/3859/1637 \nf 1493/1010/1493 1491/3777/1491 1635/1968/1635 1630/3855/1630 \nf 1638/272/1638 1639/3860/1639 1640/1969/1640 1641/3862/1641 \nf 1642/1036/1642 1643/3861/1643 1640/1969/1640 1639/3860/1639 \nf 1631/539/1631 1637/3859/1637 1640/1969/1640 1643/3861/1643 \nf 1636/1035/1636 1641/3862/1641 1640/1969/1640 1637/3859/1637 \nf 1644/273/1644 1645/3863/1645 1646/1970/1646 1647/3864/1647 \nf 1633/1037/1633 1632/3856/1632 1646/1970/1646 1645/3863/1645 \nf 1631/539/1631 1643/3861/1643 1646/1970/1646 1632/3856/1632 \nf 1642/1036/1642 1647/3864/1647 1646/1970/1646 1643/3861/1643 \nf 1475/204/1475 1478/3771/1478 1648/1971/1648 1634/3858/1634 \nf 1470/1006/1470 1649/3865/1649 1648/1971/1648 1478/3771/1478 \nf 1650/540/1650 1651/3866/1651 1648/1971/1648 1649/3865/1649 \nf 1636/1035/1636 1634/3858/1634 1648/1971/1648 1651/3866/1651 \nf 1466/203/1466 1652/3867/1652 1653/1972/1653 1467/3765/1467 \nf 1654/1038/1654 1655/3868/1655 1653/1972/1653 1652/3867/1652 \nf 1650/540/1650 1649/3865/1649 1653/1972/1653 1655/3868/1655 \nf 1470/1006/1470 1467/3765/1467 1653/1972/1653 1649/3865/1649 \nf 1656/274/1656 1657/3869/1657 1658/1973/1658 1659/3871/1659 \nf 1660/1039/1660 1661/3870/1661 1658/1973/1658 1657/3869/1657 \nf 1650/540/1650 1655/3868/1655 1658/1973/1658 1661/3870/1661 \nf 1654/1038/1654 1659/3871/1659 1658/1973/1658 1655/3868/1655 \nf 1638/272/1638 1641/3862/1641 1662/1974/1662 1663/3872/1663 \nf 1636/1035/1636 1651/3866/1651 1662/1974/1662 1641/3862/1641 \nf 1650/540/1650 1661/3870/1661 1662/1974/1662 1651/3866/1651 \nf 1660/1039/1660 1663/3872/1663 1662/1974/1662 1661/3870/1661 \nf 1664/275/1664 1665/3873/1665 1666/1975/1666 1667/3876/1667 \nf 1668/1040/1668 1669/3874/1669 1666/1975/1666 1665/3873/1665 \nf 1670/541/1670 1671/3875/1671 1666/1975/1666 1669/3874/1669 \nf 1672/1042/1672 1667/3876/1667 1666/1975/1666 1671/3875/1671 \nf 1673/276/1673 1674/3877/1674 1675/1976/1675 1676/3879/1676 \nf 1677/1041/1677 1678/3878/1678 1675/1976/1675 1674/3877/1674 \nf 1670/541/1670 1669/3874/1669 1675/1976/1675 1678/3878/1678 \nf 1668/1040/1668 1676/3879/1676 1675/1976/1675 1669/3874/1669 \nf 1638/272/1638 1663/3872/1663 1679/1977/1679 1680/3881/1680 \nf 1660/1039/1660 1681/3880/1681 1679/1977/1679 1663/3872/1663 \nf 1670/541/1670 1678/3878/1678 1679/1977/1679 1681/3880/1681 \nf 1677/1041/1677 1680/3881/1680 1679/1977/1679 1678/3878/1678 \nf 1656/274/1656 1682/3882/1682 1683/1978/1683 1657/3869/1657 \nf 1672/1042/1672 1671/3875/1671 1683/1978/1683 1682/3882/1682 \nf 1670/541/1670 1681/3880/1681 1683/1978/1683 1671/3875/1671 \nf 1660/1039/1660 1657/3869/1657 1683/1978/1683 1681/3880/1681 \nf 1673/276/1673 1684/3883/1684 1685/1979/1685 1674/3877/1674 \nf 1686/1043/1686 1687/3884/1687 1685/1979/1685 1684/3883/1684 \nf 1688/542/1688 1689/3885/1689 1685/1979/1685 1687/3884/1687 \nf 1677/1041/1677 1674/3877/1674 1685/1979/1685 1689/3885/1689 \nf 1690/277/1690 1691/3886/1691 1692/1980/1692 1693/3888/1693 \nf 1694/1044/1694 1695/3887/1695 1692/1980/1692 1691/3886/1691 \nf 1688/542/1688 1687/3884/1687 1692/1980/1692 1695/3887/1695 \nf 1686/1043/1686 1693/3888/1693 1692/1980/1692 1687/3884/1687 \nf 1644/273/1644 1647/3864/1647 1696/1981/1696 1697/3890/1697 \nf 1642/1036/1642 1698/3889/1698 1696/1981/1696 1647/3864/1647 \nf 1688/542/1688 1695/3887/1695 1696/1981/1696 1698/3889/1698 \nf 1694/1044/1694 1697/3890/1697 1696/1981/1696 1695/3887/1695 \nf 1638/272/1638 1680/3881/1680 1699/1982/1699 1639/3860/1639 \nf 1677/1041/1677 1689/3885/1689 1699/1982/1699 1680/3881/1680 \nf 1688/542/1688 1698/3889/1698 1699/1982/1699 1689/3885/1689 \nf 1642/1036/1642 1639/3860/1639 1699/1982/1699 1698/3889/1698 \nf 1700/278/1700 1701/3891/1701 1702/1983/1702 1703/3894/1703 \nf 1704/1045/1704 1705/3892/1705 1702/1983/1702 1701/3891/1701 \nf 1706/543/1706 1707/3893/1707 1702/1983/1702 1705/3892/1705 \nf 1708/1048/1708 1703/3894/1703 1702/1983/1702 1707/3893/1707 \nf 1709/281/1709 1710/3895/1710 1711/1984/1711 1712/3897/1712 \nf 1713/1046/1713 1714/3896/1714 1711/1984/1711 1710/3895/1710 \nf 1706/543/1706 1705/3892/1705 1711/1984/1711 1714/3896/1714 \nf 1704/1045/1704 1712/3897/1712 1711/1984/1711 1705/3892/1705 \nf 1715/282/1715 1716/3898/1716 1717/1985/1717 1718/3900/1718 \nf 1719/1047/1719 1720/3899/1720 1717/1985/1717 1716/3898/1716 \nf 1706/543/1706 1714/3896/1714 1717/1985/1717 1720/3899/1720 \nf 1713/1046/1713 1718/3900/1718 1717/1985/1717 1714/3896/1714 \nf 1721/283/1721 1722/3901/1722 1723/1986/1723 1724/3902/1724 \nf 1708/1048/1708 1707/3893/1707 1723/1986/1723 1722/3901/1722 \nf 1706/543/1706 1720/3899/1720 1723/1986/1723 1707/3893/1707 \nf 1719/1047/1719 1724/3902/1724 1723/1986/1723 1720/3899/1720 \nf 1709/281/1709 1725/3903/1725 1726/1987/1726 1710/3895/1710 \nf 1727/1049/1727 1728/3904/1728 1726/1987/1726 1725/3903/1725 \nf 1729/544/1729 1730/3905/1730 1726/1987/1726 1728/3904/1728 \nf 1713/1046/1713 1710/3895/1710 1726/1987/1726 1730/3905/1730 \nf 1731/284/1731 1732/3906/1732 1733/1988/1733 1734/3908/1734 \nf 1735/1050/1735 1736/3907/1736 1733/1988/1733 1732/3906/1732 \nf 1729/544/1729 1728/3904/1728 1733/1988/1733 1736/3907/1736 \nf 1727/1049/1727 1734/3908/1734 1733/1988/1733 1728/3904/1728 \nf 1737/286/1737 1738/3909/1738 1739/1989/1739 1740/3911/1740 \nf 1741/1051/1741 1742/3910/1742 1739/1989/1739 1738/3909/1738 \nf 1729/544/1729 1736/3907/1736 1739/1989/1739 1742/3910/1742 \nf 1735/1050/1735 1740/3911/1740 1739/1989/1739 1736/3907/1736 \nf 1715/282/1715 1718/3900/1718 1743/1990/1743 1744/3912/1744 \nf 1713/1046/1713 1730/3905/1730 1743/1990/1743 1718/3900/1718 \nf 1729/544/1729 1742/3910/1742 1743/1990/1743 1730/3905/1730 \nf 1741/1051/1741 1744/3912/1744 1743/1990/1743 1742/3910/1742 \nf 1618/271/1618 1745/3913/1745 1746/1991/1746 1747/3916/1747 \nf 1748/1052/1748 1749/3914/1749 1746/1991/1746 1745/3913/1745 \nf 1750/545/1750 1751/3915/1751 1746/1991/1746 1749/3914/1749 \nf 1752/1054/1752 1747/3916/1747 1746/1991/1746 1751/3915/1751 \nf 1753/287/1753 1754/3917/1754 1755/1992/1755 1756/3919/1756 \nf 1757/1053/1757 1758/3918/1758 1755/1992/1755 1754/3917/1754 \nf 1750/545/1750 1749/3914/1749 1755/1992/1755 1758/3918/1758 \nf 1748/1052/1748 1756/3919/1756 1755/1992/1755 1749/3914/1749 \nf 1715/282/1715 1744/3912/1744 1759/1993/1759 1760/3921/1760 \nf 1741/1051/1741 1761/3920/1761 1759/1993/1759 1744/3912/1744 \nf 1750/545/1750 1758/3918/1758 1759/1993/1759 1761/3920/1761 \nf 1757/1053/1757 1760/3921/1760 1759/1993/1759 1758/3918/1758 \nf 1737/286/1737 1762/3922/1762 1763/1994/1763 1738/3909/1738 \nf 1752/1054/1752 1751/3915/1751 1763/1994/1763 1762/3922/1762 \nf 1750/545/1750 1761/3920/1761 1763/1994/1763 1751/3915/1751 \nf 1741/1051/1741 1738/3909/1738 1763/1994/1763 1761/3920/1761 \nf 1753/287/1753 1764/3923/1764 1765/1995/1765 1754/3917/1754 \nf 1766/1055/1766 1767/3924/1767 1765/1995/1765 1764/3923/1764 \nf 1768/546/1768 1769/3925/1769 1765/1995/1765 1767/3924/1767 \nf 1757/1053/1757 1754/3917/1754 1765/1995/1765 1769/3925/1769 \nf 1770/288/1770 1771/3926/1771 1772/1996/1772 1773/3928/1773 \nf 1774/1056/1774 1775/3927/1775 1772/1996/1772 1771/3926/1771 \nf 1768/546/1768 1767/3924/1767 1772/1996/1772 1775/3927/1775 \nf 1766/1055/1766 1773/3928/1773 1772/1996/1772 1767/3924/1767 \nf 1721/283/1721 1724/3902/1724 1776/1997/1776 1777/3930/1777 \nf 1719/1047/1719 1778/3929/1778 1776/1997/1776 1724/3902/1724 \nf 1768/546/1768 1775/3927/1775 1776/1997/1776 1778/3929/1778 \nf 1774/1056/1774 1777/3930/1777 1776/1997/1776 1775/3927/1775 \nf 1715/282/1715 1760/3921/1760 1779/1998/1779 1716/3898/1716 \nf 1757/1053/1757 1769/3925/1769 1779/1998/1779 1760/3921/1760 \nf 1768/546/1768 1778/3929/1778 1779/1998/1779 1769/3925/1769 \nf 1719/1047/1719 1716/3898/1716 1779/1998/1779 1778/3929/1778 \nf 1780/289/1780 1781/3931/1781 1782/1999/1782 1783/3934/1783 \nf 1784/1057/1784 1785/3932/1785 1782/1999/1782 1781/3931/1781 \nf 1786/547/1786 1787/3933/1787 1782/1999/1782 1785/3932/1785 \nf 1788/1061/1788 1783/3934/1783 1782/1999/1782 1787/3933/1787 \nf 1789/290/1789 1790/3935/1790 1791/2000/1791 1792/3938/1792 \nf 1793/1058/1793 1794/3937/1794 1791/2000/1791 1790/3935/1790 \nf 1786/547/1786 1785/3932/1785 1791/2000/1791 1794/3937/1794 \nf 1784/1057/1784 1792/3938/1792 1791/2000/1791 1785/3932/1785 \nf 1795/295/1795 1796/3939/1796 1797/2001/1797 1798/3941/1798 \nf 1799/1060/1799 1800/3940/1800 1797/2001/1797 1796/3939/1796 \nf 1786/547/1786 1794/3937/1794 1797/2001/1797 1800/3940/1800 \nf 1793/1058/1793 1798/3941/1798 1797/2001/1797 1794/3937/1794 \nf 1801/296/1801 1802/3943/1802 1803/2002/1803 1804/3944/1804 \nf 1788/1061/1788 1787/3933/1787 1803/2002/1803 1802/3943/1802 \nf 1786/547/1786 1800/3940/1800 1803/2002/1803 1787/3933/1787 \nf 1799/1060/1799 1804/3944/1804 1803/2002/1803 1800/3940/1800 \nf 1789/63/1789 1805/3945/1805 1806/2003/1806 1790/3936/1790 \nf 1807/1062/1807 1808/3946/1808 1806/2003/1806 1805/3945/1805 \nf 1809/548/1809 1810/3947/1810 1806/2003/1806 1808/3946/1808 \nf 1793/1059/1793 1790/3936/1790 1806/2003/1806 1810/3947/1810 \nf 1811/64/1811 1812/3948/1812 1813/2004/1813 1814/3950/1814 \nf 1815/1063/1815 1816/3949/1816 1813/2004/1813 1812/3948/1812 \nf 1809/548/1809 1808/3946/1808 1813/2004/1813 1816/3949/1816 \nf 1807/1062/1807 1814/3950/1814 1813/2004/1813 1808/3946/1808 \nf 1817/69/1817 1818/3951/1818 1819/2005/1819 1820/3953/1820 \nf 1821/1064/1821 1822/3952/1822 1819/2005/1819 1818/3951/1818 \nf 1809/548/1809 1816/3949/1816 1819/2005/1819 1822/3952/1822 \nf 1815/1063/1815 1820/3953/1820 1819/2005/1819 1816/3949/1816 \nf 1795/71/1795 1798/3942/1798 1823/2006/1823 1824/3954/1824 \nf 1793/1059/1793 1810/3947/1810 1823/2006/1823 1798/3942/1798 \nf 1809/548/1809 1822/3952/1822 1823/2006/1823 1810/3947/1810 \nf 1821/1064/1821 1824/3954/1824 1823/2006/1823 1822/3952/1822 \nf 1578/81/1578 1581/3829/1581 1825/2007/1825 1826/3957/1826 \nf 1574/1025/1574 1827/3955/1827 1825/2007/1825 1581/3829/1581 \nf 1828/549/1828 1829/3956/1829 1825/2007/1825 1827/3955/1827 \nf 1830/1067/1830 1826/3957/1826 1825/2007/1825 1829/3956/1829 \nf 1556/83/1556 1831/3958/1831 1832/2008/1832 1572/3822/1572 \nf 1833/1065/1833 1834/3960/1834 1832/2008/1832 1831/3958/1831 \nf 1828/549/1828 1827/3955/1827 1832/2008/1832 1834/3960/1834 \nf 1574/1025/1574 1572/3822/1572 1832/2008/1832 1827/3955/1827 \nf 1795/71/1795 1824/3954/1824 1835/2009/1835 1836/3962/1836 \nf 1821/1064/1821 1837/3961/1837 1835/2009/1835 1824/3954/1824 \nf 1828/549/1828 1834/3960/1834 1835/2009/1835 1837/3961/1837 \nf 1833/1065/1833 1836/3962/1836 1835/2009/1835 1834/3960/1834 \nf 1817/69/1817 1838/3964/1838 1839/2010/1839 1818/3951/1818 \nf 1830/1067/1830 1829/3956/1829 1839/2010/1839 1838/3964/1838 \nf 1828/549/1828 1837/3961/1837 1839/2010/1839 1829/3956/1829 \nf 1821/1064/1821 1818/3951/1818 1839/2010/1839 1837/3961/1837 \nf 1556/220/1556 1559/3815/1559 1840/2011/1840 1831/3959/1831 \nf 1551/1020/1551 1841/3965/1841 1840/2011/1840 1559/3815/1559 \nf 1842/550/1842 1843/3966/1843 1840/2011/1840 1841/3965/1841 \nf 1833/1066/1833 1831/3959/1831 1840/2011/1840 1843/3966/1843 \nf 1547/218/1547 1844/3967/1844 1845/2012/1845 1548/3809/1548 \nf 1846/1068/1846 1847/3968/1847 1845/2012/1845 1844/3967/1844 \nf 1842/550/1842 1841/3965/1841 1845/2012/1845 1847/3968/1847 \nf 1551/1020/1551 1548/3809/1548 1845/2012/1845 1841/3965/1841 \nf 1801/296/1801 1804/3944/1804 1848/2013/1848 1849/3970/1849 \nf 1799/1060/1799 1850/3969/1850 1848/2013/1848 1804/3944/1804 \nf 1842/550/1842 1847/3968/1847 1848/2013/1848 1850/3969/1850 \nf 1846/1068/1846 1849/3970/1849 1848/2013/1848 1847/3968/1847 \nf 1795/295/1795 1836/3963/1836 1851/2014/1851 1796/3939/1796 \nf 1833/1066/1833 1843/3966/1843 1851/2014/1851 1836/3963/1836 \nf 1842/550/1842 1850/3969/1850 1851/2014/1851 1843/3966/1843 \nf 1799/1060/1799 1796/3939/1796 1851/2014/1851 1850/3969/1850 \nf 1618/271/1618 1621/3852/1621 1852/2015/1852 1745/3913/1745 \nf 1614/1033/1614 1853/3971/1853 1852/2015/1852 1621/3852/1621 \nf 1854/551/1854 1855/3972/1855 1852/2015/1852 1853/3971/1853 \nf 1748/1052/1748 1745/3913/1745 1852/2015/1852 1855/3972/1855 \nf 1601/270/1601 1856/3973/1856 1857/2016/1857 1612/3847/1612 \nf 1858/1069/1858 1859/3974/1859 1857/2016/1857 1856/3973/1856 \nf 1854/551/1854 1853/3971/1853 1857/2016/1857 1859/3974/1859 \nf 1614/1033/1614 1612/3847/1612 1857/2016/1857 1853/3971/1853 \nf 1860/301/1860 1861/3975/1861 1862/2017/1862 1863/3977/1863 \nf 1864/1070/1864 1865/3976/1865 1862/2017/1862 1861/3975/1861 \nf 1854/551/1854 1859/3974/1859 1862/2017/1862 1865/3976/1865 \nf 1858/1069/1858 1863/3977/1863 1862/2017/1862 1859/3974/1859 \nf 1753/287/1753 1756/3919/1756 1866/2018/1866 1867/3978/1867 \nf 1748/1052/1748 1855/3972/1855 1866/2018/1866 1756/3919/1756 \nf 1854/551/1854 1865/3976/1865 1866/2018/1866 1855/3972/1855 \nf 1864/1070/1864 1867/3978/1867 1866/2018/1866 1865/3976/1865 \nf 1601/270/1601 1604/3842/1604 1868/2019/1868 1856/3973/1856 \nf 1596/1029/1596 1869/3979/1869 1868/2019/1868 1604/3842/1604 \nf 1870/552/1870 1871/3980/1871 1868/2019/1868 1869/3979/1869 \nf 1858/1069/1858 1856/3973/1856 1868/2019/1868 1871/3980/1871 \nf 1592/269/1592 1872/3981/1872 1873/2020/1873 1593/3835/1593 \nf 1874/1071/1874 1875/3983/1875 1873/2020/1873 1872/3981/1872 \nf 1870/552/1870 1869/3979/1869 1873/2020/1873 1875/3983/1875 \nf 1596/1029/1596 1593/3835/1593 1873/2020/1873 1869/3979/1869 \nf 1876/304/1876 1877/3984/1877 1878/2021/1878 1879/3986/1879 \nf 1880/1073/1880 1881/3985/1881 1878/2021/1878 1877/3984/1877 \nf 1870/552/1870 1875/3983/1875 1878/2021/1878 1881/3985/1881 \nf 1874/1071/1874 1879/3986/1879 1878/2021/1878 1875/3983/1875 \nf 1860/301/1860 1863/3977/1863 1882/2022/1882 1883/3988/1883 \nf 1858/1069/1858 1871/3980/1871 1882/2022/1882 1863/3977/1863 \nf 1870/552/1870 1881/3985/1881 1882/2022/1882 1871/3980/1871 \nf 1880/1073/1880 1883/3988/1883 1882/2022/1882 1881/3985/1881 \nf 1884/306/1884 1885/3989/1885 1886/2023/1886 1887/3992/1887 \nf 1888/1074/1888 1889/3990/1889 1886/2023/1886 1885/3989/1885 \nf 1890/553/1890 1891/3991/1891 1886/2023/1886 1889/3990/1889 \nf 1892/1076/1892 1887/3992/1887 1886/2023/1886 1891/3991/1891 \nf 1893/307/1893 1894/3994/1894 1895/2024/1895 1896/3996/1896 \nf 1897/1075/1897 1898/3995/1898 1895/2024/1895 1894/3994/1894 \nf 1890/553/1890 1889/3990/1889 1895/2024/1895 1898/3995/1898 \nf 1888/1074/1888 1896/3996/1896 1895/2024/1895 1889/3990/1889 \nf 1860/301/1860 1883/3988/1883 1899/2025/1899 1900/3998/1900 \nf 1880/1073/1880 1901/3997/1901 1899/2025/1899 1883/3988/1883 \nf 1890/553/1890 1898/3995/1898 1899/2025/1899 1901/3997/1901 \nf 1897/1075/1897 1900/3998/1900 1899/2025/1899 1898/3995/1898 \nf 1876/304/1876 1902/3999/1902 1903/2026/1903 1877/3984/1877 \nf 1892/1076/1892 1891/3991/1891 1903/2026/1903 1902/3999/1902 \nf 1890/553/1890 1901/3997/1901 1903/2026/1903 1891/3991/1891 \nf 1880/1073/1880 1877/3984/1877 1903/2026/1903 1901/3997/1901 \nf 1893/307/1893 1904/4001/1904 1905/2027/1905 1894/3994/1894 \nf 1906/1078/1906 1907/4002/1907 1905/2027/1905 1904/4001/1904 \nf 1908/554/1908 1909/4003/1909 1905/2027/1905 1907/4002/1907 \nf 1897/1075/1897 1894/3994/1894 1905/2027/1905 1909/4003/1909 \nf 1770/288/1770 1773/3928/1773 1910/2028/1910 1911/4005/1911 \nf 1766/1055/1766 1912/4004/1912 1910/2028/1910 1773/3928/1773 \nf 1908/554/1908 1907/4002/1907 1910/2028/1910 1912/4004/1912 \nf 1906/1078/1906 1911/4005/1911 1910/2028/1910 1907/4002/1907 \nf 1753/287/1753 1867/3978/1867 1913/2029/1913 1764/3923/1764 \nf 1864/1070/1864 1914/4006/1914 1913/2029/1913 1867/3978/1867 \nf 1908/554/1908 1912/4004/1912 1913/2029/1913 1914/4006/1914 \nf 1766/1055/1766 1764/3923/1764 1913/2029/1913 1912/4004/1912 \nf 1860/301/1860 1900/3998/1900 1915/2030/1915 1861/3975/1861 \nf 1897/1075/1897 1909/4003/1909 1915/2030/1915 1900/3998/1900 \nf 1908/554/1908 1914/4006/1914 1915/2030/1915 1909/4003/1909 \nf 1864/1070/1864 1861/3975/1861 1915/2030/1915 1914/4006/1914 \nf 1618/271/1618 1747/3916/1747 1916/2031/1916 1619/3850/1619 \nf 1752/1054/1752 1917/4007/1917 1916/2031/1916 1747/3916/1747 \nf 1918/555/1918 1919/4008/1919 1916/2031/1916 1917/4007/1917 \nf 1622/1034/1622 1619/3850/1619 1916/2031/1916 1919/4008/1919 \nf 1737/286/1737 1920/4009/1920 1921/2032/1921 1762/3922/1762 \nf 1922/1079/1922 1923/4010/1923 1921/2032/1921 1920/4009/1920 \nf 1918/555/1918 1917/4007/1917 1921/2032/1921 1923/4010/1923 \nf 1752/1054/1752 1762/3922/1762 1921/2032/1921 1917/4007/1917 \nf 1924/308/1924 1925/4011/1925 1926/2033/1926 1927/4013/1927 \nf 1928/1080/1928 1929/4012/1929 1926/2033/1926 1925/4011/1925 \nf 1918/555/1918 1923/4010/1923 1926/2033/1926 1929/4012/1929 \nf 1922/1079/1922 1927/4013/1927 1926/2033/1926 1923/4010/1923 \nf 1568/266/1568 1625/3854/1625 1930/2034/1930 1931/4014/1931 \nf 1622/1034/1622 1919/4008/1919 1930/2034/1930 1625/3854/1625 \nf 1918/555/1918 1929/4012/1929 1930/2034/1930 1919/4008/1919 \nf 1928/1080/1928 1931/4014/1931 1930/2034/1930 1929/4012/1929 \nf 1737/286/1737 1740/3911/1740 1932/2035/1932 1920/4009/1920 \nf 1735/1050/1735 1933/4015/1933 1932/2035/1932 1740/3911/1740 \nf 1934/556/1934 1935/4016/1935 1932/2035/1932 1933/4015/1933 \nf 1922/1079/1922 1920/4009/1920 1932/2035/1932 1935/4016/1935 \nf 1731/284/1731 1936/4017/1936 1937/2036/1937 1732/3906/1732 \nf 1938/1081/1938 1939/4018/1939 1937/2036/1937 1936/4017/1936 \nf 1934/556/1934 1933/4015/1933 1937/2036/1937 1939/4018/1939 \nf 1735/1050/1735 1732/3906/1732 1937/2036/1937 1933/4015/1933 \nf 1940/309/1940 1941/4019/1941 1942/2037/1942 1943/4021/1943 \nf 1944/1082/1944 1945/4020/1945 1942/2037/1942 1941/4019/1941 \nf 1934/556/1934 1939/4018/1939 1942/2037/1942 1945/4020/1945 \nf 1938/1081/1938 1943/4021/1943 1942/2037/1942 1939/4018/1939 \nf 1924/308/1924 1927/4013/1927 1946/2038/1946 1947/4022/1947 \nf 1922/1079/1922 1935/4016/1935 1946/2038/1946 1927/4013/1927 \nf 1934/556/1934 1945/4020/1945 1946/2038/1946 1935/4016/1935 \nf 1944/1082/1944 1947/4022/1947 1946/2038/1946 1945/4020/1945 \nf 1780/289/1780 1783/3934/1783 1948/2039/1948 1949/4025/1949 \nf 1788/1061/1788 1950/4023/1950 1948/2039/1948 1783/3934/1783 \nf 1951/557/1951 1952/4024/1952 1948/2039/1948 1950/4023/1950 \nf 1953/1084/1953 1949/4025/1949 1948/2039/1948 1952/4024/1952 \nf 1801/296/1801 1954/4026/1954 1955/2040/1955 1802/3943/1802 \nf 1956/1083/1956 1957/4027/1957 1955/2040/1955 1954/4026/1954 \nf 1951/557/1951 1950/4023/1950 1955/2040/1955 1957/4027/1957 \nf 1788/1061/1788 1802/3943/1802 1955/2040/1955 1950/4023/1950 \nf 1924/308/1924 1947/4022/1947 1958/2041/1958 1959/4029/1959 \nf 1944/1082/1944 1960/4028/1960 1958/2041/1958 1947/4022/1947 \nf 1951/557/1951 1957/4027/1957 1958/2041/1958 1960/4028/1960 \nf 1956/1083/1956 1959/4029/1959 1958/2041/1958 1957/4027/1957 \nf 1940/309/1940 1961/4030/1961 1962/2042/1962 1941/4019/1941 \nf 1953/1084/1953 1952/4024/1952 1962/2042/1962 1961/4030/1961 \nf 1951/557/1951 1960/4028/1960 1962/2042/1962 1952/4024/1952 \nf 1944/1082/1944 1941/4019/1941 1962/2042/1962 1960/4028/1960 \nf 1801/296/1801 1849/3970/1849 1963/2043/1963 1954/4026/1954 \nf 1846/1068/1846 1964/4031/1964 1963/2043/1963 1849/3970/1849 \nf 1965/558/1965 1966/4032/1966 1963/2043/1963 1964/4031/1964 \nf 1956/1083/1956 1954/4026/1954 1963/2043/1963 1966/4032/1966 \nf 1547/218/1547 1550/3812/1550 1967/2044/1967 1844/3967/1844 \nf 1555/1023/1555 1968/4033/1968 1967/2044/1967 1550/3812/1550 \nf 1965/558/1965 1964/4031/1964 1967/2044/1967 1968/4033/1968 \nf 1846/1068/1846 1844/3967/1844 1967/2044/1967 1964/4031/1964 \nf 1568/266/1568 1931/4014/1931 1969/2045/1969 1569/3819/1569 \nf 1928/1080/1928 1970/4034/1970 1969/2045/1969 1931/4014/1931 \nf 1965/558/1965 1968/4033/1968 1969/2045/1969 1970/4034/1970 \nf 1555/1023/1555 1569/3819/1569 1969/2045/1969 1968/4033/1968 \nf 1924/308/1924 1959/4029/1959 1971/2046/1971 1925/4011/1925 \nf 1956/1083/1956 1966/4032/1966 1971/2046/1971 1959/4029/1959 \nf 1965/558/1965 1970/4034/1970 1971/2046/1971 1966/4032/1966 \nf 1928/1080/1928 1925/4011/1925 1971/2046/1971 1970/4034/1970 \nf 1972/84/1972 1973/4035/1973 1974/2047/1974 1975/4038/1975 \nf 1976/1085/1976 1977/4036/1977 1974/2047/1974 1973/4035/1973 \nf 1978/559/1978 1979/4037/1979 1974/2047/1974 1977/4036/1977 \nf 1980/1088/1980 1975/4038/1975 1974/2047/1974 1979/4037/1979 \nf 1981/150/1981 1982/4039/1982 1983/2048/1983 1984/4041/1984 \nf 1985/1086/1985 1986/4040/1986 1983/2048/1983 1982/4039/1982 \nf 1978/559/1978 1977/4036/1977 1983/2048/1983 1986/4040/1986 \nf 1976/1085/1976 1984/4041/1984 1983/2048/1983 1977/4036/1977 \nf 1987/151/1987 1988/4042/1988 1989/2049/1989 1990/4044/1990 \nf 1991/1087/1991 1992/4043/1992 1989/2049/1989 1988/4042/1988 \nf 1978/559/1978 1986/4040/1986 1989/2049/1989 1992/4043/1992 \nf 1985/1086/1985 1990/4044/1990 1989/2049/1989 1986/4040/1986 \nf 1993/157/1993 1994/4045/1994 1995/2050/1995 1996/4046/1996 \nf 1980/1088/1980 1979/4037/1979 1995/2050/1995 1994/4045/1994 \nf 1978/559/1978 1992/4043/1992 1995/2050/1995 1979/4037/1979 \nf 1991/1087/1991 1996/4046/1996 1995/2050/1995 1992/4043/1992 \nf 1981/150/1981 1997/4047/1997 1998/2051/1998 1982/4039/1982 \nf 1999/1089/1999 2000/4048/2000 1998/2051/1998 1997/4047/1997 \nf 2001/560/2001 2002/4049/2002 1998/2051/1998 2000/4048/2000 \nf 1985/1086/1985 1982/4039/1982 1998/2051/1998 2002/4049/2002 \nf 2003/158/2003 2004/4050/2004 2005/2052/2005 2006/4052/2006 \nf 2007/1090/2007 2008/4051/2008 2005/2052/2005 2004/4050/2004 \nf 2001/560/2001 2000/4048/2000 2005/2052/2005 2008/4051/2008 \nf 1999/1089/1999 2006/4052/2006 2005/2052/2005 2000/4048/2000 \nf 2009/169/2009 2010/4053/2010 2011/2053/2011 2012/4055/2012 \nf 2013/1091/2013 2014/4054/2014 2011/2053/2011 2010/4053/2010 \nf 2001/560/2001 2008/4051/2008 2011/2053/2011 2014/4054/2014 \nf 2007/1090/2007 2012/4055/2012 2011/2053/2011 2008/4051/2008 \nf 1987/151/1987 1990/4044/1990 2015/2054/2015 2016/4056/2016 \nf 1985/1086/1985 2002/4049/2002 2015/2054/2015 1990/4044/1990 \nf 2001/560/2001 2014/4054/2014 2015/2054/2015 2002/4049/2002 \nf 2013/1091/2013 2016/4056/2016 2015/2054/2015 2014/4054/2014 \nf 1811/64/1811 2017/4057/2017 2018/2055/2018 2019/4060/2019 \nf 2020/1092/2020 2021/4058/2021 2018/2055/2018 2017/4057/2017 \nf 2022/561/2022 2023/4059/2023 2018/2055/2018 2021/4058/2021 \nf 2024/1094/2024 2019/4060/2019 2018/2055/2018 2023/4059/2023 \nf 2025/170/2025 2026/4061/2026 2027/2056/2027 2028/4063/2028 \nf 2029/1093/2029 2030/4062/2030 2027/2056/2027 2026/4061/2026 \nf 2022/561/2022 2021/4058/2021 2027/2056/2027 2030/4062/2030 \nf 2020/1092/2020 2028/4063/2028 2027/2056/2027 2021/4058/2021 \nf 1987/151/1987 2016/4056/2016 2031/2057/2031 2032/4065/2032 \nf 2013/1091/2013 2033/4064/2033 2031/2057/2031 2016/4056/2016 \nf 2022/561/2022 2030/4062/2030 2031/2057/2031 2033/4064/2033 \nf 2029/1093/2029 2032/4065/2032 2031/2057/2031 2030/4062/2030 \nf 2009/169/2009 2034/4066/2034 2035/2058/2035 2010/4053/2010 \nf 2024/1094/2024 2023/4059/2023 2035/2058/2035 2034/4066/2034 \nf 2022/561/2022 2033/4064/2033 2035/2058/2035 2023/4059/2023 \nf 2013/1091/2013 2010/4053/2010 2035/2058/2035 2033/4064/2033 \nf 2025/170/2025 2036/4067/2036 2037/2059/2037 2026/4061/2026 \nf 2038/1095/2038 2039/4069/2039 2037/2059/2037 2036/4067/2036 \nf 2040/562/2040 2041/4070/2041 2037/2059/2037 2039/4069/2039 \nf 2029/1093/2029 2026/4061/2026 2037/2059/2037 2041/4070/2041 \nf 1537/172/1537 2042/4071/2042 2043/2060/2043 2044/4074/2044 \nf 2045/1097/2045 2046/4073/2046 2043/2060/2043 2042/4071/2042 \nf 2040/562/2040 2039/4069/2039 2043/2060/2043 2046/4073/2046 \nf 2038/1095/2038 2044/4074/2044 2043/2060/2043 2039/4069/2039 \nf 1993/157/1993 1996/4046/1996 2047/2061/2047 2048/4077/2048 \nf 1991/1087/1991 2049/4076/2049 2047/2061/2047 1996/4046/1996 \nf 2040/562/2040 2046/4073/2046 2047/2061/2047 2049/4076/2049 \nf 2045/1097/2045 2048/4077/2048 2047/2061/2047 2046/4073/2046 \nf 1987/151/1987 2032/4065/2032 2050/2062/2050 1988/4042/1988 \nf 2029/1093/2029 2041/4070/2041 2050/2062/2050 2032/4065/2032 \nf 2040/562/2040 2049/4076/2049 2050/2062/2050 2041/4070/2041 \nf 1991/1087/1991 1988/4042/1988 2050/2062/2050 2049/4076/2049 \nf 1770/288/1770 1911/4005/1911 2051/2063/2051 2052/4081/2052 \nf 1906/1078/1906 2053/4079/2053 2051/2063/2051 1911/4005/1911 \nf 2054/563/2054 2055/4080/2055 2051/2063/2051 2053/4079/2053 \nf 2056/1101/2056 2052/4081/2052 2051/2063/2051 2055/4080/2055 \nf 1893/307/1893 2057/4082/2057 2058/2064/2058 1904/4001/1904 \nf 2059/1099/2059 2060/4083/2060 2058/2064/2058 2057/4082/2057 \nf 2054/563/2054 2053/4079/2053 2058/2064/2058 2060/4083/2060 \nf 1906/1078/1906 1904/4001/1904 2058/2064/2058 2053/4079/2053 \nf 2061/311/2061 2062/4084/2062 2063/2065/2063 2064/4086/2064 \nf 2065/1100/2065 2066/4085/2066 2063/2065/2063 2062/4084/2062 \nf 2054/563/2054 2060/4083/2060 2063/2065/2063 2066/4085/2066 \nf 2059/1099/2059 2064/4086/2064 2063/2065/2063 2060/4083/2060 \nf 2067/312/2067 2068/4087/2068 2069/2066/2069 2070/4088/2070 \nf 2056/1101/2056 2055/4080/2055 2069/2066/2069 2068/4087/2068 \nf 2054/563/2054 2066/4085/2066 2069/2066/2069 2055/4080/2055 \nf 2065/1100/2065 2070/4088/2070 2069/2066/2069 2066/4085/2066 \nf 1893/307/1893 1896/3996/1896 2071/2067/2071 2057/4082/2057 \nf 1888/1074/1888 2072/4089/2072 2071/2067/2071 1896/3996/1896 \nf 2073/564/2073 2074/4090/2074 2071/2067/2071 2072/4089/2072 \nf 2059/1099/2059 2057/4082/2057 2071/2067/2071 2074/4090/2074 \nf 1884/306/1884 2075/4091/2075 2076/2068/2076 1885/3989/1885 \nf 2077/1102/2077 2078/4093/2078 2076/2068/2076 2075/4091/2075 \nf 2073/564/2073 2072/4089/2072 2076/2068/2076 2078/4093/2078 \nf 1888/1074/1888 1885/3989/1885 2076/2068/2076 2072/4089/2072 \nf 2079/313/2079 2080/4094/2080 2081/2069/2081 2082/4096/2082 \nf 2083/1104/2083 2084/4095/2084 2081/2069/2081 2080/4094/2080 \nf 2073/564/2073 2078/4093/2078 2081/2069/2081 2084/4095/2084 \nf 2077/1102/2077 2082/4096/2082 2081/2069/2081 2078/4093/2078 \nf 2061/311/2061 2064/4086/2064 2085/2070/2085 2086/4098/2086 \nf 2059/1099/2059 2074/4090/2074 2085/2070/2085 2064/4086/2064 \nf 2073/564/2073 2084/4095/2084 2085/2070/2085 2074/4090/2074 \nf 2083/1104/2083 2086/4098/2086 2085/2070/2085 2084/4095/2084 \nf 626/74/626 629/3329/629 2087/2071/2087 2088/4101/2088 \nf 634/897/634 2089/4099/2089 2087/2071/2087 629/3329/629 \nf 2090/565/2090 2091/4100/2091 2087/2071/2087 2089/4099/2089 \nf 2092/1106/2092 2088/4101/2088 2087/2071/2087 2091/4100/2091 \nf 618/72/618 2093/4103/2093 2094/2072/2094 644/3336/644 \nf 2095/1105/2095 2096/4104/2096 2094/2072/2094 2093/4103/2093 \nf 2090/565/2090 2089/4099/2089 2094/2072/2094 2096/4104/2096 \nf 634/897/634 644/3336/644 2094/2072/2094 2089/4099/2089 \nf 2061/311/2061 2086/4098/2086 2097/2073/2097 2098/4106/2098 \nf 2083/1104/2083 2099/4105/2099 2097/2073/2097 2086/4098/2086 \nf 2090/565/2090 2096/4104/2096 2097/2073/2097 2099/4105/2099 \nf 2095/1105/2095 2098/4106/2098 2097/2073/2097 2096/4104/2096 \nf 2079/313/2079 2100/4107/2100 2101/2074/2101 2080/4094/2080 \nf 2092/1106/2092 2091/4100/2091 2101/2074/2101 2100/4107/2100 \nf 2090/565/2090 2099/4105/2099 2101/2074/2101 2091/4100/2091 \nf 2083/1104/2083 2080/4094/2080 2101/2074/2101 2099/4105/2099 \nf 618/72/618 621/3323/621 2102/2075/2102 2093/4103/2093 \nf 616/892/616 2103/4109/2103 2102/2075/2102 621/3323/621 \nf 2104/566/2104 2105/4110/2105 2102/2075/2102 2103/4109/2103 \nf 2095/1105/2095 2093/4103/2093 2102/2075/2102 2105/4110/2105 \nf 612/70/612 2106/4111/2106 2107/2076/2107 613/3318/613 \nf 2108/1108/2108 2109/4112/2109 2107/2076/2107 2106/4111/2106 \nf 2104/566/2104 2103/4109/2103 2107/2076/2107 2109/4112/2109 \nf 616/892/616 613/3318/613 2107/2076/2107 2103/4109/2103 \nf 2067/312/2067 2070/4088/2070 2110/2077/2110 2111/4114/2111 \nf 2065/1100/2065 2112/4113/2112 2110/2077/2110 2070/4088/2070 \nf 2104/566/2104 2109/4112/2109 2110/2077/2110 2112/4113/2112 \nf 2108/1108/2108 2111/4114/2111 2110/2077/2110 2109/4112/2109 \nf 2061/311/2061 2098/4106/2098 2113/2078/2113 2062/4084/2062 \nf 2095/1105/2095 2105/4110/2105 2113/2078/2113 2098/4106/2098 \nf 2104/566/2104 2112/4113/2112 2113/2078/2113 2105/4110/2105 \nf 2065/1100/2065 2062/4084/2062 2113/2078/2113 2112/4113/2112 \nf 1497/208/1497 1629/3857/1629 2114/2079/2114 2115/4117/2115 \nf 1633/1037/1633 2116/4115/2116 2114/2079/2114 1629/3857/1629 \nf 2117/567/2117 2118/4116/2118 2114/2079/2114 2116/4115/2116 \nf 2119/1111/2119 2115/4117/2115 2114/2079/2114 2118/4116/2118 \nf 1644/273/1644 2120/4118/2120 2121/2080/2121 1645/3863/1645 \nf 2122/1109/2122 2123/4119/2123 2121/2080/2121 2120/4118/2120 \nf 2117/567/2117 2116/4115/2116 2121/2080/2121 2123/4119/2123 \nf 1633/1037/1633 1645/3863/1645 2121/2080/2121 2116/4115/2116 \nf 2124/314/2124 2125/4120/2125 2126/2081/2126 2127/4122/2127 \nf 2128/1110/2128 2129/4121/2129 2126/2081/2126 2125/4120/2125 \nf 2117/567/2117 2123/4119/2123 2126/2081/2126 2129/4121/2129 \nf 2122/1109/2122 2127/4122/2127 2126/2081/2126 2123/4119/2123 \nf 2130/315/2130 2131/4123/2131 2132/2082/2132 2133/4124/2133 \nf 2119/1111/2119 2118/4116/2118 2132/2082/2132 2131/4123/2131 \nf 2117/567/2117 2129/4121/2129 2132/2082/2132 2118/4116/2118 \nf 2128/1110/2128 2133/4124/2133 2132/2082/2132 2129/4121/2129 \nf 1644/273/1644 1697/3890/1697 2134/2083/2134 2120/4118/2120 \nf 1694/1044/1694 2135/4125/2135 2134/2083/2134 1697/3890/1697 \nf 2136/568/2136 2137/4126/2137 2134/2083/2134 2135/4125/2135 \nf 2122/1109/2122 2120/4118/2120 2134/2083/2134 2137/4126/2137 \nf 1690/277/1690 2138/4127/2138 2139/2084/2139 1691/3886/1691 \nf 2140/1112/2140 2141/4128/2141 2139/2084/2139 2138/4127/2138 \nf 2136/568/2136 2135/4125/2135 2139/2084/2139 2141/4128/2141 \nf 1694/1044/1694 1691/3886/1691 2139/2084/2139 2135/4125/2135 \nf 2142/316/2142 2143/4129/2143 2144/2085/2144 2145/4131/2145 \nf 2146/1113/2146 2147/4130/2147 2144/2085/2144 2143/4129/2143 \nf 2136/568/2136 2141/4128/2141 2144/2085/2144 2147/4130/2147 \nf 2140/1112/2140 2145/4131/2145 2144/2085/2144 2141/4128/2141 \nf 2124/314/2124 2127/4122/2127 2148/2086/2148 2149/4132/2149 \nf 2122/1109/2122 2137/4126/2137 2148/2086/2148 2127/4122/2127 \nf 2136/568/2136 2147/4130/2147 2148/2086/2148 2137/4126/2137 \nf 2146/1113/2146 2149/4132/2149 2148/2086/2148 2147/4130/2147 \nf 698/177/698 701/3368/701 2150/2087/2150 2151/4135/2151 \nf 706/908/706 2152/4133/2152 2150/2087/2150 701/3368/701 \nf 2153/569/2153 2154/4134/2154 2150/2087/2150 2152/4133/2152 \nf 2155/1115/2155 2151/4135/2151 2150/2087/2150 2154/4134/2154 \nf 690/88/690 2156/4136/2156 2157/2088/2157 716/3374/716 \nf 2158/1114/2158 2159/4137/2159 2157/2088/2157 2156/4136/2156 \nf 2153/569/2153 2152/4133/2152 2157/2088/2157 2159/4137/2159 \nf 706/908/706 716/3374/716 2157/2088/2157 2152/4133/2152 \nf 2124/314/2124 2149/4132/2149 2160/2089/2160 2161/4139/2161 \nf 2146/1113/2146 2162/4138/2162 2160/2089/2160 2149/4132/2149 \nf 2153/569/2153 2159/4137/2159 2160/2089/2160 2162/4138/2162 \nf 2158/1114/2158 2161/4139/2161 2160/2089/2160 2159/4137/2159 \nf 2142/316/2142 2163/4140/2163 2164/2090/2164 2143/4129/2143 \nf 2155/1115/2155 2154/4134/2154 2164/2090/2164 2163/4140/2163 \nf 2153/569/2153 2162/4138/2162 2164/2090/2164 2154/4134/2154 \nf 2146/1113/2146 2143/4129/2143 2164/2090/2164 2162/4138/2162 \nf 690/88/690 693/3363/693 2165/2091/2165 2156/4136/2156 \nf 688/904/688 2166/4141/2166 2165/2091/2165 693/3363/693 \nf 2167/570/2167 2168/4142/2168 2165/2091/2165 2166/4141/2166 \nf 2158/1114/2158 2156/4136/2156 2165/2091/2165 2168/4142/2168 \nf 684/86/684 2169/4143/2169 2170/2092/2170 685/3358/685 \nf 2171/1116/2171 2172/4144/2172 2170/2092/2170 2169/4143/2169 \nf 2167/570/2167 2166/4141/2166 2170/2092/2170 2172/4144/2172 \nf 688/904/688 685/3358/685 2170/2092/2170 2166/4141/2166 \nf 2130/315/2130 2133/4124/2133 2173/2093/2173 2174/4146/2174 \nf 2128/1110/2128 2175/4145/2175 2173/2093/2173 2133/4124/2133 \nf 2167/570/2167 2172/4144/2172 2173/2093/2173 2175/4145/2175 \nf 2171/1116/2171 2174/4146/2174 2173/2093/2173 2172/4144/2172 \nf 2124/314/2124 2161/4139/2161 2176/2094/2176 2125/4120/2125 \nf 2158/1114/2158 2168/4142/2168 2176/2094/2176 2161/4139/2161 \nf 2167/570/2167 2175/4145/2175 2176/2094/2176 2168/4142/2168 \nf 2128/1110/2128 2125/4120/2125 2176/2094/2176 2175/4145/2175 \nf 1700/278/1700 1703/3894/1703 2177/2095/2177 2178/4149/2178 \nf 1708/1048/1708 2179/4147/2179 2177/2095/2177 1703/3894/1703 \nf 2180/571/2180 2181/4148/2181 2177/2095/2177 2179/4147/2179 \nf 2182/1119/2182 2178/4149/2178 2177/2095/2177 2181/4148/2181 \nf 1721/283/1721 2183/4150/2183 2184/2096/2184 1722/3901/1722 \nf 2185/1117/2185 2186/4151/2186 2184/2096/2184 2183/4150/2183 \nf 2180/571/2180 2179/4147/2179 2184/2096/2184 2186/4151/2186 \nf 1708/1048/1708 1722/3901/1722 2184/2096/2184 2179/4147/2179 \nf 2187/317/2187 2188/4152/2188 2189/2097/2189 2190/4154/2190 \nf 2191/1118/2191 2192/4153/2192 2189/2097/2189 2188/4152/2188 \nf 2180/571/2180 2186/4151/2186 2189/2097/2189 2192/4153/2192 \nf 2185/1117/2185 2190/4154/2190 2189/2097/2189 2186/4151/2186 \nf 2193/318/2193 2194/4155/2194 2195/2098/2195 2196/4156/2196 \nf 2182/1119/2182 2181/4148/2181 2195/2098/2195 2194/4155/2194 \nf 2180/571/2180 2192/4153/2192 2195/2098/2195 2181/4148/2181 \nf 2191/1118/2191 2196/4156/2196 2195/2098/2195 2192/4153/2192 \nf 1721/283/1721 1777/3930/1777 2197/2099/2197 2183/4150/2183 \nf 1774/1056/1774 2198/4157/2198 2197/2099/2197 1777/3930/1777 \nf 2199/572/2199 2200/4158/2200 2197/2099/2197 2198/4157/2198 \nf 2185/1117/2185 2183/4150/2183 2197/2099/2197 2200/4158/2200 \nf 1770/288/1770 2052/4081/2052 2201/2100/2201 1771/3926/1771 \nf 2056/1101/2056 2202/4159/2202 2201/2100/2201 2052/4081/2052 \nf 2199/572/2199 2198/4157/2198 2201/2100/2201 2202/4159/2202 \nf 1774/1056/1774 1771/3926/1771 2201/2100/2201 2198/4157/2198 \nf 2067/312/2067 2203/4160/2203 2204/2101/2204 2068/4087/2068 \nf 2205/1120/2205 2206/4161/2206 2204/2101/2204 2203/4160/2203 \nf 2199/572/2199 2202/4159/2202 2204/2101/2204 2206/4161/2206 \nf 2056/1101/2056 2068/4087/2068 2204/2101/2204 2202/4159/2202 \nf 2187/317/2187 2190/4154/2190 2207/2102/2207 2208/4162/2208 \nf 2185/1117/2185 2200/4158/2200 2207/2102/2207 2190/4154/2190 \nf 2199/572/2199 2206/4161/2206 2207/2102/2207 2200/4158/2200 \nf 2205/1120/2205 2208/4162/2208 2207/2102/2207 2206/4161/2206 \nf 612/70/612 771/3403/771 2209/2103/2209 2106/4111/2106 \nf 775/917/775 2210/4163/2210 2209/2103/2209 771/3403/771 \nf 2211/573/2211 2212/4164/2212 2209/2103/2209 2210/4163/2210 \nf 2108/1108/2108 2106/4111/2106 2209/2103/2209 2212/4164/2212 \nf 762/182/762 2213/4165/2213 2214/2104/2214 783/3408/783 \nf 2215/1121/2215 2216/4166/2216 2214/2104/2214 2213/4165/2213 \nf 2211/573/2211 2210/4163/2210 2214/2104/2214 2216/4166/2216 \nf 775/917/775 783/3408/783 2214/2104/2214 2210/4163/2210 \nf 2187/317/2187 2208/4162/2208 2217/2105/2217 2218/4168/2218 \nf 2205/1120/2205 2219/4167/2219 2217/2105/2217 2208/4162/2208 \nf 2211/573/2211 2216/4166/2216 2217/2105/2217 2219/4167/2219 \nf 2215/1121/2215 2218/4168/2218 2217/2105/2217 2216/4166/2216 \nf 2067/312/2067 2111/4114/2111 2220/2106/2220 2203/4160/2203 \nf 2108/1108/2108 2212/4164/2212 2220/2106/2220 2111/4114/2111 \nf 2211/573/2211 2219/4167/2219 2220/2106/2220 2212/4164/2212 \nf 2205/1120/2205 2203/4160/2203 2220/2106/2220 2219/4167/2219 \nf 762/182/762 765/3399/765 2221/2107/2221 2213/4165/2213 \nf 760/914/760 2222/4169/2222 2221/2107/2221 765/3399/765 \nf 2223/574/2223 2224/4170/2224 2221/2107/2221 2222/4169/2222 \nf 2215/1121/2215 2213/4165/2213 2221/2107/2221 2224/4170/2224 \nf 756/181/756 2225/4171/2225 2226/2108/2226 757/3394/757 \nf 2227/1122/2227 2228/4172/2228 2226/2108/2226 2225/4171/2225 \nf 2223/574/2223 2222/4169/2222 2226/2108/2226 2228/4172/2228 \nf 760/914/760 757/3394/757 2226/2108/2226 2222/4169/2222 \nf 2193/318/2193 2196/4156/2196 2229/2109/2229 2230/4174/2230 \nf 2191/1118/2191 2231/4173/2231 2229/2109/2229 2196/4156/2196 \nf 2223/574/2223 2228/4172/2228 2229/2109/2229 2231/4173/2231 \nf 2227/1122/2227 2230/4174/2230 2229/2109/2229 2228/4172/2228 \nf 2187/317/2187 2218/4168/2218 2232/2110/2232 2188/4152/2188 \nf 2215/1121/2215 2224/4170/2224 2232/2110/2232 2218/4168/2218 \nf 2223/574/2223 2231/4173/2231 2232/2110/2232 2224/4170/2224 \nf 2191/1118/2191 2188/4152/2188 2232/2110/2232 2231/4173/2231 \nf 2233/124/2233 2234/4175/2234 2235/2111/2235 2236/4178/2236 \nf 2237/1123/2237 2238/4176/2238 2235/2111/2235 2234/4175/2234 \nf 2239/575/2239 2240/4177/2240 2235/2111/2235 2238/4176/2238 \nf 2241/1126/2241 2236/4178/2236 2235/2111/2235 2240/4177/2240 \nf 2242/135/2242 2243/4179/2243 2244/2112/2244 2245/4181/2245 \nf 2246/1124/2246 2247/4180/2247 2244/2112/2244 2243/4179/2243 \nf 2239/575/2239 2238/4176/2238 2244/2112/2244 2247/4180/2247 \nf 2237/1123/2237 2245/4181/2245 2244/2112/2244 2238/4176/2238 \nf 2248/136/2248 2249/4182/2249 2250/2113/2250 2251/4184/2251 \nf 2252/1125/2252 2253/4183/2253 2250/2113/2250 2249/4182/2249 \nf 2239/575/2239 2247/4180/2247 2250/2113/2250 2253/4183/2253 \nf 2246/1124/2246 2251/4184/2251 2250/2113/2250 2247/4180/2247 \nf 2254/166/2254 2255/4185/2255 2256/2114/2256 2257/4186/2257 \nf 2241/1126/2241 2240/4177/2240 2256/2114/2256 2255/4185/2255 \nf 2239/575/2239 2253/4183/2253 2256/2114/2256 2240/4177/2240 \nf 2252/1125/2252 2257/4186/2257 2256/2114/2256 2253/4183/2253 \nf 2242/135/2242 2258/4187/2258 2259/2115/2259 2243/4179/2243 \nf 2260/1127/2260 2261/4188/2261 2259/2115/2259 2258/4187/2258 \nf 2262/576/2262 2263/4189/2263 2259/2115/2259 2261/4188/2261 \nf 2246/1124/2246 2243/4179/2243 2259/2115/2259 2263/4189/2263 \nf 1511/167/1511 2264/4190/2264 2265/2116/2265 2266/4193/2266 \nf 2267/1128/2267 2268/4192/2268 2265/2116/2265 2264/4190/2264 \nf 2262/576/2262 2261/4188/2261 2265/2116/2265 2268/4192/2268 \nf 2260/1127/2260 2266/4193/2266 2265/2116/2265 2261/4188/2261 \nf 2269/168/2269 2270/4194/2270 2271/2117/2271 2272/4196/2272 \nf 2273/1130/2273 2274/4195/2274 2271/2117/2271 2270/4194/2270 \nf 2262/576/2262 2268/4192/2268 2271/2117/2271 2274/4195/2274 \nf 2267/1128/2267 2272/4196/2272 2271/2117/2271 2268/4192/2268 \nf 2248/136/2248 2251/4184/2251 2275/2118/2275 2276/4198/2276 \nf 2246/1124/2246 2263/4189/2263 2275/2118/2275 2251/4184/2251 \nf 2262/576/2262 2274/4195/2274 2275/2118/2275 2263/4189/2263 \nf 2273/1130/2273 2276/4198/2276 2275/2118/2275 2274/4195/2274 \nf 839/47/839 842/3439/842 2277/2119/2277 2278/4201/2278 \nf 847/928/847 2279/4199/2279 2277/2119/2277 842/3439/842 \nf 2280/577/2280 2281/4200/2281 2277/2119/2277 2279/4199/2279 \nf 2282/1132/2282 2278/4201/2278 2277/2119/2277 2281/4200/2281 \nf 831/46/831 2283/4203/2283 2284/2120/2284 857/3446/857 \nf 2285/1131/2285 2286/4204/2286 2284/2120/2284 2283/4203/2283 \nf 2280/577/2280 2279/4199/2279 2284/2120/2284 2286/4204/2286 \nf 847/928/847 857/3446/857 2284/2120/2284 2279/4199/2279 \nf 2248/136/2248 2276/4198/2276 2287/2121/2287 2288/4206/2288 \nf 2273/1130/2273 2289/4205/2289 2287/2121/2287 2276/4198/2276 \nf 2280/577/2280 2286/4204/2286 2287/2121/2287 2289/4205/2289 \nf 2285/1131/2285 2288/4206/2288 2287/2121/2287 2286/4204/2286 \nf 2269/168/2269 2290/4207/2290 2291/2122/2291 2270/4194/2270 \nf 2282/1132/2282 2281/4200/2281 2291/2122/2291 2290/4207/2290 \nf 2280/577/2280 2289/4205/2289 2291/2122/2291 2281/4200/2281 \nf 2273/1130/2273 2270/4194/2270 2291/2122/2291 2289/4205/2289 \nf 831/46/831 834/3433/834 2292/2123/2292 2283/4203/2283 \nf 829/923/829 2293/4209/2293 2292/2123/2292 834/3433/834 \nf 2294/578/2294 2295/4210/2295 2292/2123/2292 2293/4209/2293 \nf 2285/1131/2285 2283/4203/2283 2292/2123/2292 2295/4210/2295 \nf 825/44/825 2296/4211/2296 2297/2124/2297 826/3428/826 \nf 2298/1134/2298 2299/4212/2299 2297/2124/2297 2296/4211/2296 \nf 2294/578/2294 2293/4209/2293 2297/2124/2297 2299/4212/2299 \nf 829/923/829 826/3428/826 2297/2124/2297 2293/4209/2293 \nf 2254/166/2254 2257/4186/2257 2300/2125/2300 2301/4214/2301 \nf 2252/1125/2252 2302/4213/2302 2300/2125/2300 2257/4186/2257 \nf 2294/578/2294 2299/4212/2299 2300/2125/2300 2302/4213/2302 \nf 2298/1134/2298 2301/4214/2301 2300/2125/2300 2299/4212/2299 \nf 2248/136/2248 2288/4206/2288 2303/2126/2303 2249/4182/2249 \nf 2285/1131/2285 2295/4210/2295 2303/2126/2303 2288/4206/2288 \nf 2294/578/2294 2302/4213/2302 2303/2126/2303 2295/4210/2295 \nf 2252/1125/2252 2249/4182/2249 2303/2126/2303 2302/4213/2302 \nf 698/177/698 2151/4135/2151 2304/2127/2304 874/3457/874 \nf 2155/1115/2155 2305/4215/2305 2304/2127/2304 2151/4135/2151 \nf 2306/579/2306 2307/4216/2307 2304/2127/2304 2305/4215/2305 \nf 876/932/876 874/3457/874 2304/2127/2304 2307/4216/2307 \nf 2142/316/2142 2308/4217/2308 2309/2128/2309 2163/4140/2163 \nf 2310/1135/2310 2311/4218/2311 2309/2128/2309 2308/4217/2308 \nf 2306/579/2306 2305/4215/2305 2309/2128/2309 2311/4218/2311 \nf 2155/1115/2155 2163/4140/2163 2309/2128/2309 2305/4215/2305 \nf 2312/319/2312 2313/4219/2313 2314/2129/2314 2315/4221/2315 \nf 2316/1136/2316 2317/4220/2317 2314/2129/2314 2313/4219/2313 \nf 2306/579/2306 2311/4218/2311 2314/2129/2314 2317/4220/2317 \nf 2310/1135/2310 2315/4221/2315 2314/2129/2314 2311/4218/2311 \nf 880/183/880 883/3462/883 2318/2130/2318 2319/4222/2319 \nf 876/932/876 2307/4216/2307 2318/2130/2318 883/3462/883 \nf 2306/579/2306 2317/4220/2317 2318/2130/2318 2307/4216/2307 \nf 2316/1136/2316 2319/4222/2319 2318/2130/2318 2317/4220/2317 \nf 2142/316/2142 2145/4131/2145 2320/2131/2320 2308/4217/2308 \nf 2140/1112/2140 2321/4223/2321 2320/2131/2320 2145/4131/2145 \nf 2322/580/2322 2323/4224/2323 2320/2131/2320 2321/4223/2321 \nf 2310/1135/2310 2308/4217/2308 2320/2131/2320 2323/4224/2323 \nf 1690/277/1690 2324/4225/2324 2325/2132/2325 2138/4127/2138 \nf 2326/1137/2326 2327/4226/2327 2325/2132/2325 2324/4225/2324 \nf 2322/580/2322 2321/4223/2321 2325/2132/2325 2327/4226/2327 \nf 2140/1112/2140 2138/4127/2138 2325/2132/2325 2321/4223/2321 \nf 2328/321/2328 2329/4227/2329 2330/2133/2330 2331/4229/2331 \nf 2332/1138/2332 2333/4228/2333 2330/2133/2330 2329/4227/2329 \nf 2322/580/2322 2327/4226/2327 2330/2133/2330 2333/4228/2333 \nf 2326/1137/2326 2331/4229/2331 2330/2133/2330 2327/4226/2327 \nf 2312/319/2312 2315/4221/2315 2334/2134/2334 2335/4230/2335 \nf 2310/1135/2310 2323/4224/2323 2334/2134/2334 2315/4221/2315 \nf 2322/580/2322 2333/4228/2333 2334/2134/2334 2323/4224/2323 \nf 2332/1138/2332 2335/4230/2335 2334/2134/2334 2333/4228/2333 \nf 1700/278/1700 2178/4149/2178 2336/2135/2336 2337/4233/2337 \nf 2182/1119/2182 2338/4231/2338 2336/2135/2336 2178/4149/2178 \nf 2339/581/2339 2340/4232/2340 2336/2135/2336 2338/4231/2338 \nf 2341/1140/2341 2337/4233/2337 2336/2135/2336 2340/4232/2340 \nf 2193/318/2193 2342/4234/2342 2343/2136/2343 2194/4155/2194 \nf 2344/1139/2344 2345/4235/2345 2343/2136/2343 2342/4234/2342 \nf 2339/581/2339 2338/4231/2338 2343/2136/2343 2345/4235/2345 \nf 2182/1119/2182 2194/4155/2194 2343/2136/2343 2338/4231/2338 \nf 2312/319/2312 2335/4230/2335 2346/2137/2346 2347/4237/2347 \nf 2332/1138/2332 2348/4236/2348 2346/2137/2346 2335/4230/2335 \nf 2339/581/2339 2345/4235/2345 2346/2137/2346 2348/4236/2348 \nf 2344/1139/2344 2347/4237/2347 2346/2137/2346 2345/4235/2345 \nf 2328/321/2328 2349/4238/2349 2350/2138/2350 2329/4227/2329 \nf 2341/1140/2341 2340/4232/2340 2350/2138/2350 2349/4238/2349 \nf 2339/581/2339 2348/4236/2348 2350/2138/2350 2340/4232/2340 \nf 2332/1138/2332 2329/4227/2329 2350/2138/2350 2348/4236/2348 \nf 2193/318/2193 2230/4174/2230 2351/2139/2351 2342/4234/2342 \nf 2227/1122/2227 2352/4239/2352 2351/2139/2351 2230/4174/2230 \nf 2353/582/2353 2354/4240/2354 2351/2139/2351 2352/4239/2352 \nf 2344/1139/2344 2342/4234/2342 2351/2139/2351 2354/4240/2354 \nf 756/181/756 901/3471/901 2355/2140/2355 2225/4171/2225 \nf 896/935/896 2356/4241/2356 2355/2140/2355 901/3471/901 \nf 2353/582/2353 2352/4239/2352 2355/2140/2355 2356/4241/2356 \nf 2227/1122/2227 2225/4171/2225 2355/2140/2355 2352/4239/2352 \nf 880/183/880 2319/4222/2319 2357/2141/2357 894/3467/894 \nf 2316/1136/2316 2358/4242/2358 2357/2141/2357 2319/4222/2319 \nf 2353/582/2353 2356/4241/2356 2357/2141/2357 2358/4242/2358 \nf 896/935/896 894/3467/894 2357/2141/2357 2356/4241/2356 \nf 2312/319/2312 2347/4237/2347 2359/2142/2359 2313/4219/2313 \nf 2344/1139/2344 2354/4240/2354 2359/2142/2359 2347/4237/2347 \nf 2353/582/2353 2358/4242/2358 2359/2142/2359 2354/4240/2354 \nf 2316/1136/2316 2313/4219/2313 2359/2142/2359 2358/4242/2358 \nf 1690/277/1690 1693/3888/1693 2360/2143/2360 2324/4225/2324 \nf 1686/1043/1686 2361/4243/2361 2360/2143/2360 1693/3888/1693 \nf 2362/583/2362 2363/4244/2363 2360/2143/2360 2361/4243/2361 \nf 2326/1137/2326 2324/4225/2324 2360/2143/2360 2363/4244/2363 \nf 1673/276/1673 2364/4245/2364 2365/2144/2365 1684/3883/1684 \nf 2366/1141/2366 2367/4246/2367 2365/2144/2365 2364/4245/2364 \nf 2362/583/2362 2361/4243/2361 2365/2144/2365 2367/4246/2367 \nf 1686/1043/1686 1684/3883/1684 2365/2144/2365 2361/4243/2361 \nf 2368/322/2368 2369/4247/2369 2370/2145/2370 2371/4249/2371 \nf 2372/1142/2372 2373/4248/2373 2370/2145/2370 2369/4247/2369 \nf 2362/583/2362 2367/4246/2367 2370/2145/2370 2373/4248/2373 \nf 2366/1141/2366 2371/4249/2371 2370/2145/2370 2367/4246/2367 \nf 2328/321/2328 2331/4229/2331 2374/2146/2374 2375/4250/2375 \nf 2326/1137/2326 2363/4244/2363 2374/2146/2374 2331/4229/2331 \nf 2362/583/2362 2373/4248/2373 2374/2146/2374 2363/4244/2363 \nf 2372/1142/2372 2375/4250/2375 2374/2146/2374 2373/4248/2373 \nf 1673/276/1673 1676/3879/1676 2376/2147/2376 2364/4245/2364 \nf 1668/1040/1668 2377/4251/2377 2376/2147/2376 1676/3879/1676 \nf 2378/584/2378 2379/4252/2379 2376/2147/2376 2377/4251/2377 \nf 2366/1141/2366 2364/4245/2364 2376/2147/2376 2379/4252/2379 \nf 1664/275/1664 2380/4253/2380 2381/2148/2381 1665/3873/1665 \nf 2382/1143/2382 2383/4254/2383 2381/2148/2381 2380/4253/2380 \nf 2378/584/2378 2377/4251/2377 2381/2148/2381 2383/4254/2383 \nf 1668/1040/1668 1665/3873/1665 2381/2148/2381 2377/4251/2377 \nf 2384/324/2384 2385/4255/2385 2386/2149/2386 2387/4257/2387 \nf 2388/1144/2388 2389/4256/2389 2386/2149/2386 2385/4255/2385 \nf 2378/584/2378 2383/4254/2383 2386/2149/2386 2389/4256/2389 \nf 2382/1143/2382 2387/4257/2387 2386/2149/2386 2383/4254/2383 \nf 2368/322/2368 2371/4249/2371 2390/2150/2390 2391/4258/2391 \nf 2366/1141/2366 2379/4252/2379 2390/2150/2390 2371/4249/2371 \nf 2378/584/2378 2389/4256/2389 2390/2150/2390 2379/4252/2379 \nf 2388/1144/2388 2391/4258/2391 2390/2150/2390 2389/4256/2389 \nf 1731/284/1731 1734/3908/1734 2392/2151/2392 2393/4261/2393 \nf 1727/1049/1727 2394/4259/2394 2392/2151/2392 1734/3908/1734 \nf 2395/585/2395 2396/4260/2396 2392/2151/2392 2394/4259/2394 \nf 2397/1146/2397 2393/4261/2393 2392/2151/2392 2396/4260/2396 \nf 1709/281/1709 2398/4262/2398 2399/2152/2399 1725/3903/1725 \nf 2400/1145/2400 2401/4263/2401 2399/2152/2399 2398/4262/2398 \nf 2395/585/2395 2394/4259/2394 2399/2152/2399 2401/4263/2401 \nf 1727/1049/1727 1725/3903/1725 2399/2152/2399 2394/4259/2394 \nf 2368/322/2368 2391/4258/2391 2402/2153/2402 2403/4265/2403 \nf 2388/1144/2388 2404/4264/2404 2402/2153/2402 2391/4258/2391 \nf 2395/585/2395 2401/4263/2401 2402/2153/2402 2404/4264/2404 \nf 2400/1145/2400 2403/4265/2403 2402/2153/2402 2401/4263/2401 \nf 2384/324/2384 2405/4266/2405 2406/2154/2406 2385/4255/2385 \nf 2397/1146/2397 2396/4260/2396 2406/2154/2406 2405/4266/2405 \nf 2395/585/2395 2404/4264/2404 2406/2154/2406 2396/4260/2396 \nf 2388/1144/2388 2385/4255/2385 2406/2154/2406 2404/4264/2404 \nf 1709/281/1709 1712/3897/1712 2407/2155/2407 2398/4262/2398 \nf 1704/1045/1704 2408/4267/2408 2407/2155/2407 1712/3897/1712 \nf 2409/586/2409 2410/4268/2410 2407/2155/2407 2408/4267/2408 \nf 2400/1145/2400 2398/4262/2398 2407/2155/2407 2410/4268/2410 \nf 1700/278/1700 2337/4233/2337 2411/2156/2411 1701/3891/1701 \nf 2341/1140/2341 2412/4269/2412 2411/2156/2411 2337/4233/2337 \nf 2409/586/2409 2408/4267/2408 2411/2156/2411 2412/4269/2412 \nf 1704/1045/1704 1701/3891/1701 2411/2156/2411 2408/4267/2408 \nf 2328/321/2328 2375/4250/2375 2413/2157/2413 2349/4238/2349 \nf 2372/1142/2372 2414/4270/2414 2413/2157/2413 2375/4250/2375 \nf 2409/586/2409 2412/4269/2412 2413/2157/2413 2414/4270/2414 \nf 2341/1140/2341 2349/4238/2349 2413/2157/2413 2412/4269/2412 \nf 2368/322/2368 2403/4265/2403 2415/2158/2415 2369/4247/2369 \nf 2400/1145/2400 2410/4268/2410 2415/2158/2415 2403/4265/2403 \nf 2409/586/2409 2414/4270/2414 2415/2158/2415 2410/4268/2410 \nf 2372/1142/2372 2369/4247/2369 2415/2158/2415 2414/4270/2414 \nf 1664/275/1664 1667/3876/1667 2416/2159/2416 2380/4253/2380 \nf 1672/1042/1672 2417/4271/2417 2416/2159/2416 1667/3876/1667 \nf 2418/587/2418 2419/4272/2419 2416/2159/2416 2417/4271/2417 \nf 2382/1143/2382 2380/4253/2380 2416/2159/2416 2419/4272/2419 \nf 1656/274/1656 2420/4273/2420 2421/2160/2421 1682/3882/1682 \nf 2422/1147/2422 2423/4274/2423 2421/2160/2421 2420/4273/2420 \nf 2418/587/2418 2417/4271/2417 2421/2160/2421 2423/4274/2423 \nf 1672/1042/1672 1682/3882/1682 2421/2160/2421 2417/4271/2417 \nf 2424/326/2424 2425/4275/2425 2426/2161/2426 2427/4277/2427 \nf 2428/1148/2428 2429/4276/2429 2426/2161/2426 2425/4275/2425 \nf 2418/587/2418 2423/4274/2423 2426/2161/2426 2429/4276/2429 \nf 2422/1147/2422 2427/4277/2427 2426/2161/2426 2423/4274/2423 \nf 2384/324/2384 2387/4257/2387 2430/2162/2430 2431/4278/2431 \nf 2382/1143/2382 2419/4272/2419 2430/2162/2430 2387/4257/2387 \nf 2418/587/2418 2429/4276/2429 2430/2162/2430 2419/4272/2419 \nf 2428/1148/2428 2431/4278/2431 2430/2162/2430 2429/4276/2429 \nf 1656/274/1656 1659/3871/1659 2432/2163/2432 2420/4273/2420 \nf 1654/1038/1654 2433/4279/2433 2432/2163/2432 1659/3871/1659 \nf 2434/588/2434 2435/4280/2435 2432/2163/2432 2433/4279/2433 \nf 2422/1147/2422 2420/4273/2420 2432/2163/2432 2435/4280/2435 \nf 1466/203/1466 2436/4281/2436 2437/2164/2437 1652/3867/1652 \nf 2438/1149/2438 2439/4282/2439 2437/2164/2437 2436/4281/2436 \nf 2434/588/2434 2433/4279/2433 2437/2164/2437 2439/4282/2439 \nf 1654/1038/1654 1652/3867/1652 2437/2164/2437 2433/4279/2433 \nf 2440/328/2440 2441/4283/2441 2442/2165/2442 2443/4285/2443 \nf 2444/1150/2444 2445/4284/2445 2442/2165/2442 2441/4283/2441 \nf 2434/588/2434 2439/4282/2439 2442/2165/2442 2445/4284/2445 \nf 2438/1149/2438 2443/4285/2443 2442/2165/2442 2439/4282/2439 \nf 2424/326/2424 2427/4277/2427 2446/2166/2446 2447/4286/2447 \nf 2422/1147/2422 2435/4280/2435 2446/2166/2446 2427/4277/2427 \nf 2434/588/2434 2445/4284/2445 2446/2166/2446 2435/4280/2435 \nf 2444/1150/2444 2447/4286/2447 2446/2166/2446 2445/4284/2445 \nf 1780/289/1780 1949/4025/1949 2448/2167/2448 2449/4289/2449 \nf 1953/1084/1953 2450/4287/2450 2448/2167/2448 1949/4025/1949 \nf 2451/589/2451 2452/4288/2452 2448/2167/2448 2450/4287/2450 \nf 2453/1152/2453 2449/4289/2449 2448/2167/2448 2452/4288/2452 \nf 1940/309/1940 2454/4290/2454 2455/2168/2455 1961/4030/1961 \nf 2456/1151/2456 2457/4291/2457 2455/2168/2455 2454/4290/2454 \nf 2451/589/2451 2450/4287/2450 2455/2168/2455 2457/4291/2457 \nf 1953/1084/1953 1961/4030/1961 2455/2168/2455 2450/4287/2450 \nf 2424/326/2424 2447/4286/2447 2458/2169/2458 2459/4293/2459 \nf 2444/1150/2444 2460/4292/2460 2458/2169/2458 2447/4286/2447 \nf 2451/589/2451 2457/4291/2457 2458/2169/2458 2460/4292/2460 \nf 2456/1151/2456 2459/4293/2459 2458/2169/2458 2457/4291/2457 \nf 2440/328/2440 2461/4294/2461 2462/2170/2462 2441/4283/2441 \nf 2453/1152/2453 2452/4288/2452 2462/2170/2462 2461/4294/2461 \nf 2451/589/2451 2460/4292/2460 2462/2170/2462 2452/4288/2452 \nf 2444/1150/2444 2441/4283/2441 2462/2170/2462 2460/4292/2460 \nf 1940/309/1940 1943/4021/1943 2463/2171/2463 2454/4290/2454 \nf 1938/1081/1938 2464/4295/2464 2463/2171/2463 1943/4021/1943 \nf 2465/590/2465 2466/4296/2466 2463/2171/2463 2464/4295/2464 \nf 2456/1151/2456 2454/4290/2454 2463/2171/2463 2466/4296/2466 \nf 1731/284/1731 2393/4261/2393 2467/2172/2467 1936/4017/1936 \nf 2397/1146/2397 2468/4297/2468 2467/2172/2467 2393/4261/2393 \nf 2465/590/2465 2464/4295/2464 2467/2172/2467 2468/4297/2468 \nf 1938/1081/1938 1936/4017/1936 2467/2172/2467 2464/4295/2464 \nf 2384/324/2384 2431/4278/2431 2469/2173/2469 2405/4266/2405 \nf 2428/1148/2428 2470/4298/2470 2469/2173/2469 2431/4278/2431 \nf 2465/590/2465 2468/4297/2468 2469/2173/2469 2470/4298/2470 \nf 2397/1146/2397 2405/4266/2405 2469/2173/2469 2468/4297/2468 \nf 2424/326/2424 2459/4293/2459 2471/2174/2471 2425/4275/2425 \nf 2456/1151/2456 2466/4296/2466 2471/2174/2471 2459/4293/2459 \nf 2465/590/2465 2470/4298/2470 2471/2174/2471 2466/4296/2466 \nf 2428/1148/2428 2425/4275/2425 2471/2174/2471 2470/4298/2470 \nf 1537/188/1537 1540/3806/1540 2472/2175/2472 2042/4072/2042 \nf 1533/1018/1533 2473/4299/2473 2472/2175/2472 1540/3806/1540 \nf 2474/591/2474 2475/4300/2475 2472/2175/2472 2473/4299/2473 \nf 2045/1098/2045 2042/4072/2042 2472/2175/2472 2475/4300/2475 \nf 1520/192/1520 2476/4301/2476 2477/2176/2477 1531/3800/1531 \nf 2478/1153/2478 2479/4302/2479 2477/2176/2477 2476/4301/2476 \nf 2474/591/2474 2473/4299/2473 2477/2176/2477 2479/4302/2479 \nf 1533/1018/1533 1531/3800/1531 2477/2176/2477 2473/4299/2473 \nf 2480/210/2480 2481/4303/2481 2482/2177/2482 2483/4306/2483 \nf 2484/1154/2484 2485/4305/2485 2482/2177/2482 2481/4303/2481 \nf 2474/591/2474 2479/4302/2479 2482/2177/2482 2485/4305/2485 \nf 2478/1153/2478 2483/4306/2483 2482/2177/2482 2479/4302/2479 \nf 1993/214/1993 2048/4078/2048 2486/2178/2486 2487/4307/2487 \nf 2045/1098/2045 2475/4300/2475 2486/2178/2486 2048/4078/2048 \nf 2474/591/2474 2485/4305/2485 2486/2178/2486 2475/4300/2475 \nf 2484/1154/2484 2487/4307/2487 2486/2178/2486 2485/4305/2485 \nf 1520/192/1520 1523/3795/1523 2488/2179/2488 2476/4301/2476 \nf 1515/1014/1515 2489/4309/2489 2488/2179/2488 1523/3795/1523 \nf 2490/592/2490 2491/4310/2491 2488/2179/2488 2489/4309/2489 \nf 2478/1153/2478 2476/4301/2476 2488/2179/2488 2491/4310/2491 \nf 1511/167/1511 2266/4193/2266 2492/2180/2492 1512/3788/1512 \nf 2260/1127/2260 2493/4311/2493 2492/2180/2492 2266/4193/2266 \nf 2490/592/2490 2489/4309/2489 2492/2180/2492 2493/4311/2493 \nf 1515/1014/1515 1512/3788/1512 2492/2180/2492 2489/4309/2489 \nf 2242/135/2242 2494/4312/2494 2495/2181/2495 2258/4187/2258 \nf 2496/1156/2496 2497/4313/2497 2495/2181/2495 2494/4312/2494 \nf 2490/592/2490 2493/4311/2493 2495/2181/2495 2497/4313/2497 \nf 2260/1127/2260 2258/4187/2258 2495/2181/2495 2493/4311/2493 \nf 2480/210/2480 2483/4306/2483 2498/2182/2498 2499/4314/2499 \nf 2478/1153/2478 2491/4310/2491 2498/2182/2498 2483/4306/2483 \nf 2490/592/2490 2497/4313/2497 2498/2182/2498 2491/4310/2491 \nf 2496/1156/2496 2499/4314/2499 2498/2182/2498 2497/4313/2497 \nf 2233/124/2233 2500/4315/2500 2501/2183/2501 2234/4175/2234 \nf 2502/1157/2502 2503/4316/2503 2501/2183/2501 2500/4315/2500 \nf 2504/593/2504 2505/4317/2505 2501/2183/2501 2503/4316/2503 \nf 2237/1123/2237 2234/4175/2234 2501/2183/2501 2505/4317/2505 \nf 2506/232/2506 2507/4318/2507 2508/2184/2508 2509/4321/2509 \nf 2510/1158/2510 2511/4320/2511 2508/2184/2508 2507/4318/2507 \nf 2504/593/2504 2503/4316/2503 2508/2184/2508 2511/4320/2511 \nf 2502/1157/2502 2509/4321/2509 2508/2184/2508 2503/4316/2503 \nf 2480/210/2480 2499/4314/2499 2512/2185/2512 2513/4323/2513 \nf 2496/1156/2496 2514/4322/2514 2512/2185/2512 2499/4314/2499 \nf 2504/593/2504 2511/4320/2511 2512/2185/2512 2514/4322/2514 \nf 2510/1158/2510 2513/4323/2513 2512/2185/2512 2511/4320/2511 \nf 2242/135/2242 2245/4181/2245 2515/2186/2515 2494/4312/2494 \nf 2237/1123/2237 2505/4317/2505 2515/2186/2515 2245/4181/2245 \nf 2504/593/2504 2514/4322/2514 2515/2186/2515 2505/4317/2505 \nf 2496/1156/2496 2494/4312/2494 2515/2186/2515 2514/4322/2514 \nf 2506/206/2506 2516/4325/2516 2517/2187/2517 2507/4319/2507 \nf 2518/1160/2518 2519/4326/2519 2517/2187/2517 2516/4325/2516 \nf 2520/594/2520 2521/4327/2521 2517/2187/2517 2519/4326/2519 \nf 2510/1159/2510 2507/4319/2507 2517/2187/2517 2521/4327/2521 \nf 1972/84/1972 1975/4038/1975 2522/2188/2522 2523/4329/2523 \nf 1980/1088/1980 2524/4328/2524 2522/2188/2522 1975/4038/1975 \nf 2520/594/2520 2519/4326/2519 2522/2188/2522 2524/4328/2524 \nf 2518/1160/2518 2523/4329/2523 2522/2188/2522 2519/4326/2519 \nf 1993/157/1993 2487/4308/2487 2525/2189/2525 1994/4045/1994 \nf 2484/1155/2484 2526/4330/2526 2525/2189/2525 2487/4308/2487 \nf 2520/594/2520 2524/4328/2524 2525/2189/2525 2526/4330/2526 \nf 1980/1088/1980 1994/4045/1994 2525/2189/2525 2524/4328/2524 \nf 2480/216/2480 2513/4324/2513 2527/2190/2527 2481/4304/2481 \nf 2510/1159/2510 2521/4327/2521 2527/2190/2527 2513/4324/2513 \nf 2520/594/2520 2526/4330/2526 2527/2190/2527 2521/4327/2521 \nf 2484/1155/2484 2481/4304/2481 2527/2190/2527 2526/4330/2526 \nf 1592/139/1592 1595/3839/1595 2528/2191/2528 2529/4333/2529 \nf 1600/1032/1600 2530/4331/2530 2528/2191/2528 1595/3839/1595 \nf 2531/595/2531 2532/4332/2532 2528/2191/2528 2530/4331/2530 \nf 2533/1164/2533 2529/4333/2529 2528/2191/2528 2532/4332/2532 \nf 1584/153/1584 2534/4334/2534 2535/2192/2535 1610/3846/1610 \nf 2536/1161/2536 2537/4336/2537 2535/2192/2535 2534/4334/2534 \nf 2531/595/2531 2530/4331/2530 2535/2192/2535 2537/4336/2537 \nf 1600/1032/1600 1610/3846/1610 2535/2192/2535 2530/4331/2530 \nf 2538/160/2538 2539/4337/2539 2540/2193/2540 2541/4339/2541 \nf 2542/1163/2542 2543/4338/2543 2540/2193/2540 2539/4337/2539 \nf 2531/595/2531 2537/4336/2537 2540/2193/2540 2543/4338/2543 \nf 2536/1161/2536 2541/4339/2541 2540/2193/2540 2537/4336/2537 \nf 2544/171/2544 2545/4341/2545 2546/2194/2546 2547/4342/2547 \nf 2533/1164/2533 2532/4332/2532 2546/2194/2546 2545/4341/2545 \nf 2531/595/2531 2543/4338/2543 2546/2194/2546 2532/4332/2532 \nf 2542/1163/2542 2547/4342/2547 2546/2194/2546 2543/4338/2543 \nf 1584/250/1584 1587/3833/1587 2548/2195/2548 2534/4335/2534 \nf 1582/1027/1582 2549/4343/2549 2548/2195/2548 1587/3833/1587 \nf 2550/596/2550 2551/4344/2551 2548/2195/2548 2549/4343/2549 \nf 2536/1162/2536 2534/4335/2534 2548/2195/2548 2551/4344/2551 \nf 1578/81/1578 2552/4345/2552 2553/2196/2553 1579/3826/1579 \nf 2554/1165/2554 2555/4346/2555 2553/2196/2553 2552/4345/2552 \nf 2550/596/2550 2549/4343/2549 2553/2196/2553 2555/4346/2555 \nf 1582/1027/1582 1579/3826/1579 2553/2196/2553 2549/4343/2549 \nf 2556/260/2556 2557/4347/2557 2558/2197/2558 2559/4349/2559 \nf 2560/1166/2560 2561/4348/2561 2558/2197/2558 2557/4347/2557 \nf 2550/596/2550 2555/4346/2555 2558/2197/2558 2561/4348/2561 \nf 2554/1165/2554 2559/4349/2559 2558/2197/2558 2555/4346/2555 \nf 2538/320/2538 2541/4340/2541 2562/2198/2562 2563/4350/2563 \nf 2536/1162/2536 2551/4344/2551 2562/2198/2562 2541/4340/2541 \nf 2550/596/2550 2561/4348/2561 2562/2198/2562 2551/4344/2551 \nf 2560/1166/2560 2563/4350/2563 2562/2198/2562 2561/4348/2561 \nf 2564/327/2564 2565/4351/2565 2566/2199/2566 2567/4354/2567 \nf 2568/1167/2568 2569/4352/2569 2566/2199/2566 2565/4351/2565 \nf 2570/597/2570 2571/4353/2571 2566/2199/2566 2569/4352/2569 \nf 2572/1170/2572 2567/4354/2567 2566/2199/2566 2571/4353/2571 \nf 2573/342/2573 2574/4355/2574 2575/2200/2575 2576/4358/2576 \nf 2577/1168/2577 2578/4357/2578 2575/2200/2575 2574/4355/2574 \nf 2570/597/2570 2569/4352/2569 2575/2200/2575 2578/4357/2578 \nf 2568/1167/2568 2576/4358/2576 2575/2200/2575 2569/4352/2569 \nf 2538/320/2538 2563/4350/2563 2579/2201/2579 2580/4360/2580 \nf 2560/1166/2560 2581/4359/2581 2579/2201/2579 2563/4350/2563 \nf 2570/597/2570 2578/4357/2578 2579/2201/2579 2581/4359/2581 \nf 2577/1168/2577 2580/4360/2580 2579/2201/2579 2578/4357/2578 \nf 2556/260/2556 2582/4362/2582 2583/2202/2583 2557/4347/2557 \nf 2572/1170/2572 2571/4353/2571 2583/2202/2583 2582/4362/2582 \nf 2570/597/2570 2581/4359/2581 2583/2202/2583 2571/4353/2571 \nf 2560/1166/2560 2557/4347/2557 2583/2202/2583 2581/4359/2581 \nf 2573/173/2573 2584/4363/2584 2585/2203/2585 2574/4356/2574 \nf 2586/1171/2586 2587/4364/2587 2585/2203/2585 2584/4363/2584 \nf 2588/598/2588 2589/4365/2589 2585/2203/2585 2587/4364/2587 \nf 2577/1169/2577 2574/4356/2574 2585/2203/2585 2589/4365/2589 \nf 2590/175/2590 2591/4366/2591 2592/2204/2592 2593/4368/2593 \nf 2594/1172/2594 2595/4367/2595 2592/2204/2592 2591/4366/2591 \nf 2588/598/2588 2587/4364/2587 2592/2204/2592 2595/4367/2595 \nf 2586/1171/2586 2593/4368/2593 2592/2204/2592 2587/4364/2587 \nf 2544/171/2544 2547/4342/2547 2596/2205/2596 2597/4370/2597 \nf 2542/1163/2542 2598/4369/2598 2596/2205/2596 2547/4342/2547 \nf 2588/598/2588 2595/4367/2595 2596/2205/2596 2598/4369/2598 \nf 2594/1172/2594 2597/4370/2597 2596/2205/2596 2595/4367/2595 \nf 2538/160/2538 2580/4361/2580 2599/2206/2599 2539/4337/2539 \nf 2577/1169/2577 2589/4365/2589 2599/2206/2599 2580/4361/2580 \nf 2588/598/2588 2598/4369/2598 2599/2206/2599 2589/4365/2589 \nf 2542/1163/2542 2539/4337/2539 2599/2206/2599 2598/4369/2598 \nf 1578/81/1578 1826/3957/1826 2600/2207/2600 2552/4345/2552 \nf 1830/1067/1830 2601/4371/2601 2600/2207/2600 1826/3957/1826 \nf 2602/599/2602 2603/4372/2603 2600/2207/2600 2601/4371/2601 \nf 2554/1165/2554 2552/4345/2552 2600/2207/2600 2603/4372/2603 \nf 1817/69/1817 2604/4373/2604 2605/2208/2605 1838/3964/1838 \nf 2606/1173/2606 2607/4374/2607 2605/2208/2605 2604/4373/2604 \nf 2602/599/2602 2601/4371/2601 2605/2208/2605 2607/4374/2607 \nf 1830/1067/1830 1838/3964/1838 2605/2208/2605 2601/4371/2601 \nf 2608/403/2608 2609/4375/2609 2610/2209/2610 2611/4377/2611 \nf 2612/1174/2612 2613/4376/2613 2610/2209/2610 2609/4375/2609 \nf 2602/599/2602 2607/4374/2607 2610/2209/2610 2613/4376/2613 \nf 2606/1173/2606 2611/4377/2611 2610/2209/2610 2607/4374/2607 \nf 2556/260/2556 2559/4349/2559 2614/2210/2614 2615/4378/2615 \nf 2554/1165/2554 2603/4372/2603 2614/2210/2614 2559/4349/2559 \nf 2602/599/2602 2613/4376/2613 2614/2210/2614 2603/4372/2603 \nf 2612/1174/2612 2615/4378/2615 2614/2210/2614 2613/4376/2613 \nf 1817/69/1817 1820/3953/1820 2616/2211/2616 2604/4373/2604 \nf 1815/1063/1815 2617/4379/2617 2616/2211/2616 1820/3953/1820 \nf 2618/600/2618 2619/4380/2619 2616/2211/2616 2617/4379/2617 \nf 2606/1173/2606 2604/4373/2604 2616/2211/2616 2619/4380/2619 \nf 1811/64/1811 2019/4060/2019 2620/2212/2620 1812/3948/1812 \nf 2024/1094/2024 2621/4381/2621 2620/2212/2620 2019/4060/2019 \nf 2618/600/2618 2617/4379/2617 2620/2212/2620 2621/4381/2621 \nf 1815/1063/1815 1812/3948/1812 2620/2212/2620 2617/4379/2617 \nf 2009/169/2009 2622/4382/2622 2623/2213/2623 2034/4066/2034 \nf 2624/1175/2624 2625/4383/2625 2623/2213/2623 2622/4382/2622 \nf 2618/600/2618 2621/4381/2621 2623/2213/2623 2625/4383/2625 \nf 2024/1094/2024 2034/4066/2034 2623/2213/2623 2621/4381/2621 \nf 2608/403/2608 2611/4377/2611 2626/2214/2626 2627/4384/2627 \nf 2606/1173/2606 2619/4380/2619 2626/2214/2626 2611/4377/2611 \nf 2618/600/2618 2625/4383/2625 2626/2214/2626 2619/4380/2619 \nf 2624/1175/2624 2627/4384/2627 2626/2214/2626 2625/4383/2625 \nf 2003/158/2003 2628/4385/2628 2629/2215/2629 2004/4050/2004 \nf 2630/1176/2630 2631/4386/2631 2629/2215/2629 2628/4385/2628 \nf 2632/601/2632 2633/4387/2633 2629/2215/2629 2631/4386/2631 \nf 2007/1090/2007 2004/4050/2004 2629/2215/2629 2633/4387/2633 \nf 2634/407/2634 2635/4388/2635 2636/2216/2636 2637/4390/2637 \nf 2638/1177/2638 2639/4389/2639 2636/2216/2636 2635/4388/2635 \nf 2632/601/2632 2631/4386/2631 2636/2216/2636 2639/4389/2639 \nf 2630/1176/2630 2637/4390/2637 2636/2216/2636 2631/4386/2631 \nf 2608/403/2608 2627/4384/2627 2640/2217/2640 2641/4392/2641 \nf 2624/1175/2624 2642/4391/2642 2640/2217/2640 2627/4384/2627 \nf 2632/601/2632 2639/4389/2639 2640/2217/2640 2642/4391/2642 \nf 2638/1177/2638 2641/4392/2641 2640/2217/2640 2639/4389/2639 \nf 2009/169/2009 2012/4055/2012 2643/2218/2643 2622/4382/2622 \nf 2007/1090/2007 2633/4387/2633 2643/2218/2643 2012/4055/2012 \nf 2632/601/2632 2642/4391/2642 2643/2218/2643 2633/4387/2633 \nf 2624/1175/2624 2622/4382/2622 2643/2218/2643 2642/4391/2642 \nf 2634/407/2634 2644/4393/2644 2645/2219/2645 2635/4388/2635 \nf 2646/1178/2646 2647/4394/2647 2645/2219/2645 2644/4393/2644 \nf 2648/602/2648 2649/4395/2649 2645/2219/2645 2647/4394/2647 \nf 2638/1177/2638 2635/4388/2635 2645/2219/2645 2649/4395/2649 \nf 2564/327/2564 2567/4354/2567 2650/2220/2650 2651/4397/2651 \nf 2572/1170/2572 2652/4396/2652 2650/2220/2650 2567/4354/2567 \nf 2648/602/2648 2647/4394/2647 2650/2220/2650 2652/4396/2652 \nf 2646/1178/2646 2651/4397/2651 2650/2220/2650 2647/4394/2647 \nf 2556/260/2556 2615/4378/2615 2653/2221/2653 2582/4362/2582 \nf 2612/1174/2612 2654/4398/2654 2653/2221/2653 2615/4378/2615 \nf 2648/602/2648 2652/4396/2652 2653/2221/2653 2654/4398/2654 \nf 2572/1170/2572 2582/4362/2582 2653/2221/2653 2652/4396/2652 \nf 2608/403/2608 2641/4392/2641 2655/2222/2655 2609/4375/2609 \nf 2638/1177/2638 2649/4395/2649 2655/2222/2655 2641/4392/2641 \nf 2648/602/2648 2654/4398/2654 2655/2222/2655 2649/4395/2649 \nf 2612/1174/2612 2609/4375/2609 2655/2222/2655 2654/4398/2654 \nf 1884/193/1884 1887/3993/1887 2656/2223/2656 2657/4401/2657 \nf 1892/1077/1892 2658/4399/2658 2656/2223/2656 1887/3993/1887 \nf 2659/603/2659 2660/4400/2660 2656/2223/2656 2658/4399/2658 \nf 2661/1181/2661 2657/4401/2657 2656/2223/2656 2660/4400/2660 \nf 1876/195/1876 2662/4402/2662 2663/2224/2663 1902/4000/1902 \nf 2664/1179/2664 2665/4403/2665 2663/2224/2663 2662/4402/2662 \nf 2659/603/2659 2658/4399/2658 2663/2224/2663 2665/4403/2665 \nf 1892/1077/1892 1902/4000/1902 2663/2224/2663 2658/4399/2658 \nf 2666/197/2666 2667/4404/2667 2668/2225/2668 2669/4406/2669 \nf 2670/1180/2670 2671/4405/2671 2668/2225/2668 2667/4404/2667 \nf 2659/603/2659 2665/4403/2665 2668/2225/2668 2671/4405/2671 \nf 2664/1179/2664 2669/4406/2669 2668/2225/2668 2665/4403/2665 \nf 2672/215/2672 2673/4407/2673 2674/2226/2674 2675/4408/2675 \nf 2661/1181/2661 2660/4400/2660 2674/2226/2674 2673/4407/2673 \nf 2659/603/2659 2671/4405/2671 2674/2226/2674 2660/4400/2660 \nf 2670/1180/2670 2675/4408/2675 2674/2226/2674 2671/4405/2671 \nf 1876/195/1876 1879/3987/1879 2676/2227/2676 2662/4402/2662 \nf 1874/1072/1874 2677/4409/2677 2676/2227/2676 1879/3987/1879 \nf 2678/604/2678 2679/4410/2679 2676/2227/2676 2677/4409/2677 \nf 2664/1179/2664 2662/4402/2662 2676/2227/2676 2679/4410/2679 \nf 1592/139/1592 2529/4333/2529 2680/2228/2680 1872/3982/1872 \nf 2533/1164/2533 2681/4411/2681 2680/2228/2680 2529/4333/2529 \nf 2678/604/2678 2677/4409/2677 2680/2228/2680 2681/4411/2681 \nf 1874/1072/1874 1872/3982/1872 2680/2228/2680 2677/4409/2677 \nf 2544/171/2544 2682/4412/2682 2683/2229/2683 2545/4341/2545 \nf 2684/1182/2684 2685/4413/2685 2683/2229/2683 2682/4412/2682 \nf 2678/604/2678 2681/4411/2681 2683/2229/2683 2685/4413/2685 \nf 2533/1164/2533 2545/4341/2545 2683/2229/2683 2681/4411/2681 \nf 2666/197/2666 2669/4406/2669 2686/2230/2686 2687/4414/2687 \nf 2664/1179/2664 2679/4410/2679 2686/2230/2686 2669/4406/2669 \nf 2678/604/2678 2685/4413/2685 2686/2230/2686 2679/4410/2679 \nf 2684/1182/2684 2687/4414/2687 2686/2230/2686 2685/4413/2685 \nf 2590/175/2590 2688/4415/2688 2689/2231/2689 2591/4366/2591 \nf 2690/1183/2690 2691/4416/2691 2689/2231/2689 2688/4415/2688 \nf 2692/605/2692 2693/4417/2693 2689/2231/2689 2691/4416/2691 \nf 2594/1172/2594 2591/4366/2591 2689/2231/2689 2693/4417/2693 \nf 2694/217/2694 2695/4418/2695 2696/2232/2696 2697/4420/2697 \nf 2698/1184/2698 2699/4419/2699 2696/2232/2696 2695/4418/2695 \nf 2692/605/2692 2691/4416/2691 2696/2232/2696 2699/4419/2699 \nf 2690/1183/2690 2697/4420/2697 2696/2232/2696 2691/4416/2691 \nf 2666/197/2666 2687/4414/2687 2700/2233/2700 2701/4422/2701 \nf 2684/1182/2684 2702/4421/2702 2700/2233/2700 2687/4414/2687 \nf 2692/605/2692 2699/4419/2699 2700/2233/2700 2702/4421/2702 \nf 2698/1184/2698 2701/4422/2701 2700/2233/2700 2699/4419/2699 \nf 2544/171/2544 2597/4370/2597 2703/2234/2703 2682/4412/2682 \nf 2594/1172/2594 2693/4417/2693 2703/2234/2703 2597/4370/2597 \nf 2692/605/2692 2702/4421/2702 2703/2234/2703 2693/4417/2693 \nf 2684/1182/2684 2682/4412/2682 2703/2234/2703 2702/4421/2702 \nf 2694/217/2694 2704/4423/2704 2705/2235/2705 2695/4418/2695 \nf 2706/1185/2706 2707/4424/2707 2705/2235/2705 2704/4423/2704 \nf 2708/606/2708 2709/4425/2709 2705/2235/2705 2707/4424/2707 \nf 2698/1184/2698 2695/4418/2695 2705/2235/2705 2709/4425/2709 \nf 2710/219/2710 2711/4426/2711 2712/2236/2712 2713/4428/2713 \nf 2714/1186/2714 2715/4427/2715 2712/2236/2712 2711/4426/2711 \nf 2708/606/2708 2707/4424/2707 2712/2236/2712 2715/4427/2715 \nf 2706/1185/2706 2713/4428/2713 2712/2236/2712 2707/4424/2707 \nf 2672/215/2672 2675/4408/2675 2716/2237/2716 2717/4430/2717 \nf 2670/1180/2670 2718/4429/2718 2716/2237/2716 2675/4408/2675 \nf 2708/606/2708 2715/4427/2715 2716/2237/2716 2718/4429/2718 \nf 2714/1186/2714 2717/4430/2717 2716/2237/2716 2715/4427/2715 \nf 2666/197/2666 2701/4422/2701 2719/2238/2719 2667/4404/2667 \nf 2698/1184/2698 2709/4425/2709 2719/2238/2719 2701/4422/2701 \nf 2708/606/2708 2718/4429/2718 2719/2238/2719 2709/4425/2709 \nf 2670/1180/2670 2667/4404/2667 2719/2238/2719 2718/4429/2718 \nf 1537/213/1537 2044/4075/2044 2720/2239/2720 1538/3803/1538 \nf 2038/1096/2038 2721/4431/2721 2720/2239/2720 2044/4075/2044 \nf 2722/607/2722 2723/4432/2723 2720/2239/2720 2721/4431/2721 \nf 1541/1019/1541 1538/3803/1538 2720/2239/2720 2723/4432/2723 \nf 2025/330/2025 2724/4433/2724 2725/2240/2725 2036/4068/2036 \nf 2726/1187/2726 2727/4435/2727 2725/2240/2725 2724/4433/2724 \nf 2722/607/2722 2721/4431/2721 2725/2240/2725 2727/4435/2727 \nf 2038/1096/2038 2036/4068/2036 2725/2240/2725 2721/4431/2721 \nf 2728/331/2728 2729/4436/2729 2730/2241/2730 2731/4438/2731 \nf 2732/1189/2732 2733/4437/2733 2730/2241/2730 2729/4436/2729 \nf 2722/607/2722 2727/4435/2727 2730/2241/2730 2733/4437/2733 \nf 2726/1187/2726 2731/4438/2731 2730/2241/2730 2727/4435/2727 \nf 1487/207/1487 1544/3808/1544 2734/2242/2734 2735/4440/2735 \nf 1541/1019/1541 2723/4432/2723 2734/2242/2734 1544/3808/1544 \nf 2722/607/2722 2733/4437/2733 2734/2242/2734 2723/4432/2723 \nf 2732/1189/2732 2735/4440/2735 2734/2242/2734 2733/4437/2733 \nf 2025/170/2025 2028/4063/2028 2736/2243/2736 2724/4434/2724 \nf 2020/1092/2020 2737/4441/2737 2736/2243/2736 2028/4063/2028 \nf 2738/608/2738 2739/4442/2739 2736/2243/2736 2737/4441/2737 \nf 2726/1188/2726 2724/4434/2724 2736/2243/2736 2739/4442/2739 \nf 1811/64/1811 1814/3950/1814 2740/2244/2740 2017/4057/2017 \nf 1807/1062/1807 2741/4443/2741 2740/2244/2740 1814/3950/1814 \nf 2738/608/2738 2737/4441/2737 2740/2244/2740 2741/4443/2741 \nf 2020/1092/2020 2017/4057/2017 2740/2244/2740 2737/4441/2737 \nf 1789/63/1789 2742/4444/2742 2743/2245/2743 1805/3945/1805 \nf 2744/1190/2744 2745/4446/2745 2743/2245/2743 2742/4444/2742 \nf 2738/608/2738 2741/4443/2741 2743/2245/2743 2745/4446/2745 \nf 1807/1062/1807 1805/3945/1805 2743/2245/2743 2741/4443/2741 \nf 2728/408/2728 2731/4439/2731 2746/2246/2746 2747/4447/2747 \nf 2726/1188/2726 2739/4442/2739 2746/2246/2746 2731/4439/2731 \nf 2738/608/2738 2745/4446/2745 2746/2246/2746 2739/4442/2739 \nf 2744/1190/2744 2747/4447/2747 2746/2246/2746 2745/4446/2745 \nf 1780/289/1780 2449/4289/2449 2748/2247/2748 1781/3931/1781 \nf 2453/1152/2453 2749/4449/2749 2748/2247/2748 2449/4289/2449 \nf 2750/609/2750 2751/4450/2751 2748/2247/2748 2749/4449/2749 \nf 1784/1057/1784 1781/3931/1781 2748/2247/2748 2751/4450/2751 \nf 2440/328/2440 2752/4451/2752 2753/2248/2753 2461/4294/2461 \nf 2754/1192/2754 2755/4452/2755 2753/2248/2753 2752/4451/2752 \nf 2750/609/2750 2749/4449/2749 2753/2248/2753 2755/4452/2755 \nf 2453/1152/2453 2461/4294/2461 2753/2248/2753 2749/4449/2749 \nf 2728/331/2728 2747/4448/2747 2756/2249/2756 2757/4454/2757 \nf 2744/1191/2744 2758/4453/2758 2756/2249/2756 2747/4448/2747 \nf 2750/609/2750 2755/4452/2755 2756/2249/2756 2758/4453/2758 \nf 2754/1192/2754 2757/4454/2757 2756/2249/2756 2755/4452/2755 \nf 1789/290/1789 1792/3938/1792 2759/2250/2759 2742/4445/2742 \nf 1784/1057/1784 2751/4450/2751 2759/2250/2759 1792/3938/1792 \nf 2750/609/2750 2758/4453/2758 2759/2250/2759 2751/4450/2751 \nf 2744/1191/2744 2742/4445/2742 2759/2250/2759 2758/4453/2758 \nf 2440/328/2440 2443/4285/2443 2760/2251/2760 2752/4451/2752 \nf 2438/1149/2438 2761/4455/2761 2760/2251/2760 2443/4285/2443 \nf 2762/610/2762 2763/4456/2763 2760/2251/2760 2761/4455/2761 \nf 2754/1192/2754 2752/4451/2752 2760/2251/2760 2763/4456/2763 \nf 1466/203/1466 1469/3768/1469 2764/2252/2764 2436/4281/2436 \nf 1474/1009/1474 2765/4457/2765 2764/2252/2764 1469/3768/1469 \nf 2762/610/2762 2761/4455/2761 2764/2252/2764 2765/4457/2765 \nf 2438/1149/2438 2436/4281/2436 2764/2252/2764 2761/4455/2761 \nf 1487/207/1487 2735/4440/2735 2766/2253/2766 1488/3775/1488 \nf 2732/1189/2732 2767/4458/2767 2766/2253/2766 2735/4440/2735 \nf 2762/610/2762 2765/4457/2765 2766/2253/2766 2767/4458/2767 \nf 1474/1009/1474 1488/3775/1488 2766/2253/2766 2765/4457/2765 \nf 2728/331/2728 2757/4454/2757 2768/2254/2768 2729/4436/2729 \nf 2754/1192/2754 2763/4456/2763 2768/2254/2768 2757/4454/2757 \nf 2762/610/2762 2767/4458/2767 2768/2254/2768 2763/4456/2763 \nf 2732/1189/2732 2729/4436/2729 2768/2254/2768 2767/4458/2767 \nf 626/95/626 2088/4102/2088 2769/2255/2769 1346/3705/1346 \nf 2092/1107/2092 2770/4459/2770 2769/2255/2769 2088/4102/2088 \nf 2771/611/2771 2772/4460/2772 2769/2255/2769 2770/4459/2770 \nf 1348/992/1348 1346/3705/1346 2769/2255/2769 2772/4460/2772 \nf 2079/237/2079 2773/4461/2773 2774/2256/2774 2100/4108/2100 \nf 2775/1193/2775 2776/4462/2776 2774/2256/2774 2773/4461/2773 \nf 2771/611/2771 2770/4459/2770 2774/2256/2774 2776/4462/2776 \nf 2092/1107/2092 2100/4108/2100 2774/2256/2774 2770/4459/2770 \nf 2777/239/2777 2778/4463/2778 2779/2257/2779 2780/4465/2780 \nf 2781/1194/2781 2782/4464/2782 2779/2257/2779 2778/4463/2778 \nf 2771/611/2771 2776/4462/2776 2779/2257/2779 2782/4464/2782 \nf 2775/1193/2775 2780/4465/2780 2779/2257/2779 2776/4462/2776 \nf 1352/110/1352 1355/3710/1355 2783/2258/2783 2784/4466/2784 \nf 1348/992/1348 2772/4460/2772 2783/2258/2783 1355/3710/1355 \nf 2771/611/2771 2782/4464/2782 2783/2258/2783 2772/4460/2772 \nf 2781/1194/2781 2784/4466/2784 2783/2258/2783 2782/4464/2782 \nf 2079/237/2079 2082/4097/2082 2785/2259/2785 2773/4461/2773 \nf 2077/1103/2077 2786/4467/2786 2785/2259/2785 2082/4097/2082 \nf 2787/612/2787 2788/4468/2788 2785/2259/2785 2786/4467/2786 \nf 2775/1193/2775 2773/4461/2773 2785/2259/2785 2788/4468/2788 \nf 1884/193/1884 2657/4401/2657 2789/2260/2789 2075/4092/2075 \nf 2661/1181/2661 2790/4469/2790 2789/2260/2789 2657/4401/2657 \nf 2787/612/2787 2786/4467/2786 2789/2260/2789 2790/4469/2790 \nf 2077/1103/2077 2075/4092/2075 2789/2260/2789 2786/4467/2786 \nf 2672/215/2672 2791/4470/2791 2792/2261/2792 2673/4407/2673 \nf 2793/1195/2793 2794/4471/2794 2792/2261/2792 2791/4470/2791 \nf 2787/612/2787 2790/4469/2790 2792/2261/2792 2794/4471/2794 \nf 2661/1181/2661 2673/4407/2673 2792/2261/2792 2790/4469/2790 \nf 2777/239/2777 2780/4465/2780 2795/2262/2795 2796/4472/2796 \nf 2775/1193/2775 2788/4468/2788 2795/2262/2795 2780/4465/2780 \nf 2787/612/2787 2794/4471/2794 2795/2262/2795 2788/4468/2788 \nf 2793/1195/2793 2796/4472/2796 2795/2262/2795 2794/4471/2794 \nf 2710/219/2710 2797/4473/2797 2798/2263/2798 2711/4426/2711 \nf 2799/1196/2799 2800/4474/2800 2798/2263/2798 2797/4473/2797 \nf 2801/613/2801 2802/4475/2802 2798/2263/2798 2800/4474/2800 \nf 2714/1186/2714 2711/4426/2711 2798/2263/2798 2802/4475/2802 \nf 2803/241/2803 2804/4476/2804 2805/2264/2805 2806/4478/2806 \nf 2807/1197/2807 2808/4477/2808 2805/2264/2805 2804/4476/2804 \nf 2801/613/2801 2800/4474/2800 2805/2264/2805 2808/4477/2808 \nf 2799/1196/2799 2806/4478/2806 2805/2264/2805 2800/4474/2800 \nf 2777/239/2777 2796/4472/2796 2809/2265/2809 2810/4480/2810 \nf 2793/1195/2793 2811/4479/2811 2809/2265/2809 2796/4472/2796 \nf 2801/613/2801 2808/4477/2808 2809/2265/2809 2811/4479/2811 \nf 2807/1197/2807 2810/4480/2810 2809/2265/2809 2808/4477/2808 \nf 2672/215/2672 2717/4430/2717 2812/2266/2812 2791/4470/2791 \nf 2714/1186/2714 2802/4475/2802 2812/2266/2812 2717/4430/2717 \nf 2801/613/2801 2811/4479/2811 2812/2266/2812 2802/4475/2802 \nf 2793/1195/2793 2791/4470/2791 2812/2266/2812 2811/4479/2811 \nf 2803/241/2803 2813/4481/2813 2814/2267/2814 2804/4476/2804 \nf 2815/1198/2815 2816/4482/2816 2814/2267/2814 2813/4481/2813 \nf 2817/614/2817 2818/4483/2818 2814/2267/2814 2816/4482/2816 \nf 2807/1197/2807 2804/4476/2804 2814/2267/2814 2818/4483/2818 \nf 1372/129/1372 1375/3720/1375 2819/2268/2819 2820/4485/2820 \nf 1368/995/1368 2821/4484/2821 2819/2268/2819 1375/3720/1375 \nf 2817/614/2817 2816/4482/2816 2819/2268/2819 2821/4484/2821 \nf 2815/1198/2815 2820/4485/2820 2819/2268/2819 2816/4482/2816 \nf 1352/110/1352 2784/4466/2784 2822/2269/2822 1366/3715/1366 \nf 2781/1194/2781 2823/4486/2823 2822/2269/2822 2784/4466/2784 \nf 2817/614/2817 2821/4484/2821 2822/2269/2822 2823/4486/2823 \nf 1368/995/1368 1366/3715/1366 2822/2269/2822 2821/4484/2821 \nf 2777/239/2777 2810/4480/2810 2824/2270/2824 2778/4463/2778 \nf 2807/1197/2807 2818/4483/2818 2824/2270/2824 2810/4480/2810 \nf 2817/614/2817 2823/4486/2823 2824/2270/2824 2818/4483/2818 \nf 2781/1194/2781 2778/4463/2778 2824/2270/2824 2823/4486/2823 \nf 839/199/839 2278/4202/2278 2825/2271/2825 1410/3737/1410 \nf 2282/1133/2282 2826/4487/2826 2825/2271/2825 2278/4202/2278 \nf 2827/615/2827 2828/4488/2828 2825/2271/2825 2826/4487/2826 \nf 1412/1000/1412 1410/3737/1410 2825/2271/2825 2828/4488/2828 \nf 2269/332/2269 2829/4489/2829 2830/2272/2830 2290/4208/2290 \nf 2831/1199/2831 2832/4490/2832 2830/2272/2830 2829/4489/2829 \nf 2827/615/2827 2826/4487/2826 2830/2272/2830 2832/4490/2832 \nf 2282/1133/2282 2290/4208/2290 2830/2272/2830 2826/4487/2826 \nf 2833/333/2833 2834/4491/2834 2835/2273/2835 2836/4493/2836 \nf 2837/1200/2837 2838/4492/2838 2835/2273/2835 2834/4491/2834 \nf 2827/615/2827 2832/4490/2832 2835/2273/2835 2838/4492/2838 \nf 2831/1199/2831 2836/4493/2836 2835/2273/2835 2832/4490/2832 \nf 1416/200/1416 1419/3742/1419 2839/2274/2839 2840/4494/2840 \nf 1412/1000/1412 2828/4488/2828 2839/2274/2839 1419/3742/1419 \nf 2827/615/2827 2838/4492/2838 2839/2274/2839 2828/4488/2828 \nf 2837/1200/2837 2840/4494/2840 2839/2274/2839 2838/4492/2838 \nf 2269/332/2269 2272/4197/2272 2841/2275/2841 2829/4489/2829 \nf 2267/1129/2267 2842/4495/2842 2841/2275/2841 2272/4197/2272 \nf 2843/616/2843 2844/4496/2844 2841/2275/2841 2842/4495/2842 \nf 2831/1199/2831 2829/4489/2829 2841/2275/2841 2844/4496/2844 \nf 1511/211/1511 1514/3791/1514 2845/2276/2845 2264/4191/2264 \nf 1519/1016/1519 2846/4497/2846 2845/2276/2845 1514/3791/1514 \nf 2843/616/2843 2842/4495/2842 2845/2276/2845 2846/4497/2846 \nf 2267/1129/2267 2264/4191/2264 2845/2276/2845 2842/4495/2842 \nf 1503/209/1503 2847/4498/2847 2848/2277/2848 1529/3798/1529 \nf 2849/1201/2849 2850/4499/2850 2848/2277/2848 2847/4498/2847 \nf 2843/616/2843 2846/4497/2846 2848/2277/2848 2850/4499/2850 \nf 1519/1016/1519 1529/3798/1529 2848/2277/2848 2846/4497/2846 \nf 2833/333/2833 2836/4493/2836 2851/2278/2851 2852/4500/2852 \nf 2831/1199/2831 2844/4496/2844 2851/2278/2851 2836/4493/2836 \nf 2843/616/2843 2850/4499/2850 2851/2278/2851 2844/4496/2844 \nf 2849/1201/2849 2852/4500/2852 2851/2278/2851 2850/4499/2850 \nf 1497/208/1497 2115/4117/2115 2853/2279/2853 1498/3780/1498 \nf 2119/1111/2119 2854/4501/2854 2853/2279/2853 2115/4117/2115 \nf 2855/617/2855 2856/4502/2856 2853/2279/2853 2854/4501/2854 \nf 1501/1011/1501 1498/3780/1498 2853/2279/2853 2856/4502/2856 \nf 2130/315/2130 2857/4503/2857 2858/2280/2858 2131/4123/2131 \nf 2859/1202/2859 2860/4504/2860 2858/2280/2858 2857/4503/2857 \nf 2855/617/2855 2854/4501/2854 2858/2280/2858 2860/4504/2860 \nf 2119/1111/2119 2131/4123/2131 2858/2280/2858 2854/4501/2854 \nf 2833/333/2833 2852/4500/2852 2861/2281/2861 2862/4506/2862 \nf 2849/1201/2849 2863/4505/2863 2861/2281/2861 2852/4500/2852 \nf 2855/617/2855 2860/4504/2860 2861/2281/2861 2863/4505/2863 \nf 2859/1202/2859 2862/4506/2862 2861/2281/2861 2860/4504/2860 \nf 1503/209/1503 1506/3785/1506 2864/2282/2864 2847/4498/2847 \nf 1501/1011/1501 2856/4502/2856 2864/2282/2864 1506/3785/1506 \nf 2855/617/2855 2863/4505/2863 2864/2282/2864 2856/4502/2856 \nf 2849/1201/2849 2847/4498/2847 2864/2282/2864 2863/4505/2863 \nf 2130/315/2130 2174/4146/2174 2865/2283/2865 2857/4503/2857 \nf 2171/1116/2171 2866/4507/2866 2865/2283/2865 2174/4146/2174 \nf 2867/618/2867 2868/4508/2868 2865/2283/2865 2866/4507/2866 \nf 2859/1202/2859 2857/4503/2857 2865/2283/2865 2868/4508/2868 \nf 684/86/684 1437/3751/1437 2869/2284/2869 2169/4143/2169 \nf 1432/1003/1432 2870/4509/2870 2869/2284/2869 1437/3751/1437 \nf 2867/618/2867 2866/4507/2866 2869/2284/2869 2870/4509/2870 \nf 2171/1116/2171 2169/4143/2169 2869/2284/2869 2866/4507/2866 \nf 1416/200/1416 2840/4494/2840 2871/2285/2871 1430/3747/1430 \nf 2837/1200/2837 2872/4510/2872 2871/2285/2871 2840/4494/2840 \nf 2867/618/2867 2870/4509/2870 2871/2285/2871 2872/4510/2872 \nf 1432/1003/1432 1430/3747/1430 2871/2285/2871 2870/4509/2870 \nf 2833/333/2833 2862/4506/2862 2873/2286/2873 2834/4491/2834 \nf 2859/1202/2859 2868/4508/2868 2873/2286/2873 2862/4506/2862 \nf 2867/618/2867 2872/4510/2872 2873/2286/2873 2868/4508/2868 \nf 2837/1200/2837 2834/4491/2834 2873/2286/2873 2872/4510/2872 \nf 2874/89/2874 2875/4511/2875 2876/2287/2876 2877/4514/2877 \nf 2878/1203/2878 2879/4512/2879 2876/2287/2876 2875/4511/2875 \nf 2880/619/2880 2881/4513/2881 2876/2287/2876 2879/4512/2879 \nf 2882/1206/2882 2877/4514/2877 2876/2287/2876 2881/4513/2881 \nf 2883/92/2883 2884/4515/2884 2885/2288/2885 2886/4517/2886 \nf 2887/1204/2887 2888/4516/2888 2885/2288/2885 2884/4515/2884 \nf 2880/619/2880 2879/4512/2879 2885/2288/2885 2888/4516/2888 \nf 2878/1203/2878 2886/4517/2886 2885/2288/2885 2879/4512/2879 \nf 2889/93/2889 2890/4518/2890 2891/2289/2891 2892/4520/2892 \nf 2893/1205/2893 2894/4519/2894 2891/2289/2891 2890/4518/2890 \nf 2880/619/2880 2888/4516/2888 2891/2289/2891 2894/4519/2894 \nf 2887/1204/2887 2892/4520/2892 2891/2289/2891 2888/4516/2888 \nf 2895/94/2895 2896/4521/2896 2897/2290/2897 2898/4522/2898 \nf 2882/1206/2882 2881/4513/2881 2897/2290/2897 2896/4521/2896 \nf 2880/619/2880 2894/4519/2894 2897/2290/2897 2881/4513/2881 \nf 2893/1205/2893 2898/4522/2898 2897/2290/2897 2894/4519/2894 \nf 2883/92/2883 2899/4523/2899 2900/2291/2900 2884/4515/2884 \nf 2901/1207/2901 2902/4524/2902 2900/2291/2900 2899/4523/2899 \nf 2903/620/2903 2904/4525/2904 2900/2291/2900 2902/4524/2902 \nf 2887/1204/2887 2884/4515/2884 2900/2291/2900 2904/4525/2904 \nf 2905/96/2905 2906/4526/2906 2907/2292/2907 2908/4528/2908 \nf 2909/1208/2909 2910/4527/2910 2907/2292/2907 2906/4526/2906 \nf 2903/620/2903 2902/4524/2902 2907/2292/2907 2910/4527/2910 \nf 2901/1207/2901 2908/4528/2908 2907/2292/2907 2902/4524/2902 \nf 2911/97/2911 2912/4529/2912 2913/2293/2913 2914/4531/2914 \nf 2915/1209/2915 2916/4530/2916 2913/2293/2913 2912/4529/2912 \nf 2903/620/2903 2910/4527/2910 2913/2293/2913 2916/4530/2916 \nf 2909/1208/2909 2914/4531/2914 2913/2293/2913 2910/4527/2910 \nf 2889/93/2889 2892/4520/2892 2917/2294/2917 2918/4532/2918 \nf 2887/1204/2887 2904/4525/2904 2917/2294/2917 2892/4520/2892 \nf 2903/620/2903 2916/4530/2916 2917/2294/2917 2904/4525/2904 \nf 2915/1209/2915 2918/4532/2918 2917/2294/2917 2916/4530/2916 \nf 2919/98/2919 2920/4533/2920 2921/2295/2921 2922/4537/2922 \nf 2923/1210/2923 2924/4535/2924 2921/2295/2921 2920/4533/2920 \nf 2925/621/2925 2926/4536/2926 2921/2295/2921 2924/4535/2924 \nf 2927/1213/2927 2922/4537/2922 2921/2295/2921 2926/4536/2926 \nf 2928/99/2928 2929/4538/2929 2930/2296/2930 2931/4540/2931 \nf 2932/1212/2932 2933/4539/2933 2930/2296/2930 2929/4538/2929 \nf 2925/621/2925 2924/4535/2924 2930/2296/2930 2933/4539/2933 \nf 2923/1210/2923 2931/4540/2931 2930/2296/2930 2924/4535/2924 \nf 2889/93/2889 2918/4532/2918 2934/2297/2934 2935/4543/2935 \nf 2915/1209/2915 2936/4542/2936 2934/2297/2934 2918/4532/2918 \nf 2925/621/2925 2933/4539/2933 2934/2297/2934 2936/4542/2936 \nf 2932/1212/2932 2935/4543/2935 2934/2297/2934 2933/4539/2933 \nf 2911/97/2911 2937/4544/2937 2938/2298/2938 2912/4529/2912 \nf 2927/1213/2927 2926/4536/2926 2938/2298/2938 2937/4544/2937 \nf 2925/621/2925 2936/4542/2936 2938/2298/2938 2926/4536/2926 \nf 2915/1209/2915 2912/4529/2912 2938/2298/2938 2936/4542/2936 \nf 2928/99/2928 2939/4545/2939 2940/2299/2940 2929/4538/2929 \nf 2941/1214/2941 2942/4547/2942 2940/2299/2940 2939/4545/2939 \nf 2943/622/2943 2944/4548/2944 2940/2299/2940 2942/4547/2942 \nf 2932/1212/2932 2929/4538/2929 2940/2299/2940 2944/4548/2944 \nf 2945/100/2945 2946/4549/2946 2947/2300/2947 2948/4551/2948 \nf 2949/1216/2949 2950/4550/2950 2947/2300/2947 2946/4549/2946 \nf 2943/622/2943 2942/4547/2942 2947/2300/2947 2950/4550/2950 \nf 2941/1214/2941 2948/4551/2948 2947/2300/2947 2942/4547/2942 \nf 2895/94/2895 2898/4522/2898 2951/2301/2951 2952/4554/2952 \nf 2893/1205/2893 2953/4553/2953 2951/2301/2951 2898/4522/2898 \nf 2943/622/2943 2950/4550/2950 2951/2301/2951 2953/4553/2953 \nf 2949/1216/2949 2952/4554/2952 2951/2301/2951 2950/4550/2950 \nf 2889/93/2889 2935/4543/2935 2954/2302/2954 2890/4518/2890 \nf 2932/1212/2932 2944/4548/2944 2954/2302/2954 2935/4543/2935 \nf 2943/622/2943 2953/4553/2953 2954/2302/2954 2944/4548/2944 \nf 2893/1205/2893 2890/4518/2890 2954/2302/2954 2953/4553/2953 \nf 2955/101/2955 2956/4555/2956 2957/2303/2957 2958/4558/2958 \nf 2959/1217/2959 2960/4556/2960 2957/2303/2957 2956/4555/2956 \nf 2961/623/2961 2962/4557/2962 2957/2303/2957 2960/4556/2960 \nf 2963/1220/2963 2958/4558/2958 2957/2303/2957 2962/4557/2962 \nf 2964/102/2964 2965/4559/2965 2966/2304/2966 2967/4561/2967 \nf 2968/1218/2968 2969/4560/2969 2966/2304/2966 2965/4559/2965 \nf 2961/623/2961 2960/4556/2960 2966/2304/2966 2969/4560/2969 \nf 2959/1217/2959 2967/4561/2967 2966/2304/2966 2960/4556/2960 \nf 2970/103/2970 2971/4562/2971 2972/2305/2972 2973/4564/2973 \nf 2974/1219/2974 2975/4563/2975 2972/2305/2972 2971/4562/2971 \nf 2961/623/2961 2969/4560/2969 2972/2305/2972 2975/4563/2975 \nf 2968/1218/2968 2973/4564/2973 2972/2305/2972 2969/4560/2969 \nf 2976/104/2976 2977/4565/2977 2978/2306/2978 2979/4566/2979 \nf 2963/1220/2963 2962/4557/2962 2978/2306/2978 2977/4565/2977 \nf 2961/623/2961 2975/4563/2975 2978/2306/2978 2962/4557/2962 \nf 2974/1219/2974 2979/4566/2979 2978/2306/2978 2975/4563/2975 \nf 2964/102/2964 2980/4567/2980 2981/2307/2981 2965/4559/2965 \nf 2982/1221/2982 2983/4569/2983 2981/2307/2981 2980/4567/2980 \nf 2984/624/2984 2985/4570/2985 2981/2307/2981 2983/4569/2983 \nf 2968/1218/2968 2965/4559/2965 2981/2307/2981 2985/4570/2985 \nf 2986/105/2986 2987/4571/2987 2988/2308/2988 2989/4574/2989 \nf 2990/1223/2990 2991/4573/2991 2988/2308/2988 2987/4571/2987 \nf 2984/624/2984 2983/4569/2983 2988/2308/2988 2991/4573/2991 \nf 2982/1221/2982 2989/4574/2989 2988/2308/2988 2983/4569/2983 \nf 2992/106/2992 2993/4576/2993 2994/2309/2994 2995/4578/2995 \nf 2996/1225/2996 2997/4577/2997 2994/2309/2994 2993/4576/2993 \nf 2984/624/2984 2991/4573/2991 2994/2309/2994 2997/4577/2997 \nf 2990/1223/2990 2995/4578/2995 2994/2309/2994 2991/4573/2991 \nf 2970/103/2970 2973/4564/2973 2998/2310/2998 2999/4580/2999 \nf 2968/1218/2968 2985/4570/2985 2998/2310/2998 2973/4564/2973 \nf 2984/624/2984 2997/4577/2997 2998/2310/2998 2985/4570/2985 \nf 2996/1225/2996 2999/4580/2999 2998/2310/2998 2997/4577/2997 \nf 3000/109/3000 3001/4581/3001 3002/2311/3002 3003/4584/3003 \nf 3004/1226/3004 3005/4582/3005 3002/2311/3002 3001/4581/3001 \nf 3006/625/3006 3007/4583/3007 3002/2311/3002 3005/4582/3005 \nf 3008/1228/3008 3003/4584/3003 3002/2311/3002 3007/4583/3007 \nf 3009/111/3009 3010/4586/3010 3011/2312/3011 3012/4588/3012 \nf 3013/1227/3013 3014/4587/3014 3011/2312/3011 3010/4586/3010 \nf 3006/625/3006 3005/4582/3005 3011/2312/3011 3014/4587/3014 \nf 3004/1226/3004 3012/4588/3012 3011/2312/3011 3005/4582/3005 \nf 2970/103/2970 2999/4580/2999 3015/2313/3015 3016/4590/3016 \nf 2996/1225/2996 3017/4589/3017 3015/2313/3015 2999/4580/2999 \nf 3006/625/3006 3014/4587/3014 3015/2313/3015 3017/4589/3017 \nf 3013/1227/3013 3016/4590/3016 3015/2313/3015 3014/4587/3014 \nf 2992/106/2992 3018/4591/3018 3019/2314/3019 2993/4576/2993 \nf 3008/1228/3008 3007/4583/3007 3019/2314/3019 3018/4591/3018 \nf 3006/625/3006 3017/4589/3017 3019/2314/3019 3007/4583/3007 \nf 2996/1225/2996 2993/4576/2993 3019/2314/3019 3017/4589/3017 \nf 3009/111/3009 3020/4593/3020 3021/2315/3021 3010/4586/3010 \nf 3022/1230/3022 3023/4594/3023 3021/2315/3021 3020/4593/3020 \nf 3024/626/3024 3025/4595/3025 3021/2315/3021 3023/4594/3023 \nf 3013/1227/3013 3010/4586/3010 3021/2315/3021 3025/4595/3025 \nf 3026/112/3026 3027/4596/3027 3028/2316/3028 3029/4598/3029 \nf 3030/1231/3030 3031/4597/3031 3028/2316/3028 3027/4596/3027 \nf 3024/626/3024 3023/4594/3023 3028/2316/3028 3031/4597/3031 \nf 3022/1230/3022 3029/4598/3029 3028/2316/3028 3023/4594/3023 \nf 2976/104/2976 2979/4566/2979 3032/2317/3032 3033/4600/3033 \nf 2974/1219/2974 3034/4599/3034 3032/2317/3032 2979/4566/2979 \nf 3024/626/3024 3031/4597/3031 3032/2317/3032 3034/4599/3034 \nf 3030/1231/3030 3033/4600/3033 3032/2317/3032 3031/4597/3031 \nf 2970/103/2970 3016/4590/3016 3035/2318/3035 2971/4562/2971 \nf 3013/1227/3013 3025/4595/3025 3035/2318/3035 3016/4590/3016 \nf 3024/626/3024 3034/4599/3034 3035/2318/3035 3025/4595/3025 \nf 2974/1219/2974 2971/4562/2971 3035/2318/3035 3034/4599/3034 \nf 2905/96/2905 2908/4528/2908 3036/2319/3036 3037/4603/3037 \nf 2901/1207/2901 3038/4601/3038 3036/2319/3036 2908/4528/2908 \nf 3039/627/3039 3040/4602/3040 3036/2319/3036 3038/4601/3038 \nf 3041/1234/3041 3037/4603/3037 3036/2319/3036 3040/4602/3040 \nf 2883/92/2883 3042/4604/3042 3043/2320/3043 2899/4523/2899 \nf 3044/1232/3044 3045/4605/3045 3043/2320/3043 3042/4604/3042 \nf 3039/627/3039 3038/4601/3038 3043/2320/3043 3045/4605/3045 \nf 2901/1207/2901 2899/4523/2899 3043/2320/3043 3038/4601/3038 \nf 3046/114/3046 3047/4606/3047 3048/2321/3048 3049/4608/3049 \nf 3050/1233/3050 3051/4607/3051 3048/2321/3048 3047/4606/3047 \nf 3039/627/3039 3045/4605/3045 3048/2321/3048 3051/4607/3051 \nf 3044/1232/3044 3049/4608/3049 3048/2321/3048 3045/4605/3045 \nf 3052/116/3052 3053/4609/3053 3054/2322/3054 3055/4610/3055 \nf 3041/1234/3041 3040/4602/3040 3054/2322/3054 3053/4609/3053 \nf 3039/627/3039 3051/4607/3051 3054/2322/3054 3040/4602/3040 \nf 3050/1233/3050 3055/4610/3055 3054/2322/3054 3051/4607/3051 \nf 2883/92/2883 2886/4517/2886 3056/2323/3056 3042/4604/3042 \nf 2878/1203/2878 3057/4611/3057 3056/2323/3056 2886/4517/2886 \nf 3058/628/3058 3059/4612/3059 3056/2323/3056 3057/4611/3057 \nf 3044/1232/3044 3042/4604/3042 3056/2323/3056 3059/4612/3059 \nf 2874/89/2874 3060/4613/3060 3061/2324/3061 2875/4511/2875 \nf 3062/1235/3062 3063/4614/3063 3061/2324/3061 3060/4613/3060 \nf 3058/628/3058 3057/4611/3057 3061/2324/3061 3063/4614/3063 \nf 2878/1203/2878 2875/4511/2875 3061/2324/3061 3057/4611/3057 \nf 3064/118/3064 3065/4615/3065 3066/2325/3066 3067/4617/3067 \nf 3068/1236/3068 3069/4616/3069 3066/2325/3066 3065/4615/3065 \nf 3058/628/3058 3063/4614/3063 3066/2325/3066 3069/4616/3069 \nf 3062/1235/3062 3067/4617/3067 3066/2325/3066 3063/4614/3063 \nf 3046/114/3046 3049/4608/3049 3070/2326/3070 3071/4618/3071 \nf 3044/1232/3044 3059/4612/3059 3070/2326/3070 3049/4608/3049 \nf 3058/628/3058 3069/4616/3069 3070/2326/3070 3059/4612/3059 \nf 3068/1236/3068 3071/4618/3071 3070/2326/3070 3069/4616/3069 \nf 3072/119/3072 3073/4619/3073 3074/2327/3074 3075/4622/3075 \nf 3076/1237/3076 3077/4620/3077 3074/2327/3074 3073/4619/3073 \nf 3078/629/3078 3079/4621/3079 3074/2327/3074 3077/4620/3077 \nf 3080/1239/3080 3075/4622/3075 3074/2327/3074 3079/4621/3079 \nf 3081/120/3081 3082/4623/3082 3083/2328/3083 3084/4625/3084 \nf 3085/1238/3085 3086/4624/3086 3083/2328/3083 3082/4623/3082 \nf 3078/629/3078 3077/4620/3077 3083/2328/3083 3086/4624/3086 \nf 3076/1237/3076 3084/4625/3084 3083/2328/3083 3077/4620/3077 \nf 3046/114/3046 3071/4618/3071 3087/2329/3087 3088/4627/3088 \nf 3068/1236/3068 3089/4626/3089 3087/2329/3087 3071/4618/3071 \nf 3078/629/3078 3086/4624/3086 3087/2329/3087 3089/4626/3089 \nf 3085/1238/3085 3088/4627/3088 3087/2329/3087 3086/4624/3086 \nf 3064/118/3064 3090/4628/3090 3091/2330/3091 3065/4615/3065 \nf 3080/1239/3080 3079/4621/3079 3091/2330/3091 3090/4628/3090 \nf 3078/629/3078 3089/4626/3089 3091/2330/3091 3079/4621/3079 \nf 3068/1236/3068 3065/4615/3065 3091/2330/3091 3089/4626/3089 \nf 3081/120/3081 3092/4629/3092 3093/2331/3093 3082/4623/3082 \nf 3094/1240/3094 3095/4630/3095 3093/2331/3093 3092/4629/3092 \nf 3096/630/3096 3097/4631/3097 3093/2331/3093 3095/4630/3095 \nf 3085/1238/3085 3082/4623/3082 3093/2331/3093 3097/4631/3097 \nf 3098/121/3098 3099/4632/3099 3100/2332/3100 3101/4634/3101 \nf 3102/1241/3102 3103/4633/3103 3100/2332/3100 3099/4632/3099 \nf 3096/630/3096 3095/4630/3095 3100/2332/3100 3103/4633/3103 \nf 3094/1240/3094 3101/4634/3101 3100/2332/3100 3095/4630/3095 \nf 3052/116/3052 3055/4610/3055 3104/2333/3104 3105/4636/3105 \nf 3050/1233/3050 3106/4635/3106 3104/2333/3104 3055/4610/3055 \nf 3096/630/3096 3103/4633/3103 3104/2333/3104 3106/4635/3106 \nf 3102/1241/3102 3105/4636/3105 3104/2333/3104 3103/4633/3103 \nf 3046/114/3046 3088/4627/3088 3107/2334/3107 3047/4606/3047 \nf 3085/1238/3085 3097/4631/3097 3107/2334/3107 3088/4627/3088 \nf 3096/630/3096 3106/4635/3106 3107/2334/3107 3097/4631/3097 \nf 3050/1233/3050 3047/4606/3047 3107/2334/3107 3106/4635/3106 \nf 3108/130/3108 3109/4637/3109 3110/2335/3110 3111/4640/3111 \nf 3112/1242/3112 3113/4638/3113 3110/2335/3110 3109/4637/3109 \nf 3114/631/3114 3115/4639/3115 3110/2335/3110 3113/4638/3113 \nf 3116/1245/3116 3111/4640/3111 3110/2335/3110 3115/4639/3115 \nf 3117/132/3117 3118/4641/3118 3119/2336/3119 3120/4643/3120 \nf 3121/1243/3121 3122/4642/3122 3119/2336/3119 3118/4641/3118 \nf 3114/631/3114 3113/4638/3113 3119/2336/3119 3122/4642/3122 \nf 3112/1242/3112 3120/4643/3120 3119/2336/3119 3113/4638/3113 \nf 3123/133/3123 3124/4644/3124 3125/2337/3125 3126/4646/3126 \nf 3127/1244/3127 3128/4645/3128 3125/2337/3125 3124/4644/3124 \nf 3114/631/3114 3122/4642/3122 3125/2337/3125 3128/4645/3128 \nf 3121/1243/3121 3126/4646/3126 3125/2337/3125 3122/4642/3122 \nf 3129/134/3129 3130/4647/3130 3131/2338/3131 3132/4648/3132 \nf 3116/1245/3116 3115/4639/3115 3131/2338/3131 3130/4647/3130 \nf 3114/631/3114 3128/4645/3128 3131/2338/3131 3115/4639/3115 \nf 3127/1244/3127 3132/4648/3132 3131/2338/3131 3128/4645/3128 \nf 3117/132/3117 3133/4649/3133 3134/2339/3134 3118/4641/3118 \nf 3135/1246/3135 3136/4650/3136 3134/2339/3134 3133/4649/3133 \nf 3137/632/3137 3138/4651/3138 3134/2339/3134 3136/4650/3136 \nf 3121/1243/3121 3118/4641/3118 3134/2339/3134 3138/4651/3138 \nf 3139/137/3139 3140/4652/3140 3141/2340/3141 3142/4654/3142 \nf 3143/1247/3143 3144/4653/3144 3141/2340/3141 3140/4652/3140 \nf 3137/632/3137 3136/4650/3136 3141/2340/3141 3144/4653/3144 \nf 3135/1246/3135 3142/4654/3142 3141/2340/3141 3136/4650/3136 \nf 3145/138/3145 3146/4655/3146 3147/2341/3147 3148/4657/3148 \nf 3149/1248/3149 3150/4656/3150 3147/2341/3147 3146/4655/3146 \nf 3137/632/3137 3144/4653/3144 3147/2341/3147 3150/4656/3150 \nf 3143/1247/3143 3148/4657/3148 3147/2341/3147 3144/4653/3144 \nf 3123/133/3123 3126/4646/3126 3151/2342/3151 3152/4658/3152 \nf 3121/1243/3121 3138/4651/3138 3151/2342/3151 3126/4646/3126 \nf 3137/632/3137 3150/4656/3150 3151/2342/3151 3138/4651/3138 \nf 3149/1248/3149 3152/4658/3152 3151/2342/3151 3150/4656/3150 \nf 3026/112/3026 3153/4659/3153 3154/2343/3154 3155/4662/3155 \nf 3156/1249/3156 3157/4660/3157 3154/2343/3154 3153/4659/3153 \nf 3158/633/3158 3159/4661/3159 3154/2343/3154 3157/4660/3157 \nf 3160/1251/3160 3155/4662/3155 3154/2343/3154 3159/4661/3159 \nf 3161/140/3161 3162/4663/3162 3163/2344/3163 3164/4665/3164 \nf 3165/1250/3165 3166/4664/3166 3163/2344/3163 3162/4663/3162 \nf 3158/633/3158 3157/4660/3157 3163/2344/3163 3166/4664/3166 \nf 3156/1249/3156 3164/4665/3164 3163/2344/3163 3157/4660/3157 \nf 3123/133/3123 3152/4658/3152 3167/2345/3167 3168/4667/3168 \nf 3149/1248/3149 3169/4666/3169 3167/2345/3167 3152/4658/3152 \nf 3158/633/3158 3166/4664/3166 3167/2345/3167 3169/4666/3169 \nf 3165/1250/3165 3168/4667/3168 3167/2345/3167 3166/4664/3166 \nf 3145/138/3145 3170/4668/3170 3171/2346/3171 3146/4655/3146 \nf 3160/1251/3160 3159/4661/3159 3171/2346/3171 3170/4668/3170 \nf 3158/633/3158 3169/4666/3169 3171/2346/3171 3159/4661/3159 \nf 3149/1248/3149 3146/4655/3146 3171/2346/3171 3169/4666/3169 \nf 3161/140/3161 3172/4669/3172 3173/2347/3173 3162/4663/3162 \nf 3174/1252/3174 3175/4670/3175 3173/2347/3173 3172/4669/3172 \nf 3176/634/3176 3177/4671/3177 3173/2347/3173 3175/4670/3175 \nf 3165/1250/3165 3162/4663/3162 3173/2347/3173 3177/4671/3177 \nf 3178/141/3178 3179/4672/3179 3180/2348/3180 3181/4674/3181 \nf 3182/1253/3182 3183/4673/3183 3180/2348/3180 3179/4672/3179 \nf 3176/634/3176 3175/4670/3175 3180/2348/3180 3183/4673/3183 \nf 3174/1252/3174 3181/4674/3181 3180/2348/3180 3175/4670/3175 \nf 3129/134/3129 3132/4648/3132 3184/2349/3184 3185/4676/3185 \nf 3127/1244/3127 3186/4675/3186 3184/2349/3184 3132/4648/3132 \nf 3176/634/3176 3183/4673/3183 3184/2349/3184 3186/4675/3186 \nf 3182/1253/3182 3185/4676/3185 3184/2349/3184 3183/4673/3183 \nf 3123/133/3123 3168/4667/3168 3187/2350/3187 3124/4644/3124 \nf 3165/1250/3165 3177/4671/3177 3187/2350/3187 3168/4667/3168 \nf 3176/634/3176 3186/4675/3186 3187/2350/3187 3177/4671/3177 \nf 3127/1244/3127 3124/4644/3124 3187/2350/3187 3186/4675/3186 \nf 3188/142/3188 3189/4677/3189 3190/2351/3190 3191/4680/3191 \nf 3192/1254/3192 3193/4678/3193 3190/2351/3190 3189/4677/3189 \nf 3194/635/3194 3195/4679/3195 3190/2351/3190 3193/4678/3193 \nf 3196/1258/3196 3191/4680/3191 3190/2351/3190 3195/4679/3195 \nf 3197/143/3197 3198/4681/3198 3199/2352/3199 3200/4684/3200 \nf 3201/1255/3201 3202/4683/3202 3199/2352/3199 3198/4681/3198 \nf 3194/635/3194 3193/4678/3193 3199/2352/3199 3202/4683/3202 \nf 3192/1254/3192 3200/4684/3200 3199/2352/3199 3193/4678/3193 \nf 3203/144/3203 3204/4685/3204 3205/2353/3205 3206/4687/3206 \nf 3207/1257/3207 3208/4686/3208 3205/2353/3205 3204/4685/3204 \nf 3194/635/3194 3202/4683/3202 3205/2353/3205 3208/4686/3208 \nf 3201/1255/3201 3206/4687/3206 3205/2353/3205 3202/4683/3202 \nf 3209/145/3209 3210/4689/3210 3211/2354/3211 3212/4690/3212 \nf 3196/1258/3196 3195/4679/3195 3211/2354/3211 3210/4689/3210 \nf 3194/635/3194 3208/4686/3208 3211/2354/3211 3195/4679/3195 \nf 3207/1257/3207 3212/4690/3212 3211/2354/3211 3208/4686/3208 \nf 3197/386/3197 3213/4691/3213 3214/2355/3214 3198/4682/3198 \nf 3215/1259/3215 3216/4692/3216 3214/2355/3214 3213/4691/3213 \nf 3217/636/3217 3218/4693/3218 3214/2355/3214 3216/4692/3216 \nf 3201/1256/3201 3198/4682/3198 3214/2355/3214 3218/4693/3218 \nf 3219/387/3219 3220/4694/3220 3221/2356/3221 3222/4696/3222 \nf 3223/1260/3223 3224/4695/3224 3221/2356/3221 3220/4694/3220 \nf 3217/636/3217 3216/4692/3216 3221/2356/3221 3224/4695/3224 \nf 3215/1259/3215 3222/4696/3222 3221/2356/3221 3216/4692/3216 \nf 3225/413/3225 3226/4697/3226 3227/2357/3227 3228/4699/3228 \nf 3229/1261/3229 3230/4698/3230 3227/2357/3227 3226/4697/3226 \nf 3217/636/3217 3224/4695/3224 3227/2357/3227 3230/4698/3230 \nf 3223/1260/3223 3228/4699/3228 3227/2357/3227 3224/4695/3224 \nf 3203/414/3203 3206/4688/3206 3231/2358/3231 3232/4700/3232 \nf 3201/1256/3201 3218/4693/3218 3231/2358/3231 3206/4688/3206 \nf 3217/636/3217 3230/4698/3230 3231/2358/3231 3218/4693/3218 \nf 3229/1261/3229 3232/4700/3232 3231/2358/3231 3230/4698/3230 \nf 2986/417/2986 2989/4575/2989 3233/2359/3233 3234/4703/3234 \nf 2982/1222/2982 3235/4701/3235 3233/2359/3233 2989/4575/2989 \nf 3236/637/3236 3237/4702/3237 3233/2359/3233 3235/4701/3235 \nf 3238/1264/3238 3234/4703/3234 3233/2359/3233 3237/4702/3237 \nf 2964/418/2964 3239/4704/3239 3240/2360/3240 2980/4568/2980 \nf 3241/1262/3241 3242/4706/3242 3240/2360/3240 3239/4704/3239 \nf 3236/637/3236 3235/4701/3235 3240/2360/3240 3242/4706/3242 \nf 2982/1222/2982 2980/4568/2980 3240/2360/3240 3235/4701/3235 \nf 3203/414/3203 3232/4700/3232 3243/2361/3243 3244/4708/3244 \nf 3229/1261/3229 3245/4707/3245 3243/2361/3243 3232/4700/3232 \nf 3236/637/3236 3242/4706/3242 3243/2361/3243 3245/4707/3245 \nf 3241/1262/3241 3244/4708/3244 3243/2361/3243 3242/4706/3242 \nf 3225/413/3225 3246/4710/3246 3247/2362/3247 3226/4697/3226 \nf 3238/1264/3238 3237/4702/3237 3247/2362/3247 3246/4710/3246 \nf 3236/637/3236 3245/4707/3245 3247/2362/3247 3237/4702/3237 \nf 3229/1261/3229 3226/4697/3226 3247/2362/3247 3245/4707/3245 \nf 2964/102/2964 2967/4561/2967 3248/2363/3248 3239/4705/3239 \nf 2959/1217/2959 3249/4711/3249 3248/2363/3248 2967/4561/2967 \nf 3250/638/3250 3251/4712/3251 3248/2363/3248 3249/4711/3249 \nf 3241/1263/3241 3239/4705/3239 3248/2363/3248 3251/4712/3251 \nf 2955/101/2955 3252/4713/3252 3253/2364/3253 2956/4555/2956 \nf 3254/1265/3254 3255/4714/3255 3253/2364/3253 3252/4713/3252 \nf 3250/638/3250 3249/4711/3249 3253/2364/3253 3255/4714/3255 \nf 2959/1217/2959 2956/4555/2956 3253/2364/3253 3249/4711/3249 \nf 3209/145/3209 3212/4690/3212 3256/2365/3256 3257/4716/3257 \nf 3207/1257/3207 3258/4715/3258 3256/2365/3256 3212/4690/3212 \nf 3250/638/3250 3255/4714/3255 3256/2365/3256 3258/4715/3258 \nf 3254/1265/3254 3257/4716/3257 3256/2365/3256 3255/4714/3255 \nf 3203/144/3203 3244/4709/3244 3259/2366/3259 3204/4685/3204 \nf 3241/1263/3241 3251/4712/3251 3259/2366/3259 3244/4709/3244 \nf 3250/638/3250 3258/4715/3258 3259/2366/3259 3251/4712/3251 \nf 3207/1257/3207 3204/4685/3204 3259/2366/3259 3258/4715/3258 \nf 3026/112/3026 3029/4598/3029 3260/2367/3260 3153/4659/3153 \nf 3022/1230/3022 3261/4717/3261 3260/2367/3260 3029/4598/3029 \nf 3262/639/3262 3263/4718/3263 3260/2367/3260 3261/4717/3261 \nf 3156/1249/3156 3153/4659/3153 3260/2367/3260 3263/4718/3263 \nf 3009/111/3009 3264/4719/3264 3265/2368/3265 3020/4593/3020 \nf 3266/1266/3266 3267/4720/3267 3265/2368/3265 3264/4719/3264 \nf 3262/639/3262 3261/4717/3261 3265/2368/3265 3267/4720/3267 \nf 3022/1230/3022 3020/4593/3020 3265/2368/3265 3261/4717/3261 \nf 3268/146/3268 3269/4721/3269 3270/2369/3270 3271/4723/3271 \nf 3272/1267/3272 3273/4722/3273 3270/2369/3270 3269/4721/3269 \nf 3262/639/3262 3267/4720/3267 3270/2369/3270 3273/4722/3273 \nf 3266/1266/3266 3271/4723/3271 3270/2369/3270 3267/4720/3267 \nf 3161/140/3161 3164/4665/3164 3274/2370/3274 3275/4724/3275 \nf 3156/1249/3156 3263/4718/3263 3274/2370/3274 3164/4665/3164 \nf 3262/639/3262 3273/4722/3273 3274/2370/3274 3263/4718/3263 \nf 3272/1267/3272 3275/4724/3275 3274/2370/3274 3273/4722/3273 \nf 3009/111/3009 3012/4588/3012 3276/2371/3276 3264/4719/3264 \nf 3004/1226/3004 3277/4725/3277 3276/2371/3276 3012/4588/3012 \nf 3278/640/3278 3279/4726/3279 3276/2371/3276 3277/4725/3277 \nf 3266/1266/3266 3264/4719/3264 3276/2371/3276 3279/4726/3279 \nf 3000/109/3000 3280/4727/3280 3281/2372/3281 3001/4581/3001 \nf 3282/1268/3282 3283/4729/3283 3281/2372/3281 3280/4727/3280 \nf 3278/640/3278 3277/4725/3277 3281/2372/3281 3283/4729/3283 \nf 3004/1226/3004 3001/4581/3001 3281/2372/3281 3277/4725/3277 \nf 3284/147/3284 3285/4730/3285 3286/2373/3286 3287/4732/3287 \nf 3288/1270/3288 3289/4731/3289 3286/2373/3286 3285/4730/3285 \nf 3278/640/3278 3283/4729/3283 3286/2373/3286 3289/4731/3289 \nf 3282/1268/3282 3287/4732/3287 3286/2373/3286 3283/4729/3283 \nf 3268/146/3268 3271/4723/3271 3290/2374/3290 3291/4734/3291 \nf 3266/1266/3266 3279/4726/3279 3290/2374/3290 3271/4723/3271 \nf 3278/640/3278 3289/4731/3289 3290/2374/3290 3279/4726/3279 \nf 3288/1270/3288 3291/4734/3291 3290/2374/3290 3289/4731/3289 \nf 3292/148/3292 3293/4735/3293 3294/2375/3294 3295/4738/3295 \nf 3296/1271/3296 3297/4736/3297 3294/2375/3294 3293/4735/3293 \nf 3298/641/3298 3299/4737/3299 3294/2375/3294 3297/4736/3297 \nf 3300/1273/3300 3295/4738/3295 3294/2375/3294 3299/4737/3299 \nf 3301/149/3301 3302/4740/3302 3303/2376/3303 3304/4742/3304 \nf 3305/1272/3305 3306/4741/3306 3303/2376/3303 3302/4740/3302 \nf 3298/641/3298 3297/4736/3297 3303/2376/3303 3306/4741/3306 \nf 3296/1271/3296 3304/4742/3304 3303/2376/3303 3297/4736/3297 \nf 3268/146/3268 3291/4734/3291 3307/2377/3307 3308/4744/3308 \nf 3288/1270/3288 3309/4743/3309 3307/2377/3307 3291/4734/3291 \nf 3298/641/3298 3306/4741/3306 3307/2377/3307 3309/4743/3309 \nf 3305/1272/3305 3308/4744/3308 3307/2377/3307 3306/4741/3306 \nf 3284/147/3284 3310/4745/3310 3311/2378/3311 3285/4730/3285 \nf 3300/1273/3300 3299/4737/3299 3311/2378/3311 3310/4745/3310 \nf 3298/641/3298 3309/4743/3309 3311/2378/3311 3299/4737/3299 \nf 3288/1270/3288 3285/4730/3285 3311/2378/3311 3309/4743/3309 \nf 3301/149/3301 3312/4747/3312 3313/2379/3313 3302/4740/3302 \nf 3314/1275/3314 3315/4748/3315 3313/2379/3313 3312/4747/3312 \nf 3316/642/3316 3317/4749/3317 3313/2379/3313 3315/4748/3315 \nf 3305/1272/3305 3302/4740/3302 3313/2379/3313 3317/4749/3317 \nf 3178/141/3178 3181/4674/3181 3318/2380/3318 3319/4751/3319 \nf 3174/1252/3174 3320/4750/3320 3318/2380/3318 3181/4674/3181 \nf 3316/642/3316 3315/4748/3315 3318/2380/3318 3320/4750/3320 \nf 3314/1275/3314 3319/4751/3319 3318/2380/3318 3315/4748/3315 \nf 3161/140/3161 3275/4724/3275 3321/2381/3321 3172/4669/3172 \nf 3272/1267/3272 3322/4752/3322 3321/2381/3321 3275/4724/3275 \nf 3316/642/3316 3320/4750/3320 3321/2381/3321 3322/4752/3322 \nf 3174/1252/3174 3172/4669/3172 3321/2381/3321 3320/4750/3320 \nf 3268/146/3268 3308/4744/3308 3323/2382/3323 3269/4721/3269 \nf 3305/1272/3305 3317/4749/3317 3323/2382/3323 3308/4744/3308 \nf 3316/642/3316 3322/4752/3322 3323/2382/3323 3317/4749/3317 \nf 3272/1267/3272 3269/4721/3269 3323/2382/3323 3322/4752/3322 \nf 3026/112/3026 3155/4662/3155 3324/2383/3324 3027/4596/3027 \nf 3160/1251/3160 3325/4753/3325 3324/2383/3324 3155/4662/3155 \nf 3326/643/3326 3327/4754/3327 3324/2383/3324 3325/4753/3325 \nf 3030/1231/3030 3027/4596/3027 3324/2383/3324 3327/4754/3327 \nf 3145/138/3145 3328/4755/3328 3329/2384/3329 3170/4668/3170 \nf 3330/1276/3330 3331/4756/3331 3329/2384/3329 3328/4755/3328 \nf 3326/643/3326 3325/4753/3325 3329/2384/3329 3331/4756/3331 \nf 3160/1251/3160 3170/4668/3170 3329/2384/3329 3325/4753/3325 \nf 3332/152/3332 3333/4757/3333 3334/2385/3334 3335/4759/3335 \nf 3336/1277/3336 3337/4758/3337 3334/2385/3334 3333/4757/3333 \nf 3326/643/3326 3331/4756/3331 3334/2385/3334 3337/4758/3337 \nf 3330/1276/3330 3335/4759/3335 3334/2385/3334 3331/4756/3331 \nf 2976/104/2976 3033/4600/3033 3338/2386/3338 3339/4760/3339 \nf 3030/1231/3030 3327/4754/3327 3338/2386/3338 3033/4600/3033 \nf 3326/643/3326 3337/4758/3337 3338/2386/3338 3327/4754/3327 \nf 3336/1277/3336 3339/4760/3339 3338/2386/3338 3337/4758/3337 \nf 3145/138/3145 3148/4657/3148 3340/2387/3340 3328/4755/3328 \nf 3143/1247/3143 3341/4761/3341 3340/2387/3340 3148/4657/3148 \nf 3342/644/3342 3343/4762/3343 3340/2387/3340 3341/4761/3341 \nf 3330/1276/3330 3328/4755/3328 3340/2387/3340 3343/4762/3343 \nf 3139/137/3139 3344/4763/3344 3345/2388/3345 3140/4652/3140 \nf 3346/1278/3346 3347/4764/3347 3345/2388/3345 3344/4763/3344 \nf 3342/644/3342 3341/4761/3341 3345/2388/3345 3347/4764/3347 \nf 3143/1247/3143 3140/4652/3140 3345/2388/3345 3341/4761/3341 \nf 3348/154/3348 3349/4765/3349 3350/2389/3350 3351/4767/3351 \nf 3352/1279/3352 3353/4766/3353 3350/2389/3350 3349/4765/3349 \nf 3342/644/3342 3347/4764/3347 3350/2389/3350 3353/4766/3353 \nf 3346/1278/3346 3351/4767/3351 3350/2389/3350 3347/4764/3347 \nf 3332/152/3332 3335/4759/3335 3354/2390/3354 3355/4768/3355 \nf 3330/1276/3330 3343/4762/3343 3354/2390/3354 3335/4759/3335 \nf 3342/644/3342 3353/4766/3353 3354/2390/3354 3343/4762/3343 \nf 3352/1279/3352 3355/4768/3355 3354/2390/3354 3353/4766/3353 \nf 3188/142/3188 3191/4680/3191 3356/2391/3356 3357/4771/3357 \nf 3196/1258/3196 3358/4769/3358 3356/2391/3356 3191/4680/3191 \nf 3359/645/3359 3360/4770/3360 3356/2391/3356 3358/4769/3358 \nf 3361/1281/3361 3357/4771/3357 3356/2391/3356 3360/4770/3360 \nf 3209/145/3209 3362/4772/3362 3363/2392/3363 3210/4689/3210 \nf 3364/1280/3364 3365/4773/3365 3363/2392/3363 3362/4772/3362 \nf 3359/645/3359 3358/4769/3358 3363/2392/3363 3365/4773/3365 \nf 3196/1258/3196 3210/4689/3210 3363/2392/3363 3358/4769/3358 \nf 3332/152/3332 3355/4768/3355 3366/2393/3366 3367/4775/3367 \nf 3352/1279/3352 3368/4774/3368 3366/2393/3366 3355/4768/3355 \nf 3359/645/3359 3365/4773/3365 3366/2393/3366 3368/4774/3368 \nf 3364/1280/3364 3367/4775/3367 3366/2393/3366 3365/4773/3365 \nf 3348/154/3348 3369/4776/3369 3370/2394/3370 3349/4765/3349 \nf 3361/1281/3361 3360/4770/3360 3370/2394/3370 3369/4776/3369 \nf 3359/645/3359 3368/4774/3368 3370/2394/3370 3360/4770/3360 \nf 3352/1279/3352 3349/4765/3349 3370/2394/3370 3368/4774/3368 \nf 3209/145/3209 3257/4716/3257 3371/2395/3371 3362/4772/3362 \nf 3254/1265/3254 3372/4777/3372 3371/2395/3371 3257/4716/3257 \nf 3373/646/3373 3374/4778/3374 3371/2395/3371 3372/4777/3372 \nf 3364/1280/3364 3362/4772/3362 3371/2395/3371 3374/4778/3374 \nf 2955/101/2955 2958/4558/2958 3375/2396/3375 3252/4713/3252 \nf 2963/1220/2963 3376/4779/3376 3375/2396/3375 2958/4558/2958 \nf 3373/646/3373 3372/4777/3372 3375/2396/3375 3376/4779/3376 \nf 3254/1265/3254 3252/4713/3252 3375/2396/3375 3372/4777/3372 \nf 2976/104/2976 3339/4760/3339 3377/2397/3377 2977/4565/2977 \nf 3336/1277/3336 3378/4780/3378 3377/2397/3377 3339/4760/3339 \nf 3373/646/3373 3376/4779/3376 3377/2397/3377 3378/4780/3378 \nf 2963/1220/2963 2977/4565/2977 3377/2397/3377 3376/4779/3376 \nf 3332/152/3332 3367/4775/3367 3379/2398/3379 3333/4757/3333 \nf 3364/1280/3364 3374/4778/3374 3379/2398/3379 3367/4775/3367 \nf 3373/646/3373 3378/4780/3378 3379/2398/3379 3374/4778/3374 \nf 3336/1277/3336 3333/4757/3333 3379/2398/3379 3378/4780/3378 \nf 507/41/507 510/3264/510 3380/2399/3380 3381/4783/3381 \nf 515/877/515 3382/4781/3382 3380/2399/3380 510/3264/510 \nf 3383/647/3383 3384/4782/3384 3380/2399/3380 3382/4781/3382 \nf 3385/1284/3385 3381/4783/3381 3380/2399/3380 3384/4782/3384 \nf 528/113/528 3386/4784/3386 3387/2400/3387 529/3271/529 \nf 3388/1282/3388 3389/4785/3389 3387/2400/3387 3386/4784/3386 \nf 3383/647/3383 3382/4781/3382 3387/2400/3387 3389/4785/3389 \nf 515/877/515 529/3271/529 3387/2400/3387 3382/4781/3382 \nf 3390/419/3390 3391/4786/3391 3392/2401/3392 3393/4788/3393 \nf 3394/1283/3394 3395/4787/3395 3392/2401/3392 3391/4786/3391 \nf 3383/647/3383 3389/4785/3389 3392/2401/3392 3395/4787/3395 \nf 3388/1282/3388 3393/4788/3393 3392/2401/3392 3389/4785/3389 \nf 3396/420/3396 3397/4789/3397 3398/2402/3398 3399/4790/3399 \nf 3385/1284/3385 3384/4782/3384 3398/2402/3398 3397/4789/3397 \nf 3383/647/3383 3395/4787/3395 3398/2402/3398 3384/4782/3384 \nf 3394/1283/3394 3399/4790/3399 3398/2402/3398 3395/4787/3395 \nf 528/113/528 583/3304/583 3400/2403/3400 3386/4784/3386 \nf 580/887/580 3401/4791/3401 3400/2403/3400 583/3304/583 \nf 3402/648/3402 3403/4792/3403 3400/2403/3400 3401/4791/3401 \nf 3388/1282/3388 3386/4784/3386 3400/2403/3400 3403/4792/3403 \nf 576/128/576 3404/4793/3404 3405/2404/3405 577/3300/577 \nf 3406/1285/3406 3407/4794/3407 3405/2404/3405 3404/4793/3404 \nf 3402/648/3402 3401/4791/3401 3405/2404/3405 3407/4794/3407 \nf 580/887/580 577/3300/577 3405/2404/3405 3401/4791/3401 \nf 3408/434/3408 3409/4795/3409 3410/2405/3410 3411/4797/3411 \nf 3412/1286/3412 3413/4796/3413 3410/2405/3410 3409/4795/3409 \nf 3402/648/3402 3407/4794/3407 3410/2405/3410 3413/4796/3413 \nf 3406/1285/3406 3411/4797/3411 3410/2405/3410 3407/4794/3407 \nf 3390/419/3390 3393/4788/3393 3414/2406/3414 3415/4798/3415 \nf 3388/1282/3388 3403/4792/3403 3414/2406/3414 3393/4788/3393 \nf 3402/648/3402 3413/4796/3413 3414/2406/3414 3403/4792/3403 \nf 3412/1286/3412 3415/4798/3415 3414/2406/3414 3413/4796/3413 \nf 3219/387/3219 3416/4799/3416 3417/2407/3417 3418/4802/3418 \nf 3419/1287/3419 3420/4800/3420 3417/2407/3417 3416/4799/3416 \nf 3421/649/3421 3422/4801/3422 3417/2407/3417 3420/4800/3420 \nf 3423/1289/3423 3418/4802/3418 3417/2407/3417 3422/4801/3422 \nf 3424/435/3424 3425/4803/3425 3426/2408/3426 3427/4805/3427 \nf 3428/1288/3428 3429/4804/3429 3426/2408/3426 3425/4803/3425 \nf 3421/649/3421 3420/4800/3420 3426/2408/3426 3429/4804/3429 \nf 3419/1287/3419 3427/4805/3427 3426/2408/3426 3420/4800/3420 \nf 3390/419/3390 3415/4798/3415 3430/2409/3430 3431/4807/3431 \nf 3412/1286/3412 3432/4806/3432 3430/2409/3430 3415/4798/3415 \nf 3421/649/3421 3429/4804/3429 3430/2409/3430 3432/4806/3432 \nf 3428/1288/3428 3431/4807/3431 3430/2409/3430 3429/4804/3429 \nf 3408/434/3408 3433/4808/3433 3434/2410/3434 3409/4795/3409 \nf 3423/1289/3423 3422/4801/3422 3434/2410/3434 3433/4808/3433 \nf 3421/649/3421 3432/4806/3432 3434/2410/3434 3422/4801/3422 \nf 3412/1286/3412 3409/4795/3409 3434/2410/3434 3432/4806/3432 \nf 3424/435/3424 3435/4809/3435 3436/2411/3436 3425/4803/3425 \nf 3437/1290/3437 3438/4811/3438 3436/2411/3436 3435/4809/3435 \nf 3439/650/3439 3440/4812/3440 3436/2411/3436 3438/4811/3438 \nf 3428/1288/3428 3425/4803/3425 3436/2411/3436 3440/4812/3440 \nf 2945/436/2945 3441/4813/3441 3442/2412/3442 3443/4816/3443 \nf 3444/1292/3444 3445/4815/3445 3442/2412/3442 3441/4813/3441 \nf 3439/650/3439 3438/4811/3438 3442/2412/3442 3445/4815/3445 \nf 3437/1290/3437 3443/4816/3443 3442/2412/3442 3438/4811/3438 \nf 3396/420/3396 3399/4790/3399 3446/2413/3446 3447/4819/3447 \nf 3394/1283/3394 3448/4818/3448 3446/2413/3446 3399/4790/3399 \nf 3439/650/3439 3445/4815/3445 3446/2413/3446 3448/4818/3448 \nf 3444/1292/3444 3447/4819/3447 3446/2413/3446 3445/4815/3445 \nf 3390/419/3390 3431/4807/3431 3449/2414/3449 3391/4786/3391 \nf 3428/1288/3428 3440/4812/3440 3449/2414/3449 3431/4807/3431 \nf 3439/650/3439 3448/4818/3448 3449/2414/3449 3440/4812/3440 \nf 3394/1283/3394 3391/4786/3391 3449/2414/3449 3448/4818/3448 \nf 3178/141/3178 3319/4751/3319 3450/2415/3450 3451/4823/3451 \nf 3314/1275/3314 3452/4821/3452 3450/2415/3450 3319/4751/3319 \nf 3453/651/3453 3454/4822/3454 3450/2415/3450 3452/4821/3452 \nf 3455/1296/3455 3451/4823/3451 3450/2415/3450 3454/4822/3454 \nf 3301/149/3301 3456/4824/3456 3457/2416/3457 3312/4747/3312 \nf 3458/1294/3458 3459/4825/3459 3457/2416/3457 3456/4824/3456 \nf 3453/651/3453 3452/4821/3452 3457/2416/3457 3459/4825/3459 \nf 3314/1275/3314 3312/4747/3312 3457/2416/3457 3452/4821/3452 \nf 3460/155/3460 3461/4826/3461 3462/2417/3462 3463/4828/3463 \nf 3464/1295/3464 3465/4827/3465 3462/2417/3462 3461/4826/3461 \nf 3453/651/3453 3459/4825/3459 3462/2417/3462 3465/4827/3465 \nf 3458/1294/3458 3463/4828/3463 3462/2417/3462 3459/4825/3459 \nf 3466/156/3466 3467/4829/3467 3468/2418/3468 3469/4830/3469 \nf 3455/1296/3455 3454/4822/3454 3468/2418/3468 3467/4829/3467 \nf 3453/651/3453 3465/4827/3465 3468/2418/3468 3454/4822/3454 \nf 3464/1295/3464 3469/4830/3469 3468/2418/3468 3465/4827/3465 \nf 3301/149/3301 3304/4742/3304 3470/2419/3470 3456/4824/3456 \nf 3296/1271/3296 3471/4831/3471 3470/2419/3470 3304/4742/3304 \nf 3472/652/3472 3473/4832/3473 3470/2419/3470 3471/4831/3471 \nf 3458/1294/3458 3456/4824/3456 3470/2419/3470 3473/4832/3473 \nf 3292/148/3292 3474/4833/3474 3475/2420/3475 3293/4735/3293 \nf 3476/1297/3476 3477/4835/3477 3475/2420/3475 3474/4833/3474 \nf 3472/652/3472 3471/4831/3471 3475/2420/3475 3477/4835/3477 \nf 3296/1271/3296 3293/4735/3293 3475/2420/3475 3471/4831/3471 \nf 3478/159/3478 3479/4836/3479 3480/2421/3480 3481/4838/3481 \nf 3482/1299/3482 3483/4837/3483 3480/2421/3480 3479/4836/3479 \nf 3472/652/3472 3477/4835/3477 3480/2421/3480 3483/4837/3483 \nf 3476/1297/3476 3481/4838/3481 3480/2421/3480 3477/4835/3477 \nf 3460/155/3460 3463/4828/3463 3484/2422/3484 3485/4840/3485 \nf 3458/1294/3458 3473/4832/3473 3484/2422/3484 3463/4828/3463 \nf 3472/652/3472 3483/4837/3483 3484/2422/3484 3473/4832/3473 \nf 3482/1299/3482 3485/4840/3485 3484/2422/3484 3483/4837/3483 \nf 3486/161/3486 3487/4841/3487 3488/2423/3488 3489/4844/3489 \nf 3490/1300/3490 3491/4842/3491 3488/2423/3488 3487/4841/3487 \nf 3492/653/3492 3493/4843/3493 3488/2423/3488 3491/4842/3491 \nf 3494/1302/3494 3489/4844/3489 3488/2423/3488 3493/4843/3493 \nf 3495/162/3495 3496/4846/3496 3497/2424/3497 3498/4848/3498 \nf 3499/1301/3499 3500/4847/3500 3497/2424/3497 3496/4846/3496 \nf 3492/653/3492 3491/4842/3491 3497/2424/3497 3500/4847/3500 \nf 3490/1300/3490 3498/4848/3498 3497/2424/3497 3491/4842/3491 \nf 3460/155/3460 3485/4840/3485 3501/2425/3501 3502/4850/3502 \nf 3482/1299/3482 3503/4849/3503 3501/2425/3501 3485/4840/3485 \nf 3492/653/3492 3500/4847/3500 3501/2425/3501 3503/4849/3503 \nf 3499/1301/3499 3502/4850/3502 3501/2425/3501 3500/4847/3500 \nf 3478/159/3478 3504/4851/3504 3505/2426/3505 3479/4836/3479 \nf 3494/1302/3494 3493/4843/3493 3505/2426/3505 3504/4851/3504 \nf 3492/653/3492 3503/4849/3503 3505/2426/3505 3493/4843/3493 \nf 3482/1299/3482 3479/4836/3479 3505/2426/3505 3503/4849/3503 \nf 3495/162/3495 3506/4853/3506 3507/2427/3507 3496/4846/3496 \nf 3508/1304/3508 3509/4854/3509 3507/2427/3507 3506/4853/3506 \nf 3510/654/3510 3511/4855/3511 3507/2427/3507 3509/4854/3509 \nf 3499/1301/3499 3496/4846/3496 3507/2427/3507 3511/4855/3511 \nf 3512/163/3512 3513/4856/3513 3514/2428/3514 3515/4858/3515 \nf 3516/1305/3516 3517/4857/3517 3514/2428/3514 3513/4856/3513 \nf 3510/654/3510 3509/4854/3509 3514/2428/3514 3517/4857/3517 \nf 3508/1304/3508 3515/4858/3515 3514/2428/3514 3509/4854/3509 \nf 3466/156/3466 3469/4830/3469 3518/2429/3518 3519/4860/3519 \nf 3464/1295/3464 3520/4859/3520 3518/2429/3518 3469/4830/3469 \nf 3510/654/3510 3517/4857/3517 3518/2429/3518 3520/4859/3520 \nf 3516/1305/3516 3519/4860/3519 3518/2429/3518 3517/4857/3517 \nf 3460/155/3460 3502/4850/3502 3521/2430/3521 3461/4826/3461 \nf 3499/1301/3499 3511/4855/3511 3521/2430/3521 3502/4850/3502 \nf 3510/654/3510 3520/4859/3520 3521/2430/3521 3511/4855/3511 \nf 3464/1295/3464 3461/4826/3461 3521/2430/3521 3520/4859/3520 \nf 2905/96/2905 3037/4603/3037 3522/2431/3522 3523/4863/3523 \nf 3041/1234/3041 3524/4861/3524 3522/2431/3522 3037/4603/3037 \nf 3525/655/3525 3526/4862/3526 3522/2431/3522 3524/4861/3524 \nf 3527/1308/3527 3523/4863/3523 3522/2431/3522 3526/4862/3526 \nf 3052/116/3052 3528/4864/3528 3529/2432/3529 3053/4609/3053 \nf 3530/1306/3530 3531/4865/3531 3529/2432/3529 3528/4864/3528 \nf 3525/655/3525 3524/4861/3524 3529/2432/3529 3531/4865/3531 \nf 3041/1234/3041 3053/4609/3053 3529/2432/3529 3524/4861/3524 \nf 3532/164/3532 3533/4866/3533 3534/2433/3534 3535/4868/3535 \nf 3536/1307/3536 3537/4867/3537 3534/2433/3534 3533/4866/3533 \nf 3525/655/3525 3531/4865/3531 3534/2433/3534 3537/4867/3537 \nf 3530/1306/3530 3535/4868/3535 3534/2433/3534 3531/4865/3531 \nf 3538/165/3538 3539/4869/3539 3540/2434/3540 3541/4870/3541 \nf 3527/1308/3527 3526/4862/3526 3540/2434/3540 3539/4869/3539 \nf 3525/655/3525 3537/4867/3537 3540/2434/3540 3526/4862/3526 \nf 3536/1307/3536 3541/4870/3541 3540/2434/3540 3537/4867/3537 \nf 3052/116/3052 3105/4636/3105 3542/2435/3542 3528/4864/3528 \nf 3102/1241/3102 3543/4871/3543 3542/2435/3542 3105/4636/3105 \nf 3544/656/3544 3545/4872/3545 3542/2435/3542 3543/4871/3543 \nf 3530/1306/3530 3528/4864/3528 3542/2435/3542 3545/4872/3545 \nf 3098/121/3098 3546/4873/3546 3547/2436/3547 3099/4632/3099 \nf 3548/1309/3548 3549/4874/3549 3547/2436/3547 3546/4873/3546 \nf 3544/656/3544 3543/4871/3543 3547/2436/3547 3549/4874/3549 \nf 3102/1241/3102 3099/4632/3099 3547/2436/3547 3543/4871/3543 \nf 3550/174/3550 3551/4875/3551 3552/2437/3552 3553/4877/3553 \nf 3554/1310/3554 3555/4876/3555 3552/2437/3552 3551/4875/3551 \nf 3544/656/3544 3549/4874/3549 3552/2437/3552 3555/4876/3555 \nf 3548/1309/3548 3553/4877/3553 3552/2437/3552 3549/4874/3549 \nf 3532/164/3532 3535/4868/3535 3556/2438/3556 3557/4878/3557 \nf 3530/1306/3530 3545/4872/3545 3556/2438/3556 3535/4868/3535 \nf 3544/656/3544 3555/4876/3555 3556/2438/3556 3545/4872/3545 \nf 3554/1310/3554 3557/4878/3557 3556/2438/3556 3555/4876/3555 \nf 3558/176/3558 3559/4879/3559 3560/2439/3560 3561/4882/3561 \nf 3562/1311/3562 3563/4880/3563 3560/2439/3560 3559/4879/3559 \nf 3564/657/3564 3565/4881/3565 3560/2439/3560 3563/4880/3563 \nf 3566/1313/3566 3561/4882/3561 3560/2439/3560 3565/4881/3565 \nf 3567/221/3567 3568/4883/3568 3569/2440/3569 3570/4885/3570 \nf 3571/1312/3571 3572/4884/3572 3569/2440/3569 3568/4883/3568 \nf 3564/657/3564 3563/4880/3563 3569/2440/3569 3572/4884/3572 \nf 3562/1311/3562 3570/4885/3570 3569/2440/3569 3563/4880/3563 \nf 3532/164/3532 3557/4878/3557 3573/2441/3573 3574/4887/3574 \nf 3554/1310/3554 3575/4886/3575 3573/2441/3573 3557/4878/3557 \nf 3564/657/3564 3572/4884/3572 3573/2441/3573 3575/4886/3575 \nf 3571/1312/3571 3574/4887/3574 3573/2441/3573 3572/4884/3572 \nf 3550/174/3550 3576/4888/3576 3577/2442/3577 3551/4875/3551 \nf 3566/1313/3566 3565/4881/3565 3577/2442/3577 3576/4888/3576 \nf 3564/657/3564 3575/4886/3575 3577/2442/3577 3565/4881/3565 \nf 3554/1310/3554 3551/4875/3551 3577/2442/3577 3575/4886/3575 \nf 3567/221/3567 3578/4889/3578 3579/2443/3579 3568/4883/3568 \nf 3580/1314/3580 3581/4890/3581 3579/2443/3579 3578/4889/3578 \nf 3582/658/3582 3583/4891/3583 3579/2443/3579 3581/4890/3581 \nf 3571/1312/3571 3568/4883/3568 3579/2443/3579 3583/4891/3583 \nf 3584/222/3584 3585/4892/3585 3586/2444/3586 3587/4894/3587 \nf 3588/1315/3588 3589/4893/3589 3586/2444/3586 3585/4892/3585 \nf 3582/658/3582 3581/4890/3581 3586/2444/3586 3589/4893/3589 \nf 3580/1314/3580 3587/4894/3587 3586/2444/3586 3581/4890/3581 \nf 3538/165/3538 3541/4870/3541 3590/2445/3590 3591/4896/3591 \nf 3536/1307/3536 3592/4895/3592 3590/2445/3590 3541/4870/3541 \nf 3582/658/3582 3589/4893/3589 3590/2445/3590 3592/4895/3592 \nf 3588/1315/3588 3591/4896/3591 3590/2445/3590 3589/4893/3589 \nf 3532/164/3532 3574/4887/3574 3593/2446/3593 3533/4866/3533 \nf 3571/1312/3571 3583/4891/3583 3593/2446/3593 3574/4887/3574 \nf 3582/658/3582 3592/4895/3592 3593/2446/3593 3583/4891/3583 \nf 3536/1307/3536 3533/4866/3533 3593/2446/3593 3592/4895/3592 \nf 3108/130/3108 3111/4640/3111 3594/2447/3594 3595/4899/3595 \nf 3116/1245/3116 3596/4897/3596 3594/2447/3594 3111/4640/3111 \nf 3597/659/3597 3598/4898/3598 3594/2447/3594 3596/4897/3596 \nf 3599/1318/3599 3595/4899/3595 3594/2447/3594 3598/4898/3598 \nf 3129/134/3129 3600/4900/3600 3601/2448/3601 3130/4647/3130 \nf 3602/1316/3602 3603/4901/3603 3601/2448/3601 3600/4900/3600 \nf 3597/659/3597 3596/4897/3596 3601/2448/3601 3603/4901/3603 \nf 3116/1245/3116 3130/4647/3130 3601/2448/3601 3596/4897/3596 \nf 3604/223/3604 3605/4902/3605 3606/2449/3606 3607/4904/3607 \nf 3608/1317/3608 3609/4903/3609 3606/2449/3606 3605/4902/3605 \nf 3597/659/3597 3603/4901/3603 3606/2449/3606 3609/4903/3609 \nf 3602/1316/3602 3607/4904/3607 3606/2449/3606 3603/4901/3603 \nf 3610/224/3610 3611/4905/3611 3612/2450/3612 3613/4906/3613 \nf 3599/1318/3599 3598/4898/3598 3612/2450/3612 3611/4905/3611 \nf 3597/659/3597 3609/4903/3609 3612/2450/3612 3598/4898/3598 \nf 3608/1317/3608 3613/4906/3613 3612/2450/3612 3609/4903/3609 \nf 3129/134/3129 3185/4676/3185 3614/2451/3614 3600/4900/3600 \nf 3182/1253/3182 3615/4907/3615 3614/2451/3614 3185/4676/3185 \nf 3616/660/3616 3617/4908/3617 3614/2451/3614 3615/4907/3615 \nf 3602/1316/3602 3600/4900/3600 3614/2451/3614 3617/4908/3617 \nf 3178/141/3178 3451/4823/3451 3618/2452/3618 3179/4672/3179 \nf 3455/1296/3455 3619/4909/3619 3618/2452/3618 3451/4823/3451 \nf 3616/660/3616 3615/4907/3615 3618/2452/3618 3619/4909/3619 \nf 3182/1253/3182 3179/4672/3179 3618/2452/3618 3615/4907/3615 \nf 3466/156/3466 3620/4910/3620 3621/2453/3621 3467/4829/3467 \nf 3622/1319/3622 3623/4911/3623 3621/2453/3621 3620/4910/3620 \nf 3616/660/3616 3619/4909/3619 3621/2453/3621 3623/4911/3623 \nf 3455/1296/3455 3467/4829/3467 3621/2453/3621 3619/4909/3619 \nf 3604/223/3604 3607/4904/3607 3624/2454/3624 3625/4912/3625 \nf 3602/1316/3602 3617/4908/3617 3624/2454/3624 3607/4904/3607 \nf 3616/660/3616 3623/4911/3623 3624/2454/3624 3617/4908/3617 \nf 3622/1319/3622 3625/4912/3625 3624/2454/3624 3623/4911/3623 \nf 3512/163/3512 3626/4913/3626 3627/2455/3627 3513/4856/3513 \nf 3628/1320/3628 3629/4914/3629 3627/2455/3627 3626/4913/3626 \nf 3630/661/3630 3631/4915/3631 3627/2455/3627 3629/4914/3629 \nf 3516/1305/3516 3513/4856/3513 3627/2455/3627 3631/4915/3631 \nf 3632/225/3632 3633/4916/3633 3634/2456/3634 3635/4918/3635 \nf 3636/1321/3636 3637/4917/3637 3634/2456/3634 3633/4916/3633 \nf 3630/661/3630 3629/4914/3629 3634/2456/3634 3637/4917/3637 \nf 3628/1320/3628 3635/4918/3635 3634/2456/3634 3629/4914/3629 \nf 3604/223/3604 3625/4912/3625 3638/2457/3638 3639/4920/3639 \nf 3622/1319/3622 3640/4919/3640 3638/2457/3638 3625/4912/3625 \nf 3630/661/3630 3637/4917/3637 3638/2457/3638 3640/4919/3640 \nf 3636/1321/3636 3639/4920/3639 3638/2457/3638 3637/4917/3637 \nf 3466/156/3466 3519/4860/3519 3641/2458/3641 3620/4910/3620 \nf 3516/1305/3516 3631/4915/3631 3641/2458/3641 3519/4860/3519 \nf 3630/661/3630 3640/4919/3640 3641/2458/3641 3631/4915/3631 \nf 3622/1319/3622 3620/4910/3620 3641/2458/3641 3640/4919/3640 \nf 3632/225/3632 3642/4921/3642 3643/2459/3643 3633/4916/3633 \nf 3644/1322/3644 3645/4922/3645 3643/2459/3643 3642/4921/3642 \nf 3646/662/3646 3647/4923/3647 3643/2459/3643 3645/4922/3645 \nf 3636/1321/3636 3633/4916/3633 3643/2459/3643 3647/4923/3647 \nf 3648/226/3648 3649/4924/3649 3650/2460/3650 3651/4926/3651 \nf 3652/1323/3652 3653/4925/3653 3650/2460/3650 3649/4924/3649 \nf 3646/662/3646 3645/4922/3645 3650/2460/3650 3653/4925/3653 \nf 3644/1322/3644 3651/4926/3651 3650/2460/3650 3645/4922/3645 \nf 3610/224/3610 3613/4906/3613 3654/2461/3654 3655/4928/3655 \nf 3608/1317/3608 3656/4927/3656 3654/2461/3654 3613/4906/3613 \nf 3646/662/3646 3653/4925/3653 3654/2461/3654 3656/4927/3656 \nf 3652/1323/3652 3655/4928/3655 3654/2461/3654 3653/4925/3653 \nf 3604/223/3604 3639/4920/3639 3657/2462/3657 3605/4902/3605 \nf 3636/1321/3636 3647/4923/3647 3657/2462/3657 3639/4920/3639 \nf 3646/662/3646 3656/4927/3656 3657/2462/3657 3647/4923/3647 \nf 3608/1317/3608 3605/4902/3605 3657/2462/3657 3656/4927/3656 \nf 794/21/794 3658/4929/3658 3659/2463/3659 795/3413/795 \nf 3660/1324/3660 3661/4930/3661 3659/2463/3659 3658/4929/3658 \nf 3662/663/3662 3663/4931/3663 3659/2463/3659 3661/4930/3661 \nf 798/918/798 795/3413/795 3659/2463/3659 3663/4931/3663 \nf 3664/236/3664 3665/4932/3665 3666/2464/3666 3667/4934/3667 \nf 3668/1325/3668 3669/4933/3669 3666/2464/3666 3665/4932/3665 \nf 3662/663/3662 3661/4930/3661 3666/2464/3666 3669/4933/3669 \nf 3660/1324/3660 3667/4934/3667 3666/2464/3666 3661/4930/3661 \nf 3670/254/3670 3671/4935/3671 3672/2465/3672 3673/4937/3673 \nf 3674/1326/3674 3675/4936/3675 3672/2465/3672 3671/4935/3671 \nf 3662/663/3662 3669/4933/3669 3672/2465/3672 3675/4936/3675 \nf 3668/1325/3668 3673/4937/3673 3672/2465/3672 3669/4933/3669 \nf 803/28/803 806/3419/806 3676/2466/3676 3677/4938/3677 \nf 798/918/798 3663/4931/3663 3676/2466/3676 806/3419/806 \nf 3662/663/3662 3675/4936/3675 3676/2466/3676 3663/4931/3663 \nf 3674/1326/3674 3677/4938/3677 3676/2466/3676 3675/4936/3675 \nf 3664/236/3664 3678/4939/3678 3679/2467/3679 3665/4932/3665 \nf 3680/1327/3680 3681/4940/3681 3679/2467/3679 3678/4939/3678 \nf 3682/664/3682 3683/4941/3683 3679/2467/3679 3681/4940/3681 \nf 3668/1325/3668 3665/4932/3665 3679/2467/3679 3683/4941/3683 \nf 2919/258/2919 3684/4942/3684 3685/2468/3685 3686/4945/3686 \nf 3687/1328/3687 3688/4944/3688 3685/2468/3685 3684/4942/3684 \nf 3682/664/3682 3681/4940/3681 3685/2468/3685 3688/4944/3688 \nf 3680/1327/3680 3686/4945/3686 3685/2468/3685 3681/4940/3681 \nf 3689/280/3689 3690/4946/3690 3691/2469/3691 3692/4948/3692 \nf 3693/1330/3693 3694/4947/3694 3691/2469/3691 3690/4946/3690 \nf 3682/664/3682 3688/4944/3688 3691/2469/3691 3694/4947/3694 \nf 3687/1328/3687 3692/4948/3692 3691/2469/3691 3688/4944/3688 \nf 3670/254/3670 3673/4937/3673 3695/2470/3695 3696/4950/3696 \nf 3668/1325/3668 3683/4941/3683 3695/2470/3695 3673/4937/3673 \nf 3682/664/3682 3694/4947/3694 3695/2470/3695 3683/4941/3683 \nf 3693/1330/3693 3696/4950/3696 3695/2470/3695 3694/4947/3694 \nf 3697/285/3697 3698/4951/3698 3699/2471/3699 3700/4954/3700 \nf 3701/1331/3701 3702/4952/3702 3699/2471/3699 3698/4951/3698 \nf 3703/665/3703 3704/4953/3704 3699/2471/3699 3702/4952/3702 \nf 3705/1333/3705 3700/4954/3700 3699/2471/3699 3704/4953/3704 \nf 3706/291/3706 3707/4956/3707 3708/2472/3708 3709/4958/3709 \nf 3710/1332/3710 3711/4957/3711 3708/2472/3708 3707/4956/3707 \nf 3703/665/3703 3702/4952/3702 3708/2472/3708 3711/4957/3711 \nf 3701/1331/3701 3709/4958/3709 3708/2472/3708 3702/4952/3702 \nf 3670/254/3670 3696/4950/3696 3712/2473/3712 3713/4960/3713 \nf 3693/1330/3693 3714/4959/3714 3712/2473/3712 3696/4950/3696 \nf 3703/665/3703 3711/4957/3711 3712/2473/3712 3714/4959/3714 \nf 3710/1332/3710 3713/4960/3713 3712/2473/3712 3711/4957/3711 \nf 3689/280/3689 3715/4961/3715 3716/2474/3716 3690/4946/3690 \nf 3705/1333/3705 3704/4953/3704 3716/2474/3716 3715/4961/3715 \nf 3703/665/3703 3714/4959/3714 3716/2474/3716 3704/4953/3704 \nf 3693/1330/3693 3690/4946/3690 3716/2474/3716 3714/4959/3714 \nf 3706/291/3706 3717/4963/3717 3718/2475/3718 3707/4956/3707 \nf 3719/1335/3719 3720/4964/3720 3718/2475/3718 3717/4963/3717 \nf 3721/666/3721 3722/4965/3722 3718/2475/3718 3720/4964/3720 \nf 3710/1332/3710 3707/4956/3707 3718/2475/3718 3722/4965/3722 \nf 825/44/825 828/3430/828 3723/2476/3723 3724/4967/3724 \nf 821/922/821 3725/4966/3725 3723/2476/3723 828/3430/828 \nf 3721/666/3721 3720/4964/3720 3723/2476/3723 3725/4966/3725 \nf 3719/1335/3719 3724/4967/3724 3723/2476/3723 3720/4964/3720 \nf 803/28/803 3677/4938/3677 3726/2477/3726 819/3425/819 \nf 3674/1326/3674 3727/4968/3727 3726/2477/3726 3677/4938/3677 \nf 3721/666/3721 3725/4966/3725 3726/2477/3726 3727/4968/3727 \nf 821/922/821 819/3425/819 3726/2477/3726 3725/4966/3725 \nf 3670/254/3670 3713/4960/3713 3728/2478/3728 3671/4935/3671 \nf 3710/1332/3710 3722/4965/3722 3728/2478/3728 3713/4960/3713 \nf 3721/666/3721 3727/4968/3727 3728/2478/3728 3722/4965/3722 \nf 3674/1326/3674 3671/4935/3671 3728/2478/3728 3727/4968/3727 \nf 3558/176/3558 3561/4882/3561 3729/2479/3729 3730/4971/3730 \nf 3566/1313/3566 3731/4969/3731 3729/2479/3729 3561/4882/3561 \nf 3732/667/3732 3733/4970/3733 3729/2479/3729 3731/4969/3731 \nf 3734/1338/3734 3730/4971/3730 3729/2479/3729 3733/4970/3733 \nf 3550/174/3550 3735/4972/3735 3736/2480/3736 3576/4888/3576 \nf 3737/1336/3737 3738/4973/3738 3736/2480/3736 3735/4972/3735 \nf 3732/667/3732 3731/4969/3731 3736/2480/3736 3738/4973/3738 \nf 3566/1313/3566 3576/4888/3576 3736/2480/3736 3731/4969/3731 \nf 3739/227/3739 3740/4974/3740 3741/2481/3741 3742/4976/3742 \nf 3743/1337/3743 3744/4975/3744 3741/2481/3741 3740/4974/3740 \nf 3732/667/3732 3738/4973/3738 3741/2481/3741 3744/4975/3744 \nf 3737/1336/3737 3742/4976/3742 3741/2481/3741 3738/4973/3738 \nf 3745/229/3745 3746/4977/3746 3747/2482/3747 3748/4978/3748 \nf 3734/1338/3734 3733/4970/3733 3747/2482/3747 3746/4977/3746 \nf 3732/667/3732 3744/4975/3744 3747/2482/3747 3733/4970/3733 \nf 3743/1337/3743 3748/4978/3748 3747/2482/3747 3744/4975/3744 \nf 3550/174/3550 3553/4877/3553 3749/2483/3749 3735/4972/3735 \nf 3548/1309/3548 3750/4979/3750 3749/2483/3749 3553/4877/3553 \nf 3751/668/3751 3752/4980/3752 3749/2483/3749 3750/4979/3750 \nf 3737/1336/3737 3735/4972/3735 3749/2483/3749 3752/4980/3752 \nf 3098/121/3098 3753/4981/3753 3754/2484/3754 3546/4873/3546 \nf 3755/1339/3755 3756/4982/3756 3754/2484/3754 3753/4981/3753 \nf 3751/668/3751 3750/4979/3750 3754/2484/3754 3756/4982/3756 \nf 3548/1309/3548 3546/4873/3546 3754/2484/3754 3750/4979/3750 \nf 3757/230/3757 3758/4983/3758 3759/2485/3759 3760/4985/3760 \nf 3761/1340/3761 3762/4984/3762 3759/2485/3759 3758/4983/3758 \nf 3751/668/3751 3756/4982/3756 3759/2485/3759 3762/4984/3762 \nf 3755/1339/3755 3760/4985/3760 3759/2485/3759 3756/4982/3756 \nf 3739/227/3739 3742/4976/3742 3763/2486/3763 3764/4986/3764 \nf 3737/1336/3737 3752/4980/3752 3763/2486/3763 3742/4976/3742 \nf 3751/668/3751 3762/4984/3762 3763/2486/3763 3752/4980/3752 \nf 3761/1340/3761 3764/4986/3764 3763/2486/3763 3762/4984/3762 \nf 3108/130/3108 3595/4899/3595 3765/2487/3765 3766/4989/3766 \nf 3599/1318/3599 3767/4987/3767 3765/2487/3765 3595/4899/3595 \nf 3768/669/3768 3769/4988/3769 3765/2487/3765 3767/4987/3767 \nf 3770/1342/3770 3766/4989/3766 3765/2487/3765 3769/4988/3769 \nf 3610/224/3610 3771/4990/3771 3772/2488/3772 3611/4905/3611 \nf 3773/1341/3773 3774/4991/3774 3772/2488/3772 3771/4990/3771 \nf 3768/669/3768 3767/4987/3767 3772/2488/3772 3774/4991/3774 \nf 3599/1318/3599 3611/4905/3611 3772/2488/3772 3767/4987/3767 \nf 3739/227/3739 3764/4986/3764 3775/2489/3775 3776/4993/3776 \nf 3761/1340/3761 3777/4992/3777 3775/2489/3775 3764/4986/3764 \nf 3768/669/3768 3774/4991/3774 3775/2489/3775 3777/4992/3777 \nf 3773/1341/3773 3776/4993/3776 3775/2489/3775 3774/4991/3774 \nf 3757/230/3757 3778/4994/3778 3779/2490/3779 3758/4983/3758 \nf 3770/1342/3770 3769/4988/3769 3779/2490/3779 3778/4994/3778 \nf 3768/669/3768 3777/4992/3777 3779/2490/3779 3769/4988/3769 \nf 3761/1340/3761 3758/4983/3758 3779/2490/3779 3777/4992/3777 \nf 3610/224/3610 3655/4928/3655 3780/2491/3780 3771/4990/3771 \nf 3652/1323/3652 3781/4995/3781 3780/2491/3780 3655/4928/3655 \nf 3782/670/3782 3783/4996/3783 3780/2491/3780 3781/4995/3781 \nf 3773/1341/3773 3771/4990/3771 3780/2491/3780 3783/4996/3783 \nf 3648/226/3648 3784/4997/3784 3785/2492/3785 3649/4924/3649 \nf 3786/1343/3786 3787/4998/3787 3785/2492/3785 3784/4997/3784 \nf 3782/670/3782 3781/4995/3781 3785/2492/3785 3787/4998/3787 \nf 3652/1323/3652 3649/4924/3649 3785/2492/3785 3781/4995/3781 \nf 3745/229/3745 3748/4978/3748 3788/2493/3788 3789/5000/3789 \nf 3743/1337/3743 3790/4999/3790 3788/2493/3788 3748/4978/3748 \nf 3782/670/3782 3787/4998/3787 3788/2493/3788 3790/4999/3790 \nf 3786/1343/3786 3789/5000/3789 3788/2493/3788 3787/4998/3787 \nf 3739/227/3739 3776/4993/3776 3791/2494/3791 3740/4974/3740 \nf 3773/1341/3773 3783/4996/3783 3791/2494/3791 3776/4993/3776 \nf 3782/670/3782 3790/4999/3790 3791/2494/3791 3783/4996/3783 \nf 3743/1337/3743 3740/4974/3740 3791/2494/3791 3790/4999/3790 \nf 3098/121/3098 3101/4634/3101 3792/2495/3792 3753/4981/3753 \nf 3094/1240/3094 3793/5001/3793 3792/2495/3792 3101/4634/3101 \nf 3794/671/3794 3795/5002/3795 3792/2495/3792 3793/5001/3793 \nf 3755/1339/3755 3753/4981/3753 3792/2495/3792 3795/5002/3795 \nf 3081/120/3081 3796/5003/3796 3797/2496/3797 3092/4629/3092 \nf 3798/1344/3798 3799/5004/3799 3797/2496/3797 3796/5003/3796 \nf 3794/671/3794 3793/5001/3793 3797/2496/3797 3799/5004/3799 \nf 3094/1240/3094 3092/4629/3092 3797/2496/3797 3793/5001/3793 \nf 3800/231/3800 3801/5005/3801 3802/2497/3802 3803/5007/3803 \nf 3804/1345/3804 3805/5006/3805 3802/2497/3802 3801/5005/3801 \nf 3794/671/3794 3799/5004/3799 3802/2497/3802 3805/5006/3805 \nf 3798/1344/3798 3803/5007/3803 3802/2497/3802 3799/5004/3799 \nf 3757/230/3757 3760/4985/3760 3806/2498/3806 3807/5008/3807 \nf 3755/1339/3755 3795/5002/3795 3806/2498/3806 3760/4985/3760 \nf 3794/671/3794 3805/5006/3805 3806/2498/3806 3795/5002/3795 \nf 3804/1345/3804 3807/5008/3807 3806/2498/3806 3805/5006/3805 \nf 3081/120/3081 3084/4625/3084 3808/2499/3808 3796/5003/3796 \nf 3076/1237/3076 3809/5009/3809 3808/2499/3808 3084/4625/3084 \nf 3810/672/3810 3811/5010/3811 3808/2499/3808 3809/5009/3809 \nf 3798/1344/3798 3796/5003/3796 3808/2499/3808 3811/5010/3811 \nf 3072/119/3072 3812/5011/3812 3813/2500/3813 3073/4619/3073 \nf 3814/1346/3814 3815/5012/3815 3813/2500/3813 3812/5011/3812 \nf 3810/672/3810 3809/5009/3809 3813/2500/3813 3815/5012/3815 \nf 3076/1237/3076 3073/4619/3073 3813/2500/3813 3809/5009/3809 \nf 3816/233/3816 3817/5013/3817 3818/2501/3818 3819/5015/3819 \nf 3820/1347/3820 3821/5014/3821 3818/2501/3818 3817/5013/3817 \nf 3810/672/3810 3815/5012/3815 3818/2501/3818 3821/5014/3821 \nf 3814/1346/3814 3819/5015/3819 3818/2501/3818 3815/5012/3815 \nf 3800/231/3800 3803/5007/3803 3822/2502/3822 3823/5016/3823 \nf 3798/1344/3798 3811/5010/3811 3822/2502/3822 3803/5007/3803 \nf 3810/672/3810 3821/5014/3821 3822/2502/3822 3811/5010/3811 \nf 3820/1347/3820 3823/5016/3823 3822/2502/3822 3821/5014/3821 \nf 3139/137/3139 3142/4654/3142 3824/2503/3824 3825/5019/3825 \nf 3135/1246/3135 3826/5017/3826 3824/2503/3824 3142/4654/3142 \nf 3827/673/3827 3828/5018/3828 3824/2503/3824 3826/5017/3826 \nf 3829/1349/3829 3825/5019/3825 3824/2503/3824 3828/5018/3828 \nf 3117/132/3117 3830/5020/3830 3831/2504/3831 3133/4649/3133 \nf 3832/1348/3832 3833/5021/3833 3831/2504/3831 3830/5020/3830 \nf 3827/673/3827 3826/5017/3826 3831/2504/3831 3833/5021/3833 \nf 3135/1246/3135 3133/4649/3133 3831/2504/3831 3826/5017/3826 \nf 3800/231/3800 3823/5016/3823 3834/2505/3834 3835/5023/3835 \nf 3820/1347/3820 3836/5022/3836 3834/2505/3834 3823/5016/3823 \nf 3827/673/3827 3833/5021/3833 3834/2505/3834 3836/5022/3836 \nf 3832/1348/3832 3835/5023/3835 3834/2505/3834 3833/5021/3833 \nf 3816/233/3816 3837/5024/3837 3838/2506/3838 3817/5013/3817 \nf 3829/1349/3829 3828/5018/3828 3838/2506/3838 3837/5024/3837 \nf 3827/673/3827 3836/5022/3836 3838/2506/3838 3828/5018/3828 \nf 3820/1347/3820 3817/5013/3817 3838/2506/3838 3836/5022/3836 \nf 3117/132/3117 3120/4643/3120 3839/2507/3839 3830/5020/3830 \nf 3112/1242/3112 3840/5025/3840 3839/2507/3839 3120/4643/3120 \nf 3841/674/3841 3842/5026/3842 3839/2507/3839 3840/5025/3840 \nf 3832/1348/3832 3830/5020/3830 3839/2507/3839 3842/5026/3842 \nf 3108/130/3108 3766/4989/3766 3843/2508/3843 3109/4637/3109 \nf 3770/1342/3770 3844/5027/3844 3843/2508/3843 3766/4989/3766 \nf 3841/674/3841 3840/5025/3840 3843/2508/3843 3844/5027/3844 \nf 3112/1242/3112 3109/4637/3109 3843/2508/3843 3840/5025/3840 \nf 3757/230/3757 3807/5008/3807 3845/2509/3845 3778/4994/3778 \nf 3804/1345/3804 3846/5028/3846 3845/2509/3845 3807/5008/3807 \nf 3841/674/3841 3844/5027/3844 3845/2509/3845 3846/5028/3846 \nf 3770/1342/3770 3778/4994/3778 3845/2509/3845 3844/5027/3844 \nf 3800/231/3800 3835/5023/3835 3847/2510/3847 3801/5005/3801 \nf 3832/1348/3832 3842/5026/3842 3847/2510/3847 3835/5023/3835 \nf 3841/674/3841 3846/5028/3846 3847/2510/3847 3842/5026/3842 \nf 3804/1345/3804 3801/5005/3801 3847/2510/3847 3846/5028/3846 \nf 3072/119/3072 3075/4622/3075 3848/2511/3848 3812/5011/3812 \nf 3080/1239/3080 3849/5029/3849 3848/2511/3848 3075/4622/3075 \nf 3850/675/3850 3851/5030/3851 3848/2511/3848 3849/5029/3849 \nf 3814/1346/3814 3812/5011/3812 3848/2511/3848 3851/5030/3851 \nf 3064/118/3064 3852/5031/3852 3853/2512/3853 3090/4628/3090 \nf 3854/1350/3854 3855/5032/3855 3853/2512/3853 3852/5031/3852 \nf 3850/675/3850 3849/5029/3849 3853/2512/3853 3855/5032/3855 \nf 3080/1239/3080 3090/4628/3090 3853/2512/3853 3849/5029/3849 \nf 3856/234/3856 3857/5033/3857 3858/2513/3858 3859/5035/3859 \nf 3860/1351/3860 3861/5034/3861 3858/2513/3858 3857/5033/3857 \nf 3850/675/3850 3855/5032/3855 3858/2513/3858 3861/5034/3861 \nf 3854/1350/3854 3859/5035/3859 3858/2513/3858 3855/5032/3855 \nf 3816/233/3816 3819/5015/3819 3862/2514/3862 3863/5036/3863 \nf 3814/1346/3814 3851/5030/3851 3862/2514/3862 3819/5015/3819 \nf 3850/675/3850 3861/5034/3861 3862/2514/3862 3851/5030/3851 \nf 3860/1351/3860 3863/5036/3863 3862/2514/3862 3861/5034/3861 \nf 3064/118/3064 3067/4617/3067 3864/2515/3864 3852/5031/3852 \nf 3062/1235/3062 3865/5037/3865 3864/2515/3864 3067/4617/3067 \nf 3866/676/3866 3867/5038/3867 3864/2515/3864 3865/5037/3865 \nf 3854/1350/3854 3852/5031/3852 3864/2515/3864 3867/5038/3867 \nf 2874/89/2874 3868/5039/3868 3869/2516/3869 3060/4613/3060 \nf 3870/1352/3870 3871/5040/3871 3869/2516/3869 3868/5039/3868 \nf 3866/676/3866 3865/5037/3865 3869/2516/3869 3871/5040/3871 \nf 3062/1235/3062 3060/4613/3060 3869/2516/3869 3865/5037/3865 \nf 3872/235/3872 3873/5041/3873 3874/2517/3874 3875/5043/3875 \nf 3876/1353/3876 3877/5042/3877 3874/2517/3874 3873/5041/3873 \nf 3866/676/3866 3871/5040/3871 3874/2517/3874 3877/5042/3877 \nf 3870/1352/3870 3875/5043/3875 3874/2517/3874 3871/5040/3871 \nf 3856/234/3856 3859/5035/3859 3878/2518/3878 3879/5044/3879 \nf 3854/1350/3854 3867/5038/3867 3878/2518/3878 3859/5035/3859 \nf 3866/676/3866 3877/5042/3877 3878/2518/3878 3867/5038/3867 \nf 3876/1353/3876 3879/5044/3879 3878/2518/3878 3877/5042/3877 \nf 3188/142/3188 3357/4771/3357 3880/2519/3880 3881/5047/3881 \nf 3361/1281/3361 3882/5045/3882 3880/2519/3880 3357/4771/3357 \nf 3883/677/3883 3884/5046/3884 3880/2519/3880 3882/5045/3882 \nf 3885/1355/3885 3881/5047/3881 3880/2519/3880 3884/5046/3884 \nf 3348/154/3348 3886/5048/3886 3887/2520/3887 3369/4776/3369 \nf 3888/1354/3888 3889/5049/3889 3887/2520/3887 3886/5048/3886 \nf 3883/677/3883 3882/5045/3882 3887/2520/3887 3889/5049/3889 \nf 3361/1281/3361 3369/4776/3369 3887/2520/3887 3882/5045/3882 \nf 3856/234/3856 3879/5044/3879 3890/2521/3890 3891/5051/3891 \nf 3876/1353/3876 3892/5050/3892 3890/2521/3890 3879/5044/3879 \nf 3883/677/3883 3889/5049/3889 3890/2521/3890 3892/5050/3892 \nf 3888/1354/3888 3891/5051/3891 3890/2521/3890 3889/5049/3889 \nf 3872/235/3872 3893/5052/3893 3894/2522/3894 3873/5041/3873 \nf 3885/1355/3885 3884/5046/3884 3894/2522/3894 3893/5052/3893 \nf 3883/677/3883 3892/5050/3892 3894/2522/3894 3884/5046/3884 \nf 3876/1353/3876 3873/5041/3873 3894/2522/3894 3892/5050/3892 \nf 3348/154/3348 3351/4767/3351 3895/2523/3895 3886/5048/3886 \nf 3346/1278/3346 3896/5053/3896 3895/2523/3895 3351/4767/3351 \nf 3897/678/3897 3898/5054/3898 3895/2523/3895 3896/5053/3896 \nf 3888/1354/3888 3886/5048/3886 3895/2523/3895 3898/5054/3898 \nf 3139/137/3139 3825/5019/3825 3899/2524/3899 3344/4763/3344 \nf 3829/1349/3829 3900/5055/3900 3899/2524/3899 3825/5019/3825 \nf 3897/678/3897 3896/5053/3896 3899/2524/3899 3900/5055/3900 \nf 3346/1278/3346 3344/4763/3344 3899/2524/3899 3896/5053/3896 \nf 3816/233/3816 3863/5036/3863 3901/2525/3901 3837/5024/3837 \nf 3860/1351/3860 3902/5056/3902 3901/2525/3901 3863/5036/3863 \nf 3897/678/3897 3900/5055/3900 3901/2525/3901 3902/5056/3902 \nf 3829/1349/3829 3837/5024/3837 3901/2525/3901 3900/5055/3900 \nf 3856/234/3856 3891/5051/3891 3903/2526/3903 3857/5033/3857 \nf 3888/1354/3888 3898/5054/3898 3903/2526/3903 3891/5051/3891 \nf 3897/678/3897 3902/5056/3902 3903/2526/3903 3898/5054/3898 \nf 3860/1351/3860 3857/5033/3857 3903/2526/3903 3902/5056/3902 \nf 2945/297/2945 2948/4552/2948 3904/2527/3904 3441/4814/3441 \nf 2941/1215/2941 3905/5057/3905 3904/2527/3904 2948/4552/2948 \nf 3906/679/3906 3907/5058/3907 3904/2527/3904 3905/5057/3905 \nf 3444/1293/3444 3441/4814/3441 3904/2527/3904 3907/5058/3907 \nf 2928/303/2928 3908/5059/3908 3909/2528/3909 2939/4546/2939 \nf 3910/1356/3910 3911/5060/3911 3909/2528/3909 3908/5059/3908 \nf 3906/679/3906 3905/5057/3905 3909/2528/3909 3911/5060/3911 \nf 2941/1215/2941 2939/4546/2939 3909/2528/3909 3905/5057/3905 \nf 3912/305/3912 3913/5061/3913 3914/2529/3914 3915/5064/3915 \nf 3916/1357/3916 3917/5063/3917 3914/2529/3914 3913/5061/3913 \nf 3906/679/3906 3911/5060/3911 3914/2529/3914 3917/5063/3917 \nf 3910/1356/3910 3915/5064/3915 3914/2529/3914 3911/5060/3911 \nf 3396/325/3396 3447/4820/3447 3918/2530/3918 3919/5065/3919 \nf 3444/1293/3444 3907/5058/3907 3918/2530/3918 3447/4820/3447 \nf 3906/679/3906 3917/5063/3917 3918/2530/3918 3907/5058/3907 \nf 3916/1357/3916 3919/5065/3919 3918/2530/3918 3917/5063/3917 \nf 2928/303/2928 2931/4541/2931 3920/2531/3920 3908/5059/3908 \nf 2923/1211/2923 3921/5067/3921 3920/2531/3920 2931/4541/2931 \nf 3922/680/3922 3923/5068/3923 3920/2531/3920 3921/5067/3921 \nf 3910/1356/3910 3908/5059/3908 3920/2531/3920 3923/5068/3923 \nf 2919/258/2919 3686/4945/3686 3924/2532/3924 2920/4534/2920 \nf 3680/1327/3680 3925/5069/3925 3924/2532/3924 3686/4945/3686 \nf 3922/680/3922 3921/5067/3921 3924/2532/3924 3925/5069/3925 \nf 2923/1211/2923 2920/4534/2920 3924/2532/3924 3921/5067/3921 \nf 3664/236/3664 3926/5070/3926 3927/2533/3927 3678/4939/3678 \nf 3928/1359/3928 3929/5071/3929 3927/2533/3927 3926/5070/3926 \nf 3922/680/3922 3925/5069/3925 3927/2533/3927 3929/5071/3929 \nf 3680/1327/3680 3678/4939/3678 3927/2533/3927 3925/5069/3925 \nf 3912/305/3912 3915/5064/3915 3930/2534/3930 3931/5072/3931 \nf 3910/1356/3910 3923/5068/3923 3930/2534/3930 3915/5064/3915 \nf 3922/680/3922 3929/5071/3929 3930/2534/3930 3923/5068/3923 \nf 3928/1359/3928 3931/5072/3931 3930/2534/3930 3929/5071/3929 \nf 794/21/794 1082/3567/1082 3932/2535/3932 3658/4929/3658 \nf 1086/959/1086 3933/5073/3933 3932/2535/3932 1082/3567/1082 \nf 3934/681/3934 3935/5074/3935 3932/2535/3932 3933/5073/3933 \nf 3660/1324/3660 3658/4929/3658 3932/2535/3932 3935/5074/3935 \nf 1073/123/1073 3936/5075/3936 3937/2536/3937 1094/3572/1094 \nf 3938/1360/3938 3939/5077/3939 3937/2536/3937 3936/5075/3936 \nf 3934/681/3934 3933/5073/3933 3937/2536/3937 3939/5077/3939 \nf 1086/959/1086 1094/3572/1094 3937/2536/3937 3933/5073/3933 \nf 3912/305/3912 3931/5072/3931 3940/2537/3940 3941/5079/3941 \nf 3928/1359/3928 3942/5078/3942 3940/2537/3940 3931/5072/3931 \nf 3934/681/3934 3939/5077/3939 3940/2537/3940 3942/5078/3942 \nf 3938/1360/3938 3941/5079/3941 3940/2537/3940 3939/5077/3939 \nf 3664/236/3664 3667/4934/3667 3943/2538/3943 3926/5070/3926 \nf 3660/1324/3660 3935/5074/3935 3943/2538/3943 3667/4934/3667 \nf 3934/681/3934 3942/5078/3942 3943/2538/3943 3935/5074/3935 \nf 3928/1359/3928 3926/5070/3926 3943/2538/3943 3942/5078/3942 \nf 1073/184/1073 1076/3562/1076 3944/2539/3944 3936/5076/3936 \nf 1071/955/1071 3945/5081/3945 3944/2539/3944 1076/3562/1076 \nf 3946/682/3946 3947/5082/3947 3944/2539/3944 3945/5081/3945 \nf 3938/1361/3938 3936/5076/3936 3944/2539/3944 3947/5082/3947 \nf 507/41/507 3381/4783/3381 3948/2540/3948 1069/3557/1069 \nf 3385/1284/3385 3949/5083/3949 3948/2540/3948 3381/4783/3381 \nf 3946/682/3946 3945/5081/3945 3948/2540/3948 3949/5083/3949 \nf 1071/955/1071 1069/3557/1069 3948/2540/3948 3945/5081/3945 \nf 3396/420/3396 3919/5066/3919 3950/2541/3950 3397/4789/3397 \nf 3916/1358/3916 3951/5084/3951 3950/2541/3950 3919/5066/3919 \nf 3946/682/3946 3949/5083/3949 3950/2541/3950 3951/5084/3951 \nf 3385/1284/3385 3397/4789/3397 3950/2541/3950 3949/5083/3949 \nf 3912/437/3912 3941/5080/3941 3952/2542/3952 3913/5062/3913 \nf 3938/1361/3938 3947/5082/3947 3952/2542/3952 3941/5080/3941 \nf 3946/682/3946 3951/5084/3951 3952/2542/3952 3947/5082/3947 \nf 3916/1358/3916 3913/5062/3913 3952/2542/3952 3951/5084/3951 \nf 3000/259/3000 3003/4585/3003 3953/2543/3953 3954/5087/3954 \nf 3008/1229/3008 3955/5085/3955 3953/2543/3953 3003/4585/3003 \nf 3956/683/3956 3957/5086/3957 3953/2543/3953 3955/5085/3955 \nf 3958/1365/3958 3954/5087/3954 3953/2543/3953 3957/5086/3957 \nf 2992/261/2992 3959/5088/3959 3960/2544/3960 3018/4592/3018 \nf 3961/1362/3961 3962/5090/3962 3960/2544/3960 3959/5088/3959 \nf 3956/683/3956 3955/5085/3955 3960/2544/3960 3962/5090/3962 \nf 3008/1229/3008 3018/4592/3018 3960/2544/3960 3955/5085/3955 \nf 3963/263/3963 3964/5091/3964 3965/2545/3965 3966/5093/3966 \nf 3967/1364/3967 3968/5092/3968 3965/2545/3965 3964/5091/3964 \nf 3956/683/3956 3962/5090/3962 3965/2545/3965 3968/5092/3968 \nf 3961/1362/3961 3966/5093/3966 3965/2545/3965 3962/5090/3962 \nf 3969/292/3969 3970/5095/3970 3971/2546/3971 3972/5096/3972 \nf 3958/1365/3958 3957/5086/3957 3971/2546/3971 3970/5095/3970 \nf 3956/683/3956 3968/5092/3968 3971/2546/3971 3957/5086/3957 \nf 3967/1364/3967 3972/5096/3972 3971/2546/3971 3968/5092/3968 \nf 2992/438/2992 2995/4579/2995 3973/2547/3973 3959/5089/3959 \nf 2990/1224/2990 3974/5097/3974 3973/2547/3973 2995/4579/2995 \nf 3975/684/3975 3976/5098/3976 3973/2547/3973 3974/5097/3974 \nf 3961/1363/3961 3959/5089/3959 3973/2547/3973 3976/5098/3976 \nf 2986/417/2986 3977/5099/3977 3978/2548/3978 2987/4572/2987 \nf 3979/1366/3979 3980/5100/3980 3978/2548/3978 3977/5099/3977 \nf 3975/684/3975 3974/5097/3974 3978/2548/3978 3980/5100/3980 \nf 2990/1224/2990 2987/4572/2987 3978/2548/3978 3974/5097/3974 \nf 3981/439/3981 3982/5101/3982 3983/2549/3983 3984/5103/3984 \nf 3985/1367/3985 3986/5102/3986 3983/2549/3983 3982/5101/3982 \nf 3975/684/3975 3980/5100/3980 3983/2549/3983 3986/5102/3986 \nf 3979/1366/3979 3984/5103/3984 3983/2549/3983 3980/5100/3980 \nf 3963/440/3963 3966/5094/3966 3987/2550/3987 3988/5104/3988 \nf 3961/1363/3961 3976/5098/3976 3987/2550/3987 3966/5094/3966 \nf 3975/684/3975 3986/5102/3986 3987/2550/3987 3976/5098/3976 \nf 3985/1367/3985 3988/5104/3988 3987/2550/3987 3986/5102/3986 \nf 1145/228/1145 1148/3604/1148 3989/2551/3989 3990/5107/3990 \nf 1153/970/1153 3991/5105/3991 3989/2551/3989 1148/3604/1148 \nf 3992/685/3992 3993/5106/3993 3989/2551/3989 3991/5105/3991 \nf 3994/1370/3994 3990/5107/3990 3989/2551/3989 3993/5106/3993 \nf 1137/293/1137 3995/5108/3995 3996/2552/3996 1163/3610/1163 \nf 3997/1368/3997 3998/5110/3998 3996/2552/3996 3995/5108/3995 \nf 3992/685/3992 3991/5105/3991 3996/2552/3996 3998/5110/3998 \nf 1153/970/1153 1163/3610/1163 3996/2552/3996 3991/5105/3991 \nf 3963/440/3963 3988/5104/3988 3999/2553/3999 4000/5112/4000 \nf 3985/1367/3985 4001/5111/4001 3999/2553/3999 3988/5104/3988 \nf 3992/685/3992 3998/5110/3998 3999/2553/3999 4001/5111/4001 \nf 3997/1368/3997 4000/5112/4000 3999/2553/3999 3998/5110/3998 \nf 3981/439/3981 4002/5114/4002 4003/2554/4003 3982/5101/3982 \nf 3994/1370/3994 3993/5106/3993 4003/2554/4003 4002/5114/4002 \nf 3992/685/3992 4001/5111/4001 4003/2554/4003 3993/5106/3993 \nf 3985/1367/3985 3982/5101/3982 4003/2554/4003 4001/5111/4001 \nf 1137/43/1137 1140/3598/1140 4004/2555/4004 3995/5109/3995 \nf 1135/965/1135 4005/5115/4005 4004/2555/4004 1140/3598/1140 \nf 4006/686/4006 4007/5116/4007 4004/2555/4004 4005/5115/4005 \nf 3997/1369/3997 3995/5109/3995 4004/2555/4004 4007/5116/4007 \nf 1131/39/1131 4008/5117/4008 4009/2556/4009 1132/3592/1132 \nf 4010/1371/4010 4011/5118/4011 4009/2556/4009 4008/5117/4008 \nf 4006/686/4006 4005/5115/4005 4009/2556/4009 4011/5118/4011 \nf 1135/965/1135 1132/3592/1132 4009/2556/4009 4005/5115/4005 \nf 3969/292/3969 3972/5096/3972 4012/2557/4012 4013/5120/4013 \nf 3967/1364/3967 4014/5119/4014 4012/2557/4012 3972/5096/3972 \nf 4006/686/4006 4011/5118/4011 4012/2557/4012 4014/5119/4014 \nf 4010/1371/4010 4013/5120/4013 4012/2557/4012 4011/5118/4011 \nf 3963/263/3963 4000/5113/4000 4015/2558/4015 3964/5091/3964 \nf 3997/1369/3997 4007/5116/4007 4015/2558/4015 4000/5113/4000 \nf 4006/686/4006 4014/5119/4014 4015/2558/4015 4007/5116/4007 \nf 3967/1364/3967 3964/5091/3964 4015/2558/4015 4014/5119/4014 \nf 2986/417/2986 3234/4703/3234 4016/2559/4016 3977/5099/3977 \nf 3238/1264/3238 4017/5121/4017 4016/2559/4016 3234/4703/3234 \nf 4018/687/4018 4019/5122/4019 4016/2559/4016 4017/5121/4017 \nf 3979/1366/3979 3977/5099/3977 4016/2559/4016 4019/5122/4019 \nf 3225/413/3225 4020/5123/4020 4021/2560/4021 3246/4710/3246 \nf 4022/1372/4022 4023/5124/4023 4021/2560/4021 4020/5123/4020 \nf 4018/687/4018 4017/5121/4017 4021/2560/4021 4023/5124/4023 \nf 3238/1264/3238 3246/4710/3246 4021/2560/4021 4017/5121/4017 \nf 4024/441/4024 4025/5125/4025 4026/2561/4026 4027/5127/4027 \nf 4028/1373/4028 4029/5126/4029 4026/2561/4026 4025/5125/4025 \nf 4018/687/4018 4023/5124/4023 4026/2561/4026 4029/5126/4029 \nf 4022/1372/4022 4027/5127/4027 4026/2561/4026 4023/5124/4023 \nf 3981/439/3981 3984/5103/3984 4030/2562/4030 4031/5128/4031 \nf 3979/1366/3979 4019/5122/4019 4030/2562/4030 3984/5103/3984 \nf 4018/687/4018 4029/5126/4029 4030/2562/4030 4019/5122/4019 \nf 4028/1373/4028 4031/5128/4031 4030/2562/4030 4029/5126/4029 \nf 3225/413/3225 3228/4699/3228 4032/2563/4032 4020/5123/4020 \nf 3223/1260/3223 4033/5129/4033 4032/2563/4032 3228/4699/3228 \nf 4034/688/4034 4035/5130/4035 4032/2563/4032 4033/5129/4033 \nf 4022/1372/4022 4020/5123/4020 4032/2563/4032 4035/5130/4035 \nf 3219/387/3219 3418/4802/3418 4036/2564/4036 3220/4694/3220 \nf 3423/1289/3423 4037/5131/4037 4036/2564/4036 3418/4802/3418 \nf 4034/688/4034 4033/5129/4033 4036/2564/4036 4037/5131/4037 \nf 3223/1260/3223 3220/4694/3220 4036/2564/4036 4033/5129/4033 \nf 3408/434/3408 4038/5132/4038 4039/2565/4039 3433/4808/3433 \nf 4040/1374/4040 4041/5133/4041 4039/2565/4039 4038/5132/4038 \nf 4034/688/4034 4037/5131/4037 4039/2565/4039 4041/5133/4041 \nf 3423/1289/3423 3433/4808/3433 4039/2565/4039 4037/5131/4037 \nf 4024/441/4024 4027/5127/4027 4042/2566/4042 4043/5134/4043 \nf 4022/1372/4022 4035/5130/4035 4042/2566/4042 4027/5127/4027 \nf 4034/688/4034 4041/5133/4041 4042/2566/4042 4035/5130/4035 \nf 4040/1374/4040 4043/5134/4043 4042/2566/4042 4041/5133/4041 \nf 576/128/576 1210/3635/1210 4044/2567/4044 3404/4793/3404 \nf 1214/977/1214 4045/5135/4045 4044/2567/4044 1210/3635/1210 \nf 4046/689/4046 4047/5136/4047 4044/2567/4044 4045/5135/4045 \nf 3406/1285/3406 3404/4793/3404 4044/2567/4044 4047/5136/4047 \nf 1201/369/1201 4048/5137/4048 4049/2568/4049 1222/3640/1222 \nf 4050/1375/4050 4051/5138/4051 4049/2568/4049 4048/5137/4048 \nf 4046/689/4046 4045/5135/4045 4049/2568/4049 4051/5138/4051 \nf 1214/977/1214 1222/3640/1222 4049/2568/4049 4045/5135/4045 \nf 4024/441/4024 4043/5134/4043 4052/2569/4052 4053/5140/4053 \nf 4040/1374/4040 4054/5139/4054 4052/2569/4052 4043/5134/4043 \nf 4046/689/4046 4051/5138/4051 4052/2569/4052 4054/5139/4054 \nf 4050/1375/4050 4053/5140/4053 4052/2569/4052 4051/5138/4051 \nf 3408/434/3408 3411/4797/3411 4055/2570/4055 4038/5132/4038 \nf 3406/1285/3406 4047/5136/4047 4055/2570/4055 3411/4797/3411 \nf 4046/689/4046 4054/5139/4054 4055/2570/4055 4047/5136/4047 \nf 4040/1374/4040 4038/5132/4038 4055/2570/4055 4054/5139/4054 \nf 1201/369/1201 1204/3631/1204 4056/2571/4056 4048/5137/4048 \nf 1199/974/1199 4057/5141/4057 4056/2571/4056 1204/3631/1204 \nf 4058/690/4058 4059/5142/4059 4056/2571/4056 4057/5141/4057 \nf 4050/1375/4050 4048/5137/4048 4056/2571/4056 4059/5142/4059 \nf 1145/228/1145 3990/5107/3990 4060/2572/4060 1197/3627/1197 \nf 3994/1370/3994 4061/5143/4061 4060/2572/4060 3990/5107/3990 \nf 4058/690/4058 4057/5141/4057 4060/2572/4060 4061/5143/4061 \nf 1199/974/1199 1197/3627/1197 4060/2572/4060 4057/5141/4057 \nf 3981/439/3981 4031/5128/4031 4062/2573/4062 4002/5114/4002 \nf 4028/1373/4028 4063/5144/4063 4062/2573/4062 4031/5128/4031 \nf 4058/690/4058 4061/5143/4061 4062/2573/4062 4063/5144/4063 \nf 3994/1370/3994 4002/5114/4002 4062/2573/4062 4061/5143/4061 \nf 4024/441/4024 4053/5140/4053 4064/2574/4064 4025/5125/4025 \nf 4050/1375/4050 4059/5142/4059 4064/2574/4064 4053/5140/4053 \nf 4058/690/4058 4063/5144/4063 4064/2574/4064 4059/5142/4059 \nf 4028/1373/4028 4025/5125/4025 4064/2574/4064 4063/5144/4063 \nf 3292/294/3292 3295/4739/3295 4065/2575/4065 4066/5147/4066 \nf 3300/1274/3300 4067/5145/4067 4065/2575/4065 3295/4739/3295 \nf 4068/691/4068 4069/5146/4069 4065/2575/4065 4067/5145/4067 \nf 4070/1378/4070 4066/5147/4066 4065/2575/4065 4069/5146/4069 \nf 3284/298/3284 4071/5148/4071 4072/2576/4072 3310/4746/3310 \nf 4073/1376/4073 4074/5149/4074 4072/2576/4072 4071/5148/4071 \nf 4068/691/4068 4067/5145/4067 4072/2576/4072 4074/5149/4074 \nf 3300/1274/3300 3310/4746/3310 4072/2576/4072 4067/5145/4067 \nf 4075/300/4075 4076/5150/4076 4077/2577/4077 4078/5152/4078 \nf 4079/1377/4079 4080/5151/4080 4077/2577/4077 4076/5150/4076 \nf 4068/691/4068 4074/5149/4074 4077/2577/4077 4080/5151/4080 \nf 4073/1376/4073 4078/5152/4078 4077/2577/4077 4074/5149/4074 \nf 4081/302/4081 4082/5153/4082 4083/2578/4083 4084/5154/4084 \nf 4070/1378/4070 4069/5146/4069 4083/2578/4083 4082/5153/4082 \nf 4068/691/4068 4080/5151/4080 4083/2578/4083 4069/5146/4069 \nf 4079/1377/4079 4084/5154/4084 4083/2578/4083 4080/5151/4080 \nf 3284/298/3284 3287/4733/3287 4085/2579/4085 4071/5148/4071 \nf 3282/1269/3282 4086/5155/4086 4085/2579/4085 3287/4733/3287 \nf 4087/692/4087 4088/5156/4088 4085/2579/4085 4086/5155/4086 \nf 4073/1376/4073 4071/5148/4071 4085/2579/4085 4088/5156/4088 \nf 3000/259/3000 3954/5087/3954 4089/2580/4089 3280/4728/3280 \nf 3958/1365/3958 4090/5157/4090 4089/2580/4089 3954/5087/3954 \nf 4087/692/4087 4086/5155/4086 4089/2580/4089 4090/5157/4090 \nf 3282/1269/3282 3280/4728/3280 4089/2580/4089 4086/5155/4086 \nf 3969/292/3969 4091/5158/4091 4092/2581/4092 3970/5095/3970 \nf 4093/1379/4093 4094/5159/4094 4092/2581/4092 4091/5158/4091 \nf 4087/692/4087 4090/5157/4090 4092/2581/4092 4094/5159/4094 \nf 3958/1365/3958 3970/5095/3970 4092/2581/4092 4090/5157/4090 \nf 4075/300/4075 4078/5152/4078 4095/2582/4095 4096/5160/4096 \nf 4073/1376/4073 4088/5156/4088 4095/2582/4095 4078/5152/4078 \nf 4087/692/4087 4094/5159/4094 4095/2582/4095 4088/5156/4088 \nf 4093/1379/4093 4096/5160/4096 4095/2582/4095 4094/5159/4094 \nf 1131/39/1131 1274/3667/1274 4097/2583/4097 4008/5117/4008 \nf 1278/985/1278 4098/5161/4098 4097/2583/4097 1274/3667/1274 \nf 4099/693/4099 4100/5162/4100 4097/2583/4097 4098/5161/4098 \nf 4010/1371/4010 4008/5117/4008 4097/2583/4097 4100/5162/4100 \nf 1265/87/1265 4101/5163/4101 4102/2584/4102 1286/3672/1286 \nf 4103/1380/4103 4104/5164/4104 4102/2584/4102 4101/5163/4101 \nf 4099/693/4099 4098/5161/4098 4102/2584/4102 4104/5164/4104 \nf 1278/985/1278 1286/3672/1286 4102/2584/4102 4098/5161/4098 \nf 4075/300/4075 4096/5160/4096 4105/2585/4105 4106/5166/4106 \nf 4093/1379/4093 4107/5165/4107 4105/2585/4105 4096/5160/4096 \nf 4099/693/4099 4104/5164/4104 4105/2585/4105 4107/5165/4107 \nf 4103/1380/4103 4106/5166/4106 4105/2585/4105 4104/5164/4104 \nf 3969/292/3969 4013/5120/4013 4108/2586/4108 4091/5158/4091 \nf 4010/1371/4010 4100/5162/4100 4108/2586/4108 4013/5120/4013 \nf 4099/693/4099 4107/5165/4107 4108/2586/4108 4100/5162/4100 \nf 4093/1379/4093 4091/5158/4091 4108/2586/4108 4107/5165/4107 \nf 1265/87/1265 1268/3663/1268 4109/2587/4109 4101/5163/4101 \nf 1263/982/1263 4110/5167/4110 4109/2587/4109 1268/3663/1268 \nf 4111/694/4111 4112/5168/4112 4109/2587/4109 4110/5167/4110 \nf 4103/1380/4103 4101/5163/4101 4109/2587/4109 4112/5168/4112 \nf 1259/85/1259 4113/5169/4113 4114/2588/4114 1260/3658/1260 \nf 4115/1381/4115 4116/5170/4116 4114/2588/4114 4113/5169/4113 \nf 4111/694/4111 4110/5167/4110 4114/2588/4114 4116/5170/4116 \nf 1263/982/1263 1260/3658/1260 4114/2588/4114 4110/5167/4110 \nf 4081/302/4081 4084/5154/4084 4117/2589/4117 4118/5172/4118 \nf 4079/1377/4079 4119/5171/4119 4117/2589/4117 4084/5154/4084 \nf 4111/694/4111 4116/5170/4116 4117/2589/4117 4119/5171/4119 \nf 4115/1381/4115 4118/5172/4118 4117/2589/4117 4116/5170/4116 \nf 4075/300/4075 4106/5166/4106 4120/2590/4120 4076/5150/4076 \nf 4103/1380/4103 4112/5168/4112 4120/2590/4120 4106/5166/4106 \nf 4111/694/4111 4119/5171/4119 4120/2590/4120 4112/5168/4112 \nf 4079/1377/4079 4076/5150/4076 4120/2590/4120 4119/5171/4119 \nf 2945/100/2945 3443/4817/3443 4121/2591/4121 2946/4549/2946 \nf 3437/1291/3437 4122/5173/4122 4121/2591/4121 3443/4817/3443 \nf 4123/695/4123 4124/5174/4124 4121/2591/4121 4122/5173/4122 \nf 2949/1216/2949 2946/4549/2946 4121/2591/4121 4124/5174/4124 \nf 3424/240/3424 4125/5175/4125 4126/2592/4126 3435/4810/3435 \nf 4127/1382/4127 4128/5177/4128 4126/2592/4126 4125/5175/4125 \nf 4123/695/4123 4122/5173/4122 4126/2592/4126 4128/5177/4128 \nf 3437/1291/3437 3435/4810/3435 4126/2592/4126 4122/5173/4122 \nf 4129/242/4129 4130/5178/4130 4131/2593/4131 4132/5180/4132 \nf 4133/1384/4133 4134/5179/4134 4131/2593/4131 4130/5178/4130 \nf 4123/695/4123 4128/5177/4128 4131/2593/4131 4134/5179/4134 \nf 4127/1382/4127 4132/5180/4132 4131/2593/4131 4128/5177/4128 \nf 2895/94/2895 2952/4554/2952 4135/2594/4135 4136/5182/4136 \nf 2949/1216/2949 4124/5174/4124 4135/2594/4135 2952/4554/2952 \nf 4123/695/4123 4134/5179/4134 4135/2594/4135 4124/5174/4124 \nf 4133/1384/4133 4136/5182/4136 4135/2594/4135 4134/5179/4134 \nf 3424/435/3424 3427/4805/3427 4137/2595/4137 4125/5176/4125 \nf 3419/1287/3419 4138/5183/4138 4137/2595/4137 3427/4805/3427 \nf 4139/696/4139 4140/5184/4140 4137/2595/4137 4138/5183/4138 \nf 4127/1383/4127 4125/5176/4125 4137/2595/4137 4140/5184/4140 \nf 3219/387/3219 3222/4696/3222 4141/2596/4141 3416/4799/3416 \nf 3215/1259/3215 4142/5185/4142 4141/2596/4141 3222/4696/3222 \nf 4139/696/4139 4138/5183/4138 4141/2596/4141 4142/5185/4142 \nf 3419/1287/3419 3416/4799/3416 4141/2596/4141 4138/5183/4138 \nf 3197/386/3197 4143/5186/4143 4144/2597/4144 3213/4691/3213 \nf 4145/1385/4145 4146/5188/4146 4144/2597/4144 4143/5186/4143 \nf 4139/696/4139 4142/5185/4142 4144/2597/4144 4146/5188/4146 \nf 3215/1259/3215 3213/4691/3213 4144/2597/4144 4142/5185/4142 \nf 4129/442/4129 4132/5181/4132 4147/2598/4147 4148/5189/4148 \nf 4127/1383/4127 4140/5184/4140 4147/2598/4147 4132/5181/4132 \nf 4139/696/4139 4146/5188/4146 4147/2598/4147 4140/5184/4140 \nf 4145/1385/4145 4148/5189/4148 4147/2598/4147 4146/5188/4146 \nf 3188/142/3188 3881/5047/3881 4149/2599/4149 3189/4677/3189 \nf 3885/1355/3885 4150/5191/4150 4149/2599/4149 3881/5047/3881 \nf 4151/697/4151 4152/5192/4152 4149/2599/4149 4150/5191/4150 \nf 3192/1254/3192 3189/4677/3189 4149/2599/4149 4152/5192/4152 \nf 3872/235/3872 4153/5193/4153 4154/2600/4154 3893/5052/3893 \nf 4155/1387/4155 4156/5194/4156 4154/2600/4154 4153/5193/4153 \nf 4151/697/4151 4150/5191/4150 4154/2600/4154 4156/5194/4156 \nf 3885/1355/3885 3893/5052/3893 4154/2600/4154 4150/5191/4150 \nf 4129/242/4129 4148/5190/4148 4157/2601/4157 4158/5196/4158 \nf 4145/1386/4145 4159/5195/4159 4157/2601/4157 4148/5190/4148 \nf 4151/697/4151 4156/5194/4156 4157/2601/4157 4159/5195/4159 \nf 4155/1387/4155 4158/5196/4158 4157/2601/4157 4156/5194/4156 \nf 3197/143/3197 3200/4684/3200 4160/2602/4160 4143/5187/4143 \nf 3192/1254/3192 4152/5192/4152 4160/2602/4160 3200/4684/3200 \nf 4151/697/4151 4159/5195/4159 4160/2602/4160 4152/5192/4152 \nf 4145/1386/4145 4143/5187/4143 4160/2602/4160 4159/5195/4159 \nf 3872/235/3872 3875/5043/3875 4161/2603/4161 4153/5193/4153 \nf 3870/1352/3870 4162/5197/4162 4161/2603/4161 3875/5043/3875 \nf 4163/698/4163 4164/5198/4164 4161/2603/4161 4162/5197/4162 \nf 4155/1387/4155 4153/5193/4153 4161/2603/4161 4164/5198/4164 \nf 2874/89/2874 2877/4514/2877 4165/2604/4165 3868/5039/3868 \nf 2882/1206/2882 4166/5199/4166 4165/2604/4165 2877/4514/2877 \nf 4163/698/4163 4162/5197/4162 4165/2604/4165 4166/5199/4166 \nf 3870/1352/3870 3868/5039/3868 4165/2604/4165 4162/5197/4162 \nf 2895/94/2895 4136/5182/4136 4167/2605/4167 2896/4521/2896 \nf 4133/1384/4133 4168/5200/4168 4167/2605/4167 4136/5182/4136 \nf 4163/698/4163 4166/5199/4166 4167/2605/4167 4168/5200/4168 \nf 2882/1206/2882 2896/4521/2896 4167/2605/4167 4166/5199/4166 \nf 4129/242/4129 4158/5196/4158 4169/2606/4169 4130/5178/4130 \nf 4155/1387/4155 4164/5198/4164 4169/2606/4169 4158/5196/4158 \nf 4163/698/4163 4168/5200/4168 4169/2606/4169 4164/5198/4164 \nf 4133/1384/4133 4130/5178/4130 4169/2606/4169 4168/5200/4168 \nf 3486/310/3486 3489/4845/3489 4170/2607/4170 4171/5203/4171 \nf 3494/1303/3494 4172/5201/4172 4170/2607/4170 3489/4845/3489 \nf 4173/699/4173 4174/5202/4174 4170/2607/4170 4172/5201/4172 \nf 4175/1390/4175 4171/5203/4171 4170/2607/4170 4174/5202/4174 \nf 3478/323/3478 4176/5204/4176 4177/2608/4177 3504/4852/3504 \nf 4178/1388/4178 4179/5205/4179 4177/2608/4177 4176/5204/4176 \nf 4173/699/4173 4172/5201/4172 4177/2608/4177 4179/5205/4179 \nf 3494/1303/3494 3504/4852/3504 4177/2608/4177 4172/5201/4172 \nf 4180/329/4180 4181/5206/4181 4182/2609/4182 4183/5208/4183 \nf 4184/1389/4184 4185/5207/4185 4182/2609/4182 4181/5206/4181 \nf 4173/699/4173 4179/5205/4179 4182/2609/4182 4185/5207/4185 \nf 4178/1388/4178 4183/5208/4183 4182/2609/4182 4179/5205/4179 \nf 4186/334/4186 4187/5209/4187 4188/2610/4188 4189/5210/4189 \nf 4175/1390/4175 4174/5202/4174 4188/2610/4188 4187/5209/4187 \nf 4173/699/4173 4185/5207/4185 4188/2610/4188 4174/5202/4174 \nf 4184/1389/4184 4189/5210/4189 4188/2610/4188 4185/5207/4185 \nf 3478/323/3478 3481/4839/3481 4190/2611/4190 4176/5204/4176 \nf 3476/1298/3476 4191/5211/4191 4190/2611/4190 3481/4839/3481 \nf 4192/700/4192 4193/5212/4193 4190/2611/4190 4191/5211/4191 \nf 4178/1388/4178 4176/5204/4176 4190/2611/4190 4193/5212/4193 \nf 3292/294/3292 4066/5147/4066 4194/2612/4194 3474/4834/3474 \nf 4070/1378/4070 4195/5213/4195 4194/2612/4194 4066/5147/4066 \nf 4192/700/4192 4191/5211/4191 4194/2612/4194 4195/5213/4195 \nf 3476/1298/3476 3474/4834/3474 4194/2612/4194 4191/5211/4191 \nf 4081/302/4081 4196/5214/4196 4197/2613/4197 4082/5153/4082 \nf 4198/1391/4198 4199/5215/4199 4197/2613/4197 4196/5214/4196 \nf 4192/700/4192 4195/5213/4195 4197/2613/4197 4199/5215/4199 \nf 4070/1378/4070 4082/5153/4082 4197/2613/4197 4195/5213/4195 \nf 4180/329/4180 4183/5208/4183 4200/2614/4200 4201/5216/4201 \nf 4178/1388/4178 4193/5212/4193 4200/2614/4200 4183/5208/4183 \nf 4192/700/4192 4199/5215/4199 4200/2614/4200 4193/5212/4193 \nf 4198/1391/4198 4201/5216/4201 4200/2614/4200 4199/5215/4199 \nf 1259/85/1259 1387/3727/1387 4202/2615/4202 4113/5169/4113 \nf 1391/999/1391 4203/5217/4203 4202/2615/4202 1387/3727/1387 \nf 4204/701/4204 4205/5218/4205 4202/2615/4202 4203/5217/4203 \nf 4115/1381/4115 4113/5169/4113 4202/2615/4202 4205/5218/4205 \nf 1378/131/1378 4206/5219/4206 4207/2616/4207 1399/3732/1399 \nf 4208/1392/4208 4209/5220/4209 4207/2616/4207 4206/5219/4206 \nf 4204/701/4204 4203/5217/4203 4207/2616/4207 4209/5220/4209 \nf 1391/999/1391 1399/3732/1399 4207/2616/4207 4203/5217/4203 \nf 4180/329/4180 4201/5216/4201 4210/2617/4210 4211/5222/4211 \nf 4198/1391/4198 4212/5221/4212 4210/2617/4210 4201/5216/4201 \nf 4204/701/4204 4209/5220/4209 4210/2617/4210 4212/5221/4212 \nf 4208/1392/4208 4211/5222/4211 4210/2617/4210 4209/5220/4209 \nf 4081/302/4081 4118/5172/4118 4213/2618/4213 4196/5214/4196 \nf 4115/1381/4115 4205/5218/4205 4213/2618/4213 4118/5172/4118 \nf 4204/701/4204 4212/5221/4212 4213/2618/4213 4205/5218/4205 \nf 4198/1391/4198 4196/5214/4196 4213/2618/4213 4212/5221/4212 \nf 1378/131/1378 1381/3723/1381 4214/2619/4214 4206/5219/4206 \nf 1376/996/1376 4215/5223/4215 4214/2619/4214 1381/3723/1381 \nf 4216/702/4216 4217/5224/4217 4214/2619/4214 4215/5223/4215 \nf 4208/1392/4208 4206/5219/4206 4214/2619/4214 4217/5224/4217 \nf 1372/129/1372 4218/5225/4218 4219/2620/4219 1373/3718/1373 \nf 4220/1393/4220 4221/5226/4221 4219/2620/4219 4218/5225/4218 \nf 4216/702/4216 4215/5223/4215 4219/2620/4219 4221/5226/4221 \nf 1376/996/1376 1373/3718/1373 4219/2620/4219 4215/5223/4215 \nf 4186/334/4186 4189/5210/4189 4222/2621/4222 4223/5228/4223 \nf 4184/1389/4184 4224/5227/4224 4222/2621/4222 4189/5210/4189 \nf 4216/702/4216 4221/5226/4221 4222/2621/4222 4224/5227/4224 \nf 4220/1393/4220 4223/5228/4223 4222/2621/4222 4221/5226/4221 \nf 4180/329/4180 4211/5222/4211 4225/2622/4225 4181/5206/4181 \nf 4208/1392/4208 4217/5224/4217 4225/2622/4225 4211/5222/4211 \nf 4216/702/4216 4224/5227/4224 4225/2622/4225 4217/5224/4217 \nf 4184/1389/4184 4181/5206/4181 4225/2622/4225 4224/5227/4224 \nf 3697/243/3697 3700/4955/3700 4226/2623/4226 4227/5231/4227 \nf 3705/1334/3705 4228/5229/4228 4226/2623/4226 3700/4955/3700 \nf 4229/703/4229 4230/5230/4230 4226/2623/4226 4228/5229/4228 \nf 4231/1396/4231 4227/5231/4227 4226/2623/4226 4230/5230/4230 \nf 3689/244/3689 4232/5232/4232 4233/2624/4233 3715/4962/3715 \nf 4234/1394/4234 4235/5233/4235 4233/2624/4233 4232/5232/4232 \nf 4229/703/4229 4228/5229/4228 4233/2624/4233 4235/5233/4235 \nf 3705/1334/3705 3715/4962/3715 4233/2624/4233 4228/5229/4228 \nf 4236/245/4236 4237/5234/4237 4238/2625/4238 4239/5236/4239 \nf 4240/1395/4240 4241/5235/4241 4238/2625/4238 4237/5234/4237 \nf 4229/703/4229 4235/5233/4235 4238/2625/4238 4241/5235/4241 \nf 4234/1394/4234 4239/5236/4239 4238/2625/4238 4235/5233/4235 \nf 4242/246/4242 4243/5237/4243 4244/2626/4244 4245/5238/4245 \nf 4231/1396/4231 4230/5230/4230 4244/2626/4244 4243/5237/4243 \nf 4229/703/4229 4241/5235/4241 4244/2626/4244 4230/5230/4230 \nf 4240/1395/4240 4245/5238/4245 4244/2626/4244 4241/5235/4241 \nf 3689/244/3689 3692/4949/3692 4246/2627/4246 4232/5232/4232 \nf 3687/1329/3687 4247/5239/4247 4246/2627/4246 3692/4949/3692 \nf 4248/704/4248 4249/5240/4249 4246/2627/4246 4247/5239/4247 \nf 4234/1394/4234 4232/5232/4232 4246/2627/4246 4249/5240/4249 \nf 2919/98/2919 2922/4537/2922 4250/2628/4250 3684/4943/3684 \nf 2927/1213/2927 4251/5241/4251 4250/2628/4250 2922/4537/2922 \nf 4248/704/4248 4247/5239/4247 4250/2628/4250 4251/5241/4251 \nf 3687/1329/3687 3684/4943/3684 4250/2628/4250 4247/5239/4247 \nf 2911/97/2911 4252/5242/4252 4253/2629/4253 2937/4544/2937 \nf 4254/1397/4254 4255/5243/4255 4253/2629/4253 4252/5242/4252 \nf 4248/704/4248 4251/5241/4251 4253/2629/4253 4255/5243/4255 \nf 2927/1213/2927 2937/4544/2937 4253/2629/4253 4251/5241/4251 \nf 4236/245/4236 4239/5236/4239 4256/2630/4256 4257/5244/4257 \nf 4234/1394/4234 4249/5240/4249 4256/2630/4256 4239/5236/4239 \nf 4248/704/4248 4255/5243/4255 4256/2630/4256 4249/5240/4249 \nf 4254/1397/4254 4257/5244/4257 4256/2630/4256 4255/5243/4255 \nf 2905/96/2905 3523/4863/3523 4258/2631/4258 2906/4526/2906 \nf 3527/1308/3527 4259/5245/4259 4258/2631/4258 3523/4863/3523 \nf 4260/705/4260 4261/5246/4261 4258/2631/4258 4259/5245/4259 \nf 2909/1208/2909 2906/4526/2906 4258/2631/4258 4261/5246/4261 \nf 3538/165/3538 4262/5247/4262 4263/2632/4263 3539/4869/3539 \nf 4264/1398/4264 4265/5248/4265 4263/2632/4263 4262/5247/4262 \nf 4260/705/4260 4259/5245/4259 4263/2632/4263 4265/5248/4265 \nf 3527/1308/3527 3539/4869/3539 4263/2632/4263 4259/5245/4259 \nf 4236/245/4236 4257/5244/4257 4266/2633/4266 4267/5250/4267 \nf 4254/1397/4254 4268/5249/4268 4266/2633/4266 4257/5244/4257 \nf 4260/705/4260 4265/5248/4265 4266/2633/4266 4268/5249/4268 \nf 4264/1398/4264 4267/5250/4267 4266/2633/4266 4265/5248/4265 \nf 2911/97/2911 2914/4531/2914 4269/2634/4269 4252/5242/4252 \nf 2909/1208/2909 4261/5246/4261 4269/2634/4269 2914/4531/2914 \nf 4260/705/4260 4268/5249/4268 4269/2634/4269 4261/5246/4261 \nf 4254/1397/4254 4252/5242/4252 4269/2634/4269 4268/5249/4268 \nf 3538/165/3538 3591/4896/3591 4270/2635/4270 4262/5247/4262 \nf 3588/1315/3588 4271/5251/4271 4270/2635/4270 3591/4896/3591 \nf 4272/706/4272 4273/5252/4273 4270/2635/4270 4271/5251/4271 \nf 4264/1398/4264 4262/5247/4262 4270/2635/4270 4273/5252/4273 \nf 3584/222/3584 4274/5253/4274 4275/2636/4275 3585/4892/3585 \nf 4276/1399/4276 4277/5254/4277 4275/2636/4275 4274/5253/4274 \nf 4272/706/4272 4271/5251/4271 4275/2636/4275 4277/5254/4277 \nf 3588/1315/3588 3585/4892/3585 4275/2636/4275 4271/5251/4271 \nf 4242/246/4242 4245/5238/4245 4278/2637/4278 4279/5256/4279 \nf 4240/1395/4240 4280/5255/4280 4278/2637/4278 4245/5238/4245 \nf 4272/706/4272 4277/5254/4277 4278/2637/4278 4280/5255/4280 \nf 4276/1399/4276 4279/5256/4279 4278/2637/4278 4277/5254/4277 \nf 4236/245/4236 4267/5250/4267 4281/2638/4281 4237/5234/4237 \nf 4264/1398/4264 4273/5252/4273 4281/2638/4281 4267/5250/4267 \nf 4272/706/4272 4280/5255/4280 4281/2638/4281 4273/5252/4273 \nf 4240/1395/4240 4237/5234/4237 4281/2638/4281 4280/5255/4280 \nf 4282/247/4282 4283/5257/4283 4284/2639/4284 4285/5260/4285 \nf 4286/1400/4286 4287/5258/4287 4284/2639/4284 4283/5257/4283 \nf 4288/707/4288 4289/5259/4289 4284/2639/4284 4287/5258/4287 \nf 4290/1403/4290 4285/5260/4285 4284/2639/4284 4289/5259/4289 \nf 4291/248/4291 4292/5261/4292 4293/2640/4293 4294/5263/4294 \nf 4295/1401/4295 4296/5262/4296 4293/2640/4293 4292/5261/4292 \nf 4288/707/4288 4287/5258/4287 4293/2640/4293 4296/5262/4296 \nf 4286/1400/4286 4294/5263/4294 4293/2640/4293 4287/5258/4287 \nf 4297/249/4297 4298/5264/4298 4299/2641/4299 4300/5266/4300 \nf 4301/1402/4301 4302/5265/4302 4299/2641/4299 4298/5264/4298 \nf 4288/707/4288 4296/5262/4296 4299/2641/4299 4302/5265/4302 \nf 4295/1401/4295 4300/5266/4300 4299/2641/4299 4296/5262/4296 \nf 4303/251/4303 4304/5267/4304 4305/2642/4305 4306/5268/4306 \nf 4290/1403/4290 4289/5259/4289 4305/2642/4305 4304/5267/4304 \nf 4288/707/4288 4302/5265/4302 4305/2642/4305 4289/5259/4289 \nf 4301/1402/4301 4306/5268/4306 4305/2642/4305 4302/5265/4302 \nf 4291/248/4291 4307/5269/4307 4308/2643/4308 4292/5261/4292 \nf 4309/1404/4309 4310/5270/4310 4308/2643/4308 4307/5269/4307 \nf 4311/708/4311 4312/5271/4312 4308/2643/4308 4310/5270/4310 \nf 4295/1401/4295 4292/5261/4292 4308/2643/4308 4312/5271/4312 \nf 4313/252/4313 4314/5272/4314 4315/2644/4315 4316/5275/4316 \nf 4317/1405/4317 4318/5274/4318 4315/2644/4315 4314/5272/4314 \nf 4311/708/4311 4310/5270/4310 4315/2644/4315 4318/5274/4318 \nf 4309/1404/4309 4316/5275/4316 4315/2644/4315 4310/5270/4310 \nf 4319/253/4319 4320/5276/4320 4321/2645/4321 4322/5278/4322 \nf 4323/1407/4323 4324/5277/4324 4321/2645/4321 4320/5276/4320 \nf 4311/708/4311 4318/5274/4318 4321/2645/4321 4324/5277/4324 \nf 4317/1405/4317 4322/5278/4322 4321/2645/4321 4318/5274/4318 \nf 4297/249/4297 4300/5266/4300 4325/2646/4325 4326/5280/4326 \nf 4295/1401/4295 4312/5271/4312 4325/2646/4325 4300/5266/4300 \nf 4311/708/4311 4324/5277/4324 4325/2646/4325 4312/5271/4312 \nf 4323/1407/4323 4326/5280/4326 4325/2646/4325 4324/5277/4324 \nf 4327/255/4327 4328/5281/4328 4329/2647/4329 4330/5284/4330 \nf 4331/1408/4331 4332/5282/4332 4329/2647/4329 4328/5281/4328 \nf 4333/709/4333 4334/5283/4334 4329/2647/4329 4332/5282/4332 \nf 4335/1410/4335 4330/5284/4330 4329/2647/4329 4334/5283/4334 \nf 4336/256/4336 4337/5286/4337 4338/2648/4338 4339/5288/4339 \nf 4340/1409/4340 4341/5287/4341 4338/2648/4338 4337/5286/4337 \nf 4333/709/4333 4332/5282/4332 4338/2648/4338 4341/5287/4341 \nf 4331/1408/4331 4339/5288/4339 4338/2648/4338 4332/5282/4332 \nf 4297/249/4297 4326/5280/4326 4342/2649/4342 4343/5290/4343 \nf 4323/1407/4323 4344/5289/4344 4342/2649/4342 4326/5280/4326 \nf 4333/709/4333 4341/5287/4341 4342/2649/4342 4344/5289/4344 \nf 4340/1409/4340 4343/5290/4343 4342/2649/4342 4341/5287/4341 \nf 4319/253/4319 4345/5291/4345 4346/2650/4346 4320/5276/4320 \nf 4335/1410/4335 4334/5283/4334 4346/2650/4346 4345/5291/4345 \nf 4333/709/4333 4344/5289/4344 4346/2650/4346 4334/5283/4334 \nf 4323/1407/4323 4320/5276/4320 4346/2650/4346 4344/5289/4344 \nf 4336/256/4336 4347/5293/4347 4348/2651/4348 4337/5286/4337 \nf 4349/1412/4349 4350/5294/4350 4348/2651/4348 4347/5293/4347 \nf 4351/710/4351 4352/5295/4352 4348/2651/4348 4350/5294/4350 \nf 4340/1409/4340 4337/5286/4337 4348/2651/4348 4352/5295/4352 \nf 4353/257/4353 4354/5296/4354 4355/2652/4355 4356/5298/4356 \nf 4357/1413/4357 4358/5297/4358 4355/2652/4355 4354/5296/4354 \nf 4351/710/4351 4350/5294/4350 4355/2652/4355 4358/5297/4358 \nf 4349/1412/4349 4356/5298/4356 4355/2652/4355 4350/5294/4350 \nf 4303/251/4303 4306/5268/4306 4359/2653/4359 4360/5300/4360 \nf 4301/1402/4301 4361/5299/4361 4359/2653/4359 4306/5268/4306 \nf 4351/710/4351 4358/5297/4358 4359/2653/4359 4361/5299/4361 \nf 4357/1413/4357 4360/5300/4360 4359/2653/4359 4358/5297/4358 \nf 4297/249/4297 4343/5290/4343 4362/2654/4362 4298/5264/4298 \nf 4340/1409/4340 4352/5295/4352 4362/2654/4362 4343/5290/4343 \nf 4351/710/4351 4361/5299/4361 4362/2654/4362 4352/5295/4352 \nf 4301/1402/4301 4298/5264/4298 4362/2654/4362 4361/5299/4361 \nf 4363/262/4363 4364/5301/4364 4365/2655/4365 4366/5304/4366 \nf 4367/1414/4367 4368/5302/4368 4365/2655/4365 4364/5301/4364 \nf 4369/711/4369 4370/5303/4370 4365/2655/4365 4368/5302/4368 \nf 4371/1417/4371 4366/5304/4366 4365/2655/4365 4370/5303/4370 \nf 4372/264/4372 4373/5305/4373 4374/2656/4374 4375/5307/4375 \nf 4376/1415/4376 4377/5306/4377 4374/2656/4374 4373/5305/4373 \nf 4369/711/4369 4368/5302/4368 4374/2656/4374 4377/5306/4377 \nf 4367/1414/4367 4375/5307/4375 4374/2656/4374 4368/5302/4368 \nf 4378/346/4378 4379/5308/4379 4380/2657/4380 4381/5310/4381 \nf 4382/1416/4382 4383/5309/4383 4380/2657/4380 4379/5308/4379 \nf 4369/711/4369 4377/5306/4377 4380/2657/4380 4383/5309/4383 \nf 4376/1415/4376 4381/5310/4381 4380/2657/4380 4377/5306/4377 \nf 4384/348/4384 4385/5311/4385 4386/2658/4386 4387/5312/4387 \nf 4371/1417/4371 4370/5303/4370 4386/2658/4386 4385/5311/4385 \nf 4369/711/4369 4383/5309/4383 4386/2658/4386 4370/5303/4370 \nf 4382/1416/4382 4387/5312/4387 4386/2658/4386 4383/5309/4383 \nf 4372/264/4372 4388/5313/4388 4389/2659/4389 4373/5305/4373 \nf 4390/1418/4390 4391/5314/4391 4389/2659/4389 4388/5313/4388 \nf 4392/712/4392 4393/5315/4393 4389/2659/4389 4391/5314/4391 \nf 4376/1415/4376 4373/5305/4373 4389/2659/4389 4393/5315/4393 \nf 4394/349/4394 4395/5316/4395 4396/2660/4396 4397/5318/4397 \nf 4398/1419/4398 4399/5317/4399 4396/2660/4396 4395/5316/4395 \nf 4392/712/4392 4391/5314/4391 4396/2660/4396 4399/5317/4399 \nf 4390/1418/4390 4397/5318/4397 4396/2660/4396 4391/5314/4391 \nf 4400/350/4400 4401/5319/4401 4402/2661/4402 4403/5321/4403 \nf 4404/1420/4404 4405/5320/4405 4402/2661/4402 4401/5319/4401 \nf 4392/712/4392 4399/5317/4399 4402/2661/4402 4405/5320/4405 \nf 4398/1419/4398 4403/5321/4403 4402/2661/4402 4399/5317/4399 \nf 4378/346/4378 4381/5310/4381 4406/2662/4406 4407/5322/4407 \nf 4376/1415/4376 4393/5315/4393 4406/2662/4406 4381/5310/4381 \nf 4392/712/4392 4405/5320/4405 4406/2662/4406 4393/5315/4393 \nf 4404/1420/4404 4407/5322/4407 4406/2662/4406 4405/5320/4405 \nf 4408/351/4408 4409/5323/4409 4410/2663/4410 4411/5327/4411 \nf 4412/1421/4412 4413/5325/4413 4410/2663/4410 4409/5323/4409 \nf 4414/713/4414 4415/5326/4415 4410/2663/4410 4413/5325/4413 \nf 4416/1424/4416 4411/5327/4411 4410/2663/4410 4415/5326/4415 \nf 4417/353/4417 4418/5328/4418 4419/2664/4419 4420/5330/4420 \nf 4421/1423/4421 4422/5329/4422 4419/2664/4419 4418/5328/4418 \nf 4414/713/4414 4413/5325/4413 4419/2664/4419 4422/5329/4422 \nf 4412/1421/4412 4420/5330/4420 4419/2664/4419 4413/5325/4413 \nf 4378/346/4378 4407/5322/4407 4423/2665/4423 4424/5333/4424 \nf 4404/1420/4404 4425/5332/4425 4423/2665/4423 4407/5322/4407 \nf 4414/713/4414 4422/5329/4422 4423/2665/4423 4425/5332/4425 \nf 4421/1423/4421 4424/5333/4424 4423/2665/4423 4422/5329/4422 \nf 4400/350/4400 4426/5334/4426 4427/2666/4427 4401/5319/4401 \nf 4416/1424/4416 4415/5326/4415 4427/2666/4427 4426/5334/4426 \nf 4414/713/4414 4425/5332/4425 4427/2666/4427 4415/5326/4415 \nf 4404/1420/4404 4401/5319/4401 4427/2666/4427 4425/5332/4425 \nf 4417/353/4417 4428/5335/4428 4429/2667/4429 4418/5328/4418 \nf 4430/1425/4430 4431/5337/4431 4429/2667/4429 4428/5335/4428 \nf 4432/714/4432 4433/5338/4433 4429/2667/4429 4431/5337/4431 \nf 4421/1423/4421 4418/5328/4418 4429/2667/4429 4433/5338/4433 \nf 4434/354/4434 4435/5339/4435 4436/2668/4436 4437/5342/4437 \nf 4438/1427/4438 4439/5341/4439 4436/2668/4436 4435/5339/4435 \nf 4432/714/4432 4431/5337/4431 4436/2668/4436 4439/5341/4439 \nf 4430/1425/4430 4437/5342/4437 4436/2668/4436 4431/5337/4431 \nf 4384/348/4384 4387/5312/4387 4440/2669/4440 4441/5345/4441 \nf 4382/1416/4382 4442/5344/4442 4440/2669/4440 4387/5312/4387 \nf 4432/714/4432 4439/5341/4439 4440/2669/4440 4442/5344/4442 \nf 4438/1427/4438 4441/5345/4441 4440/2669/4440 4439/5341/4439 \nf 4378/346/4378 4424/5333/4424 4443/2670/4443 4379/5308/4379 \nf 4421/1423/4421 4433/5338/4433 4443/2670/4443 4424/5333/4424 \nf 4432/714/4432 4442/5344/4442 4443/2670/4443 4433/5338/4433 \nf 4382/1416/4382 4379/5308/4379 4443/2670/4443 4442/5344/4442 \nf 4353/257/4353 4444/5347/4444 4445/2671/4445 4354/5296/4354 \nf 4446/1429/4446 4447/5348/4447 4445/2671/4445 4444/5347/4444 \nf 4448/715/4448 4449/5349/4449 4445/2671/4445 4447/5348/4447 \nf 4357/1413/4357 4354/5296/4354 4445/2671/4445 4449/5349/4449 \nf 4450/355/4450 4451/5350/4451 4452/2672/4452 4453/5352/4453 \nf 4454/1430/4454 4455/5351/4455 4452/2672/4452 4451/5350/4451 \nf 4448/715/4448 4447/5348/4447 4452/2672/4452 4455/5351/4455 \nf 4446/1429/4446 4453/5352/4453 4452/2672/4452 4447/5348/4447 \nf 4456/356/4456 4457/5353/4457 4458/2673/4458 4459/5355/4459 \nf 4460/1431/4460 4461/5354/4461 4458/2673/4458 4457/5353/4457 \nf 4448/715/4448 4455/5351/4455 4458/2673/4458 4461/5354/4461 \nf 4454/1430/4454 4459/5355/4459 4458/2673/4458 4455/5351/4455 \nf 4303/251/4303 4360/5300/4360 4462/2674/4462 4463/5356/4463 \nf 4357/1413/4357 4449/5349/4449 4462/2674/4462 4360/5300/4360 \nf 4448/715/4448 4461/5354/4461 4462/2674/4462 4449/5349/4449 \nf 4460/1431/4460 4463/5356/4463 4462/2674/4462 4461/5354/4461 \nf 4450/355/4450 4464/5357/4464 4465/2675/4465 4451/5350/4451 \nf 4466/1432/4466 4467/5358/4467 4465/2675/4465 4464/5357/4464 \nf 4468/716/4468 4469/5359/4469 4465/2675/4465 4467/5358/4467 \nf 4454/1430/4454 4451/5350/4451 4465/2675/4465 4469/5359/4469 \nf 4470/357/4470 4471/5360/4471 4472/2676/4472 4473/5362/4473 \nf 4474/1433/4474 4475/5361/4475 4472/2676/4472 4471/5360/4471 \nf 4468/716/4468 4467/5358/4467 4472/2676/4472 4475/5361/4475 \nf 4466/1432/4466 4473/5362/4473 4472/2676/4472 4467/5358/4467 \nf 4476/358/4476 4477/5363/4477 4478/2677/4478 4479/5365/4479 \nf 4480/1434/4480 4481/5364/4481 4478/2677/4478 4477/5363/4477 \nf 4468/716/4468 4475/5361/4475 4478/2677/4478 4481/5364/4481 \nf 4474/1433/4474 4479/5365/4479 4478/2677/4478 4475/5361/4475 \nf 4456/356/4456 4459/5355/4459 4482/2678/4482 4483/5366/4483 \nf 4454/1430/4454 4469/5359/4469 4482/2678/4482 4459/5355/4459 \nf 4468/716/4468 4481/5364/4481 4482/2678/4482 4469/5359/4469 \nf 4480/1434/4480 4483/5366/4483 4482/2678/4482 4481/5364/4481 \nf 4484/359/4484 4485/5367/4485 4486/2679/4486 4487/5370/4487 \nf 4488/1435/4488 4489/5368/4489 4486/2679/4486 4485/5367/4485 \nf 4490/717/4490 4491/5369/4491 4486/2679/4486 4489/5368/4489 \nf 4492/1437/4492 4487/5370/4487 4486/2679/4486 4491/5369/4491 \nf 4493/360/4493 4494/5371/4494 4495/2680/4495 4496/5373/4496 \nf 4497/1436/4497 4498/5372/4498 4495/2680/4495 4494/5371/4494 \nf 4490/717/4490 4489/5368/4489 4495/2680/4495 4498/5372/4498 \nf 4488/1435/4488 4496/5373/4496 4495/2680/4495 4489/5368/4489 \nf 4456/356/4456 4483/5366/4483 4499/2681/4499 4500/5375/4500 \nf 4480/1434/4480 4501/5374/4501 4499/2681/4499 4483/5366/4483 \nf 4490/717/4490 4498/5372/4498 4499/2681/4499 4501/5374/4501 \nf 4497/1436/4497 4500/5375/4500 4499/2681/4499 4498/5372/4498 \nf 4476/358/4476 4502/5376/4502 4503/2682/4503 4477/5363/4477 \nf 4492/1437/4492 4491/5369/4491 4503/2682/4503 4502/5376/4502 \nf 4490/717/4490 4501/5374/4501 4503/2682/4503 4491/5369/4491 \nf 4480/1434/4480 4477/5363/4477 4503/2682/4503 4501/5374/4501 \nf 4493/360/4493 4504/5377/4504 4505/2683/4505 4494/5371/4494 \nf 4506/1438/4506 4507/5378/4507 4505/2683/4505 4504/5377/4504 \nf 4508/718/4508 4509/5379/4509 4505/2683/4505 4507/5378/4507 \nf 4497/1436/4497 4494/5371/4494 4505/2683/4505 4509/5379/4509 \nf 4282/247/4282 4285/5260/4285 4510/2684/4510 4511/5381/4511 \nf 4290/1403/4290 4512/5380/4512 4510/2684/4510 4285/5260/4285 \nf 4508/718/4508 4507/5378/4507 4510/2684/4510 4512/5380/4512 \nf 4506/1438/4506 4511/5381/4511 4510/2684/4510 4507/5378/4507 \nf 4303/251/4303 4463/5356/4463 4513/2685/4513 4304/5267/4304 \nf 4460/1431/4460 4514/5382/4514 4513/2685/4513 4463/5356/4463 \nf 4508/718/4508 4512/5380/4512 4513/2685/4513 4514/5382/4514 \nf 4290/1403/4290 4304/5267/4304 4513/2685/4513 4512/5380/4512 \nf 4456/356/4456 4500/5375/4500 4515/2686/4515 4457/5353/4457 \nf 4497/1436/4497 4509/5379/4509 4515/2686/4515 4500/5375/4500 \nf 4508/718/4508 4514/5382/4514 4515/2686/4515 4509/5379/4509 \nf 4460/1431/4460 4457/5353/4457 4515/2686/4515 4514/5382/4514 \nf 4516/361/4516 4517/5383/4517 4518/2687/4518 4519/5386/4519 \nf 4520/1439/4520 4521/5384/4521 4518/2687/4518 4517/5383/4517 \nf 4522/719/4522 4523/5385/4523 4518/2687/4518 4521/5384/4521 \nf 4524/1442/4524 4519/5386/4519 4518/2687/4518 4523/5385/4523 \nf 4525/363/4525 4526/5387/4526 4527/2688/4527 4528/5389/4528 \nf 4529/1440/4529 4530/5388/4530 4527/2688/4527 4526/5387/4526 \nf 4522/719/4522 4521/5384/4521 4527/2688/4527 4530/5388/4530 \nf 4520/1439/4520 4528/5389/4528 4527/2688/4527 4521/5384/4521 \nf 4531/364/4531 4532/5390/4532 4533/2689/4533 4534/5392/4534 \nf 4535/1441/4535 4536/5391/4536 4533/2689/4533 4532/5390/4532 \nf 4522/719/4522 4530/5388/4530 4533/2689/4533 4536/5391/4536 \nf 4529/1440/4529 4534/5392/4534 4533/2689/4533 4530/5388/4530 \nf 4537/366/4537 4538/5393/4538 4539/2690/4539 4540/5394/4540 \nf 4524/1442/4524 4523/5385/4523 4539/2690/4539 4538/5393/4538 \nf 4522/719/4522 4536/5391/4536 4539/2690/4539 4523/5385/4523 \nf 4535/1441/4535 4540/5394/4540 4539/2690/4539 4536/5391/4536 \nf 4525/363/4525 4541/5395/4541 4542/2691/4542 4526/5387/4526 \nf 4543/1443/4543 4544/5396/4544 4542/2691/4542 4541/5395/4541 \nf 4545/720/4545 4546/5397/4546 4542/2691/4542 4544/5396/4544 \nf 4529/1440/4529 4526/5387/4526 4542/2691/4542 4546/5397/4546 \nf 4547/368/4547 4548/5398/4548 4549/2692/4549 4550/5400/4550 \nf 4551/1444/4551 4552/5399/4552 4549/2692/4549 4548/5398/4548 \nf 4545/720/4545 4544/5396/4544 4549/2692/4549 4552/5399/4552 \nf 4543/1443/4543 4550/5400/4550 4549/2692/4549 4544/5396/4544 \nf 4553/371/4553 4554/5401/4554 4555/2693/4555 4556/5403/4556 \nf 4557/1445/4557 4558/5402/4558 4555/2693/4555 4554/5401/4554 \nf 4545/720/4545 4552/5399/4552 4555/2693/4555 4558/5402/4558 \nf 4551/1444/4551 4556/5403/4556 4555/2693/4555 4552/5399/4552 \nf 4531/364/4531 4534/5392/4534 4559/2694/4559 4560/5404/4560 \nf 4529/1440/4529 4546/5397/4546 4559/2694/4559 4534/5392/4534 \nf 4545/720/4545 4558/5402/4558 4559/2694/4559 4546/5397/4546 \nf 4557/1445/4557 4560/5404/4560 4559/2694/4559 4558/5402/4558 \nf 4394/349/4394 4561/5405/4561 4562/2695/4562 4563/5408/4563 \nf 4564/1446/4564 4565/5406/4565 4562/2695/4562 4561/5405/4561 \nf 4566/721/4566 4567/5407/4567 4562/2695/4562 4565/5406/4565 \nf 4568/1448/4568 4563/5408/4563 4562/2695/4562 4567/5407/4567 \nf 4569/372/4569 4570/5409/4570 4571/2696/4571 4572/5411/4572 \nf 4573/1447/4573 4574/5410/4574 4571/2696/4571 4570/5409/4570 \nf 4566/721/4566 4565/5406/4565 4571/2696/4571 4574/5410/4574 \nf 4564/1446/4564 4572/5411/4572 4571/2696/4571 4565/5406/4565 \nf 4531/364/4531 4560/5404/4560 4575/2697/4575 4576/5413/4576 \nf 4557/1445/4557 4577/5412/4577 4575/2697/4575 4560/5404/4560 \nf 4566/721/4566 4574/5410/4574 4575/2697/4575 4577/5412/4577 \nf 4573/1447/4573 4576/5413/4576 4575/2697/4575 4574/5410/4574 \nf 4553/371/4553 4578/5414/4578 4579/2698/4579 4554/5401/4554 \nf 4568/1448/4568 4567/5407/4567 4579/2698/4579 4578/5414/4578 \nf 4566/721/4566 4577/5412/4577 4579/2698/4579 4567/5407/4567 \nf 4557/1445/4557 4554/5401/4554 4579/2698/4579 4577/5412/4577 \nf 4569/372/4569 4580/5415/4580 4581/2699/4581 4570/5409/4570 \nf 4582/1449/4582 4583/5416/4583 4581/2699/4581 4580/5415/4580 \nf 4584/722/4584 4585/5417/4585 4581/2699/4581 4583/5416/4583 \nf 4573/1447/4573 4570/5409/4570 4581/2699/4581 4585/5417/4585 \nf 4586/374/4586 4587/5418/4587 4588/2700/4588 4589/5420/4589 \nf 4590/1450/4590 4591/5419/4591 4588/2700/4588 4587/5418/4587 \nf 4584/722/4584 4583/5416/4583 4588/2700/4588 4591/5419/4591 \nf 4582/1449/4582 4589/5420/4589 4588/2700/4588 4583/5416/4583 \nf 4537/366/4537 4540/5394/4540 4592/2701/4592 4593/5422/4593 \nf 4535/1441/4535 4594/5421/4594 4592/2701/4592 4540/5394/4540 \nf 4584/722/4584 4591/5419/4591 4592/2701/4592 4594/5421/4594 \nf 4590/1450/4590 4593/5422/4593 4592/2701/4592 4591/5419/4591 \nf 4531/364/4531 4576/5413/4576 4595/2702/4595 4532/5390/4532 \nf 4573/1447/4573 4585/5417/4585 4595/2702/4595 4576/5413/4576 \nf 4584/722/4584 4594/5421/4594 4595/2702/4595 4585/5417/4585 \nf 4535/1441/4535 4532/5390/4532 4595/2702/4595 4594/5421/4594 \nf 4596/375/4596 4597/5423/4597 4598/2703/4598 4599/5426/4599 \nf 4600/1451/4600 4601/5424/4601 4598/2703/4598 4597/5423/4597 \nf 4602/723/4602 4603/5425/4603 4598/2703/4598 4601/5424/4601 \nf 4604/1455/4604 4599/5426/4599 4598/2703/4598 4603/5425/4603 \nf 4605/376/4605 4606/5427/4606 4607/2704/4607 4608/5429/4608 \nf 4609/1452/4609 4610/5428/4610 4607/2704/4607 4606/5427/4606 \nf 4602/723/4602 4601/5424/4601 4607/2704/4607 4610/5428/4610 \nf 4600/1451/4600 4608/5429/4608 4607/2704/4607 4601/5424/4601 \nf 4611/377/4611 4612/5430/4612 4613/2705/4613 4614/5433/4614 \nf 4615/1453/4615 4616/5432/4616 4613/2705/4613 4612/5430/4612 \nf 4602/723/4602 4610/5428/4610 4613/2705/4613 4616/5432/4616 \nf 4609/1452/4609 4614/5433/4614 4613/2705/4613 4610/5428/4610 \nf 4617/378/4617 4618/5434/4618 4619/2706/4619 4620/5435/4620 \nf 4604/1455/4604 4603/5425/4603 4619/2706/4619 4618/5434/4618 \nf 4602/723/4602 4616/5432/4616 4619/2706/4619 4603/5425/4603 \nf 4615/1453/4615 4620/5435/4620 4619/2706/4619 4616/5432/4616 \nf 4605/376/4605 4621/5437/4621 4622/2707/4622 4606/5427/4606 \nf 4623/1456/4623 4624/5438/4624 4622/2707/4622 4621/5437/4621 \nf 4625/724/4625 4626/5439/4626 4622/2707/4622 4624/5438/4624 \nf 4609/1452/4609 4606/5427/4606 4622/2707/4622 4626/5439/4626 \nf 4363/262/4363 4366/5304/4366 4627/2708/4627 4628/5441/4628 \nf 4371/1417/4371 4629/5440/4629 4627/2708/4627 4366/5304/4366 \nf 4625/724/4625 4624/5438/4624 4627/2708/4627 4629/5440/4629 \nf 4623/1456/4623 4628/5441/4628 4627/2708/4627 4624/5438/4624 \nf 4384/348/4384 4630/5442/4630 4631/2709/4631 4385/5311/4385 \nf 4632/1457/4632 4633/5444/4633 4631/2709/4631 4630/5442/4630 \nf 4625/724/4625 4629/5440/4629 4631/2709/4631 4633/5444/4633 \nf 4371/1417/4371 4385/5311/4385 4631/2709/4631 4629/5440/4629 \nf 4611/377/4611 4614/5433/4614 4634/2710/4634 4635/5445/4635 \nf 4609/1452/4609 4626/5439/4626 4634/2710/4634 4614/5433/4614 \nf 4625/724/4625 4633/5444/4633 4634/2710/4634 4626/5439/4626 \nf 4632/1457/4632 4635/5445/4635 4634/2710/4634 4633/5444/4633 \nf 4434/411/4434 4636/5447/4636 4637/2711/4637 4435/5340/4435 \nf 4638/1459/4638 4639/5448/4639 4637/2711/4637 4636/5447/4636 \nf 4640/725/4640 4641/5449/4641 4637/2711/4637 4639/5448/4639 \nf 4438/1428/4438 4435/5340/4435 4637/2711/4637 4641/5449/4641 \nf 4642/412/4642 4643/5450/4643 4644/2712/4644 4645/5452/4645 \nf 4646/1460/4646 4647/5451/4647 4644/2712/4644 4643/5450/4643 \nf 4640/725/4640 4639/5448/4639 4644/2712/4644 4647/5451/4647 \nf 4638/1459/4638 4645/5452/4645 4644/2712/4644 4639/5448/4639 \nf 4611/415/4611 4635/5446/4635 4648/2713/4648 4649/5454/4649 \nf 4632/1458/4632 4650/5453/4650 4648/2713/4648 4635/5446/4635 \nf 4640/725/4640 4647/5451/4647 4648/2713/4648 4650/5453/4650 \nf 4646/1460/4646 4649/5454/4649 4648/2713/4648 4647/5451/4647 \nf 4384/416/4384 4441/5346/4441 4651/2714/4651 4630/5443/4630 \nf 4438/1428/4438 4641/5449/4641 4651/2714/4651 4441/5346/4441 \nf 4640/725/4640 4650/5453/4650 4651/2714/4651 4641/5449/4641 \nf 4632/1458/4632 4630/5443/4630 4651/2714/4651 4650/5453/4650 \nf 4642/412/4642 4652/5455/4652 4653/2715/4653 4643/5450/4643 \nf 4654/1461/4654 4655/5456/4655 4653/2715/4653 4652/5455/4652 \nf 4656/726/4656 4657/5457/4657 4653/2715/4653 4655/5456/4655 \nf 4646/1460/4646 4643/5450/4643 4653/2715/4653 4657/5457/4657 \nf 4658/421/4658 4659/5458/4659 4660/2716/4660 4661/5460/4661 \nf 4662/1462/4662 4663/5459/4663 4660/2716/4660 4659/5458/4659 \nf 4656/726/4656 4655/5456/4655 4660/2716/4660 4663/5459/4663 \nf 4654/1461/4654 4661/5460/4661 4660/2716/4660 4655/5456/4655 \nf 4617/422/4617 4620/5436/4620 4664/2717/4664 4665/5462/4665 \nf 4615/1454/4615 4666/5461/4666 4664/2717/4664 4620/5436/4620 \nf 4656/726/4656 4663/5459/4663 4664/2717/4664 4666/5461/4666 \nf 4662/1462/4662 4665/5462/4665 4664/2717/4664 4663/5459/4663 \nf 4611/415/4611 4649/5454/4649 4667/2718/4667 4612/5431/4612 \nf 4646/1460/4646 4657/5457/4657 4667/2718/4667 4649/5454/4649 \nf 4656/726/4656 4666/5461/4666 4667/2718/4667 4657/5457/4657 \nf 4615/1454/4615 4612/5431/4612 4667/2718/4667 4666/5461/4666 \nf 4394/349/4394 4563/5408/4563 4668/2719/4668 4395/5316/4395 \nf 4568/1448/4568 4669/5463/4669 4668/2719/4668 4563/5408/4563 \nf 4670/727/4670 4671/5464/4671 4668/2719/4668 4669/5463/4669 \nf 4398/1419/4398 4395/5316/4395 4668/2719/4668 4671/5464/4671 \nf 4553/371/4553 4672/5465/4672 4673/2720/4673 4578/5414/4578 \nf 4674/1463/4674 4675/5466/4675 4673/2720/4673 4672/5465/4672 \nf 4670/727/4670 4669/5463/4669 4673/2720/4673 4675/5466/4675 \nf 4568/1448/4568 4578/5414/4578 4673/2720/4673 4669/5463/4669 \nf 4676/382/4676 4677/5467/4677 4678/2721/4678 4679/5469/4679 \nf 4680/1464/4680 4681/5468/4681 4678/2721/4678 4677/5467/4677 \nf 4670/727/4670 4675/5466/4675 4678/2721/4678 4681/5468/4681 \nf 4674/1463/4674 4679/5469/4679 4678/2721/4678 4675/5466/4675 \nf 4400/350/4400 4403/5321/4403 4682/2722/4682 4683/5470/4683 \nf 4398/1419/4398 4671/5464/4671 4682/2722/4682 4403/5321/4403 \nf 4670/727/4670 4681/5468/4681 4682/2722/4682 4671/5464/4671 \nf 4680/1464/4680 4683/5470/4683 4682/2722/4682 4681/5468/4681 \nf 4553/371/4553 4556/5403/4556 4684/2723/4684 4672/5465/4672 \nf 4551/1444/4551 4685/5471/4685 4684/2723/4684 4556/5403/4556 \nf 4686/728/4686 4687/5472/4687 4684/2723/4684 4685/5471/4685 \nf 4674/1463/4674 4672/5465/4672 4684/2723/4684 4687/5472/4687 \nf 4547/368/4547 4688/5473/4688 4689/2724/4689 4548/5398/4548 \nf 4690/1465/4690 4691/5474/4691 4689/2724/4689 4688/5473/4688 \nf 4686/728/4686 4685/5471/4685 4689/2724/4689 4691/5474/4691 \nf 4551/1444/4551 4548/5398/4548 4689/2724/4689 4685/5471/4685 \nf 4692/383/4692 4693/5475/4693 4694/2725/4694 4695/5477/4695 \nf 4696/1466/4696 4697/5476/4697 4694/2725/4694 4693/5475/4693 \nf 4686/728/4686 4691/5474/4691 4694/2725/4694 4697/5476/4697 \nf 4690/1465/4690 4695/5477/4695 4694/2725/4694 4691/5474/4691 \nf 4676/382/4676 4679/5469/4679 4698/2726/4698 4699/5478/4699 \nf 4674/1463/4674 4687/5472/4687 4698/2726/4698 4679/5469/4679 \nf 4686/728/4686 4697/5476/4697 4698/2726/4698 4687/5472/4687 \nf 4696/1466/4696 4699/5478/4699 4698/2726/4698 4697/5476/4697 \nf 4700/384/4700 4701/5479/4701 4702/2727/4702 4703/5483/4703 \nf 4704/1467/4704 4705/5481/4705 4702/2727/4702 4701/5479/4701 \nf 4706/729/4706 4707/5482/4707 4702/2727/4702 4705/5481/4705 \nf 4708/1470/4708 4703/5483/4703 4702/2727/4702 4707/5482/4707 \nf 4709/385/4709 4710/5484/4710 4711/2728/4711 4712/5486/4712 \nf 4713/1469/4713 4714/5485/4714 4711/2728/4711 4710/5484/4710 \nf 4706/729/4706 4705/5481/4705 4711/2728/4711 4714/5485/4714 \nf 4704/1467/4704 4712/5486/4712 4711/2728/4711 4705/5481/4705 \nf 4676/382/4676 4699/5478/4699 4715/2729/4715 4716/5489/4716 \nf 4696/1466/4696 4717/5488/4717 4715/2729/4715 4699/5478/4699 \nf 4706/729/4706 4714/5485/4714 4715/2729/4715 4717/5488/4717 \nf 4713/1469/4713 4716/5489/4716 4715/2729/4715 4714/5485/4714 \nf 4692/383/4692 4718/5490/4718 4719/2730/4719 4693/5475/4693 \nf 4708/1470/4708 4707/5482/4707 4719/2730/4719 4718/5490/4718 \nf 4706/729/4706 4717/5488/4717 4719/2730/4719 4707/5482/4707 \nf 4696/1466/4696 4693/5475/4693 4719/2730/4719 4717/5488/4717 \nf 4709/385/4709 4720/5491/4720 4721/2731/4721 4710/5484/4710 \nf 4722/1471/4722 4723/5493/4723 4721/2731/4721 4720/5491/4720 \nf 4724/730/4724 4725/5494/4725 4721/2731/4721 4723/5493/4723 \nf 4713/1469/4713 4710/5484/4710 4721/2731/4721 4725/5494/4725 \nf 4408/351/4408 4411/5327/4411 4726/2732/4726 4727/5496/4727 \nf 4416/1424/4416 4728/5495/4728 4726/2732/4726 4411/5327/4411 \nf 4724/730/4724 4723/5493/4723 4726/2732/4726 4728/5495/4728 \nf 4722/1471/4722 4727/5496/4727 4726/2732/4726 4723/5493/4723 \nf 4400/350/4400 4683/5470/4683 4729/2733/4729 4426/5334/4426 \nf 4680/1464/4680 4730/5498/4730 4729/2733/4729 4683/5470/4683 \nf 4724/730/4724 4728/5495/4728 4729/2733/4729 4730/5498/4730 \nf 4416/1424/4416 4426/5334/4426 4729/2733/4729 4728/5495/4728 \nf 4676/382/4676 4716/5489/4716 4731/2734/4731 4677/5467/4677 \nf 4713/1469/4713 4725/5494/4725 4731/2734/4731 4716/5489/4716 \nf 4724/730/4724 4730/5498/4730 4731/2734/4731 4725/5494/4725 \nf 4680/1464/4680 4677/5467/4677 4731/2734/4731 4730/5498/4730 \nf 4394/349/4394 4397/5318/4397 4732/2735/4732 4561/5405/4561 \nf 4390/1418/4390 4733/5499/4733 4732/2735/4732 4397/5318/4397 \nf 4734/731/4734 4735/5500/4735 4732/2735/4732 4733/5499/4733 \nf 4564/1446/4564 4561/5405/4561 4732/2735/4732 4735/5500/4735 \nf 4372/264/4372 4736/5501/4736 4737/2736/4737 4388/5313/4388 \nf 4738/1473/4738 4739/5502/4739 4737/2736/4737 4736/5501/4736 \nf 4734/731/4734 4733/5499/4733 4737/2736/4737 4739/5502/4739 \nf 4390/1418/4390 4388/5313/4388 4737/2736/4737 4733/5499/4733 \nf 4740/388/4740 4741/5503/4741 4742/2737/4742 4743/5505/4743 \nf 4744/1474/4744 4745/5504/4745 4742/2737/4742 4741/5503/4741 \nf 4734/731/4734 4739/5502/4739 4742/2737/4742 4745/5504/4745 \nf 4738/1473/4738 4743/5505/4743 4742/2737/4742 4739/5502/4739 \nf 4569/372/4569 4572/5411/4572 4746/2738/4746 4747/5506/4747 \nf 4564/1446/4564 4735/5500/4735 4746/2738/4746 4572/5411/4572 \nf 4734/731/4734 4745/5504/4745 4746/2738/4746 4735/5500/4735 \nf 4744/1474/4744 4747/5506/4747 4746/2738/4746 4745/5504/4745 \nf 4372/264/4372 4375/5307/4375 4748/2739/4748 4736/5501/4736 \nf 4367/1414/4367 4749/5507/4749 4748/2739/4748 4375/5307/4375 \nf 4750/732/4750 4751/5508/4751 4748/2739/4748 4749/5507/4749 \nf 4738/1473/4738 4736/5501/4736 4748/2739/4748 4751/5508/4751 \nf 4363/262/4363 4628/5441/4628 4752/2740/4752 4364/5301/4364 \nf 4623/1456/4623 4753/5509/4753 4752/2740/4752 4628/5441/4628 \nf 4750/732/4750 4749/5507/4749 4752/2740/4752 4753/5509/4753 \nf 4367/1414/4367 4364/5301/4364 4752/2740/4752 4749/5507/4749 \nf 4605/376/4605 4754/5510/4754 4755/2741/4755 4621/5437/4621 \nf 4756/1475/4756 4757/5511/4757 4755/2741/4755 4754/5510/4754 \nf 4750/732/4750 4753/5509/4753 4755/2741/4755 4757/5511/4757 \nf 4623/1456/4623 4621/5437/4621 4755/2741/4755 4753/5509/4753 \nf 4740/388/4740 4743/5505/4743 4758/2742/4758 4759/5512/4759 \nf 4738/1473/4738 4751/5508/4751 4758/2742/4758 4743/5505/4743 \nf 4750/732/4750 4757/5511/4757 4758/2742/4758 4751/5508/4751 \nf 4756/1475/4756 4759/5512/4759 4758/2742/4758 4757/5511/4757 \nf 4596/375/4596 4760/5513/4760 4761/2743/4761 4597/5423/4597 \nf 4762/1476/4762 4763/5514/4763 4761/2743/4761 4760/5513/4760 \nf 4764/733/4764 4765/5515/4765 4761/2743/4761 4763/5514/4763 \nf 4600/1451/4600 4597/5423/4597 4761/2743/4761 4765/5515/4765 \nf 4766/389/4766 4767/5516/4767 4768/2744/4768 4769/5518/4769 \nf 4770/1477/4770 4771/5517/4771 4768/2744/4768 4767/5516/4767 \nf 4764/733/4764 4763/5514/4763 4768/2744/4768 4771/5517/4771 \nf 4762/1476/4762 4769/5518/4769 4768/2744/4768 4763/5514/4763 \nf 4740/388/4740 4759/5512/4759 4772/2745/4772 4773/5520/4773 \nf 4756/1475/4756 4774/5519/4774 4772/2745/4772 4759/5512/4759 \nf 4764/733/4764 4771/5517/4771 4772/2745/4772 4774/5519/4774 \nf 4770/1477/4770 4773/5520/4773 4772/2745/4772 4771/5517/4771 \nf 4605/376/4605 4608/5429/4608 4775/2746/4775 4754/5510/4754 \nf 4600/1451/4600 4765/5515/4765 4775/2746/4775 4608/5429/4608 \nf 4764/733/4764 4774/5519/4774 4775/2746/4775 4765/5515/4765 \nf 4756/1475/4756 4754/5510/4754 4775/2746/4775 4774/5519/4774 \nf 4766/389/4766 4776/5521/4776 4777/2747/4777 4767/5516/4767 \nf 4778/1478/4778 4779/5522/4779 4777/2747/4777 4776/5521/4776 \nf 4780/734/4780 4781/5523/4781 4777/2747/4777 4779/5522/4779 \nf 4770/1477/4770 4767/5516/4767 4777/2747/4777 4781/5523/4781 \nf 4586/374/4586 4589/5420/4589 4782/2748/4782 4783/5525/4783 \nf 4582/1449/4582 4784/5524/4784 4782/2748/4782 4589/5420/4589 \nf 4780/734/4780 4779/5522/4779 4782/2748/4782 4784/5524/4784 \nf 4778/1478/4778 4783/5525/4783 4782/2748/4782 4779/5522/4779 \nf 4569/372/4569 4747/5506/4747 4785/2749/4785 4580/5415/4580 \nf 4744/1474/4744 4786/5526/4786 4785/2749/4785 4747/5506/4747 \nf 4780/734/4780 4784/5524/4784 4785/2749/4785 4786/5526/4786 \nf 4582/1449/4582 4580/5415/4580 4785/2749/4785 4784/5524/4784 \nf 4740/388/4740 4773/5520/4773 4787/2750/4787 4741/5503/4741 \nf 4770/1477/4770 4781/5523/4781 4787/2750/4787 4773/5520/4773 \nf 4780/734/4780 4786/5526/4786 4787/2750/4787 4781/5523/4781 \nf 4744/1474/4744 4741/5503/4741 4787/2750/4787 4786/5526/4786 \nf 1972/84/1972 4788/5527/4788 4789/2751/4789 1973/4035/1973 \nf 4790/1479/4790 4791/5528/4791 4789/2751/4789 4788/5527/4788 \nf 4792/735/4792 4793/5529/4793 4789/2751/4789 4791/5528/4791 \nf 1976/1085/1976 1973/4035/1973 4789/2751/4789 4793/5529/4793 \nf 4794/423/4794 4795/5530/4795 4796/2752/4796 4797/5532/4797 \nf 4798/1480/4798 4799/5531/4799 4796/2752/4796 4795/5530/4795 \nf 4792/735/4792 4791/5528/4791 4796/2752/4796 4799/5531/4799 \nf 4790/1479/4790 4797/5532/4797 4796/2752/4796 4791/5528/4791 \nf 4800/424/4800 4801/5533/4801 4802/2753/4802 4803/5535/4803 \nf 4804/1481/4804 4805/5534/4805 4802/2753/4802 4801/5533/4801 \nf 4792/735/4792 4799/5531/4799 4802/2753/4802 4805/5534/4805 \nf 4798/1480/4798 4803/5535/4803 4802/2753/4802 4799/5531/4799 \nf 1981/150/1981 1984/4041/1984 4806/2754/4806 4807/5536/4807 \nf 1976/1085/1976 4793/5529/4793 4806/2754/4806 1984/4041/1984 \nf 4792/735/4792 4805/5534/4805 4806/2754/4806 4793/5529/4793 \nf 4804/1481/4804 4807/5536/4807 4806/2754/4806 4805/5534/4805 \nf 4794/423/4794 4808/5537/4808 4809/2755/4809 4795/5530/4795 \nf 4810/1482/4810 4811/5539/4811 4809/2755/4809 4808/5537/4808 \nf 4812/736/4812 4813/5540/4813 4809/2755/4809 4811/5539/4811 \nf 4798/1480/4798 4795/5530/4795 4809/2755/4809 4813/5540/4813 \nf 4313/425/4313 4814/5541/4814 4815/2756/4815 4816/5544/4816 \nf 4817/1484/4817 4818/5543/4818 4815/2756/4815 4814/5541/4814 \nf 4812/736/4812 4811/5539/4811 4815/2756/4815 4818/5543/4818 \nf 4810/1482/4810 4816/5544/4816 4815/2756/4815 4811/5539/4811 \nf 4819/426/4819 4820/5546/4820 4821/2757/4821 4822/5548/4822 \nf 4823/1486/4823 4824/5547/4824 4821/2757/4821 4820/5546/4820 \nf 4812/736/4812 4818/5543/4818 4821/2757/4821 4824/5547/4824 \nf 4817/1484/4817 4822/5548/4822 4821/2757/4821 4818/5543/4818 \nf 4800/424/4800 4803/5535/4803 4825/2758/4825 4826/5550/4826 \nf 4798/1480/4798 4813/5540/4813 4825/2758/4825 4803/5535/4803 \nf 4812/736/4812 4824/5547/4824 4825/2758/4825 4813/5540/4813 \nf 4823/1486/4823 4826/5550/4826 4825/2758/4825 4824/5547/4824 \nf 4658/421/4658 4827/5551/4827 4828/2759/4828 4829/5554/4829 \nf 4830/1487/4830 4831/5552/4831 4828/2759/4828 4827/5551/4827 \nf 4832/737/4832 4833/5553/4833 4828/2759/4828 4831/5552/4831 \nf 4834/1489/4834 4829/5554/4829 4828/2759/4828 4833/5553/4833 \nf 4835/427/4835 4836/5555/4836 4837/2760/4837 4838/5557/4838 \nf 4839/1488/4839 4840/5556/4840 4837/2760/4837 4836/5555/4836 \nf 4832/737/4832 4831/5552/4831 4837/2760/4837 4840/5556/4840 \nf 4830/1487/4830 4838/5557/4838 4837/2760/4837 4831/5552/4831 \nf 4800/424/4800 4826/5550/4826 4841/2761/4841 4842/5559/4842 \nf 4823/1486/4823 4843/5558/4843 4841/2761/4841 4826/5550/4826 \nf 4832/737/4832 4840/5556/4840 4841/2761/4841 4843/5558/4843 \nf 4839/1488/4839 4842/5559/4842 4841/2761/4841 4840/5556/4840 \nf 4819/426/4819 4844/5560/4844 4845/2762/4845 4820/5546/4820 \nf 4834/1489/4834 4833/5553/4833 4845/2762/4845 4844/5560/4844 \nf 4832/737/4832 4843/5558/4843 4845/2762/4845 4833/5553/4833 \nf 4823/1486/4823 4820/5546/4820 4845/2762/4845 4843/5558/4843 \nf 4835/427/4835 4846/5561/4846 4847/2763/4847 4836/5555/4836 \nf 4848/1490/4848 4849/5562/4849 4847/2763/4847 4846/5561/4846 \nf 4850/738/4850 4851/5563/4851 4847/2763/4847 4849/5562/4849 \nf 4839/1488/4839 4836/5555/4836 4847/2763/4847 4851/5563/4851 \nf 2003/158/2003 2006/4052/2006 4852/2764/4852 4853/5565/4853 \nf 1999/1089/1999 4854/5564/4854 4852/2764/4852 2006/4052/2006 \nf 4850/738/4850 4849/5562/4849 4852/2764/4852 4854/5564/4854 \nf 4848/1490/4848 4853/5565/4853 4852/2764/4852 4849/5562/4849 \nf 1981/150/1981 4807/5536/4807 4855/2765/4855 1997/4047/1997 \nf 4804/1481/4804 4856/5566/4856 4855/2765/4855 4807/5536/4807 \nf 4850/738/4850 4854/5564/4854 4855/2765/4855 4856/5566/4856 \nf 1999/1089/1999 1997/4047/1997 4855/2765/4855 4854/5564/4854 \nf 4800/424/4800 4842/5559/4842 4857/2766/4857 4801/5533/4801 \nf 4839/1488/4839 4851/5563/4851 4857/2766/4857 4842/5559/4842 \nf 4850/738/4850 4856/5566/4856 4857/2766/4857 4851/5563/4851 \nf 4804/1481/4804 4801/5533/4801 4857/2766/4857 4856/5566/4856 \nf 4547/368/4547 4858/5567/4858 4859/2767/4859 4688/5473/4688 \nf 4860/1491/4860 4861/5568/4861 4859/2767/4859 4858/5567/4858 \nf 4862/739/4862 4863/5569/4863 4859/2767/4859 4861/5568/4861 \nf 4690/1465/4690 4688/5473/4688 4859/2767/4859 4863/5569/4863 \nf 4864/390/4864 4865/5570/4865 4866/2768/4866 4867/5572/4867 \nf 4868/1492/4868 4869/5571/4869 4866/2768/4866 4865/5570/4865 \nf 4862/739/4862 4861/5568/4861 4866/2768/4866 4869/5571/4869 \nf 4860/1491/4860 4867/5572/4867 4866/2768/4866 4861/5568/4861 \nf 4870/391/4870 4871/5573/4871 4872/2769/4872 4873/5575/4873 \nf 4874/1493/4874 4875/5574/4875 4872/2769/4872 4871/5573/4871 \nf 4862/739/4862 4869/5571/4869 4872/2769/4872 4875/5574/4875 \nf 4868/1492/4868 4873/5575/4873 4872/2769/4872 4869/5571/4869 \nf 4692/383/4692 4695/5477/4695 4876/2770/4876 4877/5576/4877 \nf 4690/1465/4690 4863/5569/4863 4876/2770/4876 4695/5477/4695 \nf 4862/739/4862 4875/5574/4875 4876/2770/4876 4863/5569/4863 \nf 4874/1493/4874 4877/5576/4877 4876/2770/4876 4875/5574/4875 \nf 4864/390/4864 4878/5577/4878 4879/2771/4879 4865/5570/4865 \nf 4880/1494/4880 4881/5578/4881 4879/2771/4879 4878/5577/4878 \nf 4882/740/4882 4883/5579/4883 4879/2771/4879 4881/5578/4881 \nf 4868/1492/4868 4865/5570/4865 4879/2771/4879 4883/5579/4883 \nf 3512/163/3512 3515/4858/3515 4884/2772/4884 4885/5581/4885 \nf 3508/1304/3508 4886/5580/4886 4884/2772/4884 3515/4858/3515 \nf 4882/740/4882 4881/5578/4881 4884/2772/4884 4886/5580/4886 \nf 4880/1494/4880 4885/5581/4885 4884/2772/4884 4881/5578/4881 \nf 3495/162/3495 4887/5582/4887 4888/2773/4888 3506/4853/3506 \nf 4889/1495/4889 4890/5583/4890 4888/2773/4888 4887/5582/4887 \nf 4882/740/4882 4886/5580/4886 4888/2773/4888 4890/5583/4890 \nf 3508/1304/3508 3506/4853/3506 4888/2773/4888 4886/5580/4886 \nf 4870/391/4870 4873/5575/4873 4891/2774/4891 4892/5584/4892 \nf 4868/1492/4868 4883/5579/4883 4891/2774/4891 4873/5575/4873 \nf 4882/740/4882 4890/5583/4890 4891/2774/4891 4883/5579/4883 \nf 4889/1495/4889 4892/5584/4892 4891/2774/4891 4890/5583/4890 \nf 3486/161/3486 4893/5585/4893 4894/2775/4894 3487/4841/3487 \nf 4895/1496/4895 4896/5587/4896 4894/2775/4894 4893/5585/4893 \nf 4897/741/4897 4898/5588/4898 4894/2775/4894 4896/5587/4896 \nf 3490/1300/3490 3487/4841/3487 4894/2775/4894 4898/5588/4898 \nf 4899/392/4899 4900/5589/4900 4901/2776/4901 4902/5591/4902 \nf 4903/1498/4903 4904/5590/4904 4901/2776/4901 4900/5589/4900 \nf 4897/741/4897 4896/5587/4896 4901/2776/4901 4904/5590/4904 \nf 4895/1496/4895 4902/5591/4902 4901/2776/4901 4896/5587/4896 \nf 4870/391/4870 4892/5584/4892 4905/2777/4905 4906/5594/4906 \nf 4889/1495/4889 4907/5593/4907 4905/2777/4905 4892/5584/4892 \nf 4897/741/4897 4904/5590/4904 4905/2777/4905 4907/5593/4907 \nf 4903/1498/4903 4906/5594/4906 4905/2777/4905 4904/5590/4904 \nf 3495/162/3495 3498/4848/3498 4908/2778/4908 4887/5582/4887 \nf 3490/1300/3490 4898/5588/4898 4908/2778/4908 3498/4848/3498 \nf 4897/741/4897 4907/5593/4907 4908/2778/4908 4898/5588/4898 \nf 4889/1495/4889 4887/5582/4887 4908/2778/4908 4907/5593/4907 \nf 4899/392/4899 4909/5595/4909 4910/2779/4910 4900/5589/4900 \nf 4911/1499/4911 4912/5597/4912 4910/2779/4910 4909/5595/4909 \nf 4913/742/4913 4914/5598/4914 4910/2779/4910 4912/5597/4912 \nf 4903/1498/4903 4900/5589/4900 4910/2779/4910 4914/5598/4914 \nf 4700/384/4700 4703/5483/4703 4915/2780/4915 4916/5600/4916 \nf 4708/1470/4708 4917/5599/4917 4915/2780/4915 4703/5483/4703 \nf 4913/742/4913 4912/5597/4912 4915/2780/4915 4917/5599/4917 \nf 4911/1499/4911 4916/5600/4916 4915/2780/4915 4912/5597/4912 \nf 4692/383/4692 4877/5576/4877 4918/2781/4918 4718/5490/4718 \nf 4874/1493/4874 4919/5602/4919 4918/2781/4918 4877/5576/4877 \nf 4913/742/4913 4917/5599/4917 4918/2781/4918 4919/5602/4919 \nf 4708/1470/4708 4718/5490/4718 4918/2781/4918 4917/5599/4917 \nf 4870/391/4870 4906/5594/4906 4920/2782/4920 4871/5573/4871 \nf 4903/1498/4903 4914/5598/4914 4920/2782/4920 4906/5594/4906 \nf 4913/742/4913 4919/5602/4919 4920/2782/4920 4914/5598/4914 \nf 4874/1493/4874 4871/5573/4871 4920/2782/4920 4919/5602/4919 \nf 4353/257/4353 4921/5603/4921 4922/2783/4922 4444/5347/4444 \nf 4923/1501/4923 4924/5604/4924 4922/2783/4922 4921/5603/4921 \nf 4925/743/4925 4926/5605/4926 4922/2783/4922 4924/5604/4924 \nf 4446/1429/4446 4444/5347/4444 4922/2783/4922 4926/5605/4926 \nf 4927/393/4927 4928/5606/4928 4929/2784/4929 4930/5608/4930 \nf 4931/1502/4931 4932/5607/4932 4929/2784/4929 4928/5606/4928 \nf 4925/743/4925 4924/5604/4924 4929/2784/4929 4932/5607/4932 \nf 4923/1501/4923 4930/5608/4930 4929/2784/4929 4924/5604/4924 \nf 4933/394/4933 4934/5609/4934 4935/2785/4935 4936/5611/4936 \nf 4937/1503/4937 4938/5610/4938 4935/2785/4935 4934/5609/4934 \nf 4925/743/4925 4932/5607/4932 4935/2785/4935 4938/5610/4938 \nf 4931/1502/4931 4936/5611/4936 4935/2785/4935 4932/5607/4932 \nf 4450/355/4450 4453/5352/4453 4939/2786/4939 4940/5612/4940 \nf 4446/1429/4446 4926/5605/4926 4939/2786/4939 4453/5352/4453 \nf 4925/743/4925 4938/5610/4938 4939/2786/4939 4926/5605/4926 \nf 4937/1503/4937 4940/5612/4940 4939/2786/4939 4938/5610/4938 \nf 4927/393/4927 4941/5613/4941 4942/2787/4942 4928/5606/4928 \nf 4943/1504/4943 4944/5614/4944 4942/2787/4942 4941/5613/4941 \nf 4945/744/4945 4946/5615/4946 4942/2787/4942 4944/5614/4944 \nf 4931/1502/4931 4928/5606/4928 4942/2787/4942 4946/5615/4946 \nf 3584/222/3584 3587/4894/3587 4947/2788/4947 4948/5617/4948 \nf 3580/1314/3580 4949/5616/4949 4947/2788/4947 3587/4894/3587 \nf 4945/744/4945 4944/5614/4944 4947/2788/4947 4949/5616/4949 \nf 4943/1504/4943 4948/5617/4948 4947/2788/4947 4944/5614/4944 \nf 3567/221/3567 4950/5618/4950 4951/2789/4951 3578/4889/3578 \nf 4952/1505/4952 4953/5619/4953 4951/2789/4951 4950/5618/4950 \nf 4945/744/4945 4949/5616/4949 4951/2789/4951 4953/5619/4953 \nf 3580/1314/3580 3578/4889/3578 4951/2789/4951 4949/5616/4949 \nf 4933/394/4933 4936/5611/4936 4954/2790/4954 4955/5620/4955 \nf 4931/1502/4931 4946/5615/4946 4954/2790/4954 4936/5611/4936 \nf 4945/744/4945 4953/5619/4953 4954/2790/4954 4946/5615/4946 \nf 4952/1505/4952 4955/5620/4955 4954/2790/4954 4953/5619/4953 \nf 3558/176/3558 4956/5621/4956 4957/2791/4957 3559/4879/3559 \nf 4958/1506/4958 4959/5622/4959 4957/2791/4957 4956/5621/4956 \nf 4960/745/4960 4961/5623/4961 4957/2791/4957 4959/5622/4959 \nf 3562/1311/3562 3559/4879/3559 4957/2791/4957 4961/5623/4961 \nf 4962/395/4962 4963/5624/4963 4964/2792/4964 4965/5626/4965 \nf 4966/1507/4966 4967/5625/4967 4964/2792/4964 4963/5624/4963 \nf 4960/745/4960 4959/5622/4959 4964/2792/4964 4967/5625/4967 \nf 4958/1506/4958 4965/5626/4965 4964/2792/4964 4959/5622/4959 \nf 4933/394/4933 4955/5620/4955 4968/2793/4968 4969/5628/4969 \nf 4952/1505/4952 4970/5627/4970 4968/2793/4968 4955/5620/4955 \nf 4960/745/4960 4967/5625/4967 4968/2793/4968 4970/5627/4970 \nf 4966/1507/4966 4969/5628/4969 4968/2793/4968 4967/5625/4967 \nf 3567/221/3567 3570/4885/3570 4971/2794/4971 4950/5618/4950 \nf 3562/1311/3562 4961/5623/4961 4971/2794/4971 3570/4885/3570 \nf 4960/745/4960 4970/5627/4970 4971/2794/4971 4961/5623/4961 \nf 4952/1505/4952 4950/5618/4950 4971/2794/4971 4970/5627/4970 \nf 4962/395/4962 4972/5629/4972 4973/2795/4973 4963/5624/4963 \nf 4974/1508/4974 4975/5630/4975 4973/2795/4973 4972/5629/4972 \nf 4976/746/4976 4977/5631/4977 4973/2795/4973 4975/5630/4975 \nf 4966/1507/4966 4963/5624/4963 4973/2795/4973 4977/5631/4977 \nf 4470/357/4470 4473/5362/4473 4978/2796/4978 4979/5633/4979 \nf 4466/1432/4466 4980/5632/4980 4978/2796/4978 4473/5362/4473 \nf 4976/746/4976 4975/5630/4975 4978/2796/4978 4980/5632/4980 \nf 4974/1508/4974 4979/5633/4979 4978/2796/4978 4975/5630/4975 \nf 4450/355/4450 4940/5612/4940 4981/2797/4981 4464/5357/4464 \nf 4937/1503/4937 4982/5634/4982 4981/2797/4981 4940/5612/4940 \nf 4976/746/4976 4980/5632/4980 4981/2797/4981 4982/5634/4982 \nf 4466/1432/4466 4464/5357/4464 4981/2797/4981 4980/5632/4980 \nf 4933/394/4933 4969/5628/4969 4983/2798/4983 4934/5609/4934 \nf 4966/1507/4966 4977/5631/4977 4983/2798/4983 4969/5628/4969 \nf 4976/746/4976 4982/5634/4982 4983/2798/4983 4977/5631/4977 \nf 4937/1503/4937 4934/5609/4934 4983/2798/4983 4982/5634/4982 \nf 4516/361/4516 4984/5635/4984 4985/2799/4985 4517/5383/4517 \nf 4986/1509/4986 4987/5636/4987 4985/2799/4985 4984/5635/4984 \nf 4988/747/4988 4989/5637/4989 4985/2799/4985 4987/5636/4987 \nf 4520/1439/4520 4517/5383/4517 4985/2799/4985 4989/5637/4989 \nf 4990/396/4990 4991/5638/4991 4992/2800/4992 4993/5640/4993 \nf 4994/1510/4994 4995/5639/4995 4992/2800/4992 4991/5638/4991 \nf 4988/747/4988 4987/5636/4987 4992/2800/4992 4995/5639/4995 \nf 4986/1509/4986 4993/5640/4993 4992/2800/4992 4987/5636/4987 \nf 4996/397/4996 4997/5641/4997 4998/2801/4998 4999/5643/4999 \nf 5000/1511/5000 5001/5642/5001 4998/2801/4998 4997/5641/4997 \nf 4988/747/4988 4995/5639/4995 4998/2801/4998 5001/5642/5001 \nf 4994/1510/4994 4999/5643/4999 4998/2801/4998 4995/5639/4995 \nf 4525/363/4525 4528/5389/4528 5002/2802/5002 5003/5644/5003 \nf 4520/1439/4520 4989/5637/4989 5002/2802/5002 4528/5389/4528 \nf 4988/747/4988 5001/5642/5001 5002/2802/5002 4989/5637/4989 \nf 5000/1511/5000 5003/5644/5003 5002/2802/5002 5001/5642/5001 \nf 4990/396/4990 5004/5645/5004 5005/2803/5005 4991/5638/4991 \nf 5006/1512/5006 5007/5646/5007 5005/2803/5005 5004/5645/5004 \nf 5008/748/5008 5009/5647/5009 5005/2803/5005 5007/5646/5007 \nf 4994/1510/4994 4991/5638/4991 5005/2803/5005 5009/5647/5009 \nf 3648/226/3648 3651/4926/3651 5010/2804/5010 5011/5649/5011 \nf 3644/1322/3644 5012/5648/5012 5010/2804/5010 3651/4926/3651 \nf 5008/748/5008 5007/5646/5007 5010/2804/5010 5012/5648/5012 \nf 5006/1512/5006 5011/5649/5011 5010/2804/5010 5007/5646/5007 \nf 3632/225/3632 5013/5650/5013 5014/2805/5014 3642/4921/3642 \nf 5015/1513/5015 5016/5651/5016 5014/2805/5014 5013/5650/5013 \nf 5008/748/5008 5012/5648/5012 5014/2805/5014 5016/5651/5016 \nf 3644/1322/3644 3642/4921/3642 5014/2805/5014 5012/5648/5012 \nf 4996/397/4996 4999/5643/4999 5017/2806/5017 5018/5652/5018 \nf 4994/1510/4994 5009/5647/5009 5017/2806/5017 4999/5643/4999 \nf 5008/748/5008 5016/5651/5016 5017/2806/5017 5009/5647/5009 \nf 5015/1513/5015 5018/5652/5018 5017/2806/5017 5016/5651/5016 \nf 3512/163/3512 4885/5581/4885 5019/2807/5019 3626/4913/3626 \nf 4880/1494/4880 5020/5653/5020 5019/2807/5019 4885/5581/4885 \nf 5021/749/5021 5022/5654/5022 5019/2807/5019 5020/5653/5020 \nf 3628/1320/3628 3626/4913/3626 5019/2807/5019 5022/5654/5022 \nf 4864/390/4864 5023/5655/5023 5024/2808/5024 4878/5577/4878 \nf 5025/1514/5025 5026/5656/5026 5024/2808/5024 5023/5655/5023 \nf 5021/749/5021 5020/5653/5020 5024/2808/5024 5026/5656/5026 \nf 4880/1494/4880 4878/5577/4878 5024/2808/5024 5020/5653/5020 \nf 4996/397/4996 5018/5652/5018 5027/2809/5027 5028/5658/5028 \nf 5015/1513/5015 5029/5657/5029 5027/2809/5027 5018/5652/5018 \nf 5021/749/5021 5026/5656/5026 5027/2809/5027 5029/5657/5029 \nf 5025/1514/5025 5028/5658/5028 5027/2809/5027 5026/5656/5026 \nf 3632/225/3632 3635/4918/3635 5030/2810/5030 5013/5650/5013 \nf 3628/1320/3628 5022/5654/5022 5030/2810/5030 3635/4918/3635 \nf 5021/749/5021 5029/5657/5029 5030/2810/5030 5022/5654/5022 \nf 5015/1513/5015 5013/5650/5013 5030/2810/5030 5029/5657/5029 \nf 4864/390/4864 4867/5572/4867 5031/2811/5031 5023/5655/5023 \nf 4860/1491/4860 5032/5659/5032 5031/2811/5031 4867/5572/4867 \nf 5033/750/5033 5034/5660/5034 5031/2811/5031 5032/5659/5032 \nf 5025/1514/5025 5023/5655/5023 5031/2811/5031 5034/5660/5034 \nf 4547/368/4547 4550/5400/4550 5035/2812/5035 4858/5567/4858 \nf 4543/1443/4543 5036/5661/5036 5035/2812/5035 4550/5400/4550 \nf 5033/750/5033 5032/5659/5032 5035/2812/5035 5036/5661/5036 \nf 4860/1491/4860 4858/5567/4858 5035/2812/5035 5032/5659/5032 \nf 4525/363/4525 5003/5644/5003 5037/2813/5037 4541/5395/4541 \nf 5000/1511/5000 5038/5662/5038 5037/2813/5037 5003/5644/5003 \nf 5033/750/5033 5036/5661/5036 5037/2813/5037 5038/5662/5038 \nf 4543/1443/4543 4541/5395/4541 5037/2813/5037 5036/5661/5036 \nf 4996/397/4996 5028/5658/5028 5039/2814/5039 4997/5641/4997 \nf 5025/1514/5025 5034/5660/5034 5039/2814/5039 5028/5658/5028 \nf 5033/750/5033 5038/5662/5038 5039/2814/5039 5034/5660/5034 \nf 5000/1511/5000 4997/5641/4997 5039/2814/5039 5038/5662/5038 \nf 2233/124/2233 2236/4178/2236 5040/2815/5040 5041/5665/5041 \nf 2241/1126/2241 5042/5663/5042 5040/2815/5040 2236/4178/2236 \nf 5043/751/5043 5044/5664/5044 5040/2815/5040 5042/5663/5042 \nf 5045/1517/5045 5041/5665/5041 5040/2815/5040 5044/5664/5044 \nf 2254/166/2254 5046/5666/5046 5047/2816/5047 2255/4185/2255 \nf 5048/1515/5048 5049/5667/5049 5047/2816/5047 5046/5666/5046 \nf 5043/751/5043 5042/5663/5042 5047/2816/5047 5049/5667/5049 \nf 2241/1126/2241 2255/4185/2255 5047/2816/5047 5042/5663/5042 \nf 5050/335/5050 5051/5668/5051 5052/2817/5052 5053/5670/5053 \nf 5054/1516/5054 5055/5669/5055 5052/2817/5052 5051/5668/5051 \nf 5043/751/5043 5049/5667/5049 5052/2817/5052 5055/5669/5055 \nf 5048/1515/5048 5053/5670/5053 5052/2817/5052 5049/5667/5049 \nf 5056/336/5056 5057/5671/5057 5058/2818/5058 5059/5672/5059 \nf 5045/1517/5045 5044/5664/5044 5058/2818/5058 5057/5671/5057 \nf 5043/751/5043 5055/5669/5055 5058/2818/5058 5044/5664/5044 \nf 5054/1516/5054 5059/5672/5059 5058/2818/5058 5055/5669/5055 \nf 2254/166/2254 2301/4214/2301 5060/2819/5060 5046/5666/5046 \nf 2298/1134/2298 5061/5673/5061 5060/2819/5060 2301/4214/2301 \nf 5062/752/5062 5063/5674/5063 5060/2819/5060 5061/5673/5061 \nf 5048/1515/5048 5046/5666/5046 5060/2819/5060 5063/5674/5063 \nf 825/44/825 3724/4967/3724 5064/2820/5064 2296/4211/2296 \nf 3719/1335/3719 5065/5675/5065 5064/2820/5064 3724/4967/3724 \nf 5062/752/5062 5061/5673/5061 5064/2820/5064 5065/5675/5065 \nf 2298/1134/2298 2296/4211/2296 5064/2820/5064 5061/5673/5061 \nf 3706/291/3706 5066/5676/5066 5067/2821/5067 3717/4963/3717 \nf 5068/1518/5068 5069/5677/5069 5067/2821/5067 5066/5676/5066 \nf 5062/752/5062 5065/5675/5065 5067/2821/5067 5069/5677/5069 \nf 3719/1335/3719 3717/4963/3717 5067/2821/5067 5065/5675/5065 \nf 5050/335/5050 5053/5670/5053 5070/2822/5070 5071/5678/5071 \nf 5048/1515/5048 5063/5674/5063 5070/2822/5070 5053/5670/5053 \nf 5062/752/5062 5069/5677/5069 5070/2822/5070 5063/5674/5063 \nf 5068/1518/5068 5071/5678/5071 5070/2822/5070 5069/5677/5069 \nf 3697/285/3697 5072/5679/5072 5073/2823/5073 3698/4951/3698 \nf 5074/1519/5074 5075/5681/5075 5073/2823/5073 5072/5679/5072 \nf 5076/753/5076 5077/5682/5077 5073/2823/5073 5075/5681/5075 \nf 3701/1331/3701 3698/4951/3698 5073/2823/5073 5077/5682/5077 \nf 5078/347/5078 5079/5683/5079 5080/2824/5080 5081/5685/5081 \nf 5082/1521/5082 5083/5684/5083 5080/2824/5080 5079/5683/5079 \nf 5076/753/5076 5075/5681/5075 5080/2824/5080 5083/5684/5083 \nf 5074/1519/5074 5081/5685/5081 5080/2824/5080 5075/5681/5075 \nf 5050/335/5050 5071/5678/5071 5084/2825/5084 5085/5688/5085 \nf 5068/1518/5068 5086/5687/5086 5084/2825/5084 5071/5678/5071 \nf 5076/753/5076 5083/5684/5083 5084/2825/5084 5086/5687/5086 \nf 5082/1521/5082 5085/5688/5085 5084/2825/5084 5083/5684/5083 \nf 3706/291/3706 3709/4958/3709 5087/2826/5087 5066/5676/5066 \nf 3701/1331/3701 5077/5682/5077 5087/2826/5087 3709/4958/3709 \nf 5076/753/5076 5086/5687/5086 5087/2826/5087 5077/5682/5077 \nf 5068/1518/5068 5066/5676/5066 5087/2826/5087 5086/5687/5086 \nf 5078/347/5078 5088/5689/5088 5089/2827/5089 5079/5683/5079 \nf 5090/1522/5090 5091/5691/5091 5089/2827/5089 5088/5689/5088 \nf 5092/754/5092 5093/5692/5093 5089/2827/5089 5091/5691/5091 \nf 5082/1521/5082 5079/5683/5079 5089/2827/5089 5093/5692/5093 \nf 4327/367/4327 5094/5693/5094 5095/2828/5095 5096/5695/5096 \nf 5097/1524/5097 5098/5694/5098 5095/2828/5095 5094/5693/5094 \nf 5092/754/5092 5091/5691/5091 5095/2828/5095 5098/5694/5098 \nf 5090/1522/5090 5096/5695/5096 5095/2828/5095 5091/5691/5091 \nf 5056/336/5056 5059/5672/5059 5099/2829/5099 5100/5698/5100 \nf 5054/1516/5054 5101/5697/5101 5099/2829/5099 5059/5672/5059 \nf 5092/754/5092 5098/5694/5098 5099/2829/5099 5101/5697/5101 \nf 5097/1524/5097 5100/5698/5100 5099/2829/5099 5098/5694/5098 \nf 5050/335/5050 5085/5688/5085 5102/2830/5102 5051/5668/5051 \nf 5082/1521/5082 5093/5692/5093 5102/2830/5102 5085/5688/5085 \nf 5092/754/5092 5101/5697/5101 5102/2830/5102 5093/5692/5093 \nf 5054/1516/5054 5051/5668/5051 5102/2830/5102 5101/5697/5101 \nf 3558/176/3558 3730/4971/3730 5103/2831/5103 4956/5621/4956 \nf 3734/1338/3734 5104/5699/5104 5103/2831/5103 3730/4971/3730 \nf 5105/755/5105 5106/5700/5106 5103/2831/5103 5104/5699/5104 \nf 4958/1506/4958 4956/5621/4956 5103/2831/5103 5106/5700/5106 \nf 3745/229/3745 5107/5701/5107 5108/2832/5108 3746/4977/3746 \nf 5109/1525/5109 5110/5702/5110 5108/2832/5108 5107/5701/5107 \nf 5105/755/5105 5104/5699/5104 5108/2832/5108 5110/5702/5110 \nf 3734/1338/3734 3746/4977/3746 5108/2832/5108 5104/5699/5104 \nf 5111/398/5111 5112/5703/5112 5113/2833/5113 5114/5705/5114 \nf 5115/1526/5115 5116/5704/5116 5113/2833/5113 5112/5703/5112 \nf 5105/755/5105 5110/5702/5110 5113/2833/5113 5116/5704/5116 \nf 5109/1525/5109 5114/5705/5114 5113/2833/5113 5110/5702/5110 \nf 4962/395/4962 4965/5626/4965 5117/2834/5117 5118/5706/5118 \nf 4958/1506/4958 5106/5700/5106 5117/2834/5117 4965/5626/4965 \nf 5105/755/5105 5116/5704/5116 5117/2834/5117 5106/5700/5106 \nf 5115/1526/5115 5118/5706/5118 5117/2834/5117 5116/5704/5116 \nf 3745/229/3745 3789/5000/3789 5119/2835/5119 5107/5701/5107 \nf 3786/1343/3786 5120/5707/5120 5119/2835/5119 3789/5000/3789 \nf 5121/756/5121 5122/5708/5122 5119/2835/5119 5120/5707/5120 \nf 5109/1525/5109 5107/5701/5107 5119/2835/5119 5122/5708/5122 \nf 3648/226/3648 5011/5649/5011 5123/2836/5123 3784/4997/3784 \nf 5006/1512/5006 5124/5709/5124 5123/2836/5123 5011/5649/5011 \nf 5121/756/5121 5120/5707/5120 5123/2836/5123 5124/5709/5124 \nf 3786/1343/3786 3784/4997/3784 5123/2836/5123 5120/5707/5120 \nf 4990/396/4990 5125/5710/5125 5126/2837/5126 5004/5645/5004 \nf 5127/1527/5127 5128/5711/5128 5126/2837/5126 5125/5710/5125 \nf 5121/756/5121 5124/5709/5124 5126/2837/5126 5128/5711/5128 \nf 5006/1512/5006 5004/5645/5004 5126/2837/5126 5124/5709/5124 \nf 5111/398/5111 5114/5705/5114 5129/2838/5129 5130/5712/5130 \nf 5109/1525/5109 5122/5708/5122 5129/2838/5129 5114/5705/5114 \nf 5121/756/5121 5128/5711/5128 5129/2838/5129 5122/5708/5122 \nf 5127/1527/5127 5130/5712/5130 5129/2838/5129 5128/5711/5128 \nf 4516/361/4516 5131/5713/5131 5132/2839/5132 4984/5635/4984 \nf 5133/1528/5133 5134/5714/5134 5132/2839/5132 5131/5713/5131 \nf 5135/757/5135 5136/5715/5136 5132/2839/5132 5134/5714/5134 \nf 4986/1509/4986 4984/5635/4984 5132/2839/5132 5136/5715/5136 \nf 5137/399/5137 5138/5716/5138 5139/2840/5139 5140/5718/5140 \nf 5141/1529/5141 5142/5717/5142 5139/2840/5139 5138/5716/5138 \nf 5135/757/5135 5134/5714/5134 5139/2840/5139 5142/5717/5142 \nf 5133/1528/5133 5140/5718/5140 5139/2840/5139 5134/5714/5134 \nf 5111/398/5111 5130/5712/5130 5143/2841/5143 5144/5720/5144 \nf 5127/1527/5127 5145/5719/5145 5143/2841/5143 5130/5712/5130 \nf 5135/757/5135 5142/5717/5142 5143/2841/5143 5145/5719/5145 \nf 5141/1529/5141 5144/5720/5144 5143/2841/5143 5142/5717/5142 \nf 4990/396/4990 4993/5640/4993 5146/2842/5146 5125/5710/5125 \nf 4986/1509/4986 5136/5715/5136 5146/2842/5146 4993/5640/4993 \nf 5135/757/5135 5145/5719/5145 5146/2842/5146 5136/5715/5136 \nf 5127/1527/5127 5125/5710/5125 5146/2842/5146 5145/5719/5145 \nf 5137/399/5137 5147/5721/5147 5148/2843/5148 5138/5716/5138 \nf 5149/1530/5149 5150/5722/5150 5148/2843/5148 5147/5721/5147 \nf 5151/758/5151 5152/5723/5152 5148/2843/5148 5150/5722/5150 \nf 5141/1529/5141 5138/5716/5138 5148/2843/5148 5152/5723/5152 \nf 4470/357/4470 4979/5633/4979 5153/2844/5153 5154/5725/5154 \nf 4974/1508/4974 5155/5724/5155 5153/2844/5153 4979/5633/4979 \nf 5151/758/5151 5150/5722/5150 5153/2844/5153 5155/5724/5155 \nf 5149/1530/5149 5154/5725/5154 5153/2844/5153 5150/5722/5150 \nf 4962/395/4962 5118/5706/5118 5156/2845/5156 4972/5629/4972 \nf 5115/1526/5115 5157/5726/5157 5156/2845/5156 5118/5706/5118 \nf 5151/758/5151 5155/5724/5155 5156/2845/5156 5157/5726/5157 \nf 4974/1508/4974 4972/5629/4972 5156/2845/5156 5155/5724/5155 \nf 5111/398/5111 5144/5720/5144 5158/2846/5158 5112/5703/5112 \nf 5141/1529/5141 5152/5723/5152 5158/2846/5158 5144/5720/5144 \nf 5151/758/5151 5157/5726/5157 5158/2846/5158 5152/5723/5152 \nf 5115/1526/5115 5112/5703/5112 5158/2846/5158 5157/5726/5157 \nf 4470/357/4470 5154/5725/5154 5159/2847/5159 4471/5360/4471 \nf 5149/1530/5149 5160/5727/5160 5159/2847/5159 5154/5725/5154 \nf 5161/759/5161 5162/5728/5162 5159/2847/5159 5160/5727/5160 \nf 4474/1433/4474 4471/5360/4471 5159/2847/5159 5162/5728/5162 \nf 5137/399/5137 5163/5729/5163 5164/2848/5164 5147/5721/5147 \nf 5165/1531/5165 5166/5730/5166 5164/2848/5164 5163/5729/5163 \nf 5161/759/5161 5160/5727/5160 5164/2848/5164 5166/5730/5166 \nf 5149/1530/5149 5147/5721/5147 5164/2848/5164 5160/5727/5160 \nf 5167/400/5167 5168/5731/5168 5169/2849/5169 5170/5733/5170 \nf 5171/1532/5171 5172/5732/5172 5169/2849/5169 5168/5731/5168 \nf 5161/759/5161 5166/5730/5166 5169/2849/5169 5172/5732/5172 \nf 5165/1531/5165 5170/5733/5170 5169/2849/5169 5166/5730/5166 \nf 4476/358/4476 4479/5365/4479 5173/2850/5173 5174/5734/5174 \nf 4474/1433/4474 5162/5728/5162 5173/2850/5173 4479/5365/4479 \nf 5161/759/5161 5172/5732/5172 5173/2850/5173 5162/5728/5162 \nf 5171/1532/5171 5174/5734/5174 5173/2850/5173 5172/5732/5172 \nf 5137/399/5137 5140/5718/5140 5175/2851/5175 5163/5729/5163 \nf 5133/1528/5133 5176/5735/5176 5175/2851/5175 5140/5718/5140 \nf 5177/760/5177 5178/5736/5178 5175/2851/5175 5176/5735/5176 \nf 5165/1531/5165 5163/5729/5163 5175/2851/5175 5178/5736/5178 \nf 4516/361/4516 4519/5386/4519 5179/2852/5179 5131/5713/5131 \nf 4524/1442/4524 5180/5737/5180 5179/2852/5179 4519/5386/4519 \nf 5177/760/5177 5176/5735/5176 5179/2852/5179 5180/5737/5180 \nf 5133/1528/5133 5131/5713/5131 5179/2852/5179 5176/5735/5176 \nf 4537/366/4537 5181/5738/5181 5182/2853/5182 4538/5393/4538 \nf 5183/1533/5183 5184/5739/5184 5182/2853/5182 5181/5738/5181 \nf 5177/760/5177 5180/5737/5180 5182/2853/5182 5184/5739/5184 \nf 4524/1442/4524 4538/5393/4538 5182/2853/5182 5180/5737/5180 \nf 5167/400/5167 5170/5733/5170 5185/2854/5185 5186/5740/5186 \nf 5165/1531/5165 5178/5736/5178 5185/2854/5185 5170/5733/5170 \nf 5177/760/5177 5184/5739/5184 5185/2854/5185 5178/5736/5178 \nf 5183/1533/5183 5186/5740/5186 5185/2854/5185 5184/5739/5184 \nf 4586/374/4586 5187/5741/5187 5188/2855/5188 4587/5418/4587 \nf 5189/1534/5189 5190/5742/5190 5188/2855/5188 5187/5741/5187 \nf 5191/761/5191 5192/5743/5192 5188/2855/5188 5190/5742/5190 \nf 4590/1450/4590 4587/5418/4587 5188/2855/5188 5192/5743/5192 \nf 5193/401/5193 5194/5744/5194 5195/2856/5195 5196/5746/5196 \nf 5197/1535/5197 5198/5745/5198 5195/2856/5195 5194/5744/5194 \nf 5191/761/5191 5190/5742/5190 5195/2856/5195 5198/5745/5198 \nf 5189/1534/5189 5196/5746/5196 5195/2856/5195 5190/5742/5190 \nf 5167/400/5167 5186/5740/5186 5199/2857/5199 5200/5748/5200 \nf 5183/1533/5183 5201/5747/5201 5199/2857/5199 5186/5740/5186 \nf 5191/761/5191 5198/5745/5198 5199/2857/5199 5201/5747/5201 \nf 5197/1535/5197 5200/5748/5200 5199/2857/5199 5198/5745/5198 \nf 4537/366/4537 4593/5422/4593 5202/2858/5202 5181/5738/5181 \nf 4590/1450/4590 5192/5743/5192 5202/2858/5202 4593/5422/4593 \nf 5191/761/5191 5201/5747/5201 5202/2858/5202 5192/5743/5192 \nf 5183/1533/5183 5181/5738/5181 5202/2858/5202 5201/5747/5201 \nf 5193/401/5193 5203/5749/5203 5204/2859/5204 5194/5744/5194 \nf 5205/1536/5205 5206/5750/5206 5204/2859/5204 5203/5749/5203 \nf 5207/762/5207 5208/5751/5208 5204/2859/5204 5206/5750/5206 \nf 5197/1535/5197 5194/5744/5194 5204/2859/5204 5208/5751/5208 \nf 4484/359/4484 4487/5370/4487 5209/2860/5209 5210/5753/5210 \nf 4492/1437/4492 5211/5752/5211 5209/2860/5209 4487/5370/4487 \nf 5207/762/5207 5206/5750/5206 5209/2860/5209 5211/5752/5211 \nf 5205/1536/5205 5210/5753/5210 5209/2860/5209 5206/5750/5206 \nf 4476/358/4476 5174/5734/5174 5212/2861/5212 4502/5376/4502 \nf 5171/1532/5171 5213/5754/5213 5212/2861/5212 5174/5734/5174 \nf 5207/762/5207 5211/5752/5211 5212/2861/5212 5213/5754/5213 \nf 4492/1437/4492 4502/5376/4502 5212/2861/5212 5211/5752/5211 \nf 5167/400/5167 5200/5748/5200 5214/2862/5214 5168/5731/5168 \nf 5197/1535/5197 5208/5751/5208 5214/2862/5214 5200/5748/5200 \nf 5207/762/5207 5213/5754/5213 5214/2862/5214 5208/5751/5208 \nf 5171/1532/5171 5168/5731/5168 5214/2862/5214 5213/5754/5213 \nf 4484/359/4484 5210/5753/5210 5215/2863/5215 4485/5367/4485 \nf 5205/1536/5205 5216/5755/5216 5215/2863/5215 5210/5753/5210 \nf 5217/763/5217 5218/5756/5218 5215/2863/5215 5216/5755/5216 \nf 4488/1435/4488 4485/5367/4485 5215/2863/5215 5218/5756/5218 \nf 5193/401/5193 5219/5757/5219 5220/2864/5220 5203/5749/5203 \nf 5221/1537/5221 5222/5758/5222 5220/2864/5220 5219/5757/5219 \nf 5217/763/5217 5216/5755/5216 5220/2864/5220 5222/5758/5222 \nf 5205/1536/5205 5203/5749/5203 5220/2864/5220 5216/5755/5216 \nf 5223/402/5223 5224/5759/5224 5225/2865/5225 5226/5761/5226 \nf 5227/1538/5227 5228/5760/5228 5225/2865/5225 5224/5759/5224 \nf 5217/763/5217 5222/5758/5222 5225/2865/5225 5228/5760/5228 \nf 5221/1537/5221 5226/5761/5226 5225/2865/5225 5222/5758/5222 \nf 4493/360/4493 4496/5373/4496 5229/2866/5229 5230/5762/5230 \nf 4488/1435/4488 5218/5756/5218 5229/2866/5229 4496/5373/4496 \nf 5217/763/5217 5228/5760/5228 5229/2866/5229 5218/5756/5218 \nf 5227/1538/5227 5230/5762/5230 5229/2866/5229 5228/5760/5228 \nf 5193/401/5193 5196/5746/5196 5231/2867/5231 5219/5757/5219 \nf 5189/1534/5189 5232/5763/5232 5231/2867/5231 5196/5746/5196 \nf 5233/764/5233 5234/5764/5234 5231/2867/5231 5232/5763/5232 \nf 5221/1537/5221 5219/5757/5219 5231/2867/5231 5234/5764/5234 \nf 4586/374/4586 4783/5525/4783 5235/2868/5235 5187/5741/5187 \nf 4778/1478/4778 5236/5765/5236 5235/2868/5235 4783/5525/4783 \nf 5233/764/5233 5232/5763/5232 5235/2868/5235 5236/5765/5236 \nf 5189/1534/5189 5187/5741/5187 5235/2868/5235 5232/5763/5232 \nf 4766/389/4766 5237/5766/5237 5238/2869/5238 4776/5521/4776 \nf 5239/1539/5239 5240/5767/5240 5238/2869/5238 5237/5766/5237 \nf 5233/764/5233 5236/5765/5236 5238/2869/5238 5240/5767/5240 \nf 4778/1478/4778 4776/5521/4776 5238/2869/5238 5236/5765/5236 \nf 5223/402/5223 5226/5761/5226 5241/2870/5241 5242/5768/5242 \nf 5221/1537/5221 5234/5764/5234 5241/2870/5241 5226/5761/5226 \nf 5233/764/5233 5240/5767/5240 5241/2870/5241 5234/5764/5234 \nf 5239/1539/5239 5242/5768/5242 5241/2870/5241 5240/5767/5240 \nf 4596/375/4596 5243/5769/5243 5244/2871/5244 4760/5513/4760 \nf 5245/1540/5245 5246/5770/5246 5244/2871/5244 5243/5769/5243 \nf 5247/765/5247 5248/5771/5248 5244/2871/5244 5246/5770/5246 \nf 4762/1476/4762 4760/5513/4760 5244/2871/5244 5248/5771/5248 \nf 5249/404/5249 5250/5772/5250 5251/2872/5251 5252/5774/5252 \nf 5253/1541/5253 5254/5773/5254 5251/2872/5251 5250/5772/5250 \nf 5247/765/5247 5246/5770/5246 5251/2872/5251 5254/5773/5254 \nf 5245/1540/5245 5252/5774/5252 5251/2872/5251 5246/5770/5246 \nf 5223/402/5223 5242/5768/5242 5255/2873/5255 5256/5776/5256 \nf 5239/1539/5239 5257/5775/5257 5255/2873/5255 5242/5768/5242 \nf 5247/765/5247 5254/5773/5254 5255/2873/5255 5257/5775/5257 \nf 5253/1541/5253 5256/5776/5256 5255/2873/5255 5254/5773/5254 \nf 4766/389/4766 4769/5518/4769 5258/2874/5258 5237/5766/5237 \nf 4762/1476/4762 5248/5771/5248 5258/2874/5258 4769/5518/4769 \nf 5247/765/5247 5257/5775/5257 5258/2874/5258 5248/5771/5248 \nf 5239/1539/5239 5237/5766/5237 5258/2874/5258 5257/5775/5257 \nf 5249/404/5249 5259/5777/5259 5260/2875/5260 5250/5772/5250 \nf 5261/1542/5261 5262/5778/5262 5260/2875/5260 5259/5777/5259 \nf 5263/766/5263 5264/5779/5264 5260/2875/5260 5262/5778/5262 \nf 5253/1541/5253 5250/5772/5250 5260/2875/5260 5264/5779/5264 \nf 4282/247/4282 4511/5381/4511 5265/2876/5265 5266/5781/5266 \nf 4506/1438/4506 5267/5780/5267 5265/2876/5265 4511/5381/4511 \nf 5263/766/5263 5262/5778/5262 5265/2876/5265 5267/5780/5267 \nf 5261/1542/5261 5266/5781/5266 5265/2876/5265 5262/5778/5262 \nf 4493/360/4493 5230/5762/5230 5268/2877/5268 4504/5377/4504 \nf 5227/1538/5227 5269/5782/5269 5268/2877/5268 5230/5762/5230 \nf 5263/766/5263 5267/5780/5267 5268/2877/5268 5269/5782/5269 \nf 4506/1438/4506 4504/5377/4504 5268/2877/5268 5267/5780/5267 \nf 5223/402/5223 5256/5776/5256 5270/2878/5270 5224/5759/5224 \nf 5253/1541/5253 5264/5779/5264 5270/2878/5270 5256/5776/5256 \nf 5263/766/5263 5269/5782/5269 5270/2878/5270 5264/5779/5264 \nf 5227/1538/5227 5224/5759/5224 5270/2878/5270 5269/5782/5269 \nf 4313/373/4313 4816/5545/4816 5271/2879/5271 4314/5273/4314 \nf 4810/1483/4810 5272/5783/5272 5271/2879/5271 4816/5545/4816 \nf 5273/767/5273 5274/5784/5274 5271/2879/5271 5272/5783/5272 \nf 4317/1406/4317 4314/5273/4314 5271/2879/5271 5274/5784/5274 \nf 4794/379/4794 5275/5785/5275 5276/2880/5276 4808/5538/4808 \nf 5277/1543/5277 5278/5787/5278 5276/2880/5276 5275/5785/5275 \nf 5273/767/5273 5272/5783/5272 5276/2880/5276 5278/5787/5278 \nf 4810/1483/4810 4808/5538/4808 5276/2880/5276 5272/5783/5272 \nf 5279/380/5279 5280/5788/5280 5281/2881/5281 5282/5790/5282 \nf 5283/1545/5283 5284/5789/5284 5281/2881/5281 5280/5788/5280 \nf 5273/767/5273 5278/5787/5278 5281/2881/5281 5284/5789/5284 \nf 5277/1543/5277 5282/5790/5282 5281/2881/5281 5278/5787/5278 \nf 4319/381/4319 4322/5279/4322 5285/2882/5285 5286/5792/5286 \nf 4317/1406/4317 5274/5784/5274 5285/2882/5285 4322/5279/4322 \nf 5273/767/5273 5284/5789/5284 5285/2882/5285 5274/5784/5274 \nf 5283/1545/5283 5286/5792/5286 5285/2882/5285 5284/5789/5284 \nf 4794/423/4794 4797/5532/4797 5287/2883/5287 5275/5786/5275 \nf 4790/1479/4790 5288/5793/5288 5287/2883/5287 4797/5532/4797 \nf 5289/768/5289 5290/5794/5290 5287/2883/5287 5288/5793/5288 \nf 5277/1544/5277 5275/5786/5275 5287/2883/5287 5290/5794/5290 \nf 1972/84/1972 2523/4329/2523 5291/2884/5291 4788/5527/4788 \nf 2518/1160/2518 5292/5795/5292 5291/2884/5291 2523/4329/2523 \nf 5289/768/5289 5288/5793/5288 5291/2884/5291 5292/5795/5292 \nf 4790/1479/4790 4788/5527/4788 5291/2884/5291 5288/5793/5288 \nf 2506/206/2506 5293/5796/5293 5294/2885/5294 2516/4325/2516 \nf 5295/1546/5295 5296/5798/5296 5294/2885/5294 5293/5796/5293 \nf 5289/768/5289 5292/5795/5292 5294/2885/5294 5296/5798/5296 \nf 2518/1160/2518 2516/4325/2516 5294/2885/5294 5292/5795/5292 \nf 5279/428/5279 5282/5791/5282 5297/2886/5297 5298/5799/5298 \nf 5277/1544/5277 5290/5794/5290 5297/2886/5297 5282/5791/5282 \nf 5289/768/5289 5296/5798/5296 5297/2886/5297 5290/5794/5290 \nf 5295/1546/5295 5298/5799/5298 5297/2886/5297 5296/5798/5296 \nf 2233/124/2233 5041/5665/5041 5299/2887/5299 2500/4315/2500 \nf 5045/1517/5045 5300/5801/5300 5299/2887/5299 5041/5665/5041 \nf 5301/769/5301 5302/5802/5302 5299/2887/5299 5300/5801/5300 \nf 2502/1157/2502 2500/4315/2500 5299/2887/5299 5302/5802/5302 \nf 5056/336/5056 5303/5803/5303 5304/2888/5304 5057/5671/5057 \nf 5305/1548/5305 5306/5804/5306 5304/2888/5304 5303/5803/5303 \nf 5301/769/5301 5300/5801/5300 5304/2888/5304 5306/5804/5306 \nf 5045/1517/5045 5057/5671/5057 5304/2888/5304 5300/5801/5300 \nf 5279/380/5279 5298/5800/5298 5307/2889/5307 5308/5806/5308 \nf 5295/1547/5295 5309/5805/5309 5307/2889/5307 5298/5800/5298 \nf 5301/769/5301 5306/5804/5306 5307/2889/5307 5309/5805/5309 \nf 5305/1548/5305 5308/5806/5308 5307/2889/5307 5306/5804/5306 \nf 2506/232/2506 2509/4321/2509 5310/2890/5310 5293/5797/5293 \nf 2502/1157/2502 5302/5802/5302 5310/2890/5310 2509/4321/2509 \nf 5301/769/5301 5309/5805/5309 5310/2890/5310 5302/5802/5302 \nf 5295/1547/5295 5293/5797/5293 5310/2890/5310 5309/5805/5309 \nf 5056/336/5056 5100/5698/5100 5311/2891/5311 5303/5803/5303 \nf 5097/1524/5097 5312/5807/5312 5311/2891/5311 5100/5698/5100 \nf 5313/770/5313 5314/5808/5314 5311/2891/5311 5312/5807/5312 \nf 5305/1548/5305 5303/5803/5303 5311/2891/5311 5314/5808/5314 \nf 4327/367/4327 4330/5285/4330 5315/2892/5315 5094/5693/5094 \nf 4335/1411/4335 5316/5809/5316 5315/2892/5315 4330/5285/4330 \nf 5313/770/5313 5312/5807/5312 5315/2892/5315 5316/5809/5316 \nf 5097/1524/5097 5094/5693/5094 5315/2892/5315 5312/5807/5312 \nf 4319/381/4319 5286/5792/5286 5317/2893/5317 4345/5292/4345 \nf 5283/1545/5283 5318/5810/5318 5317/2893/5317 5286/5792/5286 \nf 5313/770/5313 5316/5809/5316 5317/2893/5317 5318/5810/5318 \nf 4335/1411/4335 4345/5292/4345 5317/2893/5317 5316/5809/5316 \nf 5279/380/5279 5308/5806/5308 5319/2894/5319 5280/5788/5280 \nf 5305/1548/5305 5314/5808/5314 5319/2894/5319 5308/5806/5308 \nf 5313/770/5313 5318/5810/5318 5319/2894/5319 5314/5808/5314 \nf 5283/1545/5283 5280/5788/5280 5319/2894/5319 5318/5810/5318 \nf 4408/337/4408 5320/5811/5320 5321/2895/5321 4409/5324/4409 \nf 5322/1549/5322 5323/5812/5323 5321/2895/5321 5320/5811/5320 \nf 5324/771/5324 5325/5813/5325 5321/2895/5321 5323/5812/5323 \nf 4412/1422/4412 4409/5324/4409 5321/2895/5321 5325/5813/5325 \nf 5326/338/5326 5327/5814/5327 5328/2896/5328 5329/5816/5329 \nf 5330/1550/5330 5331/5815/5331 5328/2896/5328 5327/5814/5327 \nf 5324/771/5324 5323/5812/5323 5328/2896/5328 5331/5815/5331 \nf 5322/1549/5322 5329/5816/5329 5328/2896/5328 5323/5812/5323 \nf 5332/339/5332 5333/5817/5333 5334/2897/5334 5335/5820/5335 \nf 5336/1551/5336 5337/5819/5337 5334/2897/5334 5333/5817/5333 \nf 5324/771/5324 5331/5815/5331 5334/2897/5334 5337/5819/5337 \nf 5330/1550/5330 5335/5820/5335 5334/2897/5334 5331/5815/5331 \nf 4417/340/4417 4420/5331/4420 5338/2898/5338 5339/5821/5339 \nf 4412/1422/4412 5325/5813/5325 5338/2898/5338 4420/5331/4420 \nf 5324/771/5324 5337/5819/5337 5338/2898/5338 5325/5813/5325 \nf 5336/1551/5336 5339/5821/5339 5338/2898/5338 5337/5819/5337 \nf 5326/338/5326 5340/5823/5340 5341/2899/5341 5327/5814/5327 \nf 5342/1553/5342 5343/5824/5343 5341/2899/5341 5340/5823/5340 \nf 5344/772/5344 5345/5825/5345 5341/2899/5341 5343/5824/5343 \nf 5330/1550/5330 5327/5814/5327 5341/2899/5341 5345/5825/5345 \nf 2590/175/2590 2593/4368/2593 5346/2900/5346 5347/5827/5347 \nf 2586/1171/2586 5348/5826/5348 5346/2900/5346 2593/4368/2593 \nf 5344/772/5344 5343/5824/5343 5346/2900/5346 5348/5826/5348 \nf 5342/1553/5342 5347/5827/5347 5346/2900/5346 5343/5824/5343 \nf 2573/173/2573 5349/5828/5349 5350/2901/5350 2584/4363/2584 \nf 5351/1554/5351 5352/5830/5352 5350/2901/5350 5349/5828/5349 \nf 5344/772/5344 5348/5826/5348 5350/2901/5350 5352/5830/5352 \nf 2586/1171/2586 2584/4363/2584 5350/2901/5350 5348/5826/5348 \nf 5332/339/5332 5335/5820/5335 5353/2902/5353 5354/5831/5354 \nf 5330/1550/5330 5345/5825/5345 5353/2902/5353 5335/5820/5335 \nf 5344/772/5344 5352/5830/5352 5353/2902/5353 5345/5825/5345 \nf 5351/1554/5351 5354/5831/5354 5353/2902/5353 5352/5830/5352 \nf 2564/327/2564 5355/5833/5355 5356/2903/5356 2565/4351/2565 \nf 5357/1556/5357 5358/5834/5358 5356/2903/5356 5355/5833/5355 \nf 5359/773/5359 5360/5835/5360 5356/2903/5356 5358/5834/5358 \nf 2568/1167/2568 2565/4351/2565 5356/2903/5356 5360/5835/5360 \nf 5361/429/5361 5362/5836/5362 5363/2904/5363 5364/5838/5364 \nf 5365/1557/5365 5366/5837/5366 5363/2904/5363 5362/5836/5362 \nf 5359/773/5359 5358/5834/5358 5363/2904/5363 5366/5837/5366 \nf 5357/1556/5357 5364/5838/5364 5363/2904/5363 5358/5834/5358 \nf 5332/430/5332 5354/5832/5354 5367/2905/5367 5368/5840/5368 \nf 5351/1555/5351 5369/5839/5369 5367/2905/5367 5354/5832/5354 \nf 5359/773/5359 5366/5837/5366 5367/2905/5367 5369/5839/5369 \nf 5365/1557/5365 5368/5840/5368 5367/2905/5367 5366/5837/5366 \nf 2573/342/2573 2576/4358/2576 5370/2906/5370 5349/5829/5349 \nf 2568/1167/2568 5360/5835/5360 5370/2906/5370 2576/4358/2576 \nf 5359/773/5359 5369/5839/5369 5370/2906/5370 5360/5835/5360 \nf 5351/1555/5351 5349/5829/5349 5370/2906/5370 5369/5839/5369 \nf 5361/429/5361 5371/5841/5371 5372/2907/5372 5362/5836/5362 \nf 5373/1558/5373 5374/5842/5374 5372/2907/5372 5371/5841/5371 \nf 5375/774/5375 5376/5843/5376 5372/2907/5372 5374/5842/5374 \nf 5365/1557/5365 5362/5836/5362 5372/2907/5372 5376/5843/5376 \nf 4434/411/4434 4437/5343/4437 5377/2908/5377 5378/5845/5378 \nf 4430/1426/4430 5379/5844/5379 5377/2908/5377 4437/5343/4437 \nf 5375/774/5375 5374/5842/5374 5377/2908/5377 5379/5844/5379 \nf 5373/1558/5373 5378/5845/5378 5377/2908/5377 5374/5842/5374 \nf 4417/431/4417 5339/5822/5339 5380/2909/5380 4428/5336/4428 \nf 5336/1552/5336 5381/5846/5381 5380/2909/5380 5339/5822/5339 \nf 5375/774/5375 5379/5844/5379 5380/2909/5380 5381/5846/5381 \nf 4430/1426/4430 4428/5336/4428 5380/2909/5380 5379/5844/5379 \nf 5332/430/5332 5368/5840/5368 5382/2910/5382 5333/5818/5333 \nf 5365/1557/5365 5376/5843/5376 5382/2910/5382 5368/5840/5368 \nf 5375/774/5375 5381/5846/5381 5382/2910/5382 5376/5843/5376 \nf 5336/1552/5336 5333/5818/5333 5382/2910/5382 5381/5846/5381 \nf 4434/411/4434 5378/5845/5378 5383/2911/5383 4636/5447/4636 \nf 5373/1558/5373 5384/5847/5384 5383/2911/5383 5378/5845/5378 \nf 5385/775/5385 5386/5848/5386 5383/2911/5383 5384/5847/5384 \nf 4638/1459/4638 4636/5447/4636 5383/2911/5383 5386/5848/5386 \nf 5361/429/5361 5387/5849/5387 5388/2912/5388 5371/5841/5371 \nf 5389/1559/5389 5390/5850/5390 5388/2912/5388 5387/5849/5387 \nf 5385/775/5385 5384/5847/5384 5388/2912/5388 5390/5850/5390 \nf 5373/1558/5373 5371/5841/5371 5388/2912/5388 5384/5847/5384 \nf 5391/432/5391 5392/5851/5392 5393/2913/5393 5394/5853/5394 \nf 5395/1560/5395 5396/5852/5396 5393/2913/5393 5392/5851/5392 \nf 5385/775/5385 5390/5850/5390 5393/2913/5393 5396/5852/5396 \nf 5389/1559/5389 5394/5853/5394 5393/2913/5393 5390/5850/5390 \nf 4642/412/4642 4645/5452/4645 5397/2914/5397 5398/5854/5398 \nf 4638/1459/4638 5386/5848/5386 5397/2914/5397 4645/5452/4645 \nf 5385/775/5385 5396/5852/5396 5397/2914/5397 5386/5848/5386 \nf 5395/1560/5395 5398/5854/5398 5397/2914/5397 5396/5852/5396 \nf 5361/429/5361 5364/5838/5364 5399/2915/5399 5387/5849/5387 \nf 5357/1556/5357 5400/5855/5400 5399/2915/5399 5364/5838/5364 \nf 5401/776/5401 5402/5856/5402 5399/2915/5399 5400/5855/5400 \nf 5389/1559/5389 5387/5849/5387 5399/2915/5399 5402/5856/5402 \nf 2564/327/2564 2651/4397/2651 5403/2916/5403 5355/5833/5355 \nf 2646/1178/2646 5404/5857/5404 5403/2916/5403 2651/4397/2651 \nf 5401/776/5401 5400/5855/5400 5403/2916/5403 5404/5857/5404 \nf 5357/1556/5357 5355/5833/5355 5403/2916/5403 5400/5855/5400 \nf 2634/407/2634 5405/5858/5405 5406/2917/5406 2644/4393/2644 \nf 5407/1561/5407 5408/5859/5408 5406/2917/5406 5405/5858/5405 \nf 5401/776/5401 5404/5857/5404 5406/2917/5406 5408/5859/5408 \nf 2646/1178/2646 2644/4393/2644 5406/2917/5406 5404/5857/5404 \nf 5391/432/5391 5394/5853/5394 5409/2918/5409 5410/5860/5410 \nf 5389/1559/5389 5402/5856/5402 5409/2918/5409 5394/5853/5394 \nf 5401/776/5401 5408/5859/5408 5409/2918/5409 5402/5856/5402 \nf 5407/1561/5407 5410/5860/5410 5409/2918/5409 5408/5859/5408 \nf 2003/158/2003 4853/5565/4853 5411/2919/5411 2628/4385/2628 \nf 4848/1490/4848 5412/5861/5412 5411/2919/5411 4853/5565/4853 \nf 5413/777/5413 5414/5862/5414 5411/2919/5411 5412/5861/5412 \nf 2630/1176/2630 2628/4385/2628 5411/2919/5411 5414/5862/5414 \nf 4835/427/4835 5415/5863/5415 5416/2920/5416 4846/5561/4846 \nf 5417/1562/5417 5418/5864/5418 5416/2920/5416 5415/5863/5415 \nf 5413/777/5413 5412/5861/5412 5416/2920/5416 5418/5864/5418 \nf 4848/1490/4848 4846/5561/4846 5416/2920/5416 5412/5861/5412 \nf 5391/432/5391 5410/5860/5410 5419/2921/5419 5420/5866/5420 \nf 5407/1561/5407 5421/5865/5421 5419/2921/5419 5410/5860/5410 \nf 5413/777/5413 5418/5864/5418 5419/2921/5419 5421/5865/5421 \nf 5417/1562/5417 5420/5866/5420 5419/2921/5419 5418/5864/5418 \nf 2634/407/2634 2637/4390/2637 5422/2922/5422 5405/5858/5405 \nf 2630/1176/2630 5414/5862/5414 5422/2922/5422 2637/4390/2637 \nf 5413/777/5413 5421/5865/5421 5422/2922/5422 5414/5862/5414 \nf 5407/1561/5407 5405/5858/5405 5422/2922/5422 5421/5865/5421 \nf 4835/427/4835 4838/5557/4838 5423/2923/5423 5415/5863/5415 \nf 4830/1487/4830 5424/5867/5424 5423/2923/5423 4838/5557/4838 \nf 5425/778/5425 5426/5868/5426 5423/2923/5423 5424/5867/5424 \nf 5417/1562/5417 5415/5863/5415 5423/2923/5423 5426/5868/5426 \nf 4658/421/4658 4661/5460/4661 5427/2924/5427 4827/5551/4827 \nf 4654/1461/4654 5428/5869/5428 5427/2924/5427 4661/5460/4661 \nf 5425/778/5425 5424/5867/5424 5427/2924/5427 5428/5869/5428 \nf 4830/1487/4830 4827/5551/4827 5427/2924/5427 5424/5867/5424 \nf 4642/412/4642 5398/5854/5398 5429/2925/5429 4652/5455/4652 \nf 5395/1560/5395 5430/5870/5430 5429/2925/5429 5398/5854/5398 \nf 5425/778/5425 5428/5869/5428 5429/2925/5429 5430/5870/5430 \nf 4654/1461/4654 4652/5455/4652 5429/2925/5429 5428/5869/5428 \nf 5391/432/5391 5420/5866/5420 5431/2926/5431 5392/5851/5392 \nf 5417/1562/5417 5426/5868/5426 5431/2926/5431 5420/5866/5420 \nf 5425/778/5425 5430/5870/5430 5431/2926/5431 5426/5868/5426 \nf 5395/1560/5395 5392/5851/5392 5431/2926/5431 5430/5870/5430 \nf 4700/341/4700 5432/5871/5432 5433/2927/5433 4701/5480/4701 \nf 5434/1563/5434 5435/5872/5435 5433/2927/5433 5432/5871/5432 \nf 5436/779/5436 5437/5873/5437 5433/2927/5433 5435/5872/5435 \nf 4704/1468/4704 4701/5480/4701 5433/2927/5433 5437/5873/5437 \nf 5438/343/5438 5439/5874/5439 5440/2928/5440 5441/5876/5441 \nf 5442/1564/5442 5443/5875/5443 5440/2928/5440 5439/5874/5439 \nf 5436/779/5436 5435/5872/5435 5440/2928/5440 5443/5875/5443 \nf 5434/1563/5434 5441/5876/5441 5440/2928/5440 5435/5872/5435 \nf 5444/344/5444 5445/5877/5445 5446/2929/5446 5447/5879/5447 \nf 5448/1565/5448 5449/5878/5449 5446/2929/5446 5445/5877/5445 \nf 5436/779/5436 5443/5875/5443 5446/2929/5446 5449/5878/5449 \nf 5442/1564/5442 5447/5879/5447 5446/2929/5446 5443/5875/5443 \nf 4709/345/4709 4712/5487/4712 5450/2930/5450 5451/5880/5451 \nf 4704/1468/4704 5437/5873/5437 5450/2930/5450 4712/5487/4712 \nf 5436/779/5436 5449/5878/5449 5450/2930/5450 5437/5873/5437 \nf 5448/1565/5448 5451/5880/5451 5450/2930/5450 5449/5878/5449 \nf 5438/343/5438 5452/5881/5452 5453/2931/5453 5439/5874/5439 \nf 5454/1566/5454 5455/5882/5455 5453/2931/5453 5452/5881/5452 \nf 5456/780/5456 5457/5883/5457 5453/2931/5453 5455/5882/5455 \nf 5442/1564/5442 5439/5874/5439 5453/2931/5453 5457/5883/5457 \nf 2710/219/2710 2713/4428/2713 5458/2932/5458 5459/5885/5459 \nf 2706/1185/2706 5460/5884/5460 5458/2932/5458 2713/4428/2713 \nf 5456/780/5456 5455/5882/5455 5458/2932/5458 5460/5884/5460 \nf 5454/1566/5454 5459/5885/5459 5458/2932/5458 5455/5882/5455 \nf 2694/217/2694 5461/5886/5461 5462/2933/5462 2704/4423/2704 \nf 5463/1567/5463 5464/5887/5464 5462/2933/5462 5461/5886/5461 \nf 5456/780/5456 5460/5884/5460 5462/2933/5462 5464/5887/5464 \nf 2706/1185/2706 2704/4423/2704 5462/2933/5462 5460/5884/5460 \nf 5444/344/5444 5447/5879/5447 5465/2934/5465 5466/5888/5466 \nf 5442/1564/5442 5457/5883/5457 5465/2934/5465 5447/5879/5447 \nf 5456/780/5456 5464/5887/5464 5465/2934/5465 5457/5883/5457 \nf 5463/1567/5463 5466/5888/5466 5465/2934/5465 5464/5887/5464 \nf 2590/175/2590 5347/5827/5347 5467/2935/5467 2688/4415/2688 \nf 5342/1553/5342 5468/5889/5468 5467/2935/5467 5347/5827/5347 \nf 5469/781/5469 5470/5890/5470 5467/2935/5467 5468/5889/5468 \nf 2690/1183/2690 2688/4415/2688 5467/2935/5467 5470/5890/5470 \nf 5326/338/5326 5471/5891/5471 5472/2936/5472 5340/5823/5340 \nf 5473/1568/5473 5474/5892/5474 5472/2936/5472 5471/5891/5471 \nf 5469/781/5469 5468/5889/5468 5472/2936/5472 5474/5892/5474 \nf 5342/1553/5342 5340/5823/5340 5472/2936/5472 5468/5889/5468 \nf 5444/344/5444 5466/5888/5466 5475/2937/5475 5476/5894/5476 \nf 5463/1567/5463 5477/5893/5477 5475/2937/5475 5466/5888/5466 \nf 5469/781/5469 5474/5892/5474 5475/2937/5475 5477/5893/5477 \nf 5473/1568/5473 5476/5894/5476 5475/2937/5475 5474/5892/5474 \nf 2694/217/2694 2697/4420/2697 5478/2938/5478 5461/5886/5461 \nf 2690/1183/2690 5470/5890/5470 5478/2938/5478 2697/4420/2697 \nf 5469/781/5469 5477/5893/5477 5478/2938/5478 5470/5890/5470 \nf 5463/1567/5463 5461/5886/5461 5478/2938/5478 5477/5893/5477 \nf 5326/338/5326 5329/5816/5329 5479/2939/5479 5471/5891/5471 \nf 5322/1549/5322 5480/5895/5480 5479/2939/5479 5329/5816/5329 \nf 5481/782/5481 5482/5896/5482 5479/2939/5479 5480/5895/5480 \nf 5473/1568/5473 5471/5891/5471 5479/2939/5479 5482/5896/5482 \nf 4408/337/4408 4727/5497/4727 5483/2940/5483 5320/5811/5320 \nf 4722/1472/4722 5484/5897/5484 5483/2940/5483 4727/5497/4727 \nf 5481/782/5481 5480/5895/5480 5483/2940/5483 5484/5897/5484 \nf 5322/1549/5322 5320/5811/5320 5483/2940/5483 5480/5895/5480 \nf 4709/345/4709 5451/5880/5451 5485/2941/5485 4720/5492/4720 \nf 5448/1565/5448 5486/5898/5486 5485/2941/5485 5451/5880/5451 \nf 5481/782/5481 5484/5897/5484 5485/2941/5485 5486/5898/5486 \nf 4722/1472/4722 4720/5492/4720 5485/2941/5485 5484/5897/5484 \nf 5444/344/5444 5476/5894/5476 5487/2942/5487 5445/5877/5445 \nf 5473/1568/5473 5482/5896/5482 5487/2942/5487 5476/5894/5476 \nf 5481/782/5481 5486/5898/5486 5487/2942/5487 5482/5896/5482 \nf 5448/1565/5448 5445/5877/5445 5487/2942/5487 5486/5898/5486 \nf 4313/252/4313 4316/5275/4316 5488/2943/5488 4814/5542/4814 \nf 4309/1404/4309 5489/5899/5489 5488/2943/5488 4316/5275/4316 \nf 5490/783/5490 5491/5900/5491 5488/2943/5488 5489/5899/5489 \nf 4817/1485/4817 4814/5542/4814 5488/2943/5488 5491/5900/5491 \nf 4291/248/4291 5492/5901/5492 5493/2944/5493 4307/5269/4307 \nf 5494/1569/5494 5495/5902/5495 5493/2944/5493 5492/5901/5492 \nf 5490/783/5490 5489/5899/5489 5493/2944/5493 5495/5902/5495 \nf 4309/1404/4309 4307/5269/4307 5493/2944/5493 5489/5899/5489 \nf 5496/405/5496 5497/5903/5497 5498/2945/5498 5499/5906/5499 \nf 5500/1570/5500 5501/5905/5501 5498/2945/5498 5497/5903/5497 \nf 5490/783/5490 5495/5902/5495 5498/2945/5498 5501/5905/5501 \nf 5494/1569/5494 5499/5906/5499 5498/2945/5498 5495/5902/5495 \nf 4819/406/4819 4822/5549/4822 5502/2946/5502 5503/5907/5503 \nf 4817/1485/4817 5491/5900/5491 5502/2946/5502 4822/5549/4822 \nf 5490/783/5490 5501/5905/5501 5502/2946/5502 5491/5900/5491 \nf 5500/1570/5500 5503/5907/5503 5502/2946/5502 5501/5905/5501 \nf 4291/248/4291 4294/5263/4294 5504/2947/5504 5492/5901/5492 \nf 4286/1400/4286 5505/5909/5505 5504/2947/5504 4294/5263/4294 \nf 5506/784/5506 5507/5910/5507 5504/2947/5504 5505/5909/5505 \nf 5494/1569/5494 5492/5901/5492 5504/2947/5504 5507/5910/5507 \nf 4282/247/4282 5266/5781/5266 5508/2948/5508 4283/5257/4283 \nf 5261/1542/5261 5509/5911/5509 5508/2948/5508 5266/5781/5266 \nf 5506/784/5506 5505/5909/5505 5508/2948/5508 5509/5911/5509 \nf 4286/1400/4286 4283/5257/4283 5508/2948/5508 5505/5909/5505 \nf 5249/404/5249 5510/5912/5510 5511/2949/5511 5259/5777/5259 \nf 5512/1572/5512 5513/5913/5513 5511/2949/5511 5510/5912/5510 \nf 5506/784/5506 5509/5911/5509 5511/2949/5511 5513/5913/5513 \nf 5261/1542/5261 5259/5777/5259 5511/2949/5511 5509/5911/5509 \nf 5496/405/5496 5499/5906/5499 5514/2950/5514 5515/5914/5515 \nf 5494/1569/5494 5507/5910/5507 5514/2950/5514 5499/5906/5499 \nf 5506/784/5506 5513/5913/5513 5514/2950/5514 5507/5910/5507 \nf 5512/1572/5512 5515/5914/5515 5514/2950/5514 5513/5913/5513 \nf 4596/375/4596 4599/5426/4599 5516/2951/5516 5243/5769/5243 \nf 4604/1455/4604 5517/5915/5517 5516/2951/5516 4599/5426/4599 \nf 5518/785/5518 5519/5916/5519 5516/2951/5516 5517/5915/5517 \nf 5245/1540/5245 5243/5769/5243 5516/2951/5516 5519/5916/5519 \nf 4617/378/4617 5520/5917/5520 5521/2952/5521 4618/5434/4618 \nf 5522/1573/5522 5523/5919/5523 5521/2952/5521 5520/5917/5520 \nf 5518/785/5518 5517/5915/5517 5521/2952/5521 5523/5919/5523 \nf 4604/1455/4604 4618/5434/4618 5521/2952/5521 5517/5915/5517 \nf 5496/405/5496 5515/5914/5515 5524/2953/5524 5525/5921/5525 \nf 5512/1572/5512 5526/5920/5526 5524/2953/5524 5515/5914/5515 \nf 5518/785/5518 5523/5919/5523 5524/2953/5524 5526/5920/5526 \nf 5522/1573/5522 5525/5921/5525 5524/2953/5524 5523/5919/5523 \nf 5249/404/5249 5252/5774/5252 5527/2954/5527 5510/5912/5510 \nf 5245/1540/5245 5519/5916/5519 5527/2954/5527 5252/5774/5252 \nf 5518/785/5518 5526/5920/5526 5527/2954/5527 5519/5916/5519 \nf 5512/1572/5512 5510/5912/5510 5527/2954/5527 5526/5920/5526 \nf 4617/422/4617 4665/5462/4665 5528/2955/5528 5520/5918/5520 \nf 4662/1462/4662 5529/5923/5529 5528/2955/5528 4665/5462/4665 \nf 5530/786/5530 5531/5924/5531 5528/2955/5528 5529/5923/5529 \nf 5522/1574/5522 5520/5918/5520 5528/2955/5528 5531/5924/5531 \nf 4658/421/4658 4829/5554/4829 5532/2956/5532 4659/5458/4659 \nf 4834/1489/4834 5533/5925/5533 5532/2956/5532 4829/5554/4829 \nf 5530/786/5530 5529/5923/5529 5532/2956/5532 5533/5925/5533 \nf 4662/1462/4662 4659/5458/4659 5532/2956/5532 5529/5923/5529 \nf 4819/426/4819 5503/5908/5503 5534/2957/5534 4844/5560/4844 \nf 5500/1571/5500 5535/5926/5535 5534/2957/5534 5503/5908/5503 \nf 5530/786/5530 5533/5925/5533 5534/2957/5534 5535/5926/5535 \nf 4834/1489/4834 4844/5560/4844 5534/2957/5534 5533/5925/5533 \nf 5496/433/5496 5525/5922/5525 5536/2958/5536 5497/5904/5497 \nf 5522/1574/5522 5531/5924/5531 5536/2958/5536 5525/5922/5525 \nf 5530/786/5530 5535/5926/5535 5536/2958/5536 5531/5924/5531 \nf 5500/1571/5500 5497/5904/5497 5536/2958/5536 5535/5926/5535 \nf 3486/310/3486 4171/5203/4171 5537/2959/5537 4893/5586/4893 \nf 4175/1390/4175 5538/5927/5538 5537/2959/5537 4171/5203/4171 \nf 5539/787/5539 5540/5928/5540 5537/2959/5537 5538/5927/5538 \nf 4895/1497/4895 4893/5586/4893 5537/2959/5537 5540/5928/5540 \nf 4186/334/4186 5541/5929/5541 5542/2960/5542 4187/5209/4187 \nf 5543/1575/5543 5544/5930/5544 5542/2960/5542 5541/5929/5541 \nf 5539/787/5539 5538/5927/5538 5542/2960/5542 5544/5930/5544 \nf 4175/1390/4175 4187/5209/4187 5542/2960/5542 5538/5927/5538 \nf 5545/352/5545 5546/5931/5546 5547/2961/5547 5548/5933/5548 \nf 5549/1576/5549 5550/5932/5550 5547/2961/5547 5546/5931/5546 \nf 5539/787/5539 5544/5930/5544 5547/2961/5547 5550/5932/5550 \nf 5543/1575/5543 5548/5933/5548 5547/2961/5547 5544/5930/5544 \nf 4899/365/4899 4902/5592/4902 5551/2962/5551 5552/5934/5552 \nf 4895/1497/4895 5540/5928/5540 5551/2962/5551 4902/5592/4902 \nf 5539/787/5539 5550/5932/5550 5551/2962/5551 5540/5928/5540 \nf 5549/1576/5549 5552/5934/5552 5551/2962/5551 5550/5932/5550 \nf 4186/334/4186 4223/5228/4223 5553/2963/5553 5541/5929/5541 \nf 4220/1393/4220 5554/5935/5554 5553/2963/5553 4223/5228/4223 \nf 5555/788/5555 5556/5936/5556 5553/2963/5553 5554/5935/5554 \nf 5543/1575/5543 5541/5929/5541 5553/2963/5553 5556/5936/5556 \nf 1372/129/1372 2820/4485/2820 5557/2964/5557 4218/5225/4218 \nf 2815/1198/2815 5558/5937/5558 5557/2964/5557 2820/4485/2820 \nf 5555/788/5555 5554/5935/5554 5557/2964/5557 5558/5937/5558 \nf 4220/1393/4220 4218/5225/4218 5557/2964/5557 5554/5935/5554 \nf 2803/241/2803 5559/5938/5559 5560/2965/5560 2813/4481/2813 \nf 5561/1577/5561 5562/5939/5562 5560/2965/5560 5559/5938/5559 \nf 5555/788/5555 5558/5937/5558 5560/2965/5560 5562/5939/5562 \nf 2815/1198/2815 2813/4481/2813 5560/2965/5560 5558/5937/5558 \nf 5545/352/5545 5548/5933/5548 5563/2966/5563 5564/5940/5564 \nf 5543/1575/5543 5556/5936/5556 5563/2966/5563 5548/5933/5548 \nf 5555/788/5555 5562/5939/5562 5563/2966/5563 5556/5936/5556 \nf 5561/1577/5561 5564/5940/5564 5563/2966/5563 5562/5939/5562 \nf 2710/219/2710 5459/5885/5459 5565/2967/5565 2797/4473/2797 \nf 5454/1566/5454 5566/5941/5566 5565/2967/5565 5459/5885/5459 \nf 5567/789/5567 5568/5942/5568 5565/2967/5565 5566/5941/5566 \nf 2799/1196/2799 2797/4473/2797 5565/2967/5565 5568/5942/5568 \nf 5438/343/5438 5569/5943/5569 5570/2968/5570 5452/5881/5452 \nf 5571/1578/5571 5572/5944/5572 5570/2968/5570 5569/5943/5569 \nf 5567/789/5567 5566/5941/5566 5570/2968/5570 5572/5944/5572 \nf 5454/1566/5454 5452/5881/5452 5570/2968/5570 5566/5941/5566 \nf 5545/352/5545 5564/5940/5564 5573/2969/5573 5574/5946/5574 \nf 5561/1577/5561 5575/5945/5575 5573/2969/5573 5564/5940/5564 \nf 5567/789/5567 5572/5944/5572 5573/2969/5573 5575/5945/5575 \nf 5571/1578/5571 5574/5946/5574 5573/2969/5573 5572/5944/5572 \nf 2803/241/2803 2806/4478/2806 5576/2970/5576 5559/5938/5559 \nf 2799/1196/2799 5568/5942/5568 5576/2970/5576 2806/4478/2806 \nf 5567/789/5567 5575/5945/5575 5576/2970/5576 5568/5942/5568 \nf 5561/1577/5561 5559/5938/5559 5576/2970/5576 5575/5945/5575 \nf 5438/343/5438 5441/5876/5441 5577/2971/5577 5569/5943/5569 \nf 5434/1563/5434 5578/5947/5578 5577/2971/5577 5441/5876/5441 \nf 5579/790/5579 5580/5948/5580 5577/2971/5577 5578/5947/5578 \nf 5571/1578/5571 5569/5943/5569 5577/2971/5577 5580/5948/5580 \nf 4700/341/4700 4916/5601/4916 5581/2972/5581 5432/5871/5432 \nf 4911/1500/4911 5582/5949/5582 5581/2972/5581 4916/5601/4916 \nf 5579/790/5579 5578/5947/5578 5581/2972/5581 5582/5949/5582 \nf 5434/1563/5434 5432/5871/5432 5581/2972/5581 5578/5947/5578 \nf 4899/365/4899 5552/5934/5552 5583/2973/5583 4909/5596/4909 \nf 5549/1576/5549 5584/5950/5584 5583/2973/5583 5552/5934/5552 \nf 5579/790/5579 5582/5949/5582 5583/2973/5583 5584/5950/5584 \nf 4911/1500/4911 4909/5596/4909 5583/2973/5583 5582/5949/5582 \nf 5545/352/5545 5574/5946/5574 5585/2974/5585 5546/5931/5546 \nf 5571/1578/5571 5580/5948/5580 5585/2974/5585 5574/5946/5574 \nf 5579/790/5579 5584/5950/5584 5585/2974/5585 5580/5948/5580 \nf 5549/1576/5549 5546/5931/5546 5585/2974/5585 5584/5950/5584 \nf 3697/243/3697 4227/5231/4227 5586/2975/5586 5072/5680/5072 \nf 4231/1396/4231 5587/5951/5587 5586/2975/5586 4227/5231/4227 \nf 5588/791/5588 5589/5952/5589 5586/2975/5586 5587/5951/5587 \nf 5074/1520/5074 5072/5680/5072 5586/2975/5586 5589/5952/5589 \nf 4242/246/4242 5590/5953/5590 5591/2976/5591 4243/5237/4243 \nf 5592/1579/5592 5593/5954/5593 5591/2976/5591 5590/5953/5590 \nf 5588/791/5588 5587/5951/5587 5591/2976/5591 5593/5954/5593 \nf 4231/1396/4231 4243/5237/4243 5591/2976/5591 5587/5951/5587 \nf 5594/409/5594 5595/5955/5595 5596/2977/5596 5597/5957/5597 \nf 5598/1580/5598 5599/5956/5599 5596/2977/5596 5595/5955/5595 \nf 5588/791/5588 5593/5954/5593 5596/2977/5596 5599/5956/5599 \nf 5592/1579/5592 5597/5957/5597 5596/2977/5596 5593/5954/5593 \nf 5078/410/5078 5081/5686/5081 5600/2978/5600 5601/5958/5601 \nf 5074/1520/5074 5589/5952/5589 5600/2978/5600 5081/5686/5081 \nf 5588/791/5588 5599/5956/5599 5600/2978/5600 5589/5952/5589 \nf 5598/1580/5598 5601/5958/5601 5600/2978/5600 5599/5956/5599 \nf 4242/246/4242 4279/5256/4279 5602/2979/5602 5590/5953/5590 \nf 4276/1399/4276 5603/5959/5603 5602/2979/5602 4279/5256/4279 \nf 5604/792/5604 5605/5960/5605 5602/2979/5602 5603/5959/5603 \nf 5592/1579/5592 5590/5953/5590 5602/2979/5602 5605/5960/5605 \nf 3584/222/3584 4948/5617/4948 5606/2980/5606 4274/5253/4274 \nf 4943/1504/4943 5607/5961/5607 5606/2980/5606 4948/5617/4948 \nf 5604/792/5604 5603/5959/5603 5606/2980/5606 5607/5961/5607 \nf 4276/1399/4276 4274/5253/4274 5606/2980/5606 5603/5959/5603 \nf 4927/393/4927 5608/5962/5608 5609/2981/5609 4941/5613/4941 \nf 5610/1581/5610 5611/5963/5611 5609/2981/5609 5608/5962/5608 \nf 5604/792/5604 5607/5961/5607 5609/2981/5609 5611/5963/5611 \nf 4943/1504/4943 4941/5613/4941 5609/2981/5609 5607/5961/5607 \nf 5594/409/5594 5597/5957/5597 5612/2982/5612 5613/5964/5613 \nf 5592/1579/5592 5605/5960/5605 5612/2982/5612 5597/5957/5597 \nf 5604/792/5604 5611/5963/5611 5612/2982/5612 5605/5960/5605 \nf 5610/1581/5610 5613/5964/5613 5612/2982/5612 5611/5963/5611 \nf 4353/257/4353 4356/5298/4356 5614/2983/5614 4921/5603/4921 \nf 4349/1412/4349 5615/5965/5615 5614/2983/5614 4356/5298/4356 \nf 5616/793/5616 5617/5966/5617 5614/2983/5614 5615/5965/5615 \nf 4923/1501/4923 4921/5603/4921 5614/2983/5614 5617/5966/5617 \nf 4336/256/4336 5618/5967/5618 5619/2984/5619 4347/5293/4347 \nf 5620/1582/5620 5621/5968/5621 5619/2984/5619 5618/5967/5618 \nf 5616/793/5616 5615/5965/5615 5619/2984/5619 5621/5968/5621 \nf 4349/1412/4349 4347/5293/4347 5619/2984/5619 5615/5965/5615 \nf 5594/409/5594 5613/5964/5613 5622/2985/5622 5623/5970/5623 \nf 5610/1581/5610 5624/5969/5624 5622/2985/5622 5613/5964/5613 \nf 5616/793/5616 5621/5968/5621 5622/2985/5622 5624/5969/5624 \nf 5620/1582/5620 5623/5970/5623 5622/2985/5622 5621/5968/5621 \nf 4927/393/4927 4930/5608/4930 5625/2986/5625 5608/5962/5608 \nf 4923/1501/4923 5617/5966/5617 5625/2986/5625 4930/5608/4930 \nf 5616/793/5616 5624/5969/5624 5625/2986/5625 5617/5966/5617 \nf 5610/1581/5610 5608/5962/5608 5625/2986/5625 5624/5969/5624 \nf 4336/256/4336 4339/5288/4339 5626/2987/5626 5618/5967/5618 \nf 4331/1408/4331 5627/5971/5627 5626/2987/5626 4339/5288/4339 \nf 5628/794/5628 5629/5972/5629 5626/2987/5626 5627/5971/5627 \nf 5620/1582/5620 5618/5967/5618 5626/2987/5626 5629/5972/5629 \nf 4327/255/4327 5096/5696/5096 5630/2988/5630 4328/5281/4328 \nf 5090/1523/5090 5631/5973/5631 5630/2988/5630 5096/5696/5096 \nf 5628/794/5628 5627/5971/5627 5630/2988/5630 5631/5973/5631 \nf 4331/1408/4331 4328/5281/4328 5630/2988/5630 5627/5971/5627 \nf 5078/410/5078 5601/5958/5601 5632/2989/5632 5088/5690/5088 \nf 5598/1580/5598 5633/5974/5633 5632/2989/5632 5601/5958/5601 \nf 5628/794/5628 5631/5973/5631 5632/2989/5632 5633/5974/5633 \nf 5090/1523/5090 5088/5690/5088 5632/2989/5632 5631/5973/5631 \nf 5594/409/5594 5623/5970/5623 5634/2990/5634 5595/5955/5595 \nf 5620/1582/5620 5629/5972/5629 5634/2990/5634 5623/5970/5623 \nf 5628/794/5628 5633/5974/5633 5634/2990/5634 5629/5972/5629 \nf 5598/1580/5598 5595/5955/5595 5634/2990/5634 5633/5974/5633 \n# 5632 polygons\n\n"
  },
  {
    "path": "public/three/MeshSurfaceSampler.js",
    "content": "( function () {\n\n\t/**\n * Utility class for sampling weighted random points on the surface of a mesh.\n *\n * Building the sampler is a one-time O(n) operation. Once built, any number of\n * random samples may be selected in O(logn) time. Memory usage is O(n).\n *\n * References:\n * - http://www.joesfer.com/?p=84\n * - https://stackoverflow.com/a/4322940/1314762\n */\n\n\tconst _face = new THREE.Triangle();\n\n\tconst _color = new THREE.Vector3();\n\n\tclass MeshSurfaceSampler {\n\n\t\tconstructor( mesh ) {\n\n\t\t\tlet geometry = mesh.geometry;\n\n\t\t\tif ( ! geometry.isBufferGeometry || geometry.attributes.position.itemSize !== 3 ) {\n\n\t\t\t\tthrow new Error( 'THREE.MeshSurfaceSampler: Requires BufferGeometry triangle mesh.' );\n\n\t\t\t}\n\n\t\t\tif ( geometry.index ) {\n\n\t\t\t\tconsole.warn( 'THREE.MeshSurfaceSampler: Converting geometry to non-indexed BufferGeometry.' );\n\t\t\t\tgeometry = geometry.toNonIndexed();\n\n\t\t\t}\n\n\t\t\tthis.geometry = geometry;\n\t\t\tthis.randomFunction = Math.random;\n\t\t\tthis.positionAttribute = this.geometry.getAttribute( 'position' );\n\t\t\tthis.colorAttribute = this.geometry.getAttribute( 'color' );\n\t\t\tthis.weightAttribute = null;\n\t\t\tthis.distribution = null;\n\n\t\t}\n\n\t\tsetWeightAttribute( name ) {\n\n\t\t\tthis.weightAttribute = name ? this.geometry.getAttribute( name ) : null;\n\t\t\treturn this;\n\n\t\t}\n\n\t\tbuild() {\n\n\t\t\tconst positionAttribute = this.positionAttribute;\n\t\t\tconst weightAttribute = this.weightAttribute;\n\t\t\tconst faceWeights = new Float32Array( positionAttribute.count / 3 ); // Accumulate weights for each mesh face.\n\n\t\t\tfor ( let i = 0; i < positionAttribute.count; i += 3 ) {\n\n\t\t\t\tlet faceWeight = 1;\n\n\t\t\t\tif ( weightAttribute ) {\n\n\t\t\t\t\tfaceWeight = weightAttribute.getX( i ) + weightAttribute.getX( i + 1 ) + weightAttribute.getX( i + 2 );\n\n\t\t\t\t}\n\n\t\t\t\t_face.a.fromBufferAttribute( positionAttribute, i );\n\n\t\t\t\t_face.b.fromBufferAttribute( positionAttribute, i + 1 );\n\n\t\t\t\t_face.c.fromBufferAttribute( positionAttribute, i + 2 );\n\n\t\t\t\tfaceWeight *= _face.getArea();\n\t\t\t\tfaceWeights[ i / 3 ] = faceWeight;\n\n\t\t\t} // Store cumulative total face weights in an array, where weight index\n\t\t\t// corresponds to face index.\n\n\n\t\t\tthis.distribution = new Float32Array( positionAttribute.count / 3 );\n\t\t\tlet cumulativeTotal = 0;\n\n\t\t\tfor ( let i = 0; i < faceWeights.length; i ++ ) {\n\n\t\t\t\tcumulativeTotal += faceWeights[ i ];\n\t\t\t\tthis.distribution[ i ] = cumulativeTotal;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t\tsetRandomGenerator( randomFunction ) {\n\n\t\t\tthis.randomFunction = randomFunction;\n\t\t\treturn this;\n\n\t\t}\n\n\t\tsample( targetPosition, targetNormal, targetColor ) {\n\n\t\t\tconst cumulativeTotal = this.distribution[ this.distribution.length - 1 ];\n\t\t\tconst faceIndex = this.binarySearch( this.randomFunction() * cumulativeTotal );\n\t\t\treturn this.sampleFace( faceIndex, targetPosition, targetNormal, targetColor );\n\n\t\t}\n\n\t\tbinarySearch( x ) {\n\n\t\t\tconst dist = this.distribution;\n\t\t\tlet start = 0;\n\t\t\tlet end = dist.length - 1;\n\t\t\tlet index = - 1;\n\n\t\t\twhile ( start <= end ) {\n\n\t\t\t\tconst mid = Math.ceil( ( start + end ) / 2 );\n\n\t\t\t\tif ( mid === 0 || dist[ mid - 1 ] <= x && dist[ mid ] > x ) {\n\n\t\t\t\t\tindex = mid;\n\t\t\t\t\tbreak;\n\n\t\t\t\t} else if ( x < dist[ mid ] ) {\n\n\t\t\t\t\tend = mid - 1;\n\n\t\t\t\t} else {\n\n\t\t\t\t\tstart = mid + 1;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn index;\n\n\t\t}\n\n\t\tsampleFace( faceIndex, targetPosition, targetNormal, targetColor ) {\n\n\t\t\tlet u = this.randomFunction();\n\t\t\tlet v = this.randomFunction();\n\n\t\t\tif ( u + v > 1 ) {\n\n\t\t\t\tu = 1 - u;\n\t\t\t\tv = 1 - v;\n\n\t\t\t}\n\n\t\t\t_face.a.fromBufferAttribute( this.positionAttribute, faceIndex * 3 );\n\n\t\t\t_face.b.fromBufferAttribute( this.positionAttribute, faceIndex * 3 + 1 );\n\n\t\t\t_face.c.fromBufferAttribute( this.positionAttribute, faceIndex * 3 + 2 );\n\n\t\t\ttargetPosition.set( 0, 0, 0 ).addScaledVector( _face.a, u ).addScaledVector( _face.b, v ).addScaledVector( _face.c, 1 - ( u + v ) );\n\n\t\t\tif ( targetNormal !== undefined ) {\n\n\t\t\t\t_face.getNormal( targetNormal );\n\n\t\t\t}\n\n\t\t\tif ( targetColor !== undefined && this.colorAttribute !== undefined ) {\n\n\t\t\t\t_face.a.fromBufferAttribute( this.colorAttribute, faceIndex * 3 );\n\n\t\t\t\t_face.b.fromBufferAttribute( this.colorAttribute, faceIndex * 3 + 1 );\n\n\t\t\t\t_face.c.fromBufferAttribute( this.colorAttribute, faceIndex * 3 + 2 );\n\n\t\t\t\t_color.set( 0, 0, 0 ).addScaledVector( _face.a, u ).addScaledVector( _face.b, v ).addScaledVector( _face.c, 1 - ( u + v ) );\n\n\t\t\t\ttargetColor.r = _color.x;\n\t\t\t\ttargetColor.g = _color.y;\n\t\t\t\ttargetColor.b = _color.z;\n\n\t\t\t}\n\n\t\t\treturn this;\n\n\t\t}\n\n\t}\n\n\tTHREE.MeshSurfaceSampler = MeshSurfaceSampler;\n\n} )();\n"
  },
  {
    "path": "public/three/OBJLoader.js",
    "content": "( function () {\n\n\tconst _object_pattern = /^[og]\\s*(.+)?/; // mtllib file_reference\n\n\tconst _material_library_pattern = /^mtllib /; // usemtl material_name\n\n\tconst _material_use_pattern = /^usemtl /; // usemap map_name\n\n\tconst _map_use_pattern = /^usemap /;\n\n\tconst _vA = new THREE.Vector3();\n\n\tconst _vB = new THREE.Vector3();\n\n\tconst _vC = new THREE.Vector3();\n\n\tconst _ab = new THREE.Vector3();\n\n\tconst _cb = new THREE.Vector3();\n\n\tfunction ParserState() {\n\n\t\tconst state = {\n\t\t\tobjects: [],\n\t\t\tobject: {},\n\t\t\tvertices: [],\n\t\t\tnormals: [],\n\t\t\tcolors: [],\n\t\t\tuvs: [],\n\t\t\tmaterials: {},\n\t\t\tmaterialLibraries: [],\n\t\t\tstartObject: function ( name, fromDeclaration ) {\n\n\t\t\t\t// If the current object (initial from reset) is not from a g/o declaration in the parsed\n\t\t\t\t// file. We need to use it for the first parsed g/o to keep things in sync.\n\t\t\t\tif ( this.object && this.object.fromDeclaration === false ) {\n\n\t\t\t\t\tthis.object.name = name;\n\t\t\t\t\tthis.object.fromDeclaration = fromDeclaration !== false;\n\t\t\t\t\treturn;\n\n\t\t\t\t}\n\n\t\t\t\tconst previousMaterial = this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined;\n\n\t\t\t\tif ( this.object && typeof this.object._finalize === 'function' ) {\n\n\t\t\t\t\tthis.object._finalize( true );\n\n\t\t\t\t}\n\n\t\t\t\tthis.object = {\n\t\t\t\t\tname: name || '',\n\t\t\t\t\tfromDeclaration: fromDeclaration !== false,\n\t\t\t\t\tgeometry: {\n\t\t\t\t\t\tvertices: [],\n\t\t\t\t\t\tnormals: [],\n\t\t\t\t\t\tcolors: [],\n\t\t\t\t\t\tuvs: [],\n\t\t\t\t\t\thasUVIndices: false\n\t\t\t\t\t},\n\t\t\t\t\tmaterials: [],\n\t\t\t\t\tsmooth: true,\n\t\t\t\t\tstartMaterial: function ( name, libraries ) {\n\n\t\t\t\t\t\tconst previous = this._finalize( false ); // New usemtl declaration overwrites an inherited material, except if faces were declared\n\t\t\t\t\t\t// after the material, then it must be preserved for proper MultiMaterial continuation.\n\n\n\t\t\t\t\t\tif ( previous && ( previous.inherited || previous.groupCount <= 0 ) ) {\n\n\t\t\t\t\t\t\tthis.materials.splice( previous.index, 1 );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst material = {\n\t\t\t\t\t\t\tindex: this.materials.length,\n\t\t\t\t\t\t\tname: name || '',\n\t\t\t\t\t\t\tmtllib: Array.isArray( libraries ) && libraries.length > 0 ? libraries[ libraries.length - 1 ] : '',\n\t\t\t\t\t\t\tsmooth: previous !== undefined ? previous.smooth : this.smooth,\n\t\t\t\t\t\t\tgroupStart: previous !== undefined ? previous.groupEnd : 0,\n\t\t\t\t\t\t\tgroupEnd: - 1,\n\t\t\t\t\t\t\tgroupCount: - 1,\n\t\t\t\t\t\t\tinherited: false,\n\t\t\t\t\t\t\tclone: function ( index ) {\n\n\t\t\t\t\t\t\t\tconst cloned = {\n\t\t\t\t\t\t\t\t\tindex: typeof index === 'number' ? index : this.index,\n\t\t\t\t\t\t\t\t\tname: this.name,\n\t\t\t\t\t\t\t\t\tmtllib: this.mtllib,\n\t\t\t\t\t\t\t\t\tsmooth: this.smooth,\n\t\t\t\t\t\t\t\t\tgroupStart: 0,\n\t\t\t\t\t\t\t\t\tgroupEnd: - 1,\n\t\t\t\t\t\t\t\t\tgroupCount: - 1,\n\t\t\t\t\t\t\t\t\tinherited: false\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tcloned.clone = this.clone.bind( cloned );\n\t\t\t\t\t\t\t\treturn cloned;\n\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t\tthis.materials.push( material );\n\t\t\t\t\t\treturn material;\n\n\t\t\t\t\t},\n\t\t\t\t\tcurrentMaterial: function () {\n\n\t\t\t\t\t\tif ( this.materials.length > 0 ) {\n\n\t\t\t\t\t\t\treturn this.materials[ this.materials.length - 1 ];\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn undefined;\n\n\t\t\t\t\t},\n\t\t\t\t\t_finalize: function ( end ) {\n\n\t\t\t\t\t\tconst lastMultiMaterial = this.currentMaterial();\n\n\t\t\t\t\t\tif ( lastMultiMaterial && lastMultiMaterial.groupEnd === - 1 ) {\n\n\t\t\t\t\t\t\tlastMultiMaterial.groupEnd = this.geometry.vertices.length / 3;\n\t\t\t\t\t\t\tlastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart;\n\t\t\t\t\t\t\tlastMultiMaterial.inherited = false;\n\n\t\t\t\t\t\t} // Ignore objects tail materials if no face declarations followed them before a new o/g started.\n\n\n\t\t\t\t\t\tif ( end && this.materials.length > 1 ) {\n\n\t\t\t\t\t\t\tfor ( let mi = this.materials.length - 1; mi >= 0; mi -- ) {\n\n\t\t\t\t\t\t\t\tif ( this.materials[ mi ].groupCount <= 0 ) {\n\n\t\t\t\t\t\t\t\t\tthis.materials.splice( mi, 1 );\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} // Guarantee at least one empty material, this makes the creation later more straight forward.\n\n\n\t\t\t\t\t\tif ( end && this.materials.length === 0 ) {\n\n\t\t\t\t\t\t\tthis.materials.push( {\n\t\t\t\t\t\t\t\tname: '',\n\t\t\t\t\t\t\t\tsmooth: this.smooth\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn lastMultiMaterial;\n\n\t\t\t\t\t}\n\t\t\t\t}; // Inherit previous objects material.\n\t\t\t\t// Spec tells us that a declared material must be set to all objects until a new material is declared.\n\t\t\t\t// If a usemtl declaration is encountered while this new object is being parsed, it will\n\t\t\t\t// overwrite the inherited material. Exception being that there was already face declarations\n\t\t\t\t// to the inherited material, then it will be preserved for proper MultiMaterial continuation.\n\n\t\t\t\tif ( previousMaterial && previousMaterial.name && typeof previousMaterial.clone === 'function' ) {\n\n\t\t\t\t\tconst declared = previousMaterial.clone( 0 );\n\t\t\t\t\tdeclared.inherited = true;\n\t\t\t\t\tthis.object.materials.push( declared );\n\n\t\t\t\t}\n\n\t\t\t\tthis.objects.push( this.object );\n\n\t\t\t},\n\t\t\tfinalize: function () {\n\n\t\t\t\tif ( this.object && typeof this.object._finalize === 'function' ) {\n\n\t\t\t\t\tthis.object._finalize( true );\n\n\t\t\t\t}\n\n\t\t\t},\n\t\t\tparseVertexIndex: function ( value, len ) {\n\n\t\t\t\tconst index = parseInt( value, 10 );\n\t\t\t\treturn ( index >= 0 ? index - 1 : index + len / 3 ) * 3;\n\n\t\t\t},\n\t\t\tparseNormalIndex: function ( value, len ) {\n\n\t\t\t\tconst index = parseInt( value, 10 );\n\t\t\t\treturn ( index >= 0 ? index - 1 : index + len / 3 ) * 3;\n\n\t\t\t},\n\t\t\tparseUVIndex: function ( value, len ) {\n\n\t\t\t\tconst index = parseInt( value, 10 );\n\t\t\t\treturn ( index >= 0 ? index - 1 : index + len / 2 ) * 2;\n\n\t\t\t},\n\t\t\taddVertex: function ( a, b, c ) {\n\n\t\t\t\tconst src = this.vertices;\n\t\t\t\tconst dst = this.object.geometry.vertices;\n\t\t\t\tdst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );\n\t\t\t\tdst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );\n\t\t\t\tdst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );\n\n\t\t\t},\n\t\t\taddVertexPoint: function ( a ) {\n\n\t\t\t\tconst src = this.vertices;\n\t\t\t\tconst dst = this.object.geometry.vertices;\n\t\t\t\tdst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );\n\n\t\t\t},\n\t\t\taddVertexLine: function ( a ) {\n\n\t\t\t\tconst src = this.vertices;\n\t\t\t\tconst dst = this.object.geometry.vertices;\n\t\t\t\tdst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );\n\n\t\t\t},\n\t\t\taddNormal: function ( a, b, c ) {\n\n\t\t\t\tconst src = this.normals;\n\t\t\t\tconst dst = this.object.geometry.normals;\n\t\t\t\tdst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );\n\t\t\t\tdst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );\n\t\t\t\tdst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );\n\n\t\t\t},\n\t\t\taddFaceNormal: function ( a, b, c ) {\n\n\t\t\t\tconst src = this.vertices;\n\t\t\t\tconst dst = this.object.geometry.normals;\n\n\t\t\t\t_vA.fromArray( src, a );\n\n\t\t\t\t_vB.fromArray( src, b );\n\n\t\t\t\t_vC.fromArray( src, c );\n\n\t\t\t\t_cb.subVectors( _vC, _vB );\n\n\t\t\t\t_ab.subVectors( _vA, _vB );\n\n\t\t\t\t_cb.cross( _ab );\n\n\t\t\t\t_cb.normalize();\n\n\t\t\t\tdst.push( _cb.x, _cb.y, _cb.z );\n\t\t\t\tdst.push( _cb.x, _cb.y, _cb.z );\n\t\t\t\tdst.push( _cb.x, _cb.y, _cb.z );\n\n\t\t\t},\n\t\t\taddColor: function ( a, b, c ) {\n\n\t\t\t\tconst src = this.colors;\n\t\t\t\tconst dst = this.object.geometry.colors;\n\t\t\t\tif ( src[ a ] !== undefined ) dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );\n\t\t\t\tif ( src[ b ] !== undefined ) dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );\n\t\t\t\tif ( src[ c ] !== undefined ) dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );\n\n\t\t\t},\n\t\t\taddUV: function ( a, b, c ) {\n\n\t\t\t\tconst src = this.uvs;\n\t\t\t\tconst dst = this.object.geometry.uvs;\n\t\t\t\tdst.push( src[ a + 0 ], src[ a + 1 ] );\n\t\t\t\tdst.push( src[ b + 0 ], src[ b + 1 ] );\n\t\t\t\tdst.push( src[ c + 0 ], src[ c + 1 ] );\n\n\t\t\t},\n\t\t\taddDefaultUV: function () {\n\n\t\t\t\tconst dst = this.object.geometry.uvs;\n\t\t\t\tdst.push( 0, 0 );\n\t\t\t\tdst.push( 0, 0 );\n\t\t\t\tdst.push( 0, 0 );\n\n\t\t\t},\n\t\t\taddUVLine: function ( a ) {\n\n\t\t\t\tconst src = this.uvs;\n\t\t\t\tconst dst = this.object.geometry.uvs;\n\t\t\t\tdst.push( src[ a + 0 ], src[ a + 1 ] );\n\n\t\t\t},\n\t\t\taddFace: function ( a, b, c, ua, ub, uc, na, nb, nc ) {\n\n\t\t\t\tconst vLen = this.vertices.length;\n\t\t\t\tlet ia = this.parseVertexIndex( a, vLen );\n\t\t\t\tlet ib = this.parseVertexIndex( b, vLen );\n\t\t\t\tlet ic = this.parseVertexIndex( c, vLen );\n\t\t\t\tthis.addVertex( ia, ib, ic );\n\t\t\t\tthis.addColor( ia, ib, ic ); // normals\n\n\t\t\t\tif ( na !== undefined && na !== '' ) {\n\n\t\t\t\t\tconst nLen = this.normals.length;\n\t\t\t\t\tia = this.parseNormalIndex( na, nLen );\n\t\t\t\t\tib = this.parseNormalIndex( nb, nLen );\n\t\t\t\t\tic = this.parseNormalIndex( nc, nLen );\n\t\t\t\t\tthis.addNormal( ia, ib, ic );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthis.addFaceNormal( ia, ib, ic );\n\n\t\t\t\t} // uvs\n\n\n\t\t\t\tif ( ua !== undefined && ua !== '' ) {\n\n\t\t\t\t\tconst uvLen = this.uvs.length;\n\t\t\t\t\tia = this.parseUVIndex( ua, uvLen );\n\t\t\t\t\tib = this.parseUVIndex( ub, uvLen );\n\t\t\t\t\tic = this.parseUVIndex( uc, uvLen );\n\t\t\t\t\tthis.addUV( ia, ib, ic );\n\t\t\t\t\tthis.object.geometry.hasUVIndices = true;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// add placeholder values (for inconsistent face definitions)\n\t\t\t\t\tthis.addDefaultUV();\n\n\t\t\t\t}\n\n\t\t\t},\n\t\t\taddPointGeometry: function ( vertices ) {\n\n\t\t\t\tthis.object.geometry.type = 'Points';\n\t\t\t\tconst vLen = this.vertices.length;\n\n\t\t\t\tfor ( let vi = 0, l = vertices.length; vi < l; vi ++ ) {\n\n\t\t\t\t\tconst index = this.parseVertexIndex( vertices[ vi ], vLen );\n\t\t\t\t\tthis.addVertexPoint( index );\n\t\t\t\t\tthis.addColor( index );\n\n\t\t\t\t}\n\n\t\t\t},\n\t\t\taddLineGeometry: function ( vertices, uvs ) {\n\n\t\t\t\tthis.object.geometry.type = 'Line';\n\t\t\t\tconst vLen = this.vertices.length;\n\t\t\t\tconst uvLen = this.uvs.length;\n\n\t\t\t\tfor ( let vi = 0, l = vertices.length; vi < l; vi ++ ) {\n\n\t\t\t\t\tthis.addVertexLine( this.parseVertexIndex( vertices[ vi ], vLen ) );\n\n\t\t\t\t}\n\n\t\t\t\tfor ( let uvi = 0, l = uvs.length; uvi < l; uvi ++ ) {\n\n\t\t\t\t\tthis.addUVLine( this.parseUVIndex( uvs[ uvi ], uvLen ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\t\t};\n\t\tstate.startObject( '', false );\n\t\treturn state;\n\n\t} //\n\n\n\tclass OBJLoader extends THREE.Loader {\n\n\t\tconstructor( manager ) {\n\n\t\t\tsuper( manager );\n\t\t\tthis.materials = null;\n\n\t\t}\n\n\t\tload( url, onLoad, onProgress, onError ) {\n\n\t\t\tconst scope = this;\n\t\t\tconst loader = new THREE.FileLoader( this.manager );\n\t\t\tloader.setPath( this.path );\n\t\t\tloader.setRequestHeader( this.requestHeader );\n\t\t\tloader.setWithCredentials( this.withCredentials );\n\t\t\tloader.load( url, function ( text ) {\n\n\t\t\t\ttry {\n\n\t\t\t\t\tonLoad( scope.parse( text ) );\n\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\tif ( onError ) {\n\n\t\t\t\t\t\tonError( e );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.error( e );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tscope.manager.itemError( url );\n\n\t\t\t\t}\n\n\t\t\t}, onProgress, onError );\n\n\t\t}\n\n\t\tsetMaterials( materials ) {\n\n\t\t\tthis.materials = materials;\n\t\t\treturn this;\n\n\t\t}\n\n\t\tparse( text ) {\n\n\t\t\tconst state = new ParserState();\n\n\t\t\tif ( text.indexOf( '\\r\\n' ) !== - 1 ) {\n\n\t\t\t\t// This is faster than String.split with regex that splits on both\n\t\t\t\ttext = text.replace( /\\r\\n/g, '\\n' );\n\n\t\t\t}\n\n\t\t\tif ( text.indexOf( '\\\\\\n' ) !== - 1 ) {\n\n\t\t\t\t// join lines separated by a line continuation character (\\)\n\t\t\t\ttext = text.replace( /\\\\\\n/g, '' );\n\n\t\t\t}\n\n\t\t\tconst lines = text.split( '\\n' );\n\t\t\tlet line = '',\n\t\t\t\tlineFirstChar = '';\n\t\t\tlet lineLength = 0;\n\t\t\tlet result = []; // Faster to just trim left side of the line. Use if available.\n\n\t\t\tconst trimLeft = typeof ''.trimLeft === 'function';\n\n\t\t\tfor ( let i = 0, l = lines.length; i < l; i ++ ) {\n\n\t\t\t\tline = lines[ i ];\n\t\t\t\tline = trimLeft ? line.trimLeft() : line.trim();\n\t\t\t\tlineLength = line.length;\n\t\t\t\tif ( lineLength === 0 ) continue;\n\t\t\t\tlineFirstChar = line.charAt( 0 ); // @todo invoke passed in handler if any\n\n\t\t\t\tif ( lineFirstChar === '#' ) continue;\n\n\t\t\t\tif ( lineFirstChar === 'v' ) {\n\n\t\t\t\t\tconst data = line.split( /\\s+/ );\n\n\t\t\t\t\tswitch ( data[ 0 ] ) {\n\n\t\t\t\t\t\tcase 'v':\n\t\t\t\t\t\t\tstate.vertices.push( parseFloat( data[ 1 ] ), parseFloat( data[ 2 ] ), parseFloat( data[ 3 ] ) );\n\n\t\t\t\t\t\t\tif ( data.length >= 7 ) {\n\n\t\t\t\t\t\t\t\tstate.colors.push( parseFloat( data[ 4 ] ), parseFloat( data[ 5 ] ), parseFloat( data[ 6 ] ) );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// if no colors are defined, add placeholders so color and vertex indices match\n\t\t\t\t\t\t\t\tstate.colors.push( undefined, undefined, undefined );\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'vn':\n\t\t\t\t\t\t\tstate.normals.push( parseFloat( data[ 1 ] ), parseFloat( data[ 2 ] ), parseFloat( data[ 3 ] ) );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase 'vt':\n\t\t\t\t\t\t\tstate.uvs.push( parseFloat( data[ 1 ] ), parseFloat( data[ 2 ] ) );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( lineFirstChar === 'f' ) {\n\n\t\t\t\t\tconst lineData = line.substr( 1 ).trim();\n\t\t\t\t\tconst vertexData = lineData.split( /\\s+/ );\n\t\t\t\t\tconst faceVertices = []; // Parse the face vertex data into an easy to work with format\n\n\t\t\t\t\tfor ( let j = 0, jl = vertexData.length; j < jl; j ++ ) {\n\n\t\t\t\t\t\tconst vertex = vertexData[ j ];\n\n\t\t\t\t\t\tif ( vertex.length > 0 ) {\n\n\t\t\t\t\t\t\tconst vertexParts = vertex.split( '/' );\n\t\t\t\t\t\t\tfaceVertices.push( vertexParts );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} // Draw an edge between the first vertex and all subsequent vertices to form an n-gon\n\n\n\t\t\t\t\tconst v1 = faceVertices[ 0 ];\n\n\t\t\t\t\tfor ( let j = 1, jl = faceVertices.length - 1; j < jl; j ++ ) {\n\n\t\t\t\t\t\tconst v2 = faceVertices[ j ];\n\t\t\t\t\t\tconst v3 = faceVertices[ j + 1 ];\n\t\t\t\t\t\tstate.addFace( v1[ 0 ], v2[ 0 ], v3[ 0 ], v1[ 1 ], v2[ 1 ], v3[ 1 ], v1[ 2 ], v2[ 2 ], v3[ 2 ] );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( lineFirstChar === 'l' ) {\n\n\t\t\t\t\tconst lineParts = line.substring( 1 ).trim().split( ' ' );\n\t\t\t\t\tlet lineVertices = [];\n\t\t\t\t\tconst lineUVs = [];\n\n\t\t\t\t\tif ( line.indexOf( '/' ) === - 1 ) {\n\n\t\t\t\t\t\tlineVertices = lineParts;\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tfor ( let li = 0, llen = lineParts.length; li < llen; li ++ ) {\n\n\t\t\t\t\t\t\tconst parts = lineParts[ li ].split( '/' );\n\t\t\t\t\t\t\tif ( parts[ 0 ] !== '' ) lineVertices.push( parts[ 0 ] );\n\t\t\t\t\t\t\tif ( parts[ 1 ] !== '' ) lineUVs.push( parts[ 1 ] );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tstate.addLineGeometry( lineVertices, lineUVs );\n\n\t\t\t\t} else if ( lineFirstChar === 'p' ) {\n\n\t\t\t\t\tconst lineData = line.substr( 1 ).trim();\n\t\t\t\t\tconst pointData = lineData.split( ' ' );\n\t\t\t\t\tstate.addPointGeometry( pointData );\n\n\t\t\t\t} else if ( ( result = _object_pattern.exec( line ) ) !== null ) {\n\n\t\t\t\t\t// o object_name\n\t\t\t\t\t// or\n\t\t\t\t\t// g group_name\n\t\t\t\t\t// WORKAROUND: https://bugs.chromium.org/p/v8/issues/detail?id=2869\n\t\t\t\t\t// let name = result[ 0 ].substr( 1 ).trim();\n\t\t\t\t\tconst name = ( ' ' + result[ 0 ].substr( 1 ).trim() ).substr( 1 );\n\t\t\t\t\tstate.startObject( name );\n\n\t\t\t\t} else if ( _material_use_pattern.test( line ) ) {\n\n\t\t\t\t\t// material\n\t\t\t\t\tstate.object.startMaterial( line.substring( 7 ).trim(), state.materialLibraries );\n\n\t\t\t\t} else if ( _material_library_pattern.test( line ) ) {\n\n\t\t\t\t\t// mtl file\n\t\t\t\t\tstate.materialLibraries.push( line.substring( 7 ).trim() );\n\n\t\t\t\t} else if ( _map_use_pattern.test( line ) ) {\n\n\t\t\t\t\t// the line is parsed but ignored since the loader assumes textures are defined MTL files\n\t\t\t\t\t// (according to https://www.okino.com/conv/imp_wave.htm, 'usemap' is the old-style Wavefront texture reference method)\n\t\t\t\t\tconsole.warn( 'THREE.OBJLoader: Rendering identifier \"usemap\" not supported. Textures must be defined in MTL files.' );\n\n\t\t\t\t} else if ( lineFirstChar === 's' ) {\n\n\t\t\t\t\tresult = line.split( ' ' ); // smooth shading\n\t\t\t\t\t// @todo Handle files that have varying smooth values for a set of faces inside one geometry,\n\t\t\t\t\t// but does not define a usemtl for each face set.\n\t\t\t\t\t// This should be detected and a dummy material created (later MultiMaterial and geometry groups).\n\t\t\t\t\t// This requires some care to not create extra material on each smooth value for \"normal\" obj files.\n\t\t\t\t\t// where explicit usemtl defines geometry groups.\n\t\t\t\t\t// Example asset: examples/models/obj/cerberus/Cerberus.obj\n\n\t\t\t\t\t/*\n        \t * http://paulbourke.net/dataformats/obj/\n        \t * or\n        \t * http://www.cs.utah.edu/~boulos/cs3505/obj_spec.pdf\n        \t *\n        \t * From chapter \"Grouping\" Syntax explanation \"s group_number\":\n        \t * \"group_number is the smoothing group number. To turn off smoothing groups, use a value of 0 or off.\n        \t * Polygonal elements use group numbers to put elements in different smoothing groups. For free-form\n        \t * surfaces, smoothing groups are either turned on or off; there is no difference between values greater\n        \t * than 0.\"\n        \t */\n\n\t\t\t\t\tif ( result.length > 1 ) {\n\n\t\t\t\t\t\tconst value = result[ 1 ].trim().toLowerCase();\n\t\t\t\t\t\tstate.object.smooth = value !== '0' && value !== 'off';\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// ZBrush can produce \"s\" lines #11707\n\t\t\t\t\t\tstate.object.smooth = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tconst material = state.object.currentMaterial();\n\t\t\t\t\tif ( material ) material.smooth = state.object.smooth;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Handle null terminated files without exception\n\t\t\t\t\tif ( line === '\\0' ) continue;\n\t\t\t\t\tconsole.warn( 'THREE.OBJLoader: Unexpected line: \"' + line + '\"' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tstate.finalize();\n\t\t\tconst container = new THREE.Group();\n\t\t\tcontainer.materialLibraries = [].concat( state.materialLibraries );\n\t\t\tconst hasPrimitives = ! ( state.objects.length === 1 && state.objects[ 0 ].geometry.vertices.length === 0 );\n\n\t\t\tif ( hasPrimitives === true ) {\n\n\t\t\t\tfor ( let i = 0, l = state.objects.length; i < l; i ++ ) {\n\n\t\t\t\t\tconst object = state.objects[ i ];\n\t\t\t\t\tconst geometry = object.geometry;\n\t\t\t\t\tconst materials = object.materials;\n\t\t\t\t\tconst isLine = geometry.type === 'Line';\n\t\t\t\t\tconst isPoints = geometry.type === 'Points';\n\t\t\t\t\tlet hasVertexColors = false; // Skip o/g line declarations that did not follow with any faces\n\n\t\t\t\t\tif ( geometry.vertices.length === 0 ) continue;\n\t\t\t\t\tconst buffergeometry = new THREE.BufferGeometry();\n\t\t\t\t\tbuffergeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( geometry.vertices, 3 ) );\n\n\t\t\t\t\tif ( geometry.normals.length > 0 ) {\n\n\t\t\t\t\t\tbuffergeometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( geometry.normals, 3 ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( geometry.colors.length > 0 ) {\n\n\t\t\t\t\t\thasVertexColors = true;\n\t\t\t\t\t\tbuffergeometry.setAttribute( 'color', new THREE.Float32BufferAttribute( geometry.colors, 3 ) );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( geometry.hasUVIndices === true ) {\n\n\t\t\t\t\t\tbuffergeometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( geometry.uvs, 2 ) );\n\n\t\t\t\t\t} // Create materials\n\n\n\t\t\t\t\tconst createdMaterials = [];\n\n\t\t\t\t\tfor ( let mi = 0, miLen = materials.length; mi < miLen; mi ++ ) {\n\n\t\t\t\t\t\tconst sourceMaterial = materials[ mi ];\n\t\t\t\t\t\tconst materialHash = sourceMaterial.name + '_' + sourceMaterial.smooth + '_' + hasVertexColors;\n\t\t\t\t\t\tlet material = state.materials[ materialHash ];\n\n\t\t\t\t\t\tif ( this.materials !== null ) {\n\n\t\t\t\t\t\t\tmaterial = this.materials.create( sourceMaterial.name ); // mtl etc. loaders probably can't create line materials correctly, copy properties to a line material.\n\n\t\t\t\t\t\t\tif ( isLine && material && ! ( material instanceof THREE.LineBasicMaterial ) ) {\n\n\t\t\t\t\t\t\t\tconst materialLine = new THREE.LineBasicMaterial();\n\t\t\t\t\t\t\t\tTHREE.Material.prototype.copy.call( materialLine, material );\n\t\t\t\t\t\t\t\tmaterialLine.color.copy( material.color );\n\t\t\t\t\t\t\t\tmaterial = materialLine;\n\n\t\t\t\t\t\t\t} else if ( isPoints && material && ! ( material instanceof THREE.PointsMaterial ) ) {\n\n\t\t\t\t\t\t\t\tconst materialPoints = new THREE.PointsMaterial( {\n\t\t\t\t\t\t\t\t\tsize: 10,\n\t\t\t\t\t\t\t\t\tsizeAttenuation: false\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t\tTHREE.Material.prototype.copy.call( materialPoints, material );\n\t\t\t\t\t\t\t\tmaterialPoints.color.copy( material.color );\n\t\t\t\t\t\t\t\tmaterialPoints.map = material.map;\n\t\t\t\t\t\t\t\tmaterial = materialPoints;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( material === undefined ) {\n\n\t\t\t\t\t\t\tif ( isLine ) {\n\n\t\t\t\t\t\t\t\tmaterial = new THREE.LineBasicMaterial();\n\n\t\t\t\t\t\t\t} else if ( isPoints ) {\n\n\t\t\t\t\t\t\t\tmaterial = new THREE.PointsMaterial( {\n\t\t\t\t\t\t\t\t\tsize: 1,\n\t\t\t\t\t\t\t\t\tsizeAttenuation: false\n\t\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tmaterial = new THREE.MeshPhongMaterial();\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tmaterial.name = sourceMaterial.name;\n\t\t\t\t\t\t\tmaterial.flatShading = sourceMaterial.smooth ? false : true;\n\t\t\t\t\t\t\tmaterial.vertexColors = hasVertexColors;\n\t\t\t\t\t\t\tstate.materials[ materialHash ] = material;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcreatedMaterials.push( material );\n\n\t\t\t\t\t} // Create mesh\n\n\n\t\t\t\t\tlet mesh;\n\n\t\t\t\t\tif ( createdMaterials.length > 1 ) {\n\n\t\t\t\t\t\tfor ( let mi = 0, miLen = materials.length; mi < miLen; mi ++ ) {\n\n\t\t\t\t\t\t\tconst sourceMaterial = materials[ mi ];\n\t\t\t\t\t\t\tbuffergeometry.addGroup( sourceMaterial.groupStart, sourceMaterial.groupCount, mi );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( isLine ) {\n\n\t\t\t\t\t\t\tmesh = new THREE.LineSegments( buffergeometry, createdMaterials );\n\n\t\t\t\t\t\t} else if ( isPoints ) {\n\n\t\t\t\t\t\t\tmesh = new THREE.Points( buffergeometry, createdMaterials );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tmesh = new THREE.Mesh( buffergeometry, createdMaterials );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tif ( isLine ) {\n\n\t\t\t\t\t\t\tmesh = new THREE.LineSegments( buffergeometry, createdMaterials[ 0 ] );\n\n\t\t\t\t\t\t} else if ( isPoints ) {\n\n\t\t\t\t\t\t\tmesh = new THREE.Points( buffergeometry, createdMaterials[ 0 ] );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tmesh = new THREE.Mesh( buffergeometry, createdMaterials[ 0 ] );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tmesh.name = object.name;\n\t\t\t\t\tcontainer.add( mesh );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// if there is only the default parser state object with no geometry data, interpret data as point cloud\n\t\t\t\tif ( state.vertices.length > 0 ) {\n\n\t\t\t\t\tconst material = new THREE.PointsMaterial( {\n\t\t\t\t\t\tsize: 1,\n\t\t\t\t\t\tsizeAttenuation: false\n\t\t\t\t\t} );\n\t\t\t\t\tconst buffergeometry = new THREE.BufferGeometry();\n\t\t\t\t\tbuffergeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( state.vertices, 3 ) );\n\n\t\t\t\t\tif ( state.colors.length > 0 && state.colors[ 0 ] !== undefined ) {\n\n\t\t\t\t\t\tbuffergeometry.setAttribute( 'color', new THREE.Float32BufferAttribute( state.colors, 3 ) );\n\t\t\t\t\t\tmaterial.vertexColors = true;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tconst points = new THREE.Points( buffergeometry, material );\n\t\t\t\t\tcontainer.add( points );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\treturn container;\n\n\t\t}\n\n\t}\n\n\tTHREE.OBJLoader = OBJLoader;\n\n} )();\n"
  },
  {
    "path": "public/three/TrackballControls.js",
    "content": "( function () {\n\n\tconst _changeEvent = {\n\t\ttype: 'change'\n\t};\n\tconst _startEvent = {\n\t\ttype: 'start'\n\t};\n\tconst _endEvent = {\n\t\ttype: 'end'\n\t};\n\n\tclass TrackballControls extends THREE.EventDispatcher {\n\n\t\tconstructor( object, domElement ) {\n\n\t\t\tsuper();\n\t\t\tif ( domElement === undefined ) console.warn( 'THREE.TrackballControls: The second parameter \"domElement\" is now mandatory.' );\n\t\t\tif ( domElement === document ) console.error( 'THREE.TrackballControls: \"document\" should not be used as the target \"domElement\". Please use \"renderer.domElement\" instead.' );\n\t\t\tconst scope = this;\n\t\t\tconst STATE = {\n\t\t\t\tNONE: - 1,\n\t\t\t\tROTATE: 0,\n\t\t\t\tZOOM: 1,\n\t\t\t\tPAN: 2,\n\t\t\t\tTOUCH_ROTATE: 3,\n\t\t\t\tTOUCH_ZOOM_PAN: 4\n\t\t\t};\n\t\t\tthis.object = object;\n\t\t\tthis.domElement = domElement;\n\t\t\tthis.domElement.style.touchAction = 'none'; // disable touch scroll\n\t\t\t// API\n\n\t\t\tthis.enabled = true;\n\t\t\tthis.screen = {\n\t\t\t\tleft: 0,\n\t\t\t\ttop: 0,\n\t\t\t\twidth: 0,\n\t\t\t\theight: 0\n\t\t\t};\n\t\t\tthis.rotateSpeed = 1.0;\n\t\t\tthis.zoomSpeed = 1.2;\n\t\t\tthis.panSpeed = 0.3;\n\t\t\tthis.noRotate = false;\n\t\t\tthis.noZoom = false;\n\t\t\tthis.noPan = false;\n\t\t\tthis.staticMoving = false;\n\t\t\tthis.dynamicDampingFactor = 0.2;\n\t\t\tthis.minDistance = 0;\n\t\t\tthis.maxDistance = Infinity;\n\t\t\tthis.keys = [ 'KeyA',\n\t\t\t\t/*A*/\n\t\t\t\t'KeyS',\n\t\t\t\t/*S*/\n\t\t\t\t'KeyD'\n\t\t\t\t/*D*/\n\t\t\t];\n\t\t\tthis.mouseButtons = {\n\t\t\t\tLEFT: THREE.MOUSE.ROTATE,\n\t\t\t\tMIDDLE: THREE.MOUSE.DOLLY,\n\t\t\t\tRIGHT: THREE.MOUSE.PAN\n\t\t\t}; // internals\n\n\t\t\tthis.target = new THREE.Vector3();\n\t\t\tconst EPS = 0.000001;\n\t\t\tconst lastPosition = new THREE.Vector3();\n\t\t\tlet lastZoom = 1;\n\t\t\tlet _state = STATE.NONE,\n\t\t\t\t_keyState = STATE.NONE,\n\t\t\t\t_touchZoomDistanceStart = 0,\n\t\t\t\t_touchZoomDistanceEnd = 0,\n\t\t\t\t_lastAngle = 0;\n\n\t\t\tconst _eye = new THREE.Vector3(),\n\t\t\t\t_movePrev = new THREE.Vector2(),\n\t\t\t\t_moveCurr = new THREE.Vector2(),\n\t\t\t\t_lastAxis = new THREE.Vector3(),\n\t\t\t\t_zoomStart = new THREE.Vector2(),\n\t\t\t\t_zoomEnd = new THREE.Vector2(),\n\t\t\t\t_panStart = new THREE.Vector2(),\n\t\t\t\t_panEnd = new THREE.Vector2(),\n\t\t\t\t_pointers = [],\n\t\t\t\t_pointerPositions = {}; // for reset\n\n\n\t\t\tthis.target0 = this.target.clone();\n\t\t\tthis.position0 = this.object.position.clone();\n\t\t\tthis.up0 = this.object.up.clone();\n\t\t\tthis.zoom0 = this.object.zoom; // methods\n\n\t\t\tthis.handleResize = function () {\n\n\t\t\t\tconst box = scope.domElement.getBoundingClientRect(); // adjustments come from similar code in the jquery offset() function\n\n\t\t\t\tconst d = scope.domElement.ownerDocument.documentElement;\n\t\t\t\tscope.screen.left = box.left + window.pageXOffset - d.clientLeft;\n\t\t\t\tscope.screen.top = box.top + window.pageYOffset - d.clientTop;\n\t\t\t\tscope.screen.width = box.width;\n\t\t\t\tscope.screen.height = box.height;\n\n\t\t\t};\n\n\t\t\tconst getMouseOnScreen = function () {\n\n\t\t\t\tconst vector = new THREE.Vector2();\n\t\t\t\treturn function getMouseOnScreen( pageX, pageY ) {\n\n\t\t\t\t\tvector.set( ( pageX - scope.screen.left ) / scope.screen.width, ( pageY - scope.screen.top ) / scope.screen.height );\n\t\t\t\t\treturn vector;\n\n\t\t\t\t};\n\n\t\t\t}();\n\n\t\t\tconst getMouseOnCircle = function () {\n\n\t\t\t\tconst vector = new THREE.Vector2();\n\t\t\t\treturn function getMouseOnCircle( pageX, pageY ) {\n\n\t\t\t\t\tvector.set( ( pageX - scope.screen.width * 0.5 - scope.screen.left ) / ( scope.screen.width * 0.5 ), ( scope.screen.height + 2 * ( scope.screen.top - pageY ) ) / scope.screen.width // screen.width intentional\n\t\t\t\t\t);\n\t\t\t\t\treturn vector;\n\n\t\t\t\t};\n\n\t\t\t}();\n\n\t\t\tthis.rotateCamera = function () {\n\n\t\t\t\tconst axis = new THREE.Vector3(),\n\t\t\t\t\tquaternion = new THREE.Quaternion(),\n\t\t\t\t\teyeDirection = new THREE.Vector3(),\n\t\t\t\t\tobjectUpDirection = new THREE.Vector3(),\n\t\t\t\t\tobjectSidewaysDirection = new THREE.Vector3(),\n\t\t\t\t\tmoveDirection = new THREE.Vector3();\n\t\t\t\treturn function rotateCamera() {\n\n\t\t\t\t\tmoveDirection.set( _moveCurr.x - _movePrev.x, _moveCurr.y - _movePrev.y, 0 );\n\t\t\t\t\tlet angle = moveDirection.length();\n\n\t\t\t\t\tif ( angle ) {\n\n\t\t\t\t\t\t_eye.copy( scope.object.position ).sub( scope.target );\n\n\t\t\t\t\t\teyeDirection.copy( _eye ).normalize();\n\t\t\t\t\t\tobjectUpDirection.copy( scope.object.up ).normalize();\n\t\t\t\t\t\tobjectSidewaysDirection.crossVectors( objectUpDirection, eyeDirection ).normalize();\n\t\t\t\t\t\tobjectUpDirection.setLength( _moveCurr.y - _movePrev.y );\n\t\t\t\t\t\tobjectSidewaysDirection.setLength( _moveCurr.x - _movePrev.x );\n\t\t\t\t\t\tmoveDirection.copy( objectUpDirection.add( objectSidewaysDirection ) );\n\t\t\t\t\t\taxis.crossVectors( moveDirection, _eye ).normalize();\n\t\t\t\t\t\tangle *= scope.rotateSpeed;\n\t\t\t\t\t\tquaternion.setFromAxisAngle( axis, angle );\n\n\t\t\t\t\t\t_eye.applyQuaternion( quaternion );\n\n\t\t\t\t\t\tscope.object.up.applyQuaternion( quaternion );\n\n\t\t\t\t\t\t_lastAxis.copy( axis );\n\n\t\t\t\t\t\t_lastAngle = angle;\n\n\t\t\t\t\t} else if ( ! scope.staticMoving && _lastAngle ) {\n\n\t\t\t\t\t\t_lastAngle *= Math.sqrt( 1.0 - scope.dynamicDampingFactor );\n\n\t\t\t\t\t\t_eye.copy( scope.object.position ).sub( scope.target );\n\n\t\t\t\t\t\tquaternion.setFromAxisAngle( _lastAxis, _lastAngle );\n\n\t\t\t\t\t\t_eye.applyQuaternion( quaternion );\n\n\t\t\t\t\t\tscope.object.up.applyQuaternion( quaternion );\n\n\t\t\t\t\t}\n\n\t\t\t\t\t_movePrev.copy( _moveCurr );\n\n\t\t\t\t};\n\n\t\t\t}();\n\n\t\t\tthis.zoomCamera = function () {\n\n\t\t\t\tlet factor;\n\n\t\t\t\tif ( _state === STATE.TOUCH_ZOOM_PAN ) {\n\n\t\t\t\t\tfactor = _touchZoomDistanceStart / _touchZoomDistanceEnd;\n\t\t\t\t\t_touchZoomDistanceStart = _touchZoomDistanceEnd;\n\n\t\t\t\t\tif ( scope.object.isPerspectiveCamera ) {\n\n\t\t\t\t\t\t_eye.multiplyScalar( factor );\n\n\t\t\t\t\t} else if ( scope.object.isOrthographicCamera ) {\n\n\t\t\t\t\t\tscope.object.zoom *= factor;\n\t\t\t\t\t\tscope.object.updateProjectionMatrix();\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tconsole.warn( 'THREE.TrackballControls: Unsupported camera type' );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tfactor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * scope.zoomSpeed;\n\n\t\t\t\t\tif ( factor !== 1.0 && factor > 0.0 ) {\n\n\t\t\t\t\t\tif ( scope.object.isPerspectiveCamera ) {\n\n\t\t\t\t\t\t\t_eye.multiplyScalar( factor );\n\n\t\t\t\t\t\t} else if ( scope.object.isOrthographicCamera ) {\n\n\t\t\t\t\t\t\tscope.object.zoom /= factor;\n\t\t\t\t\t\t\tscope.object.updateProjectionMatrix();\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\tconsole.warn( 'THREE.TrackballControls: Unsupported camera type' );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( scope.staticMoving ) {\n\n\t\t\t\t\t\t_zoomStart.copy( _zoomEnd );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t_zoomStart.y += ( _zoomEnd.y - _zoomStart.y ) * this.dynamicDampingFactor;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t\tthis.panCamera = function () {\n\n\t\t\t\tconst mouseChange = new THREE.Vector2(),\n\t\t\t\t\tobjectUp = new THREE.Vector3(),\n\t\t\t\t\tpan = new THREE.Vector3();\n\t\t\t\treturn function panCamera() {\n\n\t\t\t\t\tmouseChange.copy( _panEnd ).sub( _panStart );\n\n\t\t\t\t\tif ( mouseChange.lengthSq() ) {\n\n\t\t\t\t\t\tif ( scope.object.isOrthographicCamera ) {\n\n\t\t\t\t\t\t\tconst scale_x = ( scope.object.right - scope.object.left ) / scope.object.zoom / scope.domElement.clientWidth;\n\t\t\t\t\t\t\tconst scale_y = ( scope.object.top - scope.object.bottom ) / scope.object.zoom / scope.domElement.clientWidth;\n\t\t\t\t\t\t\tmouseChange.x *= scale_x;\n\t\t\t\t\t\t\tmouseChange.y *= scale_y;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tmouseChange.multiplyScalar( _eye.length() * scope.panSpeed );\n\t\t\t\t\t\tpan.copy( _eye ).cross( scope.object.up ).setLength( mouseChange.x );\n\t\t\t\t\t\tpan.add( objectUp.copy( scope.object.up ).setLength( mouseChange.y ) );\n\t\t\t\t\t\tscope.object.position.add( pan );\n\t\t\t\t\t\tscope.target.add( pan );\n\n\t\t\t\t\t\tif ( scope.staticMoving ) {\n\n\t\t\t\t\t\t\t_panStart.copy( _panEnd );\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t_panStart.add( mouseChange.subVectors( _panEnd, _panStart ).multiplyScalar( scope.dynamicDampingFactor ) );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t};\n\n\t\t\t}();\n\n\t\t\tthis.checkDistances = function () {\n\n\t\t\t\tif ( ! scope.noZoom || ! scope.noPan ) {\n\n\t\t\t\t\tif ( _eye.lengthSq() > scope.maxDistance * scope.maxDistance ) {\n\n\t\t\t\t\t\tscope.object.position.addVectors( scope.target, _eye.setLength( scope.maxDistance ) );\n\n\t\t\t\t\t\t_zoomStart.copy( _zoomEnd );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( _eye.lengthSq() < scope.minDistance * scope.minDistance ) {\n\n\t\t\t\t\t\tscope.object.position.addVectors( scope.target, _eye.setLength( scope.minDistance ) );\n\n\t\t\t\t\t\t_zoomStart.copy( _zoomEnd );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t\tthis.update = function () {\n\n\t\t\t\t_eye.subVectors( scope.object.position, scope.target );\n\n\t\t\t\tif ( ! scope.noRotate ) {\n\n\t\t\t\t\tscope.rotateCamera();\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! scope.noZoom ) {\n\n\t\t\t\t\tscope.zoomCamera();\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! scope.noPan ) {\n\n\t\t\t\t\tscope.panCamera();\n\n\t\t\t\t}\n\n\t\t\t\tscope.object.position.addVectors( scope.target, _eye );\n\n\t\t\t\tif ( scope.object.isPerspectiveCamera ) {\n\n\t\t\t\t\tscope.checkDistances();\n\t\t\t\t\tscope.object.lookAt( scope.target );\n\n\t\t\t\t\tif ( lastPosition.distanceToSquared( scope.object.position ) > EPS ) {\n\n\t\t\t\t\t\tscope.dispatchEvent( _changeEvent );\n\t\t\t\t\t\tlastPosition.copy( scope.object.position );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( scope.object.isOrthographicCamera ) {\n\n\t\t\t\t\tscope.object.lookAt( scope.target );\n\n\t\t\t\t\tif ( lastPosition.distanceToSquared( scope.object.position ) > EPS || lastZoom !== scope.object.zoom ) {\n\n\t\t\t\t\t\tscope.dispatchEvent( _changeEvent );\n\t\t\t\t\t\tlastPosition.copy( scope.object.position );\n\t\t\t\t\t\tlastZoom = scope.object.zoom;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( 'THREE.TrackballControls: Unsupported camera type' );\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t\tthis.reset = function () {\n\n\t\t\t\t_state = STATE.NONE;\n\t\t\t\t_keyState = STATE.NONE;\n\t\t\t\tscope.target.copy( scope.target0 );\n\t\t\t\tscope.object.position.copy( scope.position0 );\n\t\t\t\tscope.object.up.copy( scope.up0 );\n\t\t\t\tscope.object.zoom = scope.zoom0;\n\t\t\t\tscope.object.updateProjectionMatrix();\n\n\t\t\t\t_eye.subVectors( scope.object.position, scope.target );\n\n\t\t\t\tscope.object.lookAt( scope.target );\n\t\t\t\tscope.dispatchEvent( _changeEvent );\n\t\t\t\tlastPosition.copy( scope.object.position );\n\t\t\t\tlastZoom = scope.object.zoom;\n\n\t\t\t}; // listeners\n\n\n\t\t\tfunction onPointerDown( event ) {\n\n\t\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\t\tif ( _pointers.length === 0 ) {\n\n\t\t\t\t\tscope.domElement.setPointerCapture( event.pointerId );\n\t\t\t\t\tscope.domElement.addEventListener( 'pointermove', onPointerMove );\n\t\t\t\t\tscope.domElement.addEventListener( 'pointerup', onPointerUp );\n\n\t\t\t\t} //\n\n\n\t\t\t\taddPointer( event );\n\n\t\t\t\tif ( event.pointerType === 'touch' ) {\n\n\t\t\t\t\tonTouchStart( event );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tonMouseDown( event );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction onPointerMove( event ) {\n\n\t\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\t\tif ( event.pointerType === 'touch' ) {\n\n\t\t\t\t\tonTouchMove( event );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tonMouseMove( event );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction onPointerUp( event ) {\n\n\t\t\t\tif ( scope.enabled === false ) return;\n\n\t\t\t\tif ( event.pointerType === 'touch' ) {\n\n\t\t\t\t\tonTouchEnd( event );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tonMouseUp();\n\n\t\t\t\t} //\n\n\n\t\t\t\tremovePointer( event );\n\n\t\t\t\tif ( _pointers.length === 0 ) {\n\n\t\t\t\t\tscope.domElement.releasePointerCapture( event.pointerId );\n\t\t\t\t\tscope.domElement.removeEventListener( 'pointermove', onPointerMove );\n\t\t\t\t\tscope.domElement.removeEventListener( 'pointerup', onPointerUp );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction onPointerCancel( event ) {\n\n\t\t\t\tremovePointer( event );\n\n\t\t\t}\n\n\t\t\tfunction keydown( event ) {\n\n\t\t\t\tif ( scope.enabled === false ) return;\n\t\t\t\twindow.removeEventListener( 'keydown', keydown );\n\n\t\t\t\tif ( _keyState !== STATE.NONE ) {\n\n\t\t\t\t\treturn;\n\n\t\t\t\t} else if ( event.code === scope.keys[ STATE.ROTATE ] && ! scope.noRotate ) {\n\n\t\t\t\t\t_keyState = STATE.ROTATE;\n\n\t\t\t\t} else if ( event.code === scope.keys[ STATE.ZOOM ] && ! scope.noZoom ) {\n\n\t\t\t\t\t_keyState = STATE.ZOOM;\n\n\t\t\t\t} else if ( event.code === scope.keys[ STATE.PAN ] && ! scope.noPan ) {\n\n\t\t\t\t\t_keyState = STATE.PAN;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction keyup() {\n\n\t\t\t\tif ( scope.enabled === false ) return;\n\t\t\t\t_keyState = STATE.NONE;\n\t\t\t\twindow.addEventListener( 'keydown', keydown );\n\n\t\t\t}\n\n\t\t\tfunction onMouseDown( event ) {\n\n\t\t\t\tif ( _state === STATE.NONE ) {\n\n\t\t\t\t\tswitch ( event.button ) {\n\n\t\t\t\t\t\tcase scope.mouseButtons.LEFT:\n\t\t\t\t\t\t\t_state = STATE.ROTATE;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase scope.mouseButtons.MIDDLE:\n\t\t\t\t\t\t\t_state = STATE.ZOOM;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase scope.mouseButtons.RIGHT:\n\t\t\t\t\t\t\t_state = STATE.PAN;\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t_state = STATE.NONE;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tconst state = _keyState !== STATE.NONE ? _keyState : _state;\n\n\t\t\t\tif ( state === STATE.ROTATE && ! scope.noRotate ) {\n\n\t\t\t\t\t_moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );\n\n\t\t\t\t\t_movePrev.copy( _moveCurr );\n\n\t\t\t\t} else if ( state === STATE.ZOOM && ! scope.noZoom ) {\n\n\t\t\t\t\t_zoomStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );\n\n\t\t\t\t\t_zoomEnd.copy( _zoomStart );\n\n\t\t\t\t} else if ( state === STATE.PAN && ! scope.noPan ) {\n\n\t\t\t\t\t_panStart.copy( getMouseOnScreen( event.pageX, event.pageY ) );\n\n\t\t\t\t\t_panEnd.copy( _panStart );\n\n\t\t\t\t}\n\n\t\t\t\tscope.dispatchEvent( _startEvent );\n\n\t\t\t}\n\n\t\t\tfunction onMouseMove( event ) {\n\n\t\t\t\tconst state = _keyState !== STATE.NONE ? _keyState : _state;\n\n\t\t\t\tif ( state === STATE.ROTATE && ! scope.noRotate ) {\n\n\t\t\t\t\t_movePrev.copy( _moveCurr );\n\n\t\t\t\t\t_moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );\n\n\t\t\t\t} else if ( state === STATE.ZOOM && ! scope.noZoom ) {\n\n\t\t\t\t\t_zoomEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) );\n\n\t\t\t\t} else if ( state === STATE.PAN && ! scope.noPan ) {\n\n\t\t\t\t\t_panEnd.copy( getMouseOnScreen( event.pageX, event.pageY ) );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction onMouseUp() {\n\n\t\t\t\t_state = STATE.NONE;\n\t\t\t\tscope.dispatchEvent( _endEvent );\n\n\t\t\t}\n\n\t\t\tfunction onMouseWheel( event ) {\n\n\t\t\t\tif ( scope.enabled === false ) return;\n\t\t\t\tif ( scope.noZoom === true ) return;\n\t\t\t\tevent.preventDefault();\n\n\t\t\t\tswitch ( event.deltaMode ) {\n\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\t// Zoom in pages\n\t\t\t\t\t\t_zoomStart.y -= event.deltaY * 0.025;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\t// Zoom in lines\n\t\t\t\t\t\t_zoomStart.y -= event.deltaY * 0.01;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t// undefined, 0, assume pixels\n\t\t\t\t\t\t_zoomStart.y -= event.deltaY * 0.00025;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tscope.dispatchEvent( _startEvent );\n\t\t\t\tscope.dispatchEvent( _endEvent );\n\n\t\t\t}\n\n\t\t\tfunction onTouchStart( event ) {\n\n\t\t\t\ttrackPointer( event );\n\n\t\t\t\tswitch ( _pointers.length ) {\n\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\t_state = STATE.TOUCH_ROTATE;\n\n\t\t\t\t\t\t_moveCurr.copy( getMouseOnCircle( _pointers[ 0 ].pageX, _pointers[ 0 ].pageY ) );\n\n\t\t\t\t\t\t_movePrev.copy( _moveCurr );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t// 2 or more\n\t\t\t\t\t\t_state = STATE.TOUCH_ZOOM_PAN;\n\t\t\t\t\t\tconst dx = _pointers[ 0 ].pageX - _pointers[ 1 ].pageX;\n\t\t\t\t\t\tconst dy = _pointers[ 0 ].pageY - _pointers[ 1 ].pageY;\n\t\t\t\t\t\t_touchZoomDistanceEnd = _touchZoomDistanceStart = Math.sqrt( dx * dx + dy * dy );\n\t\t\t\t\t\tconst x = ( _pointers[ 0 ].pageX + _pointers[ 1 ].pageX ) / 2;\n\t\t\t\t\t\tconst y = ( _pointers[ 0 ].pageY + _pointers[ 1 ].pageY ) / 2;\n\n\t\t\t\t\t\t_panStart.copy( getMouseOnScreen( x, y ) );\n\n\t\t\t\t\t\t_panEnd.copy( _panStart );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tscope.dispatchEvent( _startEvent );\n\n\t\t\t}\n\n\t\t\tfunction onTouchMove( event ) {\n\n\t\t\t\ttrackPointer( event );\n\n\t\t\t\tswitch ( _pointers.length ) {\n\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\t_movePrev.copy( _moveCurr );\n\n\t\t\t\t\t\t_moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t// 2 or more\n\t\t\t\t\t\tconst position = getSecondPointerPosition( event );\n\t\t\t\t\t\tconst dx = event.pageX - position.x;\n\t\t\t\t\t\tconst dy = event.pageY - position.y;\n\t\t\t\t\t\t_touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy );\n\t\t\t\t\t\tconst x = ( event.pageX + position.x ) / 2;\n\t\t\t\t\t\tconst y = ( event.pageY + position.y ) / 2;\n\n\t\t\t\t\t\t_panEnd.copy( getMouseOnScreen( x, y ) );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction onTouchEnd( event ) {\n\n\t\t\t\tswitch ( _pointers.length ) {\n\n\t\t\t\t\tcase 0:\n\t\t\t\t\t\t_state = STATE.NONE;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\t_state = STATE.TOUCH_ROTATE;\n\n\t\t\t\t\t\t_moveCurr.copy( getMouseOnCircle( event.pageX, event.pageY ) );\n\n\t\t\t\t\t\t_movePrev.copy( _moveCurr );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\t_state = STATE.TOUCH_ZOOM_PAN;\n\n\t\t\t\t\t\t_moveCurr.copy( getMouseOnCircle( event.pageX - _movePrev.pageX, event.pageY - _movePrev.pageY ) );\n\n\t\t\t\t\t\t_movePrev.copy( _moveCurr );\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tscope.dispatchEvent( _endEvent );\n\n\t\t\t}\n\n\t\t\tfunction contextmenu( event ) {\n\n\t\t\t\tif ( scope.enabled === false ) return;\n\t\t\t\tevent.preventDefault();\n\n\t\t\t}\n\n\t\t\tfunction addPointer( event ) {\n\n\t\t\t\t_pointers.push( event );\n\n\t\t\t}\n\n\t\t\tfunction removePointer( event ) {\n\n\t\t\t\tdelete _pointerPositions[ event.pointerId ];\n\n\t\t\t\tfor ( let i = 0; i < _pointers.length; i ++ ) {\n\n\t\t\t\t\tif ( _pointers[ i ].pointerId == event.pointerId ) {\n\n\t\t\t\t\t\t_pointers.splice( i, 1 );\n\n\t\t\t\t\t\treturn;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tfunction trackPointer( event ) {\n\n\t\t\t\tlet position = _pointerPositions[ event.pointerId ];\n\n\t\t\t\tif ( position === undefined ) {\n\n\t\t\t\t\tposition = new THREE.Vector2();\n\t\t\t\t\t_pointerPositions[ event.pointerId ] = position;\n\n\t\t\t\t}\n\n\t\t\t\tposition.set( event.pageX, event.pageY );\n\n\t\t\t}\n\n\t\t\tfunction getSecondPointerPosition( event ) {\n\n\t\t\t\tconst pointer = event.pointerId === _pointers[ 0 ].pointerId ? _pointers[ 1 ] : _pointers[ 0 ];\n\t\t\t\treturn _pointerPositions[ pointer.pointerId ];\n\n\t\t\t}\n\n\t\t\tthis.dispose = function () {\n\n\t\t\t\tscope.domElement.removeEventListener( 'contextmenu', contextmenu );\n\t\t\t\tscope.domElement.removeEventListener( 'pointerdown', onPointerDown );\n\t\t\t\tscope.domElement.removeEventListener( 'pointercancel', onPointerCancel );\n\t\t\t\tscope.domElement.removeEventListener( 'wheel', onMouseWheel );\n\t\t\t\tscope.domElement.removeEventListener( 'pointermove', onPointerMove );\n\t\t\t\tscope.domElement.removeEventListener( 'pointerup', onPointerUp );\n\t\t\t\twindow.removeEventListener( 'keydown', keydown );\n\t\t\t\twindow.removeEventListener( 'keyup', keyup );\n\n\t\t\t};\n\n\t\t\tthis.domElement.addEventListener( 'contextmenu', contextmenu );\n\t\t\tthis.domElement.addEventListener( 'pointerdown', onPointerDown );\n\t\t\tthis.domElement.addEventListener( 'pointercancel', onPointerCancel );\n\t\t\tthis.domElement.addEventListener( 'wheel', onMouseWheel, {\n\t\t\t\tpassive: false\n\t\t\t} );\n\t\t\twindow.addEventListener( 'keydown', keydown );\n\t\t\twindow.addEventListener( 'keyup', keyup );\n\t\t\tthis.handleResize(); // force an update at start\n\n\t\t\tthis.update();\n\n\t\t}\n\n\t}\n\n\tTHREE.TrackballControls = TrackballControls;\n\n} )();\n"
  },
  {
    "path": "public/three/simplex-noise.js",
    "content": "/*\n * A fast javascript implementation of simplex noise by Jonas Wagner\n\nBased on a speed-improved simplex noise algorithm for 2D, 3D and 4D in Java.\nWhich is based on example code by Stefan Gustavson (stegu@itn.liu.se).\nWith Optimisations by Peter Eastman (peastman@drizzle.stanford.edu).\nBetter rank ordering method by Stefan Gustavson in 2012.\n\n Copyright (c) 2018 Jonas Wagner\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n */\n(function() {\n  'use strict';\n\n  var F2 = 0.5 * (Math.sqrt(3.0) - 1.0);\n  var G2 = (3.0 - Math.sqrt(3.0)) / 6.0;\n  var F3 = 1.0 / 3.0;\n  var G3 = 1.0 / 6.0;\n  var F4 = (Math.sqrt(5.0) - 1.0) / 4.0;\n  var G4 = (5.0 - Math.sqrt(5.0)) / 20.0;\n\n  function SimplexNoise(randomOrSeed) {\n    var random;\n    if (typeof randomOrSeed == 'function') {\n      random = randomOrSeed;\n    }\n    else if (randomOrSeed) {\n      random = alea(randomOrSeed);\n    } else {\n      random = Math.random;\n    }\n    this.p = buildPermutationTable(random);\n    this.perm = new Uint8Array(512);\n    this.permMod12 = new Uint8Array(512);\n    for (var i = 0; i < 512; i++) {\n      this.perm[i] = this.p[i & 255];\n      this.permMod12[i] = this.perm[i] % 12;\n    }\n\n  }\n  SimplexNoise.prototype = {\n    grad3: new Float32Array([1, 1, 0,\n      -1, 1, 0,\n      1, -1, 0,\n\n      -1, -1, 0,\n      1, 0, 1,\n      -1, 0, 1,\n\n      1, 0, -1,\n      -1, 0, -1,\n      0, 1, 1,\n\n      0, -1, 1,\n      0, 1, -1,\n      0, -1, -1]),\n    grad4: new Float32Array([0, 1, 1, 1, 0, 1, 1, -1, 0, 1, -1, 1, 0, 1, -1, -1,\n      0, -1, 1, 1, 0, -1, 1, -1, 0, -1, -1, 1, 0, -1, -1, -1,\n      1, 0, 1, 1, 1, 0, 1, -1, 1, 0, -1, 1, 1, 0, -1, -1,\n      -1, 0, 1, 1, -1, 0, 1, -1, -1, 0, -1, 1, -1, 0, -1, -1,\n      1, 1, 0, 1, 1, 1, 0, -1, 1, -1, 0, 1, 1, -1, 0, -1,\n      -1, 1, 0, 1, -1, 1, 0, -1, -1, -1, 0, 1, -1, -1, 0, -1,\n      1, 1, 1, 0, 1, 1, -1, 0, 1, -1, 1, 0, 1, -1, -1, 0,\n      -1, 1, 1, 0, -1, 1, -1, 0, -1, -1, 1, 0, -1, -1, -1, 0]),\n    noise2D: function(xin, yin) {\n      var permMod12 = this.permMod12;\n      var perm = this.perm;\n      var grad3 = this.grad3;\n      var n0 = 0; // Noise contributions from the three corners\n      var n1 = 0;\n      var n2 = 0;\n      // Skew the input space to determine which simplex cell we're in\n      var s = (xin + yin) * F2; // Hairy factor for 2D\n      var i = Math.floor(xin + s);\n      var j = Math.floor(yin + s);\n      var t = (i + j) * G2;\n      var X0 = i - t; // Unskew the cell origin back to (x,y) space\n      var Y0 = j - t;\n      var x0 = xin - X0; // The x,y distances from the cell origin\n      var y0 = yin - Y0;\n      // For the 2D case, the simplex shape is an equilateral triangle.\n      // Determine which simplex we are in.\n      var i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords\n      if (x0 > y0) {\n        i1 = 1;\n        j1 = 0;\n      } // lower triangle, XY order: (0,0)->(1,0)->(1,1)\n      else {\n        i1 = 0;\n        j1 = 1;\n      } // upper triangle, YX order: (0,0)->(0,1)->(1,1)\n      // A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and\n      // a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where\n      // c = (3-sqrt(3))/6\n      var x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords\n      var y1 = y0 - j1 + G2;\n      var x2 = x0 - 1.0 + 2.0 * G2; // Offsets for last corner in (x,y) unskewed coords\n      var y2 = y0 - 1.0 + 2.0 * G2;\n      // Work out the hashed gradient indices of the three simplex corners\n      var ii = i & 255;\n      var jj = j & 255;\n      // Calculate the contribution from the three corners\n      var t0 = 0.5 - x0 * x0 - y0 * y0;\n      if (t0 >= 0) {\n        var gi0 = permMod12[ii + perm[jj]] * 3;\n        t0 *= t0;\n        n0 = t0 * t0 * (grad3[gi0] * x0 + grad3[gi0 + 1] * y0); // (x,y) of grad3 used for 2D gradient\n      }\n      var t1 = 0.5 - x1 * x1 - y1 * y1;\n      if (t1 >= 0) {\n        var gi1 = permMod12[ii + i1 + perm[jj + j1]] * 3;\n        t1 *= t1;\n        n1 = t1 * t1 * (grad3[gi1] * x1 + grad3[gi1 + 1] * y1);\n      }\n      var t2 = 0.5 - x2 * x2 - y2 * y2;\n      if (t2 >= 0) {\n        var gi2 = permMod12[ii + 1 + perm[jj + 1]] * 3;\n        t2 *= t2;\n        n2 = t2 * t2 * (grad3[gi2] * x2 + grad3[gi2 + 1] * y2);\n      }\n      // Add contributions from each corner to get the final noise value.\n      // The result is scaled to return values in the interval [-1,1].\n      return 70.0 * (n0 + n1 + n2);\n    },\n    // 3D simplex noise\n    noise3D: function(xin, yin, zin) {\n      var permMod12 = this.permMod12;\n      var perm = this.perm;\n      var grad3 = this.grad3;\n      var n0, n1, n2, n3; // Noise contributions from the four corners\n      // Skew the input space to determine which simplex cell we're in\n      var s = (xin + yin + zin) * F3; // Very nice and simple skew factor for 3D\n      var i = Math.floor(xin + s);\n      var j = Math.floor(yin + s);\n      var k = Math.floor(zin + s);\n      var t = (i + j + k) * G3;\n      var X0 = i - t; // Unskew the cell origin back to (x,y,z) space\n      var Y0 = j - t;\n      var Z0 = k - t;\n      var x0 = xin - X0; // The x,y,z distances from the cell origin\n      var y0 = yin - Y0;\n      var z0 = zin - Z0;\n      // For the 3D case, the simplex shape is a slightly irregular tetrahedron.\n      // Determine which simplex we are in.\n      var i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords\n      var i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords\n      if (x0 >= y0) {\n        if (y0 >= z0) {\n          i1 = 1;\n          j1 = 0;\n          k1 = 0;\n          i2 = 1;\n          j2 = 1;\n          k2 = 0;\n        } // X Y Z order\n        else if (x0 >= z0) {\n          i1 = 1;\n          j1 = 0;\n          k1 = 0;\n          i2 = 1;\n          j2 = 0;\n          k2 = 1;\n        } // X Z Y order\n        else {\n          i1 = 0;\n          j1 = 0;\n          k1 = 1;\n          i2 = 1;\n          j2 = 0;\n          k2 = 1;\n        } // Z X Y order\n      }\n      else { // x0<y0\n        if (y0 < z0) {\n          i1 = 0;\n          j1 = 0;\n          k1 = 1;\n          i2 = 0;\n          j2 = 1;\n          k2 = 1;\n        } // Z Y X order\n        else if (x0 < z0) {\n          i1 = 0;\n          j1 = 1;\n          k1 = 0;\n          i2 = 0;\n          j2 = 1;\n          k2 = 1;\n        } // Y Z X order\n        else {\n          i1 = 0;\n          j1 = 1;\n          k1 = 0;\n          i2 = 1;\n          j2 = 1;\n          k2 = 0;\n        } // Y X Z order\n      }\n      // A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z),\n      // a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and\n      // a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where\n      // c = 1/6.\n      var x1 = x0 - i1 + G3; // Offsets for second corner in (x,y,z) coords\n      var y1 = y0 - j1 + G3;\n      var z1 = z0 - k1 + G3;\n      var x2 = x0 - i2 + 2.0 * G3; // Offsets for third corner in (x,y,z) coords\n      var y2 = y0 - j2 + 2.0 * G3;\n      var z2 = z0 - k2 + 2.0 * G3;\n      var x3 = x0 - 1.0 + 3.0 * G3; // Offsets for last corner in (x,y,z) coords\n      var y3 = y0 - 1.0 + 3.0 * G3;\n      var z3 = z0 - 1.0 + 3.0 * G3;\n      // Work out the hashed gradient indices of the four simplex corners\n      var ii = i & 255;\n      var jj = j & 255;\n      var kk = k & 255;\n      // Calculate the contribution from the four corners\n      var t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0;\n      if (t0 < 0) n0 = 0.0;\n      else {\n        var gi0 = permMod12[ii + perm[jj + perm[kk]]] * 3;\n        t0 *= t0;\n        n0 = t0 * t0 * (grad3[gi0] * x0 + grad3[gi0 + 1] * y0 + grad3[gi0 + 2] * z0);\n      }\n      var t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1;\n      if (t1 < 0) n1 = 0.0;\n      else {\n        var gi1 = permMod12[ii + i1 + perm[jj + j1 + perm[kk + k1]]] * 3;\n        t1 *= t1;\n        n1 = t1 * t1 * (grad3[gi1] * x1 + grad3[gi1 + 1] * y1 + grad3[gi1 + 2] * z1);\n      }\n      var t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2;\n      if (t2 < 0) n2 = 0.0;\n      else {\n        var gi2 = permMod12[ii + i2 + perm[jj + j2 + perm[kk + k2]]] * 3;\n        t2 *= t2;\n        n2 = t2 * t2 * (grad3[gi2] * x2 + grad3[gi2 + 1] * y2 + grad3[gi2 + 2] * z2);\n      }\n      var t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3;\n      if (t3 < 0) n3 = 0.0;\n      else {\n        var gi3 = permMod12[ii + 1 + perm[jj + 1 + perm[kk + 1]]] * 3;\n        t3 *= t3;\n        n3 = t3 * t3 * (grad3[gi3] * x3 + grad3[gi3 + 1] * y3 + grad3[gi3 + 2] * z3);\n      }\n      // Add contributions from each corner to get the final noise value.\n      // The result is scaled to stay just inside [-1,1]\n      return 32.0 * (n0 + n1 + n2 + n3);\n    },\n    // 4D simplex noise, better simplex rank ordering method 2012-03-09\n    noise4D: function(x, y, z, w) {\n      var perm = this.perm;\n      var grad4 = this.grad4;\n\n      var n0, n1, n2, n3, n4; // Noise contributions from the five corners\n      // Skew the (x,y,z,w) space to determine which cell of 24 simplices we're in\n      var s = (x + y + z + w) * F4; // Factor for 4D skewing\n      var i = Math.floor(x + s);\n      var j = Math.floor(y + s);\n      var k = Math.floor(z + s);\n      var l = Math.floor(w + s);\n      var t = (i + j + k + l) * G4; // Factor for 4D unskewing\n      var X0 = i - t; // Unskew the cell origin back to (x,y,z,w) space\n      var Y0 = j - t;\n      var Z0 = k - t;\n      var W0 = l - t;\n      var x0 = x - X0; // The x,y,z,w distances from the cell origin\n      var y0 = y - Y0;\n      var z0 = z - Z0;\n      var w0 = w - W0;\n      // For the 4D case, the simplex is a 4D shape I won't even try to describe.\n      // To find out which of the 24 possible simplices we're in, we need to\n      // determine the magnitude ordering of x0, y0, z0 and w0.\n      // Six pair-wise comparisons are performed between each possible pair\n      // of the four coordinates, and the results are used to rank the numbers.\n      var rankx = 0;\n      var ranky = 0;\n      var rankz = 0;\n      var rankw = 0;\n      if (x0 > y0) rankx++;\n      else ranky++;\n      if (x0 > z0) rankx++;\n      else rankz++;\n      if (x0 > w0) rankx++;\n      else rankw++;\n      if (y0 > z0) ranky++;\n      else rankz++;\n      if (y0 > w0) ranky++;\n      else rankw++;\n      if (z0 > w0) rankz++;\n      else rankw++;\n      var i1, j1, k1, l1; // The integer offsets for the second simplex corner\n      var i2, j2, k2, l2; // The integer offsets for the third simplex corner\n      var i3, j3, k3, l3; // The integer offsets for the fourth simplex corner\n      // simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order.\n      // Many values of c will never occur, since e.g. x>y>z>w makes x<z, y<w and x<w\n      // impossible. Only the 24 indices which have non-zero entries make any sense.\n      // We use a thresholding to set the coordinates in turn from the largest magnitude.\n      // Rank 3 denotes the largest coordinate.\n      i1 = rankx >= 3 ? 1 : 0;\n      j1 = ranky >= 3 ? 1 : 0;\n      k1 = rankz >= 3 ? 1 : 0;\n      l1 = rankw >= 3 ? 1 : 0;\n      // Rank 2 denotes the second largest coordinate.\n      i2 = rankx >= 2 ? 1 : 0;\n      j2 = ranky >= 2 ? 1 : 0;\n      k2 = rankz >= 2 ? 1 : 0;\n      l2 = rankw >= 2 ? 1 : 0;\n      // Rank 1 denotes the second smallest coordinate.\n      i3 = rankx >= 1 ? 1 : 0;\n      j3 = ranky >= 1 ? 1 : 0;\n      k3 = rankz >= 1 ? 1 : 0;\n      l3 = rankw >= 1 ? 1 : 0;\n      // The fifth corner has all coordinate offsets = 1, so no need to compute that.\n      var x1 = x0 - i1 + G4; // Offsets for second corner in (x,y,z,w) coords\n      var y1 = y0 - j1 + G4;\n      var z1 = z0 - k1 + G4;\n      var w1 = w0 - l1 + G4;\n      var x2 = x0 - i2 + 2.0 * G4; // Offsets for third corner in (x,y,z,w) coords\n      var y2 = y0 - j2 + 2.0 * G4;\n      var z2 = z0 - k2 + 2.0 * G4;\n      var w2 = w0 - l2 + 2.0 * G4;\n      var x3 = x0 - i3 + 3.0 * G4; // Offsets for fourth corner in (x,y,z,w) coords\n      var y3 = y0 - j3 + 3.0 * G4;\n      var z3 = z0 - k3 + 3.0 * G4;\n      var w3 = w0 - l3 + 3.0 * G4;\n      var x4 = x0 - 1.0 + 4.0 * G4; // Offsets for last corner in (x,y,z,w) coords\n      var y4 = y0 - 1.0 + 4.0 * G4;\n      var z4 = z0 - 1.0 + 4.0 * G4;\n      var w4 = w0 - 1.0 + 4.0 * G4;\n      // Work out the hashed gradient indices of the five simplex corners\n      var ii = i & 255;\n      var jj = j & 255;\n      var kk = k & 255;\n      var ll = l & 255;\n      // Calculate the contribution from the five corners\n      var t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0;\n      if (t0 < 0) n0 = 0.0;\n      else {\n        var gi0 = (perm[ii + perm[jj + perm[kk + perm[ll]]]] % 32) * 4;\n        t0 *= t0;\n        n0 = t0 * t0 * (grad4[gi0] * x0 + grad4[gi0 + 1] * y0 + grad4[gi0 + 2] * z0 + grad4[gi0 + 3] * w0);\n      }\n      var t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1;\n      if (t1 < 0) n1 = 0.0;\n      else {\n        var gi1 = (perm[ii + i1 + perm[jj + j1 + perm[kk + k1 + perm[ll + l1]]]] % 32) * 4;\n        t1 *= t1;\n        n1 = t1 * t1 * (grad4[gi1] * x1 + grad4[gi1 + 1] * y1 + grad4[gi1 + 2] * z1 + grad4[gi1 + 3] * w1);\n      }\n      var t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2;\n      if (t2 < 0) n2 = 0.0;\n      else {\n        var gi2 = (perm[ii + i2 + perm[jj + j2 + perm[kk + k2 + perm[ll + l2]]]] % 32) * 4;\n        t2 *= t2;\n        n2 = t2 * t2 * (grad4[gi2] * x2 + grad4[gi2 + 1] * y2 + grad4[gi2 + 2] * z2 + grad4[gi2 + 3] * w2);\n      }\n      var t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3;\n      if (t3 < 0) n3 = 0.0;\n      else {\n        var gi3 = (perm[ii + i3 + perm[jj + j3 + perm[kk + k3 + perm[ll + l3]]]] % 32) * 4;\n        t3 *= t3;\n        n3 = t3 * t3 * (grad4[gi3] * x3 + grad4[gi3 + 1] * y3 + grad4[gi3 + 2] * z3 + grad4[gi3 + 3] * w3);\n      }\n      var t4 = 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4;\n      if (t4 < 0) n4 = 0.0;\n      else {\n        var gi4 = (perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] % 32) * 4;\n        t4 *= t4;\n        n4 = t4 * t4 * (grad4[gi4] * x4 + grad4[gi4 + 1] * y4 + grad4[gi4 + 2] * z4 + grad4[gi4 + 3] * w4);\n      }\n      // Sum up and scale the result to cover the range [-1,1]\n      return 27.0 * (n0 + n1 + n2 + n3 + n4);\n    }\n  };\n\n  function buildPermutationTable(random) {\n    var i;\n    var p = new Uint8Array(256);\n    for (i = 0; i < 256; i++) {\n      p[i] = i;\n    }\n    for (i = 0; i < 255; i++) {\n      var r = i + ~~(random() * (256 - i));\n      var aux = p[i];\n      p[i] = p[r];\n      p[r] = aux;\n    }\n    return p;\n  }\n  SimplexNoise._buildPermutationTable = buildPermutationTable;\n\n  /*\n  The ALEA PRNG and masher code used by simplex-noise.js\n  is based on code by Johannes Baagøe, modified by Jonas Wagner.\n  See alea.md for the full license.\n  */\n  function alea() {\n    var s0 = 0;\n    var s1 = 0;\n    var s2 = 0;\n    var c = 1;\n\n    var mash = masher();\n    s0 = mash(' ');\n    s1 = mash(' ');\n    s2 = mash(' ');\n\n    for (var i = 0; i < arguments.length; i++) {\n      s0 -= mash(arguments[i]);\n      if (s0 < 0) {\n        s0 += 1;\n      }\n      s1 -= mash(arguments[i]);\n      if (s1 < 0) {\n        s1 += 1;\n      }\n      s2 -= mash(arguments[i]);\n      if (s2 < 0) {\n        s2 += 1;\n      }\n    }\n    mash = null;\n    return function() {\n      var t = 2091639 * s0 + c * 2.3283064365386963e-10; // 2^-32\n      s0 = s1;\n      s1 = s2;\n      return s2 = t - (c = t | 0);\n    };\n  }\n  function masher() {\n    var n = 0xefc8249d;\n    return function(data) {\n      data = data.toString();\n      for (var i = 0; i < data.length; i++) {\n        n += data.charCodeAt(i);\n        var h = 0.02519603282416938 * n;\n        n = h >>> 0;\n        h -= n;\n        h *= n;\n        n = h >>> 0;\n        h -= n;\n        n += h * 0x100000000; // 2^32\n      }\n      return (n >>> 0) * 2.3283064365386963e-10; // 2^-32\n    };\n  }\n\n  // amd\n  if (typeof define !== 'undefined' && define.amd) define(function() {return SimplexNoise;});\n  // common js\n  if (typeof exports !== 'undefined') exports.SimplexNoise = SimplexNoise;\n  // browser\n  else if (typeof window !== 'undefined') window.SimplexNoise = SimplexNoise;\n  // nodejs\n  if (typeof module !== 'undefined') {\n    module.exports = SimplexNoise;\n  }\n\n})();\n"
  },
  {
    "path": "python_backend/app/api/routers.py",
    "content": "# -*- coding: utf-8 -*-\nfrom fastapi import APIRouter\nfrom app.api.v1.interpreter import router as interpreter_router\nfrom app.api.v1.ollama import router as ollama_router\nfrom app.core.conf import settings\n\nv1 = APIRouter(prefix=settings.API_V1_STR)\nv1.include_router(interpreter_router, prefix='/interpreter', tags=['Interpreter'])\nv1.include_router(ollama_router, prefix='/ollama', tags=['ollama'])\n"
  },
  {
    "path": "python_backend/app/api/v1/interpreter.py",
    "content": "# -*- coding: utf-8 -*-\n\nfrom fastapi import APIRouter\nfrom fastapi.responses import StreamingResponse\nfrom app.common.open_interpreter import open_interpreter\nfrom app.common.response import ResponseModel\nfrom app.schemas.interpreter import InterpreterMessage\n\nrouter = APIRouter()\n\n\n@router.post('/chat', summary='ChatGPT')\ndef interpreter_chat(message: InterpreterMessage) -> ResponseModel:\n    result = open_interpreter.chat(message)\n    return ResponseModel(data=result)\n\n\n@router.post('/chat-stream', summary='ChatGPT 流式响应')\ndef interpreter_chat_stream(message: InterpreterMessage) -> StreamingResponse:\n    def event_stream():\n        for result in open_interpreter.chat(message, stream=True):\n            yield f'{result}\\n\\n'\n\n    return StreamingResponse(event_stream(), media_type='text/event-stream')\n\n\n@router.get('/history', summary='历史消息')\ndef interpreter_history() -> ResponseModel:\n    return ResponseModel(data=open_interpreter.messages)\n\n\n@router.post('/reset', summary='重置上下文')\ndef interpreter_reset() -> ResponseModel:\n    open_interpreter.reset()\n    return ResponseModel()\n"
  },
  {
    "path": "python_backend/app/api/v1/ollama.py",
    "content": "# -*- coding: utf-8 -*-\nfrom typing import Annotated\nimport msgspec.json\nfrom fastapi import APIRouter, Query\nfrom ollama import AsyncClient\nfrom starlette.responses import StreamingResponse\nfrom app.common.response import ResponseModel\nfrom app.core.conf import settings\nfrom app.schemas.ollama import OllamaMessages\n\nrouter = APIRouter()\n\n\n@router.post('/chat', summary='ChatGPT')\nasync def ollama_chat(messages: OllamaMessages) -> ResponseModel:\n    result = await AsyncClient().chat(\n        model=settings.OLLAMA_MODEL, messages=[{'role': messages.role, 'content': messages.content}]\n    )\n    return ResponseModel(data=result)\n\n\n@router.post('/chat-stream', summary='ChatGPT 流式响应')\nasync def ollama_chat_stream(messages: OllamaMessages):\n    async def event_stream():\n        async for result in await AsyncClient().chat(\n            model=settings.OLLAMA_MODEL,\n            messages=[{'role': messages.role, 'content': messages.content}],\n            stream=True,\n        ):\n            text_line = msgspec.json.encode(result)\n            yield f'{text_line}\\n\\n'\n\n    return StreamingResponse(event_stream(), media_type='text/event-stream')\n\n\n@router.get('/list', summary='本地离线模型列表')\nasync def ollama_list() -> ResponseModel:\n    data = await AsyncClient().list()\n    return ResponseModel(data=data)\n\n\n@router.post('/pull', summary='拉取离线模型')\nasync def ollama_pull(model: Annotated[str, Query()]) -> ResponseModel:\n    data = await AsyncClient().pull(model)\n    return ResponseModel(data=data)\n\n\n@router.delete('/delete', summary='删除本地离线模型')\nasync def ollama_delete(model: Annotated[str, Query()]) -> ResponseModel:\n    data = await AsyncClient().delete(model)\n    return ResponseModel(data=data)\n"
  },
  {
    "path": "python_backend/app/common/log.py",
    "content": "# -*- coding: utf-8 -*-\nfrom __future__ import annotations\nimport os\nimport loguru\nfrom loguru import logger\nfrom app.core import path_conf\n\n\nclass Logger:\n    @staticmethod\n    def log() -> loguru.Logger:\n        if not os.path.exists(path_conf.LogPath):\n            os.mkdir(path_conf.LogPath)\n\n        # 日志文件\n        log_file = os.path.join(path_conf.LogPath, 'fastapi_chatgpt.log')\n\n        # loguru日志\n        logger.add(\n            log_file,\n            encoding='utf-8',\n            level='DEBUG',\n            rotation='10 MB',\n            retention='7 days',\n            enqueue=True,\n            backtrace=True,\n            diagnose=True,\n        )\n\n        return logger\n\n\nlog = Logger().log()\n"
  },
  {
    "path": "python_backend/app/common/open_interpreter.py",
    "content": "# -*- coding: utf-8 -*-\nfrom interpreter.core.core import OpenInterpreter as _OpenInterpreter\nfrom app.core.conf import settings\n\nclass OpenInterpreter(_OpenInterpreter):\n    def __init__(self):\n        super().__init__()\n        self.offline = True\n        self.auto_run = settings.INTERPRETER_AUTO_RUN\n        self.max_output = settings.INTERPRETER_MAX_OUTPUT\n        # LLM\n        self.llm.model = f'ollama_chat/{settings.OLLAMA_MODEL}'\n        self.llm.api_base = settings.INTERPRETER_API_BASE\n        self.llm.temperature = settings.INTERPRETER_TEMPERATURE\n        self.llm.max_tokens = settings.INTERPRETER_MAX_TOKENS\n        self.llm.max_budget = settings.INTERPRETER_MAX_BUDGET\n        self.llm.context_window = settings.INTERPRETER_CONTEXT_WINDOW\n\n\nopen_interpreter = OpenInterpreter()\n"
  },
  {
    "path": "python_backend/app/common/response.py",
    "content": "# -*- coding: utf-8 -*-\nfrom typing import Any\nfrom pydantic import BaseModel\n\nclass ResponseModel(BaseModel):\n    code: int = 200\n    msg: str = 'OK'\n    data: Any = None\n    "
  },
  {
    "path": "python_backend/app/core/conf.py",
    "content": "# -*- coding: utf-8 -*-\nfrom functools import lru_cache\n\nfrom pydantic_settings import BaseSettings, SettingsConfigDict\n\n\nclass Settings(BaseSettings):\n    model_config = SettingsConfigDict(env_file='.env', env_file_encoding='utf-8')\n\n    # FastAPI设置\n    API_V1_STR: str = '/api/v1'\n    TITLE: str = 'FastAPI'\n    VERSION: str = '0.0.1'\n    DESCRIPTION: str = 'FastAPI ChatGPT API'\n    DOCS_URL: str | None = f'{API_V1_STR}/docs'\n    REDOCS_URL: str | None = f'{API_V1_STR}/redocs'\n    OPENAPI_URL: str | None = f'{API_V1_STR}/openapi'\n\n    # Uvicorn设置\n    UVICORN_HOST: str = '127.0.0.1'\n    UVICORN_PORT: int = 8000\n    UVICORN_RELOAD: bool = True\n\n    # ollama设置\n    OLLAMA_MODEL: str = 'gemma:2b'\n\n    # Interpreter设置\n    INTERPRETER_AUTO_RUN: bool = False\n    INTERPRETER_MAX_OUTPUT: int = 2200\n    INTERPRETER_API_BASE: str = 'http://localhost:11434'  # ollama serve地址\n    INTERPRETER_TEMPERATURE: int | float = 0\n    INTERPRETER_MAX_TOKENS: int | None = 100\n    INTERPRETER_MAX_BUDGET: int | float | None = None\n    INTERPRETER_CONTEXT_WINDOW: int = 3000\n\n\n@lru_cache\ndef get_settings():\n    return Settings()\n\n\nsettings = get_settings()\n"
  },
  {
    "path": "python_backend/app/core/path_conf.py",
    "content": "# -*- coding: utf-8 -*-\nimport os\n\nfrom pathlib import Path\n\nBasePath = Path(__file__).resolve().parent.parent.parent\n\n# 日志文件路径\nLogPath = os.path.join(BasePath, 'app', 'log')\n"
  },
  {
    "path": "python_backend/app/main.py",
    "content": "# -*- coding: utf-8 -*-\nimport uvicorn\nfrom fastapi import FastAPI, Request\nfrom starlette.responses import JSONResponse\nfrom app.api.routers import v1\nfrom app.common.log import log\nfrom app.common.response import ResponseModel\nfrom app.core.conf import settings\n\napp = FastAPI(\n    title=settings.TITLE,\n    version=settings.VERSION,\n    description=settings.DESCRIPTION,\n    docs_url=settings.DOCS_URL,\n    redoc_url=settings.REDOCS_URL,\n    openapi_url=settings.OPENAPI_URL,\n)\n\n\napp.include_router(v1)\n\n\n@app.exception_handler(Exception)\nasync def openai_auth_exception_handler(request: Request, exc: Exception):\n    import traceback\n\n    log.error(f'❌: {traceback.format_exc()}')\n    return JSONResponse(\n        status_code=500,\n        content=ResponseModel(code=500, msg=str(exc)).model_dump(),\n    )\n\n\nif __name__ == '__main__':\n    try:\n        log.info(\n            \"\"\"\\n\n /$$$$$$$$                   /$$      /$$$$$$  /$$$$$$$  /$$$$$$\n| $$_____/                  | $$     /$$__  $$| $$__  $$|_  $$_/\n| $$    /$$$$$$   /$$$$$$$ /$$$$$$  | $$  | $$| $$  | $$  | $$  \n| $$$$$|____  $$ /$$_____/|_  $$_/  | $$$$$$$$| $$$$$$$/  | $$  \n| $$__/ /$$$$$$$|  $$$$$$   | $$    | $$__  $$| $$____/   | $$  \n| $$   /$$__  $$ |____  $$  | $$ /$$| $$  | $$| $$        | $$  \n| $$  |  $$$$$$$ /$$$$$$$/  |  $$$$/| $$  | $$| $$       /$$$$$$\n|__/   |_______/|_______/    |___/  |__/  |__/|__/      |______/\n\n            \"\"\"\n        )\n        uvicorn.run(\n            app='main:app',\n            host=settings.UVICORN_HOST,\n            port=settings.UVICORN_PORT,\n            reload=settings.UVICORN_RELOAD,\n        )\n    except Exception as e:\n        log.error(f'❌ FastAPI start filed: {e}')\n        "
  },
  {
    "path": "python_backend/app/requirements.txt",
    "content": "# 核心依赖\nfastapi==0.110.0\nuvicorn==0.27.1\npydantic==2.4.2\npydantic-settings==2.2.1\npython-dotenv==1.0.0\npython-multipart==0.0.9\n\n# Ollama 和 AI 相关\nollama==0.1.6\nopen-interpreter==0.2.0\nlitellm==1.27.4\nopenai==1.12.0\ntiktoken==0.4.0\ntokenizers==0.14.1\ntokentrim==0.1.13\nhuggingface-hub==0.17.3\n\n# HTTP 和网络\nhttpx==0.25.2\nhttpcore==1.0.4\naiohttp==3.8.6\naiosignal==1.3.1\nfrozenlist==1.4.0\nmultidict==6.0.4\nyarl==1.9.2\nrequests==2.31.0\nurllib3==1.26.18\ncertifi==2023.7.22\nidna==3.4\ncharset-normalizer==3.3.2\n\n# 异步和并发\nanyio==3.7.1\nasync-timeout==4.0.3\nsniffio==1.3.0\n\n# 日志和调试\nloguru==0.7.2\nrich==13.6.0\npygments==2.16.1\nmarkdown-it-py==3.0.0\nmdurl==0.1.2\n\n# 数据处理\nnumpy==1.26.4\nregex==2023.10.3\ntqdm==4.66.1\npackaging==23.2\nsix==1.16.0\n\n# 系统工具\npsutil==5.9.6\nplatformdirs==3.11.0\nappdirs==1.4.4\ndistro==1.9.0\nfilelock==3.13.1\nfsspec==2023.10.0\n\n# 配置和工具\nclick==8.1.7\njinja2==3.1.2\nmarkupsafe==2.1.3\npyyaml==6.0.1\ntoml==0.10.2\npython-editor==1.0.4\nwcwidth==0.2.9\n"
  },
  {
    "path": "python_backend/app/schemas/interpreter.py",
    "content": "# -*- coding: utf-8 -*-\nfrom pydantic import BaseModel\n\n\nclass InterpreterMessage(BaseModel):\n    message: str\n    "
  },
  {
    "path": "python_backend/app/schemas/ollama.py",
    "content": "# -*- coding: utf-8 -*-\nfrom typing import Literal\n\nfrom pydantic import BaseModel\n\n\nclass OllamaMessages(BaseModel):\n    role: Literal['system', 'user', 'assistant']\n    content: str\n    images: list[str] | None = None\n"
  },
  {
    "path": "python_backend/config/config.py",
    "content": "# -*- coding: utf-8 -*-\n#文心模型类型\nAPI_TYPE = \"aistudio\"\n#文心模型token 地址地址https://aistudio.baidu.com/index/accessToken\nACCESS_TOKEN = \"文心一言token\"\n# 网页的端口, -1代表随机端口\nWEB_PORT = 8099\n# 文心一言模型选择是\nLLM_MODEL = \"ernie-3.5\"\n"
  },
  {
    "path": "python_backend/config/config_private.py",
    "content": "# -*- coding: utf-8 -*-\n#文心模型类型\nAPI_TYPE = \"aistudio\"\n#文心模型token 申请地址https://aistudio.baidu.com/index/accessToken\nACCESS_TOKEN = \"文心一言token\"\n# 网页的端口, -1代表随机端口\nWEB_PORT = 8099\n# 文心一言模型选择是\nLLM_MODEL = \"ernie-3.5\"\n"
  },
  {
    "path": "python_backend/content.txt",
    "content": "文生图测试内容 - ChattyPlay"
  },
  {
    "path": "python_backend/main.py",
    "content": "# -*- coding: utf-8 -*-\nimport erniebot\nfrom tools.config_tool import get_conf\nfrom tools.read_file import read\nfrom tools.stable_api import txt2img\nfrom tools.generate_video import image_to_video_mp4\n\n\ndef str_to_jsonstr(data: str):\n    \"\"\"\n    过滤字符串\n    :param data:\n    :return:\n    \"\"\"\n    start_index = data.find(\"```json\")\n    end_index = data.rfind(\"```\")\n    del_json = data[start_index+8:end_index]\n    return del_json\n\n\ndef main():\n    print('------------------文章生成图片提示词-------------------')\n    API_TYPE, ACCESS_TOKEN, WEB_PORT, LLM_MODEL = get_conf('API_TYPE', 'ACCESS_TOKEN', 'WEB_PORT', 'LLM_MODEL')\n    erniebot.api_type = API_TYPE\n    erniebot.access_token = ACCESS_TOKEN\n    prefix_prompt = \"你是一个提示词专家，你的任务是辅助我生成优质的文生图提示词，要求：1.文章按照句号分隔；2.每句话生成一个文生图提示词；3.输出json格式数据，内容标签content,提示词标签prompt。内容如下：\"\n    content = read('python_backend/content.txt')\n    stream = False\n    response = erniebot.ChatCompletion.create(\n        model='ernie-4.0',\n        messages=[{'role': 'user', 'content': prefix_prompt + content}],\n        stream=stream)\n\n    result = \"\"\n    if stream:\n        for resp in response:\n            result += resp.get_result()\n    else:\n        result = response.get_result()\n    print(result)\n    dict_data = eval(str_to_jsonstr(result))\n    print('------------------文生图片-------------------')\n    i = 1\n    for prompt_item in dict_data:\n        txt2img(prompt=prompt_item['prompt'], image_name=str(i)+'.png')\n        i = i+1\n        print('第'+str(i)+'张图')\n    print('------------------生成视频开始-------------------')\n    image_to_video_mp4(output='result.mp4',height=768,width=1024)\n    print('------------------生成视频成功-------------------')\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "python_backend/requirements.txt",
    "content": "docx2txt==0.8\nerniebot==0.5.0\nflask == 2.3.2\ngradio==3.28.0\nsentence_transformers==2.2.2\nPillow==9.5.0\n"
  },
  {
    "path": "python_backend/tools/config_tool.py",
    "content": "# -*- coding: utf-8 -*-\nimport importlib\nfrom functools import lru_cache\nimport sys\nimport os\nimport socket\nfrom contextlib import closing\n@lru_cache(maxsize=128)\ndef read_single_conf_lru_cache(arg):\n    \"\"\"\n      获取读取\n    \"\"\"\n    # 根目录\n    project_dir = os.path.dirname(sys.argv[0])\n    sys.path.append(project_dir+'/config')\n    try: r = getattr(importlib.import_module('config_private'), arg)\n    except: r = getattr(importlib.import_module('config'), arg)\n    return r\n\n\ndef get_conf(*args):\n    \"\"\"\n      获取配置\n    \"\"\"\n    # 建议您复制一个config_private.py放自己的秘密, 如token, 避免不小心传github被别人看到\n    res = []\n    for arg in args:\n        r = read_single_conf_lru_cache(arg)\n        res.append(r)\n    return res\ndef get_free_port():\n    \"\"\"\n        返回当前系统中可用的未使用端口。\n    \"\"\"\n    with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s:\n        s.bind(('', 0))\n        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n        return s.getsockname()[1]\n    "
  },
  {
    "path": "python_backend/tools/generate_video.py",
    "content": "# -*- coding: utf-8 -*-\nimport cv2 as cv\nfrom PIL import Image\nimport numpy as np\nimport os\nimport math\nproject_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\npath_img = project_dir+'/output/image/'\npath_video = project_dir+'/output/video/'\npath_video_avi = project_dir+'/output/video/test.avi'\nvideo_name = 'test.mp4'\n\n\ndef image_to_video_mp4(file_path=path_img, output=video_name, height=512, width=512, fps=60,effects=True):\n    print('file_path:'+file_path)\n    # 生成图片目录下以图片名字为内容的列表\n    img_list = os.listdir(file_path)\n    # 用于mp4格式的生成\n    fourcc = cv.VideoWriter_fourcc(*'mp4v')\n    # 创建一个写入视频对象\n    videowriter = cv.VideoWriter(path_video+output, fourcc, fps, (width, height))\n    for img in img_list:\n        path = file_path + img\n        if len(img) < 4:\n            continue\n        if effects:\n            for i in range(fps + 1):\n                frame = pillow_to_cv(image_crop(path, height, width, i))\n                # 特效\n                if i > 52:\n                    if i % 2 == 0:#光照\n                      frame = illumination_image(frame)\n                    else:#流年\n                      frame = flow_image(frame)\n                videowriter.write(frame)\n        else:\n            frame = cv.imread(path)\n            for i in range(fps+1):\n                videowriter.write(frame)\n\n    videowriter.release()\n\n\ndef image_resize(image_path, height, width):\n    image = Image.open(image_path)\n    new_size = (width, height)\n    return image.resize(new_size)\n\n\ndef image_crop(image_path, height, width, step):\n    image = Image.open(image_path)\n    height_n = image.height\n    width_n = image.width\n    s_height = height_n/800\n    s_width = width_n/800\n    new_size = (s_width*step, s_height*step, width_n-s_width*step, height_n-s_height*step)\n    crop_image = image.crop(new_size)\n    return crop_image.resize((width, height))\n\n\ndef pillow_to_cv(image_pil):\n    return cv.cvtColor(np.asarray(image_pil),cv.COLOR_RGB2BGR)\n\n\ndef cv_to_pillow(image_cv):\n    return Image.fromarray(cv.cvtColor(image_cv,cv.COLOR_BGR2RGB))\n\n\ndef image_to_video_avi(file_path=path_img, output=path_video_avi, height=512, width=512, fps=60):\n    # 生成图片目录下以图片名字为内容的列表\n    img_list = os.listdir(file_path)\n    # avi格式的生成\n    fourcc = cv.VideoWriter_fourcc('M', 'J', 'P', 'G')\n    # 创建一个写入视频对象\n    videowriter = cv.VideoWriter(output, fourcc, fps, (width, height))\n    for img in img_list:\n        path = file_path + img\n        if len(img) < 4:\n            continue\n        for i in range(501):\n            frame = pillow_to_cv(image_crop(path,height,width,i))\n            videowriter.write(frame)\n    videowriter.release()\n\ndef illumination_image(img):\n    \"\"\"\n    光照特效 img = cv.imread\n    :return:\n    \"\"\"\n    # 获取图像行和列\n    rows, cols = img.shape[:2]\n    # 设置中心点和光照半径\n    centerX = rows / 2 - 20\n    centerY = cols / 2 + 20\n    radius = min(centerX, centerY)\n    # 设置光照强度\n    strength = 100\n    # 新建目标图像\n    dst = np.zeros((rows, cols, 3), dtype=\"uint8\")\n    # 图像光照特效\n    for i in range(rows):\n        for j in range(cols):\n            # 计算当前点到光照中心距离(平面坐标系中两点之间的距离)\n            distance = math.pow((centerY - j), 2) + math.pow((centerX - i), 2)\n            # 获取原始图像\n            B = img[i, j][0]\n            G = img[i, j][1]\n            R = img[i, j][2]\n            if (distance < radius * radius):\n                # 按照距离大小计算增强的光照值\n                result = (int)(strength * (1.0 - math.sqrt(distance) / radius))\n                B = img[i, j][0] + result\n                G = img[i, j][1] + result\n                R = img[i, j][2] + result\n                # 判断边界 防止越界\n                B = min(255, max(0, B))\n                G = min(255, max(0, G))\n                R = min(255, max(0, R))\n                dst[i, j] = np.uint8((B, G, R))\n            else:\n                dst[i, j] = np.uint8((B, G, R))\n\n    return dst\n\n\ndef flow_image(img):\n    \"\"\"\n    流年特效\n    :param img: img = cv.imread\n    :return:\n    \"\"\"\n    # 获取图像行和列\n    rows, cols = img.shape[:2]\n    # 新建目标图像\n    dst = np.zeros((rows, cols, 3), dtype=\"uint8\")\n    # 图像流年特效\n    for i in range(rows):\n        for j in range(cols):\n            # B通道的数值开平方乘以参数12\n            B = math.sqrt(img[i, j][0]) * 12\n            G = img[i, j][1]\n            R = img[i, j][2]\n            if B > 255:\n                B = 255\n            dst[i, j] = np.uint8((B, G, R))\n    return dst\n\n\ndef filter_image(img):\n    \"\"\"\n    图像滤镜\n    :param img: img = cv.imread\n    :return:\n    \"\"\"\n    # 获取滤镜颜色\n    def getBGR(image_bgr, table, i, j):\n        # 获取图像颜色\n        b, g, r = image_bgr[i][j]\n        # 计算标准颜色表中颜色的位置坐标\n        x = int(g / 4 + int(b / 32) * 63)\n        y = int(r / 4 + int((b % 32) / 4) * 63)\n        # 返回滤镜颜色表中对应的颜色\n        return lj_map[x][y]\n    # 滤镜图像\n    lj_map = img\n    # 获取图像行和列\n    rows, cols = img.shape[:2]\n    # 新建目标图像\n    dst = np.zeros((rows, cols, 3), dtype=\"uint8\")\n    # 循环设置滤镜颜色\n    for i in range(rows):\n        for j in range(cols):\n            dst[i][j] = getBGR(img, lj_map, i, j)\n    return dst\n\n\ndef nostalgia_image(img):\n   \"\"\"\n   :param img:\n   :return:\n   \"\"\"\n   # 获取图像行和列\n   rows, cols = img.shape[:2]\n   # 新建目标图像\n   dst = np.zeros((rows, cols, 3), dtype=\"uint8\")\n   # 图像怀旧特效\n   for i in range(rows):\n       for j in range(cols):\n           B = 0.272 * img[i, j][2] + 0.534 * img[i, j][1] + 0.131 * img[i, j][0]\n           G = 0.349 * img[i, j][2] + 0.686 * img[i, j][1] + 0.168 * img[i, j][0]\n           R = 0.393 * img[i, j][2] + 0.769 * img[i, j][1] + 0.189 * img[i, j][0]\n           if B > 255:\n               B = 255\n           if G > 255:\n               G = 255\n           if R > 255:\n               R = 255\n           dst[i, j] = np.uint8((B, G, R))\n\n   return dst\n\n\ndef sketch_image(img):\n     \"\"\"\n     素描特效\n     :param img:\n     :return:\n     \"\"\"\n     # 图像灰度处理\n     gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)\n     # 高斯滤波降噪\n     gaussian = cv.GaussianBlur(gray, (5, 5), 0)\n     # Canny算子\n     canny = cv.Canny(gaussian, 50, 150)\n     # 阈值化处理\n     ret, result = cv.threshold(canny, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)\n     return result\n"
  },
  {
    "path": "python_backend/tools/image_effect.py",
    "content": "# -*- coding: utf-8 -*-\nfrom PIL import Image, ImageSequence, ImageEnhance\n\n\ndef add_fade_effect(image_path, duration=1):\n    \"\"\"\n    给图片添加淡入淡出动画效果。\n    :param image_path: 图片文件路径。\n    :param duration: 每帧持续时间（秒）。\n    \"\"\"\n    image = Image.open(image_path)\n    width, height = image.size\n\n    # 生成淡入淡出的渐变掩码\n    def fade_mask(t):\n        return int(255 * (1 - min(1, t / (duration / 2))))\n\n    frames = []\n    for i in range(int(duration * 60) // 2):  # 每秒60帧\n        # 生成淡入渐变\n        fade_in = Image.new('RGBA', (width, height), (0, 0, 0, fade_mask(i)))\n        frames.append(Image.composite(Image.blend, image, fade_in))\n\n        # 生成淡出渐变\n        fade_out = Image.new('RGBA', (width, height), (0, 0, 0, 255 - fade_mask(i + duration * 60 // 2)))\n        frames.append(Image.composite(Image.blend, image, fade_out))\n\n    # 保存为GIF动画\n    frames[0].save('fade_effect.gif', save_all=True, append_images=frames[1:], duration=duration, loop=0)\n\n\n# 使用例子\nadd_fade_effect('1.png', duration=1)  # 图片路径，持续时间为1秒的淡入淡出动画\n"
  },
  {
    "path": "python_backend/tools/read_file.py",
    "content": "# -*- coding: utf-8 -*-\ndef read(file_path):\n    \"\"\"\n        读文件\n    \"\"\"\n    f = open(file_path, \"r\", encoding='utf-8')\n    lines = f.readlines()  # 读取全部内容\n    return ''.join(lines)\n\n"
  },
  {
    "path": "python_backend/tools/stable_api.py",
    "content": "# -*- coding: utf-8 -*-\n# api文档 http://127.0.0.1:7860/docs\n# 第三方api调用库 https://github.com/mix1009/sdwebuiapi\nimport requests\nimport base64\nimport os\n# 文生图片api\nurl = \"http://127.0.0.1:7860\"\nproject_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\npath_img = project_dir+'/output/image/'\npath_image = project_dir+'/output/locimg/'\n\n\ndef txt2img(prompt='puppy dog',image_name='test.png'):\n    payload = {\n        \"prompt\": prompt,\n        \"steps\": 20,\n        \"width\": 1024,\n        \"height\": 768,\n        \"sampler_index\": \"Euler a\",\n        \"override_settings\": {\n        \"sd_model_checkpoint\": \"novelV1\"}\n    }\n    # 发送请求\n    response = requests.post(url=f'{url}/sdapi/v1/txt2img', json=payload)\n    print('--------')\n    print(response)\n    r = response.json()\n    # 保存图片\n    check_and_create_path(path_img)\n    with open(path_img+image_name, 'wb') as f:\n        f.write(base64.b64decode(r['images'][0]))\n\n\ndef txt2img_imgname(prompt='puppy dog', negative_prompt='', sampler='DPM++ 3M SDE Karras', image_name='test.png', img_path='1/'):\n    payload = {\n        \"prompt\": prompt,\n        \"negative_prompt\": negative_prompt,\n        \"steps\": 35,\n        \"width\": 1024,\n        \"height\": 768,\n        \"sampler_index\": sampler,\n        \"override_settings\": {\n        \"sd_model_checkpoint\": \"tianyuan\"}\n    }\n    # 发送请求\n    response = requests.post(url=f'{url}/sdapi/v1/txt2img', json=payload)\n    print('--------')\n    print(response)\n    r = response.json()\n    # 保存图片\n    check_and_create_path(path_image+img_path)\n    with open(path_image+img_path+image_name, 'wb') as f:\n        f.write(base64.b64decode(r['images'][0]))\n\n\ndef check_and_create_path(path):\n    # 检查路径是否存在\n    if not os.path.exists(path):\n        # 如果路径不存在，则创建\n        try:\n            os.makedirs(path)\n        except OSError as e:\n            # 如果创建过程中出现错误（例如目录已存在），则打印错误信息并跳过\n            print(f\"Error: {e}\")\n    else:\n        print(f\"Path '{path}' exists.\")\n"
  },
  {
    "path": "src/App.tsx",
    "content": "import React, { useState, useEffect } from 'react'\nimport { BrowserRouter as Router, Routes, Route, useLocation, useNavigate } from 'react-router-dom'\nimport { GoogleOAuthProvider } from '@react-oauth/google'\nimport { isAuthenticated } from './utils/token'\nimport { ConfigProvider, Spin } from 'antd'\nimport zhCN from 'antd/locale/zh_CN'\nimport NProgress from 'nprogress'\nimport Home from './pages/Home'\nimport Login from './pages/Login'\nimport GPT from './pages/GPT'\nimport Video from './pages/Video'\nimport Music from './pages/Music'\nimport Cartoon from './pages/Cartoon'\nimport CartoonDetail from './pages/CartoonDetail'\nimport CartoonChapter from './pages/CartoonChapter'\nimport Gold from './pages/Gold'\nimport Trans from './pages/Trans'\nimport TextToPhoto from './pages/TextToPhoto'\nimport Help from './pages/Help'\nimport About from './pages/About'\nimport PaperListPage from './pages/PaperListPage'\nimport NotFound from './pages/NotFound'\nimport Navbar from './components/Navbar'\nimport Footer from './components/Footer'\nimport ClickEffect from './components/ClickEffect'\nimport Live2DDashboard from './components/Live2DDashboard'\nimport VersionUpdateModal from './components/VersionUpdateModal'\nimport { GoofishLayout } from './components/goofish'\nimport Dashboard from './pages/goofish/Dashboard'\nimport Accounts from './pages/goofish/Accounts'\nimport { Conversations } from './pages/goofish/Conversations'\nimport Orders from './pages/goofish/Orders'\nimport AutoReply from './pages/goofish/AutoReply'\nimport AutoSell from './pages/goofish/AutoSell'\nimport Workflow from './pages/goofish/Workflow'\nimport Logs from './pages/goofish/Logs'\nimport Goods from './pages/goofish/Goods'\nimport { scrollToTop } from './utils/backTop'\nimport { isMobileDevice } from './utils/isMobile'\nimport WorkerAgent from './pages/WorkerAgent'\nimport Markmap from './pages/Markmap'\nimport Latex from './pages/Latex'\n\n// 公开路由\nconst publicRoutes = ['/']\n\n// 移动端限制监工路由\nconst workerAgentRoutes = ['/worker']\n\n// 配置 NProgress\nNProgress.configure({\n  minimum: 0.1,\n  easing: 'ease',\n  speed: 300,\n  showSpinner: true,\n  trickleSpeed: 200,\n  parent: 'body'\n})\n\nconst AppContent: React.FC = () => {\n  const location = useLocation()\n  const navigate = useNavigate()\n  const [loading, setLoading] = useState(true)\n\n  // 判断是否是首页\n  const isHomePage = location.pathname === '/home'\n\n  // 路由守卫：检查是否登录\n  useEffect(() => {\n    // 如果是移动端、生产环境下访问监工路由且已登录，重定向到首页\n    if (process.env.NODE_ENV === 'production' && workerAgentRoutes.includes(location.pathname) && isMobileDevice() && isAuthenticated()) {\n      navigate('/home', { replace: true })\n      return\n    }\n    // 如果是移动端、生产环境下访问监工路由且未登录，重定向到登录页\n    if (process.env.NODE_ENV === 'production' && workerAgentRoutes.includes(location.pathname) && isMobileDevice() && !isAuthenticated()) {\n      navigate('/', { replace: true })\n      return\n    }\n    // 如果已登录且在登录页，跳转到首页\n    if (publicRoutes.includes(location.pathname) && isAuthenticated()) {\n      navigate('/home', { replace: true })\n      return\n    }\n    // 如果不是公开路由且未登录，则跳转到登录页\n    if (!publicRoutes.includes(location.pathname) && !isAuthenticated()) {\n      navigate('/', { replace: true })\n    }\n  }, [location.pathname, navigate])\n\n  // 初始化加载\n  useEffect(() => {\n    const timer = setTimeout(() => {\n      setLoading(false)\n    }, 800)\n\n    return () => clearTimeout(timer)\n  }, [])\n\n  // 路由变化时显示进度条\n  useEffect(() => {\n    NProgress.start()\n\n    // 使用 requestAnimationFrame 确保进度条能正确显示\n    const frame = requestAnimationFrame(() => {\n      NProgress.set(0.4)\n    })\n\n    const timer = setTimeout(() => {\n      NProgress.done()\n      scrollToTop()\n    }, 500)\n\n    return () => {\n      cancelAnimationFrame(frame)\n      clearTimeout(timer)\n      NProgress.done()\n    }\n  }, [location.pathname])\n\n  // 检查是否是登录页面\n  const isLoginPage = location.pathname === '/'\n\n  if (loading) {\n    return (\n      <div style={{\n        display: 'flex',\n        justifyContent: 'center',\n        alignItems: 'center',\n        height: '100vh',\n        background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\n        position: 'relative',\n        overflow: 'hidden'\n      }}>\n        {/* 背景动画效果 */}\n        <div style={{\n          position: 'absolute',\n          width: '200%',\n          height: '200%',\n          background: 'radial-gradient(circle, rgba(255,255,255,0.1) 1px, transparent 1px)',\n          backgroundSize: '50px 50px',\n          animation: 'moveBackground 20s linear infinite'\n        }} />\n        <style>{`\n          @keyframes moveBackground {\n            0% { transform: translate(0, 0); }\n            100% { transform: translate(-50px, -50px); }\n          }\n        `}</style>\n        <div style={{\n          textAlign: 'center',\n          zIndex: 1,\n          animation: 'fadeIn 0.5s ease-out'\n        }}>\n          <Spin size=\"large\" />\n          <div style={{\n            marginTop: '16px',\n            color: '#fff',\n            fontSize: '1.1rem',\n            animation: 'pulse 1.5s ease-in-out infinite'\n          }}>\n            加载中...\n          </div>\n        </div>\n        <style>{`\n          @keyframes fadeIn {\n            from { opacity: 0; transform: translateY(-20px); }\n            to { opacity: 1; transform: translateY(0); }\n          }\n          @keyframes pulse {\n            0%, 100% { opacity: 1; }\n            50% { opacity: 0.5; }\n          }\n        `}</style>\n      </div>\n    )\n  }\n\n  // 登录页面不显示 Header 和 Footer\n  if (isLoginPage) {\n    return (\n      <main style={{ flex: 1, minHeight: '100vh' }}>\n        <Routes>\n          <Route path=\"/\" element={<Login />} />\n        </Routes>\n      </main>\n    )\n  }\n\n  return (\n    <div style={{ display: 'flex', flexDirection: 'column', minHeight: '100vh' }}>\n      <ClickEffect />\n      <Navbar />\n      <main style={{\n        flex: 1,\n        paddingTop: '64px',\n        transition: 'padding-top 0.3s ease',\n        backgroundColor: '#f5f5f5'\n      }}>\n        <Routes>\n          <Route path=\"/home\" element={<Home />} />\n          <Route path=\"/gpt\" element={<GPT />} />\n          <Route path=\"/video\" element={<Video />} />\n          <Route path=\"/music\" element={<Music />} />\n          <Route path=\"/cartoon\" element={<Cartoon />} />\n          <Route path=\"/cartoon/:id\" element={<CartoonDetail />} />\n          <Route path=\"/cartoon/chapter/:comicId\" element={<CartoonChapter />} />\n          <Route path=\"/gold\" element={<Gold />} />\n          <Route path=\"/trans\" element={<Trans />} />\n          <Route path=\"/text-to-photo\" element={<TextToPhoto />} />\n          <Route path=\"/help\" element={<Help />} />\n          <Route path=\"/about\" element={<About />} />\n          <Route path=\"/papers\" element={<PaperListPage />} />\n          <Route path=\"/markmap\" element={<Markmap />} />\n          <Route path=\"/latex\" element={<Latex />} />\n          <Route path=\"/worker\" element={<WorkerAgent />} />\n          {/* Goofish 闲鱼管理模块 */}\n          <Route path=\"/goofish\" element={<GoofishLayout />}>\n            <Route index element={<Dashboard />} />\n            <Route path=\"accounts\" element={<Accounts />} />\n            <Route path=\"conversations\" element={<Conversations />} />\n            <Route path=\"orders\" element={<Orders />} />\n            <Route path=\"goods\" element={<Goods />} />\n            <Route path=\"autoreply\" element={<AutoReply />} />\n            <Route path=\"autosell\" element={<AutoSell />} />\n            <Route path=\"workflow\" element={<Workflow />} />\n            <Route path=\"logs\" element={<Logs />} />\n          </Route>\n          <Route path=\"*\" element={<NotFound />} />\n        </Routes>\n      </main>\n      <Footer />\n      {/* 只在 /home 路由下渲染看板娘 */}\n      {isHomePage && <Live2DDashboard isVisible={true} />}\n    </div>\n  )\n}\n\nconst App: React.FC = () => {\n  const googleClientId = import.meta.env.VITE_GOOGLE_CLIENT_ID || ''\n\n  return (\n    <ConfigProvider locale={zhCN}>\n      <GoogleOAuthProvider clientId={googleClientId}>\n        <Router>\n          <VersionUpdateModal />\n          <AppContent />\n        </Router>\n      </GoogleOAuthProvider>\n    </ConfigProvider>\n  )\n}\n\nexport default App\n"
  },
  {
    "path": "src/assets/css/ai.scss",
    "content": ".markdown-content {\n  line-height: 1.7;\n  color: #334155;\n\n  // 标题样式\n  h1, h2, h3, h4, h5, h6 {\n    margin: 16px 0 8px;\n    font-weight: 600;\n    line-height: 1.4;\n    color: #1e293b;\n\n    &:first-child {\n      margin-top: 0;\n    }\n  }\n\n  h1 { font-size: 1.8rem; border-bottom: 2px solid #e2e8f0; padding-bottom: 8px; }\n  h2 { font-size: 1.5rem; border-bottom: 1px solid #e2e8f0; padding-bottom: 6px; }\n  h3 { font-size: 1.25rem; }\n  h4 { font-size: 1.1rem; }\n  h5 { font-size: 1rem; }\n  h6 { font-size: 0.9rem; color: #64748b; }\n\n  // 段落\n  p {\n    margin: 8px 0;\n\n    &:first-child {\n      margin-top: 0;\n    }\n\n    &:last-child {\n      margin-bottom: 0;\n    }\n  }\n\n  // 列表\n  ul, ol {\n    margin: 8px 0;\n    padding-left: 24px;\n  }\n\n  li {\n    margin: 4px 0;\n  }\n\n  // 代码块容器\n  .code-container {\n    margin: 12px 0;\n    border-radius: 8px;\n    overflow: hidden;\n    background: #1e293b;\n    box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);\n  }\n\n  .code-header {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    padding: 8px 16px;\n    background: #334155;\n    border-bottom: 1px solid #475569;\n\n    .language-label {\n      font-size: 0.75rem;\n      font-weight: 600;\n      text-transform: uppercase;\n      color: #e2e8f0;\n      font-family: 'Fira Code', 'Consolas', monospace;\n    }\n\n    .copy-btn {\n      display: flex;\n      align-items: center;\n      gap: 4px;\n      padding: 4px 12px;\n      background: #475569;\n      color: #e2e8f0;\n      border: none;\n      border-radius: 4px;\n      font-size: 0.75rem;\n      cursor: pointer;\n      transition: all 0.2s ease;\n\n      &:hover {\n        background: #64748b;\n        transform: translateY(-1px);\n      }\n\n      &:active {\n        transform: translateY(0);\n      }\n\n      .copy-icon {\n        width: 14px;\n        height: 14px;\n      }\n    }\n  }\n\n  pre {\n    margin: 0;\n    padding: 16px;\n    overflow-x: auto;\n    background: #1e293b;\n\n    code {\n      font-family: 'Fira Code', 'Consolas', 'Monaco', monospace;\n      font-size: 0.9rem;\n      line-height: 1.6;\n      color: #e2e8f0;\n      background: transparent;\n      padding: 0;\n    }\n  }\n\n  // 行内代码\n  code:not(pre code) {\n    background: #f1f5f9;\n    padding: 2px 6px;\n    border-radius: 4px;\n    font-family: 'Fira Code', 'Consolas', monospace;\n    font-size: 0.9em;\n    color: #dc2626;\n  }\n\n  // 引用块\n  blockquote {\n    border-left: 4px solid #3b82f6;\n    padding-left: 16px;\n    margin: 12px 0;\n    color: #64748b;\n    font-style: italic;\n    background: #f8fafc;\n    padding: 12px 16px;\n    border-radius: 0 8px 8px 0;\n  }\n\n  // 表格\n  table {\n    border-collapse: collapse;\n    width: 100%;\n    margin: 12px 0;\n    overflow: hidden;\n    border-radius: 8px;\n    box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);\n\n    th, td {\n      border: 1px solid #e2e8f0;\n      padding: 12px 16px;\n      text-align: left;\n    }\n\n    th {\n      background: #f8fafc;\n      font-weight: 600;\n      color: #334155;\n    }\n\n    tr:nth-child(even) {\n      background: #f8fafc;\n    }\n\n    tr:hover {\n      background: #f1f5f9;\n    }\n  }\n\n  // 链接\n  a {\n    color: #3b82f6;\n    text-decoration: none;\n    border-bottom: 1px solid transparent;\n    transition: all 0.2s ease;\n\n    &:hover {\n      border-bottom-color: #3b82f6;\n    }\n  }\n\n  // 分隔线\n  hr {\n    border: none;\n    border-top: 2px solid #e2e8f0;\n    margin: 16px 0;\n  }\n\n  // 图片\n  img {\n    max-width: 100%;\n    height: auto;\n    border-radius: 8px;\n    margin: 8px 0;\n    box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);\n  }\n\n  // 任务列表\n  input[type=\"checkbox\"] {\n    margin-right: 8px;\n    accent-color: #3b82f6;\n  }\n\n  // 移动端优化\n  @media (max-width: 768px) {\n    h1 { font-size: 1.4rem; }\n    h2 { font-size: 1.2rem; }\n    h3 { font-size: 1.1rem; }\n\n    .code-header {\n      padding: 6px 12px;\n\n      .language-label {\n        font-size: 0.65rem;\n      }\n\n      .copy-btn {\n        padding: 3px 8px;\n        font-size: 0.65rem;\n\n        .copy-icon {\n          width: 12px;\n          height: 12px;\n        }\n      }\n    }\n\n    pre {\n      padding: 12px;\n\n      code {\n        font-size: 0.8rem;\n      }\n    }\n\n    table {\n      font-size: 0.85rem;\n\n      th, td {\n        padding: 8px 12px;\n      }\n    }\n\n    ul, ol {\n      padding-left: 20px;\n    }\n  }\n}\n\n// 流式内容样式\n.streaming-content {\n  position: relative;\n\n  .cursor-blink {\n    display: inline-block;\n    width: 2px;\n    height: 1.2em;\n    background: #3b82f6;\n    animation: blink 1s infinite;\n    vertical-align: text-bottom;\n    margin-left: 2px;\n  }\n}\n\n@keyframes blink {\n  0%, 50% {\n    opacity: 1;\n  }\n  51%, 100% {\n    opacity: 0;\n  }\n}\n\n// 消息动画\n@keyframes messageSlideIn {\n  from {\n    opacity: 0;\n    transform: translateY(10px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.message-animate {\n  animation: messageSlideIn 0.3s ease-out;\n}\n\n// 欢迎卡片动画\n@keyframes fadeIn {\n  from {\n    opacity: 0;\n    transform: translateY(20px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.welcome-animate {\n  animation: fadeIn 0.6s ease-out;\n}\n\n// 脉冲动画\n@keyframes pulse {\n  0%, 100% {\n    opacity: 1;\n  }\n  50% {\n    opacity: 0.5;\n  }\n}\n\n.pulse {\n  animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n}\n\n// 滚动条样式\n.custom-scrollbar {\n  &::-webkit-scrollbar {\n    width: 8px;\n    height: 8px;\n  }\n\n  &::-webkit-scrollbar-track {\n    background: #f1f5f9;\n    border-radius: 10px;\n  }\n\n  &::-webkit-scrollbar-thumb {\n    background: linear-gradient(135deg, #3b82f6 0%, #6366f1 100%);\n    border-radius: 10px;\n\n    &:hover {\n      background: linear-gradient(135deg, #2563eb 0%, #4f46e5 100%);\n    }\n  }\n\n  // 移动端滚动条更细\n  @media (max-width: 768px) {\n    &::-webkit-scrollbar {\n      width: 4px;\n      height: 4px;\n    }\n  }\n}\n\n// 深色模式支持\n@media (prefers-color-scheme: dark) {\n  .markdown-content {\n    color: #cbd5e1;\n\n    h1, h2, h3, h4, h5, h6 {\n      color: #f1f5f9;\n    }\n\n    h1 { border-bottom-color: #475569; }\n    h2 { border-bottom-color: #475569; }\n\n    code:not(pre code) {\n      background: #334155;\n      color: #fca5a5;\n    }\n\n    blockquote {\n      background: #1e293b;\n      border-left-color: #60a5fa;\n      color: #94a3b8;\n    }\n\n    table {\n      th, td {\n        border-color: #475569;\n      }\n\n      th {\n        background: #1e293b;\n        color: #e2e8f0;\n      }\n\n      tr:nth-child(even) {\n        background: #1e293b;\n      }\n\n      tr:hover {\n        background: #334155;\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/assets/css/global.css",
    "content": "* {\n  margin: 0;\n  padding: 0;\n  box-sizing: border-box;\n}\n\nbody {\n  font-family:\n    -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", \"Oxygen\", \"Ubuntu\",\n    \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", sans-serif;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  background-color: #f8fafc;\n  color: #334155;\n}\n\ncode {\n  font-family:\n    source-code-pro, Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\n\nhtml {\n  scroll-behavior: smooth;\n}\n\n#root {\n  min-height: 100vh;\n}\n\n/* 响应式设计 */\n@media (max-width: 768px) {\n  html {\n    font-size: 14px;\n  }\n}\n\n@media (max-width: 480px) {\n  html {\n    font-size: 12px;\n  }\n}\n\n/* 动画效果 */\n@keyframes fadeIn {\n  from {\n    opacity: 0;\n    transform: translateY(20px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n@keyframes slideIn {\n  from {\n    opacity: 0;\n    transform: translateX(-20px);\n  }\n  to {\n    opacity: 1;\n    transform: translateX(0);\n  }\n}\n\n@keyframes pulse {\n  0%,\n  100% {\n    transform: scale(1);\n  }\n  50% {\n    transform: scale(1.05);\n  }\n}\n\n.fade-in {\n  animation: fadeIn 0.5s ease-out forwards;\n}\n\n.slide-in {\n  animation: slideIn 0.3s ease-out forwards;\n}\n\n.pulse {\n  animation: pulse 2s infinite;\n}\n\n/* NProgress 样式优化 */\n#nprogress {\n  pointer-events: none;\n}\n\n#nprogress .bar {\n  background: linear-gradient(90deg, #667eea 0%, #764ba2 100%) !important;\n  position: fixed;\n  z-index: 9999;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 3px;\n  box-shadow: 0 0 10px rgba(102, 126, 234, 0.5);\n}\n\n#nprogress .peg {\n  display: none;\n}\n\n#nprogress .spinner {\n  display: block !important;\n  position: fixed;\n  z-index: 9999;\n  top: 15px;\n  right: 15px;\n}\n\n#nprogress .spinner-icon {\n  width: 20px;\n  height: 20px;\n  border: 3px solid transparent;\n  border-top-color: #667eea !important;\n  border-left-color: #764ba2 !important;\n  border-radius: 50%;\n  animation: nprogress-spinner 400ms linear infinite;\n}\n\n@keyframes nprogress-spinner {\n  0% {\n    transform: rotate(0deg);\n  }\n  100% {\n    transform: rotate(360deg);\n  }\n}\n\n/* 页面过渡动画 */\n@keyframes pageTransition {\n  from {\n    opacity: 0;\n    transform: translateY(30px) scale(0.95);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0) scale(1);\n  }\n}\n\n.page-transition {\n  animation: pageTransition 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards;\n}\n\n/* 卡片悬停效果 */\n@keyframes cardHover {\n  0% {\n    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);\n  }\n  100% {\n    box-shadow: 0 12px 40px rgba(102, 126, 234, 0.2);\n  }\n}\n\n/* 波浪动画 */\n@keyframes wave {\n  0% {\n    transform: translateX(0) translateZ(0) scaleY(1);\n  }\n  50% {\n    transform: translateX(-25%) translateZ(0) scaleY(0.55);\n  }\n  100% {\n    transform: translateX(-50%) translateZ(0) scaleY(1);\n  }\n}\n\n/* 闪烁动画 */\n@keyframes shimmer {\n  0% {\n    background-position: -1000px 0;\n  }\n  100% {\n    background-position: 1000px 0;\n  }\n}\n\n.shimmer {\n  animation: shimmer 2s infinite;\n  background: linear-gradient(to right, #f6f7f8 4%, #edeef1 25%, #f6f7f8 36%);\n  background-size: 1000px 100%;\n}\n\n/* 浮动动画 */\n@keyframes float {\n  0%,\n  100% {\n    transform: translateY(0);\n  }\n  50% {\n    transform: translateY(-10px);\n  }\n}\n\n.float {\n  animation: float 3s ease-in-out infinite;\n}\n\n/* 光晕效果 */\n.glow {\n  box-shadow: 0 0 20px rgba(102, 126, 234, 0.4);\n  transition: box-shadow 0.3s ease;\n}\n\n.glow:hover {\n  box-shadow: 0 0 30px rgba(102, 126, 234, 0.6);\n}\n\n/* 渐变文字 */\n.gradient-text {\n  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n  -webkit-background-clip: text;\n  -webkit-text-fill-color: transparent;\n  background-clip: text;\n}\n\n/* 按钮点击效果 */\n.btn-click {\n  transition: all 0.2s ease;\n}\n\n.btn-click:active {\n  transform: scale(0.95);\n}\n\n/* Chrome, Safari, Edge */\n::-webkit-scrollbar {\n  display: none;\n  width: 0;\n  height: 0;\n  background: transparent;\n}\n\n/* Firefox */\n* {\n  scrollbar-width: none;\n}\n\n/* IE/Edge */\n* {\n  -ms-overflow-style: none;\n}\n\n/* 平滑滚动 */\n* {\n  scroll-behavior: smooth;\n}\n\n/* 禁用移动端点击高亮 */\n* {\n  -webkit-tap-highlight-color: transparent;\n}\n\n/* 文本选择样式 */\n::selection {\n  background: rgba(102, 126, 234, 0.3);\n  color: #334155;\n}\n\n::-moz-selection {\n  background: rgba(102, 126, 234, 0.3);\n  color: #334155;\n}\n"
  },
  {
    "path": "src/assets/css/gold.scss",
    "content": "/* 终端容器 */\n.terminal-container {\n  display: flex;\n  flex-direction: column;\n  min-height: 100vh;\n  background: linear-gradient(180deg, #0d0d12 0%, #0a0a0f 100%);\n}\n\n/* 顶部导航栏 */\n.top-header {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  padding: 12px 24px;\n  background: linear-gradient(90deg, #1a1a24 0%, #12121a 100%);\n  border-bottom: 1px solid #2a2a3a;\n}\n\n@media (max-width: 768px) {\n  .top-header {\n    padding: 10px 16px;\n  }\n}\n\n.header-left {\n  display: flex;\n  align-items: center;\n  gap: 24px;\n}\n\n@media (max-width: 768px) {\n  .header-left {\n    gap: 12px;\n  }\n}\n\n.logo {\n  display: flex;\n  align-items: center;\n  gap: 8px;\n}\n\n.logo-symbol {\n  font-size: 24px;\n  font-weight: 700;\n  color: #fbbf24;\n  background: linear-gradient(135deg, #fcd34d, #f59e0b);\n  background-clip: text;\n  -webkit-background-clip: text;\n  -webkit-text-fill-color: transparent;\n}\n\n.logo-text {\n  font-size: 14px;\n  font-weight: 600;\n  color: #888;\n  letter-spacing: 2px;\n}\n\n.market-status {\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  font-size: 12px;\n  color: #888;\n}\n\n.status-dot {\n  width: 8px;\n  height: 8px;\n  background: #22c55e;\n  border-radius: 50%;\n  animation: pulse 2s infinite;\n}\n\n@keyframes pulse {\n  0%, 100% { opacity: 1; }\n  50% { opacity: 0.5; }\n}\n\n.header-center {\n  font-size: 14px;\n  color: #888;\n  font-family: 'SF Mono', monospace;\n}\n\n.current-time {\n  color: #fbbf24;\n}\n\n.header-right {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n}\n\n.refresh-btn {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  width: 36px;\n  height: 36px;\n  background: rgba(251, 191, 36, 0.1);\n  border: 1px solid rgba(251, 191, 36, 0.3);\n  border-radius: 8px;\n  color: #fbbf24;\n  cursor: pointer;\n  transition: all 0.2s;\n}\n\n.refresh-btn:hover {\n  background: rgba(251, 191, 36, 0.2);\n  transform: rotate(180deg);\n}\n\n/* 主内容区域 */\n.main-content-new {\n  display: flex;\n  flex-direction: column;\n  gap: 16px;\n  padding: 16px 24px;\n  flex: 1;\n  min-height: 0;\n  overflow-y: auto;\n}\n\n@media (max-width: 768px) {\n  .main-content-new {\n    padding: 12px 16px;\n    gap: 12px;\n  }\n}\n\n/* 价格卡片行 */\n.price-cards-row {\n  display: grid;\n  grid-template-columns: 1fr 1fr;\n  gap: 16px;\n}\n\n@media (max-width: 768px) {\n  .price-cards-row {\n    grid-template-columns: 1fr;\n    gap: 12px;\n  }\n}\n\n/* 新价格卡片样式 */\n.price-card-new {\n  display: flex;\n  align-items: flex-start;\n  gap: 16px;\n  background: linear-gradient(135deg, #1a1a24 0%, #14141c 100%);\n  border: 1px solid #2a2a3a;\n  border-radius: 12px;\n  padding: 20px;\n  transition: all 0.3s ease;\n}\n\n.price-card-new:hover {\n  border-color: #fbbf24;\n  box-shadow: 0 0 20px rgba(251, 191, 36, 0.1);\n}\n\n.price-card-new.domestic {\n  border-color: #3a2a2a;\n}\n\n.price-card-new.domestic:hover {\n  border-color: #ef4444;\n  box-shadow: 0 0 20px rgba(239, 68, 68, 0.1);\n}\n\n/* 移动端价格卡片适配 */\n@media (max-width: 768px) {\n  .price-card-new {\n    flex-wrap: wrap;\n    padding: 16px;\n    gap: 12px;\n  }\n\n  .card-icon {\n    width: 40px;\n    height: 40px;\n  }\n\n  .card-info {\n    flex: 1;\n    min-width: 0;\n  }\n\n  .card-price {\n    font-size: 24px;\n  }\n\n  .card-extra {\n    width: 100%;\n    padding-left: 0;\n    border-left: none;\n    border-top: 1px solid #2a2a3a;\n    padding-top: 12px;\n    flex-direction: row;\n    flex-wrap: wrap;\n    gap: 8px;\n  }\n\n  .extra-item {\n    flex: 1 1 calc(50% - 4px);\n    min-width: 120px;\n  }\n}\n\n.card-icon {\n  width: 48px;\n  height: 48px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  border-radius: 12px;\n  flex-shrink: 0;\n}\n\n.card-icon.intl {\n  background: rgba(251, 191, 36, 0.15);\n  color: #fbbf24;\n}\n\n.card-icon.cn {\n  background: rgba(239, 68, 68, 0.15);\n  color: #ef4444;\n}\n\n.card-info {\n  flex: 1;\n}\n\n.card-label {\n  font-size: 12px;\n  color: #888;\n  margin-bottom: 4px;\n  display: flex;\n  align-items: center;\n  gap: 8px;\n}\n\n.card-label .badge {\n  font-size: 9px;\n  padding: 2px 6px;\n  background: rgba(251, 191, 36, 0.2);\n  color: #fbbf24;\n  border-radius: 4px;\n  font-weight: 600;\n}\n\n.card-label .badge.cn {\n  background: rgba(239, 68, 68, 0.2);\n  color: #ef4444;\n}\n\n.card-price {\n  font-size: 28px;\n  font-weight: 700;\n  font-family: 'SF Mono', monospace;\n  margin-bottom: 2px;\n}\n\n.card-price.up { color: #22c55e; }\n.card-price.down { color: #ef4444; }\n\n.card-change {\n  font-size: 13px;\n  font-family: 'SF Mono', monospace;\n}\n\n.card-change.up { color: #22c55e; }\n.card-change.down { color: #ef4444; }\n\n.card-extra {\n  display: flex;\n  flex-direction: column;\n  gap: 4px;\n  padding-left: 16px;\n  border-left: 1px solid #2a2a3a;\n}\n\n.extra-item {\n  display: flex;\n  justify-content: space-between;\n  gap: 16px;\n  word-break: keep-all;\n  font-size: 11px;\n}\n\n.extra-item span:first-child { color: #666; }\n.extra-item span:last-child { color: #aaa; font-family: 'SF Mono', monospace; }\n.extra-item .up { color: #22c55e; }\n.extra-item .down { color: #ef4444; }\n\n/* 双图表区域 */\n.charts-row {\n  display: grid;\n  grid-template-columns: 1fr 1fr;\n  gap: 16px;\n}\n\n@media (max-width: 1200px) {\n  .charts-row {\n    grid-template-columns: 1fr;\n  }\n}\n\n.chart-card {\n  background: linear-gradient(135deg, #1a1a24 0%, #14141c 100%);\n  border: 1px solid #2a2a3a;\n  border-radius: 12px;\n  overflow: hidden;\n}\n\n.chart-card-header {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  padding: 16px 20px;\n  border-bottom: 1px solid #2a2a3a;\n}\n\n.chart-card-title {\n  display: flex;\n  align-items: center;\n  gap: 10px;\n}\n\n.chart-card-title h3 {\n  font-size: 14px;\n  font-weight: 600;\n  color: #fff;\n  margin: 0;\n}\n\n.title-icon {\n  font-size: 10px;\n}\n\n.title-icon.intl { color: #fbbf24; }\n.title-icon.cn { color: #ef4444; }\n\n.chart-source {\n  font-size: 10px;\n  color: #555;\n  text-transform: uppercase;\n}\n\n.period-selector {\n  display: flex;\n  gap: 4px;\n  background: #0a0a0f;\n  padding: 4px;\n  border-radius: 6px;\n}\n\n.period-selector .period-btn {\n  padding: 4px 10px;\n  font-size: 11px;\n  font-weight: 500;\n  color: #666;\n  background: transparent;\n  border: none;\n  border-radius: 4px;\n  cursor: pointer;\n  transition: all 0.2s;\n}\n\n.period-selector .period-btn:hover {\n  color: #fff;\n}\n\n.period-selector .period-btn.active {\n  background: linear-gradient(135deg, #fbbf24, #f59e0b);\n  color: #000;\n}\n\n.chart-area {\n  height: 280px;\n  padding: 12px;\n}\n\n.chart-iframe-container {\n  height: 420px;\n  width: 100%;\n  overflow: hidden;\n  background: #0a0a0f;\n  position: relative;\n}\n\n.charts-row.single-chart {\n  display: block;\n}\n\n.chart-card.full-width {\n  width: 100%;\n  max-width: 100%;\n}\n\n/* K线图区域样式 */\n.chart-section {\n  background: linear-gradient(135deg, #1a1a24 0%, #14141c 100%);\n  border-radius: 16px;\n  padding: 20px;\n  margin: 20px 0;\n  border: 1px solid rgba(251, 191, 36, 0.1);\n}\n\n@media (max-width: 768px) {\n  .chart-section {\n    border-radius: 12px;\n    padding: 12px;\n    margin: 12px 0;\n  }\n}\n\n.chart-header {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  margin-bottom: 16px;\n  flex-wrap: wrap;\n  gap: 12px;\n}\n\n@media (max-width: 768px) {\n  .chart-header {\n    margin-bottom: 12px;\n  }\n\n  .chart-header h3 {\n    font-size: 14px;\n  }\n\n  .chart-source {\n    font-size: 10px;\n  }\n}\n\n.chart-header h3 {\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  color: #fbbf24;\n  font-size: 16px;\n  font-weight: 600;\n  margin: 0;\n}\n\n.period-selector {\n  display: flex;\n  gap: 6px;\n}\n\n.period-selector button {\n  padding: 6px 12px;\n  background: rgba(251, 191, 36, 0.1);\n  border: 1px solid rgba(251, 191, 36, 0.2);\n  border-radius: 6px;\n  color: #fbbf24;\n  font-size: 13px;\n  cursor: pointer;\n  transition: all 0.3s ease;\n}\n\n.period-selector button:hover {\n  background: rgba(251, 191, 36, 0.2);\n  border-color: rgba(251, 191, 36, 0.4);\n}\n\n.period-selector button.active {\n  background: #fbbf24;\n  color: #000;\n  border-color: #fbbf24;\n}\n\n.chart-container {\n  background: #0a0a0f;\n  border-radius: 10px;\n  padding: 12px;\n  border: 1px solid rgba(251, 191, 36, 0.1);\n  overflow: hidden;\n}\n\n.chart-canvas {\n  width: 100%;\n  height: 450px;\n  min-height: 300px;\n}\n\n/* TradingView容器 */\n.tradingview-container {\n  height: 450px;\n  padding: 0;\n}\n\n@media (max-width: 768px) {\n  .tradingview-container {\n    height: 350px;\n  }\n}\n\n.chart-iframe {\n  width: 100%;\n  height: 100%;\n  border: none;\n}\n\n.chart-source {\n  color: #9ca3af;\n  font-size: 12px;\n}\n\n/* 电脑端/手机端显示控制 */\n.desktop-only {\n  display: block !important;\n}\n\n/* 手机端适配 */\n@media (max-width: 768px) {  \n  .chart-section {\n    padding: 12px;\n    margin: 12px 0;\n    border-radius: 12px;\n  }\n}\n\n/* 平板端适配 */\n@media (min-width: 769px) and (max-width: 1024px) {\n  .tradingview-container {\n    height: 380px;\n  }\n}\n\n.chart-iframe {\n  width: 100%;\n  height: 100%;\n  border: none;\n}\n\n/* Markdown样式 */\n.markdown-body h2 {\n  font-size: 18px;\n  font-weight: 700;\n  color: #fbbf24;\n  margin: 20px 0 12px 0;\n  padding-bottom: 8px;\n  border-bottom: 1px solid #3a3a4a;\n}\n\n.markdown-body h3 {\n  font-size: 15px;\n  font-weight: 600;\n  color: #22c55e;\n  margin: 16px 0 10px 0;\n}\n\n.markdown-body p {\n  margin: 8px 0;\n  color: #ccc;\n}\n\n.markdown-body strong {\n  color: #fff;\n  font-weight: 600;\n}\n\n.markdown-body ul, .markdown-body ol {\n  margin: 8px 0;\n  padding-left: 20px;\n}\n\n.markdown-body li {\n  margin: 6px 0;\n  color: #bbb;\n}\n\n.markdown-body li::marker {\n  color: #fbbf24;\n}\n\n.markdown-body hr {\n  border: none;\n  border-top: 1px dashed #3a3a4a;\n  margin: 16px 0;\n}\n\n.markdown-body code {\n  background: rgba(251, 191, 36, 0.1);\n  color: #fbbf24;\n  padding: 2px 6px;\n  border-radius: 4px;\n  font-size: 12px;\n}\n\n.markdown-body blockquote {\n  border-left: 3px solid #fbbf24;\n  padding-left: 12px;\n  margin: 12px 0;\n  color: #999;\n  font-style: italic;\n}\n\n/* 价格面板 */\n.price-panel {\n  display: flex;\n  flex-direction: column;\n  gap: 16px;\n}\n\n.price-card {\n  background: linear-gradient(135deg, #1a1a24 0%, #14141c 100%);\n  border: 1px solid #2a2a3a;\n  border-radius: 12px;\n  padding: 16px;\n}\n\n.price-card.domestic {\n  border-color: #3a2a1a;\n}\n\n.card-header {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  margin-bottom: 12px;\n}\n\n.card-symbol {\n  font-size: 16px;\n  font-weight: 700;\n  color: #fff;\n}\n\n.card-badge {\n  font-size: 10px;\n  padding: 2px 8px;\n  background: rgba(251, 191, 36, 0.2);\n  color: #fbbf24;\n  border-radius: 4px;\n  font-weight: 600;\n}\n\n.card-badge.cn {\n  background: rgba(239, 68, 68, 0.2);\n  color: #ef4444;\n}\n\n.price-main {\n  margin-bottom: 8px;\n}\n\n.price-value {\n  font-size: 32px;\n  font-weight: 700;\n  font-family: 'SF Mono', monospace;\n}\n\n.price-value.up {\n  color: #22c55e;\n}\n\n.price-value.down {\n  color: #ef4444;\n}\n\n.price-change {\n  display: flex;\n  gap: 8px;\n  font-size: 14px;\n  font-family: 'SF Mono', monospace;\n  margin-bottom: 12px;\n}\n\n.price-change.up {\n  color: #22c55e;\n}\n\n.price-change.down {\n  color: #ef4444;\n}\n\n.price-details {\n  border-top: 1px solid #2a2a3a;\n  padding-top: 12px;\n}\n\n.detail-row {\n  display: flex;\n  justify-content: space-between;\n  font-size: 12px;\n  padding: 4px 0;\n  color: #888;\n}\n\n.detail-row span:last-child {\n  color: #ccc;\n  font-family: 'SF Mono', monospace;\n}\n\n.detail-row .up {\n  color: #22c55e;\n}\n\n.detail-row .down {\n  color: #ef4444;\n}\n\n.price-source {\n  margin-top: 12px;\n  font-size: 10px;\n  color: #555;\n  text-transform: uppercase;\n}\n\n/* 图表区域 */\n.chart-section {\n  background: linear-gradient(135deg, #1a1a24 0%, #14141c 100%);\n  border: 1px solid #2a2a3a;\n  border-radius: 12px;\n  display: flex;\n  flex-direction: column;\n  overflow: hidden;\n}\n\n.chart-header {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  padding: 16px;\n  border-bottom: 1px solid #2a2a3a;\n}\n\n.chart-title h2 {\n  font-size: 16px;\n  font-weight: 600;\n  color: #fff;\n  margin: 0;\n}\n\n.chart-subtitle {\n  font-size: 12px;\n  color: #666;\n}\n\n.chart-controls {\n  display: flex;\n  gap: 12px;\n}\n\n.period-tabs {\n  display: flex;\n  gap: 4px;\n  background: #0a0a0f;\n  padding: 4px;\n  border-radius: 8px;\n}\n\n.period-btn {\n  padding: 6px 12px;\n  font-size: 12px;\n  font-weight: 500;\n  color: #888;\n  background: transparent;\n  border: none;\n  border-radius: 6px;\n  cursor: pointer;\n  transition: all 0.2s;\n}\n\n.period-btn:hover {\n  color: #fff;\n}\n\n.period-btn.active {\n  background: linear-gradient(135deg, #fbbf24, #f59e0b);\n  color: #000;\n}\n\n.chart-container {\n  flex: 1;\n  min-height: 400px;\n  padding: 8px;\n}\n\n/* 水印样式 */\n.watermark-container {\n  position: fixed;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  pointer-events: none;\n  z-index: 9999;\n  overflow: hidden;\n  opacity: 0.08;\n}\n\n.watermark-content {\n  position: absolute;\n  top: -50%;\n  left: -50%;\n  width: 200%;\n  height: 200%;\n  display: flex;\n  flex-wrap: wrap;\n  transform: rotate(-30deg);\n}\n\n.watermark-item {\n  width: 300px;\n  height: 200px;\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n  align-items: center;\n  font-family: 'SF Mono', monospace;\n  font-size: 14px;\n  color: #fbbf24;\n  font-weight: 600;\n  gap: 4px;\n}\n\n/* 订阅图标按钮 */\n.subscribe-icon-btn {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  width: 24px;\n  height: 24px;\n  margin-left: 8px;\n  background: rgba(251, 191, 36, 0.15);\n  border: 1px solid rgba(251, 191, 36, 0.4);\n  border-radius: 6px;\n  color: #fbbf24;\n  cursor: pointer;\n  transition: all 0.3s ease;\n}\n\n.subscribe-icon-btn:hover {\n  background: rgba(251, 191, 36, 0.25);\n  border-color: #fbbf24;\n  transform: scale(1.1);\n  box-shadow: 0 0 12px rgba(251, 191, 36, 0.3);\n}\n\n.subscribe-icon-btn:active {\n  transform: scale(0.95);\n}\n\n/* Loading 遮罩 */\n.loading-overlay {\n  position: fixed;\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  background: rgba(13, 13, 18, 0.9);\n  backdrop-filter: blur(8px);\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  gap: 16px;\n  z-index: 10000;\n  animation: fadeIn 0.3s ease;\n}\n\n@keyframes fadeIn {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n.loading-overlay .ant-spin {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  gap: 16px;\n}\n\n.loading-overlay .ant-spin-text {\n  color: #fbbf24;\n  font-size: 14px;\n  font-weight: 500;\n  margin-top: 12px;\n}\n\n.loading-text {\n  color: #fbbf24;\n  font-size: 16px;\n  font-weight: 500;\n  letter-spacing: 1px;\n}\n\n/* 自定义 Spin 颜色为金色 */\n.loading-overlay .ant-spin-dot-item {\n  background-color: #fbbf24 !important;\n}\n"
  },
  {
    "path": "src/assets/css/markdown.css",
    "content": "#chat-markdown ol {\n  padding-left: 2em;\n}\n#chat-markdown .hljs {\n  border-radius: 5px;\n  padding: 50px 15px 15px 15px;\n  position: relative;\n  overflow: auto;\n  background: #292b33;\n}\n#chat-markdown .hljs::-webkit-scrollbar {\n  height: 9px;\n}\n#chat-markdown .hljs::-webkit-scrollbar-track {\n  background-color: #fff;\n}\n\n#chat-markdown .hljs::-webkit-scrollbar-thumb {\n  background-color: #d8d8d8;\n  border-radius: 5px;\n}\n#chat-markdown .hljs .code-header {\n  display: flex;\n  justify-content: space-between;\n  height: 35px;\n  width: 100%;\n  background-color: rgb(50, 55, 65);\n  position: absolute;\n  left: 0;\n  top: 0;\n  border-radius: 5px 5px 0 0;\n  font-family: SFMono-Regular,Menlo,Monaco,Consolas,\"Liberation Mono\",\"Courier New\",monospace;\n}\n#chat-markdown .hljs .code-header .copy {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  cursor: pointer;\n  padding-right: 10px;\n  font-size: 12px;\n}\n#chat-markdown .hljs .code-header .copy img {\n  height: 19px;\n  width: 19px;\n}\n#chat-markdown .hljs .code-header .copy p {\n  color: #fff;\n}\n#chat-markdown .hljs .code-header .lang {\n  font-size: 12px;\n  height: 35px;\n  cursor: pointer;\n  color: #fff;\n  line-height: 35px;\n  padding-left: 15px;\n}\n#chat-markdown .hljs code {\n  font-family: SFMono-Regular,Menlo,Monaco,Consolas,monospace !important;\n}\n#chat-markdown .hljs code {\n  color: rgb(212, 212, 212);\n}\n#chat-markdown .hljs code span {\n  color: rgb(212, 212, 212);\n}\n#chat-markdown .hljs code .hljs-comment {\n  color: rgb(106, 153, 85);\n}\n#chat-markdown .hljs code .hljs-keyword {\n  color: rgb(86, 156, 214);\n}\n#chat-markdown .hljs code .function_ {\n  color: rgb(220, 220, 170);\n}\n#chat-markdown .hljs code .hljs-params {\n  color: rgb(156, 220, 254);\n}\n#chat-markdown .hljs code .class_ {\n  color: rgb(78, 201, 176);\n}"
  },
  {
    "path": "src/components/ClickEffect.tsx",
    "content": "import React, { useEffect, useCallback } from 'react'\nimport styled from 'styled-components'\n\n// 社会主义核心价值观词语\nconst WORDS = [\n  '富强',\n  '民主',\n  '文明',\n  '和谐',\n  '自由',\n  '平等',\n  '公正',\n  '法治',\n  '爱国',\n  '敬业',\n  '诚信',\n  '友善'\n]\n\n// 浮动文字样式\nconst FloatingText = styled.b<{ x: number; y: number; color: string; opacity: number; scale: number }>`\n  position: fixed;\n  left: ${props => props.x}px;\n  top: ${props => props.y}px;\n  font-size: 16px;\n  cursor: default;\n  color: ${props => props.color};\n  opacity: ${props => props.opacity};\n  transform: scale(${props => props.scale});\n  pointer-events: none;\n  user-select: none;\n  transition: none;\n  z-index: 9999;\n  font-weight: 500;\n  text-shadow: 0 0 2px rgba(255, 255, 255, 0.5);\n`\n\ninterface WordInstance {\n  id: number\n  text: string\n  x: number\n  y: number\n  color: string\n  opacity: number\n  scale: number\n}\n\n// 生成随机颜色\nconst randomColor = (): string => {\n  const r = Math.floor(Math.random() * 255)\n  const g = Math.floor(Math.random() * 255)\n  const b = Math.floor(Math.random() * 255)\n  return `rgb(${r}, ${g}, ${b})`\n}\n\nconst ClickEffect: React.FC = () => {\n  const [words, setWords] = React.useState<WordInstance[]>([])\n  const wordIndexRef = React.useRef(0)\n  const animationFrameRef = React.useRef<number>()\n\n  // 处理点击事件\n  const handleClick = useCallback((event: MouseEvent) => {\n    const fontSize = 16\n    const x = event.clientX - fontSize / 2\n    const y = event.clientY - fontSize\n\n    const newWord: WordInstance = {\n      id: Date.now() + Math.random(),\n      text: WORDS[wordIndexRef.current],\n      x,\n      y,\n      color: randomColor(),\n      opacity: 1,\n      scale: 1.2\n    }\n\n    // 更新词语索引\n    wordIndexRef.current = (wordIndexRef.current + 1) % WORDS.length\n\n    setWords(prev => [...prev, newWord])\n  }, [])\n\n  // 动画更新循环\n  useEffect(() => {\n    const updateWords = () => {\n      setWords(prev => {\n        const updated = prev.map(word => ({\n          ...word,\n          y: word.y - 1, // 向上移动\n          opacity: word.opacity - 0.016, // 逐渐消失\n          scale: word.scale + 0.002 // 逐渐放大\n        }))\n\n        // 移除已经完全透明的词语\n        const visible = updated.filter(word => word.opacity > 0)\n\n        return visible\n      })\n\n      animationFrameRef.current = requestAnimationFrame(updateWords)\n    }\n\n    animationFrameRef.current = requestAnimationFrame(updateWords)\n\n    return () => {\n      if (animationFrameRef.current) {\n        cancelAnimationFrame(animationFrameRef.current)\n      }\n    }\n  }, [])\n\n  // 添加全局点击事件监听\n  useEffect(() => {\n    window.addEventListener('click', handleClick)\n\n    return () => {\n      window.removeEventListener('click', handleClick)\n    }\n  }, [handleClick])\n\n  return (\n    <>\n      {words.map(word => (\n        <FloatingText\n          key={word.id}\n          x={word.x}\n          y={word.y}\n          color={word.color}\n          opacity={word.opacity}\n          scale={word.scale}\n        >\n          {word.text}\n        </FloatingText>\n      ))}\n    </>\n  )\n}\n\nexport default ClickEffect\n"
  },
  {
    "path": "src/components/Footer.tsx",
    "content": "import React from 'react'\nimport { Typography } from 'antd'\nimport { useTranslation } from 'react-i18next'\nimport styled from 'styled-components'\n\nconst { Text } = Typography\n\nconst FooterContainer = styled.footer`\n  background: #000;\n  color: #fff;\n  padding: 20px;\n  margin-top: auto;\n`\n\nconst FooterContent = styled.div`\n  max-width: 1200px;\n  margin: 0 auto;\n  text-align: center;\n\n  @media (min-width: 768px) {\n    text-align: left;\n  }\n`\n\nconst Footer: React.FC = () => {\n  const { t } = useTranslation()\n\n  return (\n    <FooterContainer>\n      <FooterContent>\n        <div style={{ textAlign: 'center', display: 'flex', flexDirection: 'column' }}>\n          <Text style={{ color: 'rgba(255, 255, 255, 0.8)' }}>\n             <span id=\"busuanzi_container_site_pv\">{t('common.siteVisits')}<span id=\"busuanzi_value_site_pv\">258341</span>{t('common.visitsUnit')}</span>\n          </Text>\n          <Text style={{ color: 'rgba(255, 255, 255, 0.8)', marginLeft: '20px' }}>\n             <span>{t('common.copyright')}</span>\n          </Text>\n        </div>\n      </FooterContent>\n    </FooterContainer>\n  )\n}\n\nexport default Footer\n"
  },
  {
    "path": "src/components/HeartBeat.tsx",
    "content": "import React, { useEffect, useRef } from 'react'\nimport * as THREE from 'three'\nimport { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js'\nimport { MeshSurfaceSampler } from 'three-stdlib'\nimport { TrackballControls } from 'three-stdlib'\nimport { createNoise4D } from 'simplex-noise'\nimport gsap from 'gsap'\nimport styled from 'styled-components'\n\nconst HeartBeatContainer = styled.div`\n  position: fixed;\n  top: 0;\n  left: 0;\n  width: 100vw;\n  height: 100vh;\n  background: #000000;\n  z-index: 9999;\n`\n\ninterface HeartBeatProps {\n  onComplete: () => void\n}\n\nconst HeartBeat: React.FC<HeartBeatProps> = ({ onComplete }) => {\n  const containerRef = useRef<HTMLDivElement>(null)\n  const timerRef = useRef<ReturnType<typeof setTimeout>>()\n\n  useEffect(() => {\n    if (!containerRef.current) return\n\n    console.log('初始化粒子心跳效果')\n\n    // 创建场景\n    const scene = new THREE.Scene()\n\n    // 创建相机\n    const camera = new THREE.PerspectiveCamera(\n      75,\n      window.innerWidth / window.innerHeight,\n      0.1,\n      1000\n    )\n    camera.position.z = 1.8\n\n    // 创建渲染器\n    const renderer = new THREE.WebGLRenderer({ antialias: true })\n    renderer.setClearColor(new THREE.Color('rgb(0,0,0)'))\n    renderer.setSize(window.innerWidth, window.innerHeight)\n    renderer.setPixelRatio(window.devicePixelRatio)\n    containerRef.current.appendChild(renderer.domElement)\n\n    // 轨迹球控制器\n    const controls = new TrackballControls(camera, renderer.domElement)\n    controls.noPan = true\n    controls.maxDistance = 3\n    controls.minDistance = 0.7\n\n    // 创建物体组\n    const group = new THREE.Group()\n    scene.add(group)\n\n    let heart: any = null\n    let sampler: any = null\n    let originHeart: Float32Array | null = null\n\n    // 调色板\n    const palette = [\n      new THREE.Color('#ffd4ee'),\n      new THREE.Color('#ff77fc'),\n      new THREE.Color('#ff77ae'),\n      new THREE.Color('#ff1775')\n    ]\n\n    // 简单噪声\n    const simplex = createNoise4D()\n    const pos = new THREE.Vector3()\n\n    // 粒子类\n    class SparkPoint {\n      color: THREE.Color\n      rand: number\n      pos: THREE.Vector3\n      one: THREE.Vector3 | null\n      two: THREE.Vector3 | null\n\n      constructor() {\n        if (sampler) {\n          sampler.sample(pos)\n        }\n        this.color = palette[Math.floor(Math.random() * palette.length)]\n        this.rand = Math.random() * 0.03\n        this.pos = pos.clone()\n        this.one = null\n        this.two = null\n      }\n\n      update(beatValue: number) {\n        const noise =\n          simplex(pos.x * 1, pos.y * 1, pos.z * 1, 0.1) + 1.5\n        const noise2 =\n          simplex(pos.x * 500, pos.y * 500, pos.z * 500, 1) + 1\n        this.one = this.pos.clone().multiplyScalar(1.01 + noise * 0.15 * beatValue)\n        this.two = this.pos\n          .clone()\n          .multiplyScalar(1 + noise2 * 1 * (beatValue + 0.3) - beatValue * 1.2)\n      }\n    }\n\n    const spikes: SparkPoint[] = []\n    let positions: number[] = []\n    let colors: number[] = []\n\n    // 粒子几何体和材质\n    const geometry = new THREE.BufferGeometry()\n    const material = new THREE.PointsMaterial({\n      vertexColors: true,\n      size: 0.009\n    })\n    const particles = new THREE.Points(geometry, material)\n    group.add(particles)\n\n    // 心跳动画变量\n    const beat = { a: 0 }\n\n    // OBJ加载器\n    const loader = new OBJLoader()\n    loader.load(\n      '/model/heartBeat.obj',\n      (obj) => {\n        console.log('模型加载成功')\n        heart = (obj as any).children[0]\n        heart.geometry.rotateX(-Math.PI * 0.5)\n        heart.geometry.scale(0.04, 0.04, 0.04)\n        heart.geometry.translate(0, -0.4, 0)\n        group.add(heart)\n\n        // 基础网格材质\n        heart.material = new THREE.MeshBasicMaterial({\n          color: new THREE.Color('rgb(0,0,0)')\n        })\n        originHeart = new Float32Array(heart.geometry.attributes.position.array)\n\n        // 创建表面采样器\n        sampler = new MeshSurfaceSampler(heart).build()\n\n        // 初始化粒子\n        init()\n\n        // 设置心跳动画\n        gsap\n          .timeline({\n            repeat: -1,\n            repeatDelay: 0.3\n          })\n          .to(beat, {\n            a: 0.5,\n            duration: 0.6,\n            ease: 'power2.in'\n          })\n          .to(beat, {\n            a: 0.0,\n            duration: 0.6,\n            ease: 'power3.out'\n          })\n\n        // 开始渲染循环\n        renderer.setAnimationLoop(render)\n\n        // 模型加载完成后，开始3秒计时\n        console.log('设置3秒定时器')\n        timerRef.current = setTimeout(() => {\n          console.log('3秒到达，调用 onComplete')\n          renderer.setAnimationLoop(null) // 停止渲染循环\n          onComplete()\n        }, 3000)\n      },\n      (progress) => {\n        console.log('加载进度:', Math.round((progress.loaded / progress.total) * 100) + '%')\n      },\n      (error) => {\n        console.error('模型加载失败:', error)\n      }\n    )\n\n    function init() {\n      positions = []\n      colors = []\n      for (let i = 0; i < 10000; i++) {\n        const g = new SparkPoint()\n        spikes.push(g)\n      }\n    }\n\n    const maxZ = 0.23\n    const rateZ = 0.5\n\n    function render(a: number) {\n      positions = []\n      colors = []\n      spikes.forEach((g) => {\n        g.update(beat.a)\n        const rand = g.rand\n        const color = g.color\n        if (maxZ * rateZ + rand > (g.one?.z || 0) && (g.one?.z || 0) > -maxZ * rateZ - rand) {\n          positions.push(g.one!.x, g.one!.y, g.one!.z)\n          colors.push(color.r, color.g, color.b)\n        }\n        if (maxZ * rateZ + rand * 2 > (g.one?.z || 0) && (g.one?.z || 0) > -maxZ * rateZ - rand * 2) {\n          positions.push(g.two!.x, g.two!.y, g.two!.z)\n          colors.push(color.r, color.g, color.b)\n        }\n      })\n\n      geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(positions), 3))\n      geometry.setAttribute('color', new THREE.BufferAttribute(new Float32Array(colors), 3))\n\n      if (heart && originHeart) {\n        const vs = heart.geometry.attributes.position.array\n        for (let i = 0; i < vs.length; i += 3) {\n          const v = new THREE.Vector3(originHeart[i], originHeart[i + 1], originHeart[i + 2])\n          const noise = simplex(originHeart[i] * 1.5, originHeart[i + 1] * 1.5, originHeart[i + 2] * 1.5, a * 0.0005) + 1\n          v.multiplyScalar(0 + noise * 0.15 * beat.a)\n          vs[i] = v.x\n          vs[i + 1] = v.y\n          vs[i + 2] = v.z\n        }\n        heart.geometry.attributes.position.needsUpdate = true\n      }\n\n      controls.update()\n      renderer.render(scene, camera)\n    }\n\n    // 窗口大小调整\n    const handleResize = () => {\n      camera.aspect = window.innerWidth / window.innerHeight\n      camera.updateProjectionMatrix()\n      renderer.setSize(window.innerWidth, window.innerHeight)\n    }\n    window.addEventListener('resize', handleResize)\n\n    // 清理\n    return () => {\n      console.log('清理 HeartBeat 组件')\n      if (timerRef.current) {\n        clearTimeout(timerRef.current)\n      }\n      window.removeEventListener('resize', handleResize)\n      renderer.setAnimationLoop(null)\n      if (containerRef.current && renderer.domElement.parentNode === containerRef.current) {\n        containerRef.current.removeChild(renderer.domElement)\n      }\n      renderer.dispose()\n      scene.clear()\n    }\n  }, [onComplete])\n\n  return <HeartBeatContainer ref={containerRef} />\n}\n\nexport default HeartBeat\n"
  },
  {
    "path": "src/components/Live2DDashboard.tsx",
    "content": "import React, { useEffect, useRef, useState } from 'react'\nimport styled from 'styled-components'\n\n// 全局变量\nlet isGlobalStyleAdded = false\n// 全局初始化状态\nlet isInitializing = false\n// Live2D 实例\nlet oml2dInstance: any = null\n\nconst Live2DContainer = styled.div<{ $visible: boolean }>`\n  position: fixed;\n  bottom: 20px;\n  right: 20px;\n  z-index: 9999;\n  width: 250px;\n  height: 350px;\n  opacity: ${props => props.$visible ? 1 : 0};\n  transition: opacity 0.3s ease;\n  pointer-events: ${props => props.$visible ? 'auto' : 'none'};\n\n  #oml2d-container,\n  #oml2d-container * {\n    pointer-events: auto !important;\n  }\n\n  @media (max-width: 768px) {\n    width: 200px;\n    height: 280px;\n    bottom: 10px;\n    right: 10px;\n  }\n`\n\nconst LoadingText = styled.div`\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n  color: #667eea;\n  font-size: 12px;\n  text-align: center;\n  pointer-events: none;\n`\n\ninterface Live2DDashboardProps {\n  isVisible: boolean\n}\n\nconst Live2DDashboard: React.FC<Live2DDashboardProps> = ({ isVisible }) => {\n  const containerRef = useRef<HTMLDivElement>(null)\n  const [loaded, setLoaded] = useState(false)\n  const initRef = useRef(false)\n\n  useEffect(() => {\n    if (initRef.current || isInitializing) {\n      console.log('Live2D 已初始化或正在初始化...')\n    }\n\n    // 标记全局初始化状态\n    isInitializing = true\n    let isMounted = true\n\n    // 添加全局样式覆盖\n    if (!isGlobalStyleAdded) {\n      const styleId = 'oml2d-override-style'\n      if (!document.getElementById(styleId)) {\n        const style = document.createElement('style')\n        style.id = styleId\n        style.innerHTML = `\n          #oml2d-stage {\n            left: auto !important;\n            right: 0 !important;\n          }\n        `\n        document.head.appendChild(style)\n      }\n      isGlobalStyleAdded = true\n    }\n\n    const initLive2D = async () => {\n      try {\n        console.log('开始初始化 Live2D 看板娘...')\n\n        // 动态导入 oh-my-live2d\n        const { loadOml2d } = await import('oh-my-live2d')\n\n        if (!isMounted || !containerRef.current) {\n          console.log('组件已卸载或容器不存在')\n          isInitializing = false\n          return\n        }\n\n        // 创建容器\n        const container = document.createElement('div')\n        container.id = 'oml2d-container'\n        container.style.cssText = 'width: 100%; height: 100%;'\n        containerRef.current.appendChild(container)\n\n        console.log('加载 Live2D 模型...')\n        // 初始化 Live2D 并保存实例\n        oml2dInstance = await loadOml2d({\n          models: [\n            {\n              path: 'https://model.hacxy.cn/HK416-2-normal/model.json',\n              position: [0, 50],\n              scale: 0.08,\n              stageStyle: {\n                height: 450\n              }\n            }\n          ]\n        })\n\n        console.log('Live2D 模型加载完成')\n\n        // 初始化后强制修改样式\n        setTimeout(() => {\n          const stage = document.getElementById('oml2d-stage')\n          if (stage) {\n            stage.style.setProperty('left', 'auto', 'important')\n            stage.style.setProperty('right', '0', 'important')\n            console.log('oml2d-stage 样式已修改')\n          }\n        }, 100)\n\n        console.log('Live2D 看板娘初始化成功')\n        initRef.current = true\n\n        if (isMounted) {\n          setLoaded(true)\n          console.log('看板娘已设置为可见')\n        }\n\n      } catch (error) {\n        console.error('Live2D 初始化失败:', error)\n        // 初始化失败时重置标记，允许重试\n        isInitializing = false\n        initRef.current = false\n      }\n    }\n\n    initLive2D()\n\n    return () => {\n      isMounted = false\n\n      // 组件卸载时销毁 Live2D 实例并清理 DOM\n      if (oml2dInstance) {\n        console.log('组件卸载，销毁 Live2D 实例')\n        try {\n          if (oml2dInstance.destroy) {\n            oml2dInstance.destroy()\n          }\n        } catch (error) {\n          console.error('销毁 Live2D 失败:', error)\n        }\n        oml2dInstance = null\n      }\n\n      // 移除所有 oml2d 相关的 DOM 元素\n      // 先移除 canvas 等子元素\n      const canvases = document.querySelectorAll('#oml2d-stage canvas')\n      canvases.forEach(canvas => canvas.remove())\n\n      // 再移除 stage 元素\n      const stage = document.getElementById('oml2d-stage')\n      if (stage) {\n        stage.remove()\n        console.log('已移除 oml2d-stage 元素')\n      }\n\n      // 移除其他可能的 oml2d 元素\n      const oml2dElements = document.querySelectorAll('[id^=\"oml2d\"]')\n      oml2dElements.forEach(el => el.remove())\n\n      console.log('Live2D 资源清理完成')\n    }\n  }, [])\n\n  return (\n    <Live2DContainer ref={containerRef} $visible={isVisible && loaded}>\n      {!loaded && <LoadingText>看板娘加载中...</LoadingText>}\n    </Live2DContainer>\n  )\n}\n\nexport default Live2DDashboard\n"
  },
  {
    "path": "src/components/Navbar.tsx",
    "content": "import React, { useState, useEffect } from 'react'\nimport { Menu, Button, Drawer, message, Dropdown, Avatar } from 'antd'\nimport type { MenuProps } from 'antd'\nimport {\n  HomeOutlined,\n  MessageOutlined,\n  VideoCameraOutlined,\n  SoundOutlined,\n  BookOutlined,\n  UserOutlined,\n  LogoutOutlined,\n  MenuOutlined,\n  ReadOutlined,\n  GoldOutlined,\n  AndroidOutlined,\n  RobotOutlined,\n  NodeIndexOutlined\n} from '@ant-design/icons'\nimport { useLocation, useNavigate } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport styled from 'styled-components'\nimport { logoImage, translateImage } from '@/utils/images'\nimport { isAuthenticated, removeToken } from '@/utils/token'\n\nconst NavbarContainer = styled.nav`\n  position: fixed;\n  top: 0;\n  left: 0;\n  right: 0;\n  z-index: 1000;\n  background: rgba(255, 255, 255, 0.95);\n  backdrop-filter: blur(10px);\n  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n  transition: all 0.3s ease;\n\n  .ant-menu {\n    border-bottom: none;\n    background: transparent;\n  }\n\n  .ant-menu-item {\n    transition: all 0.3s ease;\n  }\n\n  .ant-menu-item:hover {\n    background: rgba(102, 126, 234, 0.1) !important;\n  }\n\n  .ant-menu-item-selected {\n    background: rgba(102, 126, 234, 0.15) !important;\n    color: #667eea !important;\n  }\n\n  @media (max-width: 768px) {\n    padding: 0 16px;\n  }\n`\n\nconst Logo = styled.div`\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  font-size: 1.2rem;\n  font-weight: bold;\n  color: #667eea;\n  padding: 0 24px;\n  cursor: pointer;\n  transition: all 0.3s ease;\n\n  &:hover {\n    transform: translateY(-2px);\n  }\n\n  img {\n    width: 40px;\n    height: 40px;\n    border-radius: 8px;\n  }\n\n  @media (max-width: 768px) {\n    padding: 0;\n    font-size: 1rem;\n\n    img {\n      width: 32px;\n      height: 32px;\n    }\n  }\n`\n\nconst NavbarContent = styled.div`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  height: 64px;\n  padding: 0 24px;\n\n  @media (max-width: 768px) {\n    padding: 0 16px;\n  }\n`\n\nconst LogoutButton = styled(Button)`\n  border-radius: 20px;\n  height: 36px;\n  padding: 0 20px;\n  font-weight: 500;\n  transition: all 0.3s ease;\n\n  &:hover {\n    transform: translateY(-2px);\n    box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);\n  }\n`\n\nconst UserAvatar = styled(Avatar)`\n  cursor: pointer;\n  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n  transition: all 0.3s ease;\n\n  &:hover {\n    transform: scale(1.1);\n    box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);\n  }\n`\n\nconst UserDropdownMenu = styled.div`\n  padding: 12px 16px;\n  border-radius: 8px;\n  background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%);\n  border: 1px solid rgba(102, 126, 234, 0.2);\n\n  .user-info {\n    display: flex;\n    flex-direction: column;\n    gap: 4px;\n  }\n\n  .user-label {\n    font-size: 12px;\n    color: #888;\n  }\n\n  .user-name {\n    font-size: 14px;\n    font-weight: 600;\n    color: #333;\n  }\n`\n\nconst Navbar: React.FC = () => {\n  const { t, i18n } = useTranslation()\n  const location = useLocation()\n  const navigate = useNavigate()\n  const [drawerVisible, setDrawerVisible] = useState(false)\n  const [isMobile, setIsMobile] = useState(false)\n  const [isLoggedIn, setIsLoggedIn] = useState(false)\n  const [username, setUsername] = useState<string>('')\n\n  useEffect(() => {\n    const checkMobile = () => {\n      setIsMobile(window.innerWidth <= 768)\n    }\n\n    checkMobile()\n    window.addEventListener('resize', checkMobile)\n\n    return () => window.removeEventListener('resize', checkMobile)\n  }, [])\n\n  useEffect(() => {\n    // 检查登录状态\n    setIsLoggedIn(isAuthenticated())\n  }, [])\n\n  useEffect(() => {\n    // 检查登录状态\n    const checkLoginStatus = () => {\n      const loginStatus = localStorage.getItem('isLoggedIn')\n      setIsLoggedIn(loginStatus === 'true')\n      setUsername(localStorage.getItem('username') || '')\n    }\n\n    checkLoginStatus()\n\n    // 监听存储变化\n    const handleStorageChange = (e: StorageEvent) => {\n      if (e.key === 'isLoggedIn') {\n        setIsLoggedIn(e.newValue === 'true')\n      }\n      if (e.key === 'username') {\n        setUsername(e.newValue || '')\n      }\n    }\n\n    window.addEventListener('storage', handleStorageChange)\n    return () => window.removeEventListener('storage', handleStorageChange)\n  }, [])\n\n  const menuItems = [\n    { key: '/home', label: t('nav.home'), icon: <HomeOutlined /> },\n    { key: '/cartoon', label: t('nav.cartoon'), icon: <ReadOutlined /> },\n    { key: '/papers', label: t('nav.paper'), icon: <BookOutlined /> },\n    { key: '/goofish', label: t('nav.goofish'), icon: <AndroidOutlined /> },\n    { key: '/video', label: t('nav.video'), icon: <VideoCameraOutlined /> },\n    { key: '/music', label: t('nav.music'), icon: <SoundOutlined /> },\n    { key: '/gold', label: t('nav.gold'), icon: <GoldOutlined /> },\n    { key: '/gpt', label: t('nav.chatgpt'), icon: <MessageOutlined /> },\n    { key: '/markmap', label: t('nav.aimarkmap'), icon: <NodeIndexOutlined /> },\n    // 如果是移动端，不显示监工菜单项\n    ...(isMobile ? [] : [{ key: '/worker', label: t('nav.worker'), icon: <RobotOutlined /> }]),\n    { key: '/about', label: t('nav.about'), icon: <UserOutlined /> }\n  ]\n\n  const handleMenuClick = (e: { key: string }) => {\n    navigate(e.key)\n    if (isMobile) {\n      setDrawerVisible(false)\n    }\n  }\n\n  const handleLogout = () => {\n    removeToken()\n    localStorage.removeItem('isLoggedIn')\n    localStorage.removeItem('username')\n    setIsLoggedIn(false)\n    message.success(t('common.logoutSuccess'))\n    navigate('/')\n  }\n\n  const handleLogoClick = () => {\n    navigate('/home')\n  }\n\n  const handleLanguageChange = (lang: string) => {\n    i18n.changeLanguage(lang)\n    localStorage.setItem('language', lang)\n  }\n\n  const languageItems: MenuProps['items'] = [\n    {\n      key: 'zh',\n      label: t('common.chinese'),\n      onClick: () => handleLanguageChange('zh')\n    },\n    {\n      key: 'en',\n      label: t('common.english'),\n      onClick: () => handleLanguageChange('en')\n    }\n  ]\n\n  // 获取当前选中的菜单项\n  const getSelectedKey = (pathname: string): string => {\n    // 检查是否以 /cartoon 开头\n    if (pathname.startsWith('/cartoon')) {\n      return '/cartoon'\n    }\n    // 其他路径直接返回\n    return pathname\n  }\n\n  const currentKey = getSelectedKey(location.pathname)\n\n  // 移动端视图\n  if (isMobile) {\n    return (\n      <NavbarContainer>\n        <NavbarContent>\n          <Logo onClick={handleLogoClick}>\n            <img src={logoImage} alt=\"Logo\" />\n            <span>ChattyPlay</span>\n          </Logo>\n          <div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>\n            <Dropdown menu={{ items: languageItems }} placement=\"bottomRight\">\n              <Button\n                type=\"text\"\n                icon={<img src={translateImage} style={{ transform: 'scale(0.8)' }} />}\n                style={{ fontSize: '1.2rem' }}\n              />\n            </Dropdown>\n            {isLoggedIn && (\n              <>\n                <LogoutButton\n                  type=\"default\"\n                  icon={<LogoutOutlined />}\n                  onClick={handleLogout}\n                  size=\"small\"\n                >\n                  {t('nav.logout')}\n                </LogoutButton>\n                <Dropdown\n                  menu={{ items: [] }}\n                  dropdownRender={() => (\n                    <UserDropdownMenu>\n                      <div className=\"user-info\">\n                        <span className=\"user-label\">{t('nav.user')}</span>\n                        <span className=\"user-name\">{username}</span>\n                      </div>\n                    </UserDropdownMenu>\n                  )}\n                  placement=\"bottomRight\"\n                  trigger={['hover']}\n                >\n                  <UserAvatar icon={<UserOutlined />} />\n                </Dropdown>\n              </>\n            )}\n            <Button\n              type=\"text\"\n              icon={<MenuOutlined />}\n              onClick={() => setDrawerVisible(true)}\n              style={{ fontSize: '1.5rem' }}\n            />\n          </div>\n        </NavbarContent>\n\n        <Drawer\n          title={t('nav.navigationMenu')}\n          placement=\"left\"\n          onClose={() => setDrawerVisible(false)}\n          open={drawerVisible}\n        >\n          <Menu\n            mode=\"inline\"\n            selectedKeys={[currentKey]}\n            onClick={handleMenuClick}\n            items={menuItems}\n            style={{ borderRight: 0 }}\n          />\n        </Drawer>\n      </NavbarContainer>\n    )\n  }\n\n  // PC端视图\n  return (\n    <NavbarContainer>\n      <NavbarContent>\n        <Logo onClick={handleLogoClick}>\n          <img src={logoImage} alt=\"Logo\" />\n          <span>ChattyPlay</span>\n        </Logo>\n\n        <Menu\n          mode=\"horizontal\"\n          selectedKeys={[currentKey]}\n          onClick={handleMenuClick}\n          items={menuItems}\n          style={{ flex: 1, border: 'none', height: '64px', lineHeight: '64px' }}\n        />\n\n        <div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>\n          <Dropdown menu={{ items: languageItems }} placement=\"bottomRight\">\n            <Button\n              type=\"text\"\n              icon={<img src={translateImage} style={{ transform: 'scale(0.8)' }} />}\n              style={{ fontSize: '1.2rem' }}\n            />\n          </Dropdown>\n\n          {isLoggedIn ? (\n            <>\n              <LogoutButton\n                type=\"primary\"\n                icon={<LogoutOutlined />}\n                onClick={handleLogout}\n                style={{\n                  background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\n                  border: 'none'\n                }}\n              >\n                {t('nav.logout')}\n              </LogoutButton>\n              <Dropdown\n                menu={{ items: [] }}\n                dropdownRender={() => (\n                  <UserDropdownMenu>\n                    <div className=\"user-info\">\n                      <span className=\"user-label\">{t('nav.user')}</span>\n                      <span className=\"user-name\">{username}</span>\n                    </div>\n                  </UserDropdownMenu>\n                )}\n                placement=\"bottomRight\"\n                trigger={['hover']}\n              >\n                <UserAvatar icon={<UserOutlined />} />\n              </Dropdown>\n            </>\n          ) : (\n            <Button\n              type=\"primary\"\n              icon={<UserOutlined />}\n              onClick={() => navigate('/')}\n              style={{\n                borderRadius: '20px',\n                height: '36px',\n                padding: '0 20px',\n                background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\n                border: 'none',\n                fontWeight: '500'\n              }}\n            >\n              {t('nav.login')}\n            </Button>\n          )}\n        </div>\n      </NavbarContent>\n    </NavbarContainer>\n  )\n}\n\nexport default Navbar\n"
  },
  {
    "path": "src/components/VerifyCode.tsx",
    "content": "import React, { useEffect, useRef } from 'react'\nimport styled from 'styled-components'\n\ninterface VerifyCodeProps {\n  code: string\n}\n\nconst CanvasWrapper = styled.div`\n  width: 120px;\n  height: 40px;\n\n  canvas {\n    border-radius: 8px;\n    cursor: pointer;\n    background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);\n  }\n`\n\nconst VerifyCode: React.FC<VerifyCodeProps> = ({ code }) => {\n  const canvasRef = useRef<HTMLCanvasElement>(null)\n\n  useEffect(() => {\n    if (!canvasRef.current) return\n\n    const canvas = canvasRef.current\n    const ctx = canvas.getContext('2d')\n    if (!ctx) return\n\n    // 清除画布\n    ctx.clearRect(0, 0, canvas.width, canvas.height)\n\n    // 绘制干扰线\n    for (let i = 0; i < 5; i++) {\n      ctx.beginPath()\n      ctx.strokeStyle = `rgba(0, 0, 0, ${Math.random() * 0.3})`\n      ctx.moveTo(Math.random() * canvas.width, Math.random() * canvas.height)\n      ctx.lineTo(Math.random() * canvas.width, Math.random() * canvas.height)\n      ctx.lineWidth = Math.random() * 2 + 1\n      ctx.stroke()\n    }\n\n    // 绘制文字\n    const fontSize = 24\n    const charSpacing = canvas.width / code.length\n    ctx.font = `bold ${fontSize}px Arial`\n\n    for (let i = 0; i < code.length; i++) {\n      ctx.save()\n\n      // 随机倾斜\n      const rotate = (Math.random() - 0.5) * 0.4\n      ctx.translate(i * charSpacing + charSpacing / 2, canvas.height / 2)\n      ctx.rotate(rotate)\n\n      // 随机颜色\n      const color = `rgba(${Math.floor(Math.random() * 255)}, ${Math.floor(Math.random() * 255)}, ${Math.floor(Math.random() * 255)}, 0.8)`\n      ctx.fillStyle = color\n\n      ctx.textBaseline = 'middle'\n      ctx.textAlign = 'center'\n\n      ctx.fillText(code[i], 0, 0)\n\n      ctx.restore()\n    }\n\n    // 绘制干扰点\n    for (let i = 0; i < 50; i++) {\n      ctx.beginPath()\n      ctx.arc(\n        Math.random() * canvas.width,\n        Math.random() * canvas.height,\n        Math.random() * 1.5,\n        0,\n        2 * Math.PI\n      )\n      ctx.fillStyle = `rgba(0, 0, 0, ${Math.random() * 0.3})`\n      ctx.fill()\n    }\n  }, [code])\n\n  return (\n    <CanvasWrapper>\n      <canvas\n        ref={canvasRef}\n        width={120}\n        height={40}\n      />\n    </CanvasWrapper>\n  )\n}\n\nexport default VerifyCode\n"
  },
  {
    "path": "src/components/VersionUpdateModal.tsx",
    "content": "import React, { useEffect, useState } from 'react'\nimport { Modal, Button } from 'antd'\nimport { useTranslation } from 'react-i18next'\nimport {\n  checkVersionUpdate,\n  handleVersionUpdate,\n  updateStoredVersion,\n  getVersionInfo,\n  isVersionUpdateHandled,\n  markVersionUpdateHandled\n} from '../utils/versionChecker'\n\ninterface VersionUpdateModalProps {\n  /** 是否自动检测版本更新 */\n  autoCheck?: boolean\n  /** 检测间隔时间（毫秒），默认 5000ms */\n  checkInterval?: number\n}\n\nconst VersionUpdateModal: React.FC<VersionUpdateModalProps> = ({\n  autoCheck = true,\n  checkInterval = 5000\n}) => {\n  const { t } = useTranslation()\n  const [visible, setVisible] = useState(false)\n  const versionInfo = getVersionInfo()\n\n  /**\n   * 处理更新按钮点击\n   */\n  const handleUpdate = () => {\n    // 标记已处理\n    markVersionUpdateHandled()\n    // 更新版本号\n    updateStoredVersion()\n    // 清空 localStorage 并重新加载\n    handleVersionUpdate()\n  }\n\n  /**\n   * 执行版本检查\n   */\n  const performVersionCheck = () => {\n    // 如果已经处理过，不再显示\n    if (isVersionUpdateHandled()) {\n      return\n    }\n\n    const hasUpdate = checkVersionUpdate()\n\n    if (hasUpdate) {\n      setVisible(true)\n    }\n  }\n\n  /**\n   * 初始化时检查版本更新\n   */\n  useEffect(() => {\n    if (autoCheck) {\n      // 延迟检查，避免与其他初始化逻辑冲突\n      const timer = setTimeout(() => {\n        performVersionCheck()\n      }, checkInterval)\n\n      return () => clearTimeout(timer)\n    }\n  }, [autoCheck, checkInterval])\n\n  return (\n    <Modal\n      title={t('versionUpdate.title')}\n      open={visible}\n      centered\n      closable={false}\n      maskClosable={false}\n      keyboard={false}\n      width={420}\n      footer={null}\n      onCancel={() => {}}\n    >\n      <div style={{ padding: '8px 0' }}>\n        <p style={{ fontSize: '16px', fontWeight: 500, marginBottom: '16px' }}>\n          {t('versionUpdate.message')}\n        </p>\n        <p style={{ fontSize: '14px', color: '#666', marginBottom: '8px' }}>\n          {t('versionUpdate.currentVersion')}{versionInfo.stored}\n        </p>\n        <p style={{ fontSize: '14px', color: '#666', marginBottom: '16px' }}>\n          {t('versionUpdate.latestVersion')}{versionInfo.current}\n        </p>\n        <p style={{ fontSize: '14px', color: '#ff4d4f', marginBottom: '24px' }}>\n          {t('versionUpdate.description')}\n        </p>\n        <Button\n          type=\"primary\"\n          danger\n          size=\"large\"\n          block\n          onClick={handleUpdate}\n        >\n          {t('versionUpdate.updateButton')}\n        </Button>\n      </div>\n    </Modal>\n  )\n}\n\nexport default VersionUpdateModal\n"
  },
  {
    "path": "src/components/goofish/GoofishLayout.tsx",
    "content": "import React, { useState, useEffect } from 'react'\nimport { Layout, Menu, theme, Button, Typography, Space } from 'antd'\nimport { Outlet, useNavigate, useLocation } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport {\n  DashboardOutlined,\n  UserOutlined,\n  MessageOutlined,\n  ShoppingOutlined,\n  RobotOutlined,\n  FileTextOutlined,\n  BranchesOutlined,\n  MenuFoldOutlined,\n  MenuUnfoldOutlined,\n  HomeOutlined\n} from '@ant-design/icons'\n\nconst { Sider, Content, Header } = Layout\nconst { Title } = Typography\n\nconst GoofishLayout: React.FC = () => {\n  const navigate = useNavigate()\n  const { t } = useTranslation()\n  const location = useLocation()\n  const [collapsed, setCollapsed] = useState(false)\n  const [isMobile, setIsMobile] = useState(false)\n  const {\n    token: { colorBgContainer, borderRadiusLG }\n  } = theme.useToken()\n\n  // 检测屏幕尺寸\n  useEffect(() => {\n    const checkMobile = () => {\n      setIsMobile(window.innerWidth < 768)\n      if (window.innerWidth < 768) {\n        setCollapsed(true)\n      }\n    }\n\n    checkMobile()\n    window.addEventListener('resize', checkMobile)\n    return () => window.removeEventListener('resize', checkMobile)\n  }, [])\n\n  const menuItems = [\n    { key: '/goofish', icon: <DashboardOutlined />, label: t('goofish.data') },\n    { key: '/goofish/accounts', icon: <UserOutlined />, label: t('goofish.accounts') },\n    { key: '/goofish/conversations', icon: <MessageOutlined />, label: t('goofish.conversations') },\n    { key: '/goofish/orders', icon: <ShoppingOutlined />, label: t('goofish.orders') },\n    { key: '/goofish/goods', icon: <ShoppingOutlined />, label: t('goofish.goods') },\n    { key: '/goofish/autoreply', icon: <RobotOutlined />, label: t('goofish.autoreply') },\n    { key: '/goofish/autosell', icon: <ShoppingOutlined />, label: t('goofish.autosell') },\n    { key: '/goofish/workflow', icon: <BranchesOutlined />, label: t('goofish.workflow') },\n    { key: '/goofish/logs', icon: <FileTextOutlined />, label: t('goofish.logs') }\n  ]\n\n  const getPageTitle = () => {\n    const item = menuItems.find(m => m.key === location.pathname)\n    return item?.label || t('goofish.assistant')\n  }\n\n  const handleMenuClick = ({ key }: { key: string }) => {\n    navigate(key)\n    // 移动端点击菜单后自动收起侧边栏\n    if (isMobile) {\n      setCollapsed(true)\n    }\n  }\n\n  return (\n    <>\n      {/* 移动端菜单优化 */}\n      <style>{`\n        @media (max-width: 767px) {\n          .ant-menu-item {\n            height: 36px !important;\n            line-height: 36px !important;\n            padding: 0 12px !important;\n            margin: 2px 0 !important;\n          }\n          .ant-menu-item .anticon {\n            font-size: 14px !important;\n            margin-inline-end: 8px !important;\n          }\n          /* 移动端表格优化 */\n          .ant-table {\n            font-size: 12px !important;\n          }\n          .ant-table-thead > tr > th,\n          .ant-table-tbody > tr > td {\n            padding: 8px 8px !important;\n          }\n          /* 移动端卡片内边距优化 */\n          .ant-card {\n            margin-bottom: 12px !important;\n          }\n          .ant-card-body {\n            padding: 12px !important;\n          }\n          /* 移动端按钮尺寸优化 */\n          .ant-btn {\n            font-size: 13px !important;\n            height: 32px !important;\n            padding: 4px 12px !important;\n          }\n          .ant-btn-sm {\n            font-size: 12px !important;\n            height: 28px !important;\n            padding: 0 8px !important;\n          }\n          /* 移动端输入框优化 */\n          .ant-input,\n          .ant-select {\n            font-size: 13px !important;\n          }\n          /* 移动端统计卡片优化 */\n          .ant-statistic-title {\n            font-size: 13px !important;\n          }\n          .ant-statistic-content {\n            font-size: 20px !important;\n          }\n          /* 移动端标签优化 */\n          .ant-tag {\n            font-size: 11px !important;\n            padding: 0 4px !important;\n          }\n        }\n        @media (max-width: 575px) {\n          /* 超小屏幕优化 */\n          .goofish-content {\n            margin: 8px !important;\n            padding: 12px !important;\n          }\n        }\n      `}</style>\n      <Layout style={{ minHeight: '100vh', position: 'relative' }}>\n      {/* 移动端遮罩层 */}\n      {isMobile && !collapsed && (\n        <div\n          style={{\n            position: 'fixed',\n            top: 0,\n            left: 0,\n            right: 0,\n            bottom: 0,\n            backgroundColor: 'rgba(0, 0, 0, 0.45)',\n            zIndex: 99,\n            transition: 'all 0.3s'\n          }}\n          onClick={() => setCollapsed(true)}\n        />\n      )}\n\n      <Sider\n        collapsible\n        collapsed={collapsed}\n        onCollapse={setCollapsed}\n        theme=\"light\"\n        style={{\n          height: '100vh',\n          position: 'fixed',\n          left: 0,\n          top: 0,\n          bottom: 0,\n          zIndex: isMobile && !collapsed ? 1000 : 100,\n          transition: 'all 0.2s',\n          [isMobile && collapsed ? 'transform' : '']: isMobile && collapsed ? 'translateX(-100%)' : 'translateX(0)',\n          display: 'flex',\n          flexDirection: 'column',\n          background: '#fff',\n          borderRight: '1px solid #f0f0f0'\n        }}\n        trigger={null}\n        width={isMobile ? 240 : 220}\n        collapsedWidth={isMobile ? 0 : 64}\n      >\n        <div style={{\n          height: isMobile ? 48 : 56,\n          display: 'flex',\n          alignItems: 'center',\n          justifyContent: collapsed ? 'center' : 'space-between',\n          padding: collapsed ? 0 : '0 16px',\n          background: '#fafafa',\n          borderBottom: '1px solid #f0f0f0',\n          flexShrink: 0\n        }}>\n          {!collapsed && (\n            <Space>\n              <ShoppingOutlined style={{ fontSize: isMobile ? 18 : 22, color: '#1890ff' }} />\n              <Title level={4} style={{ color: '#333', margin: 0, fontSize: isMobile ? 14 : 15 }}>\n                {t('goofish.assistant')}\n              </Title>\n            </Space>\n          )}\n          {collapsed && !isMobile && (\n            <ShoppingOutlined style={{ fontSize: 22, color: '#1890ff' }} />\n          )}\n          {!collapsed && isMobile && (\n            <Button\n              type=\"text\"\n              icon={<MenuFoldOutlined />}\n              onClick={() => setCollapsed(true)}\n              style={{ fontSize: 14 }}\n            />\n          )}\n        </div>\n        <div style={{\n          flex: 1,\n          overflow: isMobile ? 'visible' : 'auto',\n          overflowX: 'hidden',\n          background: '#fff',\n          WebkitOverflowScrolling: 'touch'\n        }}>\n          <Menu\n            mode=\"inline\"\n            selectedKeys={[location.pathname]}\n            items={menuItems}\n            onClick={handleMenuClick}\n            style={{\n              borderRight: 0,\n              ...(isMobile && {\n                fontSize: '13px'\n              })\n            }}\n            inlineIndent={isMobile ? 12 : 16}\n          />\n        </div>\n      </Sider>\n\n      <Layout\n        style={{\n          marginLeft: isMobile ? 0 : (collapsed ? 64 : 220),\n          transition: 'margin-left 0.2s',\n          display: 'flex',\n          flexDirection: 'column'\n        }}\n      >\n        <Header\n          style={{\n            padding: isMobile ? '0 12px' : '0 24px',\n            background: colorBgContainer,\n            borderBottom: '1px solid #f0f0f0',\n            display: isMobile && !collapsed ? 'none' : 'flex',\n            alignItems: 'center',\n            justifyContent: 'space-between',\n            height: isMobile ? 56 : 64,\n            position: 'sticky',\n            top: 0,\n            zIndex: isMobile && !collapsed ? 1001 : 99,\n            boxShadow: '0 1px 4px rgba(0,21,41,.08)'\n          }}\n        >\n          <Space size={isMobile ? 'small' : 'middle'}>\n            <Button\n              type=\"text\"\n              icon={collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}\n              onClick={() => setCollapsed(!collapsed)}\n              style={{ fontSize: isMobile ? 14 : 16, width: isMobile ? 40 : 48, height: isMobile ? 40 : 48 }}\n            />\n            <Title level={4} style={{ margin: 0, fontSize: isMobile ? 16 : 18 }}>\n              {getPageTitle()}\n            </Title>\n          </Space>\n\n          <Button\n            type=\"text\"\n            icon={<HomeOutlined />}\n            onClick={() => navigate('/home')}\n            style={{ fontSize: isMobile ? 13 : 14 }}\n          >\n            {isMobile ? '' : t('goofish.home')}\n          </Button>\n        </Header>\n\n        <Content\n          className=\"goofish-content\"\n          style={{\n            margin: isMobile ? '8px' : '16px',\n            padding: isMobile ? '12px' : '24px',\n            background: colorBgContainer,\n            borderRadius: borderRadiusLG,\n            flex: 1,\n            overflowY: 'hidden',\n            overflowX: 'hidden',\n            boxShadow: '0 1px 2px rgba(0,0,0,0.03)',\n            transition: 'all 0.2s'\n          }}\n        >\n          <Outlet />\n        </Content>\n      </Layout>\n    </Layout>\n    </>\n  )\n}\n\nexport default GoofishLayout\n"
  },
  {
    "path": "src/components/goofish/index.ts",
    "content": "export { default as GoofishLayout } from './GoofishLayout'\n"
  },
  {
    "path": "src/components/latex/FileTree.tsx",
    "content": "import React, { useState, useMemo, useCallback, useEffect } from 'react'\nimport { Tree, Input, Button, Modal, message, Dropdown, Popconfirm, Upload } from 'antd'\nimport type { DataNode, TreeProps } from 'antd/es/tree'\nimport {\n  FileTextOutlined,\n  PictureOutlined,\n  FileOutlined,\n  PlusOutlined,\n  DeleteOutlined,\n  EditOutlined,\n  MoreOutlined,\n  FolderOutlined,\n  FolderOpenOutlined,\n} from '@ant-design/icons'\nimport type { MenuProps } from 'antd'\nimport './tree.css'\n\n// 持久化的文件树存储，在模块级别保存\nlet persistedFiles: FileNode[] | null = null\n\nexport interface FileNode {\n  key: string\n  title: string\n  type: 'tex' | 'bib' | 'cls' | 'image' | 'other' | 'folder'\n  content?: string\n  children?: FileNode[]\n  url?: string\n  imageBlob?: Blob  // 真实图片 Blob\n  imageUrl?: string // base64 预览 URL\n}\n\n// File/Blob 转 base64\nconst blobToBase64 = (blob: Blob): Promise<string> => {\n  return new Promise((resolve, reject) => {\n    const reader = new FileReader()\n    reader.onloadend = () => resolve(reader.result as string)\n    reader.onerror = reject\n    reader.readAsDataURL(blob)\n  })\n}\n\n// base64 转 Blob\nconst base64ToBlob = (base64: string): Blob => {\n  const parts = base64.split(';base64,')\n  const contentType = parts[0].split(':')[1]\n  const raw = window.atob(parts[1])\n  const rawLength = raw.length\n  const uInt8Array = new Uint8Array(rawLength)\n  for (let i = 0; i < rawLength; ++i) {\n    uInt8Array[i] = raw.charCodeAt(i)\n  }\n  return new Blob([uInt8Array], { type: contentType })\n}\n\nconst getFileIcon = (type: FileNode['type'], expanded?: boolean) => {\n  switch (type) {\n    case 'tex':\n      return <FileTextOutlined style={{ color: '#667eea' }} />\n    case 'bib':\n      return <FileTextOutlined style={{ color: '#764ba2' }} />\n    case 'cls':\n      return <FileTextOutlined style={{ color: '#f59e0b' }} />\n    case 'image':\n      return <PictureOutlined style={{ color: '#10b981' }} />\n    case 'folder':\n      return expanded ? <FolderOpenOutlined style={{ color: '#fbbf24' }} /> : <FolderOutlined style={{ color: '#fbbf24' }} />\n    default:\n      return <FileOutlined />\n  }\n}\n\nconst getFileType = (filename: string): FileNode['type'] => {\n  if (filename.endsWith('.tex')) return 'tex'\n  if (filename.endsWith('.bib')) return 'bib'\n  if (filename.endsWith('.cls')) return 'cls'\n  if (/\\.(png|jpg|jpeg|gif|svg|eps|bmp|webp)$/i.test(filename)) return 'image'\n  return 'other'\n}\n\nconst isImageFile = (filename: string): boolean => {\n  return /\\.(png|jpg|jpeg|gif|svg|eps|bmp|webp)$/i.test(filename)\n}\n\nconst initialFiles: FileNode[] = [\n  {\n    key: 'main',\n    title: 'main.tex',\n    type: 'tex',\n    content: `\\\\documentclass{article}\n\\\\usepackage[utf8]{inputenc}\n\\\\usepackage{ctex}\n\\\\usepackage{graphicx}\n\\\\usepackage{amsmath}\n\n\\\\title{我的第一篇 LaTeX 文档}\n\\\\author{Your Name}\n\\\\date{\\\\today}\n\n\\\\begin{document}\n\n\\\\maketitle\n\n\\\\section{简介}\n这是使用 LaTeX 编写的示例文档。\n\n\\\\section{数学公式}\n著名的欧拉公式:\n\\\\begin{equation}\ne^{i\\\\pi} + 1 = 0\n\\\\end{equation}\n\n\\\\section{列表}\n\\\\begin{itemize}\n  \\\\item 第一项\n  \\\\item 第二项\n  \\\\item 第三项\n\\\\end{itemize}\n\n\\\\section{结论}\n本文档展示了 LaTeX 的一些基本功能。\n\n\\\\end{document}`,\n  },\n]\n\ninterface FileTreeProps {\n  selectedKey: string | null\n  onSelectFile: (key: string, content: string, imageBlob?: Blob) => void  // 修改：添加 imageBlob 参数\n  onImagesChange?: (images: Array<{ key: string; name: string; blob: Blob }>) => void  // 新增：图片文件变化时的回调\n}\n\ninterface TreeTitleProps {\n  nodeKey: string\n  title: string\n  nodeType: FileNode['type']\n  editingName: string\n  editingKey: string | null\n  onStartRename: (key: string) => void\n  onDeleteFile: (key: string) => void\n  onConfirmRename: () => void\n  onEditingNameChange: (name: string) => void\n}\n\nconst TreeNodeTitle: React.FC<TreeTitleProps> = ({\n  nodeKey,\n  title,\n  nodeType,\n  editingName,\n  editingKey,\n  onStartRename,\n  onDeleteFile,\n  onConfirmRename,\n  onEditingNameChange,\n}) => {\n  const menuItems: MenuProps['items'] = [\n    {\n      key: 'rename',\n      icon: <EditOutlined />,\n      label: '重命名',\n      onClick: (e) => {\n        e.domEvent.stopPropagation()\n        onStartRename(nodeKey)\n      },\n    },\n    {\n      key: 'delete',\n      icon: <DeleteOutlined />,\n      label: (\n        <Popconfirm\n          title={`确定要删除这个${nodeType === 'folder' ? '文件夹' : '文件'}吗？`}\n          description={nodeType === 'folder' ? '删除后文件夹内的所有内容也将被删除' : ''}\n          onConfirm={(e) => {\n            e?.stopPropagation()\n            onDeleteFile(nodeKey)\n          }}\n          okText=\"确定\"\n          cancelText=\"取消\"\n        >\n          <span onClick={(e) => e.stopPropagation()}>删除</span>\n        </Popconfirm>\n      ),\n    },\n  ]\n\n  if (editingKey === nodeKey) {\n    return (\n      <input\n        autoFocus\n        style={{\n          width: '100%',\n          border: '1px solid #1890ff',\n          borderRadius: 2,\n          outline: 'none',\n          fontSize: 14,\n          padding: '0 4px',\n          boxSizing: 'border-box'\n        }}\n        value={editingName}\n        onChange={(e) => onEditingNameChange(e.target.value)}\n        onKeyDown={(e) => {\n          if (e.key === 'Enter') onConfirmRename()\n        }}\n        onBlur={() => onConfirmRename()}\n        onClick={(e) => e.stopPropagation()}\n      />\n    )\n  }\n\n  return (\n    <div style={{ \n      display: 'flex', \n      alignItems: 'center', \n      justifyContent: 'space-between', \n      width: '100%', \n      flex: 1,\n      minWidth: 0,\n      gap: 8\n    }}>\n      <span style={{ \n        flex: 1, \n        overflow: 'hidden', \n        textOverflow: 'ellipsis', \n        whiteSpace: 'nowrap',\n        fontSize: 14\n      }}>\n        {title}\n      </span>\n      <Dropdown menu={{ items: menuItems }} trigger={['click']}>\n        <MoreOutlined\n          onClick={(e) => e.stopPropagation()}\n          style={{ \n            opacity: 0.5, \n            fontSize: 12, \n            flexShrink: 0,\n            cursor: 'pointer',\n            transition: 'opacity 0.2s'\n          }}\n          onMouseEnter={(e) => {\n            e.currentTarget.style.opacity = '1'\n          }}\n          onMouseLeave={(e) => {\n            e.currentTarget.style.opacity = '0.5'\n          }}\n        />\n      </Dropdown>\n    </div>\n  )\n}\n\nconst FileTree: React.FC<FileTreeProps> = ({ selectedKey, onSelectFile, onImagesChange }) => {\n  const [files, setFiles] = useState<FileNode[]>(() => {\n    // 初始化时优先使用持久化的数据\n    if (persistedFiles) return persistedFiles\n    const savedFiles = localStorage.getItem('latex-file-tree-v3')\n    if (savedFiles) {\n      try {\n        const parsed = JSON.parse(savedFiles)\n        persistedFiles = parsed\n        return parsed\n      } catch (e) {\n        console.error('加载文件树失败:', e)\n      }\n    }\n    return initialFiles\n  })\n  const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([])\n  const [isAddModalOpen, setIsAddModalOpen] = useState(false)\n  const [isAddFolderModalOpen, setIsAddFolderModalOpen] = useState(false)\n  const [newFileName, setNewFileName] = useState('')\n  const [newFolderName, setNewFolderName] = useState('')\n  const [editingKey, setEditingKey] = useState<string | null>(null)\n  const [editingName, setEditingName] = useState('')\n  const [currentFolderKey, setCurrentFolderKey] = useState<string | null>(null)\n\n  // 保存文件树（不保存 Blob，Blob 单独用 IndexedDB）\n  useEffect(() => {\n    const filesToSave = files.map(node => {\n      // 从 localStorage 恢复文件内容\n      const savedContent = localStorage.getItem(`latex-file-${node.key}`)\n      // 如果是图片节点，保存 base64 数据到 localStorage\n      if (node.type === 'image' && node.imageUrl) {\n        localStorage.setItem(`latex-image-${node.key}`, node.imageUrl)\n      }\n      return {\n        ...node,\n        content: savedContent ?? node.content,\n        imageBlob: undefined, // 不序列化 Blob\n        imageUrl: node.type === 'image' ? node.imageUrl : undefined,\n      }\n    })\n    persistedFiles = filesToSave\n    localStorage.setItem('latex-file-tree-v3', JSON.stringify(filesToSave))\n  }, [files])\n\n  const findNode = useCallback((nodes: FileNode[], key: string): FileNode | null => {\n    for (const node of nodes) {\n      if (node.key === key) return node\n      if (node.children) {\n        const found = findNode(node.children, key)\n        if (found) return found\n      }\n    }\n    return null\n  }, [])\n\n  const findParentNode = useCallback((nodes: FileNode[], key: string, parent: FileNode | null = null): FileNode | null => {\n    for (const node of nodes) {\n      if (node.key === key) return parent\n      if (node.children) {\n        const found = findParentNode(node.children, key, node)\n        if (found) return found\n      }\n    }\n    return null\n  }, [])\n\n  const addNodeToParent = useCallback((currentNodes: FileNode[], parentKey: string | null, newNode: FileNode): FileNode[] => {\n    if (parentKey === null) {\n      return [...currentNodes, newNode]\n    }\n    \n    return currentNodes.map((node) => {\n      if (node.key === parentKey) {\n        return {\n          ...node,\n          children: [...(node.children || []), newNode]\n        }\n      }\n      if (node.children) {\n        return {\n          ...node,\n          children: addNodeToParent(node.children, parentKey, newNode)\n        }\n      }\n      return node\n    })\n  }, [])\n\n  const deleteNode = useCallback((nodes: FileNode[], keyToDelete: string): FileNode[] => {\n    return nodes.filter((node) => {\n      if (node.key === keyToDelete) {\n        // 清理图片 URL\n        if (node.imageUrl) {\n          URL.revokeObjectURL(node.imageUrl)\n        }\n        return false\n      }\n      if (node.children) {\n        node.children = deleteNode(node.children, keyToDelete)\n      }\n      return true\n    })\n  }, [])\n\n  const renameNode = useCallback((nodes: FileNode[], keyToRename: string, newName: string): FileNode[] => {\n    return nodes.map((node) => {\n      if (node.key === keyToRename) {\n        return {\n          ...node,\n          title: newName,\n          type: node.type === 'folder' ? 'folder' : getFileType(newName),\n        }\n      }\n      if (node.children) {\n        return {\n          ...node,\n          children: renameNode(node.children, keyToRename, newName)\n        }\n      }\n      return node\n    })\n  }, [])\n\n  const handleDeleteFile = useCallback((key: string) => {\n    setFiles((prev) => deleteNode(prev, key))\n    if (selectedKey === key) {\n      onSelectFile('', '')\n    }\n    message.success('已删除')\n  }, [deleteNode, selectedKey, onSelectFile])\n\n  const handleStartRename = useCallback((key: string) => {\n    const node = findNode(files, key)\n    if (node) {\n      setEditingKey(key)\n      setEditingName(node.title)\n    }\n  }, [files, findNode])\n\n  const handleConfirmRename = useCallback(() => {\n    if (!editingKey || !editingName.trim()) {\n      setEditingKey(null)\n      return\n    }\n\n    setFiles((prev) => renameNode(prev, editingKey, editingName.trim()))\n    setEditingKey(null)\n    setEditingName('')\n    message.success('重命名成功')\n  }, [editingKey, editingName, renameNode])\n\n  const handleSelect: TreeProps['onSelect'] = useCallback((selectedKeys: React.Key[]) => {\n    if (selectedKeys.length > 0) {\n      const key = selectedKeys[0] as string\n      const node = findNode(files, key)\n\n      if (node) {\n        // 更新当前文件夹为选中节点的父文件夹\n        const parentNode = findParentNode(files, key)\n        setCurrentFolderKey(parentNode?.key || null)\n\n        if (node.type !== 'folder') {\n          if (node.type === 'image') {\n            // 优先使用 localStorage 恢复图片（base64 格式）\n            const savedImageUrl = localStorage.getItem(`latex-image-${key}`)\n            const imageUrl = savedImageUrl || node.imageUrl || ''\n            onSelectFile(key, `IMAGE:${imageUrl}`, node.imageBlob)\n          } else {\n            // 优先使用 localStorage 恢复文件内容\n            const savedContent = localStorage.getItem(`latex-file-${key}`)\n            onSelectFile(key, savedContent ?? node.content ?? '')\n          }\n        } else {\n          onSelectFile(key, '')\n        }\n      }\n    } else {\n      setCurrentFolderKey(null)\n    }\n  }, [files, findNode, findParentNode, onSelectFile])\n\n  const handleAddFile = useCallback(() => {\n    if (!newFileName.trim()) {\n      message.error('请输入文件名')\n      return\n    }\n\n    const newFile: FileNode = {\n      key: `file-${Date.now()}`,\n      title: newFileName.trim(),\n      type: getFileType(newFileName.trim()),\n      content: '',\n    }\n\n    setFiles((prev) => addNodeToParent(prev, currentFolderKey, newFile))\n    \n    if (currentFolderKey && !expandedKeys.includes(currentFolderKey)) {\n      setExpandedKeys([...expandedKeys, currentFolderKey])\n    }\n    \n    setNewFileName('')\n    setIsAddModalOpen(false)\n    message.success('文件添加成功')\n    onSelectFile(newFile.key, '')\n  }, [newFileName, currentFolderKey, addNodeToParent, expandedKeys, onSelectFile])\n\n  const handleAddFolder = useCallback(() => {\n    if (!newFolderName.trim()) {\n      message.error('请输入文件夹名称')\n      return\n    }\n\n    const newFolder: FileNode = {\n      key: `folder-${Date.now()}`,\n      title: newFolderName.trim(),\n      type: 'folder',\n      children: [],\n    }\n\n    setFiles((prev) => addNodeToParent(prev, currentFolderKey, newFolder))\n    \n    if (currentFolderKey && !expandedKeys.includes(currentFolderKey)) {\n      setExpandedKeys([...expandedKeys, currentFolderKey])\n    }\n    \n    setNewFolderName('')\n    setIsAddFolderModalOpen(false)\n    message.success('文件夹创建成功')\n  }, [newFolderName, currentFolderKey, addNodeToParent, expandedKeys])\n\n  // 上传图片文件 - 使用 base64 存储，刷新后能恢复\n  const handleImageUpload = useCallback(async (file: File) => {\n    if (!isImageFile(file.name)) {\n      message.error('请上传图片文件 (png, jpg, jpeg, gif, svg, eps, bmp, webp)')\n      return false\n    }\n\n    if (file.size > 10 * 1024 * 1024) {\n      message.error('图片大小不能超过10MB')\n      return false\n    }\n\n    // 转为 base64\n    const base64 = await blobToBase64(file)\n    const key = `image-${Date.now()}-${file.name}`\n\n    const newImageFile: FileNode = {\n      key,\n      title: file.name,\n      type: 'image',\n      imageBlob: file,           // 保留 Blob 用于编译\n      imageUrl: base64,          // 使用 base64，刷新后能恢复\n      content: base64,           // 兼容旧逻辑\n      url: base64,\n    }\n\n    setFiles((prev) => addNodeToParent(prev, currentFolderKey, newImageFile))\n\n    if (currentFolderKey && !expandedKeys.includes(currentFolderKey)) {\n      setExpandedKeys([...expandedKeys, currentFolderKey])\n    }\n\n    message.success(`图片 \"${file.name}\" 上传成功`)\n    onSelectFile(key, `IMAGE:${base64}`, file)\n\n    return false\n  }, [currentFolderKey, addNodeToParent, expandedKeys, onSelectFile])\n\n  // 调试用 - 移入生产后删除\n  useEffect(() => {\n    console.log('files updated:', JSON.stringify(files.map(f => ({ key: f.key, title: f.title }))))\n  }, [files])\n\n  const treeData = useMemo((): DataNode[] => {\n    const build = (nodes: FileNode[]): DataNode[] => {\n      // @ts-ignore\n      return nodes.map((node) => ({\n        key: node.key,\n        title: (\n          <TreeNodeTitle\n            nodeKey={node.key}\n            title={node.title}\n            nodeType={node.type}\n            editingName={editingName}\n            editingKey={editingKey}\n            onStartRename={handleStartRename}\n            onDeleteFile={handleDeleteFile}\n            onConfirmRename={handleConfirmRename}\n            onEditingNameChange={setEditingName}\n          />\n        ),\n        icon: ({ expanded }: { expanded: boolean }) => getFileIcon(node.type, expanded),\n        isLeaf: node.type !== 'folder',\n        children: node.children ? build(node.children) : undefined,\n      }))\n    }\n    return build(files)\n  }, [files, editingName, editingKey, handleStartRename, handleDeleteFile, handleConfirmRename])\n\n  const getCurrentFolderName = () => {\n    if (!currentFolderKey) return ''\n    const folder = findNode(files, currentFolderKey)\n    return folder ? ` (到 \"${folder.title}\")` : ''\n  }\n\n  // 获取所有图片文件（用于编译）\n  useEffect(() => {\n    if (onImagesChange) {\n      const collectImages = (nodes: FileNode[]): Array<{ key: string; name: string; blob: Blob }> => {\n        const images: Array<{ key: string; name: string; blob: Blob }> = []\n        for (const node of nodes) {\n          if (node.type === 'image') {\n            let blob = node.imageBlob\n            // 如果没有 Blob 但有 base64，则转换\n            if (!blob && node.imageUrl && node.imageUrl.startsWith('data:')) {\n              blob = base64ToBlob(node.imageUrl)\n            }\n            if (blob) {\n              images.push({\n                key: node.key,\n                name: node.title,\n                blob\n              })\n            }\n          }\n          if (node.children) {\n            images.push(...collectImages(node.children))\n          }\n        }\n        return images\n      }\n\n      onImagesChange(collectImages(files))\n    }\n  }, [files, onImagesChange])\n\n  return (\n    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', minHeight: 0, width: '100%', boxSizing: 'border-box' }}>\n      <div\n        style={{\n          padding: '8px 12px',\n          borderBottom: '1px solid #f0f0f0',\n          display: 'flex',\n          alignItems: 'center',\n          justifyContent: 'space-between',\n          gap: 4,\n          flexShrink: 0,\n          minWidth: 0\n        }}\n      >\n        <span style={{ fontWeight: 600, color: '#333', flex: 1 }}>文件</span>\n        <Button\n          type=\"text\"\n          icon={<FolderOutlined />}\n          size=\"small\"\n          onClick={() => setIsAddFolderModalOpen(true)}\n          title=\"新建文件夹\"\n          style={{ flexShrink: 0 }}\n        />\n        <Button\n          type=\"text\"\n          icon={<PlusOutlined />}\n          size=\"small\"\n          onClick={() => setIsAddModalOpen(true)}\n          title=\"新建文本文件\"\n          style={{ flexShrink: 0 }}\n        />\n        <Upload\n          accept=\"image/png,image/jpg,image/jpeg,image/gif,image/svg,image/bmp,image/webp\"\n          showUploadList={false}\n          beforeUpload={handleImageUpload}\n          customRequest={() => {}}\n        >\n          <Button\n            type=\"text\"\n            icon={<PictureOutlined />}\n            size=\"small\"\n            title=\"上传图片\"\n            style={{ flexShrink: 0 }}\n          />\n        </Upload>\n      </div>\n\n      <div style={{ flex: 1, overflow: 'auto', padding: '8px', minHeight: 0 }}>\n        <Tree\n          showIcon\n          selectedKeys={selectedKey ? [selectedKey] : []}\n          expandedKeys={expandedKeys}\n          onExpand={(keys) => setExpandedKeys(keys)}\n          onSelect={handleSelect}\n          treeData={treeData}\n          style={{ width: '100%' }}\n        />\n      </div>\n\n      <Modal\n        title={`新建文本文件${getCurrentFolderName()}`}\n        open={isAddModalOpen}\n        onOk={handleAddFile}\n        onCancel={() => {\n          setIsAddModalOpen(false)\n          setNewFileName('')\n        }}\n        okText=\"创建\"\n        cancelText=\"取消\"\n        zIndex={1100}\n      >\n        <Input\n          placeholder=\"请输入文件名，如: main.tex, notes.txt\"\n          value={newFileName}\n          onChange={(e) => setNewFileName(e.target.value)}\n          onPressEnter={handleAddFile}\n          autoFocus\n        />\n        <div style={{ marginTop: 8, fontSize: 12, color: '#999' }}>\n          支持的文件类型: .tex, .bib, .cls, .txt 等文本文件\n        </div>\n      </Modal>\n\n      <Modal\n        title={`新建文件夹${getCurrentFolderName()}`}\n        open={isAddFolderModalOpen}\n        onOk={handleAddFolder}\n        onCancel={() => {\n          setIsAddFolderModalOpen(false)\n          setNewFolderName('')\n        }}\n        okText=\"创建\"\n        cancelText=\"取消\"\n      >\n        <Input\n          placeholder=\"请输入文件夹名称\"\n          value={newFolderName}\n          onChange={(e) => setNewFolderName(e.target.value)}\n          onPressEnter={handleAddFolder}\n          autoFocus\n        />\n      </Modal>\n    </div>\n  )\n}\n\nexport default FileTree"
  },
  {
    "path": "src/components/latex/LatexEditor.tsx",
    "content": "import React, { useEffect, useRef } from 'react'\nimport Editor, { OnMount } from '@monaco-editor/react'\nimport type { editor } from 'monaco-editor'\nimport { Spin } from 'antd'\n\ninterface LatexEditorProps {\n  value: string\n  onChange: (value: string) => void\n  fileName?: string\n}\n\nconst LatexEditor: React.FC<LatexEditorProps> = ({ value, onChange, fileName }) => {\n  const editorRef = useRef<editor.IStandaloneCodeEditor | null>(null)\n\n  // 编辑器挂载完成\n  const handleEditorDidMount: OnMount = (editor, monaco) => {\n    editorRef.current = editor\n\n    // 注册 LaTeX 语言（如果 Monaco 内置没有）\n    if (!monaco.languages.getLanguages().some((lang: { id: string }) => lang.id === 'latex')) {\n      monaco.languages.register({ id: 'latex' })\n\n      // LaTeX 语法高亮规则\n      monaco.languages.setMonarchTokensProvider('latex', {\n        tokenizer: {\n          root: [\n            // 注释\n            [/%.*$/, 'comment'],\n            // 命令以 \\ 开头\n            [/\\\\[a-zA-Z]+/, 'keyword'],\n            [/\\\\[^a-zA-Z]/, 'keyword'],\n            // 环境\n            [/\\\\begin\\{[^}]+\\}/, 'keyword'],\n            [/\\\\end\\{[^}]+\\}/, 'keyword'],\n            // 大括号内容\n            [/\\{[^}]*\\}/, 'string'],\n            // 编译指令\n            [/\\\\(?:documentclass|usepackage|begin|end|author|title|date|bibliography)/, 'keyword'],\n            // 数学模式\n            [/\\$\\$/, { token: 'delimiter', bracket: '@open', next: '@mathDisplay' }],\n            [/\\$/, { token: 'delimiter', bracket: '@open', next: '@mathInline' }],\n            // 普通文本\n            [/[\\[\\]]/, 'string'],\n          ],\n          mathDisplay: [\n            [/\\$\\$/, { token: 'delimiter', bracket: '@close', next: '@pop' }],\n            [/./, 'number'],\n          ],\n          mathInline: [\n            [/\\$/, { token: 'delimiter', bracket: '@close', next: '@pop' }],\n            [/./, 'number'],\n          ],\n        },\n      })\n\n      // LaTeX 主题定义（可选）\n      monaco.editor.defineTheme('latexTheme', {\n        base: 'vs',\n        inherit: true,\n        rules: [\n          { token: 'keyword', foreground: '667eea', fontStyle: 'bold' },\n          { token: 'comment', foreground: '6b7280', fontStyle: 'italic' },\n          { token: 'string', foreground: '10b981' },\n          { token: 'number', foreground: 'f59e0b' },\n        ],\n        colors: {},\n      })\n    }\n\n    // 设置编辑器选项\n    editor.updateOptions({\n      fontSize: 14,\n      lineNumbers: 'on',\n      minimap: { enabled: false },\n      wordWrap: 'on',\n      automaticLayout: true,\n      scrollBeyondLastLine: false,\n      fontFamily: \"'Fira Code', 'Cascadia Code', Consolas, monospace\",\n      fontLigatures: true,\n      tabSize: 2,\n      renderWhitespace: 'selection',\n      bracketPairColorization: { enabled: true },\n    })\n\n    // 聚焦编辑器\n    editor.focus()\n  }\n\n  // 内容变化处理\n  const handleEditorChange = (newValue: string | undefined) => {\n    if (newValue !== undefined) {\n      onChange(newValue)\n    }\n  }\n\n  // 监听 value 变化（文件切换时）\n  useEffect(() => {\n    if (editorRef.current) {\n      const currentValue = editorRef.current.getValue()\n      if (currentValue !== value) {\n        editorRef.current.setValue(value)\n      }\n    }\n  }, [value])\n\n  return (\n    <div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>\n      {/* 文件标签 */}\n      {fileName && (\n        <div\n          style={{\n            padding: '8px 16px',\n            background: '#fafafa',\n            borderBottom: '1px solid #f0f0f0',\n            fontSize: 13,\n            color: '#666',\n            display: 'flex',\n            alignItems: 'center',\n            gap: 8,\n          }}\n        >\n          <span style={{ fontWeight: 500 }}>{fileName}</span>\n          <span style={{ color: '#ccc' }}>|</span>\n          <span style={{ fontSize: 12 }}>.tex, .bib, .cls, .txt 等文本文件</span>\n        </div>\n      )}\n\n      {/* 编辑器 */}\n      <div style={{ flex: 1 }}>\n        <Editor\n          height=\"100%\"\n          language=\"latex\"\n          value={value}\n          onChange={handleEditorChange}\n          onMount={handleEditorDidMount}\n          loading={\n            <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}>\n              <Spin />\n            </div>\n          }\n          options={{\n            minimap: { enabled: false },\n            fontSize: 14,\n            lineNumbers: 'on',\n            wordWrap: 'on',\n            automaticLayout: true,\n            scrollBeyondLastLine: false,\n          }}\n        />\n      </div>\n    </div>\n  )\n}\n\nexport default LatexEditor\n"
  },
  {
    "path": "src/components/latex/PdfPreview.tsx",
    "content": "import React, { useState } from 'react'\nimport { Document, Page, pdfjs } from 'react-pdf'\nimport { Spin, Button, Space, message } from 'antd'\nimport {\n  ZoomInOutlined,\n  ZoomOutOutlined,\n  LeftOutlined,\n  RightOutlined,\n  ReloadOutlined,\n  FilePdfOutlined,\n  DownloadOutlined\n} from '@ant-design/icons'\nimport 'react-pdf/dist/Page/AnnotationLayer.css'\nimport 'react-pdf/dist/Page/TextLayer.css'\n\n// 配置 PDF.js worker\npdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`\n\ninterface PdfPreviewProps {\n  pdfBlob: Blob | null\n  isCompiling: boolean\n  compileError?: string | null\n  onRetry?: () => void\n  // 可选：自定义下载文件名\n  downloadFileName?: string\n}\n\nconst PdfPreview: React.FC<PdfPreviewProps> = ({\n  pdfBlob,\n  isCompiling,\n  compileError,\n  onRetry,\n  downloadFileName = 'document.pdf', // 默认文件名\n}) => {\n  const [numPages, setNumPages] = useState<number>(0)\n  const [pageNumber, setPageNumber] = useState<number>(1)\n  const [scale, setScale] = useState<number>(1.0)\n  const [pdfUrl, setPdfUrl] = useState<string | null>(null)\n  const [, setLoadError] = useState<string | null>(null)\n\n  // 生成 PDF URL\n  React.useEffect(() => {\n    if (pdfBlob) {\n      // 清理旧的URL\n      if (pdfUrl) {\n        URL.revokeObjectURL(pdfUrl)\n      }\n\n      const url = URL.createObjectURL(pdfBlob)\n      setPdfUrl(url)\n      setLoadError(null)\n      setPageNumber(1)\n      setNumPages(0) // 重置页数\n\n      return () => {\n        URL.revokeObjectURL(url)\n      }\n    } else {\n      setPdfUrl(null)\n      setNumPages(0)\n    }\n  }, [pdfBlob])\n\n  // PDF 加载成功\n  const onDocumentLoadSuccess = ({ numPages }: { numPages: number }) => {\n    setNumPages(numPages)\n    setLoadError(null)\n  }\n\n  // PDF 加载失败\n  const onDocumentLoadError = (error: Error) => {\n    console.error('PDF load error:', error)\n    setLoadError('PDF 加载失败，请尝试重新编译')\n  }\n\n  // 翻页\n  const goToPrevPage = () => {\n    setPageNumber(prev => Math.max(1, prev - 1))\n  }\n\n  const goToNextPage = () => {\n    setPageNumber(prev => Math.min(numPages, prev + 1))\n  }\n\n  // 缩放\n  const zoomIn = () => {\n    setScale(prev => Math.min(3, prev + 0.25))\n  }\n\n  const zoomOut = () => {\n    setScale(prev => Math.max(0.5, prev - 0.25))\n  }\n\n  // 下载 PDF\n  const handleDownload = () => {\n    if (!pdfBlob) {\n      message.warning('没有可下载的 PDF 文件')\n      return\n    }\n\n    try {\n      // 创建下载链接\n      const url = URL.createObjectURL(pdfBlob)\n      const link = document.createElement('a')\n      link.href = url\n      link.download = downloadFileName\n      \n      // 触发下载\n      document.body.appendChild(link)\n      link.click()\n      \n      // 清理\n      document.body.removeChild(link)\n      URL.revokeObjectURL(url)\n      \n      message.success('PDF 下载成功')\n    } catch (error) {\n      console.error('下载失败:', error)\n      message.error('下载失败，请重试')\n    }\n  }\n\n  // 判断是否可以下载\n  const canDownload = !isCompiling && !compileError && pdfBlob\n\n  return (\n    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: '#f5f5f5' }}>\n      {/* 工具栏 */}\n      <div\n        style={{\n          padding: '8px 12px',\n          background: '#fff',\n          borderBottom: '1px solid #f0f0f0',\n          display: 'flex',\n          alignItems: 'center',\n          justifyContent: 'space-between',\n        }}\n      >\n        <span style={{ fontWeight: 600, color: '#333' }}>PDF 预览</span>\n\n        <Space size=\"small\">\n          {/* 下载按钮 */}\n          {canDownload && (\n            <Button\n              type=\"text\"\n              icon={<DownloadOutlined />}\n              size=\"small\"\n              onClick={handleDownload}\n              title=\"下载 PDF\"\n            />\n          )}\n          \n          {numPages > 0 && (\n            <>\n              <Button\n                type=\"text\"\n                icon={<ZoomOutOutlined />}\n                size=\"small\"\n                onClick={zoomOut}\n                disabled={scale <= 0.5}\n              />\n              <span style={{ fontSize: 12, minWidth: 50, textAlign: 'center' }}>\n                {Math.round(scale * 100)}%\n              </span>\n              <Button\n                type=\"text\"\n                icon={<ZoomInOutlined />}\n                size=\"small\"\n                onClick={zoomIn}\n                disabled={scale >= 3}\n              />\n            </>\n          )}\n        </Space>\n      </div>\n\n      {/* PDF 内容区 */}\n      <div\n        style={{\n          flex: 1,\n          overflow: 'auto',\n          display: 'flex',\n          justifyContent: 'center',\n          padding: 16,\n          scrollbarWidth: 'none',\n        }}\n      >\n        {/* 编译中 */}\n        {isCompiling && (\n          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 16 }}>\n            <Spin size=\"large\" tip=\"正在编译 LaTeX...\" />\n            <span style={{ color: '#666', fontSize: 13 }}>编译可能需要几秒钟...</span>\n          </div>\n        )}\n\n        {/* 编译错误 */}\n        {!isCompiling && compileError && (\n          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 16, padding: 24 }}>\n            <div style={{ color: '#ef4444', fontSize: 14, textAlign: 'center', maxWidth: 300 }}>\n              {compileError}\n            </div>\n            {onRetry && (\n              <Button\n                type=\"primary\"\n                icon={<ReloadOutlined />}\n                onClick={onRetry}\n              >\n                重新编译\n              </Button>\n            )}\n          </div>\n        )}\n\n        {/* PDF 预览 */}\n        {!isCompiling && !compileError && pdfUrl && (\n          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>\n            <Document\n              file={pdfUrl}\n              onLoadSuccess={onDocumentLoadSuccess}\n              onLoadError={onDocumentLoadError}\n              loading={\n                <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n                  <Spin size=\"small\" />\n                  <span style={{ color: '#666', fontSize: 13 }}>加载 PDF...</span>\n                </div>\n              }\n              error={\n                <div style={{ color: '#ef4444', padding: 16 }}>\n                  PDF 加载失败\n                </div>\n              }\n            >\n              <Page\n                pageNumber={pageNumber}\n                scale={scale}\n                renderTextLayer={true}\n                renderAnnotationLayer={true}\n                loading={\n                  <div style={{ padding: 20 }}>\n                    <Spin tip=\"加载页面...\" />\n                  </div>\n                }\n              />\n            </Document>\n          </div>\n        )}\n\n        {/* 空状态 */}\n        {!isCompiling && !compileError && !pdfUrl && (\n          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 16 }}>\n            <FilePdfOutlined style={{ fontSize: 48, color: '#d9d9d9' }} />\n            <span style={{ color: '#999', fontSize: 14 }}>\n              点击「编译」按钮生成 PDF\n            </span>\n            {onRetry && (\n              <Button\n                type=\"primary\"\n                icon={<ReloadOutlined />}\n                onClick={onRetry}\n              >\n                开始编译\n              </Button>\n            )}\n          </div>\n        )}\n      </div>\n\n      {/* 翻页控制 */}\n      {numPages > 0 && (\n        <div\n          style={{\n            padding: '8px 12px',\n            background: '#fff',\n            borderTop: '1px solid #f0f0f0',\n            display: 'flex',\n            alignItems: 'center',\n            justifyContent: 'center',\n            gap: 12,\n          }}\n        >\n          <Button\n            type=\"text\"\n            icon={<LeftOutlined />}\n            size=\"small\"\n            onClick={goToPrevPage}\n            disabled={pageNumber <= 1}\n          />\n          <span style={{ fontSize: 13 }}>\n            第 {pageNumber} / {numPages} 页\n          </span>\n          <Button\n            type=\"text\"\n            icon={<RightOutlined />}\n            size=\"small\"\n            onClick={goToNextPage}\n            disabled={pageNumber >= numPages}\n          />\n        </div>\n      )}\n    </div>\n  )\n}\n\nexport default PdfPreview\n"
  },
  {
    "path": "src/components/latex/tree.css",
    "content": "/* 覆盖 Ant Design Tree 组件的样式 */\n.ant-tree .ant-tree-node-content-wrapper,\ndiv.ant-tree .ant-tree-node-content-wrapper,\n[class*=\"ant-tree-node-content-wrapper\"] {\n  display: flex !important;\n  flex: 1 !important;\n  min-width: 0 !important;\n  width: 100% !important;\n}\n\n/* 确保标题容器占满剩余空间 */\n.ant-tree .ant-tree-title,\n[class*=\"ant-tree-title\"] {\n  flex: 1 !important;\n  min-width: 0 !important;\n  width: 100% !important;\n}\n\n/* 树节点整体占满宽度 */\n.ant-tree .ant-tree-treenode,\n[class*=\"ant-tree-treenode\"] {\n  width: 100% !important;\n}\n\n/* 文件图标和内容容器 */\n.ant-tree-node-content-wrapper .ant-tree-iconEle {\n  flex-shrink: 0 !important;\n}\n"
  },
  {
    "path": "src/components/markmap/EditNodeModal.tsx",
    "content": "import React from 'react'\nimport { Modal, Input } from 'antd'\nimport { useTranslation } from 'react-i18next'\n\nconst { TextArea } = Input\n\ninterface EditNodeModalProps {\n  visible: boolean\n  defaultValue: string\n  onSave: (value: string) => void\n  onCancel: () => void\n}\n\nconst EditNodeModal: React.FC<EditNodeModalProps> = ({\n  visible,\n  defaultValue,\n  onSave,\n  onCancel\n}) => {\n  const { t } = useTranslation()\n\n  return (\n    <Modal\n      title={t('aimarkmap.editNodeTitle')}\n      open={visible}\n      onCancel={onCancel}\n      footer={null}\n      className='max-w-lg'\n    >\n      <div className='space-y-4 py-4'>\n        <TextArea\n          defaultValue={defaultValue}\n          onChange={(e) => onSave(e.target.value)}\n          placeholder={t('aimarkmap.editNodePlaceholder')}\n          rows={4}\n          className='h-24'\n        />\n      </div>\n    </Modal>\n  )\n}\n\nexport default EditNodeModal\n"
  },
  {
    "path": "src/components/markmap/EditorPanel.tsx",
    "content": "import React from 'react'\nimport { Button, Input, Slider } from 'antd'\nimport { ClearOutlined } from '@ant-design/icons'\nimport { useTranslation } from 'react-i18next'\n\nconst { TextArea } = Input\n\ninterface EditorPanelProps {\n  searchValue: string\n  currentMarkdown: string\n  currentViewMode: 'input' | 'original' | 'markdown'\n  versionCount: number\n  aiResults: Array<{ markdown: string }>\n  onVersionCountChange: (value: number) => void\n  onGenerate: () => void\n  onClear: () => void\n  onSwitchView: (view: 'input' | 'original' | 'markdown') => void\n  onTopicInput: (e: React.ChangeEvent<HTMLTextAreaElement>) => void\n  onDisplayEdit: (e: React.ChangeEvent<HTMLTextAreaElement>) => void\n  onOpenPromptModal: () => void\n  isLoading: boolean\n  currentMobilePanel: 'editor' | 'mindmap'\n}\n\nconst EditorPanel: React.FC<EditorPanelProps> = ({\n  searchValue,\n  currentMarkdown,\n  currentViewMode,\n  versionCount,\n  aiResults,\n  onVersionCountChange,\n  onGenerate,\n  onClear,\n  onSwitchView,\n  onTopicInput,\n  onDisplayEdit,\n  onOpenPromptModal,\n  isLoading,\n  currentMobilePanel\n}) => {\n  const { t } = useTranslation()\n\n  return (\n    <div\n      className={`editor-panel absolute sm:relative top-0 left-0 w-full sm:w-96 h-full bg-white/95 backdrop-blur rounded-none sm:rounded-lg shadow-lg flex flex-col overflow-hidden transition-transform duration-300 z-10 sm:z-auto ${\n        currentMobilePanel === 'editor' ? 'translate-x-0' : '-translate-x-full sm:translate-x-0'\n      } ${currentMobilePanel === 'editor' ? 'opacity-100' : 'opacity-0 sm:opacity-100'} sm:opacity-100 sm:translate-x-0`}\n    >\n      <div className='bg-gradient-to-r from-indigo-500 to-purple-600 p-2 sm:p-4 border-b border-indigo-200 flex justify-between items-center'>\n        <Button\n          type='text'\n          onClick={onOpenPromptModal}\n          className='text-white'\n        >\n          {t('aimarkmap.promptSettingsBtn')}\n        </Button>\n      </div>\n\n      <div className='p-2 sm:p-4 bg-white/80 border-b border-gray-200'>\n        <div className='flex items-center gap-2'>\n          <span className='text-xs sm:text-sm text-gray-600'>{t('aimarkmap.versionsLabel')}</span>\n          <Slider\n            min={1}\n            max={5}\n            value={versionCount}\n            onChange={onVersionCountChange}\n            className='flex-1'\n          />\n          <span className='text-indigo-600 font-semibold min-w-[20px] text-center'>\n            {versionCount}\n          </span>\n        </div>\n      </div>\n\n      <div className='p-2 sm:p-4 bg-white/80 border-b border-gray-200'>\n        <div className='flex gap-1 mb-2'>\n          <Button\n            type='primary'\n            icon={<span>🚀</span>}\n            onClick={onGenerate}\n            loading={isLoading}\n            className='flex-1 bg-gradient-to-r from-indigo-500 to-purple-600 border-0'\n          >\n            {t('aimarkmap.generateBtn')}\n          </Button>\n          <Button\n            icon={<ClearOutlined />}\n            onClick={onClear}\n            className='flex-1 bg-gradient-to-r from-red-50 to-pink-50 text-red-600 border-red-400'\n          >\n            {t('aimarkmap.clearBtn')}\n          </Button>\n        </div>\n        <div className='flex gap-1'>\n          <Button\n            icon={<span>📄</span>}\n            onClick={() => onSwitchView('original')}\n            className={`flex-1 ${\n              currentViewMode === 'original'\n                ? 'bg-gradient-to-r from-indigo-500 to-purple-600 text-white'\n                : 'bg-gradient-to-r from-blue-50 to-purple-50 text-indigo-600 border-indigo-300'\n            }`}\n            disabled={!searchValue.trim()}\n          >\n            {t('aimarkmap.showOriginalBtn')}\n          </Button>\n          <Button\n            icon={<span>📝</span>}\n            onClick={() => onSwitchView('markdown')}\n            className={`flex-1 ${\n              currentViewMode === 'markdown'\n                ? 'bg-gradient-to-r from-indigo-500 to-purple-600 text-white'\n                : 'bg-gradient-to-r from-green-50 to-blue-50 text-green-700 border-green-500'\n            }`}\n            disabled={aiResults.length === 0 && !searchValue.trim().startsWith('#')}\n          >\n            {t('aimarkmap.showMarkdownBtn')}\n          </Button>\n        </div>\n      </div>\n\n      <div className='flex-1 p-2 sm:p-4 flex flex-col'>\n        <TextArea\n          value={searchValue}\n          placeholder={t('aimarkmap.topicInputPlaceholder')}\n          onInput={onTopicInput}\n          className={`w-full flex-1 min-h-[200px] ${\n            currentViewMode === 'input' ? 'block' : 'hidden'\n          }`}\n        />\n        <TextArea\n          value={currentViewMode === 'original' ? searchValue : currentMarkdown}\n          onChange={currentViewMode === 'markdown' ? onDisplayEdit : undefined}\n          readOnly={currentViewMode === 'original'}\n          placeholder={t('aimarkmap.contentDisplayPlaceholder')}\n          className={`w-full flex-1 min-h-[200px] ${\n            currentViewMode !== 'input' ? 'block' : 'hidden'\n          }`}\n        />\n      </div>\n    </div>\n  )\n}\n\nexport default EditorPanel\n"
  },
  {
    "path": "src/components/markmap/InfoModal.tsx",
    "content": "import React from 'react'\nimport { Modal } from 'antd'\nimport { useTranslation } from 'react-i18next'\n\ninterface InfoModalProps {\n  visible: boolean\n  onClose: () => void\n}\n\nconst InfoModal: React.FC<InfoModalProps> = ({ visible, onClose }) => {\n  const { t } = useTranslation()\n\n  return (\n    <Modal\n      title={t('aimarkmap.infoModalTitle')}\n      open={visible}\n      onCancel={onClose}\n      footer={null}\n      width={800}\n      className='max-h-[80vh]'\n    >\n      <div\n        className='overflow-y-auto max-h-[60vh] p-4'\n        dangerouslySetInnerHTML={{ __html: t('aimarkmap.infoModalContentHtml') }}\n      />\n    </Modal>\n  )\n}\n\nexport default InfoModal\n"
  },
  {
    "path": "src/components/markmap/LandscapeMode.tsx",
    "content": "import React from 'react'\nimport { Button } from 'antd'\nimport { FullscreenExitOutlined } from '@ant-design/icons'\nimport { useTranslation } from 'react-i18next'\n\ninterface LandscapeModeProps {\n  isVisible: boolean\n  landscapeContentRef: React.RefObject<HTMLDivElement>\n  aiResults: Array<{ markdown: string }>\n  activeResultIndex: number\n  onSwitchVersion: (index: number) => void\n  onExportSVG: () => void\n  onExportPNG: () => void\n  onClose: () => void\n}\n\nconst LandscapeMode: React.FC<LandscapeModeProps> = ({\n  isVisible,\n  landscapeContentRef,\n  aiResults,\n  activeResultIndex,\n  onSwitchVersion,\n  onExportSVG,\n  onExportPNG,\n  onClose\n}) => {\n  const { t } = useTranslation()\n\n  if (!isVisible) return null\n\n  return (\n    <div className='landscape-mode-overlay fixed inset-0 bg-white z-[9999] flex flex-col'>\n      <div className='flex justify-between items-center p-2 bg-gradient-to-r from-indigo-500 to-purple-600 text-white'>\n        <span className='text-sm font-semibold'>{t('aimarkmap.mindmapPreviewTitle')}</span>\n        <div className='flex gap-1 overflow-x-auto px-2'>\n          {aiResults.length > 1 && aiResults.map((_, index) => (\n            <Button\n              key={index}\n              size='small'\n              className={`${\n                index === activeResultIndex\n                  ? 'bg-white/40 font-bold border-white'\n                  : 'bg-white/20 border-white/30'\n              } text-white whitespace-nowrap`}\n              onClick={() => onSwitchVersion(index)}\n            >\n              {t('aimarkmap.js_tab_version', { i: index + 1 })}\n            </Button>\n          ))}\n        </div>\n        <div className='flex items-center gap-2'>\n          <Button\n            size='small'\n            onClick={onExportSVG}\n            className='bg-white/20 text-white border-white/30'\n          >\n            {t('aimarkmap.exportSvgBtn')}\n          </Button>\n          <Button\n            size='small'\n            onClick={onExportPNG}\n            className='bg-white/20 text-white border-white/30'\n          >\n            {t('aimarkmap.exportPngBtn')}\n          </Button>\n          <Button\n            size='small'\n            onClick={onClose}\n            className='bg-white/20 text-white border-white/30'\n          >\n            <FullscreenExitOutlined /> {t('aimarkmap.mobileCloseLandscape')}\n          </Button>\n        </div>\n      </div>\n      <div\n        id='landscape-content'\n        ref={landscapeContentRef}\n        className='flex-1 overflow-hidden relative bg-white'\n      ></div>\n    </div>\n  )\n}\n\nexport default LandscapeMode\n"
  },
  {
    "path": "src/components/markmap/MindmapPanel.tsx",
    "content": "import React from 'react'\nimport { Button } from 'antd'\nimport {\n  FullscreenOutlined,\n  FullscreenExitOutlined,\n  FileImageOutlined,\n  FileOutlined,\n  ZoomInOutlined,\n  ZoomOutOutlined,\n  CompressOutlined\n} from '@ant-design/icons'\nimport { useTranslation } from 'react-i18next'\n\ninterface MindmapPanelProps {\n  mindmapContainerRef: React.RefObject<HTMLDivElement>\n  mindmapSvgRef: React.RefObject<SVGSVGElement>\n  isLoading: boolean\n  timerSeconds: number\n  statusMessage: string\n  isFullscreen: boolean\n  aiResults: Array<{ markdown: string }>\n  activeResultIndex: number\n  zoomLevel: number\n  onToggleFullscreen: () => void\n  onExportSVG: () => void\n  onExportPNG: () => void\n  onSwitchVersion: (index: number) => void\n  onZoomIn: () => void\n  onZoomOut: () => void\n  onResetZoom: () => void\n  currentMobilePanel: 'editor' | 'mindmap'\n}\n\nconst MindmapPanel: React.FC<MindmapPanelProps> = ({\n  mindmapContainerRef,\n  mindmapSvgRef,\n  isLoading,\n  timerSeconds,\n  statusMessage,\n  isFullscreen,\n  aiResults,\n  activeResultIndex,\n  zoomLevel,\n  onToggleFullscreen,\n  onExportSVG,\n  onExportPNG,\n  onSwitchVersion,\n  onZoomIn,\n  onZoomOut,\n  onResetZoom,\n  currentMobilePanel\n}) => {\n  const { t } = useTranslation()\n\n  return (\n    <div\n      className={`mindmap-panel absolute sm:relative top-0 left-0 w-full h-full bg-white rounded-none sm:rounded-lg shadow-lg flex flex-col overflow-hidden transition-transform duration-300 z-0 sm:z-auto ${\n        currentMobilePanel === 'mindmap' ? 'translate-x-0' : 'translate-x-full sm:translate-x-0'\n      } ${currentMobilePanel === 'mindmap' ? 'opacity-100' : 'opacity-0 sm:opacity-100'} sm:opacity-100 sm:translate-x-0`}\n    >\n      <div className='bg-gradient-to-r from-indigo-500 to-purple-600 text-white p-2 sm:p-4 flex flex-wrap items-center gap-2'>\n        <span className='text-sm sm:text-base font-semibold'>{t('aimarkmap.mindmapPreviewTitle')}</span>\n        <div className='flex gap-1 order-3 w-full sm:w-auto sm:order-none'>\n          {aiResults.length > 1 && aiResults.map((_, index) => (\n            <Button\n              key={index}\n              size='small'\n              className={`${\n                index === activeResultIndex\n                  ? 'bg-white/40 font-bold border-white'\n                  : 'bg-white/20 border-white/30'\n              } text-white`}\n              onClick={() => onSwitchVersion(index)}\n            >\n              {t('aimarkmap.js_tab_version', { i: index + 1 })}\n            </Button>\n          ))}\n        </div>\n        <div className='flex items-center gap-2 ml-auto'>\n          <Button\n            size='small'\n            icon={<ZoomOutOutlined />}\n            onClick={onZoomOut}\n            className='bg-white/20 text-white border-white/30'\n            title={t('aimarkmap.js_zoom_out')}\n          />\n          <span className='text-sm font-medium w-12 text-center'>{Math.round(zoomLevel * 100)}%</span>\n          <Button\n            size='small'\n            icon={<ZoomInOutlined />}\n            onClick={onZoomIn}\n            className='bg-white/20 text-white border-white/30'\n            title={t('aimarkmap.js_zoom_in')}\n          />\n          <Button\n            size='small'\n            icon={<CompressOutlined />}\n            onClick={onResetZoom}\n            className='bg-white/20 text-white border-white/30'\n            title={t('aimarkmap.js_reset_zoom')}\n          />\n          <Button\n            size='small'\n            icon={isFullscreen ? <FullscreenExitOutlined /> : <FullscreenOutlined />}\n            onClick={onToggleFullscreen}\n            className='bg-white/20 text-white border-white/30 hidden sm:inline-flex'\n          >\n            {isFullscreen ? t('aimarkmap.js_exit_fullscreen') : t('aimarkmap.js_fullscreen')}\n          </Button>\n          <Button\n            size='small'\n            icon={<FileOutlined />}\n            onClick={onExportSVG}\n            className='bg-white/20 text-white border-white/30'\n          >\n            {t('aimarkmap.exportSvgBtn')}\n          </Button>\n          <Button\n            size='small'\n            icon={<FileImageOutlined />}\n            onClick={onExportPNG}\n            className='bg-white/20 text-white border-white/30'\n          >\n            {t('aimarkmap.exportPngBtn')}\n          </Button>\n        </div>\n      </div>\n\n      <div\n        ref={mindmapContainerRef}\n        className='flex-1 relative bg-white'\n      >\n        <svg ref={mindmapSvgRef} id='mindmap' className='w-full h-full'></svg>\n\n        {isLoading && (\n          <div className='absolute inset-0 bg-white/90 flex flex-col items-center justify-center z-50 gap-2'>\n            <div className='relative w-16 h-16'>\n              <div className='w-16 h-16 border-4 border-gray-200 border-t-indigo-600 rounded-full animate-spin'></div>\n              <span className='absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 font-semibold text-indigo-600'>\n                {timerSeconds.toFixed(1)}s\n              </span>\n            </div>\n            <div className='text-sm text-gray-600'>{t('aimarkmap.thinkingMessage')}</div>\n            <div className='text-xs text-gray-500'>{statusMessage}</div>\n          </div>\n        )}\n      </div>\n    </div>\n  )\n}\n\nexport default MindmapPanel\n"
  },
  {
    "path": "src/components/markmap/MobileMenu.tsx",
    "content": "import React from 'react'\nimport { Button } from 'antd'\nimport { InfoCircleOutlined, GithubOutlined } from '@ant-design/icons'\nimport { useTranslation } from 'react-i18next'\nimport { useChangeLanguage } from '@/hooks/useChangeLanguage'\n\ninterface MobileMenuProps {\n  isOpen: boolean\n  onClose: () => void\n  onOpenInfo: () => void\n}\n\nconst MobileMenu: React.FC<MobileMenuProps> = ({ isOpen, onClose, onOpenInfo }) => {\n  const { t, i18n } = useTranslation()\n  const changeLanguage = useChangeLanguage()\n\n  return (\n    <div\n      id='mobile-menu'\n      className={`fixed top-14 left-0 right-0 bg-white/98 backdrop-blur-md p-4 shadow-lg z-30 flex-col gap-3 max-h-[calc(100vh-3.5rem)] overflow-y-auto transition-all duration-300 sm:hidden ${\n        isOpen ? 'flex' : 'hidden'\n      }`}\n    >\n      <button\n        onClick={() => {\n          onOpenInfo()\n          onClose()\n        }}\n        className='flex items-center gap-3 p-3 bg-indigo-50 rounded-lg text-indigo-600 font-medium w-full text-left'\n      >\n        <InfoCircleOutlined className='text-xl' />\n        <span>{t('aimarkmap.helpBtnTitle')}</span>\n      </button>\n      <a\n        href='https://github.com/kongkongyo/Ai-Markmap'\n        target='_blank'\n        rel='noopener noreferrer'\n        className='flex items-center gap-3 p-3 bg-indigo-50 rounded-lg text-indigo-600 font-medium'\n      >\n        <GithubOutlined className='text-xl' />\n        <span>GitHub</span>\n      </a>\n      <div className='flex gap-2 pt-2'>\n        <Button\n          className={`flex-1 ${i18n.language === 'zh' ? 'bg-indigo-600 text-white' : 'bg-indigo-50 text-indigo-600 border-indigo-300'}`}\n          onClick={() => changeLanguage('zh')}\n        >\n          中文\n        </Button>\n        <Button\n          className={`flex-1 ${i18n.language === 'en' ? 'bg-indigo-600 text-white' : 'bg-indigo-50 text-indigo-600 border-indigo-300'}`}\n          onClick={() => changeLanguage('en')}\n        >\n          EN\n        </Button>\n      </div>\n    </div>\n  )\n}\n\nexport default MobileMenu\n"
  },
  {
    "path": "src/components/markmap/MobileTabBar.tsx",
    "content": "import React from 'react'\nimport { EditOutlined } from '@ant-design/icons'\nimport { useTranslation } from 'react-i18next'\n\ninterface MobileTabBarProps {\n  currentMobilePanel: 'editor' | 'mindmap'\n  onSwitchPanel: (panel: 'editor' | 'mindmap') => void\n  onToggleLandscape: () => void\n}\n\nconst MobileTabBar: React.FC<MobileTabBarProps> = ({\n  currentMobilePanel,\n  onSwitchPanel,\n  onToggleLandscape\n}) => {\n  const { t } = useTranslation()\n\n  return (\n    <div className='fixed bottom-0 left-0 right-0 h-14 bg-white border-t border-gray-200 flex justify-around items-center shadow-lg z-30 sm:hidden'>\n      <button\n        className={`tab-btn flex flex-col items-center justify-center gap-1 flex-1 h-full ${\n          currentMobilePanel === 'editor' ? 'text-indigo-600' : 'text-gray-600'\n        }`}\n        onClick={() => onSwitchPanel('editor')}\n      >\n        <EditOutlined className='text-2xl' />\n        <span className='text-xs'>{t('aimarkmap.mobileTabEditor')}</span>\n      </button>\n      <button\n        className={`tab-btn flex flex-col items-center justify-center gap-1 flex-1 h-full ${\n          currentMobilePanel === 'mindmap' ? 'text-indigo-600' : 'text-gray-600'\n        }`}\n        onClick={() => onSwitchPanel('mindmap')}\n      >\n        <svg className='w-6 h-6' viewBox='0 0 24 24' fill='none' stroke='currentColor' strokeWidth='2'>\n          <circle cx='12' cy='12' r='3'></circle>\n          <line x1='12' y1='2' x2='12' y2='6'></line>\n          <line x1='12' y1='18' x2='12' y2='22'></line>\n          <line x1='4.93' y1='4.93' x2='7.76' y2='7.76'></line>\n          <line x1='16.24' y1='16.24' x2='19.07' y2='19.07'></line>\n          <line x1='2' y1='12' x2='6' y2='12'></line>\n          <line x1='18' y1='12' x2='22' y2='12'></line>\n          <line x1='4.93' y1='19.07' x2='7.76' y2='16.24'></line>\n          <line x1='16.24' y1='7.76' x2='19.07' y2='4.93'></line>\n        </svg>\n        <span className='text-xs'>{t('aimarkmap.mobileTabMindmap')}</span>\n      </button>\n      <button\n        className={`tab-btn flex flex-col items-center justify-center gap-1 flex-1 h-full ${\n          currentMobilePanel === 'mindmap' ? 'text-indigo-600' : 'text-gray-600 opacity-50 pointer-events-none'\n        }`}\n        onClick={onToggleLandscape}\n      >\n        <svg className='w-6 h-6' viewBox='0 0 24 24' fill='none' stroke='currentColor' strokeWidth='2'>\n          <rect x='2' y='6' width='20' height='12' rx='2'></rect>\n          <path d='M12 10v4'></path>\n          <path d='M10 12h4'></path>\n        </svg>\n        <span className='text-xs'>{t('aimarkmap.mobileTabLandscape')}</span>\n      </button>\n    </div>\n  )\n}\n\nexport default MobileTabBar\n"
  },
  {
    "path": "src/components/markmap/PromptModal.tsx",
    "content": "import React from 'react'\nimport { Modal, Input, Button } from 'antd'\nimport { useTranslation } from 'react-i18next'\n\nconst { TextArea } = Input\n\ninterface PromptModalProps {\n  visible: boolean\n  promptTemplate: string\n  onPromptChange: (value: string) => void\n  onSave: () => void\n  onCancel: () => void\n}\n\nconst PromptModal: React.FC<PromptModalProps> = ({\n  visible,\n  promptTemplate,\n  onPromptChange,\n  onSave,\n  onCancel\n}) => {\n  const { t } = useTranslation()\n\n  return (\n    <Modal\n      title={t('aimarkmap.promptSettingsTitle')}\n      open={visible}\n      onCancel={onCancel}\n      footer={null}\n      className='max-w-2xl'\n    >\n      <div className='space-y-4 py-4'>\n        <div\n          className='bg-blue-50 border border-blue-200 text-blue-600 p-3 rounded text-sm'\n          dangerouslySetInnerHTML={{ __html: t('aimarkmap.promptTip') }}\n        />\n        <TextArea\n          value={promptTemplate}\n          onChange={(e) => onPromptChange(e.target.value)}\n          placeholder={t('aimarkmap.promptInputPlaceholder')}\n          rows={10}\n          className='min-h-[200px]'\n        />\n        <div className='flex justify-end'>\n          <Button type='primary' onClick={onSave}>\n            {t('aimarkmap.saveAndCloseBtn')}\n          </Button>\n        </div>\n      </div>\n    </Modal>\n  )\n}\n\nexport default PromptModal\n"
  },
  {
    "path": "src/components/video/VideoDownload.tsx",
    "content": "import React, { useState } from 'react'\nimport { Input, Button, message, Typography, Card, Spin, Tag, Space, Divider, Progress } from 'antd'\nimport { LinkOutlined, DownloadOutlined, LoadingOutlined, PlayCircleOutlined, ReloadOutlined } from '@ant-design/icons'\nimport styled from 'styled-components'\nimport { useTranslation } from 'react-i18next'\n\nconst { Title, Text, Paragraph } = Typography\nconst { TextArea } = Input\n\ninterface VideoFormat {\n  format_id: string\n  ext: string\n  url: string\n  vcodec: string\n  acodec: string\n  width?: number\n  height?: number\n  filesize?: number\n}\n\ninterface VideoInfo {\n  title: string\n  thumbnail: string\n  duration: number\n  url: string | null\n  webpage_url: string\n  formats: VideoFormat[]\n  _source: string\n  _bilibili_dash?: boolean\n  _解析方式?: string\n}\n\ninterface DownloadProgress {\n  formatId: string\n  loaded: number\n  total: number\n  percentage: number\n}\n\nconst PageContainer = styled.div`\n  max-width: 900px;\n  margin: 0 auto;\n`\n\nconst InputCard = styled(Card)`\n  border-radius: 16px;\n  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);\n  margin-bottom: 32px;\n  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);\n\n  .ant-card-body {\n    padding: 32px;\n  }\n`\n\nconst InputHeader = styled.div`\n  text-align: center;\n  margin-bottom: 24px;\n`\n\nconst GradientTitle = styled(Title)`\n  background: linear-gradient(90deg, #6a11cb 0%, #2575fc 50%, #ff2575 100%);\n  -webkit-background-clip: text;\n  -webkit-text-fill-color: transparent;\n  background-clip: text;\n  margin-bottom: 8px !important;\n`\n\nconst StyledTextArea = styled(TextArea)`\n  border-radius: 12px;\n  border: 2px solid #e0e0e0;\n  padding: 16px;\n  font-size: 15px;\n  transition: all 0.3s ease;\n\n  &:focus {\n    border-color: #667eea;\n    box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);\n  }\n\n  &::placeholder {\n    color: #999;\n  }\n`\n\nconst ExtractButton = styled(Button)`\n  margin-top: 20px;\n  height: 48px;\n  border-radius: 12px;\n  font-size: 16px;\n  font-weight: 600;\n  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n  border: none;\n  color: #fff;\n  box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  gap: 8px;\n  width: 100%;\n\n  &:hover {\n    background: linear-gradient(135deg, #5568d3 0%, #6a3f8f 100%);\n    color: #fff;\n    box-shadow: 0 6px 20px rgba(102, 126, 234, 0.6);\n    transform: translateY(-2px);\n  }\n\n  &:active {\n    transform: translateY(0);\n  }\n`\n\nconst ResultCard = styled(Card)`\n  border-radius: 16px;\n  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);\n  margin-bottom: 20px;\n  overflow: hidden;\n\n  .ant-card-body {\n    padding: 0;\n  }\n`\n\nconst VideoHeader = styled.div`\n  display: flex;\n  gap: 20px;\n  padding: 24px;\n  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);\n`\n\nconst ThumbnailWrapper = styled.div`\n  position: relative;\n  flex-shrink: 0;\n  border-radius: 12px;\n  overflow: hidden;\n  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n\n  img {\n    width: 200px;\n    height: 150px;\n    object-fit: cover;\n    display: block;\n  }\n`\n\nconst PlayOverlay = styled.div`\n  position: absolute;\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  background: rgba(0, 0, 0, 0.3);\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  opacity: 0;\n  transition: opacity 0.3s ease;\n\n  &:hover {\n    opacity: 1;\n  }\n`\n\nconst VideoInfo = styled.div`\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  justify-content: center;\n`\n\nconst VideoTitle = styled(Title)`\n  margin-bottom: 12px !important;\n  line-height: 1.4 !important;\n`\n\nconst MetaInfo = styled(Space)`\n  margin-bottom: 12px;\n`\n\nconst FormatSection = styled.div`\n  padding: 24px;\n  background: #fff;\n`\n\nconst FormatTitle = styled(Title)`\n  font-size: 18px;\n  margin-bottom: 20px !important;\n`\n\nconst FormatGrid = styled.div`\n  display: grid;\n  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n  gap: 16px;\n`\n\nconst FormatCard = styled.div`\n  border: 2px solid #e8e8e8;\n  border-radius: 12px;\n  padding: 16px;\n  transition: all 0.3s ease;\n  background: #fafafa;\n\n  &:hover {\n    border-color: #667eea;\n    background: #f0f3ff;\n    box-shadow: 0 4px 12px rgba(102, 126, 234, 0.15);\n  }\n`\n\nconst FormatHeader = styled.div`\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  margin-bottom: 12px;\n`\n\nconst FormatTag = styled(Tag)`\n  margin: 0;\n  padding: 4px 12px;\n  border-radius: 6px;\n  font-weight: 500;\n`\n\nconst FormatDetails = styled.div`\n  color: #666;\n  font-size: 13px;\n  margin-bottom: 16px;\n  line-height: 1.8;\n`\n\nconst DownloadButton = styled(Button)`\n  width: 100%;\n  height: 40px;\n  border-radius: 8px;\n  font-weight: 500;\n  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n  border: none;\n  color: #fff;\n\n  &:hover {\n    background: linear-gradient(135deg, #5568d3 0%, #6a3f8f 100%);\n    color: #fff;\n  }\n`\n\nconst SupportSection = styled.div`\n  margin-top: 60px;\n\n  h3 {\n    text-align: center;\n    margin-bottom: 30px;\n    font-size: 1.5rem;\n    color: #333;\n  }\n`\n\nconst PlatformGrid = styled.div`\n  display: grid;\n  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));\n  gap: 20px;\n\n  @media (max-width: 768px) {\n    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));\n    gap: 15px;\n  }\n`\n\nconst PlatformCard = styled.a`\n  display: block;\n  background: #fff;\n  padding: 20px;\n  border-radius: 12px;\n  text-align: center;\n  text-decoration: none;\n  color: #333;\n  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n  transition: all 0.3s ease;\n  cursor: pointer;\n\n  &:hover {\n    transform: translateY(-5px);\n    box-shadow: 0 8px 16px rgba(0, 0, 0, 0.12);\n  }\n\n  .platform-name {\n    font-weight: 600;\n    margin-bottom: 8px;\n    color: #667eea;\n  }\n\n  .platform-status {\n    font-size: 0.85rem;\n    color: #52c41a;\n  }\n`\n\nconst formatFileSize = (bytes?: number): string => {\n  if (!bytes) return '未知大小'\n  const units = ['B', 'KB', 'MB', 'GB']\n  let size = bytes\n  let unitIndex = 0\n  while (size >= 1024 && unitIndex < units.length - 1) {\n    size /= 1024\n    unitIndex++\n  }\n  return `${size.toFixed(2)} ${units[unitIndex]}`\n}\n\nconst formatDuration = (seconds: number): string => {\n  const mins = Math.floor(seconds / 60)\n  const secs = seconds % 60\n  return `${mins}:${secs.toString().padStart(2, '0')}`\n}\n\n// 支持的视频平台列表\nconst getPlatforms = (t: any) => [\n  { name: t('video.bilibili'), url: 'https://www.bilibili.com/', status: t('video.availableRecommended') },\n  { name: t('video.douyin'), url: 'https://www.douyin.com/', status: t('video.availableRecommended') },\n  { name: t('video.xiaohongshu'), url: 'https://www.xiaohongshu.com/', status: t('video.availableRecommended') },\n]\n\nconst VideoDownload: React.FC = () => {\n  const { t } = useTranslation()\n  const PLATFORMS = getPlatforms(t)\n  const [videoUrl, setVideoUrl] = useState('')\n  const [loading, setLoading] = useState(false)\n  const [videoInfo, setVideoInfo] = useState<VideoInfo | null>(null)\n  const [downloadProgress, setDownloadProgress] = useState<Record<string, DownloadProgress>>({})\n\n  const handleExtract = async () => {\n    if (!videoUrl.trim()) {\n      message.warning('请输入视频链接')\n      return\n    }\n\n    // 验证URL格式\n    try {\n      new URL(videoUrl)\n    } catch {\n      message.error('请输入有效的视频链接')\n      return\n    }\n\n    setLoading(true)\n    setVideoInfo(null)\n\n    try {\n      const response = await fetch('/api/resolve', {\n        method: 'POST',\n        headers: {\n          'Content-Type': 'application/json',\n        },\n        body: JSON.stringify({ url: videoUrl })\n      })\n\n      if (!response.ok) {\n        const responseText = await response.text()\n        let errorMessage = '解析失败'\n        try {\n          const errorData = JSON.parse(responseText)\n          errorMessage = errorData.error || errorData.message || errorMessage\n        } catch {\n          if (responseText) {\n            errorMessage = `解析失败 (${response.status}): ${responseText.substring(0, 200)}`\n          }\n        }\n        throw new Error(errorMessage)\n      }\n\n      const data: VideoInfo = await response.json()\n\n      if (!data.formats || data.formats.length === 0) {\n        message.warning('未找到可下载的视频格式')\n      } else {\n        setVideoInfo(data)\n        message.success('解析成功')\n      }\n    } catch (error) {\n      message.error('解析失败，请检查链接是否正确')\n      console.error('解析错误:', error)\n    } finally {\n      setLoading(false)\n    }\n  }\n\n  const handleDownload = async (format: VideoFormat, index: number) => {\n    const formatId = `download-${index}`\n\n    // 检测是否是B站视频\n    const isBilibili = videoInfo?._source === 'bilibili_official_api' ||\n                       videoInfo?.webpage_url?.includes('bilibili.com')\n\n    // 检测是否是抖音视频\n    const isDouyin = videoInfo?._source?.includes('douyin') ||\n                     videoInfo?.webpage_url?.includes('douyin.com')\n    \n    // 检测是否是小红书视频\n    const isXHS = videoInfo?._source?.includes('\"xiaohongshu') ||\n                     videoInfo?.webpage_url?.includes('xiaohongshu.com')\n\n    console.log('🔍 下载调试信息:', {\n      index,\n      formatId,\n      isBilibili,\n      isDouyin,\n      isXHS,\n      _source: videoInfo?._source,\n      url: videoInfo?.webpage_url,\n      ext: format.ext,\n      vcodec: format.vcodec,\n      bilibiliCondition: isBilibili && format.ext === 'mp4' && format.vcodec !== 'none',\n      douyinCondition: (isDouyin || isXHS) && format.ext === 'mp4' && format.vcodec !== 'none'\n    })\n\n    // 如果是B站的MP4视频，使用特殊下载API\n    if (isBilibili && format.ext === 'mp4' && format.vcodec !== 'none') {\n      console.log('✅ 使用B站下载API')\n      message.loading('正在准备下载...', 0)\n\n      try {\n        // 使用fetch发送POST请求到bilibili-download API\n        const response = await fetch('/api/bilibili-download', {\n          method: 'POST',\n          headers: {\n            'Content-Type': 'application/json',\n          },\n          body: JSON.stringify({ url: videoInfo?.webpage_url })\n        })\n\n        message.destroy()\n\n        if (response.ok) {\n          // 获取响应的Content-Type\n          const contentType = response.headers.get('content-type') || ''\n          console.log('📡 响应Content-Type:', contentType)\n\n          if (contentType.includes('application/json')) {\n            console.log('📄 JSON响应，解析中...')\n            // JSON响应 - 可能包含下载链接\n            const data = await response.json()\n            if (data.url || data.download_url) {\n              const downloadUrl = data.url || data.download_url\n              // 使用带进度的下载\n              await downloadWithProgress(downloadUrl, `${videoInfo?.title || 'video'}.mp4`, formatId)\n            } else {\n              message.warning('未获取到下载链接，使用备用下载方式')\n              // 回退到直接下载\n              const link = document.createElement('a')\n              link.href = format.url\n              link.target = '_blank'\n              document.body.appendChild(link)\n              link.click()\n              document.body.removeChild(link)\n              message.success('开始下载')\n            }\n          } else {\n            // 视频文件响应 - 带进度下载\n            console.log('🎬 视频文件响应，开始带进度下载')\n            const contentLength = response.headers.get('content-length')\n            const total = contentLength ? parseInt(contentLength, 10) : 0\n            console.log('📦 文件大小:', total, 'bytes')\n\n            const reader = response.body?.getReader()\n            const chunks: Uint8Array[] = []\n            let receivedLength = 0\n\n            if (reader) {\n              console.log('✅ Reader创建成功，初始化进度')\n              // 初始化进度\n              setDownloadProgress({\n                [formatId]: { formatId, loaded: 0, total, percentage: 0 }\n              })\n\n              while (true) {\n                const { done, value } = await reader.read()\n\n                if (done) break\n\n                chunks.push(value)\n                receivedLength += value.length\n\n                // 更新进度\n                const percentage = total > 0 ? Math.round((receivedLength / total) * 100) : 0\n                console.log(`📊 下载进度: ${percentage}% (${receivedLength}/${total})`)\n                setDownloadProgress(prev => ({\n                  ...prev,\n                  [formatId]: { formatId, loaded: receivedLength, total, percentage }\n                }))\n              }\n\n              console.log('✅ 下载完成，创建Blob')\n\n              // 合并所有chunks\n              const blob = new Blob(chunks.map(chunk => chunk.buffer as ArrayBuffer), { type: contentType })\n              const url = URL.createObjectURL(blob)\n\n              // 下载文件\n              const link = document.createElement('a')\n              link.href = url\n              link.download = `${videoInfo?.title || 'video'}.mp4`\n              document.body.appendChild(link)\n              link.click()\n              document.body.removeChild(link)\n              URL.revokeObjectURL(url)\n\n              // 清除进度\n              setDownloadProgress(prev => {\n                const newProgress = { ...prev }\n                delete newProgress[formatId]\n                return newProgress\n              })\n\n              message.success('下载完成！')\n            } else {\n              throw new Error('无法读取响应流')\n            }\n          }\n        } else {\n          throw new Error(`HTTP ${response.status}`)\n        }\n      } catch (error) {\n        message.destroy()\n        message.error('下载失败，使用直接下载')\n        console.error('B站下载错误:', error)\n\n        // 清除进度\n        setDownloadProgress(prev => {\n          const newProgress = { ...prev }\n          delete newProgress[formatId]\n          return newProgress\n        })\n\n        // 失败时回退到直接下载\n        const link = document.createElement('a')\n        link.href = format.url\n        link.target = '_blank'\n        document.body.appendChild(link)\n        link.click()\n        document.body.removeChild(link)\n        message.success('开始下载')\n      }\n    } else if ((isDouyin || isXHS) && format.ext === 'mp4' && format.vcodec !== 'none') {\n      // 如果是抖音或小红书的MP4视频，使用proxy-download API\n      console.log('✅ 使用抖音/小红书下载API')\n      message.loading('正在准备下载...', 0)\n\n      try {\n        const filename = `${videoInfo?.title || 'video'}.mp4`\n\n        // 使用fetch发送POST请求到proxy-download API\n        const response = await fetch('/api/proxy-download', {\n          method: 'POST',\n          headers: {\n            'Content-Type': 'application/json',\n          },\n          body: JSON.stringify({\n            url: videoInfo?.url,\n            filename: filename\n          })\n        })\n\n        message.destroy()\n\n        if (response.ok) {\n          // 获取响应的Content-Type\n          const contentType = response.headers.get('content-type') || ''\n          console.log('📡 抖音响应Content-Type:', contentType)\n\n          if (contentType.includes('application/json')) {\n            console.log('📄 JSON响应，解析中...')\n            // JSON响应 - 可能包含错误信息\n            const data = await response.json()\n            if (data.error) {\n              message.error(data.error || '下载失败')\n            } else if (data.url || data.download_url) {\n              const downloadUrl = data.url || data.download_url\n              // 使用带进度的下载\n              await downloadWithProgress(downloadUrl, filename, formatId)\n            } else {\n              message.warning('未获取到下载链接，使用备用下载方式')\n              // 回退到直接下载\n              const link = document.createElement('a')\n              link.href = format.url\n              link.target = '_blank'\n              document.body.appendChild(link)\n              link.click()\n              document.body.removeChild(link)\n              message.success('开始下载')\n            }\n          } else {\n            // 视频文件响应 - 带进度下载\n            console.log('🎬 视频文件响应，开始带进度下载')\n            const contentLength = response.headers.get('content-length')\n            const total = contentLength ? parseInt(contentLength, 10) : 0\n            console.log('📦 文件大小:', total, 'bytes')\n\n            const reader = response.body?.getReader()\n            const chunks: Uint8Array[] = []\n            let receivedLength = 0\n\n            if (reader) {\n              console.log('✅ Reader创建成功，初始化进度')\n              // 初始化进度\n              setDownloadProgress({\n                [formatId]: { formatId, loaded: 0, total, percentage: 0 }\n              })\n\n              while (true) {\n                const { done, value } = await reader.read()\n\n                if (done) break\n\n                chunks.push(value)\n                receivedLength += value.length\n\n                // 更新进度\n                const percentage = total > 0 ? Math.round((receivedLength / total) * 100) : 0\n                console.log(`📊 下载进度: ${percentage}% (${receivedLength}/${total})`)\n                setDownloadProgress(prev => ({\n                  ...prev,\n                  [formatId]: { formatId, loaded: receivedLength, total, percentage }\n                }))\n              }\n\n              console.log('✅ 下载完成，创建Blob')\n\n              // 合并所有chunks\n              const blob = new Blob(chunks.map(chunk => chunk.buffer as ArrayBuffer), { type: contentType })\n              const url = URL.createObjectURL(blob)\n\n              // 下载文件\n              const link = document.createElement('a')\n              link.href = url\n              link.download = filename\n              document.body.appendChild(link)\n              link.click()\n              document.body.removeChild(link)\n              URL.revokeObjectURL(url)\n\n              // 清除进度\n              setDownloadProgress(prev => {\n                const newProgress = { ...prev }\n                delete newProgress[formatId]\n                return newProgress\n              })\n\n              message.success('下载完成！')\n            } else {\n              throw new Error('无法读取响应流')\n            }\n          }\n        } else {\n          throw new Error(`HTTP ${response.status}`)\n        }\n      } catch (error) {\n        message.destroy()\n        console.error('❌ 抖音下载错误:', error)\n        message.error('下载失败，使用直接下载')\n\n        // 清除进度\n        setDownloadProgress(prev => {\n          const newProgress = { ...prev }\n          delete newProgress[formatId]\n          return newProgress\n        })\n\n        // 失败时回退到直接下载\n        const link = document.createElement('a')\n        link.href = format.url\n        link.target = '_blank'\n        document.body.appendChild(link)\n        link.click()\n        document.body.removeChild(link)\n        message.success('开始下载')\n      }\n    } else {\n      // 非B站视频或音频文件，直接下载\n      console.log('🔗 非B站MP4，使用直接下载')\n      const link = document.createElement('a')\n      link.href = format.url\n      link.download = `${videoInfo?.title || 'video'}.${format.ext}`\n      link.target = '_blank'\n      document.body.appendChild(link)\n      link.click()\n      document.body.removeChild(link)\n      message.success('开始下载')\n    }\n  }\n\n  // 带进度的下载函数\n  const downloadWithProgress = async (url: string, filename: string, formatId: string) => {\n    try {\n      const response = await fetch(url)\n\n      if (!response.ok) {\n        throw new Error(`HTTP ${response.status}`)\n      }\n\n      const contentLength = response.headers.get('content-length')\n      const total = contentLength ? parseInt(contentLength, 10) : 0\n\n      const reader = response.body?.getReader()\n      const chunks: Uint8Array[] = []\n      let receivedLength = 0\n\n      if (reader) {\n        // 初始化进度\n        setDownloadProgress({\n          [formatId]: { formatId, loaded: 0, total, percentage: 0 }\n        })\n\n        while (true) {\n          const { done, value } = await reader.read()\n\n          if (done) break\n\n          chunks.push(value)\n          receivedLength += value.length\n\n          // 更新进度\n          const percentage = total > 0 ? Math.round((receivedLength / total) * 100) : 0\n          setDownloadProgress(prev => ({\n            ...prev,\n            [formatId]: { formatId, loaded: receivedLength, total, percentage }\n          }))\n        }\n\n        // 合并所有chunks\n        const blob = new Blob(chunks.map(chunk => chunk.buffer as ArrayBuffer))\n        const blobUrl = URL.createObjectURL(blob)\n\n        // 下载文件\n        const link = document.createElement('a')\n        link.href = blobUrl\n        link.download = filename\n        document.body.appendChild(link)\n        link.click()\n        document.body.removeChild(link)\n        URL.revokeObjectURL(blobUrl)\n\n        // 清除进度\n        setDownloadProgress(prev => {\n          const newProgress = { ...prev }\n          delete newProgress[formatId]\n          return newProgress\n        })\n\n        message.success('下载完成！')\n      } else {\n        throw new Error('无法读取响应流')\n      }\n    } catch (error) {\n      // 清除进度\n      setDownloadProgress(prev => {\n        const newProgress = { ...prev }\n        delete newProgress[formatId]\n        return newProgress\n      })\n\n      throw error\n    }\n  }\n\n  const getCodecInfo = (format: VideoFormat): string => {\n    const parts: string[] = []\n    if (format.vcodec && format.vcodec !== 'none') {\n      parts.push(`视频: ${format.vcodec}`)\n    }\n    if (format.acodec && format.acodec !== 'none') {\n      parts.push(`音频: ${format.acodec}`)\n    }\n    return parts.length > 0 ? parts.join(' | ') : '未知编码'\n  }\n\n  const handleReset = () => {\n    setVideoUrl('')\n    setVideoInfo(null)\n    setDownloadProgress({})\n  }\n\n  const handlePlatformClick = (platform: { name: string; url: string }) => {\n    window.open(platform.url, '_blank')\n  }\n\n  return (\n    <PageContainer>\n      <InputCard>\n        <InputHeader>\n          <GradientTitle level={2}>{t('video.downloadTitle')}</GradientTitle>\n          <Paragraph style={{ color: '#666', marginBottom: 0 }}>\n            {t('video.downloadDescription')}\n          </Paragraph>\n        </InputHeader>\n\n        <StyledTextArea\n          value={videoUrl}\n          onChange={(e) => setVideoUrl(e.target.value)}\n          placeholder={t('video.downloadPlaceholder')}\n          autoSize={{ minRows: 3, maxRows: 6 }}\n          // @ts-ignore\n          prefix={<LinkOutlined />}\n          onPressEnter={handleExtract}\n        />\n\n        <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>\n          <ExtractButton\n            icon={loading ? <LoadingOutlined /> : <DownloadOutlined />}\n            onClick={handleExtract}\n            loading={loading}\n          >\n            {loading ? t('video.extracting') : t('video.extractVideo')}\n          </ExtractButton>\n          <ExtractButton\n            icon={<ReloadOutlined />}\n            onClick={handleReset}\n            style={{ borderRadius: '12px', marginLeft: '12px' }}\n          >\n            {t('video.reset')}\n          </ExtractButton>\n        </div>\n      </InputCard>\n\n      {loading && (\n        <div style={{ textAlign: 'center', padding: '40px' }}>\n          <Spin size=\"large\" />\n          <p style={{ marginTop: '16px', color: '#999' }}>正在解析视频信息...</p>\n        </div>\n      )}\n\n      {!loading && videoInfo && (\n        <ResultCard>\n          <VideoHeader>\n            <ThumbnailWrapper>\n              <img\n                src={videoInfo.thumbnail}\n                alt={videoInfo.title}\n                referrerPolicy=\"no-referrer\"\n                onError={(e) => {\n                  const target = e.target as HTMLImageElement\n                  target.src = 'data:image/svg+xml,%3Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"200\" height=\"150\"%3E%3Crect fill=\"%23f0f0f0\" width=\"200\" height=\"150\"/%3E%3Ctext fill=\"%23999\" x=\"50%25\" y=\"50%25\" text-anchor=\"middle\" dy=\".3em\"%3E无封面%3C/text%3E%3C/svg%3E'\n                }}\n              />\n              <PlayOverlay>\n                <PlayCircleOutlined style={{ fontSize: '48px', color: '#fff' }} />\n              </PlayOverlay>\n            </ThumbnailWrapper>\n            <VideoInfo>\n              <VideoTitle level={4} ellipsis={{ rows: 2 }}>\n                {videoInfo.title}\n              </VideoTitle>\n              <MetaInfo wrap>\n                <Tag color=\"blue\">时长: {formatDuration(videoInfo.duration)}</Tag>\n                <Tag color=\"purple\">{videoInfo._source}</Tag>\n                {videoInfo._解析方式 && (\n                  <Tag color=\"green\">{videoInfo._解析方式}</Tag>\n                )}\n              </MetaInfo>\n              {videoInfo.webpage_url && (\n                <Text type=\"secondary\" style={{ fontSize: '13px' }}>\n                  来源: <a href={videoInfo.webpage_url} target=\"_blank\" rel=\"noopener noreferrer\">\n                    {videoInfo.webpage_url}\n                  </a>\n                </Text>\n              )}\n            </VideoInfo>\n          </VideoHeader>\n\n          <Divider style={{ margin: 0 }} />\n\n          <FormatSection>\n            <FormatTitle level={4}>{t('video.downloadFormat')}</FormatTitle>\n            <FormatGrid>\n              {videoInfo.formats.map((format, index) => {\n                // 调试日志\n                const isBilibili = videoInfo._source === 'bilibili_official_api' || videoInfo.webpage_url?.includes('bilibili.com')\n                const isDouyin = videoInfo._source?.includes('douyin') || videoInfo.webpage_url?.includes('douyin.com')\n                console.log(`📦 格式 ${index}:`, {\n                  ext: format.ext,\n                  vcodec: format.vcodec,\n                  acodec: format.acodec,\n                  isBilibili,\n                  isDouyin,\n                  willUseBilibiliProgress: isBilibili && format.ext === 'mp4' && format.vcodec !== 'none',\n                  willUseDouyinProgress: isDouyin && format.ext === 'mp4' && format.vcodec !== 'none'\n                })\n\n                return (\n                <FormatCard key={index}>\n                  <FormatHeader>\n                    <FormatTag color={format.vcodec !== 'none' ? 'blue' : 'orange'}>\n                      {format.vcodec !== 'none' ? '视频' : '音频'}\n                    </FormatTag>\n                    <FormatTag color=\"default\">{format.ext.toUpperCase()}</FormatTag>\n                  </FormatHeader>\n                  <FormatDetails>\n                    {format.width && format.height && (\n                      <div>分辨率: {format.width} × {format.height}</div>\n                    )}\n                    <div>大小: {formatFileSize(format.filesize)}</div>\n                    <div>编码: {getCodecInfo(format)}</div>\n                  </FormatDetails>\n                  <DownloadButton\n                    icon={<DownloadOutlined />}\n                    onClick={() => handleDownload(format, index)}\n                    disabled={!!downloadProgress[`download-${index}`]}\n                  >\n                    {downloadProgress[`download-${index}`]\n                      ? `下载中 ${downloadProgress[`download-${index}`].percentage}%`\n                      : `下载 ${format.ext.toUpperCase()}`\n                    }\n                  </DownloadButton>\n                  {downloadProgress[`download-${index}`] && (\n                    <div style={{ marginTop: '12px' }}>\n                      <Progress\n                        percent={downloadProgress[`download-${index}`].percentage}\n                        status=\"active\"\n                        size=\"small\"\n                        strokeColor={{\n                          '0%': '#667eea',\n                          '100%': '#764ba2',\n                        }}\n                      />\n                      <div style={{ fontSize: '12px', color: '#666', marginTop: '4px', textAlign: 'center' }}>\n                        {formatFileSize(downloadProgress[`download-${index}`].loaded)} / {formatFileSize(downloadProgress[`download-${index}`].total)}\n                      </div>\n                    </div>\n                  )}\n                </FormatCard>\n                )\n              })}\n            </FormatGrid>\n          </FormatSection>\n        </ResultCard>\n      )}\n\n      {!loading && !videoInfo && (\n        <SupportSection>\n          <h3>{t('video.supportedSites')}</h3>\n          <PlatformGrid>\n            {PLATFORMS.map((platform: any) => (\n              <PlatformCard\n                key={platform.name}\n                onClick={() => handlePlatformClick(platform)}\n              >\n                <div className=\"platform-name\">{platform.name}</div>\n                <div className=\"platform-status\">{platform.status}</div>\n              </PlatformCard>\n            ))}\n          </PlatformGrid>\n        </SupportSection>\n      )}\n\n    </PageContainer>\n  )\n}\n\nexport default VideoDownload\n"
  },
  {
    "path": "src/components/video/VideoParse.tsx",
    "content": "import React, { useState } from 'react'\nimport { Input, Button, Select, message, Typography } from 'antd'\nimport { PlayCircleOutlined, FullscreenOutlined, FullscreenExitOutlined } from '@ant-design/icons'\nimport { useTranslation } from 'react-i18next'\nimport styled from 'styled-components'\n\nconst { Title, Paragraph } = Typography\nconst { Option } = Select\n\n// 扩展 ScreenOrientation 类型以支持 lock 和 unlock 方法\ndeclare global {\n  interface ScreenOrientation {\n    lock?(orientation: any): Promise<void>\n    // @ts-ignore\n    unlock?(): void\n  }\n}\n\n// 视频解析接口列表\nconst getApiList = (t: any) => [\n  {\n    name: t('video.api1'),\n    url: import.meta.env.VITE_VIDEO_PARSE_URL1 || ''\n  },\n  {\n    name: t('video.api2'),\n    url: import.meta.env.VITE_VIDEO_PARSE_URL2 || ''\n  },\n  {\n    name: t('video.api3'),\n    url: import.meta.env.VITE_VIDEO_PARSE_URL3 || ''\n  },\n  {\n    name: t('video.api4'),\n    url: import.meta.env.VITE_VIDEO_PARSE_URL4 || ''\n  },\n  {\n    name: t('video.api5'),\n    url: import.meta.env.VITE_VIDEO_PARSE_URL5 || ''\n  }\n]\n\nconst PageContainer = styled.div`\n  max-width: 1200px;\n  margin: 0 auto;\n  padding: 40px 20px;\n  min-height: calc(100vh - 200px);\n`\n\nconst SearchSection = styled.div`\n  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n  padding: 40px;\n  border-radius: 16px;\n  margin-bottom: 40px;\n  text-align: center;\n  color: #fff;\n  box-shadow: 0 8px 24px rgba(102, 126, 234, 0.3);\n\n  h2 {\n    margin-bottom: 20px;\n    font-size: 2rem;\n  }\n\n  p {\n    margin-bottom: 30px;\n    opacity: 0.9;\n  }\n`\n\nconst FormSection = styled.div`\n  display: flex;\n  gap: 12px;\n  justify-content: center;\n  align-items: center;\n  flex-wrap: wrap;\n  max-width: 900px;\n  margin: 0 auto;\n`\n\nconst VideoSection = styled.div<{ $isFullscreen: boolean }>`\n  background: #fff;\n  border-radius: 16px;\n  padding: 20px;\n  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);\n  margin-bottom: 40px;\n  position: ${props => props.$isFullscreen ? 'fixed' : 'relative'};\n  top: ${props => props.$isFullscreen ? '0' : 'auto'};\n  left: ${props => props.$isFullscreen ? '0' : 'auto'};\n  width: ${props => props.$isFullscreen ? '100vw' : 'auto'};\n  height: ${props => props.$isFullscreen ? '100vh' : 'auto'};\n  z-index: ${props => props.$isFullscreen ? '9999' : 'auto'};\n  border-radius: ${props => props.$isFullscreen ? '0' : '16px'};\n  padding: ${props => props.$isFullscreen ? '0' : '20px'};\n\n  iframe {\n    width: 100%;\n    height: ${props => props.$isFullscreen ? '100vh' : '600px'};\n    border: none;\n    border-radius: 8px;\n    background: #000;\n    display: block;\n  }\n\n  @media (max-width: 768px) {\n    padding: ${props => props.$isFullscreen ? '0' : '10px'};\n\n    iframe {\n      height: ${props => props.$isFullscreen ? '100vh' : '300px'};\n    }\n  }\n`\n\nconst FullscreenButton = styled(Button)`\n  position: absolute;\n  top: 30px;\n  right: 30px;\n  z-index: 10;\n  background: rgba(0, 0, 0, 0.6) !important;\n  border: none !important;\n  color: #fff !important;\n\n  &:hover {\n    background: rgba(0, 0, 0, 0.8) !important;\n  }\n`\n\nconst RotatePrompt = styled.div<{ $show: boolean }>`\n  position: fixed;\n  top: 0;\n  left: 0;\n  width: 100vw;\n  height: 100vh;\n  background: rgba(0, 0, 0, 0.9);\n  display: ${props => props.$show ? 'flex' : 'none'};\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  z-index: 10000;\n  color: #fff;\n  text-align: center;\n  padding: 20px;\n\n  .icon {\n    font-size: 64px;\n    margin-bottom: 20px;\n    animation: rotate 1.5s ease-in-out infinite;\n  }\n\n  .text {\n    font-size: 1.2rem;\n    line-height: 1.6;\n  }\n\n  .sub-text {\n    font-size: 0.9rem;\n    margin-top: 15px;\n    opacity: 0.7;\n  }\n\n  @keyframes rotate {\n    0% {\n      transform: rotate(0deg);\n    }\n    25% {\n      transform: rotate(-90deg);\n    }\n    75% {\n      transform: rotate(-90deg);\n    }\n    100% {\n      transform: rotate(0deg);\n    }\n  }\n\n  @media (min-width: 769px) {\n    display: none !important;\n  }\n`\n\nconst SupportSection = styled.div`\n  margin-top: 60px;\n\n  h3 {\n    text-align: center;\n    margin-bottom: 30px;\n    font-size: 1.5rem;\n    color: #333;\n  }\n`\n\nconst PlatformGrid = styled.div`\n  display: grid;\n  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));\n  gap: 20px;\n\n  @media (max-width: 768px) {\n    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));\n    gap: 15px;\n  }\n`\n\nconst PlatformCard = styled.a`\n  display: block;\n  background: #fff;\n  padding: 20px;\n  border-radius: 12px;\n  text-align: center;\n  text-decoration: none;\n  color: #333;\n  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n  transition: all 0.3s ease;\n  cursor: pointer;\n\n  &:hover {\n    transform: translateY(-5px);\n    box-shadow: 0 8px 16px rgba(0, 0, 0, 0.12);\n  }\n\n  .platform-name {\n    font-weight: 600;\n    margin-bottom: 8px;\n    color: #667eea;\n  }\n\n  .platform-status {\n    font-size: 0.85rem;\n    color: #52c41a;\n  }\n`\n\n// 支持的视频平台列表\nconst getPlatforms = (t: any) => [\n  { name: t('video.tencentVideo'), url: 'http://v.qq.com/', status: t('video.availableRecommended') },\n  { name: t('video.iqiyi'), url: 'http://www.iqiyi.com/', status: t('video.availableRecommended') },\n  { name: t('video.youku'), url: 'http://www.youku.com/', status: t('video.availableRecommended') },\n  { name: t('video.mgtv'), url: 'http://www.mgtv.com/', status: t('video.availableRecommended') },\n  { name: t('video.bilibili'), url: 'https://www.bilibili.com/', status: t('video.availableRecommended') },\n  { name: t('video.letv'), url: 'http://www.le.com/', status: t('video.available') },\n  { name: t('video.tudou'), url: 'http://www.tudou.com/', status: t('video.available') },\n  { name: t('video.sohu'), url: 'http://tv.sohu.com/', status: t('video.available') },\n  { name: t('video.pptv'), url: 'http://www.pptv.com/', status: t('video.available') },\n  { name: t('video.movie1905'), url: 'http://www.1905.com/', status: t('video.available') },\n  { name: t('video.hjtv'), url: 'https://www.hjtv.me/', status: t('video.mayNotBeAvailable') },\n  { name: t('video.omofun'), url: 'https://omofun.tv/', status: t('video.mayNotBeAvailable') }\n]\n\n// 检测是否为移动端设备\nconst isMobileDevice = () => {\n  return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)\n}\n\n// 检测是否支持屏幕方向锁定 API\nconst isOrientationLockSupported = () => {\n  return !!(screen.orientation && (screen.orientation as any).lock)\n}\n\n// 锁定屏幕方向为横屏（仅在真实移动设备且支持该 API 时生效）\nconst lockOrientation = async () => {\n  // 静默处理，不在控制台输出错误\n  if (isOrientationLockSupported()) {\n    try {\n      await (screen.orientation as any).lock('landscape')\n    } catch {\n      // 忽略错误：可能是模拟器、桌面浏览器或不支持的设备\n    }\n  }\n}\n\n// 解锁屏幕方向\nconst unlockOrientation = () => {\n  // 静默处理，不在控制台输出错误\n  if (screen.orientation && typeof screen.orientation.unlock === 'function') {\n    try {\n      screen.orientation.unlock()\n    } catch {\n      // 忽略错误\n    }\n  }\n}\n\nconst VideoParse: React.FC = () => {\n  const { t } = useTranslation()\n  const [videoUrl, setVideoUrl] = useState('')\n  const [selectedApi, setSelectedApi] = useState(getApiList(t)[0]?.url || '')\n  const [loading, setLoading] = useState(false)\n  const [playUrl, setPlayUrl] = useState('')\n  const [isFullscreen, setIsFullscreen] = useState(false)\n  const [showRotatePrompt, setShowRotatePrompt] = useState(false)\n\n  // 获取API列表\n  const API_LIST = getApiList(t)\n\n  // 获取平台列表\n  const PLATFORMS = getPlatforms(t)\n\n  // 验证URL格式\n  const isValidUrl = (url: string) => {\n    try {\n      const urlObj = new URL(url)\n      return urlObj.protocol === 'http:' || urlObj.protocol === 'https:'\n    } catch {\n      return false\n    }\n  }\n\n  const handleParse = async () => {\n    // 验证视频链接\n    if (!videoUrl.trim()) {\n      message.warning(t('video.noUrlTip'))\n      return\n    }\n\n    // 验证URL格式\n    if (!isValidUrl(videoUrl)) {\n      message.error(t('video.parseFailed'))\n      return\n    }\n\n    // 验证是否选择了解析接口\n    if (!selectedApi) {\n      message.warning(t('video.parseFailed'))\n      return\n    }\n\n    setLoading(true)\n\n    try {\n      // 构建播放地址\n      const finalUrl = selectedApi + encodeURIComponent(videoUrl)\n      setPlayUrl(finalUrl)\n\n      // 模拟加载延迟\n      setTimeout(() => {\n        setLoading(false)\n        message.success(t('video.parseSuccess'))\n      }, 500)\n    } catch (error) {\n      message.error(t('video.parseFailed'))\n      setLoading(false)\n    }\n  }\n\n  const handlePlatformClick = (platform: { name: string; url: string }) => {\n    window.open(platform.url, '_blank')\n  }\n\n  const toggleFullscreen = () => {\n    const newFullscreenState = !isFullscreen\n    setIsFullscreen(newFullscreenState)\n\n    // 移动端处理\n    if (isMobileDevice()) {\n      if (newFullscreenState) {\n        // 尝试锁定横屏\n        lockOrientation()\n        // 显示旋转提示（仅在 HTTP 环境或不支持锁定 API 时）\n        setShowRotatePrompt(true)\n        // 3秒后自动隐藏提示\n        setTimeout(() => setShowRotatePrompt(false), 3000)\n      } else {\n        unlockOrientation()\n        setShowRotatePrompt(false)\n      }\n    }\n  }\n\n  return (\n    <PageContainer>\n      {/* 横屏提示 */}\n      <RotatePrompt $show={showRotatePrompt}>\n        <div className=\"icon\">📱</div>\n        <div className=\"text\">{t('video.rotatePrompt')}</div>\n        <div className=\"sub-text\">{t('video.rotateSubPrompt')}</div>\n      </RotatePrompt>\n\n      <SearchSection>\n        <Title level={2} style={{ color: '#fff', marginBottom: '16px' }}>\n          {t('video.title')}\n        </Title>\n        <Paragraph style={{ fontSize: '1.1rem', marginBottom: '24px' }}>\n          {t('video.description')}\n        </Paragraph>\n\n        <FormSection>\n          <Select\n            value={selectedApi}\n            onChange={setSelectedApi}\n            placeholder={t('video.selectApi')}\n            style={{ width: 200, borderRadius: '12px' }}\n            size=\"large\"\n          >\n            {API_LIST.map((api: any) => (\n              <Option key={api.url} value={api.url}>\n                {api.name}\n              </Option>\n            ))}\n          </Select>\n\n          <Input\n            value={videoUrl}\n            onChange={(e) => setVideoUrl(e.target.value)}\n            placeholder={t('video.placeholder')}\n            style={{ flex: 1, minWidth: 300, borderRadius: '12px' }}\n            onPressEnter={handleParse}\n            size=\"large\"\n            allowClear\n          />\n\n          <Button\n            type=\"primary\"\n            icon={<PlayCircleOutlined />}\n            onClick={handleParse}\n            loading={loading}\n            size=\"large\"\n            style={{\n              background: '#fff',\n              color: '#667eea',\n              border: 'none',\n              minWidth: '120px'\n            }}\n          >\n            {t('video.parseBtn')}\n          </Button>\n        </FormSection>\n\n        <Paragraph style={{ fontSize: '0.9rem', marginTop: '16px', opacity: 0.8 }}>\n          {t('video.parseTimeoutTip')}\n        </Paragraph>\n      </SearchSection>\n\n      {/* 视频播放区域 */}\n      {playUrl && (\n        <VideoSection $isFullscreen={isFullscreen}>\n          <FullscreenButton\n            icon={isFullscreen ? <FullscreenExitOutlined /> : <FullscreenOutlined />}\n            onClick={toggleFullscreen}\n          >\n            {isFullscreen ? t('video.exitFullscreenBtn') : t('video.fullscreenBtn')}\n          </FullscreenButton>\n          <iframe\n            src={playUrl}\n            allowFullScreen\n            allow=\"autoplay; encrypted-media\"\n            title=\"video-player\"\n          />\n        </VideoSection>\n      )}\n\n      <SupportSection>\n        <h3>{t('video.supportedSites')}</h3>\n        <PlatformGrid>\n          {PLATFORMS.map((platform: any) => (\n            <PlatformCard\n              key={platform.name}\n              onClick={() => handlePlatformClick(platform)}\n            >\n              <div className=\"platform-name\">{platform.name}</div>\n              <div className=\"platform-status\">{platform.status}</div>\n            </PlatformCard>\n          ))}\n        </PlatformGrid>\n      </SupportSection>\n    </PageContainer>\n  )\n}\n\nexport default VideoParse\n"
  },
  {
    "path": "src/goofish/ai-tools/chat-history.tool.ts",
    "content": "/**\n * AI 聊天历史工具\n * 获取当前会话的历史消息作为上下文\n */\n\nimport { db } from '../db/connection'\n\nexport interface ChatHistoryContext {\n  accountId: string\n  chatId: string\n}\n\nexport interface ChatHistoryMessage {\n  role: 'user' | 'assistant'\n  content: string\n  time: string\n}\n\n/**\n * 获取会话历史消息\n * 返回最近的消息，按时间正序排列\n */\nexport function getChatHistory(ctx: ChatHistoryContext, limit = 10): ChatHistoryMessage[] {\n  const { accountId, chatId } = ctx\n  \n  if (!accountId || !chatId) {\n    return []\n  }\n\n  try {\n    const rows = db.prepare(`\n            SELECT content, direction, msg_time\n            FROM conversation_messages\n            WHERE account_id = ? AND chat_id = ?\n            ORDER BY created_at DESC\n            LIMIT ?\n        `).all(accountId, chatId, limit) as any[]\n\n        // 反转为时间正序\n        return rows.reverse().map(row => ({\n            role: row.direction === 'in' ? 'user' as const : 'assistant' as const,\n            content: row.content,\n            time: row.msg_time\n        }))\n      } catch {\n        return []\n    }\n}\n"
  },
  {
    "path": "src/goofish/ai-tools/index.ts",
    "content": "/**\n * AI 工具模块\n * 导出可供 AI 使用的工具函数和定义\n */\n\nexport {\n  queryBuyerOrders,\n  orderQueryToolDefinition,\n  type OrderQueryContext,\n  type OrderQueryResult,\n} from \"./order-query.tool\"\n\nexport {\n  getChatHistory,\n  type ChatHistoryContext,\n  type ChatHistoryMessage,\n} from \"./chat-history.tool\"\n\nimport { orderQueryToolDefinition } from \"./order-query.tool\"\n\n// 所有可用的工具定义\nexport const AI_TOOLS = [orderQueryToolDefinition]\n"
  },
  {
    "path": "src/goofish/ai-tools/order-query.tool.ts",
    "content": "/**\n * AI 订单查询工具\n * 允许 AI 查询当前对话买家的订单信息\n */\n\nimport { db } from \"../db/connection\"\nimport { ORDER_STATUS_TEXT } from \"../types/order.types\"\n\nexport interface OrderQueryContext {\n  accountId: string; // 卖家账号ID\n  buyerUserId: string; // 买家用户ID\n}\n\nexport interface OrderQueryResult {\n  success: boolean;\n  orders?: {\n    orderId: string;\n    itemTitle: string;\n    price: string;\n    status: string;\n    orderTime: string;\n    payTime: string | null;\n    shipTime: string | null;\n  }[];\n  message?: string;\n}\n\n/**\n * 查询买家订单\n * 只返回当前对话买家在当前卖家账号下的订单\n */\nexport function queryBuyerOrders(ctx: OrderQueryContext): OrderQueryResult {\n  const { accountId, buyerUserId } = ctx\n\n  if (!accountId || !buyerUserId) {\n    return { success: false, message: \"缺少必要参数\" }\n  }\n\n  try {\n    const rows = db\n      .prepare(\n        `\n            SELECT order_id, item_title, price, status, status_text,\n                   order_time, pay_time, ship_time\n            FROM orders\n            WHERE account_id = ? AND buyer_user_id = ?\n            ORDER BY order_time DESC\n            LIMIT 10\n        `,\n      )\n      .all(accountId, buyerUserId) as any[]\n\n    if (rows.length === 0) {\n      return { success: true, orders: [], message: \"该买家暂无订单记录\" }\n    }\n\n    const orders = rows.map((row) => ({\n      orderId: row.order_id,\n      itemTitle: row.item_title || \"未知商品\",\n      price: row.price || \"0\",\n      status: row.status_text || ORDER_STATUS_TEXT[row.status] || \"未知状态\",\n      orderTime: row.order_time,\n      payTime: row.pay_time,\n      shipTime: row.ship_time,\n    }))\n\n    return { success: true, orders }\n  } catch (e) {\n    return { success: false, message: \"查询订单失败\" }\n  }\n}\n\n/**\n * OpenAI Function Calling 工具定义\n */\nexport const orderQueryToolDefinition = {\n  type: \"function\" as const,\n  function: {\n    name: \"query_buyer_orders\",\n    description: \"查询当前对话买家的订单信息，包括订单号、商品、价格、状态等\",\n    parameters: {\n      type: \"object\",\n      properties: {},\n      required: [],\n    },\n  },\n}\n"
  },
  {
    "path": "src/goofish/api/index.ts",
    "content": "/**\n * API 模块统一导出\n */\n\nexport { startServer, setClientManager, createApp } from './server.js'\nexport { messageStore } from './stores/message.store.js'\nexport { conversationStore } from './stores/conversation.store.js'\n"
  },
  {
    "path": "src/goofish/api/middlewares/index.ts",
    "content": "export { securityMiddleware } from './security.middleware'\n"
  },
  {
    "path": "src/goofish/api/middlewares/security.middleware.ts",
    "content": "/**\n * 安全中间件\n * 使用 Hono 内置 CSRF 中间件限制 API 只能从同源请求\n */\n\nimport { csrf } from \"hono/csrf\";\nimport type { Context, Next } from \"hono\";\n\nimport { createLogger } from \"../../core/logger\";\n\nconst logger = createLogger(\"Api:Security\");\n\n// 白名单路径（不需要验证来源）- 仅开发环境使用\nconst WHITELIST_PATHS: string[] = [];\n\n/**\n * 创建安全中间件\n * 使用 Hono CSRF 中间件验证 Origin 和 Sec-Fetch-Site 头\n */\nexport function createSecurityMiddleware() {\n  // Hono CSRF 中间件 - 验证同源请求\n  const csrfMiddleware = csrf({\n    // 动态验证 Origin（同源或本地开发）\n    origin: (origin, c) => {\n      const host = c.req.header(\"host\");\n      if (!origin || !host) return false;\n\n      // 提取 origin 的 host 部分\n      try {\n        const originUrl = new URL(origin);\n        // 同源检查\n        if (originUrl.host === host) return true;\n        // 本地开发允许\n        if (\n          originUrl.hostname === \"localhost\" ||\n          originUrl.hostname === \"127.0.0.1\"\n        ) {\n          return true;\n        }\n      } catch {\n        return false;\n      }\n      return false;\n    },\n    // 允许同源和直接访问（浏览器地址栏）\n    secFetchSite: [\"same-origin\", \"none\"],\n  });\n\n  return async (c: Context, next: Next) => {\n    const path = c.req.path;\n\n    // 白名单路径直接放行\n    if (WHITELIST_PATHS.some((p) => path.startsWith(p))) {\n      return next();\n    }\n\n    // GET/HEAD/OPTIONS 请求放行（CSRF 只保护修改操作）\n    const method = c.req.method;\n    if (method === \"GET\" || method === \"HEAD\" || method === \"OPTIONS\") {\n      return next();\n    }\n\n    // 使用 CSRF 中间件验证\n    try {\n      return await csrfMiddleware(c, next);\n    } catch {\n      logger.warn(`拒绝非法请求: ${method} ${path}`);\n      return c.json({ error: \"Forbidden\" }, 403);\n    }\n  };\n}\n\n// 兼容旧的导出方式\nexport const securityMiddleware = createSecurityMiddleware();\n"
  },
  {
    "path": "src/goofish/api/routes/accounts.ts",
    "content": "import { Hono } from \"hono\";\n\nimport { createLogger } from \"../../core/logger\";\nimport { CookiesManager } from \"../../core/cookies.manager\";\nimport {\n  getAllAccounts,\n  getAccount,\n  upsertAccount,\n  deleteAccount,\n  updateAccountEnabled,\n  getAccountStatus,\n  updateAccountUserInfo,\n} from \"../../db/index\";\nimport { fetchUserInfo } from \"../../services/index\";\nimport { parseCookies } from \"../../utils/cookies\";\nimport type { ClientManager } from \"../../websocket/client.manager\";\n\nconst logger = createLogger(\"Api:Account\");\n\nexport function createAccountRoutes(\n  getClientManager: () => ClientManager | null,\n) {\n  const router = new Hono();\n\n  // 获取所有账号\n  router.get(\"/\", (c) => {\n    const accounts = getAllAccounts().map((a) => ({\n      ...a,\n      cookies: a.cookies.substring(0, 50) + \"...\",\n      status: getAccountStatus(a.id),\n    }));\n    return c.json({ accounts });\n  });\n\n  // 获取单个账号\n  router.get(\"/:id\", (c) => {\n    const id = c.req.param(\"id\");\n    const account = getAccount(id);\n    if (!account) {\n      return c.json({ error: \"Account not found\" }, 404);\n    }\n    return c.json({\n      ...account,\n      cookies: account.cookies.substring(0, 50) + \"...\",\n      status: getAccountStatus(id),\n    });\n  });\n\n  // 添加/更新账号\n  router.post(\"/\", async (c) => {\n    const body = await c.req.json();\n    const { id, cookies, remark, enabled } = body;\n\n    if (cookies) {\n      // 新账号：先从 cookies 中提取 userId 作为临时 accountId\n      const cookiesObj = parseCookies(cookies);\n      const tempAccountId = cookiesObj[\"unb\"];\n      if (!tempAccountId) {\n        return c.json({ error: \"Cookie中缺少必需的unb字段\" }, 400);\n      }\n\n      // 先保存账号到数据库（这样 CookiesManager 才能工作）\n      upsertAccount({\n        id: tempAccountId,\n        cookies,\n        remark,\n        enabled,\n      });\n\n      // 然后获取用户信息\n      const userInfo = await fetchUserInfo(tempAccountId);\n      if (!userInfo) {\n        // 删除刚创建的账号\n        deleteAccount(tempAccountId);\n        return c.json({ error: \"Cookie无效或已过期，无法获取用户信息\" }, 400);\n      }\n\n      logger.info(`获取用户信息: ${userInfo.displayName} (${tempAccountId})`);\n\n      // 更新用户信息\n      updateAccountUserInfo(\n        tempAccountId,\n        userInfo.displayName,\n        userInfo.avatar,\n      );\n\n      return c.json({ success: true, accountId: tempAccountId });\n    }\n\n    if (!id) {\n      return c.json({ error: \"Missing id\" }, 400);\n    }\n\n    const existing = getAccount(id);\n    if (!existing) {\n      return c.json({ error: \"Account not found\" }, 404);\n    }\n    const success = upsertAccount({\n      id,\n      cookies: existing.cookies,\n      nickname: existing.nickname,\n      avatar: existing.avatar,\n      remark,\n      enabled,\n    });\n    return c.json({ success });\n  });\n\n  // 刷新账号用户信息\n  router.post(\"/:id/refresh-info\", async (c) => {\n    const id = c.req.param(\"id\");\n    const account = getAccount(id);\n    if (!account) {\n      return c.json({ error: \"Account not found\" }, 404);\n    }\n\n    const userInfo = await fetchUserInfo(id);\n\n    if (userInfo) {\n      updateAccountUserInfo(id, userInfo.displayName, userInfo.avatar);\n      return c.json({ success: true, userInfo });\n    }\n    return c.json({ success: false, error: \"Failed to fetch user info\" });\n  });\n\n  // 删除账号\n  router.delete(\"/:id\", (c) => {\n    const id = c.req.param(\"id\");\n    getClientManager()?.stopClient(id);\n    const success = deleteAccount(id);\n    return c.json({ success });\n  });\n\n  // 启用/禁用账号\n  router.patch(\"/:id/enabled\", async (c) => {\n    const id = c.req.param(\"id\");\n    const body = await c.req.json();\n    const { enabled } = body;\n    const success = updateAccountEnabled(id, enabled);\n    const clientManager = getClientManager();\n    if (enabled && clientManager) {\n      await clientManager.startClient(id);\n    } else if (!enabled && clientManager) {\n      clientManager.stopClient(id);\n    }\n    return c.json({ success });\n  });\n\n  // 启动账号\n  router.post(\"/:id/start\", async (c) => {\n    const id = c.req.param(\"id\");\n    const clientManager = getClientManager();\n    if (!clientManager) {\n      return c.json({ error: \"ClientManager not initialized\" }, 500);\n    }\n    const account = getAccount(id);\n    if (!account) {\n      return c.json({ error: \"Account not found\" }, 404);\n    }\n    const success = await clientManager.startClient(id);\n    if (success) {\n      updateAccountEnabled(id, true);\n    }\n    return c.json({ success });\n  });\n\n  // 停止账号\n  router.post(\"/:id/stop\", (c) => {\n    const id = c.req.param(\"id\");\n    const clientManager = getClientManager();\n    if (!clientManager) {\n      return c.json({ error: \"ClientManager not initialized\" }, 500);\n    }\n    const success = clientManager.stopClient(id);\n    if (success) {\n      updateAccountEnabled(id, false);\n    }\n    return c.json({ success });\n  });\n\n  // 重启账号\n  router.post(\"/:id/restart\", async (c) => {\n    const id = c.req.param(\"id\");\n    const clientManager = getClientManager();\n    if (!clientManager) {\n      return c.json({ error: \"ClientManager not initialized\" }, 500);\n    }\n    const success = await clientManager.restartClient(id);\n    return c.json({ success });\n  });\n\n  return router;\n}\n"
  },
  {
    "path": "src/goofish/api/routes/auth.route.ts",
    "content": "/**\n * 用户认证路由\n */\n\nimport { Hono } from 'hono'\nimport { register, login, getUserByToken } from '../../services/auth.service'\nimport { createLogger } from '../../core/logger'\nimport { verifyTurnstileToken } from '../../../services/turnstile'\n\nconst logger = createLogger('AuthRoute')\nconst authRoute = new Hono()\n\n/**\n * 用户注册\n * POST /api/auth/register\n */\nauthRoute.post('/register', async (c) => {\n  try {\n    const body = await c.req.json()\n    const { username, password, email, 'cf-turnstile-response': turnstileToken } = body\n\n    const isDev = process.env.NODE_ENV !== 'production'\n\n    // 验证 Turnstile token（开发环境跳过）\n    if (turnstileToken && !isDev) {\n      const verifyResult = await verifyTurnstileToken(turnstileToken)\n      if (!verifyResult.success) {\n        return c.json({\n          success: false,\n          message: `人机验证失败: ${verifyResult.error}`,\n        }, 403)\n      }\n    }\n\n    if (!username || !password) {\n      return c.json({\n        success: false,\n        message: '用户名和密码不能为空'\n      }, 400)\n    }\n\n    const result = await register({ username, password, email })\n\n    if (result.success) {\n      return c.json(result)\n    } else {\n      return c.json(result, 400)\n    }\n  } catch (error) {\n    // @ts-ignore\n    logger.error('注册接口错误:', error)\n    return c.json({\n      success: false,\n      message: '服务器错误'\n    }, 500)\n  }\n})\n\n/**\n * 用户登录\n * POST /api/auth/login\n */\nauthRoute.post('/login', async (c) => {\n  try {\n    const body = await c.req.json()\n    const { username, password, 'cf-turnstile-response': turnstileToken } = body\n\n    const isDev = process.env.NODE_ENV !== 'production'\n\n    // 验证 Turnstile token（开发环境跳过）\n    if (turnstileToken && !isDev) {\n      const verifyResult = await verifyTurnstileToken(turnstileToken)\n      if (!verifyResult.success) {\n        return c.json({\n          success: false,\n          message: `人机验证失败: ${verifyResult.error}`,\n        }, 403)\n      }\n    }\n\n    if (!username || !password) {\n      return c.json({\n        success: false,\n        message: '用户名和密码不能为空'\n      }, 400)\n    }\n\n    const result = await login({ username, password })\n\n    if (result.success) {\n      return c.json(result)\n    } else {\n      return c.json(result, 400)\n    }\n  } catch (error) {\n    // @ts-ignore\n    logger.error('登录接口错误:', error)\n    return c.json({\n      success: false,\n      message: '服务器错误'\n    }, 500)\n  }\n})\n\n/**\n * 验证 token 并获取用户信息\n * GET /api/auth/me\n */\nauthRoute.get('/me', async (c) => {\n  try {\n    const token = c.req.header('Authorization')?.replace('Bearer ', '')\n\n    if (!token) {\n      return c.json({\n        success: false,\n        message: '未提供认证令牌'\n      }, 401)\n    }\n\n    const user = getUserByToken(token)\n\n    if (!user) {\n      return c.json({\n        success: false,\n        message: '无效的认证令牌'\n      }, 401)\n    }\n\n    return c.json({\n      success: true,\n      user\n    })\n  } catch (error) {\n    // @ts-ignore\n    logger.error('获取用户信息接口错误:', error)\n    return c.json({\n      success: false,\n      message: '服务器错误'\n    }, 500)\n  }\n})\n\nexport { authRoute }\n"
  },
  {
    "path": "src/goofish/api/routes/autoreply.ts",
    "content": "import { Hono } from \"hono\";\nimport { readFileSync } from \"fs\";\nimport { fileURLToPath } from \"url\";\nimport { dirname, join } from \"path\";\n\nimport {\n  getAutoReplyRules,\n  getAutoReplyRule,\n  createAutoReplyRule,\n  updateAutoReplyRule,\n  deleteAutoReplyRule,\n  toggleAutoReplyRule,\n  getAISettings,\n  saveAISettings,\n} from \"../../db/index\";\nimport { testAIConnection } from \"../../services/index\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n// 读取默认提示词\nfunction getDefaultPrompt(): string {\n  try {\n    const promptPath = join(__dirname, \"../../assets/default-prompt.md\");\n    return readFileSync(promptPath, \"utf-8\");\n  } catch {\n    return \"你是一个闲鱼卖家的智能客服助手，请用简洁友好的语气回复买家的消息。\";\n  }\n}\n\nexport function createAutoReplyRoutes() {\n  const router = new Hono();\n\n  // ========== AI 设置 ==========\n\n  // 获取 AI 设置\n  router.get(\"/ai\", (c) => {\n    const settings = getAISettings();\n    return c.json({\n      baseUrl: settings.baseUrl,\n      apiKey: settings.apiKey ? \"******\" : \"\",\n      hasApiKey: !!settings.apiKey,\n      model: settings.model,\n      systemPrompt: settings.systemPrompt,\n    });\n  });\n\n  // 保存 AI 设置\n  router.put(\"/ai\", async (c) => {\n    const body = await c.req.json();\n    const { baseUrl, apiKey, model, systemPrompt } = body;\n\n    const updates: any = {};\n    if (baseUrl !== undefined) updates.baseUrl = baseUrl;\n    if (apiKey !== undefined && apiKey !== \"******\") updates.apiKey = apiKey;\n    if (model !== undefined) updates.model = model;\n    if (systemPrompt !== undefined) updates.systemPrompt = systemPrompt;\n\n    saveAISettings(updates);\n    return c.json({ success: true });\n  });\n\n  // 测试 AI 连接\n  router.post(\"/ai/test\", async (c) => {\n    const result = await testAIConnection();\n    return c.json(result);\n  });\n\n  // 获取默认提示词\n  router.get(\"/ai/default-prompt\", (c) => {\n    return c.json({ prompt: getDefaultPrompt() });\n  });\n\n  // ========== 规则管理 ==========\n\n  // 获取所有规则\n  router.get(\"/\", (c) => {\n    const rules = getAutoReplyRules();\n    return c.json({\n      rules: rules.map((r) => ({\n        id: r.id,\n        name: r.name,\n        enabled: r.enabled === 1,\n        priority: r.priority,\n        matchType: r.match_type,\n        matchPattern: r.match_pattern,\n        replyContent: r.reply_content,\n        accountId: r.account_id,\n        excludeMatch: r.exclude_match === 1,\n        createdAt: r.created_at,\n        updatedAt: r.updated_at,\n      })),\n    });\n  });\n\n  // 获取单个规则\n  router.get(\"/:id\", (c) => {\n    const id = parseInt(c.req.param(\"id\"));\n    const rule = getAutoReplyRule(id);\n    if (!rule) {\n      return c.json({ error: \"Rule not found\" }, 404);\n    }\n    return c.json({\n      id: rule.id,\n      name: rule.name,\n      enabled: rule.enabled === 1,\n      priority: rule.priority,\n      matchType: rule.match_type,\n      matchPattern: rule.match_pattern,\n      replyContent: rule.reply_content,\n      accountId: rule.account_id,\n      excludeMatch: rule.exclude_match === 1,\n      createdAt: rule.created_at,\n      updatedAt: rule.updated_at,\n    });\n  });\n\n  // 创建规则\n  router.post(\"/\", async (c) => {\n    const body = await c.req.json();\n    const {\n      name,\n      enabled,\n      priority,\n      matchType,\n      matchPattern,\n      replyContent,\n      accountId,\n      excludeMatch,\n    } = body;\n\n    if (!name || !matchType) {\n      return c.json({ error: \"Missing required fields\" }, 400);\n    }\n\n    // 排除匹配规则不需要匹配内容，AI 类型也不需要强制填写\n    if (\n      !excludeMatch &&\n      matchType !== \"ai\" &&\n      (!matchPattern || !replyContent)\n    ) {\n      return c.json({ error: \"Missing required fields\" }, 400);\n    }\n\n    if (![\"exact\", \"contains\", \"regex\", \"ai\"].includes(matchType)) {\n      return c.json({ error: \"Invalid matchType\" }, 400);\n    }\n\n    // AI 规则：如果提示词为空，填入全局提示词\n    let finalReplyContent = replyContent || \"\";\n    if (matchType === \"ai\" && !finalReplyContent) {\n      const aiSettings = getAISettings();\n      finalReplyContent = aiSettings.systemPrompt || \"\";\n    }\n\n    const id = createAutoReplyRule({\n      name,\n      enabled: enabled !== false,\n      priority: priority || 0,\n      matchType,\n      matchPattern: matchPattern || \"\",\n      replyContent: finalReplyContent,\n      accountId: accountId || null,\n      excludeMatch: excludeMatch || false,\n    });\n\n    return c.json({ success: true, id });\n  });\n\n  // 更新规则\n  router.put(\"/:id\", async (c) => {\n    const id = parseInt(c.req.param(\"id\"));\n    const body = await c.req.json();\n\n    if (\n      body.matchType &&\n      ![\"exact\", \"contains\", \"regex\", \"ai\"].includes(body.matchType)\n    ) {\n      return c.json({ error: \"Invalid matchType\" }, 400);\n    }\n\n    // AI 规则：如果提示词为空，填入全局提示词\n    if (body.matchType === \"ai\" && !body.replyContent) {\n      const aiSettings = getAISettings();\n      body.replyContent = aiSettings.systemPrompt || \"\";\n    }\n\n    const success = updateAutoReplyRule(id, body);\n    if (!success) {\n      return c.json({ error: \"Rule not found\" }, 404);\n    }\n\n    return c.json({ success: true });\n  });\n\n  // 删除规则\n  router.delete(\"/:id\", (c) => {\n    const id = parseInt(c.req.param(\"id\"));\n    const success = deleteAutoReplyRule(id);\n    if (!success) {\n      return c.json({ error: \"Rule not found\" }, 404);\n    }\n    return c.json({ success: true });\n  });\n\n  // 切换规则启用状态\n  router.post(\"/:id/toggle\", (c) => {\n    const id = parseInt(c.req.param(\"id\"));\n    const success = toggleAutoReplyRule(id);\n    if (!success) {\n      return c.json({ error: \"Rule not found\" }, 404);\n    }\n    return c.json({ success: true });\n  });\n\n  return router;\n}\n"
  },
  {
    "path": "src/goofish/api/routes/autosell.ts",
    "content": "/**\n * 自动发货 API 路由\n */\n\nimport { Hono } from \"hono\";\n\nimport {\n  getAutoSellRules,\n  getAutoSellRule,\n  createAutoSellRule,\n  updateAutoSellRule,\n  deleteAutoSellRule,\n  toggleAutoSellRule,\n  getStockItems,\n  getStockStats,\n  addStockItems,\n  clearStock,\n  getDeliveryLogs,\n} from \"../../db/index\";\n\nexport function createAutoSellRoutes() {\n  const router = new Hono();\n\n  // ========== 规则管理 ==========\n\n  // 获取所有规则\n  router.get(\"/\", (c) => {\n    const rules = getAutoSellRules();\n    // 附加库存统计\n    const rulesWithStats = rules.map((r) => {\n      if (r.deliveryType === \"stock\") {\n        const stats = getStockStats(r.id);\n        return { ...r, stockCount: stats.total, usedCount: stats.used };\n      }\n      return r;\n    });\n    return c.json({ rules: rulesWithStats });\n  });\n\n  // 获取单个规则\n  router.get(\"/:id\", (c) => {\n    const id = parseInt(c.req.param(\"id\"));\n    const rule = getAutoSellRule(id);\n    if (!rule) {\n      return c.json({ error: \"规则不存在\" }, 404);\n    }\n    if (rule.deliveryType === \"stock\") {\n      const stats = getStockStats(id);\n      return c.json({\n        ...rule,\n        stockCount: stats.total,\n        usedCount: stats.used,\n      });\n    }\n    return c.json(rule);\n  });\n\n  // 创建规则\n  router.post(\"/\", async (c) => {\n    const body = await c.req.json();\n    const id = createAutoSellRule(body);\n    return c.json({ success: true, id });\n  });\n\n  // 更新规则\n  router.put(\"/:id\", async (c) => {\n    const id = parseInt(c.req.param(\"id\"));\n    const body = await c.req.json();\n    const success = updateAutoSellRule(id, body);\n    return c.json({ success });\n  });\n\n  // 删除规则\n  router.delete(\"/:id\", (c) => {\n    const id = parseInt(c.req.param(\"id\"));\n    const success = deleteAutoSellRule(id);\n    return c.json({ success });\n  });\n\n  // 切换规则状态\n  router.post(\"/:id/toggle\", (c) => {\n    const id = parseInt(c.req.param(\"id\"));\n    const success = toggleAutoSellRule(id);\n    return c.json({ success });\n  });\n\n  // ========== 库存管理 ==========\n\n  // 获取规则库存\n  router.get(\"/:id/stock\", (c) => {\n    const id = parseInt(c.req.param(\"id\"));\n    const includeUsed = c.req.query(\"includeUsed\") === \"true\";\n    const items = getStockItems(id, includeUsed);\n    const stats = getStockStats(id);\n    return c.json({ items, stats });\n  });\n\n  // 添加库存\n  router.post(\"/:id/stock\", async (c) => {\n    const id = parseInt(c.req.param(\"id\"));\n    const body = await c.req.json();\n    const contents = body.contents as string[];\n    if (!Array.isArray(contents) || contents.length === 0) {\n      return c.json({ error: \"请提供库存内容\" }, 400);\n    }\n    const count = addStockItems(id, contents);\n    return c.json({ success: true, count });\n  });\n\n  // 清空库存\n  router.delete(\"/:id/stock\", (c) => {\n    const id = parseInt(c.req.param(\"id\"));\n    const onlyUsed = c.req.query(\"onlyUsed\") === \"true\";\n    const count = clearStock(id, onlyUsed);\n    return c.json({ success: true, count });\n  });\n\n  // ========== 发货记录 ==========\n\n  // 获取发货记录\n  router.get(\"/logs\", (c) => {\n    const ruleId = c.req.query(\"ruleId\");\n    const orderId = c.req.query(\"orderId\");\n    const accountId = c.req.query(\"accountId\");\n    const limit = parseInt(c.req.query(\"limit\") || \"50\");\n    const offset = parseInt(c.req.query(\"offset\") || \"0\");\n\n    const result = getDeliveryLogs({\n      ruleId: ruleId ? parseInt(ruleId) : undefined,\n      orderId: orderId || undefined,\n      accountId: accountId || undefined,\n      limit,\n      offset,\n    });\n    return c.json(result);\n  });\n\n  return router;\n}\n"
  },
  {
    "path": "src/goofish/api/routes/conversations.ts",
    "content": "import { Hono } from \"hono\";\n\nimport { conversationStore } from \"../stores/conversation.store\";\nimport { fetchUserHead } from \"../../services/index\";\nimport { getAccount } from \"../../db/index\";\n\nexport function createConversationRoutes() {\n  const router = new Hono();\n\n  // 获取对话列表（分页）\n  router.get(\"/\", (c) => {\n    const limit = parseInt(c.req.query(\"limit\") || \"20\");\n    const offset = parseInt(c.req.query(\"offset\") || \"0\");\n    const { conversations, total } = conversationStore.getAll(limit, offset);\n    return c.json({ conversations, total, limit, offset });\n  });\n\n  // 获取单个对话详情（只需要 chatId）\n  router.get(\"/:chatId\", (c) => {\n    const chatId = c.req.param(\"chatId\");\n    const limit = parseInt(c.req.query(\"limit\") || \"50\");\n    const beforeId = c.req.query(\"beforeId\")\n      ? parseInt(c.req.query(\"beforeId\")!)\n      : undefined;\n\n    // 尝试从所有账号中查找对话\n    const { conversations } = conversationStore.getAll(1000, 0); // 获取最多1000个对话\n    const conv = conversations.find((c) => c.chatId === chatId);\n\n    if (!conv) {\n      return c.json({ error: \"Conversation not found\" }, 404);\n    }\n\n    // 使用找到的 accountId 获取完整对话详情\n    const fullConv = conversationStore.get(\n      conv.accountId,\n      chatId,\n      limit,\n      beforeId,\n    );\n    if (!fullConv) {\n      return c.json({ error: \"Conversation details not found\" }, 404);\n    }\n\n    return c.json(fullConv);\n  });\n\n  // 获取单个对话详情（分页消息）\n  // 路径格式: /:accountId/:chatId\n  router.get(\"/:accountId/:chatId\", (c) => {\n    const accountId = c.req.param(\"accountId\");\n    const chatId = c.req.param(\"chatId\");\n    const limit = parseInt(c.req.query(\"limit\") || \"50\");\n    const beforeId = c.req.query(\"beforeId\")\n      ? parseInt(c.req.query(\"beforeId\")!)\n      : undefined;\n    const conv = conversationStore.get(accountId, chatId, limit, beforeId);\n    if (!conv) {\n      return c.json({ error: \"Conversation not found\" }, 404);\n    }\n    return c.json(conv);\n  });\n\n  // 标记对话已读\n  router.post(\"/:accountId/:chatId/read\", (c) => {\n    const accountId = c.req.param(\"accountId\");\n    const chatId = c.req.param(\"chatId\");\n    conversationStore.markRead(accountId, chatId);\n    return c.json({ success: true });\n  });\n\n  // 获取用户头像\n  router.get(\"/user/:userId/avatar\", async (c) => {\n    const userId = c.req.param(\"userId\");\n    const accountId = c.req.query(\"accountId\");\n\n    const accounts = accountId ? [getAccount(accountId)] : [];\n    if (accounts.length === 0 || !accounts[0]) {\n      return c.json({ error: \"No account available\" }, 400);\n    }\n\n    const account = accounts[0];\n    const { userHead } = await fetchUserHead(account.id, userId);\n\n    if (userHead) {\n      return c.json(userHead);\n    }\n    return c.json({ error: \"Failed to fetch user info\" }, 404);\n  });\n\n  return router;\n}\n"
  },
  {
    "path": "src/goofish/api/routes/dev-messages.route.ts",
    "content": "import { Hono } from \"hono\";\nimport {\n  existsSync,\n  mkdirSync,\n  writeFileSync,\n  readdirSync,\n  unlinkSync,\n  statSync,\n} from \"fs\";\nimport { join } from \"path\";\n\nimport { createLogger } from \"../../core/logger\";\nimport { decryptMessagePack } from \"../../utils/msgpack\";\n\nconst logger = createLogger(\"Api:DevMsg\");\n\n// raw 日志目录\nconst RAW_LOG_DIR = join(process.cwd(), \"logs\", \"raw\");\nconst RAW_RETENTION_DAYS = 3;\n\n// 存储原始消息的缓冲区\ninterface RawMessage {\n  accountId: string;\n  timestamp: string;\n  lwp: string;\n  data: any;\n  decoded: any[] | null;\n}\n\nconst messageBuffer: RawMessage[] = [];\nconst MAX_BUFFER_SIZE = 500;\n\n// 解码消息数据\nfunction decodeMessageData(msgData: any): any[] | null {\n  try {\n    const body = msgData.body || {};\n    let dataList: any[] = [];\n\n    if (body.syncPushPackage?.data) {\n      dataList = body.syncPushPackage.data;\n    } else if (Array.isArray(body.data)) {\n      dataList = body.data;\n    } else if (Array.isArray(body)) {\n      dataList = body;\n    }\n\n    if (dataList.length === 0) return null;\n\n    const decoded: any[] = [];\n    for (const item of dataList) {\n      const data = typeof item === \"object\" ? item.data || item : item;\n      if (!data) continue;\n\n      try {\n        const result = decryptMessagePack(data);\n        if (result) {\n          decoded.push(result);\n        }\n      } catch {\n        // 尝试 base64 + JSON\n        try {\n          const str = Buffer.from(data, \"base64\").toString(\"utf-8\");\n          const parsed = JSON.parse(str);\n          decoded.push(parsed);\n        } catch {\n          decoded.push({ raw: data });\n        }\n      }\n    }\n\n    return decoded.length > 0 ? decoded : null;\n  } catch {\n    return null;\n  }\n}\n\n// 保存原始消息到文件\nfunction saveRawToFile(accountId: string, data: any, decoded: any[] | null) {\n  try {\n    // 确保目录存在\n    if (!existsSync(RAW_LOG_DIR)) {\n      mkdirSync(RAW_LOG_DIR, { recursive: true });\n    }\n\n    const now = new Date();\n    const dateStr = now.toISOString().slice(0, 10); // YYYY-MM-DD\n    const timeStr = now.toISOString().slice(11, 19).replace(/:/g, \"\"); // HHMMSS\n    const ms = now.getMilliseconds().toString().padStart(3, \"0\");\n    const filename = `${dateStr}_${timeStr}_${ms}_${accountId}.json`;\n    const filepath = join(RAW_LOG_DIR, filename);\n\n    // 保存原始数据和解码后的数据\n    const content = {\n      accountId,\n      timestamp: now.toISOString(),\n      raw: data,\n      decoded,\n    };\n\n    writeFileSync(filepath, JSON.stringify(content, null, 2), \"utf-8\");\n  } catch (e) {\n    logger.debug(`保存原始消息到文件失败: ${e}`);\n  }\n}\n\n// 添加原始消息到缓冲区\nexport function addRawMessage(accountId: string, data: any) {\n  const decoded = decodeMessageData(data);\n\n  // 保存到文件（包含解码后的数据）\n  saveRawToFile(accountId, data, decoded);\n\n  const msg: RawMessage = {\n    accountId,\n    timestamp: new Date().toISOString(),\n    lwp: data.lwp || \"\",\n    data,\n    decoded,\n  };\n  messageBuffer.unshift(msg);\n\n  if (messageBuffer.length > MAX_BUFFER_SIZE) {\n    messageBuffer.pop();\n  }\n}\n\n// 清空缓冲区\nexport function clearMessageBuffer() {\n  messageBuffer.length = 0;\n}\n\n// 清理过期的原始消息文件\nexport function cleanOldRawMessages() {\n  try {\n    if (!existsSync(RAW_LOG_DIR)) return;\n\n    const now = Date.now();\n    const maxAge = RAW_RETENTION_DAYS * 24 * 60 * 60 * 1000;\n    const files = readdirSync(RAW_LOG_DIR);\n    let cleanedCount = 0;\n\n    for (const file of files) {\n      if (!file.endsWith(\".json\")) continue;\n\n      const filepath = join(RAW_LOG_DIR, file);\n      try {\n        const stat = statSync(filepath);\n        if (now - stat.mtimeMs > maxAge) {\n          unlinkSync(filepath);\n          cleanedCount++;\n        }\n      } catch {\n        // 忽略单个文件错误\n      }\n    }\n\n    if (cleanedCount > 0) {\n      logger.info(`清理了 ${cleanedCount} 个过期的原始消息文件`);\n    }\n  } catch (e) {\n    logger.debug(`清理原始消息文件失败: ${e}`);\n  }\n}\n\n// 启动时清理一次，之后每小时清理\ncleanOldRawMessages();\nsetInterval(cleanOldRawMessages, 60 * 60 * 1000);\n\nexport function createDevMessageRoutes() {\n  const router = new Hono();\n\n  // 获取所有原始消息\n  router.get(\"/\", (c) => {\n    const accountId = c.req.query(\"accountId\");\n    const limit = parseInt(c.req.query(\"limit\") || \"100\");\n\n    let messages = messageBuffer;\n\n    if (accountId) {\n      messages = messages.filter((m) => m.accountId === accountId);\n    }\n\n    return c.json({\n      total: messages.length,\n      messages: messages.slice(0, limit),\n    });\n  });\n\n  // 获取指定账号的原始消息\n  router.get(\"/:accountId\", (c) => {\n    const accountId = c.req.param(\"accountId\");\n    const limit = parseInt(c.req.query(\"limit\") || \"100\");\n\n    const messages = messageBuffer.filter((m) => m.accountId === accountId);\n\n    return c.json({\n      accountId,\n      total: messages.length,\n      messages: messages.slice(0, limit),\n    });\n  });\n\n  // 清空消息缓冲区\n  router.delete(\"/\", (c) => {\n    clearMessageBuffer();\n    logger.info(\"消息缓冲区已清空\");\n    return c.json({ success: true });\n  });\n\n  // SSE 实时推送消息\n  router.get(\"/stream\", async (c) => {\n    const accountId = c.req.query(\"accountId\");\n\n    c.header(\"Content-Type\", \"text/event-stream\");\n    c.header(\"Cache-Control\", \"no-cache\");\n    c.header(\"Connection\", \"keep-alive\");\n\n    let lastIndex = 0;\n\n    const stream = new ReadableStream({\n      start(controller) {\n        const encoder = new TextEncoder();\n\n        controller.enqueue(\n          encoder.encode(\n            `data: ${JSON.stringify({ type: \"connected\", accountId: accountId || \"all\" })}\\n\\n`,\n          ),\n        );\n\n        const interval = setInterval(() => {\n          const currentLength = messageBuffer.length;\n\n          if (currentLength > lastIndex) {\n            const newMessages = messageBuffer.slice(\n              0,\n              currentLength - lastIndex,\n            );\n\n            for (const msg of newMessages.reverse()) {\n              if (!accountId || msg.accountId === accountId) {\n                controller.enqueue(\n                  encoder.encode(`data: ${JSON.stringify(msg)}\\n\\n`),\n                );\n              }\n            }\n\n            lastIndex = currentLength;\n          }\n        }, 500);\n\n        setTimeout(() => {\n          clearInterval(interval);\n          controller.close();\n        }, 30000);\n      },\n    });\n\n    return new Response(stream, {\n      headers: {\n        \"Content-Type\": \"text/event-stream\",\n        \"Cache-Control\": \"no-cache\",\n        Connection: \"keep-alive\",\n      },\n    });\n  });\n\n  return router;\n}\n"
  },
  {
    "path": "src/goofish/api/routes/goods.ts",
    "content": "import { Hono } from \"hono\";\n\nimport { getAllAccounts, getAccount } from \"../../db/index\";\nimport { fetchGoodsList } from \"../../services/index\";\nimport type { ClientManager } from \"../../websocket/client.manager\";\n\nexport function createGoodsRoutes(\n  getClientManager: () => ClientManager | null,\n) {\n  const router = new Hono();\n\n  // 获取所有账号的商品列表（只获取在线账号）\n  router.get(\"/\", async (c) => {\n    const accountId = c.req.query(\"accountId\");\n    const page = parseInt(c.req.query(\"page\") || \"1\");\n\n    if (accountId) {\n      const account = getAccount(accountId);\n      if (!account) {\n        return c.json({ error: \"Account not found\" }, 404);\n      }\n      const result = await fetchGoodsList(accountId, accountId, page);\n\n      return c.json({\n        items: result.items.map((item) => ({ ...item, accountId })),\n        nextPage: result.nextPage,\n        totalCount: result.totalCount,\n      });\n    }\n\n    // 获取所有账号，但只处理在线的\n    const accounts = getAllAccounts();\n    const clientManager = getClientManager();\n    const allItems: any[] = [];\n    let totalCount = 0;\n\n    for (const account of accounts) {\n      // 检查账号是否在线\n      const client = clientManager?.getClient(account.id);\n      if (!client || !client.isConnected()) {\n        continue; // 跳过离线账号\n      }\n\n      const result = await fetchGoodsList(account.id, account.id, page);\n\n      const itemsWithAccount = result.items.map((item) => ({\n        ...item,\n        accountId: account.id,\n        accountNickname: account.nickname,\n      }));\n      allItems.push(...itemsWithAccount);\n      totalCount += result.totalCount;\n    }\n\n    return c.json({\n      items: allItems,\n      totalCount,\n    });\n  });\n\n  // 获取单个账号的商品列表\n  router.get(\"/account/:id\", async (c) => {\n    const id = c.req.param(\"id\");\n    const page = parseInt(c.req.query(\"page\") || \"1\");\n\n    const account = getAccount(id);\n    if (!account) {\n      return c.json({ error: \"Account not found\" }, 404);\n    }\n\n    const result = await fetchGoodsList(id, id, page);\n\n    return c.json({\n      items: result.items,\n      nextPage: result.nextPage,\n      totalCount: result.totalCount,\n    });\n  });\n\n  return router;\n}\n"
  },
  {
    "path": "src/goofish/api/routes/index.ts",
    "content": "export { createAccountRoutes } from './accounts'\nexport { createGoodsRoutes } from './goods'\nexport { createMessageRoutes } from './messages'\nexport { createStatusRoutes } from './status'\nexport { createConversationRoutes } from './conversations'\nexport { createLogsRoutes } from './logs'\nexport { createAutoReplyRoutes } from './autoreply'\nexport { createOrderRoutes } from './order.route'\nexport { createAutoSellRoutes } from './autosell'\nexport { createWorkflowRoutes } from './workflow.route'\nexport { authRoute } from './auth.route'\n"
  },
  {
    "path": "src/goofish/api/routes/logs.ts",
    "content": "import { Hono } from \"hono\";\nimport fs from \"fs\";\nimport path from \"path\";\n\nconst logsDir = path.join(process.cwd(), \"logs\");\n\nexport function createLogsRoutes() {\n  const app = new Hono();\n\n  // 根路径 - 返回日志信息\n  app.get(\"/\", (c) => {\n    try {\n      if (!fs.existsSync(logsDir)) {\n        return c.json({\n          message: \"日志目录不存在\",\n          logsDir,\n          endpoints: {\n            \"/api/logs/dates\": \"获取所有日志日期列表\",\n            \"/api/logs/current\": \"获取当前运行的日志\",\n            \"/api/logs/files/:date\": \"获取指定日期的日志文件列表\",\n            \"/api/logs/content/:date/:file\": \"获取指定日志文件内容\",\n          },\n        });\n      }\n\n      const entries = fs.readdirSync(logsDir, { withFileTypes: true });\n      const dates = entries\n        .filter((e) => e.isDirectory() && /^\\d{4}-\\d{2}-\\d{2}$/.test(e.name))\n        .map((e) => e.name)\n        .sort((a, b) => b.localeCompare(a));\n\n      return c.json({\n        message: \"Goofish 日志 API\",\n        logsDir,\n        availableDates: dates.slice(0, 5),\n        totalCount: dates.length,\n        endpoints: {\n          \"/api/logs/dates\": \"获取所有日志日期列表\",\n          \"/api/logs/current\": \"获取当前运行的日志\",\n          \"/api/logs/files/:date\": \"获取指定日期的日志文件列表\",\n          \"/api/logs/content/:date/:file\": \"获取指定日志文件内容\",\n        },\n      });\n    } catch (error) {\n      return c.json({ error: \"获取日志信息失败\" }, 500);\n    }\n  });\n\n  // 获取日志日期列表\n  app.get(\"/dates\", (c) => {\n    try {\n      if (!fs.existsSync(logsDir)) {\n        return c.json({ dates: [] });\n      }\n      const entries = fs.readdirSync(logsDir, { withFileTypes: true });\n      const dates = entries\n        .filter((e) => e.isDirectory() && /^\\d{4}-\\d{2}-\\d{2}$/.test(e.name))\n        .map((e) => e.name)\n        .sort((a, b) => b.localeCompare(a));\n      return c.json({ dates });\n    } catch {\n      return c.json({ error: \"获取日志日期失败\" }, 500);\n    }\n  });\n\n  // 获取指定日期的日志文件列表\n  app.get(\"/files/:date\", (c) => {\n    try {\n      const date = c.req.param(\"date\");\n      const dayDir = path.join(logsDir, date);\n      if (!fs.existsSync(dayDir)) {\n        return c.json({ files: [] });\n      }\n      const files = fs\n        .readdirSync(dayDir)\n        .filter((f) => f.endsWith(\".log\"))\n        .map((f) => {\n          const stat = fs.statSync(path.join(dayDir, f));\n          return { name: f, size: stat.size, mtime: stat.mtimeMs };\n        })\n        .sort((a, b) => b.mtime - a.mtime);\n      return c.json({ files });\n    } catch {\n      return c.json({ error: \"获取日志文件列表失败\" }, 500);\n    }\n  });\n\n  // 获取日志文件内容\n  app.get(\"/content/:date/:file\", (c) => {\n    try {\n      const date = c.req.param(\"date\");\n      const file = c.req.param(\"file\");\n      const level = c.req.query(\"level\");\n      const limit = c.req.query(\"limit\") || \"500\";\n      const filePath = path.join(logsDir, date, file);\n\n      if (!fs.existsSync(filePath)) {\n        return c.json({ error: \"日志文件不存在\" }, 404);\n      }\n\n      const content = fs.readFileSync(filePath, \"utf-8\");\n      let lines = content.split(\"\\n\").filter((l) => l.trim());\n\n      if (level && level !== \"ALL\") {\n        lines = lines.filter((l) => l.includes(`| ${level} `));\n      }\n\n      const maxLines = parseInt(limit, 10) || 500;\n      const total = lines.length;\n      lines = lines.slice(-maxLines);\n\n      return c.json({ lines, total, filtered: total > maxLines });\n    } catch {\n      return c.json({ error: \"读取日志文件失败\" }, 500);\n    }\n  });\n\n  // 获取当前运行日志（实时）\n  app.get(\"/current\", (c) => {\n    try {\n      const level = c.req.query(\"level\");\n      const limit = c.req.query(\"limit\") || \"100\";\n\n      const now = new Date();\n      const dateStr = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, \"0\")}-${String(now.getDate()).padStart(2, \"0\")}`;\n      const dayDir = path.join(logsDir, dateStr);\n\n      if (!fs.existsSync(dayDir)) {\n        return c.json({ lines: [], total: 0, file: null });\n      }\n\n      const files = fs\n        .readdirSync(dayDir)\n        .filter((f) => f.endsWith(\".log\"))\n        .map((f) => ({\n          name: f,\n          mtime: fs.statSync(path.join(dayDir, f)).mtimeMs,\n        }))\n        .sort((a, b) => b.mtime - a.mtime);\n\n      if (files.length === 0) {\n        return c.json({ lines: [], total: 0, file: null });\n      }\n\n      const latestFile = files[0].name;\n      const filePath = path.join(dayDir, latestFile);\n      const content = fs.readFileSync(filePath, \"utf-8\");\n      let lines = content.split(\"\\n\").filter((l) => l.trim());\n\n      if (level && level !== \"ALL\") {\n        lines = lines.filter((l) => l.includes(`| ${level} `));\n      }\n\n      const maxLines = parseInt(limit, 10) || 100;\n      const total = lines.length;\n      lines = lines.slice(-maxLines);\n\n      return c.json({ lines, total, file: latestFile, date: dateStr });\n    } catch {\n      return c.json({ error: \"读取当前日志失败\" }, 500);\n    }\n  });\n\n  return app;\n}\n"
  },
  {
    "path": "src/goofish/api/routes/messages.ts",
    "content": "import { Hono } from \"hono\";\nimport { messageStore } from \"../stores/message.store\";\nimport type { ClientManager } from \"../../websocket/client.manager\";\n\nexport function createMessageRoutes(\n  getClientManager: () => ClientManager | null,\n) {\n  const router = new Hono();\n\n  // 获取消息列表\n  router.get(\"/\", (c) => {\n    const limit = parseInt(c.req.query(\"limit\") || \"20\");\n    return c.json({\n      messages: messageStore.getRecent(limit),\n      total: messageStore.count(),\n    });\n  });\n\n  // 发送消息\n  router.post(\"/send\", async (c) => {\n    const clientManager = getClientManager();\n    if (!clientManager) {\n      return c.json({ error: \"ClientManager not initialized\" }, 500);\n    }\n    const body = await c.req.json();\n    const { accountId, chatId, toUserId, text } = body;\n    if (!accountId || !chatId || !toUserId || !text) {\n      return c.json(\n        { error: \"Missing accountId, chatId, toUserId or text\" },\n        400,\n      );\n    }\n    const client = clientManager.getClient(accountId);\n    if (!client) {\n      return c.json({ error: \"Account not connected\" }, 400);\n    }\n    const success = await client.sendMessage(chatId, toUserId, text);\n    return c.json({ success });\n  });\n\n  return router;\n}\n"
  },
  {
    "path": "src/goofish/api/routes/order.route.ts",
    "content": "/**\n * 订单 API 路由\n */\n\nimport { Hono } from \"hono\";\n\nimport {\n  getOrderList,\n  getOrder,\n  fetchAndUpdateOrderDetail,\n} from \"../../services/order.service\";\nimport { updateOrderStatus, deleteOrder } from \"../../db/order.repository\";\nimport { OrderStatus, ORDER_STATUS_TEXT } from \"../../types/order.types\";\nimport type { ClientManager } from \"../../websocket/client.manager\";\n\nexport function createOrderRoutes(\n  getClientManager: () => ClientManager | null,\n) {\n  const app = new Hono();\n\n  // 获取订单列表\n  app.get(\"/\", async (c) => {\n    const accountId = c.req.query(\"accountId\");\n    const status = c.req.query(\"status\");\n    const limit = parseInt(c.req.query(\"limit\") || \"50\");\n    const offset = parseInt(c.req.query(\"offset\") || \"0\");\n\n    const result = getOrderList({\n      accountId: accountId || undefined,\n      status: status ? parseInt(status) : undefined,\n      limit,\n      offset,\n    });\n\n    return c.json(result);\n  });\n\n  // 获取单个订单\n  app.get(\"/:orderId\", async (c) => {\n    const orderId = c.req.param(\"orderId\");\n    const order = getOrder(orderId);\n\n    if (!order) {\n      return c.json({ error: \"订单不存在\" }, 404);\n    }\n\n    return c.json({ order });\n  });\n\n  // 刷新订单详情\n  app.post(\"/:orderId/refresh\", async (c) => {\n    const orderId = c.req.param(\"orderId\");\n    const clientManager = getClientManager();\n\n    if (!clientManager) {\n      return c.json({ error: \"ClientManager 未初始化\" }, 500);\n    }\n\n    const localOrder = getOrder(orderId);\n    if (!localOrder) {\n      return c.json({ error: \"订单不存在\" }, 404);\n    }\n\n    const client = clientManager.getClient(localOrder.accountId);\n    if (!client) {\n      return c.json({ error: \"账号未连接\" }, 400);\n    }\n\n    const detail = await fetchAndUpdateOrderDetail(client, orderId);\n    if (!detail) {\n      return c.json({ error: \"获取订单详情失败\" }, 500);\n    }\n\n    const updatedOrder = getOrder(orderId);\n    return c.json({ success: true, order: updatedOrder });\n  });\n\n  // 通过账号获取订单详情\n  app.post(\"/fetch\", async (c) => {\n    const body = await c.req.json();\n    const { accountId, orderId } = body;\n\n    if (!accountId || !orderId) {\n      return c.json({ error: \"缺少 accountId 或 orderId\" }, 400);\n    }\n\n    const clientManager = getClientManager();\n    if (!clientManager) {\n      return c.json({ error: \"ClientManager 未初始化\" }, 500);\n    }\n\n    const client = clientManager.getClient(accountId);\n    if (!client) {\n      return c.json({ error: \"账号未连接\" }, 400);\n    }\n\n    const detail = await fetchAndUpdateOrderDetail(client, orderId);\n    if (!detail) {\n      return c.json({ error: \"获取订单详情失败\" }, 500);\n    }\n\n    const order = getOrder(orderId);\n    return c.json({ success: true, order });\n  });\n\n  // 确认发货\n  app.post(\"/:orderId/ship\", async (c) => {\n    const orderId = c.req.param(\"orderId\");\n    const clientManager = getClientManager();\n\n    if (!clientManager) {\n      return c.json({ error: \"ClientManager 未初始化\" }, 500);\n    }\n\n    const localOrder = getOrder(orderId);\n    if (!localOrder) {\n      return c.json({ error: \"订单不存在\" }, 404);\n    }\n\n    if (localOrder.status !== OrderStatus.PENDING_SHIPMENT) {\n      return c.json({ error: \"只有待发货状态的订单才能执行发货\" }, 400);\n    }\n\n    const client = clientManager.getClient(localOrder.accountId);\n    if (!client) {\n      return c.json({ error: \"账号未连接\" }, 400);\n    }\n\n    const result = await client.confirmShipment(orderId);\n    if (result.success) {\n      updateOrderStatus(\n        orderId,\n        OrderStatus.PENDING_RECEIPT,\n        ORDER_STATUS_TEXT[OrderStatus.PENDING_RECEIPT],\n        \"ship_time\",\n      );\n      const updatedOrder = getOrder(orderId);\n      return c.json({ success: true, order: updatedOrder });\n    }\n\n    return c.json({ success: false, error: result.error }, 500);\n  });\n\n  // 免拼发货\n  app.post(\"/:orderId/freeship\", async (c) => {\n    const orderId = c.req.param(\"orderId\");\n    const clientManager = getClientManager();\n\n    if (!clientManager) {\n      return c.json({ error: \"ClientManager 未初始化\" }, 500);\n    }\n\n    const localOrder = getOrder(orderId);\n    if (!localOrder) {\n      return c.json({ error: \"订单不存在\" }, 404);\n    }\n\n    if (localOrder.status !== OrderStatus.PENDING_SHIPMENT) {\n      return c.json({ error: \"只有待发货状态的订单才能执行发货\" }, 400);\n    }\n\n    if (!localOrder.itemId || !localOrder.buyerUserId) {\n      return c.json({ error: \"订单缺少商品ID或买家ID，请先刷新订单详情\" }, 400);\n    }\n\n    const client = clientManager.getClient(localOrder.accountId);\n    if (!client) {\n      return c.json({ error: \"账号未连接\" }, 400);\n    }\n\n    const result = await client.freeShipping(\n      orderId,\n      localOrder.itemId,\n      localOrder.buyerUserId,\n    );\n    if (result.success) {\n      updateOrderStatus(\n        orderId,\n        OrderStatus.PENDING_RECEIPT,\n        ORDER_STATUS_TEXT[OrderStatus.PENDING_RECEIPT],\n        \"ship_time\",\n      );\n      const updatedOrder = getOrder(orderId);\n      return c.json({ success: true, order: updatedOrder });\n    }\n\n    return c.json({ success: false, error: result.error }, 500);\n  });\n\n  // 删除订单记录\n  app.delete(\"/:orderId\", async (c) => {\n    const orderId = c.req.param(\"orderId\");\n\n    const localOrder = getOrder(orderId);\n    if (!localOrder) {\n      return c.json({ error: \"订单不存在\" }, 404);\n    }\n\n    const success = deleteOrder(orderId);\n    if (success) {\n      return c.json({ success: true, message: \"订单记录已删除\" });\n    }\n\n    return c.json({ success: false, error: \"删除失败\" }, 500);\n  });\n\n  return app;\n}\n"
  },
  {
    "path": "src/goofish/api/routes/status.ts",
    "content": "import { Hono } from \"hono\";\nimport { messageStore } from \"../stores/message.store\";\nimport { getAllMessagesCount } from \"../../db/conversation.repository\";\nimport type { ClientManager } from \"../../websocket/client.manager\";\n\nexport function createStatusRoutes(\n  getClientManager: () => ClientManager | null,\n) {\n  const router = new Hono();\n\n  // 健康检查\n  router.get(\"/health\", (c) => {\n    return c.json({ status: \"ok\", timestamp: Date.now() });\n  });\n\n  // 获取整体状态\n  router.get(\"/status\", (c) => {\n    const clientManager = getClientManager();\n    if (!clientManager) {\n      return c.json({ error: \"ClientManager not initialized\" }, 500);\n    }\n    return c.json({\n      clients: clientManager.getStatus(),\n      activeCount: clientManager.getActiveCount(),\n      messageCount: getAllMessagesCount(),\n    });\n  });\n\n  return router;\n}\n"
  },
  {
    "path": "src/goofish/api/routes/workflow.route.ts",
    "content": "/**\n * 发货流程 API 路由\n */\n\nimport { Hono } from \"hono\";\n\nimport {\n  getWorkflows,\n  getWorkflowById,\n  createWorkflow,\n  updateWorkflow,\n  deleteWorkflow,\n} from \"../../db/index\";\n\nexport function createWorkflowRoutes() {\n  const app = new Hono();\n\n  // 获取所有流程\n  app.get(\"/\", (c) => {\n    const workflows = getWorkflows();\n    return c.json({ workflows });\n  });\n\n  // 获取单个流程\n  app.get(\"/:id\", (c) => {\n    const id = parseInt(c.req.param(\"id\"));\n    const workflow = getWorkflowById(id);\n    if (!workflow) {\n      return c.json({ error: \"流程不存在\" }, 404);\n    }\n    return c.json({ workflow });\n  });\n\n  // 创建流程\n  app.post(\"/\", async (c) => {\n    const body = await c.req.json();\n    const { name, description, definition, isDefault } = body;\n\n    if (!name || !definition) {\n      return c.json({ error: \"缺少必要参数\" }, 400);\n    }\n\n    const id = createWorkflow({ name, description, definition, isDefault });\n    return c.json({ success: true, id });\n  });\n\n  // 更新流程\n  app.put(\"/:id\", async (c) => {\n    const id = parseInt(c.req.param(\"id\"));\n    const body = await c.req.json();\n\n    const success = updateWorkflow(id, body);\n    if (!success) {\n      return c.json({ error: \"更新失败\" }, 400);\n    }\n    return c.json({ success: true });\n  });\n\n  // 删除流程\n  app.delete(\"/:id\", (c) => {\n    const id = parseInt(c.req.param(\"id\"));\n    const success = deleteWorkflow(id);\n    if (!success) {\n      return c.json({ error: \"删除失败，默认流程不能删除\" }, 400);\n    }\n    return c.json({ success: true });\n  });\n\n  // 设为默认流程\n  app.post(\"/:id/default\", (c) => {\n    const id = parseInt(c.req.param(\"id\"));\n    const success = updateWorkflow(id, { isDefault: true });\n    if (!success) {\n      return c.json({ error: \"设置失败\" }, 400);\n    }\n    return c.json({ success: true });\n  });\n\n  return app;\n}\n"
  },
  {
    "path": "src/goofish/api/routes/ws-push.route.ts",
    "content": "/**\n * WebSocket 推送路由\n * 替代 SSE，使用 WebSocket 实现实时数据推送\n */\n\nimport { Hono } from \"hono\";\nimport type { WSContext } from \"hono/ws\";\n\nimport { createLogger } from \"../../core/logger\";\nimport { appEvents, Events } from \"../../core/event-emitter\";\nimport { getOrders, getOrderCount } from \"../../db/order.repository\";\nimport { getAllAccounts } from \"../../db/account.repository\";\nimport { getAllConversations } from \"../../services/conversation.service\";\nimport type { ClientManager } from \"../../websocket/client.manager\";\n\nconst logger = createLogger(\"Api:WS\");\n\n// 存储所有 WebSocket 连接\nconst wsClients = new Set<{\n  ws: WSContext;\n  subscriptions: Set<string>;\n  params: Record<string, string | number | undefined>;\n}>();\n\n// 发送数据到订阅了特定事件的客户端\nfunction broadcast(\n  event: string,\n  getData: (params: Record<string, string | number | undefined>) => unknown,\n) {\n  // @ts-ignore\n  for (const client of wsClients) {\n    if (client.subscriptions.has(event)) {\n      try {\n        const data = getData(client.params);\n        client.ws.send(JSON.stringify({ event, data }));\n      } catch (e) {\n        logger.debug(`WebSocket 推送失败: ${e}`);\n      }\n    }\n  }\n}\n\n// 初始化事件监听（只需要一次）\nlet eventsInitialized = false;\n\nexport function initWSEvents(getClientManager: () => ClientManager | null) {\n  if (eventsInitialized) return;\n  eventsInitialized = true;\n\n  // 订单更新\n  appEvents.on(Events.ORDERS_UPDATED, () => {\n    broadcast(\"orders\", (params) => {\n      const orders = getOrders({\n        accountId: params.accountId as string | undefined,\n        status: params.status as number | undefined,\n        limit: 50,\n        offset: 0,\n      });\n      const total = getOrderCount({\n        accountId: params.accountId as string | undefined,\n        status: params.status as number | undefined,\n      });\n      return { orders, total };\n    });\n  });\n\n  // 账号更新\n  appEvents.on(Events.ACCOUNTS_UPDATED, () => {\n    broadcast(\"accounts\", () => {\n      const accounts = getAllAccounts();\n      const clientManager = getClientManager();\n      const clients = clientManager?.getStatus() || [];\n      return { accounts, clients };\n    });\n  });\n\n  // 对话更新\n  appEvents.on(Events.CONVERSATIONS_UPDATED, () => {\n    broadcast(\"conversations\", (params) => {\n      const limit = (params.limit as number) || 20;\n      const { conversations, total } = getAllConversations(limit, 0);\n      return { conversations, total };\n    });\n  });\n\n  logger.info(\"WebSocket 事件监听已初始化\");\n}\n\nexport function createWSPushHandler(\n  getClientManager: () => ClientManager | null,\n) {\n  // 确保事件监听已初始化\n  initWSEvents(getClientManager);\n\n  return {\n    onOpen(_event: Event, ws: WSContext) {\n      const client = {\n        ws,\n        subscriptions: new Set<string>(),\n        params: {} as Record<string, string | number | undefined>,\n      };\n      wsClients.add(client);\n      logger.debug(`WebSocket 连接建立，当前连接数: ${wsClients.size}`);\n    },\n\n    onMessage(event: MessageEvent, ws: WSContext) {\n      try {\n        const msg = JSON.parse(event.data as string);\n        // @ts-ignore\n        const client = [...wsClients].find((c) => c.ws === ws);\n        if (!client) return;\n\n        // 订阅消息格式: { action: 'subscribe', events: ['orders', 'accounts'], params: { accountId: '...' } }\n        if (msg.action === \"subscribe\" && Array.isArray(msg.events)) {\n          for (const evt of msg.events) {\n            client.subscriptions.add(evt);\n          }\n          if (msg.params) {\n            Object.assign(client.params, msg.params);\n          }\n\n          // 立即发送当前数据\n          for (const evt of msg.events) {\n            sendInitialData(ws, evt, client.params, getClientManager);\n          }\n\n          logger.debug(`客户端订阅: ${msg.events.join(\", \")}`);\n        }\n\n        // 取消订阅: { action: 'unsubscribe', events: ['orders'] }\n        if (msg.action === \"unsubscribe\" && Array.isArray(msg.events)) {\n          for (const evt of msg.events) {\n            client.subscriptions.delete(evt);\n          }\n        }\n\n        // 更新参数: { action: 'updateParams', params: { accountId: '...' } }\n        if (msg.action === \"updateParams\" && msg.params) {\n          Object.assign(client.params, msg.params);\n          // 重新发送订阅的数据\n          for (const evt of client.subscriptions) {\n            sendInitialData(ws, evt, client.params, getClientManager);\n          }\n        }\n      } catch {\n        // 忽略解析错误\n      }\n    },\n\n    onClose() {\n      // @ts-ignore\n      for (const client of wsClients) {\n        if (client.ws.readyState >= 2) {\n          // CLOSING or CLOSED\n          wsClients.delete(client);\n        }\n      }\n      logger.debug(`WebSocket 连接关闭，当前连接数: ${wsClients.size}`);\n    },\n\n    onError() {\n      // 清理已关闭的连接\n      // @ts-ignore\n      for (const client of wsClients) {\n        if (client.ws.readyState >= 2) {\n          wsClients.delete(client);\n        }\n      }\n    },\n  };\n}\n\n// 发送初始数据\nfunction sendInitialData(\n  ws: WSContext,\n  event: string,\n  params: Record<string, string | number | undefined>,\n  getClientManager: () => ClientManager | null,\n) {\n  try {\n    let data: unknown;\n\n    switch (event) {\n      case \"orders\": {\n        const orders = getOrders({\n          accountId: params.accountId as string | undefined,\n          status: params.status as number | undefined,\n          limit: 50,\n          offset: 0,\n        });\n        const total = getOrderCount({\n          accountId: params.accountId as string | undefined,\n          status: params.status as number | undefined,\n        });\n        data = { orders, total };\n        break;\n      }\n      case \"accounts\": {\n        const accounts = getAllAccounts();\n        const clientManager = getClientManager();\n        const clients = clientManager?.getStatus() || [];\n        data = { accounts, clients };\n        break;\n      }\n      case \"conversations\": {\n        const limit = (params.limit as number) || 20;\n        const { conversations, total } = getAllConversations(limit, 0);\n        data = { conversations, total };\n        break;\n      }\n      default:\n        return;\n    }\n\n    ws.send(JSON.stringify({ event, data }));\n  } catch (e) {\n    logger.debug(`发送初始数据失败: ${e}`);\n  }\n}\n\n// 获取当前连接数（用于调试）\nexport function getWSClientCount() {\n  return wsClients.size;\n}\n"
  },
  {
    "path": "src/goofish/api/server.ts",
    "content": "import { serve } from \"@hono/node-server\";\nimport { createNodeWebSocket } from \"@hono/node-ws\";\nimport { Hono } from \"hono\";\nimport { cors } from \"hono/cors\";\n\nimport { createLogger } from \"../core/logger\";\nimport { SERVER_CONFIG, ENV } from \"../core/constants\";\nimport { securityMiddleware } from \"./middlewares\";\nimport {\n  createAccountRoutes,\n  createGoodsRoutes,\n  createMessageRoutes,\n  createStatusRoutes,\n  createConversationRoutes,\n  createLogsRoutes,\n  createAutoReplyRoutes,\n  createOrderRoutes,\n  createAutoSellRoutes,\n  createWorkflowRoutes,\n  authRoute,\n} from \"./routes\";\nimport { createDevMessageRoutes } from \"./routes/dev-messages.route\";\nimport { createWSPushHandler } from \"./routes/ws-push.route\";\nimport type { ClientManager } from \"../websocket/client.manager\";\n\nconst logger = createLogger(\"Goofish:Api:Server\");\nconst apiLogger = createLogger(\"Goofish:Api:Request\");\n\nlet clientManager: ClientManager | null = null;\n\nexport function setClientManager(cm: ClientManager) {\n  clientManager = cm;\n}\n\nfunction getClientManager() {\n  return clientManager;\n}\n\n// WebSocket 相关\nlet upgradeWebSocket:\n  | ReturnType<typeof createNodeWebSocket>[\"upgradeWebSocket\"]\n  | null = null;\nlet injectWebSocket:\n  | ReturnType<typeof createNodeWebSocket>[\"injectWebSocket\"]\n  | null = null;\n\nexport function createApp() {\n  const app = new Hono();\n\n  // 创建 WebSocket 支持\n  const nodeWS = createNodeWebSocket({ app });\n  upgradeWebSocket = nodeWS.upgradeWebSocket;\n  injectWebSocket = nodeWS.injectWebSocket;\n\n  app.use(\"*\", cors());\n\n  // 安全中间件 - 限制 API 只能从前端请求（排除 WebSocket）\n  app.use(\"/api/*\", securityMiddleware);\n\n  // API 日志 - 只记录非 GET 请求，减少日志量\n  app.use(\"/api/*\", async (c, next) => {\n    await next();\n    if (c.req.method !== \"GET\") {\n      apiLogger.info(`${c.req.method} ${c.req.path}`);\n    }\n  });\n\n  // WebSocket 推送端点\n  app.get(\n    \"/ws\",\n    upgradeWebSocket(() => createWSPushHandler(getClientManager)),\n  );\n\n  // 挂载路由模块\n  const statusRoutes = createStatusRoutes(getClientManager);\n  app.route(\"/\", statusRoutes);\n  app.route(\"/api\", statusRoutes);\n\n  app.route(\"/api/accounts\", createAccountRoutes(getClientManager));\n  app.route(\"/api/goods\", createGoodsRoutes(getClientManager));\n  app.route(\"/api/messages\", createMessageRoutes(getClientManager));\n  app.route(\"/api/conversations\", createConversationRoutes());\n  app.route(\"/api/logs\", createLogsRoutes());\n  app.route(\"/api/autoreply\", createAutoReplyRoutes());\n  app.route(\"/api/orders\", createOrderRoutes(getClientManager));\n  app.route(\"/api/autosell\", createAutoSellRoutes());\n  app.route(\"/api/workflows\", createWorkflowRoutes());\n  app.route(\"/api/auth\", authRoute);\n\n  // 开发环境才注册调试路由\n  if (ENV.IS_DEV) {\n    app.route(\"/api/dev/messages\", createDevMessageRoutes());\n    logger.info(\"开发模式：已启用调试路由 /api/dev/messages\");\n  }\n\n  // 兼容旧的发送消息接口\n  app.post(\"/api/send\", async (c) => {\n    if (!clientManager) {\n      return c.json({ error: \"ClientManager not initialized\" }, 500);\n    }\n    const body = await c.req.json();\n    const { accountId, chatId, toUserId, text } = body;\n    if (!accountId || !chatId || !toUserId || !text) {\n      return c.json(\n        { error: \"Missing accountId, chatId, toUserId or text\" },\n        400,\n      );\n    }\n    const client = clientManager.getClient(accountId);\n    if (!client) {\n      return c.json({ error: \"Account not connected\" }, 400);\n    }\n    const success = await client.sendMessage(chatId, toUserId, text);\n    return c.json({ success });\n  });\n\n  // 兼容旧的账号商品接口\n  app.get(\"/api/accounts/:id/goods\", async (c) => {\n    const id = c.req.param(\"id\");\n    const page = c.req.query(\"page\") || \"1\";\n    const url = new URL(c.req.url);\n    url.pathname = `/api/goods/account/${id}`;\n    return c.redirect(url.pathname + `?page=${page}`);\n  });\n\n  return app;\n}\n\nexport function startServer(port = SERVER_CONFIG.PORT) {\n  const app = createApp();\n\n  const server = serve({ fetch: app.fetch, port }, () => {\n    logger.info(`Goofish 服务器启动在端口 ${port}`);\n  });\n\n  // 注入 WebSocket 支持\n  if (injectWebSocket) {\n    injectWebSocket(server);\n    logger.info(\"WebSocket 推送已启用\");\n  }\n\n  return server;\n}\n"
  },
  {
    "path": "src/goofish/api/stores/conversation.store.ts",
    "content": "/**\n * 对话存储（兼容层）\n * 委托给 conversation.service 处理\n */\n\nimport {\n  addIncomingMessage,\n  addOutgoingMessage,\n  updateUserAvatar as updateAvatar,\n  getAllConversations,\n  getConversationDetail,\n  markAsRead,\n} from \"../../services/index\";\nimport type { ChatMessage, Conversation } from \"../../types/index\";\n\nclass ConversationStore {\n  addIncoming(accountId: string, msg: ChatMessage) {\n    addIncomingMessage(accountId, msg);\n  }\n\n  addOutgoing(\n    accountId: string,\n    chatId: string,\n    toUserId: string,\n    content: string,\n  ) {\n    addOutgoingMessage(accountId, chatId, toUserId, content);\n  }\n\n  updateUserAvatar(accountId: string, chatId: string, avatar: string) {\n    updateAvatar(accountId, chatId, avatar);\n  }\n\n  getAll(\n    limit = 20,\n    offset = 0,\n  ): { conversations: Conversation[]; total: number } {\n    return getAllConversations(limit, offset);\n  }\n\n  get(\n    accountId: string,\n    chatId: string,\n    messageLimit = 50,\n    beforeId?: number,\n  ): Conversation | undefined {\n    return getConversationDetail(accountId, chatId, messageLimit, beforeId);\n  }\n\n  markRead(accountId: string, chatId: string) {\n    markAsRead(accountId, chatId);\n  }\n}\n\nexport const conversationStore = new ConversationStore();\n"
  },
  {
    "path": "src/goofish/api/stores/message.store.ts",
    "content": "/**\n * 消息存储（兼容层）\n * 委托给 message.service 处理\n */\n\nimport {\n  addMessage,\n  getRecentMessages,\n  getAllMessages,\n  getMessageCount,\n  clearMessages,\n} from \"../../services/index\";\nimport type { StoredMessage, ChatMessage } from \"../../types/index\";\n\nclass MessageStore {\n  add(msg: ChatMessage) {\n    addMessage(msg);\n  }\n\n  getRecent(limit = 20): StoredMessage[] {\n    return getRecentMessages(limit);\n  }\n\n  getAll(): StoredMessage[] {\n    return getAllMessages();\n  }\n\n  count(): number {\n    return getMessageCount();\n  }\n\n  clear() {\n    clearMessages();\n  }\n}\n\nexport const messageStore = new MessageStore();\n"
  },
  {
    "path": "src/goofish/core/constants.ts",
    "content": "// WebSocket 配置\nexport const WS_CONFIG = {\n  URL: \"wss://wss-goofish.dingtalk.com/\",\n  HEARTBEAT_INTERVAL: 15, // 心跳间隔（秒）\n  HEARTBEAT_TIMEOUT: 30, // 心跳超时（秒）\n  TOKEN_REFRESH_INTERVAL: 3600, // Token刷新间隔（秒）- 1小时\n  TOKEN_RETRY_INTERVAL: 300, // Token刷新失败重试间隔（秒）- 5分钟\n  MAX_RECONNECT_ATTEMPTS: 5, // 最大重连次数\n  RECONNECT_DELAY: 5000, // 重连延迟（毫秒）\n  APP_KEY: \"444e9908a51d1cb236a27862abc769c9\",\n  SIGN_APP_KEY: \"34839810\",\n};\n\n// API 配置\nexport const API_CONFIG = {\n  BASE_URL: \"https://h5api.m.goofish.com/h5\",\n  VERSION: \"1.0\",\n};\n\n// API 方法\nexport const API_METHODS = {\n  TOKEN: \"mtop.taobao.idlemessage.pc.login.token\",\n  USER_INFO: \"mtop.idle.web.user.page.nav\",\n  LOGIN_USER: \"mtop.taobao.idlemessage.pc.loginuser.get\",\n  ITEM_LIST: \"mtop.idle.web.xyh.item.list\",\n  USER_HEAD: \"mtop.idle.web.user.page.head\",\n  HAS_LOGIN: \"newlogin/hasLogin.do\",\n  ORDER_DETAIL: \"mtop.idle.web.trade.order.detail\",\n  CONFIRM_SHIPMENT: \"mtop.taobao.idle.logistic.consign.dummy\",\n  FREE_SHIPPING: \"mtop.idle.groupon.activity.seller.freeshipping\",\n};\n\n// Passport API 配置\nexport const PASSPORT_CONFIG = {\n  BASE_URL: \"https://passport.goofish.com\",\n};\n\n// 构建完整 API URL\nexport function buildApiUrl(\n  method: string,\n  version = API_CONFIG.VERSION,\n): string {\n  return `${API_CONFIG.BASE_URL}/${method}/${version}/`;\n}\n\n// API 端点（兼容旧代码）\nexport const API_ENDPOINTS = {\n  TOKEN: buildApiUrl(API_METHODS.TOKEN),\n  USER_INFO: buildApiUrl(API_METHODS.USER_INFO),\n  LOGIN_USER: buildApiUrl(API_METHODS.LOGIN_USER),\n  ITEM_LIST: buildApiUrl(API_METHODS.ITEM_LIST),\n  USER_HEAD: buildApiUrl(API_METHODS.USER_HEAD),\n  ORDER_DETAIL: buildApiUrl(API_METHODS.ORDER_DETAIL),\n  CONFIRM_SHIPMENT: buildApiUrl(API_METHODS.CONFIRM_SHIPMENT),\n  FREE_SHIPPING: buildApiUrl(API_METHODS.FREE_SHIPPING),\n};\n\n// WebSocket 请求头\nexport const WS_HEADERS = {\n  \"Accept-Encoding\": \"gzip, deflate, br, zstd\",\n  \"Accept-Language\": \"zh-CN,zh;q=0.9\",\n  \"Cache-Control\": \"no-cache\",\n  Connection: \"Upgrade\",\n  Host: \"wss-goofish.dingtalk.com\",\n  Origin: \"https://www.goofish.com\",\n  Pragma: \"no-cache\",\n  \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\",\n};\n\n// 日志配置\nexport const LOG_CONFIG = {\n  LEVEL: \"INFO\" as const,\n  RETENTION_DAYS: 7,\n};\n\n// 环境配置\nexport const ENV = {\n  IS_DEV: process.env.NODE_ENV !== \"production\",\n};\n\n// API 服务器配置\nexport const SERVER_CONFIG = {\n  PORT: 3001,\n  STATIC_DIR: \"public\",\n};\n\n// 数据库配置\nexport const DB_CONFIG = {\n  PATH: \"data/goofishcbot.db\",\n};\n"
  },
  {
    "path": "src/goofish/core/cookies.manager.ts",
    "content": "import { getAccount, updateAccountCookies } from \"../db/index\";\nimport {\n  parseCookies,\n  mergeCookies,\n  parseSetCookieHeaders,\n} from \"../utils/cookies\";\nimport { createLogger } from \"./logger\";\n\nconst logger = createLogger(\"Core:Cookies\");\n\n/**\n * Cookies 管理器\n * 统一管理 cookies 的读取和写入，确保所有地方使用最新的 cookies\n *\n * 设计原则：\n * 1. 读取：始终从数据库读取，保证获取最新值\n * 2. 写入：增量合并后写入数据库，任何地方都可以更新\n * 3. 不在内存中缓存 cookies，避免状态不一致\n */\nexport class CookiesManager {\n  /**\n   * 获取账号的最新 cookies 字符串\n   */\n  static getCookies(accountId: string): string | null {\n    const account = getAccount(accountId);\n    return account?.cookies || null;\n  }\n\n  /**\n   * 获取账号的最新 cookies 对象\n   */\n  static getCookiesObject(accountId: string): Record<string, string> {\n    const cookiesStr = this.getCookies(accountId);\n    return cookiesStr ? parseCookies(cookiesStr) : {};\n  }\n\n  /**\n   * 获取指定的 cookie 值\n   */\n  static getCookie(accountId: string, name: string): string | undefined {\n    const cookies = this.getCookiesObject(accountId);\n    return cookies[name];\n  }\n\n  /**\n   * 更新 cookies（增量合并）\n   * @param accountId 账号ID\n   * @param newCookies 新的 cookies（可以是字符串或对象）\n   * @returns 合并后的完整 cookies 字符串，如果没有实际更新则返回 null\n   */\n  static updateCookies(\n    accountId: string,\n    newCookies: string | Record<string, string>,\n  ): string | null {\n    const currentCookies = this.getCookies(accountId);\n    if (!currentCookies) {\n      logger.warn(`[${accountId}] 账号不存在，无法更新 cookies`);\n      return null;\n    }\n\n    const currentCookiesObj = parseCookies(currentCookies);\n    const newCookiesObj =\n      typeof newCookies === \"string\" ? parseCookies(newCookies) : newCookies;\n\n    // 检查哪些字段实际发生了变化\n    const changedFields: string[] = [];\n    for (const [key, value] of Object.entries(newCookiesObj)) {\n      if (currentCookiesObj[key] !== value) {\n        changedFields.push(key);\n      }\n    }\n\n    // 如果没有实际变化，不更新不输出日志\n    if (changedFields.length === 0) {\n      return null;\n    }\n\n    const mergedCookies = mergeCookies(currentCookies, newCookiesObj);\n\n    if (updateAccountCookies(accountId, mergedCookies)) {\n      logger.info(\n        `[${accountId}] Cookies 已更新 | 变更字段: ${changedFields.join(\", \")}`,\n      );\n      return mergedCookies;\n    }\n\n    return null;\n  }\n\n  /**\n   * 处理 HTTP 响应中的 Set-Cookie，自动更新到数据库\n   * @param accountId 账号ID\n   * @param response HTTP 响应对象\n   * @returns 是否有更新\n   */\n  static handleResponseCookies(accountId: string, response: Response): boolean {\n    const setCookieHeaders = response.headers.getSetCookie?.() || [];\n    if (setCookieHeaders.length === 0) {\n      return false;\n    }\n\n    const newCookies = parseSetCookieHeaders(setCookieHeaders);\n    if (Object.keys(newCookies).length === 0) {\n      return false;\n    }\n\n    const result = this.updateCookies(accountId, newCookies);\n    return result !== null;\n  }\n\n  /**\n   * 获取用于 API 签名的 h5 token\n   */\n  static getH5Token(accountId: string): string {\n    const h5tk = this.getCookie(accountId, \"_m_h5_tk\");\n    return h5tk?.split(\"_\")[0] || \"\";\n  }\n\n  /**\n   * 获取用户 ID (unb)\n   */\n  static getUserId(accountId: string): string | undefined {\n    return this.getCookie(accountId, \"unb\");\n  }\n}\n"
  },
  {
    "path": "src/goofish/core/event-emitter.ts",
    "content": "/**\n * 全局事件发射器\n * 用于数据变化时通知 SSE 推送\n * 使用防抖机制避免频繁触发\n */\n\nimport { EventEmitter } from \"events\";\n\nexport const appEvents = new EventEmitter();\n\n// 增加最大监听器数量（SSE 连接可能较多）\nappEvents.setMaxListeners(50);\n\n// 事件类型\nexport const Events = {\n  ORDERS_UPDATED: \"orders:updated\",\n  ACCOUNTS_UPDATED: \"accounts:updated\",\n  CONVERSATIONS_UPDATED: \"conversations:updated\",\n} as const;\n\n// 防抖定时器\nconst debounceTimers: Record<string, NodeJS.Timeout | null> = {\n  orders: null,\n  accounts: null,\n  conversations: null,\n};\n\n// 防抖延迟（毫秒）\nconst DEBOUNCE_DELAY = 100;\n\n// 触发订单更新事件（防抖）\nexport function emitOrdersUpdated() {\n  if (debounceTimers.orders) {\n    clearTimeout(debounceTimers.orders);\n  }\n  debounceTimers.orders = setTimeout(() => {\n    appEvents.emit(Events.ORDERS_UPDATED);\n    debounceTimers.orders = null;\n  }, DEBOUNCE_DELAY);\n}\n\n// 触发账号更新事件（防抖）\nexport function emitAccountsUpdated() {\n  if (debounceTimers.accounts) {\n    clearTimeout(debounceTimers.accounts);\n  }\n  debounceTimers.accounts = setTimeout(() => {\n    appEvents.emit(Events.ACCOUNTS_UPDATED);\n    debounceTimers.accounts = null;\n  }, DEBOUNCE_DELAY);\n}\n\n// 触发对话更新事件（防抖）\nexport function emitConversationsUpdated() {\n  if (debounceTimers.conversations) {\n    clearTimeout(debounceTimers.conversations);\n  }\n  debounceTimers.conversations = setTimeout(() => {\n    appEvents.emit(Events.CONVERSATIONS_UPDATED);\n    debounceTimers.conversations = null;\n  }, DEBOUNCE_DELAY);\n}\n"
  },
  {
    "path": "src/goofish/core/logger.ts",
    "content": "import fs from \"fs\";\nimport path from \"path\";\n\nconst logsDir = path.join(process.cwd(), \"logs\");\n\nexport type LogLevel = \"DEBUG\" | \"INFO\" | \"WARN\" | \"ERROR\";\n\nconst levelPriority: Record<LogLevel, number> = {\n  DEBUG: 0,\n  INFO: 1,\n  WARN: 2,\n  ERROR: 3,\n};\n\nlet currentLevel: LogLevel = \"INFO\";\nlet currentLogFile: string = \"\";\n\nexport function setLogLevel(level: LogLevel) {\n  currentLevel = level;\n}\n\nfunction formatTime(): string {\n  const now = new Date();\n  const y = now.getFullYear();\n  const m = String(now.getMonth() + 1).padStart(2, \"0\");\n  const d = String(now.getDate()).padStart(2, \"0\");\n  const h = String(now.getHours()).padStart(2, \"0\");\n  const min = String(now.getMinutes()).padStart(2, \"0\");\n  const s = String(now.getSeconds()).padStart(2, \"0\");\n  return `${y}-${m}-${d} ${h}:${min}:${s}`;\n}\n\nfunction getDateStr(): string {\n  const now = new Date();\n  const y = now.getFullYear();\n  const m = String(now.getMonth() + 1).padStart(2, \"0\");\n  const d = String(now.getDate()).padStart(2, \"0\");\n  return `${y}-${m}-${d}`;\n}\n\nfunction getTimestampStr(): string {\n  const now = new Date();\n  const y = now.getFullYear();\n  const m = String(now.getMonth() + 1).padStart(2, \"0\");\n  const d = String(now.getDate()).padStart(2, \"0\");\n  const h = String(now.getHours()).padStart(2, \"0\");\n  const min = String(now.getMinutes()).padStart(2, \"0\");\n  const s = String(now.getSeconds()).padStart(2, \"0\");\n  return `${y}${m}${d}_${h}${min}${s}`;\n}\n\n// 初始化日志文件（每次启动创建新文件）\nfunction initLogFile(): string {\n  const dateStr = getDateStr();\n  const dayDir = path.join(logsDir, dateStr);\n\n  // 确保日期目录存在\n  if (!fs.existsSync(dayDir)) {\n    fs.mkdirSync(dayDir, { recursive: true });\n  }\n\n  // 以启动时间戳命名日志文件\n  const timestamp = getTimestampStr();\n  return path.join(dayDir, `${timestamp}.log`);\n}\n\n// 日志队列，确保顺序\nconst logQueue: string[] = [];\nlet isWriting = false;\n\nfunction flushLogs() {\n  if (isWriting || logQueue.length === 0) return;\n  isWriting = true;\n\n  const content = logQueue.splice(0, logQueue.length).join(\"\\n\") + \"\\n\";\n\n  fs.appendFile(currentLogFile, content, \"utf-8\", () => {\n    isWriting = false;\n    if (logQueue.length > 0) flushLogs();\n  });\n}\n\nexport function log(level: LogLevel, module: string, message: string) {\n  if (levelPriority[level] < levelPriority[currentLevel]) return;\n\n  const time = formatTime();\n  const logLine = `${time} | ${level.padEnd(5)} | ${module.padEnd(12)} | ${message}`;\n\n  const colors: Record<LogLevel, string> = {\n    DEBUG: \"\\x1b[90m\",\n    INFO: \"\\x1b[36m\",\n    WARN: \"\\x1b[33m\",\n    ERROR: \"\\x1b[31m\",\n  };\n  process.stdout.write(`${colors[level]}${logLine}\\x1b[0m\\n`);\n\n  logQueue.push(logLine);\n  flushLogs();\n}\n\nexport function cleanOldLogs(retentionDays = 7) {\n  if (!fs.existsSync(logsDir)) return;\n\n  const now = Date.now();\n  const maxAge = retentionDays * 24 * 60 * 60 * 1000;\n\n  // 遍历日期文件夹\n  const entries = fs.readdirSync(logsDir, { withFileTypes: true });\n\n  for (const entry of entries) {\n    const entryPath = path.join(logsDir, entry.name);\n\n    if (entry.isDirectory()) {\n      // 检查文件夹日期\n      const stat = fs.statSync(entryPath);\n      if (now - stat.mtimeMs > maxAge) {\n        fs.rmSync(entryPath, { recursive: true, force: true });\n        log(\"INFO\", \"Logger\", `已删除过期日志目录: ${entry.name}`);\n      }\n    } else if (entry.name.endsWith(\".log\")) {\n      // 兼容旧的日志文件（直接在logs目录下的）\n      const stat = fs.statSync(entryPath);\n      if (now - stat.mtimeMs > maxAge) {\n        fs.unlinkSync(entryPath);\n        log(\"INFO\", \"Logger\", `已删除过期日志: ${entry.name}`);\n      }\n    }\n  }\n}\n\nexport interface Logger {\n  debug: (msg: string) => void;\n  info: (msg: string) => void;\n  warn: (msg: string) => void;\n  error: (msg: string) => void;\n}\n\nexport function createLogger(module: string): Logger {\n  return {\n    debug: (msg: string) => log(\"DEBUG\", module, msg),\n    info: (msg: string) => log(\"INFO\", module, msg),\n    warn: (msg: string) => log(\"WARN\", module, msg),\n    error: (msg: string) => log(\"ERROR\", module, msg),\n  };\n}\n\n// 初始化\ncurrentLogFile = initLogFile();\n"
  },
  {
    "path": "src/goofish/db/account.repository.ts",
    "content": "/**\n * 账号数据仓库\n */\n\nimport { db } from \"./connection\";\nimport { createLogger } from \"../core/logger\";\nimport { nowLocalString } from \"../utils/date\";\nimport { emitAccountsUpdated } from \"../core/event-emitter\";\nimport type {\n  Account,\n  AccountStatus,\n  UpsertAccountParams,\n  UpdateAccountStatusParams,\n} from \"../types/index\";\n\nconst logger = createLogger(\"Db:Account\");\n\n// 获取所有启用的账号\nexport function getEnabledAccounts(): Account[] {\n  const stmt = db.prepare(`\n        SELECT id, cookies, user_id as userId, nickname, avatar, enabled, remark, \n               created_at as createdAt, updated_at as updatedAt\n        FROM accounts WHERE enabled = 1\n    `);\n  return stmt.all() as Account[];\n}\n\n// 获取所有账号\nexport function getAllAccounts(): Account[] {\n  const stmt = db.prepare(`\n        SELECT id, cookies, user_id as userId, nickname, avatar, enabled, remark,\n               created_at as createdAt, updated_at as updatedAt\n        FROM accounts\n    `);\n  return stmt.all() as Account[];\n}\n\n// 获取单个账号\nexport function getAccount(id: string): Account | null {\n  const stmt = db.prepare(`\n        SELECT id, cookies, user_id as userId, nickname, avatar, enabled, remark,\n               created_at as createdAt, updated_at as updatedAt\n        FROM accounts WHERE id = ?\n    `);\n  return stmt.get(id) as Account | null;\n}\n\n// 添加或更新账号\nexport function upsertAccount(account: UpsertAccountParams): boolean {\n  try {\n    const now = nowLocalString();\n    const stmt = db.prepare(`\n            INSERT INTO accounts (id, cookies, user_id, nickname, avatar, enabled, remark, updated_at)\n            VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n            ON CONFLICT(id) DO UPDATE SET\n                cookies = excluded.cookies,\n                user_id = COALESCE(excluded.user_id, user_id),\n                nickname = COALESCE(excluded.nickname, nickname),\n                avatar = COALESCE(excluded.avatar, avatar),\n                enabled = COALESCE(excluded.enabled, enabled),\n                remark = COALESCE(excluded.remark, remark),\n                updated_at = excluded.updated_at\n        `);\n    stmt.run(\n      account.id,\n      account.cookies,\n      account.userId || null,\n      account.nickname || null,\n      account.avatar || null,\n      account.enabled !== false ? 1 : 0,\n      account.remark || \"\",\n      now,\n    );\n    logger.info(`账号已保存: ${account.id}`);\n    emitAccountsUpdated();\n    return true;\n  } catch (e) {\n    logger.error(`保存账号失败: ${e}`);\n    return false;\n  }\n}\n\n// 更新账号用户信息\nexport function updateAccountUserInfo(\n  id: string,\n  nickname: string,\n  avatar: string,\n): boolean {\n  try {\n    const now = nowLocalString();\n    const stmt = db.prepare(`\n            UPDATE accounts SET nickname = ?, avatar = ?, updated_at = ? WHERE id = ?\n        `);\n    stmt.run(nickname, avatar, now, id);\n    logger.info(`账号用户信息已更新: ${id} -> ${nickname}`);\n    emitAccountsUpdated();\n    return true;\n  } catch (e) {\n    logger.error(`更新账号用户信息失败: ${e}`);\n    return false;\n  }\n}\n\n// 更新账号 cookies\nexport function updateAccountCookies(id: string, cookies: string): boolean {\n  try {\n    const now = nowLocalString();\n    const stmt = db.prepare(`\n            UPDATE accounts SET cookies = ?, updated_at = ? WHERE id = ?\n        `);\n    stmt.run(cookies, now, id);\n    logger.info(`账号 cookies 已更新: ${id}`);\n    emitAccountsUpdated();\n    return true;\n  } catch (e) {\n    logger.error(`更新账号 cookies 失败: ${e}`);\n    return false;\n  }\n}\n\n// 更新账号启用状态\nexport function updateAccountEnabled(id: string, enabled: boolean): boolean {\n  try {\n    const now = nowLocalString();\n    const stmt = db.prepare(`\n            UPDATE accounts SET enabled = ?, updated_at = ? WHERE id = ?\n        `);\n    stmt.run(enabled ? 1 : 0, now, id);\n    emitAccountsUpdated();\n    return true;\n  } catch (e) {\n    logger.error(`更新账号状态失败: ${e}`);\n    return false;\n  }\n}\n\n// 删除账号\nexport function deleteAccount(id: string): boolean {\n  try {\n    const stmt = db.prepare(\"DELETE FROM accounts WHERE id = ?\");\n    stmt.run(id);\n    logger.info(`账号已删除: ${id}`);\n    emitAccountsUpdated();\n    return true;\n  } catch (e) {\n    logger.error(`删除账号失败: ${e}`);\n    return false;\n  }\n}\n\n// 更新账号连接状态（只在连接状态变化时触发事件）\nexport function updateAccountStatus(\n  status: UpdateAccountStatusParams,\n): boolean {\n  try {\n    const now = nowLocalString();\n\n    // 检查连接状态是否变化\n    const shouldEmit = status.connected !== undefined;\n    let statusChanged = false;\n\n    if (shouldEmit) {\n      const current = getAccountStatus(status.accountId);\n      statusChanged = !current || current.connected !== status.connected;\n    }\n\n    const stmt = db.prepare(`\n            INSERT INTO account_status (account_id, connected, last_heartbeat, last_token_refresh, error_message, updated_at)\n            VALUES (?, ?, ?, ?, ?, ?)\n            ON CONFLICT(account_id) DO UPDATE SET\n                connected = COALESCE(excluded.connected, connected),\n                last_heartbeat = COALESCE(excluded.last_heartbeat, last_heartbeat),\n                last_token_refresh = COALESCE(excluded.last_token_refresh, last_token_refresh),\n                error_message = excluded.error_message,\n                updated_at = excluded.updated_at\n        `);\n    stmt.run(\n      status.accountId,\n      status.connected !== undefined ? (status.connected ? 1 : 0) : null,\n      status.lastHeartbeat || null,\n      status.lastTokenRefresh || null,\n      status.errorMessage ?? null,\n      now,\n    );\n\n    // 只在连接状态变化时触发事件\n    if (statusChanged) {\n      emitAccountsUpdated();\n    }\n    return true;\n  } catch (e) {\n    logger.error(`更新账号状态失败: ${e}`);\n    return false;\n  }\n}\n\n// 获取账号状态\nexport function getAccountStatus(accountId: string): AccountStatus | null {\n  const stmt = db.prepare(`\n        SELECT account_id as accountId, connected, last_heartbeat as lastHeartbeat,\n               last_token_refresh as lastTokenRefresh, error_message as errorMessage\n        FROM account_status WHERE account_id = ?\n    `);\n  const result = stmt.get(accountId) as any;\n  if (result) {\n    result.connected = !!result.connected;\n  }\n  return result;\n}\n"
  },
  {
    "path": "src/goofish/db/autoreply.repository.ts",
    "content": "/**\n * 自动回复规则数据仓库\n */\n\nimport { db } from \"./connection\";\nimport type {\n  DbAutoReplyRule,\n  CreateAutoReplyRuleParams,\n  UpdateAutoReplyRuleParams,\n} from \"../types/index\";\n\n// 获取所有规则\nexport function getAutoReplyRules(): DbAutoReplyRule[] {\n  const stmt = db.prepare(\n    \"SELECT * FROM autoreply_rules ORDER BY priority DESC, id ASC\",\n  );\n  return stmt.all() as DbAutoReplyRule[];\n}\n\n// 获取启用的规则\nexport function getEnabledAutoReplyRules(\n  accountId?: string,\n): DbAutoReplyRule[] {\n  if (accountId) {\n    const stmt = db.prepare(`\n            SELECT * FROM autoreply_rules \n            WHERE enabled = 1 AND (account_id IS NULL OR account_id = ?)\n            ORDER BY priority DESC, id ASC\n        `);\n    return stmt.all(accountId) as DbAutoReplyRule[];\n  }\n  const stmt = db.prepare(`\n        SELECT * FROM autoreply_rules \n        WHERE enabled = 1\n        ORDER BY priority DESC, id ASC\n    `);\n  return stmt.all() as DbAutoReplyRule[];\n}\n\n// 获取单个规则\nexport function getAutoReplyRule(id: number): DbAutoReplyRule | undefined {\n  const stmt = db.prepare(\"SELECT * FROM autoreply_rules WHERE id = ?\");\n  return stmt.get(id) as DbAutoReplyRule | undefined;\n}\n\n// 创建规则\nexport function createAutoReplyRule(rule: CreateAutoReplyRuleParams): number {\n  const stmt = db.prepare(`\n        INSERT INTO autoreply_rules (name, enabled, priority, match_type, match_pattern, reply_content, account_id, exclude_match)\n        VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n    `);\n  const result = stmt.run(\n    rule.name,\n    rule.enabled !== false ? 1 : 0,\n    rule.priority || 0,\n    rule.matchType,\n    rule.matchPattern,\n    rule.replyContent,\n    rule.accountId || null,\n    rule.excludeMatch ? 1 : 0,\n  );\n  return result.lastInsertRowid as number;\n}\n\n// 更新规则\nexport function updateAutoReplyRule(\n  id: number,\n  rule: UpdateAutoReplyRuleParams,\n): boolean {\n  const existing = getAutoReplyRule(id);\n  if (!existing) return false;\n\n  const stmt = db.prepare(`\n        UPDATE autoreply_rules SET\n            name = ?, enabled = ?, priority = ?, match_type = ?,\n            match_pattern = ?, reply_content = ?, account_id = ?, exclude_match = ?,\n            updated_at = CURRENT_TIMESTAMP\n        WHERE id = ?\n    `);\n  stmt.run(\n    rule.name ?? existing.name,\n    rule.enabled !== undefined ? (rule.enabled ? 1 : 0) : existing.enabled,\n    rule.priority ?? existing.priority,\n    rule.matchType ?? existing.match_type,\n    rule.matchPattern ?? existing.match_pattern,\n    rule.replyContent ?? existing.reply_content,\n    rule.accountId !== undefined ? rule.accountId : existing.account_id,\n    rule.excludeMatch !== undefined\n      ? rule.excludeMatch\n        ? 1\n        : 0\n      : existing.exclude_match || 0,\n    id,\n  );\n  return true;\n}\n\n// 删除规则\nexport function deleteAutoReplyRule(id: number): boolean {\n  const stmt = db.prepare(\"DELETE FROM autoreply_rules WHERE id = ?\");\n  const result = stmt.run(id);\n  return result.changes > 0;\n}\n\n// 切换规则启用状态\nexport function toggleAutoReplyRule(id: number): boolean {\n  const stmt = db.prepare(\n    \"UPDATE autoreply_rules SET enabled = 1 - enabled, updated_at = CURRENT_TIMESTAMP WHERE id = ?\",\n  );\n  const result = stmt.run(id);\n  return result.changes > 0;\n}\n"
  },
  {
    "path": "src/goofish/db/autosell.repository.ts",
    "content": "/**\n * 自动发货数据仓库\n */\n\nimport { db } from \"./connection\";\nimport type {\n  DbAutoSellRule,\n  DbStockItem,\n  DbDeliveryLog,\n  CreateAutoSellRuleParams,\n  UpdateAutoSellRuleParams,\n  AutoSellRule,\n  StockItem,\n  DeliveryLog,\n} from \"../types/index\";\n\n// ========== 规则管理 ==========\n\n// 转换数据库规则到业务对象\nfunction toRule(row: any): AutoSellRule {\n  return {\n    id: row.id,\n    name: row.name,\n    enabled: row.enabled === 1,\n    itemId: row.item_id,\n    accountId: row.account_id,\n    deliveryType: row.delivery_type,\n    deliveryContent: row.delivery_content,\n    apiConfig: row.api_config ? JSON.parse(row.api_config) : null,\n    triggerOn: row.trigger_on,\n    workflowId: row.workflow_id || null,\n    createdAt: row.created_at,\n    updatedAt: row.updated_at,\n  };\n}\n\n// 获取所有规则\nexport function getAutoSellRules(): AutoSellRule[] {\n  const stmt = db.prepare(\"SELECT * FROM autosell_rules ORDER BY id DESC\");\n  const rows = stmt.all() as DbAutoSellRule[];\n  return rows.map(toRule);\n}\n\n// 获取启用的规则\nexport function getEnabledAutoSellRules(\n  accountId?: string,\n  itemId?: string,\n): AutoSellRule[] {\n  let sql = \"SELECT * FROM autosell_rules WHERE enabled = 1\";\n  const params: any[] = [];\n\n  if (accountId) {\n    sql += \" AND (account_id IS NULL OR account_id = ?)\";\n    params.push(accountId);\n  }\n  if (itemId) {\n    sql += \" AND (item_id IS NULL OR item_id = ?)\";\n    params.push(itemId);\n  }\n\n  sql += \" ORDER BY id ASC\";\n  const stmt = db.prepare(sql);\n  const rows = stmt.all(...params) as DbAutoSellRule[];\n  return rows.map(toRule);\n}\n\n// 获取单个规则\nexport function getAutoSellRule(id: number): AutoSellRule | undefined {\n  const stmt = db.prepare(\"SELECT * FROM autosell_rules WHERE id = ?\");\n  const row = stmt.get(id) as DbAutoSellRule | undefined;\n  return row ? toRule(row) : undefined;\n}\n\n// 创建规则\nexport function createAutoSellRule(rule: CreateAutoSellRuleParams): number {\n  const stmt = db.prepare(`\n        INSERT INTO autosell_rules (name, enabled, item_id, account_id, delivery_type, delivery_content, api_config, trigger_on, workflow_id)\n        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n    `);\n  const result = stmt.run(\n    rule.name,\n    rule.enabled !== false ? 1 : 0,\n    rule.itemId || null,\n    rule.accountId || null,\n    rule.deliveryType,\n    rule.deliveryContent || null,\n    rule.apiConfig ? JSON.stringify(rule.apiConfig) : null,\n    rule.triggerOn || \"paid\",\n    rule.workflowId || null,\n  );\n  return result.lastInsertRowid as number;\n}\n\n// 更新规则\nexport function updateAutoSellRule(\n  id: number,\n  rule: UpdateAutoSellRuleParams,\n): boolean {\n  const existing = getAutoSellRule(id);\n  if (!existing) return false;\n\n  const stmt = db.prepare(`\n        UPDATE autosell_rules SET\n            name = ?, enabled = ?, item_id = ?, account_id = ?,\n            delivery_type = ?, delivery_content = ?, api_config = ?, trigger_on = ?, workflow_id = ?,\n            updated_at = CURRENT_TIMESTAMP\n        WHERE id = ?\n    `);\n  stmt.run(\n    rule.name ?? existing.name,\n    rule.enabled !== undefined\n      ? rule.enabled\n        ? 1\n        : 0\n      : existing.enabled\n        ? 1\n        : 0,\n    rule.itemId !== undefined ? rule.itemId : existing.itemId,\n    rule.accountId !== undefined ? rule.accountId : existing.accountId,\n    rule.deliveryType ?? existing.deliveryType,\n    rule.deliveryContent !== undefined\n      ? rule.deliveryContent\n      : existing.deliveryContent,\n    rule.apiConfig !== undefined\n      ? rule.apiConfig\n        ? JSON.stringify(rule.apiConfig)\n        : null\n      : existing.apiConfig\n        ? JSON.stringify(existing.apiConfig)\n        : null,\n    rule.triggerOn ?? existing.triggerOn,\n    rule.workflowId !== undefined ? rule.workflowId : existing.workflowId,\n    id,\n  );\n  return true;\n}\n\n// 删除规则\nexport function deleteAutoSellRule(id: number): boolean {\n  const stmt = db.prepare(\"DELETE FROM autosell_rules WHERE id = ?\");\n  const result = stmt.run(id);\n  return result.changes > 0;\n}\n\n// 切换规则启用状态\nexport function toggleAutoSellRule(id: number): boolean {\n  const stmt = db.prepare(\n    \"UPDATE autosell_rules SET enabled = 1 - enabled, updated_at = CURRENT_TIMESTAMP WHERE id = ?\",\n  );\n  const result = stmt.run(id);\n  return result.changes > 0;\n}\n\n// ========== 库存管理 ==========\n\n// 转换库存项\nfunction toStockItem(row: DbStockItem): StockItem {\n  return {\n    id: row.id,\n    ruleId: row.rule_id,\n    content: row.content,\n    used: row.used === 1,\n    usedOrderId: row.used_order_id,\n    createdAt: row.created_at,\n    usedAt: row.used_at,\n  };\n}\n\n// 获取规则的库存\nexport function getStockItems(\n  ruleId: number,\n  includeUsed = false,\n): StockItem[] {\n  const sql = includeUsed\n    ? \"SELECT * FROM autosell_stock WHERE rule_id = ? ORDER BY id ASC\"\n    : \"SELECT * FROM autosell_stock WHERE rule_id = ? AND used = 0 ORDER BY id ASC\";\n  const stmt = db.prepare(sql);\n  const rows = stmt.all(ruleId) as DbStockItem[];\n  return rows.map(toStockItem);\n}\n\n// 获取库存统计\nexport function getStockStats(ruleId: number): {\n  total: number;\n  used: number;\n  available: number;\n} {\n  const stmt = db.prepare(`\n        SELECT \n            COUNT(*) as total,\n            SUM(CASE WHEN used = 1 THEN 1 ELSE 0 END) as used\n        FROM autosell_stock WHERE rule_id = ?\n    `);\n  const row = stmt.get(ruleId) as { total: number; used: number };\n  return {\n    total: row.total,\n    used: row.used || 0,\n    available: row.total - (row.used || 0),\n  };\n}\n\n// 添加库存\nexport function addStockItems(ruleId: number, contents: string[]): number {\n  const stmt = db.prepare(\n    \"INSERT INTO autosell_stock (rule_id, content) VALUES (?, ?)\",\n  );\n  const insertMany = db.transaction((items: string[]) => {\n    for (const content of items) {\n      stmt.run(ruleId, content);\n    }\n    return items.length;\n  });\n  return insertMany(contents);\n}\n\n// 取出一个库存（标记为已使用）\nexport function consumeStock(\n  ruleId: number,\n  orderId: string,\n): StockItem | null {\n  const selectStmt = db.prepare(\n    \"SELECT * FROM autosell_stock WHERE rule_id = ? AND used = 0 ORDER BY id ASC LIMIT 1\",\n  );\n  const row = selectStmt.get(ruleId) as DbStockItem | undefined;\n  if (!row) return null;\n\n  const updateStmt = db.prepare(\n    \"UPDATE autosell_stock SET used = 1, used_order_id = ?, used_at = CURRENT_TIMESTAMP WHERE id = ?\",\n  );\n  updateStmt.run(orderId, row.id);\n\n  return toStockItem({ ...row, used: 1, used_order_id: orderId });\n}\n\n// 清空规则库存\nexport function clearStock(ruleId: number, onlyUsed = false): number {\n  const sql = onlyUsed\n    ? \"DELETE FROM autosell_stock WHERE rule_id = ? AND used = 1\"\n    : \"DELETE FROM autosell_stock WHERE rule_id = ?\";\n  const stmt = db.prepare(sql);\n  const result = stmt.run(ruleId);\n  return result.changes;\n}\n\n// ========== 发货记录 ==========\n\n// 转换发货记录\nfunction toDeliveryLog(row: DbDeliveryLog): DeliveryLog {\n  return {\n    id: row.id,\n    ruleId: row.rule_id,\n    orderId: row.order_id,\n    accountId: row.account_id,\n    deliveryType: row.delivery_type,\n    content: row.content,\n    status: row.status as \"success\" | \"failed\",\n    errorMessage: row.error_message,\n    createdAt: row.created_at,\n  };\n}\n\n// 添加发货记录\nexport function addDeliveryLog(log: {\n  ruleId?: number | null;\n  orderId: string;\n  accountId: string;\n  deliveryType: string;\n  content: string;\n  status: \"success\" | \"failed\";\n  errorMessage?: string | null;\n}): number {\n  const stmt = db.prepare(`\n        INSERT INTO autosell_logs (rule_id, order_id, account_id, delivery_type, content, status, error_message)\n        VALUES (?, ?, ?, ?, ?, ?, ?)\n    `);\n  const result = stmt.run(\n    log.ruleId || null,\n    log.orderId,\n    log.accountId,\n    log.deliveryType,\n    log.content,\n    log.status,\n    log.errorMessage || null,\n  );\n  return result.lastInsertRowid as number;\n}\n\n// 获取发货记录\nexport function getDeliveryLogs(params: {\n  ruleId?: number;\n  orderId?: string;\n  accountId?: string;\n  limit?: number;\n  offset?: number;\n}): { logs: DeliveryLog[]; total: number } {\n  let whereClauses: string[] = [];\n  const queryParams: any[] = [];\n\n  if (params.ruleId) {\n    whereClauses.push(\"rule_id = ?\");\n    queryParams.push(params.ruleId);\n  }\n  if (params.orderId) {\n    whereClauses.push(\"order_id = ?\");\n    queryParams.push(params.orderId);\n  }\n  if (params.accountId) {\n    whereClauses.push(\"account_id = ?\");\n    queryParams.push(params.accountId);\n  }\n\n  const whereClause =\n    whereClauses.length > 0 ? `WHERE ${whereClauses.join(\" AND \")}` : \"\";\n\n  const countStmt = db.prepare(\n    `SELECT COUNT(*) as total FROM autosell_logs ${whereClause}`,\n  );\n  const { total } = countStmt.get(...queryParams) as { total: number };\n\n  const limit = params.limit || 50;\n  const offset = params.offset || 0;\n  const dataStmt = db.prepare(\n    `SELECT * FROM autosell_logs ${whereClause} ORDER BY id DESC LIMIT ? OFFSET ?`,\n  );\n  const rows = dataStmt.all(...queryParams, limit, offset) as DbDeliveryLog[];\n\n  return { logs: rows.map(toDeliveryLog), total };\n}\n\n// 检查订单是否已发货\nexport function hasDelivered(orderId: string): boolean {\n  const stmt = db.prepare(\n    \"SELECT id FROM autosell_logs WHERE order_id = ? AND status = ? LIMIT 1\",\n  );\n  const row = stmt.get(orderId, \"success\");\n  return !!row;\n}\n"
  },
  {
    "path": "src/goofish/db/connection.ts",
    "content": "/**\n * 数据库连接管理\n */\n\nimport Database from \"better-sqlite3\";\nimport path from \"path\";\nimport fs from \"fs\";\n\nimport { DB_CONFIG } from \"../core/constants\";\nimport { createLogger } from \"../core/logger\";\n\nconst logger = createLogger(\"Db\");\n\n// 确保数据目录存在\nconst dbDir = path.join(process.cwd(), \"data\");\nif (!fs.existsSync(dbDir)) {\n  fs.mkdirSync(dbDir, { recursive: true });\n}\n\nconst dbPath = path.join(process.cwd(), DB_CONFIG.PATH);\nexport const db = new Database(dbPath);\n\n// 启用 WAL 模式提高并发性能\ndb.pragma(\"journal_mode = WAL\");\n\nexport function closeDatabase() {\n  db.close();\n  logger.info(\"数据库连接已关闭\");\n}\n\nexport function getDbPath(): string {\n  return dbPath;\n}\n"
  },
  {
    "path": "src/goofish/db/conversation.repository.ts",
    "content": "/**\n * 对话数据仓库\n */\n\nimport { db } from \"./connection\";\nimport { emitConversationsUpdated } from \"../core/event-emitter\";\nimport type {\n  DbConversation,\n  DbConversationMessage,\n  UpsertConversationParams,\n  AddConversationMessageParams,\n} from \"../types/index\";\n\n// 获取对话列表（分页）\nexport function getConversations(limit = 20, offset = 0): DbConversation[] {\n  const stmt = db.prepare(`\n        SELECT account_id, chat_id, user_id, user_name, user_avatar, last_message, last_time, unread\n        FROM conversations ORDER BY last_time DESC LIMIT ? OFFSET ?\n    `);\n  return stmt.all(limit, offset) as DbConversation[];\n}\n\n// 获取对话总数\nexport function getConversationCount(): number {\n  const stmt = db.prepare(\"SELECT COUNT(*) as count FROM conversations\");\n  return (stmt.get() as { count: number }).count;\n}\n\n// 获取单个对话\nexport function getConversation(\n  accountId: string,\n  chatId: string,\n): DbConversation | undefined {\n  const stmt = db.prepare(\n    \"SELECT * FROM conversations WHERE account_id = ? AND chat_id = ?\",\n  );\n  return stmt.get(accountId, chatId) as DbConversation | undefined;\n}\n\n// 创建或更新对话（不触发事件，由调用方统一触发）\nexport function upsertConversation(\n  conv: UpsertConversationParams,\n  emitEvent = true,\n) {\n  const existing = getConversation(conv.accountId, conv.chatId);\n  if (existing) {\n    const stmt = db.prepare(`\n            UPDATE conversations SET\n                user_name = ?, user_avatar = COALESCE(?, user_avatar),\n                last_message = ?, last_time = ?, unread = unread + ?,\n                updated_at = CURRENT_TIMESTAMP\n            WHERE account_id = ? AND chat_id = ?\n        `);\n    stmt.run(\n      conv.userName,\n      conv.userAvatar,\n      conv.lastMessage,\n      conv.lastTime,\n      conv.unread || 0,\n      conv.accountId,\n      conv.chatId,\n    );\n  } else {\n    const stmt = db.prepare(`\n            INSERT INTO conversations (account_id, chat_id, user_id, user_name, user_avatar, last_message, last_time, unread)\n            VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n        `);\n    stmt.run(\n      conv.accountId,\n      conv.chatId,\n      conv.userId,\n      conv.userName,\n      conv.userAvatar || null,\n      conv.lastMessage,\n      conv.lastTime,\n      conv.unread || 0,\n    );\n  }\n  if (emitEvent) {\n    emitConversationsUpdated();\n  }\n}\n\n// 更新用户头像\nexport function updateConversationAvatar(\n  accountId: string,\n  chatId: string,\n  avatar: string,\n) {\n  const stmt = db.prepare(\n    \"UPDATE conversations SET user_avatar = ? WHERE account_id = ? AND chat_id = ?\",\n  );\n  stmt.run(avatar, accountId, chatId);\n}\n\n// 标记已读\nexport function markConversationRead(accountId: string, chatId: string) {\n  const stmt = db.prepare(\n    \"UPDATE conversations SET unread = 0 WHERE account_id = ? AND chat_id = ?\",\n  );\n  stmt.run(accountId, chatId);\n  emitConversationsUpdated();\n}\n\n// 获取对话消息（分页）\nexport function getConversationMessages(\n  accountId: string,\n  chatId: string,\n  limit = 50,\n  beforeId?: number,\n): DbConversationMessage[] {\n  if (beforeId) {\n    const stmt = db.prepare(`\n            SELECT * FROM conversation_messages\n            WHERE account_id = ? AND chat_id = ? AND id < ?\n            ORDER BY created_at DESC LIMIT ?\n        `);\n    return (\n      stmt.all(accountId, chatId, beforeId, limit) as DbConversationMessage[]\n    ).reverse();\n  }\n  const stmt = db.prepare(`\n        SELECT * FROM conversation_messages\n        WHERE account_id = ? AND chat_id = ?\n        ORDER BY created_at DESC LIMIT ?\n    `);\n  return (\n    stmt.all(accountId, chatId, limit) as DbConversationMessage[]\n  ).reverse();\n}\n\n// 获取对话消息总数\nexport function getConversationMessageCount(\n  accountId: string,\n  chatId: string,\n): number {\n  const stmt = db.prepare(\n    \"SELECT COUNT(*) as count FROM conversation_messages WHERE account_id = ? AND chat_id = ?\",\n  );\n  return (stmt.get(accountId, chatId) as { count: number }).count;\n}\n\n// 获取所有消息总数\nexport function getAllMessagesCount(): number {\n  const stmt = db.prepare(\n    \"SELECT COUNT(*) as count FROM conversation_messages\",\n  );\n  return (stmt.get() as { count: number }).count;\n}\n\n// 添加消息\nexport function addConversationMessage(\n  msg: AddConversationMessageParams,\n): number {\n  const stmt = db.prepare(`\n        INSERT INTO conversation_messages (account_id, chat_id, sender_id, sender_name, content, msg_time, msg_id, direction, created_at)\n        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n    `);\n  const result = stmt.run(\n    msg.accountId,\n    msg.chatId,\n    msg.senderId,\n    msg.senderName,\n    msg.content,\n    msg.msgTime,\n    msg.msgId || null,\n    msg.direction,\n    Date.now(),\n  );\n  emitConversationsUpdated();\n  return result.lastInsertRowid as number;\n}\n"
  },
  {
    "path": "src/goofish/db/index.ts",
    "content": "/**\n * 数据库模块统一导出\n */\n\nimport { db, closeDatabase, getDbPath } from \"./connection\";\nimport { runMigrations } from \"./migrations\";\nimport { createLogger } from \"../core/logger\";\n\nconst logger = createLogger(\"Db\");\n\n// 初始化数据库\nexport function initDatabase() {\n  logger.info(`初始化数据库: ${getDbPath()}`);\n  runMigrations();\n  logger.info(\"数据库初始化完成\");\n}\n\n// 导出连接\nexport { db, closeDatabase };\n\n// 导出仓库函数\nexport {\n  getEnabledAccounts,\n  getAllAccounts,\n  getAccount,\n  upsertAccount,\n  updateAccountUserInfo,\n  updateAccountCookies,\n  updateAccountEnabled,\n  deleteAccount,\n  updateAccountStatus,\n  getAccountStatus,\n} from \"./account.repository\";\n\nexport {\n  getConversations,\n  getConversationCount,\n  getConversation,\n  upsertConversation,\n  updateConversationAvatar,\n  markConversationRead,\n  getConversationMessages,\n  getConversationMessageCount,\n  addConversationMessage,\n} from \"./conversation.repository\";\n\nexport {\n  getAutoReplyRules,\n  getEnabledAutoReplyRules,\n  getAutoReplyRule,\n  createAutoReplyRule,\n  updateAutoReplyRule,\n  deleteAutoReplyRule,\n  toggleAutoReplyRule,\n} from \"./autoreply.repository\";\n\nexport {\n  getUserAvatar,\n  saveUserAvatar,\n  hasUserAvatar,\n} from \"./user-avatar.repository\";\n\nexport {\n  getOrders,\n  getOrderCount,\n  getOrderById,\n  upsertOrder,\n  updateOrderStatus,\n  deleteOrder,\n} from \"./order.repository\";\n\nexport {\n  getSetting,\n  setSetting,\n  deleteSetting,\n  getSettings,\n  getAISettings,\n  saveAISettings,\n  AI_SETTINGS_KEYS,\n} from \"./settings.repository\";\n\nexport {\n  getAutoSellRules,\n  getEnabledAutoSellRules,\n  getAutoSellRule,\n  createAutoSellRule,\n  updateAutoSellRule,\n  deleteAutoSellRule,\n  toggleAutoSellRule,\n  getStockItems,\n  getStockStats,\n  addStockItems,\n  consumeStock,\n  clearStock,\n  addDeliveryLog,\n  getDeliveryLogs,\n  hasDelivered,\n} from \"./autosell.repository\";\n\nexport {\n  getWorkflows,\n  getWorkflowById,\n  getDefaultWorkflow,\n  createWorkflow,\n  updateWorkflow,\n  deleteWorkflow,\n  createWorkflowExecution,\n  getWorkflowExecution,\n  getWorkflowExecutionByOrderId,\n  getWaitingExecutions,\n  updateWorkflowExecution,\n} from \"./workflow.repository\";\n"
  },
  {
    "path": "src/goofish/db/migrations.ts",
    "content": "/**\n * 数据库迁移和表结构初始化\n */\n\nimport { db } from './connection'\nimport { createLogger } from '../core/logger'\n\nconst logger = createLogger('Db:Migration')\n\n// 安全添加列（如果不存在）\nfunction safeAddColumn(table: string, column: string, type: string) {\n  try {\n    db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${type}`)\n  } catch {\n    // 列已存在，忽略\n  }\n}\n\n// 创建账号相关表\nfunction createAccountTables() {\n  db.exec(`\n    CREATE TABLE IF NOT EXISTS accounts (\n      id TEXT PRIMARY KEY,\n      cookies TEXT NOT NULL,\n      user_id TEXT,\n      nickname TEXT,\n      avatar TEXT,\n      enabled INTEGER DEFAULT 1,\n      remark TEXT DEFAULT '',\n      created_at TEXT DEFAULT CURRENT_TIMESTAMP,\n      updated_at TEXT DEFAULT CURRENT_TIMESTAMP\n    )\n  `)\n\n  safeAddColumn('accounts', 'avatar', 'TEXT')\n\n  db.exec(`\n    CREATE TABLE IF NOT EXISTS account_status (\n      account_id TEXT PRIMARY KEY,\n      connected INTEGER DEFAULT 0,\n      last_heartbeat TEXT,\n      last_token_refresh TEXT,\n      error_message TEXT,\n      updated_at TEXT DEFAULT CURRENT_TIMESTAMP,\n      FOREIGN KEY (account_id) REFERENCES accounts(id) ON DELETE CASCADE\n    )\n  `)\n}\n\n// 创建消息相关表\nfunction createMessageTables() {\n  db.exec(`\n    CREATE TABLE IF NOT EXISTS messages (\n      id INTEGER PRIMARY KEY AUTOINCREMENT,\n      account_id TEXT NOT NULL,\n      chat_id TEXT,\n      sender_id TEXT,\n      sender_name TEXT,\n      content TEXT,\n      raw TEXT,\n      created_at TEXT DEFAULT CURRENT_TIMESTAMP,\n      FOREIGN KEY (account_id) REFERENCES accounts(id) ON DELETE CASCADE\n    )\n  `)\n}\n\n// 创建对话相关表\nfunction createConversationTables() {\n  db.exec(`\n    CREATE TABLE IF NOT EXISTS conversations (\n      account_id TEXT NOT NULL,\n      chat_id TEXT NOT NULL,\n      user_id TEXT NOT NULL,\n      user_name TEXT NOT NULL,\n      user_avatar TEXT,\n      last_message TEXT,\n      last_time INTEGER DEFAULT 0,\n      unread INTEGER DEFAULT 0,\n      created_at TEXT DEFAULT CURRENT_TIMESTAMP,\n      updated_at TEXT DEFAULT CURRENT_TIMESTAMP,\n      PRIMARY KEY (account_id, chat_id)\n    )\n  `)\n\n  safeAddColumn('conversations', 'account_id', \"TEXT DEFAULT ''\")\n\n  db.exec(`\n    CREATE TABLE IF NOT EXISTS conversation_messages (\n      id INTEGER PRIMARY KEY AUTOINCREMENT,\n      account_id TEXT NOT NULL,\n      chat_id TEXT NOT NULL,\n      sender_id TEXT NOT NULL,\n      sender_name TEXT NOT NULL,\n      content TEXT NOT NULL,\n      msg_time TEXT,\n      msg_id TEXT,\n      direction TEXT NOT NULL,\n      created_at INTEGER NOT NULL\n    )\n  `)\n\n  safeAddColumn('conversation_messages', 'msg_id', 'TEXT')\n  safeAddColumn('conversation_messages', 'account_id', \"TEXT DEFAULT ''\")\n\n  // 创建索引\n  db.exec(`CREATE INDEX IF NOT EXISTS idx_conv_msg_account_chat \n    ON conversation_messages(account_id, chat_id)`)\n  db.exec(`CREATE INDEX IF NOT EXISTS idx_conv_msg_created_at \n    ON conversation_messages(created_at)`)\n  db.exec(`CREATE INDEX IF NOT EXISTS idx_conversations_last_time \n    ON conversations(last_time DESC)`)\n  db.exec(`CREATE INDEX IF NOT EXISTS idx_conversations_account \n    ON conversations(account_id)`)\n}\n\n// 创建自动回复表\nfunction createAutoReplyTables() {\n  db.exec(`\n    CREATE TABLE IF NOT EXISTS autoreply_rules (\n      id INTEGER PRIMARY KEY AUTOINCREMENT,\n      name TEXT NOT NULL,\n      enabled INTEGER DEFAULT 1,\n      priority INTEGER DEFAULT 0,\n      match_type TEXT NOT NULL,\n      match_pattern TEXT NOT NULL,\n      reply_content TEXT NOT NULL,\n      account_id TEXT,\n      exclude_match INTEGER DEFAULT 0,\n      created_at TEXT DEFAULT CURRENT_TIMESTAMP,\n      updated_at TEXT DEFAULT CURRENT_TIMESTAMP\n    )\n  `)\n\n  // 添加 exclude_match 列（如果不存在）\n  safeAddColumn('autoreply_rules', 'exclude_match', 'INTEGER DEFAULT 0')\n\n  // 插入默认测试规则\n  const testRule = db.prepare(\n    'SELECT id FROM autoreply_rules WHERE match_pattern = ?'\n  ).get('123')\n\n  if (!testRule) {\n    db.prepare(`\n      INSERT INTO autoreply_rules (name, enabled, priority, match_type, match_pattern, reply_content)\n      VALUES (?, ?, ?, ?, ?, ?)\n    `).run('测试规则', 1, 100, 'exact', '123', '456')\n    logger.info('已创建默认测试自动回复规则')\n  }\n}\n\n// 创建用户头像缓存表\nfunction createUserAvatarTables() {\n  db.exec(`\n    CREATE TABLE IF NOT EXISTS user_avatars (\n      user_id TEXT PRIMARY KEY,\n      display_name TEXT,\n      avatar TEXT NOT NULL,\n      ip_location TEXT,\n      introduction TEXT,\n      created_at TEXT DEFAULT CURRENT_TIMESTAMP,\n      updated_at TEXT DEFAULT CURRENT_TIMESTAMP\n    )\n  `)\n}\n\n// 创建订单表\nfunction createOrderTables() {\n  db.exec(`\n    CREATE TABLE IF NOT EXISTS orders (\n      id INTEGER PRIMARY KEY AUTOINCREMENT,\n      order_id TEXT UNIQUE NOT NULL,\n      account_id TEXT NOT NULL,\n      item_id TEXT,\n      item_title TEXT,\n      item_pic_url TEXT,\n      price TEXT,\n      buyer_user_id TEXT,\n      buyer_nickname TEXT,\n      chat_id TEXT,\n      status INTEGER DEFAULT 0,\n      status_text TEXT,\n      order_time TEXT,\n      pay_time TEXT,\n      ship_time TEXT,\n      complete_time TEXT,\n      created_at TEXT DEFAULT CURRENT_TIMESTAMP,\n      updated_at TEXT DEFAULT CURRENT_TIMESTAMP,\n      FOREIGN KEY (account_id) REFERENCES accounts(id) ON DELETE CASCADE\n    )\n  `)\n\n  // 添加 chat_id 列（如果不存在）\n  safeAddColumn('orders', 'chat_id', 'TEXT')\n\n  // 创建索引\n  db.exec(`CREATE INDEX IF NOT EXISTS idx_orders_account \n    ON orders(account_id)`)\n  db.exec(`CREATE INDEX IF NOT EXISTS idx_orders_status \n    ON orders(status)`)\n  db.exec(`CREATE INDEX IF NOT EXISTS idx_orders_updated \n    ON orders(updated_at DESC)`)\n}\n\n// 创建系统设置表\nfunction createSettingsTables() {\n  db.exec(`\n    CREATE TABLE IF NOT EXISTS settings (\n      key TEXT PRIMARY KEY,\n      value TEXT NOT NULL,\n      updated_at TEXT DEFAULT CURRENT_TIMESTAMP\n    )\n  `)\n}\n\n// 创建 ChattyPlay 用户表\nfunction createChattyplayUserTables() {\n  db.exec(`\n    CREATE TABLE IF NOT EXISTS chattyplay_user (\n      id INTEGER PRIMARY KEY AUTOINCREMENT,\n      username TEXT UNIQUE NOT NULL,\n      password TEXT NOT NULL,\n      email TEXT UNIQUE,\n      avatar TEXT,\n      created_at TEXT DEFAULT CURRENT_TIMESTAMP,\n      updated_at TEXT DEFAULT CURRENT_TIMESTAMP,\n      last_login TEXT\n    )\n  `)\n\n  // 创建索引\n  db.exec(`CREATE INDEX IF NOT EXISTS idx_chattyplay_user_username\n    ON chattyplay_user(username)`)\n  db.exec(`CREATE INDEX IF NOT EXISTS idx_chattyplay_user_email\n    ON chattyplay_user(email)`)\n}\n\n// 创建自动发货表\nfunction createAutoSellTables() {\n  db.exec(`\n    CREATE TABLE IF NOT EXISTS autosell_rules (\n      id INTEGER PRIMARY KEY AUTOINCREMENT,\n      name TEXT NOT NULL,\n      enabled INTEGER DEFAULT 1,\n      item_id TEXT,\n      account_id TEXT,\n      delivery_type TEXT NOT NULL,\n      delivery_content TEXT,\n      api_config TEXT,\n      trigger_on TEXT DEFAULT 'paid',\n      workflow_id INTEGER,\n      created_at TEXT DEFAULT CURRENT_TIMESTAMP,\n      updated_at TEXT DEFAULT CURRENT_TIMESTAMP\n    )\n  `)\n\n  safeAddColumn('autosell_rules', 'workflow_id', 'INTEGER')\n\n  db.exec(`\n    CREATE TABLE IF NOT EXISTS autosell_stock (\n      id INTEGER PRIMARY KEY AUTOINCREMENT,\n      rule_id INTEGER NOT NULL,\n      content TEXT NOT NULL,\n      used INTEGER DEFAULT 0,\n      used_order_id TEXT,\n      created_at TEXT DEFAULT CURRENT_TIMESTAMP,\n      used_at TEXT,\n      FOREIGN KEY (rule_id) REFERENCES autosell_rules(id) ON DELETE CASCADE\n    )\n  `)\n\n  db.exec(`\n    CREATE TABLE IF NOT EXISTS autosell_logs (\n      id INTEGER PRIMARY KEY AUTOINCREMENT,\n      rule_id INTEGER,\n      order_id TEXT NOT NULL,\n      account_id TEXT NOT NULL,\n      delivery_type TEXT NOT NULL,\n      content TEXT NOT NULL,\n      status TEXT DEFAULT 'success',\n      error_message TEXT,\n      created_at TEXT DEFAULT CURRENT_TIMESTAMP\n    )\n  `)\n\n  // 创建索引\n  db.exec(`CREATE INDEX IF NOT EXISTS idx_autosell_stock_rule \n    ON autosell_stock(rule_id, used)`)\n  db.exec(`CREATE INDEX IF NOT EXISTS idx_autosell_logs_order \n    ON autosell_logs(order_id)`)\n}\n\n// 创建发货流程表\nfunction createWorkflowTables() {\n  db.exec(`\n    CREATE TABLE IF NOT EXISTS workflows (\n      id INTEGER PRIMARY KEY AUTOINCREMENT,\n      name TEXT NOT NULL,\n      description TEXT,\n      definition TEXT NOT NULL,\n      is_default INTEGER DEFAULT 0,\n      enabled INTEGER DEFAULT 1,\n      created_at TEXT DEFAULT CURRENT_TIMESTAMP,\n      updated_at TEXT DEFAULT CURRENT_TIMESTAMP\n    )\n  `)\n\n  db.exec(`\n    CREATE TABLE IF NOT EXISTS workflow_executions (\n      id INTEGER PRIMARY KEY AUTOINCREMENT,\n      workflow_id INTEGER NOT NULL,\n      order_id TEXT NOT NULL,\n      account_id TEXT NOT NULL,\n      rule_id INTEGER NOT NULL,\n      status TEXT DEFAULT 'pending',\n      current_node_id TEXT,\n      waiting_for_reply INTEGER DEFAULT 0,\n      expected_keywords TEXT,\n      context TEXT DEFAULT '{}',\n      created_at TEXT DEFAULT CURRENT_TIMESTAMP,\n      updated_at TEXT DEFAULT CURRENT_TIMESTAMP,\n      FOREIGN KEY (workflow_id) REFERENCES workflows(id) ON DELETE CASCADE\n    )\n  `)\n\n  // 创建索引\n  db.exec(`CREATE INDEX IF NOT EXISTS idx_workflow_exec_order \n    ON workflow_executions(order_id)`)\n  db.exec(`CREATE INDEX IF NOT EXISTS idx_workflow_exec_waiting \n    ON workflow_executions(account_id, waiting_for_reply, status)`)\n\n  // 插入默认流程\n  const defaultWorkflow = db.prepare(\n    'SELECT id FROM workflows WHERE is_default = 1'\n  ).get()\n\n  if (!defaultWorkflow) {\n    const defaultDef = JSON.stringify({\n      nodes: [\n        { id: 'trigger', type: 'trigger', name: '触发', config: {}, posX: 100, posY: 200 },\n        { id: 'delivery', type: 'delivery', name: '发货', config: {}, posX: 350, posY: 200 },\n        { id: 'ship', type: 'ship', name: '标记发货', config: {}, posX: 600, posY: 200 }\n      ],\n      connections: [\n        { fromNode: 'trigger', fromOutput: 'output_1', toNode: 'delivery', toInput: 'input_1' },\n        { fromNode: 'delivery', fromOutput: 'output_1', toNode: 'ship', toInput: 'input_1' }\n      ]\n    })\n    db.prepare(`\n      INSERT INTO workflows (name, description, definition, is_default, enabled)\n      VALUES (?, ?, ?, 1, 1)\n    `).run('默认流程', '触发 → 发货 → 标记发货', defaultDef)\n    logger.info('已创建默认发货流程')\n  }\n}\n\nexport function runMigrations() {\n  logger.info('开始数据库迁移...')\n\n  createAccountTables()\n  createMessageTables()\n  createConversationTables()\n  createAutoReplyTables()\n  createUserAvatarTables()\n  createOrderTables()\n  createSettingsTables()\n  createChattyplayUserTables()\n  createAutoSellTables()\n  createWorkflowTables()\n\n  logger.info('数据库迁移完成')\n}\n"
  },
  {
    "path": "src/goofish/db/order.repository.ts",
    "content": "/**\n * 订单数据仓库\n */\n\nimport { db } from \"./connection\";\nimport { nowLocalString } from \"../utils/date\";\nimport { emitOrdersUpdated } from \"../core/event-emitter\";\nimport type { OrderRecord, OrderListParams } from \"../types/order.types\";\n\n// 获取订单列表\nexport function getOrders(params: OrderListParams = {}): OrderRecord[] {\n  const { accountId, status, limit = 50, offset = 0 } = params;\n\n  let sql = \"SELECT * FROM orders WHERE 1=1\";\n  const sqlParams: any[] = [];\n\n  if (accountId) {\n    sql += \" AND account_id = ?\";\n    sqlParams.push(accountId);\n  }\n\n  if (status !== undefined) {\n    sql += \" AND status = ?\";\n    sqlParams.push(status);\n  }\n\n  sql += \" ORDER BY updated_at DESC LIMIT ? OFFSET ?\";\n  sqlParams.push(limit, offset);\n\n  const rows = db.prepare(sql).all(...sqlParams) as any[];\n  return rows.map(mapRowToOrder);\n}\n\n// 获取订单总数\nexport function getOrderCount(params: OrderListParams = {}): number {\n  const { accountId, status } = params;\n\n  let sql = \"SELECT COUNT(*) as count FROM orders WHERE 1=1\";\n  const sqlParams: any[] = [];\n\n  if (accountId) {\n    sql += \" AND account_id = ?\";\n    sqlParams.push(accountId);\n  }\n\n  if (status !== undefined) {\n    sql += \" AND status = ?\";\n    sqlParams.push(status);\n  }\n\n  const row = db.prepare(sql).get(...sqlParams) as { count: number };\n  return row.count;\n}\n\n// 根据订单 ID 获取订单\nexport function getOrderById(orderId: string): OrderRecord | null {\n  const row = db\n    .prepare(\"SELECT * FROM orders WHERE order_id = ?\")\n    .get(orderId) as any;\n\n  return row ? mapRowToOrder(row) : null;\n}\n\n// 创建或更新订单\nexport function upsertOrder(\n  order: Partial<OrderRecord> & { orderId: string; accountId: string },\n): void {\n  const now = nowLocalString();\n\n  db.prepare(\n    `\n        INSERT INTO orders (\n            order_id, account_id, item_id, item_title, item_pic_url,\n            price, buyer_user_id, buyer_nickname, chat_id, status, status_text,\n            order_time, pay_time, ship_time, complete_time, created_at, updated_at\n        ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n        ON CONFLICT(order_id) DO UPDATE SET\n            item_id = COALESCE(excluded.item_id, item_id),\n            item_title = COALESCE(excluded.item_title, item_title),\n            item_pic_url = COALESCE(excluded.item_pic_url, item_pic_url),\n            price = COALESCE(excluded.price, price),\n            buyer_user_id = COALESCE(excluded.buyer_user_id, buyer_user_id),\n            buyer_nickname = COALESCE(excluded.buyer_nickname, buyer_nickname),\n            chat_id = COALESCE(excluded.chat_id, chat_id),\n            status = COALESCE(excluded.status, status),\n            status_text = COALESCE(excluded.status_text, status_text),\n            order_time = COALESCE(excluded.order_time, order_time),\n            pay_time = COALESCE(excluded.pay_time, pay_time),\n            ship_time = COALESCE(excluded.ship_time, ship_time),\n            complete_time = COALESCE(excluded.complete_time, complete_time),\n            updated_at = excluded.updated_at\n    `,\n  ).run(\n    order.orderId,\n    order.accountId,\n    order.itemId || null,\n    order.itemTitle || null,\n    order.itemPicUrl || null,\n    order.price || null,\n    order.buyerUserId || null,\n    order.buyerNickname || null,\n    order.chatId || null,\n    order.status || 1,\n    order.statusText || null,\n    order.orderTime || now,\n    order.payTime || null,\n    order.shipTime || null,\n    order.completeTime || null,\n    now,\n    now,\n  );\n\n  emitOrdersUpdated();\n}\n\n// 更新订单状态\nexport function updateOrderStatus(\n  orderId: string,\n  status: number,\n  statusText: string,\n  timeField?: \"pay_time\" | \"ship_time\" | \"complete_time\",\n): void {\n  const now = nowLocalString();\n\n  let sql = \"UPDATE orders SET status = ?, status_text = ?, updated_at = ?\";\n  const params: any[] = [status, statusText, now];\n\n  if (timeField) {\n    sql += `, ${timeField} = ?`;\n    params.push(now);\n  }\n\n  sql += \" WHERE order_id = ?\";\n  params.push(orderId);\n\n  db.prepare(sql).run(...params);\n  emitOrdersUpdated();\n}\n\n// 删除订单\nexport function deleteOrder(orderId: string): boolean {\n  const result = db\n    .prepare(\"DELETE FROM orders WHERE order_id = ?\")\n    .run(orderId);\n  if (result.changes > 0) {\n    emitOrdersUpdated();\n  }\n  return result.changes > 0;\n}\n\n// 行数据映射\nfunction mapRowToOrder(row: any): OrderRecord {\n  return {\n    id: row.id,\n    orderId: row.order_id,\n    accountId: row.account_id,\n    itemId: row.item_id,\n    itemTitle: row.item_title,\n    itemPicUrl: row.item_pic_url,\n    price: row.price,\n    buyerUserId: row.buyer_user_id,\n    buyerNickname: row.buyer_nickname,\n    chatId: row.chat_id,\n    status: row.status,\n    statusText: row.status_text,\n    orderTime: row.order_time,\n    payTime: row.pay_time,\n    shipTime: row.ship_time,\n    completeTime: row.complete_time,\n    createdAt: row.created_at,\n    updatedAt: row.updated_at,\n  };\n}\n"
  },
  {
    "path": "src/goofish/db/settings.repository.ts",
    "content": "/**\n * 系统设置数据仓库\n */\n\nimport { db } from \"./connection\";\n\ninterface DbSetting {\n  key: string;\n  value: string;\n  updated_at: string;\n}\n\n// 获取设置值\nexport function getSetting(key: string): string | null {\n  const stmt = db.prepare(\"SELECT value FROM settings WHERE key = ?\");\n  const row = stmt.get(key) as DbSetting | undefined;\n  return row?.value ?? null;\n}\n\n// 设置值\nexport function setSetting(key: string, value: string): void {\n  const stmt = db.prepare(`\n    INSERT INTO settings (key, value, updated_at) VALUES (?, ?, CURRENT_TIMESTAMP)\n    ON CONFLICT(key) DO UPDATE SET value = ?, updated_at = CURRENT_TIMESTAMP\n  `);\n  stmt.run(key, value, value);\n}\n\n// 删除设置\nexport function deleteSetting(key: string): boolean {\n  const stmt = db.prepare(\"DELETE FROM settings WHERE key = ?\");\n  const result = stmt.run(key);\n  return result.changes > 0;\n}\n\n// 获取多个设置\nexport function getSettings(keys: string[]): Record<string, string | null> {\n  const result: Record<string, string | null> = {};\n  for (const key of keys) {\n    result[key] = getSetting(key);\n  }\n  return result;\n}\n\n// AI 设置相关 key\nexport const AI_SETTINGS_KEYS = {\n  BASE_URL: \"ai_base_url\",\n  API_KEY: \"ai_api_key\",\n  MODEL: \"ai_model\",\n  SYSTEM_PROMPT: \"ai_system_prompt\",\n};\n\n// 获取 AI 设置\nexport function getAISettings() {\n  return {\n    baseUrl: getSetting(AI_SETTINGS_KEYS.BASE_URL) || \"\",\n    apiKey: getSetting(AI_SETTINGS_KEYS.API_KEY) || \"\",\n    model: getSetting(AI_SETTINGS_KEYS.MODEL) || \"gpt-3.5-turbo\",\n    systemPrompt: getSetting(AI_SETTINGS_KEYS.SYSTEM_PROMPT) || \"\",\n  };\n}\n\n// 保存 AI 设置\nexport function saveAISettings(settings: {\n  baseUrl?: string;\n  apiKey?: string;\n  model?: string;\n  systemPrompt?: string;\n}) {\n  if (settings.baseUrl !== undefined) {\n    setSetting(AI_SETTINGS_KEYS.BASE_URL, settings.baseUrl);\n  }\n  if (settings.apiKey !== undefined) {\n    setSetting(AI_SETTINGS_KEYS.API_KEY, settings.apiKey);\n  }\n  if (settings.model !== undefined) {\n    setSetting(AI_SETTINGS_KEYS.MODEL, settings.model);\n  }\n  if (settings.systemPrompt !== undefined) {\n    setSetting(AI_SETTINGS_KEYS.SYSTEM_PROMPT, settings.systemPrompt);\n  }\n}\n"
  },
  {
    "path": "src/goofish/db/user-avatar.repository.ts",
    "content": "/**\n * 用户头像缓存数据仓库\n */\n\nimport { db } from \"./connection\";\nimport type { DbUserAvatar, SaveUserAvatarParams } from \"../types/index\";\n\n// 获取用户头像\nexport function getUserAvatar(userId: string): DbUserAvatar | undefined {\n  const stmt = db.prepare(\"SELECT * FROM user_avatars WHERE user_id = ?\");\n  return stmt.get(userId) as DbUserAvatar | undefined;\n}\n\n// 保存用户头像\nexport function saveUserAvatar(data: SaveUserAvatarParams): boolean {\n  try {\n    const stmt = db.prepare(`\n            INSERT INTO user_avatars (user_id, display_name, avatar, ip_location, introduction)\n            VALUES (?, ?, ?, ?, ?)\n            ON CONFLICT(user_id) DO UPDATE SET\n                display_name = COALESCE(excluded.display_name, display_name),\n                avatar = excluded.avatar,\n                ip_location = COALESCE(excluded.ip_location, ip_location),\n                introduction = COALESCE(excluded.introduction, introduction),\n                updated_at = CURRENT_TIMESTAMP\n        `);\n    stmt.run(\n      data.userId,\n      data.displayName || null,\n      data.avatar,\n      data.ipLocation || null,\n      data.introduction || null,\n    );\n    return true;\n  } catch {\n    return false;\n  }\n}\n\n// 检查用户头像是否存在\nexport function hasUserAvatar(userId: string): boolean {\n  const stmt = db.prepare(\"SELECT 1 FROM user_avatars WHERE user_id = ?\");\n  return !!stmt.get(userId);\n}\n"
  },
  {
    "path": "src/goofish/db/user.repository.ts",
    "content": "/**\n * ChattyPlay 用户数据访问层\n */\n\nimport { db } from './connection'\nimport { createLogger } from '../core/logger'\n\nconst logger = createLogger('Db:UserRepository')\n\nexport interface ChattyplayUser {\n  id?: number\n  username: string\n  password: string\n  email?: string\n  avatar?: string\n  created_at?: string\n  updated_at?: string\n  last_login?: string\n}\n\nexport interface UserWithoutPassword {\n  id: number\n  username: string\n  email?: string\n  avatar?: string\n  created_at?: string\n  updated_at?: string\n  last_login?: string\n}\n\nexport class UserRepository {\n  /**\n   * 根据用户名查找用户\n   */\n  findByUsername(username: string): ChattyplayUser | undefined {\n    try {\n      const stmt = db.prepare('SELECT * FROM chattyplay_user WHERE username = ?')\n      return stmt.get(username) as ChattyplayUser | undefined\n    } catch (error) {\n      // @ts-ignore\n      logger.error('根据用户名查找用户失败:', error)\n      throw error\n    }\n  }\n\n  /**\n   * 根据邮箱查找用户\n   */\n  findByEmail(email: string): ChattyplayUser | undefined {\n    try {\n      const stmt = db.prepare('SELECT * FROM chattyplay_user WHERE email = ?')\n      return stmt.get(email) as ChattyplayUser | undefined\n    } catch (error) {\n      // @ts-ignore\n      logger.error('根据邮箱查找用户失败:', error)\n      throw error\n    }\n  }\n\n  /**\n   * 根据 ID 查找用户（不包含密码）\n   */\n  findById(id: number): UserWithoutPassword | undefined {\n    try {\n      const stmt = db.prepare('SELECT id, username, email, avatar, created_at, updated_at, last_login FROM chattyplay_user WHERE id = ?')\n      return stmt.get(id) as UserWithoutPassword | undefined\n    } catch (error) {\n      // @ts-ignore\n      logger.error('根据ID查找用户失败:', error)\n      throw error\n    }\n  }\n\n  /**\n   * 创建新用户\n   */\n  create(user: Omit<ChattyplayUser, 'id' | 'created_at' | 'updated_at'>): number {\n    try {\n      const stmt = db.prepare(`\n        INSERT INTO chattyplay_user (username, password, email, avatar)\n        VALUES (?, ?, ?, ?)\n      `)\n      const result = stmt.run(user.username, user.password, user.email || null, user.avatar || null)\n      logger.info(`创建用户成功: ${user.username}`)\n      return result.lastInsertRowid as number\n    } catch (error) {\n      // @ts-ignore\n      logger.error('创建用户失败:', error)\n      throw error\n    }\n  }\n\n  /**\n   * 更新最后登录时间\n   */\n  updateLastLogin(userId: number): void {\n    try {\n      const stmt = db.prepare(`\n        UPDATE chattyplay_user\n        SET last_login = CURRENT_TIMESTAMP\n        WHERE id = ?\n      `)\n      stmt.run(userId)\n    } catch (error) {\n      // @ts-ignore\n      logger.error('更新最后登录时间失败:', error)\n      throw error\n    }\n  }\n\n  /**\n   * 更新用户头像\n   */\n  updateAvatar(userId: number, avatar: string): void {\n    try {\n      const stmt = db.prepare(`\n        UPDATE chattyplay_user\n        SET avatar = ?, updated_at = CURRENT_TIMESTAMP\n        WHERE id = ?\n      `)\n      stmt.run(avatar, userId)\n    } catch (error) {\n      // @ts-ignore\n      logger.error('更新用户头像失败:', error)\n      throw error\n    }\n  }\n\n  /**\n   * 更新用户邮箱\n   */\n  updateEmail(userId: number, email: string): void {\n    try {\n      const stmt = db.prepare(`\n        UPDATE chattyplay_user\n        SET email = ?, updated_at = CURRENT_TIMESTAMP\n        WHERE id = ?\n      `)\n      stmt.run(email, userId)\n    } catch (error) {\n      // @ts-ignore\n      logger.error('更新用户邮箱失败:', error)\n      throw error\n    }\n  }\n}\n\nexport const userRepository = new UserRepository()\n"
  },
  {
    "path": "src/goofish/db/workflow.repository.ts",
    "content": "/**\n * 发货流程数据仓库\n */\n\nimport { db } from \"./connection\";\nimport type {\n  Workflow,\n  WorkflowDefinition,\n  WorkflowExecution,\n  WorkflowExecutionStatus,\n} from \"../types/workflow.types\";\n\n// 获取所有流程\nexport function getWorkflows(): Workflow[] {\n  const stmt = db.prepare(`\n        SELECT id, name, description, definition, is_default, enabled, created_at, updated_at\n        FROM workflows ORDER BY is_default DESC, id ASC\n    `);\n  const rows = stmt.all() as any[];\n  return rows.map((row) => ({\n    id: row.id,\n    name: row.name,\n    description: row.description,\n    definition: JSON.parse(row.definition),\n    isDefault: Boolean(row.is_default),\n    enabled: Boolean(row.enabled),\n    createdAt: row.created_at,\n    updatedAt: row.updated_at,\n  }));\n}\n\n// 获取单个流程\nexport function getWorkflowById(id: number): Workflow | null {\n  const stmt = db.prepare(`\n        SELECT id, name, description, definition, is_default, enabled, created_at, updated_at\n        FROM workflows WHERE id = ?\n    `);\n  const row = stmt.get(id) as any;\n  if (!row) return null;\n  return {\n    id: row.id,\n    name: row.name,\n    description: row.description,\n    definition: JSON.parse(row.definition),\n    isDefault: Boolean(row.is_default),\n    enabled: Boolean(row.enabled),\n    createdAt: row.created_at,\n    updatedAt: row.updated_at,\n  };\n}\n\n// 获取默认流程\nexport function getDefaultWorkflow(): Workflow | null {\n  const stmt = db.prepare(`\n        SELECT id, name, description, definition, is_default, enabled, created_at, updated_at\n        FROM workflows WHERE is_default = 1 LIMIT 1\n    `);\n  const row = stmt.get() as any;\n  if (!row) return null;\n  return {\n    id: row.id,\n    name: row.name,\n    description: row.description,\n    definition: JSON.parse(row.definition),\n    isDefault: Boolean(row.is_default),\n    enabled: Boolean(row.enabled),\n    createdAt: row.created_at,\n    updatedAt: row.updated_at,\n  };\n}\n\n// 创建流程\nexport function createWorkflow(data: {\n  name: string;\n  description?: string;\n  definition: WorkflowDefinition;\n  isDefault?: boolean;\n}): number {\n  // 如果设为默认，先取消其他默认\n  if (data.isDefault) {\n    db.prepare(\"UPDATE workflows SET is_default = 0\").run();\n  }\n\n  const stmt = db.prepare(`\n        INSERT INTO workflows (name, description, definition, is_default, enabled)\n        VALUES (?, ?, ?, ?, 1)\n    `);\n  const result = stmt.run(\n    data.name,\n    data.description || null,\n    JSON.stringify(data.definition),\n    data.isDefault ? 1 : 0,\n  );\n  return result.lastInsertRowid as number;\n}\n\n// 更新流程\nexport function updateWorkflow(\n  id: number,\n  data: {\n    name?: string;\n    description?: string;\n    definition?: WorkflowDefinition;\n    isDefault?: boolean;\n    enabled?: boolean;\n  },\n): boolean {\n  const workflow = getWorkflowById(id);\n  if (!workflow) return false;\n\n  // 如果设为默认，先取消其他默认\n  if (data.isDefault) {\n    db.prepare(\"UPDATE workflows SET is_default = 0 WHERE id != ?\").run(id);\n  }\n\n  const stmt = db.prepare(`\n        UPDATE workflows SET\n            name = COALESCE(?, name),\n            description = COALESCE(?, description),\n            definition = COALESCE(?, definition),\n            is_default = COALESCE(?, is_default),\n            enabled = COALESCE(?, enabled),\n            updated_at = CURRENT_TIMESTAMP\n        WHERE id = ?\n    `);\n  stmt.run(\n    data.name ?? null,\n    data.description ?? null,\n    data.definition ? JSON.stringify(data.definition) : null,\n    data.isDefault !== undefined ? (data.isDefault ? 1 : 0) : null,\n    data.enabled !== undefined ? (data.enabled ? 1 : 0) : null,\n    id,\n  );\n  return true;\n}\n\n// 删除流程\nexport function deleteWorkflow(id: number): boolean {\n  const workflow = getWorkflowById(id);\n  if (!workflow || workflow.isDefault) return false; // 不能删除默认流程\n\n  const stmt = db.prepare(\"DELETE FROM workflows WHERE id = ?\");\n  stmt.run(id);\n  return true;\n}\n\n// ============ 流程执行相关 ============\n\n// 创建流程执行记录\nexport function createWorkflowExecution(data: {\n  workflowId: number;\n  orderId: string;\n  accountId: string;\n  ruleId: number;\n  currentNodeId?: string;\n  context?: Record<string, any>;\n}): number {\n  const stmt = db.prepare(`\n        INSERT INTO workflow_executions \n        (workflow_id, order_id, account_id, rule_id, status, current_node_id, context)\n        VALUES (?, ?, ?, ?, 'pending', ?, ?)\n    `);\n  const result = stmt.run(\n    data.workflowId,\n    data.orderId,\n    data.accountId,\n    data.ruleId,\n    data.currentNodeId || null,\n    JSON.stringify(data.context || {}),\n  );\n  return result.lastInsertRowid as number;\n}\n\n// 获取流程执行记录\nexport function getWorkflowExecution(id: number): WorkflowExecution | null {\n  const stmt = db.prepare(`\n        SELECT id, workflow_id, order_id, account_id, rule_id, status, \n               current_node_id, waiting_for_reply, expected_keywords, context,\n               created_at, updated_at\n        FROM workflow_executions WHERE id = ?\n    `);\n  const row = stmt.get(id) as any;\n  if (!row) return null;\n  return mapExecutionRow(row);\n}\n\n// 根据订单ID获取执行记录\nexport function getWorkflowExecutionByOrderId(\n  orderId: string,\n): WorkflowExecution | null {\n  const stmt = db.prepare(`\n        SELECT id, workflow_id, order_id, account_id, rule_id, status, \n               current_node_id, waiting_for_reply, expected_keywords, context,\n               created_at, updated_at\n        FROM workflow_executions \n        WHERE order_id = ? AND status NOT IN ('completed', 'failed')\n        ORDER BY id DESC LIMIT 1\n    `);\n  const row = stmt.get(orderId) as any;\n  if (!row) return null;\n  return mapExecutionRow(row);\n}\n\n// 获取等待用户回复的执行记录\nexport function getWaitingExecutions(accountId: string): WorkflowExecution[] {\n  const stmt = db.prepare(`\n        SELECT id, workflow_id, order_id, account_id, rule_id, status, \n               current_node_id, waiting_for_reply, expected_keywords, context,\n               created_at, updated_at\n        FROM workflow_executions \n        WHERE account_id = ? AND waiting_for_reply = 1 AND status = 'waiting'\n    `);\n  const rows = stmt.all(accountId) as any[];\n  return rows.map(mapExecutionRow);\n}\n\n// 更新流程执行状态\nexport function updateWorkflowExecution(\n  id: number,\n  data: {\n    status?: WorkflowExecutionStatus;\n    currentNodeId?: string | null;\n    waitingForReply?: boolean;\n    expectedKeywords?: string[] | null;\n    context?: Record<string, any>;\n  },\n): boolean {\n  const stmt = db.prepare(`\n        UPDATE workflow_executions SET\n            status = COALESCE(?, status),\n            current_node_id = COALESCE(?, current_node_id),\n            waiting_for_reply = COALESCE(?, waiting_for_reply),\n            expected_keywords = COALESCE(?, expected_keywords),\n            context = COALESCE(?, context),\n            updated_at = CURRENT_TIMESTAMP\n        WHERE id = ?\n    `);\n  stmt.run(\n    data.status ?? null,\n    data.currentNodeId !== undefined ? data.currentNodeId : null,\n    data.waitingForReply !== undefined ? (data.waitingForReply ? 1 : 0) : null,\n    data.expectedKeywords !== undefined\n      ? data.expectedKeywords\n        ? JSON.stringify(data.expectedKeywords)\n        : null\n      : null,\n    data.context ? JSON.stringify(data.context) : null,\n    id,\n  );\n  return true;\n}\n\nfunction mapExecutionRow(row: any): WorkflowExecution {\n  return {\n    id: row.id,\n    workflowId: row.workflow_id,\n    orderId: row.order_id,\n    accountId: row.account_id,\n    ruleId: row.rule_id,\n    status: row.status,\n    currentNodeId: row.current_node_id,\n    waitingForReply: Boolean(row.waiting_for_reply),\n    expectedKeywords: row.expected_keywords\n      ? JSON.parse(row.expected_keywords)\n      : null,\n    context: row.context ? JSON.parse(row.context) : {},\n    createdAt: row.created_at,\n    updatedAt: row.updated_at,\n  };\n}\n"
  },
  {
    "path": "src/goofish/index.ts",
    "content": "import {\n  createLogger,\n  cleanOldLogs,\n  setLogLevel,\n  LogLevel,\n} from \"./core/logger\";\nimport { ClientManager } from \"./websocket\";\nimport { initDatabase, closeDatabase } from \"./db\";\nimport {\n  startServer,\n  setClientManager,\n  messageStore,\n  conversationStore,\n} from \"./api\";\nimport {\n  fetchUserHead,\n  handleOrderMessage,\n  fetchAndUpdateOrderDetail,\n} from \"./services\";\nimport { SERVER_CONFIG, LOG_CONFIG } from \"./core/constants\";\n\nconst logger = createLogger(\"Goofish:App\");\n\n// 保存 clientManager 引用供异步函数使用\nlet clientManager: ClientManager;\n\nexport async function startGoofishServer(port: number = 3001) {\n  // 设置日志级别\n  setLogLevel(LOG_CONFIG.LEVEL as LogLevel);\n\n  // 清理过期日志\n  cleanOldLogs(LOG_CONFIG.RETENTION_DAYS);\n\n  logger.info(\"启动闲鱼多账号WebSocket客户端...\");\n\n  // 初始化数据库\n  initDatabase();\n\n  // 创建客户端管理器\n  clientManager = new ClientManager(async (accountId, msg) => {\n    logger.info(`收到新消息: ${msg.senderName}: ${msg.content}`);\n    messageStore.add(msg);\n    conversationStore.addIncoming(accountId, msg);\n\n    // 处理订单状态消息\n    if (msg.isOrderMessage && msg.orderId) {\n      logger.info(`订单消息: orderId=${msg.orderId}`);\n      handleOrderMessage(accountId, msg.orderId, msg.chatId);\n      // 异步获取订单详情\n      fetchOrderDetailAsync(accountId, msg.orderId);\n    }\n\n    // 异步获取用户头像（不阻塞消息处理）\n    fetchUserAvatarAsync(accountId, msg.chatId, msg.senderId);\n  });\n\n  // 设置 API 客户端管理器引用\n  setClientManager(clientManager);\n\n  // 启动 API 服务器\n  startServer(port);\n\n  // 从数据库加载并启动所有启用的账号\n  await clientManager.startAll();\n\n  // 优雅退出\n  process.on(\"SIGINT\", () => {\n    logger.info(\"收到退出信号，正在断开连接...\");\n    clientManager.stopAll();\n    closeDatabase();\n    process.exit(0);\n  });\n\n  process.on(\"SIGTERM\", () => {\n    logger.info(\"收到终止信号，正在断开连接...\");\n    clientManager.stopAll();\n    closeDatabase();\n    process.exit(0);\n  });\n\n  logger.info(\"Goofish 系统已启动，等待消息...\");\n}\n\n// 异步获取用户头像\nasync function fetchUserAvatarAsync(\n  accountId: string,\n  chatId: string,\n  userId: string,\n) {\n  try {\n    const { userHead } = await fetchUserHead(accountId, userId);\n\n    if (userHead?.avatar) {\n      conversationStore.updateUserAvatar(accountId, chatId, userHead.avatar);\n    }\n  } catch (e) {\n    logger.debug(`获取用户头像失败: ${e}`);\n  }\n}\n\n// 异步获取订单详情\nasync function fetchOrderDetailAsync(accountId: string, orderId: string) {\n  try {\n    const client = clientManager.getClient(accountId);\n    if (!client) {\n      logger.warn(`获取订单详情失败: 账号 ${accountId} 客户端不存在`);\n      return;\n    }\n    await fetchAndUpdateOrderDetail(client, orderId);\n  } catch (e) {\n    logger.debug(`获取订单详情失败: ${e}`);\n  }\n}\n"
  },
  {
    "path": "src/goofish/services/ai.service.ts",
    "content": "/**\n * AI 回复服务\n */\n\nimport OpenAI from \"openai\";\n\nimport { createLogger } from \"../core/logger\";\nimport { getAISettings } from \"../db/index\";\nimport {\n  AI_TOOLS,\n  queryBuyerOrders,\n  getChatHistory,\n  type OrderQueryContext,\n} from \"../ai-tools/index\";\n\nconst logger = createLogger(\"Svc:AI\");\n\nlet openaiClient: OpenAI | null = null;\nlet lastSettings: string = \"\";\n\n// 获取或创建 OpenAI 客户端\nfunction getClient(): OpenAI | null {\n  const settings = getAISettings();\n\n  if (!settings.apiKey) {\n    return null;\n  }\n\n  const settingsKey = `${settings.baseUrl}|${settings.apiKey}`;\n\n  if (openaiClient && lastSettings === settingsKey) {\n    return openaiClient;\n  }\n\n  openaiClient = new OpenAI({\n    apiKey: settings.apiKey,\n    baseURL: settings.baseUrl || undefined,\n  });\n  lastSettings = settingsKey;\n\n  return openaiClient;\n}\n\nexport interface AIContext {\n  userName?: string;\n  itemTitle?: string;\n  accountId?: string;\n  buyerUserId?: string;\n  chatId?: string;\n}\n\n/**\n * 执行工具调用\n */\nfunction executeToolCall(toolName: string, _args: any, ctx: AIContext): string {\n  logger.info(\n    `执行工具调用: ${toolName}, accountId=${ctx.accountId}, buyerUserId=${ctx.buyerUserId}`,\n  );\n\n  switch (toolName) {\n    case \"query_buyer_orders\": {\n      if (!ctx.accountId || !ctx.buyerUserId) {\n        return JSON.stringify({ success: false, message: \"无法获取买家信息\" });\n      }\n      const orderCtx: OrderQueryContext = {\n        accountId: ctx.accountId,\n        buyerUserId: ctx.buyerUserId,\n      };\n      const result = queryBuyerOrders(orderCtx);\n      logger.info(`订单查询结果: ${JSON.stringify(result)}`);\n      return JSON.stringify(result);\n    }\n    default:\n      return JSON.stringify({ success: false, message: \"未知工具\" });\n  }\n}\n\n/**\n * 生成 AI 回复\n */\nexport async function generateAIReply(\n  userMessage: string,\n  context?: AIContext,\n  rulePrompt?: string,\n): Promise<string | null> {\n  const client = getClient();\n  if (!client) {\n    logger.warn(\"AI 服务未配置\");\n    return null;\n  }\n\n  const settings = getAISettings();\n\n  try {\n    // 优先使用规则级别的提示词，否则使用全局提示词\n    let systemPrompt =\n      rulePrompt ||\n      settings.systemPrompt ||\n      \"你是一个闲鱼卖家的智能客服助手，请用简洁友好的语气回复买家的消息。\";\n\n    // 如果启用了工具，添加工具使用说明\n    if (context?.accountId && context?.buyerUserId) {\n      systemPrompt +=\n        \"\\n\\n你可以使用 query_buyer_orders 工具查询当前买家在本店的订单信息。当买家询问订单相关问题时，请先调用此工具获取订单数据再回复。\";\n    }\n\n    const messages: OpenAI.ChatCompletionMessageParam[] = [\n      { role: \"system\", content: systemPrompt },\n    ];\n\n    // 添加上下文信息\n    if (context?.userName || context?.itemTitle) {\n      let contextMsg = \"当前对话信息：\";\n      if (context.userName) contextMsg += `买家昵称: ${context.userName}；`;\n      if (context.itemTitle) contextMsg += `商品: ${context.itemTitle}；`;\n      messages.push({ role: \"system\", content: contextMsg });\n    }\n\n    // 添加聊天历史作为上下文\n    if (context?.accountId && context?.chatId) {\n      const history = getChatHistory(\n        { accountId: context.accountId, chatId: context.chatId },\n        10,\n      );\n      if (history.length > 0) {\n        logger.debug(`加载 ${history.length} 条历史消息作为上下文`);\n        for (const msg of history) {\n          messages.push({ role: msg.role, content: msg.content });\n        }\n      }\n    }\n\n    // 添加当前用户消息\n    messages.push({ role: \"user\", content: userMessage });\n\n    // 判断是否启用工具（需要有买家信息）\n    const enableTools = !!(context?.accountId && context?.buyerUserId);\n\n    logger.info(`AI 调用: enableTools=${enableTools}, model=${settings.model}`);\n\n    const requestParams: OpenAI.ChatCompletionCreateParams = {\n      model: settings.model || \"gpt-3.5-turbo\",\n      messages,\n      max_tokens: 500,\n      temperature: 0.7,\n    };\n\n    if (enableTools) {\n      requestParams.tools = AI_TOOLS;\n      requestParams.tool_choice = \"auto\";\n      logger.info(\n        `已启用工具: ${AI_TOOLS.map((t) => t.function.name).join(\", \")}`,\n      );\n    }\n\n    const response = await client.chat.completions.create(requestParams);\n\n    const choice = response.choices[0];\n    logger.info(\n      `AI 响应: finish_reason=${choice?.finish_reason}, has_tool_calls=${!!choice?.message?.tool_calls}`,\n    );\n\n    // 处理工具调用（有些模型 finish_reason 可能不是 tool_calls 但仍有 tool_calls）\n    if (choice?.message?.tool_calls && choice.message.tool_calls.length > 0) {\n      const toolCalls = choice.message.tool_calls as Array<{\n        id: string;\n        function: { name: string; arguments: string };\n      }>;\n      logger.info(\n        `AI 请求调用工具: ${toolCalls.map((t) => t.function.name).join(\", \")}`,\n      );\n\n      // 添加助手消息\n      messages.push(choice.message);\n\n      // 执行工具调用并添加结果\n      for (const toolCall of toolCalls) {\n        const toolResult = executeToolCall(\n          toolCall.function.name,\n          JSON.parse(toolCall.function.arguments || \"{}\"),\n          context || {},\n        );\n        messages.push({\n          role: \"tool\",\n          tool_call_id: toolCall.id,\n          content: toolResult,\n        });\n        logger.debug(\n          `工具 ${toolCall.function.name} 返回: ${toolResult.slice(0, 100)}...`,\n        );\n      }\n\n      // 再次调用获取最终回复\n      const finalResponse = await client.chat.completions.create({\n        model: settings.model || \"gpt-3.5-turbo\",\n        messages,\n        max_tokens: 500,\n        temperature: 0.7,\n      });\n\n      const reply = finalResponse.choices[0]?.message?.content?.trim();\n      if (reply) {\n        logger.info(\n          `AI 回复生成成功(含工具): ${userMessage.slice(0, 30)}... -> ${reply.slice(0, 30)}...`,\n        );\n        return reply;\n      }\n    }\n\n    // 直接回复\n    const reply = choice?.message?.content?.trim();\n\n    if (reply) {\n      logger.info(\n        `AI 回复生成成功: ${userMessage.slice(0, 30)}... -> ${reply.slice(0, 30)}...`,\n      );\n      return reply;\n    }\n\n    return null;\n  } catch (e) {\n    logger.error(`AI 回复生成失败: ${e}`);\n    return null;\n  }\n}\n\n/**\n * 测试 AI 连接\n */\nexport async function testAIConnection(): Promise<{\n  success: boolean;\n  error?: string;\n}> {\n  const client = getClient();\n  if (!client) {\n    return { success: false, error: \"AI 服务未配置，请先设置 API Key\" };\n  }\n\n  const settings = getAISettings();\n\n  try {\n    const response = await client.chat.completions.create({\n      model: settings.model || \"gpt-3.5-turbo\",\n      messages: [{ role: \"user\", content: \"你好\" }],\n      max_tokens: 10,\n    });\n\n    if (response.choices[0]?.message?.content) {\n      return { success: true };\n    }\n    return { success: false, error: \"未收到有效响应\" };\n  } catch (e: any) {\n    return { success: false, error: e.message || \"连接失败\" };\n  }\n}\n"
  },
  {
    "path": "src/goofish/services/auth.service.ts",
    "content": "/**\n * 用户认证服务\n */\n\nimport { userRepository, ChattyplayUser, UserWithoutPassword } from '../db/user.repository'\nimport { hashPassword, verifyPassword } from '../utils/password.util'\nimport { generateToken, verifyToken, TokenPayload } from '../utils/jwt.util'\nimport { createLogger } from '../core/logger'\n\nconst logger = createLogger('AuthService')\n\nexport interface RegisterData {\n  username: string\n  password: string\n  email?: string\n}\n\nexport interface LoginData {\n  username: string\n  password: string\n}\n\nexport interface AuthResponse {\n  success: boolean\n  message?: string\n  token?: string\n  user?: UserWithoutPassword\n}\n\n/**\n * 用户注册\n */\nexport async function register(data: RegisterData): Promise<AuthResponse> {\n  try {\n    // 验证用户名长度\n    if (data.username.length < 3 || data.username.length > 20) {\n      return {\n        success: false,\n        message: '用户名长度必须在3-20个字符之间'\n      }\n    }\n\n    // 验证密码长度\n    if (data.password.length < 6 || data.password.length > 20) {\n      return {\n        success: false,\n        message: '密码长度必须在6-20个字符之间'\n      }\n    }\n\n    // 验证邮箱格式（如果提供）\n    if (data.email) {\n      const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n      if (!emailRegex.test(data.email)) {\n        return {\n          success: false,\n          message: '邮箱格式不正确'\n        }\n      }\n    }\n\n    // 检查用户名是否已存在\n    const existingUser = userRepository.findByUsername(data.username)\n    if (existingUser) {\n      return {\n        success: false,\n        message: '用户名已存在'\n      }\n    }\n\n    // 检查邮箱是否已存在（如果提供）\n    if (data.email) {\n      const existingEmail = userRepository.findByEmail(data.email)\n      if (existingEmail) {\n        return {\n          success: false,\n          message: '邮箱已被注册'\n        }\n      }\n    }\n\n    // 加密密码\n    const hashedPassword = hashPassword(data.password)\n\n    // 创建用户\n    const userId = userRepository.create({\n      username: data.username,\n      password: hashedPassword,\n      email: data.email\n    })\n\n    // 获取用户信息（不包含密码）\n    const user = userRepository.findById(userId)\n    if (!user) {\n      return {\n        success: false,\n        message: '创建用户失败'\n      }\n    }\n\n    // 生成 token\n    const token = generateToken({\n      userId: user.id,\n      username: user.username\n    })\n\n    logger.info(`用户注册成功: ${data.username}`)\n\n    return {\n      success: true,\n      message: '注册成功',\n      token,\n      user\n    }\n  } catch (error) {\n    // @ts-ignore\n    logger.error('注册失败:', error)\n    return {\n      success: false,\n      message: '注册失败，请稍后重试'\n    }\n  }\n}\n\n/**\n * 用户登录\n */\nexport async function login(data: LoginData): Promise<AuthResponse> {\n  try {\n    // 查找用户\n    const user = userRepository.findByUsername(data.username)\n    if (!user) {\n      return {\n        success: false,\n        message: '用户名或密码错误'\n      }\n    }\n\n    // 验证密码\n    const isPasswordValid = verifyPassword(data.password, user.password)\n    if (!isPasswordValid) {\n      return {\n        success: false,\n        message: '用户名或密码错误'\n      }\n    }\n\n    // 更新最后登录时间\n    userRepository.updateLastLogin(user.id!)\n\n    // 获取用户信息（不包含密码）\n    const userWithoutPassword = userRepository.findById(user.id!)\n    if (!userWithoutPassword) {\n      return {\n        success: false,\n        message: '登录失败'\n      }\n    }\n\n    // 生成 token\n    const token = generateToken({\n      userId: userWithoutPassword.id,\n      username: userWithoutPassword.username\n    })\n\n    logger.info(`用户登录成功: ${data.username}`)\n\n    return {\n      success: true,\n      message: '登录成功',\n      token,\n      user: userWithoutPassword\n    }\n  } catch (error) {\n    // @ts-ignore\n    logger.error('登录失败:', error)\n    return {\n      success: false,\n      message: '登录失败，请稍后重试'\n    }\n  }\n}\n\n/**\n * 验证 token\n */\nexport function authenticateToken(token: string): TokenPayload | null {\n  return verifyToken(token)\n}\n\n/**\n * 根据 token 获取用户信息\n */\nexport function getUserByToken(token: string): UserWithoutPassword | null {\n  const payload = verifyToken(token)\n  if (!payload) {\n    return null\n  }\n\n  const user = userRepository.findById(payload.userId)\n  return user || null\n}\n"
  },
  {
    "path": "src/goofish/services/autoreply.service.ts",
    "content": "/**\n * 自动回复服务\n */\n\nimport { createLogger } from \"../core/logger\";\nimport { getEnabledAutoReplyRules } from \"../db/index\";\nimport { generateAIReply, type AIContext } from \"./ai.service\";\nimport type {\n  ChatMessage,\n  DbAutoReplyRule,\n  AutoReplyResult,\n} from \"../types/index\";\n\nconst logger = createLogger(\"Svc:AutoReply\");\n\n/**\n * 检查消息是否匹配自动回复规则\n */\nexport async function checkAutoReply(\n  accountId: string,\n  msg: ChatMessage,\n  context?: { userName?: string; itemTitle?: string },\n): Promise<AutoReplyResult> {\n  const rules = getEnabledAutoReplyRules(accountId);\n\n  // 分离普通规则和排除匹配规则\n  const normalRules = rules.filter((r) => !r.exclude_match);\n  const excludeRules = rules.filter((r) => r.exclude_match);\n\n  // 构建 AI 上下文，包含买家信息用于工具调用\n  const aiContext: AIContext = {\n    userName: context?.userName || msg.senderName,\n    itemTitle: context?.itemTitle,\n    accountId,\n    buyerUserId: msg.senderId,\n    chatId: msg.chatId,\n  };\n\n  // 先检查普通规则\n  for (const rule of normalRules) {\n    // AI 规则特殊处理\n    if (rule.match_type === \"ai\") {\n      if (matchAITrigger(rule, msg.content)) {\n        const rulePrompt = rule.reply_content || undefined;\n        const aiReply = await generateAIReply(\n          msg.content,\n          aiContext,\n          rulePrompt,\n        );\n        if (aiReply) {\n          logger.info(`[${accountId}] AI 回复: ${msg.content} -> ${aiReply}`);\n          return {\n            matched: true,\n            ruleName: rule.name,\n            replyContent: aiReply,\n            isAI: true,\n          };\n        }\n      }\n      continue;\n    }\n\n    // 普通规则匹配\n    if (matchRule(rule, msg.content)) {\n      logger.info(\n        `[${accountId}] 消息匹配规则 \"${rule.name}\": ${msg.content} -> ${rule.reply_content}`,\n      );\n      return {\n        matched: true,\n        ruleName: rule.name,\n        replyContent: rule.reply_content,\n      };\n    }\n  }\n\n  // 普通规则都没匹配，检查排除匹配规则\n  for (const rule of excludeRules) {\n    // AI 类型的排除匹配规则\n    if (rule.match_type === \"ai\") {\n      const rulePrompt = rule.reply_content || undefined;\n      const aiReply = await generateAIReply(msg.content, aiContext, rulePrompt);\n      if (aiReply) {\n        logger.info(\n          `[${accountId}] AI 排除匹配回复: ${msg.content} -> ${aiReply}`,\n        );\n        return {\n          matched: true,\n          ruleName: rule.name,\n          replyContent: aiReply,\n          isAI: true,\n        };\n      }\n      continue;\n    }\n\n    // 普通排除匹配规则\n    logger.info(\n      `[${accountId}] 排除匹配规则 \"${rule.name}\": ${msg.content} -> ${rule.reply_content}`,\n    );\n    return {\n      matched: true,\n      ruleName: rule.name,\n      replyContent: rule.reply_content,\n    };\n  }\n\n  return { matched: false };\n}\n\n/**\n * 检查是否触发 AI 回复\n */\nfunction matchAITrigger(rule: DbAutoReplyRule, content: string): boolean {\n  const pattern = rule.match_pattern.trim();\n\n  // 空模式表示匹配所有消息\n  if (!pattern || pattern === \"*\") {\n    return true;\n  }\n\n  // 支持关键词列表（逗号分隔）\n  const keywords = pattern\n    .split(\",\")\n    .map((k) => k.trim())\n    .filter(Boolean);\n  if (keywords.length === 0) {\n    return true;\n  }\n\n  const text = content.trim().toLowerCase();\n  return keywords.some((kw) => text.includes(kw.toLowerCase()));\n}\n\n/**\n * 检查内容是否匹配规则\n */\nfunction matchRule(rule: DbAutoReplyRule, content: string): boolean {\n  const pattern = rule.match_pattern;\n  const text = content.trim();\n\n  switch (rule.match_type) {\n    case \"exact\":\n      return text === pattern;\n    case \"contains\":\n      return text.includes(pattern);\n    case \"regex\":\n      try {\n        const regex = new RegExp(pattern, \"i\");\n        return regex.test(text);\n      } catch (e) {\n        logger.warn(`规则 \"${rule.name}\" 的正则表达式无效: ${pattern}`);\n        return false;\n      }\n    default:\n      return false;\n  }\n}\n\n/**\n * 获取匹配类型的显示名称\n */\nexport function getMatchTypeName(type: string): string {\n  switch (type) {\n    case \"exact\":\n      return \"精确匹配\";\n    case \"contains\":\n      return \"包含关键词\";\n    case \"regex\":\n      return \"正则表达式\";\n    case \"ai\":\n      return \"AI 回复\";\n    default:\n      return type;\n  }\n}\n"
  },
  {
    "path": "src/goofish/services/autosell.service.ts",
    "content": "/**\n * 自动发货服务\n */\n\nimport { createLogger } from \"../core/logger\";\nimport {\n  getEnabledAutoSellRules,\n  getStockStats,\n  consumeStock,\n  addDeliveryLog,\n  hasDelivered,\n} from \"../db/index\";\nimport type { AutoSellRule, DeliveryResult, ApiConfig } from \"../types/index\";\n\nconst logger = createLogger(\"Svc:AutoSell\");\n\n/**\n * 通过 API 获取发货内容\n */\nasync function fetchFromApi(\n  config: ApiConfig,\n  context: Record<string, string>,\n): Promise<string> {\n  let url = config.url;\n  let body = config.body;\n\n  // 替换变量\n  for (const [key, value] of Object.entries(context)) {\n    const placeholder = `{{${key}}}`;\n    url = url.replace(new RegExp(placeholder, \"g\"), value);\n    if (body) {\n      body = body.replace(new RegExp(placeholder, \"g\"), value);\n    }\n  }\n\n  const headers: Record<string, string> = {\n    \"Content-Type\": \"application/json\",\n    ...config.headers,\n  };\n\n  const response = await fetch(url, {\n    method: config.method,\n    headers,\n    body: config.method === \"POST\" ? body : undefined,\n  });\n\n  if (!response.ok) {\n    throw new Error(`API 请求失败: ${response.status} ${response.statusText}`);\n  }\n\n  const data = await response.json();\n\n  // 从响应中提取内容\n  if (config.responseField) {\n    const fields = config.responseField.split(\".\");\n    let result = data;\n    for (const field of fields) {\n      result = result?.[field];\n    }\n    if (result === undefined) {\n      throw new Error(`响应中未找到字段: ${config.responseField}`);\n    }\n    return String(result);\n  }\n\n  return typeof data === \"string\" ? data : JSON.stringify(data);\n}\n\n/**\n * 执行发货\n */\nasync function executeDelivery(\n  rule: AutoSellRule,\n  orderId: string,\n  context: Record<string, string>,\n): Promise<DeliveryResult> {\n  switch (rule.deliveryType) {\n    case \"fixed\":\n      if (!rule.deliveryContent) {\n        return { success: false, error: \"未配置发货内容\" };\n      }\n      return { success: true, content: rule.deliveryContent };\n\n    case \"stock\": {\n      const stock = consumeStock(rule.id, orderId);\n      if (!stock) {\n        return { success: false, error: \"库存不足\" };\n      }\n      return { success: true, content: stock.content };\n    }\n\n    case \"api\": {\n      if (!rule.apiConfig) {\n        return { success: false, error: \"未配置 API\" };\n      }\n      try {\n        const content = await fetchFromApi(rule.apiConfig, context);\n        return { success: true, content };\n      } catch (e: any) {\n        return { success: false, error: e.message };\n      }\n    }\n\n    default:\n      return { success: false, error: \"未知发货类型\" };\n  }\n}\n\n/**\n * 处理订单自动发货\n */\nexport async function processAutoSell(\n  accountId: string,\n  orderId: string,\n  itemId?: string,\n  triggerOn: \"paid\" | \"confirmed\" = \"paid\",\n): Promise<DeliveryResult & { ruleName?: string }> {\n  // 检查是否已发货\n  if (hasDelivered(orderId)) {\n    logger.info(`订单 ${orderId} 已发货，跳过`);\n    return { success: false, error: \"订单已发货\" };\n  }\n\n  // 获取匹配的规则\n  const rules = getEnabledAutoSellRules(accountId, itemId);\n  const matchedRule = rules.find((r) => r.triggerOn === triggerOn);\n\n  if (!matchedRule) {\n    logger.debug(`订单 ${orderId} 无匹配的自动发货规则`);\n    return { success: false, error: \"无匹配规则\" };\n  }\n\n  // 检查库存类型的库存是否充足\n  if (matchedRule.deliveryType === \"stock\") {\n    const stats = getStockStats(matchedRule.id);\n    if (stats.available <= 0) {\n      logger.warn(`规则 \"${matchedRule.name}\" 库存不足`);\n      return { success: false, error: \"库存不足\", ruleName: matchedRule.name };\n    }\n  }\n\n  // 执行发货\n  const context = { orderId, accountId, itemId: itemId || \"\" };\n  const result = await executeDelivery(matchedRule, orderId, context);\n\n  // 记录发货日志\n  addDeliveryLog({\n    ruleId: matchedRule.id,\n    orderId,\n    accountId,\n    deliveryType: matchedRule.deliveryType,\n    content: result.content || \"\",\n    status: result.success ? \"success\" : \"failed\",\n    errorMessage: result.error,\n  });\n\n  if (result.success) {\n    logger.info(`订单 ${orderId} 自动发货成功: ${matchedRule.name}`);\n  } else {\n    logger.error(`订单 ${orderId} 自动发货失败: ${result.error}`);\n  }\n\n  return { ...result, ruleName: matchedRule.name };\n}\n\n/**\n * 获取规则的库存状态\n */\nexport function getRuleStockStatus(ruleId: number) {\n  return getStockStats(ruleId);\n}\n"
  },
  {
    "path": "src/goofish/services/conversation.service.ts",
    "content": "/**\n * 对话服务\n * 处理对话相关的业务逻辑\n */\n\nimport {\n  getConversations,\n  getConversation,\n  upsertConversation,\n  updateConversationAvatar,\n  markConversationRead,\n  getConversationMessages,\n  getConversationMessageCount,\n  addConversationMessage,\n  getConversationCount,\n  getAccount,\n} from \"../db/index\";\nimport type {\n  ChatMessage,\n  Conversation,\n  ConversationMessage,\n} from \"../types/index\";\n\n/**\n * 添加收到的消息\n */\nexport function addIncomingMessage(accountId: string, msg: ChatMessage) {\n  const timestamp = Date.now();\n\n  // 先更新对话，不触发事件\n  upsertConversation(\n    {\n      accountId,\n      chatId: msg.chatId,\n      userId: msg.senderId,\n      userName: msg.senderName,\n      lastMessage: msg.content,\n      lastTime: timestamp,\n      unread: 1,\n    },\n    false,\n  );\n\n  // 添加消息，触发事件\n  addConversationMessage({\n    accountId,\n    chatId: msg.chatId,\n    senderId: msg.senderId,\n    senderName: msg.senderName,\n    content: msg.content,\n    msgTime: msg.msgTime,\n    msgId: msg.msgId,\n    direction: \"in\",\n  });\n}\n\n/**\n * 添加发出的消息\n */\nexport function addOutgoingMessage(\n  accountId: string,\n  chatId: string,\n  toUserId: string,\n  content: string,\n) {\n  const timestamp = Date.now();\n  const conv = getConversation(accountId, chatId);\n  if (!conv) return;\n\n  const account = getAccount(accountId);\n  const senderName = account?.nickname || \"我\";\n\n  // 先更新对话，不触发事件\n  upsertConversation(\n    {\n      accountId,\n      chatId,\n      userId: conv.user_id,\n      userName: conv.user_name,\n      lastMessage: content,\n      lastTime: timestamp,\n      unread: 0,\n    },\n    false,\n  );\n\n  // 添加消息，触发事件\n  addConversationMessage({\n    accountId,\n    chatId,\n    senderId: accountId,\n    senderName,\n    content,\n    msgTime: new Date().toLocaleString(\"zh-CN\", { hour12: false }),\n    direction: \"out\",\n  });\n}\n\n/**\n * 更新用户头像\n */\nexport function updateUserAvatar(\n  accountId: string,\n  chatId: string,\n  avatar: string,\n) {\n  updateConversationAvatar(accountId, chatId, avatar);\n}\n\n/**\n * 获取所有对话列表\n */\nexport function getAllConversations(\n  limit = 20,\n  offset = 0,\n): { conversations: Conversation[]; total: number } {\n  const dbConvs = getConversations(limit, offset);\n  const total = getConversationCount();\n\n  const conversations = dbConvs.map((c) => {\n    const account = getAccount(c.account_id);\n    return {\n      accountId: c.account_id,\n      accountNickname: account?.nickname || c.account_id,\n      chatId: c.chat_id,\n      userId: c.user_id,\n      userName: c.user_name,\n      userAvatar: c.user_avatar || undefined,\n      lastMessage: c.last_message,\n      lastTime: c.last_time,\n      unread: c.unread,\n      messageCount: getConversationMessageCount(c.account_id, c.chat_id),\n    };\n  });\n\n  return { conversations, total };\n}\n\n/**\n * 获取单个对话详情\n */\nexport function getConversationDetail(\n  accountId: string,\n  chatId: string,\n  messageLimit = 50,\n  beforeId?: number,\n): Conversation | undefined {\n  const conv = getConversation(accountId, chatId);\n  if (!conv) return undefined;\n\n  const account = getAccount(accountId);\n  const dbMsgs = getConversationMessages(\n    accountId,\n    chatId,\n    messageLimit,\n    beforeId,\n  );\n\n  const messages: ConversationMessage[] = dbMsgs.map((m) => ({\n    id: m.id,\n    senderId: m.sender_id,\n    senderName: m.sender_name,\n    content: m.content,\n    msgTime: m.msg_time,\n    msgId: m.msg_id || undefined,\n    timestamp: m.created_at,\n    direction: m.direction,\n  }));\n\n  return {\n    accountId: conv.account_id,\n    accountNickname: account?.nickname || conv.account_id,\n    chatId: conv.chat_id,\n    userId: conv.user_id,\n    userName: conv.user_name,\n    userAvatar: conv.user_avatar || undefined,\n    lastMessage: conv.last_message,\n    lastTime: conv.last_time,\n    unread: conv.unread,\n    messageCount: getConversationMessageCount(accountId, chatId),\n    messages,\n  };\n}\n\n/**\n * 标记对话已读\n */\nexport function markAsRead(accountId: string, chatId: string) {\n  markConversationRead(accountId, chatId);\n}\n"
  },
  {
    "path": "src/goofish/services/goods.service.ts",
    "content": "/**\n * 商品服务\n */\n\nimport { API_ENDPOINTS, WS_CONFIG } from \"../core/constants\";\nimport { CookiesManager } from \"../core/cookies.manager\";\nimport { generateSign } from \"../utils/crypto\";\nimport { createLogger } from \"../core/logger\";\nimport type { GoodsItem, GoodsListResult } from \"../types/index\";\n\nconst logger = createLogger(\"Svc:Goods\");\n\n/**\n * 获取商品列表\n */\nexport async function fetchGoodsList(\n  accountId: string,\n  userId: string,\n  page = 1,\n  pageSize = 20,\n): Promise<GoodsListResult> {\n  try {\n    const cookiesStr = CookiesManager.getCookies(accountId);\n    if (!cookiesStr) {\n      logger.error(`[${accountId}] 无法获取 cookies`);\n      return { items: [], nextPage: false, totalCount: 0 };\n    }\n\n    const timestamp = Date.now().toString();\n    const dataVal = JSON.stringify({ userId, pageNumber: page, pageSize });\n    const h5Token = CookiesManager.getH5Token(accountId);\n    const sign = generateSign(timestamp, h5Token, dataVal);\n\n    const params = new URLSearchParams({\n      jsv: \"2.7.2\",\n      appKey: WS_CONFIG.SIGN_APP_KEY,\n      t: timestamp,\n      sign,\n      v: \"1.0\",\n      type: \"originaljson\",\n      accountSite: \"xianyu\",\n      dataType: \"json\",\n      timeout: \"20000\",\n      api: \"mtop.idle.web.xyh.item.list\",\n    });\n\n    const res = await fetch(`${API_ENDPOINTS.ITEM_LIST}?${params}`, {\n      method: \"POST\",\n      headers: {\n        accept: \"application/json\",\n        \"content-type\": \"application/x-www-form-urlencoded\",\n        origin: \"https://www.goofish.com\",\n        referer: \"https://www.goofish.com/\",\n        \"user-agent\":\n          \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\",\n        cookie: cookiesStr,\n      },\n      body: `data=${encodeURIComponent(dataVal)}`,\n    });\n\n    CookiesManager.handleResponseCookies(accountId, res);\n\n    const resJson = await res.json();\n\n    if (resJson?.ret?.some((r: string) => r.includes(\"SUCCESS\"))) {\n      const data = resJson.data || {};\n      const cardList = data.cardList || [];\n\n      const items: GoodsItem[] = cardList.map((card: any) => {\n        const cardData = card.cardData || {};\n        const detailParams = cardData.detailParams || {};\n        const picInfo = cardData.picInfo || {};\n        const priceInfo = cardData.priceInfo || {};\n\n        return {\n          id: cardData.id || detailParams.itemId || \"\",\n          title: cardData.title || detailParams.title || \"\",\n          price: priceInfo.price || detailParams.soldPrice || \"\",\n          picUrl: picInfo.picUrl || detailParams.picUrl || \"\",\n          picWidth: picInfo.width || parseInt(detailParams.picWidth) || 0,\n          picHeight: picInfo.height || parseInt(detailParams.picHeight) || 0,\n          categoryId: cardData.categoryId || 0,\n          itemStatus: cardData.itemStatus ?? 0,\n          hasVideo: picInfo.hasVideo || false,\n          soldPrice: detailParams.soldPrice,\n          postInfo: detailParams.postInfo,\n        };\n      });\n\n      logger.info(`[${accountId}] 获取商品列表成功，共 ${items.length} 件商品`);\n      return {\n        items,\n        nextPage: data.nextPage || false,\n        totalCount: data.totalCount || items.length,\n      };\n    }\n\n    logger.warn(\n      `[${accountId}] 获取商品列表失败: ${JSON.stringify(resJson?.ret)}`,\n    );\n    return { items: [], nextPage: false, totalCount: 0 };\n  } catch (e) {\n    logger.error(`[${accountId}] 获取商品列表异常: ${e}`);\n    return { items: [], nextPage: false, totalCount: 0 };\n  }\n}\n"
  },
  {
    "path": "src/goofish/services/index.ts",
    "content": "/**\n * 服务层统一导出\n */\n\n// 自动回复服务\nexport { checkAutoReply, getMatchTypeName } from \"./autoreply.service\";\n\n// 对话服务\nexport {\n  addIncomingMessage,\n  addOutgoingMessage,\n  updateUserAvatar,\n  getAllConversations,\n  getConversationDetail,\n  markAsRead,\n} from \"./conversation.service\";\n\n// 消息服务\nexport {\n  addMessage,\n  getRecentMessages,\n  getAllMessages,\n  getMessageCount,\n  clearMessages,\n} from \"./message.service\";\n\n// 商品服务\nexport { fetchGoodsList } from \"./goods.service\";\n\n// 用户服务\nexport {\n  getCachedUserHead,\n  isUserHeadCached,\n  fetchUserHead,\n  fetchLoginUserId,\n  fetchUserProfile,\n  fetchUserInfo,\n} from \"./user.service\";\n\n// 订单服务\nexport {\n  getOrderList,\n  getOrder,\n  handleOrderMessage,\n  fetchAndUpdateOrderDetail,\n} from \"./order.service\";\n\n// AI 服务\nexport { generateAIReply, testAIConnection } from \"./ai.service\";\n\n// 自动发货服务\nexport { processAutoSell, getRuleStockStatus } from \"./autosell.service\";\n\n// 流程执行服务\nexport { startWorkflowExecution, handleUserReply } from \"./workflow.service\";\n"
  },
  {
    "path": "src/goofish/services/message.service.ts",
    "content": "/**\n * 消息服务\n * 处理消息存储和查询\n */\n\nimport type { StoredMessage, ChatMessage } from \"../types/index\";\n\nconst MAX_MESSAGES = 100;\n\n// 内存消息存储\nconst messages: StoredMessage[] = [];\n\n/**\n * 添加消息\n */\nexport function addMessage(msg: ChatMessage) {\n  const stored: StoredMessage = { ...msg, timestamp: Date.now() };\n  messages.push(stored);\n\n  if (messages.length > MAX_MESSAGES) {\n    messages.splice(0, messages.length - MAX_MESSAGES);\n  }\n}\n\n/**\n * 获取最近消息\n */\nexport function getRecentMessages(limit = 20): StoredMessage[] {\n  return messages.slice(-limit);\n}\n\n/**\n * 获取所有消息\n */\nexport function getAllMessages(): StoredMessage[] {\n  return [...messages];\n}\n\n/**\n * 获取消息数量\n */\nexport function getMessageCount(): number {\n  return messages.length;\n}\n\n/**\n * 清空消息\n */\nexport function clearMessages() {\n  messages.length = 0;\n}\n"
  },
  {
    "path": "src/goofish/services/order.service.ts",
    "content": "/**\n * 订单服务\n * 简化版：订单ID唯一，通过API获取订单详情\n */\n\nimport { createLogger } from \"../core/logger\";\nimport {\n  getOrders,\n  getOrderCount,\n  getOrderById,\n  upsertOrder,\n  updateOrderStatus,\n  getEnabledAutoSellRules,\n} from \"../db/index\";\nimport { OrderStatus, ORDER_STATUS_TEXT } from \"../types/order.types\";\nimport { startWorkflowExecution } from \"./workflow.service\";\nimport type {\n  OrderRecord,\n  OrderListParams,\n  OrderDetailData,\n} from \"../types/order.types\";\nimport type { GoofishClient } from \"../websocket/client\";\n\nconst logger = createLogger(\"Svc:Order\");\n\n// 获取订单列表\nexport function getOrderList(params: OrderListParams) {\n  const orders = getOrders(params);\n  const total = getOrderCount(params);\n  return {\n    orders,\n    total,\n    limit: params.limit || 50,\n    offset: params.offset || 0,\n  };\n}\n\n// 获取单个订单\nexport function getOrder(orderId: string): OrderRecord | null {\n  return getOrderById(orderId);\n}\n\n// 处理订单消息：仅记录订单ID，详情通过API获取\nexport function handleOrderMessage(\n  accountId: string,\n  orderId: string,\n  chatId?: string,\n): void {\n  logger.info(`收到订单消息: ${orderId}`);\n\n  // 检查订单是否已存在\n  const existing = getOrderById(orderId);\n  if (!existing) {\n    // 创建订单占位记录\n    upsertOrder({\n      orderId,\n      accountId,\n      status: 0,\n      statusText: \"获取中...\",\n      chatId,\n    });\n    logger.info(`新订单记录已创建: ${orderId}`);\n  } else if (chatId && !existing.chatId) {\n    // 更新 chatId\n    upsertOrder({\n      ...existing,\n      chatId,\n    });\n  }\n}\n\n// 通过 API 获取订单详情并更新数据库\nexport async function fetchAndUpdateOrderDetail(\n  client: GoofishClient,\n  orderId: string,\n): Promise<OrderDetailData | null> {\n  try {\n    const detail = await client.fetchOrderDetail(orderId);\n    if (!detail?.data) {\n      logger.warn(`订单详情响应为空: ${orderId}`);\n      return null;\n    }\n\n    const data = detail.data;\n\n    // 解析订单信息\n    const orderInfoVO = data.components?.find(\n      (c: any) => c.render === \"orderInfoVO\",\n    )?.data;\n    const itemInfo = orderInfoVO?.itemInfo;\n    const orderInfoList = orderInfoVO?.orderInfoList || [];\n\n    // 提取字段\n    const buyerNickname = orderInfoList.find(\n      (i: any) => i.title === \"买家昵称\",\n    )?.value;\n    const orderTime = orderInfoList.find(\n      (i: any) => i.title === \"下单时间\",\n    )?.value;\n    const payTime = orderInfoList.find(\n      (i: any) => i.title === \"付款时间\",\n    )?.value;\n    const shipTime = orderInfoList.find(\n      (i: any) => i.title === \"发货时间\",\n    )?.value;\n    const completeTime = orderInfoList.find(\n      (i: any) => i.title === \"成交时间\",\n    )?.value;\n\n    const itemIdStr = data.itemId ? String(data.itemId) : undefined;\n    const buyerUserIdStr = data.peerUserId\n      ? String(data.peerUserId)\n      : undefined;\n    const status = data.status;\n    const statusText =\n      data.utArgs?.orderMainTitle || ORDER_STATUS_TEXT[status] || \"未知状态\";\n\n    const itemTitle = itemInfo?.title;\n    const itemPicUrl = itemInfo?.itemMainPictCdnUrl;\n    const price = itemInfo?.price || orderInfoVO?.priceInfo?.amount?.value;\n\n    logger.info(`订单详情: ${orderId}, 状态=${statusText}, 商品=${itemTitle}`);\n\n    // 获取旧订单状态\n    const oldOrder = getOrderById(orderId);\n    const oldStatus = oldOrder?.status;\n\n    upsertOrder({\n      orderId,\n      accountId: client.accountId,\n      itemId: itemIdStr,\n      itemTitle,\n      itemPicUrl,\n      price,\n      buyerUserId: buyerUserIdStr,\n      buyerNickname,\n      status,\n      statusText,\n      orderTime,\n      payTime,\n      shipTime,\n      completeTime,\n    });\n\n    // 检查是否需要触发自动发货\n    if (\n      status === OrderStatus.PENDING_SHIPMENT &&\n      oldStatus !== OrderStatus.PENDING_SHIPMENT\n    ) {\n      // 订单变为待发货状态，触发自动发货\n      await triggerAutoSell(client, orderId, itemIdStr, buyerUserIdStr, \"paid\");\n    } else if (\n      status === OrderStatus.PENDING_RECEIPT &&\n      oldStatus !== OrderStatus.PENDING_RECEIPT\n    ) {\n      // 订单变为待收货状态，触发确认收货后的自动发货\n      await triggerAutoSell(\n        client,\n        orderId,\n        itemIdStr,\n        buyerUserIdStr,\n        \"confirmed\",\n      );\n    }\n\n    return data;\n  } catch (e) {\n    logger.error(`获取订单详情失败: ${orderId} - ${e}`);\n    return null;\n  }\n}\n\n/**\n * 触发自动发货（通过流程引擎）\n */\nasync function triggerAutoSell(\n  client: GoofishClient,\n  orderId: string,\n  itemId: string | undefined,\n  buyerUserId: string | undefined,\n  triggerOn: \"paid\" | \"confirmed\",\n): Promise<void> {\n  try {\n    // 获取匹配的规则\n    const rules = getEnabledAutoSellRules(client.accountId, itemId);\n    const matchedRule = rules.find((r) => r.triggerOn === triggerOn);\n\n    if (!matchedRule) {\n      logger.debug(`订单 ${orderId} 无匹配的自动发货规则`);\n      return;\n    }\n\n    // 从订单记录获取 chatId\n    const order = getOrderById(orderId);\n    const chatId = order?.chatId || undefined;\n\n    // 启动流程执行\n    const result = await startWorkflowExecution(matchedRule.workflowId, {\n      orderId,\n      accountId: client.accountId,\n      itemId,\n      ruleId: matchedRule.id,\n      client,\n      buyerUserId,\n      chatId,\n    });\n\n    if (!result.success) {\n      if (result.error !== \"流程已在执行中\") {\n        logger.warn(`自动发货流程启动失败: ${orderId} - ${result.error}`);\n      }\n    } else {\n      logger.info(`自动发货流程已启动: ${orderId}, 规则: ${matchedRule.name}`);\n    }\n  } catch (e) {\n    logger.error(`触发自动发货异常: ${orderId} - ${e}`);\n  }\n}\n"
  },
  {
    "path": "src/goofish/services/user.service.ts",
    "content": "/**\n * 用户服务\n */\n\nimport { API_ENDPOINTS, WS_CONFIG } from \"../core/constants\";\nimport { CookiesManager } from \"../core/cookies.manager\";\nimport { generateSign } from \"../utils/crypto\";\nimport { createLogger } from \"../core/logger\";\nimport { getUserAvatar, saveUserAvatar, hasUserAvatar } from \"../db/index\";\nimport type { UserHeadInfo, AccountUserInfo } from \"../types/index\";\n\nconst logger = createLogger(\"Svc:User\");\n\n/**\n * 从缓存获取用户头像\n */\nexport function getCachedUserHead(userId: string): UserHeadInfo | null {\n  const cached = getUserAvatar(userId);\n  if (cached) {\n    return {\n      userId: cached.user_id,\n      displayName: cached.display_name || \"\",\n      avatar: cached.avatar,\n      ipLocation: cached.ip_location || undefined,\n      introduction: cached.introduction || undefined,\n    };\n  }\n  return null;\n}\n\n/**\n * 检查用户头像是否已缓存\n */\nexport function isUserHeadCached(userId: string): boolean {\n  return hasUserAvatar(userId);\n}\n\n/**\n * 获取用户头像信息\n */\nexport async function fetchUserHead(\n  accountId: string,\n  userId: string,\n  skipCache = false,\n): Promise<{ userHead: UserHeadInfo | null; fromCache?: boolean }> {\n  if (!skipCache) {\n    const cached = getCachedUserHead(userId);\n    if (cached) {\n      logger.debug(`用户 ${userId} 头像已缓存，跳过 API 请求`);\n      return { userHead: cached, fromCache: true };\n    }\n  }\n\n  try {\n    const cookiesStr = CookiesManager.getCookies(accountId);\n    if (!cookiesStr) {\n      logger.error(`[${accountId}] 无法获取 cookies`);\n      return { userHead: null, fromCache: false };\n    }\n\n    const timestamp = Date.now().toString();\n    const dataVal = JSON.stringify({ self: false, userId });\n    const h5Token = CookiesManager.getH5Token(accountId);\n    const sign = generateSign(timestamp, h5Token, dataVal);\n\n    const params = new URLSearchParams({\n      jsv: \"2.7.2\",\n      appKey: WS_CONFIG.SIGN_APP_KEY,\n      t: timestamp,\n      sign,\n      v: \"1.0\",\n      type: \"originaljson\",\n      accountSite: \"xianyu\",\n      dataType: \"json\",\n      timeout: \"20000\",\n      api: \"mtop.idle.web.user.page.head\",\n      sessionOption: \"AutoLoginOnly\",\n    });\n\n    const res = await fetch(`${API_ENDPOINTS.USER_HEAD}?${params}`, {\n      method: \"POST\",\n      headers: {\n        accept: \"application/json\",\n        \"content-type\": \"application/x-www-form-urlencoded\",\n        origin: \"https://www.goofish.com\",\n        referer: \"https://www.goofish.com/\",\n        \"user-agent\":\n          \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\",\n        cookie: cookiesStr,\n      },\n      body: `data=${encodeURIComponent(dataVal)}`,\n    });\n\n    CookiesManager.handleResponseCookies(accountId, res);\n\n    const json = await res.json();\n    logger.debug(`用户头像响应: ${JSON.stringify(json?.ret)}`);\n\n    if (\n      json?.ret?.some((r: string) => r.includes(\"SUCCESS\")) &&\n      json?.data?.module?.base\n    ) {\n      const base = json.data.module.base;\n      const avatar = base.avatar?.avatar || \"\";\n      logger.info(`获取用户 ${userId} 头像成功: ${avatar.substring(0, 50)}...`);\n\n      const userHead: UserHeadInfo = {\n        userId,\n        displayName: base.displayName || \"\",\n        avatar,\n        ipLocation: base.ipLocation,\n        introduction: base.introduction,\n      };\n\n      saveUserAvatar({\n        userId,\n        displayName: userHead.displayName,\n        avatar: userHead.avatar,\n        ipLocation: userHead.ipLocation,\n        introduction: userHead.introduction,\n      });\n\n      return { userHead, fromCache: false };\n    }\n\n    logger.warn(`获取用户 ${userId} 头像失败: ${JSON.stringify(json?.ret)}`);\n    return { userHead: null, fromCache: false };\n  } catch (e) {\n    logger.error(`获取用户头像异常: ${e}`);\n    return { userHead: null, fromCache: false };\n  }\n}\n\n/**\n * 获取登录用户ID\n */\nexport async function fetchLoginUserId(\n  accountId: string,\n): Promise<string | null> {\n  try {\n    const cookiesStr = CookiesManager.getCookies(accountId);\n    if (!cookiesStr) {\n      logger.error(`[${accountId}] 无法获取 cookies`);\n      return null;\n    }\n\n    const timestamp = Date.now().toString();\n    const dataVal = JSON.stringify({});\n    const h5Token = CookiesManager.getH5Token(accountId);\n    const sign = generateSign(timestamp, h5Token, dataVal);\n\n    const params = new URLSearchParams({\n      jsv: \"2.7.2\",\n      appKey: WS_CONFIG.SIGN_APP_KEY,\n      t: timestamp,\n      sign,\n      v: \"1.0\",\n      type: \"originaljson\",\n      accountSite: \"xianyu\",\n      dataType: \"json\",\n      timeout: \"20000\",\n      api: \"mtop.taobao.idlemessage.pc.loginuser.get\",\n    });\n\n    const res = await fetch(`${API_ENDPOINTS.LOGIN_USER}?${params}`, {\n      method: \"POST\",\n      headers: {\n        accept: \"application/json\",\n        \"content-type\": \"application/x-www-form-urlencoded\",\n        origin: \"https://www.goofish.com\",\n        referer: \"https://www.goofish.com/\",\n        \"user-agent\":\n          \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\",\n        cookie: cookiesStr,\n      },\n      body: `data=${encodeURIComponent(dataVal)}`,\n    });\n\n    CookiesManager.handleResponseCookies(accountId, res);\n\n    const resJson = await res.json();\n\n    if (\n      resJson?.ret?.some((r: string) => r.includes(\"SUCCESS\")) &&\n      resJson?.data?.userId\n    ) {\n      const userId = String(resJson.data.userId);\n      logger.info(`[${accountId}] 获取用户ID成功: ${userId}`);\n      return userId;\n    }\n\n    logger.warn(\n      `[${accountId}] 获取用户ID失败: ${JSON.stringify(resJson?.ret)}`,\n    );\n    return null;\n  } catch (e) {\n    logger.error(`[${accountId}] 获取用户ID异常: ${e}`);\n    return null;\n  }\n}\n\n/**\n * 获取用户详细信息\n */\nexport async function fetchUserProfile(\n  accountId: string,\n): Promise<Omit<AccountUserInfo, \"userId\"> | null> {\n  try {\n    const cookiesStr = CookiesManager.getCookies(accountId);\n    if (!cookiesStr) {\n      logger.error(`[${accountId}] 无法获取 cookies`);\n      return null;\n    }\n\n    const timestamp = Date.now().toString();\n    const dataVal = JSON.stringify({});\n    const h5Token = CookiesManager.getH5Token(accountId);\n    const sign = generateSign(timestamp, h5Token, dataVal);\n\n    const params = new URLSearchParams({\n      jsv: \"2.7.2\",\n      appKey: WS_CONFIG.SIGN_APP_KEY,\n      t: timestamp,\n      sign,\n      v: \"1.0\",\n      type: \"originaljson\",\n      accountSite: \"xianyu\",\n      dataType: \"json\",\n      timeout: \"20000\",\n      api: \"mtop.idle.web.user.page.nav\",\n    });\n\n    const res = await fetch(`${API_ENDPOINTS.USER_INFO}?${params}`, {\n      method: \"POST\",\n      headers: {\n        accept: \"application/json\",\n        \"content-type\": \"application/x-www-form-urlencoded\",\n        origin: \"https://www.goofish.com\",\n        referer: \"https://www.goofish.com/\",\n        \"user-agent\":\n          \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\",\n        cookie: cookiesStr,\n      },\n      body: `data=${encodeURIComponent(dataVal)}`,\n    });\n\n    CookiesManager.handleResponseCookies(accountId, res);\n\n    const resJson = await res.json();\n\n    if (resJson?.ret?.some((r: string) => r.includes(\"SUCCESS\"))) {\n      const base = resJson?.data?.module?.base;\n      if (base) {\n        logger.info(`[${accountId}] 获取用户信息成功: ${base.displayName}`);\n        return {\n          displayName: base.displayName || \"\",\n          avatar: base.avatar || \"\",\n          soldCount: base.soldCount,\n          followers: base.followers,\n          following: base.following,\n        };\n      }\n    }\n\n    logger.warn(\n      `[${accountId}] 获取用户信息失败: ${JSON.stringify(resJson?.ret)}`,\n    );\n    return null;\n  } catch (e) {\n    logger.error(`[${accountId}] 获取用户信息异常: ${e}`);\n    return null;\n  }\n}\n\n/**\n * 获取完整用户信息\n */\nexport async function fetchUserInfo(\n  accountId: string,\n): Promise<AccountUserInfo | null> {\n  const userId = await fetchLoginUserId(accountId);\n  if (!userId) {\n    return null;\n  }\n\n  const profile = await fetchUserProfile(accountId);\n  if (!profile) {\n    return { userId, displayName: \"\", avatar: \"\" };\n  }\n\n  return { userId, ...profile };\n}\n"
  },
  {
    "path": "src/goofish/services/workflow.service.ts",
    "content": "/**\n * 流程执行引擎\n * 负责执行发货流程，支持自动回复节点等待用户确认\n */\n\nimport { createLogger } from \"../core/logger\";\nimport {\n  getWorkflowById,\n  getDefaultWorkflow,\n  createWorkflowExecution,\n  getWorkflowExecution,\n  getWorkflowExecutionByOrderId,\n  getWaitingExecutions,\n  updateWorkflowExecution,\n  getAutoSellRule,\n} from \"../db/index\";\nimport { processAutoSell } from \"./autosell.service\";\nimport type {\n  Workflow,\n  WorkflowDefinition,\n  WorkflowNode,\n  WorkflowExecution,\n  WorkflowNodeType,\n} from \"../types/workflow.types\";\nimport type { GoofishClient } from \"../websocket/client\";\n\nconst logger = createLogger(\"Svc:Workflow\");\n\ninterface ExecutionContext {\n  orderId: string;\n  accountId: string;\n  itemId?: string;\n  ruleId: number;\n  client: GoofishClient;\n  buyerUserId?: string;\n  chatId?: string;\n}\n\n/**\n * 启动流程执行\n */\nexport async function startWorkflowExecution(\n  workflowId: number | null,\n  context: ExecutionContext,\n): Promise<{ success: boolean; error?: string }> {\n  // 获取流程定义\n  let workflow: Workflow | null;\n  if (workflowId) {\n    workflow = getWorkflowById(workflowId);\n  } else {\n    workflow = getDefaultWorkflow();\n  }\n\n  if (!workflow) {\n    // 没有流程定义，使用默认逻辑直接发货\n    return executeDefaultFlow(context);\n  }\n\n  // 检查是否已有执行中的流程\n  const existing = getWorkflowExecutionByOrderId(context.orderId);\n  if (existing) {\n    logger.info(`订单 ${context.orderId} 已有执行中的流程`);\n    return { success: false, error: \"流程已在执行中\" };\n  }\n\n  // 找到触发节点\n  const triggerNode = workflow.definition.nodes.find(\n    (n) => n.type === \"trigger\",\n  );\n  if (!triggerNode) {\n    logger.error(`流程 ${workflow.id} 没有触发节点`);\n    return { success: false, error: \"流程配置错误：缺少触发节点\" };\n  }\n\n  // 创建执行记录\n  const executionId = createWorkflowExecution({\n    workflowId: workflow.id,\n    orderId: context.orderId,\n    accountId: context.accountId,\n    ruleId: context.ruleId,\n    currentNodeId: triggerNode.id,\n    context: {\n      itemId: context.itemId,\n      buyerUserId: context.buyerUserId,\n      chatId: context.chatId,\n    },\n  });\n\n  logger.info(`创建流程执行: ${executionId}, 订单: ${context.orderId}`);\n\n  // 开始执行流程\n  return executeFromNode(\n    executionId,\n    workflow.definition,\n    triggerNode.id,\n    context,\n  );\n}\n\n/**\n * 从指定节点开始执行流程\n */\nasync function executeFromNode(\n  executionId: number,\n  definition: WorkflowDefinition,\n  nodeId: string,\n  context: ExecutionContext,\n): Promise<{ success: boolean; error?: string }> {\n  const node = definition.nodes.find((n) => n.id === nodeId);\n  if (!node) {\n    updateWorkflowExecution(executionId, { status: \"failed\" });\n    return { success: false, error: `节点不存在: ${nodeId}` };\n  }\n\n  updateWorkflowExecution(executionId, {\n    status: \"running\",\n    currentNodeId: nodeId,\n  });\n\n  // 执行当前节点\n  const result = await executeNode(executionId, node, context);\n\n  if (!result.success) {\n    updateWorkflowExecution(executionId, { status: \"failed\" });\n    return result;\n  }\n\n  // 如果节点需要等待（如自动回复节点）\n  if (result.waiting) {\n    updateWorkflowExecution(executionId, {\n      status: \"waiting\",\n      waitingForReply: true,\n      expectedKeywords: result.expectedKeywords || null,\n    });\n    return { success: true };\n  }\n\n  // 找到下一个节点\n  const nextNodeId = findNextNode(definition, nodeId, result.output);\n  if (!nextNodeId) {\n    // 流程结束\n    updateWorkflowExecution(executionId, { status: \"completed\" });\n    logger.info(`流程执行完成: ${executionId}`);\n    return { success: true };\n  }\n\n  // 继续执行下一个节点\n  return executeFromNode(executionId, definition, nextNodeId, context);\n}\n\n/**\n * 执行单个节点\n */\nasync function executeNode(\n  executionId: number,\n  node: WorkflowNode,\n  context: ExecutionContext,\n): Promise<{\n  success: boolean;\n  error?: string;\n  waiting?: boolean;\n  expectedKeywords?: string[];\n  output?: string;\n}> {\n  logger.debug(`执行节点: ${node.id} (${node.type})`);\n\n  switch (node.type) {\n    case \"trigger\":\n      // 触发节点，直接通过\n      return { success: true, output: \"output_1\" };\n\n    case \"delivery\":\n      // 发货节点 - 发送发货内容\n      return executeDeliveryNode(node, context);\n\n    case \"ship\":\n      // 标记发货节点 - 调用平台 API\n      return executeShipNode(node, context);\n\n    case \"autoreply\":\n      // 自动回复节点，需要等待用户确认\n      return executeAutoReplyNode(node, context);\n\n    case \"delay\":\n      // 延迟节点\n      return executeDelayNode(node);\n\n    case \"condition\":\n      // 条件节点\n      return executeConditionNode(node, context);\n\n    case \"notify\":\n      // 通知节点 - 发送消息给买家\n      return executeNotifyNode(node, context);\n\n    default:\n      return { success: false, error: `未知节点类型: ${node.type}` };\n  }\n}\n\n/**\n * 执行发货节点 - 发送发货内容给买家\n */\nasync function executeDeliveryNode(\n  node: WorkflowNode,\n  context: ExecutionContext,\n): Promise<{ success: boolean; error?: string; output?: string }> {\n  const rule = getAutoSellRule(context.ruleId);\n  if (!rule) {\n    return { success: false, error: \"发货规则不存在\" };\n  }\n\n  // 调用自动发货服务获取发货内容\n  const result = await processAutoSell(\n    context.accountId,\n    context.orderId,\n    context.itemId,\n    rule.triggerOn,\n  );\n\n  if (!result.success) {\n    return { success: false, error: result.error };\n  }\n\n  // 发送发货内容给买家\n  if (result.content && context.chatId && context.buyerUserId) {\n    const sendResult = await context.client.sendMessage(\n      context.chatId,\n      context.buyerUserId,\n      result.content,\n    );\n    if (!sendResult) {\n      return { success: false, error: \"发送发货消息失败\" };\n    }\n    logger.info(`发货消息已发送: ${context.orderId}`);\n  } else if (result.content && !context.chatId) {\n    logger.warn(`发货节点缺少 chatId，无法发送消息: ${context.orderId}`);\n  }\n\n  return { success: true, output: \"output_1\" };\n}\n\n/**\n * 执行标记发货节点 - 调用平台 API 标记发货\n */\nasync function executeShipNode(\n  node: WorkflowNode,\n  context: ExecutionContext,\n): Promise<{ success: boolean; error?: string; output?: string }> {\n  // 获取发货方式，默认虚拟发货\n  const deliveryMode = node.config.deliveryMode || \"virtual\";\n\n  let shipResult: { success: boolean; error?: string };\n\n  if (deliveryMode === \"freeshipping\") {\n    // 免拼发货需要 itemId 和 buyerId\n    if (!context.itemId || !context.buyerUserId) {\n      logger.warn(\n        `免拼发货缺少参数: itemId=${context.itemId}, buyerUserId=${context.buyerUserId}`,\n      );\n      // 降级为虚拟发货\n      shipResult = await context.client.confirmShipment(context.orderId);\n      logger.info(`订单降级为虚拟发货: ${context.orderId}`);\n    } else {\n      shipResult = await context.client.freeShipping(\n        context.orderId,\n        context.itemId,\n        context.buyerUserId,\n      );\n      logger.info(`订单免拼发货: ${context.orderId}`);\n    }\n  } else {\n    // 虚拟发货（确认发货）\n    shipResult = await context.client.confirmShipment(context.orderId);\n    logger.info(`订单虚拟发货: ${context.orderId}`);\n  }\n\n  if (!shipResult.success) {\n    return { success: false, error: shipResult.error || \"标记发货失败\" };\n  }\n\n  return { success: true, output: \"output_1\" };\n}\n\n/**\n * 执行自动回复节点（等待用户确认）\n */\nasync function executeAutoReplyNode(\n  node: WorkflowNode,\n  context: ExecutionContext,\n): Promise<{\n  success: boolean;\n  error?: string;\n  waiting?: boolean;\n  expectedKeywords?: string[];\n}> {\n  // 发送提示消息\n  const promptMessage = node.config.promptMessage;\n  if (promptMessage) {\n    if (!context.chatId || !context.buyerUserId) {\n      logger.warn(\n        `等待回复节点缺少 chatId 或 buyerUserId，无法发送提示消息: ${context.orderId}`,\n      );\n    } else {\n      await context.client.sendMessage(\n        context.chatId,\n        context.buyerUserId,\n        promptMessage,\n      );\n      logger.info(`已发送提示消息: ${context.orderId}`);\n    }\n  }\n\n  // 获取关键词配置\n  const keywords = node.config.keywords ||\n    node.config.expectedKeywords || [\"确认\", \"同意\", \"好的\", \"ok\"];\n\n  logger.info(\n    `等待用户确认: ${context.orderId}, 关键词: ${keywords.join(\",\")}`,\n  );\n\n  return {\n    success: true,\n    waiting: true,\n    expectedKeywords: keywords,\n  };\n}\n\n/**\n * 执行延迟节点\n */\nasync function executeDelayNode(\n  node: WorkflowNode,\n): Promise<{ success: boolean; output?: string }> {\n  let delayMs: number;\n\n  if (node.config.delayMode === \"random\") {\n    // 浮动时间模式\n    const minMs = node.config.delayMinMs || 0;\n    const maxMs = node.config.delayMaxMs || 10000;\n    delayMs = Math.floor(Math.random() * (maxMs - minMs + 1)) + minMs;\n    logger.debug(\n      `延迟节点: 浮动模式, 范围 ${minMs}-${maxMs}ms, 实际 ${delayMs}ms`,\n    );\n  } else {\n    // 固定时间模式\n    delayMs = node.config.delayMs || (node.config.delaySeconds || 0) * 1000;\n    logger.debug(`延迟节点: 固定模式, ${delayMs}ms`);\n  }\n\n  if (delayMs > 0) {\n    await new Promise((resolve) => setTimeout(resolve, delayMs));\n  }\n\n  return { success: true, output: \"output_1\" };\n}\n\n/**\n * 执行条件节点\n */\nasync function executeConditionNode(\n  node: WorkflowNode,\n  context: ExecutionContext,\n): Promise<{ success: boolean; output?: string }> {\n  // TODO: 实现条件判断逻辑\n  // 目前默认走 output_1\n  return { success: true, output: \"output_1\" };\n}\n\n/**\n * 执行通知节点 - 发送消息给买家\n */\nasync function executeNotifyNode(\n  node: WorkflowNode,\n  context: ExecutionContext,\n): Promise<{ success: boolean; error?: string; output?: string }> {\n  const message = node.config.message;\n  if (!message) {\n    logger.warn(`通知节点没有配置消息内容: ${node.id}`);\n    return { success: true, output: \"output_1\" };\n  }\n\n  if (!context.chatId || !context.buyerUserId) {\n    logger.warn(`通知节点缺少 chatId 或 buyerUserId: ${context.orderId}`);\n    return { success: true, output: \"output_1\" };\n  }\n\n  const sendResult = await context.client.sendMessage(\n    context.chatId,\n    context.buyerUserId,\n    message,\n  );\n\n  if (!sendResult) {\n    return { success: false, error: \"发送通知消息失败\" };\n  }\n\n  logger.info(`通知消息已发送: ${context.orderId}`);\n  return { success: true, output: \"output_1\" };\n}\n\n/**\n * 找到下一个节点\n */\nfunction findNextNode(\n  definition: WorkflowDefinition,\n  currentNodeId: string,\n  outputKey?: string,\n): string | null {\n  const output = outputKey || \"output_1\";\n  const connection = definition.connections.find(\n    (c) => c.fromNode === currentNodeId && c.fromOutput === output,\n  );\n  return connection?.toNode || null;\n}\n\n/**\n * 执行默认流程（无自定义流程时）\n */\nasync function executeDefaultFlow(\n  context: ExecutionContext,\n): Promise<{ success: boolean; error?: string }> {\n  // 直接调用自动发货\n  const rule = getAutoSellRule(context.ruleId);\n  if (!rule) {\n    return { success: false, error: \"发货规则不存在\" };\n  }\n\n  const result = await processAutoSell(\n    context.accountId,\n    context.orderId,\n    context.itemId,\n    rule.triggerOn,\n  );\n\n  if (!result.success) {\n    return { success: false, error: result.error };\n  }\n\n  // 发送消息\n  if (result.content && context.chatId && context.buyerUserId) {\n    await context.client.sendMessage(\n      context.chatId,\n      context.buyerUserId,\n      result.content,\n    );\n  } else if (result.content && !context.chatId) {\n    logger.warn(`默认流程缺少 chatId，无法发送消息: ${context.orderId}`);\n  }\n\n  // 标记发货（仅待发货触发时）\n  if (rule.triggerOn === \"paid\") {\n    await context.client.confirmShipment(context.orderId);\n  }\n\n  return { success: true };\n}\n\n/**\n * 处理用户回复，继续执行等待中的流程\n */\nexport async function handleUserReply(\n  accountId: string,\n  chatId: string,\n  buyerUserId: string,\n  message: string,\n  client: GoofishClient,\n): Promise<boolean> {\n  // 获取该账号等待中的流程执行\n  const waitingExecutions = getWaitingExecutions(accountId);\n\n  for (const execution of waitingExecutions) {\n    const keywords = execution.expectedKeywords || [];\n    const matched = keywords.some((kw) =>\n      message.toLowerCase().includes(kw.toLowerCase()),\n    );\n\n    if (matched) {\n      logger.info(`用户回复匹配，继续执行流程: ${execution.id}`);\n\n      // 获取流程定义\n      const workflow = getWorkflowById(execution.workflowId);\n      if (!workflow) continue;\n\n      // 更新状态\n      updateWorkflowExecution(execution.id, {\n        waitingForReply: false,\n        expectedKeywords: null,\n      });\n\n      // 找到下一个节点并继续执行\n      const nextNodeId = findNextNode(\n        workflow.definition,\n        execution.currentNodeId!,\n        \"output_1\",\n      );\n\n      if (nextNodeId) {\n        const context: ExecutionContext = {\n          orderId: execution.orderId,\n          accountId: execution.accountId,\n          ruleId: execution.ruleId,\n          client,\n          chatId,\n          buyerUserId,\n          itemId: execution.context?.itemId,\n        };\n\n        await executeFromNode(\n          execution.id,\n          workflow.definition,\n          nextNodeId,\n          context,\n        );\n      } else {\n        updateWorkflowExecution(execution.id, { status: \"completed\" });\n      }\n\n      return true;\n    }\n  }\n\n  return false;\n}\n"
  },
  {
    "path": "src/goofish/types/account.types.ts",
    "content": "/**\n * 账号相关类型定义\n */\n\nimport type { Timestamped } from \"./common.types\";\n\n// 账号信息\nexport interface Account extends Timestamped {\n  id: string;\n  cookies: string;\n  userId?: string;\n  nickname?: string;\n  avatar?: string;\n  enabled: boolean;\n  remark?: string;\n}\n\n// 账号状态\nexport interface AccountStatus {\n  accountId: string;\n  connected: boolean;\n  lastHeartbeat?: string;\n  lastTokenRefresh?: string;\n  errorMessage?: string;\n}\n\n// 账号用户信息\nexport interface AccountUserInfo {\n  userId: string;\n  displayName: string;\n  avatar: string;\n  soldCount?: number;\n  followers?: string;\n  following?: string;\n}\n\n// 创建/更新账号参数\nexport interface UpsertAccountParams {\n  id: string;\n  cookies: string;\n  userId?: string;\n  nickname?: string;\n  avatar?: string;\n  enabled?: boolean;\n  remark?: string;\n}\n\n// 更新账号状态参数\nexport interface UpdateAccountStatusParams {\n  accountId: string;\n  connected?: boolean;\n  lastHeartbeat?: string;\n  lastTokenRefresh?: string;\n  errorMessage?: string;\n}\n"
  },
  {
    "path": "src/goofish/types/autoreply.types.ts",
    "content": "/**\n * 自动回复相关类型定义\n */\n\n// 匹配类型\nexport type MatchType = \"exact\" | \"contains\" | \"regex\" | \"ai\";\n\n// 自动回复规则\nexport interface AutoReplyRule {\n  id: number;\n  name: string;\n  enabled: boolean;\n  priority: number;\n  matchType: MatchType;\n  matchPattern: string;\n  replyContent: string;\n  accountId: string | null;\n  excludeMatch: boolean; // 排除匹配：匹配其他规则未匹配的内容\n  createdAt?: string;\n  updatedAt?: string;\n}\n\n// 数据库自动回复规则\nexport interface DbAutoReplyRule {\n  id: number;\n  name: string;\n  enabled: number;\n  priority: number;\n  match_type: MatchType;\n  match_pattern: string;\n  reply_content: string;\n  account_id: string | null;\n  exclude_match: number; // 0 或 1\n  created_at: string;\n  updated_at: string;\n}\n\n// 创建规则参数\nexport interface CreateAutoReplyRuleParams {\n  name: string;\n  enabled?: boolean;\n  priority?: number;\n  matchType: MatchType;\n  matchPattern: string;\n  replyContent: string;\n  accountId?: string | null;\n  excludeMatch?: boolean;\n}\n\n// 更新规则参数\nexport interface UpdateAutoReplyRuleParams {\n  name?: string;\n  enabled?: boolean;\n  priority?: number;\n  matchType?: MatchType;\n  matchPattern?: string;\n  replyContent?: string;\n  accountId?: string | null;\n  excludeMatch?: boolean;\n}\n\n// 自动回复结果\nexport interface AutoReplyResult {\n  matched: boolean;\n  ruleName?: string;\n  replyContent?: string;\n  isAI?: boolean;\n}\n"
  },
  {
    "path": "src/goofish/types/autosell.types.ts",
    "content": "/**\n * 自动发货相关类型定义\n */\n\n// 发货类型\nexport type DeliveryType = \"fixed\" | \"stock\" | \"api\";\n\n// 触发时机\nexport type TriggerOn = \"paid\" | \"confirmed\";\n\n// API 配置\nexport interface ApiConfig {\n  url: string;\n  method: \"GET\" | \"POST\";\n  headers?: Record<string, string>;\n  body?: string;\n  responseField?: string; // 响应中取货字段路径\n}\n\n// 自动发货规则\nexport interface AutoSellRule {\n  id: number;\n  name: string;\n  enabled: boolean;\n  itemId: string | null;\n  accountId: string | null;\n  deliveryType: DeliveryType;\n  deliveryContent: string | null;\n  apiConfig: ApiConfig | null;\n  triggerOn: TriggerOn;\n  workflowId: number | null;\n  stockCount?: number; // 库存数量（仅stock类型）\n  usedCount?: number; // 已用数量\n  createdAt?: string;\n  updatedAt?: string;\n}\n\n// 数据库自动发货规则\nexport interface DbAutoSellRule {\n  id: number;\n  name: string;\n  enabled: number;\n  item_id: string | null;\n  account_id: string | null;\n  delivery_type: DeliveryType;\n  delivery_content: string | null;\n  api_config: string | null;\n  trigger_on: TriggerOn;\n  created_at: string;\n  updated_at: string;\n}\n\n// 库存项\nexport interface StockItem {\n  id: number;\n  ruleId: number;\n  content: string;\n  used: boolean;\n  usedOrderId: string | null;\n  createdAt: string;\n  usedAt: string | null;\n}\n\n// 数据库库存项\nexport interface DbStockItem {\n  id: number;\n  rule_id: number;\n  content: string;\n  used: number;\n  used_order_id: string | null;\n  created_at: string;\n  used_at: string | null;\n}\n\n// 发货记录\nexport interface DeliveryLog {\n  id: number;\n  ruleId: number | null;\n  orderId: string;\n  accountId: string;\n  deliveryType: DeliveryType;\n  content: string;\n  status: \"success\" | \"failed\";\n  errorMessage: string | null;\n  createdAt: string;\n}\n\n// 数据库发货记录\nexport interface DbDeliveryLog {\n  id: number;\n  rule_id: number | null;\n  order_id: string;\n  account_id: string;\n  delivery_type: DeliveryType;\n  content: string;\n  status: string;\n  error_message: string | null;\n  created_at: string;\n}\n\n// 创建规则参数\nexport interface CreateAutoSellRuleParams {\n  name: string;\n  enabled?: boolean;\n  itemId?: string | null;\n  accountId?: string | null;\n  deliveryType: DeliveryType;\n  deliveryContent?: string | null;\n  apiConfig?: ApiConfig | null;\n  triggerOn?: TriggerOn;\n  workflowId?: number | null;\n}\n\n// 更新规则参数\nexport interface UpdateAutoSellRuleParams {\n  name?: string;\n  enabled?: boolean;\n  itemId?: string | null;\n  accountId?: string | null;\n  deliveryType?: DeliveryType;\n  deliveryContent?: string | null;\n  apiConfig?: ApiConfig | null;\n  triggerOn?: TriggerOn;\n  workflowId?: number | null;\n}\n\n// 发货结果\nexport interface DeliveryResult {\n  success: boolean;\n  content?: string;\n  error?: string;\n}\n"
  },
  {
    "path": "src/goofish/types/common.types.ts",
    "content": "/**\n * 通用类型定义\n */\n\n// 分页参数\nexport interface PaginationParams {\n  limit: number;\n  offset: number;\n}\n\n// 分页结果\nexport interface PaginatedResult<T> {\n  items: T[];\n  total: number;\n  limit: number;\n  offset: number;\n}\n\n// API 响应基础结构\nexport interface ApiResponse<T = unknown> {\n  success: boolean;\n  data?: T;\n  error?: string;\n  message?: string;\n}\n\n// 时间戳相关\nexport interface Timestamped {\n  createdAt?: string;\n  updatedAt?: string;\n}\n"
  },
  {
    "path": "src/goofish/types/conversation.types.ts",
    "content": "/**\n * 对话相关类型定义\n */\n\nimport type { ConversationMessage, MessageDirection } from \"./message.types\";\n\n// 对话信息\nexport interface Conversation {\n  accountId: string;\n  accountNickname?: string;\n  chatId: string;\n  userId: string;\n  userName: string;\n  userAvatar?: string;\n  lastMessage: string;\n  lastTime: number;\n  unread: number;\n  messageCount?: number;\n  messages?: ConversationMessage[];\n}\n\n// 数据库对话记录\nexport interface DbConversation {\n  account_id: string;\n  chat_id: string;\n  user_id: string;\n  user_name: string;\n  user_avatar: string | null;\n  last_message: string;\n  last_time: number;\n  unread: number;\n}\n\n// 数据库对话消息记录\nexport interface DbConversationMessage {\n  id: number;\n  account_id: string;\n  chat_id: string;\n  sender_id: string;\n  sender_name: string;\n  content: string;\n  msg_time: string;\n  msg_id: string | null;\n  direction: MessageDirection;\n  created_at: number;\n}\n\n// 创建/更新对话参数\nexport interface UpsertConversationParams {\n  accountId: string;\n  chatId: string;\n  userId: string;\n  userName: string;\n  userAvatar?: string;\n  lastMessage: string;\n  lastTime: number;\n  unread?: number;\n}\n\n// 添加对话消息参数\nexport interface AddConversationMessageParams {\n  accountId: string;\n  chatId: string;\n  senderId: string;\n  senderName: string;\n  content: string;\n  msgTime: string;\n  msgId?: string;\n  direction: MessageDirection;\n}\n"
  },
  {
    "path": "src/goofish/types/goods.types.ts",
    "content": "/**\n * 商品相关类型定义\n */\n\n// 商品信息\nexport interface GoodsItem {\n  id: string;\n  title: string;\n  price: string;\n  picUrl: string;\n  picWidth: number;\n  picHeight: number;\n  categoryId: number;\n  itemStatus: number; // 0: 在售\n  hasVideo: boolean;\n  soldPrice?: string;\n  postInfo?: string;\n  accountId?: string;\n  accountNickname?: string;\n}\n\n// 商品列表结果\nexport interface GoodsListResult {\n  items: GoodsItem[];\n  nextPage: boolean;\n  totalCount: number;\n}\n"
  },
  {
    "path": "src/goofish/types/index.ts",
    "content": "// 通用类型\nexport * from './common.types'\n\n// 账号类型\nexport * from './account.types'\n\n// 消息类型\nexport * from './message.types'\n\n// 对话类型\nexport * from './conversation.types'\n\n// 自动回复类型\nexport * from './autoreply.types'\n\n// 商品类型\nexport * from './goods.types'\n\n// 用户类型\nexport * from './user.types'\n\n// 订单类型\nexport * from './order.types'\n\n// 自动发货类型\nexport * from './autosell.types'\n\n// 发货流程类型\nexport * from './workflow.types'\n"
  },
  {
    "path": "src/goofish/types/message.types.ts",
    "content": "/**\n * 消息相关类型定义\n */\n\n// 聊天消息\nexport interface ChatMessage {\n  senderId: string;\n  senderName: string;\n  msgTime: string;\n  content: string;\n  chatId: string;\n  msgId?: string;\n  raw: unknown;\n  // 订单相关信息\n  orderId?: string;\n  orderStatus?: string;\n  isOrderMessage?: boolean;\n}\n\n// 存储的消息（带时间戳）\nexport interface StoredMessage extends ChatMessage {\n  timestamp: number;\n}\n\n// 消息方向\nexport type MessageDirection = \"in\" | \"out\";\n\n// 对话消息\nexport interface ConversationMessage {\n  id: number;\n  senderId: string;\n  senderName: string;\n  content: string;\n  msgTime: string;\n  msgId?: string;\n  timestamp: number;\n  direction: MessageDirection;\n}\n\n// 消息回调\nexport type MessageCallback = (\n  accountId: string,\n  msg: ChatMessage,\n) => void | Promise<void>;\n"
  },
  {
    "path": "src/goofish/types/order.types.ts",
    "content": "/**\n * 订单相关类型定义\n */\n\n// 订单状态枚举\nexport enum OrderStatus {\n  PENDING_PAYMENT = 1, // 待付款\n  PENDING_SHIPMENT = 2, // 待发货\n  PENDING_RECEIPT = 3, // 待收货\n  COMPLETED = 4, // 交易成功\n  CLOSED = 6, // 已关闭\n}\n\n// 订单状态文本映射\nexport const ORDER_STATUS_TEXT: Record<number, string> = {\n  0: \"获取中\",\n  [OrderStatus.PENDING_PAYMENT]: \"待付款\",\n  [OrderStatus.PENDING_SHIPMENT]: \"待发货\",\n  [OrderStatus.PENDING_RECEIPT]: \"待收货\",\n  [OrderStatus.COMPLETED]: \"交易成功\",\n  [OrderStatus.CLOSED]: \"已关闭\",\n};\n\n// 数据库订单记录\nexport interface OrderRecord {\n  id: number;\n  orderId: string;\n  accountId: string;\n  itemId: string | null;\n  itemTitle: string | null;\n  itemPicUrl: string | null;\n  price: string | null;\n  buyerUserId: string | null;\n  buyerNickname: string | null;\n  chatId: string | null;\n  status: number;\n  statusText: string;\n  orderTime: string;\n  payTime: string | null;\n  shipTime: string | null;\n  completeTime: string | null;\n  createdAt: string;\n  updatedAt: string;\n}\n\n// 订单详情 API 响应数据\nexport interface OrderDetailData {\n  orderId: number;\n  bizOrderId?: number;\n  itemId: number;\n  peerUserId: number;\n  seller: boolean;\n  status: number;\n  components: OrderComponent[];\n  bottomBarVO?: {\n    buttonList: OrderButton[];\n  };\n  utArgs?: {\n    orderStatusName: string;\n    orderMainTitle: string;\n    orderId: string;\n    orderStatus: string;\n  };\n}\n\nexport interface OrderComponent {\n  render: string;\n  data: any;\n}\n\nexport interface OrderButton {\n  name: string;\n  style: string;\n  tradeAction: string;\n  buttonDisable: boolean;\n}\n\n// 订单列表查询参数\nexport interface OrderListParams {\n  accountId?: string;\n  status?: number;\n  limit?: number;\n  offset?: number;\n}\n\n// 订单列表响应\nexport interface OrderListResponse {\n  orders: OrderRecord[];\n  total: number;\n  limit: number;\n  offset: number;\n}\n"
  },
  {
    "path": "src/goofish/types/user.types.ts",
    "content": "/**\n * 用户相关类型定义\n */\n\n// 用户头像信息\nexport interface UserHeadInfo {\n  userId: string;\n  displayName: string;\n  avatar: string;\n  ipLocation?: string;\n  introduction?: string;\n}\n\n// 数据库用户头像缓存\nexport interface DbUserAvatar {\n  user_id: string;\n  display_name: string | null;\n  avatar: string;\n  ip_location: string | null;\n  introduction: string | null;\n  created_at: string;\n  updated_at: string;\n}\n\n// 保存用户头像参数\nexport interface SaveUserAvatarParams {\n  userId: string;\n  displayName?: string;\n  avatar: string;\n  ipLocation?: string;\n  introduction?: string;\n}\n"
  },
  {
    "path": "src/goofish/types/workflow.types.ts",
    "content": "/**\n * 发货流程相关类型定义\n */\n\n// 流程节点类型\nexport type WorkflowNodeType =\n  | \"trigger\" // 触发节点（开始）\n  | \"autoreply\" // 自动回复节点（等待用户确认）\n  | \"delivery\" // 发货节点\n  | \"ship\" // 标记发货节点\n  | \"delay\" // 延迟节点\n  | \"condition\" // 条件节点\n  | \"notify\"; // 通知节点\n\n// 流程节点\nexport interface WorkflowNode {\n  id: string;\n  type: WorkflowNodeType;\n  name: string;\n  // 节点配置\n  config: {\n    // delivery: 发货方式 (virtual=虚拟发货, freeshipping=免拼发货)\n    deliveryMode?: \"virtual\" | \"freeshipping\";\n    // autoreply: 提示消息\n    promptMessage?: string;\n    // autoreply: 期望的用户回复关键词\n    keywords?: string[];\n    // autoreply: 匹配模式\n    matchMode?: \"exact\" | \"contains\";\n    // delay: 延迟毫秒数\n    delayMs?: number;\n    // delay: 延迟模式 (fixed=固定, random=浮动)\n    delayMode?: \"fixed\" | \"random\";\n    // delay: 浮动模式最小毫秒\n    delayMinMs?: number;\n    // delay: 浮动模式最大毫秒\n    delayMaxMs?: number;\n    // condition: 条件表达式\n    expression?: string;\n    // notify: 通知消息\n    message?: string;\n    // 兼容旧字段\n    autoReplyRuleId?: number;\n    expectedKeywords?: string[];\n    delaySeconds?: number;\n    condition?: string;\n  };\n  // 位置信息（用于编辑器）\n  posX: number;\n  posY: number;\n}\n\n// 流程连接\nexport interface WorkflowConnection {\n  fromNode: string;\n  fromOutput: string;\n  toNode: string;\n  toInput: string;\n}\n\n// 流程定义\nexport interface WorkflowDefinition {\n  nodes: WorkflowNode[];\n  connections: WorkflowConnection[];\n}\n\n// 流程记录\nexport interface Workflow {\n  id: number;\n  name: string;\n  description: string | null;\n  definition: WorkflowDefinition;\n  isDefault: boolean;\n  enabled: boolean;\n  createdAt: string;\n  updatedAt: string;\n}\n\n// 流程执行状态\nexport type WorkflowExecutionStatus =\n  | \"pending\"\n  | \"running\"\n  | \"waiting\"\n  | \"completed\"\n  | \"failed\";\n\n// 流程执行记录\nexport interface WorkflowExecution {\n  id: number;\n  workflowId: number;\n  orderId: string;\n  accountId: string;\n  ruleId: number;\n  status: WorkflowExecutionStatus;\n  currentNodeId: string | null;\n  // 等待用户回复的相关信息\n  waitingForReply: boolean;\n  expectedKeywords: string[] | null;\n  // 执行上下文数据\n  context: Record<string, any>;\n  createdAt: string;\n  updatedAt: string;\n}\n\n// 默认流程：触发 -> 发货 -> 标记发货\nexport const DEFAULT_WORKFLOW: WorkflowDefinition = {\n  nodes: [\n    {\n      id: \"trigger\",\n      type: \"trigger\",\n      name: \"触发\",\n      config: {},\n      posX: 100,\n      posY: 200,\n    },\n    {\n      id: \"delivery\",\n      type: \"delivery\",\n      name: \"发货\",\n      config: {},\n      posX: 350,\n      posY: 200,\n    },\n    {\n      id: \"ship\",\n      type: \"ship\",\n      name: \"标记发货\",\n      config: {},\n      posX: 600,\n      posY: 200,\n    },\n  ],\n  connections: [\n    {\n      fromNode: \"trigger\",\n      fromOutput: \"output_1\",\n      toNode: \"delivery\",\n      toInput: \"input_1\",\n    },\n    {\n      fromNode: \"delivery\",\n      fromOutput: \"output_1\",\n      toNode: \"ship\",\n      toInput: \"input_1\",\n    },\n  ],\n};\n"
  },
  {
    "path": "src/goofish/utils/cookies.ts",
    "content": "// 解析 cookies 字符串为对象\nexport function parseCookies(cookiesStr: string): Record<string, string> {\n  if (!cookiesStr) return {};\n  const cookies: Record<string, string> = {};\n  for (const cookie of cookiesStr.replace(/; /g, \";\").split(\";\")) {\n    const trimmed = cookie.trim();\n    const idx = trimmed.indexOf(\"=\");\n    if (idx > 0) {\n      cookies[trimmed.slice(0, idx).trim()] = trimmed.slice(idx + 1).trim();\n    }\n  }\n  return cookies;\n}\n\n// 将 cookies 对象转换为字符串\nexport function stringifyCookies(cookies: Record<string, string>): string {\n  return Object.entries(cookies)\n    .map(([key, value]) => `${key}=${value}`)\n    .join(\"; \");\n}\n\n// 合并 cookies，新的覆盖旧的\nexport function mergeCookies(\n  oldCookiesStr: string,\n  newCookies: Record<string, string>,\n): string {\n  const merged = parseCookies(oldCookiesStr);\n  for (const [key, value] of Object.entries(newCookies)) {\n    if (value) {\n      merged[key] = value;\n    }\n  }\n  return stringifyCookies(merged);\n}\n\n// 从 Set-Cookie 响应头解析 cookies\nexport function parseSetCookieHeaders(\n  setCookieHeaders: string[],\n): Record<string, string> {\n  const cookies: Record<string, string> = {};\n  for (const header of setCookieHeaders) {\n    // Set-Cookie 格式: name=value; Path=/; Domain=.goofish.com; ...\n    const parts = header.split(\";\");\n    if (parts.length > 0) {\n      const cookiePart = parts[0].trim();\n      const idx = cookiePart.indexOf(\"=\");\n      if (idx > 0) {\n        const name = cookiePart.slice(0, idx).trim();\n        const value = cookiePart.slice(idx + 1).trim();\n        cookies[name] = value;\n      }\n    }\n  }\n  return cookies;\n}\n"
  },
  {
    "path": "src/goofish/utils/crypto.ts",
    "content": "import crypto from \"crypto\";\n\nexport function generateMid(): string {\n  const randomPart = Math.floor(Math.random() * 1000);\n  const timestamp = Date.now();\n  return `${randomPart}${timestamp} 0`;\n}\n\nexport function generateUuid(): string {\n  const chars = \"0123456789abcdef\";\n  const sections = [8, 4, 4, 4, 12];\n  return sections\n    .map((len) =>\n      Array.from(\n        { length: len },\n        () => chars[Math.floor(Math.random() * 16)],\n      ).join(\"\"),\n    )\n    .join(\"-\");\n}\n\nexport function generateDeviceId(userId: string): string {\n  const chars =\n    \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n  const result: string[] = [];\n  for (let i = 0; i < 36; i++) {\n    if ([8, 13, 18, 23].includes(i)) {\n      result.push(\"-\");\n    } else if (i === 14) {\n      result.push(\"4\");\n    } else if (i === 19) {\n      const randVal = Math.floor(Math.random() * 16);\n      result.push(chars[(randVal & 0x3) | 0x8]);\n    } else {\n      result.push(chars[Math.floor(Math.random() * 16)]);\n    }\n  }\n  return result.join(\"\") + \"-\" + userId;\n}\n\nexport function generateSign(t: string, token: string, data: string): string {\n  const appKey = \"34839810\";\n  const msg = `${token}&${t}&${appKey}&${data}`;\n  return crypto.createHash(\"md5\").update(msg).digest(\"hex\");\n}\n"
  },
  {
    "path": "src/goofish/utils/date.ts",
    "content": "/**\n * 日期时间工具函数\n */\n\n// 获取当前本地时间字符串（格式：YYYY-MM-DD HH:mm:ss）\nexport function nowLocalString(): string {\n  const now = new Date();\n  const year = now.getFullYear();\n  const month = String(now.getMonth() + 1).padStart(2, \"0\");\n  const day = String(now.getDate()).padStart(2, \"0\");\n  const hours = String(now.getHours()).padStart(2, \"0\");\n  const minutes = String(now.getMinutes()).padStart(2, \"0\");\n  const seconds = String(now.getSeconds()).padStart(2, \"0\");\n  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;\n}\n"
  },
  {
    "path": "src/goofish/utils/index.ts",
    "content": "/**\n * 工具函数统一导出\n */\n\nexport { generateMid, generateUuid, generateDeviceId, generateSign } from './crypto'\nexport { parseCookies, stringifyCookies, mergeCookies, parseSetCookieHeaders } from './cookies'\nexport { decryptMessagePack } from './msgpack'\n"
  },
  {
    "path": "src/goofish/utils/jwt.util.ts",
    "content": "/**\n * JWT 工具\n * 简单的 token 生成和验证\n */\n\nimport CryptoJS from 'crypto-js'\n\nconst JWT_SECRET = 'chattyplay-jwt-secret-2024'\nconst TOKEN_EXPIRY = 7 * 24 * 60 * 60 * 1000 // 7天\n\nexport interface TokenPayload {\n  userId: number\n  username: string\n  exp?: number\n}\n\n/**\n * 生成 JWT token\n */\nexport function generateToken(payload: Omit<TokenPayload, 'exp'>): string {\n  const tokenPayload: TokenPayload = {\n    ...payload,\n    exp: Date.now() + TOKEN_EXPIRY\n  }\n\n  const header = {\n    alg: 'HS256',\n    typ: 'JWT'\n  }\n\n  const encodedHeader = base64UrlEncode(JSON.stringify(header))\n  const encodedPayload = base64UrlEncode(JSON.stringify(tokenPayload))\n  const signature = CryptoJS.HmacSHA256(`${encodedHeader}.${encodedPayload}`, JWT_SECRET).toString()\n  const encodedSignature = base64UrlEncode(signature)\n\n  return `${encodedHeader}.${encodedPayload}.${encodedSignature}`\n}\n\n/**\n * 验证 JWT token\n */\nexport function verifyToken(token: string): TokenPayload | null {\n  try {\n    const [encodedHeader, encodedPayload, encodedSignature] = token.split('.')\n\n    if (!encodedHeader || !encodedPayload || !encodedSignature) {\n      return null\n    }\n\n    // 验证签名\n    const signature = CryptoJS.HmacSHA256(`${encodedHeader}.${encodedPayload}`, JWT_SECRET).toString()\n    const encodedSignatureCheck = base64UrlEncode(signature)\n\n    if (encodedSignature !== encodedSignatureCheck) {\n      return null\n    }\n\n    // 解析 payload\n    const payload = JSON.parse(base64UrlDecode(encodedPayload)) as TokenPayload\n\n    // 检查过期时间\n    if (payload.exp && payload.exp < Date.now()) {\n      return null\n    }\n\n    return payload\n  } catch (error) {\n    console.error('Token verification failed:', error)\n    return null\n  }\n}\n\n/**\n * Base64 URL 编码\n */\nfunction base64UrlEncode(str: string): string {\n  return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(str))\n    .replace(/\\+/g, '-')\n    .replace(/\\//g, '_')\n    .replace(/=/g, '')\n}\n\n/**\n * Base64 URL 解码\n */\nfunction base64UrlDecode(str: string): string {\n  let base64 = str.replace(/-/g, '+').replace(/_/g, '/')\n  while (base64.length % 4) {\n    base64 += '='\n  }\n  return CryptoJS.enc.Base64.parse(base64).toString(CryptoJS.enc.Utf8)\n}\n"
  },
  {
    "path": "src/goofish/utils/msgpack.ts",
    "content": "// MessagePack 解码器\nclass MessagePackDecoder {\n  private data: Buffer;\n  private pos = 0;\n\n  constructor(data: Buffer) {\n    this.data = data;\n  }\n\n  private readByte(): number {\n    return this.data[this.pos++];\n  }\n\n  private readBytes(count: number): Buffer {\n    const result = this.data.subarray(this.pos, this.pos + count);\n    this.pos += count;\n    return result;\n  }\n\n  private readUint32(): number {\n    const val = this.data.readUInt32BE(this.pos);\n    this.pos += 4;\n    return val;\n  }\n\n  private readString(length: number): string {\n    return this.readBytes(length).toString(\"utf-8\");\n  }\n\n  decodeValue(): any {\n    const fmt = this.readByte();\n\n    if (fmt <= 0x7f) return fmt;\n    if (fmt >= 0x80 && fmt <= 0x8f) return this.decodeMap(fmt & 0x0f);\n    if (fmt >= 0x90 && fmt <= 0x9f) return this.decodeArray(fmt & 0x0f);\n    if (fmt >= 0xa0 && fmt <= 0xbf) return this.readString(fmt & 0x1f);\n    if (fmt === 0xc0) return null;\n    if (fmt === 0xc2) return false;\n    if (fmt === 0xc3) return true;\n    if (fmt === 0xc4) return this.readBytes(this.readByte());\n    if (fmt === 0xc5) {\n      const len = this.data.readUInt16BE(this.pos);\n      this.pos += 2;\n      return this.readBytes(len);\n    }\n    if (fmt === 0xc6) return this.readBytes(this.readUint32());\n    if (fmt === 0xcc) return this.readByte();\n    if (fmt === 0xcd) {\n      const val = this.data.readUInt16BE(this.pos);\n      this.pos += 2;\n      return val;\n    }\n    if (fmt === 0xce) return this.readUint32();\n    if (fmt === 0xcf) {\n      const val = this.data.readBigUInt64BE(this.pos);\n      this.pos += 8;\n      return Number(val);\n    }\n    if (fmt === 0xd9) return this.readString(this.readByte());\n    if (fmt === 0xda) {\n      const len = this.data.readUInt16BE(this.pos);\n      this.pos += 2;\n      return this.readString(len);\n    }\n    if (fmt === 0xdb) return this.readString(this.readUint32());\n    if (fmt === 0xdc) {\n      const len = this.data.readUInt16BE(this.pos);\n      this.pos += 2;\n      return this.decodeArray(len);\n    }\n    if (fmt === 0xdd) return this.decodeArray(this.readUint32());\n    if (fmt === 0xde) {\n      const len = this.data.readUInt16BE(this.pos);\n      this.pos += 2;\n      return this.decodeMap(len);\n    }\n    if (fmt === 0xdf) return this.decodeMap(this.readUint32());\n    if (fmt >= 0xe0) return fmt - 0x100;\n\n    throw new Error(`Unknown format: ${fmt.toString(16)}`);\n  }\n\n  private decodeArray(size: number): any[] {\n    return Array.from({ length: size }, () => this.decodeValue());\n  }\n\n  private decodeMap(size: number): Record<string, any> {\n    const result: Record<string, any> = {};\n    for (let i = 0; i < size; i++) {\n      const key = this.decodeValue();\n      result[String(key)] = this.decodeValue();\n    }\n    return result;\n  }\n\n  decode(): any {\n    return this.decodeValue();\n  }\n}\n\nexport function decryptMessagePack(data: string): any {\n  let padded = data;\n  const missing = data.length % 4;\n  if (missing) padded += \"=\".repeat(4 - missing);\n\n  const decoded = Buffer.from(padded, \"base64\");\n  const decoder = new MessagePackDecoder(decoded);\n  return decoder.decode();\n}\n"
  },
  {
    "path": "src/goofish/utils/password.util.ts",
    "content": "/**\n * 密码加密工具\n * 使用 crypto-js 进行密码哈希\n */\n\nimport CryptoJS from 'crypto-js'\n\nconst SECRET_KEY = 'chattyplay-secret-key-2024'\n\n/**\n * 对密码进行哈希加密\n * @param password 原始密码\n * @returns 加密后的密码\n */\nexport function hashPassword(password: string): string {\n  return CryptoJS.SHA256(password + SECRET_KEY).toString()\n}\n\n/**\n * 验证密码\n * @param password 原始密码\n * @param hashedPassword 加密后的密码\n * @returns 是否匹配\n */\nexport function verifyPassword(password: string, hashedPassword: string): boolean {\n  const hashed = hashPassword(password)\n  return hashed === hashedPassword\n}\n"
  },
  {
    "path": "src/goofish/websocket/client.manager.ts",
    "content": "import { GoofishClient } from \"./client\";\nimport { createLogger } from \"../core/logger\";\nimport { getEnabledAccounts, updateAccountStatus } from \"../db/index\";\nimport type { MessageCallback } from \"../types/index\";\n\nconst logger = createLogger(\"Ws:Manager\");\n\nexport class ClientManager {\n  private clients: Map<string, GoofishClient> = new Map();\n  private onMessage?: MessageCallback;\n\n  constructor(onMessage?: MessageCallback) {\n    this.onMessage = onMessage;\n  }\n\n  // 从数据库加载并启动所有启用的账号\n  async startAll(): Promise<void> {\n    const accounts = getEnabledAccounts();\n    logger.info(`从数据库加载了 ${accounts.length} 个启用的账号`);\n\n    for (const account of accounts) {\n      await this.startClient(account.id);\n    }\n  }\n\n  // 启动单个客户端\n  async startClient(accountId: string): Promise<boolean> {\n    if (this.clients.has(accountId)) {\n      logger.warn(`账号 ${accountId} 已在运行中`);\n      return false;\n    }\n\n    try {\n      const client = new GoofishClient(accountId, this.onMessage);\n      const success = await client.run();\n\n      if (success) {\n        this.clients.set(accountId, client);\n        logger.info(`账号 ${accountId} 启动成功`);\n        return true;\n      } else {\n        logger.error(`账号 ${accountId} 启动失败`);\n        updateAccountStatus({\n          accountId,\n          connected: false,\n          errorMessage: \"启动失败\",\n        });\n        return false;\n      }\n    } catch (e: any) {\n      logger.error(`账号 ${accountId} 启动异常: ${e.message}`);\n      updateAccountStatus({\n        accountId,\n        connected: false,\n        errorMessage: e.message,\n      });\n      return false;\n    }\n  }\n\n  // 停止单个客户端\n  stopClient(accountId: string): boolean {\n    const client = this.clients.get(accountId);\n    if (!client) {\n      logger.warn(`账号 ${accountId} 未在运行`);\n      return false;\n    }\n\n    client.disconnect();\n    this.clients.delete(accountId);\n    logger.info(`账号 ${accountId} 已停止`);\n    return true;\n  }\n\n  // 重启单个客户端\n  async restartClient(accountId: string): Promise<boolean> {\n    this.stopClient(accountId);\n    await new Promise((r) => setTimeout(r, 1000));\n    return this.startClient(accountId);\n  }\n\n  // 停止所有客户端\n  stopAll(): void {\n    logger.info(\"正在停止所有客户端...\");\n    // @ts-ignore\n    for (const [accountId] of this.clients) {\n      this.stopClient(accountId);\n    }\n    logger.info(\"所有客户端已停止\");\n  }\n\n  // 获取客户端\n  getClient(accountId: string): GoofishClient | undefined {\n    return this.clients.get(accountId);\n  }\n\n  // 获取所有客户端状态\n  getStatus(): Array<{\n    accountId: string;\n    connected: boolean;\n    userId: string;\n  }> {\n    const status: Array<{\n      accountId: string;\n      connected: boolean;\n      userId: string;\n    }> = [];\n    // @ts-ignore\n    for (const [accountId, client] of this.clients) {\n      status.push({\n        accountId,\n        connected: client.isConnected(),\n        userId: client.getUserId(),\n      });\n    }\n    return status;\n  }\n\n  // 获取运行中的客户端数量\n  getActiveCount(): number {\n    let count = 0;\n    // @ts-ignore\n    for (const client of this.clients.values()) {\n      if (client.isConnected()) count++;\n    }\n    return count;\n  }\n}\n"
  },
  {
    "path": "src/goofish/websocket/client.ts",
    "content": "import WebSocket from \"ws\";\nimport { WS_CONFIG, WS_HEADERS, API_ENDPOINTS } from \"../core/constants\";\nimport { createLogger } from \"../core/logger\";\nimport { CookiesManager } from \"../core/cookies.manager\";\nimport { generateDeviceId, generateMid, generateSign } from \"../utils/crypto\";\nimport { nowLocalString } from \"../utils/date\";\nimport { TokenManager } from \"./token\";\nimport { updateAccountStatus } from \"../db/index\";\nimport { sendMessage } from \"./message.sender\";\nimport { processWebSocketMessage } from \"./message.receiver\";\nimport type { MessageCallback } from \"../types/index\";\n\nconst logger = createLogger(\"Ws:Client\");\n\nexport class GoofishClient {\n  private _accountId: string;\n  private myId: string;\n  private deviceId: string;\n  private ws: WebSocket | null = null;\n  private tokenManager: TokenManager;\n  private running = false;\n  private connectionFailures = 0;\n  private heartbeatTimer: NodeJS.Timeout | null = null;\n  private tokenRefreshTimer: NodeJS.Timeout | null = null;\n  private onMessage?: MessageCallback;\n\n  constructor(accountId: string, onMessage?: MessageCallback) {\n    this._accountId = accountId;\n    this.onMessage = onMessage;\n\n    // 从数据库获取 cookies 验证\n    const userId = CookiesManager.getUserId(accountId);\n    if (!userId) throw new Error(\"Cookie中缺少必需的'unb'字段或账号不存在\");\n\n    this.myId = userId;\n    this.deviceId = generateDeviceId(this.myId);\n    this.tokenManager = new TokenManager(accountId, this.deviceId);\n\n    logger.info(`[${this._accountId}] 客户端初始化完成，用户ID: ${this.myId}`);\n  }\n\n  get accountId(): string {\n    return this._accountId;\n  }\n\n  getAccountId(): string {\n    return this._accountId;\n  }\n\n  isConnected(): boolean {\n    return this.ws?.readyState === WebSocket.OPEN;\n  }\n\n  getUserId(): string {\n    return this.myId;\n  }\n\n  async sendMessage(\n    chatId: string,\n    toUserId: string,\n    text: string,\n  ): Promise<boolean> {\n    if (!this.ws) return false;\n    return sendMessage({\n      accountId: this._accountId,\n      myId: this.myId,\n      ws: this.ws,\n      chatId,\n      toUserId,\n      text,\n    });\n  }\n\n  // 获取订单详情\n  async fetchOrderDetail(orderId: string): Promise<any> {\n    try {\n      const cookiesStr = CookiesManager.getCookies(this._accountId);\n      if (!cookiesStr) {\n        logger.error(`[${this._accountId}] 无法获取 cookies`);\n        return null;\n      }\n\n      const h5Token = CookiesManager.getH5Token(this._accountId);\n      if (!h5Token) {\n        logger.warn(`[${this._accountId}] h5Token 为空，尝试刷新 token`);\n      }\n\n      const timestamp = Date.now().toString();\n      const dataVal = JSON.stringify({ tid: orderId });\n      const sign = generateSign(timestamp, h5Token, dataVal);\n\n      logger.debug(\n        `[${this._accountId}] 订单API请求 - orderId: ${orderId}, h5Token: ${h5Token ? h5Token.substring(0, 8) + \"...\" : \"空\"}`,\n      );\n\n      const params = new URLSearchParams({\n        jsv: \"2.7.2\",\n        appKey: WS_CONFIG.SIGN_APP_KEY,\n        t: timestamp,\n        sign,\n        v: \"1.0\",\n        type: \"originaljson\",\n        accountSite: \"xianyu\",\n        dataType: \"json\",\n        timeout: \"20000\",\n        api: \"mtop.idle.web.trade.order.detail\",\n        sessionOption: \"AutoLoginOnly\",\n      });\n\n      const res = await fetch(`${API_ENDPOINTS.ORDER_DETAIL}?${params}`, {\n        method: \"POST\",\n        headers: {\n          accept: \"application/json\",\n          \"content-type\": \"application/x-www-form-urlencoded\",\n          origin: \"https://www.goofish.com\",\n          referer: \"https://www.goofish.com/\",\n          \"user-agent\":\n            \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\",\n          cookie: cookiesStr,\n        },\n        body: `data=${encodeURIComponent(dataVal)}`,\n      });\n\n      CookiesManager.handleResponseCookies(this._accountId, res);\n      const resJson = await res.json();\n\n      if (resJson?.ret?.some((r: string) => r.includes(\"SUCCESS\"))) {\n        logger.info(`[${this._accountId}] 获取订单详情成功: ${orderId}`);\n        return resJson;\n      }\n\n      const retMsg = resJson?.ret?.join(\", \") || \"未知错误\";\n      logger.warn(`[${this._accountId}] 获取订单详情失败: ${retMsg}`);\n\n      if (\n        retMsg.includes(\"TOKEN\") ||\n        retMsg.includes(\"FAIL_SYS_SESSION_EXPIRED\")\n      ) {\n        logger.warn(`[${this._accountId}] Token 可能已过期，请尝试刷新账号`);\n      }\n\n      return null;\n    } catch (e) {\n      logger.error(`[${this._accountId}] 获取订单详情异常: ${e}`);\n      return null;\n    }\n  }\n\n  // 确认发货（虚拟发货/无需物流）\n  async confirmShipment(\n    orderId: string,\n  ): Promise<{ success: boolean; error?: string }> {\n    try {\n      const cookiesStr = CookiesManager.getCookies(this._accountId);\n      if (!cookiesStr) {\n        return { success: false, error: \"无法获取 cookies\" };\n      }\n\n      const h5Token = CookiesManager.getH5Token(this._accountId);\n      if (!h5Token) {\n        return { success: false, error: \"h5Token 为空\" };\n      }\n\n      const timestamp = Date.now().toString();\n      const dataVal = JSON.stringify({\n        orderId,\n        tradeText: \"\",\n        picList: [],\n        newUnconsign: true,\n      });\n      const sign = generateSign(timestamp, h5Token, dataVal);\n\n      const params = new URLSearchParams({\n        jsv: \"2.7.2\",\n        appKey: WS_CONFIG.SIGN_APP_KEY,\n        t: timestamp,\n        sign,\n        v: \"1.0\",\n        type: \"originaljson\",\n        accountSite: \"xianyu\",\n        dataType: \"json\",\n        timeout: \"20000\",\n        api: \"mtop.taobao.idle.logistic.consign.dummy\",\n        sessionOption: \"AutoLoginOnly\",\n      });\n\n      logger.info(`[${this._accountId}] 确认发货请求 - orderId: ${orderId}`);\n\n      const res = await fetch(`${API_ENDPOINTS.CONFIRM_SHIPMENT}?${params}`, {\n        method: \"POST\",\n        headers: {\n          accept: \"application/json\",\n          \"content-type\": \"application/x-www-form-urlencoded\",\n          origin: \"https://www.goofish.com\",\n          referer: \"https://www.goofish.com/\",\n          \"user-agent\":\n            \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\",\n          cookie: cookiesStr,\n        },\n        body: `data=${encodeURIComponent(dataVal)}`,\n      });\n\n      CookiesManager.handleResponseCookies(this._accountId, res);\n      const resJson = await res.json();\n\n      if (resJson?.ret?.some((r: string) => r.includes(\"SUCCESS\"))) {\n        logger.info(`[${this._accountId}] 确认发货成功: ${orderId}`);\n        return { success: true };\n      }\n\n      const retMsg = resJson?.ret?.join(\", \") || \"未知错误\";\n      logger.warn(`[${this._accountId}] 确认发货失败: ${retMsg}`);\n      return { success: false, error: retMsg };\n    } catch (e) {\n      logger.error(`[${this._accountId}] 确认发货异常: ${e}`);\n      return { success: false, error: String(e) };\n    }\n  }\n\n  // 免拼发货\n  async freeShipping(\n    orderId: string,\n    itemId: string,\n    buyerId: string,\n  ): Promise<{ success: boolean; error?: string }> {\n    try {\n      const cookiesStr = CookiesManager.getCookies(this._accountId);\n      if (!cookiesStr) {\n        return { success: false, error: \"无法获取 cookies\" };\n      }\n\n      const h5Token = CookiesManager.getH5Token(this._accountId);\n      if (!h5Token) {\n        return { success: false, error: \"h5Token 为空\" };\n      }\n\n      const timestamp = Date.now().toString();\n      const dataVal = JSON.stringify({\n        bizOrderId: orderId,\n        itemId,\n        buyerId,\n      });\n      const sign = generateSign(timestamp, h5Token, dataVal);\n\n      const params = new URLSearchParams({\n        jsv: \"2.7.2\",\n        appKey: WS_CONFIG.SIGN_APP_KEY,\n        t: timestamp,\n        sign,\n        v: \"1.0\",\n        type: \"originaljson\",\n        accountSite: \"xianyu\",\n        dataType: \"json\",\n        timeout: \"20000\",\n        api: \"mtop.idle.groupon.activity.seller.freeshipping\",\n        sessionOption: \"AutoLoginOnly\",\n      });\n\n      logger.info(\n        `[${this._accountId}] 免拼发货请求 - orderId: ${orderId}, itemId: ${itemId}, buyerId: ${buyerId}`,\n      );\n\n      const res = await fetch(`${API_ENDPOINTS.FREE_SHIPPING}?${params}`, {\n        method: \"POST\",\n        headers: {\n          accept: \"application/json\",\n          \"content-type\": \"application/x-www-form-urlencoded\",\n          origin: \"https://www.goofish.com\",\n          referer: \"https://www.goofish.com/\",\n          \"user-agent\":\n            \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\",\n          cookie: cookiesStr,\n        },\n        body: `data=${encodeURIComponent(dataVal)}`,\n      });\n\n      CookiesManager.handleResponseCookies(this._accountId, res);\n      const resJson = await res.json();\n\n      if (resJson?.ret?.some((r: string) => r.includes(\"SUCCESS\"))) {\n        logger.info(`[${this._accountId}] 免拼发货成功: ${orderId}`);\n        return { success: true };\n      }\n\n      const retMsg = resJson?.ret?.join(\", \") || \"未知错误\";\n      logger.warn(`[${this._accountId}] 免拼发货失败: ${retMsg}`);\n      return { success: false, error: retMsg };\n    } catch (e) {\n      logger.error(`[${this._accountId}] 免拼发货异常: ${e}`);\n      return { success: false, error: String(e) };\n    }\n  }\n\n  private startHeartbeat() {\n    this.heartbeatTimer = setInterval(() => {\n      if (this.ws?.readyState === WebSocket.OPEN) {\n        const msg = { lwp: \"/!\", headers: { mid: generateMid() } };\n        this.ws.send(JSON.stringify(msg));\n        logger.debug(`[${this._accountId}] 心跳已发送`);\n        updateAccountStatus({\n          accountId: this._accountId,\n          lastHeartbeat: nowLocalString(),\n        });\n      }\n    }, WS_CONFIG.HEARTBEAT_INTERVAL * 1000);\n  }\n\n  private startTokenRefresh() {\n    this.tokenRefreshTimer = setInterval(async () => {\n      if (this.running) {\n        logger.info(`[${this._accountId}] 开始定时刷新Token...`);\n        const token = await this.tokenManager.refresh();\n        if (token) {\n          logger.info(`[${this._accountId}] Token刷新成功`);\n          updateAccountStatus({\n            accountId: this._accountId,\n            lastTokenRefresh: nowLocalString(),\n          });\n        } else {\n          logger.warn(`[${this._accountId}] Token刷新失败`);\n        }\n      }\n    }, WS_CONFIG.TOKEN_REFRESH_INTERVAL * 1000);\n    logger.info(\n      `[${this._accountId}] Token刷新定时器已启动，间隔: ${WS_CONFIG.TOKEN_REFRESH_INTERVAL}秒`,\n    );\n  }\n\n  private async initConnection() {\n    if (!this.ws) return;\n\n    let token = this.tokenManager.getToken();\n    if (!token) {\n      logger.info(`[${this._accountId}] 首次连接，正在获取Token...`);\n      token = await this.tokenManager.refresh();\n      if (!token) {\n        logger.error(`[${this._accountId}] 获取Token失败，无法完成注册`);\n        return;\n      }\n    }\n\n    const regMsg = {\n      lwp: \"/reg\",\n      headers: {\n        \"cache-header\": \"app-key token ua wv\",\n        \"app-key\": WS_CONFIG.APP_KEY,\n        token: token,\n        ua: \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\",\n        dt: \"j\",\n        wv: \"im:3,au:3,sy:6\",\n        sync: \"0,0;0;0;\",\n        did: this.deviceId,\n        mid: generateMid(),\n      },\n    };\n    this.ws.send(JSON.stringify(regMsg));\n    logger.info(`[${this._accountId}] 注册消息已发送`);\n\n    await new Promise((r) => setTimeout(r, 1000));\n\n    const currentTime = Date.now();\n    const syncMsg = {\n      lwp: \"/r/SyncStatus/ackDiff\",\n      headers: { mid: generateMid() },\n      body: [\n        {\n          pipeline: \"sync\",\n          tooLong2Tag: \"PNM,1\",\n          channel: \"sync\",\n          topic: \"sync\",\n          highPts: 0,\n          pts: currentTime * 1000,\n          seq: 0,\n          timestamp: currentTime,\n        },\n      ],\n    };\n    this.ws.send(JSON.stringify(syncMsg));\n    logger.info(`[${this._accountId}] 连接注册完成`);\n  }\n\n  private sendAck(headers: any) {\n    if (this.ws?.readyState !== WebSocket.OPEN) return;\n    const ack = {\n      code: 200,\n      headers: { mid: headers?.mid || generateMid(), sid: headers?.sid || \"\" },\n    };\n    this.ws.send(JSON.stringify(ack));\n  }\n\n  async connect(): Promise<boolean> {\n    return new Promise((resolve) => {\n      try {\n        logger.info(`[${this._accountId}] 正在连接 WebSocket...`);\n        this.ws = new WebSocket(WS_CONFIG.URL, { headers: WS_HEADERS });\n\n        this.ws.on(\"open\", async () => {\n          logger.info(`[${this._accountId}] WebSocket 连接已建立`);\n          this.connectionFailures = 0;\n          updateAccountStatus({\n            accountId: this._accountId,\n            connected: true,\n            errorMessage: \"\",\n          });\n\n          try {\n            await this.initConnection();\n            this.startHeartbeat();\n            this.startTokenRefresh();\n            resolve(true);\n          } catch (e) {\n            logger.error(`[${this._accountId}] 初始化连接失败: ${e}`);\n            resolve(false);\n          }\n        });\n\n        this.ws.on(\"message\", async (data) => {\n          try {\n            const msgData = JSON.parse(data.toString());\n            await processWebSocketMessage(\n              msgData,\n              {\n                accountId: this._accountId,\n                myId: this.myId,\n                client: this,\n                onMessage: this.onMessage,\n                onAutoReply: (chatId, senderId, content) =>\n                  this.sendMessage(chatId, senderId, content),\n              },\n              (headers) => this.sendAck(headers),\n            );\n          } catch (e) {\n            logger.error(`[${this._accountId}] 解析消息失败: ${e}`);\n          }\n        });\n\n        this.ws.on(\"close\", (code, reason) => {\n          logger.warn(\n            `[${this._accountId}] WebSocket 连接关闭: ${code} - ${reason}`,\n          );\n          this.cleanup();\n          updateAccountStatus({ accountId: this._accountId, connected: false });\n\n          if (\n            this.running &&\n            this.connectionFailures < WS_CONFIG.MAX_RECONNECT_ATTEMPTS\n          ) {\n            this.connectionFailures++;\n            logger.info(\n              `[${this._accountId}] ${WS_CONFIG.RECONNECT_DELAY / 1000}秒后尝试重连 (${this.connectionFailures}/${WS_CONFIG.MAX_RECONNECT_ATTEMPTS})`,\n            );\n            setTimeout(() => this.connect(), WS_CONFIG.RECONNECT_DELAY);\n          }\n        });\n\n        this.ws.on(\"error\", (err) => {\n          logger.error(`[${this._accountId}] WebSocket 错误: ${err.message}`);\n          updateAccountStatus({\n            accountId: this._accountId,\n            errorMessage: err.message,\n          });\n          resolve(false);\n        });\n      } catch (e) {\n        logger.error(`[${this._accountId}] 连接失败: ${e}`);\n        resolve(false);\n      }\n    });\n  }\n\n  private cleanup() {\n    if (this.heartbeatTimer) {\n      clearInterval(this.heartbeatTimer);\n      this.heartbeatTimer = null;\n    }\n    if (this.tokenRefreshTimer) {\n      clearInterval(this.tokenRefreshTimer);\n      this.tokenRefreshTimer = null;\n    }\n  }\n\n  disconnect() {\n    this.running = false;\n    this.cleanup();\n    if (this.ws) {\n      this.ws.close();\n      this.ws = null;\n    }\n    updateAccountStatus({ accountId: this._accountId, connected: false });\n    logger.info(`[${this._accountId}] 客户端已断开连接`);\n  }\n\n  async run() {\n    this.running = true;\n    const connected = await this.connect();\n    if (!connected) {\n      logger.error(`[${this._accountId}] 启动失败`);\n      this.running = false;\n    }\n    return connected;\n  }\n}\n"
  },
  {
    "path": "src/goofish/websocket/index.ts",
    "content": "/**\n * WebSocket 模块统一导出\n */\n\nexport { GoofishClient } from './client'\nexport { ClientManager } from './client.manager'\nexport { TokenManager } from './token'\nexport { decryptSyncData, extractChatMessage, isSystemMessage } from './message.parser'\nexport { sendMessage } from './message.sender'\nexport { handleSyncMessage, processWebSocketMessage } from './message.receiver'\n"
  },
  {
    "path": "src/goofish/websocket/message.parser.ts",
    "content": "import { decryptMessagePack } from \"../utils/msgpack\";\nimport { createLogger } from \"../core/logger\";\nimport type { ChatMessage } from \"../types/index\";\n\nconst logger = createLogger(\"Ws:Parser\");\n\n// 纯系统提示消息（不需要处理的）\nconst SYSTEM_MESSAGES = [\n  \"[不想宝贝被砍价?设置不砍价回复  ]\",\n  \"AI正在帮你回复消息，不错过每笔订单\",\n  \"发来一条消息\",\n  \"发来一条新消息\",\n  \"快给ta一个评价吧~\",\n  \"快给ta一个评价吧～\",\n  \"卖家人不错？送Ta闲鱼小红花\",\n];\n\n// 订单状态消息（需要捕获但不触发自动回复）\nconst ORDER_STATUS_MESSAGES = [\n  \"[我已拍下，待付款]\",\n  \"[我已付款，等待你发货]\",\n  \"[已付款，待发货]\",\n  \"[你已发货]\",\n  \"[你已发货，请等待买家确认收货]\",\n  \"[买家确认收货，交易成功]\",\n  \"[你已确认收货，交易成功]\",\n  \"[你关闭了订单，钱款已原路退返]\",\n  \"[未付款，买家关闭了订单]\",\n  \"[记得及时确认收货]\",\n  \"已发货\",\n  \"有蚂蚁森林能量可领\",\n];\n\nexport function isSystemMessage(content: string): boolean {\n  return SYSTEM_MESSAGES.includes(content);\n}\n\nexport function isOrderStatusMessage(content: string): boolean {\n  return ORDER_STATUS_MESSAGES.some((msg) => content.includes(msg));\n}\n\nexport function decryptSyncData(data: string): any | null {\n  // 先尝试 MessagePack 解码（这是主要格式）\n  try {\n    const result = decryptMessagePack(data);\n    if (result && typeof result === \"object\") {\n      // 检查是否是有效的聊天消息结构\n      const msg1 = result[\"1\"] || result[1];\n      if (msg1 && typeof msg1 === \"object\") {\n        const msg10 = msg1[\"10\"] || msg1[10];\n        if (msg10 && typeof msg10 === \"object\" && \"reminderContent\" in msg10) {\n          return result;\n        }\n      }\n    }\n  } catch (e) {\n    logger.debug(`MessagePack解密失败: ${e}`);\n  }\n\n  // 尝试 base64 + JSON\n  try {\n    const decoded = Buffer.from(data, \"base64\").toString(\"utf-8\");\n    const parsed = JSON.parse(decoded);\n    if (typeof parsed === \"object\") {\n      if (\"chatType\" in parsed) return null; // 系统消息\n      return parsed;\n    }\n  } catch {\n    // 忽略 JSON 解析失败\n  }\n\n  return null;\n}\n\nexport function extractChatMessage(\n  message: any,\n  myId: string,\n): ChatMessage | null {\n  try {\n    // 检查消息结构\n    if (!message || typeof message !== \"object\") return null;\n\n    // 支持两种消息结构：数字键和字符串键\n    const msg1 = message[\"1\"] || message[1];\n    if (!msg1 || typeof msg1 !== \"object\") return null;\n\n    const msg10 = msg1[\"10\"] || msg1[10];\n    if (!msg10 || typeof msg10 !== \"object\") return null;\n\n    const createTime = parseInt(msg1[\"5\"] || msg1[5] || \"0\");\n    const senderName = msg10.senderNick || msg10.reminderTitle || \"未知用户\";\n    const senderId = msg10.senderUserId || \"unknown\";\n    const content = msg10.reminderContent || \"\";\n\n    // 提取 chatId\n    const chatIdRaw = msg1[\"2\"] || msg1[2] || \"\";\n    const chatId = String(chatIdRaw).includes(\"@\")\n      ? String(chatIdRaw).split(\"@\")[0]\n      : String(chatIdRaw);\n\n    // 提取 API 消息 ID 和订单信息 (从 extJson 中)\n    let msgId: string | undefined;\n    let orderId: string | undefined;\n    let orderStatus: string | undefined;\n    try {\n      const extJson = msg10.extJson;\n      if (extJson) {\n        const ext = JSON.parse(extJson);\n        msgId = ext.messageId || ext.msg_id;\n        // updateKey 格式有两种:\n        // 1. orderId:contentType:taskName:num (如 3142117850666220888:20:BUYER_CONFIRM:74)\n        // 2. sessionId:orderId:contentType:taskName:num (如 56627074402:3142117850666220888:100:REMIND:26)\n        if (ext.updateKey) {\n          const parts = ext.updateKey.split(\":\");\n          for (const part of parts) {\n            if (/^\\d{15,}$/.test(part)) {\n              orderId = part;\n              break;\n            }\n          }\n        }\n      }\n    } catch {\n      // 忽略解析失败\n    }\n\n    // 从 bizTag 提取订单状态\n    try {\n      const bizTag = msg10.bizTag;\n      if (bizTag) {\n        const tag = JSON.parse(bizTag);\n        orderStatus = tag.taskName;\n      }\n    } catch {\n      // 忽略解析失败\n    }\n\n    // 从 reminderUrl 提取订单ID（备用方案）\n    if (!orderId && msg10.reminderUrl) {\n      const urlMatch = msg10.reminderUrl.match(/orderId=(\\d+)/);\n      if (urlMatch) {\n        orderId = urlMatch[1];\n      }\n    }\n\n    // 从消息内容的 dxCard/tip 中提取订单ID（备用方案）\n    if (!orderId) {\n      try {\n        const msg6 = msg1[\"6\"] || msg1[6];\n        if (msg6) {\n          const msg63 = msg6[\"3\"] || msg6[3];\n          if (msg63) {\n            const cardJson = msg63[\"5\"] || msg63[5];\n            if (cardJson) {\n              const card = JSON.parse(cardJson);\n              // 从 tip.argInfo.args.orderId 提取（蚂蚁森林能量等消息）\n              const tipOrderId = card?.tip?.argInfo?.args?.orderId;\n              if (tipOrderId && /^\\d{15,}$/.test(tipOrderId)) {\n                orderId = tipOrderId;\n              }\n              // 从 main.targetUrl 提取 (fleamarket://order_detail?id=xxx)\n              if (!orderId) {\n                const mainTargetUrl = card?.dxCard?.item?.main?.targetUrl;\n                if (mainTargetUrl) {\n                  const match = mainTargetUrl.match(/[?&]id=(\\d{15,})/);\n                  if (match) orderId = match[1];\n                }\n              }\n              // 从 button targetUrl 提取 (orderId=xxx)\n              if (!orderId) {\n                const btnUrl =\n                  card?.dxCard?.item?.main?.exContent?.button?.targetUrl;\n                if (btnUrl) {\n                  const match = btnUrl.match(\n                    /orderId=(\\d{15,})|bizOrderId=(\\d{15,})/,\n                  );\n                  if (match) orderId = match[1] || match[2];\n                }\n              }\n              // 从 dynamicOperation.changeContent.dxCard 提取（已付款待发货等消息）\n              if (!orderId) {\n                const changeTargetUrl =\n                  card?.dynamicOperation?.changeContent?.dxCard?.item?.main\n                    ?.targetUrl;\n                if (changeTargetUrl) {\n                  const match = changeTargetUrl.match(/[?&]id=(\\d{15,})/);\n                  if (match) orderId = match[1];\n                }\n              }\n              // 从 dynamicOperation.changeContent.dxCard.button 提取\n              if (!orderId) {\n                const changeBtnUrl =\n                  card?.dynamicOperation?.changeContent?.dxCard?.item?.main\n                    ?.exContent?.button?.targetUrl;\n                if (changeBtnUrl) {\n                  const match = changeBtnUrl.match(\n                    /[?&]id=(\\d{15,})|orderId=(\\d{15,})/,\n                  );\n                  if (match) orderId = match[1] || match[2];\n                }\n              }\n            }\n          }\n        }\n      } catch {\n        // 忽略解析失败\n      }\n    }\n\n    const msgTime = createTime\n      ? new Date(createTime).toLocaleString(\"zh-CN\", { hour12: false })\n      : new Date().toLocaleString(\"zh-CN\", { hour12: false });\n\n    // 检查是否是订单状态消息\n    const isOrderMessage = isOrderStatusMessage(content);\n\n    // 过滤自己的消息（但订单状态消息除外，因为可能是系统发送的）\n    if (senderId === myId && !isOrderMessage) {\n      logger.debug(`[${msgTime}] 忽略自己发送的消息`);\n      return null;\n    }\n\n    // 过滤纯系统消息（不包含有用信息的）\n    if (isSystemMessage(content)) {\n      logger.debug(`[${msgTime}] 系统消息不处理: ${content}`);\n      return null;\n    }\n\n    // 过滤空消息\n    if (!content || content.trim() === \"\") {\n      logger.debug(`[${msgTime}] 忽略空消息`);\n      return null;\n    }\n\n    // 订单状态消息特殊日志\n    if (isOrderMessage && orderId) {\n      logger.info(\n        `[${msgTime}] 订单状态消息 - 订单ID: ${orderId}, 状态: ${orderStatus || content}`,\n      );\n    }\n\n    return {\n      senderId,\n      senderName,\n      msgTime,\n      content,\n      chatId,\n      msgId,\n      raw: message,\n      orderId,\n      orderStatus,\n      isOrderMessage,\n    };\n  } catch (e) {\n    logger.error(`提取聊天消息失败: ${e}`);\n    return null;\n  }\n}\n"
  },
  {
    "path": "src/goofish/websocket/message.receiver.ts",
    "content": "import { createLogger } from \"../core/logger\";\nimport {\n  decryptSyncData,\n  extractChatMessage,\n  isOrderStatusMessage,\n} from \"./message.parser\";\nimport { checkAutoReply, handleUserReply } from \"../services/index\";\nimport { addRawMessage } from \"../api/routes/dev-messages.route\";\nimport type { ChatMessage, MessageCallback } from \"../types/index\";\nimport type { GoofishClient } from \"./client\";\n\nconst logger = createLogger(\"Ws:Receiver\");\n\nexport interface MessageReceiverContext {\n  accountId: string;\n  myId: string;\n  client?: GoofishClient;\n  onMessage?: MessageCallback;\n  onAutoReply?: (\n    chatId: string,\n    senderId: string,\n    content: string,\n  ) => Promise<boolean | void>;\n}\n\n/**\n * 处理同步消息数据\n */\nexport async function handleSyncMessage(\n  msgData: any,\n  ctx: MessageReceiverContext,\n): Promise<ChatMessage[]> {\n  const { accountId, myId, onMessage, onAutoReply } = ctx;\n  const body = msgData.body || {};\n  let dataList: any[] = [];\n\n  if (body.syncPushPackage?.data) {\n    dataList = body.syncPushPackage.data;\n    logger.debug(\n      `[${accountId}] 从 syncPushPackage.data 获取到 ${dataList.length} 条数据`,\n    );\n  } else if (Array.isArray(body.data)) {\n    dataList = body.data;\n    logger.debug(\n      `[${accountId}] 从 body.data 获取到 ${dataList.length} 条数据`,\n    );\n  } else if (Array.isArray(body)) {\n    dataList = body;\n    logger.debug(\n      `[${accountId}] body 本身是数组，包含 ${dataList.length} 条数据`,\n    );\n  }\n\n  if (dataList.length === 0) {\n    logger.debug(`[${accountId}] 没有数据需要处理`);\n    return [];\n  }\n\n  const messages: ChatMessage[] = [];\n\n  for (const item of dataList) {\n    const data = typeof item === \"object\" ? item.data || item : item;\n    if (!data) {\n      logger.debug(`[${accountId}] 跳过空数据项`);\n      continue;\n    }\n\n    logger.debug(\n      `[${accountId}] 尝试解密数据: ${typeof data === \"string\" ? data.substring(0, 50) + \"...\" : JSON.stringify(data).substring(0, 50) + \"...\"}`,\n    );\n\n    const message = decryptSyncData(data);\n    if (!message) {\n      logger.debug(`[${accountId}] 解密失败或非聊天消息`);\n      continue;\n    }\n\n    const chatMsg = extractChatMessage(message, myId);\n    if (!chatMsg) {\n      logger.debug(`[${accountId}] 提取聊天消息失败`);\n      continue;\n    }\n\n    logger.info(\n      `[${accountId}] [${chatMsg.msgTime}] 收到消息 - 发送者: ${chatMsg.senderName}, chatId: ${chatMsg.chatId}, 内容: ${chatMsg.content}${chatMsg.orderId ? `, 订单ID: ${chatMsg.orderId}` : \"\"}`,\n    );\n    messages.push(chatMsg);\n\n    // 订单状态消息不触发自动回复\n    if (chatMsg.isOrderMessage) {\n      logger.debug(`[${accountId}] 订单状态消息，跳过自动回复检查`);\n    } else {\n      // 先检查是否有等待中的工作流程需要继续执行\n      if (ctx.client && chatMsg.chatId) {\n        const workflowHandled = await handleUserReply(\n          accountId,\n          chatMsg.chatId,\n          chatMsg.senderId,\n          chatMsg.content,\n          ctx.client,\n        );\n        if (workflowHandled) {\n          logger.info(`[${accountId}] 用户回复已触发工作流程继续执行`);\n        }\n      }\n\n      // 检查自动回复规则\n      const autoReplyResult = await checkAutoReply(accountId, chatMsg);\n      if (\n        autoReplyResult.matched &&\n        autoReplyResult.replyContent &&\n        chatMsg.chatId &&\n        onAutoReply\n      ) {\n        await onAutoReply(\n          chatMsg.chatId,\n          chatMsg.senderId,\n          autoReplyResult.replyContent,\n        );\n      }\n    }\n\n    if (onMessage) {\n      await onMessage(accountId, chatMsg);\n    }\n  }\n\n  return messages;\n}\n\n/**\n * 处理 WebSocket 消息\n */\nexport async function processWebSocketMessage(\n  msgData: any,\n  ctx: MessageReceiverContext,\n  sendAck: (headers: any) => void,\n): Promise<void> {\n  const { accountId } = ctx;\n\n  try {\n    const lwp = msgData.lwp || \"\";\n\n    // 忽略响应消息\n    if (msgData.code === 200) return;\n\n    // 注册响应\n    if (lwp === \"/r\") {\n      const code = msgData.headers?.code;\n      if (code === \"200\" || code === 200) {\n        logger.info(`[${accountId}] WebSocket注册成功`);\n      } else {\n        logger.error(\n          `[${accountId}] WebSocket注册失败: ${JSON.stringify(msgData)}`,\n        );\n      }\n      return;\n    }\n\n    // 同步消息 - 添加到开发调试缓冲区\n    if (lwp === \"/s/sync\" || lwp.toLowerCase().includes(\"/sync\")) {\n      logger.debug(`[${accountId}] 收到同步消息: ${lwp}`);\n      addRawMessage(accountId, msgData);\n      sendAck(msgData.headers);\n      await handleSyncMessage(msgData, ctx);\n      return;\n    }\n\n    // 推送消息 - 添加到开发调试缓冲区\n    if (lwp === \"/p\") {\n      logger.debug(`[${accountId}] 收到推送消息`);\n      addRawMessage(accountId, msgData);\n      sendAck(msgData.headers);\n      if (msgData?.body?.syncPushPackage?.data?.length > 0 || msgData?.body) {\n        await handleSyncMessage(msgData, ctx);\n      }\n      return;\n    }\n\n    // 其他消息类型\n    if (lwp) {\n      logger.debug(`[${accountId}] 收到其他消息类型: ${lwp}`);\n    }\n  } catch (e) {\n    logger.error(`[${accountId}] 处理消息异常: ${e}`);\n  }\n}\n"
  },
  {
    "path": "src/goofish/websocket/message.sender.ts",
    "content": "import WebSocket from \"ws\";\nimport { createLogger } from \"../core/logger\";\nimport { generateMid, generateUuid } from \"../utils/crypto\";\nimport { conversationStore } from \"../api/stores/conversation.store\";\n\nconst logger = createLogger(\"Ws:Sender\");\n\nexport interface SendMessageOptions {\n  accountId: string;\n  myId: string;\n  ws: WebSocket;\n  chatId: string;\n  toUserId: string;\n  text: string;\n}\n\n/**\n * 发送消息到指定用户\n */\nexport async function sendMessage(\n  options: SendMessageOptions,\n): Promise<boolean> {\n  const { accountId, myId, ws, chatId, toUserId, text } = options;\n\n  if (!ws || ws.readyState !== WebSocket.OPEN) {\n    logger.error(`[${accountId}] WebSocket未连接，无法发送消息`);\n    return false;\n  }\n\n  try {\n    const textContent = { contentType: 1, text: { text } };\n    const textBase64 = Buffer.from(JSON.stringify(textContent)).toString(\n      \"base64\",\n    );\n\n    const msg = {\n      lwp: \"/r/MessageSend/sendByReceiverScope\",\n      headers: { mid: generateMid() },\n      body: [\n        {\n          uuid: generateUuid(),\n          cid: `${chatId}@goofish`,\n          conversationType: 1,\n          content: { contentType: 101, custom: { type: 1, data: textBase64 } },\n          redPointPolicy: 0,\n          extension: { extJson: \"{}\" },\n          ctx: { appVersion: \"1.0\", platform: \"web\" },\n          mtags: {},\n          msgReadStatusSetting: 1,\n        },\n        { actualReceivers: [`${toUserId}@goofish`, `${myId}@goofish`] },\n      ],\n    };\n\n    ws.send(JSON.stringify(msg));\n    logger.info(`[${accountId}] 消息已发送到 ${toUserId}: ${text}`);\n\n    // 记录发出的消息\n    conversationStore.addOutgoing(accountId, chatId, toUserId, text);\n\n    return true;\n  } catch (e) {\n    logger.error(`[${accountId}] 发送消息失败: ${e}`);\n    return false;\n  }\n}\n"
  },
  {
    "path": "src/goofish/websocket/token.ts",
    "content": "import { WS_CONFIG, API_ENDPOINTS, PASSPORT_CONFIG } from \"../core/constants\";\nimport { CookiesManager } from \"../core/cookies.manager\";\nimport { generateSign } from \"../utils/crypto\";\nimport { createLogger } from \"../core/logger\";\n\nconst logger = createLogger(\"Ws:Token\");\n\n// Session 过期错误标识\nconst SESSION_EXPIRED_ERRORS = [\"FAIL_SYS_SESSION_EXPIRED\", \"SESSION_EXPIRED\"];\n\nexport class TokenManager {\n  private currentToken: string | null = null;\n  private lastRefreshTime = 0;\n  private deviceId: string;\n  private accountId: string;\n\n  constructor(accountId: string, deviceId: string) {\n    this.accountId = accountId;\n    this.deviceId = deviceId;\n  }\n\n  getToken(): string | null {\n    return this.currentToken;\n  }\n\n  isExpired(): boolean {\n    return (\n      !this.currentToken ||\n      Date.now() - this.lastRefreshTime >=\n        WS_CONFIG.TOKEN_REFRESH_INTERVAL * 1000\n    );\n  }\n\n  // 调用 hasLogin 接口刷新登录状态\n  private async hasLogin(retryCount = 0): Promise<boolean> {\n    if (retryCount >= 2) {\n      logger.error(`[${this.accountId}] hasLogin 检查失败，重试次数过多`);\n      return false;\n    }\n\n    try {\n      // 每次从数据库获取最新 cookies\n      const cookiesStr = CookiesManager.getCookies(this.accountId);\n      const cookies = CookiesManager.getCookiesObject(this.accountId);\n\n      if (!cookiesStr) {\n        logger.error(`[${this.accountId}] 无法获取 cookies`);\n        return false;\n      }\n\n      const url = `${PASSPORT_CONFIG.BASE_URL}/newlogin/hasLogin.do`;\n      const params = new URLSearchParams({\n        appName: \"xianyu\",\n        fromSite: \"77\",\n      });\n\n      const formData = new URLSearchParams({\n        hid: cookies[\"unb\"] || \"\",\n        ltl: \"true\",\n        appName: \"xianyu\",\n        appEntrance: \"web\",\n        _csrf_token: cookies[\"XSRF-TOKEN\"] || \"\",\n        umidToken: \"\",\n        hsiz: cookies[\"cookie2\"] || \"\",\n        bizParams: \"taobaoBizLoginFrom=web\",\n        mainPage: \"false\",\n        isMobile: \"false\",\n        lang: \"zh_CN\",\n        returnUrl: \"\",\n        fromSite: \"77\",\n        isIframe: \"true\",\n        documentReferer: \"https://www.goofish.com/\",\n        defaultView: \"hasLogin\",\n        umidTag: \"SERVER\",\n        deviceId: cookies[\"cna\"] || \"\",\n      });\n\n      const res = await fetch(`${url}?${params}`, {\n        method: \"POST\",\n        headers: {\n          accept: \"application/json\",\n          \"content-type\": \"application/x-www-form-urlencoded\",\n          origin: \"https://www.goofish.com\",\n          referer: \"https://www.goofish.com/\",\n          \"user-agent\":\n            \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\",\n          cookie: cookiesStr,\n        },\n        body: formData.toString(),\n      });\n\n      // 处理 Set-Cookie，自动更新到数据库\n      CookiesManager.handleResponseCookies(this.accountId, res);\n\n      const resJson = await res.json();\n\n      if (resJson?.content?.success) {\n        logger.info(`[${this.accountId}] hasLogin 验证成功`);\n        return true;\n      }\n\n      logger.warn(\n        `[${this.accountId}] hasLogin 验证失败: ${JSON.stringify(resJson)}`,\n      );\n      await new Promise((r) => setTimeout(r, 500));\n      return this.hasLogin(retryCount + 1);\n    } catch (e) {\n      logger.error(`[${this.accountId}] hasLogin 请求异常: ${e}`);\n      await new Promise((r) => setTimeout(r, 500));\n      return this.hasLogin(retryCount + 1);\n    }\n  }\n\n  // 检查是否为 Session 过期错误\n  private isSessionExpiredError(error: string): boolean {\n    return SESSION_EXPIRED_ERRORS.some((e) => error.includes(e));\n  }\n\n  // 执行单次 token 请求\n  private async doTokenRequest(): Promise<{\n    success: boolean;\n    token?: string;\n    cookiesUpdated: boolean;\n    error?: string;\n  }> {\n    // 每次从数据库获取最新 cookies\n    const cookiesStr = CookiesManager.getCookies(this.accountId);\n    if (!cookiesStr) {\n      return {\n        success: false,\n        cookiesUpdated: false,\n        error: \"无法获取 cookies\",\n      };\n    }\n\n    const timestamp = Date.now().toString();\n    const dataVal = JSON.stringify({\n      appKey: WS_CONFIG.APP_KEY,\n      deviceId: this.deviceId,\n    });\n    const h5Token = CookiesManager.getH5Token(this.accountId);\n    const sign = generateSign(timestamp, h5Token, dataVal);\n\n    const params = new URLSearchParams({\n      jsv: \"2.7.2\",\n      appKey: WS_CONFIG.SIGN_APP_KEY,\n      t: timestamp,\n      sign,\n      v: \"1.0\",\n      type: \"originaljson\",\n      accountSite: \"xianyu\",\n      dataType: \"json\",\n      timeout: \"20000\",\n      api: \"mtop.taobao.idlemessage.pc.login.token\",\n      sessionOption: \"AutoLoginOnly\",\n    });\n\n    const res = await fetch(`${API_ENDPOINTS.TOKEN}?${params}`, {\n      method: \"POST\",\n      headers: {\n        accept: \"application/json\",\n        \"content-type\": \"application/x-www-form-urlencoded\",\n        origin: \"https://www.goofish.com\",\n        referer: \"https://www.goofish.com/\",\n        \"user-agent\":\n          \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\",\n        cookie: cookiesStr,\n      },\n      body: `data=${encodeURIComponent(dataVal)}`,\n    });\n\n    // 处理 Set-Cookie，自动更新到数据库\n    const cookiesUpdated = CookiesManager.handleResponseCookies(\n      this.accountId,\n      res,\n    );\n    const resJson = await res.json();\n\n    if (\n      resJson?.ret?.some((r: string) => r.includes(\"SUCCESS\")) &&\n      resJson?.data?.accessToken\n    ) {\n      return { success: true, token: resJson.data.accessToken, cookiesUpdated };\n    }\n\n    const errorMsg = resJson?.ret?.join(\", \") || \"Unknown error\";\n    return { success: false, cookiesUpdated, error: errorMsg };\n  }\n\n  async refresh(): Promise<string | null> {\n    try {\n      logger.info(`[${this.accountId}] 开始刷新Token...`);\n\n      // 第一次请求\n      let result = await this.doTokenRequest();\n\n      // 如果失败但 cookies 更新了（token 过期场景），用新 token 重试\n      if (!result.success && result.cookiesUpdated) {\n        logger.info(`[${this.accountId}] Token过期，使用新Cookies重试...`);\n        result = await this.doTokenRequest();\n      }\n\n      // 如果仍然失败且是 Session 过期错误，尝试 hasLogin 刷新\n      if (\n        !result.success &&\n        result.error &&\n        this.isSessionExpiredError(result.error)\n      ) {\n        logger.info(`[${this.accountId}] Session过期，尝试 hasLogin 刷新...`);\n        const loginSuccess = await this.hasLogin();\n        if (loginSuccess) {\n          logger.info(`[${this.accountId}] hasLogin 成功，重新获取Token...`);\n          result = await this.doTokenRequest();\n          // hasLogin 后可能还需要处理 token 更新\n          if (!result.success && result.cookiesUpdated) {\n            result = await this.doTokenRequest();\n          }\n        }\n      }\n\n      if (result.success && result.token) {\n        this.currentToken = result.token;\n        this.lastRefreshTime = Date.now();\n        logger.info(`[${this.accountId}] Token刷新成功`);\n        return this.currentToken;\n      }\n\n      logger.error(`[${this.accountId}] Token刷新失败: ${result.error}`);\n      return null;\n    } catch (e) {\n      logger.error(`[${this.accountId}] Token刷新异常: ${e}`);\n      return null;\n    }\n  }\n}\n"
  },
  {
    "path": "src/hooks/goofish/index.ts",
    "content": "export { useGoofishWebSocket } from './useWebSocket'\n"
  },
  {
    "path": "src/hooks/goofish/useWebSocket.ts",
    "content": "import { useEffect, useState, useRef } from 'react'\nimport { statusApi } from '@/services/goofish'\n\ninterface UseWebSocketOptions {\n  onMessage?: (data: any) => void\n  onError?: (error: Event) => void\n  reconnectInterval?: number\n}\n\nexport function useGoofishWebSocket(options: UseWebSocketOptions = {}) {\n  const [connected, setConnected] = useState(false)\n  const [status, setStatus] = useState<any>(null)\n  const [wsInstance, setWsInstance] = useState<WebSocket | null>(null)\n  const wsRef = useRef<WebSocket | null>(null)\n  const reconnectTimerRef = useRef<NodeJS.Timeout | null>(null)\n  const { onMessage, onError, reconnectInterval = 5000 } = options\n\n  // 连接 WebSocket\n  const connect = () => {\n    if (wsRef.current?.readyState === WebSocket.OPEN) {\n      return\n    }\n\n    const ws = new WebSocket('ws://localhost:3001/ws')\n    wsRef.current = ws\n\n    ws.onopen = () => {\n      console.log('Goofish WebSocket connected')\n      setConnected(true)\n      setWsInstance(ws)\n    }\n\n    ws.onclose = () => {\n      console.log('Goofish WebSocket disconnected')\n      setConnected(false)\n      setWsInstance(null)\n\n      // 自动重连\n      if (reconnectTimerRef.current) {\n        clearTimeout(reconnectTimerRef.current)\n      }\n      reconnectTimerRef.current = setTimeout(() => {\n        console.log('Reconnecting to Goofish WebSocket...')\n        connect()\n      }, reconnectInterval)\n    }\n\n    ws.onerror = (error) => {\n      console.error('Goofish WebSocket error:', error)\n      onError?.(error)\n    }\n\n    ws.onmessage = (event) => {\n      try {\n        const data = JSON.parse(event.data)\n        onMessage?.(data)\n      } catch (e) {\n        console.error('Failed to parse WebSocket message:', e)\n      }\n    }\n  }\n\n  // 断开连接\n  const disconnect = () => {\n    if (reconnectTimerRef.current) {\n      clearTimeout(reconnectTimerRef.current)\n    }\n    if (wsRef.current) {\n      wsRef.current.close()\n      wsRef.current = null\n    }\n    setConnected(false)\n  }\n\n  // 获取状态\n  const fetchStatus = async () => {\n    try {\n      const response = await statusApi.getStatus()\n      setStatus(response.data)\n    } catch (error) {\n      console.error('Failed to fetch status:', error)\n    }\n  }\n\n  useEffect(() => {\n    connect()\n    fetchStatus()\n\n    return () => {\n      disconnect()\n    }\n  }, [])\n\n  return {\n    connected,\n    status,\n    refetchStatus: fetchStatus,\n    ws: wsInstance\n  }\n}\n"
  },
  {
    "path": "src/hooks/useChangeLanguage.ts",
    "content": "import { useCallback } from 'react'\nimport { useTranslation } from 'react-i18next'\n\nexport const useChangeLanguage = () => {\n  const { i18n } = useTranslation()\n\n  const changeLanguage = useCallback((lang: string) => {\n    i18n.changeLanguage(lang)\n    localStorage.setItem('language', lang)\n    document.documentElement.lang = lang\n  }, [i18n])\n\n  return changeLanguage\n}\n"
  },
  {
    "path": "src/i18n/config.ts",
    "content": "import i18n from 'i18next'\nimport { initReactI18next } from 'react-i18next'\nimport LanguageDetector from 'i18next-browser-languagedetector'\nimport zh from './locales/zh'\nimport en from './locales/en'\nimport { detectLanguageFromIP } from '../utils/checkIp'\n\n// 从 localStorage 获取保存的语言设置\nconst savedLanguage = localStorage.getItem('language')\n\n// 如果有保存的语言设置，直接使用；否则使用默认 'zh'，稍后通过 IP 检测更新\nconst initialLanguage = savedLanguage || 'zh'\n\n// 初始化 i18n\ni18n\n  .use(LanguageDetector) // 自动检测用户语言\n  .use(initReactI18next) // 绑定 react-i18next\n  .init({\n    resources: {\n      zh: {\n        translation: zh.translation\n      },\n      en: {\n        translation: en.translation\n      }\n    },\n    lng: initialLanguage, // 初始语言\n    fallbackLng: 'zh', // 回退语言\n    interpolation: {\n      escapeValue: false // React 已经防止 XSS\n    },\n    detection: {\n      // 优先使用 localStorage，其次使用我们自定义的 IP 检测\n      order: ['localStorage'],\n      caches: ['localStorage']\n    }\n  })\n\n// 如果没有保存的语言设置，异步检测 IP 归属地并更新语言\nif (!savedLanguage) {\n  detectLanguageFromIP().then((detectedLanguage) => {\n    // 只在检测到的语言与当前不同时才更新\n    if (detectedLanguage !== i18n.language) {\n      i18n.changeLanguage(detectedLanguage)\n      localStorage.setItem('language', detectedLanguage)\n      console.log('Language detected from IP location:', detectedLanguage)\n    }\n  })\n}\n\nexport default i18n\n"
  },
  {
    "path": "src/i18n/locales/en/about.ts",
    "content": "export default {\n  title: 'About Me (Looking for referrals~)',\n  role: 'A full-stack technology enthusiast',\n  name: '0x3f',\n  description: 'The ultimate invincible super explosive tyrannosaurus warrior',\n  contact: 'Contact',\n  wechat: 'WeChat: Dveiklokk',\n  internship: 'Internship Experience',\n  internship1: 'Bachelor\\'s degree from non-double-first-class university, Master\\'s from 211 double-first-class university',\n  internship2: 'Worked at Meituan, Huawei, Tencent',\n  awards: 'Awards',\n  award1: 'Software Engineer (Intermediate Level)',\n  award2: 'Two patents, two software copyrights',\n  award3: 'CCF-C CAS one-zone TOP journal paper, CCF-B CAS two-zone journal paper, EI conference publications, journal paper',\n  award4: 'CET-4, Computer Network Technology Level 3',\n  award5: 'National First Prize in Mathematical Modeling',\n  award6: 'National Third Prize in Lanqiao Cup Java, Provincial Second in Programming Competition',\n  award7: 'Provincial First Prize in NETCCS and Provincial Second Prize in FLTRP English Competition',\n  award8: 'Provincial Second Prize in Innovation and Entrepreneurship Competition',\n  award9: 'University Scholarship, National Endeavor Scholarship',\n  supportMe: 'Support Me',\n  addMe: 'Add Me',\n  email: 'Email: 891523233@qq.com',\n  products: 'Featured Products',\n  loadingProducts: 'Loading products...',\n  autoDelivery: 'Auto Delivery',\n  stockShort: 'Stock Shortage',\n  noProducts: 'No products available',\n  digitalGoodsNotice: 'Digital Goods Purchase Notice',\n  importantNotice: 'By purchasing products on this platform, you agree to the service provider\\'s terms of service. The products are digital products, and once sold, they are not returnable or exchangeable. By placing an order, you acknowledge that you have fully understood the product information and voluntarily accept the risk associated with the purchase.',\n  projectExperience: 'Project Experience',\n  technologyStack: 'Technology Stack',\n  deliveryQuality: 'Delivery Quality',\n}\n"
  },
  {
    "path": "src/i18n/locales/en/aimarkmap.ts",
    "content": "const aimarkmap = {\n  promptSettingsBtn: '📝 Prompt Settings',\n  apiSettingsBtn: '⚙️ API Settings',\n  modelLabel: 'Model:',\n  modelLabelMobile: 'Model Select:',\n  queryBtn: '🔍 Query',\n  versionsLabel: 'Versions:',\n  generateBtn: 'AI Generate',\n  showOriginalBtn: 'Original',\n  showMarkdownBtn: 'Markdown',\n  clearBtn: 'Clear',\n  fullscreenBtn: 'Fullscreen',\n  exportPngBtn: 'Export PNG',\n  exportSvgBtn: 'Export SVG',\n  mindmapPreviewTitle: '🧠 Mind Map Preview',\n  thinkingMessage: 'AI is thinking...',\n  apiSettingsTitle: '⚙️ API Settings',\n  apiUrlLabel: 'API URL:',\n  apiKeyLabel: 'API Key:',\n  saveAndCloseBtn: '💾 Save & Close',\n  promptSettingsTitle: '📝 Prompt Settings',\n  promptTip: 'Please make sure to include <code>{{CONTENT}}</code> in the prompt template, which will be replaced with the input content from the left.',\n  editNodeTitle: '✏️ Edit Node',\n  deleteNodeBtn: '🗑️ Delete Node',\n  helpBtnTitle: 'Help & Information',\n  infoModalTitle: 'Instructions, Terms & Privacy Policy',\n  infoModalContentHtml: `\n    <h2>Instructions</h2>\n    <ul>\n      <li><strong>API Settings:</strong> On first use, click the <code>⚙️ API Settings</code> button in the top right to enter the API URL and Key provided by your AI service provider. The configuration will be saved locally in your browser.</li>\n      <li><strong>Model Selection:</strong> In the left panel, select or enter the AI model you want to use. Click <code>🔍 Query</code> to automatically fetch a list of supported models from the API URL.</li>\n      <li><strong>Content Input:</strong> In the largest input box on the left, you can enter descriptive text or paste pre-formatted Markdown content.</li>\n      <li><strong>AI Generation:</strong> After entering descriptive text, use the slider to select the number of different versions you want the AI to generate (1-5), then click <code>🚀 AI Generate</code>.</li>\n      <li><strong>Switching Versions:</strong> After successful generation, version tabs (e.g., \"Version 1\", \"Version 2\") will appear above the mind map preview area. Click to view different versions.</li>\n      <li><strong>Editing and Viewing:</strong>\n        <ul style=\"margin-top: 0.5rem;\">\n          <li>On the mind map, <strong>right-click</strong> any node to select <strong>\"Edit Node\"</strong> or <strong>\"Delete Node\"</strong>.</li>\n          <li>The <code>📝 Show Markdown</code> button on the left allows you to view and edit the AI-generated Markdown source.</li>\n        </ul>\n      </li>\n      <li><strong>Export & Fullscreen:</strong> Use the buttons in the top right of the preview area to export the current mind map as an <code>SVG</code> or <code>PNG</code> image, or enter fullscreen mode.</li>\n    </ul>\n    <h2>Terms of Service</h2>\n    <p>By using AiMarkmap, you agree to the following terms:</p>\n    <ul>\n      <li>You are solely responsible for all content (including text, API keys, etc.) you input into this product. You must ensure that the input content does not infringe on any third-party rights and does not violate any applicable laws and regulations.</li>\n      <li>You are prohibited from using this product for any form of malicious activity, including but not limited to, making a large number of unreasonable API requests, disseminating illegal information, or attacking third-party services.</li>\n    </ul>\n    <h2>Privacy Policy</h2>\n    <p>We take your privacy very seriously. Please read the following information carefully about how we handle your data:</p>\n    <h3>Data Collection</h3>\n    <p>This product primarily handles two types of data:</p>\n    <ul>\n      <li><strong>Configuration Information:</strong> The API URL, API Key, selected model, and other settings you enter. This information is stored <strong>only on your own computer</strong> using the browser's <code>localStorage</code> technology to simplify your subsequent use and is not uploaded to AiMarkmap's servers.</li>\n      <li><strong>Input Content:</strong> The text content you provide to generate mind maps.</li>\n    </ul>\n    <p>This product <strong>does not use</strong> any third-party analytics tools (like Google Analytics) to track your personal behavior.</p>\n    <h3>Data Usage</h3>\n    <p>All of your data processing is done on the <strong>client-side (in your browser)</strong>. The process is as follows:</p>\n    <ul>\n      <li>Your API key and input content are combined into a request by your browser and sent directly to the third-party AI service you specify in the settings (such as OpenAI, Google AI, etc.) only when you click the \"AI Generate\" button.</li>\n      <li><strong>AiMarkmap's servers do not store, proxy, or have any visibility into</strong> your API key and input content. The data transmission path is: Your Browser -> Your Specified AI Service Provider.</li>\n    </ul>\n    <h3>Third-Party Services</h3>\n    <p>As a client-side tool, this product calls third-party AI services based on your configuration. The data you send is subject to the privacy policy and data usage terms of the AI service provider you use. We strongly recommend that you review the official privacy policies of the respective service providers before use.</p>\n    <h2>Disclaimer</h2>\n    <ul>\n      <li><strong>Accuracy of AI-Generated Content:</strong> All content generated by AI models is for reference only. We do not guarantee its accuracy, completeness, or suitability. You need to judge for yourself and are responsible for all consequences arising from the use of these results.</li>\n      <li><strong>Service Availability:</strong> As this product relies on network connectivity and the stability of third-party API services, we do not promise that the service will be 100% uninterrupted or error-free. We do not assume any responsibility for service unavailability caused by network issues, API provider failures, or your own configuration errors.</li>\n    </ul>`,\n  customModelInputPlaceholder: 'Enter custom model name',\n  topicInputPlaceholder: 'Enter or paste Markdown directly, or input text and click \"AI Generate\"...',\n  contentDisplayPlaceholder: 'Edit content...',\n  apiUrlPlaceholder: 'AI API Address',\n  apiKeyPlaceholder: 'API Key',\n  toggleVisibilityTitle: 'Show/Hide Key',\n  promptInputPlaceholder: 'Edit AI Prompt template here...',\n  editNodePlaceholder: 'Enter the new content for the node...',\n  js_generating: 'Generating...',\n  js_exporting: 'Exporting...',\n  js_querying: 'Querying...',\n  js_exit_fullscreen: 'Exit Fullscreen',\n  js_fullscreen: 'Fullscreen',\n  js_status_requesting: 'Initiating AI request...',\n  js_status_generated: 'Successfully generated {{s}}/{{n}} versions...',\n  js_status_done: 'Generation complete! {{n}} valid versions available.',\n  js_tab_version: 'Version {{i}}',\n  js_alert_no_content: 'Please enter content first!',\n  js_alert_all_failed: 'All AI generation requests failed or returned empty content. Please check API settings and network.',\n  js_alert_gen_failed: 'AI generation failed: {{msg}}',\n  js_alert_no_clipboard: \"Your browser does not support the Clipboard API. Please paste the content manually.\",\n  js_alert_clipboard_empty: 'Clipboard is empty.',\n  js_alert_clipboard_error: 'Could not read from clipboard.\\nPlease ensure the page is active and has permission to read the clipboard.',\n  js_alert_query_no_config: 'Please configure API URL and Key in settings first!',\n  js_alert_query_failed: 'Query models failed: {{msg}}',\n  js_alert_query_success: 'Successfully fetched {{n}} available models!',\n  js_alert_no_mindmap: 'Could not find the mind map to export.',\n  js_alert_export_error: 'An error occurred while exporting the {{type}} image. Please try again later.',\n  js_zoom_in: 'Zoom In',\n  js_zoom_out: 'Zoom Out',\n  js_reset_zoom: 'Reset Zoom',\n  mobileTabEditor: 'Edit',\n  mobileTabMindmap: 'Map',\n  mobileTabLandscape: 'Rotate',\n  mobileCloseLandscape: 'Exit',\n  defaultMarkdown: `# 🤖 AI Mind Map Generation - AiMarkmap\n\n## ✨ Features\n### 🎯 Smart Generation\n- ✨ **Custom number of versions (1-5)**\n- AI-driven content creation\n### 🔧 Custom Configuration\n- Easy model selection\n- Prompt template configuration via modal\n- Personalized settings\n\n## 🚀 How to Use\n### 📝 Input Content\n- Describe content in the left input box\n- Or paste Markdown directly\n### 🤖 AI Processing\n- **Use the slider to select version count**\n- Click the generate button\n### 🎨 Visualization\n- **Click tabs to switch between versions**\n- Real-time mind map preview\n- One-click PNG export`,\n  defaultPrompt: `You are an expert in information architecture, skilled at extracting the structure and hierarchy of information. Please output the following content in Markdown format for a mind map: \"{{CONTENT}}\".\n\nPlease adhere to the following requirements:\n\n1.  Content Analysis:\n    - Analyze the inherent logical structure of the content and elaborate on the hierarchy as much as possible, expanding on each point.\n\n2.  Structural Requirements:\n    - Keep the structure clear for easy reading and parsing.\n    - Use clear hierarchies with #, ##, ###, etc., for different levels.\n    - Use the original language of the text for all nodes.\n    - Present items in the content as lists.\n    - The central topic should be around 10 words.\n    - There should be a minimum of 3 levels, with no maximum limit.\n    - If a level or branch contains too much text, split the content into same-level items or create deeper levels to keep the structure clean and concise.\n\n3.  Content Handling:\n    - Preserve the original sentences.\n    - Do not add explanations or extra comments.\n    - Do not add your own opinions or information outside the provided text.\n    - Minor sentence adjustments for clarity are acceptable.\n    - Long or complex sentences can be broken down into bullet points.\n\n4.  Enhance Visibility:\n    - Use Emoji to improve readability where appropriate.\n\n5.  Output Language:\n    - If the main content of the original text is not Chinese, output all Markdown content in the language of the original text.\n\n6.  Output Format:\n    - The final output must be in pure Markdown format.\n    - Output only the Markdown text itself.\n    - Do not wrap the output in code blocks.`\n}\n\nexport default aimarkmap\n"
  },
  {
    "path": "src/i18n/locales/en/cartoon.ts",
    "content": "export default {\n  title: 'Cartoon',\n  subTitle: 'Mercury Cartoon',\n  description: 'Discover more exciting cartoon works',\n  searchPlaceholder: 'Search cartoons...',\n  searchBtn: 'Search',\n  ranking: 'Ranking',\n  hot: 'Hot',\n  new: 'New',\n  finished: 'Finished',\n  ongoing: 'Ongoing',\n  chapters: 'Chapters',\n  startReading: 'Start Reading',\n  prevChapter: 'Previous Chapter',\n  nextChapter: 'Next Chapter',\n  noResults: 'No cartoons found',\n  noData: 'No data',\n  searchResults: 'Search results: found',\n  relatedCartoons: 'related cartoons',\n  enterKeyword: 'Please enter search keyword',\n  fetchRankTypesFailed: 'Failed to fetch ranking types',\n  fetchCartoonListFailed: 'Failed to fetch cartoon list',\n  searchFailed: 'Search failed, please try again later',\n  foundResults: 'Found X related cartoons'\n}\n"
  },
  {
    "path": "src/i18n/locales/en/cartoonChapter.ts",
    "content": "export default {\n  backToDetail: 'Back to Detail',\n  noContent: 'No chapter content found',\n  fetchChapterFailed: 'Failed to fetch chapter content',\n  alreadyFirstChapter: 'Already the first chapter',\n  alreadyLastChapter: 'Already the last chapter',\n  total: 'Total',\n  pages: 'pages',\n  page: 'Page',\n  backToTop: 'Back to Top'\n}\n"
  },
  {
    "path": "src/i18n/locales/en/cartoonDetail.ts",
    "content": "export default {\n  backToList: 'Back to List',\n  notFound: 'No cartoon information found',\n  fetchDetailFailed: 'Failed to fetch cartoon details',\n  author: 'Author',\n  status: 'Status',\n  likes: 'Likes',\n  tags: 'Tags',\n  intro: 'Introduction',\n  chapterList: 'Chapter List',\n  episode: 'Episode',\n  hua: ''\n}\n"
  },
  {
    "path": "src/i18n/locales/en/common.ts",
    "content": "export default {\n  chinese: '中文',\n  english: 'English',\n  logoutSuccess: 'Logged out successfully',\n  loading: 'Loading...',\n  submit: 'Submit',\n  cancel: 'Cancel',\n  confirm: 'Confirm',\n  search: 'Search',\n  delete: 'Delete',\n  edit: 'Edit',\n  save: 'Save',\n  back: 'Back',\n  more: 'More',\n  close: 'Close',\n  refresh: 'Refresh',\n  copy: 'Copy',\n  copySuccess: 'Copied successfully',\n  copyFailed: 'Copy failed',\n  download: 'Download',\n  downloadSuccess: 'Downloaded successfully',\n  downloadFailed: 'Download failed',\n  clear: 'Clear',\n  settings: 'Settings',\n  generate: 'Generate',\n  generating: 'Generating...',\n  siteVisits: 'Site visits today',\n  visitsUnit: 'visits',\n  copyright: '© Copyright 2023 P1Kaj1uu. All Rights Reserved.'\n}\n"
  },
  {
    "path": "src/i18n/locales/en/gold.ts",
    "content": "export default {\n  loading: 'Fetching real-time data...',\n  domesticGold: 'Domestic Gold',\n  internationalGold: 'International Gold',\n  high: 'High',\n  low: 'Low',\n  open: 'Open',\n  prevClose: 'Prev Close',\n  volume: 'Volume',\n  silver: 'Silver',\n  updateTime: 'Update Time',\n  priceTrend: 'Gold Price Trend',\n  '7days': '7 Days',\n  '30days': '30 Days',\n  '90days': '90 Days',\n  refresh: 'Refresh Data',\n  refreshSuccess: 'Refreshed successfully',\n  fetchPriceFailed: 'Failed to fetch gold price',\n  fetchChartFailed: 'Failed to fetch K-line data',\n  noChartData: 'No chart data available',\n  realtimeQuote: 'Real-time Quote',\n  tradingviewWarning: 'VPN required to access TradingView',\n  subscribeTitle: 'Subscribe to Gold Price',\n  subscribeTooltip: 'Subscribe to Gold Price',\n  subscribeDescription: 'You will receive email notifications when gold prices are updated',\n  emailPlaceholder: 'Enter your email address',\n  subscribe: 'Subscribe',\n  subscribeSuccess: 'Subscription successful! You will receive email notifications when gold prices are updated',\n  subscribeFailed: 'Subscription failed, please try again later',\n  invalidEmail: 'Please enter a valid email address',\n  emailNotConfigured: 'Email service not configured, please configure email.config.js first'\n}\n"
  },
  {
    "path": "src/i18n/locales/en/goofish.ts",
    "content": "const goofish = {\n  data: 'Goofish Data',\n  accounts: 'Accounts',\n  conversations: 'Conversations',\n  orders: 'Orders',\n  goods: 'Goods',\n  autoreply: 'Auto Reply',\n  autosell: 'Auto Sell',\n  workflow: 'Workflow Graph',\n  logs: 'System Logs',\n  assistant: 'Goofish Assistant',\n  home: 'Back Home'\n}\n\nexport default goofish\n"
  },
  {
    "path": "src/i18n/locales/en/gpt.ts",
    "content": "export default {\n  title: 'ChatGPT',\n  welcomeMessage: 'Hello! I am ChattyPlay AI assistant. I can help you with any questions, such as coding problems, study questions, sports questions, etc. How can I help you?',\n  placeholder: 'Enter your question...',\n  sendBtn: 'Send',\n  clearBtn: 'Clear Chat',\n  thinking: 'Thinking...',\n  error: 'An error occurred, please try again',\n  emptyMessage: 'Please enter a message',\n  copySuccess: 'Copied successfully!',\n  codeCopySuccess: 'Code copied successfully!',\n  replyComplete: 'Response complete',\n  replyInterrupted: 'Response interrupted, current content saved',\n  fallbackResponse: 'Sorry, I encountered an issue while processing your request. Please try again later.',\n  browserNotSupportSpeech: 'Your browser does not support speech synthesis',\n  speakStart: 'Starting speech...',\n  speakComplete: 'Speech completed',\n  speakError: 'Speech error',\n  feedbackLike: 'Thank you for your feedback!',\n  feedbackDislike: 'We will continue to improve!',\n  clearConfirmTitle: 'Confirm Clear',\n  clearConfirmContent: 'Are you sure you want to clear the current conversation?',\n  cleared: 'Conversation cleared',\n  userRole: 'User',\n  aiRole: 'AI Assistant',\n  exportSuccess: 'Chat history exported successfully!',\n  stopGenerate: 'Stop Generating',\n  typing: 'AI is typing...',\n  clearTooltip: 'Clear current conversation',\n  exportTooltip: 'Export current conversation',\n  enterToSend: 'Press Enter to send, Shift + Enter for new line',\n  subtitle: 'Intelligent Q&A, please ask questions in a standardized and healthy manner, AI answers are for reference only',\n  modelName: 'DeepSeek V3.2 Model',\n  copy: 'Copy',\n  readAloud: 'Read Aloud',\n  helpful: 'Helpful',\n  needsImprovement: 'Needs Improvement',\n  networkError: 'Network error, using fallback response',\n  exportFilename: 'ChattyPlay_AI_Conversation'\n}\n"
  },
  {
    "path": "src/i18n/locales/en/help.ts",
    "content": "export default {\n  title: 'Help',\n  description: 'Detailed tutorials and documentation to help you get started',\n  comingSoon: 'Content is under construction...',\n  chatgpt: {\n    title: 'ChatGPT Conversation',\n    description: 'Have intelligent conversations with powerful AI language models to get information and help. Enter your questions and AI will provide detailed answers.',\n    step1: 'Enter your question in the input box',\n    step2: 'Click send button or press Enter',\n    step3: 'Wait for AI response',\n    step4: 'You can copy, save or continue the conversation'\n  },\n  video: {\n    title: 'Video Parse',\n    description: 'Supports parsing video resources from multiple platforms. Get HD videos with one click. Enter video link to parse and download.',\n    step1: 'Get the video link you want to parse',\n    step2: 'Paste it into the input box',\n    step3: 'Click parse button',\n    step4: 'Select quality and click download'\n  },\n  music: {\n    title: 'Music Parse',\n    description: 'Parse music resources, supports multiple formats. Enter music link to parse and get high-quality audio.',\n    step1: 'Get the music link you want to parse',\n    step2: 'Paste it into the input box',\n    step3: 'Click parse button',\n    step4: 'Select quality and click download'\n  },\n  trans: {\n    title: 'Online Translation',\n    description: 'Supports multiple language translation, fast and accurate service. Enter text to translate to target language.',\n    step1: 'Enter or paste the text to translate',\n    step2: 'Select source and target languages',\n    step3: 'Click translate button',\n    step4: 'You can copy, download or listen to translation result'\n  },\n  textToPhoto: {\n    title: 'Text to Photo',\n    description: 'Convert text descriptions into beautiful images with unlimited creativity. Describe the image you want and AI will generate it for you.',\n    step1: 'Describe the image you want in detail',\n    step2: 'Select image style and size',\n    step3: 'Click generate image button',\n    step4: 'Wait for image generation to complete',\n    step5: 'You can download or regenerate'\n  },\n  faq: {\n    title: 'FAQ',\n    description: 'Answers to common questions users encounter during use.',\n    step1: 'What to do if parsing fails?',\n    step2: 'How to handle video playback issues?',\n    step3: 'How to solve inaccurate translation results?',\n    step4: 'How to save history records?'\n  },\n  stepsTitle: 'Usage Steps:'\n}\n"
  },
  {
    "path": "src/i18n/locales/en/home.ts",
    "content": "export default {\n  welcome: 'Welcome to ChattyPlay!',\n  description: 'A platform integrating multiple intelligent tools, providing you with music parsing, video parsing, AI dialogue and other features.',\n  features: {\n    music: {\n      title: 'Music Parse',\n      description: 'Search and play your favorite music, supporting multiple music platforms'\n    },\n    video: {\n      title: 'Video Parse',\n      description: 'Parse video resources from major video platforms, supporting multiple quality options'\n    },\n    trans: {\n      title: 'Paper Rewriter',\n      description: 'Intelligent text processing to help you optimize papers and documents'\n    },\n    chatgpt: {\n      title: 'ChatGPT',\n      description: 'Have intelligent conversations with powerful AI language models to get information and help'\n    },\n    cartoon: {\n      title: 'Cartoon',\n      description: 'Discover more exciting cartoon works, supporting search, rankings and chapter reading'\n    },\n    textToPhoto: {\n      title: 'Text to Photo',\n      description: 'Convert text descriptions into beautiful pictures with unlimited creativity'\n    },\n    help: {\n      title: 'Help',\n      description: 'Detailed tutorials and documentation to help you get started quickly'\n    },\n    papers: {\n      title: 'AI Papers',\n      description: 'Explore the latest AI research progress'\n    },\n    gold: {\n      title: 'Real-time Gold',\n      description: 'Real-time gold price and k-line chart, helping you make trading decisions'\n    },\n    goofish: {\n      title: 'Goofish Assistant',\n      description: 'Provides automatic trading, automatic reply, automatic monitoring and other functions on the Goofish platform, helping you easily buy and sell second-hand items'\n    },\n    worker: {\n      title: 'Agent Supervisor',\n      description: 'Monitor and manage your intelligent Agents, view their operational status online, handle exceptions promptly, simulate the work status of employees, and ensure Agents operate efficiently and stably'\n    },\n    markmap: {\n      title: 'Mind Map',\n      description: 'Convert text content into mind maps, helping you better organize and understand information, improve work efficiency, and save generated mind maps as images or Markdown format for easy sharing and use'\n    }\n  },\n  footer: {\n    slogan: '💗 The future is promising 💗',\n    thanks: 'Thank you for using ChattyPlay! I am committed to providing you with more practical and interesting features. Stay tuned for future updates and improvements!'\n  }\n}\n"
  },
  {
    "path": "src/i18n/locales/en/latex.ts",
    "content": "const latex = {\n  title: 'LaTeX Editor',\n  compile: 'Compile',\n  compiling: 'Compiling...',\n  compileSuccess: 'Compile successful',\n  compileError: 'Compile failed',\n  preview: 'PDF Preview',\n  files: 'Files',\n  addFile: 'New File',\n  deleteFile: 'Delete File',\n  renameFile: 'Rename',\n  page: 'Page {{current}} of {{total}}',\n  zoomIn: 'Zoom In',\n  zoomOut: 'Zoom Out',\n  fullscreen: 'Fullscreen',\n  exitFullscreen: 'Exit Fullscreen',\n  emptyHint: 'Click \"Compile\" to generate PDF',\n  retry: 'Retry',\n  timeout: 'Compile timeout, please try again',\n}\n\nexport default latex\n"
  },
  {
    "path": "src/i18n/locales/en/login.ts",
    "content": "export default {\n  account: 'Account',\n  accountPlaceholder: 'Enter your ChattyPlay account',\n  accountRequired: 'Please enter your ChattyPlay account',\n  password: 'Password',\n  passwordPlaceholder: 'Enter your ChattyPlay password',\n  passwordRequired: 'Please enter your ChattyPlay password',\n  passwordLength: 'Password length must be between 6 and 11 characters',\n  email: 'Email',\n  emailPlaceholder: 'Enter your email (optional)',\n  confirmPassword: 'Confirm Password',\n  confirmPasswordPlaceholder: 'Confirm your password',\n  confirmPasswordRequired: 'Please confirm your password',\n  confirmPasswordMismatch: 'Passwords do not match',\n  verifyCode: 'Verify Code',\n  verifyCodePlaceholder: 'Enter verify code',\n  verifyCodeRequired: 'Please enter verify code',\n  verifyCodeError: 'Incorrect verification code, please re-enter',\n  agree: 'Agree to terms',\n  agreeRequired: 'Please agree to the terms before logging in',\n  loginBtn: 'Login',\n  registerBtn: 'Register',\n  switchToLogin: 'Already have an account? Login',\n  switchToRegister: \"Don't have an account? Register\",\n  resetBtn: 'Reset',\n  forgetPassword: 'Forgot password?',\n  loginSuccess: 'Login successful!',\n  registerSuccess: 'Registration successful!',\n  loginFailed: 'Login failed, please try again',\n  registerFailed: 'Registration failed, please try again',\n  accountExists: 'Account already exists',\n  emailExists: 'Email already registered',\n  invalidEmail: 'Invalid email format',\n  forgetPasswordTip: 'Forgot password feature is under development...',\n  thirdPartyLoginTip: 'Or login with third-party account',\n  usernameLength: 'Username length must be between 3 and 20 characters',\n  passwordLengthRegister: 'Password length must be between 6 and 20 characters'\n}\n"
  },
  {
    "path": "src/i18n/locales/en/music.ts",
    "content": "export default {\n  title: 'Music Parse',\n  subTitle: 'Music',\n  description: 'Enter song name to play online, supports multiple music platforms',\n  placeholder: 'Enter song name',\n  searchBtn: 'Search',\n  clearBtn: 'Clear',\n  noKeywordTip: 'Please enter song name',\n  searchSuccess: 'Search successful',\n  searchFailed: 'Search failed, please try again',\n  noResults: 'No results found',\n  hotComments: 'Hot Comments',\n  mvNotAvailable: 'MV is not available',\n  fetchMVFailed: 'Failed to fetch MV',\n  fetchMusicFailed: 'Failed to fetch music, please check network connection and try again',\n}\n"
  },
  {
    "path": "src/i18n/locales/en/nav.ts",
    "content": "const nav = {\n  home: 'Home',\n  chatgpt: 'ChatGPT',\n  video: 'Video',\n  music: 'Music',\n  cartoon: 'Cartoon',\n  paper: 'Paper',\n  trans: 'Paper Rewriter',\n  textToPhoto: 'Text to Photo',\n  gold: 'Gold',\n  aimarkmap: 'Map',\n  about: 'About',\n  login: 'Login',\n  logout: 'Logout',\n  language: 'Language',\n  navigationMenu: 'Navigation Menu',\n  goofish: 'Goofish',\n  worker: 'Worker',\n  user: 'Current User:'\n}\n\nexport default nav\n"
  },
  {
    "path": "src/i18n/locales/en/notFound.ts",
    "content": "export default {\n  title: '404',\n  description: 'Sorry, the page you visited does not exist',\n  backHomeBtn: 'Back to Home'\n}\n"
  },
  {
    "path": "src/i18n/locales/en/paper.ts",
    "content": "export default {\n  title: 'AI Papers',\n  content: 'Explore the latest AI research papers, models, datasets, and applications',\n  tip: 'Tip: Need a VPN to access',\n  dataSource: 'Data source: Hugging Face • Real-time sync',\n  today: 'Today',\n  hot: 'Hot',\n  detail: 'Detail',\n  search: 'Search by name, author, description...',\n  showDetail: 'Show Detail',\n  project: 'Project Home',\n  arXiv: 'arXiv Paper',\n  github: 'GitHub Code',\n  all: 'All Types',\n  model: 'Model',\n  dataset: 'Dataset',\n  application: 'Application',\n  noResult: 'No related results found',\n  noData: 'No data available',\n  tryDifferentKeywords: 'Try different search keywords',\n  networkError: 'Please refresh later or check your network connection',\n  clearSearch: 'Clear Search',\n  parameterCount: 'Parameter Count:',\n  dataSize: 'Data Size:',\n  hardware: 'Hardware:',\n  retry: 'Retry',\n  found: 'Found',\n  relatedResults: 'related results',\n  unknown: 'Unknown',\n  apiError: 'Daily paper API returns data in an unexpected format',\n  loadError: 'Failed to load daily papers. Please try again later',\n  hotApiError: 'Hot paper API returns data in an unexpected format',\n  hotLoadError: 'Failed to load hot papers. Please try again later',\n  paper: 'Paper',\n  gotoLatexEdit: 'Go to Latex Editor',\n}\n"
  },
  {
    "path": "src/i18n/locales/en/textToPhoto.ts",
    "content": "export default {\n  title: 'Text to Photo',\n  description: 'Use Stable Diffusion API to generate beautiful images from text descriptions',\n  positivePrompt: 'Positive Prompt *',\n  positivePromptDesc: ' - Describe what you want to see in the image',\n  negativePrompt: 'Negative Prompt',\n  negativePromptDesc: ' - Describe what you don\\'t want to see',\n  positivePromptPlaceholder: 'e.g.: A cute orange cat sitting on a sunny windowsill, digital art, high quality',\n  negativePromptPlaceholder: 'e.g.: blurry, low quality, distorted, watermark, text',\n  imageSize: 'Image Size',\n  samples: 'Number of Images',\n  steps: 'Denoising Steps',\n  guidanceScale: 'Guidance Scale',\n  seed: 'Random Seed',\n  seedPlaceholder: 'Leave empty for random',\n  randomSeed: 'Random Seed',\n  random: 'Random',\n  advancedSettings: 'Advanced Settings',\n  functionOptions: 'Function Options',\n  safetyChecker: 'NSFW Checker',\n  enhancePrompt: 'Enhance Prompt',\n  multiLingual: 'Multi-lingual',\n  selfAttention: 'High Quality Mode',\n  upscale: '2x Upscale',\n  panorama: 'Panorama',\n  yes: 'Yes',\n  no: 'No',\n  generateBtn: 'Generate Image',\n  downloadAllBtn: 'Download All',\n  downloadBtn: 'Download',\n  clearBtn: 'Clear',\n  noImagesToDownload: 'No images to download',\n  enterPositivePrompt: 'Please enter positive prompt',\n  generateSuccess: 'Successfully generated X images',\n  generateFailed: 'Generation failed',\n  imageDownloadSuccess: 'Image downloaded successfully',\n  startDownload: 'Starting download of X images',\n  generatingImage: 'Generating image, please wait...',\n  imageDisplayPlaceholder: 'Image will be displayed here after generation',\n  imageLoadFailed: 'Image failed to load, please try again',\n  imageNLoadFailed: 'Image X failed to load'\n}\n"
  },
  {
    "path": "src/i18n/locales/en/trans.ts",
    "content": "export default {\n  title: 'Online Translation',\n  description: 'Support multiple language translation, fast and accurate service',\n  sourceTextPlaceholder: 'Enter text to translate...',\n  translatedTextPlaceholder: 'Translation result will be displayed here...',\n  translateBtn: 'Translate',\n  swapBtn: 'Swap Languages',\n  copyBtn: 'Copy',\n  downloadBtn: 'Download',\n  speakBtn: 'Speak',\n  translateSuccess: 'Translation successful',\n  translateFailed: 'Translation failed',\n  translateEmpty: 'Translation result is empty',\n  noTextToTranslate: 'Please enter text to translate',\n  noContentToDownload: 'No content to download',\n  noTextWarning: 'Please enter text to translate',\n  browserNotSupportSpeech: 'Your browser does not support speech synthesis',\n  networkError: 'Translation failed, please check your network connection',\n  languages: {\n    zh: 'Chinese',\n    en: 'English',\n    jp: 'Japanese',\n    kor: 'Korean',\n    fra: 'French',\n    de: 'German',\n    spa: 'Spanish',\n    ru: 'Russian'\n  }\n}\n"
  },
  {
    "path": "src/i18n/locales/en/versionUpdate.ts",
    "content": "export default {\n  title: 'New Version Available',\n  message: 'A new version has been detected!',\n  currentVersion: 'Current Version: ',\n  latestVersion: 'Latest Version: ',\n  description: 'For the best experience, please update to the latest version. All cached data will be cleared after the update.',\n  updateButton: 'Update Now'\n}\n"
  },
  {
    "path": "src/i18n/locales/en/video.ts",
    "content": "export default {\n  tabParse: 'Video Parse',\n  tabDownload: 'Video Download',\n  title: 'Video Parse',\n  description: 'Enter video link to play online, supports major video platforms',\n  placeholder: 'Enter video link',\n  parseBtn: 'Parse',\n  clearBtn: 'Clear',\n  fullscreenBtn: 'Fullscreen',\n  exitFullscreenBtn: 'Exit Fullscreen',\n  noUrlTip: 'Please enter video link',\n  parseSuccess: 'Parse successful',\n  parseFailed: 'Parse failed, please check the link',\n  selectApi: 'Please select parse API',\n  parseTimeoutTip: 'If video parsing takes too long, you can select a different parse API and try again!',\n  rotatePrompt: 'Please rotate your device to landscape mode',\n  rotateSubPrompt: 'For better viewing experience',\n  supportedSites: 'Video - Supported Sites (including but not limited to)',\n  api1: 'Parse API 1',\n  api2: 'Parse API 2',\n  api3: 'Parse API 3',\n  api4: 'Parse API 4',\n  api5: 'Parse API 5',\n  availableRecommended: 'Available - Highly Recommended',\n  available: 'Available',\n  mayNotBeAvailable: 'May Not Be Available',\n  tencentVideo: 'Tencent Video',\n  iqiyi: 'iQIYI',\n  youku: 'Youku',\n  mgtv: 'Mango TV',\n  bilibili: 'Bilibili',\n  letv: 'LeTV',\n  tudou: 'Tudou',\n  sohu: 'Sohu Video',\n  pptv: 'PPTV',\n  movie1905: '1905 Movie',\n  hjtv: 'HJTV',\n  omofun: 'OmoFun',\n  douyin: 'Douyin',\n  xiaohongshu: 'Xiaohongshu',\n  downloadTitle: 'Download Video Without Watermark',\n  downloadDescription: 'Supports Bilibili, Douyin, Xiaohongshu and more platforms',\n  downloadPlaceholder: 'Paste video link here (supports Douyin, Xiaohongshu, Bilibili, etc.)',\n  extracting: 'Extracting...',\n  extractVideo: 'Extract Video',\n  downloadFormat: 'Download Format',\n  reset: 'Reset',\n}\n"
  },
  {
    "path": "src/i18n/locales/en.ts",
    "content": "import nav from './en/nav'\nimport home from './en/home'\nimport login from './en/login'\nimport video from './en/video'\nimport music from './en/music'\nimport about from './en/about'\nimport gpt from './en/gpt'\nimport cartoon from './en/cartoon'\nimport cartoonDetail from './en/cartoonDetail'\nimport cartoonChapter from './en/cartoonChapter'\nimport common from './en/common'\nimport versionUpdate from './en/versionUpdate'\nimport trans from './en/trans'\nimport paper from './en/paper'\nimport textToPhoto from './en/textToPhoto'\nimport notFound from './en/notFound'\nimport gold from './en/gold'\nimport help from './en/help'\nimport goofish from './en/goofish'\nimport aimarkmap from './en/aimarkmap'\nimport latex from './en/latex'\n\nexport default {\n  translation: {\n    nav,\n    home,\n    login,\n    video,\n    music,\n    about,\n    gpt,\n    cartoon,\n    cartoonDetail,\n    cartoonChapter,\n    common,\n    versionUpdate,\n    trans,\n    paper,\n    textToPhoto,\n    notFound,\n    gold,\n    help,\n    goofish,\n    aimarkmap,\n    latex\n  }\n}\n"
  },
  {
    "path": "src/i18n/locales/zh/about.ts",
    "content": "const about = {\n  title: '关于我（求内推～）',\n  role: '一名全栈技术的爱好者',\n  name: '不见水星记（研一',\n  description: '宇宙终极无敌超级爆炸究极飞天帅比暴龙战士',\n  contact: '联系方式',\n  wechat: '微信号：Dveiklokk',\n  internship: '实习经历',\n  internship1: '双非本，211双一流硕士',\n  internship2: '曾在美团、华为、腾讯工作过',\n  awards: '获奖情况',\n  award1: '软考中级软件设计师',\n  award2: '发明专利两项，软件著作权两项',\n  award3: 'CCF-C中科院一区TOP期刊论文一篇，CCF-B中科院二区期刊论文一篇，EI会议，学报',\n  award4: '英语四级、计算机三级网络技术',\n  award5: '数学建模竞赛国一',\n  award6: '蓝桥杯Java国三、计挑Java省二',\n  award7: 'NETCCS省一、外研社英语竞赛省二',\n  award8: '创新创业大赛省二',\n  award9: '校奖学金，国家励志奖学金',\n  supportMe: '支持我',\n  addMe: '添加我',\n  email: '邮箱：891523233@qq.com',\n  products: '精选商品',\n  loadingProducts: '加载商品中...',\n  autoDelivery: '自动发货',\n  stockShort: '库存紧张',\n  noProducts: '暂无商品',\n  digitalGoodsNotice: '数字商品购买须知',\n  importantNotice: '在本平台购买商品即表示您同意服务提供商协议，同时本商品为数字产品，售出后不支持退货换货。下单即视为您已全面了解商品信息，自愿承担相应风险。',\n  projectExperience: '项目经验',\n  technologyStack: '技术栈',\n  deliveryQuality: '用心交付',\n}\n\nexport default about\n"
  },
  {
    "path": "src/i18n/locales/zh/aimarkmap.ts",
    "content": "const aimarkmap = {\n  promptSettingsBtn: '📝 Prompt设置',\n  apiSettingsBtn: '⚙️ API设置',\n  modelLabel: '模型:',\n  modelLabelMobile: '模型选择:',\n  queryBtn: '🔍 查询',\n  versionsLabel: '生成数量:',\n  generateBtn: 'AI生成',\n  showOriginalBtn: '原文',\n  showMarkdownBtn: 'Markdown',\n  clearBtn: '清空',\n  fullscreenBtn: '全屏显示',\n  exportPngBtn: '导出 PNG',\n  exportSvgBtn: '导出 SVG',\n  mindmapPreviewTitle: '🧠 思维导图预览',\n  thinkingMessage: 'AI正在思考中...',\n  apiSettingsTitle: '⚙️ API 设置',\n  apiUrlLabel: 'API地址:',\n  apiKeyLabel: 'API秘钥:',\n  saveAndCloseBtn: '💾 保存并关闭',\n  promptSettingsTitle: '📝 Prompt 设置',\n  promptTip: '请确保在Prompt模板中包含 <code>{{CONTENT}}</code>，它将被替换为左侧的输入内容。',\n  editNodeTitle: '✏️ 编辑节点',\n  deleteNodeBtn: '🗑️ 删除节点',\n  helpBtnTitle: '帮助与信息',\n  infoModalTitle: '使用说明、服务条款和隐私政策',\n  infoModalContentHtml: `\n    <h2>使用说明</h2>\n    <ul>\n      <li><strong>API 设置:</strong> 首次使用，请点击右上角的 <code>⚙️ API设置</code> 按钮，填入您的 AI 服务商提供的 API 地址 (URL) 和密钥 (Key)。配置将自动保存在您的浏览器本地。</li>\n      <li><strong>模型选择:</strong> 在左侧面板选择或输入您想使用的 AI 模型。点击 <code>🔍 查询</code> 可自动获取该 API 地址下支持的模型列表。</li>\n      <li><strong>内容输入:</strong> 在左侧最大的输入框中，您可以输入一段描述性文本，或者直接粘贴已经格式化好的 Markdown 内容。</li>\n      <li><strong>AI 生成:</strong> 输入描述性文本后，通过滑块选择希望 AI 生成的不同版本数量（1-5个），然后点击 <code>🚀 AI生成</code>。</li>\n      <li><strong>版本切换:</strong> 生成成功后，思维导图预览区上方会出现版本选项卡 (如\"版本1\", \"版本2\")，点击即可切换查看不同版本。</li>\n      <li><strong>编辑与查看:</strong>\n        <ul style=\"margin-top: 0.5rem;\">\n          <li>在思维导图上对任意节点<strong>单击右键</strong>，可选择<strong>\"编辑节点\"</strong>或<strong>\"删除节点\"</strong>。</li>\n          <li>左侧的 <code>📝 显示Markdown</code> 按钮可以让你查看和编辑 AI 生成的 Markdown 源码。</li>\n        </ul>\n      </li>\n      <li><strong>导出与全屏:</strong> 使用预览区右上角的按钮可将当前思维导图导出为 <code>SVG</code> 或 <code>PNG</code> 图片，或进入全屏模式。</li>\n    </ul>\n    <h2>服务条款</h2>\n    <p>当您使用 Markmap 时，即表示您同意以下条款：</p>\n    <ul>\n      <li>您对自己输入到本产品中的所有内容（包括文本、API密钥等）负全部责任。您必须保证输入的内容不侵犯任何第三方权利，且不违反任何适用法律法规。</li>\n      <li>禁止利用本产品进行任何形式的恶意行为，包括但不限于大量的、不合理的 API 请求、传播非法信息、或攻击第三方服务。</li>\n    </ul>\n    <h2>隐私政策</h2>\n    <p>我们高度重视您的隐私。请仔细阅读以下关于我们如何处理您的数据的信息：</p>\n    <h3>数据收集</h3>\n    <p>本产品主要处理两类数据：</p>\n    <ul>\n      <li><strong>配置信息:</strong> 您输入的 API 地址、API 密钥、所选模型等配置。这些信息仅使用浏览器的 <code>localStorage</code> 技术存储在<strong>您自己的电脑上</strong>，用于简化您的后续使用，不会上传到 AiMarkmap 的服务器。</li>\n      <li><strong>输入内容:</strong> 您为生成思维导图而输入的文本内容。</li>\n    </ul>\n    <p>本产品<strong>不使用</strong>任何第三方分析工具（如 Google Analytics）来追踪您的个人行为。</p>\n    <h3>数据使用</h3>\n    <p>您的所有数据处理均在<strong>浏览器端（客户端）</strong>完成。具体流程如下：</p>\n    <ul>\n      <li>您的 API 密钥和输入内容仅在您点击\"AI生成\"按钮时，由您的浏览器直接组合成一个请求，发送给您在设置中指定的第三方 AI 服务（如 OpenAI、Google AI 等）。</li>\n      <li><strong>Markmap 的服务器不存储、不中转、也无法看到</strong>您的 API 密钥和输入内容。数据传输路径为：您的浏览器 -> 您指定的 AI 服务提供商。</li>\n    </ul>\n    <h3>第三方服务</h3>\n    <p>本产品作为一个客户端工具，会根据您的配置调用第三方 AI 服务。您发送的数据将受您所使用的 AI 服务提供商的隐私政策和数据使用条款约束。我们强烈建议您在使用前查阅相应服务商的官方隐私政策。</p>\n    <h2>免责声明</h2>\n    <ul>\n      <li><strong>AI 生成内容的准确性：</strong>由 AI 模型生成的所有内容仅供参考。我们不保证其准确性、完整性或适用性。您需要自行判断并对使用这些结果所造成的一切后果负责。</li>\n      <li><strong>服务可用性：</strong>由于本产品依赖于网络连接和第三方 API 服务的稳定性，我们不承诺服务 100% 不间断或无错误。因网络问题、API 服务商故障或您自身配置错误导致的服务不可用，我们不承担任何责任。</li>\n    </ul>`,\n  customModelInputPlaceholder: '输入自定义模型名称',\n  topicInputPlaceholder: '可直接输入或粘贴Markdown，或输入普通文本后点击\"AI生成\"...',\n  contentDisplayPlaceholder: '编辑内容...',\n  apiUrlPlaceholder: 'AI API地址',\n  apiKeyPlaceholder: 'API密钥',\n  toggleVisibilityTitle: '显示/隐藏密钥',\n  promptInputPlaceholder: '在此编辑AI Prompt模板...',\n  editNodePlaceholder: '输入节点的新内容...',\n  js_generating: '生成中...',\n  js_exporting: '导出中...',\n  js_querying: '查询中...',\n  js_exit_fullscreen: '退出全屏',\n  js_fullscreen: '全屏显示',\n  js_status_requesting: '正在发起AI请求...',\n  js_status_generated: '已成功生成 {{s}}/{{n}} 个版本...',\n  js_status_done: '生成完成！共 {{n}} 个有效版本。',\n  js_tab_version: '版本 {{i}}',\n  js_alert_no_content: '请先输入内容！',\n  js_alert_all_failed: '所有AI生成请求均失败或返回空内容。请检查API设置和网络。',\n  js_alert_gen_failed: 'AI生成失败: {{msg}}',\n  js_alert_no_clipboard: '您的浏览器不支持剪贴板 API，请手动粘贴内容。',\n  js_alert_clipboard_empty: '剪贴板内容为空。',\n  js_alert_clipboard_error: '无法读取剪贴板内容。\\n请确保页面处于激活状态，并已授予浏览器读取剪贴板的权限。',\n  js_alert_query_no_config: '请先在设置中配置API地址和密钥！',\n  js_alert_query_failed: '查询模型失败: {{msg}}',\n  js_alert_query_success: '成功获取到 {{n}} 个可用模型！',\n  js_alert_no_mindmap: '找不到思维导图，无法导出。',\n  js_alert_export_error: '导出{{type}}图片时发生错误，请稍后重试。',\n  js_zoom_in: '放大',\n  js_zoom_out: '缩小',\n  js_reset_zoom: '重置缩放',\n  mobileTabEditor: '编辑',\n  mobileTabMindmap: '导图',\n  mobileTabLandscape: '横屏',\n  mobileCloseLandscape: '退出横屏',\n  defaultMarkdown: `# 🤖 AI思维导图生成\n\n## ✨ 新功能特性\n### 🎯 智能生成\n- ✨ **自定义生成版本数量 (1-5)**\n- AI驱动的内容创建\n### 🔧 自定义配置\n- 便捷的模型选择\n- 弹窗配置Prompt模板\n- 个性化设置\n\n## 🚀 使用流程\n### 📝 输入内容\n- 在左侧输入框描述内容\n- 或直接粘贴Markdown\n### 🤖 AI处理\n- **拖动滑块选择版本数**\n- 点击生成按钮\n### 🎨 可视化展示\n- **点击选项卡切换不同版本**\n- 实时预览思维导图\n- 一键导出SVG&PNG图片`,\n  defaultPrompt: `{{CONTENT}}\n请按以下设定的思维导图架构师的身份对以上内容执行任务。\n\n# Role: 思维导图架构师\n\n## Profile\n- description: 精通信息结构提取与层次关系分析，能够将复杂文本内容转化为清晰、分层的思维导图格式，便于阅读与理解。\n- background: 拥有丰富的信息架构设计经验，熟悉多种内容结构优化方法，擅长运用Markdown及视觉元素增强内容表现力。\n- personality: 细致严谨，逻辑清晰，注重条理性与用户体验，表达简洁明了。\n- expertise: 信息架构设计、内容层次化、结构化表达、Markdown思维导图制作。\n- target_audience: 内容编辑人员、文档撰写者、项目管理者、学习者及需要清晰信息结构的用户群体。\n\n## Skills\n\n1. 信息结构设计\n   - 层级划分: 根据内容逻辑精准划分多层级结构\n   - 关系梳理: 明确主次、分支及关联节点\n   - 内容细化: 优化内容条目，细化分点展开\n   - 逻辑优化: 保持结构简洁且易读\n\n2. Markdown及可视化表达\n   - 思维导图格式制作: 灵活使用#、##、###等级标题表达层次\n   - 列表运用: 以条目列表形式呈现节点内容\n   - 语言保持: 保持原文语言与用词\n   - Emoji增强: 合理使用Emoji增强视觉导向与可读性\n\n3. Rules\n\n1. 基本原则：\n   - 原文尊重：所有内容必须保留原文句子，杜绝改写或删减关键内容\n   - 结构清晰：层级分明，结构简洁，避免内容堆叠不清晰\n   - 语言一致：输出语言应与原文本主要语言保持一致\n   - 可视增强：尽量融合Emoji，增强层次感和视觉舒适度\n\n\n2. 行为准则：\n   - 不添不减：不得添加任何解释、观点或额外信息\n   - 句式优化：适度调整句式以提升表达通顺度和条理明晰\n   - 内容拆分：长句或内容过多时合理拆分并保持逻辑完整\n   - 专业严谨：坚持专业风格，避免模糊和歧义表述\n\n\n3. 限制条件：\n   - 不允许自创内容：不加入个人见解或未出现的信息\n   - 禁止格式错误：排版清晰，禁止Markdown语法错误\n   - 中心主题限制：中心主题字数限制10个字左右\n   - 层级限制：最少3级，层级数可根据内容合理扩展无上限\n\n## Workflows\n\n- 目标: 将原始文本内容转化为清晰分层的思维导图Markdown格式，便于直接阅读和内容解析\n- 步骤 1: 彻底阅读并理解原始内容，分析其内在逻辑和层级关系\n- 步骤 2: 按照层级使用#标题标记，条目采用列表形式排列，确保不少于三级层级\n- 步骤 3: 对长句进行分点拆解，调整句式增强表述清晰度，并合适插入Emoji提升视觉效果\n- 步骤 4: 最终输出为纯Markdown格式，只输出 Markdown文本本体，不要使用代码块包裹。\n- 预期结果: 输出符合规范的Markdown格式思维导图文本，层级明晰，内容完整，语言统一，无任何附加解释或内容`\n}\n\nexport default aimarkmap\n"
  },
  {
    "path": "src/i18n/locales/zh/cartoon.ts",
    "content": "const cartoon = {\n  title: '漫画',\n  subTitle: '水星记图漫',\n  description: '发现更多精彩的漫画作品',\n  searchPlaceholder: '搜索漫画...',\n  searchBtn: '搜索',\n  ranking: '排行榜',\n  hot: '热门',\n  new: '最新',\n  finished: '已完结',\n  ongoing: '连载中',\n  chapters: '章节',\n  startReading: '开始阅读',\n  prevChapter: '上一章',\n  nextChapter: '下一章',\n  noResults: '未找到相关漫画',\n  noData: '暂无数据',\n  searchResults: '搜索结果：共找到',\n  relatedCartoons: '个相关漫画',\n  enterKeyword: '请输入搜索关键字',\n  fetchRankTypesFailed: '获取排行榜类型失败',\n  fetchCartoonListFailed: '获取漫画列表失败',\n  searchFailed: '搜索失败，请稍后重试',\n  foundResults: '找到 X 个相关漫画'\n}\n\nexport default cartoon\n"
  },
  {
    "path": "src/i18n/locales/zh/cartoonChapter.ts",
    "content": "const cartoonChapter = {\n  backToDetail: '返回详情',\n  noContent: '未找到章节内容',\n  fetchChapterFailed: '获取章节内容失败',\n  alreadyFirstChapter: '已经是第一章了',\n  alreadyLastChapter: '已经是最后一章了',\n  total: '共',\n  pages: '页',\n  page: '第',\n  backToTop: '返回顶部'\n}\n\nexport default cartoonChapter\n"
  },
  {
    "path": "src/i18n/locales/zh/cartoonDetail.ts",
    "content": "const cartoonDetail = {\n  backToList: '返回列表',\n  notFound: '未找到漫画信息',\n  fetchDetailFailed: '获取漫画详情失败',\n  author: '作者',\n  status: '状态',\n  likes: '点赞',\n  tags: '标签',\n  intro: '简介',\n  chapterList: '章节列表',\n  episode: '第',\n  hua: '话'\n}\n\nexport default cartoonDetail\n"
  },
  {
    "path": "src/i18n/locales/zh/common.ts",
    "content": "const common = {\n  chinese: '中文',\n  english: 'English',\n  logoutSuccess: '已退出登录',\n  loading: '加载中...',\n  submit: '提交',\n  cancel: '取消',\n  confirm: '确认',\n  search: '搜索',\n  delete: '删除',\n  edit: '编辑',\n  save: '保存',\n  back: '返回',\n  more: '更多',\n  close: '关闭',\n  refresh: '刷新',\n  copy: '复制',\n  copySuccess: '复制成功',\n  copyFailed: '复制失败',\n  download: '下载',\n  downloadSuccess: '下载成功',\n  downloadFailed: '下载失败',\n  clear: '清空',\n  settings: '设置',\n  generate: '生成',\n  generating: '生成中...',\n  siteVisits: '本站今日总访问量',\n  visitsUnit: '次',\n  copyright: '© Copyright 2023 P1Kaj1uu. All Rights Reserved.'\n}\n\nexport default common\n"
  },
  {
    "path": "src/i18n/locales/zh/gold.ts",
    "content": "const gold = {\n  loading: '实时数据获取中...',\n  domesticGold: '国内黄金',\n  internationalGold: '国际黄金',\n  high: '最高',\n  low: '最低',\n  open: '开盘',\n  prevClose: '昨收',\n  updateTime: '更新时间',\n  priceTrend: '黄金价格走势',\n  '7days': '7天',\n  '30days': '30天',\n  '90days': '90天',\n  refresh: '刷新数据',\n  refreshSuccess: '刷新成功',\n  fetchPriceFailed: '获取价格数据失败',\n  fetchChartFailed: '获取K线数据失败',\n  noChartData: '暂无图表数据',\n  volume: '成交量',\n  silver: '白银',\n  realtimeQuote: '实时行情',\n  tradingviewWarning: '需要科学上网工具访问TradingView',\n  subscribeTitle: '订阅黄金走势',\n  subscribeTooltip: '订阅黄金走势',\n  subscribeDescription: '订阅后，黄金价格更新时将实时发送邮件通知',\n  emailPlaceholder: '请输入您的邮箱地址',\n  subscribe: '订阅',\n  subscribeSuccess: '订阅成功！金价更新时会发送邮件通知',\n  subscribeFailed: '订阅失败，请稍后重试',\n  invalidEmail: '请输入有效的邮箱地址',\n  emailNotConfigured: '邮件服务未配置，请先配置 email.config.js'\n}\n\nexport default gold\n"
  },
  {
    "path": "src/i18n/locales/zh/goofish.ts",
    "content": "const goofish = {\n  data: '闲鱼数据',\n  accounts: '账号管理',\n  conversations: '对话管理',\n  orders: '订单管理',\n  goods: '商品管理',\n  autoreply: '自动回复',\n  autosell: '自动发货',\n  workflow: '工作流图',\n  logs: '系统日志',\n  assistant: '闲鱼助手',\n  home: '返回首页'\n}\n\nexport default goofish\n"
  },
  {
    "path": "src/i18n/locales/zh/gpt.ts",
    "content": "const gpt = {\n  title: 'ChatGPT',\n  welcomeMessage: '您好！我是ChattyPlay AI助手，可以为您解答任何问题，比如代码问题、学习问题、运动问题等。请问有什么可以帮助您的吗？',\n  placeholder: '输入您的问题...',\n  sendBtn: '发送',\n  clearBtn: '清空对话',\n  thinking: '思考中...',\n  error: '发生错误，请重试',\n  emptyMessage: '请输入消息内容',\n  copySuccess: '复制成功！',\n  codeCopySuccess: '代码复制成功！',\n  replyComplete: '回复完成',\n  replyInterrupted: '回复已中断，已保存当前内容',\n  fallbackResponse: '抱歉，我在处理您的请求时遇到了问题。请稍后重试。',\n  browserNotSupportSpeech: '您的浏览器不支持语音播报功能',\n  speakStart: '开始播报...',\n  speakComplete: '播报完成',\n  speakError: '播报出错',\n  feedbackLike: '感谢您的反馈！',\n  feedbackDislike: '我们会继续改进！',\n  clearConfirmTitle: '确认清空',\n  clearConfirmContent: '确定要清空当前对话记录吗？',\n  cleared: '对话已清空',\n  userRole: '用户',\n  aiRole: 'AI助手',\n  exportSuccess: '聊天记录导出成功！',\n  stopGenerate: '停止生成',\n  typing: 'AI正在输入...',\n  clearTooltip: '清空当前对话记录',\n  exportTooltip: '导出当前对话',\n  enterToSend: '按 Enter 发送，Shift + Enter 换行',\n  subtitle: '智能问答，请规范问题健康提问，AI回答仅供参考',\n  modelName: 'DeepSeek V3.2模型',\n  copy: '复制',\n  readAloud: '朗读',\n  helpful: '有帮助',\n  needsImprovement: '需改进',\n  networkError: '网络错误，已使用备用回复',\n  exportFilename: 'ChattyPlay_AI对话'\n}\n\nexport default gpt\n"
  },
  {
    "path": "src/i18n/locales/zh/help.ts",
    "content": "const help = {\n  title: '使用帮助',\n  description: '详细的使用教程和帮助文档，让您快速上手',\n  comingSoon: '内容正在建设中...',\n  chatgpt: {\n    title: 'ChatGPT 对话',\n    description: '与强大的 AI 语言模型进行智能对话，获取各种信息和帮助。输入您的问题，AI 会给出详细的回答。',\n    step1: '在输入框中输入您的问题',\n    step2: '点击发送按钮或按回车键',\n    step3: '等待 AI 回复',\n    step4: '可以复制、保存或继续对话'\n  },\n  video: {\n    title: '视频解析',\n    description: '支持解析多个平台的视频资源，一键获取高清视频。输入视频链接即可解析下载。',\n    step1: '获取需要解析的视频链接',\n    step2: '粘贴到输入框中',\n    step3: '点击解析按钮',\n    step4: '选择画质后点击下载'\n  },\n  music: {\n    title: '音乐解析',\n    description: '解析音乐资源，支持多种格式下载。输入音乐链接即可解析获取高品质音频。',\n    step1: '获取需要解析的音乐链接',\n    step2: '粘贴到输入框中',\n    step3: '点击解析按钮',\n    step4: '选择音质后点击下载'\n  },\n  trans: {\n    title: '在线翻译',\n    description: '支持多种语言互译，快速准确的翻译服务。输入文本即可翻译成目标语言。',\n    step1: '输入或粘贴需要翻译的文本',\n    step2: '选择源语言和目标语言',\n    step3: '点击翻译按钮',\n    step4: '可以复制、下载或朗读翻译结果'\n  },\n  textToPhoto: {\n    title: '文字转图',\n    description: '将文字描述转换为精美的图片，创意无限。描述您想要的图片，AI 会为您生成。',\n    step1: '详细描述您想要的图片',\n    step2: '选择图片风格和尺寸',\n    step3: '点击生成图片按钮',\n    step4: '等待图片生成完成',\n    step5: '可以下载或重新生成'\n  },\n  faq: {\n    title: '常见问题',\n    description: '解答用户在使用过程中遇到的常见问题。',\n    step1: '解析失败怎么办？',\n    step2: '视频无法播放如何处理？',\n    step3: '翻译结果不准确如何解决？',\n    step4: '如何保存历史记录？'\n  },\n  stepsTitle: '使用步骤：'\n}\n\nexport default help\n"
  },
  {
    "path": "src/i18n/locales/zh/home.ts",
    "content": "const home = {\n  welcome: '欢迎来到 ChattyPlay！',\n  description: '一个集成了多种智能工具的平台，为您提供音乐解析、视频解析、AI 对话等功能。',\n  features: {\n    music: {\n      title: '音乐解析',\n      description: '搜索并播放您喜欢的音乐，支持多种音乐平台解析'\n    },\n    video: {\n      title: '视频解析',\n      description: '解析各大视频平台的视频资源，支持多种画质选择'\n    },\n    trans: {\n      title: '论文降重',\n      description: '智能文本处理，帮助您优化论文和文档内容'\n    },\n    chatgpt: {\n      title: 'ChatGPT',\n      description: '与强大的 AI 语言模型进行智能对话，获取各种信息和帮助'\n    },\n    cartoon: {\n      title: '漫画',\n      description: '发现更多精彩的漫画作品，支持搜索、排行榜和章节阅读'\n    },\n    textToPhoto: {\n      title: '文字转图',\n      description: '将文字描述转换为精美的图片，创意无限'\n    },\n    help: {\n      title: '使用帮助',\n      description: '详细的使用教程和帮助文档，让您快速上手'\n    },\n    papers: {\n      title: '论文文献',\n      description: '探索最新人工智能研究进展'\n    },\n    gold: {\n      title: '实时黄金',\n      description: '实时获取黄金价格和k线图，帮助您进行交易决策'\n    },\n    goofish: {\n      title: '闲鱼助手',\n      description: '提供闲鱼平台的自动交易、自动回复、自动监控等功能，助您轻松买卖二手物品'\n    },\n    worker: {\n      title: 'Agent监工',\n      description: '监控和管理您的智能Agent，在线查看Agent运行状态，及时处理异常情况，模拟打工人的工作状态，确保Agent高效稳定运行'\n    },\n    markmap: {\n      title: '思维导图',\n      description: '将文本内容转换为思维导图，帮助您更好地组织和理解信息，提高工作效率，可将生成的思维导图保存为图片或Markdown格式，方便分享和使用'\n    }\n  },\n  footer: {\n    slogan: '💗 来日方长，未来可期 💗',\n    thanks: '感谢您使用 ChattyPlay！我致力于为您提供更多实用且有趣的功能，敬请期待未来的更新与改进！'\n  }\n}\n\nexport default home\n"
  },
  {
    "path": "src/i18n/locales/zh/latex.ts",
    "content": "const latex = {\n  title: 'LaTeX 编辑器',\n  compile: '编译',\n  compiling: '编译中...',\n  compileSuccess: '编译成功',\n  compileError: '编译失败',\n  preview: 'PDF 预览',\n  files: '文件',\n  addFile: '新建文件',\n  deleteFile: '删除文件',\n  renameFile: '重命名',\n  page: '第 {{current}} / {{total}} 页',\n  zoomIn: '放大',\n  zoomOut: '缩小',\n  fullscreen: '全屏',\n  exitFullscreen: '退出全屏',\n  emptyHint: '点击「编译」按钮生成 PDF',\n  retry: '重新编译',\n  timeout: '编译超时，请稍后重试',\n}\n\nexport default latex\n"
  },
  {
    "path": "src/i18n/locales/zh/login.ts",
    "content": "export default {\n  account: '账号',\n  accountPlaceholder: '请输入您的 ChattyPlay 账号',\n  accountRequired: '请输入您的 ChattyPlay 账号',\n  password: '密码',\n  passwordPlaceholder: '请输入您的 ChattyPlay 密码',\n  passwordRequired: '请输入您的 ChattyPlay 密码',\n  passwordLength: '密码长度在 6 到 11 个字符',\n  email: '邮箱',\n  emailPlaceholder: '请输入您的邮箱（可选）',\n  confirmPassword: '确认密码',\n  confirmPasswordPlaceholder: '请再次输入密码',\n  confirmPasswordRequired: '请确认密码',\n  confirmPasswordMismatch: '两次输入的密码不一致',\n  verifyCode: '验证码',\n  verifyCodePlaceholder: '请输入验证码',\n  verifyCodeRequired: '请输入验证码',\n  verifyCodeError: '验证码不正确，请重新输入',\n  agree: '同意协议',\n  agreeRequired: '请同意协议后再登录',\n  loginBtn: '登录',\n  registerBtn: '注册',\n  switchToLogin: '已有账号？去登录',\n  switchToRegister: '没有账号？去注册',\n  resetBtn: '重置',\n  forgetPassword: '忘记密码？',\n  loginSuccess: '登录成功！',\n  registerSuccess: '注册成功！',\n  loginFailed: '登录失败，请重试',\n  registerFailed: '注册失败，请重试',\n  accountExists: '账号已存在',\n  emailExists: '邮箱已被注册',\n  invalidEmail: '邮箱格式不正确',\n  forgetPasswordTip: '忘记密码功能开发中...',\n  thirdPartyLoginTip: '或使用第三方账号登录',\n  usernameLength: '用户名长度必须在3-20个字符之间',\n  passwordLengthRegister: '密码长度必须在6-20个字符之间'\n}\n"
  },
  {
    "path": "src/i18n/locales/zh/music.ts",
    "content": "export default {\n  title: '音乐解析',\n  subTitle: '水星乐',\n  description: '输入歌曲名称即可在线播放，支持多种音乐平台',\n  placeholder: '请输入歌曲名称',\n  searchBtn: '搜索',\n  clearBtn: '清空',\n  noKeywordTip: '请输入歌曲名称',\n  searchSuccess: '搜索成功',\n  searchFailed: '搜索失败，请重试',\n  noResults: '未找到相关歌曲',\n  hotComments: '热门留言',\n  mvNotAvailable: '该MV暂无资源',\n  fetchMVFailed: '获取MV失败',\n  fetchMusicFailed: '获取歌曲失败，请检查网络连接后重试',\n}\n"
  },
  {
    "path": "src/i18n/locales/zh/nav.ts",
    "content": "const nav = {\n  home: '首页',\n  chatgpt: '助手',\n  video: '视频',\n  music: '音乐',\n  cartoon: '漫画',\n  paper: '论文',\n  trans: '论文降重',\n  textToPhoto: '绘图',\n  gold: '黄金',\n  aimarkmap: '导图',\n  about: '关于',\n  login: '登录',\n  logout: '退出',\n  language: '语言',\n  navigationMenu: '导航菜单',\n  goofish: '闲鱼',\n  worker: '监工',\n  user: '当前用户：'\n}\n\nexport default nav\n"
  },
  {
    "path": "src/i18n/locales/zh/notFound.ts",
    "content": "export default {\n  title: '404',\n  description: '抱歉，您访问的页面不存在',\n  backHomeBtn: '返回首页'\n}\n"
  },
  {
    "path": "src/i18n/locales/zh/paper.ts",
    "content": "export default {\n  title: 'AI 领域相关论文',\n  content: '探索最新人工智能研究进展，包括但不限于论文、模型、数据集和应用',\n  tip: '温馨提示：需要科学上网工具访问',\n  dataSource: '数据来源于 Hugging Face • 实时同步',\n  today: '今日',\n  hot: '热门',\n  detail: '详情',\n  search: '搜索名称、作者、描述...',\n  showDetail: '查看详情',\n  project: '项目主页',\n  arXiv: 'arXiv论文',\n  github: 'GitHub代码',\n  all: '全部类型',\n  model: '模型',\n  dataset: '数据集',\n  application: '应用',\n  noResult: '未找到相关结果',\n  noData: '暂无数据',\n  tryDifferentKeywords: '尝试不同的搜索关键词',\n  networkError: '请稍后刷新或检查网络连接',\n  clearSearch: '清空搜索',\n  parameterCount: '参数量:',\n  dataSize: '数据量:',\n  hardware: '硬件:',\n  retry: '重试',\n  found: '找到',\n  relatedResults: '个相关结果',\n  unknown: '未知',\n  apiError: '每日论文API返回的数据格式不符合预期',\n  loadError: '加载每日论文失败，请稍后重试',\n  hotApiError: '热门论文API返回的数据格式不符合预期',\n  hotLoadError: '加载热门数据失败，请稍后重试',\n  paper: '论文',\n  gotoLatexEdit: '前往Latex编辑',\n}\n"
  },
  {
    "path": "src/i18n/locales/zh/textToPhoto.ts",
    "content": "export default {\n  title: '文字转图',\n  description: '使用 Stable Diffusion API 根据文本描述生成精美的图像',\n  positivePrompt: '正面提示词 (Prompt) *',\n  positivePromptDesc: ' - 描述您想要在图像中看到的内容',\n  negativePrompt: '负面提示词 (Negative Prompt)',\n  negativePromptDesc: ' - 描述您不想要的内容',\n  positivePromptPlaceholder: '例如：一只可爱的橘猫，坐在阳光明媚的窗台上，数字艺术，高质量',\n  negativePromptPlaceholder: '例如：模糊，低质量，变形，水印，文字',\n  imageSize: '图片尺寸',\n  samples: '生成数量',\n  steps: '去噪步骤 (Steps)',\n  guidanceScale: '指导强度 (Guidance Scale)',\n  seed: '随机种子 (Seed)',\n  seedPlaceholder: '留空为随机',\n  randomSeed: '随机种子',\n  random: '随机',\n  advancedSettings: '高级设置',\n  functionOptions: '功能选项',\n  safetyChecker: 'NSFW 检查',\n  enhancePrompt: '增强提示',\n  multiLingual: '多语言支持',\n  selfAttention: '高质量模式',\n  upscale: '2倍放大',\n  panorama: '全景图像',\n  yes: '是',\n  no: '否',\n  generateBtn: '生成图片',\n  downloadAllBtn: '下载全部图片',\n  downloadBtn: '下载',\n  clearBtn: '清空',\n  noImagesToDownload: '没有图片可下载',\n  enterPositivePrompt: '请输入正面提示词',\n  generateSuccess: '成功生成 X 张图片',\n  generateFailed: '生成失败',\n  imageDownloadSuccess: '图片下载成功',\n  startDownload: '开始下载 X 张图片',\n  generatingImage: '正在生成图片，请稍候...',\n  imageDisplayPlaceholder: '图片将在生成后显示在这里',\n  imageLoadFailed: '图片加载失败，请重试',\n  imageNLoadFailed: '图片 X 加载失败'\n}\n"
  },
  {
    "path": "src/i18n/locales/zh/trans.ts",
    "content": "export default {\n  title: '在线翻译',\n  description: '支持多种语言互译，快速准确的翻译服务',\n  sourceTextPlaceholder: '请输入要翻译的文本...',\n  translatedTextPlaceholder: '翻译结果将显示在这里...',\n  translateBtn: '翻译',\n  swapBtn: '交换语言',\n  copyBtn: '复制',\n  downloadBtn: '下载',\n  speakBtn: '朗读',\n  translateSuccess: '翻译成功',\n  translateFailed: '翻译失败',\n  translateEmpty: '翻译结果为空',\n  noTextToTranslate: '请输入要翻译的文本',\n  noContentToDownload: '没有内容可下载',\n  noTextWarning: '请输入要翻译的文本',\n  browserNotSupportSpeech: '您的浏览器不支持语音朗读功能',\n  networkError: '翻译失败，请检查网络连接',\n  languages: {\n    zh: '中文',\n    en: '英文',\n    jp: '日文',\n    kor: '韩文',\n    fra: '法文',\n    de: '德文',\n    spa: '西班牙文',\n    ru: '俄文'\n  }\n}\n"
  },
  {
    "path": "src/i18n/locales/zh/versionUpdate.ts",
    "content": "export default {\n  title: '发现新版本',\n  message: '检测到新版本可用！',\n  currentVersion: '当前版本：',\n  latestVersion: '最新版本：',\n  description: '为了获得最佳体验，请更新到最新版本。更新后将清除所有缓存数据。',\n  updateButton: '立即更新'\n}\n"
  },
  {
    "path": "src/i18n/locales/zh/video.ts",
    "content": "export default {\n  tabParse: '视频解析',\n  tabDownload: '视频下载',\n  title: '视频解析',\n  description: '输入视频链接即可在线播放，支持各大视频平台',\n  placeholder: '请输入视频链接',\n  parseBtn: '开始解析',\n  clearBtn: '清空',\n  fullscreenBtn: '全屏',\n  exitFullscreenBtn: '退出全屏',\n  noUrlTip: '请输入视频链接',\n  parseSuccess: '解析成功',\n  parseFailed: '解析失败，请检查链接是否正确',\n  selectApi: '请选择解析接口',\n  parseTimeoutTip: '如遇视频解析时间过长，若不想等待，可重新选择解析接口，重新解析视频！',\n  rotatePrompt: '请将设备旋转至横屏观看',\n  rotateSubPrompt: '获得更好的观看体验',\n  supportedSites: '视频 - 网站（包括但不限于）',\n  api1: '解析接口1',\n  api2: '解析接口2',\n  api3: '解析接口3',\n  api4: '解析接口4',\n  api5: '解析接口5',\n  availableRecommended: '可用-超推荐',\n  available: '可用',\n  mayNotBeAvailable: '可能不可用',\n  tencentVideo: '腾讯视频',\n  iqiyi: '爱奇艺',\n  youku: '优酷',\n  mgtv: '芒果TV',\n  bilibili: '哔哩哔哩',\n  letv: '乐视TV',\n  tudou: '土豆视频',\n  sohu: '搜狐视频',\n  pptv: 'PPTV聚力',\n  movie1905: '1905电影网',\n  hjtv: '韩剧TV',\n  omofun: 'OmoFun',\n  douyin: '抖音',\n  xiaohongshu: '小红书',\n  downloadTitle: '去水印下载视频',\n  downloadDescription: '支持B站、抖音、小红书等多个平台',\n  downloadPlaceholder: '在这里粘贴视频链接 (支持抖音、小红书、B站等多个平台)',\n  extracting: '解析中...',\n  extractVideo: '提取视频',\n  downloadFormat: '下载格式',\n  reset: '重置',\n}\n"
  },
  {
    "path": "src/i18n/locales/zh.ts",
    "content": "import nav from './zh/nav'\nimport home from './zh/home'\nimport login from './zh/login'\nimport video from './zh/video'\nimport music from './zh/music'\nimport about from './zh/about'\nimport gpt from './zh/gpt'\nimport cartoon from './zh/cartoon'\nimport cartoonDetail from './zh/cartoonDetail'\nimport cartoonChapter from './zh/cartoonChapter'\nimport common from './zh/common'\nimport versionUpdate from './zh/versionUpdate'\nimport trans from './zh/trans'\nimport paper from './zh/paper'\nimport textToPhoto from './zh/textToPhoto'\nimport notFound from './zh/notFound'\nimport gold from './zh/gold'\nimport help from './zh/help'\nimport goofish from './zh/goofish'\nimport aimarkmap from './zh/aimarkmap'\nimport latex from './zh/latex'\n\nexport default {\n  translation: {\n    nav,\n    home,\n    login,\n    video,\n    music,\n    about,\n    gpt,\n    cartoon,\n    cartoonDetail,\n    cartoonChapter,\n    common,\n    versionUpdate,\n    trans,\n    paper,\n    textToPhoto,\n    notFound,\n    gold,\n    help,\n    goofish,\n    aimarkmap,\n    latex\n  }\n}\n"
  },
  {
    "path": "src/index.css",
    "content": "/* Tailwind CSS 指令 */\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n/* 全局视觉特效样式 */\nbody {\n  margin: 0;\n  padding: 0;\n  font-family:\n    -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", \"Oxygen\", \"Ubuntu\",\n    \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", sans-serif;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);\n  min-height: 100vh;\n}\n\n#root {\n  min-height: 100vh;\n}\n\n/* 平滑滚动 */\nhtml {\n  scroll-behavior: smooth;\n}\n\n/* 全局动画效果 */\n@keyframes fadeIn {\n  from {\n    opacity: 0;\n  }\n  to {\n    opacity: 1;\n  }\n}\n\n@keyframes fadeInUp {\n  from {\n    opacity: 0;\n    transform: translateY(30px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n@keyframes fadeInDown {\n  from {\n    opacity: 0;\n    transform: translateY(-30px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n@keyframes slideInLeft {\n  from {\n    opacity: 0;\n    transform: translateX(-30px);\n  }\n  to {\n    opacity: 1;\n    transform: translateX(0);\n  }\n}\n\n@keyframes slideInRight {\n  from {\n    opacity: 0;\n    transform: translateX(30px);\n  }\n  to {\n    opacity: 1;\n    transform: translateX(0);\n  }\n}\n\n@keyframes pulse {\n  0%,\n  100% {\n    transform: scale(1);\n  }\n  50% {\n    transform: scale(1.05);\n  }\n}\n\n@keyframes rotate {\n  from {\n    transform: rotate(0deg);\n  }\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n/* 页面加载动画 */\n.fade-in {\n  animation: fadeIn 0.5s ease-in;\n}\n\n.fade-in-up {\n  animation: fadeInUp 0.6s ease-out;\n}\n\n.fade-in-down {\n  animation: fadeInDown 0.6s ease-out;\n}\n\n.slide-in-left {\n  animation: slideInLeft 0.5s ease-out;\n}\n\n.slide-in-right {\n  animation: slideInRight 0.5s ease-out;\n}\n\n.pulse {\n  animation: pulse 2s infinite;\n}\n\n.rotate {\n  animation: rotate 20s linear infinite;\n}\n\n/* 粒子背景动画 */\n.particle-bg {\n  position: fixed;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  z-index: -1;\n  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n  overflow: hidden;\n}\n\n.particle {\n  position: absolute;\n  background: rgba(255, 255, 255, 0.1);\n  border-radius: 50%;\n  pointer-events: none;\n  animation: float 6s ease-in-out infinite;\n}\n\n@keyframes float {\n  0%,\n  100% {\n    transform: translateY(0) translateX(0);\n  }\n  25% {\n    transform: translateY(-20px) translateX(10px);\n  }\n  50% {\n    transform: translateY(-40px) translateX(0);\n  }\n  75% {\n    transform: translateY(-20px) translateX(-10px);\n  }\n}\n\n/* 卡片悬浮效果 */\n.card-hover {\n  transition: all 0.3s ease;\n  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n}\n\n.card-hover:hover {\n  transform: translateY(-5px);\n  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);\n}\n\n/* 按钮悬停效果 */\n.btn-hover {\n  transition: all 0.3s ease;\n  position: relative;\n  overflow: hidden;\n}\n\n.btn-hover::before {\n  content: \"\";\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  width: 0;\n  height: 0;\n  border-radius: 50%;\n  background: rgba(255, 255, 255, 0.3);\n  transform: translate(-50%, -50%);\n  transition:\n    width 0.6s,\n    height 0.6s;\n}\n\n.btn-hover:hover::before {\n  width: 300px;\n  height: 300px;\n}\n\n/* 响应式设计 */\n@media (max-width: 768px) {\n  body {\n    font-size: 14px;\n  }\n\n  .particle {\n    display: none;\n  }\n}\n\n@media (max-width: 480px) {\n  body {\n    font-size: 12px;\n  }\n}\n\n.ant-form .ant-form-item,\n[class*=\"ant-form-item\"] {\n  margin-bottom: 2px !important;\n}\n\n.ant-form .ant-form-item-label,\n[class*=\"ant-form-item\"] {\n  padding: 0px !important;\n}\n"
  },
  {
    "path": "src/main.tsx",
    "content": "import React, { Component, ReactNode } from 'react'\nimport ReactDOM from 'react-dom/client'\nimport App from './App.tsx'\nimport { initAnalytics } from './sdk/analytics'\nimport './assets/css/global.css'\nimport './index.css'\nimport 'antd/dist/reset.css'\nimport 'nprogress/nprogress.css'\nimport 'highlight.js/styles/github.css'\nimport './i18n/config'\n\n// 初始化埋点SDK\nconst analytics = initAnalytics({\n  reportUrl: import.meta.env.VITE_ANALYTICS_REPORT_URL,\n  appId: 'chattyplay', // 应用ID\n  debug: import.meta.env.DEV, // 开发环境开启调试\n  autoTrack: true, // 自动追踪页面浏览\n  collectDevice: true, // 收集设备信息\n  batchConfig: {\n    enabled: true,\n    maxSize: 10,\n    timeout: 5000\n  }\n})\n\n// 全局访问埋点SDK\nif (typeof window !== 'undefined') {\n  (window as any).analytics = analytics\n}\n\n// 声明 Fundebug 全局变量类型\ndeclare global {\n  interface Window {\n    fundebug: any\n  }\n}\n\nconst fundebug = typeof window !== 'undefined' ? window.fundebug : null\n\n// ErrorBoundary 组件\ninterface ErrorBoundaryState {\n  hasError: boolean\n}\n\ninterface ErrorBoundaryProps {\n  children: ReactNode\n}\n\nclass ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {\n  constructor(props: ErrorBoundaryProps) {\n    super(props)\n    this.state = { hasError: false }\n  }\n\n  componentDidCatch(error: Error, errorInfo: any) {\n    this.setState({ hasError: true })\n    // 将 component 中的报错发送到 Fundebug\n    if (fundebug) {\n      fundebug.notifyError(error, {\n        metaData: {\n          info: errorInfo\n        }\n      })\n    }\n  }\n\n  render() {\n    if (this.state.hasError) {\n      return null\n    }\n    return this.props.children\n  }\n}\n\nReactDOM.createRoot(document.getElementById('root')!).render(\n  <React.StrictMode>\n    <ErrorBoundary>\n      <App />\n    </ErrorBoundary>\n  </React.StrictMode>,\n)\n"
  },
  {
    "path": "src/pages/About.tsx",
    "content": "import React, { useState, useEffect } from 'react'\nimport { Card, Row, Col, Typography, Modal, Spin, message, Tag, Button, Input, Badge, Divider, Tooltip, Form } from 'antd'\nimport {\n  GithubOutlined,\n  MailOutlined,\n  WechatOutlined,\n  ShoppingOutlined,\n  DollarOutlined,\n  ExclamationCircleOutlined,\n  InboxOutlined,\n  ClockCircleOutlined,\n  CheckCircleOutlined,\n  ThunderboltOutlined,\n  CustomerServiceOutlined,\n  FileProtectOutlined,\n} from '@ant-design/icons'\nimport { useTranslation } from 'react-i18next'\nimport styled, { keyframes } from 'styled-components'\nimport { meImage, payImage, wxImage } from '@/utils/images'\n\nconst { Title, Paragraph } = Typography\nconst { useForm } = Form\n\n// 动画定义\nconst float = keyframes`\n  0%, 100% { transform: translateY(0px); }\n  50% { transform: translateY(-10px); }\n`\n\nconst slideUp = keyframes`\n  from {\n    opacity: 0;\n    transform: translateY(30px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n`\n\nconst PageContainer = styled.div`\n  max-width: 1400px;\n  margin: 0 auto;\n  padding: 40px 20px;\n  min-height: calc(100vh - 200px);\n  background: linear-gradient(135deg, #f5f7fa 0%, #eef2f7 100%);\n`\n\nconst SectionTitle = styled.h2`\n  margin-bottom: 48px;\n  text-align: center;\n  font-size: 2.5rem;\n  font-weight: 700;\n  background: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%);\n  -webkit-background-clip: text;\n  -webkit-text-fill-color: transparent;\n  background-clip: text;\n  position: relative;\n  \n  &::after {\n    content: '';\n    position: absolute;\n    bottom: -12px;\n    left: 50%;\n    transform: translateX(-50%);\n    width: 60px;\n    height: 3px;\n    background: linear-gradient(90deg, #667eea, #764ba2);\n    border-radius: 2px;\n  }\n`\n\nconst AboutCard = styled(Card)`\n  border-radius: 20px;\n  border: none;\n  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.06);\n  transition: all 0.3s ease;\n  height: 100%;\n  overflow: hidden;\n  backdrop-filter: blur(10px);\n  background: rgba(255, 255, 255, 0.95);\n\n  &:hover {\n    transform: translateY(-5px);\n    box-shadow: 0 16px 40px rgba(102, 126, 234, 0.15);\n  }\n\n  .ant-card-head {\n    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n    color: #fff;\n    border-radius: 20px 20px 0 0;\n    border-bottom: none;\n    \n    .ant-card-head-title {\n      color: #fff;\n    }\n  }\n`\n\nconst ProfileCard = styled(Card)`\n  border-radius: 20px;\n  border: none;\n  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.06);\n  text-align: center;\n  height: 100%;\n  background: linear-gradient(135deg, rgba(255,255,255,0.98) 0%, rgba(255,255,255,0.95) 100%);\n  backdrop-filter: blur(10px);\n  transition: all 0.3s ease;\n\n  &:hover {\n    transform: translateY(-5px);\n    box-shadow: 0 16px 40px rgba(102, 126, 234, 0.15);\n  }\n\n  .profile-avatar {\n    width: 120px;\n    height: 120px;\n    border-radius: 50%;\n    margin: 0 auto 20px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    background: linear-gradient(135deg, #667eea, #764ba2);\n    padding: 4px;\n    animation: ${float} 3s ease-in-out infinite;\n    \n    img {\n      border-radius: 50%;\n      border: 3px solid #fff;\n    }\n  }\n`\n\nconst SocialLinks = styled.div`\n  display: flex;\n  justify-content: center;\n  gap: 20px;\n  margin: 24px 0;\n\n  a, span {\n    width: 44px;\n    height: 44px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    border-radius: 50%;\n    background: linear-gradient(135deg, #667eea15 0%, #764ba215 100%);\n    transition: all 0.3s ease;\n    font-size: 1.4rem;\n    cursor: pointer;\n\n    &:hover {\n      transform: translateY(-3px);\n      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n      \n      a, span {\n        color: #fff !important;\n      }\n    }\n  }\n\n  a {\n    color: #667eea;\n  }\n\n  span {\n    color: #667eea;\n  }\n`\n\nconst TechList = styled.div`\n  display: flex;\n  flex-wrap: wrap;\n  gap: 10px;\n  justify-content: center;\n  margin-top: 16px;\n\n  .tech-tag {\n    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n    color: #fff;\n    padding: 6px 14px;\n    border-radius: 24px;\n    font-size: 0.85rem;\n    font-weight: 500;\n    transition: all 0.3s ease;\n    cursor: default;\n\n    &:hover {\n      transform: scale(1.05);\n      box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);\n    }\n  }\n`\n\nconst WeChatIcon = styled.span``\n\nconst ModalContent = styled.div`\n  text-align: center;\n  padding: 30px 20px;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n`\n\nconst CarouselContainer = styled.div`\n  position: relative;\n  width: 100%;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  min-height: 380px;\n`\n\nconst CarouselSlide = styled.div<{ isVisible: boolean; slideDirection: 'left' | 'right' }>`\n  display: ${props => (props.isVisible ? 'flex' : 'none')};\n  width: 100%;\n  flex-direction: column;\n  align-items: center;\n  animation: slide${props => (props.slideDirection === 'left' ? 'Left' : 'Right')} 0.4s\n    cubic-bezier(0.4, 0, 0.2, 1);\n\n  @keyframes slideLeft {\n    from {\n      opacity: 0;\n      transform: translateX(50px) scale(0.9);\n    }\n    to {\n      opacity: 1;\n      transform: translateX(0) scale(1);\n    }\n  }\n\n  @keyframes slideRight {\n    from {\n      opacity: 0;\n      transform: translateX(-50px) scale(0.9);\n    }\n    to {\n      opacity: 1;\n      transform: translateX(0) scale(1);\n    }\n  }\n`\n\nconst QRImage = styled.img`\n  width: 100%;\n  max-width: 280px;\n  border-radius: 20px;\n  box-shadow: 0 12px 40px rgba(102, 126, 234, 0.25);\n  transition: all 0.3s ease;\n\n  &:hover {\n    transform: scale(1.03);\n    box-shadow: 0 20px 48px rgba(102, 126, 234, 0.35);\n  }\n`\n\nconst SlideTitle = styled.h3`\n  font-size: 1.8rem;\n  margin-bottom: 24px;\n  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n  -webkit-background-clip: text;\n  -webkit-text-fill-color: transparent;\n  background-clip: text;\n  font-weight: 700;\n  letter-spacing: 1px;\n`\n\nconst NavigationButton = styled.button`\n  position: absolute;\n  top: 50%;\n  transform: translateY(-50%);\n  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n  border: none;\n  color: white;\n  width: 48px;\n  height: 48px;\n  border-radius: 50%;\n  cursor: pointer;\n  font-size: 1.5rem;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);\n  z-index: 10;\n\n  &:hover {\n    transform: translateY(-50%) scale(1.15);\n    box-shadow: 0 6px 20px rgba(102, 126, 234, 0.5);\n  }\n\n  &:active {\n    transform: translateY(-50%) scale(1.05);\n  }\n\n  &.prev {\n    left: -30px;\n  }\n\n  &.next {\n    right: -30px;\n  }\n`\n\n// 商品卡片样式\nconst ProductCard = styled(Card)`\n  border-radius: 16px;\n  border: 1px solid rgba(102, 126, 234, 0.1);\n  background: linear-gradient(135deg, #ffffff 0%, #f8faff 100%);\n  transition: all 0.3s ease;\n  margin-bottom: 16px;\n  cursor: pointer;\n  position: relative;\n  overflow: hidden;\n\n  &::before {\n    content: '';\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    height: 3px;\n    background: linear-gradient(90deg, #667eea, #764ba2, #f093fb);\n    transform: scaleX(0);\n    transition: transform 0.3s ease;\n  }\n\n  &:hover {\n    transform: translateY(-6px) scale(1.02);\n    box-shadow: 0 16px 32px rgba(102, 126, 234, 0.2);\n    border-color: rgba(102, 126, 234, 0.3);\n    \n    &::before {\n      transform: scaleX(1);\n    }\n  }\n\n  .ant-card-body {\n    padding: 18px;\n  }\n`\n\nconst ProductHeader = styled.div`\n  display: flex;\n  align-items: flex-start;\n  justify-content: space-between;\n  margin-bottom: 12px;\n  gap: 12px;\n`\n\nconst ProductName = styled.div`\n  font-size: 16px;\n  font-weight: 700;\n  color: #1a1a2e;\n  flex: 1;\n  display: flex;\n  align-items: center;\n  gap: 6px;\n`\n\nconst ProductTags = styled.div`\n  display: flex;\n  gap: 8px;\n  flex-wrap: wrap;\n  justify-content: flex-end;\n`\n\nconst ProductPrice = styled.div`\n  display: flex;\n  align-items: baseline;\n  gap: 4px;\n  font-size: 20px;\n  font-weight: bold;\n  color: #00b42a;\n  margin-top: 12px;\n  padding-top: 12px;\n  border-top: 1px dashed rgba(0, 0, 0, 0.06);\n`\n\nconst PriceUnit = styled.span`\n  font-size: 12px;\n  font-weight: normal;\n  color: #999;\n`\n\nconst ProductDesc = styled(Paragraph)`\n  font-size: 13px;\n  color: #666;\n  margin-bottom: 0;\n  line-height: 1.5;\n`\n\nconst ProductsTitle = styled.h3`\n  font-size: 1.3rem;\n  font-weight: 700;\n  margin-bottom: 20px;\n  color: #1a1a2e;\n  display: flex;\n  align-items: center;\n  gap: 10px;\n  position: relative;\n  \n  &::after {\n    content: '';\n    flex: 1;\n    height: 1px;\n    background: linear-gradient(90deg, #667eea, transparent);\n    margin-left: 12px;\n  }\n`\n\nconst ProductsContainer = styled.div`\n  height: 100%;\n  display: flex;\n  flex-direction: column;\n`\n\n// 购买须知样式\nconst NoticeSection = styled.div`\n  margin-top: 28px;\n  padding: 18px;\n  background: linear-gradient(135deg, #fff9f0 0%, #fff5e6 100%);\n  border-radius: 16px;\n  border-left: 4px solid #ff9800;\n  animation: ${slideUp} 0.5s ease-out;\n\n  .notice-title {\n    font-weight: 700;\n    margin-bottom: 12px;\n    color: #ff9800;\n    font-size: 15px;\n    display: flex;\n    align-items: center;\n    gap: 8px;\n  }\n\n  .notice-list {\n    margin: 0;\n    padding-left: 20px;\n    color: #666;\n    font-size: 12px;\n  }\n\n  .notice-list li {\n    margin-bottom: 8px;\n    line-height: 1.5;\n  }\n\n  .notice-list li.red {\n    color: #ff4d4f;\n    font-weight: 500;\n  }\n`\n\n// 商品详情弹窗样式\nconst DetailModal = styled(Modal)`\n  .ant-modal-content {\n    border-radius: 24px;\n    overflow: hidden;\n  }\n  \n  .ant-modal-header {\n    border-bottom: 1px solid rgba(102, 126, 234, 0.1);\n    padding: 20px 24px;\n    background: linear-gradient(135deg, #667eea08 0%, #764ba208 100%);\n  }\n\n  .ant-modal-body {\n    padding: 24px;\n  }\n\n  .detail-header {\n    margin-bottom: 8px;\n  }\n\n  .detail-title {\n    font-size: 22px;\n    font-weight: 700;\n    margin-bottom: 12px;\n    color: #1a1a2e;\n  }\n\n  .detail-info {\n    display: flex;\n    gap: 20px;\n    flex-wrap: wrap;\n  }\n\n  .detail-info-item {\n    display: inline-flex;\n    align-items: center;\n    gap: 6px;\n    color: #666;\n    font-size: 13px;\n    background: #f5f5f5;\n    padding: 4px 12px;\n    border-radius: 20px;\n  }\n\n  .detail-image {\n    width: 100%;\n    max-height: 280px;\n    object-fit: cover;\n    border-radius: 16px;\n    margin-bottom: 20px;\n  }\n\n  .detail-price {\n    font-size: 28px;\n    font-weight: bold;\n    background: linear-gradient(135deg, #667eea, #764ba2);\n    -webkit-background-clip: text;\n    -webkit-text-fill-color: transparent;\n    background-clip: text;\n    margin-bottom: 20px;\n  }\n\n  .detail-desc {\n    color: #666;\n    margin-bottom: 24px;\n    line-height: 1.6;\n    \n    strong {\n      color: #333;\n      display: block;\n      margin-bottom: 8px;\n    }\n    \n    p {\n      margin-bottom: 12px;\n    }\n  }\n\n  .buy-section {\n    margin-top: 16px;\n  }\n`\n\n// 统计数字样式\nconst StatsRow = styled.div`\n  display: flex;\n  justify-content: space-around;\n  margin: 20px 0 16px;\n  padding: 12px;\n  background: linear-gradient(135deg, #667eea08, #764ba208);\n  border-radius: 16px;\n`\n\nconst StatItem = styled.div`\n  text-align: center;\n  \n  .stat-number {\n    font-size: 20px;\n    font-weight: 700;\n    color: #667eea;\n  }\n  \n  .stat-label {\n    font-size: 12px;\n    color: #999;\n    margin-top: 4px;\n  }\n`\n\nconst About: React.FC = () => {\n  const { t } = useTranslation()\n  const technologies = ['Vue', 'React', 'TypeScript', 'JavaScript', 'Node.js', 'Java', 'Kotlin', 'Python', 'MySQL', 'Docker', 'Nginx']\n\n  const [isModalVisible, setIsModalVisible] = useState(false)\n  const [currentSlide, setCurrentSlide] = useState(0)\n  const [slideDirection, setSlideDirection] = useState<'left' | 'right'>('right')\n  \n  // 商品相关状态\n  const [products, setProducts] = useState<any[]>([])\n  const [loading, setLoading] = useState(false)\n  const [selectedProduct, setSelectedProduct] = useState<any>(null)\n  const [isDetailModalVisible, setIsDetailModalVisible] = useState(false)\n  const [buyLoading, setBuyLoading] = useState(false)\n  const [form] = useForm()\n\n  const slides = [\n    { image: payImage, title: t('about.supportMe') },\n    { image: wxImage, title: t('about.addMe') }\n  ]\n\n  // 获取商品列表\n  useEffect(() => {\n    const fetchProducts = async () => {\n      setLoading(true)\n      try {\n        const response = await fetch(`${import.meta.env.VITE_PAY_URL}/mapi/merchant/info`, {\n          method: 'GET',\n          headers: {\n            Authorization: `Bearer ${import.meta.env.VITE_PAY_BEARER_KEY}`,\n            'X-Idr-Locale': 'zh-cn',\n            'Content-Type': 'application/json',\n          },\n        })\n        \n        const data = await response.json()\n        if (data.code === 0 && data.result?.projects) {\n          const allProducts = data.result.projects.flatMap((project: any) => \n            (project.skus || []).map((sku: any) => ({\n              id: sku.id,\n              name: sku.name,\n              desc: sku.desc,\n              price: sku.pricing?.price,\n              currency: sku.pricing?.currency || 'CNY',\n              stock: sku.stock || 999999,\n              autoDelivery: sku.auto_delivery || true,\n              projectName: project.name,\n              projectId: project.id,\n              cover: project.cover,\n              link: project.link,\n            }))\n          )\n          setProducts(allProducts)\n        }\n      } catch (error) {\n        console.error('获取商品失败:', error)\n        message.error('获取商品列表失败')\n      } finally {\n        setLoading(false)\n      }\n    }\n    \n    fetchProducts()\n  }, [])\n\n  const handlePrevSlide = () => {\n    setSlideDirection('right')\n    setCurrentSlide(prev => (prev === 0 ? slides.length - 1 : prev - 1))\n  }\n\n  const handleNextSlide = () => {\n    setSlideDirection('left')\n    setCurrentSlide(prev => (prev === slides.length - 1 ? 0 : prev + 1))\n  }\n\n  // 打开商品详情\n  const handleOpenDetail = (product: any) => {\n    setSelectedProduct(product)\n    form.setFieldsValue({ quantity: '', contactInfo: '', coupon: '' })\n    setIsDetailModalVisible(true)\n  }\n\n  // 创建订单\n  const createOrder = async (values: any) => {\n    const { quantity, contactInfo, coupon } = values\n    const product = selectedProduct\n\n    const quantityNumber = parseInt(quantity, 10)\n\n    const res = await fetch(`${import.meta.env.VITE_PAY_URL}/mapi/order/add`, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n        Authorization: `Bearer ${import.meta.env.VITE_PAY_BEARER_KEY}`,\n        'X-Idr-Locale': 'zh-cn',\n      },\n      body: JSON.stringify({\n        projectId: product.projectId,\n        skuId: product.id,\n        orderInfo: {\n          maxQuantity: 100,\n          quantity: quantityNumber,\n          coupon: coupon || '',\n          contactInfo: contactInfo || ''\n        }\n      }),\n    })\n\n    const data = await res.json()\n    if (data.code !== 0) throw new Error(data.message || '创建订单失败')\n    return data.result.orderId\n  }\n\n  // 获取支付链接\n  const getPayUrl = async (orderId: string) => {\n    const res = await fetch(`${import.meta.env.VITE_PAY_URL}/mapi/order/pay`, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n        Authorization: `Bearer ${import.meta.env.VITE_PAY_BEARER_KEY}`,\n        'X-Idr-Locale': 'zh-cn',\n      },\n      body: JSON.stringify({\n        id: orderId,\n        method: 'alipay',\n        redirectUrl: window.location.href,\n      }),\n    })\n\n    const data = await res.json()\n    if (data.code !== 0) throw new Error(data.message || '获取支付链接失败')\n    return data.result.payUrl\n  }\n\n  // 下单主流程\n  const handleBuy = async () => {\n    try {\n      setBuyLoading(true)\n      const values = await form.validateFields()\n      message.loading('创建订单中...', 0)\n\n      const orderId = await createOrder(values)\n      message.destroy()\n      message.loading('获取支付链接...', 0)\n\n      const payUrl = await getPayUrl(orderId)\n      message.destroy()\n\n      Modal.info({\n        title: '订单创建成功',\n        content: '即将跳转到支付页面，请完成付款',\n        onOk: () => {\n          window.open(payUrl, '_blank')\n          setIsDetailModalVisible(false)\n        },\n      })\n    } catch (err: any) {\n      message.destroy()\n      message.error(err.message || '下单失败')\n    } finally {\n      setBuyLoading(false)\n    }\n  }\n\n  return (\n    <PageContainer>\n      <SectionTitle>\n        {t('about.title')}\n      </SectionTitle>\n      \n      {/* 三列布局 */}\n      <Row gutter={[24, 24]}>\n        {/* 第一列：个人信息 */}\n        <Col xs={24} md={8} lg={7}>\n          <ProfileCard>\n            <div className=\"profile-avatar\">\n              <img\n                src={meImage}\n                alt=\"My Logo\"\n                style={{ width: '112px', height: '112px', borderRadius: '50%', objectFit: 'cover' }}\n              />\n            </div>\n            <Title level={4} style={{ marginBottom: 8, color: '#1a1a2e' }}>\n              {t('about.name')}\n            </Title>\n            <Paragraph style={{ color: '#667eea', marginBottom: 8, fontWeight: 500 }}>\n              {t('about.role')}\n            </Paragraph>\n            <Paragraph style={{ color: '#64748b', fontSize: 14, marginBottom: 24 }}>\n              {t('about.description')}\n            </Paragraph>\n            \n            <StatsRow>\n              <StatItem>\n                <div className=\"stat-number\">10+</div>\n                <div className=\"stat-label\">{t('about.projectExperience')}</div>\n              </StatItem>\n              <StatItem>\n                <div className=\"stat-number\">15+</div>\n                <div className=\"stat-label\">{t('about.technologyStack')}</div>\n              </StatItem>\n              <StatItem>\n                <div className=\"stat-number\">100%</div>\n                <div className=\"stat-label\">{t('about.deliveryQuality')}</div>\n              </StatItem>\n            </StatsRow>\n\n            <SocialLinks>\n              <Tooltip title=\"GitHub\">\n                <a href=\"https://github.com/P1kaj1uu\" target=\"_blank\" rel=\"noopener noreferrer\">\n                  <GithubOutlined />\n                </a>\n              </Tooltip>\n              <Tooltip title=\"邮箱\">\n                <a href=\"mailto:891523233@qq.com\">\n                  <MailOutlined />\n                </a>\n              </Tooltip>\n              <Tooltip title=\"微信\">\n                <WeChatIcon onClick={() => setIsModalVisible(true)}>\n                  <WechatOutlined />\n                </WeChatIcon>\n              </Tooltip>\n            </SocialLinks>\n            \n            <Divider style={{ margin: '16px 0' }} />\n            \n            <TechList>\n              {technologies.map((tech, index) => (\n                <span key={index} className=\"tech-tag\">\n                  {tech}\n                </span>\n              ))}\n            </TechList>\n          </ProfileCard>\n        </Col>\n        \n        {/* 第二列：详细介绍 */}\n        <Col xs={24} md={16} lg={10}>\n          <AboutCard>\n            <Card.Meta\n              description={\n                <div>\n                  <Title level={5} style={{ color: '#667eea' }}>\n                    📋 {t('about.contact')}\n                  </Title>\n                  <ul style={{ paddingLeft: '20px', color: '#64748b', marginBottom: 24 }}>\n                    <li style={{ marginBottom: 8 }}>{t('about.wechat')}</li>\n                    <li>{t('about.email')}</li>\n                  </ul>\n                  \n                  <Divider style={{ margin: '16px 0' }} />\n                  \n                  <Title level={5} style={{ marginBottom: 16, color: '#667eea' }}>\n                    💼 {t('about.internship')}\n                  </Title>\n                  <ul style={{ paddingLeft: '20px', color: '#64748b', marginBottom: 24 }}>\n                    <li style={{ marginBottom: 8 }}>{t('about.internship1')}</li>\n                    <li>{t('about.internship2')}</li>\n                  </ul>\n                  \n                  <Divider style={{ margin: '16px 0' }} />\n                  \n                  <Title level={5} style={{ marginBottom: 16, color: '#667eea' }}>\n                    🏆 {t('about.awards')}\n                  </Title>\n                  <ul style={{ paddingLeft: '20px', color: '#64748b' }}>\n                    <li style={{ marginBottom: 8 }}>{t('about.award1')}</li>\n                    <li style={{ marginBottom: 8 }}>{t('about.award2')}</li>\n                    <li style={{ marginBottom: 8 }}>{t('about.award3')}</li>\n                    <li style={{ marginBottom: 8 }}>{t('about.award4')}</li>\n                    <li style={{ marginBottom: 8 }}>{t('about.award5')}</li>\n                    <li style={{ marginBottom: 8 }}>{t('about.award6')}</li>\n                    <li style={{ marginBottom: 8 }}>{t('about.award7')}</li>\n                    <li style={{ marginBottom: 8 }}>{t('about.award8')}</li>\n                    <li>{t('about.award9')}</li>\n                  </ul>\n                </div>\n              }\n            />\n          </AboutCard>\n        </Col>\n        \n        {/* 第三列：商品列表 */}\n        <Col xs={24} lg={7}>\n          <ProductsContainer>\n            <ProductsTitle>\n              <ShoppingOutlined style={{ color: '#667eea' }} /> {t('about.products')}\n              <Badge count={products.length} style={{ backgroundColor: '#667eea' }} />\n            </ProductsTitle>\n            \n            {loading ? (\n              <div style={{ textAlign: 'center', padding: '60px' }}>\n                <Spin size=\"large\" tip={t('about.loadingProducts')} />\n              </div>\n            ) : products.length > 0 ? (\n              <div>\n                {/* @ts-ignore */}\n                {products.map((product, idx) => (\n                  <ProductCard key={product.id} onClick={() => handleOpenDetail(product)}>\n                    <ProductHeader>\n                      <ProductName>\n                        <ThunderboltOutlined style={{ color: '#667eea', fontSize: 14 }} />\n                        {product.name}\n                      </ProductName>\n                      <ProductTags>\n                        {product.autoDelivery && (\n                          <Tag icon={<CheckCircleOutlined />} color=\"success\" style={{ borderRadius: 12 }}>\n                            {t('about.autoDelivery')}\n                          </Tag>\n                        )}\n                        {product.stock < 100 && (\n                          <Tag icon={<ClockCircleOutlined />} color=\"orange\" style={{ borderRadius: 12 }}>\n                            {t('about.stockShort')}\n                          </Tag>\n                        )}\n                      </ProductTags>\n                    </ProductHeader>\n                    <ProductDesc type=\"secondary\" ellipsis={{ rows: 2 }}>\n                      {product.desc || '无限制使用网站所有功能'}\n                    </ProductDesc>\n                    <ProductPrice>\n                      <DollarOutlined />\n                      {product.price}\n                      <PriceUnit>USD / 件</PriceUnit>\n                    </ProductPrice>\n                  </ProductCard>\n                ))}\n              </div>\n            ) : (\n              <div style={{ textAlign: 'center', padding: '60px', color: '#999', background: '#fafafa', borderRadius: 16 }}>\n                <ShoppingOutlined style={{ fontSize: 48, marginBottom: 16, opacity: 0.5 }} />\n                <Paragraph style={{ color: '#999' }}>{t('about.noProducts')}</Paragraph>\n              </div>\n            )}\n\n            {/* 数字商品购买须知 */}\n            <NoticeSection>\n              <div className=\"notice-title\">\n                <FileProtectOutlined /> {t('about.digitalGoodsNotice')}\n              </div>\n              <ul className=\"notice-list\">\n                <li className=\"red\">\n                  <ExclamationCircleOutlined style={{ marginRight: 6 }} />\n                  {t('about.importantNotice')}\n                </li>\n              </ul>\n            </NoticeSection>\n          </ProductsContainer>\n        </Col>\n      </Row>\n\n      {/* 微信/支付宝弹窗 */}\n      <Modal\n        open={isModalVisible}\n        onCancel={() => setIsModalVisible(false)}\n        footer={null}\n        width={520}\n        centered\n        styles={{ body: { padding: 0 } }}\n      >\n        <ModalContent>\n          <CarouselContainer>\n            <NavigationButton className=\"prev\" onClick={handlePrevSlide}>\n              ‹\n            </NavigationButton>\n            <NavigationButton className=\"next\" onClick={handleNextSlide}>\n              ›\n            </NavigationButton>\n\n            {slides.map((slide, index) => (\n              <CarouselSlide key={index} isVisible={index === currentSlide} slideDirection={slideDirection}>\n                <SlideTitle>{slide.title}</SlideTitle>\n                <QRImage src={slide.image} alt={slide.title} />\n              </CarouselSlide>\n            ))}\n          </CarouselContainer>\n        </ModalContent>\n      </Modal>\n\n      {/* 商品详情弹窗 */}\n      <DetailModal\n        open={isDetailModalVisible}\n        onCancel={() => {\n          setIsDetailModalVisible(false)\n          setSelectedProduct(null)\n          form.resetFields()\n        }}\n        footer={null}\n        width={580}\n        centered\n        title={null}\n        afterClose={() => {\n          form.resetFields()\n          setSelectedProduct(null)\n        }}\n      >\n        {selectedProduct && (\n          <>\n            <div className=\"detail-header\">\n              <div className=\"detail-title\">{selectedProduct.name}</div>\n              <div className=\"detail-info\">\n                <span className=\"detail-info-item\">\n                  <InboxOutlined /> 库存: {selectedProduct.stock}\n                </span>\n                {selectedProduct.autoDelivery && (\n                  <span className=\"detail-info-item\">\n                    <CheckCircleOutlined style={{ color: '#00b42a' }} /> 自动发货\n                  </span>\n                )}\n                <span className=\"detail-info-item\">\n                  <CustomerServiceOutlined /> 7x24h 售后\n                </span>\n              </div>\n            </div>\n\n            {selectedProduct.cover && (\n              <img\n                src={selectedProduct.cover}\n                alt={selectedProduct.name}\n                className=\"detail-image\"\n              />\n            )}\n            \n            <div className=\"detail-price\">\n              ${selectedProduct.price} <span style={{ fontSize: 14, fontWeight: 'normal', color: '#999' }}>USD / 件</span>\n            </div>\n            \n            <div className=\"detail-desc\">\n              <strong>📝 商品描述：</strong>\n              <p>{selectedProduct.desc || '无限制使用网站所有功能'}</p>\n              {selectedProduct.link && (\n                <p style={{ marginTop: 8 }}>\n                  <strong>🔗 文档链接：</strong>\n                  <a href={selectedProduct.link} target=\"_blank\" rel=\"noopener noreferrer\">\n                    查看详情文档 →\n                  </a>\n                </p>\n              )}\n            </div>\n\n            <Form form={form} layout=\"vertical\" className=\"buy-section\">\n              <Form.Item\n                name=\"quantity\"\n                label=\"购买数量\"\n                rules={[{ required: true, min: 1, message: '请输入购买数量' }]}\n              >\n                <Input placeholder='请输入购买数量' autoComplete='off' type=\"number\" min={1} max={selectedProduct.stock} style={{ width: '100%' }} />\n              </Form.Item>\n\n              <Form.Item\n                name=\"contactInfo\"\n                label=\"联系方式（用于找回订单）\"\n                rules={[{ required: true, message: '请输入联系方式' }]}\n              >\n                <Input autoComplete='off' placeholder=\"邮箱/QQ/微信/手机号\" />\n              </Form.Item>\n\n              <Form.Item name=\"coupon\" label=\"优惠券（可选）\">\n                <Input autoComplete='off' placeholder=\"输入优惠码\" />\n              </Form.Item>\n\n              <Button\n                type=\"primary\"\n                size=\"large\"\n                block\n                loading={buyLoading}\n                onClick={handleBuy}\n                style={{\n                  background: 'linear-gradient(135deg, #667eea, #764ba2)',\n                  border: 'none',\n                  borderRadius: 12,\n                  height: 48,\n                  fontSize: 16,\n                }}\n              >\n                立即下单\n              </Button>\n            </Form>\n          </>\n        )}\n      </DetailModal>\n    </PageContainer>\n  )\n}\n\nexport default About"
  },
  {
    "path": "src/pages/Cartoon.tsx",
    "content": "import React, { useState, useEffect } from 'react'\nimport {\n  Typography,\n  Row,\n  Col,\n  Card,\n  Tabs,\n  Spin,\n  message,\n  Image,\n  Tag,\n  Input,\n  Space\n} from 'antd'\nimport {\n  SearchOutlined,\n  StarOutlined,\n  EyeOutlined\n} from '@ant-design/icons'\nimport { useNavigate } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport styled from 'styled-components'\n\nconst { Title, Text, Paragraph } = Typography\nconst { Search } = Input\n\nconst CartoonContainer = styled.div`\n  width: 100%;\n  min-height: calc(100vh - 64px);\n  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);\n  padding: 80px 24px 24px;\n\n  @media (max-width: 768px) {\n    padding: 70px 16px 16px;\n  }\n`\n\nconst ContentWrapper = styled.div`\n  max-width: 1400px;\n  margin: 0 auto;\n`\n\nconst StyledCard = styled(Card)`\n  border-radius: 12px;\n  overflow: hidden;\n  transition: all 0.3s ease;\n  cursor: pointer;\n  height: 100%;\n\n  &:hover {\n    transform: translateY(-4px);\n    box-shadow: 0 8px 24px rgba(102, 126, 234, 0.2);\n  }\n\n  .ant-card-cover {\n    overflow: hidden;\n  }\n\n  .ant-card-cover img {\n    transition: transform 0.3s ease;\n  }\n\n  &:hover .ant-card-cover img {\n    transform: scale(1.05);\n  }\n\n  .ant-card-body {\n    padding: 16px;\n  }\n`\n\nconst CartoonImage = styled(Image)`\n  width: 100%;\n  height: 280px;\n  object-fit: cover;\n\n  @media (max-width: 768px) {\n    height: 200px;\n  }\n`\n\nconst DescriptionText = styled.div`\n  font-size: 12px;\n  color: rgba(0, 0, 0, 0.45);\n  display: -webkit-box;\n  -webkit-line-clamp: 2;\n  -webkit-box-orient: vertical;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  line-height: 1.5;\n  max-height: 36px;\n  word-break: break-word;\n`\n\nconst HeaderSection = styled.div`\n  margin-bottom: 32px;\n  text-align: center;\n\n  h1 {\n    font-size: 2.5rem;\n    font-weight: bold;\n    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n    -webkit-background-clip: text;\n    -webkit-text-fill-color: transparent;\n    background-clip: text;\n    margin-bottom: 8px;\n  }\n\n  p {\n    font-size: 1rem;\n    color: #666;\n  }\n`\n\nconst StyledTabs = styled(Tabs)`\n  .ant-tabs-nav {\n    margin-bottom: 24px;\n  }\n\n  .ant-tabs-tab {\n    font-size: 16px;\n    font-weight: 500;\n  }\n`\n\ninterface RankType {\n  rank_id: number;\n  title: string;\n  description: string;\n}\n\ninterface Topic {\n  id: number;\n  title: string;\n  description: string;\n  cover?: string;\n  views_count: number;\n  likes_count: number;\n  is_finish: number;\n}\n\ninterface CartoonData {\n  id: number;\n  title: string;\n  description: string;\n  cover?: string;\n  views_count?: number;\n  likes_count?: number;\n  is_finish?: number;\n}\n\nconst Cartoon: React.FC = () => {\n  const { t } = useTranslation()\n  const navigate = useNavigate()\n  const [loading, setLoading] = useState(false)\n  const [rankTypes, setRankTypes] = useState<RankType[]>([])\n  const [cartoonList, setCartoonList] = useState<CartoonData[]>([])\n  const [selectedRankId, setSelectedRankId] = useState<number | null>(null)\n  const [searchKeyword, setSearchKeyword] = useState('')\n  const [isSearching, setIsSearching] = useState(false)\n  const [searchResults, setSearchResults] = useState<CartoonData[]>([])\n\n  // 获取排行榜类型列表\n  useEffect(() => {\n    fetchRankTypes()\n  }, [])\n\n  // 获取排行榜类型列表\n  const fetchRankTypes = async () => {\n    try {\n      setLoading(true)\n      const response = await fetch((`/api/kuaikan/v2/pweb/rank_type_list`))\n      const data = await response.json()\n\n      if (data.data && data.data.rank_types) {\n        setRankTypes(data.data.rank_types)\n        // 默认选择第一个排行榜\n        if (data.data.rank_types.length > 0) {\n          const firstRankId = data.data.rank_types[0].rank_id\n          setSelectedRankId(firstRankId)\n          fetchCartoonList(firstRankId)\n        }\n      }\n    } catch (error) {\n      console.error('获取排行榜类型失败:', error)\n      message.error(t('cartoon.fetchRankTypesFailed'))\n    } finally {\n      setLoading(false)\n    }\n  }\n\n  // 获取漫画列表\n  const fetchCartoonList = async (rankId: number) => {\n    try {\n      setLoading(true)\n      const response = await fetch(\n        `/api/kuaikan/v2/pweb/rank/topics?rank_id=${rankId}`\n      )\n      const data = await response.json()\n\n      if (data.data && data.data.rank_info && data.data.rank_info.topics) {\n        const topics: Topic[] = data.data.rank_info.topics\n        const formattedData: CartoonData[] = topics.map(topic => ({\n          id: topic.id,\n          title: topic.title,\n          description: topic.description,\n          // @ts-ignore\n          cover: topic.cover_image_url,\n          views_count: topic.views_count,\n          likes_count: topic.likes_count,\n          is_finish: topic.is_finish\n        }))\n        setCartoonList(formattedData)\n      }\n    } catch (error) {\n      console.error('获取漫画列表失败:', error)\n      message.error(t('cartoon.fetchCartoonListFailed'))\n    } finally {\n      setLoading(false)\n    }\n  }\n\n  // 处理排行榜切换\n  const handleTabChange = (key: string) => {\n    const rankId = parseInt(key)\n    setSelectedRankId(rankId)\n    fetchCartoonList(rankId)\n  }\n\n  // 处理漫画卡片点击\n  const handleCardClick = (cartoon: CartoonData) => {\n    navigate(`/cartoon/${cartoon.id}`)\n  }\n\n  // 格式化数字显示\n  const formatNumber = (num: number = 0) => {\n    if (num >= 10000) {\n      return (num / 10000).toFixed(1) + '万'\n    }\n    return num.toString()\n  }\n\n  // 搜索漫画\n  const handleSearch = async (keyword: string) => {\n    if (!keyword.trim()) {\n      message.warning(t('cartoon.enterKeyword'))\n      return\n    }\n\n    try {\n      setLoading(true)\n      setIsSearching(true)\n      const response = await fetch((`/api/kuaikan/v1/search/topic?q=${encodeURIComponent(keyword)}&f=3&size=18`))\n      const data = await response.json()\n\n      if (data.data && data.data.hit) {\n        const hitList: Topic[] = data.data.hit\n        const formattedData: CartoonData[] = hitList.map(topic => ({\n          id: topic.id,\n          title: topic.title,\n          description: topic.description,\n          // @ts-ignore\n          cover: topic.cover_image_url,\n          views_count: topic.views_count,\n          likes_count: topic.likes_count,\n          is_finish: topic.is_finish\n        }))\n        setSearchResults(formattedData)\n        message.success(t('cartoon.foundResults').replace('X', formattedData.length.toString()))\n      } else {\n        setSearchResults([])\n        message.info(t('cartoon.noResults'))\n      }\n    } catch (error) {\n      console.error('搜索失败:', error)\n      message.error(t('cartoon.searchFailed'))\n    } finally {\n      setLoading(false)\n    }\n  }\n\n  // 清除搜索\n  const handleClearSearch = () => {\n    setIsSearching(false)\n    setSearchResults([])\n    setSearchKeyword('')\n  }\n\n  const tabItems = rankTypes.map(rankType => ({\n    key: rankType.rank_id.toString(),\n    label: rankType.title\n  }))\n\n  return (\n    <CartoonContainer>\n      <ContentWrapper>\n        <HeaderSection>\n          <Title>{t('cartoon.subTitle')}</Title>\n          <Paragraph>{t('cartoon.description')}</Paragraph>\n          <Search\n            placeholder={t('cartoon.searchPlaceholder')}\n            allowClear\n            enterButton={<SearchOutlined />}\n            size=\"large\"\n            style={{ maxWidth: 500, marginTop: 16 }}\n            value={searchKeyword}\n            onChange={e => setSearchKeyword(e.target.value)}\n            onSearch={value => {\n              if (value) {\n                handleSearch(value)\n              } else {\n                handleClearSearch()\n              }\n            }}\n            onClear={handleClearSearch}\n          />\n        </HeaderSection>\n\n        <Spin spinning={loading} tip={t('common.loading')}>\n          {isSearching ? (\n            <>\n              {searchResults.length > 0 && (\n                <div style={{ marginBottom: 16 }}>\n                  <Space>\n                    <Text type=\"secondary\">\n                      {t('cartoon.searchResults')} <Text strong>{searchResults.length}</Text> {t('cartoon.relatedCartoons')}\n                    </Text>\n                  </Space>\n                </div>\n              )}\n\n              <Row gutter={[24, 24]}>\n                {searchResults.map(cartoon => (\n                  <Col xs={12} sm={8} md={6} lg={4} xl={4} key={cartoon.id}>\n                    <StyledCard\n                      hoverable\n                      cover={\n                        <div\n                          style={{ overflow: 'hidden', position: 'relative' }}\n                          onClick={() => handleCardClick(cartoon)}\n                        >\n                          <CartoonImage\n                            src={cartoon.cover}\n                            alt={cartoon.title}\n                            preview={false}\n                          />\n                          {cartoon.is_finish === 1 && (\n                            <Tag color=\"success\" style={{ position: 'absolute', top: 8, right: 8 }}>\n                              {t('cartoon.finished')}\n                            </Tag>\n                          )}\n                        </div>\n                      }\n                      onClick={() => handleCardClick(cartoon)}\n                    >\n                      <Card.Meta\n                        title={\n                          <Text ellipsis={{ tooltip: cartoon.title }} strong>\n                            {cartoon.title}\n                          </Text>\n                        }\n                        description={\n                          <Space direction=\"vertical\" size={4}>\n                            <DescriptionText title={cartoon.description}>\n                              {cartoon.description}\n                            </DescriptionText>\n                            <Space size={12}>\n                              {cartoon.views_count && (\n                                <Text type=\"secondary\" style={{ fontSize: 12 }}>\n                                  <EyeOutlined /> {formatNumber(cartoon.views_count)}\n                                </Text>\n                              )}\n                              {cartoon.likes_count && (\n                                <Text type=\"secondary\" style={{ fontSize: 12 }}>\n                                  <StarOutlined /> {formatNumber(cartoon.likes_count)}\n                                </Text>\n                              )}\n                            </Space>\n                          </Space>\n                        }\n                      />\n                    </StyledCard>\n                  </Col>\n                ))}\n              </Row>\n\n              {searchResults.length === 0 && !loading && (\n                <div style={{ textAlign: 'center', padding: '60px 0', color: '#999' }}>\n                  {t('cartoon.noResults')}\n                </div>\n              )}\n            </>\n          ) : (\n            <>\n              <StyledTabs\n                activeKey={selectedRankId?.toString() || ''}\n                items={tabItems}\n                onChange={handleTabChange}\n                type=\"card\"\n              />\n\n              <Row gutter={[24, 24]}>\n                {cartoonList.map(cartoon => (\n                  <Col xs={12} sm={8} md={6} lg={4} xl={4} key={cartoon.id}>\n                    <StyledCard\n                      hoverable\n                      cover={\n                        <div\n                          style={{ overflow: 'hidden', position: 'relative' }}\n                          onClick={() => handleCardClick(cartoon)}\n                        >\n                          <CartoonImage\n                            src={cartoon.cover}\n                            alt={cartoon.title}\n                            preview={false}\n                          />\n                          {cartoon.is_finish === 1 && (\n                            <Tag color=\"success\" style={{ position: 'absolute', top: 8, right: 8 }}>\n                              {t('cartoon.finished')}\n                            </Tag>\n                          )}\n                        </div>\n                      }\n                      onClick={() => handleCardClick(cartoon)}\n                    >\n                      <Card.Meta\n                        title={\n                          <Text ellipsis={{ tooltip: cartoon.title }} strong>\n                            {cartoon.title}\n                          </Text>\n                        }\n                        description={\n                          <Space direction=\"vertical\" size={4}>\n                            <DescriptionText title={cartoon.description}>\n                              {cartoon.description}\n                            </DescriptionText>\n                            <Space size={12}>\n                              {cartoon.views_count && (\n                                <Text type=\"secondary\" style={{ fontSize: 12 }}>\n                                  <EyeOutlined /> {formatNumber(cartoon.views_count)}\n                                </Text>\n                              )}\n                              {cartoon.likes_count && (\n                                <Text type=\"secondary\" style={{ fontSize: 12 }}>\n                                  <StarOutlined /> {formatNumber(cartoon.likes_count)}\n                                </Text>\n                              )}\n                            </Space>\n                          </Space>\n                        }\n                      />\n                    </StyledCard>\n                  </Col>\n                ))}\n              </Row>\n\n              {cartoonList.length === 0 && !loading && (\n                <div style={{ textAlign: 'center', padding: '60px 0', color: '#999' }}>\n                  {t('cartoon.noData')}\n                </div>\n              )}\n            </>\n          )}\n        </Spin>\n      </ContentWrapper>\n    </CartoonContainer>\n  )\n}\n\nexport default Cartoon\n"
  },
  {
    "path": "src/pages/CartoonChapter.tsx",
    "content": "import React, { useState, useEffect } from 'react'\nimport { useParams, useNavigate } from 'react-router-dom'\nimport {\n  Typography,\n  Spin,\n  message,\n  Button,\n  Space,\n  Card,\n  Row,\n  Col\n} from 'antd'\nimport {\n  ArrowLeftOutlined,\n  ArrowRightOutlined,\n  BookOutlined,\n  VerticalAlignTopOutlined\n} from '@ant-design/icons'\nimport { useTranslation } from 'react-i18next'\nimport styled from 'styled-components'\n\nconst { Title, Paragraph } = Typography\n\nconst ChapterContainer = styled.div`\n  width: 100%;\n  min-height: calc(100vh - 64px);\n  background: #f0f2f5;\n  padding: 80px 24px 24px;\n\n  @media (max-width: 768px) {\n    padding: 70px 16px 16px;\n  }\n`\n\nconst ContentWrapper = styled.div`\n  max-width: 900px;\n  margin: 0 auto;\n`\n\nconst HeaderBar = styled.div`\n  background: white;\n  padding: 16px 24px;\n  border-radius: 12px;\n  margin-bottom: 24px;\n  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  flex-wrap: wrap;\n  gap: 16px;\n\n  @media (max-width: 768px) {\n    flex-direction: column;\n    align-items: stretch;\n  }\n`\n\nconst ComicImage = styled.img`\n  width: 100%;\n  height: auto;\n  display: block;\n  margin: 0 auto;\n  background: #f5f5f5;\n\n  @media (max-width: 768px) {\n    max-width: 100%;\n  }\n`\n\nconst NavigationButton = styled(Button)`\n  border-radius: 20px;\n  height: 40px;\n  font-weight: 500;\n\n  &:hover {\n    transform: translateY(-2px);\n    box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);\n  }\n\n  &:disabled {\n    cursor: not-allowed;\n    &:hover {\n      transform: none;\n      box-shadow: none;\n    }\n  }\n`\n\nconst BackToTopButton = styled.button<{ $visible: boolean }>`\n  position: fixed;\n  right: 24px;\n  bottom: 80px;\n  z-index: 10000;\n  width: 56px;\n  height: 56px;\n  border-radius: 50%;\n  border: none;\n  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n  color: white;\n  font-size: 24px;\n  cursor: pointer;\n  display: ${props => props.$visible ? 'flex' : 'none'};\n  align-items: center;\n  justify-content: center;\n  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);\n  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n  opacity: ${props => props.$visible ? 1 : 0};\n  transform: ${props => props.$visible ? 'translateY(0)' : 'translateY(20px)'};\n  pointer-events: ${props => props.$visible ? 'auto' : 'none'};\n\n  &:hover {\n    background: linear-gradient(135deg, #764ba2 0%, #667eea 100%);\n    transform: translateY(-4px);\n    box-shadow: 0 8px 24px rgba(102, 126, 234, 0.5);\n  }\n\n  &:active {\n    transform: translateY(-2px);\n    box-shadow: 0 4px 16px rgba(102, 126, 234, 0.4);\n  }\n\n  &:focus {\n    outline: none;\n    box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4), 0 0 0 3px rgba(102, 126, 234, 0.1);\n  }\n\n  @media (max-width: 768px) {\n    right: 16px;\n    bottom: 70px;\n    width: 48px;\n    height: 48px;\n    font-size: 20px;\n  }\n`\n\ninterface ComicInfo {\n  id: number;\n  title: string;\n  comic_images: Array<{ url: string }>;\n  topic_id: number;\n  order: number;\n  previous_comic_info?: {\n    id: number;\n    title: string;\n  };\n  next_comic_info?: {\n    id: number;\n    title: string;\n  };\n}\n\nconst CartoonChapter: React.FC = () => {\n  const { t } = useTranslation()\n  const { comicId } = useParams<{ comicId: string }>()\n  const navigate = useNavigate()\n  const [loading, setLoading] = useState(false)\n  const [comicInfo, setComicInfo] = useState<ComicInfo | null>(null)\n  const [nextComicInfo, setNextComicInfo] = useState<ComicInfo | null>(null)\n  const [previousComicInfo, setPreviousComicInfo] = useState<ComicInfo | null>(null)\n  const [topicInfo, setTopicInfo] = useState<any>(null)\n  const [showBackToTop, setShowBackToTop] = useState(false)\n\n  useEffect(() => {\n    if (comicId) {\n      fetchComicDetail(Number(comicId))\n      scrollToTop()\n    }\n  }, [comicId])\n\n  // 监听滚动，显示/隐藏返回顶部按钮\n  useEffect(() => {\n    const handleScroll = () => {\n      setShowBackToTop(window.scrollY > 400)\n    }\n\n    window.addEventListener('scroll', handleScroll)\n    return () => window.removeEventListener('scroll', handleScroll)\n  }, [])\n\n  // 返回顶部\n  const scrollToTop = () => {\n    window.scrollTo({\n      top: 0,\n      behavior: 'smooth'\n    })\n  }\n\n  // 获取章节详情\n  const fetchComicDetail = async (id: number) => {\n    try {\n      setLoading(true)\n      const response = await fetch((`/api/kuaikan/v2/pweb/comic/${id}`))\n      const data = await response.json()\n\n      if (data.data && data.data.comic_info) {\n        setComicInfo(data.data.comic_info)\n        setNextComicInfo(data.data.next_comic_info)\n        setPreviousComicInfo(data.data.previous_comic_info)\n        setTopicInfo(data.data.topic_info)\n      } else {\n        message.error(t('cartoonChapter.fetchChapterFailed'))\n      }\n    } catch (error) {\n      console.error('获取章节内容失败:', error)\n      message.error(t('cartoonChapter.fetchChapterFailed'))\n    } finally {\n      setLoading(false)\n    }\n  }\n\n  // 上一章\n  const handlePrevious = () => {\n    if (previousComicInfo?.id) {\n      navigate(`/cartoon/chapter/${previousComicInfo.id}`)\n      scrollToTop()\n    } else {\n      message.warning(t('cartoonChapter.alreadyFirstChapter'))\n    }\n  }\n\n  // 下一章\n  const handleNext = () => {\n    if (nextComicInfo?.id) {\n      navigate(`/cartoon/chapter/${nextComicInfo.id}`)\n      scrollToTop()\n    } else {\n      message.info(t('cartoonChapter.alreadyLastChapter'))\n    }\n  }\n\n  // 返回详情页\n  const handleBack = () => {\n    if (comicInfo) {\n      navigate(`/cartoon/${topicInfo.id}`)\n    } else {\n      navigate('/cartoon')\n    }\n  }\n\n  if (loading) {\n    return (\n      <ChapterContainer>\n        <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', minHeight: '60vh' }}>\n          <Spin size=\"large\" tip={t('common.loading')} />\n        </div>\n      </ChapterContainer>\n    )\n  }\n\n  if (!comicInfo) {\n    return (\n      <ChapterContainer>\n        <ContentWrapper>\n          <NavigationButton\n            type=\"default\"\n            icon={<ArrowLeftOutlined />}\n            onClick={handleBack}\n          >\n            {t('cartoonChapter.backToDetail')}\n          </NavigationButton>\n          <div style={{ textAlign: 'center', padding: '60px 0', color: '#999' }}>\n            {t('cartoonChapter.noContent')}\n          </div>\n        </ContentWrapper>\n      </ChapterContainer>\n    )\n  }\n\n  return (\n    <>\n      <ChapterContainer>\n      <ContentWrapper>\n        <HeaderBar>\n          <Space direction=\"vertical\" size={4}>\n            <Title level={4} style={{ margin: 0 }}>\n              {comicInfo.title}\n            </Title>\n            <Paragraph type=\"secondary\" style={{ margin: 0, fontSize: 12 }}>\n              {t('cartoonChapter.total')} {comicInfo.comic_images?.length || 0} {t('cartoonChapter.pages')}\n            </Paragraph>\n          </Space>\n\n          <Space wrap>\n            <NavigationButton\n              type=\"default\"\n              icon={<ArrowLeftOutlined />}\n              onClick={handlePrevious}\n              disabled={!previousComicInfo?.id}\n            >\n              {t('cartoon.prevChapter')}\n            </NavigationButton>\n            <NavigationButton\n              type=\"default\"\n              onClick={handleBack}\n            >\n              {t('cartoonChapter.backToDetail')}\n            </NavigationButton>\n            <NavigationButton\n              type=\"primary\"\n              onClick={handleNext}\n              icon={<ArrowRightOutlined />}\n              disabled={!nextComicInfo?.id}\n            >\n              {t('cartoon.nextChapter')}\n            </NavigationButton>\n          </Space>\n        </HeaderBar>\n\n        <Card\n          bordered={false}\n          style={{ borderRadius: 12, boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)' }}\n        >\n          {comicInfo.comic_images && comicInfo.comic_images.length > 0 ? (\n            <div>\n              {comicInfo.comic_images.map((imageUrl, index) => (\n                <ComicImage\n                  key={index}\n                  // @ts-ignore\n                  src={imageUrl.url}\n                  alt={`${comicInfo.title} - ${t('cartoonChapter.page')} ${index + 1}`}\n                  loading=\"lazy\"\n                />\n              ))}\n            </div>\n          ) : (\n            <div style={{ textAlign: 'center', padding: '60px 0', color: '#999' }}>\n              {t('cartoonChapter.noContent')}\n            </div>\n          )}\n        </Card>\n\n        <Row gutter={[16, 16]} style={{ marginTop: 24 }}>\n          <Col span={8}>\n            <NavigationButton\n              type=\"default\"\n              block\n              icon={<ArrowLeftOutlined />}\n              onClick={handlePrevious}\n              disabled={!previousComicInfo?.id}\n            >\n              {t('cartoon.prevChapter')}\n            </NavigationButton>\n          </Col>\n          <Col span={8}>\n            <NavigationButton\n              type=\"default\"\n              block\n              onClick={handleBack}\n              icon={<BookOutlined />}\n            >\n              {t('cartoonChapter.backToDetail')}\n            </NavigationButton>\n          </Col>\n          <Col span={8}>\n            <NavigationButton\n              type=\"primary\"\n              block\n              onClick={handleNext}\n              icon={<ArrowRightOutlined />}\n              disabled={!nextComicInfo?.id}\n            >\n              {t('cartoon.nextChapter')}\n            </NavigationButton>\n          </Col>\n        </Row>\n      </ContentWrapper>\n    </ChapterContainer>\n\n    {/* 返回顶部按钮 - 移到容器外部 */}\n    <BackToTopButton\n      $visible={showBackToTop}\n      onClick={scrollToTop}\n      aria-label={t('cartoonChapter.backToTop')}\n    >\n      <VerticalAlignTopOutlined />\n    </BackToTopButton>\n  </>\n)}\n\nexport default CartoonChapter\n"
  },
  {
    "path": "src/pages/CartoonDetail.tsx",
    "content": "import React, { useState, useEffect } from 'react'\nimport { useParams, useNavigate } from 'react-router-dom'\nimport {\n  Typography,\n  Row,\n  Col,\n  Card,\n  Spin,\n  message,\n  Image,\n  Tag,\n  Button,\n  Space,\n  Divider,\n  List\n} from 'antd'\nimport {\n  ArrowLeftOutlined,\n  BookOutlined,\n  EyeOutlined,\n  StarOutlined,\n  UserOutlined,\n  ReadOutlined\n} from '@ant-design/icons'\nimport { useTranslation } from 'react-i18next'\nimport styled from 'styled-components'\n\nconst { Title, Text, Paragraph } = Typography\n\nconst DetailContainer = styled.div`\n  width: 100%;\n  min-height: calc(100vh - 64px);\n  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);\n  padding: 80px 24px 24px;\n\n  @media (max-width: 768px) {\n    padding: 70px 16px 16px;\n  }\n`\n\nconst ContentWrapper = styled.div`\n  max-width: 1200px;\n  margin: 0 auto;\n`\n\nconst HeaderCard = styled(Card)`\n  border-radius: 16px;\n  overflow: hidden;\n  margin-bottom: 24px;\n  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);\n`\n\nconst CoverImage = styled(Image)`\n  width: 100%;\n  max-width: 300px;\n  border-radius: 12px;\n  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n\n  @media (max-width: 768px) {\n    max-width: 200px;\n  }\n`\n\nconst InfoSection = styled.div`\n  padding: 24px;\n\n  .ant-typography {\n    margin-bottom: 12px;\n  }\n`\n\nconst ChapterList = styled(Card)`\n  border-radius: 16px;\n  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);\n\n  .ant-list-item {\n    padding: 16px 24px;\n    cursor: pointer;\n    transition: all 0.3s ease;\n\n    &:hover {\n      background: rgba(102, 126, 234, 0.05);\n    }\n  }\n`\n\nconst BackButton = styled(Button)`\n  margin-bottom: 24px;\n  border-radius: 20px;\n  height: 40px;\n  padding: 0 24px;\n  font-weight: 500;\n\n  &:hover {\n    transform: translateX(-4px);\n  }\n`\n\ninterface TopicInfo {\n  id: number;\n  title: string;\n  description: string;\n  cover: string;\n  views_count: number;\n  likes_count: number;\n  is_finish: number;\n  author: {\n    name: string;\n  };\n  tag_list: Array<{\n    id: number;\n    title: string;\n  }>;\n  comics: Array<{\n    id: number;\n    title: string;\n    cover: string;\n    order: number;\n  }>;\n}\n\nconst CartoonDetail: React.FC = () => {\n  const { t } = useTranslation()\n  const { id } = useParams<{ id: string }>()\n  const navigate = useNavigate()\n  const [loading, setLoading] = useState(false)\n  const [topicInfo, setTopicInfo] = useState<TopicInfo | null>(null)\n\n  useEffect(() => {\n    if (id) {\n      fetchTopicDetail(Number(id))\n    }\n  }, [id])\n\n  // 获取漫画详情\n  const fetchTopicDetail = async (topicId: number) => {\n    try {\n      setLoading(true)\n      const response = await fetch((`/api/kuaikan/v2/pweb/topic/${topicId}`))\n      const data = await response.json()\n\n      if (data.data && data.data.topic_info) {\n        setTopicInfo(data.data.topic_info)\n      } else {\n        message.error(t('cartoonDetail.fetchDetailFailed'))\n      }\n    } catch (error) {\n      console.error('获取漫画详情失败:', error)\n      message.error(t('cartoonDetail.fetchDetailFailed'))\n    } finally {\n      setLoading(false)\n    }\n  }\n\n  // 处理章节点击\n  const handleChapterClick = async (comicId: number) => {\n    try {\n      const response = await fetch((`/api/kuaikan/v2/pweb/comic/${comicId}`))\n      const data = await response.json()\n    \n      if (data.data && data.data.comic_info && data.data.comic_info.comic_images) {\n        navigate(`/cartoon/chapter/${comicId}`)\n      } else {\n        message.warning(t('cartoonChapter.noContent'))\n      }\n    } catch (error) {\n      console.error('获取章节内容失败:', error)\n      message.error(t('cartoonChapter.fetchChapterFailed'))\n    }\n  }\n\n  // 格式化数字显示\n  const formatNumber = (num: number = 0) => {\n    if (num >= 10000) {\n      return (num / 10000).toFixed(1) + '万'\n    }\n    return num.toString()\n  }\n\n  if (loading) {\n    return (\n      <DetailContainer>\n        <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', minHeight: '60vh' }}>\n          <Spin size=\"large\" tip={t('common.loading')} />\n        </div>\n      </DetailContainer>\n    )\n  }\n\n  if (!topicInfo) {\n    return (\n      <DetailContainer>\n        <ContentWrapper>\n          <BackButton\n            type=\"default\"\n            icon={<ArrowLeftOutlined />}\n            onClick={() => navigate('/cartoon')}\n          >\n            {t('cartoonDetail.backToList')}\n          </BackButton>\n          <div style={{ textAlign: 'center', padding: '60px 0', color: '#999' }}>\n            {t('cartoonDetail.notFound')}\n          </div>\n        </ContentWrapper>\n      </DetailContainer>\n    )\n  }\n\n  return (\n    <DetailContainer>\n      <ContentWrapper>\n        <BackButton\n          type=\"default\"\n          icon={<ArrowLeftOutlined />}\n          onClick={() => navigate('/cartoon')}\n        >\n          {t('cartoonDetail.backToList')}\n        </BackButton>\n\n        <HeaderCard>\n          <Row gutter={[32, 32]}>\n            <Col xs={24} sm={8} md={6} style={{ display: 'flex', justifyContent: 'center' }}>\n              <CoverImage\n                // @ts-ignore\n                src={topicInfo.cover_image_url}\n                alt={topicInfo.title}\n                preview={false}\n              />\n            </Col>\n            <Col xs={24} sm={16} md={18}>\n              <InfoSection>\n                <Title level={2} style={{ marginBottom: 16 }}>\n                  {topicInfo.title}\n                  {topicInfo.is_finish === 1 && (\n                    <Tag color=\"success\" style={{ marginLeft: 12 }}>{t('cartoon.finished')}</Tag>\n                  )}\n                </Title>\n\n                <Space direction=\"vertical\" size={12} style={{ width: '100%' }}>\n                  {/* @ts-ignore */}\n                  {topicInfo.user && (\n                    <Text>\n                      <UserOutlined style={{ marginRight: 8 }} />\n                      {t('cartoonDetail.author')}：{/* @ts-ignore */}\n                      {topicInfo.user.nickname}\n                    </Text>\n                  )}\n\n                  <Space size={24} wrap>\n                    <Text>\n                      <EyeOutlined style={{ marginRight: 8 }} />\n                      {/* @ts-ignore */}\n                      {t('cartoonDetail.status')}：{formatNumber(topicInfo.update_status)}\n                    </Text>\n                    <Text>\n                      <StarOutlined style={{ marginRight: 8 }} />\n                      {t('cartoonDetail.likes')}：{formatNumber(topicInfo.likes_count)}\n                    </Text>\n                    <Text>\n                      <BookOutlined style={{ marginRight: 8 }} />\n                      {t('cartoon.chapters')}：{topicInfo.comics?.length || 0} {t('cartoonDetail.hua')}\n                    </Text>\n                  </Space>\n\n                  {/* @ts-ignore */}\n                  {topicInfo.tags && topicInfo.tags.length > 0 && (\n                    <div>\n                      <Text style={{ marginRight: 12 }}>{t('cartoonDetail.tags')}：</Text>\n                      {/* @ts-ignore */}\n                      {topicInfo.tags.map(tag => (\n                        <Tag color=\"blue\" key={tag} style={{ marginBottom: 8 }}>\n                          {tag}\n                        </Tag>\n                      ))}\n                    </div>\n                  )}\n\n                  <Divider style={{ margin: '12px 0' }} />\n\n                  <div>\n                    <Text strong style={{ display: 'block', marginBottom: 8 }}>\n                      {t('cartoonDetail.intro')}：\n                    </Text>\n                    <Paragraph style={{ marginBottom: 0, color: '#666' }}>\n                      {topicInfo.description}\n                    </Paragraph>\n                  </div>\n                </Space>\n              </InfoSection>\n            </Col>\n          </Row>\n        </HeaderCard>\n\n        {topicInfo.comics && topicInfo.comics.length > 0 && (\n          <ChapterList\n            title={\n              <Space>\n                <ReadOutlined />\n                <Text strong>{t('cartoonDetail.chapterList')}</Text>\n              </Space>\n            }\n          >\n            <List\n              dataSource={topicInfo.comics.sort((a, b) => b.id - a.id)}\n              renderItem={(comic, index) => (\n                <List.Item\n                  onClick={() => handleChapterClick(comic.id)}\n                >\n                  <List.Item.Meta\n                    avatar={\n                      <Text style={{ fontSize: 16, fontWeight: 500, minWidth: 60 }}>\n                        {t('cartoonDetail.episode')} {topicInfo.comics!.length - index} {t('cartoonDetail.hua')}\n                      </Text>\n                    }\n                    title={comic.title}\n                    // @ts-ignore\n                    description={comic.created_at}\n                  />\n                </List.Item>\n              )}\n            />\n          </ChapterList>\n        )}\n      </ContentWrapper>\n    </DetailContainer>\n  )\n}\n\nexport default CartoonDetail\n"
  },
  {
    "path": "src/pages/GPT.tsx",
    "content": "import React, { useState, useRef, useEffect, useCallback } from 'react'\nimport { Input, Button, Avatar, message, Modal, Tooltip, Badge } from 'antd'\nimport {\n  SendOutlined,\n  CopyOutlined,\n  DeleteOutlined,\n  UserOutlined,\n  RobotOutlined,\n  SoundOutlined,\n  StopOutlined,\n  DownloadOutlined,\n  LikeOutlined,\n  DislikeOutlined,\n  InfoCircleOutlined\n} from '@ant-design/icons'\nimport { useTranslation } from 'react-i18next'\nimport OpenAI from 'openai'\nimport { marked } from 'marked'\nimport HCaptcha from '@hcaptcha/react-hcaptcha'\nimport 'highlight.js/styles/github-dark.css'\nimport '@/assets/css/ai.scss'\n\nconst { TextArea } = Input\n\n// 配置 marked\nmarked.setOptions({\n  breaks: true,\n  gfm: true\n})\n\ninterface ChatMessage {\n  role: 'user' | 'assistant'\n  content: string\n  timestamp: number\n  rating?: 'like' | 'dislike'\n}\n\ninterface CaptchaPromise {\n  resolve: (token: string) => void\n  reject: (reason?: any) => void\n  timeoutId?: NodeJS.Timeout\n}\n\nconst GPT: React.FC = () => {\n  const { t } = useTranslation()\n  const [inputMessage, setInputMessage] = useState('')\n  const [messages, setMessages] = useState<ChatMessage[]>([\n    {\n      role: 'assistant',\n      content: t('gpt.welcomeMessage'),\n      timestamp: Date.now() - 1000\n    }\n  ])\n  const [isStreaming, setIsStreaming] = useState(false)\n  const [streamingContent, setStreamingContent] = useState('')\n  const messagesContainerRef = useRef<HTMLDivElement>(null)\n  const inputRef = useRef<any>(null)\n  const abortControllerRef = useRef<AbortController | null>(null)\n  const speechSynthesisRef = useRef<SpeechSynthesis | null>(null)\n  const autoSendTriggerRef = useRef<string | null>(null)\n  const hcaptchaRef = useRef<any>(null)\n  const captchaPromiseRef = useRef<CaptchaPromise | null>(null)\n\n  // 初始化 OpenAI 客户端（从环境变量读取配置）\n  const openai = new OpenAI({\n    baseURL: import.meta.env.VITE_OPENAI_BASE_URL || 'https://api.deepseek.com/v1',\n    apiKey: import.meta.env.VITE_OPENAI_API_KEY || '',\n    dangerouslyAllowBrowser: true\n  })\n\n  // 加载本地存储的消息\n  useEffect(() => {\n    try {\n      const saved = localStorage.getItem('chat_messages')\n      if (saved) {\n        const parsed = JSON.parse(saved)\n        if (Array.isArray(parsed) && parsed.length > 0) {\n          setMessages(parsed)\n        }\n      }\n    } catch (err) {\n      console.error('加载消息失败:', err)\n    }\n  }, [])\n\n  // 保存消息到本地存储\n  const saveMessagesToLocalStorage = useCallback((msgs: ChatMessage[]) => {\n    try {\n      localStorage.setItem('chat_messages', JSON.stringify(msgs))\n    } catch (err) {\n      console.error('保存消息失败:', err)\n    }\n  }, [])\n\n  // 滚动到底部\n  const scrollToBottom = useCallback(() => {\n    setTimeout(() => {\n      if (messagesContainerRef.current) {\n        messagesContainerRef.current.scrollTop = messagesContainerRef.current.scrollHeight\n      }\n    }, 100)\n  }, [])\n\n  // 聚焦输入框\n  const focusInput = useCallback(() => {\n    inputRef.current?.focus()\n  }, [])\n\n  // 初始化代码复制按钮\n  const initCodeCopyButtons = useCallback(() => {\n    setTimeout(() => {\n      const copyButtons = document.querySelectorAll('.copy-btn')\n      copyButtons.forEach((button) => {\n        const newButton = button.cloneNode(true)\n        button.parentNode?.replaceChild(newButton, button)\n      })\n\n      document.querySelectorAll('.copy-btn').forEach((button) => {\n        button.addEventListener('click', async (e: Event) => {\n          e.preventDefault()\n          e.stopPropagation()\n          const target = e.currentTarget as HTMLElement\n          const code = target.getAttribute('data-code')\n          if (code) {\n            try {\n              const decodedCode = decodeURIComponent(code)\n              await navigator.clipboard.writeText(decodedCode)\n              message.success(t('gpt.copySuccess'))\n            } catch (err) {\n              const textArea = document.createElement('textarea')\n              textArea.value = decodeURIComponent(code)\n              document.body.appendChild(textArea)\n              textArea.select()\n              document.execCommand('copy')\n              document.body.removeChild(textArea)\n              message.success(t('gpt.copySuccess'))\n            }\n          }\n        })\n      })\n    }, 100)\n  }, [])\n\n  // 监听消息变化\n  useEffect(() => {\n    scrollToBottom()\n    initCodeCopyButtons()\n    saveMessagesToLocalStorage(messages)\n  }, [messages, scrollToBottom, initCodeCopyButtons, saveMessagesToLocalStorage])\n\n  // 监听自动发送触发器\n  useEffect(() => {\n    if (autoSendTriggerRef.current && inputMessage === autoSendTriggerRef.current) {\n      autoSendTriggerRef.current = null\n\n      // 延迟一下确保状态已更新\n      setTimeout(() => {\n        if (inputMessage.trim() && !isStreaming) {\n          sendMessage()\n        }\n      }, 100)\n    }\n  }, [inputMessage, isStreaming])\n\n  // 监听流式内容变化\n  useEffect(() => {\n    if (streamingContent) {\n      scrollToBottom()\n    }\n  }, [streamingContent, scrollToBottom])\n\n  // 初始化语音合成\n  useEffect(() => {\n    if ('speechSynthesis' in window) {\n      speechSynthesisRef.current = window.speechSynthesis\n    }\n\n    return () => {\n      if (speechSynthesisRef.current) {\n        speechSynthesisRef.current.cancel()\n      }\n      if (abortControllerRef.current) {\n        abortControllerRef.current.abort()\n      }\n    }\n  }, [])\n\n  // Markdown 渲染函数\n  const renderMarkdown = useCallback((text: string): string => {\n    if (!text) return ''\n    const rendered = marked.parse(text) as string\n\n    // 为代码块添加复制按钮\n    return rendered.replace(\n      /<pre><code class=\"hljs language-(\\w+)\">([\\s\\S]*?)<\\/code><\\/pre>/g,\n      (_match: string, lang: string, code: string) => {\n        const escapedCode = code.replace(/\"/g, '&quot;')\n        return `<div class=\"code-container\">\n          <div class=\"code-header\">\n            <span class=\"language-label\">${lang}</span>\n            <button class=\"copy-btn\" data-code=\"${encodeURIComponent(escapedCode)}\">\n              <svg class=\"copy-icon\" viewBox=\"0 0 24 24\" width=\"14\" height=\"14\">\n                <path fill=\"currentColor\" d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\"/>\n              </svg>\n              {t('common.copy')}\n            </button>\n          </div>\n          <pre><code class=\"hljs language-${lang}\">${code}</code></pre>\n        </div>`\n      }\n    )\n  }, [])\n\n  // 格式化时间\n  const formatTime = useCallback((timestamp: number) => {\n    const date = new Date(timestamp)\n    return date\n      .toLocaleString('zh-CN', {\n        year: 'numeric',\n        month: '2-digit',\n        day: '2-digit',\n        hour: '2-digit',\n        minute: '2-digit',\n        second: '2-digit',\n        hour12: false\n      })\n      .replace(/\\//g, '-')\n      .replace(/,/g, '')\n  }, [])\n\n  // 发送消息 - 流式处理\n  const sendMessage = async () => {\n    if (!inputMessage.trim() || isStreaming) {\n      return\n    }\n    \n    try {\n      const token = await new Promise<string>((resolve, reject) => {\n        const timeoutId = setTimeout(() => {\n          if (captchaPromiseRef.current) {\n            reject(new Error('验证超时，请重试'))\n            captchaPromiseRef.current = null\n          }\n        }, 120000)\n        \n        captchaPromiseRef.current = { resolve, reject, timeoutId }\n        \n        if (hcaptchaRef.current) {\n          hcaptchaRef.current.execute()\n        } else {\n          reject(new Error('HCaptcha 组件未初始化'))\n        }\n      })\n      \n      console.log('验证通过，token:', token)\n      const userMessage = inputMessage.trim()\n    const newMessages = [\n      ...messages,\n      {\n        role: 'user' as const,\n        content: userMessage,\n        timestamp: Date.now()\n      }\n    ]\n\n    setMessages(newMessages)\n    setInputMessage('')\n    scrollToBottom()\n    focusInput()\n\n    setIsStreaming(true)\n    setStreamingContent('')\n\n    // 创建中止控制器\n    abortControllerRef.current = new AbortController()\n\n    try {\n      // 准备对话历史\n      const conversationHistory = newMessages\n        .filter((msg) => msg.role === 'user' || msg.role === 'assistant')\n        .map((msg) => ({\n          role: msg.role,\n          content: msg.content\n        }))\n\n      // 调用流式 API\n      const stream = await openai.chat.completions.create(\n        {\n          model: 'deepseek-v3-2-251201',\n          messages: [\n            {\n              role: 'system',\n              content: `You are a ChattyPlay AI assistant, focused on helping users learn, answer questions, and provide study advice. Please answer in a friendly, professional tone, and try to use Markdown format to organize your content, including:\n- Use headings (#, ##, ###) to organize content structure\n- Use lists (-, 1.) to enumerate key points\n- Use code blocks (\\`\\`\\`) to display code examples\n- Use bold (**) to emphasize important concepts\n- Use tables to compare information\n\nPlease ensure your answers are accurate, detailed, and easy to understand.`\n            },\n            ...conversationHistory\n          ],\n          stream: true,\n          max_tokens: 2000\n        },\n        {\n          signal: abortControllerRef.current.signal\n        }\n      )\n\n      // 处理流式响应\n      let accumulatedContent = ''\n      for await (const chunk of stream) {\n        const content = chunk.choices[0]?.delta?.content\n        if (content) {\n          accumulatedContent += content\n          setStreamingContent(accumulatedContent)\n        }\n      }\n\n      // 流式完成，将内容添加到消息列表\n      if (accumulatedContent) {\n        setMessages((prev) => [\n          ...prev,\n          {\n            role: 'assistant',\n            content: accumulatedContent,\n            timestamp: Date.now()\n          }\n        ])\n        message.success(t('gpt.replyComplete'))\n      }\n    } catch (error: any) {\n      if (error.name === 'AbortError') {\n        console.log('请求被用户中止')\n        if (streamingContent) {\n          setMessages((prev) => [\n            ...prev,\n            {\n              role: 'assistant',\n              content: streamingContent,\n              timestamp: Date.now()\n            }\n          ])\n          message.info(t('gpt.replyInterrupted'))\n        }\n      } else {\n        console.error('API调用错误:', error)\n        // 备用回复\n        const fallbackResponse = `${t('gpt.fallbackResponse')}\n\n## Learning Suggestions\n1. **Understand Core Concepts**: Master the basics first\n2. **Practice**: Deepen understanding through practice\n3. **Seek Help**: Ask teachers or classmates for assistance\n\n## Recommended Resources\n- Relevant textbooks and reference materials\n- Online learning platforms\n- Educational video resources\n\nIf you need more detailed answers, please try again later or contact technical support.`\n        setMessages((prev) => [\n          ...prev,\n          {\n            role: 'assistant',\n            content: fallbackResponse,\n            timestamp: Date.now()\n          }\n        ])\n        message.error(t('gpt.networkError'))\n      }\n    } finally {\n      setIsStreaming(false)\n      setStreamingContent('')\n      abortControllerRef.current = null\n      // 清除url参数\n      window.history.replaceState({}, document.title, window.location.pathname)\n      scrollToBottom()\n    }\n\n    } catch (error) {}\n\n  }\n\n  useEffect(() => {\n    const urlParams = new URLSearchParams(window.location.search)\n    const paperTitle = urlParams.get('paper')\n    const pdfUrl = urlParams.get('pdf')\n    // 判断是否url上有paper和pdf参数\n    if (paperTitle && pdfUrl) {\n      let content = `\n        论文解读分析，论文链接是：${pdfUrl}，论文标题是：${paperTitle}。\n\n        你是一名AI领域的研究生，目标是深入理解论文的方法部分，包括方法动机、设计逻辑、流程细节、优势与不足，以便学习和在研究中借鉴。你的角色是高效、深入的论文分析师。\n        \n        任务：\n          请在阅读论文（用户提供的论文链接和论文标题）后，围绕以下要点进行总结和分析：\n          0. 翻译摘要原文\n          1. 方法动机\n            a) 作者为什么提出这个方法？阐述其背后的驱动力。\n            b) 现有方法的痛点/不足是什么？具体指出局限性。\n            c) 论文的研究假设或直觉是什么？用简洁语言概括。\n          2. 方法设计\n            a) 给出清晰的方法流程总结（pipeline），逐步解释输入→处理→输出。必须讲清楚每一步的具体操作和技术细节。这一步必须非常细致，这是用户的主要阅读目标。\n            b) 如果涉及模型结构，请描述每个模块的功能与作用，以及它们如何协同工作。\n            c) 如果有公式/算法，请用通俗语言解释它们的意义和在方法中的角色。\n          3. 与其他方法对比\n            a) 本方法和现有主流方法相比，有什么本质不同？\n            b) 创新点在哪里？明确指出贡献度。\n            c) 在什么场景下更适用？分析其适用范围。\n            d) 用表格总结 方法对比（优点/缺点/改进点），确保对比项清晰。\n          4. 实验表现与优势\n            a) 作者如何验证该方法的有效性？描述实验设计和设置。\n            b) 实验结果在哪些指标上超越了对比方法？列出几个最具代表性的关键数据和结论。\n            c) 哪些场景/数据集下优势最明显？提供具体证据。\n            d) 是否有局限性（比如泛化能力、计算开销、对特定数据的依赖）？指出论文中承认或隐含的不足。\n          5. 学习与应用\n            a) 论文是否开源？如果我想实现/复现这个方法，关键步骤是什么？\n            b) 需要注意哪些超参数、数据预处理、训练细节？提供实现层面的建议。\n            c) 该方法能否迁移到其他任务？如果能，如何迁移？\n          6. 总结\n            a) 用一句话概括这个方法的核心思想（不超过50字）。\n            b) 给出一个“速记版pipeline”（使用3-5个关键步骤），方便记忆。这个pipeline不要使用论文使用的专业词汇，而是应当具有自明性，让读者只看pipeline即可大体理解论文内容。不要用比喻，直白的讲出内容。\n        \n        行为和规则：\n          - 语言风格：专业、严谨、逻辑性强，完全采用中文进行回复。\n          - 回复结构：严格按照上述六个大点和其子点进行分析和总结，使用清晰的分段和编号。\n          - 数据来源：所有分析必须基于用户提供的论文内容信息。如果用户没有提供足够信息，可以基于常识进行合理推测，但必须明确指出是推测。\n          - 聚焦核心：重点解析方法（Methodology）部分，避免过度讨论引言和结论。\n          - 输出要求：用户可能不再阅读论文具体内容，而是只阅读你提供的信息，因此请确保你的分析详尽且准确。\n      `\n      setIsStreaming(false)\n      autoSendTriggerRef.current = content\n      setInputMessage(content)\n    }\n  }, [])\n\n  // 停止生成\n  const stopGeneration = () => {\n    if (abortControllerRef.current) {\n      abortControllerRef.current.abort()\n      setIsStreaming(false)\n    }\n  }\n\n  // 复制消息\n  const copyMessage = async (content: string) => {\n    try {\n      await navigator.clipboard.writeText(content)\n      message.success(t('gpt.copySuccess'))\n    } catch (err) {\n      const textArea = document.createElement('textarea')\n      textArea.value = content\n      document.body.appendChild(textArea)\n      textArea.select()\n      document.execCommand('copy')\n      document.body.removeChild(textArea)\n      message.success(t('gpt.copySuccess'))\n    }\n  }\n\n  // 语音播报\n  const speakMessage = (content: string) => {\n    if (!('speechSynthesis' in window)) {\n      message.warning(t('gpt.browserNotSupportSpeech'))\n      return\n    }\n\n    if (speechSynthesisRef.current) {\n      speechSynthesisRef.current.cancel()\n    }\n\n    // 移除Markdown标记，只播报纯文本\n    const plainText = content\n      .replace(/#{1,6}\\s?/g, '') // 移除标题标记\n      .replace(/\\*\\*(.*?)\\*\\*/g, '$1') // 移除粗体\n      .replace(/\\*(.*?)\\*/g, '$1') // 移除斜体\n      .replace(/`(.*?)`/g, '$1') // 移除行内代码\n      .replace(/```[\\s\\S]*?```/g, '') // 移除代码块\n      .replace(/\\[([^\\[]+)\\]\\(([^\\)]+)\\)/g, '$1') // 移除链接标记\n\n    const utterance = new SpeechSynthesisUtterance(plainText)\n    utterance.lang = 'zh-CN'\n    utterance.rate = 1\n    utterance.pitch = 1\n    utterance.volume = 1\n    utterance.onstart = () => {\n      message.info(t('gpt.speakStart'))\n    }\n    utterance.onend = () => {\n      message.success(t('gpt.speakComplete'))\n    }\n    utterance.onerror = () => {\n      message.error(t('gpt.speakError'))\n    }\n\n    speechSynthesisRef.current?.speak(utterance)\n  }\n\n  // 评分消息\n  const rateMessage = (index: number, rating: 'like' | 'dislike') => {\n    if (messages[index].role === 'assistant') {\n      const newMessages = [...messages]\n      newMessages[index].rating = rating\n      setMessages(newMessages)\n      message.success(rating === 'like' ? t('gpt.feedbackLike') : t('gpt.feedbackDislike'))\n    }\n  }\n\n  // 清空消息\n  const clearMessages = () => {\n    Modal.confirm({\n      title: t('gpt.clearConfirmTitle'),\n      content: t('gpt.clearConfirmContent'),\n      okText: t('common.confirm'),\n      cancelText: t('common.cancel'),\n      onOk: () => {\n        setMessages([\n          {\n            role: 'assistant',\n            content: t('gpt.welcomeMessage'),\n            timestamp: Date.now()\n          }\n        ])\n        localStorage.removeItem('chat_messages')\n        message.success(t('gpt.cleared'))\n        scrollToBottom()\n      }\n    })\n  }\n\n  // 导出聊天记录\n  const exportChat = () => {\n    const chatText = messages\n      .map((msg) => {\n        const role = msg.role === 'user' ? t('gpt.userRole') : t('gpt.aiRole')\n        const time = formatTime(msg.timestamp)\n        return `[${role} ${time}]\\n${msg.content}\\n`\n      })\n      .join('\\n' + '='.repeat(50) + '\\n\\n')\n\n    const blob = new Blob([chatText], { type: 'text/plain;charset=utf-8' })\n    const url = URL.createObjectURL(blob)\n    const a = document.createElement('a')\n    a.href = url\n    a.download = `${t('gpt.exportFilename')}_${new Date().toISOString().slice(0, 10)}.txt`\n    document.body.appendChild(a)\n    a.click()\n    document.body.removeChild(a)\n    URL.revokeObjectURL(url)\n    message.success(t('gpt.exportSuccess'))\n  }\n\n  // 处理键盘事件\n  const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n    if (e.key === 'Enter' && !e.shiftKey) {\n      e.preventDefault()\n      sendMessage()\n    }\n  }\n\n  const handleVerify = (token: string) => {\n    console.log('hcaptcha验证成功', token)\n    if (captchaPromiseRef.current) {\n      if ((captchaPromiseRef.current as any).timeoutId) {\n        clearTimeout((captchaPromiseRef.current as any).timeoutId)\n      }\n      captchaPromiseRef.current.resolve(token)\n      captchaPromiseRef.current = null\n    }\n  }\n\n  const handleError = (err: any) => {\n    console.error('hcaptcha验证失败', err)\n    if (captchaPromiseRef.current) {\n      if ((captchaPromiseRef.current as any).timeoutId) {\n        clearTimeout((captchaPromiseRef.current as any).timeoutId)\n      }\n      captchaPromiseRef.current.reject(new Error('验证失败，请重试'))\n      captchaPromiseRef.current = null\n    }\n    message.error('验证失败，请重试')\n  }\n\n  return (\n    <div className=\"bg-gradient-to-br from-gray-50 to-blue-50 min-h-screen p-2 md:p-4\">\n      {/* 主聊天区域 */}\n      <div className=\"mx-auto max-w-5xl bg-white rounded-xl md:rounded-2xl shadow-xl overflow-hidden h-[calc(100vh-16px)] md:h-auto flex flex-col\">\n        {/* 头部 */}\n        <div className=\"p-3 md:p-4 border-b bg-gradient-to-r from-blue-500 to-indigo-500 flex-shrink-0\">\n          <div className=\"flex items-center justify-between\">\n            <div className=\"flex items-center space-x-2 md:space-x-3\">\n              <div>\n                <h1 className=\"text-lg md:text-xl font-bold text-white\">{t('gpt.title')}</h1>\n                <p className=\"text-blue-100 text-xs md:text-sm hidden sm:block\">{t('gpt.subtitle')}</p>\n              </div>\n            </div>\n            <div className=\"flex items-center space-x-1 md:space-x-2\">\n              <Badge status=\"success\" text={<span className=\"text-white text-xs hidden md:inline-block\">{t('gpt.modelName')}</span>} />\n              {isStreaming && (\n                <Button\n                  size=\"small\"\n                  danger\n                  onClick={stopGeneration}\n                  icon={<StopOutlined />}\n                  className=\"text-xs px-2\"\n                >\n                  <span className=\"hidden sm:inline\">{t('gpt.stopGenerate')}</span>\n                </Button>\n              )}\n            </div>\n          </div>\n        </div>\n\n        {/* 消息区域 */}\n        <div\n          ref={messagesContainerRef}\n          className={`overflow-y-auto p-3 md:p-6 space-y-4 md:space-y-6 custom-scrollbar flex-1 min-h-[160px] md:min-h-[calc(100vh-200px)] ${\n            messages.length > 0 ? '' : 'flex items-center justify-center'\n          }`}\n        >\n          {/* 欢迎消息 */}\n          {messages.length === 0 && (\n            <div className=\"flex flex-col items-center justify-center py-8 md:py-12 px-4 welcome-animate\">\n              <Avatar\n                size={64}\n                className=\"mb-3 md:mb-4 bg-gradient-to-r from-blue-500 to-indigo-500 shadow-lg\"\n                icon={<RobotOutlined />}\n              />\n              <h2 className=\"text-xl md:text-2xl font-bold text-gray-800 mb-2 text-center\">{t('gpt.title')}</h2>\n              <p className=\"text-gray-600 text-center max-w-md text-sm md:text-base\">\n                {t('gpt.welcomeMessage')}\n              </p>\n            </div>\n          )}\n\n          {/* 消息列表 */}\n          {messages.map((msg, index) => (\n            <div\n              key={index}\n              className={`flex gap-2 md:gap-3 message-animate ${msg.role === 'user' ? 'flex-row-reverse' : ''}`}\n            >\n              {/* 头像 */}\n              <Avatar\n                size={32}\n                className={`flex-shrink-0 ${\n                  msg.role === 'user'\n                    ? 'bg-gradient-to-r from-green-500 to-emerald-500'\n                    : 'bg-gradient-to-r from-blue-500 to-indigo-500'\n                }`}\n                icon={msg.role === 'user' ? <UserOutlined /> : <RobotOutlined />}\n              />\n\n              {/* 消息内容 */}\n              <div\n                className={`max-w-[85%] sm:max-w-[80%] md:max-w-[70%] rounded-xl md:rounded-2xl p-3 md:p-4 relative group ${\n                  msg.role === 'user'\n                    ? 'bg-gradient-to-r from-green-50 to-emerald-50 rounded-br-none border border-emerald-100'\n                    : 'bg-gradient-to-r from-blue-50 to-indigo-50 rounded-bl-none border border-blue-100'\n                }`}\n              >\n                {/* 操作按钮 */}\n                <div\n                  className={`absolute -top-2 flex space-x-1 opacity-0 group-hover:opacity-100 transition-opacity duration-200 ${\n                    msg.role === 'user' ? '-left-2' : '-right-2'\n                  }`}\n                >\n                  <Tooltip title={t('gpt.copy')}>\n                    <Button\n                      size=\"small\"\n                      shape=\"circle\"\n                      icon={<CopyOutlined />}\n                      onClick={() => copyMessage(msg.content)}\n                    />\n                  </Tooltip>\n                  {msg.role === 'assistant' && (\n                    <>\n                      <Tooltip title={t('gpt.readAloud')}>\n                        <Button\n                          size=\"small\"\n                          shape=\"circle\"\n                          icon={<SoundOutlined />}\n                          onClick={() => speakMessage(msg.content)}\n                        />\n                      </Tooltip>\n                      <Tooltip title={t('gpt.helpful')}>\n                        <Button\n                          size=\"small\"\n                          shape=\"circle\"\n                          icon={<LikeOutlined />}\n                          type={msg.rating === 'like' ? 'primary' : 'default'}\n                          onClick={() => rateMessage(index, 'like')}\n                        />\n                      </Tooltip>\n                    </>\n                  )}\n                </div>\n\n                {/* 消息内容 */}\n                <div className={msg.role === 'user' ? 'text-gray-800' : ''}>\n                  {msg.role === 'assistant' ? (\n                    <div\n                      className=\"markdown-content\"\n                      dangerouslySetInnerHTML={{ __html: renderMarkdown(msg.content) }}\n                    />\n                  ) : (\n                    msg.content\n                  )}\n                </div>\n\n                {/* 消息时间和评分 */}\n                <div\n                  className={`flex items-center justify-between mt-3 pt-3 border-t ${\n                    msg.role === 'user' ? 'border-emerald-100 ml-auto' : 'border-blue-100'\n                  }`}\n                >\n                  <div className={`text-xs ${msg.role === 'user' ? 'text-gray-500 ml-auto' : 'text-gray-500'}`}>\n                    {formatTime(msg.timestamp)}\n                  </div>\n                  {msg.role === 'assistant' && msg.rating && (\n                    <div className=\"flex items-center text-xs text-gray-500\">\n                      {msg.rating === 'like' ? (\n                        <LikeOutlined className=\"text-green-500 mr-1\" />\n                      ) : (\n                        <DislikeOutlined className=\"text-red-500 mr-1\" />\n                      )}\n                      <span>{msg.rating === 'like' ? t('gpt.helpful') : t('gpt.needsImprovement')}</span>\n                    </div>\n                  )}\n                </div>\n              </div>\n            </div>\n          ))}\n\n          {/* 流式输出显示 */}\n          {isStreaming && (\n            <div className=\"flex gap-2 md:gap-3 message-animate\">\n              <Avatar size={32} className=\"bg-gradient-to-r from-blue-500 to-indigo-500\" icon={<RobotOutlined />} />\n              <div className=\"bg-gradient-to-r from-blue-50 to-indigo-50 rounded-xl md:rounded-2xl rounded-bl-none p-3 md:p-4 w-full border border-blue-100\">\n                <div className=\"flex items-center space-x-2 mb-2 md:mb-3\">\n                  <div className=\"flex space-x-1\">\n                    <div className=\"w-2 h-2 bg-blue-400 rounded-full pulse\" style={{ animationDelay: '0ms' }}></div>\n                    <div className=\"w-2 h-2 bg-blue-400 rounded-full pulse\" style={{ animationDelay: '150ms' }}></div>\n                    <div className=\"w-2 h-2 bg-blue-400 rounded-full pulse\" style={{ animationDelay: '300ms' }}></div>\n                  </div>\n                  <span className=\"text-xs md:text-sm text-gray-500\">{t('gpt.typing')}</span>\n                </div>\n                <div className=\"markdown-content streaming-content\">\n                  <div\n                    dangerouslySetInnerHTML={{ __html: renderMarkdown(streamingContent) }}\n                    className=\"min-h-[20px]\"\n                  />\n                  <span className=\"cursor-blink\">|</span>\n                </div>\n              </div>\n            </div>\n          )}\n        </div>\n\n        {/* 输入区域 */}\n        <div className=\"border-t p-3 md:p-4 bg-gray-50 flex-shrink-0\">\n          {/* 快捷操作栏 */}\n          <div className=\"flex items-center justify-between mb-2 md:mb-3\">\n            <div className=\"flex items-center space-x-1 md:space-x-2\">\n              <Tooltip title={t('gpt.clearTooltip')}>\n                <Button size=\"small\" icon={<DeleteOutlined />} onClick={clearMessages} className=\"text-xs md:text-sm\">\n                  <span className=\"hidden sm:inline\">{t('gpt.clearBtn')}</span>\n                </Button>\n              </Tooltip>\n              <Tooltip title={t('gpt.exportTooltip')}>\n                <Button size=\"small\" icon={<DownloadOutlined />} onClick={exportChat} className=\"text-xs md:text-sm\">\n                  <span className=\"hidden sm:inline\">{t('common.download')}</span>\n                </Button>\n              </Tooltip>\n            </div>\n            <div className=\"text-xs text-gray-500 flex items-center sm:flex\">\n              <InfoCircleOutlined className=\"mr-1\" />\n              {t('gpt.enterToSend')}\n            </div>\n          </div>\n\n          <div className=\"flex gap-2 md:gap-3\">\n            <div className=\"flex-1\">\n              <TextArea\n                ref={inputRef}\n                value={inputMessage}\n                onChange={(e) => setInputMessage(e.target.value)}\n                onKeyDown={handleKeyDown}\n                placeholder={t('gpt.placeholder')}\n                autoSize={{ minRows: 1, maxRows: 3 }}\n                disabled={isStreaming}\n                className=\"bg-white text-sm md:text-base\"\n              />\n            </div>\n            <Button\n              type=\"primary\"\n              size=\"large\"\n              loading={isStreaming}\n              onClick={sendMessage}\n              disabled={!inputMessage.trim() || isStreaming}\n              icon={<SendOutlined />}\n              className=\"h-10 md:h-12 px-3 md:px-6 bg-gradient-to-r from-blue-500 to-indigo-500 border-0 shadow-md hover:shadow-lg\"\n            >\n              <span className=\"hidden md:inline\">{isStreaming ? t('common.generating') : t('gpt.sendBtn')}</span>\n            </Button>\n          </div>\n\n          <HCaptcha\n            ref={hcaptchaRef}\n            sitekey={import.meta.env.VITE_HCAPTCHA_SITE_KEY}\n            onVerify={handleVerify}\n            onError={handleError}\n            onExpire={() => {\n              console.log('验证码过期')\n              message.warning('验证已过期，请重新验证')\n            }}\n            size=\"invisible\"\n          />\n        </div>\n      </div>\n    </div>\n  )\n}\n\nexport default GPT\n"
  },
  {
    "path": "src/pages/Gold.tsx",
    "content": "import React, { useState, useEffect, useRef } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { message, Modal, Input, Button, Spin } from 'antd'\nimport axios from 'axios'\nimport { marked } from 'marked'\nimport * as echarts from 'echarts'\nimport { formatPrice, formatChange, formatPercent, getPriceClass } from '@/utils/price'\nimport '@/assets/css/gold.scss'\nimport emailjs from '@emailjs/browser'\n// @ts-ignore\nimport { emailConfig } from '../../email.config'\n\ninterface PriceData {\n  international?: {\n    price: number;\n    change: number;\n    changePercent: number;\n    previousClose?: number;\n    silverPrice?: number;\n    source?: string;\n  };\n  domestic?: {\n    price: number;\n    change: number;\n    changePercent: number;\n    open?: number;\n    high?: number;\n    low?: number;\n    volume?: number;\n    source?: string;\n  };\n}\n\ninterface KlineData {\n  date: string;\n  open: number;\n  high: number;\n  low: number;\n  close: number;\n  volume: number;\n}\n\nconst Gold: React.FC = () => {\n  const { t } = useTranslation()\n  const [priceData, setPriceData] = useState<PriceData>({})\n  // @ts-ignore\n  const [klineData, setKlineData] = useState<KlineData[]>([])\n  // @ts-ignore\n  const [currentPeriod, setCurrentPeriod] = useState<number>(30)\n  const [currentTime, setCurrentTime] = useState<string>('')\n  const klineChartRef = useRef<HTMLDivElement>(null)\n  const chartInstanceRef = useRef<echarts.ECharts | null>(null)\n  const priceUpdateIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null)\n  const timeUpdateIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null)\n  const [subscribeModalVisible, setSubscribeModalVisible] = useState(false)\n  const [emailInput, setEmailInput] = useState('')\n  const [subscribing, setSubscribing] = useState(false)\n  const [loading, setLoading] = useState(true)\n  const isFirstLoadRef = useRef(true)\n\n  const API_BASE = import.meta.env.VITE_GOLD_API_BASE_URL || ''\n\n  const updateTime = (): void => {\n    const now = new Date()\n    setCurrentTime(now.toLocaleString('zh-CN', {\n      year: 'numeric',\n      month: '2-digit',\n      day: '2-digit',\n      hour: '2-digit',\n      minute: '2-digit',\n      second: '2-digit',\n    }))\n  }\n\n  // 刷新所有数据\n  const refreshAllData = (): void => {\n    fetchPriceData()\n    fetchKlineData(currentPeriod)\n  }\n\n  // 获取价格数据\n  const fetchPriceData = async (): Promise<void> => {\n    try {\n      const response = await axios.get(`${API_BASE}/api/price/all`)\n      setPriceData({\n        international: response.data.international,\n        domestic: response.data.domestic,\n      })\n    } catch (error) {\n      console.error('获取价格数据失败:', error)\n      message.error(t('gold.fetchPriceFailed'))\n    } finally {\n      // 只在第一次加载时关闭 loading\n      if (isFirstLoadRef.current) {\n        setLoading(false)\n        isFirstLoadRef.current = false\n      }\n    }\n  }\n\n  // 获取K线数据\n  const fetchKlineData = async (days: number = 30): Promise<void> => {\n    try {\n      const response = await axios.get(`${API_BASE}/api/chart/kline?days=${days}`)\n      setKlineData(response.data.rawData)\n      if (chartInstanceRef.current && response.data.chartOption) {\n        chartInstanceRef.current.setOption(response.data.chartOption)\n      }\n    } catch (error) {\n      console.error('获取K线数据失败:', error)\n      message.error(t('gold.fetchChartFailed'))\n    }\n  }\n\n  // 订阅金价\n  const handleSubscribe = async (): Promise<void> => {\n    // 邮箱格式验证\n    const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n    if (!emailInput || !emailRegex.test(emailInput)) {\n      message.error(t('gold.invalidEmail'))\n      return\n    }\n\n    // 检查 EmailJS 配置\n    if (emailConfig.PUBLIC_KEY === 'YOUR_PUBLIC_KEY_HERE' ||\n        emailConfig.SERVICE_ID === 'YOUR_SERVICE_ID_HERE' ||\n        emailConfig.TEMPLATE_ID === 'YOUR_TEMPLATE_ID_HERE') {\n      message.error(t('gold.emailNotConfigured'))\n      return\n    }\n\n    setSubscribing(true)\n    try {\n      // 初始化 EmailJS\n      emailjs.init(emailConfig.PUBLIC_KEY)\n\n      // 邮件参数\n      const templateParams = {\n        email: emailInput,\n        to_email: emailInput,\n        domestic_price: formatPrice(priceData.domestic?.price, 'CNY'),\n        international_price: formatPrice(priceData.international?.price, 'USD'),\n        current_time: currentTime,\n        from_name: emailConfig.fromName,\n      }\n\n      // 发送邮件\n      await emailjs.send(\n        emailConfig.SERVICE_ID,\n        emailConfig.TEMPLATE_ID,\n        templateParams\n      )\n\n      message.success(t('gold.subscribeSuccess'))\n      setSubscribeModalVisible(false)\n      setEmailInput('')\n    } catch (error) {\n      console.error('订阅失败:', error)\n      message.error(t('gold.subscribeFailed'))\n    } finally {\n      setSubscribing(false)\n    }\n  }\n\n  const initChart = (): void => {\n    // 初始化K线图\n    if (klineChartRef.current) {\n      chartInstanceRef.current = echarts.init(klineChartRef.current, 'dark')\n    }\n    window.addEventListener('resize', () => {\n      chartInstanceRef.current?.resize()\n    })\n  }\n\n  useEffect(() => {\n    // 配置marked选项\n    marked.setOptions({\n      breaks: true,\n      gfm: true,\n    })\n\n    // 初始化时间\n    updateTime()\n    timeUpdateIntervalRef.current = setInterval(updateTime, 1000)\n    \n    // 初始化图表\n    initChart()\n    \n    // 获取初始数据\n    fetchPriceData()\n    fetchKlineData(currentPeriod)\n\n    // 定时更新价格，每3秒更新一次\n    priceUpdateIntervalRef.current = setInterval(fetchPriceData, 3000)\n\n    // 清理函数\n    return () => {\n      if (priceUpdateIntervalRef.current) {\n        clearInterval(priceUpdateIntervalRef.current)\n      }\n      if (timeUpdateIntervalRef.current) {\n        clearInterval(timeUpdateIntervalRef.current)\n      }\n      \n      // 销毁图表实例\n      if (chartInstanceRef.current) {\n        chartInstanceRef.current.dispose()\n      }\n      \n      window.removeEventListener('resize', () => {\n        chartInstanceRef.current?.resize()\n      })\n    }\n  }, [currentPeriod])\n\n  return (\n    <div className=\"terminal-container\">\n      {/* Loading */}\n      {loading && (\n        <div className=\"loading-overlay\">\n          <Spin size=\"large\" />\n          <div className=\"loading-text\">{t('gold.loading')}</div>\n        </div>\n      )}\n\n      {/* 顶部导航栏 */}\n      <header className=\"top-header\">\n        <div className=\"header-left\">\n          <div className=\"market-status\">\n            <span className=\"status-dot\"></span>\n            <span className='current-time'>{t('gold.realtimeQuote')}</span>\n          </div>\n        </div>\n        <div className=\"header-center\">\n          <span className=\"current-time\">{currentTime}</span>\n        </div>\n        <div className=\"header-right\">\n          <button className=\"refresh-btn\" onClick={refreshAllData} title={t('gold.refresh')}>\n            <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n              <path d=\"M1 4v6h6M23 20v-6h-6\"/>\n              <path d=\"M20.49 9A9 9 0 0 0 5.64 5.64L1 10m22 4l-4.64 4.36A9 9 0 0 1 3.51 15\"/>\n            </svg>\n          </button>\n        </div>\n      </header>\n\n      {/* 主内容区域 */}\n      <main className=\"main-content-new\">\n        {/* 价格 */}\n        <section className=\"price-cards-row\">\n          {/* 国内黄金 */}\n          <div className=\"price-card-new domestic\">\n            <div className=\"card-icon cn\">\n              <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n                <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"/>\n                <path d=\"M12 8v8M8 12h8\" stroke=\"currentColor\" strokeWidth=\"2\"/>\n              </svg>\n            </div>\n            <div className=\"card-info\">\n              <div className=\"card-label\">{t('gold.domesticGold')}<span className=\"badge cn\">CNY</span></div>\n              <div className={`card-price ${getPriceClass(priceData.domestic?.changePercent)}`}>\n                {formatPrice(priceData.domestic?.price, 'CNY')}\n              </div>\n              <div className={`card-change ${getPriceClass(priceData.domestic?.changePercent)}`}>\n                {formatChange(priceData.domestic?.change)} ({formatPercent(priceData.domestic?.changePercent)})\n              </div>\n            </div>\n            <div className=\"card-extra\">\n              <div className=\"extra-item\">\n                <span>{t('gold.open')}</span>\n                <span>{priceData.domestic?.open?.toFixed(2) || '--'}</span>\n              </div>\n              <div className=\"extra-item\">\n                <span>{t('gold.high')}</span>\n                <span className=\"up\">{priceData.domestic?.high?.toFixed(2) || '--'}</span>\n              </div>\n              <div className=\"extra-item\">\n                <span>{t('gold.low')}</span>\n                <span className=\"down\">{priceData.domestic?.low?.toFixed(2) || '--'}</span>\n              </div>\n              <div className=\"extra-item\">\n                <span>{t('gold.volume')}</span>\n                <span>{priceData.domestic?.volume || '--'}</span>\n              </div>\n            </div>\n          </div>\n\n          {/* 国际金价 */}\n          <div className=\"price-card-new\">\n            <div className=\"card-icon intl\">\n              <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n                <circle cx=\"12\" cy=\"12\" r=\"10\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"/>\n                <path d=\"M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"/>\n              </svg>\n            </div>\n            <div className=\"card-info\">\n              <div className=\"card-label\">{t('gold.internationalGold')}<span className=\"badge\">SPOT</span></div>\n              <div className={`card-price ${getPriceClass(priceData.international?.changePercent)}`}>\n                {formatPrice(priceData.international?.price, 'USD')}\n              </div>\n              <div className={`card-change ${getPriceClass(priceData.international?.changePercent)}`}>\n                {formatChange(priceData.international?.change)} ({formatPercent(priceData.international?.changePercent)})\n              </div>\n            </div>\n            <div className=\"card-extra\">\n              <div className=\"extra-item\">\n                <span>{t('gold.prevClose')}</span>\n                <span>{priceData.international?.previousClose?.toFixed(2) || '--'}</span>\n              </div>\n              <div className=\"extra-item\">\n                <span>{t('gold.silver')}</span>\n                <span>{priceData.international?.silverPrice?.toFixed(2) || '--'}</span>\n              </div>\n            </div>\n          </div>\n        </section>\n\n        {/* K线图区域 */}\n        <section className=\"chart-section desktop-only\">\n          <div className=\"chart-header\">\n            <h3>\n              <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n                <path d=\"M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7z\"/>\n              </svg>\n              {t('gold.priceTrend')}\n              <button\n                className=\"subscribe-icon-btn\"\n                onClick={() => setSubscribeModalVisible(true)}\n                title={t('gold.subscribeTooltip')}\n              >\n                <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\">\n                  <path d=\"M12 5v14M5 12h14\"/>\n                </svg>\n              </button>\n            </h3>\n            <span className=\"chart-source\">{t('gold.tradingviewWarning')}</span>\n          </div>\n          <div className=\"chart-container tradingview-container\">\n            <iframe\n              src=\"https://s.tradingview.com/widgetembed/?frameElementId=tradingview_gold&symbol=OANDA%3AXAUUSD&interval=D&hidesidetoolbar=1&symboledit=0&saveimage=0&toolbarbg=1a1a24&studies=[]&theme=dark&style=1&timezone=Asia%2FShanghai&withdateranges=1&showpopupbutton=0&studies_overrides=%7B%7D&overrides=%7B%7D&enabled_features=[]&disabled_features=[]&locale=zh_CN\"\n              className=\"chart-iframe\"\n              frameBorder=\"0\"\n              scrolling=\"no\"\n              allowFullScreen\n              title=\"TradingView Chart\"\n            ></iframe>\n          </div>\n        </section>\n      </main>\n\n      {/* 全屏水印 */}\n      <div className=\"watermark-container\">\n        <div className=\"watermark-content\">\n          {Array.from({ length: 20 }).map((_, index) => (\n            <div className=\"watermark-item\" key={index}>\n              <span>ChattyPlay</span>\n              <span>P1Kaj1uu</span>\n              <span>不见水星记</span>\n            </div>\n          ))}\n        </div>\n      </div>\n\n      {/* 订阅弹窗 */}\n      <Modal\n        title={<div style={{ fontSize: '18px', fontWeight: 600 }}>{t('gold.subscribeTitle')}</div>}\n        open={subscribeModalVisible}\n        onCancel={() => {\n          setSubscribeModalVisible(false)\n          setEmailInput('')\n        }}\n        footer={[\n          <Button key=\"cancel\" onClick={() => {\n            setSubscribeModalVisible(false)\n            setEmailInput('')\n          }}>\n            {t('common.cancel')}\n          </Button>,\n          <Button\n            key=\"submit\"\n            type=\"primary\"\n            loading={subscribing}\n            onClick={handleSubscribe}\n            style={{ backgroundColor: '#d4af37', borderColor: '#d4af37' }}\n          >\n            {t('gold.subscribe')}\n          </Button>,\n        ]}\n      >\n        <div style={{ padding: '20px 0' }}>\n          <p style={{ marginBottom: '16px', color: '#666' }}>\n            {t('gold.subscribeDescription')}\n          </p>\n          <Input\n            placeholder={t('gold.emailPlaceholder')}\n            value={emailInput}\n            onChange={(e) => setEmailInput(e.target.value)}\n            onPressEnter={handleSubscribe}\n            size=\"large\"\n            type=\"email\"\n          />\n        </div>\n      </Modal>\n    </div>\n  )\n}\n\nexport default Gold\n"
  },
  {
    "path": "src/pages/Help.tsx",
    "content": "import React from 'react'\nimport { Card, Row, Col, Typography } from 'antd'\nimport {\n  MessageOutlined,\n  VideoCameraOutlined,\n  SoundOutlined,\n  TranslationOutlined,\n  PictureOutlined,\n  QuestionCircleOutlined\n} from '@ant-design/icons'\nimport { useTranslation } from 'react-i18next'\nimport styled from 'styled-components'\n\nconst { Title, Paragraph } = Typography\n\nconst PageContainer = styled.div`\n  max-width: 1200px;\n  margin: 0 auto;\n  padding: 40px 20px;\n  min-height: calc(100vh - 200px);\n`\n\nconst SectionTitle = styled.h2`\n  margin-bottom: 40px;\n  text-align: center;\n  font-size: 2rem;\n  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n  -webkit-background-clip: text;\n  -webkit-text-fill-color: transparent;\n  background-clip: text;\n`\n\nconst HelpCard = styled(Card)`\n  border-radius: 12px;\n  border: none;\n  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);\n  transition: all 0.3s ease;\n  height: 100%;\n\n  &:hover {\n    transform: translateY(-5px);\n    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);\n  }\n\n  .ant-card-head {\n    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n    color: #fff;\n    border-radius: 12px 12px 0 0;\n  }\n`\n\nconst HelpIcon = styled.div`\n  font-size: 2.5rem;\n  color: #667eea;\n  margin-bottom: 16px;\n`\n\nconst Help: React.FC = () => {\n  const { t } = useTranslation()\n  const helpSections = [\n    {\n      title: t('help.chatgpt.title'),\n      description: t('help.chatgpt.description'),\n      icon: <MessageOutlined />,\n      steps: [\n        t('help.chatgpt.step1'),\n        t('help.chatgpt.step2'),\n        t('help.chatgpt.step3'),\n        t('help.chatgpt.step4')\n      ]\n    },\n    {\n      title: t('help.video.title'),\n      description: t('help.video.description'),\n      icon: <VideoCameraOutlined />,\n      steps: [\n        t('help.video.step1'),\n        t('help.video.step2'),\n        t('help.video.step3'),\n        t('help.video.step4')\n      ]\n    },\n    {\n      title: t('help.music.title'),\n      description: t('help.music.description'),\n      icon: <SoundOutlined />,\n      steps: [\n        t('help.music.step1'),\n        t('help.music.step2'),\n        t('help.music.step3'),\n        t('help.music.step4')\n      ]\n    },\n    {\n      title: t('help.trans.title'),\n      description: t('help.trans.description'),\n      icon: <TranslationOutlined />,\n      steps: [\n        t('help.trans.step1'),\n        t('help.trans.step2'),\n        t('help.trans.step3'),\n        t('help.trans.step4')\n      ]\n    },\n    {\n      title: t('help.textToPhoto.title'),\n      description: t('help.textToPhoto.description'),\n      icon: <PictureOutlined />,\n      steps: [\n        t('help.textToPhoto.step1'),\n        t('help.textToPhoto.step2'),\n        t('help.textToPhoto.step3'),\n        t('help.textToPhoto.step4'),\n        t('help.textToPhoto.step5')\n      ]\n    },\n    {\n      title: t('help.faq.title'),\n      description: t('help.faq.description'),\n      icon: <QuestionCircleOutlined />,\n      steps: [\n        t('help.faq.step1'),\n        t('help.faq.step2'),\n        t('help.faq.step3'),\n        t('help.faq.step4')\n      ]\n    }\n  ]\n\n  return (\n    <PageContainer>\n      <SectionTitle>{t('help.title')}</SectionTitle>\n      <Row gutter={[24, 24]}>\n        {helpSections.map((section, index) => (\n          <Col xs={24} md={12} key={index}>\n            <HelpCard hoverable>\n              <Card.Meta\n                title={\n                  <div style={{\n                    display: 'flex',\n                    alignItems: 'center',\n                    gap: '12px'\n                  }}>\n                    <HelpIcon>{section.icon}</HelpIcon>\n                    <span>{section.title}</span>\n                  </div>\n                }\n                description={\n                  <div>\n                    <Paragraph style={{ marginBottom: '24px', color: '#64748b' }}>\n                      {section.description}\n                    </Paragraph>\n                    <Title level={5} style={{ marginBottom: '16px', fontSize: '1rem' }}>\n                      {t('help.stepsTitle')}\n                    </Title>\n                    <ul style={{\n                      listStyle: 'none',\n                      padding: 0,\n                      margin: 0\n                    }}>\n                      {section.steps.map((step, stepIndex) => (\n                        <li key={stepIndex} style={{\n                          padding: '8px 0',\n                          paddingLeft: '24px',\n                          position: 'relative'\n                        }}>\n                          <span style={{\n                            position: 'absolute',\n                            left: 0,\n                            top: '8px',\n                            width: '20px',\n                            height: '20px',\n                            background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\n                            color: '#fff',\n                            borderRadius: '50%',\n                            display: 'flex',\n                            alignItems: 'center',\n                            justifyContent: 'center',\n                            fontSize: '0.8rem',\n                            fontWeight: 'bold'\n                          }}>\n                            {stepIndex + 1}\n                          </span>\n                          {step}\n                        </li>\n                      ))}\n                    </ul>\n                  </div>\n                }\n              />\n            </HelpCard>\n          </Col>\n        ))}\n      </Row>\n    </PageContainer>\n  )\n}\n\nexport default Help\n"
  },
  {
    "path": "src/pages/Home.tsx",
    "content": "import React from 'react'\nimport { Typography, Row, Col, Card } from 'antd'\nimport {\n  SoundOutlined,\n  VideoCameraOutlined,\n  TranslationOutlined,\n  MessageOutlined,\n  PictureOutlined,\n  QuestionCircleOutlined,\n  ReadOutlined,\n  BookOutlined,\n  GoldOutlined,\n  AndroidOutlined,\n  RobotOutlined,\n  NodeIndexOutlined\n} from '@ant-design/icons'\nimport { useNavigate } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport styled from 'styled-components'\nimport { logoImage } from '@/utils/images'\n\nconst { Title, Paragraph } = Typography\n\nconst HomeContainer = styled.div`\n  width: 100%;\n  min-height: calc(100vh - 64px);\n  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);\n  position: relative;\n  overflow: hidden;\n\n  /* 背景动画效果 */\n  &::before {\n    content: '';\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    background: radial-gradient(circle at 20% 50%, rgba(102, 126, 234, 0.05) 0%, transparent 50%),\n                radial-gradient(circle at 80% 50%, rgba(118, 75, 162, 0.05) 0%, transparent 50%);\n    animation: backgroundPulse 15s ease-in-out infinite;\n    pointer-events: none;\n  }\n\n  @keyframes backgroundPulse {\n    0%, 100% {\n      opacity: 1;\n      transform: scale(1);\n    }\n    50% {\n      opacity: 0.8;\n      transform: scale(1.05);\n    }\n  }\n`\n\nconst ContentWrapper = styled.div`\n  position: relative;\n  z-index: 1;\n  max-width: 1200px;\n  margin: 0 auto;\n  padding: 40px 24px;\n  width: 100%;\n  box-sizing: border-box;\n\n  @media (max-width: 768px) {\n    padding: 24px 16px;\n  }\n`\n\nconst WelcomeSection = styled.div`\n  text-align: center;\n  padding: 40px 20px;\n  margin-bottom: 40px;\n  animation: fadeInDown 0.8s ease-out;\n\n  @keyframes fadeInDown {\n    from {\n      opacity: 0;\n      transform: translateY(-30px);\n    }\n    to {\n      opacity: 1;\n      transform: translateY(0);\n    }\n  }\n\n  .logo {\n    width: 80px;\n    height: 80px;\n    border-radius: 50%;\n    margin-bottom: 20px;\n    animation: logoFloat 3s ease-in-out infinite;\n  }\n\n  @keyframes logoFloat {\n    0%, 100% {\n      transform: translateY(0) rotate(0deg);\n    }\n    50% {\n      transform: translateY(-10px) rotate(5deg);\n    }\n  }\n\n  @media (max-width: 768px) {\n    padding: 24px 16px;\n  }\n\n  h1 {\n    font-size: clamp(1.8rem, 5vw, 2.5rem) !important;\n  }\n\n  p {\n    font-size: clamp(1rem, 2vw, 1.2rem) !important;\n  }\n`\n\nconst ContentCard = styled(Card)`\n  border-radius: 16px;\n  border: none;\n  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);\n  transition: all 0.3s ease;\n  height: 100%;\n  cursor: pointer;\n  overflow: hidden;\n  position: relative;\n  width: 100%;\n\n  &::before {\n    content: '';\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    height: 4px;\n    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n    transform: scaleX(0);\n    transition: transform 0.3s ease;\n  }\n\n  &:hover::before {\n    transform: scaleX(1);\n  }\n\n  &:hover {\n    transform: translateY(-8px);\n    box-shadow: 0 12px 32px rgba(102, 126, 234, 0.2);\n  }\n\n  .ant-card-body {\n    padding: 24px;\n\n    @media (max-width: 768px) {\n      padding: 20px;\n    }\n  }\n`\n\nconst FeatureIcon = styled.div`\n  font-size: 3rem;\n  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n  -webkit-background-clip: text;\n  -webkit-text-fill-color: transparent;\n  background-clip: text;\n  margin-bottom: 16px;\n  transition: transform 0.3s ease;\n\n  @media (max-width: 768px) {\n    font-size: 2.5rem;\n  }\n`\n\nconst Home: React.FC = () => {\n  const { t } = useTranslation()\n  const navigate = useNavigate()\n\n  const features = [\n    {\n      title: t('home.features.music.title'),\n      description: t('home.features.music.description'),\n      icon: <SoundOutlined />,\n      path: '/music'\n    },\n    {\n      title: t('home.features.video.title'),\n      description: t('home.features.video.description'),\n      icon: <VideoCameraOutlined />,\n      path: '/video'\n    },\n    {\n      title: t('home.features.papers.title'),\n      description: t('home.features.papers.description'),\n      icon: <BookOutlined />,\n      path: '/papers'\n    },\n    {\n      title: t('home.features.goofish.title'),\n      description: t('home.features.goofish.description'),\n      icon: <AndroidOutlined />,\n      path: '/goofish'\n    },\n    {\n      title: t('home.features.chatgpt.title'),\n      description: t('home.features.chatgpt.description'),\n      icon: <MessageOutlined />,\n      path: '/gpt'\n    },\n    {\n      title: t('home.features.markmap.title'),\n      description: t('home.features.markmap.description'),\n      icon: <NodeIndexOutlined />,\n      path: '/markmap'\n    },\n    {\n      title: t('home.features.gold.title'),\n      description: t('home.features.gold.description'),\n      icon: <GoldOutlined />,\n      path: '/gold'\n    },\n    {\n      title: t('home.features.cartoon.title'),\n      description: t('home.features.cartoon.description'),\n      icon: <ReadOutlined />,\n      path: '/cartoon'\n    },\n    {\n      title: t('home.features.worker.title'),\n      description: t('home.features.worker.description'),\n      icon: <RobotOutlined />,\n      path: '/worker'\n    },\n    {\n      title: t('home.features.textToPhoto.title'),\n      description: t('home.features.textToPhoto.description'),\n      icon: <PictureOutlined />,\n      path: '/text-to-photo'\n    },\n    {\n      title: t('home.features.trans.title'),\n      description: t('home.features.trans.description'),\n      icon: <TranslationOutlined />,\n      path: '/trans'\n    },\n    {\n      title: t('home.features.help.title'),\n      description: t('home.features.help.description'),\n      icon: <QuestionCircleOutlined />,\n      path: '/help'\n    }\n  ]\n\n  return (\n    <HomeContainer>\n      <ContentWrapper>\n        <WelcomeSection>\n          <img\n            src={logoImage}\n            alt=\"Logo\"\n            className=\"logo\"\n            style={{ width: '80px', height: '80px', borderRadius: '50%', 'display': 'inline-block', textAlign: 'center' }}\n          />\n          <Title level={1} style={{\n            marginBottom: '16px',\n            fontWeight: 'bold',\n            background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\n            WebkitBackgroundClip: 'text',\n            WebkitTextFillColor: 'transparent',\n            backgroundClip: 'text'\n          }}>\n            {t('home.welcome')}\n          </Title>\n          <Paragraph style={{\n            color: '#64748b',\n            marginBottom: '0',\n            maxWidth: '600px',\n            margin: '0 auto'\n          }}>\n            {t('home.description')}\n          </Paragraph>\n        </WelcomeSection>\n\n        <Row gutter={[16, 16]}>\n          {features.map((feature, index) => (\n            <Col\n              xs={24}\n              sm={12}\n              md={8}\n              key={index}\n              style={{\n                animationDelay: `${index * 0.1}s`\n              }}\n            >\n              <ContentCard\n                hoverable\n                onClick={() => navigate(feature.path)}\n                style={{ animation: 'fadeInUp 0.6s ease-out forwards', opacity: 0 }}\n              >\n                <FeatureIcon>{feature.icon}</FeatureIcon>\n                <Title level={4} style={{ marginBottom: '12px', fontSize: '1.1rem' }}>\n                  {feature.title}\n                </Title>\n                <Paragraph style={{ color: '#64748b', marginBottom: 0, minHeight: '48px', fontSize: '0.95rem' }}>\n                  {feature.description}\n                </Paragraph>\n              </ContentCard>\n            </Col>\n          ))}\n        </Row>\n\n        <div style={{\n          marginTop: '40px',\n          padding: '24px',\n          background: 'rgba(255, 255, 255, 0.8)',\n          backdropFilter: 'blur(10px)',\n          borderRadius: '16px',\n          textAlign: 'center',\n          boxShadow: '0 4px 12px rgba(0, 0, 0, 0.05)'\n        }}>\n          <Paragraph style={{\n            fontSize: '1rem',\n            color: '#64748b',\n            marginBottom: '12px'\n          }}>\n            {t('home.footer.slogan')}\n          </Paragraph>\n          <Paragraph style={{ color: '#94a3b8', marginBottom: 0, fontSize: '0.9rem' }}>\n            {t('home.footer.thanks')}\n          </Paragraph>\n        </div>\n      </ContentWrapper>\n\n      <style>{`\n        @keyframes fadeInUp {\n          from {\n            opacity: 0;\n            transform: translateY(30px);\n          }\n          to {\n            opacity: 1;\n            transform: translateY(0);\n          }\n        }\n      `}</style>\n    </HomeContainer>\n  )\n}\n\nexport default Home\n"
  },
  {
    "path": "src/pages/Latex.tsx",
    "content": "import React, { useState, useEffect, useCallback, useRef } from 'react'\nimport { Button, message, Tooltip, Select, Radio } from 'antd'\nimport { PlayCircleOutlined, FullscreenOutlined, FileTextOutlined, EditOutlined, EyeOutlined } from '@ant-design/icons'\nimport FileTree from '@/components/latex/FileTree'\nimport LatexEditor from '@/components/latex/LatexEditor'\nimport PdfPreview from '@/components/latex/PdfPreview'\nimport { compileLatex } from '@/services/latexApi'\n\nconst Latex: React.FC = () => {\n  // 状态管理\n  const [selectedFileKey, setSelectedFileKey] = useState<string | null>('main')\n  const [selectedFileName, setSelectedFileName] = useState<string>('main.tex')\n  const [editorContent, setEditorContent] = useState<string>('')\n  const [pdfBlob, setPdfBlob] = useState<Blob | null>(null)\n  const [isCompiling, setIsCompiling] = useState(false)\n  const [compileError, setCompileError] = useState<string | null>(null)\n  const [isFullscreen, setIsFullscreen] = useState(false)\n  const [compiler, setCompiler] = useState<'xelatex' | 'pdflatex' | 'lualatex'>('xelatex')\n  const [isImage, setIsImage] = useState(false)\n  const [imageUrl, setImageUrl] = useState('')\n  const [imageFiles, setImageFiles] = useState<Array<{ key: string; name: string; blob: Blob }>>([])\n  \n  // 移动端视图切换：'files' | 'editor' | 'preview'\n  const [mobileView, setMobileView] = useState<'files' | 'editor' | 'preview'>('editor')\n\n  // 防抖定时器\n  const debounceTimerRef = useRef<NodeJS.Timeout | null>(null)\n\n  // 初始加载默认内容\n  useEffect(() => {\n    // 提供英文和中文模板选择\n    const englishTemplate = `\\\\documentclass{article}\n\\\\usepackage[utf8]{inputenc}\n\\\\usepackage{amsmath}\n\\\\usepackage{graphicx}\n\\\\usepackage{float}\n\\\\title{My First LaTeX Document}\n\\\\author{Your Name}\n\\\\date{\\\\today}\n\n\\\\begin{document}\n\n\\\\maketitle\n\n\\\\section{Introduction}\nThis is a sample LaTeX document for testing.\n\n\\\\section{Mathematical Formulas}\nThe famous Euler's formula:\n\\\\begin{equation}\ne^{i\\\\pi} + 1 = 0\n\\\\end{equation}\n\nEinstein's mass-energy equivalence:\n\\\\begin{equation}\nE = mc^2\n\\\\end{equation}\n\n\\\\section{Lists}\n\\\\begin{itemize}\n  \\\\item First item\n  \\\\item Second item\n  \\\\item Third item\n\\\\end{itemize}\n\n\\\\section{Conclusion}\nThis document demonstrates some basic LaTeX features.\n\n\\\\end{document}`\n\n    const chineseTemplate = `\\\\documentclass[UTF8]{ctexart}\n\\\\usepackage{xeCJK}\n\\\\setCJKmainfont{Noto Sans CJK SC}\n\\\\usepackage{graphicx}\n\\\\usepackage{float}\n\\\\title{我的第一篇 LaTeX 文档}\n\\\\author{Your Name}\n\\\\date{\\\\today}\n\n\\\\begin{document}\n\n\\\\maketitle\n\n\\\\section{简介}\n这是使用 LaTeX 编写的示例文档。\n\n\\\\section{数学公式}\n著名的欧拉公式:\n\\\\begin{equation}\ne^{i\\\\pi} + 1 = 0\n\\\\end{equation}\n\n爱因斯坦质能方程:\n\\\\begin{equation}\nE = mc^2\n\\\\end{equation}\n\n\\\\section{列表}\n\\\\begin{itemize}\n  \\\\item 第一项\n  \\\\item 第二项\n  \\\\item 第三项\n\\\\end{itemize}\n\n\\\\section{结论}\n本文档展示了 LaTeX 的一些基本功能。\n\n\\\\end{document}`\n\n    // 存储中文模板供用户选择\n    localStorage.setItem('latex-chinese-template', chineseTemplate)\n    localStorage.setItem('latex-english-template', englishTemplate)\n\n    // 检查是否有保存的文件内容，如果有则加载，否则使用模板\n    const savedContent = localStorage.getItem('latex-file-main')\n    if (savedContent) {\n      setEditorContent(savedContent)\n    } else {\n      setEditorContent(englishTemplate)\n    }\n  }, [])\n\n  // 编译 LaTeX\n  const handleCompile = useCallback(async (code?: string) => {\n    const codeToCompile = code ?? editorContent\n\n    if (!codeToCompile.trim()) {\n      message.warning('请输入 LaTeX 代码')\n      return\n    }\n\n    setIsCompiling(true)\n    setCompileError(null)\n    setPdfBlob(null) // 清除旧的PDF缓存\n\n    try {\n      // 将图片文件转换为 base64 格式\n      const filesArray = await Promise.all(\n        imageFiles.map(async (img) => {\n          const base64 = await blobToBase64(img.blob)\n          return {\n            name: img.name,\n            content: base64\n          }\n        })\n      )\n\n      console.log('编译时包含的图片文件:', imageFiles.map(f => f.name))\n\n      const result = await compileLatex({ code: codeToCompile, compiler, files: filesArray })\n\n      if (result.success && result.pdfBlob) {\n        setPdfBlob(result.pdfBlob)\n        message.success('编译成功')\n        \n        // 编译成功后自动切换到预览视图（移动端）\n        if (window.innerWidth < 700) {\n          setMobileView('preview')\n        }\n      } else {\n        setCompileError(result.error || '编译失败')\n        message.error(result.error || '编译失败')\n      }\n    } catch (err) {\n      const errorMsg = err instanceof Error ? err.message : '编译请求失败'\n      setCompileError(errorMsg)\n      message.error(errorMsg)\n    } finally {\n      setIsCompiling(false)\n    }\n  }, [editorContent, compiler, imageFiles])\n\n  // 辅助函数：将 Blob 转换为 base64 格式\n  const blobToBase64 = (blob: Blob): Promise<string> => {\n    return new Promise((resolve, reject) => {\n      const reader = new FileReader()\n      reader.onloadend = () => {\n        // 保留完整的 data URI 格式\n        resolve(reader.result as string)\n      }\n      reader.onerror = reject\n      reader.readAsDataURL(blob)\n    })\n  }\n\n  // 文件树选择\n  const handleSelectFile = useCallback((key: string, content: string, imageBlob?: Blob) => {\n    console.log('imageBlob:', imageBlob)\n    // 先保存当前编辑内容到 localStorage\n    if (selectedFileKey && editorContent) {\n      localStorage.setItem(`latex-file-${selectedFileKey}`, editorContent)\n    }\n\n    setSelectedFileKey(key)\n\n    // 检查是否为图片文件（以 IMAGE: 开头）\n    if (content.startsWith('IMAGE:')) {\n      // 是图片文件\n      const imageData = content.substring(6) // 去掉 \"IMAGE:\" 前缀\n      setIsImage(true)\n      setImageUrl(imageData)\n      setEditorContent('') // 清空编辑器内容\n      setSelectedFileName(key.split('-').pop() || 'image.png')\n    } else {\n      // 是文本文件\n      setIsImage(false)\n      setImageUrl('')\n    \n      // 从 localStorage 读取文件内容\n      const savedContent = localStorage.getItem(`latex-file-${key}`)\n      const fileContent = savedContent ?? content\n    \n      setEditorContent(fileContent)\n      console.log('fileContent', key)\n      setSelectedFileName('文本文件')\n    }\n    \n    // 移动端选择文件后切换到编辑器视图\n    if (window.innerWidth < 700) {\n      setMobileView('editor')\n    }\n  }, [selectedFileKey, editorContent])\n\n  // 全屏切换\n  const toggleFullscreen = () => {\n    if (!document.fullscreenElement) {\n      document.documentElement.requestFullscreen()\n      setIsFullscreen(true)\n    } else {\n      document.exitFullscreen()\n      setIsFullscreen(false)\n    }\n  }\n\n  // 清理定时器\n  useEffect(() => {\n    return () => {\n      if (debounceTimerRef.current) {\n        clearTimeout(debounceTimerRef.current)\n      }\n    }\n  }, [])\n\n  // 监听窗口大小变化\n  const [isMobile, setIsMobile] = useState(window.innerWidth < 700)\n\n  useEffect(() => {\n    const handleResize = () => {\n      setIsMobile(window.innerWidth < 700)\n    }\n    window.addEventListener('resize', handleResize)\n    return () => window.removeEventListener('resize', handleResize)\n  }, [])\n\n  // 自动保存文件内容到 localStorage\n  useEffect(() => {\n    if (selectedFileKey && editorContent && !isImage) {\n      localStorage.setItem(`latex-file-${selectedFileKey}`, editorContent)\n    }\n  }, [selectedFileKey, editorContent, isImage])\n\n  return (\n    <div\n      style={{\n        display: 'flex',\n        flexDirection: 'column',\n        height: 'calc(100vh - 64px)',\n        background: '#fff',\n      }}\n    >\n      {/* 顶部工具栏 */}\n      <div\n        style={{\n          padding: '8px 16px',\n          background: '#fafafa',\n          borderBottom: '1px solid #f0f0f0',\n          display: 'flex',\n          alignItems: 'center',\n          justifyContent: 'space-between',\n          flexWrap: 'wrap',\n          gap: '8px',\n        }}\n      >\n        <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>\n          <span style={{ fontSize: 14, fontWeight: 500, color: '#333' }}>\n            LaTeX 编辑器\n          </span>\n          {!isMobile && selectedFileName && (\n            <span style={{ fontSize: 12, color: '#999' }}>\n              {selectedFileName}\n            </span>\n          )}\n        </div>\n\n        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n          {!isMobile && (\n            <>\n              <Button\n                size=\"small\"\n                onClick={() => {\n                  const englishTemplate = localStorage.getItem('latex-english-template')\n                  if (englishTemplate) {\n                    setEditorContent(englishTemplate)\n                    message.success('已切换到英文模板')\n                  }\n                }}\n              >\n                英文模板\n              </Button>\n\n              <Button\n                size=\"small\"\n                onClick={() => {\n                  const chineseTemplate = localStorage.getItem('latex-chinese-template')\n                  if (chineseTemplate) {\n                    setEditorContent(chineseTemplate)\n                    message.warning('中文模板：编译可能需要更多时间，且显示效果取决于服务器字体支持')\n                  }\n                }}\n              >\n                中文模板\n              </Button>\n            </>\n          )}\n\n          <Select\n            value={compiler}\n            onChange={(value) => setCompiler(value)}\n            style={{ width: isMobile ? 100 : 120 }}\n            size=\"small\"\n          >\n            <Select.Option value=\"xelatex\">XeLaTeX</Select.Option>\n            <Select.Option value=\"pdflatex\">PDFLaTeX</Select.Option>\n            <Select.Option value=\"lualatex\">LuaLaTeX</Select.Option>\n          </Select>\n\n          <Button\n            type=\"primary\"\n            icon={<PlayCircleOutlined />}\n            onClick={() => handleCompile()}\n            loading={isCompiling}\n            size={isMobile ? \"small\" : \"middle\"}\n            style={{\n              background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\n              border: 'none',\n            }}\n          >\n            编译\n          </Button>\n\n          <Tooltip title={isFullscreen ? '退出全屏' : '全屏'}>\n            <Button\n              icon={<FullscreenOutlined />}\n              onClick={toggleFullscreen}\n              size={isMobile ? \"small\" : \"middle\"}\n            />\n          </Tooltip>\n        </div>\n      </div>\n\n      {/* 三栏布局 - 响应式 */}\n      <div style={{ flex: 1, display: 'flex', overflow: 'hidden', position: 'relative', minHeight: 0 }}>\n        {/* 左侧文件树 - PC端固定显示 */}\n        {!isMobile && (\n          <div\n            style={{\n              width: 240,\n              borderRight: '1px solid #f0f0f0',\n              overflow: 'auto',\n              display: 'flex',\n              flexDirection: 'column',\n              minHeight: 0\n            }}\n          >\n            <FileTree\n              selectedKey={selectedFileKey}\n              onSelectFile={handleSelectFile}\n              onImagesChange={setImageFiles}\n            />\n          </div>\n        )}\n\n        {/* 移动端文件树视图 */}\n        {isMobile && mobileView === 'files' && (\n          <div\n            style={{\n              flex: 1,\n              overflow: 'hidden',\n              display: 'flex',\n              flexDirection: 'column',\n              minHeight: 0\n            }}\n          >\n            <FileTree\n              selectedKey={selectedFileKey}\n              onSelectFile={handleSelectFile}\n              onImagesChange={setImageFiles}\n            />\n          </div>\n        )}\n\n        {/* 中间编辑器 - PC端固定显示，移动端根据视图切换 */}\n        {!isMobile && (\n          <div\n            style={{\n              flex: 1,\n              height: '100%',\n              overflow: 'hidden',\n              display: 'flex',\n              flexDirection: 'column',\n              minHeight: 0\n            }}\n          >\n            {isImage ? (\n              <div style={{\n                height: '100%',\n                display: 'flex',\n                alignItems: 'center',\n                justifyContent: 'center',\n                background: '#f5f5f5'\n              }}>\n                <img\n                  src={imageUrl}\n                  alt=\"预览\"\n                  style={{\n                    maxWidth: '100%',\n                    maxHeight: '100%',\n                    objectFit: 'contain'\n                  }}\n                />\n              </div>\n            ) : (\n              <LatexEditor\n                value={editorContent}\n                onChange={setEditorContent}\n                fileName={selectedFileName}\n              />\n            )}\n          </div>\n        )}\n\n        {/* 移动端编辑器视图 */}\n        {isMobile && mobileView === 'editor' && (\n          <div\n            style={{\n              flex: 1,\n              overflow: 'hidden',\n              display: 'flex',\n              flexDirection: 'column',\n              minHeight: 0\n            }}\n          >\n            {isImage ? (\n              <div style={{\n                height: '100%',\n                display: 'flex',\n                alignItems: 'center',\n                justifyContent: 'center',\n                background: '#f5f5f5'\n              }}>\n                <img\n                  src={imageUrl}\n                  alt=\"预览\"\n                  style={{\n                    maxWidth: '100%',\n                    maxHeight: '100%',\n                    objectFit: 'contain'\n                  }}\n                />\n              </div>\n            ) : (\n              <LatexEditor\n                value={editorContent}\n                onChange={setEditorContent}\n                fileName={selectedFileName}\n              />\n            )}\n          </div>\n        )}\n\n        {/* 右侧 PDF 预览 - PC端固定显示 */}\n        {!isMobile && (\n          <div\n            style={{\n              width: '45%',\n              minWidth: 300,\n              height: '100%',\n              borderLeft: isMobile ? 'none' : '1px solid #f0f0f0',\n              overflow: 'hidden',\n              display: 'flex',\n              flexDirection: 'column',\n              position: isMobile ? 'absolute' : 'relative',\n              top: 0,\n              left: 0,\n              right: 0,\n              bottom: 0,\n              background: '#fff',\n              zIndex: isMobile && mobileView !== 'preview' ? 5 : 10\n            }}\n          >\n            <PdfPreview\n              pdfBlob={pdfBlob}\n              isCompiling={isCompiling}\n              compileError={compileError}\n              onRetry={() => handleCompile()}\n              downloadFileName=\"Latex-Document.pdf\"\n            />\n          </div>\n        )}\n\n        {/* 移动端预览视图 */}\n        {isMobile && mobileView === 'preview' && (\n          <div\n            style={{\n              flex: 1,\n              overflow: 'hidden',\n              display: 'flex',\n              flexDirection: 'column',\n              minHeight: 0\n            }}\n          >\n            <PdfPreview\n              pdfBlob={pdfBlob}\n              isCompiling={isCompiling}\n              compileError={compileError}\n              onRetry={() => handleCompile()}\n              downloadFileName=\"Latex-Document.pdf\"\n            />\n          </div>\n        )}\n      </div>\n\n      {/* 移动端底部导航栏 */}\n      {isMobile && (\n        <div\n          style={{\n            display: 'flex',\n            alignItems: 'center',\n            justifyContent: 'space-around',\n            padding: '8px 16px',\n            background: '#fff',\n            borderTop: '1px solid #f0f0f0',\n            boxShadow: '0 -2px 8px rgba(0,0,0,0.05)',\n            zIndex: 25,\n            position: 'relative'\n          }}\n        >\n          <Radio.Group\n            value={mobileView}\n            onChange={(e) => setMobileView(e.target.value)}\n            optionType=\"button\"\n            buttonStyle=\"solid\"\n            size=\"small\"\n            className=\"bg-white rounded-lg flex w-full\"\n            style={{ display: 'flex', width: '100%' }}\n          >\n            <Radio.Button value=\"files\" className=\"flex-1 text-center\" style={{ flex: 1 }}>\n              <FileTextOutlined /> 文件\n            </Radio.Button>\n            <Radio.Button value=\"editor\" className=\"flex-1 text-center\" style={{ flex: 1 }}>\n              <EditOutlined /> 编辑\n            </Radio.Button>\n            <Radio.Button value=\"preview\" className=\"flex-1 text-center\" style={{ flex: 1 }}>\n              <EyeOutlined /> 预览\n            </Radio.Button>\n          </Radio.Group>\n        </div>\n      )}\n    </div>\n  )\n}\n\nexport default Latex"
  },
  {
    "path": "src/pages/Login.tsx",
    "content": "import React, { useState, useEffect, useRef } from 'react'\nimport { Form, Input, Button, Checkbox, message, Space } from 'antd'\nimport {\n  UserOutlined,\n  LockOutlined,\n  KeyOutlined,\n  EyeOutlined,\n  EyeInvisibleOutlined,\n} from '@ant-design/icons'\nimport { useGoogleLogin } from '@react-oauth/google'\nimport { FcGoogle } from 'react-icons/fc'\nimport { FaGithub } from 'react-icons/fa'\nimport { useNavigate } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport styled from 'styled-components'\nimport VerifyCode from '../components/VerifyCode'\nimport HeartBeat from '../components/HeartBeat'\nimport { logoImage } from '@/utils/images'\nimport { setToken } from '@/utils/token'\nimport { isMobileDevice } from '@/utils/isMobile'\n\n// Cloudflare Turnstile 配置\nconst TURNSTILE_SITE_KEY = import.meta.env.VITE_TURNSTILE_SITE_KEY || ''\n\n// 创建气泡组件\nconst Bubble = styled.div<{ size: number; left: number; delay: number; popped: boolean }>`\n  position: absolute;\n  bottom: -100px;\n  left: ${props => props.left}%;\n  width: ${props => props.size}px;\n  height: ${props => props.size}px;\n  background: radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.3));\n  border-radius: 50%;\n  animation: rise ${props => 4 + props.delay}s ease-in infinite;\n  opacity: 0;\n  pointer-events: none;\n  transition: transform 0.1s ease-out, opacity 0.1s ease-out;\n  ${props => props.popped && `\n    animation: none;\n    transform: scale(0);\n    opacity: 0;\n  `}\n\n  @keyframes rise {\n    0% {\n      bottom: -100px;\n      opacity: 0;\n      transform: translateX(0) scale(1);\n    }\n    10% {\n      opacity: 0.8;\n    }\n    90% {\n      opacity: 0.8;\n      transform: translateX(${props => Math.sin(props.delay * 10) * 30}px) scale(1);\n    }\n    100% {\n      bottom: 100vh;\n      opacity: 0;\n      transform: translateX(${props => Math.sin(props.delay * 10) * 50}px) scale(1.2);\n    }\n  }\n\n  /* 气泡光泽效果 */\n  &::after {\n    content: '';\n    position: absolute;\n    top: 15%;\n    left: 20%;\n    width: 30%;\n    height: 30%;\n    background: rgba(255, 255, 255, 0.6);\n    border-radius: 50%;\n    filter: blur(2px);\n  }\n`\n\nconst LoginContainer = styled.div`\n  min-height: 100vh;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  padding: 20px;\n  background: linear-gradient(45deg, #667eea, #764ba2, #f093fb, #f5576c, #667eea);\n  background-size: 400% 400%;\n  animation: gradientShift 15s ease infinite;\n  position: relative;\n  overflow: hidden;\n\n  @keyframes gradientShift {\n    0% { background-position: 0% 50%; }\n    50% { background-position: 100% 50%; }\n    100% { background-position: 0% 50%; }\n  }\n\n  /* 动态光晕效果 */\n  &::before {\n    content: '';\n    position: absolute;\n    top: -50%;\n    left: -50%;\n    width: 200%;\n    height: 200%;\n    background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 1px, transparent 1px);\n    background-size: 60px 60px;\n    animation: moveBackground 30s linear infinite;\n  }\n\n  @keyframes moveBackground {\n    0% { transform: translate(0, 0) rotate(0deg); }\n    100% { transform: translate(60px, 60px) rotate(360deg); }\n  }\n`\n\nconst LoginBox = styled.div`\n  width: 100%;\n  max-width: 400px;\n  background: rgba(255, 255, 255, 0.95);\n  backdrop-filter: blur(10px);\n  border-radius: 20px;\n  box-shadow:\n    0 20px 60px rgba(0, 0, 0, 0.3),\n    0 0 0 1px rgba(255, 255, 255, 0.5) inset;\n  position: relative;\n  z-index: 1;\n  padding: 12px 32px;\n  animation: boxAppear 0.6s cubic-bezier(0.16, 1, 0.3, 1);\n\n  @keyframes boxAppear {\n    from {\n      opacity: 0;\n      transform: translateY(30px) scale(0.9);\n    }\n    to {\n      opacity: 1;\n      transform: translateY(0) scale(1);\n    }\n  }\n\n  @media (max-width: 480px) {\n    max-width: 100%;\n    padding: 24px;\n  }\n`\n\nconst Logo = styled.div`\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  margin-bottom: 24px;\n\n  img {\n    width: 60px;\n    height: 60px;\n    border-radius: 50%;\n    margin-bottom: 12px;\n    animation: logoAnimation 3s ease-in-out infinite;\n    box-shadow: 0 8px 20px rgba(102, 126, 234, 0.4);\n  }\n\n  @keyframes logoAnimation {\n    0%, 100% {\n      transform: rotate(0deg) scale(1);\n    }\n    50% {\n      transform: rotate(180deg) scale(1.05);\n    }\n  }\n\n  h3 {\n    margin: 0;\n    font-size: 1.3rem;\n    font-weight: bold;\n    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n    -webkit-background-clip: text;\n    -webkit-text-fill-color: transparent;\n    background-clip: text;\n    letter-spacing: 0.1em;\n  }\n`\n\nconst OAuthDivider = styled.div`\n  display: flex;\n  align-items: center;\n  margin: 24px 0;\n  color: #94a3b8;\n  font-size: 0.875rem;\n\n  &::before,\n  &::after {\n    content: '';\n    flex: 1;\n    height: 1px;\n    background: linear-gradient(to right, transparent, #e2e8f0, transparent);\n  }\n\n  &::before {\n    margin-right: 16px;\n  }\n\n  &::after {\n    margin-left: 16px;\n  }\n`\n\nconst OAuthButtonContainer = styled.div`\n  display: flex;\n  gap: 12px;\n  margin-bottom: 16px;\n`\n\nconst OAuthButton = styled.button<{ variant: 'google' | 'github' }>`\n  flex: 1;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  gap: 8px;\n  height: 44px;\n  border: 1px solid ${props => props.variant === 'google' ? '#dadce0' : '#d1d5db'};\n  border-radius: 8px;\n  background: ${props => props.variant === 'google' ? '#fff' : '#24292e'};\n  color: ${props => props.variant === 'github' ? '#fff' : '#3c4043'};\n  font-size: 0.9rem;\n  font-weight: 500;\n  cursor: pointer;\n  transition: all 0.2s ease;\n  padding: 0 16px;\n\n  &:hover {\n    transform: translateY(-1px);\n    box-shadow: 0 4px 12px ${props => props.variant === 'google' ? 'rgba(60, 64, 67, 0.3)' : 'rgba(36, 41, 46, 0.3)'};\n    border-color: ${props => props.variant === 'google' ? '#d3d3d3' : '#1a202c'};\n  }\n\n  &:active {\n    transform: translateY(0);\n  }\n\n  svg {\n    width: 20px;\n    height: 20px;\n  }\n`\n\nconst ModeSwitch = styled.div`\n  text-align: center;\n  margin-top: 16px;\n  color: #667eea;\n  cursor: pointer;\n  font-size: 0.9rem;\n  transition: color 0.2s;\n\n  &:hover {\n    color: #764ba2;\n    text-decoration: underline;\n  }\n`\n\n// 添加 Turnstile 脚本加载\nconst loadTurnstileScript = (): Promise<void> => {\n  return new Promise((resolve, reject) => {\n    // 如果已经加载完成\n    if (window.turnstile) {\n      resolve()\n      return\n    }\n\n    // 检查是否已有脚本标签\n    const existingScript = document.querySelector('script[src*=\"challenges.cloudflare.com/turnstile\"]')\n    if (existingScript) {\n      existingScript.addEventListener('load', () => resolve())\n      existingScript.addEventListener('error', () => reject())\n      return\n    }\n\n    const script = document.createElement('script')\n    script.src = 'https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit'\n    script.async = true\n    script.defer = true\n    script.onload = () => resolve()\n    script.onerror = () => reject(new Error('Failed to load Turnstile script'))\n    document.head.appendChild(script)\n  })\n}\n\nconst Login: React.FC = () => {\n  const { t } = useTranslation()\n  const [loginForm] = Form.useForm()\n  const [registerForm] = Form.useForm()\n  const [verifyCode, setVerifyCode] = useState('')\n  const [loading, setLoading] = useState(false)\n  const [isAgreed, setIsAgreed] = useState(true)\n  const [showHeartBeat, setShowHeartBeat] = useState(false)\n  const [isLoginMode, setIsLoginMode] = useState(true)\n  const [turnstileReady, setTurnstileReady] = useState(false)\n  const turnstileLoginRef = useRef<HTMLDivElement>(null)\n  const turnstileRegisterRef = useRef<HTMLDivElement>(null)\n  const turnstileWidgetId = useRef<{ login: string | null; register: string | null }>({ login: null, register: null })\n  const navigate = useNavigate()\n  const [bubbles, setBubbles] = useState(() =>\n    Array.from({ length: 15 }, () => ({\n      size: Math.random() * 30 + 10,\n      left: Math.random() * 100,\n      delay: Math.random() * 3,\n      popped: false\n    }))\n  )\n\n  useEffect(() => {\n    generateVerifyCode()\n\n    // 气泡破裂效果\n    const popBubbles = setInterval(() => {\n      setBubbles(prev => {\n        const popIndex = Math.floor(Math.random() * prev.length)\n        const newBubbles = [...prev]\n\n        // 破裂动画\n        newBubbles[popIndex] = { ...newBubbles[popIndex], popped: true }\n\n        // 重新生成该气泡\n        setTimeout(() => {\n          setBubbles(current => {\n            const reset = [...current]\n            reset[popIndex] = {\n              size: Math.random() * 30 + 10,\n              left: Math.random() * 100,\n              delay: Math.random() * 3,\n              popped: false\n            }\n            return reset\n          })\n        }, 100)\n\n        return newBubbles\n      })\n    }, 2000)\n\n    return () => clearInterval(popBubbles)\n  }, [])\n\n  // 加载 Turnstile 脚本\n  useEffect(() => {\n    // 如果没有配置站点密钥，跳过加载\n    if (!TURNSTILE_SITE_KEY) {\n      console.warn('Turnstile site key not configured, skipping verification')\n      return\n    }\n\n    loadTurnstileScript()\n      .then(() => {\n        setTurnstileReady(true)\n      })\n      .catch((error) => {\n        console.warn('Failed to load Turnstile:', error)\n        // Turnstile 加载失败，允许用户继续登录（静默降级）\n        setTurnstileReady(true) // 设置为 true 避免一直等待\n      })\n  }, [])\n\n  const generateVerifyCode = () => {\n    const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'\n    let code = ''\n    for (let i = 0; i < 4; i++) {\n      code += chars.charAt(Math.floor(Math.random() * chars.length))\n    }\n    setVerifyCode(code)\n  }\n\n  // 初始化 Turnstile\n  const initTurnstile = (containerId: 'login' | 'register') => {\n    const container = containerId === 'login' ? turnstileLoginRef.current : turnstileRegisterRef.current\n    const widgetKey = containerId === 'login' ? 'login' : 'register'\n\n    if (!container || !window.turnstile) return\n\n    // 清除已有的 widget\n    if (turnstileWidgetId.current[widgetKey]) {\n      try {\n        window.turnstile.remove(turnstileWidgetId.current[widgetKey]!)\n      } catch (e) {\n        // ignore\n      }\n      turnstileWidgetId.current[widgetKey] = null\n    }\n\n    try {\n      const widgetId = window.turnstile.render(container, {\n        sitekey: TURNSTILE_SITE_KEY,\n        theme: 'light',\n        callback: (token: string) => {\n          console.log(token)\n        },\n        'expired-callback': () => {\n          console.log(`Turnstile token expired for ${containerId}`)\n        },\n        // @ts-ignore\n        'error-callback': (err: any) => {\n          console.error(`Turnstile error for ${containerId}:`, err)\n        },\n      })\n      turnstileWidgetId.current[widgetKey] = widgetId\n    } catch (e) {\n      console.warn(`Turnstile render failed for ${containerId}:`, e)\n    }\n  }\n\n  // 当 Turnstile 准备好且容器存在时初始化\n  useEffect(() => {\n    if (turnstileReady && turnstileLoginRef.current) {\n      initTurnstile('login')\n    }\n  }, [turnstileReady, isLoginMode])\n\n  useEffect(() => {\n    if (turnstileReady && !isLoginMode && turnstileRegisterRef.current) {\n      initTurnstile('register')\n    }\n  }, [turnstileReady, isLoginMode])\n\n  // 获取 Turnstile token\n  const getTurnstileToken = (mode: 'login' | 'register'): string | null => {\n    const widgetId = turnstileWidgetId.current[mode]\n    if (window.turnstile && widgetId) {\n      try {\n        return window.turnstile.getResponse(widgetId)\n      } catch (e) {\n        return null\n      }\n    }\n    return null\n  }\n\n  // 重置 Turnstile\n  const resetTurnstile = (mode: 'login' | 'register') => {\n    const widgetId = turnstileWidgetId.current[mode]\n    if (window.turnstile && widgetId) {\n      try {\n        window.turnstile.reset(widgetId)\n      } catch (e) {\n        // ignore\n      }\n    }\n  }\n\n  const handleLogin = async (values: any) => {\n    const isCodeValid = values.code?.toUpperCase() === verifyCode.toUpperCase()\n\n    if (!isCodeValid) {\n      message.error(t('login.verifyCodeError'))\n      generateVerifyCode()\n      loginForm.setFieldsValue({ code: '' })\n      return\n    }\n\n    if (!isAgreed) {\n      message.error(t('login.agreeRequired'))\n      return\n    }\n\n    // 获取 Turnstile token\n    const turnstileToken = getTurnstileToken('login')\n\n    // 如果没有 token 且 Turnstile 已加载，说明用户未完成验证（仅生产环境检查）\n    if (!import.meta.env.DEV && turnstileReady && !turnstileToken) {\n      message.error('请完成人机验证')\n      return\n    }\n\n    setLoading(true)\n    try {\n      const response = await fetch('/api/auth/login', {\n        method: 'POST',\n        headers: {\n          'Content-Type': 'application/json'\n        },\n        body: JSON.stringify({\n          username: values.username,\n          password: values.password,\n          ...(turnstileToken ? { 'cf-turnstile-response': turnstileToken } : {})\n        })\n      })\n\n      const data = await response.json()\n\n      if (data.success) {\n        // 保存登录状态和 token\n        setToken(data.token)\n        localStorage.setItem('isLoggedIn', 'true')\n        localStorage.setItem('username', data.user.username)\n        localStorage.setItem('userId', data.user.id.toString())\n        if (data.user.avatar) {\n          localStorage.setItem('avatar', data.user.avatar)\n        }\n\n        message.success(t('login.loginSuccess'))\n        if (!isMobileDevice()) {\n          setShowHeartBeat(true)\n        } else {\n          setShowHeartBeat(false)\n          navigate('/home')\n        }\n      } else {\n        message.error(data.message || t('login.loginFailed'))\n        // 登录失败时重置 Turnstile\n        resetTurnstile('login')\n      }\n    } catch (error: any) {\n      console.error('Login error:', error)\n      message.error(error.message || t('login.loginFailed'))\n      resetTurnstile('login')\n    } finally {\n      setLoading(false)\n    }\n  }\n\n  const handleRegister = async (values: any) => {\n    const isCodeValid = values.code?.toUpperCase() === verifyCode.toUpperCase()\n\n    if (!isCodeValid) {\n      message.error(t('login.verifyCodeError'))\n      generateVerifyCode()\n      registerForm.setFieldsValue({ code: '' })\n      return\n    }\n\n    if (!isAgreed) {\n      message.error(t('login.agreeRequired'))\n      return\n    }\n\n    if (values.password !== values.confirmPassword) {\n      message.error(t('login.confirmPasswordMismatch'))\n      return\n    }\n\n    // 获取 Turnstile token\n    const turnstileToken = getTurnstileToken('register')\n\n    // 如果没有 token 且 Turnstile 已加载，说明用户未完成验证（仅生产环境检查）\n    if (!import.meta.env.DEV && turnstileReady && !turnstileToken) {\n      message.error('请完成人机验证')\n      return\n    }\n\n    setLoading(true)\n    try {\n      const response = await fetch('/api/auth/register', {\n        method: 'POST',\n        headers: {\n          'Content-Type': 'application/json'\n        },\n        body: JSON.stringify({\n          username: values.username,\n          password: values.password,\n          email: values.email,\n          ...(turnstileToken ? { 'cf-turnstile-response': turnstileToken } : {})\n        })\n      })\n\n      const data = await response.json()\n\n      if (data.success) {\n        message.success(t('login.registerSuccess'))\n        toggleMode()\n      } else {\n        message.error(data.message || t('login.registerFailed'))\n        // 注册失败时重置 Turnstile\n        resetTurnstile('register')\n      }\n    } catch (error: any) {\n      console.error('Register error:', error)\n      message.error(error.message || t('login.registerFailed'))\n      resetTurnstile('register')\n    } finally {\n      setLoading(false)\n    }\n  }\n\n  const handleHeartBeatComplete = () => {\n    navigate('/home')\n  }\n\n  const handleReset = () => {\n    loginForm.resetFields()\n    registerForm.resetFields()\n    generateVerifyCode()\n    // 重置 Turnstile\n    resetTurnstile('login')\n    resetTurnstile('register')\n  }\n\n  const toggleMode = () => {\n    setIsLoginMode(!isLoginMode)\n    loginForm.resetFields()\n    registerForm.resetFields()\n    generateVerifyCode()\n    // 切换模式后重置对应的 Turnstile\n    setTimeout(() => {\n      resetTurnstile('login')\n      resetTurnstile('register')\n    }, 100)\n  }\n\n  // Google OAuth\n  const googleLogin = useGoogleLogin({\n    onSuccess: async (tokenResponse) => {\n      console.log('Google Access Token:', tokenResponse)\n\n      // 获取用户信息\n      try {\n        const response = await fetch('https://www.googleapis.com/oauth2/v3/userinfo', {\n          headers: {\n            Authorization: `Bearer ${tokenResponse.access_token}`\n          }\n        })\n        const userData = await response.json()\n        console.log('Google User Data:', userData)\n\n        // 保存登录状态\n        setToken()\n        localStorage.setItem('isLoggedIn', 'true')\n        localStorage.setItem('username', userData.name || 'Google用户')\n        localStorage.setItem('email', userData.email || '')\n        localStorage.setItem('avatar', userData.picture || '')\n\n        message.success(t('login.loginSuccess'))\n        setShowHeartBeat(true)\n      } catch (error) {\n        console.error('Error fetching Google user info:', error)\n        message.error(t('login.loginFailed'))\n      }\n    },\n    onError: () => {\n      console.error('Google Login Failed')\n      message.error(t('login.loginFailed'))\n    },\n  })\n\n  // GitHub OAuth 处理\n  const handleGithubLogin = () => {\n    const clientId = import.meta.env.VITE_GITHUB_CLIENT_ID\n    if (!clientId || clientId === 'your_github_client_id_here') {\n      message.error('GitHub Client ID 未配置，请先配置')\n      return\n    }\n\n    // 构建 GitHub OAuth 授权 URL，直接回调到 /home\n    const redirectUri = window.location.origin + '/home'\n    const githubAuthUrl = `https://github.com/login/oauth/authorize?client_id=${clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&scope=user:email`\n\n    // 跳转到 GitHub 授权页面\n    window.location.href = githubAuthUrl\n    setToken()\n    localStorage.setItem('isLoggedIn', 'true')\n    localStorage.setItem('username', 'Github用户')\n  }\n\n  return (\n    <>\n      {showHeartBeat ? (\n        <HeartBeat onComplete={handleHeartBeatComplete} />\n      ) : (\n        <LoginContainer>\n          {bubbles.map((bubble, index) => (\n            <Bubble\n              key={index}\n              size={bubble.size}\n              left={bubble.left}\n              delay={bubble.delay}\n              popped={bubble.popped}\n            />\n          ))}\n\n          <LoginBox>\n            <Logo>\n              <img src={logoImage} alt=\"Logo\" />\n              <h3>ChattyPlay</h3>\n            </Logo>\n\n            {isLoginMode ? (\n              <Form\n                form={loginForm}\n                onFinish={handleLogin}\n                layout=\"vertical\"\n                style={{ marginBottom: '0' }}\n              >\n                <Form.Item\n                  name=\"username\"\n                  label={t('login.account')}\n                  rules={[{ required: true, message: t('login.accountRequired') }]}\n                >\n                  <Input\n                    prefix={<UserOutlined />}\n                    placeholder={t('login.accountPlaceholder')}\n                    size=\"large\"\n                    autoComplete=\"off\"\n                  />\n                </Form.Item>\n\n                <Form.Item\n                  name=\"password\"\n                  label={t('login.password')}\n                  rules={[\n                    { required: true, message: t('login.passwordRequired') },\n                    { min: 6, max: 20, message: t('login.passwordLength') }\n                  ]}               \n                >\n                  <Input.Password\n                    prefix={<LockOutlined />}\n                    placeholder={t('login.passwordPlaceholder')}\n                    size=\"large\"\n                    iconRender={(visible) => (\n                      visible ? <EyeOutlined /> : <EyeInvisibleOutlined />\n                    )}\n                  />\n                </Form.Item>\n\n                <Form.Item\n                  name=\"code\"\n                  label={t('login.verifyCode')}\n                  rules={[{ required: true, message: t('login.verifyCodeRequired') }]}\n                >\n                  <div style={{ display: 'flex', gap: '12px', alignItems: 'center' }}>\n                    <Input\n                      prefix={<KeyOutlined />}\n                      placeholder={t('login.verifyCodePlaceholder')}\n                      size=\"large\"\n                      maxLength={4}\n                      style={{ flex: 1 }}\n                    />\n                    <div style={{ cursor: 'pointer', userSelect: 'none' }} onClick={generateVerifyCode}>\n                      <VerifyCode code={verifyCode} />\n                    </div>\n                  </div>\n                </Form.Item>\n\n                <div style={{\n                  display: 'flex',\n                  justifyContent: 'space-between',\n                  alignItems: 'center',\n                  marginBottom: '12px',\n                  paddingTop: '12px',\n                  borderTop: '1px solid #e2e8f0'\n                }}>\n                  <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>\n                    <Checkbox\n                      checked={isAgreed}\n                      onChange={(e) => setIsAgreed(e.target.checked)}\n                    >\n                      {t('login.agree')}\n                    </Checkbox>\n                  </div>\n                </div>\n\n                <div style={{ display: 'flex', justifyContent: 'center', marginBottom: '12px' }}>\n                  <div ref={turnstileLoginRef} />\n                </div>\n\n                <Form.Item>\n                  <Space style={{ width: '100%', justifyContent: 'center' }} size={8}>\n                    <Button\n                      type=\"primary\"\n                      htmlType=\"submit\"\n                      loading={loading}\n                      style={{\n                        flex: 1,\n                        height: '44px',\n                        fontSize: '0.95rem',\n                        background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\n                        border: 'none'\n                      }}\n                    >\n                      {t('login.loginBtn')}\n                    </Button>\n                    <Button\n                      onClick={handleReset}\n                      style={{ flex: 1, height: '44px', fontSize: '0.95rem' }}\n                    >\n                      {t('login.resetBtn')}\n                    </Button>\n                  </Space>\n                </Form.Item>\n              </Form>\n            ) : (\n              <Form\n                form={registerForm}\n                onFinish={handleRegister}\n                layout=\"vertical\"\n                style={{ marginBottom: '0' }}\n              >\n                <Form.Item\n                  name=\"username\"\n                  label={t('login.account')}\n                  rules={[\n                    { required: true, message: t('login.accountRequired') },\n                    { min: 3, max: 20, message: t('login.usernameLength') }\n                  ]}\n                >\n                  <Input\n                    prefix={<UserOutlined />}\n                    placeholder={t('login.accountPlaceholder')}\n                    size=\"large\"\n                    autoComplete=\"off\"\n                  />\n                </Form.Item>\n\n                <Form.Item\n                  name=\"password\"\n                  label={t('login.password')}\n                  rules={[\n                    { required: true, message: t('login.passwordRequired') },\n                    { min: 6, max: 20, message: t('login.passwordLengthRegister') }\n                  ]}\n                >\n                  <Input.Password\n                    prefix={<LockOutlined />}\n                    placeholder={t('login.passwordPlaceholder')}\n                    size=\"large\"\n                    iconRender={(visible) => (\n                      visible ? <EyeOutlined /> : <EyeInvisibleOutlined />\n                    )}\n                  />\n                </Form.Item>\n\n                <Form.Item\n                  name=\"confirmPassword\"\n                  label={t('login.confirmPassword')}\n                  dependencies={['password']}\n                  rules={[\n                    { required: true, message: t('login.confirmPasswordRequired') },\n                    ({ getFieldValue }) => ({\n                      validator(_, value) {\n                        if (!value || getFieldValue('password') === value) {\n                          return Promise.resolve()\n                        }\n                        return Promise.reject(new Error(t('login.confirmPasswordMismatch')))\n                      },\n                    }),\n                  ]}\n                >\n                  <Input.Password\n                    prefix={<LockOutlined />}\n                    placeholder={t('login.confirmPasswordPlaceholder')}\n                    size=\"large\"\n                    iconRender={(visible) => (\n                      visible ? <EyeOutlined /> : <EyeInvisibleOutlined />\n                    )}\n                  />\n                </Form.Item>\n\n                {/* 注册时添加邮箱字段（如果需要） */}\n                <Form.Item\n                  name=\"email\"\n                  label={t('login.email') || '邮箱'}\n                  rules={[\n                    { type: 'email', message: t('login.emailInvalid') || '请输入有效的邮箱地址' }\n                  ]}\n                >\n                  <Input\n                    placeholder=\"your@email.com\"\n                    size=\"large\"\n                  />\n                </Form.Item>\n\n                <Form.Item\n                  name=\"code\"\n                  label={t('login.verifyCode')}\n                  rules={[{ required: true, message: t('login.verifyCodeRequired') }]}\n                >\n                  <div style={{ display: 'flex', gap: '12px', alignItems: 'center' }}>\n                    <Input\n                      prefix={<KeyOutlined />}\n                      placeholder={t('login.verifyCodePlaceholder')}\n                      size=\"large\"\n                      maxLength={4}\n                      style={{ flex: 1 }}\n                    />\n                    <div style={{ cursor: 'pointer', userSelect: 'none' }} onClick={generateVerifyCode}>\n                      <VerifyCode code={verifyCode} />\n                    </div>\n                  </div>\n                </Form.Item>\n\n                <div style={{\n                  display: 'flex',\n                  justifyContent: 'space-between',\n                  alignItems: 'center',\n                  marginBottom: '12px',\n                  paddingTop: '12px',\n                  borderTop: '1px solid #e2e8f0'\n                }}>\n                  <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>\n                    <Checkbox\n                      checked={isAgreed}\n                      onChange={(e) => setIsAgreed(e.target.checked)}\n                    >\n                      {t('login.agree')}\n                    </Checkbox>\n                  </div>\n                </div>\n\n                <div style={{ display: 'flex', justifyContent: 'center', marginBottom: '8px' }}>\n                  <div ref={turnstileRegisterRef} />\n                </div>\n\n                <Form.Item style={{ marginBottom: '8px' }}>\n                  <Space style={{ width: '100%', justifyContent: 'center' }} size={8}>\n                    <Button\n                      type=\"primary\"\n                      htmlType=\"submit\"\n                      loading={loading}\n                      style={{\n                        flex: 1,\n                        height: '44px',\n                        fontSize: '0.95rem',\n                        background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\n                        border: 'none'\n                      }}\n                    >\n                      {t('login.registerBtn')}\n                    </Button>\n                    <Button\n                      onClick={handleReset}\n                      style={{ flex: 1, height: '44px', fontSize: '0.95rem' }}\n                    >\n                      {t('login.resetBtn')}\n                    </Button>\n                  </Space>\n                </Form.Item>\n              </Form>\n            )}\n\n            <ModeSwitch onClick={toggleMode}>\n              {isLoginMode ? t('login.switchToRegister') : t('login.switchToLogin')}\n            </ModeSwitch>\n\n            {/* OAuth 第三方登录 */}\n            <OAuthDivider>{t('login.thirdPartyLoginTip')}</OAuthDivider>\n\n            <OAuthButtonContainer>\n              <OAuthButton variant=\"google\" onClick={() => googleLogin()}>\n                <FcGoogle />\n                Google\n              </OAuthButton>\n              <OAuthButton variant=\"github\" onClick={handleGithubLogin}>\n                <FaGithub />\n                GitHub\n              </OAuthButton>\n            </OAuthButtonContainer>\n          </LoginBox>\n        </LoginContainer>\n      )}\n    </>\n  )\n}\n\nexport default Login"
  },
  {
    "path": "src/pages/Markmap.tsx",
    "content": "import React, { useState, useEffect, useRef } from 'react'\nimport { message } from 'antd'\nimport { useTranslation } from 'react-i18next'\nimport EditorPanel from '@/components/markmap/EditorPanel'\nimport MindmapPanel from '@/components/markmap/MindmapPanel'\nimport MobileMenu from '@/components/markmap/MobileMenu'\nimport MobileTabBar from '@/components/markmap/MobileTabBar'\nimport PromptModal from '@/components/markmap/PromptModal'\nimport EditNodeModal from '@/components/markmap/EditNodeModal'\nimport InfoModal from '@/components/markmap/InfoModal'\nimport LandscapeMode from '@/components/markmap/LandscapeMode'\nimport {\n  waitForLibraries,\n  getNodeColor,\n  createExportableSvg,\n  downloadBlob,\n  generateExportFileName,\n  collectNodeLines,\n  removeContextMenu,\n  createContextMenu,\n  LAST_SUCCESSFUL_MODEL_KEY,\n  type AiResult,\n  type NodeContext\n} from '@/utils/markmap'\n\nconst Markmap: React.FC = () => {\n  const { t } = useTranslation()\n  const [mm, setMm] = useState<any>(null)\n  const [transformer, setTransformer] = useState<any>(null)\n  const [currentMarkdown, setCurrentMarkdown] = useState<string>('')\n  const [aiResults, setAiResults] = useState<AiResult[]>([])\n  const [activeResultIndex, setActiveResultIndex] = useState<number>(-1)\n  const [currentViewMode, setCurrentViewMode] = useState<'input' | 'original' | 'markdown'>('input')\n  const [aiPromptTemplate, setAiPromptTemplate] = useState<string>('')\n  const [editingNodeContext, setEditingNodeContext] = useState<NodeContext | null>(null)\n  const [isLoading, setIsLoading] = useState<boolean>(false)\n  const [timerSeconds, setTimerSeconds] = useState<number>(0)\n  const [statusMessage, setStatusMessage] = useState<string>('')\n  const [apiUrl, setApiUrl] = useState<string>('')\n  const [apiKey, setApiKey] = useState<string>('')\n  const [selectedModel, setSelectedModel] = useState<string>('gpt-4o-mini')\n  const [customModel, setCustomModel] = useState<string>('')\n  const [versionCount, setVersionCount] = useState<number>(1)\n  const [availableModels, setAvailableModels] = useState<string[]>([])\n  const [promptModalVisible, setPromptModalVisible] = useState<boolean>(false)\n  const [infoModalVisible, setInfoModalVisible] = useState<boolean>(false)\n  const [editModalVisible, setEditModalVisible] = useState<boolean>(false)\n  const [isFullscreen, setIsFullscreen] = useState<boolean>(false)\n  const [isMobileMenuOpen, setIsMobileMenuOpen] = useState<boolean>(false)\n  const [currentMobilePanel, setCurrentMobilePanel] = useState<'editor' | 'mindmap'>('editor')\n  const [isLandscapeMode, setIsLandscapeMode] = useState<boolean>(false)\n  const [searchValue, setSearchValue] = useState('')\n  const [zoomLevel, setZoomLevel] = useState<number>(1)\n  const timerIntervalRef = useRef<NodeJS.Timeout | null>(null)\n  const startTimeRef = useRef<number>(0)\n  const mindmapContainerRef = useRef<HTMLDivElement>(null)\n  const mindmapSvgRef = useRef<SVGSVGElement>(null)\n  const landscapeContentRef = useRef<HTMLDivElement>(null)\n  const isInitializedRef = useRef<boolean>(false)\n\n  useEffect(() => {\n    // 防止重复初始化\n    if (isInitializedRef.current) return\n\n    const initLibraries = async () => {\n      try {\n        await waitForLibraries()\n\n        // 清空 SVG 内容\n        if (mindmapSvgRef.current) {\n          mindmapSvgRef.current.innerHTML = ''\n        }\n\n        const { Transformer, Markmap } = window.markmap\n        const transformerInstance = new Transformer()\n        setTransformer(transformerInstance)\n\n        if (mindmapSvgRef.current) {\n          const mmInstance = Markmap.create(mindmapSvgRef.current, {\n            duration: 500,\n            nodeMinHeight: 20,\n            spacingVertical: 8,\n            spacingHorizontal: 100,\n            autoFit: true,\n            fitRatio: 0.95,\n            color: getNodeColor,\n            // 添加额外的样式配置确保一致性\n            maxWidth: 0,\n            nodeMin: 16,\n            paddingX: 8,\n          })\n          setMm(mmInstance)\n        }\n\n        loadConfig()\n        loadPrompt()\n\n        // 只在第一次加载时设置默认 markdown\n        const defaultMarkdown = t('aimarkmap.defaultMarkdown')\n        setCurrentMarkdown(defaultMarkdown)\n\n        isInitializedRef.current = true\n\n        if (apiUrl && apiKey) {\n          queryAvailableModels(true)\n        }\n      } catch (error) {\n        console.error('初始化失败:', error)\n        message.error('初始化失败，请刷新页面重试')\n      }\n    }\n\n    initLibraries()\n\n    document.addEventListener('fullscreenchange', handleFullScreenChange)\n    document.addEventListener('webkitfullscreenchange', handleFullScreenChange)\n    document.addEventListener('mozfullscreenchange', handleFullScreenChange)\n    document.addEventListener('MSFullscreenChange', handleFullScreenChange)\n    document.addEventListener('click', handleDocumentClick)\n    document.addEventListener('keydown', handleKeyDown)\n\n    return () => {\n      document.removeEventListener('fullscreenchange', handleFullScreenChange)\n      document.removeEventListener('webkitfullscreenchange', handleFullScreenChange)\n      document.removeEventListener('mozfullscreenchange', handleFullScreenChange)\n      document.removeEventListener('MSFullscreenChange', handleFullScreenChange)\n      document.removeEventListener('click', handleDocumentClick)\n      document.removeEventListener('keydown', handleKeyDown)\n      if (timerIntervalRef.current) {\n        clearInterval(timerIntervalRef.current)\n      }\n    }\n  }, [])\n\n  // 更新 Mindmap 数据和视图\n  useEffect(() => {\n    if (mm && transformer) {\n      try {\n        const { root } = transformer.transform(currentMarkdown)\n        mm.setData(root)\n        // 立即调用 fit 确保样式和布局正确应用\n        setTimeout(() => mm.fit(), 50)\n      } catch (error) {\n        console.error('渲染Markmap失败:', error)\n      }\n    }\n  }, [currentMarkdown, mm, transformer])\n\n  // 保存配置到本地存储\n  useEffect(() => {\n    const config = {\n      apiUrl,\n      apiKey,\n      model: selectedModel,\n      customModel,\n      versionCount,\n    }\n    localStorage.setItem('ai-mindmap-config', JSON.stringify(config))\n  }, [apiUrl, apiKey, selectedModel, customModel, versionCount])\n\n  // 设置节点交互事件\n  useEffect(() => {\n    if (mm && window.d3) {\n      setupNodeInteraction()\n    }\n  }, [mm])\n\n  const loadConfig = () => {\n    try {\n      const configStr = localStorage.getItem('ai-mindmap-config')\n      const parsed = configStr ? JSON.parse(configStr) : {}\n\n      setApiUrl(parsed.apiUrl || '')\n      setApiKey(parsed.apiKey || '')\n\n      if (parsed.versionCount) {\n        setVersionCount(parseInt(parsed.versionCount))\n      }\n\n      const lastSuccessfulModel = localStorage.getItem(LAST_SUCCESSFUL_MODEL_KEY)\n      const modelToSet = lastSuccessfulModel || parsed.model || 'gpt-4o-mini'\n\n      if (['gpt-4o-mini', 'custom', ...availableModels].includes(modelToSet)) {\n        setSelectedModel(modelToSet)\n      } else {\n        setSelectedModel('custom')\n        setCustomModel(modelToSet)\n      }\n    } catch (e) {\n      console.error('解析本地配置失败', e)\n      localStorage.removeItem('ai-mindmap-config')\n    }\n  }\n\n  const loadPrompt = () => {\n    const savedPrompt = localStorage.getItem('ai-mindmap-prompt')\n    setAiPromptTemplate(savedPrompt || t('aimarkmap.defaultPrompt'))\n  }\n\n  const queryAvailableModels = async (isSilent = false) => {\n    if (!apiUrl || !apiKey) {\n      if (!isSilent) {\n        message.warning(t('aimarkmap.js_alert_query_no_config'))\n      }\n      return\n    }\n\n    try {\n      let modelsApiUrl\n\n      try {\n        const url = new URL(apiUrl)\n        let pathname = url.pathname.replace(/\\/chat\\/completions\\/?$/, '')\n        if (!pathname.endsWith('/models')) {\n          pathname = pathname.replace(/\\/$/, '') + '/models'\n        }\n        modelsApiUrl = url.origin + pathname\n      } catch (urlError) {\n        modelsApiUrl = apiUrl.replace(/\\/chat\\/completions$/, '/models')\n        if (!modelsApiUrl.endsWith('/models')) {\n          const baseUrlMatch = apiUrl.match(/^(https?:\\/\\/[^\\/]+(?:\\/[^\\/]+)*?\\/v\\d+)/)\n          if (baseUrlMatch) {\n            modelsApiUrl = `${baseUrlMatch[1]}/models`\n          } else {\n            throw new Error('无法从API地址推断出/models路径，请检查API地址格式。')\n          }\n        }\n      }\n\n      const response = await fetch(modelsApiUrl, {\n        method: 'GET',\n        headers: {\n          'Authorization': `Bearer ${apiKey}`,\n          'Content-Type': 'application/json'\n        },\n        mode: 'cors'\n      })\n\n      if (!response.ok) {\n        const errorText = await response.text()\n        throw new Error(`查询失败: ${response.status} - ${response.statusText}. 响应: ${errorText}`)\n      }\n\n      const data = await response.json()\n      const models = (data.data || data.models || []).map((m: any) => m.id || m.name || m).filter(Boolean)\n      if (models.length === 0) throw new Error('未找到可用模型')\n\n      setAvailableModels(models)\n\n      if (!models.includes(selectedModel === 'custom' ? customModel : selectedModel)) {\n        setSelectedModel('custom')\n      }\n\n      if (!isSilent) {\n        message.success(t('aimarkmap.js_alert_query_success', { n: models.length }))\n      }\n    } catch (error: any) {\n      console.error('查询模型失败:', error)\n      if (!isSilent) {\n        message.error(t('aimarkmap.js_alert_query_failed', { msg: error.message }))\n      }\n    }\n  }\n\n  const generateWithAI = async () => {\n    if (!searchValue) {\n      message.warning(t('aimarkmap.js_alert_no_content'))\n      return\n    }\n\n    setIsLoading(true)\n    setStatusMessage(t('aimarkmap.js_status_requesting'))\n    startTimer()\n\n    try {\n      const content = searchValue\n      const fetchPromises = []\n      const url = import.meta.env.VITE_OPENAI_BASE_URL + '/chat/completions'\n      const deepseekKey = import.meta.env.VITE_OPENAI_API_KEY || ''\n      for (let i = 0; i < versionCount; i++) {\n        fetchPromises.push(\n          fetch(url, {\n            method: 'POST',\n            headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${deepseekKey}` },\n            body: JSON.stringify({\n              model: 'deepseek-v3-2-251201',\n              messages: [{ role: 'user', content: aiPromptTemplate.replace('{{CONTENT}}', content) }],\n              max_tokens: 2000,\n              temperature: 0.6 + i * 0.15,\n            })\n          })\n        )\n      }\n\n      const responses = await Promise.allSettled(fetchPromises)\n      let successfulResults: AiResult[] = []\n\n      for (const result of responses) {\n        if (result.status === 'fulfilled') {\n          const response = result.value\n          if (response.ok) {\n            try {\n              const data = await response.json()\n              const markdownContent = data.choices?.[0]?.message?.content\n              if (markdownContent) {\n                const { root } = transformer.transform(markdownContent.trim())\n                successfulResults.push({ markdown: markdownContent.trim(), root })\n              }\n            } catch (e) {\n              console.error('解析AI响应失败:', e)\n            }\n          }\n        } else {\n          console.error('一个AI请求失败:', result.reason)\n        }\n        setStatusMessage(t('aimarkmap.js_status_generated', { s: successfulResults.length, n: versionCount }))\n      }\n\n      if (successfulResults.length > 0) {\n        localStorage.setItem(LAST_SUCCESSFUL_MODEL_KEY, 'deepseek-chat')\n        setAiResults(successfulResults)\n        setActiveResultIndex(0)\n        setCurrentMarkdown(successfulResults[0].markdown)\n        setCurrentViewMode('markdown')\n        message.success(t('aimarkmap.js_status_done', { n: successfulResults.length }))\n\n        // 移动端自动跳转到导图面板\n        if (window.innerWidth <= 768) {\n          setCurrentMobilePanel('mindmap')\n        }\n      } else {\n        throw new Error(t('aimarkmap.js_alert_all_failed'))\n      }\n    } catch (error: any) {\n      console.error('AI生成失败:', error)\n      message.error(t('aimarkmap.js_alert_gen_failed', { msg: error.message }))\n    } finally {\n      stopTimer()\n      setIsLoading(false)\n    }\n  }\n\n  const startTimer = () => {\n    startTimeRef.current = Date.now()\n    setTimerSeconds(0)\n    if (timerIntervalRef.current) {\n      clearInterval(timerIntervalRef.current)\n    }\n    timerIntervalRef.current = setInterval(() => {\n      const elapsedSeconds = (Date.now() - startTimeRef.current) / 1000\n      setTimerSeconds(parseFloat(elapsedSeconds.toFixed(1)))\n    }, 100)\n  }\n\n  const stopTimer = () => {\n    if (timerIntervalRef.current) {\n      clearInterval(timerIntervalRef.current)\n      timerIntervalRef.current = null\n    }\n  }\n\n  const clearContent = () => {\n    setSearchValue('')\n    setAiResults([])\n    setActiveResultIndex(-1)\n    setCurrentMarkdown(t('aimarkmap.defaultMarkdown'))\n    setCurrentViewMode('input')\n  }\n\n  const switchToResult = (index: number) => {\n    if (index < 0 || index >= aiResults.length) return\n\n    setActiveResultIndex(index)\n    setCurrentMarkdown(aiResults[index].markdown)\n  }\n\n  const handleDisplayEdit = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n    const newMarkdown = e.target.value\n    setCurrentMarkdown(newMarkdown)\n\n    if (activeResultIndex > -1 && aiResults[activeResultIndex]) {\n      const updatedResults = [...aiResults]\n      updatedResults[activeResultIndex].markdown = newMarkdown\n      try {\n        const { root } = transformer.transform(newMarkdown)\n        updatedResults[activeResultIndex].root = root\n      } catch (error) {\n        console.error('Error parsing edited markdown:', error)\n      }\n      setAiResults(updatedResults)\n    }\n  }\n\n  const handleTopicInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n    const text = e.target.value\n    setSearchValue(text)\n    if (text.trim().startsWith('#')) {\n      setAiResults([])\n      setActiveResultIndex(-1)\n      setCurrentMarkdown(text)\n    }\n  }\n\n  const toggleFullScreen = () => {\n    const mindmapPanel = document.querySelector('.mindmap-panel') as any\n    if (!mindmapPanel) return\n\n    const doc = document as any\n    const isFullScreen = doc.fullscreenElement || doc.webkitFullscreenElement || doc.mozFullScreenElement || doc.msFullscreenElement\n\n    if (!isFullScreen) {\n      if (mindmapPanel.requestFullscreen) {\n        mindmapPanel.requestFullscreen()\n      } else if (mindmapPanel.mozRequestFullScreen) {\n        mindmapPanel.mozRequestFullScreen()\n      } else if (mindmapPanel.webkitRequestFullscreen) {\n        mindmapPanel.webkitRequestFullscreen()\n      } else if (mindmapPanel.msRequestFullscreen) {\n        mindmapPanel.msRequestFullscreen()\n      }\n    } else {\n      if (doc.exitFullscreen) {\n        doc.exitFullscreen()\n      } else if (doc.mozCancelFullScreen) {\n        doc.mozCancelFullScreen()\n      } else if (doc.webkitExitFullscreen) {\n        doc.webkitExitFullscreen()\n      } else if (doc.msExitFullscreen) {\n        doc.msExitFullscreen()\n      }\n    }\n  }\n\n  const handleFullScreenChange = () => {\n    const doc = document as any\n    const isFullScreen = doc.fullscreenElement || doc.webkitFullscreenElement || doc.mozFullScreenElement || doc.msFullscreenElement\n    setIsFullscreen(!!isFullScreen)\n\n    if (mm) {\n      setTimeout(() => { mm.fit() }, 200)\n    }\n  }\n\n  const exportSVG = async () => {\n    if (!mindmapSvgRef.current || !mm) {\n      message.warning(t('aimarkmap.js_alert_no_mindmap'))\n      return\n    }\n\n    try {\n      // 等待 markmap 完成渲染和适配\n      mm.fit()\n      await new Promise(resolve => setTimeout(resolve, 500))\n\n      const svgData = createExportableSvg(mindmapSvgRef.current)\n\n      if (!svgData) {\n        throw new Error(t('aimarkmap.js_alert_no_mindmap'))\n      }\n\n      const svgBlob = new Blob([svgData.svgString], { type: 'image/svg+xml;charset=utf-8' })\n      downloadBlob(svgBlob, generateExportFileName(currentMarkdown, 'svg'))\n    } catch (error) {\n      console.error('导出SVG失败:', error)\n      message.error(t('aimarkmap.js_alert_export_error', { type: 'SVG' }))\n    }\n  }\n\n  const exportPNG = async () => {\n    if (!mindmapSvgRef.current || !mm) {\n      message.warning(t('aimarkmap.js_alert_no_mindmap'))\n      return\n    }\n\n    try {\n      // 等待 markmap 完成渲染和适配\n      mm.fit()\n      await new Promise(resolve => setTimeout(resolve, 500))\n\n      const svgData = createExportableSvg(mindmapSvgRef.current)\n\n      if (!svgData) {\n        throw new Error(t('aimarkmap.js_alert_no_mindmap'))\n      }\n\n      // 提高缩放比例以获得更清晰的图片\n      const scale = 5\n      const margin = 20\n      const canvas = document.createElement('canvas')\n      canvas.width = (svgData.width + margin * 2) * scale\n      canvas.height = (svgData.height + margin * 2) * scale\n\n      const ctx = canvas.getContext('2d')\n      if (!ctx) throw new Error('无法获取Canvas上下文')\n\n      // 启用高质量图像平滑\n      ctx.imageSmoothingEnabled = true\n      ctx.imageSmoothingQuality = 'high'\n\n      // 填充白色背景\n      ctx.fillStyle = 'white'\n      ctx.fillRect(0, 0, canvas.width, canvas.height)\n\n      const dataUrl = 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svgData.svgString)))\n\n      const img = await new Promise<HTMLImageElement>((resolve, reject) => {\n        const image = new Image()\n        image.onload = () => resolve(image)\n        image.onerror = (err) => reject(new Error('Failed to load SVG as image. ' + err))\n        image.src = dataUrl\n      })\n\n      if (img.decode) await img.decode()\n\n      ctx.drawImage(img, margin * scale, margin * scale, svgData.width * scale, svgData.height * scale)\n\n      // 使用最高质量导出\n      const blob = await new Promise<Blob | null>(resolve =>\n        canvas.toBlob(resolve, 'image/png', 1.0)\n      )\n\n      if (blob) {\n        downloadBlob(blob, generateExportFileName(currentMarkdown, 'png'))\n      } else {\n        throw new Error('Canvas toBlob failed.')\n      }\n    } catch (error) {\n      console.error('导出PNG时发生意外错误:', error)\n      message.error(t('aimarkmap.js_alert_export_error', { type: 'PNG' }))\n    }\n  }\n\n  const openEditModal = (_originalText: string, lineIndex: number, prefix: string) => {\n    setEditingNodeContext({ lineIndex, prefix })\n    setEditModalVisible(true)\n  }\n\n  const closeEditModal = () => {\n    setEditingNodeContext(null)\n    setEditModalVisible(false)\n  }\n\n  const saveNodeEdit = (newText: string) => {\n    if (!editingNodeContext) return\n\n    const { lineIndex, prefix } = editingNodeContext\n    const newLine = prefix + newText\n\n    const lines = currentMarkdown.split('\\n')\n    if (lines[lineIndex] !== undefined) {\n      lines[lineIndex] = newLine\n      const updatedMarkdown = lines.join('\\n')\n      setCurrentMarkdown(updatedMarkdown)\n    }\n\n    if (activeResultIndex > -1 && aiResults[activeResultIndex]) {\n      const updatedResults = [...aiResults]\n      updatedResults[activeResultIndex].markdown = currentMarkdown\n      try {\n        const { root } = transformer.transform(currentMarkdown)\n        updatedResults[activeResultIndex].root = root\n      } catch (error) {\n        console.error('Error parsing edited markdown after node edit:', error)\n      }\n      setAiResults(updatedResults)\n    }\n\n    closeEditModal()\n  }\n\n  const deleteNode = (nodeToDelete: any) => {\n    if (!nodeToDelete) return\n\n    const linesToDelete = new Set<number>()\n    collectNodeLines(nodeToDelete, linesToDelete)\n\n    if (linesToDelete.size === 0) {\n      console.warn('Could not find line numbers for node deletion.', nodeToDelete)\n      return\n    }\n\n    const lines = currentMarkdown.split('\\n')\n    const newLines = lines.filter((_, i) => !linesToDelete.has(i))\n    const updatedMarkdown = newLines.join('\\n')\n    setCurrentMarkdown(updatedMarkdown)\n\n    if (activeResultIndex > -1 && aiResults[activeResultIndex]) {\n      const updatedResults = [...aiResults]\n      updatedResults[activeResultIndex].markdown = updatedMarkdown\n      try {\n        const { root } = transformer.transform(updatedMarkdown)\n        updatedResults[activeResultIndex].root = root\n      } catch (error) {\n        console.error('Error parsing markdown after node deletion:', error)\n      }\n      setAiResults(updatedResults)\n    }\n  }\n\n  const setupNodeInteraction = () => {\n    if (!mm || !window.d3) return\n\n    document.addEventListener('click', (e) => {\n      if (!(e.target as Element).closest('.context-menu')) {\n        removeContextMenu()\n      }\n    })\n\n    mm.svg.on('contextmenu.editor', (event: MouseEvent) => {\n      event.preventDefault()\n      event.stopPropagation()\n      removeContextMenu()\n\n      const node = (event.target as Element).closest('.markmap-node')\n      if (!node) return\n\n      const d = window.d3.select(node).datum()\n      if (!d?.data?.payload?.lines) return\n\n      createContextMenu(event, d, currentMarkdown, openEditModal, deleteNode)\n    })\n\n    // 设置 SVG 缩放行为\n    const svg = mm.svg\n\n    const zoom = window.d3.zoom()\n      .scaleExtent([0.3, 3])\n      .on('zoom', (event: any) => {\n        svg.select('g').attr('transform', event.transform)\n        // 更新缩放级别状态\n        setZoomLevel(event.transform.k)\n      })\n\n    svg.call(zoom as any)\n  }\n\n  const handleDocumentClick = (e: MouseEvent) => {\n    if (isMobileMenuOpen) {\n      const mobileMenu = document.getElementById('mobile-menu')\n      const hamburgerBtn = document.getElementById('hamburger-btn')\n      if (!mobileMenu?.contains(e.target as Node) && !hamburgerBtn?.contains(e.target as Node)) {\n        setIsMobileMenuOpen(false)\n      }\n    }\n  }\n\n  const handleKeyDown = (e: KeyboardEvent) => {\n    if (e.key === 'Escape') {\n      if (isLandscapeMode) {\n        e.preventDefault()\n        closeLandscapeMode()\n        return\n      }\n      if (editModalVisible) {\n        e.preventDefault()\n        closeEditModal()\n      } else {\n        removeContextMenu()\n      }\n      return\n    }\n\n    if (e.key === 'F11') {\n      e.preventDefault()\n      toggleFullScreen()\n    }\n\n    const activeEl = document.activeElement\n    const isEditing = activeEl && (activeEl.tagName === 'INPUT' || activeEl.tagName === 'TEXTAREA')\n\n    if (!isEditing && aiResults.length > 1) {\n      let newIndex\n      if (e.key === 'ArrowRight') {\n        e.preventDefault()\n        newIndex = (activeResultIndex + 1) % aiResults.length\n        switchToResult(newIndex)\n      } else if (e.key === 'ArrowLeft') {\n        e.preventDefault()\n        newIndex = (activeResultIndex - 1 + aiResults.length) % aiResults.length\n        switchToResult(newIndex)\n      }\n    }\n\n    if ((e.ctrlKey || e.metaKey) && !e.shiftKey && !e.altKey) {\n      if (e.key === 's') {\n        e.preventDefault()\n        exportPNG()\n      }\n    }\n  }\n\n  const toggleLandscapeMode = () => {\n    if (window.innerWidth > 768) return\n    if (currentMobilePanel !== 'mindmap') return\n\n    if (!isLandscapeMode) {\n      setIsLandscapeMode(true)\n      document.body.style.overflow = 'hidden'\n      setTimeout(() => {\n        centerLandscapeMindmap()\n      }, 100)\n    } else {\n      closeLandscapeMode()\n    }\n  }\n\n  const closeLandscapeMode = () => {\n    setIsLandscapeMode(false)\n    document.body.style.overflow = ''\n  }\n\n  const centerLandscapeMindmap = () => {\n    const svg = document.querySelector('#landscape-mindmap')\n    if (!svg) return\n\n    const g = svg.querySelector('g')\n    if (!g) return\n\n    const bbox = g.getBBox()\n    const containerWidth = svg.clientWidth\n    const containerHeight = svg.clientHeight\n\n    if (bbox.width === 0 || bbox.height === 0) return\n\n    const padding = 40\n    const scaleX = (containerWidth - padding * 2) / bbox.width\n    const scaleY = (containerHeight - padding * 2) / bbox.height\n    const scale = Math.min(scaleX, scaleY, 1.5)\n\n    const centerX = containerWidth / 2\n    const centerY = containerHeight / 2\n    const contentCenterX = bbox.x + bbox.width / 2\n    const contentCenterY = bbox.y + bbox.height / 2\n\n    const translateX = centerX - contentCenterX * scale\n    const translateY = centerY - contentCenterY * scale\n\n    g.setAttribute('transform', `translate(${translateX}, ${translateY}) scale(${scale})`)\n  }\n\n  const switchLandscapeVersion = (index: number) => {\n    if (index < 0 || index >= aiResults.length) return\n\n    setActiveResultIndex(index)\n    setCurrentMarkdown(aiResults[index].markdown)\n\n    setTimeout(() => {\n      const content = document.getElementById('landscape-content')\n      const originalSvg = document.querySelector('#mindmap')\n      if (originalSvg && content) {\n        const clonedSvg = originalSvg.cloneNode(true)\n        ;(clonedSvg as SVGElement).id = 'landscape-mindmap'\n        ;(clonedSvg as SVGElement).style.cssText = 'width:100%;height:100%;display:block;'\n        content.innerHTML = ''\n        content.appendChild(clonedSvg)\n        setTimeout(() => {\n          centerLandscapeMindmap()\n        }, 100)\n      }\n    }, 100)\n  }\n\n  const exportLandscapeSVG = async () => {\n    const landscapeSvg = document.querySelector('#landscape-mindmap') as SVGSVGElement\n    if (!landscapeSvg) {\n      message.warning(t('aimarkmap.js_alert_no_mindmap'))\n      return\n    }\n\n    try {\n      // 等待渲染完成\n      await new Promise(resolve => setTimeout(resolve, 300))\n\n      const svgData = createExportableSvg(landscapeSvg)\n      if (!svgData) {\n        throw new Error(t('aimarkmap.js_alert_no_mindmap'))\n      }\n\n      const svgBlob = new Blob([svgData.svgString], { type: 'image/svg+xml;charset=utf-8' })\n      downloadBlob(svgBlob, generateExportFileName(currentMarkdown, 'svg'))\n    } catch (error) {\n      console.error('横屏导出SVG失败:', error)\n      message.error(t('aimarkmap.js_alert_export_error', { type: 'SVG' }))\n    }\n  }\n\n  const exportLandscapePNG = async () => {\n    const landscapeSvg = document.querySelector('#landscape-mindmap') as SVGSVGElement\n    if (!landscapeSvg) {\n      message.warning(t('aimarkmap.js_alert_no_mindmap'))\n      return\n    }\n\n    try {\n      // 等待渲染完成\n      await new Promise(resolve => setTimeout(resolve, 300))\n\n      const svgData = createExportableSvg(landscapeSvg)\n      if (!svgData) {\n        throw new Error(t('aimarkmap.js_alert_no_mindmap'))\n      }\n\n      // 提高缩放比例以获得更清晰的图片\n      const scale = 5\n      const margin = 20\n      const canvas = document.createElement('canvas')\n      canvas.width = (svgData.width + margin * 2) * scale\n      canvas.height = (svgData.height + margin * 2) * scale\n\n      const ctx = canvas.getContext('2d')\n      if (!ctx) throw new Error('无法获取Canvas上下文')\n\n      // 启用高质量图像平滑\n      ctx.imageSmoothingEnabled = true\n      ctx.imageSmoothingQuality = 'high'\n\n      // 填充白色背景\n      ctx.fillStyle = 'white'\n      ctx.fillRect(0, 0, canvas.width, canvas.height)\n\n      const dataUrl = 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svgData.svgString)))\n\n      const img = await new Promise<HTMLImageElement>((resolve, reject) => {\n        const image = new Image()\n        image.onload = () => resolve(image)\n        image.onerror = (err) => reject(new Error('Failed to load SVG as image. ' + err))\n        image.src = dataUrl\n      })\n\n      if (img.decode) await img.decode()\n\n      ctx.drawImage(img, margin * scale, margin * scale, svgData.width * scale, svgData.height * scale)\n\n      // 使用最高质量导出\n      const blob = await new Promise<Blob | null>(resolve =>\n        canvas.toBlob(resolve, 'image/png', 1.0)\n      )\n\n      if (blob) {\n        downloadBlob(blob, generateExportFileName(currentMarkdown, 'png'))\n      } else {\n        throw new Error('Canvas toBlob failed.')\n      }\n    } catch (error) {\n      console.error('横屏导出PNG失败:', error)\n      message.error(t('aimarkmap.js_alert_export_error', { type: 'PNG' }))\n    }\n  }\n\n  const handleZoomIn = () => {\n    if (!mm || !window.d3) return\n    const svg = mm.svg\n    svg.transition().duration(300).call(\n      window.d3.zoom().scaleBy as any,\n      1.2\n    )\n  }\n\n  const handleZoomOut = () => {\n    if (!mm || !window.d3) return\n    const svg = mm.svg\n    svg.transition().duration(300).call(\n      window.d3.zoom().scaleBy as any,\n      0.8\n    )\n  }\n\n  const handleResetZoom = () => {\n    if (!mm || !window.d3) return\n    const svg = mm.svg\n    svg.transition().duration(300).call(\n      window.d3.zoom().transform as any,\n      window.d3.zoomIdentity\n    )\n    setTimeout(() => {\n      mm.fit()\n      setZoomLevel(1)\n    }, 300)\n  }\n\n  const handleSavePrompt = () => {\n    if (aiPromptTemplate) {\n      if (aiPromptTemplate.includes('{{CONTENT}}')) {\n        localStorage.setItem('ai-mindmap-prompt', aiPromptTemplate)\n      } else {\n        const newPrompt = aiPromptTemplate + '\\n\\n\"{{CONTENT}}\"'\n        setAiPromptTemplate(newPrompt)\n        localStorage.setItem('ai-mindmap-prompt', newPrompt)\n      }\n    } else {\n      localStorage.removeItem('ai-mindmap-prompt')\n      setAiPromptTemplate(t('aimarkmap.defaultPrompt'))\n    }\n    setPromptModalVisible(false)\n  }\n\n  return (\n    <div className='min-h-screen font-sans'>\n      <MobileMenu\n        isOpen={isMobileMenuOpen}\n        onClose={() => setIsMobileMenuOpen(false)}\n        onOpenInfo={() => setInfoModalVisible(true)}\n      />\n\n      <div className='flex h-[calc(100vh-3.5rem-3.5rem)] sm:h-[calc(100vh-4rem)] p-0 sm:p-4 gap-0 sm:gap-4 relative overflow-hidden'>\n        <EditorPanel\n          searchValue={searchValue}\n          currentMarkdown={currentMarkdown}\n          currentViewMode={currentViewMode}\n          versionCount={versionCount}\n          aiResults={aiResults}\n          onVersionCountChange={setVersionCount}\n          onGenerate={generateWithAI}\n          onClear={clearContent}\n          onSwitchView={setCurrentViewMode}\n          onTopicInput={handleTopicInput}\n          onDisplayEdit={handleDisplayEdit}\n          onOpenPromptModal={() => setPromptModalVisible(true)}\n          isLoading={isLoading}\n          currentMobilePanel={currentMobilePanel}\n        />\n\n        <MindmapPanel\n          mindmapContainerRef={mindmapContainerRef}\n          mindmapSvgRef={mindmapSvgRef}\n          isLoading={isLoading}\n          timerSeconds={timerSeconds}\n          statusMessage={statusMessage}\n          isFullscreen={isFullscreen}\n          aiResults={aiResults}\n          activeResultIndex={activeResultIndex}\n          zoomLevel={zoomLevel}\n          onToggleFullscreen={toggleFullScreen}\n          onExportSVG={exportSVG}\n          onExportPNG={exportPNG}\n          onSwitchVersion={switchToResult}\n          onZoomIn={handleZoomIn}\n          onZoomOut={handleZoomOut}\n          onResetZoom={handleResetZoom}\n          currentMobilePanel={currentMobilePanel}\n        />\n      </div>\n\n      <MobileTabBar\n        currentMobilePanel={currentMobilePanel}\n        onSwitchPanel={setCurrentMobilePanel}\n        onToggleLandscape={toggleLandscapeMode}\n      />\n\n      <LandscapeMode\n        isVisible={isLandscapeMode}\n        landscapeContentRef={landscapeContentRef}\n        aiResults={aiResults}\n        activeResultIndex={activeResultIndex}\n        onSwitchVersion={switchLandscapeVersion}\n        onExportSVG={exportLandscapeSVG}\n        onExportPNG={exportLandscapePNG}\n        onClose={closeLandscapeMode}\n      />\n\n      <PromptModal\n        visible={promptModalVisible}\n        promptTemplate={aiPromptTemplate}\n        onPromptChange={setAiPromptTemplate}\n        onSave={handleSavePrompt}\n        onCancel={() => setPromptModalVisible(false)}\n      />\n\n      <EditNodeModal\n        visible={editModalVisible}\n        defaultValue={editingNodeContext ? '' : ''}\n        onSave={saveNodeEdit}\n        onCancel={closeEditModal}\n      />\n\n      <InfoModal\n        visible={infoModalVisible}\n        onClose={() => setInfoModalVisible(false)}\n      />\n\n      <style>{`\n        /* 全局 markmap 样式 - 确保所有导图样式一致 */\n        .markmap {\n          font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n        }\n        .markmap text {\n          font-size: 14px !important;\n          font-weight: 500 !important;\n        }\n        .markmap g[data-depth=\"0\"] text {\n          font-size: 20px !important;\n          font-weight: 700 !important;\n        }\n        .markmap g[data-depth=\"1\"] text {\n          font-size: 16px !important;\n          font-weight: 600 !important;\n        }\n        .markmap g[data-depth=\"2\"] text {\n          font-size: 14px !important;\n          font-weight: 500 !important;\n        }\n        .markmap g[data-depth=\"3\"] text,\n        .markmap g[data-depth=\"4\"] text,\n        .markmap g[data-depth=\"5\"] text {\n          font-size: 13px !important;\n          font-weight: 400 !important;\n        }\n        /* 确保线条和形状颜色一致 */\n        .markmap path {\n          stroke-width: 1.5 !important;\n        }\n        .markmap circle {\n          stroke-width: 1.5 !important;\n        }\n\n        .context-menu {\n          position: absolute;\n          z-index: 3000;\n          background-color: #ffffff;\n          border: 1px solid #e0e0e0;\n          border-radius: 8px;\n          box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n          padding: 6px 0;\n          min-width: 150px;\n          font-size: 0.9rem;\n          list-style: none;\n          user-select: none;\n        }\n        .context-menu-item {\n          padding: 8px 16px;\n          cursor: pointer;\n          color: #333;\n          display: flex;\n          align-items: center;\n          gap: 8px;\n        }\n        .context-menu-item:hover {\n          background-color: #f5f5f5;\n        }\n        @media (max-width: 768px) {\n          .editor-panel,\n          .mindmap-panel {\n            transition: transform 0.3s ease, opacity 0.2s ease;\n          }\n        }\n      `}</style>\n    </div>\n  )\n}\n\nexport default Markmap\n"
  },
  {
    "path": "src/pages/Music.tsx",
    "content": "import React, { useState, useRef, useEffect } from 'react'\nimport { message } from 'antd'\nimport { CloseOutlined } from '@ant-design/icons'\nimport { useTranslation } from 'react-i18next'\nimport styled from 'styled-components'\nimport axios from 'axios'\n\nconst MusicContainer = styled.div`\n  min-height: calc(100vh - 120px);\n  padding: 20px;\n  position: relative;\n`\n\nconst PlayWrap = styled.div`\n  width: 100%;\n  max-width: 1000px;\n  height: 600px;\n  margin: 0 auto;\n  position: relative;\n  background: rgba(255, 255, 255, 0.1);\n  border-radius: 8px;\n  overflow: hidden;\n`\n\nconst SearchBar = styled.div`\n  height: 60px;\n  background-color: #1eacda;\n  border-top-left-radius: 4px;\n  border-top-right-radius: 4px;\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 0 23px;\n  position: relative;\n  z-index: 11;\n\n  .title {\n    font-size: 20px;\n    font-weight: 600;\n    color: #fff;\n  }\n\n  .logo {\n    width: 50px;\n    height: 50px;\n    border-radius: 50%;\n  }\n\n  input {\n    width: 100%;\n    max-width: 200px;\n    height: 34px;\n    border-radius: 17px;\n    border: 0px;\n    background: rgba(255, 255, 255, 0.45) url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path fill=\"%23333\" d=\"M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z\"/></svg>') right 10px center no-repeat;\n    padding-right: 35px;\n    text-indent: 15px;\n    outline: none;\n    color: #333;\n    font-size: 14px;\n\n    &::placeholder {\n      color: rgba(0, 0, 0, 0.4);\n    }\n\n    &:focus {\n      background-color: rgba(255, 255, 255, 0.6);\n    }\n  }\n`\n\nconst CenterCon = styled.div`\n  height: 490px;\n  background-color: rgba(255, 255, 255, 0.5);\n  display: flex;\n  justify-content: center;\n  position: relative;\n`\n\nconst SongWrapper = styled.div<{ show: boolean }>`\n  width: 200px;\n  height: 490px;\n  box-sizing: border-box;\n  padding: 10px;\n  z-index: 1;\n  display: ${props => props.show ? 'block' : 'none'};\n`\n\nconst SongList = styled.ul`\n  width: 100%;\n  overflow-y: auto;\n  overflow-x: hidden;\n  height: 100%;\n  list-style: none;\n  padding: 0;\n  margin: 0;\n\n  &::-webkit-scrollbar {\n    display: none;\n  }\n\n  li {\n    font-size: 12px;\n    color: #333;\n    height: 40px;\n    display: flex;\n    flex-wrap: wrap;\n    align-items: center;\n    width: 180px;\n    padding-left: 10px;\n    cursor: pointer;\n    transition: all 0.3s ease;\n\n    &:nth-child(odd) {\n      background-color: rgba(240, 240, 240, 0.3);\n    }\n\n    &:hover {\n      background-color: rgba(30, 172, 218, 0.3);\n    }\n\n    .play-icon {\n      display: block;\n      width: 17px;\n      height: 17px;\n      margin-right: 5px;\n      position: relative;\n\n      &.playing {\n        &::before {\n          content: '';\n          position: absolute;\n          left: 3px;\n          top: 4px;\n          width: 4px;\n          height: 8px;\n          background: #1eacda;\n          border-radius: 2px;\n          animation: pulse 1s ease-in-out infinite;\n        }\n\n        &::after {\n          content: '';\n          position: absolute;\n          left: 10px;\n          top: 4px;\n          width: 4px;\n          height: 8px;\n          background: #1eacda;\n          border-radius: 2px;\n          animation: pulse 1s ease-in-out infinite 0.2s;\n        }\n      }\n\n      &:not(.playing)::after {\n        content: '';\n        position: absolute;\n        left: 6px;\n        top: 5px;\n        width: 0;\n        height: 0;\n        border-left: 5px solid #1eacda;\n        border-top: 3px solid transparent;\n        border-bottom: 3px solid transparent;\n      }\n    }\n\n    b {\n      font-weight: normal;\n      width: 122px;\n      overflow: hidden;\n      text-overflow: ellipsis;\n      white-space: nowrap;\n      color: #333;\n      font-size: 12px;\n\n      &.active {\n        color: #1eacda;\n        font-weight: 600;\n        font-size: 15px;\n      }\n    }\n\n    span {\n      margin-left: auto;\n\n      i {\n        display: block;\n        width: 23px;\n        height: 17px;\n        cursor: pointer;\n        background: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><path fill=\"%23333\" d=\"M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z\"/><path d=\"M6.271 5.055a.5.5 0 0 1 .52.038l3.5 2.5a.5.5 0 0 1 0 .864l-3.5 2.5A.5.5 0 0 1 6 10.5v-5a.5.5 0 0 1 .271-.445z\"/></svg>') center no-repeat;\n        background-size: contain;\n      }\n    }\n  }\n\n  @keyframes pulse {\n    0%, 100% { opacity: 1; }\n    50% { opacity: 0.5; }\n  }\n`\n\nconst CommentWrapper = styled.div`\n  height: 490px;\n  flex: 1;\n  padding: 25px 10px;\n  box-sizing: border-box;\n  overflow: hidden;\n\n  .title {\n    font-size: 14px;\n    font-weight: 600;\n    color: #333;\n    white-space: nowrap;\n  }\n\n  .comment-list {\n    overflow: auto;\n    height: 460px;\n    margin-top: 30px;\n\n    &::-webkit-scrollbar {\n      width: 4px;\n    }\n\n    &::-webkit-scrollbar-thumb {\n      background: rgba(0, 0, 0, 0.2);\n      border-radius: 2px;\n    }\n  }\n\n  dl {\n    padding-top: 10px;\n    padding-left: 55px;\n    position: relative;\n    margin-bottom: 20px;\n  }\n\n  dt {\n    position: absolute;\n    left: 4px;\n    top: 10px;\n\n    img {\n      width: 40px;\n      height: 40px;\n      border-radius: 20px;\n    }\n  }\n\n  dd {\n    font-size: 12px;\n\n    &.name {\n      font-weight: bold;\n      color: #333;\n      padding-top: 5px;\n    }\n\n    &.detail {\n      color: #666;\n      margin-top: 5px;\n      line-height: 18px;\n    }\n  }\n`\n\nconst AudioCon = styled.div`\n  height: 50px;\n  background-color: #f1f3f4;\n  border-bottom-left-radius: 4px;\n  border-bottom-right-radius: 4px;\n  display: flex;\n  align-items: center;\n  padding: 0 20px;\n\n  audio {\n    width: 100%;\n    height: 40px;\n    outline: none;\n  }\n`\n\nconst VideoCon = styled.div<{ show: boolean }>`\n  position: fixed;\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  z-index: 999;\n  display: ${props => props.show ? 'block' : 'none'};\n\n  video {\n    position: fixed;\n    width: 800px;\n    height: 600px;\n    left: 50%;\n    top: 50%;\n    margin-top: -300px;\n    margin-left: -400px;\n    z-index: 990;\n  }\n\n  .mask {\n    position: fixed;\n    width: 100%;\n    height: 100%;\n    left: 0;\n    top: 0;\n    z-index: 980;\n    background-color: rgba(0, 0, 0, 0.8);\n    cursor: pointer;\n  }\n\n  .close-btn {\n    position: fixed;\n    width: 40px;\n    height: 40px;\n    left: 50%;\n    margin-left: 400px;\n    margin-top: -300px;\n    top: 50%;\n    z-index: 995;\n    cursor: pointer;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    background: rgba(255, 255, 255, 0.9);\n    border-radius: 50%;\n  }\n`\n\nconst LoadingCon = styled.div<{ show: boolean }>`\n  width: 400px;\n  height: 490px;\n  display: ${props => props.show ? 'flex' : 'none'};\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  z-index: 20;\n\n  .loading-disc {\n    width: 200px;\n    height: 200px;\n    border-radius: 50%;\n    background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);\n    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.4);\n    animation: rotate 2s linear infinite;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    position: relative;\n\n    &::before {\n      content: '';\n      position: absolute;\n      width: 100%;\n      height: 100%;\n      border-radius: 50%;\n      background: repeating-radial-gradient(\n        circle at center,\n        transparent 0,\n        transparent 2px,\n        rgba(255, 255, 255, 0.03) 2px,\n        rgba(255, 255, 255, 0.03) 4px\n      );\n    }\n\n    &::after {\n      content: '🎵';\n      font-size: 48px;\n    }\n  }\n\n  .loading-text {\n    padding: 0 20px;\n    margin-top: 30px;\n    text-align: center;\n    color: #333;\n    font-size: 16px;\n    animation: pulse 1.5s ease-in-out infinite;\n  }\n\n  @keyframes rotate {\n    from {\n      transform: rotate(0deg);\n    }\n    to {\n      transform: rotate(360deg);\n    }\n  }\n\n  @keyframes pulse {\n    0%, 100% {\n      opacity: 0.4;\n    }\n    50% {\n      opacity: 1;\n    }\n  }\n`\n\ninterface SearchResult {\n  id: number\n  name: string\n  artists: Array<{ name: string }>\n  album: { name: string; picUrl: string }\n  duration: number\n  mvid: number\n}\n\ninterface Comment {\n  user: {\n    nickname: string\n    avatarUrl: string\n  }\n  content: string\n}\n\nconst Music: React.FC = () => {\n  const { t } = useTranslation()\n  const [query, setQuery] = useState('')\n  const [musicList, setMusicList] = useState<SearchResult[]>([])\n  const [musicUrl, setMusicUrl] = useState('')\n  const [hotComments, setHotComments] = useState<Comment[]>([])\n  const [isPlaying, setIsPlaying] = useState(false)\n  const [showMV, setShowMV] = useState(false)\n  const [mvUrl, setMvUrl] = useState('')\n  const [currentId, setCurrentId] = useState<number | null>(null)\n  const [loading, setLoading] = useState(false)\n  const [hasMusic, setHasMusic] = useState(false)\n  const [screenWidth, setScreenWidth] = useState(typeof window !== 'undefined' ? window.innerWidth : 1000)\n  const audioRef = useRef<HTMLAudioElement>(null)\n\n  // 监听屏幕尺寸变化\n  useEffect(() => {\n    const handleResize = () => {\n      setScreenWidth(window.innerWidth)\n    }\n\n    window.addEventListener('resize', handleResize)\n    return () => {\n      window.removeEventListener('resize', handleResize)\n    }\n  }, [])\n\n  // 搜索歌曲\n  const searchMusic = async () => {\n    if (!query.trim()) {\n      message.warning(t('music.noKeywordTip'))\n      return\n    }\n\n    try {\n      const response = await axios.get(\n        `/api/netease/search?keywords=${encodeURIComponent(query)}`\n      )\n\n      if (response.data?.result?.songs) {\n        setMusicList(response.data.result.songs)\n      } else {\n        message.info(t('music.noResults'))\n      }\n    } catch (error) {\n      message.error(t('music.searchFailed'))\n    }\n  }\n\n  // 获取音乐URL\n  const fetchMusicUrl = async (musicId: number) => {\n    try {\n      const levels = ['standard', 'higher', 'exhigh']\n\n      for (const level of levels) {\n        try {\n          const response = await axios.get(\n            `/api/netease/song/url/v1?id=${musicId}&level=${level}`\n          )\n\n          if (response.data?.data?.[0]?.url) {\n            const url = response.data.data[0].url\n            if (url && url.length > 10 && !url.includes('404')) {\n              return url\n            }\n          }\n        } catch (err) {\n          continue\n        }\n      }\n\n      return null\n    } catch (error) {\n      return null\n    }\n  }\n\n  // 获取热门评论\n  const fetchHotComments = async (musicId: number) => {\n    try {\n      const response = await axios.get(`/api/netease/comment/hot?type=0&id=${musicId}`)\n      if (response.data?.hotComments) {\n        return response.data.hotComments\n      }\n      return []\n    } catch (error) {\n      return []\n    }\n  }\n\n  // 播放音乐\n  const playMusic = async (musicId: number) => {\n    setCurrentId(musicId)\n    setLoading(true)\n    setHasMusic(false)\n\n    // 获取音乐URL\n    const url = await fetchMusicUrl(musicId)\n    if (!url) {\n      message.error(t('music.fetchMusicFailed'))\n      setLoading(false)\n      return\n    }\n\n    // 获取评论\n    const comments = await fetchHotComments(musicId)\n    setHotComments(comments)\n\n    setMusicUrl(url)\n    setHasMusic(true)\n    setLoading(false)\n\n    // 播放\n    setTimeout(() => {\n      if (audioRef.current) {\n        audioRef.current.src = url\n        audioRef.current.play()\n      }\n    }, 100)\n  }\n\n  // 播放MV\n  const playMV = async (mvid: number) => {\n    try {\n      const response = await axios.get(`/api/netease/mv/url?id=${mvid}`)\n      if (response.data?.data?.url) {\n        setMvUrl(response.data.data.url)\n        setShowMV(true)\n      } else {\n        message.warning(t('music.mvNotAvailable'))\n      }\n    } catch (error) {\n      message.error(t('music.fetchMVFailed'))\n    }\n  }\n\n  return (\n    <MusicContainer>\n      <PlayWrap>\n        <SearchBar>\n          <div className=\"title\">{t('music.subTitle')}</div>\n          <input\n            type=\"text\"\n            value={query}\n            onChange={(e) => setQuery(e.target.value)}\n            placeholder={t('music.placeholder')}\n            onKeyDown={(e) => e.key === 'Enter' && searchMusic()}\n          />\n        </SearchBar>\n\n        <CenterCon>\n          <SongWrapper show={musicList.length > 0}>\n            <SongList>\n              {musicList.map((item) => (\n                <li\n                  key={item.id}\n                  onClick={() => playMusic(item.id)}\n                >\n                  <span className={`play-icon ${currentId === item.id && isPlaying ? 'playing' : ''}`} />\n                  <b className={currentId === item.id ? 'active' : ''}>\n                    {item.name}\n                  </b>\n                  {item.mvid > 0 && (\n                    <span onClick={(e) => { e.stopPropagation(); playMV(item.mvid) }}>\n                      <i />\n                    </span>\n                  )}\n                </li>\n              ))}\n            </SongList>\n          </SongWrapper>\n\n          <LoadingCon show={((loading && !hasMusic) || (musicList.length >= 0 && hotComments.length === 0)) && (screenWidth >= 500 || musicList.length === 0)}>\n            <div className=\"loading-disc\" />\n            <div className=\"loading-text\">{t('music.description')}</div>\n          </LoadingCon>\n\n          {hasMusic && screenWidth >= 500 && (\n            <CommentWrapper>\n              <div className=\"title\">{t('music.hotComments')}</div>\n              <div className=\"comment-list\">\n                {hotComments.map((comment, index) => (\n                  <dl key={index}>\n                    <dt>\n                      <img src={comment.user.avatarUrl} alt=\"\" />\n                    </dt>\n                    <dd className=\"name\">{comment.user.nickname}</dd>\n                    <dd className=\"detail\">{comment.content}</dd>\n                  </dl>\n                ))}\n              </div>\n            </CommentWrapper>\n          )}\n        </CenterCon>\n\n        <AudioCon>\n          <audio\n            ref={audioRef}\n            src={musicUrl}\n            controls\n            autoPlay\n            loop\n            onPlay={() => setIsPlaying(true)}\n            onPause={() => setIsPlaying(false)}\n          />\n        </AudioCon>\n      </PlayWrap>\n\n      <VideoCon show={showMV}>\n        <video src={mvUrl} controls autoPlay />\n        <div className=\"mask\" onClick={() => setShowMV(false)} />\n        <div className=\"close-btn\" onClick={() => setShowMV(false)}>\n          <CloseOutlined />\n        </div>\n      </VideoCon>\n    </MusicContainer>\n  )\n}\n\nexport default Music\n"
  },
  {
    "path": "src/pages/NotFound.tsx",
    "content": "import React from 'react'\nimport { Button, Typography } from 'antd'\nimport { HomeOutlined, ArrowLeftOutlined } from '@ant-design/icons'\nimport { useNavigate } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport styled from 'styled-components'\n\nconst { Title, Paragraph } = Typography\n\nconst NotFoundContainer = styled.div`\n  min-height: calc(100vh - 200px);\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);\n  padding: 40px 20px;\n  position: relative;\n  overflow: hidden;\n\n  /* 背景动画 */\n  &::before {\n    content: '';\n    position: absolute;\n    top: -50%;\n    left: -50%;\n    width: 200%;\n    height: 200%;\n    background: radial-gradient(circle, rgba(102, 126, 234, 0.1) 2px, transparent 2px);\n    background-size: 50px 50px;\n    animation: moveBackground 30s linear infinite;\n  }\n\n  @keyframes moveBackground {\n    0% { transform: rotate(0deg); }\n    100% { transform: rotate(360deg); }\n  }\n`\n\nconst NotFoundCard = styled.div`\n  text-align: center;\n  padding: 60px 40px;\n  background: rgba(255, 255, 255, 0.95);\n  backdrop-filter: blur(10px);\n  border-radius: 24px;\n  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.1);\n  position: relative;\n  z-index: 1;\n  animation: cardAppear 0.6s cubic-bezier(0.16, 1, 0.3, 1);\n\n  @keyframes cardAppear {\n    from {\n      opacity: 0;\n      transform: translateY(30px) scale(0.9);\n    }\n    to {\n      opacity: 1;\n      transform: translateY(0) scale(1);\n    }\n  }\n\n  @media (max-width: 768px) {\n    padding: 40px 24px;\n    border-radius: 20px;\n  }\n`\n\nconst ErrorCode = styled.div`\n  font-size: 12rem;\n  font-weight: 900;\n  background: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%);\n  -webkit-background-clip: text;\n  -webkit-text-fill-color: transparent;\n  background-clip: text;\n  line-height: 1;\n  margin-bottom: 20px;\n  position: relative;\n  animation: numberFloat 3s ease-in-out infinite;\n\n  @keyframes numberFloat {\n    0%, 100% {\n      transform: translateY(0) scale(1);\n    }\n    50% {\n      transform: translateY(-10px) scale(1.02);\n    }\n  }\n\n  &::after {\n    content: '404';\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n    -webkit-background-clip: text;\n    -webkit-text-fill-color: transparent;\n    background-clip: text;\n    filter: blur(20px);\n    opacity: 0.3;\n    z-index: -1;\n    animation: numberPulse 3s ease-in-out infinite;\n  }\n\n  @keyframes numberPulse {\n    0%, 100% {\n      transform: scale(1);\n      opacity: 0.3;\n    }\n    50% {\n      transform: scale(1.05);\n      opacity: 0.5;\n    }\n  }\n\n  @media (max-width: 768px) {\n    font-size: 8rem;\n  }\n\n  @media (max-width: 480px) {\n    font-size: 6rem;\n  }\n`\n\nconst GhostIcon = styled.div`\n  font-size: 4rem;\n  margin-bottom: 20px;\n  animation: ghostFloat 3s ease-in-out infinite;\n\n  @keyframes ghostFloat {\n    0%, 100% {\n      transform: translateY(0) rotate(0deg);\n    }\n    25% {\n      transform: translateY(-10px) rotate(-5deg);\n    }\n    75% {\n      transform: translateY(-10px) rotate(5deg);\n    }\n  }\n\n  @media (max-width: 768px) {\n    font-size: 3rem;\n  }\n`\n\nconst ActionButtons = styled.div`\n  display: flex;\n  gap: 16px;\n  justify-content: center;\n  margin-top: 40px;\n  flex-wrap: wrap;\n\n  .ant-btn {\n    height: 48px;\n    padding: 0 32px;\n    font-size: 1rem;\n    border-radius: 24px;\n    font-weight: 500;\n    transition: all 0.3s ease;\n\n    &:hover {\n      transform: translateY(-2px);\n      box-shadow: 0 8px 20px rgba(102, 126, 234, 0.3);\n    }\n\n    &:active {\n      transform: translateY(0);\n    }\n  }\n\n  @media (max-width: 768px) {\n    flex-direction: column;\n    gap: 12px;\n\n    .ant-btn {\n      width: 100%;\n    }\n  }\n`\n\nconst NotFound: React.FC = () => {\n  const { t } = useTranslation()\n  const navigate = useNavigate()\n\n  return (\n    <NotFoundContainer>\n      <NotFoundCard>\n        <GhostIcon>👻</GhostIcon>\n        <ErrorCode>404</ErrorCode>\n        <Title level={2} style={{\n          marginBottom: '16px',\n          fontSize: '2rem',\n          background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\n          WebkitBackgroundClip: 'text',\n          WebkitTextFillColor: 'transparent',\n          backgroundClip: 'text'\n        }}>\n          {t('notFound.title')}\n        </Title>\n        <Paragraph style={{\n          fontSize: '1.1rem',\n          color: '#64748b',\n          marginBottom: '32px',\n          maxWidth: '400px',\n          margin: '0 auto 32px'\n        }}>\n          {t('notFound.description')}\n        </Paragraph>\n\n        <ActionButtons>\n          <Button\n            type=\"primary\"\n            icon={<HomeOutlined />}\n            onClick={() => navigate('/home')}\n            style={{\n              background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\n              border: 'none'\n            }}\n          >\n            {t('notFound.backHomeBtn')}\n          </Button>\n          <Button\n            icon={<ArrowLeftOutlined />}\n            onClick={() => navigate(-1)}\n          >\n            {t('common.back')}\n          </Button>\n        </ActionButtons>\n      </NotFoundCard>\n    </NotFoundContainer>\n  )\n}\n\nexport default NotFound\n"
  },
  {
    "path": "src/pages/PaperListPage.tsx",
    "content": "import React, { useState, useEffect } from 'react'\nimport { useNavigate } from 'react-router-dom'\nimport { Card, Input, Button, Radio, RadioChangeEvent, Avatar, Tag, Skeleton, Tooltip, Badge, Dropdown, Image, Modal } from 'antd'\nimport { \n  SearchOutlined, \n  GithubOutlined, \n  LinkOutlined, \n  CalendarOutlined, \n  MessageOutlined,\n  FireOutlined,\n  DatabaseOutlined,\n  CodeOutlined,\n  DownOutlined,\n  DownloadOutlined,\n  ProjectOutlined,\n  PaperClipOutlined,\n  FilePdfOutlined,\n  OpenAIOutlined,\n} from '@ant-design/icons'\nimport { \n  getAuthorNames, \n  getAuthorDataName, \n  getOrganizationName, \n  formatNumber, \n  formatParamCount, \n  getTaskTag, \n  getHardwareTag \n} from '@/utils/paper'\nimport { useTranslation } from 'react-i18next'\nimport { isMobileDevice } from '@/utils/isMobile'\nimport axios from 'axios'\ninterface AuthorData {\n  _id: string;\n  avatarUrl?: string;\n  fullname: string;\n  name: string;\n  type: string;\n  isPro?: boolean;\n  isHf?: boolean;\n  isHfAdmin?: boolean;\n  isMod?: boolean;\n  plan?: string;\n  followerCount: number;\n  isUserFollowing: boolean;\n}\n\ninterface InferenceProvider {\n  provider: string;\n  modelStatus: string;\n  providerStatus: string;\n  providerId: string;\n  task: string;\n  adapterWeightsPath?: string;\n  features?: {\n    structuredOutput?: boolean;\n    toolCalling?: boolean;\n  };\n  isCheapestPricingOutput?: boolean;\n  isFastestThroughput?: boolean;\n  isModelAuthor?: boolean;\n  tokensPerSecond?: number;\n  pricingOutput?: number;\n}\n\ninterface ModelData {\n  author: string;\n  authorData?: AuthorData;\n  downloads: number;\n  gated: boolean;\n  id: string;\n  availableInferenceProviders?: InferenceProvider[];\n  isLikedByUser: boolean;\n  lastModified: string;\n  likes: number;\n  pipeline_tag?: string;\n  private: boolean;\n  repoType: 'model';\n  widgetOutputUrls?: any[];\n  numParameters?: number;\n}\n\ninterface DatasetData {\n  author: string;\n  downloads: number;\n  gated: boolean;\n  id: string;\n  isLikedByUser: boolean;\n  lastModified: string;\n  likes: number;\n  private: boolean;\n  repoType: 'dataset';\n  datasetsServerInfo?: {\n    viewer: string;\n    numRows: number;\n    libraries: string[];\n    formats: string[];\n    modalities: string[];\n  };\n  isBenchmark?: boolean;\n}\n\ninterface SpaceData {\n  author: string;\n  authorData?: AuthorData;\n  colorFrom: string;\n  colorTo: string;\n  createdAt: string;\n  emoji: string;\n  id: string;\n  isLikedByUser: boolean;\n  lastModified: string;\n  likes: number;\n  pinned: boolean;\n  private: boolean;\n  repoType: 'space';\n  runtime?: {\n    stage: string;\n    hardware: {\n      current: string;\n      requested: string;\n    };\n    storage: string | null;\n    gcTimeout: number;\n    replicas: {\n      current: number;\n      requested: number | string;\n    };\n    devMode: boolean;\n    domains: Array<{\n      domain: string;\n      stage: string;\n    }>;\n    sha: string;\n  };\n  shortDescription?: string;\n  title: string;\n  ai_short_description?: string;\n  ai_category?: string;\n  tags?: string[];\n  featured?: boolean;\n  originRepo?: {\n    name: string;\n    author: {\n      _id: string;\n      avatarUrl: string;\n      fullname: string;\n      name: string;\n      type: string;\n    };\n  };\n}\n\ninterface RepoData {\n  recentlyTrending: Array<{\n    repoData: ModelData | DatasetData | SpaceData;\n    repoType: 'model' | 'dataset' | 'space';\n  }>;\n}\n\ninterface PaperDetail {\n  id: string;\n  authors: Array<{ name: string; _id: string }>;\n  publishedAt: string;\n  title: string;\n  summary: string;\n  upvotes: number;\n  discussionId: string;\n  ai_summary?: string;\n  ai_keywords?: string[];\n  githubRepo?: string;\n  githubStars?: number;\n  projectPage?: string;\n  mediaUrls?: string[];\n  thumbnail?: string;\n  authorData?: AuthorData;\n  pipeline_tag?: string;\n  downloads?: number;\n  numParameters?: number;\n  lastModified: string;\n  repoType: 'model' | 'dataset' | 'space' | 'paper';\n  shortDescription?: string;\n  ai_category?: string;\n  datasetsServerInfo?: {\n    numRows: number;\n    modalities: string[];\n  };\n  runtime?: SpaceData['runtime'];\n  isSpace?: boolean;\n  numComments?: number;\n  submittedBy?: AuthorData;\n  organization?: {\n    _id: string;\n    name: string;\n    fullname: string;\n    avatar?: string;\n  };\n}\n\nconst PaperListPage: React.FC = () => {\n  const { t } = useTranslation()\n  const navigate = useNavigate()\n  const [activeTab, setActiveTab] = useState<string>('daily');\n  const [searchQuery, setSearchQuery] = useState<string>('');\n  const [papers, setPapers] = useState<PaperDetail[]>([]);\n  const [loading, setLoading] = useState<boolean>(true);\n  const [fetchError, setFetchError] = useState<string | null>(null);\n  const [repoTypeFilter, setRepoTypeFilter] = useState<string>('all');\n  \n  // 添加PDF弹窗相关的状态\n  const [pdfModalVisible, setPdfModalVisible] = useState<boolean>(false);\n  const [currentPdfUrl, setCurrentPdfUrl] = useState<string>('');\n  const [currentPaperTitle, setCurrentPaperTitle] = useState<string>('');\n\n  const API_PAPERS_URL = import.meta.env.VITE_PAPERS_API_URL || ''\n\n  // 获取每日论文数据\n  const fetchDailyPapers = async () => {\n    try {\n      // 添加时间戳和缓存控制头，确保获取最新数据\n      const timestamp = Date.now()\n      const response = await axios.get(`${API_PAPERS_URL}/daily_papers`, {\n        headers: {\n          'Cache-Control': 'no-cache',\n          'Pragma': 'no-cache'\n        },\n        params: {\n          _t: timestamp\n        }\n      })\n      \n      if (response.data && Array.isArray(response.data)) {\n        const formattedPapers: PaperDetail[] = response.data.map((item: any) => ({\n          id: item.paper?.id || item.id || Math.random().toString(),\n          authors: item.paper?.authors || [],\n          publishedAt: item.paper?.publishedAt || item.publishedAt,\n          title: item.paper?.title || item.title,\n          summary: item.paper?.summary || item.summary,\n          upvotes: item.paper?.upvotes || 0,\n          discussionId: item.paper?.discussionId || '',\n          ai_summary: item.paper?.ai_summary,\n          ai_keywords: item.paper?.ai_keywords,\n          githubRepo: item.paper?.githubRepo,\n          githubStars: item.paper?.githubStars,\n          projectPage: item.paper?.projectPage,\n          thumbnail: item.thumbnail,\n          authorData: item.submittedBy || item.paper?.submittedOnDailyBy,\n          lastModified: item.paper?.publishedAt || item.publishedAt,\n          repoType: 'model',\n          numComments: item.numComments,\n          submittedBy: item.submittedBy,\n          organization: item.organization,\n        }))\n        \n        const processedPapers = formattedPapers.sort(\n          (a, b) => new Date(b.publishedAt).getTime() - new Date(a.publishedAt).getTime()\n        )\n        setPapers(processedPapers)\n      } else {\n        setFetchError(t('paper.apiError'))\n        setPapers([])\n      }\n    } catch (error) {\n      console.error('获取每日论文数据失败:', error)\n      setFetchError(t('paper.loadError'))\n      setPapers([])\n    }\n  }\n\n  // 获取热门数据\n  const fetchTrendingPapers = async () => {\n    try {\n      // 添加时间戳和缓存控制头，确保获取最新数据\n      const timestamp = Date.now()\n      const response = await axios.get<RepoData>(`${API_PAPERS_URL}/trending`, {\n        headers: {\n          'Cache-Control': 'no-cache',\n          'Pragma': 'no-cache'\n        },\n        params: {\n          _t: timestamp\n        }\n      })\n      \n      if (response.data?.recentlyTrending && Array.isArray(response.data.recentlyTrending)) {\n        const formattedPapers: PaperDetail[] = response.data.recentlyTrending.map((item) => {\n          const repoData = item.repoData\n          \n          // 缩略图URL\n          const generateThumbnail = (id: string) => {\n            const parts = id.split('/')\n            if (parts.length >= 2) {\n              return `https://hf-mirror.com/front/thumbnails/${parts[0]}/${parts[1]}.png`\n            }\n            return undefined\n          }\n          \n          // 根据不同类型处理数据\n          if (item.repoType === 'model') {\n            const modelData = repoData as ModelData\n            return {\n              id: modelData.id,\n              authors: modelData.authorData ? [{ name: modelData.authorData.fullname, _id: modelData.authorData._id }] : [],\n              publishedAt: modelData.lastModified,\n              title: modelData.id,\n              summary: modelData.pipeline_tag || 'AI模型',\n              upvotes: modelData.likes,\n              discussionId: modelData.id,\n              thumbnail: generateThumbnail(modelData.id),\n              authorData: modelData.authorData,\n              pipeline_tag: modelData.pipeline_tag,\n              downloads: modelData.downloads,\n              numParameters: modelData.numParameters,\n              lastModified: modelData.lastModified,\n              repoType: 'model',\n            }\n          } else if (item.repoType === 'dataset') {\n            const datasetData = repoData as DatasetData;\n            return {\n              id: datasetData.id,\n              authors: [],\n              publishedAt: datasetData.lastModified,\n              title: datasetData.id,\n              summary: t('paper.dataset'),\n              upvotes: datasetData.likes,\n              discussionId: datasetData.id,\n              thumbnail: generateThumbnail(datasetData.id),\n              downloads: datasetData.downloads,\n              lastModified: datasetData.lastModified,\n              repoType: 'dataset',\n              datasetsServerInfo: datasetData.datasetsServerInfo,\n            }\n          } else if (item.repoType === 'space') {\n            const spaceData = repoData as SpaceData\n            return {\n              id: spaceData.id,\n              authors: spaceData.authorData ? [{ name: spaceData.authorData.fullname, _id: spaceData.authorData._id }] : [],\n              publishedAt: spaceData.lastModified,\n              title: spaceData.title,\n              summary: spaceData.ai_short_description || spaceData.shortDescription || 'AI应用',\n              upvotes: spaceData.likes,\n              discussionId: spaceData.id,\n              thumbnail: generateThumbnail(spaceData.id),\n              authorData: spaceData.authorData,\n              lastModified: spaceData.lastModified,\n              repoType: 'space',\n              shortDescription: spaceData.shortDescription,\n              ai_category: spaceData.ai_category,\n              runtime: spaceData.runtime,\n              isSpace: true,\n              projectPage: `https://huggingface.co/spaces/${spaceData.id}`,\n            }\n          }\n          \n          return {\n            id: repoData.id,\n            authors: [],\n            publishedAt: repoData.lastModified,\n            title: repoData.id,\n            summary: '未知类型',\n            upvotes: repoData.likes || 0,\n            discussionId: repoData.id,\n            thumbnail: generateThumbnail(repoData.id),\n            lastModified: repoData.lastModified,\n            repoType: item.repoType,\n          } as PaperDetail\n        })\n        \n        const processedPapers = formattedPapers.sort((a, b) => b.upvotes - a.upvotes)\n        setPapers(processedPapers)\n      } else {\n        setFetchError(t('paper.hotApiError'))\n        setPapers([])\n      }\n    } catch (error) {\n      console.error('获取热门数据失败:', error)\n      setFetchError(t('paper.hotLoadError'))\n      setPapers([])\n    }\n  }\n\n  // 获取数据\n  const fetchPapers = async () => {\n    setLoading(true)\n    setFetchError(null)\n    \n    if (activeTab === 'daily') {\n      await fetchDailyPapers()\n    } else if (activeTab === 'trending') {\n      await fetchTrendingPapers()\n    }\n    \n    setLoading(false)\n  }\n\n  useEffect(() => {\n    fetchPapers()\n  }, [activeTab])\n\n  const handleTabChange = (e: RadioChangeEvent) => {\n    setActiveTab(e.target.value)\n  }\n\n  const handleSearch = (value: string) => {\n    setSearchQuery(value)\n  }\n\n  // 根据类型获取标签颜色\n  const getTypeTag = (repoType: string) => {\n    switch (repoType) {\n      case 'model':\n        return { icon: <DatabaseOutlined />, color: 'blue', text: t('paper.model') }\n      case 'dataset':\n        return { icon: <DatabaseOutlined />, color: 'green', text: t('paper.dataset') }\n      case 'space':\n        return { icon: <CodeOutlined />, color: 'purple', text: t('paper.application') }\n      case 'paper':\n        return { icon: <FilePdfOutlined />, color: 'orange', text: t('paper.paper') }\n      default:\n        return { icon: null, color: 'default', text: t('paper.unknown') }\n    }\n  }\n\n  // 处理PDF预览\n  const handlePdfPreview = (pdfUrl: string, paperTitle: string) => {\n    if (isMobileDevice()) {\n      let viewerUrl = ''\n      try {\n        viewerUrl = `https://docs.google.com/viewer?url=${encodeURIComponent(pdfUrl)}&embedded=true`\n      } catch (error) {\n        viewerUrl = `https://mozilla.github.io/pdf.js/web/viewer.html?file=${encodeURIComponent(pdfUrl)}`\n      }\n      setCurrentPdfUrl(viewerUrl)\n      setCurrentPaperTitle(paperTitle)\n      setPdfModalVisible(true)\n    } else {\n      setCurrentPdfUrl(pdfUrl)\n      setCurrentPaperTitle(paperTitle)\n      setPdfModalVisible(true)\n    }\n  }\n\n  // 跳转到ChatGPT对话\n  const toggleChat = (pdfUrl: string, paperTitle: string) => {\n    const chatUrl = `/gpt?paper=${encodeURIComponent(paperTitle)}&pdf=${encodeURIComponent(pdfUrl)}`\n    window.location.href = chatUrl\n  }\n\n  // 关闭PDF弹窗\n  const handlePdfModalClose = () => {\n    setPdfModalVisible(false)\n    setCurrentPdfUrl('')\n    setCurrentPaperTitle('')\n  }\n\n  // 获取所有可用链接\n  const getAllLinks = (paper: PaperDetail) => {\n    const links = []\n\n    // 论文链接（如果是arXiv ID）\n    if (paper.id && paper.id.match(/^\\d{4}\\.\\d{5}$/)) {\n      links.push({\n        key: `arxiv-${paper.id}`,\n        icon: <PaperClipOutlined />,\n        href: `https://arxiv.org/pdf/${paper.id}`,\n        tooltip: '查看论文',\n        type: 'default' as const,\n        flag: true\n      })\n    }\n    \n    // HuggingFace详情链接\n    if (paper.id) {\n      links.push({\n        key: 'hf-detail',\n        icon: <LinkOutlined />,\n        // 如果是daily paper，https://huggingface.co/papers/${paper.id}\n        // 如果是trending paper，如果是数据集：https://huggingface.co/datasets/${paper.id}，如果是应用：https://huggingface.co/spaces/${paper.id}，如果是模型：https://huggingface.co/${paper.id}\n        href: activeTab === 'daily' ? `https://hf-mirror.com/papers/${paper.id}` : (paper.repoType === 'dataset' ? `https://hf-mirror.com/datasets/${paper.id}` : (paper.repoType === 'space' ? `https://huggingface.co/spaces/${paper.id}` : `https://hf-mirror.com/${paper.id}`)),\n        tooltip: t('paper.showDetail'),\n        type: 'primary' as const\n      })\n    }\n    \n    // GitHub链接\n    if (paper.githubRepo) {\n      links.push({\n        key: 'github',\n        icon: <GithubOutlined />,\n        href: paper.githubRepo,\n        tooltip: t('paper.github'),\n        type: 'default' as const\n      })\n    }\n    \n    // 项目主页链接\n    if (paper.projectPage) {\n      links.push({\n        key: 'project',\n        icon: <ProjectOutlined />,\n        href: paper.projectPage,\n        tooltip: t('paper.project'),\n        type: 'default' as const\n      })\n    }\n    \n    // 论文链接（如果是arXiv ID）- 这里是摘要链接\n    // 仅在非移动设备上添加摘要链接\n    if (paper.id && paper.id.match(/^\\d{4}\\.\\d{5}$/) && !isMobileDevice()) {\n      links.push({\n        key: `arxiv-abs-${paper.id}`,\n        icon: <PaperClipOutlined />,\n        href: `https://arxiv.org/abs/${paper.id}`,\n        tooltip: t('paper.arXiv'),\n        type: 'default' as const\n      })\n    }\n    \n    return links\n  }\n\n  // 筛选论文\n  const filteredPapers = papers.filter(paper => {\n    // 先按类型过滤\n    if (repoTypeFilter !== 'all' && paper.repoType !== repoTypeFilter) {\n      return false\n    }\n    \n    if (!searchQuery.trim()) return true\n    \n    const searchLower = searchQuery.toLowerCase()\n    return (\n      paper.title.toLowerCase().includes(searchLower) ||\n      paper.summary.toLowerCase().includes(searchLower) ||\n      getAuthorNames(paper.authors).toLowerCase().includes(searchLower) ||\n      getAuthorDataName(paper.authorData).toLowerCase().includes(searchLower) ||\n      (paper.pipeline_tag && paper.pipeline_tag.toLowerCase().includes(searchLower)) ||\n      (paper.ai_category && paper.ai_category.toLowerCase().includes(searchLower)) ||\n      (paper.organization && getOrganizationName(paper.organization).toLowerCase().includes(searchLower))\n    )\n  })\n\n  // 类型筛选菜单\n  const repoTypeMenuItems = [\n    { key: 'all', label: t('paper.all') },\n    { key: 'model', label: t('paper.model') },\n    { key: 'dataset', label: t('paper.dataset') },\n    { key: 'space', label: t('paper.application') },\n  ]\n\n  return (\n    <div className=\"min-h-screen bg-gray-50 p-4 md:p-6\">\n      <div className=\"max-w-6xl mx-auto\">\n        <header className=\"mb-6\">\n          <div className=\"flex flex-col sm:flex-row justify-between items-start sm:items-center mb-4\">\n            <div>\n              <h1 className=\"text-2xl font-bold text-gray-900\">{t('paper.title')}</h1>\n              <p className=\"text-gray-600 text-sm mt-1\">{t('paper.content')}</p>\n              <p className=\"text-black-400 text-xs mt-1\">{t('paper.dataSource')}</p>\n              <span className=\"text-red-400 text-xs mt-1\">{t('paper.tip')}</span>\n            </div>\n            \n            <div className=\"mt-3 sm:mt-0\">\n              <Radio.Group \n                value={activeTab} \n                onChange={handleTabChange}\n                optionType=\"button\"\n                buttonStyle=\"solid\"\n                size=\"small\"\n                className=\"bg-white rounded-lg flex\"\n              >\n                <Radio.Button value=\"daily\" className=\"px-3 py-1 text-sm\">{t('paper.today')}</Radio.Button>\n                <Radio.Button value=\"trending\" className=\"px-3 py-1 text-sm flex items-center\">\n                  <FireOutlined className=\"mr-1\" /> {t('paper.hot')}\n                </Radio.Button>\n              </Radio.Group>\n              <Radio.Group\n                optionType=\"button\"\n                buttonStyle=\"solid\"\n                size=\"small\"\n                className=\"bg-white rounded-lg flex mt-8 max-[700px]:hidden\"\n              >\n                <Button type=\"primary\" className=\"px-3 py-1 text-sm\" onClick={() => navigate('/latex')}>{t('paper.gotoLatexEdit')}</Button>\n              </Radio.Group>\n            </div>\n          </div>\n\n          {/* 搜索和筛选区域 */}\n          <div className=\"flex flex-col sm:flex-row gap-3 mb-6\">\n            <div className=\"flex-1\">\n              <Input\n                size=\"middle\"\n                placeholder={t('paper.search')}\n                prefix={<SearchOutlined className=\"text-gray-400\" />}\n                value={searchQuery}\n                onChange={(e) => setSearchQuery(e.target.value)}\n                onPressEnter={(e) => handleSearch((e.target as HTMLInputElement).value)}\n                className=\"rounded-lg\"\n              />\n            </div>\n            \n            {activeTab === 'trending' && (\n              <Dropdown\n                menu={{\n                  items: repoTypeMenuItems,\n                  selectedKeys: [repoTypeFilter],\n                  onClick: (e) => setRepoTypeFilter(e.key)\n                }}\n                placement=\"bottomRight\"\n              >\n                <Button className=\"rounded-lg\">\n                  {repoTypeFilter === 'all' ? t('paper.all') : \n                   repoTypeFilter === 'model' ? t('paper.model') :\n                   repoTypeFilter === 'dataset' ? t('paper.dataset') : t('paper.application')}\n                  <DownOutlined />\n                </Button>\n              </Dropdown>\n            )}\n          </div>\n          \n          {searchQuery && (\n            <div className=\"text-xs text-gray-500 mt-2\">\n              <span>{t('paper.found')} {filteredPapers.length} {t('paper.relatedResults')}</span>\n            </div>\n          )}\n        </header>\n\n        {/* 主要内容区域 */}\n        <main>\n          {fetchError && (\n            <div className=\"mb-4 p-3 bg-red-50 border border-red-200 rounded-lg text-red-700 text-sm\">\n              <div className=\"flex items-center justify-between\">\n                <span>{fetchError}</span>\n                <Button type=\"link\" size=\"small\" onClick={fetchPapers} className=\"p-0\">\n                  {t('paper.retry')}\n                </Button>\n              </div>\n            </div>\n          )}\n\n          {loading ? (\n            // 先加载骨架屏\n            <div className=\"space-y-3\">\n              {[1, 2, 3, 4, 5].map(i => (\n                <div key={i} className=\"bg-white rounded-lg border p-3\">\n                  <Skeleton active paragraph={{ rows: 2 }} />\n                </div>\n              ))}\n            </div>\n          ) : filteredPapers.length > 0 ? (\n            <div className=\"space-y-3\">\n              {filteredPapers.map((paper, index) => {\n                if (activeTab === 'daily') {\n                  paper.repoType = 'paper'\n                }\n                const typeTag = getTypeTag(paper.repoType);\n                const isTrending = activeTab === 'trending';\n                const allLinks = getAllLinks(paper);\n                const taskTag = getTaskTag(paper.pipeline_tag);\n                const hardwareTag = getHardwareTag(paper.runtime);\n                \n                return (\n                  <Card\n                    key={`${paper.id}-${index}`}\n                    className=\"rounded-lg border hover:border-blue-300 hover:shadow-sm transition-all duration-200 bg-white\"\n                    bodyStyle={{ padding: '12px' }}\n                  >\n                    <div className=\"flex\">\n                      {/* 左侧：封面图 */}\n                      {paper.thumbnail && activeTab === 'daily' && (\n                        <div className=\"flex-shrink-0 w-[30%] h-full mr-4\">\n                          <Image\n                            src={paper.thumbnail}\n                            alt={paper.title}\n                            className=\"w-full h-full object-cover rounded border border-gray-200\"\n                          />\n                        </div>\n                      )}\n\n                      {/* 中间：内容区域 */}\n                      <div className=\"flex-1 min-w-0\">\n                        {/* 标题和标签行 */}\n                        <div className=\"flex items-start justify-between mb-2\">\n                          <div className=\"flex items-center flex-1 mr-2\">\n                            {isTrending && index < 3 && (\n                              <Badge\n                                count={`🔥 Top ${index + 1}`}\n                                style={{ \n                                  backgroundColor: '#dc2626',\n                                  fontSize: '10px',\n                                  padding: '0 4px',\n                                  height: '18px',\n                                  lineHeight: '18px',\n                                  marginRight: '8px'\n                                }}\n                              />\n                            )}\n                            <h3 className=\"text-base font-semibold text-gray-900 line-clamp-1 flex-1\">\n                              {paper.title}\n                            </h3>\n                          </div>\n                          <div className=\"flex items-center space-x-2\">\n                            {/* 类型标签 */}\n                            <Tag \n                              color={typeTag.color} \n                              icon={typeTag.icon}\n                              className=\"text-xs\"\n                            >\n                              {activeTab === 'daily' ? t('paper.paper') : typeTag.text}\n                            </Tag>\n                            \n                            {/* 点赞数 */}\n                            {paper.upvotes >= 20 && (\n                              <Badge\n                                count={`🔥 ${formatNumber(paper.upvotes)}`}\n                                style={{ \n                                  backgroundColor: '#f97316',\n                                  fontSize: '11px',\n                                  padding: '0 6px',\n                                  height: '20px',\n                                  lineHeight: '20px'\n                                }}\n                              />\n                            )}\n                          </div>\n                        </div>\n\n                        {/* 关键词 */}\n                          {paper.ai_keywords && paper.ai_keywords.length > 0 && !isMobileDevice() && (\n                            <div className=\"flex items-center overflow-auto mb-2\" style={{ scrollbarWidth: 'none' }}>\n                              {\n                                paper.ai_keywords.map((keyword, index) => (\n                                  <Tag key={index} color=\"cyan\" className=\"text-xs\">\n                                    {keyword}\n                                  </Tag>\n                                ))\n                              }\n                            </div>\n                          )}\n                          {paper.ai_keywords && paper.ai_keywords.length > 0 && isMobileDevice() && (\n                            <div className=\"flex items-center overflow-auto mb-2\" style={{ scrollbarWidth: 'none' }}>\n                              {/* 随机展示一个paper.ai_keywords的tag标签 */}\n                              <Tag key={0} color=\"cyan\" className=\"text-xs\">\n                                {paper.ai_keywords[Math.floor(Math.random() * paper.ai_keywords.length)]}\n                              </Tag>\n                            </div>\n                          )}\n\n                        {/* 摘要/描述 */}\n                        <p className=\"text-gray-600 text-sm mb-2 line-clamp-2 leading-relaxed\">\n                          {paper.summary || paper.ai_summary}\n                        </p>\n\n                        {/* 元信息行 */}\n                        <div className=\"flex flex-wrap items-center gap-2 text-xs text-gray-500 mb-2\">\n                          {/* 作者/机构信息 */}\n                          {(paper.authorData || paper.authors.length > 0 || paper.organization) && (\n                            <div className=\"flex items-center\">\n                              <Avatar \n                                size={16}\n                                src={paper.authorData?.avatarUrl || paper.organization?.avatar}\n                                className=\"mr-1\"\n                              />\n                              <span className=\"font-medium text-gray-700\">\n                                {getAuthorNames(paper.authors) || \n                                 getAuthorDataName(paper.authorData) || \n                                 getOrganizationName(paper.organization)}\n                              </span>\n                            </div>\n                          )}\n\n                          {/* 任务类型标签 */}\n                          {taskTag && (\n                            <div className=\"flex items-center\">\n                              <Tag color=\"cyan\" className=\"text-xs\">\n                                {taskTag}\n                              </Tag>\n                            </div>\n                          )}\n\n                          {/* 时间信息 */}\n                          {paper.publishedAt && (\n                            <div className=\"flex items-center\">\n                              <CalendarOutlined className=\"mr-1\" />\n                              <span>{new Date(paper.publishedAt).toLocaleString()}</span>\n                            </div>\n                          )}\n                        </div>\n\n                        {/* 统计信息行 */}\n                        <div className=\"flex flex-wrap gap-3 mb-3 text-xs text-gray-600\">\n                          {/* 下载量 */}\n                          {paper.downloads !== undefined && paper.downloads > 0 && (\n                            <div className=\"flex items-center\">\n                              <DownloadOutlined className=\"mr-1\" />\n                              <span>{formatNumber(paper.downloads)}</span>\n                            </div>\n                          )}\n                          \n                          {/* 评论数 */}\n                          {paper.numComments !== undefined && paper.numComments > 0 && (\n                            <div className=\"flex items-center\">\n                              <MessageOutlined className=\"mr-1\" />\n                              <span>{paper.numComments}</span>\n                            </div>\n                          )}\n                          \n                          {/* 参数量 */}\n                          {paper.numParameters && (\n                            <div className=\"flex items-center\">\n                              <span className=\"font-medium mr-1\">{t('paper.parameterCount')}</span>\n                              <span>{formatParamCount(paper.numParameters)}</span>\n                            </div>\n                          )}\n                          \n                          {/* 数据集大小 */}\n                          {paper.datasetsServerInfo && (\n                            <div className=\"flex items-center\">\n                              <span className=\"font-medium mr-1\">{t('paper.dataSize')}</span>\n                              <span>{formatNumber(paper.datasetsServerInfo.numRows)}</span>\n                            </div>\n                          )}\n                          \n                          {/* 应用硬件 */}\n                          {hardwareTag && (\n                            <div className=\"flex items-center\">\n                              <span className=\"font-medium mr-1\">{t('paper.hardware')}</span>\n                              <span>{hardwareTag}</span>\n                            </div>\n                          )}\n                        </div>\n\n                        {/* 链接按钮行 */}\n                        <div className=\"flex items-center justify-between pt-2 border-t border-gray-100\">\n                          {/* 左侧：分类信息 */}\n                          <div className=\"flex items-center\">\n                            {paper.ai_category && (\n                              <span className=\"text-xs text-gray-600 px-2 py-1 bg-gray-100 rounded\">\n                                {paper.ai_category}\n                              </span>\n                            )}\n                          </div>\n\n                          {/* 右侧：所有链接按钮 */}\n                          <div className=\"flex items-center justify-end space-x-2 w-full\">\n                            {allLinks.map((link) => {\n                              // 如果是flag为true的链接，显示PDF预览按钮\n                              if (link.flag) {\n                                return (\n                                  <React.Fragment key={link.key}>\n                                    <Button\n                                      type=\"default\"\n                                      size=\"small\"\n                                      icon={<FilePdfOutlined />}\n                                      onClick={() => handlePdfPreview(link.href, paper.title)}\n                                      className=\"p-1 text-xs bg-red-50 text-red-600 border-red-200 hover:bg-red-100\"\n                                    >\n                                      PDF\n                                    </Button>\n                                    <Button\n                                      type=\"default\"\n                                      size=\"small\"\n                                      icon={<OpenAIOutlined />}\n                                      onClick={() => toggleChat(link.href, paper.title)}\n                                      className=\"p-1 text-xs bg-blue-50 text-black border-black-200 hover:bg-gray-200\"\n                                    >\n                                      GPT\n                                    </Button>\n                                  </React.Fragment>\n                                );\n                              }\n\n                              // 普通链接按钮\n                              return (\n                                <Tooltip key={link.key} title={link.tooltip}>\n                                  <Button\n                                    type={link.type}\n                                    size=\"small\"\n                                    icon={link.icon}\n                                    href={link.href}\n                                    target=\"_blank\"\n                                    className=\"p-1 text-xs\"\n                                  >\n                                    {link.type === 'primary' && t('paper.detail')}\n                                  </Button>\n                                </Tooltip>\n                              );\n                            })}\n                          </div>\n                        </div>\n                      </div>\n                    </div>\n                  </Card>\n                )\n              })}\n            </div>\n          ) : (\n            // 无结果状态\n            <div className=\"text-center py-10\">\n              <div className=\"inline-flex items-center justify-center w-12 h-12 rounded-full bg-gray-100 mb-4\">\n                <SearchOutlined className=\"text-xl text-gray-400\" />\n              </div>\n              <h3 className=\"text-lg font-medium text-gray-900 mb-2\">\n                {searchQuery ? t('paper.noResult') : t('paper.noData')}\n              </h3>\n              <p className=\"text-gray-600 text-sm mb-4\">\n                {searchQuery \n                  ? t('paper.tryDifferentKeywords') \n                  : t('paper.networkError')}\n              </p>\n              {searchQuery && (\n                <Button \n                  type=\"link\" \n                  onClick={() => setSearchQuery('')}\n                  className=\"text-sm\"\n                >\n                  {t('paper.clearSearch')}\n                </Button>\n              )}\n            </div>\n          )}\n        </main>\n\n        {/* PDF预览弹窗 */}\n        <Modal\n          title={\n            <div className=\"flex items-center\">\n              <FilePdfOutlined className=\"text-red-500 mr-2\" />\n              <span className=\"font-medium\">{currentPaperTitle}</span>\n            </div>\n          }\n          open={pdfModalVisible}\n          onCancel={handlePdfModalClose}\n          footer={null}\n          width=\"80%\"\n          style={{ top: 20 }}\n          styles={{ body: { height: '80vh', padding: 0 } }}\n        >\n          {currentPdfUrl && (\n            <iframe\n              src={`${currentPdfUrl}#view=FitH`}\n              title={`PDF - ${currentPaperTitle}`}\n              width=\"100%\"\n              height=\"100%\"\n              style={{ border: 'none' }}\n              className=\"w-full h-full\"\n            />\n          )}\n        </Modal>\n      </div>\n    </div>\n  )\n}\n\nexport default PaperListPage"
  },
  {
    "path": "src/pages/TextToPhoto.tsx",
    "content": "import React, { useState } from 'react'\nimport { Input, Button, Select, Card, Row, Col, message, Typography, Slider, Collapse } from 'antd'\nimport {\n  PictureOutlined,\n  DownloadOutlined,\n  ClearOutlined,\n  SettingOutlined\n} from '@ant-design/icons'\nimport { useTranslation } from 'react-i18next'\nimport styled from 'styled-components'\n\nconst { TextArea } = Input\nconst { Option } = Select\nconst { Title, Paragraph, Text } = Typography\nconst { Panel } = Collapse\n\nconst PageContainer = styled.div`\n  max-width: 1200px;\n  margin: 0 auto;\n  padding: 40px 20px;\n  min-height: calc(100vh - 200px);\n`\n\nconst GeneratorCard = styled(Card)`\n  border-radius: 16px;\n  border: none;\n  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);\n  padding: 40px;\n\n  @media (max-width: 768px) {\n    padding: 24px;\n  }\n`\n\nconst TextAreaWrapper = styled.div`\n  .ant-input {\n    border-radius: 12px;\n    min-height: 100px;\n    font-size: 1rem;\n    line-height: 1.6;\n  }\n`\n\nconst ImagePreview = styled.div`\n  background: #f8fafc;\n  border-radius: 12px;\n  padding: 20px;\n  text-align: center;\n  min-height: 400px;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n\n  img {\n    max-width: 100%;\n    max-height: 500px;\n    border-radius: 8px;\n    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);\n  }\n\n  .placeholder {\n    color: #94a3b8;\n    font-size: 1.1rem;\n  }\n\n  .images-grid {\n    display: grid;\n    grid-template-columns: repeat(2, 1fr);\n    gap: 16px;\n    width: 100%;\n\n    img {\n      width: 100%;\n      height: auto;\n    }\n  }\n\n  @media (max-width: 576px) {\n    .images-grid {\n      grid-template-columns: 1fr;\n    }\n  }\n`\n\nconst ActionButtons = styled.div`\n  display: flex;\n  gap: 12px;\n  justify-content: center;\n  margin-top: 24px;\n\n  .ant-btn {\n    border-radius: 12px;\n    padding: 10px 24px;\n    font-size: 1rem;\n  }\n`\n\nconst SettingItem = styled.div`\n  margin-bottom: 16px;\n\n  .setting-label {\n    display: flex;\n    justify-content: space-between;\n    margin-bottom: 8px;\n    font-size: 0.9rem;\n    color: #64748b;\n  }\n\n  .ant-slider {\n    margin: 8px 0;\n  }\n`\n\nconst TextToPhoto: React.FC = () => {\n  const { t } = useTranslation()\n  const [prompt, setPrompt] = useState('')\n  const [negativePrompt, setNegativePrompt] = useState('')\n  const [imageSize, setImageSize] = useState('512x512')\n  const [samples, setSamples] = useState(1)\n  const [steps, setSteps] = useState(31)\n  const [guidanceScale, setGuidanceScale] = useState(7.5)\n  const [seed, setSeed] = useState<number | null>(null)\n  const [safetyChecker, setSafetyChecker] = useState('no')\n  const [enhancePrompt, setEnhancePrompt] = useState('no')\n  const [multiLingual, setMultiLingual] = useState('no')\n  const [selfAttention, setSelfAttention] = useState('no')\n  const [upscale, setUpscale] = useState('no')\n  const [panorama, setPanorama] = useState('no')\n  const [generatedImages, setGeneratedImages] = useState<string[]>([])\n  const [loading, setLoading] = useState(false)\n  const [imageLoadState, setImageLoadState] = useState<Record<number, boolean>>({})\n\n  const sizeOptions = [\n    { value: '256x256', label: '256x256' },\n    { value: '512x512', label: '512x512' },\n    { value: '768x768', label: '768x768' },\n    { value: '1024x1024', label: '1024x1024' }\n  ]\n\n  const handleGenerate = async () => {\n    if (!prompt.trim()) {\n      message.warning(t('textToPhoto.enterPositivePrompt'))\n      return\n    }\n\n    setLoading(true)\n    setGeneratedImages([])\n    setImageLoadState({})\n\n    try {\n      const [width, height] = imageSize.split('x').map(Number)\n\n      // 使用 Pollinations.ai API - 完全免费，无需 API Key\n      const images: string[] = []\n\n      for (let i = 0; i < samples; i++) {\n        // 构建请求 URL\n        // Pollinations.ai 不支持 negative 参数，我们将负面提示词集成到 prompt 中\n        let finalPrompt = prompt\n        if (negativePrompt && negativePrompt.trim()) {\n          // 使用特殊语法来排除元素\n          finalPrompt = `${prompt}, avoiding: ${negativePrompt}`\n        }\n\n        const params = new URLSearchParams({\n          width: width.toString(),\n          height: height.toString(),\n          seed: seed === null ? Math.floor(Math.random() * 1000000).toString() : (seed + i).toString(),\n          model: 'flux',\n          nologo: 'true'\n        })\n\n        // 添加随机数避免缓存\n        params.append('noCache', Date.now().toString())\n\n        const imageUrl = `https://image.pollinations.ai/prompt/${encodeURIComponent(finalPrompt)}?${params.toString()}`\n        images.push(imageUrl)\n      }\n\n      console.log('生成的图片 URL:', images)\n\n      // 直接设置图片 URL\n      setGeneratedImages(images)\n      message.success(t('textToPhoto.generateSuccess').replace('X', images.length.toString()))\n    } catch (error: any) {\n      console.error('生成图片时出错:', error)\n      message.error(`${t('textToPhoto.generateFailed')}: ${error.message || t('trans.networkError')}`)\n    } finally {\n      setLoading(false)\n    }\n  }\n\n  const handleDownload = (imageUrl: string, index: number) => {\n    const link = document.createElement('a')\n    link.href = imageUrl\n    link.download = `generated_image_${Date.now()}_${index + 1}.png`\n    link.target = '_blank'\n    link.click()\n    message.success(t('textToPhoto.imageDownloadSuccess'))\n  }\n\n  const handleDownloadAll = () => {\n    if (generatedImages.length === 0) {\n      message.warning(t('textToPhoto.noImagesToDownload'))\n      return\n    }\n\n    generatedImages.forEach((imageUrl, index) => {\n      setTimeout(() => {\n        handleDownload(imageUrl, index)\n      }, index * 500)\n    })\n    message.success(t('textToPhoto.startDownload').replace('X', generatedImages.length.toString()))\n  }\n\n  const handleClear = () => {\n    setPrompt('')\n    setNegativePrompt('')\n    setGeneratedImages([])\n    setSamples(1)\n    setSteps(31)\n    setGuidanceScale(7.5)\n    setSeed(null)\n  }\n\n  return (\n    <PageContainer>\n      <GeneratorCard>\n        <Title level={2} style={{ textAlign: 'center', marginBottom: '16px' }}>\n          {t('textToPhoto.title')}\n        </Title>\n        <Paragraph style={{\n          textAlign: 'center',\n          color: '#64748b',\n          marginBottom: '32px'\n        }}>\n          {t('textToPhoto.description')}\n        </Paragraph>\n\n        <Row gutter={[24, 24]}>\n          <Col xs={24} lg={12}>\n            <div style={{ marginBottom: '16px' }}>\n              <Text strong>{t('textToPhoto.positivePrompt')}</Text>\n              <Text type=\"secondary\" style={{ marginLeft: '8px' }}>{t('textToPhoto.positivePromptDesc')}</Text>\n            </div>\n            <TextAreaWrapper>\n              <TextArea\n                value={prompt}\n                onChange={(e) => setPrompt(e.target.value)}\n                placeholder={t('textToPhoto.positivePromptPlaceholder')}\n                autoSize={{ minRows: 3, maxRows: 6 }}\n                style={{ background: '#f8fafc', marginBottom: '16px' }}\n              />\n            </TextAreaWrapper>\n\n            <div style={{ marginBottom: '16px' }}>\n              <Text strong>{t('textToPhoto.negativePrompt')}</Text>\n              <Text type=\"secondary\" style={{ marginLeft: '8px' }}>{t('textToPhoto.negativePromptDesc')}</Text>\n            </div>\n            <TextAreaWrapper>\n              <TextArea\n                value={negativePrompt}\n                onChange={(e) => setNegativePrompt(e.target.value)}\n                placeholder={t('textToPhoto.negativePromptPlaceholder')}\n                autoSize={{ minRows: 2, maxRows: 4 }}\n                style={{ background: '#f8fafc', marginBottom: '16px' }}\n              />\n            </TextAreaWrapper>\n\n            <Collapse\n              ghost\n              expandIconPosition=\"end\"\n              style={{ marginBottom: '16px' }}\n            >\n              <Panel header={<span><SettingOutlined /> {t('textToPhoto.advancedSettings')}</span>} key=\"settings\">\n                <SettingItem>\n                  <div className=\"setting-label\">\n                    <span>{t('textToPhoto.imageSize')}</span>\n                    <Text>{imageSize}</Text>\n                  </div>\n                  <Select\n                    value={imageSize}\n                    onChange={setImageSize}\n                    style={{ width: '100%' }}\n                  >\n                    {sizeOptions.map(option => (\n                      <Option key={option.value} value={option.value}>\n                        {option.label}\n                      </Option>\n                    ))}\n                  </Select>\n                </SettingItem>\n\n                <SettingItem>\n                  <div className=\"setting-label\">\n                    <span>{t('textToPhoto.samples')}</span>\n                    <Text>{samples}</Text>\n                  </div>\n                  <Slider\n                    min={1}\n                    max={4}\n                    value={samples}\n                    onChange={setSamples}\n                  />\n                </SettingItem>\n\n                <SettingItem>\n                  <div className=\"setting-label\">\n                    <span>{t('textToPhoto.steps')}</span>\n                    <Text>{steps}</Text>\n                  </div>\n                  <Slider\n                    min={21}\n                    max={51}\n                    step={10}\n                    value={steps}\n                    onChange={setSteps}\n                    marks={{ 21: '21', 31: '31', 41: '41', 51: '51' }}\n                  />\n                </SettingItem>\n\n                <SettingItem>\n                  <div className=\"setting-label\">\n                    <span>{t('textToPhoto.guidanceScale')}</span>\n                    <Text>{guidanceScale}</Text>\n                  </div>\n                  <Slider\n                    min={1}\n                    max={20}\n                    step={0.5}\n                    value={guidanceScale}\n                    onChange={setGuidanceScale}\n                  />\n                </SettingItem>\n\n                <SettingItem>\n                  <div className=\"setting-label\">\n                    <span>{t('textToPhoto.seed')}</span>\n                    <Text>{seed === null ? t('textToPhoto.random') : seed}</Text>\n                  </div>\n                  <Slider\n                    min={0}\n                    max={999999999}\n                    step={1}\n                    value={seed || 0}\n                    onChange={(value) => setSeed(value === 0 ? null : value)}\n                  />\n                  <Button\n                    size=\"small\"\n                    onClick={() => setSeed(null)}\n                    style={{ marginTop: '4px' }}\n                  >\n                    {t('textToPhoto.randomSeed')}\n                  </Button>\n                </SettingItem>\n\n                <div style={{ marginTop: '16px' }}>\n                  <Text strong>{t('textToPhoto.functionOptions')}</Text>\n                  <div style={{ marginTop: '8px', display: 'flex', flexDirection: 'column', gap: '8px' }}>\n                    <div>\n                      <Text style={{ marginRight: '8px' }}>{t('textToPhoto.safetyChecker')}:</Text>\n                      <Select\n                        value={safetyChecker}\n                        onChange={setSafetyChecker}\n                        size=\"small\"\n                      >\n                        <Option value=\"yes\">{t('textToPhoto.yes')}</Option>\n                        <Option value=\"no\">{t('textToPhoto.no')}</Option>\n                      </Select>\n                    </div>\n                    <div>\n                      <Text style={{ marginRight: '8px' }}>{t('textToPhoto.enhancePrompt')}:</Text>\n                      <Select\n                        value={enhancePrompt}\n                        onChange={setEnhancePrompt}\n                        size=\"small\"\n                      >\n                        <Option value=\"yes\">{t('textToPhoto.yes')}</Option>\n                        <Option value=\"no\">{t('textToPhoto.no')}</Option>\n                      </Select>\n                    </div>\n                    <div>\n                      <Text style={{ marginRight: '8px' }}>{t('textToPhoto.multiLingual')}:</Text>\n                      <Select\n                        value={multiLingual}\n                        onChange={setMultiLingual}\n                        size=\"small\"\n                      >\n                        <Option value=\"yes\">{t('textToPhoto.yes')}</Option>\n                        <Option value=\"no\">{t('textToPhoto.no')}</Option>\n                      </Select>\n                    </div>\n                    <div>\n                      <Text style={{ marginRight: '8px' }}>{t('textToPhoto.selfAttention')}:</Text>\n                      <Select\n                        value={selfAttention}\n                        onChange={setSelfAttention}\n                        size=\"small\"\n                      >\n                        <Option value=\"yes\">{t('textToPhoto.yes')}</Option>\n                        <Option value=\"no\">{t('textToPhoto.no')}</Option>\n                      </Select>\n                    </div>\n                    <div>\n                      <Text style={{ marginRight: '8px' }}>{t('textToPhoto.upscale')}:</Text>\n                      <Select\n                        value={upscale}\n                        onChange={setUpscale}\n                        size=\"small\"\n                      >\n                        <Option value=\"yes\">{t('textToPhoto.yes')}</Option>\n                        <Option value=\"no\">{t('textToPhoto.no')}</Option>\n                      </Select>\n                    </div>\n                    <div>\n                      <Text style={{ marginRight: '8px' }}>{t('textToPhoto.panorama')}:</Text>\n                      <Select\n                        value={panorama}\n                        onChange={setPanorama}\n                        size=\"small\"\n                      >\n                        <Option value=\"yes\">{t('textToPhoto.yes')}</Option>\n                        <Option value=\"no\">{t('textToPhoto.no')}</Option>\n                      </Select>\n                    </div>\n                  </div>\n                </div>\n              </Panel>\n            </Collapse>\n\n            <ActionButtons>\n              <Button\n                type=\"primary\"\n                size=\"large\"\n                icon={<PictureOutlined />}\n                onClick={handleGenerate}\n                loading={loading}\n                style={{\n                  background: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',\n                  border: 'none',\n                  padding: '12px 48px',\n                  fontSize: '1.1rem'\n                }}\n              >\n                {t('textToPhoto.generateBtn')}\n              </Button>\n              {generatedImages.length > 0 && (\n                <>\n                  <Button\n                    icon={<ClearOutlined />}\n                    size=\"large\"\n                    onClick={handleClear}\n                  >\n                    {t('textToPhoto.clearBtn')}\n                  </Button>\n                </>\n              )}\n            </ActionButtons>\n          </Col>\n\n          <Col xs={24} lg={12}>\n            <ImagePreview>\n              {generatedImages.length > 0 ? (\n                <div style={{ width: '100%' }}>\n                  {generatedImages.length === 1 ? (\n                    <img\n                      src={generatedImages[0]}\n                      alt=\"Generated\"\n                      crossOrigin=\"anonymous\"\n                      onLoad={() => setImageLoadState({ 0: true })}\n                      onError={() => message.warning(t('textToPhoto.imageLoadFailed'))}\n                      style={{ opacity: imageLoadState[0] ? 1 : 0.5 }}\n                    />\n                  ) : (\n                    <div className=\"images-grid\">\n                      {generatedImages.map((imageUrl, index) => (\n                        <div key={index} style={{ position: 'relative' }}>\n                          <img\n                            src={imageUrl}\n                            alt={`Generated ${index + 1}`}\n                            crossOrigin=\"anonymous\"\n                            onLoad={() => setImageLoadState((prev) => ({ ...prev, [index]: true }))}\n                            onError={() => message.warning(t('textToPhoto.imageNLoadFailed').replace('X', (index + 1).toString()))}\n                            style={{ opacity: imageLoadState[index] ? 1 : 0.5 }}\n                          />\n                          <Button\n                            type=\"primary\"\n                            size=\"small\"\n                            icon={<DownloadOutlined />}\n                            onClick={() => handleDownload(imageUrl, index)}\n                            style={{\n                              position: 'absolute',\n                              bottom: '8px',\n                              right: '8px',\n                              opacity: 0.9\n                            }}\n                          >\n                            {t('textToPhoto.downloadBtn')}\n                          </Button>\n                        </div>\n                      ))}\n                    </div>\n                  )}\n                  {generatedImages.length > 1 && (\n                    <Button\n                      type=\"primary\"\n                      icon={<DownloadOutlined />}\n                      onClick={handleDownloadAll}\n                      style={{\n                        marginTop: '16px',\n                        background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\n                        border: 'none'\n                      }}\n                    >\n                      {t('textToPhoto.downloadAllBtn')}\n                    </Button>\n                  )}\n                </div>\n              ) : (\n                <div className=\"placeholder\">\n                  <PictureOutlined style={{ fontSize: '3rem', marginBottom: '16px', display: 'block' }} />\n                  {loading ? t('textToPhoto.generatingImage') : t('textToPhoto.imageDisplayPlaceholder')}\n                </div>\n              )}\n            </ImagePreview>\n          </Col>\n        </Row>\n      </GeneratorCard>\n    </PageContainer>\n  )\n}\n\nexport default TextToPhoto\n"
  },
  {
    "path": "src/pages/Trans.tsx",
    "content": "import React, { useState } from 'react'\nimport { Input, Button, Select, Card, Row, Col, message, Typography } from 'antd'\nimport {\n  SwapOutlined,\n  CopyOutlined,\n  DownloadOutlined,\n  SoundOutlined\n} from '@ant-design/icons'\nimport { useTranslation } from 'react-i18next'\nimport styled from 'styled-components'\nimport MD5 from 'crypto-js/md5'\n\nconst { TextArea } = Input\nconst { Option } = Select\nconst { Title, Paragraph } = Typography\n\nconst PageContainer = styled.div`\n  max-width: 900px;\n  margin: 0 auto;\n  padding: 40px 20px;\n  min-height: calc(100vh - 200px);\n`\n\nconst TranslatorCard = styled(Card)`\n  border-radius: 16px;\n  border: none;\n  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);\n  padding: 40px;\n\n  @media (max-width: 768px) {\n    padding: 24px;\n  }\n`\n\nconst LanguageSelector = styled.div`\n  display: flex;\n  gap: 12px;\n  align-items: center;\n  justify-content: center;\n  margin: 24px 0;\n`\n\nconst TextAreaWrapper = styled.div`\n  .ant-input {\n    border-radius: 12px;\n    min-height: 200px;\n    font-size: 1rem;\n    line-height: 1.6;\n  }\n`\n\nconst ActionButtons = styled.div`\n  display: flex;\n  gap: 12px;\n  justify-content: center;\n  margin-top: 24px;\n\n  .ant-btn {\n    border-radius: 12px;\n    padding: 10px 24px;\n    font-size: 1rem;\n  }\n`\n\n// 百度翻译API配置（从环境变量读取）\nconst BAIDU_APP_ID = import.meta.env.VITE_BAIDU_APP_ID || ''\nconst BAIDU_SECRET_KEY = import.meta.env.VITE_BAIDU_SECRET_KEY || ''\n\nconst Trans: React.FC = () => {\n  const { t } = useTranslation()\n  const [sourceText, setSourceText] = useState('')\n  const [translatedText, setTranslatedText] = useState('')\n  const [sourceLang, setSourceLang] = useState('zh')\n  const [targetLang, setTargetLang] = useState('en')\n  const [loading, setLoading] = useState(false)\n\n  // 生成百度翻译API签名\n  const generateSign = (query: string, salt: string): string => {\n    const str = BAIDU_APP_ID + query + salt + BAIDU_SECRET_KEY\n    return MD5(str).toString()\n  }\n\n  const languageOptions = [\n    { value: 'zh', label: t('trans.languages.zh') },\n    { value: 'en', label: t('trans.languages.en') },\n    { value: 'jp', label: t('trans.languages.jp') },\n    { value: 'kor', label: t('trans.languages.kor') },\n    { value: 'fra', label: t('trans.languages.fra') },\n    { value: 'de', label: t('trans.languages.de') },\n    { value: 'spa', label: t('trans.languages.spa') },\n    { value: 'ru', label: t('trans.languages.ru') }\n  ]\n\n  const handleTranslate = async () => {\n    if (!sourceText.trim()) {\n      message.warning(t('trans.noTextToTranslate'))\n      return\n    }\n\n    setLoading(true)\n    try {\n      // 生成随机数\n      const salt = Date.now().toString()\n      // 生成签名\n      const sign = generateSign(sourceText, salt)\n\n      // 调用百度翻译API\n      const response = await fetch(\n        (`/api/translate?q=${encodeURIComponent(sourceText)}&from=${sourceLang}&to=${targetLang}&appid=${BAIDU_APP_ID}&salt=${salt}&sign=${sign}`)\n      )\n\n      const data = await response.json()\n\n      if (data.error_code) {\n        message.error(`${t('trans.translateFailed')}: ${data.error_msg}`)\n        setLoading(false)\n        return\n      }\n\n      // 解析翻译结果\n      if (data.trans_result && data.trans_result.length > 0) {\n        const result = data.trans_result.map((item: any) => item.dst).join('\\n')\n        setTranslatedText(result)\n        message.success(t('trans.translateSuccess'))\n      } else {\n        message.error(t('trans.translateEmpty'))\n      }\n    } catch (error) {\n      console.error('翻译错误:', error)\n      message.error(t('trans.networkError'))\n    } finally {\n      setLoading(false)\n    }\n  }\n\n  const handleSwapLanguages = () => {\n    setSourceText(translatedText)\n    setTranslatedText(sourceText)\n    const temp = sourceLang\n    setSourceLang(targetLang)\n    setTargetLang(temp)\n  }\n\n  const handleCopy = (text: string) => {\n    navigator.clipboard.writeText(text)\n      .then(() => message.success(t('common.copySuccess')))\n      .catch(() => message.error(t('common.copyFailed')))\n  }\n\n  const handleDownload = () => {\n    if (!translatedText) {\n      message.warning(t('trans.noContentToDownload'))\n      return\n    }\n\n    const blob = new Blob([translatedText], { type: 'text/plain' })\n    const url = URL.createObjectURL(blob)\n    const a = document.createElement('a')\n    a.href = url\n    a.download = `translation_${Date.now()}.txt`\n    a.click()\n    URL.revokeObjectURL(url)\n    message.success(t('common.downloadSuccess'))\n  }\n\n  const handleSpeak = (text: string, lang: string) => {\n    if ('speechSynthesis' in window) {\n      const utterance = new SpeechSynthesisUtterance(text)\n      utterance.lang = lang\n      window.speechSynthesis.speak(utterance)\n    } else {\n      message.warning(t('trans.browserNotSupportSpeech'))\n    }\n  }\n\n  return (\n    <PageContainer>\n      <TranslatorCard>\n        <Title level={2} style={{ textAlign: 'center', marginBottom: '32px' }}>\n          {t('trans.title')}\n        </Title>\n        <Paragraph style={{\n          textAlign: 'center',\n          color: '#64748b',\n          marginBottom: '32px'\n        }}>\n          {t('trans.description')}\n        </Paragraph>\n\n        <Row gutter={[24, 24]}>\n          <Col xs={24}>\n            <div style={{ marginBottom: '16px' }}>\n              <LanguageSelector>\n                <Select\n                  value={sourceLang}\n                  onChange={setSourceLang}\n                  style={{ width: '120px' }}\n                >\n                  {languageOptions.map(option => (\n                    <Option key={option.value} value={option.value}>\n                      {option.label}\n                    </Option>\n                  ))}\n                </Select>\n                <Button\n                  icon={<SwapOutlined />}\n                  onClick={handleSwapLanguages}\n                  type=\"text\"\n                />\n                <Select\n                  value={targetLang}\n                  onChange={setTargetLang}\n                  style={{ width: '120px' }}\n                >\n                  {languageOptions.map(option => (\n                    <Option key={option.value} value={option.value}>\n                      {option.label}\n                    </Option>\n                  ))}\n                </Select>\n              </LanguageSelector>\n            </div>\n\n            <Row gutter={[24, 0]} align=\"top\">\n              <Col xs={24} md={12}>\n                <TextAreaWrapper>\n                  <TextArea\n                    value={sourceText}\n                    onChange={(e) => setSourceText(e.target.value)}\n                    placeholder={t('trans.sourceTextPlaceholder')}\n                    autoSize={{ minRows: 6, maxRows: 12 }}\n                    style={{ background: '#f8fafc' }}\n                  />\n                </TextAreaWrapper>\n                <div style={{\n                  display: 'flex',\n                  gap: '8px',\n                  marginTop: '12px',\n                  justifyContent: 'flex-end'\n                }}>\n                  <Button\n                    icon={<SoundOutlined />}\n                    onClick={() => handleSpeak(sourceText, sourceLang)}\n                    type=\"text\"\n                  >\n                    {t('trans.speakBtn')}\n                  </Button>\n                  <Button\n                    icon={<CopyOutlined />}\n                    onClick={() => handleCopy(sourceText)}\n                    type=\"text\"\n                  >\n                    {t('trans.copyBtn')}\n                  </Button>\n                </div>\n              </Col>\n\n              <Col xs={24} md={12}>\n                <TextAreaWrapper>\n                  <TextArea\n                    value={translatedText}\n                    onChange={(e) => setTranslatedText(e.target.value)}\n                    placeholder={t('trans.translatedTextPlaceholder')}\n                    autoSize={{ minRows: 6, maxRows: 12 }}\n                    style={{ background: '#f8fafc' }}\n                    disabled\n                  />\n                </TextAreaWrapper>\n                <div style={{\n                  display: 'flex',\n                  gap: '8px',\n                  marginTop: '12px',\n                  justifyContent: 'flex-end'\n                }}>\n                  <Button\n                    icon={<SoundOutlined />}\n                    onClick={() => handleSpeak(translatedText, targetLang)}\n                    type=\"text\"\n                  >\n                    {t('trans.speakBtn')}\n                  </Button>\n                  <Button\n                    icon={<CopyOutlined />}\n                    onClick={() => handleCopy(translatedText)}\n                    type=\"text\"\n                  >\n                    {t('trans.copyBtn')}\n                  </Button>\n                </div>\n              </Col>\n            </Row>\n\n            <ActionButtons>\n              <Button\n                type=\"primary\"\n                size=\"large\"\n                onClick={handleTranslate}\n                loading={loading}\n                style={{\n                  background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\n                  border: 'none',\n                  padding: '12px 48px',\n                  fontSize: '1.1rem'\n                }}\n              >\n                {t('trans.translateBtn')}\n              </Button>\n              {translatedText && (\n                <Button\n                  icon={<DownloadOutlined />}\n                  size=\"large\"\n                  onClick={handleDownload}\n                >\n                  {t('trans.downloadBtn')}\n                </Button>\n              )}\n            </ActionButtons>\n          </Col>\n        </Row>\n      </TranslatorCard>\n    </PageContainer>\n  )\n}\n\nexport default Trans\n"
  },
  {
    "path": "src/pages/Video.tsx",
    "content": "import React, { useState } from 'react'\nimport { Button } from 'antd'\nimport { PlayCircleOutlined, DownloadOutlined } from '@ant-design/icons'\nimport styled from 'styled-components'\nimport { useTranslation } from 'react-i18next'\nimport VideoParse from '@/components/video/VideoParse'\nimport VideoDownload from '@/components/video/VideoDownload'\n\nconst PageContainer = styled.div`\n  max-width: 1200px;\n  margin: 0 auto;\n  padding: 40px 20px;\n  min-height: calc(100vh - 200px);\n`\n\nconst TabContainer = styled.div`\n  display: flex;\n  justify-content: center;\n  gap: 16px;\n  margin-bottom: 32px;\n`\n\nconst TabButton = styled(Button)<{ $active: boolean }>`\n  min-width: 140px;\n  height: 48px;\n  border-radius: 24px;\n  font-size: 16px;\n  font-weight: 500;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  gap: 8px;\n\n  ${props => props.$active ? `\n    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n    border-color: transparent;\n    color: #fff;\n    box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);\n\n    &:hover {\n      background: linear-gradient(135deg, #5568d3 0%, #6a3f8f 100%);\n      color: #fff;\n    }\n  ` : `\n    background: #fff;\n    border-color: #d9d9d9;\n    color: #666;\n\n    &:hover {\n      border-color: #667eea;\n      color: #667eea;\n    }\n  `}\n`\n\nconst Video: React.FC = () => {\n  const { t } = useTranslation()\n  const [activeTab, setActiveTab] = useState<'parse' | 'download'>('parse')\n\n  return (\n    <PageContainer>\n      <TabContainer>\n        <TabButton\n          $active={activeTab === 'parse'}\n          icon={<PlayCircleOutlined />}\n          onClick={() => setActiveTab('parse')}\n        >\n          {t('video.tabParse')}\n        </TabButton>\n        <TabButton\n          $active={activeTab === 'download'}\n          icon={<DownloadOutlined />}\n          onClick={() => setActiveTab('download')}\n        >\n          {t('video.tabDownload')}\n        </TabButton>\n      </TabContainer>\n\n      {activeTab === 'parse' ? <VideoParse /> : <VideoDownload />}\n    </PageContainer>\n  )\n}\n\nexport default Video\n"
  },
  {
    "path": "src/pages/WorkerAgent.tsx",
    "content": "import React, { useState } from 'react'\nimport { Spin } from 'antd'\n\nconst WorkerAgent: React.FC = () => {\n  // 生产环境下才显示加载效果\n  const [loading, setLoading] = useState(process.env.NODE_ENV === 'production')\n\n  return (\n    <div style={{ position: 'relative' }}>\n      {loading && (\n        <div style={{ \n          position: 'absolute', \n          top: '50%', \n          left: '50%', \n          transform: 'translate(-50%, -50%)',\n          zIndex: 1\n        }}>\n          <Spin size=\"large\" />\n        </div>\n      )}\n      {/* 生产环境下才显示iframe */}\n      {process.env.NODE_ENV === 'production' && (\n        <iframe\n          src={import.meta.env.VITE_AGENT_API_URL}\n          width=\"100%\"\n          height=\"650px\"\n          style={{ border: 'none', opacity: loading ? 0 : 1 }}\n          onLoad={() => setLoading(false)}\n        />\n      )}\n    </div>\n  );\n}\n\nexport default WorkerAgent\n"
  },
  {
    "path": "src/pages/goofish/Accounts/index.tsx",
    "content": "import React, { useEffect, useState } from 'react'\nimport { \n  Card, \n  Form, \n  Input, \n  Button, \n  Table, \n  Space, \n  Popconfirm, \n  message, \n  Avatar,\n  Typography,\n  Row,\n  Col,\n  Badge,\n  Tooltip\n} from 'antd'\nimport { \n  PlusOutlined, \n  EditOutlined, \n  DeleteOutlined, \n  PlayCircleOutlined,\n  StopOutlined,\n  ReloadOutlined,\n  UserOutlined,\n  QuestionCircleOutlined\n} from '@ant-design/icons'\nimport { useGoofishWebSocket } from '@/hooks/goofish'\nimport { accountApi } from '@/services/goofish'\nimport type { Account } from '@/types/goofish'\n\nconst { TextArea } = Input\nconst { Text } = Typography\n\nconst Accounts: React.FC = () => {\n  const { status, refetchStatus } = useGoofishWebSocket({\n    onMessage: (data) => {\n      if (data.type === 'accounts') {\n        loadAccounts()\n      }\n    }\n  })\n  \n  const [accounts, setAccounts] = useState<Account[]>([])\n  const [loading, setLoading] = useState(false)\n  const [submitting, setSubmitting] = useState(false)\n  const [editingId, setEditingId] = useState<string | null>(null)\n  const [refreshingId, setRefreshingId] = useState<string | null>(null)\n  const [form] = Form.useForm()\n\n  useEffect(() => {\n    loadAccounts()\n  }, [])\n\n  const loadAccounts = async () => {\n    setLoading(true)\n    try {\n      const response = await accountApi.getAccounts()\n      setAccounts(response.data?.accounts || [])\n      refetchStatus()\n    } catch (error) {\n      message.error('加载账号列表失败')\n    } finally {\n      setLoading(false)\n    }\n  }\n\n  const isConnected = (accountId: string): boolean => {\n    return status?.clients?.some((c: any) => c.accountId === accountId && c.connected) || false\n  }\n\n  const formatTime = (time?: string): string => {\n    return time ? new Date(time).toLocaleString('zh-CN') : '-'\n  }\n\n  const onFinish = async (values: any) => {\n    setSubmitting(true)\n    try {\n      if (editingId) {\n        await accountApi.saveAccount({\n          id: editingId,\n          remark: values.remark,\n          ...(values.cookies && { cookies: values.cookies })\n        })\n        message.success('保存成功')\n      } else {\n        if (!values.cookies?.trim()) {\n          message.error('请填写 Cookies')\n          return\n        }\n        await accountApi.saveAccount({\n          cookies: values.cookies.trim(),\n          remark: values.remark\n        })\n        message.success('添加成功')\n      }\n      form.resetFields()\n      setEditingId(null)\n      loadAccounts()\n    } catch (error) {\n      message.error('操作失败')\n    } finally {\n      setSubmitting(false)\n    }\n  }\n\n  const onEdit = (account: Account) => {\n    setEditingId(account.id)\n    form.setFieldsValue({\n      remark: account.remark || ''\n    })\n  }\n\n  const onCancelEdit = () => {\n    setEditingId(null)\n    form.resetFields()\n  }\n\n  const onRefreshInfo = async (id: string) => {\n    setRefreshingId(id)\n    try {\n      await accountApi.saveAccount({ id }) // 刷新用户信息\n      message.success('刷新成功')\n      loadAccounts()\n    } catch (error) {\n      message.error('刷新失败')\n    } finally {\n      setRefreshingId(null)\n    }\n  }\n\n  const onStart = async (id: string) => {\n    try {\n      await accountApi.startAccount(id)\n      message.success('启动成功')\n      loadAccounts()\n    } catch (error) {\n      message.error('启动失败')\n    }\n  }\n\n  const onStop = async (id: string) => {\n    try {\n      await accountApi.stopAccount(id)\n      message.success('停止成功')\n      loadAccounts()\n    } catch (error) {\n      message.error('停止失败')\n    }\n  }\n\n  const onDelete = async (id: string) => {\n    try {\n      await accountApi.deleteAccount(id)\n      message.success('删除成功')\n      loadAccounts()\n    } catch (error) {\n      message.error('删除失败')\n    }\n  }\n\n  const columns = [\n    {\n      title: '账号',\n      dataIndex: 'account',\n      key: 'account',\n      render: (_: any, record: Account) => (\n        <Space>\n          <Avatar \n            size={40} \n            src={record.avatar} \n            icon={!record.avatar && <UserOutlined />}\n          />\n          <div>\n            <div style={{ fontWeight: 500 }}>\n              {record.nickname || '未知用户'}\n            </div>\n            <Text type=\"secondary\" style={{ fontSize: '12px' }}>\n              {record.id}\n            </Text>\n          </div>\n        </Space>\n      )\n    },\n    {\n      title: '备注',\n      dataIndex: 'remark',\n      key: 'remark',\n      render: (remark?: string) => remark || '-'\n    },\n    {\n      title: '状态',\n      dataIndex: 'id',\n      key: 'status',\n      render: (id: string) => (\n        isConnected(id) ? (\n          <Badge status=\"success\" text=\"在线\" />\n        ) : (\n          <Badge status=\"default\" text=\"离线\" />\n        )\n      )\n    },\n    {\n      title: '更新时间',\n      dataIndex: 'updatedAt',\n      key: 'updatedAt',\n      render: (time?: string) => (\n        <Text type=\"secondary\" style={{ fontSize: '12px' }}>\n          {formatTime(time)}\n        </Text>\n      )\n    },\n    {\n      title: '操作',\n      key: 'actions',\n      render: (_: any, record: Account) => (\n        <Space size=\"small\">\n          <Tooltip title=\"刷新用户信息\">\n            <Button \n              type=\"text\" \n              size=\"small\"\n              icon={<ReloadOutlined spin={refreshingId === record.id} />}\n              onClick={() => onRefreshInfo(record.id)}\n              loading={refreshingId === record.id}\n            />\n          </Tooltip>\n          <Tooltip title=\"编辑\">\n            <Button \n              type=\"text\" \n              size=\"small\"\n              icon={<EditOutlined />}\n              onClick={() => onEdit(record)}\n            />\n          </Tooltip>\n          {!isConnected(record.id) ? (\n            <Tooltip title=\"启动\">\n              <Button \n                type=\"text\" \n                size=\"small\"\n                icon={<PlayCircleOutlined />}\n                onClick={() => onStart(record.id)}\n              />\n            </Tooltip>\n          ) : (\n            <Tooltip title=\"停止\">\n              <Button \n                type=\"text\" \n                size=\"small\"\n                icon={<StopOutlined />}\n                onClick={() => onStop(record.id)}\n              />\n            </Tooltip>\n          )}\n          <Popconfirm\n            title=\"确定删除该账号？\"\n            onConfirm={() => onDelete(record.id)}\n            okText=\"确定\"\n            cancelText=\"取消\"\n          >\n            <Tooltip title=\"删除\">\n              <Button \n                type=\"text\" \n                danger\n                size=\"small\"\n                icon={<DeleteOutlined />}\n              />\n            </Tooltip>\n          </Popconfirm>\n        </Space>\n      )\n    }\n  ]\n\n  return (\n    <div>\n      {/* 账号列表 */}\n      <Card style={{ marginBottom: 16 }}>\n        <Table\n          columns={columns}\n          dataSource={accounts}\n          rowKey=\"id\"\n          loading={loading}\n          pagination={false}\n          scroll={{ x: 'max-content' }}\n        />\n      </Card>\n\n      {/* 添加/编辑表单 */}\n      <Row gutter={16}>\n        <Col xs={24} md={12}>\n          <Card\n            title={editingId ? '编辑账号' : '添加账号'}\n            extra={!editingId && <QuestionCircleOutlined />}\n          >\n            <Form\n              form={form}\n              layout=\"vertical\"\n              onFinish={onFinish}\n            >\n              {editingId && (\n                <Form.Item label=\"账号ID\">\n                  <Input value={editingId} autoComplete=\"off\" disabled />\n                </Form.Item>\n              )}\n\n              {!editingId && (\n                <Form.Item\n                  label=\"Cookies\"\n                  name=\"cookies\"\n                  rules={[{ required: true, message: '请填写 Cookies' }]}\n                >\n                  <TextArea\n                    rows={4}\n                    placeholder=\"粘贴 Cookie 字符串，系统将自动获取用户信息\"\n                    style={{ fontFamily: 'monospace', fontSize: '12px' }}\n                  />\n                </Form.Item>\n              )}\n\n              <Form.Item label=\"备注\" name=\"remark\">\n                <Input placeholder=\"可选，方便识别\" autoComplete=\"off\" />\n              </Form.Item>\n\n              <Form.Item>\n                <Space style={{ width: '100%', justifyContent: 'flex-end' }}>\n                  {editingId && (\n                    <Button onClick={onCancelEdit}>\n                      取消\n                    </Button>\n                  )}\n                  <Button\n                    type=\"primary\"\n                    htmlType=\"submit\"\n                    loading={submitting}\n                    icon={editingId ? <EditOutlined /> : <PlusOutlined />}\n                  >\n                    {editingId ? '保存' : '添加'}\n                  </Button>\n                </Space>\n              </Form.Item>\n            </Form>\n          </Card>\n        </Col>\n\n        {/* 帮助卡片 */}\n        <Col xs={24} md={12}>\n          <Card size=\"small\">\n            <Space direction=\"vertical\" size=\"small\">\n              <Text strong><QuestionCircleOutlined /> 如何获取 Cookies？</Text>\n              <ol style={{ paddingLeft: 16, margin: 0, fontSize: '12px', color: '#999' }}>\n                <li>登录闲鱼网页版 (goofish.com)</li>\n                <li>按 F12 打开开发者工具</li>\n                <li>切换到 Network 标签</li>\n                <li>刷新页面，点击任意请求</li>\n                <li>在 Headers 中找到 Cookie</li>\n              </ol>\n            </Space>\n          </Card>\n        </Col>\n      </Row>\n    </div>\n  )\n}\n\nexport default Accounts\n"
  },
  {
    "path": "src/pages/goofish/AutoReply/index.tsx",
    "content": "import React, { useEffect, useState } from 'react'\nimport { \n  Card, \n  Form, \n  Input, \n  Button, \n  Switch, \n  Select, \n  Table, \n  Space, \n  message, \n  Popconfirm,\n  Row,\n  Col,\n  Tag,\n  Typography\n} from 'antd'\nimport { \n  PlusOutlined, \n  EditOutlined, \n  DeleteOutlined,\n  ReloadOutlined\n} from '@ant-design/icons'\nimport { autoReplyApi } from '@/services/goofish'\nimport type { AutoReplyRule } from '@/types/goofish'\n\nconst { TextArea } = Input\nconst { Option } = Select\nconst { Text } = Typography\n\nconst MATCH_TYPES = [\n  { value: 'exact', label: '精确匹配' },\n  { value: 'contains', label: '包含关键词' },\n  { value: 'regex', label: '正则表达式' }\n]\n\nconst AutoReply: React.FC = () => {\n  const [rules, setRules] = useState<AutoReplyRule[]>([])\n  const [loading, setLoading] = useState(false)\n  const [saving, setSaving] = useState(false)\n  const [editingId, setEditingId] = useState<number | null>(null)\n  const [form] = Form.useForm()\n\n  useEffect(() => {\n    loadRules()\n  }, [])\n\n  const loadRules = async () => {\n    setLoading(true)\n    try {\n      const response = await autoReplyApi.getRules()\n      setRules(response.data?.rules || [])\n    } catch (error) {\n      message.error('加载规则失败')\n    } finally {\n      setLoading(false)\n    }\n  }\n\n  const onFinish = async (values: any) => {\n    setSaving(true)\n    try {\n      if (editingId) {\n        await autoReplyApi.updateRule(editingId, values)\n        message.success('更新成功')\n      } else {\n        await autoReplyApi.createRule(values)\n        message.success('添加成功')\n      }\n      form.resetFields()\n      setEditingId(null)\n      loadRules()\n    } catch (error) {\n      message.error('操作失败')\n    } finally {\n      setSaving(false)\n    }\n  }\n\n  const onEdit = (record: AutoReplyRule) => {\n    setEditingId(record.id)\n    form.setFieldsValue(record)\n  }\n\n  const onCancelEdit = () => {\n    setEditingId(null)\n    form.resetFields()\n  }\n\n  const onDelete = async (id: number) => {\n    try {\n      await autoReplyApi.deleteRule(id)\n      message.success('删除成功')\n      loadRules()\n    } catch (error) {\n      message.error('删除失败')\n    }\n  }\n\n  const onToggleEnabled = async (id: number, enabled: boolean) => {\n    try {\n      await autoReplyApi.updateRule(id, { enabled })\n      message.success(enabled ? '已启用' : '已禁用')\n      loadRules()\n    } catch (error) {\n      message.error('操作失败')\n    }\n  }\n\n  const columns = [\n    {\n      title: '规则名称',\n      dataIndex: 'name',\n      key: 'name',\n      render: (name: string, record: AutoReplyRule) => (\n        <Space>\n          {name}\n          {!record.enabled && <Tag color=\"default\">已禁用</Tag>}\n        </Space>\n      )\n    },\n    {\n      title: '匹配方式',\n      dataIndex: 'matchType',\n      key: 'matchType',\n      render: (type: string) => {\n        const config = MATCH_TYPES.find(t => t.value === type)\n        return <Tag>{config?.label || type}</Tag>\n      }\n    },\n    {\n      title: '匹配内容',\n      dataIndex: 'matchPattern',\n      key: 'matchPattern',\n      ellipsis: true\n    },\n    {\n      title: '回复内容',\n      dataIndex: 'replyContent',\n      key: 'replyContent',\n      ellipsis: true,\n      render: (content: string) => (\n        <Text ellipsis={{ tooltip: content }} style={{ maxWidth: 200 }}>\n          {content}\n        </Text>\n      )\n    },\n    {\n      title: '优先级',\n      dataIndex: 'priority',\n      key: 'priority',\n      width: 80\n    },\n    {\n      title: '操作',\n      key: 'actions',\n      render: (_: any, record: AutoReplyRule) => (\n        <Space size=\"small\">\n          <Button\n            type=\"text\"\n            size=\"small\"\n            onClick={() => onToggleEnabled(record.id, !record.enabled)}\n          >\n            {record.enabled ? '禁用' : '启用'}\n          </Button>\n          <Button\n            type=\"text\"\n            size=\"small\"\n            icon={<EditOutlined />}\n            onClick={() => onEdit(record)}\n          >\n            编辑\n          </Button>\n          <Popconfirm\n            title=\"确定删除该规则？\"\n            onConfirm={() => onDelete(record.id)}\n            okText=\"确定\"\n            cancelText=\"取消\"\n          >\n            <Button\n              type=\"text\"\n              danger\n              size=\"small\"\n              icon={<DeleteOutlined />}\n            >\n              删除\n            </Button>\n          </Popconfirm>\n        </Space>\n      )\n    }\n  ]\n\n  return (\n    <div>\n      {/* 规则列表 */}\n      <Card style={{ marginBottom: 16 }}>\n        <Table\n          columns={columns}\n          dataSource={rules}\n          rowKey=\"id\"\n          loading={loading}\n          pagination={{ pageSize: 10 }}\n          scroll={{ x: 'max-content' }}\n        />\n      </Card>\n\n      {/* 添加/编辑表单 */}\n      <Row gutter={16}>\n        <Col xs={24} md={12}>\n          <Card\n            title={editingId ? '编辑规则' : '添加规则'}\n            extra={!editingId && <Button icon={<ReloadOutlined />} onClick={loadRules}>刷新</Button>}\n          >\n            <Form\n              form={form}\n              layout=\"vertical\"\n              onFinish={onFinish}\n              initialValues={{\n                enabled: true,\n                priority: 0,\n                matchType: 'exact'\n              }}\n            >\n              <Row gutter={16}>\n                <Col xs={24} md={12}>\n                  <Form.Item\n                    label=\"规则名称\"\n                    name=\"name\"\n                    rules={[{ required: true, message: '请输入规则名称' }]}\n                  >\n                    <Input placeholder=\"例如：问候语回复\" autoComplete=\"off\" />\n                  </Form.Item>\n                </Col>\n                <Col xs={24} md={12}>\n                  <Form.Item\n                    label=\"匹配方式\"\n                    name=\"matchType\"\n                    rules={[{ required: true }]}\n                  >\n                    <Select>\n                      {MATCH_TYPES.map(type => (\n                        <Option key={type.value} value={type.value}>\n                          {type.label}\n                        </Option>\n                      ))}\n                    </Select>\n                  </Form.Item>\n                </Col>\n              </Row>\n\n              <Form.Item\n                label=\"匹配内容\"\n                name=\"matchPattern\"\n                rules={[{ required: true, message: '请输入匹配内容' }]}\n                extra=\"消息内容必须完全等于此内容\"\n              >\n                <Input placeholder=\"输入要匹配的关键词\" autoComplete=\"off\" />\n              </Form.Item>\n\n              <Form.Item\n                label=\"回复内容\"\n                name=\"replyContent\"\n                rules={[{ required: true, message: '请输入回复内容' }]}\n              >\n                <TextArea rows={3} placeholder=\"输入回复内容\" />\n              </Form.Item>\n\n              <Row gutter={16}>\n                <Col xs={24} md={12}>\n                  <Form.Item\n                    label=\"优先级\"\n                    name=\"priority\"\n                    extra=\"数字越大优先级越高\"\n                  >\n                    <Input type=\"number\" placeholder=\"0\" />\n                  </Form.Item>\n                </Col>\n                <Col xs={24} md={12}>\n                  <Form.Item\n                    label=\"启用状态\"\n                    name=\"enabled\"\n                    valuePropName=\"checked\"\n                  >\n                    <Switch />\n                  </Form.Item>\n                </Col>\n              </Row>\n\n              <Form.Item>\n                <Space style={{ width: '100%', justifyContent: 'flex-end' }}>\n                  {editingId && (\n                    <Button onClick={onCancelEdit}>\n                      取消\n                    </Button>\n                  )}\n                  <Button\n                    type=\"primary\"\n                    htmlType=\"submit\"\n                    loading={saving}\n                    icon={editingId ? <EditOutlined /> : <PlusOutlined />}\n                  >\n                    {editingId ? '保存' : '添加'}\n                  </Button>\n                </Space>\n              </Form.Item>\n            </Form>\n          </Card>\n        </Col>\n\n        {/* 说明卡片 */}\n        <Col xs={24} md={12}>\n          <Card title=\"使用说明\" size=\"small\">\n            <Space direction=\"vertical\" size=\"small\">\n              <Text>自动回复规则会按照优先级从高到低依次匹配。</Text>\n              <Text strong>匹配方式说明：</Text>\n              <ul style={{ paddingLeft: 16, margin: 0, fontSize: '12px', color: '#666' }}>\n                <li><strong>精确匹配</strong>：消息内容必须完全等于匹配内容</li>\n                <li><strong>包含关键词</strong>：消息内容包含匹配内容即可触发</li>\n                <li><strong>正则表达式</strong>：使用正则表达式进行高级匹配</li>\n              </ul>\n              <Text type=\"secondary\" style={{ fontSize: '12px' }}>\n                提示：优先级数字越大，规则越先匹配。建议将常用规则设置较高优先级。\n              </Text>\n            </Space>\n          </Card>\n        </Col>\n      </Row>\n    </div>\n  )\n}\n\nexport default AutoReply\n"
  },
  {
    "path": "src/pages/goofish/AutoSell/index.tsx",
    "content": "import React, { useEffect, useState } from 'react'\nimport { \n  Card, \n  Form, \n  Input, \n  Button, \n  Switch, \n  Select, \n  Table, \n  Space, \n  message, \n  Popconfirm,\n  Row,\n  Col,\n  Tag,\n  Typography\n} from 'antd'\nimport { \n  PlusOutlined, \n  EditOutlined, \n  DeleteOutlined,\n  ReloadOutlined,\n  GiftOutlined\n} from '@ant-design/icons'\nimport { autoSellApi, accountApi } from '@/services/goofish'\nimport type { AutoSellRule } from '@/types/goofish'\n\nconst { TextArea } = Input\nconst { Option } = Select\nconst { Text } = Typography\n\nconst DELIVERY_TYPES = [\n  { value: 'static', label: '静态内容' },\n  { value: 'api', label: 'API 接口' }\n]\n\nconst AutoSell: React.FC = () => {\n  const [rules, setRules] = useState<AutoSellRule[]>([])\n  const [accounts, setAccounts] = useState<any[]>([])\n  const [loading, setLoading] = useState(false)\n  const [saving, setSaving] = useState(false)\n  const [editingId, setEditingId] = useState<number | null>(null)\n  const [form] = Form.useForm()\n  const [deliveryType, setDeliveryType] = useState<'static' | 'api'>('static')\n\n  useEffect(() => {\n    loadRules()\n    loadAccounts()\n  }, [])\n\n  const loadRules = async () => {\n    setLoading(true)\n    try {\n      const response = await autoSellApi.getRules()\n      setRules(response.data?.rules || [])\n    } catch (error) {\n      message.error('加载规则失败')\n    } finally {\n      setLoading(false)\n    }\n  }\n\n  const loadAccounts = async () => {\n    try {\n      const response = await accountApi.getAccounts()\n      setAccounts(response.data?.accounts || [])\n    } catch (error) {\n      console.error('加载账号失败:', error)\n    }\n  }\n\n  const onFinish = async (values: any) => {\n    setSaving(true)\n    try {\n      const data = {\n        ...values,\n        deliveryType: deliveryType,\n        apiConfig: deliveryType === 'api' ? JSON.stringify({\n          url: values.apiUrl,\n          method: values.apiMethod || 'GET',\n          headers: values.apiHeaders || '{}'\n        }) : undefined\n      }\n      \n      if (editingId) {\n        await autoSellApi.updateRule(editingId, data)\n        message.success('更新成功')\n      } else {\n        await autoSellApi.createRule(data)\n        message.success('添加成功')\n      }\n      form.resetFields()\n      setEditingId(null)\n      loadRules()\n    } catch (error) {\n      message.error('操作失败')\n    } finally {\n      setSaving(false)\n    }\n  }\n\n  const onEdit = (record: AutoSellRule) => {\n    setEditingId(record.id)\n    const type = record.deliveryType || 'static'\n    setDeliveryType(type as any)\n    \n    const formValues: any = {\n      name: record.name,\n      enabled: record.enabled,\n      itemId: record.itemId,\n      accountId: record.accountId,\n      triggerOn: record.triggerOn,\n      deliveryContent: record.deliveryContent\n    }\n    \n    if (type === 'api' && record.apiConfig) {\n      try {\n        const apiConfig = JSON.parse(record.apiConfig || '{}')\n        Object.assign(formValues, apiConfig)\n      } catch (e) {\n        console.error('解析 API 配置失败', e)\n      }\n    }\n    \n    form.setFieldsValue(formValues)\n  }\n\n  const onCancelEdit = () => {\n    setEditingId(null)\n    form.resetFields()\n    setDeliveryType('static')\n  }\n\n  const onDelete = async (id: number) => {\n    try {\n      await autoSellApi.deleteRule(id)\n      message.success('删除成功')\n      loadRules()\n    } catch (error) {\n      message.error('删除失败')\n    }\n  }\n\n  const columns = [\n    {\n      title: '规则名称',\n      dataIndex: 'name',\n      key: 'name',\n      render: (name: string, record: AutoSellRule) => (\n        <Space>\n          <GiftOutlined />\n          {name}\n          {!record.enabled && <Tag color=\"default\">已禁用</Tag>}\n        </Space>\n      )\n    },\n    {\n      title: '商品ID',\n      dataIndex: 'itemId',\n      key: 'itemId',\n      render: (itemId?: string) => itemId || <Text type=\"secondary\">全部商品</Text>\n    },\n    {\n      title: '发货方式',\n      dataIndex: 'deliveryType',\n      key: 'deliveryType',\n      render: (type: string) => {\n        const config = DELIVERY_TYPES.find(t => t.value === type)\n        return <Tag color={type === 'api' ? 'blue' : 'green'}>{config?.label || type}</Tag>\n      }\n    },\n    {\n      title: '触发时机',\n      dataIndex: 'triggerOn',\n      key: 'triggerOn',\n      render: (trigger: string) => (\n        <Tag>{trigger === 'paid' ? '付款后' : '下单后'}</Tag>\n      )\n    },\n    {\n      title: '操作',\n      key: 'actions',\n      render: (_: any, record: AutoSellRule) => (\n        <Space size=\"small\">\n          <Button\n            type=\"text\"\n            size=\"small\"\n            icon={<EditOutlined />}\n            onClick={() => onEdit(record)}\n          >\n            编辑\n          </Button>\n          <Popconfirm\n            title=\"确定删除该规则？\"\n            onConfirm={() => onDelete(record.id)}\n            okText=\"确定\"\n            cancelText=\"取消\"\n          >\n            <Button\n              type=\"text\"\n              danger\n              size=\"small\"\n              icon={<DeleteOutlined />}\n            >\n              删除\n            </Button>\n          </Popconfirm>\n        </Space>\n      )\n    }\n  ]\n\n  return (\n    <div>\n      {/* 规则列表 */}\n      <Card style={{ marginBottom: 16 }}>\n        <Table\n          columns={columns}\n          dataSource={rules}\n          rowKey=\"id\"\n          loading={loading}\n          pagination={{ pageSize: 10 }}\n          scroll={{ x: 'max-content' }}\n        />\n      </Card>\n\n      {/* 添加/编辑表单 */}\n      <Row gutter={16}>\n        <Col xs={24} md={12}>\n          <Card\n            title={editingId ? '编辑规则' : '添加规则'}\n            extra={!editingId && <Button icon={<ReloadOutlined />} onClick={loadRules}>刷新</Button>}\n          >\n            <Form\n              form={form}\n              layout=\"vertical\"\n              onFinish={onFinish}\n              initialValues={{\n                enabled: true,\n                triggerOn: 'paid',\n                apiMethod: 'GET'\n              }}\n            >\n              <Row gutter={16}>\n                <Col xs={24} md={12}>\n                  <Form.Item\n                    label=\"规则名称\"\n                    name=\"name\"\n                    rules={[{ required: true, message: '请输入规则名称' }]}\n                  >\n                    <Input placeholder=\"例如：虚拟商品自动发货\" autoComplete=\"off\" />\n                  </Form.Item>\n                </Col>\n                <Col xs={24} md={12}>\n                  <Form.Item\n                    label=\"触发时机\"\n                    name=\"triggerOn\"\n                    rules={[{ required: true }]}\n                  >\n                    <Select>\n                      <Option value=\"paid\">付款后</Option>\n                      <Option value=\"ordered\">下单后</Option>\n                    </Select>\n                  </Form.Item>\n                </Col>\n              </Row>\n\n              <Row gutter={16}>\n                <Col xs={24} md={12}>\n                  <Form.Item\n                    label=\"商品ID\"\n                    name=\"itemId\"\n                    extra=\"留空则适用于所有商品\"\n                  >\n                    <Input placeholder=\"输入商品ID\" autoComplete=\"off\" />\n                  </Form.Item>\n                </Col>\n                <Col xs={24} md={12}>\n                  <Form.Item\n                    label=\"关联账号\"\n                    name=\"accountId\"\n                    extra=\"留空则适用于所有账号\"\n                  >\n                    <Select placeholder=\"选择账号\" allowClear>\n                      {accounts.map(account => (\n                        <Option key={account.id} value={account.id}>\n                          {account.nickname || account.id}\n                        </Option>\n                      ))}\n                    </Select>\n                  </Form.Item>\n                </Col>\n              </Row>\n\n              <Form.Item label=\"发货方式\">\n                <Select\n                  value={deliveryType}\n                  onChange={(value) => setDeliveryType(value as any)}\n                >\n                  <Option value=\"static\">静态发货</Option>\n                  <Option value=\"api\">API 发货</Option>\n                </Select>\n              </Form.Item>\n\n              {deliveryType === 'static' ? (\n                <Form.Item\n                  label=\"发货内容\"\n                  name=\"deliveryContent\"\n                  rules={[{ required: true, message: '请输入发货内容' }]}\n                  extra=\"支持变量：{订单号}、{商品名}、{买家昵称}\"\n                >\n                  <TextArea rows={4} placeholder=\"例如：您的卡密是：ABC123\" />\n                </Form.Item>\n              ) : (\n                <>\n                  <Form.Item\n                    label=\"API 地址\"\n                    name=\"apiUrl\"\n                    rules={[{ required: true, message: '请输入 API 地址' }]}\n                  >\n                    <Input placeholder=\"https://api.example.com/deliver\" autoComplete=\"off\" />\n                  </Form.Item>\n                  <Row gutter={16}>\n                    <Col xs={24} md={12}>\n                      <Form.Item\n                        label=\"请求方法\"\n                        name=\"apiMethod\"\n                      >\n                        <Select>\n                          <Option value=\"GET\">GET</Option>\n                          <Option value=\"POST\">POST</Option>\n                        </Select>\n                      </Form.Item>\n                    </Col>\n                    <Col xs={24} md={12}>\n                      <Form.Item\n                        label=\"启用状态\"\n                        name=\"enabled\"\n                        valuePropName=\"checked\"\n                      >\n                        <Switch />\n                      </Form.Item>\n                    </Col>\n                  </Row>\n                  <Form.Item\n                    label=\"请求头\"\n                    name=\"apiHeaders\"\n                    extra='JSON 格式，例如：{\"Authorization\": \"Bearer xxx\"}'\n                  >\n                    <TextArea rows={2} placeholder='{\"Authorization\": \"Bearer xxx\"}' />\n                  </Form.Item>\n                </>\n              )}\n\n              {deliveryType === 'static' && (\n                <Form.Item\n                  label=\"启用状态\"\n                  name=\"enabled\"\n                  valuePropName=\"checked\"\n                >\n                  <Switch />\n                </Form.Item>\n              )}\n\n              <Form.Item>\n                <Space style={{ width: '100%', justifyContent: 'flex-end' }}>\n                  {editingId && (\n                    <Button onClick={onCancelEdit}>\n                      取消\n                    </Button>\n                  )}\n                  <Button\n                    type=\"primary\"\n                    htmlType=\"submit\"\n                    loading={saving}\n                    icon={editingId ? <EditOutlined /> : <PlusOutlined />}\n                  >\n                    {editingId ? '保存' : '添加'}\n                  </Button>\n                </Space>\n              </Form.Item>\n            </Form>\n          </Card>\n        </Col>\n\n        {/* 说明卡片 */}\n        <Col xs={24} md={12}>\n          <Card title=\"使用说明\" size=\"small\">\n            <Space direction=\"vertical\" size=\"small\">\n              <Text>自动发货规则会在订单触发指定条件后自动执行发货操作。</Text>\n              <Text strong>发货方式说明：</Text>\n              <ul style={{ paddingLeft: 16, margin: 0, fontSize: '12px', color: '#666' }}>\n                <li><strong>静态发货</strong>：直接返回预设的文本内容，支持变量</li>\n                <li><strong>API 发货</strong>：调用外部 API 接口获取发货内容</li>\n              </ul>\n              <Text strong style={{ marginTop: 8 }}>支持的变量：</Text>\n              <ul style={{ paddingLeft: 16, margin: 0, fontSize: '12px', color: '#666' }}>\n                <li><code>{\"{订单号}\"}</code> - 订单编号</li>\n                <li><code>{\"{商品名}\"}</code> - 商品名称</li>\n                <li><code>{\"{买家昵称}\"}</code> - 买家昵称</li>\n              </ul>\n              <Text type=\"secondary\" style={{ fontSize: '12px' }}>\n                提示：商品ID和账号ID留空时，规则将应用于所有商品和所有账号。\n              </Text>\n            </Space>\n          </Card>\n        </Col>\n      </Row>\n    </div>\n  )\n}\n\nexport default AutoSell\n"
  },
  {
    "path": "src/pages/goofish/Conversations/index.tsx",
    "content": "import React, { useEffect, useState, useRef } from 'react'\nimport { \n  Layout, \n  List, \n  Input, \n  Button, \n  Avatar, \n  Badge, \n  Space, \n  Typography, \n  message,\n  Spin,\n  Empty\n} from 'antd'\nimport { \n  SendOutlined, \n  UserOutlined,\n  MessageOutlined\n} from '@ant-design/icons'\nimport { useGoofishWebSocket } from '@/hooks/goofish'\nimport { conversationApi, messageApi } from '@/services/goofish'\nimport type { Conversation } from '@/types/goofish'\n\nconst { TextArea } = Input\nconst { Sider, Content } = Layout\nconst { Text } = Typography\n\ninterface MessageItem {\n  id?: number\n  senderId?: string\n  senderName?: string\n  content?: string\n  direction?: 'in' | 'out'\n  msgTime?: string\n  timestamp?: number\n}\n\nexport const Conversations: React.FC = () => {\n  const { connected, ws } = useGoofishWebSocket({\n    onMessage: (data) => {\n      console.log('[Conversations] 收到 WebSocket 消息:', data)\n      // 处理 WebSocket 对话更新消息\n      if (data.event === 'conversations' && data.data) {\n        handleConversationsUpdate(data.data)\n      }\n    }\n  })\n  const messagesEndRef = useRef<HTMLDivElement>(null)\n\n  const [conversations, setConversations] = useState<Conversation[]>([])\n  const [selectedConversation, setSelectedConversation] = useState<Conversation | null>(null)\n  const [messages, setMessages] = useState<MessageItem[]>([])\n  const [loading, setLoading] = useState(false)\n  const [messagesLoading, setMessagesLoading] = useState(false)\n  const [sending, setSending] = useState(false)\n  const [inputText, setInputText] = useState('')\n  const [isMobile, setIsMobile] = useState(false)\n  const [showChat, setShowChat] = useState(false)\n  const subscribedRef = useRef(false)\n\n  useEffect(() => {\n    loadConversations()\n    const checkMobile = () => {\n      setIsMobile(window.innerWidth < 768)\n    }\n    checkMobile()\n    window.addEventListener('resize', checkMobile)\n    return () => window.removeEventListener('resize', checkMobile)\n  }, [])\n\n  // 订阅 WebSocket 对话更新\n  useEffect(() => {\n    if (ws?.readyState === WebSocket.OPEN && !subscribedRef.current) {\n      console.log('[Conversations] 订阅对话更新')\n      ws.send(JSON.stringify({\n        action: 'subscribe',\n        events: ['conversations'],\n        params: { limit: 50 }\n      }))\n      subscribedRef.current = true\n    }\n\n    return () => {\n      if (ws?.readyState === WebSocket.OPEN && subscribedRef.current) {\n        console.log('[Conversations] 取消订阅对话更新')\n        ws.send(JSON.stringify({\n          action: 'unsubscribe',\n          events: ['conversations']\n        }))\n        subscribedRef.current = false\n      }\n    }\n  }, [ws])\n\n  // 处理 WebSocket 对话更新\n  const handleConversationsUpdate = (data: { conversations?: Conversation[]; total?: number }) => {\n    const { conversations: newConversations } = data\n\n    console.log('[Conversations] 处理对话更新:', newConversations?.length, '个对话')\n\n    if (!newConversations || newConversations.length === 0) {\n      console.log('[Conversations] 没有新对话，跳过更新')\n      return\n    }\n\n    // 更新对话列表\n    setConversations(prevConversations => {\n      const updatedMap = new Map()\n\n      // 先添加新对话数据\n      for (const conv of newConversations) {\n        updatedMap.set(conv.chatId, conv)\n      }\n\n      // 保留旧数据中不在新数据里的对话\n      for (const conv of prevConversations) {\n        if (!updatedMap.has(conv.chatId)) {\n          updatedMap.set(conv.chatId, conv)\n        }\n      }\n\n      // 转换为数组并排序（最新的在前面）\n      return Array.from(updatedMap.values()).sort((a, b) => {\n        const timeA = Number(a.lastTime || 0)\n        const timeB = Number(b.lastTime || 0)\n        return timeB - timeA\n      })\n    })\n\n    // 如果当前正在查看某个对话，检查是否有新消息\n    if (selectedConversation) {\n      const updatedConv = newConversations.find(c => c.chatId === selectedConversation.chatId)\n      if (updatedConv && updatedConv.unread > 0) {\n        // 对话有新消息，重新加载消息\n        conversationApi.getConversation(selectedConversation.chatId).then(response => {\n          const newMessages = response.data?.messages || []\n          setMessages(newMessages)\n        }).catch(error => {\n          console.error('加载消息失败:', error)\n        })\n\n        // 更新当前对话的信息（未读数、最后消息等）\n        setSelectedConversation(updatedConv)\n      }\n    }\n  }\n\n  const formatTime = (time?: string | number): string => {\n    if (!time) return ''\n\n    let date: Date\n\n    // 处理数字时间戳（毫秒）\n    if (typeof time === 'number') {\n      date = new Date(time)\n    } else {\n      // 处理字符串时间 - 尝试多种格式\n      // 尝试标准格式\n      date = new Date(time)\n\n      // 如果解析失败，尝试 \"2026/2/27 20:49:11\" 格式\n      if (isNaN(date.getTime())) {\n        const parts = time.split(' ')\n        if (parts.length === 2) {\n          const datePart = parts[0].replace(/\\//g, '-')\n          const timePart = parts[1]\n          date = new Date(`${datePart} ${timePart}`)\n        }\n      }\n\n      // 如果还是失败，尝试 Unix 时间戳字符串\n      if (isNaN(date.getTime())) {\n        const timestamp = parseInt(time)\n        if (!isNaN(timestamp)) {\n          date = new Date(timestamp)\n        }\n      }\n    }\n\n    if (isNaN(date.getTime())) {\n      console.warn('Invalid date format:', time)\n      return String(time)\n    }\n\n    const now = new Date()\n    const diff = now.getTime() - date.getTime()\n\n    // 如果是未来的时间，直接返回格式化的日期时间\n    if (diff < 0) {\n      return date.toLocaleString('zh-CN', {\n        month: '2-digit',\n        day: '2-digit',\n        hour: '2-digit',\n        minute: '2-digit'\n      })\n    }\n\n    if (diff < 60000) return '刚刚'\n    if (diff < 3600000) return `${Math.floor(diff / 60000)}分钟前`\n    if (diff < 86400000) return `${Math.floor(diff / 3600000)}小时前`\n    if (diff < 604800000) return `${Math.floor(diff / 86400000)}天前`\n\n    // 超过7天显示具体日期\n    return date.toLocaleDateString('zh-CN')\n  }\n\n  const loadConversations = async () => {\n    setLoading(true)\n    try {\n      const response = await conversationApi.getConversations({ limit: 50, offset: 0 })\n      setConversations(response.data?.conversations || [])\n    } catch (error) {\n      message.error('加载对话列表失败')\n    } finally {\n      setLoading(false)\n    }\n  }\n\n  const selectConversation = async (conversation: Conversation) => {\n    setSelectedConversation(conversation)\n    setMessagesLoading(true)\n\n    // 标记对话为已读\n    try {\n      await conversationApi.markAsRead(conversation.chatId, conversation.accountId)\n      // 更新对话列表中的未读数\n      setConversations(prev =>\n        prev.map(c =>\n          c.chatId === conversation.chatId ? { ...c, unread: 0 } : c\n        )\n      )\n    } catch (error) {\n      console.error('标记已读失败:', error)\n    }\n\n    try {\n      const response = await conversationApi.getConversation(conversation.chatId)\n      setMessages(response.data?.messages || [])\n      if (isMobile) {\n        setShowChat(true)\n      }\n    } catch (error) {\n      message.error('加载消息失败')\n    } finally {\n      setMessagesLoading(false)\n    }\n  }\n\n  const backToList = () => {\n    setShowChat(false)\n    setSelectedConversation(null)\n  }\n\n  const sendMessage = async () => {\n    if (!inputText.trim() || !selectedConversation) {\n      message.warning('请输入消息内容')\n      return\n    }\n\n    setSending(true)\n    try {\n      await messageApi.sendMessage({\n        accountId: selectedConversation.accountId,\n        chatId: selectedConversation.chatId,\n        toUserId: selectedConversation.userId,\n        text: inputText.trim()\n      })\n      \n      // 添加消息到列表\n      setMessages(prev => [...prev, {\n        content: inputText.trim(),\n        direction: 'out' as const,\n        msgTime: new Date().toLocaleString('zh-CN'),\n        timestamp: Date.now()\n      }])\n      \n      setInputText('')\n      message.success('发送成功')\n    } catch (error) {\n      message.error('发送失败')\n    } finally {\n      setSending(false)\n    }\n  }\n\n  return (\n    <div style={{ height: isMobile ? 'calc(100vh - 120px)' : 'calc(100vh - 180px)' }}>\n      <Layout style={{ height: '100%', background: '#fff', borderRadius: 8 }}>\n        {/* 移动端：显示列表或聊天界面 */}\n        {isMobile ? (\n          showChat && selectedConversation ? (\n            // 移动端聊天界面\n            <Layout style={{ display: 'flex', flexDirection: 'column' }}>\n              {/* 头部 */}\n              <div style={{\n                padding: isMobile ? '8px 12px' : '12px 16px',\n                borderBottom: '1px solid #e8e8e8',\n                background: '#fafafa',\n                display: 'flex',\n                alignItems: 'center',\n                gap: 8\n              }}>\n                <Button\n                  type=\"text\"\n                  size=\"small\"\n                  onClick={backToList}\n                  style={{ flexShrink: 0 }}\n                >\n                  ← 返回\n                </Button>\n                <Avatar\n                  size={32}\n                  src={selectedConversation.userAvatar}\n                  icon={!selectedConversation.userAvatar && <UserOutlined />}\n                />\n                <div style={{ flex: 1, minWidth: 0 }}>\n                  <Text strong style={{ fontSize: isMobile ? 14 : undefined }}>{selectedConversation.userName}</Text>\n                  <br />\n                  <Text type=\"secondary\" style={{ fontSize: '11px' }}>\n                    {selectedConversation.userId}\n                  </Text>\n                </div>\n              </div>\n\n              {/* 消息列表 */}\n              <Content style={{\n                padding: isMobile ? '8px' : '16px',\n                overflowY: 'auto',\n                background: '#f5f5f5',\n                flex: 1\n              }}>\n                <Spin spinning={messagesLoading}>\n                  {messages.length === 0 ? (\n                    <Empty\n                      description=\"暂无消息\"\n                      style={{ marginTop: 100 }}\n                    />\n                  ) : (\n                    <Space direction=\"vertical\" style={{ width: '100%' }} size=\"middle\">\n                      {messages.map((msg, index) => (\n                        <div\n                          key={index}\n                          style={{\n                            display: 'flex',\n                            justifyContent: msg.direction === 'out' ? 'flex-end' : 'flex-start',\n                            gap: 8\n                          }}\n                        >\n                          {msg.direction === 'in' && (\n                            <Avatar\n                              size={32}\n                              src={selectedConversation.userAvatar}\n                              icon={<UserOutlined />}\n                              style={{ flexShrink: 0 }}\n                            />\n                          )}\n                          <div style={{\n                            display: 'flex',\n                            flexDirection: 'column',\n                            alignItems: msg.direction === 'out' ? 'flex-end' : 'flex-start',\n                            maxWidth: isMobile ? 250 : 400\n                          }}>\n                            <div style={{\n                              padding: '10px 14px',\n                              borderRadius: 12,\n                              background: msg.direction === 'out' ? '#1890ff' : '#fff',\n                              color: msg.direction === 'out' ? '#fff' : '#000',\n                              wordBreak: 'break-word',\n                              fontSize: isMobile ? 13 : 14,\n                              boxShadow: '0 1px 2px rgba(0,0,0,0.1)'\n                            }}>\n                              {msg.content}\n                            </div>\n                            <Text\n                              type=\"secondary\"\n                              style={{ fontSize: '11px', marginTop: 4, display: 'block' }}\n                            >\n                              {formatTime(msg.msgTime || msg.timestamp)}\n                            </Text>\n                          </div>\n                          {msg.direction === 'out' && (\n                            <Avatar\n                              size={32}\n                              icon={<UserOutlined />}\n                              style={{ flexShrink: 0, backgroundColor: '#1890ff' }}\n                            />\n                          )}\n                        </div>\n                      ))}\n                      <div ref={messagesEndRef} />\n                    </Space>\n                  )}\n                </Spin>\n              </Content>\n\n              {/* 输入框 */}\n              <div style={{\n                padding: isMobile ? '8px 12px' : '12px 16px',\n                borderTop: '1px solid #e8e8e8',\n                background: '#fff'\n              }}>\n                <Space.Compact style={{ width: '100%' }}>\n                  <TextArea\n                    value={inputText}\n                    onChange={(e) => setInputText(e.target.value)}\n                    placeholder=\"输入消息...\"\n                    autoSize={{ minRows: 1, maxRows: 4 }}\n                    onPressEnter={(e) => {\n                      if (!e.shiftKey) {\n                        e.preventDefault()\n                        sendMessage()\n                      }\n                    }}\n                  />\n                  <Button\n                    type=\"primary\"\n                    icon={<SendOutlined />}\n                    loading={sending}\n                    onClick={sendMessage}\n                  >\n                    发送\n                  </Button>\n                </Space.Compact>\n              </div>\n            </Layout>\n          ) : (\n            // 移动端对话列表\n            <div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>\n              <div style={{ padding: isMobile ? '12px' : '16px', borderBottom: '1px solid #e8e8e8' }}>\n                <Space>\n                  <MessageOutlined />\n                  <Text strong>对话列表</Text>\n                  {connected ? (\n                    <Badge status=\"success\" text=\"已连接\" />\n                  ) : (\n                    <Badge status=\"error\" text=\"未连接\" />\n                  )}\n                </Space>\n              </div>\n\n              <Spin spinning={loading} style={{ flex: 1, overflow: 'auto' }}>\n                <List\n                  dataSource={conversations}\n                  renderItem={(item) => (\n                    <List.Item\n                      key={item.chatId}\n                      style={{\n                        padding: isMobile ? '10px 12px' : '12px 16px',\n                        cursor: 'pointer',\n                        background: selectedConversation?.chatId === item.chatId ? '#e6f7ff' : 'transparent'\n                      }}\n                      onClick={() => selectConversation(item)}\n                    >\n                      <List.Item.Meta\n                        avatar={\n                          <Avatar\n                            size={isMobile ? 36 : 40}\n                            src={item.userAvatar}\n                            icon={!item.userAvatar && <UserOutlined />}\n                          />\n                        }\n                        title={\n                          <div style={{ display: 'flex', justifyContent: 'space-between' }}>\n                            <Text strong style={{ fontSize: isMobile ? 14 : undefined }}>{item.userName}</Text>\n                            {item.unread > 0 && (\n                              <Badge count={item.unread} size=\"small\" />\n                            )}\n                          </div>\n                        }\n                        description={\n                          <div>\n                            <Text\n                              ellipsis={{ tooltip: item.lastMessage }}\n                              style={{ fontSize: '12px' }}\n                            >\n                              {item.lastMessage || '暂无消息'}\n                            </Text>\n                            <div style={{ fontSize: '11px', color: '#999', marginTop: 4 }}>\n                              {formatTime(item.lastTime ? String(item.lastTime) : undefined)}\n                            </div>\n                          </div>\n                        }\n                      />\n                    </List.Item>\n                  )}\n                />\n              </Spin>\n            </div>\n          )\n        ) : (\n          // 桌面端：左右分栏布局\n          <>\n            <Sider width={300} style={{ background: '#f5f5f5', borderRight: '1px solid #e8e8e8' }}>\n              <div style={{ padding: '16px', borderBottom: '1px solid #e8e8e8' }}>\n                <Space>\n                  <MessageOutlined />\n                  <Text strong>对话列表</Text>\n                  {connected ? (\n                    <Badge status=\"success\" text=\"已连接\" />\n                  ) : (\n                    <Badge status=\"error\" text=\"未连接\" />\n                  )}\n                </Space>\n              </div>\n\n              <Spin spinning={loading}>\n                <List\n                  dataSource={conversations}\n                  renderItem={(item) => (\n                    <List.Item\n                      key={item.chatId}\n                      style={{\n                        padding: '12px 16px',\n                        cursor: 'pointer',\n                        background: selectedConversation?.chatId === item.chatId ? '#e6f7ff' : 'transparent'\n                      }}\n                      onClick={() => selectConversation(item)}\n                    >\n                      <List.Item.Meta\n                        avatar={\n                          <Avatar\n                            size={40}\n                            src={item.userAvatar}\n                            icon={!item.userAvatar && <UserOutlined />}\n                          />\n                        }\n                        title={\n                          <div style={{ display: 'flex', justifyContent: 'space-between' }}>\n                            <Text strong>{item.userName}</Text>\n                            {item.unread > 0 && (\n                              <Badge count={item.unread} size=\"small\" />\n                            )}\n                          </div>\n                        }\n                        description={\n                          <div>\n                            <Text\n                              ellipsis={{ tooltip: item.lastMessage }}\n                              style={{ fontSize: '12px' }}\n                            >\n                              {item.lastMessage || '暂无消息'}\n                            </Text>\n                            <div style={{ fontSize: '11px', color: '#999', marginTop: 4 }}>\n                              {formatTime(item.lastTime ? String(item.lastTime) : undefined)}\n                            </div>\n                          </div>\n                        }\n                      />\n                    </List.Item>\n                  )}\n                />\n              </Spin>\n            </Sider>\n\n            {/* 右侧消息区域 */}\n            <Layout>\n              {selectedConversation ? (\n                <>\n                  {/* 头部 */}\n                  <div style={{\n                    padding: '12px 16px',\n                    borderBottom: '1px solid #e8e8e8',\n                    background: '#fafafa'\n                  }}>\n                    <Space>\n                      <Avatar\n                        size={32}\n                        src={selectedConversation.userAvatar}\n                        icon={!selectedConversation.userAvatar && <UserOutlined />}\n                      />\n                      <div>\n                        <Text strong>{selectedConversation.userName}</Text>\n                        <br />\n                        <Text type=\"secondary\" style={{ fontSize: '12px' }}>\n                          {selectedConversation.userId}\n                        </Text>\n                      </div>\n                    </Space>\n                  </div>\n\n                  {/* 消息列表 */}\n                  <Content style={{\n                    padding: '16px',\n                    overflowY: 'auto',\n                    background: '#f5f5f5'\n                  }}>\n                    <Spin spinning={messagesLoading}>\n                      {messages.length === 0 ? (\n                        <Empty\n                          description=\"暂无消息\"\n                          style={{ marginTop: 100 }}\n                        />\n                      ) : (\n                        <Space direction=\"vertical\" style={{ width: '100%' }} size=\"middle\">\n                          {messages.map((msg, index) => (\n                            <div\n                              key={index}\n                              style={{\n                                display: 'flex',\n                                justifyContent: msg.direction === 'out' ? 'flex-end' : 'flex-start',\n                                gap: 8\n                              }}\n                            >\n                              {msg.direction === 'in' && (\n                                <Avatar\n                                  size={32}\n                                  src={selectedConversation.userAvatar}\n                                  icon={<UserOutlined />}\n                                  style={{ flexShrink: 0 }}\n                                />\n                              )}\n                              <div style={{\n                                display: 'flex',\n                                flexDirection: 'column',\n                                alignItems: msg.direction === 'out' ? 'flex-end' : 'flex-start',\n                                maxWidth: 400\n                              }}>\n                                <div style={{\n                                  padding: '10px 14px',\n                                  borderRadius: 12,\n                                  background: msg.direction === 'out' ? '#1890ff' : '#fff',\n                                  color: msg.direction === 'out' ? '#fff' : '#000',\n                                  wordBreak: 'break-word',\n                                  fontSize: 14,\n                                  boxShadow: '0 1px 2px rgba(0,0,0,0.1)'\n                                }}>\n                                  {msg.content}\n                                </div>\n                                <Text\n                                  type=\"secondary\"\n                                  style={{ fontSize: '11px', marginTop: 4, display: 'block' }}\n                                >\n                                  {formatTime(msg.msgTime || msg.timestamp)}\n                                </Text>\n                              </div>\n                              {msg.direction === 'out' && (\n                                <Avatar\n                                  size={32}\n                                  icon={<UserOutlined />}\n                                  style={{ flexShrink: 0, backgroundColor: '#1890ff' }}\n                                />\n                              )}\n                            </div>\n                          ))}\n                          <div ref={messagesEndRef} />\n                        </Space>\n                      )}\n                    </Spin>\n                  </Content>\n\n                  {/* 输入框 */}\n                  <div style={{\n                    padding: '12px 16px',\n                    borderTop: '1px solid #e8e8e8',\n                    background: '#fff'\n                  }}>\n                    <Space.Compact style={{ width: '100%' }}>\n                      <TextArea\n                        value={inputText}\n                        onChange={(e) => setInputText(e.target.value)}\n                        placeholder=\"输入消息...\"\n                        autoSize={{ minRows: 1, maxRows: 4 }}\n                        onPressEnter={(e) => {\n                          if (!e.shiftKey) {\n                            e.preventDefault()\n                            sendMessage()\n                          }\n                        }}\n                      />\n                      <Button\n                        type=\"primary\"\n                        icon={<SendOutlined />}\n                        loading={sending}\n                        onClick={sendMessage}\n                      >\n                        发送\n                      </Button>\n                    </Space.Compact>\n                  </div>\n                </>\n              ) : (\n                <div style={{\n                  display: 'flex',\n                  alignItems: 'center',\n                  justifyContent: 'center',\n                  height: '100%',\n                  background: '#f5f5f5'\n                }}>\n                  <Empty description=\"选择一个对话开始聊天\" />\n                </div>\n              )}\n            </Layout>\n          </>\n        )}\n      </Layout>\n    </div>\n  )\n}\n"
  },
  {
    "path": "src/pages/goofish/Dashboard/index.tsx",
    "content": "import React, { useEffect, useState } from 'react'\nimport { Card, Row, Col, Statistic, Badge, Space, Alert } from 'antd'\nimport { \n  UserOutlined, \n  MessageOutlined, \n  CheckCircleOutlined,\n  WarningOutlined\n} from '@ant-design/icons'\nimport { useGoofishWebSocket } from '@/hooks/goofish'\nimport { accountApi } from '@/services/goofish'\n\nconst Dashboard: React.FC = () => {\n  const { connected, status, refetchStatus } = useGoofishWebSocket({\n    onMessage: (data) => {\n      if (data.type === 'status') {\n        refetchStatus()\n      }\n    }\n  })\n  \n  const [accounts, setAccounts] = useState<any[]>([])\n  const [loading, setLoading] = useState(false)\n\n  useEffect(() => {\n    loadAccounts()\n  }, [])\n\n  const loadAccounts = async () => {\n    setLoading(true)\n    try {\n      const response = await accountApi.getAccounts()\n      setAccounts(response.data?.accounts || [])\n    } catch (error) {\n      console.error('Failed to load accounts:', error)\n    } finally {\n      setLoading(false)\n    }\n  }\n\n  const activeAccounts = accounts.filter(a => a.enabled).length\n  const connectedAccounts = status?.clients?.filter((c: any) => c.connected).length || 0\n\n  return (\n    <div>\n      <Space direction=\"vertical\" size=\"large\" style={{ width: '100%' }}>\n        {/* 警告信息 */}\n        {!connected && (\n          <Alert\n            message=\"服务离线\"\n            description=\"无法连接到 Goofish 服务器，请检查服务是否正常运行。\"\n            type=\"warning\"\n            showIcon\n            icon={<WarningOutlined />}\n            closable\n          />\n        )}\n\n        {/* 警告信息 */}\n        {!connected && (\n          <Alert\n            message=\"服务离线\"\n            description=\"无法连接到 Goofish 服务器，请检查服务是否正常运行。\"\n            type=\"warning\"\n            showIcon\n            icon={<WarningOutlined />}\n          />\n        )}\n\n        {/* 统计卡片 */}\n        <Row gutter={[16, 16]}>\n          <Col xs={24} sm={12} md={6}>\n            <Card>\n              <Statistic\n                title=\"账号总数\"\n                value={accounts.length}\n                prefix={<UserOutlined />}\n                loading={loading}\n              />\n            </Card>\n          </Col>\n          <Col xs={24} sm={12} md={6}>\n            <Card>\n              <Statistic\n                title=\"启用账号\"\n                value={activeAccounts}\n                prefix={<CheckCircleOutlined />}\n                loading={loading}\n              />\n            </Card>\n          </Col>\n          <Col xs={24} sm={12} md={6}>\n            <Card>\n              <Statistic\n                title=\"在线账号\"\n                value={connectedAccounts}\n                prefix={<CheckCircleOutlined />}\n                valueStyle={{ color: connectedAccounts === activeAccounts ? '#3f8600' : '#cf1322' }}\n                loading={loading}\n              />\n            </Card>\n          </Col>\n          <Col xs={24} sm={12} md={6}>\n            <Card>\n              <Statistic\n                title=\"消息总数\"\n                value={status?.messageCount || 0}\n                prefix={<MessageOutlined />}\n                loading={loading}\n              />\n            </Card>\n          </Col>\n        </Row>\n\n        {/* 账号状态列表 */}\n        <Card title=\"账号状态\" extra={<a onClick={loadAccounts}>刷新</a>}>\n          {accounts.length === 0 ? (\n            <div style={{ textAlign: 'center', padding: '40px', color: '#999' }}>\n              暂无账号，请先添加账号\n            </div>\n          ) : (\n            <Space direction=\"vertical\" style={{ width: '100%' }} size=\"middle\">\n              {accounts.map(account => {\n                const clientStatus = status?.clients?.find((c: any) => c.accountId === account.id)\n                const isConnected = clientStatus?.connected || false\n                \n                return (\n                  <div key={account.id} style={{ \n                    display: 'flex', \n                    justifyContent: 'space-between',\n                    alignItems: 'center',\n                    padding: '12px',\n                    background: '#fafafa',\n                    borderRadius: '8px'\n                  }}>\n                    <Space>\n                      {account.avatar && (\n                        <img \n                          src={account.avatar} \n                          alt=\"\" \n                          style={{ width: 40, height: 40, borderRadius: '50%' }}\n                        />\n                      )}\n                      <div>\n                        <div style={{ fontWeight: 500 }}>\n                          {account.nickname || account.userId || '未命名账号'}\n                        </div>\n                        <div style={{ fontSize: '12px', color: '#999' }}>\n                          ID: {account.id} {account.remark && `(${account.remark})`}\n                        </div>\n                      </div>\n                    </Space>\n                    <Space>\n                      <Badge \n                        status={account.enabled ? (isConnected ? 'success' : 'warning') : 'default'} \n                        text={\n                          !account.enabled ? '已禁用' : \n                          isConnected ? '已连接' : '未连接'\n                        } \n                      />\n                    </Space>\n                  </div>\n                )\n              })}\n            </Space>\n          )}\n        </Card>\n      </Space>\n    </div>\n  )\n}\n\nexport default Dashboard\n"
  },
  {
    "path": "src/pages/goofish/Goods/index.tsx",
    "content": "import React, { useEffect, useState } from 'react'\nimport {\n  Card,\n  Row,\n  Col,\n  Image,\n  Tag,\n  Button,\n  Select,\n  Space,\n  Typography,\n  Badge,\n  Tooltip,\n  Spin,\n  Empty,\n  message\n} from 'antd'\nimport {\n  ReloadOutlined,\n  ShoppingOutlined,\n} from '@ant-design/icons'\nimport { accountApi } from '@/services/goofish'\n\nconst { Option } = Select\nconst { Text } = Typography\n\ninterface GoodsItem {\n  id: string\n  title: string\n  price?: string\n  picUrl?: string\n  picWidth?: number\n  picHeight?: number\n  categoryId?: number\n  itemStatus: number\n  hasVideo?: boolean\n  soldPrice?: string\n  postInfo?: string\n  accountId?: string\n}\n\nconst Goods: React.FC = () => {\n  const [goods, setGoods] = useState<GoodsItem[]>([])\n  const [accounts, setAccounts] = useState<any[]>([])\n  const [loading, setLoading] = useState(false)\n  const [selectedAccountId, setSelectedAccountId] = useState<string>(\n    localStorage.getItem('goofish_goods_filter_account') || ''\n  )\n  const [selectedStatus, setSelectedStatus] = useState<string>(\n    localStorage.getItem('goofish_goods_filter_status') || ''\n  )\n\n  useEffect(() => {\n    loadAccounts()\n    loadGoods()\n  }, [selectedAccountId, selectedStatus])\n\n  const loadAccounts = async () => {\n    try {\n      const response = await accountApi.getAccounts()\n      const accountsData = response.data?.accounts || []\n      setAccounts(accountsData)\n\n      // 如果没有选中的账号且有账号数据，默认选中第一个\n      if (!selectedAccountId && accountsData.length > 0) {\n        const firstAccountId = accountsData[0].id\n        setSelectedAccountId(firstAccountId)\n        localStorage.setItem('goofish_goods_filter_account', firstAccountId)\n      } else {\n        localStorage.setItem('goofish_goods_filter_account', '选择账号')\n      }\n    } catch (error) {\n      console.error('加载账号列表失败', error)\n    }\n  }\n\n  const loadGoods = async () => {\n    setLoading(true)\n    try {\n      const params: any = {}\n      if (selectedAccountId) params.accountId = selectedAccountId\n      if (selectedStatus) params.status = selectedStatus\n\n      // 使用 fetch 调用商品接口\n      const queryString = new URLSearchParams(params).toString()\n      const response = await fetch(`/api/goods${queryString ? '?' + queryString : ''}`)\n      const data = await response.json()\n      setGoods(data.items || [])\n    } catch (error) {\n      message.error('加载商品列表失败')\n    } finally {\n      setLoading(false)\n    }\n  }\n\n  const onAccountChange = (value: string) => {\n    setSelectedAccountId(value)\n    localStorage.setItem('goofish_goods_filter_account', value)\n  }\n\n  const onStatusChange = (value: string) => {\n    setSelectedStatus(value)\n    localStorage.setItem('goofish_goods_filter_status', value)\n  }\n\n  const getStatusText = (status: number): string => {\n    switch (status) {\n      case 0: return '在售'\n      case 1: return '已下架'\n      default: return '未知'\n    }\n  }\n\n  const getStatusColor = (status: number): string => {\n    switch (status) {\n      case 0: return 'success'\n      case 1: return 'warning'\n      default: return 'default'\n    }\n  }\n\n  const filteredGoods = goods.filter(item => {\n    if (selectedStatus === '') return true\n    return item.itemStatus === Number(selectedStatus)\n  })\n\n  const stats = {\n    total: goods.length,\n    onSale: goods.filter(g => g.itemStatus === 0).length,\n    offSale: goods.filter(g => g.itemStatus === 1).length\n  }\n\n  const getAccountNickname = (accountId: string): string => {\n    const account = accounts.find(a => a.id === accountId)\n    return account?.nickname || account?.userId || accountId\n  }\n\n  return (\n    <div>\n      {/* 统计卡片 */}\n      <Row gutter={16} style={{ marginBottom: 16 }}>\n        <Col xs={12} sm={6}>\n          <Card>\n            <div style={{ textAlign: 'center' }}>\n              <ShoppingOutlined style={{ fontSize: 24, color: '#1890ff' }} />\n              <div style={{ fontSize: 24, fontWeight: 'bold', marginTop: 8 }}>{stats.total}</div>\n              <div style={{ color: '#999' }}>商品总数</div>\n            </div>\n          </Card>\n        </Col>\n        <Col xs={12} sm={6}>\n          <Card>\n            <div style={{ textAlign: 'center' }}>\n              <Badge status=\"success\" />\n              <div style={{ fontSize: 24, fontWeight: 'bold', marginTop: 8 }}>{stats.onSale}</div>\n              <div style={{ color: '#999' }}>在售</div>\n            </div>\n          </Card>\n        </Col>\n        <Col xs={12} sm={6}>\n          <Card>\n            <div style={{ textAlign: 'center' }}>\n              <Badge status=\"warning\" />\n              <div style={{ fontSize: 24, fontWeight: 'bold', marginTop: 8 }}>{stats.offSale}</div>\n              <div style={{ color: '#999' }}>已下架</div>\n            </div>\n          </Card>\n        </Col>\n        <Col xs={12} sm={6}>\n          <Card>\n            <div style={{ textAlign: 'center' }}>\n              <Badge status=\"processing\" />\n              <div style={{ fontSize: 24, fontWeight: 'bold', marginTop: 8 }}>{goods.filter(g => g.hasVideo).length}</div>\n              <div style={{ color: '#999' }}>含视频</div>\n            </div>\n          </Card>\n        </Col>\n      </Row>\n\n      {/* 筛选条件 */}\n      <Card style={{ marginBottom: 16 }}>\n        <Space size=\"middle\" wrap>\n          <Select\n            style={{ width: '100%', maxWidth: 200 }}\n            placeholder=\"选择账号\"\n            allowClear\n            value={selectedAccountId}\n            onChange={onAccountChange}\n          >\n            {accounts.map(account => (\n              <Option key={account.id} value={account.id}>\n                {account.nickname || account.id}\n              </Option>\n            ))}\n          </Select>\n\n          <Select\n            style={{ width: '100%', maxWidth: 150 }}\n            placeholder=\"商品状态\"\n            value={selectedStatus}\n            onChange={onStatusChange}\n          >\n            <Option value=\"\">全部状态</Option>\n            <Option value=\"0\">在售</Option>\n            <Option value=\"1\">已下架</Option>\n          </Select>\n\n          <Button icon={<ReloadOutlined />} onClick={loadGoods} loading={loading}>\n            刷新\n          </Button>\n        </Space>\n      </Card>\n\n      {/* 商品列表 */}\n      <Spin spinning={loading}>\n        {filteredGoods.length === 0 ? (\n          <Empty\n            description=\"暂无商品\"\n            style={{ padding: '100px 0' }}\n          />\n        ) : (\n          <Row gutter={[16, 16]}>\n            {filteredGoods.map(item => (\n              <Col xs={24} sm={12} md={8} lg={6} key={item.id}>\n                <Card\n                  hoverable\n                  style={{ height: 'auto', minHeight: 380 }}\n                  bodyStyle={{ padding: '12px', height: '100%', display: 'flex', flexDirection: 'column' }}\n                  cover={\n                    item.picUrl ? (\n                      <div style={{ height: 200, overflow: 'hidden', position: 'relative' }}>\n                        <Image\n                          src={item.picUrl}\n                          alt={item.title}\n                          style={{ width: '100%', height: '100%', objectFit: 'cover' }}\n                          preview={false}\n                        />\n                        <div style={{ position: 'absolute', top: 8, right: 8 }}>\n                          <Tag color={getStatusColor(item.itemStatus)}>\n                            {getStatusText(item.itemStatus)}\n                          </Tag>\n                        </div>\n                      </div>\n                    ) : (\n                      <div style={{\n                        height: 200,\n                        display: 'flex',\n                        alignItems: 'center',\n                        justifyContent: 'center',\n                        background: '#f5f5f5'\n                      }}>\n                        <ShoppingOutlined style={{ fontSize: 48, color: '#d9d9d9' }} />\n                      </div>\n                    )\n                  }\n                >\n                  <Space direction=\"vertical\" size=\"small\" style={{ width: '100%', flex: 1 }}>\n                    <Tooltip title={item.title}>\n                      <Text strong ellipsis={{ tooltip: item.title }} style={{ display: 'block' }}>\n                        {item.title}\n                      </Text>\n                    </Tooltip>\n\n                    {item.price && (\n                      <Text type=\"danger\" strong style={{ fontSize: 18 }}>\n                        ¥{item.price}\n                      </Text>\n                    )}\n\n                    <div style={{ flex: 1 }} />\n\n                    <div style={{ borderTop: '1px solid #f0f0f0', paddingTop: 8 }}>\n                      <Space direction=\"vertical\" size=\"small\" style={{ width: '100%' }}>\n                        <Row gutter={8} style={{ fontSize: 12, color: '#999' }}>\n                          <Col span={12}>\n                            {item.hasVideo ? '有视频' : '无视频'}\n                          </Col>\n                          {item.postInfo && (\n                            <Col span={12} style={{ textAlign: 'right' }}>\n                              <Tag color=\"blue\" style={{ fontSize: 11 }}>{item.postInfo}</Tag>\n                            </Col>\n                          )}\n                        </Row>\n\n                        {item.accountId && (\n                          <Text type=\"secondary\" style={{ fontSize: 12, display: 'flex', alignItems: 'center' }}>\n                            {getAccountNickname(item.accountId)}\n                          </Text>\n                        )}\n                      </Space>\n                    </div>\n                  </Space>\n                </Card>\n              </Col>\n            ))}\n          </Row>\n        )}\n      </Spin>\n    </div>\n  )\n}\n\nexport default Goods\n"
  },
  {
    "path": "src/pages/goofish/Logs/index.tsx",
    "content": "import React, { useEffect, useState } from 'react'\nimport {\n  Card,\n  Select,\n  List,\n  Tag,\n  Space,\n  Button,\n  Typography,\n  Input,\n  Grid\n} from 'antd'\nimport {\n  ReloadOutlined,\n  SearchOutlined,\n  FileTextOutlined,\n  BugOutlined,\n  ExclamationCircleOutlined,\n  InfoCircleOutlined\n} from '@ant-design/icons'\nimport { logApi } from '@/services/goofish'\nimport type { LogEntry } from '@/types/goofish'\n\nconst { Option } = Select\nconst { Text } = Typography\nconst { Search } = Input\nconst { useBreakpoint } = Grid\n\nconst LEVEL_CONFIG: Record<string, { color: string; icon: any }> = {\n  DEBUG: { color: 'default', icon: <BugOutlined /> },\n  debug: { color: 'default', icon: <BugOutlined /> },\n  INFO: { color: 'blue', icon: <InfoCircleOutlined /> },\n  info: { color: 'blue', icon: <InfoCircleOutlined /> },\n  WARN: { color: 'orange', icon: <ExclamationCircleOutlined /> },\n  warn: { color: 'orange', icon: <ExclamationCircleOutlined /> },\n  ERROR: { color: 'red', icon: <ExclamationCircleOutlined /> },\n  error: { color: 'red', icon: <ExclamationCircleOutlined /> }\n}\n\nconst Logs: React.FC = () => {\n  const screens = useBreakpoint()\n  const isMobile = !screens.md\n\n  const [logs, setLogs] = useState<LogEntry[]>([])\n  const [loading, setLoading] = useState(false)\n  const [levelFilter, setLevelFilter] = useState<string>('ALL')\n  const [searchText, setSearchText] = useState('')\n  // @ts-ignore\n  const [autoRefresh, setAutoRefresh] = useState(true)\n\n  useEffect(() => {\n    loadLogs()\n    if (autoRefresh) {\n      const interval = setInterval(loadLogs, 5000)\n      return () => clearInterval(interval)\n    }\n  }, [levelFilter, autoRefresh])\n\n  const loadLogs = async () => {\n    setLoading(true)\n    try {\n      const response = await logApi.getLogs({\n        level: levelFilter === 'ALL' ? undefined : levelFilter,\n        limit: 100\n      })\n\n      // 解析日志行\n      const lines = response.data?.lines || []\n      const parsedLogs: LogEntry[] = lines.map((line: string, index: number) => {\n        // 日志格式: 2026-02-27 10:30:45 | INFO | Context | Message\n        const parts = line.split(' | ')\n        let timestamp: string | undefined\n        let level: LogEntry['level'] = 'INFO'\n        let context: string | undefined\n        let message = line\n\n        if (parts.length >= 3) {\n          const [timeStr, levelStr, ...rest] = parts\n          timestamp = timeStr\n          level = levelStr as LogEntry['level']\n\n          // 最后一部分是消息，中间的是上下文\n          const contextAndMessage = rest.join(' | ')\n          const messageParts = contextAndMessage.split('] ')\n\n          if (messageParts.length > 1) {\n            context = messageParts[0].replace('[', '').replace(']', '')\n            message = messageParts.slice(1).join('] ')\n          } else {\n            message = contextAndMessage\n          }\n        }\n\n        return {\n          id: index,\n          timestamp,\n          level,\n          context,\n          message\n        }\n      })\n\n      setLogs(parsedLogs)\n    } catch (error) {\n      console.error('加载日志失败', error)\n    } finally {\n      setLoading(false)\n    }\n  }\n\n  const filteredLogs = logs.filter(log => {\n    if (!searchText) return true\n    return log.message?.toLowerCase().includes(searchText.toLowerCase()) ||\n           log.context?.toLowerCase().includes(searchText.toLowerCase())\n  })\n\n  const getLevelIcon = (level: string) => {\n    return LEVEL_CONFIG[level]?.icon || <FileTextOutlined />\n  }\n\n  const getLevelColor = (level: string) => {\n    return LEVEL_CONFIG[level]?.color || 'default'\n  }\n\n  const formatTime = (time?: string): string => {\n    if (!time) return '-'\n    return new Date(time).toLocaleTimeString('zh-CN')\n  }\n\n  return (\n    <div>\n      <Card\n        title=\"系统日志\"\n        styles={{\n          body: { padding: isMobile ? '12px' : '24px' },\n          header: { padding: isMobile ? '12px 16px' : undefined }\n        }}\n        extra={\n          !isMobile && (\n            <Space>\n              <Select\n                value={levelFilter}\n                onChange={setLevelFilter}\n                style={{ width: 120 }}\n              >\n                <Option value=\"ALL\">全部级别</Option>\n                <Option value=\"ERROR\">错误</Option>\n                <Option value=\"WARN\">警告</Option>\n                <Option value=\"INFO\">信息</Option>\n                <Option value=\"DEBUG\">调试</Option>\n              </Select>\n              <Search\n                placeholder=\"搜索日志\"\n                allowClear\n                style={{ width: 200 }}\n                onChange={(e) => setSearchText(e.target.value)}\n                prefix={<SearchOutlined />}\n              />\n              <Button\n                icon={<ReloadOutlined />}\n                onClick={loadLogs}\n                loading={loading}\n              >\n                刷新\n              </Button>\n            </Space>\n          )\n        }\n      >\n        {/* 移动端筛选区域 */}\n        {isMobile && (\n          <Space direction=\"vertical\" style={{ width: '100%', marginBottom: 16 }} size=\"small\">\n            <Space wrap>\n              <Select\n                value={levelFilter}\n                onChange={setLevelFilter}\n                style={{ width: 100 }}\n                size=\"small\"\n              >\n                <Option value=\"ALL\">全部级别</Option>\n                <Option value=\"ERROR\">错误</Option>\n                <Option value=\"WARN\">警告</Option>\n                <Option value=\"INFO\">信息</Option>\n                <Option value=\"DEBUG\">调试</Option>\n              </Select>\n              <Search\n                placeholder=\"搜索日志\"\n                allowClear\n                style={{ width: 140 }}\n                size=\"small\"\n                onChange={(e) => setSearchText(e.target.value)}\n                prefix={<SearchOutlined />}\n              />\n              <Button\n                icon={<ReloadOutlined />}\n                onClick={loadLogs}\n                loading={loading}\n                size=\"small\"\n              >\n                刷新\n              </Button>\n            </Space>\n          </Space>\n        )}\n        <List\n          dataSource={filteredLogs}\n          renderItem={(log) => (\n            <List.Item\n              key={log.id}\n              style={{\n                padding: isMobile ? '6px 0' : '8px 0',\n                borderBottom: '1px solid #f0f0f0'\n              }}\n            >\n              <Space direction=\"vertical\" style={{ width: '100%' }} size=\"small\">\n                <Space wrap={isMobile}>\n                  <Text type=\"secondary\" style={{ fontSize: isMobile ? '11px' : '12px', fontFamily: 'monospace' }}>\n                    {formatTime(log.timestamp)}\n                  </Text>\n                  <Tag\n                    icon={getLevelIcon(log.level)}\n                    color={getLevelColor(log.level)}\n                    style={{ fontSize: isMobile ? '10px' : undefined }}\n                  >\n                    {log.level}\n                  </Tag>\n                  {log.context && (\n                    <Text type=\"secondary\" style={{ fontSize: isMobile ? '11px' : '12px' }}>\n                      [{log.context}]\n                    </Text>\n                  )}\n                </Space>\n                <Text\n                  style={{\n                    fontFamily: 'monospace',\n                    fontSize: isMobile ? '12px' : '13px',\n                    wordBreak: 'break-all'\n                  }}\n                >\n                  {log.message}\n                </Text>\n              </Space>\n            </List.Item>\n          )}\n          loading={loading}\n        />\n      </Card>\n    </div>\n  )\n}\n\nexport default Logs\n"
  },
  {
    "path": "src/pages/goofish/Orders/index.tsx",
    "content": "import React, { useEffect, useState } from 'react'\nimport { \n  Card, \n  Table, \n  Space, \n  Tag, \n  Button, \n  Select, \n  Input, \n  Image, \n  Modal, \n  Form, \n  message,\n  Row,\n  Col,\n  Statistic,\n  Tooltip,\n  Typography\n} from 'antd'\nimport {\n  ReloadOutlined,\n  SendOutlined,\n  ShoppingCartOutlined,\n  DollarOutlined,\n  CheckCircleOutlined\n} from '@ant-design/icons'\nimport { orderApi, accountApi } from '@/services/goofish'\nimport type { Order } from '@/types/goofish'\n\nconst { Option } = Select\nconst { TextArea } = Input\nconst { Text } = Typography\n\nenum OrderStatus {\n  FETCHING = 0,\n  PENDING_PAYMENT = 1,\n  PENDING_SHIPMENT = 2,\n  PENDING_RECEIPT = 3,\n  COMPLETED = 4,\n  CLOSED = 5\n}\n\nconst STATUS_CONFIG: Record<number, { text: string; color: string }> = {\n  [OrderStatus.FETCHING]: { text: '获取中', color: 'default' },\n  [OrderStatus.PENDING_PAYMENT]: { text: '待付款', color: 'orange' },\n  [OrderStatus.PENDING_SHIPMENT]: { text: '待发货', color: 'blue' },\n  [OrderStatus.PENDING_RECEIPT]: { text: '待收货', color: 'cyan' },\n  [OrderStatus.COMPLETED]: { text: '交易成功', color: 'green' },\n  [OrderStatus.CLOSED]: { text: '已关闭', color: 'default' }\n}\n\nconst Orders: React.FC = () => {\n  const [orders, setOrders] = useState<Order[]>([])\n  const [accounts, setAccounts] = useState<any[]>([])\n  const [loading, setLoading] = useState(false)\n  const [refreshingId, setRefreshingId] = useState<string | null>(null)\n  const [shippingModalVisible, setShippingModalVisible] = useState(false)\n  const [currentOrder, setCurrentOrder] = useState<Order | null>(null)\n  const [shippingForm] = Form.useForm()\n  const [isMobile, setIsMobile] = useState(false)\n\n  // 筛选条件\n  const [selectedAccountId, setSelectedAccountId] = useState<string>('')\n  const [selectedStatus, setSelectedStatus] = useState<number | ''>('')\n\n  // 分页\n  const [total, setTotal] = useState(0)\n  const [currentPage, setCurrentPage] = useState(1)\n  const [pageSize] = useState(20)\n\n  // 检测移动端\n  useEffect(() => {\n    const checkMobile = () => {\n      setIsMobile(window.innerWidth < 768)\n    }\n    checkMobile()\n    window.addEventListener('resize', checkMobile)\n    return () => window.removeEventListener('resize', checkMobile)\n  }, [])\n\n  // 加载数据\n  useEffect(() => {\n    loadAccounts()\n    loadOrders()\n  }, [selectedAccountId, selectedStatus, currentPage])\n\n  const loadAccounts = async () => {\n    try {\n      const response = await accountApi.getAccounts()\n      setAccounts(response.data?.accounts || [])\n    } catch (error) {\n      console.error('加载账号失败:', error)\n    }\n  }\n\n  const loadOrders = async () => {\n    setLoading(true)\n    try {\n      const params: any = {\n        limit: pageSize,\n        offset: (currentPage - 1) * pageSize\n      }\n      if (selectedAccountId) params.accountId = selectedAccountId\n      if (selectedStatus !== '') params.status = selectedStatus\n\n      const response = await orderApi.getOrders(params)\n      setOrders(response.data?.orders || [])\n      setTotal(response.data?.total || 0)\n    } catch (error) {\n      message.error('加载订单列表失败')\n    } finally {\n      setLoading(false)\n    }\n  }\n\n  const onRefresh = async (orderId: string) => {\n    setRefreshingId(orderId)\n    try {\n      await orderApi.getOrder(Number(orderId.split('-')[1]))\n      message.success('刷新成功')\n      loadOrders()\n    } catch (error) {\n      message.error('刷新失败')\n    } finally {\n      setRefreshingId(null)\n    }\n  }\n\n  const onShip = (order: Order) => {\n    setCurrentOrder(order)\n    setShippingModalVisible(true)\n    shippingForm.resetFields()\n  }\n\n  const onShipSubmit = async (values: any) => {\n    if (!currentOrder) return\n\n    try {\n      await orderApi.confirmShipment(currentOrder.id, {\n        shipmentType: values.shipmentType,\n        ...values.shipmentType === 'manual' && {\n          company: values.company,\n          trackingNumber: values.trackingNumber\n        },\n        ...values.shipmentType === 'free' && {\n          freeShippingReason: values.freeShippingReason\n        }\n      })\n      message.success('发货成功')\n      setShippingModalVisible(false)\n      loadOrders()\n    } catch (error) {\n      message.error('发货失败')\n    }\n  }\n\n  const getStatusText = (status: number): string => {\n    return STATUS_CONFIG[status]?.text || '未知'\n  }\n\n  const getStatusColor = (status: number): string => {\n    return STATUS_CONFIG[status]?.color || 'default'\n  }\n\n  const formatTime = (time?: string): string => {\n    return time ? new Date(time).toLocaleString('zh-CN') : '-'\n  }\n\n  // 统计数据\n  const stats = {\n    total: orders.length,\n    pendingShipment: orders.filter(o => o.status === OrderStatus.PENDING_SHIPMENT).length,\n    totalAmount: orders.reduce((sum, o) => {\n      const price = parseFloat(o.price || '0')\n      return sum + price\n    }, 0)\n  }\n\n  const columns = [\n    {\n      title: '商品',\n      dataIndex: 'itemTitle',\n      key: 'itemTitle',\n      render: (_: any, record: Order) => (\n        <Space>\n          {record.itemPicUrl && (\n            <Image\n              width={48}\n              height={48}\n              src={record.itemPicUrl}\n              style={{ borderRadius: 4 }}\n            />\n          )}\n          <div>\n            <div style={{ fontWeight: 500 }}>{record.itemTitle || '未知商品'}</div>\n            <Text type=\"secondary\" style={{ fontSize: '12px' }}>\n              {record.orderId}\n            </Text>\n          </div>\n        </Space>\n      )\n    },\n    {\n      title: '买家',\n      dataIndex: 'buyerNickname',\n      key: 'buyerNickname',\n      render: (nickname?: string) => nickname || '-'\n    },\n    {\n      title: '金额',\n      dataIndex: 'price',\n      key: 'price',\n      render: (price?: string) => (\n        <Text strong style={{ color: '#ff4d4f' }}>\n          ¥{price || '0.00'}\n        </Text>\n      )\n    },\n    {\n      title: '状态',\n      dataIndex: 'status',\n      key: 'status',\n      render: (status: number) => (\n        <Tag color={getStatusColor(status)}>\n          {getStatusText(status)}\n        </Tag>\n      )\n    },\n    {\n      title: '下单时间',\n      dataIndex: 'orderTime',\n      key: 'orderTime',\n      render: formatTime\n    },\n    {\n      title: '操作',\n      key: 'actions',\n      render: (_: any, record: Order) => (\n        <Space size=\"small\">\n          <Tooltip title=\"刷新订单\">\n            <Button \n              type=\"text\" \n              size=\"small\"\n              icon={<ReloadOutlined spin={refreshingId === record.orderId} />}\n              onClick={() => onRefresh(record.orderId)}\n              loading={refreshingId === record.orderId}\n            />\n          </Tooltip>\n          {record.status === OrderStatus.PENDING_SHIPMENT && (\n            <Button \n              type=\"primary\" \n              size=\"small\"\n              icon={<SendOutlined />}\n              onClick={() => onShip(record)}\n            >\n              发货\n            </Button>\n          )}\n        </Space>\n      )\n    }\n  ]\n\n  return (\n    <div>\n      {/* 统计卡片 */}\n      <Row gutter={[16, 16]} style={{ marginBottom: 16 }}>\n        <Col xs={24} sm={12} md={8}>\n          <Card>\n            <Statistic\n              title=\"总订单数\"\n              value={total}\n              prefix={<ShoppingCartOutlined />}\n            />\n          </Card>\n        </Col>\n        <Col xs={24} sm={12} md={8}>\n          <Card>\n            <Statistic\n              title=\"待发货\"\n              value={stats.pendingShipment}\n              prefix={<SendOutlined />}\n              valueStyle={{ color: '#ff4d4f' }}\n            />\n          </Card>\n        </Col>\n        <Col xs={24} sm={12} md={8}>\n          <Card>\n            <Statistic\n              title=\"总金额\"\n              value={stats.totalAmount}\n              prefix={<DollarOutlined />}\n              precision={2}\n              valueStyle={{ color: '#52c41a' }}\n            />\n          </Card>\n        </Col>\n      </Row>\n\n      {/* 筛选条件 */}\n      <Card style={{ marginBottom: 16 }}>\n        <Space size=\"middle\" wrap>\n          <Select\n            style={{ width: isMobile ? '100%' : 150, maxWidth: 200 }}\n            placeholder=\"选择账号\"\n            allowClear\n            value={selectedAccountId || undefined}\n            onChange={(value) => {\n              setSelectedAccountId(value || '')\n              setCurrentPage(1)\n            }}\n          >\n            {accounts.map(account => (\n              <Option key={account.id} value={account.id}>\n                {account.nickname || account.id}\n              </Option>\n            ))}\n          </Select>\n\n          <Select\n            style={{ width: isMobile ? '100%' : 120, maxWidth: 150 }}\n            placeholder=\"订单状态\"\n            value={selectedStatus}\n            onChange={(value) => {\n              setSelectedStatus(value)\n              setCurrentPage(1)\n            }}\n          >\n            <Option value=\"\">全部状态</Option>\n            {Object.entries(STATUS_CONFIG).map(([value, config]) => (\n              <Option key={value} value={Number(value)}>\n                {config.text}\n              </Option>\n            ))}\n          </Select>\n\n          <Button icon={<ReloadOutlined />} onClick={loadOrders}>\n            刷新\n          </Button>\n        </Space>\n      </Card>\n\n      {/* 订单列表 */}\n      <Card>\n        <Table\n          columns={columns}\n          dataSource={orders}\n          rowKey=\"id\"\n          loading={loading}\n          scroll={{ x: 'max-content' }}\n          pagination={{\n            current: currentPage,\n            pageSize,\n            total,\n            onChange: (page) => setCurrentPage(page),\n            showSizeChanger: false,\n            simple: true\n          }}\n          expandable={{\n            expandedRowRender: (record) => (\n              <Card size=\"small\" style={{ margin: 0 }}>\n                <Row gutter={[8, 8]}>\n                  <Col xs={12} sm={12} md={12}>\n                    <Space direction=\"vertical\" size=\"small\">\n                      <Text type=\"secondary\">订单编号</Text>\n                      <Text copyable style={{ fontSize: 12 }}>{record.orderId}</Text>\n                    </Space>\n                  </Col>\n                  <Col xs={12} sm={12} md={12}>\n                    <Space direction=\"vertical\" size=\"small\">\n                      <Text type=\"secondary\">商品ID</Text>\n                      <Text style={{ fontSize: 12 }}>{record.itemId || '-'}</Text>\n                    </Space>\n                  </Col>\n                  <Col xs={12} sm={12} md={12}>\n                    <Space direction=\"vertical\" size=\"small\">\n                      <Text type=\"secondary\">买家ID</Text>\n                      <Text style={{ fontSize: 12 }}>{record.buyerUserId || '-'}</Text>\n                    </Space>\n                  </Col>\n                  <Col xs={12} sm={12} md={12}>\n                    <Space direction=\"vertical\" size=\"small\">\n                      <Text type=\"secondary\">付款时间</Text>\n                      <Text>{formatTime(record.payTime)}</Text>\n                    </Space>\n                  </Col>\n                </Row>\n              </Card>\n            )\n          }}\n        />\n      </Card>\n\n      {/* 发货弹窗 */}\n      <Modal\n        title=\"确认发货\"\n        open={shippingModalVisible}\n        onCancel={() => setShippingModalVisible(false)}\n        footer={null}\n      >\n        <Form\n          form={shippingForm}\n          layout=\"vertical\"\n          onFinish={onShipSubmit}\n        >\n          <Form.Item\n            label=\"发货方式\"\n            name=\"shipmentType\"\n            rules={[{ required: true, message: '请选择发货方式' }]}\n          >\n            <Select placeholder=\"请选择\">\n              <Option value=\"free\">免拼发货</Option>\n              <Option value=\"manual\">手动发货</Option>\n            </Select>\n          </Form.Item>\n\n          <Form.Item noStyle shouldUpdate={(prev, curr) => prev.shipmentType !== curr.shipmentType}>\n            {({ getFieldValue }) => {\n              const shipmentType = getFieldValue('shipmentType')\n              \n              if (shipmentType === 'manual') {\n                return (\n                  <>\n                    <Form.Item\n                      label=\"物流公司\"\n                      name=\"company\"\n                      rules={[{ required: true, message: '请输入物流公司' }]}\n                    >\n                      <Input placeholder=\"如：顺丰速运\" autoComplete=\"off\" />\n                    </Form.Item>\n                    <Form.Item\n                      label=\"物流单号\"\n                      name=\"trackingNumber\"\n                      rules={[{ required: true, message: '请输入物流单号' }]}\n                    >\n                      <Input placeholder=\"请输入物流单号\" autoComplete=\"off\" />\n                    </Form.Item>\n                  </>\n                )\n              }\n              \n              if (shipmentType === 'free') {\n                return (\n                  <Form.Item\n                    label=\"免拼原因\"\n                    name=\"freeShippingReason\"\n                    rules={[{ required: true, message: '请输入免拼原因' }]}\n                  >\n                    <TextArea rows={3} placeholder=\"请输入免拼原因\" />\n                  </Form.Item>\n                )\n              }\n              \n              return null\n            }}\n          </Form.Item>\n\n          <Form.Item>\n            <Space style={{ width: '100%', justifyContent: 'flex-end' }}>\n              <Button onClick={() => setShippingModalVisible(false)}>\n                取消\n              </Button>\n              <Button type=\"primary\" htmlType=\"submit\" icon={<CheckCircleOutlined />}>\n                确认发货\n              </Button>\n            </Space>\n          </Form.Item>\n        </Form>\n      </Modal>\n    </div>\n  )\n}\n\nexport default Orders\n"
  },
  {
    "path": "src/pages/goofish/Workflow/index.tsx",
    "content": "import React, { useEffect, useState } from 'react'\nimport { \n  Card, \n  Button, \n  Space, \n  message, \n  Modal, \n  Form, \n  Input, \n  Switch, \n  Tag,\n  Typography,\n  Row,\n  Col,\n  Empty,\n  Divider,\n} from 'antd'\nimport { \n  PlusOutlined, \n  EditOutlined, \n  DeleteOutlined,\n  BranchesOutlined\n} from '@ant-design/icons'\nimport { workflowApi } from '@/services/goofish'\nimport type { Workflow } from '@/types/goofish'\n\nconst { TextArea } = Input\nconst { Text, Title } = Typography\n\nconst NODE_TYPES = [\n  { value: 'trigger', label: '触发器', color: 'blue' },\n  { value: 'autoreply', label: '自动回复', color: 'green' },\n  { value: 'delivery', label: '发货', color: 'orange' },\n  { value: 'ship', label: '确认发货', color: 'cyan' },\n  { value: 'delay', label: '延迟', color: 'purple' },\n  { value: 'condition', label: '条件判断', color: 'red' }\n]\n\nconst Workflow: React.FC = () => {\n  const [workflows, setWorkflows] = useState<Workflow[]>([])\n  const [modalVisible, setModalVisible] = useState(false)\n  const [editingId, setEditingId] = useState<number | null>(null)\n  const [form] = Form.useForm()\n\n  useEffect(() => {\n    loadWorkflows()\n  }, [])\n\n  const loadWorkflows = async () => {\n    try {\n      const response = await workflowApi.getWorkflows()\n      setWorkflows(response.data?.workflows || [])\n    } catch (error) {\n      message.error('加载工作流失败')\n    }\n  }\n\n  const onCreate = () => {\n    setEditingId(null)\n    form.resetFields()\n    setModalVisible(true)\n  }\n\n  const onEdit = (workflow: Workflow) => {\n    setEditingId(workflow.id)\n    form.setFieldsValue({\n      name: workflow.name,\n      description: workflow.description,\n      enabled: workflow.enabled\n    })\n    setModalVisible(true)\n  }\n\n  const onDelete = async (id: number) => {\n    try {\n      await workflowApi.deleteWorkflow(id)\n      message.success('删除成功')\n      loadWorkflows()\n    } catch (error) {\n      message.error('删除失败')\n    }\n  }\n\n  const onModalOk = async () => {\n    try {\n      const values = await form.validateFields()\n      if (editingId) {\n        await workflowApi.updateWorkflow(editingId, values)\n        message.success('更新成功')\n      } else {\n        await workflowApi.createWorkflow({\n          ...values,\n          definition: { nodes: [], edges: [] }\n        })\n        message.success('创建成功')\n      }\n      setModalVisible(false)\n      loadWorkflows()\n    } catch (error) {\n      message.error('操作失败')\n    }\n  }\n\n  const renderWorkflowPreview = (workflow: Workflow) => {\n    const nodeCount = workflow.definition?.nodes?.length || 0\n    const edgeCount = workflow.definition?.edges?.length || 0\n    \n    return (\n      <Space direction=\"vertical\" size=\"small\" style={{ width: '100%' }}>\n        <Space wrap>\n          {workflow.definition?.nodes?.map((node: any) => {\n            const config = NODE_TYPES.find(t => t.value === node.type)\n            return (\n              <Tag key={node.id} color={config?.color}>\n                {config?.label || node.type}\n              </Tag>\n            )\n          })}\n        </Space>\n        <Text type=\"secondary\" style={{ fontSize: '12px' }}>\n          {nodeCount} 个节点 · {edgeCount} 条连线\n        </Text>\n      </Space>\n    )\n  }\n\n  return (\n    <div>\n      <Card\n        title={\n          <Space>\n            <BranchesOutlined />\n            工作流管理\n          </Space>\n        }\n        extra={\n          <Button \n            type=\"primary\" \n            icon={<PlusOutlined />}\n            onClick={onCreate}\n          >\n            新建工作流\n          </Button>\n        }\n      >\n        {workflows.length === 0 ? (\n          <Empty\n            description=\"暂无工作流\"\n            style={{ padding: '40px 0' }}\n          >\n            <Button type=\"primary\" icon={<PlusOutlined />} onClick={onCreate}>\n              创建第一个工作流\n            </Button>\n          </Empty>\n        ) : (\n          <Row gutter={16}>\n            {workflows.map((workflow) => (\n              <Col xs={24} sm={12} lg={8} key={workflow.id}>\n                <Card\n                  size=\"small\"\n                  style={{ marginBottom: 16 }}\n                  bodyStyle={{ padding: '16px' }}\n                >\n                  <Space direction=\"vertical\" style={{ width: '100%' }} size=\"small\">\n                    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'start' }}>\n                      <Space direction=\"vertical\" size={0}>\n                        <Title level={5} style={{ margin: 0 }}>\n                          {workflow.name}\n                        </Title>\n                        {workflow.isDefault && (\n                          <Tag color=\"blue\">默认</Tag>\n                        )}\n                        {!workflow.enabled && (\n                          <Tag color=\"default\">已禁用</Tag>\n                        )}\n                      </Space>\n                      <Space size=\"small\">\n                        <Button\n                          type=\"text\"\n                          size=\"small\"\n                          icon={<EditOutlined />}\n                          onClick={() => onEdit(workflow)}\n                        />\n                        <Button\n                          type=\"text\"\n                          size=\"small\"\n                          danger\n                          icon={<DeleteOutlined />}\n                          onClick={() => onDelete(workflow.id)}\n                        />\n                      </Space>\n                    </div>\n                    \n                    {workflow.description && (\n                      <Text type=\"secondary\" ellipsis>\n                        {workflow.description}\n                      </Text>\n                    )}\n                    \n                    <Divider style={{ margin: '8px 0' }} />\n                    \n                    {renderWorkflowPreview(workflow)}\n                  </Space>\n                </Card>\n              </Col>\n            ))}\n          </Row>\n        )}\n      </Card>\n\n      {/* 编辑/创建工作流弹窗 */}\n      <Modal\n        title={editingId ? '编辑工作流' : '新建工作流'}\n        open={modalVisible}\n        onCancel={() => setModalVisible(false)}\n        onOk={onModalOk}\n        width={600}\n      >\n        <Form\n          form={form}\n          layout=\"vertical\"\n          initialValues={{\n            enabled: true,\n            isDefault: false\n          }}\n        >\n          <Form.Item\n            label=\"工作流名称\"\n            name=\"name\"\n            rules={[{ required: true, message: '请输入工作流名称' }]}\n          >\n            <Input placeholder=\"例如：标准发货流程\" autoComplete=\"off\" />\n          </Form.Item>\n\n          <Form.Item\n            label=\"描述\"\n            name=\"description\"\n          >\n            <TextArea rows={2} placeholder=\"描述此工作流的用途\" />\n          </Form.Item>\n\n          <Form.Item\n            label=\"设为默认\"\n            name=\"isDefault\"\n            valuePropName=\"checked\"\n            extra=\"默认工作流将自动应用于新创建的自动发货规则\"\n          >\n            <Switch />\n          </Form.Item>\n\n          <Form.Item\n            label=\"启用状态\"\n            name=\"enabled\"\n            valuePropName=\"checked\"\n          >\n            <Switch />\n          </Form.Item>\n        </Form>\n      </Modal>\n    </div>\n  )\n}\n\nexport default Workflow\n"
  },
  {
    "path": "src/sdk/analytics/README.md",
    "content": "# 埋点SDK使用文档\n\n## 简介\n\n这是一个轻量级的前端埋点SDK，使用GIF图片方式发送数据，具有以下特点：\n\n- 🚀 轻量级，无依赖\n- 📊 支持批量上报\n- 🎯 自动收集页面浏览和设备信息\n- 🛡️ 自动捕获JavaScript错误\n- 🔐 设备指纹识别\n- 📱 完美支持单页应用(SPA)\n\n## 安装配置\n\n### 1. 基本配置\n\n在项目入口文件（如 `main.tsx`）中引入并初始化：\n\n```typescript\nimport { initAnalytics } from \"./sdk/analytics\";\n\n// 初始化SDK\nconst analytics = initAnalytics({\n  reportUrl: \"https://your-analytics-api.com/collect.gif\", // 上报地址\n  appId: \"your-app-id\", // 应用ID\n  userId: \"user-123\", // 可选：用户ID\n  debug: true, // 可选：开启调试模式\n  autoTrack: true, // 可选：自动追踪页面浏览\n  collectDevice: true, // 可选：收集设备信息\n  batchConfig: {\n    enabled: true, // 启用批量上报\n    maxSize: 10, // 批量最大数量\n    timeout: 5000, // 批量上报超时时间(ms)\n  },\n});\n```\n\n### 2. 在应用中使用\n\n```typescript\nimport { getAnalytics } from \"./sdk/analytics\";\n\n// 获取SDK实例\nconst analytics = getAnalytics();\n\n// 追踪自定义事件\nanalytics?.track(\"custom_event\", {\n  param1: \"value1\",\n  param2: \"value2\",\n});\n\n// 追踪按钮点击\nanalytics?.trackClick(\"submit_button\", {\n  page: \"homepage\",\n  section: \"hero\",\n});\n\n// 追踪表单提交\nanalytics?.trackSubmit(\"login_form\", {\n  success: true,\n});\n\n// 追踪用户行为\nanalytics?.trackAction(\"scroll\", \"product_list\", {\n  depth: 50,\n});\n\n// 设置用户ID\nanalytics?.setUserId(\"user-456\");\n\n// 设置用户属性\nanalytics?.setUserProperties({\n  name: \"John Doe\",\n  email: \"john@example.com\",\n  plan: \"premium\",\n});\n\n// 追踪错误\ntry {\n  // 可能出错的代码\n} catch (error) {\n  analytics?.trackError(error, {\n    context: \"user_login\",\n  });\n}\n```\n\n## API文档\n\n### 配置选项 (AnalyticsConfig)\n\n| 参数          | 类型    | 必填 | 说明                           |\n| ------------- | ------- | ---- | ------------------------------ |\n| reportUrl     | string  | 是   | 数据上报地址                   |\n| appId         | string  | 是   | 应用唯一标识                   |\n| userId        | string  | 否   | 用户ID                         |\n| debug         | boolean | 否   | 是否开启调试模式，默认false    |\n| autoTrack     | boolean | 否   | 是否自动追踪页面浏览，默认true |\n| collectDevice | boolean | 否   | 是否收集设备信息，默认true     |\n| batchConfig   | object  | 否   | 批量上报配置                   |\n\n### 主要方法\n\n#### init()\n\n初始化SDK，自动收集页面信息和设置监听器。\n\n#### track(event, properties)\n\n追踪自定义事件。\n\n**参数：**\n\n- `event` (string): 事件名称\n- `properties` (object): 事件属性\n\n**示例：**\n\n```typescript\nanalytics.track(\"purchase\", {\n  product_id: \"123\",\n  amount: 99.99,\n  currency: \"USD\",\n});\n```\n\n#### trackPageView()\n\n追踪页面浏览事件，通常自动调用。\n\n#### trackAction(action, target, properties)\n\n追踪用户行为。\n\n**参数：**\n\n- `action` (string): 行为类型（如click、scroll等）\n- `target` (string): 行为目标\n- `properties` (object): 额外属性\n\n#### trackClick(buttonName, properties)\n\n追踪按钮点击事件。\n\n#### trackSubmit(formName, properties)\n\n追踪表单提交事件。\n\n#### trackError(error, context)\n\n追踪错误信息。\n\n#### setUserId(userId)\n\n设置用户ID。\n\n#### setUserProperties(properties)\n\n设置用户属性。\n\n#### destroy()\n\n销毁SDK实例，清理资源。\n\n## 数据格式\n\n### 单个事件数据结构\n\n```typescript\n{\n  event: string,           // 事件名称\n  properties: object,      // 事件属性\n  timestamp: number,       // 时间戳\n  url: string,            // 页面URL\n  title: string,          // 页面标题\n  userId: string,         // 用户ID\n  sessionId: string,      // 会话ID\n  device: {               // 设备信息\n    userAgent: string,\n    platform: string,\n    language: string,\n    screen: string,\n    timezone: string,\n    fingerprint: string\n  }\n}\n```\n\n### 预设事件类型\n\n| 事件名称        | 触发时机          | 属性                       |\n| --------------- | ----------------- | -------------------------- |\n| page_view       | 页面加载/路由变化 | referrer, path, search     |\n| user_action     | 用户操作          | action, target             |\n| button_click    | 按钮点击          | button_name                |\n| form_submit     | 表单提交          | form_name                  |\n| error           | JavaScript错误    | error_message, error_stack |\n| user_properties | 用户属性设置      | 用户自定义属性             |\n\n## 服务端接收\n\n### Node.js示例\n\n```javascript\nconst express = require(\"express\");\nconst app = express();\n\napp.get(\"/collect.gif\", (req, res) => {\n  try {\n    // 获取数据\n    const data = req.query.data;\n    const decodedData = Buffer.from(data, \"base64\").toString();\n    const eventData = JSON.parse(decodedData);\n\n    // 处理数据\n    console.log(\"Received analytics data:\", eventData);\n\n    // 保存到数据库或发送到其他服务\n    // saveToDatabase(eventData);\n\n    // 返回1x1透明GIF\n    const gif = Buffer.from(\n      \"R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\",\n      \"base64\",\n    );\n    res.setHeader(\"Content-Type\", \"image/gif\");\n    res.setHeader(\"Content-Length\", gif.length);\n    res.send(gif);\n  } catch (error) {\n    console.error(\"Error processing analytics data:\", error);\n    res.status(400).send(\"Bad Request\");\n  }\n});\n\napp.listen(3000, () => {\n  console.log(\"Analytics server running on port 3000\");\n});\n```\n\n## 注意事项\n\n1. **CORS配置**：确保上报地址配置了正确的CORS策略\n2. **数据大小**：由于URL长度限制，单个事件数据不宜过大\n3. **隐私保护**：遵循相关隐私法规，不收集敏感信息\n4. **性能影响**：批量上报和GIF图片方式对性能影响很小\n5. **错误处理**：SDK内置错误处理，不会影响主业务逻辑\n\n## TypeScript支持\n\n本SDK完全使用TypeScript编写，提供完整的类型定义：\n\n```typescript\nimport { AnalyticsSDK, AnalyticsConfig, EventData } from \"./sdk/analytics\";\n\n// 完整的类型支持\nconst config: AnalyticsConfig = {\n  reportUrl: \"https://example.com/collect.gif\",\n  appId: \"my-app\",\n};\n\nconst sdk: AnalyticsSDK = initAnalytics(config);\n```\n"
  },
  {
    "path": "src/sdk/analytics/examples.tsx",
    "content": "/**\n * 埋点SDK使用示例\n */\n\nimport React, { useRef, useState } from 'react'\nimport { useAnalytics, usePageTracking, useClickTracking, useVisibilityTracking, useScrollTracking, useDurationTracking } from './hooks'\n\n/**\n * 示例1: 基本使用\n */\nexport function BasicExample() {\n  const { track, trackClick, trackSubmit, trackError } = useAnalytics()\n\n  const handleButtonClick = () => {\n    trackClick('example_button', {\n      page: 'example',\n      section: 'basic'\n    })\n    console.log('Button clicked - event tracked')\n  }\n\n  const handleFormSubmit = (e: React.FormEvent) => {\n    e.preventDefault()\n    trackSubmit('example_form', {\n      field_count: 2\n    })\n    console.log('Form submitted - event tracked')\n  }\n\n  const handleCustomEvent = () => {\n    track('custom_event', {\n      custom_param: 'value',\n      timestamp: Date.now()\n    })\n    console.log('Custom event tracked')\n  }\n\n  const handleError = () => {\n    try {\n      throw new Error('Example error')\n    } catch (error) {\n      // @ts-ignore\n      trackError(error, {\n        component: 'BasicExample',\n        action: 'error_demo'\n      })\n      console.log('Error tracked')\n    }\n  }\n\n  return (\n    <div style={{ padding: '20px' }}>\n      <h2>基本使用示例</h2>\n\n      <div style={{ marginBottom: '10px' }}>\n        <button onClick={handleButtonClick}>\n          点击追踪按钮\n        </button>\n      </div>\n\n      <form onSubmit={handleFormSubmit} style={{ marginBottom: '10px' }}>\n        <input type=\"text\" placeholder=\"输入内容\" required />\n        <button type=\"submit\">提交表单</button>\n      </form>\n\n      <div style={{ marginBottom: '10px' }}>\n        <button onClick={handleCustomEvent}>\n          自定义事件\n        </button>\n      </div>\n\n      <div>\n        <button onClick={handleError}>\n          错误追踪\n        </button>\n      </div>\n    </div>\n  )\n}\n\n/**\n * 示例2: 页面追踪\n */\nexport function PageTrackingExample() {\n  // 自动追踪页面浏览\n  usePageTracking(true)\n\n  // 追踪页面停留时间\n  useDurationTracking('page_tracking_example', 10000) // 每10秒上报一次\n\n  return (\n    <div style={{ padding: '20px' }}>\n      <h2>页面追踪示例</h2>\n      <p>此页面会自动追踪页面浏览和停留时间</p>\n    </div>\n  )\n}\n\n/**\n * 示例3: 元素点击追踪\n */\nexport function ClickTrackingExample() {\n  const buttonRef = useRef<HTMLButtonElement>(null)\n  const linkRef = useRef<HTMLAnchorElement>(null)\n\n  // 追踪按钮点击\n  useClickTracking(buttonRef, 'tracked_button', {\n    component: 'ClickTrackingExample'\n  })\n\n  // 追踪链接点击\n  useClickTracking(linkRef, 'tracked_link', {\n    type: 'external_link'\n  })\n\n  return (\n    <div style={{ padding: '20px' }}>\n      <h2>元素点击追踪</h2>\n\n      <button ref={buttonRef} style={{ marginRight: '10px' }}>\n        自动追踪点击的按钮\n      </button>\n\n      <a ref={linkRef} href=\"#\" onClick={(e) => e.preventDefault()}>\n        自动追踪点击的链接\n      </a>\n\n      <p style={{ marginTop: '10px', color: '#666' }}>\n        打开控制台查看追踪的事件\n      </p>\n    </div>\n  )\n}\n\n/**\n * 示例4: 可见性追踪\n */\nexport function VisibilityTrackingExample() {\n  const sectionRef = useRef<HTMLDivElement>(null)\n\n  // 追踪元素可见性\n  useVisibilityTracking(sectionRef, 'section_visible', {\n    section_name: 'example_section'\n  })\n\n  return (\n    <div style={{ padding: '20px' }}>\n      <h2>可见性追踪</h2>\n\n      <div style={{ height: '100vh', background: '#f0f0f0', marginBottom: '20px' }}>\n        向下滚动查看追踪区域\n      </div>\n\n      <div\n        ref={sectionRef}\n        style={{\n          padding: '40px',\n          background: '#e6f7ff',\n          border: '2px solid #1890ff',\n          borderRadius: '8px'\n        }}\n      >\n        <h3>追踪区域</h3>\n        <p>当这个区域50%可见时，会触发追踪事件</p>\n      </div>\n\n      <div style={{ height: '100vh', marginTop: '20px', background: '#f0f0f0' }}>\n        继续滚动测试\n      </div>\n    </div>\n  )\n}\n\n/**\n * 示例5: 滚动深度追踪\n */\nexport function ScrollTrackingExample() {\n  // 追踪滚动深度，每25%上报一次\n  useScrollTracking(25, 'article_scroll')\n\n  return (\n    <div style={{ padding: '20px' }}>\n      <h2>滚动深度追踪</h2>\n      <p>向下滚动，每25%会触发一次追踪事件</p>\n\n      <div style={{ marginTop: '20px' }}>\n        {[...Array(20)].map((_, i) => (\n          <p key={i} style={{ marginBottom: '10px', lineHeight: '1.6' }}>\n            这是第 {i + 1} 段内容，用于测试滚动深度追踪。滚动页面时，SDK会自动追踪用户的滚动行为。\n          </p>\n        ))}\n      </div>\n    </div>\n  )\n}\n\n/**\n * 示例6: 综合应用\n */\nexport function ComprehensiveExample() {\n  const { track, trackClick, trackAction } = useAnalytics()\n  const [inputValue, setInputValue] = useState('')\n  const [clickCount, setClickCount] = useState(0)\n  const heroRef = useRef<HTMLDivElement>(null)\n\n  // 页面追踪\n  usePageTracking(true)\n\n  // Hero区域可见性追踪\n  useVisibilityTracking(heroRef, 'hero_visible')\n\n  // 滚动深度追踪\n  useScrollTracking(20, 'landing_page_scroll')\n\n  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n    const value = e.target.value\n    setInputValue(value)\n\n    // 追踪输入行为\n    trackAction('input', 'search_box', {\n      value_length: value.length,\n      has_content: value.length > 0\n    })\n  }\n\n  const handleSearch = () => {\n    trackClick('search_button', {\n      search_term: inputValue,\n      term_length: inputValue.length\n    })\n    console.log('搜索:', inputValue)\n  }\n\n  const handleIncrement = () => {\n    const newCount = clickCount + 1\n    setClickCount(newCount)\n\n    track('counter_increment', {\n      new_value: newCount,\n      page: 'comprehensive_example'\n    })\n  }\n\n  return (\n    <div style={{ padding: '20px', fontFamily: 'Arial, sans-serif' }}>\n      {/* Hero区域 */}\n      <div\n        ref={heroRef}\n        style={{\n          padding: '60px 20px',\n          background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\n          color: 'white',\n          borderRadius: '8px',\n          marginBottom: '30px',\n          textAlign: 'center'\n        }}\n      >\n        <h1 style={{ margin: '0 0 10px 0' }}>埋点SDK综合示例</h1>\n        <p style={{ margin: 0 }}>展示各种追踪功能的完整应用</p>\n      </div>\n\n      {/* 搜索区域 */}\n      <div style={{ marginBottom: '30px' }}>\n        <h3>搜索追踪</h3>\n        <div style={{ display: 'flex', gap: '10px' }}>\n          <input\n            type=\"text\"\n            value={inputValue}\n            onChange={handleInputChange}\n            placeholder=\"输入搜索内容...\"\n            style={{\n              padding: '8px 12px',\n              border: '1px solid #ddd',\n              borderRadius: '4px',\n              flex: 1\n            }}\n          />\n          <button\n            onClick={handleSearch}\n            style={{\n              padding: '8px 16px',\n              background: '#667eea',\n              color: 'white',\n              border: 'none',\n              borderRadius: '4px',\n              cursor: 'pointer'\n            }}\n          >\n            搜索\n          </button>\n        </div>\n        <p style={{ color: '#666', fontSize: '14px', marginTop: '5px' }}>\n          输入时会追踪输入行为\n        </p>\n      </div>\n\n      {/* 计数器区域 */}\n      <div style={{ marginBottom: '30px' }}>\n        <h3>交互追踪</h3>\n        <div style={{ textAlign: 'center', padding: '20px', background: '#f8f9fa', borderRadius: '8px' }}>\n          <div style={{ fontSize: '48px', fontWeight: 'bold', color: '#667eea', marginBottom: '10px' }}>\n            {clickCount}\n          </div>\n          <button\n            onClick={handleIncrement}\n            style={{\n              padding: '10px 20px',\n              background: '#28a745',\n              color: 'white',\n              border: 'none',\n              borderRadius: '4px',\n              cursor: 'pointer',\n              fontSize: '16px'\n            }}\n          >\n            点击增加 (追踪每次点击)\n          </button>\n        </div>\n      </div>\n\n      {/* 内容区域 */}\n      <div style={{ marginBottom: '30px' }}>\n        <h3>内容区域</h3>\n        {[...Array(10)].map((_, i) => (\n          <div\n            key={i}\n            style={{\n              padding: '15px',\n              background: i % 2 === 0 ? '#f8f9fa' : 'white',\n              borderRadius: '4px',\n              marginBottom: '10px'\n            }}\n          >\n            <h4>内容块 {i + 1}</h4>\n            <p style={{ margin: '5px 0', color: '#666' }}>\n              这是内容块 {i + 1}，用于测试滚动深度追踪。向下滚动查看更多内容。\n            </p>\n          </div>\n        ))}\n      </div>\n\n      {/* 控制面板 */}\n      <div style={{\n        padding: '20px',\n        background: '#fff3cd',\n        border: '1px solid #ffc107',\n        borderRadius: '4px'\n      }}>\n        <h4>追踪说明</h4>\n        <ul style={{ margin: '10px 0', paddingLeft: '20px' }}>\n          <li>页面加载时自动追踪页面浏览</li>\n          <li>Hero区域可见时触发可见性追踪</li>\n          <li>输入时追踪输入行为</li>\n          <li>点击搜索按钮追踪点击事件</li>\n          <li>每次增加计数器都追踪</li>\n          <li>滚动时追踪滚动深度（每20%）</li>\n          <li>页面停留时间定时上报</li>\n        </ul>\n        <p style={{ margin: '10px 0 0 0', fontSize: '14px', color: '#856404' }}>\n          打开浏览器控制台查看详细的追踪日志（需要开启debug模式）\n        </p>\n      </div>\n    </div>\n  )\n}\n\n/**\n * 在App.tsx中集成示例\n */\nexport function AnalyticsIntegrationExample() {\n  return (\n    <div>\n      <h1>埋点SDK集成示例</h1>\n\n      {/* 选择要查看的示例 */}\n      <div style={{ marginBottom: '20px' }}>\n        <h3>选择示例:</h3>\n        <nav style={{ display: 'flex', gap: '10px', flexWrap: 'wrap' }}>\n          <a href=\"#basic\" style={{ color: '#667eea' }}>基本使用</a>\n          <a href=\"#page\" style={{ color: '#667eea' }}>页面追踪</a>\n          <a href=\"#click\" style={{ color: '#667eea' }}>点击追踪</a>\n          <a href=\"#visibility\" style={{ color: '#667eea' }}>可见性追踪</a>\n          <a href=\"#scroll\" style={{ color: '#667eea' }}>滚动追踪</a>\n          <a href=\"#comprehensive\" style={{ color: '#667eea' }}>综合示例</a>\n        </nav>\n      </div>\n\n      <section id=\"basic\">\n        <BasicExample />\n      </section>\n\n      <hr style={{ margin: '40px 0' }} />\n\n      <section id=\"page\">\n        <PageTrackingExample />\n      </section>\n\n      <hr style={{ margin: '40px 0' }} />\n\n      <section id=\"click\">\n        <ClickTrackingExample />\n      </section>\n\n      <hr style={{ margin: '40px 0' }} />\n\n      <section id=\"visibility\">\n        <VisibilityTrackingExample />\n      </section>\n\n      <hr style={{ margin: '40px 0' }} />\n\n      <section id=\"scroll\">\n        <ScrollTrackingExample />\n      </section>\n\n      <hr style={{ margin: '40px 0' }} />\n\n      <section id=\"comprehensive\">\n        <ComprehensiveExample />\n      </section>\n    </div>\n  )\n}\n"
  },
  {
    "path": "src/sdk/analytics/hooks.ts",
    "content": "/**\n * 埋点SDK React Hooks\n */\n\nimport { useEffect, useCallback, useRef } from 'react'\nimport { getAnalytics } from './index'\n\n/**\n * 使用埋点SDK的Hook\n */\nexport function useAnalytics() {\n  const analytics = getAnalytics()\n\n  // 追踪页面浏览\n  const trackPageView = useCallback(() => {\n    analytics?.trackPageView()\n  }, [analytics])\n\n  // 追踪自定义事件\n  const track = useCallback((event: string, properties?: Record<string, any>) => {\n    analytics?.track(event, properties)\n  }, [analytics])\n\n  // 追踪按钮点击\n  const trackClick = useCallback((buttonName: string, properties?: Record<string, any>) => {\n    analytics?.trackClick(buttonName, properties)\n  }, [analytics])\n\n  // 追踪表单提交\n  const trackSubmit = useCallback((formName: string, properties?: Record<string, any>) => {\n    analytics?.trackSubmit(formName, properties)\n  }, [analytics])\n\n  // 追踪用户行为\n  const trackAction = useCallback((action: string, target: string, properties?: Record<string, any>) => {\n    analytics?.trackAction(action, target, properties)\n  }, [analytics])\n\n  // 追踪错误\n  const trackError = useCallback((error: Error | string, context?: Record<string, any>) => {\n    analytics?.trackError(error, context)\n  }, [analytics])\n\n  return {\n    trackPageView,\n    track,\n    trackClick,\n    trackSubmit,\n    trackAction,\n    trackError,\n    analytics\n  }\n}\n\n/**\n * 页面浏览追踪Hook\n */\nexport function usePageTracking(enabled: boolean = true) {\n  useEffect(() => {\n    if (enabled) {\n      const analytics = getAnalytics()\n      analytics?.trackPageView()\n    }\n  }, [enabled])\n}\n\n/**\n * 事件追踪Hook\n */\nexport function useEventTracking(eventName: string, properties?: Record<string, any>, dependencies: any[] = []) {\n  useEffect(() => {\n    const analytics = getAnalytics()\n    analytics?.track(eventName, properties)\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, dependencies)\n}\n\n/**\n * 点击追踪Hook\n */\nexport function useClickTracking(elementRef: React.RefObject<HTMLElement>, eventName: string, properties?: Record<string, any>) {\n  useEffect(() => {\n    const element = elementRef.current\n    if (!element) return\n\n    const handleClick = () => {\n      const analytics = getAnalytics()\n      analytics?.trackClick(eventName, properties)\n    }\n\n    element.addEventListener('click', handleClick)\n\n    return () => {\n      element.removeEventListener('click', handleClick)\n    }\n  }, [elementRef, eventName, properties])\n}\n\n/**\n * 可见性追踪Hook\n */\nexport function useVisibilityTracking(elementRef: React.RefObject<HTMLElement>, eventName: string, properties?: Record<string, any>) {\n  const hasTracked = useRef(false)\n\n  useEffect(() => {\n    const element = elementRef.current\n    if (!element) return\n\n    const observer = new IntersectionObserver(\n      (entries) => {\n        entries.forEach((entry) => {\n          if (entry.isIntersecting && !hasTracked.current) {\n            const analytics = getAnalytics()\n            analytics?.track(eventName, {\n              ...properties,\n              visible: true\n            })\n            hasTracked.current = true\n          }\n        })\n      },\n      { threshold: 0.5 }\n    )\n\n    observer.observe(element)\n\n    return () => {\n      observer.disconnect()\n    }\n  }, [elementRef, eventName, properties])\n}\n\n/**\n * 表单追踪Hook\n */\nexport function useFormTracking(formName: string, onSuccess?: (data: any) => void, onError?: (error: any) => void) {\n  const analytics = getAnalytics()\n\n  const trackSubmit = useCallback((data: any) => {\n    analytics?.trackSubmit(formName, {\n      success: true,\n      ...data\n    })\n    onSuccess?.(data)\n  }, [analytics, formName, onSuccess])\n\n  const trackError = useCallback((error: any) => {\n    analytics?.trackError(error, {\n      context: formName\n    })\n    onError?.(error)\n  }, [analytics, formName, onError])\n\n  return {\n    trackSubmit,\n    trackError\n  }\n}\n\n/**\n * 滚动追踪Hook\n */\nexport function useScrollTracking(threshold: number = 50, eventName: string = 'scroll_depth') {\n  const trackedDepths = useRef<Set<number>>(new Set())\n\n  useEffect(() => {\n    const handleScroll = () => {\n      const scrollHeight = document.documentElement.scrollHeight - window.innerHeight\n      const scrollPercentage = (window.scrollY / scrollHeight) * 100\n\n      const depth = Math.floor(scrollPercentage / threshold) * threshold\n\n      if (depth > 0 && depth <= 100 && !trackedDepths.current.has(depth)) {\n        trackedDepths.current.add(depth)\n\n        const analytics = getAnalytics()\n        analytics?.track(eventName, {\n          depth: `${depth}%`,\n          scroll_depth: depth\n        })\n      }\n    }\n\n    window.addEventListener('scroll', handleScroll, { passive: true })\n    return () => window.removeEventListener('scroll', handleScroll)\n  }, [threshold, eventName])\n}\n\n/**\n * 停留时间追踪Hook\n */\nexport function useDurationTracking(pageName: string, reportInterval: number = 30000) {\n  useEffect(() => {\n    const startTime = Date.now()\n    const analytics = getAnalytics()\n\n    // 定时上报停留时间\n    const interval = setInterval(() => {\n      const duration = Date.now() - startTime\n      analytics?.track('duration', {\n        page: pageName,\n        duration_ms: duration,\n        duration_seconds: Math.floor(duration / 1000)\n      })\n    }, reportInterval)\n\n    // 页面卸载时上报总停留时间\n    const handleBeforeUnload = () => {\n      const duration = Date.now() - startTime\n      analytics?.track('page_duration', {\n        page: pageName,\n        duration_ms: duration,\n        duration_seconds: Math.floor(duration / 1000)\n      })\n    }\n\n    window.addEventListener('beforeunload', handleBeforeUnload)\n\n    return () => {\n      clearInterval(interval)\n      window.removeEventListener('beforeunload', handleBeforeUnload)\n    }\n  }, [pageName, reportInterval])\n}\n"
  },
  {
    "path": "src/sdk/analytics/index.ts",
    "content": "/**\n * 埋点SDK - Analytics SDK\n * 使用GIF图片方式发送埋点数据\n */\n\n// 配置接口\ninterface AnalyticsConfig {\n  // 上报地址\n  reportUrl: string\n  // 应用ID\n  appId: string\n  // 用户ID\n  userId?: string\n  // 是否开启调试模式\n  debug?: boolean\n  // 是否自动收集页面浏览\n  autoTrack?: boolean\n  // 是否收集设备信息\n  collectDevice?: boolean\n  // 批量上报配置\n  batchConfig?: {\n    enabled: boolean\n    maxSize: number\n    timeout: number\n  }\n}\n\n// 事件数据接口\ninterface EventData {\n  // 事件名称\n  event: string\n  // 事件属性\n  properties?: Record<string, any>\n  // 时间戳\n  timestamp?: number\n  // 页面URL\n  url?: string\n  // 页面标题\n  title?: string\n  // 用户ID\n  userId?: string\n  // 设备信息\n  device?: DeviceInfo\n  // 会话ID\n  sessionId?: string\n}\n\n// 设备信息接口\ninterface DeviceInfo {\n  userAgent: string\n  platform: string\n  language: string\n  screen: string\n  timezone: string\n  fingerprint?: string\n}\n\n// 上报数据接口\ninterface ReportData extends EventData {\n  appId: string\n  sessionId: string\n  device: DeviceInfo\n}\n\nclass AnalyticsSDK {\n  private config: AnalyticsConfig\n  private sessionId: string\n  private eventQueue: EventData[] = []\n  private batchTimer: NodeJS.Timeout | null = null\n  private isInitialized = false\n\n  constructor(config: AnalyticsConfig) {\n    this.config = {\n      debug: false,\n      autoTrack: true,\n      collectDevice: true,\n      batchConfig: {\n        enabled: true,\n        maxSize: 10,\n        timeout: 5000\n      },\n      ...config\n    }\n    this.sessionId = this.generateSessionId()\n  }\n\n  /**\n   * 初始化SDK\n   */\n  init(): void {\n    if (this.isInitialized) {\n      this.warn('SDK already initialized')\n      return\n    }\n\n    this.log('Initializing Analytics SDK...')\n\n    // 自动收集页面浏览\n    if (this.config.autoTrack) {\n      this.trackPageView()\n      this.trackPageChanges()\n    }\n\n    // 设置错误监听\n    this.setupErrorTracking()\n\n    // 设置卸载监听\n    this.setupUnloadTracking()\n\n    this.isInitialized = true\n    this.log('Analytics SDK initialized successfully')\n  }\n\n  /**\n   * 追踪自定义事件\n   */\n  track(event: string, properties: Record<string, any> = {}): void {\n    const eventData: EventData = {\n      event,\n      properties,\n      timestamp: Date.now(),\n      url: window.location.href,\n      title: document.title,\n      userId: this.config.userId,\n      sessionId: this.sessionId\n    }\n\n    if (this.config.collectDevice) {\n      eventData.device = this.getDeviceInfo()\n    }\n\n    this.log('Tracking event:', eventData)\n\n    if (this.config.batchConfig?.enabled) {\n      this.addToBatch(eventData)\n    } else {\n      this.sendEvent(eventData)\n    }\n  }\n\n  /**\n   * 追踪页面浏览\n   */\n  trackPageView(): void {\n    this.track('page_view', {\n      referrer: document.referrer,\n      path: window.location.pathname,\n      search: window.location.search\n    })\n  }\n\n  /**\n   * 追踪用户行为\n   */\n  trackAction(action: string, target: string, properties: Record<string, any> = {}): void {\n    this.track('user_action', {\n      action,\n      target,\n      ...properties\n    })\n  }\n\n  /**\n   * 追踪按钮点击\n   */\n  trackClick(buttonName: string, properties: Record<string, any> = {}): void {\n    this.track('button_click', {\n      button_name: buttonName,\n      ...properties\n    })\n  }\n\n  /**\n   * 追踪表单提交\n   */\n  trackSubmit(formName: string, properties: Record<string, any> = {}): void {\n    this.track('form_submit', {\n      form_name: formName,\n      ...properties\n    })\n  }\n\n  /**\n   * 追踪错误\n   */\n  trackError(error: Error | string, context: Record<string, any> = {}): void {\n    const errorMessage = typeof error === 'string' ? error : error.message\n    const errorStack = typeof error === 'string' ? '' : error.stack\n\n    this.track('error', {\n      error_message: errorMessage,\n      error_stack: errorStack,\n      ...context\n    })\n  }\n\n  /**\n   * 设置用户ID\n   */\n  setUserId(userId: string): void {\n    this.config.userId = userId\n    this.log('User ID set:', userId)\n  }\n\n  /**\n   * 设置用户属性\n   */\n  setUserProperties(properties: Record<string, any>): void {\n    this.track('user_properties', properties)\n  }\n\n  /**\n   * 生成会话ID\n   */\n  private generateSessionId(): string {\n    return `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`\n  }\n\n  /**\n   * 获取设备信息\n   */\n  private getDeviceInfo(): DeviceInfo {\n    const screen = `${window.screen.width}x${window.screen.height}`\n    const fingerprint = this.generateFingerprint()\n\n    return {\n      userAgent: navigator.userAgent,\n      platform: navigator.platform,\n      language: navigator.language,\n      screen,\n      timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n      fingerprint\n    }\n  }\n\n  /**\n   * 生成设备指纹（简化版）\n   */\n  private generateFingerprint(): string {\n    const components = [\n      navigator.userAgent,\n      navigator.language,\n      screen.colorDepth,\n      new Date().getTimezoneOffset(),\n      !!window.sessionStorage,\n      !!window.localStorage,\n      navigator.platform\n    ]\n\n    const data = components.join('|')\n    let hash = 0\n    for (let i = 0; i < data.length; i++) {\n      const char = data.charCodeAt(i)\n      hash = ((hash << 5) - hash) + char\n      hash = hash & hash // Convert to 32bit integer\n    }\n    return Math.abs(hash).toString(16)\n  }\n\n  /**\n   * 添加到批量队列\n   */\n  private addToBatch(eventData: EventData): void {\n    this.eventQueue.push(eventData)\n\n    if (this.eventQueue.length >= (this.config.batchConfig?.maxSize || 10)) {\n      this.flushBatch()\n    } else {\n      this.startBatchTimer()\n    }\n  }\n\n  /**\n   * 开始批量定时器\n   */\n  private startBatchTimer(): void {\n    if (this.batchTimer) {\n      clearTimeout(this.batchTimer)\n    }\n\n    this.batchTimer = setTimeout(() => {\n      this.flushBatch()\n    }, this.config.batchConfig?.timeout || 5000)\n  }\n\n  /**\n   * 刷新批量队列\n   */\n  private flushBatch(): void {\n    if (this.eventQueue.length === 0) return\n\n    const events = [...this.eventQueue]\n    this.eventQueue = []\n\n    if (this.batchTimer) {\n      clearTimeout(this.batchTimer)\n      this.batchTimer = null\n    }\n\n    this.sendBatch(events)\n  }\n\n  /**\n   * 发送单个事件\n   */\n  private sendEvent(eventData: EventData): void {\n    const reportData: ReportData = {\n      ...eventData,\n      appId: this.config.appId,\n      sessionId: this.sessionId,\n      device: eventData.device || this.getDeviceInfo()\n    }\n\n    this.sendViaGIF(reportData)\n  }\n\n  /**\n   * 批量发送事件\n   */\n  private sendBatch(events: EventData[]): void {\n    const reportData = {\n      events,\n      appId: this.config.appId,\n      sessionId: this.sessionId,\n      timestamp: Date.now()\n    }\n\n    this.sendViaGIF(reportData, true)\n  }\n\n  /**\n   * 通过GIF图片发送数据\n   */\n  private sendViaGIF(data: any, isBatch = false): void {\n    try {\n      const params = new URLSearchParams()\n\n      // 将数据编码并添加到URL参数\n      const encodedData = this.btoa(JSON.stringify(data))\n      params.append('data', encodedData)\n\n      if (isBatch) {\n        params.append('batch', '1')\n      }\n\n      const url = `${this.config.reportUrl}?${params.toString()}`\n\n      // 创建Image对象发送请求\n      const img = new Image()\n      img.onload = () => this.log('Event sent successfully')\n      img.onerror = (error) => this.warn('Failed to send event:', error)\n      img.src = url\n\n    } catch (error) {\n      this.warn('Error sending event:', error)\n    }\n  }\n\n  /**\n   * Base64编码（兼容性处理）\n   */\n  private btoa(str: string): string {\n    try {\n      return window.btoa(unescape(encodeURIComponent(str)))\n    } catch (e) {\n      // 如果btoa失败，使用简单的编码\n      return Buffer.from(str).toString('base64')\n    }\n  }\n\n  /**\n   * 监听页面变化\n   */\n  private trackPageChanges(): void {\n    // 监听路由变化（针对单页应用）\n    const originalPushState = history.pushState\n    const originalReplaceState = history.replaceState\n\n    history.pushState = (...args) => {\n      originalPushState.apply(history, args)\n      this.trackPageView()\n    }\n\n    history.replaceState = (...args) => {\n      originalReplaceState.apply(history, args)\n      this.trackPageView()\n    }\n\n    // 监听popstate事件\n    window.addEventListener('popstate', () => {\n      this.trackPageView()\n    })\n\n    // 监听hash变化\n    window.addEventListener('hashchange', () => {\n      this.trackPageView()\n    })\n  }\n\n  /**\n   * 设置错误追踪\n   */\n  private setupErrorTracking(): void {\n    // 捕获JavaScript错误\n    window.addEventListener('error', (event) => {\n      this.trackError(event.message, {\n        filename: event.filename,\n        lineno: event.lineno,\n        colno: event.colno,\n        type: 'javascript_error'\n      })\n    })\n\n    // 捕获未处理的Promise rejection\n    window.addEventListener('unhandledrejection', (event) => {\n      this.trackError(event.reason, {\n        type: 'unhandled_rejection'\n      })\n    })\n\n    // 捕获资源加载错误\n    window.addEventListener('error', (event) => {\n      if (event.target !== window) {\n        this.trackError('Resource load error', {\n          target: (event.target as HTMLElement).tagName,\n          type: 'resource_error'\n        })\n      }\n    }, true)\n  }\n\n  /**\n   * 设置页面卸载追踪\n   */\n  private setupUnloadTracking(): void {\n    // 页面卸载时发送剩余事件\n    window.addEventListener('beforeunload', () => {\n      if (this.eventQueue.length > 0) {\n        // 使用sendBeacon确保数据发送\n        this.flushBatch()\n      }\n    })\n\n    // 页面隐藏时也发送\n    document.addEventListener('visibilitychange', () => {\n      if (document.hidden && this.eventQueue.length > 0) {\n        this.flushBatch()\n      }\n    })\n  }\n\n  /**\n   * 日志输出\n   */\n  private log(...args: any[]): void {\n    if (this.config.debug) {\n      console.log('[Analytics SDK]', ...args)\n    }\n  }\n\n  /**\n   * 警告输出\n   */\n  private warn(...args: any[]): void {\n    if (this.config.debug) {\n      console.warn('[Analytics SDK]', ...args)\n    }\n  }\n\n  /**\n   * 销毁SDK\n   */\n  destroy(): void {\n    this.log('Destroying Analytics SDK...')\n\n    // 刷新剩余事件\n    if (this.eventQueue.length > 0) {\n      this.flushBatch()\n    }\n\n    // 清除定时器\n    if (this.batchTimer) {\n      clearTimeout(this.batchTimer)\n      this.batchTimer = null\n    }\n\n    this.isInitialized = false\n    this.log('Analytics SDK destroyed')\n  }\n}\n\n// 导出单例模式\nlet analyticsInstance: AnalyticsSDK | null = null\n\nexport function initAnalytics(config: AnalyticsConfig): AnalyticsSDK {\n  if (!analyticsInstance) {\n    analyticsInstance = new AnalyticsSDK(config)\n    analyticsInstance.init()\n  }\n  return analyticsInstance\n}\n\nexport function getAnalytics(): AnalyticsSDK | null {\n  return analyticsInstance\n}\n\nexport { AnalyticsSDK }\nexport type { AnalyticsConfig, EventData }\n"
  },
  {
    "path": "src/sdk/analytics/types.d.ts",
    "content": "/**\n * 埋点SDK全局类型定义\n */\n\nimport { AnalyticsSDK } from './index'\n\ndeclare global {\n  interface Window {\n    /**\n     * 全局埋点SDK实例\n     */\n    analytics?: AnalyticsSDK\n\n    /**\n     * 埋点SDK配置（可选）\n     */\n    analyticsConfig?: {\n      reportUrl: string\n      appId: string\n      userId?: string\n      debug?: boolean\n    }\n  }\n}\n\nexport {}\n"
  },
  {
    "path": "src/sdk/fingerprint/README.md",
    "content": "# 指纹技术SDK (Fingerprint SDK)\n\n一个强大的浏览器指纹识别SDK，用于设备唯一标识和用户追踪。\n\n## 功能特性\n\n- 🔍 **全面的数据采集** - 收集浏览器、屏幕、Canvas、WebGL、音频等多种指纹特征\n- 🔐 **多种哈希算法** - 支持SHA-256、SHA-384、SHA-512、MD5等哈希算法\n- 💾 **本地存储管理** - 自动管理指纹数据的本地存储\n- 📊 **访问统计** - 跟踪首次访问时间、最后访问时间和访问次数\n- 🎯 **高置信度** - 基于数据完整性计算指纹置信度\n- 🔄 **指纹验证** - 支持指纹一致性验证和相似度比较\n- 📦 **TypeScript支持** - 完整的TypeScript类型定义\n\n## 快速开始\n\n### 基本使用\n\n```typescript\nimport { getFingerprint, getVisitorId } from \"@/sdk/fingerprint\";\n\n// 获取指纹\nconst result = await getFingerprint();\nconsole.log(\"Visitor ID:\", result.visitorId);\nconsole.log(\"Fingerprint Hash:\", result.hash);\nconsole.log(\"Confidence:\", result.confidence);\n\n// 获取访问者ID\nconst visitorId = getVisitorId();\nconsole.log(\"Visitor ID:\", visitorId);\n```\n\n### 高级使用\n\n```typescript\nimport { FingerprintSDK } from \"@/sdk/fingerprint\";\n\n// 创建自定义配置的SDK实例\nconst sdk = new FingerprintSDK({\n  includeCanvas: true,\n  includeWebGL: true,\n  includeAudio: true,\n  includeScreen: true,\n  includeTimezone: true,\n  includeFeatures: true,\n  storageKey: \"my_app_fingerprint\",\n  hashAlgorithm: \"sha256\",\n});\n\n// 获取指纹\nconst fingerprint = await sdk.getFingerprint();\n\n// 检查是否首次访问\nif (sdk.isFirstVisit()) {\n  console.log(\"Welcome, new visitor!\");\n} else {\n  const stats = sdk.getVisitStats();\n  console.log(\"Welcome back! Visit count:\", stats?.visitCount);\n}\n\n// 获取指纹详细信息\nconst details = sdk.getFingerprintDetails();\nconsole.log(\"Browser:\", details?.browser);\nconsole.log(\"Screen:\", details?.screen);\nconsole.log(\"Canvas:\", details?.canvas);\n```\n\n### 指纹验证\n\n```typescript\nimport { FingerprintSDK } from \"@/sdk/fingerprint\";\n\nconst sdk = new FingerprintSDK();\n\n// 验证指纹是否匹配\nconst isValid = await sdk.validateFingerprint(\"expected_hash\");\nconsole.log(\"Fingerprint valid:\", isValid);\n\n// 比较两个指纹的相似度\nconst similarity = sdk.compareFingerprints(\"other_hash\");\nconsole.log(\"Similarity:\", similarity + \"%\");\n```\n\n### 指纹导入导出\n\n```typescript\nimport { FingerprintSDK } from \"@/sdk/fingerprint\";\n\nconst sdk = new FingerprintSDK();\n\n// 导出指纹数据 (用于备份)\nconst exported = sdk.exportFingerprint();\nconsole.log(\"Exported:\", exported);\n\n// 导入指纹数据 (用于恢复)\nconst success = sdk.importFingerprint(exported);\nconsole.log(\"Imported:\", success);\n```\n\n## API 文档\n\n### FingerprintSDK\n\n#### 构造函数\n\n```typescript\nconstructor(options?: FingerprintOptions)\n```\n\n**参数:**\n\n- `options.includeCanvas` - 是否包含Canvas指纹 (默认: true)\n- `options.includeWebGL` - 是否包含WebGL指纹 (默认: true)\n- `options.includeAudio` - 是否包含音频指纹 (默认: true)\n- `options.includeScreen` - 是否包含屏幕信息 (默认: true)\n- `options.includeTimezone` - 是否包含时区信息 (默认: true)\n- `options.includeFeatures` - 是否包含特性支持信息 (默认: true)\n- `options.storageKey` - 本地存储键名 (默认: 'fingerprint_data')\n- `options.hashAlgorithm` - 哈希算法 (默认: 'sha256')\n\n#### 方法\n\n##### `getFingerprint(): Promise<FingerprintResult>`\n\n获取指纹，如果本地已有则复用，否则生成新的。\n\n**返回:** `Promise<FingerprintResult>`\n\n##### `generateFingerprint(): Promise<FingerprintResult>`\n\n生成新的指纹。\n\n**返回:** `Promise<FingerprintResult>`\n\n##### `validateFingerprint(expectedHash: string): Promise<boolean>`\n\n验证指纹是否匹配。\n\n**参数:**\n\n- `expectedHash` - 期望的指纹哈希\n\n**返回:** `Promise<boolean>`\n\n##### `getVisitorId(): string | null`\n\n获取访问者ID。\n\n**返回:** `string | null`\n\n##### `getHash(): string | null`\n\n获取指纹哈希。\n\n**返回:** `string | null`\n\n##### `getVisitStats(): VisitStats | null`\n\n获取访问统计。\n\n**返回:** `{ firstSeen: number; lastSeen: number; visitCount: number } | null`\n\n##### `clearFingerprint(): boolean`\n\n清除指纹数据。\n\n**返回:** `boolean`\n\n##### `exportFingerprint(): string`\n\n导出指纹数据。\n\n**返回:** `string` (Base64编码的指纹数据)\n\n##### `importFingerprint(exportedData: string): boolean`\n\n导入指纹数据。\n\n**参数:**\n\n- `exportedData` - 导出的指纹数据\n\n**返回:** `boolean`\n\n##### `isFirstVisit(): boolean`\n\n检查是否首次访问。\n\n**返回:** `boolean`\n\n##### `getFingerprintDetails(): Partial<FingerprintData> | null`\n\n获取指纹的详细信息。\n\n**返回:** `Partial<FingerprintData> | null`\n\n##### `compareFingerprints(otherHash: string): number`\n\n比较两个指纹的相似度。\n\n**参数:**\n\n- `otherHash` - 另一个指纹哈希\n\n**返回:** `number` (0-100的相似度百分比)\n\n## 类型定义\n\n### FingerprintResult\n\n```typescript\ninterface FingerprintResult {\n  hash: string; // 指纹哈希\n  confidence: number; // 置信度 (0-100)\n  data: FingerprintData; // 指纹数据\n  visitorId: string; // 访问者ID\n}\n```\n\n### FingerprintData\n\n```typescript\ninterface FingerprintData {\n  browser: BrowserInfo; // 浏览器信息\n  screen: ScreenInfo; // 屏幕信息\n  canvas: CanvasInfo; // Canvas信息\n  audio: AudioInfo; // 音频信息\n  timezone: TimeZoneInfo; // 时区信息\n  features: FeatureInfo; // 特性支持信息\n  timestamp: number; // 时间戳\n}\n```\n\n## 在React组件中使用\n\n```tsx\nimport { useEffect, useState } from \"react\";\nimport { getFingerprint } from \"@/sdk/fingerprint\";\n\nfunction UserProfile() {\n  const [fingerprint, setFingerprint] = useState<string | null>(null);\n  const [visitorId, setVisitorId] = useState<string | null>(null);\n\n  useEffect(() => {\n    async function loadFingerprint() {\n      const result = await getFingerprint();\n      setFingerprint(result.hash);\n      setVisitorId(result.visitorId);\n    }\n\n    loadFingerprint();\n  }, []);\n\n  return (\n    <div>\n      <p>Visitor ID: {visitorId}</p>\n      <p>Fingerprint: {fingerprint}</p>\n    </div>\n  );\n}\n```\n\n## 注意事项\n\n1. **隐私合规** - 使用指纹识别技术时，请确保遵守相关隐私法规（如GDPR、CCPA等）\n2. **指纹变化** - 某些情况下指纹可能会变化（如浏览器更新、硬件变更等）\n3. **隐私模式** - 在隐私模式下，某些指纹特征可能无法采集\n4. **跨浏览器** - 不同浏览器的指纹可能不同\n5. **存储限制** - LocalStorage有存储大小限制，请注意数据量\n\n## 性能优化建议\n\n1. **延迟加载** - 可以在页面加载后再获取指纹，避免阻塞首屏渲染\n2. **缓存结果** - 指纹结果会自动缓存，避免重复计算\n3. **选择性采集** - 根据需要选择采集哪些特征，减少计算开销\n4. **后台计算** - 对于耗时的操作（如音频指纹），可以在后台进行\n"
  },
  {
    "path": "src/sdk/fingerprint/collector.ts",
    "content": "/**\n * 指纹数据采集器\n * 负责收集各种浏览器和设备特征\n */\n\nimport type { BrowserInfo, ScreenInfo, CanvasInfo, AudioInfo, TimeZoneInfo, FeatureInfo } from './types';\n\nexport class FingerprintCollector {\n  /**\n   * 收集浏览器信息\n   */\n  static collectBrowserInfo(): BrowserInfo {\n    return {\n      userAgent: navigator.userAgent,\n      language: navigator.language,\n      languages: [...navigator.languages],\n      platform: navigator.platform,\n      cookieEnabled: navigator.cookieEnabled,\n      doNotTrack: navigator.doNotTrack,\n      hardwareConcurrency: navigator.hardwareConcurrency || 0,\n      deviceMemory: (navigator as any).deviceMemory,\n      maxTouchPoints: navigator.maxTouchPoints || 0,\n    };\n  }\n\n  /**\n   * 收集屏幕信息\n   */\n  static collectScreenInfo(): ScreenInfo {\n    const screen = window.screen;\n    return {\n      width: screen.width,\n      height: screen.height,\n      availWidth: screen.availWidth,\n      availHeight: screen.availHeight,\n      colorDepth: screen.colorDepth,\n      pixelDepth: screen.pixelDepth,\n      orientation: (screen as any).orientation?.type || null,\n      devicePixelRatio: window.devicePixelRatio,\n    };\n  }\n\n  /**\n   * 收集Canvas指纹\n   */\n  static collectCanvasInfo(): CanvasInfo {\n    const canvas = document.createElement('canvas');\n    const ctx = canvas.getContext('2d');\n\n    // Canvas指纹\n    let canvasFingerprint = '';\n    if (ctx) {\n      canvas.width = 280;\n      canvas.height = 60;\n      ctx.fillStyle = '#f60';\n      ctx.fillRect(100, 1, 62, 20);\n      ctx.fillStyle = '#069';\n      ctx.font = '14px Arial';\n      ctx.fillText('Hello, World! 🌍', 2, 15);\n      ctx.fillStyle = 'rgba(102, 204, 0, 0.7)';\n      ctx.fillText('Hello, World! 🌍', 4, 45);\n      canvasFingerprint = canvas.toDataURL();\n    }\n\n    // WebGL指纹\n    let webglFingerprint = '';\n    let webglVendor = '';\n    let webglRenderer = '';\n\n    try {\n      const glCanvas = document.createElement('canvas');\n      const gl = glCanvas.getContext('webgl') || glCanvas.getContext('experimental-webgl');\n\n      if (gl) {\n        // @ts-ignore\n        const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');\n        if (debugInfo) {\n          // @ts-ignore\n          webglVendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);\n          // @ts-ignore\n          webglRenderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);\n        }\n\n        // 生成WebGL指纹\n        // @ts-ignore\n        const fingerprint = this.getWebGLFingerprint(gl);\n        webglFingerprint = fingerprint;\n      }\n    } catch (e) {\n      console.warn('WebGL fingerprint collection failed:', e);\n    }\n\n    return {\n      canvasFingerprint,\n      webglFingerprint,\n      webglVendor,\n      webglRenderer,\n    };\n  }\n\n  /**\n   * 获取WebGL指纹\n   */\n  private static getWebGLFingerprint(gl: WebGLRenderingContext): string {\n    // 创建一个简单的WebGL场景\n    const vertexShader = gl.createShader(gl.VERTEX_SHADER);\n    gl.shaderSource(vertexShader!, 'attribute vec2 attr; void main() { gl_Position = vec4(attr, 0.0, 1.0); }');\n    gl.compileShader(vertexShader!);\n\n    const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n    gl.shaderSource(fragmentShader!, 'void main() { gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); }');\n    gl.compileShader(fragmentShader!);\n\n    const program = gl.createProgram();\n    gl.attachShader(program, vertexShader!);\n    gl.attachShader(program, fragmentShader!);\n    gl.linkProgram(program);\n    gl.useProgram(program);\n\n    // 获取一些WebGL参数\n    const parameters = [\n      gl.VENDOR,\n      gl.RENDERER,\n      gl.VERSION,\n      gl.SHADING_LANGUAGE_VERSION,\n    ];\n\n    return parameters.map(param => gl.getParameter(param)).join('|');\n  }\n\n  /**\n   * 收集音频指纹\n   */\n  static collectAudioInfo(): AudioInfo {\n    let audioFingerprint = '';\n\n    try {\n      const AudioContext = window.AudioContext || (window as any).webkitAudioContext;\n      if (AudioContext) {\n        const audioContext = new AudioContext();\n\n        // 创建一个简单的音频处理链\n        const oscillator = audioContext.createOscillator();\n        const analyser = audioContext.createAnalyser();\n        const gain = audioContext.createGain();\n        const processor = audioContext.createScriptProcessor(4096, 1, 1);\n\n        gain.gain.value = 0; // 静音\n        oscillator.type = 'triangle';\n        oscillator.frequency.value = 10000;\n\n        oscillator.connect(analyser);\n        analyser.connect(processor);\n        processor.connect(gain);\n        gain.connect(audioContext.destination);\n\n        oscillator.start(0);\n\n        // 收集音频上下文信息\n        audioFingerprint = JSON.stringify({\n          sampleRate: audioContext.sampleRate,\n          maxChannelCount: audioContext.destination.maxChannelCount,\n          channelCount: audioContext.destination.channelCount,\n          numberOfInputs: audioContext.destination.numberOfInputs,\n          numberOfOutputs: audioContext.destination.numberOfOutputs,\n        });\n\n        oscillator.stop();\n        audioContext.close();\n      }\n    } catch (e) {\n      console.warn('Audio fingerprint collection failed:', e);\n    }\n\n    return { audioFingerprint };\n  }\n\n  /**\n   * 收集时区信息\n   */\n  static collectTimeZoneInfo(): TimeZoneInfo {\n    return {\n      timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n      timezoneOffset: new Date().getTimezoneOffset(),\n      timezoneName: new Date().toString().match(/\\((.+)\\)/)?.[1] || '',\n    };\n  }\n\n  /**\n   * 收集特性支持信息\n   */\n  static collectFeatureInfo(): FeatureInfo {\n    const testCanvas = document.createElement('canvas');\n    const testAudio = document.createElement('audio');\n\n    return {\n      supportsWebGL: !!(\n        window.WebGLRenderingContext &&\n        (testCanvas.getContext('webgl') || testCanvas.getContext('experimental-webgl'))\n      ),\n      supportsWebGL2: !!(\n        window.WebGL2RenderingContext &&\n        testCanvas.getContext('webgl2')\n      ),\n      supportsCanvas: !!(testCanvas.getContext && testCanvas.getContext('2d')),\n      supportsAudio: !!(testAudio.canPlayType && testAudio.canPlayType('audio/mpeg')),\n      supportsLocalStorage: this.testLocalStorage(),\n      supportsSessionStorage: this.testSessionStorage(),\n      supportsIndexedDB: this.testIndexedDB(),\n    };\n  }\n\n  /**\n   * 测试LocalStorage是否可用\n   */\n  private static testLocalStorage(): boolean {\n    try {\n      const test = '__localStorage_test__';\n      localStorage.setItem(test, test);\n      localStorage.removeItem(test);\n      return true;\n    } catch (e) {\n      return false;\n    }\n  }\n\n  /**\n   * 测试SessionStorage是否可用\n   */\n  private static testSessionStorage(): boolean {\n    try {\n      const test = '__sessionStorage_test__';\n      sessionStorage.setItem(test, test);\n      sessionStorage.removeItem(test);\n      return true;\n    } catch (e) {\n      return false;\n    }\n  }\n\n  /**\n   * 测试IndexedDB是否可用\n   */\n  private static testIndexedDB(): boolean {\n    try {\n      return !!window.indexedDB;\n    } catch (e) {\n      return false;\n    }\n  }\n\n  /**\n   * 收集所有指纹数据\n   */\n  static collectAll(options: {\n    includeCanvas?: boolean;\n    includeWebGL?: boolean;\n    includeAudio?: boolean;\n    includeScreen?: boolean;\n    includeTimezone?: boolean;\n    includeFeatures?: boolean;\n  } = {}) {\n    const data: any = {\n      browser: this.collectBrowserInfo(),\n      timestamp: Date.now(),\n    };\n\n    if (options.includeScreen !== false) {\n      data.screen = this.collectScreenInfo();\n    }\n\n    if (options.includeCanvas !== false) {\n      data.canvas = this.collectCanvasInfo();\n    }\n\n    if (options.includeAudio !== false) {\n      data.audio = this.collectAudioInfo();\n    }\n\n    if (options.includeTimezone !== false) {\n      data.timezone = this.collectTimeZoneInfo();\n    }\n\n    if (options.includeFeatures !== false) {\n      data.features = this.collectFeatureInfo();\n    }\n\n    return data;\n  }\n}\n"
  },
  {
    "path": "src/sdk/fingerprint/examples.tsx",
    "content": "/**\n * 指纹SDK使用示例组件\n * 展示如何在React组件中使用指纹SDK\n */\n\nimport { useState } from 'react';\nimport {\n  useFingerprint,\n  useVisitorId,\n  useFingerprintCompare,\n  useVisitStats,\n  FingerprintSDK\n} from '../index';\nimport type { FingerprintResult } from './types';\n\n/**\n * 示例1: 基础使用 - 显示访问者信息\n */\nexport function BasicFingerprintExample() {\n  const { fingerprint, visitorId, hash, isLoading, isError, error } = useFingerprint();\n\n  if (isLoading) {\n    return <div className=\"p-4 bg-blue-50 rounded\">正在加载指纹信息...</div>;\n  }\n\n  if (isError) {\n    return <div className=\"p-4 bg-red-50 rounded text-red-600\">\n      加载失败: {error?.message}\n    </div>;\n  }\n\n  return (\n    <div className=\"p-4 bg-green-50 rounded\">\n      <h3 className=\"text-lg font-bold mb-2\">访客信息</h3>\n      <p><strong>访问者ID:</strong> {visitorId}</p>\n      <p><strong>指纹哈希:</strong> {hash?.substring(0, 16)}...</p>\n      <p><strong>置信度:</strong> {fingerprint?.confidence}%</p>\n    </div>\n  );\n}\n\n/**\n * 示例2: 访问统计\n */\nexport function VisitStatsExample() {\n  const stats = useVisitStats();\n\n  if (!stats) {\n    return <div className=\"p-4 bg-gray-50 rounded\">加载统计信息中...</div>;\n  }\n\n  return (\n    <div className=\"p-4 bg-purple-50 rounded\">\n      <h3 className=\"text-lg font-bold mb-2\">访问统计</h3>\n      <p><strong>首次访问:</strong> {new Date(stats.firstSeen).toLocaleString()}</p>\n      <p><strong>最后访问:</strong> {new Date(stats.lastSeen).toLocaleString()}</p>\n      <p><strong>访问次数:</strong> {stats.visitCount}</p>\n    </div>\n  );\n}\n\n/**\n * 示例3: 完整的指纹信息展示\n */\nexport function FullFingerprintExample() {\n  const {\n    fingerprint,\n    visitorId,\n    isLoading,\n    refresh,\n    clear,\n    regenerate\n  } = useFingerprint({\n    autoLoad: true,\n    onSuccess: (result) => {\n      console.log('指纹获取成功:', result);\n    },\n    onError: (error) => {\n      console.error('指纹获取失败:', error);\n    }\n  });\n\n  const [showDetails, setShowDetails] = useState(false);\n\n  if (isLoading) {\n    return <div className=\"p-4\">加载中...</div>;\n  }\n\n  if (!fingerprint) {\n    return <div className=\"p-4\">未找到指纹信息</div>;\n  }\n\n  return (\n    <div className=\"p-6 border rounded-lg shadow-md\">\n      <h2 className=\"text-2xl font-bold mb-4\">指纹信息详情</h2>\n\n      {/* 基本信息 */}\n      <div className=\"mb-4 p-4 bg-blue-50 rounded\">\n        <h3 className=\"font-bold mb-2\">基本信息</h3>\n        <p><strong>访问者ID:</strong> {visitorId}</p>\n        <p><strong>指纹哈希:</strong> {fingerprint.hash}</p>\n        <p><strong>置信度:</strong> {fingerprint.confidence}%</p>\n      </div>\n\n      {/* 操作按钮 */}\n      <div className=\"mb-4 flex gap-2\">\n        <button\n          onClick={refresh}\n          className=\"px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600\"\n        >\n          刷新\n        </button>\n        <button\n          onClick={() => regenerate()}\n          className=\"px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600\"\n        >\n          重新生成\n        </button>\n        <button\n          onClick={() => {\n            clear();\n            setShowDetails(false);\n          }}\n          className=\"px-4 py-2 bg-red-500 text-white rounded hover:bg-red-600\"\n        >\n          清除\n        </button>\n        <button\n          onClick={() => setShowDetails(!showDetails)}\n          className=\"px-4 py-2 bg-gray-500 text-white rounded hover:bg-gray-600\"\n        >\n          {showDetails ? '隐藏' : '显示'}详情\n        </button>\n      </div>\n\n      {/* 详细信息 */}\n      {showDetails && (\n        <div className=\"space-y-4\">\n          {/* 浏览器信息 */}\n          <div className=\"p-4 bg-gray-50 rounded\">\n            <h4 className=\"font-bold mb-2\">浏览器信息</h4>\n            <div className=\"text-sm space-y-1\">\n              <p><strong>User Agent:</strong> {fingerprint.data.browser.userAgent}</p>\n              <p><strong>语言:</strong> {fingerprint.data.browser.language}</p>\n              <p><strong>平台:</strong> {fingerprint.data.browser.platform}</p>\n              <p><strong>CPU核心数:</strong> {fingerprint.data.browser.hardwareConcurrency}</p>\n              <p><strong>设备内存:</strong> {fingerprint.data.browser.deviceMemory}GB</p>\n              <p><strong>触摸点:</strong> {fingerprint.data.browser.maxTouchPoints}</p>\n            </div>\n          </div>\n\n          {/* 屏幕信息 */}\n          <div className=\"p-4 bg-gray-50 rounded\">\n            <h4 className=\"font-bold mb-2\">屏幕信息</h4>\n            <div className=\"text-sm space-y-1\">\n              <p><strong>分辨率:</strong> {fingerprint.data.screen.width}x{fingerprint.data.screen.height}</p>\n              <p><strong>可用分辨率:</strong> {fingerprint.data.screen.availWidth}x{fingerprint.data.screen.availHeight}</p>\n              <p><strong>颜色深度:</strong> {fingerprint.data.screen.colorDepth}bit</p>\n              <p><strong>设备像素比:</strong> {fingerprint.data.screen.devicePixelRatio}</p>\n            </div>\n          </div>\n\n          {/* Canvas信息 */}\n          <div className=\"p-4 bg-gray-50 rounded\">\n            <h4 className=\"font-bold mb-2\">Canvas信息</h4>\n            <div className=\"text-sm space-y-1\">\n              <p><strong>Canvas指纹:</strong> {fingerprint.data.canvas.canvasFingerprint.substring(0, 50)}...</p>\n              <p><strong>WebGL指纹:</strong> {fingerprint.data.canvas.webglFingerprint.substring(0, 50)}...</p>\n              <p><strong>WebGL厂商:</strong> {fingerprint.data.canvas.webglVendor}</p>\n              <p><strong>WebGL渲染器:</strong> {fingerprint.data.canvas.webglRenderer}</p>\n            </div>\n          </div>\n\n          {/* 时区信息 */}\n          <div className=\"p-4 bg-gray-50 rounded\">\n            <h4 className=\"font-bold mb-2\">时区信息</h4>\n            <div className=\"text-sm space-y-1\">\n              <p><strong>时区:</strong> {fingerprint.data.timezone.timezone}</p>\n              <p><strong>时区偏移:</strong> {fingerprint.data.timezone.timezoneOffset}分钟</p>\n              <p><strong>时区名称:</strong> {fingerprint.data.timezone.timezoneName}</p>\n            </div>\n          </div>\n\n          {/* 特性支持 */}\n          <div className=\"p-4 bg-gray-50 rounded\">\n            <h4 className=\"font-bold mb-2\">特性支持</h4>\n            <div className=\"text-sm space-y-1\">\n              <p><strong>WebGL:</strong> {fingerprint.data.features.supportsWebGL ? '✓' : '✗'}</p>\n              <p><strong>WebGL2:</strong> {fingerprint.data.features.supportsWebGL2 ? '✓' : '✗'}</p>\n              <p><strong>Canvas:</strong> {fingerprint.data.features.supportsCanvas ? '✓' : '✗'}</p>\n              <p><strong>Audio:</strong> {fingerprint.data.features.supportsAudio ? '✓' : '✗'}</p>\n              <p><strong>LocalStorage:</strong> {fingerprint.data.features.supportsLocalStorage ? '✓' : '✗'}</p>\n              <p><strong>IndexedDB:</strong> {fingerprint.data.features.supportsIndexedDB ? '✓' : '✗'}</p>\n            </div>\n          </div>\n        </div>\n      )}\n    </div>\n  );\n}\n\n/**\n * 示例4: 指纹对比\n */\nexport function FingerprintCompareExample() {\n  const { similarity, compare } = useFingerprintCompare();\n  const [otherHash, setOtherHash] = useState('');\n\n  return (\n    <div className=\"p-4 border rounded-lg\">\n      <h3 className=\"text-lg font-bold mb-2\">指纹对比</h3>\n\n      <div className=\"mb-4\">\n        <input\n          type=\"text\"\n          value={otherHash}\n          onChange={(e) => setOtherHash(e.target.value)}\n          placeholder=\"输入要对比的指纹哈希\"\n          className=\"w-full p-2 border rounded\"\n        />\n      </div>\n\n      <button\n        onClick={() => compare(otherHash)}\n        className=\"px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600\"\n        disabled={!otherHash}\n      >\n        对比\n      </button>\n\n      {similarity !== null && (\n        <div className=\"mt-4 p-4 bg-gray-50 rounded\">\n          <p><strong>相似度:</strong> {similarity}%</p>\n          <div className=\"w-full bg-gray-200 rounded-full h-4 mt-2\">\n            <div\n              className=\"bg-blue-500 h-4 rounded-full\"\n              style={{ width: `${similarity}%` }}\n            />\n          </div>\n        </div>\n      )}\n    </div>\n  );\n}\n\n/**\n * 示例5: 高级用法 - 自定义SDK配置\n */\nexport function AdvancedFingerprintExample() {\n  const [customSdk] = useState(() => new FingerprintSDK({\n    storageKey: 'my_custom_fingerprint',\n    hashAlgorithm: 'sha512',\n    includeAudio: false, // 禁用音频指纹\n  }));\n\n  const [result, setResult] = useState<FingerprintResult | null>(null);\n\n  const handleGetFingerprint = async () => {\n    const fp = await customSdk.getFingerprint();\n    setResult(fp);\n  };\n\n  const handleExport = () => {\n    const exported = customSdk.exportFingerprint();\n    console.log('Exported fingerprint:', exported);\n    alert(`已导出指纹数据: ${exported.substring(0, 50)}...`);\n  };\n\n  const handleClear = () => {\n    customSdk.clearFingerprint();\n    setResult(null);\n  };\n\n  return (\n    <div className=\"p-4 border rounded-lg\">\n      <h3 className=\"text-lg font-bold mb-2\">高级用法</h3>\n\n      <div className=\"mb-4 flex gap-2\">\n        <button\n          onClick={handleGetFingerprint}\n          className=\"px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600\"\n        >\n          获取指纹\n        </button>\n        <button\n          onClick={handleExport}\n          className=\"px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600\"\n        >\n          导出\n        </button>\n        <button\n          onClick={handleClear}\n          className=\"px-4 py-2 bg-red-500 text-white rounded hover:bg-red-600\"\n        >\n          清除\n        </button>\n      </div>\n\n      {result && (\n        <div className=\"mt-4 p-4 bg-gray-50 rounded\">\n          <p><strong>访问者ID:</strong> {result.visitorId}</p>\n          <p><strong>指纹哈希:</strong> {result.hash.substring(0, 32)}...</p>\n          <p><strong>置信度:</strong> {result.confidence}%</p>\n        </div>\n      )}\n    </div>\n  );\n}\n\n/**\n * 示例6: 简单的访问者ID显示\n */\nexport function SimpleVisitorIdExample() {\n  const visitorId = useVisitorId();\n\n  return (\n    <div className=\"p-2 bg-blue-100 rounded inline-block\">\n      <span className=\"text-sm\">\n        访问者ID: <code className=\"bg-gray-200 px-2 py-1 rounded\">{visitorId || '加载中...'}</code>\n      </span>\n    </div>\n  );\n}\n\n/**\n * 组合示例 - 完整的指纹仪表板\n */\nexport function FingerprintDashboard() {\n  return (\n    <div className=\"container mx-auto p-4 space-y-6\">\n      <h1 className=\"text-3xl font-bold\">指纹SDK示例仪表板</h1>\n\n      <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n        <BasicFingerprintExample />\n        <VisitStatsExample />\n      </div>\n\n      <FullFingerprintExample />\n\n      <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n        <FingerprintCompareExample />\n        <AdvancedFingerprintExample />\n      </div>\n\n      <div className=\"text-center\">\n        <SimpleVisitorIdExample />\n      </div>\n    </div>\n  );\n}\n"
  },
  {
    "path": "src/sdk/fingerprint/hash.ts",
    "content": "/**\n * 指纹哈希生成器\n * 负责将采集的数据转换为唯一的哈希值\n */\n\nimport type { FingerprintData, FingerprintOptions } from './types';\n\nexport class FingerprintHasher {\n  /**\n   * 生成指纹哈希\n   */\n  static async generateHash(\n    data: FingerprintData,\n    options: FingerprintOptions = {}\n  ): Promise<string> {\n    const algorithm = options.hashAlgorithm || 'sha256';\n\n    // 将数据转换为字符串\n    const dataString = this.normalizeData(data);\n\n    switch (algorithm) {\n      case 'sha256':\n        return this.sha256(dataString);\n      case 'sha384':\n        return this.sha384(dataString);\n      case 'sha512':\n        return this.sha512(dataString);\n      case 'md5':\n        return this.md5(dataString);\n      case 'simple':\n        return this.simpleHash(dataString);\n      default:\n        return this.sha256(dataString);\n    }\n  }\n\n  /**\n   * 标准化数据为字符串\n   */\n  private static normalizeData(data: any): string {\n    // 过滤掉时间戳等会变化的字段\n    const stableData = { ...data };\n    delete stableData.timestamp;\n\n    // 按键排序并序列化\n    const sortedKeys = Object.keys(stableData).sort();\n    const normalized = sortedKeys.map(key => {\n      const value = stableData[key];\n      if (typeof value === 'object') {\n        return JSON.stringify(value, Object.keys(value).sort());\n      }\n      return String(value);\n    }).join('|');\n\n    return normalized;\n  }\n\n  /**\n   * SHA-256 哈希\n   */\n  private static async sha256(data: string): Promise<string> {\n    const msgBuffer = new TextEncoder().encode(data);\n    const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);\n    const hashArray = Array.from(new Uint8Array(hashBuffer));\n    return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\n  }\n\n  /**\n   * SHA-384 哈希\n   */\n  private static async sha384(data: string): Promise<string> {\n    const msgBuffer = new TextEncoder().encode(data);\n    const hashBuffer = await crypto.subtle.digest('SHA-384', msgBuffer);\n    const hashArray = Array.from(new Uint8Array(hashBuffer));\n    return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\n  }\n\n  /**\n   * SHA-512 哈希\n   */\n  private static async sha512(data: string): Promise<string> {\n    const msgBuffer = new TextEncoder().encode(data);\n    const hashBuffer = await crypto.subtle.digest('SHA-512', msgBuffer);\n    const hashArray = Array.from(new Uint8Array(hashBuffer));\n    return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\n  }\n\n  /**\n   * MD5 哈希 (简化版)\n   */\n  private static md5(data: string): string {\n    // 这是一个简化的MD5实现，生产环境建议使用crypto-js等库\n    const rotateLeft = (value: number, shift: number) => {\n      return (value << shift) | (value >>> (32 - shift));\n    };\n\n    const addUnsigned = (a: number, b: number) => {\n      const lsw = (a & 0xFFFF) + (b & 0xFFFF);\n      const msw = (a >> 16) + (b >> 16) + (lsw >> 16);\n      return (msw << 16) | (lsw & 0xFFFF);\n    };\n\n    const f = (x: number, y: number, z: number) => (x & y) | (~x & z);\n    const g = (x: number, y: number, z: number) => (x & z) | (y & ~z);\n    const h = (x: number, y: number, z: number) => x ^ y ^ z;\n    const i = (x: number, y: number, z: number) => y ^ (x | ~z);\n\n    const ff = (a: number, b: number, c: number, d: number, x: number, s: number, ac: number) => {\n      a = addUnsigned(a, addUnsigned(addUnsigned(f(b, c, d), x), ac));\n      return addUnsigned(rotateLeft(a, s), b);\n    };\n\n    const gg = (a: number, b: number, c: number, d: number, x: number, s: number, ac: number) => {\n      a = addUnsigned(a, addUnsigned(addUnsigned(g(b, c, d), x), ac));\n      return addUnsigned(rotateLeft(a, s), b);\n    };\n\n    const hh = (a: number, b: number, c: number, d: number, x: number, s: number, ac: number) => {\n      a = addUnsigned(a, addUnsigned(addUnsigned(h(b, c, d), x), ac));\n      return addUnsigned(rotateLeft(a, s), b);\n    };\n\n    const ii = (a: number, b: number, c: number, d: number, x: number, s: number, ac: number) => {\n      a = addUnsigned(a, addUnsigned(addUnsigned(i(b, c, d), x), ac));\n      return addUnsigned(rotateLeft(a, s), b);\n    };\n\n    const convertToWordArray = (str: string) => {\n      let lWordCount: number;\n      const lMessageLength = str.length;\n      const lNumberOfWordsTemp1 = lMessageLength + 8;\n      const lNumberOfWordsTemp2 = (lNumberOfWordsTemp1 - (lNumberOfWordsTemp1 % 64)) / 64;\n      const lNumberOfWords = (lNumberOfWordsTemp2 + 1) * 16;\n      const lWordArray: number[] = Array(lNumberOfWords - 1).fill(0);\n      let lBytePosition = 0;\n      let lByteCount = 0;\n\n      while (lByteCount < lMessageLength) {\n        lWordCount = (lByteCount - (lByteCount % 4)) / 4;\n        lBytePosition = (lByteCount % 4) * 8;\n        lWordArray[lWordCount] = lWordArray[lWordCount] | (str.charCodeAt(lByteCount) << lBytePosition);\n        lByteCount++;\n      }\n\n      lWordCount = (lByteCount - (lByteCount % 4)) / 4;\n      lBytePosition = (lByteCount % 4) * 8;\n      lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);\n      lWordArray[lNumberOfWords - 2] = lMessageLength << 3;\n      lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;\n\n      return lWordArray;\n    };\n\n    const wordToHex = (value: number) => {\n      let hex = '';\n      for (let i = 0; i <= 3; i++) {\n        const byte = (value >>> (i * 8)) & 255;\n        hex += byte.toString(16).padStart(2, '0');\n      }\n      return hex;\n    };\n\n    const x = convertToWordArray(data);\n    let a = 0x67452301;\n    let b = 0xEFCDAB89;\n    let c = 0x98BADCFE;\n    let d = 0x10325476;\n\n    const S11 = 7, S12 = 12, S13 = 17, S14 = 22;\n    const S21 = 5, S22 = 9, S23 = 14, S24 = 20;\n    const S31 = 4, S32 = 11, S33 = 16, S34 = 23;\n    const S41 = 6, S42 = 10, S43 = 15, S44 = 21;\n\n    for (let k = 0; k < x.length; k += 16) {\n      const AA = a;\n      const BB = b;\n      const CC = c;\n      const DD = d;\n\n      a = ff(a, b, c, d, x[k + 0], S11, 0xD76AA478);\n      d = ff(d, a, b, c, x[k + 1], S12, 0xE8C7B756);\n      c = ff(c, d, a, b, x[k + 2], S13, 0x242070DB);\n      b = ff(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);\n      a = ff(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);\n      d = ff(d, a, b, c, x[k + 5], S12, 0x4787C62A);\n      c = ff(c, d, a, b, x[k + 6], S13, 0xA8304613);\n      b = ff(b, c, d, a, x[k + 7], S14, 0xFD469501);\n      a = ff(a, b, c, d, x[k + 8], S11, 0x698098D8);\n      d = ff(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);\n      c = ff(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);\n      b = ff(b, c, d, a, x[k + 11], S14, 0x895CD7BE);\n      a = ff(a, b, c, d, x[k + 12], S11, 0x6B901122);\n      d = ff(d, a, b, c, x[k + 13], S12, 0xFD987193);\n      c = ff(c, d, a, b, x[k + 14], S13, 0xA679438E);\n      b = ff(b, c, d, a, x[k + 15], S14, 0x49B40821);\n      a = gg(a, b, c, d, x[k + 1], S21, 0xF61E2562);\n      d = gg(d, a, b, c, x[k + 6], S22, 0xC040B340);\n      c = gg(c, d, a, b, x[k + 11], S23, 0x265E5A51);\n      b = gg(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);\n      a = gg(a, b, c, d, x[k + 5], S21, 0xD62F105D);\n      d = gg(d, a, b, c, x[k + 10], S22, 0x2441453);\n      c = gg(c, d, a, b, x[k + 15], S23, 0xD8A1E681);\n      b = gg(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);\n      a = gg(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);\n      d = gg(d, a, b, c, x[k + 14], S22, 0xC33707D6);\n      c = gg(c, d, a, b, x[k + 3], S23, 0xF4D50D87);\n      b = gg(b, c, d, a, x[k + 8], S24, 0x455A14ED);\n      a = gg(a, b, c, d, x[k + 13], S21, 0xA9E3E905);\n      d = gg(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);\n      c = gg(c, d, a, b, x[k + 7], S23, 0x676F02D9);\n      b = gg(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);\n      a = hh(a, b, c, d, x[k + 5], S31, 0xFFFA3942);\n      d = hh(d, a, b, c, x[k + 8], S32, 0x8771F681);\n      c = hh(c, d, a, b, x[k + 11], S33, 0x6D9D6122);\n      b = hh(b, c, d, a, x[k + 14], S34, 0xFDE5380C);\n      a = hh(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);\n      d = hh(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);\n      c = hh(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);\n      b = hh(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);\n      a = hh(a, b, c, d, x[k + 13], S31, 0x289B7EC6);\n      d = hh(d, a, b, c, x[k + 0], S32, 0xEAA127FA);\n      c = hh(c, d, a, b, x[k + 3], S33, 0xD4EF3085);\n      b = hh(b, c, d, a, x[k + 6], S34, 0x4881D05);\n      a = hh(a, b, c, d, x[k + 9], S31, 0xD9D4D039);\n      d = hh(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);\n      c = hh(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);\n      b = hh(b, c, d, a, x[k + 2], S34, 0xC4AC5665);\n      a = ii(a, b, c, d, x[k + 0], S41, 0xF4292244);\n      d = ii(d, a, b, c, x[k + 7], S42, 0x432AFF97);\n      c = ii(c, d, a, b, x[k + 14], S43, 0xAB9423A7);\n      b = ii(b, c, d, a, x[k + 5], S44, 0xFC93A039);\n      a = ii(a, b, c, d, x[k + 12], S41, 0x655B59C3);\n      d = ii(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);\n      c = ii(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);\n      b = ii(b, c, d, a, x[k + 1], S44, 0x85845DD1);\n      a = ii(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);\n      d = ii(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);\n      c = ii(c, d, a, b, x[k + 6], S43, 0xA3014314);\n      b = ii(b, c, d, a, x[k + 13], S44, 0x4E0811A1);\n      a = ii(a, b, c, d, x[k + 4], S41, 0xF7537E82);\n      d = ii(d, a, b, c, x[k + 11], S42, 0xBD3AF235);\n      c = ii(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);\n      b = ii(b, c, d, a, x[k + 9], S44, 0xEB86D391);\n\n      a = addUnsigned(a, AA);\n      b = addUnsigned(b, BB);\n      c = addUnsigned(c, CC);\n      d = addUnsigned(d, DD);\n    }\n\n    return (wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d)).toLowerCase();\n  }\n\n  /**\n   * 简单哈希 (用于快速生成)\n   */\n  private static simpleHash(data: string): string {\n    let hash = 0;\n    if (data.length === 0) return hash.toString(16);\n\n    for (let i = 0; i < data.length; i++) {\n      const char = data.charCodeAt(i);\n      hash = ((hash << 5) - hash) + char;\n      hash = hash & hash; // Convert to 32bit integer\n    }\n\n    return Math.abs(hash).toString(16);\n  }\n\n  /**\n   * 生成访问者ID\n   */\n  static generateVisitorId(): string {\n    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n      const r = Math.random() * 16 | 0;\n      const v = c === 'x' ? r : (r & 0x3 | 0x8);\n      return v.toString(16);\n    });\n  }\n\n  /**\n   * 计算置信度 (基于收集的数据完整性)\n   */\n  static calculateConfidence(data: FingerprintData): number {\n    let score = 0;\n    let maxScore = 0;\n\n    // 浏览器信息 (必需)\n    if (data.browser?.userAgent) score += 20;\n    maxScore += 20;\n\n    // 屏幕信息\n    if (data.screen?.width && data.screen?.height) score += 15;\n    maxScore += 15;\n\n    // Canvas指纹\n    if (data.canvas?.canvasFingerprint) score += 20;\n    maxScore += 20;\n\n    // WebGL指纹\n    if (data.canvas?.webglFingerprint) score += 15;\n    maxScore += 15;\n\n    // 音频指纹\n    if (data.audio?.audioFingerprint) score += 10;\n    maxScore += 10;\n\n    // 时区信息\n    if (data.timezone?.timezone) score += 10;\n    maxScore += 10;\n\n    // 特性支持\n    if (data.features) score += 10;\n    maxScore += 10;\n\n    return Math.round((score / maxScore) * 100);\n  }\n}\n"
  },
  {
    "path": "src/sdk/fingerprint/hooks.ts",
    "content": "/**\n * 指纹SDK的React Hooks\n * 提供便捷的React集成方式\n */\n\nimport { useState, useEffect, useCallback, useRef } from 'react';\nimport { FingerprintSDK } from './index';\nimport type { FingerprintResult, FingerprintOptions } from './types';\n\nexport interface UseFingerprintOptions extends FingerprintOptions {\n  /**\n   * 是否在组件挂载时自动获取指纹\n   * @default true\n   */\n  autoLoad?: boolean;\n\n  /**\n   * 获取指纹成功后的回调\n   */\n  onSuccess?: (result: FingerprintResult) => void;\n\n  /**\n   * 获取指纹失败后的回调\n   */\n  onError?: (error: Error) => void;\n}\n\nexport interface UseFingerprintReturn {\n  /**\n   * 指纹结果\n   */\n  fingerprint: FingerprintResult | null;\n\n  /**\n   * 访问者ID\n   */\n  visitorId: string | null;\n\n  /**\n   * 指纹哈希\n   */\n  hash: string | null;\n\n  /**\n   * 置信度\n   */\n  confidence: number | null;\n\n  /**\n   * 是否正在加载\n   */\n  isLoading: boolean;\n\n  /**\n   * 是否加载出错\n   */\n  isError: boolean;\n\n  /**\n   * 错误信息\n   */\n  error: Error | null;\n\n  /**\n   * 是否首次访问\n   */\n  isFirstVisit: boolean | null;\n\n  /**\n   * 访问统计\n   */\n  visitStats: {\n    firstSeen: number;\n    lastSeen: number;\n    visitCount: number;\n  } | null;\n\n  /**\n   * 刷新指纹\n   */\n  refresh: () => Promise<void>;\n\n  /**\n   * 清除指纹\n   */\n  clear: () => boolean;\n\n  /**\n   * 重新生成指纹\n   */\n  regenerate: () => Promise<FingerprintResult>;\n}\n\n/**\n * 指纹SDK的React Hook\n *\n * @example\n * ```tsx\n * function MyComponent() {\n *   const { fingerprint, visitorId, isLoading, refresh } = useFingerprint();\n *\n *   if (isLoading) return <div>Loading...</div>;\n *\n *   return (\n *     <div>\n *       <p>Visitor ID: {visitorId}</p>\n *       <p>Fingerprint: {fingerprint?.hash}</p>\n *       <button onClick={refresh}>Refresh</button>\n *     </div>\n *   );\n * }\n * ```\n */\nexport function useFingerprint(options: UseFingerprintOptions = {}): UseFingerprintReturn {\n  const {\n    autoLoad = true,\n    onSuccess,\n    onError,\n    ...sdkOptions\n  } = options;\n\n  const [fingerprint, setFingerprint] = useState<FingerprintResult | null>(null);\n  const [isLoading, setIsLoading] = useState(false);\n  const [isError, setIsError] = useState(false);\n  const [error, setError] = useState<Error | null>(null);\n\n  const sdkRef = useRef<FingerprintSDK | null>(null);\n\n  // 初始化SDK\n  useEffect(() => {\n    sdkRef.current = new FingerprintSDK(sdkOptions);\n  }, [JSON.stringify(sdkOptions)]);\n\n  // 获取指纹\n  const loadFingerprint = useCallback(async () => {\n    if (!sdkRef.current) return;\n\n    setIsLoading(true);\n    setIsError(false);\n    setError(null);\n\n    try {\n      const result = await sdkRef.current.getFingerprint();\n      setFingerprint(result);\n      onSuccess?.(result);\n    } catch (err) {\n      const error = err instanceof Error ? err : new Error('Failed to load fingerprint');\n      setIsError(true);\n      setError(error);\n      onError?.(error);\n    } finally {\n      setIsLoading(false);\n    }\n  }, [onSuccess, onError]);\n\n  // 自动加载\n  useEffect(() => {\n    if (autoLoad) {\n      loadFingerprint();\n    }\n  }, [autoLoad, loadFingerprint]);\n\n  // 刷新指纹\n  const refresh = useCallback(async () => {\n    await loadFingerprint();\n  }, [loadFingerprint]);\n\n  // 清除指纹\n  const clear = useCallback(() => {\n    if (!sdkRef.current) return false;\n\n    const success = sdkRef.current.clearFingerprint();\n    if (success) {\n      setFingerprint(null);\n    }\n    return success;\n  }, []);\n\n  // 重新生成指纹\n  const regenerate = useCallback(async () => {\n    if (!sdkRef.current) {\n      throw new Error('SDK not initialized');\n    }\n\n    setIsLoading(true);\n    setIsError(false);\n    setError(null);\n\n    try {\n      const result = await sdkRef.current.regenerateFingerprint();\n      setFingerprint(result);\n      onSuccess?.(result);\n      return result;\n    } catch (err) {\n      const error = err instanceof Error ? err : new Error('Failed to regenerate fingerprint');\n      setIsError(true);\n      setError(error);\n      onError?.(error);\n      throw error;\n    } finally {\n      setIsLoading(false);\n    }\n  }, [onSuccess, onError]);\n\n  // 获取访问者ID\n  const visitorId = fingerprint?.visitorId ?? null;\n\n  // 获取指纹哈希\n  const hash = fingerprint?.hash ?? null;\n\n  // 获取置信度\n  const confidence = fingerprint?.confidence ?? null;\n\n  // 获取是否首次访问\n  const isFirstVisit = useCallback(() => {\n    if (!sdkRef.current) return null;\n    return sdkRef.current.isFirstVisit();\n  }, []);\n\n  // 获取访问统计\n  const visitStats = useCallback(() => {\n    if (!sdkRef.current) return null;\n    return sdkRef.current.getVisitStats();\n  }, []);\n\n  return {\n    fingerprint,\n    visitorId,\n    hash,\n    confidence,\n    isLoading,\n    isError,\n    error,\n    isFirstVisit: isFirstVisit(),\n    visitStats: visitStats(),\n    refresh,\n    clear,\n    regenerate,\n  };\n}\n\n/**\n * 简化版的指纹Hook，只返回访问者ID\n *\n * @example\n * ```tsx\n * function MyComponent() {\n *   const visitorId = useVisitorId();\n *   return <div>Visitor: {visitorId || 'Loading...'}</div>;\n * }\n * ```\n */\nexport function useVisitorId(): string | null {\n  const [visitorId, setVisitorId] = useState<string | null>(null);\n\n  useEffect(() => {\n    const sdk = new FingerprintSDK();\n\n    async function loadVisitorId() {\n      const id = sdk.getVisitorId();\n      if (id) {\n        setVisitorId(id);\n      } else {\n        const result = await sdk.getFingerprint();\n        setVisitorId(result.visitorId);\n      }\n    }\n\n    loadVisitorId();\n  }, []);\n\n  return visitorId;\n}\n\n/**\n * 指纹对比Hook\n * 用于比较两个指纹的相似度\n *\n * @example\n * ```tsx\n * function FingerprintCompare({ otherHash }) {\n *   const { similarity, compare } = useFingerprintCompare();\n *\n *   return (\n *     <div>\n *       <p>Similarity: {similarity}%</p>\n *       <button onClick={() => compare(otherHash)}>Compare</button>\n *     </div>\n *   );\n * }\n * ```\n */\nexport function useFingerprintCompare() {\n  const [similarity, setSimilarity] = useState<number | null>(null);\n  const sdkRef = useRef<FingerprintSDK | null>(null);\n\n  useEffect(() => {\n    sdkRef.current = new FingerprintSDK();\n  }, []);\n\n  const compare = useCallback((otherHash: string) => {\n    if (!sdkRef.current) return;\n\n    const result = sdkRef.current.compareFingerprints(otherHash);\n    setSimilarity(result);\n  }, []);\n\n  return { similarity, compare };\n}\n\n/**\n * 指纹统计Hook\n * 用于访问统计\n *\n * @example\n * ```tsx\n * function VisitStats() {\n *   const stats = useVisitStats();\n *\n *   if (!stats) return <div>Loading...</div>;\n *\n *   return (\n *     <div>\n *       <p>First visit: {new Date(stats.firstSeen).toLocaleString()}</p>\n *       <p>Last visit: {new Date(stats.lastSeen).toLocaleString()}</p>\n *       <p>Visit count: {stats.visitCount}</p>\n *     </div>\n *   );\n * }\n * ```\n */\nexport function useVisitStats() {\n  const [stats, setStats] = useState<{\n    firstSeen: number;\n    lastSeen: number;\n    visitCount: number;\n  } | null>(null);\n\n  useEffect(() => {\n    const sdk = new FingerprintSDK();\n    const visitStats = sdk.getVisitStats();\n    setStats(visitStats);\n  }, []);\n\n  return stats;\n}\n"
  },
  {
    "path": "src/sdk/fingerprint/index.ts",
    "content": "/**\n * 指纹技术SDK\n * 用于浏览器指纹识别和设备唯一标识\n *\n * @example\n * ```typescript\n * import { FingerprintSDK } from '@/sdk/fingerprint';\n *\n * // 初始化SDK\n * const sdk = new FingerprintSDK();\n *\n * // 获取指纹\n * const result = await sdk.getFingerprint();\n * console.log('Visitor ID:', result.visitorId);\n * console.log('Fingerprint Hash:', result.hash);\n * ```\n */\n\nimport { FingerprintCollector } from './collector';\nimport { FingerprintHasher } from './hash';\nimport { FingerprintStorage } from './storage';\nimport type { FingerprintData, FingerprintOptions, FingerprintResult, StorageData } from './types';\n\nexport class FingerprintSDK {\n  private storage: FingerprintStorage;\n  private options: Required<FingerprintOptions>;\n  private currentFingerprint: FingerprintResult | null = null;\n\n  constructor(options: FingerprintOptions = {}) {\n    this.options = {\n      includeCanvas: options.includeCanvas ?? true,\n      includeWebGL: options.includeWebGL ?? true,\n      includeAudio: options.includeAudio ?? true,\n      includeScreen: options.includeScreen ?? true,\n      includeTimezone: options.includeTimezone ?? true,\n      includeFeatures: options.includeFeatures ?? true,\n      storageKey: options.storageKey ?? 'fingerprint_data',\n      hashAlgorithm: options.hashAlgorithm ?? 'sha256',\n    };\n\n    this.storage = new FingerprintStorage(this.options.storageKey);\n  }\n\n  /**\n   * 获取指纹 (主要方法)\n   * 如果本地已有指纹则复用，否则生成新的\n   */\n  async getFingerprint(): Promise<FingerprintResult> {\n    // 检查本地是否已有指纹\n    if (this.storage.exists()) {\n      const storedData = this.storage.load()!;\n\n      // 验证指纹是否仍然有效\n      const isValid = await this.validateFingerprint(storedData.hash);\n\n      if (isValid) {\n        // 更新访问统计\n        this.storage.updateVisit();\n\n        // 重新采集数据以获取最新信息\n        const currentData = FingerprintCollector.collectAll(this.options);\n\n        this.currentFingerprint = {\n          hash: storedData.hash,\n          visitorId: storedData.visitorId,\n          confidence: FingerprintHasher.calculateConfidence(currentData),\n          data: currentData,\n        };\n\n        return this.currentFingerprint;\n      }\n    }\n\n    // 生成新指纹\n    return await this.generateFingerprint();\n  }\n\n  /**\n   * 生成新的指纹\n   */\n  async generateFingerprint(): Promise<FingerprintResult> {\n    // 采集指纹数据\n    const data = FingerprintCollector.collectAll(this.options) as FingerprintData;\n\n    // 生成哈希\n    const hash = await FingerprintHasher.generateHash(data, this.options);\n\n    // 生成访问者ID\n    const visitorId = FingerprintHasher.generateVisitorId();\n\n    // 计算置信度\n    const confidence = FingerprintHasher.calculateConfidence(data);\n\n    // 保存到本地存储\n    const storageData: StorageData = {\n      hash,\n      visitorId,\n      firstSeen: Date.now(),\n      lastSeen: Date.now(),\n      visitCount: 1,\n    };\n    this.storage.save(storageData);\n\n    this.currentFingerprint = {\n      hash,\n      visitorId,\n      confidence,\n      data,\n    };\n\n    return this.currentFingerprint;\n  }\n\n  /**\n   * 验证指纹是否匹配\n   */\n  async validateFingerprint(expectedHash: string): Promise<boolean> {\n    try {\n      // 重新采集数据\n      const currentData = FingerprintCollector.collectAll(this.options);\n\n      // 生成新的哈希\n      const currentHash = await FingerprintHasher.generateHash(currentData, this.options);\n\n      // 比较哈希\n      return currentHash === expectedHash;\n    } catch (e) {\n      console.warn('Fingerprint validation failed:', e);\n      return false;\n    }\n  }\n\n  /**\n   * 获取访问者ID\n   */\n  getVisitorId(): string | null {\n    return this.storage.getVisitorId();\n  }\n\n  /**\n   * 获取指纹哈希\n   */\n  getHash(): string | null {\n    return this.storage.getHash();\n  }\n\n  /**\n   * 获取访问统计\n   */\n  getVisitStats(): { firstSeen: number; lastSeen: number; visitCount: number } | null {\n    return this.storage.getVisitStats();\n  }\n\n  /**\n   * 清除指纹数据\n   */\n  clearFingerprint(): boolean {\n    this.currentFingerprint = null;\n    return this.storage.clear();\n  }\n\n  /**\n   * 导出指纹数据\n   */\n  exportFingerprint(): string {\n    return this.storage.export();\n  }\n\n  /**\n   * 导入指纹数据\n   */\n  importFingerprint(exportedData: string): boolean {\n    return this.storage.import(exportedData);\n  }\n\n  /**\n   * 获取当前指纹数据\n   */\n  getCurrentFingerprint(): FingerprintResult | null {\n    return this.currentFingerprint;\n  }\n\n  /**\n   * 重新生成指纹\n   */\n  async regenerateFingerprint(): Promise<FingerprintResult> {\n    this.clearFingerprint();\n    return await this.getFingerprint();\n  }\n\n  /**\n   * 检查是否首次访问\n   */\n  isFirstVisit(): boolean {\n    const stats = this.storage.getVisitStats();\n    return stats === null || stats.visitCount <= 1;\n  }\n\n  /**\n   * 获取指纹的详细信息 (用于调试)\n   */\n  getFingerprintDetails(): Partial<FingerprintData> | null {\n    if (!this.currentFingerprint) {\n      return null;\n    }\n\n    return {\n      browser: this.currentFingerprint.data.browser,\n      screen: this.currentFingerprint.data.screen,\n      canvas: this.currentFingerprint.data.canvas,\n      audio: this.currentFingerprint.data.audio,\n      timezone: this.currentFingerprint.data.timezone,\n      features: this.currentFingerprint.data.features,\n    };\n  }\n\n  /**\n   * 比较两个指纹的相似度\n   */\n  compareFingerprints(otherHash: string): number {\n    if (!this.currentFingerprint) {\n      return 0;\n    }\n\n    // 简单的字符串相似度比较\n    const hash1 = this.currentFingerprint.hash;\n    const hash2 = otherHash;\n\n    if (hash1 === hash2) return 100;\n\n    // 计算汉明距离 (对于相同长度的哈希)\n    let distance = 0;\n    const minLength = Math.min(hash1.length, hash2.length);\n\n    for (let i = 0; i < minLength; i++) {\n      if (hash1[i] !== hash2[i]) {\n        distance++;\n      }\n    }\n\n    // 转换为相似度百分比\n    const maxDistance = Math.max(hash1.length, hash2.length);\n    const similarity = ((maxDistance - distance) / maxDistance) * 100;\n\n    return Math.max(0, Math.round(similarity));\n  }\n}\n\n// 导出所有类型和工具类\nexport * from './types';\nexport { FingerprintCollector } from './collector';\nexport { FingerprintHasher } from './hash';\nexport { FingerprintStorage } from './storage';\n\n// 创建默认实例\nexport const fingerprintSDK = new FingerprintSDK();\n\n// 便捷方法\nexport async function getFingerprint(): Promise<FingerprintResult> {\n  return fingerprintSDK.getFingerprint();\n}\n\nexport function getVisitorId(): string | null {\n  return fingerprintSDK.getVisitorId();\n}\n\nexport function getHash(): string | null {\n  return fingerprintSDK.getHash();\n}\n\nexport function clearFingerprint(): boolean {\n  return fingerprintSDK.clearFingerprint();\n}\n"
  },
  {
    "path": "src/sdk/fingerprint/storage.ts",
    "content": "/**\n * 指纹存储管理器\n * 负责指纹数据的本地存储和管理\n */\n\nimport type { StorageData } from './types';\n\nexport class FingerprintStorage {\n  private readonly storageKey: string;\n\n  constructor(storageKey: string = 'fingerprint_data') {\n    this.storageKey = storageKey;\n  }\n\n  /**\n   * 保存指纹数据到本地存储\n   */\n  save(data: StorageData): boolean {\n    try {\n      const serialized = JSON.stringify(data);\n      localStorage.setItem(this.storageKey, serialized);\n      return true;\n    } catch (e) {\n      console.warn('Failed to save fingerprint data:', e);\n      return false;\n    }\n  }\n\n  /**\n   * 从本地存储加载指纹数据\n   */\n  load(): StorageData | null {\n    try {\n      const serialized = localStorage.getItem(this.storageKey);\n      if (!serialized) return null;\n\n      const data = JSON.parse(serialized) as StorageData;\n      return data;\n    } catch (e) {\n      console.warn('Failed to load fingerprint data:', e);\n      return null;\n    }\n  }\n\n  /**\n   * 更新访问计数和最后访问时间\n   */\n  updateVisit(): StorageData | null {\n    const data = this.load();\n    if (!data) return null;\n\n    data.lastSeen = Date.now();\n    data.visitCount += 1;\n\n    this.save(data);\n    return data;\n  }\n\n  /**\n   * 清除指纹数据\n   */\n  clear(): boolean {\n    try {\n      localStorage.removeItem(this.storageKey);\n      return true;\n    } catch (e) {\n      console.warn('Failed to clear fingerprint data:', e);\n      return false;\n    }\n  }\n\n  /**\n   * 检查指纹是否存在\n   */\n  exists(): boolean {\n    return this.load() !== null;\n  }\n\n  /**\n   * 获取访问者ID\n   */\n  getVisitorId(): string | null {\n    const data = this.load();\n    return data?.visitorId || null;\n  }\n\n  /**\n   * 获取指纹哈希\n   */\n  getHash(): string | null {\n    const data = this.load();\n    return data?.hash || null;\n  }\n\n  /**\n   * 获取访问统计\n   */\n  getVisitStats(): { firstSeen: number; lastSeen: number; visitCount: number } | null {\n    const data = this.load();\n    if (!data) return null;\n\n    return {\n      firstSeen: data.firstSeen,\n      lastSeen: data.lastSeen,\n      visitCount: data.visitCount,\n    };\n  }\n\n  /**\n   * 设置SessionStorage (临时存储)\n   */\n  setSessionData(key: string, value: string): boolean {\n    try {\n      sessionStorage.setItem(`${this.storageKey}_${key}`, value);\n      return true;\n    } catch (e) {\n      console.warn('Failed to set session data:', e);\n      return false;\n    }\n  }\n\n  /**\n   * 获取SessionStorage (临时存储)\n   */\n  getSessionData(key: string): string | null {\n    try {\n      return sessionStorage.getItem(`${this.storageKey}_${key}`);\n    } catch (e) {\n      console.warn('Failed to get session data:', e);\n      return null;\n    }\n  }\n\n  /**\n   * 清除SessionStorage (临时存储)\n   */\n  clearSessionData(key?: string): boolean {\n    try {\n      if (key) {\n        sessionStorage.removeItem(`${this.storageKey}_${key}`);\n      } else {\n        // 清除所有相关session数据\n        Object.keys(sessionStorage)\n          .filter(k => k.startsWith(this.storageKey))\n          .forEach(k => sessionStorage.removeItem(k));\n      }\n      return true;\n    } catch (e) {\n      console.warn('Failed to clear session data:', e);\n      return false;\n    }\n  }\n\n  /**\n   * 导出指纹数据 (用于备份)\n   */\n  export(): string {\n    const data = this.load();\n    if (!data) return '';\n\n    return btoa(JSON.stringify(data));\n  }\n\n  /**\n   * 导入指纹数据 (用于恢复)\n   */\n  import(exportedData: string): boolean {\n    try {\n      const decoded = atob(exportedData);\n      const data = JSON.parse(decoded) as StorageData;\n\n      // 验证数据格式\n      if (!data.hash || !data.visitorId) {\n        throw new Error('Invalid fingerprint data format');\n      }\n\n      return this.save(data);\n    } catch (e) {\n      console.warn('Failed to import fingerprint data:', e);\n      return false;\n    }\n  }\n}\n"
  },
  {
    "path": "src/sdk/fingerprint/types.ts",
    "content": "/**\n * 指纹SDK类型定义\n */\n\nexport interface BrowserInfo {\n  userAgent: string;\n  language: string;\n  languages: string[];\n  platform: string;\n  cookieEnabled: boolean;\n  doNotTrack: string | null;\n  hardwareConcurrency: number;\n  deviceMemory: number | undefined;\n  maxTouchPoints: number;\n}\n\nexport interface ScreenInfo {\n  width: number;\n  height: number;\n  availWidth: number;\n  availHeight: number;\n  colorDepth: number;\n  pixelDepth: number;\n  orientation: string | null;\n  devicePixelRatio: number;\n}\n\nexport interface CanvasInfo {\n  canvasFingerprint: string;\n  webglFingerprint: string;\n  webglVendor: string;\n  webglRenderer: string;\n}\n\nexport interface AudioInfo {\n  audioFingerprint: string;\n}\n\nexport interface TimeZoneInfo {\n  timezone: string;\n  timezoneOffset: number;\n  timezoneName: string;\n}\n\nexport interface FeatureInfo {\n  supportsWebGL: boolean;\n  supportsWebGL2: boolean;\n  supportsCanvas: boolean;\n  supportsAudio: boolean;\n  supportsLocalStorage: boolean;\n  supportsSessionStorage: boolean;\n  supportsIndexedDB: boolean;\n}\n\nexport interface FingerprintData {\n  browser: BrowserInfo;\n  screen: ScreenInfo;\n  canvas: CanvasInfo;\n  audio: AudioInfo;\n  timezone: TimeZoneInfo;\n  features: FeatureInfo;\n  timestamp: number;\n}\n\nexport interface FingerprintOptions {\n  includeCanvas?: boolean;\n  includeWebGL?: boolean;\n  includeAudio?: boolean;\n  includeScreen?: boolean;\n  includeTimezone?: boolean;\n  includeFeatures?: boolean;\n  storageKey?: string;\n  hashAlgorithm?: 'sha256' | 'sha384' | 'sha512' | 'md5' | 'simple';\n}\n\nexport interface FingerprintResult {\n  hash: string;\n  confidence: number;\n  data: FingerprintData;\n  visitorId: string;\n}\n\nexport interface StorageData {\n  hash: string;\n  visitorId: string;\n  firstSeen: number;\n  lastSeen: number;\n  visitCount: number;\n}\n"
  },
  {
    "path": "src/sdk/index.ts",
    "content": "/**\n * SDK统一导出\n * 提供所有SDK模块的统一入口\n */\n\nexport * from './fingerprint';\nexport * from './fingerprint/hooks';\n"
  },
  {
    "path": "src/services/goofish/index.ts",
    "content": "/**\n * Goofish API 服务\n * 基于 axios 的 HTTP 请求封装\n */\n\nimport axios from 'axios'\n\nconst API_BASE = '/api'\n\n// 创建 axios 实例\nconst apiClient = axios.create({\n  baseURL: API_BASE,\n  timeout: 30000,\n  headers: {\n    'Content-Type': 'application/json'\n  }\n})\n\n// 请求拦截器\napiClient.interceptors.request.use(\n  (config) => {\n    return config\n  },\n  (error) => {\n    return Promise.reject(error)\n  }\n)\n\n// 响应拦截器\napiClient.interceptors.response.use(\n  (response) => response,\n  (error) => {\n    console.error('API Error:', error)\n    return Promise.reject(error)\n  }\n)\n\n// ==================== 账号管理 ====================\nexport const accountApi = {\n  // 获取所有账号\n  getAccounts: () => apiClient.get('/accounts'),\n  \n  // 获取单个账号\n  getAccount: (id: string) => apiClient.get(`/accounts/${id}`),\n  \n  // 添加/更新账号\n  saveAccount: (data: any) => apiClient.post('/accounts', data),\n  \n  // 删除账号\n  deleteAccount: (id: string) => apiClient.delete(`/accounts/${id}`),\n  \n  // 启用/禁用账号\n  toggleAccount: (id: string, enabled: boolean) => \n    apiClient.patch(`/accounts/${id}/enabled`, { enabled }),\n  \n  // 启动账号\n  startAccount: (id: string) => apiClient.post(`/accounts/${id}/start`),\n  \n  // 停止账号\n  stopAccount: (id: string) => apiClient.post(`/accounts/${id}/stop`),\n  \n  // 重启账号\n  restartAccount: (id: string) => apiClient.post(`/accounts/${id}/restart`)\n}\n\n// ==================== 对话管理 ====================\nexport const conversationApi = {\n  // 获取对话列表\n  getConversations: (params?: any) => apiClient.get('/conversations', { params }),\n\n  // 获取对话详情\n  getConversation: (chatId: string) => apiClient.get(`/conversations/${chatId}`),\n\n  // 标记已读\n  markAsRead: (chatId: string, accountId?: string) =>\n    accountId\n      ? apiClient.post(`/conversations/${accountId}/${chatId}/read`)\n      : apiClient.post(`/conversations/${chatId}/read`)\n}\n\n// ==================== 消息管理 ====================\nexport const messageApi = {\n  // 获取消息列表\n  getMessages: (params?: any) => apiClient.get('/messages', { params }),\n\n  // 发送消息\n  sendMessage: (data: { accountId: string; chatId: string; toUserId: string; text: string }) =>\n    apiClient.post('/messages/send', data)\n}\n\n// ==================== 订单管理 ====================\nexport const orderApi = {\n  // 获取订单列表\n  getOrders: (params?: any) => apiClient.get('/orders', { params }),\n  \n  // 获取订单详情\n  getOrder: (id: number) => apiClient.get(`/orders/${id}`),\n  \n  // 确认发货\n  confirmShipment: (id: number, data: any) => \n    apiClient.post(`/orders/${id}/confirm-shipment`, data),\n  \n  // 免拼发货\n  freeShipping: (id: number, data: any) => \n    apiClient.post(`/orders/${id}/free-shipping`, data)\n}\n\n// ==================== 自动回复 ====================\nexport const autoReplyApi = {\n  // 获取规则列表\n  getRules: () => apiClient.get('/autoreply'),\n  \n  // 创建规则\n  createRule: (data: any) => apiClient.post('/autoreply', data),\n  \n  // 更新规则\n  updateRule: (id: number, data: any) => apiClient.put(`/autoreply/${id}`, data),\n  \n  // 删除规则\n  deleteRule: (id: number) => apiClient.delete(`/autoreply/${id}`)\n}\n\n// ==================== 自动发货 ====================\nexport const autoSellApi = {\n  // 获取规则列表\n  getRules: () => apiClient.get('/autosell'),\n  \n  // 创建规则\n  createRule: (data: any) => apiClient.post('/autosell', data),\n  \n  // 更新规则\n  updateRule: (id: number, data: any) => apiClient.put(`/autosell/${id}`, data),\n  \n  // 删除规则\n  deleteRule: (id: number) => apiClient.delete(`/autosell/${id}`)\n}\n\n// ==================== 工作流 ====================\nexport const workflowApi = {\n  // 获取工作流列表\n  getWorkflows: () => apiClient.get('/workflows'),\n  \n  // 获取工作流详情\n  getWorkflow: (id: number) => apiClient.get(`/workflows/${id}`),\n  \n  // 创建工作流\n  createWorkflow: (data: any) => apiClient.post('/workflows', data),\n  \n  // 更新工作流\n  updateWorkflow: (id: number, data: any) => apiClient.put(`/workflows/${id}`, data),\n  \n  // 删除工作流\n  deleteWorkflow: (id: number) => apiClient.delete(`/workflows/${id}`)\n}\n\n// ==================== 日志 ====================\nexport const logApi = {\n  // 获取当前运行日志\n  getLogs: (params?: any) => apiClient.get('/logs/current', { params }),\n\n  // 获取日志日期列表\n  getDates: () => apiClient.get('/logs/dates'),\n\n  // 获取指定日期的日志文件列表\n  getFiles: (date: string) => apiClient.get(`/logs/files/${date}`),\n\n  // 获取指定日志文件内容\n  getContent: (date: string, file: string, params?: any) =>\n    apiClient.get(`/logs/content/${date}/${file}`, { params })\n}\n\n// ==================== 系统状态 ====================\nexport const statusApi = {\n  // 获取系统状态\n  getStatus: () => apiClient.get('/status')\n}\n\nexport default {\n  account: accountApi,\n  conversation: conversationApi,\n  message: messageApi,\n  order: orderApi,\n  autoReply: autoReplyApi,\n  autoSell: autoSellApi,\n  workflow: workflowApi,\n  log: logApi,\n  status: statusApi\n}\n"
  },
  {
    "path": "src/services/latexApi.ts",
    "content": "/**\n * LaTeX 编译 API 服务\n * 通过本地代理调用第三方在线 API 编译 LaTeX 代码，返回 PDF Blob\n */\n\nexport interface CompileOptions {\n  code: string\n  compiler?: 'xelatex' | 'pdflatex' | 'lualatex'\n  timeout?: number\n  files?: Array<{\n    name: string\n    content: string  // base64 编码的文件内容\n  }>\n}\n\nexport interface CompileResult {\n  success: boolean\n  pdfBlob?: Blob\n  error?: string\n}\n\n/**\n * 编译 LaTeX 代码\n * @param options.code - LaTeX 源代码\n * @param options.compiler - LaTeX 编译器 (xelatex, pdflatex, lualatex)，默认 xelatex（推荐用于中文）\n * @param options.timeout - 超时时间（毫秒），默认 60000\n * @param options.files - 附加文件（如图片），格式为 [{ name: 'image.png', content: 'base64...' }]\n */\nexport async function compileLatex({ code, compiler = 'xelatex', timeout = 60000, files = [] }: CompileOptions): Promise<CompileResult> {\n  try {\n    const controller = new AbortController()\n    const timeoutId = setTimeout(() => controller.abort(), timeout)\n\n    // 使用本地代理 API\n    const response = await fetch('/api/latex/compile', {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n      },\n      body: JSON.stringify({ code, compiler, files }),\n      signal: controller.signal,\n    })\n\n    clearTimeout(timeoutId)\n\n    const contentType = response.headers.get('content-type') || ''\n\n    // PDF 响应\n    if (contentType.includes('application/pdf')) {\n      const pdfBlob = await response.blob()\n      return {\n        success: true,\n        pdfBlob,\n      }\n    }\n\n    // 非 PDF 响应，解析错误信息\n    if (!response.ok) {\n      let errorMsg = `编译失败: ${response.status} ${response.statusText}`\n      try {\n        const errorData = await response.json()\n        if (errorData.error) errorMsg = errorData.error\n        if (errorData.message) errorMsg = errorData.message\n      } catch { /* ignore parse error */ }\n      return {\n        success: false,\n        error: errorMsg,\n      }\n    }\n\n    // 未知响应类型\n    return {\n      success: false,\n      error: '编译失败，服务器返回了非 PDF 内容',\n    }\n  } catch (err) {\n    if (err instanceof Error) {\n      if (err.name === 'AbortError') {\n        return {\n          success: false,\n          error: '编译超时，请稍后重试',\n        }\n      }\n      return {\n        success: false,\n        error: `编译请求失败: ${err.message}`,\n      }\n    }\n    return {\n      success: false,\n      error: '编译请求失败，未知错误',\n    }\n  }\n}\n\n/**\n * 检查 LaTeX API 是否可用（通过本地代理）\n */\nexport async function checkApiHealth(): Promise<boolean> {\n  try {\n    const response = await fetch('/api/latex/health', {\n      method: 'GET',\n      signal: AbortSignal.timeout(5000),\n    })\n    return response.ok\n  } catch {\n    return false\n  }\n}\n"
  },
  {
    "path": "src/services/server.ts",
    "content": "import { serve } from '@hono/node-server'\nimport { Hono } from 'hono'\nimport { cors } from 'hono/cors'\nimport { logger } from 'hono/logger'\nimport { networkInterfaces } from 'os'\nimport { createNodeWebSocket } from '@hono/node-ws'\nimport { initDatabase, closeDatabase } from '../goofish/db'\nimport { ClientManager } from '../goofish/websocket'\nimport { fetchUserHead, handleOrderMessage, fetchAndUpdateOrderDetail } from '../goofish/services'\nimport { messageStore, conversationStore, setClientManager } from '../goofish/api'\nimport { createLogger, cleanOldLogs, setLogLevel, LogLevel } from '../goofish/core/logger'\nimport { LOG_CONFIG } from '../goofish/core/constants'\nimport { createStatusRoutes } from '../goofish/api/routes'\nimport { createWSPushHandler } from '../goofish/api/routes/ws-push.route'\nimport { createAccountRoutes } from '../goofish/api/routes/accounts'\nimport { createGoodsRoutes } from '../goofish/api/routes/goods'\nimport { createMessageRoutes } from '../goofish/api/routes/messages'\nimport { createConversationRoutes } from '../goofish/api/routes/conversations'\nimport { createLogsRoutes } from '../goofish/api/routes/logs'\nimport { createAutoReplyRoutes } from '../goofish/api/routes/autoreply'\nimport { createOrderRoutes } from '../goofish/api/routes/order.route'\nimport { createAutoSellRoutes } from '../goofish/api/routes/autosell'\nimport { createWorkflowRoutes } from '../goofish/api/routes/workflow.route'\nimport { authRoute } from '../goofish/api/routes/auth.route'\n\nconst goofishLogger = createLogger('Goofish:Integration')\nconst app = new Hono()\n\n// WebSocket 支持\nconst nodeWS = createNodeWebSocket({ app })\nconst { upgradeWebSocket, injectWebSocket } = nodeWS\n\n// Goofish ClientManager\nlet clientManager: ClientManager\n\n// 初始化 Goofish\nasync function initGoofish() {\n  goofishLogger.info('初始化 Goofish 服务...')\n\n  // 设置日志级别\n  setLogLevel(LOG_CONFIG.LEVEL as LogLevel)\n\n  // 清理过期日志\n  cleanOldLogs(LOG_CONFIG.RETENTION_DAYS)\n\n  // 初始化数据库\n  initDatabase()\n\n  // 创建客户端管理器\n  clientManager = new ClientManager(async (accountId, msg) => {\n    goofishLogger.info(`收到新消息: ${msg.senderName}: ${msg.content}`)\n    messageStore.add(msg)\n    conversationStore.addIncoming(accountId, msg)\n\n    // 处理订单状态消息\n    if (msg.isOrderMessage && msg.orderId) {\n      goofishLogger.info(`订单消息: orderId=${msg.orderId}`)\n      handleOrderMessage(accountId, msg.orderId, msg.chatId)\n      fetchOrderDetailAsync(accountId, msg.orderId)\n    }\n\n    // 异步获取用户头像（不阻塞消息处理）\n    fetchUserAvatarAsync(accountId, msg.chatId, msg.senderId)\n  })\n\n  // 设置 API 客户端管理器引用\n  setClientManager(clientManager)\n\n  // 从数据库加载并启动所有启用的账号\n  await clientManager.startAll()\n\n  goofishLogger.info('Goofish 服务初始化完成')\n}\n\n// 异步获取用户头像\nasync function fetchUserAvatarAsync(accountId: string, chatId: string, userId: string) {\n  try {\n    const { userHead } = await fetchUserHead(accountId, userId)\n    if (userHead?.avatar) {\n      conversationStore.updateUserAvatar(accountId, chatId, userHead.avatar)\n    }\n  } catch (e) {\n    goofishLogger.debug(`获取用户头像失败: ${e}`)\n  }\n}\n\n// 异步获取订单详情\nasync function fetchOrderDetailAsync(accountId: string, orderId: string) {\n  try {\n    const client = clientManager.getClient(accountId)\n    if (!client) {\n      goofishLogger.warn(`获取订单详情失败: 账号 ${accountId} 客户端不存在`)\n      return\n    }\n    await fetchAndUpdateOrderDetail(client, orderId)\n  } catch (e) {\n    goofishLogger.debug(`获取订单详情失败: ${e}`)\n  }\n}\n\n// 获取局域网 IP 地址\nfunction getLocalIP(): string {\n  const nets = networkInterfaces()\n  for (const name of Object.keys(nets)) {\n    for (const net of nets[name] || []) {\n      if (net.family === 'IPv4' && !net.internal) {\n        return net.address\n      }\n    }\n  }\n  return 'localhost'\n}\n\nconst localIP = getLocalIP()\n\n// 环境判断\nconst isDev = process.env.NODE_ENV !== 'production'\n\n// CORS 配置\napp.use('/*', cors({\n  origin: isDev\n    ? '*'\n    : ['http://123.60.91.107'],\n  allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH'],\n  allowHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],\n  credentials: true,\n  maxAge: 86400,\n}))\n\n// 日志中间件\napp.use('/*', logger())\n\n// 请求计时中间件\napp.use('/*', async (c, next) => {\n  const start = Date.now()\n  await next()\n  const duration = Date.now() - start\n  c.header('X-Response-Time', `${duration}ms`)\n})\n\n// WebSocket 推送端点\napp.get('/ws', upgradeWebSocket(() => createWSPushHandler(() => clientManager)))\n\n// 健康检查\napp.get('/health', (c) => {\n  return c.json({\n    status: 'ok',\n    environment: isDev ? 'development' : 'production',\n    timestamp: new Date().toISOString(),\n    version: '4.0.0'\n  })\n})\n\n// API 路由信息\napp.get('/api/info', (c) => {\n  return c.json({\n    message: 'API Proxy Server',\n    version: '4.0.0',\n    environment: isDev ? 'development' : 'production',\n    endpoints: {\n      '/health': 'Health check endpoint',\n      '/api/translate': 'Baidu Translate API proxy',\n      '/api/kuaikan/*': 'Kuaikan Manhua API proxy (PC)',\n      '/api/kuaikan-m/*': 'Kuaikan Manhua API proxy (Mobile)',\n      '/api/netease/*': 'Netease Cloud Music API proxy',\n      '/api/latex': 'LaTeX compilation API proxy',\n      '/ws': 'WebSocket endpoint',\n      '/api/accounts': 'Goofish account management',\n      '/api/conversations': 'Goofish conversations',\n      '/api/orders': 'Goofish orders',\n      '/api/autoreply': 'Auto reply rules',\n      '/api/autosell': 'Auto sell rules',\n      '/api/workflows': 'Workflow management',\n      '/api/logs': 'System logs',\n      '/api/auth': 'User authentication (login, register)',\n      '/api/info': 'This endpoint',\n    },\n    timestamp: new Date().toISOString()\n  })\n})\n\n// Goofish 路由（必须在代理中间件之前注册）\nconst getClientManager = () => clientManager\napp.route('/', createStatusRoutes(getClientManager))\napp.route('/api', createStatusRoutes(getClientManager))\napp.route('/api/accounts', createAccountRoutes(getClientManager))\napp.route('/api/goods', createGoodsRoutes(getClientManager))\napp.route('/api/messages', createMessageRoutes(getClientManager))\napp.route('/api/conversations', createConversationRoutes())\napp.route('/api/logs', createLogsRoutes())\napp.route('/api/autoreply', createAutoReplyRoutes())\napp.route('/api/orders', createOrderRoutes(getClientManager))\napp.route('/api/autosell', createAutoSellRoutes())\napp.route('/api/workflows', createWorkflowRoutes())\napp.route('/api/auth', authRoute)\n\n// LaTeX 编译 API 代理\napp.post('/api/latex/compile', async (c) => {\n  try {\n    const { code, compiler = 'xelatex', files = [] } = await c.req.json()\n\n    // 添加时间戳确保请求唯一性\n    const timestamp = new Date().toISOString()\n    console.log(`[${timestamp}] LaTeX 编译请求`)\n\n    if (!code || typeof code !== 'string') {\n      return c.json({\n        success: false,\n        error: '请提供有效的 LaTeX 代码'\n      }, 400)\n    }\n\n    console.log('LaTeX 编译请求:', {\n      compiler,\n      codeLength: code.length,\n      codePreview: code.substring(0, 100) + (code.length > 100 ? '...' : ''),\n      filesCount: files.length,\n      files: files.map((f: any) => ({ name: f.name, contentLength: f.content?.length }))\n    })\n\n    // 如果有图片文件，使用正确的 API 格式传递\n    let processedCode = code\n    if (files && files.length > 0) {\n      console.log('检测到图片文件，使用多文件资源格式')\n    }\n\n    // 检测是否包含中文字符\n    const hasChinese = /[一-龥]/.test(processedCode)\n    console.log('包含中文:', hasChinese)\n\n    // 如果包含中文，尝试使用专门处理中文的服务\n    if (hasChinese) {\n      console.log('检测到中文内容，使用特殊的中文处理方案')\n\n      // 方案1: 尝试使用 Overleaf-style API\n      try {\n        const overleafUrl = 'https://compile.overleaf.com/docs'\n\n        // 构建文件列表：主文件（图片已嵌入）\n        const requestFiles: any[] = [{\n          name: 'main.tex',\n          content: processedCode\n        }]\n\n        // 不再需要添加附加文件，因为图片已经嵌入到代码中\n\n        const response = await fetch(overleafUrl, {\n          method: 'POST',\n          headers: {\n            'Content-Type': 'application/json',\n          },\n          body: JSON.stringify({\n            compiler: compiler,\n            files: requestFiles,\n            options: {\n              timeout: 60\n            }\n          }),\n        })\n\n        if (response.ok) {\n          const data = await response.json()\n          if (data.pdfs && data.pdfs['main.pdf']) {\n            const pdfData = data.pdfs['main.pdf']\n            const pdfBuffer = Buffer.from(pdfData, 'base64')\n\n            return new Response(pdfBuffer, {\n              headers: {\n                'Content-Type': 'application/pdf',\n                'Content-Disposition': 'attachment; filename=\"document.pdf\"',\n                'Access-Control-Allow-Origin': '*',\n              },\n            })\n          }\n        }\n      } catch (error) {\n        console.error('Overleaf API 失败:', error)\n      }\n\n      // 方案2: 修改LaTeX代码以使用更通用的字体设置\n      console.log('尝试修改LaTeX代码以支持中文')\n      let modifiedCode = processedCode  // 使用已经处理过（包含图片）的代码\n\n      // 如果代码中没有ctex相关包，添加中文支持\n      if (!processedCode.includes('ctex') && !processedCode.includes('CJK')) {\n        // 在documentclass后添加中文支持\n        modifiedCode = processedCode.replace(\n          /\\\\documentclass(\\[[^\\]]*\\])?\\{([^}]+)\\}/,\n          (match, options, docclass) => {\n            if (docclass === 'ctexart') {\n              return match // 已经是ctexart，不修改\n            }\n            return `\\\\documentclass${options || ''}{${docclass}}\\n\\\\usepackage{CJKutf8}\\n\\\\usepackage{CJK}`\n          }\n        )\n\n        // 在document环境中添加CJK支持\n        if (modifiedCode.includes('\\\\begin{document}')) {\n          modifiedCode = modifiedCode.replace(\n            '\\\\begin{document}',\n            '\\\\begin{document}\\n\\\\begin{CJK*}{UTF8}{gbsn}'\n          )\n        }\n\n        if (modifiedCode.includes('\\\\end{document}')) {\n          modifiedCode = modifiedCode.replace(\n            '\\\\end{document}',\n            '\\\\end{CJK*}\\n\\\\end{document}'\n          )\n        }\n      }\n\n      console.log('修改后的代码预览:', modifiedCode.substring(0, 200) + '...')\n\n      // 使用修改后的代码尝试编译\n      const latexApiUrl = 'https://latex.ytotech.com/builds/sync'\n\n      // 构建请求数据 - 使用正确的 resources 格式\n      const resources: any[] = [{\n        main: true,\n        content: modifiedCode\n      }]\n\n      // 添加附加文件（图片等）- 使用正确的格式\n      if (files && files.length > 0) {\n        for (const file of files) {\n          if (file.name && file.content) {\n            // 提取纯 base64 数据（去掉 data:image/...;base64, 前缀）\n            let base64Data = file.content\n            if (base64Data.startsWith('data:')) {\n              base64Data = base64Data.split(',')[1] || base64Data\n            }\n\n            // 使用正确的 API 格式：path + file\n            resources.push({\n              path: file.name,\n              file: base64Data\n            })\n\n            console.log(`添加图片资源（中文处理）: ${file.name}`)\n          }\n        }\n      }\n\n      const requestData = {\n        compiler: compiler,\n        resources: resources\n      }\n\n      console.log('发送到 LaTeX API 的请求（中文处理）:', {\n        compiler,\n        codeLength: modifiedCode.length,\n        资源数量: resources.length,\n        包含图片: files && files.length > 0\n      })\n\n      const response = await fetch(latexApiUrl, {\n        method: 'POST',\n        headers: {\n          'Content-Type': 'application/json',\n        },\n        body: JSON.stringify(requestData),\n      })\n\n      if (response.ok) {\n        const contentType = response.headers.get('content-type') || ''\n        if (contentType.includes('application/pdf')) {\n          const pdfBuffer = await response.arrayBuffer()\n          console.log('中文PDF生成成功，大小:', pdfBuffer.byteLength, '字节')\n\n          return new Response(pdfBuffer, {\n            headers: {\n              'Content-Type': 'application/pdf',\n              'Content-Disposition': 'attachment; filename=\"document.pdf\"',\n              'Access-Control-Allow-Origin': '*',\n            },\n          })\n        }\n      }\n    }\n\n    // 非中文内容或中文处理失败，使用标准流程\n    const latexApiUrl = 'https://latex.ytotech.com/builds/sync'\n\n    // 构建请求数据 - 使用正确的 resources 格式\n    const resources: any[] = [{\n      main: true,\n      content: processedCode\n    }]\n\n    // 添加附加文件（图片等）- 使用正确的格式\n    if (files && files.length > 0) {\n      for (const file of files) {\n        if (file.name && file.content) {\n          // 提取纯 base64 数据（去掉 data:image/...;base64, 前缀）\n          let base64Data = file.content\n          if (base64Data.startsWith('data:')) {\n            base64Data = base64Data.split(',')[1] || base64Data\n          }\n\n          // 使用正确的 API 格式：path + file\n          resources.push({\n            path: file.name,\n            file: base64Data\n          })\n\n          console.log(`添加图片资源: ${file.name}`)\n        }\n      }\n    }\n\n    const requestData = {\n      compiler: compiler,\n      resources: resources\n    }\n\n    console.log('发送到 LaTeX API 的请求:', {\n      compiler,\n      codeLength: processedCode.length,\n      资源数量: resources.length,\n      包含图片: files && files.length > 0\n    })\n\n    const response = await fetch(latexApiUrl, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n      },\n      body: JSON.stringify(requestData),\n    })\n\n    console.log('API 响应状态:', response.status, response.statusText)\n\n    if (!response.ok) {\n      const errorText = await response.text()\n      console.error('LaTeX API 错误响应:', errorText)\n      console.error('请求体详情:', JSON.stringify(requestData, null, 2))\n      throw new Error(`LaTeX API 返回错误: ${response.status} ${response.statusText} - ${errorText}`)\n    }\n\n    const contentType = response.headers.get('content-type') || ''\n    console.log('响应内容类型:', contentType)\n\n    if (contentType.includes('application/pdf')) {\n      const pdfBuffer = await response.arrayBuffer()\n      console.log('PDF 生成成功，大小:', pdfBuffer.byteLength, '字节')\n\n      return new Response(pdfBuffer, {\n        headers: {\n          'Content-Type': 'application/pdf',\n          'Content-Disposition': 'attachment; filename=\"document.pdf\"',\n          'Access-Control-Allow-Origin': '*',\n          'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',\n          'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n        },\n      })\n    }\n\n    const errorText = await response.text()\n    console.error('非 PDF 响应:', errorText)\n    return c.json({\n      success: false,\n      error: `编译失败，服务器返回非 PDF 内容: ${errorText.substring(0, 200)}`\n    }, 500)\n\n  } catch (error) {\n    console.error('LaTeX 编译代理错误:', error)\n\n    const errorMessage = error instanceof Error ? error.message : '未知错误'\n    return c.json({\n      success: false,\n      error: `LaTeX 编译失败: ${errorMessage}`\n    }, 500)\n  }\n})\n\n// LaTeX 编译健康检查\napp.get('/api/latex/health', async (c) => {\n  try {\n    const testCode = '\\\\documentclass{article}\\\\begin{document}Hello World\\\\end{document}'\n    const response = await fetch(`https://latex.ytotech.com/builds/sync?content=${encodeURIComponent(testCode)}`, {\n      method: 'GET',\n    })\n\n    return c.json({\n      status: response.ok ? 'available' : 'unavailable',\n      statusCode: response.status,\n      timestamp: new Date().toISOString()\n    })\n  } catch (error) {\n    return c.json({\n      status: 'error',\n      error: error instanceof Error ? error.message : '未知错误',\n      timestamp: new Date().toISOString()\n    }, 503)\n  }\n})\n\n// 视频下载API代理\napp.post('/api/resolve', async (c) => {\n  const targetUrl = 'https://xiazaishipin.com/api/resolve'\n\n  try {\n    const body = await c.req.json()\n    console.log('[Video API] 解析请求:', body.url?.substring(0, 50))\n\n    const response = await fetch(targetUrl, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n        'Referer': 'https://xiazaishipin.com/',\n        'Origin': 'https://xiazaishipin.com',\n        'Accept': 'application/json, text/plain, */*',\n        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',\n      },\n      body: JSON.stringify(body),\n    })\n\n    const responseData = await response.json()\n    console.log('[Video API] 解析成功:', responseData.title)\n\n    // 将thumbnail URL替换为代理URL\n    if (responseData.thumbnail) {\n      responseData.thumbnail = `/api/image-proxy?url=${encodeURIComponent(responseData.thumbnail)}`\n    }\n\n    return c.json(responseData, response.status as any)\n  } catch (error) {\n    console.error('[Video API] 错误:', error)\n    return c.json({\n      error: '视频解析失败',\n      message: error instanceof Error ? error.message : 'Unknown error'\n    }, 500)\n  }\n})\n\n// 图片代理 - 绕过防盗链\napp.get('/api/image-proxy', async (c) => {\n  const imageUrl = c.req.query('url')\n\n  if (!imageUrl) {\n    return c.json({ error: 'Missing url parameter' }, 400)\n  }\n\n  try {\n    console.log('[Image Proxy] 代理图片:', imageUrl.substring(0, 80))\n\n    const response = await fetch(imageUrl, {\n      headers: {\n        'Referer': 'https://www.bilibili.com/',\n        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',\n      },\n    })\n\n    if (!response.ok) {\n      throw new Error(`Failed to fetch image: ${response.status}`)\n    }\n\n    const imageBuffer = await response.arrayBuffer()\n    const contentType = response.headers.get('Content-Type') || 'image/jpeg'\n\n    return new Response(imageBuffer, {\n      headers: {\n        'Content-Type': contentType,\n        'Cache-Control': 'public, max-age=86400', // 缓存1天\n      },\n    })\n  } catch (error) {\n    console.error('[Image Proxy] 错误:', error)\n    return c.json({\n      error: 'Failed to proxy image',\n      message: error instanceof Error ? error.message : 'Unknown error'\n    }, 500)\n  }\n})\n\n// B站视频下载代理\napp.post('/api/bilibili-download', async (c) => {\n  const targetUrl = 'https://xiazaishipin.com/api/bilibili-download'\n\n  try {\n    const body = await c.req.json()\n    console.log('[Bilibili Download] 下载请求:', body.url?.substring(0, 50))\n\n    const response = await fetch(targetUrl, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n        'Referer': 'https://xiazaishipin.com/',\n        'Origin': 'https://xiazaishipin.com',\n        'Accept': '*/*',\n        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',\n      },\n      body: JSON.stringify(body),\n    })\n\n    console.log('[Bilibili Download] 下载响应:', response.status, response.headers.get('content-type'))\n\n    // 检查响应类型\n    const contentType = response.headers.get('content-type') || ''\n\n    if (contentType.includes('application/json')) {\n      // JSON响应 - 可能包含下载链接或错误信息\n      const jsonData = await response.json()\n      return c.json(jsonData)\n    } else {\n      // 视频文件响应 - 流式转发以支持前端进度显示\n      const reader = response.body?.getReader()\n\n      if (!reader) {\n        throw new Error('无法获取响应流')\n      }\n\n      // 创建一个新的 ReadableStream 来转发数据\n      const stream = new ReadableStream({\n        async start(controller) {\n          try {\n            while (true) {\n              const { done, value } = await reader.read()\n              if (done) {\n                controller.close()\n                break\n              }\n              controller.enqueue(value)\n            }\n          } catch (error) {\n            console.error('[Bilibili Download] 流传输错误:', error)\n            controller.error(error)\n          } finally {\n            reader.releaseLock()\n          }\n        }\n      })\n\n      return new Response(stream, {\n        status: response.status,\n        headers: {\n          'Content-Type': contentType,\n          'Content-Disposition': response.headers.get('Content-Disposition') || `attachment; filename=\"video.mp4\"`,\n          'Content-Length': response.headers.get('Content-Length') || '',\n          'Cache-Control': 'no-cache',\n        },\n      })\n    }\n  } catch (error) {\n    console.error('[Bilibili Download] 错误:', error)\n    return c.json({\n      error: 'B站视频下载失败',\n      message: error instanceof Error ? error.message : 'Unknown error'\n    }, 500)\n  }\n})\n\n// 抖音和小红书视频下载代理\napp.post('/api/proxy-download', async (c) => {\n  const targetUrl = 'https://xiazaishipin.com/api/proxy-download'\n\n  try {\n    const body = await c.req.json()\n    console.log('[Douyin Download] 下载请求:', body.url?.substring(0, 50), 'filename:', body.filename)\n\n    const response = await fetch(targetUrl, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n        'Referer': 'https://xiazaishipin.com/',\n        'Origin': 'https://xiazaishipin.com',\n        'Accept': '*/*',\n        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',\n      },\n      body: JSON.stringify(body),\n    })\n\n    console.log('[Douyin Download] 下载响应:', response.status, response.headers.get('content-type'))\n\n    // 检查响应类型\n    const contentType = response.headers.get('content-type') || ''\n\n    if (contentType.includes('application/json')) {\n      // JSON响应 - 可能包含错误信息\n      const jsonData = await response.json()\n      return c.json(jsonData)\n    } else {\n      // 视频文件响应 - 流式转发以支持前端进度显示\n      const reader = response.body?.getReader()\n\n      if (!reader) {\n        throw new Error('无法获取响应流')\n      }\n\n      // 创建一个新的 ReadableStream 来转发数据\n      const stream = new ReadableStream({\n        async start(controller) {\n          try {\n            while (true) {\n              const { done, value } = await reader.read()\n              if (done) {\n                controller.close()\n                break\n              }\n              controller.enqueue(value)\n            }\n          } catch (error) {\n            console.error('[Douyin Download] 流传输错误:', error)\n            controller.error(error)\n          } finally {\n            reader.releaseLock()\n          }\n        }\n      })\n\n      return new Response(stream, {\n        status: response.status,\n        headers: {\n          'Content-Type': contentType,\n          'Content-Disposition': response.headers.get('Content-Disposition') || `attachment; filename=\"${body.filename || 'video.mp4'}\"`,\n          'Content-Length': response.headers.get('Content-Length') || '',\n          'Cache-Control': 'no-cache',\n        },\n      })\n    }\n  } catch (error) {\n    console.error('[Douyin Download] 错误:', error)\n    return c.json({\n      error: '抖音视频下载失败',\n      message: error instanceof Error ? error.message : 'Unknown error'\n    }, 500)\n  }\n})\n\n// 代理配置映射\nconst PROXY_CONFIG: Record<string, {\n  target: string\n  pathRewrite: string\n  timeout?: number\n  headers?: Record<string, string>\n}> = {\n  '/api/translate': {\n    target: 'https://fanyi-api.baidu.com/api/trans/vip',\n    pathRewrite: '/translate',\n    timeout: 10000,\n    headers: {\n      'Referer': 'https://fanyi.baidu.com/',\n      'Origin': 'https://fanyi.baidu.com',\n    },\n  },\n  '/api/kuaikan': {\n    target: 'https://www.kuaikanmanhua.com',\n    pathRewrite: '',\n    timeout: 15000,\n    headers: {\n      'Referer': 'https://www.kuaikanmanhua.com/',\n      'Origin': 'https://www.kuaikanmanhua.com',\n    },\n  },\n  '/api/kuaikan-m': {\n    target: 'https://m.kuaikanmanhua.com',\n    pathRewrite: '',\n    timeout: 15000,\n    headers: {\n      'Referer': 'https://m.kuaikanmanhua.com/',\n      'Origin': 'https://m.kuaikanmanhua.com',\n    },\n  },\n  '/api/netease': {\n    target: 'https://netease-cloud-music-api.fe-mm.com',\n    pathRewrite: '',\n    timeout: 10000,\n    headers: {\n      'Referer': 'https://netease-cloud-music-api.fe-mm.com/',\n    },\n  },\n}\n\n// 匹配代理目标（优先匹配最长路径）\nfunction matchProxyTarget(path: string): { prefix: string; config: typeof PROXY_CONFIG[keyof typeof PROXY_CONFIG] } | null {\n  // 排除 Goofish 路由和认证路由\n  const goofishRoutes = ['/api/accounts', '/api/goods', '/api/messages', '/api/conversations', '/api/logs', '/api/autoreply', '/api/orders', '/api/autosell', '/api/workflows', '/api/status', '/api/auth', '/ws']\n  for (const route of goofishRoutes) {\n    if (path.startsWith(route)) {\n      return null\n    }\n  }\n\n  const sortedPrefixes = Object.keys(PROXY_CONFIG).sort((a, b) => b.length - a.length)\n  for (const prefix of sortedPrefixes) {\n    if (path.startsWith(prefix)) {\n      return { prefix, config: PROXY_CONFIG[prefix] }\n    }\n  }\n  return null\n}\n\n// 路径重写\nfunction rewritePath(path: string, prefix: string, replacement: string): string {\n  return path.replace(new RegExp(`^${prefix}`), replacement)\n}\n\n// 请求缓存（仅用于开发环境）\nconst cache = new Map<string, { data: ArrayBuffer; expiry: number }>()\nconst CACHE_TTL = 5 * 60 * 1000 // 5分钟\n\n// 代理中间件（必须在所有 goofish 路由之后注册）\napp.all('/api/*', async (c, next) => {\n  const path = c.req.path\n  const method = c.req.method\n\n  // 添加调试日志\n  console.log(`[Proxy] ${method} ${path}`)\n\n  // 检查是否是 goofish 路由，如果是则跳过代理处理，让下一个处理程序处理\n  const goofishRoutes = ['/api/accounts', '/api/goods', '/api/messages', '/api/conversations', '/api/logs', '/api/autoreply', '/api/orders', '/api/autosell', '/api/workflows', '/api/status', '/api/info', '/api/auth']\n  for (const route of goofishRoutes) {\n    if (path.startsWith(route)) {\n      // 这是一个 goofish 路由，让下一个处理程序处理\n      console.log(`[Proxy] Skipping goofish route: ${path}`)\n      return next()\n    }\n  }\n\n  const matched = matchProxyTarget(path)\n\n  if (!matched) {\n    console.log(`[Proxy] No proxy target found for: ${path}`)\n    return c.json(\n      {\n        error: 'No proxy target found',\n        availableEndpoints: Object.keys(PROXY_CONFIG),\n        path: path,\n      },\n      404\n    )\n  }\n\n  console.log(`[Proxy] Matched target for ${path}:`, matched.prefix, '->', matched.config.target)\n\n  const { prefix, config } = matched\n  const { target, pathRewrite, timeout = 10000, headers: customHeaders = {} } = config\n\n  // 构建目标URL\n  const rewrittenPath = rewritePath(path, prefix, pathRewrite)\n  const queryString = c.req.query()\n  const queryParams = new URLSearchParams(queryString).toString()\n  const targetUrl = `${target}${rewrittenPath}${queryParams ? `?${queryParams}` : ''}`\n\n  // 检查缓存（仅GET请求）\n  if (isDev && c.req.method === 'GET') {\n    const cached = cache.get(targetUrl)\n    if (cached && cached.expiry > Date.now()) {\n      return new Response(cached.data, {\n        status: 200,\n        headers: {\n          'Content-Type': 'application/json',\n          'X-Cache': 'HIT',\n        },\n      })\n    }\n  }\n\n  try {\n    // 构建 AbortController 用于超时控制\n    const controller = new AbortController()\n    const timeoutId = setTimeout(() => controller.abort(), timeout)\n\n    // 获取请求体（非 GET/HEAD 请求）\n    let body: ArrayBuffer | undefined\n    if (c.req.method !== 'GET' && c.req.method !== 'HEAD') {\n      body = await c.req.arrayBuffer()\n    }\n\n    console.log(`[Proxy] Forwarding ${c.req.method} request to: ${targetUrl}`)\n    if (body) {\n      console.log(`[Proxy] Request body:`, new TextDecoder().decode(body))\n    }\n\n    // 转发请求\n    const response = await fetch(targetUrl, {\n      method: c.req.method,\n      headers: {\n        'Content-Type': c.req.header('Content-Type') || 'application/json',\n        'User-Agent': c.req.header('User-Agent') ||\n          'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',\n        'Accept': 'application/json, text/plain, */*',\n        'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',\n        ...customHeaders,\n      },\n      body,\n      signal: controller.signal,\n    })\n\n    clearTimeout(timeoutId)\n\n    console.log(`[Proxy] Response status: ${response.status} ${response.statusText}`)\n\n    // 获取响应内容\n    const responseData = await response.arrayBuffer()\n\n    // 缓存成功的 GET 响应\n    if (isDev && c.req.method === 'GET' && response.ok) {\n      cache.set(targetUrl, {\n        data: responseData,\n        expiry: Date.now() + CACHE_TTL,\n      })\n      // 限制缓存大小\n      if (cache.size > 100) {\n        const firstKey = cache.keys().next().value\n        if (firstKey) cache.delete(firstKey)\n      }\n    }\n\n    // 返回响应\n    return new Response(responseData, {\n      status: response.status,\n      statusText: response.statusText,\n      headers: {\n        'Content-Type': response.headers.get('Content-Type') || 'application/json',\n        'X-Cache': 'MISS',\n        'Access-Control-Expose-Headers': 'Content-Type, X-Cache, X-Response-Time',\n      },\n    })\n  } catch (error) {\n    // 清理超时的缓存\n    if (c.req.method === 'GET') {\n      cache.delete(targetUrl)\n    }\n\n    const errorMessage = error instanceof Error ? error.message : 'Unknown error'\n    const isAbort = error instanceof Error && error.name === 'AbortError'\n\n    console.error('Proxy error:', {\n      url: targetUrl,\n      method: c.req.method,\n      error: errorMessage,\n      timestamp: new Date().toISOString(),\n    })\n\n    return c.json(\n      {\n        error: isAbort ? 'Request timeout' : 'Proxy request failed',\n        message: errorMessage,\n        target: targetUrl,\n        method: c.req.method,\n        timestamp: new Date().toISOString(),\n      },\n      isAbort ? 504 : 502\n    )\n  }\n})\n\n// 404 处理\napp.notFound((c) => {\n  return c.json({\n    error: 'Not Found',\n    message: `Route ${c.req.method} ${c.req.path} not found`,\n    availableRoutes: [\n      'GET /health',\n      'GET /ws',\n      'GET /api/info',\n      '/api/accounts/*',\n      '/api/conversations/*',\n      '/api/orders/*',\n      '/api/autoreply/*',\n      '/api/autosell/*',\n      '/api/workflows/*',\n      '/api/logs/*',\n      '/api/auth/*',\n      'ALL /api/* (proxy)',\n    ],\n  }, 404)\n})\n\n// 错误处理\napp.onError((err, c) => {\n  console.error('Server error:', err)\n  return c.json({\n    error: 'Internal Server Error',\n    message: err.message,\n    timestamp: new Date().toISOString(),\n  }, 500)\n})\n\n// 启动服务器\nconst port = Number(process.env.PORT) || 3001\nconst hostname = '0.0.0.0'\n\nconsole.log('\\n' + '='.repeat(50))\nconsole.log(`Hono Proxy Server with Goofish`)\nconsole.log('='.repeat(50))\nconsole.log(`Environment: ${isDev ? 'development' : 'production'}`)\nconsole.log(`Local access:   http://localhost:${port}`)\nconsole.log(`Network access: http://${localIP}:${port}`)\nconsole.log(`API info:       http://${localIP}:${port}/api/info`)\nconsole.log(`Health check:   http://${localIP}:${port}/health`)\nconsole.log(`WebSocket:      ws://${localIP}:${port}/ws`)\nconsole.log('='.repeat(50) + '\\n')\n\n// 初始化 Goofish 后启动服务器\ninitGoofish().then(() => {\n  const server = serve({\n    fetch: app.fetch,\n    port,\n    hostname,\n  })\n\n  // 注入 WebSocket 支持\n  injectWebSocket(server)\n\n  // 优雅退出\n  process.on('SIGINT', () => {\n    goofishLogger.info('收到退出信号，正在断开连接...')\n    if (clientManager) {\n      clientManager.stopAll()\n    }\n    closeDatabase()\n    process.exit(0)\n  })\n\n  process.on('SIGTERM', () => {\n    goofishLogger.info('收到终止信号，正在断开连接...')\n    if (clientManager) {\n      clientManager.stopAll()\n    }\n    closeDatabase()\n    process.exit(0)\n  })\n}).catch((err) => {\n  console.error('Failed to initialize Goofish:', err)\n  process.exit(1)\n})\n"
  },
  {
    "path": "src/services/turnstile.ts",
    "content": "/**\n * Cloudflare Turnstile 验证服务\n */\n\nconst TURNSTILE_SECRET_KEY = process.env.TURNSTILE_SECRET_KEY || ''\nconst TURNSTILE_VERIFY_URL = 'https://challenges.cloudflare.com/turnstile/v0/siteverify'\n\nexport interface TurnstileVerifyResult {\n  success: boolean\n  'error-codes'?: string[]\n  validation?: string\n  expire?: string\n}\n\n/**\n * 验证 Turnstile token\n */\nexport async function verifyTurnstileToken(token: string): Promise<{\n  success: boolean\n  error?: string\n}> {\n  if (!TURNSTILE_SECRET_KEY) {\n    console.warn('Turnstile secret key not configured, skipping verification')\n    return { success: true }\n  }\n\n  try {\n    const response = await fetch(TURNSTILE_VERIFY_URL, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/x-www-form-urlencoded',\n      },\n      body: new URLSearchParams({\n        secret: TURNSTILE_SECRET_KEY,\n        response: token,\n      }),\n    })\n\n    const result: TurnstileVerifyResult = await response.json()\n\n    if (result.success) {\n      return { success: true }\n    } else {\n      const errorCodes = result['error-codes'] || []\n      console.error('Turnstile verification failed:', errorCodes)\n      return {\n        success: false,\n        error: errorCodes.length > 0 ? errorCodes.join(', ') : 'Verification failed',\n      }\n    }\n  } catch (error) {\n    console.error('Turnstile verification error:', error)\n    return {\n      success: false,\n      error: 'Verification service unavailable',\n    }\n  }\n}\n"
  },
  {
    "path": "src/types/goofish/index.ts",
    "content": "/**\n * Goofish 闲鱼模块类型定义\n */\n\n// 账号相关类型\nexport interface Account {\n  id: string\n  cookies: string\n  userId?: string\n  nickname?: string\n  avatar?: string\n  enabled: boolean\n  remark?: string\n  createdAt?: string\n  updatedAt?: string\n}\n\nexport interface ClientStatus {\n  accountId: string\n  connected: boolean\n  userId: string\n}\n\nexport interface StatusResponse {\n  clients: ClientStatus[]\n  activeCount: number\n  messageCount: number\n}\n\n// 消息相关类型\nexport interface Message {\n  id: number\n  accountId: string\n  chatId?: string\n  senderId?: string\n  senderName?: string\n  content?: string\n  raw?: string\n  createdAt?: string\n}\n\n// 对话相关类型\nexport interface Conversation {\n  accountId: string\n  chatId: string\n  userId: string\n  userName: string\n  userAvatar?: string\n  lastMessage?: string\n  lastTime: number\n  unread: number\n  createdAt?: string\n  updatedAt?: string\n}\n\n// 订单相关类型\nexport interface Order {\n  id: number\n  orderId: string\n  accountId: string\n  itemId?: string\n  itemTitle?: string\n  itemPicUrl?: string\n  price?: string\n  buyerUserId?: string\n  buyerNickname?: string\n  chatId?: string\n  status: number\n  statusText?: string\n  orderTime?: string\n  payTime?: string\n  shipTime?: string\n  completeTime?: string\n  createdAt?: string\n  updatedAt?: string\n}\n\n// 自动回复相关类型\nexport interface AutoReplyRule {\n  id: number\n  name: string\n  enabled: boolean\n  priority: number\n  matchType: 'contains' | 'equals' | 'regex' | 'startsWith' | 'endsWith'\n  matchPattern: string\n  replyContent: string\n  accountId?: string\n  excludeMatch: boolean\n  createdAt?: string\n  updatedAt?: string\n}\n\n// 自动发货相关类型\nexport interface AutoSellRule {\n  id: number\n  name: string\n  enabled: boolean\n  itemId?: string\n  accountId?: string\n  deliveryType: 'static' | 'api'\n  deliveryContent: string\n  apiConfig?: string\n  triggerOn: 'paid' | 'ordered'\n  workflowId?: number\n  createdAt?: string\n  updatedAt?: string\n}\n\n// 工作流相关类型\nexport interface Workflow {\n  id: number\n  name: string\n  description?: string\n  definition: WorkflowDefinition\n  isDefault: boolean\n  enabled: boolean\n  createdAt?: string\n  updatedAt?: string\n}\n\nexport interface WorkflowDefinition {\n  nodes: WorkflowNode[]\n  edges: WorkflowEdge[]\n}\n\nexport type WorkflowNodeType = \n  | 'trigger'\n  | 'autoreply'\n  | 'delivery'\n  | 'ship'\n  | 'delay'\n  | 'condition'\n  | 'notify'\n\nexport interface WorkflowNode {\n  id: string\n  type: WorkflowNodeType\n  position: { x: number; y: number }\n  data: Record<string, any>\n}\n\nexport interface WorkflowEdge {\n  id: string\n  source: string\n  target: string\n  condition?: string\n}\n\n// 日志相关类型\nexport interface LogEntry {\n  id: number\n  level: 'info' | 'warn' | 'error' | 'debug' | 'INFO' | 'WARN' | 'ERROR' | 'DEBUG'\n  message: string\n  timestamp?: string\n  context?: string\n}\n"
  },
  {
    "path": "src/types/turnstile.d.ts",
    "content": "/**\n * Cloudflare Turnstile 类型声明\n */\n\ninterface TurnstileObject {\n  render(container: Element | string, options: TurnstileConfig): string\n  getResponse(widgetId?: string): string\n  reset(widgetId: string): void\n  remove(widgetId: string): void\n}\n\ninterface TurnstileConfig {\n  sitekey: string\n  theme?: 'light' | 'dark' | 'auto'\n  size?: 'normal' | 'compact'\n  callback?: (token: string) => void\n  'expired-callback'?: () => void\n  'error-callback'?: () => void\n  'before-callback'?: () => void\n  'timeout-callback'?: () => void\n  theme?: 'light' | 'dark' | 'auto'\n}\n\ninterface Window {\n  turnstile?: TurnstileObject\n}\n"
  },
  {
    "path": "src/utils/backTop.ts",
    "content": "/** 滚动到页面顶部 */\nexport const scrollToTop = () => {\n  window.scrollTo({\n    top: 0,\n    behavior: 'smooth'\n  })\n}\n"
  },
  {
    "path": "src/utils/checkIp.ts",
    "content": "/**\n * 检测 IP 归属地并返回语言代码\n * @returns Promise<string> 返回 'zh' (中文) 或 'en' (英文)\n */\nexport const detectLanguageFromIP = async (): Promise<string> => {\n  try {\n    // 使用免费的 IP 地理位置查询 API\n    const response = await fetch('https://ipapi.co/json/')\n    const data = await response.json()\n\n    // 如果是中国大陆，返回 'zh'，否则返回 'en'\n    if (data.country_code === 'CN' || data.country === 'China') {\n      return 'zh'\n    }\n    return 'en'\n  } catch (error) {\n    console.error('IP detection failed, using browser language:', error)\n    // 如果 IP 检测失败，回退到浏览器语言检测\n    const browserLang = navigator.language || navigator.languages?.[0] || 'zh'\n    // 浏览器语言以 zh 开头（如 zh-CN, zh-TW）则使用中文，否则使用英文\n    return browserLang.startsWith('zh') ? 'zh' : 'en'\n  }\n}\n"
  },
  {
    "path": "src/utils/images.ts",
    "content": "/**\n * 统一管理项目中的图片资源\n * 集中导入所有图片，便于维护和管理\n */\nimport logoImg from '@/assets/images/logo.png'\nimport meImg from '@/assets/images/me.jpg'\nimport wxImg from '@/assets/images/wx.jpg'\nimport payImg from '@/assets/images/wxPay.png'\nimport translateImg from '@/assets/images/translate.png'\n\n// 导出所有图片\nexport const logoImage = logoImg\nexport const meImage = meImg\nexport const wxImage = wxImg\nexport const payImage = payImg\nexport const translateImage = translateImg\n"
  },
  {
    "path": "src/utils/isMobile.ts",
    "content": "// 检测是否为移动端设备\nexport const isMobileDevice = () => {\n  return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)\n}\n"
  },
  {
    "path": "src/utils/markmap.ts",
    "content": "declare global {\n  interface Window {\n    markmap: any\n    d3: any\n    fullscreenElement?: any\n    webkitFullscreenElement?: any\n    mozFullScreenElement?: any\n    msFullscreenElement?: any\n  }\n}\n\nexport interface AiResult {\n  markdown: string\n  root: any\n}\n\nexport interface NodeContext {\n  lineIndex: number\n  prefix: string\n}\n\nexport const LAST_SUCCESSFUL_MODEL_KEY = 'ai-mindmap-last-successful-model'\nexport const colorPalette = ['#3B82F6', '#16A34A', '#F97316', '#9333EA', '#E11D48', '#0891B2']\n\nexport const waitForLibraries = (): Promise<void> => {\n  return new Promise((resolve, reject) => {\n    const checkInterval = setInterval(() => {\n      if (window.markmap) {\n        clearInterval(checkInterval)\n        resolve()\n      }\n    }, 100)\n    setTimeout(() => {\n      clearInterval(checkInterval)\n      reject(new Error('核心库加载超时，请检查网络连接或刷新页面。'))\n    }, 10000)\n  })\n}\n\nexport const getNodeColor = (node: any) => {\n  if (node.depth === 0) return '#374151'\n  const index = (node.depth - 1) % colorPalette.length\n  return colorPalette[index]\n}\n\nexport const getMindmapCssRules = () => {\n  let cssText = ''\n\n  // 收集所有 markmap 相关的样式规则\n  const relevantSelectors = [\n    '.markmap',\n    '.markmap text',\n    '.markmap g',\n    '.markmap path',\n    '.markmap line',\n    '.markmap circle',\n    '.markmap foreignObject',\n    '[data-depth]'\n  ]\n\n  for (const styleSheet of document.styleSheets) {\n    try {\n      if (styleSheet.cssRules) {\n        for (const rule of styleSheet.cssRules as any) {\n          const selectorText = rule.selectorText\n          // 包含任何相关选择器的规则都收集\n          if (relevantSelectors.some(selector => selectorText?.includes(selector))) {\n            cssText += rule.cssText + '\\n'\n          }\n        }\n      }\n    } catch (e) {\n      console.warn('无法读取样式表中的CSS规则:', styleSheet.href, e)\n    }\n  }\n\n  // 添加内联样式（如果有的话）\n  const inlineStyles = document.querySelectorAll('style[data-markmap]')\n  inlineStyles.forEach(style => {\n    if (style.textContent) {\n      cssText += style.textContent\n    }\n  })\n\n  return cssText\n}\n\nexport const createExportableSvg = (svgElement: SVGSVGElement) => {\n  // 直接使用 SVG 的当前尺寸和 viewBox\n  const viewBox = svgElement.viewBox.baseVal\n  const rect = svgElement.getBoundingClientRect()\n\n  let viewBoxX = 0\n  let viewBoxY = 0\n  let viewBoxWidth = rect.width || 800\n  let viewBoxHeight = rect.height || 600\n\n  // 如果 SVG 有有效的 viewBox，使用它\n  if (viewBox && viewBox.width > 0 && viewBox.height > 0) {\n    viewBoxX = viewBox.x\n    viewBoxY = viewBox.y\n    viewBoxWidth = viewBox.width\n    viewBoxHeight = viewBox.height\n  }\n\n  // 克隆 SVG\n  const svgClone = svgElement.cloneNode(true) as SVGSVGElement\n\n  // 移除动态属性\n  svgClone.removeAttribute('style')\n  svgClone.removeAttribute('width')\n  svgClone.removeAttribute('height')\n\n  // 添加 padding，确保内容不会被裁剪\n  const padding = 60\n  const finalWidth = viewBoxWidth + padding * 2\n  const finalHeight = viewBoxHeight + padding * 2\n\n  // 设置固定尺寸\n  svgClone.setAttribute('width', finalWidth.toString())\n  svgClone.setAttribute('height', finalHeight.toString())\n\n  // 调整 viewBox 以包含 padding\n  svgClone.setAttribute('viewBox', `${viewBoxX - padding} ${viewBoxY - padding} ${finalWidth} ${finalHeight}`)\n\n  // 添加样式\n  const style = document.createElement('style')\n  style.textContent = getMindmapCssRules()\n  svgClone.insertBefore(style, svgClone.firstChild)\n\n  const serializer = new XMLSerializer()\n  let svgString = serializer.serializeToString(svgClone)\n\n  // 修复命名空间\n  svgString = svgString.replace(/(\\w+)?:?xlink=/g, 'xmlns:xlink=').replace(/NS\\d+:href/g, 'xlink:href')\n\n  return { svgString, width: finalWidth, height: finalHeight }\n}\n\nexport const downloadBlob = (blob: Blob, fileName: string) => {\n  const url = URL.createObjectURL(blob)\n  const link = document.createElement('a')\n  link.href = url\n  link.download = fileName\n\n  document.body.appendChild(link)\n  link.click()\n\n  document.body.removeChild(link)\n  URL.revokeObjectURL(url)\n}\n\nexport const generateExportFileName = (markdown: string, extension: string) => {\n  let topic = 'aimarkmap'\n  const lines = markdown.split('\\n')\n  for (const line of lines) {\n    const match = line.match(/^#\\s+(.+)/)\n    if (match) {\n      topic = match[1].replace(/[^\\w\\u4e00-\\u9fa5]/g, '').trim() || 'aimarkmap'\n      break\n    }\n  }\n\n  const now = new Date()\n  const dateStr = now.getFullYear().toString() +\n    String(now.getMonth() + 1).padStart(2, '0') +\n    String(now.getDate()).padStart(2, '0') +\n    String(now.getHours()).padStart(2, '0') +\n    String(now.getMinutes()).padStart(2, '0') +\n    String(now.getSeconds()).padStart(2, '0')\n\n  return `${topic}_${dateStr}.${extension}`\n}\n\nexport const collectNodeLines = (node: any, linesSet: Set<number>) => {\n  const markmapNode = node.data\n  if (markmapNode?.payload?.lines) {\n    const [start, end] = markmapNode.payload.lines\n    for (let i = start; i < end; i++) {\n      linesSet.add(i)\n    }\n  }\n  if (node.children) {\n    for (const child of node.children) {\n      collectNodeLines(child, linesSet)\n    }\n  }\n}\n\nexport const removeContextMenu = () => {\n  const existingMenu = document.getElementById('node-context-menu')\n  if (existingMenu) {\n    existingMenu.remove()\n  }\n}\n\nexport const createContextMenu = (\n  event: MouseEvent,\n  nodeData: any,\n  currentMarkdown: string,\n  onEditNode: (originalText: string, lineIndex: number, prefix: string) => void,\n  onDeleteNode: (node: any) => void\n) => {\n  event.preventDefault()\n  event.stopPropagation()\n  removeContextMenu()\n\n  const { pageX, pageY } = event\n\n  const lines = currentMarkdown.split('\\n')\n  const lineIndex = nodeData.data?.payload?.lines?.[0]\n  if (lineIndex === undefined || lines[lineIndex] === undefined) {\n    console.error('Invalid node data for context menu:', nodeData)\n    return\n  }\n  const fullLine = lines[lineIndex]\n\n  const menu = document.createElement('div')\n  menu.id = 'node-context-menu'\n  menu.className = 'context-menu'\n  menu.addEventListener('contextmenu', e => e.preventDefault())\n\n  const editItem = document.createElement('div')\n  editItem.className = 'context-menu-item'\n  editItem.innerHTML = '✏️ 编辑节点'\n  editItem.onclick = (e) => {\n    e.stopPropagation()\n    removeContextMenu()\n\n    const match = fullLine.match(/^(\\s*(?:#+\\s*|-\\s*|\\d+\\.\\s*))/)\n    const prefix = match ? match[0] : ''\n    const originalText = nodeData.data.content\n\n    onEditNode(originalText, lineIndex, prefix)\n  }\n  menu.appendChild(editItem)\n\n  const deleteItem = document.createElement('div')\n  deleteItem.className = 'context-menu-item'\n  deleteItem.innerHTML = '🗑️ 删除节点'\n  deleteItem.onclick = (e) => {\n    e.stopPropagation()\n    onDeleteNode(nodeData)\n    removeContextMenu()\n  }\n  menu.appendChild(deleteItem)\n\n  document.body.appendChild(menu)\n\n  const menuWidth = menu.offsetWidth\n  const menuHeight = menu.offsetHeight\n  const { innerWidth, innerHeight } = window\n\n  let left = pageX\n  let top = pageY\n\n  if (pageX + menuWidth > innerWidth) {\n    left = innerWidth - menuWidth - 5\n  }\n  if (pageY + menuHeight > innerHeight) {\n    top = innerHeight - menuHeight - 5\n  }\n\n  menu.style.top = `${top}px`\n  menu.style.left = `${left}px`\n}\n"
  },
  {
    "path": "src/utils/paper.ts",
    "content": "import dayjs from 'dayjs'\n\ninterface AuthorData {\n  _id: string;\n  avatarUrl?: string;\n  fullname: string;\n  name: string;\n  type: string;\n  isPro?: boolean;\n  isHf?: boolean;\n  isHfAdmin?: boolean;\n  isMod?: boolean;\n  plan?: string;\n  followerCount: number;\n  isUserFollowing: boolean;\n}\n\n/**\n * 获取作者姓名列表\n * @param authors 作者数据数组\n * @returns 格式化后的作者姓名字符串\n*/\nexport const getAuthorNames = (authors: Array<{ name: string; _id: string }>): string => {\n  if (!authors || !Array.isArray(authors) || authors.length === 0) return '未知作者'\n  const names = authors.slice(0, 2).map(author => author.name)\n  return names.length > 2 ? `${names.join(', ')} 等` : names.join(', ')\n}\n\n/**\n * 获取作者姓名或用户名\n * @param authorData 作者数据\n * @returns 作者姓名或用户名\n*/\nexport const getAuthorDataName = (authorData?: AuthorData): string => {\n  return authorData?.fullname || authorData?.name || '未知'\n}\n\n/**\n * 获取组织名称\n * @param org 组织数据\n * @returns 组织名称\n*/\nexport const getOrganizationName = (org?: { fullname?: string; name?: string }): string => {\n  return org?.fullname || org?.name || ''\n}\n\n/**\n * 获取时间agos\n * @param dateString 日期字符串\n * @returns 时间agos字符串\n*/\nexport const getTimeAgo = (dateString: string): string => {\n  const date = dayjs(dateString)\n  const now = dayjs()\n  const diffHours = now.diff(date, 'hour')\n  if (diffHours < 1) return '刚刚'\n  if (diffHours < 24) return `${diffHours}小时前`\n  if (diffHours < 24 * 7) return `${Math.floor(diffHours / 24)}天前`\n  return date.format('MM-DD')\n}\n\n/**\n * 格式化数字，添加单位（k、M）\n * @param num 数字\n * @returns 格式化后的字符串\n*/\nexport const formatNumber = (num: number | undefined): string => {\n  if (num === undefined) return '0'\n  if (num >= 1000000) return `${(num / 1000000).toFixed(1)}M`\n  if (num >= 1000) return `${(num / 1000).toFixed(1)}k`\n  return num.toString()\n}\n\n/**\n * 格式化参数数量，添加单位（B、M、k）\n * @param params 参数数量\n * @returns 格式化后的字符串\n*/\nexport const formatParamCount = (params: number | undefined): string => {\n  if (!params) return ''\n  if (params >= 1000000000) return `${(params / 1000000000).toFixed(1)}B`\n  if (params >= 1000000) return `${(params / 1000000).toFixed(1)}M`\n  return formatNumber(params)\n}\n\n/**\n * 获取模型任务标签\n * @param pipeline_tag 模型任务标签\n * @returns 格式化后的任务标签字符串\n*/\nexport const getTaskTag = (pipeline_tag?: string) => {\n  if (!pipeline_tag) return null\n  const taskMap: Record<string, string> = {\n    'text-generation': '文本生成',\n    'image-to-text': '图生文',\n    'any-to-any': '多模态',\n    'text-to-audio': '文生音频',\n    'image-text-to-text': '图文理解',\n    'automatic-speech-recognition': '语音识别',\n    'conversational': '对话',\n  }\n  return taskMap[pipeline_tag] || pipeline_tag\n}\n\n/**\n * 获取硬件标签\n * @param runtime 模型运行时信息\n * @returns 格式化后的硬件标签字符串\n*/\nexport const getHardwareTag = (runtime: any) => {\n  if (!runtime?.hardware?.current) return null\n  const hw = runtime.hardware.current\n  if (hw.includes('a100')) return 'A100'\n  if (hw.includes('a10g')) return 'A10G'\n  if (hw.includes('cpu')) return 'CPU'\n  return hw\n}\n"
  },
  {
    "path": "src/utils/price.ts",
    "content": "/**\n * 格式化价格\n * @param price - 价格值\n * @param currency - 货币类型，例如 'USD' 或 'CNY'\n * @returns 返回格式化后的价格字符串，例如 '$10.00' 或 '¥10.00'\n */\nexport const formatPrice = (price: number | undefined, currency: string): string => {\n  if (!price) return '--'\n  const formatted = price.toFixed(2)\n  return currency === 'USD' ? `$${formatted}` : `¥${formatted}`\n}\n\n/**\n * 格式化价格变化值\n * @param change - 价格变化值\n * @returns 返回格式化后的价格变化字符串，例如 '+10.00' 或 '-5.00'\n */\nexport const formatChange = (change: number | undefined): string => {\n  if (change === undefined) return '--'\n  const sign = change >= 0 ? '+' : ''\n  return `${sign}${change.toFixed(2)}`\n}\n\n/**\n * 格式化百分比\n * @param percent - 百分比值\n * @returns 返回格式化后的百分比字符串，例如 '+10.00%' 或 '-5.00%'\n */\nexport const formatPercent = (percent: number | undefined): string => {\n  if (percent === undefined) return '--'\n  const sign = percent >= 0 ? '+' : ''\n  return `${sign}${percent.toFixed(2)}%`\n}\n\n/**\n * 根据价格变化百分比返回价格类名\n * @param changePercent - 价格变化百分比值\n * @returns 返回价格类名，例如 'up' 或 'down'\n */\nexport const getPriceClass = (changePercent: number | undefined): string => {\n  if (changePercent === undefined) return ''\n  return changePercent >= 0 ? 'up' : 'down'\n}\n"
  },
  {
    "path": "src/utils/token.ts",
    "content": "/**\n * Token 管理工具\n * 用于管理用户登录状态的 token\n */\n\nconst TOKEN_KEY = 'chattyplay-token'\n\n/**\n * 生成随机 token\n */\nconst generateToken = (): string => {\n  return Math.random().toString(36).substring(2) + Date.now().toString(36)\n}\n\n/**\n * 保存 token 到 localStorage\n * @param token - 要保存的 token 值，如果不传则自动生成随机 token\n */\nexport const setToken = (token?: string): void => {\n  const tokenValue = token || generateToken()\n  localStorage.setItem(TOKEN_KEY, tokenValue)\n}\n\n/**\n * 获取 token\n * @returns 返回存储的 token，如果不存在则返回 null\n */\nexport const getToken = (): string | null => {\n  return localStorage.getItem(TOKEN_KEY)\n}\n\n/**\n * 删除 token（退出登录时使用）\n */\nexport const removeToken = (): void => {\n  localStorage.removeItem(TOKEN_KEY)\n}\n\n/**\n * 检查是否已登录\n * @returns 返回是否已登录（token 是否存在）\n */\nexport const isAuthenticated = (): boolean => {\n  return !!getToken()\n}\n\n/**\n * 保存键值对到 localStorage\n * @param key - 键名\n * @param value - 键值\n */\nexport const setStorageItem = (key: string, value: string): void => {\n  localStorage.setItem(key, value)\n}\n\n/**\n * 获取 localStorage 中的值\n * @param key - 键名\n * @returns 返回对应的值，如果不存在则返回 null\n */\nexport const getStorageItem = (key: string): string | null => {\n  return localStorage.getItem(key)\n}\n\n/**\n * 删除 localStorage 中的键值对\n * @param key - 键名\n */\nexport const removeStorageItem = (key: string): void => {\n  localStorage.removeItem(key)\n}\n\n/**\n * 清空所有 localStorage 数据\n */\nexport const clearStorage = (): void => {\n  localStorage.clear()\n}\n"
  },
  {
    "path": "src/utils/versionChecker.ts",
    "content": "/**\n * 版本检测工具\n * 用于检测应用版本更新并提示用户\n */\n\nexport interface VersionInfo {\n  current: string\n  stored: string | null\n}\n\nconst VERSION_STORAGE_KEY = 'app_version'\nconst VERSION_CHECK_FLAG_KEY = 'version_update_checked'\n\n/**\n * 获取当前应用版本\n * 从 package.json 读取版本号\n */\nexport const getCurrentVersion = (): string => {\n  // 从全局变量获取版本（在 vite.config.ts 中定义）\n  if (typeof __APP_VERSION__ !== 'undefined') {\n    return __APP_VERSION__\n  }\n  // 备用方案：从环境变量获取\n  return import.meta.env.VITE_APP_VERSION || '1.0.0'\n}\n\n/**\n * 获取存储的版本号\n */\nexport const getStoredVersion = (): string | null => {\n  return localStorage.getItem(VERSION_STORAGE_KEY)\n}\n\n/**\n * 保存当前版本号到 localStorage\n */\nexport const saveCurrentVersion = (): void => {\n  const version = getCurrentVersion()\n  localStorage.setItem(VERSION_STORAGE_KEY, version)\n}\n\n/**\n * 检查版本是否更新\n * @returns {boolean} 如果版本已更新返回 true，否则返回 false\n */\nexport const checkVersionUpdate = (): boolean => {\n  const currentVersion = getCurrentVersion()\n  const storedVersion = getStoredVersion()\n\n  // 如果没有存储过版本，说明是首次安装，不需要提示\n  if (!storedVersion) {\n    saveCurrentVersion()\n    return false\n  }\n\n  // 比较版本号\n  if (currentVersion !== storedVersion) {\n    return true\n  }\n\n  return false\n}\n\n/**\n * 获取版本信息\n */\nexport const getVersionInfo = (): VersionInfo => {\n  return {\n    current: getCurrentVersion(),\n    stored: getStoredVersion()\n  }\n}\n\n/**\n * 处理版本更新后的清理工作\n * 清空 localStorage，保留之前的语言设置，然后重新加载页面\n */\nexport const handleVersionUpdate = (): void => {\n  // 保留需要保留的键值\n  const preservedKeys = ['language', 'i18nextLng']\n  const preservedData: Record<string, string | null> = {}\n  \n  // 保存需要保留的数据\n  preservedKeys.forEach(key => {\n    const value = localStorage.getItem(key)\n    if (value !== null) {\n      preservedData[key] = value\n    }\n  })\n  \n  // 清空所有 localStorage\n  localStorage.clear()\n  \n  // 恢复需要保留的数据\n  Object.entries(preservedData).forEach(([key, value]) => {\n    if (value !== null) {\n      localStorage.setItem(key, value)\n    }\n  })\n  \n  // 重新加载页面\n  window.location.reload()\n}\n\n/**\n * 标记版本更新已处理\n */\nexport const markVersionUpdateHandled = (): void => {\n  localStorage.setItem(VERSION_CHECK_FLAG_KEY, 'true')\n}\n\n/**\n * 检查是否已处理过版本更新提示\n */\nexport const isVersionUpdateHandled = (): boolean => {\n  return localStorage.getItem(VERSION_CHECK_FLAG_KEY) === 'true'\n}\n\n/**\n * 保存新版本号（用户确认更新后）\n */\nexport const updateStoredVersion = (): void => {\n  saveCurrentVersion()\n  // 清除处理标记\n  localStorage.removeItem(VERSION_CHECK_FLAG_KEY)\n}\n"
  },
  {
    "path": "src/version.d.ts",
    "content": "/**\n * 全局类型声明\n */\ndeclare const __APP_VERSION__: string\n"
  },
  {
    "path": "src/vite-env.d.ts",
    "content": "/// <reference types=\"vite/client\" />\n\ninterface ImportMetaEnv {\n  readonly VITE_BAIDU_APP_ID: string\n  readonly VITE_BAIDU_SECRET_KEY: string\n  readonly VITE_OPENAI_BASE_URL: string\n  readonly VITE_OPENAI_API_KEY: string\n}\n\ninterface ImportMeta {\n  readonly env: ImportMetaEnv\n}\n"
  },
  {
    "path": "tailwind.config.js",
    "content": "/** @type {import('tailwindcss').Config} */\nexport default {\n  content: [\n    \"./index.html\",\n    \"./src/**/*.{js,ts,jsx,tsx}\",\n  ],\n  theme: {\n    extend: {},\n  },\n  plugins: [],\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"useDefineForClassFields\": true,\n    \"lib\": [\"ES2020\", \"DOM\", \"DOM.Iterable\"],\n    \"types\": [\"node\"],\n    \"module\": \"ESNext\",\n    \"skipLibCheck\": true,\n\n    /* Bundler mode */\n    \"moduleResolution\": \"bundler\",\n    \"allowImportingTsExtensions\": true,\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"noEmit\": true,\n    \"jsx\": \"react-jsx\",\n\n    /* Path aliases */\n    \"baseUrl\": \".\",\n    \"paths\": {\n      \"@/*\": [\"./src/*\"]\n    },\n\n    /* Linting */\n    \"strict\": true,\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": true,\n    \"noFallthroughCasesInSwitch\": true\n  },\n  \"include\": [\"src\", \"api\"],\n  \"exclude\": [\"src/services/server.ts\", \"src/services/worker.ts\", \"src/goofish\"],\n  \"references\": [{ \"path\": \"./tsconfig.node.json\" }]\n}"
  },
  {
    "path": "tsconfig.node.json",
    "content": "{\n  \"compilerOptions\": {\n    \"composite\": true,\n    \"skipLibCheck\": true,\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"allowSyntheticDefaultImports\": true,\n    \"types\": [\"node\"]\n  },\n  \"include\": [\"vite.config.ts\"]\n}\n"
  },
  {
    "path": "vercel.json",
    "content": "{\n  \"headers\": [\n    {\n      \"source\": \"/api/(.*)\",\n      \"headers\": [\n        { \"key\": \"Access-Control-Allow-Origin\", \"value\": \"*\" },\n        { \"key\": \"Access-Control-Allow-Methods\", \"value\": \"GET,POST,PUT,DELETE,OPTIONS\" },\n        { \"key\": \"Access-Control-Allow-Headers\", \"value\": \"Content-Type, Authorization\" },\n        { \"key\": \"Access-Control-Allow-Credentials\", \"value\": \"true\" },\n        { \"key\": \"Cache-Control\", \"value\": \"no-store, no-cache, must-revalidate\" }\n      ]\n    },\n    {\n      \"source\": \"/(.*)\",\n      \"headers\": [\n        { \"key\": \"Cache-Control\", \"value\": \"public, max-age=0, must-revalidate\" }\n      ]\n    }\n  ],\n  \"rewrites\": [\n    {\n      \"source\": \"/api/translate/:path*\",\n      \"destination\": \"https://fanyi-api.baidu.com/api/trans/vip/translate/:path*\"\n    },\n    {\n      \"source\": \"/api/kuaikan/:path*\",\n      \"destination\": \"https://www.kuaikanmanhua.com/:path*\"\n    },\n    {\n      \"source\": \"/api/kuaikan-m/:path*\",\n      \"destination\": \"https://m.kuaikanmanhua.com/:path*\"\n    },\n    {\n      \"source\": \"/api/netease/:path*\",\n      \"destination\": \"https://netease-cloud-music-api.fe-mm.com/:path*\"\n    },\n    {\n      \"source\": \"/api/:path*\",\n      \"destination\": \"/api/index.ts\"\n    },\n    {\n      \"source\": \"/((?!api/).*)\",\n      \"destination\": \"/index.html\"\n    }\n  ]\n}\n"
  },
  {
    "path": "vite.config.ts",
    "content": "import { defineConfig } from 'vite'\nimport react from '@vitejs/plugin-react'\nimport pkg from './package.json'\nimport { spawn } from 'child_process'\nimport { copyFileSync, existsSync } from 'fs'\nimport { resolve } from 'path'\n\n// Hono 服务器插件 - 自动启动后端服务\nfunction honoServerPlugin() {\n  return {\n    name: 'hono-server',\n    configureServer() {\n      const serverProcess = spawn('npx', ['tsx', 'src/services/server.ts'], {\n        stdio: 'inherit',\n        shell: true\n      })\n\n      console.log('\\x1b[36m%s\\x1b[0m', 'Hono Proxy Server with Goofish started')\n\n      // Vite 服务器关闭时也关闭 Hono 服务器\n      return () => {\n        serverProcess.kill()\n        console.log('\\x1b[33m%s\\x1b[0m', 'Hono Proxy Server stopped')\n      }\n    }\n  }\n}\n\n// 复制 .htaccess 到 dist 目录\nfunction copyHtaccessPlugin() {\n  return {\n    name: 'copy-htaccess',\n    closeBundle() {\n      const publicHtaccess = resolve(__dirname, 'public', '.htaccess')\n      const distHtaccess = resolve(__dirname, 'dist', '.htaccess')\n\n      if (existsSync(publicHtaccess)) {\n        copyFileSync(publicHtaccess, distHtaccess)\n        console.log('\\x1b[32m%s\\x1b[0m', 'Copied .htaccess to dist/')\n      } else {\n        console.log('\\x1b[33m%s\\x1b[0m', 'No .htaccess found in public/')\n      }\n    }\n  }\n}\n\n// https://vitejs.dev/config/\nexport default defineConfig({\n  define: {\n    __APP_VERSION__: JSON.stringify(pkg.version)\n  },\n  plugins: [react(), honoServerPlugin(), copyHtaccessPlugin()],\n  server: {\n    host: '0.0.0.0', // 允许真机通过局域网 IP 访问\n    port: 3000,\n    open: true,\n    // 代理配置：开发环境下将 /api 请求转发到后端服务器\n    proxy: {\n      '/api': {\n        target: 'http://localhost:3001',\n        changeOrigin: true,\n        rewrite: (path) => path\n      },\n      '/api/latex': {\n        target: 'http://localhost:3001',\n        changeOrigin: true,\n        rewrite: (path) => path\n      },\n      '/ws': {\n        target: 'ws://localhost:3001',\n        ws: true\n      },\n      '/health': {\n        target: 'http://localhost:3001',\n        changeOrigin: true\n      }\n    }\n  },\n  resolve: {\n    alias: {\n      '@': '/src'\n    }\n  },\n  css: {\n    preprocessorOptions: {\n      less: {\n        javascriptEnabled: true\n      }\n    }\n  }\n})\n"
  }
]