[
  {
    "path": ".changelogrc.js",
    "content": "module.exports = {\n    preset: 'conventionalcommits',\n    releaseCount: 0,\n    outputUnreleased: true,\n    lernaPackage: false,\n    tagPrefix: 'v',\n    issuePrefixes: ['#'],\n    commitUrlFormat: '{{host}}/{{owner}}/{{repository}}/commit/{{hash}}',\n    compareUrlFormat: '{{host}}/{{owner}}/{{repository}}/compare/{{previousTag}}...{{currentTag}}',\n    issueUrlFormat: '{{host}}/{{owner}}/{{repository}}/issues/{{id}}',\n    userUrlFormat: '{{host}}/{{user}}',\n    // 自定义类型和 emoji\n    types: [\n        { type: 'feat', section: '✨ Features | 新功能' },\n        { type: 'fix', section: '🐛 Bug Fixes | Bug 修复' },\n        { type: 'docs', section: '📝 Documentation | 文档' },\n        { type: 'style', section: '💄 Styles | 风格' },\n        { type: 'refactor', section: '♻️ Code Refactoring | 代码重构' },\n        { type: 'perf', section: '⚡ Performance Improvements | 性能优化' },\n        { type: 'test', section: '✅ Tests | 测试' },\n        { type: 'build', section: '📦‍ Build System | 打包构建' },\n        { type: 'ci', section: '👷 Continuous Integration | CI 配置' },\n        { type: 'chore', section: '🚀 Chore | 构建/工程依赖/工具' },\n        { type: 'revert', section: '⏪ Revert | 回退' }\n    ]\n};\n"
  },
  {
    "path": ".copilot.md",
    "content": "项目说明：\n本项目为 uView Pro 组件库，基于 uni-app、Vue3、TypeScript、Composition API 语法，重构自 uView UI 1.8.8。\n\n目录规范：\n\n- 每个组件目录下包含：组件名.vue、types.ts（Props、emit等类型定义）\n- 组件代码路径：src/uni_modules/uview-pro/components/组件名/\n- 示例代码路径：src/pages/\n\n开发建议：\n\n- 组件开发请统一使用 Vue3 + TS + <script setup> 语法\n- 类型定义（Props、emit等）请放在 types.ts 文件\n- 示例代码请放在 src/pages 下，便于查阅和演示\n"
  },
  {
    "path": ".cz-config.js",
    "content": "module.exports = {\n    // 可选类型\n    types: [\n        { value: 'feat', name: 'feat:     新功能' },\n        { value: 'fix', name: 'fix:      修复bug' },\n        { value: 'docs', name: 'docs:     文档更新' },\n        { value: 'style', name: 'style:    代码格式调整' },\n        { value: 'refactor', name: 'refactor: 代码重构' },\n        { value: 'perf', name: 'perf:     性能优化' },\n        { value: 'test', name: 'test:     测试相关' },\n        { value: 'build', name: 'build:    构建相关' },\n        { value: 'ci', name: 'ci:        CI/CD相关' },\n        { value: 'chore', name: 'chore:    其他修改' },\n        { value: 'revert', name: 'revert:   回退代码' }\n    ],\n    // 消息步骤\n    messages: {\n        type: '选择更改类型:',\n        scope: '更改范围 (可选):',\n        subject: '简短描述:',\n        body: '详细描述 (可选):',\n        breaking: '破坏性变更 (可选):',\n        footer: '关联issue (可选):',\n        confirmCommit: '确认提交?'\n    },\n    // 跳过问题\n    skipQuestions: ['body', 'footer'],\n    // 范围列表\n    scopes: [\n        { name: 'components', description: '组件相关' },\n        { name: 'pages', description: '页面相关' },\n        { name: 'utils', description: '工具函数' },\n        { name: 'styles', description: '样式相关' },\n        { name: 'docs', description: '文档相关' },\n        { name: 'config', description: '配置相关' },\n        { name: 'deps', description: '依赖相关' }\n    ],\n    // 范围前缀\n    scopePrefix: '',\n    // 主题前缀\n    subjectPrefix: '',\n    // 主题后缀\n    subjectSuffix: '',\n    // 范围前缀\n    scopePrefix: '',\n    // 范围后缀\n    scopeSuffix: '',\n    // 主题前缀\n    subjectPrefix: '',\n    // 主题后缀\n    subjectSuffix: '',\n    // 破坏性变更前缀\n    breakingPrefix: 'BREAKING CHANGE:',\n    // 关联issue前缀\n    footerPrefix: 'Closes',\n    // 关联issue后缀\n    footerSuffix: '',\n    // 是否允许自定义范围\n    allowCustomScopes: true,\n    // 是否允许空范围\n    allowEmptyScopes: true,\n    // 是否允许自定义主题\n    allowCustomSubject: true,\n    // 是否允许空主题\n    allowEmptySubject: false,\n    // 主题最大长度\n    subjectLimit: 100,\n    // 范围最大长度\n    scopeLimit: 100\n};\n"
  },
  {
    "path": ".czrc",
    "content": "{\n  \"path\": \"./node_modules/cz-git\"\n} "
  },
  {
    "path": ".editorconfig",
    "content": "[*]\n#缩进风格：空格\nindent_style = tab\n#缩进大小2\nindent_size = 4\n#换行符lf\nend_of_line = lf\n#字符集utf-8\ncharset = utf-8\n\n\n"
  },
  {
    "path": ".eslintignore",
    "content": "unpackage\nnode_modules\nasync-validator.js\ncalendar.js\narea.ts\ncity.ts\nprovince.ts\n"
  },
  {
    "path": ".gitee/ISSUE_TEMPLATE/bug_report.yml",
    "content": "name: 问题反馈\nabout: 提交问题反馈或使用疑问，便于强化项目维护和优化体验\nlabels: ['bug', 'question']\ntitle: '【问题反馈】'\nbody:\n    - type: textarea\n      attributes:\n          label: 问题描述\n          description: 请简要描述您遇到的问题或疑问。\n    - type: textarea\n      attributes:\n          label: 复现步骤\n          description: 请详细描述如何复现该问题，建议提供相关页面/组件/功能入口、操作步骤、期望结果与实际结果。\n    - type: textarea\n      attributes:\n          label: 复现环境\n          description: |\n              - uView Pro 版本：\n              - uni-app 版本：\n              - 运行平台：H5 / 微信小程序 / 支付宝小程序 / App / 其他\n              - 浏览器或系统版本：\n    - type: textarea\n      attributes:\n          label: 截图或日志（可选）\n          description: 如有报错信息、控制台输出、页面截图等，请一并附上，便于定位问题。\n    - type: textarea\n      attributes:\n          label: 其他补充信息（可选）\n          description: 如有相关代码片段、配置文件、第三方依赖等信息，请补充说明。\n"
  },
  {
    "path": ".gitee/ISSUE_TEMPLATE/feature_request.yml",
    "content": "name: 新功能征集\nabout: 提出新功能或优化建议，使 uView Pro 更强大！\nlabels: ['enhancement', 'feature-request']\ntitle: '【新功能征集】'\nbody:\n    - type: textarea\n      attributes:\n          label: 功能描述\n          description: 简要说明您希望实现的功能是什么。\n    - type: textarea\n      attributes:\n          label: 使用场景\n          description: 举例说明该功能在实际项目中的应用场景或痛点。\n    - type: textarea\n      attributes:\n          label: 期望效果\n          description: 描述该功能实现后，开发者或用户将获得哪些便利。\n    - type: textarea\n      attributes:\n          label: API 设计（可选）\n          description: 如有具体 API 或用法建议，请一并提供。\n    - type: textarea\n      attributes:\n          label: 相关资料（可选）\n          description: 如有参考的其他框架、设计稿、交互原型等，请附上链接或截图。\n    - type: textarea\n      attributes:\n          label: 扩展建议（可选）\n          description: 如有多端兼容性、性能、可配置性、文档等建议可补充。\n"
  },
  {
    "path": ".gitee/PULL_REQUEST_TEMPLATE.md",
    "content": "# 该模板用于 Gitee Pull Request 自动加载，无需 YAML 头部\n\n## 🔀 PR 提交 | Pull Request\n\n感谢您的贡献！为提升代码质量和协作效率，请按以下模板补充关键信息：\n\n### 1. 变更类型\n\n- [ ] 新功能（Feature）\n- [ ] 问题修复（Bugfix）\n- [ ] 文档优化（Docs）\n- [ ] 样式调整（Style）\n- [ ] 代码重构（Refactor）\n- [ ] 性能优化（Perf）\n- [ ] 测试用例（Test）\n- [ ] 构建相关（Build）\n- [ ] 其他（请说明）：\n\n### 2. 变更内容简述\n\n请简要描述本次 PR 的主要内容、涉及的模块或组件。\n\n### 3. 相关 Issue（可选）\n\n如有相关 Issue，请填写（如：Close #123）。\n\n### 4. 变更影响范围\n\n- [ ] 兼容多端（H5/小程序/APP 等）\n- [ ] 影响现有 API\n- [ ] 需要文档同步\n- [ ] 需要补充测试\n- [ ] 其他：\n\n### 5. 测试用例与截图（可选）\n\n如有测试截图、演示视频、关键代码片段等，请一并附上。\n\n### 6. 其他说明（可选）\n\n如有注意事项、兼容性说明、后续计划等，请补充。\n\n---\n\n**提交格式参考：**\n\n```markdown\n### 变更类型\n\n- 新功能\n\n### 变更内容简述\n\n新增 u-xxx 组件，支持 xxx 功能。\n\n### 相关 Issue\n\nClose #123\n\n### 变更影响范围\n\n- 兼容多端\n- 需要文档同步\n\n### 测试用例与截图\n\n<粘贴截图或说明>\n\n### 其他说明\n\n无\n```\n\n---\n\n感谢您的贡献！我们会尽快审核和合并。如有疑问欢迎补充说明。\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: '问题反馈 Bug Report / Question'\nabout: '提交问题反馈或使用疑问，便于强化项目维护和优化体验'\ntitle: '【问题反馈】'\nlabels: ['bug', 'question']\nassignees: []\n---\n\n## 🐛 问题反馈 | Bug Report / Question\n\n### 1. 问题描述\n\n请简要描述您遇到的问题或疑问。\n\n### 2. 复现步骤\n\n请详细描述如何复现该问题，建议提供：\n\n- 相关页面/组件/功能入口\n- 操作步骤\n- 期望结果与实际结果\n\n### 3. 复现环境\n\n- uView Pro 版本：\n- uni-app 版本：\n- 运行平台：H5 / 微信小程序 / 支付宝小程序 / App / 其他\n- 浏览器或系统版本：\n\n### 4. 截图或日志（可选）\n\n如有报错信息、控制台输出、页面截图等，请一并附上，便于定位问题。\n\n### 5. 其他补充信息（可选）\n\n如有相关代码片段、配置文件、第三方依赖等信息，请补充说明。\n\n---\n\n感谢您的反馈！我们会尽快跟进和处理。如有更多细节，欢迎补充。\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: '新功能征集 Feature Request'\nabout: '提出新功能或优化建议，使 uView Pro 更强大！'\ntitle: '【新功能征集】'\nlabels: ['enhancement', 'feature-request']\nassignees: []\n---\n\n## 🚀 新功能征集 | Feature Request\n\n### 1. 说明\n\n感谢您关注 uView Pro！我们欢迎社区开发者和用户为框架提出新功能建议。请详细描述您希望添加的功能、预期的使用场景，以及该功能将如何提升开发体验或解决实际问题。我们会认真评估每一条建议，并根据实际情况进行规划和实现。\n\n### 2. 提交要求\n\n请在提交新功能建议时，尽量补充以下内容：\n\n- **功能描述**：简要说明您希望实现的功能是什么。\n- **使用场景**：举例说明该功能在实际项目中的应用场景或痛点。\n- **期望效果**：描述该功能实现后，开发者或用户将获得哪些便利。\n- **API 设计（可选）**：如有具体 API 或用法建议，请一并提供。\n- **相关资料（可选）**：如有参考的其他框架、设计稿、交互原型等，请附上链接或截图。\n\n### 3. 使用场景举例\n\n- 需要支持某类业务常用的 UI 组件（如时间轴、甘特图、数据可视化等）\n- 希望增强现有组件的某些能力（如表单校验、国际化、无障碍支持等）\n- 期望提供更灵活的主题定制、暗黑模式、响应式布局等\n- 希望集成第三方服务（如地图、支付、消息推送等）\n- 其他能提升开发效率或用户体验的创新点\n\n### 4. 扩展建议\n\n- **多端兼容性**：请考虑新功能在 H5、微信/支付宝/百度/QQ 小程序、App 等多端的适配性。\n- **性能与体积**：建议关注实现方式对包体积和运行性能的影响，避免引入过重依赖。\n- **可配置性**：优先考虑通用性和可配置性，便于不同项目灵活使用。\n- **文档与示例**：如有时间，欢迎一并补充文档说明或 DEMO 示例，方便他人理解和使用。\n\n---\n\n我们期待您的宝贵建议，共同打造更好用的 uView Pro！🎉\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/pull_request_template.md",
    "content": "---\nname: 'PR 提交 Pull Request'\nabout: '提交优质 PR，使 uView Pro 更强大！'\ntitle: '【PR提交】'\nlabels: ['pr', 'contribution']\nassignees: []\n---\n\n## 🔀 PR 提交 | Pull Request\n\n感谢您的贡献！为提升代码质量和协作效率，请按以下模板补充关键信息：\n\n### 1. 变更类型\n\n- [ ] 新功能（Feature）\n- [ ] 问题修复（Bugfix）\n- [ ] 文档优化（Docs）\n- [ ] 样式调整（Style）\n- [ ] 代码重构（Refactor）\n- [ ] 性能优化（Perf）\n- [ ] 测试用例（Test）\n- [ ] 构建相关（Build）\n- [ ] 其他（请说明）：\n\n### 2. 变更内容简述\n\n请简要描述本次 PR 的主要内容、涉及的模块或组件。\n\n### 3. 相关 Issue（可选）\n\n如有相关 Issue，请填写（如：Close #123）。\n\n### 4. 变更影响范围\n\n- [ ] 兼容多端（H5/小程序/APP 等）\n- [ ] 影响现有 API\n- [ ] 需要文档同步\n- [ ] 需要补充测试\n- [ ] 其他：\n\n### 5. 测试用例与截图（可选）\n\n如有测试截图、演示视频、关键代码片段等，请一并附上。\n\n### 6. 其他说明（可选）\n\n如有注意事项、兼容性说明、后续计划等，请补充。\n\n---\n\n感谢您的贡献！我们会尽快审核和合并。如有疑问欢迎补充说明。\n"
  },
  {
    "path": ".gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\npnpm-debug.log*\nlerna-debug.log*\n\nnode_modules\n.DS_Store\ndist\nbuild/\ndocs/\n*.local\n*.zip\n\n# Editor directories and files\n.idea\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n*.sw?\n.npmrc\n.trae/\n.agents/\nskills-lock.json\n"
  },
  {
    "path": ".hbuilderx/launch.json",
    "content": "{\n    \"version\": \"1.0\",\n    \"configurations\": [\n        {\n            \"playground\": \"standard\",\n            \"type\": \"uni-app:app-android\"\n        }\n    ]\n}\n"
  },
  {
    "path": ".husky/commit-msg",
    "content": "#!/usr/bin/env sh\n\nnpx --no -- commitlint --edit \"$1\" "
  },
  {
    "path": ".husky/pre-commit",
    "content": "#!/usr/bin/env sh\n. \"$(dirname \"$0\")/_/husky.sh\"\n\n# 可以在这里添加其他pre-commit检查，比如lint-staged等\nnpx lint-staged\n\n# 校验已缓存区文件格式和类型\n# npx lint-staged\n# pnpm exec vue-tsc --noEmit --incremental --include $(git diff --cached --name-only --diff-filter=ACM | grep -E '\\.(ts|vue)$' | tr '\\n' ' ')\n"
  },
  {
    "path": ".lintstagedrc",
    "content": "{\n    \"*.{js,ts,vue,scss,md,json}\": \"prettier --write --ignore-path .prettierignore\"\n}\n"
  },
  {
    "path": ".nvmrc",
    "content": "20.13.1"
  },
  {
    "path": ".prettierignore",
    "content": "node_modules\n*.log\ndist\nbuild\ncoverage\n*.min.js\n*.map\n*.md\npnpm-lock.yaml\nasync-validator.js\ncalendar.js\narea.ts\ncity.ts\nprovince.ts\nsrc/uni_modules/zero-markdown-view/*\n"
  },
  {
    "path": ".prettierrc.js",
    "content": "/**\n * Prettier 代码格式化配置\n * 详见：https://prettier.io/docs/en/options.html\n */\nmodule.exports = {\n    // 箭头函数参数是否加括号\n    arrowParens: 'avoid', // always/avoid\n    // 对象字面量大括号间是否加空格\n    bracketSpacing: true,\n    // 换行符风格（auto/lf/crlf/cr）\n    endOfLine: 'auto',\n    // HTML 空白敏感度\n    htmlWhitespaceSensitivity: 'css',\n    // 是否在文件头插入 @prettier\n    insertPragma: false,\n    // JSX > 是否将 > 放在同一行\n    jsxBracketSameLine: false,\n    // JSX 使用单引号\n    jsxSingleQuote: true,\n    // 每行最大字符数\n    printWidth: 120, // 推荐 100~120\n    // markdown/文档换行策略\n    proseWrap: 'preserve',\n    // 对象属性是否强制加引号\n    quoteProps: 'as-needed',\n    // 是否要求文件头有 @prettier\n    requirePragma: false,\n    // 语句末尾加分号\n    semi: true,\n    // 使用单引号\n    singleQuote: true,\n    // tab 宽度\n    tabWidth: 4,\n    // 末尾是否加逗号\n    trailingComma: 'none', // es5/none/all\n    // 使用 tab 还是空格\n    useTabs: false,\n    // Vue 文件 script/style 是否缩进\n    vueIndentScriptAndStyle: false,\n    // 是否格式化嵌入的代码（如 HTML <script>）\n    embeddedLanguageFormatting: 'auto'\n};\n"
  },
  {
    "path": ".vscode/extensions.json",
    "content": "{\n    // 推荐团队/贡献者安装的 VS Code 插件\n    \"recommendations\": [\n        \"esbenp.prettier-vscode\", // Prettier 代码格式化\n        \"Vue.volar\", // Vue3 官方语法支持（推荐代替 vetur）\n        \"dbaeumer.vscode-eslint\", // ESLint 代码规范\n        \"stylelint.vscode-stylelint\", // CSS/SCSS/Less 规范\n        \"streetsidesoftware.code-spell-checker\" // 拼写检查\n    ]\n}\n"
  },
  {
    "path": ".vscode/settings.json",
    "content": "{\n    \"git.enableSmartCommit\": true,\n    \"git.confirmSync\": false,\n    \"git.autofetch\": true,\n    \"emmet.includeLanguages\": {\n        \"vue-html\": \"html\",\n        \"vue\": \"html\"\n    },\n    \"typescript.preferences.importModuleSpecifier\": \"relative\",\n    \"editor.formatOnSave\": true,\n    \"editor.defaultFormatter\": \"esbenp.prettier-vscode\",\n    \"editor.codeActionsOnSave\": {\n        \"source.fixAll.eslint\": \"explicit\"\n    },\n    \"files.associations\": {\n        \"*.cz-config.js\": \"javascript\"\n    },\n    \"i18n-ally.localesPaths\": [\"src/locales\", \"src/locales/langs\", \"src/uni_modules/uview-pro/locale\"],\n    \"eslint.validate\": [\"javascript\", \"typescript\", \"vue\"],\n    \"[vue]\": {\n        \"editor.defaultFormatter\": \"esbenp.prettier-vscode\"\n    },\n    // Markdown 文件禁用保存时格式化\n    \"[markdown]\": {\n        \"editor.formatOnSave\": false\n    }\n}\n"
  },
  {
    "path": ".vscode/uview-pro.code-snippets",
    "content": "{\n    // Place your colorful-uni-plus 工作区 snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and\n    // description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope\n    // is left empty or omitted, the snippet gets applied to all languages. The prefix is what is\n    // used to trigger the snippet and the body will be expanded and inserted. Possible variables are:\n    // $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.\n    // Placeholders with the same ids are connected.\n    // Example:\n    \"Print to console\": {\n        \"scope\": \"javascript,typescript\",\n        \"prefix\": \"types\",\n        \"body\": [\n            \"import { type ComponentPublicInstance, type ExtractPropTypes } from 'vue'\",\n            \"\",\n            \"// 定义组件 Props\",\n            \"export const Props = {\",\n            \"$1\",\n            \"}\",\n            \"\",\n            \"// 将 Props 转换为类型\",\n            \"export type Props = ExtractPropTypes<typeof Props>\",\n            \"\",\n            \"// 暴露的组件实例方法和属性\",\n            \"export type Expose = {\",\n            \"\",\n            \"}\",\n            \"// 导出组件实例类型\",\n            \"export type Instance = ComponentPublicInstance<Props, Expose>\"\n        ],\n        \"description\": \"初始化组件types定义\"\n    }\n}\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\r\n\r\nAll notable changes to this project will be documented in this file.\r\n\r\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),\r\nand this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\r\n\r\n## 0.6.0-beta.1 - 2026-05-08\n\n### ✨ Features | 新功能\n\n- **u-upload:** 新增image-shape属性支持圆形和方形展示 ([fac9414](https://github.com/anyup/uView-Pro/commit/fac941413ba4d944116513934306376a0188fcda))\n- **u-upload:** 新增customChoose属性支持自定义文件选择功能 ([97e17ee](https://github.com/anyup/uView-Pro/commit/97e17eeae15c03a7791bb5eec4159782f3d70d84))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.6.0-beta.0 - 2026-04-30\n\n### ✨ Features | 新功能\n\n- **u-upload:** 新增多种上传模式和文件类型支持，支持图片、视频、文档等多种类型，支持网格(grid)和列表(list)两种展示模式 ([f75d34c](https://github.com/anyup/uView-Pro/commit/f75d34c22d551c41e8e873bc5779089ff2b2c0c7))\n- **u-upload:** 新增 v-model 支持并优化文件列表同步逻辑 ([5548d84](https://github.com/anyup/uView-Pro/commit/5548d847b5c442da40775ec06ecfab7f0fddf448))\n- **upload:** 完善上传组件示例页面功能，添加多种上传模式示例：图片上传（网格模式）、文件上传（列表模式）、视频上传 ([d43b3d2](https://github.com/anyup/uView-Pro/commit/d43b3d2c7f0ff7a7fe45467d49d451ca878b7eb1))\n\n### ♻️ Code Refactoring | 代码重构\n\n- **u-divider:** 规范化 slot 标签 ([fccac33](https://github.com/anyup/uView-Pro/commit/fccac33b6adce3395179d5c55b7b8a0a4d25a800))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-upload:** 优化微信小程序平台监听文件列表变化不触发on-list-change事件的场景 ([47fa5c1](https://github.com/anyup/uView-Pro/commit/47fa5c1dfa30214dfc40f7ee01b09f6f95d09b9a))\n- **changelog:** 修复版本标题格式和Unreleased区块处理 ([3a87f47](https://github.com/anyup/uView-Pro/commit/3a87f4739cdebc1aafcb33e3f9b31dd79f9bc3d2))\n\n### 👷 Continuous Integration | CI 配置\n\n- 增强预发布版本支持和发布管理功能 ([86abdaa](https://github.com/anyup/uView-Pro/commit/86abdaad6a618dfa42416138f05baf910f52fba5))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## [0.5.18] - 2026-04-22\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-calendar:** 修复农历数据响应式访问问题 ([0a88b13](https://github.com/anyup/uView-Pro/commit/0a88b13911fc8c47229f5d9cab0fdfc8ade09ecb))\r\n- **mp-weixin:** 修复微信小程序演示示例vue-i18n多语言切换后uni.getLocale()始终获取中文的问题 ([30b811f](https://github.com/anyup/uView-Pro/commit/30b811f85db29165cd150bea380dfe44f94fda79))\r\n- **demo:** 取消底部导航标题配置设置国际化文案 ([7b949ab](https://github.com/anyup/uView-Pro/commit/7b949ab8695fbc3d9db51b96da1b25a1f05c2ed3))\r\n- **demo:** 修复日历组件demo切换逻辑 ([9aa706a](https://github.com/anyup/uView-Pro/commit/9aa706a0e7b564c2bef75d1d6e7a90023dfc1c17))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **u-tabbar:** 底部导航栏支持自定义item宽度配置，优化item平分功能 ([997846f](https://github.com/anyup/uView-Pro/commit/997846fb5f8ba4648e4d0514f0846ce80a217490))\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- update uview pro desc ([ba65d2e](https://github.com/anyup/uView-Pro/commit/ba65d2e34a1e620b595122a81df48a333c97bbcd))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.5.17] - 2026-04-15\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **demo:** 修复topTips组件演示示例在小程序中不弹出的问题，需设置自定义navbar高度 ([0c72d24](https://github.com/anyup/uView-Pro/commit/0c72d24cd77f4ba6b6cb411810fcf5f0bd1d3272))\r\n- **u-table:** 修复表格表头暗黑模式背景色问题 ([c7fd1a5](https://github.com/anyup/uView-Pro/commit/c7fd1a58e87c4efb84ccf737fe9d1e755908ba8f))\r\n- **u-alert-tips:** 修复关闭按钮颜色样式问题 ([94001cf](https://github.com/anyup/uView-Pro/commit/94001cf79a03ea75695e414a7971e7ec39f445b6))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **theme:** 更新主题配置和本地化文本 ([4caa2ed](https://github.com/anyup/uView-Pro/commit/4caa2edf9542f7f2b0a7bb9870585390f0241e80))\r\n- **u-calendar:** 增强日历组件功能，支持多种日历模式：打卡签到、节假日标记、价格日历等场景，支持自定义插槽功能，动态价格显示；支持选中日期，只读模式设置；修复范围选择背景色样式问题 ([7a9250e](https://github.com/anyup/uView-Pro/commit/7a9250eb49f6694286bb0c3dad7bc9780ae95864))\r\n- **u-popup:** 新增inline模式支持，允许弹窗组件直接插入页面内容而非传统弹窗形式 ([2e8890c](https://github.com/anyup/uView-Pro/commit/2e8890ca3c9cacb90739b33cb0e38db7e2bdb473))\r\n- **u-calendar:** 统一日期格式YYYY-MM-DD，确保跨组件日期处理的一致性 ([092cc53](https://github.com/anyup/uView-Pro/commit/092cc5392b64990342c43fcbac9aec1bfa2bf982))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **u-calendar:** 重构日历组件模板，统一页面和弹窗模式的日历组件结构 ([42894b8](https://github.com/anyup/uView-Pro/commit/42894b850f903e2471ca42e02f0379443139838b))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.5.16] - 2026-03-26\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **web:** 浏览器平台添加触摸模拟器支持 ([cf96a73](https://github.com/anyup/uView-Pro/commit/cf96a73e09512291143954401aa7850ac59f1207))\r\n- **u-button:** 新增 large、small 按钮尺寸选项，丰富按钮尺寸规格 ([053d7e8](https://github.com/anyup/uView-Pro/commit/053d7e8ab92af403cdfde36369f38a2aded27288))\r\n- **u-input:** u-input添加size属性，支持small/default/large预设值以及自定义尺寸（#137） ([afed961](https://github.com/anyup/uView-Pro/commit/afed961f65c86bd84a2b02828bb361480c7f95b3))\r\n- **u-textarea:** u-textarea组件新增size属性，支持small/default/large预设值以及自定义数值（#137） ([47296e8](https://github.com/anyup/uView-Pro/commit/47296e8669d419d41959dff01de758a610122d34))\r\n- **u-checkbox:** u-checkbox，u-checkbox-group支持small/default/large预设尺寸配置，优化组件样式（#137） ([e8918e2](https://github.com/anyup/uView-Pro/commit/e8918e28a413d861e05a213d49f9a1b39af17964))\r\n- **u-radio:** u-radio，u-radio-group支持small/default/large预设尺寸配置（#137） ([51af7f8](https://github.com/anyup/uView-Pro/commit/51af7f8f86eed99ee159738e43d5dc2d5c6747c8))\r\n- **u-switch:** u-switch支持small/default/large预设尺寸配置（#137） ([6041d52](https://github.com/anyup/uView-Pro/commit/6041d52338172d40957e3ed7af1dde01aa7de074))\r\n- **u-form:** 新增表单大小配置功能，u-form支持小、中、大三种尺寸设置（#137） ([324adb9](https://github.com/anyup/uView-Pro/commit/324adb99de9dfbb72a0a0c40748c11323d3b9470))\r\n- **u-tag:** 为深色模式标签添加边框样式，保持统一性 ([84d0ad6](https://github.com/anyup/uView-Pro/commit/84d0ad6c805d570e216beaa2dc586687a5aae848))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- 添加调试模式配置并重构日志系统 ([a52a3f7](https://github.com/anyup/uView-Pro/commit/a52a3f7d6be7d8332a67c1d8458f4e65e0a0204e))\r\n- **props:** 移除baseProps公共属性并内联到各组件，修复uni_modules引入方式在微信小程序正式打包运行报错的问题 ([f30f779](https://github.com/anyup/uView-Pro/commit/f30f7792a48679afc3cf705a5eb0b182591fe9b5))\r\n- **form:** 调整表单大小配置位置 ([45ffecd](https://github.com/anyup/uView-Pro/commit/45ffecd3522df85cdaaa62ecb9c33d7839443586))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **useChildren:** 修复组件关系工具子组件ID缓存问题，避免同组件多次调用useChildren时重复注册 ([3a8c659](https://github.com/anyup/uView-Pro/commit/3a8c659ce596b483559cf4b061d0b54d784a902b))\r\n- **u-form:** 修复移除字段时方法不存在的错误 ([58ada99](https://github.com/anyup/uView-Pro/commit/58ada99a8cbd44874eebfd305a4aeb721add8558))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.5.15] - 2026-03-25\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-form:** 修复表单项底部边框默认值逻辑 ([d939fbd](https://github.com/anyup/uView-Pro/commit/d939fbd5df85c266f8a8f5e23ebeca251eee94ec))\r\n- **u-input:** 修复u-input输入框在某些微信小程序平台下，重新获取焦点时会清空输入框的问题 ([cedecfa](https://github.com/anyup/uView-Pro/commit/cedecfa4bf2142046bb512b1d9e87f6c9d77516d))\r\n- **demo:** 优化微信小程序首页u-sticky使用配置 ([cc4e9ac](https://github.com/anyup/uView-Pro/commit/cc4e9ac9f022e7713b2eb2746038a8481729c0b4))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **types:** 添加昵称输入类型支持 ([bd15170](https://github.com/anyup/uView-Pro/commit/bd15170d0ccc76098debb9e37b4acfbe43fef043))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/xaunseus\"><img src=\"https://github.com/xaunseus.png?size=40\" width=\"40\" height=\"40\" alt=\"xaunseus\" title=\"xaunseus\"/></a> \r\n\r\n## [0.5.14] - 2026-03-23\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-toast:** 调整提示框位置和边框样式 ([093e31a](https://github.com/anyup/uView-Pro/commit/093e31a34a26902ced26ac841ddfa738fa796528))\r\n- **u-form:** 修复表单项错误消息样式显示问题 ([462eb6e](https://github.com/anyup/uView-Pro/commit/462eb6e9e3b4d676ac97877327d93705f53400a5))\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- **readme:** 添加快速启动模板链接 ([afce866](https://github.com/anyup/uView-Pro/commit/afce866f0e7e20b97132bebcbaf56f9aafc25c5c))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **u-form-item:** 增加前后图标前缀自定义配置和插槽支持 ([9f32cf7](https://github.com/anyup/uView-Pro/commit/9f32cf7f32e0697ab6771711bc96bc2d8395c597))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.5.13] - 2026-03-17\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **u-tabs:** tabs标签组件添加徽标圆点配置功能 ([4c9fe9b](https://github.com/anyup/uView-Pro/commit/4c9fe9b36ee9f04721f53e177bea08407c5e6d11))\r\n- **u-input:** 优化输入框清除图标显示控制逻辑（#141） ([e08bc10](https://github.com/anyup/uView-Pro/commit/e08bc10ffe81945b09f1afc50e273588b346c9d8))\r\n- **u-textarea:** 优化textarea清空按钮显示逻辑（#141） ([feab6cf](https://github.com/anyup/uView-Pro/commit/feab6cf55c17e655b7a89b9f748ef814b5ff8472))\r\n- **demo:** 优化微信小程序声明显示条件 ([72a5cd2](https://github.com/anyup/uView-Pro/commit/72a5cd2503bf90e99a9b7379703e7dce284896cc))\r\n- **toast:** 调整toast组件配置并添加回调功能 ([e9f697f](https://github.com/anyup/uView-Pro/commit/e9f697f58c6cc207bc4df3c16203565762cb860e))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.5.12] - 2026-03-09\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-tabs:** 延迟初始化tabs组件以确保正确获取尺寸信息，修复在App端滑块偏移问题（#139） ([90f79ff](https://github.com/anyup/uView-Pro/commit/90f79ff8f1e71a2ebc05be7d0318b8107425e09a))\r\n- **u-upload:** 优化u-upload组件在暗黑模式下的显示效果 ([24955ad](https://github.com/anyup/uView-Pro/commit/24955ad947d6edc736c695f9052344a83fa191ae))\r\n- **u-calendar:** 优化日历组件设置为range范围选择时，仅当开始、结束时间选择完成时才可点击确定（#136） ([4dee864](https://github.com/anyup/uView-Pro/commit/4dee864abda5e65a755aaaccbaffc430ca463cdd))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **demo:** 添加H5平台条件编译控制，优化组件描述文案 ([d482223](https://github.com/anyup/uView-Pro/commit/d4822234e1f0e13a6480732350f884d5034368b5))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.5.11] - 2026-03-02\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-table:** 修复table文字换行后导致的行高度不一致，边框线错位的问题 ([b6b9c33](https://github.com/anyup/uView-Pro/commit/b6b9c33d41ac3adc6f6a1eb33edd50a355d267bf))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.5.10] - 2026-02-28\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **useToast:** 修复useToast使用全局弹出时，某场景下弹出失败的问题 ([83b3d7b](https://github.com/anyup/uView-Pro/commit/83b3d7b64995a1801fdf6a33ff2ce0c99ecceaa6))\r\n- **useModal:** 修复useModal使用全局弹出时，某场景下弹出失败的问题 ([43f98ea](https://github.com/anyup/uView-Pro/commit/43f98ea4adda12e28cd1d906c36279f808b3ea32))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.5.9] - 2026-02-26\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **calendar:** minDate / maxDate 纳入校验年月范围 ([249c04f](https://github.com/anyup/uView-Pro/commit/249c04f11e8610df4964f2d24d5fbe580e9236f8))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **calendar:** 日历选择演示页面新增最小/最大日期切换功能 ([dc8aeae](https://github.com/anyup/uView-Pro/commit/dc8aeae5072774d3d1be1318e4f7b4567c9b0385))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/zakicheung\"><img src=\"https://github.com/zakicheung.png?size=40\" width=\"40\" height=\"40\" alt=\"张淇\" title=\"张淇\"/></a> <a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.5.8] - 2026-02-10\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- **deps:** 更新 uni-app 相关依赖包版本到 4.87，修复更新包后运行到 h5 报错问题 ([b00751b](https://github.com/anyup/uView-Pro/commit/b00751b2643bd582f2d1b9472e245d856352d4ed))\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- 添加npm下载量统计徽章 ([63971ee](https://github.com/anyup/uView-Pro/commit/63971eead3365d5efe29166b2252e58904c0306c))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **useToast:** 修复使用useToast全局提示会触发多次监听的问题（#130） ([ae56413](https://github.com/anyup/uView-Pro/commit/ae564132604d27c3d92de2f6ece5eaae75980aaa))\r\n- **useModal:** 修复使用useModal全局弹窗会触发多次监听的问题（#130） ([50da10c](https://github.com/anyup/uView-Pro/commit/50da10c7c19d65885244df5c99634775be088824))\r\n- **u-upload:** 修复u-upload组件中删除确认弹窗的“取消”和“确认”按钮国际化问题（#128） ([e48ab1d](https://github.com/anyup/uView-Pro/commit/e48ab1d23f50c850b1fd85c9b48860bd1d5105b0))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **useToast:** 支持使用useToast页面级弹出时，toast可指定页面ID（#130） ([7d09ffe](https://github.com/anyup/uView-Pro/commit/7d09ffe5f8bbee5a3872dfc716dc7ba013f7e1bc))\r\n- **useModal:** 支持使用useModal页面级弹出时，modal可指定页面ID（#130） ([63af409](https://github.com/anyup/uView-Pro/commit/63af409370f775bac7ceabe98db8b5225491baa8))\r\n- **u-button:** 添加按钮文本属性支持 ([72fda47](https://github.com/anyup/uView-Pro/commit/72fda47673f1b099f12dcd88ca20570d20d3d5bc))\r\n- **router:** 添加路由跳转hooks功能 ([cb5a687](https://github.com/anyup/uView-Pro/commit/cb5a687bd7ec8c863d237f69b5cb486e86016398))\r\n- **demo:** 添加useModal和useToast示例页面 ([f42ca51](https://github.com/anyup/uView-Pro/commit/f42ca51839b1ebd3f02106da0310f4bbbfbb96cf))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.5.7] - 2026-02-06\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-tabs:** 修复u-tabs的scroll-view在不同平台会显示滚动条的问题，统一各平台的滚动条隐藏逻辑 ([6ba904b](https://github.com/anyup/uView-Pro/commit/6ba904b85fdc5be69ab8b430878e16fa74674c64))\r\n- **demo:** 修复演示项目在钉钉小程序调用uni.setTabBarItem报错问题（#125） ([fd4ea39](https://github.com/anyup/uView-Pro/commit/fd4ea3987928039e9dcc3a53dc8bea42fce2b685))\r\n- **u-input,u-field:** 修复输入框绑定值为undefined和null时的显示异常问题 ([4af659f](https://github.com/anyup/uView-Pro/commit/4af659fb365179e3ed7db26a1d8571c327497f7a))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **demo-page:** 所有页面支持小程序分享功能 ([a055904](https://github.com/anyup/uView-Pro/commit/a05590443e898ed076d47a04cb8bfc74c2e73da8))\r\n- **u-card:** u-card添加圆角配置功能并调整默认边框样式 ([e43c939](https://github.com/anyup/uView-Pro/commit/e43c9396a17fe485305e63895a7ea8d6edf1906b))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.5.6] - 2026-02-04\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **vue-tsc:** 修复部分定时器ts类型定义错误问题（#124） ([dada764](https://github.com/anyup/uView-Pro/commit/dada764eaa6ea73402e8fa6d96a783ae2a68715a))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.5.5] - 2026-02-02\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **u-toast:** 新增页面级toast功能并优化loading逻辑 ([4eae5b7](https://github.com/anyup/uView-Pro/commit/4eae5b7ef5d4494c4619bee383e62490994b4317))\r\n- **useModal:** 新增useModal函数式调用API和全局modal功能（#101） ([724edf3](https://github.com/anyup/uView-Pro/commit/724edf3cd69607a6d4e33954f8d2d701f9502ff3))\r\n- **locale:** 新增语言配置的标签字段label和区域设置字段locale ([49ba6cb](https://github.com/anyup/uView-Pro/commit/49ba6cbea6b53712496e465dd40654af7608a02d))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **demo:** 调整demo演示中吸顶组件默认偏移量为200 ([165da80](https://github.com/anyup/uView-Pro/commit/165da80eb9eec54cf1a5fa8511d82e2b3d11fed1))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.5.4] - 2026-01-30\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **types:** 优化组件库类型定义和代码健壮性 ([e83eac8](https://github.com/anyup/uView-Pro/commit/e83eac8192476dea5e2d4e5b8b3c68b7da992673))\r\n- **u-navbar:** 修复状态栏高度获取的条件判断，区分鸿蒙、微信小程序和其他 ([b13d112](https://github.com/anyup/uView-Pro/commit/b13d112be80c46f62bfa343a089f2de70a00f774))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **u-loading:** 增强u-loading的自定义样式功能 ([c9151ce](https://github.com/anyup/uView-Pro/commit/c9151ce4bee44c762bd7970ab280184c730e97b1))\r\n- **u-toast:** 新增函数式调用API和全局toast功能（#101） ([b8c8fbf](https://github.com/anyup/uView-Pro/commit/b8c8fbff70c14fe0a6106794a638e450cecbeddf))\r\n- **components:** 优化组件类型安全 ([02b638f](https://github.com/anyup/uView-Pro/commit/02b638f6e251c9b52e5e3ebb1e40d644d895308a))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **demo:** 移除多余的toast引用 ([67b2677](https://github.com/anyup/uView-Pro/commit/67b26772eb67e9e2b830c95359688b0116395452))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.5.3] - 2026-01-26\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **demo-page:** 移除标签栏外层sticky组件 ([ed49275](https://github.com/anyup/uView-Pro/commit/ed49275bc2962426dc4f9185b4b35f6a994cf383))\r\n\r\n### 👷 Continuous Integration | CI 配置\r\n\r\n- 添加 npm 包测试脚本 ([78c5524](https://github.com/anyup/uView-Pro/commit/78c5524abbbc368949ec58437361c995f5146234))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **locale:** 修复本地运行时locale国际化字段未加载成功的问题 ([10c017a](https://github.com/anyup/uView-Pro/commit/10c017a401232224ca1642274d65f031f74f12f0))\r\n- **u-picker:** 修复u-picker/u-select选择器在亮色/暗黑模式下背景色显示问题 ([072a6cc](https://github.com/anyup/uView-Pro/commit/072a6cc1095b5f17b0c15c3cd2a3d6a75d8a9f08))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.5.2] - 2026-01-23\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **u-checkbox-group:** 重构u-checkbox多选框组件，group支持v-model双向绑定，标准化使用api ([e4a12f1](https://github.com/anyup/uView-Pro/commit/e4a12f1af6a4d8cae18823b42a918052df36b62d))\r\n- **hooks:** 新增防抖和节流hook ([4b09373](https://github.com/anyup/uView-Pro/commit/4b09373c31dc3ab7ded01c6ea0cfdf902642b857))\r\n- **u-search:** 新增adjust-position属性控制键盘弹出时的高度调节 ([3443e7c](https://github.com/anyup/uView-Pro/commit/3443e7cc0d754c10df03134e8bc2c6c977758610))\r\n- **u-tabbar:** 调整u-tabbar凸起图标上边距以优化显示效果 ([d0963be](https://github.com/anyup/uView-Pro/commit/d0963be197079733779719aae43694ae5b47e6bc))\r\n- **u-transition:** 新增transition过渡动画组件 ([28ee2c8](https://github.com/anyup/uView-Pro/commit/28ee2c8b0f74bae722f0fe50e498e3407907d2f6))\r\n- **u-transition:** 添加动画模式切换时的时序控制 ([af4bf0a](https://github.com/anyup/uView-Pro/commit/af4bf0a690128ba16e7660d2ae54c5b93644cfdf))\r\n- **u-text:** 优化按钮模式在block模式下的样式 ([afda81d](https://github.com/anyup/uView-Pro/commit/afda81d0c8fa7b628b81f8368e6bd2983779b7c9))\r\n- **u-radio:** 添加label和value属性支持 ([1b824d7](https://github.com/anyup/uView-Pro/commit/1b824d7867dc7fcc3793d7b5d84cbbbcb512dab0))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-checkbox-group:** 修复全选时，u-checkbox-group多次触发change的问题 ([9f813df](https://github.com/anyup/uView-Pro/commit/9f813dfb8a2b8e178b7347223281e09b039f74b0))\r\n- **u-gap:** 修复 gap 间隔槽传递带单位尺寸无法正确解析的问题 ([cc24efd](https://github.com/anyup/uView-Pro/commit/cc24efd658e510fb9655a189ceaee2647db81528))\r\n- **u-alert-tips:** 修复微信小程序下组件样式和图标配置不生效的问题 ([d74900e](https://github.com/anyup/uView-Pro/commit/d74900e9e8a61a68b8971abc81e440e8449d3576))\r\n- **u-navbar:** 修复获取状态栏高度在某些平台失败的问题 ([b8b288e](https://github.com/anyup/uView-Pro/commit/b8b288e33348b78e03be349c6c123e36511342af))\r\n- **u-toast:** 修复toast提示组件设置prop无效的问题 ([ecd3a0a](https://github.com/anyup/uView-Pro/commit/ecd3a0a23a0ca039fa0abe3a946bfdf1024dd10a))\r\n- **locale:** 修复注册uview-pro组件库时，未传递locale导致初始化语言包失败的问题 ([d716100](https://github.com/anyup/uView-Pro/commit/d7161000fe9e3d222453603d8fa31d29a1b9a9bb))\r\n- **u-field:** 修复u-field在禁用状态下，点击输入框无法触发click事件的问题 ([f47761d](https://github.com/anyup/uView-Pro/commit/f47761d00fe2913f0e611577651a3f4108e060b6))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **demo:** 重构u-checkbox复选框演示示例 ([77fc19b](https://github.com/anyup/uView-Pro/commit/77fc19b6f23f8d776b7a56ef9ac27726da7405a1))\r\n- **demo:** 同步鸿蒙应用功能 ([2ac7050](https://github.com/anyup/uView-Pro/commit/2ac70500004e04bd22442d696e3e869ba33ac355))\r\n- update release scripts ([818f8b9](https://github.com/anyup/uView-Pro/commit/818f8b9cf6a0a22893305f76e4af2b71409cbc12))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.5.1] - 2026-01-15\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **locale:** 统一组件国际化命名空间，以保持命名的一致性并避免与自定义字段时冲突 ([8bd3cc3](https://github.com/anyup/uView-Pro/commit/8bd3cc32b26349da63f5005cb3c29e575c831142))\r\n- **u-form:** 支持label插槽功能 ([f82994f](https://github.com/anyup/uView-Pro/commit/f82994f5500ec4509dff64c05e115afb0465d4a2))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.5.0] - 2026-01-14\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **locale:** 添加组件国际化支持和 use locale hooks ([ff96211](https://github.com/anyup/uView-Pro/commit/ff96211423d27bde350a2ea4b9f1d5a5eb72d604))\r\n- **locale:** 添加中、英文国际化语言字段支持 ([257eb41](https://github.com/anyup/uView-Pro/commit/257eb4143ac39cab4940ab76844d0c3be02b198c))\r\n- **locale:** 所有组件实现组件国际化显示替换 ([ef52ff7](https://github.com/anyup/uView-Pro/commit/ef52ff7669c8cb7389377b8bdd4da681dddbb0a6))\r\n- **locale:** 跟随vue-i18n国际化语言切换功能 ([cccecb0](https://github.com/anyup/uView-Pro/commit/cccecb03763990689e6e66d856cf3588157a61b6))\r\n- **fullScreen:** 优化fullscreen页面配置和实现，支持国际化 ([8518218](https://github.com/anyup/uView-Pro/commit/85182186848fa6443ed74de9af1e3f5cd15fa724))\r\n- **locale:** 新增locale国际化和vue-i18n切换示例页面 ([da79723](https://github.com/anyup/uView-Pro/commit/da797230005ff130ea66c315921e4d8d9fa613c1))\r\n- **demo-page:** 添加支付宝小程序navbar兼容性处理 ([75284a4](https://github.com/anyup/uView-Pro/commit/75284a403b9eb7dee9625279ca5cadd14bba3a63))\r\n- **u-skeleton:** 重构u-skeleton骨架屏组件实现全新设计 ([c39405d](https://github.com/anyup/uView-Pro/commit/c39405dfd8c4e1fe06fd842efde79ebf6706b0d1))\r\n- **u-tabbar:** 重构u-tabbar组件内部结构，增加图标文字间距配置 ([e5655da](https://github.com/anyup/uView-Pro/commit/e5655da55c515a8288b12e37084dfec093da542b))\r\n- **mp-weixin:** 添加小程序全局分享功能 ([e4f8bf5](https://github.com/anyup/uView-Pro/commit/e4f8bf5baae237e8dc443de7c90cd751ef045101))\r\n- **useLocale:** uselocale hooks 支持命名空间功能 ([4d6e8f2](https://github.com/anyup/uView-Pro/commit/4d6e8f26976725cfdf862bd21af3648b864fdc29))\r\n- **u-tabbar:** 优化u-tabbar文本样式渲染优先级 ([7d73861](https://github.com/anyup/uView-Pro/commit/7d73861b4cbe1266bc4cbfff31b45a57d9ed960f))\r\n- **locale:** 初始化多语言时添加 isForce 参数支持强制设置默认语言 ([3309017](https://github.com/anyup/uView-Pro/commit/3309017e6fea3bc00f10efcec9f3ec3f83de9a88))\r\n- **demo:** 优化国际化配置示例并添加多语言支持 ([177b978](https://github.com/anyup/uView-Pro/commit/177b97869f14023daf4bca632093076716b616d6))\r\n- **theme:** 主题配置支持强制初始化功能 ([95c895d](https://github.com/anyup/uView-Pro/commit/95c895d0cfb1df37aa6285b88a2247f83add7361))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.4.13] - 2026-01-06\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **theme:** 主题初始化时支持默认主题设置 ([f2b61f6](https://github.com/anyup/uView-Pro/commit/f2b61f6caa1c285753b2e02f97309aa55bb77cca))\r\n- **theme:** 增强主题系统初始化配置，支持在初始化时设置默认主题和暗黑模式 ([d228d10](https://github.com/anyup/uView-Pro/commit/d228d100baf619799b1dc1c8e289e1e8c9a30699))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-number-box:** 修复 u-number-box 步进器 disabled 时字体不显示问题 ([75b3a74](https://github.com/anyup/uView-Pro/commit/75b3a74e6e763dec1a1ee0d3b4d0a62d646ee389))\r\n- **u-textarea:** 修复u-textarea组件设置props.border='none'无效的问题 ([c5a97ba](https://github.com/anyup/uView-Pro/commit/c5a97ba4c00d226c8c0fd9605660d2654dec9dc2))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **theme:** 调整u-bg-gray-light默认色值，优化演示示例 ([37d6bda](https://github.com/anyup/uView-Pro/commit/37d6bda939f5d7c54aec09960878f236dfa32bb2))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.4.12] - 2026-01-04\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **u-action-sheet:** 优化u-action-sheet组件的类型定义 ([bc5e474](https://github.com/anyup/uView-Pro/commit/bc5e474e7117e20495504ff0e2397a147595033c))\r\n- **zIndex:** 统一组件z-index值配置 ([ae1da98](https://github.com/anyup/uView-Pro/commit/ae1da986d307e5b4855fa32e5b2995fdb7be69e8))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **form:** 修复field实例销毁时没有正常移除问题 ([57bfd3b](https://github.com/anyup/uView-Pro/commit/57bfd3bf9315d74c416869cd5a8c41562231166a))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **u-tabbar:** 新增z-index属性支持自定义层级 ([c75d45f](https://github.com/anyup/uView-Pro/commit/c75d45f45e237453d0248124cdbe5bb797edb117))\r\n- **u-modal:** 增加u-modal基础属性支持和自定义样式功能 ([201231e](https://github.com/anyup/uView-Pro/commit/201231ee2e0c25c605f12f582650b048e83213de))\r\n- **components:** 增加u-pagination和u-picker自定义样式支持 ([eb22265](https://github.com/anyup/uView-Pro/commit/eb222657540179fcf8359133df83da89c10b09b8))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/yoshinosk\"><img src=\"https://github.com/yoshinosk.png?size=40\" width=\"40\" height=\"40\" alt=\"yoshinosk\" title=\"yoshinosk\"/></a> <a href=\"https://github.com/liujiayii\"><img src=\"https://github.com/liujiayii.png?size=40\" width=\"40\" height=\"40\" alt=\"liujiayii\" title=\"liujiayii\"/></a> \r\n\r\n## [0.4.11] - 2025-12-30\r\n\r\n### 📦‍ Build System | 打包构建\r\n\r\n- 添加edgeone.json配置 ([ed7ba7d](https://github.com/anyup/uView-Pro/commit/ed7ba7d94dbfa791264a624a03938dc6ac58c0bb))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **theme:** 修复运行时设置 color 与 theme 主题色不同步问题 ([1dcf56a](https://github.com/anyup/uView-Pro/commit/1dcf56a232f5b046e0dce5eb58ec90fb46ce19d5))\r\n- **u-top-tips:** 修复顶部提示组件zindex显示问题，避免影响其他组件的层级显示 ([91391a8](https://github.com/anyup/uView-Pro/commit/91391a8ca10d505936c0b45488af0a3145cab335))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.4.10] - 2025-12-26\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- **contributors:** 更新贡献者映射配置 ([d496b21](https://github.com/anyup/uView-Pro/commit/d496b21d85bede68fefc9ffd752e31ecde14735a))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-popup:** 修复u-popup设置mode=center，点击遮罩层无法关闭的问题 ([3896019](https://github.com/anyup/uView-Pro/commit/389601965933d9e1dc74d32c370c4e858df86595))\r\n- **u-upload:** 优化u-upload组件在多个平台的样式兼容性 ([bfb60b5](https://github.com/anyup/uView-Pro/commit/bfb60b5c2f431d14425eceed9c9e5c248e7cfa29))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **u-tabbar:** 增强u-tabbar组件能力，支持文字和图标显示隐藏配置功能 ([29f3394](https://github.com/anyup/uView-Pro/commit/29f3394d7e8a5e2a818e397ffe97420855970333))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.4.9] - 2025-12-24\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- **readme:** 修复捐赠页面链接 ([93323ab](https://github.com/anyup/uView-Pro/commit/93323ab414ddc5a4542604928f221a050cbe55c5))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **request:** 增强http请求工具，添加请求超时配置和全局配置合并功能 ([54d4a44](https://github.com/anyup/uView-Pro/commit/54d4a448a82d76889524cc2ad0f8f08b758b73fb))\r\n- **http:** 修改http请求实例和响应拦截器 ([d566496](https://github.com/anyup/uView-Pro/commit/d56649673103b519492033504aa387cd6d037721))\r\n- **source:** 添加静态资源文件 ([346bce6](https://github.com/anyup/uView-Pro/commit/346bce63126c4cb2c9db1f1665568eb11e26be07))\r\n- **pages:** 优化多个页面演示样式，统一布局和暗黑模式 ([da68f17](https://github.com/anyup/uView-Pro/commit/da68f17ddf3018f7f5d53a7eebfb3dc1bad550ab))\r\n- **i18n:** 完善国际化支持文案 ([68accbd](https://github.com/anyup/uView-Pro/commit/68accbd1d864f190e510de380d4ed8d603f8676b))\r\n- **pages:** 更新iconfont图标 ([bafd4af](https://github.com/anyup/uView-Pro/commit/bafd4af26f6d2ca4dbe6e818b31be84f57c787b0))\r\n- **demo-page:** 调整演示页面样式并添加tabbar支持 ([f4c5cfc](https://github.com/anyup/uView-Pro/commit/f4c5cfc70920b50602f226220ded4690279cb331))\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- **harmony:** 添加调试配置并调整harmony兼容版本 ([bd18fd2](https://github.com/anyup/uView-Pro/commit/bd18fd234bf0aec9671663f5b26294b4622bae81))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.4.8] - 2025-12-23\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-avatar:** 修复 ios 微信小程序默认头像不显示问题 ([9e3420f](https://github.com/anyup/uView-Pro/commit/9e3420fb8d0db533ce7fb3a8e83543b43ac0c7a7))\r\n- 修复 u-cell 组件中使用 u-icon 样式在微信小程序不生效问题，修复 u-upload 图片上传失败重试是否显示提示配置不生效问题 ([e591d62](https://github.com/anyup/uView-Pro/commit/e591d62befce95c207ca47158549e6fd97f1e58d))\r\n- **u-cell-item:** 修复图标样式问题并优化组件结构 ([294bf4b](https://github.com/anyup/uView-Pro/commit/294bf4be88fb53a2ccd72fcc8702b09f6d736a30))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **theme:** 修改主题默认为官方内置主题，暗黑模式默认为亮色 ([176b482](https://github.com/anyup/uView-Pro/commit/176b48210209ae362fe30e459e73dff6fc81b53e))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/lime\"><img src=\"https://github.com/lime.png?size=40\" width=\"40\" height=\"40\" alt=\"lime\" title=\"lime\"/></a> \r\n\r\n## [0.4.7] - 2025-12-19\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- 忽略部分文件 ([a8a747f](https://github.com/anyup/uView-Pro/commit/a8a747f97e93ed278a305cd1b2671d2ede5c0fde))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **u-tabbar:** u-tabbar 组件支持 custom-icon 直接配置图标 custom-prefix ([e577c2d](https://github.com/anyup/uView-Pro/commit/e577c2d083cf46db7124b0df46b2848ef9bdbe80))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-icon:** 修复图标组件样式和事件处理问题 ([1cadf27](https://github.com/anyup/uView-Pro/commit/1cadf27f8bd2aec3a11fb1befb9255256a2e3b3a))\r\n- **u-pagination:** 修复分页切换时传递不正确的当前页码值 ([4befe02](https://github.com/anyup/uView-Pro/commit/4befe02c5cbb4e7db6fbf49f04ca68fac0f69a37))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.4.6] - 2025-12-17\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- 添加鸿蒙系统预览说明及二维码 ([7f6199a](https://github.com/anyup/uView-Pro/commit/7f6199a30d5477743c20b27a94711b4605787757))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **u-slider:** 增强滑块组件功能与灵活性，支持设置滑块的整体范围起点(start)和终点(end) ([a20c44b](https://github.com/anyup/uView-Pro/commit/a20c44b0270cffde02afd8738a932b2d6bae49f4))\r\n- **button:** 新增按钮禁用与自定义样式功能演示 ([5f1f482](https://github.com/anyup/uView-Pro/commit/5f1f4823e027dc5ab2e6f49f29fe327c6d4318c6))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **button:** 更新禁用状态下按钮样式优先级 ([b3ff20b](https://github.com/anyup/uView-Pro/commit/b3ff20b59818c8bc8204bb2a489eff42ded7e842))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.4.5] - 2025-12-10\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **u-input:** 为选择类型输入框添加覆盖层以增强交互 ([9b7bac2](https://github.com/anyup/uView-Pro/commit/9b7bac221195d010c31b15915d2927d095bd257f))\r\n- **u-form:** 增强 u-form 深层校验、动态校验表单 ([97d0ccb](https://github.com/anyup/uView-Pro/commit/97d0ccbe03391f63bed81dcfd1af1432f4f7c77d))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-input:** 修复清空图标点击事件冒泡问题 ([8a214ff](https://github.com/anyup/uView-Pro/commit/8a214ffe8e5588395cdc456e600bc8dd0f03a603))\r\n- **style:** 修复除H5环境外主题样式作用域问题 ([c02ba3c](https://github.com/anyup/uView-Pro/commit/c02ba3c1454e709b1fa9de817d77b0f2128b5fc0))\r\n- **u-switch:** 修复开关组件激活颜色默认值的响应式问题 ([3d78647](https://github.com/anyup/uView-Pro/commit/3d78647d75c3201cced2643395ff5dd935d0e7ec))\r\n- **form:** 修复 form 校验报错问题 ([8d6d60d](https://github.com/anyup/uView-Pro/commit/8d6d60d4af4e5653f7b87afc3f208d0e26809505))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/yoshinosk\"><img src=\"https://github.com/yoshinosk.png?size=40\" width=\"40\" height=\"40\" alt=\"yoshinosk\" title=\"yoshinosk\"/></a> \r\n\r\n## [0.4.4] - 2025-12-08\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **u-card:** u-card 组件的默认插槽同 body 插槽 ([ffa13ed](https://github.com/anyup/uView-Pro/commit/ffa13edcf17ff1559e8bdf2260f6b146680f9d07))\r\n- **u-tag:** 优化自定义样式 custom-style 应用，支持 text 插槽内容 ([5bdb733](https://github.com/anyup/uView-Pro/commit/5bdb73346252850d74165cda0bb00766e5f6f59f))\r\n- **u-line-progress:** 优化u-line-progress进度条百分比显示方式 ([1c1d979](https://github.com/anyup/uView-Pro/commit/1c1d97958f3c7e5a28943b46ea25d38b50449364))\r\n- **switch:** 增强开关组件支持自定义值类型 ([2bcb136](https://github.com/anyup/uView-Pro/commit/2bcb1368aa1f3c7fe83799e909b89fc4349b30c3))\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- 优化 Markdown 文档样式和格式 ([c80ff6d](https://github.com/anyup/uView-Pro/commit/c80ff6df269eb92a88001373aa96344ff4cafb79))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/liujiayii\"><img src=\"https://github.com/liujiayii.png?size=40\" width=\"40\" height=\"40\" alt=\"liujiayii\" title=\"liujiayii\"/></a> \r\n\r\n## [0.4.3] - 2025-12-03\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- 更新项目描述和移除冗余信息 ([3d5c105](https://github.com/anyup/uView-Pro/commit/3d5c1053873a1a1dc592e02caf62b5e5f9aba3ad))\r\n- **readme:** 更新交流反馈和捐赠链接 ([266e788](https://github.com/anyup/uView-Pro/commit/266e7883a4e2f3ea8058e0bba0b7ce07a972bad8))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **theme:** 修复不使用 u-config-privider 全局注入时，部分颜色变量不存在的问题 ([cd82d9d](https://github.com/anyup/uView-Pro/commit/cd82d9da3e8fd6066177e3b78b855583e2756a5f))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.4.2] - 2025-12-01\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- **scripts:** 更新发布指定版本说明文档 ([db6bfe8](https://github.com/anyup/uView-Pro/commit/db6bfe8a7ec2812f34738b5b707240cdfe57e8b3))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **theme:** 修复npm方式加载主题包失效的问题 ([7b9c947](https://github.com/anyup/uView-Pro/commit/7b9c947581697ddbd36632919652689ca8595503))\r\n- **dark-mode:** 修复 App 平台暗黑模式跟随系统下，切换系统暗黑模式后不即时生效问题 ([880b181](https://github.com/anyup/uView-Pro/commit/880b18153d186f6f5c5f9c81bf12307bd8f00c22))\r\n- **initTheme:** 优化组件库 install 方法中的主题初始化默认逻辑 ([39e273b](https://github.com/anyup/uView-Pro/commit/39e273b98cd53ec2891c7e68419dd6dfbbeb30c0))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \r\n\r\n## [0.4.1] - 2025-11-30\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **root:** 新增根节点组件支持，优化主题文件 ([12d14f8](https://github.com/anyup/uView-Pro/commit/12d14f8c859bae1e330b246b6eb1f87c2597c2d7))\r\n- **iconfont:** 新增iconfont实例 ([4d34d25](https://github.com/anyup/uView-Pro/commit/4d34d25f0c124a6622b8b38b7501b85586843a42))\r\n- **locales:** 新增locales中英文字段 ([2dbad6d](https://github.com/anyup/uView-Pro/commit/2dbad6d38bc5cd2fbe55aa0998d2264782cb4dfe))\r\n- **markdown-view:** 新增 markdown-view 模块 ([9e21b6a](https://github.com/anyup/uView-Pro/commit/9e21b6af96c17175dd178923ab2f98c595bacb20))\r\n- **u-config-provider:** 新增 u-config-provider 组件用于全局主题管理 ([f44857c](https://github.com/anyup/uView-Pro/commit/f44857c44f0354b9408bc40c8d586ace1ea40538))\r\n- **theme:** 实现自定义多主题，主题切换功能 ([9551d26](https://github.com/anyup/uView-Pro/commit/9551d260451d2c21b7fe9dfab4850a57c5601573))\r\n- **demo:** 新增 demo-page 组件并重构组件演示页面，添加 API 文档展示 ([ecfd77e](https://github.com/anyup/uView-Pro/commit/ecfd77ea3776720e0bbba7f7678896e685adff3a))\r\n- **demo-page:** 优化代码示例组件文档获取方式 ([50738be](https://github.com/anyup/uView-Pro/commit/50738beafa879e3f95831287a1aa7cb560b59c20))\r\n- **theme:** 实现暗黑模式并优化多主题管理 ([38f9346](https://github.com/anyup/uView-Pro/commit/38f93464edf7ba3e6a0d28c025e31cfe27a147bb))\r\n- **u-config-provider:** 完善u-config-provider主题注入和暗黑模式切换 ([726a7f9](https://github.com/anyup/uView-Pro/commit/726a7f96a31c2e6346c9037842963624b22c3f60))\r\n- **demo:** 优化主题切换示例逻辑和样式 ([d69af6a](https://github.com/anyup/uView-Pro/commit/d69af6a82b639d35ce757abccccb9f8f9aae14a5))\r\n- **theme:** 优化主题系统，兼容单主题、多主题配置能力 ([d06cd7f](https://github.com/anyup/uView-Pro/commit/d06cd7f592e5ae4f9dae7f0cd90f173f76cc5e62))\r\n- **theme:** 更新深蓝主题的色彩配置 ([77e8e5c](https://github.com/anyup/uView-Pro/commit/77e8e5c6ca55281253f86dbc5244c807f04324b3))\r\n- **config-provider:** 增加非 H5 平台系统暗黑模式识别 ([2175dc6](https://github.com/anyup/uView-Pro/commit/2175dc6892f7f559507e19c44638f5c57ac13e4a))\r\n- **u-button:** 调整u-button按钮节流默认值为0，优化点击逻辑 ([3fa2593](https://github.com/anyup/uView-Pro/commit/3fa2593dba31c05a97e001fda9cd233306f42a9d))\r\n- **theme:** 优化主题配置中的暗黑模式处理逻辑，按规则自动生成完整暗色方案 ([8246853](https://github.com/anyup/uView-Pro/commit/82468538004c88637b98c9bd2381b0d44aef0d22))\r\n- **system:** 添加系统主题变更监听 ([9c35243](https://github.com/anyup/uView-Pro/commit/9c3524390847d92c7345e8a27c4603afa8d094f4))\r\n- **theme:** 多主题配置兼容单主题 ([79d3223](https://github.com/anyup/uView-Pro/commit/79d3223459a306fb4ba320713ed03a4a6579f563))\r\n- **u-image:** 增强 u-image 组件自定义样式 ([b133c3c](https://github.com/anyup/uView-Pro/commit/b133c3c00f14738eaa0a61eaec19dbe1b5defcfe))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **app:** 添加本地应用资源 ([cd3f020](https://github.com/anyup/uView-Pro/commit/cd3f02074c871772ea0e42fb26336751eeda7c35))\r\n- **theme:** 重构主题配置和颜色处理逻辑 ([31aa36b](https://github.com/anyup/uView-Pro/commit/31aa36b9207144836be7073a804b8c7ebd68fc6b))\r\n- **demo:** 修改演示页面功能及样式，调整演示组件整体样式 ([8760b3c](https://github.com/anyup/uView-Pro/commit/8760b3c82ff129bd1695e384abbc762de6c85cd4))\r\n- **components:** 优化多个组件主题颜色变量使用，兼容多主题和暗黑模式 ([1a2856f](https://github.com/anyup/uView-Pro/commit/1a2856fc98ec3169d29330f9b7470e936d4aa334))\r\n- **demo:** 优化演示示例 Demo 的功能 ([445878b](https://github.com/anyup/uView-Pro/commit/445878b906475f5dd3bcc9b15efd9aac597f0603))\r\n- **demo-page:** 优化demo page展示，主题切换逻辑优化 ([c5ecbaa](https://github.com/anyup/uView-Pro/commit/c5ecbaa437e51cf1bf47f84f0f3bc071f37dd413))\r\n- 更新自定义主题文件 ([cab8be3](https://github.com/anyup/uView-Pro/commit/cab8be38832bca9de1254a06f199e6b3704ee88e))\r\n- **color:** 重构颜色组件以提升可维护性 ([d92a052](https://github.com/anyup/uView-Pro/commit/d92a0526f7bfa51eeb40bb90eb0e7fc8f24fe488))\r\n\r\n### ⚡ Performance Improvements | 性能优化\r\n\r\n- 优化微信小程序代码包体积 ([bf56c99](https://github.com/anyup/uView-Pro/commit/bf56c99515e41d067481cd6498187ed5bd37c193))\r\n\r\n### 💄 Styles | 风格\r\n\r\n- **demo:** 优化演示页面样式 ([ae5de09](https://github.com/anyup/uView-Pro/commit/ae5de091ee1234b4432eb7d2609f77fd5afd27aa))\r\n- **components:** 使用变量替代硬编码的颜色值 ([cf0044e](https://github.com/anyup/uView-Pro/commit/cf0044e3be68daff91b764eb31a75cf3ecad86aa))\r\n- **demo:** 优化替代组件颜色硬编码值，保证主题色和暗黑模式 ([291e92b](https://github.com/anyup/uView-Pro/commit/291e92b07d80532b1620f62ae0ac3f4909bdab6a))\r\n\r\n### 📦‍ Build System | 打包构建\r\n\r\n- 新增颜色替换脚本 ([b160c28](https://github.com/anyup/uView-Pro/commit/b160c28e838a4f27b9bfa2f3ce47e8ad46e807a0))\r\n- 指定 Node.js 版本 ([7147284](https://github.com/anyup/uView-Pro/commit/714728421527bbd5abed02fe4fdf51cdf3c2a583))\r\n- **deps:** 更新 dcloudio uni-app 依赖版本至 4.76 ([f92a348](https://github.com/anyup/uView-Pro/commit/f92a34892369facda3d89add34cfbeddc1872a65))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-tabbar:** 修复 u-tabbar 在鸿蒙应用上高度计算错误的问题 ([cc4bc1a](https://github.com/anyup/uView-Pro/commit/cc4bc1add7ef63f6d9eb519e9ee38414ef3c73eb))\r\n- **clipboard:** 处理未传入可选参数引起的错误 ([1756b53](https://github.com/anyup/uView-Pro/commit/1756b53f8ce2e2a21d288124c257b4729e48d92a))\r\n- **theme:** 修复获取系统设置的theme不正确的问题 ([58b0cbb](https://github.com/anyup/uView-Pro/commit/58b0cbb3aa666d8f127bc88850b66d469cc1b996))\r\n- **install:** 优化 install 方法的错误处理和代码结构 ([7edb867](https://github.com/anyup/uView-Pro/commit/7edb8673b0cdf4238c184a480b91fb73908e6c5c))\r\n\r\n### 👷 Continuous Integration | CI 配置\r\n\r\n- **release:** 支持直接指定版本号发布 ([e4db5f8](https://github.com/anyup/uView-Pro/commit/e4db5f8b349954548ddef37fc02aa5a397cace01))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/lonelyflyer\"><img src=\"https://github.com/lonelyflyer.png?size=40\" width=\"40\" height=\"40\" alt=\"Lonelyflyer\" title=\"Lonelyflyer\"/></a> \r\n\r\n## [0.3.16] - 2025-11-21\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- 更新贡献者信息 ([a6d52dc](https://github.com/anyup/uView-Pro/commit/a6d52dc6db9d56ccdf5c5ad4230e32c716e36241))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **u-waterfall:** 优化瀑布流组件性能和代码结构 ([841c465](https://github.com/anyup/uView-Pro/commit/841c465de4f1a1efc43e05248794b566e0051bd8))\r\n- **pages:** 重构工具和模板页面，优化i18n国际化功能 ([6cfda7f](https://github.com/anyup/uView-Pro/commit/6cfda7f2ecfd6dd60501201d8797fe702b29df4d))\r\n- **u-dropdown:** 删除无用的测试代码 ([7c06f1f](https://github.com/anyup/uView-Pro/commit/7c06f1f3f0d1dcd5ae2bbd3420a4124c5faec004))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **backTop:** 修复回到顶部组件示例无效的问题 ([5a9b736](https://github.com/anyup/uView-Pro/commit/5a9b7366f5916627815488039327669f424dd0ce))\r\n- **u-text:** 修复 u-text 组件单行省略号显示无效的问题 ([041ee36](https://github.com/anyup/uView-Pro/commit/041ee36fb60d5a082fbdde7e9334ae42b386944c))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **u-link:** 添加自定义点击跳转功能 ([8a521f3](https://github.com/anyup/uView-Pro/commit/8a521f36a9f417aa90263cdcf7978ce48d6ed01e))\r\n- **u-tabs:** 增强 u-tabs 组件，支持隐藏 tab 项的功能配置 ([9a58964](https://github.com/anyup/uView-Pro/commit/9a58964061a7d18510624fb4c6d009568bd3974c))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.3.15] - 2025-11-14\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **u-dropdown:** u-dropdown中的u-dropdown-item中新增控制显示隐藏属性 ([e4ee28f](https://github.com/anyup/uView-Pro/commit/e4ee28fd0a66ceb6bbed07b7969862e936e5e573))\r\n- 支持嵌套属性验证(a.b.c格式) ([1bbead8](https://github.com/anyup/uView-Pro/commit/1bbead8be764491844a7d3909480a360ff2dc4d4))\r\n- **form:** 添加表单字段的嵌套校验演示示例 ([73b4abe](https://github.com/anyup/uView-Pro/commit/73b4abe98047ac5193b56b71cdacb05957760e93))\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- 更新应用 logo 和图标 ([38d52e4](https://github.com/anyup/uView-Pro/commit/38d52e4a9e8656bcae89892a5f94a5201a1af7b2))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- 更新 logo 图片地址 ([c0fe3d1](https://github.com/anyup/uView-Pro/commit/c0fe3d15d6f4498229feaba860ff78e43a5297e6))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/xiaozuoovo\"><img src=\"https://github.com/xiaozuoovo.png?size=40\" width=\"40\" height=\"40\" alt=\"XiaoZuoOvO\" title=\"XiaoZuoOvO\"/></a> <a href=\"https://github.com/不爱说话郭德纲\"><img src=\"https://github.com/不爱说话郭德纲.png?size=40\" width=\"40\" height=\"40\" alt=\"不爱说话郭德纲\" title=\"不爱说话郭德纲\"/></a> <a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.3.14] - 2025-11-14\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **app-harmony:** 更新应用信息并添加鸿蒙签名配置，鸿蒙应用打包差异性编译 ([81a33c1](https://github.com/anyup/uView-Pro/commit/81a33c13a471721848033cc5f7ac1e3b3b30abc6))\r\n- **u-message-input:** 新增输入框类型prop，支持number，text等模式 ([68a865a](https://github.com/anyup/uView-Pro/commit/68a865a12b7e0b20db458ea403579d28a227aaeb))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **components:** 优化 u-icon 和 u-toast 组件样式和结构 ([3cfb01d](https://github.com/anyup/uView-Pro/commit/3cfb01ddb8612e274e1bccd43fca0b5bb4e0a405))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.3.13] - 2025-11-11\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-root-portal:** 修复根节点传送组件运行时报错问题 ([3c24a75](https://github.com/anyup/uView-Pro/commit/3c24a75de00982bbdc1388a413721377de4f1e3d))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.3.12] - 2025-11-10\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-dropdown:** 修复下拉菜单激活颜色不正确的问题 ([d3cc1e8](https://github.com/anyup/uView-Pro/commit/d3cc1e87ff0951c5385da5e667a528d30b7fd1cf))\r\n\r\n### 📦‍ Build System | 打包构建\r\n\r\n- **app-harmony:** 新增 HarmonyOS 构建配置 ([c18a537](https://github.com/anyup/uView-Pro/commit/c18a537d9bf4edcbe626290642225363486cfb1e))\r\n- 更新项目版本号 ([8eaee77](https://github.com/anyup/uView-Pro/commit/8eaee7784fb348c5637b55b037f62ba51409a4f2))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.3.10] - 2025-11-06\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **theme:** 优化动态颜色获取方式 ([26f44dd](https://github.com/anyup/uView-Pro/commit/26f44dd0d03b9cb93a2bc6b94ab6eb15a7b2261e))\r\n- **types:** 优化类型导入并修复 u-pagination 类型定义 ([c6cbe61](https://github.com/anyup/uView-Pro/commit/c6cbe61242492ddae896ad44482f130da90033dc))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **u-pagination:** 新增分页组件及演示示例 ([3915064](https://github.com/anyup/uView-Pro/commit/39150648e599e818ce5c3648b3829f30754e2706))\r\n- **u-navbar:** 新增左侧插槽 left ([4474e3b](https://github.com/anyup/uView-Pro/commit/4474e3b07d44126dbbcb85957bf1026c602301e7))\r\n- **u-input:** 新增 focus 发射当前输入值 ([d8082ec](https://github.com/anyup/uView-Pro/commit/d8082ec2d30ae143a2cb223b6a933e5b58e1826b))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **demo:** 修复 u-navbar 演示示例中，因 ref('toast') 和组件名重复问题 ([2bd32a3](https://github.com/anyup/uView-Pro/commit/2bd32a3906fa3dd7ae2a91c8e0382aef7089bba7))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/wjp980108\"><img src=\"https://github.com/wjp980108.png?size=40\" width=\"40\" height=\"40\" alt=\"wjp980108\" title=\"wjp980108\"/></a> <a href=\"https://github.com/wjp\"><img src=\"https://github.com/wjp.png?size=40\" width=\"40\" height=\"40\" alt=\"wjp\" title=\"wjp\"/></a>\r\n\r\n## [0.3.9] - 2025-11-05\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **types:** 修正组件声明文件中uLoadmore的命名大小写问题 ([eb69b18](https://github.com/anyup/uView-Pro/commit/eb69b18d969dac13a75375501018edc4f3097e33))\r\n- **loadmore:** 修复 u-loadmore 组件使用类型声明报错问题 ([92facfd](https://github.com/anyup/uView-Pro/commit/92facfdb5b2b57bcd634d93412c90661c5f6e59d))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **theme:** 新增本地主题文件支持 ([a989314](https://github.com/anyup/uView-Pro/commit/a989314a7b691e94ed81e524100e70d6e9a22a12))\r\n- **theme:** 实现运行时主题变更功能，新增 setTheme 函数 ([12765d0](https://github.com/anyup/uView-Pro/commit/12765d07244a9d6ca49c4dd34d81f66a61c87c6d))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/liujiayii\"><img src=\"https://github.com/liujiayii.png?size=40\" width=\"40\" height=\"40\" alt=\"liujiayii\" title=\"liujiayii\"/></a> <a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.3.8] - 2025-11-04\r\n\r\n### 📦‍ Build System | 打包构建\r\n\r\n- 新增钉钉小程序运行和打包命令 ([a5b4ab3](https://github.com/anyup/uView-Pro/commit/a5b4ab3abab95b4c56bf02415f1785371f7f19ee))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-circle-progress:** 修复微信小程序 canvas 2d 环形进度条绘制问题,适配不同平台的 canvas 上下文 ([e7ab701](https://github.com/anyup/uView-Pro/commit/e7ab701bcbd83e7861aeb9a104269265c6b38a56))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **u-fab:** 新增悬浮按钮组件及演示示例 ([85848de](https://github.com/anyup/uView-Pro/commit/85848de6bae15d91942a633959459ae8e6ecb857))\r\n- **u-fab:** 优化悬浮组件功能和交互，新增预设定位position、拖动吸边autoStick属性 ([65a4bde](https://github.com/anyup/uView-Pro/commit/65a4bde2331c8b2a49933bb4c5d7e1f97a11c56a))\r\n- **u-text:** 新增 u-text 组件默认插槽支持 ([a7b6e59](https://github.com/anyup/uView-Pro/commit/a7b6e5944afbcd48920c25a58c07642544ff3d3e))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **fab:** 优化 fab 组件示例代码 ([ca71fa2](https://github.com/anyup/uView-Pro/commit/ca71fa28fa86baa53384eb366384d97a0b8d84b2))\r\n- **u-fab:** 重构 gap 属性以支持对象类型 ([bee34bf](https://github.com/anyup/uView-Pro/commit/bee34bffd6a7587e9a82fe3e35cc64c096d8d2b3))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/wjp980108\"><img src=\"https://github.com/wjp980108.png?size=40\" width=\"40\" height=\"40\" alt=\"wjp980108\" title=\"wjp980108\"/></a>\r\n\r\n## [0.3.7] - 2025-10-28\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-index-list:** 修复 u-index-list 组件中 indexList 的响应式，确保数据正确对应，滚动到正确的锚点 ([536479b](https://github.com/anyup/uView-Pro/commit/536479b0c444f50892c789191265b373297ec0b5))\r\n- **u-form:** 优化 u-form-item 组件样式，修复微信小程序光标样式偏移问题 ([7e6694b](https://github.com/anyup/uView-Pro/commit/7e6694b5db11f654b081d10bb83d53c99437c730))\r\n- **u-form:** 优化 model 属性的响应式更新，修复 model 对象整体替换导致的表单校验失效问题 ([bc49b5b](https://github.com/anyup/uView-Pro/commit/bc49b5b2fa6f51c803d64252184f5eba93a0d3c1))\r\n- **u-form:** 修复 u-form 的重置表单方法 resetFields 失效问题 ([a31f800](https://github.com/anyup/uView-Pro/commit/a31f800e206fa9671bdd0d6a46ca7a4afba6aefd))\r\n- **u-checkbox:** 修复 u-checkbox 单独使用报错的问题 ([dad2832](https://github.com/anyup/uView-Pro/commit/dad2832a2e7219b0454ec97970c9cb8f4fac0625))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **u-textarea:** 新增 u-textarea 组件及演示示例，增强 textarea 功能，分离 u-input 的 textarea 模式 ([efbb75e](https://github.com/anyup/uView-Pro/commit/efbb75e21a044a664267930396ce496fd64d33fe))\r\n- **u-input:** 增强 u-input 的 textarea 字数统计功能 ([5e14354](https://github.com/anyup/uView-Pro/commit/5e14354a2e34768650cd2417f81b14cdbbced132))\r\n- **u-form:** 增强表单校验功能，发射校验错误，便于自定义提示 ([a553b53](https://github.com/anyup/uView-Pro/commit/a553b53581cc470938030c0f1f8d5f7671d8c25a))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **form:** 优化表单组件的提示文本 ([04b5fc7](https://github.com/anyup/uView-Pro/commit/04b5fc7a071835425786958c5f6de04e233c151c))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.3.6] - 2025-10-24\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **u-select:** 优化选择器组件 u-select 默认值处理逻辑，添加 preserveSelection 属性，用于控制是否保留用户上次确认的选择 ([8493ff1](https://github.com/anyup/uView-Pro/commit/8493ff16d2eee42fabe926917d940a350b86abe0))\r\n- **u-picker:** 优化 picker 的初始化和渲染流程，实现多次打开 picker 时保留用户选择的逻辑，新增 preserveSelection 属性支持 ([974872e](https://github.com/anyup/uView-Pro/commit/974872ec944fbb28cdb3c40fda08c9039bf0b960))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **components:** 使用主题色替代硬编码颜色值，统一组件的颜色风格，便于未来主题颜色的调整和维护 ([ec348d4](https://github.com/anyup/uView-Pro/commit/ec348d4a8bff4dee62da78eadd23fc3a292ebdca))\r\n- **example:** 代码示例中使用主题色替换硬编码颜色值 ([3216497](https://github.com/anyup/uView-Pro/commit/32164973d54cfff3edcbe765a8ed27158f4bec7d))\r\n- **u-steps:** 新增u-step ([6b86eea](https://github.com/anyup/uView-Pro/commit/6b86eeaf7699eb13f739fc038d86efb4e3b48f8a))\r\n- **u-step:** 替换步骤条组件中的默认硬编码颜色值 ([f3408ef](https://github.com/anyup/uView-Pro/commit/f3408ef006991702895432e775f266fb196ddf12))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-picker:** 修复使用u-picker组件选择地区不设置默认值报错的问题 ([7941135](https://github.com/anyup/uView-Pro/commit/7941135a87a3511a562ed10e34573ef7f786fb57))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/lonelyflyer\"><img src=\"https://github.com/lonelyflyer.png?size=40\" width=\"40\" height=\"40\" alt=\"Lonelyflyer\" title=\"Lonelyflyer\"/></a>\r\n\r\n## [0.3.5] - 2025-10-21\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-input:** 修复input组件不支持input事件的问题 ([52d6a6a](https://github.com/anyup/uView-Pro/commit/52d6a6aaeec9ec78e4088234ff7ba056cc10fd9c))\r\n- **u-search:** 修复search组件不支持input事件的问题 ([603b96f](https://github.com/anyup/uView-Pro/commit/603b96f7eeb16d3e54c82b0be7dd03deb930aef5))\r\n- **u-popup:** 修复微信小程序环境下，u-popup 组件 mode=center 时，设置关闭图标位置无效的问题 ([f08197a](https://github.com/anyup/uView-Pro/commit/f08197aafdc3f874b1efcddf6cc6ff9c9edde954))\r\n- **u-line-progress:** type 属性设置后仍被 active-color 内联样式覆盖的问题 ([c6f29f9](https://github.com/anyup/uView-Pro/commit/c6f29f9dc8437035a0e698e869af2fd418d0bd65))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **useChildren:** 添加子组件索引功能 ([8ad744f](https://github.com/anyup/uView-Pro/commit/8ad744fd51df934cc20c099686cbdc5512b22c79))\r\n- **addUnit:** 增强 addUnit 函数支持多值空格分隔 ([6d89cd3](https://github.com/anyup/uView-Pro/commit/6d89cd3c5aacc0770f6f2684fd737d0f05a6e929))\r\n- **u-action-sheet:** 新增自定义 ActionSheet 组件 ([f709523](https://github.com/anyup/uView-Pro/commit/f709523cba5a089eed7c717cc36b9ab199ae24da))\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- 移除issue模板中的提交格式参考 ([83799e8](https://github.com/anyup/uView-Pro/commit/83799e882f69b0e8787a014cfab9f16ab34ba57c))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **u-popup:** 移除弹窗组件中的冗余代码 ([40c5b64](https://github.com/anyup/uView-Pro/commit/40c5b641539fce56af4f9a4ad2440b9240464a89))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/sunjianwei\"><img src=\"https://github.com/sunjianwei.png?size=40\" width=\"40\" height=\"40\" alt=\"sunjianwei\" title=\"sunjianwei\"/></a> <a href=\"https://github.com/koboshi\"><img src=\"https://github.com/koboshi.png?size=40\" width=\"40\" height=\"40\" alt=\"koboshi\" title=\"koboshi\"/></a>\r\n\r\n## [0.3.4] - 2025-10-20\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **components:** 移除不必要的父组件和事件总线相关代码，优化组件间通信 ([280c2f8](https://github.com/anyup/uView-Pro/commit/280c2f8acc75764a7706ec38c742cc16703c941a))\r\n- **u-safe-bottom:** 优化底部安全区组件 ([161f2d3](https://github.com/anyup/uView-Pro/commit/161f2d32ff6b9abbb6f8221a4dd99c438a606e94))\r\n- **u-status-bar:** 优化状态栏组件 ([53c50ab](https://github.com/anyup/uView-Pro/commit/53c50ab8b6314a7d702b90e6b48b79301a334090))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-subsection:** 优化列表和模式变化的监听逻辑，移除不必要的初始化调用 ([f77ee7c](https://github.com/anyup/uView-Pro/commit/f77ee7ccc7521ec2472f72dcf2fb47362ca0abd9))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.3.3] - 2025-10-16\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-read-more:** 修复 init 方法无法在外部调用的问题 ([415d401](https://github.com/anyup/uView-Pro/commit/415d401883a3567653ab1f311b28b075b7bb5603))\r\n- **u-button:** 修复 hover-class 属性被忽略的问题 ([b919c58](https://github.com/anyup/uView-Pro/commit/b919c58cea048f9e559a6448cebe5abbf1490acf))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **component-relation:** 重构组件关系逻辑并添加新功能 ([85d0cd2](https://github.com/anyup/uView-Pro/commit/85d0cd20db839a61733887f82825d47de0a1b1a6))\r\n- **u-talbe:** 重构u-td和u-th组件，增强u-table的兼容性 ([3fbbc52](https://github.com/anyup/uView-Pro/commit/3fbbc5233bd41b91ca829f9a65cf95ee3b599e36))\r\n- 修改 uView Pro 日志配置 ([6b9bb68](https://github.com/anyup/uView-Pro/commit/6b9bb6852af3eb24f109207f864145771c3e9c79))\r\n- **clipboard:** add clipboard function ([efdaa58](https://github.com/anyup/uView-Pro/commit/efdaa58dda923b281d9b764a82a7492f36717ac4))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/koboshi\"><img src=\"https://github.com/koboshi.png?size=40\" width=\"40\" height=\"40\" alt=\"koboshi\" title=\"koboshi\"/></a> <a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/lonelyflyer\"><img src=\"https://github.com/lonelyflyer.png?size=40\" width=\"40\" height=\"40\" alt=\"Lonelyflyer\" title=\"Lonelyflyer\"/></a>\r\n\r\n## [0.3.2] - 2025-10-15\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- **changelog:** 更新 CHANGELOG.md 生成配置 ([27a2609](https://github.com/anyup/uView-Pro/commit/27a26095b92cf8cbc6477c563a68b1557f9fb045))\r\n- 更新交流群图片链接 ([832815d](https://github.com/anyup/uView-Pro/commit/832815deb63f8b144f525591d16e3ccf900b8632))\r\n\r\n### ⚡ Performance Improvements | 性能优化\r\n\r\n- **component-relation:** 增强组件间通信功能；修改 broadcast 方法，支持定向广播；移除对子组件名称的强制要求，允许匿名组件 ([28ea814](https://github.com/anyup/uView-Pro/commit/28ea814810055aa4c99b53d676b16da337fdf7d5))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-index-list:** 重构索引锚点组件，兼容多端，修复IndexList索引列表在微信小程序没有吸顶效果 ([ce6a7a3](https://github.com/anyup/uView-Pro/commit/ce6a7a3c01b622cad268779098390c0d593f75bc))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.3.1] - tag v0.3.1\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.3.1\r\n2025-10-14\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- 更新 package.json 中的平台支持信息 ([c30da7c](https://github.com/anyup/uView-Pro/commit/c30da7cf32c8c97e740df75166d1d7dfa4016942))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **request:** 修复http request请求拦截器中config.header为undefined的问题 ([8da453a](https://github.com/anyup/uView-Pro/commit/8da453afe193338a53c9f320346acabdb8803a79))\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- **release:** bump version to 0.3.1 ([4fc2902](https://github.com/anyup/uView-Pro/commit/4fc29028bdd360833c285857e8c588ad1dfd28f3))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.3.0] - tag v0.3.0\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.3.0\r\n2025-10-12\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- 更新开源捐赠图片 ([8eb0f00](https://github.com/anyup/uView-Pro/commit/8eb0f00ed5308cd1c3574b66dc752b050bbfcb70))\r\n- update readme ([c93cdcb](https://github.com/anyup/uView-Pro/commit/c93cdcb1278040b8c5b6232b0d7928edad22af5d))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **component-relation:** 添加组件关系管理 Hooks 工具，用于完全替换 provide/inject，全平台兼容 ([927be95](https://github.com/anyup/uView-Pro/commit/927be95e8b1c1bd5e05cf91c00888c314f6431e8))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **components:** 重构复选框checkbox和手风琴collapse组件，使用新版组件关系管理工具，优化兼容性 ([a6b2e86](https://github.com/anyup/uView-Pro/commit/a6b2e86394193a1ff5b58df045cba5518b322d38))\r\n- **u-radio:** 修复单选框组件，兼容微信、头条小程序 ([6c409dc](https://github.com/anyup/uView-Pro/commit/6c409dc2c0ed116abcdde23a366c7f575fd56a24))\r\n- **styles:** 优化 u-collapse-item 和 u-text 组件的样式合并逻辑 ([d4436c5](https://github.com/anyup/uView-Pro/commit/d4436c51dc2ddb27d70eeba4cad804504da40013))\r\n- **layout:** 优化布局组件兼容性 ([285b7a7](https://github.com/anyup/uView-Pro/commit/285b7a73fcd9f8a21521be0d7e7a83690495dc4b))\r\n- **u-form:** 重构表单组件的错误处理和样式，增强兼容性，支持多种小程序平台 ([587f87d](https://github.com/anyup/uView-Pro/commit/587f87d1b8d3dd6cd98e583b2640bef61bd8f119))\r\n- **components:** 所有组件允许接受外部样式，允许样式穿透 ([e736e90](https://github.com/anyup/uView-Pro/commit/e736e9014e36c995ba434a56a6ccfee01c56ad35))\r\n- **u-grid:** 重构宫格组件，支持自定义样式 ([d999ece](https://github.com/anyup/uView-Pro/commit/d999eceed2447ddc99a62a6bdcc57deaa1d1b515))\r\n- **component-relation:** 优化子组件挂载时连接父组件的逻辑 ([2d038f2](https://github.com/anyup/uView-Pro/commit/2d038f2721e91db2f1773079341473505f2f6836))\r\n- **u-dropdown:** 重构下拉菜单组件，兼容多平台 ([393caa5](https://github.com/anyup/uView-Pro/commit/393caa57910e9a63484e0c9e852c634fc15ef606))\r\n- **components:** 优化部分组件中的 customStyle 属性及样式处理 ([3506a5a](https://github.com/anyup/uView-Pro/commit/3506a5a055a7a106311351b4b8b90127b019a061))\r\n- **components:** 统一使用 customClass 和 customStyle 属性，统一处理组件样式和类名 ([d400997](https://github.com/anyup/uView-Pro/commit/d40099782b97011edc04c5040342b585b8f18fcd))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-collapse:** 修复手风琴模式和非手风琴模式的处理回调时，index错误的问题 ([a5882eb](https://github.com/anyup/uView-Pro/commit/a5882eb17d87fee4e06448ecc353bf4237f25d52))\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- **release:** bump version to 0.3.0 ([959c6a7](https://github.com/anyup/uView-Pro/commit/959c6a7c191ddeacac5fdf86cf72ddb72fd736a7))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.2.4] - tag v0.2.4\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.2.4\r\n2025-10-08\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **i18n:** 修复切换中英文切换失效问题 ([d61d817](https://github.com/anyup/uView-Pro/commit/d61d81790aecd774435999c9ab8c3672a2df38ad))\r\n- **style:** 修复文本溢出样式u-line-1生成错误问题 ([5d2bf3c](https://github.com/anyup/uView-Pro/commit/5d2bf3ca080f8c5bc9fe40bb1f421c28f7ee8017))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **calendar:** 增加日历组件的页面显示模式 ([af13724](https://github.com/anyup/uView-Pro/commit/af137241e644a5f1e99b07e580c8d3aca9250e9e))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- 优化代码格式和可读性 ([2e338d5](https://github.com/anyup/uView-Pro/commit/2e338d5cb2dbf3ce42f38c9581c04164b852f992))\r\n- **useComponent:** 重构组件事件处理并添加热更新支持 ([80f7e5e](https://github.com/anyup/uView-Pro/commit/80f7e5efaa2b2ab1668969072cb6d18652d00cc2))\r\n- **u-collapse:** 重构 u-collapse 组件中的事件处理逻辑 ([6aadfd1](https://github.com/anyup/uView-Pro/commit/6aadfd16d5aefd45f022c8da1612ba1921942f6e))\r\n- **u-checkbox:** 优化复选框组件的父组件事件处理 ([3b597ea](https://github.com/anyup/uView-Pro/commit/3b597ea2833ca71e5752d097b2f07c143869f0d2))\r\n- **hooks:** 优化 useComponent 以支持页面级别组件关系管理 ([429192f](https://github.com/anyup/uView-Pro/commit/429192f66ba59a26acb957acfc01d5f318d43fb6))\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- 更新微信交流群图片链接 ([e67588a](https://github.com/anyup/uView-Pro/commit/e67588ae392d5150ec4d271ce45e65fe32372460))\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- **release:** bump version to 0.2.4 ([27e1624](https://github.com/anyup/uView-Pro/commit/27e1624619311de1ee10f4dfc0ef5ffbd6210898))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.2.3] - tag v0.2.3\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.2.3\r\n2025-10-06\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-collapse:** 修复手风琴组件在头条小程序的兼容性 ([3189dc4](https://github.com/anyup/uView-Pro/commit/3189dc468edd977bc3e20256bd8a6c1b124bc4e6))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **util:** 新增日志功能并调整主题配置 ([5e07894](https://github.com/anyup/uView-Pro/commit/5e078945fb64867e4e49be1c9228aac7be8c1104))\r\n- **components:** 重构复选框和手风琴组件，新增父子组件通信库 ([55b9b60](https://github.com/anyup/uView-Pro/commit/55b9b6069f1a40a6c4190b27952bcf9a489f8923))\r\n- **util:** 添加自定义事件总线 ([6589f4f](https://github.com/anyup/uView-Pro/commit/6589f4f20b1391a9267670f6622538d4a6db0d82))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **components:** 重构复选框和折叠组件，支持多平台小程序，微信，支付宝，头条 ([0ebc0f5](https://github.com/anyup/uView-Pro/commit/0ebc0f5edcc1df6ccd9baaaf659a0bde7b37d21d))\r\n- **hooks:** 移除组件关系热更新时的错误日志输出 ([c8a2a3d](https://github.com/anyup/uView-Pro/commit/c8a2a3d041a55f94c8bd86d47eaaee9657cbd597))\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- **readme:** 更新微信交流群二维码 ([cff3a3d](https://github.com/anyup/uView-Pro/commit/cff3a3dbb035ca365a1ab9839b14f300ef775c16))\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- **release:** bump version to 0.2.3 ([f125c67](https://github.com/anyup/uView-Pro/commit/f125c67f3e9a6303cfa9a8e8718b66531c923ddb))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.2.2] - tag v0.2.2\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.2.2\r\n2025-09-30\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- 删除未使用的公共 API 和国际化文件 ([e73d3da](https://github.com/anyup/uView-Pro/commit/e73d3da7ede71584ec8b58a386307747b62f5e7a))\r\n- **release:** bump version to 0.2.2 ([c1932fe](https://github.com/anyup/uView-Pro/commit/c1932fe43b224109e49465b2a454c15965587a19))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **components:** 提示组件抽离为全局组件 wx-tips ([3fc0111](https://github.com/anyup/uView-Pro/commit/3fc0111f296de37bdb9b56fdfc023537aa6d79c4))\r\n- **u-collapse:** 优化手风琴模式和样式配置 ([5cff422](https://github.com/anyup/uView-Pro/commit/5cff422a8462403f3c3f23a66f9306a81499a3b0))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **components:** 新增 u-root-portal 根节点传送组件 ([891d021](https://github.com/anyup/uView-Pro/commit/891d021faf76ad0248ef21248d89ff1fe1c5b669))\r\n- **manifest:** 添加支付宝小程序配置 ([cb0b42a](https://github.com/anyup/uView-Pro/commit/cb0b42a9397df1c335d2c5492136efa38dde2ca0))\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- 添加支付宝小程序二维码并更新微信群聊图片 ([1dc0db3](https://github.com/anyup/uView-Pro/commit/1dc0db340e34675f15a7e83c79c3ac5d453853a2))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.2.1] - tag v0.2.1\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.2.1\r\n2025-09-29\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- 优化代码格式化和 ESLint 配置 ([771eacd](https://github.com/anyup/uView-Pro/commit/771eacd58d410e468a8aec4225bbe7b402480b2f))\r\n- **release:** bump version to 0.2.1 ([b835513](https://github.com/anyup/uView-Pro/commit/b8355133aa7bdb57344a662f4968e148f652ffb6))\r\n\r\n### ⚡ Performance Improvements | 性能优化\r\n\r\n- 压缩部分js工具库 ([6615b70](https://github.com/anyup/uView-Pro/commit/6615b7085a51c4fbc9f884ec68e05db1a1e89e27))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **u-calendar:** 日历组件增加农历显示功能 ([e2368ac](https://github.com/anyup/uView-Pro/commit/e2368ac88b0abb4493ab12a1785eb2a0e38e502c))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **calendar:** 重构日历组件类型定义 ([0040e9e](https://github.com/anyup/uView-Pro/commit/0040e9e1095446536370e9aca3c135bc05527acb))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-input:** 修复输入框禁用状态时清空按钮仍显示的问题 ([722715f](https://github.com/anyup/uView-Pro/commit/722715f7d6607584c0e158ba2de2342147e3be17))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.2.0] - tag v0.2.0\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.2.0\r\n2025-09-28\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **example:** 优化 about 页面中的链接处理 ([d04ba8a](https://github.com/anyup/uView-Pro/commit/d04ba8a26278b6a0ea4f5e906bfec89ce6954459))\r\n- **css:** 重构 CSS 样式并添加新样式 ([50b2670](https://github.com/anyup/uView-Pro/commit/50b2670a5e09aff9994a97f60a7d376b5b99a544))\r\n- **libs:** 重构 libs 工具类代码并优化导出方式 ([10a604e](https://github.com/anyup/uView-Pro/commit/10a604e86f8712ee65c658a019c231b56cdcc7e7))\r\n- **u-icon:** 移除 customStyle 属性并整合全局样式 ([cd52e14](https://github.com/anyup/uView-Pro/commit/cd52e14739604f1f126205e16383f187f1d38e8e))\r\n- **props:** 优化 Props 类型定义和样式处理 ([c6ca0de](https://github.com/anyup/uView-Pro/commit/c6ca0de0876cb61671c25e58f33e51674edab266))\r\n- **u-text:** 优化文本组件的样式和布局 ([885a0cf](https://github.com/anyup/uView-Pro/commit/885a0cf3f348184b3546979f1cc1914ded198411))\r\n- **u-text:** 优化文本组件样式和属性 ([315d437](https://github.com/anyup/uView-Pro/commit/315d4379148fddbed059e55e5f9a0d0268345e62))\r\n- **pages:** 优化微信小程序多个页面的用户提示展示，审核相关 ([0f3741f](https://github.com/anyup/uView-Pro/commit/0f3741f65d39f74bc3dc27df8514324e02c3582a))\r\n- **pages:** 添加微信小程序端布局演示提示 ([9eaac70](https://github.com/anyup/uView-Pro/commit/9eaac70cf143327589d56a627160f33c56585d2e))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **components:** 添加 input 组件演示页面 ([91baf00](https://github.com/anyup/uView-Pro/commit/91baf0012e381856b79ca49edb60735928d78099))\r\n- **collapse:** 更新折叠面板组件默认配置和样式 ([a03e0be](https://github.com/anyup/uView-Pro/commit/a03e0be3a9f8ac8b03dbd406d5d8c37227e869bd))\r\n- **components:** 新增 Text 组件 ([a034f9d](https://github.com/anyup/uView-Pro/commit/a034f9d029ab38dbf1a066978f3c62c1328c96a5))\r\n- **hooks:** 重构 useParent 并添加父子组件关系管理 ([37e35d8](https://github.com/anyup/uView-Pro/commit/37e35d84112a08b3d28aa8e5caec12a0a2696594))\r\n- **hooks:** 新增自定义 Hooks 工具库 ([0b3f680](https://github.com/anyup/uView-Pro/commit/0b3f68051b09917fbd39006093291f6dcc4eb0ef))\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- 添加 Copilot 提示词 ([c10cd20](https://github.com/anyup/uView-Pro/commit/c10cd201214907ae2ac8228498927a59f8411cfb))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-collapse:** 重构手风琴组件并解决手风琴失效问题 ([a64e607](https://github.com/anyup/uView-Pro/commit/a64e6075f556ffeb3f5ad6b9ea443e3a22f83a86))\r\n- **u-collapse:** 修复折叠面板内容高度在头条小程序适配 ([5fdcd26](https://github.com/anyup/uView-Pro/commit/5fdcd262ab3e134a97a4f25482d188d93222fddf))\r\n\r\n### 👷 Continuous Integration | CI 配置\r\n\r\n- **vscode:** 设置 Vue 文件默认格式化工具为 Prettier ([84d5259](https://github.com/anyup/uView-Pro/commit/84d52599f2632e814a137e8d553793fb3cdad1f1))\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- **release:** bump version to 0.2.0 ([41a9319](https://github.com/anyup/uView-Pro/commit/41a93199896682b574f78f161b5a63b2268ae89a))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.1.1] - tag v0.1.1\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.1.1\r\n2025-09-22\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **theme:** 重构主题颜色定义和导出 ([a58a477](https://github.com/anyup/uView-Pro/commit/a58a477c8af42e466ed544d7737d84de80f3dc27))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **i18n:** 优化国际化配置并添加安全措施 ([952dd88](https://github.com/anyup/uView-Pro/commit/952dd887dcadeebccb98a25ec066181904ab727e))\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- 简化提交 issue 模板结构 ([c818685](https://github.com/anyup/uView-Pro/commit/c818685383ae400b10d6662e7f4b9ba6be5b31f6))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-input:** 解决u-input组件在微信小程序端，开启clearable属性后，focus会自动清空输入问题 ([283551c](https://github.com/anyup/uView-Pro/commit/283551c54cd7006899a66b97afe7137b4bbb14b1))\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- **release:** bump version to 0.1.1 ([7397b86](https://github.com/anyup/uView-Pro/commit/7397b86aa2670cb8c7a7d094a62a895ec1fb560d))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.1.0] - tag v0.1.0\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.1.0\r\n2025-09-21\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **http:** 优化 HTTP 请求和响应拦截器 ([b9ea27f](https://github.com/anyup/uView-Pro/commit/b9ea27f7a2fc3425316211784a07b2cde030282a))\r\n- 修改路由基础路径 ([23143c8](https://github.com/anyup/uView-Pro/commit/23143c839242fcd19c9c6ca73a8ff1bcfdb8b83b))\r\n- 移除多个组件中未使用的样式标签 ([f8d353a](https://github.com/anyup/uView-Pro/commit/f8d353a0b99b3d9a2530d8d8a4bd8d0d5fe7dcc5))\r\n- 更新项目文档链接和基础配置 ([435a1ea](https://github.com/anyup/uView-Pro/commit/435a1ea5b89f8ba850f3cd469f4583d3946f8142))\r\n\r\n### 📦‍ Build System | 打包构建\r\n\r\n- **vite:** 配置别名和服务器设置 ([b319288](https://github.com/anyup/uView-Pro/commit/b3192882a104963ab6a2c7b6c03e2fb8ee17f609))\r\n- **vite:** 配置别名和服务器设置 ([9483730](https://github.com/anyup/uView-Pro/commit/9483730b371a5722511cd515d20a1eac28834f04))\r\n- 添加修复空 CSS 文件的脚本 ([38b943d](https://github.com/anyup/uView-Pro/commit/38b943d0f1234978e90284fa759f13b604160e96))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **theme:** 支持自定义的color值传入 ([3de798f](https://github.com/anyup/uView-Pro/commit/3de798f8de48af07774376366f5472f463b07177))\r\n\r\n### 💄 Styles | 风格\r\n\r\n- 移除多余空格和换行 ([80df4d4](https://github.com/anyup/uView-Pro/commit/80df4d44b631b12adb1ae45a6dd0dfa69a2694b1))\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- 更新交流群图片 ([3b71cb0](https://github.com/anyup/uView-Pro/commit/3b71cb092efd4c5a89c36ee559028d0fe438a013))\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- **release:** bump version to 0.1.0 ([2b3ef26](https://github.com/anyup/uView-Pro/commit/2b3ef26968f8c87bd3086877315efee8d11183fe))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.0.23] - tag v0.0.23\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.0.23\r\n2025-09-15\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-collapse:** fix accordion mode ([c411fef](https://github.com/anyup/uView-Pro/commit/c411fef340cff07ab06a64f623741e9c1ad125cb))\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- revert comments ([3eed330](https://github.com/anyup/uView-Pro/commit/3eed330c27a7026eb87cb9ef285d1ecbe6789552))\r\n- **docs:** 增加贡献者 ([8b9d44e](https://github.com/anyup/uView-Pro/commit/8b9d44e281c02f639079b77b7c32cc0a566b35a1))\r\n- **docs:** add contributors ([b4035da](https://github.com/anyup/uView-Pro/commit/b4035da5a39acc5ae9dcb13b06143cda6a73fec3))\r\n- **release:** bump version to 0.0.23 ([b230c3f](https://github.com/anyup/uView-Pro/commit/b230c3fb9436bf9ea8c51c20c9c0a0d8cb5bb34a))\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- 更新交流群二维码图片 ([00c0581](https://github.com/anyup/uView-Pro/commit/00c058159ea9d169219474728e8b31cdc892ab2c))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/bin\"><img src=\"https://github.com/bin.png?size=40\" width=\"40\" height=\"40\" alt=\"Bin\" title=\"Bin\"/></a> <a href=\"https://github.com/fuwb\"><img src=\"https://github.com/fuwb.png?size=40\" width=\"40\" height=\"40\" alt=\"fuwb\" title=\"fuwb\"/></a> <a href=\"https://github.com/qianyuanji\"><img src=\"https://github.com/qianyuanji.png?size=40\" width=\"40\" height=\"40\" alt=\"qianyuanji\" title=\"qianyuanji\"/></a> <a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.0.22] - tag v0.0.22\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.0.22\r\n2025-09-11\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- 忽略 pnpm-lock.yaml 文件 ([28802d3](https://github.com/anyup/uView-Pro/commit/28802d308d3c1f2d0d6b583b3b27725b6b40b1a9))\r\n- **release:** bump version to 0.0.22 ([1b30faa](https://github.com/anyup/uView-Pro/commit/1b30faab76518af4799767204abd838a876d9fd0))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **td/th:** fix invalid width setting ([21718fc](https://github.com/anyup/uView-Pro/commit/21718fc3b2f09e1ccf9f1ce8247b78f30e5fe465))\r\n- **u-modal:** 修复在 modal 组件中添加 clearLoading 方法的暴露，以便外部可以调用 ([34b51a7](https://github.com/anyup/uView-Pro/commit/34b51a7187da296b11f4b5db027a86c41a50a477))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **components:** add u-status-bar and u-safe-bottom component ([2085e73](https://github.com/anyup/uView-Pro/commit/2085e73be725f921c436069c27c124e507b24d0e))\r\n- **u-upload:** 调整上传组件默认值和功能 ([4808627](https://github.com/anyup/uView-Pro/commit/48086274f5fe16f4b3b7554a99038a76aa08e8c5))\r\n- **pages:** 在多个页面中添加功能说明的弹窗提示 ([5e59855](https://github.com/anyup/uView-Pro/commit/5e59855ff81f21c54cbfa44a3f4641b4b9f1f6bd))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/bin\"><img src=\"https://github.com/bin.png?size=40\" width=\"40\" height=\"40\" alt=\"Bin\" title=\"Bin\"/></a> <a href=\"https://github.com/lonely-flyer\"><img src=\"https://github.com/lonely-flyer.png?size=40\" width=\"40\" height=\"40\" alt=\"Lonely-flyer\" title=\"Lonely-flyer\"/></a>\r\n\r\n## [0.0.21] - tag v0.0.21\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.0.21\r\n2025-09-09\r\n\r\n### ⚡ Performance Improvements | 性能优化\r\n\r\n- **pages:** options 语法升级为 composition 语法 ([e38878c](https://github.com/anyup/uView-Pro/commit/e38878c696ffc548374169423613e97c3878bafd))\r\n- **pages:** options 语法升级为 composition 语法 ([0403545](https://github.com/anyup/uView-Pro/commit/040354507bd187a9bff4371fc4950dfd6412cd5b))\r\n- **pages:** options 语法升级为 composition 语法 ([514ecb6](https://github.com/anyup/uView-Pro/commit/514ecb6f8e2b133b962a6cbe7609a64e4d973928))\r\n- **pages:** options 语法升级为 composition 语法 ([ffcc1cb](https://github.com/anyup/uView-Pro/commit/ffcc1cb8993196252535ea6553d7fd999ab57719))\r\n- **pages:** options 语法升级为 composition 语法 ([2c755e3](https://github.com/anyup/uView-Pro/commit/2c755e3e1f386c3be1ae8955607d64f72b2b6640))\r\n- 优化首页图标渲染问题 ([a6d4b16](https://github.com/anyup/uView-Pro/commit/a6d4b1690544f3261fb138cb490a10131d4fb749))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-tag:** 修复 u-tag 类型 ([c9071a6](https://github.com/anyup/uView-Pro/commit/c9071a610e08efc4581eff97e4d4998c2d01c9eb))\r\n- **u-table:** 修复 u-table props style 属性变化时，u-th/t-td 未更新问题 ([b1ee7d6](https://github.com/anyup/uView-Pro/commit/b1ee7d6ade7a59e305d7a4081415418387bb6832))\r\n- 修复微信小程序环境下 http interceptor 的路径问题 ([a7fe746](https://github.com/anyup/uView-Pro/commit/a7fe7466b3f66644e097ee6be23f231bce77fa5f))\r\n- 优化checkbox示例页面逻辑 ([9818b20](https://github.com/anyup/uView-Pro/commit/9818b20471e11b96ded606db808f2eda32904f82))\r\n- 修复微信小程序不支持u-circle-progress绘制canvas失败问题 ([46406c5](https://github.com/anyup/uView-Pro/commit/46406c593260f29b081c6a5d98c48dc97e225600))\r\n- 修复 u-picker 组件 params 属性默认值设置 ([36a713b](https://github.com/anyup/uView-Pro/commit/36a713b3c84ddb6e9ef40132512063cdde35ea19))\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- 更新微信交流群图片 ([825b187](https://github.com/anyup/uView-Pro/commit/825b187619ee745a23559bfe0b597b75f90f220d))\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- update project configuration and add prettier support ([9c0cc6a](https://github.com/anyup/uView-Pro/commit/9c0cc6ae3719b975d702b0283bd0c15ee4f3c374))\r\n- **release:** bump version to 0.0.21 ([7bbcbeb](https://github.com/anyup/uView-Pro/commit/7bbcbeb8fa98057e6ff94a9c3233fbc5fc13758d))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **library:** 移除不需要的 globalVariable ([420c40e](https://github.com/anyup/uView-Pro/commit/420c40eac3c67e184924e166edaf4cf2ea904477))\r\n- 更新 pages.json ([03297ce](https://github.com/anyup/uView-Pro/commit/03297ce219ae9337c1a424b9583fa53c74f0291d))\r\n\r\n### 💄 Styles | 风格\r\n\r\n- 格式化代码 ([a9e0a38](https://github.com/anyup/uView-Pro/commit/a9e0a387ffa55df740b828ea4a1463d97089c4bd))\r\n\r\n### 📦‍ Build System | 打包构建\r\n\r\n- mp-alipay 开启 component2 支持 ([430d248](https://github.com/anyup/uView-Pro/commit/430d248ef9e805365dcee0373f6a524bd7084a38))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/bin\"><img src=\"https://github.com/bin.png?size=40\" width=\"40\" height=\"40\" alt=\"Bin\" title=\"Bin\"/></a> <a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.0.20] - tag v0.0.20\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.0.20\r\n2025-09-08\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- 优化http使用示例 ([39d0910](https://github.com/anyup/uView-Pro/commit/39d091056dc1e335625ce884aade35c8bd11ee6f))\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- 更新微信交流群图片 ([21bbec1](https://github.com/anyup/uView-Pro/commit/21bbec14937ee52b225d1f415d90aecbe4d4950f))\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- update project configuration and add prettier support ([74a714d](https://github.com/anyup/uView-Pro/commit/74a714ddc30dc0c2c5a6389f254f1e2c922d905e))\r\n- **release:** bump version to 0.0.20 ([0b94520](https://github.com/anyup/uView-Pro/commit/0b945200d962e584b4c467fdd312e45f944f3f64))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- 修复微信小程序环境下 http interceptor 的路径问题 ([6db4db8](https://github.com/anyup/uView-Pro/commit/6db4db89ef1ab22e3051a6ee944ba44430aa3474))\r\n\r\n### 👷 Continuous Integration | CI 配置\r\n\r\n- update husky pre-commit ([dd04f9a](https://github.com/anyup/uView-Pro/commit/dd04f9a8f2ebdbec37a148e1cf2fa3280c1ab2cd))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.0.19] - tag v0.0.19\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.0.19\r\n2025-09-04\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- include uview-pro changelog.md in release commit ([18d902d](https://github.com/anyup/uView-Pro/commit/18d902db2bba4f8f574d7b3b72be218747525bb9))\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- update uview pro changelog ([31261db](https://github.com/anyup/uView-Pro/commit/31261dbd6b17aea8126a43def1912324b782096e))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- 移除 uni-http 模块 ([5f21735](https://github.com/anyup/uView-Pro/commit/5f2173503cc904fb0a7fa2abd3ed3b9dbe09aeb2))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- 新增http请求模块并实现插件化 ([31c6f88](https://github.com/anyup/uView-Pro/commit/31c6f880d12e586d445faddcc1a3910fda9926bc))\r\n- 增强 toast 工具函数的灵活性 ([2232054](https://github.com/anyup/uView-Pro/commit/22320540acee36c6c11688387431a4ddba93520f))\r\n- 添加 HTTP 请求拦截器和配置示例代码 ([aba7cf9](https://github.com/anyup/uView-Pro/commit/aba7cf97ed2424432da51be1841aa17a5a2d7932))\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- **release:** bump version to 0.0.19 ([ac9f999](https://github.com/anyup/uView-Pro/commit/ac9f9990cab450e14ddcd14681004417a14846ac))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.0.18] - tag v0.0.18\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.0.18\r\n2025-09-03\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- update release script for better version management ([b64f38f](https://github.com/anyup/uView-Pro/commit/b64f38fea28de39c99cdf84f7e767aa7ceac1344))\r\n- **release:** bump version to 0.0.18 ([ba61715](https://github.com/anyup/uView-Pro/commit/ba61715b4288f0c7beba5452f1c00a7dbfa3fb47))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **u-checkbox:** 兼容头条小程序获取父组件数据不支持provide/inject的写法 ([498e12e](https://github.com/anyup/uView-Pro/commit/498e12e2f3aa52021d1be282426536b45f39ca6a))\r\n\r\n### 👷 Continuous Integration | CI 配置\r\n\r\n- optimize changelog generation and spacing ([3103e7b](https://github.com/anyup/uView-Pro/commit/3103e7b56a0e2dd0392efdb6a85824b11ef6800c))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.0.17] - tag v0.0.17\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.0.17\r\n2025-09-02\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **components:** add u-loading-popup component ([6245df9](https://github.com/anyup/uView-Pro/commit/6245df951034b06225ab36d3f18cae8e7ab4b329))\r\n- loading popup component enhance functionality and customization ([82f2aba](https://github.com/anyup/uView-Pro/commit/82f2aba81ead557e6c827cee13c2354fb8c3e16a))\r\n- 添加 Loading 加载弹窗组件的示例页面 ([1bce868](https://github.com/anyup/uView-Pro/commit/1bce86810863012c5a73104ca0a85ebacb4aa92a))\r\n- 更新发布脚本，支持同时更新两个package.json文件的版本号 ([b251b31](https://github.com/anyup/uView-Pro/commit/b251b314d0ef6f64653299460bcf321ec0872e0b))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- 修复瀑布流组件u-waterfll，暴露celar/remove/modify方法 ([240e023](https://github.com/anyup/uView-Pro/commit/240e0238af092d4c6bde86d0db9e49636b806d6f))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- migrate waterfall demo to vue 3 composition api ([93949ad](https://github.com/anyup/uView-Pro/commit/93949ad8ae2a36c6130f87340c222ab9ec69d21f))\r\n- 优化 loading popup 弹窗组件 ([eb0c981](https://github.com/anyup/uView-Pro/commit/eb0c981184a28952004c137f2db4fbc460e72a0f))\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- update docs ([8604485](https://github.com/anyup/uView-Pro/commit/860448594a35814f0f0891ac12b586b7e2b533a4))\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- **release:** bump version to 0.0.17 ([9fcbdd9](https://github.com/anyup/uView-Pro/commit/9fcbdd90a0a1764134c8d33a011223a5dda990be))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.0.15] - tag v0.0.15\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.0.15\r\n2025-08-30\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- update readme docs ([2633c45](https://github.com/anyup/uView-Pro/commit/2633c4504a678802a997e6065292204f3b3fda2a))\r\n- update readme docs ([2fd99d8](https://github.com/anyup/uView-Pro/commit/2fd99d8f6f9531e172e6eeabff513bdb3efcee41))\r\n- update readme ([179c9d3](https://github.com/anyup/uView-Pro/commit/179c9d36f9872b4d69d4792f65cf0e01cca96f85))\r\n- update readme docs ([ed211d7](https://github.com/anyup/uView-Pro/commit/ed211d7cf5cee823e94294506f786d8ce1877d14))\r\n- 更新文档链接 ([58e34d5](https://github.com/anyup/uView-Pro/commit/58e34d50b1bff89ad76132b2b72fe7abe45918ed))\r\n- types/v3-directive not published ([fc93b34](https://github.com/anyup/uView-Pro/commit/fc93b349c326aa29f872d3e337954fc91c9221c9))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- 解决使用u-swipe-action右边会出现一条背景线的bug ([a5b60c6](https://github.com/anyup/uView-Pro/commit/a5b60c6485120e164c0e0c29eea3b765c10f9aac))\r\n- update error text descriptions ([314c394](https://github.com/anyup/uView-Pro/commit/314c3940145c657b12f16d005af7d271f4ae74e3))\r\n- **u-form:** update form validation rules and improve form component ([3912fd6](https://github.com/anyup/uView-Pro/commit/3912fd6ade3a1d612f6f5e86ddc0336376ee5618))\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- **release:** bump version to 0.0.14 ([d1afdf7](https://github.com/anyup/uView-Pro/commit/d1afdf735853eae65cc8676f2182379868ed9c4a))\r\n- **release:** bump version to 0.0.15 ([d5bc854](https://github.com/anyup/uView-Pro/commit/d5bc854a4410104ca1864e35f9a932c7452a196f))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- 优化 u-image 组件 slot 使用体验，兼容头条小程序 ([a6ca54f](https://github.com/anyup/uView-Pro/commit/a6ca54fce06b20b7a6938d0bef9342954b787641))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **form:** migrate form demo to vue 3 composition api ([9d7c7d3](https://github.com/anyup/uView-Pro/commit/9d7c7d3f1bbfeda145bd3de57c65e0eccbcfdde9))\r\n\r\n### 👷 Continuous Integration | CI 配置\r\n\r\n- update changelog script with correct github url ([7761721](https://github.com/anyup/uView-Pro/commit/7761721dbd580de37fa94ac48514aeb4d570bc77))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.0.13] - tag v0.0.13\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.0.13\r\n2025-08-27\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- 修复count-down组件暴露start和end方法 ([0f42a01](https://github.com/anyup/uView-Pro/commit/0f42a01f55aa6799f57eb93dc5d029b06115b154))\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- 更新文档 ([ec8d987](https://github.com/anyup/uView-Pro/commit/ec8d987c840d32729b9d227f6cdcb1005aec4028))\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- **release:** bump version to 0.0.13 ([ea5c4df](https://github.com/anyup/uView-Pro/commit/ea5c4df6b77c4a7004fb0e4a9d538917e1ed4003))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.0.12] - tag v0.0.12\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.0.12\r\n2025-08-27\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- update readme docs ([103114b](https://github.com/anyup/uView-Pro/commit/103114b364add458d7d986fc2bfea2960b71231a))\r\n- update readme docs ([06fd2ac](https://github.com/anyup/uView-Pro/commit/06fd2acbcbd2693bb77cf541f99bbcda41c4547d))\r\n- update readme docs ([db35ab7](https://github.com/anyup/uView-Pro/commit/db35ab7e11daafd28097bae9eb4afeb92556cc83))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- 优化 async-validator 文件多余注释导致的问题 ([f06c80d](https://github.com/anyup/uView-Pro/commit/f06c80d57e61e7b75f1384fe89f309b8a0e379fa))\r\n\r\n### 📦‍ Build System | 打包构建\r\n\r\n- 编译文件 ([212ec8d](https://github.com/anyup/uView-Pro/commit/212ec8d306725cb5e7a7680b399553ddbaff07b4))\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- **release:** bump version to 0.0.12 ([f791252](https://github.com/anyup/uView-Pro/commit/f7912525316f493d925eef34fed01594eb6d7d61))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.0.11] - tag v0.0.11\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.0.11\r\n2025-08-26\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- 修复u-count-down倒计时符号显示逻辑 ([a4c9498](https://github.com/anyup/uView-Pro/commit/a4c94986b020c5ac0fdf92bde3c7b79cdfbedbe8))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- 取消 async-validator ts 检查 ([772a729](https://github.com/anyup/uView-Pro/commit/772a729164f2cb268a886b6749e4a58846ebb3dc))\r\n- 移除u-tr未使用的类型导入和属性定义 ([46ce459](https://github.com/anyup/uView-Pro/commit/46ce4590166a30a0eb048110efc046095a87f6e8))\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- update docs ([541f7bb](https://github.com/anyup/uView-Pro/commit/541f7bbc31a40cc7ce286c2a20b49545b1e823f5))\r\n- 更新 package.json 描述文件 ([e1ced9c](https://github.com/anyup/uView-Pro/commit/e1ced9c412f2cd85d485054946df436b014b726e))\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- **release:** bump version to 0.0.11 ([86f972a](https://github.com/anyup/uView-Pro/commit/86f972ab537120e86acac35441466ca710370b0b))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.0.10] - tag v0.0.10\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.0.10\r\n2025-08-26\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- 完善 select 组件类型定义 ([26af2da](https://github.com/anyup/uView-Pro/commit/26af2da5be7801e35ffbbdd4aebcbfd13e5a44fe))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- 添加 easycom 组件自动扫描 ([b125039](https://github.com/anyup/uView-Pro/commit/b1250390a4f594f5deaa133d7a92bd6e72707890))\r\n- 增强 u-select 组件的类型安全和功能 ([38635e9](https://github.com/anyup/uView-Pro/commit/38635e963f9eff6e4c730692e8c97f10b3a092c5))\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- 更新快速上手指南 ([a863a7a](https://github.com/anyup/uView-Pro/commit/a863a7a1b25a28dbb8318c35986f8e86117475be))\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- **release:** bump version to 0.0.10 ([7914ffb](https://github.com/anyup/uView-Pro/commit/7914ffb5d13ddf192c8d489b85ce7c38804deda4))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.0.9] - tag v0.0.9\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.0.9\r\n2025-08-25\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- 优化全局工具导出方式 ([7a80b6f](https://github.com/anyup/uView-Pro/commit/7a80b6f99ad3022ca995f99f8ec6803af7941eb9))\r\n\r\n### 📦‍ Build System | 打包构建\r\n\r\n- update version to 0.0.9 ([1bb904a](https://github.com/anyup/uView-Pro/commit/1bb904ab28017afb0e7fcad19db422ddfeeb4c3f))\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- update changelog ([48d8e88](https://github.com/anyup/uView-Pro/commit/48d8e88f9e9918542777a77c1098d9c183b7be4d))\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- **release:** bump version to 0.0.9 ([e7cedb3](https://github.com/anyup/uView-Pro/commit/e7cedb37e2b1917f1bb66c43012e4d33662b5ec2))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.0.8] - tag v0.0.8\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.0.8\r\n2025-08-25\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- 重构类型定义types ([466463e](https://github.com/anyup/uView-Pro/commit/466463ea51909210c698d52577b0fccf35091558))\r\n- 重构组件Props属性定义，每个组件具有完善的ts类型定义 ([8cc0de7](https://github.com/anyup/uView-Pro/commit/8cc0de7c1527b48dd223d89207135eea01766294))\r\n- 重构类型定义并统一到全局类型文件global types ([b0fd010](https://github.com/anyup/uView-Pro/commit/b0fd0107289eb1c6df2f58d91b63d9b25902caee))\r\n\r\n### 📦‍ Build System | 打包构建\r\n\r\n- release v0.0.8 ([6f8c240](https://github.com/anyup/uView-Pro/commit/6f8c24044f966fbdc8323e3a29718c45b31005c2))\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- **release:** bump version to 0.0.8 ([168fd72](https://github.com/anyup/uView-Pro/commit/168fd7298f89e886e44d418250297b487b573c93))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.0.7] - tag v0.0.7\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\nRelease version 0.0.7\r\n2025-08-21\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- **README:** 更新文档 ([7b0fcaf](https://github.com/anyup/uView-Pro/commit/7b0fcaf8d940077a3626bf5b4d27ea76281aa4cc))\r\n- 更新项目文档链接 ([a5b2ec1](https://github.com/anyup/uView-Pro/commit/a5b2ec12e932beb483dc7235e255e4ea258eb6e3))\r\n- 更新插件市场下载链接 ([16ecf8d](https://github.com/anyup/uView-Pro/commit/16ecf8d2a8339467f34d2b39779be89b2fb195f5))\r\n- 添加 issue 和 PR 模板以提高项目管理效率 ([fd93594](https://github.com/anyup/uView-Pro/commit/fd93594649bb082ebb031d3835a5bd8db1141347))\r\n- 更新 issue 和 PR 模板 ([b090a23](https://github.com/anyup/uView-Pro/commit/b090a23443103008a88fb708deb3b8600a5dd070))\r\n- 添加 issue 和 PR 模板 ([5b94bff](https://github.com/anyup/uView-Pro/commit/5b94bff012db1f3baa8eec692d423535b9fd431f))\r\n- 删除无用的 issue 模板 ([b85761c](https://github.com/anyup/uView-Pro/commit/b85761ceebe25ef06b275b4497d6cfb10667aca8))\r\n- 更新 README.md 中的徽章 ([4f9e241](https://github.com/anyup/uView-Pro/commit/4f9e241518a19db051bb7d787bca3deddfdd3bdf))\r\n- **README:** 更新项目徽章和文档链接 ([e759065](https://github.com/anyup/uView-Pro/commit/e759065dced747c68ccf4a8258dce1b273aba260))\r\n- **request:** 添加 uni-http 使用说明并实现 hooks 版本 ([00191b3](https://github.com/anyup/uView-Pro/commit/00191b3dd2110cb5a15e170ba0fab0fce41a1f7c))\r\n- **uview-pro:** 更新 readme 文档 ([8d300a8](https://github.com/anyup/uView-Pro/commit/8d300a82a64149d33e76f6a927050a23158856c9))\r\n- 更新 README ([81243c6](https://github.com/anyup/uView-Pro/commit/81243c6d70006202420f0e831d650db458fe043d))\r\n- **uview-pro:** 更新组件功能和优化描述 ([a840a46](https://github.com/anyup/uView-Pro/commit/a840a46cd3d35b8d2a4d287f2a9ca192ff596969))\r\n- **uview-pro:** 更新组件列表和 changelog ([aee4275](https://github.com/anyup/uView-Pro/commit/aee4275641f3e5f97192349587b1b53acc5321e2))\r\n- 更新 SSR 安装指南和 pages.json 配置 ([dcb8b91](https://github.com/anyup/uView-Pro/commit/dcb8b91b45b2fedb02fbfd59f24d8627b38cb600))\r\n- 更新图片链接 ([24484aa](https://github.com/anyup/uView-Pro/commit/24484aae02f4bcc0880b80c2910b264486e9b592))\r\n\r\n### ♻️ Code Refactoring | 代码重构\r\n\r\n- **components:** [icon] 优化 margin 为 space ([e26b5db](https://github.com/anyup/uView-Pro/commit/e26b5dbc1d0d670484744d55bbfeb61a7b33bf6c))\r\n- 更新文档链接为 Netlify 部署地址 ([3b7adfd](https://github.com/anyup/uView-Pro/commit/3b7adfde4d22403123c27f777027884a93ec516b))\r\n- **page-nav:** 重构页面导航栏组件 ([9ae343c](https://github.com/anyup/uView-Pro/commit/9ae343c3fda13599f02528e3c7ee5d75e1c021b6))\r\n- **gitee:** 优化 Gitee Issue 模板并调整页面配置 ([be54720](https://github.com/anyup/uView-Pro/commit/be547205d2c095316d7eb9252be0f4010719d06f))\r\n- **uview-pro:** 重构 md5 函数的默认导出方式 ([75b6d3c](https://github.com/anyup/uView-Pro/commit/75b6d3c8840c922bbb03835ae4899cd28742e129))\r\n- **example:** 重构 components 页面 ([a03c62d](https://github.com/anyup/uView-Pro/commit/a03c62ddd5bb0809f869cb847179549ae2b9cbd2))\r\n- **library:** 重构工具库示例页面 ([49b438e](https://github.com/anyup/uView-Pro/commit/49b438ef141327af01b61d4ef2d1e14387dcd340))\r\n- **components:** 更新多个组件插槽使用方式 ([c38ea5b](https://github.com/anyup/uView-Pro/commit/c38ea5b75e2a63f0bc54e489eaa09449122d6911))\r\n- 优化关于页面布局和内容 ([ad5f6a4](https://github.com/anyup/uView-Pro/commit/ad5f6a47847999268b43b8c5dbf1a34cb8f70802))\r\n- 删除分类数据文件 ([5ed7a11](https://github.com/anyup/uView-Pro/commit/5ed7a1113db58ff493ad606296a210358348affe))\r\n- 重构index list页面 ([13d780e](https://github.com/anyup/uView-Pro/commit/13d780ea5acc4c8eed72062482735df826d4b37a))\r\n- 更新商场菜单组件引用 ([a5f1bf3](https://github.com/anyup/uView-Pro/commit/a5f1bf3f256705d6cad028d60701b4b0544332de))\r\n- 修改图片地址 ([c459893](https://github.com/anyup/uView-Pro/commit/c459893848936aa9a44e7bda3277ab1428109869))\r\n- 重构upload上传组件示例页面 ([686831d](https://github.com/anyup/uView-Pro/commit/686831de357aca67bbf7015e2f0696cf6bf48164))\r\n- 优化多个组件的代码结构和样式 ([f2af44c](https://github.com/anyup/uView-Pro/commit/f2af44ca1710334495e4c4fad99d04027b3788f8))\r\n- 删除不再使用的u-parse组件及相关文件 ([a09bc6d](https://github.com/anyup/uView-Pro/commit/a09bc6d595d5ee8757c97778433488a9c08431ab))\r\n- 优化多个组件的代码结构 ([df66344](https://github.com/anyup/uView-Pro/commit/df663445ae7082e2e6c88ac5d8cead1b757e8fc8))\r\n- 重构 u-avatar-cropper 组件的类型声明文件 ([dc951c9](https://github.com/anyup/uView-Pro/commit/dc951c96346946e651c889dcaa3a7cb198e67116))\r\n- 添加 async-validator 类型声明文件 ([752116b](https://github.com/anyup/uView-Pro/commit/752116b2b723160764579f5c63a13a638dd14240))\r\n\r\n### 📦‍ Build System | 打包构建\r\n\r\n- 修改路由基础路径，去除h5 ([24dbff7](https://github.com/anyup/uView-Pro/commit/24dbff796e577157ac2ec8764d48b476cb6eb2ea))\r\n- 更新版本号versionCode ([3877b67](https://github.com/anyup/uView-Pro/commit/3877b67dd8b9a2a6acb142c9ee7cdfe0bbf31912))\r\n- 更新 android sdk 版本号 ([8885a1d](https://github.com/anyup/uView-Pro/commit/8885a1d2c2d1b165a1930452bb741d3e895c3957))\r\n- version 0.0.5 ([2f97a50](https://github.com/anyup/uView-Pro/commit/2f97a50c9954375257e430d971dd80b2d7234fa6))\r\n- 更新版本号 ([1280508](https://github.com/anyup/uView-Pro/commit/1280508612cfefa8fbf12df0c089886581d24ed5))\r\n- 更新组件库显示名称 ([89f06df](https://github.com/anyup/uView-Pro/commit/89f06df683e76104eab4ba7cf09094cd2930d63f))\r\n- 更新项目依赖并优化打包构建 ([c172d36](https://github.com/anyup/uView-Pro/commit/c172d368d82404564650756a872cd7c7e29ebfa2))\r\n- 更新版本号至 0.0.6 ([04c8bac](https://github.com/anyup/uView-Pro/commit/04c8bace794fd1fe16c53565df2236c96e80a835))\r\n\r\n### ✨ Features | 新功能\r\n\r\n- **example:** 添加页面分享功能 ([0c1a8e2](https://github.com/anyup/uView-Pro/commit/0c1a8e2d05a194791c494a6cb2c1b7c6fe4873a8))\r\n- **components:** 添加 demo-animation 组件 ([aca752b](https://github.com/anyup/uView-Pro/commit/aca752b02d37c8c8382bae65825401f4531f227d))\r\n- **components:** 添加 demo-card 组件 ([60ca440](https://github.com/anyup/uView-Pro/commit/60ca4403df5d7336d3a6bf533aee765dfcfba0a6))\r\n- **example:** 添加 JS 工具库示例页面 ([685ab38](https://github.com/anyup/uView-Pro/commit/685ab38bae80161b9db795069eb9497944fcb746))\r\n- **tabBar:** 添加工具页面并调整 tabBar 列表 ([1f4ba43](https://github.com/anyup/uView-Pro/commit/1f4ba43f9d29a4c8fd6bf12de577ff59933ea312))\r\n- **uview-pro:** 发布 0.0.4 版本 ([5d595d2](https://github.com/anyup/uView-Pro/commit/5d595d281ed957184d3925c5d059224f6cafb9e6))\r\n- 添加提交规范相关配置文件git-cz/husky/changelog ([d93b816](https://github.com/anyup/uView-Pro/commit/d93b816a5a3e468c4bc45e3161d7c006cba5fbf6))\r\n- 优化 deepClone 和 deepMerge 页面的结果展示 ([b0daa70](https://github.com/anyup/uView-Pro/commit/b0daa700b6a385e037d38dc1f10b3612596e2403))\r\n- 新增优惠券模板 ([1b77762](https://github.com/anyup/uView-Pro/commit/1b777621615f7ebe9d83606d53650987c8b2c4e0))\r\n- 更新easycom配置说明，一定要放在custom里，否则不生效 ([fc14bf9](https://github.com/anyup/uView-Pro/commit/fc14bf90cb77088d258e20e79e3d25820f37e97e))\r\n- 添加 u-city-select 城市选择器组件 ([0eb4806](https://github.com/anyup/uView-Pro/commit/0eb4806db3be39e1a6c6f33c9ea511d8445da884))\r\n- 添加模板示例页面 ([3336af4](https://github.com/anyup/uView-Pro/commit/3336af406161648d18578c988d9b3ad79b86059a))\r\n- 新增模版相关页面 ([8925a02](https://github.com/anyup/uView-Pro/commit/8925a02f9fa88f4742d984f2ff02909afc6ad0d7))\r\n- 重构request类，优化泛型支持 ([d7b2e6a](https://github.com/anyup/uView-Pro/commit/d7b2e6a224d96f717e5bdbaf09edb19b712ced47))\r\n- 完善u-button的open-type支持类型 ([37c0db5](https://github.com/anyup/uView-Pro/commit/37c0db527258bca57dbd55d7013b633230489853))\r\n- 添加 uview-pro 组件库的 TypeScript 类型声明 ([e6b2cbf](https://github.com/anyup/uView-Pro/commit/e6b2cbfc8417b0877c8cd1d374e2cd8731ec6bec))\r\n- changelog增加生成指定范围变更日志的功能 ([79c6fd0](https://github.com/anyup/uView-Pro/commit/79c6fd01426ff3b4a83db2b98a8b595805fc9d22))\r\n\r\n### 🐛 Bug Fixes | Bug 修复\r\n\r\n- **components:** update ([b0f7b17](https://github.com/anyup/uView-Pro/commit/b0f7b171916b0c65ed452d04354a5b80f3745e87))\r\n- **upload:** 解决上传组件并添加自定义按钮不生效的问题 ([ae35c0e](https://github.com/anyup/uView-Pro/commit/ae35c0e5517add4ec703ffd6a9a3d0133d17ddb5))\r\n- u-upload 暴露 lists 属性 ([09f8424](https://github.com/anyup/uView-Pro/commit/09f8424774baaee3b6fc7a42458949f8d5903951))\r\n- u-upload深度监听文件列表变化并优化事件触发 ([a41a571](https://github.com/anyup/uView-Pro/commit/a41a5719ddf9d6793b78c55a13025bbdc88fdfe3))\r\n- 修复 notice 组件背景色和键盘组件默认值问题 ([4ef252a](https://github.com/anyup/uView-Pro/commit/4ef252a4f4a093d0899fc3de4ad1b3bfc74277b4))\r\n- 修复中tabbar布局高度计算错误的问题 ([5c1342c](https://github.com/anyup/uView-Pro/commit/5c1342cb3fb6dd2c7c84fe785953fcaed13e809f))\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- 更新 .gitignore 文件 ([8ff834e](https://github.com/anyup/uView-Pro/commit/8ff834ed6d0bceaf9c2c467a1d4a5f63bc06ad19))\r\n- **release:** bump version to 0.0.7 ([6830df1](https://github.com/anyup/uView-Pro/commit/6830df1cde517c063c26c2d5f16f22259b3b2f5d))\r\n\r\n### 💄 Styles | 风格\r\n\r\n- 添加 referrer 策略 meta 标签 ([5f8961a](https://github.com/anyup/uView-Pro/commit/5f8961ab19cd166b06f7d42af204c84ed61f42b9))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/wjp\"><img src=\"https://github.com/wjp.png?size=40\" width=\"40\" height=\"40\" alt=\"wjp\" title=\"wjp\"/></a> <a href=\"https://github.com/chouchouji\"><img src=\"https://github.com/chouchouji.png?size=40\" width=\"40\" height=\"40\" alt=\"chouchouji\" title=\"chouchouji\"/></a> <a href=\"https://github.com/yourname\"><img src=\"https://github.com/yourname.png?size=40\" width=\"40\" height=\"40\" alt=\"Your Name\" title=\"Your Name\"/></a>\r\n\r\n## [0.0.3] - tag v0.0.3\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r\n- 添加插件使用示例工程\r\n- github/gitee/npmjs/插件市场版本同步2025-08-06\r\n\r\n### 📝 Documentation | 文档\r\n\r\n- 添加 uView Pro QQ 交流群链接 ([756befb](https://github.com/anyup/uView-Pro/commit/756befbf5646129f2d6dd4652bc6e5934cbe3a3b))\r\n- 更新 README 中的徽章链接 ([b28b150](https://github.com/anyup/uView-Pro/commit/b28b150614cd8fffff4763ec6cd2ce35a76bb777))\r\n- 调整 README.md 中的徽标位置 ([56aa752](https://github.com/anyup/uView-Pro/commit/56aa7523ac4c7da57eeb7cc024ec2f2e2473ff78))\r\n- **readme:** 更新 uView Pro 项目文档 ([5bf77b5](https://github.com/anyup/uView-Pro/commit/5bf77b50763307f0a9569c0a48bfd996fb876396))\r\n- **README:** 更新项目徽标展示布局 ([650ed2f](https://github.com/anyup/uView-Pro/commit/650ed2f5c5ca4a092d468342bf1e113befd07784))\r\n- 更新 README 中的项目链接 ([335b707](https://github.com/anyup/uView-Pro/commit/335b707a8941a5c4a429f9734a69a2cae951cbfc))\r\n- **README:** 更新安装方式说明 ([c1f95ac](https://github.com/anyup/uView-Pro/commit/c1f95ac6f57aefe069adcdb7ab4bc51edac8aab8))\r\n- 更新官方文档链接 ([7cd7ce9](https://github.com/anyup/uView-Pro/commit/7cd7ce9425987993b3e6a0c89e271d6bffac3a64))\r\n- **uview-pro:** 更新文档链接地址 ([9688d79](https://github.com/anyup/uView-Pro/commit/9688d790af3526f8dcecd08574ab6a7ee7a2a1c6))\r\n- **README:** 更新快速入门指南并优化文档结构 ([d894a5b](https://github.com/anyup/uView-Pro/commit/d894a5b7bfa6944bda7267d5ccc030c58019ce0b))\r\n- **README:** 更新中文和英文版本的 README 文件 ([a9102c1](https://github.com/anyup/uView-Pro/commit/a9102c12672db1cf5df79f385d5f46d4d63c3ca0))\r\n- 更新 README 文件中的 GitHub 链接 ([dc80417](https://github.com/anyup/uView-Pro/commit/dc804176d4a11a79e1fdbaf510935be00f94aebb))\r\n- **readme:** 移除升级指南链接 ([e6417dd](https://github.com/anyup/uView-Pro/commit/e6417dd3078f132c3040ea5a089c1445f82bc27a))\r\n- **README:** 更新文档链接 ([6794352](https://github.com/anyup/uView-Pro/commit/6794352e3a15a568e1fb9a75201fde8cb4a4cf59))\r\n\r\n### 🚀 Chore | 构建/工程依赖/工具\r\n\r\n- 更新 .gitignore 文件 ([b38550b](https://github.com/anyup/uView-Pro/commit/b38550bb0861b04afedfa2e50ffd1fa8435b43b2))\r\n\r\n### 👷 Continuous Integration | CI 配置\r\n\r\n- **uview-pro:** 更新 Vue 版本兼容性并调整文档 ([82c3725](https://github.com/anyup/uView-Pro/commit/82c37255f42a0b7a26bf829552fb0d27f8a38a15))\r\n\r\n### 👥 Contributors\r\n\r\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\r\n\r\n## [0.0.2] - tag v0.0.2\r\n\r\nTagger: anyup <anyupxing@163.com>\r\n\r"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# 贡献指南\n\n感谢您的贡献！为保证代码风格统一，所有提交必须通过 Prettier 格式化校验。\n\n## 代码风格要求\n\n- 仓库已配置 `.prettierrc.js`，请勿修改格式化规则。\n- 所有 JS/TS/Vue/SCSS/MD/JSON 文件必须通过 Prettier 校验。\n- 提交前会自动执行格式化检查，未通过则无法提交。\n\n## 本地开发建议\n\n1. 安装依赖：\n    ```bash\n    npm install\n    ```\n2. 推荐在编辑器安装 Prettier 插件，保存时自动格式化。\n3. 手动格式化：\n    ```bash\n    npm run format\n    ```\n\n## PR 合并要求\n\n- 未通过 Prettier 校验的代码将被拒绝合并。\n- 如遇格式化问题请先修复后再提交。\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2025 uviewpro.cn\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README-pnpm.md",
    "content": "# 使用 pnpm 管理依赖\n\n本项目为 pnpm 依赖管理。\n\n## 常用命令\n\n- 安装依赖：\n    ```bash\n    pnpm install\n    ```\n- 启动开发：\n\n    ```bash\n    # 运行h5\n    pnpm dev:h5\n\n    # 运行微信小程序\n    pnpm dev:mp-weixin\n\n    # 运行安卓APP\n    pnpm dev:app-android\n    ```\n\n- 构建生产包：\n\n    ```bash\n    # 运行h5\n    pnpm build:h5\n\n    # 运行微信小程序\n    pnpm build:mp-weixin\n\n    # 运行安卓APP\n    pnpm build:app-android\n    ```\n\n- 添加依赖：\n    ```bash\n    pnpm add <包名>\n    ```\n- 删除依赖：\n    ```bash\n    pnpm remove <包名>\n    ```\n\n## 说明\n\n- 已自动生成 `pnpm-lock.yaml`，请勿手动修改。\n- 如遇 node_modules 兼容问题，可先删除 node_modules 和 pnpm-lock.yaml 后重新 `pnpm install`。\n- 推荐全员统一使用 pnpm，避免包管理混乱。\n"
  },
  {
    "path": "README.en.md",
    "content": "<!-- Language Switch Button -->\n<p align=\"right\" style=\"margin-top: 10px;\">\n    <span style=\"padding: 6px 16px; background: #ededed; color: #333; border-radius: 6px; margin-left: 8px; font-weight: bold;\">English</span>\n    <a href=\"README.md\" style=\"padding: 6px 16px; background: #2979ff; color: #fff; border-radius: 6px; text-decoration: none; font-weight: bold;\">中文</a>\n</p>\n\n<p align=\"center\">\n    <img alt=\"logo\" src=\"https://ik.imagekit.io/anyup/uview-pro/common/logo-new.png\" width=\"120\" height=\"120\" style=\"margin-bottom: 10px;\">\n</p>\n<h3 align=\"center\" style=\"margin: 30px 0 30px;font-weight: bold;font-size:40px;\">uView Pro</h3>\n<h3 align=\"center\">uni-app Vue3 Multi-platform Rapid Development UI Framework</h3>\n\n<div align=\"center\">\n\n[![star](https://gitee.com/anyup/uView-Pro/badge/star.svg)](https://gitee.com/anyup/uView-Pro)\n[![fork](https://gitee.com/anyup/uView-Pro/badge/fork.svg)](https://gitee.com/anyup/uView-Pro)\n[![stars](https://img.shields.io/github/stars/anyup/uView-Pro?style=flat-square&logo=GitHub)](https://github.com/anyup/uView-Pro)\n[![forks](https://img.shields.io/github/forks/anyup/uView-Pro?style=flat-square&logo=GitHub)](https://github.com/anyup/uView-Pro)\n[![issues](https://img.shields.io/github/issues/anyup/uView-Pro?style=flat-square&logo=GitHub)](https://github.com/anyup/uView-Pro/issues)\n[![downloads](https://img.shields.io/npm/dm/uview-pro?logo=npm&link=https%3A%2F%2Fwww.npmjs.com%2Fpackage%2Fuview-pro&style=flat-square)](https://www.npmjs.com/package/uview-pro)\n[![npm version](https://img.shields.io/npm/v/uview-pro)](https://www.npmjs.com/package/uview-pro)\n[![Website](https://img.shields.io/badge/uView%20Pro-docs-blue?style=flat-square)](https://uviewpro.cn)\n[![node version](https://img.shields.io/badge/node-%3E%3D18-green)](https://nodejs.org/)\n[![pnpm version](https://img.shields.io/badge/pnpm-%3E%3D7.30-green)](https://pnpm.io/)\n[![license](https://img.shields.io/github/license/anyup/uView-Pro?style=flat-square)](https://en.wikipedia.org/wiki/MIT_License)\n\n</div>\n\n## Description\n\nuView UI is an excellent UI framework in the [uni-app](https://uniapp.dcloud.io/) ecosystem, providing comprehensive components and handy tools for efficient development.\n\nuView Pro is a uni-app ecosystem framework that fully supports Vue3.0 and TypeScript. The baseline version of uView Pro is modified based on uView 1.8.8, completely reconstructed using TypeScript, and now fully supports uni-app Vue3.0.\n\n## [Official Documentation: https://uviewpro.cn](https://uviewpro.cn)\n\n## [Quick Start: https://starter.uviewpro.cn](https://starter.uviewpro.cn)\n\n## Features\n\n- Compatible with Android, iOS, WeChat Mini Programs, H5, QQ Mini Programs, Baidu Mini Programs, Alipay Mini Programs, and Toutiao Mini Programs\n- 70+ selected components, rich in functionality, multi-end compatibility, quick integration, and ready to use out of the box\n- Numerous handy JS tools for efficient development\n- A variety of commonly used pages and layouts, allowing you to focus on logic and achieve more with less effort\n- Detailed documentation and modern demo effects\n- On-demand import, streamlined bundle size\n\n## HarmonyOS Preview\n\nThe uView Pro HarmonyOS application has officially been launched in the Huawei App Market, providing you with a complete business scenario demonstration platform. It includes a component library, template samples, scenario cases, and supports one-click copying and downloading to help developers quickly get started and experience the practical value of the components!\n\n> System requirements: Only supported on HarmonyOS 5.0 and above devices\n\n<table>\n    <tr align=\"center\">\n        <td><img src=\"https://ik.imagekit.io/anyup/images/social/qr_harmony.png\" width=\"180\" height=\"180\" ></td>\n    </tr>\n    <tr>\n        <td align=\"center\"><strong>HarmonyOS</strong><br>（Scan with browse）</td>\n    </tr>\n</table>\n\n## Mobile Preview\n\nYou can scan the following QR codes with **WeChat** or **mobile browser** to view the best demo effect.\n\n<table class=\"table\">\n    <tr>\n        <td><img src=\"https://ik.imagekit.io/anyup/images/social/qr_uview_pro_wx.jpg\" width=\"150\" height=\"150\" ></td>\n        <td><img src=\"https://ik.imagekit.io/anyup/images/social/qr_uview_pro_alipay.png\" width=\"150\" height=\"150\" ></td>\n        <td><img src=\"https://ik.imagekit.io/anyup/images/social/qr_uview_pro_h5.png\" width=\"150\" height=\"150\" ></td>\n        <td><img src=\"https://ik.imagekit.io/anyup/images/social/qr_uview_pro_android.png\" width=\"150\" height=\"150\" ></td>\n    </tr>\n    <tr>\n        <td align=\"center\"><strong>WeChat Mini Program</strong><br>(Scan with WeChat)</td>\n        <td align=\"center\"><strong>AliPay Mini Program</strong><br>(Scan with AliPay)</td>\n        <td align=\"center\"><strong>H5</strong><br>(Scan with browser)</td>\n        <td align=\"center\"><strong>Android</strong><br>(Scan with browser)</td>\n    </tr>\n</table>\n\nTo run the sample project, please [download the source code](https://github.com/anyup/uview-pro) and execute the following commands in the project root directory:\n\n```bash\npnpm install\npnpm dev\n```\n\nFor more running and building commands, please refer to the [pnpm Running Guide](README-pnpm.md)\n\n## Links\n\n- [Github](https://github.com/anyup/uview-pro)\n- [Gitee](https://gitee.com/anyup/uview-pro)\n- [Official Documentation](https://uviewpro.cn)\n- [Changelog](https://github.com/anyup/uView-Pro/blob/master/src/uni_modules/uview-pro/changelog.md)\n\n## Communication & Feedback\n\nuView Pro WeChat Group： [Click to Join](https://uviewpro.cn/zh/resource/about.html)\n\nuView Pro QQ Group: [Click to Join](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=98nSVDldWEbDdq4lxiP4aL7uATfMSlI6&authKey=G2yQJ5MQiKzMldaxBsIfKt17NuJuUw8Fr6zdKLggc6NZXgw4BVbqkU2U3EE994yd&noverify=0&group_code=811732166)\n\n<table class=\"table\">\n    <tr>\n        <td><img src=\"https://ik.imagekit.io/anyup/images/social/weixin-chat-cl.png\" width=\"250\" height=\"345\" ></td>\n        <td><img src=\"https://ik.imagekit.io/anyup/images/social/qq-chat.png\" width=\"250\" height=\"345\" ></td>\n    </tr>\n    <tr>\n        <td align=\"center\"><strong>WeChat Group</strong><br></td>\n        <td align=\"center\"><strong>QQ Group</strong><br></td>\n    </tr>\n</table>\n\n## About PR\n\nWe are very happy to accept high-quality PRs from everyone. However, please note that uView Pro needs to be compatible with multiple platforms (Mini Programs, H5, iOS App, Android App), including nvue and vue pages.\n\nTherefore, before you fix bugs and submit PRs, please try your best to test compatibility on these platforms. It would be best to include test screenshots to facilitate review. Thank you very much!\n\n## Installation And Configuration\n\nuView Pro supports both `npm` and `uni_modules` installation methods, and the configuration is highly consistent. No matter which method you use, you can use easycom for automatic component import, greatly improving development efficiency. The following is a unified configuration guide:\n\n### 1. Install uView Pro\n\n- npm installation:\n\n```bash\nnpm install uview-pro\n# or\nyarn add uview-pro\n# or\npnpm add uview-pro\n```\n\n- uni_modules installation:\n\nDownload from HBuilderX plugin market or manually, and place uView Pro in the `uni_modules` directory.\n\n[Plugin Market: https://ext.dcloud.net.cn/plugin?id=24633](https://ext.dcloud.net.cn/plugin?id=24633)\n\n### 2. Import uView Pro main library\n\nImport and register uView Pro in `main.ts`:\n\n```js\n// main.ts\nimport { createSSRApp } from 'vue';\n// npm method\nimport uViewPro from 'uview-pro';\n// uni_modules method\n// import uViewPro from \"@/uni_modules/uview-pro\";\n\nexport function createApp() {\n    const app = createSSRApp(App);\n    app.use(uViewPro);\n    return {\n        app\n    };\n}\n```\n\n### 3. Import global styles\n\nImport theme styles in `uni.scss`:\n\n```scss\n/* uni.scss */\n// npm method\n@import 'uview-pro/theme.scss';\n// uni_modules method\n// @import \"@/uni_modules/uview-pro/theme.scss\";\n```\n\nImport base styles at the top of `App.vue`:\n\n```scss\n<style lang=\"scss\">\n  // npm method\n  @import \"uview-pro/index.scss\";\n  // uni_modules method\n  // @import \"@/uni_modules/uview-pro/index.scss\";\n</style>\n```\n\n### 4. Configure easycom for automatic component import\n\nConfigure easycom rules in `pages.json` for automatic component import:\n\n```json\n// pages.json\n{\n    \"easycom\": {\n        \"autoscan\": true,\n        \"custom\": {\n            // npm method\n            \"^u-(.*)\": \"uview-pro/components/u-$1/u-$1.vue\"\n            // uni_modules method\n            // \"^u-(.*)\": \"@/uni_modules/uview-pro/components/u-$1/u-$1.vue\"\n        }\n    },\n    \"pages\": [\n        // ...\n    ]\n}\n```\n\n**Tips**\n\n-   1. After modifying the `easycom` rules, you need to restart HX or recompile the project.\n-   2. Please ensure there is only one easycom field in `pages.json`, otherwise please merge multiple rules yourself.\n-   3. It must be placed inside `custom`, otherwise it will not take effect.\n\n### 5. Volar Type Support\n\nFor global Volar type support in CLI projects, add the following to `tsconfig.json`:\n\n```json\n{\n    \"compilerOptions\": {\n        // npm method\n        \"types\": [\"uview-pro/types\"]\n        // uni_modules method\n        // \"types\": [\"@/uni_modules/uview-pro/types\"]\n    }\n}\n```\n\n> HBuilderX projects do not support the types configuration in tsconfig.json. CLI projects are recommended to configure for the best TS experience.\n\n### 6. Component Usage\n\nAfter configuration, you can use uView Pro components directly in SFC without import or components registration:\n\n```vue\n<template>\n    <u-button type=\"primary\">Button</u-button>\n</template>\n```\n\nSee [Quick Start](https://uviewpro.cn/zh/components/quickstart.html) for more details.\n\n## Donate to uView Pro\n\nThe documentation and framework source code of uView Pro are developed based on uView UI and are therefore open source and free. If you think uView Pro has helped your development work, you can donate to support uView Pro. There is no threshold for donation, even a cup of cola is appreciated (believe me, this is more meaningful than tipping a streamer).\n\n<table class=\"table\">\n    <tr>\n        <td><img src=\"https://ik.imagekit.io/anyup/images/social/wechat-pay.png\" width=\"250\" height=\"345\" ></td>\n        <td><img src=\"https://ik.imagekit.io/anyup/images/social/ali-pay.png\" width=\"250\" height=\"345\" ></td>\n    </tr>\n    <tr>\n        <td align=\"center\"><strong>WeChat</strong><br></td>\n        <td align=\"center\"><strong>Alipay</strong><br></td>\n    </tr>\n</table>\n\n## Contributors\n\n<a href=\"https://github.com/anyup/uView-Pro/graphs/contributors\">\n  <img alt=\"Contributors\" src=\"https://contrib.rocks/image?repo=anyup/uView-Pro\" />\n</a>\n\n## License\n\nuView Pro follows the [MIT](https://en.wikipedia.org/wiki/MIT_License) open source license, which means you do not need to pay any fees or obtain authorization to use uView Pro in your products.\n\n## Acknowledgements\n\nSpecial thanks to the uView UI development team, all contributors to uView UI, and all contributors to uView Pro.\n\n- [Github](https://github.com/anyup/uview-pro)\n- [Gitee](https://gitee.com/anyup/uview-pro)\n- [uView UI 1.0](https://github.com/umicro/uView)\n- [uView UI 2.0](https://github.com/umicro/uView2.0)\n"
  },
  {
    "path": "README.md",
    "content": "<!-- 语言切换按钮 -->\n<p align=\"right\" style=\"margin-top: 10px;\">\n    <a href=\"README.en.md\" style=\"padding: 6px 16px; background: #2979ff; color: #fff; border-radius: 6px; text-decoration: none; font-weight: bold;\">English</a>\n    <span style=\"padding: 6px 16px; background: #ededed; color: #333; border-radius: 6px; margin-left: 8px; font-weight: bold;\">中文</span>\n</p>\n\n<p align=\"center\">\n    <img alt=\"logo\" src=\"https://ik.imagekit.io/anyup/uview-pro/common/logo-new.png\" width=\"120\" height=\"120\" style=\"margin-bottom: 10px;\">\n</p>\n<h3 align=\"center\" style=\"margin: 30px 0 30px;font-weight: bold;font-size:40px;\">uView Pro</h3>\n<h3 align=\"center\">uni-app Vue3 多平台快速开发的 UI 框架</h3>\n\n<div align=\"center\">\n\n[![star](https://gitee.com/anyup/uView-Pro/badge/star.svg)](https://gitee.com/anyup/uView-Pro)\n[![fork](https://gitee.com/anyup/uView-Pro/badge/fork.svg)](https://gitee.com/anyup/uView-Pro)\n[![stars](https://img.shields.io/github/stars/anyup/uView-Pro?style=flat-square&logo=GitHub)](https://github.com/anyup/uView-Pro)\n[![forks](https://img.shields.io/github/forks/anyup/uView-Pro?style=flat-square&logo=GitHub)](https://github.com/anyup/uView-Pro)\n[![issues](https://img.shields.io/github/issues/anyup/uView-Pro?style=flat-square&logo=GitHub)](https://github.com/anyup/uView-Pro/issues)\n[![downloads](https://img.shields.io/npm/dm/uview-pro?logo=npm&link=https%3A%2F%2Fwww.npmjs.com%2Fpackage%2Fuview-pro&style=flat-square)](https://www.npmjs.com/package/uview-pro)\n[![npm version](https://img.shields.io/npm/v/uview-pro)](https://www.npmjs.com/package/uview-pro)\n[![Website](https://img.shields.io/badge/uView%20Pro-docs-blue?style=flat-square)](https://uviewpro.cn)\n[![node version](https://img.shields.io/badge/node-%3E%3D18-green)](https://nodejs.org/)\n[![pnpm version](https://img.shields.io/badge/pnpm-%3E%3D7.30-green)](https://pnpm.io/)\n[![license](https://img.shields.io/github/license/anyup/uView-Pro?style=flat-square)](https://en.wikipedia.org/wiki/MIT_License)\n\n</div>\n\n## 说明\n\n`uView UI`，是 [uni-app](https://uniapp.dcloud.io/) 生态优秀的 UI 框架，全面的组件和便捷的工具会让您信手拈来，如鱼得水。\n\n`uView Pro`，是全面支持 Vue3.0、TypeScript 的 uni-app 生态框架，uView Pro 的基线版本是基于 uView 1.8.8 修改，使用 TypeScript 完全重构，已覆盖 Android、iOS、鸿蒙以及微信/头条/支付宝等主流小程序平台，真正实现“一套代码，多端运行”，支持多主题系统、暗黑模式与国际化（i18n）。\n\n## [官方文档：https://uviewpro.cn](https://uviewpro.cn)\n\n## [快速启动模板：https://starter.uviewpro.cn](https://starter.uviewpro.cn)\n\n## 特性\n\n- 兼容安卓，iOS，微信小程序，H5，QQ 小程序，百度小程序，支付宝小程序，头条小程序\n- 70+精选组件，功能丰富，多端兼容，让您快速集成，开箱即用\n- 众多贴心的 JS 利器，让您飞镖在手，召之即来，百步穿杨\n- 众多的常用页面和布局，让您专注逻辑，事半功倍\n- 详尽的文档支持，现代化的演示效果\n- 按需引入，精简打包体积\n\n## 鸿蒙预览\n\n🎉🎉 uView Pro 鸿蒙端应用已正式上线华为鸿蒙应用市场，为您提供完整的业务场景演示平台，包含组件库、模板示例、场景案例等，支持一键复制下载，帮助开发者快速上手并体验组件的实际应用价值！\n\n> 系统要求：仅支持 HarmonyOS 5.0 及以上版本设备\n\n<table>\n    <tr align=\"center\">\n        <td><img src=\"https://ik.imagekit.io/anyup/images/social/qr_harmony.png\" width=\"180\" height=\"180\" ></td>\n    </tr>\n    <tr>\n        <td align=\"center\"><strong>鸿蒙应用</strong><br>（浏览器扫码）</td>\n    </tr>\n</table>\n\n## 手机预览\n\n您可以通过**微信**或**手机浏览器**扫描以下二维码，查看最佳的演示效果。\n\n<table class=\"table\">\n    <tr>\n        <td><img src=\"https://ik.imagekit.io/anyup/images/social/qr_uview_pro_wx.jpg\" width=\"150\" height=\"150\" ></td>\n        <td><img src=\"https://ik.imagekit.io/anyup/images/social/qr_uview_pro_alipay.png\" width=\"150\" height=\"150\" ></td>\n        <td><img src=\"https://ik.imagekit.io/anyup/images/social/qr_uview_pro_h5.png\" width=\"150\" height=\"150\" ></td>\n        <td><img src=\"https://ik.imagekit.io/anyup/images/social/qr_uview_pro_android.png\" width=\"150\" height=\"150\" ></td>\n    </tr>\n    <tr>\n        <td align=\"center\"><strong>微信小程序</strong><br>（微信扫码）</td>\n        <td align=\"center\"><strong>支付宝小程序</strong><br>（支付宝扫码）</td>\n        <td align=\"center\"><strong>H5</strong><br>（浏览器扫码）</td>\n        <td align=\"center\"><strong>Android</strong><br>（浏览器扫码）</td>\n    </tr>\n</table>\n\n运行示例工程，请[下载源码](https://github.com/anyup/uview-pro)后，在项目根目录执行以下命令：\n\n```bash\npnpm install\npnpm dev\n```\n\n更多运行和构建命令参考：[pnpm 运行指南](README-pnpm.md)\n\n## 链接\n\n- [Github](https://github.com/anyup/uview-pro)\n- [Gitee](https://gitee.com/anyup/uview-pro)\n- [官方文档](https://uviewpro.cn)\n- [更新日志](https://github.com/anyup/uView-Pro/blob/master/src/uni_modules/uview-pro/changelog.md)\n\n## 交流反馈\n\n`uView Pro` 微信交流群： [点击进入](https://uviewpro.cn/zh/resource/about.html)\n\n`uView Pro` QQ 交流群： [点击进入](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=98nSVDldWEbDdq4lxiP4aL7uATfMSlI6&authKey=G2yQJ5MQiKzMldaxBsIfKt17NuJuUw8Fr6zdKLggc6NZXgw4BVbqkU2U3EE994yd&noverify=0&group_code=811732166)\n\n<table class=\"table\">\n    <tr>\n        <td><img src=\"https://ik.imagekit.io/anyup/images/social/weixin-chat-cl.png\" width=\"250\" height=\"345\" ></td>\n        <td><img src=\"https://ik.imagekit.io/anyup/images/social/qq-chat.png\" width=\"250\" height=\"345\" ></td>\n    </tr>\n    <tr>\n        <td align=\"center\"><strong>微信群</strong><br></td>\n        <td align=\"center\"><strong>QQ群</strong><br></td>\n    </tr>\n</table>\n\n## 关于 PR\n\n我们非常乐意接受各位的优质 PR，但在此之前我希望您了解 `uView Pro` 是一个需要兼容多个平台的（小程序、h5、iOS App、Android App）包括 nvue 页面、vue 页面。\n\n所以希望在您修复 bug 并提交之前尽可能的去这些平台测试一下兼容性。最好能携带测试截图以方便审核。非常感谢！\n\n## 安装配置\n\n`uView Pro` 支持 `npm` 和 `uni_modules` 两种主流安装方式，配置方式高度一致。无论采用哪种方式，均可通过 `easycom` 实现组件自动引入，极大提升开发效率。以下为统一的配置说明：\n\n### 1. 安装 uView Pro\n\n- npm 安装：\n\n```bash\nnpm install uview-pro\n# 或\nyarn add uview-pro\n# 或\npnpm add uview-pro\n```\n\n- uni_modules 安装：\n\n通过 HBuilderX 插件市场或手动下载，将 uView Pro 放入 `uni_modules` 目录。\n\n[插件市场：https://ext.dcloud.net.cn/plugin?id=24633](https://ext.dcloud.net.cn/plugin?id=24633)\n\n### 2. 引入 uView Pro 主库\n\n在 `main.ts` 中引入并注册 uView Pro：\n\n```js\nimport { createSSRApp } from 'vue';\n// npm 方式\nimport uViewPro from 'uview-pro';\n// uni_modules 方式\n// import uViewPro from \"@/uni_modules/uview-pro\";\n\nexport function createApp() {\n    const app = createSSRApp(App);\n    app.use(uViewPro);\n    return {\n        app\n    };\n}\n```\n\n### 3. 引入全局样式\n\n在 `uni.scss` 中引入主题样式：\n\n```scss\n/* npm 方式 */\n@import 'uview-pro/theme.scss';\n/* uni_modules 方式 */\n/* @import \"@/uni_modules/uview-pro/theme.scss\"; */\n```\n\n在 `App.vue` 首行引入基础样式：\n\n```scss\n<style lang=\"scss\">\n  /* npm 方式 */\n  @import \"uview-pro/index.scss\";\n  /* uni_modules 方式 */\n  /* @import \"@/uni_modules/uview-pro/index.scss\"; */\n</style>\n```\n\n### 4. 配置 easycom 自动引入组件\n\n在 `pages.json` 中配置 `easycom` 规则，实现组件自动引入：\n\n```json\n{\n    \"easycom\": {\n        \"autoscan\": true,\n        \"custom\": {\n            // npm 方式\n            \"^u-(.*)\": \"uview-pro/components/u-$1/u-$1.vue\"\n            // uni_modules 方式\n            // \"^u-(.*)\": \"@/uni_modules/uview-pro/components/u-$1/u-$1.vue\"\n        }\n    },\n    \"pages\": []\n}\n```\n\n**温馨提示**\n\n- 1.修改 `easycom` 规则后需重启 HX 或重新编译项目。\n- 2.请确保 `pages.json` 中只有一个 easycom 字段，否则请自行合并多个规则。\n- 3.一定要放在 `custom` 内，否则无效。\n\n### 5. Volar 类型提示支持\n\n如需在 `CLI` 项目中获得 `Volar` 的全局类型提示，请在 `tsconfig.json` 中添加：\n\n```json\n{\n    \"compilerOptions\": {\n        // npm 方式\n        \"types\": [\"uview-pro/types\"]\n        // uni_modules 方式\n        // \"types\": [\"@/uni_modules/uview-pro/types\"]\n    }\n}\n```\n\n> HBuilderX 项目暂不支持 `tsconfig.json` 的 `types` 配置，`CLI` 项目推荐配置以获得最佳 `TS` 体验。\n\n### 6. 组件使用\n\n配置完成后，无需 `import` 和 `components` 注册，可直接在 `SFC` 中使用 `uView Pro` 组件：\n\n```vue\n<template>\n    <u-button type=\"primary\">按钮</u-button>\n</template>\n```\n\n请通过[快速上手](https://uviewpro.cn/zh/components/quickstart.html)了解更详细的内容\n\n## 捐赠 uView Pro\n\n`uView Pro` 文档内容和框架源码基于 `uView UI` 二次开发，因此全部开源免费，如果您认为 `uView Pro` 帮到了您的开发工作，您可以捐赠 `uView Pro` 的研发工作，捐赠无门槛，哪怕是一杯可乐也好(相信这比打赏主播更有意义)。\n\n<table class=\"table\">\n    <tr>\n        <td><img src=\"https://ik.imagekit.io/anyup/images/social/wechat-pay.png\" width=\"250\" height=\"345\" ></td>\n        <td><img src=\"https://ik.imagekit.io/anyup/images/social/ali-pay.png\" width=\"250\" height=\"345\" ></td>\n    </tr>\n    <tr>\n        <td align=\"center\"><strong>微信</strong><br></td>\n        <td align=\"center\"><strong>支付宝</strong><br></td>\n    </tr>\n</table>\n\n## 贡献者\n\n<a href=\"https://github.com/anyup/uView-Pro/graphs/contributors\">\n  <img alt=\"Contributors\" src=\"https://contrib.rocks/image?repo=anyup/uView-Pro\" />\n</a>\n\n## 版权信息\n\n`uView Pro` 遵循[MIT](https://en.wikipedia.org/wiki/MIT_License)开源协议，意味着您无需支付任何费用，也无需授权，即可将 `uView Pro` 应用到您的产品中。\n\n## 鸣谢\n\n再次感谢 `uView UI` 开发团队，以及所有为 `uView UI` 的贡献者，以及所有为 `uView Pro` 的贡献者。\n\n- [Github](https://github.com/anyup/uview-pro)\n- [Gitee](https://gitee.com/anyup/uview-pro)\n- [uView UI 1.0](https://github.com/umicro/uView)\n- [uView UI 2.0](https://github.com/umicro/uView2.0)\n"
  },
  {
    "path": "commitlint.config.js",
    "content": "module.exports = {\n    extends: ['@commitlint/config-conventional'],\n    rules: {\n        'type-enum': [\n            2,\n            'always',\n            ['feat', 'fix', 'docs', 'style', 'refactor', 'perf', 'test', 'build', 'ci', 'chore', 'revert']\n        ],\n        'type-case': [2, 'always', 'lowerCase'],\n        'type-empty': [2, 'never'],\n        'subject-case': [2, 'always', 'lowerCase'],\n        'subject-empty': [2, 'never'],\n        'subject-full-stop': [2, 'never', '.'],\n        'header-max-length': [2, 'always', 100]\n    }\n};\n"
  },
  {
    "path": "edgeone.json",
    "content": "{\n    \"nodeVersion\": \"20.18.0\"\n}\n"
  },
  {
    "path": "harmony-configs/build-profile.json5",
    "content": "{\n    app: {\n        signingConfigs: [\n            {\n                name: 'default',\n                type: 'HarmonyOS',\n                material: {\n                    certpath: 'D:/workspace/anyup/uView-Pro/docs/uviewpro.cer',\n                    keyAlias: 'uviewpro',\n                    keyPassword: '0000001E03BC9F744DDA1E65DB718ABE646E0C96802C4E604F7BB8E641FE1E6C0BB5F6CF2CC8F93E9DD5970C60D9',\n                    profile: 'D:/workspace/anyup/uView-Pro/docs/uviewpro_prodRelease.p7b',\n                    signAlg: 'SHA256withECDSA',\n                    storeFile: 'D:/workspace/anyup/uView-Pro/docs/uviewpro.p12',\n                    storePassword: '0000001EC410E2814F8ECF2C93D41DBCA86EF1381EBB4F9244F19A773307924FD9277EDD4D41DFDCE9D7E5D64F0A'\n                }\n            },\n            {\n                name: 'release',\n                type: 'HarmonyOS',\n                material: {\n                    storeFile: 'D:/workspace/anyup/uView-Pro/docs/uviewpro.p12',\n                    storePassword: '0000001E30C002F824A24AAE774D27FD6C08E3A1C204051D8AE3B98CD212AAB3063E2E585F3E8DA111351F1C45E9',\n                    keyAlias: 'uviewpro',\n                    keyPassword: '0000001E22D0A4589545854C7766D101B721B0238D57AC30E5368E43F61A08656442D948EF5DC4D3E47AC40AABE7',\n                    signAlg: 'SHA256withECDSA',\n                    profile: 'D:/workspace/anyup/uView-Pro/docs/uviewpro_prodRelease.p7b',\n                    certpath: 'D:/workspace/anyup/uView-Pro/docs/uviewpro.cer'\n                }\n            }\n        ],\n        products: [\n            {\n                name: 'default',\n                signingConfig: 'default',\n                targetSdkVersion: '6.0.0(20)',\n                compatibleSdkVersion: '5.0.0(12)',\n                compatibleSdkVersionStage: 'beta6',\n                runtimeOS: 'HarmonyOS',\n                buildOption: {\n                    strictMode: {\n                        caseSensitiveCheck: true,\n                        useNormalizedOHMUrl: true\n                    }\n                }\n            },\n            {\n                name: 'release',\n                signingConfig: 'release',\n                targetSdkVersion: '6.0.0(20)',\n                compatibleSdkVersion: '5.0.0(12)',\n                compatibleSdkVersionStage: 'beta6',\n                runtimeOS: 'HarmonyOS',\n                buildOption: {\n                    strictMode: {\n                        caseSensitiveCheck: true,\n                        useNormalizedOHMUrl: true\n                    }\n                }\n            }\n        ],\n        buildModeSet: [\n            {\n                name: 'debug'\n            },\n            {\n                name: 'release'\n            }\n        ]\n    },\n    modules: [\n        {\n            name: 'entry',\n            srcPath: './entry',\n            targets: [\n                {\n                    name: 'default',\n                    applyToProducts: ['default']\n                }\n            ]\n        }\n    ]\n}\n"
  },
  {
    "path": "index.html",
    "content": "<!doctype html>\n<html>\n    <head>\n        <meta charset=\"UTF-8\" />\n        <meta name=\"referrer\" content=\"no-referrer\" />\n        <link\n            rel=\"shortcut icon\"\n            type=\"image/x-icon\"\n            href=\"https://ik.imagekit.io/anyup/uview-pro/common/favicon.ico\"\n        />\n        <script>\n            var coverSupport =\n                'CSS' in window &&\n                typeof CSS.supports === 'function' &&\n                (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'));\n            document.write(\n                '<meta name=\"viewport\" content=\"width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +\n                    (coverSupport ? ', viewport-fit=cover' : '') +\n                    '\" />'\n            );\n        </script>\n        <!-- 正式发布的时候使用，开发期间不启用。↓ -->\n        <script src=\"/static/common/js/touch-emulator.js\"></script>\n        <script>\n            TouchEmulator();\n        </script>\n        <title></title>\n        <!--preload-links-->\n        <!--app-context-->\n    </head>\n    <body>\n        <div id=\"app\"><!--app-html--></div>\n        <script type=\"module\" src=\"/src/main.ts\"></script>\n    </body>\n</html>\n"
  },
  {
    "path": "package.json",
    "content": "{\n    \"name\": \"uview-pro-demo\",\n    \"version\": \"0.6.0-beta.1\",\n    \"scripts\": {\n        \"dev\": \"uni\",\n        \"dev:custom\": \"uni -p\",\n        \"dev:h5\": \"uni\",\n        \"dev:h5:ssr\": \"uni --ssr\",\n        \"dev:app\": \"uni -p app\",\n        \"dev:app-android\": \"uni -p app-android\",\n        \"dev:app-ios\": \"uni -p app-ios\",\n        \"dev:mp-alipay\": \"uni -p mp-alipay\",\n        \"dev:mp-baidu\": \"uni -p mp-baidu\",\n        \"dev:mp-jd\": \"uni -p mp-jd\",\n        \"dev:mp-kuaishou\": \"uni -p mp-kuaishou\",\n        \"dev:mp-lark\": \"uni -p mp-lark\",\n        \"dev:mp-qq\": \"uni -p mp-qq\",\n        \"dev:mp-toutiao\": \"uni -p mp-toutiao\",\n        \"dev:mp-weixin\": \"uni -p mp-weixin\",\n        \"dev:mp-xhs\": \"uni -p mp-xhs\",\n        \"dev:mp-dingtalk\": \"uni -p mp-dingtalk\",\n        \"dev:quickapp-webview\": \"uni -p quickapp-webview\",\n        \"dev:quickapp-webview-huawei\": \"uni -p quickapp-webview-huawei\",\n        \"dev:quickapp-webview-union\": \"uni -p quickapp-webview-union\",\n        \"build\": \"node scripts/update-date.js && uni build\",\n        \"postbuild\": \"node scripts/fix-empty-css.js\",\n        \"build:custom\": \"node scripts/update-date.js && uni build -p\",\n        \"build:h5\": \"node scripts/update-date.js && uni build\",\n        \"build:h5:ssr\": \"uni build --ssr\",\n        \"build:app\": \"uni build -p app\",\n        \"build:app-android\": \"uni build -p app-android\",\n        \"build:app-ios\": \"uni build -p app-ios\",\n        \"build:mp-alipay\": \"uni build -p mp-alipay\",\n        \"build:mp-baidu\": \"uni build -p mp-baidu\",\n        \"build:mp-jd\": \"uni build -p mp-jd\",\n        \"build:mp-kuaishou\": \"uni build -p mp-kuaishou\",\n        \"build:mp-lark\": \"uni build -p mp-lark\",\n        \"build:mp-qq\": \"uni build -p mp-qq\",\n        \"build:mp-toutiao\": \"uni build -p mp-toutiao\",\n        \"build:mp-weixin\": \"node scripts/update-date.js && uni build -p mp-weixin\",\n        \"build:mp-xhs\": \"uni build -p mp-xhs\",\n        \"build:mp-dingtalk\": \"uni build -p mp-dingtalk\",\n        \"build:quickapp-webview\": \"uni build -p quickapp-webview\",\n        \"build:quickapp-webview-huawei\": \"uni build -p quickapp-webview-huawei\",\n        \"build:quickapp-webview-union\": \"uni build -p quickapp-webview-union\",\n        \"type-check\": \"vue-tsc --noEmit\",\n        \"commit\": \"git-cz\",\n        \"commit:lint\": \"commitlint --edit\",\n        \"changelog\": \"node scripts/generate-changelog.js\",\n        \"changelog:first\": \"node scripts/generate-changelog.js\",\n        \"changelog:emoji\": \"node scripts/generate-changelog.js --emoji\",\n        \"changelog:plain\": \"node scripts/generate-changelog.js --plain\",\n        \"changelog:current\": \"node scripts/generate-changelog.js --emoji --current\",\n        \"changelog:current:plain\": \"node scripts/generate-changelog.js --plain --current\",\n        \"changelog:current:no-unreleased\": \"node scripts/generate-changelog.js --emoji --current --no-unreleased\",\n        \"changelog:current:plain:no-unreleased\": \"node scripts/generate-changelog.js --plain --current --no-unreleased\",\n        \"changelog:last\": \"node scripts/generate-changelog.js --emoji --last\",\n        \"changelog:last:plain\": \"node scripts/generate-changelog.js --plain --last\",\n        \"changelog:all\": \"node scripts/generate-changelog.js --emoji --all\",\n        \"changelog:all:plain\": \"node scripts/generate-changelog.js --plain --all\",\n        \"release\": \"node scripts/release.js\",\n        \"release:changelog\": \"npm run changelog && git add CHANGELOG.md && git commit -m 'docs: update changelog' && git push\",\n        \"release:patch\": \"node scripts/release.js patch\",\n        \"release:minor\": \"node scripts/release.js minor\",\n        \"release:major\": \"node scripts/release.js major\",\n        \"release:beta\": \"node scripts/release.js prerelease beta\",\n        \"release:alpha\": \"node scripts/release.js prerelease alpha\",\n        \"release:rc\": \"node scripts/release.js prerelease rc\",\n        \"release:push\": \"node scripts/release.js push\",\n        \"release:undo\": \"node scripts/release.js undo\",\n        \"publish\": \"cd src/uni_modules/uview-pro && npm publish --access public && cd ../../..\",\n        \"prepare\": \"husky\",\n        \"format\": \"prettier --write . --ignore-path .prettierignore\",\n        \"test:npm\": \"node scripts/test-npm-package.js\",\n        \"test:npm:cleanup\": \"node scripts/test-npm-cleanup.js\"\n    },\n    \"config\": {\n        \"commitizen\": {\n            \"path\": \"./node_modules/cz-git\"\n        }\n    },\n    \"dependencies\": {\n        \"@dcloudio/uni-app\": \"3.0.0-4080720251210001\",\n        \"@dcloudio/uni-app-harmony\": \"3.0.0-4080720251210001\",\n        \"@dcloudio/uni-app-plus\": \"3.0.0-4080720251210001\",\n        \"@dcloudio/uni-components\": \"3.0.0-4080720251210001\",\n        \"@dcloudio/uni-h5\": \"3.0.0-4080720251210001\",\n        \"@dcloudio/uni-mp-alipay\": \"3.0.0-4080720251210001\",\n        \"@dcloudio/uni-mp-baidu\": \"3.0.0-4080720251210001\",\n        \"@dcloudio/uni-mp-harmony\": \"3.0.0-4080720251210001\",\n        \"@dcloudio/uni-mp-jd\": \"3.0.0-4080720251210001\",\n        \"@dcloudio/uni-mp-kuaishou\": \"3.0.0-4080720251210001\",\n        \"@dcloudio/uni-mp-lark\": \"3.0.0-4080720251210001\",\n        \"@dcloudio/uni-mp-qq\": \"3.0.0-4080720251210001\",\n        \"@dcloudio/uni-mp-toutiao\": \"3.0.0-4080720251210001\",\n        \"@dcloudio/uni-mp-weixin\": \"3.0.0-4080720251210001\",\n        \"@dcloudio/uni-mp-xhs\": \"3.0.0-4080720251210001\",\n        \"@dcloudio/uni-quickapp-webview\": \"3.0.0-4080720251210001\",\n        \"vue\": \"^3.4.21\",\n        \"vue-i18n\": \"9.1.9\"\n    },\n    \"devDependencies\": {\n        \"@commitlint/cli\": \"^19.8.1\",\n        \"@commitlint/config-conventional\": \"^19.8.1\",\n        \"@dcloudio/types\": \"^3.4.8\",\n        \"@dcloudio/uni-automator\": \"3.0.0-4080720251210001\",\n        \"@dcloudio/uni-cli-shared\": \"3.0.0-4080720251210001\",\n        \"@dcloudio/uni-stacktracey\": \"3.0.0-4080720251210001\",\n        \"@dcloudio/vite-plugin-uni\": \"3.0.0-4080720251210001\",\n        \"@uni-ku/root\": \"^1.4.1\",\n        \"@vue/runtime-core\": \"3.4.21\",\n        \"@vue/tsconfig\": \"^0.8.1\",\n        \"commitizen\": \"^4.3.1\",\n        \"cz-git\": \"^1.12.0\",\n        \"husky\": \"^9.1.7\",\n        \"prettier\": \"^3.6.2\",\n        \"sass\": \"1.63.2\",\n        \"sass-loader\": \"10.4.1\",\n        \"typescript\": \"^5.5.4\",\n        \"vite\": \"5.2.8\",\n        \"vue-tsc\": \"^3.0.5\"\n    },\n    \"lint-staged\": {\n        \"*.{js,ts,vue,scss,md,json}\": \"prettier --write --ignore-path .prettierignore\"\n    },\n    \"uni-app\": {\n        \"scripts\": {\n            \"mp-dingtalk\": {\n                \"title\": \"钉钉小程序\",\n                \"env\": {\n                    \"UNI_PLATFORM\": \"mp-alipay\"\n                },\n                \"define\": {\n                    \"MP-DINGTALK\": true\n                }\n            }\n        }\n    },\n    \"volta\": {\n        \"node\": \"20.13.1\"\n    },\n    \"buildDate\": \"2026-04-17\",\n    \"releaseDate\": \"2026-05-08\"\n}\n"
  },
  {
    "path": "scripts/README.md",
    "content": "# 发布脚本使用说明\n\n本项目提供了多个版本的发布脚本，以确保在不同操作系统上都能正常运行。\n\n## 脚本文件说明\n\n- `release.sh` - Bash 脚本 (适用于 Linux/macOS)\n- `release.ps1` - PowerShell 脚本 (适用于 Windows)\n- `release.bat` - 批处理脚本 (适用于 Windows)\n- `release.js` - Node.js 脚本 (适用于所有平台，推荐使用)\n\n## 使用方法\n\n### 1. 推荐方式 (跨平台)\n\n使用 Node.js 脚本，在所有平台上都能运行：\n\n```bash\n# 发布补丁版本\nnpm run release:patch\n\n# 发布次要版本\nnpm run release:minor\n\n# 发布主要版本\nnpm run release:major\n\n# 发布指定版本\nnpm run release 0.5.1\n```\n\n或者直接使用：\n\n```bash\nnode scripts/release.js patch\nnode scripts/release.js minor\nnode scripts/release.js major\nnode scripts/release.js 0.5.1\n```\n\n### 2. Windows PowerShell 方式\n\n```powershell\n# 发布补丁版本\nnpm run release:patch:win\n\n# 发布次要版本\nnpm run release:minor:win\n\n# 发布主要版本\nnpm run release:major:win\n```\n\n或者直接使用：\n\n```powershell\npowershell -ExecutionPolicy Bypass -File scripts/release.ps1 patch\n```\n\n### 3. Windows 批处理方式\n\n```cmd\n# 发布补丁版本\nnpm run release:patch:bat\n\n# 发布次要版本\nnpm run release:minor:bat\n\n# 发布主要版本\nnpm run release:major:bat\n```\n\n或者直接使用：\n\n```cmd\nscripts\\release.bat patch\n```\n\n### 4. Linux/macOS 方式\n\n```bash\n# 发布补丁版本\nnpm run release:patch\n\n# 发布次要版本\nnpm run release:minor\n\n# 发布主要版本\nnpm run release:major\n```\n\n或者直接使用：\n\n```bash\n./scripts/release.sh patch\n```\n\n## 版本类型说明\n\n- `patch` - 补丁版本 (修复 bug，如 1.0.0 → 1.0.1)\n- `minor` - 次要版本 (新功能，如 1.0.0 → 1.1.0)\n- `major` - 主要版本 (破坏性更新，如 1.0.0 → 2.0.0)\n- `0.5.1` - 指定版本 (自定义更新，如 1.0.0 → 1.5.1)\n\n## 脚本功能\n\n所有脚本都会执行以下操作：\n\n1. ✅ 检查 Git 状态 (确保没有未提交的更改)\n2. ✅ 检查当前分支 (建议在 main/master 分支上发布)\n3. ✅ 更新根目录 package.json 中的版本号\n4. ✅ 更新 uview-pro 模块 package.json 中的版本号\n5. ✅ 生成 CHANGELOG.md\n6. ✅ 提交所有更改\n7. ✅ 创建 Git 标签\n8. ✅ 推送到远程仓库\n\n## 注意事项\n\n- 确保已安装 Node.js 和 npm\n- 确保 Git 已配置并可以推送到远程仓库\n- 确保有足够的权限执行脚本\n- 在 Windows 上使用 PowerShell 时，可能需要调整执行策略\n\n## 故障排除\n\n### Windows PowerShell 执行策略问题\n\n如果遇到执行策略错误，可以运行：\n\n```powershell\nSet-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser\n```\n\n### 权限问题\n\n确保脚本文件有执行权限：\n\n```bash\nchmod +x scripts/release.sh\n```\n\n### Git 配置问题\n\n确保 Git 已正确配置：\n\n```bash\ngit config --global user.name \"Your Name\"\ngit config --global user.email \"your.email@example.com\"\n```\n\n## 发布平台令牌（GitHub / Gitee）\n\n发布脚本支持在推送标签后自动创建 Release，并将当前版本的 changelog 作为 Release 描述。需要为对应平台配置令牌（Token）：\n\n### GitHub Token\n\n1. 创建 Token：\n    - GitHub → Settings → Developer settings → Personal access tokens\n    - 任选其一：\n        - classic：勾选 `repo`（至少包含 repo:status、repo_deployment、public_repo）\n        - fine-grained：选择当前仓库，权限建议：`Contents: Read and write`、`Metadata: Read-only`\n2. 设置环境变量（Windows PowerShell）：\n    - 仅当前会话：\n\n    ```powershell\n    $env:GITHUB_TOKEN = \"你的token\"\n    ```\n\n    - 永久生效（新开终端生效）：\n\n    ```powershell\n    setx GITHUB_TOKEN \"你的token\"\n    ```\n\n    - 亦可使用 `GH_TOKEN`：\n\n    ```powershell\n    $env:GH_TOKEN = \"你的token\"; setx GH_TOKEN \"你的token\"\n    ```\n\n### Gitee Token\n\n1. 创建 Token：\n    - Gitee → 头像 → 设置 → 私人令牌（或 安全设置 → 私人令牌）\n    - 新建令牌，授予仓库相关权限（至少包含发布 Release 所需权限）\n2. 设置环境变量（Windows PowerShell）：\n    - 仅当前会话：\n\n    ```powershell\n    $env:GITEE_TOKEN = \"你的token\"\n    ```\n\n    - 永久生效（新开终端生效）：\n\n    ```powershell\n    setx GITEE_TOKEN \"你的token\"\n    ```\n\n### 验证\n\n重新打开 PowerShell，执行：\n\n```powershell\necho $env:GITHUB_TOKEN\necho $env:GH_TOKEN\necho $env:GITEE_TOKEN\n```\n\n能看到值即已生效。随后正常执行：\n\n```bash\npnpm release:patch | pnpm release:minor | pnpm release:major\n```\n\n脚本会自动识别远程仓库：\n\n- GitHub 仓库使用 `GITHUB_TOKEN`/`GH_TOKEN` 创建 Release\n- Gitee 仓库使用 `GITEE_TOKEN` 创建 Release\n"
  },
  {
    "path": "scripts/contributors-map.json",
    "content": "{\n    \"nameToGithub\": {\n        \"前端梦工厂\": \"anyup\",\n        \"不爱说话郭德纲\": \"elkelkelkelkelk\",\n        \"xiaozuoovo\": \"zuo-wentao\",\n        \"lime\": \"limes-cloud\",\n        \"张淇\": \"zakicheung\"\n    },\n    \"ignore\": [\"前端梦工厂\"],\n    \"note\": \"此文件用于将作者名映射到 GitHub 用户名。如果自动推断的用户名头像不显示，可以在此配置。ignore 数组中的作者名将不会显示头像。\"\n}\n"
  },
  {
    "path": "scripts/contributors-usage.md",
    "content": "# Contributors 配置使用说明\n\n## 📋 配置文件\n\n`scripts/contributors-map.json` 用于配置贡献者信息。\n\n## 🎯 配置项说明\n\n### 1. nameToGithub（映射配置）\n\n将作者名映射到 GitHub 用户名。\n\n```json\n{\n    \"nameToGithub\": {\n        \"前端梦工厂\": \"anyup\",\n        \"John Doe\": \"johndoe\"\n    }\n}\n```\n\n**使用场景**：\n\n- 自动推断的 GitHub 用户名不正确\n- 作者名与 GitHub 用户名不一致\n- 需要指定特定的 GitHub 用户名\n\n### 2. ignore（忽略配置）\n\n忽略某些贡献者，不显示他们的头像。\n\n```json\n{\n    \"ignore\": [\"bot\", \"dependabot\", \"某些用户\"]\n}\n```\n\n**使用场景**：\n\n- 机器人账号（如 dependabot）\n- 头像不显示的用户\n- 不想显示的贡献者\n\n## 📝 完整配置示例\n\n```json\n{\n    \"nameToGithub\": {\n        \"前端梦工厂\": \"anyup\",\n        \"John Doe\": \"johndoe\",\n        \"李四\": \"lisi\"\n    },\n    \"ignore\": [\"bot\", \"dependabot\", \"某些用户\"],\n    \"note\": \"此文件用于将作者名映射到 GitHub 用户名。如果自动推断的用户名头像不显示，可以在此配置。ignore 数组中的作者名将不会显示头像。\"\n}\n```\n\n## 🔧 使用方法\n\n### 添加映射\n\n编辑 `scripts/contributors-map.json`，在 `nameToGithub` 中添加映射：\n\n```json\n{\n    \"nameToGithub\": {\n        \"作者名\": \"github用户名\"\n    }\n}\n```\n\n### 忽略贡献者\n\n编辑 `scripts/contributors-map.json`，在 `ignore` 数组中添加要忽略的作者名：\n\n```json\n{\n    \"ignore\": [\"要忽略的作者名\"]\n}\n```\n\n## 🚀 重新生成 Changelog\n\n修改配置后，需要重新生成 changelog：\n\n```bash\n# 生成所有版本\npnpm changelog:all\n\n# 生成当前版本\npnpm changelog:current:no-unreleased\n```\n\n## 📊 优先级说明\n\n1. **ignore 配置**：最高优先级，如果在 ignore 列表中，直接跳过\n2. **nameToGithub 映射**：如果配置了映射，使用映射的 GitHub 用户名\n3. **自动推断**：将作者名转换为小写并移除空格作为 GitHub 用户名\n\n## ❓ 常见问题\n\n### Q: 如何查看贡献者列表？\n\nA: 运行以下命令查看所有贡献者：\n\n```bash\ngit log --format=\"%an\" | sort -u\n```\n\n### Q: 如何忽略机器人账号？\n\nA: 在 `ignore` 数组中添加机器人名称：\n\n```json\n{\n    \"ignore\": [\"dependabot[bot]\", \"renovate[bot]\"]\n}\n```\n\n### Q: 如何为中文作者名配置映射？\n\nA: 直接在 `nameToGithub` 中配置：\n\n```json\n{\n    \"nameToGithub\": {\n        \"前端梦工厂\": \"anyup\",\n        \"张三\": \"zhangsan\"\n    }\n}\n```\n\n## 📚 相关文件\n\n- `scripts/contributors-map.json` - 配置文件\n- `scripts/generate-changelog.js` - 生成脚本\n- `CHANGELOG.md` - 生成的变更日志\n"
  },
  {
    "path": "scripts/fix-empty-css.js",
    "content": "#!/usr/bin/env node\n\n/*\n  Ensure non-empty CSS assets in dist to avoid hosts stripping zero-byte files\n  Usage: runs automatically via npm postbuild\n*/\n\nconst fs = require('fs');\nconst path = require('path');\n\nconst DIST_DIR = path.resolve(process.cwd(), 'dist');\n\nfunction walk(dir, handler) {\n    const entries = fs.readdirSync(dir, { withFileTypes: true });\n    for (const entry of entries) {\n        const full = path.join(dir, entry.name);\n        if (entry.isDirectory()) walk(full, handler);\n        else handler(full);\n    }\n}\n\nfunction ensureCssNotEmpty(filePath) {\n    try {\n        const stat = fs.statSync(filePath);\n        if (stat.size === 0) {\n            fs.writeFileSync(\n                filePath,\n                '/* keep: prevent hosting from stripping empty CSS; referenced by JS chunk */\\n',\n                'utf8'\n            );\n            // eslint-disable-next-line no-console\n            console.log(`fixed empty css: ${path.relative(process.cwd(), filePath)}`);\n        }\n    } catch (e) {\n        // eslint-disable-next-line no-console\n        console.warn(`skip css check: ${filePath}`, e?.message);\n    }\n}\n\nfunction run() {\n    if (!fs.existsSync(DIST_DIR)) return;\n    walk(DIST_DIR, full => {\n        if (full.endsWith('.css')) ensureCssNotEmpty(full);\n    });\n}\n\nrun();\n"
  },
  {
    "path": "scripts/generate-changelog.js",
    "content": "#!/usr/bin/env node\n\nconst { execSync } = require('child_process');\nconst fs = require('fs');\nconst path = require('path');\n\n// 解析命令行参数\nconst args = process.argv.slice(2);\nconst useEmoji = args.includes('--emoji');\nconst usePlain = args.includes('--plain');\nconst onlyCurrent = args.includes('--current');\nconst sinceLastTag = args.includes('--last') || args.includes('--since-last-tag');\nconst generateAll = args.includes('--all') || args.includes('--by-tags');\nconst noUnreleased = args.includes('--no-unreleased');\n\n// 如果没有指定参数，默认使用 emoji\nconst shouldUseEmoji = useEmoji || (!usePlain && !useEmoji);\n\n// Emoji 映射\nconst emojiMap = {\n    feat: '✨',\n    fix: '🐛',\n    docs: '📝',\n    style: '💄',\n    refactor: '♻️',\n    perf: '⚡',\n    test: '✅',\n    build: '📦‍',\n    ci: '👷',\n    chore: '🚀',\n    revert: '⏪'\n};\n\n// 类型名称映射（带 emoji）\nconst typeNamesWithEmoji = {\n    feat: '✨ Features | 新功能',\n    fix: '🐛 Bug Fixes | Bug 修复',\n    docs: '📝 Documentation | 文档',\n    style: '💄 Styles | 风格',\n    refactor: '♻️ Code Refactoring | 代码重构',\n    perf: '⚡ Performance Improvements | 性能优化',\n    test: '✅ Tests | 测试',\n    build: '📦‍ Build System | 打包构建',\n    ci: '👷 Continuous Integration | CI 配置',\n    chore: '🚀 Chore | 构建/工程依赖/工具',\n    revert: '⏪ Revert | 回退'\n};\n\n// 类型名称映射（不带 emoji）\nconst typeNamesPlain = {\n    feat: 'Features | 新功能',\n    fix: 'Bug Fixes | Bug 修复',\n    docs: 'Documentation | 文档',\n    style: 'Styles | 风格',\n    refactor: 'Code Refactoring | 代码重构',\n    perf: 'Performance Improvements | 性能优化',\n    test: 'Tests | 测试',\n    build: 'Build System | 打包构建',\n    ci: 'Continuous Integration | CI 配置',\n    chore: 'Chore | 构建/工程依赖/工具',\n    revert: 'Revert | 回退'\n};\n\n// 根据设置选择类型名称\nconst typeNames = shouldUseEmoji ? typeNamesWithEmoji : typeNamesPlain;\n\nfunction safeExec(cmd) {\n    try {\n        return execSync(cmd, { encoding: 'utf8' }).trim();\n    } catch (e) {\n        return '';\n    }\n}\n\nfunction resolveRange() {\n    // --current: 以 package.json 的 version 为标签 vX.Y.Z，取上一个标签..当前标签\n    if (onlyCurrent) {\n        const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));\n        const currentTag = `v${pkg.version}`;\n        // 上一个标签（当前标签的前一个）\n        const prevTag = safeExec(`git describe --tags --abbrev=0 ${currentTag}^`);\n        if (prevTag) return `${prevTag}..${currentTag}`;\n        // 兜底：若当前标签不存在，则取最近一个标签..HEAD\n        const lastTag = safeExec('git describe --tags --abbrev=0');\n        if (lastTag) return `${lastTag}..HEAD`;\n        return '';\n    }\n    // --last / --since-last-tag: 最近一个标签..HEAD\n    if (sinceLastTag) {\n        const lastTag = safeExec('git describe --tags --abbrev=0');\n        if (lastTag) return `${lastTag}..HEAD`;\n        return '';\n    }\n    // 默认：全量\n    return '';\n}\n\nfunction buildSectionHeader({ version, date }) {\n    return `## ${version} - ${date}`;\n}\n\nfunction collectCommits(range) {\n    const rangeArg = range ? ` ${range}` : '';\n    const lines = execSync(`git log${rangeArg} --pretty=format:\"%H|%s|%an|%ae\" --reverse`, { encoding: 'utf8' })\n        .split('\\n')\n        .filter(line => line.trim());\n    return lines.map(line => {\n        const [hash, subject, authorName, authorEmail] = line.split('|');\n        return { hash, subject, authorName, authorEmail };\n    });\n}\n\nfunction groupCommitsByType(commits) {\n    const commitsByType = {};\n    commits.forEach(commit => {\n        if (!commit.subject) return;\n        const match = commit.subject.match(/^(\\w+)(?:\\(([^)]+)\\))?:\\s*(.+)/);\n        if (match) {\n            const [, type, scope, description] = match;\n            if (!emojiMap[type]) return;\n            if (!commitsByType[type]) commitsByType[type] = [];\n            commitsByType[type].push({\n                ...commit,\n                scope: scope || '',\n                description: description.trim()\n            });\n        }\n    });\n    return commitsByType;\n}\n\nfunction collectContributors(commits) {\n    const contributorsMap = new Map();\n    const seenUsernames = new Set(); // 用于去重 GitHub 用户名\n\n    // 读取贡献者映射配置\n    let nameToGithub = {};\n    let ignoreList = [];\n    try {\n        const configPath = path.join(__dirname, 'contributors-map.json');\n        if (fs.existsSync(configPath)) {\n            const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));\n            nameToGithub = config.nameToGithub || {};\n            ignoreList = config.ignore || [];\n        }\n    } catch (e) {\n        // 忽略配置文件读取错误\n    }\n\n    commits.forEach(commit => {\n        if (!commit.authorName || !commit.authorEmail) return;\n\n        // 检查是否在忽略列表中\n        if (ignoreList.includes(commit.authorName)) {\n            return;\n        }\n\n        const key = `${commit.authorName}|${commit.authorEmail}`;\n        if (!contributorsMap.has(key)) {\n            let githubUsername = '';\n\n            // 1. 优先使用配置文件中的映射\n            if (nameToGithub[commit.authorName]) {\n                githubUsername = nameToGithub[commit.authorName];\n            } else {\n                // 2. 使用作者名称推断 GitHub 用户名\n                // 将作者名转换为小写并移除空格\n                githubUsername = commit.authorName.toLowerCase().replace(/\\s+/g, '');\n            }\n\n            // 3. 检查 GitHub 用户名是否已存在，避免重复\n            if (!seenUsernames.has(githubUsername)) {\n                seenUsernames.add(githubUsername);\n                contributorsMap.set(key, {\n                    name: commit.authorName,\n                    email: commit.authorEmail,\n                    githubUsername: githubUsername\n                });\n            }\n        }\n    });\n\n    return Array.from(contributorsMap.values());\n}\n\nfunction renderContributors(contributors) {\n    if (!contributors || contributors.length === 0) return '';\n\n    let section = '### 👥 Contributors\\n\\n';\n\n    contributors.forEach(contributor => {\n        if (contributor.githubUsername) {\n            // 使用 GitHub 头像\n            section += `<a href=\"https://github.com/${contributor.githubUsername}\"><img src=\"https://github.com/${contributor.githubUsername}.png?size=40\" width=\"40\" height=\"40\" alt=\"${contributor.name}\" title=\"${contributor.name}\"/></a> `;\n        } else {\n            // 没有 GitHub 用户名，显示姓名\n            section += `**${contributor.name}** `;\n        }\n    });\n\n    section += '\\n\\n';\n    return section;\n}\n\nfunction renderBodyFromGroups(commitsByType, contributors = null) {\n    let body = '';\n    Object.keys(commitsByType).forEach(type => {\n        if (commitsByType[type].length === 0) return;\n        const typeName = typeNames[type];\n        body += `### ${typeName}\\n\\n`;\n        commitsByType[type].forEach(commit => {\n            const scope = commit.scope ? `**${commit.scope}:** ` : '';\n            const shortHash = commit.hash.substring(0, 7);\n            body += `- ${scope}${commit.description} ([${shortHash}](https://github.com/anyup/uView-Pro/commit/${commit.hash}))\\n`;\n        });\n        body += '\\n';\n    });\n\n    // 添加 Contributors 部分\n    if (contributors && contributors.length > 0) {\n        body += renderContributors(contributors);\n    }\n\n    return body;\n}\n\nfunction renderFallbackBody() {\n    if (shouldUseEmoji) {\n        return `### ✨ Features | 新功能\\n\\n- Initial project setup with commitizen, cz-git, and conventional changelog\\n\\n### 🐛 Bug Fixes | Bug 修复\\n\\n### 📝 Documentation | 文档\\n\\n### 💄 Styles | 风格\\n\\n### ♻️ Code Refactoring | 代码重构\\n\\n### ⚡ Performance Improvements | 性能优化\\n\\n### ✅ Tests | 测试\\n\\n### 📦‍ Build System | 打包构建\\n\\n### 👷 Continuous Integration | CI 配置\\n\\n### 🚀 Chore | 构建/工程依赖/工具\\n\\n### ⏪ Revert | 回退\\n\\n`;\n    }\n    return `### Features | 新功能\\n\\n- Initial project setup with commitizen, cz-git, and conventional changelog\\n\\n### Bug Fixes | Bug 修复\\n\\n### Documentation | 文档\\n\\n### Styles | 风格\\n\\n### Code Refactoring | 代码重构\\n\\n### Performance Improvements | 性能优化\\n\\n### Tests | 测试\\n\\n### Build System | 打包构建\\n\\n### Continuous Integration | CI 配置\\n\\n### Chore | 构建/工程依赖/工具\\n\\n### Revert | 回退\\n\\n`;\n}\n\nfunction generateChangelog() {\n    try {\n        const range = resolveRange();\n        console.log(\n            `🔄 Generating changelog... ${shouldUseEmoji ? 'with emoji' : 'without emoji'}${range ? ` (range: ${range})` : ''}`\n        );\n\n        // 解析提交\n        const commits = collectCommits(range);\n        const commitsByType = groupCommitsByType(commits);\n\n        // 收集贡献者信息\n        const contributors = collectContributors(commits);\n\n        const hasExisting = fs.existsSync('CHANGELOG.md');\n        const existingContent = hasExisting ? fs.readFileSync('CHANGELOG.md', 'utf8') : '';\n\n        // 标准化头部（可选移除 Unreleased）\n        const baseHeader = `# Changelog\\n\\nAll notable changes to this project will be documented in this file.\\n\\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),\\nand this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\\n\\n`;\n        const standardHeader = noUnreleased ? baseHeader : baseHeader + '## [Unreleased]\\n\\n';\n\n        let changelogBody = renderBodyFromGroups(commitsByType, contributors);\n\n        // 如果没有找到任何符合规范的提交，添加默认内容\n        if (Object.keys(commitsByType).length === 0) {\n            changelogBody += renderFallbackBody();\n        }\n\n        let finalContent = '';\n        if (generateAll) {\n            // 基于标签重建所有版本区块\n            const tagsOutput = safeExec('git tag --list --sort=-v:refname');\n            const tags = tagsOutput ? tagsOutput.split('\\n').filter(Boolean) : [];\n\n            let sections = '';\n            for (let i = 0; i < tags.length; i++) {\n                const tag = tags[i];\n                const prev = tags[i + 1];\n                const tagDate = safeExec(`git show -s --format=%ad --date=format:%Y-%m-%d ${tag}`) || '';\n                const rangeExp = prev ? `${prev}..${tag}` : `${tag}`;\n                const tagCommits = collectCommits(rangeExp);\n                const groups = groupCommitsByType(tagCommits);\n                const tagContributors = collectContributors(tagCommits);\n                let body = renderBodyFromGroups(groups, tagContributors);\n                if (!body) body = renderFallbackBody();\n                const header = buildSectionHeader({ version: tag.replace(/^v/, ''), date: tagDate });\n                sections += `${header}\\n\\n${body}`;\n            }\n\n            const headerIdx = existingContent.indexOf('## [Unreleased]');\n            const base =\n                headerIdx !== -1\n                    ? existingContent.slice(0, existingContent.indexOf('\\n', headerIdx) + 1)\n                    : standardHeader;\n            finalContent = base + '\\n' + sections.trim() + '\\n';\n        } else if (onlyCurrent) {\n            // 将当前范围内容生成到版本段落，并插入到 Unreleased 之后\n            const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));\n            const version = pkg.version;\n            const today = new Date();\n            const yyyy = today.getFullYear();\n            const mm = String(today.getMonth() + 1).padStart(2, '0');\n            const dd = String(today.getDate()).padStart(2, '0');\n            const dateStr = `${yyyy}-${mm}-${dd}`;\n\n            const sectionHeader = buildSectionHeader({ version, date: dateStr });\n            const newSection = `${sectionHeader}\\n\\n${changelogBody}`;\n\n            if (hasExisting) {\n                if (noUnreleased) {\n                    // 不保留 Unreleased 模式：找到第一个版本区块（跳过 ## [Unreleased]），在其前插入新版本\n                    let firstVersionIndex = existingContent.indexOf('\\n## ');\n                    // 如果找到的是 ## [Unreleased]，则继续找下一个\n                    if (firstVersionIndex !== -1) {\n                        const lineEnd = existingContent.indexOf('\\n', firstVersionIndex + 1);\n                        const headerLine = existingContent.slice(firstVersionIndex, lineEnd);\n                        if (headerLine.includes('[Unreleased]')) {\n                            firstVersionIndex = existingContent.indexOf('\\n## ', lineEnd);\n                        }\n                    }\n                    if (firstVersionIndex !== -1) {\n                        finalContent =\n                            existingContent.slice(0, firstVersionIndex) +\n                            '\\n' +\n                            newSection +\n                            '\\n' +\n                            existingContent.slice(firstVersionIndex);\n                    } else {\n                        // 没有版本区块，直接追加\n                        finalContent = existingContent + '\\n' + newSection + '\\n';\n                    }\n                } else {\n                    // 保留 Unreleased 模式：找到 Unreleased 段落，在其后插入新版本\n                    const unreleasedIndex = existingContent.indexOf('## [Unreleased]');\n                    if (unreleasedIndex !== -1) {\n                        // 找到 Unreleased 段落的结束位置（下一个 \"## \" 标题或文件末尾）\n                        const afterUnreleased = existingContent.indexOf(\n                            '\\n## ',\n                            unreleasedIndex + '## [Unreleased]'.length\n                        );\n                        if (afterUnreleased !== -1) {\n                            finalContent =\n                                existingContent.slice(0, afterUnreleased) +\n                                '\\n' +\n                                newSection +\n                                '\\n' +\n                                existingContent.slice(afterUnreleased);\n                        } else {\n                            finalContent = existingContent + '\\n' + newSection + '\\n';\n                        }\n                    } else {\n                        // 不存在 Unreleased，则在头部后插入\n                        finalContent = standardHeader + newSection + '\\n' + existingContent;\n                    }\n                }\n            } else {\n                // 初次生成，包含标准头和新版本段\n                finalContent = standardHeader + newSection + '\\n';\n            }\n        } else {\n            // 默认行为：写入标准头和将本次统计结果放在 Unreleased 下\n            finalContent = standardHeader + changelogBody;\n        }\n\n        // 彻底清理重复内容（防止多次运行导致重复）\n        if (finalContent.includes('# Changelog')) {\n            // 找到第一个头部结束位置\n            const headerEndIndex = finalContent.indexOf('\\n\\n## ');\n            if (headerEndIndex !== -1) {\n                const header = finalContent.slice(0, headerEndIndex);\n                const body = finalContent.slice(headerEndIndex);\n\n                // 移除所有重复的头部和重复的版本区块\n                let cleanBody = body;\n\n                // 移除重复的头部\n                cleanBody = cleanBody.replace(\n                    /# Changelog\\n\\nAll notable changes to this project will be documented in this file\\.\\n\\nThe format is based on \\[Keep a Changelog\\].*?and this project adheres to \\[Semantic Versioning\\].*?\\n\\n/g,\n                    ''\n                );\n\n                // 移除重复的版本区块（保留第一个）\n                const versionBlocks = cleanBody.split('\\n## ');\n                if (versionBlocks.length > 1) {\n                    const firstBlock = versionBlocks[0];\n                    const otherBlocks = versionBlocks.slice(1);\n\n                    // 去重：只保留唯一的版本区块\n                    const uniqueBlocks = [];\n                    const seenVersions = new Set();\n\n                    otherBlocks.forEach(block => {\n                        // 跳过 Unreleased 区块\n                        if (block.startsWith('[Unreleased]')) {\n                            return;\n                        }\n                        const versionMatch = block.match(/^(\\[?\\d+\\.\\d+\\.\\d+)/);\n                        if (versionMatch && !seenVersions.has(versionMatch[1])) {\n                            seenVersions.add(versionMatch[1]);\n                            uniqueBlocks.push('## ' + block);\n                        }\n                    });\n\n                    cleanBody = firstBlock + (uniqueBlocks.length > 0 ? '\\n' + uniqueBlocks.join('\\n') : '');\n                }\n\n                finalContent = header + cleanBody;\n            }\n        }\n\n        // 统一调整版本间隔为1行（清理多余的空行）\n        if (finalContent.includes('## ')) {\n            // 清理头部后的多余空行，只保留1行间隔（匹配 ## [Unreleased] 或 ## 版本号）\n            finalContent = finalContent.replace(/(# Changelog[\\s\\S]*?)\\n\\n\\n+## /, '$1\\n\\n## ');\n\n            // 清理版本区块之间的多余空行，只保留1行间隔\n            finalContent = finalContent.replace(/\\n\\n\\n+## /g, '\\n\\n## ');\n\n            // 清理文件末尾的多余空行\n            finalContent = finalContent.replace(/\\n+$/, '\\n');\n        }\n\n        // 写入主 CHANGELOG.md 文件\n        fs.writeFileSync('CHANGELOG.md', finalContent);\n        console.log(`✅ Changelog generated successfully ${shouldUseEmoji ? 'with emoji icons' : 'without emoji'}!`);\n\n        // 如果是 current 模式且 no-unreleased，同时更新组件库的 changelog.md\n        if (onlyCurrent && noUnreleased) {\n            try {\n                const componentChangelogPath = 'src/uni_modules/uview-pro/changelog.md';\n                if (fs.existsSync(componentChangelogPath)) {\n                    const componentContent = fs.readFileSync(componentChangelogPath, 'utf8');\n\n                    // 提取当前版本的内容（兼容带方括号和不带方括号的格式）\n                    const currentVersion = JSON.parse(fs.readFileSync('package.json', 'utf8')).version;\n                    const currentSectionMatch = finalContent.match(\n                        new RegExp(`## \\\\[?${currentVersion}\\\\]?[\\\\s\\\\S]*?(?=\\\\n## |$)`)\n                    );\n\n                    if (currentSectionMatch) {\n                        let currentSection = currentSectionMatch[0];\n\n                        // 转换为组件库 changelog 的格式（去掉 emoji，调整日期格式）\n                        currentSection = currentSection\n                            .replace(/## \\[?(\\d+\\.\\d+\\.\\d+[^\\s]*)\\]? - (\\d{4}-\\d{2}-\\d{2})/, '## $1（$2）')\n                            .replace(/### 🚀 Chore \\| 构建\\/工程依赖\\/工具/, '### 🚀 Chore | 构建/工程依赖/工具')\n                            .replace(/### 🐛 Bug Fixes \\| Bug 修复/, '### 🐛 Bug Fixes | Bug 修复')\n                            .replace(/### ✨ Features \\| 新功能/, '### ✨ Features | 新功能')\n                            .replace(/### ♻️ Code Refactoring \\| 代码重构/, '### ♻️ Code Refactoring | 代码重构')\n                            .replace(/### 📝 Documentation \\| 文档/, '### 📝 Documentation | 文档')\n                            .replace(/### 💄 Styles \\| 风格/, '### 💄 Styles | 风格')\n                            .replace(\n                                /### ⚡ Performance Improvements \\| 性能优化/,\n                                '### ⚡ Performance Improvements | 性能优化'\n                            )\n                            .replace(/### ✅ Tests \\| 测试/, '### ✅ Tests | 测试')\n                            .replace(/### 📦‍ Build System \\| 打包构建/, '### 📦‍ Build System | 打包构建')\n                            .replace(\n                                /### 👷 Continuous Integration \\| CI 配置/,\n                                '### 👷 Continuous Integration | CI 配置'\n                            )\n                            .replace(/### ⏪ Revert \\| 回退/, '### ⏪ Revert | 回退')\n                            .replace(/### 👥 Contributors/, '### 👥 Contributors');\n\n                        // 检查是否已经存在该版本\n                        const versionExists = new RegExp(`## ${currentVersion}（`).test(componentContent);\n\n                        if (!versionExists) {\n                            // 在文件开头插入新版本，只保留1行间隔\n                            // 清理 currentSection 末尾的多余空行\n                            const cleanSection = currentSection.replace(/\\n+$/, '');\n                            const newContent = cleanSection + '\\n\\n' + componentContent;\n                            fs.writeFileSync(componentChangelogPath, newContent);\n                            console.log(`✅ Component changelog updated: ${componentChangelogPath}`);\n                        } else {\n                            console.log(`ℹ️  Version ${currentVersion} already exists in component changelog`);\n                        }\n                    }\n                } else {\n                    console.log(`⚠️  Component changelog file not found: ${componentChangelogPath}`);\n                }\n            } catch (error) {\n                console.log(`⚠️  Failed to update component changelog: ${error.message}`);\n            }\n        }\n\n        // 显示统计信息\n        Object.keys(commitsByType).forEach(type => {\n            const emoji = shouldUseEmoji ? emojiMap[type] + ' ' : '';\n            console.log(`${emoji}${typeNamesPlain[type]}: ${commitsByType[type].length} commits`);\n        });\n\n        // 显示使用说明\n        console.log('\\n📖 Usage:');\n        console.log('  pnpm changelog:emoji              - Generate changelog with emoji (full history)');\n        console.log('  pnpm changelog:plain              - Generate changelog without emoji (full history)');\n        console.log('  pnpm changelog:current            - Generate current version changelog (emoji)');\n        console.log('  pnpm changelog:current:plain      - Generate current version changelog (plain)');\n        console.log('  pnpm changelog:last               - Generate since last tag changelog (emoji)');\n        console.log('  pnpm changelog:last:plain         - Generate since last tag changelog (plain)');\n        console.log('  pnpm changelog:all                - Rebuild all version sections from git tags (emoji)');\n        console.log('  pnpm changelog:all:plain          - Rebuild all version sections from git tags (plain)');\n    } catch (error) {\n        console.error('❌ Error generating changelog:', error.message);\n        process.exit(1);\n    }\n}\n\ngenerateChangelog();\n"
  },
  {
    "path": "scripts/listColors.mjs",
    "content": "import fs from 'fs';\nimport { fileURLToPath } from 'url';\nimport { dirname, join } from 'path';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst root = join(__dirname, '..', 'src', 'uni_modules', 'uview-pro', 'components');\n\nconst pattern = /#([0-9a-fA-F]{3,6})/g;\nconst counts = {};\n\nfunction walk(dir) {\n    const entries = fs.readdirSync(dir, { withFileTypes: true });\n    for (const entry of entries) {\n        const fullPath = join(dir, entry.name);\n        if (entry.isDirectory()) {\n            walk(fullPath);\n        } else if (entry.isFile()) {\n            let text;\n            try {\n                text = fs.readFileSync(fullPath, 'utf8');\n            } catch (e) {\n                text = fs.readFileSync(fullPath, { encoding: 'utf8', flag: 'r' });\n            }\n            let match;\n            while ((match = pattern.exec(text)) !== null) {\n                const hex = match[0].toLowerCase();\n                counts[hex] = (counts[hex] || 0) + 1;\n            }\n        }\n    }\n}\n\nwalk(root);\n\nObject.keys(counts)\n    .sort()\n    .forEach(hex => {\n        console.log(`${hex} ${counts[hex]}`);\n    });\n"
  },
  {
    "path": "scripts/release.bat",
    "content": "@echo off\nsetlocal enabledelayedexpansion\n\nREM 发布脚本 (批处理版本)\nREM 使用方法: scripts\\release.bat [patch|minor|major]\n\nif \"%~1\"==\"\" (\n    echo 请指定版本类型: patch, minor, 或 major\n    echo 使用方法: scripts\\release.bat [patch^|minor^|major]\n    exit /b 1\n)\n\nset VERSION_TYPE=%~1\n\nREM 验证版本类型\nif not \"%VERSION_TYPE%\"==\"patch\" if not \"%VERSION_TYPE%\"==\"minor\" if not \"%VERSION_TYPE%\"==\"major\" (\n    echo 错误: 版本类型必须是 patch, minor, 或 major\n    exit /b 1\n)\n\necho 开始发布 %VERSION_TYPE% 版本...\n\nREM 检查是否有未提交的更改\ngit status --porcelain >nul 2>&1\nif %errorlevel% neq 0 (\n    echo 错误: 有未提交的更改，请先提交或暂存\n    git status --porcelain\n    exit /b 1\n)\n\nREM 检查当前分支\nfor /f \"tokens=*\" %%i in ('git branch --show-current') do set CURRENT_BRANCH=%%i\nif not \"%CURRENT_BRANCH%\"==\"main\" if not \"%CURRENT_BRANCH%\"==\"master\" (\n    echo 警告: 当前分支是 %CURRENT_BRANCH%，建议在 main 或 master 分支上发布\n    set /p CONTINUE=\"是否继续? (y/N): \"\n    if /i not \"!CONTINUE!\"==\"y\" exit /b 1\n)\n\nREM 更新版本号\necho 更新版本号...\ncall npm version %VERSION_TYPE% --no-git-tag-version\n\nREM 获取新版本号\nfor /f \"tokens=*\" %%i in ('node -p \"require('./package.json').version\"') do set NEW_VERSION=%%i\necho 新版本: %NEW_VERSION%\n\nREM 同时更新uview-pro模块的版本号\necho 更新uview-pro模块版本号...\nset UVEW_PRO_PACKAGE_PATH=src\\uni_modules\\uview-pro\\package.json\nif exist \"%UVEW_PRO_PACKAGE_PATH%\" (\n    node -e \"const pkg = require('./%UVEW_PRO_PACKAGE_PATH%'); pkg.version = '%NEW_VERSION%'; require('fs').writeFileSync('./%UVEW_PRO_PACKAGE_PATH%', JSON.stringify(pkg, null, 4) + '\\n');\"\n    echo ✅ uview-pro模块版本已更新为: %NEW_VERSION%\n) else (\n    echo ⚠️  未找到uview-pro模块的package.json文件\n)\n\nREM 生成 changelog\necho 生成 changelog...\ncall npm run changelog\n\nREM 提交更改\necho 提交更改...\ngit add package.json src/uni_modules/uview-pro/package.json CHANGELOG.md\ngit commit -m \"chore(release): bump version to %NEW_VERSION%\n\n- Update package.json version\n- Update uview-pro module version\n- Generate changelog for %NEW_VERSION%\"\n\nREM 创建标签\necho 创建标签 v%NEW_VERSION%...\ngit tag -a \"v%NEW_VERSION%\" -m \"Release version %NEW_VERSION%\"\n\nREM 推送更改和标签\necho 推送更改和标签...\ngit push origin HEAD\ngit push origin \"v%NEW_VERSION%\"\n\necho ✅ 版本 %NEW_VERSION% 发布成功!\necho 📝 Changelog 已更新\necho 🏷️  标签 v%NEW_VERSION% 已创建并推送\necho.\necho 下一步:\necho 1. 在 GitHub/GitLab 上创建 Release\necho 2. 将 CHANGELOG.md 中的内容复制到 Release 描述中\necho 3. 上传构建产物 (如果需要)\n"
  },
  {
    "path": "scripts/release.js",
    "content": "#!/usr/bin/env node\n\n/**\n * 发布脚本 (Node.js版本)\n * 使用方法:\n *   node scripts/release.js [patch|minor|major]              # 语义化版本（默认不推送）\n *   node scripts/release.js prerelease [alpha|beta|rc]       # 预览版本（默认不推送）\n *   node scripts/release.js 0.5.1                          # 直接指定版本号（默认不推送）\n *   node scripts/release.js patch --push                   # 提交并推送\n *   node scripts/release.js push                           # 推送上次未推送的发布\n *   node scripts/release.js undo                           # 撤销本地发布（仅未推送时）\n * 在所有平台上都能运行\n */\n\nconst { execSync, spawn } = require('child_process');\nconst fs = require('fs');\nconst path = require('path');\n\n// 获取命令行参数\nconst args = process.argv.slice(2);\n\n// 特殊命令：push - 用于推送之前未 push 的发布\nif (args[0] === 'push') {\n    console.log('🚀 开始推送发布标签和提交...');\n    try {\n        // 获取当前版本\n        const packageJsonPath = path.join(process.cwd(), 'package.json');\n        const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));\n        const version = packageJson.version;\n\n        // 推送提交和标签\n        console.log('📤 推送提交...');\n        execSync('git push origin HEAD', { stdio: 'inherit' });\n        console.log(`📤 推送标签 v${version}...`);\n        execSync(`git push origin \"v${version}\"`, { stdio: 'inherit' });\n        console.log(`✅ 版本 ${version} 推送成功！`);\n        process.exit(0);\n    } catch (error) {\n        console.error('❌ 推送失败:', error.message);\n        process.exit(1);\n    }\n}\n\n// 特殊命令：undo - 用于撤销本地的发布（仅支持未推送的情况）\nif (args[0] === 'undo') {\n    console.log('↩️  开始撤销本地发布...');\n    try {\n        // 获取当前版本\n        const packageJsonPath = path.join(process.cwd(), 'package.json');\n        const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));\n        const version = packageJson.version;\n        const tagName = `v${version}`;\n\n        // 检查是否有未推送的提交\n        console.log('🔍 检查提交状态...');\n        try {\n            const unpushedCommits = execSync('git log origin/HEAD..HEAD --oneline', { encoding: 'utf8' }).trim();\n            if (!unpushedCommits) {\n                console.error('❌ 错误：没有未推送的提交，或者当前分支没有远程跟踪分支');\n                console.error('💡 该命令仅用于撤销未推送的本地发布');\n                process.exit(1);\n            }\n        } catch (e) {\n            // 如果没有远程分支，git log 会报错，这也是可以撤销的情况\n        }\n\n        // 检查标签是否存在\n        console.log(`🔍 检查标签 ${tagName}...`);\n        let tagExists = false;\n        try {\n            execSync(`git rev-parse ${tagName}`, { stdio: 'pipe' });\n            tagExists = true;\n        } catch (e) {\n            console.log(`⚠️  标签 ${tagName} 不存在`);\n        }\n\n        // 获取最后一次提交信息\n        const lastCommitMsg = execSync('git log -1 --pretty=%B', { encoding: 'utf8' }).trim();\n        const isReleaseCommit = lastCommitMsg.includes('chore(release): bump version to');\n\n        if (!isReleaseCommit) {\n            console.error('❌ 错误：最后一次提交不是发布提交');\n            console.error('💡 最后一次提交信息:', lastCommitMsg.substring(0, 50) + '...');\n            console.error('💡 请手动检查并撤销');\n            process.exit(1);\n        }\n\n        console.log('');\n        console.log('⚠️  即将执行以下操作：');\n        console.log(`   1. 删除本地标签: ${tagName}`);\n        console.log('   2. 撤销最后一次提交（保留修改到暂存区）');\n        console.log('   3. 恢复 package.json 和 changelog 文件');\n        console.log('');\n        console.log('💡 撤销后版本号需要手动修改回之前的版本');\n        console.log('');\n\n        // 由于是命令行工具，直接执行而不询问\n        // 删除本地标签\n        if (tagExists) {\n            console.log(`🗑️  删除本地标签 ${tagName}...`);\n            execSync(`git tag -d ${tagName}`, { stdio: 'inherit' });\n        }\n\n        // 撤销最后一次提交，保留修改\n        console.log('↩️  撤销最后一次提交...');\n        execSync('git reset --soft HEAD~1', { stdio: 'inherit' });\n\n        // 恢复 package.json 文件\n        console.log('📄 恢复 package.json...');\n        execSync('git checkout -- package.json', { stdio: 'inherit' });\n\n        // 恢复 uview-pro 模块的 package.json\n        const uviewProPackagePath = 'src/uni_modules/uview-pro/package.json';\n        if (fs.existsSync(uviewProPackagePath)) {\n            console.log('📄 恢复 uview-pro package.json...');\n            try {\n                execSync(`git checkout -- ${uviewProPackagePath}`, { stdio: 'inherit' });\n            } catch (e) {\n                console.log('⚠️  未找到 uview-pro package.json 或无需恢复');\n            }\n        }\n\n        // 恢复 changelog\n        console.log('📄 恢复 changelog...');\n        execSync('git checkout -- CHANGELOG.md', { stdio: 'inherit' });\n        try {\n            execSync('git checkout -- src/uni_modules/uview-pro/changelog.md', { stdio: 'inherit' });\n        } catch (e) {\n            console.log('⚠️  未找到 uview-pro changelog 或无需恢复');\n        }\n\n        console.log('');\n        console.log('✅ 本地发布撤销成功！');\n        console.log('');\n        console.log('📋 当前状态：');\n        console.log(`   • 标签 ${tagName} 已删除`);\n        console.log('   • 提交已撤销，修改已保留在暂存区');\n        console.log('   • package.json 和 changelog 已恢复');\n        console.log('');\n        console.log('💡 如需修改版本号，请手动编辑 package.json');\n        console.log('💡 如需重新发布，运行: npm run release:patch (或其他版本类型)');\n        process.exit(0);\n    } catch (error) {\n        console.error('❌ 撤销失败:', error.message);\n        process.exit(1);\n    }\n}\n\n// 检查是否有 --push 参数（默认不推送）\nconst shouldPush = args.includes('--push');\nconst versionInput = args.find(arg => !arg.startsWith('--'));\n\n// 验证版本号格式 (支持 x.y.z 格式，如 0.5.1, 1.0.0, 2.3.4-beta.1)\nfunction isValidVersion(version) {\n    if (!version || typeof version !== 'string') return false;\n    // 匹配语义化版本号: x.y.z 或 x.y.z-prerelease\n    const semverRegex = /^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?$/;\n    return semverRegex.test(version);\n}\n\n// 判断是语义化版本类型还是直接指定版本号\nconst isSemverType = ['patch', 'minor', 'major', 'prerelease'].includes(versionInput);\nconst isDirectVersion = isValidVersion(versionInput);\n\n// 验证参数\nif (!versionInput || (!isSemverType && !isDirectVersion)) {\n    console.error('❌ 请指定版本类型或版本号');\n    console.error('使用方法:');\n    console.error('  node scripts/release.js [patch|minor|major]              # 语义化版本（默认不推送）');\n    console.error('  node scripts/release.js prerelease [alpha|beta|rc]       # 预览版本（默认不推送）');\n    console.error('  node scripts/release.js 0.5.1                            # 直接指定版本号（默认不推送）');\n    console.error('');\n    console.error('选项:');\n    console.error('  --push                                                   # 提交并推送');\n    console.error('');\n    console.error('其他命令:');\n    console.error('  node scripts/release.js push                             # 推送上次未推送的发布');\n    console.error('  node scripts/release.js undo                             # 撤销本地发布（仅未推送时）');\n    process.exit(1);\n}\n\n// 处理 prerelease 类型和标识\nlet prereleaseId = '';\nif (versionInput === 'prerelease') {\n    prereleaseId = args[1] || 'beta'; // 默认使用 beta\n}\n\nconst versionType = isSemverType ? versionInput : null;\nconst targetVersion = isDirectVersion ? versionInput : null;\n\n// 显示发布信息\nconst releaseTypeText = targetVersion\n    ? targetVersion\n    : versionType === 'prerelease'\n      ? `${prereleaseId} 预览版`\n      : versionType;\nconst isPrereleaseType = versionType === 'prerelease' || (targetVersion && targetVersion.includes('-'));\n\nconsole.log(`${isPrereleaseType ? '🧪' : '🚀'} 开始发布 ${releaseTypeText} 版本...`);\n\n// 执行命令的辅助函数\nfunction execCommand(command, options = {}) {\n    try {\n        const result = execSync(command, {\n            encoding: 'utf8',\n            stdio: 'inherit',\n            ...options\n        });\n        return result;\n    } catch (error) {\n        console.error(`❌ 命令执行失败: ${command}`);\n        console.error(error.message);\n        process.exit(1);\n    }\n}\n\n// 检查是否有未提交的更改\nconsole.log('📋 检查Git状态...');\nconst gitStatus = execCommand('git status --porcelain', { stdio: 'pipe' });\nif (gitStatus.trim()) {\n    console.error('❌ 有未提交的更改，请先提交或暂存');\n    console.log(gitStatus);\n    process.exit(1);\n}\n\n// 检查当前分支\nconsole.log('🌿 检查当前分支...');\nconst currentBranch = execCommand('git branch --show-current', { stdio: 'pipe' }).trim();\nif (currentBranch !== 'main' && currentBranch !== 'master') {\n    console.warn(`⚠️  警告: 当前分支是 ${currentBranch}，建议在 main 或 master 分支上发布`);\n\n    // 在Node.js中实现交互式输入\n    const readline = require('readline');\n    const rl = readline.createInterface({\n        input: process.stdin,\n        output: process.stdout\n    });\n\n    rl.question('是否继续? (y/N): ', answer => {\n        rl.close();\n        if (!/^[Yy]$/.test(answer)) {\n            console.log('❌ 操作已取消');\n            process.exit(1);\n        }\n        continueRelease();\n    });\n} else {\n    continueRelease();\n}\n\nfunction continueRelease() {\n    try {\n        const packageJsonPath = path.join(process.cwd(), 'package.json');\n        const currentDate = new Date().toISOString().split('T')[0]; // YYYY-MM-DD格式\n        let newVersion;\n        const isPrerelease = versionType === 'prerelease' || (targetVersion && targetVersion.includes('-'));\n\n        // 更新版本号\n        if (targetVersion) {\n            // 直接指定版本号\n            console.log(`📦 更新版本号为 ${targetVersion}...`);\n            const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));\n            packageJson.version = targetVersion;\n            // 更新发布日期\n            packageJson.releaseDate = currentDate;\n            fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\\n');\n            newVersion = targetVersion;\n        } else if (versionType === 'prerelease') {\n            // 预览版本\n            console.log(`📦 更新版本号为 ${prereleaseId} 预览版本...`);\n            execCommand(`npm version prerelease --preid=${prereleaseId} --no-git-tag-version`);\n            const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));\n            newVersion = packageJson.version;\n            // 更新发布日期\n            packageJson.releaseDate = currentDate;\n            fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\\n');\n        } else {\n            // 语义化版本类型\n            console.log('📦 更新版本号...');\n            execCommand(`npm version ${versionType} --no-git-tag-version`);\n            const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));\n            newVersion = packageJson.version;\n            // 更新发布日期\n            packageJson.releaseDate = currentDate;\n            fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\\n');\n        }\n\n        console.log(`✨ 新版本: ${newVersion}`);\n        console.log(`✅ 发布日期: ${currentDate}`);\n\n        // 同时更新uview-pro模块的版本号\n        console.log('📦 更新uview-pro模块版本号...');\n        const uviewProPackagePath = path.join(process.cwd(), 'src', 'uni_modules', 'uview-pro', 'package.json');\n        if (fs.existsSync(uviewProPackagePath)) {\n            const uviewProPackage = JSON.parse(fs.readFileSync(uviewProPackagePath, 'utf8'));\n            uviewProPackage.version = newVersion;\n            fs.writeFileSync(uviewProPackagePath, JSON.stringify(uviewProPackage, null, 4) + '\\n');\n            console.log(`✅ uview-pro模块版本已更新为: ${newVersion}`);\n        } else {\n            console.warn('⚠️  未找到uview-pro模块的package.json文件');\n        }\n\n        // 生成 changelog（按当前版本生成版本化条目，可配置是否保留 Unreleased）\n        console.log('📝 生成 changelog...');\n        execCommand('npm run changelog:current:no-unreleased');\n\n        // 提交更改\n        console.log('💾 提交更改...');\n        execCommand(\n            'git add package.json src/uni_modules/uview-pro/package.json CHANGELOG.md src/uni_modules/uview-pro/changelog.md'\n        );\n        execCommand(`git commit -m \"chore(release): bump version to ${newVersion}\n\n- Update package.json version\n- Update uview-pro module version\n- Generate changelog for ${newVersion}\n- Update uview-pro component changelog\"`);\n\n        // 创建标签\n        console.log(`🏷️  创建标签 v${newVersion}...`);\n        execCommand(`git tag -a \"v${newVersion}\" -m \"Release version ${newVersion}\"`);\n\n        // 推送更改和标签\n        if (shouldPush) {\n            console.log('🚀 推送更改和标签...');\n            execCommand('git push origin HEAD');\n            execCommand(`git push origin \"v${newVersion}\"`);\n        }\n\n        console.log(`${isPrerelease ? '🎉 预览版本' : '✅ 版本'} ${newVersion} 发布成功!`);\n        console.log('📝 Changelog 已更新');\n        if (shouldPush) {\n            console.log(`🏷️  标签 v${newVersion} 已创建并推送`);\n        } else {\n            console.log(`🏷️  标签 v${newVersion} 已创建（未推送）`);\n            console.log('💡 如需推送，运行: npm run release:push');\n            console.log(`   或: git push origin HEAD && git push origin \"v${newVersion}\"`);\n        }\n        if (isPrerelease) {\n            console.log('');\n            console.log('⚠️  这是一个预览版本，仅供测试使用');\n        }\n        console.log('');\n        console.log('📋 下一步:');\n        if (!shouldPush) {\n            console.log('1. 检查无误后，运行 npm run release:push 推送发布');\n            console.log('2. 如需创建 GitHub/Gitee Release，请手动前往仓库创建');\n        } else {\n            console.log('如需创建 GitHub/Gitee Release，请手动前往仓库创建');\n        }\n    } catch (error) {\n        console.error('❌ 发布过程中出现错误:', error.message);\n        process.exit(1);\n    }\n}\n"
  },
  {
    "path": "scripts/release.ps1",
    "content": "# 发布脚本 (PowerShell版本)\n# 使用方法: .\\scripts\\release.ps1 [patch|minor|major]\n\nparam(\n    [Parameter(Mandatory=$true)]\n    [ValidateSet(\"patch\", \"minor\", \"major\")]\n    [string]$VersionType\n)\n\n# 设置错误处理\n$ErrorActionPreference = \"Stop\"\n\nWrite-Host \"开始发布 $VersionType 版本...\" -ForegroundColor Green\n\n# 检查是否有未提交的更改\n$gitStatus = git status --porcelain\nif ($gitStatus) {\n    Write-Host \"错误: 有未提交的更改，请先提交或暂存\" -ForegroundColor Red\n    Write-Host $gitStatus\n    exit 1\n}\n\n# 检查当前分支\n$currentBranch = git branch --show-current\nif ($currentBranch -ne \"main\" -and $currentBranch -ne \"master\") {\n    Write-Host \"警告: 当前分支是 $currentBranch，建议在 main 或 master 分支上发布\" -ForegroundColor Yellow\n    $continue = Read-Host \"是否继续? (y/N)\"\n    if ($continue -notmatch \"^[Yy]$\") {\n        exit 1\n    }\n}\n\n# 更新版本号\nWrite-Host \"更新版本号...\" -ForegroundColor Cyan\nnpm version $VersionType --no-git-tag-version\n\n# 获取新版本号\n$packageJson = Get-Content \"package.json\" | ConvertFrom-Json\n$newVersion = $packageJson.version\nWrite-Host \"新版本: $newVersion\" -ForegroundColor Green\n\n# 同时更新uview-pro模块的版本号\nWrite-Host \"更新uview-pro模块版本号...\" -ForegroundColor Cyan\n$uviewProPackagePath = \"src\\uni_modules\\uview-pro\\package.json\"\nif (Test-Path $uviewProPackagePath) {\n    $uviewProPackage = Get-Content $uviewProPackagePath | ConvertFrom-Json\n    $uviewProPackage.version = $newVersion\n    $uviewProPackage | ConvertTo-Json -Depth 10 | Set-Content $uviewProPackagePath\n    Write-Host \"✅ uview-pro模块版本已更新为: $newVersion\" -ForegroundColor Green\n} else {\n    Write-Host \"⚠️  未找到uview-pro模块的package.json文件\" -ForegroundColor Yellow\n}\n\n# 生成 changelog\nWrite-Host \"生成 changelog...\" -ForegroundColor Cyan\nnpm run changelog\n\n# 提交更改\nWrite-Host \"提交更改...\" -ForegroundColor Cyan\ngit add package.json src/uni_modules/uview-pro/package.json CHANGELOG.md\ngit commit -m \"chore(release): bump version to $newVersion\n\n- Update package.json version\n- Update uview-pro module version\n- Generate changelog for $newVersion\"\n\n# 创建标签\nWrite-Host \"创建标签 v$newVersion...\" -ForegroundColor Cyan\ngit tag -a \"v$newVersion\" -m \"Release version $newVersion\"\n\n# 推送更改和标签\nWrite-Host \"推送更改和标签...\" -ForegroundColor Cyan\ngit push origin HEAD\ngit push origin \"v$newVersion\"\n\nWrite-Host \"✅ 版本 $newVersion 发布成功!\" -ForegroundColor Green\nWrite-Host \"📝 Changelog 已更新\" -ForegroundColor Green\nWrite-Host \"🏷️  标签 v$newVersion 已创建并推送\" -ForegroundColor Green\nWrite-Host \"\"\nWrite-Host \"下一步:\" -ForegroundColor Yellow\nWrite-Host \"1. 在 GitHub/GitLab 上创建 Release\" -ForegroundColor White\nWrite-Host \"2. 将 CHANGELOG.md 中的内容复制到 Release 描述中\" -ForegroundColor White\nWrite-Host \"3. 上传构建产物 (如果需要)\" -ForegroundColor White\n"
  },
  {
    "path": "scripts/release.sh",
    "content": "#!/bin/bash\n\n# 发布脚本\n# 使用方法: ./scripts/release.sh [patch|minor|major]\n\nset -e\n\n# 检查参数\nif [ $# -eq 0 ]; then\n    echo \"请指定版本类型: patch, minor, 或 major\"\n    echo \"使用方法: ./scripts/release.sh [patch|minor|major]\"\n    exit 1\nfi\n\nVERSION_TYPE=$1\n\n# 验证版本类型\nif [[ ! \"$VERSION_TYPE\" =~ ^(patch|minor|major)$ ]]; then\n    echo \"错误: 版本类型必须是 patch, minor, 或 major\"\n    exit 1\nfi\n\necho \"开始发布 $VERSION_TYPE 版本...\"\n\n# 检查是否有未提交的更改\nif [ -n \"$(git status --porcelain)\" ]; then\n    echo \"错误: 有未提交的更改，请先提交或暂存\"\n    git status --porcelain\n    exit 1\nfi\n\n# 检查当前分支\nCURRENT_BRANCH=$(git branch --show-current)\nif [ \"$CURRENT_BRANCH\" != \"main\" ] && [ \"$CURRENT_BRANCH\" != \"master\" ]; then\n    echo \"警告: 当前分支是 $CURRENT_BRANCH，建议在 main 或 master 分支上发布\"\n    read -p \"是否继续? (y/N): \" -n 1 -r\n    echo\n    if [[ ! $REPLY =~ ^[Yy]$ ]]; then\n        exit 1\n    fi\nfi\n\n# 更新版本号\necho \"更新版本号...\"\nnpm version $VERSION_TYPE --no-git-tag-version\n\n# 获取新版本号\nNEW_VERSION=$(node -p \"require('./package.json').version\")\necho \"新版本: $NEW_VERSION\"\n\n# 生成 changelog\necho \"生成 changelog...\"\nnpm run changelog\n\n# 提交更改\necho \"提交更改...\"\ngit add package.json CHANGELOG.md\ngit commit -m \"chore(release): bump version to $NEW_VERSION\n\n- Update package.json version\n- Generate changelog for $NEW_VERSION\"\n\n# 创建标签\necho \"创建标签 v$NEW_VERSION...\"\ngit tag -a \"v$NEW_VERSION\" -m \"Release version $NEW_VERSION\"\n\n# 推送更改和标签\necho \"推送更改和标签...\"\ngit push origin HEAD\ngit push origin \"v$NEW_VERSION\"\n\necho \"✅ 版本 $NEW_VERSION 发布成功!\"\necho \"📝 Changelog 已更新\"\necho \"🏷️  标签 v$NEW_VERSION 已创建并推送\"\necho \"\"\necho \"下一步:\"\necho \"1. 在 GitHub/GitLab 上创建 Release\"\necho \"2. 将 CHANGELOG.md 中的内容复制到 Release 描述中\"\necho \"3. 上传构建产物 (如果需要)\" "
  },
  {
    "path": "scripts/replaceColors.mjs",
    "content": "import fs from 'fs';\nimport path from 'path';\n\nconst rootDir = path.join('src', 'uni_modules', 'uview-pro', 'components');\n\nconst replacements = new Map(\n    Object.entries({\n        '#ffffff': 'var(--u-white-color)',\n        '#fefefe': 'var(--u-white-color)',\n        '#000000': 'var(--u-black-color)',\n        '#303133': 'var(--u-main-color)',\n        '#323233': 'var(--u-main-color)',\n        '#333333': 'var(--u-main-color)',\n        '#585858': 'var(--u-content-color)',\n        '#606266': 'var(--u-content-color)',\n        '#909399': 'var(--u-tips-color)',\n        '#969799': 'var(--u-tips-color)',\n        '#888992': 'var(--u-tips-color)',\n        '#888888': 'var(--u-tips-color)',\n        '#8799a3': 'var(--u-tips-color)',\n        '#8f8d8e': 'var(--u-tips-color)',\n        '#b2b2b2': 'var(--u-light-color)',\n        '#b7b7b7': 'var(--u-light-color)',\n        '#c0c4cc': 'var(--u-light-color)',\n        '#c7c7c7': 'var(--u-light-color)',\n        '#c8c9cc': 'var(--u-type-info-disabled)',\n        '#cccccc': 'var(--u-light-color)',\n        '#d4d4d4': 'var(--u-divider-color)',\n        '#dcdfe6': 'var(--u-border-color)',\n        '#dddddd': 'var(--u-divider-color)',\n        '#e1e1e1': 'var(--u-divider-color)',\n        '#e4e4e4': 'var(--u-divider-color)',\n        '#e4e7ed': 'var(--u-border-color)',\n        '#e5e5e5': 'var(--u-divider-color)',\n        '#e7e6eb': 'var(--u-divider-color)',\n        '#eaeef1': 'var(--u-bg-gray-light)',\n        '#ebedf0': 'var(--u-bg-gray-light)',\n        '#ebeef5': 'var(--u-bg-gray-light)',\n        '#ececec': 'var(--u-divider-color)',\n        '#eeeeef': 'var(--u-divider-color)',\n        '#f2f2f2': 'var(--u-bg-gray-light)',\n        '#f2f3f5': 'var(--u-bg-gray-light)',\n        '#f3f4f6': 'var(--u-bg-color)',\n        '#f7f7f7': 'var(--u-bg-gray-light)',\n        '#f7f8fa': 'var(--u-bg-gray-light)',\n        '#f56c6c': 'var(--u-type-error)',\n        '#fa3534': 'var(--u-type-error)',\n        '#fde2e2': 'var(--u-type-error-light)',\n        '#faecd8': 'var(--u-type-warning-light)',\n        '#ff9900': 'var(--u-type-warning)',\n        '#19be6b': 'var(--u-type-success)',\n        '#00c777': 'var(--u-type-success)',\n        '#04b00f': 'var(--u-type-success-dark)',\n        '#bef5c8': 'var(--u-type-success-light)',\n        '#2979ff': 'var(--u-type-primary)',\n        '#fff': 'var(--u-white-color)',\n        '#000': 'var(--u-black-color)',\n        '#333': 'var(--u-main-color)',\n        '#bbb': 'var(--u-light-color)',\n        '#eee': 'var(--u-divider-color)',\n        '#ddd': 'var(--u-divider-color)'\n    })\n);\n\nconst filesUpdated = [];\n\nfunction replaceInFile(filePath) {\n    let content = fs.readFileSync(filePath, 'utf8');\n    let replaced = false;\n    replacements.forEach((value, key) => {\n        const pattern = new RegExp(key.replace('#', '\\\\#'), 'gi');\n        if (pattern.test(content)) {\n            content = content.replace(pattern, value);\n            replaced = true;\n        }\n    });\n    if (replaced) {\n        fs.writeFileSync(filePath, content, 'utf8');\n        filesUpdated.push(filePath);\n    }\n}\n\nfunction walk(dir) {\n    const entries = fs.readdirSync(dir, { withFileTypes: true });\n    for (const entry of entries) {\n        const fullPath = path.join(dir, entry.name);\n        if (entry.isDirectory()) {\n            walk(fullPath);\n        } else if (entry.isFile()) {\n            replaceInFile(fullPath);\n        }\n    }\n}\n\nwalk(rootDir);\n\nconsole.log(`Updated ${filesUpdated.length} files.`);\n"
  },
  {
    "path": "scripts/test-npm-cleanup.js",
    "content": "#!/usr/bin/env node\nconst fs = require('fs');\nconst path = require('path');\nconst { spawnSync } = require('child_process');\n\nconst root = path.resolve(__dirname, '..');\nconst packageDir = path.join(root, 'src', 'uni_modules', 'uview-pro');\nconst nodeModulesPath = path.join(root, 'node_modules', 'uview-pro');\n\nfunction log(...args) {\n    console.log('[test-npm-cleanup]', ...args);\n}\n\n// 删除 node_modules/uview-pro（若存在）\ntry {\n    if (fs.existsSync(nodeModulesPath)) {\n        fs.rmSync(nodeModulesPath, { recursive: true, force: true });\n        log('Removed', nodeModulesPath);\n    } else {\n        log('No npm node_modules/uview-pro found.');\n    }\n} catch (e) {\n    console.error('Error removing node_modules/uview-pro:', e);\n}\n\n// 删除打包产物 *.tgz\ntry {\n    if (fs.existsSync(packageDir)) {\n        const files = fs.readdirSync(packageDir);\n        files.forEach(f => {\n            if (/^uview-pro-.*\\\\.tgz$/.test(f)) {\n                const p = path.join(packageDir, f);\n                try {\n                    fs.unlinkSync(p);\n                    log('Removed', p);\n                } catch (e) {}\n            }\n        });\n    }\n} catch (e) {\n    // ignore\n}\n\nlog('Cleanup finished. Note: vite.config.ts/pages.json/src/main.ts 的修改需要手动恢复或使用 git checkout。');\n"
  },
  {
    "path": "scripts/test-npm-package.js",
    "content": "#!/usr/bin/env node\n/**\n * 简化版自动化脚本（用于 test:local）\n * 功能：\n *  1) 打包 src/uni_modules/uview-pro（pnpm 优先，fallback npm）\n *  2) 使用 pnpm/add 或 npm 安装生成的 tgz 到项目（不修改源码，不创建备份）\n *  3) 修改 vite.config.ts 注释掉本地 alias（根据你的要求）\n *  4) 修改 src/pages.json 的 easycom 映射为 \"uview-pro/...\"\n *\n * 注意：本脚本不会启动 dev，也不会创建 bak 或自动恢复，所有改动请你自行恢复或使用 cleanup 脚本。\n */\nconst fs = require('fs');\nconst path = require('path');\nconst { spawnSync } = require('child_process');\n\nconst root = path.resolve(__dirname, '..');\nconst packageDir = path.join(root, 'src', 'uni_modules', 'uview-pro');\nconst viteConfigPath = path.join(root, 'vite.config.ts');\nconst pagesJsonPath = path.join(root, 'src', 'pages.json');\nconst mainTsPath = path.join(root, 'src', 'main.ts');\n\nfunction log(...args) {\n    console.log('[test-npm-package]', ...args);\n}\n\n// 简化处理：不使用包管理器 add/tgz 安装，直接拷贝源码到 node_modules/uview-pro\nfunction copyDirSync(src, dest) {\n    if (!fs.existsSync(src)) throw new Error('源目录不存在: ' + src);\n    // 删除目标如果存在\n    if (fs.existsSync(dest)) {\n        fs.rmSync(dest, { recursive: true, force: true });\n    }\n    fs.mkdirSync(dest, { recursive: true });\n    const entries = fs.readdirSync(src, { withFileTypes: true });\n    for (const entry of entries) {\n        const srcPath = path.join(src, entry.name);\n        const destPath = path.join(dest, entry.name);\n        if (entry.isDirectory()) {\n            copyDirSync(srcPath, destPath);\n        } else if (entry.isFile()) {\n            fs.copyFileSync(srcPath, destPath);\n        }\n    }\n}\n\nfunction installByCopy() {\n    const nodeModulesTarget = path.join(root, 'node_modules', 'uview-pro');\n    try {\n        log('将源码拷贝到', nodeModulesTarget, '用于本地测试（不会修改 package.json 或 lockfile）');\n        copyDirSync(packageDir, nodeModulesTarget);\n        log('拷贝完成。');\n    } catch (e) {\n        console.error('拷贝安装失败：', e);\n        process.exit(1);\n    }\n}\n\nfunction modifyViteConfig() {\n    try {\n        if (!fs.existsSync(viteConfigPath)) {\n            log('vite.config.ts 未找到，跳过修改');\n            return;\n        }\n        let content = fs.readFileSync(viteConfigPath, 'utf8');\n        const lines = content.split(/\\r?\\n/);\n        let changed = false;\n        const newLines = lines.map(ln => {\n            const trimmed = ln.trim();\n            // 如果行已经被注释，跳过\n            if (trimmed.startsWith('//')) return ln;\n            // 如果包含 alias 指向 src/uni_modules/uview-pro 的字符串，将其注释\n            if (ln.includes('src/uni_modules/uview-pro')) {\n                changed = true;\n                return `// ${ln}`;\n            }\n            return ln;\n        });\n        if (changed) {\n            fs.writeFileSync(viteConfigPath, newLines.join('\\n'), 'utf8');\n            log('已修改 vite.config.ts（注释包含 uview-pro alias 的行）。');\n        } else {\n            log('vite.config.ts 中未找到需注释的 uview-pro alias 行，跳过。');\n        }\n    } catch (e) {\n        console.error('修改 vite.config.ts 失败：', e);\n    }\n}\n\nfunction modifyPagesJson() {\n    try {\n        if (!fs.existsSync(pagesJsonPath)) {\n            log('src/pages.json 未找到，跳过修改');\n            return;\n        }\n        let content = fs.readFileSync(pagesJsonPath, 'utf8');\n        // 将 easycom 的映射从 \"@/uni_modules/uview-pro/...\" 改为 \"uview-pro/...\"\n        content = content.replace(\n            /\"@\\/uni_modules\\/uview-pro\\/components\\/u-\\$1\\/u-\\$1\\.vue\"/g,\n            `\"uview-pro/components/u-$1/u-$1.vue\"`\n        );\n        // 也尝试不带 quotes 的老格式\n        content = content.replace(\n            /@\\/uni_modules\\/uview-pro\\/components\\/u-\\$1\\/u-\\$1\\.vue/g,\n            `uview-pro/components/u-$1/u-$1.vue`\n        );\n        fs.writeFileSync(pagesJsonPath, content, 'utf8');\n        log('已修改 src/pages.json（easycom 映射改为 uview-pro）。');\n    } catch (e) {\n        console.error('修改 src/pages.json 失败：', e);\n    }\n}\n\nfunction ensureMainImport() {\n    try {\n        if (!fs.existsSync(mainTsPath)) {\n            log('src/main.ts 未找到，跳过 import 替换');\n            return;\n        }\n        let content = fs.readFileSync(mainTsPath, 'utf8');\n        if (content.indexOf(\"from 'uview-pro'\") === -1 && content.indexOf('from \"uview-pro\"') === -1) {\n            // 替换 \"@/uni_modules/uview-pro\" 为 \"uview-pro\"\n            content = content.replace(/from\\s+['\"]@\\/uni_modules\\/uview-pro['\"]/g, `from 'uview-pro'`);\n            fs.writeFileSync(mainTsPath, content, 'utf8');\n            log(\"已替换 src/main.ts 的导入为 from 'uview-pro'。\");\n        } else {\n            log(\"src/main.ts 已使用 from 'uview-pro'，无需修改。\");\n        }\n    } catch (e) {\n        console.error('处理 src/main.ts 失败：', e);\n    }\n}\n\nfunction main() {\n    log('开始执行 test-npm 步骤（不会启动 dev，且不会创建 bak/自动恢复）。');\n    // 1. 直接把 src/uni_modules/uview-pro 拷贝到 node_modules/uview-pro（不改 package.json / lockfile）\n    installByCopy();\n    // 3. 修改 vite.config.ts 注释 alias\n    modifyViteConfig();\n    // 4. 修改 pages.json 替换 easycom 映射\n    modifyPagesJson();\n    // 5. 确保 main.ts 导入使用 'uview-pro'\n    ensureMainImport();\n\n    log(\n        '全部步骤完成。请手动运行 dev（例如：pnpm run dev 或 npm run dev），并在测试完成后手动清理或使用 npm run test:npm:cleanup。'\n    );\n}\n\nmain();\n"
  },
  {
    "path": "scripts/update-date.js",
    "content": "#!/usr/bin/env node\n\n/**\n * 更新发布日期脚本\n * 用于在package.json中添加或更新发布日期字段\n * 使用方法:\n *   node scripts/update-date.js [package.json路径]\n * 如果不指定路径，默认更新当前目录的package.json\n */\n\nconst fs = require('fs');\nconst path = require('path');\n\n// 获取命令行参数\nconst args = process.argv.slice(2);\nconst packageJsonPath = args[0] || path.join(process.cwd(), 'package.json');\n\n// 获取当前日期 (YYYY-MM-DD格式)\nfunction getCurrentDate() {\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    return `${year}-${month}-${day}`;\n}\n\n// 检查文件是否存在\nif (!fs.existsSync(packageJsonPath)) {\n    console.error(`❌ 文件不存在: ${packageJsonPath}`);\n    process.exit(1);\n}\n\ntry {\n    // 读取package.json\n    const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));\n\n    // 获取当前日期\n    const currentDate = getCurrentDate();\n\n    // 添加或更新编译日期\n    packageJson.buildDate = currentDate;\n\n    // 写回文件，保持格式化\n    fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\\n');\n\n    console.log(`✅ 编译日期已更新: ${currentDate}`);\n    console.log(`📄 文件: ${packageJsonPath}`);\n} catch (error) {\n    console.error('❌ 更新发布日期失败:', error.message);\n    process.exit(1);\n}\n"
  },
  {
    "path": "shims-uni.d.ts",
    "content": "/// <reference types='@dcloudio/types' />\nimport 'vue';\n\ndeclare module '@vue/runtime-core' {\n    type Hooks = App.AppInstance & Page.PageInstance;\n\n    interface ComponentCustomOptions extends Hooks {}\n}\n"
  },
  {
    "path": "src/App.ku.vue",
    "content": "<script setup lang=\"ts\">\nimport { onLoad, onShow } from '@dcloudio/uni-app';\nimport { useTheme, useLocale } from 'uview-pro';\nimport { computed } from 'vue';\n\nconst { darkMode, themes, currentTheme } = useTheme();\nconst { currentLocale, locales } = useLocale();\n\nconst currentThemeName = computed(() => currentTheme.value?.name);\nconst currentLocaleName = computed(() => currentLocale.value?.name);\n\nonLoad(() => {\n    console.log('darkMode->', darkMode.value);\n    console.log('theme->', currentThemeName.value);\n    console.log('locale->', currentLocaleName.value);\n    console.log('locales->', locales.value);\n});\n\nonShow(() => {});\n</script>\n\n<template>\n    <u-config-provider\n        :dark-mode=\"darkMode\"\n        :themes=\"themes\"\n        :current-theme=\"currentThemeName\"\n        :current-locale=\"currentLocaleName\"\n    >\n        <KuRootView />\n        <u-toast global></u-toast>\n        <u-modal global></u-modal>\n    </u-config-provider>\n</template>\n\n<style lang=\"scss\"></style>\n"
  },
  {
    "path": "src/App.vue",
    "content": "<script setup lang=\"ts\">\r\nimport { onLaunch, onShow, onHide, onThemeChange } from '@dcloudio/uni-app';\r\nonLaunch(() => {\r\n    console.log('App Launch');\r\n});\r\nonShow(() => {\r\n    console.log('App Show');\r\n});\r\nonHide(() => {\r\n    console.log('App Hide');\r\n});\r\nonThemeChange(res => {\r\n    console.log('[App.vue] system theme changed', res);\r\n});\r\n</script>\r\n<style lang=\"scss\">\r\n@import '@/uni_modules/uview-pro/index.scss';\r\n@import '@/common/iconfont.css';\r\n@import '@/common/demo.scss';\r\n</style>\r\n"
  },
  {
    "path": "src/api/index.ts",
    "content": "import { Request } from 'uview-pro';\n\nexport const http = new Request();\n\nhttp.setConfig({\n    baseUrl: '/static/app'\n});\n\nhttp.interceptor.response = async (response: any) => {\n    const { statusCode, data: rawData, errMsg } = response as any;\n    return rawData;\n};\n\nexport function getJson(id: string) {\n    return loadJSON(`/${id}.json`);\n}\n\nexport function getMarkdown(id: string) {\n    return loadJSON(`/markdown/${id}.md`);\n}\n\nfunction loadJSON(path: string) {\n    // 动态读取本地 json 文件，path 需以 /app/ 开头\n    // #ifdef APP-HARMONY\n    return new Promise((resolve, reject) => {\n        const fs = uni.getFileSystemManager();\n        const filePath = path.startsWith('/') ? `/static/app${path}` : `/static/app/${path}`;\n        fs.readFile({\n            filePath,\n            encoding: 'utf-8',\n            success: res => {\n                try {\n                    // res.data 可能为 string 或 ArrayBuffer\n                    const data = typeof res.data === 'string' ? res.data : '';\n                    resolve(data);\n                } catch (e) {\n                    console.error(e);\n                    reject(e);\n                }\n            },\n            fail: err => {\n                reject(err);\n            }\n        });\n    });\n    // #endif\n    // #ifndef APP-HARMONY\n    return http.get(path, { t: Date.now() }, { meta: { loading: false } });\n    // #endif\n}\n"
  },
  {
    "path": "src/common/classify.data.ts",
    "content": "export default [\n    {\n        name: '女装',\n        foods: [\n            {\n                name: 'A字裙',\n                key: 'A字裙',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/1.png',\n                cat: 10\n            },\n            {\n                name: 'T恤',\n                key: 'T恤',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/2.png',\n                cat: 10\n            },\n            {\n                name: '半身裙',\n                key: '半身裙',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/3.png',\n                cat: 10\n            },\n            {\n                name: '衬衫',\n                key: '衬衫',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/4.png',\n                cat: 10\n            },\n            {\n                name: '短裙',\n                key: '短裙',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/5.png',\n                cat: 10\n            },\n            {\n                name: '阔腿裤',\n                key: '阔腿裤',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/6.png',\n                cat: 10\n            },\n            {\n                name: '连衣裙',\n                key: '连衣裙',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/7.png',\n                cat: 10\n            },\n            {\n                name: '妈妈装',\n                key: '妈妈装',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/8.png',\n                cat: 10\n            },\n            {\n                name: '牛仔裤',\n                key: '牛仔裤',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/9.png',\n                cat: 10\n            },\n            {\n                name: '情侣装',\n                key: '情侣装',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/10.png',\n                cat: 10\n            },\n            {\n                name: '休闲裤',\n                key: '休闲裤',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/11.png',\n                cat: 10\n            },\n            {\n                name: '雪纺衫',\n                key: '雪纺衫',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/12.png',\n                cat: 10\n            },\n            {\n                name: '防晒衣',\n                key: '防晒衣',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/13.png',\n                cat: 10\n            },\n            {\n                name: '礼服/婚纱',\n                key: '礼服婚纱',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/14.png',\n                cat: 10\n            }\n        ]\n    },\n    {\n        name: '美食',\n        foods: [\n            {\n                name: '火锅',\n                key: '火锅',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/1.png',\n                cat: 6\n            },\n            {\n                name: '糕点饼干',\n                key: '糕点饼干',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/2.png',\n                cat: 6\n            },\n            {\n                name: '坚果果干',\n                key: '坚果果干',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/3.png',\n                cat: 6\n            },\n            {\n                name: '酒类',\n                key: '酒类',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/4.png',\n                cat: 6\n            },\n            {\n                name: '辣条',\n                key: '辣条',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/5.png',\n                cat: 6\n            },\n            {\n                name: '大礼包',\n                key: '大礼包',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/6.png',\n                cat: 6\n            },\n            {\n                name: '精品茗茶',\n                key: '茶',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/7.png',\n                cat: 6\n            },\n            {\n                name: '休闲食品',\n                key: '休闲食品',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/8.png',\n                cat: 6\n            },\n            {\n                name: '糖果巧克力',\n                key: '糖果巧克力',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/9.png',\n                cat: 6\n            },\n            {\n                name: '方便速食',\n                key: '方便速食',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/10.png',\n                cat: 6\n            },\n            {\n                name: '营养代餐',\n                key: '营养代餐',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/11.png',\n                cat: 6\n            },\n            {\n                name: '粮油副食',\n                key: '粮油',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/12.png',\n                cat: 6\n            },\n            {\n                name: '生鲜水果',\n                key: '水果',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/13.png',\n                cat: 6\n            },\n            {\n                name: '饮品',\n                key: '饮品',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/14.png',\n                cat: 6\n            }\n        ]\n    },\n    {\n        name: '美妆',\n        foods: [\n            {\n                name: '化妆刷',\n                key: '化妆刷',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/1.png',\n                cat: 3\n            },\n            {\n                name: '粉底',\n                key: '粉底',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/2.png',\n                cat: 3\n            },\n            {\n                name: '洗发护发',\n                key: '洗发护发',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/3.png',\n                cat: 3\n            },\n            {\n                name: '美容工具',\n                key: '美容工具',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/4.png',\n                cat: 3\n            },\n            {\n                name: '眼部护理',\n                key: '眼部护理',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/5.png',\n                cat: 3\n            },\n            {\n                name: '眉妆',\n                key: '眉妆',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/6.png',\n                cat: 3\n            },\n            {\n                name: '卸妆品',\n                key: '卸妆品',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/7.png',\n                cat: 3\n            },\n            {\n                name: '基础护肤',\n                key: '基础护肤',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/8.png',\n                cat: 3\n            },\n            {\n                name: '眼妆',\n                key: '眼妆',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/9.png',\n                cat: 3\n            },\n            {\n                name: '唇妆',\n                key: '唇妆',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/10.png',\n                cat: 3\n            },\n            {\n                name: '面膜',\n                key: '面膜',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/11.png',\n                cat: 3\n            },\n            {\n                name: '沐浴用品',\n                key: '沐浴用品',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/12.png',\n                cat: 3\n            },\n            {\n                name: '护肤套装',\n                key: '护肤套装',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/13.png',\n                cat: 3\n            },\n            {\n                name: '防晒品',\n                key: '防晒品',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/14.png',\n                cat: 3\n            },\n            {\n                name: '美甲',\n                key: '美甲',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/15.png',\n                cat: 3\n            }\n        ]\n    },\n    {\n        name: '居家日用',\n        foods: [\n            {\n                name: '垃圾袋',\n                key: '垃圾袋',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/1.png',\n                cat: 4\n            },\n            {\n                name: '纸巾',\n                key: '纸巾',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/2.png',\n                cat: 4\n            },\n            {\n                name: '驱蚊用品',\n                key: '驱蚊用品',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/3.png',\n                cat: 4\n            },\n            {\n                name: '收纳神器',\n                key: '收纳神器',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/4.png',\n                cat: 4\n            },\n            {\n                name: '厨房用品',\n                key: '厨房用品',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/5.png',\n                cat: 4\n            },\n            {\n                name: '厨房烹饪',\n                key: '烹饪',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/6.png',\n                cat: 4\n            },\n            {\n                name: '衣物晾晒',\n                key: '衣物晾晒',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/7.png',\n                cat: 4\n            },\n            {\n                name: '衣物护理',\n                key: '衣物护理',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/8.png',\n                cat: 4\n            },\n            {\n                name: '宠物用品',\n                key: '宠物用品',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/9.png',\n                cat: 4\n            },\n            {\n                name: '医药保健',\n                key: '医药',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/10.png',\n                cat: 4\n            },\n            {\n                name: '日用百货',\n                key: '百货',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/11.png',\n                cat: 4\n            },\n            {\n                name: '清洁用品',\n                key: '清洁',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/12.png',\n                cat: 4\n            },\n            {\n                name: '绿植园艺',\n                key: '绿植',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/13.png',\n                cat: 4\n            }\n        ]\n    },\n    {\n        name: '男装',\n        foods: [\n            {\n                name: '爸爸装',\n                key: '爸爸装',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/5/1.png',\n                cat: 12\n            },\n            {\n                name: '牛仔裤',\n                key: '牛仔裤',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/5/2.png',\n                cat: 12\n            },\n            {\n                name: '衬衫',\n                key: '衬衫',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/5/3.png',\n                cat: 12\n            },\n            {\n                name: '休闲裤',\n                key: '休闲裤',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/5/4.png',\n                cat: 12\n            },\n            {\n                name: '外套',\n                key: '外套',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/5/5.png',\n                cat: 12\n            },\n            {\n                name: 'T恤',\n                key: 'T恤',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/5/6.png',\n                cat: 12\n            },\n            {\n                name: '套装',\n                key: '套装',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/5/7.png',\n                cat: 12\n            },\n            {\n                name: '运动裤',\n                key: '运动裤',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/5/8.png',\n                cat: 12\n            },\n            {\n                name: '马甲/背心',\n                key: '马甲背心',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/5/9.png',\n                cat: 12\n            },\n            {\n                name: 'POLO衫',\n                key: 'POLO衫',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/5/10.png',\n                cat: 12\n            },\n            {\n                name: '商务装',\n                key: '商务装',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/5/11.png',\n                cat: 12\n            }\n        ]\n    },\n    {\n        name: '鞋品',\n        foods: [\n            {\n                name: '单鞋',\n                key: '单鞋',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/6/1.png',\n                cat: 5\n            },\n            {\n                name: '皮鞋',\n                key: '皮鞋',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/6/2.png',\n                cat: 5\n            },\n            {\n                name: '帆布鞋',\n                key: '帆布鞋',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/6/3.png',\n                cat: 5\n            },\n            {\n                name: '北京老布鞋',\n                key: '北京老布鞋',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/6/4.png',\n                cat: 5\n            },\n            {\n                name: '运动鞋',\n                key: '运动鞋',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/6/5.png',\n                cat: 5\n            },\n            {\n                name: '拖鞋',\n                key: '拖鞋',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/6/6.png',\n                cat: 5\n            },\n            {\n                name: '凉鞋',\n                key: '凉鞋',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/6/7.png',\n                cat: 5\n            },\n            {\n                name: '休闲鞋',\n                key: '休闲鞋',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/6/8.png',\n                cat: 5\n            },\n            {\n                name: '高跟鞋',\n                key: '高跟鞋',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/6/9.png',\n                cat: 5\n            },\n            {\n                name: '老人鞋',\n                key: '老人鞋',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/6/10.png',\n                cat: 5\n            },\n            {\n                name: '懒人鞋',\n                key: '懒人鞋',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/6/11.png',\n                cat: 5\n            }\n        ]\n    },\n    {\n        name: '数码家电',\n        foods: [\n            {\n                name: '数据线',\n                key: '数据线',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/1.png',\n                cat: 8\n            },\n            {\n                name: '耳机',\n                key: '耳机',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/2.png',\n                cat: 8\n            },\n            {\n                name: '生活家电',\n                key: '家电',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/3.png',\n                cat: 8\n            },\n            {\n                name: '电风扇',\n                key: '电风扇',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/4.png',\n                cat: 8\n            },\n            {\n                name: '电吹风',\n                key: '电吹风',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/5.png',\n                cat: 8\n            },\n            {\n                name: '手机壳',\n                key: '手机壳',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/6.png',\n                cat: 8\n            },\n            {\n                name: '榨汁机',\n                key: '榨汁机',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/7.png',\n                cat: 8\n            },\n            {\n                name: '小家电',\n                key: '小家电',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/8.png',\n                cat: 8\n            },\n            {\n                name: '数码电子',\n                key: '数码',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/9.png',\n                cat: 8\n            },\n            {\n                name: '电饭锅',\n                key: '电饭锅',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/10.png',\n                cat: 8\n            },\n            {\n                name: '手机支架',\n                key: '手机支架',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/11.png',\n                cat: 8\n            },\n            {\n                name: '剃须刀',\n                key: '剃须刀',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/12.png',\n                cat: 8\n            },\n            {\n                name: '充电宝',\n                key: '充电宝',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/13.png',\n                cat: 8\n            },\n            {\n                name: '手机配件',\n                key: '手机配件',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/14.png',\n                cat: 8\n            }\n        ]\n    },\n    {\n        name: '母婴',\n        foods: [\n            {\n                name: '婴童服饰',\n                key: '衣服',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/1.png',\n                cat: 2\n            },\n            {\n                name: '玩具乐器',\n                key: '玩具乐器',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/2.png',\n                cat: 2\n            },\n            {\n                name: '尿不湿',\n                key: '尿不湿',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/3.png',\n                cat: 2\n            },\n            {\n                name: '安抚牙胶',\n                key: '安抚牙胶',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/4.png',\n                cat: 2\n            },\n            {\n                name: '奶瓶奶嘴',\n                key: '奶瓶奶嘴',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/5.png',\n                cat: 2\n            },\n            {\n                name: '孕妈用品',\n                key: '孕妈用品',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/6.png',\n                cat: 2\n            },\n            {\n                name: '宝宝用品',\n                key: '宝宝用品',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/7.png',\n                cat: 2\n            },\n            {\n                name: '婴童湿巾',\n                key: '湿巾',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/8.png',\n                cat: 2\n            },\n            {\n                name: '喂养洗护',\n                key: '洗护',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/9.png',\n                cat: 2\n            },\n            {\n                name: '婴童鞋靴',\n                key: '童鞋',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/10.png',\n                cat: 2\n            },\n            {\n                name: '口水巾',\n                key: '口水巾',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/11.png',\n                cat: 2\n            },\n            {\n                name: '营养辅食',\n                key: '营养',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/12.png',\n                cat: 2\n            },\n            {\n                name: '婴幼书籍',\n                key: '书籍',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/13.png',\n                cat: 2\n            },\n            {\n                name: '婴儿车',\n                key: '婴儿车',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/14.png',\n                cat: 2\n            }\n        ]\n    },\n    {\n        name: '箱包',\n        foods: [\n            {\n                name: '单肩包',\n                key: '单肩包',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/9/1.png',\n                cat: 0\n            },\n            {\n                name: '斜挎包',\n                key: '斜挎包',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/9/2.png',\n                cat: 0\n            },\n            {\n                name: '女包',\n                key: '女包',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/9/3.png',\n                cat: 0\n            },\n            {\n                name: '男包',\n                key: '男包',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/9/4.png',\n                cat: 0\n            },\n            {\n                name: '双肩包',\n                key: '双肩包',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/9/5.png',\n                cat: 0\n            },\n            {\n                name: '小方包',\n                key: '小方包',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/9/6.png',\n                cat: 0\n            },\n            {\n                name: '钱包',\n                key: '钱包',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/9/7.png',\n                cat: 0\n            },\n            {\n                name: '旅行箱包',\n                key: '旅行箱包',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/9/8.png',\n                cat: 0\n            },\n            {\n                name: '零钱包',\n                key: '零钱包',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/9/9.png',\n                cat: 0\n            },\n            {\n                name: '手提包',\n                key: '手提包',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/9/10.png',\n                cat: 0\n            },\n            {\n                name: '胸包',\n                key: '胸包',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/9/11.png',\n                cat: 0\n            }\n        ]\n    },\n    {\n        name: '内衣',\n        foods: [\n            {\n                name: '袜子',\n                key: '袜子',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/10/1.png',\n                cat: 11\n            },\n            {\n                name: '吊带背心',\n                key: '吊带背心',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/10/2.png',\n                cat: 11\n            },\n            {\n                name: '抹胸',\n                key: '抹胸',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/10/3.png',\n                cat: 11\n            },\n            {\n                name: '内裤',\n                key: '内裤',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/10/4.png',\n                cat: 11\n            },\n            {\n                name: '文胸',\n                key: '文胸',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/10/5.png',\n                cat: 11\n            },\n            {\n                name: '文胸套装',\n                key: '文胸套装',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/10/6.png',\n                cat: 11\n            },\n            {\n                name: '打底塑身',\n                key: '打底塑身',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/10/7.png',\n                cat: 11\n            },\n            {\n                name: '家居服',\n                key: '家居服',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/10/8.png',\n                cat: 11\n            },\n            {\n                name: '船袜',\n                key: '船袜',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/10/9.png',\n                cat: 11\n            },\n            {\n                name: '情侣睡衣',\n                key: '情侣睡衣',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/10/10.png',\n                cat: 11\n            },\n            {\n                name: '丝袜',\n                key: '丝袜',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/10/11.png',\n                cat: 11\n            }\n        ]\n    },\n    {\n        name: '文娱车品',\n        foods: [\n            {\n                name: '车市车品',\n                key: '车市车品',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/11/1.png',\n                cat: 7\n            },\n            {\n                name: '办公文具',\n                key: '办公文具',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/11/2.png',\n                cat: 7\n            },\n            {\n                name: '考试必备',\n                key: '考试必备',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/11/3.png',\n                cat: 7\n            },\n            {\n                name: '笔记本',\n                key: '笔记本',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/11/4.png',\n                cat: 7\n            },\n            {\n                name: '艺术礼品',\n                key: '礼品',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/11/5.png',\n                cat: 7\n            },\n            {\n                name: '书写工具',\n                key: '书写工具',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/11/6.png',\n                cat: 7\n            },\n            {\n                name: '车载电器',\n                key: '车载电器',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/11/7.png',\n                cat: 7\n            },\n            {\n                name: '图书音像',\n                key: '图书音像',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/11/8.png',\n                cat: 7\n            },\n            {\n                name: '画具画材',\n                key: '画具画材',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/11/9.png',\n                cat: 7\n            }\n        ]\n    },\n    {\n        name: '配饰',\n        foods: [\n            {\n                name: '太阳镜',\n                key: '太阳镜',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/12/1.png',\n                cat: 0\n            },\n            {\n                name: '皮带',\n                key: '皮带',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/12/2.png',\n                cat: 0\n            },\n            {\n                name: '棒球帽',\n                key: '棒球帽',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/12/3.png',\n                cat: 0\n            },\n            {\n                name: '手表',\n                key: '手表',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/12/4.png',\n                cat: 0\n            },\n            {\n                name: '发饰',\n                key: '发饰',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/12/5.png',\n                cat: 0\n            },\n            {\n                name: '项链',\n                key: '项链',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/12/6.png',\n                cat: 0\n            },\n            {\n                name: '手饰',\n                key: '手饰',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/12/7.png',\n                cat: 0\n            },\n            {\n                name: '耳环',\n                key: '耳环',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/12/8.png',\n                cat: 0\n            },\n            {\n                name: '帽子丝巾',\n                key: '帽子丝巾',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/12/9.png',\n                cat: 0\n            },\n            {\n                name: '眼镜墨镜',\n                key: '眼镜墨镜',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/12/10.png',\n                cat: 0\n            },\n            {\n                name: '发带发箍',\n                key: '发带发箍',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/12/11.png',\n                cat: 0\n            }\n        ]\n    },\n    {\n        name: '家装家纺',\n        foods: [\n            {\n                name: '家居饰品',\n                key: '家居饰品',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/1.png',\n                cat: 0\n            },\n            {\n                name: '凉席',\n                key: '凉席',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/2.png',\n                cat: 0\n            },\n            {\n                name: '背枕靠枕',\n                key: '靠枕',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/3.png',\n                cat: 0\n            },\n            {\n                name: '床上用品',\n                key: '床上用品',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/4.png',\n                cat: 0\n            },\n            {\n                name: '摆件',\n                key: '摆件',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/5.png',\n                cat: 0\n            },\n            {\n                name: '四件套',\n                key: '四件套',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/6.png',\n                cat: 0\n            },\n            {\n                name: '装饰品',\n                key: '装饰品',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/7.png',\n                cat: 0\n            },\n            {\n                name: '卫浴用品',\n                key: '卫浴',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/8.png',\n                cat: 0\n            },\n            {\n                name: '家居家装',\n                key: '家具',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/9.png',\n                cat: 0\n            },\n            {\n                name: '蚊帐',\n                key: '蚊帐',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/10.png',\n                cat: 0\n            },\n            {\n                name: '墙纸贴纸',\n                key: '墙纸',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/11.png',\n                cat: 0\n            },\n            {\n                name: '空调被',\n                key: '空调被',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/12.png',\n                cat: 0\n            }\n        ]\n    },\n    {\n        name: '户外运动',\n        foods: [\n            {\n                name: '游泳装备',\n                key: '游泳',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/14/1.png',\n                cat: 0\n            },\n            {\n                name: '泳镜',\n                key: '泳镜',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/14/2.png',\n                cat: 0\n            },\n            {\n                name: '户外装备',\n                key: '户外',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/14/3.png',\n                cat: 0\n            },\n            {\n                name: '健身服饰',\n                key: '健身',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/14/4.png',\n                cat: 0\n            },\n            {\n                name: '泳衣',\n                key: '泳衣',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/14/5.png',\n                cat: 0\n            },\n            {\n                name: '瑜伽垫',\n                key: '瑜伽垫',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/14/6.png',\n                cat: 0\n            },\n            {\n                name: '瑜伽用品',\n                key: '瑜伽',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/14/7.png',\n                cat: 0\n            },\n            {\n                name: '健身装备',\n                key: '健身',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/14/8.png',\n                cat: 0\n            },\n            {\n                name: '球迷用品',\n                key: '球迷',\n                icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/14/9.png',\n                cat: 0\n            }\n        ]\n    }\n];\n"
  },
  {
    "path": "src/common/constant.ts",
    "content": "import { versionName as appVersion } from '../manifest.json';\nimport { version as uViewProVersion, buildDate, releaseDate } from '../../package.json';\n\nexport const APP_INFO: {\n    name: string;\n    version: string;\n    buildTime: string;\n    platform: string;\n} = {\n    name: 'uViewPro(跨平台UI组件库)',\n    version: appVersion,\n    buildTime: buildDate,\n    platform: getPlatform()\n};\n\nexport const UVIEW_PRO_INFO = {\n    name: 'uview-pro',\n    version: uViewProVersion,\n    buildTime: releaseDate\n};\n\nfunction getPlatform() {\n    let platform = uni.getSystemInfoSync().platform;\n    if (platform) {\n        return platform;\n    }\n    // #ifdef H5\n    platform = 'H5';\n    // #endif\n    // #ifdef MP-WEIXIN\n    platform = '微信小程序';\n    // #endif\n    // #ifdef MP-ALIPAY\n    platform = '支付宝小程序';\n    // #endif\n    // #ifdef APP-PLUS\n    platform = 'App';\n    // #endif\n    // #ifdef APP-HARMONY\n    platform = 'HarmonyOS';\n    // #endif\n    platform = '未知平台';\n    return platform;\n}\n\ntype PlatformType = 'H5' | 'weixin' | 'alipay' | 'toutiao' | 'App' | 'HarmonyOS';\nexport function isPlatform(value: PlatformType | PlatformType[]): boolean {\n    let platform = '';\n    // #ifdef H5\n    platform = 'H5';\n    // #endif\n    // #ifdef MP-WEIXIN\n    platform = 'weixin';\n    // #endif\n    // #ifdef MP-ALIPAY\n    platform = 'alipay';\n    // #endif\n    // #ifdef MP-TOUTIAO\n    platform = 'toutiao';\n    // #endif\n    // #ifdef APP-PLUS\n    platform = 'App';\n    // #endif\n    // #ifdef APP-HARMONY\n    platform = 'HarmonyOS';\n    // #endif\n    return Array.isArray(value)\n        ? value.some(v => v.toLowerCase() === platform.toLowerCase())\n        : platform.toLowerCase() === value.toLowerCase();\n}\n\nexport const ONBOARDING_STORAGE_BASE_KEY = `guide-onboarded-${APP_INFO.version}`;\n\nexport const GUIDE_TABS_KEY = `guide-page-tabs-${APP_INFO.version}`;\n\nexport const GUIDE_FAB_KEY = `guide-page-fab-${APP_INFO.version}`;\n\nexport const GUIDE_TABBAR_KEY = `guide-page-tabbar-${APP_INFO.version}`;\n\nexport const GUIDE_THEME_SWITCHER_KEY = `guide-theme-switcher-${APP_INFO.version}`;\n\nexport const GUIDE_EXPERIENCE_KEY = `guide-experience-entry-${APP_INFO.version}`;\n"
  },
  {
    "path": "src/common/demo-experience.config.json",
    "content": "{\n    \"component-image\": {\n        \"tasks\": [\n            {\n                \"key\": \"status\",\n                \"title\": \"切换不同加载状态\",\n                \"desc\": \"体验加载成功 / 加载中 / 加载失败三种反馈效果\"\n            },\n            {\n                \"key\": \"slot\",\n                \"title\": \"自定义占位反馈\",\n                \"desc\": \"启用自定义加载中与错误插槽，观察差异\"\n            },\n            {\n                \"key\": \"shape\",\n                \"title\": \"调整图片形状\",\n                \"desc\": \"在方形与圆形样式之间切换，感受视觉变化\"\n            },\n            {\n                \"key\": \"source\",\n                \"title\": \"切换资源来源\",\n                \"desc\": \"在网络图片与本地图片之间切换，体验加载表现\"\n            }\n        ]\n    },\n    \"component-button\": {\n        \"tasks\": [\n            { \"key\": \"type\", \"title\": \"切换按钮主题\", \"desc\": \"体验 primary / error / warning / success 不同主题风格\" },\n            { \"key\": \"size\", \"title\": \"调整按钮尺寸\", \"desc\": \"在默认 / 中等 / 迷你之间切换，感受占位变化\" },\n            { \"key\": \"shape\", \"title\": \"改变按钮形状\", \"desc\": \"在直角与圆角之间切换，观察视觉差异\" },\n            { \"key\": \"plain\", \"title\": \"体验镂空样式\", \"desc\": \"在是否镂空之间切换，体验不同信息层级\" },\n            { \"key\": \"ripple\", \"title\": \"水波纹动效体验\", \"desc\": \"开启/关闭水波纹，再点击按钮观察动效\" },\n            { \"key\": \"hairLine\", \"title\": \"细边框显示\", \"desc\": \"打开或关闭细边框，感受边界勾勒效果\" },\n            { \"key\": \"loading\", \"title\": \"加载状态反馈\", \"desc\": \"切换按钮加载状态，体验“执行中”反馈样式\" }\n        ]\n    },\n    \"component-avatar\": {\n        \"tasks\": [\n            { \"key\": \"mode\", \"title\": \"切换头像形态\", \"desc\": \"在圆形与圆角方形之间来回体验\" },\n            { \"key\": \"sex\", \"title\": \"调整性别标识\", \"desc\": \"切换男 / 女 / 不显示三种性别标识\" },\n            { \"key\": \"level\", \"title\": \"显示/隐藏等级\", \"desc\": \"控制等级角标的显示与否，感受信息密度变化\" },\n            { \"key\": \"content\", \"title\": \"自定义头像内容\", \"desc\": \"在图片头像与纯文字头像之间切换\" },\n            { \"key\": \"size\", \"title\": \"调整头像尺寸\", \"desc\": \"尝试 large / default / mini / 自定义像素四种尺寸\" }\n        ]\n    }\n}\n"
  },
  {
    "path": "src/common/demo.scss",
    "content": "page {\n    background-color: $u-bg-white;\n    width: 100%;\n    height: 100vh;\n}\n/* #ifndef APP-NVUE */\nview,\ntext {\n    box-sizing: border-box;\n}\n/* #endif */\n\n/* start--演示页面使用的统一样式--start */\n.u-demo {\n    padding: 10px 20px 25px 20px;\n}\n\n.u-demo-wrap {\n    border-width: 1px;\n    border-color: $u-border-color;\n    border-style: dashed;\n    background-color: $u-bg-white;\n    padding: 20px 10px;\n    transition:\n        background-color 0.3s ease,\n        border-color 0.3s ease;\n}\n\n.u-demo-area {\n    text-align: center;\n}\n\n.u-no-demo-here {\n    color: $u-tips-color;\n    font-size: 13px;\n}\n\n.u-demo-result-line {\n    border-width: 1px;\n    border-color: $u-border-color;\n    border-style: dashed;\n    padding: 5px 20px;\n    margin-top: 30px;\n    border-radius: 5px;\n    background-color: rgba(var(--u-border-color-rgb), 0.2);\n    color: $u-content-color;\n    font-size: 16px;\n    /* #ifndef APP-NVUE */\n    word-break: break-word;\n    display: inline-block;\n    /* #endif */\n    text-align: left;\n}\n\n.u-demo-title,\n.u-config-title {\n    text-align: center;\n    font-size: 16px;\n    font-weight: bold;\n    margin-bottom: 20px;\n    color: $u-main-color;\n}\n\n.u-config-item {\n    margin-top: 25px;\n}\n\n.u-config-title {\n    margin-top: 20px;\n    padding-bottom: 5px;\n}\n\n.u-item-title {\n    position: relative;\n    font-size: 15px;\n    padding-left: 8px;\n    line-height: 1;\n    margin-bottom: 11px;\n    color: $u-main-color;\n}\n\n.u-item-title:after {\n    position: absolute;\n    width: 4px;\n    top: -1px;\n    height: 16px;\n    /* #ifndef APP-NVUE */\n    content: '';\n    /* #endif */\n    left: 0;\n    border-radius: 10px;\n    background-color: $u-content-color;\n}\n\n.u-block {\n    padding: 14px;\n    &__section {\n        margin-bottom: 10px;\n    }\n    &__title {\n        margin-top: 10px;\n        font-size: 15px;\n        color: $u-content-color;\n        margin-bottom: 10px;\n    }\n    &__flex {\n        /* #ifndef APP-NVUE */\n        display: flex;\n        /* #endif */\n    }\n}\n\n// 使用了cell组件的icon图片样式\n.u-cell-icon {\n    width: 36rpx;\n    height: 36rpx;\n    margin-right: 8rpx;\n}\n\n.u-page {\n    padding: 15px 15px 40px 15px;\n}\n\n.u-demo-block {\n    flex: 1;\n    margin-bottom: 23px;\n\n    &__content {\n        @include vue-flex(column);\n    }\n\n    &__title {\n        font-size: 14px;\n        color: $u-tips-color;\n        margin-bottom: 8px;\n        @include vue-flex;\n    }\n}\n/* end--演示页面使用的统一样式--end */\n"
  },
  {
    "path": "src/common/http.interceptor.ts",
    "content": "import type { RequestConfig, RequestInterceptor, RequestMeta, RequestOptions } from 'uview-pro';\n\n// 示例：演示如何使用token\nconst token = '';\n// 演示\nlet baseUrl = 'https://env-00jxty5jnvo5-static.normal.cloudstatic.cn';\n// #ifdef APP\n// baseUrl = '/static/app';\n// #endif\n\n// 演示\nfunction logout() {\n    return new Promise(resolve => {\n        setTimeout(() => {\n            resolve(true);\n        }, 1000);\n    });\n}\n\n// 全局配置\nconst httpRequestConfig: RequestConfig = {\n    baseUrl,\n    header: {\n        'content-type': 'application/json'\n    },\n    timeout: 50000,\n    meta: {\n        originalData: true,\n        toast: true,\n        loading: true\n    }\n};\n\n// 请求/响应拦截器\nconst httpInterceptor: RequestInterceptor = {\n    // 请求拦截器\n    request: (config: RequestOptions) => {\n        // console.log('请求拦截器', config);\n        const meta: RequestMeta = config.meta || {};\n        meta.loading && showLoading();\n        if (token) {\n            config.header.Authorization = `Bearer ${token}`;\n        }\n        return config;\n    },\n    // 响应拦截器\n    response: async (response: any) => {\n        // console.log('响应拦截器', response);\n        const meta: RequestMeta = response.config?.meta || {};\n        meta.loading && hideLoading();\n        const { statusCode, data: rawData, errMsg } = response as any;\n        // 网络错误\n        if (errMsg && errMsg.includes('Failed to connect')) {\n            meta.toast && showToast('网络错误', 'error');\n            throw new Error('网络错误');\n        }\n        if (errMsg && errMsg.includes('request:fail')) {\n            meta.toast && showToast('请求错误：未知', 'error');\n            throw new Error('请求错误：未知');\n        }\n        // 请求错误\n        if (!(statusCode >= 200 && statusCode < 300)) {\n            const errorMessage = `请求错误[${statusCode}]`;\n            meta.toast && showToast(errorMessage, 'error');\n            throw new Error(`${errorMessage}：${errMsg}`);\n        }\n        // 业务逻辑错误：登录过期/状态码不正确\n        // 这里仅为演示，根据实际业务确定\n        // const { code, msg } = rawData as any;\n        // if (code === 403 || code === 401) {\n        //     meta.toast && showToast('登录已过期', 'error');\n        //     await logout();\n        //     setTimeout(() => {\n        //         uni.reLaunch({ url: '/pages/login/login' });\n        //     }, 1000);\n        //     throw new Error(`请求错误[${code}]：${msg}`);\n        // } else if (!(code >= 200 && code < 300)) {\n        //     meta.toast && showToast(msg, 'error', { duration: 2500 });\n        //     throw new Error(`请求错误[${code}]：${msg}`);\n        // }\n        return rawData;\n    }\n};\n\n// 显示加载中，可以替换为uview-pro的u-loading-popup组件\nfunction showLoading() {\n    uni.showLoading({\n        title: '加载中...',\n        mask: true\n    });\n}\n\n// 隐藏加载中，可以替换为uview-pro的u-loading-popup组件\nfunction hideLoading() {\n    // 代码示例使用settimeout，仅为演示，实际开发中去掉\n    setTimeout(() => {\n        uni.hideLoading();\n    }, 1000);\n}\n\n// 显示toast，可以替换为uview-pro的u-toast组件\nfunction showToast(\n    title = '',\n    icon: 'success' | 'error' | 'none' = 'none',\n    options: { duration: number } = { duration: 2000 }\n) {\n    if (title.length === 0) {\n        return;\n    }\n    // 代码示例使用settimeout，仅为演示，实际开发中去掉\n    setTimeout(() => {\n        uni.showToast({\n            title,\n            icon: title.length && title.length > 7 ? 'none' : icon,\n            duration: options.duration || 2000\n        });\n    }, 1000);\n}\n\n// 导出\nexport { httpInterceptor, httpRequestConfig };\n"
  },
  {
    "path": "src/common/iconfont.css",
    "content": "@font-face {\n    font-family: 'custom-icon'; /* Project id 5067119 */\n    src: url('data:application/x-font-woff2;charset=utf-8;base64,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')\n        format('woff2');\n}\n\n.custom-icon {\n    font-family: 'custom-icon' !important;\n    font-size: 16px;\n    font-style: normal;\n    -webkit-font-smoothing: antialiased;\n    -moz-osx-font-smoothing: grayscale;\n}\n\n.custom-icon-map-route:before {\n    content: '\\e660';\n}\n\n.custom-icon-compass:before {\n    content: '\\e731';\n}\n\n.custom-icon-guide:before {\n    content: '\\e617';\n}\n\n.custom-icon-levels:before {\n    content: '\\e60d';\n}\n\n.custom-icon-eye:before {\n    content: '\\e68e';\n}\n\n.custom-icon-target:before {\n    content: '\\ee64';\n}\n\n.custom-icon-sparkles:before {\n    content: '\\ea28';\n}\n\n.custom-icon-file-text:before {\n    content: '\\ea2e';\n}\n\n.custom-icon-hand-sparkles:before {\n    content: '\\eb43';\n}\n\n.custom-icon-magic-sparkles:before {\n    content: '\\eb67';\n}\n\n.custom-icon-map-circle-fill:before {\n    content: '\\ebff';\n}\n\n.custom-icon-map-circle:before {\n    content: '\\ec00';\n}\n\n.custom-icon-sun:before {\n    content: '\\e712';\n}\n\n.custom-icon-theme-fill:before {\n    content: '\\e615';\n}\n\n.custom-icon-theme:before {\n    content: '\\e60c';\n}\n\n.custom-icon-star:before {\n    content: '\\fb33';\n}\n\n.custom-icon-template-fill:before {\n    content: '\\eac3';\n}\n\n.custom-icon-tool-fill:before {\n    content: '\\e785';\n}\n\n.custom-icon-about-fill:before {\n    content: '\\e79f';\n}\n\n.custom-icon-component-fill:before {\n    content: '\\e605';\n}\n\n.custom-icon-about:before {\n    content: '\\e7a8';\n}\n\n.custom-icon-template:before {\n    content: '\\e60f';\n}\n\n.custom-icon-component:before {\n    content: '\\e759';\n}\n\n.custom-icon-tool:before {\n    content: '\\e78e';\n}\n\n.custom-icon-auto:before {\n    content: '\\e772';\n}\n\n.custom-icon-moon:before {\n    content: '\\e609';\n}\n\n.custom-icon-layouts:before {\n    content: '\\e66e';\n}\n\n.custom-icon-input:before {\n    content: '\\e6fd';\n}\n\n.custom-icon-textarea:before {\n    content: '\\e871';\n}\n\n.custom-icon-pagination:before {\n    content: '\\e681';\n}\n\n.custom-icon-fab:before {\n    content: '\\e656';\n}\n\n.custom-icon-github:before {\n    content: '\\e885';\n}\n\n.custom-icon-rocket:before {\n    content: '\\e651';\n}\n\n.custom-icon-share1:before {\n    content: '\\e655';\n}\n\n.custom-icon-qq-circle-fill:before {\n    content: '\\e887';\n}\n\n.custom-icon-message:before {\n    content: '\\e66f';\n}\n\n.custom-icon-weixin:before {\n    content: '\\e608';\n}\n\n.custom-icon-gitee:before {\n    content: '\\e618';\n}\n\n.custom-icon-menu1:before {\n    content: '\\e706';\n}\n\n.custom-icon-order:before {\n    content: '\\e626';\n}\n\n.custom-icon-comment:before {\n    content: '\\e60a';\n}\n\n.custom-icon-address:before {\n    content: '\\e63e';\n}\n\n.custom-icon-login:before {\n    content: '\\e72a';\n}\n\n.custom-icon-keyboard:before {\n    content: '\\e64b';\n}\n\n.custom-icon-onekey:before {\n    content: '\\e607';\n}\n\n.custom-icon-usercenter:before {\n    content: '\\e678';\n}\n\n.custom-icon-city:before {\n    content: '\\e61d';\n}\n\n.custom-icon-order2:before {\n    content: '\\e603';\n}\n\n.custom-icon-coupon:before {\n    content: '\\e643';\n}\n\n.custom-icon-menu2:before {\n    content: '\\e604';\n}\n\n.custom-icon-tools:before {\n    content: '\\e6cf';\n}\n\n.custom-icon-clone:before {\n    content: '\\e692';\n}\n\n.custom-icon-color:before {\n    content: '\\e601';\n}\n\n.custom-icon-time:before {\n    content: '\\e606';\n}\n\n.custom-icon-switch:before {\n    content: '\\e6c0';\n}\n\n.custom-icon-throttle:before {\n    content: '\\e64a';\n}\n\n.custom-icon-share:before {\n    content: '\\e64c';\n}\n\n.custom-icon-from:before {\n    content: '\\e60b';\n}\n\n.custom-icon-rect:before {\n    content: '\\e92f';\n}\n\n.custom-icon-network:before {\n    content: '\\e99b';\n}\n\n.custom-icon-route:before {\n    content: '\\e65e';\n}\n\n.custom-icon-http:before {\n    content: '\\e616';\n}\n\n.custom-icon-test:before {\n    content: '\\e636';\n}\n\n.custom-icon-array:before {\n    content: '\\e659';\n}\n\n.custom-icon-merge:before {\n    content: '\\e75f';\n}\n\n.custom-icon-id:before {\n    content: '\\e648';\n}\n\n.custom-icon-random:before {\n    content: '\\e650';\n}\n\n.custom-icon-md5:before {\n    content: '\\e600';\n}\n\n.custom-icon-params:before {\n    content: '\\e625';\n}\n\n.custom-icon-trim:before {\n    content: '\\e602';\n}\n"
  },
  {
    "path": "src/common/index.list.ts",
    "content": "export default {\n    list: [\n        {\n            letter: 'A',\n            data: [\n                {\n                    name: '阿拉斯加',\n                    mobile: '13588889999',\n                    keyword: '阿拉斯加ABA13588889999'\n                },\n                {\n                    name: '阿克苏',\n                    mobile: '0551-4386721',\n                    keyword: '阿克苏AKESU0551-4386721'\n                },\n                {\n                    name: '阿拉善',\n                    mobile: '4008009100',\n                    keyword: '阿拉善ALASHAN4008009100'\n                },\n                {\n                    name: '阿勒泰',\n                    mobile: '13588889999',\n                    keyword: '阿勒泰ALETAI13588889999'\n                },\n                {\n                    name: '阿里',\n                    mobile: '13588889999',\n                    keyword: '阿里ALI13588889999'\n                },\n                {\n                    name: '安阳',\n                    mobile: '13588889999',\n                    keyword: '13588889999安阳ANYANG'\n                }\n            ]\n        },\n        {\n            letter: 'B',\n            data: [\n                {\n                    name: '白城',\n                    mobile: '该主子没有留电话~',\n                    keyword: '白城BAICHENG'\n                },\n                {\n                    name: '白山',\n                    mobile: '13588889999',\n                    keyword: '白山BAISHAN13588889999'\n                },\n                {\n                    name: '白银',\n                    mobile: '13588889999',\n                    keyword: '白银BAIYIN13588889999'\n                },\n                {\n                    name: '保定',\n                    mobile: '13588889999',\n                    keyword: '保定BAODING13588889999'\n                }\n            ]\n        },\n        {\n            letter: 'C',\n            data: [\n                {\n                    name: '沧州',\n                    mobile: '13588889999',\n                    keyword: '沧州CANGZHOU13588889999'\n                },\n                {\n                    name: '长春',\n                    mobile: '13588889999',\n                    keyword: '长春CHANGCHUN13588889999'\n                }\n            ]\n        },\n        {\n            letter: 'D',\n            data: [\n                {\n                    name: '大理',\n                    mobile: '13588889999',\n                    keyword: '大理DALI13588889999'\n                },\n                {\n                    name: '大连',\n                    mobile: '13588889999',\n                    keyword: '大连DALIAN13588889999'\n                }\n            ]\n        },\n        {\n            letter: 'E',\n            data: [\n                {\n                    name: '鄂尔多斯',\n                    mobile: '13588889999',\n                    keyword: '鄂尔多斯EERDUOSI13588889999'\n                },\n                {\n                    name: '恩施',\n                    mobile: '13588889999',\n                    keyword: '恩施ENSHI13588889999'\n                },\n                {\n                    name: '鄂州',\n                    mobile: '13588889999',\n                    keyword: '鄂州EZHOU13588889999'\n                }\n            ]\n        },\n        {\n            letter: 'F',\n            data: [\n                {\n                    name: '防城港',\n                    mobile: '该主子没有留电话~',\n                    keyword: '防城港FANGCHENGGANG'\n                },\n                {\n                    name: '抚顺',\n                    mobile: '13588889999',\n                    keyword: '抚顺FUSHUN13588889999'\n                },\n                {\n                    name: '阜新',\n                    mobile: '13588889999',\n                    keyword: '阜新FUXIN13588889999'\n                },\n                {\n                    name: '阜阳',\n                    mobile: '13588889999',\n                    keyword: '阜阳FUYANG13588889999'\n                },\n                {\n                    name: '抚州',\n                    mobile: '13588889999',\n                    keyword: '抚州FUZHOU13588889999'\n                },\n                {\n                    name: '福州',\n                    mobile: '13588889999',\n                    keyword: '福州FUZHOU13588889999'\n                }\n            ]\n        },\n        {\n            letter: 'G',\n            data: [\n                {\n                    name: '甘南',\n                    mobile: '13588889999',\n                    keyword: '甘南GANNAN13588889999'\n                },\n                {\n                    name: '赣州',\n                    mobile: '13588889999',\n                    keyword: '赣州GANZHOU13588889999'\n                },\n                {\n                    name: '甘孜',\n                    mobile: '13588889999',\n                    keyword: '甘孜GANZI13588889999'\n                }\n            ]\n        },\n        {\n            letter: 'H',\n            data: [\n                {\n                    name: '哈尔滨',\n                    mobile: '13588889999',\n                    keyword: '哈尔滨HAERBIN13588889999'\n                },\n                {\n                    name: '海北',\n                    mobile: '13588889999',\n                    keyword: '海北HAIBEI13588889999'\n                },\n                {\n                    name: '海东',\n                    mobile: '13588889999',\n                    keyword: '海东HAIDONG13588889999'\n                },\n                {\n                    name: '海口',\n                    mobile: '13588889999',\n                    keyword: '海口HAIKOU13588889999'\n                }\n            ]\n        },\n        {\n            letter: 'I',\n            data: [\n                {\n                    name: 'ice',\n                    mobile: '13588889999',\n                    keyword: '佳木斯JIAMUSI13588889999'\n                }\n            ]\n        },\n        {\n            letter: 'J',\n            data: [\n                {\n                    name: '佳木斯',\n                    mobile: '13588889999',\n                    keyword: '佳木斯JIAMUSI13588889999'\n                },\n                {\n                    name: '吉安',\n                    mobile: '13588889999',\n                    keyword: '吉安JIAN13588889999'\n                },\n                {\n                    name: '江门',\n                    mobile: '13588889999',\n                    keyword: '江门JIANGMEN13588889999'\n                }\n            ]\n        },\n        {\n            letter: 'K',\n            data: [\n                {\n                    name: '开封',\n                    mobile: '13588889999',\n                    keyword: '开封KAIFENG13588889999'\n                },\n                {\n                    name: '喀什',\n                    mobile: '13588889999',\n                    keyword: '喀什KASHI13588889999'\n                },\n                {\n                    name: '克拉玛依',\n                    mobile: '13588889999',\n                    keyword: '克拉玛依KELAMAYI13588889999'\n                }\n            ]\n        },\n        {\n            letter: 'L',\n            data: [\n                {\n                    name: '来宾',\n                    mobile: '13588889999',\n                    keyword: '来宾LAIBIN13588889999'\n                },\n                {\n                    name: '兰州',\n                    mobile: '13588889999',\n                    keyword: '兰州LANZHOU13588889999'\n                },\n                {\n                    name: '拉萨',\n                    mobile: '13588889999',\n                    keyword: '拉萨LASA13588889999'\n                },\n                {\n                    name: '乐山',\n                    mobile: '13588889999',\n                    keyword: '乐山LESHAN13588889999'\n                },\n                {\n                    name: '凉山',\n                    mobile: '13588889999',\n                    keyword: '凉山LIANGSHAN13588889999'\n                },\n                {\n                    name: '连云港',\n                    mobile: '13588889999',\n                    keyword: '连云港LIANYUNGANG13588889999'\n                },\n                {\n                    name: '聊城',\n                    mobile: '18322223333',\n                    keyword: '聊城LIAOCHENG18322223333'\n                },\n                {\n                    name: '辽阳',\n                    mobile: '18322223333',\n                    keyword: '辽阳LIAOYANG18322223333'\n                },\n                {\n                    name: '辽源',\n                    mobile: '18322223333',\n                    keyword: '辽源LIAOYUAN18322223333'\n                },\n                {\n                    name: '丽江',\n                    mobile: '18322223333',\n                    keyword: '丽江LIJIANG18322223333'\n                },\n                {\n                    name: '临沧',\n                    mobile: '18322223333',\n                    keyword: '临沧LINCANG18322223333'\n                },\n                {\n                    name: '临汾',\n                    mobile: '18322223333',\n                    keyword: '临汾LINFEN18322223333'\n                },\n                {\n                    name: '临夏',\n                    mobile: '18322223333',\n                    keyword: '临夏LINXIA18322223333'\n                },\n                {\n                    name: '临沂',\n                    mobile: '18322223333',\n                    keyword: '临沂LINYI18322223333'\n                },\n                {\n                    name: '林芝',\n                    mobile: '18322223333',\n                    keyword: '林芝LINZHI18322223333'\n                },\n                {\n                    name: '丽水',\n                    mobile: '18322223333',\n                    keyword: '丽水LISHUI18322223333'\n                }\n            ]\n        },\n        {\n            letter: 'M',\n            data: [\n                {\n                    name: '眉山',\n                    mobile: '15544448888',\n                    keyword: '眉山MEISHAN15544448888'\n                },\n                {\n                    name: '梅州',\n                    mobile: '15544448888',\n                    keyword: '梅州MEIZHOU15544448888'\n                },\n                {\n                    name: '绵阳',\n                    mobile: '15544448888',\n                    keyword: '绵阳MIANYANG15544448888'\n                },\n                {\n                    name: '牡丹江',\n                    mobile: '15544448888',\n                    keyword: '牡丹江MUDANJIANG15544448888'\n                }\n            ]\n        },\n        {\n            letter: 'N',\n            data: [\n                {\n                    name: '南昌',\n                    mobile: '15544448888',\n                    keyword: '南昌NANCHANG15544448888'\n                },\n                {\n                    name: '南充',\n                    mobile: '15544448888',\n                    keyword: '南充NANCHONG15544448888'\n                },\n                {\n                    name: '南京',\n                    mobile: '15544448888',\n                    keyword: '南京NANJING15544448888'\n                },\n                {\n                    name: '南宁',\n                    mobile: '15544448888',\n                    keyword: '南宁NANNING15544448888'\n                },\n                {\n                    name: '南平',\n                    mobile: '15544448888',\n                    keyword: '南平NANPING15544448888'\n                }\n            ]\n        },\n        {\n            letter: 'O',\n            data: [\n                {\n                    name: '欧阳',\n                    mobile: '15544448888',\n                    keyword: '欧阳ouyang15544448888'\n                }\n            ]\n        },\n        {\n            letter: 'P',\n            data: [\n                {\n                    name: '盘锦',\n                    mobile: '15544448888',\n                    keyword: '盘锦PANJIN15544448888'\n                },\n                {\n                    name: '攀枝花',\n                    mobile: '15544448888',\n                    keyword: '攀枝花PANZHIHUA15544448888'\n                },\n                {\n                    name: '平顶山',\n                    mobile: '15544448888',\n                    keyword: '平顶山PINGDINGSHAN15544448888'\n                },\n                {\n                    name: '平凉',\n                    mobile: '15544448888',\n                    keyword: '平凉PINGLIANG15544448888'\n                },\n                {\n                    name: '萍乡',\n                    mobile: '15544448888',\n                    keyword: '萍乡PINGXIANG15544448888'\n                },\n                {\n                    name: '普洱',\n                    mobile: '15544448888',\n                    keyword: '普洱PUER15544448888'\n                },\n                {\n                    name: '莆田',\n                    mobile: '15544448888',\n                    keyword: '莆田PUTIAN15544448888'\n                },\n                {\n                    name: '濮阳',\n                    mobile: '15544448888',\n                    keyword: '濮阳PUYANG15544448888'\n                }\n            ]\n        },\n        {\n            letter: 'Q',\n            data: [\n                {\n                    name: '黔东南',\n                    mobile: '15544448888',\n                    keyword: '黔东南QIANDONGNAN15544448888'\n                },\n                {\n                    name: '黔南',\n                    mobile: '15544448888',\n                    keyword: '黔南QIANNAN15544448888'\n                },\n                {\n                    name: '黔西南',\n                    mobile: '15544448888',\n                    keyword: '黔西南QIANXINAN15544448888'\n                }\n            ]\n        },\n        {\n            letter: 'R',\n            data: [\n                {\n                    name: '日喀则',\n                    mobile: '15544448888',\n                    keyword: '日喀则RIKAZE15544448888'\n                },\n                {\n                    name: '日照',\n                    mobile: '15544448888',\n                    keyword: '日照RIZHAO15544448888'\n                }\n            ]\n        },\n        {\n            letter: 'S',\n            data: [\n                {\n                    name: '三门峡',\n                    mobile: '15544448888',\n                    keyword: '三门峡SANMENXIA15544448888'\n                },\n                {\n                    name: '三明',\n                    mobile: '15544448888',\n                    keyword: '三明SANMING15544448888'\n                },\n                {\n                    name: '三沙',\n                    mobile: '15544448888',\n                    keyword: '三沙SANSHA15544448888'\n                }\n            ]\n        },\n        {\n            letter: 'T',\n            data: [\n                {\n                    name: '塔城',\n                    mobile: '15544448888',\n                    keyword: '塔城TACHENG15544448888'\n                },\n                {\n                    name: '漯河',\n                    mobile: '15544448888',\n                    keyword: '漯河TAHE15544448888'\n                },\n                {\n                    name: '泰安',\n                    mobile: '15544448888',\n                    keyword: '泰安TAIAN15544448888'\n                }\n            ]\n        },\n        {\n            letter: 'W',\n            data: [\n                {\n                    name: '潍坊',\n                    mobile: '15544448888',\n                    keyword: '潍坊WEIFANG15544448888'\n                },\n                {\n                    name: '威海',\n                    mobile: '15544448888',\n                    keyword: '威海WEIHAI15544448888'\n                },\n                {\n                    name: '渭南',\n                    mobile: '15544448888',\n                    keyword: '渭南WEINAN15544448888'\n                },\n                {\n                    name: '文山',\n                    mobile: '15544448888',\n                    keyword: '文山WENSHAN15544448888'\n                }\n            ]\n        },\n        {\n            letter: 'X',\n            data: [\n                {\n                    name: '厦门',\n                    mobile: '15544448888',\n                    keyword: '厦门XIAMEN15544448888'\n                },\n                {\n                    name: '西安',\n                    mobile: '15544448888',\n                    keyword: '西安XIAN15544448888'\n                },\n                {\n                    name: '湘潭',\n                    mobile: '15544448888',\n                    keyword: '湘潭XIANGTAN15544448888'\n                }\n            ]\n        },\n        {\n            letter: 'Y',\n            data: [\n                {\n                    name: '雅安',\n                    mobile: '15544448888',\n                    keyword: '雅安YAAN15544448888'\n                },\n                {\n                    name: '延安',\n                    mobile: '15544448888',\n                    keyword: '延安YANAN15544448888'\n                },\n                {\n                    name: '延边',\n                    mobile: '15544448888',\n                    keyword: '延边YANBIAN15544448888'\n                },\n                {\n                    name: '盐城',\n                    mobile: '15544448888',\n                    keyword: '盐城YANCHENG15544448888'\n                }\n            ]\n        },\n        {\n            letter: 'Z',\n            data: [\n                {\n                    name: '枣庄',\n                    mobile: '15544448888',\n                    keyword: '枣庄ZAOZHUANG15544448888'\n                },\n                {\n                    name: '张家界',\n                    mobile: '15544448888',\n                    keyword: '张家界ZHANGJIAJIE15544448888'\n                },\n                {\n                    name: '张家口',\n                    mobile: '15544448888',\n                    keyword: '张家口ZHANGJIAKOU15544448888'\n                }\n            ]\n        },\n        {\n            letter: '#',\n            data: [\n                {\n                    name: '其他',\n                    mobile: '16666666666',\n                    keyword: 'echo16666666666'\n                }\n            ]\n        }\n    ]\n};\n"
  },
  {
    "path": "src/common/request.ts",
    "content": "import { deepMerge } from 'uview-pro';\n\n/**\n * 请求配置项Meta类型定义\n */\nexport interface RequestMeta {\n    toast?: boolean;\n    loading?: boolean;\n    originalData?: boolean;\n    [key: string]: any;\n}\n\n/**\n * 请求配置项类型定义\n */\nexport interface RequestConfig {\n    baseUrl?: string;\n    header?: Record<string, any>;\n    method?: string;\n    dataType?: string;\n    responseType?: string;\n    timeout?: number;\n    meta?: RequestMeta;\n    [key: string]: any;\n}\n\n/**\n * 忽略的请求参数类型定义\n */\nconst IGNORE_REQUEST_KEYS = ['baseUrl', 'meta'];\n\n/**\n * 请求拦截器类型定义\n */\nexport interface RequestInterceptor {\n    request?: ((options: RequestOptions) => RequestOptions | false) | null;\n    response?: ((response: any) => any | false) | null;\n}\n\n/**\n * 请求参数类型定义\n */\nexport interface RequestOptions {\n    url: string;\n    header: Record<string, any>;\n    method: 'GET' | 'POST' | 'OPTIONS' | 'HEAD' | 'PUT' | 'DELETE' | 'TRACE' | 'CONNECT';\n    data?: any;\n    dataType?: string;\n    responseType?: string;\n    params?: Record<string, any>;\n    complete?: (response: any) => void;\n    meta?: RequestMeta;\n    [key: string]: any;\n}\n\nexport class Request {\n    public config: RequestConfig;\n    public interceptor: RequestInterceptor;\n    public options?: RequestOptions;\n    // per-request storage to avoid concurrent overwrites of instance-level `options`\n    private _requestMap: Map<number, RequestOptions> = new Map();\n    private _taskMap: Map<number, any> = new Map(); // store uni.request task for abort\n    private _rejectMap: Map<number, (reason?: any) => void> = new Map();\n    private _reqId = 0;\n\n    constructor() {\n        this.config = {\n            baseUrl: '', // 请求的根域名\n            header: {}, // 默认的请求头\n            method: 'POST', // 请求方式\n            dataType: 'json', // 设置为json，返回后uni.request会对数据进行一次JSON.parse\n            responseType: 'text', // 此参数无需处理，因为5+和支付宝小程序不支持，默认为text即可\n            timeout: 60000,\n            meta: {\n                originalData: true, // 是否在拦截器中返回服务端的原始数据，见文档说明\n                toast: false, // 是否在请求出错时，弹出toast\n                loading: false // 是否显示加载中\n            }\n        };\n        this.interceptor = {\n            request: null,\n            response: null\n        };\n    }\n    /**\n     * 返回当前未完成请求的快照（用于调试）\n     * 返回数组，元素为 { id, options } 的浅拷贝，不会暴露内部 Map 引用\n     */\n    public getPendingRequestOptions(): Array<{ id: number; options: RequestOptions }> {\n        const result: Array<{ id: number; options: RequestOptions }> = [];\n        for (const [id, opts] of this._requestMap.entries()) {\n            result.push({ id, options: { ...opts } });\n        }\n        return result;\n    }\n    /**\n     * 按 id 取消请求（如果还在 pending）\n     * 返回取消结果和是否已发送（sent）\n     */\n    public cancelRequestById(id: number): { cancelled: boolean; sent: boolean } {\n        const task = this._taskMap.get(id);\n        const reject = this._rejectMap.get(id);\n        let cancelled = false;\n        let sent = false;\n        try {\n            if (task) {\n                sent = true;\n                if (typeof task.abort === 'function') {\n                    task.abort();\n                    cancelled = true;\n                }\n            }\n        } catch (e) {\n            // ignore abort errors but still attempt reject/cleanup\n        }\n        if (reject) {\n            try {\n                reject(new Error('Request cancelled by id'));\n            } catch (e) {\n                // swallow\n            }\n            cancelled = true;\n        }\n        // cleanup maps\n        this._taskMap.delete(id);\n        this._rejectMap.delete(id);\n        this._requestMap.delete(id);\n        return { cancelled, sent };\n    }\n\n    /**\n     * 取消所有未完成的请求，返回每个请求的取消结果\n     */\n    public cancelAllPendingRequests(): Array<{ id: number; cancelled: boolean; sent: boolean }> {\n        const results: Array<{ id: number; cancelled: boolean; sent: boolean }> = [];\n        const ids = Array.from(this._requestMap.keys());\n        for (const id of ids) {\n            const res = this.cancelRequestById(id);\n            results.push({ id, cancelled: res.cancelled, sent: res.sent });\n        }\n        return results;\n    }\n\n    /**\n     * 根据 URL 或正则取消匹配的未完成请求\n     * @param urlOrRegex 字符串或 RegExp，字符串支持精确匹配或作为子串匹配\n     * @returns 每个被尝试取消请求的结果数组\n     */\n    public cancelRequestsByUrl(\n        urlOrRegex: string | RegExp\n    ): Array<{ id: number; url: string; cancelled: boolean; sent: boolean }> {\n        const results: Array<{ id: number; url: string; cancelled: boolean; sent: boolean }> = [];\n        const matcher =\n            typeof urlOrRegex === 'string'\n                ? (u: string) => u === urlOrRegex || u.endsWith(urlOrRegex) || u.indexOf(urlOrRegex) !== -1\n                : (u: string) => (urlOrRegex as RegExp).test(u);\n        for (const [id, opts] of this._requestMap.entries()) {\n            const u = opts?.url || '';\n            try {\n                if (matcher(u)) {\n                    const res = this.cancelRequestById(id);\n                    results.push({ id, url: u, cancelled: res.cancelled, sent: res.sent });\n                }\n            } catch (e) {\n                results.push({ id, url: u, cancelled: false, sent: Boolean(this._taskMap.get(id)) });\n            }\n        }\n        return results;\n    }\n    /**\n     * 将全局配置合并到本次请求的 options 中\n     * - 忽略 IGNORE_REQUEST_KEYS 中的字段（如 meta）\n     * - 对 header 使用深合并（全局 header 为默认，options.header 优先）\n     * - 对对象类型的字段尝试深合并，基础类型以 options 值优先\n     * - 处理 baseUrl：若存在全局 baseUrl 且 options.url 非完整 url（非 http 开头），则合并成完整 URL\n     */\n    private mergeGlobalConfigToOptions(options: RequestOptions): RequestOptions {\n        const mergedOptions: RequestOptions = { ...options };\n        for (const key of Object.keys(this.config)) {\n            if (IGNORE_REQUEST_KEYS.includes(key)) {\n                continue;\n            }\n            const cfgVal = this.config[key];\n            const optVal = options[key];\n\n            // 跳过未设置的全局配置\n            if (cfgVal === undefined) continue;\n\n            // header 需要做深合并，且以 options.header 为准覆盖同名属性\n            if (key === 'header') {\n                mergedOptions.header = deepMerge(cfgVal || {}, optVal || {});\n                continue;\n            }\n\n            // 针对 method 等枚举字符串，优先使用 options 中的值，否则使用全局配置\n            if (typeof cfgVal === 'string' || typeof cfgVal === 'number' || typeof cfgVal === 'boolean') {\n                mergedOptions[key] = optVal !== undefined ? optVal : cfgVal;\n                continue;\n            }\n\n            // 对对象类型的配置（如自定义扩展）尝试做深合并\n            if (typeof cfgVal === 'object' && !Array.isArray(cfgVal)) {\n                mergedOptions[key] = deepMerge(cfgVal || {}, optVal || {});\n                continue;\n            }\n\n            // 其他类型，若 options 未传入则使用全局配置\n            if (optVal === undefined) {\n                mergedOptions[key] = cfgVal;\n            }\n        }\n        // 如果存在 baseUrl，并且 options.url 为相对地址，则拼接成完整 url\n        const baseUrl = this.config.baseUrl;\n        if (\n            baseUrl &&\n            mergedOptions.url &&\n            typeof mergedOptions.url === 'string' &&\n            mergedOptions.url.indexOf('http') !== 0\n        ) {\n            mergedOptions.url =\n                baseUrl + (mergedOptions.url.indexOf('/') === 0 ? mergedOptions.url : `/${mergedOptions.url}`);\n        }\n        // 确保 url 存在，且为 string\n        if (!mergedOptions.url) {\n            mergedOptions.url = '';\n        }\n        return mergedOptions;\n    }\n    /**\n     * 验证并规范化 RequestOptions，返回规范化后的对象\n     * - 确保 url 为 string\n     * - 确保 method 为大写且在允许集合内；否则使用全局默认 method\n     * - 确保 header 为对象\n     */\n    private validateOptions(options: RequestOptions): RequestOptions {\n        const normalized: RequestOptions = { ...options };\n        // url\n        normalized.url = normalized.url == null ? '' : String(normalized.url);\n\n        // header\n        if (!normalized.header || typeof normalized.header !== 'object' || Array.isArray(normalized.header)) {\n            normalized.header = {};\n        }\n\n        // method\n        const allowedMethods = new Set(['GET', 'POST', 'OPTIONS', 'HEAD', 'PUT', 'DELETE', 'TRACE', 'CONNECT']);\n        if (normalized.method) {\n            const m = String(normalized.method).toUpperCase();\n            normalized.method = (allowedMethods.has(m) ? m : String(this.config.method || 'POST')) as any;\n        } else {\n            normalized.method = (String(this.config.method || 'POST').toUpperCase() as any) || 'POST';\n        }\n\n        // meta default\n        if (!normalized.meta || typeof normalized.meta !== 'object') {\n            normalized.meta = normalized.meta || {};\n        }\n\n        return normalized;\n    }\n    /**\n     * 设置全局默认配置\n     * @param customConfig 自定义配置\n     */\n    setConfig(customConfig: Partial<RequestConfig>): void {\n        this.config = deepMerge(this.config, customConfig);\n    }\n\n    /**\n     * 主要请求部分\n     * @param options 请求参数\n     */\n    request<T = unknown>(options: RequestOptions): Promise<T> {\n        // 合并 meta 配置，优先级：单次请求 > 全局\n        const mergedMeta: RequestMeta = {\n            ...this.config.meta,\n            ...(options.meta || {})\n        };\n        // 让 options.meta 传递到拦截器\n        options.meta = mergedMeta;\n        options.url = options.url || '';\n        options.params = options.params || {};\n        // 将全局配置合并到本次请求 options 中（注意忽略一些特殊字段如 baseUrl/meta）\n        options = this.mergeGlobalConfigToOptions(options);\n        // 对合并后的 options 做一次规范化校验\n        options = this.validateOptions(options);\n\n        if (this.interceptor.request && typeof this.interceptor.request === 'function') {\n            const interceptorRequest = this.interceptor.request(options);\n            // 保持兼容：原逻辑中若返回 falsy 则视为取消请求，返回一个 pending Promise\n            if (!interceptorRequest) {\n                return new Promise(() => {});\n            }\n            // 若返回对象，则校验并使用拦截器返回的 options\n            if (typeof interceptorRequest === 'object') {\n                const validated = this.validateOptions(interceptorRequest as RequestOptions);\n                options = validated;\n            } else {\n                // 若返回非对象且非 false，则视为拦截器实现错误，reject\n                return Promise.reject(new Error('Interceptor must return false or a RequestOptions object'));\n            }\n        }\n\n        // 为避免并发写入实例级 `options`，使用 per-request id 存储本次请求参数（供调试/排查）\n        const reqId = ++this._reqId;\n        this._requestMap.set(reqId, options);\n\n        return new Promise<T>((resolve, reject) => {\n            // 保存 reject 以便外部 cancel 使用\n            this._rejectMap.set(reqId, reject);\n            options.complete = (response: any) => {\n                // 清理对应请求的存储\n                this._requestMap.delete(reqId);\n                this._taskMap.delete(reqId);\n                this._rejectMap.delete(reqId);\n                // 读取 meta 配置\n                const meta = options.meta || this.config.meta || {};\n                const originalData = meta.originalData ?? false;\n                // 拦截器处理，加入request的配置参数\n                response.config = options;\n                if (originalData) {\n                    // 判断是否存在拦截器\n                    if (this.interceptor.response && typeof this.interceptor.response === 'function') {\n                        const resInterceptors = this.interceptor.response(response);\n                        // 如果拦截器不返回false，就将拦截器返回的内容给请求的then回调\n                        if (resInterceptors !== false) {\n                            resolve(resInterceptors);\n                        } else {\n                            // 如果拦截器返回false，意味着拦截器定义者认为返回有问题，直接接入catch回调\n                            reject(response);\n                        }\n                    } else {\n                        // 如果要求返回原始数据，就算没有拦截器，也返回最原始的数据\n                        resolve(response);\n                    }\n                } else {\n                    if (response.statusCode === 200) {\n                        if (this.interceptor.response && typeof this.interceptor.response === 'function') {\n                            const resInterceptors = this.interceptor.response(response.data);\n                            if (resInterceptors !== false) {\n                                resolve(resInterceptors);\n                            } else {\n                                reject(response.data);\n                            }\n                        } else {\n                            // 如果不是返回原始数据(originalData=false)，且没有拦截器的情况下，返回纯数据给then回调\n                            resolve(response.data);\n                        }\n                    } else {\n                        reject(response);\n                    }\n                }\n            };\n            try {\n                const task = uni.request(options);\n                // 保存 request task 以便 cancel\n                this._taskMap.set(reqId, task);\n            } catch (err) {\n                // 捕获同步抛出的异常并 reject\n                // 清理 maps\n                this._requestMap.delete(reqId);\n                this._taskMap.delete(reqId);\n                this._rejectMap.delete(reqId);\n                reject(err);\n            }\n        });\n    }\n\n    get<T = unknown>(\n        url: string,\n        data: any = {},\n        options: { header?: Record<string, any>; meta?: RequestMeta } = {}\n    ): Promise<T> {\n        return this.request<T>({\n            method: 'GET',\n            url,\n            data,\n            header: options.header,\n            meta: options.meta\n        });\n    }\n\n    post<T = unknown>(\n        url: string,\n        data: any = {},\n        options: { header?: Record<string, any>; meta?: RequestMeta } = {}\n    ): Promise<T> {\n        return this.request<T>({\n            url,\n            method: 'POST',\n            data,\n            header: options.header,\n            meta: options.meta\n        });\n    }\n\n    put<T = unknown>(\n        url: string,\n        data: any = {},\n        options: { header?: Record<string, any>; meta?: RequestMeta } = {}\n    ): Promise<T> {\n        return this.request<T>({\n            url,\n            method: 'PUT',\n            data,\n            header: options.header,\n            meta: options.meta\n        });\n    }\n\n    delete<T = unknown>(\n        url: string,\n        data: any = {},\n        options: { header?: Record<string, any>; meta?: RequestMeta } = {}\n    ): Promise<T> {\n        return this.request<T>({\n            url,\n            method: 'DELETE',\n            data,\n            header: options.header,\n            meta: options.meta\n        });\n    }\n}\n\n// 插件化导出，支持 app.use(http, { interceptor })\nconst httpInstance = new Request();\n\ninterface HttpPluginOptions {\n    requestConfig?: Partial<RequestConfig>;\n    interceptor?: RequestInterceptor;\n}\n\n// 全局导出，支持 import { httpPlugin } from 'uview-pro'\nconst httpPlugin = {\n    install(app: any, options: HttpPluginOptions = {}) {\n        if (options.interceptor) {\n            const { request, response } = options.interceptor;\n            if (request) httpInstance.interceptor.request = request;\n            if (response) httpInstance.interceptor.response = response;\n        }\n        if (options.requestConfig) {\n            httpInstance.setConfig(options.requestConfig);\n        }\n        app.config.globalProperties.$http = httpInstance;\n    }\n};\n\n// 全局导出，支持 import { http } from 'uview-pro'\nexport { httpInstance as http };\n\n// 插件化导出，支持 app.use(http, { interceptor })\nexport default httpPlugin;\n"
  },
  {
    "path": "src/common/share.ts",
    "content": "function getCurrentPageUrl() {\n    const pages = getCurrentPages();\n    // 页面栈中的最后一个即为项为当前页面，route属性为页面路径\n    const pageUrl = pages[pages.length - 1].route as string;\n    return `/${pageUrl}`;\n}\n\nexport default {\n    // 发送给朋友\n    onShareAppMessage(res) {\n        return {\n            title: 'uView Pro',\n            desc: '多平台快速开发 UI 组件库',\n            path: getCurrentPageUrl()\n        };\n    },\n    //分享到朋友圈\n    onShareTimeline(res) {\n        return {\n            title: 'uView Pro',\n            desc: '多平台快速开发 UI 组件库',\n            path: getCurrentPageUrl()\n        };\n    }\n};\n"
  },
  {
    "path": "src/common/useExperience.ts",
    "content": "import { ref, computed, type Ref } from 'vue';\n// @ts-ignore\nimport config from './demo-experience.config.json';\nimport { useExperienceCenter } from './useExperienceCenter';\n\nexport interface ExperienceTaskConfig {\n    key: string;\n    title: string;\n    desc: string;\n}\n\nexport interface ExperiencePageConfig {\n    tasks?: ExperienceTaskConfig[];\n}\n\nexport interface ExperienceTask extends ExperienceTaskConfig {\n    done: boolean;\n}\n\nexport interface Mission {\n    id: string;\n    title: string;\n    desc: string;\n    reward: number;\n    componentKey: string;\n    hint: string;\n}\n\nexport const missionPool: Mission[] = [\n    {\n        id: 'image-shape',\n        title: '体验图片组件形态',\n        desc: '前往 Image 示例，切换一次圆形和方形展示，并完成一次状态切换。',\n        reward: 25,\n        componentKey: 'Image 图片',\n        hint: 'Image 组件 - 任务体验'\n    },\n    {\n        id: 'theme',\n        title: '探索主题切换',\n        desc: '在首页主题切换区体验至少 2 套不同主题，感受配色变化。',\n        reward: 20,\n        componentKey: 'Theme 主题',\n        hint: '组件首页 - 主题按钮'\n    },\n    {\n        id: 'slider-move',\n        title: '体验滑块组件',\n        desc: '前往 Slider 示例，拖动滑块并查看数值变化，完成一次完整交互。',\n        reward: 30,\n        componentKey: 'Slider 滑块',\n        hint: 'Slider 组件 - 互动反馈'\n    },\n    {\n        id: 'transition',\n        title: '预览过渡动画',\n        desc: '前往 Transition 示例，切换不同的动画效果，体验至少 3 种过渡动画。',\n        reward: 35,\n        componentKey: 'Transition 过渡',\n        hint: 'Transition 组件 - 组件演示'\n    },\n    {\n        id: 'button',\n        title: '点击按钮组件',\n        desc: '前往 Button 示例，点击不同主题按钮，并查看反馈效果，完成一次点击交互。',\n        reward: 15,\n        componentKey: 'Button 按钮',\n        hint: 'Button 组件 - 组件演示'\n    },\n    {\n        id: 'cell',\n        title: '使用单元格导航',\n        desc: '前往 Cell 示例，点击任意单元格进行导航，体验列表交互。',\n        reward: 20,\n        componentKey: 'Cell 单元格',\n        hint: 'Cell 组件 - 组件演示'\n    },\n    {\n        id: 'rate',\n        title: '体验评分组件',\n        desc: '前往 Rate 示例，进行评分操作，体验至少 3 次评分变化。',\n        reward: 25,\n        componentKey: 'Rate 评分',\n        hint: 'Rate 组件 - 互动反馈'\n    },\n    {\n        id: 'popup',\n        title: '打开弹出层',\n        desc: '前往 Popup 示例，打开至少 2 个不同方向的弹出层，体验弹出效果。',\n        reward: 30,\n        componentKey: 'Popup 弹出层',\n        hint: 'Popup 组件 - 组件演示'\n    },\n    {\n        id: 'form',\n        title: '提交表单数据',\n        desc: '前往 Form 示例，填写表单并提交，完成一次表单交互。',\n        reward: 40,\n        componentKey: 'Form 表单',\n        hint: 'Form 组件 - 组件演示'\n    },\n    {\n        id: 'tabs',\n        title: '切换标签页',\n        desc: '前往 Tabs 示例，切换至少 3 个不同的标签页，体验标签切换。',\n        reward: 20,\n        componentKey: 'Tabs 标签页',\n        hint: 'Tabs 组件 - 组件演示'\n    },\n    {\n        id: 'template',\n        title: '浏览模板场景',\n        desc: '打开模板示例页，浏览任意一个模板详情，了解组件组合用法。',\n        reward: 25,\n        componentKey: 'Template 模板',\n        hint: '模板示例 - 场景浏览'\n    },\n    {\n        id: 'tools',\n        title: '浏览工具场景',\n        desc: '在体验地图页面查看自己的等级和统计数据，了解体验进度。',\n        reward: 15,\n        componentKey: 'Tools 工具',\n        hint: '工具示例 - 场景浏览'\n    }\n];\n\ninterface ExperienceState {\n    tasks: Ref<ExperienceTask[]>;\n    logs: Ref<string[]>;\n}\n\ntype ExperienceConfigMap = Record<string, ExperiencePageConfig>;\n\nconst experienceConfig = config as ExperienceConfigMap;\nconst stateMap: Record<string, ExperienceState> = {};\n\nfunction createInitialTasks(pageKey: string): ExperienceTask[] {\n    const pageConfig = experienceConfig[pageKey];\n    const tasks = pageConfig?.tasks || [];\n    return tasks.map(task => ({\n        ...task,\n        done: false\n    }));\n}\n\nfunction getStorageKeys(pageKey: string) {\n    const base = `uview-demo-experience-${pageKey}`;\n    return {\n        task: `${base}-tasks`,\n        log: `${base}-logs`\n    };\n}\n\nfunction restoreState(pageKey: string): ExperienceState {\n    const tasks = ref<ExperienceTask[]>(createInitialTasks(pageKey));\n    const logs = ref<string[]>([]);\n\n    try {\n        if (typeof uni !== 'undefined') {\n            const keys = getStorageKeys(pageKey);\n            const taskCache = uni.getStorageSync(keys.task);\n            const logCache = uni.getStorageSync(keys.log);\n            if (Array.isArray(taskCache) && taskCache.length) {\n                tasks.value = taskCache as ExperienceTask[];\n            }\n            if (Array.isArray(logCache)) {\n                logs.value = logCache as string[];\n            }\n        }\n    } catch (error) {\n        console.warn('restoreState error', error);\n    }\n\n    return { tasks, logs };\n}\n\nfunction persistState(pageKey: string, state: ExperienceState) {\n    try {\n        if (typeof uni === 'undefined') return;\n        const keys = getStorageKeys(pageKey);\n        uni.setStorageSync(keys.task, state.tasks.value);\n        uni.setStorageSync(keys.log, state.logs.value);\n    } catch (error) {\n        console.warn('persistState error', error);\n    }\n}\n\nexport function useExperience(pageKey: string) {\n    if (!stateMap[pageKey]) {\n        stateMap[pageKey] = restoreState(pageKey);\n    }\n    const state = stateMap[pageKey];\n    const center = useExperienceCenter();\n    center.registerComponent(pageKey);\n\n    const taskProgress = computed(() => {\n        if (!state.tasks.value.length) return 0;\n        const finished = state.tasks.value.filter(task => task.done).length;\n        return Math.round((finished / state.tasks.value.length) * 100);\n    });\n\n    const completeTask = (key: string, xpBonus = 12) => {\n        const task = state.tasks.value.find(item => item.key === key);\n        if (task && !task.done) {\n            task.done = true;\n            persistState(pageKey, state);\n            center.gainExperience(pageKey, xpBonus, `完成任务 · ${task.title}`, { type: 'task' });\n        }\n    };\n\n    const toggleTask = (index: number, value: boolean) => {\n        if (!state.tasks.value[index]) return;\n        state.tasks.value[index].done = value;\n        persistState(pageKey, state);\n    };\n\n    const recordAction = (message: string, xpBonus = 4) => {\n        const date = new Date();\n        const time = `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`;\n        state.logs.value.unshift(`${time} · ${message}`);\n        state.logs.value = state.logs.value.slice(0, 6);\n        persistState(pageKey, state);\n        if (typeof uni !== 'undefined' && typeof uni.vibrateShort === 'function') {\n            uni.vibrateShort();\n        }\n        center.gainExperience(pageKey, xpBonus, message, { type: 'interaction' });\n    };\n\n    const resetExperience = () => {\n        state.tasks.value = createInitialTasks(pageKey);\n        state.logs.value = [];\n        persistState(pageKey, state);\n    };\n\n    return {\n        tasks: state.tasks,\n        logs: state.logs,\n        taskProgress,\n        completeTask,\n        toggleTask,\n        recordAction,\n        resetExperience\n    };\n}\n\n// 任务领取状态管理\nconst MISSION_STORAGE_KEY = 'uview-experience-assigned-missions';\nconst COMPLETED_MISSIONS_KEY = 'uview-experience-completed-missions';\nconst assignedMissionIds = ref<string[]>([]);\nconst completedMissionIds = ref<string[]>([]); // 已完成但未领取积分的任务\n\n// 加载已领取的任务\nfunction loadAssignedMissions() {\n    try {\n        if (typeof uni === 'undefined') return;\n        const cache = uni.getStorageSync(MISSION_STORAGE_KEY);\n        if (Array.isArray(cache)) {\n            assignedMissionIds.value = cache;\n        }\n    } catch (error) {\n        console.warn('loadAssignedMissions error', error);\n    }\n}\n\n// 保存已领取的任务\nfunction saveAssignedMissions() {\n    try {\n        if (typeof uni === 'undefined') return;\n        uni.setStorageSync(MISSION_STORAGE_KEY, assignedMissionIds.value);\n    } catch (error) {\n        console.warn('saveAssignedMissions error', error);\n    }\n}\n\n// 加载已完成的任务\nfunction loadCompletedMissions() {\n    try {\n        if (typeof uni === 'undefined') return;\n        const cache = uni.getStorageSync(COMPLETED_MISSIONS_KEY);\n        if (Array.isArray(cache)) {\n            completedMissionIds.value = cache;\n        }\n    } catch (error) {\n        console.warn('loadCompletedMissions error', error);\n    }\n}\n\n// 保存已完成的任务\nfunction saveCompletedMissions() {\n    try {\n        if (typeof uni === 'undefined') return;\n        uni.setStorageSync(COMPLETED_MISSIONS_KEY, completedMissionIds.value);\n    } catch (error) {\n        console.warn('saveCompletedMissions error', error);\n    }\n}\n\n// 初始化时加载\nloadAssignedMissions();\nloadCompletedMissions();\n\n/**\n * 取消任务（从已领取列表中移除）\n * @param missionId 任务ID\n * @returns 是否成功取消任务\n */\nexport function unassignMission(missionId: string): boolean {\n    if (!assignedMissionIds.value.includes(missionId)) {\n        return false;\n    }\n\n    assignedMissionIds.value = assignedMissionIds.value.filter(id => id !== missionId);\n    saveAssignedMissions();\n    return true;\n}\n\n/**\n * 领取任务\n * @param missionId 任务ID\n * @param force 是否强制领取（如果任务已领取，先取消再领取）\n * @returns 是否成功领取任务\n */\nexport function assignMission(missionId: string, force = false): boolean {\n    const mission = missionPool.find(m => m.id === missionId);\n    if (!mission) {\n        console.warn(`Mission not found: ${missionId}`);\n        return false;\n    }\n\n    // 如果任务已经领取且不强制，返回 false\n    if (assignedMissionIds.value.includes(missionId) && !force) {\n        return false;\n    }\n\n    // 如果强制领取且任务已存在，先移除\n    if (force && assignedMissionIds.value.includes(missionId)) {\n        assignedMissionIds.value = assignedMissionIds.value.filter(id => id !== missionId);\n    }\n\n    // 添加任务到已领取列表\n    assignedMissionIds.value.push(missionId);\n    saveAssignedMissions();\n    return true;\n}\n\n/**\n * 完成任务（通过任务ID）- 只标记为完成，不直接给积分\n * @param missionId 任务ID\n * @returns 是否成功完成任务\n */\nexport function completeMission(missionId: string): boolean {\n    const mission = missionPool.find(m => m.id === missionId);\n    if (!mission) {\n        console.warn(`Mission not found: ${missionId}`);\n        return false;\n    }\n\n    // 检查任务是否已领取\n    if (!assignedMissionIds.value.includes(missionId)) {\n        console.warn(`Mission not assigned: ${missionId}`);\n        return false;\n    }\n\n    // 如果任务已经完成，不再重复完成\n    if (completedMissionIds.value.includes(missionId)) {\n        return false;\n    }\n\n    // 标记任务为已完成（但未领取积分）\n    completedMissionIds.value.push(missionId);\n    saveCompletedMissions();\n\n    if (typeof uni !== 'undefined') {\n        uni.showToast({ title: '任务已完成，请前往体验地图领取积分', icon: 'success', duration: 2000 });\n    }\n\n    return true;\n}\n\n/**\n * 领取任务积分（在体验地图中调用）\n * @param missionId 任务ID\n * @returns 是否成功领取积分\n */\nexport function claimMissionReward(missionId: string): boolean {\n    const mission = missionPool.find(m => m.id === missionId);\n    if (!mission) {\n        console.warn(`Mission not found: ${missionId}`);\n        return false;\n    }\n\n    // 检查任务是否已完成\n    if (!completedMissionIds.value.includes(missionId)) {\n        console.warn(`Mission not completed: ${missionId}`);\n        if (typeof uni !== 'undefined') {\n            uni.showToast({ title: '任务尚未完成', icon: 'none' });\n        }\n        return false;\n    }\n\n    // 发放积分\n    const center = useExperienceCenter();\n    center.gainExperience(mission.componentKey, mission.reward, `体验任务 · ${mission.title}`, { type: 'task' });\n\n    if (typeof uni !== 'undefined') {\n        uni.showToast({ title: `领取积分 +${mission.reward}XP`, icon: 'success' });\n    }\n\n    // 从已完成列表中移除（已领取积分）\n    completedMissionIds.value = completedMissionIds.value.filter(id => id !== missionId);\n    saveCompletedMissions();\n\n    // 从已领取列表中移除\n    assignedMissionIds.value = assignedMissionIds.value.filter(id => id !== missionId);\n    saveAssignedMissions();\n\n    return true;\n}\n\n/**\n * 获取已领取的任务ID列表\n */\nexport function getAssignedMissionIds(): string[] {\n    return [...assignedMissionIds.value];\n}\n\n/**\n * 获取已完成但未领取积分的任务ID列表\n */\nexport function getCompletedMissionIds(): string[] {\n    return [...completedMissionIds.value];\n}\n\n/**\n * 检查任务是否已领取\n */\nexport function isMissionAssigned(missionId: string): boolean {\n    return assignedMissionIds.value.includes(missionId);\n}\n\n/**\n * 检查任务是否已完成（但未领取积分）\n */\nexport function isMissionCompleted(missionId: string): boolean {\n    return completedMissionIds.value.includes(missionId);\n}\n"
  },
  {
    "path": "src/common/useExperienceCenter.ts",
    "content": "import { ref, computed } from 'vue';\n\ninterface ComponentStat {\n    key: string;\n    xp: number;\n    visits: number;\n    interactions: number;\n    tasksCompleted: number;\n    lastAction?: string;\n    lastUpdated?: number;\n}\n\ninterface ExperienceLog {\n    message: string;\n    timestamp: number;\n}\n\ninterface AtlasNode {\n    id: string;\n    title: string;\n    tip: string;\n    threshold: number;\n}\n\ninterface PersistedState {\n    xp: number;\n    totalInteractions: number;\n    componentStats: Record<string, ComponentStat>;\n    logs: ExperienceLog[];\n}\n\nconst STORAGE_KEY = 'uview-experience-center';\n\nconst atlas: AtlasNode[] = [\n    { id: 'start', title: '起步探索', tip: '完成任意组件的首次交互', threshold: 0 },\n    { id: 'interact', title: '交互达人', tip: '累计体验值达到 200 点', threshold: 200 },\n    { id: 'scene', title: '场景高手', tip: '累计体验值达到 500 点', threshold: 500 },\n    { id: 'mentor', title: '体验导师', tip: '累计体验值达到 1000 点', threshold: 1000 },\n    { id: 'master', title: '体验大师', tip: '累计体验值达到 2000 点', threshold: 2000 },\n    { id: 'legend', title: '体验传说', tip: '累计体验值达到 5000 点', threshold: 5000 }\n];\n\nconst xp = ref(0);\nconst totalInteractions = ref(0);\nconst componentStats = ref<Record<string, ComponentStat>>({});\nconst logs = ref<ExperienceLog[]>([]);\nconst lastGain = ref<{ amount: number; source: string; componentKey: string; timestamp: number } | null>(null);\nlet initialized = false;\n\nfunction loadState() {\n    if (initialized) return;\n    initialized = true;\n    try {\n        if (typeof uni === 'undefined') return;\n        const cache = uni.getStorageSync(STORAGE_KEY);\n        if (cache) {\n            const parsed = cache as PersistedState;\n            xp.value = parsed.xp || 0;\n            totalInteractions.value = parsed.totalInteractions || 0;\n            componentStats.value = parsed.componentStats || {};\n            logs.value = parsed.logs || [];\n        }\n    } catch (error) {\n        console.warn('useExperienceCenter loadState error', error);\n    }\n}\n\nfunction persistState() {\n    try {\n        if (typeof uni === 'undefined') return;\n        const payload: PersistedState = {\n            xp: xp.value,\n            totalInteractions: totalInteractions.value,\n            componentStats: componentStats.value,\n            logs: logs.value\n        };\n        uni.setStorageSync(STORAGE_KEY, payload);\n    } catch (error) {\n        console.warn('useExperienceCenter persistState error', error);\n    }\n}\n\nfunction ensureRegistered(key: string) {\n    if (!componentStats.value[key]) {\n        componentStats.value = {\n            ...componentStats.value,\n            [key]: {\n                key,\n                xp: 0,\n                visits: 0,\n                interactions: 0,\n                tasksCompleted: 0\n            }\n        };\n    }\n}\n\nexport function useExperienceCenter() {\n    loadState();\n\n    const levelInfo = computed(() => {\n        let current = atlas[0];\n        for (const node of atlas) {\n            if (xp.value >= node.threshold) {\n                current = node;\n            } else {\n                break;\n            }\n        }\n        return current;\n    });\n\n    const nextLevel = computed(() => {\n        const currentIndex = atlas.findIndex(node => node.id === levelInfo.value.id);\n        return atlas[currentIndex + 1] || null;\n    });\n\n    const levelProgress = computed(() => {\n        const next = nextLevel.value;\n        if (!next) {\n            return 100;\n        }\n        const currentThreshold = levelInfo.value.threshold;\n        const span = next.threshold - currentThreshold;\n        if (span <= 0) return 100;\n        return Math.min(100, Math.round(((xp.value - currentThreshold) / span) * 100));\n    });\n\n    const mapSteps = computed(() => {\n        return atlas.map((node, index) => {\n            const reached = xp.value >= node.threshold;\n            const next = atlas[index + 1];\n            let status: 'finish' | 'process' | 'wait' = 'wait';\n            if (reached && (!next || xp.value >= next.threshold)) {\n                status = 'finish';\n            } else if (reached) {\n                status = 'process';\n            }\n            return {\n                ...node,\n                status,\n                percent:\n                    status === 'process' && next\n                        ? Math.min(\n                              100,\n                              Math.round(((xp.value - node.threshold) / (next.threshold - node.threshold)) * 100)\n                          )\n                        : status === 'finish'\n                          ? 100\n                          : 0\n            };\n        });\n    });\n\n    const recentLogs = computed(() => logs.value.slice(0, 6));\n\n    const componentSummary = computed(() => {\n        const keys = Object.keys(componentStats.value);\n        const stats = keys.map(key => componentStats.value[key]);\n        const tasksCompleted = stats.reduce((sum, item) => sum + item.tasksCompleted, 0);\n        const totalXP = stats.reduce((sum, item) => sum + item.xp, 0);\n        const mostActive = stats.sort((a, b) => b.xp - a.xp)[0];\n        return {\n            components: keys.length,\n            tasksCompleted,\n            totalXP,\n            mostActive\n        };\n    });\n\n    const registerComponent = (key: string) => {\n        if (!key) return;\n        ensureRegistered(key);\n        componentStats.value[key] = {\n            ...componentStats.value[key],\n            visits: componentStats.value[key].visits + 1,\n            lastUpdated: Date.now()\n        };\n        persistState();\n    };\n\n    const gainExperience = (\n        componentKey: string,\n        amount = 4,\n        source = '交互体验',\n        payload?: { type?: 'task' | 'interaction' }\n    ) => {\n        if (!componentKey || amount <= 0) return;\n        ensureRegistered(componentKey);\n        xp.value += amount;\n        totalInteractions.value += 1;\n        const stat = componentStats.value[componentKey];\n        stat.xp += amount;\n        stat.interactions += 1;\n        if (payload?.type === 'task') {\n            stat.tasksCompleted += 1;\n        }\n        stat.lastAction = source;\n        stat.lastUpdated = Date.now();\n        componentStats.value = {\n            ...componentStats.value,\n            [componentKey]: { ...stat }\n        };\n        const timestamp = Date.now();\n        logs.value = [{ message: `${source} +${amount}XP`, timestamp }, ...logs.value].slice(0, 12);\n        lastGain.value = { amount, source, componentKey, timestamp };\n        persistState();\n    };\n\n    return {\n        xp,\n        totalInteractions,\n        levelInfo,\n        nextLevel,\n        levelProgress,\n        mapSteps,\n        recentLogs,\n        componentSummary,\n        componentStats,\n        lastGain,\n        registerComponent,\n        gainExperience\n    };\n}\n"
  },
  {
    "path": "src/common/useHooks.ts",
    "content": "import { useLocale } from 'uview-pro';\nimport { useI18n } from 'vue-i18n';\n\nexport function useLang() {\n    const { locale } = useI18n();\n    const { setLocale } = useLocale();\n    function switchLang(payload: any) {\n        // 切换uniapp语言\n        uni.setLocale(payload.locale);\n        uni.setStorageSync('UNI_LOCALE', payload.locale);\n        // 切换vue-i18n语言\n        locale.value = payload.locale;\n        // 切换uView Pro语言\n        setLocale(payload.name);\n    }\n\n    return {\n        switchLang\n    };\n}\n\n/**\n * 获取标题（中英文）\n */\nexport function useTitle(index: number) {\n    const { t, locale } = useI18n();\n    const titles = ['nav.components', 'nav.js', 'nav.experience', 'nav.template', 'nav.about'];\n    function getTitle(key: string, item: any = null) {\n        if (!item) return key;\n        return locale.value === 'zh-Hans' ? item[key] : item[`${key}_en`];\n    }\n\n    function setTitle() {\n        uni?.setNavigationBarTitle({\n            title: t(titles[index])\n        });\n        // titles.forEach((text, index) => {\n        //     uni?.setTabBarItem({\n        //         index,\n        //         text: t(text)\n        //     });\n        // });\n    }\n\n    return { getTitle, setTitle };\n}\n"
  },
  {
    "path": "src/common/util.ts",
    "content": "import { useI18n } from 'vue-i18n';\n\n/**\n * 生成随机背景颜色\n */\nexport function getRandomColor(): string {\n    const colors = [\n        '#39b54a', // green\n        '#f39c12', // orange\n        '#3498db', // blue\n        '#e74c3c', // red\n        '#9b59b6', // purple\n        '#16a085', // teal\n        '#e67e22', // carrot\n        '#2ecc71', // emerald\n        '#1abc9c', // turquoise\n        '#34495e', // wet asphalt\n        '#2980b9',\n        '#8e44ad',\n        '#2c3e50',\n        '#c0392b',\n        '#d35400',\n        '#27ae60',\n        '#f1c40f',\n        '#7f8c8d',\n        '#e84393',\n        '#00b894',\n        '#fdcb6e',\n        '#6c5ce7',\n        '#0984e3',\n        '#00cec9',\n        '#fab1a0',\n        '#ff7675',\n        '#55efc4'\n    ];\n    return colors[Math.floor(Math.random() * colors.length)];\n}\n"
  },
  {
    "path": "src/components/demo-animation/animation.css",
    "content": "/**\n * Animation 微动画  \n */\n\n/* css 滤镜 控制黑白底色gif的 */\n.gif-black {\n    mix-blend-mode: screen;\n}\n.gif-white {\n    mix-blend-mode: multiply;\n}\n\n/* Animation css */\n[class*='animation-'] {\n    animation-duration: 0.5s;\n    animation-timing-function: ease-out;\n    animation-fill-mode: both;\n}\n\n.animation-fade {\n    animation-name: fade;\n    animation-duration: 0.8s;\n    animation-timing-function: linear;\n}\n\n.animation-scale-up {\n    animation-name: scale-up;\n}\n\n.animation-scale-down {\n    animation-name: scale-down;\n}\n\n.animation-slide-top {\n    animation-name: slide-top;\n}\n\n.animation-slide-bottom {\n    animation-name: slide-bottom;\n}\n\n.animation-slide-left {\n    animation-name: slide-left;\n}\n\n.animation-slide-right {\n    animation-name: slide-right;\n}\n\n.animation-shake {\n    animation-name: shake;\n}\n\n.animation-reverse {\n    animation-direction: reverse;\n}\n\n@keyframes fade {\n    0% {\n        opacity: 0;\n    }\n\n    100% {\n        opacity: 1;\n    }\n}\n\n@keyframes scale-up {\n    0% {\n        opacity: 0;\n        transform: scale(0.2);\n    }\n\n    100% {\n        opacity: 1;\n        transform: scale(1);\n    }\n}\n\n@keyframes scale-down {\n    0% {\n        opacity: 0;\n        transform: scale(1.8);\n    }\n\n    100% {\n        opacity: 1;\n        transform: scale(1);\n    }\n}\n\n@keyframes slide-top {\n    0% {\n        opacity: 0;\n        transform: translateY(-100%);\n    }\n\n    100% {\n        opacity: 1;\n        transform: translateY(0);\n    }\n}\n\n@keyframes slide-bottom {\n    0% {\n        opacity: 0;\n        transform: translateY(100%);\n    }\n\n    100% {\n        opacity: 1;\n        transform: translateY(0);\n    }\n}\n\n@keyframes shake {\n    0%,\n    100% {\n        transform: translateX(0);\n    }\n\n    10% {\n        transform: translateX(-9px);\n    }\n\n    20% {\n        transform: translateX(8px);\n    }\n\n    30% {\n        transform: translateX(-7px);\n    }\n\n    40% {\n        transform: translateX(6px);\n    }\n\n    50% {\n        transform: translateX(-5px);\n    }\n\n    60% {\n        transform: translateX(4px);\n    }\n\n    70% {\n        transform: translateX(-3px);\n    }\n\n    80% {\n        transform: translateX(2px);\n    }\n\n    90% {\n        transform: translateX(-1px);\n    }\n}\n\n@keyframes slide-left {\n    0% {\n        opacity: 0;\n        transform: translateX(-100%);\n    }\n\n    100% {\n        opacity: 1;\n        transform: translateX(0);\n    }\n}\n\n@keyframes slide-right {\n    0% {\n        opacity: 0;\n        transform: translateX(100%);\n    }\n\n    100% {\n        opacity: 1;\n        transform: translateX(0);\n    }\n}\n"
  },
  {
    "path": "src/components/demo-animation/demo-animation.vue",
    "content": "<template>\n    <view :class=\"[animationName]\" :style=\"[animationDelay ? { animationDelay: animationDelay * 0.1 + 's' } : {}]\">\n        <slot></slot>\n    </view>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref, onBeforeMount } from 'vue';\n\ntype AnimationType =\n    | 'fade'\n    | 'scale-up'\n    | 'scale-down'\n    | 'slide-top'\n    | 'slide-bottom'\n    | 'slide-left'\n    | 'slide-right'\n    | 'shake'\n    | '';\n\nconst props = defineProps({\n    name: {\n        type: String as () => AnimationType,\n        default: ''\n    },\n    delay: {\n        type: Number,\n        default: 0\n    }\n});\n\nconst animationName = ref('');\nconst animationDelay = ref(0);\n\nonBeforeMount(() => {\n    animationName.value = props.name ? `animation-${props.name}` : '';\n    animationDelay.value = props.delay || 0;\n});\n\n/**\n * 切换动画效果\n * @param name 动画名称\n * @param delay 延迟时间\n */\nfunction toggle(name?: AnimationType, delay?: number) {\n    animationName.value = name ? `animation-${name}` : `animation-${props.name}`;\n    animationDelay.value = delay || props.delay;\n    setTimeout(() => {\n        animationName.value = '';\n    }, 500);\n}\n\ndefineExpose({\n    toggle\n});\n</script>\n\n<style>\n@import 'animation.css';\n</style>\n"
  },
  {
    "path": "src/components/demo-card/demo-card.vue",
    "content": "<template>\n    <view class=\"card-list\">\n        <view\n            hover-class=\"none\"\n            :url=\"item.path\"\n            class=\"card-item\"\n            :style=\"{ backgroundColor: navColors[item.path] }\"\n            v-for=\"(item, index) in list\"\n            :key=\"index\"\n            @click=\"navigateTo(item.path)\"\n        >\n            <demo-animation name=\"slide-bottom\" :delay=\"1\">\n                <view class=\"card-item-title\" style=\"color: #fff\">{{ getFieldTitle(item) }}</view>\n                <view class=\"card-item-name\" style=\"color: #fff\">Go ></view>\n                <!-- <image style=\"width: 30rpx\" :src=\"getIcon(item.icon)\" mode=\"widthFix\"></image> -->\n            </demo-animation>\n        </view>\n    </view>\n</template>\n\n<script setup lang=\"ts\">\nimport { getRandomColor } from '@/common/util';\nimport { onMounted, ref } from 'vue';\nimport { useI18n } from 'vue-i18n';\n\nconst props = defineProps({\n    list: {\n        type: Array as () => any[],\n        default: () => {\n            return [];\n        }\n    },\n    openPage: {\n        type: Function,\n        default: undefined\n    }\n});\n\nconst emit = defineEmits(['item-click']);\n\n// 国际化\nconst { t, locale } = useI18n();\n\n// 存储每个item的随机背景色\nconst navColors = ref<Record<string, string>>({});\n/**\n * 获取分组标题（中英文）\n */\nfunction getGroupTitle(item: any) {\n    return locale.value === 'zh-Hans' ? item.groupName : item.groupName_en;\n}\n\n/**\n * 获取字段标题（中英文）\n */\nfunction getFieldTitle(item: any) {\n    return locale.value === 'zh-Hans' ? item.title : item.title_en;\n}\n\n/**\n * 路由跳转\n */\nfunction navigateTo(path: string) {\n    if (props.openPage) {\n        props.openPage(path);\n        return;\n    }\n    uni.navigateTo({ url: path });\n}\n\nonMounted(() => {\n    // 为每个item分配随机背景色\n    props.list.forEach((item: any) => {\n        navColors.value[item.path] = getRandomColor();\n    });\n});\n</script>\n\n<style lang=\"scss\" scoped>\n.card-list {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 40rpx;\n    justify-content: space-between;\n    margin-bottom: 40rpx;\n}\n\n.card-item {\n    box-sizing: border-box;\n    padding: 20rpx 30rpx;\n    border-radius: 8px;\n    width: calc(50% - 22rpx);\n    min-width: 160rpx;\n    background-size: cover;\n    background-position: center;\n    position: relative;\n    z-index: 1;\n    background-image: url(https://ik.imagekit.io/anyup/uview-pro/common/bg-item.png);\n    transition: background 0.3s;\n    /* #ifdef APP-PLUS */\n    margin-bottom: 40rpx;\n    /* #endif */\n}\n\n.card-item::after {\n    content: '';\n    position: absolute;\n    z-index: -1;\n    background-color: inherit;\n    width: 100%;\n    height: 100%;\n    left: 0;\n    bottom: -10%;\n    border-radius: 10rpx;\n    opacity: 0.2;\n    transform: scale(0.9, 0.9);\n}\n\n.card-item.cur {\n    color: #fff;\n    background: rgb(94, 185, 94);\n    box-shadow: 4rpx 4rpx 6rpx rgba(94, 185, 94, 0.4);\n}\n\n.card-item-title {\n    font-size: 26rpx;\n    font-weight: 400;\n    height: 80rpx;\n    max-height: 80rpx;\n}\n\n.card-item-title::first-letter {\n    font-size: 30rpx;\n    margin-right: 4rpx;\n}\n\n.card-item-name {\n    font-size: 24rpx;\n    text-transform: Capitalize;\n    position: relative;\n}\n\n.card-item-name::before {\n    content: '';\n    position: absolute;\n    display: block;\n    width: 40rpx;\n    height: 6rpx;\n    background: #fff;\n    bottom: 0;\n    right: 0;\n    opacity: 0.5;\n}\n\n.card-item-name::after {\n    content: '';\n    position: absolute;\n    display: block;\n    width: 100rpx;\n    height: 1px;\n    background: #fff;\n    bottom: 0;\n    right: 40rpx;\n    opacity: 0.3;\n}\n\n.card-item-name::first-letter {\n    font-weight: bold;\n    font-size: 30rpx;\n    margin-right: 1px;\n}\n\n.card-item image {\n    position: absolute;\n    right: 10rpx;\n    top: 10rpx;\n    font-size: 52rpx;\n    width: 60rpx;\n    height: 60rpx;\n    text-align: center;\n    line-height: 60rpx;\n}\n</style>\n"
  },
  {
    "path": "src/components/demo-guide/demo-guide.vue",
    "content": "<template>\n    <view v-if=\"show\" class=\"demo-guide\">\n        <view class=\"demo-guide__bg\">\n            <view class=\"demo-guide__bg-circle demo-guide__bg-circle--1\"></view>\n            <view class=\"demo-guide__bg-circle demo-guide__bg-circle--2\"></view>\n            <view class=\"demo-guide__bg-circle demo-guide__bg-circle--3\"></view>\n        </view>\n\n        <view class=\"onboarding-header\">\n            <view class=\"onboarding-badge\">\n                <u-icon custom-prefix=\"custom-icon\" name=\"sparkles\" size=\"32\" color=\"#fff\"></u-icon>\n                <text>uView Pro</text>\n            </view>\n            <view class=\"onboarding-subtitle\">高质量跨平台 UI 组件库</view>\n            <view class=\"onboarding-subdesc\">跨端一致体验 · 深度适配 HarmonyOS App</view>\n        </view>\n\n        <swiper\n            class=\"onboarding-swiper\"\n            :class=\"{ 'onboarding-swiper--disabled': !enableSwipe }\"\n            :current=\"onboardingIndex\"\n            @change=\"handleOnboardingChange\"\n            :duration=\"500\"\n        >\n            <swiper-item v-for=\"(slide, index) in onboardingSlides\" :key=\"`slide-${index}-${slideKey}`\">\n                <view class=\"onboarding-slide\">\n                    <view\n                        v-for=\"(card, cardIndex) in slide.cards\"\n                        :key=\"`card-${index}-${cardIndex}`\"\n                        class=\"onboarding-card\"\n                        :class=\"[\n                            `onboarding-card--${card.position}`,\n                            `onboarding-card--${card.size || 'medium'}`,\n                            { 'onboarding-card--active': activeCardId === `${index}-${cardIndex}` }\n                        ]\"\n                        :style=\"getCardStyle(card, cardIndex, index, cardIndex)\"\n                        @click=\"handleCardClick(index, cardIndex)\"\n                    >\n                        <view class=\"onboarding-card__icon\" v-if=\"card.icon\">\n                            <u-icon\n                                :custom-prefix=\"card.prefix || 'custom-icon'\"\n                                :name=\"card.icon\"\n                                size=\"64\"\n                                :color=\"card.iconColor || '#fff'\"\n                            ></u-icon>\n                        </view>\n                        <view class=\"onboarding-card__content\">\n                            <view class=\"onboarding-card__title\">{{ card.title }}</view>\n                            <view class=\"onboarding-card__desc\">{{ card.desc }}</view>\n                            <view v-if=\"card.features && card.features.length\" class=\"onboarding-card__features\">\n                                <view\n                                    v-for=\"(feature, fIndex) in card.features\"\n                                    :key=\"fIndex\"\n                                    class=\"onboarding-card__feature\"\n                                >\n                                    <view class=\"onboarding-card__feature-dot\"></view>\n                                    <text>{{ feature }}</text>\n                                </view>\n                            </view>\n                        </view>\n                    </view>\n                </view>\n            </swiper-item>\n        </swiper>\n\n        <view class=\"onboarding-dots\">\n            <view\n                v-for=\"(slide, index) in onboardingSlides\"\n                :key=\"slide.title + index\"\n                class=\"onboarding-dot\"\n                :class=\"{ 'onboarding-dot--active': onboardingIndex === index }\"\n                @click=\"handleDotClick(index)\"\n            ></view>\n        </view>\n\n        <view class=\"onboarding-actions\">\n            <view v-if=\"onboardingIndex > 0\" class=\"action-btn action-btn--prev\" @click=\"handlePrev\">\n                <u-icon name=\"arrow-left\" size=\"32\" color=\"#fff\"></u-icon>\n                <text>上一步</text>\n            </view>\n            <view\n                v-if=\"onboardingIndex < onboardingSlides.length - 1\"\n                class=\"action-btn action-btn--next\"\n                @click=\"handleNext\"\n            >\n                <text>下一步</text>\n                <u-icon name=\"arrow-right\" size=\"32\" color=\"#fff\"></u-icon>\n            </view>\n            <view v-else class=\"action-btn action-btn--complete\" @click=\"handleComplete\">\n                <u-icon custom-prefix=\"custom-icon\" name=\"sparkles\" size=\"36\" color=\"#fff\"></u-icon>\n                <text>进入应用</text>\n            </view>\n        </view>\n    </view>\n</template>\n\n<script setup lang=\"ts\">\nimport { $u } from 'uview-pro';\nimport { ref, computed, onMounted, nextTick } from 'vue';\nimport { ONBOARDING_STORAGE_BASE_KEY } from '../../common/constant';\n\ninterface OnboardingCard {\n    title: string;\n    desc: string;\n    icon?: string;\n    prefix?: string;\n    iconColor?: string;\n    position: 'top-left' | 'top-right' | 'center' | 'bottom-left' | 'bottom-right';\n    size?: 'small' | 'medium' | 'large';\n    features?: string[];\n    delay?: number;\n}\n\ninterface OnboardingSlide {\n    title: string;\n    cards: OnboardingCard[];\n}\n\nconst props = withDefaults(\n    defineProps<{\n        show?: boolean;\n        storageKey?: string;\n        slides?: OnboardingSlide[];\n        enableSwipe?: boolean;\n    }>(),\n    {\n        show: undefined,\n        storageKey: ONBOARDING_STORAGE_BASE_KEY,\n        enableSwipe: true,\n        slides: () => [\n            {\n                title: '组件体验升级',\n                cards: [\n                    {\n                        title: '互动反馈',\n                        desc: '通过点赞、收藏、评分等互动方式，深度体验每个组件的交互能力',\n                        icon: 'hand-sparkles',\n                        prefix: 'custom-icon',\n                        iconColor: $u.color.primaryDark,\n                        position: 'top-left',\n                        size: 'large',\n                        features: ['实时反馈', '体验记录', '进度追踪'],\n                        delay: 0\n                    },\n                    {\n                        title: '任务挑战',\n                        desc: '完成组件任务，解锁更多功能，获得体验值奖励',\n                        icon: 'target',\n                        prefix: 'custom-icon',\n                        iconColor: $u.color.successDark,\n                        position: 'top-right',\n                        size: 'medium',\n                        features: ['任务引导', '成就系统'],\n                        delay: 150\n                    },\n                    {\n                        title: '体验地图',\n                        desc: '查看你的成长轨迹，解锁更多体验节点，成为组件专家',\n                        icon: 'map-circle',\n                        prefix: 'custom-icon',\n                        iconColor: $u.color.warningDark,\n                        position: 'bottom-left',\n                        size: 'medium',\n                        delay: 300\n                    },\n                    {\n                        title: '完整能力',\n                        desc: '全面了解组件的所有功能和配置选项，掌握最佳实践',\n                        icon: 'sparkles',\n                        prefix: 'custom-icon',\n                        iconColor: $u.color.errorDark,\n                        position: 'bottom-right',\n                        size: 'small',\n                        delay: 450\n                    }\n                ]\n            },\n            {\n                title: '任务式学习',\n                cards: [\n                    {\n                        title: '可视化任务',\n                        desc: '每个组件都提供清晰的任务指引，帮助你快速上手',\n                        icon: 'eye',\n                        prefix: 'custom-icon',\n                        iconColor: $u.color.primaryDark,\n                        position: 'top-left',\n                        size: 'large',\n                        features: ['任务列表', '进度显示', '完成奖励'],\n                        delay: 0\n                    },\n                    {\n                        title: '操作引导',\n                        desc: '按照提示完成加载、配置、动效等操作，学习组件用法',\n                        icon: 'guide',\n                        prefix: 'custom-icon',\n                        iconColor: $u.color.successDark,\n                        position: 'center',\n                        size: 'large',\n                        features: ['步骤指引', '实时提示'],\n                        delay: 200\n                    },\n                    {\n                        title: '实践操作',\n                        desc: '通过实际操作加深理解，掌握组件的各种配置和用法',\n                        icon: 'tool',\n                        prefix: 'custom-icon',\n                        iconColor: $u.color.warningDark,\n                        position: 'bottom-left',\n                        size: 'medium',\n                        delay: 400\n                    },\n                    {\n                        title: '技能提升',\n                        desc: '完成任务获得经验值，提升你的组件使用技能等级',\n                        icon: 'levels',\n                        prefix: 'custom-icon',\n                        iconColor: $u.color.errorDark,\n                        position: 'bottom-right',\n                        size: 'small',\n                        delay: 600\n                    }\n                ]\n            },\n            {\n                title: '养成式成长',\n                cards: [\n                    {\n                        title: '体验值系统',\n                        desc: '每次交互都会增加体验值，记录你的学习成长轨迹',\n                        icon: 'star',\n                        prefix: 'custom-icon',\n                        iconColor: $u.color.primaryDark,\n                        position: 'top-left',\n                        size: 'large',\n                        features: ['XP 累积', '等级提升', '成就解锁'],\n                        delay: 0\n                    },\n                    {\n                        title: '节点解锁',\n                        desc: '随着体验值增加，逐步解锁体验地图的更多节点',\n                        icon: 'map-circle',\n                        prefix: 'custom-icon',\n                        iconColor: $u.color.successDark,\n                        position: 'top-right',\n                        size: 'medium',\n                        delay: 200\n                    },\n                    {\n                        title: '成长记录',\n                        desc: '查看详细的体验记录，了解你的学习进度和成就',\n                        icon: 'file-text',\n                        prefix: 'custom-icon',\n                        iconColor: $u.color.warningDark,\n                        position: 'bottom-left',\n                        size: 'medium',\n                        delay: 400\n                    },\n                    {\n                        title: '持续探索',\n                        desc: '不断探索新组件，解锁更多功能，成为真正的组件专家',\n                        icon: 'compass',\n                        prefix: 'custom-icon',\n                        iconColor: $u.color.errorDark,\n                        position: 'bottom-right',\n                        size: 'small',\n                        delay: 600\n                    }\n                ]\n            }\n        ]\n    }\n);\n\nconst emit = defineEmits<{\n    complete: [];\n    skip: [];\n    'update:show': [value: boolean];\n}>();\n\nconst onboardingSlides = ref<OnboardingSlide[]>(props.slides);\nconst internalShow = ref(false);\nconst onboardingIndex = ref(0);\nconst slideKey = ref(0);\nconst activeCardId = ref<string | null>(null);\nconst isChanging = ref(false);\n\nconst enableSwipe = computed(() => props.enableSwipe);\n\nconst show = computed({\n    get: () => (props.show !== undefined ? props.show : internalShow.value),\n    set: (value: boolean) => {\n        if (props.show === undefined) {\n            internalShow.value = value;\n        }\n        emit('update:show', value);\n    }\n});\nconst getOnboardingStorageKey = () => {\n    let version = '';\n    try {\n        // @ts-ignore 运行时全局配置，由 uni-app 注入\n        const cfg = typeof __uniConfig !== 'undefined' ? __uniConfig : undefined;\n        version = cfg?.versionName || cfg?.version || '';\n    } catch (error) {\n        console.warn('getOnboardingStorageKey error', error);\n    }\n    const baseKey = props.storageKey || ONBOARDING_STORAGE_BASE_KEY;\n    return version ? `${baseKey}-${version}` : baseKey;\n};\n\nconst checkOnboarding = () => {\n    try {\n        if (typeof uni === 'undefined') {\n            if (props.show === undefined) {\n                internalShow.value = false;\n            }\n            emit('update:show', false);\n            return;\n        }\n        const key = getOnboardingStorageKey();\n        const viewed = uni.getStorageSync(key);\n        const shouldShow = !viewed;\n        if (props.show === undefined) {\n            internalShow.value = shouldShow;\n        }\n        emit('update:show', shouldShow);\n    } catch (error) {\n        console.warn('checkOnboarding error', error);\n        if (props.show === undefined) {\n            internalShow.value = true;\n        }\n        emit('update:show', true);\n    }\n};\n\nlet animationTimer: ReturnType<typeof setTimeout> | null = null;\n\nconst triggerAnimation = () => {\n    if (isChanging.value) return;\n    isChanging.value = true;\n    activeCardId.value = null;\n\n    // 清除之前的定时器\n    if (animationTimer) {\n        clearTimeout(animationTimer);\n    }\n\n    // 延迟更新slideKey，避免频繁更新\n    animationTimer = setTimeout(() => {\n        slideKey.value += 1;\n        // 延迟重置，确保动画完成\n        setTimeout(() => {\n            isChanging.value = false;\n        }, 600);\n    }, 50);\n};\n\nconst handleNext = () => {\n    if (onboardingIndex.value < onboardingSlides.value.length - 1) {\n        onboardingIndex.value += 1;\n        triggerAnimation();\n    } else {\n        handleComplete();\n    }\n};\n\nconst handlePrev = () => {\n    if (onboardingIndex.value > 0) {\n        onboardingIndex.value -= 1;\n        triggerAnimation();\n    }\n};\n\nconst handleSkip = () => {\n    show.value = false;\n    try {\n        if (typeof uni !== 'undefined') {\n            const key = getOnboardingStorageKey();\n            uni.setStorageSync(key, true);\n        }\n    } catch (error) {\n        console.warn('handleSkip error', error);\n    }\n    emit('skip');\n};\n\nconst handleComplete = () => {\n    show.value = false;\n    try {\n        if (typeof uni !== 'undefined') {\n            const key = getOnboardingStorageKey();\n            uni.setStorageSync(key, true);\n        }\n    } catch (error) {\n        console.warn('handleComplete error', error);\n    }\n    emit('complete');\n};\n\nlet changeTimer: ReturnType<typeof setTimeout> | null = null;\n\nconst handleOnboardingChange = (event: any) => {\n    const newIndex = event.detail.current;\n    if (newIndex !== onboardingIndex.value) {\n        // 清除之前的定时器\n        if (changeTimer) {\n            clearTimeout(changeTimer);\n        }\n\n        onboardingIndex.value = newIndex;\n        activeCardId.value = null;\n\n        // 延迟触发动画，避免滑动过程中频繁更新\n        changeTimer = setTimeout(() => {\n            if (!isChanging.value) {\n                triggerAnimation();\n            }\n        }, 100);\n    }\n};\n\nconst handleDotClick = (index: number) => {\n    if (index !== onboardingIndex.value && !isChanging.value) {\n        onboardingIndex.value = index;\n        triggerAnimation();\n    }\n};\n\nconst handleCardClick = (slideIndex: number, cardIndex: number) => {\n    // 只允许点击当前页面的卡片\n    if (slideIndex !== onboardingIndex.value) return;\n\n    const cardId = `${slideIndex}-${cardIndex}`;\n    if (activeCardId.value === cardId) {\n        // 如果已经选中，则取消选中\n        activeCardId.value = null;\n    } else {\n        // 选中新卡片\n        activeCardId.value = cardId;\n    }\n};\n\nconst getCardStyle = (card: OnboardingCard, cardIndex: number, slideIndex: number, cardIdx: number) => {\n    const isActive = activeCardId.value === `${slideIndex}-${cardIdx}`;\n    const baseStyle: Record<string, any> = {\n        '--card-delay': `${card.delay || cardIndex * 100}ms`\n    };\n\n    // 选中时设置高 z-index，确保置顶\n    if (isActive) {\n        baseStyle['z-index'] = 999;\n    }\n\n    // 根据位置设置不同的初始位置（用于飞入动画）\n    const positions: Record<string, { x: string; y: string }> = {\n        'top-left': { x: '-120%', y: '-120%' },\n        'top-right': { x: '120%', y: '-120%' },\n        center: { x: '0', y: '-150%' },\n        'bottom-left': { x: '-120%', y: '120%' },\n        'bottom-right': { x: '120%', y: '120%' }\n    };\n\n    const pos = positions[card.position] || { x: '0', y: '0' };\n    baseStyle['--card-start-x'] = pos.x;\n    baseStyle['--card-start-y'] = pos.y;\n\n    return baseStyle;\n};\n\nonMounted(() => {\n    checkOnboarding();\n});\n</script>\n\n<style lang=\"scss\" scoped>\n.demo-guide {\n    position: fixed;\n    left: 0;\n    top: 0;\n    width: 100%;\n    height: 100%;\n    z-index: 99;\n    background: linear-gradient(135deg, #667eea 0%, #764ba2 25%, #f093fb 50%, #4facfe 75%, #00f2fe 100%);\n    background-size: 400% 400%;\n    animation: gradientShift 15s ease infinite;\n    display: flex;\n    flex-direction: column;\n    padding: 100rpx 30rpx 60rpx 30rpx;\n    box-sizing: border-box;\n    overflow: hidden;\n}\n\n@keyframes gradientShift {\n    0% {\n        background-position: 0% 50%;\n    }\n    50% {\n        background-position: 100% 50%;\n    }\n    100% {\n        background-position: 0% 50%;\n    }\n}\n\n.demo-guide__bg {\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    overflow: hidden;\n    pointer-events: none;\n}\n\n.demo-guide__bg-circle {\n    position: absolute;\n    border-radius: 50%;\n    background: rgba(255, 255, 255, 0.1);\n    animation: float 20s ease-in-out infinite;\n\n    &--1 {\n        width: 400rpx;\n        height: 400rpx;\n        top: -100rpx;\n        left: -100rpx;\n        animation-delay: 0s;\n    }\n\n    &--2 {\n        width: 300rpx;\n        height: 300rpx;\n        bottom: -50rpx;\n        right: -50rpx;\n        animation-delay: 5s;\n    }\n\n    &--3 {\n        width: 250rpx;\n        height: 250rpx;\n        top: 50%;\n        right: -50rpx;\n        animation-delay: 10s;\n    }\n}\n\n@keyframes float {\n    0%,\n    100% {\n        transform: translate(0, 0) scale(1);\n        opacity: 0.3;\n    }\n    33% {\n        transform: translate(50rpx, 50rpx) scale(1.1);\n        opacity: 0.5;\n    }\n    66% {\n        transform: translate(-50rpx, -50rpx) scale(0.9);\n        opacity: 0.4;\n    }\n}\n\n.onboarding-header {\n    position: relative;\n    z-index: 2;\n    padding-bottom: 32rpx;\n    text-align: center;\n}\n\n.onboarding-badge {\n    display: inline-flex;\n    align-items: center;\n    justify-content: center;\n    gap: 8rpx;\n    padding: 8rpx 24rpx;\n    border-radius: 999rpx;\n    border: 2rpx solid rgba(255, 255, 255, 0.8);\n    background: rgba(255, 255, 255, 0.15);\n    backdrop-filter: blur(10rpx);\n    font-size: 24rpx;\n    font-weight: 700;\n    color: #fff;\n    margin-bottom: 16rpx;\n    box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);\n    animation: badgePulse 2s ease-in-out infinite;\n}\n\n@keyframes badgePulse {\n    0%,\n    100% {\n        transform: scale(1);\n        box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);\n    }\n    50% {\n        transform: scale(1.05);\n        box-shadow: 0 6rpx 24rpx rgba(255, 255, 255, 0.3);\n    }\n}\n\n.onboarding-subtitle {\n    font-size: 40rpx;\n    font-weight: 800;\n    color: #fff;\n    text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.2);\n    margin-bottom: 8rpx;\n    letter-spacing: 2rpx;\n}\n\n.onboarding-subdesc {\n    font-size: 26rpx;\n    color: rgba(255, 255, 255, 0.9);\n    text-shadow: 0 1rpx 4rpx rgba(0, 0, 0, 0.1);\n}\n\n.onboarding-swiper {\n    flex: 1;\n    position: relative;\n    z-index: 2;\n\n    &--disabled {\n        touch-action: none;\n        pointer-events: auto;\n\n        :deep(.uni-swiper-wrapper) {\n            touch-action: none;\n        }\n    }\n}\n\n.onboarding-slide {\n    height: 100%;\n    position: relative;\n    padding: 20rpx;\n    box-sizing: border-box;\n    overflow: hidden;\n}\n\n.onboarding-card {\n    position: absolute;\n    background: rgba(255, 255, 255, 0.95);\n    backdrop-filter: blur(20rpx);\n    border-radius: 24rpx;\n    padding: 28rpx;\n    box-shadow:\n        0 12rpx 32rpx rgba(0, 0, 0, 0.15),\n        0 4rpx 12rpx rgba(0, 0, 0, 0.1);\n    animation: cardFlyIn 0.8s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;\n    opacity: 0;\n    transform: translate(var(--card-start-x, 0), var(--card-start-y, 0)) scale(0.8);\n    animation-delay: var(--card-delay, 0ms);\n    transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);\n    border: 2rpx solid rgba(255, 255, 255, 0.5);\n    cursor: pointer;\n    user-select: none;\n\n    &:active:not(.onboarding-card--active) {\n        transform: translate(0, 0) scale(0.98);\n    }\n\n    &:hover:not(.onboarding-card--active) {\n        transform: translate(0, 0) scale(1.02);\n    }\n\n    &--top-left {\n        top: 10%;\n        left: 4%;\n        width: 48%;\n    }\n\n    &--top-right {\n        top: 10%;\n        right: 4%;\n        width: 48%;\n    }\n\n    &--center {\n        top: 50%;\n        left: 50%;\n        width: 70% !important;\n        transform: translate(-50%, -50%) translate(var(--card-start-x, 0), var(--card-start-y, 0)) scale(0.8);\n        animation-name: cardFlyInCenter;\n        z-index: 10;\n\n        &:active:not(.onboarding-card--active) {\n            transform: translate(-50%, -50%) scale(0.98);\n        }\n\n        &:hover:not(.onboarding-card--active) {\n            transform: translate(-50%, -50%) scale(1.02);\n        }\n    }\n\n    &--bottom-left {\n        bottom: 15%;\n        left: 4%;\n        width: 48%;\n    }\n\n    &--bottom-right {\n        bottom: 15%;\n        right: 4%;\n        width: 48%;\n    }\n\n    &--active {\n        opacity: 1 !important;\n        transform: translate(0, 0) scale(1.05) !important;\n        box-shadow:\n            0 20rpx 48rpx rgba(41, 121, 255, 0.25),\n            0 8rpx 24rpx rgba(25, 190, 107, 0.2),\n            0 0 0 4rpx rgba(41, 121, 255, 0.2),\n            inset 0 0 0 1rpx rgba(255, 255, 255, 0.5);\n        border: 2rpx solid rgba(41, 121, 255, 0.4);\n        background: rgba(255, 255, 255, 1) !important;\n        animation: cardActiveGlow 3s ease-in-out infinite;\n        visibility: visible !important;\n\n        .onboarding-card__icon {\n            background: linear-gradient(135deg, rgba(41, 121, 255, 0.15), rgba(25, 190, 107, 0.15));\n            box-shadow: 0 4rpx 12rpx rgba(41, 121, 255, 0.2);\n            transform: scale(1.05);\n        }\n\n        .onboarding-card__title {\n            color: #303133 !important;\n            font-weight: 700;\n            text-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.05);\n        }\n\n        .onboarding-card__desc {\n            color: #606266 !important;\n        }\n\n        .onboarding-card__feature {\n            color: #909399 !important;\n        }\n\n        &::before {\n            content: '';\n            position: absolute;\n            top: -4rpx;\n            left: -4rpx;\n            right: -4rpx;\n            bottom: -4rpx;\n            border-radius: 26rpx;\n            background: linear-gradient(\n                135deg,\n                rgba(41, 121, 255, 0.3),\n                rgba(25, 190, 107, 0.3),\n                rgba(41, 121, 255, 0.3)\n            );\n            z-index: -1;\n            opacity: 0.4;\n            animation: cardActiveGlowRing 3s ease-in-out infinite;\n            filter: blur(12rpx);\n        }\n\n        &::after {\n            content: '';\n            position: absolute;\n            top: -2rpx;\n            left: -2rpx;\n            right: -2rpx;\n            bottom: -2rpx;\n            border-radius: 24rpx;\n            background: linear-gradient(135deg, rgba(41, 121, 255, 0.15), rgba(25, 190, 107, 0.15));\n            z-index: -1;\n            opacity: 0.6;\n            animation: cardActiveGlowInner 3s ease-in-out infinite;\n        }\n\n        &:active {\n            transform: translate(0, 0) scale(1.03) !important;\n        }\n    }\n\n    &--center.onboarding-card--active {\n        opacity: 1 !important;\n        transform: translate(-50%, -50%) scale(1.05) !important;\n        visibility: visible !important;\n\n        .onboarding-card__title {\n            color: #303133 !important;\n            font-weight: 700;\n            text-shadow: 0 1rpx 2rpx rgba(0, 0, 0, 0.05);\n        }\n\n        .onboarding-card__desc {\n            color: #606266 !important;\n        }\n\n        .onboarding-card__feature {\n            color: #909399 !important;\n        }\n\n        &:active {\n            transform: translate(-50%, -50%) scale(1.03) !important;\n        }\n    }\n}\n\n@keyframes cardActiveGlow {\n    0%,\n    100% {\n        box-shadow:\n            0 20rpx 48rpx rgba(41, 121, 255, 0.25),\n            0 8rpx 24rpx rgba(25, 190, 107, 0.2),\n            0 0 0 4rpx rgba(41, 121, 255, 0.2),\n            inset 0 0 0 1rpx rgba(255, 255, 255, 0.5);\n    }\n    50% {\n        box-shadow:\n            0 24rpx 56rpx rgba(41, 121, 255, 0.3),\n            0 12rpx 32rpx rgba(25, 190, 107, 0.25),\n            0 0 0 6rpx rgba(41, 121, 255, 0.25),\n            inset 0 0 0 1rpx rgba(255, 255, 255, 0.6);\n    }\n}\n\n@keyframes cardActiveGlowRing {\n    0%,\n    100% {\n        opacity: 0.4;\n        transform: scale(1);\n        filter: blur(12rpx);\n    }\n    50% {\n        opacity: 0.5;\n        transform: scale(1.01);\n        filter: blur(14rpx);\n    }\n}\n\n@keyframes cardActiveGlowInner {\n    0%,\n    100% {\n        opacity: 0.6;\n    }\n    50% {\n        opacity: 0.7;\n    }\n}\n\n// 根据size调整卡片大小\n.onboarding-card--small {\n    width: 42% !important;\n    padding: 20rpx;\n\n    .onboarding-card__icon {\n        width: 60rpx;\n        height: 60rpx;\n    }\n\n    .onboarding-card__title {\n        font-size: 28rpx;\n    }\n\n    .onboarding-card__desc {\n        font-size: 22rpx;\n    }\n}\n\n.onboarding-card--large {\n    width: 55% !important;\n    padding: 32rpx;\n\n    .onboarding-card__icon {\n        width: 100rpx;\n        height: 100rpx;\n    }\n\n    .onboarding-card__title {\n        font-size: 36rpx;\n    }\n\n    .onboarding-card__desc {\n        font-size: 26rpx;\n    }\n}\n\n.onboarding-card--medium {\n    width: 48%;\n    padding: 28rpx;\n}\n\n@keyframes cardFlyIn {\n    to {\n        opacity: 1;\n        transform: translate(0, 0) scale(1);\n    }\n}\n\n@keyframes cardFlyInCenter {\n    to {\n        opacity: 1;\n        transform: translate(-50%, -50%) scale(1);\n    }\n}\n\n.onboarding-card__icon {\n    width: 80rpx;\n    height: 80rpx;\n    border-radius: 20rpx;\n    background: linear-gradient(135deg, rgba(102, 126, 234, 0.1), rgba(118, 75, 162, 0.1));\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    margin-bottom: 16rpx;\n    box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);\n}\n\n.onboarding-card__content {\n    display: flex;\n    flex-direction: column;\n    gap: 12rpx;\n}\n\n.onboarding-card__title {\n    font-size: 32rpx;\n    font-weight: 700;\n    color: #303133;\n    line-height: 1.4;\n}\n\n.onboarding-card__desc {\n    font-size: 24rpx;\n    color: #606266;\n    line-height: 1.6;\n}\n\n.onboarding-card__features {\n    display: flex;\n    flex-direction: column;\n    gap: 8rpx;\n    margin-top: 8rpx;\n    padding-top: 16rpx;\n    border-top: 1rpx solid rgba(0, 0, 0, 0.06);\n}\n\n.onboarding-card__feature {\n    display: flex;\n    align-items: center;\n    gap: 12rpx;\n    font-size: 22rpx;\n    color: #909399;\n\n    &-dot {\n        width: 8rpx;\n        height: 8rpx;\n        border-radius: 50%;\n        background: linear-gradient(135deg, #667eea, #764ba2);\n        flex-shrink: 0;\n    }\n}\n\n.onboarding-dots {\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    gap: 16rpx;\n    margin: 24rpx 0;\n    position: relative;\n    z-index: 2;\n}\n\n.onboarding-dot {\n    width: 16rpx;\n    height: 16rpx;\n    border-radius: 50%;\n    background: rgba(255, 255, 255, 0.4);\n    transition: all 0.3s ease;\n    cursor: pointer;\n    position: relative;\n\n    &::before {\n        content: '';\n        position: absolute;\n        top: 50%;\n        left: 50%;\n        transform: translate(-50%, -50%);\n        width: 100%;\n        height: 100%;\n        border-radius: 50%;\n        background: rgba(255, 255, 255, 0.2);\n        transition: all 0.3s ease;\n    }\n\n    &--active {\n        width: 40rpx;\n        background: #fff;\n        box-shadow: 0 4rpx 12rpx rgba(255, 255, 255, 0.5);\n\n        &::before {\n            width: 200%;\n            height: 200%;\n            background: rgba(255, 255, 255, 0.1);\n        }\n    }\n}\n\n.onboarding-actions {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    gap: 20rpx;\n    position: relative;\n    z-index: 2;\n}\n\n.action-btn {\n    flex: 1;\n    height: 88rpx;\n    border-radius: 44rpx;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    gap: 12rpx;\n    font-size: 28rpx;\n    font-weight: 600;\n    color: #fff;\n    transition: all 0.3s ease;\n    position: relative;\n    overflow: hidden;\n    cursor: pointer;\n\n    &::before {\n        content: '';\n        position: absolute;\n        top: 0;\n        left: -100%;\n        width: 100%;\n        height: 100%;\n        background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);\n        transition: left 0.5s ease;\n    }\n\n    &:active::before {\n        left: 100%;\n    }\n\n    &--prev {\n        background: linear-gradient(135deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.15));\n        backdrop-filter: blur(10rpx);\n        border: 2rpx solid rgba(255, 255, 255, 0.4);\n        box-shadow: 0 4rpx 12rpx rgba(255, 255, 255, 0.1);\n\n        &:active {\n            transform: scale(0.95);\n            box-shadow: 0 2rpx 8rpx rgba(255, 255, 255, 0.2);\n        }\n    }\n\n    &--next {\n        background: linear-gradient(135deg, rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.2));\n        backdrop-filter: blur(10rpx);\n        border: 2rpx solid rgba(255, 255, 255, 0.5);\n        box-shadow: 0 8rpx 24rpx rgba(255, 255, 255, 0.2);\n\n        &:active {\n            transform: scale(0.95);\n            box-shadow: 0 4rpx 12rpx rgba(255, 255, 255, 0.3);\n        }\n    }\n\n    &--complete {\n        background: linear-gradient(135deg, #667eea, #764ba2);\n        box-shadow: 0 8rpx 24rpx rgba(102, 126, 234, 0.4);\n        animation: completePulse 2s ease-in-out infinite;\n\n        &:active {\n            transform: scale(0.95);\n        }\n    }\n}\n\n@keyframes completePulse {\n    0%,\n    100% {\n        box-shadow: 0 8rpx 24rpx rgba(102, 126, 234, 0.4);\n    }\n    50% {\n        box-shadow: 0 12rpx 32rpx rgba(102, 126, 234, 0.6);\n    }\n}\n</style>\n"
  },
  {
    "path": "src/components/demo-guide-use/demo-guide-use.vue",
    "content": "<template>\n    <view class=\"guide-wrapper\" :class=\"{ 'guide-wrapper--active': displayShow }\">\n        <!-- 目标插槽区域 -->\n        <view class=\"guide-wrapper__target\" :style=\"targetStyle\">\n            <slot />\n        </view>\n\n        <!-- 引导遮罩层 -->\n        <view v-if=\"displayShow\" class=\"demo-guide-overlay\" @touchmove.stop.prevent>\n            <!-- 全屏蒙层 -->\n            <view class=\"demo-guide-overlay__mask\"></view>\n\n            <!-- 气泡提示 -->\n            <view class=\"demo-guide-overlay__bubble\" :class=\"bubbleAnimationClass\" :style=\"bubblePositionStyle\">\n                <view class=\"demo-guide-overlay__hand\">{{ displayHand }}</view>\n                <view class=\"demo-guide-overlay__text\">\n                    <text>{{ text }}</text>\n                </view>\n                <u-button type=\"primary\" size=\"mini\" shape=\"circle\" @click.stop=\"handleClose\">\n                    {{ buttonText }}\n                </u-button>\n            </view>\n        </view>\n    </view>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, onMounted, ref, watch } from 'vue';\nimport { $u } from 'uview-pro';\n\nconst props = withDefaults(\n    defineProps<{\n        show?: boolean;\n        storageKey?: string;\n        text?: string;\n        hand?: string;\n        buttonText?: string;\n        placement?: 'top' | 'bottom' | 'left' | 'right' | 'auto';\n        position?: string | Record<string, any>;\n        immediate?: boolean | string;\n    }>(),\n    {\n        show: false,\n        storageKey: '',\n        text: '',\n        hand: '',\n        buttonText: '知道了',\n        placement: 'auto',\n        position: '',\n        immediate: false\n    }\n);\n\nconst emit = defineEmits(['close', 'checkStorage']);\nconst displayShow = ref(false);\nconst setDisplayShow = () => {\n    if (props.show) {\n        displayShow.value = true;\n    }\n    let showValue = false;\n    if (props.storageKey) {\n        showValue = !uni.getStorageSync(props.storageKey);\n    }\n    displayShow.value = props.immediate ? showValue : false;\n};\n\nconst displayHand = computed(() => {\n    if (props.hand) return props.hand;\n    switch (props.placement) {\n        case 'top':\n            return '👇';\n        case 'left':\n            return '👉';\n        case 'right':\n            return '👈';\n        case 'bottom':\n        default:\n            return '👆';\n    }\n});\n\nwatch(\n    () => [props.show, props.storageKey, props.immediate],\n    () => {\n        // #ifdef APP-HARMONY\n        setDisplayShow;\n        // #endif\n    }\n);\n\nconst bubbleAnimationClass = computed(() => {\n    const placement = props.placement === 'auto' ? 'bottom' : props.placement;\n    return `demo-guide-overlay__bubble--${placement}`;\n});\n\nconst bubblePositionStyle = computed(() => {\n    return $u.toStyle(props.position);\n});\n\nconst targetStyle = computed(() => {\n    const style: Record<string, any> = {};\n    if (displayShow.value) {\n        // 确保目标元素在最上层\n        style.zIndex = 20002;\n        style.pointerEvents = 'none';\n    }\n    return style;\n});\n\nconst handleClose = () => {\n    if (props.storageKey) uni.setStorageSync(props.storageKey, true);\n    displayShow.value = false;\n    emit('close');\n};\n\nfunction showByStorage() {\n    if (props.storageKey) {\n        const shown = !uni.getStorageSync(props.storageKey);\n        displayShow.value = shown;\n    }\n}\n\nfunction show(byStorage = false) {\n    if (byStorage) return showByStorage();\n    displayShow.value = true;\n}\n\nfunction close() {\n    handleClose();\n}\n\nonMounted(() => {\n    // #ifdef APP-HARMONY\n    if (props.storageKey) {\n        const shown = !uni.getStorageSync(props.storageKey);\n        emit('checkStorage', shown);\n    }\n    setDisplayShow();\n    // #endif\n});\n\ndefineExpose({\n    show,\n    close\n});\n</script>\n\n<style lang=\"scss\" scoped>\n.guide-wrapper {\n    position: relative;\n    display: block;\n\n    &__target {\n        position: relative;\n    }\n}\n\n.demo-guide-overlay {\n    position: fixed;\n    inset: 0;\n    z-index: 20000;\n    pointer-events: none; // 遮罩层本身不拦截事件\n    width: 100%;\n    height: 100vh;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n\n    &__mask {\n        position: absolute;\n        inset: 0;\n        // background: rgba(0, 0, 0, 0.5);\n        backdrop-filter: blur(8rpx);\n        pointer-events: auto; // 允许蒙层拦截所有事件，阻止页面交互\n        width: 100%;\n        height: 100vh;\n    }\n\n    &__bubble {\n        position: fixed;\n        min-width: 300rpx;\n        max-width: 520rpx;\n        padding: 24rpx 32rpx;\n        border-radius: 16rpx;\n        background: rgba(255, 255, 255, 0.98);\n        box-shadow: 0 12rpx 48rpx rgba(0, 0, 0, 0.2);\n        backdrop-filter: blur(12rpx);\n        display: flex;\n        flex-direction: column;\n        align-items: center;\n        gap: 16rpx;\n        z-index: 20003;\n        pointer-events: auto;\n        animation: bubbleFadeIn 0.3s ease-out;\n\n        &--top {\n            animation:\n                bubbleFadeIn 0.3s ease-out,\n                bubbleFloatTop 1.5s ease-in-out 0.3s infinite;\n        }\n\n        &--bottom {\n            animation:\n                bubbleFadeIn 0.3s ease-out,\n                bubbleFloatBottom 1.5s ease-in-out 0.3s infinite;\n        }\n\n        &--left {\n            animation:\n                bubbleFadeIn 0.3s ease-out,\n                bubbleFloatLeft 1.5s ease-in-out 0.3s infinite;\n        }\n\n        &--right {\n            animation:\n                bubbleFadeIn 0.3s ease-out,\n                bubbleFloatRight 1.5s ease-in-out 0.3s infinite;\n        }\n    }\n\n    &__hand {\n        font-size: 48rpx;\n        line-height: 1;\n    }\n\n    &__text {\n        font-size: 28rpx;\n        color: #666;\n        line-height: 1.6;\n        text-align: center;\n        font-weight: 500;\n    }\n}\n\n@keyframes bubbleFadeIn {\n    from {\n        opacity: 0;\n        transform: translateY(20rpx) scale(0.9);\n    }\n    to {\n        opacity: 1;\n        transform: translateY(0) scale(1);\n    }\n}\n\n@keyframes bubbleFloatTop {\n    0%,\n    100% {\n        transform: translateY(0);\n    }\n    50% {\n        transform: translateY(-12rpx);\n    }\n}\n\n@keyframes bubbleFloatBottom {\n    0%,\n    100% {\n        transform: translateY(0);\n    }\n    50% {\n        transform: translateY(12rpx);\n    }\n}\n\n@keyframes bubbleFloatLeft {\n    0%,\n    100% {\n        transform: translateX(0);\n    }\n    50% {\n        transform: translateX(-12rpx);\n    }\n}\n\n@keyframes bubbleFloatRight {\n    0%,\n    100% {\n        transform: translateX(0);\n    }\n    50% {\n        transform: translateX(12rpx);\n    }\n}\n</style>\n"
  },
  {
    "path": "src/components/demo-page/demo-page.vue",
    "content": "<template>\n    <view class=\"demo-page\" :class=\"{ 'has-tabbar': tabbar }\" :style=\"$u.toStyle(customStyle)\">\n        <!-- 引导页 -->\n        <!-- #ifdef APP-HARMONY || APP-PLUS -->\n        <demo-guide v-model:show=\"showOnboarding\" @complete=\"handleOnboardingComplete\" @skip=\"handleOnboardingSkip\" />\n        <!-- #endif -->\n        <view v-if=\"!showOnboarding\">\n            <!-- 导航栏 -->\n            <!-- #ifndef MP-ALIPAY -->\n            <u-navbar\n                v-if=\"!hideNav && !showOnboarding\"\n                :is-back=\"navBack\"\n                :title=\"navTitle || title\"\n                :background=\"background\"\n                :is-fixed=\"true\"\n                :immersive=\"false\"\n                back-icon-name=\"arrow-leftward\"\n                title-width=\"350\"\n                title-color=\"#ffffff\"\n                back-icon-color=\"#ffffff\"\n            >\n                <template #left>\n                    <view v-if=\"tabbar\" class=\"u-m-l-30\">\n                        <!-- #ifdef MP -->\n                        <u-icon\n                            custom-prefix=\"custom-icon\"\n                            name=\"theme-fill\"\n                            size=\"46\"\n                            color=\"#ffffff\"\n                            custom-style=\"margin-right:16px\"\n                            @click=\"$u.route('/pages/other/theme/index')\"\n                        ></u-icon>\n                        <!-- #endif -->\n                        <u-icon\n                            custom-prefix=\"custom-icon\"\n                            :name=\"darkModeIcon\"\n                            size=\"46\"\n                            color=\"#ffffff\"\n                            @click=\"switchTheme\"\n                        ></u-icon>\n                    </view>\n                    <view v-else>\n                        <!-- #ifdef H5 -->\n                        <u-icon\n                            custom-prefix=\"custom-icon\"\n                            :name=\"darkModeIcon\"\n                            size=\"46\"\n                            color=\"#ffffff\"\n                            @click=\"switchTheme\"\n                        ></u-icon>\n                        <!-- #endif -->\n                        <!-- #ifdef MP -->\n                        <u-icon\n                            name=\"share1\"\n                            size=\"48\"\n                            color=\"#ffffff\"\n                            custom-style=\"margin-left:7px\"\n                            custom-prefix=\"custom-icon\"\n                            @click=\"sharePage\"\n                        ></u-icon>\n                        <!-- #endif -->\n                    </view>\n                </template>\n                <!-- #ifndef MP -->\n                <template #right>\n                    <view class=\"u-m-r-20\">\n                        <u-icon\n                            v-if=\"tabbar\"\n                            custom-prefix=\"custom-icon\"\n                            name=\"theme-fill\"\n                            size=\"44\"\n                            color=\"#ffffff\"\n                            @click=\"$u.route('/pages/other/theme/index')\"\n                        ></u-icon>\n                        <u-icon\n                            name=\"share1\"\n                            size=\"46\"\n                            color=\"#ffffff\"\n                            custom-style=\"margin-left:10px\"\n                            custom-prefix=\"custom-icon\"\n                            @click=\"sharePage\"\n                        ></u-icon>\n                    </view>\n                </template>\n                <!-- #endif -->\n            </u-navbar>\n            <!-- #endif -->\n            <wx-tips v-if=\"showWxTips\" />\n            <!-- 标题 -->\n            <view v-if=\"title || desc\" class=\"demo-page_header\">\n                <view class=\"demo-page_title\">{{ title }}</view>\n                <view class=\"demo-page_desc\" v-if=\"desc\">{{ desc }}</view>\n            </view>\n            <!-- 标签栏 -->\n            <demo-guide-use\n                v-if=\"!tabbar && !hideTabs && tabList.length > 1\"\n                :immediate=\"guideImmediate[0]\"\n                :position=\"{ top: '500rpx', right: '200rpx' }\"\n                :storage-key=\"GUIDE_TABS_KEY\"\n                placement=\"bottom\"\n                text=\"左右切换体验：\\n演示：初步了解组件的各项能力\\n互动反馈：组件沉浸式体验评价\\nAPI文档：探索组件更多详细用法\"\n                button-text=\"下一步\"\n                @close=\"guideImmediate[1] = true\"\n            >\n                <view v-if=\"!tabbar && !hideTabs && tabList.length > 1\" class=\"demo-page-tabs\">\n                    <view class=\"demo-page-tabs__container\">\n                        <view\n                            v-for=\"(item, index) in tabList\"\n                            :key=\"index\"\n                            class=\"demo-page-tabs__item\"\n                            :class=\"{ 'demo-page-tabs__item--active': tabIndex === index }\"\n                            @click=\"change(index)\"\n                        >\n                            <view class=\"demo-page-tabs__item-content\">\n                                <text class=\"demo-page-tabs__item-text\">{{ item.name }}</text>\n                                <view class=\"demo-page-tabs__item-indicator\"></view>\n                            </view>\n                        </view>\n                        <view class=\"demo-page-tabs__slider\" :style=\"sliderStyle\"></view>\n                    </view>\n                </view>\n            </demo-guide-use>\n            <!-- #ifdef MP-WEIXIN -->\n            <ad-custom v-if=\"!hideAd && !tabbar\" unit-id=\"adunit-f5898174f44ec220\"></ad-custom>\n            <!-- #endif -->\n            <!-- 1.组件演示 -->\n            <view class=\"demo-page-default\" v-show=\"currentTabName === TAB_NAMES.base\">\n                <u-transition :show=\"transitionShow\" :name=\"fabTransitionName\" :duration=\"1300\" :key=\"fabKey\">\n                    <slot />\n                </u-transition>\n            </view>\n            <!-- 2.互动反馈 -->\n            <view class=\"demo-page_scene\" v-show=\"currentTabName === TAB_NAMES.interaction && enableExperience\">\n                <u-transition :show=\"transitionShow\" :name=\"fabTransitionName\" :duration=\"1300\" :key=\"fabKey\">\n                    <view class=\"demo-page_toolbar\">\n                        <view class=\"toolbar-head\">\n                            <u-gap></u-gap>\n                            <u-line-progress\n                                :percent=\"experienceProgress\"\n                                height=\"12px\"\n                                :show-text=\"false\"\n                                active-color=\"var(--u-type-primary)\"\n                                inactive-color=\"rgba(0,0,0,0.08)\"\n                            />\n                            <text class=\"toolbar-head__tip\">{{ experienceHint }}</text>\n                        </view>\n                        <u-gap></u-gap>\n\n                        <view class=\"toolbar-stats\">\n                            <view class=\"toolbar-stat-card\">\n                                <view class=\"stat-card__icon\">\n                                    <u-icon name=\"thumb-up-fill\" size=\"40\" color=\"#ff4757\"></u-icon>\n                                </view>\n                                <view class=\"stat-card__content\">\n                                    <view class=\"stat-card__value\">{{ toolbarState.liked ? '已点赞' : '未点赞' }}</view>\n                                    <view class=\"stat-card__label\">点赞状态</view>\n                                </view>\n                            </view>\n                            <view class=\"toolbar-stat-card\">\n                                <view class=\"stat-card__icon\">\n                                    <u-icon name=\"star-fill\" size=\"40\" color=\"#ffa502\"></u-icon>\n                                </view>\n                                <view class=\"stat-card__content\">\n                                    <view class=\"stat-card__value\">\n                                        {{ toolbarState.bookmarked ? '已收藏' : '未收藏' }}\n                                    </view>\n                                    <view class=\"stat-card__label\">收藏状态</view>\n                                </view>\n                            </view>\n                            <view class=\"toolbar-stat-card\">\n                                <view class=\"stat-card__icon\">\n                                    <u-icon\n                                        custom-prefix=\"custom-icon\"\n                                        name=\"hand-sparkles\"\n                                        size=\"40\"\n                                        color=\"#5f27cd\"\n                                    ></u-icon>\n                                </view>\n                                <view class=\"stat-card__content\">\n                                    <view class=\"stat-card__value\">{{ toolbarState.interactions }}</view>\n                                    <view class=\"stat-card__label\">互动次数</view>\n                                </view>\n                            </view>\n                        </view>\n                        <view class=\"toolbar-actions\">\n                            <u-button\n                                shape=\"circle\"\n                                size=\"mini\"\n                                :type=\"toolbarState.liked ? 'error' : 'default'\"\n                                :plain=\"!toolbarState.liked\"\n                                @click=\"toggleLike\"\n                            >\n                                <u-icon :name=\"toolbarState.liked ? 'thumb-up-fill' : 'thumb-up'\" size=\"36\"></u-icon>\n                                <text class=\"toolbar-actions__text\">{{ toolbarState.liked ? '已点赞' : '点赞' }}</text>\n                            </u-button>\n                            <u-button\n                                shape=\"circle\"\n                                size=\"mini\"\n                                :type=\"toolbarState.bookmarked ? 'primary' : 'default'\"\n                                :plain=\"!toolbarState.bookmarked\"\n                                @click=\"toggleBookmark\"\n                            >\n                                <u-icon :name=\"toolbarState.bookmarked ? 'star-fill' : 'star'\" size=\"36\"></u-icon>\n                                <text class=\"toolbar-actions__text\">{{\n                                    toolbarState.bookmarked ? '已收藏' : '收藏'\n                                }}</text>\n                            </u-button>\n                        </view>\n                        <u-gap></u-gap>\n\n                        <view class=\"toolbar-rate\">\n                            <view class=\"toolbar-rate__label\">体验评分</view>\n                            <u-rate\n                                :count=\"5\"\n                                :model-value=\"toolbarState.rating\"\n                                allow-half\n                                active-color=\"var(--u-type-warning)\"\n                                @change=\"handleRateChange\"\n                            />\n                            <text class=\"toolbar-rate__desc\">{{ rateText }}</text>\n                        </view>\n                        <u-gap></u-gap>\n\n                        <view class=\"toolbar-section\">\n                            <view class=\"toolbar-section__title\">\n                                <u-icon\n                                    custom-prefix=\"custom-icon\"\n                                    name=\"file-text\"\n                                    size=\"32\"\n                                    color=\"var(--u-type-primary)\"\n                                ></u-icon>\n                                <text>体验记录</text>\n                            </view>\n                            <view class=\"toolbar-log\" v-if=\"experienceLogs && experienceLogs.length\">\n                                <view v-for=\"(log, index) in experienceLogs\" :key=\"index\" class=\"toolbar-log__item\">\n                                    <view class=\"toolbar-log__time\">{{ formatLogTime(index) }}</view>\n                                    <view class=\"toolbar-log__content\">{{ log }}</view>\n                                </view>\n                            </view>\n                            <view v-else class=\"toolbar-empty\">\n                                <u-icon\n                                    custom-prefix=\"custom-icon\"\n                                    name=\"file-text\"\n                                    size=\"48\"\n                                    color=\"var(--u-tips-color)\"\n                                ></u-icon>\n                                <text>暂无体验记录，开始互动吧</text>\n                            </view>\n                        </view>\n                    </view>\n                </u-transition>\n            </view>\n            <!-- 3.API文档 -->\n            <view class=\"demo-page_api\" v-show=\"currentTabName === TAB_NAMES.api\">\n                <slot name=\"api\">\n                    <view v-if=\"apiContent\">\n                        <!-- #ifdef APP-HARMONY -->\n                        <zero-markdown-view\n                            :themeColor=\"$u.getColor('primary')\"\n                            :markdown=\"apiContent\"\n                        ></zero-markdown-view>\n                        <!-- #endif -->\n                    </view>\n                    <view v-else>\n                        <u-gap height=\"100\"></u-gap>\n                        <u-empty mode=\"data\" text=\"暂无文档\"></u-empty>\n                    </view>\n                </slot>\n            </view>\n            <!-- 互动反馈组件FAB -->\n            <!-- #ifndef H5 -->\n            <demo-guide-use\n                v-if=\"!tabbar && showFab\"\n                :immediate=\"guideImmediate[1]\"\n                :position=\"{ bottom: '100rpx', right: '200rpx' }\"\n                :storage-key=\"GUIDE_FAB_KEY\"\n                placement=\"left\"\n                text=\"这里可以切换主题与预览炫酷动效\"\n                button-text=\"去试试\"\n                @close=\"guideImmediate[2] = true\"\n            >\n                <view class=\"demo-page_feedback\" v-show=\"!tabbar\">\n                    <u-fab\n                        ref=\"uFabRef\"\n                        type=\"primary\"\n                        direction=\"top\"\n                        :draggable=\"true\"\n                        :autoStick=\"true\"\n                        :gap=\"{ right: 20, bottom: 130 }\"\n                    >\n                        <u-button\n                            shape=\"circle\"\n                            size=\"mini\"\n                            type=\"warning\"\n                            custom-class=\"demo-page-fabbtn\"\n                            @click=\"toggleTheme\"\n                        >\n                            <u-icon custom-prefix=\"custom-icon\" name=\"magic-sparkles\" size=\"38\"></u-icon>\n                        </u-button>\n\n                        <u-button\n                            shape=\"circle\"\n                            size=\"mini\"\n                            type=\"success\"\n                            custom-class=\"demo-page-fabbtn\"\n                            @click=\"playFabAnimation\"\n                        >\n                            <u-icon custom-prefix=\"custom-icon\" name=\"hand-sparkles\" size=\"38\"></u-icon>\n                        </u-button>\n                    </u-fab>\n                </view>\n            </demo-guide-use>\n            <!-- #endif -->\n            <!-- 底部标签栏 -->\n            <demo-guide-use\n                v-if=\"tabbar && !showOnboarding\"\n                ref=\"tabbarGuideRef\"\n                :position=\"{ bottom: '300rpx', left: '100rpx' }\"\n                :storage-key=\"GUIDE_TABBAR_KEY\"\n                placement=\"top\"\n                text=\"切换底部标签栏，探索更多精彩内容\"\n                button-text=\"我知道了\"\n            >\n                <u-tabbar\n                    v-if=\"tabbar && !showOnboarding\"\n                    v-model=\"current\"\n                    :mid-button=\"true\"\n                    :list=\"tabbarList\"\n                    :active-color=\"$u.color.primary\"\n                ></u-tabbar>\n            </demo-guide-use>\n            <!-- 体验提示 -->\n            <u-transition name=\"fade\" :show=\"Boolean(xpToast)\">\n                <view v-if=\"xpToast\" class=\"experience-toast\">\n                    <view class=\"experience-toast__inner\"> +{{ xpToast.amount }} XP · {{ xpToast.source }} </view>\n                </view>\n            </u-transition>\n        </view>\n        <u-action-sheet v-model=\"actionSheetShow\" :safe-area-inset-bottom=\"true\">\n            <u-action-sheet-item padding=\"0\">\n                <u-text\n                    text=\"分享给朋友\"\n                    size=\"32\"\n                    openType=\"share\"\n                    :block=\"true\"\n                    line-height=\"50px\"\n                    align=\"center\"\n                ></u-text>\n            </u-action-sheet-item>\n        </u-action-sheet>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-input',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { $u, useTheme, useToast } from 'uview-pro';\nimport { ref, computed, onMounted, onUnmounted, reactive, type PropType, watch } from 'vue';\nimport { getMarkdown } from '@/api';\nimport type { TabbarItem, TabsItem, ThemeType } from '@/uni_modules/uview-pro/types/global';\nimport { useI18n } from 'vue-i18n';\nimport { useExperience } from '@/common/useExperience';\nimport { useExperienceCenter } from '@/common/useExperienceCenter';\nimport DemoGuide from '@/components/demo-guide/demo-guide.vue';\nimport DemoGuideUse from '@/components/demo-guide-use/demo-guide-use.vue';\nimport { GUIDE_TABS_KEY, GUIDE_FAB_KEY, GUIDE_TABBAR_KEY, isPlatform } from '@/common/constant';\n\nconst { darkMode, getDarkMode, setDarkMode, setTheme, currentTheme, getAvailableThemes } = useTheme();\n\nconst props = defineProps({\n    navTitle: {\n        type: String,\n        default: ''\n    },\n    navBack: {\n        type: Boolean,\n        default: true\n    },\n    hideNav: {\n        type: Boolean,\n        default: false\n    },\n    tabbar: {\n        type: Boolean,\n        default: false\n    },\n    hideTabs: {\n        type: Boolean,\n        default: false\n    },\n    hideAd: {\n        type: Boolean,\n        default: false\n    },\n    showWxTips: {\n        type: Boolean,\n        default: false\n    },\n    title: {\n        type: String,\n        default: ''\n    },\n    desc: {\n        type: String,\n        default: ''\n    },\n    scenes: {\n        type: Array as PropType<SceneItem[]>,\n        default: () => []\n    },\n    apis: {\n        type: String as PropType<string>,\n        default: ''\n    },\n    faqs: {\n        type: Array as PropType<FaqItem[]>,\n        default: () => []\n    },\n    enableExperience: {\n        type: Boolean,\n        default: true\n    },\n    experienceKey: {\n        type: String,\n        default: ''\n    },\n    extras: {\n        type: Array,\n        default: () => []\n    },\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: ''\n    }\n});\n\ninterface SceneItem {\n    title: string;\n    desc: string;\n    demo?: any;\n}\ninterface FaqItem {\n    q: string;\n    a: string;\n}\n\nconst background = reactive({\n    backgroundColor: 'var(--u-type-primary)',\n    // 渐变色\n    backgroundImage: 'linear-gradient(90deg, var(--u-type-primary-dark), var(--u-type-primary-disabled))'\n});\n\nconst { t } = useI18n();\n\nconst guideImmediate = ref([true, false]);\nconst tabbarGuideRef = ref();\nconst toast = useToast();\nconst actionSheetShow = ref(false);\nfunction showTabbarGuide() {\n    tabbarGuideRef.value.show();\n}\n\nfunction showToast(title: string, type: ThemeType = 'success') {\n    toast.show({\n        title,\n        type,\n        duration: 2000,\n        icon: true,\n        position: 'top'\n    });\n}\n\nconst darkModeIcon = computed(() => {\n    switch (darkMode.value) {\n        case 'light':\n            return 'sun';\n        case 'dark':\n            return 'moon';\n        case 'auto':\n            return 'auto';\n        default:\n            return 'sun';\n    }\n});\n\n// 定义响应式数据\nconst tabbarList = computed<TabbarItem[]>(() => {\n    return [\n        {\n            text: t('nav.components'),\n            iconPath: 'component',\n            selectedIconPath: 'component-fill',\n            pagePath: '/pages/example/components',\n            customIcon: true\n        },\n        {\n            text: t('nav.js'),\n            iconPath: 'tool',\n            selectedIconPath: 'tool-fill',\n            pagePath: '/pages/example/js',\n            customIcon: true\n        },\n        {\n            iconPath: 'map-circle',\n            selectedIconPath: 'map-circle-fill',\n            text: t('nav.experience'),\n            pagePath: '/pages/example/experienceMap',\n            midButton: true,\n            customIcon: true\n        },\n        {\n            text: t('nav.template'),\n            iconPath: 'template',\n            selectedIconPath: 'template-fill',\n            pagePath: '/pages/example/template',\n            customIcon: true\n        },\n        {\n            text: t('nav.about'),\n            iconPath: 'about',\n            selectedIconPath: 'about-fill',\n            pagePath: '/pages/example/about',\n            customIcon: true\n        }\n    ];\n});\n\nconst current = ref<number>(0);\n\nconst slots = defineSlots();\nconst TAB_NAMES = {\n    base: '组件演示',\n    interaction: '互动反馈',\n    api: 'API文档'\n} as const;\nconst apiContent = ref<String>('');\nconst showOnboarding = ref(false);\n\nconst enableExperience = computed(() => props.enableExperience);\nconst tabList = computed(() => {\n    const result: TabsItem[] = [{ name: TAB_NAMES.base, hidden: false }];\n    if (enableExperience.value) {\n        result.push({ name: TAB_NAMES.interaction, hidden: false });\n    }\n    result.push({ name: TAB_NAMES.api, hidden: props.apis && isPlatform('HarmonyOS') ? false : true });\n    return result.filter(item => !item.hidden);\n});\nconst tabIndex = ref(0);\nconst currentTabName = computed(() => tabList.value[tabIndex.value]?.name || TAB_NAMES.base);\n\nconst showFab = computed(() => {\n    if (props.hideTabs) {\n        return false;\n    }\n    if (currentTabName.value === TAB_NAMES.base || currentTabName.value === TAB_NAMES.interaction) {\n        return true;\n    }\n    return false;\n});\nwatch(\n    tabList,\n    list => {\n        if (!list.length) {\n            tabIndex.value = 0;\n            return;\n        }\n        if (tabIndex.value >= list.length) {\n            tabIndex.value = list.length - 1;\n        }\n    },\n    { immediate: true }\n);\n\nconst apis = computed<string>(() => props.apis ?? '');\nconst experienceKey = computed(() => props.experienceKey || props.title || 'default');\nconst { logs: experienceLogs, recordAction } = useExperience(experienceKey.value);\nconst { lastGain } = useExperienceCenter();\nconst storageKey = computed(() => {\n    const base = props.experienceKey || props.title || 'default';\n    return `uview-demo-experience-${base}`;\n});\nconst toolbarState = ref({\n    liked: false,\n    bookmarked: false,\n    rating: 0,\n    interactions: 0\n});\nconst xpToast = ref<{ amount: number; source: string } | null>(null);\nlet xpToastTimer: ReturnType<typeof setTimeout> | null = null;\nconst experienceProgress = computed(() => {\n    const likeScore = toolbarState.value.liked ? 15 : 0;\n    const bookmarkScore = toolbarState.value.bookmarked ? 20 : 0;\n    const ratingScore = toolbarState.value.rating * 10;\n    const interactionScore = Math.min(toolbarState.value.interactions * 8, 45);\n    const total = likeScore + bookmarkScore + ratingScore + interactionScore;\n    return Math.min(100, total);\n});\nconst rateText = computed(() => {\n    if (!toolbarState.value.rating) return '请为体验评分';\n    if (toolbarState.value.rating >= 4.5) return '沉浸式体验';\n    if (toolbarState.value.rating >= 3) return '不错，可以继续优化';\n    return '欢迎继续提建议';\n});\nconst experienceHint = computed(() => {\n    if (experienceProgress.value >= 80) return '体验任务完成度很高，继续探索吧';\n    if (experienceProgress.value >= 40) return '完成互动可解锁更多提示';\n    return '点击上方按钮即可累积体验值';\n});\n\nconst handleOnboardingComplete = () => {\n    showOnboarding.value = false;\n};\n\nconst handleOnboardingSkip = () => {\n    showOnboarding.value = false;\n};\nwatch(\n    () => lastGain.value?.timestamp,\n    () => {\n        if (!lastGain.value) return;\n        xpToast.value = {\n            amount: lastGain.value.amount,\n            source: lastGain.value.source\n        };\n        if (xpToastTimer) {\n            clearTimeout(xpToastTimer);\n        }\n        xpToastTimer = setTimeout(() => {\n            xpToast.value = null;\n        }, 1800);\n    }\n);\nonUnmounted(() => {\n    if (xpToastTimer) {\n        clearTimeout(xpToastTimer);\n    }\n});\n\nconst persistToolbarState = () => {\n    try {\n        if (typeof uni === 'undefined') return;\n        const payload = {\n            ...toolbarState.value\n        };\n        uni.setStorageSync(storageKey.value, payload);\n    } catch (error) {\n        console.warn('persistToolbarState error', error);\n    }\n};\nconst loadToolbarState = () => {\n    try {\n        if (typeof uni === 'undefined') return;\n        const cache = uni.getStorageSync(storageKey.value) || {};\n        if (Object.keys(cache).length) {\n            toolbarState.value = Object.assign({}, toolbarState.value, cache);\n        }\n    } catch (error) {\n        console.warn('loadToolbarState error', error);\n    }\n};\nconst trackInteraction = (message: string) => {\n    toolbarState.value.interactions += 1;\n    recordAction(message);\n    persistToolbarState();\n};\nconst toggleLike = () => {\n    toolbarState.value.liked = !toolbarState.value.liked;\n    trackInteraction(toolbarState.value.liked ? '已点赞当前组件' : '取消点赞');\n};\nconst toggleBookmark = () => {\n    toolbarState.value.bookmarked = !toolbarState.value.bookmarked;\n    trackInteraction(toolbarState.value.bookmarked ? '收藏到本地体验集' : '取消收藏');\n\n    // 同步保存到收藏列表\n    if (toolbarState.value.bookmarked) {\n        addToFavorites();\n    } else {\n        removeFromFavorites();\n    }\n};\n\n// 添加到收藏列表\nconst addToFavorites = () => {\n    try {\n        if (typeof uni === 'undefined' || typeof getCurrentPages === 'undefined') return;\n        const STORAGE_KEY = 'uview-favorites';\n        const favorites = uni.getStorageSync(STORAGE_KEY) || [];\n        const pages = getCurrentPages();\n        if (!pages || pages.length === 0) return;\n        const currentPage = pages[pages.length - 1];\n        const currentPath = currentPage?.route || '';\n        const fullPath = '/' + currentPath;\n\n        // 检查是否已收藏\n        const exists = favorites.some((item: any) => item.path === fullPath);\n        if (exists) return;\n\n        // 获取组件信息\n        const componentTitle = props.title || '未命名组件';\n        const componentDesc = props.desc || '';\n\n        const favoriteItem = {\n            path: fullPath,\n            title: componentTitle,\n            desc: componentDesc,\n            icon: props.experienceKey || currentPath.split('/').pop() || '',\n            collectedAt: Date.now()\n        };\n\n        favorites.unshift(favoriteItem);\n        uni.setStorageSync(STORAGE_KEY, favorites);\n    } catch (error) {\n        console.warn('addToFavorites error', error);\n    }\n};\n\n// 从收藏列表移除\nconst removeFromFavorites = () => {\n    try {\n        if (typeof uni === 'undefined' || typeof getCurrentPages === 'undefined') return;\n        const STORAGE_KEY = 'uview-favorites';\n        const favorites = uni.getStorageSync(STORAGE_KEY) || [];\n        const pages = getCurrentPages();\n        if (!pages || pages.length === 0) return;\n        const currentPage = pages[pages.length - 1];\n        const currentPath = currentPage?.route || '';\n        const fullPath = '/' + currentPath;\n\n        const filtered = favorites.filter((item: any) => item.path !== fullPath);\n        uni.setStorageSync(STORAGE_KEY, filtered);\n    } catch (error) {\n        console.warn('removeFromFavorites error', error);\n    }\n};\nconst handleRateChange = (value: number) => {\n    toolbarState.value.rating = value;\n    trackInteraction(`评分 ${value} 分`);\n};\n\n// FAB 动效预览相关\nconst transitionNames = ['fade', 'slide-up', 'slide-down', 'slide-left', 'slide-right', 'zoom-in', 'zoom-out'] as const;\nconst fabTransitionName = ref<(typeof transitionNames)[number]>('fade');\nconst transitionTexts = {\n    fade: 'fade 淡入淡出',\n    'slide-up': 'slide-up 上滑',\n    'slide-down': 'slide-down 下滑',\n    'slide-left': 'slide-left 左滑',\n    'slide-right': 'slide-right 右滑',\n    'zoom-in': '`zoom-in 放大',\n    'zoom-out': 'zoom-out 缩小'\n};\nconst fabColor = ref('#2979ff');\nconst transitionShow = ref(true);\nconst fabKey = ref(0);\nconst fabColors = [\n    '#2979ff', // primary\n    '#19be6b', // success\n    '#ff9900', // warning\n    '#ff4757', // error\n    '#5f27cd', // purple\n    '#00d2d3', // cyan\n    '#ff6348' // coral\n];\n\nconst themeNames = getAvailableThemes().map(theme => theme.name);\nconst toggleTheme = () => {\n    const currentIndex = themeNames.indexOf(currentTheme.value?.name || 'uviewpro');\n    const nextIndex = (currentIndex + 1) % themeNames.length;\n    const nextTheme = themeNames[nextIndex];\n    setTheme(nextTheme);\n    trackInteraction('触发主题预览');\n    $u.debounce(() => {\n        showToast(`已切换到「${nextTheme}」主题`, 'success');\n    }, 600);\n};\n\nconst playFabAnimation = () => {\n    // 随机选择transition效果\n    const randomIndex = Math.floor(Math.random() * transitionNames.length);\n    fabTransitionName.value = transitionNames[randomIndex];\n\n    // 随机选择颜色\n    const colorIndex = Math.floor(Math.random() * fabColors.length);\n    fabColor.value = fabColors[colorIndex];\n\n    // 触发动画：先隐藏再显示\n    transitionShow.value = false;\n    fabKey.value += 1;\n    setTimeout(() => {\n        transitionShow.value = true;\n    }, 50);\n\n    trackInteraction('触发随机动效预览');\n    if (typeof uni !== 'undefined' && typeof uni.vibrateShort === 'function') {\n        uni.vibrateShort();\n    }\n    $u.debounce(() => {\n        showToast(`随机动效预览「${transitionTexts?.[fabTransitionName.value] ?? '动画'}」已渲染`, 'success');\n    }, 1300);\n};\n\nconst formatLogTime = (index: number) => {\n    // 简单的相对时间显示\n    const total = experienceLogs.value?.length || 0;\n    const reverseIndex = total - index - 1;\n    if (reverseIndex === 0) return '刚刚';\n    if (reverseIndex === 1) return '1次前';\n    return `${reverseIndex}次前`;\n};\n\nfunction switchTheme() {\n    switch (getDarkMode()) {\n        case 'light':\n            setDarkMode('dark');\n            break;\n        case 'dark':\n            setDarkMode('auto');\n            break;\n        case 'auto':\n            setDarkMode('light');\n            break;\n        default:\n            setDarkMode('dark');\n            break;\n    }\n}\n// 定义change事件回调函数\nconst change = (index: number) => {\n    tabIndex.value = index;\n};\n\n// 计算滑动指示器的样式\nconst sliderStyle = computed(() => {\n    if (tabList.value.length === 0) return {};\n\n    const itemWidth = 100 / tabList.value.length;\n    const left = tabIndex.value * itemWidth;\n\n    return {\n        width: `${itemWidth}%`,\n        left: `${left}%`,\n        '--primary-color': $u.color.primary\n    };\n});\n\nfunction sharePage() {\n    const pages = getCurrentPages();\n    // 页面栈中的最后一个即为项为当前页面，route属性为页面路径\n    const pageUrl = pages[pages.length - 1].route as string;\n    const fullPath = 'https://h5.uviewpro.cn/#/' + pageUrl;\n    // #ifdef H5\n    window.open(fullPath);\n    // #endif\n    // #ifdef APP\n    plus.runtime.openURL(fullPath);\n    // #endif\n    // #ifdef MP\n    actionSheetShow.value = true;\n    // #endif\n}\n\nonMounted(() => {\n    // #ifndef MP\n    if (apis.value) {\n        getMarkdown(apis.value).then((res: any) => {\n            apiContent.value = res;\n        });\n    }\n    // #endif\n});\nwatch(\n    () => storageKey.value,\n    () => {\n        loadToolbarState();\n    },\n    { immediate: true }\n);\n\ndefineExpose({\n    showTabbarGuide,\n    changeTab: change\n});\n</script>\n\n<style lang=\"scss\" scoped>\n.demo-page {\n    width: 100%;\n    min-height: 100vh;\n    // padding-bottom: 30rpx;\n    overflow-y: auto;\n    background-color: $u-bg-white;\n    -webkit-font-smoothing: antialiased;\n    color: $u-main-color;\n    transition: background 0.3s ease;\n\n    &.has-tabbar {\n        background-image: linear-gradient(\n            135deg,\n            rgba(var(--u-type-primary-rgb, 41, 121, 255), 0.04) 0%,\n            rgba(var(--u-type-success-rgb, 25, 190, 107), 0.04) 40%,\n            rgba(var(--u-type-warning-rgb, 255, 153, 0), 0.04) 100%\n        );\n    }\n\n    &_api,\n    &_scene,\n    &_fap {\n        padding: 24rpx;\n    }\n    &_header {\n        padding: 24rpx;\n\n        margin-bottom: 24rpx;\n    }\n    &_title {\n        font-size: 36rpx;\n        font-weight: bold;\n        color: $u-type-primary;\n    }\n    &_desc {\n        color: $u-tips-color;\n        font-size: 26rpx;\n        margin-top: 8rpx;\n    }\n    &_feedback {\n        text-align: center;\n        :deep(.demo-page-fabbtn) {\n            min-width: auto !important;\n            box-sizing: border-box;\n            width: 55px !important;\n            height: 55px !important;\n            border-radius: 50px !important;\n            margin: 0 8rpx 30rpx 8rpx;\n            box-shadow: 0 10rpx 26rpx $u-shadow-color;\n        }\n    }\n    &_toolbar {\n        margin: 0 24rpx 20rpx;\n        padding: 24rpx;\n        border-radius: 18rpx;\n        background: $u-bg-white;\n        border: 1px solid $u-border-color;\n        box-shadow: 0 10rpx 26rpx $u-shadow-color;\n        display: flex;\n        flex-direction: column;\n        gap: 20rpx;\n    }\n}\n\n// 自定义 Tabs 样式\n.demo-page-tabs {\n    background-color: $u-bg-white;\n    backdrop-filter: blur(20rpx);\n    border-bottom: 1rpx solid rgba(0, 0, 0, 0.06);\n    box-shadow:\n        0 2rpx 12rpx rgba(0, 0, 0, 0.04),\n        inset 0 -1rpx 0 rgba(0, 0, 0, 0.02);\n    position: relative;\n    z-index: 10;\n\n    &__container {\n        position: relative;\n        display: flex;\n        align-items: center;\n        height: 88rpx;\n        padding: 0 24rpx;\n    }\n\n    &__item {\n        flex: 1;\n        height: 100%;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        position: relative;\n        cursor: pointer;\n        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n        z-index: 2;\n        overflow: hidden;\n\n        &::before {\n            content: '';\n            position: absolute;\n            top: 50%;\n            left: 50%;\n            width: 0;\n            height: 0;\n            border-radius: 50%;\n            background: radial-gradient(circle, rgba(var(--u-type-primary-rgb, 41, 121, 255), 0.1), transparent);\n            transform: translate(-50%, -50%);\n            transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n        }\n\n        &--active {\n            .demo-page-tabs__item-text {\n                color: var(--primary-color, var(--u-type-primary));\n                font-weight: 700;\n                transform: scale(1.05);\n                text-shadow: 0 2rpx 8rpx rgba(var(--u-type-primary-rgb, 41, 121, 255), 0.2);\n            }\n\n            .demo-page-tabs__item-indicator {\n                opacity: 1;\n                transform: scaleX(1);\n            }\n\n            &::before {\n                width: 200rpx;\n                height: 200rpx;\n            }\n        }\n\n        &:active {\n            transform: scale(0.98);\n        }\n\n        &:hover:not(&--active) {\n            .demo-page-tabs__item-text {\n                color: $u-tips-color;\n            }\n        }\n    }\n\n    &__item-content {\n        position: relative;\n        display: flex;\n        flex-direction: column;\n        align-items: center;\n        gap: 8rpx;\n    }\n\n    &__item-text {\n        font-size: 28rpx;\n        color: $u-content-color;\n        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n        position: relative;\n        z-index: 2;\n    }\n\n    &__item-indicator {\n        width: 48rpx;\n        height: 6rpx;\n        border-radius: 3rpx;\n        background: linear-gradient(\n            90deg,\n            var(--primary-color, var(--u-type-primary)),\n            rgba(var(--u-type-primary-rgb, 41, 121, 255), 0.6)\n        );\n        opacity: 0;\n        transform: scaleX(0);\n        transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);\n        box-shadow: 0 2rpx 12rpx rgba(var(--u-type-primary-rgb, 41, 121, 255), 0.4);\n        position: relative;\n\n        &::after {\n            content: '';\n            position: absolute;\n            top: 50%;\n            left: 50%;\n            transform: translate(-50%, -50%);\n            width: 100%;\n            height: 100%;\n            background: radial-gradient(ellipse, rgba(255, 255, 255, 0.5), transparent);\n            border-radius: 3rpx;\n        }\n    }\n\n    &__slider {\n        position: absolute;\n        bottom: 0;\n        height: 6rpx;\n        background: linear-gradient(\n            90deg,\n            rgba(var(--u-type-primary-rgb, 41, 121, 255), 0.3),\n            var(--primary-color, var(--u-type-primary)),\n            rgba(var(--u-type-primary-rgb, 41, 121, 255), 0.8),\n            var(--primary-color, var(--u-type-primary)),\n            rgba(var(--u-type-primary-rgb, 41, 121, 255), 0.3)\n        );\n        background-size: 200% 100%;\n        border-radius: 3rpx 3rpx 0 0;\n        transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);\n        z-index: 1;\n        box-shadow:\n            0 -4rpx 12rpx rgba(var(--u-type-primary-rgb, 41, 121, 255), 0.3),\n            0 0 24rpx rgba(var(--u-type-primary-rgb, 41, 121, 255), 0.2);\n        animation: sliderGradient 3s ease infinite;\n\n        &::before {\n            content: '';\n            position: absolute;\n            top: -4rpx;\n            left: 50%;\n            transform: translateX(-50%);\n            width: 80rpx;\n            height: 12rpx;\n            background: radial-gradient(ellipse, rgba(var(--u-type-primary-rgb, 41, 121, 255), 0.5), transparent);\n            border-radius: 50%;\n            animation: sliderGlow 2s ease-in-out infinite;\n        }\n\n        &::after {\n            content: '';\n            position: absolute;\n            top: 0;\n            left: 0;\n            right: 0;\n            bottom: 0;\n            background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);\n            animation: sliderShine 2.5s ease-in-out infinite;\n            border-radius: 3rpx 3rpx 0 0;\n        }\n    }\n}\n\n@keyframes sliderGradient {\n    0% {\n        background-position: 0% 50%;\n    }\n    50% {\n        background-position: 100% 50%;\n    }\n    100% {\n        background-position: 0% 50%;\n    }\n}\n\n@keyframes sliderGlow {\n    0%,\n    100% {\n        opacity: 0.5;\n        transform: translateX(-50%) scale(1);\n    }\n    50% {\n        opacity: 0.8;\n        transform: translateX(-50%) scale(1.3);\n    }\n}\n\n@keyframes sliderShine {\n    0% {\n        transform: translateX(-100%) skewX(-20deg);\n    }\n    100% {\n        transform: translateX(200%) skewX(-20deg);\n    }\n}\n\n.scene-item,\n.faq-item {\n    margin-bottom: 24rpx;\n}\n.scene-title {\n    font-weight: bold;\n}\n.scene-desc,\n.faq-q {\n    display: flex;\n    align-items: center;\n    font-size: 28rpx;\n    font-weight: 500;\n    color: $u-type-error;\n    margin-top: 8rpx;\n    margin-bottom: 2rpx;\n}\n.faq-q-label {\n    font-weight: bold;\n    margin-right: 4rpx;\n}\n.faq-q-text {\n    color: $u-main-color;\n    font-weight: normal;\n}\n.faq-a {\n    display: flex;\n    align-items: flex-start;\n    font-size: 28rpx;\n    color: $u-type-success;\n    margin-top: 2rpx;\n    margin-bottom: 12rpx;\n}\n.faq-a-label {\n    font-weight: bold;\n    margin-right: 4rpx;\n}\n.faq-a-text {\n    color: $u-main-color;\n    font-weight: normal;\n}\n.toolbar-head {\n    display: flex;\n    flex-direction: column;\n    gap: 8rpx;\n    &__tip {\n        font-size: 24rpx;\n        color: $u-content-color;\n    }\n}\n.toolbar-actions {\n    display: flex;\n    justify-content: space-between;\n    gap: 16rpx;\n    &__text {\n        margin-left: 6rpx;\n        font-size: 24rpx;\n    }\n}\n.toolbar-stats {\n    display: flex;\n    gap: 16rpx;\n    margin: 8rpx 0;\n}\n\n.toolbar-stat-card {\n    flex: 1;\n    display: flex;\n    align-items: center;\n    gap: 12rpx;\n    padding: 16rpx 10rpx;\n    border-radius: 12rpx;\n    background: linear-gradient(\n        135deg,\n        rgba(var(--u-type-primary-rgb, 41, 121, 255), 0.08),\n        rgba(var(--u-type-primary-rgb, 41, 121, 255), 0.04)\n    );\n    border: 1px solid rgba(var(--u-type-primary-rgb, 41, 121, 255), 0.1);\n}\n\n.stat-card__icon {\n    width: 64rpx;\n    height: 64rpx;\n    border-radius: 12rpx;\n    background: rgba(255, 255, 255, 0.9);\n    display: flex;\n    align-items: center;\n    justify-content: center;\n}\n\n.stat-card__content {\n    flex: 1;\n    display: flex;\n    flex-direction: column;\n    gap: 4rpx;\n}\n\n.stat-card__value {\n    font-size: 26rpx;\n    font-weight: 600;\n    color: $u-main-color;\n}\n\n.stat-card__label {\n    font-size: 22rpx;\n    color: $u-tips-color;\n}\n\n.toolbar-rate {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    gap: 16rpx;\n    &__label {\n        font-size: 26rpx;\n        font-weight: 500;\n        color: $u-main-color;\n    }\n    &__desc {\n        font-size: 24rpx;\n        color: $u-tips-color;\n    }\n}\n\n.toolbar-section {\n    margin-top: 8rpx;\n    &__title {\n        display: flex;\n        align-items: center;\n        gap: 8rpx;\n        font-size: 28rpx;\n        font-weight: 600;\n        color: $u-main-color;\n        margin-bottom: 12rpx;\n    }\n}\n\n.toolbar-log {\n    background: rgba(var(--u-type-primary-rgb, 41, 121, 255), 0.04);\n    border-radius: 12rpx;\n    padding: 16rpx;\n    font-size: 22rpx;\n    color: $u-content-color;\n    max-height: 400rpx;\n    overflow-y: auto;\n    &__item {\n        display: flex;\n        align-items: flex-start;\n        gap: 12rpx;\n        padding: 12rpx 0;\n        border-bottom: 1px solid rgba(0, 0, 0, 0.06);\n        &:last-child {\n            border-bottom: none;\n        }\n    }\n    &__time {\n        flex-shrink: 0;\n        font-size: 20rpx;\n        color: $u-tips-color;\n        min-width: 80rpx;\n    }\n    &__content {\n        flex: 1;\n        color: $u-content-color;\n        line-height: 1.5;\n    }\n}\n\n.toolbar-empty {\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    justify-content: center;\n    padding: 60rpx 20rpx;\n    gap: 16rpx;\n    color: $u-tips-color;\n    font-size: 24rpx;\n}\n\n.fab-trigger-wrapper {\n    width: 112rpx;\n    height: 112rpx;\n    border-radius: 112rpx;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15);\n    transition: background-color 0.3s ease;\n    cursor: pointer;\n}\n.map-level {\n    display: flex;\n    flex-direction: column;\n    gap: 12rpx;\n    &__value {\n        font-size: 40rpx;\n        font-weight: 700;\n        color: $u-type-warning;\n    }\n    &__hint {\n        font-size: 24rpx;\n        color: $u-tips-color;\n    }\n}\n.map-stats {\n    display: flex;\n    justify-content: space-between;\n    margin-top: 24rpx;\n    gap: 16rpx;\n}\n.map-stat {\n    flex: 1;\n    background: rgba(255, 255, 255, 0.8);\n    border-radius: 16rpx;\n    padding: 16rpx;\n    text-align: center;\n    &__value {\n        font-size: 32rpx;\n        font-weight: 600;\n        color: $u-main-color;\n    }\n    &__label {\n        font-size: 22rpx;\n        color: $u-tips-color;\n    }\n}\n.map-steps {\n    display: flex;\n    flex-direction: column;\n    gap: 20rpx;\n}\n.map-step {\n    padding: 20rpx;\n    border-radius: 18rpx;\n    background: rgba(255, 255, 255, 0.9);\n    border: 1px solid rgba(0, 0, 0, 0.04);\n    &__header {\n        display: flex;\n        justify-content: space-between;\n        align-items: center;\n        margin-bottom: 12rpx;\n    }\n    &__title {\n        font-size: 28rpx;\n        font-weight: 600;\n    }\n    &__tip {\n        margin-top: 12rpx;\n        font-size: 24rpx;\n        color: $u-content-color;\n    }\n}\n.experience-toast {\n    position: fixed;\n    bottom: 160rpx;\n    right: 30rpx;\n    z-index: 19990;\n    &__inner {\n        background: rgba(0, 0, 0, 0.78);\n        color: #fff;\n        padding: 18rpx 28rpx;\n        border-radius: 30rpx;\n        font-size: 24rpx;\n        box-shadow: 0 10rpx 20rpx rgba(0, 0, 0, 0.2);\n    }\n}\n</style>\n"
  },
  {
    "path": "src/components/page-nav/page-nav.vue",
    "content": "<template>\n    <view class=\"nav-wrap\">\n        <view class=\"nav-title\">\n            <image class=\"logo\" src=\"/static/logo.png\" mode=\"widthFix\"></image>\n            <view class=\"nav-info\">\n                <view class=\"nav-title__text\">\n                    <text class=\"nav-info__title__text\">uView Pro</text>\n                </view>\n                <view class=\"nav-slogan\">\n                    {{ t('common.intro') }}\n                </view>\n            </view>\n        </view>\n        <view class=\"nav-desc\">\n            {{ desc }}\n        </view>\n        <view class=\"lang\">\n            <u-icon\n                size=\"50\"\n                :color=\"darkMode === 'dark' ? 'warning' : 'primary'\"\n                :name=\"lang\"\n                @click=\"switchLanguage\"\n            ></u-icon>\n        </view>\n    </view>\n</template>\n\n<script setup lang=\"ts\">\nimport { useTheme } from 'uview-pro';\nimport { computed } from 'vue';\nimport { useI18n } from 'vue-i18n';\nimport { useLang, useTitle } from '@/common/useHooks';\n\nconst { darkMode } = useTheme();\n\n/**\n * 页面导航栏组件\n * @description 顶部logo、标题、描述、语言切换\n */\n\nconst props = defineProps<{\n    desc?: string;\n    title?: string;\n    index: number;\n}>();\n\n// 国际化钩子\nconst { t, locale } = useI18n();\nconst { setTitle } = useTitle(props.index);\nconst { switchLang } = useLang();\n\n/**\n * 当前语言标识\n */\nconst lang = computed(() => {\n    return locale.value === 'zh-Hans' ? 'zh' : 'en';\n});\n\n/**\n * 语言切换\n */\nfunction switchLanguage() {\n    const nextLang = locale.value === 'zh-Hans' ? 'en' : 'zh-Hans';\n    switchLang({\n        name: nextLang === 'zh-Hans' ? 'zh-CN' : 'en-US',\n        locale: nextLang\n    });\n    // 设置标题\n    setTitle();\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.nav-wrap {\n    padding: 15px;\n    position: relative;\n}\n\n.lang {\n    position: absolute;\n    top: 15px;\n    right: 15px;\n}\n\n.nav-title {\n    /* #ifndef APP-NVUE */\n    display: flex;\n    /* #endif */\n    flex-direction: row;\n    align-items: center;\n}\n\n.nav-info {\n    margin-left: 15px;\n}\n\n.nav-title__text {\n    /* #ifndef APP-NVUE */\n    display: flex;\n    /* #endif */\n    color: $u-main-color;\n    font-size: 25px;\n    font-weight: bold;\n}\n\n.logo {\n    width: 70px;\n    /* #ifndef APP-NVUE */\n    height: auto;\n    /* #endif */\n}\n\n.nav-slogan {\n    color: $u-tips-color;\n    font-size: 14px;\n}\n\n.nav-desc {\n    margin-top: 10px;\n    font-size: 14px;\n    color: $u-content-color;\n}\n</style>\n"
  },
  {
    "path": "src/components/wx-tips/wx-tips.vue",
    "content": "<template>\n    <view>\n        <u-alert-tips\n            :show=\"show\"\n            :description=\"description\"\n            :close-able=\"true\"\n            :show-icon=\"true\"\n            title=\"提示\"\n            type=\"warning\"\n            @close=\"show = false\"\n        ></u-alert-tips>\n    </view>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from 'vue';\n\nconst show = ref(false);\n\n// #ifdef MP-WEIXIN\nshow.value = true;\n// #endif\n\nconst props = defineProps({\n    type: {\n        type: Number,\n        default: -1\n    }\n});\n\nconst description = computed(() => {\n    switch (props.type) {\n        case 0:\n            return '该页面仅为表单校验演示功能，所有用户信息不存储！';\n        case 1:\n            return '该页面仅为布局演示功能，非电商类小程序，不具备实际功能！';\n        default:\n            return '该页面仅为功能演示，所有用户信息不存储！非电商类小程序，不具备实际功能！';\n    }\n});\n</script>\n"
  },
  {
    "path": "src/env.d.ts",
    "content": "/// <reference types=\"vite/client\" />\n\ndeclare module '*.vue' {\n    import { DefineComponent } from 'vue';\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types\n    const component: DefineComponent<{}, {}, any>;\n    export default component;\n}\n"
  },
  {
    "path": "src/locales/index.ts",
    "content": "import { createI18n } from 'vue-i18n';\n\nimport en from './langs/en.json'; // 英文\nimport zhHans from './langs/zh-Hans.json'; // 简体中文\n\nconst messages = {\n    en,\n    'zh-Hans': zhHans\n};\n\n// 安全获取locale，避免在SSR环境下出现问题\nexport const getSafeLocale = () => {\n    try {\n        return uni.getStorageSync('UNI_LOCALE') || uni.getLocale() || 'zh-Hans';\n    } catch (e) {\n        return 'zh-Hans';\n    }\n};\n\nexport const getDefaultLocale = () => {\n    switch (getSafeLocale()) {\n        case 'en':\n            return 'en-US';\n        default:\n            return 'zh-CN';\n    }\n};\n\nconst i18n = createI18n({\n    locale: getSafeLocale(),\n    fallbackLocale: 'zh-Hans',\n    messages,\n    allowComposition: true,\n    legacy: false,\n    globalInjection: true\n});\n\nexport default i18n;\n"
  },
  {
    "path": "src/locales/langs/en.json",
    "content": "{\n    \"components\": {\n        \"find\": \"Found\",\n        \"matchingComponent\": \"matching components\",\n        \"clear\": \"Clear\",\n        \"searchComponent\": \"Search components...\",\n        \"search\": \"Search\",\n        \"notFound\": \"No matching component was found.\",\n        \"theme\": \"Switch Theme\",\n        \"desc\": \"uView Pro is a high-quality, cross-platform UI component library for multiple platforms. It includes 80+ built-in components and a rich utility library to help efficiently develop Mini Programs, H5, Apps, HarmonyOS, and more.\"\n    },\n    \"js\": {\n        \"desc\": \"Numerous intimate gadgets are a weapon that you can call upon during the development process, allowing you to dart in your hand and pierce the Yang with a hundred steps.\"\n    },\n    \"template\": {\n        \"desc\": \"Collection of many commonly used pages and layouts, reducing the repetitive work of developers, allowing you to focus on logic and get twice the result with half the effort.\"\n    },\n    \"nav\": {\n        \"components\": \"Components\",\n        \"js\": \"Tools\",\n        \"template\": \"Template\",\n        \"about\": \"About\",\n        \"experience\": \"Experience\"\n    },\n    \"common\": {\n        \"intro\": \"UI framework for rapid development of multiple platforms\",\n        \"title\": \"uView Pro\",\n        \"tryit\": \"Try-it\",\n        \"experienceMap\": \"Experience Map\",\n        \"experienceMapDesc\": \"View component experience levels and task completion status\",\n        \"scene\": \"Scene\",\n        \"sceneDesc\": \"Experience business scenarios and feel the use of components in applications\"\n    },\n    \"theme\": {\n        \"uviewpro\": \"Default\",\n        \"purple\": \"Purple\",\n        \"green\": \"Green\",\n        \"orange\": \"Orange\",\n        \"dark\": \"DarkBlue\"\n    }\n}\n"
  },
  {
    "path": "src/locales/langs/zh-Hans.json",
    "content": "{\n    \"components\": {\n        \"find\": \"找到\",\n        \"matchingComponent\": \"个匹配组件\",\n        \"clear\": \"清空\",\n        \"searchComponent\": \"搜索组件...\",\n        \"search\": \"搜索\",\n        \"notFound\": \"未找到匹配的组件\",\n        \"theme\": \"切换主题\",\n        \"desc\": \"uView Pro 是一套高质量、跨平台的多端 UI 组件库，内置 80+ 组件与丰富工具库，助力高效开发小程序、H5、App、HarmonyOS 等应用！\"\n    },\n    \"js\": {\n        \"desc\": \"uView Pro 提供了众多的贴心小工具，是你开发过程中召之即来的利器，让你飞镖在手，百步穿杨！\"\n    },\n    \"template\": {\n        \"desc\": \"uView Pro 收集了众多的常用页面和布局，减少开发者的重复工作，让你专注逻辑，事半功倍！\"\n    },\n    \"nav\": {\n        \"components\": \"组件\",\n        \"js\": \"工具\",\n        \"template\": \"模板\",\n        \"about\": \"关于\",\n        \"experience\": \"体验地图\"\n    },\n    \"common\": {\n        \"intro\": \"多平台快速开发的UI框架\",\n        \"title\": \"uView UI\",\n        \"tryit\": \"试一试\",\n        \"experienceMap\": \"体验地图\",\n        \"experienceMapDesc\": \"查看组件体验等级与任务完成情况\",\n        \"scene\": \"实用场景\",\n        \"sceneDesc\": \"体验完整的业务场景，感受组件在实际应用中的使用\"\n    },\n    \"theme\": {\n        \"uviewpro\": \"官方蓝\",\n        \"purple\": \"霞光紫\",\n        \"green\": \"清翠绿\",\n        \"orange\": \"暖阳橙\",\n        \"dark\": \"深邃蓝\"\n    }\n}\n"
  },
  {
    "path": "src/main.ts",
    "content": "import { createSSRApp } from 'vue';\r\nimport App from './App.vue';\r\nimport themes from '@/uview-pro.theme';\r\nimport uViewPro, { httpPlugin } from '@/uni_modules/uview-pro';\r\nimport { httpInterceptor, httpRequestConfig } from './common/http.interceptor';\r\nimport i18n from '@/locales';\r\n// #ifdef MP\r\nimport share from './common/share';\r\n// #endif\r\nexport function createApp() {\r\n    const app = createSSRApp(App);\r\n    app.use(i18n);\r\n    // 引入uView Pro 主库\r\n    app.use(uViewPro, {\r\n        theme: {\r\n            themes: themes, // 主题对象数组，至少需要包含一个主题对象，且每个对象必须包含 name 和 color 字段\r\n            defaultTheme: 'green', // 默认主题名称，需与 themes 中的 name 字段对应\r\n            defaultDarkMode: 'auto', // 默认暗黑模式跟随系统，支持 'auto' | 'light' | 'dark'\r\n            isForce: false // 是否初始化强制使用默认主题，如果为true，则会覆盖用户之前选择的主题；如果为false，则会优先使用用户之前选择的主题\r\n        },\r\n        locale: {\r\n            // 部分覆盖内置语言包\r\n            locales: [\r\n                { name: 'zh-CN', uModal: { confirmText: '好的', cancelText: '算了' } },\r\n                { name: 'en-US', uModal: { confirmText: 'OK', cancelText: 'Cancel' } }\r\n            ],\r\n            defaultLocale: 'zh-CN' // 默认语言环境，需与 locales 中的 name 字段对应\r\n        },\r\n        debugMode: false // 是否开启日志和警告\r\n    });\r\n    // 引入uView Pro 的http插件\r\n    app.use(httpPlugin, { interceptor: httpInterceptor, requestConfig: httpRequestConfig });\r\n    // #ifdef MP\r\n    // @ts-ignore\r\n    app.mixin(share);\r\n    // #endif\r\n    return {\r\n        app\r\n    };\r\n}\r\n"
  },
  {
    "path": "src/manifest.json",
    "content": "{\n    \"name\": \"uViewPro(跨平台UI组件库)\",\n    \"appid\": \"__UNI__9E7D9A9\",\n    \"description\": \"uView Pro 是一套高质量、跨平台的多端 UI 组件库，内置 80+ 组件与丰富工具库，助力高效开发小程序、H5、App、HarmonyOS 等应用。\",\n    \"versionName\": \"1.0.9\",\n    \"versionCode\": 12,\n    \"transformPx\": false,\n    /* 5+App特有相关 */\n    \"app-plus\": {\n        \"darkmode\": true,\n        \"themeLocation\": \"theme.json\",\n        \"usingComponents\": true,\n        \"nvueStyleCompiler\": \"uni-app\",\n        \"compilerVersion\": 3,\n        \"splashscreen\": {\n            \"alwaysShowBeforeRender\": true,\n            \"waiting\": true,\n            \"autoclose\": true,\n            \"delay\": 0\n        },\n        /* 模块配置 */\n        \"modules\": {},\n        /* 应用发布信息 */\n        \"distribute\": {\n            /* android打包配置 */\n            \"android\": {\n                \"permissions\": [\n                    \"<uses-permission android:name=\\\"android.permission.CHANGE_NETWORK_STATE\\\"/>\",\n                    \"<uses-permission android:name=\\\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\\\"/>\",\n                    \"<uses-permission android:name=\\\"android.permission.READ_CONTACTS\\\"/>\",\n                    \"<uses-permission android:name=\\\"android.permission.VIBRATE\\\"/>\",\n                    \"<uses-permission android:name=\\\"android.permission.READ_LOGS\\\"/>\",\n                    \"<uses-permission android:name=\\\"android.permission.ACCESS_WIFI_STATE\\\"/>\",\n                    \"<uses-feature android:name=\\\"android.hardware.camera.autofocus\\\"/>\",\n                    \"<uses-permission android:name=\\\"android.permission.WRITE_CONTACTS\\\"/>\",\n                    \"<uses-permission android:name=\\\"android.permission.ACCESS_NETWORK_STATE\\\"/>\",\n                    \"<uses-permission android:name=\\\"android.permission.CAMERA\\\"/>\",\n                    \"<uses-permission android:name=\\\"android.permission.RECORD_AUDIO\\\"/>\",\n                    \"<uses-permission android:name=\\\"android.permission.GET_ACCOUNTS\\\"/>\",\n                    \"<uses-permission android:name=\\\"android.permission.MODIFY_AUDIO_SETTINGS\\\"/>\",\n                    \"<uses-permission android:name=\\\"android.permission.READ_PHONE_STATE\\\"/>\",\n                    \"<uses-permission android:name=\\\"android.permission.CHANGE_WIFI_STATE\\\"/>\",\n                    \"<uses-permission android:name=\\\"android.permission.WAKE_LOCK\\\"/>\",\n                    \"<uses-permission android:name=\\\"android.permission.CALL_PHONE\\\"/>\",\n                    \"<uses-permission android:name=\\\"android.permission.FLASHLIGHT\\\"/>\",\n                    \"<uses-permission android:name=\\\"android.permission.ACCESS_COARSE_LOCATION\\\"/>\",\n                    \"<uses-feature android:name=\\\"android.hardware.camera\\\"/>\",\n                    \"<uses-permission android:name=\\\"android.permission.ACCESS_FINE_LOCATION\\\"/>\",\n                    \"<uses-permission android:name=\\\"android.permission.WRITE_SETTINGS\\\"/>\"\n                ],\n                \"abiFilters\": [\"armeabi-v7a\", \"arm64-v8a\"],\n                \"targetSdkVersion\": 31,\n                \"minSdkVersion\": 22\n            },\n            /* ios打包配置 */\n            \"ios\": {\n                \"dSYMs\": false\n            },\n            /* SDK配置 */\n            \"sdkConfigs\": {\n                \"ad\": {}\n            },\n            \"icons\": {\n                \"android\": {\n                    \"hdpi\": \"unpackage/res/icons/72x72.png\",\n                    \"xhdpi\": \"unpackage/res/icons/96x96.png\",\n                    \"xxhdpi\": \"unpackage/res/icons/144x144.png\",\n                    \"xxxhdpi\": \"unpackage/res/icons/192x192.png\"\n                },\n                \"ios\": {\n                    \"appstore\": \"unpackage/res/icons/1024x1024.png\",\n                    \"ipad\": {\n                        \"app\": \"unpackage/res/icons/76x76.png\",\n                        \"app@2x\": \"unpackage/res/icons/152x152.png\",\n                        \"notification\": \"unpackage/res/icons/20x20.png\",\n                        \"notification@2x\": \"unpackage/res/icons/40x40.png\",\n                        \"proapp@2x\": \"unpackage/res/icons/167x167.png\",\n                        \"settings\": \"unpackage/res/icons/29x29.png\",\n                        \"settings@2x\": \"unpackage/res/icons/58x58.png\",\n                        \"spotlight\": \"unpackage/res/icons/40x40.png\",\n                        \"spotlight@2x\": \"unpackage/res/icons/80x80.png\"\n                    },\n                    \"iphone\": {\n                        \"app@2x\": \"unpackage/res/icons/120x120.png\",\n                        \"app@3x\": \"unpackage/res/icons/180x180.png\",\n                        \"notification@2x\": \"unpackage/res/icons/40x40.png\",\n                        \"notification@3x\": \"unpackage/res/icons/60x60.png\",\n                        \"settings@2x\": \"unpackage/res/icons/58x58.png\",\n                        \"settings@3x\": \"unpackage/res/icons/87x87.png\",\n                        \"spotlight@2x\": \"unpackage/res/icons/80x80.png\",\n                        \"spotlight@3x\": \"unpackage/res/icons/120x120.png\"\n                    }\n                }\n            }\n        },\n        \"safearea\": {\n            //iOS平台的安全区域\n            \"background\": \"#ffffff\",\n            \"backgroundDark\": \"#2f0508\",\n            \"bottom\": {\n                \"offset\": \"none\"\n            }\n        }\n    },\n    /* 快应用特有相关 */\n    \"quickapp\": {},\n    /* 小程序特有相关 */\n    \"mp-weixin\": {\n        \"appid\": \"wxf2f98f5b731ecd20\",\n        \"setting\": {\n            \"urlCheck\": false\n        },\n        \"usingComponents\": true,\n        \"darkmode\": true,\n        \"themeLocation\": \"theme.json\"\n    },\n    \"mp-alipay\": {\n        \"appid\": \"2021005198657329\",\n        \"usingComponents\": true,\n        \"component2\": true\n    },\n    \"mp-baidu\": {\n        \"usingComponents\": true\n    },\n    \"mp-toutiao\": {\n        \"usingComponents\": true\n    },\n    \"h5\": {\n        \"title\": \"uView Pro\",\n        \"router\": {\n            \"mode\": \"hash\",\n            \"base\": \"./\"\n        },\n        \"optimization\": {\n            \"treeShaking\": {\n                \"enable\": true\n            }\n        },\n        \"darkmode\": true,\n        \"themeLocation\": \"theme.json\"\n    },\n    \"uniStatistics\": {\n        \"enable\": false\n    },\n    \"vueVersion\": \"3\",\n    \"app-harmony\": {\n        \"darkmode\": true,\n        \"themeLocation\": \"theme.json\",\n        \"safearea\": {\n            \"background\": \"#ffffff\",\n            \"backgroundDark\": \"#2f0508\",\n            \"bottom\": {\n                \"offset\": \"none\"\n            }\n        },\n        \"distribute\": {\n            \"bundleName\": \"cn.anyup.uviewpro\",\n            \"icons\": {\n                \"foreground\": \"unpackage/res/icons/1024x1024.png\",\n                \"background\": \"unpackage/res/icons/1024x1024.png\"\n            },\n            \"splashScreens\": {\n                \"startWindowBackground\": \"#FFFFFF\",\n                \"startWindowIcon\": \"unpackage/res/icons/1024x1024.png\"\n            },\n            \"signingConfigs\": {\n                \"default\": {\n                    \"certpath\": \"c:\\\\Users\\\\admin\\\\AppData\\\\Roaming\\\\HBuilder X\\\\extensions\\\\launcher\\\\agc-certs\\\\1762910225094.cer\",\n                    \"keyAlias\": \"debugKey\",\n                    \"keyPassword\": \"0000001B48EFEBC254AA9F73E27F2C1699BE1EFB8B45851575CECD07D2DBE82C0D76B7907E487F23F84D54\",\n                    \"profile\": \"c:\\\\Users\\\\admin\\\\AppData\\\\Roaming\\\\HBuilder X\\\\extensions\\\\launcher\\\\agc-certs\\\\1762910225094.p7b\",\n                    \"signAlg\": \"SHA256withECDSA\",\n                    \"storeFile\": \"c:\\\\Users\\\\admin\\\\AppData\\\\Roaming\\\\HBuilder X\\\\extensions\\\\launcher\\\\agc-certs\\\\1762910225094.p12\",\n                    \"storePassword\": \"0000001B48EFEBC254AA9F73E27F2C1699BE1EFB8B45851575CECD07D2DBE82C0D76B7907E487F23F84D54\"\n                },\n                \"release\": {\n                    \"certpath\": \"D:/workspace/anyup/uView-Pro/docs/uviewpro.cer\",\n                    \"keyAlias\": \"uviewpro\",\n                    \"keyPassword\": \"0000001E6691C890BDB30353B4C0D59375D5FFB9C11A3ED0CA390CAA12302677A354AB61C7795AD6D2BCD04DBBC6\",\n                    \"profile\": \"D:/workspace/anyup/uView-Pro/docs/uviewpro_prodRelease.p7b\",\n                    \"signAlg\": \"SHA256withECDSA\",\n                    \"storeFile\": \"D:/workspace/anyup/uView-Pro/docs/uviewpro.p12\",\n                    \"storePassword\": \"0000001E0E5E7477F66639990B845220FC4082AAEA6D6837F481E2E9A13ECA4F3376D378019C37B059E1A410F512\"\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/pages/componentsA/avatar/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"Avatar 头像\"\n        desc=\"用于展示用户头像、等级、性别等信息，支持多种形态和自定义内容。\"\n        :apis=\"'avatar'\"\n    >\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-avatar\n                            :mode=\"mode\"\n                            :size=\"size\"\n                            :src=\"src\"\n                            :text=\"text\"\n                            :showLevel=\"showLevel\"\n                            :showSex=\"showSex\"\n                            :sexIcon=\"sexIcon\"\n                            :bgColor=\"bgColor\"\n                        ></u-avatar>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">是否默认头像</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"defaultAvatarChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">模式选择</view>\n                        <u-subsection :list=\"['圆形', '圆角方形']\" @change=\"modeChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">性别选择</view>\n                        <u-subsection :list=\"['男', '女', '不显示']\" @change=\"sexChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">等级</view>\n                        <u-subsection :list=\"['显示', '不显示']\" @change=\"levelChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">自定义内容</view>\n                        <u-subsection current=\"0\" :list=\"['图片', '文字']\" @change=\"styleChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">尺寸</view>\n                        <u-subsection\n                            current=\"1\"\n                            :list=\"['large', 'default', 'mini', '160']\"\n                            @change=\"sizeChange\"\n                        ></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport type { Sex, Shape } from '@/uni_modules/uview-pro/types/global';\n\nconst mode = ref<Shape>('circle');\nconst src = ref('/static/logo.png');\nconst text = ref('');\nconst size = ref('90');\nconst showLevel = ref(true);\nconst showSex = ref(true);\nconst sexIcon = ref<Sex>('man');\nconst bgColor = ref('var(--u-bg-color)');\n\nfunction defaultAvatarChange(index: number) {\n    if (index === 0) {\n        src.value = '';\n    } else {\n        src.value = '/static/logo.png';\n    }\n}\n\nfunction modeChange(index: number) {\n    mode.value = index === 0 ? 'circle' : 'square';\n}\nfunction styleChange(index: number) {\n    if (index === 0) {\n        text.value = '';\n        src.value = '/static/logo.png';\n    } else {\n        text.value = '无头像';\n    }\n}\n\nfunction sizeChange(index: number) {\n    size.value = index === 0 ? 'large' : index === 1 ? 'default' : index === 2 ? 'mini' : '160';\n}\n\nfunction sexChange(index: number) {\n    showSex.value = true;\n    if (index === 0) sexIcon.value = 'man';\n    if (index === 1) sexIcon.value = 'woman';\n    if (index === 2) showSex.value = false;\n}\n\nfunction levelChange(index: number) {\n    showLevel.value = !index;\n}\n</script>\n"
  },
  {
    "path": "src/pages/componentsA/avatarCropper/index.vue",
    "content": "<template>\n    <view class=\"u-demo\">\n        <view class=\"u-demo-wrap\">\n            <view class=\"u-demo-title\">演示效果</view>\n            <view class=\"u-demo-area\">\n                <view class=\"u-avatar-wrap\">\n                    <image @tap=\"preAvatar\" class=\"u-avatar-demo\" v-if=\"avatar\" :src=\"avatar\" mode=\"aspectFill\"></image>\n                </view>\n                <u-button @click=\"chooseAvatar\">选择图片</u-button>\n            </view>\n        </view>\n        <!-- <view class=\"u-config-wrap\">\n\t\t\t<view class=\"u-config-title u-border-bottom\">\n\t\t\t\t参数配置\n\t\t\t</view>\n\t\t\t<view class=\"u-config-item\">\n\t\t\t\t<view class=\"u-item-title\">生成图片质量</view>\n\t\t\t\t<u-subsection :current=\"1\" :list=\"['0.3', '0.7', '1']\" @change=\"qualityChange\"></u-subsection>\n\t\t\t</view>\n\t\t\t<view class=\"u-config-item\">\n\t\t\t\t<view class=\"u-item-title\">自定义参数</view>\n\t\t\t\t<u-subsection :current=\"1\" :list=\"['是', '否']\" @change=\"styleChange\"></u-subsection>\n\t\t\t</view>\n\t\t</view> -->\n    </view>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\n\nconst avatar = ref('https://ik.imagekit.io/anyup/uview-pro/common/logo-new.png');\n\nconst chooseAvatar = () => {\n    $u.route({\n        url: '/uni_modules/uview-pro/components/u-avatar-cropper/u-avatar-cropper',\n        params: {\n            // 输出图片宽度，高等于宽，单位px\n            destWidth: 300,\n            // 裁剪框宽度，高等于宽，单位px\n            rectWidth: 200,\n            // 输出的图片类型，如果'png'类型发现裁剪的图片太大，改成\"jpg\"即可\n            fileType: 'jpg'\n        }\n    });\n};\n\nfunction preAvatar(path) {\n    // @ts-ignore\n    wx.previewImage({\n        current: '', // 当前显示图片的 http 链接\n        urls: [path] // 需要预览的图片 http 链接列表\n    });\n}\n\nuni.$on('uAvatarCropper', path => {\n    avatar.value = path;\n    // 可以在此上传到服务端\n    // uni.uploadFile({\n    // \turl: 'http://192.168.100.17/index.php/index/index/upload',\n    // \tfilePath: path,\n    // \tname: 'file',\n    // \tcomplete: (res) => {\n    // \t\tconsole.log(res);\n    // \t}\n    // });\n});\n</script>\n\n<style lang=\"scss\" scoped>\n.wrap {\n    padding: 24rpx;\n}\n\n.u-avatar-wrap {\n    overflow: hidden;\n    margin-bottom: 20rpx;\n}\n\n.u-avatar-demo {\n    width: 150rpx;\n    height: 150rpx;\n    border-radius: 100rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsA/backTop/index.vue",
    "content": "<template>\n    <demo-page title=\"BackTop 返回顶部\" desc=\"用于快速返回页面顶部，支持自定义样式、位置和图标。\" :apis=\"'backTop'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <view class=\"u-no-demo-here\">滚动页面即可在右下角看到返回顶部的按钮</view>\n                    </view>\n                    <u-back-top\n                        :scrollTop=\"scrollTop\"\n                        :mode=\"mode\"\n                        :bottom=\"bottom\"\n                        :right=\"right\"\n                        :top=\"top\"\n                        :icon=\"icon\"\n                        :custom-style=\"customStyle\"\n                        :icon-style=\"iconStyle\"\n                        :tips=\"tips\"\n                    />\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">模式</view>\n                        <u-subsection :list=\"['圆形', '方形']\" @change=\"modeChange\" />\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">组件位置</view>\n                        <u-subsection :list=\"['默认', '自定义']\" @change=\"positionChange\" />\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">显示组件的滚动条距离</view>\n                        <u-subsection current=\"1\" :list=\"['200', '400', '600']\" @change=\"scrollTopChange\" />\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">自定义样式</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"styleChange\" />\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport type { Shape } from '@/uni_modules/uview-pro/types/global';\nimport { $u } from '@/uni_modules/uview-pro';\nimport { onPageScroll } from '@dcloudio/uni-app';\n\nconst scrollTop = ref(0);\nconst mode = ref<Shape>('circle');\nconst bottom = ref(200);\nconst right = ref(40);\nconst top = ref(400);\nconst icon = ref('arrow-upward');\nconst iconStyle = ref({\n    color: '#909399',\n    fontSize: '38rpx'\n});\nconst customStyle = ref({});\nconst tips = ref('');\n\nfunction modeChange(index: number) {\n    mode.value = !index ? 'circle' : 'square';\n}\n\nfunction positionChange(index: number) {\n    if (index === 0) {\n        bottom.value = 200;\n        right.value = 40;\n    } else {\n        bottom.value = 400;\n        right.value = 80;\n    }\n}\n\nfunction scrollTopChange(index: number) {\n    top.value = [200, 400, 600][index];\n}\n\nfunction styleChange(index: number) {\n    if (index === 0) {\n        icon.value = 'arrow-up';\n        iconStyle.value = {\n            color: $u.color.primary,\n            fontSize: '34rpx'\n        };\n        customStyle.value = {\n            backgroundColor: '#a0cfff',\n            color: $u.color.primary\n        };\n        tips.value = '顶部';\n    } else {\n        icon.value = 'arrow-upward';\n        iconStyle.value = {\n            color: '#909399',\n            fontSize: '38rpx'\n        };\n        customStyle.value = {\n            backgroundColor: '#e1e1e1'\n        };\n        tips.value = '';\n    }\n}\nonPageScroll(e => {\n    scrollTop.value = e.scrollTop;\n});\n</script>\n\n<style lang=\"scss\" scoped>\n.u-demo {\n    height: 200vh;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsA/calendar/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"Calendar 日历 \"\n        desc=\"此组件用于单个选择日期，范围选择日期等，日历被包裹在底部弹起的容器中。\"\n        :apis=\"'calendar'\"\n    >\n        <view class=\"u-demo\">\n            <view class=\"u-demo-wrap\">\n                <view class=\"u-demo-title\">演示效果</view>\n                <view class=\"u-demo-area\">\n                    <u-calendar\n                        v-model=\"show\"\n                        ref=\"calendar\"\n                        :is-page=\"isPage\"\n                        :mode=\"mode\"\n                        :show-lunar=\"showLunar\"\n                        :start-text=\"startText\"\n                        :end-text=\"endText\"\n                        :range-color=\"rangeColor\"\n                        :range-bg-color=\"rangeBgColor\"\n                        :active-bg-color=\"activeBgColor\"\n                        :btn-type=\"btnType\"\n                        :min-date=\"minDate\"\n                        :max-date=\"maxDate\"\n                        :default-date=\"defaultDate\"\n                        :start-date=\"defaultStartDate\"\n                        :end-date=\"defaultEndDate\"\n                        :readonly=\"readonly\"\n                        :checked-dates=\"checkedDates\"\n                        :today-checked=\"todayChecked\"\n                        :checkin-mode=\"checkinMode\"\n                        :holidays=\"holidays\"\n                        :workdays=\"workdays\"\n                        :festivals=\"festivals\"\n                        :show-festival=\"showFestival\"\n                        :use-date-slot=\"useDateSlot\"\n                        :default-select-today=\"defaultSelectToday\"\n                        @change=\"change\"\n                    >\n                        <!-- 自定义日期内容插槽 - 电商价格日历示例 -->\n                        <template v-if=\"demoType === 3\" #date=\"{ date }\">\n                            <text :class=\"getPriceClass(date)\">{{ getPrice(date) }}</text>\n                        </template>\n                    </u-calendar>\n                    <view class=\"u-demo-result-line\">\n                        {{ result }}\n                    </view>\n                    <view v-if=\"showLunar && lunarResult\">\n                        {{ lunarResult }}\n                    </view>\n                </view>\n            </view>\n            <view class=\"u-config-wrap\">\n                <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                <view v-if=\"!isPage\" class=\"u-config-item\">\n                    <view class=\"u-item-title\">状态</view>\n                    <u-subsection :current=\"showBtnStatus\" :list=\"['显示', '隐藏']\" @change=\"showChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">演示场景</view>\n                    <u-subsection\n                        :current=\"demoType\"\n                        :list=\"['基础用法', '打卡签到', '节假日', '价格日历']\"\n                        @change=\"demoTypeChange\"\n                    ></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">交互模式</view>\n                    <u-subsection\n                        :current=\"readonly ? 1 : 0\"\n                        :list=\"['可点击', '只读']\"\n                        @change=\"readonlyChange\"\n                    ></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">默认选中今天</view>\n                    <u-subsection\n                        :current=\"defaultSelectToday ? 0 : 1\"\n                        :list=\"['是', '否']\"\n                        @change=\"defaultSelectTodayChange\"\n                    ></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">默认选中日期</view>\n                    <u-subsection :list=\"defaultDateList\" @change=\"defaultDateChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">显示方式</view>\n                    <u-subsection :current=\"showMode\" :list=\"['弹窗', '页面']\" @change=\"showModeChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">模式</view>\n                    <u-subsection current=\"0\" :list=\"['单个日期', '日期范围']\" @change=\"modeChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">农历</view>\n                    <u-subsection\n                        :current=\"showLunar ? 0 : 1\"\n                        :list=\"['显示', '隐藏']\"\n                        @change=\"lunarChange\"\n                    ></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">最小可选日期</view>\n                    <u-subsection :list=\"['1950-01-01', '2025-05-20']\" @change=\"minDateChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">最大可选日期</view>\n                    <u-subsection :list=\"['当前日期', '2028-05-20']\" @change=\"maxDateChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">自定义样式</view>\n                    <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"styleChange\"></u-subsection>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed } from 'vue';\nimport type {\n    CalendarChangeDate,\n    CalendarChangeRange,\n    CalendarMode,\n    ThemeType\n} from '@/uni_modules/uview-pro/types/global';\nimport { $u, useToast } from '@/uni_modules/uview-pro';\n\nconst toast = useToast();\nconst isPage = ref(false);\nconst show = ref(false);\nconst showLunar = ref(false);\nconst mode = ref<CalendarMode>('date');\nconst result = ref('请选择日期');\nconst lunarResult = ref('');\nconst startText = ref('开始');\nconst endText = ref('结束');\nconst rangeColor = ref($u.color.primary);\nconst rangeBgColor = ref('rgba(41,121,255,0.13)');\nconst activeBgColor = ref($u.color.primary);\nconst btnType = ref<ThemeType>('primary');\nconst minDate = ref('1950-01-01');\nconst maxDate = ref($u.timeFormat(new Date().getTime(), 'yyyy-mm-dd'));\n\n// 默认日期\nconst defaultDate = ref('');\nconst defaultStartDate = ref('');\nconst defaultEndDate = ref('');\nconst readonly = ref(false);\n\n// 打卡签到数据\nconst demoType = ref(0);\nconst checkedDates = ref<string[]>([]);\nconst todayChecked = ref(false);\n\n// 节假日和加班日数据\nconst holidays = ref<string[]>([]);\nconst workdays = ref<string[]>([]);\nconst showFestival = ref(false);\n\n// 节日数据\nconst festivals = ref<Record<string, string>>({});\n\n// 是否启用自定义日期插槽\nconst useDateSlot = ref(false);\n\n// 是否启用打卡签到模式\nconst checkinMode = ref(false);\n\n// 默认选中今天\nconst defaultSelectToday = ref(true);\n\n// 价格日历数据\nconst priceMap = ref<Record<string, number>>({});\n\nconst showMode = computed(() => {\n    return isPage.value ? 1 : 0;\n});\n\nconst showBtnStatus = computed(() => {\n    return show.value ? 0 : 1;\n});\n\nconst defaultDateList = computed(() => {\n    if (mode.value === 'date') {\n        return ['无', '今天', '明天', '2025-01-01'];\n    } else {\n        return ['无', '本周', '本月', '近7天'];\n    }\n});\n\n// 格式化日期为 YYYY-MM-DD 格式\nconst formatDate = (date: Date) => {\n    return $u.timeFormat(date.getTime(), 'yyyy-mm-dd');\n};\n\nconst showModeChange = (index: number) => {\n    isPage.value = index === 1;\n    show.value = index === 0;\n};\n\nfunction showChange(index: number) {\n    show.value = !index;\n}\n\nfunction modeChange(index: number) {\n    mode.value = index === 0 ? 'date' : 'range';\n    show.value = true;\n}\n\nfunction lunarChange(index: number) {\n    showLunar.value = index === 0;\n    show.value = true;\n}\n\nfunction styleChange(index: number) {\n    if (index === 0) {\n        startText.value = '住店';\n        endText.value = '离店';\n        activeBgColor.value = '#19be6b';\n        rangeColor.value = '#19be6b';\n        rangeBgColor.value = 'rgba(25,190,107, 0.13)';\n        btnType.value = 'success';\n    } else {\n        startText.value = '开始';\n        endText.value = '结束';\n        activeBgColor.value = $u.color.primary;\n    }\n    show.value = true;\n}\n\nfunction minDateChange(index: number) {\n    minDate.value = index === 0 ? '1950-01-01' : '2025-05-20';\n    show.value = true;\n}\n\nfunction maxDateChange(index: number) {\n    maxDate.value = index === 0 ? $u.timeFormat(new Date().getTime(), 'yyyy-mm-dd') : '2028-05-20';\n    show.value = true;\n}\n\nfunction readonlyChange(index: number) {\n    readonly.value = index === 1;\n    show.value = true;\n}\n\nfunction defaultSelectTodayChange(index: number) {\n    defaultSelectToday.value = index === 0;\n    show.value = true;\n}\n\nfunction defaultDateChange(index: number) {\n    const now = new Date();\n\n    if (mode.value === 'date') {\n        // 单选模式\n        switch (index) {\n            case 0:\n                defaultDate.value = '';\n                break;\n            case 1:\n                defaultDate.value = formatDate(now);\n                break;\n            case 2:\n                const tomorrow = new Date(now.getTime() + 24 * 60 * 60 * 1000);\n                defaultDate.value = formatDate(tomorrow);\n                break;\n            case 3:\n                defaultDate.value = '2025-01-01';\n                break;\n        }\n        defaultStartDate.value = '';\n        defaultEndDate.value = '';\n    } else {\n        // 范围模式\n        switch (index) {\n            case 0:\n                defaultStartDate.value = '';\n                defaultEndDate.value = '';\n                break;\n            case 1:\n                // 本周\n                const dayOfWeek = now.getDay() || 7;\n                const startOfWeek = new Date(now.getTime() - (dayOfWeek - 1) * 24 * 60 * 60 * 1000);\n                const endOfWeek = new Date(startOfWeek.getTime() + 6 * 24 * 60 * 60 * 1000);\n                defaultStartDate.value = formatDate(startOfWeek);\n                defaultEndDate.value = formatDate(endOfWeek);\n                break;\n            case 2:\n                // 本月\n                const year = now.getFullYear();\n                const month = now.getMonth();\n                const startOfMonth = new Date(year, month, 1);\n                const endOfMonth = new Date(year, month + 1, 0);\n                defaultStartDate.value = formatDate(startOfMonth);\n                defaultEndDate.value = formatDate(endOfMonth);\n                break;\n            case 3:\n                // 自定义范围\n                defaultStartDate.value = formatDate(now);\n                const customEnd = new Date(now.getTime() + 6 * 24 * 60 * 60 * 1000);\n                defaultEndDate.value = formatDate(customEnd);\n                break;\n        }\n        defaultDate.value = '';\n    }\n    show.value = true;\n}\n\nfunction change(e: CalendarChangeRange | CalendarChangeDate) {\n    if (mode.value === 'range') {\n        const range = e as CalendarChangeRange;\n        result.value = range.startDate + ' - ' + range.endDate;\n        if (showLunar.value && range.startLunar && range.endLunar) {\n            lunarResult.value =\n                `${range.startLunar.monthCn ?? ''}${range.startLunar.dayCn ?? ''}` +\n                ' - ' +\n                `${range.endLunar.monthCn ?? ''}${range.endLunar.dayCn ?? ''}`;\n        } else {\n            lunarResult.value = '';\n        }\n    } else {\n        const single = e as CalendarChangeDate;\n        result.value = single.result;\n        if (showLunar.value && single.lunar) {\n            lunarResult.value = `${single.lunar.monthCn ?? ''}${single.lunar.dayCn ?? ''}`;\n        } else {\n            lunarResult.value = '';\n        }\n        // 打卡签到模式下，点击日期模拟打卡\n        if (demoType.value === 1) {\n            const dateStr = single.result; // 使用 YYYY-MM-DD 格式\n            const todayStr = formatDate(new Date());\n            if (dateStr === todayStr) {\n                todayChecked.value = true;\n                toast.success('今日已打卡');\n            } else if (!checkedDates.value.includes(dateStr)) {\n                checkedDates.value.push(dateStr);\n                toast.success('打卡成功 ' + dateStr);\n            } else {\n                toast.success('已经打卡了~');\n            }\n        }\n    }\n}\n\nfunction demoTypeChange(index: number) {\n    demoType.value = index;\n    const now = new Date();\n    if (index === 1) {\n        // 切换到打卡签到模式，设置示例数据\n        mode.value = 'date';\n        readonly.value = false;\n        showLunar.value = true;\n        // 生成最近7天的打卡记录（模拟）\n        checkedDates.value = [];\n        for (let i = 1; i <= 7; i++) {\n            const d = new Date(now.getTime() - i * 24 * 60 * 60 * 1000);\n            checkedDates.value.push(formatDate(d));\n        }\n        todayChecked.value = false;\n        holidays.value = [];\n        workdays.value = [];\n        festivals.value = {};\n        showFestival.value = false;\n        useDateSlot.value = false;\n        checkinMode.value = true;\n        result.value = '点击今日日期进行打卡';\n    } else if (index === 2) {\n        // 切换到节假日模式\n        mode.value = 'date';\n        readonly.value = false;\n        showLunar.value = true;\n        checkedDates.value = [];\n        todayChecked.value = false;\n        useDateSlot.value = false;\n        checkinMode.value = false;\n        // 设置节假日（本月1-3号）- 使用 YYYY-MM-DD 格式\n        holidays.value = [\n            formatDate(new Date(now.getFullYear(), now.getMonth(), 1)),\n            formatDate(new Date(now.getFullYear(), now.getMonth(), 2)),\n            formatDate(new Date(now.getFullYear(), now.getMonth(), 3))\n        ];\n        // 设置加班日（本月6-7号）- 使用 YYYY-MM-DD 格式\n        workdays.value = [\n            formatDate(new Date(now.getFullYear(), now.getMonth(), 6)),\n            formatDate(new Date(now.getFullYear(), now.getMonth(), 7))\n        ];\n        // 设置节日 - 使用 MM-DD 格式（每年固定）和 YYYY-MM-DD 格式（特定年份）\n        festivals.value = {\n            // 每年固定的节日（MM-DD 格式）\n            '04-01': '愚人节',\n            '04-04': '清明节',\n            // 特定年份的节日（YYYY-MM-DD 格式）\n            [formatDate(new Date(now.getFullYear(), now.getMonth(), 20))]: '自定义'\n        };\n        showFestival.value = true;\n        result.value = '右上角红色\"休\"=节假日，蓝色\"班\"=加班日，下方显示节日名称或农历';\n    } else if (index === 3) {\n        // 切换到价格日历模式\n        mode.value = 'date';\n        readonly.value = false;\n        showLunar.value = false;\n        checkedDates.value = [];\n        todayChecked.value = false;\n        holidays.value = [];\n        workdays.value = [];\n        festivals.value = {};\n        showFestival.value = false;\n        useDateSlot.value = true;\n        checkinMode.value = false;\n        // 生成价格数据（模拟）\n        priceMap.value = {};\n        const currentMonth = now.getMonth();\n        const currentYear = now.getFullYear();\n        const daysInMonth = new Date(currentYear, currentMonth + 1, 0).getDate();\n        for (let i = 1; i <= daysInMonth; i++) {\n            const dateStr = formatDate(new Date(currentYear, currentMonth, i));\n            // 随机生成价格 99-599\n            const basePrice = 299;\n            const randomPrice = Math.floor(Math.random() * 400) + 99;\n            priceMap.value[dateStr] = randomPrice;\n        }\n        result.value = '价格日历示例，选择日期查看价格';\n    } else {\n        // 切换回基础用法\n        checkedDates.value = [];\n        todayChecked.value = false;\n        holidays.value = [];\n        workdays.value = [];\n        festivals.value = {};\n        showFestival.value = false;\n        priceMap.value = {};\n        useDateSlot.value = false;\n        checkinMode.value = false;\n        readonly.value = false;\n        result.value = '请选择日期';\n    }\n\n    if (isPage.value === false) {\n        showModeChange(index);\n    }\n}\n\n// 获取日期价格\nfunction getPrice(dateInfo: { date: string; isToday: boolean }) {\n    if (dateInfo.isToday) {\n        return '今天';\n    }\n    const price = priceMap.value[dateInfo.date];\n    if (price) {\n        return '¥' + price;\n    }\n    return '';\n}\n\n// 获取价格样式类\nfunction getPriceClass(dateInfo: { date: string; isToday: boolean; isSelected?: boolean }) {\n    // 选中的日期不添加颜色类，使用组件默认的白色\n    if (dateInfo.isSelected) {\n        return '';\n    }\n    if (dateInfo.isToday) {\n        return 'price-today';\n    }\n    const price = priceMap.value[dateInfo.date];\n    if (price && price < 200) {\n        return 'price-low';\n    }\n    if (price && price > 400) {\n        return 'price-high';\n    }\n    return 'price-normal';\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.price-today {\n    color: var(--u-type-success);\n    font-weight: bold;\n}\n.price-low {\n    color: var(--u-type-error);\n}\n.price-high {\n    color: var(--u-type-warning);\n}\n.price-normal {\n    color: var(--u-tips-color);\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsA/empty/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"Empty 空状态\"\n        desc=\"用于页面、列表、数据等内容为空时的友好占位提示，支持多种内置场景和自定义插槽。\"\n        :apis=\"'empty'\"\n    >\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-empty :mode=\"mode\">\n                            <template v-if=\"slot\" #bottom>\n                                <u-button size=\"medium\"> slot按钮 </u-button>\n                            </template>\n                        </u-empty>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">模式选择</view>\n                        <u-table>\n                            <u-tr class=\"u-tr\">\n                                <u-td class=\"u-td\">\n                                    <u-button :hair-line=\"false\" size=\"mini\" @click=\"modeChange('car')\"\n                                        >购物车为空</u-button\n                                    >\n                                </u-td>\n                                <u-td class=\"u-td\">\n                                    <u-button :hair-line=\"false\" size=\"mini\" @click=\"modeChange('page')\"\n                                        >页面不存在</u-button\n                                    >\n                                </u-td>\n                                <u-td class=\"u-td\">\n                                    <u-button :hair-line=\"false\" size=\"mini\" @click=\"modeChange('search')\">\n                                        没有搜索结果\n                                    </u-button>\n                                </u-td>\n                            </u-tr>\n                            <u-tr class=\"u-tr\">\n                                <u-td class=\"u-td\">\n                                    <u-button :hair-line=\"false\" size=\"mini\" @click=\"modeChange('address')\">\n                                        没有收货地址\n                                    </u-button>\n                                </u-td>\n                                <u-td class=\"u-td\">\n                                    <u-button :hair-line=\"false\" size=\"mini\" @click=\"modeChange('wifi')\"\n                                        >没有WiFi</u-button\n                                    >\n                                </u-td>\n                                <u-td class=\"u-td\">\n                                    <u-button :hair-line=\"false\" size=\"mini\" @click=\"modeChange('order')\"\n                                        >订单为空</u-button\n                                    >\n                                </u-td>\n                            </u-tr>\n                            <u-tr class=\"u-tr\">\n                                <u-td class=\"u-td\">\n                                    <u-button :hair-line=\"false\" size=\"mini\" @click=\"modeChange('coupon')\"\n                                        >没有优惠券</u-button\n                                    >\n                                </u-td>\n                                <u-td class=\"u-td\">\n                                    <u-button :hair-line=\"false\" size=\"mini\" @click=\"modeChange('favor')\"\n                                        >没有收藏</u-button\n                                    >\n                                </u-td>\n                                <u-td class=\"u-td\">\n                                    <u-button :hair-line=\"false\" size=\"mini\" @click=\"modeChange('permission')\"\n                                        >无权限</u-button\n                                    >\n                                </u-td>\n                            </u-tr>\n                            <u-tr class=\"u-tr\">\n                                <u-td class=\"u-td\">\n                                    <u-button :hair-line=\"false\" size=\"mini\" @click=\"modeChange('history')\">\n                                        无历史记录\n                                    </u-button>\n                                </u-td>\n                                <u-td class=\"u-td\">\n                                    <u-button :hair-line=\"false\" size=\"mini\" @click=\"modeChange('news')\"\n                                        >无新闻列表</u-button\n                                    >\n                                </u-td>\n                                <u-td class=\"u-td\">\n                                    <u-button :hair-line=\"false\" size=\"mini\" @click=\"modeChange('message')\">\n                                        消息列表为空\n                                    </u-button>\n                                </u-td>\n                            </u-tr>\n                            <u-tr class=\"u-tr\">\n                                <u-td class=\"u-td\">\n                                    <u-button :hair-line=\"false\" size=\"mini\" @click=\"modeChange('list')\"\n                                        >列表为空</u-button\n                                    >\n                                </u-td>\n                                <u-td class=\"u-td\">\n                                    <u-button :hair-line=\"false\" size=\"mini\" @click=\"modeChange('data')\"\n                                        >数据为空</u-button\n                                    >\n                                </u-td>\n                                <u-td class=\"u-td\">\n                                    <u-button :hair-line=\"false\" size=\"mini\">待扩展</u-button>\n                                </u-td>\n                            </u-tr>\n                        </u-table>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">传入slot</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"slotChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\n\nconst mode = ref('data');\nconst slot = ref(false);\n\nfunction modeChange(m = 'data') {\n    mode.value = m;\n}\n\nfunction slotChange(index: number) {\n    slot.value = !index;\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.u-demo-area {\n    height: 160px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n}\n\n.u-demo-area .u-empty {\n    padding-top: 0;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsA/field/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"Field 输入框\"\n        desc=\"用于表单、登录、注册等场景的多样化输入，支持多种类型、校验和自定义内容。\"\n        :apis=\"'field'\"\n    >\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-field\n                            v-model=\"mobile\"\n                            label=\"手机号\"\n                            :error-message=\"errorMessage\"\n                            placeholder=\"请填写手机号\"\n                            :required=\"required\"\n                            :icon=\"icon1\"\n                            :type=\"type\"\n                            :disabled=\"disabled\"\n                            @click=\"handleClick\"\n                        />\n                        <u-field\n                            v-model=\"code\"\n                            label=\"验证码\"\n                            placeholder=\"请填写验证码\"\n                            :required=\"required\"\n                            :icon=\"icon2\"\n                            :disabled=\"disabled\"\n                            @click=\"handleClick\"\n                        >\n                            <template #right>\n                                <u-button v-if=\"showBtn\" size=\"mini\" type=\"success\">发送验证码</u-button>\n                            </template>\n                        </u-field>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">右侧按钮</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"showBtnChange\" />\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">显示错误信息</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"errorMessageChange\" />\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">是否必填</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"requiredChange\" />\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">显示左图标和右箭头</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"customChange\" />\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">是否禁用</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"disabledChange\" />\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">第一个输入框为textarea类型</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"textareaChange\" />\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport type { InputType } from '@/uni_modules/uview-pro/types/global';\n\nconst mobile = ref('');\nconst code = ref('');\nconst errorMessage = ref('');\nconst required = ref(false);\nconst arrow = ref(false);\nconst showBtn = ref(false);\nconst icon1 = ref('');\nconst icon2 = ref('');\nconst type = ref<InputType>('text');\nconst disabled = ref(false);\n\nfunction handleClick() {\n    console.log('点击了输入框');\n}\n\nfunction showBtnChange(index: number) {\n    showBtn.value = index === 0;\n}\n\nfunction errorMessageChange(index: number) {\n    errorMessage.value = index === 0 ? '手机号有误' : '';\n}\n\nfunction requiredChange(index: number) {\n    required.value = index === 0;\n}\n\nfunction customChange(index: number) {\n    if (index === 0) {\n        icon1.value = 'map';\n        icon2.value = 'photo';\n        arrow.value = true;\n    } else {\n        icon1.value = '';\n        icon2.value = '';\n        arrow.value = false;\n    }\n}\n\nfunction disabledChange(index: number) {\n    disabled.value = index === 0;\n}\n\nfunction textareaChange(index: number) {\n    type.value = index === 0 ? 'textarea' : 'text';\n}\n</script>\n"
  },
  {
    "path": "src/pages/componentsA/form/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"Form 表单\"\n        desc=\"此组件一般用于表单场景，可以配置Input输入框，Select弹出框，进行表单验证等。\"\n        show-wx-tips\n        :apis=\"'form'\"\n    >\n        <view class=\"wrap\">\n            <u-form :model=\"model\" :rules=\"rules\" ref=\"uFormRef\" :errorType=\"errorType\" :size=\"size\">\n                <u-form-item\n                    :leftIconStyle=\"{ color: '#888', fontSize: '32rpx' }\"\n                    left-icon=\"account\"\n                    label-width=\"120\"\n                    :label-position=\"labelPosition\"\n                    label=\"姓名\"\n                    prop=\"name\"\n                >\n                    <u-input :border=\"border\" placeholder=\"请输入姓名\" v-model=\"model.name\" type=\"text\"></u-input>\n                </u-form-item>\n                <u-form-item :label-position=\"labelPosition\" label=\"性别\" prop=\"sex\">\n                    <u-input\n                        :border=\"border\"\n                        type=\"select\"\n                        :select-open=\"actionSheetShow\"\n                        v-model=\"model.sex\"\n                        placeholder=\"请选择性别\"\n                        @click=\"actionSheetShow = true\"\n                    ></u-input>\n                </u-form-item>\n                <u-form-item :label-position=\"labelPosition\" label=\"简介\" prop=\"intro\">\n                    <u-input type=\"textarea\" :border=\"border\" placeholder=\"请输入简介\" v-model=\"model.intro\" />\n                </u-form-item>\n                <u-form-item :label-position=\"labelPosition\" label=\"特长\" prop=\"extra.strong\">\n                    <u-textarea\n                        :border=\"border\"\n                        v-model=\"model.extra.strong\"\n                        placeholder=\"请输入特长，这是一个嵌套校验，a.b.c\"\n                        count\n                    ></u-textarea>\n                </u-form-item>\n                <u-form-item :label-position=\"labelPosition\" label=\"密码\" prop=\"password\">\n                    <u-input\n                        :password-icon=\"true\"\n                        :border=\"border\"\n                        type=\"password\"\n                        v-model=\"model.password\"\n                        placeholder=\"请输入密码\"\n                    ></u-input>\n                </u-form-item>\n                <u-form-item :label-position=\"labelPosition\" label=\"确认密码\" label-width=\"150\" prop=\"rePassword\">\n                    <u-input\n                        :border=\"border\"\n                        type=\"password\"\n                        v-model=\"model.rePassword\"\n                        placeholder=\"请确认密码\"\n                    ></u-input>\n                </u-form-item>\n                <u-form-item :label-position=\"labelPosition\" label=\"水果品种\" label-width=\"150\" prop=\"likeFruit\">\n                    <u-checkbox-group @change=\"checkboxGroupChange\" :width=\"radioCheckWidth\" :wrap=\"radioCheckWrap\">\n                        <u-checkbox\n                            v-model=\"item.checked\"\n                            v-for=\"(item, index) in checkboxList\"\n                            :key=\"index\"\n                            :name=\"item.name\"\n                            :disabled=\"item.disabled\"\n                        >\n                            {{ item.name }}\n                        </u-checkbox>\n                    </u-checkbox-group>\n                </u-form-item>\n                <u-form-item :label-position=\"labelPosition\" label=\"结算方式\" prop=\"payType\" label-width=\"150\">\n                    <u-radio-group v-model=\"model.payType\" :width=\"radioCheckWidth\" :wrap=\"radioCheckWrap\">\n                        <u-radio\n                            shape=\"circle\"\n                            v-for=\"(item, index) in radioList\"\n                            :key=\"index\"\n                            :name=\"item.name\"\n                            :disabled=\"item.disabled\"\n                        >\n                            {{ item.name }}\n                        </u-radio>\n                    </u-radio-group>\n                </u-form-item>\n                <u-form-item :label-position=\"labelPosition\" label=\"所在地区\" prop=\"region\" label-width=\"150\">\n                    <u-input\n                        :border=\"border\"\n                        type=\"select\"\n                        :select-open=\"pickerShow\"\n                        v-model=\"model.region\"\n                        placeholder=\"请选择地区\"\n                        @click=\"pickerShow = true\"\n                    ></u-input>\n                </u-form-item>\n                <u-form-item :label-position=\"labelPosition\" label=\"商品类型\" prop=\"goodsType\" label-width=\"150\">\n                    <u-input\n                        :border=\"border\"\n                        type=\"select\"\n                        :select-open=\"selectShow\"\n                        v-model=\"model.goodsType\"\n                        placeholder=\"请选择商品类型\"\n                        @click=\"selectShow = true\"\n                    ></u-input>\n                </u-form-item>\n                <u-form-item\n                    :rightIconStyle=\"{ color: '#888', fontSize: '32rpx' }\"\n                    right-icon=\"kefu-ermai\"\n                    :label-position=\"labelPosition\"\n                    label=\"手机号码\"\n                    prop=\"phone\"\n                    label-width=\"150\"\n                >\n                    <u-input :border=\"border\" placeholder=\"请输入手机号\" v-model=\"model.phone\" type=\"number\"></u-input>\n                </u-form-item>\n                <u-form-item :label-position=\"labelPosition\" label=\"验证码\" prop=\"code\" label-width=\"150\">\n                    <u-input :border=\"border\" placeholder=\"请输入验证码\" v-model=\"model.code\" type=\"text\"></u-input>\n                    <template #right>\n                        <u-button type=\"primary\" size=\"mini\" @click=\"getCode\">{{ codeTips }}</u-button>\n                    </template>\n                </u-form-item>\n                <!-- 此处switch的slot为right，如果不填写slot名，也即<u-switch v-model=\"model.remember\"></u-switch>，将会左对齐 -->\n                <u-form-item :label-position=\"labelPosition\" label=\"记住密码\" prop=\"remember\" label-width=\"150\">\n                    <template #right>\n                        <u-switch v-model=\"model.remember\"></u-switch>\n                    </template>\n                </u-form-item>\n                <u-form-item :label-position=\"labelPosition\" label=\"上传图片\" prop=\"photo\" label-width=\"150\">\n                    <u-upload width=\"160\" height=\"160\"></u-upload>\n                </u-form-item>\n                <u-form-item :label-position=\"labelPosition\" label=\"收款账户\" prop=\"receiptAccount\" label-width=\"150\">\n                    <view class=\"receipt-account-wrapper\">\n                        <view v-for=\"(item, index) in model.receiptAccount\" :key=\"index\">\n                            <u-form-item\n                                :label=\"`账户类型${index + 1}`\"\n                                :prop=\"`receiptAccount.${index}.accountType`\"\n                                :label-position=\"labelPosition\"\n                                label-width=\"160\"\n                            >\n                                <u-radio-group\n                                    v-model=\"item.accountType\"\n                                    :width=\"radioCheckWidth\"\n                                    :wrap=\"radioCheckWrap\"\n                                >\n                                    <u-radio\n                                        shape=\"circle\"\n                                        v-for=\"(item, index) in radioList\"\n                                        :key=\"index\"\n                                        :name=\"item.name\"\n                                        :disabled=\"item.disabled\"\n                                    >\n                                        {{ item.name }}\n                                    </u-radio>\n                                </u-radio-group>\n                            </u-form-item>\n                            <u-form-item\n                                :label=\"`收款账户${index + 1}`\"\n                                :prop=\"`receiptAccount.${index}.account`\"\n                                :label-position=\"labelPosition\"\n                                label-width=\"160\"\n                            >\n                                <u-input v-model=\"item.account\" placeholder=\"请输入收款账户\"></u-input>\n                            </u-form-item>\n                            <u-button @click=\"() => model.receiptAccount.splice(index, 1)\"> 删除 </u-button>\n                        </view>\n                        <view class=\"u-m-t-50\">\n                            <u-button\n                                type=\"default\"\n                                @click=\"() => model.receiptAccount.push({ accountType: '', account: '' })\"\n                                :throttle-time=\"0\"\n                            >\n                                添加\n                            </u-button>\n                        </view>\n                    </view>\n                </u-form-item>\n            </u-form>\n\n            <view class=\"agreement\">\n                <u-checkbox v-model=\"check\" @change=\"checkboxChange\">勾选代表同意 uView Pro 的版权协议</u-checkbox>\n            </view>\n            <u-button type=\"primary\" @click=\"handleSubmit\" :throttle-time=\"0\">提交</u-button>\n            <u-gap></u-gap>\n            <u-button @click=\"handleReset\" :throttle-time=\"0\">重置</u-button>\n            <u-action-sheet\n                :list=\"actionSheetList\"\n                v-model=\"actionSheetShow\"\n                @click=\"actionSheetCallback\"\n            ></u-action-sheet>\n            <u-select mode=\"single-column\" :list=\"selectList\" v-model=\"selectShow\" @confirm=\"selectConfirm\"></u-select>\n            <u-picker\n                mode=\"region\"\n                v-model=\"pickerShow\"\n                :default-region=\"['山东省', '青岛市', '崂山区']\"\n                @confirm=\"regionConfirm\"\n            ></u-picker>\n            <u-verification-code seconds=\"60\" ref=\"uCodeRef\" @change=\"codeChange\"></u-verification-code>\n            <view class=\"u-config-wrap\">\n                <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">表单大小</view>\n                    <u-subsection current=\"1\" :list=\"['小', '中', '大']\" @change=\"sizeChange\" />\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">label对齐方式</view>\n                    <u-subsection :list=\"['左边', '上方']\" @change=\"labelPositionChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">边框</view>\n                    <u-subsection\n                        :current=\"borderCurrent\"\n                        :list=\"['显示', '隐藏']\"\n                        @change=\"borderChange\"\n                    ></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">radio、checkbox样式</view>\n                    <u-subsection :list=\"['自适应', '换行', '50%宽度']\" @change=\"radioCheckboxChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">错误提示方式</view>\n                    <u-subsection :list=\"['message', 'toast', '下划线', '输入框']\" @change=\"errorChange\"></u-subsection>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, reactive, computed } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\nimport type { FormErrorType, FormRules, SizeType } from '@/uni_modules/uview-pro/types/global';\nimport { completeMission } from '../../../common/useExperience';\n\n// 表单模型类型声明\ninterface Model {\n    name: string;\n    sex: string;\n    likeFruit: string;\n    intro: string;\n    strong: string;\n    payType: string;\n    agreement: boolean;\n    region: string;\n    goodsType: string;\n    phone: string;\n    code: string;\n    password: string;\n    rePassword: string;\n    remember: boolean;\n    photo: string;\n    extra: { strong: string };\n    receiptAccount: Array<{\n        accountType: string;\n        account: string;\n    }>;\n}\n\n// 表单模型\nconst model = reactive<Model>({\n    name: '',\n    sex: '',\n    likeFruit: '',\n    intro: '',\n    strong: '',\n    payType: '',\n    agreement: false,\n    region: '',\n    goodsType: '',\n    phone: '',\n    code: '',\n    password: '',\n    rePassword: '',\n    remember: false,\n    photo: '',\n    extra: {\n        strong: ''\n    },\n    receiptAccount: [\n        {\n            accountType: '',\n            account: ''\n        }\n    ]\n});\n\n// 选择器列表\nconst selectList = ref([\n    { value: '电子产品', label: '电子产品' },\n    { value: '服装', label: '服装' },\n    { value: '工艺品', label: '工艺品' }\n]);\n\nconst size = ref<SizeType>('default');\n\n// 校验规则\nconst rules: FormRules = {\n    name: [\n        {\n            required: true,\n            message: '请输入姓名',\n            trigger: 'blur'\n        },\n        {\n            min: 3,\n            max: 5,\n            message: '姓名长度在3到5个字符',\n            trigger: ['change', 'blur']\n        },\n        {\n            // 此为同步验证，可以直接返回true或者false，如果是异步验证，稍微不同，见下方说明\n            validator: (rule, value, callback) => {\n                // 调用uView自带的js验证规则，详见：https://uviewpro.cn/zh/tools/test.html\n                return $u.test.chinese(value);\n            },\n            message: '姓名必须为中文',\n            // 触发器可以同时用blur和change，二者之间用英文逗号隔开\n            trigger: ['change', 'blur']\n        }\n        // 异步验证，用途：比如用户注册时输入完账号，后端检查账号是否已存在\n        // {\n        // \ttrigger: ['blur'],\n        // \t// 异步验证需要通过调用callback()，并且在里面抛出new Error()\n        // \t// 抛出的内容为需要提示的信息，和其他方式的message属性的提示一样\n        // \tasyncValidator: (rule, value, callback) => {\n        // \t\t$u.post('/ebapi/public_api/index').then(res => {\n        // \t\t\t// 如果验证出错，需要在callback()抛出new Error('错误提示信息')\n        // \t\t\tif(res.error) {\n        // \t\t\t\tcallback(new Error('姓名重复'));\n        // \t\t\t} else {\n        // \t\t\t\t// 如果没有错误，也要执行callback()回调\n        // \t\t\t\tcallback();\n        // \t\t\t}\n        // \t\t})\n        // \t},\n        // }\n    ],\n    sex: [\n        {\n            required: true,\n            message: '请选择性别',\n            trigger: 'change'\n        }\n    ],\n    intro: [\n        {\n            required: true,\n            message: '请输入简介',\n            trigger: ['change', 'blur']\n        },\n        {\n            min: 5,\n            message: '简介不能少于5个字',\n            trigger: ['change', 'blur']\n        },\n        // 正则校验示例，此处用正则校验是否中文，此处仅为示例，因为uView有this.$u.test.chinese可以判断是否中文\n        {\n            pattern: /^[\\u4e00-\\u9fa5]+$/gi,\n            message: '简介只能为中文',\n            trigger: ['change', 'blur']\n        }\n    ],\n    'extra.strong': [\n        {\n            required: true,\n            message: '请输入特长',\n            trigger: ['change', 'blur']\n        },\n        {\n            min: 5,\n            message: '特长不能少于5个字',\n            trigger: ['change', 'blur']\n        },\n        // 正则校验示例，此处用正则校验是否中文，此处仅为示例，因为uView有this.$u.test.chinese可以判断是否中文\n        {\n            pattern: /^[\\u4e00-\\u9fa5]+$/gi,\n            message: '特长只能为中文',\n            trigger: ['change', 'blur']\n        }\n    ],\n    // 参考文档：https://github.com/yiminghe/async-validator?tab=readme-ov-file#deep-rules\n    receiptAccount: {\n        type: 'array',\n        required: true,\n        message: '必须有一个收款账户',\n        trigger: 'blur',\n        defaultField: {\n            type: 'object',\n            fields: {\n                accountType: {\n                    required: true,\n                    message: '请选择账户类型',\n                    trigger: ['change', 'blur']\n                },\n                account: {\n                    required: true,\n                    message: '请输入收款账户',\n                    trigger: ['change', 'blur']\n                }\n            }\n        }\n    },\n    likeFruit: [\n        {\n            required: true,\n            message: '请选择您喜欢的水果',\n            trigger: 'change',\n            type: 'array'\n        }\n    ],\n    payType: [\n        {\n            required: true,\n            message: '请选择任意一种支付方式',\n            trigger: 'change'\n        }\n    ],\n    region: [\n        {\n            required: true,\n            message: '请选择地区',\n            trigger: 'change'\n        }\n    ],\n    goodsType: [\n        {\n            required: true,\n            message: '请选择商品类型',\n            trigger: 'change'\n        }\n    ],\n    phone: [\n        {\n            required: true,\n            message: '请输入手机号',\n            trigger: ['change', 'blur']\n        },\n        {\n            validator: (rule, value, callback) => {\n                // 调用uView自带的js验证规则，详见：https://uviewpro.cn/zh/tools/test.html\n                return $u.test.mobile(value);\n            },\n            message: '手机号码不正确',\n            // 触发器可以同时用blur和change，二者之间用英文逗号隔开\n            trigger: ['change', 'blur']\n        }\n    ],\n    code: [\n        {\n            required: true,\n            message: '请输入验证码',\n            trigger: ['change', 'blur']\n        },\n        {\n            type: 'number',\n            message: '验证码只能为数字',\n            trigger: ['change', 'blur']\n        }\n    ],\n    password: [\n        {\n            required: true,\n            message: '请输入密码',\n            trigger: ['change', 'blur']\n        },\n        {\n            // 正则不能含有两边的引号\n            pattern: /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]+\\S{5,12}$/,\n            message: '需同时含有字母和数字，长度在6-12之间',\n            trigger: ['change', 'blur']\n        }\n    ],\n    rePassword: [\n        {\n            required: true,\n            message: '请重新输入密码',\n            trigger: ['change', 'blur']\n        },\n        {\n            validator: (rule, value, callback) => {\n                return value === model.password;\n            },\n            message: '两次输入的密码不相等',\n            trigger: ['change', 'blur']\n        }\n    ]\n};\n\n// 边框显示\nconst border = ref(false);\n// 协议勾选\nconst check = ref(false);\n// 多选水果列表\nconst checkboxList = ref([\n    { name: '荔枝', checked: false, disabled: false },\n    { name: '香蕉', checked: false, disabled: false },\n    { name: '橙子', checked: false, disabled: false },\n    { name: '草莓', checked: false, disabled: false }\n]);\n// 单选支付方式列表\nconst radioList = ref([\n    { name: '支付宝', checked: true, disabled: false },\n    { name: '微信', checked: false, disabled: false },\n    { name: '银联', checked: false, disabled: false },\n    { name: '现金', checked: false, disabled: false }\n]);\n// 性别选择 actionSheet\nconst actionSheetList = ref([{ text: '男' }, { text: '女' }, { text: '保密' }]);\nconst actionSheetShow = ref(false);\n// 地区选择\nconst pickerShow = ref(false);\n// 商品类型选择\nconst selectShow = ref(false);\n// radio/checkbox宽度\nconst radioCheckWidth = ref<'auto' | '50%'>('auto');\n// radio/checkbox是否换行\nconst radioCheckWrap = ref(false);\n// label对齐方式\nconst labelPosition = ref<'left' | 'top'>('left');\n// 验证码按钮文案\nconst codeTips = ref('');\n// 错误提示方式\nconst errorType = ref<FormErrorType[]>(['message']);\n\n// uForm、uCode 组件ref\nconst uFormRef = ref();\nconst uCodeRef = ref();\n\n// 边框配置当前索引\nconst borderCurrent = computed(() => (border.value ? 0 : 1));\n\n// 提交表单\nfunction handleSubmit() {\n    uFormRef.value?.validate((valid: boolean, errors: any[]) => {\n        if (valid) {\n            if (!model.agreement) return $u.toast('请勾选协议');\n            console.log('验证通过', errors);\n        } else {\n            console.log('表单信息', model);\n            console.log('验证失败', errors);\n        }\n    });\n    completeMission('form');\n}\n\n// 重置表单\nfunction handleReset() {\n    uFormRef.value?.resetFields();\n    check.value = false;\n}\n// 点击actionSheet回调\nfunction actionSheetCallback(index: number) {\n    uni.hideKeyboard();\n    model.sex = actionSheetList.value[index].text;\n}\n// checkbox选择发生变化\nfunction checkboxGroupChange(e) {\n    model.likeFruit = e;\n}\n// 勾选版权协议\nfunction checkboxChange(e: { value: boolean }) {\n    model.agreement = e.value;\n}\n// 选择地区回调\ntype RegionObj = { province: { label: string }; city: { label: string }; area: { label: string } };\nfunction regionConfirm(e: RegionObj) {\n    model.region = e.province.label + '-' + e.city.label + '-' + e.area.label;\n}\n// 选择商品类型回调\nfunction selectConfirm(e: Array<{ label: string }>) {\n    model.goodsType = '';\n    e.forEach((val, index) => {\n        model.goodsType += model.goodsType === '' ? val.label : '-' + val.label;\n    });\n}\n// 边框切换\nfunction borderChange(index: number) {\n    border.value = !index;\n}\n// label对齐方式切换\nfunction labelPositionChange(index: number) {\n    labelPosition.value = index === 0 ? 'left' : 'top';\n}\n// radio/checkbox样式切换\nfunction radioCheckboxChange(index: number) {\n    if (index === 0) {\n        radioCheckWrap.value = false;\n        radioCheckWidth.value = 'auto';\n    } else if (index === 1) {\n        radioCheckWrap.value = true;\n        radioCheckWidth.value = 'auto';\n    } else if (index === 2) {\n        radioCheckWrap.value = false;\n        radioCheckWidth.value = '50%';\n    }\n}\n// 验证码变化\nfunction codeChange(text: string) {\n    codeTips.value = text;\n}\n// 获取验证码\nfunction getCode() {\n    if (uCodeRef.value?.canGetCode) {\n        // 模拟向后端请求验证码\n        uni.showLoading({\n            title: '正在获取验证码',\n            mask: true\n        });\n        setTimeout(() => {\n            uni.hideLoading();\n            // 这里此提示会被this.start()方法中的提示覆盖\n            $u.toast('验证码已发送');\n            // 通知验证码组件内部开始倒计时\n            uCodeRef.value.start();\n        }, 2000);\n    } else {\n        $u.toast('倒计时结束后再发送');\n    }\n}\n// 错误提示方式切换\nfunction errorChange(index: number) {\n    if (index === 0) errorType.value = ['message'];\n    if (index === 1) errorType.value = ['toast'];\n    if (index === 2) errorType.value = ['border-bottom'];\n    if (index === 3) errorType.value = ['border'];\n}\n\nfunction sizeChange(index: number) {\n    const sizes: SizeType[] = ['small', 'default', 'large'];\n    size.value = sizes[index];\n}\n</script>\n\n<style scoped lang=\"scss\">\n.wrap {\n    padding: 30rpx;\n}\n\n.agreement {\n    display: flex;\n    align-items: center;\n    margin: 40rpx 0;\n\n    .agreement-text {\n        padding-left: 8rpx;\n        color: $u-tips-color;\n    }\n}\n\n.receipt-account-wrapper {\n    display: flex;\n    flex-direction: column;\n    width: 100%;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsA/fullScreen/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"FullScreen 压窗屏\"\n        desc=\"用于APP端模态弹窗遮盖全屏，支持压窗效果，适合特殊场景。\"\n        :apis=\"'fullScreen'\"\n    >\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <view class=\"u-no-demo-here\">\n                            通过压窗屏打开的模态框，可以遮盖顶部原生的导航栏和底部tabbar栏。\n                            注意：压窗屏只对APP有效，其他端无效。\n                        </view>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">状态</view>\n                        <u-subsection :current=\"current\" :list=\"['打开', '关闭']\" @change=\"openModal\" />\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { onShow } from '@dcloudio/uni-app';\nimport { $u } from '@/uni_modules/uview-pro';\n\nconst current = ref(1);\n\nonShow(() => {\n    current.value = 1;\n});\n\nfunction openModal(index: number) {\n    // 可以传递参数\n    if (index === 0) {\n        $u.route('/pages/example/fullScreen');\n    }\n}\n</script>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "src/pages/componentsA/icon/index.vue",
    "content": "<template>\n    <demo-page title=\"Icon 图标\" desc=\"基于字体的图标集，包含了大多数常见场景的图标。\" :apis=\"'icon'\">\n        <view class=\"wrap\">\n            <view class=\"u-border-left u-border-top inner-wrap\">\n                <view\n                    @tap=\"selectIcon(item.name)\"\n                    class=\"u-icon-item u-border-bottom u-border-right\"\n                    v-for=\"(item, index) in iconList\"\n                    :key=\"index\"\n                >\n                    <u-icon :name=\"item.name\" size=\"40\" color=\"#909399\"></u-icon>\n                    <text class=\"u-icon-name\">{{ item.name }}</text>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\n\nconst iconList = ref([\n    {\n        name: 'level'\n    },\n    {\n        name: 'woman'\n    },\n    {\n        name: 'man'\n    },\n    {\n        name: 'arrow-left-double'\n    },\n    {\n        name: 'arrow-right-double'\n    },\n    {\n        name: 'chat'\n    },\n    {\n        name: 'chat-fill'\n    },\n    {\n        name: 'red-packet'\n    },\n    {\n        name: 'red-packet-fill'\n    },\n    {\n        name: 'order'\n    },\n    {\n        name: 'checkbox-mark'\n    },\n    {\n        name: 'arrow-up-fill'\n    },\n    {\n        name: 'arrow-down-fill'\n    },\n    {\n        name: 'backspace'\n    },\n    {\n        name: 'photo'\n    },\n    {\n        name: 'photo-fill'\n    },\n    {\n        name: 'lock'\n    },\n    {\n        name: 'lock-fill'\n    },\n    {\n        name: 'lock-open'\n    },\n    {\n        name: 'lock-opened-fill'\n    },\n    {\n        name: 'hourglass'\n    },\n    {\n        name: 'hourglass-half-fill'\n    },\n    {\n        name: 'home'\n    },\n    {\n        name: 'home-fill'\n    },\n    {\n        name: 'fingerprint'\n    },\n    {\n        name: 'cut'\n    },\n    {\n        name: 'star'\n    },\n    {\n        name: 'star-fill'\n    },\n    {\n        name: 'share'\n    },\n    {\n        name: 'share-fill'\n    },\n    {\n        name: 'volume-up'\n    },\n    {\n        name: 'volume-up-fill'\n    },\n    {\n        name: 'volume-off'\n    },\n    {\n        name: 'volume-off-fill'\n    },\n    {\n        name: 'trash'\n    },\n    {\n        name: 'trash-fill'\n    },\n    {\n        name: 'rewind-right'\n    },\n    {\n        name: 'rewind-right-fill'\n    },\n    {\n        name: 'rewind-left'\n    },\n    {\n        name: 'rewind-left-fill'\n    },\n    {\n        name: 'shopping-cart'\n    },\n    {\n        name: 'shopping-cart-fill'\n    },\n    {\n        name: 'question'\n    },\n    {\n        name: 'question-circle'\n    },\n    {\n        name: 'question-circle-fill'\n    },\n    {\n        name: 'plus'\n    },\n    {\n        name: 'plus-circle'\n    },\n    {\n        name: 'plus-circle-fill'\n    },\n    {\n        name: 'tags'\n    },\n    {\n        name: 'tags-fill'\n    },\n    {\n        name: 'pause'\n    },\n    {\n        name: 'pause-circle'\n    },\n    {\n        name: 'pause-circle-fill'\n    },\n    {\n        name: 'play-circle'\n    },\n    {\n        name: 'play-circle-fill'\n    },\n    {\n        name: 'map'\n    },\n    {\n        name: 'map-fill'\n    },\n    {\n        name: 'phone'\n    },\n    {\n        name: 'phone-fill'\n    },\n    {\n        name: 'list'\n    },\n    {\n        name: 'list-dot'\n    },\n    {\n        name: 'man-delete'\n    },\n    {\n        name: 'man-add'\n    },\n    {\n        name: 'man-add-fill'\n    },\n    {\n        name: 'person-delete-fill'\n    },\n    {\n        name: 'info'\n    },\n    {\n        name: 'info-circle'\n    },\n    {\n        name: 'info-circle-fill'\n    },\n    {\n        name: 'minus'\n    },\n    {\n        name: 'minus-circle'\n    },\n    {\n        name: 'minus-circle-fill'\n    },\n    {\n        name: 'mic'\n    },\n    {\n        name: 'mic-off'\n    },\n    {\n        name: 'grid'\n    },\n    {\n        name: 'grid-fill'\n    },\n    {\n        name: 'eye'\n    },\n    {\n        name: 'eye-fill'\n    },\n    {\n        name: 'eye-off'\n    },\n    {\n        name: 'file-text'\n    },\n    {\n        name: 'file-text-fill'\n    },\n    {\n        name: 'edit-pen'\n    },\n    {\n        name: 'edit-pen-fill'\n    },\n    {\n        name: 'email'\n    },\n    {\n        name: 'email-fill'\n    },\n    {\n        name: 'download'\n    },\n    {\n        name: 'checkmark'\n    },\n    {\n        name: 'checkmark-circle'\n    },\n    {\n        name: 'checkmark-circle-fill'\n    },\n    {\n        name: 'clock'\n    },\n    {\n        name: 'clock-fill'\n    },\n    {\n        name: 'close'\n    },\n    {\n        name: 'close-circle'\n    },\n    {\n        name: 'close-circle-fill'\n    },\n    {\n        name: 'calendar'\n    },\n    {\n        name: 'calendar-fill'\n    },\n    {\n        name: 'car'\n    },\n    {\n        name: 'car-fill'\n    },\n    {\n        name: 'bell'\n    },\n    {\n        name: 'bell-fill'\n    },\n    {\n        name: 'bookmark'\n    },\n    {\n        name: 'bookmark-fill'\n    },\n    {\n        name: 'attach'\n    },\n    {\n        name: 'play-right'\n    },\n    {\n        name: 'play-right-fill'\n    },\n    {\n        name: 'play-left'\n    },\n    {\n        name: 'play-left-fill'\n    },\n    {\n        name: 'error'\n    },\n    {\n        name: 'error-circle'\n    },\n    {\n        name: 'error-circle-fill'\n    },\n    {\n        name: 'wifi'\n    },\n    {\n        name: 'wifi-off'\n    },\n    {\n        name: 'skip-back-left'\n    },\n    {\n        name: 'skip-forward-right'\n    },\n    {\n        name: 'search'\n    },\n    {\n        name: 'setting'\n    },\n    {\n        name: 'setting-fill'\n    },\n    {\n        name: 'volume'\n    },\n    {\n        name: 'volume-fill'\n    },\n    {\n        name: 'more-dot-fill'\n    },\n    {\n        name: 'more-circle'\n    },\n    {\n        name: 'more-circle-fill'\n    },\n    {\n        name: 'bag'\n    },\n    {\n        name: 'bag-fill'\n    },\n    {\n        name: 'arrow-upward'\n    },\n    {\n        name: 'arrow-downward'\n    },\n    {\n        name: 'arrow-leftward'\n    },\n    {\n        name: 'arrow-rightward'\n    },\n    {\n        name: 'arrow-up'\n    },\n    {\n        name: 'arrow-down'\n    },\n    {\n        name: 'arrow-left'\n    },\n    {\n        name: 'arrow-right'\n    },\n    {\n        name: 'rmb'\n    },\n    {\n        name: 'rmb-circle'\n    },\n    {\n        name: 'rmb-circle-fill'\n    },\n    {\n        name: 'thumb-up'\n    },\n    {\n        name: 'thumb-up-fill'\n    },\n    {\n        name: 'thumb-down'\n    },\n    {\n        name: 'thumb-down-fill'\n    },\n    {\n        name: 'coupon'\n    },\n    {\n        name: 'coupon-fill'\n    },\n    {\n        name: 'kefu-ermai'\n    },\n    {\n        name: 'server-fill'\n    },\n    {\n        name: 'server-man'\n    },\n    {\n        name: 'scan'\n    },\n    {\n        name: 'warning'\n    },\n    {\n        name: 'warning-fill'\n    },\n    {\n        name: 'google'\n    },\n    {\n        name: 'google-circle-fill'\n    },\n    {\n        name: 'chrome-circle-fill'\n    },\n    {\n        name: 'ie'\n    },\n    {\n        name: 'IE-circle-fill'\n    },\n    {\n        name: 'github-circle-fill'\n    },\n    {\n        name: 'android-fill'\n    },\n    {\n        name: 'android-circle-fill'\n    },\n    {\n        name: 'apple-fill'\n    },\n    {\n        name: 'camera'\n    },\n    {\n        name: 'camera-fill'\n    },\n    {\n        name: 'pushpin'\n    },\n    {\n        name: 'pushpin-fill'\n    },\n    {\n        name: 'minus-square-fill'\n    },\n    {\n        name: 'plus-square-fill'\n    },\n    {\n        name: 'heart'\n    },\n    {\n        name: 'heart-fill'\n    },\n    {\n        name: 'reload'\n    },\n    {\n        name: 'account'\n    },\n    {\n        name: 'account-fill'\n    },\n    {\n        name: 'minus-people-fill'\n    },\n    {\n        name: 'plus-people-fill'\n    },\n    {\n        name: 'integral'\n    },\n    {\n        name: 'integral-fill'\n    },\n    {\n        name: 'zhihu'\n    },\n    {\n        name: 'zhihu-circle-fill'\n    },\n    {\n        name: 'gift'\n    },\n    {\n        name: 'gift-fill'\n    },\n    {\n        name: 'zhifubao'\n    },\n    {\n        name: 'zhifubao-circle-fill'\n    },\n    {\n        name: 'weixin-fill'\n    },\n    {\n        name: 'weixin-circle-fill'\n    },\n    {\n        name: 'twitter'\n    },\n    {\n        name: 'twitter-circle-fill'\n    },\n    {\n        name: 'taobao'\n    },\n    {\n        name: 'taobao-circle-fill'\n    },\n    {\n        name: 'weibo'\n    },\n    {\n        name: 'weibo-circle-fill'\n    },\n    {\n        name: 'qq-fill'\n    },\n    {\n        name: 'qq-circle-fill'\n    },\n    {\n        name: 'moments'\n    },\n    {\n        name: 'moments-circel-fill'\n    },\n    {\n        name: 'qzone'\n    },\n    {\n        name: 'qzone-circle-fill'\n    },\n    {\n        name: 'facebook'\n    },\n    {\n        name: 'facebook-circle-fill'\n    },\n    {\n        name: 'baidu'\n    },\n    {\n        name: 'baidu-circle-fill'\n    },\n    {\n        name: 'zhuanfa'\n    }\n]);\n\nconst selectIcon = (name: string) => {\n    uni.setClipboardData({\n        data: name,\n        success: () => {\n            uni.showToast({\n                title: '图标名称已复制',\n                icon: 'none'\n            });\n        }\n    });\n};\n</script>\n\n<style scoped lang=\"scss\">\n.wrap {\n    padding: 24rpx;\n}\n\n.inner-wrap {\n    display: flex;\n    flex-wrap: wrap;\n}\n.u-icon-item {\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    height: 190rpx;\n    flex: 0 0 33.33333333%;\n    justify-content: center;\n    overflow: hidden;\n}\n\n.u-icon-name {\n    color: $u-tips-color;\n    word-wrap: break-word;\n    word-break: break-all;\n    margin-top: 16rpx;\n    font-size: 26rpx;\n    padding: 0 14rpx;\n    // 给定高度是为了图标名超出一行时，进行换行能有更好的效果\n    height: 26rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsA/indexList/index.vue",
    "content": "<template>\n    <demo-page hide-tabs nav-title=\"索引列表\">\n        <u-index-list :scrollTop=\"scrollTop\" :index-list=\"indexListRef\">\n            <view v-for=\"(item, idx) in list\" :key=\"idx\">\n                <u-index-anchor :index=\"item.letter\" />\n                <view class=\"list-cell u-border-bottom\" v-for=\"(item1, idx1) in item.data\" :key=\"idx1\">\n                    {{ item1.name }}\n                </view>\n            </view>\n        </u-index-list>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport indexListDataRaw from '@/common/index.list';\nimport { onPageScroll } from '@dcloudio/uni-app';\n\n// 单个数据项类型声明\ninterface ListItemData {\n    name: string;\n    [key: string]: any;\n}\n// 单个字母分组类型声明\ninterface IndexListItem {\n    letter: string;\n    data: ListItemData[];\n}\n\n// 全部分组数据\nconst list = ref<IndexListItem[]>((indexListDataRaw as any).list);\n// 字母索引数组\nconst indexListArr: string[] = (indexListDataRaw as any).list.map((val: IndexListItem) => val.letter);\nconst indexListRef = ref<string[]>(indexListArr);\n// 当前滚动位置\nconst scrollTop = ref<number>(0);\n\n/**\n * 页面滚动事件，更新 scrollTop\n * @param e 页面滚动事件对象\n */\n\nonPageScroll((e: { scrollTop: number }) => {\n    scrollTop.value = e.scrollTop;\n});\n</script>\n\n<style lang=\"scss\" scoped>\n.list-cell {\n    display: flex;\n    box-sizing: border-box;\n    width: 100%;\n    padding: 10px 24rpx;\n    overflow: hidden;\n    color: $u-content-color;\n    font-size: 14px;\n    line-height: 24px;\n    background-color: $u-bg-white;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsA/input/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"Input 输入框\"\n        desc=\"此组件为一个输入框，默认没有边框和样式，是专门为配合表单组件u-form而设计的，利用它可以快速实现表单验证，输入内容，下拉选择等功能。\"\n        :apis=\"'input'\"\n    >\n        <view class=\"u-demo\">\n            <view class=\"u-demo-wrap\">\n                <view class=\"u-demo-title\">演示效果</view>\n                <view class=\"u-demo-area\">\n                    <u-input\n                        v-model=\"username\"\n                        label=\"用户名\"\n                        placeholder=\"请填写用户名\"\n                        :custom-style=\"customStyle\"\n                        :type=\"type\"\n                        :input-align=\"inputAlign\"\n                        :maxlength=\"maxlength\"\n                        :clearable=\"clearable\"\n                        :border=\"border\"\n                        :border-color=\"borderColor\"\n                        :focus=\"focus\"\n                        :size=\"size\"\n                    />\n                    <u-gap></u-gap>\n                    <u-input\n                        v-model=\"password\"\n                        label=\"密码\"\n                        placeholder=\"请填写密码\"\n                        :custom-style=\"customStyle\"\n                        :type=\"type2\"\n                        :input-align=\"inputAlign\"\n                        :maxlength=\"maxlength\"\n                        :clearable=\"clearable\"\n                        :border=\"border\"\n                        :border-color=\"borderColor\"\n                        :size=\"size\"\n                    >\n                    </u-input>\n                </view>\n            </view>\n            <view class=\"u-config-wrap\">\n                <view class=\"u-config-title u-border-bottom\">参数配置</view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">输入框大小</view>\n                    <u-subsection current=\"1\" :list=\"['小', '中', '大', '60']\" @change=\"sizeChange\" />\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">第一个输入框为textarea类型</view>\n                    <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"textareaChange\" />\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">输入框对齐方式</view>\n                    <u-subsection current=\"0\" :list=\"['左', '居中', '右']\" @change=\"inputAlignChange\" />\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">最大长度</view>\n                    <u-subsection current=\"0\" :list=\"['140', '20', '10']\" @change=\"maxlengthChange\" />\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">可清空</view>\n                    <u-subsection current=\"0\" :list=\"['是', '否']\" @change=\"clearableChange\" />\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">显示边框</view>\n                    <u-subsection current=\"0\" :list=\"['是', '否']\" @change=\"borderChange\" />\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">边框颜色</view>\n                    <u-subsection current=\"0\" :list=\"['#dcdfe6', '#ff0000', '#00ff00']\" @change=\"borderColorChange\" />\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">自动聚焦</view>\n                    <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"focusChange\" />\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">密码图标</view>\n                    <u-subsection current=\"0\" :list=\"['是', '否']\" @change=\"passwordIconChange\" />\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">自定义样式</view>\n                    <u-subsection current=\"1\" :list=\"['有', '无']\" @change=\"customStyleChange\" />\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport type { InputType, InputAlign, SizeType } from '@/uni_modules/uview-pro/types/global';\n\nconst username = ref('');\nconst password = ref('');\nconst type = ref<InputType>('text');\nconst type2 = ref<InputType>('password');\nconst inputAlign = ref<InputAlign>('left');\nconst maxlength = ref<number>(140);\nconst clearable = ref(true);\nconst border = ref(true);\nconst borderColor = ref('#dcdfe6');\nconst focus = ref(false);\nconst passwordIcon = ref(true);\nconst customStyle = ref<Record<string, any>>({});\nconst size = ref<SizeType | string>('default');\n\nfunction textareaChange(index: number) {\n    type.value = index === 0 ? 'textarea' : 'text';\n}\n\nfunction inputAlignChange(index: number) {\n    const aligns: InputAlign[] = ['left', 'center', 'right'];\n    inputAlign.value = aligns[index];\n    console.log(aligns[index]);\n}\nfunction maxlengthChange(index: number) {\n    maxlength.value = [140, 20, 10][index];\n}\nfunction clearableChange(index: number) {\n    clearable.value = index === 0;\n}\nfunction borderChange(index: number) {\n    border.value = index === 0;\n}\nfunction borderColorChange(index: number) {\n    borderColor.value = ['#dcdfe6', '#ff0000', '#00ff00'][index];\n}\nfunction focusChange(index: number) {\n    focus.value = index === 0;\n}\nfunction passwordIconChange(index: number) {\n    passwordIcon.value = index === 0;\n    type2.value = index === 0 ? 'password' : 'text';\n}\nfunction customStyleChange(index: number) {\n    customStyle.value = index === 0 ? { background: '#f5f5f5', color: '#333' } : {};\n}\nfunction sizeChange(index: number) {\n    const sizes: SizeType[] = ['small', 'default', 'large'];\n    if (index < 3) {\n        size.value = sizes[index];\n    } else {\n        size.value = '60rpx';\n    }\n}\n</script>\n"
  },
  {
    "path": "src/pages/componentsA/keyboard/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"Keyboard 虚拟键盘\"\n        desc=\"用于数字、身份证、车牌号等多种输入场景，支持自定义键盘类型和交互。\"\n        :apis=\"'keyboard'\"\n    >\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <view class=\"input-wrap\">\n                            <input class=\"input\" disabled type=\"text\" :value=\"input\" placeholder=\"来自键盘的输入内容\" />\n                            <u-button\n                                :custom-style=\"{ height: '32px' }\"\n                                :hairLine=\"false\"\n                                class=\"clear-btn\"\n                                @click=\"clear()\"\n                            >\n                                清空\n                            </u-button>\n                        </view>\n                        <u-keyboard\n                            :mask=\"mask\"\n                            ref=\"uKeyboard\"\n                            safe-area-inset-bottom\n                            @confirm=\"confirm\"\n                            :random=\"random\"\n                            :dotEnable=\"false\"\n                            :mode=\"mode\"\n                            :confirmBtn=\"true\"\n                            :cancelBtn=\"true\"\n                            :tooltip=\"tooltip\"\n                            v-model=\"show\"\n                            @change=\"change\"\n                            @backspace=\"backspace\"\n                        />\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">键盘开关</view>\n                        <u-subsection :current=\"show == true ? 0 : 1\" :list=\"['开', '关']\" @change=\"statusChange\" />\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">键盘类型</view>\n                        <u-subsection :list=\"['数字键盘', '身份证键盘', '车牌号键盘']\" @change=\"modeChange\" />\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">打乱顺序</view>\n                        <u-subsection :current=\"1\" :list=\"['是', '否']\" @change=\"randomChange\" />\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">上方工具条</view>\n                        <u-subsection :list=\"['显示', '隐藏']\" @change=\"tooltipChange\" />\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">是否显示遮罩</view>\n                        <u-subsection :list=\"['显示', '隐藏']\" @change=\"maskChange\" />\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\n\nconst show = ref(false);\nconst input = ref('');\nconst mode = ref('number');\nconst random = ref(false);\nconst tooltip = ref(true);\nconst mask = ref(true);\n\nfunction clear() {\n    input.value = '';\n}\n\nfunction statusChange(index: number) {\n    show.value = index === 0;\n}\n\nfunction modeChange(index) {\n    mode.value = index === 0 ? 'number' : index === 1 ? 'card' : 'car';\n    show.value = true;\n}\n\nfunction randomChange(index: number) {\n    random.value = index === 0;\n    show.value = true;\n}\n\nfunction tooltipChange(index: number) {\n    tooltip.value = index === 0;\n    show.value = true;\n}\n\nfunction maskChange(index: number) {\n    show.value = true;\n    mask.value = index === 0;\n}\n\nfunction backspace() {\n    if (input.value.length) input.value = input.value.substring(0, input.value.length - 1);\n}\n\nfunction change(detail: string) {\n    input.value += detail;\n}\n\nfunction confirm(e: any) {\n    console.log(e);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.input {\n    border: 1px solid $u-light-color;\n    border-radius: 4px;\n    margin-bottom: 20px;\n    height: 32px;\n    font-size: 26rpx;\n    flex: 1;\n    box-sizing: border-box;\n}\n\n.input-wrap {\n    display: flex;\n}\n\n.clear-btn {\n    margin-left: 10px;\n    font-size: 28rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsA/lazyLoad/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"LazyLoad 图片懒加载\"\n        desc=\"用于长列表、图片流等场景的图片懒加载，提升页面性能和体验。\"\n        :apis=\"'lazyLoad'\"\n    >\n        <template #default>\n            <view class=\"wrap\">\n                <view class=\"item-warp\">\n                    <view class=\"item\" v-for=\"(item, index) in list\" :key=\"index\">\n                        <u-lazy-load\n                            threshold=\"-450\"\n                            height=\"400\"\n                            img-mode=\"aspectFill\"\n                            border-radius=\"10\"\n                            :image=\"item.src\"\n                            :index=\"index\"\n                            @statusChange=\"statusChange\"\n                            @clickImg=\"clickImg\"\n                        />\n                    </view>\n                </view>\n                <u-loadmore :status=\"status\" @loadmore=\"getData\" />\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\nimport { onLoad } from '@dcloudio/uni-app';\nimport type { LoadmoreStatus } from '@/uni_modules/uview-pro/types/global';\n\nconst list = ref([]);\nconst status = ref<LoadmoreStatus>('loadmore');\nconst data = ref([\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i1/TB124_3NXXXXXasXVXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i7/TB1IWtgQFXXXXcmXFXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i1/TB1_f_PLXXXXXbVXpXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        // 这里会加载失败，显示错误的占位图\n        src: 'error.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i6/TB1SIYrLXXXXXaAXpXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i1/TB11yxeNVXXXXbwXFXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i3/TB1ndJiQFXXXXctaXXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i4/TB1BYGDLpXXXXbuXXXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i2/TB1_9GoMVXXXXXmaXXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i2/TB1cSZZNFXXXXaKaXXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        // 这里会加载失败，显示错误的占位图\n        src: 'error.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i8/TB1RVS_QpXXXXXBXXXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i5/TB1xEJiLXXXXXcxaXXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i6/TB1DSuHJVXXXXXmXXXXwu0bFXXX.png_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i5/TB1aMNyLpXXXXa2XXXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i8/TB1JRHEQpXXXXXwXVXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i7/TB1qKEuQpXXXXXYXXXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i7/TB1TlOfQFXXXXX2XXXXwu0bFXXX.png_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i1/TB1SKu.QpXXXXbDXVXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        // 这里会加载失败，显示错误的占位图\n        src: 'error.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i8/TB1um5GQpXXXXbiaXXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i1/TB1pxCTQpXXXXa2apXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i6/TB1zksMNVXXXXaRapXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i4/TB1nbrcOXXXXXXEXpXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i4/TB1CI_NQpXXXXXaXVXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i2/TB18vTdQFXXXXXlXpXXwu0bFXXX.png_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i7/TB1doDVQpXXXXcRaXXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i1/TB17LgBNFXXXXaSXVXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i6/TB1fVJJQFXXXXcyXpXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i3/TB1wnBTKFXXXXcQXXXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i1/TB124_3NXXXXXasXVXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i7/TB1IWtgQFXXXXcmXFXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i1/TB1_f_PLXXXXXbVXpXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i1/TB1DX3hIpXXXXXIaXXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i6/TB1SIYrLXXXXXaAXpXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i1/TB11yxeNVXXXXbwXFXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i3/TB1ndJiQFXXXXctaXXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i4/TB1BYGDLpXXXXbuXXXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i2/TB1_9GoMVXXXXXmaXXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i2/TB1cSZZNFXXXXaKaXXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        // 这里会加载失败，显示错误的占位图\n        src: 'error.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i8/TB1RVS_QpXXXXXBXXXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i5/TB1xEJiLXXXXXcxaXXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i6/TB1DSuHJVXXXXXmXXXXwu0bFXXX.png_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i5/TB1aMNyLpXXXXa2XXXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i8/TB1JRHEQpXXXXXwXVXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i7/TB1qKEuQpXXXXXYXXXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i7/TB1TlOfQFXXXXX2XXXXwu0bFXXX.png_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i1/TB1SKu.QpXXXXbDXVXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i2/TB17gJ3OXXXXXcrXpXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i8/TB1um5GQpXXXXbiaXXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i1/TB1pxCTQpXXXXa2apXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i6/TB1zksMNVXXXXaRapXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i4/TB1nbrcOXXXXXXEXpXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i4/TB1CI_NQpXXXXXaXVXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i2/TB18vTdQFXXXXXlXpXXwu0bFXXX.png_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i7/TB1doDVQpXXXXcRaXXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        src: 'https://gtd.alicdn.com/sns_logo/i1/TB17LgBNFXXXXaSXVXXSutbFXXX.jpg_240x240xz.jpg'\n    },\n    {\n        // 这里会加载失败，显示错误的占位图\n        src: 'error.jpg'\n    }\n]);\n\nonLoad(() => {\n    getData();\n});\n\nfunction statusChange(status) {\n    console.log(status);\n}\n\nfunction clickImg(img) {\n    console.log(img);\n}\n\nfunction getData() {\n    let index = 0;\n    status.value = 'loading';\n    setTimeout(() => {\n        for (let i = 0; i < 10; i++) {\n            index = $u.random(0, data.value.length - 1);\n            list.value.push({\n                src: data.value[index].src\n            });\n        }\n        status.value = 'loadmore';\n    }, 1500);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.wrap {\n    padding: 30rpx;\n    display: block;\n}\n\n.item-warp {\n    display: flex;\n    justify-content: space-between;\n    flex-wrap: wrap;\n}\n\n.item-warp .item {\n    flex: 0 0 335rpx;\n    height: 400rpx;\n    margin-bottom: 20rpx;\n    border-radius: 10rpx;\n    overflow: hidden;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsA/modal/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"Modal 弹窗\"\n        desc=\"用于消息提示、操作确认等场景的模态弹窗，支持自定义内容和异步关闭。\"\n        :apis=\"'modal'\"\n    >\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <view class=\"u-no-demo-here\">请点击弹出弹窗查看效果</view>\n                        <u-gap></u-gap>\n                        <u-button type=\"primary\" @click=\"showGlobalModal\">使用useModal弹出</u-button>\n                        <u-modal\n                            ref=\"uModalRef\"\n                            v-model=\"show\"\n                            :show-cancel-button=\"true\"\n                            :show-title=\"showTitle\"\n                            :async-close=\"asyncClose\"\n                            @confirm=\"confirm\"\n                            :content=\"content\"\n                        >\n                            <!-- #ifndef MP-WEIXIN || MP-TOUTIAO -->\n                            <template #default v-if=\"contentSlot\">\n                                <view class=\"warp\" style=\"margin: 30rpx\">\n                                    <image\n                                        class=\"logo\"\n                                        src=\"https://ik.imagekit.io/anyup/uview-pro/common/logo-new.png\"\n                                        style=\"width: 220rpx\"\n                                        mode=\"widthFix\"\n                                    ></image>\n                                </view>\n                            </template>\n                            <!-- #endif -->\n                        </u-modal>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\">参数配置</view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">状态</view>\n                        <u-subsection :current=\"current\" :list=\"['显示', '隐藏']\" @change=\"showChange\" />\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">是否显示标题</view>\n                        <u-subsection current=\"0\" :list=\"['是', '否']\" @change=\"titleChange\" />\n                    </view>\n                    <!-- #ifndef MP-WEIXIN -->\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">自定义内容</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"contentChange\" />\n                    </view>\n                    <!-- #endif -->\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">异步关闭</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"asyncChange\" />\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { useModal, useToast } from 'uview-pro';\nimport { ref, computed } from 'vue';\n\nconst show = ref<boolean>(false);\nconst content = ref<string>('慈母手中线，游子身上衣');\nconst contentSlot = ref<boolean>(false);\nconst showTitle = ref<boolean>(true);\nconst asyncClose = ref<boolean>(false);\nconst modal = useModal();\nconst toast = useToast();\n\nfunction showGlobalModal() {\n    // 完整用法\n    modal.confirm({\n        title: '确认删除',\n        content: '确定要删除这条数据吗？',\n        confirmText: '删除',\n        cancelText: '取消',\n        asyncClose: true,\n        onConfirm: () => {\n            toast.show('用户点击了确认');\n            setTimeout(() => {\n                modal.close();\n            }, 2000);\n        },\n        onCancel: () => {\n            toast.show('用户点击了取消');\n        }\n    });\n}\n\nconst current = computed(() => {\n    return show.value ? 0 : 1;\n});\n\nfunction showChange(index: number) {\n    show.value = !index;\n}\n\nfunction titleChange(index: number) {\n    showTitle.value = !index;\n    show.value = true;\n}\n\nfunction contentChange(index: number) {\n    contentSlot.value = !index;\n    show.value = true;\n}\n\nfunction asyncChange(index: number) {\n    show.value = true;\n    asyncClose.value = !index;\n}\n\nfunction confirm() {\n    setTimeout(() => {\n        show.value = false;\n    }, 2000);\n}\n</script>\n\n<style scoped lang=\"scss\">\n.logo {\n    height: auto;\n    will-change: transform;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsA/navbar/index.vue",
    "content": "<template>\n    <view>\n        <u-navbar\n            title-color=\"#fff\"\n            back-icon-color=\"#ffffff\"\n            :is-fixed=\"isFixed\"\n            :is-back=\"isBack\"\n            :background=\"background\"\n            :back-text-style=\"{ color: '#fff' }\"\n            :title=\"title\"\n            :back-icon-name=\"backIconName\"\n            :back-text=\"backText\"\n            :custom-back=\"customBack\"\n        >\n            <view class=\"slot-wrap\" v-if=\"useSlot\">\n                <view class=\"search-wrap\" v-if=\"search\">\n                    <u-search\n                        v-model=\"keyword\"\n                        :show-action=\"showAction\"\n                        height=\"56\"\n                        :action-style=\"{ color: '#fff' }\"\n                    />\n                </view>\n                <view class=\"navbar-right\" v-if=\"rightSlot\">\n                    <view class=\"message-box right-item\">\n                        <u-icon name=\"chat\" size=\"38\" />\n                        <u-badge count=\"18\" size=\"mini\" :offset=\"[-15, -15]\" />\n                    </view>\n                    <view class=\"dot-box right-item\">\n                        <u-icon name=\"calendar-fill\" size=\"38\" />\n                        <u-badge size=\"mini\" :is-dot=\"true\" :offset=\"[-6, -6]\" />\n                    </view>\n                </view>\n                <view class=\"map-wrap\" v-if=\"custom\">\n                    <u-icon name=\"map\" color=\"#ffffff\" size=\"24\" />\n                    <text class=\"map-wrap-text\">轻舟已过万重山</text>\n                    <u-icon name=\"arrow-down-fill\" color=\"#ffffff\" size=\"22\" />\n                </view>\n            </view>\n            <template #right v-if=\"rightSlot\">\n                <view class=\"navbar-right\">\n                    <view class=\"message-box right-item\">\n                        <u-icon name=\"chat\" size=\"38\" />\n                        <u-badge count=\"18\" size=\"mini\" :offset=\"[-15, -15]\" />\n                    </view>\n                    <view class=\"dot-box right-item\">\n                        <u-icon name=\"calendar-fill\" size=\"38\" />\n                        <u-badge size=\"mini\" :is-dot=\"true\" :offset=\"[-6, -6]\" />\n                    </view>\n                </view>\n            </template>\n        </u-navbar>\n        <demo-page\n            title=\"Navbar 导航栏\"\n            desc=\"用于页面顶部导航，支持自定义内容、返回事件、渐变背景等丰富场景。\"\n            :apis=\"'navbar'\"\n            hide-nav\n        >\n            <template #default>\n                <view class=\"u-demo\">\n                    <view class=\"u-demo-wrap\">\n                        <view class=\"u-demo-title\">演示效果</view>\n                        <view class=\"u-demo-area\">\n                            <u-toast ref=\"uToastRef\" />\n                            <view class=\"u-no-demo-here\">查看顶部导航栏效果</view>\n                        </view>\n                    </view>\n                    <view class=\"u-config-wrap\">\n                        <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                        <view class=\"u-config-item\">\n                            <view class=\"u-item-title\">标题长度</view>\n                            <u-subsection :list=\"['短', '中', '长']\" @change=\"titleChange\" />\n                        </view>\n                        <view class=\"u-config-item\">\n                            <view class=\"u-item-title\">隐藏左侧返回区域</view>\n                            <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"backChange\" />\n                        </view>\n                        <view class=\"u-config-item\">\n                            <view class=\"u-item-title\">自定义左侧内容</view>\n                            <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"leftChange\" />\n                        </view>\n                        <view class=\"u-config-item\">\n                            <view class=\"u-item-title\">自定义右侧内容</view>\n                            <u-subsection :current=\"slotRightCurrent\" :list=\"['是', '否']\" @change=\"rightChange\" />\n                        </view>\n                        <view class=\"u-config-item\">\n                            <view class=\"u-item-title\">传入整体slot</view>\n                            <u-subsection :list=\"['无', '搜索框', '搜索+按钮', '搜索+图标']\" @change=\"searchChange\" />\n                        </view>\n                        <view class=\"u-config-item\">\n                            <view class=\"u-item-title\">完全自定义传入内容</view>\n                            <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"customChange\" />\n                        </view>\n                        <view class=\"u-config-item\">\n                            <view class=\"u-item-title\">背景色</view>\n                            <u-subsection :list=\"['渐变', '#39CCCC', '#B471CC', '#001f3f']\" @change=\"bgColorChange\" />\n                        </view>\n                        <view class=\"u-config-item\">\n                            <view class=\"u-item-title\">自定义返回事件</view>\n                            <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"customBackChange\" />\n                        </view>\n                    </view>\n                </view>\n            </template>\n        </demo-page>\n    </view>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed } from 'vue';\n\nconst title = ref<string | null>('新闻');\nconst backText = ref<string>('返回');\nconst backIconName = ref<string>('nav-back');\nconst right = ref<boolean>(false);\nconst showAction = ref<boolean>(false);\nconst rightSlot = ref<boolean>(false);\nconst useSlot = ref<boolean>(false);\nconst background = ref<Record<string, string>>({\n    'background-image': 'linear-gradient(45deg, rgb(28, 187, 180), rgb(141, 198, 63))'\n});\nconst isBack = ref<boolean>(true);\nconst search = ref<boolean>(false);\nconst custom = ref<boolean>(false);\nconst isFixed = ref<boolean>(true);\nconst keyword = ref<string>('');\n\n// #ifdef MP\nrightSlot.value = false;\n// #endif\n// #ifndef MP\nrightSlot.value = true;\n// #endif\n\nconst customBack = ref<(() => void) | null>(null);\nconst uToastRef = ref<any>(null);\n\nconst slotRightCurrent = computed(() => {\n    return rightSlot.value ? 0 : 1;\n});\n\nfunction customBackChange(index: number): void {\n    if (index == 0) {\n        customBack.value = () => {\n            uToastRef.value.show({\n                title: '自定义返回逻辑',\n                type: 'success'\n            });\n        };\n    } else {\n        customBack.value = null;\n    }\n}\n\nfunction titleChange(index: number): void {\n    useSlot.value = false;\n    title.value = index == 0 ? '新闻' : index == 1 ? '新闻列表' : '雨打梨花深闭门，忘了青春，误了青春';\n}\n\nfunction leftChange(index: number): void {\n    if (index == 0) {\n        backText.value = '';\n        backIconName.value = 'arrow-leftward';\n    } else {\n        backText.value = '返回';\n        backIconName.value = 'arrow-left';\n    }\n}\n\nfunction searchChange(index: number): void {\n    title.value = null;\n    useSlot.value = true;\n    search.value = false;\n    custom.value = false;\n    if (index == 0) {\n        title.value = '新闻';\n        useSlot.value = false;\n        rightSlot.value = false;\n    } else if (index == 1) {\n        showAction.value = false;\n        useSlot.value = true;\n        rightSlot.value = false;\n        search.value = true;\n        rightSlot.value = false;\n    } else if (index == 2) {\n        useSlot.value = true;\n        showAction.value = true;\n        rightSlot.value = false;\n        search.value = true;\n        rightSlot.value = false;\n    } else {\n        useSlot.value = true;\n        search.value = true;\n        showAction.value = false;\n        rightSlot.value = true;\n        rightSlot.value = false;\n    }\n}\n\nfunction backChange(index: number): void {\n    isBack.value = !!index;\n}\n\nfunction bgColorChange(index: number): void {\n    background.value = {};\n    if (index == 0) {\n        background.value = {\n            'background-image': 'linear-gradient(45deg, rgb(28, 187, 180), rgb(141, 198, 63))'\n        };\n    } else {\n        const color = index == 1 ? '#39CCCC' : index == 2 ? '#B471CC' : '#001f3f';\n        background.value = {\n            background: color\n        };\n    }\n}\n\nfunction rightChange(index: number): void {\n    if (index == 0) {\n        rightSlot.value = true;\n        useSlot.value = false;\n    } else {\n        rightSlot.value = false;\n    }\n}\n\nfunction customChange(index: number): void {\n    search.value = false;\n    rightSlot.value = false;\n    if (index == 0) {\n        custom.value = true;\n        title.value = null;\n        isBack.value = false;\n        useSlot.value = true;\n    } else {\n        useSlot.value = false;\n        title.value = '新闻';\n        isBack.value = true;\n    }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.u-demo {\n    //height: 200vh;\n    height: calc(100% - 44px);\n    height: calc(100% - 44px - constant(safe-area-inset-top));\n    height: calc(100% - 44px - env(safe-area-inset-top));\n}\n\n.wrap {\n    padding: 24rpx;\n}\n\n.navbar-right {\n    margin-right: 24rpx;\n    display: flex;\n}\n\n.search-wrap {\n    margin: 0 20rpx;\n    flex: 1;\n}\n\n.right-item {\n    margin: 0 12rpx;\n    position: relative;\n    color: #ffffff;\n    display: flex;\n}\n\n.message-box {\n}\n\n.slot-wrap {\n    display: flex;\n    align-items: center;\n    flex: 1;\n}\n\n.map-wrap {\n    display: flex;\n    align-items: center;\n    padding: 4px 6px;\n    background-color: rgba(240, 240, 240, 0.35);\n    color: #fff;\n    font-size: 22rpx;\n    border-radius: 100rpx;\n    margin-left: 30rpx;\n}\n\n.map-wrap-text {\n    padding: 0 6rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsA/noNetwork/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"NoNetwork 网络异常\"\n        desc=\"用于网络断开、信号丢失等场景的友好提示，支持自定义图片和文案。\"\n        :apis=\"'noNetwork'\"\n    >\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <text class=\"no-net-tips\">请断开手机的WiFi和移动数据来查看效果</text>\n                        <u-no-network :tips=\"tips\" :image=\"image\" />\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">自定义提示语</view>\n                        <u-subsection :current=\"1\" :list=\"['是', '否']\" @change=\"tipsChange\" />\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">自定义图标</view>\n                        <u-subsection :current=\"1\" :list=\"['是', '否']\" @change=\"imageChange\" />\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\n\nlet img =\n    'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAEYCAMAAABFglBLAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6M0U3MjVFMzQwNEY1MTFFQUE4MTNDOUEzMTVBREMxQjIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6M0U3MjVFMzUwNEY1MTFFQUE4MTNDOUEzMTVBREMxQjIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDozRTcyNUUzMjA0RjUxMUVBQTgxM0M5QTMxNUFEQzFCMiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDozRTcyNUUzMzA0RjUxMUVBQTgxM0M5QTMxNUFEQzFCMiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PkHIU9QAAAMAUExURdHW2OWiou7u7tve4dnc3/vw8N3g4sPCwvjn5+jo6M7Q0u6+vtyEhPXY2Li+wuikpPXW1uXo6dba3Pbg4Na5u+qurqqyt/HJydjb3fjo6LrAxO7Bwey1td6MjOrs7fbc3OTn6Maytf7+/vz19eqqqrzCxvzz87a8wLO6vuqxsf78/PDFxenr7L/FyNTY26+2u/z09MjMzqy0udnZ2dvb27G4vMjN0O7v8P339+Ll5u3v8NDS1ODj5frt7bC3vP76+u24uOKamtTW2MTIy9zc3N7e3vPQ0OCTk8DGyfDDw9LR0c7S1LussNbY2fPOztLU1cLHyrK6vvji4vrv78bKzPX29/np6crP0vjk5Ozu78bLzuepqczR1MHFyMDEyOq1tfTS0vP09cLIy9DU173Ex8bGxvHy88/U18vO0LK4vM7OzsTKzcPJzPLMzM/T1sbMz8HJy+7FxbW8wNTW18XKzvb3+MjLzczP0d3e3+Dh4r3Dxtna29zd3rK5vdPU1cfM0Prq6uOenuPm58HGyfHz8/ro6Lq/w8nO0bzCxcrKytjZ2uXm5vTU1LvBxbW7v+rp6eefn/39/eLi4u3t7Ozs7Pj4+Pr6+vX19fHx8erq6vPz8+Xl5ff39+fn5/v7+/z8/PLx8fX09Pb29ri4uOTk5PHw8OPj4/Py8ubm5vn5+e3s7Pb19fTz8/f29tfX1+7t7cvQ0+zr6/Ly8u3t7fr5+efm5quzuOvq6vT19uvr6/j5+a61uuy6uvb39/T09Ojn5+jq6621uvn6+t/i5KyzuPn4+Le+wvv6+s3S1fj4+fDw8OHk5vv7/Pr7++Xk5LS7v7y8vObl5fz9/ff4+OTj48DEx8XJy+Hk5euysu/x8re9wfn5+v38/Pv8/Pr6++vt7uLi4+Pi4ubl5uXk5dPV1tbV1fHMzNPX2e7u7ejn6PT19fX19PDw7/b29f39/vnr6+Hh4a+3u+7t7q61uePi48PHyf35+enp6fLz9PPz8qmxtuDg4N/f3/Dv7////////1cfN/UAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAlqElEQVR42uydCXwUVZrAk5CEJBAQshACCGyjIRwBJR0It6JBGZZBkRtm5PBgFXAXHBghqAMz6LjGTrd9n7lvwn0JQhARxYNxVJTMwcwOM+7uzK6Z3VXcrnTXVr2q6q7urrvfq26c+n4egXTSVfXv993veym4JkklKdoj0IBoogHRgGiiAdGAaKIB0YBoogHRgGiiAdFEA6IBUVuwx+vqet/v1YAkhxwmcNT9gvjnsAYkGcT7eN1TtThe+1TdL2o1IEkg+rrvUV90MF9oQBIqv6ijF4a3d51XA5J4jVVXx3z587ojGpDEm/QwkO9pQJJB2CvksAYk8fJUXT31xZG63ppRTwI5QgcgR35Rd1MDkgxSX1f31P33P1V3i3u936HUyc3edWSsjuEakKRRW3r9kVv+JrRsrwbklpKTnXs+z0wfONOtAUm8rJu55oqfkZ0TOzUgCZS3Zh7s54+S5RqQhNGYMsnPISkakCSiQcjkNzUgasvUDaVsBF1fb9GXd//B0ziliPzjEA2IujLqGRaMST+cawgLNpn4q30aEDV1Va+dYRqzNy00RMoYUmdpQNTzcb8sCtuKH8w9Z4iWLuIbVzQgapmOBedDOO6c0WjgENK2vKwBUUUmvBSiUbrqxwZuOU18d5MGhEe/dI6a2WvIxA0HX1hfvH7V8gUpA9Mz3x/VuVTRLxvwdAhH5aJjBj4hv39QAxIl743ITHm6azBPnOCfVLwlc6pR3upYFbLjvIuDlEUqRYZo38JYS4gVt5rNZhMQO46byksoMeG4w8QIjtvMpJA/wP1EdZ0bKvkitkh555mBA3zSLnBlSFnNnlJvEJJ95ItW3pJAamvtZhy3m/T0g7fhthJGiG+EviYgmEJ/wHFP6GsbnlZSoicoucxmGwHVguPTBz543C9LHky/Jnql1w5KxWGo8KsThsAFYneYMOb5mlnP11ZCrwOPjfgGI8RqsZuZtUOsFmbllFhZP+zEbc8vGcqzMibv7qos3rd7Mg+TrQv2vCVkiLYc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';\n\nconst tips = ref('哎呀，网络信号丢失');\nconst image = ref<string>(img);\n\nfunction tipsChange(index: number) {\n    tips.value = index === 0 ? '人生得意须尽欢' : '哎呀，网络信号丢失';\n}\n\nfunction imageChange(index: number) {\n    image.value = index === 0 ? 'https://ik.imagekit.io/anyup/uview-pro/no-network/no_network.png' : image.value;\n}\n</script>\n\n<style scoped lang=\"scss\">\n.no-net-tips {\n    color: $u-tips-color;\n    font-size: 26rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsA/select/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"Select 选择器\"\n        desc=\"用于单列、多列独立、多列联动等多种选择场景，支持灵活数据结构和交互。\"\n        :apis=\"'select'\"\n    >\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-select\n                            @click=\"show = true\"\n                            :default-value=\"defaultValue\"\n                            :mode=\"mode\"\n                            v-model=\"show\"\n                            :list=\"list\"\n                            @confirm=\"confirm\"\n                            @cancel=\"cancel\"\n                        ></u-select>\n                        <view class=\"u-demo-result-line\">select值：{{ result }}</view>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\">参数配置</view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">状态</view>\n                        <u-subsection :current=\"current\" :list=\"['打开', '收起']\" @change=\"statusChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">模式</view>\n                        <u-subsection :list=\"['单列', '多列独立', '多列联动']\" @change=\"modeChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from 'vue';\nimport { onLoad } from '@dcloudio/uni-app';\nimport type { SelectMode } from '@/uni_modules/uview-pro/types/global';\n\nconst show = ref(false);\nconst result = ref('尚未选择');\nconst defaultValue = ref([3]);\nconst mode = ref<SelectMode>('single-column');\nconst list = ref([]);\nconst list1 = [\n    {\n        value: '江',\n        label: '江'\n    },\n    {\n        value: '湖',\n        label: '湖'\n    },\n    {\n        value: '夜',\n        label: '夜'\n    },\n    {\n        value: '雨',\n        label: '雨'\n    },\n    {\n        value: '十',\n        label: '十'\n    },\n    {\n        value: '年',\n        label: '年'\n    },\n    {\n        value: '灯',\n        label: '灯'\n    }\n];\nconst list2 = [\n    [\n        {\n            value: '昔',\n            label: '昔'\n        },\n        {\n            value: '去',\n            label: '去'\n        },\n        {\n            value: '雪',\n            label: '雪'\n        },\n        {\n            value: '如',\n            label: '如'\n        },\n        {\n            value: '花',\n            label: '花'\n        }\n    ],\n    [\n        {\n            value: '今',\n            label: '今'\n        }\n    ]\n];\nconst list3 = [\n    {\n        label: '中国',\n        value: '1',\n        children: [\n            {\n                label: '山东',\n                value: '11',\n                children: [\n                    {\n                        label: '青岛',\n                        value: '111'\n                    },\n                    {\n                        label: '济南',\n                        value: '112'\n                    },\n                    {\n                        label: '烟台',\n                        value: '113'\n                    }\n                ]\n            },\n            {\n                label: '广东',\n                value: '12',\n                children: [\n                    {\n                        label: '深圳',\n                        value: '121'\n                    },\n                    {\n                        label: '惠州',\n                        value: '122'\n                    },\n                    {\n                        label: '清远',\n                        value: '123'\n                    }\n                ]\n            }\n        ]\n    },\n    {\n        label: '美国',\n        value: '2',\n        children: [\n            {\n                label: '纽约',\n                value: '21',\n                children: [\n                    {\n                        label: '布朗克斯区',\n                        value: '211'\n                    },\n                    {\n                        label: '布鲁克林区',\n                        value: '212'\n                    },\n                    {\n                        label: '曼哈顿',\n                        value: '213'\n                    },\n                    {\n                        label: '皇后区',\n                        value: '214'\n                    },\n                    {\n                        label: '斯塔滕岛',\n                        value: '215'\n                    }\n                ]\n            }\n        ]\n    }\n];\n\nonLoad(() => {\n    list.value = list1;\n});\n\nconst current = computed(() => {\n    return show.value ? 0 : 1;\n});\n\nfunction statusChange(index: number) {\n    show.value = !index;\n}\n\nfunction modeChange(index: number) {\n    let type: SelectMode[] = ['single-column', 'mutil-column', 'mutil-column-auto'];\n    mode.value = type[index];\n    list.value = index == 0 ? list1 : index == 1 ? list2 : list3;\n    show.value = true;\n}\n\nfunction confirm(e) {\n    result.value = '';\n    e.map((val, index) => {\n        result.value += result.value == '' ? val.label : '-' + val.label;\n    });\n}\n\nfunction cancel(e) {\n    console.log(e);\n}\n</script>\n\n<style scoped lang=\"scss\">\n.badge-button {\n    padding: 4rpx 6rpx;\n    background-color: $u-type-error;\n    color: #fff;\n    border-radius: 10rpx;\n    font-size: 22rpx;\n    line-height: 1;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsA/slider/index.vue",
    "content": "<template>\n    <demo-page title=\"Slider 滑块\" desc=\"用于数值范围选择，支持自定义步进、颜色、尺寸等参数。\" :apis=\"'slider'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-slider\n                            v-model=\"value\"\n                            :step=\"step\"\n                            :height=\"height\"\n                            :block-width=\"blockWidth\"\n                            :active-color=\"activeColor\"\n                            :value=\"30\"\n                            :use-slot=\"useSlot\"\n                            :min=\"min\"\n                            :max=\"max\"\n                            :start=\"startValue\"\n                            :end=\"endValue\"\n                            :show-value=\"showValue\"\n                            @end=\"end\"\n                            @moving=\"moving\"\n                        >\n                            <!-- #ifndef MP-WEIXIN || MP-TOUTIAO -->\n                            <template v-if=\"useSlot\" #default>\n                                <view>\n                                    <view class=\"badge-button\">\n                                        {{ value }}\n                                    </view>\n                                </view>\n                            </template>\n                            <!-- #endif -->\n                        </u-slider>\n                        <view class=\"u-demo-result-line\"> 滑块值：{{ value }} </view>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\">参数配置</view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">自定义颜色</view>\n                        <u-subsection\n                            :list=\"['primary', 'warning', 'error', 'success']\"\n                            @change=\"typeChange\"\n                        ></u-subsection>\n                    </view>\n                    <!-- #ifndef MP-WEIXIN -->\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">自定义传入内容</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"slotChange\"></u-subsection>\n                    </view>\n                    <!-- #endif -->\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">自定义尺寸</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"sizeChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">步进值</view>\n                        <u-subsection :list=\"['1', '10', '20']\" @change=\"stepChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">显示滑块数字</view>\n                        <u-subsection :list=\"['否', '是']\" @change=\"showValueChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">最大最小值</view>\n                        <u-subsection :list=\"['0-100', '40-80']\" @change=\"minMaxChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">滑块起始结束值</view>\n                        <u-subsection :list=\"['0-100', '40-80']\" @change=\"edgeValueChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { $u } from '@/uni_modules/uview-pro';\nimport { ref } from 'vue';\nimport { completeMission } from '../../../common/useExperience';\n\nconst value = ref(30);\nconst useSlot = ref(false);\nconst step = ref<string | number>(1);\nconst activeColor = ref($u.color.primary);\nconst height = ref(6);\nconst blockWidth = ref(30);\nconst min = ref(0);\nconst max = ref(100);\nconst startValue = ref(0);\nconst endValue = ref(100);\nconst showValue = ref(false);\n\nfunction typeChange(index: number) {\n    let type = ['primary', 'warning', 'error', 'success'];\n    activeColor.value = $u.color[type[index]];\n}\n\nfunction sizeChange(index: number) {\n    if (index === 0) {\n        height.value = 4;\n        blockWidth.value = 30;\n    } else {\n        height.value = 6;\n        blockWidth.value = 20;\n    }\n}\n\nfunction stepChange(index: number) {\n    let arr = ['1', '10', '20'];\n    step.value = arr[index];\n}\n\nfunction slotChange(index: number) {\n    useSlot.value = !index;\n}\n\nfunction showValueChange(index: number) {\n    if (index === 0) {\n        // 不显示\n        showValue.value = false;\n    } else {\n        // 显示\n        showValue.value = true;\n    }\n}\n\nfunction minMaxChange(index: number) {\n    if (index === 0) {\n        min.value = 0;\n        max.value = 100;\n    } else {\n        min.value = 40;\n        max.value = 80;\n    }\n}\n\nfunction edgeValueChange(index: number) {\n    if (index === 0) {\n        startValue.value = 0;\n        endValue.value = 100;\n    } else {\n        startValue.value = 40;\n        endValue.value = 80;\n    }\n}\n\nfunction end() {\n    console.log('end');\n    completeMission('slider-move');\n}\n\nfunction moving() {\n    console.log('moving');\n}\n</script>\n\n<style scoped lang=\"scss\">\n.badge-button {\n    padding: 4rpx 6rpx;\n    background-color: $u-type-error;\n    color: #fff;\n    border-radius: 10rpx;\n    font-size: 22rpx;\n    line-height: 1;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsA/tabs/index.vue",
    "content": "<template>\n    <demo-page title=\"Tabs 标签页\" desc=\"用于多内容区域切换展示，支持滚动、自定义颜色、字体加粗等。\" :apis=\"'tabs'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-tabs\n                            v-if=\"control\"\n                            :bg-color=\"$u.color.bgColor\"\n                            :bold=\"bold\"\n                            :active-color=\"activeColor\"\n                            :list=\"list\"\n                            :current=\"current\"\n                            :is-scroll=\"isScroll\"\n                            :offset=\"offset\"\n                            :is-dot=\"isDot\"\n                            @change=\"change\"\n                        ></u-tabs>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">模式选择</view>\n                        <u-subsection\n                            :current=\"sectionCurrent\"\n                            :list=\"['滚动', '非滚动']\"\n                            @change=\"modeChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">标签个数(非滚动模式)</view>\n                        <u-subsection :list=\"['2', '3', '4']\" @change=\"countChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">活动选项字颜色</view>\n                        <u-subsection\n                            mode=\"button\"\n                            :list=\"['primary', 'success', 'error', 'warning']\"\n                            @change=\"colorChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">字体加粗</view>\n                        <u-subsection mode=\"button\" :list=\"['是', '否']\" @change=\"boldChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">徽标是否为圆点</view>\n                        <u-subsection mode=\"button\" :list=\"['否', '是']\" @change=\"isDotChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { $u } from '@/uni_modules/uview-pro';\nimport { onLoad } from '@dcloudio/uni-app';\nimport { ref, watch } from 'vue';\nimport { completeMission } from '@/common/useExperience';\n\nconst list = ref([]);\nconst data = ref([\n    { name: '关注', count: 100 },\n    { name: '推荐', count: 7 },\n    { name: '电影' },\n    { name: '电视剧' },\n    { name: '小视频' },\n    { name: '游戏' },\n    { name: '校园' },\n    { name: '影视' },\n    { name: '音乐' }\n]);\nconst current = ref(0);\nconst sectionCurrent = ref(0);\nconst isScroll = ref(true);\nconst tabCountIndex = ref(0);\nconst activeColor = ref($u.color['primary']);\nconst bold = ref(true);\nconst control = ref(true);\nconst offset = ref<[number, number]>([5, 0]);\nconst isDot = ref(false);\n\nonLoad(() => {\n    list.value = data.value;\n});\n\nfunction countChange(index: number) {\n    switch (index) {\n        case 0:\n            list.value = [];\n            list.value.push(data.value[0]);\n            list.value.push(data.value[1]);\n            offset.value = [5, 60];\n            break;\n        case 1:\n            list.value = [];\n            list.value.push(data.value[0]);\n            list.value.push(data.value[1]);\n            list.value.push(data.value[2]);\n            offset.value = [5, 20];\n            break;\n        case 2:\n            list.value = [];\n            list.value.push(data.value[0]);\n            list.value.push(data.value[1]);\n            list.value.push(data.value[2]);\n            list.value.push(data.value[3]);\n            offset.value = [5, 5];\n            break;\n    }\n    tabCountIndex.value = index;\n    isScroll.value = false;\n}\n\nfunction change(index: number) {\n    current.value = index;\n    completeMission('tabs');\n}\n\nfunction modeChange(index: number) {\n    control.value = false;\n    current.value = 0;\n    switch (index) {\n        case 0:\n            isScroll.value = true;\n            list.value = data.value;\n            offset.value = [5, 0];\n            break;\n        case 1:\n            isScroll.value = false;\n            countChange(tabCountIndex.value);\n            break;\n    }\n    control.value = true;\n}\n\nfunction colorChange(index: number) {\n    let color = 'primary';\n    switch (index) {\n        case 0:\n            color = 'primary';\n            break;\n        case 1:\n            color = 'success';\n            break;\n        case 2:\n            color = 'error';\n            break;\n        case 3:\n            color = 'warning';\n            break;\n    }\n    activeColor.value = $u.color[color];\n}\n\nfunction boldChange(index: number) {\n    switch (index) {\n        case 0:\n            bold.value = true;\n            break;\n        case 1:\n            bold.value = false;\n            break;\n    }\n}\n\nfunction isDotChange(index: number) {\n    switch (index) {\n        case 0:\n            isDot.value = false;\n            break;\n        case 1:\n            isDot.value = true;\n            break;\n    }\n}\n</script>\n"
  },
  {
    "path": "src/pages/componentsA/tag/index.vue",
    "content": "<template>\n    <demo-page title=\"Tag 标签\" desc=\"该组件一般用于标记和选择\" :apis=\"'tag'\">\n        <view class=\"u-demo\">\n            <view class=\"u-demo-wrap\">\n                <view class=\"u-demo-title\">演示效果</view>\n                <view class=\"u-demo-area\">\n                    <u-toast ref=\"uToastRef\"></u-toast>\n                    <u-tag\n                        :text=\"text\"\n                        :type=\"type\"\n                        :shape=\"shape\"\n                        :closeable=\"closeable\"\n                        :mode=\"mode\"\n                        @close=\"close\"\n                        @click=\"click\"\n                        :show=\"show\"\n                        :size=\"size\"\n                    />\n                </view>\n            </view>\n            <view class=\"u-config-wrap\">\n                <view class=\"u-config-title u-border-bottom\">参数配置</view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">模式选择</view>\n                    <u-subsection :list=\"['light', 'dark', 'plain']\" @change=\"modeChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">显示内容</view>\n                    <u-subsection :list=\"['蒹葭苍苍', '白露为霜', '在水一方']\" @change=\"textChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">主题选择</view>\n                    <u-subsection\n                        current=\"2\"\n                        :list=\"['primary', 'success', 'error', 'warning', 'info']\"\n                        @change=\"typeChange\"\n                    ></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">形状</view>\n                    <u-subsection\n                        :list=\"['square', 'circle', 'circleLeft', 'circleRight']\"\n                        @change=\"shapeChange\"\n                    ></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">尺寸</view>\n                    <u-subsection :list=\"['default', 'mini']\" @change=\"sizeChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">关闭图标</view>\n                    <u-subsection :list=\"['是', '否']\" @change=\"closeableChange\"></u-subsection>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport type { TagMode, TagShape, TagSize, ThemeType } from '@/uni_modules/uview-pro/types/global';\n\nconst text = ref('蒹葭苍苍');\nconst mode = ref<TagMode>('light');\nconst type = ref<ThemeType>('error');\nconst size = ref<TagSize>('default');\nconst shape = ref<TagShape>('square');\nconst closeable = ref(true);\nconst show = ref(true);\n\nconst uToastRef = ref(null);\n\nfunction modeChange(index: number) {\n    mode.value = index === 0 ? 'light' : index === 1 ? 'dark' : 'plain';\n}\n\nfunction textChange(index: number) {\n    text.value = index === 0 ? '蒹葭苍苍' : index === 1 ? '白露为霜' : '在水一方';\n}\n\nfunction typeChange(index: number) {\n    type.value =\n        index === 0 ? 'primary' : index === 1 ? 'success' : index === 2 ? 'error' : index === 3 ? 'warning' : 'info';\n}\n\nfunction shapeChange(index: number) {\n    shape.value = index === 0 ? 'square' : index === 1 ? 'circle' : index === 2 ? 'circleLeft' : 'circleRight';\n}\n\nfunction sizeChange(index: number) {\n    size.value = index === 0 ? 'default' : 'mini';\n}\n\nfunction closeableChange(index: number) {\n    closeable.value = index === 0;\n}\n\nfunction click(index: number) {\n    uToastRef.value.show({\n        title: `第${index + 1}个标签被点击`,\n        type: 'success'\n    });\n}\n\nfunction close() {\n    uToastRef.value.show({\n        title: `关闭图标被点击`,\n        type: 'success'\n    });\n}\n</script>\n"
  },
  {
    "path": "src/pages/componentsA/test/index.vue",
    "content": "<template>\n    <demo-page title=\"Test 表单校验\" desc=\"用于测试表单组件的综合使用，包括输入、选择、单选、复选等。\" :apis=\"'test'\">\n        <template #default>\n            <u-form :model=\"form\" ref=\"uForm\">\n                <u-form-item label=\"姓名\">\n                    <u-input v-model=\"form.name\" />\n                </u-form-item>\n                <u-form-item label=\"简介\">\n                    <u-input v-model=\"form.intro\" />\n                </u-form-item>\n                <u-form-item label=\"性别\">\n                    <u-input v-model=\"form.sex\" type=\"select\" />\n                </u-form-item>\n                <u-form-item label=\"水果\">\n                    <u-checkbox-group>\n                        <u-checkbox\n                            v-model=\"item.checked\"\n                            v-for=\"(item, index) in checkboxList\"\n                            :key=\"index\"\n                            :name=\"item.name\"\n                        >\n                            {{ item.name }}\n                        </u-checkbox>\n                    </u-checkbox-group>\n                </u-form-item>\n                <u-form-item label=\"味道\">\n                    <u-radio-group v-model=\"radio\">\n                        <u-radio\n                            v-for=\"(item, index) in radioList\"\n                            :key=\"index\"\n                            :name=\"item.name\"\n                            :disabled=\"item.disabled\"\n                        >\n                            {{ item.name }}\n                        </u-radio>\n                    </u-radio-group>\n                </u-form-item>\n                <u-form-item label=\"开关\">\n                    <template #right>\n                        <u-switch v-model=\"switchVal\"></u-switch>\n                    </template>\n                </u-form-item>\n            </u-form>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\n\nconst form = ref({\n    name: '',\n    intro: '',\n    sex: ''\n});\n\nconst checkboxList = ref([\n    {\n        name: '苹果',\n        checked: false,\n        disabled: false\n    },\n    {\n        name: '雪梨',\n        checked: false,\n        disabled: false\n    },\n    {\n        name: '柠檬',\n        checked: false,\n        disabled: false\n    }\n]);\n\nconst radioList = ref([\n    {\n        name: '鲜甜',\n        disabled: false\n    },\n    {\n        name: '麻辣',\n        disabled: false\n    }\n]);\n\nconst radio = ref('');\nconst switchVal = ref(false);\n</script>\n"
  },
  {
    "path": "src/pages/componentsA/textarea/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"Textarea 多行文本\"\n        desc=\"用于多行文本输入，支持字数统计、自动增高、禁用等功能。\"\n        :apis=\"'Textarea'\"\n    >\n        <template #default>\n            <view class=\"u-page\">\n                <view class=\"u-demo-block\">\n                    <text class=\"u-demo-block__title\">基础使用</text>\n                    <view class=\"u-demo-block__content\">\n                        <u-textarea v-model=\"value1\" placeholder=\"请输入内容\"></u-textarea>\n                    </view>\n                </view>\n                <view class=\"u-demo-block\">\n                    <text class=\"u-demo-block__title\">输入框大小</text>\n                    <view class=\"u-demo-block__content\">\n                        <u-textarea v-model=\"value0\" placeholder=\"小输入框\" size=\"small\" count></u-textarea>\n                        <u-gap />\n                        <u-textarea v-model=\"value0\" placeholder=\"中等输入框\" size=\"default\" count></u-textarea>\n                        <u-gap />\n                        <u-textarea v-model=\"value0\" placeholder=\"大输入框\" size=\"large\" count></u-textarea>\n                        <u-gap />\n                        <u-textarea\n                            v-model=\"value0\"\n                            placeholder=\"输入框字体40rpx，高度300rpx\"\n                            size=\"40\"\n                            height=\"300\"\n                            count\n                        ></u-textarea>\n                    </view>\n                </view>\n                <view class=\"u-demo-block\">\n                    <text class=\"u-demo-block__title\">字数统计</text>\n                    <view class=\"u-demo-block__content\">\n                        <u-textarea v-model=\"value2\" placeholder=\"请输入内容\" count></u-textarea>\n                    </view>\n                </view>\n                <view class=\"u-demo-block\">\n                    <text class=\"u-demo-block__title\">自动增高</text>\n                    <view class=\"u-demo-block__content\">\n                        <u-textarea v-model=\"value3\" placeholder=\"请输入内容\" count autoHeight></u-textarea>\n                    </view>\n                </view>\n                <view class=\"u-demo-block\">\n                    <text class=\"u-demo-block__title\">禁用状态</text>\n                    <view class=\"u-demo-block__content\">\n                        <u-textarea v-model=\"value4\" placeholder=\"文本域已被禁用\" disabled count></u-textarea>\n                    </view>\n                </view>\n                <view class=\"u-demo-block\">\n                    <text class=\"u-demo-block__title\">下划线模式</text>\n                    <view class=\"u-demo-block__content\">\n                        <u-textarea v-model=\"value5\" placeholder=\"请输入内容\" border=\"bottom\"></u-textarea>\n                    </view>\n                </view>\n                <view class=\"u-demo-block\">\n                    <text class=\"u-demo-block__title\">无边框</text>\n                    <view class=\"u-demo-block__content\">\n                        <u-textarea v-model=\"value5\" placeholder=\"请输入内容\" border=\"none\"></u-textarea>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\n\n// 页面示例中的 v-model 数据\nconst value0 = ref<string>('');\nconst value1 = ref<string>('');\nconst value2 = ref<string>('统计字数');\nconst value3 = ref<string>('');\nconst value4 = ref<string>('');\nconst value5 = ref<string>('');\n\n// 保留原示例中的 formatter 方法（若需传入组件，可通过 ref/prop 传递）\nfunction formatter(value: string) {\n    return value.replace(/[^0-9]/gi, '');\n}\n</script>\n\n<style lang=\"scss\"></style>\n"
  },
  {
    "path": "src/pages/componentsA/timeLine/index.vue",
    "content": "<template>\n    <demo-page title=\"TimeLine 时间线\" desc=\"用于展示时间流、订单物流等场景，支持自定义节点和样式。\" :apis=\"'timeLine'\">\n        <template #default>\n            <view class=\"wrap\">\n                <u-time-line>\n                    <u-time-line-item nodeTop=\"2\">\n                        <template v-slot:node>\n                            <view class=\"u-node\" style=\"background: #19be6b\">\n                                <u-icon name=\"pushpin-fill\" color=\"#fff\" :size=\"24\"></u-icon>\n                            </view>\n                        </template>\n                        <template v-slot:content>\n                            <view>\n                                <view class=\"u-order-title\">待取件</view>\n                                <view class=\"u-order-desc\">\n                                    [自提柜]您的快件已放在楼下侧门，直走前方53.6米，左拐约10步，再右拐直走，见一红灯笼停下，叩门三下，喊“芝麻开门”即可。\n                                </view>\n                                <view class=\"u-order-time\">2019-05-08 12:12</view>\n                            </view>\n                        </template>\n                    </u-time-line-item>\n                    <u-time-line-item nodeTop=\"2\">\n                        <template v-slot:node>\n                            <view class=\"u-node\">\n                                <u-icon name=\"account-fill\" color=\"#fff\" :size=\"24\"></u-icon>\n                            </view>\n                        </template>\n                        <template v-slot:content>\n                            <view>\n                                <view class=\"u-order-title unacive\">派送中</view>\n                                <view class=\"u-order-desc\">\n                                    【深圳市】快件已到达目的地，派件员为国产锦衣卫007号，电话：\n                                    <text class=\"tel\"> 13833882438 </text>，请留意快递信息\n                                </view>\n                                <view class=\"u-order-time\">2019-05-08 06:03</view>\n                            </view>\n                        </template>\n                    </u-time-line-item>\n                    <u-time-line-item nodeTop=\"2\">\n                        <template v-slot:node>\n                            <view class=\"u-node\">\n                                <u-icon name=\"car-fill\" color=\"#fff\" :size=\"24\"></u-icon>\n                            </view>\n                        </template>\n                        <template v-slot:content>\n                            <view>\n                                <view class=\"u-order-title unacive\">运输中</view>\n                                <view class=\"u-order-desc\">【深圳市】快递已到达 深圳固戍一部</view>\n                                <view class=\"u-order-time\">2019-05-07 08:05</view>\n                            </view>\n                        </template>\n                    </u-time-line-item>\n                    <u-time-line-item>\n                        <template v-slot:content>\n                            <view>\n                                <view class=\"u-order-desc\"\n                                    >【深圳市】快件已从深圳运转中心发出，正在发往深圳宝安一部</view\n                                >\n                                <view class=\"u-order-time\">2019-12-06 22:30</view>\n                            </view>\n                        </template>\n                    </u-time-line-item>\n                    <u-time-line-item>\n                        <template v-slot:content>\n                            <view>\n                                <view class=\"u-order-desc\">【深圳市】快件已到达 深圳运转中心</view>\n                                <view class=\"u-order-time\">2019-12-04 16:42</view>\n                            </view>\n                        </template>\n                    </u-time-line-item>\n                    <u-time-line-item>\n                        <template v-slot:content>\n                            <view>\n                                <view class=\"u-order-desc\"\n                                    >【郑州市】快件已从郑州运转中心出发，正在发往深圳运转中心</view\n                                >\n                                <view class=\"u-order-time\">2019-12-02 12:55</view>\n                            </view>\n                        </template>\n                    </u-time-line-item>\n                    <u-time-line-item>\n                        <template v-slot:content>\n                            <view>\n                                <view class=\"u-order-desc\">【郑州市】快件已到达 郑州运转中心</view>\n                                <view class=\"u-order-time\">2019-12-02 08:23</view>\n                            </view>\n                        </template>\n                    </u-time-line-item>\n                    <u-time-line-item nodeTop=\"0\">\n                        <template v-slot:node>\n                            <view class=\"u-node\">\n                                <u-icon name=\"file-text-fill\" color=\"#fff\" :size=\"24\"></u-icon>\n                            </view>\n                        </template>\n                        <template v-slot:content>\n                            <view>\n                                <view class=\"u-order-desc\">\n                                    您购买的商品【尚方宝剑，先斩后奏】，经由北京军区仓库发货，国内快递承运人【中南海保镖】。\n                                </view>\n                                <view class=\"u-order-time\">2019-12-01 07:00</view>\n                            </view>\n                        </template>\n                    </u-time-line-item>\n                </u-time-line>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<style lang=\"scss\" scoped>\n.wrap {\n    padding: 24rpx 24rpx 24rpx 40rpx;\n}\n\n.u-node {\n    width: 44rpx;\n    height: 44rpx;\n    border-radius: 100rpx;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    background: #d0d0d0;\n}\n\n.u-order-title {\n    color: #333333;\n    font-weight: bold;\n    font-size: 32rpx;\n}\n\n.u-order-title.unacive {\n    color: rgb(150, 150, 150);\n}\n\n.u-order-desc {\n    color: rgb(150, 150, 150);\n    font-size: 28rpx;\n    margin-bottom: 6rpx;\n}\n\n.u-order-time {\n    color: rgb(200, 200, 200);\n    font-size: 26rpx;\n}\n\n.tel {\n    color: $u-type-primary;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsA/toast/index.vue",
    "content": "<template>\n    <demo-page title=\"Toast 提示框\" desc=\"用于显示轻提示信息，支持多种主题、位置和自动跳转。\" :apis=\"'toast'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-toast :type=\"type\" ref=\"uToastRef\"></u-toast>\n                        <text class=\"no-mode-here\">弹出toast</text>\n                        <u-gap></u-gap>\n                        <u-button type=\"primary\" @click=\"showGlobalToast\">使用useToast弹出</u-button>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">主题</view>\n                        <u-subsection\n                            :current=\"4\"\n                            :list=\"['primary', 'success', 'error', 'warning', 'default']\"\n                            @change=\"typeChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">结束后自动跳转</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"urlChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">位置</view>\n                        <u-subsection\n                            current=\"1\"\n                            :list=\"['顶部', '中部', '底部']\"\n                            @change=\"positionChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">显示图标</view>\n                        <u-subsection :list=\"['是', '否']\" @change=\"iconChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { useToast } from 'uview-pro';\nimport { ref } from 'vue';\n\n/**\n * 演示 u-toast 组件的使用\n * 包含主题、跳转、位置、图标等参数演示\n */\n// 主题类型\nconst type = ref<'primary' | 'success' | 'error' | 'warning' | 'default'>('success');\n// 显示内容\nconst title = ref('桃花潭水深千尺');\n// 是否显示图标\nconst icon = ref(true);\n// 位置\nconst position = ref<'top' | 'center' | 'bottom'>('center');\n// 跳转url\nconst url = ref('');\n\n// toast 组件ref\nconst uToastRef = ref();\nconst toast = useToast();\n\nfunction showGlobalToast() {\n    toast.loading({\n        title: '加载中...',\n        type: 'primary',\n        duration: 2000,\n        callback: () => {\n            toast.success('加载完成');\n        }\n    });\n}\n\n/**\n * 主题切换\n * @param index 主题下标\n */\nfunction typeChange(index: number) {\n    type.value =\n        index == 0 ? 'primary' : index == 1 ? 'success' : index == 2 ? 'error' : index == 3 ? 'warning' : 'default';\n    show();\n}\n/**\n * 位置切换\n * @param index 位置下标\n */\nfunction positionChange(index: number) {\n    position.value = index == 0 ? 'top' : index == 1 ? 'center' : 'bottom';\n    show();\n}\n/**\n * 图标切换\n * @param index 图标下标\n */\nfunction iconChange(index: number) {\n    icon.value = index == 0 ? true : false;\n    show();\n}\n/**\n * 跳转切换\n * @param index 跳转下标\n */\nfunction urlChange(index: number) {\n    url.value = index == 0 ? '/pages/componentsC/button/index' : '';\n    show('结束后跳转到Button页面');\n}\n/**\n * 显示toast\n */\nfunction show(value?: string) {\n    uToastRef.value?.show?.({\n        title: value || title.value,\n        position: position.value,\n        type: type.value,\n        icon: icon.value,\n        url: url.value\n    });\n}\n/**\n * 隐藏toast\n */\nfunction hide() {\n    uToastRef.value?.hide?.();\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.no-mode-here {\n    color: $u-tips-color;\n    font-size: 28rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsA/topTips/index.vue",
    "content": "<template>\n    <demo-page title=\"TopTips 顶部提示\" desc=\"用于页面顶部消息提示，支持多种主题和自定义时长。\" :apis=\"'topTips'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-top-tips ref=\"uTipsRef\" :navbar-height=\"navbarHeight\" :z-index=\"999\"></u-top-tips>\n                        <text class=\"u-no-demo-here\">点击参数配置查看效果</text>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">主题选择</view>\n                        <u-subsection\n                            :list=\"['primary', 'success', 'error', 'warning', 'info']\"\n                            @change=\"typeChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">显示时间</view>\n                        <u-subsection current=\"1\" :list=\"['长', '正常', '短']\" @change=\"durationChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from 'vue';\nimport type { ThemeType } from '@/uni_modules/uview-pro/types/global';\n\nconst navbarHeight = computed(() => {\n    return uni.getSystemInfoSync().statusBarHeight + 44;\n});\n\nconst duration = ref(2000);\nconst title = ref('忽如一夜春风来，千树万树梨花开');\nconst type = ref<ThemeType>('primary');\n\nconst uTipsRef = ref(null);\n\nfunction typeChange(index: number) {\n    type.value =\n        index === 0 ? 'primary' : index == 1 ? 'success' : index == 2 ? 'error' : index == 3 ? 'warning' : 'info';\n    showTips();\n}\n\nfunction durationChange(index: number) {\n    duration.value = index === 0 ? 4000 : index == 1 ? 2000 : 500;\n    showTips();\n}\n\nfunction showTips() {\n    uTipsRef.value.show({\n        duration: duration.value,\n        title: title.value,\n        type: type.value\n    });\n}\n</script>\n"
  },
  {
    "path": "src/pages/componentsA/verificationCode/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"VerificationCode 验证码\"\n        desc=\"用于发送和倒计时验证码，支持自定义时长和文案。\"\n        :apis=\"'verificationCode'\"\n    >\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-toast ref=\"uToastRef\"></u-toast>\n                        <u-verification-code\n                            :keep-running=\"true\"\n                            :seconds=\"seconds\"\n                            @end=\"end\"\n                            @start=\"start\"\n                            ref=\"uCodeRef\"\n                            @change=\"codeChange\"\n                            :startText=\"startText\"\n                            :changeText=\"changeText\"\n                            :endText=\"endText\"\n                        ></u-verification-code>\n                        <u-button @click=\"getCode\">{{ tips }}</u-button>\n                        <u-button :custom-style=\"{ marginTop: '30rpx' }\" @tap=\"reset\" style=\"margin-top: 30rpx\"\n                            >重置</u-button\n                        >\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">倒计时间</view>\n                        <u-subsection :current=\"0\" :list=\"['60s', '10s', '5s']\" @change=\"secondsChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">自定义提示语</view>\n                        <u-subsection :current=\"1\" :list=\"['是', '否']\" @change=\"textChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\n\nconst tips = ref('');\nconst seconds = ref(60);\nconst startText = ref('获取验证码');\nconst changeText = ref('X秒重新获取');\nconst endText = ref('重新获取');\n\nconst uToastRef = ref(null);\nconst uCodeRef = ref(null);\n\nfunction codeChange(text: string) {\n    tips.value = text;\n}\n\nfunction getCode() {\n    if (uCodeRef.value.canGetCode) {\n        // 模拟向后端请求验证码\n        uni.showLoading({\n            title: '正在获取验证码'\n        });\n        setTimeout(() => {\n            uni.hideLoading();\n            // 这里此提示会被this.start()方法中的提示覆盖\n            uToastRef.value.show({\n                title: '验证码已发送',\n                type: 'success'\n            });\n            // 通知验证码组件内部开始倒计时\n            uCodeRef.value.start();\n        });\n    } else {\n        uToastRef.value.show({\n            title: '倒计时结束后再发送',\n            type: 'error'\n        });\n    }\n}\n\nfunction secondsChange(index: number) {\n    seconds.value = index == 0 ? 60 : index == 1 ? 10 : 5;\n}\n\nfunction textChange(index: number) {\n    console.log(index, 'index');\n    if (index === 0) {\n        startText.value = '点一下获取';\n        changeText.value = '重新获取Xs';\n        endText.value = '再次获取';\n    } else {\n        startText.value = '获取验证码';\n        changeText.value = 'X秒重新获取';\n        endText.value = '重新获取';\n    }\n}\n\nfunction start() {\n    uToastRef.value.show({\n        title: '倒计时开始',\n        type: 'success'\n    });\n}\n\nfunction end() {\n    uToastRef.value.show({\n        title: '倒计时结束',\n        type: 'success'\n    });\n}\n\nfunction reset() {\n    uCodeRef.value.reset();\n}\n</script>\n"
  },
  {
    "path": "src/pages/componentsB/card/index.vue",
    "content": "<template>\n    <demo-page title=\"Card 卡片\" desc=\"用于展示卡片组件，支持阴影、边框和自定义样式。\" :apis=\"'card'\">\n        <template #default>\n            <view>\n                <view class=\"u-card-wrap\">\n                    <u-card\n                        @click=\"click\"\n                        @head-click=\"headClick\"\n                        :title=\"title\"\n                        :sub-title=\"subTitle\"\n                        :thumb=\"thumb\"\n                        :padding=\"padding\"\n                        :border=\"border\"\n                        :border-radius=\"borderRadius\"\n                    >\n                        <template #body>\n                            <view class=\"u-body-item u-flex u-border-bottom u-col-between u-p-t-0\">\n                                <view class=\"u-body-item-title u-line-2\">\n                                    瓶身描绘的牡丹一如你初妆，冉冉檀香透过窗心事我了然，宣纸上走笔至此搁一半\n                                </view>\n                                <image\n                                    src=\"https://img11.360buyimg.com/n7/jfs/t1/94448/29/2734/524808/5dd4cc16E990dfb6b/59c256f85a8c3757.jpg\"\n                                    mode=\"aspectFill\"\n                                ></image>\n                            </view>\n                            <view class=\"u-body-item u-flex u-row-between u-p-b-0\">\n                                <view class=\"u-body-item-title u-line-2\">\n                                    釉色渲染仕女图韵味被私藏，而你嫣然的一笑如含苞待放\n                                </view>\n                                <image\n                                    src=\"https://img12.360buyimg.com/n7/jfs/t1/102191/19/9072/330688/5e0af7cfE17698872/c91c00d713bf729a.jpg\"\n                                    mode=\"aspectFill\"\n                                ></image>\n                            </view>\n                        </template>\n                        <template #foot>\n                            <u-icon v-if=\"bottomSlot\" name=\"chat-fill\" size=\"34\" label=\"30评论\"></u-icon>\n                        </template>\n                    </u-card>\n                </view>\n                <view class=\"u-config-wrap u-demo\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">左上角图标</view>\n                        <u-subsection :list=\"['显示', '隐藏']\" @change=\"thumbChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">内边距</view>\n                        <u-subsection current=\"1\" :list=\"['20', '30', '40']\" @change=\"paddingChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">底部</view>\n                        <u-subsection :list=\"['显示', '隐藏']\" @change=\"bottomChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">外边框</view>\n                        <u-subsection :current=\"1\" :list=\"['显示', '隐藏']\" @change=\"borderChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">圆角</view>\n                        <u-subsection\n                            :current=\"1\"\n                            :list=\"['0', '16', '30']\"\n                            @change=\"borderRadiusChange\"\n                        ></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\n\nconst title = ref('素胚勾勒出青花，笔锋浓转淡');\nconst subTitle = ref('2020-05-15');\nconst thumb = ref('https://ik.imagekit.io/anyup/uview-pro/common/logo-new.png');\nconst padding = ref(20);\nconst bottomSlot = ref(true);\nconst border = ref(false);\nconst borderRadius = ref(16);\n\nfunction thumbChange(index: number) {\n    thumb.value = index === 0 ? 'https://ik.imagekit.io/anyup/uview-pro/common/logo-new.png' : '';\n}\n\nfunction paddingChange(index: number) {\n    padding.value = [20, 30, 40][index];\n}\n\nfunction bottomChange(index: number) {\n    bottomSlot.value = !index;\n}\n\nfunction borderChange(index: number) {\n    border.value = !index;\n}\n\nfunction borderRadiusChange(index: number) {\n    borderRadius.value = [0, 16, 30][index];\n}\n\nfunction click(index: number) {\n    console.log(index);\n}\n\nfunction headClick(index: number) {\n    console.log(index);\n}\n</script>\n\n<style scoped lang=\"scss\">\n.u-demo {\n    padding-top: 0;\n}\n\n.u-card-wrap {\n    background-color: $u-bg-color;\n    padding: 1px;\n}\n\n.u-body-item {\n    font-size: 32rpx;\n    color: #333;\n    padding: 20rpx 10rpx;\n}\n\n.u-body-item image {\n    width: 120rpx;\n    flex: 0 0 120rpx;\n    height: 120rpx;\n    border-radius: 8rpx;\n    margin-left: 12rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsB/checkbox/index.vue",
    "content": "<template>\n    <demo-page title=\"Checkbox 复选框\" desc=\"用于选择一个或者多个选项。\" :apis=\"'checkbox'\">\n        <view class=\"u-demo\">\n            <view class=\"u-demo-wrap\">\n                <view class=\"u-demo-title\">演示效果</view>\n                <view class=\"u-demo-area u-flex-col u-col-center\">\n                    <view>\n                        <u-checkbox-group\n                            v-model=\"checkboxValues\"\n                            :size=\"size\"\n                            :width=\"width\"\n                            :wrap=\"wrap\"\n                            :max=\"max\"\n                            :activeColor=\"activeColor\"\n                            @change=\"checkboxGroupChange\"\n                        >\n                            <u-checkbox\n                                v-for=\"(item, index) in list\"\n                                :key=\"index\"\n                                :label=\"item.label\"\n                                :value=\"item.value\"\n                                :shape=\"shape\"\n                                :disabled=\"item.disabled\"\n                                @change=\"checkboxChange\"\n                            >\n                            </u-checkbox>\n                        </u-checkbox-group>\n                    </view>\n                    <view class=\"u-demo-result-line\">\n                        {{ checkboxValues.length ? `选中了\"${checkboxValues.join(',')}\"` : '请选择' }}\n                    </view>\n                </view>\n            </view>\n            <view class=\"u-config-wrap\">\n                <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">批量操作</view>\n                    <u-subsection :list=\"['全不选', '全选']\" @change=\"checkedAllChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">形状</view>\n                    <u-subsection :list=\"['方形', '圆形']\" @change=\"shapeChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">整体大小(单位rpx)</view>\n                    <u-subsection current=\"1\" :list=\"['小', '中', '大', '60']\" @change=\"sizeChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">激活颜色</view>\n                    <u-subsection\n                        :list=\"['primary', 'error', 'warning', 'success', 'info']\"\n                        @change=\"activeColorChange\"\n                    ></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">默认选中第一个</view>\n                    <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"defaultChooseChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">每个占一行</view>\n                    <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"wrapChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">每个宽度50%</view>\n                    <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"widthChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">最大选择数量</view>\n                    <u-subsection current=\"2\" :list=\"['1', '2', '3']\" @change=\"maxChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">禁用第一个</view>\n                    <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"disabledChange\"></u-subsection>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport type { Shape, SizeType } from '@/uni_modules/uview-pro/types/global';\nimport { $u } from '@/uni_modules/uview-pro';\n\nconst checkboxValues = ref(['荔枝']);\n\nconst list = ref([\n    {\n        label: '荔枝',\n        value: '荔枝',\n        disabled: false\n    },\n    {\n        label: '香蕉',\n        value: '香蕉',\n        disabled: false\n    },\n    {\n        label: '橙子',\n        value: '橙子',\n        disabled: false\n    },\n    {\n        label: '草莓',\n        value: '草莓',\n        disabled: false\n    }\n]);\nconst shape = ref<Shape>('square');\nconst max = ref(3);\nconst activeColor = ref('primary');\nconst size = ref<SizeType | string | number>('default');\nconst wrap = ref(false);\nconst width = ref('auto');\n\nfunction shapeChange(index: number) {\n    shape.value = index === 0 ? 'square' : 'circle';\n}\n\nfunction sizeChange(index: number) {\n    if (index > 2) {\n        size.value = 60;\n    } else {\n        size.value = index === 0 ? 'small' : index === 1 ? 'default' : 'large';\n    }\n}\n\n// 全选/全不选\nfunction checkedAllChange(index: number) {\n    checkboxValues.value = index === 1 ? list.value.map(item => item.value) : [];\n}\n\nfunction defaultChooseChange(index: number) {\n    checkboxValues.value = index === 0 ? ['荔枝'] : [];\n}\n\nfunction maxChange(index: number) {\n    max.value = index + 1;\n}\n\nfunction disabledChange(index: number) {\n    list.value[0].disabled = index === 0;\n}\n\nfunction activeColorChange(index: number) {\n    console.log(index, index);\n    // 如果用户尚未勾选任何checkbox，切换颜色时，默认选中第一个让用户看到效果，因为勾选了才有效果\n    if (!checkboxValues.value.length) checkboxValues.value = ['荔枝'];\n    let theme =\n        index === 0 ? 'primary' : index === 1 ? 'error' : index === 2 ? 'warning' : index === 3 ? 'success' : 'info';\n    activeColor.value = $u.color[theme];\n}\n\nfunction checkboxChange(e) {\n    console.log('checkboxChange', e);\n}\n\nfunction checkboxGroupChange(e) {\n    console.log('checkboxGroupChange', e);\n}\n\nfunction widthChange(index: number) {\n    width.value = index === 0 ? '50%' : '';\n}\n\nfunction wrapChange(index: number) {\n    wrap.value = !index;\n}\n</script>\n"
  },
  {
    "path": "src/pages/componentsB/divider/index.vue",
    "content": "<template>\n    <demo-page title=\"Divider 分割线\" desc=\"用于分割不同内容区域，支持自定义颜色、宽度、边距等样式。\" :apis=\"'divider'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-divider\n                            :type=\"type\"\n                            :borderColor=\"borderColor\"\n                            :bg-color=\"bgColor\"\n                            @click=\"click\"\n                            :half-width=\"halfWidth\"\n                            :color=\"color\"\n                            :font-size=\"fontSize\"\n                        >\n                            {{ text }}\n                        </u-divider>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">提示内容</view>\n                        <u-subsection :list=\"['没有更多了', '到底了']\" @change=\"textChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">单边线宽</view>\n                        <u-subsection current=\"1\" :list=\"['50', '150', '250']\" @change=\"halfWidthChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">横线颜色</view>\n                        <u-subsection\n                            :list=\"['#dcdfe6', 'primary', 'error', 'warning', 'success']\"\n                            @change=\"borderColorChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">内容样式</view>\n                        <u-subsection :list=\"['默认', '自定义']\" @change=\"contentChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { $u } from '@/uni_modules/uview-pro';\nimport { ref } from 'vue';\nimport type { ThemeType } from '@/uni_modules/uview-pro/types/global';\n\nconst text = ref('没有更多了');\nconst bgColor = ref('#fafafa');\nconst halfWidth = ref(150);\nconst borderColor = ref('#dcdfe6');\nconst type = ref<ThemeType>('primary');\nconst color = ref('#909399');\nconst fontSize = ref(26);\n\nfunction textChange(index: number) {\n    text.value = index === 0 ? '没有更多了' : '到底了';\n}\n\nfunction halfWidthChange(index: number) {\n    halfWidth.value = index === 0 ? 50 : index === 1 ? 150 : 250;\n}\n\nfunction borderColorChange(index: number) {\n    if (index === 0) {\n        borderColor.value = '#dcdfe6';\n    } else {\n        // 因为border-color参数优先级高于type，要让type起作用，就需要设置border-color为空\n        borderColor.value = '';\n        type.value = index === 1 ? 'primary' : index === 2 ? 'error' : index === 3 ? 'warning' : 'success';\n    }\n}\n\nfunction contentChange(index: number) {\n    if (index === 0) {\n        color.value = '#909399';\n        fontSize.value = 26;\n    } else {\n        color.value = $u.color['primary'];\n        fontSize.value = 30;\n    }\n}\n\nfunction click() {\n    console.log('click');\n}\n</script>\n"
  },
  {
    "path": "src/pages/componentsB/dropdown/index.vue",
    "content": "<template>\n    <demo-page title=\"Dropdown 下拉菜单\" desc=\"用于展示下拉菜单，支持单选、多选、自定义样式等功能。\" :apis=\"'dropdown'\">\n        <template #default>\n            <view>\n                <view class=\"u-m-p-50\">\n                    <view class=\"u-demo-area u-flex u-row-center\">\n                        <u-dropdown\n                            :close-on-click-mask=\"mask\"\n                            ref=\"uDropdownRef\"\n                            :activeColor=\"activeColor\"\n                            :borderBottom=\"borderBottom\"\n                        >\n                            <u-dropdown-item\n                                @change=\"change\"\n                                v-model=\"value1\"\n                                title=\"距离\"\n                                :options=\"options1\"\n                            ></u-dropdown-item>\n                            <u-dropdown-item\n                                @change=\"change\"\n                                v-model=\"value2\"\n                                title=\"温度\"\n                                :options=\"options2\"\n                            ></u-dropdown-item>\n                            <u-dropdown-item title=\"属性\">\n                                <view class=\"slot-content\">\n                                    <view class=\"item-box\">\n                                        <view\n                                            class=\"item\"\n                                            :class=\"[item.active ? 'active' : '']\"\n                                            @tap=\"tagClick(index)\"\n                                            v-for=\"(item, index) in list\"\n                                            :key=\"index\"\n                                        >\n                                            {{ item.label }}\n                                        </view>\n                                    </view>\n                                    <u-button type=\"primary\" @click=\"closeDropdown\">确定</u-button>\n                                </view>\n                            </u-dropdown-item>\n                        </u-dropdown>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">下边框</view>\n                        <u-subsection current=\"1\" :list=\"['有', '无']\" @change=\"borderChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">激活颜色</view>\n                        <u-subsection\n                            :list=\"['#2979ff', '#ff9900', '#19be6b']\"\n                            @change=\"activeColorChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">遮罩是否可点击</view>\n                        <u-subsection :list=\"['是', '否']\" @change=\"maskChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { $u } from '@/uni_modules/uview-pro';\nimport { ref } from 'vue';\n\nconst value1 = ref('');\nconst value2 = ref(2);\nconst mask = ref(true);\nconst options1 = ref([\n    {\n        label: '默认排序',\n        value: 1\n    },\n    {\n        label: '距离优先',\n        value: 2\n    },\n    {\n        label: '价格优先',\n        value: 3\n    }\n]);\nconst options2 = ref([\n    {\n        label: '去冰',\n        value: 1\n    },\n    {\n        label: '加冰',\n        value: 2\n    },\n    {\n        label: '正常温',\n        value: 3\n    },\n    {\n        label: '加热',\n        value: 4\n    },\n    {\n        label: '极寒风暴',\n        value: 5\n    }\n]);\nconst list = ref([\n    {\n        label: '琪花瑶草',\n        active: true\n    },\n    {\n        label: '清词丽句',\n        active: false\n    },\n    {\n        label: '宛转蛾眉',\n        active: false\n    },\n    {\n        label: '煦色韶光',\n        active: false\n    },\n    {\n        label: '鱼沉雁落',\n        active: false\n    },\n    {\n        label: '章台杨柳',\n        active: false\n    },\n    {\n        label: '霞光万道',\n        active: false\n    }\n]);\nconst activeColor = ref('#2979ff');\nconst borderBottom = ref(false);\n\nconst uDropdownRef = ref(null);\n\nfunction borderChange(index: number) {\n    borderBottom.value = !index;\n}\n\nfunction activeColorChange(index: number) {\n    activeColor.value = ['#2979ff', '#ff9900', '#19be6b'][index];\n}\n\nfunction change(index: number) {\n    $u.toast(`点击了第${index}项`);\n}\n\nfunction tagClick(index: number) {\n    list.value[index].active = !list.value[index].active;\n}\n\nfunction closeDropdown() {\n    $u.toast('关闭了下拉菜单');\n    uDropdownRef.value.close();\n}\n\nfunction maskChange(index: number) {\n    mask.value = !index;\n}\n</script>\n\n<style scoped lang=\"scss\">\n.u-config-wrap {\n    padding: 40rpx;\n}\n\n.slot-content {\n    background-color: $u-bg-white;\n    padding: 24rpx;\n\n    .item-box {\n        margin-bottom: 50rpx;\n        display: flex;\n        flex-wrap: wrap;\n        justify-content: space-between;\n\n        .item {\n            border: 1px solid $u-type-primary;\n            color: $u-type-primary;\n            padding: 8rpx 40rpx;\n            border-radius: 100rpx;\n            margin-top: 30rpx;\n        }\n\n        .active {\n            color: $u-white-color;\n            background-color: $u-type-primary;\n        }\n    }\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsB/image/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"Image 图片\"\n        desc=\"此组件为 uni-app 的`image`组件的加强版，在继承了原有功能外，还支持淡入动画、加载中、加载失败提示、圆角值和形状等。\"\n        :apis=\"'image'\"\n    >\n        <view class=\"u-demo\">\n            <view class=\"u-demo-wrap\">\n                <view class=\"u-demo-title\">演示效果</view>\n                <view class=\"u-demo-area u-flex u-row-center\">\n                    <u-image\n                        :shape=\"shape\"\n                        ref=\"uImageRef\"\n                        :width=\"width\"\n                        :height=\"height\"\n                        :src=\"src\"\n                        mode=\"aspectFill\"\n                        :use-slots=\"{ loading: loadingSlot, error: errorSlot }\"\n                    >\n                        <template #loading>\n                            <u-loading size=\"44\" mode=\"flower\"></u-loading>\n                        </template>\n                        <template #error>\n                            <view style=\"font-size: 24rpx\">加载失败</view>\n                        </template>\n                    </u-image>\n                </view>\n            </view>\n            <view class=\"u-config-wrap\">\n                <view class=\"u-config-title u-border-bottom\">参数配置</view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">状态</view>\n                    <u-subsection\n                        :current=\"statusCurrent\"\n                        :list=\"['加载成功', '加载中', '加载失败']\"\n                        @change=\"statusChange\"\n                    ></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">加载中状态</view>\n                    <u-subsection :list=\"['默认', '自定义']\" @change=\"loadingChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">加载失败状态</view>\n                    <u-subsection :list=\"['默认', '自定义']\" @change=\"errorChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">形状</view>\n                    <u-subsection :list=\"['方形', '圆形']\" @change=\"shapeChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">图片地址</view>\n                    <u-subsection :list=\"['网络', '本地']\" @change=\"srcChange\"></u-subsection>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { type ImageInstance } from '@/uni_modules/uview-pro/components/u-image/types';\nimport { ref } from 'vue';\nimport type { Shape } from '@/uni_modules/uview-pro/types/global';\nimport { completeMission } from '../../../common/useExperience';\n\n// 定义响应式数据\nconst src = ref('https://ik.imagekit.io/anyup/uview-pro/logo/removebg-new.png');\nconst width = ref('200');\nconst height = ref('200');\nconst loadingSlot = ref(false);\nconst statusCurrent = ref(0);\nconst errorSlot = ref(false);\nconst shape = ref<Shape>('square');\n// 获取 uImage 组件实例\nconst uImageRef = ref<ImageInstance>();\n\n// 定义方法\nconst statusChange = (index: number) => {\n    if (index == 0) {\n        uImageRef.value?.changeStatus('normal');\n    } else if (index == 1) {\n        uImageRef.value?.changeStatus('loading');\n    } else {\n        uImageRef.value?.changeStatus('error');\n    }\n};\n\nconst loadingChange = (index: number) => {\n    statusCurrent.value = 1;\n    statusChange(1);\n    loadingSlot.value = index !== 0;\n};\n\nconst errorChange = (index: number) => {\n    statusCurrent.value = 2;\n    statusChange(2);\n    errorSlot.value = index !== 0;\n};\n\nconst shapeChange = (index: number) => {\n    shape.value = index === 0 ? 'square' : 'circle';\n    completeMission('image-shape');\n};\n\nconst srcChange = (index: number) => {\n    if (index == 0) {\n        src.value = 'https://ik.imagekit.io/anyup/uview-pro/common/logo-new.png';\n    } else {\n        src.value = '/static/logo.png';\n    }\n};\n</script>\n"
  },
  {
    "path": "src/pages/componentsB/line/index.vue",
    "content": "<template>\n    <demo-page title=\"Line 线条\" desc=\"用于展示线条，支持不同方向、样式和颜色设置。\" :apis=\"'line'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area u-flex u-row-center\">\n                        <!-- 头条小程序因为兼容性，必须要给组件写上u-line类 -->\n                        <u-line\n                            class=\"u-line\"\n                            :border-style=\"borderStyle\"\n                            :color=\"color\"\n                            :length=\"length\"\n                            :direction=\"direction\"\n                            :hair-line=\"hairLine\"\n                        ></u-line>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">颜色</view>\n                        <u-subsection\n                            :list=\"['primary', 'success', 'warning', 'error', 'info']\"\n                            @change=\"colorChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">线条类型</view>\n                        <u-subsection\n                            :list=\"['实线', '方形虚线', '圆点虚线']\"\n                            @change=\"borderStyleChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">细边</view>\n                        <u-subsection :list=\"['是', '否']\" @change=\"hairLineChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">方向</view>\n                        <u-subsection :list=\"['水平', '垂直']\" @change=\"directionChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { $u } from '@/uni_modules/uview-pro';\nimport { ref } from 'vue';\nimport type { LineBorderStyle, LineDirection } from '@/uni_modules/uview-pro/types/global';\n\nconst direction = ref<LineDirection>('row');\nconst hairLine = ref(true);\nconst length = ref('100%');\nconst color = ref($u.color['primary']);\nconst borderStyle = ref<LineBorderStyle>('solid');\n\nfunction colorChange(index: number) {\n    color.value = $u.color[['primary', 'success', 'warning', 'error', 'info'][index]];\n}\n\nfunction hairLineChange(index: number) {\n    hairLine.value = !index;\n}\n\nfunction directionChange(index: number) {\n    direction.value = index === 0 ? 'row' : ('col' as LineDirection);\n    if (index === 0) length.value = '100%';\n    else length.value = '50rpx';\n}\n\nfunction borderStyleChange(index: number) {\n    borderStyle.value = ['solid', 'dashed', 'dotted'][index] as LineBorderStyle;\n}\n</script>\n"
  },
  {
    "path": "src/pages/componentsB/loading/index.vue",
    "content": "<template>\n    <demo-page title=\"Loading 加载\" desc=\"用于显示加载动画，支持圆圈和花朵两种模式。\" :apis=\"'loading'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-loading :mode=\"mode\" :show=\"show\" :color=\"color\" :size=\"size\"></u-loading>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">模式</view>\n                        <u-subsection :list=\"['圆圈', '花朵']\" @change=\"modeChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">颜色(只对圆圈模式有效)</view>\n                        <u-subsection\n                            :list=\"['default', 'primary', 'error', 'warning', 'success']\"\n                            @change=\"colorChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">尺寸(单位rpx)</view>\n                        <u-subsection current=\"1\" :list=\"['28', '34', '40']\" @change=\"sizeChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">是否显示</view>\n                        <u-subsection current=\"1\" :list=\"['否', '是']\" @change=\"showChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\n\n// 加载模式\nconst mode = ref<'circle' | 'flower'>('circle');\n// 加载颜色\nconst color = ref<string>('#c7c7c7');\n// 加载尺寸\nconst size = ref<string>('34');\n// 是否显示\nconst show = ref<boolean>(true);\n\n/**\n * 切换加载模式\n * @param index 选中索引\n */\nfunction modeChange(index: number): void {\n    mode.value = index === 0 ? 'circle' : 'flower';\n}\n\n/**\n * 切换颜色\n * @param index 选中索引\n */\nfunction colorChange(index: number): void {\n    if (index === 0) {\n        color.value = '#c7c7c7';\n    } else {\n        // 颜色映射\n        const colorMap: Record<number, keyof typeof $u.color> = {\n            1: 'primary',\n            2: 'error',\n            3: 'warning',\n            4: 'success'\n        };\n        color.value = $u.color[colorMap[index]];\n    }\n}\n\n/**\n * 切换尺寸\n * @param index 选中索引\n */\nfunction sizeChange(index: number): void {\n    size.value = index === 0 ? '28' : index === 1 ? '34' : '40';\n}\n\n/**\n * 切换显示状态\n * @param index 选中索引\n */\nfunction showChange(index: number): void {\n    show.value = !!index;\n}\n</script>\n"
  },
  {
    "path": "src/pages/componentsB/loadingPopup/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"LoadingPopup 加载弹窗\"\n        desc=\"用于显示加载弹窗，支持自定义文案、时长和方向。\"\n        :apis=\"'loadingPopup'\"\n    >\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">u-loading-popup 原生用法</view>\n                    <view class=\"u-demo-area\">\n                        <u-button type=\"primary\" @click=\"openLoading\">显示 Loading Popup</u-button>\n                        <!-- v-model:modelValue 控制弹窗显示，支持所有原生 props -->\n                        <u-loading-popup\n                            ref=\"uLoadingPopupRef\"\n                            v-model=\"show\"\n                            :text=\"text\"\n                            :cancelTime=\"cancelTime\"\n                            :duration=\"duration\"\n                            :direction=\"direction\"\n                            :color=\"color\"\n                            :size=\"size\"\n                            @cancel=\"onCancel\"\n                        />\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\">参数配置</view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">方向</view>\n                        <u-subsection :list=\"['vertical', 'horizontal']\" @change=\"directionChange\" />\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">颜色</view>\n                        <u-subsection\n                            :list=\"['#c7c7c7', 'primary', 'error', 'warning', 'success']\"\n                            @change=\"colorChange\"\n                        />\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">尺寸(单位rpx)</view>\n                        <u-subsection current=\"1\" :list=\"['32', '48', '64']\" @change=\"sizeChange\" />\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">文案</view>\n                        <input class=\"u-input\" v-model=\"text\" placeholder=\"请输入 loading 文案\" />\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">自动关闭(ms)-0为不自动关闭</view>\n                        <input class=\"u-input\" type=\"number\" v-model.number=\"duration\" placeholder=\"0=不自动关闭\" />\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">遮罩可关闭延时(ms)</view>\n                        <input class=\"u-input\" type=\"number\" v-model.number=\"cancelTime\" placeholder=\"默认10000\" />\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\n\n// 是否显示 loading popup\nconst show = ref(false);\n// loading 文案\nconst text = ref('加载中...');\n// 遮罩可关闭延时（ms）\nconst cancelTime = ref(2000);\n// 自动关闭时长（ms，0为不自动关闭）\nconst duration = ref(2000);\n// loading 方向\nconst direction = ref<'vertical' | 'horizontal'>('vertical');\n// loading 颜色\nconst color = ref<string>('#c7c7c7');\n// loading 尺寸\nconst size = ref<string | number>(48);\n\nconst uLoadingPopupRef = ref();\n\n/** 显示 loading popup */\nfunction openLoading() {\n    show.value = true;\n    // uLoadingPopupRef.value.show();\n    // setTimeout(() => {\n    //     show.value = false;\n    //     // uLoadingPopupRef.value.hide();\n    // }, 1000);\n}\n\n/** 切换方向 */\nfunction directionChange(index: number) {\n    direction.value = index === 0 ? 'vertical' : 'horizontal';\n}\n\n/** 切换颜色 */\nfunction colorChange(index: number) {\n    if (index === 0) {\n        color.value = '#c7c7c7';\n    } else {\n        const colorMap: Record<number, keyof typeof $u.color> = {\n            1: 'primary',\n            2: 'error',\n            3: 'warning',\n            4: 'success'\n        };\n        color.value = $u.color[colorMap[index]];\n    }\n}\n\n/** 切换尺寸 */\nfunction sizeChange(index: number) {\n    const sizeMap: Record<number, number> = {\n        0: 40,\n        1: 50,\n        2: 60\n    };\n    size.value = sizeMap[index];\n}\n\n/** 遮罩点击关闭回调 */\nfunction onCancel() {\n    show.value = false;\n    // 这里可做自定义提示\n}\n</script>\n\n<style scoped lang=\"scss\">\n.u-demo-area {\n    margin-bottom: 24rpx;\n}\n\n.u-input {\n    width: 300rpx;\n    border: 1px solid #eee;\n    border-radius: 8rpx;\n    padding: 8rpx 16rpx;\n    font-size: 28rpx;\n    margin-top: 8rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsB/noticeBar/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"NoticeBar 通知栏\"\n        desc=\"用于展示通知消息，支持水平和竖直滚动、自定义颜色和速度。\"\n        :apis=\"'noticeBar'\"\n    >\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-toast :type=\"type\" ref=\"uToastRef\"></u-toast>\n                        <u-notice-bar\n                            :autoplay=\"autoplay\"\n                            :playState=\"playState\"\n                            :speed=\"speed\"\n                            @getMore=\"getMore\"\n                            :mode=\"mode\"\n                            @end=\"end\"\n                            @close=\"close\"\n                            @click=\"click\"\n                            :show=\"show\"\n                            :type=\"type\"\n                            :list=\"list\"\n                            :moreIcon=\"moreIcon\"\n                            :volumeIcon=\"volumeIcon\"\n                            :duration=\"duration\"\n                            :isCircular=\"isCircular\"\n                        ></u-notice-bar>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">主题</view>\n                        <u-subsection\n                            :current=\"3\"\n                            :list=\"['primary', 'success', 'error', 'warning', 'none']\"\n                            @change=\"typeChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">滚动模式</view>\n                        <u-subsection :current=\"current\" :list=\"['水平', '垂直']\" @change=\"modeChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">是否衔接(水平模式有效)</view>\n                        <u-subsection :list=\"['是', '否']\" @change=\"isCircularChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">状态</view>\n                        <u-subsection :list=\"['播放', '暂停']\" @change=\"playStateChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">速度</view>\n                        <u-subsection :current=\"1\" :list=\"['慢', '正常', '快']\" @change=\"speedChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">图标</view>\n                        <u-subsection :list=\"['显示', '隐藏']\" @change=\"iconChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport type { Direction, PlayState, ThemeType } from '@/uni_modules/uview-pro/types/global';\n\nconst show = ref(true);\nconst autoplay = ref(false);\nconst type = ref<ThemeType>('warning');\nconst list = ref([\n    '锦瑟无端五十弦，一弦一柱思华年',\n    '庄生晓梦迷蝴蝶，望帝春心托杜鹃',\n    '沧海月明珠有泪，蓝田日暖玉生烟'\n]);\nconst mode = ref<Direction>('horizontal');\nconst playState = ref<PlayState>('play');\nconst speed = ref(160);\nconst duration = ref(2000);\nconst moreIcon = ref(true);\nconst volumeIcon = ref(true);\nconst isCircular = ref(true);\nconst current = ref(0);\n\nconst uToastRef = ref(null);\n\nfunction typeChange(index: number) {\n    type.value =\n        index === 0 ? 'primary' : index === 1 ? 'success' : index === 2 ? 'error' : index === 3 ? 'warning' : undefined;\n}\n\nfunction modeChange(index: number) {\n    current.value = index;\n    mode.value = index === 0 ? 'horizontal' : 'vertical';\n}\n\nfunction playStateChange(index: number) {\n    playState.value = index === 0 ? 'play' : 'paused';\n}\n\nfunction speedChange(index: number) {\n    if (index === 0) {\n        speed.value = 50;\n        duration.value = 6000;\n    } else if (index === 1) {\n        speed.value = 160;\n        duration.value = 2000;\n    } else {\n        speed.value = 350;\n        duration.value = 400;\n    }\n}\n\nfunction iconChange(index: number) {\n    if (index === 0) {\n        moreIcon.value = true;\n        volumeIcon.value = true;\n    } else {\n        moreIcon.value = false;\n        volumeIcon.value = false;\n    }\n}\n\nfunction isCircularChange(index: number) {\n    isCircular.value = index === 0;\n    current.value = index;\n    mode.value = 'horizontal';\n}\n\nfunction getMore() {\n    toast('点击了更多');\n}\n\nfunction toast(title: string) {\n    uToastRef.value.show({ title: title, type: 'warning' });\n}\n\nfunction end() {\n    console.log('end');\n}\n\nfunction close() {\n    console.log('close');\n}\n\nfunction click(index: number) {\n    if (mode.value == 'horizontal' && isCircular) {\n        toast('此模式无法获取Index值');\n    } else {\n        toast('点击了第' + index + '项');\n    }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.item {\n    margin-top: 30px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsB/picker/index.vue",
    "content": "<template>\n    <demo-page title=\"Picker 选择器\" desc=\"用于展示选择器，支持单选、多选、日期、地区等多种模式。\" :apis=\"'picker'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <view class=\"u-demo-result-line\">{{ input ? input : 'Picker值' }}</view>\n                        <u-picker\n                            :mode=\"mode\"\n                            :defaultTime=\"defaultTime\"\n                            v-model=\"show\"\n                            :defaultRegion=\"defaultRegion\"\n                            :params=\"params\"\n                            end-year=\"2030\"\n                            @confirm=\"confirm\"\n                            :defaultSelector=\"defaultSelector\"\n                            :range=\"range\"\n                            :range-key=\"rangKey\"\n                            :preserve-selection=\"false\"\n                            @columnchange=\"columnchange\"\n                        ></u-picker>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\">参数配置</view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">Picker开关</view>\n                        <u-subsection :current=\"status\" :list=\"['显示', '隐藏']\" @change=\"statusChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">模式选择</view>\n                        <u-subsection :list=\"['单列', '多列', '时间', '地区']\" @change=\"modeChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">默认时间</view>\n                        <u-subsection\n                            :list=\"['2019-12-11 20:15:35', '2020-02-05 13:09:42']\"\n                            @change=\"defaultTimeChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">显示时分秒</view>\n                        <u-subsection :list=\"['显示', '隐藏']\" @change=\"minSecChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">默认地区</view>\n                        <u-subsection\n                            :list=\"['广东-深圳-宝安', '海南-三亚-海棠']\"\n                            @change=\"defaultRegionChange\"\n                        ></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed } from 'vue';\nimport type { PickerMode } from '@/uni_modules/uview-pro/types/global';\n\nconst show = ref(false);\nconst input = ref<string | string[]>('');\nconst range = ref<string[] | string[][]>(['一', '片', '冰', '心', '在', '玉', '壶']);\nconst rangKey = ref('name');\nconst mode = ref<PickerMode>('selector');\nconst defaultTime = ref('2019-12-11 20:15:35');\nconst defaultSelector = ref([3]);\nconst defaultRegion = ref(['山东省', '青岛市', '崂山区']);\nconst params = ref({\n    year: true,\n    month: true,\n    day: true,\n    hour: true,\n    minute: true,\n    second: true,\n    province: true,\n    city: true,\n    area: true,\n    timestamp: true\n});\n\nconst status = computed(() => (show.value === true ? 0 : 1));\n\nfunction statusChange(index: number) {\n    show.value = index === 0;\n}\n\nfunction modeChange(index: number) {\n    mode.value = ['selector', 'multiSelector', 'time', 'region'][index] as PickerMode;\n    if (mode.value == 'selector') {\n        range.value = ['一', '片', '冰', '心', '在', '玉', '壶'];\n        defaultSelector.value = [3];\n    }\n    if (mode.value == 'multiSelector') {\n        range.value = [\n            ['亚洲', '欧洲'],\n            ['中国', '日本'],\n            ['北京', '上海', '广州']\n        ];\n        defaultSelector.value = [0, 0, 1];\n    }\n    show.value = true;\n}\n\nfunction defaultTimeChange(index: number) {\n    defaultTime.value = index == 0 ? '2019-12-11 20:15:35' : '2020-02-05 13:09:42';\n    mode.value = 'time';\n    show.value = true;\n}\n\nfunction defaultRegionChange(index: number) {\n    defaultRegion.value = index == 0 ? ['山东省', '青岛市', '崂山区'] : ['海南省', '三亚市', '海棠区'];\n    mode.value = 'region';\n    show.value = true;\n}\n\nfunction minSecChange(index: number) {\n    if (index === 0) {\n        params.value.hour = true;\n        params.value.minute = true;\n        params.value.second = true;\n    }\n    if (index === 1) {\n        defaultTime.value = '2020-02-05';\n        params.value.hour = false;\n        params.value.minute = false;\n        params.value.second = false;\n    }\n    mode.value = 'time';\n    show.value = true;\n}\n\nfunction confirm(e) {\n    input.value = '';\n    if (mode.value == 'time') {\n        if (params.value.year) input.value += e.year;\n        if (params.value.month) input.value += '-' + e.month;\n        if (params.value.day) input.value += '-' + e.day;\n        if (params.value.hour) input.value += ' ' + e.hour;\n        if (params.value.minute) input.value += ':' + e.minute;\n        if (params.value.second) input.value += ':' + e.second;\n    } else if (mode.value == 'region') {\n        input.value = e.province.label + '-' + e.city.label + '-' + e.area.label;\n    } else if (mode.value == 'selector') {\n        input.value = range.value[e[0]];\n    } else if (mode.value == 'multiSelector') {\n        input.value = range.value[0][e[0]] + '-' + range.value[1][e[1]] + '-' + range.value[2][e[2]];\n    }\n}\n\nfunction columnchange(e) {\n    let column = e.column,\n        index = e.index;\n    defaultSelector.value[column] = index;\n    switch (column) {\n        case 0:\n            switch (index) {\n                case 0:\n                    range.value[1] = ['中国', '日本'];\n                    range.value[2] = ['北京', '上海', '广州'];\n                    break;\n                case 1:\n                    range.value[1] = ['英国', '法国'];\n                    range.value[2] = ['伦敦', '曼彻斯特'];\n                    break;\n            }\n            defaultSelector.value.splice(1, 1, 0);\n            defaultSelector.value.splice(2, 1, 0);\n            break;\n        case 1: //拖动第2列\n            switch (\n                defaultSelector.value[0] //判断第一列是什么\n            ) {\n                case 0:\n                    switch (defaultSelector.value[1]) {\n                        case 0:\n                            range.value[2] = ['北京', '上海', '广州'];\n                            break;\n                        case 1:\n                            range.value[2] = ['东京', '北海道'];\n                            break;\n                    }\n                    break;\n                case 1:\n                    switch (defaultSelector.value[1]) {\n                        case 0:\n                            range.value[2] = ['伦敦', '曼彻斯特'];\n                            break;\n                        case 1:\n                            range.value[2] = ['巴黎', '马赛'];\n                            break;\n                    }\n                    break;\n            }\n            defaultSelector.value.splice(2, 1, 0);\n            break;\n    }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.input {\n    border: 1px solid $u-light-color;\n    border-radius: 4px;\n    margin-bottom: 20px;\n    height: 30px;\n    font-size: 26rpx;\n    flex: 1;\n}\n\n.input-wrap {\n    display: flex;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsB/radio/index.vue",
    "content": "<template>\n    <demo-page title=\"Radio 单选框\" desc=\"用于单项选择，支持自定义颜色、大小、禁用等功能。\" :apis=\"'radio'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area u-flex-col u-col-center\">\n                        <view>\n                            <u-radio-group\n                                v-model=\"value\"\n                                :shape=\"shape\"\n                                :size=\"size\"\n                                :width=\"width\"\n                                :wrap=\"wrap\"\n                                @change=\"radioGroupChange\"\n                                :activeColor=\"activeColor\"\n                            >\n                                <u-radio\n                                    @change=\"radioChange\"\n                                    v-for=\"(item, index) in list\"\n                                    :disabled=\"item.disabled\"\n                                    :key=\"index\"\n                                    :value=\"item.value\"\n                                    :label=\"item.label\"\n                                />\n                            </u-radio-group>\n                        </view>\n                        <view class=\"u-demo-result-line\">\n                            {{ value ? `选中了\"${value}\"` : '请选择' }}\n                        </view>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">形状</view>\n                        <u-subsection current=\"1\" :list=\"['方形', '圆形']\" @change=\"shapeChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">整体大小(单位rpx)</view>\n                        <u-subsection current=\"1\" :list=\"['小', '中', '大', '60']\" @change=\"sizeChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">激活颜色</view>\n                        <u-subsection\n                            :list=\"['primary', 'error', 'warning', 'success', 'info']\"\n                            @change=\"activeColorChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">每个占一行</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"wrapChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">每个宽度50%</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"widthChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">默认选中第一个</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"defaultChooseChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">禁用第一个</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"disabledChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { $u } from '@/uni_modules/uview-pro';\nimport type { Shape, SizeType } from '@/uni_modules/uview-pro/types/global';\nimport { reactive, ref } from 'vue';\n\nconst list = reactive([\n    {\n        label: '荔枝',\n        value: '荔枝',\n        disabled: false\n    },\n    {\n        label: '香蕉',\n        value: '香蕉',\n        disabled: false\n    },\n    {\n        label: '橙子',\n        value: '橙子',\n        disabled: false\n    },\n    {\n        label: '草莓',\n        value: '草莓',\n        disabled: false\n    }\n]);\nconst shape = ref<Shape>('circle');\nconst value = ref('荔枝');\nconst activeColor = ref($u.color.primary);\nconst size = ref<SizeType | string | number>('default');\nconst wrap = ref(false);\nconst width = ref('auto');\n\nfunction shapeChange(index: number) {\n    shape.value = index == 0 ? 'square' : 'circle';\n}\n\nfunction sizeChange(index: number) {\n    if (index > 2) {\n        size.value = 60;\n    } else {\n        size.value = index === 0 ? 'small' : index === 1 ? 'default' : 'large';\n    }\n}\n\nfunction defaultChooseChange(index: number) {\n    value.value = list[0].value;\n}\n\nfunction activeColorChange(index: number) {\n    let theme =\n        index == 0 ? 'primary' : index == 1 ? 'error' : index == 2 ? 'warning' : index == 3 ? 'success' : 'info';\n    activeColor.value = $u.color[theme];\n}\n\nfunction disabledChange(index: number) {\n    list[0].disabled = index === 0;\n}\n\nfunction radioChange(e) {\n    console.log('radioChange', e);\n}\n\nfunction radioGroupChange(e) {\n    console.log('radioGroupChange', e);\n}\n\nfunction widthChange(index: number) {\n    width.value = index == 0 ? '50%' : '';\n}\n\nfunction wrapChange(index: number) {\n    wrap.value = !index;\n}\n</script>\n"
  },
  {
    "path": "src/pages/componentsB/rate/index.vue",
    "content": "<template>\n    <demo-page title=\"Rate 评分\" desc=\"用于评分展示和交互，支持自定义大小、颜色和图标。\" :apis=\"'rate'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-rate\n                            v-model=\"value\"\n                            :count=\"count\"\n                            @change=\"change\"\n                            :active-color=\"activeColor\"\n                            :inaction-color=\"inactiveColor\"\n                            :active-icon=\"activeIcon\"\n                            :inactive-icon=\"inactiveIcon\"\n                            :disabled=\"disabled\"\n                            :colors=\"colors\"\n                            :icons=\"icons\"\n                        ></u-rate>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">初始值</view>\n                        <u-subsection :list=\"['1', '2', '3', '4']\" @change=\"currentChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">镂空状态</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"plainChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">自定义样式</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"styleChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">自定义图标</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"iconChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">是否分层</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"decimalChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">是否禁用</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"disabledChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">星星数量</view>\n                        <u-subsection current=\"1\" :list=\"['4', '5', '6']\" @change=\"countChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { $u } from '@/uni_modules/uview-pro';\nimport { ref, computed, watch } from 'vue';\nimport { completeMission } from '../../../common/useExperience';\n\nconst activeColor = ref('#FA3534');\nconst inactiveColor = ref('#b2b2b2');\nconst disabled = ref(false);\nconst count = ref(5);\nconst customIcon = ref(false);\nconst plain = ref(false);\nconst value = ref(0);\nconst colors = ref([]);\nconst icons = ref([]);\n\nwatch(value, n => {\n    // console.log(n);\n});\n\nconst activeIcon = computed(() => {\n    let icon = customIcon.value ? 'heart' : 'star';\n    return plain.value ? icon : icon + '-fill';\n});\n\nconst inactiveIcon = computed(() => {\n    let icon = customIcon.value ? 'heart' : 'star';\n    return plain.value ? icon : icon + '-fill';\n});\n\nfunction currentChange(index: number) {\n    value.value = index === 0 ? 1 : index === 1 ? 2 : index === 2 ? 3 : 4;\n}\n\nfunction plainChange(index: number) {\n    plain.value = !index;\n}\n\nfunction disabledChange(index: number) {\n    disabled.value = index === 0 ? true : false;\n}\n\nfunction countChange(index: number) {\n    count.value = index === 0 ? 4 : index == 1 ? 5 : 6;\n}\n\nfunction styleChange(index: number) {\n    if (index == 0) {\n        activeColor.value = $u.color['primary'];\n        inactiveColor.value = $u.color['info'];\n    } else {\n        activeColor.value = '#FA3534';\n        inactiveColor.value = '#b2b2b2';\n    }\n}\n\nfunction decimalChange(index: number) {\n    if (index == 0) {\n        colors.value = ['#ffc454', '#ffb409', '#ff9500'];\n        icons.value = ['thumb-down-fill', 'thumb-down-fill', 'thumb-up-fill', 'thumb-up-fill'];\n    } else {\n        colors.value = [];\n        icons.value = [];\n    }\n}\n\nfunction iconChange(index: number) {\n    customIcon.value = !index;\n}\n\nfunction change(val: number) {\n    // console.log(val);\n    completeMission('rate');\n}\n</script>\n"
  },
  {
    "path": "src/pages/componentsB/readMore/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"ReadMore 展开更多\"\n        desc=\"用于展示可收缩的长文本内容，支持自定义高度和展开关闭功能。\"\n        :apis=\"'readMore'\"\n    >\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-read-more\n                            @open=\"open\"\n                            @close=\"close\"\n                            :toggle=\"toggle\"\n                            :show-height=\"showHeight\"\n                            ref=\"uReadMoreRef\"\n                        >\n                            <!-- u-parse组件在微信小程序渲染慢，支付宝小程序rich-text不支持nodes属性 -->\n                            <!-- #ifdef MP-ALIPAY -->\n                            <!-- #endif -->\n                            <!-- #ifndef MP-ALIPAY -->\n                            <rich-text :nodes=\"content\"></rich-text>\n                            <!-- #endif -->\n                        </u-read-more>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">超出高度隐藏</view>\n                        <u-subsection\n                            current=\"1\"\n                            :list=\"['100', '200', '400']\"\n                            @change=\"showHeightChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">展开后可关闭</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"toggleChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\n\nconst content = ref(`浔阳江头夜送客，枫叶荻花秋瑟瑟。主人下马客在船，举酒欲饮无管弦。醉不成欢惨将别，别时茫茫江浸月。\n\t\t\t\t\t忽闻水上琵琶声，主人忘归客不发。寻声暗问弹者谁，琵琶声停欲语迟。移船相近邀相见，添酒回灯重开宴。千呼万唤始出来，犹抱琵琶半遮面。转轴拨弦三两声，未成曲调先有情。弦弦掩抑声声思，似诉平生不得志。低眉信手续续弹，说尽心中无限事。轻拢慢捻抹复挑，初为《霓裳》后《六幺》。大弦嘈嘈如急雨，小弦切切如私语。嘈嘈切切错杂弹，大珠小珠落玉盘。间关莺语花底滑，幽咽泉流冰下难。冰泉冷涩弦凝绝，凝绝不通声暂歇。别有幽愁暗恨生，此时无声胜有声。银瓶乍破水浆迸，铁骑突出刀枪鸣。曲终收拨当心画，四弦一声如裂帛。东船西舫悄无言，唯见江心秋月白。\n\t\t\t\t\t沉吟放拨插弦中，整顿衣裳起敛容。自言本是京城女，家在虾蟆陵下住。十三学得琵琶成，名属教坊第一部。曲罢曾教善才服，妆成每被秋娘妒。五陵年少争缠头，一曲红绡不知数。钿头银篦击节碎，血色罗裙翻酒污。今年欢笑复明年，秋月春风等闲度。弟走从军阿姨死，暮去朝来颜色故。门前冷落鞍马稀，老大嫁作商人妇。商人重利轻别离，前月浮梁买茶去。去来江口守空船，绕船月明江水寒。夜深忽梦少年事，梦啼妆泪红阑干。\n\t\t\t\t\t我闻琵琶已叹息，又闻此语重唧唧。同是天涯沦落人，相逢何必曾相识！我从去年辞帝京，谪居卧病浔阳城。浔阳地僻无音乐，终岁不闻丝竹声。住近湓江地低湿，黄芦苦竹绕宅生。其间旦暮闻何物？杜鹃啼血猿哀鸣。春江花朝秋月夜，往往取酒还独倾。岂无山歌与村笛？呕哑嘲哳难为听。今夜闻君琵琶语，如听仙乐耳暂明。莫辞更坐弹一曲，为君翻作《琵琶行》。感我此言良久立，却坐促弦弦转急。凄凄不似向前声，满座重闻皆掩泣。座中泣下谁最多？江州司马青衫湿。`);\nconst showHeight = ref(200);\nconst toggle = ref(false);\nconst uReadMoreRef = ref(null);\n\nfunction showHeightChange(index: number) {\n    showHeight.value = index === 0 ? 100 : index === 1 ? 200 : 400;\n}\n\nfunction toggleChange(index: number) {\n    toggle.value = index === 0 ? true : false;\n}\n\nfunction open() {\n    // console.log('open');\n}\n\nfunction close() {\n    // console.log('close');\n}\n</script>\n\n<style lang=\"scss\" scoped>\n// 通过/deep/样式穿透去控制组件的内容\n.wrap ::v-deep .u-content {\n    color: #666 !important;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsB/search/index.vue",
    "content": "<template>\n    <demo-page title=\"Search 搜索\" desc=\"用于搜索输入，支持不同形状、清除按钮和自定义样式。\" :apis=\"'search'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-toast ref=\"uToastRef\"></u-toast>\n                        <u-search\n                            v-model=\"value\"\n                            @change=\"change\"\n                            @custom=\"custom\"\n                            @search=\"search\"\n                            :shape=\"shape\"\n                            :clearabled=\"clearabled\"\n                            :show-action=\"showAction\"\n                            :input-align=\"inputAlign\"\n                            @clear=\"clear\"\n                        ></u-search>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">初始值</view>\n                        <u-subsection :list=\"['空', '天山雪莲']\" @change=\"valueChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">搜索框形状</view>\n                        <u-subsection :list=\"['圆形', '方形']\" @change=\"shapeChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">清除控件</view>\n                        <u-subsection :list=\"['启用', '关闭']\" @change=\"clearabledChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">右侧控件</view>\n                        <u-subsection :list=\"['启用', '关闭']\" @change=\"showActionChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">水平对齐方式</view>\n                        <u-subsection :list=\"['左', '中', '右']\" @change=\"inputAlignChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\nimport type { SearchShape, InputAlign } from '@/uni_modules/uview-pro/types/global';\n\nconst value = ref('');\nconst shape = ref<SearchShape>('round');\nconst clearabled = ref(true);\nconst showAction = ref(true);\nconst inputAlign = ref<InputAlign>('left');\nconst uToastRef = ref(null);\n\nwatch(value, val => {\n    // console.log(val);\n});\n\nfunction valueChange(index: number) {\n    value.value = index === 0 ? '' : '天山雪莲';\n}\n\nfunction shapeChange(index: number) {\n    shape.value = index === 0 ? 'round' : 'square';\n}\n\nfunction clearabledChange(index: number) {\n    clearabled.value = index === 0 ? true : false;\n}\n\nfunction showActionChange(index: number) {\n    showAction.value = index === 0 ? true : false;\n}\n\nfunction inputAlignChange(index: number) {\n    inputAlign.value = index === 0 ? 'left' : index === 1 ? 'center' : 'right';\n}\n\nfunction change(val: string) {\n    // 搜索框内容变化时，会触发此事件，value值为输入框的内容\n    //console.log(val);\n}\n\nfunction custom(val: string) {\n    //console.log(val);\n    $u.toast('输入值为：' + val);\n}\n\nfunction search(val: string) {\n    $u.toast('搜索内容为：' + val);\n}\n\nfunction clear() {\n    // console.log(value.value);\n}\n</script>\n"
  },
  {
    "path": "src/pages/componentsB/search/types.ts",
    "content": "import { type ComponentPublicInstance, type ExtractPropTypes } from 'vue';\n\n// 定义组件 Props\nexport const Props = {};\n\n// 将 Props 转换为类型\nexport type Props = ExtractPropTypes<typeof Props>;\n\n// 暴露的组件实例方法和属性\nexport type Expose = {};\n// 导出组件实例类型\nexport type Instance = ComponentPublicInstance<Props, Expose>;\n"
  },
  {
    "path": "src/pages/componentsB/skeleton/index.vue",
    "content": "<template>\n    <demo-page title=\"Skeleton 骨架屏\" desc=\"用于加载占位显示，支持动画效果和自定义样式。\" :apis=\"'skeleton'\">\n        <view class=\"u-page\">\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">基础使用</text>\n                <view class=\"u-demo-block__content\">\n                    <u-skeleton rows=\"3\" title loading></u-skeleton>\n                </view>\n            </view>\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">自定义段落行数</text>\n                <view class=\"u-demo-block__content\">\n                    <u-skeleton rows=\"2\" title loading></u-skeleton>\n                </view>\n            </view>\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">设置段落宽度</text>\n                <view class=\"u-demo-block__content\">\n                    <u-skeleton rows=\"2\" title :rowsWidth=\"['100%', '35%']\" loading></u-skeleton>\n                </view>\n            </view>\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">设置段落高度</text>\n                <view class=\"u-demo-block__content\">\n                    <u-skeleton\n                        rows=\"3\"\n                        title\n                        :rowsWidth=\"['100%', '100%', '100%']\"\n                        :rowsHeight=\"['18px', '18px', '80px']\"\n                        loading\n                    ></u-skeleton>\n                </view>\n            </view>\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">是否开启动画</text>\n                <u-switch v-model=\"switch1\" space=\"2\" inactiveColor=\"#e6e6e6\"></u-switch>\n                <u-gap height=\"15\" bgColor=\"#fff\"></u-gap>\n                <view class=\"u-demo-block__content\">\n                    <u-skeleton :animate=\"switch1\" rows=\"3\" title loading></u-skeleton>\n                </view>\n            </view>\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">展示头像</text>\n                <u-gap height=\"15\" bgColor=\"#fff\"></u-gap>\n                <view class=\"u-demo-block__content\">\n                    <u-skeleton :animate=\"switch1\" rows=\"3\" title loading avatar></u-skeleton>\n                </view>\n            </view>\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">切换状态</text>\n                <u-switch v-model=\"switch2\" space=\"2\" inactiveColor=\"#e6e6e6\"></u-switch>\n                <u-gap height=\"15\" bgColor=\"#fff\"></u-gap>\n                <view class=\"u-demo-block__content\">\n                    <u-skeleton rows=\"2\" title :loading=\"switch2\" avatar rowsHeight=\"14\">\n                        <!-- 需要在外部多嵌套一层占位view，否则在nvue下会导致样式失效 -->\n                        <view>\n                            <view class=\"u-skeleton-slot\">\n                                <image src=\"/static/uview/common/logo.png\" class=\"u-skeleton-slot__image\"></image>\n                                <view class=\"u-skeleton-slot__content\">\n                                    <u-text text=\"利剑出鞘,一统江湖\" type=\"main\" size=\"16px\"></u-text>\n                                    <u-text\n                                        type=\"tips\"\n                                        size=\"14px\"\n                                        customStyle=\"margin-top: 5px\"\n                                        text=\"众多组件覆盖开发过程的各个需求，组件功能丰富，多端兼容。让您快速集成，开箱即用\"\n                                    ></u-text>\n                                </view>\n                            </view>\n                        </view>\n                    </u-skeleton>\n                </view>\n                <u-gap height=\"50\" bgColor=\"transparent\"></u-gap>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script>\nexport default {\n    data() {\n        return {\n            switch1: true,\n            switch2: false\n        };\n    }\n};\n</script>\n\n<style lang=\"scss\">\n.u-skeleton-slot {\n    align-items: flex-start;\n\n    &__image {\n        width: 40px;\n        height: 40px;\n        border-radius: 100px;\n    }\n\n    &__content {\n        margin-left: 10px;\n        flex: 1;\n    }\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsB/steps/index.vue",
    "content": "<template>\n    <demo-page title=\"Steps 步骤条\" desc=\"用于展示步骤流程，支持不同模式和方向设置。\" :apis=\"'steps'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <view class=\"title\"> list传入 </view>\n                        <u-steps\n                            :direction=\"direction\"\n                            :current=\"current\"\n                            :list=\"steps\"\n                            :mode=\"mode\"\n                            :icon=\"icon\"\n                        ></u-steps>\n                        <view class=\"title\"> slot </view>\n                        <u-steps :direction=\"direction\" :current=\"current\" :mode=\"mode\" :icon=\"icon\">\n                            <u-step name=\"预约\">\n                                <template #desc>\n                                    <text v-show=\"current < 0\">自定义描述</text>\n                                    <text v-show=\"current >= 0\" class=\"custom-desc\">自定义描述</text>\n                                </template>\n                            </u-step>\n                            <u-step desc=\"10:30\">\n                                <template #name>\n                                    <text v-show=\"current < 1\">名额确认</text>\n                                    <text v-show=\"current >= 1\" class=\"custom-name\">名额不足</text>\n                                </template>\n                            </u-step>\n                            <u-step desc=\"11:00\">\n                                <template #name>\n                                    <text v-show=\"current < 2\">预约成功</text>\n                                    <text v-show=\"current >= 2\" class=\"custom-error-name\">预约失败</text>\n                                </template>\n                                <template #icon>\n                                    <u-icon size=\"32\" color=\"red\" name=\"close\"></u-icon>\n                                </template>\n                            </u-step>\n                        </u-steps>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">模式</view>\n                        <u-subsection :list=\"['number', 'dot']\" @change=\"modeChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">方向</view>\n                        <u-subsection :list=\"['横向', '竖向']\" @change=\"directionChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">自定义图标</view>\n                        <u-subsection :list=\"['否', '是']\" @change=\"iconChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">当前步值</view>\n                        <u-subsection\n                            :current=\"1\"\n                            :list=\"['0', '1', '2', '3', '4']\"\n                            @change=\"stepChange\"\n                        ></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, ref } from 'vue';\nimport type { StepDirection, StepMode } from '@/uni_modules/uview-pro/types/global';\n\nconst steps = computed(() => {\n    if (direction.value === 'row') {\n        return [\n            {\n                name: '下单',\n                desc: '10:30'\n            },\n            {\n                name: '出库',\n                desc: '11:00'\n            },\n            {\n                name: '运输',\n                desc: '14:00'\n            },\n            {\n                name: '签收',\n                desc: '18:30'\n            }\n        ];\n    } else {\n        return [\n            {\n                name: '下单',\n                desc: '10:30'\n            },\n            {\n                name: '出库',\n                desc: '这是一段超长描述这是一段超长描述这是一段超长描述这是一段超长描述这是一段超长描述这是一段超长描述这是一段超长描述这是一段超长描述这是一段超长描述这是一段超长描述'\n            },\n            {\n                name: '运输',\n                desc: '14:00'\n            },\n            {\n                name: '签收',\n                desc: '18:30'\n            }\n        ];\n    }\n});\n\nconst current = ref(0);\nconst icon = ref('checkmark');\nconst mode = ref<StepMode>('number');\nconst direction = ref<StepDirection>('row');\n\nfunction modeChange(index: number) {\n    mode.value = index === 0 ? 'number' : 'dot';\n}\n\nfunction stepChange(index: number) {\n    current.value = [-1, 0, 1, 2, 3][index];\n}\n\nfunction iconChange(index: number) {\n    icon.value = index === 0 ? 'checkmark' : 'map-fill';\n}\n\nfunction directionChange(index: number) {\n    direction.value = index === 0 ? 'row' : 'column';\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.wrap {\n    padding: 24rpx;\n}\n\n.box {\n    margin: 50rpx 0;\n}\n\n.title {\n    margin: 20rpx 0;\n    font-size: 30rpx;\n    position: relative;\n    line-height: 1;\n    padding-left: 22rpx;\n    text-align: left;\n\n    &:before {\n        width: 4px;\n        height: 15px;\n        border-radius: 100rpx;\n        background-color: $u-content-color;\n        content: '';\n        position: absolute;\n        left: 6rpx;\n        top: -1px;\n    }\n}\n\n.custom-name {\n    color: $u-type-warning;\n}\n\n.custom-error-name {\n    color: $u-type-error;\n}\n\n.custom-desc {\n    color: $u-type-error;\n    font-size: 18rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsB/sticky/index.vue",
    "content": "<template>\n    <demo-page title=\"Sticky 吸顶\" desc=\"用于吸顶功能，支持自定义吸顶高度和启用禁用。\" :apis=\"'sticky'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-toast ref=\"uToastRef\"></u-toast>\n                        <u-sticky :offset-top=\"offsetTop\" :enable=\"enable\" @fixed=\"fixed\" @unfixed=\"unfixed\">\n                            <view class=\"sticky\"> 宝剑锋从磨砺出,梅花香自苦寒来 </view>\n                        </u-sticky>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">吸顶高度</view>\n                        <u-subsection :current=\"2\" :list=\"['0', '120', '200']\" @change=\"offsetTopChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">状态</view>\n                        <u-subsection :list=\"['允许吸顶', '禁止吸顶']\" @change=\"enableChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\n\nconst offsetTop = ref(200);\nconst enable = ref(true);\nconst uToastRef = ref(null);\n\nfunction offsetTopChange(index: number) {\n    offsetTop.value = index === 0 ? 0 : index === 1 ? 120 : 200;\n    uni.pageScrollTo({\n        scrollTop: 0,\n        duration: 0\n    });\n}\n\nfunction enableChange(index: number) {\n    enable.value = index === 0 ? true : false;\n}\n\nfunction fixed() {\n    uToastRef.value.show({\n        type: 'warning',\n        title: '触发吸顶'\n    });\n}\n\nfunction unfixed() {\n    uToastRef.value.show({\n        type: 'success',\n        title: '取消吸顶'\n    });\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.u-demo-area {\n    overflow: hidden;\n}\n\n.u-config-wrap {\n    height: 200vh;\n}\n\n.u-demo-title {\n    margin-bottom: 140rpx;\n}\n\n.sticky {\n    background-color: $u-type-primary;\n    color: #fff;\n    padding: 24rpx;\n    margin: auto;\n    font-size: 28rpx;\n    line-height: 1;\n    border-radius: 5px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsB/swipeAction/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"SwipeAction 滑动操作\"\n        desc=\"用于滑动展示隐藏的操作按钮，支持自定义宽度和操作。\"\n        :apis=\"'swipeAction'\"\n    >\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-swipe-action\n                            :bg-color=\"$u.color.bgWhite\"\n                            @open=\"open\"\n                            :disabled=\"disabled\"\n                            :index=\"index\"\n                            v-for=\"(item, index) in list\"\n                            :key=\"item.id\"\n                            :show=\"item.show\"\n                            @click=\"click\"\n                            :btn-width=\"btnWidth\"\n                            @close=\"close\"\n                            :options=\"options\"\n                            @content-click=\"contentClick\"\n                        >\n                            <view class=\"item u-border-bottom\">\n                                <image mode=\"aspectFill\" :src=\"item.images\" />\n                                <!-- 此层wrap在此为必写的，否则可能会出现标题定位错误 -->\n                                <view class=\"title-wrap\">\n                                    <text class=\"title u-line-2\">{{ item.title }}</text>\n                                </view>\n                            </view>\n                        </u-swipe-action>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\">参数配置</view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">状态(操作第一个)</view>\n                        <u-subsection :current=\"1\" :list=\"['打开', '关闭']\" @change=\"showChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">禁止滑动</view>\n                        <u-subsection :current=\"1\" :list=\"['是', '否']\" @change=\"disabledChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { onLoad } from '@dcloudio/uni-app';\nimport { ref, nextTick } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\n\ndefineOptions({ name: 'SwipeActionDemo' });\n\n/**\n * 演示 swipeAction 组件的使用\n * 包含参数配置、事件处理等\n */\n\ninterface ListItem {\n    id: number;\n    title: string;\n    images: string;\n    show: boolean;\n}\n\nconst list1 = ref<ListItem[]>([\n    {\n        id: 1,\n        title: '长安回望绣成堆，山顶千门次第开，一骑红尘妃子笑，无人知是荔枝来',\n        images: 'https://ik.imagekit.io/anyup/uview-pro/common/logo-new.png',\n        show: false\n    },\n    {\n        id: 2,\n        title: '新丰绿树起黄埃，数骑渔阳探使回，霓裳一曲千峰上，舞破中原始下来',\n        images: 'https://ik.imagekit.io/anyup/uview-pro/common/logo-new.png',\n        show: false\n    },\n    {\n        id: 3,\n        title: '登临送目，正故国晚秋，天气初肃。千里澄江似练，翠峰如簇',\n        images: 'https://ik.imagekit.io/anyup/uview-pro/common/logo-new.png',\n        show: false\n    }\n]);\n\nconst list = ref<ListItem[]>([]);\nconst disabled = ref(false);\nconst btnWidth = ref<number>(180);\nconst show = ref(false);\nconst options = ref([\n    {\n        text: '收藏',\n        style: {\n            backgroundColor: '#007aff'\n        }\n    },\n    {\n        text: '删除',\n        style: {\n            backgroundColor: '#dd524d'\n        }\n    }\n]);\n\n// 页面加载时初始化数据\nonLoad(() => {\n    nextTick(() => {\n        list.value = list1.value.map(item => ({ ...item }));\n    });\n});\n\n/**\n * 禁止滑动切换\n */\nfunction disabledChange(index: number) {\n    disabled.value = index === 0;\n}\n\n/**\n * 状态切换（操作第一个）\n */\nfunction showChange(index: number) {\n    if (index === 0) {\n        list.value.forEach((val, ids) => {\n            val.show = ids === 0;\n        });\n    } else {\n        if (list.value[0]) list.value[0].show = false;\n    }\n}\n\n/**\n * 按钮点击事件\n */\nfunction click(index: number, index1: number) {\n    if (index1 === 1) {\n        list.value.splice(index, 1);\n        $u.toast(`删除了第${index + 1}个cell`);\n    } else {\n        if (list.value[index]) list.value[index].show = false;\n        $u.toast('收藏成功');\n    }\n}\n\n/**\n * 打开事件\n */\nfunction open(index: number) {\n    list.value[index].show = false;\n    list.value.forEach((val, idx) => {\n        val.show = idx === index;\n    });\n}\n\n/**\n * 关闭事件\n */\nfunction close(index: number) {\n    if (list.value[index]) list.value[index].show = false;\n}\n\n/**\n * 内容点击事件\n */\nfunction contentClick(index: number) {\n    // 可扩展内容点击逻辑\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.item {\n    display: flex;\n    padding: 20rpx;\n}\n\nimage {\n    width: 120rpx;\n    flex: 0 0 120rpx;\n    height: 120rpx;\n    margin-right: 20rpx;\n    border-radius: 12rpx;\n}\n\n.title {\n    text-align: left;\n    font-size: 28rpx;\n    color: $u-content-color;\n    margin-top: 20rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsB/swiper/image.ts",
    "content": "export const img1 =\n    'data:image/jpeg;base64,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';\n\nexport const img2 =\n    'data:image/jpeg;base64,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';\n\nexport const img3 =\n    'data:image/jpeg;base64,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';\n"
  },
  {
    "path": "src/pages/componentsB/swiper/index.vue",
    "content": "<template>\n    <demo-page title=\"Swiper 轮播\" desc=\"用于图片或内容轮播展示，支持多种指示器模式和自动播放。\" :apis=\"'swiper'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-swiper\n                            @change=\"change\"\n                            :height=\"250\"\n                            :list=\"list\"\n                            :title=\"title\"\n                            :effect3d=\"effect3d\"\n                            :indicator-pos=\"indicatorPos\"\n                            :mode=\"mode\"\n                            :interval=\"3000\"\n                            @click=\"click\"\n                        ></u-swiper>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">指示器模式</view>\n                        <u-subsection :list=\"['round', 'rect', 'number', 'none']\" @change=\"modeChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">标题</view>\n                        <u-subsection current=\"1\" :list=\"['显示', '隐藏']\" @change=\"titleChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">指示器位置</view>\n                        <u-subsection\n                            current=\"3\"\n                            :list=\"['上左', '上右', '下左', '下中', '下右']\"\n                            @change=\"indicatorPosChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">3D效果</view>\n                        <u-subsection current=\"1\" :list=\"['开启', '关闭']\" @change=\"effect3dChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\nimport type { SwiperIndicatorPosition, SwiperMode } from '@/uni_modules/uview-pro/types/global';\nimport { img1, img2, img3 } from './image';\n\nconst uToastRef = ref(null);\n\nconst list = ref([\n    {\n        image: img1,\n        title: '昨夜星辰昨夜风，画楼西畔桂堂东'\n    },\n    {\n        image: img2,\n        title: '身无彩凤双飞翼，心有灵犀一点通'\n    },\n    {\n        image: img3,\n        title: '谁念西风独自凉，萧萧黄叶闭疏窗，沉思往事立残阳'\n    }\n]);\n\nconst title = ref(false);\nconst mode = ref<SwiperMode>('round');\nconst indicatorPos = ref<SwiperIndicatorPosition>('bottomCenter');\nconst effect3d = ref(false);\n\nfunction titleChange(index: number) {\n    title.value = index === 0 ? true : false;\n}\n\nfunction modeChange(index: number) {\n    mode.value = index === 0 ? 'round' : index === 1 ? 'rect' : index === 2 ? 'number' : 'none';\n}\n\nfunction indicatorPosChange(index: number) {\n    indicatorPos.value =\n        index === 0\n            ? 'topLeft'\n            : index === 1\n              ? 'topRight'\n              : index === 2\n                ? 'bottomLeft'\n                : index === 3\n                  ? 'bottomCenter'\n                  : 'bottomRight';\n}\n\nfunction effect3dChange(index: number) {\n    effect3d.value = index === 0 ? true : false;\n}\n\nfunction click(index: number) {\n    uToastRef.value?.show({\n        title: `点击了第${index + 1}张图片`,\n        type: 'success'\n    });\n}\n\nfunction change(index: number) {\n    // console.log(index);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.item {\n    margin: 30rpx 0;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsB/switch/index.vue",
    "content": "<template>\n    <demo-page title=\"Switch 开关\" desc=\"用于开关切换，支持自定义颜色、大小和异步操作。\" :apis=\"'switch'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-switch\n                            v-model=\"modelValue\"\n                            :loading=\"loading\"\n                            :size=\"size\"\n                            @change=\"change\"\n                            :active-color=\"activeColor\"\n                            :disabled=\"disabled\"\n                            :activeValue=\"activeValue\"\n                            :inactiveValue=\"inactiveValue\"\n                        ></u-switch>\n                        <view>当前开关状态: {{ isChecked }}</view>\n                        <view>当前v-model: {{ modelValue }}</view>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">状态</view>\n                        <u-subsection :list=\"['关闭', '打开']\" @change=\"modelChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">颜色</view>\n                        <u-subsection\n                            :list=\"['primary', 'error', 'warning', 'success']\"\n                            @change=\"colorChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">尺寸(单位rpx)</view>\n                        <u-subsection current=\"1\" :list=\"['小', '中', '大', '80']\" @change=\"sizeChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">加载中</view>\n                        <u-subsection :list=\"['否', '是']\" @change=\"loadingChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">禁用</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"disabledChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">异步控制</view>\n                        <u-subsection :list=\"['关闭', '打开']\" @change=\"asyncChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref, computed } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\nimport type { SizeType } from '@/uni_modules/uview-pro/types/global';\n\ntype IModelValue = 1 | 100;\n\nconst activeValue = ref<IModelValue>(100);\nconst inactiveValue = ref<IModelValue>(1);\nconst modelValue = ref<IModelValue>(1);\nconst isChecked = computed<boolean>(() => modelValue.value === activeValue.value);\nconst activeColor = ref($u.color.primary);\nconst size = ref<SizeType | string | number>('default');\nconst loading = ref(false);\nconst disabled = ref(false);\n\nfunction modelChange(index: number) {\n    // 两个!!可以把0变成false，1变成true\n    modelValueChange(!!index);\n}\n\nfunction modelValueChange(value: boolean) {\n    modelValue.value = value ? activeValue.value : inactiveValue.value;\n}\n\nfunction colorChange(index: number) {\n    const color = index === 0 ? 'primary' : index === 1 ? 'error' : index === 2 ? 'warning' : 'success';\n    activeColor.value = $u.color[color];\n}\n\nfunction sizeChange(index: number) {\n    if (index > 2) {\n        size.value = 80;\n    } else {\n        size.value = index === 0 ? 'small' : index === 1 ? 'default' : 'large';\n    }\n}\n\nfunction loadingChange(index: number) {\n    loading.value = !!index;\n}\n\nfunction disabledChange(index: number) {\n    disabled.value = index === 0 ? true : false;\n}\n\nfunction asyncChange(index: number) {\n    if (isChecked.value && index === 1) {\n        $u.toast('请先关闭选择器');\n        return;\n    }\n    if (!isChecked.value && index === 0) {\n        $u.toast('请先打开选择器');\n        return;\n    }\n    const str = index === 0 ? '是否要关闭？' : '是否要打开？';\n    loading.value = true;\n    const oldStatus = isChecked.value;\n    modelValueChange(true);\n    uni.showModal({\n        title: '提示',\n        content: str,\n        complete: (res: { confirm: boolean }) => {\n            loading.value = false;\n            if (res.confirm) {\n                modelValueChange(!oldStatus);\n            } else {\n                modelValueChange(!!oldStatus);\n            }\n        }\n    });\n}\n\nfunction change(value: any) {\n    // console.log(value);\n}\n</script>\n"
  },
  {
    "path": "src/pages/componentsB/tabbar/index.vue",
    "content": "<template>\n    <demo-page title=\"Tabbar 标签栏\" desc=\"用于展示应用底部导航栏，支持自定义颜色、中间按钮和徽标。\" :apis=\"'tabbar'\">\n        <template #default>\n            <view>\n                <view class=\"u-demo\">\n                    <view class=\"u-config-wrap\">\n                        <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                        <view class=\"u-config-item\">\n                            <view class=\"u-item-title\">状态</view>\n                            <u-subsection :list=\"['显示', '隐藏']\" @change=\"showChange\"></u-subsection>\n                        </view>\n                        <view class=\"u-config-item\">\n                            <view class=\"u-item-title\">凸起按钮</view>\n                            <u-subsection :list=\"['显示', '隐藏']\" @change=\"minButtonChange\"></u-subsection>\n                        </view>\n                        <view class=\"u-config-item\">\n                            <view class=\"u-item-title\">文字</view>\n                            <u-subsection :list=\"['显示', '隐藏']\" @change=\"textShowChange\"></u-subsection>\n                        </view>\n                        <view class=\"u-config-item\">\n                            <view class=\"u-item-title\">图标</view>\n                            <u-subsection :list=\"['显示', '隐藏']\" @change=\"iconShowChange\"></u-subsection>\n                        </view>\n                        <view class=\"u-config-item\">\n                            <view class=\"u-item-title\">背景色</view>\n                            <u-subsection :list=\"['#ffffff', '#1f1f1d']\" @change=\"bgColorChange\"></u-subsection>\n                        </view>\n                        <view class=\"u-config-item\">\n                            <view class=\"u-item-title\">顶部边框</view>\n                            <u-subsection :list=\"['显示', '隐藏']\" @change=\"borderTopChange\"></u-subsection>\n                        </view>\n                        <view class=\"u-config-item\">\n                            <view class=\"u-item-title\">提示角标</view>\n                            <u-subsection :list=\"['显示', '隐藏']\" @change=\"badgeChange\"></u-subsection>\n                        </view>\n                    </view>\n                </view>\n                <u-tabbar\n                    v-model=\"current\"\n                    :show=\"show\"\n                    :bg-color=\"bgColor\"\n                    :border-top=\"borderTop\"\n                    :list=\"list\"\n                    :mid-button=\"midButton\"\n                    :inactive-color=\"inactiveColor\"\n                    :activeColor=\"activeColor\"\n                ></u-tabbar>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport type { TabbarItem } from '@/uni_modules/uview-pro/types/global';\nimport { $u } from 'uview-pro';\nimport { ref } from 'vue';\n\nconst current = ref(0);\nconst show = ref(true);\nconst bgColor = ref('#ffffff');\nconst borderTop = ref(true);\nconst originList: TabbarItem[] = [\n    {\n        iconPath: 'home',\n        selectedIconPath: 'home-fill',\n        text: '首页',\n        count: 2,\n        isDot: true,\n        customIcon: false\n    },\n    {\n        iconPath: 'photo',\n        selectedIconPath: 'photo-fill',\n        text: '放映厅',\n        customIcon: false\n    },\n    {\n        iconPath: '/static/uview/example/min_button.png',\n        selectedIconPath: '/static/uview/example/min_button_select.png',\n        text: '发布',\n        midButton: true,\n        customIcon: false\n    },\n    {\n        iconPath: 'play-right',\n        selectedIconPath: 'play-right-fill',\n        text: '直播',\n        customIcon: false\n    },\n    {\n        iconPath: 'account',\n        selectedIconPath: 'account-fill',\n        text: '我的',\n        count: 23,\n        isDot: false,\n        customIcon: false\n    }\n];\nconst list = ref<TabbarItem[]>($u.deepClone(originList));\nconst midButton = ref(true);\nconst inactiveColor = ref('#909399');\nconst activeColor = ref('#5098FF');\n\nfunction textShowChange(index: number) {\n    if (index === 1) {\n        list.value.forEach(item => {\n            item.text = '';\n            item.iconSize = 50;\n        });\n        midButton.value = false;\n    } else {\n        list.value = $u.deepClone(originList);\n        midButton.value = true;\n    }\n}\n\nfunction iconShowChange(index: number) {\n    if (index === 1) {\n        list.value.forEach(item => {\n            item.iconPath = '';\n            item.selectedIconPath = '';\n            item.textSize = 36;\n        });\n        midButton.value = false;\n    } else {\n        list.value = $u.deepClone(originList);\n        midButton.value = true;\n    }\n}\n\nfunction showChange(index: number) {\n    show.value = !index;\n}\n\nfunction bgColorChange(index: number) {\n    if (index === 0) {\n        activeColor.value = '#5098FF';\n        inactiveColor.value = '#909399';\n    }\n    if (index === 1) {\n        activeColor.value = '#D0D0D0';\n        inactiveColor.value = '#5A5A5A';\n    }\n    bgColor.value = ['#ffffff', '#1f1f1d'][index];\n}\n\nfunction borderTopChange(index: number) {\n    borderTop.value = !index;\n}\n\nfunction badgeChange(index: number) {\n    if (index === 1) {\n        list.value[0].count = 0;\n        list.value[4].count = 0;\n    } else {\n        list.value[0].count = 2;\n        list.value[4].count = 23;\n    }\n}\n\nfunction minButtonChange(index: number) {\n    midButton.value = !index;\n}\n</script>\n\n<style scoped lang=\"scss\">\n.u-demo-area {\n    margin: 0 -40rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsB/table/index.vue",
    "content": "<template>\n    <demo-page title=\"Table 表格\" desc=\"用于展示表格数据，支持自定义对齐方式和边框颜色。\" :apis=\"'table'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-toast ref=\"uToastRef\"></u-toast>\n                        <u-table :align=\"align\" :borderColor=\"borderColor\">\n                            <u-tr class=\"u-tr\">\n                                <u-th class=\"u-th\">姓名</u-th>\n                                <u-th class=\"u-th\">年龄</u-th>\n                                <u-th class=\"u-th\">性别</u-th>\n                                <u-th class=\"u-th\">其他描述</u-th>\n                            </u-tr>\n                            <u-tr class=\"u-tr\">\n                                <u-td class=\"u-td\">吕布</u-td>\n                                <u-td class=\"u-td\">22</u-td>\n                                <u-td class=\"u-td\">男</u-td>\n                                <u-td class=\"u-td\">我是吕布，地表最强</u-td>\n                            </u-tr>\n                            <u-tr class=\"u-tr\">\n                                <u-td class=\"u-td\">项羽</u-td>\n                                <u-td class=\"u-td\">28</u-td>\n                                <u-td class=\"u-td\">男</u-td>\n                                <u-td class=\"u-td\">楚霸王</u-td>\n                            </u-tr>\n                            <u-tr class=\"u-tr\">\n                                <u-td class=\"u-td\">木兰</u-td>\n                                <u-td class=\"u-td\">24</u-td>\n                                <u-td class=\"u-td\">女</u-td>\n                                <u-td class=\"u-td\">花木兰替父从军</u-td>\n                            </u-tr>\n                        </u-table>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">边框颜色</view>\n                        <u-subsection :list=\"['gray', 'primary', 'warning']\" @change=\"borderColorChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">对齐方式</view>\n                        <u-subsection current=\"1\" :list=\"['左', '中', '右']\" @change=\"alignChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\nimport type { TextAlign } from '@/uni_modules/uview-pro/types/global';\n\nconst mode = ref(false);\nconst borderColor = ref('#e4e7ed');\nconst align = ref<TextAlign>('center');\nconst uToastRef = ref(null);\n\nfunction modeChange(index: number): void {\n    // #ifdef MP-WEIXIN\n    return $u.toast('微信小程序暂不支持单元格合并');\n    // #endif\n    mode.value = index === 0;\n    // 注意：原代码中有 this.key++，但在data中没有定义key属性\n    // 如果需要key属性，请添加 const key = ref<number>(0);\n}\n\nfunction borderColorChange(index: number) {\n    borderColor.value = index === 0 ? '#e4e7ed' : index === 1 ? $u.color.primary : '#ff9900';\n}\n\nfunction alignChange(index: number) {\n    align.value = index === 0 ? 'left' : index === 1 ? 'center' : 'right';\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.wrap {\n    padding: 24rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsB/transition/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"Transition 过渡动画\"\n        desc=\"统一的过渡与进出场动效封装，支持多种预设、模式以及自定义时长/曲线/延迟。\"\n        :apis=\"'transition'\"\n        experience-key=\"component-transition\"\n    >\n        <view class=\"u-demo\">\n            <view class=\"u-demo-wrap\">\n                <view class=\"u-demo-title\">交互演示</view>\n                <view class=\"u-demo-area\">\n                    <view class=\"transition-preview u-border\">\n                        <view class=\"preview-header\">\n                            <view class=\"preset-pill\">{{ presetLabels[presetIndex] }}</view>\n                            <u-button size=\"mini\" type=\"primary\" :throttle-time=\"0\" @click=\"toggleShow\">\n                                {{ show ? '隐藏内容' : '显示内容' }}\n                            </u-button>\n                        </view>\n                        <u-transition\n                            custom-class=\"transition-preview__transition\"\n                            :show=\"show\"\n                            :name=\"activePreset\"\n                            :mode=\"activeMode\"\n                            :duration=\"previewDuration\"\n                            :delay=\"delay\"\n                            :timing-function=\"timingFunction\"\n                            :appear=\"appear\"\n                            :custom-style=\"customStyle\"\n                            @before-enter=\"handleEvent('before-enter')\"\n                            @enter=\"handleEvent('enter')\"\n                            @after-enter=\"handleEvent('after-enter')\"\n                            @before-leave=\"handleEvent('before-leave')\"\n                            @leave=\"handleEvent('leave')\"\n                            @after-leave=\"handleEvent('after-leave')\"\n                        >\n                            <view class=\"preview-card\">\n                                <view class=\"preview-card__title\">{{ presetLabels[presetIndex] }}</view>\n                                <view class=\"preview-card__desc\">\n                                    模式：{{ modeLabels[modeIndex] }} · 延迟 {{ delay }}ms · 时长 {{ enterDuration }} /\n                                    {{ leaveDuration }}ms\n                                </view>\n                                <view class=\"preview-card__badge\">{{ timingLabels[timingIndex] }}</view>\n                            </view>\n                        </u-transition>\n                        <view class=\"preview-meta\">\n                            <view>appear：{{ appear ? '启用' : '关闭' }}</view>\n                            <view>timing：{{ timingFunction }}</view>\n                        </view>\n                    </view>\n                    <view class=\"transition-gallery u-border\">\n                        <view class=\"gallery-header\">\n                            预设集合\n                            <text class=\"gallery-subtitle\">点击重播以查看不同预设的进出场表现</text>\n                        </view>\n                        <view class=\"gallery-grid\">\n                            <view class=\"gallery-item\" v-for=\"preset in presets\" :key=\"preset\">\n                                <view class=\"gallery-item__head\">\n                                    <text>{{ presetMap[preset] }}</text>\n                                    <u-button\n                                        size=\"mini\"\n                                        type=\"primary\"\n                                        plain\n                                        :throttle-time=\"0\"\n                                        @click=\"triggerGallery(preset)\"\n                                    >\n                                        重播\n                                    </u-button>\n                                </view>\n                                <u-transition\n                                    :show=\"galleryVisible[preset]\"\n                                    :name=\"preset\"\n                                    :duration=\"galleryDuration\"\n                                    appear\n                                >\n                                    <view class=\"gallery-chip\">\n                                        <text>{{ preset }}</text>\n                                    </view>\n                                </u-transition>\n                            </view>\n                        </view>\n                    </view>\n                </view>\n            </view>\n            <view class=\"u-config-wrap\">\n                <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">预设动画</view>\n                    <u-subsection\n                        :current=\"presetIndex\"\n                        :list=\"presetLabels\"\n                        @change=\"handlePresetChange\"\n                    ></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">模式</view>\n                    <u-subsection :current=\"modeIndex\" :list=\"modeLabels\" @change=\"handleModeChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">首次渲染执行 appear</view>\n                    <u-switch v-model=\"appear\"></u-switch>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">延迟 (ms)</view>\n                    <u-number-box v-model=\"delay\" :step=\"50\" :min=\"0\" :max=\"1500\"></u-number-box>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">进入时长 (ms)</view>\n                    <u-number-box v-model=\"enterDuration\" :step=\"50\" :min=\"100\" :max=\"2000\"></u-number-box>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">离开时长 (ms)</view>\n                    <u-number-box v-model=\"leaveDuration\" :step=\"50\" :min=\"100\" :max=\"2000\"></u-number-box>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">曲线</view>\n                    <u-subsection\n                        :current=\"timingIndex\"\n                        :list=\"timingLabels\"\n                        @change=\"handleTimingChange\"\n                    ></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">自定义样式</view>\n                    <u-switch v-model=\"useCustomStyle\"></u-switch>\n                </view>\n                <view class=\"u-config-item\" v-if=\"useCustomStyle\">\n                    <view class=\"u-item-title\">主题色</view>\n                    <u-subsection\n                        :current=\"accentIndex\"\n                        :list=\"accentPalette.map(item => item.label)\"\n                        @change=\"handleAccentChange\"\n                    ></u-subsection>\n                </view>\n            </view>\n        </view>\n        <view class=\"u-demo-wrap event-section\">\n            <view class=\"u-demo-title\">事件日志</view>\n            <view class=\"event-log u-border\">\n                <view v-if=\"!eventLogs.length\" class=\"event-log__empty\">触发动画以查看事件回调</view>\n                <view v-for=\"(log, index) in eventLogs\" :key=\"index\" class=\"event-log__item\">\n                    {{ log }}\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, ref, watch } from 'vue';\nimport { completeMission, useExperience } from '@/common/useExperience';\nimport type { TransitionPreset } from '@/uni_modules/uview-pro/types/global';\n\nconst presets: TransitionPreset[] = [\n    'fade',\n    'slide-up',\n    'slide-down',\n    'slide-left',\n    'slide-right',\n    'zoom-in',\n    'zoom-out'\n];\nconst presetMap: Record<TransitionPreset, string> = {\n    fade: 'Fade 淡入',\n    'slide-up': 'Slide Up 上滑',\n    'slide-down': 'Slide Down 下滑',\n    'slide-left': 'Slide Left 左滑',\n    'slide-right': 'Slide Right 右滑',\n    'zoom-in': 'Zoom In 放大',\n    'zoom-out': 'Zoom Out 缩小'\n};\nconst presetLabels = presets.map(preset => presetMap[preset]);\n\nconst modeLabels = ['默认', 'out-in', 'in-out'];\nconst modeValues: Array<'' | 'out-in' | 'in-out'> = ['', 'out-in', 'in-out'];\n\nconst timingOptions = [\n    { label: '标准', value: 'cubic-bezier(0.2, 0.8, 0.2, 1)' },\n    { label: '线性', value: 'linear' },\n    { label: 'ease-in-out', value: 'ease-in-out' },\n    { label: '回弹', value: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)' }\n];\nconst timingLabels = timingOptions.map(item => item.label);\n\nconst accentPalette = [\n    { label: '亮蓝', background: '#edf4ff', color: '#165dff' },\n    { label: '果绿', background: '#f1ffef', color: '#51c41a' },\n    { label: '橙色', background: '#fff7e6', color: '#f77234' }\n];\n\nconst presetIndex = ref(0);\nconst modeIndex = ref(0);\nconst timingIndex = ref(0);\nconst accentIndex = ref(0);\n\nconst show = ref(true);\nconst appear = ref(false);\nconst delay = ref(0);\nconst enterDuration = ref(320);\nconst leaveDuration = ref(280);\nconst useCustomStyle = ref(false);\n\nconst galleryVisible = ref<Record<TransitionPreset, boolean>>(\n    presets.reduce(\n        (acc, preset) => {\n            acc[preset] = true;\n            return acc;\n        },\n        {} as Record<TransitionPreset, boolean>\n    )\n);\n\nconst eventLogs = ref<string[]>([]);\n\nconst { completeTask, recordAction } = useExperience('component-transition');\n\nconst activePreset = computed(() => presets[presetIndex.value]);\nconst activeMode = computed(() => modeValues[modeIndex.value]);\nconst timingFunction = computed(() => timingOptions[timingIndex.value].value);\nconst durationPayload = computed(() => {\n    if (enterDuration.value === leaveDuration.value) {\n        return enterDuration.value;\n    }\n    return {\n        enter: enterDuration.value,\n        leave: leaveDuration.value\n    };\n});\nconst previewDuration = computed(() => durationPayload.value as any);\nconst galleryDuration = { enter: 240, leave: 200 } as any;\n\nconst customStyle = computed(() => {\n    if (!useCustomStyle.value) {\n        return '';\n    }\n    const palette = accentPalette[accentIndex.value];\n    return {\n        background: palette.background,\n        color: palette.color,\n        borderColor: palette.color\n    };\n});\n\nconst handlePresetChange = (index: number) => {\n    presetIndex.value = index;\n    completeTask('preset');\n    recordAction(`切换预设：${presetLabels[index]}`);\n    replayPreview();\n};\n\nconst handleModeChange = (index: number) => {\n    modeIndex.value = index;\n    completeTask('mode');\n    recordAction(`切换模式：${modeLabels[index]}`);\n    replayPreview();\n};\n\nconst handleTimingChange = (index: number) => {\n    timingIndex.value = index;\n    completeTask('timing');\n    recordAction(`切换曲线：${timingLabels[index]}`);\n};\n\nconst handleAccentChange = (index: number) => {\n    accentIndex.value = index;\n    completeTask('style');\n    recordAction(`切换主题色：${accentPalette[index].label}`);\n};\n\nconst toggleShow = () => {\n    show.value = !show.value;\n    completeTask('toggle');\n    recordAction(`切换显示：${show.value ? '显示' : '隐藏'}`);\n    completeMission('transition');\n};\n\nconst replayPreview = () => {\n    show.value = false;\n    // 小延迟重新触发 enter，让过渡立即可见\n    setTimeout(() => {\n        show.value = true;\n    }, 20);\n};\n\nconst triggerGallery = (preset: TransitionPreset) => {\n    galleryVisible.value = {\n        ...galleryVisible.value,\n        [preset]: false\n    };\n    setTimeout(() => {\n        galleryVisible.value = {\n            ...galleryVisible.value,\n            [preset]: true\n        };\n    }, 20);\n    recordAction(`重播预设：${presetMap[preset]}`);\n};\n\nconst handleEvent = (eventName: string) => {\n    const time = new Date().toLocaleTimeString();\n    eventLogs.value = [`${time} · ${eventName}`, ...eventLogs.value].slice(0, 6);\n};\n\nwatch(appear, value => {\n    recordAction(`设置 appear：${value ? '开启' : '关闭'}`);\n});\n\nwatch(delay, value => {\n    recordAction(`修改延迟：${value}ms`);\n});\n\nwatch([enterDuration, leaveDuration], ([enter, leave]) => {\n    recordAction(`修改时长：enter ${enter} / leave ${leave} ms`);\n});\n\nwatch(useCustomStyle, value => {\n    recordAction(`自定义样式：${value ? '启用' : '关闭'}`);\n});\n</script>\n\n<style lang=\"scss\" scoped>\n.transition-preview,\n.transition-gallery,\n.event-log {\n    border-radius: 16rpx;\n    padding: 24rpx;\n    background: $u-bg-white;\n}\n\n.preview-header {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    margin-bottom: 20rpx;\n}\n\n.preset-pill {\n    padding: 8rpx 16rpx;\n    border-radius: 999rpx;\n    background: $u-bg-color;\n    font-size: 26rpx;\n    color: $u-content-color;\n}\n\n.transition-preview__transition {\n    width: 100%;\n}\n\n.preview-card {\n    width: 100%;\n    border-radius: 12rpx;\n    border: 1px solid $u-border-color;\n    padding: 32rpx;\n    background: $u-bg-white;\n}\n\n.preview-card__title {\n    font-size: 32rpx;\n    font-weight: 600;\n    margin-bottom: 12rpx;\n}\n\n.preview-card__desc {\n    font-size: 26rpx;\n    color: $u-content-color;\n    margin-bottom: 16rpx;\n}\n\n.preview-card__badge {\n    display: inline-flex;\n    align-items: center;\n    padding: 4rpx 12rpx;\n    border-radius: 999rpx;\n    font-size: 24rpx;\n    background: rgba(22, 93, 255, 0.08);\n    color: $u-type-primary;\n}\n\n.preview-meta {\n    display: flex;\n    justify-content: space-between;\n    font-size: 24rpx;\n    color: $u-tips-color;\n    margin-top: 20rpx;\n}\n\n.transition-gallery {\n    margin-top: 32rpx;\n}\n\n.gallery-header {\n    font-size: 30rpx;\n    font-weight: 600;\n    margin-bottom: 20rpx;\n    display: flex;\n    flex-direction: column;\n}\n\n.gallery-subtitle {\n    font-size: 24rpx;\n    color: $u-tips-color;\n    margin-top: 4rpx;\n}\n\n.gallery-grid {\n    display: grid;\n    grid-template-columns: repeat(auto-fill, minmax(220rpx, 1fr));\n    gap: 20rpx;\n}\n\n.gallery-item {\n    padding: 16rpx;\n    border-radius: 12rpx;\n    border: 1px dashed $u-border-color;\n}\n\n.gallery-item__head {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    font-size: 26rpx;\n    color: $u-content-color;\n    margin-bottom: 12rpx;\n}\n\n.gallery-chip {\n    padding: 24rpx 30rpx;\n    text-align: center;\n    border-radius: 12rpx;\n    background: $u-bg-color;\n    color: $u-type-primary;\n    font-weight: 500;\n    font-size: 28rpx;\n}\n\n.event-section {\n    margin-top: 32rpx;\n}\n\n.event-log__empty {\n    text-align: center;\n    color: $u-tips-color;\n    padding: 32rpx 0;\n}\n\n.event-log__item {\n    font-size: 26rpx;\n    color: $u-main-color;\n    padding: 8rpx 0;\n    border-bottom: 1px solid $u-border-color;\n}\n\n.event-log__item:last-child {\n    border-bottom: none;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsB/upload/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"Upload 上传\"\n        desc=\"用于文件上传，支持图片、视频、文档等多种文件类型，支持多个文件、进度显示和自定义样式。\"\n        :apis=\"'upload'\"\n    >\n        <template #default>\n            <view class=\"u-demo\">\n                <!-- 基础用法 - 图片上传（网格模式） -->\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">基础用法 - 图片上传</view>\n                    <view class=\"u-demo-area\">\n                        <u-upload\n                            ref=\"imageUploadRef\"\n                            v-model=\"imageList\"\n                            accept=\"image\"\n                            :action=\"action\"\n                            :image-shape=\"imageShape\"\n                            :max-count=\"6\"\n                        />\n                    </view>\n                </view>\n\n                <!-- 文件上传 - 列表模式 -->\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">文件上传 - 列表模式</view>\n                    <view class=\"u-demo-area\">\n                        <u-upload\n                            ref=\"fileUploadRef\"\n                            v-model=\"fileList\"\n                            accept=\"file\"\n                            mode=\"list\"\n                            :action=\"action\"\n                            :image-shape=\"imageShape\"\n                            :max-count=\"5\"\n                            :show-file-name=\"true\"\n                            :show-file-size=\"true\"\n                        />\n                    </view>\n                </view>\n\n                <!-- 视频上传 -->\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">视频上传</view>\n                    <view class=\"u-demo-area\">\n                        <u-upload\n                            ref=\"videoUploadRef\"\n                            v-model=\"videoList\"\n                            accept=\"video\"\n                            :action=\"action\"\n                            :image-shape=\"imageShape\"\n                            :max-count=\"2\"\n                            :max-duration=\"60\"\n                            :show-file-name=\"true\"\n                        />\n                    </view>\n                </view>\n\n                <!-- 手动上传示例 -->\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">手动上传（点击按钮开始上传）</view>\n                    <view class=\"u-demo-area\">\n                        <u-upload\n                            ref=\"manualUploadRef\"\n                            v-model=\"manualList\"\n                            accept=\"image\"\n                            :action=\"action\"\n                            :image-shape=\"imageShape\"\n                            :auto-upload=\"false\"\n                            :max-count=\"3\"\n                            @on-choose-complete=\"onManualChooseComplete\"\n                        />\n                        <view class=\"u-btn-group\">\n                            <u-button\n                                :custom-style=\"{ marginTop: '20rpx' }\"\n                                type=\"primary\"\n                                :disabled=\"manualList.length === 0\"\n                                @click=\"startManualUpload\"\n                            >\n                                开始上传\n                            </u-button>\n                            <u-button\n                                :custom-style=\"{ marginTop: '20rpx', marginLeft: '20rpx' }\"\n                                @click=\"clearManualList\"\n                            >\n                                清空列表\n                            </u-button>\n                        </view>\n                    </view>\n                </view>\n\n                <!-- 自定义上传按钮 -->\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">自定义上传按钮</view>\n                    <view class=\"u-demo-area\">\n                        <u-upload\n                            ref=\"customUploadRef\"\n                            v-model=\"customList\"\n                            accept=\"image\"\n                            :action=\"action\"\n                            :image-shape=\"imageShape\"\n                            :custom-btn=\"true\"\n                            :max-count=\"3\"\n                        >\n                            <template #addBtn>\n                                <view\n                                    class=\"custom-upload-btn\"\n                                    hover-class=\"custom-upload-btn__hover\"\n                                    hover-stay-time=\"150\"\n                                >\n                                    <u-icon name=\"photo\" size=\"48\" color=\"#2979ff\"></u-icon>\n                                    <text class=\"custom-upload-text\">点击上传图片</text>\n                                </view>\n                            </template>\n                        </u-upload>\n                    </view>\n                </view>\n\n                <!-- 自定义文件列表展示 -->\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">自定义文件列表（使用 file 插槽）</view>\n                    <view class=\"u-demo-area\">\n                        <u-upload\n                            ref=\"customFileListRef\"\n                            v-model=\"customFileList\"\n                            accept=\"file\"\n                            mode=\"list\"\n                            :action=\"action\"\n                            :show-upload-list=\"false\"\n                            :custom-btn=\"true\"\n                            :max-count=\"5\"\n                        >\n                            <template #file=\"{ file }\">\n                                <view class=\"custom-file-list\">\n                                    <view v-for=\"(item, index) in file\" :key=\"index\" class=\"custom-file-item\">\n                                        <u-icon\n                                            :name=\"isImageFile(item) ? 'photo' : 'file-text'\"\n                                            size=\"40\"\n                                            color=\"var(--u-type-primary)\"\n                                        />\n                                        <view class=\"custom-file-info\">\n                                            <text class=\"custom-file-name\">{{ item.name || '未命名文件' }}</text>\n                                            <text v-if=\"item.size\" class=\"custom-file-size\">\n                                                {{ formatSize(item.size) }}\n                                            </text>\n                                        </view>\n                                        <view\n                                            v-if=\"item.progress < 100 && item.progress > 0\"\n                                            class=\"custom-file-progress\"\n                                        >\n                                            <u-line-progress :percent=\"item.progress\" height=\"8\" />\n                                        </view>\n                                        <view class=\"custom-file-status\">\n                                            <u-icon\n                                                v-if=\"item.progress === 100\"\n                                                :name=\"item.error ? 'close-circle' : 'checkmark-circle'\"\n                                                size=\"34\"\n                                                :color=\"item.error ? 'var(--u-type-error)' : 'var(--u-type-success)'\"\n                                            />\n                                            <text v-else class=\"custom-file-progress-text\">\n                                                {{ Math.floor(item.progress || 0) }}%\n                                            </text>\n                                        </view>\n                                        <view class=\"custom-file-delete\" @click=\"removeCustomFile(index)\">\n                                            <u-icon name=\"close\" size=\"24\" color=\"var(--u-tips-color)\" />\n                                        </view>\n                                    </view>\n                                </view>\n                            </template>\n                            <template #addBtn>\n                                <view class=\"custom-file-add-btn\">\n                                    <u-icon name=\"plus\" size=\"32\" color=\"var(--u-type-primary)\" />\n                                    <text class=\"custom-file-add-text\">添加文件</text>\n                                </view>\n                            </template>\n                        </u-upload>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { useToast } from '@/uni_modules/uview-pro';\nimport type { UploadFileItem } from '@/uni_modules/uview-pro/types/global';\n\nconst toast = useToast();\n\n// 上传地址（实际使用请替换为真实地址，演示使用模拟上传）\nconst action = ref<string>('https://example.com/upload');\n\n// 各上传组件引用\nconst imageUploadRef = ref();\nconst fileUploadRef = ref();\nconst manualUploadRef = ref();\nconst videoUploadRef = ref();\nconst customUploadRef = ref();\nconst customFileListRef = ref();\n\nconst imageShape = ref<string>('square');\n\n// 文件列表\nconst imageList = ref<UploadFileItem[]>([\n    {\n        url: 'https://ik.imagekit.io/anyup/uview-pro/common/logo-new.png',\n        name: 'logo.png',\n        size: 1024 * 50,\n        error: false,\n        progress: 100\n    }\n]);\n\nconst fileList = ref<UploadFileItem[]>([\n    {\n        url: 'https://example.com/document.pdf',\n        name: '示例文档.pdf',\n        size: 1024 * 1024 * 2.5,\n        error: false,\n        progress: 100\n    }\n]);\n\nconst videoList = ref<UploadFileItem[]>([\n    {\n        url: 'https://example.com/video.mp4',\n        name: '示例视频.mp4',\n        size: 1024 * 1024 * 2.5,\n        error: false,\n        progress: 100\n    }\n]);\n\nconst manualList = ref<UploadFileItem[]>([]);\nconst customList = ref<UploadFileItem[]>([]);\nconst customFileList = ref<UploadFileItem[]>([\n    {\n        url: 'https://example.com/report.pdf',\n        name: '年度报告.pdf',\n        size: 1024 * 1024 * 3.2,\n        error: false,\n        progress: 100\n    },\n    {\n        url: 'https://example.com/contract.docx',\n        name: '合同文档.docx',\n        size: 1024 * 450,\n        error: false,\n        progress: 100\n    }\n]);\n\n// 模拟上传函数\nfunction mockUpload(uploadRef: any, listRef: UploadFileItem[]) {\n    const lists = uploadRef?.lists as UploadFileItem[];\n    if (!lists || lists.length === 0) return;\n\n    lists.forEach((item: UploadFileItem, index: number) => {\n        // 只处理未上传或上传失败的文件\n        if (item.progress === 100 && !item.error) return;\n\n        const shouldSuccess = Math.random() > 0.1; // 90%成功率\n        const totalTime = 2000 + Math.random() * 2000; // 2-4秒\n        const interval = 100;\n        const step = 100 / (totalTime / interval);\n\n        let progress = item.progress || 0;\n        const timer = setInterval(() => {\n            progress += step;\n            if (progress >= 100) {\n                progress = 100;\n                clearInterval(timer);\n\n                lists[index].progress = 100;\n                if (shouldSuccess) {\n                    lists[index].error = false;\n                    lists[index].response = { code: 200, message: 'success', url: lists[index].url };\n                    toast.success('上传成功');\n                } else {\n                    lists[index].error = true;\n                    toast.error('上传失败');\n                }\n            } else {\n                lists[index].progress = Math.floor(progress);\n            }\n        }, interval);\n    });\n}\n\n// 手动上传\nfunction startManualUpload() {\n    mockUpload(manualUploadRef.value, manualList.value);\n}\n\n// 清空手动上传列表\nfunction clearManualList() {\n    manualUploadRef.value?.clear();\n    toast.success('已清空');\n}\n\n// 手动选择完成回调\nfunction onManualChooseComplete() {\n    toast.success('选择完成，点击\"开始上传\"按钮上传');\n}\n\n// 判断是否为图片文件\nfunction isImageFile(item: UploadFileItem): boolean {\n    const ext = item.name?.split('.').pop()?.toLowerCase() || '';\n    return ['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp', 'svg'].includes(ext);\n}\n\n// 格式化文件大小\nfunction formatSize(bytes: number): string {\n    if (bytes === 0) return '0 B';\n    const k = 1024;\n    const sizes = ['B', 'KB', 'MB', 'GB'];\n    const i = Math.floor(Math.log(bytes) / Math.log(k));\n    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n}\n\n// 删除自定义文件列表中的文件\nfunction removeCustomFile(index: number) {\n    customFileListRef.value?.remove(index);\n}\n</script>\n\n<style lang=\"scss\">\n.u-demo-wrap {\n    background-color: var(--u-bg-white);\n    padding: 40rpx 8rpx;\n    margin-left: -14rpx;\n    margin-right: -14rpx;\n    margin-bottom: 20rpx;\n}\n\n.u-demo-title {\n    font-size: 28rpx;\n    font-weight: bold;\n    color: var(--u-main-color);\n    margin-bottom: 20rpx;\n}\n\n.u-demo-area {\n    padding: 10rpx 0;\n}\n\n.u-btn-group {\n    display: flex;\n    flex-wrap: wrap;\n}\n\n// 自定义上传按钮样式\n.custom-upload-btn {\n    width: 200rpx;\n    height: 200rpx;\n    display: flex;\n    flex-direction: column;\n    justify-content: center;\n    align-items: center;\n    background: var(--u-bg-gray-light);\n    border-radius: 10rpx;\n    border: 2rpx dashed var(--u-border-color);\n}\n\n.custom-upload-btn__hover {\n    background-color: var(--u-bg-gray-light);\n    opacity: 0.8;\n}\n\n.custom-upload-text {\n    margin-top: 16rpx;\n    font-size: 24rpx;\n    color: var(--u-tips-color);\n}\n\n// 自定义文件列表样式\n.custom-file-list {\n    width: 100%;\n    margin-bottom: 20rpx;\n}\n\n.custom-file-item {\n    display: flex;\n    align-items: center;\n    padding: 24rpx;\n    background: var(--u-bg-white);\n    border-radius: 12rpx;\n    margin-bottom: 16rpx;\n    border: 1rpx solid var(--u-border-color);\n}\n\n.custom-file-item:last-child {\n    margin-bottom: 0;\n}\n\n.custom-file-info {\n    flex: 1;\n    margin-left: 20rpx;\n    display: flex;\n    flex-direction: column;\n    min-width: 0;\n}\n\n.custom-file-name {\n    font-size: 28rpx;\n    color: var(--u-main-color);\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n}\n\n.custom-file-size {\n    font-size: 24rpx;\n    color: var(--u-tips-color);\n    margin-top: 8rpx;\n}\n\n.custom-file-progress {\n    width: 120rpx;\n    margin-left: 20rpx;\n}\n\n.custom-file-progress-text {\n    font-size: 24rpx;\n    color: var(--u-primary-color);\n}\n\n.custom-file-status {\n    margin-left: 20rpx;\n    min-width: 48rpx;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n}\n\n.custom-file-delete {\n    display: flex;\n    align-items: center;\n    margin-left: 20rpx;\n    padding: 8rpx;\n}\n\n.custom-file-add-btn {\n    display: flex;\n    flex-direction: row;\n    align-items: center;\n    justify-content: center;\n    background: var(--u-bg-white);\n}\n\n.custom-file-add-text {\n    margin-left: 16rpx;\n    font-size: 28rpx;\n    color: var(--u-tips-color);\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsB/waterfall/index.vue",
    "content": "<template>\n    <demo-page title=\"Waterfall 瀑布流\" desc=\"用于展示瀑布流布局，支持商品卡片展示和删除操作。\" :apis=\"'waterfall'\">\n        <template #default>\n            <view class=\"wrap\">\n                <u-waterfall v-model=\"flowList\" ref=\"uWaterfallRef\">\n                    <template v-slot:left=\"{ leftList }\">\n                        <view class=\"demo-warter\" v-for=\"(item, index) in leftList\" :key=\"item.id\">\n                            <!-- 微信小程序需要hx2.8.11版本才支持在template中引入其他组件，比如下方的u-lazy-load组件 -->\n                            <u-lazy-load\n                                threshold=\"-450\"\n                                border-radius=\"10\"\n                                :image=\"item.image\"\n                                :index=\"index\"\n                            ></u-lazy-load>\n                            <view class=\"demo-title\">{{ item.title }}</view>\n                            <view class=\"demo-price\">{{ item.price }}元</view>\n                            <view class=\"demo-tag\">\n                                <view class=\"demo-tag-owner\">自营</view>\n                                <view class=\"demo-tag-text\">放心购</view>\n                            </view>\n                            <view class=\"demo-shop\">{{ item.shop }}</view>\n                            <view class=\"u-close\">\n                                <u-icon\n                                    name=\"close-circle-fill\"\n                                    color=\"#fa3534\"\n                                    size=\"34\"\n                                    @click=\"remove(item.id)\"\n                                ></u-icon>\n                            </view>\n                        </view>\n                    </template>\n                    <template v-slot:right=\"{ rightList }\">\n                        <view class=\"demo-warter\" v-for=\"(item, index) in rightList\" :key=\"item.id\">\n                            <u-lazy-load\n                                threshold=\"-450\"\n                                border-radius=\"10\"\n                                :image=\"item.image\"\n                                :index=\"index\"\n                            ></u-lazy-load>\n                            <view class=\"demo-title\">{{ item.title }}</view>\n                            <view class=\"demo-price\">{{ item.price }}元</view>\n                            <view class=\"demo-tag\">\n                                <view class=\"demo-tag-owner\">自营</view>\n                                <view class=\"demo-tag-text\">放心购</view>\n                            </view>\n                            <view class=\"demo-shop\">{{ item.shop }}</view>\n                            <view class=\"u-close\">\n                                <u-icon\n                                    name=\"close-circle-fill\"\n                                    color=\"#fa3534\"\n                                    size=\"34\"\n                                    @click=\"remove(item.id)\"\n                                ></u-icon>\n                            </view>\n                        </view>\n                    </template>\n                </u-waterfall>\n                <u-loadmore bg-color=\"rgb(240, 240, 240)\" :status=\"loadStatus\" @loadmore=\"addRandomData\"></u-loadmore>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { onLoad, onReachBottom } from '@dcloudio/uni-app';\nimport { $u } from '@/uni_modules/uview-pro';\nimport type { LoadmoreStatus } from '@/uni_modules/uview-pro/types/global';\n\n// 商品项类型声明\ninterface FlowItem {\n    id: string;\n    price: number;\n    title: string;\n    shop: string;\n    image: string;\n}\n\n// loadmore 状态类型\nconst loadStatus = ref<LoadmoreStatus>('loadmore');\n// 瀑布流数据\nconst flowList = ref<FlowItem[]>([]);\n// 商品原始列表\nconst list: FlowItem[] = [\n    {\n        price: 35,\n        title: '北国风光，千里冰封，万里雪飘',\n        shop: '李白杜甫白居易旗舰店',\n        image: 'http://pic.sc.chinaz.com/Files/pic/pic9/202002/zzpic23327_s.jpg',\n        id: ''\n    },\n    {\n        price: 75,\n        title: '望长城内外，惟余莽莽',\n        shop: '李白杜甫白居易旗舰店',\n        image: 'http://pic.sc.chinaz.com/Files/pic/pic9/202002/zzpic23325_s.jpg',\n        id: ''\n    },\n    {\n        price: 385,\n        title: '大河上下，顿失滔滔',\n        shop: '李白杜甫白居易旗舰店',\n        image: 'http://pic.sc.chinaz.com/Files/pic/pic9/202002/zzpic23327_s.jpg',\n        id: ''\n    },\n    {\n        price: 784,\n        title: '欲与天公试比高',\n        shop: '李白杜甫白居易旗舰店',\n        image: 'http://pic.sc.chinaz.com/Files/pic/pic9/202002/zzpic23325_s.jpg',\n        id: ''\n    },\n    {\n        price: 7891,\n        title: '须晴日，看红装素裹，分外妖娆',\n        shop: '李白杜甫白居易旗舰店',\n        image: 'http://pic.sc.chinaz.com/Files/pic/pic9/202002/zzpic23327_s.jpg',\n        id: ''\n    },\n    {\n        price: 2341,\n        shop: '李白杜甫白居易旗舰店',\n        title: '江山如此多娇，引无数英雄竞折腰',\n        image: 'http://pic.sc.chinaz.com/Files/pic/pic9/202002/zzpic23325_s.jpg',\n        id: ''\n    },\n    {\n        price: 661,\n        shop: '李白杜甫白居易旗舰店',\n        title: '惜秦皇汉武，略输文采',\n        image: 'http://pic.sc.chinaz.com/Files/pic/pic9/202002/zzpic23327_s.jpg',\n        id: ''\n    },\n    {\n        price: 1654,\n        title: '唐宗宋祖，稍逊风骚',\n        shop: '李白杜甫白居易旗舰店',\n        image: 'http://pic.sc.chinaz.com/Files/pic/pic9/202002/zzpic23325_s.jpg',\n        id: ''\n    },\n    {\n        price: 1678,\n        title: '一代天骄，成吉思汗',\n        shop: '李白杜甫白居易旗舰店',\n        image: 'http://pic.sc.chinaz.com/Files/pic/pic9/202002/zzpic23327_s.jpg',\n        id: ''\n    },\n    {\n        price: 924,\n        title: '只识弯弓射大雕',\n        shop: '李白杜甫白居易旗舰店',\n        image: 'http://pic.sc.chinaz.com/Files/pic/pic9/202002/zzpic23325_s.jpg',\n        id: ''\n    },\n    {\n        price: 8243,\n        title: '俱往矣，数风流人物，还看今朝',\n        shop: '李白杜甫白居易旗舰店',\n        image: 'http://pic.sc.chinaz.com/Files/pic/pic9/202002/zzpic23327_s.jpg',\n        id: ''\n    }\n];\n\n// u-waterfall 组件 ref 类型声明\nconst uWaterfallRef = ref<{ remove: (id: string) => void; clear: () => void } | null>(null);\n\n/**\n * 添加随机数据到瀑布流\n */\nfunction addRandomData(): void {\n    for (let i = 0; i < 10; i++) {\n        const index = $u.random(0, list.length - 1);\n        // 先转成字符串再转成对象，避免数组对象引用导致数据混乱\n        const item: FlowItem = JSON.parse(JSON.stringify(list[index]));\n        item.id = $u.guid();\n        flowList.value.push(item);\n    }\n}\n\n/**\n * 移除指定 id 的商品\n * @param id 商品 id\n */\nfunction remove(id: string): void {\n    uWaterfallRef.value?.remove(id);\n}\n\n/**\n * 清空瀑布流\n */\nfunction clear(): void {\n    uWaterfallRef.value?.clear();\n}\n\n// 页面加载时初始化数据\nonLoad(() => {\n    addRandomData();\n});\n\n// 触底加载更多\nonReachBottom(() => {\n    loadStatus.value = 'loading';\n    setTimeout(() => {\n        addRandomData();\n        loadStatus.value = 'loadmore';\n    }, 1000);\n});\n</script>\n\n<style lang=\"scss\" scoped>\n.demo-warter {\n    border-radius: 8px;\n    margin: 5px;\n    background-color: $u-bg-color;\n    padding: 8px;\n    position: relative;\n}\n\n.u-close {\n    position: absolute;\n    top: 32rpx;\n    right: 32rpx;\n}\n\n.demo-image {\n    width: 100%;\n    border-radius: 4px;\n}\n\n.demo-title {\n    font-size: 30rpx;\n    margin-top: 5px;\n    color: $u-main-color;\n    word-break: break-all;\n}\n\n.demo-tag {\n    display: flex;\n    margin-top: 5px;\n}\n\n.demo-tag-owner {\n    background-color: $u-type-error;\n    color: #ffffff;\n    display: flex;\n    align-items: center;\n    padding: 4rpx 14rpx;\n    border-radius: 50rpx;\n    font-size: 20rpx;\n    line-height: 1;\n}\n\n.demo-tag-text {\n    border: 1px solid $u-type-primary;\n    color: $u-type-primary;\n    margin-left: 10px;\n    border-radius: 50rpx;\n    line-height: 1;\n    padding: 4rpx 14rpx;\n    display: flex;\n    align-items: center;\n    border-radius: 50rpx;\n    font-size: 20rpx;\n}\n\n.demo-price {\n    font-size: 30rpx;\n    color: $u-type-error;\n    margin-top: 5px;\n}\n\n.demo-shop {\n    font-size: 22rpx;\n    color: $u-tips-color;\n    margin-top: 5px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsC/actionSheet/index.vue",
    "content": "<template>\n    <demo-page title=\"ActionSheet 动作菜单\" desc=\"从下方弹出的菜单列表，提供用户选择操作。\" :apis=\"'actionSheet'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-toast ref=\"uToastRef\"></u-toast>\n                        <u-button @click=\"showAction\">唤起ActionSheet</u-button>\n                        <u-action-sheet\n                            v-model=\"show\"\n                            :cancel-btn=\"cancel\"\n                            :mask-close-able=\"maskCloseAble\"\n                            :tips=\"tips\"\n                            :safe-area-inset-bottom=\"true\"\n                            @click=\"click\"\n                        >\n                            <block v-for=\"(item, index) in list\" :key=\"index\">\n                                <u-action-sheet-item\n                                    v-if=\"index !== 3\"\n                                    :text=\"item.text\"\n                                    :sub-text=\"item.subText\"\n                                    :color=\"item.color\"\n                                    :font-size=\"item.fontSize\"\n                                    :disabled=\"item.disabled\"\n                                />\n                                <u-action-sheet-item padding=\"0\" :async-close=\"true\" v-else>\n                                    <u-text\n                                        type=\"success\"\n                                        text=\"我是自定义的（微信能力）\"\n                                        size=\"32\"\n                                        openType=\"openSetting\"\n                                        :block=\"true\"\n                                        line-height=\"50px\"\n                                        align=\"center\"\n                                        @click=\"clickItem\"\n                                    ></u-text>\n                                </u-action-sheet-item>\n                            </block>\n                        </u-action-sheet>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">显示标题</view>\n                        <u-subsection :list=\"['是', '否']\" @change=\"tipsChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">取消按钮</view>\n                        <u-subsection :list=\"['是', '否']\" @change=\"cancelChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">点击遮罩关闭</view>\n                        <u-subsection :list=\"['是', '否']\" @change=\"maskClickChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\nimport type { ActionSheetTips, ActionSheetItem } from '@/uni_modules/uview-pro/types/global';\n\nconst list = ref<ActionSheetItem[]>([\n    {\n        text: '最是人间留不住'\n    },\n    {\n        text: '朱颜辞镜花辞树',\n        disabled: true\n    },\n    {\n        text: '正是江南好风景',\n        subText: '春江水暖鸭先知'\n    },\n    {\n        text: '落花时节又逢君'\n    }\n]);\n\nconst tips = ref<ActionSheetTips>({\n    text: '请谨慎执行您的操作',\n    color: $u.color.tipsColor,\n    fontSize: '24rpx'\n});\n\nconst show = ref(false);\nconst cancel = ref(true);\nconst maskCloseAble = ref(true);\nconst uToastRef = ref(null);\n\nfunction showAction() {\n    show.value = true;\n}\n\nfunction click(index: number) {\n    uToastRef.value?.show({\n        type: 'success',\n        title: '点击了第' + (index + 1) + '项'\n    });\n}\n\nfunction tipsChange(index: number) {\n    show.value = true;\n    tips.value.text = index == 0 ? '请谨慎执行您的操作' : '';\n}\n\nfunction cancelChange(index: number) {\n    show.value = true;\n    cancel.value = index === 0;\n}\n\nfunction maskClickChange(index: number) {\n    if (index === 1) cancel.value = true;\n    show.value = true;\n    maskCloseAble.value = index === 0;\n}\n\nfunction clickItem() {\n    // #ifndef MP-WEIXIN\n    uni.$u.toast('请在微信小程序内查看效果');\n    // #endif\n    setTimeout(() => {\n        show.value = false;\n    }, 500);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.wrap {\n    padding: 24rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsC/alertTips/index.vue",
    "content": "<template>\n    <demo-page title=\"AlertTips 警告提示\" desc=\"用于页面中向用户展示重要信息提示。\" :apis=\"'alertTips'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-toast ref=\"uToastRef\"></u-toast>\n                        <u-alert-tips\n                            @close=\"close\"\n                            :closeAble=\"closeAble\"\n                            :show=\"show\"\n                            @click=\"click\"\n                            :type=\"type\"\n                            :title=\"title\"\n                            :description=\"description\"\n                            :showIcon=\"showIcon\"\n                        ></u-alert-tips>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">左侧图标</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"showIconChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">关闭图标</view>\n                        <u-subsection current=\"1\" :list=\"['显示', '隐藏']\" @change=\"closeAbleChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">主题</view>\n                        <u-subsection\n                            current=\"3\"\n                            :list=\"['primary', 'success', 'error', 'warning', 'info']\"\n                            @change=\"typeChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">状态</view>\n                        <u-subsection :current=\"current\" :list=\"['开启', '关闭']\" @change=\"showChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref, computed } from 'vue';\nimport type { ThemeType } from '@/uni_modules/uview-pro/types/global';\n\nconst title = ref('大漠孤烟直，长河落日圆');\nconst description = ref(\n    '月落乌啼霜满天，江枫渔火对愁眠。姑苏城外寒山寺，夜半钟声到客船。飞流直下三千尺，疑是银河落九天！'\n);\nconst show = ref(true);\nconst closeAble = ref(false);\nconst showIcon = ref(false);\nconst type = ref<ThemeType>('warning');\nconst uToastRef = ref(null);\n\nconst current = computed<number>(() => {\n    return show.value ? 0 : 1;\n});\n\nfunction showIconChange(index: number) {\n    showIcon.value = index === 0;\n}\n\nfunction showChange(index: number) {\n    show.value = index === 0;\n}\n\nfunction closeAbleChange(index: number) {\n    closeAble.value = index === 0;\n}\n\nfunction typeChange(index: number) {\n    type.value =\n        index === 0 ? 'primary' : index === 1 ? 'success' : index === 2 ? 'error' : index === 3 ? 'warning' : 'info';\n}\n\nfunction close() {\n    show.value = false;\n    uToastRef.value?.show({\n        type: 'warning',\n        title: '点击关闭按钮'\n    });\n}\n\nfunction click() {\n    uToastRef.value?.show({\n        type: 'warning',\n        title: '点击内容'\n    });\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.wrap {\n    padding: 24rpx;\n}\n\n.item {\n    margin: 30rpx 0;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsC/badge/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"Badge 徽标数\"\n        desc=\"该组件一般用于图标右上角显示未读的消息数量，提示用户点击，有圆点和圆包含文字两种形式。\"\n        :apis=\"'badge'\"\n    >\n        <view class=\"u-demo\">\n            <view class=\"u-demo-wrap\">\n                <view class=\"u-demo-title\">演示效果</view>\n                <view class=\"u-demo-area\">\n                    <view class=\"u-badge-wrap\">\n                        <u-badge\n                            :is-center=\"isCenter\"\n                            :type=\"type\"\n                            :count=\"count\"\n                            :is-dot=\"isDot\"\n                            :offset=\"offset\"\n                            :size=\"size\"\n                        >\n                        </u-badge>\n                    </view>\n                </view>\n            </view>\n            <view class=\"u-config-wrap\">\n                <view class=\"u-config-title u-border-bottom\">参数配置</view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">数值显示</view>\n                    <u-subsection\n                        current=\"1\"\n                        :list=\"['0', '8', '15', '106', '209']\"\n                        @change=\"countChange\"\n                    ></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">主题选择</view>\n                    <u-subsection\n                        current=\"2\"\n                        :list=\"['primary', 'success', 'error', 'warning', 'info']\"\n                        @change=\"typeChange\"\n                    ></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">显示点</view>\n                    <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"isDotChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">尺寸</view>\n                    <u-subsection :list=\"['default', 'mini']\" @change=\"sizeChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">位置偏移</view>\n                    <u-subsection\n                        current=\"1\"\n                        :list=\"['[20, 20]', '[-8, -8]', '[-20, -20]']\"\n                        @change=\"offsetChange\"\n                    ></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">中心点与父右上角重合</view>\n                    <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"isCenterChange\"></u-subsection>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\nimport type { ThemeType, BadgeSize } from '@/uni_modules/uview-pro/types/global';\n\nconst count = ref(8);\nconst type = ref<ThemeType>('error');\nconst isDot = ref(false);\nconst offset = ref<[number, number]>([-8, -8]);\nconst size = ref<BadgeSize>('default');\nconst isCenter = ref(false);\n\nfunction countChange(index: number) {\n    count.value = index === 0 ? 0 : index === 1 ? 8 : index === 2 ? 15 : index === 3 ? 106 : 209;\n}\n\nfunction typeChange(index: number) {\n    type.value =\n        index === 0 ? 'primary' : index === 1 ? 'success' : index === 2 ? 'error' : index === 3 ? 'warning' : 'info';\n}\n\nfunction sizeChange(index: number) {\n    size.value = index === 0 ? 'default' : 'mini';\n}\n\nfunction isDotChange(index: number) {\n    isDot.value = index === 0 ? true : false;\n}\n\nfunction offsetChange(index: number) {\n    offset.value = index === 0 ? [20, 20] : index === 1 ? [-8, -8] : [-20, -20];\n}\n\nfunction isCenterChange(index: number) {\n    isCenter.value = index === 0 ? true : false;\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.u-badge-wrap {\n    width: 60px;\n    height: 60px;\n    border-radius: 6px;\n    background-color: $u-light-color;\n    position: relative;\n    margin: auto;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsC/button/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"Button 按钮\"\n        desc=\"该组件内部实现以uni-app`button`组件为基础，进行二次封装，有更多的主题颜色，有可选的按钮点击水波纹效果\"\n        :apis=\"'button'\"\n    >\n        <view class=\"u-demo\">\n            <view class=\"u-demo-wrap\">\n                <view class=\"u-demo-title\">演示效果</view>\n                <view class=\"u-demo-area\">\n                    <u-button\n                        @click=\"btnClick\"\n                        data-name=\"3333\"\n                        :loading=\"loading\"\n                        :plain=\"plain\"\n                        :shape=\"shape\"\n                        :size=\"size\"\n                        :ripple=\"ripple\"\n                        :hairLine=\"hairLine\"\n                        :type=\"type\"\n                        :disabled=\"disabled\"\n                        :custom-style=\"buttonCustomStyle\"\n                    >\n                        山川异域，风月同天\n                    </u-button>\n                </view>\n            </view>\n            <view class=\"u-config-wrap\">\n                <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">主题选择</view>\n                    <u-subsection\n                        :list=\"['default', 'primary', 'error', 'warning', 'success']\"\n                        @change=\"typeChange\"\n                    ></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">尺寸大小</view>\n                    <u-subsection :list=\"['默认', '大', '中等', '小', '极小']\" @change=\"sizeChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">形状</view>\n                    <u-subsection :list=\"['直角', '圆角']\" @change=\"shapeChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">镂空</view>\n                    <u-subsection :current=\"1\" :list=\"['是', '否']\" @change=\"plainChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">水波纹(感觉哪里有问题？点击顶部的按钮试试)</view>\n                    <u-subsection :current=\"1\" :list=\"['是', '否']\" @change=\"rippleChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">细边框</view>\n                    <u-subsection :list=\"['是', '否']\" @change=\"hairLineChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">加载中</view>\n                    <u-subsection :current=\"1\" :list=\"['是', '否']\" @change=\"loadingChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">禁用</view>\n                    <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"disabledChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">自定义样式</view>\n                    <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"customStyleChange\"></u-subsection>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport type { ButtonSize, ButtonType, Shape } from '@/uni_modules/uview-pro/types/global';\nimport { computed, ref } from 'vue';\nimport { completeMission } from '../../../common/useExperience';\n\n// 主题选择\nconst type = ref<ButtonType>('default');\n// 尺寸大小\nconst size = ref<ButtonSize>('default');\n// 形状\nconst shape = ref<Shape>('square');\n// 镂空\nconst plain = ref<boolean>(false);\n// 水波纹\nconst ripple = ref<boolean>(false);\n// 细边框\nconst hairLine = ref<boolean>(true);\n// 加载中\nconst loading = ref<boolean>(false);\n// 禁用\nconst disabled = ref<boolean>(false);\n// 自定义样式\nconst customStyle = ref<boolean>(false);\n// 主题选择切换\nconst typeChange = (e: number) => {\n    switch (e) {\n        case 0:\n            type.value = 'default';\n            break;\n        case 1:\n            type.value = 'primary';\n            break;\n        case 2:\n            type.value = 'error';\n            break;\n        case 3:\n            type.value = 'warning';\n            break;\n        case 4:\n            type.value = 'success';\n            break;\n    }\n    completeMission('button');\n};\n\n// 自定义样式\nconst buttonCustomStyle = computed(() => {\n    if (!customStyle.value) {\n        return {};\n    }\n    return disabled.value\n        ? {\n              backgroundColor: '#999 !important',\n              color: '#f1f1f1 !important'\n          }\n        : {\n              backgroundColor: '#000',\n              color: '#fff'\n          };\n});\n\n// 尺寸大小切换\nconst sizeChange = (e: number) => {\n    switch (e) {\n        case 0:\n            size.value = 'default';\n            break;\n        case 1:\n            size.value = 'large';\n            break;\n        case 2:\n            size.value = 'medium';\n            break;\n        case 3:\n            size.value = 'small';\n            break;\n        case 4:\n            size.value = 'mini';\n            break;\n    }\n};\n\n// 形状切换\nconst shapeChange = (e: number) => {\n    shape.value = e === 0 ? 'square' : 'circle';\n};\n\n// 镂空切换\nconst plainChange = (e: number) => {\n    plain.value = e === 0;\n};\n\n// 水波纹切换\nconst rippleChange = (e: number) => {\n    ripple.value = e === 0;\n};\n\n// 细边框切换\nconst hairLineChange = (e: number) => {\n    hairLine.value = e === 0;\n};\n\n// 加载中切换\nconst loadingChange = (index: number) => {\n    loading.value = index === 0;\n};\n\n// 禁用切换\nconst disabledChange = (e: number) => {\n    disabled.value = e === 0;\n};\n\n// 自定义样式切换\nconst customStyleChange = (e: number) => {\n    customStyle.value = e === 0;\n};\n\n// 按钮点击事件\nconst btnClick = () => {\n    uni.showToast({\n        title: '按钮被点击',\n        icon: 'none'\n    });\n};\n</script>\n\n<style lang=\"scss\" scoped>\n.box {\n    padding: 30rpx;\n}\n\n.box :deep(button) {\n    margin-bottom: 40rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsC/cell/index.vue",
    "content": "<template>\n    <demo-page title=\"Cell 单元格\" desc=\"cell单元格一般用于一组列表的情况，比如个人中心页，设置页等。\" :apis=\"'cell'\">\n        <view class=\"u-demo\">\n            <view class=\"u-demo-wrap\">\n                <view class=\"u-demo-title\">演示效果</view>\n                <view class=\"u-demo-area\">\n                    <u-cell-group title=\"读万卷书\">\n                        <u-cell-item\n                            center\n                            :is-link=\"true\"\n                            :label=\"label\"\n                            value=\"铁马冰河入梦来\"\n                            index=\"index\"\n                            @click=\"click\"\n                            :hover-class=\"hoverClass\"\n                            :arrow=\"arrow\"\n                            :title=\"title\"\n                            :icon=\"icon\"\n                        >\n                            <template v-if=\"rightSlot === 'badge'\" #right-icon>\n                                <u-badge :absolute=\"false\" count=\"105\"></u-badge>\n                            </template>\n                            <template v-if=\"rightSlot === 'switch'\" #right-icon>\n                                <u-switch v-model=\"checked\"></u-switch>\n                            </template>\n                        </u-cell-item>\n                        <u-cell-item :border-bottom=\"false\" title=\"铁马冰河入梦来\" value=\"行万里路\" :arrow=\"false\">\n                            <template #icon>\n                                <u-icon size=\"34\" name=\"calendar\" custom-style=\"margin-right: 10rpx\"></u-icon>\n                            </template>\n                            <template #right-icon>\n                                <u-icon size=\"34\" name=\"calendar\"></u-icon>\n                            </template>\n                            <template #value>\n                                <u-field></u-field>\n                            </template>\n                        </u-cell-item>\n                    </u-cell-group>\n                </view>\n            </view>\n            <view class=\"u-config-wrap\">\n                <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">更换图标</view>\n                    <u-subsection :list=\"['是', '否']\" @change=\"iconChange\"></u-subsection>\n                </view>\n                <!-- 小程序无法动态切换slot -->\n                <!-- #ifndef MP -->\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">自定义右侧内容</view>\n                    <u-subsection :list=\"['文字', 'Switch组件', 'Badge组件']\" @change=\"rightSlotChange\"></u-subsection>\n                </view>\n                <!-- #endif -->\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">描述信息</view>\n                    <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"labelChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">更换标题</view>\n                    <u-subsection :list=\"['是', '否']\" @change=\"titleChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">右侧箭头</view>\n                    <u-subsection :list=\"['是', '否']\" @change=\"arrowChange\"></u-subsection>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref, computed } from 'vue';\nimport { completeMission } from '../../../common/useExperience';\n\nconst icon = ref('setting');\nconst arrow = ref(true);\nconst label = ref('');\nconst title = ref('青山一道同云雨');\nconst rightSlot = ref('');\nconst checked = ref(false);\n\nconst hoverClass = computed<string>(() => {\n    // 如果右侧是switch步进器组件的话，去掉cell的点击反馈，因为这个时候点击的反馈应该在switch上\n    return rightSlot.value === 'switch' ? 'none' : 'u-cell-hover';\n});\n\n// 方法\nfunction iconChange(index: number) {\n    icon.value = index === 0 ? 'setting' : 'file-text';\n}\n\nfunction arrowChange(index: number) {\n    arrow.value = index === 0 ? true : false;\n}\n\nfunction labelChange(index: number) {\n    label.value = index === 0 ? '岂曰无衣，与子同裳' : '';\n}\n\nfunction titleChange(index: number) {\n    title.value = index === 0 ? '青山一道同云雨' : '明月何曾是两乡';\n}\n\nfunction rightSlotChange(index: number) {\n    rightSlot.value = index === 0 ? 'text' : index === 1 ? 'switch' : 'badge';\n    if (index === 0) arrow.value = true;\n    else arrow.value = false;\n}\n\nfunction click(index: any) {\n    // console.log(index);\n    completeMission('cell');\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.gab {\n    background-color: rgb(245, 245, 245);\n    height: 20rpx;\n}\n\n.wrap {\n    height: 100vh;\n    background-color: rgb(241, 241, 241);\n}\n\n.box {\n    padding: 30rpx 00rpx;\n    font-size: 28rpx;\n    color: $u-type-info;\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsC/circleProgress/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"CircleProgress 圆形进度条\"\n        desc=\"圆形的进度条，用于展示进度，可自定义样式和颜色。\"\n        :apis=\"'circleProgress'\"\n    >\n        <template #default>\n            <view class=\"wrap\">\n                <view class=\"item\">\n                    <u-circle-progress type=\"warning\" :percent=\"percent\">\n                        <view class=\"u-progress-content\">\n                            <view class=\"u-progress-dot\"></view>\n                            <text class=\"u-progress-info\">查找中</text>\n                        </view>\n                    </u-circle-progress>\n                    <u-circle-progress type=\"warning\" :width=\"150\" :percent=\"percent\">\n                        <view class=\"u-progress-content\">\n                            <view class=\"u-progress-dot\"></view>\n                            <text class=\"u-progress-info\">查找中</text>\n                        </view>\n                    </u-circle-progress>\n                </view>\n                <view class=\"item\">\n                    <u-line-progress></u-line-progress>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref, onMounted } from 'vue';\n\nconst percent = ref(33);\n\nonMounted(() => {\n    setTimeout(() => {\n        percent.value = 50;\n    }, 1500);\n});\n</script>\n\n<style lang=\"scss\" scoped>\n.wrap {\n    padding: 24rpx;\n}\n\n.u-progress-content {\n    position: absolute;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n}\n\n.u-progress-dot {\n    width: 16rpx;\n    height: 16rpx;\n    border-radius: 50%;\n    background-color: #fb9126;\n}\n\n.u-progress-info {\n    font-size: 28rpx;\n    padding-left: 16rpx;\n    letter-spacing: 2rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsC/collapse/index.vue",
    "content": "<template>\n    <demo-page title=\"Collapse 折叠框\" desc=\"将内容折叠起来，节省空间，用户可以点击展开查看详情。\" :apis=\"'collapse'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-toast ref=\"uToastRef\"></u-toast>\n                        <u-collapse\n                            v-if=\"key\"\n                            :item-style=\"itemStyle\"\n                            event-type=\"close\"\n                            :arrow=\"arrow\"\n                            @change=\"change\"\n                            :accordion=\"accordion\"\n                        >\n                            <u-collapse-item\n                                :index=\"index\"\n                                @change=\"itemChange\"\n                                :title=\"item.head\"\n                                v-for=\"(item, index) in itemList\"\n                                :key=\"index\"\n                                :open=\"item.open\"\n                            >\n                                {{ item.body }}\n                            </u-collapse-item>\n                        </u-collapse>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">手风琴模式</view>\n                        <u-subsection :list=\"['否', '是']\" @change=\"accordionChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">右侧箭头</view>\n                        <u-subsection :list=\"['显示', '隐藏']\" @change=\"arrowChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">自定义样式</view>\n                        <u-subsection :list=\"['否', '是']\" @change=\"styleChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref, nextTick } from 'vue';\n\nconst uToastRef = ref(null);\nconst itemList = ref([\n    {\n        head: '赏识在于角度的转换',\n        body: '只要我们正确择取一个合适的参照物乃至稍降一格去看待他人，值得赏识的东西便会扑面而来：闪光的道德、妙异的智慧、优美的人情…… 赏识不是单向的施舍，是智慧与智慧的主动碰撞',\n        open: true\n    },\n    {\n        head: '生活中不是缺少美，而是缺少发现美的眼睛',\n        body: '学会欣赏，实际是一种积极生活的态度，是生活的调味品，会在欣赏中发现生活的美',\n        open: false\n    },\n    {\n        head: '周围一些不起眼的人、事、物，或许都隐藏着不同凡响的智慧',\n        body: '但是据说雕刻大卫像所用的这块大理石，曾被多位雕刻家批评得一无是处，有些人认为这块大理石采凿得不好，有些人嫌它的纹路不够美，用它绝对雕不出好的艺术品，总之它被批评为一块不受人赏识的普通石头',\n        open: false\n    },\n    {\n        head: '点燃心中的火焰，找回了自信和人生的价值',\n        body: '他随手翻了几页，竟被一篇题名为《童年》的小说所吸引，作者是一个初出茅庐的无名小辈，但屠格涅夫却十分欣赏，钟爱有加',\n        open: false\n    },\n    {\n        head: '因为赏识，那块被人不耻的石头变成了雕塑',\n        body: '这个材料反应的就是赏识的问题，赏识是一种理解和信任，包含了肯定与欣赏，也是一种激励和引导，可以使人悔过自新，扬长避短，更健康地成长和进步',\n        open: false\n    }\n]);\nconst accordion = ref(false);\nconst arrow = ref(true);\nconst itemStyle = ref({});\nconst key = ref(true);\n\nfunction accordionChange(index: number) {\n    accordion.value = index === 1;\n    changeStatus();\n}\n\nfunction arrowChange(index: number) {\n    arrow.value = index === 0;\n    changeStatus();\n}\n\nfunction styleChange(index: number) {\n    if (index === 1) {\n        itemStyle.value = {\n            border: '1px solid rgb(230, 230, 230)',\n            marginTop: '20px',\n            padding: '0 8rpx'\n        };\n    } else {\n        itemStyle.value = {};\n    }\n    changeStatus();\n}\n\nfunction change(index: number | number[]) {\n    let displayIndex: string | number;\n    if (Array.isArray(index)) {\n        const arr = index.map(val => Number(val) + 1);\n        displayIndex = arr.join(',');\n    } else {\n        displayIndex = Number(index) + 1;\n    }\n    uToastRef.value?.show({\n        title: `点击了第${displayIndex}个`,\n        type: 'warning'\n    });\n}\n\nfunction itemChange(e: any) {\n    console.log(e);\n}\n\nfunction changeStatus() {\n    key.value = false;\n    nextTick(() => {\n        key.value = true;\n    });\n}\n</script>\n\n<style>\n.hover1 {\n    background-color: red;\n}\n</style>\n\n<style lang=\"scss\" scoped>\n.head {\n    font-size: 30rpx;\n    color: $u-main-color;\n    line-height: 1;\n    padding: 24rpx 24rpx;\n}\n\n.body {\n    font-size: 28rpx;\n    color: $u-tips-color;\n    line-height: 1.4;\n    padding: 24rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsC/color/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"Color 色彩\"\n        desc=\"uView经过大量调试和研究，得出一套专有的调色板，在各个组件内部，使用统一的配色，为您的产品带来统一又鲜明的视觉效果。\"\n        apis=\"color\"\n        :custom-style=\"{ backgroundImage: 'none' }\"\n    >\n        <view class=\"wrap\">\n            <!-- 按分组渲染色彩 -->\n            <template v-for=\"section in colorSections\" :key=\"section.id\">\n                <view class=\"section\">\n                    <view class=\"section-title\">{{ section.label }}</view>\n                    <view v-if=\"section.description\" class=\"section-desc\">{{ section.description }}</view>\n\n                    <!-- 组内颜色组 -->\n                    <view v-for=\"group in section.groups\" :key=\"group.id\" class=\"item\">\n                        <view class=\"title\">{{ group.label }}</view>\n                        <view class=\"color-box\">\n                            <!-- 遍历每个颜色 key -->\n                            <view\n                                v-for=\"colorKey in group.keys\"\n                                :key=\"colorKey\"\n                                class=\"color-item\"\n                                :class=\"isLightColor(colorKey) ? 'dark-text' : ''\"\n                                :style=\"{ background: $u.getColor(colorKey) }\"\n                            >\n                                <view class=\"color-title u-line-1\">{{ labelMap[colorKey] }}</view>\n                                <view class=\"color-value\">{{ $u.getColor(colorKey) }}</view>\n                            </view>\n                        </view>\n                    </view>\n                </view>\n            </template>\n        </view>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { $u } from 'uview-pro';\nimport type { ColorType } from '@/uni_modules/uview-pro/types/global';\n\ninterface ColorGroupConfig {\n    id: string;\n    label: string;\n    keys: ColorType[];\n}\n\ninterface ColorSectionConfig {\n    id: string;\n    label: string;\n    description?: string;\n    groups: ColorGroupConfig[];\n}\n\nconst colorSections: ColorSectionConfig[] = [\n    {\n        id: 'brand',\n        label: '品牌与状态',\n        description: '主题主色与成功/警告/错误/信息色阶梯',\n        groups: [\n            { id: 'theme', label: '主题色', keys: ['primary', 'primaryDark', 'primaryDisabled', 'primaryLight'] },\n            { id: 'error', label: '错误色', keys: ['error', 'errorDark', 'errorDisabled', 'errorLight'] },\n            { id: 'warning', label: '警告色', keys: ['warning', 'warningDark', 'warningDisabled', 'warningLight'] },\n            { id: 'info', label: '信息色', keys: ['info', 'infoDark', 'infoDisabled', 'infoLight'] },\n            { id: 'success', label: '成功色', keys: ['success', 'successDark', 'successDisabled', 'successLight'] }\n        ]\n    },\n    {\n        id: 'content',\n        label: '文本与描边',\n        description: '文字、提示与描边需要清晰的层级关系',\n        groups: [\n            {\n                id: 'text',\n                label: '文字阶梯',\n                keys: ['whiteColor', 'mainColor', 'contentColor', 'tipsColor', 'lightColor', 'blackColor']\n            },\n            { id: 'border', label: '描边与分割', keys: ['borderColor', 'dividerColor'] }\n        ]\n    },\n    {\n        id: 'surface',\n        label: '背景与表面',\n        description: '背景、卡片、深浅灰背景根据明暗形成阶梯',\n        groups: [{ id: 'bg', label: '背景阶梯', keys: ['bgWhite', 'bgColor', 'bgGrayLight', 'bgGrayDark', 'bgBlack'] }]\n    },\n    {\n        id: 'decor',\n        label: '遮罩与阴影',\n        groups: [{ id: 'mask', label: '遮罩/阴影', keys: ['maskColor', 'shadowColor'] }]\n    }\n];\n\n// key -> friendly label 映射\nconst labelMap: Record<string, string> = {\n    primary: '主题色',\n    primaryDark: '主题(深)',\n    primaryDisabled: '主题(禁用)',\n    primaryLight: '主题(淡)',\n    success: '成功色',\n    successDark: '成功色(深)',\n    successDisabled: '成功(禁用)',\n    successLight: '成功(淡)',\n    error: '错误色',\n    errorDark: '错误(深)',\n    errorDisabled: '错误(禁用)',\n    errorLight: '错误(淡)',\n    warning: '警告色',\n    warningDark: '警告(深)',\n    warningDisabled: '警告(禁用)',\n    warningLight: '警告(淡)',\n    info: '信息色',\n    infoDark: '信息(深)',\n    infoDisabled: '信息(禁用)',\n    infoLight: '信息(淡)',\n    mainColor: '主要文字',\n    contentColor: '常规文字',\n    tipsColor: '提示文字',\n    lightColor: '占位/弱色',\n    borderColor: '边框颜色',\n    dividerColor: '分割线',\n    bgColor: '背景色',\n    bgWhite: '纯白背景',\n    bgGrayLight: '浅灰背景',\n    bgGrayDark: '深灰背景',\n    bgBlack: '黑色背景',\n    whiteColor: '纯白色值',\n    blackColor: '纯黑色值',\n    maskColor: '遮罩颜色',\n    shadowColor: '阴影颜色'\n};\n\nfunction isLightColor(key: string): boolean {\n    // 简单判断白色或浅色背景\n    const lights = ['white', 'black', 'main', 'light', 'bg'];\n    return lights.some(light => key.toLowerCase().includes(light));\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.wrap {\n    padding: 18rpx;\n}\n\n.section {\n    margin-bottom: 60rpx;\n\n    &:last-child {\n        margin-bottom: 0;\n    }\n\n    .section-title {\n        font-size: 36rpx;\n        font-weight: 600;\n        color: $u-main-color;\n        margin-bottom: 12rpx;\n        line-height: 1;\n    }\n\n    .section-desc {\n        font-size: 26rpx;\n        color: $u-tips-color;\n        margin-bottom: 30rpx;\n        line-height: 1.5;\n    }\n}\n\n.item {\n    margin: 30rpx 0;\n\n    .title {\n        font-size: 30rpx;\n        position: relative;\n        line-height: 1;\n        padding-left: 22rpx;\n        color: $u-main-color;\n        margin-bottom: 16rpx;\n\n        &:before {\n            width: 4px;\n            height: 15px;\n            border-radius: 100rpx;\n            background-color: $u-content-color;\n            content: '';\n            position: absolute;\n            left: 6rpx;\n            top: -1px;\n        }\n    }\n\n    .color-box {\n        display: flex;\n        align-items: center;\n        color: #fff;\n        text-align: center;\n        margin-top: 20rpx;\n        flex-wrap: wrap;\n\n        .color-item {\n            display: flex;\n            flex: 0 0 calc(25% - 16rpx);\n            margin: 8rpx;\n            flex-direction: column;\n            border-radius: 6rpx;\n            padding: 12rpx 0;\n            justify-content: center;\n            min-height: 120rpx;\n            transition: transform 0.2s ease;\n            border: 1px solid $u-border-color;\n\n            &.dark-text {\n                color: $u-tips-color;\n            }\n\n            &:hover {\n                transform: translateY(-4rpx);\n                box-shadow: 0 8rpx 16rpx rgba(0, 0, 0, 0.1);\n            }\n        }\n\n        .color-title {\n            font-size: 28rpx;\n            font-weight: 500;\n            margin-bottom: 8rpx;\n        }\n\n        .color-value {\n            font-size: 24rpx;\n            opacity: 0.9;\n        }\n    }\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsC/countDown/index.vue",
    "content": "<template>\n    <demo-page title=\"CountDown 倒计时\" desc=\"以数字和分隔符的形式展示倒计时，精确到毫秒级别。\" :apis=\"'countDown'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-toast ref=\"uToastRef\"></u-toast>\n                        <u-count-down\n                            class=\"count-down-demo\"\n                            :timestamp=\"timestamp\"\n                            :separator=\"separator\"\n                            :showBorder=\"showBorder\"\n                            :separator-color=\"separatorColor\"\n                            :showDays=\"showDays\"\n                            :fontSize=\"fontSize\"\n                            @change=\"change\"\n                            ref=\"uCountDownRef\"\n                            :border-color=\"borderColor\"\n                            :color=\"color\"\n                            @end=\"end\"\n                            :bg-color=\"$u.color.bgWhite\"\n                        ></u-count-down>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">调整时间</view>\n                        <u-subsection :list=\"['60', '86400', '983272']\" @change=\"timestampChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">分隔符</view>\n                        <u-subsection :list=\"['英文冒号', '中文名称']\" @change=\"separatorChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">自定义样式</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"styleChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">显示天</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"showDaysChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">字体大小</view>\n                        <u-subsection current=\"1\" :list=\"['26', '30', '34']\" @change=\"fontSizeChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\n\nimport { $u } from '@/uni_modules/uview-pro';\n\nconst uToastRef = ref(null);\nconst uCountDownRef = ref(null);\n\nconst timestamp = ref(60);\nconst separator = ref('colon');\nconst showBorder = ref(false);\nconst borderColor = ref('#303133');\nconst color = ref('#303133');\nconst showDays = ref(false);\nconst fontSize = ref(30);\nconst separatorColor = ref('#303133');\n\nfunction timestampChange(index: number) {\n    timestamp.value = index === 0 ? 60 : index === 1 ? 86400 : 983272;\n}\n\nfunction separatorChange(index: number) {\n    separator.value = index === 0 ? 'colon' : 'zh';\n}\n\nfunction styleChange(index: number) {\n    if (index === 0) {\n        showBorder.value = true;\n        borderColor.value = $u.color['primary'];\n        color.value = $u.color['primary'];\n        separatorColor.value = $u.color['primary'];\n    } else {\n        showBorder.value = false;\n        borderColor.value = '#303133';\n        color.value = '#303133';\n        separatorColor.value = '#303133';\n    }\n}\n\nfunction showDaysChange(index: number) {\n    showDays.value = index === 0;\n}\n\nfunction fontSizeChange(index: number) {\n    fontSize.value = index === 0 ? 26 : index === 1 ? 30 : 34;\n}\n\nfunction end() {\n    uToastRef.value?.show({\n        title: '倒计时结束',\n        type: 'warning'\n    });\n}\n\nfunction change(timestamp: number) {\n    // console.log(timestamp);\n}\n\nfunction getSeconds(): number | undefined {\n    // console.log(uCountDown.value?.seconds);\n    return uCountDownRef.value?.seconds;\n}\n</script>\n\n<style scoped lang=\"scss\">\n.count-down-demo {\n    justify-content: center;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsC/countTo/index.vue",
    "content": "<template>\n    <demo-page title=\"CountTo 数字滚动\" desc=\"以动画形式展示数字从起始值滚动到目标值的过程。\" :apis=\"'countTo'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-toast ref=\"uToastRef\"></u-toast>\n                        <view class=\"u-no-demo-here\"\n                            >如果使用text-align: center对齐，数字滚动期间可能会抖动，见文档说明</view\n                        >\n                        <view class=\"count-to-demo\">\n                            <u-count-to\n                                class=\"count-to\"\n                                :useEasing=\"useEasing\"\n                                ref=\"uCountToRef\"\n                                :autoplay=\"autoplay\"\n                                :startVal=\"startVal\"\n                                :endVal=\"endVal\"\n                                :duration=\"duration\"\n                                :decimals=\"decimals\"\n                                :bold=\"bold\"\n                                @end=\"end\"\n                            ></u-count-to>\n                        </view>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\">参数配置</view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">状态</view>\n                        <u-subsection\n                            :current=\"current\"\n                            :list=\"['启动', '暂停', '继续', '重置']\"\n                            @change=\"statusChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">目标值</view>\n                        <u-subsection :list=\"['608', '5604', '45617']\" @change=\"endValChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">滚动时间</view>\n                        <u-subsection\n                            current=\"1\"\n                            :list=\"['1000', '2000', '3000']\"\n                            @change=\"durationChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">显示小数</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"decimalsChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">字体加粗</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"boldChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref, nextTick } from 'vue';\n\nconst uToastRef = ref(null);\nconst uCountToRef = ref(null);\n\nconst startVal = ref(0);\nconst endVal = ref(608);\nconst separator = ref(',');\nconst decimals = ref(0);\nconst duration = ref(2000);\nconst autoplay = ref(false);\nconst useEasing = ref(true);\nconst current = ref(3);\nconst isStop = ref(false); // 如果开没启动前，不允许点击状态选项的\"继续\"按钮，否则会导致显示NaN\nconst bold = ref(false);\n\nfunction endValChange(index: number) {\n    endVal.value = index === 0 ? 608 : index === 1 ? 5604 : 45617;\n    reset();\n    start();\n}\n\nfunction durationChange(index: number) {\n    duration.value = index === 0 ? 1000 : index === 1 ? 2000 : 3000;\n}\n\nfunction boldChange(index: number) {\n    bold.value = !!!index;\n}\n\nfunction decimalsChange(index: number) {\n    decimals.value = index === 0 ? 2 : 0;\n}\n\nfunction statusChange(index: number) {\n    current.value = index;\n    if (index === 0) {\n        start();\n    } else if (index === 1) {\n        stop();\n    } else if (index === 2) {\n        resume();\n    } else {\n        reset();\n    }\n}\n\nfunction end() {\n    current.value = 3;\n    uToastRef.value?.show({\n        type: 'warning',\n        title: '滚动结束'\n    });\n}\n\nfunction start() {\n    current.value = 0;\n    isStop.value = true;\n    uCountToRef.value?.start();\n}\n\nfunction stop() {\n    uCountToRef.value?.stop();\n}\n\nfunction resume() {\n    if (!isStop.value) {\n        uToastRef.value?.show({\n            type: 'error',\n            title: '请开始并暂停后才能继续'\n        });\n        nextTick(() => {\n            current.value = 3;\n        });\n        return;\n    }\n    uCountToRef.value?.resume();\n}\n\nfunction reset() {\n    uCountToRef.value?.reset();\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.count-to-demo {\n    text-align: center;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsC/fab/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"Fab 悬浮按钮\"\n        desc=\"悬浮按钮（Floating Action Button）用于在页面右下角或指定位置提供常用快捷操作入口，支持拖拽、展开子操作项、以及多种布局策略。本文件按组件文档规范提供示例与 API 说明，包含平台差异与常见问题说明。\"\n        :apis=\"'fab'\"\n    >\n        <view class=\"u-demo fab-demo\">\n            <!-- 示例：自定义触发器 -->\n            <u-fab\n                v-if=\"trigger\"\n                ref=\"uFabRef\"\n                :type=\"type\"\n                :disabled=\"disabled\"\n                :draggable=\"draggable\"\n                :autoStick=\"autoStick\"\n                :direction=\"direction\"\n                :position=\"position\"\n                :gap=\"gapObj\"\n            >\n                <template #trigger>\n                    <u-button type=\"success\" shape=\"circle\" @click=\"handleShare\" :disabled=\"disabled\">\n                        <u-icon name=\"share\" size=\"30\" margin-right=\"20px\"></u-icon>\n                        分享给朋友\n                    </u-button>\n                </template>\n            </u-fab>\n            <!-- 示例：默认触发器有子项 -->\n            <u-fab\n                v-else-if=\"child\"\n                ref=\"uFabRef\"\n                :type=\"type\"\n                :disabled=\"disabled\"\n                :draggable=\"draggable\"\n                :autoStick=\"autoStick\"\n                :direction=\"direction\"\n                :position=\"position\"\n                :gap=\"gapObj\"\n            >\n                <u-button\n                    shape=\"circle\"\n                    size=\"mini\"\n                    type=\"primary\"\n                    custom-class=\"custom-button\"\n                    @click=\"handleBtnClick\"\n                >\n                    <u-icon name=\"thumb-up\" size=\"40\"></u-icon>\n                </u-button>\n                <u-button\n                    shape=\"circle\"\n                    size=\"mini\"\n                    type=\"warning\"\n                    custom-class=\"custom-button\"\n                    @click=\"handleBtnClick\"\n                >\n                    <u-icon name=\"heart\" size=\"40\"></u-icon>\n                </u-button>\n                <u-button shape=\"circle\" size=\"mini\" type=\"error\" custom-class=\"custom-button\" @click=\"handleBtnClick\">\n                    <u-icon name=\"kefu-ermai\" size=\"40\"></u-icon>\n                </u-button>\n                <u-button shape=\"circle\" size=\"mini\" type=\"success\" custom-class=\"custom-button\" @click=\"handleShare\">\n                    <u-icon name=\"zhuanfa\" size=\"40\"></u-icon>\n                </u-button>\n            </u-fab>\n            <!-- 示例：默认触发器无子项 -->\n            <u-fab\n                v-else\n                ref=\"uFabRef\"\n                :type=\"type\"\n                :disabled=\"disabled\"\n                :draggable=\"draggable\"\n                :autoStick=\"autoStick\"\n                :direction=\"direction\"\n                :position=\"position\"\n                :gap=\"gapObj\"\n                @trigger=\"handleTrigger\"\n            ></u-fab>\n            <view class=\"u-config-wrap\">\n                <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">主题选择</view>\n                    <u-subsection\n                        :list=\"['primary', 'info', 'error', 'warning', 'success']\"\n                        @change=\"typeChange\"\n                    ></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">禁用</view>\n                    <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"disabledChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">可以拖动</view>\n                    <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"draggableChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">位置</view>\n                    <u-subsection\n                        current=\"0\"\n                        :list=\"['右下', '右上', '左下', '左上']\"\n                        @change=\"positionChange\"\n                    ></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">子项弹出方向</view>\n                    <u-subsection current=\"0\" :list=\"['上', '下', '左', '右']\" @change=\"directionChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\"> 间距 </view>\n                    <u-number-box v-model=\"gap\" :step=\"2\" :min=\"0\" :max=\"40\"></u-number-box>\n                </view>\n                <view class=\"u-config-item\" v-if=\"!trigger\">\n                    <view class=\"u-item-title\">切换展开</view>\n                    <u-button type=\"primary\" size=\"medium\" @click=\"handleToggle\" :throttle-time=\"0\">切换</u-button>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">拖动自动吸边</view>\n                    <u-switch v-model=\"autoStick\"></u-switch>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">存在子项</view>\n                    <u-switch v-model=\"child\"></u-switch>\n                </view>\n\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">自定义触发器</view>\n                    <u-switch v-model=\"trigger\"></u-switch>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, ref } from 'vue';\nimport type { FabDirection, FabGap, FabPosition, ThemeType } from '@/uni_modules/uview-pro/types/global';\nimport { $u } from '@/uni_modules/uview-pro';\n\nconst uFabRef = ref<any>(null);\n// 主题选择\nconst type = ref<ThemeType>('primary');\nconst disabled = ref(false);\nconst draggable = ref(true);\nconst direction = ref<FabDirection>('top');\nconst position = ref<FabPosition>('right-bottom');\n// gap 现在支持四边配置\nconst gap = ref(16);\nconst trigger = ref(false);\nconst child = ref(true);\nconst autoStick = ref(true);\n\nconst gapObj = computed<FabGap>(() => {\n    return {\n        top: gap.value,\n        right: gap.value,\n        bottom: gap.value,\n        left: gap.value\n    };\n});\n\n// 主题选择切换\nfunction typeChange(e: number) {\n    switch (e) {\n        case 0:\n            type.value = 'primary';\n            break;\n        case 1:\n            type.value = 'info';\n            break;\n        case 2:\n            type.value = 'error';\n            break;\n        case 3:\n            type.value = 'warning';\n            break;\n        case 4:\n            type.value = 'success';\n            break;\n    }\n}\n\n// 禁用状态切换\nfunction disabledChange(index: number) {\n    disabled.value = index === 0 ? true : false;\n}\n\n// 可拖动切换\nfunction draggableChange(index: number) {\n    draggable.value = index === 0 ? true : false;\n}\n\n// 弹出位置切换\nfunction positionChange(index: number) {\n    switch (index) {\n        case 0:\n            position.value = 'right-bottom';\n            break;\n        case 1:\n            position.value = 'right-top';\n            break;\n        case 2:\n            position.value = 'left-bottom';\n            break;\n        case 3:\n            position.value = 'left-top';\n            break;\n    }\n}\n\n// 弹出方向切换\nfunction directionChange(index: number) {\n    switch (index) {\n        case 0:\n            direction.value = 'top';\n            break;\n        case 1:\n            direction.value = 'bottom';\n            break;\n        case 2:\n            direction.value = 'left';\n            break;\n        case 3:\n            direction.value = 'right';\n            break;\n    }\n}\n// 切换展开收起\nfunction handleToggle() {\n    if (uFabRef.value) {\n        uFabRef.value.toggle();\n    }\n}\n\n// 子项按钮点击事件\nfunction handleBtnClick() {\n    $u.toast('按钮被点击');\n    handleToggle();\n}\n\n// 按钮点击事件\nconst handleShare = () => {\n    $u.toast('点击了分享按钮');\n    // #ifdef H5\n    window.open('https://github.com/anyup/uView-Pro');\n    // #endif\n};\n// 触发器点击事件\nfunction handleTrigger() {\n    $u.toast('触发器被点击');\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.fab-demo {\n    :deep(.custom-button) {\n        min-width: auto !important;\n        box-sizing: border-box;\n        width: 40px !important;\n        height: 40px !important;\n        border-radius: 20px !important;\n        margin: 8rpx;\n    }\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsC/gap/index.vue",
    "content": "<template>\n    <demo-page title=\"Gap 间距\" desc=\"用于创建固定的间距，可以是垂直或水平方向。\" :apis=\"'gap'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-gap\n                            :bg-color=\"bgColor\"\n                            :height=\"height\"\n                            :margin-top=\"marginTop\"\n                            :margin-bottom=\"marginBottom\"\n                        ></u-gap>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\">参数配置</view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">背景颜色</view>\n                        <u-subsection\n                            :list=\"['default', 'primary', 'error', 'warning', 'success']\"\n                            @change=\"bgColorChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">高度</view>\n                        <u-subsection :list=\"['30', '50', '70']\" @change=\"heightChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">上下外边距</view>\n                        <u-subsection :list=\"['30', '50', '70']\" @change=\"marginChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\n\nconst height = ref(30);\nconst bgColor = ref($u.color.bgColor);\nconst marginTop = ref<number | string>(30);\nconst marginBottom = ref<number | string>(30);\n\nfunction bgColorChange(index: number) {\n    const color =\n        index === 0 ? 'default' : index === 1 ? 'primary' : index === 2 ? 'error' : index === 3 ? 'warning' : 'success';\n    bgColor.value = color === 'default' ? $u.color['bgColor'] : $u.color[color];\n}\n\nfunction heightChange(index: number) {\n    height.value = index === 0 ? 30 : index === 1 ? 50 : 70;\n}\n\nfunction marginChange(index: number) {\n    marginTop.value = ['30', '50', '70'][index];\n    marginBottom.value = marginTop.value;\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.wrap {\n    padding: 24rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsC/grid/index.vue",
    "content": "<template>\n    <demo-page title=\"Grid 栅格\" desc=\"12列栅格系统，用于响应式布局。\" :apis=\"'grid'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-toast ref=\"ToastRef\"></u-toast>\n                        <u-grid :col=\"col\" @click=\"click\" v-if=\"!isSwiper\" :border=\"border\">\n                            <u-grid-item name=\"item1\" :index=\"0\" @click=\"itemClick\">\n                                <u-badge count=\"9\" :offset=\"[col == 3 ? 20 : 14, col == 3 ? 30 : 20]\"></u-badge>\n                                <u-icon name=\"photo\" :size=\"46\"></u-icon>\n                                <view class=\"grid-text\">图片</view>\n                            </u-grid-item>\n                            <u-grid-item :index=\"1\">\n                                <u-icon name=\"lock\" :size=\"46\"></u-icon>\n                                <view class=\"grid-text\">锁头</view>\n                            </u-grid-item>\n                            <u-grid-item :index=\"2\">\n                                <image\n                                    src=\"https://ik.imagekit.io/anyup/uview-pro/grid/hot5.png\"\n                                    :style=\"{\n                                        top: col == 3 ? '14rpx' : '8rpx',\n                                        right: col == 3 ? '40rpx' : '28rpx'\n                                    }\"\n                                    style=\"width: 34rpx; height: 34rpx\"\n                                    class=\"badge-icon\"\n                                    mode=\"widthFix\"\n                                ></image>\n                                <u-icon name=\"hourglass\" :size=\"46\"></u-icon>\n                                <view class=\"grid-text\">沙漏</view>\n                            </u-grid-item>\n                            <u-grid-item :index=\"3\">\n                                <u-icon name=\"home\" :size=\"46\"></u-icon>\n                                <view class=\"grid-text\">首页</view>\n                            </u-grid-item>\n                            <u-grid-item :index=\"4\">\n                                <u-icon name=\"star\" :size=\"46\"></u-icon>\n                                <view class=\"grid-text\">星星</view>\n                            </u-grid-item>\n                            <u-grid-item :index=\"5\">\n                                <u-icon name=\"volume-up\" :size=\"46\"></u-icon>\n                                <view class=\"grid-text\">音量</view>\n                            </u-grid-item>\n                            <u-grid-item :index=\"6\">\n                                <image\n                                    src=\"https://ik.imagekit.io/anyup/uview-pro/grid/hot6.png\"\n                                    style=\"width: 44rpx; height: 44rpx; top: 0; right: 0\"\n                                    class=\"badge-icon\"\n                                ></image>\n                                <u-icon name=\"trash\" :size=\"46\"></u-icon>\n                                <view class=\"grid-text\">回收站</view>\n                            </u-grid-item>\n                            <u-grid-item :index=\"7\">\n                                <u-icon name=\"rewind-right\" :size=\"46\"></u-icon>\n                                <view class=\"grid-text\">快进</view>\n                            </u-grid-item>\n                            <u-grid-item :index=\"8\">\n                                <u-icon name=\"shopping-cart\" :size=\"46\"></u-icon>\n                                <view class=\"grid-text\">购物车</view>\n                            </u-grid-item>\n                        </u-grid>\n                        <swiper class=\"swiper\" v-else @change=\"change\">\n                            <swiper-item>\n                                <u-grid :border=\"border\" :col=\"col\" @click=\"click\" hover-class=\"hover-class\">\n                                    <u-grid-item v-for=\"(item, index) in list\" :index=\"index\" :key=\"index\">\n                                        <u-icon :name=\"item\" :size=\"46\"></u-icon>\n                                        <text class=\"grid-text\">{{ '宫格' + (index + 1) }}</text>\n                                    </u-grid-item>\n                                </u-grid>\n                            </swiper-item>\n                            <swiper-item>\n                                <u-grid :border=\"border\" :col=\"col\" @click=\"click\">\n                                    <u-grid-item v-for=\"(item, index) in list\" :index=\"index + 9\" :key=\"index\">\n                                        <u-icon :name=\"item\" :size=\"46\"></u-icon>\n                                        <text class=\"grid-text\">{{ '宫格' + (index + 1) }}</text>\n                                    </u-grid-item>\n                                </u-grid>\n                            </swiper-item>\n                            <swiper-item>\n                                <u-grid :border=\"border\" :col=\"col\" @click=\"click\">\n                                    <u-grid-item v-for=\"(item, index) in list\" :index=\"index + 18\" :key=\"index\">\n                                        <u-icon :name=\"item\" :size=\"46\"></u-icon>\n                                        <text class=\"grid-text\">{{ '宫格' + (index + 1) }}</text>\n                                    </u-grid-item>\n                                </u-grid>\n                            </swiper-item>\n                        </swiper>\n                        <view class=\"indicator-dots\" v-if=\"isSwiper\">\n                            <view class=\"indicator-dots-item\" :class=\"[current == 0 ? 'indicator-dots-active' : '']\">\n                            </view>\n                            <view class=\"indicator-dots-item\" :class=\"[current == 1 ? 'indicator-dots-active' : '']\">\n                            </view>\n                            <view class=\"indicator-dots-item\" :class=\"[current == 2 ? 'indicator-dots-active' : '']\">\n                            </view>\n                        </view>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">是否显示边框</view>\n                        <u-subsection :list=\"['是', '否']\" @change=\"borderChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">是否可滑动</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"isSwiperChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">修改列数</view>\n                        <u-subsection :list=\"['3', '4']\" @change=\"colChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\n\nconst ToastRef = ref(null);\n\nconst list = ref(['integral', 'kefu-ermai', 'coupon', 'gift', 'scan', 'pause-circle', 'wifi', 'email', 'list']);\nconst isSwiper = ref(false);\nconst current = ref(0);\nconst border = ref(true);\nconst col = ref(3);\n\nfunction isSwiperChange(index: number) {\n    isSwiper.value = index === 0;\n}\n\nfunction borderChange(index: number) {\n    border.value = index === 0;\n}\n\nfunction colChange(index: number) {\n    col.value = index === 0 ? 3 : 4;\n}\n\nfunction click(index: number) {\n    ToastRef.value?.show({\n        title: `点击了第${index + 1}宫格`,\n        type: 'warning'\n    });\n}\n\nfunction change(e) {\n    current.value = e.detail.current;\n}\n\n// 针对单个grid-item的事件\nfunction itemClick(index: number) {\n    // console.log(index);\n}\n</script>\n\n<style scoped lang=\"scss\">\n.grid-text {\n    font-size: 28rpx;\n    margin-top: 4rpx;\n    color: $u-type-info;\n}\n\n.badge-icon {\n    position: absolute;\n    width: 40rpx;\n    height: 40rpx;\n}\n\n.swiper {\n    height: 480rpx;\n}\n\n.indicator-dots {\n    margin-top: 40rpx;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n}\n\n.indicator-dots-item {\n    background-color: $u-tips-color;\n    height: 6px;\n    width: 6px;\n    border-radius: 10px;\n    margin: 0 3px;\n}\n\n.indicator-dots-active {\n    background-color: $u-type-primary;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsC/layout/index.vue",
    "content": "<template>\n    <demo-page title=\"Layout 布局\" desc=\"通过基础的 12 分栏，迅速简便地创建布局 \" :apis=\"'layout'\">\n        <view class=\"u-demo\">\n            <view class=\"u-demo-wrap\">\n                <view class=\"u-demo-title\">演示效果</view>\n                <view class=\"u-demo-area\">\n                    <u-row :justify=\"justify\" @click=\"rowClick\" :gutter=\"gutter\">\n                        <u-col :span=\"span\" :offset=\"offset\" @click=\"click\" stop>\n                            <view class=\"demo-layout bg-purple-dark\"> </view>\n                        </u-col>\n                        <u-col :span=\"span\" :offset=\"offset\">\n                            <view class=\"demo-layout bg-purple-dark\"> </view>\n                        </u-col>\n                        <u-col :span=\"span\" :offset=\"offset\">\n                            <view class=\"demo-layout bg-purple-dark\"> </view>\n                        </u-col>\n                    </u-row>\n                </view>\n            </view>\n            <view class=\"u-config-wrap\">\n                <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">每个栅格占用栏数(演示共3个栅格)</view>\n                    <u-subsection :current=\"2\" :list=\"['1', '2', '3', '4', '5']\" @change=\"spanChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">分栏间隔</view>\n                    <u-subsection :list=\"['10', '20', '30', '40']\" @change=\"gutterChange\"></u-subsection>\n                </view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">分栏偏移</view>\n                    <u-subsection :list=\"['0', '1', '2', '3', '4']\" @change=\"offsetChange\"></u-subsection>\n                </view>\n                <!-- #ifndef MP -->\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">水平排列方式(微信小程序无效)</view>\n                    <u-subsection :list=\"['start', 'end', 'around', 'between']\" @change=\"justifyChange\"></u-subsection>\n                </view>\n                <!-- #endif -->\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\nimport type { RowJustify } from '@/uni_modules/uview-pro/types/global';\n\nconst gutter = ref(10);\nconst span = ref(3);\nconst offset = ref(0);\nconst justify = ref<RowJustify>('start');\n\nfunction click() {\n    console.log('col click');\n}\n\nfunction rowClick() {\n    console.log('row click');\n}\n\nfunction spanChange(e: number) {\n    switch (e) {\n        case 0:\n            span.value = 1;\n            break;\n        case 1:\n            span.value = 2;\n            break;\n        case 2:\n            span.value = 3;\n            break;\n        case 3:\n            span.value = 4;\n            break;\n        case 4:\n            span.value = 5;\n            break;\n    }\n}\n\nfunction gutterChange(e: number) {\n    switch (e) {\n        case 0:\n            gutter.value = 10;\n            break;\n        case 1:\n            gutter.value = 20;\n            break;\n        case 2:\n            gutter.value = 30;\n            break;\n        case 3:\n            gutter.value = 40;\n            break;\n    }\n}\n\nfunction offsetChange(e: number) {\n    switch (e) {\n        case 0:\n            offset.value = 0;\n            break;\n        case 1:\n            offset.value = 1;\n            break;\n        case 2:\n            offset.value = 2;\n            break;\n        case 3:\n            offset.value = 3;\n            break;\n    }\n}\n\nfunction justifyChange(e: number) {\n    switch (e) {\n        case 0:\n            justify.value = 'start';\n            break;\n        case 1:\n            justify.value = 'end';\n            break;\n        case 2:\n            justify.value = 'around';\n            break;\n        case 3:\n            justify.value = 'between';\n            break;\n    }\n}\n</script>\n\n<style scoped lang=\"scss\">\n.demo-layout {\n    height: 70rpx;\n    border-radius: 8rpx;\n    margin: 20rpx 0;\n}\n\n.bg-purple {\n    background: #d3dce6;\n}\n\n.bg-purple-light {\n    background: #e5e9f2;\n}\n\n.bg-purple-dark {\n    background: #99a9bf;\n}\n\n// H5中，电脑端文档演示时，可能会导致演示块挤出边界，特别处理。\n// 真实使用环境不会产生此问题\n/* #ifdef H5 */\n.u-demo-area :deep(.u-row) {\n    display: flex;\n    flex-wrap: wrap;\n}\n/* #endif */\n</style>\n"
  },
  {
    "path": "src/pages/componentsC/link/index.vue",
    "content": "<template>\n    <demo-page title=\"Link 链接\" desc=\"用于展示链接，支持不同样式和功能。\" :apis=\"'link'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-link :color=\"color\" :font-size=\"fontSize\" :under-line=\"underLine\" :href=\"href\">\n                            点此链接，跳转uView官网\n                        </u-link>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">下划线</view>\n                        <u-subsection :list=\"['显示', '隐藏']\" @change=\"underLineChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">自定义样式</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"styleChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\n\nconst href = ref('https://uviewpro.cn/zh/');\nconst underLine = ref(true);\nconst fontSize = ref(28);\nconst color = ref($u.color.primary);\n\nfunction underLineChange(index: number) {\n    underLine.value = index === 0;\n}\n\nfunction styleChange(index: number) {\n    if (index === 0) {\n        color.value = $u.color['tipsColor'];\n        fontSize.value = 34;\n    } else {\n        color.value = $u.color['primary'];\n        fontSize.value = 28;\n    }\n}\n</script>\n"
  },
  {
    "path": "src/pages/componentsC/loadmore/index.vue",
    "content": "<template>\n    <demo-page title=\"Loadmore 加载更多\" desc=\"用于列表加载更多内容的提示组件。\" :apis=\"'loadmore'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-toast ref=\"uToastRef\" />\n                        <u-loadmore\n                            :status=\"status\"\n                            :loadText=\"loadText\"\n                            :icon-type=\"iconType\"\n                            :is-dot=\"isDot\"\n                            @loadmore=\"loadmore\"\n                        />\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">模式选择</view>\n                        <u-subsection\n                            :current=\"current\"\n                            :list=\"['加载前', '加载中', '加载后', '没有更多']\"\n                            @change=\"statusChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">自定义提示语</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"loadTextChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">加载中图标样式</view>\n                        <u-subsection :list=\"['circle', 'flower']\" @change=\"styleChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">没有更多时用点替代</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"isDotChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport type { LoadmoreIconType, LoadmoreStatus } from '@/uni_modules/uview-pro/types/global';\nimport { ref } from 'vue';\n\nconst uToastRef = ref();\nconst status = ref<LoadmoreStatus>('loadmore');\nconst iconType = ref<LoadmoreIconType>('circle');\nconst isDot = ref(false);\nconst loadText = ref({\n    loadmore: '点击或上拉加载更多',\n    loading: '正在加载...',\n    nomore: '没有更多了'\n});\nconst current = ref<number>(0);\n\nfunction statusChange(index: number) {\n    current.value = index;\n    status.value = index === 0 ? 'loadmore' : index === 1 ? 'loading' : index === 2 ? 'loadmore' : 'nomore';\n}\n\nfunction loadTextChange(index: number) {\n    if (index === 0) {\n        loadText.value = {\n            loadmore: '用力往上拉',\n            loading: '正在加载，请喝杯茶...',\n            nomore: '我也是有底线的'\n        };\n    } else {\n        loadText.value = {\n            loadmore: '点击或上拉加载更多',\n            loading: '正在加载...',\n            nomore: '没有更多了'\n        };\n    }\n}\n\nfunction styleChange(index: number) {\n    current.value = 1;\n    statusChange(1);\n    iconType.value = index === 0 ? 'circle' : 'flower';\n}\n\nfunction isDotChange(index: number) {\n    current.value = 3;\n    statusChange(3);\n    isDot.value = index === 0;\n}\n\n// 点击组件，触发加载更多事件(status为'loadmore'状态下才触发)\nfunction loadmore() {\n    uToastRef.value?.show({\n        title: '点击触发加载更多',\n        type: 'success'\n    });\n}\n\n// 页面触底事件\nfunction onReachBottom() {\n    // 在此请求下一页\n}\n</script>\n"
  },
  {
    "path": "src/pages/componentsC/mask/index.vue",
    "content": "<template>\n    <demo-page title=\"Mask 遮罩层\" desc=\"用于展示遮罩层，可用于模态对话框背景或其他遮挡效果。\" :apis=\"'mask'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-toast ref=\"uToastRef\"></u-toast>\n                        <view class=\"u-no-demo-here\"> 请点击弹出遮罩查看效果 </view>\n                        <u-mask :show=\"show\" @click=\"show = false\" :zoom=\"zoom\" :duration=\"duration\">\n                            <view class=\"warp\" v-if=\"content\">\n                                <view class=\"rect\" @tap.stop></view>\n                            </view>\n                        </u-mask>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">状态</view>\n                        <u-subsection :current=\"current\" :list=\"['显示', '隐藏']\" @change=\"showChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">缩放效果</view>\n                        <u-subsection :list=\"['是', '否']\" @change=\"zoomChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">内容填充</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"contentChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">动画时长(ms)</view>\n                        <u-subsection current=\"1\" :list=\"['100', '300', '800']\" @change=\"durationChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref, computed } from 'vue';\n\nconst uToastRef = ref();\nconst show = ref(false);\nconst zoom = ref(true);\nconst duration = ref(300);\nconst content = ref(false);\n\nconst current = computed<number>(() => {\n    return show.value ? 0 : 1;\n});\n\nfunction showChange(index: number) {\n    show.value = index === 0;\n}\n\nfunction zoomChange(index: number) {\n    zoom.value = index === 0;\n    show.value = true;\n}\n\nfunction durationChange(index: number) {\n    duration.value = index === 0 ? 100 : index === 1 ? 300 : 800;\n    show.value = true;\n}\n\nfunction contentChange(index: number) {\n    content.value = index === 0;\n    show.value = true;\n}\n</script>\n\n<style scoped lang=\"scss\">\n.warp {\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    height: 100%;\n}\n\n.rect {\n    width: 120px;\n    height: 120px;\n    background-color: #fff;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsC/messageInput/index.vue",
    "content": "<template>\n    <demo-page title=\"MessageInput 消息输入\" desc=\"用于快速输入消息，常用于聊天界面。\" :apis=\"'messageInput'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-toast ref=\"uToastRef\"></u-toast>\n                        <u-message-input\n                            :type=\"type\"\n                            :mode=\"mode\"\n                            :maxlength=\"maxlength\"\n                            :value=\"value\"\n                            :breathe=\"breathe\"\n                            :bold=\"bold\"\n                            :dot-fill=\"dotFill\"\n                            :focus=\"true\"\n                            @finish=\"finish\"\n                        ></u-message-input>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">模式选择</view>\n                        <u-subsection :list=\"['number', 'text']\" @change=\"typeChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">模式选择</view>\n                        <u-subsection :list=\"['方框', '下划线', '中划线']\" @change=\"modeChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">输入长度</view>\n                        <u-subsection :list=\"['4', '5', '6']\" @change=\"maxLengthChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <!-- #ifdef MP-WEIXIN -->\n                        <view class=\"u-item-title\">初始值(为满足演示需要，微信小程序切换会有抖动，非性能问题)</view>\n                        <!-- #endif -->\n                        <!-- #ifndef MP-WEIXIN -->\n                        <view class=\"u-item-title\">初始值</view>\n                        <!-- #endif -->\n                        <u-subsection :list=\"['空', '23', '678']\" @change=\"valueChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">呼吸灯效果</view>\n                        <u-subsection :list=\"['是', '否']\" @change=\"breatheChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">是否加粗</view>\n                        <u-subsection :list=\"['是', '否']\" @change=\"boldChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">点替代输入值</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"dotFillChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\nimport type { InputType, MessageInputMode } from '@/uni_modules/uview-pro/types/global';\n\nconst type = ref<InputType>('number');\nconst mode = ref<MessageInputMode>('box');\nconst maxlength = ref(4);\nconst value = ref('');\nconst bold = ref(true);\nconst breathe = ref(true);\nconst dotFill = ref(false);\nconst uToastRef = ref(null);\n\nfunction typeChange(index: number) {\n    type.value = index === 0 ? 'number' : 'text';\n}\n\nfunction modeChange(index: number) {\n    mode.value = index === 0 ? 'box' : index === 1 ? 'bottomLine' : 'middleLine';\n}\n\nfunction maxLengthChange(index: number) {\n    maxlength.value = index === 0 ? 4 : index === 1 ? 5 : 6;\n}\n\nfunction valueChange(index: number) {\n    value.value = index === 0 ? '' : index === 1 ? '23' : '678';\n}\n\nfunction breatheChange(index: number) {\n    breathe.value = index === 0;\n}\n\nfunction boldChange(index: number) {\n    bold.value = index === 0;\n}\n\nfunction dotFillChange(index: number) {\n    dotFill.value = index === 0;\n}\n\nfunction finish(value: string) {\n    uToastRef.value?.show({\n        title: '输入完成，值为：' + value,\n        type: 'success'\n    });\n}\n</script>\n"
  },
  {
    "path": "src/pages/componentsC/numberBox/index.vue",
    "content": "<template>\n    <demo-page title=\"NumberBox 数字输入\" desc=\"用于输入数字，可以通过按钮增减。\" :apis=\"'numberBox'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-number-box\n                            v-model=\"value\"\n                            :bg-color=\"bgColor\"\n                            :color=\"color\"\n                            :min=\"0\"\n                            :step=\"step\"\n                            :disabled=\"disabled\"\n                            :disabled-input=\"disabledInput\"\n                            @change=\"change\"\n                            @focus=\"focus\"\n                        ></u-number-box>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">初始值</view>\n                        <u-subsection :list=\"['1', '5', '18']\" @change=\"valueChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">自定义样式</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"styleChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">是否禁止输入框手动输入值</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"disabledInputChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">是否禁用</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"disabledChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">步进值</view>\n                        <u-subsection :list=\"['1', '3', '5', '8']\" @change=\"stepChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\n\nconst value = ref(1);\nconst bgColor = ref('#F2F3F5');\nconst color = ref('#323233');\nconst disabledInput = ref(false);\nconst disabled = ref(false);\nconst step = ref(1);\n\nfunction valueChange(index: number) {\n    value.value = index === 0 ? 1 : index === 1 ? 5 : 18;\n}\n\nfunction styleChange(index: number) {\n    if (index === 0) {\n        bgColor.value = '#ff6d00';\n        color.value = '#fff';\n    } else {\n        bgColor.value = '#F2F3F5';\n        color.value = '#323233';\n    }\n}\n\nfunction disabledInputChange(index: number) {\n    disabledInput.value = index === 0;\n}\n\nfunction disabledChange(index: number) {\n    disabled.value = index === 0;\n}\n\nfunction stepChange(index: number) {\n    step.value = index === 0 ? 1 : index === 1 ? 3 : index === 2 ? 5 : 8;\n}\n\ninterface ChangeEvent {\n    value: number;\n}\n\nfunction change(e: ChangeEvent) {\n    //console.log(e.value);\n}\n\nfunction focus() {\n    console.log('focus');\n}\n</script>\n"
  },
  {
    "path": "src/pages/componentsC/pagination/index.vue",
    "content": "<template>\n    <demo-page title=\"Pagination 分页\" desc=\"用于展示分页控件，支持多种配置方式。\" :apis=\"'pagination'\">\n        <template #default>\n            <view class=\"u-demo pagination-demo\">\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">默认</view>\n                        <u-pagination v-model=\"current\" :total=\"21\"></u-pagination>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">使用图标</view>\n                        <u-pagination v-model=\"current1\" :total=\"35\" show-icon></u-pagination>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">自定义图标（仅支持内置图标）</view>\n                        <u-pagination\n                            v-model=\"current2\"\n                            :total=\"49\"\n                            show-icon\n                            prev-icon=\"arrow-left-double\"\n                            next-icon=\"arrow-right-double\"\n                        ></u-pagination>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">触发 change 事件</view>\n                        <u-pagination v-model=\"current3\" :total=\"50\" @change=\"handleChange\"></u-pagination>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\nimport type { PaginationChangePayload } from '@/uni_modules/uview-pro/types/global';\n\nconst current = ref(1);\nconst current1 = ref(2);\nconst current2 = ref(1);\nconst current3 = ref(1);\n\n// 触发 change 事件\nfunction handleChange(val: PaginationChangePayload) {\n    $u.toast(`触发器被点击：${val.type}`);\n}\n</script>\n"
  },
  {
    "path": "src/pages/componentsC/popup/index.vue",
    "content": "<template>\n    <demo-page title=\"Popup 弹出框\" desc=\"用于展示弹出框内容，可以从上下左右展开。\" :apis=\"'popup'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-button @click=\"btnClick\">唤起弹窗</u-button>\n                        <u-popup\n                            border-radius=\"10\"\n                            v-model=\"show\"\n                            @close=\"close\"\n                            @open=\"open\"\n                            :mode=\"mode\"\n                            length=\"50%\"\n                            :mask=\"mask\"\n                            :closeable=\"closeable\"\n                            :close-icon-pos=\"closeIconPos\"\n                            :custom-class=\"mode === 'center' ? '' : 'custom-popup-class'\"\n                            :mask-close-able=\"maskClickAble\"\n                        >\n                            <view v-if=\"mode == 'center'\" style=\"height: 400rpx\">\n                                <view class=\"close-btn\">\n                                    <u-button @click=\"show = false\" size=\"medium\">关闭弹窗</u-button>\n                                </view>\n                            </view>\n                            <view class=\"close-btn\" v-if=\"mode != 'center'\">\n                                <u-button size=\"medium\" @click=\"show = false\">关闭弹窗</u-button>\n                            </view>\n                        </u-popup>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">状态</view>\n                        <u-subsection\n                            :current=\"show == false ? 1 : 0\"\n                            :list=\"['打开', '关闭']\"\n                            @change=\"showChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">弹出方向</view>\n                        <u-subsection\n                            :current=\"2\"\n                            :list=\"['上', '下', '左', '右', '中']\"\n                            @change=\"modeChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">点击遮罩是否关闭弹窗</view>\n                        <u-subsection :list=\"['是', '否']\" @change=\"maskClickAbleChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">关闭按钮</view>\n                        <u-subsection :list=\"['显示', '隐藏']\" @change=\"closeChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">关闭按钮位置</view>\n                        <u-subsection\n                            :current=\"1\"\n                            :list=\"['左上角', '右上角', '左下角', '右下角']\"\n                            @change=\"closePosChange\"\n                        ></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref, watch } from 'vue';\nimport type { PopupMode, PopupCloseIconPos } from '@/uni_modules/uview-pro/types/global';\nimport { completeMission } from '../../../common/useExperience';\n\nconst show = ref(false);\nconst mode = ref<PopupMode>('left');\nconst mask = ref(true); // 是否显示遮罩\nconst closeable = ref(true);\nconst closeIconPos = ref<PopupCloseIconPos>('top-right');\nconst maskClickAble = ref(true);\n\nwatch(show, newValue => {\n    // console.log(newValue);\n});\n\nfunction modeChange(index: number) {\n    mode.value = index === 0 ? 'top' : index === 1 ? 'bottom' : index === 2 ? 'left' : index === 3 ? 'right' : 'center';\n    show.value = true;\n}\n\nfunction showChange(index: number) {\n    show.value = index === 0;\n}\n\nfunction closeChange(index: number) {\n    closeable.value = !index;\n}\n\nfunction closePosChange(index: number) {\n    closeIconPos.value = ['top-left', 'top-right', 'bottom-left', 'bottom-right'][index] as PopupCloseIconPos;\n}\n\nfunction maskClickAbleChange(index: number) {\n    maskClickAble.value = !index;\n}\n\nfunction close() {\n    // console.log('close');\n}\n\nfunction open() {\n    // console.log('open');\n}\n\nfunction btnClick() {\n    show.value = true;\n    completeMission('popup');\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.wrap {\n    padding: 24rpx;\n}\n\n.close-btn {\n    height: 100%;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n}\n\n:deep(.custom-popup-class) {\n    .u-drawer-content {\n        background-color: $u-bg-color;\n    }\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsC/progress/index.vue",
    "content": "<template>\n    <demo-page title=\"Progress 进度条\" desc=\"用于展示进度，可配置颜色和尺寸。\" :apis=\"'progress'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-line-progress\n                            v-if=\"mode == 'line'\"\n                            :percent=\"percent\"\n                            :active-color=\"activeColor\"\n                            :striped=\"striped\"\n                            :stripedActive=\"stripedActive\"\n                        ></u-line-progress>\n                        <u-circle-progress\n                            v-else\n                            :percent=\"percent\"\n                            :active-color=\"activeColor\"\n                            :bg-color=\"$u.color.bgWhite\"\n                        >\n                            <view class=\"u-progress-content\">\n                                <view class=\"u-progress-dot\"></view>\n                                <text class=\"u-progress-info\">查找中</text>\n                            </view>\n                        </u-circle-progress>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">模式选择</view>\n                        <u-subsection :current=\"current\" :list=\"['线型', '圆型']\" @change=\"modeChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">增减</view>\n                        <u-subsection :list=\"['减少30%', '增加30%']\" @change=\"calcChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">自定义样式(线型时有效)</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"styleChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">动态条纹(线型时有效)</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"stripedChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\n\nconst percent = ref(50);\nconst mode = ref('line');\nconst activeColor = ref('#19be6b');\nconst striped = ref(false);\nconst stripedActive = ref(false);\nconst current = ref(0);\n\nfunction modeChange(index: number) {\n    current.value = index;\n    mode.value = index === 0 ? 'line' : 'circle';\n}\n\nfunction calcChange(index: number) {\n    percent.value = index === 0 ? percent.value - 30 : percent.value + 30;\n    if (percent.value > 100) percent.value = 100;\n    if (percent.value < 0) percent.value = 0;\n}\n\nfunction styleChange(index: number) {\n    activeColor.value = index === 0 ? $u.color['error'] : '#19be6b';\n    if (index === 0) {\n        mode.value = 'line';\n        current.value = 0;\n    }\n}\n\nfunction stripedChange(index: number) {\n    striped.value = index === 0;\n    stripedActive.value = striped.value;\n    if (index === 0) {\n        mode.value = 'line';\n        current.value = 0;\n    }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.u-progress-content {\n    display: flex;\n    align-items: center;\n    justify-content: center;\n}\n\n.u-progress-dot {\n    width: 16rpx;\n    height: 16rpx;\n    border-radius: 50%;\n    background-color: #fb9126;\n}\n\n.u-progress-info {\n    font-size: 28rpx;\n    padding-left: 16rpx;\n    letter-spacing: 2rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/componentsC/section/index.vue",
    "content": "<template>\n    <demo-page title=\"Section 分段\" desc=\"用于分段显示内容，常用于对内容进行分组。\" :apis=\"'section'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-section\n                            :title=\"title\"\n                            :right=\"right\"\n                            :bold=\"bold\"\n                            :color=\"color\"\n                            :show-line=\"showLine\"\n                        ></u-section>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">更换主标题</view>\n                        <u-subsection :current=\"1\" :list=\"['是', '否']\" @change=\"titleChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">竖条状态</view>\n                        <u-subsection :list=\"['显示', '隐藏']\" @change=\"showLineChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">是否显示右边部分</view>\n                        <u-subsection :list=\"['是', '否']\" @change=\"rightChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">主标题粗体</view>\n                        <u-subsection :list=\"['是', '否']\" @change=\"boldChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">主标题颜色</view>\n                        <u-subsection :list=\"['默认', '自定义']\" @change=\"colorChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\n\nconst title = ref('红豆生南国');\nconst bold = ref(true);\nconst right = ref(true);\nconst color = ref($u.color['mainColor']);\nconst showLine = ref(true);\n\nfunction titleChange(index: number) {\n    if (index === 0) title.value = '春来发几枝';\n    else title.value = '红豆生南国';\n}\n\nfunction rightChange(index: number) {\n    right.value = index === 0;\n}\n\nfunction boldChange(index: number) {\n    bold.value = index === 0;\n}\n\nfunction colorChange(index: number) {\n    color.value = index === 0 ? $u.color['mainColor'] : $u.color['primary'];\n}\n\nfunction showLineChange(index: number) {\n    showLine.value = !index;\n}\n</script>\n"
  },
  {
    "path": "src/pages/componentsC/subsection/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"Subsection 分段选择器\"\n        desc=\"用于在多个选项间进行选择，可切换按钮或分段样式。\"\n        :apis=\"'subsection'\"\n    >\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-subsection\n                            :bold=\"bold\"\n                            :active-color=\"activeColor\"\n                            :current=\"current\"\n                            :mode=\"mode\"\n                            :list=\"list\"\n                        ></u-subsection>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">模式选择</view>\n                        <u-subsection\n                            mode=\"button\"\n                            :list=\"['button', 'subsection']\"\n                            @change=\"modeChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">Current值</view>\n                        <u-subsection mode=\"button\" :list=\"['0', '1', '2']\" @change=\"currentChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">活动选项字颜色</view>\n                        <u-subsection\n                            mode=\"button\"\n                            :list=\"['primary', 'success', 'error', 'warning']\"\n                            @change=\"colorChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">字体加粗</view>\n                        <u-subsection mode=\"button\" :list=\"['是', '否']\" @change=\"boldChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\nimport type { SubsectionListItem, SubsectionMode } from '@/uni_modules/uview-pro/types/global';\n\nconst mode = ref<SubsectionMode>('button');\nconst current = ref(0);\nconst activeColor = ref($u.color['primary']);\nconst bold = ref(true);\nconst list = ref<SubsectionListItem[]>([{ name: '待付款' }, { name: '待收货' }, { name: '选项三' }]);\nfunction modeChange(e: number) {\n    switch (e) {\n        case 0:\n            mode.value = 'button';\n            break;\n        case 1:\n            mode.value = 'subsection';\n            break;\n    }\n}\n\nfunction currentChange(e: number) {\n    current.value = e;\n}\n\nfunction colorChange(e: number) {\n    let color = 'primary';\n    switch (e) {\n        case 0:\n            color = 'primary';\n            break;\n        case 1:\n            color = 'success';\n            break;\n        case 2:\n            color = 'error';\n            break;\n        case 3:\n            color = 'warning';\n            break;\n    }\n    activeColor.value = $u.color[color];\n}\n\nfunction boldChange(e: number) {\n    switch (e) {\n        case 0:\n            bold.value = true;\n            break;\n        case 1:\n            bold.value = false;\n            break;\n    }\n}\n</script>\n"
  },
  {
    "path": "src/pages/componentsC/text/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"Text 文本\"\n        desc=\"此组件集成了文本类在项目中的常用功能，包括状态，拨打电话，格式化日期，*替换，超链接...等功能。您大可不必在使用特殊文本时自己定义，text组件几乎涵盖您能使用的大部分场景。\"\n        :apis=\"'text'\"\n    >\n        <view class=\"u-page\">\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">基础功能</text>\n                <view class=\"u-demo-block__content\">\n                    <view class=\"u-page__text-item\">\n                        <u-text text=\"我用十年青春,赴你最后之约\"></u-text>\n                    </view>\n                </view>\n            </view>\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">设置主题</text>\n                <view class=\"u-demo-block__content\">\n                    <view class=\"u-page__text-item\">\n                        <u-text text=\"主色\" type=\"primary\"></u-text>\n                    </view>\n                    <view class=\"u-page__text-item\">\n                        <u-text type=\"error\" text=\"错误\"></u-text>\n                    </view>\n                    <view class=\"u-page__text-item\">\n                        <u-text type=\"success\" text=\"成功\"></u-text>\n                    </view>\n                    <view class=\"u-page__text-item\">\n                        <u-text type=\"warning\" text=\"警告\"></u-text>\n                    </view>\n                    <view class=\"u-page__text-item\">\n                        <u-text type=\"info\" text=\"信息\"></u-text>\n                    </view>\n                </view>\n            </view>\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">拨打电话</text>\n                <view class=\"u-demo-block__content\">\n                    <view class=\"u-page__text-item\">\n                        <u-text mode=\"phone\" text=\"15019479320\"></u-text>\n                    </view>\n                </view>\n            </view>\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">日期格式化</text>\n                <view class=\"u-demo-block__content\">\n                    <view class=\"u-page__text-item\">\n                        <u-text mode=\"date\" text=\"1612959739\"></u-text>\n                    </view>\n                </view>\n            </view>\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">姓名脱敏</text>\n                <view class=\"u-demo-block__content\">\n                    <view class=\"u-page__text-item\">\n                        <u-text mode=\"name\" text=\"张三三\" format=\"encrypt\"></u-text>\n                    </view>\n                </view>\n            </view>\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">超链接</text>\n                <view class=\"u-demo-block__content\">\n                    <view class=\"u-page__text-item\">\n                        <u-text mode=\"link\" text=\"Go to uView Pro docs\" href=\"https://uviewpro.cn\"></u-text>\n                    </view>\n                </view>\n            </view>\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">显示金额</text>\n                <view class=\"u-demo-block__content\">\n                    <view class=\"u-page__text-item\">\n                        <u-text mode=\"price\" text=\"728732.32\"></u-text>\n                    </view>\n                </view>\n            </view>\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">前后图标</text>\n                <view class=\"u-demo-block__content\">\n                    <view class=\"u-page__text-item\" style=\"margin-right: 50px\">\n                        <u-text prefixIcon=\"baidu\" iconStyle=\"font-size: 19px\" text=\"百度一下\"></u-text>\n                    </view>\n                    <view class=\"u-page__text-item\">\n                        <u-text\n                            suffixIcon=\"arrow-rightward\"\n                            iconStyle=\"font-size: 18px\"\n                            text=\"查看更多\"\n                            align=\"right\"\n                            block\n                        ></u-text>\n                    </view>\n                </view>\n            </view>\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">超出1行隐藏</text>\n                <view class=\"u-demo-block__content\">\n                    <u-text\n                        :lines=\"1\"\n                        text=\"uView Pro 是在 uView 1.8.8 官方组件库基础上，采用 Vue3 全新语法彻底重构的 uni-app 生态框架。不同于市面上的其他 uView 框架等兼容 Vue3 的方案，uView Pro 并非简单兼容，而是对每一个组件和工具进行源码级重构，充分发挥 Vue3 的响应式和组合式优势，API 设计更现代，性能更优越。\"\n                    ></u-text>\n                </view>\n            </view>\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">超出多行隐藏</text>\n                <view class=\"u-demo-block__content\">\n                    <u-text\n                        :lines=\"2\"\n                        text=\"uView Pro 是在 uView 1.8.8 官方组件库基础上，采用 Vue3 全新语法彻底重构的 uni-app 生态框架。不同于市面上的其他 uView 框架等兼容 Vue3 的方案，uView Pro 并非简单兼容，而是对每一个组件和工具进行源码级重构，充分发挥 Vue3 的响应式和组合式优势，API 设计更现代，性能更优越。\"\n                    ></u-text>\n                </view>\n            </view>\n            <!-- #ifdef MP-WEIXIN -->\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">小程序开放能力</text>\n                <view class=\"u-demo-block__content\">\n                    <u-text\n                        text=\"分享到微信\"\n                        openType=\"share\"\n                        type=\"success\"\n                        align=\"left\"\n                        @click=\"clickHandler\"\n                    ></u-text>\n                </view>\n            </view>\n            <!-- #endif -->\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\n// 微信小程序开放能力点击事件\nconst clickHandler = () => {\n    // #ifndef MP-WEIXIN\n    uni.$u.toast('请在微信小程序内查看效果');\n    // #endif\n};\n</script>\n\n<style lang=\"scss\">\n.u-page__text-item {\n    margin-right: 10px;\n    flex: 1;\n}\n\n.u-demo-block__content {\n    flex-direction: row;\n    flex-wrap: wrap;\n    align-items: center;\n}\n</style>\n"
  },
  {
    "path": "src/pages/example/about/about-me.vue",
    "content": "<template>\n    <demo-page nav-title=\"关于我\" :nav-back=\"true\" hide-tabs>\n        <view class=\"about-me-page\">\n            <view class=\"section-card\">\n                <view class=\"section-card__header\">\n                    <u-icon name=\"account\" size=\"40\" color=\"var(--u-type-primary)\"></u-icon>\n                    <text class=\"section-card__title\">关于我</text>\n                </view>\n                <view class=\"section-card__body\">\n                    <view class=\"about-text\">\n                        <text class=\"about-text__highlight\">\"前端梦工厂\"</text>\n                        <text>\n                            ，一名前端开发工程师，致力于分享各种前端技术最佳解决方案。关注我，让我们一起逐梦前端！\n                        </text>\n                    </view>\n                </view>\n            </view>\n\n            <view class=\"section-card\">\n                <view class=\"section-card__header\">\n                    <u-icon name=\"chat\" size=\"40\" color=\"var(--u-type-success)\"></u-icon>\n                    <text class=\"section-card__title\">联系方式</text>\n                </view>\n                <view class=\"section-card__body\">\n                    <view class=\"contact-item\">\n                        <view class=\"contact-item__label\">微信号</view>\n                        <view class=\"contact-item__value\">anyupxing</view>\n                    </view>\n                    <view class=\"contact-item\">\n                        <view class=\"contact-item__label\">公众号</view>\n                        <view class=\"contact-item__value\">前端梦工厂</view>\n                    </view>\n                </view>\n            </view>\n\n            <view class=\"section-card\">\n                <view class=\"section-card__header\">\n                    <u-icon name=\"star\" size=\"40\" color=\"var(--u-type-warning)\"></u-icon>\n                    <text class=\"section-card__title\">个人简介</text>\n                </view>\n                <view class=\"section-card__body\">\n                    <view class=\"intro-text\">\n                        <text>\n                            专注于前端开发领域，拥有丰富的跨平台开发经验。致力于打造高质量、易用的 UI\n                            组件库，帮助开发者提升开发效率。\n                        </text>\n                    </view>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\"></script>\n\n<style lang=\"scss\" scoped>\n.about-me-page {\n    padding: 24rpx;\n    background: linear-gradient(180deg, rgba(41, 121, 255, 0.03) 0%, transparent 100%);\n    min-height: 100vh;\n    display: flex;\n    flex-direction: column;\n    gap: 24rpx;\n}\n\n.section-card {\n    background: $u-bg-gray-light;\n    border-radius: 20rpx;\n    box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.06);\n    overflow: hidden;\n    transition: all 0.3s ease;\n\n    &__header {\n        padding: 28rpx 32rpx;\n        display: flex;\n        align-items: center;\n        gap: 16rpx;\n        background: linear-gradient(135deg, rgba(41, 121, 255, 0.05), rgba(25, 190, 107, 0.05));\n        border-bottom: 1rpx solid rgba(0, 0, 0, 0.04);\n    }\n\n    &__title {\n        font-size: 32rpx;\n        font-weight: 700;\n        color: $u-main-color;\n        letter-spacing: 1rpx;\n    }\n\n    &__body {\n        padding: 24rpx 32rpx 32rpx;\n    }\n}\n\n.about-text {\n    font-size: 28rpx;\n    line-height: 1.8;\n    color: $u-content-color;\n\n    &__highlight {\n        font-weight: 700;\n        background: linear-gradient(135deg, #2979ff, #19be6b);\n        -webkit-background-clip: text;\n        -webkit-text-fill-color: transparent;\n        background-clip: text;\n    }\n}\n\n.contact-item {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    padding: 20rpx 0;\n    border-bottom: 1rpx solid rgba(0, 0, 0, 0.04);\n\n    &:last-child {\n        border-bottom: none;\n    }\n\n    &__label {\n        font-size: 28rpx;\n        color: $u-content-color;\n    }\n\n    &__value {\n        font-size: 28rpx;\n        font-weight: 600;\n        color: $u-main-color;\n    }\n}\n\n.intro-text {\n    font-size: 28rpx;\n    line-height: 1.8;\n    color: $u-content-color;\n}\n</style>\n"
  },
  {
    "path": "src/pages/example/about/contributors.vue",
    "content": "<template>\n    <demo-page nav-title=\"贡献者\" :nav-back=\"true\" hide-tabs>\n        <view class=\"contributors-page\">\n            <view class=\"section-card\">\n                <view class=\"section-card__header\">\n                    <u-icon name=\"man-add\" size=\"40\" color=\"var(--u-type-primary)\"></u-icon>\n                    <text class=\"section-card__title\">贡献者列表</text>\n                </view>\n                <view class=\"section-card__body\">\n                    <view class=\"contributors-intro\">\n                        <text>感谢所有为 uView Pro 做出贡献的开发者们！你们的支持让这个项目变得更好。</text>\n                    </view>\n                </view>\n            </view>\n\n            <view class=\"section-card\">\n                <view class=\"section-card__header\">\n                    <u-icon name=\"star\" size=\"40\" color=\"var(--u-type-warning)\"></u-icon>\n                    <text class=\"section-card__title\">活跃贡献者</text>\n                </view>\n                <view class=\"section-card__body\">\n                    <view v-for=\"(contributor, index) in contributors\" :key=\"index\" class=\"contributor-item\">\n                        <view class=\"contributor-item__avatar\">\n                            <u-avatar :src=\"getAvatarUrl(contributor.github)\" size=\"80\"></u-avatar>\n                        </view>\n                        <view class=\"contributor-item__info\">\n                            <view class=\"contributor-item__name\">{{ contributor.name }}</view>\n                            <view class=\"contributor-item__github\" v-if=\"contributor.github\">\n                                @{{ contributor.github }}\n                            </view>\n                            <view class=\"contributor-item__desc\" v-if=\"contributor.desc\">\n                                {{ contributor.desc }}\n                            </view>\n                        </view>\n                    </view>\n                </view>\n            </view>\n\n            <view class=\"section-card\">\n                <view class=\"section-card__header\">\n                    <u-icon name=\"heart\" size=\"40\" color=\"var(--u-type-error)\"></u-icon>\n                    <text class=\"section-card__title\">如何贡献</text>\n                </view>\n                <view class=\"section-card__body\">\n                    <view class=\"contribute-item\" v-for=\"(item, index) in contributeWays\" :key=\"index\">\n                        <view class=\"contribute-item__icon\">\n                            <u-icon :name=\"item.icon\" size=\"40\" :color=\"item.color\"></u-icon>\n                        </view>\n                        <view class=\"contribute-item__content\">\n                            <view class=\"contribute-item__title\">{{ item.title }}</view>\n                            <view class=\"contribute-item__desc\">{{ item.desc }}</view>\n                        </view>\n                    </view>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\n\n// 贡献者列表\nconst contributors = ref([\n    {\n        name: '前端梦工厂',\n        github: 'anyup',\n        desc: '项目创始人 & 核心维护者'\n    },\n    {\n        name: 'Bin',\n        github: 'ffgenius',\n        desc: '活跃贡献者'\n    },\n    {\n        name: 'Meet you',\n        github: 'wjp980108',\n        desc: '活跃贡献者'\n    },\n    {\n        name: 'Flyer',\n        github: 'Lonely-flyer',\n        desc: '活跃贡献者'\n    },\n    {\n        name: 'liujiayii',\n        github: 'liujiayii',\n        desc: '活跃贡献者'\n    },\n    {\n        name: 'XiaoZuoOvO',\n        github: 'zuo-wentao',\n        desc: '活跃贡献者'\n    },\n    {\n        name: '不爱说话郭德纲',\n        github: 'elkelkelkelkelk',\n        desc: '活跃贡献者'\n    }\n]);\n\n// 贡献方式\nconst contributeWays = ref([\n    {\n        icon: 'plus-circle',\n        title: '提交代码',\n        desc: '修复 Bug 或添加新功能',\n        color: 'var(--u-type-primary)'\n    },\n    {\n        icon: 'file-text',\n        title: '完善文档',\n        desc: '改进文档和示例',\n        color: 'var(--u-type-success)'\n    },\n    {\n        icon: 'question-circle',\n        title: '报告问题',\n        desc: '发现并报告 Bug',\n        color: 'var(--u-type-warning)'\n    },\n    {\n        icon: 'info-circle',\n        title: '提出建议',\n        desc: '分享你的想法和建议',\n        color: 'var(--u-type-error)'\n    }\n]);\n\n// 获取头像 URL\nfunction getAvatarUrl(github: string) {\n    if (!github) return '';\n    // #ifdef APP\n    return `/static/app/avatar/${github}.jpg`;\n    // #endif\n    return `https://ik.imagekit.io/anyup/uview-pro/avatar/${github}.jpg`;\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.contributors-page {\n    padding: 24rpx;\n    background: linear-gradient(180deg, rgba(41, 121, 255, 0.03) 0%, transparent 100%);\n    min-height: 100vh;\n    display: flex;\n    flex-direction: column;\n    gap: 24rpx;\n}\n\n.section-card {\n    background: $u-bg-gray-light;\n    border-radius: 20rpx;\n    box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.06);\n    overflow: hidden;\n    transition: all 0.3s ease;\n\n    &__header {\n        padding: 28rpx 32rpx;\n        display: flex;\n        align-items: center;\n        gap: 16rpx;\n        background: linear-gradient(135deg, rgba(41, 121, 255, 0.05), rgba(25, 190, 107, 0.05));\n        border-bottom: 1rpx solid rgba(0, 0, 0, 0.04);\n    }\n\n    &__title {\n        font-size: 32rpx;\n        font-weight: 700;\n        color: $u-main-color;\n        letter-spacing: 1rpx;\n    }\n\n    &__body {\n        padding: 24rpx 32rpx 32rpx;\n    }\n}\n\n.contributors-intro {\n    font-size: 28rpx;\n    line-height: 1.8;\n    color: $u-content-color;\n    text-align: center;\n    padding: 20rpx 0;\n}\n\n.contributor-item {\n    display: flex;\n    align-items: center;\n    gap: 24rpx;\n    padding: 24rpx 0;\n    border-bottom: 1rpx solid rgba(0, 0, 0, 0.04);\n\n    &:last-child {\n        border-bottom: none;\n    }\n\n    &__avatar {\n        flex-shrink: 0;\n    }\n\n    &__info {\n        flex: 1;\n        display: flex;\n        flex-direction: column;\n        gap: 8rpx;\n    }\n\n    &__name {\n        font-size: 30rpx;\n        font-weight: 600;\n        color: $u-main-color;\n    }\n\n    &__github {\n        font-size: 24rpx;\n        color: var(--u-type-primary);\n    }\n\n    &__desc {\n        font-size: 24rpx;\n        color: $u-tips-color;\n    }\n}\n\n.contribute-item {\n    display: flex;\n    align-items: flex-start;\n    gap: 20rpx;\n    padding: 24rpx 0;\n    border-bottom: 1rpx solid rgba(0, 0, 0, 0.04);\n\n    &:last-child {\n        border-bottom: none;\n    }\n\n    &__icon {\n        flex-shrink: 0;\n        width: 80rpx;\n        height: 80rpx;\n        border-radius: 16rpx;\n        background: rgba(41, 121, 255, 0.08);\n        display: flex;\n        align-items: center;\n        justify-content: center;\n    }\n\n    &__content {\n        flex: 1;\n        display: flex;\n        flex-direction: column;\n        gap: 8rpx;\n    }\n\n    &__title {\n        font-size: 28rpx;\n        font-weight: 600;\n        color: $u-main-color;\n    }\n\n    &__desc {\n        font-size: 24rpx;\n        color: $u-tips-color;\n        line-height: 1.6;\n    }\n}\n</style>\n"
  },
  {
    "path": "src/pages/example/about/faq.vue",
    "content": "<template>\n    <demo-page nav-title=\"常见问题\" :nav-back=\"true\" hide-tabs>\n        <view class=\"faq-page\">\n            <view class=\"section-card\">\n                <view class=\"section-card__header\">\n                    <u-icon name=\"question-circle\" size=\"40\" color=\"var(--u-type-primary)\"></u-icon>\n                    <text class=\"section-card__title\">常见问题</text>\n                </view>\n                <view class=\"section-card__body\">\n                    <u-collapse v-model=\"activeNames\" :border=\"false\">\n                        <u-collapse-item v-for=\"(item, index) in faqList\" :key=\"index\" :name=\"index\" :title=\"item.q\">\n                            <view class=\"faq-answer\">{{ item.a }}</view>\n                        </u-collapse-item>\n                    </u-collapse>\n                </view>\n            </view>\n\n            <view class=\"section-card\">\n                <view class=\"section-card__header\">\n                    <u-icon name=\"chat\" size=\"40\" color=\"var(--u-type-success)\"></u-icon>\n                    <text class=\"section-card__title\">需要帮助？</text>\n                </view>\n                <view class=\"section-card__body\">\n                    <view class=\"help-text\">\n                        <text>如果这里没有找到您想要的答案，可以通过以下方式联系我们：</text>\n                    </view>\n                    <view class=\"help-links\">\n                        <view class=\"help-link\" @click=\"copyLink('https://uviewpro.cn')\">\n                            <u-icon name=\"chrome-circle-fill\" size=\"32\" color=\"var(--u-type-primary)\"></u-icon>\n                            <text>访问官网文档：https://uviewpro.cn</text>\n                        </view>\n                        <view class=\"help-link\" @click=\"copyLink('https://github.com/anyup/uview-pro')\">\n                            <u-icon name=\"github-circle-fill\" size=\"32\" color=\"var(--u-type-info)\"></u-icon>\n                            <text>访问 GitHub 仓库：https://github.com/anyup/uview-pro</text>\n                        </view>\n                        <view class=\"help-link\" @click=\"preview('weixin-chat-cl')\">\n                            <u-icon name=\"chat\" size=\"32\" color=\"var(--u-type-success)\"></u-icon>\n                            <text>加入交流群</text>\n                        </view>\n                    </view>\n                </view>\n            </view>\n            <u-toast ref=\"uToastRef\" />\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\n\nconst uToastRef = ref();\n\n// 展开的项\nconst activeNames = ref<number[]>([0]);\n\n// FAQ 列表\nconst faqList = ref([\n    {\n        q: 'uView Pro 支持哪些平台？',\n        a: 'uView Pro 支持 H5、微信小程序、支付宝小程序、App（Android/iOS）、HarmonyOS 等多个平台，一套代码多端运行。'\n    },\n    {\n        q: '如何开始使用 uView Pro？',\n        a: '您可以通过 pnpm、npm 或 yarn 安装 uView Pro，然后在项目中引入组件即可使用。详细的使用文档请访问官网：https://uviewpro.cn'\n    },\n    {\n        q: 'uView Pro 是免费的吗？',\n        a: '是的，uView Pro 采用 MIT 开源协议，完全免费使用，包括商业项目。'\n    },\n    {\n        q: '如何自定义主题？',\n        a: 'uView Pro 提供了丰富的主题配置选项，您可以通过 ConfigProvider 组件或主题配置文件来自定义主题颜色、字体等样式。'\n    },\n    {\n        q: '遇到问题如何反馈？',\n        a: '您可以通过 GitHub Issues、微信交流群或官网反馈问题。我们会及时处理您的反馈。'\n    },\n    {\n        q: '如何贡献代码？',\n        a: '欢迎提交 Pull Request！请先 Fork 项目，创建功能分支，提交代码后发起 PR。我们会及时审查您的贡献。'\n    },\n    {\n        q: '组件支持暗黑模式吗？',\n        a: '是的，uView Pro 完全支持暗黑模式，您可以通过主题系统轻松切换明暗主题。'\n    },\n    {\n        q: '性能如何？',\n        a: 'uView Pro 经过精心优化，组件体积小、性能优异。我们持续优化组件性能，确保在各种设备上都能流畅运行。'\n    }\n]);\n\n// 复制链接\nfunction copyLink(url: string) {\n    // #ifdef H5\n    window.open(url);\n    // #endif\n    // #ifndef H5\n    uni.setClipboardData({\n        data: url,\n        success: () => {\n            showToast('链接已复制，请打开浏览器粘贴访问');\n        }\n    });\n    // #endif\n}\n\n// 图片预览\nfunction preview(url: string) {\n    if (!url) return;\n    if (!url.includes('http')) {\n        url = getImageUrl(url, true);\n    }\n    uni.previewImage({\n        urls: [url],\n        current: url\n    });\n}\n\n// 获取图片地址\nfunction getImageUrl(name: string, force: boolean = false) {\n    let url = `https://ik.imagekit.io/anyup/images/social/${name}.png`;\n    // #ifdef APP-HARMONY\n    url = `/static/app/${name}.png`;\n    // #endif\n    // #ifndef APP-HARMONY\n    if (force) {\n        url = `${url}?updatedAt=${new Date().getTime()}`;\n    }\n    // #endif\n    return url;\n}\n\n// 显示 Toast\nfunction showToast(title: string) {\n    uToastRef.value?.show({\n        title: title,\n        type: 'success'\n    });\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.faq-page {\n    padding: 24rpx;\n    background: linear-gradient(180deg, rgba(41, 121, 255, 0.03) 0%, transparent 100%);\n    min-height: 100vh;\n    display: flex;\n    flex-direction: column;\n    gap: 24rpx;\n}\n\n.section-card {\n    background: $u-bg-gray-light;\n    border-radius: 20rpx;\n    box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.06);\n    overflow: hidden;\n    transition: all 0.3s ease;\n\n    &__header {\n        padding: 28rpx 32rpx;\n        display: flex;\n        align-items: center;\n        gap: 16rpx;\n        background: linear-gradient(135deg, rgba(41, 121, 255, 0.05), rgba(25, 190, 107, 0.05));\n        border-bottom: 1rpx solid rgba(0, 0, 0, 0.04);\n    }\n\n    &__title {\n        font-size: 32rpx;\n        font-weight: 700;\n        color: $u-main-color;\n        letter-spacing: 1rpx;\n    }\n\n    &__body {\n        padding: 24rpx 32rpx 32rpx;\n    }\n}\n\n.faq-answer {\n    font-size: 26rpx;\n    line-height: 1.8;\n    color: $u-content-color;\n    padding: 16rpx 0;\n}\n\n.help-text {\n    font-size: 28rpx;\n    line-height: 1.8;\n    color: $u-content-color;\n    margin-bottom: 24rpx;\n}\n\n.help-links {\n    display: flex;\n    flex-direction: column;\n    gap: 16rpx;\n}\n\n.help-link {\n    display: flex;\n    align-items: center;\n    gap: 16rpx;\n    padding: 24rpx;\n    background: rgba(41, 121, 255, 0.06);\n    border-radius: 16rpx;\n    transition: all 0.3s ease;\n\n    &:active {\n        background: rgba(41, 121, 255, 0.12);\n        transform: scale(0.98);\n    }\n\n    text {\n        font-size: 28rpx;\n        color: $u-main-color;\n        font-weight: 500;\n    }\n}\n</style>\n"
  },
  {
    "path": "src/pages/example/about/guide.vue",
    "content": "<template>\n    <demo-page nav-title=\"使用指南\" :nav-back=\"true\" hide-tabs>\n        <view class=\"guide-page\">\n            <view class=\"section-card\">\n                <view class=\"section-card__header\">\n                    <u-icon name=\"book\" size=\"40\" color=\"var(--u-type-primary)\"></u-icon>\n                    <text class=\"section-card__title\">快速开始</text>\n                </view>\n                <view class=\"section-card__body\">\n                    <view class=\"guide-step\" v-for=\"(step, index) in quickStartSteps\" :key=\"index\">\n                        <view class=\"guide-step__number\">{{ index + 1 }}</view>\n                        <view class=\"guide-step__content\">\n                            <view class=\"guide-step__title\">{{ step.title }}</view>\n                            <view class=\"guide-step__desc\">{{ step.desc }}</view>\n                            <view class=\"guide-step__code\" v-if=\"step.code\">\n                                <text class=\"guide-step__code-text\">{{ step.code }}</text>\n                            </view>\n                        </view>\n                    </view>\n                </view>\n            </view>\n\n            <view class=\"section-card\">\n                <view class=\"section-card__header\">\n                    <u-icon name=\"list\" size=\"40\" color=\"var(--u-type-success)\"></u-icon>\n                    <text class=\"section-card__title\">学习资源</text>\n                </view>\n                <view class=\"section-card__body\">\n                    <view\n                        class=\"resource-item\"\n                        v-for=\"(item, index) in resources\"\n                        :key=\"index\"\n                        @click=\"handleResourceClick(item)\"\n                    >\n                        <view class=\"resource-item__icon\" :style=\"{ background: item.color }\">\n                            <u-icon :name=\"item.icon\" size=\"40\" color=\"#ffffff\"></u-icon>\n                        </view>\n                        <view class=\"resource-item__content\">\n                            <view class=\"resource-item__title\">{{ item.title }}</view>\n                            <view class=\"resource-item__desc\">{{ item.desc }}</view>\n                        </view>\n                        <view class=\"resource-item__arrow\">\n                            <u-icon name=\"arrow-right\" color=\"#c0c4cc\" size=\"32\"></u-icon>\n                        </view>\n                    </view>\n                </view>\n            </view>\n\n            <view class=\"section-card\">\n                <view class=\"section-card__header\">\n                    <u-icon name=\"lightbulb\" size=\"40\" color=\"var(--u-type-warning)\"></u-icon>\n                    <text class=\"section-card__title\">最佳实践</text>\n                </view>\n                <view class=\"section-card__body\">\n                    <view class=\"practice-item\" v-for=\"(item, index) in bestPractices\" :key=\"index\">\n                        <view class=\"practice-item__icon\">\n                            <u-icon name=\"checkmark-circle\" size=\"32\" color=\"var(--u-type-success)\"></u-icon>\n                        </view>\n                        <view class=\"practice-item__text\">{{ item }}</view>\n                    </view>\n                </view>\n            </view>\n\n            <u-toast ref=\"uToastRef\" />\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\n\nconst uToastRef = ref();\n\n// 快速开始步骤\nconst quickStartSteps = ref([\n    {\n        title: '安装 uView Pro',\n        desc: '通过 pnpm、npm 或 yarn 安装',\n        code: 'pnpm add uview-pro'\n    },\n    {\n        title: '注册 uView Pro',\n        desc: '在 main.ts 中引入',\n        code: \"import uviewPro from 'uview-pro';\\napp.use(uviewPro);\"\n    },\n\n    {\n        title: '引入主题样式',\n        desc: '在 uni.scss 中引入主题样式',\n        code: \"@import 'uview-pro/theme.scss';\"\n    },\n    {\n        title: '引入基础样式',\n        desc: '在 App.vue 中引入基础样式',\n        code: \"@import 'uview-pro/index.scss';\"\n    },\n\n    {\n        title: '配置 easycom 自动引入组件',\n        desc: '在 pages.json 中配置 easycom 规则',\n        code: '{\\n  \"easycom\": {\\n  \"autoscan\": true,\\n    \"custom\": {\\n      \"^u-(.*)\": \"uview-pro/components/u-$1/u-$1.vue\"\\n    }\\n  }\\n}'\n    },\n    {\n        title: '开始使用',\n        desc: '在页面中直接使用组件',\n        code: '<u-button type=\"primary\">按钮</u-button>'\n    }\n]);\n\n// 学习资源\nconst resources = ref([\n    {\n        title: '官方文档',\n        desc: 'https://uviewpro.cn',\n        icon: 'file-text',\n        color: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\n        url: 'https://uviewpro.cn'\n    },\n    {\n        title: 'GitHub 仓库',\n        desc: '查看源代码和 Issues',\n        icon: 'github-circle-fill',\n        color: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',\n        url: 'https://github.com/anyup/uview-pro'\n    },\n    {\n        title: '组件示例',\n        desc: '查看所有组件演示',\n        icon: 'grid',\n        color: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)',\n        url: '/pages/example/components',\n        onClick: () => {\n            uni.switchTab({\n                url: '/pages/example/components'\n            });\n        }\n    }\n]);\n\n// 最佳实践\nconst bestPractices = ref([\n    '使用 TypeScript 获得更好的类型提示',\n    '合理使用主题系统，保持界面风格统一',\n    '注意组件的平台兼容性',\n    '遵循组件使用规范，避免不必要的样式覆盖',\n    '定期更新到最新版本，获得新功能和修复'\n]);\n\n// 处理资源点击\nfunction handleResourceClick(item: any) {\n    if (item.onClick) {\n        item.onClick();\n        return;\n    }\n    if (item.url) {\n        if (item.url.startsWith('http')) {\n            copyLink(item.url);\n        } else {\n            uni.navigateTo({\n                url: item.url\n            });\n        }\n    }\n}\n\n// 复制链接\nfunction copyLink(url: string) {\n    // #ifdef H5\n    window.open(url);\n    // #endif\n    // #ifndef H5\n    uni.setClipboardData({\n        data: url,\n        success: () => {\n            showToast('链接已复制，请打开浏览器粘贴访问');\n        }\n    });\n    // #endif\n}\n\n// 显示 Toast\nfunction showToast(title: string) {\n    uToastRef.value?.show({\n        title: title,\n        type: 'success'\n    });\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.guide-page {\n    padding: 24rpx;\n    background: linear-gradient(180deg, rgba(41, 121, 255, 0.03) 0%, transparent 100%);\n    min-height: 100vh;\n    display: flex;\n    flex-direction: column;\n    gap: 24rpx;\n}\n\n.section-card {\n    background: $u-bg-gray-light;\n    border-radius: 20rpx;\n    box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.06);\n    overflow: hidden;\n    transition: all 0.3s ease;\n\n    &__header {\n        padding: 28rpx 32rpx;\n        display: flex;\n        align-items: center;\n        gap: 16rpx;\n        background: linear-gradient(135deg, rgba(41, 121, 255, 0.05), rgba(25, 190, 107, 0.05));\n        border-bottom: 1rpx solid rgba(0, 0, 0, 0.04);\n    }\n\n    &__title {\n        font-size: 32rpx;\n        font-weight: 700;\n        color: $u-main-color;\n        letter-spacing: 1rpx;\n    }\n\n    &__body {\n        padding: 24rpx 32rpx 32rpx;\n    }\n}\n\n.guide-step {\n    display: flex;\n    gap: 24rpx;\n    padding: 24rpx 0;\n    border-bottom: 1rpx solid rgba(0, 0, 0, 0.04);\n\n    &:last-child {\n        border-bottom: none;\n    }\n\n    &__number {\n        flex-shrink: 0;\n        width: 64rpx;\n        height: 64rpx;\n        border-radius: 50%;\n        background: linear-gradient(135deg, var(--u-type-primary), var(--u-type-success));\n        color: #ffffff;\n        font-size: 32rpx;\n        font-weight: 700;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        box-shadow: 0 4rpx 12rpx rgba(41, 121, 255, 0.3);\n    }\n\n    &__content {\n        flex: 1;\n        display: flex;\n        flex-direction: column;\n        gap: 12rpx;\n    }\n\n    &__title {\n        font-size: 30rpx;\n        font-weight: 600;\n        color: $u-main-color;\n    }\n\n    &__desc {\n        font-size: 26rpx;\n        color: $u-content-color;\n    }\n\n    &__code {\n        background: rgba(0, 0, 0, 0.04);\n        border-radius: 8rpx;\n        padding: 16rpx;\n        margin-top: 8rpx;\n    }\n\n    &__code-text {\n        font-size: 24rpx;\n        color: $u-main-color;\n        font-family: 'Courier New', monospace;\n        white-space: pre-wrap;\n        word-break: break-all;\n    }\n}\n\n.resource-item {\n    display: flex;\n    align-items: center;\n    gap: 20rpx;\n    padding: 24rpx;\n    background: rgba(255, 255, 255, 0.6);\n    border-radius: 16rpx;\n    margin-bottom: 16rpx;\n    transition: all 0.3s ease;\n    border: 1rpx solid rgba(0, 0, 0, 0.04);\n\n    &:active {\n        transform: scale(0.98);\n        background: rgba(41, 121, 255, 0.08);\n    }\n\n    &:last-child {\n        margin-bottom: 0;\n    }\n\n    &__icon {\n        flex-shrink: 0;\n        width: 80rpx;\n        height: 80rpx;\n        border-radius: 16rpx;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15);\n    }\n\n    &__content {\n        flex: 1;\n        display: flex;\n        flex-direction: column;\n        gap: 8rpx;\n    }\n\n    &__title {\n        font-size: 28rpx;\n        font-weight: 600;\n        color: $u-main-color;\n    }\n\n    &__desc {\n        font-size: 24rpx;\n        color: $u-tips-color;\n    }\n\n    &__arrow {\n        flex-shrink: 0;\n    }\n}\n\n.practice-item {\n    display: flex;\n    align-items: flex-start;\n    gap: 16rpx;\n    padding: 20rpx 0;\n    border-bottom: 1rpx solid rgba(0, 0, 0, 0.04);\n\n    &:last-child {\n        border-bottom: none;\n    }\n\n    &__icon {\n        flex-shrink: 0;\n        margin-top: 4rpx;\n    }\n\n    &__text {\n        flex: 1;\n        font-size: 26rpx;\n        line-height: 1.8;\n        color: $u-content-color;\n    }\n}\n</style>\n"
  },
  {
    "path": "src/pages/example/about/license.vue",
    "content": "<template>\n    <demo-page nav-title=\"开源协议\" :nav-back=\"true\" hide-tabs>\n        <view class=\"license-page\">\n            <view class=\"license-header\">\n                <view class=\"license-header__title\">MIT License</view>\n                <view class=\"license-header__subtitle\">Copyright (c) 2025 uviewpro.cn</view>\n            </view>\n\n            <view class=\"section-card\">\n                <view class=\"section-card__body\">\n                    <view class=\"license-content\">\n                        <view class=\"license-section\">\n                            <view class=\"license-section__title\">Permission is hereby granted</view>\n                            <view class=\"license-section__text\">\n                                free of charge, to any person obtaining a copy of this software and associated\n                                documentation files (the \"Software\"), to deal in the Software without restriction,\n                                including without limitation the rights to use, copy, modify, merge, publish,\n                                distribute, sublicense, and/or sell copies of the Software, and to permit persons to\n                                whom the Software is furnished to do so, subject to the following conditions:\n                            </view>\n                        </view>\n\n                        <view class=\"license-section\">\n                            <view class=\"license-section__title\">The above copyright notice</view>\n                            <view class=\"license-section__text\">\n                                and this permission notice shall be included in all copies or substantial portions of\n                                the Software.\n                            </view>\n                        </view>\n\n                        <view class=\"license-section\">\n                            <view class=\"license-section__title\">THE SOFTWARE IS PROVIDED \"AS IS\"</view>\n                            <view class=\"license-section__text\">\n                                WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\n                                WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n                                NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n                                OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT\n                                OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n                            </view>\n                        </view>\n                    </view>\n                </view>\n            </view>\n\n            <view class=\"section-card\">\n                <view class=\"section-card__header\">\n                    <u-icon name=\"info-circle\" size=\"40\" color=\"var(--u-type-primary)\"></u-icon>\n                    <text class=\"section-card__title\">协议说明</text>\n                </view>\n                <view class=\"section-card__body\">\n                    <view class=\"info-text\">\n                        <text\n                            >MIT License\n                            是一个宽松的开源协议，允许您自由使用、修改、分发本软件，包括商业用途。使用本软件时，请保留版权声明和许可声明。</text\n                        >\n                    </view>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\"></script>\n\n<style lang=\"scss\" scoped>\n.license-page {\n    padding: 24rpx;\n    background: linear-gradient(180deg, rgba(41, 121, 255, 0.03) 0%, transparent 100%);\n    min-height: 100vh;\n    display: flex;\n    flex-direction: column;\n    gap: 24rpx;\n}\n\n.license-header {\n    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n    border-radius: 24rpx;\n    padding: 60rpx 40rpx;\n    text-align: center;\n    box-shadow: 0 12rpx 32rpx rgba(102, 126, 234, 0.2);\n    margin-bottom: 8rpx;\n\n    &__title {\n        font-size: 48rpx;\n        font-weight: 800;\n        color: #ffffff;\n        margin-bottom: 16rpx;\n        text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.2);\n    }\n\n    &__subtitle {\n        font-size: 28rpx;\n        color: rgba(255, 255, 255, 0.9);\n    }\n}\n\n.section-card {\n    background: $u-bg-gray-light;\n    border-radius: 20rpx;\n    box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.06);\n    overflow: hidden;\n    transition: all 0.3s ease;\n\n    &__header {\n        padding: 28rpx 32rpx;\n        display: flex;\n        align-items: center;\n        gap: 16rpx;\n        background: linear-gradient(135deg, rgba(41, 121, 255, 0.05), rgba(25, 190, 107, 0.05));\n        border-bottom: 1rpx solid rgba(0, 0, 0, 0.04);\n    }\n\n    &__title {\n        font-size: 32rpx;\n        font-weight: 700;\n        color: $u-main-color;\n        letter-spacing: 1rpx;\n    }\n\n    &__body {\n        padding: 24rpx 32rpx 32rpx;\n    }\n}\n\n.license-content {\n    display: flex;\n    flex-direction: column;\n    gap: 32rpx;\n}\n\n.license-section {\n    &__title {\n        font-size: 30rpx;\n        font-weight: 700;\n        color: var(--u-type-primary);\n        margin-bottom: 16rpx;\n        line-height: 1.6;\n    }\n\n    &__text {\n        font-size: 26rpx;\n        line-height: 1.8;\n        color: $u-content-color;\n        text-align: justify;\n    }\n}\n\n.info-text {\n    font-size: 28rpx;\n    line-height: 1.8;\n    color: $u-content-color;\n}\n</style>\n"
  },
  {
    "path": "src/pages/example/about/settings.vue",
    "content": "<template>\n    <demo-page nav-title=\"设置\" :nav-back=\"true\" hide-tabs>\n        <view class=\"settings-page\">\n            <view class=\"section-card\">\n                <view class=\"section-card__header\">\n                    <u-icon name=\"setting\" size=\"40\" color=\"var(--u-type-primary)\"></u-icon>\n                    <text class=\"section-card__title\">主题设置</text>\n                </view>\n                <view class=\"section-card__body\">\n                    <view class=\"setting-item\">\n                        <view class=\"setting-item__label\">深色模式</view>\n                        <u-switch v-model=\"darkModeEnabled\" @change=\"handleDarkModeChange\"></u-switch>\n                    </view>\n                    <view class=\"setting-item\">\n                        <view class=\"setting-item__label\">主题颜色</view>\n                        <view class=\"setting-item__value\" @click=\"showThemePicker = true\">\n                            {{ currentThemeValue.label || currentTheme }}\n                            <u-icon name=\"arrow-right\" color=\"#c0c4cc\" size=\"28\"></u-icon>\n                        </view>\n                    </view>\n                    <view class=\"setting-item\">\n                        <view class=\"setting-item__label\"> 多语言 </view>\n                        <view class=\"setting-item__value\" @click=\"showLocalePicker = true\">\n                            {{ currentLocale.label || currentLocale.name }}\n                            <u-icon name=\"arrow-right\" color=\"#c0c4cc\" size=\"28\" />\n                        </view>\n                    </view>\n                </view>\n            </view>\n\n            <view class=\"section-card\">\n                <view class=\"section-card__header\">\n                    <u-icon name=\"info-circle\" size=\"40\" color=\"var(--u-type-success)\"></u-icon>\n                    <text class=\"section-card__title\">应用设置</text>\n                </view>\n                <view class=\"section-card__body\">\n                    <view class=\"setting-item\" @click=\"handleClearCache\">\n                        <view class=\"setting-item__label\">清除缓存</view>\n                        <u-icon name=\"arrow-right\" color=\"#c0c4cc\" size=\"32\"></u-icon>\n                    </view>\n                    <view class=\"setting-item\" @click=\"handleCheckUpdate\">\n                        <view class=\"setting-item__label\">检查更新</view>\n                        <view class=\"setting-item__value\">\n                            <text class=\"setting-item__version\">当前版本: v{{ APP_INFO.version }}</text>\n                            <u-icon name=\"arrow-right\" color=\"#c0c4cc\" size=\"32\"></u-icon>\n                        </view>\n                    </view>\n                </view>\n            </view>\n\n            <view class=\"section-card\">\n                <view class=\"section-card__header\">\n                    <u-icon name=\"more-circle\" size=\"40\" color=\"var(--u-type-warning)\"></u-icon>\n                    <text class=\"section-card__title\">其他</text>\n                </view>\n                <view class=\"section-card__body\">\n                    <view class=\"setting-item\" @click=\"navigateTo('/pages/other/theme/index')\">\n                        <view class=\"setting-item__label\">主题管理</view>\n                        <u-icon name=\"arrow-right\" color=\"#c0c4cc\" size=\"32\"></u-icon>\n                    </view>\n                    <view class=\"setting-item\" @click=\"navigateTo('/pages/example/about/faq')\">\n                        <view class=\"setting-item__label\">常见问题</view>\n                        <u-icon name=\"arrow-right\" color=\"#c0c4cc\" size=\"32\"></u-icon>\n                    </view>\n                </view>\n            </view>\n\n            <!-- 主题选择器 -->\n            <u-popup v-model=\"showThemePicker\" mode=\"bottom\" border-radius=\"20\">\n                <view class=\"theme-picker\">\n                    <view class=\"theme-picker__header\">\n                        <text class=\"theme-picker__title\">选择主题</text>\n                        <u-icon name=\"close\" size=\"40\" @click=\"showThemePicker = false\"></u-icon>\n                    </view>\n                    <view class=\"theme-picker__body\">\n                        <view\n                            v-for=\"theme in themes\"\n                            :key=\"theme.name\"\n                            class=\"theme-item\"\n                            :class=\"{ 'theme-item--active': currentTheme === theme.name }\"\n                            @click=\"selectTheme(theme.name)\"\n                        >\n                            <view class=\"theme-item__color\" :style=\"{ background: theme.color }\"></view>\n                            <view class=\"theme-item__name\">{{ theme.label }}</view>\n                            <u-icon\n                                v-if=\"currentTheme === theme.name\"\n                                name=\"checkmark-circle\"\n                                size=\"32\"\n                                color=\"var(--u-type-primary)\"\n                            ></u-icon>\n                        </view>\n                    </view>\n                </view>\n            </u-popup>\n\n            <!-- 多语言选择器 -->\n            <u-popup v-model=\"showLocalePicker\" mode=\"bottom\" border-radius=\"20\">\n                <view class=\"theme-picker\">\n                    <view class=\"theme-picker__header\">\n                        <text class=\"theme-picker__title\"> 选择多语言 </text>\n                        <u-icon name=\"close\" size=\"40\" @click=\"showLocalePicker = false\" />\n                    </view>\n                    <view class=\"theme-picker__body\">\n                        <view\n                            v-for=\"locale in locales\"\n                            :key=\"locale.name\"\n                            class=\"theme-item\"\n                            :class=\"{ 'theme-item--active': currentLocale.name === locale.name }\"\n                            @click=\"selectLocale(locale)\"\n                        >\n                            <view class=\"theme-item__name\">\n                                {{ locale.label }}\n                            </view>\n                            <u-icon\n                                v-if=\"currentLocale.name === locale.name\"\n                                name=\"checkmark-circle\"\n                                size=\"32\"\n                                color=\"var(--u-type-primary)\"\n                            />\n                        </view>\n                    </view>\n                </view>\n            </u-popup>\n\n            <u-toast ref=\"uToastRef\" />\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed } from 'vue';\nimport { useLocale, useTheme } from 'uview-pro';\nimport { APP_INFO } from '@/common/constant';\nimport { useLang } from '@/common/useHooks';\nconst { getDarkMode, setDarkMode, currentTheme: currentThemeValue, setTheme, getAvailableThemes } = useTheme();\nconst uToastRef = ref();\nconst { currentLocale, locales: availableLocales } = useLocale();\nconst { switchLang } = useLang();\n\nconst showThemePicker = ref(false);\nconst showLocalePicker = ref(false);\n\n// 深色模式状态\nconst darkModeEnabled = computed({\n    get: () => getDarkMode() === 'dark',\n    set: (value: boolean) => {\n        setDarkMode(value ? 'dark' : 'light');\n    }\n});\n\n// 主题列表\nconst themes = computed(() => {\n    return getAvailableThemes().map(theme => ({\n        name: theme.name,\n        label: theme.label || theme.name,\n        color: theme?.color?.primary || '#2979ff'\n    }));\n});\n\nconst locales = computed(() => {\n    return availableLocales.value.map((locale: any) => ({\n        name: locale.name,\n        label: locale.label || locale.name,\n        locale: locale.locale\n    }));\n});\n\nfunction getLocaleLabel(localeName: string) {\n    if (localeName === 'zh-CN') return '简体中文';\n    if (localeName === 'en-US') return 'English';\n    return localeName;\n}\n\n// 当前主题名称\nconst currentTheme = computed(() => {\n    return currentThemeValue.value?.name || 'uviewpro';\n});\n\n// 处理深色模式切换\nfunction handleDarkModeChange(value: boolean) {\n    setDarkMode(value ? 'dark' : 'light');\n    showToast(value ? '已开启深色模式' : '已关闭深色模式');\n}\n\n// 选择主题\nfunction selectTheme(themeName: string) {\n    setTheme(themeName);\n    showThemePicker.value = false;\n    showToast(`已切换到「${themes.value.find(t => t.name === themeName)?.label}」主题`);\n}\n\nfunction selectLocale(locale: any) {\n    switchLang(locale);\n    showLocalePicker.value = false;\n    showToast(`已切换到语言「${locale.label}」`);\n}\n\n// 清除缓存\nfunction handleClearCache() {\n    uni.showModal({\n        title: '提示',\n        content: '确定要清除所有缓存数据吗？',\n        success: res => {\n            if (res.confirm) {\n                try {\n                    uni.clearStorageSync();\n                    showToast('缓存已清除');\n                } catch (e) {\n                    showToast('清除缓存失败', 'error');\n                }\n            }\n        }\n    });\n}\n\n// 检查更新\nfunction handleCheckUpdate() {\n    showToast('当前已是最新版本');\n}\n\n// 导航\nfunction navigateTo(path: string) {\n    uni.navigateTo({\n        url: path\n    });\n}\n\n// 显示 Toast\nfunction showToast(title: string, type: 'success' | 'error' = 'success') {\n    uToastRef.value?.show({\n        title: title,\n        type: type\n    });\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.settings-page {\n    padding: 24rpx;\n    background: linear-gradient(180deg, rgba(41, 121, 255, 0.03) 0%, transparent 100%);\n    min-height: 100vh;\n    display: flex;\n    flex-direction: column;\n    gap: 24rpx;\n}\n\n.section-card {\n    background: $u-bg-gray-light;\n    border-radius: 20rpx;\n    box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.06);\n    overflow: hidden;\n    transition: all 0.3s ease;\n\n    &__header {\n        padding: 28rpx 32rpx;\n        display: flex;\n        align-items: center;\n        gap: 16rpx;\n        background: linear-gradient(135deg, rgba(41, 121, 255, 0.05), rgba(25, 190, 107, 0.05));\n        border-bottom: 1rpx solid rgba(0, 0, 0, 0.04);\n    }\n\n    &__title {\n        font-size: 32rpx;\n        font-weight: 700;\n        color: $u-main-color;\n        letter-spacing: 1rpx;\n    }\n\n    &__body {\n        padding: 24rpx 32rpx 32rpx;\n    }\n}\n\n.setting-item {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    padding: 24rpx 0;\n    border-bottom: 1rpx solid rgba(0, 0, 0, 0.04);\n    transition: all 0.2s ease;\n\n    &:last-child {\n        border-bottom: none;\n    }\n\n    &:active {\n        opacity: 0.7;\n    }\n\n    &__label {\n        font-size: 28rpx;\n        color: $u-main-color;\n    }\n\n    &__value {\n        display: flex;\n        align-items: center;\n        gap: 12rpx;\n        font-size: 26rpx;\n        color: $u-content-color;\n    }\n\n    &__version {\n        font-size: 24rpx;\n        color: $u-tips-color;\n    }\n}\n\n.theme-picker {\n    padding: 40rpx 32rpx;\n    background: $u-bg-gray-light;\n    border-radius: 20rpx 20rpx 0 0;\n\n    &__header {\n        display: flex;\n        justify-content: space-between;\n        align-items: center;\n        margin-bottom: 32rpx;\n    }\n\n    &__title {\n        font-size: 36rpx;\n        font-weight: 700;\n        color: $u-main-color;\n    }\n\n    &__body {\n        display: flex;\n        flex-direction: column;\n        gap: 16rpx;\n    }\n}\n\n.theme-item {\n    display: flex;\n    align-items: center;\n    gap: 20rpx;\n    padding: 24rpx;\n    background: rgba(255, 255, 255, 0.6);\n    border-radius: 16rpx;\n    border: 2rpx solid transparent;\n    transition: all 0.3s ease;\n\n    &:active {\n        transform: scale(0.98);\n    }\n\n    &--active {\n        border-color: var(--u-type-primary);\n        background: rgba(41, 121, 255, 0.08);\n    }\n\n    &__color {\n        width: 48rpx;\n        height: 48rpx;\n        border-radius: 12rpx;\n        box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15);\n    }\n\n    &__name {\n        flex: 1;\n        font-size: 28rpx;\n        color: $u-main-color;\n        font-weight: 500;\n    }\n}\n</style>\n"
  },
  {
    "path": "src/pages/example/about/version.vue",
    "content": "<template>\n    <demo-page nav-title=\"版本信息\" :nav-back=\"true\" hide-tabs>\n        <view class=\"version-page\">\n            <view class=\"version-card\">\n                <view class=\"version-card__logo\">\n                    <u-avatar src=\"/static/logo.png\" size=\"120\"></u-avatar>\n                </view>\n                <view class=\"version-card__name\">uView Pro</view>\n                <view class=\"version-card__version\">v{{ APP_INFO.version }}</view>\n            </view>\n\n            <view class=\"section-card\">\n                <view class=\"section-card__header\">\n                    <u-icon name=\"info-circle\" size=\"40\" color=\"var(--u-type-primary)\"></u-icon>\n                    <text class=\"section-card__title\">应用信息</text>\n                </view>\n                <view class=\"section-card__body\">\n                    <view class=\"info-item\">\n                        <view class=\"info-item__label\">应用名称</view>\n                        <view class=\"info-item__value\">{{ APP_INFO.name }}</view>\n                    </view>\n                    <view class=\"info-item\">\n                        <view class=\"info-item__label\">版本号</view>\n                        <view class=\"info-item__value\">{{ APP_INFO.version }}</view>\n                    </view>\n                    <view class=\"info-item\">\n                        <view class=\"info-item__label\">构建时间</view>\n                        <view class=\"info-item__value\">{{ APP_INFO.buildTime }}</view>\n                    </view>\n                    <view class=\"info-item\">\n                        <view class=\"info-item__label\">平台</view>\n                        <view class=\"info-item__value\">{{ APP_INFO.platform }}</view>\n                    </view>\n                </view>\n            </view>\n            <view class=\"section-card\">\n                <view class=\"section-card__header\">\n                    <u-icon name=\"tags\" size=\"40\" color=\"var(--u-type-primary)\"></u-icon>\n                    <text class=\"section-card__title\">uView Pro 组件库</text>\n                </view>\n                <view class=\"section-card__body\">\n                    <view class=\"info-item\">\n                        <view class=\"info-item__label\">组件库名称</view>\n                        <view class=\"info-item__value\">{{ UVIEW_PRO_INFO.name }}</view>\n                    </view>\n                    <view class=\"info-item\">\n                        <view class=\"info-item__label\">版本号</view>\n                        <view class=\"info-item__value\">{{ UVIEW_PRO_INFO.version }}</view>\n                    </view>\n                    <view class=\"info-item\">\n                        <view class=\"info-item__label\">发布时间</view>\n                        <view class=\"info-item__value\">{{ UVIEW_PRO_INFO.buildTime }}</view>\n                    </view>\n                </view>\n            </view>\n\n            <view class=\"section-card\" v-if=\"false\">\n                <view class=\"section-card__header\">\n                    <u-icon name=\"list\" size=\"40\" color=\"var(--u-type-success)\"></u-icon>\n                    <text class=\"section-card__title\">更新日志</text>\n                </view>\n                <view class=\"section-card__body\">\n                    <view class=\"changelog-item\" v-for=\"(item, index) in changelog\" :key=\"index\">\n                        <view class=\"changelog-item__version\">{{ item.version }}</view>\n                        <view class=\"changelog-item__date\">{{ item.date }}</view>\n                        <view class=\"changelog-item__content\">\n                            <view v-for=\"(change, idx) in item.changes\" :key=\"idx\" class=\"changelog-item__change\">\n                                • {{ change }}\n                            </view>\n                        </view>\n                    </view>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { APP_INFO, UVIEW_PRO_INFO } from '@/common/constant';\n\n// 更新日志\nconst changelog = ref([\n    {\n        version: 'v0.4.7',\n        date: '2025-12-19',\n        changes: ['优化组件性能', '修复已知问题', '新增多个组件']\n    }\n]);\n</script>\n\n<style lang=\"scss\" scoped>\n.version-page {\n    padding: 24rpx;\n    background: linear-gradient(180deg, rgba(41, 121, 255, 0.03) 0%, transparent 100%);\n    min-height: 100vh;\n    display: flex;\n    flex-direction: column;\n    gap: 24rpx;\n}\n\n.version-card {\n    background: linear-gradient(135deg, #2979ff 0%, #19be6b 50%, #ff9900 100%);\n    border-radius: 24rpx;\n    padding: 60rpx 40rpx;\n    text-align: center;\n    box-shadow: 0 12rpx 32rpx rgba(41, 121, 255, 0.2);\n    margin-bottom: 8rpx;\n\n    &__logo {\n        margin-bottom: 24rpx;\n    }\n\n    &__name {\n        font-size: 48rpx;\n        font-weight: 800;\n        color: #ffffff;\n        margin-bottom: 12rpx;\n        text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.2);\n    }\n\n    &__version {\n        font-size: 32rpx;\n        color: rgba(255, 255, 255, 0.9);\n        font-weight: 600;\n    }\n}\n\n.section-card {\n    background: $u-bg-gray-light;\n    border-radius: 20rpx;\n    box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.06);\n    overflow: hidden;\n    transition: all 0.3s ease;\n\n    &__header {\n        padding: 28rpx 32rpx;\n        display: flex;\n        align-items: center;\n        gap: 16rpx;\n        background: linear-gradient(135deg, rgba(41, 121, 255, 0.05), rgba(25, 190, 107, 0.05));\n        border-bottom: 1rpx solid rgba(0, 0, 0, 0.04);\n    }\n\n    &__title {\n        font-size: 32rpx;\n        font-weight: 700;\n        color: $u-main-color;\n        letter-spacing: 1rpx;\n    }\n\n    &__body {\n        padding: 24rpx 32rpx 32rpx;\n    }\n}\n\n.info-item {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    padding: 20rpx 0;\n    border-bottom: 1rpx solid rgba(0, 0, 0, 0.04);\n\n    &:last-child {\n        border-bottom: none;\n    }\n\n    &__label {\n        font-size: 28rpx;\n        color: $u-content-color;\n    }\n\n    &__value {\n        font-size: 28rpx;\n        font-weight: 600;\n        color: $u-main-color;\n    }\n}\n\n.changelog-item {\n    padding: 24rpx 0;\n    border-bottom: 1rpx solid rgba(0, 0, 0, 0.04);\n\n    &:last-child {\n        border-bottom: none;\n    }\n\n    &__version {\n        font-size: 32rpx;\n        font-weight: 700;\n        color: var(--u-type-primary);\n        margin-bottom: 8rpx;\n    }\n\n    &__date {\n        font-size: 24rpx;\n        color: $u-tips-color;\n        margin-bottom: 16rpx;\n    }\n\n    &__content {\n        padding-left: 16rpx;\n    }\n\n    &__change {\n        font-size: 26rpx;\n        color: $u-content-color;\n        line-height: 1.8;\n        margin-bottom: 8rpx;\n    }\n}\n</style>\n"
  },
  {
    "path": "src/pages/example/about.vue",
    "content": "<template>\n    <demo-page :nav-title=\"t('nav.about')\" :nav-back=\"false\" :tabbar=\"true\">\n        <view class=\"about-page\">\n            <!-- 用户信息卡片 -->\n            <view class=\"hero-card\" @click=\"navigateTo('/pages/example/about/about-me')\">\n                <view class=\"hero-card__bg\"></view>\n                <view class=\"hero-card__content\">\n                    <view class=\"hero-avatar\">\n                        <view class=\"hero-avatar__wrapper\">\n                            <u-avatar src=\"/static/logo.png\" size=\"160\"></u-avatar>\n                            <view class=\"hero-avatar__ring\"></view>\n                        </view>\n                    </view>\n                    <view class=\"hero-info\">\n                        <view class=\"hero-info__name\">\n                            <text class=\"hero-info__name-text\">uView Pro</text>\n                            <view class=\"hero-info__badge\">Pro</view>\n                        </view>\n                        <view class=\"hero-info__desc\">\n                            <text class=\"hero-info__desc-icon\">💬</text>\n                            <text>微信号：anyupxing</text>\n                        </view>\n                        <view class=\"hero-info__tagline\">高质量跨平台 UI 组件库</view>\n                    </view>\n                    <view class=\"hero-arrow\">\n                        <u-icon name=\"arrow-right\" color=\"rgba(255,255,255,0.8)\" size=\"36\"></u-icon>\n                    </view>\n                </view>\n            </view>\n\n            <!-- 功能入口 -->\n            <view class=\"section-card\">\n                <view class=\"section-card__header\">\n                    <u-icon custom-prefix=\"custom-icon\" name=\"grid\" size=\"40\" color=\"var(--u-type-primary)\"></u-icon>\n                    <text class=\"section-card__title\">功能入口</text>\n                </view>\n                <view class=\"section-card__body\">\n                    <view class=\"menu-grid\">\n                        <view\n                            v-for=\"(item, index) in menuList\"\n                            :key=\"index\"\n                            class=\"menu-item\"\n                            @click=\"navigateTo(item.path)\"\n                        >\n                            <view class=\"menu-item__icon\" :style=\"{ background: item.color }\">\n                                <u-icon\n                                    :custom-prefix=\"item.customIcon ? 'custom-icon' : 'uicon'\"\n                                    :name=\"item.icon\"\n                                    size=\"48\"\n                                    color=\"#ffffff\"\n                                ></u-icon>\n                            </view>\n                            <view class=\"menu-item__title\">{{ item.title }}</view>\n                            <view class=\"menu-item__desc\">{{ item.desc }}</view>\n                        </view>\n                    </view>\n                </view>\n            </view>\n\n            <!-- 交流群 -->\n            <view class=\"section-card\">\n                <view class=\"section-card__header\">\n                    <u-icon name=\"chat\" size=\"40\" color=\"var(--u-type-success)\"></u-icon>\n                    <text class=\"section-card__title\">交流反馈</text>\n                </view>\n                <view class=\"section-card__body\">\n                    <view v-for=\"(item, index) in chatList\" :key=\"index\" class=\"info-item\" @click=\"itemClick(item)\">\n                        <view class=\"info-item__icon\">\n                            <u-image\n                                :src=\"getImageUrl(item.icon)\"\n                                :width=\"64\"\n                                :height=\"64\"\n                                mode=\"aspectFill\"\n                                :fade=\"true\"\n                                radius=\"12\"\n                            ></u-image>\n                        </view>\n                        <view class=\"info-item__content\">\n                            <view class=\"info-item__title\">{{ item.title }}</view>\n                            <view class=\"info-item__label\">{{ item.label }}</view>\n                        </view>\n                        <view class=\"info-item__arrow\">\n                            <u-icon name=\"arrow-right\" color=\"#c0c4cc\" size=\"32\"></u-icon>\n                        </view>\n                    </view>\n                </view>\n            </view>\n\n            <!-- 其他信息 -->\n            <view class=\"section-card\">\n                <view class=\"section-card__header\">\n                    <u-icon name=\"moments\" size=\"40\" color=\"var(--u-type-warning)\"></u-icon>\n                    <text class=\"section-card__title\">其他信息</text>\n                </view>\n                <view class=\"section-card__body\">\n                    <view v-for=\"(item, index) in infoList\" :key=\"index\" class=\"info-item\" @click=\"itemClick(item)\">\n                        <view class=\"info-item__icon\">\n                            <u-image\n                                :src=\"getImageUrl(item.icon, true)\"\n                                :width=\"64\"\n                                :height=\"64\"\n                                mode=\"aspectFill\"\n                                :fade=\"true\"\n                                radius=\"12\"\n                            ></u-image>\n                        </view>\n                        <view class=\"info-item__content\">\n                            <view class=\"info-item__title\">{{ item.title }}</view>\n                            <view class=\"info-item__label\">{{ item.label }}</view>\n                        </view>\n                        <view class=\"info-item__arrow\">\n                            <u-icon name=\"arrow-right\" color=\"#c0c4cc\" size=\"32\"></u-icon>\n                        </view>\n                    </view>\n                </view>\n            </view>\n\n            <u-toast ref=\"uToastRef\" position=\"bottom\" />\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { useTitle } from '@/common/useHooks';\nimport { onShow } from '@dcloudio/uni-app';\nimport { ref } from 'vue';\nimport { useI18n } from 'vue-i18n';\n\nconst uToastRef = ref();\n// 国际化\nconst { t, locale } = useI18n();\nconst { setTitle } = useTitle(3);\n\n// 功能菜单列表\nconst menuList = ref([\n    {\n        title: '关于我',\n        desc: '了解开发者',\n        icon: 'account',\n        path: '/pages/example/about/about-me',\n        color: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)'\n    },\n    {\n        title: '版本信息',\n        desc: '查看应用版本',\n        icon: 'info-circle',\n        path: '/pages/example/about/version',\n        color: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)'\n    },\n    {\n        title: '开源协议',\n        desc: 'MIT License',\n        icon: 'file-text',\n        path: '/pages/example/about/license',\n        color: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)'\n    },\n    {\n        title: '贡献者',\n        desc: '感谢所有贡献者',\n        icon: 'man-add',\n        path: '/pages/example/about/contributors',\n        color: 'linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)'\n    },\n    {\n        title: '常见问题',\n        desc: 'FAQ',\n        icon: 'warning',\n        path: '/pages/example/about/faq',\n        color: 'linear-gradient(135deg, #fa709a 0%, #fee140 100%)'\n    },\n    {\n        title: '使用指南',\n        desc: '快速上手',\n        icon: 'bookmark',\n        path: '/pages/example/about/guide',\n        color: 'linear-gradient(135deg, #30cfd0 0%, #330867 100%)'\n    },\n    {\n        title: '主题',\n        desc: '多主题管理',\n        icon: 'theme-fill',\n        path: '/pages/other/theme/index',\n        color: 'linear-gradient(135deg, #ff6b6b 0%, #ff8e72 100%)',\n        customIcon: true\n    },\n    {\n        title: '国际化',\n        desc: '多语言管理',\n        icon: 'guide',\n        path: '/pages/other/locale/index',\n        color: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)',\n        customIcon: true\n    },\n    {\n        title: '设置',\n        desc: '应用设置',\n        icon: 'setting',\n        path: '/pages/example/about/settings',\n        color: 'linear-gradient(135deg, #a8edea 0%, #fed6e3 100%)'\n    }\n]);\n\n// 其他信息列表\nconst infoList = ref([\n    {\n        icon: 'uview-pro',\n        title: '官网文档',\n        label: 'https://uviewpro.cn',\n        click: () => {\n            copyLink('https://uviewpro.cn');\n        }\n    },\n    {\n        icon: 'weixin_public',\n        title: '微信公众号',\n        label: '致力于分享各种前端技术最佳解决方案',\n        click: () => {\n            preview('qr_weixin_public2');\n        }\n    },\n    {\n        icon: 'juejin',\n        title: '掘金社区',\n        label: '掘金优秀创作者',\n        click: () => {\n            copyLink('https://juejin.cn/user/4230576472589976/posts');\n        }\n    },\n    {\n        icon: 'csdn',\n        title: 'CSDN 博客',\n        label: 'CSDN博客专家',\n        click: () => {\n            copyLink('https://blog.csdn.net/qq_24956515?type=blog');\n        }\n    },\n    {\n        icon: 'donate',\n        title: '榜上有名',\n        label: '参与捐赠，即刻上榜',\n        click: () => {\n            // #ifdef MP-WEIXIN\n            copyLink('https://uviewpro.cn/zh/reward/donation.html');\n            // #endif\n            // #ifndef MP-WEIXIN\n            preview('wechat-pay');\n            // #endif\n        }\n    }\n]);\n\n// 交流群列表\nconst chatList = ref([\n    {\n        icon: 'wxpublic',\n        title: '微信交流',\n        label: '点击后长按或扫描二维码图片加入群聊，共同交流 uView Pro 相关问题',\n        click: () => {\n            // #ifdef APP-HARMONY\n            preview('weixin-chat-cl');\n            // #endif\n            // #ifndef APP-HARMONY\n            preview(`https://ik.imagekit.io/anyup/images/social/weixin-chat.png?updatedAt=${new Date().getTime()}`);\n            // #endif\n        }\n    }\n]);\n\n// 获取图片地址\nfunction getImageUrl(name: string, force: boolean = false) {\n    let url = `https://ik.imagekit.io/anyup/images/social/${name}.png`;\n    // #ifdef APP-HARMONY\n    url = `/static/app/${name}.png`;\n    // #endif\n    // #ifndef APP-HARMONY\n    if (force) {\n        url = `${url}?updatedAt=${new Date().getTime()}`;\n    }\n    // #endif\n    return url;\n}\n\n/**\n * 导航到指定页面\n */\nfunction navigateTo(path: string) {\n    uni.navigateTo({\n        url: path\n    });\n}\n\n/**\n * 列表项点击事件\n */\nfunction itemClick(item: any) {\n    item.click && item.click();\n}\n\n/**\n * 图片预览\n */\nfunction preview(url: string) {\n    if (!url) return;\n    if (!url.includes('http')) {\n        url = getImageUrl(url, true);\n    }\n    uni.previewImage({\n        urls: [url],\n        current: url\n    });\n}\n\n/**\n * 复制链接，兼容H5和小程序\n */\nfunction copyLink(url: string) {\n    // #ifdef H5\n    window.open(url);\n    // #endif\n    // #ifndef H5\n    uni.setClipboardData({\n        data: url,\n        success: () => {\n            showToast('链接已复制，请打开浏览器粘贴访问');\n        }\n    });\n    // #endif\n}\n\n// 显示Toast\nfunction showToast(title: string) {\n    // 通过ref调用uToast组件的show方法\n    uToastRef.value?.show({\n        title: title,\n        type: 'success'\n    });\n}\n\n// 设置标题\nonShow(() => {\n    setTitle();\n});\n</script>\n\n<style lang=\"scss\" scoped>\n.about-page {\n    padding: 24rpx;\n    background: linear-gradient(180deg, rgba(41, 121, 255, 0.03) 0%, transparent 100%);\n    min-height: 100vh;\n    display: flex;\n    flex-direction: column;\n    gap: 24rpx;\n}\n\n// Hero 卡片\n.hero-card {\n    position: relative;\n    margin: 0 0 8rpx;\n    border-radius: 24rpx;\n    overflow: hidden;\n    box-shadow: 0 12rpx 32rpx rgba(41, 121, 255, 0.2);\n    transition: all 0.3s ease;\n\n    &:active {\n        transform: scale(0.98);\n    }\n\n    &__bg {\n        position: absolute;\n        top: 0;\n        left: 0;\n        right: 0;\n        bottom: 0;\n        background: linear-gradient(135deg, #2979ff 0%, #19be6b 50%, #ff9900 100%);\n        opacity: 0.95;\n\n        &::before {\n            content: '';\n            position: absolute;\n            top: -50%;\n            right: -20%;\n            width: 200%;\n            height: 200%;\n            background: radial-gradient(circle, rgba(255, 255, 255, 0.2) 0%, transparent 70%);\n            animation: heroGlow 8s ease-in-out infinite;\n        }\n    }\n\n    &__content {\n        position: relative;\n        z-index: 2;\n        padding: 40rpx 32rpx;\n        display: flex;\n        align-items: center;\n        gap: 24rpx;\n    }\n}\n\n@keyframes heroGlow {\n    0%,\n    100% {\n        transform: rotate(0deg);\n        opacity: 0.3;\n    }\n    50% {\n        transform: rotate(180deg);\n        opacity: 0.6;\n    }\n}\n\n.hero-avatar {\n    flex-shrink: 0;\n\n    &__wrapper {\n        position: relative;\n        width: 160rpx;\n        height: 160rpx;\n        filter: drop-shadow(0 8rpx 16rpx rgba(0, 0, 0, 0.2));\n    }\n\n    &__ring {\n        position: absolute;\n        top: -8rpx;\n        left: -8rpx;\n        right: -8rpx;\n        bottom: -8rpx;\n        border: 4rpx solid rgba(255, 255, 255, 0.6);\n        border-radius: 50%;\n        animation: ringRotate 3s linear infinite;\n        box-shadow: 0 0 20rpx rgba(255, 255, 255, 0.3);\n    }\n}\n\n@keyframes ringRotate {\n    0% {\n        transform: rotate(0deg);\n    }\n    100% {\n        transform: rotate(360deg);\n    }\n}\n\n.hero-info {\n    flex: 1;\n    display: flex;\n    flex-direction: column;\n    gap: 12rpx;\n\n    &__name {\n        display: flex;\n        align-items: center;\n        gap: 12rpx;\n    }\n\n    &__name-text {\n        font-size: 44rpx;\n        font-weight: 800;\n        color: #ffffff;\n        letter-spacing: 2rpx;\n        text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.2);\n    }\n\n    &__badge {\n        padding: 4rpx 12rpx;\n        background: rgba(255, 255, 255, 0.3);\n        border-radius: 8rpx;\n        font-size: 20rpx;\n        font-weight: 700;\n        color: #ffffff;\n        letter-spacing: 1rpx;\n        backdrop-filter: blur(10rpx);\n    }\n\n    &__desc {\n        display: flex;\n        align-items: center;\n        gap: 8rpx;\n        font-size: 26rpx;\n        color: rgba(255, 255, 255, 0.9);\n    }\n\n    &__desc-icon {\n        font-size: 28rpx;\n    }\n\n    &__tagline {\n        font-size: 24rpx;\n        color: rgba(255, 255, 255, 0.8);\n        margin-top: 4rpx;\n    }\n}\n\n.hero-arrow {\n    flex-shrink: 0;\n    opacity: 0.8;\n    transition: all 0.3s ease;\n}\n\n.hero-card:active .hero-arrow {\n    transform: translateX(4rpx);\n}\n\n// 区块卡片\n.section-card {\n    background: $u-bg-gray-light;\n    border-radius: 20rpx;\n    box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.06);\n    overflow: hidden;\n    transition: all 0.3s ease;\n\n    &:hover {\n        box-shadow: 0 12rpx 32rpx rgba(41, 121, 255, 0.12);\n    }\n\n    &__header {\n        padding: 28rpx 32rpx;\n        display: flex;\n        align-items: center;\n        gap: 16rpx;\n        background: linear-gradient(135deg, rgba(41, 121, 255, 0.05), rgba(25, 190, 107, 0.05));\n        border-bottom: 1rpx solid rgba(0, 0, 0, 0.04);\n    }\n\n    &__title {\n        font-size: 32rpx;\n        font-weight: 700;\n        color: $u-main-color;\n        letter-spacing: 1rpx;\n    }\n\n    &__body {\n        padding: 8rpx 0;\n    }\n}\n\n// 关于文本\n.about-text {\n    padding: 24rpx 32rpx 32rpx;\n    font-size: 28rpx;\n    line-height: 1.8;\n    color: $u-content-color;\n\n    &__highlight {\n        font-weight: 700;\n        background: linear-gradient(135deg, #2979ff, #19be6b);\n        -webkit-background-clip: text;\n        -webkit-text-fill-color: transparent;\n        background-clip: text;\n    }\n}\n\n// 信息项\n.info-item {\n    display: flex;\n    align-items: center;\n    gap: 20rpx;\n    padding: 24rpx 32rpx;\n    transition: all 0.2s ease;\n    border-bottom: 1rpx solid rgba(0, 0, 0, 0.04);\n    position: relative;\n\n    &::before {\n        content: '';\n        position: absolute;\n        left: 0;\n        top: 0;\n        bottom: 0;\n        width: 0;\n        background: linear-gradient(135deg, rgba(41, 121, 255, 0.1), rgba(25, 190, 107, 0.1));\n        transition: width 0.3s ease;\n    }\n\n    &:last-child {\n        border-bottom: none;\n    }\n\n    &:active {\n        background: rgba(41, 121, 255, 0.04);\n        transform: translateX(4rpx);\n\n        &::before {\n            width: 6rpx;\n        }\n    }\n\n    &__icon {\n        flex-shrink: 0;\n        width: 64rpx;\n        height: 64rpx;\n        border-radius: 12rpx;\n        overflow: hidden;\n        box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);\n        transition: all 0.3s ease;\n    }\n\n    &:active &__icon {\n        transform: scale(1.05);\n        box-shadow: 0 6rpx 16rpx rgba(41, 121, 255, 0.2);\n    }\n\n    &__content {\n        flex: 1;\n        display: flex;\n        flex-direction: column;\n        gap: 8rpx;\n    }\n\n    &__title {\n        font-size: 30rpx;\n        font-weight: 600;\n        color: $u-main-color;\n        transition: color 0.2s ease;\n    }\n\n    &:active &__title {\n        color: var(--u-type-primary);\n    }\n\n    &__label {\n        font-size: 24rpx;\n        color: $u-tips-color;\n        line-height: 1.5;\n    }\n\n    &__arrow {\n        flex-shrink: 0;\n        opacity: 0.6;\n        transition: all 0.2s ease;\n    }\n}\n\n.info-item:active .info-item__arrow {\n    transform: translateX(4rpx);\n    opacity: 1;\n    color: var(--u-type-primary);\n}\n\n// 菜单网格\n.menu-grid {\n    display: grid;\n    grid-template-columns: repeat(3, 1fr);\n    gap: 24rpx;\n    padding: 24rpx 32rpx 32rpx;\n}\n\n.menu-item {\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    gap: 12rpx;\n    padding: 24rpx 16rpx;\n    border-radius: 16rpx;\n    background: rgba(255, 255, 255, 0.6);\n    transition: all 0.3s ease;\n    border: 1rpx solid rgba(0, 0, 0, 0.04);\n\n    &:active {\n        transform: scale(0.95);\n        background: rgba(41, 121, 255, 0.08);\n    }\n\n    &__icon {\n        width: 96rpx;\n        height: 96rpx;\n        border-radius: 20rpx;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        box-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.15);\n        transition: all 0.3s ease;\n    }\n\n    &:active &__icon {\n        transform: scale(1.1);\n        box-shadow: 0 12rpx 28rpx rgba(0, 0, 0, 0.25);\n    }\n\n    &__title {\n        font-size: 28rpx;\n        font-weight: 600;\n        color: $u-main-color;\n        text-align: center;\n    }\n\n    &__desc {\n        font-size: 22rpx;\n        color: $u-tips-color;\n        text-align: center;\n    }\n}\n</style>\n"
  },
  {
    "path": "src/pages/example/components.config.ts",
    "content": "export default [\n    {\n        groupName: '基础组件',\n        groupName_en: 'Basic components',\n        icon: 'basics',\n        list: [\n            {\n                path: '/pages/componentsC/color/index',\n                icon: 'color',\n                title: 'Color 色彩',\n                title_en: 'Color',\n                desc: '提供主题与配色示例，便于统一项目色彩方案。',\n                desc_en: 'Provides theme and color examples to help unify project colors.'\n            },\n            {\n                path: '/pages/componentsA/icon/index',\n                icon: 'icon',\n                title: 'Icon 图标',\n                title_en: 'Icon',\n                desc: '常用图标集合，支持自定义尺寸与颜色，便于界面装饰与操作提示。',\n                desc_en: 'Common icon set supporting custom size and color for UI decoration and cues.'\n            },\n            {\n                path: '/pages/componentsB/image/index',\n                icon: 'image',\n                title: 'Image 图片',\n                title_en: 'Image',\n                desc: '图片展示组件，支持懒加载、占位图与自适应显示。',\n                desc_en: 'Image display with lazy-load, placeholders and responsive modes.'\n            },\n            {\n                path: '/pages/componentsC/button/index',\n                icon: 'button',\n                title: 'Button 按钮',\n                title_en: 'Button',\n                desc: '基础按钮，支持多种样式、尺寸、禁用与加载态。',\n                desc_en: 'Basic button supporting multiple styles, sizes, disabled and loading states.'\n            },\n            {\n                path: '/pages/componentsC/layout/index',\n                icon: 'layout',\n                title: 'Layout 布局',\n                title_en: 'Layout',\n                desc: '布局容器与工具类，帮助快速搭建响应式栅格与间距。',\n                desc_en: 'Layout containers and utilities to build responsive grids and spacing.'\n            },\n            {\n                path: '/pages/componentsC/cell/index',\n                icon: 'cell',\n                title: 'Cell 单元格',\n                title_en: 'Cell',\n                desc: '列表与表单中的单元格项，常用于信息展示与跳转入口。',\n                desc_en: 'Cell items for lists and forms, commonly used for info display and navigation.'\n            },\n            {\n                path: '/pages/componentsC/badge/index',\n                icon: 'badge',\n                title: 'Badge 徽标数',\n                title_en: 'Badge',\n                desc: '徽标与角标显示，用于提示数量或状态标识。',\n                desc_en: 'Badge and corner mark display used to indicate counts or statuses.'\n            },\n            {\n                path: '/pages/componentsA/tag/index',\n                icon: 'tag',\n                title: 'Tag 标签',\n                title_en: 'Tag',\n                desc: '标签组件，用于表示分类、状态或筛选条件。',\n                desc_en: 'Tag component for categories, statuses or filter labels.'\n            },\n            {\n                path: '/pages/componentsC/text/index',\n                icon: 'text',\n                title: 'Text 文本',\n                title_en: 'Text',\n                desc: '文本展示与格式化组件，支持省略、换行与样式控制。',\n                desc_en: 'Text display and formatting with ellipsis, wrapping and style controls.'\n            },\n            {\n                path: '/pages/componentsC/fab/index',\n                icon: 'fab',\n                title: 'Fab 悬浮按钮',\n                title_en: 'Fab',\n                desc: '悬浮操作按钮，便于快速触发主要操作或快捷入口。',\n                desc_en: 'Floating action button for quick access to primary operations.'\n            }\n        ]\n    },\n    {\n        groupName: '表单组件',\n        groupName_en: 'Form components',\n        icon: 'forms',\n        list: [\n            {\n                path: '/pages/componentsA/form/index',\n                icon: 'form',\n                title: 'Form 表单',\n                title_en: 'Form',\n                desc: '表单容器，支持字段校验、布局与统一提交处理。',\n                desc_en: 'Form container supporting validation, layout and unified submit handling.'\n            },\n            {\n                path: '/pages/componentsA/input/index',\n                icon: 'input',\n                title: 'Input 输入框',\n                title_en: 'Input',\n                desc: '单行输入框，支持类型、限制与常用交互事件。',\n                desc_en: 'Single-line input with type, constraints and common interaction events.'\n            },\n            {\n                path: '/pages/componentsA/textarea/index',\n                icon: 'textarea',\n                title: 'Textarea 输入框',\n                title_en: 'Textarea',\n                desc: '多行文本输入，支持自适应高度与字数统计限制。',\n                desc_en: 'Multi-line textarea supporting auto-height and character count limits.'\n            },\n            {\n                path: '/pages/componentsA/calendar/index',\n                icon: 'calendar',\n                title: 'Calendar 日历',\n                title_en: 'Calendar',\n                desc: '日历选择器，支持单选、范围选择与多种显示模式。',\n                desc_en: 'Calendar picker supporting single, range selection and multiple display modes.'\n            },\n            {\n                path: '/pages/componentsA/select/index',\n                icon: 'select',\n                title: 'Select 列选择器',\n                title_en: 'Select',\n                desc: '列选择器，适用于多列联动与层级选择场景。',\n                desc_en: 'Column picker suitable for multi-column linkage and hierarchical selection.'\n            },\n            {\n                path: '/pages/componentsA/keyboard/index',\n                icon: 'keyboard',\n                title: 'Keyboard 键盘',\n                title_en: 'Keyboard',\n                desc: '自定义键盘组件，适用于特殊格式输入或密码场景。',\n                desc_en: 'Custom keyboard for special format inputs or password entry scenarios.'\n            },\n            {\n                path: '/pages/componentsB/picker/index',\n                icon: 'picker',\n                title: 'Picker 选择器',\n                title_en: 'Picker',\n                desc: '滚轮选择器，支持多列配置与联动数据。',\n                desc_en: 'Wheel picker supporting multi-column configuration and linked data.'\n            },\n            {\n                path: '/pages/componentsB/rate/index',\n                icon: 'rate',\n                title: 'Rate 评分',\n                title_en: 'Rate',\n                desc: '评分组件，支持半星、可交互或只读样式。',\n                desc_en: 'Rating component supporting half-stars, interactive and read-only modes.'\n            },\n            {\n                path: '/pages/componentsB/search/index',\n                icon: 'search',\n                title: 'Search 搜索',\n                title_en: 'Search',\n                desc: '搜索输入与建议组件，支持联想与清除历史。',\n                desc_en: 'Search input with suggestions, supporting autocomplete and history clearing.'\n            },\n            {\n                path: '/pages/componentsC/numberBox/index',\n                icon: 'numberBox',\n                title: 'NumberBox 步进器',\n                title_en: 'NumberBox',\n                desc: '步进器组件，用于数量选择与数值调整。',\n                desc_en: 'Stepper component for quantity selection and numeric adjustments.'\n            },\n            {\n                path: '/pages/componentsB/upload/index',\n                icon: 'upload',\n                title: 'Upload 上传',\n                title_en: 'Upload',\n                desc: '文件/图片上传，支持预览、限制大小与并发上传。',\n                desc_en: 'File/image upload with preview, size limits and concurrent uploads support.'\n            },\n            {\n                path: '/pages/componentsA/verificationCode/index',\n                icon: 'verificationCode',\n                title: 'VerificationCode 验证码倒计时',\n                title_en: 'VerificationCode',\n                desc: '验证码倒计时控件，常用于获取验证码的防重发处理。',\n                desc_en: 'Verification code countdown control to prevent repeated requests.'\n            },\n            {\n                path: '/pages/componentsA/field/index',\n                icon: 'field',\n                title: 'Field 输入框',\n                title_en: 'Field',\n                desc: '表单字段封装，包含标签、输入与校验提示。',\n                desc_en: 'Form field wrapper including label, input and validation hints.'\n            },\n            {\n                path: '/pages/componentsB/checkbox/index',\n                icon: 'checkbox',\n                title: 'Checkbox 复选框',\n                title_en: 'Checkbox',\n                desc: '复选框组件，支持多选、全选与禁用状态。',\n                desc_en: 'Checkbox supporting multiple selection, select-all and disabled states.'\n            },\n            {\n                path: '/pages/componentsB/radio/index',\n                icon: 'radio',\n                title: 'Radio 单选框',\n                title_en: 'Radio',\n                desc: '单选组件，适用于互斥选项的选择场景。',\n                desc_en: 'Radio component for mutually exclusive option selection.'\n            },\n            {\n                path: '/pages/componentsB/switch/index',\n                icon: 'switch',\n                title: 'Switch 开关选择器',\n                title_en: 'Switch',\n                desc: '开关组件，用于二元状态切换与即时交互。',\n                desc_en: 'Switch component for binary state toggling and instant interactions.'\n            },\n            {\n                path: '/pages/componentsA/slider/index',\n                icon: 'slider',\n                title: 'Slider 滑动选择器',\n                title_en: 'Slider',\n                desc: '滑动条，用于数值范围选择与微调交互。',\n                desc_en: 'Slider for selecting numeric ranges and fine adjustments.'\n            }\n        ]\n    },\n    {\n        groupName: '数据组件',\n        groupName_en: 'Data components',\n        icon: 'datas',\n        list: [\n            {\n                path: '/pages/componentsC/progress/index',\n                icon: 'progress',\n                title: 'Progress 进度条',\n                title_en: 'Progress',\n                desc: '进度条组件，支持动画、分段与环形/直线样式。',\n                desc_en: 'Progress bar with animation, segmented and circular/linear styles.'\n            },\n            {\n                path: '/pages/componentsB/table/index',\n                icon: 'table',\n                title: 'Table 表格',\n                title_en: 'Table',\n                desc: '表格组件，适用于展示大量结构化数据的场景。',\n                desc_en: 'Table component for displaying structured data.'\n            },\n            {\n                path: '/pages/componentsC/countDown/index',\n                icon: 'countDown',\n                title: 'CountDown 倒计时',\n                title_en: 'CountDown',\n                desc: '倒计时显示组件，适用于活动倒计时或延时提示。',\n                desc_en: 'Countdown display component for events or delay prompts.'\n            },\n            {\n                path: '/pages/componentsC/countTo/index',\n                icon: 'countTo',\n                title: 'CountTo 数字滚动',\n                title_en: 'CountTo',\n                desc: '数字动画组件，用于展示增长数据的滚动效果。',\n                desc_en: 'Number animation component for showcasing incremental data with rolling effect.'\n            }\n        ]\n    },\n    {\n        groupName: '反馈组件',\n        groupName_en: 'Feedback components',\n        icon: 'feedbacks',\n        list: [\n            {\n                path: '/pages/componentsC/actionSheet/index',\n                icon: 'actionSheet',\n                title: 'ActionSheet 操作菜单',\n                title_en: 'ActionSheet',\n                desc: '底部弹出操作菜单，用于提供多个快速操作选项。',\n                desc_en: 'Bottom action sheet offering multiple quick operation choices.'\n            },\n            {\n                path: '/pages/componentsC/alertTips/index',\n                icon: 'alertTips',\n                title: 'AlertTips 警告提示',\n                title_en: 'AlertTips',\n                desc: '用于展示警告或重要提示的非模态/模态消息。',\n                desc_en: 'Alert tips for showing warnings or important messages in modal/non-modal form.'\n            },\n            {\n                path: '/pages/componentsA/toast/index',\n                icon: 'toast',\n                title: 'Toast 消息提示',\n                title_en: 'Toast',\n                desc: '轻量级短时提示，用于反馈用户操作结果。',\n                desc_en: 'Lightweight transient toast for feedback on user actions.'\n            },\n            {\n                path: '/pages/componentsB/noticeBar/index',\n                icon: 'noticeBar',\n                title: 'NoticeBar 滚动通知',\n                title_en: 'NoticeBar',\n                desc: '滚动通知栏，用于展示重要消息或公告。',\n                desc_en: 'Scrolling notice bar for important messages or announcements.'\n            },\n            {\n                path: '/pages/componentsA/topTips/index',\n                icon: 'topTips',\n                title: 'TopTips 顶部提示',\n                title_en: 'TopTips',\n                desc: '顶部提示条，适用于短时警示或成功提示。',\n                desc_en: 'Top tip bar suitable for brief warnings or success messages.'\n            },\n            {\n                path: '/pages/componentsB/swipeAction/index',\n                icon: 'swipeAction',\n                title: 'SwipeAction 滑动单元格',\n                title_en: 'SwipeAction',\n                desc: '滑动操作行，支持左右滑出操作按钮（删除/更多）。',\n                desc_en: 'Swipe action rows supporting left/right action buttons like delete or more.'\n            },\n            {\n                path: '/pages/componentsC/collapse/index',\n                icon: 'collapse',\n                title: 'Collapse 折叠面板',\n                title_en: 'Collapse',\n                desc: '折叠/展开面板，用于节省空间展示可折叠内容。',\n                desc_en: 'Collapsible panels for saving space when showing expandable content.'\n            },\n            {\n                path: '/pages/componentsC/popup/index',\n                icon: 'popup',\n                title: 'Popup 弹出层',\n                title_en: 'Popup',\n                desc: '浮层弹窗组件，支持自定义位置与动画。',\n                desc_en: 'Popup layer supporting custom positions and animations.'\n            },\n            {\n                path: '/pages/componentsA/modal/index',\n                icon: 'modal',\n                title: 'Modal 模态框',\n                title_en: 'Modal',\n                desc: '模态对话框，用于确认或重要信息的交互。',\n                desc_en: 'Modal dialog for confirmations or important interactive messages.'\n            },\n            {\n                path: '/pages/componentsA/fullScreen/index',\n                icon: 'pressingScreen',\n                title: 'fullScreen 压窗屏',\n                title_en: 'fullScreen',\n                desc: '全屏展示组件，适用于沉浸式内容或应用更新提示。',\n                desc_en: 'Full-screen display for immersive content or media playback.'\n            }\n        ]\n    },\n    {\n        groupName: '布局组件',\n        groupName_en: 'Layout components',\n        icon: 'layouts',\n        list: [\n            {\n                path: '/pages/componentsB/line/index',\n                icon: 'line',\n                title: 'Line 线条',\n                title_en: 'Line',\n                desc: '线条分隔组件，用于视觉上分割内容区域。',\n                desc_en: 'Line divider used to visually separate content areas.'\n            },\n            {\n                path: '/pages/componentsB/card/index',\n                icon: 'card',\n                title: 'Card 卡片',\n                title_en: 'Card',\n                desc: '卡片容器，用于信息块的分组展示与布局美化。',\n                desc_en: 'Card container for grouping information blocks and enhancing layout.'\n            },\n            {\n                path: '/pages/componentsC/mask/index',\n                icon: 'mask',\n                title: 'Mask 遮罩层',\n                title_en: 'Mask',\n                desc: '遮罩层组件，常与弹窗或交互遮挡背景配合使用。',\n                desc_en: 'Mask overlay commonly used with popups to obscure the background.'\n            },\n            // #ifndef MP-TOUTIAO\n            {\n                path: '/pages/componentsA/noNetwork/index',\n                icon: 'noNetwork',\n                title: 'NoNetwork 无网络提示',\n                title_en: 'NoNetwork',\n                desc: '网络断开时的提示组件，提供重试或离线指引。',\n                desc_en: 'No-network hint component providing retry or offline guidance.'\n            },\n            // #endif\n            {\n                path: '/pages/componentsC/grid/index',\n                icon: 'grid',\n                title: 'Grid 宫格布局',\n                title_en: 'Grid',\n                desc: '宫格布局，适合图文导航与九宫格样式展示。',\n                desc_en: 'Grid layout suitable for image/text navigation and nine-grid displays.'\n            },\n            {\n                path: '/pages/componentsB/swiper/index',\n                icon: 'swiper',\n                title: 'Swiper 轮播图',\n                title_en: 'Swiper',\n                desc: '轮播图组件，支持自动轮播、指示器与手势滑动。',\n                desc_en: 'Carousel supporting auto-play, indicators and touch swipe.'\n            },\n            {\n                path: '/pages/componentsA/timeLine/index',\n                icon: 'timeLine',\n                title: 'TimeLine 时间轴',\n                title_en: 'TimeLine',\n                desc: '时间轴组件，用于展示事件序列与时间节点。',\n                desc_en: 'Timeline component for displaying sequences of events and time nodes.'\n            },\n            {\n                path: '/pages/componentsB/skeleton/index',\n                icon: 'skeleton',\n                title: 'Skeleton 骨架屏',\n                title_en: 'Skeleton',\n                desc: '骨架屏占位展示，改善加载时的视觉体验。',\n                desc_en: 'Skeleton placeholder to improve visual experience during loading.'\n            },\n            {\n                path: '/pages/componentsB/sticky/index',\n                icon: 'sticky',\n                title: 'Sticky 吸顶',\n                title_en: 'Sticky',\n                desc: '吸顶组件，实现元素在滚动时固定在顶部。',\n                desc_en: 'Sticky component to keep elements fixed at the top during scroll.'\n            },\n            // #ifndef MP-TOUTIAO\n            {\n                path: '/pages/componentsB/waterfall/index',\n                icon: 'waterfall',\n                title: 'Waterfall 瀑布流',\n                title_en: 'Waterfall',\n                desc: '瀑布流布局，适合不规则图片列表与瀑布展示。',\n                desc_en: 'Waterfall layout for irregular image lists and masonry-style displays.'\n            },\n            // #endif\n            {\n                path: '/pages/componentsB/divider/index',\n                icon: 'divider',\n                title: 'Divider 分割线',\n                title_en: 'Divider',\n                desc: '分割线组件，提供可定制的横向分隔样式。',\n                desc_en: 'Divider component providing customizable horizontal separation styles.'\n            }\n        ]\n    },\n    {\n        groupName: '导航组件',\n        groupName_en: 'Navigation components',\n        icon: 'navs',\n        list: [\n            {\n                path: '/pages/componentsB/dropdown/index',\n                icon: 'dropdown',\n                title: 'Dropdown 下拉菜单',\n                title_en: 'Dropdown',\n                desc: '下拉菜单，提供层级或操作选择的浮动列表。',\n                desc_en: 'Dropdown menu offering hierarchical or action choice floating lists.'\n            },\n            {\n                path: '/pages/componentsB/tabbar/index',\n                icon: 'tabbar',\n                title: 'Tabbar 底部导航栏',\n                title_en: 'Tabbar',\n                desc: '应用底部导航，支持图标、文字及选中态。',\n                desc_en: 'Bottom navigation bar supporting icons, text and selected states.'\n            },\n            {\n                path: '/pages/componentsA/backTop/index',\n                icon: 'backTop',\n                title: 'BackTop 返回顶部',\n                title_en: 'BackTop',\n                desc: '返回顶部快捷按钮，便于长页面快速回到顶部。',\n                desc_en: 'Quick back-to-top button useful for long pages.'\n            },\n            {\n                path: '/pages/componentsA/navbar/index',\n                icon: 'navbar',\n                title: 'Navbar 导航栏',\n                title_en: 'Navbar',\n                desc: '顶部导航栏，包含返回、标题与操作项。',\n                desc_en: 'Top navigation bar including back, title and action items.'\n            },\n            {\n                path: '/pages/componentsA/tabs/index',\n                icon: 'tabs',\n                title: 'Tabs 标签',\n                title_en: 'Tabs',\n                desc: '选项卡组件，用于切换不同内容视图。',\n                desc_en: 'Tabs component for switching between different content views.'\n            },\n            // #ifndef MP-ALIPAY\n            {\n                path: '/pages/template/order/index',\n                icon: 'tabsSwiper',\n                title: 'TabsSwiper 全屏选项卡',\n                title_en: 'TabsSwiper',\n                desc: '全屏选项卡，支持手势滑动与整页切换。',\n                desc_en: 'Full-screen tabs supporting gesture swipe and full-page switching.'\n            },\n            // #endif\n            {\n                path: '/pages/componentsC/subsection/index',\n                icon: 'subsection',\n                title: 'Subsection 分段器',\n                title_en: 'Subsection',\n                desc: '分段器，用于在一行内选择多个项或风格切换。',\n                desc_en: 'Subsection control for selecting multiple items or style switches in one line.'\n            },\n            {\n                path: '/pages/componentsA/indexList/index',\n                icon: 'indexList',\n                title: 'IndexList 索引列表',\n                title_en: 'IndexList',\n                desc: '带字母索引的长列表，便于快速跳转至分组项。',\n                desc_en: 'Indexed list with letters for quick navigation to grouped items.'\n            },\n            {\n                path: '/pages/componentsB/steps/index',\n                icon: 'steps',\n                title: 'Steps 步骤条',\n                title_en: 'Steps',\n                desc: '步骤条，用于展现多步骤流程与当前进度。',\n                desc_en: 'Steps bar to show multi-step processes and current progress.'\n            },\n            {\n                path: '/pages/componentsA/empty/index',\n                icon: 'empty',\n                title: 'Empty 内容为空',\n                title_en: 'Empty',\n                desc: '空状态占位组件，用于无数据时的友好提示。',\n                desc_en: 'Empty state placeholder for friendly messaging when no data exists.'\n            },\n            {\n                path: '/pages/componentsC/section/index',\n                icon: 'section',\n                title: 'Section 查看更多',\n                title_en: 'Section',\n                desc: '分段展开组件，支持查看更多与折叠收起长内容。',\n                desc_en: 'Section component supporting expand/collapse for long content.'\n            },\n            {\n                path: '/pages/componentsC/pagination/index',\n                icon: 'pagination',\n                title: 'Pagination 分页',\n                title_en: 'Pagination',\n                desc: '分页组件，控制页数跳转与当前页展示。',\n                desc_en: 'Pagination component to control page jumps and show current page.'\n            }\n        ]\n    },\n    {\n        groupName: '其他组件',\n        groupName_en: 'Other components',\n        icon: 'others',\n        list: [\n            {\n                path: '/pages/componentsC/messageInput/index',\n                icon: 'messageInput',\n                title: 'MessageInput 验证码输入',\n                title_en: 'MessageInput',\n                desc: '分段输入组件，常用于验证码/短信输入体验，支持粘贴与校验。',\n                desc_en: 'Segmented input for codes, supporting paste and validation.'\n            },\n            // {\n            //     path: '/pages/componentsC/citySelect/index',\n            //     icon: 'citySelect',\n            //     title: 'CitySelect 城市选择',\n            //     title_en: 'CitySelect',\n            //     desc: '城市选择组件，支持多级联动选择。',\n            //     desc_en: 'City selection component supporting multi-level linkage selection.'\n            // },\n            // {\n            //     path: '/pages/componentsA/avatarCropper/index',\n            //     icon: 'avatarCropper',\n            //     title: 'AvatarCropper 头像裁剪',\n            //     title_en: 'AvatarCropper'\n            // },\n            {\n                path: '/pages/componentsC/loadmore/index',\n                icon: 'loadmore',\n                title: 'Loadmore 加载更多',\n                title_en: 'Loadmore',\n                desc: '加载更多占位与触发器，通常用于下拉或滚动分页加载。',\n                desc_en: 'Load-more placeholder and trigger commonly used for pull/scroll pagination.'\n            },\n            {\n                path: '/pages/componentsB/readMore/index',\n                icon: 'readMore',\n                title: 'ReadMore 展开阅读更多',\n                title_en: 'ReadMore',\n                desc: '长文本收起与展开组件，提高长内容的可读性。',\n                desc_en: 'Read-more control to collapse/expand long text for better readability.'\n            },\n            {\n                path: '/pages/componentsA/lazyLoad/index',\n                icon: 'lazyLoad',\n                title: 'LazyLoad 懒加载',\n                title_en: 'LazyLoad',\n                desc: '按需加载图片或资源，减少首次渲染流量与性能开销。',\n                desc_en: 'Lazy load images/resources to reduce initial load and improve performance.'\n            },\n            {\n                path: '/pages/componentsC/gap/index',\n                icon: 'gap',\n                title: 'Gap 间隔槽',\n                title_en: 'Gap',\n                desc: '间隔组件，提供统一的间距帮助布局排版。',\n                desc_en: 'Gap component providing consistent spacing for layout and typography.'\n            },\n            {\n                path: '/pages/componentsA/avatar/index',\n                icon: 'avatar',\n                title: 'Avatar 头像',\n                title_en: 'Avatar',\n                desc: '用于展示用户头像、等级、性别等信息，支持多种形态和自定义内容。',\n                desc_en: 'Displays user avatar, level, gender etc., with multiple shapes and custom content.'\n            },\n            {\n                path: '/pages/componentsC/link/index',\n                icon: 'link',\n                title: 'Link 超链接',\n                title_en: 'Link',\n                desc: '超链接组件，支持跳转、外链与样式定制。',\n                desc_en: 'Link component supporting navigation, external links and style customization.'\n            },\n            {\n                path: '/pages/componentsB/loading/index',\n                icon: 'loading',\n                title: 'Loading 加载动画',\n                title_en: 'Loading',\n                desc: '加载动画组件，常用于等待态提示与占位效果。',\n                desc_en: 'Loading animation component for wait states and placeholders.'\n            },\n            {\n                path: '/pages/componentsB/loadingPopup/index',\n                icon: 'loadingPopup',\n                title: 'Loading 加载弹窗',\n                title_en: 'Loading Popup',\n                desc: '阻塞式加载弹窗，用于覆盖页面并提示加载中状态。',\n                desc_en: 'Blocking loading popup to overlay the page and indicate loading status.'\n            },\n            {\n                path: '/pages/componentsB/transition/index',\n                icon: 'loadingPopup',\n                title: 'Transition 动画',\n                title_en: 'Loading Popup',\n                desc: '阻塞式加载弹窗，用于覆盖页面并提示加载中状态。',\n                desc_en: 'Blocking loading popup to overlay the page and indicate loading status.'\n            }\n        ]\n    }\n];\n"
  },
  {
    "path": "src/pages/example/components.vue",
    "content": "<template>\n    <demo-page ref=\"demoPageRef\" :nav-title=\"t('nav.components')\" :nav-back=\"false\" :tabbar=\"true\">\n        <view class=\"wrap\">\n            <page-nav :desc=\"desc\" title=\"nav.components\" :index=\"0\"></page-nav>\n\n            <!-- 主题切换按钮区域 -->\n            <demo-guide-use\n                :storage-key=\"GUIDE_THEME_SWITCHER_KEY\"\n                :immediate=\"guideImmediate[0]\"\n                placement=\"bottom\"\n                text=\"点击「切换主题项目」可体验不同主题效果\"\n                button-text=\"我知道了\"\n                @close=\"guideImmediate[1] = true\"\n                :position=\"{ top: '800rpx', left: '100rpx' }\"\n            >\n                <view class=\"theme-switcher\">\n                    <view class=\"theme-label\">{{ t('components.theme') || '主题' }}</view>\n                    <view class=\"theme-buttons\">\n                        <view\n                            v-for=\"theme in themes\"\n                            :key=\"theme.name\"\n                            class=\"theme-btn\"\n                            :class=\"{ active: currentTheme.name === theme.name }\"\n                            @click=\"switchTheme(theme.name)\"\n                            :title=\"theme.description\"\n                        >\n                            <view class=\"theme-color\" :style=\"{ backgroundColor: theme.color.primary }\"></view>\n                            <view class=\"theme-name\">{{ t(`theme.${theme.name}`) }}</view>\n                        </view>\n                    </view>\n                </view>\n            </demo-guide-use>\n\n            <!-- 体验地图入口 -->\n            <demo-guide-use\n                :storage-key=\"GUIDE_EXPERIENCE_KEY\"\n                :immediate=\"guideImmediate[1]\"\n                placement=\"top\"\n                text=\"点击「体验地图 ITEM」可查看我的组件体验等级\"\n                button-text=\"我知道了\"\n                @close=\"demoPageRef.showTabbarGuide()\"\n                :position=\"{ top: '300rpx', left: '100rpx' }\"\n            >\n                <view\n                    class=\"experience-entry\"\n                    @click=\"$u.route({ url: '/pages/example/experienceMap', type: 'switchTab' })\"\n                >\n                    <view class=\"experience-entry__left\">\n                        <view class=\"experience-entry__title\">{{ t('common.experienceMap') }}</view>\n                        <view class=\"experience-entry__desc\">{{ t('common.experienceMapDesc') }}</view>\n                    </view>\n                    <view class=\"experience-entry__right\">\n                        <u-icon\n                            custom-prefix=\"custom-icon\"\n                            name=\"map-route\"\n                            size=\"70\"\n                            :color=\"$u.getColor('primary')\"\n                        ></u-icon>\n                    </view>\n                </view>\n            </demo-guide-use>\n\n            <!-- 实用场景入口 -->\n            <view class=\"scenes-entry\" @click=\"$u.route({ url: '/pages/scenes/index' })\">\n                <view class=\"scenes-entry__left\">\n                    <view class=\"scenes-entry__title\">{{ t('common.scene') }}</view>\n                    <view class=\"scenes-entry__desc\">{{ t('common.sceneDesc') }}</view>\n                </view>\n                <view class=\"scenes-entry__right\">\n                    <u-icon\n                        custom-prefix=\"custom-icon\"\n                        name=\"template-fill\"\n                        size=\"70\"\n                        :color=\"$u.getColor('success')\"\n                    ></u-icon>\n                </view>\n            </view>\n            <!-- 搜索区域 -->\n            <view class=\"search-container\">\n                <u-sticky :offset-top=\"offsetTop\" bg-color=\"transparent\">\n                    <view class=\"search-box\">\n                        <u-search\n                            v-model=\"searchText\"\n                            @search=\"handleSearch\"\n                            @custom=\"handleSearch\"\n                            :placeholder=\"`${t('components.searchComponent')}`\"\n                            :show-action=\"false\"\n                            :action-text=\"t('components.search')\"\n                            shape=\"round\"\n                            :bg-color=\"searchBgColor\"\n                        ></u-search>\n                    </view>\n                </u-sticky>\n\n                <view v-if=\"searchText\" class=\"search-tips\">\n                    {{ t('components.find') }} <text class=\"count\">{{ filteredList.length }}</text>\n                    {{ t('components.matchingComponent') }}\n                    <text class=\"clear-btn\" @click=\"clearSearch\">{{ t('components.clear') }}</text>\n                </view>\n            </view>\n\n            <!-- 无搜索结果 -->\n            <view v-if=\"searchText && filteredList.length === 0\" class=\"empty-state\">\n                <u-empty mode=\"search\" :text=\"t('components.notFound')\" :show-empty=\"true\"></u-empty>\n            </view>\n\n            <!-- 组件列表：流式卡片展示 -->\n            <view v-else class=\"list-wrap\">\n                <view v-for=\"(group, gIndex) in filteredList\" :key=\"gIndex\" class=\"group-section\">\n                    <view class=\"group-title\">\n                        <u-image :height=\"50\" :width=\"50\" :src=\"getIcon(group.icon)\"></u-image>\n                        <text class=\"group-name\">{{ getTitle('groupName', group) }}</text>\n                        <view class=\"group-count\">{{ group.list.length }}</view>\n                    </view>\n\n                    <view class=\"cards\">\n                        <view\n                            class=\"card\"\n                            v-for=\"(item, idx) in group.list\"\n                            :key=\"idx\"\n                            @click=\"handleCardClick(item.path)\"\n                            :style=\"{ animationDelay: gIndex * 120 + Number(idx) * 60 + 'ms' }\"\n                        >\n                            <!-- 图像小预览 -->\n                            <u-image\n                                :height=\"50\"\n                                :width=\"50\"\n                                :src=\"getIcon(item.icon || item.path)\"\n                                mode=\"widthFix\"\n                            ></u-image>\n                            <view class=\"card-body\">\n                                <view class=\"card-title\">{{ getTitle('title', item) }}</view>\n                                <view class=\"card-desc\">{{ getTitle('desc', item) }}</view>\n                            </view>\n                            <view class=\"card-arrow\">›</view>\n                        </view>\n                    </view>\n                </view>\n            </view>\n            <u-gap height=\"70\"></u-gap>\n            <u-back-top\n                mode=\"circle\"\n                :scroll-top=\"scrollTop\"\n                :bottom=\"220\"\n                :custom-style=\"{ backgroundColor: $u.getColor('primaryLight') }\"\n            >\n                <u-icon custom-prefix=\"custom-icon\" name=\"rocket\" size=\"50\" :color=\"$u.getColor('primary')\"></u-icon>\n            </u-back-top>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport rawList from './components.config';\nimport { ref, computed } from 'vue';\nimport { useI18n } from 'vue-i18n';\nimport { onPageScroll, onShow } from '@dcloudio/uni-app';\nimport { useTitle } from '@/common/useHooks';\nimport { useTheme } from '@/uni_modules/uview-pro';\nimport { $u } from 'uview-pro';\nimport { GUIDE_THEME_SWITCHER_KEY, GUIDE_EXPERIENCE_KEY } from '@/common/constant';\nimport { completeMission } from '../../common/useExperience';\n\n// 主题管理（使用组合式 useTheme）\nconst { currentTheme, themes, setTheme } = useTheme();\n\nconst switchTheme = (themeName: string) => {\n    setTheme(themeName);\n    completeMission('theme');\n};\n\nconst list = ref<any[]>(Array.isArray(rawList) ? rawList : []); // 明确类型 any[]\nconst scrollTop = ref(0);\nconst searchText = ref('');\nconst searchBgColor = computed(() => $u.getColor('bgColor'));\nconst demoPageRef = ref();\n\nconst guideImmediate = ref([true, false]);\n\n// 国际化\nconst { t, locale } = useI18n();\nconst { setTitle, getTitle } = useTitle(0);\n\n// 获取图标地址\nconst getIcon = (path: string) => {\n    // #ifdef APP\n    return '/static/app/example/' + path + '.png';\n    // #endif\n    return 'https://ik.imagekit.io/anyup/uview-pro/example/' + path + '.png';\n};\n\nconst offsetTop = computed(() => {\n    let offset = 0;\n    // #ifdef MP-WEIXIN\n    offset = 200;\n    // #endif\n    return offset; // 其他平台默认偏移\n});\n\n// 组件描述\nconst desc = computed(() => t('components.desc'));\n\nfunction backToTop() {\n    // uni.pageScrollTo 用于页面滚动到顶部\n    if (typeof uni !== 'undefined' && uni.pageScrollTo) {\n        uni.pageScrollTo({\n            scrollTop: 0,\n            duration: 0\n        });\n    }\n}\n\n// 搜索过滤逻辑：支持 title / title_en / description / path\nconst filteredList = computed(() => {\n    if (!searchText.value) {\n        return list.value;\n    }\n\n    const keyword = searchText.value.toLowerCase();\n\n    return list.value\n        .map(group => {\n            const filteredItems = group.list.filter((item: any) => {\n                const title = (getTitle('title', item) || '').toLowerCase();\n                const titleEn = (item.title_en || '').toLowerCase();\n                const desc = (item.description || item.desc || '').toLowerCase();\n                const path = (item.path || '').toLowerCase();\n\n                return (\n                    title.includes(keyword) ||\n                    titleEn.includes(keyword) ||\n                    desc.includes(keyword) ||\n                    path.includes(keyword)\n                );\n            });\n\n            return {\n                ...group,\n                list: filteredItems\n            };\n        })\n        .filter(group => group.list.length > 0);\n});\n\n/**\n * 处理搜索\n */\nfunction handleSearch() {\n    // 搜索操作\n}\n\n/**\n * 清空搜索\n */\nfunction clearSearch() {\n    searchText.value = '';\n}\n\n/**\n * 处理卡片点击\n */\nfunction handleCardClick(path: string) {\n    openPage(path);\n}\n\n/**\n * 路由跳转\n */\nfunction openPage(path: string) {\n    // 兼容所有平台的跳转\n    uni.navigateTo({ url: path });\n}\n\n// 页面滚动事件处理\nonPageScroll(e => {\n    scrollTop.value = e.scrollTop;\n});\n\n// 设置标题\nonShow(() => {\n    setTitle();\n});\n</script>\n\n<style lang=\"scss\" scoped>\n// 主题切换器\n.theme-switcher {\n    padding: 0 30rpx 24rpx 30rpx;\n    background: transparent;\n\n    .theme-label {\n        font-size: 24rpx;\n        font-weight: 600;\n        color: $u-main-color;\n        margin-bottom: 16rpx;\n    }\n\n    .theme-buttons {\n        display: flex;\n        gap: 12rpx;\n        flex-wrap: wrap;\n    }\n\n    .theme-btn {\n        display: flex;\n        flex-direction: column;\n        align-items: center;\n        gap: 8rpx;\n        padding: 12rpx 20rpx;\n        background: $u-bg-color;\n        border: 2rpx solid $u-border-color;\n        border-radius: 10rpx;\n        transition: all 0.28s cubic-bezier(0.2, 0.9, 0.2, 1);\n        cursor: pointer;\n        box-shadow: 0 4rpx 14rpx rgba(var(--u-main-color-rgb, 48, 49, 51), 0.08);\n\n        &:active,\n        &.active {\n            border-color: $u-type-primary;\n            background: rgba(var(--u-type-primary-rgb, 41, 121, 255), 0.08);\n            box-shadow: 0 8rpx 24rpx rgba(var(--u-type-primary-rgb, 41, 121, 255), 0.2);\n            transform: scale(1.02);\n        }\n\n        .theme-color {\n            width: 32rpx;\n            height: 32rpx;\n            border-radius: 50%;\n            box-shadow: 0 2rpx 8rpx rgba(var(--u-main-color-rgb, 48, 49, 51), 0.12);\n            border: 2rpx solid $u-bg-color;\n        }\n\n        .theme-name {\n            font-size: 22rpx;\n            color: $u-content-color;\n            font-weight: 500;\n        }\n\n        &.active .theme-name {\n            color: $u-type-primary;\n            font-weight: 700;\n        }\n    }\n}\n\n.experience-entry {\n    margin: 0 30rpx 12rpx;\n    padding: 30rpx 22rpx;\n    border-radius: 16rpx;\n    background: linear-gradient(135deg, rgba(41, 121, 255, 0.12), rgba(25, 190, 107, 0.08));\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    box-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.06);\n    &__left {\n        display: flex;\n        flex-direction: column;\n        gap: 6rpx;\n    }\n    &__title {\n        font-size: 28rpx;\n        font-weight: 600;\n        color: $u-main-color;\n    }\n    &__desc {\n        font-size: 24rpx;\n        color: $u-tips-color;\n    }\n}\n\n.scenes-entry {\n    margin: 0 30rpx 12rpx;\n    padding: 30rpx 22rpx;\n    border-radius: 16rpx;\n    background: linear-gradient(135deg, rgba(25, 190, 107, 0.12), rgba(41, 121, 255, 0.08));\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    box-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.06);\n    transition: all 0.3s ease;\n\n    &:active {\n        transform: scale(0.98);\n    }\n\n    &__left {\n        display: flex;\n        flex-direction: column;\n        gap: 6rpx;\n    }\n    &__title {\n        font-size: 28rpx;\n        font-weight: 600;\n        color: $u-main-color;\n    }\n    &__desc {\n        font-size: 24rpx;\n        color: $u-tips-color;\n    }\n}\n\n.u-cell-icon {\n    width: 36rpx;\n    height: 36rpx;\n    margin-right: 8rpx;\n}\n\n// 搜索容器\n.search-container {\n    padding: 10rpx 30rpx;\n    background: transparent;\n    position: relative;\n    z-index: 10;\n\n    .search-box {\n        margin-bottom: 20rpx;\n        background-color: transparent;\n        border-radius: 12rpx;\n    }\n}\n\n// 搜索提示\n.search-tips {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    padding: 12rpx 20rpx;\n    background: rgba(var(--u-type-primary-rgb, 41, 121, 255), 0.08);\n    border-radius: 8rpx;\n    font-size: 24rpx;\n    color: $u-content-color;\n    border-left: 4rpx solid $u-type-primary;\n\n    .count {\n        color: $u-type-primary;\n        font-weight: bold;\n        margin: 0 8rpx;\n    }\n\n    .clear-btn {\n        color: $u-type-primary;\n        font-size: 22rpx;\n        padding: 8rpx 16rpx;\n        background: rgba(var(--u-type-primary-rgb, 41, 121, 255), 0.12);\n        border-radius: 6rpx;\n        transition: all 0.3s ease;\n\n        &:active {\n            background: rgba(var(--u-type-primary-rgb, 41, 121, 255), 0.22);\n            transform: scale(0.95);\n        }\n    }\n}\n\n// 空状态\n.empty-state {\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    min-height: 400rpx;\n    background: transparent;\n}\n\n// 列表容器\n.list-wrap {\n    padding: 0 30rpx;\n    margin-top: 20rpx;\n}\n\n// 分组区\n.group-section {\n    margin-bottom: 36rpx;\n}\n\n/* 卡片网格 */\n.cards {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 18rpx;\n    margin-top: 20rpx;\n}\n\n.card {\n    width: calc((100% - 3 * 18rpx) / 4);\n    background: $u-bg-white;\n    border-radius: 14rpx;\n    padding: 22rpx 18rpx;\n    display: flex;\n    align-items: center;\n    box-shadow: 0 12rpx 30rpx rgba(var(--u-type-primary-rgb, 41, 121, 255), 0.08);\n    transition:\n        transform 0.18s cubic-bezier(0.2, 0.9, 0.2, 1),\n        box-shadow 0.18s ease,\n        filter 0.18s ease;\n    cursor: pointer;\n    will-change: transform, opacity;\n    opacity: 0;\n    transform: translateY(10rpx) scale(0.997);\n    animation: fadeUp 420ms cubic-bezier(0.2, 0.9, 0.2, 1) both;\n}\n\n.card:hover {\n    transform: translateY(-8rpx) scale(1.01);\n    box-shadow: 0 26rpx 60rpx rgba(var(--u-type-primary-rgb, 41, 121, 255), 0.16);\n    filter: saturate(1.02);\n}\n\n.card-body {\n    margin-left: 20rpx;\n    flex: 1;\n}\n\n.card-title {\n    font-size: 30rpx;\n    font-weight: 700;\n    color: $u-main-color;\n    margin-bottom: 16rpx;\n}\n\n.card-desc {\n    font-size: 26rpx;\n    color: $u-content-color;\n    line-height: 32rpx;\n    max-height: 64rpx;\n    overflow: hidden;\n    text-overflow: ellipsis;\n}\n\n.card-arrow {\n    font-size: 40rpx;\n    color: rgba(0, 0, 0, 0.12);\n    margin-left: 12rpx;\n    color: $u-type-primary;\n}\n\n.card:hover .card-img {\n    transform: scale(1.06) rotate(-1deg);\n}\n\n.card:hover .card-arrow {\n    transform: translateX(8rpx);\n    color: $u-type-primary;\n    transition:\n        transform 0.18s ease,\n        color 0.18s ease;\n}\n\n@keyframes fadeUp {\n    0% {\n        opacity: 0;\n        transform: translateY(12rpx) scale(0.995);\n    }\n    100% {\n        opacity: 1;\n        transform: translateY(0) scale(1);\n    }\n}\n\n/* 为了 stagger 效果：使用内联 style 设置 animation-delay */\n\n/* 响应：小屏 2 列 */\n@media (max-width: 768px) {\n    .card {\n        width: calc((100% - 18rpx) / 2);\n    }\n    .card-title {\n        font-size: 26rpx;\n    }\n\n    .card-desc {\n        font-size: 22rpx;\n        line-height: 30rpx;\n        max-height: 60rpx;\n    }\n}\n\n/* 更小屏 1 列 */\n@media (max-width: 420px) {\n    .card {\n        width: 100%;\n    }\n    .card-title {\n        font-size: 30rpx;\n    }\n\n    .card-desc {\n        font-size: 24rpx;\n        line-height: 32rpx;\n        max-height: 64rpx;\n    }\n}\n\n// 组群标题\n.group-title {\n    display: flex;\n    align-items: center;\n    font-size: 28rpx;\n    font-weight: 600;\n    color: $u-main-color;\n    height: 60rpx;\n    position: relative;\n\n    image {\n        margin-right: 20rpx;\n        border-radius: 6rpx;\n    }\n\n    .group-name {\n        flex: 1;\n        background: linear-gradient(135deg, $u-type-primary 0%, $u-type-primary-dark 100%);\n        -webkit-background-clip: text;\n        -webkit-text-fill-color: transparent;\n        background-clip: text;\n        font-size: 36rpx;\n        margin-left: 20rpx;\n    }\n\n    .group-count {\n        background: linear-gradient(135deg, $u-type-primary 0%, $u-type-primary-dark 100%);\n        color: #ffffff;\n        padding: 6rpx 16rpx;\n        border-radius: 20rpx;\n        font-size: 22rpx;\n        font-weight: 600;\n        box-shadow: 0 4rpx 15rpx rgba(102, 126, 234, 0.4);\n    }\n}\n\n// 平台特定样式\n// H5平台增强\n@media (min-width: 769px) {\n    .group-title {\n        transition: all 0.3s ease;\n\n        &:hover {\n            transform: translateX(10rpx);\n        }\n    }\n\n    .clear-btn {\n        cursor: pointer;\n\n        &:hover {\n            background: rgba(0, 122, 255, 0.15);\n        }\n    }\n}\n\n// 小程序平台\n/* #ifdef MP-WEIXIN */\n.group-title {\n    padding-right: 20rpx;\n}\n/* #endif */\n\n// App平台\n/* #ifdef APP-PLUS */\n.wrap {\n    padding-top: 10rpx;\n}\n/* #endif */\n</style>\n"
  },
  {
    "path": "src/pages/example/experienceMap.vue",
    "content": "<template>\n    <demo-page nav-title=\"体验地图\" :nav-back=\"false\" :tabbar=\"true\">\n        <view class=\"experience-map\">\n            <view class=\"hero-card u-m-b-20\">\n                <view class=\"hero-badge\">\n                    <view class=\"hero-badge__inner\">\n                        <view class=\"hero-badge__text\">{{ levelInfo.title }}</view>\n                        <view class=\"hero-badge__glow\"></view>\n                    </view>\n                </view>\n                <view class=\"hero-title\">我的组件体验等级</view>\n                <view class=\"hero-subtitle\">{{ levelInfo.title }}</view>\n                <view class=\"hero-xp\">\n                    <text class=\"hero-xp__value\">{{ xp }} XP</text>\n                    <text class=\"hero-xp__hint\">\n                        <text v-if=\"nextLevel\">\n                            距离 {{ nextLevel.title }} 还差 {{ Math.max(nextLevel.threshold - xp, 0) }} XP\n                        </text>\n                        <text v-else>已达到最高段位，继续自由探索吧</text>\n                    </text>\n                </view>\n                <u-line-progress\n                    :percent=\"levelProgress\"\n                    height=\"16px\"\n                    :show-text=\"false\"\n                    active-color=\"var(--u-type-warning)\"\n                    inactive-color=\"rgba(0,0,0,0.08)\"\n                />\n                <view class=\"hero-tags\">\n                    <u-tag size=\"mini\" type=\"primary\" :text=\"`已体验 ${componentSummary.components} 个组件`\" plain />\n                    <u-tag size=\"mini\" type=\"success\" :text=\"`完成 ${componentSummary.tasksCompleted} 个任务`\" plain />\n                    <u-tag\n                        v-if=\"componentSummary.mostActive\"\n                        size=\"mini\"\n                        type=\"warning\"\n                        :text=\"`最常用：${componentSummary.mostActive.key}`\"\n                        plain\n                    />\n                </view>\n            </view>\n\n            <u-card title=\"体验任务\" :border=\"false\" margin=\"0\">\n                <template #body>\n                    <view v-if=\"currentMission\" class=\"mission-card\">\n                        <view class=\"mission-card__title\">{{ currentMission.title }}</view>\n                        <view class=\"mission-card__desc\">{{ currentMission.desc }}</view>\n                        <view class=\"mission-card__meta\">\n                            <u-tag size=\"mini\" type=\"primary\" plain :text=\"currentMission.hint\">\n                                {{ currentMission.hint }}\n                            </u-tag>\n                            <u-tag size=\"mini\" type=\"warning\" plain :text=\"`奖励${currentMission.reward}XP`\">\n                                {{ currentMission.reward }} XP\n                            </u-tag>\n                            <u-tag v-if=\"isCurrentMissionCompleted\" size=\"mini\" type=\"success\" plain text=\"已完成\">\n                                已完成\n                            </u-tag>\n                        </view>\n                        <view class=\"mission-card__actions\">\n                            <u-button type=\"error\" size=\"mini\" plain @click=\"refreshMission\">换一个</u-button>\n                            <u-button\n                                v-if=\"isCurrentMissionCompleted\"\n                                type=\"success\"\n                                size=\"mini\"\n                                @click=\"handleClaimReward\"\n                            >\n                                领取积分\n                            </u-button>\n                            <u-button v-else type=\"primary\" size=\"mini\" @click=\"handleCompleteMission\">\n                                完成任务\n                            </u-button>\n                        </view>\n                    </view>\n                    <view v-else class=\"mission-empty\">\n                        <view class=\"mission-empty__text\">暂无任务，立即领取一个体验挑战吧～</view>\n                        <u-button type=\"primary\" size=\"mini\" @click=\"handleAssignMission\">领取任务</u-button>\n                    </view>\n                </template>\n            </u-card>\n\n            <u-card title=\"成长路线\" :border=\"false\" margin=\"0\">\n                <template #body>\n                    <view class=\"map-steps\">\n                        <view v-for=\"step in displayMapSteps\" :key=\"step.id\" class=\"map-step\">\n                            <view class=\"map-step__header\">\n                                <view class=\"map-step__title-wrap\">\n                                    <view class=\"map-step__dot\" :class=\"`map-step__dot--${step.status}`\"></view>\n                                    <text class=\"map-step__title\">{{ step.title }}</text>\n                                </view>\n                                <u-tag\n                                    size=\"mini\"\n                                    :type=\"\n                                        step.status === 'finish'\n                                            ? 'success'\n                                            : step.status === 'process'\n                                              ? 'warning'\n                                              : 'info'\n                                    \"\n                                    :text=\"\n                                        step.status === 'finish'\n                                            ? '已达成'\n                                            : step.status === 'process'\n                                              ? '进行中'\n                                              : '未解锁'\n                                    \"\n                                />\n                            </view>\n                            <u-line-progress\n                                :percent=\"step.percent\"\n                                height=\"10px\"\n                                :show-text=\"false\"\n                                active-color=\"var(--u-type-primary)\"\n                                inactive-color=\"rgba(0,0,0,0.08)\"\n                            />\n                            <view class=\"map-step__tip\">{{ step.tip }}</view>\n                        </view>\n                    </view>\n                </template>\n            </u-card>\n\n            <u-card title=\"组件体验雷达\" :border=\"false\" margin=\"0\">\n                <view class=\"radar-list\">\n                    <view v-for=\"stat in topComponents\" :key=\"stat.key\" class=\"radar-item\">\n                        <view class=\"radar-item__header\">\n                            <text class=\"radar-item__name\">{{ stat.key }}</text>\n                            <text class=\"radar-item__xp\">{{ stat.xp }} XP</text>\n                        </view>\n                        <u-line-progress\n                            :percent=\"getComponentPercent(stat.xp)\"\n                            height=\"10px\"\n                            :show-text=\"false\"\n                            active-color=\"var(--u-type-primary)\"\n                            inactive-color=\"rgba(0,0,0,0.06)\"\n                        />\n                        <view class=\"radar-item__meta\">\n                            <text>交互 {{ stat.interactions }} 次 · 任务 {{ stat.tasksCompleted }} 个</text>\n                        </view>\n                    </view>\n                    <view v-if=\"!topComponents.length\" class=\"radar-empty\">\n                        暂无组件体验记录，去任意组件页面多点点交互吧～\n                    </view>\n                </view>\n            </u-card>\n\n            <u-card title=\"最近体验记录\" :border=\"false\" margin=\"0\">\n                <view v-if=\"hasRealLogs\" class=\"log-list\">\n                    <view v-for=\"log in displayLogs\" :key=\"log.timestamp\" class=\"log-item\">\n                        <view class=\"log-item__main\">\n                            <text class=\"log-item__text\">{{ log.message }}</text>\n                        </view>\n                        <text class=\"log-item__time\">{{ formatLogTime(log.timestamp) }}</text>\n                    </view>\n                </view>\n                <view v-else class=\"log-list\">\n                    <view v-for=\"log in displayLogs\" :key=\"log.timestamp\" class=\"log-item log-item--placeholder\">\n                        <view class=\"log-item__main\">\n                            <text class=\"log-item__text\">{{ log.message }}</text>\n                        </view>\n                        <text class=\"log-item__time\">{{ formatLogTime(log.timestamp) }}</text>\n                    </view>\n                    <view class=\"log-empty\">暂无真实体验记录，先去组件页完成一些任务吧～</view>\n                </view>\n            </u-card>\n\n            <u-card title=\"下一步推荐\" :border=\"false\" margin=\"0\">\n                <view class=\"suggest-list\">\n                    <u-cell-group :border=\"false\">\n                        <u-cell-item\n                            v-for=\"suggest in suggests\"\n                            :key=\"suggest.title\"\n                            :title=\"suggest.title\"\n                            :label=\"suggest.desc\"\n                            :arrow=\"false\"\n                            :custom-style=\"{ padding: '10px 0' }\"\n                            :label-style=\"{ fontSize: '11px' }\"\n                            @click=\"goToPath(suggest.path)\"\n                        >\n                            <template #icon>\n                                <u-icon\n                                    :name=\"suggest.icon\"\n                                    custom-prefix=\"custom-icon\"\n                                    size=\"40\"\n                                    :color=\"suggest.iconColor\"\n                                    :custom-style=\"{ marginRight: '5px' }\"\n                                ></u-icon>\n                            </template>\n                            <template #right-icon>\n                                <u-tag\n                                    size=\"mini\"\n                                    type=\"primary\"\n                                    :text=\"suggest.tag\"\n                                    plain\n                                    :custom-style=\"{ width: '112rpx' }\"\n                                ></u-tag>\n                            </template>\n                        </u-cell-item>\n                    </u-cell-group>\n                </view>\n            </u-card>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from 'vue';\nimport { useExperienceCenter } from '@/common/useExperienceCenter';\nimport {\n    missionPool,\n    completeMission,\n    assignMission,\n    unassignMission,\n    claimMissionReward,\n    isMissionCompleted,\n    type Mission\n} from '@/common/useExperience';\nimport { $u } from 'uview-pro';\nimport { onShow } from '@dcloudio/uni-app';\n\nconst { xp, levelInfo, nextLevel, levelProgress, mapSteps, recentLogs, componentSummary, componentStats } =\n    useExperienceCenter();\n\nconst formatLogTime = (timestamp: number) => {\n    const date = new Date(timestamp);\n    const month = String(date.getMonth() + 1).padStart(2, '0');\n    const day = String(date.getDate()).padStart(2, '0');\n    const hour = String(date.getHours()).padStart(2, '0');\n    const minute = String(date.getMinutes()).padStart(2, '0');\n    return `${month}/${day} ${hour}:${minute}`;\n};\n\nconst topComponents = computed(() => {\n    // 从 useExperienceCenter 获取所有组件统计数据\n    const stats = (componentStats as any)?.value || componentStats || {};\n\n    // 获取所有组件的统计数据\n    const components = Object.values(stats) as any[];\n\n    // 按 XP 排序，取前 5 个\n    const sorted = components\n        .filter(stat => stat && stat.xp > 0)\n        .sort((a, b) => b.xp - a.xp)\n        .slice(0, 5);\n\n    return sorted;\n});\n\nconst getComponentPercent = (componentXp: number) => {\n    if (componentXp === 0) return 0;\n\n    // 计算该组件在所有组件中的占比，但不超过100%\n    const allComponents = topComponents.value;\n    if (allComponents.length === 0) return 0;\n\n    const maxComponentXP = Math.max(...allComponents.map(c => c.xp), componentXp);\n    if (maxComponentXP === 0) return 0;\n\n    return Math.min(100, Math.round((componentXp / maxComponentXP) * 100));\n};\n\nconst fallbackMapSteps = [\n    { id: 'start', title: '起步探索', tip: '完成任意组件的首次交互', status: 'wait', percent: 0 },\n    { id: 'interact', title: '交互达人', tip: '累计体验值达到 80 点', status: 'wait', percent: 0 },\n    { id: 'scene', title: '场景高手', tip: '完成 10 个任务点位', status: 'wait', percent: 0 },\n    { id: 'mentor', title: '体验导师', tip: '体验值达到 260 点', status: 'wait', percent: 0 }\n];\n\nconst displayMapSteps = computed(() => {\n    const steps = (mapSteps as any)?.value ?? mapSteps;\n    if (Array.isArray(steps) && steps.length) return steps;\n    return fallbackMapSteps;\n});\n\nconst fallbackLogs = [\n    { message: '完成 Image 组件任务 +12XP', timestamp: Date.now() - 1000 * 60 * 20 },\n    { message: '切换主题并收藏组件 +6XP', timestamp: Date.now() - 1000 * 60 * 60 }\n];\n\nconst getRecentLogs = () => {\n    const value = (recentLogs as any)?.value ?? recentLogs;\n    return Array.isArray(value) ? value : [];\n};\n\nconst displayLogs = computed(() => {\n    const logs = getRecentLogs();\n    if (logs.length) return logs;\n    return fallbackLogs;\n});\nconst hasRealLogs = computed(() => getRecentLogs().length > 0);\n\nconst missionStateKey = 'experience-map-mission';\nconst currentMissionId = ref<string | null>(null);\nconst completedMissionIds = ref<string[]>([]);\nconst missionVerification = ref<Record<string, { verified: boolean; timestamp: number }>>({});\n\nconst currentMission = computed(() => {\n    if (!currentMissionId.value) return null;\n    return missionPool.find(item => item.id === currentMissionId.value) ?? null;\n});\n\n// 检查当前任务是否已完成\nconst isCurrentMissionCompleted = computed(() => {\n    if (!currentMissionId.value) return false;\n    return isMissionCompleted(currentMissionId.value);\n});\n\nconst isMissionVerified = (missionId: string) => {\n    const verification = missionVerification.value[missionId];\n    if (!verification) return false;\n    // 验证时间在5分钟内有效\n    return verification.verified && Date.now() - verification.timestamp < 5 * 60 * 1000;\n};\n\nconst persistMissionState = () => {\n    try {\n        if (typeof uni === 'undefined') return;\n        uni.setStorageSync(missionStateKey, {\n            current: currentMissionId.value,\n            completed: completedMissionIds.value,\n            verification: missionVerification.value\n        });\n    } catch (error) {\n        console.warn('persistMissionState error', error);\n    }\n};\n\nconst loadMissionState = () => {\n    try {\n        if (typeof uni === 'undefined') return;\n        const cache = uni.getStorageSync(missionStateKey);\n        if (cache) {\n            currentMissionId.value = cache.current || null;\n            completedMissionIds.value = Array.isArray(cache.completed) ? cache.completed : [];\n            missionVerification.value = cache.verification || {};\n            // 如果当前有任务，确保它被标记为已领取\n            if (currentMissionId.value) {\n                assignMission(currentMissionId.value, true);\n            }\n        }\n    } catch (error) {\n        console.warn('loadMissionState error', error);\n    }\n};\n\nconst handleAssignMission = () => {\n    const available = missionPool.filter(item => !completedMissionIds.value.includes(item.id));\n    if (!available.length) {\n        uni.showToast({ title: '当前没有更多任务，稍后再来', icon: 'none' });\n        currentMissionId.value = null;\n        persistMissionState();\n        return;\n    }\n    const mission = available[Math.floor(Math.random() * available.length)];\n    currentMissionId.value = mission.id;\n    // 调用 useExperience 中的 assignMission 方法领取任务\n    assignMission(mission.id);\n    persistMissionState();\n};\n\nconst refreshMission = () => {\n    // 如果当前有任务，先取消领取\n    if (currentMissionId.value) {\n        unassignMission(currentMissionId.value);\n    }\n    currentMissionId.value = null;\n    handleAssignMission();\n};\n\nconst verifyMission = (missionId: string) => {\n    // 检查用户是否真正完成了任务\n    const mission = missionPool.find(m => m.id === missionId);\n    if (!mission) return false;\n\n    const componentKey = mission.componentKey;\n\n    // 从 useExperienceCenter 获取组件统计数据\n    const stats = (componentStats as any)?.value || componentStats || {};\n    const componentStat = stats[componentKey];\n\n    // 检查该组件是否有交互记录（交互次数 > 0 或访问次数 > 0）\n    const hasInteraction =\n        componentStat && (componentStat.interactions > 0 || componentStat.visits > 0 || componentStat.xp > 0);\n\n    // 或者检查是否有相关的体验记录\n    const logs = getRecentLogs();\n    const hasRelatedLog = logs.some(\n        log =>\n            log.message &&\n            (log.message.includes(componentKey) ||\n                log.message.includes(mission.hint) ||\n                log.message.includes(mission.title))\n    );\n\n    return hasInteraction || hasRelatedLog;\n};\n\n// 领取积分（如果任务已完成则领取积分）\nconst handleClaimReward = () => {\n    if (!currentMission.value) return;\n\n    // 检查任务是否已完成（在 completedMissionIds 中）\n    if (isCurrentMissionCompleted.value) {\n        // 任务已完成，直接领取积分（不需要验证，因为 completeMission 已经验证过了）\n        const success = claimMissionReward(currentMission.value.id);\n        if (success) {\n            currentMissionId.value = null;\n            persistMissionState();\n            handleAssignMission();\n        }\n    } else {\n        // 如果任务未完成，先验证任务是否真正完成\n        const verified = verifyMission(currentMission.value.id);\n        if (verified) {\n            // 验证通过，说明任务已完成但可能还没调用 completeMission\n            // 先标记为完成，然后领取积分\n            const completeSuccess = completeMission(currentMission.value.id);\n            if (completeSuccess) {\n                // 任务已标记为完成，现在领取积分\n                const claimSuccess = claimMissionReward(currentMission.value.id);\n                if (claimSuccess) {\n                    currentMissionId.value = null;\n                    persistMissionState();\n                    handleAssignMission();\n                }\n            }\n        } else {\n            // 验证失败，提示用户先去完成任务\n            uni.showModal({\n                title: '任务验证失败',\n                content: `请先前往\"${currentMission.value.hint}\"完成相关操作，然后再来领取积分。`,\n                showCancel: false\n            });\n        }\n    }\n};\n\n// 验证任务完成状态（当任务未完成时点击\"完成任务\"按钮）\nconst handleCompleteMission = () => {\n    if (!currentMission.value) return;\n\n    // 首先检查任务是否已经在 completedMissionIds 中（可能刚完成但界面还没更新）\n    if (isCurrentMissionCompleted.value) {\n        // 任务已完成，直接领取积分\n        handleClaimReward();\n        return;\n    }\n\n    // 验证任务是否真正完成（通过组件统计数据验证）\n    const verified = verifyMission(currentMission.value.id);\n    if (!verified) {\n        uni.showModal({\n            title: '任务验证失败',\n            content: `请先前往\"${currentMission.value.hint}\"完成相关操作，然后再来领取积分。`,\n            showCancel: false\n        });\n        return;\n    }\n\n    // 如果验证通过，说明任务已完成，但可能还没调用 completeMission\n    // 这里可以提示用户，或者自动调用 completeMission\n    uni.showToast({ title: '任务已完成，请点击\"领取积分\"按钮', icon: 'success' });\n};\n\nloadMissionState();\nif (!currentMissionId.value) {\n    handleAssignMission();\n}\n\nconst suggests = [\n    {\n        title: '多体验几类基础组件',\n        desc: '从 Button、Cell、Avatar 等基础组件开始，熟悉常用交互模式',\n        icon: 'component-fill',\n        iconColor: $u.color.primaryDark,\n        tag: '基础组件',\n        path: '/pages/example/components'\n    },\n    {\n        title: '完成更多任务点位',\n        desc: '在各示例页中按照“任务体验”提示完成任务，更快提升体验等级',\n        icon: 'target',\n        iconColor: $u.color.successDark,\n        tag: '任务挑战',\n        path: '/pages/example/components'\n    },\n    {\n        title: '探索模板示例',\n        desc: '进入模板示例页，查看完整业务场景的组件组合用法',\n        icon: 'template-fill',\n        iconColor: $u.color.warningDark,\n        tag: '场景实践',\n        path: '/pages/example/template'\n    }\n];\n\nconst goToPath = (path: string) => {\n    if (!path) return;\n    uni.navigateTo({ url: path });\n};\n\n// 页面显示时，重新加载任务状态（因为可能在组件中完成了任务）\nonShow(() => {\n    // 重新加载已完成的任务数据\n    // 注意：这里需要从 useExperience 重新获取，但由于 completedMissionIds 是模块级别的 ref，\n    // 应该已经是响应式的，所以这里主要是触发响应式更新\n    // 如果任务已完成，界面会自动显示\"领取积分\"按钮\n});\n</script>\n\n<style lang=\"scss\" scoped>\n.experience-map {\n    padding: 24rpx;\n    display: flex;\n    flex-direction: column;\n    gap: 28rpx;\n    background: linear-gradient(180deg, rgba(41, 121, 255, 0.02) 0%, transparent 100%);\n    min-height: 100vh;\n}\n\n.hero-card {\n    position: relative;\n    padding: 32rpx 24rpx;\n    border-radius: 24rpx;\n    background: linear-gradient(135deg, rgba(41, 121, 255, 0.15), rgba(25, 190, 107, 0.15), rgba(255, 153, 0, 0.1));\n    box-shadow:\n        0 12rpx 32rpx rgba(41, 121, 255, 0.15),\n        0 4rpx 12rpx rgba(0, 0, 0, 0.08);\n    overflow: hidden;\n\n    &::before {\n        content: '';\n        position: absolute;\n        top: -50%;\n        right: -20%;\n        width: 200%;\n        height: 200%;\n        background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 0%, transparent 70%);\n        animation: heroGlow 8s ease-in-out infinite;\n    }\n}\n\n@keyframes heroGlow {\n    0%,\n    100% {\n        transform: rotate(0deg);\n        opacity: 0.3;\n    }\n    50% {\n        transform: rotate(180deg);\n        opacity: 0.6;\n    }\n}\n\n.hero-badge {\n    position: absolute;\n    // top: -20rpx;\n    right: 20rpx;\n    width: 140rpx;\n    height: 140rpx;\n    z-index: 2;\n\n    &__inner {\n        position: relative;\n        width: 100%;\n        height: 100%;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        background: linear-gradient(135deg, #ff6b6b, #ffa502, #ff6348);\n        border-radius: 50%;\n        box-shadow:\n            0 8rpx 24rpx rgba(255, 107, 107, 0.4),\n            inset 0 2rpx 8rpx rgba(255, 255, 255, 0.3);\n        transform: rotate(-15deg);\n        animation: badgePulse 2s ease-in-out infinite;\n    }\n\n    &__text {\n        font-size: 22rpx;\n        font-weight: 700;\n        color: #fff;\n        text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.3);\n        letter-spacing: 2rpx;\n        transform: rotate(15deg);\n    }\n\n    &__glow {\n        position: absolute;\n        top: 50%;\n        left: 50%;\n        transform: translate(-50%, -50%);\n        width: 120%;\n        height: 120%;\n        border-radius: 50%;\n        background: radial-gradient(circle, rgba(255, 107, 107, 0.6) 0%, transparent 70%);\n        animation: badgeGlow 2s ease-in-out infinite;\n    }\n}\n\n@keyframes badgePulse {\n    0%,\n    100% {\n        transform: rotate(-15deg) scale(1);\n    }\n    50% {\n        transform: rotate(-15deg) scale(1.05);\n    }\n}\n\n@keyframes badgeGlow {\n    0%,\n    100% {\n        opacity: 0.6;\n        transform: translate(-50%, -50%) scale(1);\n    }\n    50% {\n        opacity: 1;\n        transform: translate(-50%, -50%) scale(1.2);\n    }\n}\n.hero-title {\n    font-size: 28rpx;\n    color: rgba(96, 98, 102, 0.8);\n    font-weight: 500;\n    margin-bottom: 4rpx;\n}\n.hero-subtitle {\n    margin-top: 8rpx;\n    font-size: 42rpx;\n    font-weight: 800;\n    background: linear-gradient(135deg, #2979ff, #19be6b, #ff9900);\n    -webkit-background-clip: text;\n    -webkit-text-fill-color: transparent;\n    background-clip: text;\n    letter-spacing: 2rpx;\n}\n.hero-xp {\n    margin: 20rpx 0 24rpx;\n    display: flex;\n    flex-direction: column;\n    gap: 8rpx;\n    &__value {\n        font-size: 48rpx;\n        font-weight: 800;\n        background: linear-gradient(135deg, #f59a23, #ff6b6b);\n        -webkit-background-clip: text;\n        -webkit-text-fill-color: transparent;\n        background-clip: text;\n        text-shadow: 0 2rpx 8rpx rgba(245, 154, 35, 0.3);\n    }\n    &__hint {\n        font-size: 24rpx;\n        color: rgba(144, 147, 153, 0.9);\n        line-height: 1.5;\n    }\n}\n.hero-tags {\n    margin-top: 16rpx;\n    display: flex;\n    flex-wrap: wrap;\n    gap: 12rpx;\n}\n\n.map-steps {\n    display: flex;\n    flex-direction: column;\n    gap: 20rpx;\n}\n.map-step {\n    padding: 20rpx 16rpx;\n    border-radius: 16rpx;\n    background: linear-gradient(135deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.6));\n    border: 1px solid rgba(41, 121, 255, 0.1);\n    box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04);\n    transition: all 0.3s ease;\n\n    &:hover {\n        transform: translateY(-2rpx);\n        box-shadow: 0 8rpx 20rpx rgba(41, 121, 255, 0.12);\n    }\n\n    &__header {\n        display: flex;\n        justify-content: space-between;\n        align-items: center;\n        margin-bottom: 12rpx;\n    }\n    &__title-wrap {\n        display: flex;\n        align-items: center;\n        gap: 12rpx;\n    }\n    &__title {\n        font-size: 30rpx;\n        font-weight: 700;\n        color: #303133;\n    }\n    &__tip {\n        margin-top: 10rpx;\n        font-size: 24rpx;\n        color: rgba(144, 147, 153, 0.9);\n        line-height: 1.5;\n    }\n    &__dot {\n        width: 20rpx;\n        height: 20rpx;\n        border-radius: 50%;\n        background: #dcdfe6;\n        box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);\n        position: relative;\n\n        &::after {\n            content: '';\n            position: absolute;\n            top: 50%;\n            left: 50%;\n            transform: translate(-50%, -50%);\n            width: 60%;\n            height: 60%;\n            border-radius: 50%;\n            background: rgba(255, 255, 255, 0.8);\n        }\n\n        &--finish {\n            background: linear-gradient(135deg, #67c23a, #85ce61);\n            box-shadow: 0 2rpx 12rpx rgba(103, 194, 58, 0.4);\n        }\n        &--process {\n            background: linear-gradient(135deg, #e6a23c, #f0a020);\n            box-shadow: 0 2rpx 12rpx rgba(230, 162, 60, 0.4);\n            animation: dotPulse 2s ease-in-out infinite;\n        }\n        &--wait {\n            background: #dcdfe6;\n        }\n    }\n}\n\n@keyframes dotPulse {\n    0%,\n    100% {\n        transform: scale(1);\n        opacity: 1;\n    }\n    50% {\n        transform: scale(1.2);\n        opacity: 0.8;\n    }\n}\n\n.radar-list {\n    display: flex;\n    flex-direction: column;\n    gap: 18rpx;\n}\n.radar-item {\n    padding: 16rpx;\n    border-radius: 12rpx;\n    background: linear-gradient(135deg, rgba(41, 121, 255, 0.06), rgba(25, 190, 107, 0.06));\n    border: 1px solid rgba(41, 121, 255, 0.1);\n    transition: all 0.3s ease;\n\n    &:hover {\n        transform: translateX(4rpx);\n        box-shadow: 0 4rpx 12rpx rgba(41, 121, 255, 0.15);\n    }\n\n    &__header {\n        display: flex;\n        justify-content: space-between;\n        align-items: center;\n        margin-bottom: 10rpx;\n    }\n    &__name {\n        font-size: 28rpx;\n        font-weight: 700;\n        color: #303133;\n        letter-spacing: 1rpx;\n    }\n    &__xp {\n        font-size: 26rpx;\n        font-weight: 700;\n        background: linear-gradient(135deg, #e6a23c, #f59a23);\n        -webkit-background-clip: text;\n        -webkit-text-fill-color: transparent;\n        background-clip: text;\n    }\n    &__meta {\n        margin-top: 6rpx;\n        font-size: 22rpx;\n        color: rgba(144, 147, 153, 0.9);\n    }\n}\n.radar-empty {\n    font-size: 24rpx;\n    color: #909399;\n    text-align: center;\n    padding: 24rpx 0;\n}\n\n.log-list {\n    display: flex;\n    flex-direction: column;\n    gap: 14rpx;\n}\n.log-item {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    padding: 12rpx 16rpx;\n    border-radius: 12rpx;\n    background: rgba(41, 121, 255, 0.04);\n    font-size: 24rpx;\n    color: #606266;\n    transition: all 0.2s ease;\n\n    &:hover {\n        background: rgba(41, 121, 255, 0.08);\n        transform: translateX(4rpx);\n    }\n\n    &--placeholder {\n        opacity: 0.6;\n    }\n\n    &__main {\n        flex: 1;\n    }\n\n    &__text {\n        color: #606266;\n    }\n\n    &__time {\n        font-size: 22rpx;\n        color: rgba(192, 196, 204, 0.9);\n        margin-left: 16rpx;\n    }\n}\n.log-empty {\n    font-size: 24rpx;\n    color: #909399;\n}\n\n// .suggest-list {\n.mission-card {\n    display: flex;\n    flex-direction: column;\n    gap: 16rpx;\n    padding: 20rpx;\n    border-radius: 16rpx;\n    background: linear-gradient(135deg, rgba(255, 153, 0, 0.08), rgba(255, 107, 107, 0.08));\n    border: 1px solid rgba(255, 153, 0, 0.2);\n    box-shadow: 0 4rpx 16rpx rgba(255, 153, 0, 0.1);\n\n    &__title {\n        font-size: 32rpx;\n        font-weight: 700;\n        color: #303133;\n        letter-spacing: 1rpx;\n    }\n    &__desc {\n        font-size: 26rpx;\n        color: #606266;\n        line-height: 1.6;\n    }\n    &__meta {\n        display: flex;\n        gap: 12rpx;\n        flex-wrap: wrap;\n    }\n    &__actions {\n        margin-top: 8rpx;\n        display: flex;\n        gap: 16rpx;\n        justify-content: flex-end;\n    }\n}\n.mission-empty {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    gap: 20rpx;\n    &__text {\n        font-size: 24rpx;\n        color: #909399;\n        flex: 1;\n    }\n}\n:deep(.u-cell-item) {\n    padding-left: 0 !important;\n    padding-right: 0 !important;\n}\n// }\n</style>\n"
  },
  {
    "path": "src/pages/example/fullScreen.vue",
    "content": "<template>\n    <u-full-screen :content=\"content\"> </u-full-screen>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\n\nconst content = ref<string>(`\n  1. 修复badge组件的size参数无效问题<br>\n  2. 新增Modal模态框组件<br>\n  3. 新增压窗屏组件，可以在APP上以弹窗的形式遮盖导航栏和底部tabbar<br>\n  4. 修复键盘组件在微信小程序上遮罩无效的问题\n`);\n</script>\n"
  },
  {
    "path": "src/pages/example/js.config.ts",
    "content": "export default [\n    {\n        groupName: '网络',\n        groupName_en: 'Network',\n        icon: 'network',\n        list: [\n            {\n                path: 'http',\n                icon: 'http',\n                title: 'Http 请求',\n                title_en: 'Http',\n                desc: '统一封装的网络请求，支持拦截器和全局配置',\n                desc_en: 'Unified network request wrapper supporting interceptors and global configuration'\n            }\n        ]\n    },\n    {\n        groupName: '工具库',\n        groupName_en: 'Tool library',\n        icon: 'tools',\n        list: [\n            {\n                path: 'debounce',\n                icon: 'throttle',\n                title: 'Throttle | Debounce 节流防抖',\n                title_en: 'Throttle | Debounce',\n                desc: '高频事件优化，防止重复触发',\n                desc_en: 'Optimizes high-frequency events to prevent repeated triggers'\n            },\n            {\n                path: 'deepMerge',\n                icon: 'merge',\n                title: 'DeepMerge 对象深度合并',\n                title_en: 'DeepMerge',\n                desc: '对象深度合并，常用于配置和主题',\n                desc_en: 'Deep merge objects, commonly used for configuration and themes'\n            },\n            // #ifndef APP-HARMONY\n            {\n                path: 'deepClone',\n                icon: 'clone',\n                title: 'DeepClone 对象深度克隆',\n                title_en: 'DeepClone',\n                desc: '对象/数组深度克隆，避免引用混乱',\n                desc_en: 'Deep clone objects/arrays to avoid reference issues'\n            },\n            // #endif\n            {\n                path: 'timeFormat',\n                icon: 'time',\n                title: 'TimeFormat 时间格式化',\n                title_en: 'TimeFormat',\n                desc: '时间格式化，支持多种格式',\n                desc_en: 'Time formatting, supports multiple formats'\n            },\n            {\n                path: 'timeFrom',\n                icon: 'from',\n                title: 'TimeFrom 多久之前',\n                title_en: 'TimeFrom',\n                desc: '多久之前，友好时间显示',\n                desc_en: \"Friendly 'time ago' display\"\n            },\n            {\n                path: 'guid',\n                icon: 'id',\n                title: 'Guid 全局唯一id',\n                title_en: 'Guid',\n                desc: '全局唯一 id 生成',\n                desc_en: 'Generate globally unique IDs'\n            },\n            {\n                path: 'route',\n                icon: 'route',\n                title: 'Route 路由跳转',\n                title_en: 'Route',\n                desc: '页面路由跳转，参数传递',\n                desc_en: 'Page navigation and parameter passing'\n            },\n            {\n                path: 'randomArray',\n                icon: 'array',\n                title: 'RandomArray 数组乱序',\n                title_en: 'RandomArray',\n                desc: '数组乱序，抽奖/洗牌',\n                desc_en: 'Shuffle arrays, useful for lotteries/shuffling'\n            },\n            {\n                path: 'colorSwitch',\n                icon: 'switch',\n                title: 'ColorSwitch 颜色转换',\n                title_en: 'ColorSwitch',\n                desc: '颜色值格式转换 HEX/RGB/HSL',\n                desc_en: 'Color value format conversion between HEX/RGB/HSL'\n            },\n            {\n                path: 'color',\n                icon: 'color',\n                title: 'Color 颜色值',\n                title_en: 'Color',\n                desc: '主题色、辅助色获取',\n                desc_en: 'Retrieve theme and auxiliary colors'\n            },\n            {\n                path: 'queryParams',\n                icon: 'params',\n                title: 'QueryParams 对象转URL参数',\n                title_en: 'QueryParams',\n                desc: '对象转 URL 参数字符串',\n                desc_en: 'Convert objects to URL query strings'\n            },\n            {\n                path: 'test',\n                icon: 'test',\n                title: 'Test 规则校验',\n                title_en: 'Test',\n                desc: '表单/数据规则校验',\n                desc_en: 'Form/data validation rules'\n            },\n            {\n                path: 'md5',\n                icon: 'md5',\n                title: 'Md5 md5加密',\n                title_en: 'Md5',\n                desc: 'md5 加密/签名',\n                desc_en: 'MD5 hashing/signing'\n            },\n            {\n                path: 'random',\n                icon: 'random',\n                title: 'Random 随机数值',\n                title_en: 'Random',\n                desc: '生成随机数',\n                desc_en: 'Generate random numbers'\n            },\n            {\n                path: 'trim',\n                icon: 'trim',\n                title: 'Trim 去除空格',\n                title_en: 'Trim',\n                desc: '去除字符串空格',\n                desc_en: 'Trim whitespace from strings'\n            },\n            {\n                path: 'getRect',\n                icon: 'rect',\n                title: 'GetRect 节点信息',\n                title_en: 'GetRect',\n                desc: '获取节点尺寸/位置信息',\n                desc_en: 'Get node size and position information'\n            },\n            // #ifndef APP-HARMONY\n            {\n                path: 'mpShare',\n                icon: 'share',\n                title: 'MpShare 小程序分享',\n                title_en: 'MpShare',\n                desc: '小程序分享能力',\n                desc_en: 'Mini Program sharing capability'\n            }\n            // #endif\n        ]\n    }\n];\n"
  },
  {
    "path": "src/pages/example/js.vue",
    "content": "<template>\n    <demo-page :nav-title=\"t('nav.js')\" :nav-back=\"false\" :tabbar=\"true\">\n        <view>\n            <page-nav :desc=\"desc\" title=\"nav.js\" :index=\"1\"></page-nav>\n            <view class=\"u-p-10\">\n                <u-swiper\n                    :list=\"recommendList\"\n                    :effect3d=\"false\"\n                    autoplay\n                    mode=\"none\"\n                    :title=\"true\"\n                    @click=\"swiperClick\"\n                ></u-swiper>\n            </view>\n            <view class=\"tool-group-list\">\n                <view class=\"tool-group-card\" v-for=\"(item, index) in list\" :key=\"index\">\n                    <view class=\"tool-group-header\">\n                        <u-icon\n                            :name=\"item.icon\"\n                            custom-prefix=\"custom-icon\"\n                            :size=\"50\"\n                            :color=\"getRandomColor()\"\n                        ></u-icon>\n                        <text class=\"group-title\">{{ getTitle('groupName', item) }}</text>\n                    </view>\n                    <view class=\"tool-list\">\n                        <view class=\"tool-card\" v-for=\"tool in item.list\" :key=\"tool.name\">\n                            <u-icon\n                                custom-prefix=\"custom-icon\"\n                                :name=\"tool.icon\"\n                                :size=\"50\"\n                                :color=\"getRandomColor()\"\n                            ></u-icon>\n                            <view class=\"tool-info\">\n                                <text class=\"tool-name\">{{ getTitle('title', tool) }}</text>\n                                <text class=\"tool-desc\">{{ getTitle('desc', tool) }}</text>\n                            </view>\n                            <u-button size=\"mini\" type=\"primary\" @click=\"openPage(tool.path)\">{{\n                                t('common.tryit')\n                            }}</u-button>\n                        </view>\n                    </view>\n                </view>\n            </view>\n            <u-gap height=\"70\"></u-gap>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed } from 'vue';\nimport { useI18n } from 'vue-i18n';\nimport rawList from './js.config';\nimport { onShow } from '@dcloudio/uni-app';\nimport { useTitle } from '@/common/useHooks';\nimport { completeMission } from '@/common/useExperience';\nimport { getRandomColor } from '@/common/util';\n\nconst list = ref<any[]>(Array.isArray(rawList) ? rawList : []);\n\n// 推荐工具（可自定义）\nconst recommendList = [\n    {\n        title: '统一封装的网络请求，支持拦截器和全局配置',\n        title_en: 'Unified network request, supporting interceptors and global configuration',\n        image: getBannerImage('swiper'),\n        path: 'http'\n    }\n];\n\n// 国际化\nconst { t, locale } = useI18n();\nconst { setTitle, getTitle } = useTitle(1);\n\n// 组件描述\nconst desc = computed(() => t('js.desc'));\n\nfunction openPage(path: string) {\n    uni.navigateTo({\n        url: path.indexOf('/page') == 0 ? path : '/pages/library/' + path + '/index'\n    });\n}\n\nfunction swiperClick(index: number) {\n    openPage(recommendList[index].path);\n}\n\nfunction getBannerImage(name: string) {\n    let url = `https://ik.imagekit.io/anyup/uview-pro/swiper/${name}.png`;\n    // #ifdef APP-HARMONY\n    url = `/static/app/swiper/${name}.png`;\n    // #endif\n    return url;\n}\n\n// 设置标题\nonShow(() => {\n    setTitle();\n    completeMission('tools');\n});\n</script>\n\n<style lang=\"scss\" scoped>\n.tool-group-list {\n    padding: 0 20rpx;\n}\n\n.tool-group-card {\n    background: $u-bg-color;\n    border-radius: 12rpx;\n    margin-bottom: 32rpx;\n    box-shadow: 0 12rpx 30rpx rgba(var(--u-type-primary-rgb), 0.08);\n    padding: 24rpx 20rpx 12rpx 20rpx;\n    border: 1rpx solid $u-border-color;\n}\n\n.tool-group-header {\n    display: flex;\n    align-items: center;\n    margin-bottom: 18rpx;\n}\n\n.group-title {\n    font-size: 36rpx;\n    font-weight: 500;\n    color: $u-main-color;\n    margin-left: 10rpx;\n}\n\n.tool-card {\n    display: flex;\n    align-items: center;\n    width: 100%;\n    background: rgba(var(--u-type-primary-rgb), 0.05);\n    border-radius: 12rpx;\n    margin-bottom: 14rpx;\n    padding: 30rpx 26rpx;\n}\n\n.tool-info {\n    flex: 1;\n    display: flex;\n    flex-direction: column;\n    justify-content: center;\n    margin-left: 16rpx;\n}\n\n.tool-name {\n    font-size: 30rpx;\n    color: $u-main-color;\n    font-weight: 500;\n}\n\n.tool-desc {\n    font-size: 24rpx;\n    color: $u-content-color;\n    margin-top: 10rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/example/template.config.ts",
    "content": "export default [\n    {\n        groupName: '部件',\n        groupName_en: 'Parts',\n        list: [\n            {\n                path: 'coupon',\n                icon: 'coupon',\n                title: 'Coupon 优惠券',\n                title_en: 'Coupon',\n                desc: '卡券展示与领取，支持多种样式',\n                desc_en: 'Display and claim coupons; supports multiple styles',\n                isHot: true,\n                downloadCount: 1250,\n                rating: 4.8,\n                shareLink: 'https://uviewpro.cn/zh/layout/coupon.html',\n                codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/template/coupon/index.vue'\n            }\n        ]\n    },\n    {\n        groupName: '页面',\n        groupName_en: 'Page',\n        list: [\n            {\n                path: '/pages/template/wxCenter/index',\n                icon: 'wxCenter',\n                title: 'WxCenter 仿微信个人中心',\n                title_en: 'WxCenter',\n                desc: '用户信息、菜单、订单等个人中心页面',\n                desc_en: 'User information, menus, orders and other personal center features',\n                isHot: true,\n                isNew: false,\n                downloadCount: 3200,\n                rating: 4.9,\n                shareLink: 'https://uviewpro.cn/zh/layout/wxCenter.html',\n                codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/template/wxCenter/index.vue'\n            },\n            {\n                path: '/pages/template/keyboardPay/index',\n                icon: 'keyboardPay',\n                title: 'KeyboardPay 自定义键盘支付模板',\n                title_en: 'KeyboardPay',\n                desc: '安全支付，金额输入自定义键盘',\n                desc_en: 'Secure payments with a custom keyboard for amount input',\n                isNew: true,\n                downloadCount: 890,\n                rating: 4.6,\n                shareLink: 'https://uviewpro.cn/zh/layout/keyboardPay.html',\n                codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/template/keyboardPay/index.vue'\n            },\n            {\n                path: '/pages/template/mallMenu/index1',\n                icon: 'mallMenu',\n                title: 'MallMenu 垂直分类(左右独立)',\n                title_en: 'MallMenu 1',\n                desc: '商品多级分类，左右独立滚动',\n                desc_en: 'Multi-level product categories with independent left/right scrolling',\n                downloadCount: 2100,\n                rating: 4.7,\n                shareLink: 'https://uviewpro.cn/zh/layout/menu.html',\n                codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/template/mallMenu/index1.vue'\n            },\n            {\n                path: '/pages/template/mallMenu/index2',\n                icon: 'mallMenu',\n                title: 'MallMenu 垂直分类(左右联动)',\n                title_en: 'MallMenu 2',\n                desc: '商品多级分类，左右联动高亮',\n                desc_en: 'Multi-level product categories with linked left/right highlighting',\n                isHot: true,\n                downloadCount: 2800,\n                rating: 4.8,\n                shareLink: 'https://uviewpro.cn/zh/layout/menu.html',\n                codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/template/mallMenu/index2.vue'\n            },\n            {\n                path: 'submitBar',\n                icon: 'submitBar',\n                title: 'SubmitBar 提交订单栏',\n                title_en: 'SubmitBar',\n                desc: '下单结算栏，价格与操作按钮',\n                desc_en: 'Order checkout bar showing price and action buttons',\n                downloadCount: 1500,\n                rating: 4.5,\n                shareLink: 'https://uviewpro.cn/zh/layout/submitBar.html',\n                codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/template/submitBar/index.vue'\n            },\n            {\n                path: 'comment',\n                icon: 'comment',\n                title: 'Comment 评论列表',\n                title_en: 'Comment',\n                desc: '多级评论、点赞、回复展示',\n                desc_en: 'Display of multi-level comments, likes, and replies',\n                isHot: true,\n                downloadCount: 1900,\n                rating: 4.7,\n                shareLink: 'https://uviewpro.cn/zh/layout/comment.html',\n                codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/template/comment/index.vue'\n            },\n            {\n                path: 'order',\n                icon: 'order',\n                title: 'Order 订单列表',\n                title_en: 'Order',\n                desc: '订单状态、操作、物流信息',\n                desc_en: 'Order status, actions, and logistics information',\n                isHot: true,\n                downloadCount: 2400,\n                rating: 4.8,\n                shareLink: 'https://uviewpro.cn/zh/layout/order.html',\n                codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/template/order/index.vue'\n            },\n            {\n                path: 'login',\n                icon: 'login',\n                title: 'Login 登录界面',\n                title_en: 'Login',\n                desc: '多方式登录，验证码/密码',\n                desc_en: 'Multiple login methods: verification code or password',\n                downloadCount: 3100,\n                rating: 4.9,\n                shareLink: 'https://uviewpro.cn/zh/layout/login.html',\n                codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/template/login/index.vue'\n            },\n            {\n                path: 'address',\n                icon: 'address',\n                title: 'Address 收货地址',\n                title_en: 'Address',\n                desc: '地址管理、选择、编辑',\n                desc_en: 'Address management, selection, and editing',\n                downloadCount: 1800,\n                rating: 4.6,\n                shareLink: 'https://uviewpro.cn/zh/layout/address.html',\n                codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/template/address/index.vue'\n            },\n            {\n                path: 'citySelect',\n                icon: 'citySelect',\n                title: 'CitySelect 城市选择',\n                title_en: 'CitySelect',\n                desc: '省市区三级联动、搜索定位',\n                desc_en: 'Province-city-district three-level linkage, with search and location',\n                isNew: true,\n                downloadCount: 1200,\n                rating: 4.7,\n                shareLink: 'https://uviewpro.cn/zh/layout/citySelect.html',\n                codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/template/citySelect/index.vue'\n            }\n        ]\n    },\n    {\n        groupName: '场景',\n        groupName_en: 'Scenes',\n        list: [\n            {\n                path: '/pages/scenes/todo/index',\n                icon: 'todo',\n                title: '待办事项',\n                title_en: 'Todo',\n                desc: '任务管理，提高工作效率',\n                desc_en: 'Task management to boost productivity',\n                isHot: true,\n                downloadCount: 820,\n                rating: 4.7,\n                shareLink: 'https://uviewpro.cn/zh/scenes/todo.html',\n                codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/scenes/todo/index.vue'\n            },\n            {\n                path: '/pages/scenes/notes/index',\n                icon: 'note',\n                title: '我的笔记',\n                title_en: 'Notes',\n                desc: '记录想法，随时查看',\n                desc_en: 'Capture ideas and review anytime',\n                downloadCount: 760,\n                rating: 4.6,\n                shareLink: 'https://uviewpro.cn/zh/scenes/notes.html',\n                codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/scenes/notes/index.vue'\n            },\n            {\n                path: '/pages/scenes/dashboard/index',\n                icon: 'dashboard',\n                title: '数据统计',\n                title_en: 'Dashboard',\n                desc: '使用数据一目了然',\n                desc_en: 'Usage stats at a glance',\n                isNew: true,\n                downloadCount: 680,\n                rating: 4.5,\n                shareLink: 'https://uviewpro.cn/zh/scenes/dashboard.html',\n                codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/scenes/dashboard/index.vue'\n            },\n            {\n                path: '/pages/scenes/favorites/index',\n                icon: 'favorite',\n                title: '我的收藏',\n                title_en: 'Favorites',\n                desc: '收藏喜欢的组件',\n                desc_en: 'Bookmark your favorite components',\n                downloadCount: 540,\n                rating: 4.5,\n                shareLink: 'https://uviewpro.cn/zh/scenes/favorites.html',\n                codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/scenes/favorites/index.vue'\n            }\n        ]\n    }\n];\n"
  },
  {
    "path": "src/pages/example/template.vue",
    "content": "<template>\n    <demo-page :nav-title=\"t('nav.template')\" :nav-back=\"false\" :tabbar=\"true\">\n        <view class=\"template-market\">\n            <page-nav :desc=\"desc\" title=\"nav.template\" :index=\"2\"></page-nav>\n\n            <!-- 顶部描述 -->\n            <view class=\"market-hero\">\n                <view class=\"hero-text\">\n                    <view class=\"hero-title\">模板市场 · 一键搭建业务页面</view>\n                    <view class=\"hero-desc\">精选页面、部件与完整场景示例，支持预览、下载与导出</view>\n                </view>\n                <view class=\"hero-actions\">\n                    <u-button type=\"primary\" size=\"mini\" shape=\"circle\" @click=\"currentCategory = 1\">页面</u-button>\n                    <u-button type=\"success\" size=\"mini\" shape=\"circle\" @click=\"currentCategory = 2\">部件</u-button>\n                    <u-button type=\"warning\" size=\"mini\" shape=\"circle\" @click=\"currentCategory = 3\">场景</u-button>\n                </view>\n            </view>\n\n            <!-- 搜索栏 -->\n            <view class=\"market-search\">\n                <u-search\n                    v-model=\"searchText\"\n                    placeholder=\"搜索模板...\"\n                    :show-action=\"false\"\n                    shape=\"round\"\n                    @search=\"handleSearch\"\n                ></u-search>\n            </view>\n\n            <!-- 轮播横幅 -->\n            <view class=\"market-banner\">\n                <u-swiper\n                    :list=\"bannerList\"\n                    :effect3d=\"true\"\n                    mode=\"none\"\n                    autoplay\n                    title\n                    height=\"300\"\n                    @click=\"swiperClick\"\n                ></u-swiper>\n            </view>\n\n            <!-- 分类标签 -->\n            <view class=\"market-categories\">\n                <u-subsection\n                    :list=\"categoryOptions\"\n                    :current=\"currentCategory\"\n                    @change=\"changeCategory\"\n                    active-color=\"var(--u-type-primary)\"\n                ></u-subsection>\n            </view>\n\n            <!-- 模板列表 -->\n            <view class=\"market-content\">\n                <view v-for=\"(group, gIndex) in filteredGroups\" :key=\"gIndex\" class=\"template-group\">\n                    <view class=\"group-header\">\n                        <view class=\"group-title\">\n                            <u-icon\n                                custom-prefix=\"custom-icon\"\n                                name=\"folder\"\n                                size=\"40\"\n                                :color=\"$u.getColor('primary')\"\n                            ></u-icon>\n                            <text class=\"group-name\">{{ getGroupTitle(group) }}</text>\n                        </view>\n                        <view class=\"group-count\">{{ group.list.length }} 个模板</view>\n                    </view>\n\n                    <view class=\"template-grid\">\n                        <view\n                            v-for=\"tpl in group.list\"\n                            :key=\"tpl.path\"\n                            class=\"template-card\"\n                            @click=\"openTemplateDetail(tpl)\"\n                        >\n                            <view class=\"card-preview\">\n                                <u-image\n                                    :src=\"getPreviewImage(tpl)\"\n                                    mode=\"aspectFit\"\n                                    width=\"100%\"\n                                    height=\"200\"\n                                    :lazy-load=\"true\"\n                                ></u-image>\n                                <view class=\"card-overlay\">\n                                    <view class=\"overlay-actions\">\n                                        <u-button\n                                            type=\"primary\"\n                                            size=\"mini\"\n                                            shape=\"circle\"\n                                            @click.stop=\"openTemplate(tpl)\"\n                                        >\n                                            <u-icon name=\"eye\" size=\"32\" color=\"#fff\"></u-icon>\n                                        </u-button>\n                                        <u-button\n                                            type=\"success\"\n                                            size=\"mini\"\n                                            shape=\"circle\"\n                                            @click.stop=\"handleDownload(tpl)\"\n                                        >\n                                            <u-icon name=\"download\" size=\"32\" color=\"#fff\"></u-icon>\n                                        </u-button>\n                                    </view>\n                                </view>\n                                <view v-if=\"tpl.isHot\" class=\"card-badge hot\">热门</view>\n                                <view v-if=\"tpl.isNew\" class=\"card-badge new\">新品</view>\n                            </view>\n                            <view class=\"card-content\">\n                                <view class=\"card-title\">{{ getTitle('title', tpl) }}</view>\n                                <view class=\"card-desc\">{{ getTitle('desc', tpl) }}</view>\n                                <view class=\"card-meta\">\n                                    <view class=\"meta-item\">\n                                        <u-icon name=\"download\" size=\"28\" color=\"var(--u-tips-color)\"></u-icon>\n                                        <text>{{ tpl.downloadCount || 0 }}</text>\n                                    </view>\n                                    <view class=\"meta-item\">\n                                        <u-icon name=\"star-fill\" size=\"28\" color=\"var(--u-tips-color)\"></u-icon>\n                                        <text>{{ tpl.rating || '4.5' }}</text>\n                                    </view>\n                                </view>\n                            </view>\n                        </view>\n                    </view>\n                </view>\n\n                <!-- 空状态 -->\n                <view v-if=\"filteredGroups.length === 0\" class=\"empty-state\">\n                    <u-empty mode=\"search\" text=\"未找到相关模板\" :show-empty=\"true\"></u-empty>\n                </view>\n            </view>\n\n            <u-gap height=\"70\"></u-gap>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed } from 'vue';\nimport { useI18n } from 'vue-i18n';\nimport rawList from './template.config';\nimport { onShow } from '@dcloudio/uni-app';\nimport { useTitle } from '@/common/useHooks';\nimport { completeMission } from '@/common/useExperience';\nimport { $u } from '@/uni_modules/uview-pro';\n\nconst list = ref<any[]>(Array.isArray(rawList) ? rawList : []);\nconst searchText = ref('');\nconst currentCategory = ref(0);\nconst categoryOptions = ['全部', '页面', '部件', '场景'];\n\n// 热门模板横幅（可自定义图片和描述）\nconst bannerList = [\n    {\n        title: '支持左右联动，左右分开的分类列表',\n        image: getBannerImage('swiper1'),\n        desc: '支持左右联动，左右分开的分类列表',\n        path: '/pages/template/mallMenu/index2'\n    },\n    {\n        title: '订单列表：订单状态、操作、物流',\n        image: getBannerImage('swiper2'),\n        desc: '订单状态、操作、物流',\n        path: '/pages/template/order/index'\n    },\n    {\n        title: '快速构建收货地址',\n        image: getBannerImage('swiper3'),\n        desc: '快速构建收货地址',\n        path: '/pages/template/address/index'\n    }\n];\n\n// 获取分组标题\nfunction getGroupTitle(group: any) {\n    return group.groupName || group.groupName_en || '未分类';\n}\n\n// 筛选后的分组列表\nconst filteredGroups = computed(() => {\n    let result = list.value;\n\n    // 按分类筛选\n    if (currentCategory.value > 0) {\n        const categoryMap: Record<number, string> = {\n            1: '页面',\n            2: '部件',\n            3: '场景'\n        };\n        const targetCategory = categoryMap[currentCategory.value];\n        result = result.filter((group: any) => {\n            const groupName = group.groupName || group.groupName_en || '';\n            return groupName.includes(targetCategory);\n        });\n    }\n\n    // 按搜索关键词筛选\n    if (searchText.value) {\n        const keyword = searchText.value.toLowerCase();\n        result = result\n            .map((group: any) => {\n                const filteredList = (group.list || []).filter((tpl: any) => {\n                    const title = (getTitle('title', tpl) || '').toLowerCase();\n                    const desc = (getTitle('desc', tpl) || '').toLowerCase();\n                    return title.includes(keyword) || desc.includes(keyword);\n                });\n                return {\n                    ...group,\n                    list: filteredList\n                };\n            })\n            .filter((group: any) => group.list.length > 0);\n    }\n\n    return result;\n});\n\n// 获取预览图\nfunction getPreviewImage(tpl: any) {\n    if (tpl.previewImage) {\n        return tpl.previewImage;\n    }\n    // 使用默认预览图\n    const iconName = tpl.icon || 'template';\n    // #ifdef APP\n    return `/static/app/template/${iconName}.png`;\n    // #endif\n    return `https://ik.imagekit.io/anyup/uview-pro/template/${iconName}.png`;\n}\n\n// 国际化\nconst { t, locale } = useI18n();\nconst { getTitle, setTitle } = useTitle(2);\n\n// 组件描述\nconst desc = computed(() => t('template.desc'));\n\nfunction getBannerImage(name: string) {\n    let url = `https://ik.imagekit.io/anyup/uview-pro/swiper/${name}.png`;\n    // #ifdef APP-HARMONY\n    url = `/static/app/swiper/${name}.png`;\n    // #endif\n    return url;\n}\n\nfunction swiperClick(index: number) {\n    openPage(bannerList[index].path);\n}\n\nfunction openPage(path: string) {\n    uni.navigateTo({\n        url: path.indexOf('/page') == 0 ? path : '/pages/template/' + path + '/index'\n    });\n}\n\n// 打开模板详情\nfunction openTemplateDetail(tpl: any) {\n    const fullPath = tpl.path.indexOf('/page') == 0 ? tpl.path : '/pages/template/' + tpl.path + '/index';\n    uni.navigateTo({\n        url: `/pages/template/detail/index?path=${encodeURIComponent(fullPath)}&title=${encodeURIComponent(getTitle('title', tpl))}&desc=${encodeURIComponent(getTitle('desc', tpl) || '')}`\n    });\n}\n\nfunction openTemplate(tpl: any) {\n    const fullPath = tpl.path.indexOf('/page') == 0 ? tpl.path : '/pages/template/' + tpl.path + '/index';\n\n    uni.navigateTo({\n        url: fullPath\n    });\n}\n\n// 处理下载\nfunction handleDownload(tpl: any) {\n    const itemList = ['预览模板'];\n    if (tpl.codeLink) {\n        itemList.push('下载代码');\n    }\n    if (tpl.shareLink) {\n        itemList.push('分享模板');\n    }\n    uni.showActionSheet({\n        itemList,\n        success: res => {\n            if (res.tapIndex === 0) {\n                openPage(tpl.path);\n            } else if (res.tapIndex === 1) {\n                downloadTemplate(tpl);\n            } else if (res.tapIndex === 2) {\n                shareTemplate(tpl);\n            }\n        }\n    });\n}\n\n// 下载模板代码\nfunction downloadTemplate(tpl: any) {\n    copyCodeLink(tpl.codeLink);\n}\n\n// 导出为图片\nfunction shareTemplate(tpl: any) {\n    copyShareLink(tpl.shareLink);\n}\n\n// 复制代码链接\nfunction copyCodeLink(link: string) {\n    if (!link) return;\n\n    uni.setClipboardData({\n        data: link,\n        success: () => {\n            $u.toast('代码链接已复制', 'success');\n        }\n    });\n}\n\n// 复制分享链接\nfunction copyShareLink(link: string) {\n    if (!link) return;\n    uni.setClipboardData({\n        data: link,\n        success: () => {\n            $u.toast('分享链接已复制', 'success');\n        }\n    });\n}\n\n// 搜索处理\nfunction handleSearch() {\n    // 搜索逻辑已在computed中处理\n}\n\n// 切换分类\nfunction changeCategory(index: number) {\n    currentCategory.value = index;\n}\n\n// 设置标题\nonShow(() => {\n    setTitle();\n    completeMission('template');\n});\n</script>\n\n<style lang=\"scss\" scoped>\n.template-market {\n    min-height: 100vh;\n    background: linear-gradient(180deg, rgba(41, 121, 255, 0.02) 0%, transparent 100%);\n}\n\n.market-hero {\n    margin: 0 20rpx 20rpx;\n    padding: 24rpx 28rpx;\n    background: linear-gradient(135deg, rgba(41, 121, 255, 0.12), rgba(25, 190, 107, 0.1));\n    border-radius: 16rpx;\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    gap: 20rpx;\n    box-shadow: 0 8rpx 24rpx rgba(41, 121, 255, 0.1);\n}\n\n.hero-text {\n    display: flex;\n    flex-direction: column;\n    gap: 10rpx;\n}\n\n.hero-title {\n    font-size: 32rpx;\n    font-weight: 700;\n    color: $u-main-color;\n}\n\n.hero-desc {\n    font-size: 24rpx;\n    color: $u-content-color;\n}\n\n.hero-actions {\n    display: flex;\n    gap: 12rpx;\n    flex-shrink: 0;\n}\n\n.market-search {\n    padding: 20rpx 30rpx;\n    background: transparent;\n}\n\n.market-banner {\n    padding: 0 20rpx 24rpx;\n}\n\n.market-categories {\n    padding: 0 30rpx 24rpx;\n}\n\n.market-content {\n    padding: 0 20rpx;\n}\n\n.template-group {\n    margin-bottom: 40rpx;\n}\n\n.group-header {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    margin-bottom: 24rpx;\n    padding: 0 10rpx;\n}\n\n.group-title {\n    display: flex;\n    align-items: center;\n    gap: 12rpx;\n}\n\n.group-name {\n    font-size: 32rpx;\n    font-weight: 600;\n    color: $u-main-color;\n}\n\n.group-count {\n    font-size: 24rpx;\n    color: $u-tips-color;\n    background: rgba(41, 121, 255, 0.1);\n    padding: 8rpx 16rpx;\n    border-radius: 20rpx;\n}\n\n.template-grid {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 20rpx;\n}\n\n.template-card {\n    width: calc((100% - 20rpx) / 2);\n    background: $u-bg-color;\n    border-radius: 16rpx;\n    overflow: hidden;\n    box-shadow: 0 8rpx 24rpx rgba(41, 121, 255, 0.1);\n    transition: all 0.3s ease;\n    cursor: pointer;\n\n    &:active {\n        transform: scale(0.98);\n    }\n}\n\n.card-preview {\n    position: relative;\n    width: 100%;\n    height: 200rpx;\n    overflow: hidden;\n    background: linear-gradient(135deg, rgba(41, 121, 255, 0.1), rgba(25, 190, 107, 0.1));\n\n    .card-overlay {\n        position: absolute;\n        top: 0;\n        left: 0;\n        right: 0;\n        bottom: 0;\n        z-index: 2;\n        background: linear-gradient(180deg, rgba(0, 0, 0, 0.35), rgba(0, 0, 0, 0.6));\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        opacity: 1;\n        pointer-events: auto;\n        transition: opacity 0.25s ease;\n\n        .overlay-actions {\n            display: flex;\n            gap: 20rpx;\n        }\n    }\n\n    &:active {\n        .card-overlay {\n            opacity: 1;\n        }\n    }\n\n    .card-badge {\n        position: absolute;\n        top: 12rpx;\n        right: 12rpx;\n        padding: 6rpx 16rpx;\n        border-radius: 20rpx;\n        font-size: 20rpx;\n        font-weight: 600;\n        color: #fff;\n\n        &.hot {\n            background: linear-gradient(135deg, #ff6b6b, #ff4757);\n        }\n\n        &.new {\n            background: linear-gradient(135deg, #4facfe, #00f2fe);\n        }\n    }\n}\n\n// Hover/press 显示操作层（H5 悬停、触摸按压）\n.template-card:hover .card-overlay,\n.template-card:active .card-overlay {\n    opacity: 1;\n}\n\n.card-content {\n    padding: 20rpx;\n}\n\n.card-title {\n    font-size: 28rpx;\n    font-weight: 600;\n    color: $u-main-color;\n    margin-bottom: 8rpx;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n}\n\n.card-desc {\n    font-size: 24rpx;\n    color: $u-content-color;\n    margin-bottom: 16rpx;\n    line-height: 1.5;\n    display: -webkit-box;\n    -webkit-box-orient: vertical;\n    -webkit-line-clamp: 2;\n    line-clamp: 2;\n    overflow: hidden;\n}\n\n.card-meta {\n    display: flex;\n    gap: 24rpx;\n    align-items: center;\n}\n\n.meta-item {\n    display: flex;\n    align-items: center;\n    gap: 8rpx;\n    font-size: 22rpx;\n    color: $u-tips-color;\n}\n\n.empty-state {\n    padding: 100rpx 0;\n}\n</style>\n"
  },
  {
    "path": "src/pages/hooks/useModal/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"useModal 示例\"\n        desc=\"Modal 函数式调用 hooks，基于事件机制实现。支持应用级和页面级调用，可自定义标题、内容、按钮、回调等。\"\n        :apis=\"'useModal'\"\n    >\n        <u-modal page=\"agreement\">\n            <view class=\"u-p-40\" style=\"line-height: 60rpx\">\n                <view>1. 本服务条款是您与本公司之间就使用我们的服务达成的协议。</view>\n                <view>2. 使用我们的服务即表示您同意本条款。</view>\n                <view>3. 我们保留在必要时修改条款的权利。</view>\n                <u-checkbox v-model=\"isAgree\" label=\"我已阅读并同意本服务条款\"></u-checkbox>\n            </view>\n        </u-modal>\n        <view class=\"u-page\">\n            <!-- 基础调用 -->\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">基础调用</text>\n                <view class=\"u-demo-block__content\">\n                    <u-button text=\"基础弹窗\" type=\"primary\" @click=\"handleBasic\"></u-button>\n                </view>\n            </view>\n\n            <!-- 带标题和内容 -->\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">带标题和内容</text>\n                <view class=\"u-demo-block__content\">\n                    <u-button text=\"提示弹窗\" type=\"primary\" @click=\"handleWithTitle\"></u-button>\n                </view>\n            </view>\n\n            <!-- 确认弹窗 -->\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">确认弹窗</text>\n                <view class=\"u-demo-block__content\">\n                    <u-button text=\"删除确认\" type=\"error\" @click=\"handleConfirm\"></u-button>\n                    <u-button text=\"自定义按钮\" type=\"primary\" @click=\"handleCustomButtons\"></u-button>\n                </view>\n            </view>\n\n            <!-- 异步操作 -->\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">异步操作</text>\n                <view class=\"u-demo-block__content\">\n                    <u-button text=\"异步提交\" type=\"primary\" @click=\"handleAsync\"></u-button>\n                </view>\n            </view>\n\n            <!-- 内容类型 -->\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">内容类型</text>\n                <view class=\"u-demo-block__content\">\n                    <u-button text=\"富文本内容\" type=\"primary\" @click=\"handleRichContent\"></u-button>\n                    <u-button text=\"长内容\" type=\"primary\" @click=\"handleLongContent\"></u-button>\n                </view>\n            </view>\n\n            <!-- 圆角和样式 -->\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">圆角和样式</text>\n                <view class=\"u-demo-block__content\">\n                    <u-button text=\"大圆角\" type=\"primary\" @click=\"handleBorderRadius\"></u-button>\n                </view>\n            </view>\n\n            <!-- 事件回调 -->\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">事件回调</text>\n                <view class=\"u-demo-block__content\">\n                    <u-button text=\"回调示例\" type=\"primary\" @click=\"handleCallbacks\"></u-button>\n                </view>\n            </view>\n\n            <!-- 显示结果 -->\n            <view class=\"u-demo-block\" v-if=\"result\">\n                <text class=\"u-demo-block__title\">操作结果</text>\n                <view class=\"u-demo-block__content\">\n                    <u-text :text=\"result\" type=\"success\"></u-text>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { useToast, useModal } from 'uview-pro';\n\n// 操作结果\nconst result = ref('');\n\n// 应用级 Modal\nconst modal = useModal();\nconst pageModal = useModal({ page: 'agreement' });\n// 用于显示操作结果\nconst toast = useToast();\n// 是否同意\nconst isAgree = ref(false);\n// 基础调用\nconst handleBasic = () => {\n    modal.show('这是一条简单的消息提示');\n};\n\n// 带标题和内容\nconst handleWithTitle = () => {\n    modal.show({\n        title: '操作提示',\n        content: '确定要执行此操作吗？此操作不可撤销，请谨慎操作。',\n        confirmText: '我知道了',\n        showCancelButton: false\n    });\n};\n\n// 确认弹窗\nconst handleConfirm = () => {\n    modal.confirm({\n        title: '确认删除',\n        content: '确定要删除这条数据吗？删除后无法恢复。',\n        confirmColor: '#fa3534',\n        onConfirm: () => {\n            result.value = '已删除数据';\n            toast.success('删除成功');\n        },\n        onCancel: () => {\n            result.value = '已取消删除';\n            toast.info('已取消删除');\n        }\n    });\n};\n\n// 自定义按钮\nconst handleCustomButtons = () => {\n    modal.confirm({\n        title: '自定义操作',\n        content: '请选择以下操作之一',\n        confirmText: '同意',\n        cancelText: '拒绝',\n        confirmColor: '#19c964',\n        cancelColor: '#ff9900',\n        onConfirm: () => {\n            result.value = '您选择了同意';\n            toast.success('您选择了同意');\n        },\n        onCancel: () => {\n            result.value = '您选择了拒绝';\n            toast.warning('您选择了拒绝');\n        }\n    });\n};\n\n// 异步操作\nconst handleAsync = () => {\n    modal.confirm({\n        title: '提交确认',\n        content: '确定要提交表单吗？',\n        confirmText: '提交',\n        asyncClose: true,\n        onConfirm: async () => {\n            // 模拟异步操作\n            await new Promise(resolve => setTimeout(resolve, 2000));\n            modal.close();\n            result.value = '提交成功';\n            toast.success('提交成功');\n        },\n        onCancel: () => {\n            modal.clearLoading();\n            result.value = '已取消提交';\n            toast.info('已取消提交');\n        }\n    });\n};\n\n// 富文本内容\nconst handleRichContent = () => {\n    isAgree.value = false;\n    pageModal.show({\n        title: '使用条款',\n        confirmText: '同意并继续',\n        showCancelButton: false,\n        asyncClose: true,\n        onConfirm: () => {\n            pageModal.clearLoading();\n            if (isAgree.value) {\n                pageModal.close();\n            } else {\n                toast.warning('请先阅读并同意本服务条款');\n            }\n        }\n    });\n};\n\n// 长内容\nconst handleLongContent = () => {\n    modal.show({\n        title: '隐私政策摘要',\n        content: `我们非常重视您的隐私保护。本隐私政策说明了我们如何收集、使用、存储和保护您的个人信息。\n            1. 信息收集：我们收集您提供的个人信息，包括但不限于姓名、联系方式等。\n            2. 信息使用：您的信息将用于提供和改进我们的服务。\n            3. 信息保护：我们采用行业领先的加密技术保护您的数据安全。\n            4. 信息共享：未经您的同意，我们不会向第三方出售您的个人信息。\n        `,\n        confirmText: '知道了',\n        contentStyle: 'text-align: left;',\n        showCancelButton: false\n    });\n};\n\n// 大圆角\nconst handleBorderRadius = () => {\n    modal.show({\n        title: '自定义样式',\n        content: '这是一个使用大圆角样式的弹窗示例',\n        borderRadius: 60,\n        confirmText: '确定',\n        showCancelButton: false\n    });\n};\n\n// 事件回调\nconst handleCallbacks = () => {\n    modal.confirm({\n        title: '回调测试',\n        content: '点击按钮查看回调效果',\n        confirmText: '确定',\n        cancelText: '取消',\n        onConfirm: () => {\n            console.log('确认按钮被点击');\n            result.value = '确认回调已触发';\n            toast.show('确认回调已触发');\n        },\n        onCancel: () => {\n            console.log('取消按钮被点击');\n            result.value = '取消回调已触发';\n            toast.show('取消回调已触发');\n        }\n    });\n};\n</script>\n\n<style lang=\"scss\" scoped>\n.u-page {\n    padding-bottom: 20px;\n}\n\n.u-demo-block__content {\n    flex-direction: row;\n    flex-wrap: wrap;\n    gap: 10px;\n    padding: 10px;\n    text-align: left;\n}\n</style>\n"
  },
  {
    "path": "src/pages/hooks/useToast/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"useToast 示例\"\n        desc=\"Toast 函数式调用 hooks，基于事件机制实现。支持应用级和页面级调用，可自定义主题、图标、加载状态等。\"\n        :apis=\"'useToast'\"\n    >\n        <view class=\"u-page\">\n            <!-- 基础调用 -->\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">基础调用</text>\n                <view class=\"u-demo-block__content\">\n                    <u-button text=\"纯文本\" type=\"primary\" @click=\"handleBasic\"></u-button>\n                </view>\n            </view>\n\n            <!-- 主题类型 -->\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">主题类型</text>\n                <view class=\"u-demo-block__content\">\n                    <u-button text=\"成功\" type=\"success\" @click=\"handleSuccess\"></u-button>\n                    <u-button text=\"错误\" type=\"error\" @click=\"handleError\"></u-button>\n                    <u-button text=\"警告\" type=\"warning\" @click=\"handleWarning\"></u-button>\n                    <u-button text=\"信息\" type=\"info\" @click=\"handleInfo\"></u-button>\n                </view>\n            </view>\n\n            <!-- 加载状态 -->\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">加载状态</text>\n                <view class=\"u-demo-block__content\">\n                    <u-button text=\"成功\" type=\"success\" @click=\"handleLoading('success')\"></u-button>\n                    <u-button text=\"错误\" type=\"error\" @click=\"handleLoading('error')\"></u-button>\n                    <u-button text=\"警告\" type=\"warning\" @click=\"handleLoading('warning')\"></u-button>\n                    <u-button text=\"信息\" type=\"info\" @click=\"handleLoading('info')\"></u-button>\n                </view>\n            </view>\n\n            <!-- 位置自定义 -->\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">位置自定义</text>\n                <view class=\"u-demo-block__content\">\n                    <u-button text=\"顶部显示\" type=\"primary\" @click=\"handleTop\"></u-button>\n                    <u-button text=\"中间显示\" type=\"primary\" @click=\"handleCenter\"></u-button>\n                    <u-button text=\"底部显示\" type=\"primary\" @click=\"handleBottom\"></u-button>\n                </view>\n            </view>\n\n            <!-- 参数配置 -->\n            <view class=\"u-demo-block\">\n                <text class=\"u-demo-block__title\">参数配置</text>\n                <view class=\"u-demo-block__content\">\n                    <u-button text=\"长时显示(5秒)\" type=\"primary\" @click=\"handleLongDuration\"></u-button>\n                    <u-button text=\"不自动关闭\" type=\"primary\" @click=\"handleNoAutoClose\"></u-button>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { useToast } from 'uview-pro';\nimport type { ThemeType } from 'uview-pro/types/global';\n\n// 应用级 Toast（默认）\nconst toast = useToast();\n\n// 基础调用\nconst handleBasic = () => {\n    toast.show('这是一条提示信息');\n};\n\n// 主题类型\nconst handleSuccess = () => {\n    toast.success('操作成功');\n};\n\nconst handleError = () => {\n    toast.error('操作失败，请重试');\n};\n\nconst handleWarning = () => {\n    toast.warning('请注意，这将删除数据');\n};\n\nconst handleInfo = () => {\n    toast.info('系统正在维护中');\n};\n\n// 加载状态\nconst handleLoading = (type: ThemeType) => {\n    toast.loading({\n        title: '正在提交...',\n        duration: 3000,\n        type: type,\n        position: 'center',\n        callback: () => {\n            toast.show({\n                title: `${type}状态结束`,\n                type: type\n            });\n        }\n    });\n};\n\n// 位置自定义\nconst handleTop = () => {\n    toast.show({\n        title: '顶部显示',\n        position: 'top',\n        duration: 2000\n    });\n};\n\nconst handleCenter = () => {\n    toast.show({\n        title: '中间显示',\n        position: 'center',\n        duration: 2000\n    });\n};\n\nconst handleBottom = () => {\n    toast.show({\n        title: '底部显示',\n        position: 'bottom',\n        duration: 2000\n    });\n};\n\n// 参数配置\nconst handleLongDuration = () => {\n    toast.show({\n        title: '这是一条长时显示的消息',\n        duration: 5000\n    });\n};\n\nconst handleNoAutoClose = () => {\n    toast.show({\n        title: '需要手动关闭',\n        duration: 0\n    });\n    // 可在适当时机调用 toast.close() 关闭\n};\n</script>\n\n<style lang=\"scss\">\n.u-page {\n    padding-bottom: 20px;\n}\n\n.u-demo-block__content {\n    flex-direction: row;\n    flex-wrap: wrap;\n    gap: 10px;\n    padding: 10px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/index/index.vue",
    "content": "<template>\r\n    <view class=\"content\">\r\n        <image class=\"logo\" src=\"/static/logo.png\" />\r\n        <view class=\"text-area\">\r\n            <text class=\"title\">{{ title }}</text>\r\n        </view>\r\n    </view>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref } from 'vue';\r\nconst title = ref('Hello');\r\n</script>\r\n\r\n<style>\r\n.content {\r\n    display: flex;\r\n    flex-direction: column;\r\n    align-items: center;\r\n    justify-content: center;\r\n}\r\n\r\n.logo {\r\n    height: 200rpx;\r\n    width: 200rpx;\r\n    margin-top: 200rpx;\r\n    margin-left: auto;\r\n    margin-right: auto;\r\n    margin-bottom: 50rpx;\r\n}\r\n\r\n.text-area {\r\n    display: flex;\r\n    justify-content: center;\r\n}\r\n\r\n.title {\r\n    font-size: 36rpx;\r\n    color: #8f8f94;\r\n}\r\n</style>\r\n"
  },
  {
    "path": "src/pages/library/color/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"Color 颜色\"\n        desc=\"用于获取和展示颜色对象，包含主题色、成功、警告、错误等多种预定义颜色。\"\n        :apis=\"'colorjs'\"\n    >\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <view class=\"u-no-demo-here\" style=\"text-align: left\">\n                            此处演示为通过JS调用框架内置颜色值，此外还可以通过scss变量调用。\n                        </view>\n                        <view class=\"u-demo-result-line\" :style=\"{ color: color, backgroundColor: '#ffffff' }\">\n                            晓镜但愁云鬓改，夜吟应觉月光寒\n                        </view>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">主题</view>\n                        <u-subsection\n                            :list=\"['primary', 'success', 'error', 'warning', 'info']\"\n                            @change=\"modeChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">常用颜色</view>\n                        <u-subsection\n                            :list=\"['主要文字', '常规文字', '次要文字', '占位文字', '边框颜色']\"\n                            @change=\"colorChange\"\n                        ></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\n\nconst color = ref($u.color['primary']);\n\nfunction modeChange(index: number): void {\n    let colorName =\n        index === 0 ? 'primary' : index === 1 ? 'success' : index === 2 ? 'error' : index === 3 ? 'warning' : 'info';\n    color.value = $u.color[colorName];\n}\n\nfunction colorChange(index: number): void {\n    color.value =\n        index === 0\n            ? '#303133'\n            : index === 1\n              ? '#606266'\n              : index === 2\n                ? '#909399'\n                : index === 3\n                  ? '#c0c4cc'\n                  : '#e4e7ed';\n}\n</script>\n"
  },
  {
    "path": "src/pages/library/colorSwitch/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"ColorSwitch 色系切换\"\n        desc=\"用于切换应用主题色，支持亮色和暗黑两种模式切换。\"\n        :apis=\"'colorSwitch'\"\n    >\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <view class=\"u-demo-result-line\">\n                            {{ result }}\n                        </view>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">GRB转HEX</view>\n                        <u-subsection\n                            :list=\"['rgb(12,57,231)', 'rgb(15,148,32)', 'rgb(91,52,210)']\"\n                            @change=\"rgbToHexChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">HEX转GRB</view>\n                        <u-subsection :list=\"['#0edc8a', '#d0a73c', '#3308dd']\" @change=\"hexToRgbChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">颜色渐变(rgb(21,21,21)-rgb(56,56,56)，分10份)</view>\n                        <u-button @click=\"colorGradientChange\">执行</u-button>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\nimport { onLoad } from '@dcloudio/uni-app';\nimport { $u } from '@/uni_modules/uview-pro';\n\nconst result = ref<string>('');\n\nonLoad(() => {\n    result.value = $u.rgbToHex('rgb(12,57,231)');\n});\n\nfunction rgbToHexChange(index: number) {\n    const color = index === 0 ? 'rgb(12,57,231)' : index === 1 ? 'rgb(15,148,32)' : 'rgb(91,52,210)';\n    result.value = $u.rgbToHex(color);\n}\n\nfunction hexToRgbChange(index: number) {\n    const color = index === 0 ? '#0edc8a' : index === 1 ? '#d0a73c' : '#3308dd';\n    result.value = $u.hexToRgb(color) as string;\n}\n\nfunction colorGradientChange() {\n    result.value = JSON.stringify($u.colorGradient('rgb(21,21,21)', 'rgb(56,56,56)', 10));\n}\n</script>\n"
  },
  {
    "path": "src/pages/library/debounce/index.vue",
    "content": "<template>\n    <demo-page\n        title=\"Debounce 防抖\"\n        desc=\"用于防止函数频繁执行，延迟函数执行直到调用停止后的指定时间。\"\n        :apis=\"'debounce'\"\n    >\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <view class=\"no-mode-here\"> 选择节流或者防抖模式，点击按钮，将会执行回调并显示在下方： </view>\n                        <view class=\"u-demo-result-line\" v-if=\"result.length\">\n                            <view v-for=\"(item, index) in result\" :key=\"index\">{{ index >= 1 ? '-' : '' }}回调</view>\n                        </view>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-button\" hover-class=\"u-button--hover\" hover-stay-time=\"150\" @tap=\"btnClick\">\n                        点击触发\n                    </view>\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">模式</view>\n                        <u-subsection :list=\"['节流', '防抖']\" @change=\"modeChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">时间间隔</view>\n                        <u-subsection\n                            current=\"1\"\n                            :list=\"['500ms', '1000ms', '2000ms']\"\n                            @change=\"timeoutChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">执行时机</view>\n                        <u-subsection :list=\"['开始处', '结束处']\" @change=\"immediateChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\n\ntype ModeType = 'throttle' | 'debouncd';\n\nconst result = ref<number[]>([]);\nconst timeout = ref(1000);\nconst immediate = ref(true);\nconst mode = ref<ModeType>('throttle');\n\nfunction modeChange(index: number) {\n    mode.value = index ? 'debouncd' : 'throttle';\n}\n\nfunction timeoutChange(index: number) {\n    timeout.value = [500, 1000, 2000][index];\n}\n\nfunction immediateChange(index: number) {\n    immediate.value = !index;\n}\n\nfunction getResult() {\n    if (result.value.length >= 6) result.value = [];\n    result.value.push(0);\n}\n\nfunction btnClick() {\n    if (mode.value === 'throttle') {\n        $u.throttle(getResult, timeout.value, immediate.value);\n    } else {\n        $u.debounce(getResult, timeout.value, immediate.value);\n    }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.u-button {\n    margin-top: 50rpx;\n    margin-bottom: 50rpx;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    height: 80rpx;\n    border-radius: 6rpx;\n    border: 1px solid $u-type-primary;\n    color: $u-type-primary;\n}\n\n.u-button--hover {\n    color: #fff;\n    background-color: $u-type-primary;\n}\n\n.u-demo-result-line {\n    display: flex;\n    justify-content: center;\n}\n</style>\n"
  },
  {
    "path": "src/pages/library/deepClone/index.vue",
    "content": "<template>\n    <demo-page title=\"DeepClone 深拷贝\" desc=\"用于实现对象和数组的深度克隆，完全独立于原对象。\" :apis=\"'deepClone'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <view class=\"u-no-demo-here\"> 源对象为：\"{info: {name: 'mary'}}\" </view>\n                        <view class=\"u-demo-result-line\">\n                            {{ resultValue }}\n                        </view>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref, computed } from 'vue';\nimport { onLoad } from '@dcloudio/uni-app';\nimport { $u } from '@/uni_modules/uview-pro';\n\nconst obj = ref({\n    info: {\n        name: 'mary'\n    }\n});\nconst result = ref<typeof obj.value | null>();\n\nconst resultValue = computed(() => {\n    return result.value ? JSON.stringify(result.value) : '';\n});\n\nonLoad(() => {\n    result.value = $u.deepClone(obj.value);\n});\n</script>\n"
  },
  {
    "path": "src/pages/library/deepMerge/index.vue",
    "content": "<template>\n    <demo-page title=\"DeepMerge 深合并\" desc=\"用于实现对象的深度合并，递归合并嵌套的对象属性。\" :apis=\"'deepMerge'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <view class=\"u-no-demo-here\">\n                            源对象1为：\"{info: {name: 'mary'}}\"\n                            <view> </view>\n                            源对象2为：\"{info: {age: '22'}}\"\n                        </view>\n                        <view class=\"u-demo-result-line\">\n                            {{ reslutValue }}\n                        </view>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">模式</view>\n                        <u-subsection :list=\"['浅拷贝', '深拷贝']\" @change=\"modeChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed } from 'vue';\nimport { onLoad } from '@dcloudio/uni-app';\nimport { $u } from '@/uni_modules/uview-pro';\n\ntype InfoType = {\n    name?: string;\n    age?: string;\n};\n\ntype ObjType = {\n    info: InfoType;\n};\n\nconst obj1 = ref<ObjType>({\n    info: {\n        name: 'mary'\n    }\n});\n\nconst obj2 = ref<ObjType>({\n    info: {\n        age: '22'\n    }\n});\n\nconst obj3 = ref<ObjType>({\n    info: {\n        name: 'mary'\n    }\n});\n\nconst result = ref<ObjType | string>('');\n\nconst reslutValue = computed(() => {\n    return result.value ? JSON.stringify(result.value) : '';\n});\n\nonLoad(() => {\n    result.value = Object.assign(obj1.value, obj2.value);\n    obj1.value = $u.deepClone(obj3.value);\n});\n\nfunction modeChange(index: number) {\n    if (index === 0) {\n        result.value = Object.assign(obj1.value, obj2.value);\n        // 重新修改obj1为原来的值\n        obj1.value = $u.deepClone(obj3.value);\n    } else {\n        result.value = $u.deepMerge(obj1.value, obj2.value);\n    }\n}\n</script>\n"
  },
  {
    "path": "src/pages/library/getRect/index.vue",
    "content": "<template>\n    <demo-page title=\"GetRect 获取位置尺寸\" desc=\"用于获取DOM元素的位置和尺寸信息，支持跨平台应用。\" :apis=\"'getRect'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <view\n                            :style=\"{\n                                display: !top ? 'block' : 'none'\n                            }\"\n                        >\n                            <view class=\"rect-block-1\">第一个节点</view>\n                            <view class=\"rect-block-2\">第2个节点</view>\n                            <view class=\"u-no-demo-here\">节点信息为</view>\n                            <view class=\"u-demo-result-line\">{{ resultValue }}</view>\n                        </view>\n                        <view class=\"jump-to-top\">\n                            <u-button\n                                @click=\"scrollToTop\"\n                                :style=\"{\n                                    display: top ? 'block' : 'none'\n                                }\"\n                            >\n                                点我自动滚动到顶部\n                            </u-button>\n                        </view>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\">参数配置</view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">元素</view>\n                        <u-subsection :list=\"['第一个节点', '第2个节点']\" @change=\"elChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">指定元素置顶</view>\n                        <u-subsection current=\"1\" :list=\"['是', '否']\" @change=\"topChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\nimport { getCurrentInstance, onMounted } from 'vue';\nimport { onPageScroll } from '@dcloudio/uni-app';\n\nconst instance = getCurrentInstance();\nconst result = ref('');\nconst scrollTop = ref(0);\nconst top = ref(false);\n\nconst resultValue = computed(() => {\n    return JSON.stringify(result.value);\n});\n\nonPageScroll((e: { scrollTop: number }) => {\n    scrollTop.value = e.scrollTop;\n});\n\nasync function elChange(index: number) {\n    const el = index === 0 ? '.rect-block-1' : '.rect-block-2';\n    result.value = await $u.getRect(el, instance);\n}\n\nfunction scrollToTop() {\n    $u.getRect('.jump-to-top', instance).then((res: any) => {\n        uni.pageScrollTo({\n            scrollTop: scrollTop.value + res.top,\n            duration: 0\n        });\n    });\n}\n\nfunction topChange(index: number) {\n    top.value = index === 0;\n    if (index === 1) {\n        uni.pageScrollTo({\n            scrollTop: 0,\n            duration: 0\n        });\n    }\n}\n\nonMounted(() => {\n    elChange(0);\n});\n</script>\n\n<style lang=\"scss\" scoped>\n.u-demo {\n    min-height: 200vh;\n}\n\n.rect-block-1 {\n    background-color: #a0cfff;\n    padding: 26rpx 60rpx;\n    color: #ffffff;\n    display: inline-flex;\n    margin: auto;\n}\n\n.rect-block-2 {\n    background-color: #fcbd71;\n    padding: 12rpx 8rpx;\n    width: 60%;\n    color: #ffffff;\n    margin: 30rpx auto;\n}\n</style>\n"
  },
  {
    "path": "src/pages/library/guid/index.vue",
    "content": "<template>\n    <demo-page title=\"Guid 唯一值\" desc=\"用于生成全局唯一标识符GUID，每次生成都不相同。\" :apis=\"'guid'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <view class=\"u-demo-result-line\">\n                            {{ result }}\n                        </view>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">长度</view>\n                        <u-subsection\n                            current=\"2\"\n                            :list=\"['10', '16', '32', 'rfc4122标准']\"\n                            @change=\"lengthChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">首字符为\"u\"</view>\n                        <u-subsection :list=\"['是', '否']\" @change=\"firstUChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">取值基数(进制)</view>\n                        <u-subsection\n                            current=\"3\"\n                            :list=\"['二', '八', '十', '六十二']\"\n                            @change=\"radixChange\"\n                        ></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { onLoad } from '@dcloudio/uni-app';\nimport { $u } from '@/uni_modules/uview-pro';\n\nconst length = ref(32);\nconst firstU = ref(true);\nconst radix = ref(62);\nconst result = ref(null);\n\nonLoad(() => {\n    getResult();\n});\n\nfunction lengthChange(index: number) {\n    length.value = index === 0 ? 10 : index === 1 ? 16 : index === 2 ? 32 : null;\n    getResult();\n}\n\nfunction firstUChange(index: number) {\n    firstU.value = index === 0;\n    getResult();\n}\n\nfunction radixChange(index: number) {\n    radix.value = index === 0 ? 2 : index === 1 ? 8 : index === 2 ? 10 : 62;\n    getResult();\n}\n\nfunction getResult() {\n    result.value = $u.guid(length.value, firstU.value, radix.value);\n}\n</script>\n"
  },
  {
    "path": "src/pages/library/http/index.vue",
    "content": "<template>\n    <demo-page\n        ref=\"demoPageRef\"\n        title=\"HTTP 请求\"\n        desc=\"用于发送HTTP请求，支持GET、POST等多种方法和拦截器。\"\n        :apis=\"'http'\"\n    >\n        <template #default>\n            <view class=\"u-demo\">\n                <!-- HTTP 简介 -->\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-area\">\n                        <view class=\"http-intro\">\n                            <image class=\"http-logo\" :src=\"getImageUrl('uni-http')\" mode=\"aspectFit\"></image>\n                            <view class=\"http-desc\">\n                                <text class=\"http-desc-text\">\n                                    uni-app 轻量级 Http 请求库，支持 TypeScript、Vue3、组合式\n                                    API，插件化、全局配置、请求/响应拦截器、toast/loading\n                                    灵活控制，开箱即用，适合中小型项目。\n                                </text>\n                            </view>\n                        </view>\n                    </view>\n                </view>\n\n                <!-- 核心特性 -->\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">核心特性</view>\n                    <view class=\"u-demo-area\">\n                        <view class=\"features-list\">\n                            <view class=\"feature-item\" v-for=\"(feature, index) in features\" :key=\"index\">\n                                <u-icon name=\"checkmark-circle-fill\" color=\"var(--u-type-success)\" size=\"32\"></u-icon>\n                                <text class=\"feature-text\">{{ feature }}</text>\n                            </view>\n                        </view>\n                    </view>\n                </view>\n\n                <!-- 请求演示 -->\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">请求演示</view>\n                    <view class=\"u-demo-area\">\n                        <view class=\"request-demo\">\n                            <view class=\"request-method\">\n                                <u-tag :text=\"currentMethod.toUpperCase()\" :type=\"getMethodType(currentMethod)\"></u-tag>\n                                <text class=\"request-url\">{{ requestUrl }}</text>\n                            </view>\n                            <view class=\"request-params\" v-if=\"requestParams\">\n                                <view class=\"params-title\">请求参数：</view>\n                                <view class=\"params-content\">{{ JSON.stringify(requestParams, null, 2) }}</view>\n                            </view>\n                            <view class=\"request-result\">\n                                <view class=\"result-title\">请求结果：</view>\n                                <view class=\"result-content\">\n                                    <view class=\"u-demo-result-line\">{{ resultText }}</view>\n                                </view>\n                            </view>\n                            <view class=\"request-status\" v-if=\"requestStatus\">\n                                <u-tag\n                                    :text=\"requestStatus\"\n                                    :type=\"requestStatus === '请求成功' ? 'success' : 'error'\"\n                                ></u-tag>\n                            </view>\n                        </view>\n                    </view>\n                </view>\n\n                <!-- 模拟请求 -->\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">模拟请求</view>\n                    <view class=\"u-demo-area\">\n                        <view class=\"mock-request\">\n                            <view class=\"mock-buttons\">\n                                <u-button type=\"primary\" size=\"mini\" @click=\"doGet()\">GET 请求</u-button>\n                                <u-button type=\"success\" size=\"mini\" @click=\"doPost()\">POST 请求</u-button>\n                                <u-button type=\"warning\" size=\"mini\" @click=\"doPut()\">PUT 请求</u-button>\n                                <u-button type=\"error\" size=\"mini\" @click=\"doDelete()\">DELETE 请求</u-button>\n                            </view>\n                        </view>\n                    </view>\n                </view>\n\n                <!-- 参数配置 -->\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\">参数配置</view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">请求方式</view>\n                        <u-subsection :list=\"['get', 'post', 'put', 'delete']\" @change=\"changeMethod\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">请求 Loading</view>\n                        <u-subsection :list=\"['隐藏', '显示']\" @change=\"changeLoading\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">请求错误时显示 Toast</view>\n                        <u-subsection :list=\"['显示', '隐藏']\" @change=\"changeToast\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">自定义 Header</view>\n                        <u-subsection :list=\"['是', '否']\" @change=\"changeHeader\"></u-subsection>\n                    </view>\n                </view>\n\n                <!-- 相关链接 -->\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">相关链接</view>\n                    <view class=\"u-demo-area\">\n                        <view class=\"links-list\">\n                            <u-cell-group :border=\"false\">\n                                <u-cell-item\n                                    title=\"查看文档\"\n                                    :arrow=\"true\"\n                                    @click=\"openDoc\"\n                                    :label=\"'了解 HTTP 请求库的完整用法'\"\n                                >\n                                    <template #icon>\n                                        <u-icon name=\"file-text\" size=\"40\" color=\"var(--u-type-primary)\"></u-icon>\n                                    </template>\n                                </u-cell-item>\n                                <u-cell-item\n                                    title=\"平台兼容性\"\n                                    :arrow=\"false\"\n                                    :label=\"'支持 App、H5、微信小程序、支付宝小程序等'\"\n                                >\n                                    <template #icon>\n                                        <u-icon\n                                            name=\"checkmark-circle\"\n                                            size=\"40\"\n                                            color=\"var(--u-type-success)\"\n                                        ></u-icon>\n                                    </template>\n                                </u-cell-item>\n                            </u-cell-group>\n                        </view>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { $u } from '@/uni_modules/uview-pro';\nimport { onMounted, ref, computed } from 'vue';\n\ninterface Result {\n    code: number;\n    msg: string;\n    data: any;\n}\n\n// 核心特性列表\nconst features = [\n    '支持 get/post/put/delete 四种常用请求',\n    '插件化注册，支持全局配置和拦截器',\n    'toast、loading 可全局/单次请求灵活配置',\n    '拦截器支持 token 注入、统一错误处理',\n    'TypeScript 类型友好，支持组合式 API',\n    '适配 H5、App、各主流小程序平台'\n];\n\n// 请求结果\nconst result = ref<any>({});\nconst loading = ref(false);\nconst toast = ref(true);\nconst customHeader = ref(false);\nconst currentMethod = ref<'get' | 'post' | 'put' | 'delete'>('get');\nconst requestUrl = ref('/api/demo.json');\nconst requestParams = ref<any>(null);\nconst requestStatus = ref('');\nconst demoPageRef = ref();\n\n// 格式化结果文本\nconst resultText = computed(() => {\n    if (!result.value || Object.keys(result.value).length === 0) {\n        return '暂无请求结果';\n    }\n    return JSON.stringify(result.value, null, 2);\n});\n\n// 获取图片地址\nfunction getImageUrl(name: string, force: boolean = false) {\n    let url = `https://ik.imagekit.io/anyup/images/social/${name}.png`;\n    // #ifdef APP-HARMONY\n    url = `/static/app/${name}.png`;\n    // #endif\n    // #ifndef APP-HARMONY\n    if (force) {\n        url = `${url}?updatedAt=${new Date().getTime()}`;\n    }\n    // #endif\n    return url;\n}\n\nasync function getNetworkType() {\n    return new Promise((resolve, reject) => {\n        uni.getNetworkType({\n            success: res => {\n                if (res.networkType == 'none') {\n                    resolve(res.networkType);\n                } else {\n                    reject(false);\n                }\n            }\n        });\n    });\n}\n\n// 获取请求方法类型\nfunction getMethodType(method: string): 'primary' | 'success' | 'warning' | 'error' {\n    const typeMap: Record<string, 'primary' | 'success' | 'warning' | 'error'> = {\n        get: 'primary',\n        post: 'success',\n        put: 'warning',\n        delete: 'error'\n    };\n    return typeMap[method] || 'primary';\n}\n\n// get请求\nfunction doGet(url = '/api/demo.json') {\n    currentMethod.value = 'get';\n    requestUrl.value = url;\n    requestParams.value = {\n        timestamp: Date.now()\n    };\n    requestStatus.value = '';\n\n    const options: any = { meta: { loading: loading.value, toast: toast.value } };\n    if (customHeader.value) {\n        options.header = { Authorization: 'Bearer token123', 'X-Custom-Header': 'custom-value' };\n    }\n\n    $u.http\n        .get<Result>(url, requestParams.value, options)\n        .then((res: Result) => {\n            if (res.code === 200) {\n                requestStatus.value = '请求成功';\n                setTimeout(() => {\n                    $u.toast('请求成功', 'success');\n                }, 1000);\n            }\n            result.value = res;\n        })\n        .catch((err: any) => {\n            requestStatus.value = '请求失败';\n            result.value = { error: err.message || '请求失败' };\n        });\n}\n\n// post请求\nfunction doPost(url = '/api/demo.json') {\n    currentMethod.value = 'post';\n    requestUrl.value = url;\n    requestParams.value = { name: 'uview-pro', version: '1.0.0', timestamp: Date.now() };\n    requestStatus.value = '';\n\n    const options: any = { meta: { loading: loading.value, toast: toast.value } };\n    if (customHeader.value) {\n        options.header = { Authorization: 'Bearer token123', 'X-Custom-Header': 'custom-value' };\n    }\n\n    $u.http\n        .post<Result>(url, requestParams.value, options)\n        .then((res: Result) => {\n            if (res.code === 200) {\n                requestStatus.value = '请求成功';\n                setTimeout(() => {\n                    $u.toast('请求成功', 'success');\n                }, 1000);\n            }\n            result.value = res;\n        })\n        .catch((err: any) => {\n            requestStatus.value = '请求失败';\n            result.value = { error: err.message || '请求失败' };\n        });\n}\n\n// put请求\nfunction doPut(url = '/api/demo.json') {\n    currentMethod.value = 'put';\n    requestUrl.value = url;\n    requestParams.value = { id: 1, name: 'updated-name' };\n    requestStatus.value = '';\n\n    const options: any = { meta: { loading: loading.value, toast: toast.value } };\n    if (customHeader.value) {\n        options.header = { Authorization: 'Bearer token123', 'X-Custom-Header': 'custom-value' };\n    }\n\n    $u.http\n        .put<Result>(url, requestParams.value, options)\n        .then((res: Result) => {\n            if (res.code === 200) {\n                requestStatus.value = '请求成功';\n                setTimeout(() => {\n                    $u.toast('请求成功', 'success');\n                }, 1000);\n            }\n            result.value = res;\n        })\n        .catch((err: any) => {\n            requestStatus.value = '请求失败';\n            result.value = { error: err.message || '请求失败' };\n        });\n}\n\n// delete请求\nfunction doDelete(url = '/api/demo.json') {\n    currentMethod.value = 'delete';\n    requestUrl.value = url;\n    requestParams.value = null;\n    requestStatus.value = '';\n\n    const options: any = { meta: { loading: loading.value, toast: toast.value } };\n    if (customHeader.value) {\n        options.header = { Authorization: 'Bearer token123', 'X-Custom-Header': 'custom-value' };\n    }\n\n    $u.http\n        .delete<Result>(url, {}, options)\n        .then((res: Result) => {\n            if (res.code === 200) {\n                requestStatus.value = '请求成功';\n                setTimeout(() => {\n                    $u.toast('请求成功', 'success');\n                }, 1000);\n            }\n            result.value = res;\n        })\n        .catch((err: any) => {\n            requestStatus.value = '请求失败';\n            result.value = { error: err.message || '请求失败' };\n        });\n}\n\n// 切换请求方式\nfunction changeMethod(index: number) {\n    const methods: Array<'get' | 'post' | 'put' | 'delete'> = ['get', 'post', 'put', 'delete'];\n    const method = methods[index];\n    currentMethod.value = method;\n\n    switch (method) {\n        case 'get':\n            doGet();\n            break;\n        case 'post':\n            doPost();\n            break;\n        case 'put':\n            doPut();\n            break;\n        case 'delete':\n            doDelete();\n            break;\n    }\n}\n\n// 切换模式，切换请求 Loading 的显示与隐藏\nfunction changeLoading(index: number) {\n    loading.value = index === 0;\n    doGet();\n}\n\n// 切换模式，切换请求错误时 Toast 的显示与隐藏\nfunction changeToast(index: number) {\n    toast.value = index === 0;\n    doGet(toast.value ? '/api/demo1.json' : '/api/demo.json');\n}\n\n// 切换自定义 Header\nfunction changeHeader(index: number) {\n    customHeader.value = index === 0;\n    doGet();\n}\n\n// 打开文档\nfunction openDoc() {\n    demoPageRef.value.changeTab(2);\n}\n\nonMounted(() => {});\n</script>\n\n<style lang=\"scss\" scoped>\n.http-intro {\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    padding: 40rpx 20rpx;\n    background: linear-gradient(135deg, rgba(41, 121, 255, 0.05), rgba(25, 190, 107, 0.05));\n    border-radius: 16rpx;\n}\n\n.http-logo {\n    width: 400rpx;\n    height: 200rpx;\n    margin-bottom: 30rpx;\n}\n\n.http-desc {\n    text-align: center;\n    padding: 0 20rpx;\n}\n\n.http-desc-text {\n    font-size: 28rpx;\n    line-height: 1.8;\n    color: #606266;\n}\n\n.features-list {\n    display: flex;\n    flex-direction: column;\n    gap: 20rpx;\n    padding: 20rpx 0;\n}\n\n.feature-item {\n    display: flex;\n    align-items: center;\n    gap: 16rpx;\n    padding: 16rpx;\n    background: rgba(41, 121, 255, 0.03);\n    border-radius: 12rpx;\n    border-left: 4rpx solid var(--u-type-primary);\n}\n\n.feature-text {\n    font-size: 28rpx;\n    color: #303133;\n    flex: 1;\n}\n\n.request-demo {\n    display: flex;\n    flex-direction: column;\n    gap: 24rpx;\n    padding: 20rpx;\n    background: #f8f9fa;\n    border-radius: 12rpx;\n}\n\n.request-method {\n    display: flex;\n    align-items: center;\n    gap: 16rpx;\n    padding: 16rpx;\n    background: #fff;\n    border-radius: 8rpx;\n}\n\n.request-url {\n    font-size: 28rpx;\n    color: #606266;\n    font-family: 'Courier New', monospace;\n}\n\n.request-params {\n    padding: 16rpx;\n    background: #fff;\n    border-radius: 8rpx;\n}\n\n.params-title {\n    font-size: 26rpx;\n    color: #909399;\n    margin-bottom: 12rpx;\n}\n\n.params-content {\n    font-size: 24rpx;\n    color: #303133;\n    font-family: 'Courier New', monospace;\n    white-space: pre-wrap;\n    word-break: break-all;\n}\n\n.request-result {\n    padding: 16rpx;\n    background: #fff;\n    border-radius: 8rpx;\n}\n\n.result-title {\n    font-size: 26rpx;\n    color: #909399;\n    margin-bottom: 12rpx;\n}\n\n.result-content {\n    max-height: 400rpx;\n    overflow-y: auto;\n}\n\n.request-status {\n    display: flex;\n    justify-content: center;\n    padding: 12rpx;\n}\n\n.mock-request {\n    padding: 20rpx 0;\n}\n\n.mock-buttons {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 20rpx;\n    justify-content: center;\n}\n\n.links-list {\n    padding: 20rpx 0;\n}\n\n:deep(.u-cell-item) {\n    padding: 24rpx 0;\n}\n</style>\n"
  },
  {
    "path": "src/pages/library/md5/index.vue",
    "content": "<template>\n    <demo-page title=\"Md5 MD5加密\" desc=\"用于对字符串进行MD5加密，生成不可逆的128位哈希值。\" :apis=\"'md5'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <view class=\"u-demo-result-line\">\n                            {{ result }}\n                        </view>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">源字符串</view>\n                        <u-subsection :list=\"['Take me', 'to', 'your heart']\" @change=\"getResult\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { onLoad } from '@dcloudio/uni-app';\nimport md5Libs from '@/uni_modules/uview-pro/libs/function/md5';\n\nconst result = ref(null);\nconst string = ref('Take me');\n\nonLoad(() => {\n    getResult();\n});\n\nfunction getResult(index?: number) {\n    if (index !== undefined) {\n        string.value = index === 0 ? 'Take me' : index === 1 ? 'to' : 'your heart';\n    }\n    result.value = md5Libs.md5(string.value);\n}\n</script>\n"
  },
  {
    "path": "src/pages/library/mpShare/index.vue",
    "content": "<template>\n    <demo-page title=\"MpShare 小程序分享\" desc=\"用于小程序的分享功能，支持分享到朋友圈、群聊等。\" :apis=\"'mpShare'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <view class=\"u-no-demo-here\"> 只对各家小程序有效，点击右上角的\"胶囊\"，即可弹出分享菜单 </view>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { onShareAppMessage } from '@dcloudio/uni-app';\n\nonShareAppMessage(res => {\n    return {\n        title: 'uView Pro - 组件示例',\n        path: '/pages/example/components'\n    };\n});\n</script>\n"
  },
  {
    "path": "src/pages/library/queryParams/index.vue",
    "content": "<template>\n    <demo-page title=\"QueryParams URL参数\" desc=\"用于解析和操作URL查询参数，支持参数提取和拼接。\" :apis=\"'queryParams'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <view class=\"u-no-demo-here\">源对象：{{ JSON.stringify(params) }}</view>\n                        <view class=\"u-demo-result-line\">\n                            {{ result }}\n                        </view>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">是否带问号</view>\n                        <u-subsection :list=\"['是', '否']\" @change=\"prefixChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { onLoad } from '@dcloudio/uni-app';\nimport { $u } from '@/uni_modules/uview-pro';\n\ninterface ParamsType {\n    name: string;\n    age: number;\n}\n\nconst prefix = ref(true);\nconst params = ref<ParamsType>({\n    name: '典韦',\n    age: 32\n});\nconst result = ref('');\n\nonLoad(() => {\n    getResult();\n});\n\nfunction prefixChange(index: number) {\n    prefix.value = index === 0;\n    getResult();\n}\n\nasync function getResult(): Promise<void> {\n    result.value = $u.queryParams(params.value, prefix.value);\n}\n</script>\n"
  },
  {
    "path": "src/pages/library/random/index.vue",
    "content": "<template>\n    <demo-page title=\"Random 随机数\" desc=\"用于生成指定范围内的随机数或随机小数。\" :apis=\"'random'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <view class=\"u-demo-result-line\">\n                            {{ result }}\n                        </view>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">操作</view>\n                        <u-subsection\n                            :list=\"['min=0, max=5', 'min=541, max=8164']\"\n                            @change=\"paramsChange\"\n                        ></u-subsection>\n                        <view class=\"u-btn-wrap\">\n                            <u-button @click=\"getResult\">执行</u-button>\n                        </view>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\nimport { onLoad } from '@dcloudio/uni-app';\nimport { $u } from '@/uni_modules/uview-pro';\n\nconst min = ref<number>(0);\nconst max = ref<number>(5);\nconst result = ref<string | number>('');\n\nonLoad(() => {\n    getResult();\n});\n\n/**\n * 参数变更处理\n * @param index 选择的索引\n */\nfunction paramsChange(index: number) {\n    if (index === 0) {\n        min.value = 0;\n        max.value = 5;\n    } else {\n        min.value = 541;\n        max.value = 8164;\n    }\n    getResult();\n}\n\n/**\n * 获取随机结果\n */\nfunction getResult() {\n    result.value = $u.random(min.value, max.value);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.u-btn-wrap {\n    margin-top: 50rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/library/randomArray/index.vue",
    "content": "<template>\n    <demo-page title=\"RandomArray 随机数组\" desc=\"用于从数组中随机选取指定数量的元素，不重复。\" :apis=\"'randomArray'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <view class=\"u-no-demo-here\"> 源数组为：[1, 2, 3, 4, 5] </view>\n                        <view class=\"u-demo-result-line\">\n                            {{ `[${result.join(', ')}]` }}\n                        </view>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">操作</view>\n                        <u-button @click=\"getResult\">执行</u-button>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\nimport { onLoad } from '@dcloudio/uni-app';\nimport { $u } from '@/uni_modules/uview-pro';\n\nconst orginArray = ref([1, 2, 3, 4, 5]);\nconst result = ref<number[]>([]);\n\nonLoad(() => {\n    getResult();\n});\n\n/**\n * 获取随机排序后的数组\n */\nfunction getResult() {\n    result.value = $u.randomArray(orginArray.value);\n}\n</script>\n"
  },
  {
    "path": "src/pages/library/route/index.vue",
    "content": "<template>\n    <demo-page title=\"Route 路由\" desc=\"用于页面路由导航，支持参数传递和页面返回。\" :apis=\"'route'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-button @click=\"openPage\">点击跳转</u-button>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">类型</view>\n                        <u-subsection\n                            :list=\"['navigateTo', 'switchTab', 'navigateBack']\"\n                            @change=\"typeChange\"\n                        ></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">携带参数(针对type=navigateTo)</view>\n                        <u-subsection :list=\"['是', '否']\" @change=\"paramsChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">窗口动画(App且type=navigateTo||navigateBack时有效)</view>\n                        <u-subsection :list=\"['是', '否']\" @change=\"animateChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { computed, ref } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\n\ntype RouteType = 'to' | 'tab' | 'back';\ntype AnimationType = string;\ninterface Params {\n    age?: number;\n    name?: string;\n    [key: string]: any;\n}\n\nconst type = ref<RouteType>('to');\nconst params = ref<Params>({\n    age: 22,\n    name: '李商隐'\n});\nconst animate = ref<AnimationType>('slide-in-bottom');\nconst url = ref<string>('');\n\nconst jumpUrl = computed(() => {\n    let url = '';\n    if (type.value === 'to') {\n        url = '/pages/library/route/routeTo';\n    } else if (type.value === 'tab') {\n        url = '/pages/example/about';\n    }\n    return url;\n});\n\n/**\n * 打开页面\n */\nfunction openPage() {\n    $u.route({\n        type: type.value,\n        params: params.value,\n        url: jumpUrl.value,\n        animationType: animate.value\n    });\n}\n\n/**\n * 类型变更处理\n * @param index 选择的索引\n */\nfunction typeChange(index: number): void {\n    type.value = index === 0 ? 'to' : index === 1 ? 'tab' : 'back';\n}\n\n/**\n * 参数变更处理\n * @param index 选择的索引\n */\nfunction paramsChange(index: number): void {\n    if (!index) {\n        params.value = {\n            age: 22,\n            name: '李商隐'\n        };\n    } else {\n        params.value = {};\n    }\n}\n\n/**\n * 动画变更处理\n * @param index 选择的索引\n */\nfunction animateChange(index: number): void {\n    animate.value = index === 0 ? 'slide-in-bottom' : '';\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.wrap {\n    padding: 24rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/library/route/routeTo.vue",
    "content": "<template>\n    <demo-page hide-tabs nav-title=\"路由测试\">\n        <view class=\"u-demo\">\n            <view class=\"u-demo-wrap\">\n                <view class=\"u-demo-title\">演示效果</view>\n                <view class=\"u-demo-area\">\n                    <view class=\"u-no-demo-here\"> 收到的参数为：{{ paramsStr }} </view>\n                    <view class=\"u-btn-wrap\">\n                        <u-button @click=\"back\">返回</u-button>\n                    </view>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref, computed } from 'vue';\nimport { onLoad } from '@dcloudio/uni-app';\nimport { $u } from '@/uni_modules/uview-pro';\n\nconst params = ref<Record<string, any>>({});\n\nconst paramsStr = computed(() => {\n    return JSON.stringify(params.value);\n});\n\nonLoad((option: Record<string, any>) => {\n    params.value = option;\n});\n\n/**\n * 返回上一页\n */\nfunction back() {\n    $u.route({\n        type: 'back',\n        animationType: 'slide-in-top'\n    });\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.wrap {\n    padding: 24rpx;\n}\n\n.u-btn-wrap {\n    margin-top: 50rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/library/test/index.vue",
    "content": "<template>\n    <demo-page title=\"Test 规则校验\" desc=\"用于测试和验证工具库的各种函数功能。\" :apis=\"'test'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-toast ref=\"uToastRef\"></u-toast>\n                        <view class=\"u-no-demo-here\" style=\"text-align: left\">\n                            这里仅对部分验证规则进行演示，目前总的验证规则有如下：\n                        </view>\n                        <u-table style=\"margin-top: 20rpx\">\n                            <u-tr>\n                                <u-td>邮箱号</u-td>\n                                <u-td>手机号</u-td>\n                                <u-td>URL</u-td>\n                                <u-td>普通日期</u-td>\n                            </u-tr>\n                            <u-tr>\n                                <u-td>十进制数</u-td>\n                                <u-td>身份证号</u-td>\n                                <u-td>车牌号</u-td>\n                                <u-td>金额</u-td>\n                            </u-tr>\n                            <u-tr>\n                                <u-td>汉字</u-td>\n                                <u-td>字母</u-td>\n                                <u-td>字母|数字</u-td>\n                                <u-td>包含值</u-td>\n                            </u-tr>\n                            <u-tr>\n                                <u-td>数值范围</u-td>\n                                <u-td>长度范围</u-td>\n                                <u-td width=\"50%\"></u-td>\n                            </u-tr>\n                        </u-table>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">邮箱</view>\n                        <u-subsection :list=\"email\" @change=\"emailChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">手机号</view>\n                        <u-subsection :list=\"mobile\" @change=\"mobileChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">中文</view>\n                        <u-subsection :list=\"chinese\" @change=\"chineseChange\"></u-subsection>\n                    </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">整数</view>\n                        <u-subsection :list=\"digits\" @change=\"digitsChange\"></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\n\nconst uToastRef = ref();\n\nconst email = ref(['google@gmail.com', 'google艾特gmail.com']);\nconst mobile = ref(['13478561273', '0778-3423082']);\nconst chinese = ref(['天青色等烟雨', 'Beat it']);\nconst digits = ref(['283', '下雨的声音']);\n\n/**\n * 显示提示信息\n * @param type 验证结果\n */\nfunction toast(type: boolean): void {\n    uToastRef.value.show({\n        type: type ? 'success' : 'error',\n        title: type ? '验证通过' : '验证失败'\n    });\n}\n\n/**\n * 邮箱验证\n * @param index 选择的索引\n */\nfunction emailChange(index: number): void {\n    toast($u.test.email(email.value[index]));\n}\n\n/**\n * 手机号验证\n * @param index 选择的索引\n */\nfunction mobileChange(index: number): void {\n    toast($u.test.mobile(mobile.value[index]));\n}\n\n/**\n * 中文验证\n * @param index 选择的索引\n */\nfunction chineseChange(index: number): void {\n    toast($u.test.chinese(chinese.value[index]));\n}\n\n/**\n * 整数验证\n * @param index 选择的索引\n */\nfunction digitsChange(index: number): void {\n    toast($u.test.digits(digits.value[index]));\n}\n</script>\n"
  },
  {
    "path": "src/pages/library/timeFormat/index.vue",
    "content": "<template>\n    <demo-page title=\"TimeFormat 时间格式化\" desc=\"用于将时间戳格式化为指定格式的时间字符串。\" :apis=\"'timeFormat'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <view class=\"u-no-demo-here\">输入时间：{{ timestamp }}</view>\n                        <view class=\"u-demo-result-line\">\n                            {{ result }}\n                        </view>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">格式</view>\n                        <u-subsection :list=\"['yyyy-mm-dd', 'yyyy年-mm月-dd日']\" @change=\"format1Change\"></u-subsection>\n                        <view style=\"margin-top: 50rpx\">\n                            <u-subsection :list=\"['mm-dd', 'yyyy-mm-dd hh:MM']\" @change=\"format2Change\"></u-subsection>\n                        </view>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\nimport { onLoad } from '@dcloudio/uni-app';\nimport { $u } from '@/uni_modules/uview-pro';\n\n// 响应式状态\nconst timestamp = ref<string>('2020-11-02T02:59:24.732Z');\nconst result = ref<string | null>(null);\n\n/**\n * 根据格式获取格式化后的时间\n * @param format 时间格式\n */\nfunction getResult(format: string) {\n    result.value = $u.timeFormat(timestamp.value, format);\n}\n\n/**\n * 第一个格式选择器变更事件\n * @param index 选择的索引\n */\nfunction format1Change(index: number) {\n    const format = index === 0 ? 'yyyy-mm-dd' : 'yyyy年-mm月-dd日';\n    getResult(format);\n}\n\n/**\n * 第二个格式选择器变更事件\n * @param index 选择的索引\n */\nfunction format2Change(index: number) {\n    const format = index === 0 ? 'mm-dd' : 'yyyy-mm-dd hh:MM';\n    getResult(format);\n}\n\nonLoad(() => {\n    // 本时间格式化方法，也支持模板中过滤器形式写法，如\n    // {{1585926095536 | date('yyyy-mm-dd')}} 或者 {{1585926095536 | date}}，因为'yyyy-mm-dd'为默认的参数\n    getResult('yyyy-mm-dd');\n});\n</script>\n"
  },
  {
    "path": "src/pages/library/timeFrom/index.vue",
    "content": "<template>\n    <demo-page title=\"TimeFrom 时间转换\" desc=\"用于将时间戳转换为相对时间，如几分钟前、几小时前等。\" :apis=\"'timeFrom'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <u-toast ref=\"uToastRef\"></u-toast>\n                        <view class=\"u-no-demo-here\" style=\"text-align: left\">\n                            根据当前时间，返回类似\"刚刚，5分钟前，8小时前，3天前\"等字样\n                        </view>\n                        <view class=\"u-demo-result-line\">\n                            {{ result }}\n                        </view>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">时间</view>\n                        <u-subsection :list=\"timeArr1\" @change=\"timeArr1Change\"></u-subsection>\n                        <u-gap></u-gap>\n                        <u-subsection\n                            style=\"margin-top: 40rpx\"\n                            :list=\"timeArr2\"\n                            @change=\"timeArr2Change\"\n                        ></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\nimport { onLoad } from '@dcloudio/uni-app';\nimport { $u } from '@/uni_modules/uview-pro';\n\nconst uToastRef = ref();\n\n// 微信小程序无法动态修改u-subsection的list参数，导致onLoad中赋值timeArr1，timeArr2无效，故在初始化时直接赋值\nconst nowTime = Number(+new Date());\nconst threeDayAgo = nowTime - 2 * 86400000;\n\n// 初始化时间数组\nconst arr1: string[] = [0, 0].map(() => {\n    return $u.timeFormat($u.random(threeDayAgo, nowTime), 'yyyy/mm/dd hh:MM:ss');\n});\n\nconst arr2: string[] = [0, 0].map(() => {\n    return $u.timeFormat($u.random(threeDayAgo, nowTime), 'yyyy/mm/dd hh:MM:ss');\n});\n\nconst timeArr1 = ref(arr1);\nconst timeArr2 = ref(arr2);\nconst result = ref<string | null>(null);\n\n/**\n * 第一个时间数组变更事件\n * @param index 选择的索引\n */\nfunction timeArr1Change(index: number) {\n    result.value = $u.timeFrom(new Date(timeArr1.value[index]).getTime());\n}\n\n/**\n * 第二个时间数组变更事件\n * @param index 选择的索引\n */\nfunction timeArr2Change(index: number) {\n    result.value = $u.timeFrom(new Date(timeArr2.value[index]).getTime());\n}\n\nonLoad(() => {\n    timeArr1Change(0);\n});\n</script>\n"
  },
  {
    "path": "src/pages/library/trim/index.vue",
    "content": "<template>\n    <demo-page title=\"Trim 字符串裁剪\" desc=\"用于移除字符串两端的空格、特定字符或多种空白字符。\" :apis=\"'trim'\">\n        <template #default>\n            <view class=\"u-demo\">\n                <view class=\"u-demo-wrap\">\n                    <view class=\"u-demo-title\">演示效果</view>\n                    <view class=\"u-demo-area\">\n                        <view class=\"u-no-demo-here\"> 源字符串：{{ `\"${string}\"` }} </view>\n                        <view class=\"u-demo-result-line\">\n                            {{ `\"${result}\"` }}\n                        </view>\n                    </view>\n                </view>\n                <view class=\"u-config-wrap\">\n                    <view class=\"u-config-title u-border-bottom\"> 参数配置 </view>\n                    <view class=\"u-config-item\">\n                        <view class=\"u-item-title\">模式选择</view>\n                        <u-subsection\n                            :list=\"['左空格', '全部空格', '两边空格', '右空格']\"\n                            @change=\"modeChange\"\n                        ></u-subsection>\n                    </view>\n                </view>\n            </view>\n        </template>\n    </demo-page>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref } from 'vue';\nimport { onLoad } from '@dcloudio/uni-app';\nimport { $u } from '@/uni_modules/uview-pro';\n\ntype TrimPosition = 'left' | 'all' | 'both' | 'right';\n\nconst string = ref('  我用十年  青春，赴你  最后之约  ');\nconst result = ref('');\nconst pos = ref<TrimPosition>('left');\n\n// 可能在 paramsChange 中使用的变量\nconst min = ref<number>(0);\nconst max = ref<number>(5);\n\n/**\n * 获取处理结果\n */\nfunction getResult() {\n    result.value = $u.trim(string.value, pos.value);\n}\n\n/**\n * 参数变更事件\n * @param index 选择的索引\n */\nfunction paramsChange(index: number) {\n    if (index === 0) {\n        min.value = 0;\n        max.value = 5;\n    } else {\n        min.value = 541;\n        max.value = 8164;\n    }\n    getResult();\n}\n\n/**\n * 模式变更事件\n * @param index 选择的索引\n */\nfunction modeChange(index: number) {\n    pos.value = index === 0 ? 'left' : index === 1 ? 'all' : index === 2 ? 'both' : 'right';\n    getResult();\n}\n\nonLoad(() => {\n    getResult();\n});\n</script>\n"
  },
  {
    "path": "src/pages/other/locale/index.vue",
    "content": "<script setup lang=\"ts\">\nimport { ref, computed, onMounted } from 'vue';\nimport { useLocale } from 'uview-pro';\nimport { useI18n } from 'vue-i18n';\n\n// ========== useLocale Hook 使用示例 ==========\nconst { currentLocale, locales, t: uT, initLocales, setLocale, getLocales } = useLocale();\n\n// vue-i18n\nconst { t, locale } = useI18n();\n\nconst currentLocaleName = computed(() => currentLocale.value?.name || '未初始化');\nconst vueLocale = computed(() => locale.value || '');\n\nfunction switchLang(vueLoc: any) {\n    // 切换 vue-i18n\n    locale.value = vueLoc.locale;\n    try {\n        if (typeof uni !== 'undefined' && typeof uni.setLocale === 'function') {\n            uni.setLocale(vueLoc.locale);\n            uni.setStorageSync('UNI_LOCALE', vueLoc.locale);\n        }\n    } catch (e) {\n        // ignore\n    }\n    // 同步 uView-Pro\n    setLocale(vueLoc.name);\n}\n\n// 初始化示例：如果没有 locale，则注入自定义 en-US 覆盖示例\nonMounted(() => {\n    if (!getLocales().length) {\n        initLocales(undefined, undefined);\n    }\n});\n\nfunction demoAddFrench() {\n    const fr = {\n        name: 'fr-FR',\n        label: '法语',\n        locale: 'fr-FR',\n        empty: { search: 'Aucun résultat de recherche' },\n        common: { intro: 'Bonjour depuis vue-i18n' }\n    };\n    initLocales([fr]);\n    setLocale('fr-FR');\n}\n</script>\n\n<template>\n    <demo-page nav-title=\"国际化示例\" hideTabs>\n        <view class=\"locale-page\">\n            <view class=\"header\">\n                <text class=\"title\">国际化（i18n）与组件库同步</text>\n                <text class=\"subtitle\">演示如何同时切换 vue-i18n 与 uView-Pro 的语言包</text>\n            </view>\n\n            <view class=\"info-card\">\n                <view class=\"info-row\">\n                    <text class=\"label\">vue-i18n 文案：</text>\n                    <text class=\"value\">{{ t('common.intro') }}</text>\n                </view>\n                <view class=\"info-row\">\n                    <text class=\"label\">uView-pro 文案(uEmpty.search)：</text>\n                    <text class=\"value\">{{ uT('uEmpty.search') }}</text>\n                </view>\n                <view class=\"info-row\">\n                    <text class=\"label\">vue-i18n 当前 locale：</text>\n                    <text class=\"value\">{{ vueLocale }}</text>\n                </view>\n                <view class=\"info-row\">\n                    <text class=\"label\">uView-pro 当前 locale：</text>\n                    <text class=\"value\">{{ currentLocaleName }}</text>\n                </view>\n            </view>\n            <view class=\"panel\">\n                <view class=\"panel-header\">\n                    <text class=\"panel-title\">以Empty组件为例，点击切换查看效果</text>\n                </view>\n                <view class=\"panel-content\">\n                    <u-empty mode=\"search\"></u-empty>\n                </view>\n            </view>\n            <view class=\"panel\">\n                <view class=\"panel-header\">\n                    <text class=\"panel-title\">切换示例</text>\n                </view>\n                <view class=\"panel-content\">\n                    <view class=\"button-row\">\n                        <u-button v-for=\"loc in locales\" :key=\"loc.name\" type=\"primary\" @click=\"switchLang(loc)\">\n                            切换到{{ loc.label }}\n                        </u-button>\n                        <u-button v-if=\"false\" @click=\"demoAddFrench\">Add French (fr-FR)</u-button>\n                    </view>\n                </view>\n            </view>\n\n            <view class=\"example-section\">\n                <text class=\"section-title\">示例代码</text>\n                <view class=\"code-block\">\n                    <text class=\"code-text\"\n                        >// 在main.ts中初始化uViewPro，添加新语言包 \\napp.use(uViewPro, { \\n locale: { \\n locales:\n                        [frFR], // 添加法语语言包 \\n defaultLocale: 'fr-FR' // 设置默认语言为法语 \\n } \\n}) \\n\\n//\n                        在页面中切换语言 \\nimport { useI18n } from 'vue-i18n'; \\nimport { useLocale } from 'uview-pro';\n                        \\nconst { locale } = useI18n(); \\nconst { setLocale } = useLocale(); \\n// 切换 vue-i18n 并同步到\n                        uView-Pro \\nlocale.value = 'en' \\nsetLocale('en-US')\n                    </text>\n                </view>\n            </view>\n            <u-link href=\"https://uviewpro.cn/zh/guide/i18n.html\">更多内容请参考国际化文档：https://uviewpro.cn</u-link>\n        </view>\n    </demo-page>\n</template>\n\n<style lang=\"scss\" scoped>\n.locale-page {\n    padding: 18px;\n    background: $u-bg-white;\n    color: $u-main-color;\n    min-height: 100vh;\n    box-sizing: border-box;\n}\n.header {\n    margin: 8px 0 18px;\n    text-align: center;\n}\n.title {\n    font-size: 20px;\n    font-weight: 700;\n    color: $u-type-primary;\n    display: block;\n    margin-bottom: 6px;\n}\n.subtitle {\n    font-size: 13px;\n    color: $u-content-color;\n}\n.info-card {\n    background: rgba(var(--u-border-color-rgb), 0.04);\n    border: 1px solid rgba(var(--u-border-color-rgb), 0.08);\n    border-radius: 10px;\n    padding: 14px;\n    margin-bottom: 18px;\n    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.03);\n}\n.info-row {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    padding: 10px 6px;\n    border-bottom: 1px dashed rgba(var(--u-border-color-rgb), 0.06);\n}\n.info-row:last-child {\n    border-bottom: none;\n}\n.label {\n    color: $u-type-primary;\n    flex: 0 0 55%;\n    font-weight: 600;\n}\n.value {\n    color: $u-main-color;\n    flex: 1 1 40%;\n    text-align: right;\n}\n.panel {\n    margin-bottom: 18px;\n}\n.button-row {\n    display: flex;\n    gap: 10px;\n    flex-wrap: wrap;\n}\n\n.example-section {\n    margin: 24px 0;\n}\n\n.section-title {\n    font-size: 16px;\n    font-weight: 600;\n    color: $u-type-primary;\n    margin-bottom: 12px;\n    display: block;\n}\n\n.code-block {\n    background: rgba(var(--u-border-color-rgb), 0.2);\n    border: 1px solid rgba(var(--u-border-color-rgb), 0.6);\n    border-radius: 6px;\n    padding: 12px;\n    overflow-x: auto;\n}\n\n.code-text {\n    font-family: 'Courier New', monospace;\n    font-size: 12px;\n    color: $u-main-color;\n    white-space: pre-wrap;\n    word-break: break-word;\n}\n\n.panel {\n    background: $u-bg-color;\n    border: 1px solid rgba(var(--u-border-color-rgb), 0.6);\n    border-radius: 8px;\n    margin-bottom: 16px;\n    overflow: hidden;\n}\n\n.panel-header {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    padding: 16px;\n    background: rgba(var(--u-border-color-rgb), 0.2);\n    cursor: pointer;\n    user-select: none;\n\n    &:active {\n        background: rgba(var(--u-border-color-rgb), 0.35);\n    }\n}\n\n.panel-title {\n    font-weight: 600;\n    font-size: 16px;\n    color: $u-main-color;\n}\n\n.toggle-icon {\n    color: $u-tips-color;\n    font-size: 12px;\n}\n\n.panel-content {\n    padding: 16px;\n    border-top: 1px solid $u-border-color;\n}\n</style>\n"
  },
  {
    "path": "src/pages/other/theme/index.vue",
    "content": "<script setup lang=\"ts\">\nimport type { DarkMode } from 'uview-pro/types/global';\nimport { useTheme, $u } from 'uview-pro';\nimport { ref, computed, onMounted } from 'vue';\n\n// ========== useTheme Hook 使用示例 ==========\nconst {\n    currentTheme, // 当前主题（响应式）\n    themes, // 所有主题列表（响应式）\n    darkMode, // 当前暗黑模式设置（响应式）\n    setTheme, // 切换主题\n    getDarkMode, // 获取暗黑模式设置\n    setDarkMode, // 设置暗黑模式\n    isInDarkMode, // 检查是否处于暗黑模式\n    toggleDarkMode, // 切换暗黑模式\n    getAvailableThemes, // 获取所有主题\n    initTheme // 初始化主题系统\n} = useTheme();\n\n// 本地状态\nconst showThemePanel = ref(false);\nconst showDarkModePanel = ref(false);\n\n// 计算属性\nconst darkModeLabel = computed(() => {\n    const mode = darkMode.value;\n    if (mode === 'auto') return '自动（跟随系统）';\n    if (mode === 'dark') return '暗黑模式';\n    return '亮色模式';\n});\n\nconst isDarkModeActive = computed(() => isInDarkMode());\n\n// 初始化示例主题（如果还未初始化）\nonMounted(() => {\n    if (!getAvailableThemes().length) {\n        initTheme(\n            [\n                {\n                    name: 'green',\n                    label: '绿色',\n                    description: '自然绿色主题',\n                    color: {\n                        primary: '#19be6b'\n                    }\n                },\n                {\n                    name: 'purple',\n                    label: '紫色',\n                    description: '优雅紫色主题',\n                    color: {\n                        primary: '#9c27b0'\n                    }\n                }\n            ],\n            'blue'\n        );\n    }\n});\n\n// 事件处理\nconst handleThemeChange = (themeName: string) => {\n    setTheme(themeName);\n    // showThemePanel.value = false;\n};\n\nconst handleDarkModeChange = (mode: DarkMode) => {\n    setDarkMode(mode);\n    // showDarkModePanel.value = false;\n};\n</script>\n\n<template>\n    <demo-page nav-title=\"主题管理\" hideTabs>\n        <view class=\"theme-selector-example\">\n            <!-- 标题 -->\n            <view class=\"header\">\n                <text class=\"title\">主题管理</text>\n                <text class=\"subtitle\">useTheme() Hook 完整演示</text>\n            </view>\n\n            <!-- 当前主题信息展示 -->\n            <view class=\"info-card\">\n                <view class=\"info-row\">\n                    <text class=\"label\">当前主题：</text>\n                    <text class=\"value\">{{ currentTheme?.label || currentTheme?.name || '未初始化' }}</text>\n                </view>\n                <view class=\"info-row\">\n                    <text class=\"label\">暗黑模式：</text>\n                    <text class=\"value\">{{ darkModeLabel }}</text>\n                </view>\n                <view class=\"info-row\">\n                    <text class=\"label\">实际模式：</text>\n                    <text class=\"value\" :style=\"{ color: isDarkModeActive ? '#666' : '#333' }\">\n                        {{ isDarkModeActive ? '暗黑模式' : '亮色模式' }}\n                    </text>\n                </view>\n                <view class=\"info-row\">\n                    <text class=\"label\">可用主题数：</text>\n                    <text class=\"value\">{{ themes.length }}</text>\n                </view>\n            </view>\n\n            <!-- 主题切换面板 -->\n            <view class=\"panel\">\n                <view class=\"panel-header\" @click=\"showThemePanel = !showThemePanel\">\n                    <text class=\"panel-title\">主题选择</text>\n                    <text class=\"toggle-icon\">{{ showThemePanel ? '▼' : '▶' }}</text>\n                </view>\n                <view v-if=\"showThemePanel\" class=\"panel-content\">\n                    <view class=\"theme-grid\">\n                        <view\n                            v-for=\"theme in themes\"\n                            :key=\"theme.name\"\n                            class=\"theme-item\"\n                            :class=\"{ active: currentTheme?.name === theme.name }\"\n                            @click=\"handleThemeChange(theme.name)\"\n                        >\n                            <view\n                                class=\"theme-color\"\n                                :style=\"{\n                                    backgroundColor: theme.color.primary\n                                }\"\n                            ></view>\n                            <text class=\"theme-name\">{{ theme.label || theme.name }}</text>\n                            <text class=\"theme-desc\">{{ theme.description || theme.name }}</text>\n                        </view>\n                    </view>\n                </view>\n            </view>\n\n            <!-- 暗黑模式面板 -->\n            <view class=\"panel\">\n                <view class=\"panel-header\" @click=\"showDarkModePanel = !showDarkModePanel\">\n                    <text class=\"panel-title\">暗黑模式</text>\n                    <text class=\"toggle-icon\">{{ showDarkModePanel ? '▼' : '▶' }}</text>\n                </view>\n                <view v-if=\"showDarkModePanel\" class=\"panel-content\">\n                    <view class=\"dark-mode-grid\">\n                        <view\n                            class=\"mode-item\"\n                            :class=\"{ active: darkMode === 'auto' }\"\n                            @click=\"handleDarkModeChange('auto')\"\n                        >\n                            <text class=\"mode-icon\">🔄</text>\n                            <text class=\"mode-name\">自动</text>\n                            <text class=\"mode-desc\">跟随系统设置</text>\n                        </view>\n                        <view\n                            class=\"mode-item\"\n                            :class=\"{ active: darkMode === 'light' }\"\n                            @click=\"handleDarkModeChange('light')\"\n                        >\n                            <text class=\"mode-icon\">☀️</text>\n                            <text class=\"mode-name\">亮色</text>\n                            <text class=\"mode-desc\">强制亮色模式</text>\n                        </view>\n                        <view\n                            class=\"mode-item\"\n                            :class=\"{ active: darkMode === 'dark' }\"\n                            @click=\"handleDarkModeChange('dark')\"\n                        >\n                            <text class=\"mode-icon\">🌙</text>\n                            <text class=\"mode-name\">暗黑</text>\n                            <text class=\"mode-desc\">强制暗黑模式</text>\n                        </view>\n                    </view>\n                    <view class=\"action-buttons\">\n                        <button class=\"quick-toggle\" @click=\"toggleDarkMode\">快速切换暗黑模式</button>\n                    </view>\n                </view>\n            </view>\n\n            <!-- 使用示例 -->\n            <view class=\"example-section\">\n                <text class=\"section-title\">使用示例代码</text>\n                <view class=\"code-block\">\n                    <text class=\"code-text\">\n                        // 初始化主题 \\nconst { initTheme, setTheme, setDarkMode, isInDarkMode, useTheme } = useTheme()\n                        \\ninitTheme(themes, 'purple') \\n// 切换主题 \\nsetTheme('green') \\n// 管理暗黑模式\n                        \\nsetDarkMode('dark') // 强制暗黑 \\nsetDarkMode('light') // 强制亮色 \\nsetDarkMode('auto') //\n                        跟随系统 \\n// 检查状态 \\nif (isInDarkMode()) { \\nconsole.log('当前处于暗黑模式') \\n}\n                    </text>\n                </view>\n            </view>\n\n            <!-- 颜色演示 -->\n            <view class=\"color-demo\">\n                <text class=\"section-title\">主题颜色演示</text>\n                <view class=\"color-grid\">\n                    <view class=\"color-item\">\n                        <view class=\"color-box\" :style=\"{ backgroundColor: $u.getColor('primary') }\">\n                            {{ $u.getColor('primary') }}\n                        </view>\n                        <text>primary</text>\n                    </view>\n                    <view class=\"color-item\">\n                        <view class=\"color-box\" :style=\"{ backgroundColor: $u.getColor('success') }\">\n                            {{ $u.getColor('success') }}\n                        </view>\n                        <text>success</text>\n                    </view>\n                    <view class=\"color-item\">\n                        <view class=\"color-box\" :style=\"{ backgroundColor: $u.getColor('error') }\">\n                            {{ $u.getColor('error') }}\n                        </view>\n                        <text>error</text>\n                    </view>\n                    <view class=\"color-item\">\n                        <view class=\"color-box\" :style=\"{ backgroundColor: $u.getColor('warning') }\">\n                            {{ $u.getColor('warning') }}\n                        </view>\n                        <text>warning</text>\n                    </view>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<style lang=\"scss\" scoped>\n.theme-selector-example {\n    padding: 20px;\n    background: $u-bg-color;\n    color: $u-main-color;\n    min-height: 100vh;\n}\n\n.header {\n    margin-bottom: 30px;\n    text-align: center;\n}\n\n.title {\n    font-size: 28px;\n    font-weight: bold;\n    color: $u-type-primary;\n    display: block;\n    margin-bottom: 8px;\n}\n\n.subtitle {\n    font-size: 14px;\n    color: $u-content-color;\n}\n\n.info-card {\n    background: rgba(var(--u-type-primary-rgb), 0.05);\n    border: 1px solid rgba(var(--u-type-primary-rgb), 0.2);\n    border-radius: 8px;\n    padding: 16px;\n    margin-bottom: 24px;\n}\n\n.info-row {\n    display: flex;\n    justify-content: space-between;\n    margin-bottom: 12px;\n\n    &:last-child {\n        margin-bottom: 0;\n    }\n}\n\n.label {\n    font-weight: 600;\n    color: $u-type-primary;\n}\n\n.value {\n    color: $u-main-color;\n    font-weight: 500;\n}\n\n.panel {\n    background: $u-bg-color;\n    border: 1px solid rgba(var(--u-border-color-rgb), 0.6);\n    border-radius: 8px;\n    margin-bottom: 16px;\n    overflow: hidden;\n}\n\n.panel-header {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    padding: 16px;\n    background: rgba(var(--u-border-color-rgb), 0.2);\n    cursor: pointer;\n    user-select: none;\n\n    &:active {\n        background: rgba(var(--u-border-color-rgb), 0.35);\n    }\n}\n\n.panel-title {\n    font-weight: 600;\n    font-size: 16px;\n    color: $u-main-color;\n}\n\n.toggle-icon {\n    color: $u-tips-color;\n    font-size: 12px;\n}\n\n.panel-content {\n    padding: 16px;\n    border-top: 1px solid $u-border-color;\n}\n\n.theme-grid {\n    display: grid;\n    grid-template-columns: 1fr 1fr;\n    gap: 12px;\n}\n\n.theme-item {\n    text-align: center;\n    padding: 12px;\n    border: 2px solid rgba(var(--u-border-color-rgb), 0.8);\n    border-radius: 8px;\n    cursor: pointer;\n    transition: all 0.3s ease;\n\n    &:active {\n        transform: scale(0.95);\n    }\n\n    &.active {\n        border-color: $u-type-primary;\n        background: rgba(var(--u-type-primary-rgb), 0.08);\n    }\n}\n\n.theme-color {\n    width: 40px;\n    height: 40px;\n    margin: 0 auto 8px;\n    border-radius: 50%;\n    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n}\n\n.theme-name {\n    display: block;\n    font-weight: 600;\n    margin-bottom: 4px;\n    color: $u-main-color;\n}\n\n.theme-desc {\n    display: block;\n    font-size: 12px;\n    color: $u-tips-color;\n}\n\n.dark-mode-grid {\n    display: grid;\n    grid-template-columns: 1fr 1fr 1fr;\n    gap: 12px;\n    margin-bottom: 16px;\n}\n\n.mode-item {\n    text-align: center;\n    padding: 16px 12px;\n    border: 2px solid rgba(var(--u-border-color-rgb), 0.8);\n    border-radius: 8px;\n    cursor: pointer;\n    transition: all 0.3s ease;\n\n    &:active {\n        transform: scale(0.95);\n    }\n\n    &.active {\n        border-color: $u-type-primary;\n        background: rgba(var(--u-type-primary-rgb), 0.08);\n    }\n}\n\n.mode-icon {\n    display: block;\n    font-size: 32px;\n    margin-bottom: 8px;\n}\n\n.mode-name {\n    display: block;\n    font-weight: 600;\n    color: $u-main-color;\n    margin-bottom: 4px;\n}\n\n.mode-desc {\n    display: block;\n    font-size: 12px;\n    color: $u-tips-color;\n}\n\n.action-buttons {\n    display: flex;\n    gap: 12px;\n}\n\n.quick-toggle {\n    flex: 1;\n    padding: 12px;\n    background: $u-type-primary;\n    color: white;\n    border: none;\n    border-radius: 6px;\n    font-weight: 600;\n    cursor: pointer;\n    transition: all 0.3s ease;\n\n    &:active {\n        opacity: 0.8;\n    }\n}\n\n.example-section {\n    margin: 24px 0;\n}\n\n.section-title {\n    font-size: 16px;\n    font-weight: 600;\n    color: $u-type-primary;\n    margin-bottom: 12px;\n    display: block;\n}\n\n.code-block {\n    background: rgba(var(--u-border-color-rgb), 0.2);\n    border: 1px solid rgba(var(--u-border-color-rgb), 0.6);\n    border-radius: 6px;\n    padding: 12px;\n    overflow-x: auto;\n}\n\n.code-text {\n    font-family: 'Courier New', monospace;\n    font-size: 12px;\n    color: $u-main-color;\n    line-height: 1.6;\n    white-space: pre-wrap;\n    word-break: break-all;\n}\n\n.color-demo {\n    margin-bottom: 30px;\n}\n\n.color-grid {\n    display: grid;\n    grid-template-columns: 1fr 1fr 1fr 1fr;\n    gap: 12px;\n}\n\n.color-item {\n    text-align: center;\n}\n\n.color-box {\n    width: 100%;\n    height: 60px;\n    border-radius: 6px;\n    margin-bottom: 8px;\n    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    font-size: 12px;\n    color: #ffffff;\n}\n\n.color-item text {\n    font-size: 12px;\n    color: $u-tips-color;\n}\n</style>\n"
  },
  {
    "path": "src/pages/scenes/dashboard/index.vue",
    "content": "<template>\n    <demo-page hide-tabs title=\"数据统计\" desc=\"统计你的使用情况，了解你的使用习惯。\" :nav-back=\"true\">\n        <view class=\"dashboard-container\">\n            <!-- 概览卡片 -->\n            <view class=\"overview-card\">\n                <view class=\"overview-title\">使用概览</view>\n                <view class=\"overview-stats\">\n                    <view class=\"stat-box\">\n                        <view class=\"stat-value\">{{ totalVisits }}</view>\n                        <view class=\"stat-label\">总访问次数</view>\n                    </view>\n                    <view class=\"stat-box\">\n                        <view class=\"stat-value\">{{ totalComponents }}</view>\n                        <view class=\"stat-label\">体验组件数</view>\n                    </view>\n                    <view class=\"stat-box\">\n                        <view class=\"stat-value\">{{ totalXP }}</view>\n                        <view class=\"stat-label\">累计体验值</view>\n                    </view>\n                </view>\n            </view>\n\n            <!-- 使用时长统计 -->\n            <u-card title=\"使用时长统计\" :border=\"false\">\n                <template #body>\n                    <view class=\"time-stats\">\n                        <view class=\"time-item\">\n                            <view class=\"time-label\">今日使用</view>\n                            <view class=\"time-value\">{{ formatTime(todayTime) }}</view>\n                        </view>\n                        <view class=\"time-item\">\n                            <view class=\"time-label\">本周使用</view>\n                            <view class=\"time-value\">{{ formatTime(weekTime) }}</view>\n                        </view>\n                        <view class=\"time-item\">\n                            <view class=\"time-label\">本月使用</view>\n                            <view class=\"time-value\">{{ formatTime(monthTime) }}</view>\n                        </view>\n                    </view>\n                </template>\n            </u-card>\n\n            <!-- 组件使用排行 -->\n            <u-card title=\"组件使用排行\" :border=\"false\">\n                <template #body>\n                    <view class=\"ranking-list\">\n                        <view v-for=\"(item, index) in topComponents\" :key=\"item.key\" class=\"ranking-item\">\n                            <view class=\"ranking-index\" :class=\"getRankClass(index)\">\n                                {{ index + 1 }}\n                            </view>\n                            <view class=\"ranking-info\">\n                                <view class=\"ranking-name\">{{ item.key }}</view>\n                                <view class=\"ranking-meta\">\n                                    <text>访问 {{ item.visits }} 次</text>\n                                    <text>·</text>\n                                    <text>交互 {{ item.interactions }} 次</text>\n                                </view>\n                            </view>\n                            <view class=\"ranking-xp\">{{ item.xp }} XP</view>\n                        </view>\n                        <view v-if=\"topComponents.length === 0\" class=\"ranking-empty\"> 暂无使用记录 </view>\n                    </view>\n                </template>\n            </u-card>\n\n            <!-- 功能使用统计 -->\n            <u-card title=\"功能使用统计\" :border=\"false\">\n                <template #body>\n                    <view class=\"feature-stats\">\n                        <view class=\"feature-item\">\n                            <view class=\"feature-icon\">\n                                <u-icon name=\"list\" size=\"50\" color=\"var(--u-type-primary)\"></u-icon>\n                            </view>\n                            <view class=\"feature-info\">\n                                <view class=\"feature-name\">待办事项</view>\n                                <view class=\"feature-count\">{{ todoCount }} 条</view>\n                            </view>\n                        </view>\n                        <view class=\"feature-item\">\n                            <view class=\"feature-icon\">\n                                <u-icon name=\"file-text\" size=\"50\" color=\"var(--u-type-success)\"></u-icon>\n                            </view>\n                            <view class=\"feature-info\">\n                                <view class=\"feature-name\">我的笔记</view>\n                                <view class=\"feature-count\">{{ noteCount }} 条</view>\n                            </view>\n                        </view>\n                        <view class=\"feature-item\">\n                            <view class=\"feature-icon\">\n                                <u-icon name=\"star\" size=\"50\" color=\"var(--u-type-warning)\"></u-icon>\n                            </view>\n                            <view class=\"feature-info\">\n                                <view class=\"feature-name\">收藏组件</view>\n                                <view class=\"feature-count\">{{ favoriteCount }} 个</view>\n                            </view>\n                        </view>\n                    </view>\n                </template>\n            </u-card>\n\n            <!-- 最近活动 -->\n            <u-card title=\"最近活动\" :border=\"false\">\n                <template #body>\n                    <view class=\"activity-list\">\n                        <view v-for=\"(activity, index) in recentActivities\" :key=\"index\" class=\"activity-item\">\n                            <view class=\"activity-icon\" :class=\"getActivityClass(activity.type)\">\n                                <u-icon :name=\"getActivityIcon(activity.type)\" size=\"30\" color=\"#fff\"></u-icon>\n                            </view>\n                            <view class=\"activity-content\">\n                                <view class=\"activity-text\">{{ activity.text }}</view>\n                                <view class=\"activity-time\">{{ formatActivityTime(activity.time) }}</view>\n                            </view>\n                        </view>\n                        <view v-if=\"recentActivities.length === 0\" class=\"activity-empty\"> 暂无活动记录 </view>\n                    </view>\n                </template>\n            </u-card>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted } from 'vue';\nimport { useExperienceCenter } from '@/common/useExperienceCenter';\n\nconst { componentStats, totalInteractions } = useExperienceCenter();\n\n// 统计数据\nconst totalVisits = ref(0);\nconst totalComponents = ref(0);\nconst totalXP = ref(0);\nconst todayTime = ref(0);\nconst weekTime = ref(0);\nconst monthTime = ref(0);\nconst todoCount = ref(0);\nconst noteCount = ref(0);\nconst favoriteCount = ref(0);\n\n// 组件使用排行\nconst topComponents = computed(() => {\n    const stats = (componentStats as any)?.value || componentStats || {};\n    const components = Object.entries(stats)\n        .map(([key, value]: [string, any]) => ({\n            key,\n            ...value\n        }))\n        .filter(item => item.visits > 0)\n        .sort((a, b) => b.visits - a.visits)\n        .slice(0, 10);\n    return components;\n});\n\n// 最近活动\nconst recentActivities = ref<Array<{ type: string; text: string; time: number }>>([]);\n\n// 获取排名样式\nfunction getRankClass(index: number) {\n    if (index === 0) return 'rank-gold';\n    if (index === 1) return 'rank-silver';\n    if (index === 2) return 'rank-bronze';\n    return '';\n}\n\n// 获取活动图标\nfunction getActivityIcon(type: string) {\n    const iconMap: Record<string, string> = {\n        component: 'grid-fill',\n        task: 'checkmark-circle',\n        note: 'file-text',\n        favorite: 'star'\n    };\n    return iconMap[type] || 'info-circle';\n}\n\n// 获取活动样式\nfunction getActivityClass(type: string) {\n    const classMap: Record<string, string> = {\n        component: 'activity-component',\n        task: 'activity-task',\n        note: 'activity-note',\n        favorite: 'activity-favorite'\n    };\n    return classMap[type] || 'activity-default';\n}\n\n// 格式化时间\nfunction formatTime(seconds: number) {\n    if (seconds < 60) return `${seconds}秒`;\n    if (seconds < 3600) return `${Math.floor(seconds / 60)}分钟`;\n    return `${Math.floor(seconds / 3600)}小时${Math.floor((seconds % 3600) / 60)}分钟`;\n}\n\n// 格式化活动时间\nfunction formatActivityTime(timestamp: number) {\n    const date = new Date(timestamp);\n    const now = new Date();\n    const diff = now.getTime() - date.getTime();\n    const minutes = Math.floor(diff / (1000 * 60));\n    const hours = Math.floor(diff / (1000 * 60 * 60));\n    const days = Math.floor(diff / (1000 * 60 * 60 * 24));\n\n    if (minutes < 1) return '刚刚';\n    if (minutes < 60) return `${minutes}分钟前`;\n    if (hours < 24) return `${hours}小时前`;\n    if (days < 7) return `${days}天前`;\n    return `${date.getMonth() + 1}月${date.getDate()}日`;\n}\n\n// 加载统计数据\nfunction loadStats() {\n    try {\n        // 加载体验中心数据\n        const stats = (componentStats as any)?.value || componentStats || {};\n        totalComponents.value = Object.keys(stats).length;\n        totalXP.value = Number(Object.values(stats).reduce((sum: number, item: any) => sum + (item.xp || 0), 0));\n        totalVisits.value = Number(\n            Object.values(stats).reduce((sum: number, item: any) => sum + (item.visits || 0), 0)\n        );\n\n        // 加载其他功能数据\n        const todoList = uni.getStorageSync('uview-todo-list') || [];\n        todoCount.value = Array.isArray(todoList) ? todoList.length : 0;\n\n        const notesList = uni.getStorageSync('uview-notes-list') || [];\n        noteCount.value = Array.isArray(notesList) ? notesList.length : 0;\n\n        const favorites = uni.getStorageSync('uview-favorites') || [];\n        favoriteCount.value = Array.isArray(favorites) ? favorites.length : 0;\n\n        // 模拟使用时长（实际应该从真实数据计算）\n        const today = Math.floor(Math.random() * 3600) + 1800; // 30分钟到1.5小时\n        todayTime.value = today;\n        weekTime.value = today * 7;\n        monthTime.value = today * 30;\n\n        // 生成最近活动\n        generateRecentActivities();\n    } catch (error) {\n        console.warn('loadStats error', error);\n    }\n}\n\n// 生成最近活动\nfunction generateRecentActivities() {\n    const activities = [];\n    const now = Date.now();\n\n    // 从组件统计中生成活动\n    const stats = (componentStats as any)?.value || componentStats || {};\n    Object.entries(stats).forEach(([key, value]: [string, any]) => {\n        if (value.lastUpdated) {\n            activities.push({\n                type: 'component',\n                text: `体验了 ${key} 组件`,\n                time: value.lastUpdated\n            });\n        }\n    });\n\n    // 从待办事项生成活动\n    const todoList = uni.getStorageSync('uview-todo-list') || [];\n    if (Array.isArray(todoList) && todoList.length > 0) {\n        const latestTodo = todoList.sort((a, b) => b.createdAt - a.createdAt)[0];\n        if (latestTodo) {\n            activities.push({\n                type: 'task',\n                text: `创建了待办事项：${latestTodo.text}`,\n                time: latestTodo.createdAt\n            });\n        }\n    }\n\n    // 从笔记生成活动\n    const notesList = uni.getStorageSync('uview-notes-list') || [];\n    if (Array.isArray(notesList) && notesList.length > 0) {\n        const latestNote = notesList.sort((a, b) => b.updatedAt - a.updatedAt)[0];\n        if (latestNote) {\n            activities.push({\n                type: 'note',\n                text: `创建了笔记：${latestNote.title}`,\n                time: latestNote.updatedAt\n            });\n        }\n    }\n\n    // 排序并取最近10条\n    recentActivities.value = activities.sort((a, b) => b.time - a.time).slice(0, 10);\n}\n\nonMounted(() => {\n    loadStats();\n});\n</script>\n\n<style lang=\"scss\" scoped>\n.dashboard-container {\n    padding: 24rpx;\n    min-height: 100vh;\n    background: linear-gradient(180deg, rgba(41, 121, 255, 0.02) 0%, transparent 100%);\n}\n\n.overview-card {\n    padding: 32rpx;\n    background: linear-gradient(135deg, rgba(41, 121, 255, 0.15), rgba(25, 190, 107, 0.15));\n    border-radius: 20rpx;\n    box-shadow: 0 8rpx 24rpx rgba(41, 121, 255, 0.15);\n    margin-bottom: 24rpx;\n}\n\n.overview-title {\n    font-size: 32rpx;\n    font-weight: 600;\n    color: var(--u-main-color);\n    margin-bottom: 24rpx;\n}\n\n.overview-stats {\n    display: flex;\n    gap: 20rpx;\n}\n\n.stat-box {\n    flex: 1;\n    text-align: center;\n}\n\n.stat-value {\n    font-size: 48rpx;\n    font-weight: 700;\n    color: var(--u-type-primary);\n    margin-bottom: 8rpx;\n}\n\n.stat-label {\n    font-size: 24rpx;\n    color: var(--u-content-color);\n}\n\n.time-stats {\n    display: flex;\n    flex-direction: column;\n    gap: 20rpx;\n}\n\n.time-item {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    padding: 20rpx;\n    background: rgba(41, 121, 255, 0.05);\n    border-radius: 12rpx;\n}\n\n.time-label {\n    font-size: 28rpx;\n    color: var(--u-content-color);\n}\n\n.time-value {\n    font-size: 32rpx;\n    font-weight: 600;\n    color: var(--u-type-primary);\n}\n\n.ranking-list {\n    display: flex;\n    flex-direction: column;\n    gap: 16rpx;\n}\n\n.ranking-item {\n    display: flex;\n    align-items: center;\n    padding: 20rpx;\n    background: rgba(41, 121, 255, 0.05);\n    border-radius: 12rpx;\n    gap: 20rpx;\n}\n\n.ranking-index {\n    width: 60rpx;\n    height: 60rpx;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    border-radius: 50%;\n    background: var(--u-border-color);\n    color: var(--u-content-color);\n    font-size: 28rpx;\n    font-weight: 600;\n\n    &.rank-gold {\n        background: linear-gradient(135deg, #ffd700, #ffed4e);\n        color: #fff;\n    }\n\n    &.rank-silver {\n        background: linear-gradient(135deg, #c0c0c0, #e8e8e8);\n        color: #fff;\n    }\n\n    &.rank-bronze {\n        background: linear-gradient(135deg, #cd7f32, #e6a23c);\n        color: #fff;\n    }\n}\n\n.ranking-info {\n    flex: 1;\n}\n\n.ranking-name {\n    font-size: 28rpx;\n    font-weight: 600;\n    color: var(--u-main-color);\n    margin-bottom: 8rpx;\n}\n\n.ranking-meta {\n    font-size: 22rpx;\n    color: var(--u-tips-color);\n    display: flex;\n    gap: 8rpx;\n}\n\n.ranking-xp {\n    font-size: 28rpx;\n    font-weight: 600;\n    color: var(--u-type-warning);\n}\n\n.ranking-empty {\n    text-align: center;\n    padding: 40rpx 0;\n    color: var(--u-tips-color);\n}\n\n.feature-stats {\n    display: flex;\n    flex-direction: column;\n    gap: 20rpx;\n}\n\n.feature-item {\n    display: flex;\n    align-items: center;\n    padding: 24rpx;\n    background: rgba(41, 121, 255, 0.05);\n    border-radius: 12rpx;\n    gap: 24rpx;\n}\n\n.feature-icon {\n    width: 80rpx;\n    height: 80rpx;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    background: rgba(41, 121, 255, 0.1);\n    border-radius: 16rpx;\n}\n\n.feature-info {\n    flex: 1;\n}\n\n.feature-name {\n    font-size: 28rpx;\n    font-weight: 600;\n    color: var(--u-main-color);\n    margin-bottom: 8rpx;\n}\n\n.feature-count {\n    font-size: 24rpx;\n    color: var(--u-tips-color);\n}\n\n.activity-list {\n    display: flex;\n    flex-direction: column;\n    gap: 16rpx;\n}\n\n.activity-item {\n    display: flex;\n    align-items: center;\n    gap: 20rpx;\n    padding: 20rpx;\n    background: rgba(41, 121, 255, 0.05);\n    border-radius: 12rpx;\n}\n\n.activity-icon {\n    width: 60rpx;\n    height: 60rpx;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    border-radius: 50%;\n\n    &.activity-component {\n        background: var(--u-type-primary);\n    }\n\n    &.activity-task {\n        background: var(--u-type-success);\n    }\n\n    &.activity-note {\n        background: var(--u-type-warning);\n    }\n\n    &.activity-favorite {\n        background: var(--u-type-error);\n    }\n\n    &.activity-default {\n        background: var(--u-tips-color);\n    }\n}\n\n.activity-content {\n    flex: 1;\n}\n\n.activity-text {\n    font-size: 28rpx;\n    color: var(--u-main-color);\n    margin-bottom: 8rpx;\n}\n\n.activity-time {\n    font-size: 22rpx;\n    color: var(--u-tips-color);\n}\n\n.activity-empty {\n    text-align: center;\n    padding: 40rpx 0;\n    color: var(--u-tips-color);\n}\n</style>\n"
  },
  {
    "path": "src/pages/scenes/favorites/index.vue",
    "content": "<template>\n    <demo-page hide-tabs title=\"我的收藏\" desc=\"收藏喜欢的组件\" :nav-back=\"true\">\n        <view class=\"favorites-container\">\n            <!-- 统计信息 -->\n            <view class=\"stats-section\">\n                <view class=\"stat-card\">\n                    <view class=\"stat-value\">{{ favorites.length }}</view>\n                    <view class=\"stat-label\">已收藏组件</view>\n                </view>\n            </view>\n\n            <!-- 收藏列表 -->\n            <view class=\"favorites-list\">\n                <view v-if=\"favorites.length === 0\" class=\"empty-state\">\n                    <u-empty mode=\"data\" text=\"暂无收藏，快去收藏喜欢的组件吧\" :show-empty=\"true\"></u-empty>\n                    <u-button type=\"primary\" size=\"mini\" @click=\"goToComponents\" style=\"margin-top: 40rpx\">\n                        去浏览组件\n                    </u-button>\n                </view>\n\n                <view\n                    v-for=\"item in favorites\"\n                    :key=\"item.path\"\n                    class=\"favorite-item\"\n                    @click=\"openComponent(item.path)\"\n                >\n                    <view class=\"favorite-icon\">\n                        <u-avatar :text=\"item.title\" bg-color=\"var(--u-bg-gray-light)\" mode=\"square\"></u-avatar>\n                    </view>\n                    <view class=\"favorite-info\">\n                        <view class=\"favorite-title\">{{ item.title }}</view>\n                        <view class=\"favorite-desc\">{{ item.desc || '组件描述' }}</view>\n                        <view class=\"favorite-time\">收藏于 {{ formatTime(item.collectedAt) }}</view>\n                    </view>\n                    <view class=\"favorite-actions\" @click.stop=\"removeFavorite(item.path)\">\n                        <u-icon name=\"trash\" size=\"40\" color=\"var(--u-type-error)\"></u-icon>\n                    </view>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\n\ninterface FavoriteItem {\n    path: string;\n    title: string;\n    desc?: string;\n    icon?: string;\n    collectedAt: number;\n}\n\nconst STORAGE_KEY = 'uview-favorites';\n\nconst favorites = ref<FavoriteItem[]>([]);\n\n// 获取图标地址\nfunction getIcon(path: string) {\n    // #ifdef APP\n    return '/static/app/example/' + path + '.png';\n    // #endif\n    return 'https://ik.imagekit.io/anyup/uview-pro/example/' + path + '.png';\n}\n\n// 格式化时间\nfunction formatTime(timestamp: number) {\n    const date = new Date(timestamp);\n    const month = date.getMonth() + 1;\n    const day = date.getDate();\n    const year = date.getFullYear();\n    return `${year}年${month}月${day}日`;\n}\n\n// 加载收藏\nfunction loadFavorites() {\n    try {\n        const stored = uni.getStorageSync(STORAGE_KEY);\n        if (stored && Array.isArray(stored)) {\n            favorites.value = stored.sort((a, b) => b.collectedAt - a.collectedAt);\n        }\n    } catch (error) {\n        console.warn('loadFavorites error', error);\n    }\n}\n\n// 保存收藏\nfunction saveFavorites() {\n    try {\n        uni.setStorageSync(STORAGE_KEY, favorites.value);\n    } catch (error) {\n        console.warn('saveFavorites error', error);\n    }\n}\n\n// 打开组件\nfunction openComponent(path: string) {\n    uni.navigateTo({ url: path });\n}\n\n// 移除收藏\nfunction removeFavorite(path: string) {\n    uni.showModal({\n        title: '确认取消收藏',\n        content: '确定要取消收藏这个组件吗？',\n        success: res => {\n            if (res.confirm) {\n                favorites.value = favorites.value.filter(item => item.path !== path);\n                saveFavorites();\n                $u.toast('已取消收藏', 'success');\n            }\n        }\n    });\n}\n\n// 前往组件页面\nfunction goToComponents() {\n    uni.switchTab({ url: '/pages/example/components' });\n}\n\nonMounted(() => {\n    loadFavorites();\n});\n</script>\n\n<style lang=\"scss\" scoped>\n.favorites-container {\n    padding: 24rpx;\n    min-height: 100vh;\n    background: linear-gradient(180deg, rgba(41, 121, 255, 0.02) 0%, transparent 100%);\n}\n\n.stats-section {\n    margin-bottom: 24rpx;\n}\n\n.stat-card {\n    padding: 32rpx;\n    background: linear-gradient(135deg, rgba(41, 121, 255, 0.15), rgba(25, 190, 107, 0.15));\n    border-radius: 20rpx;\n    box-shadow: 0 8rpx 24rpx rgba(41, 121, 255, 0.15);\n    text-align: center;\n}\n\n.stat-value {\n    font-size: 64rpx;\n    font-weight: 700;\n    color: var(--u-type-primary);\n    margin-bottom: 12rpx;\n}\n\n.stat-label {\n    font-size: 28rpx;\n    color: var(--u-content-color);\n}\n\n.favorites-list {\n    display: flex;\n    flex-direction: column;\n    gap: 20rpx;\n}\n\n.favorite-item {\n    display: flex;\n    align-items: center;\n    padding: 24rpx;\n    background: var(--u-bg-color);\n    border-radius: 16rpx;\n    box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);\n    gap: 20rpx;\n    transition: all 0.3s ease;\n\n    &:active {\n        transform: scale(0.98);\n    }\n}\n\n.favorite-icon {\n    flex-shrink: 0;\n}\n\n.favorite-info {\n    flex: 1;\n    min-width: 0;\n}\n\n.favorite-title {\n    font-size: 30rpx;\n    font-weight: 600;\n    color: var(--u-main-color);\n    margin-bottom: 8rpx;\n}\n\n.favorite-desc {\n    font-size: 24rpx;\n    color: var(--u-content-color);\n    margin-bottom: 8rpx;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n}\n\n.favorite-time {\n    font-size: 22rpx;\n    color: var(--u-tips-color);\n}\n\n.favorite-actions {\n    flex-shrink: 0;\n    padding: 8rpx;\n}\n\n.empty-state {\n    padding: 100rpx 0;\n    text-align: center;\n}\n</style>\n"
  },
  {
    "path": "src/pages/scenes/index.vue",
    "content": "<template>\n    <demo-page hide-tabs nav-title=\"实用场景\" :nav-back=\"true\">\n        <view class=\"scenes-container\">\n            <page-nav desc=\"体验完整的业务场景，感受组件在实际应用中的使用\" title=\"实用场景\" :index=\"0\"></page-nav>\n\n            <!-- 场景卡片列表 -->\n            <view class=\"scenes-grid\">\n                <view class=\"scene-card\" v-for=\"scene in scenes\" :key=\"scene.path\" @click=\"openScene(scene.path)\">\n                    <view class=\"scene-icon\" :style=\"{ background: scene.bgColor }\">\n                        <u-icon :name=\"scene.icon\" size=\"60\" :color=\"scene.iconColor\"></u-icon>\n                    </view>\n                    <view class=\"scene-info\">\n                        <view class=\"scene-title\">{{ scene.title }}</view>\n                        <view class=\"scene-desc\">{{ scene.desc }}</view>\n                    </view>\n                    <view class=\"scene-arrow\">›</view>\n                </view>\n            </view>\n\n            <!-- 提示信息 -->\n            <view class=\"tips-section\">\n                <u-alert-tips\n                    title=\"这些场景展示了组件在实际业务中的应用，帮助您更好地理解组件的使用方式\"\n                    type=\"primary\"\n                    :show-icon=\"true\"\n                ></u-alert-tips>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nconst scenes = [\n    {\n        title: '待办事项',\n        desc: '任务管理，提高工作效率',\n        icon: 'list',\n        iconColor: '#fff',\n        bgColor: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\n        path: '/pages/scenes/todo/index'\n    },\n    {\n        title: '我的笔记',\n        desc: '记录想法，随时查看',\n        icon: 'file-text',\n        iconColor: '#fff',\n        bgColor: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',\n        path: '/pages/scenes/notes/index'\n    },\n    {\n        title: '数据统计',\n        desc: '使用数据一目了然',\n        icon: 'tags',\n        iconColor: '#fff',\n        bgColor: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)',\n        path: '/pages/scenes/dashboard/index'\n    },\n    {\n        title: '我的收藏',\n        desc: '收藏喜欢的组件',\n        icon: 'star',\n        iconColor: '#fff',\n        bgColor: 'linear-gradient(135deg, #fa709a 0%, #fee140 100%)',\n        path: '/pages/scenes/favorites/index'\n    }\n];\n\nfunction openScene(path: string) {\n    uni.navigateTo({ url: path });\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.scenes-container {\n    padding: 24rpx;\n    min-height: 100vh;\n    background: linear-gradient(180deg, rgba(41, 121, 255, 0.02) 0%, transparent 100%);\n}\n\n.scenes-grid {\n    display: flex;\n    flex-direction: column;\n    gap: 24rpx;\n    margin-top: 24rpx;\n}\n\n.scene-card {\n    display: flex;\n    align-items: center;\n    padding: 32rpx;\n    background: var(--u-bg-color);\n    border-radius: 20rpx;\n    box-shadow: 0 8rpx 24rpx rgba(41, 121, 255, 0.1);\n    gap: 24rpx;\n    transition: all 0.3s ease;\n\n    &:active {\n        transform: scale(0.98);\n    }\n}\n\n.scene-icon {\n    width: 120rpx;\n    height: 120rpx;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    border-radius: 24rpx;\n    flex-shrink: 0;\n}\n\n.scene-info {\n    flex: 1;\n    min-width: 0;\n}\n\n.scene-title {\n    font-size: 32rpx;\n    font-weight: 600;\n    color: var(--u-main-color);\n    margin-bottom: 12rpx;\n}\n\n.scene-desc {\n    font-size: 24rpx;\n    color: var(--u-content-color);\n    line-height: 1.5;\n}\n\n.scene-arrow {\n    font-size: 48rpx;\n    color: var(--u-type-primary);\n    flex-shrink: 0;\n}\n\n.tips-section {\n    margin-top: 40rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/scenes/notes/index.vue",
    "content": "<template>\n    <demo-page hide-tabs title=\"我的笔记\" desc=\"记录你的想法，随时查看。\" :nav-back=\"true\">\n        <view class=\"notes-container\">\n            <!-- 添加笔记按钮 -->\n            <view class=\"add-button-section\">\n                <u-button type=\"primary\" @click=\"addNote\" icon=\"plus\" shape=\"circle\"> 新建笔记 </u-button>\n            </view>\n\n            <!-- 搜索框 -->\n            <view class=\"search-section\">\n                <u-search v-model=\"searchText\" placeholder=\"搜索笔记...\" :show-action=\"false\" shape=\"round\"></u-search>\n            </view>\n\n            <!-- 笔记列表 -->\n            <view class=\"notes-list\">\n                <view v-if=\"filteredNotes.length === 0\" class=\"empty-state\">\n                    <u-empty\n                        mode=\"data\"\n                        :text=\"searchText ? '未找到相关笔记' : '暂无笔记，点击上方按钮创建'\"\n                        :show-empty=\"true\"\n                    ></u-empty>\n                </view>\n\n                <view v-for=\"note in filteredNotes\" :key=\"note.id\" class=\"note-card\" @click=\"editNote(note)\">\n                    <view class=\"note-header\">\n                        <view class=\"note-title\">{{ note.title || '无标题' }}</view>\n                        <view class=\"note-time\">{{ formatTime(note.updatedAt) }}</view>\n                    </view>\n                    <view class=\"note-content\">{{ note.content || '无内容' }}</view>\n                    <view class=\"note-footer\">\n                        <u-tag v-if=\"note.tag\" :text=\"note.tag\" size=\"mini\" type=\"primary\" plain></u-tag>\n                        <view class=\"note-actions\" @click.stop=\"deleteNote(note.id)\">\n                            <u-icon name=\"trash\" size=\"36\" color=\"var(--u-type-error)\"></u-icon>\n                        </view>\n                    </view>\n                </view>\n            </view>\n\n            <!-- 添加/编辑笔记弹窗 -->\n            <u-popup v-model=\"showAddModal\" mode=\"bottom\" height=\"80%\" border-radius=\"20\">\n                <view class=\"note-editor\">\n                    <view class=\"editor-header\">\n                        <u-button type=\"error\" size=\"mini\" plain @click=\"showAddModal = false\">取消</u-button>\n                        <view class=\"editor-title\">{{ currentNote ? '编辑笔记' : '新建笔记' }}</view>\n                        <u-button type=\"primary\" size=\"mini\" @click=\"saveNote\">保存</u-button>\n                    </view>\n                    <view class=\"editor-body\">\n                        <u-gap height=\"20px\"></u-gap>\n                        <u-input\n                            v-model=\"noteForm.title\"\n                            placeholder=\"笔记标题\"\n                            :border=\"true\"\n                            :clearable=\"true\"\n                        ></u-input>\n                        <u-gap height=\"30px\"></u-gap>\n                        <u-textarea\n                            v-model=\"noteForm.content\"\n                            placeholder=\"开始记录你的想法...\"\n                            :auto-height=\"true\"\n                            :maxlength=\"2000\"\n                            height=\"200rpx\"\n                            :count=\"true\"\n                        ></u-textarea>\n                        <u-gap height=\"30px\"></u-gap>\n                        <view class=\"tag-section\">\n                            <view class=\"tag-label\">标签：</view>\n                            <u-tag\n                                v-for=\"tag in tags\"\n                                :key=\"tag\"\n                                :text=\"tag\"\n                                :type=\"noteForm.tag === tag ? 'primary' : 'info'\"\n                                @click=\"noteForm.tag = noteForm.tag === tag ? '' : tag\"\n                                style=\"margin-right: 12rpx\"\n                            ></u-tag>\n                        </view>\n                    </view>\n                </view>\n            </u-popup>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\n\ninterface Note {\n    id: string;\n    title: string;\n    content: string;\n    tag: string;\n    createdAt: number;\n    updatedAt: number;\n}\n\nconst STORAGE_KEY = 'uview-notes-list';\n\nconst notes = ref<Note[]>([]);\nconst searchText = ref('');\nconst showAddModal = ref(false);\nconst currentNote = ref<Note | null>(null);\n\nconst noteForm = ref({\n    title: '',\n    content: '',\n    tag: ''\n});\n\nconst tags = ['工作', '生活', '学习', '灵感', '其他'];\n\n// 筛选后的笔记列表\nconst filteredNotes = computed(() => {\n    let result = notes.value;\n    if (searchText.value) {\n        const keyword = searchText.value.toLowerCase();\n        result = result.filter(\n            note =>\n                note.title.toLowerCase().includes(keyword) ||\n                note.content.toLowerCase().includes(keyword) ||\n                note.tag.toLowerCase().includes(keyword)\n        );\n    }\n    return result.sort((a, b) => b.updatedAt - a.updatedAt);\n});\n\n// 格式化时间\nfunction formatTime(timestamp: number) {\n    const date = new Date(timestamp);\n    const now = new Date();\n    const diff = now.getTime() - date.getTime();\n    const days = Math.floor(diff / (1000 * 60 * 60 * 24));\n\n    if (days === 0) {\n        const hours = Math.floor(diff / (1000 * 60 * 60));\n        if (hours === 0) {\n            const minutes = Math.floor(diff / (1000 * 60));\n            return minutes <= 0 ? '刚刚' : `${minutes}分钟前`;\n        }\n        return `${hours}小时前`;\n    } else if (days === 1) {\n        return '昨天';\n    } else if (days < 7) {\n        return `${days}天前`;\n    } else {\n        const month = date.getMonth() + 1;\n        const day = date.getDate();\n        return `${month}月${day}日`;\n    }\n}\n\n// 加载笔记\nfunction loadNotes() {\n    try {\n        const stored = uni.getStorageSync(STORAGE_KEY);\n        if (stored && Array.isArray(stored)) {\n            notes.value = stored;\n        }\n    } catch (error) {\n        console.warn('loadNotes error', error);\n    }\n}\n\n// 保存笔记\nfunction saveNotes() {\n    try {\n        uni.setStorageSync(STORAGE_KEY, notes.value);\n    } catch (error) {\n        console.warn('saveNotes error', error);\n    }\n}\n\n// 保存笔记\nfunction saveNote() {\n    const { title, content, tag } = noteForm.value;\n    if (!title.trim() && !content.trim()) {\n        $u.toast('请输入标题或内容', 'warning');\n        return;\n    }\n\n    const now = Date.now();\n    if (currentNote.value) {\n        // 编辑现有笔记\n        const note = notes.value.find(n => n.id === currentNote.value!.id);\n        if (note) {\n            note.title = title;\n            note.content = content;\n            note.tag = tag;\n            note.updatedAt = now;\n        }\n    } else {\n        // 创建新笔记\n        const newNote: Note = {\n            id: Date.now().toString() + Math.random().toString(36).substr(2, 9),\n            title: title || '无标题',\n            content,\n            tag,\n            createdAt: now,\n            updatedAt: now\n        };\n        notes.value.unshift(newNote);\n    }\n\n    saveNotes();\n    resetForm();\n    showAddModal.value = false;\n    $u.toast(currentNote.value ? '保存成功' : '创建成功', 'success');\n}\n\nfunction addNote() {\n    resetForm();\n    showAddModal.value = true;\n}\n\n// 编辑笔记\nfunction editNote(note: Note) {\n    currentNote.value = note;\n    noteForm.value = {\n        title: note.title,\n        content: note.content,\n        tag: note.tag\n    };\n    showAddModal.value = true;\n}\n\n// 删除笔记\nfunction deleteNote(id: string) {\n    uni.showModal({\n        title: '确认删除',\n        content: '确定要删除这条笔记吗？',\n        success: res => {\n            if (res.confirm) {\n                notes.value = notes.value.filter(n => n.id !== id);\n                saveNotes();\n                $u.toast('删除成功', 'success');\n            }\n        }\n    });\n}\n\n// 重置表单\nfunction resetForm() {\n    currentNote.value = null;\n    noteForm.value = {\n        title: '',\n        content: '',\n        tag: ''\n    };\n}\n\nonMounted(() => {\n    loadNotes();\n});\n</script>\n\n<style lang=\"scss\" scoped>\n.notes-container {\n    padding: 24rpx;\n    min-height: 100vh;\n    background: linear-gradient(180deg, rgba(41, 121, 255, 0.02) 0%, transparent 100%);\n}\n\n.add-button-section {\n    margin-bottom: 24rpx;\n}\n\n.search-section {\n    margin-bottom: 24rpx;\n}\n\n.notes-list {\n    display: flex;\n    flex-direction: column;\n    gap: 20rpx;\n}\n\n.note-card {\n    padding: 24rpx;\n    background: var(--u-bg-color);\n    border-radius: 16rpx;\n    box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);\n    transition: all 0.3s ease;\n\n    &:active {\n        transform: scale(0.98);\n    }\n}\n\n.note-header {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    margin-bottom: 16rpx;\n}\n\n.note-title {\n    font-size: 32rpx;\n    font-weight: 600;\n    color: var(--u-main-color);\n    flex: 1;\n}\n\n.note-time {\n    font-size: 22rpx;\n    color: var(--u-tips-color);\n}\n\n.note-content {\n    font-size: 26rpx;\n    color: var(--u-content-color);\n    line-height: 1.6;\n    margin-bottom: 16rpx;\n    display: -webkit-box;\n    -webkit-box-orient: vertical;\n    -webkit-line-clamp: 3;\n    overflow: hidden;\n}\n\n.note-footer {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n}\n\n.note-actions {\n    display: flex;\n    gap: 16rpx;\n}\n\n.empty-state {\n    padding: 100rpx 0;\n}\n\n.note-editor {\n    height: 100%;\n    display: flex;\n    flex-direction: column;\n}\n\n.editor-header {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    padding: 24rpx;\n    border-bottom: 1rpx solid var(--u-border-color);\n}\n\n.editor-title {\n    font-size: 32rpx;\n    font-weight: 600;\n    color: var(--u-main-color);\n}\n\n.editor-body {\n    flex: 1;\n    padding: 24rpx;\n    overflow-y: auto;\n}\n\n.tag-section {\n    display: flex;\n    flex-wrap: wrap;\n    align-items: center;\n    gap: 12rpx;\n}\n\n.tag-label {\n    font-size: 26rpx;\n    color: var(--u-content-color);\n    margin-right: 12rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/scenes/todo/index.vue",
    "content": "<template>\n    <demo-page hide-tabs title=\"待办事项\" desc=\"记录你的任务，完成它们，并保持组织。\" :nav-back=\"true\">\n        <view class=\"todo-container\">\n            <!-- 统计卡片 -->\n            <view class=\"stats-card\">\n                <view class=\"stat-item\">\n                    <view class=\"stat-value\">{{ totalCount }}</view>\n                    <view class=\"stat-label\">全部</view>\n                </view>\n                <view class=\"stat-item\">\n                    <view class=\"stat-value\">{{ pendingCount }}</view>\n                    <view class=\"stat-label\">待完成</view>\n                </view>\n                <view class=\"stat-item\">\n                    <view class=\"stat-value\">{{ completedCount }}</view>\n                    <view class=\"stat-label\">已完成</view>\n                </view>\n            </view>\n\n            <!-- 添加任务 -->\n            <view class=\"add-section\">\n                <u-search\n                    v-model=\"newTaskText\"\n                    placeholder=\"添加新的待办事项...\"\n                    :show-action=\"true\"\n                    search-icon=\"order\"\n                    action-text=\"添加\"\n                    @custom=\"addTask\"\n                    @search=\"addTask\"\n                    shape=\"round\"\n                ></u-search>\n            </view>\n\n            <!-- 筛选标签 -->\n            <view class=\"filter-section\">\n                <u-subsection\n                    :list=\"filterOptions\"\n                    :current=\"currentFilter\"\n                    @change=\"changeFilter\"\n                    active-color=\"var(--u-type-primary)\"\n                ></u-subsection>\n            </view>\n\n            <!-- 任务列表 -->\n            <view class=\"task-list\">\n                <view v-if=\"filteredTasks.length === 0\" class=\"empty-state\">\n                    <u-empty mode=\"data\" text=\"暂无待办事项\" :show-empty=\"true\"></u-empty>\n                </view>\n\n                <view v-for=\"task in filteredTasks\" :key=\"task.id\" class=\"task-item\">\n                    <view class=\"task-content\" @click=\"toggleTask(task.id)\">\n                        <u-checkbox\n                            v-model=\"task.completed\"\n                            @change=\"toggleTask(task.id)\"\n                            shape=\"circle\"\n                            active-color=\"var(--u-type-primary)\"\n                        ></u-checkbox>\n                        <view class=\"task-text\" :class=\"{ completed: task.completed }\">\n                            <text>{{ task.text }}</text>\n                            <view v-if=\"task.completed\" class=\"completed-line\"></view>\n                        </view>\n                    </view>\n                    <view class=\"task-actions\">\n                        <u-icon\n                            name=\"trash\"\n                            size=\"40\"\n                            color=\"var(--u-type-error)\"\n                            @click=\"deleteTask(task.id)\"\n                        ></u-icon>\n                    </view>\n                </view>\n            </view>\n\n            <!-- 底部操作栏 -->\n            <view v-if=\"completedCount > 0\" class=\"bottom-actions\">\n                <u-button type=\"error\" size=\"mini\" plain @click=\"clearCompleted\">清除已完成</u-button>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\n\ninterface TodoTask {\n    id: string;\n    text: string;\n    completed: boolean;\n    createdAt: number;\n}\n\nconst STORAGE_KEY = 'uview-todo-list';\n\nconst tasks = ref<TodoTask[]>([]);\nconst newTaskText = ref('');\nconst currentFilter = ref(0);\nconst filterOptions = ['全部', '待完成', '已完成'];\n\n// 统计数据\nconst totalCount = computed(() => tasks.value.length);\nconst pendingCount = computed(() => tasks.value.filter(t => !t.completed).length);\nconst completedCount = computed(() => tasks.value.filter(t => t.completed).length);\n\n// 筛选后的任务列表\nconst filteredTasks = computed(() => {\n    if (currentFilter.value === 0) {\n        return tasks.value.sort((a, b) => b.createdAt - a.createdAt);\n    } else if (currentFilter.value === 1) {\n        return tasks.value.filter(t => !t.completed).sort((a, b) => b.createdAt - a.createdAt);\n    } else {\n        return tasks.value.filter(t => t.completed).sort((a, b) => b.createdAt - a.createdAt);\n    }\n});\n\n// 加载任务\nfunction loadTasks() {\n    try {\n        const stored = uni.getStorageSync(STORAGE_KEY);\n        if (stored && Array.isArray(stored)) {\n            tasks.value = stored;\n        }\n    } catch (error) {\n        console.warn('loadTasks error', error);\n    }\n}\n\n// 保存任务\nfunction saveTasks() {\n    try {\n        uni.setStorageSync(STORAGE_KEY, tasks.value);\n    } catch (error) {\n        console.warn('saveTasks error', error);\n    }\n}\n\n// 添加任务\nfunction addTask() {\n    const text = newTaskText.value.trim();\n    if (!text) {\n        $u.toast('请输入待办事项', 'warning');\n        return;\n    }\n\n    const newTask: TodoTask = {\n        id: Date.now().toString() + Math.random().toString(36).substr(2, 9),\n        text,\n        completed: false,\n        createdAt: Date.now()\n    };\n\n    tasks.value.unshift(newTask);\n    saveTasks();\n    newTaskText.value = '';\n    $u.toast('添加成功', 'success');\n}\n\n// 切换任务状态\nfunction toggleTask(id: string) {\n    const task = tasks.value.find(t => t.id === id);\n    if (task) {\n        task.completed = !task.completed;\n        saveTasks();\n    }\n}\n\n// 删除任务\nfunction deleteTask(id: string) {\n    uni.showModal({\n        title: '确认删除',\n        content: '确定要删除这个待办事项吗？',\n        success: res => {\n            if (res.confirm) {\n                tasks.value = tasks.value.filter(t => t.id !== id);\n                saveTasks();\n                $u.toast('删除成功', 'success');\n            }\n        }\n    });\n}\n\n// 清除已完成\nfunction clearCompleted() {\n    uni.showModal({\n        title: '确认清除',\n        content: `确定要清除 ${completedCount.value} 个已完成的任务吗？`,\n        success: res => {\n            if (res.confirm) {\n                tasks.value = tasks.value.filter(t => !t.completed);\n                saveTasks();\n                $u.toast('清除成功', 'success');\n            }\n        }\n    });\n}\n\n// 切换筛选\nfunction changeFilter(index: number) {\n    currentFilter.value = index;\n}\n\nonMounted(() => {\n    loadTasks();\n});\n</script>\n\n<style lang=\"scss\" scoped>\n.todo-container {\n    padding: 24rpx;\n    min-height: 100vh;\n    background: linear-gradient(180deg, rgba(41, 121, 255, 0.02) 0%, transparent 100%);\n}\n\n.stats-card {\n    display: flex;\n    gap: 20rpx;\n    margin-bottom: 30rpx;\n    padding: 30rpx;\n    background: linear-gradient(135deg, rgba(41, 121, 255, 0.1), rgba(25, 190, 107, 0.1));\n    border-radius: 20rpx;\n    box-shadow: 0 8rpx 24rpx rgba(41, 121, 255, 0.1);\n\n    .stat-item {\n        flex: 1;\n        text-align: center;\n\n        .stat-value {\n            font-size: 48rpx;\n            font-weight: 700;\n            color: var(--u-type-primary);\n            margin-bottom: 8rpx;\n        }\n\n        .stat-label {\n            font-size: 24rpx;\n            color: var(--u-content-color);\n        }\n    }\n}\n\n.add-section {\n    margin-bottom: 24rpx;\n}\n\n.filter-section {\n    margin-bottom: 24rpx;\n}\n\n.task-list {\n    display: flex;\n    flex-direction: column;\n    gap: 16rpx;\n}\n\n.task-item {\n    display: flex;\n    align-items: center;\n    padding: 24rpx;\n    background: var(--u-bg-color);\n    border-radius: 16rpx;\n    box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);\n    transition: all 0.3s ease;\n\n    &:active {\n        transform: scale(0.98);\n    }\n}\n\n.task-content {\n    flex: 1;\n    display: flex;\n    align-items: center;\n    gap: 20rpx;\n}\n\n.task-text {\n    flex: 1;\n    font-size: 28rpx;\n    color: var(--u-main-color);\n    position: relative;\n\n    &.completed {\n        color: var(--u-tips-color);\n    }\n\n    .completed-line {\n        position: absolute;\n        top: 50%;\n        left: 0;\n        right: 0;\n        height: 2rpx;\n        background: var(--u-tips-color);\n        transform: translateY(-50%);\n    }\n}\n\n.task-actions {\n    padding: 8rpx;\n}\n\n.empty-state {\n    padding: 100rpx 0;\n}\n\n.bottom-actions {\n    position: fixed;\n    bottom: 0;\n    left: 0;\n    right: 0;\n    padding: 24rpx;\n    background: var(--u-bg-color);\n    border-top: 1rpx solid var(--u-border-color);\n    box-shadow: 0 -4rpx 12rpx rgba(0, 0, 0, 0.05);\n}\n</style>\n"
  },
  {
    "path": "src/pages/template/address/addSite.vue",
    "content": "<template>\n    <demo-page hide-tabs show-wx-tips nav-title=\"新增地址\">\n        <view class=\"wrap\">\n            <view class=\"top\">\n                <view class=\"item\">\n                    <view class=\"left\">收货人</view>\n                    <input v-model=\"form.name\" type=\"text\" placeholder-class=\"line\" placeholder=\"请填写收货人姓名\" />\n                </view>\n                <view class=\"item\">\n                    <view class=\"left\">手机号码</view>\n                    <input v-model=\"form.phone\" type=\"text\" placeholder-class=\"line\" placeholder=\"请填写收货人手机号\" />\n                </view>\n                <view class=\"item\" @click=\"showRegionPicker\">\n                    <view class=\"left\">所在地区</view>\n                    <u-input\n                        type=\"select\"\n                        v-model=\"form.region\"\n                        readonly\n                        placeholder=\"省市区县、乡镇等\"\n                        @click=\"showRegionPicker\"\n                    ></u-input>\n                </view>\n                <view class=\"item address\">\n                    <view class=\"left\">详细地址</view>\n                    <textarea v-model=\"form.detail\" type=\"text\" placeholder-class=\"line\" placeholder=\"街道、楼牌等\" />\n                </view>\n                <!-- <view class=\"site-clipboard\">\n\t\t\t\t<textarea placeholder-class=\"line\" value=\"\" placeholder=\"粘贴文本,可自动识别姓名和地址等\" />\n\t\t\t\t<view class=\"clipboard\">\n\t\t\t\t\t地址粘贴板\n\t\t\t\t\t<u-icon name=\"arrow-down\" class=\"icon\" :size=\"20\"></u-icon>\n\t\t\t\t</view>\n\t\t\t</view> -->\n            </view>\n            <view class=\"bottom\">\n                <view class=\"tag\">\n                    <view class=\"left\">标签</view>\n                    <view class=\"right\">\n                        <text\n                            v-for=\"tag in tagOptions\"\n                            :key=\"tag\"\n                            class=\"tags\"\n                            :class=\"{ active: form.tags.includes(tag) }\"\n                            @click=\"toggleTag(tag)\"\n                        >\n                            {{ tag }}\n                        </text>\n                        <view class=\"tags plus\" @click=\"startAddTag\"><u-icon size=\"22\" name=\"plus\"></u-icon></view>\n                    </view>\n                </view>\n                <view v-if=\"editingTag\" class=\"tag-input\">\n                    <input\n                        v-model=\"newTag\"\n                        type=\"text\"\n                        placeholder-class=\"line\"\n                        placeholder=\"请输入标签名称\"\n                        confirm-type=\"done\"\n                        @confirm=\"addTag\"\n                    />\n                    <view class=\"tag-input-actions\">\n                        <u-button size=\"mini\" type=\"primary\" @click=\"addTag\">添加</u-button>\n                        <u-button size=\"mini\" type=\"info\" plain @click=\"cancelAddTag\">取消</u-button>\n                    </view>\n                </view>\n                <view class=\"default\">\n                    <view class=\"left\">\n                        <view class=\"set\">设置默认地址</view>\n                        <view class=\"tips\">提醒：每次下单会默认推荐该地址</view>\n                    </view>\n                    <view class=\"right\">\n                        <switch color=\"var(--u-type-primary)\" :checked=\"form.isDefault\" @change=\"setDefault\" />\n                    </view>\n                </view>\n            </view>\n            <view class=\"option\">\n                <u-button type=\"primary\" shape=\"circle\" @click=\"submit\">提交</u-button>\n            </view>\n            <u-picker mode=\"region\" ref=\"uPicker\" v-model=\"show\" @confirm=\"confirm\" />\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { onLoad } from '@dcloudio/uni-app';\nimport { $u } from '@/uni_modules/uview-pro';\n\nconst STORAGE_KEY = 'uview-address-list';\n\nconst tagOptions = ref<string[]>(['家', '公司', '学校']);\nconst form = ref({\n    id: '',\n    name: '',\n    phone: '',\n    region: '',\n    detail: '',\n    isDefault: false,\n    tags: [] as string[]\n});\n\n// 地区选择器显示状态\nconst show = ref(false);\n\n// 当前是否展示新增标签输入框\nconst editingTag = ref(false);\nconst newTag = ref('');\n\nfunction syncTagOptions(extraTags: string[] = []) {\n    extraTags.forEach(tag => {\n        const value = tag.trim();\n        if (value && !tagOptions.value.includes(value)) {\n            tagOptions.value.push(value);\n        }\n    });\n}\n\nfunction loadAddress(id: string) {\n    try {\n        const list = uni.getStorageSync(STORAGE_KEY) || [];\n        const target = Array.isArray(list) ? list.find((item: any) => item.id === id) : null;\n        if (target) {\n            form.value = {\n                id: target.id,\n                name: target.name,\n                phone: target.phone,\n                region: target.region,\n                detail: target.detail,\n                isDefault: !!target.isDefault,\n                tags: target.tags || []\n            };\n            syncTagOptions(form.value.tags);\n        }\n    } catch (error) {\n        console.warn('loadAddress error', error);\n    }\n}\n\nfunction setDefault() {\n    form.value.isDefault = !form.value.isDefault;\n}\n\nfunction showRegionPicker() {\n    show.value = true;\n}\nfunction confirm(e: any) {\n    form.value.region = e.province.label + '-' + e.city.label + '-' + e.area.label;\n}\n\nfunction toggleTag(tag: string) {\n    const exists = form.value.tags.includes(tag);\n    // 单选：选中则取消，未选中则仅保留当前标签\n    form.value.tags = exists ? [] : [tag];\n}\n\nfunction startAddTag() {\n    editingTag.value = true;\n    newTag.value = '';\n}\n\nfunction cancelAddTag() {\n    editingTag.value = false;\n    newTag.value = '';\n}\n\nfunction addTag() {\n    const value = newTag.value.trim();\n    if (!value) {\n        $u.toast('请输入标签名称');\n        return;\n    }\n    if (tagOptions.value.includes(value)) {\n        form.value.tags = form.value.tags.includes(value) ? [] : [value];\n        editingTag.value = false;\n        newTag.value = '';\n        return;\n    }\n    tagOptions.value.push(value);\n    // 新增即选中（单选）\n    form.value.tags = [value];\n    editingTag.value = false;\n    newTag.value = '';\n}\n\nfunction validate() {\n    if (!form.value.name.trim()) {\n        $u.toast('请填写收货人姓名');\n        return false;\n    }\n    if (!form.value.phone.trim()) {\n        $u.toast('请填写手机号');\n        return false;\n    }\n    if (!$u.test.mobile(form.value.phone)) {\n        $u.toast('手机号格式不正确');\n        return false;\n    }\n    if (!form.value.region.trim()) {\n        $u.toast('请选择地区');\n        return false;\n    }\n    if (!form.value.detail.trim()) {\n        $u.toast('请填写详细地址');\n        return false;\n    }\n    return true;\n}\n\nfunction submit() {\n    if (!validate()) return;\n    try {\n        const list = (uni.getStorageSync(STORAGE_KEY) || []) as any[];\n        let result = Array.isArray(list) ? [...list] : [];\n        if (form.value.isDefault) {\n            result = result.map(item => ({ ...item, isDefault: false }));\n        }\n        if (form.value.id) {\n            const idx = result.findIndex(item => item.id === form.value.id);\n            if (idx !== -1) {\n                result[idx] = { ...result[idx], ...form.value };\n            }\n        } else {\n            const newItem = { ...form.value, id: Date.now().toString() };\n            result.unshift(newItem);\n        }\n        uni.setStorageSync(STORAGE_KEY, result);\n        $u.toast('保存成功', 'success');\n        setTimeout(() => uni.navigateBack(), 300);\n    } catch (error) {\n        console.warn('save address error', error);\n        $u.toast('保存失败', 'error');\n    }\n}\n\nonLoad((options: any) => {\n    if (options && options.id) {\n        loadAddress(options.id);\n    }\n});\n</script>\n\n<style lang=\"scss\" scoped>\n::v-deep .line {\n    color: $u-light-color;\n    font-size: 28rpx;\n}\n.wrap {\n    .top {\n        background-color: $u-bg-white;\n        border-top: solid 2rpx $u-border-color;\n        padding: 22rpx;\n        .item {\n            display: flex;\n            font-size: 32rpx;\n            min-height: 100rpx;\n            align-items: center;\n            border-bottom: solid 2rpx $u-border-color;\n            .left {\n                width: 180rpx;\n            }\n            input {\n                text-align: left;\n            }\n        }\n\n        .address {\n            padding: 20rpx 0;\n            textarea {\n                // width: 100%;\n                height: 150rpx;\n                background-color: $u-bg-color;\n                line-height: 60rpx;\n                margin: 40rpx auto;\n                padding: 20rpx;\n            }\n        }\n        .site-clipboard {\n            padding-right: 40rpx;\n            textarea {\n                // width: 100%;\n                height: 150rpx;\n                background-color: $u-bg-color;\n                line-height: 60rpx;\n                margin: 40rpx auto;\n                padding: 20rpx;\n            }\n            .clipboard {\n                display: flex;\n                justify-content: center;\n                align-items: center;\n                font-size: 26rpx;\n                color: $u-tips-color;\n                height: 80rpx;\n                .icon {\n                    margin-top: 6rpx;\n                    margin-left: 10rpx;\n                }\n            }\n        }\n    }\n    .bottom {\n        margin-top: 20rpx;\n        padding: 40rpx;\n        padding-right: 0;\n        background-color: $u-bg-white;\n        font-size: 28rpx;\n        .tag {\n            display: flex;\n            .left {\n                width: 160rpx;\n            }\n            .right {\n                display: flex;\n                flex-wrap: wrap;\n                .tags {\n                    width: 140rpx;\n                    padding: 16rpx 8rpx;\n                    border: solid 2rpx $u-border-color;\n                    text-align: center;\n                    border-radius: 50rpx;\n                    margin: 0 10rpx 20rpx;\n                    display: flex;\n                    font-size: 28rpx;\n                    align-items: center;\n                    justify-content: center;\n                    color: $u-content-color;\n                    line-height: 1;\n                    &.active {\n                        border-color: $u-type-primary;\n                        color: $u-type-primary;\n                        background-color: rgba($u-type-primary, 0.08);\n                    }\n                }\n            }\n        }\n        .tag-input {\n            margin: 20rpx 10rpx 0;\n            padding: 20rpx;\n            border: solid 2rpx $u-border-color;\n            border-radius: 12rpx;\n            background-color: $u-bg-color;\n            input {\n                background: $u-bg-white;\n                padding: 16rpx 20rpx;\n                border-radius: 8rpx;\n            }\n            .tag-input-actions {\n                display: flex;\n                margin-top: 20rpx;\n                .u-button {\n                    margin-right: 16rpx;\n                }\n            }\n        }\n        .default {\n            margin-top: 50rpx;\n            display: flex;\n            justify-content: space-between;\n            border-bottom: solid 2rpx $u-border-color;\n            line-height: 64rpx;\n            .tips {\n                font-size: 24rpx;\n            }\n        }\n    }\n    .option {\n        background-color: $u-bg-white;\n        padding: 40rpx;\n        padding-bottom: 120rpx;\n    }\n}\n</style>\n"
  },
  {
    "path": "src/pages/template/address/index.vue",
    "content": "<template>\n    <demo-page hide-tabs nav-title=\"收货地址\">\n        <view class=\"wrap\">\n            <view class=\"item\" v-for=\"res in siteList\" :key=\"res.id\">\n                <view class=\"top\">\n                    <view class=\"name\">{{ res.name }}</view>\n                    <view class=\"phone\">{{ res.phone }}</view>\n                    <view class=\"tag\">\n                        <text v-if=\"res.isDefault\" class=\"red\">默认</text>\n                        <text v-for=\"(item, index) in res.tags\" :key=\"index\">{{ item }}</text>\n                    </view>\n                </view>\n                <view class=\"bottom\">\n                    <text class=\"addr\">{{ res.region }} {{ res.detail }}</text>\n                    <view class=\"actions\">\n                        <u-icon @click=\"editSite(res.id)\" name=\"edit-pen\" :size=\"40\" color=\"#999999\"></u-icon>\n                        <u-icon @click=\"deleteSite(res.id)\" name=\"trash\" :size=\"40\" color=\"#f56c6c\"></u-icon>\n                    </view>\n                </view>\n            </view>\n            <view v-if=\"!siteList.length\" class=\"empty\">\n                <u-gap height=\"200\"></u-gap>\n                <u-empty mode=\"list\" text=\"暂无地址，点击下方新增\" :show-empty=\"true\"></u-empty>\n            </view>\n            <view class=\"addSite\" @tap=\"toAddSite\">\n                <view class=\"add\">\n                    <u-icon name=\"plus\" color=\"#ffffff\" class=\"icon\" :size=\"30\"></u-icon>新建收货地址\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { $u } from 'uview-pro';\nimport { ref } from 'vue';\nimport { onShow } from '@dcloudio/uni-app';\n\nconst STORAGE_KEY = 'uview-address-list';\nconst siteList = ref<any[]>([]);\n\nfunction loadList() {\n    try {\n        const list = uni.getStorageSync(STORAGE_KEY) || [];\n        siteList.value = Array.isArray(list) ? list : [];\n    } catch (error) {\n        console.warn('load address list error', error);\n        siteList.value = [];\n    }\n}\n\nfunction toAddSite() {\n    uni.navigateTo({ url: '/pages/template/address/addSite' });\n}\n\nfunction editSite(id: string) {\n    uni.navigateTo({ url: `/pages/template/address/addSite?id=${id}` });\n}\n\nfunction deleteSite(id: string) {\n    uni.showModal({\n        title: '删除地址',\n        content: '确定要删除该地址吗？',\n        success: res => {\n            if (res.confirm) {\n                const list = siteList.value.filter(item => item.id !== id);\n                uni.setStorageSync(STORAGE_KEY, list);\n                siteList.value = list;\n                $u.toast('已删除', 'success');\n            }\n        }\n    });\n}\n\nonShow(loadList);\n</script>\n\n<style lang=\"scss\" scoped>\n.wrap {\n    background-color: $u-bg-white;\n}\n.item {\n    padding: 40rpx 20rpx;\n    .top {\n        display: flex;\n        font-weight: bold;\n        font-size: 34rpx;\n        .phone {\n            margin-left: 60rpx;\n        }\n        .tag {\n            display: flex;\n            font-weight: normal;\n            align-items: center;\n            text {\n                display: block;\n                width: 60rpx;\n                height: 34rpx;\n                line-height: 34rpx;\n                color: #ffffff;\n                font-size: 20rpx;\n                border-radius: 6rpx;\n                text-align: center;\n                margin-left: 30rpx;\n                background-color: rgb(49, 145, 253);\n            }\n            .red {\n                background-color: red;\n            }\n        }\n    }\n    .bottom {\n        display: flex;\n        margin-top: 20rpx;\n        font-size: 28rpx;\n        justify-content: space-between;\n        color: #999999;\n        .addr {\n            flex: 1;\n            padding-right: 20rpx;\n        }\n        .actions {\n            display: flex;\n            gap: 20rpx;\n        }\n    }\n}\n.addSite {\n    display: flex;\n    justify-content: space-around;\n    width: 600rpx;\n    line-height: 100rpx;\n    position: fixed;\n    bottom: calc(env(safe-area-inset-bottom) + 20px);\n    left: 50%;\n    transform: translateX(-50%);\n    background-color: red;\n    border-radius: 60rpx;\n    font-size: 30rpx;\n    .add {\n        display: flex;\n        align-items: center;\n        color: #ffffff;\n        .icon {\n            margin-right: 10rpx;\n        }\n    }\n}\n</style>\n"
  },
  {
    "path": "src/pages/template/citySelect/index.vue",
    "content": "<template>\n    <demo-page title=\"CitySelect 省市区选择\" desc=\"省市区选择示例\">\n        <view class=\"u-demo\">\n            <view class=\"u-demo-wrap\">\n                <view class=\"u-demo-title\">演示效果</view>\n                <view class=\"u-demo-area\">\n                    <u-city-select v-model=\"value\" @city-change=\"cityChange\"></u-city-select>\n                    <view class=\"u-demo-result-line\">{{ input ? input : 'Picker值' }}</view>\n                </view>\n            </view>\n            <view class=\"u-config-wrap\">\n                <view class=\"u-config-title u-border-bottom\">参数配置</view>\n                <view class=\"u-config-item\">\n                    <view class=\"u-item-title\">状态</view>\n                    <u-button @click=\"value = true\">打开Picker</u-button>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\n\n// Picker弹窗显示状态\nconst value = ref(false);\n// 选择结果字符串\nconst input = ref('');\n\n/**\n * 省市区选择回调\n * @param e 选中的省市区对象\n */\nfunction cityChange(e: any) {\n    input.value = e.province.label + '-' + e.city.label + '-' + e.area.label;\n}\n</script>\n\n<style scoped>\n.btn-wrap {\n    margin: 100rpx 30rpx;\n}\n</style>\n"
  },
  {
    "path": "src/pages/template/comment/index.vue",
    "content": "<template>\n    <demo-page hide-tabs nav-title=\"评论列表\">\n        <view>\n            <view class=\"comment\" v-for=\"(res, index) in commentList\" :key=\"res.id\">\n                <view class=\"left\"><image :src=\"res.url\" mode=\"aspectFill\"></image></view>\n                <view class=\"right\">\n                    <view class=\"top\">\n                        <view class=\"name\">{{ res.name }}</view>\n                        <view class=\"like\" :class=\"{ highlight: res.isLike }\">\n                            <view class=\"num\">{{ res.likeNum }}</view>\n                            <u-icon\n                                v-if=\"!res.isLike\"\n                                name=\"thumb-up\"\n                                :size=\"30\"\n                                color=\"#9a9a9a\"\n                                @click=\"getLike(index)\"\n                            ></u-icon>\n                            <u-icon v-if=\"res.isLike\" name=\"thumb-up-fill\" :size=\"30\" @click=\"getLike(index)\"></u-icon>\n                        </view>\n                    </view>\n                    <view class=\"content\">{{ res.contentText }}</view>\n                    <view class=\"reply-box\">\n                        <view class=\"item\" v-for=\"(item, index) in res.replyList\" :key=\"item.index\">\n                            <view class=\"username\">{{ item.name }}</view>\n                            <view class=\"text\">{{ item.contentStr }}</view>\n                        </view>\n                        <view class=\"all-reply\" @tap=\"toAllReply\" v-if=\"res.replyList != undefined\">\n                            共{{ res.allReply }}条回复\n                            <u-icon class=\"more\" name=\"arrow-right\" :size=\"26\"></u-icon>\n                        </view>\n                    </view>\n                    <view class=\"bottom\">\n                        {{ res.date }}\n                        <view class=\"reply\">回复</view>\n                    </view>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { $u } from 'uview-pro';\nimport { ref, onMounted } from 'vue';\n\n// 评论列表响应式\nconst commentList = ref<any[]>([]);\n\n/**\n * 跳转到全部回复页面\n */\nfunction toAllReply() {\n    uni.navigateTo({ url: '/pages/template/comment/reply' });\n}\n\n/**\n * 点赞/取消点赞\n * @param index 当前评论下标\n */\nfunction getLike(index: number) {\n    const item = commentList.value[index];\n    item.isLike = !item.isLike;\n    if (item.isLike) {\n        item.likeNum++;\n        $u.toast('点赞成功');\n    } else {\n        item.likeNum--;\n        $u.toast('取消点赞');\n    }\n}\n\n/**\n * 获取评论列表（模拟数据）\n */\nfunction getComment() {\n    commentList.value = [\n        {\n            id: 1,\n            name: '叶轻眉',\n            date: '12-25 18:58',\n            contentText: '我不信伊朗会没有后续反应，美国肯定会为今天的事情付出代价的',\n            url: 'https://ik.imagekit.io/anyup/uview-pro/template/SmilingDog.jpg',\n            allReply: 12,\n            likeNum: 33,\n            isLike: false,\n            replyList: [\n                {\n                    name: 'uview-pro',\n                    contentStr: 'uview-pro是基于uniapp的一个UI框架，代码优美简洁，宇宙超级无敌彩虹旋转好用，用它！'\n                },\n                {\n                    name: '粘粘',\n                    contentStr: '今天吃什么，明天吃什么，晚上吃什么，我只是一只小猫咪为什么要烦恼这么多'\n                }\n            ]\n        },\n        {\n            id: 2,\n            name: '叶轻眉1',\n            date: '01-25 13:58',\n            contentText: '我不信伊朗会没有后续反应，美国肯定会为今天的事情付出代价的',\n            allReply: 0,\n            likeNum: 11,\n            isLike: false,\n            url: 'https://ik.imagekit.io/anyup/uview-pro/template/niannian.jpg'\n        },\n        {\n            id: 3,\n            name: '叶轻眉2',\n            date: '03-25 13:58',\n            contentText: '我不信伊朗会没有后续反应，美国肯定会为今天的事情付出代价的',\n            allReply: 2,\n            likeNum: 21,\n            isLike: false,\n            url: '../../../static/logo.png',\n            replyList: [\n                {\n                    name: 'uView Pro',\n                    contentStr: 'uview-pro是基于uniapp的一个UI框架，代码优美简洁，宇宙超级无敌彩虹旋转好用，用它！'\n                },\n                {\n                    name: '豆包',\n                    contentStr: '想吃冰糖葫芦粘豆包，但没钱5555.........'\n                }\n            ]\n        },\n        {\n            id: 4,\n            name: '叶轻眉3',\n            date: '06-20 13:58',\n            contentText: '我不信伊朗会没有后续反应，美国肯定会为今天的事情付出代价的',\n            url: 'https://ik.imagekit.io/anyup/uview-pro/template/SmilingDog.jpg',\n            allReply: 0,\n            likeNum: 150,\n            isLike: false\n        }\n    ];\n}\n\n// 页面加载时获取评论\nonMounted(getComment);\n</script>\n\n<style lang=\"scss\" scoped>\n.comment {\n    display: flex;\n    padding: 30rpx;\n    .left {\n        image {\n            width: 64rpx;\n            height: 64rpx;\n            border-radius: 50%;\n            background-color: $u-bg-color;\n        }\n    }\n    .right {\n        flex: 1;\n        padding-left: 20rpx;\n        font-size: 30rpx;\n        .top {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            margin-bottom: 10rpx;\n            .name {\n                color: $u-type-primary;\n            }\n            .like {\n                display: flex;\n                align-items: center;\n                color: $u-tips-color;\n                font-size: 26rpx;\n                .num {\n                    margin-right: 4rpx;\n                    color: $u-tips-color;\n                }\n            }\n            .highlight {\n                color: $u-type-primary;\n                .num {\n                    color: $u-type-primary;\n                }\n            }\n        }\n        .content {\n            margin-bottom: 10rpx;\n        }\n        .reply-box {\n            background-color: $u-bg-color;\n            border-radius: 12rpx;\n            .item {\n                padding: 20rpx;\n                border-bottom: solid 2rpx $u-border-color;\n                .username {\n                    font-size: 24rpx;\n                    color: $u-tips-color;\n                }\n            }\n            .all-reply {\n                padding: 20rpx;\n                display: flex;\n                color: $u-type-primary;\n                align-items: center;\n                .more {\n                    margin-left: 6rpx;\n                }\n            }\n        }\n        .bottom {\n            margin-top: 20rpx;\n            display: flex;\n            font-size: 24rpx;\n            color: $u-tips-color;\n            .reply {\n                color: $u-type-primary;\n                margin-left: 10rpx;\n            }\n        }\n    }\n}\n</style>\n"
  },
  {
    "path": "src/pages/template/comment/reply.vue",
    "content": "<template>\n    <demo-page hide-tabs nav-title=\"评论列表\">\n        <view class=\"wrap\">\n            <view class=\"comment\">\n                <view class=\"top\">\n                    <view class=\"left\">\n                        <view class=\"heart-photo\"><image :src=\"comment.url\" mode=\"\"></image></view>\n                        <view class=\"user-info\">\n                            <view class=\"name\">{{ comment.name }}</view>\n                            <view class=\"date\">06-25 13:58</view>\n                        </view>\n                    </view>\n                    <view class=\"right\" :class=\"{ highlight: comment.isLike }\">\n                        {{ comment.likeNum }}\n                        <u-icon\n                            v-if=\"!comment.isLike\"\n                            name=\"thumb-up\"\n                            class=\"like\"\n                            color=\"$u-tips-color\"\n                            :size=\"30\"\n                            @click=\"getLike\"\n                        ></u-icon>\n                        <u-icon\n                            v-if=\"comment.isLike\"\n                            name=\"thumb-up-fill\"\n                            class=\"like\"\n                            :size=\"30\"\n                            @click=\"getLike\"\n                        ></u-icon>\n                    </view>\n                </view>\n                <view class=\"content\">{{ comment.contentText }}</view>\n            </view>\n            <view class=\"all-reply\">\n                <view class=\"all-reply-top\">全部回复（{{ comment.allReply }}）</view>\n                <view class=\"item\" v-for=\"(item, index) in commentList\" :key=\"index\">\n                    <view class=\"comment\">\n                        <view class=\"top\">\n                            <view class=\"left\">\n                                <view class=\"heart-photo\"><image :src=\"item.url\" mode=\"\"></image></view>\n                                <view class=\"user-info\">\n                                    <view class=\"name\">{{ item.name }}</view>\n                                    <view class=\"date\">{{ item.date }}</view>\n                                </view>\n                            </view>\n                            <view class=\"right\" :class=\"{ highlight: item.isLike }\">\n                                <view class=\"num\">{{ item.likeNum }}</view>\n                                <u-icon\n                                    v-if=\"!item.isLike\"\n                                    name=\"thumb-up\"\n                                    class=\"like\"\n                                    :size=\"30\"\n                                    color=\"$u-tips-color\"\n                                    @click=\"getLike(index)\"\n                                ></u-icon>\n                                <u-icon\n                                    v-if=\"item.isLike\"\n                                    name=\"thumb-up-fill\"\n                                    class=\"like\"\n                                    :size=\"30\"\n                                    @click=\"getLike(index)\"\n                                ></u-icon>\n                            </view>\n                        </view>\n                        <view class=\"reply\" v-if=\"item.reply\">\n                            <view class=\"username\">{{ item.reply.name }}</view>\n                            <view class=\"text\">{{ item.reply.contentStr }}</view>\n                        </view>\n                        <view class=\"content\">{{ item.contentText }}</view>\n                    </view>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { $u } from 'uview-pro';\nimport { ref, onMounted } from 'vue';\n\n// 主评论对象\nconst comment = ref<any>('');\n// 回复列表\nconst commentList = ref<any[]>([]);\n\n/**\n * 点赞/取消点赞\n * @param index 可选，指定为回复的下标，否则为主评论\n */\nfunction getLike(index?: number) {\n    if (typeof index === 'number') {\n        // 回复点赞\n        const item = commentList.value[index];\n        item.isLike = !item.isLike;\n        if (item.isLike) {\n            item.likeNum++;\n            $u.toast('点赞成功');\n        } else {\n            item.likeNum--;\n            $u.toast('取消点赞');\n        }\n    } else {\n        // 主评论点赞\n        comment.value.isLike = !comment.value.isLike;\n        if (comment.value.isLike) {\n            comment.value.likeNum++;\n            $u.toast('点赞成功');\n        } else {\n            comment.value.likeNum--;\n            $u.toast('取消点赞');\n        }\n    }\n}\n\n/**\n * 获取主评论和全部回复（模拟数据）\n */\nfunction getReply() {\n    comment.value = {\n        id: 1,\n        name: '叶轻眉',\n        date: '12-25 18:58',\n        contentText: '我不信伊朗会没有后续反应，美国肯定会为今天的事情付出代价的',\n        url: 'https://ik.imagekit.io/anyup/uview-pro/template/SmilingDog.jpg',\n        allReply: 12,\n        likeNum: 33,\n        isLike: false\n    };\n    commentList.value = [\n        {\n            name: '新八几',\n            date: '12-25 18:58',\n            contentText: '不要乱打广告啊喂！虽然是真的超好用',\n            url: 'https://ik.imagekit.io/anyup/uview-pro/template/SmilingDog.jpg',\n            likeNum: 33,\n            isLike: false,\n            reply: {\n                name: 'uview-pro',\n                contentStr: 'uview-pro是基于uniapp的一个UI框架，代码优美简洁，宇宙超级无敌彩虹旋转好用，用它！'\n            }\n        },\n        {\n            name: '叶轻眉1',\n            date: '01-25 13:58',\n            url: 'https://ik.imagekit.io/anyup/uview-pro/template/SmilingDog.jpg',\n            contentText: '我不信伊朗会没有后续反应，美国肯定会为今天的事情付出代价的',\n            allReply: 0,\n            likeNum: 11,\n            isLike: false,\n            reply: {\n                name: '粘粘',\n                contentStr: '今天吃什么，明天吃什么，晚上吃什么，我只是一只小猫咪为什么要烦恼这么多'\n            }\n        },\n        {\n            name: '叶轻眉2',\n            date: '03-25 13:58',\n            contentText: '我不信伊朗会没有后续反应，美国肯定会为今天的事情付出代价的',\n            likeNum: 21,\n            url: 'https://ik.imagekit.io/anyup/uview-pro/template/SmilingDog.jpg',\n            isLike: false,\n            allReply: 2,\n            reply: {\n                name: '豆包',\n                contentStr: '想吃冰糖葫芦粘豆包，但没钱5555.........'\n            }\n        },\n        {\n            name: '叶轻眉3',\n            date: '06-20 13:58',\n            contentText: '我不信伊朗会没有后续反应，美国肯定会为今天的事情付出代价的',\n            allReply: 0,\n            likeNum: 150,\n            url: 'https://ik.imagekit.io/anyup/uview-pro/template/SmilingDog.jpg',\n            isLike: false\n        }\n    ];\n}\n\n// 页面加载时获取数据\nonMounted(getReply);\n</script>\n\n<style lang=\"scss\" scoped>\npage {\n    background-color: $u-bg-color;\n}\n.comment {\n    padding: 30rpx;\n    font-size: 32rpx;\n    background-color: $u-bg-white;\n    .top {\n        display: flex;\n        justify-content: space-between;\n    }\n    .left {\n        display: flex;\n        .heart-photo {\n            image {\n                width: 64rpx;\n                height: 64rpx;\n                border-radius: 50%;\n                background-color: $u-bg-color;\n            }\n        }\n        .user-info {\n            margin-left: 10rpx;\n            .name {\n                color: $u-type-primary;\n                font-size: 28rpx;\n                margin-bottom: 4rpx;\n            }\n            .date {\n                font-size: 20rpx;\n                color: $u-light-color;\n            }\n        }\n    }\n    .right {\n        display: flex;\n        font-size: 20rpx;\n        align-items: center;\n        color: $u-tips-color;\n        .like {\n            margin-left: 6rpx;\n        }\n        .num {\n            font-size: 26rpx;\n            color: $u-tips-color;\n        }\n    }\n    .highlight {\n        color: $u-type-primary;\n        .num {\n            color: $u-type-primary;\n        }\n    }\n}\n.all-reply {\n    margin-top: 10rpx;\n    padding-top: 20rpx;\n    background-color: $u-bg-white;\n    .all-reply-top {\n        margin-left: 20rpx;\n        padding-left: 20rpx;\n        border-left: solid 4rpx $u-type-primary;\n        font-size: 30rpx;\n        font-weight: bold;\n    }\n    .item {\n        border-bottom: solid 2rpx $u-border-color;\n    }\n    .reply {\n        padding: 20rpx;\n        background-color: $u-bg-color;\n        border-radius: 12rpx;\n        margin: 10rpx 0;\n        .username {\n            font-size: 24rpx;\n            color: $u-content-color;\n        }\n    }\n}\n</style>\n"
  },
  {
    "path": "src/pages/template/coupon/index.vue",
    "content": "<template>\n    <demo-page hide-tabs nav-title=\"优惠券\">\n        <view class=\"u-wrap\">\n            <view class=\"meituan\">\n                <view class=\"content\">\n                    <view class=\"left\">\n                        <view class=\"sum\">\n                            ￥\n                            <text class=\"num\">8</text>\n                        </view>\n                        <view class=\"type\">抵用券</view>\n                    </view>\n                    <view class=\"centre\">\n                        <view class=\"title\">【洗牙】8元无门槛红包</view>\n                        <view class=\"valid-date\">今日到期</view>\n                    </view>\n                    <view class=\"right\">\n                        <view size=\"mini\" class=\"immediate-use\" :round=\"true\" @click=\"onEnterShop\">立即使用</view>\n                    </view>\n                </view>\n                <view class=\"tips\">\n                    <view class=\"circle-left\"></view>\n                    <view class=\"circle-right\"></view>\n                    <view class=\"explain u-line-1\">满8.1元可用、限最新版本客户端使用</view>\n                    <view class=\"rule u-line-1\" @tap=\"onRuleClick\">\n                        <text>使用规则</text>\n                        <u-icon name=\"arrow-right\" color=\"\" :size=\"20\"></u-icon>\n                    </view>\n                </view>\n            </view>\n            <view class=\"jingdong\">\n                <view class=\"left\">\n                    <view class=\"sum\">\n                        ￥\n                        <text class=\"num\">100</text>\n                    </view>\n                    <view class=\"type\">满149元可用</view>\n                </view>\n                <view class=\"right\">\n                    <view class=\"top\">\n                        <view class=\"title\">\n                            <text class=\"tag\">限品类东券</text>\n                            <text>仅可购买个人护理部分商品</text>\n                        </view>\n                        <view class=\"bottom\">\n                            <view class=\"date u-line-1\">2020.01.01-2020.01.31</view>\n                            <view class=\"immediate-use\">立即使用</view>\n                        </view>\n                    </view>\n                    <view class=\"tips\">\n                        <view class=\"explain\">\n                            <u-icon name=\"zhuanfa\" class=\"transpond\" :size=\"24\"></u-icon>\n                            <text>可赠送</text>\n                        </view>\n                    </view>\n                </view>\n            </view>\n            <view class=\"taobao\">\n                <view class=\"title\">\n                    <view class=\"left\">\n                        <image\n                            class=\"buddha\"\n                            src=\"https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1975388697,1068670603&fm=26&gp=0.jpg\"\n                            mode=\"aspectFill\"\n                        ></image>\n                        <view class=\"store\">袜子精保护协会</view>\n                    </view>\n                    <view class=\"entrance\" @click=\"$u.toast('点击进店')\">进店</view>\n                </view>\n                <view class=\"ticket\">\n                    <view class=\"left\">\n                        <image\n                            class=\"picture\"\n                            src=\"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1578059523488&di=5f592ac19c1b983005d3e85add469756&imgtype=0&src=http%3A%2F%2Fimg010.hc360.cn%2Fg7%2FM00%2F2D%2FB9%2FwKhQs1QfUo6EdeM-AAAAALwk1hM072.jpg\"\n                            mode=\"widthFix\"\n                        ></image>\n                        <view class=\"introduce\">\n                            <view class=\"top\">\n                                ￥\n                                <text class=\"big\">3</text>\n                                满88减3\n                            </view>\n                            <view class=\"type\">店铺优惠券</view>\n                            <view class=\"date u-line-1\">2019.11.28-2020.1.24</view>\n                        </view>\n                    </view>\n                    <view class=\"right\">\n                        <view class=\"use immediate-use\" :round=\"true\" @tap=\"onUseCoupon\">去使用</view>\n                    </view>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { $u } from 'uview-pro';\n// 示例：点击“使用规则”事件\nfunction onRuleClick() {\n    // TODO: 可弹窗或跳转规则说明\n    $u.toast('点击了使用规则');\n}\n\n// 示例：点击“进店”事件\nfunction onEnterShop() {\n    // TODO: 可跳转店铺页面\n    $u.toast('点击了进店');\n}\n\n// 示例：点击“去使用”事件\nfunction onUseCoupon() {\n    // TODO: 跳转到使用优惠券页面\n    $u.toast('点击了去使用');\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.u-wrap {\n    padding: 24rpx;\n}\n\n.meituan {\n    margin: 30rpx auto;\n    background-color: $u-bg-white;\n    width: 700rpx;\n    // border: 10rpx;\n    color: $u-type-warning;\n    font-size: 28rpx;\n    .content {\n        display: flex;\n        align-items: center;\n        padding: 80rpx 20rpx;\n        border: 10rpx;\n        background-color: $u-bg-color;\n        .left {\n            .sum {\n                font-size: 32rpx;\n                .num {\n                    font-size: 60rpx;\n                    font-weight: bold;\n                }\n            }\n        }\n        .centre {\n            margin-left: 40rpx;\n            .title {\n                font-size: 32rpx;\n                font-weight: bold;\n                color: $u-main-color;\n                margin-bottom: 20rpx;\n            }\n        }\n        .right {\n            margin-left: 30rpx;\n            .immediate-use {\n                padding: 0 20rpx;\n                height: 50rpx;\n                border-radius: 25rpx;\n                line-height: 50rpx;\n                background-color: $u-type-warning !important;\n                color: #ffffff !important;\n                font-size: 24rpx;\n                border: none;\n                word-break: keep-all;\n            }\n        }\n    }\n    .tips {\n        padding: 0 20rpx;\n        border: 10rpx;\n        background-color: $u-type-info-light;\n        position: relative;\n        color: $u-tips-color;\n        display: flex;\n        justify-content: space-between;\n        line-height: 60rpx;\n        font-size: 24rpx;\n        .circle-left,\n        .circle-right {\n            position: absolute;\n            height: 36rpx;\n            width: 18rpx;\n            background-color: $u-bg-color;\n        }\n\n        .circle-right {\n            border-radius: 40rpx 0 0 40rpx;\n            right: 0;\n            top: -18rpx;\n        }\n\n        .circle-left {\n            border-radius: 0 40rpx 40rpx 0;\n            left: 0;\n            top: -18rpx;\n        }\n        .rule {\n            font-size: 24rpx;\n            display: flex;\n            align-items: center;\n            text {\n                margin-right: 10rpx;\n                flex: 1;\n            }\n        }\n    }\n}\n\n.jingdong {\n    margin-top: 40rpx;\n    width: 700rpx;\n    height: auto;\n    background-color: $u-bg-white;\n    display: flex;\n    .left {\n        padding: 0 30rpx;\n        background-color: $u-type-primary; //rgb(94, 152, 225);\n        text-align: center;\n        font-size: 28rpx;\n        color: $u-white-color;\n        .sum {\n            margin-top: 50rpx;\n            font-weight: bold;\n            font-size: 32rpx;\n            white-space: nowrap;\n            .num {\n                font-size: 80rpx;\n            }\n        }\n        .type {\n            margin-bottom: 50rpx;\n            font-size: 24rpx;\n        }\n    }\n    .right {\n        padding: 20rpx 20rpx 0;\n        font-size: 28rpx;\n        .top {\n            border-bottom: 2rpx dashed $u-border-color;\n            .title {\n                margin-right: 60rpx;\n                line-height: 40rpx;\n                .tag {\n                    padding: 4rpx 20rpx;\n                    background-color: $u-type-primary;\n                    border-radius: 20rpx;\n                    color: $u-white-color;\n                    font-weight: bold;\n                    font-size: 24rpx;\n                    margin-right: 10rpx;\n                }\n            }\n            .bottom {\n                display: flex;\n                margin-top: 20rpx;\n                align-items: center;\n                justify-content: space-between;\n                margin-bottom: 10rpx;\n                .date {\n                    font-size: 20rpx;\n                    flex: 1;\n                }\n                .immediate-use {\n                    height: auto;\n                    padding: 0 20rpx;\n                    font-size: 24rpx;\n                    border-radius: 40rpx;\n                    line-height: 40rpx;\n                    color: $u-type-primary-disabled;\n                    border: 2rpx solid $u-type-primary-disabled;\n                }\n            }\n        }\n        .tips {\n            width: 100%;\n            line-height: 50rpx;\n            display: flex;\n            align-items: center;\n            justify-content: space-between;\n            font-size: 24rpx;\n            .transpond {\n                margin-right: 10rpx;\n            }\n            .explain {\n                display: flex;\n                align-items: center;\n            }\n            .particulars {\n                width: 30rpx;\n                height: 30rpx;\n                box-sizing: border-box;\n                padding-top: 8rpx;\n                border-radius: 50%;\n                background-color: $u-type-info-disabled;\n                text-align: center;\n            }\n        }\n    }\n}\n\n.taobao {\n    margin-top: 40rpx;\n    width: 700rpx;\n    background-color: $u-bg-white;\n    padding: 30rpx 20rpx 20rpx;\n    border-radius: 20rpx;\n    .title {\n        display: flex;\n        align-items: center;\n        justify-content: space-between;\n        margin-bottom: 20rpx;\n        font-size: 30rpx;\n        .left {\n            display: flex;\n            align-items: center;\n        }\n        .store {\n            font-weight: 500;\n        }\n        .buddha {\n            width: 70rpx;\n            height: 70rpx;\n            border-radius: 10rpx;\n            margin-right: 10rpx;\n        }\n        .entrance {\n            color: $u-type-info;\n            border: solid 2rpx $u-type-info;\n            line-height: 48rpx;\n            padding: 0 30rpx;\n            background: none;\n            border-radius: 15px;\n        }\n    }\n    .ticket {\n        display: flex;\n        .left {\n            width: 70%;\n            padding: 30rpx 20rpx;\n            background-color: $u-bg-white;\n            border-radius: 20rpx;\n            border-right: dashed 2rpx $u-white-color;\n            display: flex;\n            .picture {\n                width: 172rpx;\n                border-radius: 20rpx;\n                height: 160rpx;\n            }\n            .introduce {\n                margin-left: 10rpx;\n                .top {\n                    color: $u-type-warning;\n                    font-size: 28rpx;\n                    .big {\n                        font-size: 60rpx;\n                        font-weight: bold;\n                        margin-right: 10rpx;\n                    }\n                }\n                .type {\n                    font-size: 28rpx;\n                    color: $u-type-info-dark;\n                }\n                .date {\n                    margin-top: 10rpx;\n                    font-size: 20rpx;\n                    color: $u-type-info-dark;\n                }\n            }\n        }\n        .right {\n            width: 30%;\n            padding: 40rpx 20rpx;\n            background-color: $u-bg-white;\n            border-radius: 20rpx;\n            display: flex;\n            align-items: center;\n            .use {\n                height: auto;\n                padding: 0 20rpx;\n                font-size: 24rpx;\n                border-radius: 40rpx;\n                color: $u-white-color !important;\n                background-color: $u-type-warning !important;\n                line-height: 40rpx;\n                color: $u-type-primary-light;\n                margin-left: 20rpx;\n            }\n        }\n    }\n}\n</style>\n"
  },
  {
    "path": "src/pages/template/detail/index.vue",
    "content": "<template>\n    <demo-page hide-tabs :nav-title=\"templateTitle\" :nav-back=\"true\">\n        <view class=\"template-detail\">\n            <!-- 模板预览区域 -->\n            <view class=\"preview-section\">\n                <view class=\"preview-header\">\n                    <view class=\"preview-title\">\n                        <text class=\"title-text\">{{ templateTitle }}</text>\n                        <u-tag\n                            v-if=\"isHot\"\n                            text=\"热门\"\n                            type=\"error\"\n                            size=\"mini\"\n                            custom-style=\"margin-left: 12rpx\"\n                        ></u-tag>\n                        <u-tag\n                            v-if=\"isNew\"\n                            text=\"新品\"\n                            type=\"success\"\n                            size=\"mini\"\n                            custom-style=\"margin-left: 12rpx\"\n                        ></u-tag>\n                    </view>\n                    <view class=\"preview-desc\">{{ templateDesc }}</view>\n                </view>\n\n                <view class=\"preview-content\">\n                    <u-image :src=\"previewImage\" mode=\"widthFix\" width=\"100%\" :lazy-load=\"true\" :fade=\"true\"></u-image>\n                </view>\n            </view>\n\n            <!-- 操作按钮组 -->\n            <view class=\"action-section\">\n                <u-button type=\"primary\" @click=\"handlePreview\" icon=\"eye\" shape=\"circle\"> 预览模板 </u-button>\n                <u-button v-if=\"codeLink\" type=\"success\" @click=\"handleDownload\" icon=\"download\" shape=\"circle\" plain>\n                    下载代码\n                </u-button>\n                <u-button type=\"warning\" @click=\"handleShare\" icon=\"share\" shape=\"circle\" plain> 分享模板 </u-button>\n            </view>\n\n            <!-- 模板信息 -->\n            <u-card title=\"模板信息\" :border=\"false\">\n                <template #body>\n                    <view class=\"info-list\">\n                        <view class=\"info-item\">\n                            <view class=\"info-label\">模板类型</view>\n                            <view class=\"info-value\">{{ templateType }}</view>\n                        </view>\n                        <view class=\"info-item\">\n                            <view class=\"info-label\">下载次数</view>\n                            <view class=\"info-value\">{{ downloadCount }}</view>\n                        </view>\n                        <view class=\"info-item\">\n                            <view class=\"info-label\">评分</view>\n                            <view class=\"info-value\">\n                                <u-rate\n                                    :current=\"rating\"\n                                    :size=\"32\"\n                                    disabled\n                                    active-color=\"#ffa502\"\n                                    allow-half\n                                ></u-rate>\n                                <text style=\"margin-left: 12rpx\">{{ rating }}</text>\n                            </view>\n                        </view>\n                        <view class=\"info-item\">\n                            <view class=\"info-label\">更新时间</view>\n                            <view class=\"info-value\">{{ updateTime }}</view>\n                        </view>\n                    </view>\n                </template>\n            </u-card>\n\n            <!-- 使用说明 -->\n            <u-card title=\"使用说明\" :border=\"false\">\n                <template #body>\n                    <view class=\"usage-content\">\n                        <view class=\"usage-item\">\n                            <u-icon name=\"checkmark-circle\" size=\"32\" color=\"var(--u-type-success)\"></u-icon>\n                            <text>点击\"预览模板\"按钮查看模板效果</text>\n                        </view>\n                        <view v-if=\"codeLink\" class=\"usage-item\">\n                            <u-icon name=\"checkmark-circle\" size=\"32\" color=\"var(--u-type-success)\"></u-icon>\n                            <text>点击\"下载代码\"获取模板源代码</text>\n                        </view>\n                        <view class=\"usage-item\">\n                            <u-icon name=\"checkmark-circle\" size=\"32\" color=\"var(--u-type-success)\"></u-icon>\n                            <text>点击\"分享模板\"将模板分享给他人</text>\n                        </view>\n                    </view>\n                </template>\n            </u-card>\n\n            <!-- 相关模板推荐 -->\n            <u-card title=\"相关推荐\" :border=\"false\" v-if=\"relatedTemplates.length > 0\">\n                <template #body>\n                    <view class=\"related-list\">\n                        <view\n                            v-for=\"item in relatedTemplates\"\n                            :key=\"item.path\"\n                            class=\"related-item\"\n                            @click=\"openRelatedTemplate(item.path)\"\n                        >\n                            <u-image\n                                :src=\"getPreviewImage(item)\"\n                                mode=\"aspectFit\"\n                                width=\"120\"\n                                height=\"120\"\n                                radius=\"8\"\n                            ></u-image>\n                            <view class=\"related-info\">\n                                <view class=\"related-title\">{{ item.title }}</view>\n                                <view class=\"related-desc\">{{ item.desc }}</view>\n                            </view>\n                        </view>\n                    </view>\n                </template>\n            </u-card>\n\n            <u-action-sheet v-model=\"show\" :safe-area-inset-bottom=\"true\">\n                <u-action-sheet-item text=\"复制分享链接\" @click=\"copyShareLink()\" />\n                <u-action-sheet-item padding=\"0\">\n                    <u-text\n                        text=\"分享给朋友\"\n                        size=\"32\"\n                        openType=\"share\"\n                        :block=\"true\"\n                        line-height=\"50px\"\n                        align=\"center\"\n                    ></u-text>\n                </u-action-sheet-item>\n            </u-action-sheet>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, computed } from 'vue';\nimport { onLoad } from '@dcloudio/uni-app';\nimport { $u } from '@/uni_modules/uview-pro';\nimport templateConfig from '@/pages/example/template.config';\n\nconst templatePath = ref('');\nconst templateTitle = ref('');\nconst templateDesc = ref('');\nconst previewImage = ref('');\nconst isHot = ref(false);\nconst isNew = ref(true);\nconst downloadCount = ref(0);\nconst rating = ref(4.5);\nconst updateTime = ref('2024-01-01');\nconst relatedTemplates = ref<any[]>([]);\nconst codeLink = ref('');\nconst shareLink = ref('');\nconst show = ref(false);\n\n// 模板类型\nconst templateType = computed(() => {\n    if (templatePath.value.includes('mallMenu') || templatePath.value.includes('order')) {\n        return '页面模板';\n    }\n    return '部件模板';\n});\n\n// 获取预览图\nfunction getPreviewImage(tpl: any) {\n    if (tpl.previewImage) {\n        return tpl.previewImage;\n    }\n    const iconName = tpl.icon || 'template';\n    // #ifdef APP\n    return `/static/app/template/${iconName}.png`;\n    // #endif\n    return `https://ik.imagekit.io/anyup/uview-pro/template/${iconName}.png`;\n}\n\n// 预览模板\nfunction handlePreview() {\n    if (!templatePath.value) {\n        $u.toast('模板路径无效', 'error');\n        return;\n    }\n    uni.navigateTo({\n        url: templatePath.value\n    });\n}\n\n// 复制代码链接\nfunction copyCodeLink() {\n    if (!codeLink.value) return;\n    uni.setClipboardData({\n        data: codeLink.value,\n        success: () => {\n            $u.toast('代码链接已复制', 'success');\n            // 记录下载次数\n            downloadCount.value += 1;\n            saveDownloadCount();\n        }\n    });\n}\n\n// 复制分享链接\nfunction copyShareLink() {\n    if (!shareLink.value) return;\n    uni.setClipboardData({\n        data: shareLink.value,\n        success: () => {\n            $u.toast('分享链接已复制', 'success');\n        }\n    });\n}\n\n// 打开相关模板\nfunction openRelatedTemplate(path: string) {\n    uni.navigateTo({\n        url: path.indexOf('/page') == 0 ? path : '/pages/template/' + path + '/index'\n    });\n}\n\n// 保存下载次数\nfunction saveDownloadCount() {\n    try {\n        const key = `template-download-${templatePath.value}`;\n        uni.setStorageSync(key, downloadCount.value);\n    } catch (error) {\n        console.warn('saveDownloadCount error', error);\n    }\n}\n\n// 加载下载次数\nfunction loadDownloadCount() {\n    try {\n        const key = `template-download-${templatePath.value}`;\n        const count = uni.getStorageSync(key);\n        if (count) {\n            downloadCount.value = count;\n        }\n    } catch (error) {\n        console.warn('loadDownloadCount error', error);\n    }\n}\n\n// 加载相关模板\nfunction loadRelatedTemplates() {\n    try {\n        const allTemplates: any[] = [];\n        templateConfig.forEach((group: any) => {\n            (group.list || []).forEach((tpl: any) => {\n                allTemplates.push(tpl);\n            });\n        });\n\n        // 排除当前模板，随机选择3个\n        const filtered = allTemplates.filter(tpl => {\n            const tplPath = tpl.path.indexOf('/page') == 0 ? tpl.path : '/pages/template/' + tpl.path + '/index';\n            return tplPath !== templatePath.value;\n        });\n\n        // 随机选择\n        const shuffled = filtered.sort(() => 0.5 - Math.random());\n        relatedTemplates.value = shuffled.slice(0, 3);\n    } catch (error) {\n        console.warn('loadRelatedTemplates error', error);\n    }\n}\n\nonLoad((options: any) => {\n    if (options.path) {\n        templatePath.value = decodeURIComponent(options.path);\n    }\n    if (options.title) {\n        templateTitle.value = decodeURIComponent(options.title);\n    }\n    if (options.desc) {\n        templateDesc.value = decodeURIComponent(options.desc);\n    }\n\n    // 从配置中查找模板信息\n    let templateInfo: any = null;\n    templateConfig.forEach((group: any) => {\n        (group.list || []).forEach((tpl: any) => {\n            const tplPath = tpl.path.indexOf('/page') == 0 ? tpl.path : '/pages/template/' + tpl.path + '/index';\n            if (tplPath === templatePath.value) {\n                templateInfo = tpl;\n            }\n        });\n    });\n\n    // 设置预览与链接\n    if (templateInfo) {\n        previewImage.value = getPreviewImage(templateInfo);\n        if (templateInfo.isHot) isHot.value = true;\n        if (templateInfo.isNew) isNew.value = true;\n        if (templateInfo.downloadCount) downloadCount.value = templateInfo.downloadCount;\n        if (templateInfo.rating) rating.value = templateInfo.rating;\n        if (templateInfo.codeLink) codeLink.value = templateInfo.codeLink;\n        if (templateInfo.shareLink) shareLink.value = templateInfo.shareLink;\n    } else {\n        const slug = templatePath.value.split('/').pop() || 'template';\n        previewImage.value = getPreviewImage({ icon: slug });\n    }\n\n    // 加载数据\n    loadDownloadCount();\n    loadRelatedTemplates();\n\n    // 设置更新时间\n    updateTime.value = new Date().toLocaleDateString('zh-CN');\n});\n\nfunction handleDownload() {\n    uni.showActionSheet({\n        itemList: ['复制下载链接'],\n        success: res => {\n            copyCodeLink();\n        }\n    });\n}\n\nfunction handleShare() {\n    show.value = true;\n    // uni.showActionSheet({\n    //     itemList: ['复制分享链接'],\n    //     success: res => {\n    //         copyShareLink();\n    //     }\n    // });\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.template-detail {\n    padding: 24rpx;\n    background: linear-gradient(180deg, rgba(41, 121, 255, 0.02) 0%, transparent 100%);\n}\n\n.preview-section {\n    margin-bottom: 24rpx;\n    background: var(--u-bg-color);\n    border-radius: 20rpx;\n    overflow: hidden;\n    box-shadow: 0 8rpx 24rpx rgba(41, 121, 255, 0.1);\n}\n\n.preview-header {\n    padding: 24rpx;\n    border-bottom: 1rpx solid var(--u-border-color);\n}\n\n.preview-title {\n    display: flex;\n    align-items: center;\n    margin-bottom: 12rpx;\n}\n\n.title-text {\n    font-size: 36rpx;\n    font-weight: 600;\n    color: var(--u-main-color);\n}\n\n.preview-desc {\n    font-size: 26rpx;\n    color: var(--u-content-color);\n    line-height: 1.6;\n}\n\n.preview-content {\n    padding: 20rpx;\n    background: $u-bg-color;\n}\n\n.action-section {\n    display: flex;\n    gap: 20rpx;\n    margin-bottom: 24rpx;\n}\n\n.info-list {\n    display: flex;\n    flex-direction: column;\n    gap: 24rpx;\n}\n\n.info-item {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    padding: 16rpx 0;\n    border-bottom: 1rpx solid var(--u-border-color);\n\n    &:last-child {\n        border-bottom: none;\n    }\n}\n\n.info-label {\n    font-size: 28rpx;\n    color: var(--u-content-color);\n}\n\n.info-value {\n    font-size: 28rpx;\n    color: var(--u-main-color);\n    font-weight: 500;\n    display: flex;\n    align-items: center;\n}\n\n.usage-content {\n    display: flex;\n    flex-direction: column;\n    gap: 20rpx;\n}\n\n.usage-item {\n    display: flex;\n    align-items: center;\n    gap: 16rpx;\n    font-size: 26rpx;\n    color: var(--u-content-color);\n    line-height: 1.6;\n}\n\n.related-list {\n    display: flex;\n    flex-direction: column;\n    gap: 20rpx;\n}\n\n.related-item {\n    display: flex;\n    gap: 20rpx;\n    padding: 16rpx;\n    background: rgba(41, 121, 255, 0.05);\n    border-radius: 12rpx;\n    transition: all 0.3s ease;\n\n    &:active {\n        transform: scale(0.98);\n        background: rgba(41, 121, 255, 0.1);\n    }\n}\n\n.related-info {\n    flex: 1;\n    display: flex;\n    flex-direction: column;\n    justify-content: center;\n}\n\n.related-title {\n    font-size: 28rpx;\n    font-weight: 600;\n    color: var(--u-main-color);\n    margin-bottom: 8rpx;\n}\n\n.related-desc {\n    font-size: 24rpx;\n    color: var(--u-content-color);\n    line-height: 1.5;\n    display: -webkit-box;\n    -webkit-box-orient: vertical;\n    -webkit-line-clamp: 2;\n    line-clamp: 2;\n    overflow: hidden;\n}\n</style>\n"
  },
  {
    "path": "src/pages/template/keyboardPay/index.vue",
    "content": "<template>\n    <demo-page hide-tabs show-wx-tips nav-title=\"支付键盘\">\n        <view class=\"wrap\">\n            <view class=\"u-padding-40\">\n                <u-button type=\"success\" @click=\"showPop(true)\">\n                    <u-icon name=\"red-packet\"></u-icon>\n                    <text class=\"u-padding-left-10\">发送1.00元红包</text>\n                </u-button>\n            </view>\n            <u-keyboard\n                default=\"\"\n                ref=\"uKeyboard\"\n                mode=\"number\"\n                :mask=\"true\"\n                :mask-close-able=\"false\"\n                :dot-enabled=\"false\"\n                v-model=\"show\"\n                :safe-area-inset-bottom=\"true\"\n                :tooltip=\"false\"\n                @change=\"onChange\"\n                @backspace=\"onBackspace\"\n            >\n                <view>\n                    <view class=\"u-text-center u-padding-20 money\">\n                        <text>1.00</text>\n                        <text class=\"u-font-20 u-padding-left-10\">元</text>\n                        <view class=\"u-padding-10 close\" data-flag=\"false\" @tap=\"showPop(false)\">\n                            <u-icon name=\"close\" color=\"#333333\" size=\"28\"></u-icon>\n                        </view>\n                    </view>\n                    <view class=\"u-flex u-row-center\">\n                        <u-message-input\n                            mode=\"box\"\n                            :maxlength=\"6\"\n                            :dot-fill=\"true\"\n                            :value=\"password\"\n                            :disabled-keyboard=\"true\"\n                            @finish=\"finish\"\n                        ></u-message-input>\n                    </view>\n                    <view class=\"u-text-center u-padding-top-10 u-padding-bottom-20 tips\">支付键盘</view>\n                </view>\n            </u-keyboard>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\n\n// 支付弹窗显示状态\nconst show = ref(false);\n// 支付密码\nconst password = ref('');\n\n/**\n * 键盘输入事件\n * @param val 输入的数字\n */\nfunction onChange(val: string) {\n    if (password.value.length < 6) {\n        password.value += val;\n    }\n    if (password.value.length >= 6) {\n        pay();\n    }\n}\n\n/**\n * 键盘退格事件\n */\nfunction onBackspace() {\n    if (password.value.length > 0) {\n        password.value = password.value.substring(0, password.value.length - 1);\n    }\n}\n\n/**\n * 支付逻辑\n */\nfunction pay() {\n    uni.showLoading({ title: '支付中' });\n    setTimeout(() => {\n        uni.hideLoading();\n        show.value = false;\n        uni.showToast({ icon: 'success', title: '支付成功' });\n    }, 2000);\n}\n\n/**\n * 显示/关闭支付弹窗\n * @param flag 是否显示\n */\nfunction showPop(flag = true) {\n    password.value = '';\n    show.value = flag;\n}\n\n/**\n * 密码输入完成事件\n */\nfunction finish() {\n    // 可扩展：自动提交等\n    console.log('密码输入完成');\n}\n</script>\n\n<style lang=\"scss\">\n.money {\n    font-size: 80rpx;\n    color: $u-type-warning;\n    position: relative;\n\n    .close {\n        position: absolute;\n        top: 20rpx;\n        right: 20rpx;\n        line-height: 28rpx;\n        font-size: 28rpx;\n    }\n}\n.tips {\n    color: $u-tips-color;\n}\n</style>\n"
  },
  {
    "path": "src/pages/template/login/code.vue",
    "content": "<template>\n    <demo-page hide-tabs nav-title=\"登录\">\n        <view class=\"wrap\">\n            <view class=\"key-input\">\n                <view class=\"title\">输入验证码</view>\n                <view class=\"tips\">验证码已发送至 +150****9320</view>\n                <u-message-input\n                    :focus=\"true\"\n                    :value=\"value\"\n                    @change=\"change\"\n                    @finish=\"finish\"\n                    mode=\"bottomLine\"\n                    :maxlength=\"maxlength\"\n                ></u-message-input>\n                <text :class=\"{ error: error }\">验证码错误，请重新输入</text>\n                <view class=\"captcha\">\n                    <text :class=\"{ noCaptcha: show }\" @tap=\"noCaptcha\">收不到验证码点这里</text>\n                    <text :class=\"{ regain: !show }\">{{ second }}秒后重新获取验证码</text>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted } from 'vue';\n\n// 验证码最大长度\nconst maxlength = 4;\n// 输入的验证码\nconst value = ref('');\n// 倒计时秒数\nconst second = ref(5);\n// 是否显示“收不到验证码”\nconst show = ref(false);\n// 是否显示错误提示\nconst error = ref(false);\n\n/**\n * 倒计时逻辑，结束后显示“收不到验证码”\n */\nonMounted(() => {\n    const interval = setInterval(() => {\n        second.value--;\n        if (second.value <= 0) {\n            show.value = true;\n            if (value.value.length !== 4) {\n                error.value = true;\n            }\n            clearInterval(interval);\n        }\n    }, 1000);\n});\n\n/**\n * 收不到验证码时的操作\n */\nfunction noCaptcha() {\n    uni.showActionSheet({\n        itemList: ['重新获取验证码', '接听语音验证码'],\n        success: function (res) {\n            // 可根据选择处理\n        },\n        fail: function (res) {}\n    });\n}\n\n/**\n * 验证码输入变化事件\n */\nfunction change(val: string) {\n    // console.log('change', val);\n}\n\n/**\n * 验证码输入完成事件\n */\nfunction finish(val: string) {\n    // console.log('finish', val);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.wrap {\n    padding: 80rpx;\n}\n\n.box {\n    margin: 30rpx 0;\n    font-size: 30rpx;\n    color: 555;\n}\n\n.key-input {\n    padding: 30rpx 0;\n    text {\n        display: none;\n    }\n    .error {\n        display: block;\n        color: red;\n        font-size: 30rpx;\n        margin: 20rpx 0;\n    }\n}\n\n.title {\n    font-size: 50rpx;\n    color: #333;\n}\n\n.key-input .tips {\n    font-size: 30rpx;\n    color: #333;\n    margin-top: 20rpx;\n    margin-bottom: 60rpx;\n}\n.captcha {\n    color: $u-type-warning;\n    font-size: 30rpx;\n    margin-top: 40rpx;\n    .noCaptcha {\n        display: block;\n    }\n    .regain {\n        display: block;\n    }\n}\n</style>\n"
  },
  {
    "path": "src/pages/template/login/index.vue",
    "content": "<template>\n    <demo-page hide-tabs nav-title=\"登录\">\n        <view class=\"wrap\">\n            <view class=\"top\"></view>\n            <view class=\"content\">\n                <view class=\"title\">欢迎登录美团</view>\n                <input class=\"u-border-bottom\" type=\"number\" v-model=\"tel\" placeholder=\"请输入手机号\" />\n                <view class=\"tips\">未注册的手机号验证后自动创建美团账号</view>\n                <button @tap=\"submit\" :style=\"[inputStyle]\" class=\"getCaptcha\">获取短信验证码</button>\n                <view class=\"alternative\">\n                    <view class=\"password\" @click=\"$u.toast('密码登录')\">密码登录</view>\n                    <view class=\"issue\" @click=\"$u.toast('遇到问题')\">遇到问题</view>\n                </view>\n            </view>\n            <view class=\"loginBottom\">\n                <view class=\"loginType\">\n                    <view class=\"wechat item\" @click=\"$u.toast('微信登录')\">\n                        <view class=\"icon\"><u-icon size=\"70\" name=\"weixin-fill\" color=\"rgb(83,194,64)\"></u-icon></view>\n                        微信\n                    </view>\n                    <view class=\"QQ item\" @click=\"$u.toast('QQ登录')\">\n                        <view class=\"icon\"><u-icon size=\"70\" name=\"qq-fill\" color=\"rgb(17,183,233)\"></u-icon></view>\n                        QQ\n                    </view>\n                </view>\n                <view class=\"hint\">\n                    登录代表同意\n                    <text class=\"link\">美团点评用户协议、隐私政策，</text>\n                    并授权使用您的美团点评账号信息（如昵称、头像、收获地址）以便您统一管理\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { $u } from '@/uni_modules/uview-pro';\nimport { ref, computed } from 'vue';\n\n// 手机号输入\nconst tel = ref('');\n\n/**\n * 按钮样式动态计算\n */\nconst inputStyle = computed(() => {\n    const style: Record<string, string> = {};\n    if (tel.value) {\n        style.color = '#fff';\n        style.backgroundColor = (uni as any).$u?.color?.warning || '#f90';\n    }\n    return style;\n});\n\n/**\n * 提交手机号，校验通过跳转验证码页\n */\nfunction submit() {\n    if (!$u.test.mobile(tel.value)) {\n        $u.toast('手机号格式不正确');\n        return;\n    }\n    $u.route({ url: 'pages/template/login/code' });\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.wrap {\n    font-size: 28rpx;\n    .content {\n        width: 600rpx;\n        margin: 0 auto;\n\n        .title {\n            text-align: left;\n            font-size: 60rpx;\n            font-weight: 500;\n            margin-bottom: 100rpx;\n        }\n        input {\n            text-align: left;\n            margin-bottom: 10rpx;\n            padding-bottom: 6rpx;\n        }\n        .tips {\n            color: $u-type-info;\n            margin-bottom: 60rpx;\n            margin-top: 8rpx;\n        }\n        .getCaptcha {\n            background-color: rgb(253, 243, 208);\n            color: $u-tips-color;\n            border: none;\n            font-size: 30rpx;\n            padding: 12rpx 0;\n\n            &::after {\n                border: none;\n            }\n        }\n        .alternative {\n            color: $u-tips-color;\n            display: flex;\n            justify-content: space-between;\n            margin-top: 30rpx;\n        }\n    }\n    .loginBottom {\n        .loginType {\n            display: flex;\n            padding: 350rpx 150rpx 150rpx 150rpx;\n            justify-content: space-between;\n\n            .item {\n                display: flex;\n                flex-direction: column;\n                align-items: center;\n                color: $u-content-color;\n                font-size: 28rpx;\n            }\n        }\n\n        .hint {\n            padding: 20rpx 40rpx;\n            font-size: 20rpx;\n            color: $u-tips-color;\n\n            .link {\n                color: $u-type-warning;\n            }\n        }\n    }\n}\n</style>\n"
  },
  {
    "path": "src/pages/template/mallMenu/index1.vue",
    "content": "<template>\n    <demo-page hide-tabs hide-ad nav-title=\"分类\">\n        <view class=\"u-wrap\">\n            <view class=\"u-search-box\">\n                <u-search\n                    v-model=\"searchText\"\n                    placeholder=\"搜索商品\"\n                    shape=\"round\"\n                    @search=\"handleSearch\"\n                    @custom=\"handleSearch\"\n                ></u-search>\n            </view>\n            <view class=\"u-menu-wrap\">\n                <scroll-view scroll-y scroll-with-animation class=\"u-tab-view menu-scroll-view\" :scroll-top=\"scrollTop\">\n                    <view\n                        v-for=\"(item, index) in tabbar\"\n                        :key=\"index\"\n                        class=\"u-tab-item\"\n                        :class=\"[current == index ? 'u-tab-item-active' : '']\"\n                        :data-current=\"index\"\n                        @tap.stop=\"switchMenu(index)\"\n                    >\n                        <text class=\"u-line-1\">{{ item.name }}</text>\n                    </view>\n                </scroll-view>\n                <block v-for=\"(item, index) in tabbar\" :key=\"index\">\n                    <scroll-view scroll-y class=\"right-box\" v-if=\"current == index\">\n                        <view class=\"page-view\">\n                            <view class=\"class-item\">\n                                <view class=\"item-title\">\n                                    <text>{{ item.name }}</text>\n                                </view>\n                                <view class=\"item-container\">\n                                    <view\n                                        class=\"thumb-box\"\n                                        :class=\"{ 'thumb-box--match': isMatch(item1) }\"\n                                        v-for=\"(item1, index1) in item.foods\"\n                                        :key=\"index1\"\n                                    >\n                                        <image class=\"item-menu-image\" :src=\"item1.icon\" mode=\"\"></image>\n                                        <view\n                                            class=\"item-menu-name\"\n                                            :class=\"{ 'item-menu-name--match': isMatch(item1) }\"\n                                        >\n                                            {{ item1.name }}\n                                        </view>\n                                    </view>\n                                </view>\n                            </view>\n                        </view>\n                    </scroll-view>\n                </block>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, getCurrentInstance, computed } from 'vue';\nimport classifyDataRaw from '@/common/classify.data';\nimport { $u } from 'uview-pro';\n\n// 分类数据类型声明\ninterface FoodItem {\n    icon: string;\n    name: string;\n}\ninterface TabItem {\n    name: string;\n    foods: FoodItem[];\n}\n\nconst classifyData = classifyDataRaw as TabItem[];\nconst instance = getCurrentInstance();\nconst searchText = ref('');\n// 左侧菜单数据\nconst tabbar = ref<TabItem[]>(classifyData);\n// 左侧菜单滚动条位置\nconst scrollTop = ref(0);\n// 当前选中菜单下标\nconst current = ref(0);\n// 左侧菜单整体高度\nconst menuHeight = ref(0);\n// 单个菜单项高度\nconst menuItemHeight = ref(0);\nconst keyword = computed(() => searchText.value.trim().toLowerCase());\n\nfunction handleSearch() {\n    if (!keyword.value) return;\n    const idx = tabbar.value.findIndex(item =>\n        (item.foods || []).some(food => food.name.toLowerCase().includes(keyword.value))\n    );\n    if (idx !== -1) {\n        switchMenu(idx);\n    } else {\n        $u.toast('没有找到该商品');\n    }\n}\n\nfunction isMatch(food: FoodItem) {\n    if (!keyword.value) return false;\n    return food.name.toLowerCase().includes(keyword.value);\n}\n\n/**\n * 点击左侧菜单切换\n */\nasync function switchMenu(index: number) {\n    if (!tabbar.value.length) return;\n    if (index === current.value) return;\n    current.value = index;\n    // 如果为0，意味着尚未初始化\n    if (menuHeight.value === 0 || menuItemHeight.value === 0) {\n        await getElRect('menu-scroll-view', 'menuHeight');\n        await getElRect('u-tab-item', 'menuItemHeight');\n    }\n    // 将菜单活动item垂直居中\n    scrollTop.value = index * menuItemHeight.value + menuItemHeight.value / 2 - menuHeight.value / 2;\n}\n\n/**\n * 获取元素高度（严格 TS 类型）\n */\nfunction getElRect(elClass: string, dataVal: 'menuHeight' | 'menuItemHeight'): Promise<void> {\n    return new Promise<void>(resolve => {\n        const query = uni.createSelectorQuery().in(instance?.proxy!);\n        query\n            .select('.' + elClass)\n            .fields({ size: true }, (res: any) => {\n                // TS严格：res 可能为 NodeInfo | NodeInfo[] | null，且 height 可能为 undefined\n                const height = Array.isArray(res) ? res[0]?.height : res?.height;\n                if (typeof height !== 'number') {\n                    setTimeout(() => {\n                        getElRect(elClass, dataVal);\n                    }, 10);\n                    return;\n                }\n                if (dataVal === 'menuHeight') menuHeight.value = height;\n                if (dataVal === 'menuItemHeight') menuItemHeight.value = height;\n                resolve();\n            })\n            .exec();\n    });\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.u-wrap {\n    height: 100vh;\n    /* #ifdef MP-WEIXIN */\n    height: calc(100vh - var(--status-bar-height) - 70px);\n    /* #endif */\n    /* #ifdef H5 */\n    height: calc(100vh - var(--window-top) - 44px);\n    /* #endif */\n    display: flex;\n    flex-direction: column;\n}\n\n.u-search-box {\n    padding: 18rpx 30rpx;\n}\n\n.u-menu-wrap {\n    flex: 1;\n    display: flex;\n    overflow: hidden;\n}\n\n.u-tab-view {\n    width: 200rpx;\n    height: 100%;\n}\n\n.u-tab-item {\n    height: 110rpx;\n    background: $u-bg-color;\n    box-sizing: border-box;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    font-size: 26rpx;\n    color: $u-main-color;\n    font-weight: 400;\n    line-height: 1;\n}\n\n.u-tab-item-active {\n    position: relative;\n    color: $u-black-color;\n    font-size: 30rpx;\n    font-weight: 600;\n    background-color: $u-bg-white;\n}\n\n.u-tab-item-active::before {\n    content: '';\n    position: absolute;\n    border-left: 4px solid $u-type-primary;\n    height: 32rpx;\n    left: 0;\n    top: 39rpx;\n}\n\n.u-tab-view {\n    height: 100%;\n}\n\n.right-box {\n    background-color: $u-bg-white;\n}\n\n.page-view {\n    padding: 16rpx;\n}\n\n.class-item {\n    margin-bottom: 30rpx;\n    background-color: $u-bg-white;\n    padding: 16rpx;\n    border-radius: 8rpx;\n}\n\n.item-title {\n    font-size: 26rpx;\n    color: $u-main-color;\n    font-weight: bold;\n}\n\n.item-menu-name {\n    font-weight: normal;\n    font-size: 24rpx;\n    color: $u-main-color;\n}\n\n.item-container {\n    display: flex;\n    flex-wrap: wrap;\n}\n\n.thumb-box {\n    width: 33.333333%;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    flex-direction: column;\n    margin-top: 20rpx;\n}\n\n.thumb-box--match {\n    border: 2rpx solid $u-type-primary;\n    border-radius: 12rpx;\n    padding: 8rpx;\n}\n\n.item-menu-image {\n    width: 120rpx;\n    height: 120rpx;\n}\n\n.item-menu-name--match {\n    color: $u-type-primary;\n    font-weight: 700;\n}\n</style>\n"
  },
  {
    "path": "src/pages/template/mallMenu/index2.vue",
    "content": "<template>\n    <demo-page hide-tabs hide-ad nav-title=\"分类\">\n        <view class=\"u-wrap\">\n            <view class=\"u-search-box\">\n                <u-search\n                    v-model=\"searchText\"\n                    placeholder=\"搜索商品\"\n                    shape=\"round\"\n                    @search=\"handleSearch\"\n                    @custom=\"handleSearch\"\n                ></u-search>\n            </view>\n            <view class=\"u-menu-wrap\">\n                <scroll-view\n                    scroll-y\n                    scroll-with-animation\n                    class=\"u-tab-view menu-scroll-view\"\n                    :scroll-top=\"scrollTop\"\n                    :scroll-into-view=\"itemId\"\n                >\n                    <view\n                        v-for=\"(item, index) in tabbar\"\n                        :key=\"index\"\n                        class=\"u-tab-item\"\n                        :class=\"[current == index ? 'u-tab-item-active' : '']\"\n                        @tap.stop=\"switchMenu(index)\"\n                    >\n                        <text class=\"u-line-1\">{{ item.name }}</text>\n                    </view>\n                </scroll-view>\n                <scroll-view\n                    :scroll-top=\"scrollRightTop\"\n                    scroll-y\n                    scroll-with-animation\n                    class=\"right-box\"\n                    @scroll=\"rightScroll\"\n                >\n                    <view class=\"page-view\">\n                        <view class=\"class-item\" :id=\"'item' + index\" v-for=\"(item, index) in tabbar\" :key=\"index\">\n                            <view class=\"item-title\">\n                                <text>{{ item.name }}</text>\n                            </view>\n                            <view class=\"item-container\">\n                                <view\n                                    class=\"thumb-box\"\n                                    :class=\"{ 'thumb-box--match': isMatch(item1) }\"\n                                    v-for=\"(item1, index1) in item.foods\"\n                                    :key=\"index1\"\n                                    @click=\"$u.toast(`点击商品：${item1.name}`)\"\n                                >\n                                    <image class=\"item-menu-image\" :src=\"item1.icon\" mode=\"\"></image>\n                                    <view class=\"item-menu-name\" :class=\"{ 'item-menu-name--match': isMatch(item1) }\">\n                                        {{ item1.name }}\n                                    </view>\n                                </view>\n                            </view>\n                        </view>\n                    </view>\n                </scroll-view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n<script setup lang=\"ts\">\nimport { ref, nextTick, onMounted, getCurrentInstance, computed } from 'vue';\nimport classifyDataRaw from '@/common/classify.data';\nimport { $u } from 'uview-pro';\n\n// 分类数据类型声明\ninterface FoodItem {\n    icon: string;\n    name: string;\n}\ninterface TabItem {\n    name: string;\n    foods: FoodItem[];\n}\n\nconst classifyData = classifyDataRaw as TabItem[];\nconst tabbar = ref<TabItem[]>(classifyData);\nconst searchText = ref('');\nconst keyword = computed(() => searchText.value.trim().toLowerCase());\n// 左侧菜单滚动条位置\nconst scrollTop = ref<number>(0);\n// 记录上次右侧滚动条位置\nconst oldScrollTop = ref<number>(0);\n// 当前选中菜单下标\nconst current = ref<number>(0);\n// 左侧菜单整体高度\nconst menuHeight = ref<number>(0);\n// 单个菜单项高度\nconst menuItemHeight = ref<number>(0);\n// 右侧scroll-view用于滚动的id\nconst itemId = ref<string>('');\n// 右侧每个item到顶部的距离\nconst menuItemPos = ref<number[]>([]);\n// 右侧每个item的top数组\nconst arr = ref<number[]>([]);\n// 右侧scroll-view的滚动条高度\nconst scrollRightTop = ref<number>(0);\n// 节流定时器\nconst timer = ref<ReturnType<typeof setTimeout> | null>(null);\n\nconst instance = getCurrentInstance();\n\nonMounted(() => {\n    getMenuItemTop();\n});\n\nfunction handleSearch() {\n    if (!keyword.value) return;\n    const idx = tabbar.value.findIndex(item =>\n        (item.foods || []).some(food => food.name.toLowerCase().includes(keyword.value))\n    );\n    if (idx !== -1) {\n        switchMenu(idx);\n    } else {\n        $u.toast('没有找到该商品');\n    }\n}\n\nfunction isMatch(food: FoodItem) {\n    if (!keyword.value) return false;\n    return food.name.toLowerCase().includes(keyword.value);\n}\n\n/**\n * 点击左侧菜单切换\n */\nasync function switchMenu(index: number) {\n    if (!tabbar.value.length) return;\n    if (arr.value.length === 0) {\n        await getMenuItemTop();\n    }\n    if (index === current.value) return;\n    scrollRightTop.value = oldScrollTop.value;\n    await nextTick();\n    scrollRightTop.value = arr.value[index];\n    current.value = index;\n    leftMenuStatus(index);\n}\n\n/**\n * 获取元素高度（严格 TS 类型）\n */\nfunction getElRect(elClass: string, dataVal: 'menuHeight' | 'menuItemHeight'): Promise<void> {\n    return new Promise<void>(resolve => {\n        const query = uni.createSelectorQuery().in(instance?.proxy!);\n        query\n            .select('.' + elClass)\n            .fields({ size: true }, (res: any) => {\n                // TS严格：res 可能为 NodeInfo | NodeInfo[] | null，且 height 可能为 undefined\n                const height = Array.isArray(res) ? res[0]?.height : res?.height;\n                if (typeof height !== 'number') {\n                    setTimeout(() => {\n                        getElRect(elClass, dataVal);\n                    }, 10);\n                    return;\n                }\n                if (dataVal === 'menuHeight') menuHeight.value = height;\n                if (dataVal === 'menuItemHeight') menuItemHeight.value = height;\n                resolve();\n            })\n            .exec();\n    });\n}\n\n/**\n * 设置左侧菜单的滚动状态\n */\nasync function leftMenuStatus(index: number) {\n    current.value = index;\n    if (menuHeight.value === 0 || menuItemHeight.value === 0) {\n        await getElRect('menu-scroll-view', 'menuHeight');\n        await getElRect('u-tab-item', 'menuItemHeight');\n    }\n    scrollTop.value = index * menuItemHeight.value + menuItemHeight.value / 2 - menuHeight.value / 2;\n}\n\n/**\n * 获取右侧每个item到顶部的距离（严格 TS 类型）\n */\nfunction getMenuItemTop(): Promise<void> {\n    return new Promise<void>(resolve => {\n        const selectorQuery = uni.createSelectorQuery().in(instance?.proxy!);\n        selectorQuery\n            .selectAll('.class-item')\n            .boundingClientRect((rects: any) => {\n                // rects 可能为 NodeInfo[] 或 NodeInfo | null\n                if (!rects || !Array.isArray(rects) || !rects.length) {\n                    setTimeout(() => {\n                        getMenuItemTop();\n                    }, 10);\n                    return;\n                }\n                arr.value = [];\n                rects.forEach((rect: any, i: number) => {\n                    arr.value.push(rect.top - rects[0].top);\n                });\n                resolve();\n            })\n            .exec();\n    });\n}\n\n/**\n * 右侧菜单滚动事件\n */\nasync function rightScroll(e: { detail: { scrollTop: number } }) {\n    oldScrollTop.value = e.detail.scrollTop;\n    if (arr.value.length === 0) {\n        await getMenuItemTop();\n    }\n    if (timer.value) return;\n    if (!menuHeight.value) {\n        await getElRect('menu-scroll-view', 'menuHeight');\n    }\n    timer.value = setTimeout(() => {\n        timer.value = null;\n        const scrollHeight = e.detail.scrollTop + menuHeight.value / 2;\n        for (let i = 0; i < arr.value.length; i++) {\n            const height1 = arr.value[i];\n            const height2 = arr.value[i + 1];\n            if (!height2 || (scrollHeight >= height1 && scrollHeight < height2)) {\n                leftMenuStatus(i);\n                return;\n            }\n        }\n    }, 10);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.u-wrap {\n    height: 100vh;\n    /* #ifdef MP-WEIXIN */\n    height: calc(100vh - var(--status-bar-height) - 70px);\n    /* #endif */\n    /* #ifdef H5 */\n    height: calc(100vh - var(--window-top) - 44px);\n    /* #endif */\n    display: flex;\n    flex-direction: column;\n}\n\n.u-search-box {\n    padding: 18rpx 30rpx;\n}\n\n.u-menu-wrap {\n    flex: 1;\n    display: flex;\n    overflow: hidden;\n}\n\n.u-tab-view {\n    width: 200rpx;\n    height: 100%;\n}\n\n.u-tab-item {\n    height: 110rpx;\n    background: $u-bg-color;\n    box-sizing: border-box;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    font-size: 26rpx;\n    color: $u-main-color;\n    font-weight: 400;\n    line-height: 1;\n}\n\n.u-tab-item-active {\n    position: relative;\n    color: $u-black-color;\n    font-size: 30rpx;\n    font-weight: 600;\n    background-color: $u-bg-white;\n}\n\n.u-tab-item-active::before {\n    content: '';\n    position: absolute;\n    border-left: 4px solid $u-type-primary;\n    height: 32rpx;\n    left: 0;\n    top: 39rpx;\n}\n\n.u-tab-view {\n    height: 100%;\n}\n\n.right-box {\n    background-color: $u-bg-white;\n}\n\n.page-view {\n    padding: 16rpx;\n}\n\n.class-item {\n    margin-bottom: 30rpx;\n    background-color: $u-bg-white;\n    padding: 16rpx;\n    border-radius: 8rpx;\n}\n\n.class-item:last-child {\n    min-height: 100vh;\n}\n\n.item-title {\n    font-size: 26rpx;\n    color: $u-main-color;\n    font-weight: bold;\n}\n\n.item-menu-name {\n    font-weight: normal;\n    font-size: 24rpx;\n    color: $u-main-color;\n}\n\n.item-container {\n    display: flex;\n    flex-wrap: wrap;\n}\n\n.thumb-box {\n    width: 33.333333%;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    flex-direction: column;\n    margin-top: 20rpx;\n}\n\n.thumb-box--match {\n    border: 2rpx solid $u-type-primary;\n    border-radius: 12rpx;\n    padding: 8rpx;\n}\n\n.item-menu-image {\n    width: 120rpx;\n    height: 120rpx;\n}\n\n.item-menu-name--match {\n    color: $u-type-primary;\n    font-weight: 700;\n}\n</style>\n"
  },
  {
    "path": "src/pages/template/order/index.vue",
    "content": "<template>\n    <demo-page hide-tabs show-wx-tips nav-title=\"订单列表\">\n        <view>\n            <view class=\"wrap\">\n                <view class=\"u-tabs-box\">\n                    <u-tabs-swiper\n                        activeColor=\"#f29100\"\n                        ref=\"tabs\"\n                        :list=\"list\"\n                        :current=\"current\"\n                        @change=\"change\"\n                        :is-scroll=\"false\"\n                        swiperWidth=\"750\"\n                    ></u-tabs-swiper>\n                </view>\n                <swiper\n                    class=\"swiper-box\"\n                    :current=\"swiperCurrent\"\n                    @transition=\"transition\"\n                    @animationfinish=\"animationfinish\"\n                >\n                    <!-- 待付款 -->\n                    <swiper-item class=\"swiper-item\">\n                        <scroll-view scroll-y style=\"height: 100%; width: 100%\" @scrolltolower=\"reachBottom\">\n                            <view class=\"page-box\">\n                                <view class=\"order\" v-for=\"(res, index) in orderList[0]\" :key=\"res.id\">\n                                    <view class=\"top\">\n                                        <view class=\"left\">\n                                            <u-icon name=\"home\" :size=\"30\" color=\"rgb(94,94,94)\"></u-icon>\n                                            <view class=\"store\">{{ res.store }}</view>\n                                            <u-icon name=\"arrow-right\" color=\"rgb(203,203,203)\" :size=\"26\"></u-icon>\n                                        </view>\n                                        <view class=\"right\">{{ res.deal }}</view>\n                                    </view>\n                                    <view class=\"item\" v-for=\"(item, idx) in res.goodsList\" :key=\"idx\">\n                                        <view class=\"left\"><image :src=\"item.goodsUrl\" mode=\"aspectFill\"></image></view>\n                                        <view class=\"content\">\n                                            <view class=\"title u-line-2\">{{ item.title }}</view>\n                                            <view class=\"type\">{{ item.type }}</view>\n                                            <view class=\"delivery-time\">发货时间 {{ item.deliveryTime }}</view>\n                                        </view>\n                                        <view class=\"right\">\n                                            <view class=\"price\">\n                                                ￥{{ priceInt(item.price) }}\n                                                <text class=\"decimal\">.{{ priceDecimal(item.price) }}</text>\n                                            </view>\n                                            <view class=\"number\">x{{ item.number }}</view>\n                                        </view>\n                                    </view>\n                                    <view class=\"total\">\n                                        共{{ totalNum(res.goodsList) }}件商品 合计:\n                                        <text class=\"total-price\">\n                                            ￥{{ priceInt(totalPrice(res.goodsList)) }}.\n                                            <text class=\"decimal\">{{ priceDecimal(totalPrice(res.goodsList)) }}</text>\n                                        </text>\n                                    </view>\n                                    <view class=\"bottom\">\n                                        <view class=\"more\">\n                                            <u-icon name=\"more-dot-fill\" color=\"rgb(203,203,203)\"></u-icon>\n                                        </view>\n                                        <view class=\"logistics btn\" @click=\"$u.toast('查看物流')\">查看物流</view>\n                                        <view class=\"exchange btn\" @click=\"$u.toast('卖了换钱')\">卖了换钱</view>\n                                        <view class=\"evaluate btn\" @click=\"$u.toast('评价')\">评价</view>\n                                    </view>\n                                </view>\n                                <u-loadmore :status=\"loadStatus[0]\" bgColor=\"#f2f2f2\"></u-loadmore>\n                            </view>\n                        </scroll-view>\n                    </swiper-item>\n                    <!-- 待发货 -->\n                    <swiper-item class=\"swiper-item\">\n                        <scroll-view scroll-y style=\"height: 100%; width: 100%\" @scrolltolower=\"reachBottom\">\n                            <view class=\"page-box\">\n                                <view class=\"order\" v-for=\"(res, index) in orderList[1]\" :key=\"res.id\">\n                                    <view class=\"top\">\n                                        <view class=\"left\">\n                                            <u-icon name=\"home\" :size=\"30\" color=\"rgb(94,94,94)\"></u-icon>\n                                            <view class=\"store\">{{ res.store }}</view>\n                                            <u-icon name=\"arrow-right\" color=\"rgb(203,203,203)\" :size=\"26\"></u-icon>\n                                        </view>\n                                        <view class=\"right\">{{ res.deal }}</view>\n                                    </view>\n                                    <view class=\"item\" v-for=\"(item, idx) in res.goodsList\" :key=\"idx\">\n                                        <view class=\"left\"><image :src=\"item.goodsUrl\" mode=\"aspectFill\"></image></view>\n                                        <view class=\"content\">\n                                            <view class=\"title u-line-2\">{{ item.title }}</view>\n                                            <view class=\"type\">{{ item.type }}</view>\n                                            <view class=\"delivery-time\">发货时间 {{ item.deliveryTime }}</view>\n                                        </view>\n                                        <view class=\"right\">\n                                            <view class=\"price\">\n                                                ￥{{ priceInt(item.price) }}\n                                                <text class=\"decimal\">.{{ priceDecimal(item.price) }}</text>\n                                            </view>\n                                            <view class=\"number\">x{{ item.number }}</view>\n                                        </view>\n                                    </view>\n                                    <view class=\"total\">\n                                        共{{ totalNum(res.goodsList) }}件商品 合计:\n                                        <text class=\"total-price\">\n                                            ￥{{ priceInt(totalPrice(res.goodsList)) }}.\n                                            <text class=\"decimal\">{{ priceDecimal(totalPrice(res.goodsList)) }}</text>\n                                        </text>\n                                    </view>\n                                    <view class=\"bottom\">\n                                        <view class=\"more\">\n                                            <u-icon name=\"more-dot-fill\" color=\"rgb(203,203,203)\"></u-icon>\n                                        </view>\n                                        <view class=\"logistics btn\" @click=\"$u.toast('查看物流')\">查看物流</view>\n                                        <view class=\"exchange btn\" @click=\"$u.toast('卖了换钱')\">卖了换钱</view>\n                                        <view class=\"evaluate btn\" @click=\"$u.toast('评价')\">评价</view>\n                                    </view>\n                                </view>\n                                <u-loadmore :status=\"loadStatus[1]\" bgColor=\"#f2f2f2\"></u-loadmore>\n                            </view>\n                        </scroll-view>\n                    </swiper-item>\n                    <!-- 待收货（无数据） -->\n                    <swiper-item class=\"swiper-item\">\n                        <scroll-view scroll-y style=\"height: 100%; width: 100%\">\n                            <view class=\"page-box\">\n                                <view>\n                                    <view class=\"centre\">\n                                        <image\n                                            src=\"https://ik.imagekit.io/anyup/uview-pro/template/taobao-order.png\"\n                                            mode=\"\"\n                                        ></image>\n                                        <view class=\"explain\">\n                                            您还没有相关的订单\n                                            <view class=\"tips\">可以去看看有那些想买的</view>\n                                        </view>\n                                        <view class=\"btn\" @click=\"$u.toast('随便逛逛')\">随便逛逛</view>\n                                    </view>\n                                </view>\n                            </view>\n                        </scroll-view>\n                    </swiper-item>\n                    <!-- 待评价 -->\n                    <swiper-item class=\"swiper-item\">\n                        <scroll-view scroll-y style=\"height: 100%; width: 100%\" @scrolltolower=\"reachBottom\">\n                            <view class=\"page-box\">\n                                <view class=\"order\" v-for=\"(res, index) in orderList[3]\" :key=\"res.id\">\n                                    <view class=\"top\">\n                                        <view class=\"left\">\n                                            <u-icon name=\"home\" :size=\"30\" color=\"rgb(94,94,94)\"></u-icon>\n                                            <view class=\"store\">{{ res.store }}</view>\n                                            <u-icon name=\"arrow-right\" color=\"rgb(203,203,203)\" :size=\"26\"></u-icon>\n                                        </view>\n                                        <view class=\"right\">{{ res.deal }}</view>\n                                    </view>\n                                    <view class=\"item\" v-for=\"(item, idx) in res.goodsList\" :key=\"idx\">\n                                        <view class=\"left\"><image :src=\"item.goodsUrl\" mode=\"aspectFill\"></image></view>\n                                        <view class=\"content\">\n                                            <view class=\"title u-line-2\">{{ item.title }}</view>\n                                            <view class=\"type\">{{ item.type }}</view>\n                                            <view class=\"delivery-time\">发货时间 {{ item.deliveryTime }}</view>\n                                        </view>\n                                        <view class=\"right\">\n                                            <view class=\"price\">\n                                                ￥{{ priceInt(item.price) }}\n                                                <text class=\"decimal\">.{{ priceDecimal(item.price) }}</text>\n                                            </view>\n                                            <view class=\"number\">x{{ item.number }}</view>\n                                        </view>\n                                    </view>\n                                    <view class=\"total\">\n                                        共{{ totalNum(res.goodsList) }}件商品 合计:\n                                        <text class=\"total-price\">\n                                            ￥{{ priceInt(totalPrice(res.goodsList)) }}.\n                                            <text class=\"decimal\">{{ priceDecimal(totalPrice(res.goodsList)) }}</text>\n                                        </text>\n                                    </view>\n                                    <view class=\"bottom\">\n                                        <view class=\"more\">\n                                            <u-icon name=\"more-dot-fill\" color=\"rgb(203,203,203)\"></u-icon>\n                                        </view>\n                                        <view class=\"logistics btn\" @click=\"$u.toast('查看物流')\">查看物流</view>\n                                        <view class=\"exchange btn\" @click=\"$u.toast('卖了换钱')\">卖了换钱</view>\n                                        <view class=\"evaluate btn\" @click=\"$u.toast('评价')\">评价</view>\n                                    </view>\n                                </view>\n                                <u-loadmore :status=\"loadStatus[3]\" bgColor=\"#f2f2f2\"></u-loadmore>\n                            </view>\n                        </scroll-view>\n                    </swiper-item>\n                </swiper>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, getCurrentInstance } from 'vue';\nimport { $u } from '@/uni_modules/uview-pro';\nimport type { LoadmoreStatus } from '@/uni_modules/uview-pro/types/global';\n\n// 商品信息类型\ninterface GoodsItem {\n    goodsUrl: string;\n    title: string;\n    type: string;\n    deliveryTime: string;\n    price: string; // 价格字符串，带小数\n    number: number;\n}\n// 订单信息类型\ninterface OrderItem {\n    id: string | number;\n    store: string;\n    deal: string;\n    goodsList: GoodsItem[];\n}\n// tab 列表项类型\ninterface TabItem {\n    name: string;\n    count?: number;\n}\n\n// 订单列表，四个 tab，每个 tab 一个数组\nconst orderList = ref<OrderItem[][]>([[], [], [], []]);\n// 用于模拟生成订单的原始数据\nconst dataList = ref<OrderItem[]>([\n    {\n        id: 1,\n        store: '夏日流星限定贩卖',\n        deal: '交易成功',\n        goodsList: [\n            {\n                goodsUrl:\n                    '//img13.360buyimg.com/n7/jfs/t1/103005/7/17719/314825/5e8c19faEb7eed50d/5b81ae4b2f7f3bb7.jpg',\n                title: '【冬日限定】现货 原创jk制服女2020冬装新款小清新宽松软糯毛衣外套女开衫短款百搭日系甜美风',\n                type: '灰色;M',\n                deliveryTime: '付款后30天内发货',\n                price: '348.58',\n                number: 2\n            },\n            {\n                goodsUrl:\n                    '//img12.360buyimg.com/n7/jfs/t1/102191/19/9072/330688/5e0af7cfE17698872/c91c00d713bf729a.jpg',\n                title: '【葡萄藤】现货 小清新学院风制服格裙百褶裙女短款百搭日系甜美风原创jk制服女2020新款',\n                type: '45cm;S',\n                deliveryTime: '付款后30天内发货',\n                price: '135.00',\n                number: 1\n            }\n        ]\n    },\n    {\n        id: 2,\n        store: '江南皮革厂',\n        deal: '交易失败',\n        goodsList: [\n            {\n                goodsUrl: '//img14.360buyimg.com/n7/jfs/t1/60319/15/6105/406802/5d43f68aE9f00db8c/0affb7ac46c345e2.jpg',\n                title: '【冬日限定】现货 原创jk制服女2020冬装新款小清新宽松软糯毛衣外套女开衫短款百搭日系甜美风',\n                type: '粉色;M',\n                deliveryTime: '付款后7天内发货',\n                price: '128.05',\n                number: 1\n            }\n        ]\n    },\n    {\n        id: 3,\n        store: '三星旗舰店',\n        deal: '交易失败',\n        goodsList: [\n            {\n                goodsUrl: '//img11.360buyimg.com/n7/jfs/t1/94448/29/2734/524808/5dd4cc16E990dfb6b/59c256f85a8c3757.jpg',\n                title: '三星（SAMSUNG）京品家电 UA65RUF70AJXXZ 65英寸4K超高清 HDR 京东微联 智能语音 教育资源液晶电视机',\n                type: '4K，广色域',\n                deliveryTime: '保质5年',\n                price: '1998',\n                number: 3\n            },\n            {\n                goodsUrl:\n                    '//img14.360buyimg.com/n7/jfs/t6007/205/4099529191/294869/ae4e6d4f/595dcf19Ndce3227d.jpg!q90.jpg',\n                title: '美的(Midea)639升 对开门冰箱 19分钟急速净味 一级能效冷藏双开门杀菌智能家用双变频节能 BCD-639WKPZM(E)',\n                type: '容量大，速冻',\n                deliveryTime: '保质5年',\n                price: '2354',\n                number: 1\n            }\n        ]\n    },\n    {\n        id: 4,\n        store: '三星旗舰店',\n        deal: '交易失败',\n        goodsList: [\n            {\n                goodsUrl:\n                    '//img10.360buyimg.com/n7/jfs/t22300/31/1505958241/171936/9e201a89/5b2b12ffNe6dbb594.jpg!q90.jpg',\n                title: '法国进口红酒 拉菲（LAFITE）传奇波尔多干红葡萄酒750ml*6整箱装',\n                type: '4K，广色域',\n                deliveryTime: '珍藏10年好酒',\n                price: '1543',\n                number: 3\n            },\n            {\n                goodsUrl:\n                    '//img10.360buyimg.com/n7/jfs/t1/107598/17/3766/525060/5e143aacE9a94d43c/03573ae60b8bf0ee.jpg',\n                title: '蓝妹（BLUE GIRL）酷爽啤酒 清啤 原装进口啤酒 罐装 500ml*9听 整箱装',\n                type: '一打',\n                deliveryTime: '口感好',\n                price: '120',\n                number: 1\n            }\n        ]\n    },\n    {\n        id: 5,\n        store: '三星旗舰店',\n        deal: '交易成功',\n        goodsList: [\n            {\n                goodsUrl:\n                    '//img12.360buyimg.com/n7/jfs/t1/52408/35/3554/78293/5d12e9cfEfd118ba1/ba5995e62cbd747f.jpg!q90.jpg',\n                title: '企业微信 中控人脸指纹识别考勤机刷脸机 无线签到异地多店打卡机WX108',\n                type: '识别效率高',\n                deliveryTime: '使用方便',\n                price: '451',\n                number: 9\n            }\n        ]\n    }\n]);\n\n// tab 列表\nconst list = ref<TabItem[]>([\n    { name: '待付款' },\n    { name: '待发货' },\n    { name: '待收货' },\n    { name: '待评价', count: 12 }\n]);\n\n// 当前 tab 索引\nconst current = ref<number>(0);\n// swiper 当前索引\nconst swiperCurrent = ref<number>(0);\n// tab 高度（如需动态计算可用）\nconst tabsHeight = ref<number>(0);\n// swiper 滑动距离\nconst dx = ref<number>(0);\n// 各 tab 加载状态\nconst loadStatus = ref<LoadmoreStatus[]>(['loadmore', 'loadmore', 'loadmore', 'loadmore']);\n\n// 获取当前实例（用于 $refs）\nconst { proxy } = getCurrentInstance() as any;\n\n// 页面加载时初始化部分 tab 的订单数据\nonMounted(() => {\n    getOrderList(0);\n    getOrderList(1);\n    getOrderList(3);\n});\n\n/**\n * 获取订单列表，模拟数据填充\n * @param idx tab 索引\n */\nfunction getOrderList(idx: number) {\n    for (let i = 0; i < 5; i++) {\n        const index = $u.random(0, dataList.value.length - 1);\n        // 深拷贝数据，生成唯一 id\n        const data = JSON.parse(JSON.stringify(dataList.value[index])) as OrderItem;\n        data.id = $u.guid();\n        orderList.value[idx].push(data);\n    }\n    loadStatus.value.splice(current.value, 1, 'loadmore');\n}\n\n/**\n * 价格整数部分\n * @param val 价格字符串\n */\nfunction priceInt(val: string): string {\n    if (val !== String(parseInt(val))) return val.split('.')[0];\n    else return val;\n}\n/**\n * 价格小数部分\n * @param val 价格字符串\n */\nfunction priceDecimal(val: string): string {\n    if (val !== String(parseInt(val))) return val.slice(-2);\n    else return '00';\n}\n/**\n * 计算商品总价\n * @param items 商品数组\n */\nfunction totalPrice(items: GoodsItem[]): string {\n    let price = 0;\n    items.forEach(val => {\n        price += parseFloat(val.price);\n    });\n    return price.toFixed(2);\n}\n/**\n * 计算商品总件数\n * @param items 商品数组\n */\nfunction totalNum(items: GoodsItem[]): number {\n    let num = 0;\n    items.forEach(val => {\n        num += val.number;\n    });\n    return num;\n}\n/**\n * tab 切换事件\n * @param index 新 tab 索引\n */\nfunction change(index: number) {\n    swiperCurrent.value = index;\n    getOrderList(index);\n}\n/**\n * swiper 滑动事件\n * @param param 事件对象，包含 dx\n */\nfunction transition({ detail: { dx: dxVal } }: { detail: { dx: number } }) {\n    proxy?.$refs.tabs.setDx(dxVal);\n}\n/**\n * swiper 动画结束事件\n * @param param 事件对象，包含 current\n */\nfunction animationfinish({ detail: { current: cur } }: { detail: { current: number } }) {\n    proxy?.$refs.tabs.setFinishCurrent(cur);\n    swiperCurrent.value = cur;\n    current.value = cur;\n}\n/**\n * 滚动到底部加载更多\n */\nfunction reachBottom() {\n    // 待收货 tab（2）无数据，不加载\n    if (current.value !== 2) {\n        loadStatus.value.splice(current.value, 1, 'loading');\n        setTimeout(() => {\n            getOrderList(current.value);\n        }, 1200);\n    }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.order {\n    width: 710rpx;\n    background-color: $u-bg-white;\n    margin: 20rpx auto;\n    border-radius: 20rpx;\n    box-sizing: border-box;\n    padding: 20rpx;\n    font-size: 28rpx;\n    .top {\n        display: flex;\n        justify-content: space-between;\n        .left {\n            display: flex;\n            align-items: center;\n            .store {\n                margin: 0 10rpx;\n                font-size: 32rpx;\n                font-weight: bold;\n            }\n        }\n        .right {\n            color: $u-type-warning-dark;\n        }\n    }\n    .item {\n        display: flex;\n        margin: 20rpx 0 0;\n        .left {\n            margin-right: 20rpx;\n            image {\n                width: 200rpx;\n                height: 200rpx;\n                border-radius: 10rpx;\n            }\n        }\n        .content {\n            .title {\n                font-size: 28rpx;\n                line-height: 50rpx;\n            }\n            .type {\n                margin: 10rpx 0;\n                font-size: 24rpx;\n                color: $u-tips-color;\n            }\n            .delivery-time {\n                color: $u-type-warning;\n                font-size: 24rpx;\n            }\n        }\n        .right {\n            margin-left: 10rpx;\n            padding-top: 20rpx;\n            text-align: right;\n            .decimal {\n                font-size: 24rpx;\n                margin-top: 4rpx;\n            }\n            .number {\n                color: $u-tips-color;\n                font-size: 24rpx;\n            }\n        }\n    }\n    .total {\n        margin-top: 20rpx;\n        text-align: right;\n        font-size: 24rpx;\n        .total-price {\n            font-size: 32rpx;\n        }\n    }\n    .bottom {\n        display: flex;\n        margin-top: 40rpx;\n        padding: 0 10rpx;\n        justify-content: space-between;\n        align-items: center;\n        .btn {\n            line-height: 52rpx;\n            width: 160rpx;\n            border-radius: 26rpx;\n            border: 2rpx solid $u-border-color;\n            font-size: 26rpx;\n            text-align: center;\n            color: $u-type-info-dark;\n        }\n        .evaluate {\n            color: $u-type-warning-dark;\n            border-color: $u-type-warning-dark;\n        }\n    }\n}\n.centre {\n    text-align: center;\n    margin: 200rpx auto;\n    font-size: 32rpx;\n    image {\n        width: 164rpx;\n        height: 164rpx;\n        border-radius: 50%;\n        margin-bottom: 20rpx;\n    }\n    .tips {\n        font-size: 24rpx;\n        color: $u-tips-color;\n        margin-top: 20rpx;\n    }\n    .btn {\n        margin: 80rpx auto;\n        width: 200rpx;\n        border-radius: 32rpx;\n        line-height: 64rpx;\n        color: $u-white-color;\n        font-size: 26rpx;\n        background: linear-gradient(270deg, var(--u-type-warning-dark) 0%, var(--u-type-warning) 100%);\n    }\n}\n.wrap {\n    display: flex;\n    flex-direction: column;\n    height: calc(100vh - var(--window-top));\n    width: 100%;\n}\n.swiper-box {\n    flex: 1;\n}\n.swiper-item {\n    height: 100%;\n}\n</style>\n"
  },
  {
    "path": "src/pages/template/submitBar/index.vue",
    "content": "<template>\n    <demo-page hide-tabs show-wx-tips nav-title=\"提交订单栏\">\n        <view class=\"wrap\">\n            <view class=\"navigation\">\n                <view class=\"left\">\n                    <view class=\"item\" @click=\"$u.toast('进入客服')\">\n                        <u-icon name=\"server-fill\" :size=\"40\" :color=\"$u.color['contentColor']\"></u-icon>\n                        <view class=\"text u-line-1\">客服</view>\n                    </view>\n                    <view class=\"item\" @click=\"$u.toast('进入店铺')\">\n                        <u-icon name=\"home\" :size=\"40\" :color=\"$u.color['contentColor']\"></u-icon>\n                        <view class=\"text u-line-1\">店铺</view>\n                    </view>\n                    <view class=\"item car\" @click=\"$u.toast('进入购物车')\">\n                        <u-badge class=\"car-num\" :count=\"9\" type=\"error\" :offset=\"[-3, -6]\"></u-badge>\n                        <u-icon name=\"shopping-cart\" :size=\"40\" :color=\"$u.color['contentColor']\"></u-icon>\n                        <view class=\"text u-line-1\">购物车</view>\n                    </view>\n                </view>\n                <view class=\"right\">\n                    <view class=\"cart btn u-line-1\" @click=\"$u.toast('加入购物车')\">加入购物车</view>\n                    <view class=\"buy btn u-line-1\" @click=\"$u.toast('立即购买')\">立即购买</view>\n                </view>\n            </view>\n        </view>\n    </demo-page>\n</template>\n\n<script setup lang=\"ts\">\nimport { $u } from '@/uni_modules/uview-pro';\n</script>\n\n<style lang=\"scss\" scoped>\n.navigation {\n    display: flex;\n    border: solid 1px $u-border-color;\n    background-color: $u-bg-white;\n    padding: 16rpx 0;\n    position: fixed;\n    width: 100%;\n    bottom: env(safe-area-inset-bottom);\n    .left {\n        display: flex;\n        font-size: 20rpx;\n        .item {\n            margin: 0 30rpx;\n            &.car {\n                text-align: center;\n                position: relative;\n                .car-num {\n                    position: absolute;\n                    top: -10rpx;\n                    right: -10rpx;\n                }\n            }\n        }\n    }\n    .right {\n        display: flex;\n        font-size: 28rpx;\n        align-items: center;\n        .btn {\n            line-height: 66rpx;\n            padding: 0 30rpx;\n            border-radius: 36rpx;\n            color: $u-white-color;\n        }\n        .cart {\n            background-color: $u-type-error;\n            margin-right: 30rpx;\n        }\n        .buy {\n            background-color: $u-type-warning;\n        }\n    }\n}\n</style>\n"
  },
  {
    "path": "src/pages/template/wxCenter/index.vue",
    "content": "<template>\n    <view class=\"wrap\">\n        <u-navbar\n            :is-back=\"true\"\n            title=\"个人中心\"\n            :background=\"background\"\n            :border-bottom=\"false\"\n            :is-fixed=\"true\"\n            :immersive=\"false\"\n            back-icon-name=\"arrow-leftward\"\n            title-width=\"350\"\n            title-color=\"#ffffff\"\n            back-icon-color=\"#ffffff\"\n        >\n            <!-- #ifndef MP -->\n            <template #right>\n                <u-icon\n                    custom-style=\"margin-right:15px\"\n                    name=\"camera-fill\"\n                    color=\"#ffffff\"\n                    size=\"48\"\n                    @click=\"$u.toast('点击相机')\"\n                ></u-icon>\n            </template>\n            <!-- #endif -->\n            <!-- #ifdef MP -->\n            <template #left>\n                <u-icon\n                    custom-style=\"margin-left:7px\"\n                    name=\"camera-fill\"\n                    color=\"#ffffff\"\n                    size=\"48\"\n                    @click=\"$u.toast('点击相机')\"\n                ></u-icon>\n            </template>\n            <!-- #endif -->\n        </u-navbar>\n        <view class=\"u-flex user-box u-p-30\">\n            <view class=\"u-m-r-10\">\n                <u-avatar :src=\"pic\" size=\"140\"></u-avatar>\n            </view>\n            <view class=\"u-flex-1\">\n                <view class=\"u-font-18 u-p-b-20\">uView Pro</view>\n                <view class=\"u-font-14 u-tips-color\">微信号: anyupxing</view>\n            </view>\n            <view class=\"u-m-l-10 u-p-10\">\n                <u-icon name=\"scan\" color=\"#969799\" size=\"28\"></u-icon>\n            </view>\n            <view class=\"u-m-l-10 u-p-10\">\n                <u-icon name=\"arrow-right\" color=\"#969799\" size=\"28\"></u-icon>\n            </view>\n        </view>\n\n        <view class=\"u-m-t-20\">\n            <u-cell-group>\n                <u-cell-item icon=\"rmb-circle\" title=\"支付\" @click=\"$u.toast('点击支付')\"></u-cell-item>\n            </u-cell-group>\n        </view>\n\n        <view class=\"u-m-t-20\">\n            <u-cell-group>\n                <u-cell-item icon=\"star\" title=\"收藏\" @click=\"$u.toast('点击收藏')\"></u-cell-item>\n                <u-cell-item icon=\"photo\" title=\"相册\" @click=\"$u.toast('点击相册')\"></u-cell-item>\n                <u-cell-item icon=\"coupon\" title=\"卡券\" @click=\"$u.toast('点击卡券')\"></u-cell-item>\n                <u-cell-item icon=\"heart\" title=\"关注\" @click=\"$u.toast('点击关注')\"></u-cell-item>\n            </u-cell-group>\n        </view>\n\n        <view class=\"u-m-t-20\">\n            <u-cell-group>\n                <u-cell-item icon=\"setting\" title=\"设置\" @click=\"$u.toast('点击设置')\"></u-cell-item>\n            </u-cell-group>\n        </view>\n    </view>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, onMounted, reactive } from 'vue';\nimport { $u } from 'uview-pro';\n\n// 用户头像图片地址\nconst pic = ref<string>('https://ik.imagekit.io/anyup/uview-pro/common/logo-new.png');\n// 控制页面显示（如后续有弹窗、遮罩等可用）\nconst show = ref<boolean>(true);\n\nconst background = reactive({\n    backgroundColor: 'var(--u-type-primary)',\n    // 渐变色\n    backgroundImage: 'linear-gradient(90deg, var(--u-type-primary-dark), var(--u-type-primary-disabled))'\n});\n\n// 页面加载生命周期（如需初始化逻辑可在此处添加）\nonMounted(() => {\n    // 目前无初始化逻辑\n});\n</script>\n\n<style lang=\"scss\">\n.wrap {\n    background-color: $u-bg-color;\n}\n.camera {\n    width: 54px;\n    height: 44px;\n    &:active {\n        background-color: $u-bg-color;\n    }\n}\n.user-box {\n    background-color: $u-bg-white;\n}\n</style>\n"
  },
  {
    "path": "src/pages.json",
    "content": "{\r\n    \"easycom\": {\r\n        \"autoscan\": true,\r\n        \"custom\": {\r\n            \"^u-(.*)\": \"@/uni_modules/uview-pro/components/u-$1/u-$1.vue\"\r\n        }\r\n    },\r\n    \"pages\": [\r\n        // 演示-组件\r\n        {\r\n            \"path\": \"pages/example/components\",\r\n            \"style\": {\r\n                \"navigationBarTitleText\": \"组件\"\r\n            }\r\n        },\r\n        // 关于\r\n        {\r\n            \"path\": \"pages/example/about\",\r\n            \"style\": {\r\n                \"navigationBarTitleText\": \"关于\"\r\n                // \"navigationStyle\": \"custom\"\r\n            }\r\n        },\r\n        // 关于-关于我\r\n        {\r\n            \"path\": \"pages/example/about/about-me\",\r\n            \"style\": {\r\n                \"navigationBarTitleText\": \"关于我\"\r\n            }\r\n        },\r\n        // 关于-版本信息\r\n        {\r\n            \"path\": \"pages/example/about/version\",\r\n            \"style\": {\r\n                \"navigationBarTitleText\": \"版本信息\"\r\n            }\r\n        },\r\n        // 关于-开源协议\r\n        {\r\n            \"path\": \"pages/example/about/license\",\r\n            \"style\": {\r\n                \"navigationBarTitleText\": \"开源协议\"\r\n            }\r\n        },\r\n        // 关于-贡献者\r\n        {\r\n            \"path\": \"pages/example/about/contributors\",\r\n            \"style\": {\r\n                \"navigationBarTitleText\": \"贡献者\"\r\n            }\r\n        },\r\n        // 关于-常见问题\r\n        {\r\n            \"path\": \"pages/example/about/faq\",\r\n            \"style\": {\r\n                \"navigationBarTitleText\": \"常见问题\"\r\n            }\r\n        },\r\n        // 关于-使用指南\r\n        {\r\n            \"path\": \"pages/example/about/guide\",\r\n            \"style\": {\r\n                \"navigationBarTitleText\": \"使用指南\"\r\n            }\r\n        },\r\n        // 关于-设置\r\n        {\r\n            \"path\": \"pages/example/about/settings\",\r\n            \"style\": {\r\n                \"navigationBarTitleText\": \"设置\"\r\n            }\r\n        },\r\n        // 演示-工具\r\n        {\r\n            \"path\": \"pages/example/js\",\r\n            \"style\": {\r\n                \"navigationBarTitleText\": \"工具\"\r\n            }\r\n        },\r\n        // 演示-模板\r\n        {\r\n            \"path\": \"pages/example/template\",\r\n            \"style\": {\r\n                \"navigationBarTitleText\": \"模板\"\r\n            }\r\n        },\r\n        {\r\n            \"path\": \"pages/example/experienceMap\",\r\n            \"style\": {\r\n                \"navigationBarTitleText\": \"体验地图\"\r\n            }\r\n        },\r\n        // fullScreen-压窗屏\r\n        {\r\n            \"path\": \"pages/example/fullScreen\",\r\n            \"style\": {\r\n                \"navigationStyle\": \"custom\",\r\n                \"app-plus\": {\r\n                    \"animationType\": \"fade-in\",\r\n                    \"background\": \"transparent\",\r\n                    \"backgroundColor\": \"rgba(0,0,0,0)\",\r\n                    \"popGesture\": \"none\"\r\n                }\r\n            }\r\n        }\r\n    ],\r\n    \"subPackages\": [\r\n        {\r\n            \"root\": \"pages/componentsC\",\r\n            \"pages\": [\r\n                // gap-间隔槽\r\n                {\r\n                    \"path\": \"gap/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Gap 间隔槽\"\r\n                    }\r\n                },\r\n                // subsection分段器\r\n                {\r\n                    \"path\": \"subsection/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Subsection 分段器\"\r\n                    }\r\n                },\r\n                // section 查看更多\r\n                {\r\n                    \"path\": \"section/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Section 查看更多\"\r\n                    }\r\n                },\r\n                // link链接\r\n                {\r\n                    \"path\": \"link/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Link 链接\"\r\n                    }\r\n                },\r\n                // mask遮罩层\r\n                {\r\n                    \"path\": \"mask/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Mask 遮罩层\"\r\n                    }\r\n                },\r\n                // countTo数字滚动\r\n                {\r\n                    \"path\": \"countTo/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"CountTo 数字滚动\"\r\n                    }\r\n                },\r\n                // color颜色\r\n                {\r\n                    \"path\": \"color/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Color 颜色\"\r\n                    }\r\n                },\r\n                // countDown倒计时\r\n                {\r\n                    \"path\": \"countDown/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"CountDown 倒计时\"\r\n                    }\r\n                },\r\n                // progress进度条\r\n                {\r\n                    \"path\": \"progress/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Progress 进度条\"\r\n                    }\r\n                },\r\n                // alertTips警告提示\r\n                {\r\n                    \"path\": \"alertTips/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"AlertTips 警告提示\"\r\n                    }\r\n                },\r\n                // badge 徽标数\r\n                {\r\n                    \"path\": \"badge/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Badge 徽标数\"\r\n                    }\r\n                },\r\n                // button按钮\r\n                {\r\n                    \"path\": \"button/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Button 按钮\"\r\n                    }\r\n                },\r\n                // collapse折叠面板\r\n                {\r\n                    \"path\": \"collapse/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Collapse 折叠面板\"\r\n                    }\r\n                },\r\n                // actionSheet操作菜单\r\n                {\r\n                    \"path\": \"actionSheet/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"ActionSheet 操作菜单\"\r\n                    }\r\n                },\r\n                // messageInput验证码输入\r\n                {\r\n                    \"path\": \"messageInput/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"MessageInput 验证码输入\"\r\n                    }\r\n                },\r\n                // popup弹窗\r\n                {\r\n                    \"path\": \"popup/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Popup 弹窗\"\r\n                    }\r\n                },\r\n                // listCell\r\n                {\r\n                    \"path\": \"cell/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"ListCell 列表\"\r\n                    }\r\n                },\r\n                // numberBox数字输入框\r\n                {\r\n                    \"path\": \"numberBox/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"NumberBox 步进器\"\r\n                    }\r\n                },\r\n                // grid宫格布局\r\n                {\r\n                    \"path\": \"grid/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Grid 宫格布局\"\r\n                    }\r\n                },\r\n                // layout栅格布局\r\n                {\r\n                    \"path\": \"layout/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Layout 栅格布局\"\r\n                    }\r\n                },\r\n                // 加载更多\r\n                {\r\n                    \"path\": \"loadmore/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Loadmore 加载更多\"\r\n                    }\r\n                },\r\n                // 文本\r\n                {\r\n                    \"path\": \"text/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Text 文本\"\r\n                    }\r\n                },\r\n                // fab悬浮按钮\r\n                {\r\n                    \"path\": \"fab/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Fab 悬浮按钮\"\r\n                    }\r\n                },\r\n                // pagination分页\r\n                {\r\n                    \"path\": \"pagination/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Pagination 分页\"\r\n                    }\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"root\": \"pages/template\",\r\n            \"pages\": [\r\n                // wxCenter 仿微信个人中心\r\n                {\r\n                    \"path\": \"wxCenter/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"WxCenter 仿微信个人中心\"\r\n                    }\r\n                },\r\n                // keyboardPay 自定义键盘支付\r\n                {\r\n                    \"path\": \"keyboardPay/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"KeyboardPay 自定义键盘支付\"\r\n                    }\r\n                },\r\n                // mallMenu商城分类\r\n                {\r\n                    \"path\": \"mallMenu/index2\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"MallMenu 商城分类\"\r\n                    }\r\n                },\r\n                // mallMenu商城分类\r\n                {\r\n                    \"path\": \"mallMenu/index1\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"MallMenu 商城分类\"\r\n                    }\r\n                },\r\n                // coupon优惠券\r\n                {\r\n                    \"path\": \"coupon/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Coupon 优惠券\"\r\n                    }\r\n                },\r\n                {\r\n                    \"path\": \"login/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"美团登录\"\r\n                    }\r\n                },\r\n                // 城市选择\r\n                {\r\n                    \"path\": \"citySelect/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"城市选择\"\r\n                    }\r\n                },\r\n                // SubmitBar提交订单栏\r\n                {\r\n                    \"path\": \"submitBar/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"SubmitBar 提交订单栏\"\r\n                    }\r\n                },\r\n                // comment评论\r\n                {\r\n                    \"path\": \"comment/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"评论\"\r\n                    }\r\n                },\r\n                // comment评论详情\r\n                {\r\n                    \"path\": \"comment/reply\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"评论详情\"\r\n                    }\r\n                },\r\n                // order订单\r\n                {\r\n                    \"path\": \"order/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"订单\"\r\n                    }\r\n                },\r\n                // login登录获取验证码\r\n                {\r\n                    \"path\": \"login/code\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"登录获取验证码\"\r\n                    }\r\n                },\r\n                // address用户地址\r\n                {\r\n                    \"path\": \"address/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"用户地址\"\r\n                    }\r\n                },\r\n                // address添加用户地址\r\n                {\r\n                    \"path\": \"address/addSite\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"添加用户地址\"\r\n                    }\r\n                },\r\n                // template-模板详情\r\n                {\r\n                    \"path\": \"detail/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"模板详情\"\r\n                    }\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"root\": \"pages/library\",\r\n            \"pages\": [\r\n                // debounce-节流防抖\r\n                {\r\n                    \"path\": \"debounce/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Debounce 节流防抖\"\r\n                    }\r\n                },\r\n                // deepClone-对象深度克隆\r\n                {\r\n                    \"path\": \"deepClone/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"DeepClone 对象深度克隆\"\r\n                    }\r\n                },\r\n                // deepMerge-对象深度合并\r\n                {\r\n                    \"path\": \"deepMerge/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"DeepMerge 对象深度合并\"\r\n                    }\r\n                },\r\n                // getRect-元素节点\r\n                {\r\n                    \"path\": \"getRect/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"GetRect 元素节点\"\r\n                    }\r\n                },\r\n                // timeFrom-多久之前\r\n                {\r\n                    \"path\": \"timeFrom/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"TimeFrom 多久之前\"\r\n                    }\r\n                },\r\n                // http-请求\r\n                {\r\n                    \"path\": \"http/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Http 请求\"\r\n                    }\r\n                },\r\n                // test-规则验证\r\n                {\r\n                    \"path\": \"test/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Test 规则验证\"\r\n                    }\r\n                },\r\n                // mpShare-小程序分享\r\n                {\r\n                    \"path\": \"mpShare/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"MpShare 小程序分享\"\r\n                    }\r\n                },\r\n                // color-JS调用颜色\r\n                {\r\n                    \"path\": \"color/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Color JS调用颜色\"\r\n                    }\r\n                },\r\n                // trim-去除空格\r\n                {\r\n                    \"path\": \"trim/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Trim 去除空格\"\r\n                    }\r\n                },\r\n                // random-随机数生成\r\n                {\r\n                    \"path\": \"random/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Random 随机数生成\"\r\n                    }\r\n                },\r\n                // md5加密\r\n                {\r\n                    \"path\": \"md5/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Md5 加密\"\r\n                    }\r\n                },\r\n                // colorSwitch颜色转换\r\n                {\r\n                    \"path\": \"colorSwitch/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"ColorSwitch 颜色转换\"\r\n                    }\r\n                },\r\n                // randomArray数组乱序\r\n                {\r\n                    \"path\": \"randomArray/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"RandomArray 数组乱序\"\r\n                    }\r\n                },\r\n                // guid全局唯一标识符\r\n                {\r\n                    \"path\": \"guid/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Guid 全局唯一标识符\"\r\n                    }\r\n                },\r\n                // timeFormat时间格式化\r\n                {\r\n                    \"path\": \"timeFormat/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"TimeFormat 时间格式化\"\r\n                    }\r\n                }, // route-路由\r\n                {\r\n                    \"path\": \"route/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Route 路由\"\r\n                    }\r\n                },\r\n                // route-路由跳转\r\n                {\r\n                    \"path\": \"route/routeTo\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Route 路由跳转\"\r\n                    }\r\n                },\r\n                // queryParams-对象转URL参数\r\n                {\r\n                    \"path\": \"queryParams/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"QueryParams 对象转URL参数\"\r\n                    }\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"root\": \"pages/componentsA\",\r\n            \"pages\": [\r\n                // // parse-富文本解析器\r\n                // {\r\n                //   \"path\": \"parse/index\",\r\n                //   \"style\": {\r\n                //     \"navigationBarTitleText\": \"parse-富文本解析器\"\r\n                //   }\r\n                // },\r\n                // input-输入框\r\n                {\r\n                    \"path\": \"input/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Input 输入框\"\r\n                    }\r\n                },\r\n                {\r\n                    \"path\": \"textarea/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Textarea 输入框\"\r\n                    }\r\n                },\r\n                // backTop-返回顶部\r\n                {\r\n                    \"path\": \"backTop/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"BackTop 返回顶部\"\r\n                    }\r\n                },\r\n                // calendar-日历\r\n                {\r\n                    \"path\": \"calendar/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Calendar 日历\"\r\n                    }\r\n                },\r\n                // form-表单\r\n                {\r\n                    \"path\": \"form/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Form 表单\"\r\n                    }\r\n                },\r\n                // select-列选择器\r\n                {\r\n                    \"path\": \"select/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Select 列选择器\"\r\n                    }\r\n                },\r\n                // slider-滑动选择器\r\n                {\r\n                    \"path\": \"slider/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Slider 滑动选择器\"\r\n                    }\r\n                },\r\n                // fullScreen-压窗屏\r\n                {\r\n                    \"path\": \"fullScreen/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"FullScreen 压窗屏\"\r\n                    }\r\n                },\r\n                // navbar-自定义导航栏\r\n                {\r\n                    \"path\": \"navbar/index\",\r\n                    \"style\": {\r\n                        // \"navigationBarTitleText\": \"Navbar 自定义导航栏\",\r\n                        \"navigationStyle\": \"custom\", // 隐藏系统导航栏\r\n                        \"navigationBarTextStyle\": \"white\" // 状态栏字体为白色\r\n                    }\r\n                },\r\n                // field-输入框\r\n                {\r\n                    \"path\": \"field/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Field 输入框\"\r\n                    }\r\n                },\r\n                // modal-模态框\r\n                {\r\n                    \"path\": \"modal/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Modal 模态框\"\r\n                    }\r\n                },\r\n                // indexList索引列表\r\n                {\r\n                    \"path\": \"indexList/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"IndexList 索引列表\"\r\n                    }\r\n                },\r\n                // empty内容为空\r\n                {\r\n                    \"path\": \"empty/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Empty 内容为空\"\r\n                    }\r\n                },\r\n                // // avatarCropper-头像裁剪\r\n                // {\r\n                //     \"path\": \"avatarCropper/index\",\r\n                //     \"style\": {\r\n                //         \"navigationBarTitleText\": \"AvatarCropper 头像裁剪\"\r\n                //     }\r\n                // },\r\n                // noNetwork没有网络\r\n                {\r\n                    \"path\": \"noNetwork/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"NoNetwork 没有网络\"\r\n                    }\r\n                },\r\n                // icon字体图标\r\n                {\r\n                    \"path\": \"icon/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Icon 字体图标\"\r\n                    }\r\n                },\r\n                // avatar-用户头像展示\r\n                {\r\n                    \"path\": \"avatar/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Avatar 用户头像展示\"\r\n                    }\r\n                },\r\n                // keyboard键盘\r\n                {\r\n                    \"path\": \"keyboard/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Keyboard 键盘\"\r\n                    }\r\n                },\r\n                // 图片懒加载\r\n                {\r\n                    \"path\": \"lazyLoad/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"LazyLoad 懒加载\"\r\n                    }\r\n                },\r\n                // tabs切换\r\n                {\r\n                    \"path\": \"tabs/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Tabs 切换\"\r\n                    }\r\n                },\r\n                // tag标签\r\n                {\r\n                    \"path\": \"tag/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Tag 标签\"\r\n                    }\r\n                },\r\n                // timeLine时间轴\r\n                {\r\n                    \"path\": \"timeLine/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"TimeLine 时间轴\"\r\n                    }\r\n                },\r\n                // toast轻提示\r\n                {\r\n                    \"path\": \"toast/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Toast 轻提示\"\r\n                    }\r\n                },\r\n                // topTips消息提示\r\n                {\r\n                    \"path\": \"topTips/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"TopTips 消息提示\"\r\n                    }\r\n                },\r\n                // Code-验证码倒计时\r\n                {\r\n                    \"path\": \"verificationCode/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"VerificationCode 验证码倒计时\"\r\n                    }\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"root\": \"pages/componentsB\",\r\n            \"pages\": [\r\n                // dropdown-下拉菜单\r\n                {\r\n                    \"path\": \"dropdown/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Dropdown 下拉菜单\"\r\n                    }\r\n                },\r\n                // tabbar-底部导航栏\r\n                {\r\n                    \"path\": \"tabbar/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Tabbar 底部导航栏\"\r\n                    }\r\n                },\r\n                // line-线条\r\n                {\r\n                    \"path\": \"line/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Line 线条\"\r\n                    }\r\n                },\r\n                // image-图片\r\n                {\r\n                    \"path\": \"image/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Image 图片\"\r\n                    }\r\n                },\r\n                // card-卡片\r\n                {\r\n                    \"path\": \"card/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Card 卡片\"\r\n                    }\r\n                },\r\n                // divider-分割线\r\n                {\r\n                    \"path\": \"divider/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Divider 分割线\"\r\n                    }\r\n                },\r\n                // picker选择器\r\n                {\r\n                    \"path\": \"picker/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Picker 选择器\"\r\n                    }\r\n                }, // noticeBar通告栏\r\n                {\r\n                    \"path\": \"noticeBar/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"NoticeBar 通告栏\"\r\n                    }\r\n                },\r\n                // checkbox-复选框\r\n                {\r\n                    \"path\": \"checkbox/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Checkbox 复选框\"\r\n                    }\r\n                },\r\n                // radio-单选框\r\n                {\r\n                    \"path\": \"radio/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Radio 单选框\"\r\n                    }\r\n                },\r\n                // loading-加载动画\r\n                {\r\n                    \"path\": \"loading/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Loading 加载动画\"\r\n                    }\r\n                },\r\n                // loadingPopup-加载弹窗\r\n                {\r\n                    \"path\": \"loadingPopup/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"LoadingPopup 加载弹窗\"\r\n                    }\r\n                },\r\n                // switch-开关选择器\r\n                {\r\n                    \"path\": \"switch/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Switch 开关选择器\"\r\n                    }\r\n                },\r\n                // 骨架屏\r\n                {\r\n                    \"path\": \"skeleton/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Skeleton 骨架屏\"\r\n                    }\r\n                }, // upload上传\r\n                {\r\n                    \"path\": \"upload/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Upload 上传\"\r\n                    }\r\n                },\r\n                // waterfall瀑布流\r\n                // #ifndef MP-TOUTIAO\r\n                {\r\n                    \"path\": \"waterfall/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Waterfall 瀑布流\"\r\n                    }\r\n                },\r\n                // #endif\r\n                // table表格\r\n                {\r\n                    \"path\": \"table/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Table 表格\"\r\n                    }\r\n                },\r\n                // rate评分\r\n                {\r\n                    \"path\": \"rate/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Rate 评分\"\r\n                    }\r\n                },\r\n                // readMore显示更多\r\n                {\r\n                    \"path\": \"readMore/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"ReadMore 查看更多\"\r\n                    }\r\n                },\r\n                // search搜索框\r\n                {\r\n                    \"path\": \"search/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Search 搜索框\"\r\n                    }\r\n                },\r\n                // steps步骤条\r\n                {\r\n                    \"path\": \"steps/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Steps 步骤条\"\r\n                    }\r\n                },\r\n                // sticky吸顶\r\n                {\r\n                    \"path\": \"sticky/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Sticky 吸顶\"\r\n                    }\r\n                },\r\n                // swiper轮播图\r\n                {\r\n                    \"path\": \"swiper/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Swiper 轮播图\"\r\n                    }\r\n                },\r\n                // swipeAction-左滑删除\r\n                {\r\n                    \"path\": \"swipeAction/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"SwipeAction 左滑删除\"\r\n                    }\r\n                },\r\n                {\r\n                    \"path\": \"transition/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Transition 动画\"\r\n                    }\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"root\": \"pages/other\",\r\n            \"pages\": [\r\n                {\r\n                    \"path\": \"theme/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"Theme 主题管理\"\r\n                    }\r\n                },\r\n                {\r\n                    \"path\": \"locale/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"locale-国际化\"\r\n                    }\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"root\": \"pages/scenes\",\r\n            \"pages\": [\r\n                {\r\n                    \"path\": \"index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"实用场景\"\r\n                    }\r\n                },\r\n                {\r\n                    \"path\": \"todo/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"待办事项\"\r\n                    }\r\n                },\r\n                {\r\n                    \"path\": \"notes/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"我的笔记\"\r\n                    }\r\n                },\r\n                {\r\n                    \"path\": \"dashboard/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"数据统计\"\r\n                    }\r\n                },\r\n                {\r\n                    \"path\": \"favorites/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"我的收藏\"\r\n                    }\r\n                }\r\n            ]\r\n        },\r\n        {\r\n            \"root\": \"pages/hooks\",\r\n            \"pages\": [\r\n                {\r\n                    \"path\": \"useModal/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"useModal 模态框\"\r\n                    }\r\n                },\r\n                {\r\n                    \"path\": \"useToast/index\",\r\n                    \"style\": {\r\n                        \"navigationBarTitleText\": \"useToast 提示\"\r\n                    }\r\n                }\r\n            ]\r\n        }\r\n    ],\r\n    \"preloadRule\": {\r\n        \"pages/example/components\": {\r\n            \"network\": \"all\",\r\n            \"packages\": [\"pages/componentsA\", \"pages/componentsB\", \"pages/componentsC\"]\r\n        }\r\n    },\r\n    \"globalStyle\": {\r\n        \"backgroundColor\": \"@bgColor\",\r\n        \"backgroundColorBottom\": \"@bgColorBottom\",\r\n        \"backgroundColorTop\": \"@bgColorTop\",\r\n        \"backgroundTextStyle\": \"@bgTxtStyle\",\r\n        \"navigationBarBackgroundColor\": \"@navBgColor\",\r\n        \"navigationBarTextStyle\": \"@navTxtStyle\",\r\n        \"navigationBarTitleText\": \"uView Pro\",\r\n        \"navigationStyle\": \"custom\"\r\n    },\r\n    \"tabBar\": {\r\n        \"color\": \"@tabFontColor\",\r\n        \"selectedColor\": \"@tabSelectedColor\",\r\n        \"backgroundColor\": \"@tabBgColor\",\r\n        \"borderStyle\": \"@tabBorderStyle\",\r\n        \"list\": [\r\n            {\r\n                \"pagePath\": \"pages/example/components\"\r\n            },\r\n            {\r\n                \"pagePath\": \"pages/example/js\"\r\n            },\r\n            {\r\n                \"pagePath\": \"pages/example/experienceMap\"\r\n            },\r\n            {\r\n                \"pagePath\": \"pages/example/template\"\r\n            },\r\n            {\r\n                \"pagePath\": \"pages/example/about\"\r\n            }\r\n        ]\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/shime-uni.d.ts",
    "content": "export {};\n\ndeclare module 'vue' {\n    type Hooks = App.AppInstance & Page.PageInstance;\n    interface ComponentCustomOptions extends Hooks {}\n}\n"
  },
  {
    "path": "src/static/app/markdown/actionSheet.md",
    "content": "## ActionSheet 操作菜单 <to-api/>\n\n<demo-model url=\"/pages/componentsC/actionSheet/index\"></demo-model>\n\n本组件用于从底部弹出一个操作菜单，供用户选择并返回结果。  \n本组件功能类似于uni的`uni.showActionSheet`API，配置更加灵活，所有平台都表现一致。\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n\n- 通过`list`设置需要显示的菜单，该值为一个数组，元素为对象，对象至少要提供`text`属性，另外可选的有`fontSize`(字体大小)，`color`(颜色)，`disabled`(是否禁用，1.5.6引入)，\n`subText`(描述信息，1.6.8引入) \n- 通过`v-model`绑定一个值为布尔值的变量控制组件的弹出与收起，`v-model`的值是双向绑定的\n\n```html\n<template>\n\t<view>\n\t\t<u-action-sheet :list=\"list\" v-model=\"show\"></u-action-sheet>\n\t\t<u-button @click=\"show = true\">打开ActionSheet</u-button>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tlist: [{\n\t\t\t\t\ttext: '点赞',\n\t\t\t\t\tcolor: 'blue',\n\t\t\t\t\tfontSize: 28,\n\t\t\t\t\tsubText: '感谢您的点赞'\n\t\t\t\t}, {\n\t\t\t\t\ttext: '分享'\n\t\t\t\t}, {\n\t\t\t\t\ttext: '评论' \n\t\t\t\t}],\n\t\t\t\tshow: false\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 配置顶部的提示信息和底部取消按钮\n\n- `tips`参数为一个对象类型，属性可以设置`text`，`fontSize`(字体大小)，`color`(颜色)，文本内容将会显示组件的上方，起提示作用。\n- `cancel-btn`参数配置是否显示底部的取消按钮，默认显示\n\n```html\n<template>\n\t<u-action-sheet :list=\"list\" v-model=\"show\" :tips=\"tips\" :cancel-btn=\"true\"></u-action-sheet>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\ttips: {\n\t\t\t\t\ttext: '在水一方',\n\t\t\t\t\tcolor: '#909399',\n\t\t\t\t\tfontSize: 24\n\t\t\t\t},\n\t\t\t\tlist: [{\n\t\t\t\t\ttext: '点赞',\n\t\t\t\t\tcolor: 'blue',\n\t\t\t\t\tfontSize: 28\n\t\t\t\t}],\n\t\t\t\tshow: true\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 如何知道点了第几项\n\n`click`回调事件带有一个`index`值，这个索引值为传递的`list`数组的索引值，根据回调事件，能获得点击了\n第几项和该项的内容\n\n\n```html\n<template>\n\t<u-action-sheet :list=\"list\" @click=\"click\" v-model=\"show\"></u-action-sheet>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tlist: [{\n\t\t\t\t\ttext: '点赞',\n\t\t\t\t\tcolor: 'blue',\n\t\t\t\t\tfontSize: 28\n\t\t\t\t}, {\n\t\t\t\t\ttext: '分享'\n\t\t\t\t}, {\n\t\t\t\t\ttext: '评论'\n\t\t\t\t}],\n\t\t\t\tshow: true\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\tclick(index) {\n\t\t\t\tconsole.log(`点击了第${index + 1}项，内容为：${this.list[index].text}`)\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n\n### API\n\n### Props\n\n注意：props中没有控制组件弹出与收起的参数，因为这是通过v-model绑定变量实现的，见上方说明。\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| list | 按钮的文字数组，见上方文档示例  | Array\\<Object\\>\t | [ ] | - |\n| tips | 顶部的提示文字，见上方文档示例 | Object  | - | - |\n| cancel-btn | 是否显示底部的取消按钮 | Boolean  | true | false |\n| border-radius | 弹出部分顶部左右的圆角值，单位rpx | Number \\ String  | 0 | - |\n| mask-close-able | 点击遮罩是否可以关闭 | Boolean  | true | false |\n| safe-area-inset-bottom | 是否开启[底部安全区适配](/components/safeAreaInset.html#关于uview某些组件safe-area-inset参数的说明) | Boolean  | false | true |\n| z-index | `z-index`值 | Number \\ String  | 1075 | - |\n| cancel-text | 取消按钮的提示文字 | String  | 取消 | - |\n\n\n### Event\n\n|事件名|说明|回调参数|版本|\n|:-|:-|:-|:-|\n| click | 点击ActionSheet列表项时触发 | index: 点击了第几个，从0开始 | - |\n| close | 点击取消按钮时触发 | - | - |\n\n"
  },
  {
    "path": "src/static/app/markdown/addQQGroup.md",
    "content": "## 交流反馈\n\n<demo-model url=\"/pages/example/about\"></demo-model>\n\n#### 点击群号跳转 QQ 窗口：[群号：811732166](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=98nSVDldWEbDdq4lxiP4aL7uATfMSlI6&authKey=G2yQJ5MQiKzMldaxBsIfKt17NuJuUw8Fr6zdKLggc6NZXgw4BVbqkU2U3EE994yd&noverify=0&group_code=811732166)\n\n<chat-group></chat-group>\n"
  },
  {
    "path": "src/static/app/markdown/alertTips.md",
    "content": "## AlertTips 警告提示 <to-api/>\n\n<demo-model url=\"/pages/componentsC/alertTips/index\"></demo-model>\n\n警告提示，展现需要关注的信息。\n\n### 使用场景\n\n- 当某个页面需要向用户显示警告的信息时。\n- 非浮层的静态展现形式，始终展现，不会自动消失，用户可以点击关闭。\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |    √     |\n\n### 基本使用\n\n- 通过`title`和`description`设置组件的标题和描述内容，如果内容和标题同时存在，标题字体会被加粗加大\n- 通过`type`设置主题类型，有`primary`,`success`,`error`,`warning`,`info`可选值\n\n```html\n<template>\n\t<u-alert-tips type=\"warning\" :title=\"title\" :description=\"description\"></u-alert-tips>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\ttitle: '登高望远',\n\t\t\tdescription: '欲穷千里目，更上一层楼'\n\t\t}\n\t}\n</script>\n```\n\n### 图标\n\n通过`show-icon`设置是否显示图标，作用是让信息类型更加醒目。\n\n**注意**：当前版本图标为uView内置图标，根据`type`参数显示不同的图标，无法自定义。\n\n```html\n<u-alert-tips type=\"warning\" :show-icon=\"true\"></u-alert-tips>\n```\n\n### 可关闭的警告提示\n\n显示关闭按钮，点击可关闭警告提示。\n- `close-text`参数配置关闭的文字，默认为一个叉的icon图标。`close-able`为`true`时有效\n- `close-able`参数配置是否允许关闭的文字或图标\n\n\n由于`props`传参的限制，您需要监听组件的`close`事件，并在此此事件中设置`show`参数为`false`，才能关闭组件。\n\n\n```html\n<template>\n\t<u-alert-tips :show=\"show\" type=\"error\" @close=\"show = false\" :title=\"title\" :close-able=\"true\"></u-alert-tips>\n\t\n\t<u-alert-tips type=\"error\" :title=\"title\" close-text=\"close\" :description=\"description\" :close-able=\"true\"></u-alert-tips>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\ttitle: '寻隐者不遇',\n\t\t\tdescription: '松下问童子，言师采药去。只在此山中，云深不知处。',\n\t\t\tshow: true\n\t\t}\n\t}\n</script>\n```\n\n### API\n\n### Props\n\n| 参数        | 说明                                                            | 类型    | 默认值  | 可选值                           |\n| ----------- | --------------------------------------------------------------- | ------- | ------- | -------------------------------- |\n| title       | 显示的文字                                                      | String  | -       | -                                |\n| description | 辅助性文字，颜色比`title`浅一点，字号也小一点，可选             | String  | -       | -                                |\n| close-able  | 关闭按钮(默认为叉号icon图标)                                    | Boolean | false   | true                             |\n| type        | 使用预设的颜色                                                  | String  | warning | success / primary / error / info |\n| close-text  | 用文字替代关闭图标，`close-able`为`true`时有效                  | String  | -       | -                                |\n| show-icon   | 是否显示左边的辅助图标                                          | Boolean | false   | true                             |\n| show        | 显示或隐藏组件                                                  | Boolean | true    | false                            |\n| icon        | 左侧的图标名称，如设置`type`和`show-icon`值，会有一个默认的图标 | String  | -       | -                                |\n| icon-style  | 自定义图标的样式，对象形式                                      | Object  | -       | -                                |\n| title-style | 自定义标题的样式，对象形式                                      | Object  | -       | -                                |\n| desc-style  | 自定义内容的样式，对象形式                                      | Object  | -       | -                                |\n\n### Events\n\n| 事件名 | 说明                                              | 回调参数 |\n| :----- | :------------------------------------------------ | :------- |\n| close  | 点击关闭按钮时触发，需在此回调设置`show`为`false` | -        |\n| click  | 点击组件时触发                                    | -        |"
  },
  {
    "path": "src/static/app/markdown/avatar.md",
    "content": "## Avatar 头像 <to-api/>\n\n<demo-model url=\"/pages/componentsA/avatar/index\"></demo-model>\n\n\n本组件一般用于展示头像的地方，如个人中心，或者评论列表页的用户头像展示等场所。\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n通过`src`指定头像的路径即可简单使用，如果传递了`text`参数，`text`将会优先起作用  \n\n**注意：** 请保证传递给`src`的是绝对地址，而不是相对地址，为什么呢？因为传入`avatar`组件的相对地址，是相对于组件的，而不是父组件(页面)，所以相对址可能会出错。\n\n\n```html\n<template>\n\t<view>\n\t\t<u-avatar :src=\"src\"></u-avatar>\n\t\t<u-avatar :text=\"text\"></u-avatar>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tsrc: 'http://pic2.sc.chinaz.com/Files/pic/pic9/202002/hpic2119_s.jpg',\n\t\t\t\ttext: '无头像'\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 头像类型\n\n- `mode`参数指定头像的类型，取值`circle`为圆形，取值`square`为圆角方形\n\n```html\n<template>\n\t<u-avatar :src=\"src\" mode=\"square\"></u-avatar>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tsrc: 'http://pic2.sc.chinaz.com/Files/pic/pic9/202002/hpic2119_s.jpg'\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 默认头像\n\n如果头像加载失败，导致加载图片失败，将会显示一个默认的灰色头像\n\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| bg-color | 背景颜色，一般显示文字时用  | String | #ffffff | - |\n| src | 头像路径，如加载失败，将会显示默认头像  | String\t | - | - |\n| size | 头像尺寸，可以为指定字符串(large, default, mini)，或者数值，单位rpx | String \\| Number  | default | - |\n| mode | 显示类型，见上方说明 | String  | circle | square |\n| text | 用文字替代图片，级别优先于`src` | String  | - | - |\n| img-mode | 头像图片的裁剪类型，与uni的`image`组件的`mode`参数一致，如效果达不到需求，可尝试传`widthFix`值 | String  | aspectFill | - |\n| show-sex | 是否显示右上角的性别图标 | Boolean  | false | true |\n| sex-icon | 右上角性别图标，可传入图片路径，或内置图标名 | String  | man | woman |\n| sex-bg-color | 性别图标的背景颜色 | String  | man-primary主题，woman-error主题 | - |\n| show-level | 是否显示右下角的等级图标 | Boolean  | false | true |\n| level-icon | 右下角等级图标，可传入图片路径，或内置图标名 | String  | level | - |\n| level-bg-color | 等级图标的背景颜色 | String  | warning主题 | - |\n\n\n\n### Event\n\n|事件名|说明|回调参数|\n|:-|:-|:-|\n| click | 头像被点击 | index: 用户传递的标识符 |\n\n\n\n\n<style scoped>\nh3[id=props] + table thead tr th:nth-child(2){\n\twidth: 35%;\n}\n</style>\n"
  },
  {
    "path": "src/static/app/markdown/avatarCropper.md",
    "content": "## AvatarCropper 头像裁剪 <to-api/>\n\n<demo-model url=\"/pages/componentsA/avatarCropper/index\"></demo-model>\n\n该组件一般的图片裁剪需求场景，尤其适合于头像裁剪方面。\n\n### 平台差异说明\n\n| App | H5  | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ 小程序 |\n| :-: | :-: | :--------: | :----------: | :--------: | :--------: | :-------: |\n|  √  |  √  |     √      |      √       |     √      |     √      |     √     |\n\n### 基本使用\n\n组件使用流程：\n\n1. 打开头像裁剪页面，同时传递配置基本参数(已默认配置好最优参数)\n2. 选取图片，调整图片合适位置和大小，确定裁剪并返回此裁剪结果\n3. 在原始页面监听`uAvatarCropper`事件，获得裁剪结果\n\n```html\n<template>\n  <view class=\"wrap\">\n    <view class=\"u-avatar-wrap\">\n      <image class=\"u-avatar-demo\" :src=\"avatar\" mode=\"aspectFill\"></image>\n    </view>\n    <u-button @tap=\"chooseAvatar\">进入裁剪页</u-button>\n  </view>\n</template>\n\n<script>\n  export default {\n    data() {\n      return {\n        avatar: \"https://ik.imagekit.io/anyup/uview-pro/common/logo.png\",\n      };\n    },\n    created() {\n      // 监听从裁剪页发布的事件，获得裁剪结果\n      uni.$on(\"uAvatarCropper\", (path) => {\n        this.avatar = path;\n        // 可以在此上传到服务端\n        uni.uploadFile({\n          url: \"http://www.example.com/upload\",\n          filePath: path,\n          name: \"file\",\n          complete: (res) => {\n            console.log(res);\n          },\n        });\n      });\n    },\n    methods: {\n      chooseAvatar() {\n        // 此为uView的跳转方法，详见\"文档-JS\"部分，也可以用uni的uni.navigateTo\n        uni.$u.route({\n          // 关于此路径，请见下方\"注意事项\"\n          url: \"/uview-pro/components/u-avatar-cropper/u-avatar-cropper\",\n          // 内部已设置以下默认参数值，可不传这些参数\n          params: {\n            // 输出图片宽度，高等于宽，单位px\n            destWidth: 300,\n            // 裁剪框宽度，高等于宽，单位px\n            rectWidth: 200,\n            // 输出的图片类型，如果'png'类型发现裁剪的图片太大，改成\"jpg\"即可\n            fileType: \"jpg\",\n          },\n        });\n      },\n    },\n  };\n</script>\n\n<style lang=\"scss\" scoped>\n  .wrap {\n    padding: 40rpx;\n  }\n\n  .u-avatar-wrap {\n    margin-top: 80rpx;\n    overflow: hidden;\n    margin-bottom: 80rpx;\n    text-align: center;\n  }\n\n  .u-avatar-demo {\n    width: 150rpx;\n    height: 150rpx;\n    border-radius: 100rpx;\n  }\n</style>\n```\n\n### 注意事项\n\n根据`下载`方式和`NPM`方式引入 uView 的不同，需要进行不同的处理，下载方式可以引用`uview-pro`中的某个文件当做页面文件，但是`NPM`方式，不能引入\n`node_modules`文件夹中的`uview-pro`包的某个文件当做页面路径，故下方对两个方式分别说明：\n\n#### 1. 下载引入 uView 方式\n\n- 裁剪页面内置在 uView 中，由于打开页面，需要先在`pages.json`声明页面，故请把以下内容复制到项目根目录的`pages.json`中的`pages`数组中：\n\n```js\n{\n\t\"path\": \"uview-pro/components/u-avatar-cropper/u-avatar-cropper\",\n\t\"style\": {\n\t\t\"navigationBarTitleText\": \"头像裁剪\",\n\t\t\"navigationBarBackgroundColor\": \"#000000\"\n\t}\n}\n```\n\n#### 1. NPM 引入 uView 方式\n\n您需要去`node_modules`文件中，按路径`/node_modules/uview-pro/components/u-avatar-cropper/u-avatar-cropper.vue`找到此文件，将其内容复制出来，\n放到`/pages`文件夹中的某个文件中，再按上面下载方式引入的一样的操作，去声明和引用页面即可。\n\n- 裁剪后的结果，通过`uni.$on`监听`uAvatarCropper`事件，由于 uni-app 限制，H5 端裁剪的结果为`base64`格式，其他端为`blod`二进制形式，\n  如果后端对接收格式有要求，请自行处理\n\n### API\n\n以下参数，需要通过 URL 的 get 参数传参到裁剪页，非 props。uView 很多组件传递值的单位为`rpx`，注意这里的`dest-width`和`rect-width`单位为`px`\n\n### URL 参数\n\n| 参数       | 说明                                                           | 类型             | 默认值 | 可选值 |\n| ---------- | -------------------------------------------------------------- | ---------------- | ------ | ------ |\n| dest-width | 输出图片宽度，高等于宽，单位**px**                             | String \\| Number | 200    | -      |\n| rect-width | 裁剪框宽度，高等于宽，单位**px**                               | String \\| Number | 200    | -      |\n| file-type  | 输出的图片类型，如果'png'类型发现裁剪的图片太大，改成\"jpg\"即可 | String           | jpg    | png    |\n\n### Event\n\n| 事件名         | 说明                                | 回调参数             |\n| :------------- | :---------------------------------- | :------------------- |\n| uAvatarCropper | 裁剪结束后的事件，通过`uni.$on`监听 | path: 裁剪的图片数据 |\n"
  },
  {
    "path": "src/static/app/markdown/backTop.md",
    "content": "## BackTop 返回顶部 <to-api/>\n\n<demo-model url=\"/pages/componentsA/backTop/index\"></demo-model>\n\n\n该组件一个用于长页面，滑动一定距离后，出现返回顶部按钮，方便快速返回顶部的场景。\n\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n由于返回顶部需要实时监听滚动条的位置，从而判断返回的按钮该出现还是隐藏，由于组件无法得知页面的滚动条信息，只能在**页面**的`onPageScroll`生命周期\n中获得滚动条的位置，故需要在页面监听`onPageScroll`生命周期，实时获得滚动条的位置，通过Props传递给组件。\n\n```html\n<template>\n\t<view class=\"wrap\">\n\t\t<text>滑动页面，返回顶部按钮将出现在右下角</text>\n\t\t<u-back-top :scroll-top=\"scrollTop\"></u-back-top>\n\t</view>\n</template>\n\n<script>\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tscrollTop: 0\n\t\t}\n\t},\n\tonPageScroll(e) {\n\t\tthis.scrollTop = e.scrollTop;\n\t}\n};\n</script>\n\n<style lang=\"scss\" scoped>\n\t.wrap {\n\t\theight: 200vh;\n\t}\n</style>\n```\n\n\n### 改变返回顶部按钮的出现时机\n\n可以通过`top`参数，修改页面滚动多少距离时，出现返回顶部的按钮\n\n```html\n<u-back-top :scroll-top=\"scrollTop\" top=\"600\"></u-back-top>\n```\n\n\n### 自定义返回顶部的图标和提示\n\n- 通过`icon`修改返回顶部按钮的图标，可以是uView内置的图标，或者图片路径(需要1.3.0及以上版本)\n- 通过`tips`参数修改返回顶部按钮的文字提示信息，如果需要修改文字的颜色和大小，可以通过`custom-style`参数\n\n```html\n<u-back-top :scroll-top=\"scrollTop\" icon=\"arrow-up\" tips=\"返回\"></u-back-top>\n```\n\n\n### 其他自定义样式\n\n- 通过`icon-style`参数自定义图标的样式，比如颜色，大小等\n- 通过`custom-style`修改返回按钮的背景颜色，大小等\n- 通过`mode`修改按钮的形状，`circle`为圆形，`square`为方形\n\n注意：如果通过`icon`参数传入图片路径的话，需要通过`icon-style`参数设置图片的`width`和`height`属性\n\n```html\n<template>\n\t<view class=\"wrap\">\n\t\t<text>滑动页面，返回顶部按钮将出现在右下角</text>\n\t\t<u-back-top :scrollTop=\"scrollTop\" :mode=\"mode\" :icon-style=\"iconStyle\"></u-back-top>\n\t</view>\n</template>\n\n<script>\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tscrollTop: 0,\n\t\t\tmode: 'square',\n\t\t\ticonStyle: {\n\t\t\t\tfontSize: '32rpx',\n\t\t\t\tcolor: '#2979ff'\n\t\t\t}\n\t\t}\n\t},\n\tonPageScroll(e) {\n\t\tthis.scrollTop = e.scrollTop;\n\t}\n};\n</script>\n\n<style lang=\"scss\" scoped>\n\t.wrap {\n\t\theight: 200vh;\n\t}\n</style>\n```\n\n\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| mode | 按钮形状 | String | circle | square |\n| icon | uView内置图标名称，或图片路径 | String  | arrow-upward | - |\n| tips | 返回顶部按钮的提示文字 | String  | - | - |\n| duration | 返回顶部过程中的过渡时间，单位ms | String \\| Number  | 100 | - |\n| scroll-top | 页面的滚动距离，通过`onPageScroll`生命周期获取 | String \\| Number  | 0 | - |\n| top | 滚动条滑动多少距离时显示，单位rpx | String \\| Number  | 400 | - |\n| bottom | 返回按钮位置到屏幕底部的距离，单位rpx | String \\| Number  | 200 | - |\n| right | 返回按钮位置到屏幕右边的距离，单位rpx | String \\| Number  | 40 | - |\n| z-index | 返回顶部按钮的层级 | String \\| Number  | 9 | - |\n| icon-style | 图标的样式，对象形式 | Object  | - | - |\n| custom-style | 按钮外层的自定义样式 | Object  | - | - |\n\n\n\n\n### Slot\n\n|名称|说明|\n|:-|:-|\n| - | 自定义返回按钮的所有内容 |\n\n\n\n<style scoped>\nh3[id=slot] + table thead tr th:nth-child(2){\n\twidth: 50%;\n}\n</style>"
  },
  {
    "path": "src/static/app/markdown/badge.md",
    "content": "## Badge 徽标数 <to-api/>\n该组件一般用于图标右上角显示未读的消息数量，提示用户点击，有圆点和圆包含文字两种形式。\n\n<demo-model url=\"/pages/componentsC/badge/index\"></demo-model>\n\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |    √     |\n\n### 基本使用\n\n- 通过`count`参数定义徽标内容\n- 通过`type`设置主题。重申一次，uView中，所有组件的`type`参数都只有5个固定的可选值，分别是`primary`(蓝色-主色)，`warning`(黄色-警告)，\n`error`(红色-错误)，`success`(绿色-成功)，`info`(灰色-信息)\n\n\n此组件内部默认为`absolute`绝对定位，所以需要给`badge`父组件(元素)设置`position: relative`相对定位，\n再通过调整`offset`偏移值(数组，两个元素，第一个元素为`top`值，第二个元素为`right`值，单位rpx，可为负值，如\"[-10, -10]\")设置到合适的位置即可。  \n如果不需要组件内容默认的自动绝对定位，设置`absolute`参数为`false`即可。\n\n\n```html\n<u-badge type=\"error\" count=\"7\"></u-badge>\n```\n\n### 设置徽标的尺寸\n\n`size`参数默认为`default`，如果设置为`mini`，将会得到一个小尺寸的徽标，组件内部通过css的`scale`属性值进行缩放。\n\n```html\n<u-badge size=\"mini\" type=\"success\"></u-badge>\n```\n\n### 设置徽标的类型为一个圆点\n\n通过`is-dot`参数设置，该形式组件没有内容，只显示一个圆点\n\n```html\n<u-badge :is-dot=\"true\" type=\"success\"></u-badge>\n```\n\n### 自定义徽标样式\n\n该组件内部通过一个`view`元素实现，是一个根元素，依据`vue-cli`的`vue-loader`特性，在引用的组件上直接写类名或者内联样式，可以作用于组件内部的\n根元素上(微信小程序除外)，所以用户可以在组件引用时自定义修改样式 \n\n```html\n<u-badge type=\"green\" class=\"badge\"></u-badge>\n\n<style scoped>\n\t.badge {\n\t\tbackground-color: blue;\n\t\tcolor: white;\n\t}\n</style>\n```\n\n### 如何让组件中心点与父组件右上角重合\n\n某些特殊的场景下，特别是`badge`内容值是通过后端获取，长度未知时，会导致最终渲染出来的`badge`组件的位置与父组件右上角的位置有出入，\n为了解决这个问题，uView提供了一个`is-center`(默认为`false`)，如果设置为`true`，`offset`参数将会失效，同时`badge`组件的中心点\n将会和父组件的右上角重合。\n\n\n### API\n\n### Props\n\n| 参数           | 说明                                                                                                  | 类型             | 默认值   | 可选值                             |\n| -------------- | ----------------------------------------------------------------------------------------------------- | ---------------- | -------- | ---------------------------------- |\n| count          | 展示的数字，大于 `overflowCount` 时显示为 `${overflowCount}+`，为`0`且`show-zero`为`false`时隐藏      | String \\| Number | -        | -                                  |\n| is-dot         | 不展示数字，只有一个小点                                                                              | Boolean          | false    | true                               |\n| absolute       | 组件是否绝对定位，为`true`时，`offset`参数才有效                                                      | Boolean          | true     | false                              |\n| overflow-count | 展示封顶的数字值                                                                                      | String \\| Number | 99       | -                                  |\n| type           | 使用预设的背景颜色                                                                                    | String           | error    | success / primary / warning / info |\n| show-zero      | 当数值为 0 时，是否展示 Badge                                                                         | Boolean          | false    | true                               |\n| size           | Badge的尺寸，设为`mini`会得到小一号的`Badge`                                                          | String           | default  | mini                               |\n| offset         | 设置badge的位置偏移，格式为 [x, y]，也即设置的为`top`和`right`的值，单位rpx。`absolute`为`true`时有效 | Array            | [20, 20] | -                                  |\n| color          | 字体颜色                                                                                              | String           | #ffffff  | -                                  |\n| bgColor        | 背景颜色，优先级比`type`高，如设置，`type`参数会失效                                                  | String           | -        | -                                  |\n| is-center      | 组件中心点是否和父组件右上角重合，优先级比`offset`高，如设置，`offset`参数会失效                      | Boolean          | false    | true                               |\n\n\n\n<style scoped>\nh3[id=props] + table thead tr th:nth-child(2){\n\twidth: 40%;\n}\n</style>\n"
  },
  {
    "path": "src/static/app/markdown/button.md",
    "content": "## Button 按钮 <to-api/>\n\n<demo-model url=\"/pages/componentsC/button/index\"></demo-model>\n\n\n该组件内部实现以uni-app`button`组件为基础，进行二次封装，主要区别在于：\n- 按钮`type`值有更多的主题颜色\n- 有可选的按钮点击水波纹效果\n- 按钮`size`值有更多的尺寸可选\n\n\n1. 此组件内部使用uni-app`button`组件为基础，除了开头中所说的增加的功能，另外暴露出来的props属性和官方组件的属性完全一致，\nuni-app`button`组件比较特殊，因为它有一些其他小程序平台的特定能力，请参考文档后面的参数列表，更详细说明请参uni-app方文档：  \n[uni-app方button组件](https://uniapp.dcloud.io/component/button)  \n2. 由于微信小程序的限制，在微信小程序中设置了`form-type`的`u-button`无法触发`form`组件的`submit`事件(H5和APP正常)，详见微信小程序文档[Bug & Tip部分](https://developers.weixin.qq.com/miniprogram/dev/component/button.html)\n\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |    √     |\n\n### 基本使用\n文字内容通过`slot`传入\n\n```html\n<u-button>月落</u-button>\n```\n\n### 设置按钮的主题\n\n`type`值可选的有`default`(默认)、`primary`、`success`、`info`、`warning`、`error`\n\n```html\n<u-button >默认按钮</u-button>\n<u-button type=\"primary\">主要按钮</u-button>\n<u-button type=\"success\">成功按钮</u-button>\n<u-button type=\"info\">信息按钮</u-button>\n<u-button type=\"warning\">警告按钮</u-button>\n<u-button type=\"error\">危险按钮</u-button>\n```\n\n### 设置按钮为半圆形  \n\n`shape`默认值为`square`(按钮为圆角矩形)，设置为`circle`，则按钮两边为半圆形\n\n```html\n<u-button shape=\"square\">乌啼</u-button>\n```\n\n### 设置尺寸\n\n`button`组件的`size`（可选值为`default`(默认)，`mini`(小尺寸)和`medium`(中等尺寸)）\n\n```html\n<u-button size=\"default\">江湖</u-button>\n<u-button size=\"medium\">夜雨</u-button>\n<u-button size=\"mini\">十年灯</u-button>\n```\n\n### 设置按钮的镂空状态\n\n镂空状态按钮背景为白色，边框和文字同色，通过`plain`来设置\n\n```html\n<u-button plain>披荆</u-button>\n\n<!-- 或者显式设置为true -->\n<u-button :plain=\"true\">斩棘</u-button>\n```\n\n### 设置点击按钮的水波纹效果\n\n该效果通过给按钮绝对定位形式覆盖一个`view`，点击时改变`view`的`scale`，`opacity`样式属性，形成扩散再消失的水波纹效果。\n\n```html\n<u-button :ripple=\"true\">十年</u-button>\n\n<!-- 通过rippleBgColor设置水波纹的背景颜色 -->\n<u-button :ripple=\"true\" ripple-bg-color=\"#909399\">之约</u-button>\n```\n\n### 如何修改按钮的样式\n\n1. 针对非微信小程序平台，组件的根元素就是uni-app`button`组件，所以修改按钮的样式很容易，直接给组件定义`类名`或者嵌入`内联样式`即可。  \n2. 如果是微信小程序，编译后页面会有组件同名的元素存在，导致样式传递有问题。 \n3. 如果是为了修改按钮与其他元素之间的距离或者宽度等，可以给按钮外面套一个`view`元素，控制这个`view`与其他元素的距离或者宽度，即可达到同等效果。  \n\n所以：我们提供了一个`custom-style`参数，推荐用户可以用对象形式传递样式给组件内部，注意驼峰命名。\n\n```html\n/* 以下形式在微信小程序会无效，APP和H5有效 */\n<u-button class=\"custom-style\">雪月夜</u-button>\n\n<style scoped>\n\t.custom-style {\n\t\tcolor: #606266;\n\t\twidth: 400rpx;\n\t}\n</style>\n\n\n/* 推荐如下 */\n<u-button :custom-style=\"customStyle\">雪月夜</u-button>\n\n<script>\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tcustomStyle: {\n\t\t\t\tmarginTop: '20px', // 注意驼峰命名，并且值必须用引号包括，因为这是对象\n\t\t\t\tcolor: 'red'\n\t\t\t}\n\t\t};\n\t}\n};\n</script>\n```\n\n\n### 各家小程序开放能力的对接\n\nuView已对接uni-app档关于[uni-app方button组件](https://uni-app.dcloud.io/component/button)的所有开放能力(截止2020-04-14)uni-app-app文档说明使用即可，如果有发现遗漏的地方，请加群反馈。\n\n### API\n\n### Props\n\n\n| 属性名                 | 说明                                                                                                                                                           | 类型             | 默认值              | 可选值                                    | 平台差异说明                                    |\n| :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------- | :------------------ | :---------------------------------------- | :---------------------------------------------- |\n| size                   | 按钮的大小                                                                                                                                                     | String           | default             | medium / mini                             | -                                               |\n| ripple                 | 是否开启点击水波纹效果                                                                                                                                         | Boolean          | false               | true                                      | -                                               |\n| ripple-bg-color        | 水波纹的背景色，ripple为true时有效                                                                                                                             | String           | rgba(0, 0, 0, 0.15) | -                                         | -                                               |\n| type                   | 按钮的样式类型                                                                                                                                                 | String           | default             | primary / success / info/ warning / error | -                                               |\n| plain                  | 按钮是否镂空，背景色透明                                                                                                                                       | Boolean          | false               | true                                      | -                                               |\n| disabled               | 是否禁用                                                                                                                                                       | Boolean          | false               | true                                      | -                                               |\n| hair-line              | 是否显示按钮的细边框                                                                                                                                           | Boolean          | true                | false                                     | -                                               |\n| shape                  | 按钮外观形状，见上方说明                                                                                                                                       | String           | square              | circle                                    | -                                               |\n| loading                | 按钮名称前是否带 loading 图标                                                                                                                                  | Boolean          | false               | true                                      | App-nvue 平台，在 ios 上为雪花，Android上为圆圈 |\n| form-type              | 用于 `<form>` 组件，点击分别会触发 `<form>` 组件的 submit/reset 事件                                                                                           | String           | -                   | submit / reset                            | -                                               |\n| open-type              | 开放能力                                                                                                                                                       | String           | 请参考uni-app方文档 | -                                         | -                                               |\n| hover-class            | 指定按钮按下去的样式类。当 hover-class=\"none\" 时，没有点击态效果                                                                                               | String           | button-hover        | -                                         | App-nvue 平台暂不支持                           |\n| hover-start-time       | 按住后多久出现点击态，单位毫秒                                                                                                                                 | String \\| Number | 20                  | -                                         | -                                               |\n| hover-stay-time        | 手指松开后点击态保留时间，单位毫秒                                                                                                                             | String \\| Number | 150                 | -                                         | -                                               |\n| custom-style           | 对按钮的自定义样式，对象形式，见上方说明                                                                                                                       | Object           | -                   | -                                         | -                                               |\n| app-parameter          | 打开 APP 时，向 APP 传递的参数，open-type=launchApp时有效                                                                                                      | Boolean          | false               | true                                      | 微信小程序、QQ小程序                            |\n| hover-stop-propagation | 指定是否阻止本节点的祖先节点出现点击态                                                                                                                         | Boolean          | false               | true                                      | 微信小程序                                      |\n| lang                   | 指定返回用户信息的语言，zh_CN 简体中文，zh_TW 繁体中文，en 英文                                                                                                | String           | en                  | zh_CN \\ zh_TW                             | 微信小程序                                      |\n| session-from           | 会话来源，open-type=\"contact\"时有效                                                                                                                            | String           | -                   | -                                         | 微信小程序                                      |\n| send-message-title     | 会话内消息卡片标题，open-type=\"contact\"时有效                                                                                                                  | String           | 当前标题            | -                                         | 微信小程序                                      |\n| send-message-path      | 会话内消息卡片点击跳转小程序路径，open-type=\"contact\"时有效                                                                                                    | String           | 当前分享路径        | -                                         | 微信小程序                                      |\n| send-message-img       | 会话内消息卡片图片，open-type=\"contact\"时有效                                                                                                                  | String           | 当前页面截图        | -                                         | 微信小程序                                      |\n| show-message-card      | 是否显示会话内消息卡片，设置此参数为 true，用户进入客服会话会在右下角显示\"可能要发送的小程序\"提示，用户点击后可以快速发送小程序消息，open-type=\"contact\"时有效 | String           | -                   | -                                         | 微信小程序                                      |\n| throttle-time          | 节流的时间间隔(一定时间内无论点击多少次，只会触发一次`click`事件)，单位ms，详见[节流防抖](/js/debounce.html)                                                   | String \\| Number | 500                 | -                                         | -                                               |\n\n\n### Events\n\n**说明**：目前经测试(Hbuilder X 2.6.8)，在H5，APP，可以直接对组件监听`tap`事件，等同组件内部发出的`click`事件效果，某些HX版本上，\n微信小程序对组件使用`tap`事件可能无效，故建议对按钮组件的点击事件监听统一使用组件内部发出的`click`事件。\n\n| 属性名         | 说明                                                                                      | 类型    | 默认值     | 可选值 | 平台差异说明 |\n| :------------- | :---------------------------------------------------------------------------------------- | :------ | :--------- | :----- | :----------- |\n| click          | 按钮点击，请勿使用`@tap`点击事件，微信小程序无效，返回值为点击事件及参数                  | Handler | -          |\n| getphonenumber | open-type=\"getPhoneNumber\"时有效                                                          | Handler | 微信小程序 |\n| getuserinfo    | 用户点击该按钮时，会返回获取到的用户信息，从返回参数的detail中获取到的值同uni.getUserInfo | Handler | 微信小程序 |\n| error          | 当使用开放能力时，发生错误的回调                                                          | Handler | 微信小程序 |\n| opensetting    | 在打开授权设置页并关闭后回调                                                              | Handler | 微信小程序 |\n| launchapp      | 打开 APP 成功的回调                                                                       | Handler | 微信小程序 |\n"
  },
  {
    "path": "src/static/app/markdown/calendar.md",
    "content": "## Calendar 日历 <to-api/>\n\n<demo-model url=\"/pages/componentsA/calendar/index\"></demo-model>\n\n\n此组件用于单个选择日期，范围选择日期等，日历被包裹在底部弹起的容器中。\n\n**注意：** 此组件与[Picker 选择器](/components/picker.html)的日期选择模式有一定的重合之处，区别在于本组件为更专业的日期选择场景，能选择日期范围等。\n另外`Picker`组件的日期模式可以配置更多的参数，如时、分、秒等，可以根据不同的使用场景进行选择。\n\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n\n### 基本使用\n\n\n- 通过`v-model`绑定一个布尔变量用于打开或收起日历弹窗。\n- 通过`mode`参数指定选择单个日期，还是选择日期范围。\n\n```html\n<template>\n\t<view>\n\t\t<u-calendar v-model=\"show\" :mode=\"mode\"></u-calendar>\n\t\t<u-button @click=\"show = true\">打开</u-button>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tshow: false,\n\t\t\t\tmode: 'date'\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n\n### 日历模式\n\n- `mode`为`date`只能选择单个日期\n- `mode`为`range`可以选择日期范围\n\n\n### 单个日期模式\n\n选择日期后，需要点击底部的`确定`按钮才能触发回调事件，回调参数为一个对象，有如下属性：\n\n```js\n{\n\tday: 4, // 选择了哪一天\n\tdays: 30, // 这个月份有多少天\n\tisToday: true, // 选择的日期是否今天\n\tmonth: 6, // 选择的月份\n\tresult: \"2020-06-04\", // 选择的日期整体值\n\tweek: \"星期四\", // 选择日期所属的星期数\n\tyear: 2020 , // 选择的年份\n}\n```\n\n示例代码：\n\n```html\n<template>\n\t<u-calendar v-model=\"show\" :mode=\"mode\" @change=\"change\"></u-calendar>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tshow: true,\n\t\t\t\tmode: 'date'\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\tchange(e) {\n\t\t\t\tconsole.log(e);\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n\n### 日期范围模式\n\n此模式用于选择一个日期范围，比如住酒店的入住到离店的日期范围，有如下可配置的参数：\n\n- `active-bg-color`参数配置起始/结束日期按钮的背景色\n- `active-color`参数配置起始/结束日期按钮的字体颜色\n- `range-bg-color`参数配置起始/结束日期之间的区域的背景颜色，默认为`rgba(41,121,255,0.13)`，为浅蓝色\n- `start-text`参数用于设置起始日期底部的提示文字，如\"住店\"\n- `end-text`参数用于设置结束日期底部的提示文字，如\"离店\"\n\n\n此模式的返回参数如下：\n\n```js\n{\n\tendDate: \"2020-06-04\", // 选择的结束日期\n\tendDay: 4, // 结束日期是哪一天\n\tendMonth: 6, // 结束日期的月份\n\tendWeek: \"星期四\", // 结束日期的星期数\n\tendYear: 2020, // 结束日期的年份\n\tstartDate: \"2020-06-01\", // 选择的起始日期\n\tstartDay: 1, // 起始日期是哪一天\n\tstartMonth: 6, // 起始日期的月份\n\tstartWeek: \"星期一\", // 起始日期的星期数\n\tstartYear: 2020 // 起始日期的年份\n}\n```\n\n示例代码：\n\n```html\n<template>\n\t<u-calendar v-model=\"show\" :mode=\"mode\" @change=\"change\"></u-calendar>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tshow: true,\n\t\t\t\tmode: 'range'\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\tchange(e) {\n\t\t\t\tconsole.log(e);\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n\n### 自定义内容\n\n组件有一个默认插槽，名为`tooltip`，传入的内容将会显示在键盘的顶部位置，如使用，需要为传入的内容自定义样式。\n\n```html\n<template>\n\t<u-calendar v-model=\"show\" :mode=\"mode\" @change=\"change\">\n\t\t<template #tooltip>\n\t\t\t<view class=\"title\">\n\t\t\t\t请选择住店/离店时间\n\t\t\t</view>\n\t\t</template>\n\t</u-calendar>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tshow: true,\n\t\t\t\tmode: 'range'\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\tchange(e) {\n\t\t\t\tconsole.log(e);\n\t\t\t}\n\t\t}\n\t}\n</script>\n\n<style lang=\"scss\" scoped>\n\t.title{\n\t\tcolor: $u-type-primary;\n\t\ttext-align: center;\n\t\tpadding: 20rpx 0 0 0;\n\t}\n</style>\n```\n\n\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| mode | 选择日期的模式，date-为单个日期，range-为选择日期范围 | String | date | range |\n| v-model | 布尔值变量，用于控制日历的弹出与收起 | Boolean | false | true |\n| safe-area-inset-bottom | 是否开启[底部安全区适配](/components/safeAreaInset.html#关于uview某些组件safe-area-inset参数的说明) | Boolean  | false | true |\n| change-year | 是否显示顶部的切换年份方向的按钮  | Boolean | true | false |\n| change-month | 是否显示顶部的切换月份方向的按钮  | Boolean | true | false |\n| max-year | 可切换的最大年份 | Number \\| String | 2050 | - |\n| min-year | 可切换的最小年份 | Number \\| String | 1950 | - |\n| min-date | 最小可选日期 | Number \\| String | 1950-01-01 | - |\n| max-date | 最大可选日期 | Number \\| String | 当前日期 | - |\n| border-radius | 弹窗顶部左右两边的圆角值，单位rpx  | Number \\| String | 20 | - |\n| mask-close-able | 是否允许通过点击遮罩关闭日历  | Boolean | true | false |\n| month-arrow-color | 月份切换按钮箭头颜色 | String | #606266 | - |\n| year-arrow-color | 年份切换按钮箭头颜色 | String | #909399 | - |\n| color | 日期字体的默认颜色 | String | #303133 | - |\n| active-bg-color | 起始/结束日期按钮的背景色 | String | #2979ff | - |\n| z-index | 弹出时的`z-index`值 | String \\| Number | 10075 | - |\n| active-color | 起始/结束日期按钮的字体颜色 | String | #ffffff | - |\n| range-bg-color | 起始/结束日期之间的区域的背景颜色 | String | rgba(41,121,255,0.13) | - |\n| range-color | 选择范围内字体颜色 | String | #2979ff | - |\n| start-text | 起始日期底部的提示文字 | String | 开始 | - |\n| end-text | 结束日期底部的提示文字 | String | 结束 | - |\n| btn-type | 底部确定按钮的主题 | String | primary | default / success / info/ warning / error |\n| toolTip | 顶部提示文字，如设置名为`tooltip`的`slot`，此参数将失效 | String | 选择日期 | - |\n| closeable | 是否显示右上角的关闭图标 | Boolean | true | false |\n\n\n### Slot\n\n|名称|说明|\n|:-|:-|\n| tooltip | 自定义日历顶部的内容 |\n\n\n### Event\n\n|事件名|说明|回调参数|\n|:-|:-|:-|:-|\n| change | 点击右上角`确定`按钮时触发 | 选择日期相关的返回参数 |\n\n\n\n<style scoped>\nh3[id=props] + table thead tr th:nth-child(2){\n\twidth: 40%;\n}\n\nh3[id=slot] + table thead tr th:nth-child(2){\n\twidth: 50%;\n}\n</style>"
  },
  {
    "path": "src/static/app/markdown/card.md",
    "content": "## Card 卡片 <to-api/>\n\n<demo-model url=\"/pages/componentsB/card/index\"></demo-model>\n\n卡片组件一般用于多个列表条目，且风格统一的场景。\n\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n组件的头部信息可以通过参数配置，其他主体和底部的信息，需要通过`slot`传入。\n\n- `title`配置标题\n- `sub-title`配置副标题\n\n```html\n<template>\n\t<u-card :title=\"title\" :sub-title=\"subTitle\" :thumb=\"thumb\">\n\t\t<template #body>\n\t\t\t<view class=\"u-body-item u-flex u-border-bottom u-col-between u-p-t-0\">\n\t\t\t\t<view class=\"u-body-item-title u-line-2\">瓶身描绘的牡丹一如你初妆，冉冉檀香透过窗心事我了然，宣纸上走笔至此搁一半</view>\n\t\t\t\t<image src=\"https://img11.360buyimg.com/n7/jfs/t1/94448/29/2734/524808/5dd4cc16E990dfb6b/59c256f85a8c3757.jpg\" mode=\"aspectFill\"></image>\n\t\t\t</view>\n\t\t\t<view class=\"u-body-item u-flex u-row-between u-p-b-0\">\n\t\t\t\t<view class=\"u-body-item-title u-line-2\">釉色渲染仕女图韵味被私藏，而你嫣然的一笑如含苞待放</view>\n\t\t\t\t<image src=\"https://img12.360buyimg.com/n7/jfs/t1/102191/19/9072/330688/5e0af7cfE17698872/c91c00d713bf729a.jpg\" mode=\"aspectFill\"></image>\n\t\t\t</view>\n\t\t</template>\n\t\t<template #foot>\n\t\t\t<u-icon name=\"chat-fill\" size=\"34\" color=\"\" label=\"30评论\"></u-icon>\n\t\t</template>\n\t</u-card>\n</template>\n\n<script>\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\ttitle: '素胚勾勒出青花，笔锋浓转淡',\n\t\t\tsubTitle: '2020-05-15',\n\t\t\tthumb: 'http://pic2.sc.chinaz.com/Files/pic/pic9/202002/hpic2119_s.jpg',\n\t\t};\n\t}\n};\n</script>\n\n<style scoped lang=\"scss\">\n\t.u-card-wrap { \n\t\tbackground-color: $u-bg-color;\n\t\tpadding: 1px;\n\t}\n\t\n\t.u-body-item {\n\t\tfont-size: 32rpx;\n\t\tcolor: #333;\n\t\tpadding: 20rpx 10rpx;\n\t}\n\t\t\n\t.u-body-item image {\n\t\twidth: 120rpx;\n\t\tflex: 0 0 120rpx;\n\t\theight: 120rpx;\n\t\tborder-radius: 8rpx;\n\t\tmargin-left: 12rpx;\n\t}\n</style>\n```\n\n### 配置卡片间距\n\n可以通过`margin`参数配置卡片与屏幕左右的边距，以及上下卡片之间的距离，如: `20rpx 30rpx`、`20rpx 30rpx 30rpx 20rpx`。  \n注意：当设置`full`参数为`true`的时候，也就是卡片占据屏幕总宽度的时候，通过`margin`配置的左右边距会失效。\n\n```html\n<u-card margin=\"30rpx\"></u-card>\n```\n\n\n### 配置卡片左上角的缩略图\n\n这个缩略图是可选的，显示在卡片的左上角位置，如果配置了`thumb`参数(图片路径)，就会显示图片。  \n- `thumb`缩略图路径\n- `thumb-width`缩略图宽度，高等于宽\n- `thumb-circle`缩略图是否为圆形\n\n\n```html\n<u-card thumb=\"xxx.jpg\" thumb-width=\"60\"></u-card>\n```\n\n\n### 配置卡片边框\n\n这里说的边框，有3个：\n\n- `border`配置是否显示整个卡片的外边框\n- `head-border-bottom`配置是否显示卡片内部头部的下边框\n- `foot-border-top`配置是否显示卡片内部底部的上边框 \n\n```html\n<u-card :border=\"false\" :foot-border-top=\"false\"></u-card>\n```\n\n\n### 设置内边距\n\n默认下，卡片内部的头部，主体，底部都有一个内边距，可以通过配置`padding`参数去覆盖：\n\n```html\n<u-card padding=\"30\"></u-card>\n```\n\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| full | 卡片与屏幕两侧是否留空隙  | Boolean | fasle | true |\n| title | 头部左边的标题  | String\t | - | - |\n| title-color | 标题颜色 | String  | #303133 | - |\n| title-size | 标题字体大小，单位rpx | String \\| Number  | 30 | - |\n| sub-title | 头部右边的副标题 | String  | - | - |\n| sub-title-color | 副标题颜色 | String  | #909399 | - |\n| sub-title-size | 副标题字体大小 | String \\| Number  | 26 | - |\n| border | 是否显示边框 | Boolean  | true | false |\n| index | 用于标识点击了第几个卡片 | String \\| Number  | - | - |\n| margin | 卡片与屏幕两边和上下元素的间距，需带单位，如\"30rpx 20rpx\"，见上方说明 | String  | 30rpx | - |\n| border-radius | 卡片整体的圆角值，单位rpx | String \\| Number  | 16 | - |\n| head-style | 头部自定义样式，对象形式 | Object  | - | - |\n| body-style | 主体自定义样式，对象形式 | Object  | - | - |\n| foot-style | 底部自定义样式，对象形式 | Object  | - | - |\n| head-border-bottom | 是否显示头部的下边框 | Boolean  | true | false |\n| foot-border-top | 是否显示底部的上边框 | Boolean  | true | false |\n| thumb | 缩略图路径，如设置将显示在标题的左边，不建议使用相对路径 | String  | - | - |\n| thumb-width | 缩略图的宽度，高等于宽，单位rpx | String \\| Number  | 60 | - |\n| thumb-circle | 缩略图是否为圆形 | Boolean  | false | true |\n| padding | 给head，body，foot部的内边距，见上方说明，单位rpx | String \\| Number  | 30 | - |\n| show-head | 是否显示头部 | Boolean  | true | false |\n| show-foot | 是否显示尾部 | Boolean  | true | false |\n| box-shadow | 卡片外围阴影，字符串形式 | String  | none | - |\n\n\n### Slot\n\n| 名称          | 说明            |\n|-------------  |---------------- |\n| head | 自定义卡片头部内容  |\n| body | 自定义卡片主体部分内容 |\n| foot | 自定义卡片底部部分内容 |\n\n\n### Event\n\n|事件名|说明|回调参数|\n|:-|:-|:-|\n| click | 整个卡片任意位置被点击时触发 | index: 用户传递的标识符 |\n| head-click | 卡片头部被点击时触发 | index: 用户传递的标识符 |\n| body-click | 卡片主体部分被点击时触发 | index: 用户传递的标识符 |\n| foot-click | 卡片底部部分被点击时触发 | index: 用户传递的标识符 |\n\n\n\n\n<style scoped>\nh3[id=props] + table thead tr th:nth-child(2){\n\twidth: 35%;\n}\n\nh3[id=slot] + table thead tr th:nth-child(2){\n\twidth: 50%;\n}\n</style>"
  },
  {
    "path": "src/static/app/markdown/cell.md",
    "content": "## Cell 单元格 <to-api/>\n\n<demo-model url=\"/pages/componentsC/cell/index\"></demo-model>\n\n\ncell单元格一般用于一组列表的情况，比如个人中心页，设置页等。\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n- 该组件需要搭配`cell-group`使用，并由它实现列表组的上下边框，如不需要上下边框，配置`cellGroup`的`border`参数为`false`即可。\n- 通过`title`设置左侧标题，`value`设置右侧内容。\n- 通过`icon`字段设置图标，值为uView自带的[Icon 图标](/components/icon.html)名。\n\n**注意：** 由于`cell`组件需要由`cellGroup`组件提供参数值，这些父子组件间通过Vue的\"provide/inject\"特性注入依赖，\n所以您必须使用`cellGroup`包裹`cell`组件才能正常使用。\n\n```html\n<template>\n\t<u-cell-group>\n\t\t<u-cell-item icon=\"setting-fill\" title=\"个人设置\"></u-cell-item>\n\t\t<u-cell-item icon=\"integral-fill\" title=\"会员等级\" value=\"新版本\"></u-cell-item>\n\t</u-cell-group>\n</template>\n```\n\n### 自定义内容\n\n- 通过插槽`icon`可以自定义图标，内容会替换左边图标位置\n- 通过插槽`title`定义左边标题部分\n- 通过插槽`right-icon`定义右边内容部分\n\n```html\n<u-cell-group>\n\t<u-cell-item  title=\"夕阳无限好\" arrow-direction=\"down\">\n\t\t<template #icon>\n\t\t\t<u-icon size=\"32\" name=\"search\"></u-icon>\n\t\t</template>\n\t\t<template #right-icon>\n\t\t\t<u-switch v-model=\"checked\"></u-switch>\n\t\t</template>\n\t</u-cell-item>\n\t<u-cell-item icon=\"setting-fill\" title=\"只是近黄昏\"></u-cell-item>\n</u-cell-group>\n```\n\n如上所示，可以给`cell-item`组件通过`<template #right-icon></template>`设定右边uView自带的`badge`或者`switch`组件：\n- 如果搭配的是`badge`组件，注意设置`absolute`参数为`false`去掉绝对定位，否则其位于右侧的恰当位置，详见[Badge 徽标数](/components/badge.html)。\n- 如果搭配的是`switch`组件，注意要通过`v-model`绑定一个内容为布尔值的变量，否则无法操作`switch`，详见[Switch 开关选择器](/components/switch.html)。\n\n### 展示右箭头\n\n设置`arrow`为`true`，将会显示右侧的箭头，可以通过arrow-direction控制箭头的方向\n\n```html\n<u-cell-group>\n\t<u-cell-item icon=\"share\" title=\"停车坐爱枫林晚\" :arrow=\"true\" arrow-direction=\"down\"></u-cell-item>\n\t<u-cell-item icon=\"map\" title=\"霜叶红于二月花\" :arrow=\"false\"></u-cell-item>\n</u-cell-group>\n```\n\n### 分组标题\n\n通过`cell-group`的`title`参数可以指定分组标题\n\n```html\n<u-cell-group title=\"设置喜好\">\n\t<u-cell-item icon=\"setting-fill\" title=\"个人设置\"></u-cell-item>\n\t<u-cell-item icon=\"integral-fill\" title=\"会员等级\" value=\"新版本\"></u-cell-item>\n</u-cell-group>\n```\n\n\n### 是否开启点击反馈\n\n如果将`arrow`参数设置为`true`，意味着这是一个可点击的Cell，默认会给一个点击的反馈效果，如果您想自定义这个反馈效果，可以通过\n`hover-class`参数传入一个样式类名，这个类必须写在全局样式中，如`App.vue`、或通过`Apop.vue`引入的全局样式中，一般建议定义反馈的背景颜色，或者是透明度即可。\n如果不想要任何效果，将`hover-class`设置为`none`即可。\n\n```html\n<u-cell-group title=\"设置喜好\">\n\t<u-cell-item icon=\"setting-fill\" title=\"个人设置\" hover-class=\"cell-hover-class\"></u-cell-item>\n</u-cell-group>\n```\n\n```css\n/* App.vue */\n.cell-hover-class {\n\tbackground-color: rgb(235, 237, 238);\n}\n\n/* 或者单是设置透明度 */\n.cell-hover-class {\n\topacity: 0.5;\n}\n```\n\n### API\n\n### CellGroup Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| title | 分组标题  | String | - | - |\n| border | 是否显示外边框 | Boolean  | true | false |\n| title-style | 分组标题的的样式，对象形式，如{'font-size': '24rpx'} 或 {'fontSize': '24rpx'} | object  | - | - |\n\n### CellItem Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| title | 左侧标题  | String | - | - |\n| icon | 左侧图标名，只支持uView内置图标，见[Icon 图标](/components/icon.html) | String  | - | - |\n| icon-style | icon的样式，对象形式 | Object | - | - |\n| value | 右侧内容 | String  | - | - |\n| label | 标题下方的描述信息 | String | - | - |\n| border-bottom | 是否显示cell的下边框 | Boolean  | true | false |\n| border-top | 是否显示cell的上边框 | Boolean  | false | true |\n| border-gap | `border-bottom`为`true`时，Cell列表中间的条目的下边框是否与左边有一个间隔 <Badge type=\"error\" text=\"已废弃\" />  | Boolean  | true | false |\n| hover-class | 是否开启点击反馈，`none`为无效果，见上方说明 | String  | - | none |\n| arrow | 是否显示右侧箭头，开启的话，将会默认带上点击反馈，可通过`hover-class`配置 | Boolean | true | false |\n| arrow-direction | 箭头方向，可选值为 | String  | right | up / down |\n| title-style | 标题样式，对象形式 | Object | - | - |\n| required | 是否显示左边表示必填的星号 | Boolean | false | true |\n| value-style | 右侧内容样式，对象形式 | Object | - | - |\n| label-style | 标题下方描述信息的样式，对象形式 | Object | - | - |\n| bg-color | 背景颜色，默认透明背景 | String  | transparent | - |\n| index | 用于在`click`事件回调中返回，标识当前是第几个Item  | String \\| Number | - | - |\n| title-width | 标题的宽度，单位rpx | Number \\| String | - | - |\n| icon-size | 左边通过`icon`参数传入的图标的大小，单位rpx | Number \\| String | 34 | - |\n| center | 是否使内容垂直居中 | Boolean | false | true |\n\n\n### CellItem Slot\n\n| 名称          | 说明            |\n|-------------  |---------------- |\n| title | 自定义左侧标题部分的内容，如需使用，请勿定义`title`参数，或赋值`null`即可  |\n| icon | 自定义左侧的图标 |\n| right-icon | 自定义右侧图标内容，需设置`arrow`为`false`才起作用 |\n| label | 自定义`label`内容，需同时设置`use-label-slot`为`true` |\n\n### CellItem Event\n\n|事件名|说明|回调参数|\n|:-|:-|:-|:-|\n| click | 点击cell列表时触发 | index: 通过`props`传递的`index`参数 |\n\n\n\n<style scoped>\nh3[id=cellgroup-props] + table thead tr th:nth-child(2){\n\twidth: 40%;\n}\n\nh3[id=cellitem-props] + table thead tr th:nth-child(2){\n\twidth: 40%;\n}\n\nh3[id=cellitem-slot] + table thead tr th:nth-child(2){\n\twidth: 50%;\n}\n</style>"
  },
  {
    "path": "src/static/app/markdown/changeGuide.md",
    "content": "## 升级指南\n\n本专题不是每次更新版本的时候都会写入内容，只有某些需要特殊留意和处理的版本升级时，才会在这里写入相关的升级指导，如果您想看看uView近来\n都有哪些升级记录，请移步：[更新日志](/components/changelog.html)\n\n<demo-model url=\"/\"></demo-model>\n\n\n### 1.5.8升级指导(2020-08-03)\n\n由于`1.5.6`版本新增了[uni.$u.sys](/js/fastUse.html)和[uni.$u.os](/js/fastUse.html)属性，因为属性是初始化时执行一次，导致获取首页和\n内页通过`uni.$u.sys`获取`windowHeight`高度可能不准确的问题，详见[全局赋值设备信息的陷阱](/components/feature.html#全局赋值设备信息的陷阱)。  \n因此，我们在`1.5.8`版本中，将二者修改为方法的形式，简而言之，是需要后面加上括号，修改后为如下用法：\n```js\nconsole.log(uni.$u.sys()) \n\nconsole.log(uni.$u.os()) \n```\n这意味着，如果您使用了`uni.$u.sys`和`uni.$u.os`必须要将其修改为`uni.$u.sys()`和`uni.$u.os()`才行。\n\n\n### 1.5.4升级指导(2020-07-21)\n\n\n本次升级主要针对支付宝小程序，需要项目开启支付宝小程序的[component2](https://uniapp.dcloud.io/collocation/manifest?id=mp-alipay)模式(默认关闭)，做法：  \n在项目根目录`manifest.json`中新增`mp-alipay`属性节点，设置`component2`值为`true`：  \n```json\n......\n\"mp-alipay\" : {\n\t\"component2\": true\n},\n......\n```\n\n\n- 本次升级主要针对支付宝小程序的兼容，uView目前已全面实现对支付宝小程序的兼容，前提是需要开启支付宝特有的`component2`模式，才能实现一些新特性和支持。  \n- 本次升级中，由于table表格组件的单元格合并模式兼容性不好，且实现方式较为复杂，不利于该组件日后的升级和扩展，故在`1.5.4`版本废弃了table的单元格合并模式，\n如果您没有使用table的单元格合并模式，则无需理会，如果使用了可以按如下方法处理：\n1. 拷贝一份uView原来的table组件，单独引入：到`/uview-pro/components`中把`u-table`、`u-th`、`u-tr`、`u-td`拷贝到其他目录，另起别名使用\n2. 稍微修改组件用法，使用正常的table写法，放弃单元格合并模式\n\n<br>\n<br>\n\n\n### 1.2.8升级指导(2020-05-22)\n\n本次升级，对`Waterfall`瀑布流组件进行升级，新增了可以清空和移除瀑布流列表数据的组件内部方法，需要通过`ref`调用，因为组件内部无法直接修改父组件的数据，\n所以需要您手动将原来的`flow-list`参数改为`v-model`双向绑定父组件的数据，内部才可以修改父组件的瀑布流数组数据。\n\n<br>\n<br>\n\n### 1.1.9升级指导(2020-05-06)\n\n本次升级，对swipeAction组件进行了修改，可以配置多个按钮，原本通过`btn-text`和`btn-bg-color`配置按钮的文字和背景颜色，本次升级，加入`options`\n参数(数组)，可以配置多个按钮，详见[SwipeAction 滑动操作](/components/swipeAction.html)的基本说明，另外，点击的回调事件中，返回了两个\n参数，一个为Props传递的`index`参数，另一个`options`按钮参数的索引。\n\n<br>\n<br>\n\n### 1.1.7升级指导(2020-05-05)\n\n本次升级，迎来了uView的一个跨越发展，uView正式支持npm方式安装，借助此方式，您不用每次都下载覆盖升级，仅执行`npm update uview-pro`即可，\n由于uView在npm的包名为`uview-pro`，引入时需写上`import uView from \"uview-pro\"`，旧版中下载方式安装时uView的文件夹为`uview`，为了规范和统一，\n在此`1.1.7`版本后，uView将以前根目录的`uview`文件夹，改名为`uview-pro`，其他保持不变。  \n\n对此您有两个选择：\n1. uView下载解压后得到`uview-pro`文件夹，您可以将其改名为`uview`，从而覆盖原有的同名库(如果这不是您第一次下载的话)，这样您无需在`pages.json`、`main.js`、`uni.scss`、`App.vue`做出路径名称的变更(但是我们不推荐这样做)\n2. 如果您是在进行下载方式的升级，删掉(或备份)原来的`uview`文件夹，将`uview-pro`文件夹放到根目录，然后根据[下载安装方式配置](/components/downloadSetting.html)说明对`pages.json`、`main.js`、`uni.scss`、`App.vue`做出细微修改。(推荐此方式，一劳永逸)\n\n<br>\n<br>\n\n### 1.1.4升级指导(2020-04-29)\n\n由于本次更新，加入基础类[内置样式](/components/common.html)，需要作出一些调整(修改两行代码)，原因如下：\n\n1. 内置样式如果放在uni.scss文件中，在微信小程序上，由于编译机制的问题，会同时被打包\n到全局样式文件和单独的每个页面样式文件中，可能造成分包、整包变大而无法预览或者发布。故uView对此样式进行了分拆，将基础样式类放到uView库的`index.scss`中，由于目前uni-app的V3版本不支持在main.js中引入，\n故需要在App.vue中引入，不会导致被打包到每个单独的页面样式文件中。\n2. 由于uni-app的机制，对于SCSS的变量，只能在uni.scss中引入才生效，故uView将主题样式变量相关的部分，放到了uView库的`theme.scss`文件中。\n\n具体操作如下：\n\n- 在`App.vue`中**首行**的位置，增加如下一行`import \"@/uview-pro/index.scss\"`：\n\n\n1. 必须要将标签加入`lang=\"scss\"`属性以支持SCSS，否则会出错！\n2. 请将将引入的代码，写在`style`标签的首行。\n\n\n```css\n<style lang=\"scss\">\n\t/* 注意要写在第一行，同时给style标签加入lang=\"scss\"属性 */\n\t@import \"@/uview-pro/index.scss\";\n\t\n\t/* ......其他的样式 */\n</style>\n```\n\n- 在项目根目录的`uni.scss`中，删除原来的`@import '@/uview-pro/theme.scss';`一行，改成如下：\n\n```js\n// 删除原来的这一行\n// @import '@/uview-pro/index.scss';\n\n// 加入这一行\n@import '@/uview-pro/theme.scss';\n```"
  },
  {
    "path": "src/static/app/markdown/changelog.md",
    "content": "## 0.0.19（2025-09-04）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- include uview-pro changelog.md in release commit ([18d902d](https://github.com/anyup/uView-Pro/commit/18d902db2bba4f8f574d7b3b72be218747525bb9))\n\n### 📝 Documentation | 文档\n\n- update uview pro changelog ([31261db](https://github.com/anyup/uView-Pro/commit/31261dbd6b17aea8126a43def1912324b782096e))\n\n### ♻️ Code Refactoring | 代码重构\n\n- 移除 uni-http 模块 ([5f21735](https://github.com/anyup/uView-Pro/commit/5f2173503cc904fb0a7fa2abd3ed3b9dbe09aeb2))\n\n### ✨ Features | 新功能\n\n- 新增http请求模块并实现插件化 ([31c6f88](https://github.com/anyup/uView-Pro/commit/31c6f880d12e586d445faddcc1a3910fda9926bc))\n- 增强 toast 工具函数的灵活性 ([2232054](https://github.com/anyup/uView-Pro/commit/22320540acee36c6c11688387431a4ddba93520f))\n- 添加 HTTP 请求拦截器和配置示例代码 ([aba7cf9](https://github.com/anyup/uView-Pro/commit/aba7cf97ed2424432da51be1841aa17a5a2d7932))\n\n## 0.0.18（2025-09-03）\n\n### 🚀 Chore | 构建/工程依赖/工具\n\n- update release script for better version management ([b64f38f](https://github.com/anyup/uView-Pro/commit/b64f38fea28de39c99cdf84f7e767aa7ceac1344))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-checkbox:** 兼容头条小程序获取父组件数据不支持provide/inject的写法 ([498e12e](https://github.com/anyup/uView-Pro/commit/498e12e2f3aa52021d1be282426536b45f39ca6a))\n\n### 👷 Continuous Integration | CI 配置\n\n- optimize changelog generation and spacing ([3103e7b](https://github.com/anyup/uView-Pro/commit/3103e7b56a0e2dd0392efdb6a85824b11ef6800c))\n\n## 0.0.17（2025-09-02）\n\n### ♻️ Code Refactoring | 代码重构\n\n-   瀑布流组件示例代码重构为 Vue3 ([93949ad](https://github.com/anyup/uView-Pro/commit/93949ad8ae2a36c6130f87340c222ab9ec69d21f))\n\n### ✨ Features | 新功能\n\n-   新增组件 u-loading-popup，一个可以配置的加载提示弹窗 ([6245df9](https://github.com/anyup/uView-Pro/commit/6245df951034b06225ab36d3f18cae8e7ab4b329))\n-   新增 Loading 加载弹窗组件的示例页面 ([1bce868](https://github.com/anyup/uView-Pro/commit/1bce86810863012c5a73104ca0a85ebacb4aa92a))\n\n### 🐛 Bug Fixes | Bug 修复\n\n-   修复瀑布流组件 u-waterfll，暴露 celar/remove/modify 方法 ([240e023](https://github.com/anyup/uView-Pro/commit/240e0238af092d4c6bde86d0db9e49636b806d6f))\n\n## 0.0.15（2025-08-30）\n\n### ✨ Features | 新功能\n\n-   优化 u-image 组件 slot 使用体验，兼容头条小程序 ([a6ca54f](https://github.com/anyup/uView-Pro/commit/a6ca54fce06b20b7a6938d0bef9342954b787641))\n\n### ♻️ Bug Fixes | Bug 修复\n\n-   优化 label 的声明错误问题 ([314c394](https://github.com/anyup/uView-Pro/commit/314c3940145c657b12f16d005af7d271f4ae74e3))\n-   优化头条小程序 form 表单校验的兼容性问题 ([3912fd6](https://github.com/anyup/uView-Pro/commit/3912fd6ade3a1d612f6f5e86ddc0336376ee5618))\n\n## 0.0.14（2025-08-28）\n\n### 🐛 Bug Fixes | Bug 修复\n\n-   修复使用 u-swipe-action 右边会出现一条背景线的 bug ([a5b60c6](https://github.com/anyup/uView-Pro/commit/a5b60c6485120e164c0e0c29eea3b765c10f9aac))\n\n## 0.0.13（2025-08-27）\n\n### 🐛 Bug Fixes | Bug 修复\n\n-   修复 count-down 组件暴露 start 和 end 方法 ([0f42a01](https://github.com/anyup/uView-Pro/commit/0f42a01f55aa6799f57eb93dc5d029b06115b154))\n\n## 0.0.12（2025-08-27）\n\n### 🐛 Bug Fixes | Bug 修复\n\n-   优化 async-validator 文件多余注释导致的问题 ([f06c80d](https://github.com/anyup/uView-Pro/commit/f06c80d57e61e7b75f1384fe89f309b8a0e379fa))\n\n## 0.0.11（2025-08-26）\n\n### ♻️ Code Refactoring | 代码重构\n\n-   取消 async-validator ts 检查 ([772a729](https://github.com/anyup/uView-Pro/commit/772a729164f2cb268a886b6749e4a58846ebb3dc))\n-   移除 u-tr 未使用的类型导入和属性定义 ([46ce459](https://github.com/anyup/uView-Pro/commit/46ce4590166a30a0eb048110efc046095a87f6e8))\n\n### 🐛 Bug Fixes | Bug 修复\n\n-   修复 u-count-down 倒计时符号显示逻辑 ([a4c9498](https://github.com/anyup/uView-Pro/commit/a4c94986b020c5ac0fdf92bde3c7b79cdfbedbe8))\n\n## 0.0.10（2025-08-26）\n\n### ✨ Features | 新功能\n\n-   添加 easycom 组件自动扫描 ([b125039](https://github.com/anyup/uView-Pro/commit/b1250390a4f594f5deaa133d7a92bd6e72707890))\n-   增强 u-select 组件的类型安全和功能 ([38635e9](https://github.com/anyup/uView-Pro/commit/38635e963f9eff6e4c730692e8c97f10b3a092c5))\n\n## 0.0.9（2025-08-25）\n\n### ♻️ Code Refactoring | 代码重构\n\n-   优化全局工具导出方式 ([7a80b6f](https://github.com/anyup/uView-Pro/commit/7a80b6f99ad3022ca995f99f8ec6803af7941eb9))\n\n## 0.0.8（2025-08-25）\n\n### ♻️ Code Refactoring | 代码重构\n\n-   重构组件 Props 属性定义，每个组件具有完善的 ts 类型定义 ([8cc0de7](https://github.com/anyup/uView-Pro/commit/8cc0de7c1527b48dd223d89207135eea01766294))\n-   重构类型定义并统一到全局类型文件 global types ([b0fd010](https://github.com/anyup/uView-Pro/commit/b0fd0107289eb1c6df2f58d91b63d9b25902caee))\n\n## 0.0.7（2025-08-21）\n\n### 🐛 Bug Fixes | Bug 修复\n\n-   修复中 tabbar 布局高度计算错误的问题 ([5c1342c](https://github.com/anyup/uView-Pro/commit/5c1342cb3fb6dd2c7c84fe785953fcaed13e809f))\n\n### 📦‍ Build System | 打包构建\n\n-   更新项目依赖并优化打包构建 ([c172d36](https://github.com/anyup/uView-Pro/commit/c172d368d82404564650756a872cd7c7e29ebfa2))\n\n## 0.0.5（2025-08-19）\n\n### ✨ Features | 新功能\n\n-   新增 u-city-select 城市选择器组件 ([0eb4806](https://github.com/anyup/uView-Pro/commit/0eb4806db3be39e1a6c6f33c9ea511d8445da884))\n-   完善 u-button 的 open-type 支持类型 ([37c0db5](https://github.com/anyup/uView-Pro/commit/37c0db527258bca57dbd55d7013b633230489853))\n\n### 🐛 Bug Fixes | Bug 修复\n\n-   u-upload 暴露 lists 属性 ([09f8424](https://github.com/anyup/uView-Pro/commit/09f8424774baaee3b6fc7a42458949f8d5903951))\n-   u-upload 深度监听文件列表变化并优化事件触发 ([a41a571](https://github.com/anyup/uView-Pro/commit/a41a5719ddf9d6793b78c55a13025bbdc88fdfe3))\n\n### 🚀 Demos | 示例页面优化\n\n-   优化关于页面布局和内容 ([ad5f6a4](https://github.com/anyup/uView-Pro/commit/ad5f6a47847999268b43b8c5dbf1a34cb8f70802))\n-   删除分类数据文件 ([5ed7a11](https://github.com/anyup/uView-Pro/commit/5ed7a1113db58ff493ad606296a210358348affe))\n-   重构 index list 页面 ([13d780e](https://github.com/anyup/uView-Pro/commit/13d780ea5acc4c8eed72062482735df826d4b37a))\n-   更新商场菜单组件引用 ([a5f1bf3](https://github.com/anyup/uView-Pro/commit/a5f1bf3f256705d6cad028d60701b4b0544332de))\n-   修改图片地址 ([c459893](https://github.com/anyup/uView-Pro/commit/c459893848936aa9a44e7bda3277ab1428109869))\n-   重构 upload 上传组件示例页面 ([686831d](https://github.com/anyup/uView-Pro/commit/686831de357aca67bbf7015e2f0696cf6bf48164))\n-   优化多个组件的代码结构和样式 ([f2af44c](https://github.com/anyup/uView-Pro/commit/f2af44ca1710334495e4c4fad99d04027b3788f8))\n-   添加提交规范相关配置文件 git-cz/husky/changelog ([d93b816](https://github.com/anyup/uView-Pro/commit/d93b816a5a3e468c4bc45e3161d7c006cba5fbf6))\n-   优化 deepClone 和 deepMerge 页面的结果展示 ([b0daa70](https://github.com/anyup/uView-Pro/commit/b0daa700b6a385e037d38dc1f10b3612596e2403))\n-   新增优惠券模板 ([1b77762](https://github.com/anyup/uView-Pro/commit/1b777621615f7ebe9d83606d53650987c8b2c4e0))\n-   更新 easycom 配置说明，一定要放在 custom 里，否则不生效 ([fc14bf9](https://github.com/anyup/uView-Pro/commit/fc14bf90cb77088d258e20e79e3d25820f37e97e))\n-   添加模板示例页面 ([3336af4](https://github.com/anyup/uView-Pro/commit/3336af406161648d18578c988d9b3ad79b86059a))\n-   新增模版相关页面 ([8925a02](https://github.com/anyup/uView-Pro/commit/8925a02f9fa88f4742d984f2ff02909afc6ad0d7))\n-   重构 request 类，优化泛型支持 ([d7b2e6a](https://github.com/anyup/uView-Pro/commit/d7b2e6a224d96f717e5bdbaf09edb19b712ced47))\n\n## 0.0.4（2025-08-14）\n\n### 新增\n\n-   `u-icon` 组件新增 `space` 属性，表示`label` 在四周时与图标的距离，权重高于 `margin`，单位 rpx\n-   新增`$u`工具库各类方法，同步文档\n-   组件全部 setup 化，全面支持 TypeScript 和 Vue3\n-   工具库示例页面全部 setup 化\n\n### 优化\n\n-   组件样式兼容多端\n-   代码注释与类型完善\n-   优化演示代码兼容性\n\n### 修复\n\n-   修复类型声明、变量冲突、lint 报错等问题\n\n## 0.0.3（2025-08-06）\n\n-   添加插件使用示例工程\n\n## 0.0.2（2025-08-04）\n\n-   解决一些 npm 包依赖问题\n\n## 0.0.1（2025-08-04）\n\n-   70+精选组件，使用 Vue3+TS 全面重构，功能丰富，多端兼容，让您快速集成，开箱即用\n-   兼容安卓，iOS，微信小程序，H5 等\n-   详尽的文档支持，现代化的演示效果\n-   按需引入，精简打包体积\n\n### 基础组件（8）\n\n-   Color 色彩\n-   Icon 图标\n-   Image 图片\n-   Button 按钮\n-   Layout 布局\n-   Cell 单元格\n-   Badge 徽标数\n-   Tag 标签\n\n---\n\n### 表单组件（15）\n\n-   Form 表单\n-   Calendar 日历\n-   Select 列选择器\n-   Keyboard 键盘\n-   Picker 选择器\n-   Rate 评分\n-   Search 搜索\n-   NumberBox 步进器\n-   Upload 上传\n-   VerificationCode 验证码倒计时\n-   Field 输入框\n-   Checkbox 复选框\n-   Radio 单选框\n-   Switch 开关选择器\n-   Slider 滑动选择器\n\n---\n\n### 数据组件（4）\n\n-   Progress 进度条\n-   Table 表格\n-   CountDown 倒计时\n-   CountTo 数字滚动\n\n---\n\n### 反馈组件（10）\n\n-   ActionSheet 操作菜单\n-   AlertTips 警告提示\n-   Toast 消息提示\n-   NoticeBar 滚动通知\n-   TopTips 顶部提示\n-   SwipeAction 滑动单元格\n-   Collapse 折叠面板\n-   Popup 弹出层\n-   Modal 模态框\n-   fullScreen 压窗屏\n\n---\n\n### 布局组件（11）\n\n-   Line 线条\n-   Card 卡片\n-   Mask 遮罩层\n-   NoNetwork 无网络提示\n-   Grid 宫格布局\n-   Swiper 轮播图\n-   TimeLine 时间轴\n-   Skeleton 骨架屏\n-   Sticky 吸顶\n-   Waterfall 瀑布流\n-   Divider 分割线\n\n---\n\n### 导航组件（11）\n\n-   Dropdown 下拉菜单\n-   Tabbar 底部导航栏\n-   BackTop 返回顶部\n-   Navbar 导航栏\n-   Tabs 标签\n-   TabsSwiper 全屏选项卡\n-   Subsection 分段器\n-   IndexList 索引列表\n-   Steps 步骤条\n-   Empty 内容为空\n-   Section 查看更多\n\n---\n\n### 其他组件（8）\n\n-   MessageInput 验证码输入\n-   Loadmore 加载更多\n-   ReadMore 展开阅读更多\n-   LazyLoad 懒加载\n-   Gap 间隔槽\n-   Avatar 头像\n-   Link 超链接\n-   Loading 加载动画\n\n---\n"
  },
  {
    "path": "src/static/app/markdown/chatGroup.md",
    "content": "## 交流反馈\n\n<demo-model url=\"/pages/example/about\"></demo-model>\n\n#### 点击群号跳转 QQ 窗口：[群号：811732166](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=98nSVDldWEbDdq4lxiP4aL7uATfMSlI6&authKey=G2yQJ5MQiKzMldaxBsIfKt17NuJuUw8Fr6zdKLggc6NZXgw4BVbqkU2U3EE994yd&noverify=0&group_code=811732166)\n\n<chat-group></chat-group>\n"
  },
  {
    "path": "src/static/app/markdown/checkbox.md",
    "content": "## Checkbox 复选框 <to-api/>\n\n<demo-model url=\"/pages/componentsB/checkbox/index\"></demo-model>\n\n\n复选框组件一般用于需要多个选择的场景，该组件功能完整，使用方便\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n- 该组件无需强制搭配`checkboxGroup`组件使用(视情况而定)，可以单个独立使用`u-checkbox`组件\n- 通过`v-model`给`checkbox`绑定一个变量，这个绑定的变量是双向的(初始值只能是`true`或者`false`)，也就是说，您可以无需监听`checkbox`或者`checkboxGroup`组件的`change`事件，也能知道哪个复选框\n被勾选了\n\n\n```html\n<template>\n\t<view class=\"\">\n\t\t<u-checkbox-group @change=\"checkboxGroupChange\">\n\t\t\t<u-checkbox \n\t\t\t\t@change=\"checkboxChange\" \n\t\t\t\tv-model=\"item.checked\" \n\t\t\t\tv-for=\"(item, index) in list\" :key=\"index\" \n\t\t\t\t:name=\"item.name\"\n\t\t\t>{{item.name}}</u-checkbox>\n\t\t</u-checkbox-group>\n\t\t<u-button @click=\"checkedAll\">全选</u-button>\n\t</view>\n</template>\n\n<script>\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tlist: [\n\t\t\t\t{\n\t\t\t\t\tname: 'apple',\n\t\t\t\t\tchecked: false,\n\t\t\t\t\tdisabled: false\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'banner',\n\t\t\t\t\tchecked: false,\n\t\t\t\t\tdisabled: false\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'orange',\n\t\t\t\t\tchecked: false,\n\t\t\t\t\tdisabled: false\n\t\t\t\t}\n\t\t\t]\n\t\t};\n\t},\n\tmethods: {\n\t\t// 选中某个复选框时，由checkbox时触发\n\t\tcheckboxChange(e) {\n\t\t\t//console.log(e);\n\t\t},\n\t\t// 选中任一checkbox时，由checkbox-group触发\n\t\tcheckboxGroupChange(e) {\n\t\t\t// console.log(e);\n\t\t},\n\t\t// 全选\n\t\tcheckedAll() {\n\t\t\tthis.list.map(val => {\n\t\t\t\tval.checked = true;\n\t\t\t})\n\t\t}\n\t}\n};\n</script>\n```\n\n### 禁用checkbox\n\n设置`disabled`为`true`，即可禁用某个组件，让用户无法点击，禁用分为两种状态，一是未勾选前禁用，这时只显示一个灰色的区域。二是已勾选后\n再禁用，会有灰色的已勾选的图标，但此时依然是不可操作的。\n\n```html\n<u-checkbox-group>\n\t<u-checkbox v-model=\"checked\" :disabled=\"false\">天涯</u-checkbox>\n</u-checkbox-group>\n```\n\n### 自定义形状\n\n可以通过设置`shape`为`square`或者`circle`，将复选框设置为方形或者圆形\n\n\n```html\n<u-checkbox-group>\n\t<u-checkbox v-model=\"checked\" shape=\"circle\">明月</u-checkbox>\n</u-checkbox-group>\n```\n\n\n### 自定义颜色\n\n此处所指的颜色，为`checkbox`选中时的背景颜色，参数为`active-color`\n\n\n```html\n<u-checkbox-group>\n\t<u-checkbox v-model=\"checked\" active-color=\"red\">光影</u-checkbox>\n</u-checkbox-group>\n```\n\n\n### 文本是否可点击\n\n设置`label-disabled`为`false`，点击文本时，无法操作`checkbox`\n\n\n\n```html\n<u-checkbox-group>\n\t<u-checkbox v-model=\"checked\" :label-disabled=\"false\">剑舞</u-checkbox>\n</u-checkbox-group>\n```\n\n\n### API\n\n### Checkbox Props\n\n注意：需要给`checkbox`组件通过`v-model`绑定一个**布尔值**，来初始化`checkbox`的状态，随后该值被双向绑定，\n当用户勾选复选框时，该值在`checkbox`内部被修改为`true`，并反映到父组件，否则为`false`，换言之，您无需监听`checkbox`的`change`事件，也能\n知道某一个`checkbox`是否被选中的状态\n\n注意：`checkbox`和`checkbox-group`二者同名参数中，`checkbox`的参数优先级更高。\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| v-model | 双向绑定某一个`checkbox`的值，如果将该变量设置为`true`，将会被选中 | String \\ Number | - | - |\n| size | 组件整体的大小，单位rpx  | String \\ Number | - | - |\n| label-size | label字体大小，单位rpx  | String \\ Number | - | - |\n| icon-size | 图标大小，单位rpx  | String \\ Number | - | - |\n| name | `checkbox`组件的标示符  | String \\ Number | - | - |\n| shape | 形状，见上方说明 | String  | - | square |\n| disabled | 是否禁用 | Boolean  | - | false / true |\n| label-disabled | 是否禁止点击文本操作`checkbox` | Boolean  | - | false / true |\n| active-color | 选中时的颜色，如设置`CheckboxGroup`的`active-color`将失效 | String  | - | - |\n\n\n\n### CheckboxGroup Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| max | 最多能选中多少个`checkbox`  | String \\ Number | 999 | - |\n| disabled | 是否禁用所有`checkbox`  | Boolean | false | true |\n| icon-size | 图标大小，单位rpx  | String \\ Number | 20 | - |\n| size | 组件整体的大小，单位rpx  | String \\ Number | 34 | - |\n| shape | 形状，见上方说明 | String  | circle | square |\n| active-color | 选中时的颜色，应用到所有子`Checkbox`组件 | String  | #2979ff | - |\n| label-disabled | 是否禁止点击文本操作`checkbox` | Boolean  | false | true |\n| width | `checkbox`的宽度，需带单位，如`50%`，`150rpx` | String  | auto | - |\n| wrap | 是否每个`checkbox`占一行 | Boolean  | false | true |\n\n\n### Checkbox Event\n\n|事件名|说明|回调参数|版本|\n|:-|:-|:-|:-|\n| change | 某个`checkbox`状态发生变化时触发，回调为一个对象 | detail = {value: [true或者false，true为被选中，否则反之], name: [通过props传递的`name`参数] } | - |\n\n\n### CheckboxGroup Event\n\n|事件名|说明|回调参数|版本|\n|:-|:-|:-|:-|\n| change | 任一个`checkbox`状态发生变化时触发，回调为一个对象 | detail = array( [元素为被选中的`checkbox`的`name`] ) | - |\n\n\n\n<style scoped>\nh3[id=checkbox-props] + p + table thead tr th:nth-child(2){\n\twidth: 35%;\n}\n</style>"
  },
  {
    "path": "src/static/app/markdown/circleProgress.md",
    "content": "## CircleProgress 圆形进度条 <to-api/>\n\n\n<demo-model url=\"/pages/componentsC/progress/index\"></demo-model>\n\n\n展示操作或任务的当前进度，比如上传文件，是一个圆形的进度环。  \n\n### 内部实现\n\n组件内部通过`canvas`实现，有更好的性能和通用性。\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n- 通过`percent`设置当前的进度值，该值区间为0-100\n- 通过`active-color`设置圆环的颜色，也可以直接设置`type`主题颜色，使用预置值\n- 通过默认`slot`传入内容，将会显示在圆环的内部\n\n```html\n<template>\n\t<u-circle-progress active-color=\"#2979ff\" :percent=\"80\">\n\t\t<view class=\"u-progress-content\">\n\t\t\t<view class=\"u-progress-dot\"></view>\n\t\t\t<text class='u-progress-info'>查找中</text>\n\t\t</view>\n\t</u-circle-progress>\n</template>\n\n<style lang=\"scss\" scoped>\n\t.u-progress-content {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t}\n\t\n\t.u-progress-dot {\n\t\twidth: 16rpx;\n\t\theight: 16rpx;\n\t\tborder-radius: 50%;\n\t\tbackground-color: #fb9126;\n\t}\n\t\n\t.u-progress-info {\n\t\tfont-size: 28rpx;\n\t\tpadding-left: 16rpx;\n\t\tletter-spacing: 2rpx\n\t}\n</style>\n```\n\n### 设置圆环的动画时间\n\n通过`duration`设置圆环从0递增到100%(也即一圆周)所需的时间，如需动态修改进度值时会用到，比如用户进行某一个操作之后，\n需要把进度值从30%改为80%，这里增加了50%(80% - 30% = 50%)，也即半个圆周，所需时间为`duration`的一半，因为`duration`值为一个圆周的时间。\n\n```html\n<u-circle-progress type=\"primary\" :percent=\"30\" duration=\"2000\"></u-circle-progress>\n```\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| percent | 圆环进度百分比值，为数值类型，0-100  | String \\| Number | - | - |\n| inactive-color | 圆环的底色，默认为灰色(该值无法动态变更) | String  | #ececec | - |\n| active-color | 圆环激活部分的颜色(该值无法动态变更) | String  | #19be6b | - |\n| width | 整个圆环组件的宽度，高度默认等于宽度值，单位rpx | String \\| Number  | 200 | - |\n| border-width | 圆环的边框宽度，单位rpx | String \\| Number  | 14 | - |\n| duration | 整个圆环执行一圈的时间，单位ms | String \\| Number  | 1500 | - |\n| type | 如设置，`active-color`值将会失效 | String  | - | success / primary / error / info / warning |\n| bg-color | 整个组件背景颜色，默认为白色 | String  | #ffffff | - |\n\n\n<style scoped>\nh3[id=props] + table thead tr th:nth-child(2){\n\twidth: 40%;\n}\n</style>"
  },
  {
    "path": "src/static/app/markdown/collapse.md",
    "content": "## Collapse 折叠面板 <to-api/>\n\n<demo-model url=\"/pages/componentsC/collapse/index\"></demo-model>\n\n\n通过折叠面板收纳内容区域\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n默认为手风琴模式，即打开一个，另外所有的都会关闭。可以将`u-collapse`的`accordion`设置为`false`，这样可以允许打开多个面板\n\n```html\n<template>\n\t<u-collapse>\n\t\t<u-collapse-item :title=\"item.head\" v-for=\"(item, index) in itemList\" :key=\"index\">\n\t\t\t{{item.body}}\n\t\t</u-collapse-item>\n\t</u-collapse>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\titemList: [{\n\t\t\t\t\thead: \"赏识在于角度的转换\",\n\t\t\t\t\tbody: \"只要我们正确择取一个合适的参照物乃至稍降一格去看待他人，值得赏识的东西便会扑面而来\",\n\t\t\t\t\topen: true,\n\t\t\t\t\tdisabled: true\n\t\t\t\t},{\n\t\t\t\t\thead: \"生活中不是缺少美，而是缺少发现美的眼睛\",\n\t\t\t\t\tbody: \"学会欣赏，实际是一种积极生活的态度，是生活的调味品，会在欣赏中发现生活的美\",\n\t\t\t\t\topen: false,\n\t\t\t\t},{\n\t\t\t\t\thead: \"周围一些不起眼的人、事、物，或许都隐藏着不同凡响的智慧\",\n\t\t\t\t\tbody: \"但是据说雕刻大卫像所用的这块大理石，曾被多位雕刻家批评得一无是处，有些人认为这块大理石采凿得不好，有些人嫌它的纹路不够美\",\n\t\t\t\t\topen: false,\n\t\t\t\t}],\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 控制面板的初始状态，以及是否可以操作\n\n- 设置`u-collapse-item`的`open`参数为`true`，可以让面板初始化时为打开状态\n- 如果设置`u-collapse-item`的`disabled`参数为`true`，那么面板会保持初始状态，无法关闭或打开\n\n```html\n<template>\n\t<u-collapse>\n\t\t<u-collapse-item :title=\"item.head\" v-for=\"(item, index) in itemList\" :key=\"index\" :open=\"item.open\" :disabled=\"item.disabled\">\n\t\t\t{{item.body}}\n\t\t</u-collapse-item>\n\t</u-collapse>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\titemList: [{\n\t\t\t\t\thead: \"赏识在于角度的转换\",\n\t\t\t\t\tbody: \"只要我们正确择取一个合适的参照物乃至稍降一格去看待他人，值得赏识的东西便会扑面而来\",\n\t\t\t\t\topen: true,\n\t\t\t\t\tdisabled: true\n\t\t\t\t},{\n\t\t\t\t\thead: \"生活中不是缺少美，而是缺少发现美的眼睛\",\n\t\t\t\t\tbody: \"学会欣赏，实际是一种积极生活的态度，是生活的调味品，会在欣赏中发现生活的美\",\n\t\t\t\t\topen: false,\n\t\t\t\t},{\n\t\t\t\t\thead: \"周围一些不起眼的人、事、物，或许都隐藏着不同凡响的智慧\",\n\t\t\t\t\tbody: \"但是据说雕刻大卫像所用的这块大理石，曾被多位雕刻家批评得一无是处，有些人认为这块大理石采凿得不好，有些人嫌它的纹路不够美\",\n\t\t\t\t\topen: false,\n\t\t\t\t}],\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n\n### 自定义样式\n\n在此组件中，可以通过多个方式对每个`Item`进行样式定义，我们可以从如下方面思考和着手：\n\n#### 1. 如果修改展开后的内容？  \n- 因为是通过默认的`slot`传入的(见上方示例)，我们可以加一个`view`元素当做外层，在父组件给它添加样式，如下：\n\n```html\n<template>\n\t<u-collapse :item-style=\"itemStyle\" event-type=\"close\" :arrow=\"arrow\" :accordion=\"accordion\" @change=\"change\">\n\t\t<u-collapse-item :index=\"index\" @change=\"itemChange\" :title=\"item.head\" v-for=\"(item, index) in itemList\" :key=\"index\">\n\t\t\t<view class=\"collapse-item\">\n\t\t\t\t{{item.body}}\n\t\t\t</view>\n\t\t</u-collapse-item>\n\t</u-collapse>\n</template>\n\n<style scoped>\n\t.collapse-item {\n\t\tcolor: red;\n\t\tpadding-bottom: 10px;\n\t}\n</style>\n```\n\n- 通过`Collapse`的`body-style`参数也可以配置主体内容的样式，需要注意上面的自定义`slot`内容如果在父组件定义了样式，会优先起作用。\n\n#### 2. 如何自定义标题的样式？\n\n如果想修改头部标题的字体大小，颜色等，可以通过`head-style`参数修改。\n\n\n#### 3. 如何修改整个`Item`的样式？\n\n有时候我们需要修改`Item`的整体样式，比如将各个`Item`之间隔开，这时我们可以通过`item-style`参数进行设置，比如：\n\n```html\n<template>\n\t<u-collapse :item-style=\"itemStyle\">\n\t\t......\n\t</u-collapse>\n</template>\n\n<script>\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\titemStyle: {\n\t\t\t\tmarginTop: '20px'\n\t\t\t}\n\t\t}\n\t}\n}\n</script>\n```\n\n\n\n### API\n\n### Collapse Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| accordion | 是否手风琴模式  | Boolean | true | false |\n| arrow | 是否显示标题右侧的箭头  | Boolean | true | false |\n| arrow-color | 标题右侧箭头的颜色 | String | #909399 | - |\n| item-style<Badge text=\"1.3.0\" /> | 整个`Item`的自定义样式，对象形式  | Object | - | - |\n| head-style | `Item`的标题自定义样式，对象形式  | Object | - | - |\n| body-style | `Item`的主体自定义样式，对象形式  | Object | - | - |\n| hover-class | 样式类名，按下时有效，样式必须写在根目录的`App.vue`或通过其引入的全局样式中才有效，`none`为无效果，作用于头部标题区域  | String | u-hover-class | none / 其他 |\n\n### Collapse Item Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| title | 面板标题  | String | - | - |\n| index | 主要用于事件的回调，标识那个Item被点击  | String \\/ Number | - | - |\n| disabled | 面板是否可以打开或收起  | Boolean | false | true |\n| open | 设置某个面板的初始状态是否打开  | Boolean | false | true |\n| name | 唯一标识符，如不设置，默认用当前`collapse-item`的索引值 | String \\/ Number | - | - |\n| align | 标题的对齐方式  | String | left | - |\n| active-style | 不显示箭头时，可以添加当前选择的collapse-item活动样式，对象形式  | Object | - | - |\n\n\n### Collapse Event\n\n注意：请在`<u-collapse></u-collapse>`上监听此事件\n\n|事件名|说明|回调参数|\n|:-|:-|:-|:-|\n| change | 当前激活面板展开时触发(如果是手风琴模式，参数activeNames类型为String，否则为Array) | activeNames: String / Array |\n\n\n### Collapse Item Event\n\n注意：请在`<u-collapse-item></u-collapse-item>`上监听此事件\n\n|事件名|说明|回调参数|\n|:-|:-|:-|:-|\n| change | 某个item被打开或者收起时触发 | 对象，{index: index, show: true \\| false }，index为`collapse-item`的`index`参数，show为`true`表示被打开，`false`表示被收起 |\n\n\n### Collapse Methods \n\n注意：此方法需要通过`ref`调用\n\n|方法|说明|\n|:-|:-|\n| init  | 重新初始化内部高度计算，用于异步获取内容的情形，请结合`this.$nextTick()`使用 |\n\n\n### Slot\n\n| 名称          | 说明            |\n|-------------  |---------------- |\n| - |  主体部分的内容  |\n| title |  头部的内容，不含右边的箭头  |\n| title-all |  整个头部的内容，包含右边的箭头  |\n\n\n<style scoped>\nh3[id=collapse-props] + table thead tr th:nth-child(2){\n\twidth: 40%;\n}\n\nh3[id=collapse-item-props] + table thead tr th:nth-child(2){\n\twidth: 40%;\n}\n\nh3[id=collapse-event] + p + table thead tr th:nth-child(2){\n\twidth: 50%;\n}\n\nh3[id=collapse-methods] + table thead tr th:nth-child(2){\n\twidth: 50%;\n}\n\nh3[id=collapse-item-event] + p + table thead tr th:nth-child(3){\n\twidth: 50%;\n}\n\nh3[id=slot] + table thead tr th:nth-child(2){\n\twidth: 50%;\n}\n</style>"
  },
  {
    "path": "src/static/app/markdown/color.md",
    "content": "## Color 色彩\n\n<demo-model url=\"/pages/componentsC/color/index\"></demo-model>\n\n\nuView经过大量调试和研究，得出一套专有的调色板，在各个组件内部，使用统一的配色，为您的产品带来统一又鲜明的视觉效果。\n\n\nuView为了更好编写css，使用了scss预处理器，使用uView之前，请确认您的Hbuilder X已经安装了scss预处理器，一般情况下，相信您已经安装了。如果没有安装，\n请在 Hbuilder X->工具->插件安装 中找到找到\"scss/sass编译\"安装即可，安装完毕如果不生效，请重启Hbuilder X。\n\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |    √     |\n\n### 主题色\n\n`primary`，`success`，`error`，`warning`，`info`是uView的主题色，他们给人在视觉感受上分别对应于蓝色，绿色，红色，黄色，灰色。\n而他们又有对应的`disabled`、`dark`和`light`状态，分别表示对应的禁止，加深和变浅的对应颜色。举例uView的`button`组件来说：\n1. 设置`type`参数为`primary`时，按钮显示蓝色。\n2. 按钮被按下时，使用的是`primary`的加深颜色，也即`dark`状态。\n3. 按钮设置为镂空状态(`plain`为`true`)时，背景色为`primary`的变浅颜色，也即`light`状态。\n4. 按钮处于禁止状态时，使用的是`primary`的稍浅颜色，也即`disabled`状态。\n\n### 主色\n\n蓝色作为uView主色调，表示一种鲜明，积极的态度\n\n<div class=\"color-box\">\n\t<div class=\"color-item\" style=\"background: #2979ff; color:#fff;\">\n\t\tPrimary<br>\n\t\t#2979ff\n\t\t<div class=\"color-sub\">\n\t\t\t<div class=\"sub-item\" style=\"background: #2b85e4; color:#fff;\">\n\t\t\t\tDark<br>\n\t\t\t\t#2b85e4\n\t\t\t</div>\n\t\t\t<div class=\"sub-item\" style=\"background: #a0cfff; color:#606266;\">\n\t\t\t\tDisabled<br>\n\t\t\t\t#a0cfff\n\t\t\t</div>\n\t\t\t<div class=\"sub-item\" style=\"background: #ecf5ff; color:#606266;\">\n\t\t\t\tLight<br>\n\t\t\t\t#ecf5ff\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</div>\n\n我们在全局样式中，通过`scss`提供了对应的颜色变量名，方便您在任何可写css的地方，调用这些变量，如下：\n\n```css\n/* 变量的定义，该部分uView已全局引入，无需您编写 */\n$u-type-primary: #2979ff;\n$u-type-primary-light: #ecf5ff;\n$u-type-primary-disabled: #a0cfff;\n$u-type-primary-dark: #2b85e4;\n\n\n/* 在您编写css的地方使用这些变量 */\n.title {\n\tcolor: $u-type-primary;\n\t......\n}\n```\n\n\n### 辅助色\n\n除了主色外的场景色，需要在不同的场景中使用，如绿色代表成功，红色代表错误，黄色代表警示。\n\n<div class=\"color-box\">\n\t<div class=\"color-item\" style=\"background: #fa3534; color:#fff;\">\n\t\tError<br>\n\t\t#fa3534\n\t\t<div class=\"color-sub\">\n\t\t\t<div class=\"sub-item\" style=\"background: #dd6161; color:#fff;\">\n\t\t\t\tDark<br>\n\t\t\t\t#dd6161\n\t\t\t</div>\n\t\t\t<div class=\"sub-item\" style=\"background: #fab6b6; color:#606266;\">\n\t\t\t\tDisabled<br>\n\t\t\t\t#fab6b6\n\t\t\t</div>\n\t\t\t<div class=\"sub-item\" style=\"background: #fef0f0; color:#606266;\">\n\t\t\t\tLight<br>\n\t\t\t\t#fef0f0\n\t\t\t</div>\n\t\t</div>\n\t</div>\n\t<div class=\"color-item\" style=\"background: #ff9900; color:#fff;\">\n\t\tWarning<br>\n\t\t#ff9900\n\t\t<div class=\"color-sub\">\n\t\t\t<div class=\"sub-item\" style=\"background: #f29100; color:#fff;\">\n\t\t\t\tDark<br>\n\t\t\t\t#f29100\n\t\t\t</div>\n\t\t\t<div class=\"sub-item\" style=\"background: #fcbd71; color:#606266;\">\n\t\t\t\tDisabled<br>\n\t\t\t\t#fcbd71\n\t\t\t</div>\n\t\t\t<div class=\"sub-item\" style=\"background: #fdf6ec; color:#606266;\">\n\t\t\t\tLight<br>\n\t\t\t\t#fdf6ec\n\t\t\t</div>\n\t\t</div>\n\t</div>\n\t<div class=\"color-item\" style=\"background: #19be6b; color:#fff;\">\n\t\tSuccess<br>\n\t\t#19be6b\n\t\t<div class=\"color-sub\">\n\t\t\t<div class=\"sub-item\" style=\"background: #18b566; color:#fff;\">\n\t\t\t\tDark<br>\n\t\t\t\t#18b566\n\t\t\t</div>\n\t\t\t<div class=\"sub-item\" style=\"background: #71d5a1; color:#606266;\">\n\t\t\t\tDisabled<br>\n\t\t\t\t#71d5a1\n\t\t\t</div>\n\t\t\t<div class=\"sub-item\" style=\"background: #dbf1e1; color:#606266;\">\n\t\t\t\tLight<br>\n\t\t\t\t#dbf1e1\n\t\t\t</div>\n\t\t</div>\n\t</div>\n\t<div class=\"color-item\" style=\"background: #909399; color:#fff;\">\n\t\tInfo<br>\n\t\t#909399\n\t\t<div class=\"color-sub\">\n\t\t\t<div class=\"sub-item\" style=\"background: #82848a; color:#fff;\">\n\t\t\t\tDark<br>\n\t\t\t\t#82848a\n\t\t\t</div>\n\t\t\t<div class=\"sub-item\" style=\"background: #c8c9cc; color:#606266;\">\n\t\t\t\tDisabled<br>\n\t\t\t\t#c8c9cc\n\t\t\t</div>\n\t\t\t<div class=\"sub-item\" style=\"background: #f4f4f5; color:#606266;\">\n\t\t\t\tLight<br>\n\t\t\t\t#f4f4f5\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</div>\n\n我们在全局样式中，通过`scss`提供了对应的颜色变量名，方便您在任何可写css的地方，调用这些变量，如下：\n\n```css\n/* 变量的定义，该部分uView已全局引入，无需您编写 */\n\n$u-type-warning: #ff9900;\n$u-type-warning-disabled: #fcbd71;\n$u-type-warning-dark: #f29100;\n$u-type-warning-light: #fdf6ec;\n\n$u-type-success: #19be6b;\n$u-type-success-disabled: #71d5a1;\n$u-type-success-dark: #18b566;\n$u-type-success-light: #dbf1e1;\n\n$u-type-error: #fa3534;\n$u-type-error-disabled: #fab6b6;\n$u-type-error-dark: #dd6161;\n$u-type-error-light: #fef0f0;\n\n$u-type-info: #909399;\n$u-type-info-disabled: #c8c9cc;\n$u-type-info-dark: #82848a;\n$u-type-info-light: #f4f4f5;\n\n/* 在您编写css的地方使用这些变量 */\n.title {\n\tcolor: $u-type-info;\n\t......\n}\n```\n\n### 文字颜色\n\nuView中，分别提炼了4种用于文字颜色，分别是：主要文字、常规文字、次要文字、占位文字颜色。\n\n- 主要文字颜色一般用于内容的标题等，如新闻列表的标题\n- 常规文字颜色一般用于内容的主体，如新闻列表的概要\n- 次要文字颜色一般用于内容的提示部分，如新闻列表底部的时间，评论数量的提示文字\n- 占位文字颜色属于更浅的灰色，看场景选择使用\n\n<div class=\"color-box\">\n\t<div class=\"color-item\" style=\"background: #303133; color:#fff;\">\n\t\t主要文字<br>\n\t\t#303133\n\t\t<div class=\"color-sub\">\n\t\t\t<div class=\"sub-item\" style=\"background: #606266; color:#fff;\">\n\t\t\t\t常规文字<br>\n\t\t\t\t#606266\n\t\t\t</div>\n\t\t\t<div class=\"sub-item\" style=\"background: #909399; color:#fff;\">\n\t\t\t\t次要文字<br>\n\t\t\t\t#909399\n\t\t\t</div>\n\t\t\t<div class=\"sub-item\" style=\"background: #c0c4cc; color:#303133;\">\n\t\t\t\t占位文字<br>\n\t\t\t\t#c0c4cc\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</div>\n\n```css\n/* 变量的定义，该部分uView已全局引入，无需您编写 */\n$u-main-color: #303133;\n$u-content-color: #606266;\n$u-tips-color: #909399;\n$u-light-color: #c0c4cc;\n\n/* 在您编写css的地方使用这些变量 */\n.title {\n\tcolor: $u-main-color;\n}\n```\n\n\n### 背景颜色\n\nuView中，定义了一个背景颜色，如下：\n\n<div class=\"color-box\">\n\t<div class=\"color-item\" style=\"background: #f3f4f6; color:#909399;\">\n\t\t背景颜色<br>\n\t\t#f3f4f6\n\t</div>\n</div>\n\n我们在全局样式中，通过`scss`提供了对应的颜色变量名，方便您在任何可写css的地方，调用这个变量，如下：\n\n```css\n/* 变量的定义，该部分uView已全局引入，无需您编写 */\n$u-bg-color: #f3f4f6;\n\n/* 在您编写css的地方使用这些变量 */\n.title {\n\tcolor: $u-bg-color;\n}\n```\n\n\n### 边框颜色\n\nuView自定义了一个边框的颜色，值为`#e4e7ed`，如果想使用，如下：\n\n```css\n/* 变量的定义，该部分uView已全局引入，无需您编写 */\n$u-border-color: #e4e7ed;\n\n/* 在您编写css的地方使用这个变量 */\n.item {\n\tborder: 1px solid $u-border-color;\n}\n```\n\n<style scoped>\n.color-box {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n}\n\n.color-item {\n\tbox-sizing: border-box;\n\ttext-align: left;\n\tpadding: 20px 25px;\n\tborder-radius: 5px;\n\tflex: 0 0 31.5%;\n\tposition: relative;\n\theight: 130px;\n\toverflow: hidden;\n\tmargin-right: 4%;\n\tmargin-bottom: 35px;\n\tmin-width: 300px;\n}\n\n.color-item:nth-child(3n) {\n\t\n}\n\n.color-sub {\n\tposition: absolute;\n\tbottom: 0;\n\twidth: 100%;\n\tleft: 0;\n\tdisplay: flex;\n\theight: 50px;\n}\n\n.sub-item {\n\tdisplay: flex;\n\tflex: 1;\n\talign-items: center;\n\tjustify-content: flex-start;\n\tpadding: 0 10px;\n\tfont-size: 13px;\n}\n\n.sub-item:first-child {\n\tborder-radius: 0 0 0 5px;\n}\n\n.sub-item:last-child {\n\tborder-radius: 0 0 5px 0;\n}\n\n</style>\n\n"
  },
  {
    "path": "src/static/app/markdown/colorSwitch.md",
    "content": "# colorSwitch 颜色转换\n\n<demo-model url=\"/pages/library/colorSwitch/index\"></demo-model>\n\n\n## RGB转十六进制Hex\n\n### rgbToHex(rgb)\n\n该函数可以将一个RGB颜色值转换成一个Hex的十六进制颜色值\n\n- `rgb` <String\\> RGB颜色值，如`rgb(230, 231, 233)`\n\n```js\nimport { ref, onMounted } from 'vue';\nimport { $u } from 'uview-pro';\n\nconst rgb = ref('rgb(13, 145, 20)');\n\nonMounted(() => {\n  console.log($u.rgbToHex(rgb.value));\n});\n```\n\n\n## 十六进制Hex转RGB\n\n### hexToRgb(hex)\n\n该函数可以将一个Hex的十六进制颜色值转换成一个RGB颜色值\n\n- `hex` <String\\> HEx颜色值，如`#0afdce`\n\n```js\nimport { ref, onMounted } from 'vue';\nimport { $u } from 'uview-pro';\n\nconst hex = ref('#0afdce');\n\nonMounted(() => {\n  console.log($u.hexToRgb(hex.value));\n});\n```\n\n\n## 颜色渐变\n\n### colorGradient(startColor, endColor, step)\n\n该函数实现两个颜色值之间等分取值，返回一个数组，元素为十六进制形式的颜色值，数组长度为`step`值。 \n例如：colorGradient('rgb(250, 250, 250)', 'rgb(252, 252, 252)', 3)，得到的结果为[\"#fafafa\", \"#fafafa\", \"#fbfbfb\"]\n\n- `startColor` <String\\> 开始颜色值，可以是HEX或者RGB颜色值，如`#0afdce`或者`rgb(120, 130, 150)`\n- `endColor` <String\\> 结束颜色值，可以是HEX或者RGB颜色值，如`#0afdce`或者`rgb(120, 130, 150)`\n- `step` <Number\\> 均分值，把开始值和结束值平均分成多少份\n\n```js\nconsole.log(uni.$u.colorGradient('rgb(250,250,250)', 'rgb(252,252,252)', 3));\n// 结果为：[\"#fafafa\", \"#fafafa\", \"#fbfbfb\"]\n```\n\n\n## 颜色透明度\n\n### colorToRgba(color, opacity = 0.3)\n\n该函数可以接受一个`十六进制`或者`rgb`格式的颜色值(不能接受命名式颜色格式，比如`white`)，返回此颜色的`rgba`格式值，如下：\n\n- `color` <String\\> 颜色值，只能`hex`或者`rgba`格式\n- `opacity` <Number\\> 不透明度值，取值为0-1之间\n\n\n```js\nuni.$u.colorToRgba('#000000', 0.35);\n// 结果为 rgba(0, 0, 0, 0.35)\n\nuni.$u.colorToRgba('rgb(255, 180, 0)', 0.4);\n// 结果为 rgba(255, 180, 0, 0.4)\n```\n\n"
  },
  {
    "path": "src/static/app/markdown/colorjs.md",
    "content": "# color 颜色值\n\n<demo-model url=\"/pages/componentsC/color/index\"></demo-model>\n\n\n此功能为uView内部通过js提供的一些颜色值，可以用于通过js修改元素字体，背景颜色等一些场景，常用于uView的各个组件中。  \n这些颜色值，挂载在`$u`对象下的`color`数组中，关于这些颜色值的具体描述，详见[Color 色彩](/zh/components/color.html)  \n使用方法：如使用`primary`颜色值，方法为：`$u.color['primary']`\n\n**说明**：这些通过JS调用的颜色值，也是能通过CSS调用的，二者等价。详见[Color 色彩](/zh/components/color.html)  \n\n## 主题颜色\n\n该主题颜色值，一共有5个，分别是`primary`、`error`、`success`、`info`、`warning`\n\n```js\nimport { ref, onMounted } from 'vue';\n\nconst errorColor = ref('');\n\nonMounted(() => {\n  errorColor.value = uni.$u.color['error'];\n});\n```\n\n\n## 文字颜色\n\nuView一共提供了四个颜色值，具体请见组件部分[Color色彩](/zh/components/color.html)  \n分别有：`mainColor`、`contentColor`、`tipsColor`、`lightColor`、`borderColor`(边框颜色值)\n\n```js\nconsole.log(uni.$u.color['contentColor']);\n```\n\n\n## 背景颜色\n\nuView提供了一个浅灰的背景颜色值，该值为`#f3f4f6`\n\n```js\nconsole.log(uni.$u.color['bgColor']);\n```\n\n"
  },
  {
    "path": "src/static/app/markdown/common.md",
    "content": "## 内置样式\n\n<demo-model url=\"/\"></demo-model>\n\n### 说明\n\nuView Pro 组件功能的实现，并不依赖全局样式，内置的一些类名，只是提供一些基础且常用的样式，仅此而已。  \n注意：请根据[快速上手](/components/quickstart.html)中的说明，引入 uView Pro 提供的 scss 文件。\n\n\n由于 uView Pro 的内置样式均是写在 scss 文件中的，您在使用的时候，请确保要给页面的`style`标签加上`lang=\"scss\"`属性，否则可能会报错。\n\n<!-- 另外，您可能需要留意，如果页面的`style`标签加入了`lang=\"scss\"`属性，就必须要在`style`标签中写入内容，哪怕是无用的样式也好，否则HX不会解析scss，此非uView的问题。 -->\n\n\n\n### 文字省略\n\n`u-line-1`,`u-line-2`,`u-line-3`,`u-line-4`,`u-line-5`五个类名在文字超出内容盒子时，分别只显示一行、两行、三行、四行、五行+省略号。\n\n```html\n<view class=\"u-line-1\">\n  是日也，天朗气清，惠风和畅，仰观宇宙之大，俯察品类之盛，所以游目骋怀，足以极视听之娱，信可乐也\n</view>\n```\n\n### 定位\n\nuView Pro 内置了关于相对和绝对定位的两个类，分别为`u-relative`(`u-rela`)和`u-absolute`(`u-abso`)：\n\n```css\n.u-relative,\n.u-rela {\n  position: relative;\n}\n\n.u-absolute,\n.u-abso {\n  position: absolute;\n}\n```\n\n### 字体大小\n\n#### **1. 数值形式**\n\nuView Pro 为了方便用户写字体，通过 SCSS 生成了一套样式类，专门用于定位字体的大小。对于字体，不同用户可能有喜欢`px`，也有喜欢`rpx`单位的，\n一般来说，在 uni-app 上，`rpx`单位最终表现出来的大小数值为`px`的两倍左右，也就是说，`24rpx`和`12px`的字体大小是差不多的。  \nuView Pro 为此提供了一个类`u-font-x`，这个`x`为 10-40 之间(包含 10 和 40)，当`x >= 10 && x < 20`时，表现为`px`性质，当`x >= 20 && x <= 40`时，表现为`rpx`性质。\n\n用法如下：\n\n- 当`x >= 10 && x < 20`时，表现为`px`性质\n\n```html\n<view class=\"u-font-13\"></view>\n```\n\n这个`.u-font-13`在 uView 的内部样式定义为：\n\n```css\n.u-font-13 {\n  font-size: 13px;\n}\n```\n\n- 当`x >= 20 && x <= 40`时，表现为`rpx`性质\n\n```html\n<view class=\"u-font-26\"></view>\n```\n\n这个`.u-font-26`在 uView Pro 的内部样式定义为：\n\n```css\n.u-font-26 {\n  font-size: 26rpx;\n}\n```\n\n#### **2. 断点形式**\n\n为了更加形象和方便记忆，uView 另外提供了一套断点的字体大小，分别以`xs`、`sm`、`md`、`lg`、`xl`作为后缀，如下：\n\n```css\n.u-font-xs {\n  font-size: 22rpx;\n}\n\n.u-font-sm {\n  font-size: 26rpx;\n}\n\n.u-font-md {\n  font-size: 28rpx;\n}\n\n.u-font-lg {\n  font-size: 30rpx;\n}\n\n.u-font-xl {\n  font-size: 34rpx;\n}\n```\n\n### 文字对齐\n\nuView Pro 为文字对齐定义了 3 个类，分别如下：\n\n```css\n/* 文字左对齐 */\n.u-text-left {\n  text-align: left;\n}\n\n/* 文字居中对齐 */\n.u-text-center {\n  text-align: center;\n}\n\n/* 文字右对齐 */\n.u-text-right {\n  text-align: right;\n}\n```\n\n### 重置按钮样式\n\n我们知道，uni-app 和微信小程序的`button`按钮是自带样式的，比如边框，内边距，行高等。在某些特殊场景，我们可能会需要清除这些样式，仅仅只留下按钮文本，就像\n单纯的`view`元素一样，不带预置样式，场景：  \n在微信小程序中，我们知道`button`设置`open-type`参数为`getUserInfo`(或者分享场景)，点击按钮可以弹出让用户授权的系统弹窗，有时候我们可能需要按钮形式展现，但也有时候我们仅仅需要\n\"点击登录/授权/分享\"几个字，同时具备获取相应的功能，就需要清除按钮的样式了，只需要给`button`加上`u-reset-button`类名即可。\n\n```html\n<button class=\"u-reset-button\">点击登录</button>\n```\n\n提示：\n\n1. 此种场景，不建议使用 uView Pro 的`u-button`组件，使用原生的`button`即可\n2. 有时候，我们可能弹出询问用户是否想授权，可以用`u-modal`组件，此组件有一个`confirm-button`的`slot`用于替换`确定`按钮，用户点击确定，即可授权。\n\n````html\n/* 请在微信开发工具中运行此代码 */ ```vue\n<template>\n  <view>\n    <u-modal v-model=\"show\" content=\"点击确定进行授权\">\n      <template #confirm-button>\n        <button\n          open-type=\"getUserInfo\"\n          class=\"u-reset-button\"\n          @getuserinfo=\"getUserInfo\"\n        >\n          确定\n        </button>\n      </template>\n    </u-modal>\n    <u-button @click=\"show = true\">打开modal</u-button>\n  </view>\n</template>\n\n<script setup lang=\"ts\">\n  import { ref } from \"vue\";\n\n  const show = ref(true);\n\n  function getUserInfo(res: any) {\n    console.log(res);\n  }\n</script>\n````\n\n### 内外边距\n\nuView 定义了一套内外边距的类名，调用简单，方便用户使用，类似`u-padding-x`、`u-margin-left-x`等，这里的`x`取值规则如下：\n\n- 1-80(可以等于 80)之间的偶数(双数)\n- 能被 5 除尽的 1-80 之间的数，如 5，10，15，35 等\n\n类名的取值有如下：\n\n**注意：** uView 同时也给了一套简写的方法，二者是等价的。\n\n- u-padding-x == u-p-x\n- u-padding-left-x == u-p-l-x\n- u-padding-top-x == u-p-t-x\n- u-padding-right-x == u-p-r-x\n- u-padding-bottom-x == u-p-b-x\n- u-margin-x == u-m-x\n- u-margin-left-x == u-m-l-x\n- u-margin-top-x == u-m-t-x\n- u-margin-right-x == u-m-r-x\n- u-margin-bottom-x == u-m-b-x\n\n<!-- 以下为1.3.9新增的样式：\n\n- u-margin-left-right-x  ==  u-m-l-r-x\n- u-margin-top-button-x  ==  u-m-t-b-x\n- u-padding-left-right-x  ==  u-p-l-r-x\n- u-padding-top-bottom-x  ==  u-p-t-b-x -->\n\n如果我们想定义`26rpx`的**左外边距**：\n\n```html\n<view class=\"u-margin-left-26\"></view>\n```\n\n这个`.u-margin-left-26`在 uView 的内部样式定义为：\n\n```css\n.u-margin-left-26 {\n  margin-left: 26rpx;\n}\n```\n\n如果我们想要`35rpx`的内边距：\n\n```html\n<view class=\"u-padding-35\"></view>\n```\n\n这个`.u-padding-35`在 uView 的内部样式定义为：\n\n```css\n.u-padding-35 {\n  padding: 35rpx;\n}\n```\n\n### flex 布局\n\n在看这个部分的时候，请确保您对`flex`是了解的，否则可以参考[阮一峰的 flex 教程](http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html)  \n由于我们经常要使用`flex`布局，而其中的大部分样式又都是重复的，总是少不了如下的几句：\n\n```css\n/* 父盒子 */\ndisplay: flex;\nflex-wrap: wrap;\nflex-direction: row;\nalign-items: center;\n\n/* 子元素 */\nflex: 1;\n```\n\n基于以上，uView 定义了一个最常用的总集合类，名为`u-flex`，其内部值如下：\n\n#### **1. 总超集**\n\n```css\n.u-flex {\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n}\n```\n\n#### **2. 子元素是否换行**\n\n```css\n/* 换行 */\n.u-flex-wrap {\n  flex-wrap: wrap;\n}\n\n/* 不换行 */\n.u-flex-nowrap {\n  flex-wrap: nowrap;\n}\n```\n\n\n当我们写这些跟`flex`相关的类名时，总应该把`u-flex`写在`class`多个类名的左边，因为`u-flex`是一个集合类，如果你不想要其中的某个属性，如`align-items: center`\n，可以通过右边的类名覆盖它。\n\n\n覆盖`u-flex`中的`align-items: center`(对齐)，改为顶部对齐`u-col-top`：\n\n```html\n<view class=\"u-flex u-col-top\"> ...... </view>\n```\n\n最终内部表现如下(其它以此类推)：\n\n```css\n.u-flex {\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n}\n\n/* 由于align-items: flex-start在后面，故覆盖了\"u-flex\"的align-items: center */\n.u-col-top {\n  align-items: flex-start;\n}\n```\n\n#### **3. 子元素在上下左右的对齐方式**\n\n这里类名的命名依据为，`col`为`column`(列，竖向)的缩写，`row`为行的意思(横向)，所以就有垂直方向上的诸如`u-col-center`表\n垂直居中对齐，`u-row-left`代表水平左对齐。  \n此类名控制的是子元素，是需要写在父元素盒子上的：\n\n```css\n/* 垂直居中 */\n.u-col-center {\n  align-items: center;\n}\n\n/* 顶部对齐 */\n.u-col-top {\n  align-items: flex-start;\n}\n\n/* 底部对齐 */\n.u-col-bottom {\n  align-items: flex-end;\n}\n\n/* 左边对齐 */\n.u-row-left {\n  justify-content: flex-start;\n}\n\n/* 水平居中 */\n.u-row-center {\n  justify-content: center;\n}\n\n/* 右边对齐 */\n.u-row-right {\n  justify-content: flex-end;\n}\n\n/* 水平两端对齐，项目之间的间隔都相等 */\n.u-row-between {\n  justify-content: space-between;\n}\n\n/* 水平每个项目两侧的间隔相等，所以项目之间的间隔比项目与父元素两边的间隔大一倍 */\n.u-row-around {\n  justify-content: space-around;\n}\n```\n\n#### **4. 子元素空间分布**\n\n此类名是写在子元素的`class`中的，主要用于决定子元素占据的父元素的空间大小，类名为`u-flex-x`，`x`的取值为`x >= 1 && x <= 12`：\n\n```css\n.u-flex-1 {\n  flex: 1;\n}\n\n.u-flex-2 {\n  flex: 2;\n}\n\n.u-flex-3 {\n  flex: 3;\n}\n\n/* ...... */\n\n.u-flex-12 {\n  flex: 12;\n}\n```\n\n### 边框\n\nuni-app，iOS 和少数设备使用`1rpx`是能够得到类似`0.5px`的半像素宽度的，但是某些情况下是不兼容的，\n故 uView 提供了一套兼容的 css 类名，方便用户使用。  \n`u-border`表示给元素添加四周的边框，`u-border-top`为上边框，`u-border-right`为右边框，\n`u-border-bottom`为下边框，`u-border-left`为左边框。  \n说明：如果想调整边框与内容的距离，修改元素的内边距即可。\n\n```html\n<view class=\"u-border-bottom\">\n  夫人之相与，俯仰一世，或取诸怀抱，悟言一室之内；或因寄所托，放浪形骸之外\n</view>\n```\n\n### 文字颜色\n\nuView 提供了四个关于文字的颜色，具体详见文档的[Color 色彩](/components/color.html)部分，分别是：\n\n- `main-color`主要颜色，可以用于标题等需要重颜色的场景\n- `content-color`内容颜色，可以用于一般性内容的场景\n- `tips-color`提示颜色，可以用于浅颜色的提示语的场景\n- `light-color`为比`tips-color`更浅的颜色，可以和`tips-color`搭配使用\n\n举个例子：  \n我们平时看到的 APP 的新闻列表，标题颜色可以用`$u-main-color`，简介部分颜色可以用`$u-content-color`，底部的发布时间文字等可以用`$u-tips-color`。\n\n#### **1. 类名方案**\n\n这个方案，直接通过类名调用，有这几个对应类名：`u-main-color`、`u-content-color`、`u-tips-color`、`u-light-color`。\n\n```html\n<view class=\"u-main-color\"> ...... </view>\n```\n\n#### **2. SCSS 变量名方案**\n\nuView 提供了四个关于文字颜色的 scss 变量名，具体详见文档的[Color 色彩](/components/color.html)部分，分别是：\n\n- `$u-main-color`\n- `$u-content-color`\n- `$u-tips-color`\n- `$u-light-color`\n\n```html\n<!-- 请确保在style标签声明了\"lang=\"scss\"\" -->\n<style lang=\"scss\" scoped>\n  .box {\n    color: $u-main-color;\n  }\n\n  .count {\n    border-color: $u-light-color;\n  }\n</style>\n```\n\n### 主题色\n\nuView 提供五个关于主题的 scss 颜色变量，如有需要，可合理使用。具体详见文档的[Color 色彩](/components/color.html)部分，分别是：\n\n- `$u-type-primary`为蓝色，uView 的主色彩，代表热情，友好，积极，向上之意。\n- `$u-type-warning`为黄色，代表警告之意。\n- `$u-type-success`为绿色，代表成功之意。\n- `$u-type-error`为红色，代表错误之意。\n- `$u-type-info`为灰色，代表一般信息之意。\n\n```html\n<style lang=\"scss\" scoped>\n  .item {\n    color: $u-type-primary;\n  }\n</style>\n```\n"
  },
  {
    "path": "src/static/app/markdown/countDown.md",
    "content": "## CountDown 倒计时 <to-api/>\n\n<demo-model url=\"/pages/componentsC/countDown/index\"></demo-model>\n\n\n该组件一般使用于某个活动的截止时间上，通过数字的变化，给用户明确的时间感受，提示用户进行某一个行为操作。\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n- 通过`timestamp`参数设置倒计时间，单位为`秒`\n\n```html\n<template>\n\t<u-count-down :timestamp=\"timestamp\"></u-count-down>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\ttimestamp: 86400,\n\t\t}\n\t}\n</script>\n```\n\n### 设置是否显示天，时，分，秒\n\n说明：参数的配置原则应该是\"自右向左\"的，设置了\"时\"，它右边的\"分\"和\"秒\"也应该设置为`true`\n\n- `show-days`，`show-hours`，`show-minutes`，`show-seconds`等参数默认为`true`，分别对应是否显示倒计时的\"天\"，\"时\"，\"分\"，\"秒\"。\n\n该示例表示只显示倒计时的分和秒\n\n```html\n<u-count-down :timestamp=\"86400\" :show-days=\"false\" :show-hours=\"false\"></u-count-down>\n```\n\n### 倒计时分隔符\n\n通过配置`separator`参数为`colon`或者`zh`来区分分隔符。`separator-size`配置分隔符的大小，单位rpx。`separator-color`配置分隔符的颜色\n`separator`可选值如下：\n- `colon`(默认)时显示为冒号，如：23:14:51\n- `zh`时显示为中文，如：23时14分51秒\n\n```html\n<u-count-down :timestamp=\"86400\" separator=\"colon\" separator-size=\"28\" separator-color=\"#606266\"></u-count-down>\n```\n\n### 倒计时样式\n\n- 通过`color`设置倒计数字的颜色\n- `font-size`设置倒计数字的大小，重申一次：uView中，所有`font-size`，`width`，`height`，`padding`，`margin`等props参数\n的单位默认都是`rpx`，特别说明除外(极少数场景会要求px单位)。关于`rpx`单位的说明，请参考uni官方文档：[尺寸单位](https://uniapp.dcloud.io/frame?id=%e5%b0%ba%e5%af%b8%e5%8d%95%e4%bd%8d)\n- `show-border`参数设置倒计数字是否添加边框，`border-color`参数设置边框的颜色\n\n```html\n<u-count-down :timestamp=\"86400\" :show-border=\"true\" font-size=\"28\" color=\"#606266\" border-color=\"#909399\"></u-count-down>\n```\n\n### 倒计时执行的时机\n\n通过`autoplay`配置倒计时是否在组件的`mounted`生命周期进行初始化(在`timestamp`有值前提下)，如果设置`autoplay`为`false`，就需要手动通过\n`refs`的形式通知倒计时开始执行，调用的是组件内部的`start()`方法\n\n```html\n<template>\n\t<u-count-down ref=\"uCountDown\" :timestamp=\"86400\" :autoplay=\"false\"></u-count-down>\n</template>\n\n<script>\n\texport default {\n\t\tonLoad() {\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.$refs.uCountDown.start();\n\t\t\t}, 2000)\n\t\t}\n\t}\n</script>\n```\n\n\n### 如何获取当前倒计的秒数\n\n有时候我们可会需要记录当前剩余的秒数，并在某个时机重新触发，可以通过如下两个方式实现：\n\n- 监听`change`事件，在回调中获得当前剩余的秒数\n- 通过ref调用，获取内部的`seconds`参数即为当前剩余的秒数\n\n\n```html\n<template>\n\t<u-count-down ref=\"uCountDown\" :timestamp=\"timestamp\" @change=\"change\"></u-count-down>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\ttimestamp: 86400\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\t// 事件触发，每秒一次\n\t\t\tchange(timestamp) {\n\t\t\t\tconsole.log(timestamp);\n\t\t\t},\n\t\t\t// ref形式获取内部的值\n\t\t\tgetSeconds() {\n\t\t\t\tconsole.log(this.$refs.uCountDown.seconds);\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| timestamp | 倒计时，单位为秒 | String \\| Number | 0 | - |\n| autoplay | 是否自动开始倒计时，如果为`false`，需手动调用开始方法。见上方说明  | Boolean | true | false |\n| separator | 分隔符，`colon`为英文冒号，`zh`为中文 | String  | colon | zh |\n| separator-size | 分隔符的字体大小，单位rpx | String \\| Number  | 30 | - |\n| separator-color | 分隔符的颜色 | String  | #303133 | - |\n| font-size | 倒计时字体大小，单位rpx | String \\| Number  | 30 | - |\n| show-border | 是否显示倒计时数字的边框 | Boolean | false | true |\n| border-color | 数字边框的颜色 | String  | #303133 | - |\n| bg-color | 倒计时数字的背景颜色 | String  | #ffffff | - |\n| color | 倒计时数字的颜色 | String  | #303133 | - |\n| height | 数字高度值(宽度等同此值)，设置边框时看情况是否需要设置此值，单位rpx | String  | auto | - |\n| show-days | 是否显示倒计时的\"天\"部分 | Boolean  | true | false |\n| show-hours | 是否显示倒计时的\"时\"部分 | Boolean  | true | false |\n| show-minutes | 是否显示倒计时的\"分\"部分 | Boolean  | true | false |\n| show-seconds | 是否显示倒计时的\"秒\"部分 | Boolean  | true | false |\n| hide-zero-day | 当\"天\"的部分为0时，隐藏该字段 | Boolean  | true | false |\n\n\n### Events\n\n|事件名|说明|回调参数|\n|:-|:-|:-|\n|end|倒计时结束|-|\n|change|倒计过程中，每秒触发一次|timestamp: 当前剩余的倒计秒数|\n\n\n\n### Methods\n\n需要通过ref获取倒计时组件才能调用，见上方\"倒计时执行的时机\"说明\n\n| 名称          | 说明            |\n|-------------  |---------------- |\n| start | 开始倒计时  |\n"
  },
  {
    "path": "src/static/app/markdown/countTo.md",
    "content": "## CountTo 数字滚动 <to-api/>\n\n<demo-model url=\"/pages/componentsC/countTo/index\"></demo-model>\n\n\n该组件一般用于需要滚动数字到某一个值的场景，目标要求是一个递增的值。\n\n\n如果给组件的父元素设置`text-align: center`想让数字水平居中，可能是由于元素内容快速变化而导致渲染的问题，在APP上组件可能会有轻微的左右抖动现象，\n解决办法是给父元素设置`padding-left`或者`margin-left`即可。\n\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |    √     |\n\n### 基本使用\n\n通过`start-val`设置开始值，`end-val`设置结束值\n\n```html\n<u-count-to :start-val=\"30\" :end-val=\"500\"></u-count-to>\n```\n\n### 设置滚动相关参数\n\n- 通过`duration`设置从开始值到结束值整个滚动过程所需的时间，单位`ms`\n- 通过`use-easing`设置滚动快结尾的时候，是否放慢滚动的速度，给用户更好的视觉效果\n\n```html\n<u-count-to :start-val=\"30\" :end-val=\"500\" :duration=\"2000\" :use-easing=\"false\"></u-count-to>\n```\n\n### 是否显示小数位\n\n通过`decimals`设置显示的小数位，如果设置了，在滚动过程中，小数位会一起变化。如果`start-val`和`end-val`是带小数的，应该设置`decimals`为\n`start-val`和`end-val`一样的小数位数值，如`end-val`为1200.55，那么`decimals`应该设置为2。\n\n```html\n<u-count-to :start-val=\"30\" :end-val=\"500.55\" :decimals=\"2\"></u-count-to>\n```\n\n### 千分位分隔符\n\n通过`separator`配置千分位分隔符，默认为空字符串，可以设置英文逗号\",\"，此参数表现为`end-val`值超过1000时，比如为\"1257\"，那么滚动后会变成\"1,245\"，在金额数值时，\n该参数可能会用上。\n\n```html\n<u-count-to :end-val=\"1542\" separator=\",\"></u-count-to>\n```\n\n### 滚动执行的时机\n\n可以通过`autoplay`设置是否需要初始化时就开始滚动，默认为`true`，如果设置为`false`，可以通过组件的`ref`去控制组件内部的`start()`和`paused()`\n方法来开始或暂停。\n\n```html\n<template>\n\t<u-count-to ref=\"uCountTo\" :end-val=\"endVal\" :autoplay=\"autoplay\"></u-count-to>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tendVal: 5000.55,\n\t\t\t\tautoplay: false\n\t\t\t};\n\t\t},\n\t\tmethods: {\n\t\t\tstart() {\n\t\t\t\tthis.$refs.uCountTo.start();\n\t\t\t},\n\t\t\tpaused() {\n\t\t\t\tthis.$refs.uCountTo.paused();\n\t\t\t},\n\t\t\treStart() {\n\t\t\t\tthis.$refs.uCountTo.reStart();\n\t\t\t},\n\t\t}\n\t}\n</script>\n```\n\n### API\n\n### Props\n\n| 参数       | 说明                                 | 类型             | 默认值  | 可选值 |\n| ---------- | ------------------------------------ | ---------------- | ------- | ------ |\n| start-val  | 开始值                               | String \\| Number | 0       | -      |\n| end-val    | 结束值                               | String \\| Number | 0       | -      |\n| duration   | 滚动过程所需的时间，单位ms           | String \\| Number | 2000    | -      |\n| autoplay   | 是否自动开始滚动                     | Boolean          | true    | false  |\n| decimals   | 要显示的小数位数，见上方说明         | String \\| Number | 0       | -      |\n| use-easing | 滚动结束时，是否缓动结尾，见上方说明 | Boolean          | true    | false  |\n| separator  | 千位分隔符，见上方说明               | String           | -       | -      |\n| color      | 字体颜色                             | String           | #303133 | -      |\n| font-size  | 字体大小，单位rpx                    | String \\| Number | 50      | -      |\n| bold       | 字体是否加粗                         | Boolean          | false   | true   |\n\n\n### Methods\n\n此方法如要通过ref手动调用\n\n| 名称    | 说明                                      |\n| ------- | ----------------------------------------- |\n| start   | `autoplay`为`false`时，通过此方法启动滚动 |\n| reStart | 暂停后重新开始滚动(从暂停前的值开始滚动)  |\n| paused  | 暂停滚动                                  |\n\n\n### Event\n\n| 事件名 | 说明                   | 回调参数 | 版本 |\n| :----- | :--------------------- | :------- | :--- |\n| end    | 数值滚动到目标值时触发 | -        | -    |\n\n\n<style scoped>\nh3[id=methods] + p + table thead tr th:nth-child(1) {\n\twidth: 50%;\n}\n\nh3[id=methods] + p + table thead tr th:nth-child(2) {\n\twidth: 50%;\n}\n</style>"
  },
  {
    "path": "src/static/app/markdown/debounce.md",
    "content": "# throttle & debounce节流防抖\n\n<demo-model url=\"/pages/library/debounce/index\"></demo-model>\n\n### 何谓节流和防抖？\n\n- 节流  \n节流的意思是，规定时间内，只触发一次。比如我们设定500ms，在这个时间内，无论点击按钮多少次，它都只会触发一次。具体场景可以是抢购时候，由于有无数人\n快速点击按钮，如果每次点击都发送请求，就会给服务器造成巨大的压力，但是我们进行节流后，就会大大减少请求的次数。\n\n- 防抖  \n防抖的意思是，在连续的操作中，无论进行了多长时间，只有某一次的操作后在指定的时间内没有再操作，这一次才被判定有效。具体场景可以搜索框输入关键字过程中实时\n请求服务器匹配搜索结果，如果不进行处理，那么就是输入框内容一直变化，导致一直发送请求。如果进行防抖处理，结果就是当我们输入内容完成后，一定时间(比如500ms)没有再\n输入内容，这时再触发请求。\n\n结合以上两种情况，回到我们最实际的场景，比如防止表单提交按钮被多次触发，我们应该选择使用`节流`而不是`防抖`方案。\n\nuView内置的按钮组件`u-button`内部已做节流处理，无需外部再做节流处理。配置`throttle-time`参数，可以设置节流的时间，详见[Button 按钮](/zh/components/button.html)\n\n## 节流\n\n### throttle(func, wait = 500, immediate = true)\n\n规定时间内，只触发一次，可以通过设置`immediate`来决定触发的时机在这个时间的开始，还是结束的时候执行。\n\n- `func` <Function\\> 触发回调执行的函数\n- `wait` <Number\\> 时间间隔，单位ms\n- `immediate` <Number\\> 在开始还是结束处触发，比如设置`wait`为1000ms，如果在一秒内进行了5次操作，只触发一次，如果`immediate`为`true`，那么就会在第一次操作\n触发回调，如果为`false`，就会在第5次操作触发回调。\n\n\n```html\n<template>\n    <view class=\"\">\n\t\t<!-- 此处用法为在模板中使用，无需写this，直接$u.throttle()即可 -->\n    \t<view class=\"throttle\" @tap=\"$u.throttle(btnAClick, 500)\">\n    \t\t露从今夜白\n    \t</view>\n    \t<view class=\"throttle\" @tap=\"btnBClick\">\n    \t\t月是故乡明\n    \t</view>\n    </view>\n</template>\n\n<script setup lang=\"ts\">\nimport { $u } from 'uview-pro'\n\nfunction btnAClick() {\n\tconsole.log('btnClick');\n},\nfunction btnBClick() {\n\t$u.throttle(toNext, 500)\n},\nfunction toNext() {\n\tconsole.log('btnBClick');\n}\n</script>\n\n<style lang=\"scss\">\n    .throttle {\n\t\tmargin-top: 50rpx;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\theight: 100rpx;\n\t\tborder: 1px solid $u-type-primary;\n\t}\n</style>\n```\n\n\n\n## 防抖\n\n### debounce(func, wait = 500, immediate = false)\n\n在连续的操作中，无论进行了多长时间，只有某一次的操作后在指定的时间内没有再操作，这一次才被判定有效\n\n- `func` <Function\\> 触发回调执行的函数\n- `wait` <Number\\> 时间间隔，单位ms\n- `immediate` <Number\\> 在开始还是结束处触发，如非特殊情况，一般默认为`false`即可\n\n\n```html\n<template>\n    <view class=\"\">\n\t\t<!-- 此处用法为在模板中使用，无需写this，直接$u.debounce()即可 -->\n    \t<view class=\"debounce\" @tap=\"$u.debounce(btnAClick, 500)\">\n    \t\t露从今夜白\n    \t</view>\n    \t<view class=\"debounce\" @tap=\"btnBClick\">\n    \t\t月是故乡明\n    \t</view>\n    </view>\n</template>\n\n<script setup lang=\"ts\">\nimport { $u } from 'uview-pro'\n\nfunction btnAClick() {\n\tconsole.log('btnClick');\n},\nfunction btnBClick() {\n\t$u.debounce(toNext, 500)\n},\nfunction toNext() {\n\tconsole.log('btnBClick');\n}\n</script>\n\n<style lang=\"scss\">\n    .debounce {\n\t\tmargin-top: 50rpx;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\theight: 100rpx;\n\t\tborder: 1px solid $u-type-primary;\n\t}\n</style>\n```"
  },
  {
    "path": "src/static/app/markdown/deepClone.md",
    "content": "# deepClone 对象深度克隆\n\n<demo-model url=\"/pages/library/deepClone/index\"></demo-model>\n\n\n<br>\n\n由于JS对象包括的范围非常广，加上ES6又有众多的新特性，很难、也没必要做到囊括所有的类型和情况，这里说的\"对象\"，指的是普通的对象，不包括修改对象原型链，\n或者为\"Function\"，\"Promise\"等的情况，请留意。\n\n<br>\n\n场景：  \n\n- 我们平时可能会遇到需要通过`console.log`打印一个对象，至执行打印的时刻，此对象为空，后面的逻辑中对此对象进行了修改赋值，但是我们在控制台直接看到的打印结果\n却是修改后的值，这让人匪夷所思，虽然我们可以通过`console.log(JSON.parse(JSON.stringify(object)))`的形式处理，但是需要写这长长的一串，难免让人心生抵触。\n\n- 当我们将一个对象(变量A)赋值给另一个变量(变量B)时，修改变量B，因为对象引用的特性，导致A也同时被修改，所以有时候我们需要将A克隆给B，这样修改B的时候，就不会\n导致A也被修改。\n\n### deepClone(object = {})\n\n- `object` <Object\\> 需要被克隆的对象\n\n```js\nlet a = {\n\tname: 'mary'\n};\n\n// 直接赋值，为对象引用，即修改b等于修改a，因为a和b为同一个值\nlet b = a;\n\nb.name = 'juli';\nconsole.log(b); // 结果为 {name: 'juli'}\nconsole.log(a); // 结果为 {name: 'juli'}\n\n\n// 深度克隆\nlet b = uni.$u.deepClone(a);\n\nb.name = 'juli';\nconsole.log(b); // 结果为 {name: 'juli'}\nconsole.log(a); // 结果为 {name: 'mary'}\n```"
  },
  {
    "path": "src/static/app/markdown/deepMerge.md",
    "content": "# deepMerge 对象深度合并\n\n<demo-model url=\"/pages/library/deepMerge/index\"></demo-model>\n\n<br>\n\n由于JS对象包括的范围非常广，加上ES6又有众多的新特性，很难、也没必要做到囊括所有的类型和情况，这里说的\"对象\"，指的是普通的对象，不包括修改对象原型链，\n或者为\"Function\"，\"Promise\"等的情况，请留意。\n\n<br>\n\n在ES6中，我们可以很方便的使用`Object.assign`进行对象合并，但这只是浅层的合并，如果对象的属性为数组或者对象的时候，会导致属性内部的值丢失。\n  \n**注意：** 此处合并不同于`Object.assign`，因为`Object.assign(a, b)`会修改`a`的值为最终的结果(这往往不是我们所期望的)，但是`deepMerge(a, b)`并不会修改`a`的值。\n\n\n### deepMerge(target = {}, source = {})\n\n- `target` <Object\\> 目标对象\n- `source` <Object\\> 源对象\n\n`Object.assign`浅合并示例：\n\n```js\nlet a = {\n\tinfo: {\n\t\tname: 'mary'\n\t}\n}\n\nlet b = {\n\tinfo: {\n\t\tage: '22'\n\t}\n}\n\n// 使用Object.assign进行合并，注意此时a被修改了\nlet c = Object.assign(a, b);\n\n// 我们期望的结果为：\nc = {\n\tinfo: {\n\t\tname: 'mary',\n\t\tage: '22'\n\t}\n}\n\n// 事实上，我们得到的结果却为：\nc = {\n\tinfo: {\n\t\tage: '22'\n\t}\n}\n```\n\n深度合并示例：\n\n```js\nlet a = {\n\tinfo: {\n\t\tname: 'mary'\n\t}\n}\n\nlet b = {\n\tinfo: {\n\t\tage: '22'\n\t}\n}\n\nlet c = uni.$u.deepMerge(a, b);\n\n// c为我们期望的结果\nc = {\n\tinfo: {\n\t\tage: '22',\n\t\tname: 'mary'\n\t}\n}\n```"
  },
  {
    "path": "src/static/app/markdown/divider.md",
    "content": "## Divider 分割线 <to-api/>\n\n<demo-model url=\"/pages/componentsB/divider/index\"></demo-model>\n\n\n区隔内容的分割线，一般用于页面底部\"没有更多\"的提示。\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n文字内容通过`slot`传入\n\n```html\n<u-divider>大漠孤烟直</u-divider>\n```\n\n### 设置文字颜色\n可以通过`color`指定文字的颜色\n```html\n<u-divider color=\"#fa3534\">长河落日圆</u-divider>\n```\n\n### 设置单边边线条宽度和颜色\n\n- `half-width`指定文字某一边的线条宽度(注意这里设置的是一边，而不是文字两边线条的总长度)，`half-width`可以是数值(rpx)或者百分比\n- `type`可以快捷的设置线条为某一个主题色(默认`primary`)，`border-color`参数同样也能设置线条颜色，优先级高于`type`，也即是说二者同时\n设置了值，将会是`border-color`起作用。反之，如果要让`type`值起作用，就要将`border-color`置为空字符串或者`null`。\n\n```html\n<u-divider color=\"#fa3534\" half-width=\"200\" border-color=\"#6d6d6d\">姑苏城外寒山寺</u-divider>\n```\n\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            |        默认值        | 可选值   |\n|-------------  |---------------- |---------------- |---------------------- |-------- |\n| half-width | 文字左或右边线条宽度，数值或百分比，数值时单位为rpx  | String \\| Number | - | 150 |\n| border-color | 线条颜色，优先级高于`type` | String  | #dcdfe6 | - |\n| color | 文字颜色 | String  | #909399 | - |\n| fontSize | 字体大小，单位rpx | String \\| Number  | 26 | - |\n| bg-color | 整个divider的背景颜色 | String  | #ffffff | - |\n| height | 整个divider的高度，单位rpx | string \\| Number  | 40 | - |\n| type | 将线条设置主题色 | string  | primary | info \\ success \\ warning \\ error |\n| margin-top | 与前一个元素的距离，单位rpx | String \\| Number  | 0 | - |\n| margin-bottom | 与后一个元素的距离，单位rpx | String \\| Number  | 0 | - |\n| use-slot | 是否使用slot传入内容，如果不传入，中间不会有空隙 | Boolean  | true | false |\n\n\n\n### Events\n\n\n|事件名|说明|回调参数|版本|\n|:-|:-|:-|:-|\n| click | divider组件被点击时触发 | - | - |"
  },
  {
    "path": "src/static/app/markdown/downloadSetting.md",
    "content": "## 下载安装方式配置\n\n### 关于 SCSS\n\nuView Pro 依赖 SCSS，您必须要安装此插件，否则无法正常运行。\n\n- 如果您的项目是由`HBuilder X`创建的，相信已经安装 scss 插件，如果没有，请在 HX 菜单的 工具->插件安装中找到\"scss/sass 编译\"插件进行安装，\n  如不生效，重启 HX 即可\n- 如果您的项目是由`vue-cli`创建的，请通过以下命令安装对 sass(scss)的支持，如果已安装，请略过。\n\n```js\n// 安装sass\nnpm i sass -D\n\n// 安装sass-loader\nnpm i sass-loader -D\n```\n\n### 准备工作\n\n在进行配置之前，请确保您已经根据[安装](/components/install.html)中的步骤对 uView Pro 进行了下载安装，如果没有，请先下载安装。\n\n### 配置步骤\n\n#### 1. 引入 uView 主库\n\n在项目根目录中的`main.ts`中，引入并使用 uView Pro 的工具库，注意这两行要放在`import Vue`之后。\n\n```js\n// main.ts\nimport { createSSRApp } from \"vue\";\nimport uViewPro from \"uview-pro\";\n\nexport function createApp() {\n  const app = createSSRApp(App);\n  app.use(uViewPro);\n  // 其他配置\n  return {\n    app,\n  };\n}\n```\n\n#### 2. 在引入 uView Pro 的全局 SCSS 主题文件\n\n在项目根目录的`uni.scss`中引入此文件。\n\n```css\n/* uni.scss */\n@import \"uview-pro/theme.scss\";\n```\n\n#### 3. 引入 uView Pro 基础样式\n\n\n在`App.vue`中**首行**的位置引入，注意给 style 标签加入 lang=\"scss\"属性\n\n\n```css\n<style lang=\"scss\">\n\t/* 注意要写在第一行，同时给style标签加入lang=\"scss\"属性 */\n\t@import \"uview-pro/index.scss\";\n</style>\n```\n\n#### 4. 配置 easycom 组件模式\n\n此配置需要在项目根目录的`pages.json`中进行。\n\n\n\n1. uni-app 为了调试性能的原因，修改`easycom`规则不会实时生效，配置完后，您需要重启 HX 或者重新编译项目才能正常使用 uView 的功能。\n2. 请确保您的`pages.json`中只有一个`easycom`字段，否则请自行合并多个引入规则。\n3. 注意一定要放在`custom`里，否则无效，https://ask.dcloud.net.cn/question/131175\n\n\n\n```json\n// pages.json\n{\n  \"easycom\": {\n    // 注意一定要放在custom里，否则无效，https://ask.dcloud.net.cn/question/131175\n    \"custom\": {\n      \"^u-(.*)\": \"@/uview-pro/components/u-$1/u-$1.vue\"\n    }\n  },\n  // 此为本身已有的内容\n  \"pages\": [\n    // ......\n  ]\n}\n```\n"
  },
  {
    "path": "src/static/app/markdown/dropdown.md",
    "content": "## Dropdown 下拉菜单  <to-api/>\n      \n<demo-model url=\"/pages/componentsB/dropdown/index\"></demo-model>\n\n该组件一般用于向下展开菜单，同时可切换多个选项卡的场景。\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n使用前说明：\n\n- 该组件必须结合`u-dorpdown`和`u-dropdown-item`一起使用，展开的内容由`u-dropdown-item`通过传递参数或者`slot`提供\n- 组件的菜单栏标题由`u-dropdown-item`通过`title`参数提供\n- `u-dropdown-item`带有默认的单选展示功能，通过`options`(见下方说明)配置，传入`slot`则会覆盖默认功能，通过`v-model`双向绑定`options`选中项的`value`值\n\n\n```html\n<template>\n\t<view class=\"\">\n\t\t<u-dropdown>\n\t\t\t<u-dropdown-item v-model=\"value1\" title=\"距离\" :options=\"options1\"></u-dropdown-item>\n\t\t\t<u-dropdown-item v-model=\"value2\" title=\"温度\" :options=\"options2\"></u-dropdown-item>\n\t\t</u-dropdown>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tvalue1: 1,\n\t\t\t\tvalue2: 2,\n\t\t\t\toptions1: [{\n\t\t\t\t\t\tlabel: '默认排序',\n\t\t\t\t\t\tvalue: 1,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: '距离优先',\n\t\t\t\t\t\tvalue: 2,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: '价格优先',\n\t\t\t\t\t\tvalue: 3,\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\toptions2: [{\n\t\t\t\t\t\tlabel: '去冰',\n\t\t\t\t\t\tvalue: 1,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: '加冰',\n\t\t\t\t\t\tvalue: 2,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t}\n\t\t},\n\t}\n</script>\n```\n\n### 配置选项卡默认功能\n\n如上所示，`u-dropdown-item`具有默认的单选功能，这里主要讲解其`options`和`v-model`参数：\n\n`options`参数为一个数组，元素为对象，其中`label`为需要展示的提示文字，`value`为点击时双向绑定给`v-model`的值，`v-model`初始化时如果设置\n某个`options`中的`value`，则该条目将会被默认选中：\n\n```js\nlet options = [\n\t{\n\t\tlabel: '蜀道难',\n\t\tvalue: 1\n\t},\n\t{\n\t\tlabel: '难以上青天',\n\t\tvalue: 2\n\t}\n]\n```\n\n\n### 配置选项卡自定义功能\n\n在选项卡默认的单选功能无法满足的时候，我们可以给`u-dropw-item`传递`slot`来自定义需要展示的内容。  \n\n问：如果自定义内容，如何实现点击其中的按钮关闭下拉菜单？\n\n答：在`u-dropdown`中，有一个`close()`方法，可以通过`ref`获取实例，并调用方法进行关闭即可。\n\n\n```html\n<template>\n\t<view class=\"\">\n\t\t<u-dropdown ref=\"uDropdown\">\n\t\t\t<u-dropdown-item title=\"属性\">\n\t\t\t\t<view class=\"slot-content\">\n\t\t\t\t\t<view class=\"u-text-center u-content-color u-m-t-20 u-m-b-20\">其他自定义内容</view>\n\t\t\t\t\t<u-button type=\"primary\" @click=\"closeDropdown\">确定</u-button>\n\t\t\t\t</view>\n\t\t\t</u-dropdown-item>\n\t\t</u-dropdown>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tmethods: {\n\t\t\tcloseDropdown() {\n\t\t\t\tthis.$refs.uDropdown.close();\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 配置选项卡内容可滚动\n\n如果我们想给自定义内容的选项中局部内容可滚动，可以通过嵌入`scroll-view`元素实现，需要注意的是`scroll-view`必须声明高度才有效，大概如下：\n\n```html\n<template>\n\t<view class=\"\">\n\t\t<u-dropdown ref=\"uDropdown\">\n\t\t\t<u-dropdown-item title=\"属性\">\n\t\t\t\t<view class=\"slot-content\" style=\"background-color: #FFFFFF;\">\n\t\t\t\t\t<scroll-view scroll-y=\"true\" style=\"height: 200rpx;\">\n\t\t\t\t\t\t<view class=\"u-text-center u-content-color u-m-t-20 u-m-b-20\">无言独上西楼</view>\n\t\t\t\t\t\t<view class=\"u-text-center u-content-color u-m-t-20 u-m-b-20\">月如钩</view>\n\t\t\t\t\t\t<view class=\"u-text-center u-content-color u-m-t-20 u-m-b-20\">寂寞梧桐深院锁清秋</view>\n\t\t\t\t\t\t<view class=\"u-text-center u-content-color u-m-t-20 u-m-b-20\">剪不断</view>\n\t\t\t\t\t\t<view class=\"u-text-center u-content-color u-m-t-20 u-m-b-20\">理还乱</view>\n\t\t\t\t\t\t<view class=\"u-text-center u-content-color u-m-t-20 u-m-b-20\">是离愁</view>\n\t\t\t\t\t\t<view class=\"u-text-center u-content-color u-m-t-20 u-m-b-20\">别是一般滋味在心头</view>\n\t\t\t\t\t</scroll-view>\n\t\t\t\t\t<u-button type=\"primary\" @click=\"closeDropdown\">确定</u-button>\n\t\t\t\t</view>\n\t\t\t</u-dropdown-item>\n\t\t</u-dropdown>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tmethods: {\n\t\t\tcloseDropdown() {\n\t\t\t\tthis.$refs.uDropdown.close();\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n\n### 如何保持菜单高亮\n\n有时候，我们可能会希望下拉菜单收起之后，标题部分可以保持高亮，组件内部可以做到这样的要求，但是如果通过自定义`slot`传入了内容，那么组件就不知道\n收起的时候，是否该保持菜单的高亮了，因为组件不知道您在自定义的内容中是否进行了\"操作\"，所以我们提供了一个手动通过`ref`设置的`highlight(index)`方法，\n让您自主决定是否让某个菜单高亮，可以自行结合`change`(dropdown-item)、`open`(dropdown)、`close`(dropdown)事件进行组合操作。\n\n```html\n<template>\n\t<view class=\"\">\n\t\t<u-dropdown ref=\"uDropdown\" @open=\"open\" @close=\"close\">\n\t\t\t<u-dropdown-item v-model=\"value1\" title=\"距离\" :options=\"options1\" @change=\"change\"></u-dropdown-item>\n\t\t\t<u-dropdown-item v-model=\"value2\" title=\"温度\" :options=\"options2\"></u-dropdown-item>\n\t\t</u-dropdown>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tvalue1: 1,\n\t\t\t\tvalue2: 2,\n\t\t\t\toptions1: [{\n\t\t\t\t\t\tlabel: '默认排序',\n\t\t\t\t\t\tvalue: 1,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: '距离优先',\n\t\t\t\t\t\tvalue: 2,\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\toptions2: [{\n\t\t\t\t\t\tlabel: '去冰',\n\t\t\t\t\t\tvalue: 1,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: '加冰',\n\t\t\t\t\t\tvalue: 2,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\topen(index) {\n\t\t\t\t// 展开某个下来菜单时，先关闭原来的其他菜单的高亮\n\t\t\t\t// 同时内部会自动给当前展开项进行高亮\n\t\t\t\tthis.$refs.uDropdown.highlight();\n\t\t\t},\n\t\t\tclose(index) {\n\t\t\t\t// 关闭的时候，给当前项加上高亮\n\t\t\t\t// 当然，您也可以通过监听dropdown-item的@change事件进行处理\n\t\t\t\tthis.$refs.uDropdown.highlight(index);\n\t\t\t},\n\t\t\tchange() {\n\t\t\t\t// 更多的细节，如有需要请自行根据业务逻辑进行处理\n\t\t\t\t// this.$refs.uDropdown.highlight(xxx);\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 兼容性\n\n- 由于`头条小程序`的兼容性原因，如果`u-dropdown`父元素设置了`display: flex`，您可能需要给组件添加`u-dropdown`类，如下：\n\n```html\n<u-dropdown class=\"u-dropdown\"></u-dropdown>\n```\n\n### API\n\n### Dropdown Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| active-color | 标题和选项卡选中的颜色  | String  | #2979ff | - |\n| inactive-color | 标题和选项卡未选中的颜色  | String  | #606266 | - |\n| close-on-click-mask | 点击遮罩是否关闭菜单  | Boolean | true | false |\n| close-on-click-self | 点击当前激活项标题是否关闭菜单  | Boolean | true | false |\n| duration | 选项卡展开和收起的过渡时间，单位ms  | String \\| Number | 300 | - |\n| height | 标题菜单的高度，单位任意，数值默认为rpx单位 | String \\| Number | 80 | - |\n| border-bottom | 标题菜单是否显示下边框  | Boolean | false | true |\n| title-size | 标题的字体大小，单位任意，数值默认为rpx单位 | String \\| Number | 28 | - |\n| border-radius | 菜单展开内容下方的圆角值，单位任意 | String \\| Number | 0 | - |\n| menu-icon | 标题菜单右侧的图标 | String | arrow-down | arrow-down-fill |\n| menu-icon-size | 标题菜单右侧的图标的大小，单位任意，数值默认为rpx单位 | String \\| Number | 26 | - |\n\n\n### Dropdown Events\n\n|事件名|说明|回调参数|\n|:-|:-|:-|:-|\n| open | 下拉菜单被打开时触发 | (index) - 当前被打开菜单的索引 |\n| close | 下拉菜单被关闭时触发 | (index) - 当前被关闭菜单的索引 |\n\n\n### Dropdown-item Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| v-model | 双向绑定选项卡选择值  | String \\| Number | - | - |\n| title | 菜单项标题  | String  | - | - |\n| options | 选项数据，如果传入了默认slot，此参数无效，数据结构见上方说明  | Array[Object]  | - | - |\n| disabled | 是否禁用此选项卡  | Boolean | false | true |\n| height | 弹窗下拉内容的高度(内容超出将会滚动)，`slot`自定义内容时无效(自行使用`scroll-view`处理)，单位任意，默认rpx | String \\| Number | auto | - |\n\n\n\n### Dropdown-item Slot\n\n| 名称          | 说明            |\n|-------------  |---------------- |\n| - | 自定义选项卡内容  |\n\n\n\n### Dropdown-item Events\n\n|事件名|说明|回调参数|\n|:-|:-|:-|:-|\n| change | 每个`u-dropdown`均有此回调，点击某个`options`选项时触发 | (value) - 点击项绑定的`value`属性值 |\n\n\n### Dropdown-item Methods\n\n这些为组件内部的方法，需要通过`ref`调用\n\n| 参数          | 说明            | \n|-------------  |---------------- |\n| highlight(index) | index为需要设置高亮的菜单项的索引(从0开始)，不写表示清空内部的高亮 | \n\n\n\n<style scoped>\nh3[id=dropdown-item-slot] + table thead tr th:nth-child(2){\n\twidth: 50%;\n}\n\nh3[id=dropdown-item-methods] + p + table thead tr th:nth-child(2){\n\twidth: 70%;\n}\n\nh3[id=dropdown-events] + table thead tr th:nth-child(2){\n\twidth: 33.33%;\n}\n\nh3[id=dropdown-item-events] + table thead tr th:nth-child(2){\n\twidth: 33.33%;\n}\n</style>"
  },
  {
    "path": "src/static/app/markdown/empty.md",
    "content": "## Empty 内容为空 <to-api/>\n\n<demo-model url=\"/pages/componentsA/empty/index\"></demo-model>\n\n\n该组件用于需要加载内容，但是加载的第一页数据就为空，提示一个\"没有内容\"的场景，\n我们精心挑选了十几个场景的图标，方便您使用。\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |    √     |\n\n### 基本使用\n\n\n从`1.4.2`版本起，移除了此组件内置的图片，因为这些图片太大，影响了组件库的大小。改用字体图标的形式提供，缺点是字体图标只能是单色的，形状与原来的图片也有些许出入。\n基于以上，我们的专业设计师精心为您准备了一套精美缺省图，带有图片和`Sketch`文件，您可以下载或修改后再使用：[资源下载](/components/resource.html)\n\n\n- 通过`text`参数配置提示的文字内容\n- 通过`mode`(默认为`data`)参数配置要显示的图标\n\n```html\n<u-empty text=\"所谓伊人，在水一方\" mode=\"list\"></u-empty>\n```\n\n### 内置图标\n\n这些图标已内置，直接通过`mode`参数引用即可\n\n| 名称       | 说明                 |\n| ---------- | -------------------- |\n| car        | 购物车为空           |\n| page       | 页面不存在           |\n| search     | 没有搜索结果         |\n| address    | 没有收货地址         |\n| wifi       | 没有WiFi             |\n| order      | 订单为空             |\n| coupon     | 没有优惠券           |\n| favor      | 无收藏               |\n| permission | 无权限               |\n| history    | 无历史记录           |\n| news       | 无新闻列表           |\n| message    | 消息列表为空         |\n| list       | 列表为空(通用)       |\n| data       | 数据为空(默认，通用) |\n\n\n### API\n\n### Props\n\n| 参数                                            | 说明                                                               | 类型             | 默认值  | 可选值 |\n| ----------------------------------------------- | ------------------------------------------------------------------ | ---------------- | ------- | ------ |\n| color                                           | 文字颜色                                                           | String           | #c0c4cc | -      |\n| text                                            | 文字提示                                                           | String           | 无内容  | -      |\n| icon-color                                      | icon的颜色，字体图标时有效                                         | String           | #c0c4cc | -      |\n| icon-size                                       | icon的大小，单位rpx，如果`src`为图片路径，此参数可以设置图片的尺寸 | String \\| Number | 120     | -      |\n| src                                             | 图标名称或者图片路径(绝对路径)，如定义，`mode`参数会失效           | String           | -       | -      |\n| font-size                                       | 提示文字的大小，单位rpx                                            | String \\| Number | 28      | -      |\n| mode                                            | 内置的图标，见上方说明                                             | String           | data    | -      |\n| img-width <Badge type=\"error\" text=\"已废弃\" />  | 图标的宽度，单位rpx                                                | String \\| Number | 240     | -      |\n| img-height <Badge type=\"error\" text=\"已废弃\" /> | 图标的高度，单位rpx                                                | String           | auto    | -      |\n| show                                            | 是否显示组件                                                       | Boolean          | true    | false  |\n| margin-top                                      | 组件到上一个元素的间距,单位rpx                                     | String \\| Number | 0       | -      |\n\n\n\n### Slot\n\n| 名称   | 说明                     |\n| ------ | ------------------------ |\n| bottom | 给组件底部传入`slot`内容 |\n\n\n<style scoped>\nh3[id=内置图标] + p + table thead tr th:nth-child(2){\n\twidth: 50%;\n}\n</style>"
  },
  {
    "path": "src/static/app/markdown/fastUse.md",
    "content": "# 便捷工具\n\n<demo-model url=\"/pages/componentsA/toast/index\"></demo-model>\n\n\n此专题内容为一些方便用户快速，便捷使用的小工具，可能是uView的一些方法的简易版，或者对uni的一些方法进行二次封装，方便用户\n快速使用。\n\n\n### toast(title, duration = 1500)\n\n- `title` <String\\> toast的消息内容\n- `duration` <Number\\> toast出现到消失的时间，单位ms，默认1500ms\n\n此方法为uniapp的`uni.showToast`的二次封装，方便用户使用，参数只能配置`title`和`duration`\n\n```js\nuni.$u.toast('Hello uView!');\n```\n\n\n### os()\n\n此属性用于返回平台的名称，为小写的`ios`或`android`  \n\n**注意：** 以方法形式调用\n\n```js\nconsole.log(uni.$u.os())\n```\n\n\n### sys()\n\n此属性用于获取设备的信息，相当于uni.getSystemInfoSync()的效果  \n\n**注意：** 以方法形式调用，因为属性方式调用，结果可能会不准确\n\n```js\nconsole.log(uni.$u.sys())\n```\n\n"
  },
  {
    "path": "src/static/app/markdown/feature.md",
    "content": "## 注意事项\n\n由于 uni-app 支持多端开发，而各端，特别是各小程序平台，没有统一的标准，加重了开发者和企业的成本，幸好 uni-app 使用 Vue 标准，对各端进行了写法的统一，\n推动了生态的发展，但是由于某些小程序平台自身的原因，仍然会出现某些兼容性问题，我们会将制作 uView 过程中遇到，和平时收集的兼容性问题呈现在本专题，希望能\n帮助到 uni-app 开发者。\n\n### 支付宝小程序\n\n\nuView Pro 需要开启了`component2`模式才支持支付宝小程序\n\n\n1. 支付宝在很早前，已升级为`component2`模式，此模式支持更多的功能和特性，uni-app 上，很多的特性，如`provide/inject`、`$slots`等，需要开启此模式才能支持，\n   而此模式在 uni-app 新建项目中默认是关闭的，因而需要在项目根目录的`manifest.json`中开启，如没有`alipay`属性节点，新增即可：\n\n```json\n......\n\"mp-alipay\" : {\n\t\"component2\": true\n},\n......\n```\n\n2. uView Pro 的`waterfall`瀑布流组件使用了`$scoped slot`特性，由于 hx 的问题，在 hx2.8.2 修正了此问题，所以瀑布流组件需要 hx2.8.2 及以上才支持支付宝小程序。\n\n### Vue 特性在各平台支持度\n\n1. 以下特性，uView 已对各小程序开发工具，H5 浏览器，APP(不含 NVUE)进行过实测，均获得支持，其中支付宝小程序需要开启`component2`模式。\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ 小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :-------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |     √     |\n\n- provide / inject\n- $slots\n- v-model / sync\n- $parent / $children\n\n<style scoped>\nh3[id=vue特性在各平台支持度] + ol + table thead tr th:nth-child(2){\n\twidth: auto;\n}\n</style>\n\n<!-- ### 二次修改封装uView组件\n\nuView组件一直追求完善而精致，如果您觉得某个组件可能和您的需求不一致，或者您有更好的实现方案和或思路，您可以在群里反馈给我们，也可以在[github](https://github.com/anyup/uView-Pro)上\n给我们提PR，我们会第一时间跟进和处理。\n如果您仍然有需要修改uView组件源码的需求，通常情况下，可以有如下两个办法：\n\n- 直接修改组件的部分源码，这样的好处是方便快捷，然而缺点也是显而易见的，这意味着您无法再升级后续的uView版本，这是我们不推荐的。\n- 您可以将某个组件复制出来放到某个文件进行修改，再通过`import`的形式引入使用，这样可以正常升级uView的后续版本。\n\n然而，我们有更好的方案，本质上还是利用了`easycom`的特性，让您能无感的修改并使用uView的组件，以下以修改`u-button`组件作为示例：\n\n1). 到`uview-pro`组件库文件中的`components`目录中复制`u-button`目录，并粘贴到项目**根目录**的`components`目录中\n\n2). 此时`uview-pro/components`和根目录的`components`目录中，各有一份`u-button`组件源码，在符合规则的情况下，hx编译会自动对根目录的`components`组件引用`easycom`\n规则，但由于`pages.json`中定义了`easycom`规则，所以`uview-pro/components`中的同名组件比根目录的`components`目录中的同名组件优先级更高，解决办法是\n在`pages.json`中定义另一条`easycom`规则：\n\n```json\n// pages.json\n\"easycom\": {\n\t\"^u-(.*)\": \"@/uview-pro/components/u-$1/u-$1.vue\",\n\t// 由于后来者居上的原则，下面的规则覆盖上面的规则，所以同名组件时，components中的u-button比uview-pro中的u-button优先级更高\n\t\"^u-(.*)\": \"@/components/u-$1/u-$1.vue\"\n}\n```\n\n3). 进行以上操作后，您可以尽情修改根目录的`components`中的`u-button`组件源码，在页面同样是通过`<u-button></u-button>`形式使用，\n但最终引用的却是您修改后的组件。 -->\n\n### 设置页面背景颜色\n\n一般情况下，我们给页面的`page`节点或者给页面的最外层`view`设置背景颜色，二者分别有如下需要注意点：\n\n#### 1. 通过`page`节点设置\n\n这个方式全端有效，但是需要注意的是，在微信小程序，或者某些安卓机型上，该节点如果写在带`scoped`属性的样式标签内是无效的，所以我们建议\n您可以在页面多加一个不带 scoped 属性的样式标签，如下：\n\n```css\n/* 如果需要css的支持，还可以添加lang属性 */\n<style lang=\"scss\">\npage {\n\tbackground-color: $u-bg-color;\n}\n</style>\n\n/* 带scoed属性的其他样式 */\n<style lang=\"scss\" scoped>\n.box {\n\t......\n}\n</style>\n```\n\n#### 2. 通过页面外层`view`设置\n\n相比`page`节点，`view`的高度默认为内容高度，所以如果页面内容不足一屏高度时，底部剩余部分依然为默认的白色，所以我们给需要这个`view`设置一个\n最低高度，让它等于窗口高度：\n\n```html\n<template>\n  <view class=\"wrap\"> ...... </view>\n</template>\n\n<style scoped lang=\"scss\">\n  .wrap {\n    background-color: $u-bg-color;\n    min-height: 100vh;\n  }\n</style>\n```\n\n### 全局赋值设备信息的陷阱\n\n我们都知道，可以通过`uni.getSystemInfoSync()`获取设备信息，但是每次用到时都写一遍是很繁琐的，所以很多同学们都会突发奇想，比如在`main.js`或者\n在`App.vue`中将`uni.getSystemInfoSync()`的结果赋值给`Vue.prototype`，如下：\n\n```js\n// main.js\nVue.prototype.system = uni.getSystemInfoSync();\n```\n\n上面的写法没有问题，我们可以任意地方通过`this.system`得到设备的信息，但是这里有一个陷阱，写在`main.js`，意味着赋值代码只会被执行一次，且是 APP 启动的时候，\n但是 uni-app 中，设备信息的`windowHeight`属性是不含 APP 的导航栏和 tabbar 高度在内的，当我们进入首页时，`windowHeight`不含 tabbar 高度在内，高度可能为\n'700px'，但是进入内页后，没有 tabbar，这时的`windowHeight`高度依然为 700px(少掉了 tabbar 的 50px 高度)，显然是不正确的。  \n上面说的只是对`windowHeight`属性有影响，其他的属性无碍，如果是需要获取高度，建议每次都执行`uni.getSystemInfoSync()`，或者通过 uView 提供的快捷工具\n`uni.$u.sys()`方法获取即可。\n\n### 小程序主包太大无法预览和发布\n\n我们都知道微信小程序预览和发布的主包大小都不能超过`2M`，否则无法真机预览和上传发布，经常有同学反馈刚使用 uView，调试时候主包就超过了`2M`而无法真机预览，\n我们在这里做一个说明，uView 是`按需引入`的，在发行时，HX 会自动剔除您没有使用组件，即使您使用了 uView 的全部组件，整个 uView 的大小也只有 500K 左右，但是有如下两点前提：\n\n- **调试**  \n  在调试阶段，为了调试的友好效果和编译速度等，HX 默认是没有对 JS 进行压缩和去除注释，也没有进行组件按需引入的，所以会导致 JS 文件都很大，我们需要在\n  HBuilder X 进行如下操作，再重新编译即可：\n\n```js\nHBuilderX   运行->运行到小程序模拟器->勾选 运行时是否压缩代码\n```\n\n- **发布**  \n  在 HX 中进行发布时，uView 的组件会按需引入(使用 uView 所有组件的情况下，占用空间 500k 左右)，如果主包依然超出`2M`，您需要从多个方面着手：\n\n1. [小程序分包](https://uniapp.dcloud.io/collocation/pages?id=subpackages)\n2. 将静态资源放到服务器进行引用\n3. 取消\"ES6 转 ES5\"设置\n\n### uni.scss 的优缺点\n\n`uni.scss`为 uni-app 新建项目自带工程文件，使用的预处理器为`sass/scss`，由此可见，uni-app 官方推荐的是`scss`，同时我们 uView 也是`scss`的坚定推崇者，不建议在\nuni-app 中使用`less`、`stylus`等。\n\n`uni.scss`具有如下一些特点：\n\n- 无需引入，uni-app 在编译时，会自动引入此文件\n- 在此中定义的`scss`变量，可以全局使用，可以在此定义一些颜色，主题，尺寸等变量\n- **`uni.scss`会编译到每个`scss`文件中**(请着重理解这一句话)\n\n综上所述，我们可以得知，`uni.scss`主要是利用`scss`的特性，定义一些全局变量，供各个写了`lang=scss`的 style 标签引用，但是这引出了一个重要的问题：  \n`uni.scss`中所写的一切内容，都会注入到每个声明了`scss`的文件中，这意味着，如果您的`uni.scss`如果有几百行，大小 10k 左右，那么这个 10k 都会被注入所有的\n其他`scss`文件(页面)中，如果您的应用有 50 个页面，那么有可能因此导致整体的包体积多了 50 \\* 10 = 500k 的大小，这可能会导致小程序包太大而无法预览和发布，\n所以，我们建议您只将`scss`变量相关的内容放到`uni.scss`中。\n\n### 样式覆盖兼容性\n\n为了避免样式被用户覆盖，或者被污染，一般组件或者页面都会给`style`标签加上`scoped`属性，如下演示为一个组件的内部构造：\n\n```html\n/* item.vue */\n<template>\n  <view class=\"item\"></view>\n</template>\n\n<style scoped>\n  .item {\n    border: 1px solid red;\n  }\n</style>\n```\n\n我们在页面中引入上方的`item`组件，并且想修改它的`border`边框为颜色(blue)，一般通过`v-deep`或`/deep/`指令修改，如下写法：\n\n```html\n<template>\n  <item></item>\n</template>\n\n<style scoped>\n  ::v-deep .item {\n    border: 1px solid blue;\n  }\n</style>\n```\n\n上面的写法，在`App`和`H5`正常，但是在微信小程序无效，它要求`::v-deep`或`/deep/`前面必须还要有父元素的类名存在，如下：\n\n```html\n<template>\n  <view class=\"wrap\">\n    <item></item>\n  </view>\n</template>\n\n<style scoped>\n  .wrap ::v-deep .item {\n    border: 1px solid blue;\n  }\n</style>\n```\n\n如果是在支付宝小程序中，写在组件上的类名和内联样式，都是无效的，如下：\n\n```html\n<template>\n  /*\n  在支付宝小程序，组件标签上的任何class和style都会被剔除，不会添加到组件内部的根元素中\n  */\n  <item style=\"border: 1px solid blue\" class=\"item\"></item>\n</template>\n```\n"
  },
  {
    "path": "src/static/app/markdown/field.md",
    "content": "## Field 输入框 <to-api/>\n\n<demo-model url=\"/pages/componentsA/field/index\"></demo-model>\n\n\n借助此组件，可以实现表单的输入， 有\"text\"和\"textarea\"类型的，此外，借助uView的`picker`和`actionSheet`组件可以快速实现上拉菜单，时间，地区选择等，\n为表单解决方案的利器。\n\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n\n### 基本使用\n\n- 通过`v-model`，可以双向绑定输入框的值\n- 通过`label`设置输入框左边的提示文字\n- 通过`placeholder`指定个性化的提示语\n\n```html\n<template>\n\t<view>\n\t\t<u-field\n\t\t\tv-model=\"mobile\"\n\t\t\tlabel=\"手机号\"\n\t\t\tplaceholder=\"请填写手机号\"\n\t\t>\n\t\t</u-field>\n\t\t<u-field\n\t\t\tv-model=\"code\"\n\t\t\tlabel=\"验证码\"\n\t\t\tplaceholder=\"请填写验证码\"\n\t\t>\n\t\t</u-field>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tmobile: '',\n\t\t\t\tcode: ''\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n\n#### 自定义输入框类型\n\n我们可以通过`type`参数来自定义输入框的类型，如果为`text`(默认)内部为`input`输入框，如果为`textarea`值，内部为`textarea`输入框，相比`input`输入框，\n它的默认高度约为两个`input`的高度，且可以换行，同时组件高度也会自动增高，适用于需要多行输入的场景。\n\n```html\n<template>\n\t<view class=\"\">\n\t\t<u-field\n\t\t\tv-model=\"mobile\"\n\t\t\tlabel=\"手机号\"\n\t\t\tplaceholder=\"请填写手机号\"\n\t\t>\n\t\t</u-field>\n\t\t\n\t\t<u-field\n\t\t\tv-model=\"mobile\"\n\t\t\tlabel=\"手机号\"\n\t\t\tplaceholder=\"请填写手机号\"\n\t\t\ttype=\"textarea\"\n\t\t>\n\t\t</u-field>\n\t</view>\n</template>\n```\n\n\n#### 必填和错误提示\n\n- 通过设置`required`，可以给输入框左边添加一个红色的\"*\"号，它只起提示作用，uView内部不会判断用户是否输入了值，您需要提交的时候，通过`v-model`绑定的值自行判断\n- 通过设置`error-message`，会在输入框下方给用红色给出错误提示\n\n```html\n<template>\n\t<view class=\"\">\n\t\t<u-field\n\t\t\tv-model=\"mobile\"\n\t\t\tlabel=\"手机号\"\n\t\t\trequired\n\t\t\t:error-message=\"errorMessage\"\n\t\t>\n\t\t</u-field>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\terrorMessage: '剑未配妥，出门已是江湖'\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n\n#### 在输入框尾部插入按钮\n\n此为在表单填写时，可能需要用户发送验证码的场景，可以通过`slot`插入一个uView的[button](/components/button.html)组件，通过结合uView的[VerificationCode](/components/verificationCode.html)，\n可以简单，迅速的将功能集成\n\n```html\n<template>\n\t<view class=\"\">\n\t\t<u-field\n\t\t\tv-model=\"code\"\n\t\t\tlabel=\"验证码\"\n\t\t\tplaceholder=\"请填写验证码\"\n\t\t>\n\t\t\t<template #right>\n\t\t\t\t<u-button size=\"mini\" type=\"success\" @click=\"getCode\">{{codeText}}</u-button>\n\t\t\t</template>\n\t\t</u-field>\n\t\t<u-verification-code ref=\"uCode\" @change=\"codeChange\"></u-verification-code>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tmobile: '',\n\t\t\t\tcode: '',\n\t\t\t\tcodeText: ''\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\tcodeChange(text) {\n\t\t\t\tthis.codeText = text;\n\t\t\t},\n\t\t\tgetCode() {\n\t\t\t\tif(this.$refs.uCode.canGetCode) {\n\t\t\t\t\t// 模拟向后端请求验证码\n\t\t\t\t\tuni.showLoading({\n\t\t\t\t\t\ttitle: '正在获取验证码'\n\t\t\t\t\t})\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tuni.hideLoading();\n\t\t\t\t\t\t// 通知验证码组件内部开始倒计时\n\t\t\t\t\t\tthis.$refs.uCode.start();\n\t\t\t\t\t}, 1000);\n\t\t\t\t}else {\n\t\t\t\t\tuni.$u.toast('倒计时结束后再发送');\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n\n#### 如何与Picker或者actionSheet等组件结合\n\n某些场景，比如需要用用户选择性别，或者时间，地区选择等，我们可以结合uView的[ActionSheet](/components/actionSheet.html)和[Picker](/components/picker.html)组件解决，\n这种情况，一般都是要求`field`组件是不可输入内容的，我们需要设置`disabled`参数为`true`，既然是需要弹出选择框，`field`组件右边应该要有一个实心向下的\n三角形图标，配置为`right-icon`为`arrow-down-fill`，同时监听`click`即可。这一切，uView都帮您想到，并且做好了。  \n\n\n\n```html\n<template>\n\t<view class=\"\">\n\t\t<u-field @click=\"showAction\" v-model=\"sex\" \n\t\t:disabled=\"true\" label=\"性别\" placeholder=\"请选择性别\"\n\t\tright-icon=\"arrow-down-fill\"\n\t\t>\n\t\t</u-field>\n\t\t<u-action-sheet @click=\"clickItem\" :list=\"sexList\" v-model=\"show\"></u-action-sheet>\n\t</view>\n</template>\n\n<script>\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tsex: '',\n\t\t\tsexList: [\n\t\t\t\t{\n\t\t\t\t\ttext: '男',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttext: '女'\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttext: '保密'\n\t\t\t\t}\n\t\t\t],\n\t\t\tshow: false\n\t\t};\n\t},\n\tmethods: {\n\t\tshowAction() {\n\t\t\tthis.show = true;\n\t\t},\n\t\tclickItem(index) {\n\t\t\tthis.sex = this.sexList[index].text;\n\t\t}\n\t}\n};\n</script>\n```\n\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| type | 输入框的类型 | String  | text | textarea |\n| icon | `label`左边的图标，限uView的图标名称 | String | - | - |\n| border-bottom | 是否显示field的下边框 | Boolean  | true | false |\n| border-top | 是否显示field的上边框 | Boolean  | false | true |\n| icon-style | icon的样式，对象形式 | Object | - | - |\n| right-icon | 输入框右边的图标名称，限uView的图标名称 | String  | - | - |\n| required | 是否必填，左边显示红色\"*\"号 | Boolean  | false | true |\n| label | 输入框左边的文字提示 | String  | - | - |\n| password | 是否密码输入方式(用点替换文字)，`type`为`text`时有效 | Boolean  | false | true |\n| clearable | 是否显示右侧清空内容的图标控件(输入框有内容，且获得焦点时才显示)，点击可清空输入框内容 | Boolean  | true | false |\n| label-width | `label`的宽度，单位rpx | Number \\| String | 130 | - |\n| label-align | `label`的文字对齐方式 | String  | left | center / right |\n| input-align | 输入框内容对齐方式 | String | left | center / right |\n| icon-color | 左边通过`icon`配置的图标的颜色 | String  | #606266 | - |\n| clear-size | 清除图标的大小，单位rpx | Number \\| String | 30 | - |\n| field-style | 输入框的样式，对象形式 | Object  | - | - |\n| auto-height | 是否自动增高输入区域，`type`为`textarea`时有效 | Boolean | true | false |\n| error-message | 显示的错误提示内容，如果为空字符串或者`false`，则不显示错误信息 | String \\ Boolean  | - | - |\n| placeholder | 输入框的提示文字 | String | - | - |\n| placeholder-style | `placeholder`的样式(内联样式，字符串)，如\"color: #ddd\" | String | - | - |\n| focus | 是否自动获得焦点 | Boolean | false | true |\n| fixed | 如果`type`为`textarea`，且在一个\"position:fixed\"的区域，需要指明为`true` | Boolean | false | true |\n| disabled | 是否不可输入 | Boolean | false | true |\n| maxlength | 最大输入长度，设置为 -1 的时候不限制最大长度 | Number \\| String | 140 | - |\n| confirm-type | 设置键盘右下角按钮的文字，仅在type=\"text\"时生效 | String | done | - |\n| trim | 是否自动去除两端的空格 | Boolean | true | false |\n\n\n### Slot\n\n| 名称          | 说明            |\n|-------------  |---------------- |\n| icon | 自定义左侧的图标 |\n| right | 自定义右侧内容 |\n\n\n### Events\n\n|事件名|说明|回调参数|\n|:-|:-|:-|:-|\n| input | 输入框内容发生变化时触发 | value：输入框的内容，建议通过`v-model`双向绑定输入值，而不是监听此事件的形式 |\n| focus | 输入框获得焦点时触发 | - |\n| blur | 输入框失去焦点时触发 | - |\n| confirm | 点击完成按钮时触发 | value：输入框的内容，建议通过`v-model`双向绑定输入值，而不是监听此事件的形式 | \n| right-icon-click | 通过`right-icon`生成的图标被点击时触发 |\n| click | 输入框被点击或者通过`right-icon`生成的图标被点击时触发，这样设计是考虑到传递右边的图标，一般都为需要弹出\"picker\"等操作时的场景，点击倒三角图标，理应发出此事件，见上方说明| - |\n\n\n<style scoped>\nh3[id=props] + table thead tr th:nth-child(2){\n\twidth: 40%;\n}\n\nh3[id='cellitem-slot'] + table thead tr th:nth-child(2){\n\twidth: 50%;\n}\n\nh3[id='cellitem-events'] + table thead tr th:nth-child(2){\n\twidth: 40%;\n}\n\nh3[id='cellitem-events'] + table thead tr th:nth-child(3){\n\twidth: 40%;\n}\n</style>\n"
  },
  {
    "path": "src/static/app/markdown/form.md",
    "content": "## Form 表单 <to-api/>\n\n此组件一般用于表单场景，可以配置Input输入框，Select弹出框，进行表单验证等。\n\n<demo-model url=\"/pages/componentsA/form/index\"></demo-model>\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n此组件一般是用于表单验证使用，每一个表单域由一个`u-form-item`组成，表单域中可以放置`u-input`、`u-checkbox`、`u-radio`、`u-switch`等。\n\n- 在表单组中，通过`model`参数绑定一个对象，这个对象的属性为各个`u-form-item`内组件的对应变量。\n- 由于表单验证和绑定表单规则时，需要通过`ref`操作，故这里需要给`form`组件声明`ref=\"uFormRef\"`属性。\n- 关于`u-from-item`内其他可能包含的诸如`input`、`radio`等组件，请见各自组件的相关文档说明。\n\n下方为一个经典表单的示例，包含`input`、`textarea`、`radio`、`checkbox`、`switch`的组合使用：\n\n```vue\n<template>\n\t<u-form :model=\"form\" ref=\"uFormRef\">\n\t\t<u-form-item label=\"姓名\"><u-input v-model=\"form.name\" /></u-form-item>\n\t\t<u-form-item label=\"简介\"><u-input v-model=\"form.intro\" /></u-form-item>\n\t\t<u-form-item label=\"性别\"><u-input v-model=\"form.sex\" type=\"select\" /></u-form-item>\n\t\t<u-form-item label=\"水果\">\n\t\t\t<u-checkbox-group>\n\t\t\t\t<u-checkbox\n\t\t\t\t\tv-for=\"(item, index) in checkboxList\"\n\t\t\t\t\t:key=\"index\"\n\t\t\t\t\tv-model=\"item.checked\"\n\t\t\t\t\t:name=\"item.name\"\n\t\t\t\t>\n\t\t\t\t\t{{ item.name }}\n\t\t\t\t</u-checkbox>\n\t\t\t</u-checkbox-group>\n\t\t</u-form-item>\n\t\t<u-form-item label=\"味道\">\n\t\t\t<u-radio-group v-model=\"radio\">\n\t\t\t\t<u-radio\n\t\t\t\t\tv-for=\"(item, index) in radioList\"\n\t\t\t\t\t:key=\"index\"\n\t\t\t\t\t:name=\"item.name\"\n\t\t\t\t\t:disabled=\"item.disabled\"\n\t\t\t\t>\n\t\t\t\t\t{{ item.name }}\n\t\t\t\t</u-radio>\n\t\t\t</u-radio-group>\n\t\t</u-form-item>\n\t\t<u-form-item label=\"开关\">\n\t\t\t<template #right>\n\t\t\t\t<u-switch v-model=\"switchVal\"></u-switch>\n\t\t\t</template>\n\t\t</u-form-item>\n\t</u-form>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, reactive } from 'vue';\n\nconst uFormRef = ref();\nconst form = reactive({\n\tname: '',\n\tintro: '',\n\tsex: ''\n});\nconst checkboxList = reactive([\n\t{ name: '苹果', checked: false, disabled: false },\n\t{ name: '雪梨', checked: false, disabled: false },\n\t{ name: '柠檬', checked: false, disabled: false }\n]);\nconst radioList = reactive([\n\t{ name: '鲜甜', disabled: false },\n\t{ name: '麻辣', disabled: false }\n]);\nconst radio = ref('');\nconst switchVal = ref(false);\n</script>\n```\n\n### Form-item组件说明\n\n此组件一般需要搭配`Form`组件使用，也可以单独搭配`Input`等组件使用，由于此组件参数较多，这里只对其中参数最简要介绍，其余请见底部的API说明：\n\n- `prop`为传入`Form`组件的`model`中的属性字段，如果需要表单验证，此属性是必填的。\n- `label-position`可以配置左侧\"label\"的对齐方式，可选为`left`和`top`。\n- `border-bottom`是否显示表单域的下划线，如果给`Input`组件配置了边框，可以将此属性设置为`false`，从而隐藏默认的下划线。\n- 如果想在表单域配置左右的图标(或小图片，1.3.0开始，[Icon 图标](/components/icon.html)可以配置图片)，可以通过`left-icon`和`right-icon`参数实现。\n\n### 表单验证\n\nuView Pro的表单组件具备完整的验证功能，在开始之前，需要了解如下几个注意事项，方面您快速上手：\n\n#### `Form`组件绑定`model`参数\n\n- `model`参数为一个对象，对象属性为需要验证的变量名。\n- 通过`ref`，在`onMounted`生命周期调用组件的`setRules`方法绑定验证规则，无法通过`props`传递变量，是因为微信小程序会过滤掉对象中的方法，导致自定义验证规则无效。\n\n```vue\n<template>\n\t<view>\n\t\t<u-form :model=\"form\" ref=\"uFormRef\">\n\t\t\t<u-form-item label=\"姓名\" prop=\"name\">\n\t\t\t\t<u-input v-model=\"form.name\" />\n\t\t\t</u-form-item>\n\t\t\t<u-form-item label=\"简介\" prop=\"intro\">\n\t\t\t\t<u-input v-model=\"form.intro\" />\n\t\t\t</u-form-item>\n\t\t</u-form>\n\t\t<u-button @click=\"submit\">提交</u-button>\n\t</view>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, reactive, onMounted } from 'vue';\n\nconst uFormRef = ref();\nconst form = reactive({\n\tname: '',\n\tintro: ''\n});\nconst rules = {\n\tname: [\n\t\t{\n\t\t\trequired: true,\n\t\t\tmessage: '请输入姓名',\n\t\t\t// 可以单个或者同时写两个触发验证方式 \n\t\t\ttrigger: ['change', 'blur']\n\t\t}\n\t],\n\tintro: [\n\t\t{\n\t\t\tmin: 5,\n\t\t\tmessage: '简介不能少于5个字',\n\t\t\ttrigger: 'change'\n\t\t}\n\t]\n};\n\nfunction submit() {\n\tuFormRef.value?.validate((valid: boolean) => {\n\t\tif (valid) {\n\t\t\tconsole.log('验证通过');\n\t\t} else {\n\t\t\tconsole.log('验证失败');\n\t\t}\n\t});\n}\n\nonMounted(() => {\n\tuFormRef.value?.setRules(rules);\n});\n</script>\n```\n\n#### u-form-item绑定`label`和`prop`\n\n此组件最大的作用是与`u-form`和`u-input`等组件进行交互，在表单验证时，需要绑定`prop`参数，此参数为`u-form`组件的`model`对象中的属性名，\n目的是在验证时，通过这个`prop`属性名将父组件`u-form`的`model`和`rules`规则关联起来。\n\n注意点：\n\n- 通过`prop`绑定对应的属性名，这里是字符串，而不是一个变量。\n- 通过`label`参数设置左边显示的提示文字，另外通过`label-position`可以配置`label`在左边还是上方。\n\n```vue\n<template>\n\t<u-form :model=\"form\" ref=\"uFormRef\">\n\t\t<u-form-item label=\"姓名\" prop=\"name\">\n\t\t\t<u-input v-model=\"form.name\" />\n\t\t</u-form-item>\n\t\t<u-form-item label=\"简介\" prop=\"intro\">\n\t\t\t<u-input v-model=\"form.intro\" />\n\t\t</u-form-item>\n\t</u-form>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, reactive, onMounted } from 'vue';\n\nconst uFormRef = ref();\nconst form = reactive({\n\tname: '',\n\tintro: ''\n});\nconst rules = {\n\tname: [\n\t\t{\n\t\t\trequired: true,\n\t\t\tmessage: '请输入姓名',\n\t\t\t// 可以单个或者同时写两个触发验证方式\n\t\t\ttrigger: ['blur', 'change']\n\t\t}\n\t],\n\tintro: [\n\t\t{\n\t\t\tmin: 5,\n\t\t\tmessage: '简介不能少于5个字',\n\t\t\ttrigger: 'change'\n\t\t}\n\t]\n};\n\nonMounted(() => {\n\tuFormRef.value?.setRules(rules);\n});\n</script>\n```\n\n从上面的示例我们可以看到，`rules`中的属性名和`form`的属性名是一致的，同时传递给`u-form-item`的`prop`参数绑定的也是相同的属性名，注意这里`prop`参数绑定的是\n字符串(属性名)，而不是一个变量。\n\n#### 验证规则\n\n组件验证部分采用了[async-validator](https://github.com/yiminghe/async-validator)，一个字段可以设置多个内置规则，以及自定义规则，触发方式等，\n每个字段的验证规则为一个数组，数组的每一个元素对象为其中一条规则(一个字段的验证可以配置多个规则)，如下：\n\n```ts\nconst rules = {\n\tname: [\n\t\t// 对name字段进行长度验证\n\t\t{\n\t\t\tmin: 5,\n\t\t\tmessage: '简介不能少于5个字',\n\t\t\ttrigger: 'change'\n\t\t},\n\t\t// 对name字段进行必填验证\n\t\t{\n\t\t\trequired: true,\n\t\t\tmessage: '请填写姓名',\n\t\t\ttrigger: ['change', 'blur']\n\t\t}\n\t]\n};\n```\n\n#### 验证规则属性\n\n每一个验证规则中，可以配置多个属性，下面对常用的属性进行讲解，更具体的可以查看[async-validator](https://github.com/yiminghe/async-validator)的文档说明：\n\n- `trigger`{String | Array}：触发校验的方式有2种：\n\t- change：字段值发生变化时校验\n\t- blur：输入框失去焦点时触发\n\t- 如果同时监听两种方式，需要写成数组形式：`['change', 'blur']`\n\n- `type`{String}  \n内置校验规则，如这些规则无法满足需求，可以使用正则匹配、或者使用`validator`自定义方法并结合uView自带[验证规则](/js/test.html)。  \n\t- string：必须是 `string` 类型，默认类型  \n\t- number：必须是 `number` 类型  \n\t- boolean：必须是 `boolean` 类型  \n\t- method：必须是 `function` 类型  \n\t- regexp：必须是 `regexp` 类型，这里的正则，指的是判断字段的内容是否一个正则表达式，而不是用这个正则去匹配字段值 \n\t- integer：必须是`整数`类型  \n\t- float：必须是`浮点数`类型  \n\t- array：必须是 `array` 类型  \n\t- object：必须是 `object` 类型  \n\t- enum：必须出现在 `enmu` 指定的值中  \n\t- date：必须是 `date` 类型  \n\t- url：必须是 `url` 类型  \n\t- hex：必须是 `16` 进制类型  \n\t- email：必须是 `email` 类型  \n\t- any：任意类型\n\t\n- `required`  \n布尔值，是否必填，配置此参数不会显示输入框左边的必填星号，如需要，请配置`u-form-item`的`required`为`true`\n\n- `pattern`  \n要求此参数值为一个正则表达式，如： /\\d+/，**不能**带引号，如：\"/\\d+/\"，组件会对字段进行正则判断，返回结果。\n\n- `min`  \n最小值，如果字段类型为字符串和数组，会取字符串长度与数组长度(length)与`min`比较，如果字段是数值，则直接与`min`比较。\n\n- `max`  \n最大值，规则同`min`参数\n\n- `len`  \n指定长度，规则同`min`，优先级高于`min`和`max`  \n\n- `enum`{Array}\n指定的值，配合 type: 'enum' 使用\n\n- `whitespace`{Boolean}  \n如果字段值内容都为空格，默认无法通过`required: true`校验，如果要允许通过，需要将此参数设置为`true`\n\n- `transform`{Function}，校验前对值进行转换，函数的参数为当前值，返回值为改变后的值，参数如如下：\n\t- `value`：当前校验字段的值\n\n- `message`  \n校验不通过时的提示信息  \n\n- `validator`{Function}：自定义**同步**校验函数，参数如下：\n\t- `rule`：当前校验字段在 rules 中所对应的校验规则\n\t- `value`：当前校验字段的值\n\t- `callback`：校验完成时的回调，一般无需执行callback，返回`true`(校验通过)或者`false`(校验失败)即可\n\n- `asyncValidator`{Function}：自定义**异步**校验函数，参数如下：\n\t- `rule`：当前校验字段在 rules 中所对应的校验规则\n\t- `value`：当前校验字段的值\n\t- `callback`：校验完成时的回调，执行完异步操作(比如向后端请求数据验证)，如果不通过，需要callback(new Error('提示错误信息'))，如果校验通过，执行callback()即可\n\n#### uView Pro自带验证规则\n\nuView在JS板块的[Test 规则校验](/js/test.html)中有大量内置的验证规则，这些规则对表单验证来说，属于**自定义规则**，故需要用到上方规则属性的\n`validator`自定义验证函数，这里做一个详细说明。  \n\n我们知道uView有自带的判断手机号的验证方法`uni.$u.test.mobile(value)`，但是[async-validator](https://github.com/yiminghe/async-validator)没有\n内置判断手机号的规则，所以将二者结合使用：\n\n```ts\nconst rules = {\n\t// 字段名称\n\tmobile: [\n\t\t{\n\t\t\trequired: true,\n\t\t\tmessage: '请输入手机号',\n\t\t\ttrigger: ['change', 'blur']\n\t\t},\n\t\t{\n\t\t\t// 自定义验证函数，见上说明\n\t\t\tvalidator: (rule: any, value: string, callback: Function) => {\n\t\t\t\t// uni.$u.test.mobile()就是返回true或者false的\n\t\t\t\treturn uni.$u.test.mobile(value);\n\t\t\t},\n\t\t\tmessage: '手机号码不正确',\n\t\t\ttrigger: ['change', 'blur']\n\t\t}\n\t]\n};\n```\n\n#### 综合实战\n\n上面讲述了[async-validator](https://github.com/yiminghe/async-validator)的规则和配置，以及uView内置规则的结合使用，下面我们进行一个综合\n实战示例，要入对某一个字段进行如下验证(验证实现有多种方法，下方仅为引导示例，非唯一，或最优做法)：\n\n1. 必填，同时可接受`change`和`blur`触发校验：配置`required`参数为`true`，同时配置`trigger`为`[change, bulr]`\n2. 必须为字母或字符串，校验前先将字段值转为字符串类型：通过`pattern`参数配置正则：/^[0-9a-zA-Z]*$/g，通过`transform`参数在校验前对字段值转换为字符串\n3. 长度6-8个字符之间：通过 配置`min`为6，`max`为8\n4. 需要包含字母\"A\"：使用uView的`uni.$u.test.contains()`方法，并结合`validator`自定义函数实现\n5. 异步校验，输入完账号，输入框失去焦点时，向后端请求该账号是否已存在：通过上方的`asyncValidator`异步函数进行验证。\n\n综上，我们可以得出如下的一个配置规则(仅为综合演示，非最优做法)：\n\n```ts\nconst rules = {\n\tname: [\n\t\t// 必填规则\n\t\t{\n\t\t\trequired: true,\n\t\t\tmessage: '此为必填字段',\n\t\t\t// blur和change事件触发检验\n\t\t\ttrigger: ['blur', 'change']\n\t\t},\n\t\t// 正则判断为字母或数字\n\t\t{\n\t\t\tpattern: /^[0-9a-zA-Z]*$/g,\n\t\t\t// 正则检验前先将值转为字符串\n\t\t\ttransform(value: any) {\n\t\t\t\treturn String(value);\n\t\t\t},\n\t\t\tmessage: '只能包含字母或数字'\n\t\t},\n\t\t// 6-8个字符之间的判断\n\t\t{\n\t\t\tmin: 6,\n\t\t\tmax: 8,\n\t\t\tmessage: '长度在6-8个字符之间'\n\t\t},\n\t\t// 自定义规则判断是否包含字母\"A\"\n\t\t{\n\t\t\tvalidator: (rule: any, value: string, callback: Function) => {\n\t\t\t\treturn uni.$u.test.contains(value, \"A\");\n\t\t\t},\n\t\t\tmessage: '必须包含字母\"A\"'\n\t\t},\n\t\t// 校验用户是否已存在\n\t\t{\n\t\t\tasyncValidator: (rule: any, value: string, callback: Function) => {\n\t\t\t\tuni.$u.post('/xxx/xxx', { name: value }).then((res: any) => {\n\t\t\t\t\t// 如果验证不通过，需要在callback()抛出new Error('错误提示信息')\n\t\t\t\t\tif (res.error) {\n\t\t\t\t\t\tcallback(new Error('姓名重复'));\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// 如果校验通过，也要执行callback()回调\n\t\t\t\t\t\tcallback();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\t// 如果是异步校验，无需写message属性，错误的信息通过Error抛出即可\n\t\t\t// message: 'xxx'\n\t\t}\n\t]\n};\n```\n\n#### 校验错误提示方式\n\nuView提供了多种校验的错误提示方式，这些值需要包含在数组(可以填写多个值，同时进行多种提示)中，传递给`Form`组件的`error-type`参数：\n- `message`：默认为输入框下方用文字进行提示\n- `none`：只要包含此值，将不会进行任何提示\n- `border-bottom`：配置作用域底部的下划线显示为红色\n- `border`：配置输入框的边框为红色进行提示 -- 如果有配置显示`Input`组件显示边框的话\n- `toast`：以\"toast\"提示的方式弹出错误信息，每次只弹出最前面的那个表单域的错误信息(1.3.5新增)\n\n```vue\n<template>\n\t<u-form :error-type=\"errorType\">\n\t\t<!-- ... -->\n\t</u-form>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue';\n\nconst errorType = ref(['message']);\n// 不提示\n// const errorType = ref(['none']);\n// 文字和下划线提示\n// const errorType = ref(['message', 'border-bottom']);\n</script>\n```\n\n#### 校验\n\n进行了上方的配置和讲解后，进入到最后一步，执行验证：  \n需要通过`ref`调用`Form`组件的`validate`方法，该方法回调函数的参数为一个布尔值，`true`为校验通过，否则反之。\n\n```vue\n<template>\n\t<view>\n\t\t<u-form :model=\"form\" ref=\"uFormRef\">\n\t\t\t<u-form-item label=\"姓名\" prop=\"name\">\n\t\t\t\t<u-input v-model=\"form.name\" />\n\t\t\t</u-form-item>\n\t\t</u-form>\n\t\t<u-button @click=\"submit\">提交</u-button>\n\t</view>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, reactive, onMounted } from 'vue';\n\nconst uFormRef = ref();\nconst form = reactive({\n\tname: ''\n});\nconst rules = {\n\tname: [\n\t\t{\n\t\t\trequired: true,\n\t\t\tmessage: '请输入姓名',\n\t\t\ttrigger: ['blur', 'change']\n\t\t}\n\t]\n};\n\nfunction submit() {\n\tuFormRef.value?.validate((valid: boolean) => {\n\t\tif (valid) {\n\t\t\tconsole.log('验证通过');\n\t\t} else {\n\t\t\tconsole.log('验证失败');\n\t\t}\n\t});\n}\n\nonMounted(() => {\n\tuFormRef.value?.setRules(rules);\n});\n</script>\n```\n\n### API\n\n### Form Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| model | 表单数据对象  | Object\t | - | - |\n| rules | 通过`ref`设置，见上方说明 | Object | - | - |\n| error-type | 错误的提示方式，数组形式，见上方说明 | Array | ['message', 'toast'] | - |\n| border-bottom | 是否显示表单域的下划线边框 | Boolean | true | - |\n| label-position | 表单域提示文字的位置，`left`-左侧，`top`-上方 | String | left | top |\n| label-width | 提示文字的宽度，单位rpx | String \\| Number | 90 | 数值 / auto |\n| label-style | `lable`的样式，对象形式 | Object | - | - |\n| label-align | `lable`的对齐方式 | String | left |  center / right |\n\n### Form Methods\n\n此方法如要通过ref手动调用\n\n| 名称          | 说明            |    参数   |\n|-------------  |---------------- |  ---------------- |  \n| setRules | 调用此方法，设置校验规则  | Function(rules) |\n| resetFields | 对整个表单进行重置，将所有字段值重置为初始值并移除校验结果  | - |\n| validate | 对整个表单进行校验的方法  | Function(callback: Function(boolean)) |\n\n### Form-item Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| label | 左侧提示文字  | String\t | - | - |\n| prop | 表单域`model`对象的属性名，在使用 validate、resetFields 方法的情况下，该属性是必填的 | String | - | - |\n| border-bottom | 是否显示下边框，如不需要下边框，需同时将`u-form`的同名参数设置为`false` | Boolean | true | true / false |\n| label-position | 表单域提示文字的位置，`left`-左侧，`top`-上方，如设置，将覆盖`u-form`的同名参数 | String | - | left / top |\n| label-width | 提示文字的宽度，单位rpx，如设置，将覆盖`u-form`的同名参数| String \\| Number | - | - |\n| label-style | `lable`的样式，对象形式，如设置，将覆盖`u-form`的同名参数 | Object | - | - |\n| label-align | `lable`的对齐方式，如设置，将覆盖`u-form`的同名参数 | String | - |  - |\n| right-icon | 右侧自定义字体图标(限uView内置图标)或图片地址 | String |  - |\n| left-icon | 左侧自定义字体图标(限uView内置图标)或图片地址 | String |  - |\n| left-icon-style | 左侧图标的样式，对象形式 | Object | - | - |\n| right-icon-style | 右侧图标的样式，对象形式 | Object | - | - |\n| required | 是否显示左边的\"*\"号，这里仅起展示作用，如需校验必填，请通过`rules`配置必填规则 | Boolean | false | true |\n\n### Form-item Slot\n\n|名称|说明|\n|:-|:-|\n| - | Form Item 的内容 |\n| right | 右侧自定义内容，可以在此传入一个按钮，用于获取验证码等场景 |\n\n<style scoped>\nh3[id=props] + table thead tr th:nth-child(2){\n\twidth: 35%;\n}\n</style>\n"
  },
  {
    "path": "src/static/app/markdown/fullScreen.md",
    "content": "## fullScreen 压窗屏\n\n所谓压窗屏，是指遮罩能盖住原生导航栏和底部tabbar栏的弹窗，一般用于在APP端弹出升级应用弹框，或者其他需要增强型弹窗的场景。\n\n<demo-model url=\"/pages/componentsA/fullScreen/index\"></demo-model>\n\n\n\n由于uni-app的Bug，在最新版的HX2.8.6(包括之前的多个版本)，此功能(组件)无效，等到uni-app修复此Bug时，我们会撤销此通告。\n\n\n\n\n这里的做法是在本页面打开一个新页面，同时在`pages.json`中配置本页面的背景为百分百透明，这样即可达到压窗效果。  \n由于只有APP支持设置页面背景透明度，故只有APP支持本组件做法，非APP端不支持。\n\n\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   x   |     x      |      x       |     x      |     x      |    x     |\n\n### 基本使用\n\n本组件只是提供参考思路和注意事项，因为每个人在弹窗需要实现的逻辑和样式都是不一样的，请参考本文档思路，自行实行相关功能。\n\n首先，我们需要`pages.json`中声明一个页面用于弹窗：\n\n```js\n// pages.json\n\n\"pages\": [\n\t{\n\t\t\"path\": \"uview-pro/components/u-full-screen/u-full-screen\",\n\t\t\"style\": {\n\t\t\t\"navigationStyle\": \"custom\",  // 取消本页面的导航栏\n\t\t\t\"app-plus\": {\n\t\t\t\t\"animationType\": \"fade-in\", // 设置fade-in淡入动画，为最合理的动画类型\n\t\t\t\t\"background\": \"transparent\", // 背景透明\n\t\t\t\t\"backgroundColor\": \"rgba(0,0,0,0)\", // 背景透明\n\t\t\t\t\"popGesture\": \"none\" // 关闭IOS屏幕左边滑动关闭当前页面的功能\n\t\t\t}\n\t\t}\n\t}\n]\n```\n\n通过上面的配置，我们得到了一个页面：\n- 这个页面去掉了导航栏\n- 页面进入的时候，是采用淡入动画的形式\n- 并且此页面的背景是百分比透明度，这样可以看到底层页面的内容\n- 移除在iOS上左滑手势，避免本页被左滑关闭\n\n\n### 触发压窗屏\n\n我们在父页面(当前页面)通过路由方法，打开一个新页面(上面配置的压窗屏页面)，由于它是一个普通的页面，故可以通过常规方法传递参数。\n\n```js\nexport default {\n\tonLoad() {\n\t\t// 也可以在onShow生命周期打开，此为uView封装的请求方法\n\t\tuni.$u.route(\"/uview-pro/components/u-full-screen/u-full-screen?id=1\");\n\t}\n}\n```\n\n\n### 定义压窗屏内容\n\n当我们触发(打开)了压窗屏页面之后，将会有一个新的，背景透明的页面覆盖在本页面上，由于我们的终极目标就是要做一个弹窗，让其遮罩盖住\"父页面\"的导航栏和\nTabbar栏，所以这里我们可以使用uView的[Popup 弹出层](/components/popup.html)组件，并且将`popup`组件的`mode`参数设置`center`，即中部弹出的形式。\n\n下方示例为打开一个[Modal 模态框](/components/modal.html)组件的示例，此组件内部用的也是`popup`组件。\n\n```html\n<template>\n\t<u-modal v-model=\"show\" :show-cancel-button=\"true\" confirm-text=\"升级\"\n\t\ttitle=\"发现新版本\" @cancel=\"cancel\" @confirm=\"confirm\"\n\t>\n\t\t<view class=\"u-update-content\">\n\t\t\t<rich-text :nodes=\"content\"></rich-text>\n\t\t</view>\n\t</u-modal>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tshow: true,\n\t\t\t\t// 传递给uni-app\"rich-text\"组件的内容，可以使用\"<br>\"进行换行\n\t\t\t\tcontent: `\n\t\t\t\t\t1. 修复badge组件的size参数无效问题<br>\n\t\t\t\t\t2. 新增Modal模态框组件<br>\n\t\t\t\t\t3. 新增压窗屏组件，可以在APP上以弹窗的形式遮盖导航栏和底部tabbar<br>\n\t\t\t\t\t4. 修复键盘组件在微信小程序上遮罩无效的问题\n\t\t\t\t`,\n\t\t\t}\n\t\t},\n\t\tonReady() {\n\t\t\tthis.show = true;\n\t\t},\n\t\tmethods: {\n\t\t\tcancel() {\n\t\t\t\tthis.closeModal();\n\t\t\t},\n\t\t\tconfirm() {\n\t\t\t\tthis.closeModal();\n\t\t\t},\n\t\t\tcloseModal() {\n\t\t\t\tuni.navigateBack();\n\t\t\t}\n\t\t}\n\t}\n</script>\n\n<style scoped lang=\"scss\">\n\t.u-full-content {\n\t\tbackground-color: #00C777;\n\t}\n\t\n\t.u-update-content {\n\t\tfont-size: 26rpx;\n\t\tcolor: $u-content-color;\n\t\tline-height: 1.7;\n\t\tpadding: 30rpx;\n\t}\n</style>\n```\n\n上面有一个需要注意的点，我们打开\"压窗\"弹窗后，可能需要通过一些按钮来关闭弹窗，这里关闭弹窗的本质意义是关闭弹出的页面(压窗屏弹框)，所以用的是uni-app带的\n关闭页面的接口`uni.navigateBack()`，见上方示例。\n\n\n### 注意事项\n\n由于压窗屏其实也是一个普通的页面的，当我们关闭弹窗(顶层页面)，\"父页面\"(上一个页面)就会显示出来，意味着会进入`onShow`生命周期，如有相关特定逻辑需要\n处理，可关注此处。\n\n由于弹窗打开的实际是一个页面，而不是一个组件，所以我们无法通过`props`的形式传递参数，有如下方式可以行进两个页面之间的通信：\n\n- 父页面通过URL参数的形式将参数传递给弹窗\n- 当弹窗内进行某些操作之后，可以通过`uni.$emit`的方式发送事件，父页面中通过`uni.$on`的形式接收事件和参数，达到通信的效果\n- 通过Vuex的形式共享变量\n"
  },
  {
    "path": "src/static/app/markdown/gap.md",
    "content": "## Gap 间隔槽 <to-api/>\n\n<demo-model url=\"/pages/componentsC/gap/index\"></demo-model>\n\n\n该组件一般用于内容块之间的用一个灰色块隔开的场景，方便用户风格统一，减少工作量\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n直接引入即可使用\n- 通过`height`配置高度，单位rpx\n- 通过`bg-color`配置背景颜色\n\n```html\n<u-gap height=\"80\" bg-color=\"#bbb\"></u-gap>\n```\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| bg-color |  背景颜色 | String\t | transparent(背景透明) | - |\n| height | 间隔槽高度，单位rpx  | String \\| Number | 30 | - |\n| margin-top | 与前一个元素的距离，单位rpx | String \\| Number  | 0 | - |\n| margin-bottom | 与后一个元素的距离，单位rpx | String \\| Number  | 0 | - |\n"
  },
  {
    "path": "src/static/app/markdown/getRect.md",
    "content": "# getRect 节点布局信息\n\n<demo-model url=\"/pages/library/getRect/index\"></demo-model>\n\n\n此方法封装自uni的[nodesRef.boundingClientRect](https://uniapp.dcloud.io/api/ui/nodes-info?id=nodesrefboundingclientrect)，它极大简化了\n使用复杂度，内部使用`Promise`，可以让用户同步获取节点信息。\n\n\n### getRect(selector, instance, all)\n\n- `selector` <String\\> 此参数为元素节点，可以是`id`或者`class`，比如\"#user-name\"，\".box\"\n- `instance` <ComponentInternalInstance\\> 此参数为组件实例，通过 `getCurrentInstance()` 获得\n- `all` <Boolean\\> 是否返回全部节点信息，当页面有多个相同`selector`的元素时，`all`为`true`，会以数组形式返回所有节点的信息(结果为数组，数组元素为对象)，否则只返回第一个节点的信息(结果为一个对象)\n\n注意：该方法返回的结果，共有如下有用信息：\n\n```js\nres = {\n\tleft: 0,\n\tright: 414,\n\ttop: 323,\n\theight: 2597,\n\tbottom: 2920,\n\twidth: 414\n}\n```\n\n受限于`nodesRef.boundingClientRect`，其上结果中的`left`，`top`，`right`，`bottom`，是会随着页面滚动而变化的，因为这个查询的相对于屏幕窗口，而不是\n相对于页面根元素的，但`width`，`height`，是恒定不变的，所以一般情况我们推荐您想要获取节点宽高的时候采用这个方法。\n\n由于`onLoad`生命周期元素尚未创建完成，请勿在此生命周期使用此方法，如果是页面，应该在`onReady`生命周期，组件内应该在`mounted`生命周期调用。\n如果要查询的目标，是通过服务端获取数据后才渲染的，那么应该在获取数据后，通过`this.$nextTick`调用此方法。\n\n### 异步使用方法\n\n通过`then`调用即可\n\n```js\nconst instance = getCurrentInstance()\n\ngetElInfo() {\n\tuni.$u.getRect('.user-avatar', instance).then(res => {\n\t\tconsole.log(res);\n\t})\n}\n\n```\n\n\n### 同步使用方法\n\n该方法的使用场景为您下一步的操作需要获取元素的节点后才能进行的情况，可以通过`async/await`方式调用，注意，无论是生命周期还是`methods`中的方法，都可以在\n其前面添加`async`修饰符\n\n```js\nconst instance = getCurrentInstance()\n\nasync getElInfo() {\n\tlet rectInfo = await uni.$u.getRect('.user-avatar', instance);\n\tconsole.log(rectInfo);\n}\n```\n\n\n### 请求数据后再获取节点信息\n\n此场景为元素内容为后端获取数据填充的，节点填充数据前后，元素的大小尺寸是不一样的，所以需要在获取后再执行此方法，这里通过`this.$nextTick`调用，\n是因为它会等待数据赋值，元素创建完成后再执行，此时才是准确的尺寸，以下演示，为uView Pro自带的[http 请求](/zh/tools/http.html)方法调用\n\n```html\n<template>\n\t<view>\n\t\t<view class=\"user-name\">\n\t\t\t{{ userName }}\n\t\t</view>\n\t</view>\n</template>\n\n<script setup >\nimport { ref, onMounted, getCurrentInstance } from 'vue';\n\nconst userName = ref('');\nconst instance = getCurrentInstance();\n\nonMounted(() => {\n\tgetElInfo();\n});\n\nasync function getElInfo() {\n\ttry {\n\t\tconst res = await uni.$u.post('http://www.example.com/user/info');\n\t\tuserName.value = res.name;\n\t\tawait nextTick();\n\t\tconst rect = await uni.$u.getRect('.user-avatar', instance);\n\t\tconsole.log(rect);\n\t} catch (error) {\n\t\tconsole.error(error);\n\t}\n}\n</script>\n```\n\n### 获取全部节点信息\n\n设置第二个参数为`true`，此场景为页面有多个相同类名的元素，需要获取所有同类名节点信息时候使用，返回结果为一个数组\n\n```html\n<template>\n\t<view>\n\t\t<view class=\"item\">\n\t\t\tuView Pro\n\t\t</view>\n\t\t<view class=\"item\">\n\t\t\t<view>红豆生南国，春来发几枝</view>\n\t\t\t<view>愿君多采撷，此物最相思</view>\n\t\t</view>\n\t</view>\n</template>\n\n<script setup>\nimport { ref, onMounted, getCurrentInstance } from 'vue';\n\nconst instance = getCurrentInstance();\n\nonMounted(() => {\n\tgetElInfo();\n});\n\nasync function getElInfo() {\n\ttry {\n\t\tconst rect = await uni.$u.getRect('.item', instance, true);\n\t\tconsole.log(rect); // rect为一个数组(内有2个元素)，因为页面有2个.item节点\n\t} catch (error) {\n\t\tconsole.error(error);\n\t}\n}\n</script>\n```\n\n\n### 如何让让某个元素滚动到页面顶部\n\n这里说的顶部，指的是导航栏的下方，比如我们点击某个操作，页面自动滚动，指定元素位于导航栏下方时停止。  \n我们需要结合`onPageScroll`生命周期，获得实时的页面滚动条位置。\n\n\n```html\n<template>\n\t<view class=\"wrap\">\n\t\t<view class=\"item\">\n\t\t\tuView Pro\n\t\t</view>\n\t\t<view class=\"item\">\n\t\t\tuView Pro\n\t\t</view>\n\t\t<view class=\"item\">\n\t\t\tuView Pro\n\t\t</view>\n\t\t<view class=\"item\">\n\t\t\tuView Pro\n\t\t</view>\n\t\t<view class=\"item object-item\" @tap=\"scrollEl\">\n\t\t\t点我，我就会滚动到导航栏下方\n\t\t</view>\n\t</view>\n</template>\n\n<script setup>\nimport { ref, onMounted, getCurrentInstance } from 'vue';\nimport { onPageScroll } from '@dcloudio/uni-app';\n\nconst instance = getCurrentInstance();\n\nconst scrollTop = ref(0);\n\nonPageScroll((e: { scrollTop: number }) => {\n    scrollTop.value = e.scrollTop;\n});\n\nconst scrollEl = () => {\n  uni.$u.getRect('.object-item', instance).then(res => {\n    uni.pageScrollTo({\n      scrollTop: scrollTop.value + res.top,\n      duration: 0\n    });\n  });\n}\n</script>\n\n<style lang=\"scss\" scoped>\n\t.wrap {\n\t\theight: 200vh;\n\t}\n</style>\n```"
  },
  {
    "path": "src/static/app/markdown/grid.md",
    "content": "## Grid 宫格布局 <to-api/>\n\n<demo-model url=\"/pages/componentsC/grid/index\"></demo-model>\n\n\n宫格组件一般用于同时展示多个同类项目的场景，可以给宫格的项目设置徽标组件([badge](/components/badge.html))，或者图标等，也可以扩展为左右滑动的轮播形式。\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n- 该组件外层为`u-grid`组件包裹，通过`col`设置内部宫格的列数\n- 内部通过`ugrid-item`组件的`slot`设置宫格的内容\n- 如果不需要宫格的边框，可以设置`border`为`false`\n\n```html\n<template>\n\t<u-grid :col=\"3\">\n\t\t<u-grid-item>\n\t\t\t<u-icon name=\"photo\" :size=\"46\"></u-icon>\n\t\t\t<view class=\"grid-text\">图片</view>\n\t\t</u-grid-item>\n\t\t<u-grid-item>\n\t\t\t<u-icon name=\"lock\" :size=\"46\"></u-icon>\n\t\t\t<view class=\"grid-text\">锁头</view>\n\t\t</u-grid-item>\n\t\t<u-grid-item>\n\t\t\t<u-icon name=\"hourglass\" :size=\"46\"></u-icon>\n\t\t\t<view class=\"grid-text\">沙漏</view>\n\t\t</u-grid-item>\n\t</u-grid>\n</template>\n\n<style scoped lang=\"scss\">\n\t.grid-text {\n\t\tfont-size: 28rpx;\n\t\tmargin-top: 4rpx;\n\t\tcolor: $u-type-info;\n\t}\n</style>\n```\n\n### 给宫格设置右上角的角标和图标\n\n可以通过uView的`badge`(注意Badge在此需要设置相关定位属性，详见[Badge](/components/badge.html))或者`image`设置宫格有右上角的内容\n\n```html\n<template>\n\t<u-grid :col=\"3\">\n\t\t<u-grid-item>\n\t\t\t<u-badge count=\"9\" :offset=\"[20, 20]\"></u-badge>\n\t\t\t<u-icon name=\"photo\" :size=\"46\"></u-icon>\n\t\t\t<view class=\"grid-text\">图片</view>\n\t\t</u-grid-item>\n\t\t<u-grid-item>\n\t\t\t<image src=\"/static/image/icon/hot5.png\" class=\"badge-icon\"></image>\n\t\t\t<u-icon name=\"lock\" :size=\"46\"></u-icon>\n\t\t\t<view class=\"grid-text\">锁头</view>\n\t\t</u-grid-item>\n\t\t<u-grid-item>\n\t\t\t<u-icon name=\"hourglass\" :size=\"46\"></u-icon>\n\t\t\t<view class=\"grid-text\">沙漏</view>\n\t\t</u-grid-item>\n\t</u-grid>\n</template>\n\n<style scoped lang=\"scss\">\n\t.badge-icon {\n\t\tposition: absolute;\n\t\ttop: 14rpx;\n\t\tright: 40rpx;\n\t\twidth: 30rpx;\n\t\theight: 30rpx;\n\t}\n\t\n\t.grid-text {\n\t\tfont-size: 28rpx;\n\t\tmargin-top: 4rpx;\n\t\tcolor: $u-type-info;\n\t}\n</style>\n```\n\n### 实现宫格的左右滑动\n\n结合uni的swiper组件可以实现宫格的左右滑动，因为`swiper`特性的关系，请指定`swiper`的高度 ，否则`swiper`的高度不会被内容撑开，可以自定义`swiper`的指示器，达到更高的灵活度\n\n```html\n<template>\n\t<swiper class=\"swiper\" @change=\"change\">\n\t\t<swiper-item>\n\t\t\t<u-grid :col=\"3\" @click=\"click\" hover-class=\"hover-class\">\n\t\t\t\t<u-grid-item v-for=\"(item, index) in list\" :index=\"index\" :key=\"index\">\n\t\t\t\t\t<u-icon :name=\"item\" :size=\"46\"></u-icon>\n\t\t\t\t\t<text class=\"grid-text\">{{ '宫格' + (index + 1) }}</text>\n\t\t\t\t</u-grid-item>\n\t\t\t</u-grid>\n\t\t</swiper-item>\n\t\t<swiper-item>\n\t\t\t<u-grid :col=\"3\" @click=\"click\">\n\t\t\t\t<u-grid-item v-for=\"(item, index) in list\" :index=\"index + 9\" :key=\"index\">\n\t\t\t\t\t<u-icon :name=\"item\" :size=\"46\"></u-icon>\n\t\t\t\t\t<text class=\"grid-text\">{{ '宫格' + (index + 1) }}</text>\n\t\t\t\t</u-grid-item>\n\t\t\t</u-grid>\n\t\t</swiper-item>\n\t\t<swiper-item>\n\t\t\t<u-grid :col=\"3\" @click=\"click\">\n\t\t\t\t<u-grid-item v-for=\"(item, index) in list\" :index=\"index + 18\" :key=\"index\">\n\t\t\t\t\t<u-icon :name=\"item\" :size=\"46\"></u-icon>\n\t\t\t\t\t<text class=\"grid-text\">{{ '宫格' + (index + 1) }}</text>\n\t\t\t\t</u-grid-item>\n\t\t\t</u-grid>\n\t\t</swiper-item>\n\t</swiper>\n\t<view class=\"indicator-dots\" v-if=\"isSwiper\">\n\t\t<view class=\"indicator-dots-item\" :class=\"[current == 0 ? 'indicator-dots-active' : '']\">\n\t\t</view>\n\t\t<view class=\"indicator-dots-item\" :class=\"[current == 1 ? 'indicator-dots-active' : '']\">\n\t\t</view>\n\t\t<view class=\"indicator-dots-item\" :class=\"[current == 2 ? 'indicator-dots-active' : '']\">\n\t\t</view>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tcurrent: 0,\n\t\t\t\tlist: ['integral', 'kefu-ermai', 'coupon', 'gift', 'scan', 'pause-circle', 'wifi', 'email', 'list']\n\t\t\t};\n\t\t},\n\t\tmethods: {\n\t\t\tchange(e) {\n\t\t\t\tthis.current = e.detail.current;\n\t\t\t}\n\t\t}\n\t};\n</script>\n\n<style scoped lang=\"scss\">\n\t/* 下方这些scss变量为uView内置变量，详见开发  组件-指南-内置样式 */\n\n\t.grid-text {\n\t\tfont-size: 28rpx;\n\t\tmargin-top: 4rpx;\n\t\tcolor: $u-type-info;\n\t}\n\t\n\t.swiper {\n\t\theight: 480rpx;\n\t}\n\t\n\t.indicator-dots {\n\t\tmargin-top: 40rpx;\n\t\tdisplay: flex;\n\t\tjustify-content: center;\n\t\talign-items: center;\n\t}\n\t\n\t.indicator-dots-item {\n\t\tbackground-color: $u-tips-color;\n\t\theight: 6px;\n\t\twidth: 6px;\n\t\tborder-radius: 10px;\n\t\tmargin: 0 3px;\n\t}\n\t\n\t.indicator-dots-active {\n\t\tbackground-color: $u-type-primary;\n\t}\n</style>\n```\n\n### API\n\n### Grid Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| col | 宫格的列数  | String \\| Number | 3 | - |\n| border | 是否显示宫格的边框  | Boolean\t | true | false |\n| align | 宫格的对齐方式，用于控制只有一两个宫格时的对齐场景  | String | left | center / right |\n| hover-class | 样式类名，按下时有效，样式必须写在根目录的`App.vue`或通过其引入的全局样式中才有效，`none`为无效果，作用于头部标题区域  | String | u-hover-class | none / 其他 |\n\n### Grid-item Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| bg-color | 宫格的背景颜色  | String | #ffffff | - |\n| index | 点击宫格时，返回的值  | String \\| Number\t | - | - |\n| custom-style | 自定义样式，对象形式 | Object | {padding: '30rpx 0'} | - |\n\n### Grid Event\n\n注意：请在`<u-grid></u-grid>`上监听此事件\n\n|事件名|说明|回调参数|\n|:-|:-|:-|\n|click|点击宫格触发|index: `u-grid-item`通过`props`传递的`index`值|\n\n\n### Grid-item Event\n\n注意：请在`<u-grid-item></u-grid-item>`上监听此事件\n\n|事件名|说明|回调参数|\n|:-|:-|:-|\n|click|点击宫格触发|index: `u-grid-item`通过`props`传递的`index`值|\n\n\n<style scoped>\nh3[id=grid-props] + table thead tr th:nth-child(2){\n\twidth: 40%;\n}\n</style>"
  },
  {
    "path": "src/static/app/markdown/guid.md",
    "content": "# guid 全局唯一标识符\n\n<demo-model url=\"/pages/library/guid/index\"></demo-model>\n\n\n## 唯一标识符\n\n### guid(length = 32, firstU = true, radix = 62)\n\n该函数可以生产一个全局唯一、随机的guid，默认首字母为`u`，可以用于当做元素的id或者class名等需要唯一，随机字符串的地方，因为id或者class不能以数字开头。\n\n- `length` <Number | null\\> guid的长度，默认为`32`，如果取值`null`，则按`rfc4122标准`生成对应格式的随机数\n- `firstU` <Boolean\\> 首字母是否为\"u\"，如果首字母为数字情况下，不能用作元素的`id`或者`class`，默认为`true`\n- `radix` <Number\\> 生成的基数，默认为`62`，用于生成随机数字符串为\"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\"，\n如果取2，那么返回的结果就是前两位0和1(可以理解为二进制)的随机结果，如果为7，返回的字符串就是0-7(理解为八进制)之间，\n10为十进制，以此类推。\n\n**说明**：这个方法三个参数都有默认的值，所以您调用的时候，可以无需传递任何参数也是可以的，并且**建议您这样做**。\n\n```html\n<template>\n\t<view :id=\"$u.guid()\" :class=\"elClass\">\n\t\t\n\t</view>\n</template>\n\n<script setup>\nimport { ref, onMounted } from 'vue';\nimport { $u } from 'uview-pro';\n\nconst elClass = ref('');\n\nonMounted(() => {\n  elClass.value = $u.guid(20);\n});\n</script>\n```"
  },
  {
    "path": "src/static/app/markdown/http.md",
    "content": "<demo-model url=\"/pages/library/http/index\"></demo-model>\n\n# uni-app 轻量级 Http 请求库 <BadgeVersion text=\"0.0.19\" />\n\n支持 TypeScript、Vue3、组合式 API，插件化、全局配置、请求/响应拦截器、toast/loading 灵活控制，开箱即用，适合中小型项目。目前不适用于其他的请求形式，比如上传，下载等。\n\n## 平台兼容性\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |    √     |\n\nput/delete 在某些小程序平台的限制：\n- 1.delete 请求，不支持支付宝和头条小程序(HX2.6.15)\n- 2.put 请求，不支持支付宝小程序(HX2.6.15)\n\n## 特性亮点\n\n- 支持 get/post/put/delete 四种常用请求\n- 插件化注册，支持全局配置和拦截器\n- toast、loading 可全局/单次请求灵活配置\n- 拦截器支持 token 注入、统一错误处理、登录失效跳转等\n- TypeScript 类型友好，支持组合式 API\n- 可通过 `$u.http.get/post` 方式调用（需 import { $u } from 'uview-pro'）\n- 适配 H5、App、各主流小程序平台\n\n## 基本用法\n\n### 组合式 API\n\n```ts\nimport { http } from 'uview-pro'\n\n// GET\nhttp.get('/api/user', { id: 1 }).then(res => {\n  /* ... */\n})\n\n// POST\nhttp.post('/api/login', { username: 'xx', password: 'xx' }).then(res => {\n  /* ... */\n})\n\n// PUT/DELETE\nhttp.put('/api/user/1', { name: 'new' })\nhttp.delete('/api/user/1')\n```\n\n### await/async\n\n```ts\nconst res = await http.post('/api/login', { username: 'xx' })\n```\n\n### 自定义 header\n\n```ts\nhttp.get(\n  '/api/user',\n  {},\n  {\n    header: { Authorization: 'Bearer token' }\n  }\n)\n```\n\n## 全局与动态配置\n\n### 全局配置\n\n```ts\nimport { http } from 'uview-pro'\n\nhttp.setConfig({\n  baseUrl: 'https://api.example.com',\n  meta: {\n    toast: true, // 全局开启错误toast，默认为false关闭\n    loading: true, // 全局开启loading，默认为false关闭\n    originalData: true // 是否在拦截器中返回服务端的原始数据，默认为true返回的是原始数据\n  }\n})\n```\n\n### 单次请求动态配置\n\n```ts\nhttp.post(\n  '/api/login',\n  { username: 'xx' },\n  {\n    meta: { toast: true, loading: true }\n  }\n)\n```\n\n## 最佳实践-推荐\n\n### 1. 创建拦截器文件\n\n```ts\nimport type { RequestConfig, RequestInterceptor, RequestMeta, RequestOptions } from 'uview-pro'\nimport { useUserStore } from '@/store'\n\n// 全局请求配置\nexport const httpRequestConfig: RequestConfig = {\n  baseUrl,\n  header: {\n    'content-type': 'application/json'\n  },\n  meta: {\n    originalData: true,\n    toast: true,\n    loading: true\n  }\n}\n\n// 全局请求/响应拦截器\nexport const httpInterceptor: RequestInterceptor = {\n  request: (config: RequestOptions) => {\n    const meta: RequestMeta = config.meta || {}\n    if (meta.loading) {\n      // 显示loading\n    }\n    const userStore = useUserStore()\n    if (userStore.token) {\n      config.header.Authorization = `Bearer ${userStore.token}`\n    }\n    return config\n  },\n  response: (response: any) => {\n    const meta: RequestMeta = response.config?.meta || {}\n    if (meta.loading) {\n      // 隐藏loading\n    }\n\n    // 根据业务处理错误、例如登录失效等处理接口返回错误码\n    if (response.data.code !== 200) {\n      if (meta.toast) {\n        // 可以弹出错误toast\n      }\n      throw new Error('接口返回错误码，根据业务处理，可以弹出toast')\n    }\n    return response.data\n  }\n}\n```\n\n---\n\n### 2. 注册插件（main.ts）\n\n已经定义好全局请求配置和请求/响应拦截器，可以在main.ts 中注册：\n\n```ts\nimport { createSSRApp } from 'vue'\nimport uViewPro, { httpPlugin } from 'uview-pro'\nimport { httpInterceptor, httpRequestConfig } from 'http.interceptor'\n\nexport function createApp() {\n  const app = createSSRApp(App)\n\n  // 注册uView-pro\n  app.use(uViewPro)\n\n  // 注册http插件\n  app.use(httpPlugin, {\n    interceptor: httpInterceptor,\n    requestConfig: httpRequestConfig\n  })\n\n  return { app }\n}\n```\n\n---\n\n### 3. API 管理\n\n建议将所有接口统一封装到 `api/index.ts`，便于维护和类型推断：\n\n```ts\n// api/index.ts\nimport { http } from 'uview-pro'\n\nexport const login = data => http.post('/api/login', data)\nexport const getUser = id => http.get('/api/user', { id })\n```\n\n页面中直接调用：\n\n```ts\nimport { login, getUser } from '@/api'\n\nconst user = await getUser(1)\n```\n\n---\n\n### 4. $u 工具库用法\n\n> 需 import { $u } from 'uview-pro'\n>\n> $u.http.get/post/put/delete 参数与 http 保持一致\n\n```ts\nimport { $u } from 'uview-pro'\n\n$u.http.get('/api/user', { id: 1 }, { meta: { toast: true } })\n$u.http.post('/api/login', { username: 'xx' }, { meta: { loading: true } })\n\n// 或\nuni.$u.http.get('/api/user', { id: 1 }, { meta: { toast: true } })\n```\n\n## 进阶用法\n\n### 多实例/多拦截器\n\n```ts\nimport { Request } from 'uview-pro'\n\nconst customHttp = new Request()\ncustomHttp.setConfig({ baseUrl: 'https://other.api.com' })\ncustomHttp.interceptor.request = config => {\n  // ...自定义逻辑\n  return config\n}\nexport { customHttp }\n```\n\n### 扩展 meta 字段\n\n你可以在 meta 中扩展自定义参数，在拦截器中读取：\n\n```ts\nhttp.get('/api/user', {}, { meta: { toast: true, customFlag: true } })\n// 在拦截器中：config.meta?.customFlag\n```\n\n### 结合 hooks 封装\n\n```ts\n// hooks/useApi.ts\nimport { http } from 'uview-pro'\nexport function useApi() {\n  return {\n    login: data => http.post('/api/login', data),\n    getUser: id => http.get('/api/user', { id })\n  }\n}\n```\n\n## 类型提示与 TS 支持\n\n- 所有请求方法均有完整类型推断\n- 支持泛型：`http.get<MyResType>(url)`\n- 支持自定义 Request/Response 类型\n- 推荐在 api 层定义类型，页面调用自动推断\n\n## 常见问题 FAQ\n\n### 1. 如何全局配置 baseUrl、header、meta？\n\n> 使用 `http.setConfig({ ... })`，建议在 main.ts 或拦截器注册前调用。\n\n### 2. 如何单次请求自定义 toast/loading？\n\n> 通过 meta 字段：`http.post(url, data, { meta: { toast: true, loading: true } })`\n\n### 3. 如何自定义拦截器？\n\n> 参考 http.interceptor.ts，request/response 可灵活扩展。\n\n### 4. 如何在组合式 API 中优雅使用？\n\n> 直接 `import { http }`，无需 getCurrentInstance。\n\n### 5. 如何处理多环境/多 baseUrl？\n\n> 可通过 setConfig 动态切换，或 new Request() 多实例。\n\n### 6. 如何捕获和处理错误？\n\n> 建议统一在 response 拦截器处理，页面可用 try/catch 或 .catch。\n\n### 7. $u.http.get/post 与 http 有什么区别？\n\n> $u.http.get/post 适配 uview-pro 导出的 http，参数与 http 完全一致，底层同一实现。\n> 即以下方式是同等的：\n\n```js\nimport { $u, http } from 'uview-pro'\n\n// 方式一\nhttp.get('/api/user', { id: 1 }, { meta: { toast: true } })\n\n// 方式二\n$u.http.get('/api/user', { id: 1 }, { meta: { toast: true } })\n\n// 方式三\nuni.$u.http.get('/api/user', { id: 1 }, { meta: { toast: true } })\n```\n\n### 8. put/delete 在小程序平台有限制吗？\n\n> put/delete 在支付宝、头条等部分平台有限制，详见最上方提示。\n\n---\n"
  },
  {
    "path": "src/static/app/markdown/icon.md",
    "content": "## Icon 图标 <to-api/>\n\n<demo-model url=\"/pages/componentsA/icon/index\"></demo-model>\n\n基于字体的图标集，包含了大多数常见场景的图标。\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ 小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :-------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |     √     |\n\n### 基本使用\n\n<br>\n\n\n如果您觉得内置的图标数量不够，或者不合符您的需求，别担心，我们还精心为您准备了一份简单易用的扩展自定义图标库教程：[扩展自定义图标库](https://www.uviewui.com/guide/customIcon.html)\n\n\n<br>\n\n通过`<u-icon>`形式来调用，设置`name`参数为图标名即可\n\n```html\n<u-icon name=\"photo\"></u-icon>\n```\n\n### 修改图标的样式\n\n- 通过`color`参数修改图标的颜色\n- 通过`size`参数修改图标的大小，单位为 rpx\n\n```html\n<u-icon name=\"photo\" color=\"#2979ff\" size=\"28\"></u-icon>\n```\n\n### 图片图标\n\n这里说的图片图标，指的是小图标，起作用定位为\"icon\"图标作用，而非大尺寸的图片展示场景，理论上，这个小图标应该为`png`格式的正方形图标。\n\n上面说到，给组件的`name`参数传入一个图片的名称即可显示字体图标，这些名称中不能带有`/`斜杠符号，否则会被认为是传入了图片图标，同时，`size`参数\n也被设置为这个图片图标的宽度，由于是图片，诸如颜色`color`等参数都会失效。\n\n```html\n<u-icon\n  label=\"uView\"\n  size=\"40\"\n  name=\"https://cdn.uviewui.com/uview/example/button.png\"\n></u-icon>\n```\n\n### API\n\n### Props\n\n| 参数                         | 说明                                                                                                                         | 类型             | 默认值  | 可选值              |\n| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ---------------- | ------- | ------------------- |\n| name                         | 图标名称，见示例图标集，如名称带有`/`，会被认为是图片图标                                                                    | String           | -       | -                   |\n| color                        | 图标颜色                                                                                                                     | String           | inherit | -                   |\n| size                         | 图标字体大小，单位 rpx                                                                                                       | String \\| Number | inherit | -                   |\n| index                        | 一个用于区分多个图标的值，点击图标时通过`click`事件传出                                                                      | String           | -       | -                   |\n| hover-class                  | 图标按下去的样式类，用法同 uni 的`view`组件的`hover-class`参数，详见：[hover-class](https://uniapp.dcloud.io/component/view) | String           | -       | -                   |\n| label                        | 图标右侧/下方的 label 文字                                                                                                   | String           | -       | -                   |\n| label-size                   | `label`字体大小，单位 rpx                                                                                                    | String \\| Number | 28      | -                   |\n| label-color                  | `label`字体颜色                                                                                                              | String           | #606266 | -                   |\n| custom-prefix                | 自定义字体图标库时，需要写上此值，详见：[扩展自定义图标库](https://www.uviewui.com/guide/customIcon.html)                    | String           | uicon   | -                   |\n| space <Badge text=\"0.0.4\" /> | `label`在四周时与图标的距离，权重高于 margin，单位 rpx                                                                       | String \\| Number | -       | -                   |\n| margin-left                  | `label`在右方时与图标的距离，单位 rpx                                                                                        | String \\| Number | 6       | -                   |\n| margin-top                   | `label`在下方时与图标的距离，单位 rpx                                                                                        | String \\| Number | 6       | -                   |\n| margin-bottom                | `label`在上方时与图标的距离，单位 rpx                                                                                        | String \\| Number | 6       | -                   |\n| margin-right                 | `label`在左侧时与图标的距离，单位 rpx                                                                                        | String \\| Number | 6       | -                   |\n| label-pos                    | `label`相对于图标的位置(left 和 top 为 1.4.1 新增)                                                                           | String           | right   | bottom / top / left |\n| custom-style                 | 图标的样式，可以设置字体大小，颜色等，对象形式，`size`和`color`优先级高于此参数                                              | Object           | -       | -                   |\n| width                        | `name`为图片路径时图片的宽度，单位任意，数值默认为 rpx 单位                                                                  | String \\| Number | -       | -                   |\n| height                       | `name`为图片路径时图片的高度，单位任意，数值默认为 rpx 单位                                                                  | String \\| Number | -       | -                   |\n| top                          | 如果某些场景，如果图标没有垂直居中，可以调整此参数，单位任意，数值默认为 rpx 单位                                            | String \\| Number | 0       | -                   |\n| show-decimal-icon            | 是否为 DecimalIcon                                                                                                           | Boolean          | false   | true                |\n| inactive-color               | 背景颜色，可接受主题色，仅 Decimal 时有效                                                                                    | String           | #ececec | -                   |\n| percent                      | 显示的百分比，仅 Decimal 时有效                                                                                              | String \\| Number | 50      | -                   |\n\n### Events\n\n| 事件名 | 说明           | 回调参数                          | 版本 |\n| :----- | :------------- | :-------------------------------- | :--- |\n| click  | 点击图标时触发 | index: 通过`props`传递的`index`值 | -    |\n\n### 图标集\n\n<icon />\n"
  },
  {
    "path": "src/static/app/markdown/image.md",
    "content": "## Image 图片 <to-api/>\n\n<demo-model url=\"/pages/componentsB/image/index\"></demo-model>\n\n此组件为 uni-app 的`image`组件的加强版，在继承了原有功能外，还支持淡入动画、加载中、加载失败提示、圆角值和形状等。  \n**我们推荐您在任何使用图片场景的地方，都优先考虑使用这个小巧，精致而实用的组件。**\n\n### 平台差异说明\n\n| App | H5  | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ 小程序 |\n| :-: | :-: | :--------: | :----------: | :--------: | :--------: | :-------: |\n|  √  |  √  |     √      |      √       |     √      |     √      |     √     |\n\n### 基本使用\n\n配置图片的`width`宽和`height`高，以及`src`路径即可使用。\n\n```html\n<template>\n  <u-image width=\"100%\" height=\"300rpx\" :src=\"src\"></u-image>\n</template>\n\n<script>\n  export default {\n    data() {\n      return {\n        src: \"https://cdn.uviewui.com/uview/example/fade.jpg\",\n      };\n    },\n  };\n</script>\n```\n\n### 填充模式\n\n通过`mode`参数配置填充模式，此模式用法与 uni-app 的`image`组件的`mode`参数完全一致，详见：[Image](https://uniapp.dcloud.io/component/image)\n\n```html\n<u-image src=\"https://cdn.uviewui.com/uview/example/fade.jpg\" mode=\"widthFix\"></u-image>\n```\n\n### 图片形状\n\n- 通过`shape`参数设置图片的形状，`circle`为圆形，`square`为方形\n- 如果为方形时，还可以通过`border-radius`参数设置圆角值\n\n```html\n<u-image src=\"https://cdn.uviewui.com/uview/example/fade.jpg\" shape=\"circle\"></u-image>\n```\n\n### 懒加载\n\n注意：此功能只对微信小程序、App、百度小程序、字节跳动小程序有效，默认开启。\n\n```html\n<u-image src=\"https://cdn.uviewui.com/uview/example/fade.jpg\" :lazy-load=\"true\"></u-image>\n```\n\n### 加载中提示\n\n图片加载过程中，为加载中状态(默认显示一个小图标)，可以通过`loading`自定义插槽，结合 uView 的`u-loading`组件，实现加载的动画效果。\n\n```html\n<u-image src=\"https://cdn.uviewui.com/uview/example/fade.jpg\">\n  <template #loading>\n    <u-loading></u-loading>\n  </template>\n</u-image>\n```\n\n### 加载错误提示\n\n图片加载失败时，默认显示一个错误提示图标，可以通过`error`自定义插槽，实现个性化的提示方式。\n\n```html\n<u-image src=\"https://cdn.uviewui.com/uview/example/fade.jpg\">\n  <template #error>\n    <view style=\"font-size: 24rpx;\">加载失败</view>\n  </template>\n</u-image>\n```\n\n### 淡入动画\n\n组件自带了加载完成时的淡入动画效果：\n\n- 通过`fade`参数配置是否开启动画效果\n- 通过`duration`参数配置动画的过渡时间，单位 ms\n\n```html\n<u-image\n  src=\"https://cdn.uviewui.com/uview/example/fade.jpg\"\n  :fade=\"true\"\n  duration=\"450\"\n></u-image>\n```\n\n### 事件冒泡\n\n默认情况下，组件是允许内部向外事件冒泡的，因为很多情况下，我们都希望点击图片，同时图片所在的父元素的点击事件也能触发。  \n如果您想避免事件冒泡，那么您可以在组件外面嵌套一个`view`，同时给它加上`@tap.stop`即可。\n\n```html\n<!-- 点击图片将不会触发clickHandler -->\n<view @tap=\"clickHandler\">\n  <view @tap.stop>\n    <u-image src=\"https://cdn.uviewui.com/uview/example/fade.jpg\"></u-image>\n  </view>\n</view>\n```\n\n### API\n\n### Props\n\n**注意：** 此组件为 1.4.0 版本加入的，[如何查看版本？](/components/install.html)\n\n| 参数                            | 说明                                                          | 类型             | 默认值       | 可选值 |\n| ------------------------------- | ------------------------------------------------------------- | ---------------- | ------------ | ------ |\n| src                             | 图片地址，**强烈建议**使用绝对或者网络路径                    | String           | -            | -      |\n| mode                            | 裁剪模式，见上方说明                                          | String           | aspectFill   | -      |\n| width                           | 宽度，单位任意，如果为数值，则为 rpx 单位                     | String \\| Number | 100%         | -      |\n| height                          | 高度，单位任意，如果为数值，则为 rpx 单位                     | String \\| Number | auto         | -      |\n| shape                           | 图片形状，circle-圆形，square-方形                            | String           | square       | circle |\n| border-radius                   | 圆角值，单位任意，如果为数值，则为 rpx 单位                   | String \\| Number | 0            | -      |\n| lazy-load                       | 是否懒加载，仅微信小程序、App、百度小程序、字节跳动小程序有效 | Boolean          | true         | -      |\n| show-menu-by-longpress          | 是否开启长按图片显示识别小程序码菜单，仅微信小程序有效        | Boolean          | true         | -      |\n| loading-icon                    | 加载中的图标，或者小图片                                      | String           | photo        | -      |\n| error-icon                      | 加载失败的图标，或者小图片                                    | String           | error-circle | -      |\n| show-loading                    | 是否显示加载中的图标或者自定义的 slot                         | Boolean          | true         | false  |\n| show-error                      | 是否显示加载错误的图标或者自定义的 slot                       | Boolean          | true         | false  |\n| fade                            | 是否需要淡入效果                                              | Boolean          | true         | false  |\n| webp                            | 只支持网络资源，只对微信小程序有效                            | Boolean          | false        | true   |\n| duration                        | 搭配`fade`参数的过渡时间，单位 ms                             | String \\| Number | 500          | -      |\n| bg-color | 背景颜色                                                      | String           | #f3f4f6      | -      |\n\n### Slot\n\n| 名称    | 说明                   |\n| :------ | :--------------------- |\n| loading | 自定义加载中的提示内容 |\n| error   | 自定义失败的提示内容   |\n\n### CellItem Events\n\n| 事件名 | 说明               | 回调参数      |\n| :----- | :----------------- | :------------ |\n| click  | 点击图片时触发     | -             |\n| error  | 图片加载失败时触发 | err: 错误信息 |\n| load   | 图片加载成功时触发 | -             |\n\n<style scoped>\nh3[id=slot] + table thead tr th:nth-child(2){\n\twidth: 50%;\n}\n</style>\n"
  },
  {
    "path": "src/static/app/markdown/indexList.md",
    "content": "## IndexList 索引列表 <to-api/>\n\n<demo-model url=\"/pages/componentsA/indexList/index\"></demo-model>\n\n\n通过折叠面板收纳内容区域\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n外层包裹一个`index-list`组件，内部锚点通过`index-anchor`组件传入，其余内容可以自定义\n- 可以通过`index-list`参数自定义索引字符列表\n- 需要监听页面的onPageScroll事件，将当前滚动条高度传入`index-list`组件\n\n```html\n<template>\n\t<u-index-list :scrollTop=\"scrollTop\">\n\t\t<view v-for=\"(item, index) in indexList\" :key=\"index\">\n\t\t\t<u-index-anchor :index=\"item\" />\n\t\t\t<view class=\"list-cell\">\n\t\t\t\t列表1\n\t\t\t</view>\n\t\t\t<view class=\"list-cell\">\n\t\t\t\t列表2\n\t\t\t</view>\n\t\t\t<view class=\"list-cell\">\n\t\t\t\t列表3\n\t\t\t</view>\n\t\t</view>\n\t</u-index-list>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tscrollTop: 0,\n\t\t\t\tindexList: [\"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"I\", \"J\", \"K\", \"L\", \"M\", \"N\", \"O\", \"P\", \"Q\", \"R\", \"S\", \"T\", \"U\",\n\t\t\t\t\t\"V\", \"W\", \"X\", \"Y\", \"Z\"\n\t\t\t\t]\n\t\t\t}\n\t\t},\n\t\tonPageScroll(e) {\n\t\t\tthis.scrollTop = e.scrollTop;\n\t\t}\n\t}\n</script>\n\n<style lang=\"scss\" scoped>\n\t.list-cell {\n\t\tdisplay: flex;\n\t\tbox-sizing: border-box;\n\t\twidth: 100%;\n\t\tpadding: 10px 24rpx;\n\t\toverflow: hidden;\n\t\tcolor: #323233;\n\t\tfont-size: 14px;\n\t\tline-height: 24px;\n\t\tbackground-color: #fff;\n\t}\n</style>\n```\n\n### 自定义锚点样式\n\n`index-anchor`锚点组件默认显示`index`参数的值，可以通过设置`use-slot`为`true`，传入自定义内容，同时设定\n自己的样式\n\n```html\n<template>\n\t<u-index-list :scrollTop=\"scrollTop\">\n\t\t<view v-for=\"(item, index) in indexList\" :key=\"index\">\n\t\t\t<u-index-anchor :use-slot=\"true\">\n\t\t\t\t<text class=\"anchor-text\">{{item}}</text>\n\t\t\t</u-index-anchor>\n\t\t\t<view class=\"list-cell\">\n\t\t\t\t列表1\n\t\t\t</view>\n\t\t\t<view class=\"list-cell\">\n\t\t\t\t列表2\n\t\t\t</view>\n\t\t\t<view class=\"list-cell\">\n\t\t\t\t列表3\n\t\t\t</view>\n\t\t</view>\n\t</u-index-list>\n</template>\n\n<style lang=\"scss\" scoped>\n\t.list-cell {\n\t\tdisplay: flex;\n\t\tbox-sizing: border-box;\n\t\twidth: 100%;\n\t\tpadding: 10px 24rpx;\n\t\toverflow: hidden;\n\t\tcolor: #323233;\n\t\tfont-size: 14px;\n\t\tline-height: 24px;\n\t\tbackground-color: #fff;\n\t}\n\t\n\t.anchor-text {\n\t\tcolor: red;\n\t}\n</style>\n```\n\n\n### 自定义导航栏\n\n默认情况下，组件的锚点是吸附在导航栏下方的，如果您修改了导航栏，比如取消导航栏、或者自定义了导航栏，就需要指定吸顶的高度，也就是`offset-top`\n的值，注意这个值的单位为`rpx`：\n\n- 如果取消导航栏，需要将`offset-top`为`0`\n- 如果自定义了导航栏，需要`offset-top`设置为导航栏的高度\n\n\n### API\n\n### IndexBar Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| scroll-top | 当前滚动高度，自定义组件无法获得滚动条事件，所以依赖接入方传入 | Number \\| String | - | - |\n| index-list | 索引字符列表，数组  | Array[string \\| number] | A-Z | - |\n| z-index | 锚点吸顶时的层级  | Number \\| String | 965 | - |\n| sticky | 是否开启锚点自动吸顶  | Boolean | true | false |\n| offset-top | 锚点自动吸顶时与顶部的距离，单位rpx，见上方\"自定义导航栏\"说明  | Number \\| String | 0 | - |\n| active-color | 锚点和右边索引字符高亮颜色  | String | #2979ff | - |\n\n### IndexAnchor Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| use-slot | 是否使用自定义内容的插槽  | Boolean | false | true |\n| index | 索引字符，如果定义了`use-slot`，此参数自动失效   | String \\| Number | - | - |\n| custom-style | 自定义样式，对象形式，如\"{color: 'red'}\"  | Object | - | - |\n\n\n### IndexBar Events\n\n|事件名|说明|回调参数|版本|\n|:-|:-|:-|:-|\n| select | 选中右边索引字符时触发 | index: 索引字符 | - |\n \n ### IndexAnchor Slots\n\n| 名称 | 说明 |\n|:-|:-|\n| default | 锚点位置显示内容，默认为索引字符 |"
  },
  {
    "path": "src/static/app/markdown/input.md",
    "content": "## Input 输入框 <to-api/>\n\n<!-- <demo-model url=\"/pages/componentsA/input/index\"></demo-model> -->\n\n此组件为一个输入框，默认没有边框和样式，是专门为配合表单组件[u-form](/components/form.html)而设计的，利用它可以快速实现表单验证，输入内容，下拉选择等功能。  \n\n**注意：** 当您仅是需要一个输入框的话，可以考虑使用[u-field](/components/field.html)组件，而如果是一个表单组，比如有多个输入框一起，且需要验证功能的时候，\n应该在`u-form`中嵌套`u-form-item`，再嵌套`u-input`去实现。\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n\n### 基本使用\n\n- 通过`v-model`绑定输入框的值\n- 通过`type`设置输入框的类型\n- 通过`border`配置是否显示输入框的边框\n\n```html\n<template>\n\t<u-input v-model=\"value\" :type=\"type\" :border=\"border\" />\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tvalue: '',\n\t\t\t\ttype: 'text',\n\t\t\t\tborder: true\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n\n### 输入框的类型\n\n综述：此组件通过配置`type`参数有两种形态：\n1. 一是长文本内容输入的`textarea`类型。 \n2. 二是类似普通输入框的`text`类型，在普通输入框时，由于HTML5或者小程序等一些特殊场景，此\t`type`参数又可以设置为`text`、`number`、`idcard`、`digit`等值，\n这些参数跟各个平台的兼容性有关，详见uni-app文档：[Input 组件](https://uniapp.dcloud.io/component/input)。\n\n\n#### Textarea模式\n\n此模式需要将`type`参数设置为`textarea`，有如下两个需要注意的参数：\n\n- `auto-height`参数可以配置为`textarea`输入框的高度是否随着行数增加，而自动增加输入框的高度。\n- `height`参数可以配置输入框的初始高度。\n\n```html\n<template>\n\t<u-input v-model=\"value\" :type=\"type\" :border=\"border\" :height=\"height\" :auto-height=\"autoHeight\" />\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tvalue: '',\n\t\t\t\ttype: 'textarea',\n\t\t\t\tborder: true,\n\t\t\t\theight: 100,\n\t\t\t\tautoHeight: true,\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n#### Text模式\n\n将`type`设置为`text`，此种情况为一个单纯的输入框，但是还可以将其设置为`number`、`idcard`、`digit`等值，需要考虑兼容性，见上方说明。\n\n```html\n<template>\n\t<u-input v-model=\"value\" :type=\"type\" :border=\"border\"  />\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tvalue: '',\n\t\t\t\ttype: 'text',\n\t\t\t\tborder: true,\n\t\t\t}\n\t\t},\n\t}\n</script>\n```\n\n\n#### Password模式\n\n`type`参数可以设置为`password`，此时输入内容将会用点替代：\n\n- 如果设置`password-icon`设置为`true`，右侧将会出现一个可以切换密码与普通字符的图标。\n\n```html\n<template>\n\t<u-input v-model=\"value\" :type=\"type\" :border=\"border\" :password-icon=\"passwordIcon\" />\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tvalue: '',\n\t\t\t\ttype: 'password',\n\t\t\t\tpasswordIcon: true,\n\t\t\t\tborder: true,\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n\n#### Select下拉选择模式\n\n如果将`type`设置为`select`，此时组件将会在外观上呈现出Select选择器的形态，主要体现在右侧多了一个下三角图标，但是此时组件并没有内置下拉的功能，\n主要是考虑到移动端的特殊性和uView内置组件的关联性，因为想实现下拉选择，不同场景可能会使用不同的组件，比如uView的[Picker 选择器](/components/picker.html)、\n[ActionSheet 操作菜单](/components/actionSheet.html)、[Select 列选择器](/components/select.html)等，您可以根据情况自由选择合适的组件做搭配。\n\n- 以上说的可以配合的组件，它们都有一个共同的通过`v-model`绑定弹出与收起的参数，可以同时将此参数赋值给`Input`组件的`select-open`参数，\n当此参数为`true`(也即`Select`选择器打开时)，右侧的下三角图标会翻转，为`false`时，恢复原位。\n- 监听组件的`@click`事件，在此将绑定选择器的参数修改为`true`即可。\n\n```html\n<template>\n\t<view class=\"\">\n\t\t<u-input v-model=\"value\" :type=\"type\" :border=\"border\" @click=\"show = true\" />\n\t\t<u-action-sheet :list=\"actionSheetList\" v-model=\"show\" @click=\"actionSheetCallback\"></u-action-sheet>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tvalue: '',\n\t\t\t\ttype: 'select',\n\t\t\t\tshow: false,\n\t\t\t\tborder: true,\n\t\t\t\tactionSheetList: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttext: '男'\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\ttext: '女'\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\ttext: '保密'\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\t// 点击actionSheet回调\n\t\t\tactionSheetCallback(index) {\n\t\t\t\tthis.value = this.actionSheetList[index].text;\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n\n### API\n\n### Props\n\n| 参数                                     | 说明            | 类型            | 默认值             |  可选值   |\n|----------------------------------------|---------------- |---------------|------------------ |-------- |\n| type                                   | 模式选择，见上方说明  | String\t | text | select / password / textarea / number |\n| clearable                              | 是否显示右侧的清除图标，type = select时无效 | Boolean | true | false |\n| v-model                                | 用于双向绑定输入框的值 | - | - | - |\n| input-align                            | 输入框文字的对齐方式  | String | left | center / right |\n| placeholder                            | placeholder显示值  | String | 请输入内容 | - |\n| disabled                               | 是否禁用输入框 | Boolean | false | true |\n| maxlength                              | 输入框的最大可输入长度 | Number \\| String | 140 | - |\n| placeholder-style                      | placeholder的样式，字符串形式，如\"color: red;\" | String | \"color: #c0c4cc;\" | - |\n| confirm-type                           | 设置键盘右下角按钮的文字，仅在`type`为`text`时生效  | String | done | - |\n| custom-style                           | 自定义输入框的样式，对象形式  | Object | - | - |\n| focus                                  | 是否自动获得焦点 | Boolean | false | true |\n| fixed                                  | 如果`type`为`textarea`，且在一个\"position:fixed\"的区域，需要指明为`true` | Boolean | false | true |\n| password-icon                          | `type`为`password`时，是否显示右侧的密码查看图标 | Boolean | true | false |\n| border                                 | 是否显示边框 | Boolean | false | true |\n| border-color                           | 输入框的边框颜色 | String | #dcdfe6 | - |\n| auto-height                            | 是否自动增高输入区域，`type`为`textarea`时有效 | Boolean | true | false |\n| height                                 | 高度，单位rpx | Number \\| String | text类型时为70，textarea时为100 | - |\n| cursor-spacing  | 指定光标与键盘的距离，单位**px** | Number \\| String | 0 | - |\n| selection-start | 光标起始位置，自动聚焦时有效，需与selection-end搭配使用 | Number \\| String | -1 | - |\n| selection-end   | 光标结束位置，自动聚焦时有效，需与selection-start搭配使用 | Number \\| String | -1 | - |\n| trim            | 是否自动去除两端的空格 | Boolean | true | false |\n| show-confirmbar | 是否显示键盘上方带有”完成“按钮那一栏 | Boolean | true | false |\n| adjust-position | 弹出键盘时是否自动调节高度 | Boolean | true | false |\n\n\n<style scoped>\nh3[id=props] + table thead tr th:nth-child(2){\n\twidth: 35%;\n}\n</style>\n"
  },
  {
    "path": "src/static/app/markdown/install.md",
    "content": "## 安装\n\n<demo-model url=\"/\"></demo-model>\n\n\n\n1. 由于 uView Pro 使用`easycom`模式，让您无需引入组件即可直接使用，但是此功能需要 Hbuilder X 2.5.5 及以上版本才支持，详见[配置 easycom 组件模式](/components/quickstart.html#_3-配置easycom组件模式)。\n   `easycom`打包的时候是**按需引入**的，您可以放心引入 uView Pro 的整个组件库，发布打包时会自动剔除您没有使用的组件(注意：调试时仍然是全部引入的)\n\n2. 请确保您下载的[Hbuilder X](https://www.dcloud.io/hbuilderx.html)为`APP开发版`，而非`标准版`，并且在\"工具-插件安装\"中安装了\"scss/sass 编译\"插件\n\n\n\n### 方式一：npm 安装\n\n使用 npm 的方式安装，能更方便进行升级。\n\n- 如果您的项目是通过[vue-cli](https://uniapp.dcloud.io/quickstart?id=_2-%e9%80%9a%e8%bf%87vue-cli%e5%91%bd%e4%bb%a4%e8%a1%8c)模式创建的，\n  无需手动 npm 安装`scss`，因为已内置`scss`。\n\n**注意：** 此安装方式必须要按照[npm 方式安装的配置](/components/npmSetting.html)中的说明配置了才可用，且项目名称不能有**中文**字符。\n\n```js\n// 如果您的项目是HX创建的，根目录又没有package.json文件的话，请先执行如下命令：\n// npm init -y\n\n// npm 安装\nnpm install uview-pro\n// yarn 安装\nyarn add uview-pro\n// pnpm 安装\npnpm add uview-pro\n```\n\n### 版本查询\n\n- 通过源码查看的形式\n\n可以查阅 uView Pro 的配置文件得知当前版本号，具体位置为 \"/uview-pro/package.json\" 中的 \"version\" 字段。\n\n### 方式二：下载安装\n\n使用下载的方式安装，能更方便阅读源码，但是每次升级都需要重新下载并覆盖 `uview-pro` 文件夹。\n\n- 在 uni-app 插件市场右上角选择 `下载并导入HBuilder X`，会直接导入到项目 `src` 目录的 `uni_modules` 目录中。\n- 如果您的项目是由 HBuilder X 创建的标准 uni-app 项目，将下载后的`uview-pro`文件夹，复制到项目`uni_modules`目录。\n- 如果您的项目是由[vue-cli](https://uniapp.dcloud.io/quickstart?id=_2-%e9%80%9a%e8%bf%87vue-cli%e5%91%bd%e4%bb%a4%e8%a1%8c)模式创建的，请将下载后的`uview-pro`文件夹放到项目的`src`的 `uni_modules`文件夹中即可。\n\n**注意：** 此安装方式必须要按照[下载方式安装的配置](/components/downloadSetting.html)中的说明配置了才可用。\n\n<br>\n<div @click=\"downloadPost(2)\" class=\"download-link\">\n\t<!-- 下载地址：<a href=\"https://download.uviewui.com/uView_1.3.6.zip\">uView_1.3.6.zip</a> -->\n\t下载地址：<a target=\"_blank\" href=\"https://ext.dcloud.net.cn/plugin?id=24633\">https://ext.dcloud.net.cn/plugin?id=24633</a>\n</div>\n<br>\n<br>\n\n### 示例项目\n\n此方式为整个 uView Pro 演示项目，里面有 uView Pro 核心，组件演示，模板等，建议用户可以下载\n此项目运行用于查看 UI 演示效果，复制模板案例，通过里面的示例，可以快速掌握某一个组件的用法。\n\n<!-- - 途径一：uView示例项目已内置到`HBuilder X`中，在`文件 -> 新建 -> 项目 -> uni-app`中，找到`uView Pro`下载运行即可。 -->\n\n<!-- - 途径二：在uni-app插件市场右上角选择`使用 HBuilderX 导入示例项目`或者`下载示例项目ZIP`，然后在HBuilder X中运行即可。 -->\n\n通过 github 或 gitee 下载 uView Pro 示例项目，在 VSCode 中运行即可。\n\n- github：[https://github.com/anyup/uview-pro](https://github.com/anyup/uview-pro)\n- gitee：[https://gitee.com/anyup/uview-pro](https://gitee.com/anyup/uview-pro)\n\n```bash\n\npnpm install\n\npnpm run dev:h5\n```\n\n<br>\n<div @click=\"downloadPost(3)\" class=\"download-link\">\n\t<!-- 下载地址：<a href=\"https://download.uviewui.com/uView_1.3.6_demo.zip\">uView_1.3.6_demo.zip</a> -->\n\tuni-app插件市场地址：<a target=\"_blank\" href=\"https://ext.dcloud.net.cn/plugin?id=24633\">https://ext.dcloud.net.cn/plugin?id=24633</a>\n</div>\n<br>\n<br>\n\n\n演示项目不适用于直接开发中，它只是演示用的，可以直接运行并查看效果。  \n如果在微信开发工具真机预览时，提示分包太大运行的问题，请在`HBuilder X`进行设置：菜单栏 运行 -> 运行到小程序模拟器，在下拉菜单中**勾选**\"运行时是否压缩代码\"\n\n\n<br>\n<br>\n\n<script>\nimport axios from \"axios\";\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\t\n\t\t}\n\t},\n\tmethods: {\n\t\tdownloadPost(type) {\n\t\t\tlet url = this.$themeConfig.baseUrl + '/index/index/download';\n\t\t\taxios.post(url, {\n\t\t\t    type: type,\n\t\t\t})\n\t\t\t.then(function (response) {\n\t\t\t    // console.log(response);\n\t\t\t})\n\t\t\t.catch(function (error) {\n\t\t\t   // console.log(error);\n\t\t\t});\n\t\t}\n\t}\n}\n</script>\n\n<style scoped>\n.download-link {\n\tfont-size: 14px;\n\tcolor: #5e6d82;\n}\n</style>\n"
  },
  {
    "path": "src/static/app/markdown/intro copy.md",
    "content": "# 介绍\n\n<demo-model url=\"/pages/example/js\"></demo-model>\n\n\n此函数方法，为 `uView Pro` 框架提供的一部分功能，它的实现，需要通过 `function` 调用，而不是组件的形式。 \n工具库中的所有方法，均挂载在`$u`对象下，调用方法如下：\n- 如果是在 `script` 中，需要通过`uni.$u.xxx`形式调用，如调用去除空格的`trim`方法：\n\n```js\nconsole.log(uni.$u.trim(' abc '));\t// 去除两端空格\n```\n\n或导入 `$u` 工具函数库，调用方法如下：\n\n```js\nimport { $u } from 'uview-pro'\n\nconsole.log($u.trim(' abc '));\t// 去除两端空格\n```\n\n<br>\n\n- 如果是在元素中，也需要导入，如：\n\n```html\n<template>\n\t<view>\n\t\t去除所有空格：{{$u.trim(str, 'all')}}\n\t</view>\n</template>\n\n<script setup lang=\"ts\">\n\timport { $u } from 'uview-pro'\n</script>\n```"
  },
  {
    "path": "src/static/app/markdown/intro.md",
    "content": "## 介绍\n\n<demo-model url=\"/\"></demo-model>\n\n<div class=\"intro-logo\">\n\t<img class=\"logo\" src=\"https://ik.imagekit.io/anyup/uview-pro/common/logo.png\" alt=\"uView\" />\n\t<h3>uView Pro</h3>\n\t<p class=\"slogan\">uni-app Vue3 多平台快速开发的UI框架</p>\n</div>\n\n#### 来由\n\nuni-app 在 2018 年初发布以来，一直蓬勃发展，一派欣欣向荣，社区也是人声鼎沸，众望所归。\n\n因此，uView 应运而生，uView 的目标是成为 uni-app 生态最优秀的 UI 框架。\n\n关于 uView 的取名来由，首字母`u`来自于 uni-app 首字母，uni-app 是基于 Vue.js，Vue 和 View(延伸为 UI、视图之意)同音，同时`view`组件 uni-app 中\n最基础，最重要的组件，故取名 uView，表达源于 uni-app 和 Vue 之意，同时在此也对它们表示感谢。\n\n关于 `uView-Pro`，它来源于 `uView 1.x` 和实际项目，由于之前使用 uniapp 开发的项目大多都是 uniapp + Vue2 + uView 1.x，想开始新项目使用 Vue3 时，却没有找到顺手的 UI 组件库，所以萌生了重构 `uView UI 1.x` 的想法，在 Vue3 的基础上重构了 `uView 1.8.8`，这才诞生了 `uView Pro`。\n\n`uView Pro` 的设计理念是：保持 `uView UI 1.x` 简洁的设计理念，使用 Vue3 的语法全面重构每一个组件，并保持现有 API，可以让你无缝切换！\n\n#### 适用领域\n\nuView 是 uni-app 生态专用的 UI 框架，uni-app 是一个使用 Vue 2 开发所有前端应用的框架，开发者编写一套代码，\n可发布到 iOS、Android、H5、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉)等多个平台(引言自 uni-app 网)。\n\n而 uView Pro，是 uni-app 全面兼容 Vue3 的 uni-app 生态框架，全面的组件和便捷的工具会让您信手拈来，如鱼得水。\n\n#### 版权信息\n\nuView Pro 遵循[MIT](https://baike.baidu.com/item/MIT/10772952)开源协议，意味着您无需支付任何费用，也无需授权，即可将 uView Pro 应用到您的产品中。\n\n注意：这并不意味着您可以将 uView Pro 应用到非法的领域，比如涉及赌博，暴力等方面。如因此产生纠纷等法律问题，uView Pro 不承担任何责任。\n\n### 捐赠 uView Pro 的研发\n\n<donation></donation>\n\n<style>\n.intro-logo {\n\ttext-align: center;\n}\n\n.intro-logo .logo {\n\twidth: 120px;\n\tmargin: auto;\n}\n\n.intro-logo h3 {\n\tfont-size: 30px;\n\tfont-weight: bold;\n\tmargin-top: 10px;\n\tmargin-bottom: 0;\n}\n\n.intro-logo .slogan {\n\tmargin-top: 10px!important;\n}\n</style>\n"
  },
  {
    "path": "src/static/app/markdown/keyboard.md",
    "content": "## Keyboard 键盘 <to-api/>\n\n<demo-model url=\"/pages/componentsA/keyboard/index\"></demo-model>\n\n\n此为uView自定义的键盘面板，内含了数字键盘，车牌号键，身份证号键盘3种模式，都有可以打乱按键顺序的选项。\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n\n通过`mode`参数定义键盘的类型，v-model绑定一个值为布尔值的变量控制键盘的弹出与收起：\n- mode = number (默认值)为数字键盘，此时顶部工具条中间的提示文字为\"数字键盘\"\n- mode = car 为汽车键盘，此时顶部工具条中间的提示文字为\"车牌号键盘\"\n- mode = card 为身份证键盘，此时顶部工具条中间的提示文字为\"身份证键盘\"\n\n```html\n<template>\n\t<view>\n\t\t<u-keyboard ref=\"uKeyboard\" mode=\"car\" v-model=\"show\"></u-keyboard>\n\t\t<u-button @click=\"show = true\">打开</u-button>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tshow: false\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 控制键盘顶部的工具条\n\n- 通过`tooltip`参数配置是否显示显示顶部的工具条，默认为`true`\n- 通过`tips`参数修改工具条中间的提示文字\n- 通过`show-tips`可以控制是否显示工具条中间的文字\n- 通过`cancelBtn`参数配置是否显示工具条左边的\"取消\"按钮\n- 通过`confirmBtn`参数配置是否显示工具条右边的\"完成\"按钮\n\n```html\n<u-keyboard mode=\"car\" tips=\"请输入车牌号\" :cancelBtn=\"false\"></u-keyboard>\n```\n\n### 是否显示键盘的点(\".\")按键\n\n该按键通过`dot-enabled`(默认为`true`)参数配置，只在\"mode = number\"时生效，因为车牌号和身份证键盘，用不到\".\"这个按键\n\n```html\n<u-keyboard ref=\"uKeyboard\" mode=\"number\" :dot-enabled=\"false\" v-model=\"show\"></u-keyboard>\n```\n\n### 是否打乱按键的顺序\n\n如果配置`random`参数为`true`的话，**每次**打开键盘，按键的顺序都是随机的，该功能默认是关闭的\n\n```html\n<u-keyboard ref=\"uKeyboard\" mode=\"number\" :random=\"true\" v-model=\"show\"></u-keyboard>\n```\n\n### 如何控制键盘的打开和关闭？\n\n通过v-model绑定一个值为布尔值的变量控制组件的弹出与收起，v-model的值是双向绑定的。\n\n```html\n<template>\n\t<u-keyboard mode=\"number\" v-model=\"show\"></u-keyboard>\n</template>\n\n<script>\n\texport default {\n\t\tonReady() {\n\t\t\t// 如果想一进入页面就打开键盘，请在此生命周期调用\n\t\t\tthis.show = true;\n\t\t},\n\t\tonLoad() {\n\t\t\t// 不应在此调用，因为此时u-keyboard组件尚未创建完成\n\t\t\t// this.show = true;\n\t\t}\n\t}\n</script>\n```\n\n### 如何监听键盘按键被点击？\n\n- 输入值是通过组件的`change`事件实现的，组件内部每个按键被点击的时候，组件就会发出一个`change`事件，回调参数为点击的按键的值。  \n- 通过`backspace`事件监听键盘退格键的点击，通过修改父组件的值实现退格的效果，见下方示例\n\n注意：点击退格键(也即删除键)不会触发`change`事件\n\n```html\n<template>\n\t<u-keyboard mode=\"number\" @change=\"valChange\" @backspace=\"backspace\" v-model=\"show\"></u-keyboard>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tvalue: '',\n\t\t\t\tshow: false\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\t// 按键被点击(点击退格键不会触发此事件)\n\t\t\tvalChange(val) {\n\t\t\t\t// 将每次按键的值拼接到value变量中，注意+=写法\n\t\t\t\tthis.value += val;\n\t\t\t\tconsole.log(this.value);\n\t\t\t},\n\t\t\t// 退格键被点击\n\t\t\tbackspace() {\n\t\t\t\t// 删除value的最后一个字符\n\t\t\t\tif(this.value.length) this.value = this.value.substr(0, this.value.length - 1);\n\t\t\t\tconsole.log(this.value);\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n\n### 是否显示遮罩\n\n当您使用键盘时，可能会不想显示遮罩，这时可以配置`mask`参数为`false`即可\n\n```html\n<u-keyboard mode=\"number\" v-model=\"show\" :mask=\"false\"></u-keyboard>\n```\n\n\n### API\n\n### Props\n\n注意：props中没有控制键盘弹出与收起的参数，因为这是通过v-model绑定变量实现的，见上方说明。\n\n| 参数      | 说明        | 类型     |  默认值  |  可选值   |\n|-----------|-----------|----------|----------|---------|\n| mode | 键盘类型，见上方`基本使用`的说明  | String | number | car / card |\n| dot-enabled | 是否显示\".\"按键，只在mode=number时有效 | Boolean  | true | false |\n| tooltip | 是否显示键盘顶部工具条 | Boolean  | true | false |\n| tips | 工具条中间的提示文字，见上方`基本使用`的说明 | String  | - | - |\n| show-tips | 是否显示工具条中间的文字 | Boolean  | true | false |\n| cancel-btn | 是否显示工具条左边的\"取消\"按钮 | Boolean  | true | false |\n| confirm-btn | 是否显示工具条右边的\"完成\"按钮 | Boolean  | true | false |\n| mask | 是否显示遮罩 | Boolean  | true | false |\n| z-index | 弹出键盘的`z-index`值 | Number \\| String  | 1075 | - |\n| random | 是否打乱键盘按键的顺序 | Boolean  | false | true |\n| safe-area-inset-bottom | 是否开启[底部安全区适配](/components/safeAreaInset.html#关于uview某些组件safe-area-inset参数的说明) | Boolean  | false | true |\n| mask-close-able | 是否允许点击遮罩收起键盘 | Boolean  | true | false |\n| confirm-text  | 确认按钮的文字 | String | 取消 | - |\n| cancel-text  | 取消按钮的文字 | String | 确认 | - |\n\n### Events\n\n|事件名|说明|回调参数|版本|\n|:-|:-|:-|:-|\n| change | 按键被点击(不包含退格键被点击) | 按键的值，见上方说明和示例 | - |\n| cancel | 键盘顶部工具条左边的\"取消\"按钮被点击 | - | - |\n| confirm | 键盘顶部工具条右边的\"完成\"按钮被点击 | - | - |\n| backspace | 键盘退格键被点击 | - | - |\n\n### Slot\n\n|名称|说明|版本|\n|:-|:-|:-|\n| default | 内容将会显示键盘的工具条上面，可以结合[MessageInput 验证码输入](/components/messageInput.html)组件实现类似支付宝输入密码时，上方显示输入内容的功能 |  - |\n\n\n<style scoped>\nh3[id=props] + table thead tr th:nth-child(2){\n\twidth: 40%;\n}\n\nh3[id=events] + table thead tr th:nth-child(2){\n\twidth: 40%;\n}\n\nh3[id=slot] + table thead tr th:nth-child(2){\n\twidth: 60%;\n}\n</style>"
  },
  {
    "path": "src/static/app/markdown/layout.md",
    "content": "## Layout 布局 <to-api/>\n\n<demo-model url=\"/pages/componentsC/layout/index\"></demo-model>\n\n\n通过基础的 12 分栏，迅速简便地创建布局  \n\n\n如需实现类似宫格的布局，请使用uView的[Grid宫格组件](/components/grid.html)，可以设置角标，功能更完善和灵活\n\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |    √     |\n\n### 基本使用\n\n通过`col`组件的`span`设置需要分栏的比例\n\n```html\n<template>\n\t<view class=\"wrap\">\n\t\t<u-row gutter=\"16\">\n\t\t\t<u-col span=\"3\">\n\t\t\t\t<view class=\"demo-layout bg-purple\"></view>\n\t\t\t</u-col>\n\t\t\t<u-col span=\"4\">\n\t\t\t\t<view class=\"demo-layout bg-purple-light\"></view>\n\t\t\t</u-col>\n\t\t\t<u-col span=\"5\">\n\t\t\t\t<view class=\"demo-layout bg-purple-dark\"></view>\n\t\t\t</u-col>\n\t\t</u-row>\n\t\t<u-row gutter=\"16\" justify=\"space-between\">\n\t\t\t<u-col span=\"3\">\n\t\t\t\t<view class=\"demo-layout bg-purple\"></view>\n\t\t\t</u-col>\n\t\t\t<u-col span=\"9\">\n\t\t\t\t<view class=\"demo-layout bg-purple-light\"></view>\n\t\t\t</u-col>\n\t\t</u-row>\n\t</view>\n</template>\n\n<style scoped lang=\"scss\">\n\t.wrap {\n\t\tpadding: 24rpx;\n\t}\n\n\t.u-row {\n\t\tmargin: 40rpx 0;\n\t}\n\n\t.demo-layout {\n\t\theight: 80rpx;\n\t\tborder-radius: 8rpx;\n\t}\n\n\t.bg-purple {\n\t\tbackground: #d3dce6;\n\t}\n\n\t.bg-purple-light {\n\t\tbackground: #e5e9f2;\n\t}\n\n\t.bg-purple-dark {\n\t\tbackground: #99a9bf;\n\t}\n</style>\n```\n\n### 分栏间隔\n\n通过设置`row`组件的`gutter`参数，来指定每一栏之间的间隔(最终表现为左边内边距各为gutter/2)，默认间隔为0\n\n```html\n<u-row gutter=\"16\">\n\t<u-col span=\"3\">\n\t\t<view class=\"demo-layout bg-purple\">\n\t\t</view>\n\t</u-col>\n\t<u-col span=\"9\">\n\t\t<view class=\"demo-layout bg-purple-light\">\n\t\t</view>\n\t</u-col>\n</u-row>\n```\n\n### 分栏偏移\n\n通过指定`col`组件的`offset`属性可以指定分栏偏移的栏数。\n\n```html\n<u-row gutter=\"16\">\n\t<u-col span=\"3\">\n\t\t<view class=\"demo-layout bg-purple\"></view>\n\t</u-col>\n\t<u-col span=\"3\" offset=\"6\">\n\t\t<view class=\"demo-layout bg-purple-light\"></view>\n\t</u-col>\n</u-row>\n```\n\n### 对齐方式\n\n通过`row`组件的`justify`来对分栏进行灵活的对齐，\n可选值为`start`(或`flex-start`)、`end`(或`flex-end`)、`center`、`around`(或`space-around`)、`between`(或`space-between`)，\n其最终的表现类似于css的`justify-content`属性。\n\n**注意**：由于持微信小程序编译后的特殊结构，此方式不支持微信小程序。\n\n```html\n<u-row gutter=\"16\" justify=\"center\">\n\t<u-col span=\"3\">\n\t\t<view class=\"demo-layout bg-purple\"></view>\n\t</u-col>\n\t<u-col span=\"3\">\n\t\t<view class=\"demo-layout bg-purple-light\"></view>\n\t</u-col>\n</u-row>\n```\n\n### API\n\n### Row Props\n\n| 参数    | 说明                                  | 类型             | 默认值              | 可选值                                                                       |\n| ------- | ------------------------------------- | ---------------- | ------------------- | ---------------------------------------------------------------------------- |\n| gutter  | 栅格间隔，左右各为此值的一半，单位rpx | String \\| Number | 0                   | -                                                                            |\n| justify | 水平排列方式(微信小程序暂不支持)      | String           | start(或flex-start) | end(或flex-end) / center / around(或space-around) / between(或space-between) |\n| align   | 垂直排列方式                          | String           | center              | top / bottom                                                                 |\n\n### Col Props\n\n| 参数       | 说明                               | 类型             | 默认值 | 可选值         |\n| ---------- | ---------------------------------- | ---------------- | ------ | -------------- |\n| span       | 栅格占据的列数，总12等分           | String \\| Number | 0      | 1-12           |\n| offset     | 分栏左边偏移，计算方式与`span`相同 | String \\| Number | 0      | -              |\n| text-align | 文字水平对齐方式                   | String           | left   | center / right |\n\n\n### Row Events\n\n| 事件名 | 说明        | 回调参数 |\n| :----- | :---------- | :------- |\n| click  | `row`被点击 | -        |\n\n\n### Col Events\n\n| 事件名 | 说明                               | 回调参数 |\n| :----- | :--------------------------------- | :------- |\n| click  | `col`被点击，会阻止事件冒泡到`row` | -        |"
  },
  {
    "path": "src/static/app/markdown/lazyLoad.md",
    "content": "## LazyLoad 懒加载 <to-api/>\n\n<demo-model url=\"/pages/componentsA/lazyload/index\"></demo-model>\n\n\n懒加载使用的场景为：页面有很多图片时，APP会同时加载所有的图片，导致页面卡顿，各个位置的图片出现前后不一致等   \n本组件高度封装和集成，创新性地使用`uni.createIntersectionObserver`\n接口，保证高性能的同时，还有其他友好的可配置参数，比如预加载占位图，加载错误占位图，加载位置参数(threshold)，各种事件等。\n\n<custom-block></custom-block>\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |    √     |\n\n### 基本使用\n\n通过`image`参数传入图片的`src`路径即可\n\n\n由于uni-app默认给了image组件的`height`为225px，同时也只有在uni-appimage组件的`mode`参数为`widthFix`时，image才会自动计算出一个高度值\n覆盖默认的`height`(225px)。其他`mode`参数下，如果设置`height`为`auto`，或者`100%`的话，图片将会无法显示。  \n\n所以：当您使用uView的`lazyload`组件时，如果设置`height`参数为`auto`，或者`100%`，而`img-mode`参数又不为`widthFix`的话，图片将会不显示，这不是uView的BUG。  \n\n结论：如果`img-mode`参数不为`widthFix`的话，必须设置`height`参数为一个固定的高度(单位rpx)，否则无效。\n\n\n\n```html\n<template>\n\t<view>\n\t\t<u-lazy-load v-for=\"(item, index) in list\" :key=\"index\" :image=\"item.src\"></u-lazy-load>\n\t</view>\n</template>\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\t// 设计成数组内嵌对象而不是纯数组形式，是考虑到真实环境后端返回的数据为如此形式\n\t\t\t\tlist: [{\n\t\t\t\t\t\tsrc: \"https://gtd.alicdn.com/sns_logo/i1/TB124_3NXXXXXasXVXXSutbFXXX.jpg_240x240xz.jpg\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tsrc: \"https://gtd.alicdn.com/sns_logo/i7/TB1IWtgQFXXXXcmXFXXSutbFXXX.jpg_240x240xz.jpg\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tsrc: \"https://gtd.alicdn.com/sns_logo/i1/TB1_f_PLXXXXXbVXpXXSutbFXXX.jpg_240x240xz.jpg\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t// 这里图片不存在，会加载失败，显示错误的占位图\n\t\t\t\t\t\tsrc: \"xxx\",\n\t\t\t\t\t},\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 配置占位图\n\n占位图有两种情况：\n- 一种是正常预加载时显示的，通过`loading-img`配置类似\"正在加载\"的占位图。\n- 另一种是图片加载失败(如图片不存在，路径不完整等)，通过`error-img`参数配置类似\"图片加载错误\"的占位图\n\n```html\n<template>\n\t<view>\n\t\t<u-lazy-load :image=\"image\" :loading-img=\"loadingImg\" :error-img=\"errorImg\"></u-lazy-load>\n\t</view>\n</template>\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\timage: \"https://gtd.alicdn.com/sns_logo/i1/TB124_3NXXXXXasXVXXSutbFXXX.jpg_240x240xz.jpg\",\n\t\t\t\tloadingImg: '/static/uView/loading.png',\n\t\t\t\terrorImg: '/static/uView/load_error.png'\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 图片加载位置\n\n可以通过`threshold`参数设置图片距离屏幕底部多少距离时触发图片加载，单位rpx，说明：\n- 如果取负值(如-300)，为尚未到达屏幕底部，距离300rpx时触发\n- 如果取正数(如300)，为图片超出屏幕底部300rpx时触发\n\n```html\n<u-lazy-load :image=\"image\" threshold=\"300\"></u-lazy-load>\n```\n\n\n### API\n\n###  Props\n\n| 参数          | 说明                                                                              | 类型             | 默认值      | 可选值                              |\n| ------------- | --------------------------------------------------------------------------------- | ---------------- | ----------- | ----------------------------------- |\n| index         | 用户自定义值，在事件触发时回调，用以区分是哪个图片                                | String \\| Number | -           | -                                   |\n| image         | 图片路径                                                                          | String           | -           | -                                   |\n| loading-img   | 预加载时的占位图                                                                  | String           | -           | -                                   |\n| error-img     | 图片加载出错时的占位图                                                            | String           | -           | -                                   |\n| threshold     | 触发加载时的位置，见上方说明，单位 rpx                                            | String           | 100         | -                                   |\n| duration      | 图片加载成功时，淡入淡出时间，单位ms                                              | String \\| Number | 500         | -                                   |\n| effect        | 图片加载成功时，淡入淡出的css动画效果                                             | String           | ease-in-out | linear /  ease / ease-in / ease-out |\n| is-effect     | 图片加载成功时，是否启用淡入淡出效果                                              | Boolean          | true        | false                               |\n| border-radius | 图片圆角值，单位rpx                                                               | String \\| Number | 0           | -                                   |\n| height        | 图片高度，注意：实际高度可能受`img-mode`参数影响                                  | String \\| Number | 450         | -                                   |\n| img-mode      | 图片的裁剪模式，详见[image组件裁剪模式](https://uniapp.dcloud.io/component/image) | String \\| Number | widthFix    | -                                   |\n\n### Events\n\n| 事件名 | 说明               | 回调参数                            | 版本 |\n| :----- | :----------------- | :---------------------------------- | :--- |\n| click  | 点击图片时触发     | index：用户通过props传递的`index`值 | -    |\n| load   | 图片加载成功时触发 | index：用户通过props传递的`index`值 | -    |\n| error  | 图片加载失败时触发 | index：用户通过props传递的`index`值 | -    |\n"
  },
  {
    "path": "src/static/app/markdown/line.md",
    "content": "## Line 线条 <to-api/>\n\n<demo-model url=\"/pages/componentsB/line/index\"></demo-model>\n\n此组件一般用于显示一根线条，用于分隔内容块，有横向和竖向两种模式，且能设置0.5px线条，使用也很简单。\n\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n组件内部有预置的参数，直接使用即可，有如下几个参数需要了解：\n\n- `color`为线条的颜色\n- `direction`为线条的方向，默认为横向\n- `hair-line`为是否设置细线条(0.5px)，默认为`true`\n- `length`参数需要特别留意，它需要带上单位，比如设置为\"50%\"，\"500rpx\"等，在线条为横向时，表现为线条的长度；在线条为竖向时，表现为线条的高度。\n\n```html\n<template>\n\t<u-line color=\"red\" />\n\t\n\t/* 等同于 */\n\t<u-line color=\"red\"></u-line>\n</template>\n```\n\n\n### 线条类型\n\n我们可以通过`border-style`参数设置线条的类型，有如下三种可选项：\n\n- `solid`表示实线\n- `dashed`表示方形虚线\n- `dotted`表示圆点虚线\n\n\n### 兼容性\n\n由于`头条小程序`的兼容性，如果组件无效的情况下，您可能需要给组件加上`u-line`类，如下：\n\n```html\n<u-line class=\"u-line\"></u-line>\n```\n\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| color | 线条的颜色 | String | #e4e7ed | - |\n| length | 长度，竖向时表现为高度，横向时表现为长度，可以为百分比，带rpx单位的值等 | String | 100% | - |\n| direction | 线条的方向，`row`-横向，`column`-竖向 | String | row | column |\n| hair-line | 是否显示细线条 | Boolean  | true | false |\n| margin | 线条与上下左右元素的间距，字符串形式，如\"30rpx\"、\"20rpx 30rpx\" | String  | - | - |\n| border-style | 线条类型，见上方说明 | String  | solid | dashed / dotted |\n\n\n<style scoped>\nh3[id=props] + table thead tr th:nth-child(2){\n\twidth: 37%;\n}\n</style>"
  },
  {
    "path": "src/static/app/markdown/lineProgress.md",
    "content": "## LineProgress 线形进度条 <to-api/>\n\n\n<demo-model url=\"/pages/componentsC/progress/index\"></demo-model>\n\n\n展示操作或任务的当前进度，比如上传文件，是一个线形的进度条。\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n- 通过`percent`设置当前的进度值，该值区间为0-100.\n- 通过`active-color`设置进度条的颜色，也可以直接设置`type`主题颜色(优先起作用)，使用预置值\n\n```html\n<u-line-progress active-color=\"#2979ff\" :percent=\"70\"></u-line-progress>\n```\n\n### 设置进度条动画效果\n\n该效果会在已完成的百分比部分显示移动的条纹(具体见示例效果)\n- `striped`参数配置是否显示条纹\n- `striped-active`参数配置条纹是否具有动态效果\n\n```html\n<u-line-progress :striped=\"true\" :percent=\"70\" :striped-active=\"true\"></u-line-progress>\n```\n\n### 设置进度条内部显示百分比值\n\n参数为`show-percent`  \n- 说明：进度条可以通过`height`设置高度，如果高度太小的话，是无法在内部显示当前的百分比值的\n\n```html\n<u-line-progress :percent=\"70\" :show-percent=\"true\"></u-line-progress>\n```\n\n### 修改进度条的样式\n\n- `active-color`参数修改激活部分的颜色\n- `round`参数设置进度条两端是否为半圆\n\n```html\n<u-line-progress :percent=\"70\" :round=\"false\" active-color=\"#ff9900\"></u-line-progress>\n```\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| percent | 进度条百分比值，为数值类型，0-100  | String \\| Number | - | - |\n| round | 进度条两端是否为半圆  | Boolean | true | false |\n| type | 如设置，`active-color`值将会失效 | String  | - | success / primary / error / info / warning |\n| active-color | 进度条激活部分的颜色 | String  | #19be6b | - |\n| inactive-color | 进度条的底色，默认为灰色 | String  | #ececec | - |\n| show-percent | 是否在进度条内部显示当前的百分比值数值 | Boolean  | true | false |\n| height | 进度条的高度，单位rpx | String \\| Number  | 28 | - |\n| striped | 是否显示进度条激活部分的条纹 | Boolean  | false | true |\n| striped-active | 条纹是否具有动态效果 | Boolean  | false | true |\n\n\n ### Slots\n\n| 名称 | 说明 |\n|:-|:-|\n| default | 传入自定义的显示内容，将会覆盖默认显示的百分比值 |\n\n\n<style scoped>\nh3[id=slots] + table thead tr th:nth-child(2){\n\twidth: 50%;\n}\n</style>\n"
  },
  {
    "path": "src/static/app/markdown/link.md",
    "content": "## Link 超链接\n\n<demo-model url=\"/pages/componentsC/link/index\"></demo-model>\n\n\n该组件为超链接组件，在不同平台有不同表现形式：\n- 在APP平台会通过`plus`环境打开内置浏览器\n- 在小程序中把链接复制到粘贴板，同时提示信息\n- 在H5中通过`window.open`打开链接\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n- 通过`href`设置打开的链接，`slot`传入显示的内容\n\n```html\n<u-link href=\"http://www.uviewui.com\">蜀道难，难于上青天</u-link>\n```\n\n### 下划线\n\n通过`under-line`设置是否显示链接的下划线\n\n```html\n<u-link href=\"http://www.uviewui.com\" :under-line=\"true\">蒹葭苍苍，白露为霜</u-link>\n```\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| color | 文字颜色 | String | #606266 | - |\n| font-size | 字体大小，单位rpx | String \\| Number  | 28 | - |\n| under-line | 是否显示下划线 | Boolean  | false | true |\n| href | 跳转的链接，要带上http(s) | String  | - | - |\n| line-color | 下划线颜色，默认同`color`参数颜色 | String  | - | - |\n| mp-tips | 各个小程序平台把链接复制到粘贴板后的提示语 | String  | 链接已复制，请在浏览器打开 | - |\n"
  },
  {
    "path": "src/static/app/markdown/loadMore.md",
    "content": "## loadMore 加载更多 <to-api/>\n\n<demo-model url=\"/pages/componentsC/loadmore/index\"></demo-model>\n\n\n此组件一般用于标识页面底部加载数据时的状态，共有三种状态：\n- 加载前，显示\"加载更多\"，加入点击可选，是因为数据不够一页时，无法触发页面的`onReachBottom`生命周期\n- 加载中，显示\"正在加载...\"，2种动画可选\n- 加载后，如果还有数据，回到\"加载前\"状态，否则加载结束，显示\"没有更多了\"\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n- 通过`status`设置组件的状态，加载前值为`loadmore`，加载中为`loading`，没有数据为`nomore`\n\n注意：以下示例仅为模拟效果，实际中请根据自己的逻辑，修改代码的实现\n\n```html\n<template>\n\t<view class=\"wrap\">\n\t\t<view class=\"item u-border-bottom\" v-for=\"(item, index) in list\" :key=\"index\">\n\t\t\t{{'第' + item + '条数据'}}\n\t\t</view>\n\t\t<u-loadmore :status=\"status\" />\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tstatus: 'loadmore',\n\t\t\t\tlist: 15,\n\t\t\t\tpage: 0\n\t\t\t}\n\t\t},\n\t\tonReachBottom() {\n\t\t\tif(this.page >= 3) return ;\n\t\t\tthis.status = 'loading';\n\t\t\tthis.page = ++ this.page;\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.list += 10;\n\t\t\t\tif(this.page >= 3) this.status = 'nomore';\n\t\t\t\telse this.status = 'loading';\n\t\t\t}, 2000)\n\t\t}\n\t}\n</script>\n\n<style lang=\"scss\" scoped>\n\t.wrap {\n\t\tpadding: 24rpx;\n\t}\n\t\n\t.item {\n\t\tpadding: 24rpx 0;\n\t\tcolor: $u-content-color;\n\t\tfont-size: 28rpx;\n\t}\n</style>\n```\n\n### 控制组件的提示以及动画效果\n\n- 可以通过`icon-type`设置加载中的图标为`flower`或者`circle`，如果不需要图标，可以设置`icon`为`false`\n- 可以设置`is-dot`为`true`，在没有数据时，内容显示为一个\"●\"替代默认的\"没有更多了\"\n- 可以通过配置`load-text`配置提示的文字，该参数为一个对象值，可以修改默认的文字提示，见如下：\n\n```html\n<template>\n\t<u-loadmore :status=\"status\" :icon-type=\"iconType\" :load-text=\"loadText\" />\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tstatus: 'loadmore',\n\t\t\t\ticonType: 'flower',\n\t\t\t\tloadText: {\n\t\t\t\t\tloadmore: '轻轻上拉',\n\t\t\t\t\tloading: '努力加载中',\n\t\t\t\t\tnomore: '实在没有了'\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n\n### 手动触发加载更多\n\n有时候可能会因为网络，或者数据不满一页的原因，导致无法上拉触发`onReachBottom`生命周期，这时候(需`status`为`loadmore`状态)，用户点击组件，就会触发`loadmore`\n事件，可以在回调中，进行状态的控制和数据的加载，同时也可以修改`loadText`的`loadmore`为\"上拉或点击加载更多\"进行更加人性化的提示。\n\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| status | 组件状态  | String | loadmore | loading / nomore |\n| bg-color | 组件背景颜色，在页面是非白色时会用到(1.7.0起废弃此参数，默认为transparent)  | String\t | #ffffff | - |\n| icon | 加载中时是否显示图标  | Boolean | true | false |\n| icon-type | 加载中时的图标类型， | String | circle | flower |\n| icon-color | `icon-type`为`circle`时有效，加载中的动画图标的颜色  | String | #b7b7b7 | - |\n| is-dot |  `status`为`nomore`时，内容显示为一个\"●\" | Boolean | false | true |\n| color | 字体颜色  | String | #606266 | - |\n| font-size | 字体大小，单位rpx  | String \\| Number | 28 | - |\n| load-text | 自定义显示的文字，见上方说明示例  | Object | - | - |\n| margin-top | 与前一个元素的距离，单位rpx | String \\| Number  | 0 | - |\n| margin-bottom | 与后一个元素的距离，单位rpx | String \\| Number  | 0 | - |\n\n\n### Event\n\n\n|事件名|说明|回调参数|版本|\n|:-|:-|:-|:-|\n| loadmore | `status`为`loadmore`时，点击组件会发出此事件 | - | - |"
  },
  {
    "path": "src/static/app/markdown/loading.md",
    "content": "## Loading 加载动画 <to-api/>\n\n<demo-model url=\"/pages/componentsB/loading/index\"></demo-model>\n\n\n此组件为一个小动画，目前用在uView的[loadmore加载更多](/components/loadMore.html)和[switch开关](/components/switch.html)等组件的正在加载状态场景。\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n通过`mode`设定动画的类型，`circle`为圆圈的形状，`flower`为经典类似花朵的形状\n\n\n```html\n<template>\n\t<view>\n\t\t<u-loading mode=\"circle\"></u-loading>\n\t\t<u-loading mode=\"flower\"></u-loading>\n\t</view>\n</template>\n```\n\n### 动画颜色\n\n`color`可以指定动画活动区域的颜色\n\n```html\n<u-loading color=\"red\"></u-loading>\n```\n\n### 动画尺寸\n\n通过`size`设定尺寸，单位rpx，组件内把`size`值体现为组件的宽和高\n\n```html\n<u-loading size=\"36\"></u-loading>\n```\n\n### 显示或隐藏动画\n\n通过`show`设置为`true`或`false`，来显示或隐藏动画\n\n```html\n<u-loading :show=\"true\"></u-loading>\n\n/* 等价于 */\n<u-loading show></u-loading>\n```\n\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| mode | 模式选择，见上方说明  | String | circle | flower |\n| color | 动画活动区域的颜色，只对 mode = circle 模式有效  | String\t | #c7c7c7 | - |\n| size |加载图标的大小，单位rpx | String \\| Number  | 34 | - |\n| show | 是否显示动画 | Boolean  | true | false |\n\n\n"
  },
  {
    "path": "src/static/app/markdown/mask.md",
    "content": "## Mask 遮罩层 <to-api/>\n\n<demo-model url=\"/pages/componentsC/mask/index\"></demo-model>\n\n\n创建一个遮罩层，用于强调特定的页面元素，并阻止用户对遮罩下层的内容进行操作，一般用于弹窗场景\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n- 通过`show`参数配置是否显示遮罩  \n- 遮罩被点击时，会发送一个`click`事件，如不需要此事件，请设置`mask-click-able`参数为`false`\n\n```html\n<template>\n\t<u-mask :show=\"show\" @click=\"show = false\"></u-mask>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tshow: true\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 嵌入内容\n\n通过默认插槽可以在遮罩层上嵌入任意内容  \n注意：如果不想让`slot`插槽内容的点击事件冒泡到遮罩，请给指定元素添加上`@tap.stop`\n\n```html\n<template>\n\t<u-mask :show=\"show\" @click=\"show = false\">\n\t\t<view class=\"warp\">\n\t\t\t<view class=\"rect\" @tap.stop></view>\n\t\t</view>\n\t</u-mask>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tshow: true\n\t\t\t}\n\t\t}\n\t}\n</script>\n\n<style scoped>\n\t.warp {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\theight: 100%;\n\t}\n\n\t.rect {\n\t\twidth: 120px;\n\t\theight: 120px;\n\t\tbackground-color: #fff;\n\t}\n</style>\n```\n\n### 遮罩样式\n\n- 通过`duration`设置遮罩淡入淡出的时长，单位`ms`\n- 通过`zoom`设置遮罩淡入淡出时是否带有轻微的缩放效果，内部通过`transform: scale(1.2, 1.2)`实现\n- 通过`custom-style`传入一个对象，自定义样式，如\"{backgroundColor: 'red', color: 'blue'}\"\n\n```html\n<u-mask :show=\"show\" :duration=\"400\" :zoom=\"true\" :custom-style=\"{background: 'rgba(0, 0, 0, 0.5)'}\"></u-mask>\n```\n\n### API\n\n### Props\n\n| 参数      | 说明        | 类型     |  默认值  |  可选值   |\n|-----------|-----------|----------|----------|---------|\n| show | 是否显示遮罩  | Boolean | false | true |\n| z-index | z-index 层级 | String \\| Number  | 10070 | - |\n| custom-style | 自定义样式对象，见上方说明 | Object  | - | - |\n| duration | 动画时长，单位毫秒 | String \\| Number  | 300 | - |\n| zoom | 是否使用`scale`对遮罩进行缩放 | Boolean  | true | false |\n| mask-click-able | 遮罩是否可点击，为`false`时点击不会发送`click`事件 | Boolean  | true | false |\n\n### Events\n\n|事件名|说明|回调参数|\n|:-|:-|:-|\n| click | `mask-click-able`为`true`时，点击遮罩发送此事件 | - |\n\n### Slot\n\n|名称|说明|\n|:-|:-|\n| default | 默认插槽，用于在遮罩层上方嵌入内容 |\n\n\n\n<style scoped>\nh3[id=events] + table thead tr th:nth-child(2){\n\twidth: 50%;\n}\n\nh3[id=slot] + table thead tr th:nth-child(2){\n\twidth: 50%;\n}\n</style>"
  },
  {
    "path": "src/static/app/markdown/md5.md",
    "content": "# md5 加密\n\n<demo-model url=\"/pages/library/md5/index\"></demo-model>\n\n\n该`md5`加密方法，需要手动`import`库函数，调用`md5`方法即可使用，可以对字符串加密为32位的字符串结果，如需进一步了解，\n详见[MD5百度百科](https://baike.baidu.com/item/MD5)  \n\n\n使用方法：\n\n```js\nimport { ref, onMounted } from 'vue';\nimport md5Libs from \"uview-pro/libs/function/md5\";\n\nconst md5Result = ref('');\n\nonMounted(() => {\n  md5Result.value = md5Libs.md5('uView');\n  console.log(md5Result.value);\n  // 结果为：55c859b4750225eb1cdbd9e0403ee274\n});\n```"
  },
  {
    "path": "src/static/app/markdown/messageInput.md",
    "content": "## MessageInput 验证码输入 <to-api/>\n\n<demo-model url=\"/pages/componentsC/messageInput/index\"></demo-model>\n\n\n该组件一般用于验证用户短信验证码的场景，也可以结合uView的[键盘组件](/components/keyboard.html)使用\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n- 通过`mode`参数模式，可取如下值：\n- `box`(默认)-输入位置位一个方框\n- `bottomLine`-底部显示一条横线\n- `middleLine`-中部显示一条横线\n\n```html\n<u-message-input mode=\"bottomLine\"></u-message-input>\n```\n\n### 设置最大长度和初始值\n\n- 通过`maxlength`参数配置可输入的方框个数，如5位验证码，该值设置为5即可\n- 如果需要显示默认值，请通过`value`参数配置\n\n```html\n<u-message-input maxlength=\"5\" value=\"46821\"></u-message-input>\n```\n\n### 是否自动获取焦点\n\n如果需要一打开页面，就自动弹出键盘获取焦点，请配置`focus`值为true，否则需要用户手动点击输入区域才能唤起键盘\n\n```html\n<u-message-input :focus=\"true\"></u-message-input>\n```\n\n### 配置呼吸灯效果\n\n配置`breathe`为`true`，当前激活输入框的样式会有一个类似光标一闪一闪的由浅到深的效果\n\n```html\n<u-message-input :breathe=\"true\"></u-message-input>\n```\n\n### 用\"●\"替代输入内容\n\n`dot-fill`参数配置后，输入内容将不可见，用点替代，事件回调中会返回真实值\n\n```html\n<u-message-input :dot-fill=\"true\"></u-message-input>\n```\n\n\n### 禁止唤起系统键盘\n\nuView有[键盘](/components/keyboard.html)组件，如果您想结合键盘组件进行自定义的输入效果，就需要设置`disabled-keyboard`为`true`，来保证点击\n输入框时不会触发系统自带的键盘，否则会造成冲突。\n\n### 事件回调\n\n- 每当输入内容发生改变，会回调一个`change`事件，内容为当前输入的字符串，如\"395\"\n- 当输入的内容长度(字符个数)达到`maxlength`值后，会触发`finish`事件，同时也会触发`change`事件\n\n```html\n<template>\n\t<view>\n\t\t<u-message-input @change=\"change\" @finish=\"finish\"></u-message-input>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tmethods: {\n\t\t\tchange(e) {\n\t\t\t\tconsole.log('内容改变，当前值为：' + e);\n\t\t\t},\n\t\t\tfinish(e) {\n\t\t\t\tconsole.log('输入结束，当前值为：' + e);\n\t\t\t},\n\t\t}\n\t}\n</script>\n```\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| maxlength | 输入字符个数 | String \\| Number | 4 | - |\n| dot-fill | 是否用圆点填充  | Boolean | false | true |\n| mode | 模式选择，见上方\"基本使用\"说明 | String | box | bottomLine / middleLine |\n| value | 预置值 | String \\| Number | - | - |\n| breathe | 是否开启呼吸效果，见上方说明 | Boolean | true | false |\n| focus | 是否自动获取焦点 | Boolean | false | true |\n| bold | 字体和输入横线是否加粗 | Boolean | true | false |\n| font-size | 字体大小，单位rpx | String \\| Number | 60 | - |\n| active-color | 当前激活输入框的样式 | String | #2979ff | - |\n| inactive-color | 非激活输入框的样式，文字颜色同此值 | String | #606266 | - |\n| width | 输入框的宽度(高等于宽)，单位rpx | String \\| Number | 80 | - |\n| disabled-keyboard | 禁止点击输入框唤起系统键盘 | Boolean  | false | true |\n\n### Events\n\n| 事件名 | 说明 | 回调参数 | 版本 |\n| :- | :- | :- | :- |\n| change | 输入内容发生改变时触发，具体见上方说明 | value：当前输入的值 | - |\n| finish | 输入字符个数达`maxlength`值时触发，见上方说明 | value：当前输入的值 | - |\n\n"
  },
  {
    "path": "src/static/app/markdown/modal.md",
    "content": "## Modal 模态框 <to-api/>\n\n弹出模态框，常用于消息提示、消息确认、在当前页面内完成特定的交互操作。\n\n<demo-model url=\"/pages/componentsA/modal/index\"></demo-model>\n\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n\n默认情况下，模态框只有一个`确认`按钮：\n- 请至少要配置弹框的内容参数`content`。\n- 通过`v-model`绑定一个布尔变量来控制模态框的显示与否。\n\n```html\n<template>\n\t<view>\n\t\t<u-modal v-model=\"show\" :content=\"content\"></u-modal>\n\t\t<u-button @click=\"open\">\n\t\t\t打开模态框\n\t\t</u-button>\n\t</view>\n</template>\n\t\n<script>\n\texport default {\n\t\tdata() {\t\n\t\t\treturn {\n\t\t\t\tshow: false,\n\t\t\t\tcontent: '东临碣石，以观沧海'\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\topen() {\n\t\t\t\tthis.show = true;\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 传入富文本内容\n\n有时候我们需要给模态框的内容，不一定是纯文本的字符串，可能会需要换行，嵌入其他元素等，这时候我们可以使用`slot`功能，再结合uni-app`rictText`组件，\n就能传入富文本内容了，如下演示：\n\n\n```html\n<template>\n\t<view>\n\t\t<u-modal v-model=\"show\" :title-style=\"{color: 'red'}\">\n\t\t\t<view class=\"slot-content\">\n\t\t\t\t<rich-text :nodes=\"content\"></rich-text>\n\t\t\t</view>\n\t\t</u-modal>\n\t\t<u-button @click=\"open\">\n\t\t\t打开模态框\n\t\t</u-button>\n\t</view>\n</template>\n\t\n<script>\n\texport default {\n\t\tdata() {\t\n\t\t\treturn {\n\t\t\t\tshow: false,\n\t\t\t\tcontent: `\n\t\t\t\t\t空山新雨后<br>\n\t\t\t\t\t天气晚来秋\n\t\t\t\t`\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\topen() {\n\t\t\t\tthis.show = true;\n\t\t\t}\n\t\t}\n\t}\n</script>\n<style lang=\"scss\" scoped>\n\t.slot-content {\n\t\tfont-size: 28rpx;\n\t\tcolor: $u-content-color;\n\t\tpadding-left: 30rpx;\n\t}\n</style>\n```\n\n### 异步关闭\n\n异步关闭只对\"确定\"按钮起作用，需要设置`async-close`为`true`，当点击确定按钮的时候，按钮的文字变成一个loading动画，此动画的颜色为\n`confirm-color`参数的颜色，同时Modal不会自动关闭，需要手动设置通过`v-model`绑定的变量为`false`来实现手动关闭。\n\n```html\n<template>\n\t<view class=\"\">\n\t\t<u-modal v-model=\"show\" @confirm=\"confirm\" ref=\"uModal\" :async-close=\"true\"></u-modal>\n\t\t<u-button @click=\"showModal\">弹起Modal</u-button>\n\t</view>\n</template>\n\n<script>\nexport default {\n    data() {\n        return {\n\t\t\tshow: false\n\t\t}\n\t},\n\tonLoad: function(opt) {\n\t\t\n\t},\n\tmethods:{\n\t\tshowModal() {\n\t\t\tthis.show = true;\n\t\t},\n\t\tconfirm() {\n\t\t\tsetTimeout(() => {\n\t\t\t\t// 3秒后自动关闭\n\t\t\t\tthis.show = false;\n\t\t\t\t// 如果不想关闭，而单是清除loading状态，需要通过ref手动调用方法\n\t\t\t\t// this.$refs.uModal.clearLoading();\n\t\t\t}, 3000)\n\t\t}\n    }\n}\n</script>\n```\n\n### 点击遮罩关闭\n\n有时候我们不显示\"关闭\"按钮的时候，需要点击遮罩也可以关闭Modal，这时通过配置`mask-close-able`为`true`即可\n\n```html\n<u-modal v-model=\"show\" :mask-close-able=\"true\"></u-modal>\n```\n\n### 控制模态框宽度\n\n可以通过设置`width`参数控制模态框的宽度，此值可以为数值(单位rpx)，百分比，`auto`等。\n\n\n```html\n<u-modal v-model=\"show\" width=\"70%\"></u-modal>\n```\n\n\n### 自定义样式\n\n此组件有完善的自定义功能，可以配置标题，内容，按钮等样式(传入对象形式)，具体参数详见底部的API说明\n\n```html\n<u-modal v-model=\"show\" :title-style=\"{color: 'red'}\"></u-modal>\n```\n\n\n### 缩放效果\n\n开启缩放效果，在打开和收起模态框的时候，会带有缩放效果，具体效果请见示例，此效果默认开启，通过`zoom`参数配置\n\n```html\n<u-modal v-model=\"show\" :zoom=\"false\"></u-modal>\n```\n\n\n### API\n\n### Props\n\n注意：需要给`modal`组件通过`v-model`绑定一个布尔值，来初始化`modal`的状态，随后该值被双向绑定。\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| show | 是否显示模态框，请赋值给`v-model` | Boolean  | false | true |\n| z-index | 层级  | String \\| Number | 1075 | - |\n| title | 标题内容  | String | 提示 | - |\n| width | 模态框宽度，数值时单位为rpx | String \\| Number  | 600 | 百分比 / auto |\n| content | 模态框内容，如传入`slot`内容，则此参数无效 | String  | 内容 | - |\n| show-title | 是否显示标题 | Boolean  | true | false |\n| show-confirm-button | 是否显示确认按钮 | Boolean  | true | false |\n| show-cancel-button | 是否显示取消按钮 | Boolean  | false | true |\n| confirm-text | 确认按钮的文字 | String  | 确认 | - |\n| cancel-text | 取消按钮的文字 | String  | 取消 | - |\n| cancel-color | 取消按钮的颜色 | String  | #606266 | - |\n| confirm-color | 确认按钮的颜色 | String  | #2979ff | - |\n| border-radius | 模态框圆角值，单位rpx | String \\| Number  | 16 | - |\n| title-style | 自定义标题样式，对象形式 | Object  | - | - |\n| content-style | 自定义内容样式，对象形式 | Object  | - | - |\n| cancel-style | 自定义取消按钮样式，对象形式 | Object  | - | - |\n| confirm-style | 自定义确认按钮样式，对象形式 | Object  | - | - |\n| zoom | 是否开启缩放模式 | Boolean  | true | false |\n| async-close | 是否异步关闭，只对确定按钮有效，见上方说明 | Boolean  | false | true |\n| mask-close-able | 是否允许点击遮罩关闭Modal | Boolean  | false | true |\n| negative-top | 往上偏移的值，以避免可能弹出的键盘重合，单位任意，数值则默认为rpx单位  | String \\| Number | 0 | - |\n\n\n### Event\n\n|事件名|说明|回调参数|\n|:-|:-|:-|:-|\n| confirm | 点击确认按钮时触发 | - |\n| cancel | 点击取消按钮时触发 | - |\n\n\n### Method\n\n此方法需要通过ref调用，详见上方的\"异步关闭\"\n\n|事件名|说明|\n|:-|:-|:-|\n| clearLoading | 异步控制时，通过调用此方法，可以不关闭Modal，而单是清除loading状态 |\n\n\n### Slots\n\n| 名称 | 说明 |\n|:-|:-|\n| default | 传入自定义内容，一般为富文本，见上方说明 |\n| confirm-button | 传入自定义按钮，用于在微信小程序弹窗通过按钮授权的场景 |\n\n\n<style scoped>\nh3[id=slots] + table thead tr th:nth-child(2){\n\twidth: 50%;\n}\n\nh3[id=method] + p + table thead tr th:nth-child(2){\n\twidth: 50%;\n}\n</style>"
  },
  {
    "path": "src/static/app/markdown/mpShare.md",
    "content": "# mpShare 小程序分享\n\n<demo-model url=\"/pages/library/mpShare/index\"></demo-model>\n\n\n此功能，是对uni的[onShareAppMessage 生命周期](https://uniapp.dcloud.io/api/plugins/share?id=onshareappmessage)的封装。  \n\n这里说的小程序，指的是\"微信小程序、百度小程序、头条小程序、QQ小程序，支付宝小程序等\"。  \n\n由于小程序的分享(微信、头条平台)，需要监听页面的`onShareAppMessage`生命周期，小程序需要在页面声明了此生命周期，点击右上角的\"胶囊\"才会有分享功能，\n而一般情况下，我们希望每个页面都可以分享，那就需要每个页面都写一遍这个生命周期，是很繁琐的。   \n\n基于以上，uView通过`mixin`的形式，给每一个页面注入了`onShareAppMessage`生命周期，让您简单引入，无需任何后续操作，即可让每一个页面都有分享功能(仅针对小程序)。  \n\n\n## 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   x   |   x   |     √      |      √       |     √      |     √      |    √     |\n\n\n## 基本使用\n\n需要注意的是，小程序(uni)没有提供类似\"getNavigationBarTitle\"这样的接口，所以我们无法获取当前页面导航栏的标题，换言之，我们想要每个页面个性化的\n分享标题，需要手动设置，否则**默认为小程序的名称**。\n\n分享功能是默认关闭的，但是我们写好各项配置，您只要在`main.js`中引入对应的文件即可，我们没有默认引入，是因为某些用户并不需要此功能。\n\n打开小程序分享功能：\n```js\n// main.js\n\n// 其他内容\n\n// 引入uView对小程序分享的mixin封装\nlet mpShare = require('uview-pro/libs/mixin/mpShare.js');\nVue.mixin(mpShare)\n\n// 其他内容\n```\n\n分享功能，一般有三个参数，如下：\n\n```js\n// 该对象已集成到this.$u中，内部属性如下\nuni.$u.mpShare = {\n\ttitle: '', // 默认为小程序名称，可自定义\n\tpath: '', // 默认为当前页面路径，一般无需修改，QQ小程序不支持\n\t// 分享图标，路径可以是本地文件路径、代码包文件路径或者网络图片路径。\n\t// 支持PNG及JPG，默认为当前页面的截图\n\timageUrl: '' \n}\n```\n\n以上这些，uView已通过`mixin`集成，当某一个页面您需要自定义分享信息时，可以通过\"uni.$u.mpShare\"对进行修改，在页面的`onLoad`生命周期修改即可。\n\n```vue\n<script setup lang=\"ts\">\nimport { onLoad } from '@dcloudio/uni-app'\n\nonLoad(() => {\n  uni.$u.mpShare.title = '天苍苍野茫茫，风吹草低见牛羊';\n})\n</script>\n```\n\n\n## 重写\"onShareAppMessage\"生命周期\n\n如果您基于自己的一些业务逻辑，需要更加自定义的实现逻辑，可以在页面中重写`onShareAppMessage`生命周期即可覆盖uView通过`mixin`监听的`onShareAppMessage`生命周期。\n\n```vue\n<script setup lang=\"ts\">\n// 这里如果写成onShareAppMessage: res => { ... }形式的箭头函数，在内部会无法获得this\nexport function onShareAppMessage(res: any) {\n  if (res.from === 'button') {// 来自页面内分享按钮\n    console.log(res.target)\n  }\n  return {\n    title: '自定义分享标题',\n    path: '/pages/test/test?id=123'\n  }\n}\n</script>\n```\n\n## 分享到朋友圈\n\n此功能为微信小程序最新加入的功能，仅适用于微信小程序，uView也全局监听了此生命周期。\n\n同理，你也可以在页面中重写`onShareTimeline`生命周期即可覆盖uView通过`mixin`监听的`onShareTimeline`生命周期。\n\n```vue\n<script setup lang=\"ts\">\nexport function onShareTimeline(res: any) {\n  if (res.from === 'button') {// 来自页面内分享按钮\n    console.log(res.target)\n  }\n  return {\n    title: '自定义分享标题',\n    path: '/pages/test/test?id=123'\n  }\n}\n</script>\n```\n\n<!-- ## 如何取消全局分享\n\n此功能为uView默认开启的，如果用户想全局取消或者单个页面取消分享功能，只需将\"uni.$u.mpShare\"设置为`false`即可\n\n- 全局取消，在App.vue的`onLaunch`应用生命周期中设置\n\n```js\nexport default {\n\tonLaunch() {\n\t\tuni.$u.mpShare = false;\n\t}\n}\n```\n\n- 某个特定的页面取消，在`onLoad`生命周期中设置\n\n```js\nexport default {\n\tonLoad() {\n\t\tuni.$u.mpShare = false\n\t}\n}\n``` -->\n"
  },
  {
    "path": "src/static/app/markdown/navbar.md",
    "content": "### Navbar 自定义导航栏 <to-api/>\n\n此组件一般用于在特殊情况下，需要自定义导航栏的时候用到，一般建议使用 uni-app 带的导航栏。\n\n<demo-model url=\"/pages/componentsA/navbar/index\"></demo-model>\n\n<custom-block text=\"右侧的演示中，导航栏上方有圆角，也有顶部的手机模型状态栏内容，以及返回图标和文字不对齐的情况。这是因为网页演示导致，实际中无此情况，请通过右上角的“演示”扫码查看实际效果。\"></custom-block>\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ 小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :-------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |     √     |\n\n### 基本使用\n\n默认情况下，该组件只有向左的箭头，**点击**可以返回上一页，如果您想将自定义导航栏用在 tabbar(不存在要返回的逻辑)页面，应该将`is-back`设置为`false`，\n这样会隐藏左边的返回图标区域。\n\n- 如果想在返回箭头的右边自定义类似\"返回\"字样，可以将`back-text`设置为\"返回\"，前提是`is-back`要为`true`(默认)\n- 通过`title`参数传入需要显示的标题，通过`title-width`(rpx)设置标题区域的宽度，文字超出会通过省略号隐藏\n- 通过`is-fixed`配置是否将导航栏固定在顶部\n\n\n\n- 在小程序中，导航栏会自动适配导航栏右侧的胶囊位置，避开该区域\n- 组件底部默认有一条下边框，如您不需要，可以设置`border-bottom`为`false`即可\n  \n\n```html\n<template>\n  <view>\n    <u-navbar back-text=\"返回\" title=\"剑未配妥，出门已是江湖\"></u-navbar>\n    <view class=\"content\">\n      <!-- 正文内容 -->\n    </view>\n  </view>\n</template>\n```\n\n### 注意事项\n\n既然是要自定义导航栏，那么首先就要取消系统自带的导航栏，需要在 uni-app 目的根目录的\"pages.json\"中设置，同时在此设置状态栏字体的颜色(H5 无效)，\n自定义导航栏后，如果想通过\"uni.setNavigationBarColor\"动态设置导航栏颜色相关参数，是可能会出问题的，请勿使用此方式。\n\n```js\n// pages.json\n\n\"pages\": [\n\t// navbar-自定义导航栏\n\t{\n\t\t\"path\": \"/pages/navbar/index\",\n\t\t\"style\": {\n\t\t\t\"navigationStyle\": \"custom\" ,// 隐藏系统导航栏\n\t\t\t\"navigationBarTextStyle\": \"white\" // 状态栏字体为白色，只能为 white-白色，black-黑色 二选一\n\t\t}\n\t}\n]\n```\n\n### 导航栏高度\n\n可以通过`height`(单位**px**，默认 44，和 uni-app 统导航栏高度一致)配置导航栏的高度，此高度为导航栏内容的高度，不含状态栏的高度，组件内部会自动\n加上状态栏的高度，并填充状态栏的占位区域。\n\n注意上方说的 uni-app 方的高度，这里指的是 H5，和 APP。至于各家小程序，由于受导航栏右侧胶囊的影响，目前组件内部给安卓设定的导航栏高度为`48px`，iOS 设定的导航栏高度为`44`，这是结合了大量的\n实践的出来的结果，具备完好的兼容性。\n\n### 自定义导航栏内容\n\n一般需要自定义导航栏内部的内容的时候，分几种情况：\n\n- `is-back`为`false`可以去除导航栏左侧默认的返回图标和文字。\n- 如有必要，将`title`设置空字符串，同时将会去除导航栏中间显示标题的占位区域。\n\n当将`is-back`设置为`false`，`title`设置为空字符串之后，导航栏将不会有任何默认的内容，您可以通过`slot`传入任意自定义内容，在 APP 和小程序上，导航栏\n会自动添加状态栏的占位区域。\n\n**注意：** 通过自定义`slot`传入的内容，为了能在导航栏中垂直居中，您可能需要注意下方示例的 css 的`slot-wrap`类的内容：\n\n```html\n<template>\n  <view>\n    <u-navbar :is-back=\"false\" title=\"\">\n      <view class=\"slot-wrap\"> ...... </view>\n    </u-navbar>\n    <view class=\"content\">\n      <!-- 正文内容 -->\n    </view>\n  </view>\n</template>\n\n<style scoped lang=\"scss\">\n  .slot-wrap {\n    display: flex;\n    align-items: center;\n    /* 如果您想让slot内容占满整个导航栏的宽度 */\n    /* flex: 1; */\n    /* 如果您想让slot内容与导航栏左右有空隙 */\n    /* padding: 0 30rpx; */\n  }\n</style>\n```\n\n### 自定义导航栏背景颜色\n\nuView 提供了一个`background`参数(需对象形式)，可以自定义导航栏的背景颜色：\n\n- 这个颜色，在 APP 和小程序上，包括状态的颜色在内\n- 如果是定义纯色的背景，可以设置`backgroundColor`属性\n- 如果是定义渐变的背景，可以设置`backgroundImage`属性\n- 如果是定义背景图，可以设置`background`属性，还可以加上其他属性，比如`no-repeat`，`center`等\n\n```html\n<template>\n  <view>\n    <u-navbar :is-back=\"false\" title=\"\" :background=\"background\"> </u-navbar>\n    <view class=\"content\">\n      <!-- 正文内容 -->\n    </view>\n  </view>\n</template>\n\n<script>\n  export default {\n    data() {\n      return {\n        background: {\n          backgroundColor: \"#001f3f\",\n\n          // 导航栏背景图\n          // background: 'url(https://cdn.uviewui.com/uview/xxx.jpg) no-repeat',\n          // 还可以设置背景图size属性\n          // backgroundSize: 'cover',\n\n          // 渐变色\n          // backgroundImage: 'linear-gradient(45deg, rgb(28, 187, 180), rgb(141, 198, 63))'\n        },\n      };\n    },\n  };\n</script>\n```\n\n### API\n\n### Props\n\n| 参数            | 说明                                                                                                    | 类型             | 默认值                    | 可选值 |\n| --------------- | ------------------------------------------------------------------------------------------------------- | ---------------- | ------------------------- | ------ |\n| height          | 导航栏高度(不包括状态栏高度在内，内部自动加上)，注意这里的单位是<span style=\"color: red;\">**px**</span> | String \\| Number | 44                        | -      |\n| back-icon-color | 左边返回图标的颜色                                                                                      | String           | #606266                   | -      |\n| back-icon-name  | 左边返回图标的名称，只能为 uView 自带的图标，`1.5.5`起由 arrow-left 调整为 nav-back                     | String           | nav-back                  | -      |\n| back-icon-size  | 左边返回图标的大小，单位 rpx                                                                            | String \\| Number | 30                        | -      |\n| back-text       | 返回图标右边的辅助提示文字                                                                              | String           | -                         | -      |\n| back-text-style | 返回图标右边的辅助提示文字的样式，对象形式                                                              | Object           | { color: '#606266' }      | -      |\n| title           | 导航栏标题，如设置为空字符，将会隐藏标题占位区域                                                        | String           | -                         | -      |\n| title-width     | 导航栏标题的最大宽度，内容超出会以省略号隐藏，单位 rpx                                                  | String \\| Number | 250                       | -      |\n| title-color     | 标题的颜色                                                                                              | String           | #606266                   | -      |\n| title-size      | 导航栏标题字体大小，单位 rpx，`1.5.5`起由 32 调整为 44                                                  | String \\| Number | 44                        | -      |\n| z-index         | 固定在顶部时的`z-index`值                                                                               | String \\| Number | 980                       | -      |\n| is-back         | 是否显示导航栏左边返回图标和辅助文字                                                                    | Boolean          | true                      | false  |\n| background      | 导航栏背景设置(APP 和小程序上包括状态栏的颜色)，见上方说明                                              | Object           | { background: '#ffffff' } | -      |\n| is-fixed        | 导航栏是否固定在顶部                                                                                    | Boolean          | true                      | false  |\n| border-bottom   | 导航栏底部是否显示下边框，如定义了较深的背景颜色，可取消此值                                            | Boolean          | true                      | false  |\n| custom-back     | 自定义返回逻辑方法，如传入，点击返回按钮执行函数，否则正常返回上一页，注意模板中不需要写方法参数的括号  | Function         | -                         | -      |\n| immersive       | 沉浸式，允许 fixed 定位后导航栏塌陷，仅 fixed 定位下生效                                                | Boolean          | false                     | true   |\n| title-bold      | 导航栏标题字体是否加粗                                                                                  | Boolean          | false                     | true   |\n\n### Slot\n\n| 名称  | 说明                 |\n| ----- | -------------------- |\n| -     | 自定义中间部分的内容 |\n| right | 自定义右侧部分内容   |\n\n<style scoped>\nh3[id=props] + table thead tr th:nth-child(2){\n\twidth: 40%;\n}\n\nh3[id=slot] + table thead tr th:nth-child(2){\n\twidth: 50%;\n}\n</style>\n"
  },
  {
    "path": "src/static/app/markdown/noNetwork.md",
    "content": "## NoNetwork 无网络提示 <to-api/>\n\n<demo-model url=\"/pages/componentsA/noNetwork/index\"></demo-model>\n\n\n该组件无需任何配置，引入即可，内部自动处理所有功能和事件，有如下特点：\n- 如果没有网络，该组件会以`fixed`定位，并且以很大的`z-index`值覆盖原来的内容。一旦有网络了，会自动隐藏该组件，实现自动化\n- 在APP上，嵌入了5+接口，可以直接打开手机的设置页面，方便用户进行网络相关的设置\n\n\n1. 应用有网络时，是不会触发本组件的，为了测试此功能，请关闭手机的数据连接以及WiFi即可\n2. 由于普通的组件无法覆盖原生组件，所以本组件不适用那些有`video`，`map`等原生表现的组件的页面，可以自行使用uni的`cover-view`组件修改\n\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      √       |     √      |     x      |    √     |\n\n### 基本使用\n\n```html\n<template>\n\t<view>\n\t\t<view class=\"u-text\">\n\t\t\t这里是页面正式内容\n\t\t</view>\n\t\t<u-no-network></u-no-network>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\t\n\t}\n</script>\n\n<style lang=\"scss\" scoped>\n\t.u-text {\n\t\tpadding-top: 300rpx;\n\t\tfont-size: 30rpx;\n\t\tcolor: $u-type-primary;\n\t\ttext-align: center;\n\t}\n</style>\n```\n\n\n### 兼容性\n\n- `头条小程序`不支持监听网络状态变化，故本组件不支持`头条小程序`\n\n\n### API\n\n### Props\n\n| 参数   | 说明                                        | 类型             | 默认值             | 可选值 |\n| ------ | ------------------------------------------- | ---------------- | ------------------ | ------ |\n| tips   | 没有网络时的提示语                          | String           | 哎呀，网络信号丢失 | -      |\n| zIndex | 组件的`z-index`值                           | String \\| Number | 10080              | -      |\n| image  | 无网络的图片提示，可用的src地址或base64图片 | String           | -                  | -      |\n\n### Events\n\n\n| 事件名 | 说明                           | 回调参数 |\n| :----- | :----------------------------- | :------- |\n| retry  | 用户点击页面的\"重试\"按钮时触发 | -        |\n\n"
  },
  {
    "path": "src/static/app/markdown/noticeBar.md",
    "content": "## NoticeBar 滚动通知 <to-api/>\n\n<demo-model url=\"/pages/componentsB/noticeBar/index\"></demo-model>\n\n\n该组件用于滚动通告场景，有多种模式可供选择\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n- 通过`list`数组参数设置需要滚动的内容\n- 滚动`mode`参数有两种模式，分别是`horizontal`水平滚动，`vertical`垂直滚动。其中水平滚动又可以通过`is-circular`来配置是衔接滚动(`true`)还是步进滚动(`false`)，\n衔接滚动滚动会把`list`数组元素拼接成一个字符串形式进行滚动，步进滚动模式类似轮播图水平滚动的形式，具体效果请见实例\n\n```html\n<template>\n\t<view>\n\t\t<u-notice-bar mode=\"horizontal\" :list=\"list\"></u-notice-bar>\n\t\t\n\t\t<u-notice-bar mode=\"horizontal\" :is-circular=\"false\" :list=\"list\"></u-notice-bar>\n\t\t\n\t\t<u-notice-bar mode=\"vertical\" :list=\"list\"></u-notice-bar>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tlist: [\n\t\t\t\t\t'寒雨连江夜入吴',\n\t\t\t\t\t'平明送客楚山孤',\n\t\t\t\t\t'洛阳亲友如相问',\n\t\t\t\t\t'一片冰心在玉壶'\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 配置主题\n\n- 通过`type`参数可以配置5种主题，即`primary`、`warning`(默认)、`error`、`info`、`success`、`none`\n\n说明：`none`主题默认没有背景颜色\n\n```html\n<u-notice-bar type=\"error\" :list=\"list\"></u-notice-bar>\n```\n\n### 配置图标\n\n- `volume-icon`参数配置是否显示左侧的音量小喇叭图标，默认显示\n- `more-icon`配置是否显示右侧的向右箭头，默认关闭\n- `close-icon`配置是否显示关闭的图标，默认关闭\n\n```html\n<u-notice-bar :volume-icon=\"false\" :list=\"list\"></u-notice-bar>\n\n<u-notice-bar :more-icon=\"true\" :list=\"list\"></u-notice-bar>\n\n<u-notice-bar :close-icon=\"true\" :list=\"list\"></u-notice-bar>\n```\n\n### 配置滚动速度\n\n- `mode`为`vertical`(垂直滚动)，或者`mode`为`horizontal`且`is-circular`为`false`时，两者都可视为\"步进\"滚动，此时通过`duration`设置滚动周期时长\n- `mode`为`horizontal`且`is-circular`为`true`时，可视为\"水平衔接滚动\"，此时uView加入了一个滚动因子参数，可确保在任意多内容情况下，滚动速度恒定不变，\n可通过`speed`参数配置每秒滚动的距离，单位为`rpx`\n\n```html\n<u-notice-bar :mode=\"vertical\" :duration=\"1500\" :list=\"list\"></u-notice-bar>\n\n<u-notice-bar :mode=\"vertical\" :is-circular=\"false\" :duration=\"1500\" :list=\"list\"></u-notice-bar>\n\n<u-notice-bar :mode=\"vertical\" :is-circular=\"true\" :speed=\"200\"  :list=\"list\"></u-notice-bar>\n```\n\n### 控制滚动的开始和暂停\n\n- `autoplay`参数默认为`true`，控制是否自动播放滚动通告\n- `play-state`参数为`paused`，滚动会暂停，为`play`滚动继续播放\n\n```html\n<u-notice-bar :autoplay=\"true\" play-state=\"paused\" :list=\"list\"></u-notice-bar>\n```\n\n### 事件回调\n\n- `more-icon`参数为`true`时，点击向右图标会回调一个`getMore`事件\n- `close-icon`参数为`true`时，点击关闭箭头图标会触发一个`close`事件\n- 点击通告栏的文字时，会触发`click`事件，回调参数为当前文字所在`list`数组参数的索引值\n\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| list | 滚动内容，数组形式，见上方说明 | Array | - | - |\n| type | 显示的主题  | String | warning | primary / info / error / success / none |\n| volume-icon | 是否显示小喇叭图标 | Boolean | true | false |\n| more-icon | 是否显示右边的向右箭头 | Boolean | false | true |\n| close-icon | 是否显示关闭图标 | Boolean | false | true |\n| autoplay | 是否自动播放 | Boolean | true | false |\n| color | 文字颜色 | String | - | - |\n| bg-color | 背景颜色 | String \\| Number | - | - |\n| mode | 滚动模式 | String | horizontal(水平滚动) | vertical(垂直滚动) |\n| show | 是否显示 | Boolean | true | false |\n| volume-size | 左边喇叭的大小 | String \\| Number | 34 | - |\n| font-size | 字体大小，单位rpx | String \\| Number | 28 | - |\n| duration | 滚动周期时长，只对步进模式有效，横向衔接模式无效，单位ms | String \\| Number | 2000 | - |\n| speed | 水平滚动时的滚动速度，即每秒移动多少距离，只对水平衔接方式有效，单位rpx | String \\| Number | 160 | - |\n| is-circular | `mode`为`horizontal`时，指明是否水平衔接滚动 | Boolean | true | false |\n| play-state | 播放状态，play - 播放，paused - 暂停 | String | play | paused |\n| disable-touch | 是否禁止通过手动滑动切换通知，只有mode = vertical，或者mode = horizontal且is-circular = false时有效；只支持App 2.5.5+、H5 2.5.5+、支付宝小程序、字节跳动小程序| Boolean | true | false |\n| padding | 内置滚动通知的内边距，字符串，类似\"16rpx 20rpx\" | String | 18rpx 24rpx | - |\n| border-radius | 圆角值，单位rpx | String \\ Number | 0 | - |\n| no-list-hidden | `list`为空数组时，是否显示组件 | Boolean | true | false |\n\n\n### Events\n\n详细解释见上方说明\n\n| 事件名 | 说明 | 回调参数 | 版本 |\n| :- | :- | :- | :- |\n| click | 点击通告文字触发，只有mode = vertical，或者mode = horizontal且is-circular = false时有效 | index：当前文字所在`list`数组的索引值 | - |\n| close | 点击右侧关闭图标触发 | - | - |\n| getMore | 点击右侧向右图标触发 | - | - |\n| end | 列表的消息每次被播放一个周期时触发，只有mode = vertical，或者mode = horizontal且is-circular = false时有效 | - | - |\n"
  },
  {
    "path": "src/static/app/markdown/npmSetting.md",
    "content": "## npm 安装方式配置 <to-api/>\n\n<!-- ### 关于SCSS\n\nuView依赖SCSS，您必须要安装此插件，否则无法正常运行。\n\n- 如果您的项目是由`HBuilder X`创建的，相信已经安装scss插件，如果没有，请在HX菜单的 工具->插件安装中找到\"scss/sass编译\"插件进行安装，\n如不生效，重启HX即可\n- 如果您的项目是由vue-cli创建的，请通过以下命令安装对sass(scss)的支持，如果已安装，请略过。\n\n```js\n// 安装node-sass\nnpm i node-sass -D\n\n// 安装sass-loader\nnpm i sass-loader -D\n``` -->\n\n### 准备工作\n\n在进行配置之前，请确保您已经根据[安装](/components/install.html)中的步骤对 uView 进行了 npm 安装，如果没有，请先执行安装：\n\n```js\n// 如果您的项目是HX创建的，根目录又没有package.json文件的话，请先执行如下命令：\n// npm init -y\n\n// npm 安装\nnpm install uview-pro\n// yarn 安装\nyarn add uview-pro\n// pnpm 安装\npnpm add uview-pro\n```\n\n### 配置步骤\n\n#### 1. 引入 uView 主库\n\n在项目根目录中的`main.ts`中，引入并使用 uView 的工具库，注意这两行要放在`import Vue`之后。\n\n```js\n// main.ts\nimport { createSSRApp } from \"vue\";\nimport uViewPro from \"uview-pro\";\n\nexport function createApp() {\n  const app = createSSRApp(App);\n  app.use(uViewPro);\n  // 其他配置\n  return {\n    app,\n  };\n}\n```\n\n#### 2. 在引入 uView 的全局 SCSS 主题文件\n\n在项目根目录的`uni.scss`中引入此文件。\n\n```css\n/* uni.scss */\n@import \"uview-pro/theme.scss\";\n```\n\n#### 3. 引入 uView 基础样式\n\n\n在`App.vue`中**首行**的位置引入，注意给 style 标签加入 lang=\"scss\"属性\n\n\n```css\n<style lang=\"scss\">\n\t/* 注意要写在第一行，同时给style标签加入lang=\"scss\"属性 */\n\t@import \"uview-pro/index.scss\";\n</style>\n```\n\n#### 4. 配置 easycom 组件模式\n\n此配置需要在项目根目录的`pages.json`中进行。\n\n\n\n1. uni-app 为了调试性能的原因，修改`easycom`规则不会实时生效，配置完后，您需要重启 HX 或者重新编译项目才能正常使用 uView 的功能。\n2. 请确保您的`pages.json`中只有一个`easycom`字段，否则请自行合并多个引入规则。\n3. 注意一定要放在`custom`里，否则无效，https://ask.dcloud.net.cn/question/131175\n\n\n\n```json\n// pages.json\n{\n  \"easycom\": {\n    // 注意一定要放在custom里，否则无效，https://ask.dcloud.net.cn/question/131175\n    \"custom\": {\n      \"^u-(.*)\": \"uview-pro/components/u-$1/u-$1.vue\"\n    }\n  },\n  // 此为本身已有的内容\n  \"pages\": [\n    // ......\n  ]\n}\n```\n"
  },
  {
    "path": "src/static/app/markdown/numberBox.md",
    "content": "## NumberBox 步进器 <to-api/>\n\n<demo-model url=\"/pages/componentsC/numberBox/index\"></demo-model>\n\n\n该组件一般用于商城购物选择物品数量的场景\n\n注意：该输入框只能输入大于或等于0的整数，不支持小数输入\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n通过`v-model`绑定`value`初始值，此值是双向绑定的，**无需**在回调中将返回的数值重新赋值给`value`。\n\n```html\n<template>\n\t<u-number-box v-model=\"value\" @change=\"valChange\"></u-number-box>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tvalue: 0\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\tvalChange(e) {\n\t\t\t\tconsole.log('当前值为: ' + e.value)\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 步长设置\n\n- 通过`step`属性设置每次点击增加或减少按钮时变化的值，默认为1\n\n**注意：** 自`1.4.5`版本起，`step`参数支持小数值，如`1.1`、`0.3`等\n\n下面示例每次都会加2或者减2\n\n```html\n<u-number-box :step=\"2\"></u-number-box>\n```\n\n### 限制输入范围\n\n通过`min`和`max`参数限制输的入值最小值和最大值\n\n```html\n<u-number-box :min=\"1\" :max=\"100\"></u-number-box>\n```\n\n### 禁用状态\n\n通过设置`disabled`参数来禁用输入框，禁用状态下无法点击加减按钮或修改输入框的值\n\n```html\n<u-number-box :disabled=\"true\"></u-number-box>\n```\n\n### 自定义大小\n\n- 通过`input-width`参数设置输入框的宽度\n- 通过`input-height`参数设置输入框和按钮的高度，单位都是rpx\n\n```html\n<u-number-box :input-width=\"100\" :input-height=\"60\"></u-number-box>\n```\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| v-model | 输入框初始值 | Number | 1 | - |\n| bg-color | 输入框和按钮的背景颜色  | String | #F2F3F5 | - |\n| min | 用户可输入的最小值 | Number | 0 | - |\n| max | 用户可输入的最大值 | Number | 99999 | - |\n| step | 步长，每次加或减的值，<Badge text=\"1.4.5\" />起支持小数值，如需小数，请设置`positive-integer`为`false` | Number | 1 | - |\n| disabled | 是否禁用操作，禁用后无法加减或手动修改输入框的值 | Boolean | false | true |\n| size | 输入框文字和按钮字体大小，单位rpx | String \\| Number | 26 | - |\n| color | 输入框文字和加减按钮图标的颜色 | String | #323233 | - |\n| input-width | 输入框宽度，单位rpx | String \\| Number | 80 | - |\n| input-height | 输入框和按钮的高度，单位rpx | String \\| Number | 50 | - |\n| index | 事件回调时用以区分当前发生变化的是哪个输入框 | String \\| Number | - | - |\n| disabled-input | 是否禁止输入框手动输入值 | Boolean | false | true |\n| cursor-spacing | 指定光标于键盘的距离，避免键盘遮挡输入框，单位rpx | String \\| Number | 200 | - |\n| long-press | 是否开启长按连续递增或递减 | Boolean | true | false |\n| press-time  | 开启长按触发后，每触发一次需要多久，单位ms | String \\| Number | 250 | - |\n| positive-integer | 是否只能输入正整数 | Boolean | true | false |\n\n\n### Events\n\n| 事件名 | 说明 | 回调参数 | 版本 |\n| :- | :- | :- | :- |\n| change | 输入框内容发生变化时触发，对象形式 | value：输入框当前值，index：通过props传递的`index`值 | - |\n| blur | 输入框失去焦点时触发，对象形式 | value：输入框当前值，index：通过props传递的`index`值 | - |\n| minus | 点击减少按钮时触发(按钮可点击情况下)，对象形式 | value：输入框当前值，index：通过props传递的`index`值 | - |\n| plus | 点击增加按钮时触发(按钮可点击情况下)，对象形式 | value：输入框当前值，index：通过props传递的`index`值 | - |\n| blur  | 输入框失去焦点时触发，对象形式 | value：输入框当前值，index：通过props传递的`index`值 | - |\n\n\n<style scoped>\nh3[id=props] + table thead tr th:nth-child(2){\n\twidth: 40%;\n}\n\nh3[id=events] + table thead tr th:nth-child(2){\n\twidth: 40%;\n}\n\nh3[id=events] + table thead tr th:nth-child(3){\n\twidth: 40%;\n}\n</style>"
  },
  {
    "path": "src/static/app/markdown/nvue.md",
    "content": "## Nvue 特性相关\n\n前言：uView 在 1.x 版本，只有部分组件支持`nvue`，不推荐在`nvue`项目中使用，uView Pro 也不建议在`nvue`项目中使用，我们在这里做一个专题，列出一些`nvue`上的坑，希望能帮助到您。\n\n### Text 组件\n\n- 我们在`vue`中，可以将文本相关的内容放到`view`或者`text`组件，这都是没问题的，但是在`nvue`中，需要动态响应(双向绑定)的内容，必须放在`text`标签，如果放在`view`可以正常显示，但是无法双向绑定。\n\n- 在`nvue`中，文本的样式无法继承父元素的颜色(color)，必须具体到给每一个`text`元素定义类名，在通过指定的类名给赋予颜色值，其他类似出现不能继承父组件的情况，也可参考此做法。\n\n- 在`nvue`中，`text`组件不能换行写内容，否则会出现无法去除的周边空白内容(类似被加上了`padding`或者`margin`的效果)，如下：\n\n```html\n<!-- nvue中错误写法 -->\n<text> 桃花潭水深千尺 </text>\n\n<!-- nvue中正确写法 -->\n<text>不及汪伦送我情</text>\n```\n\n### 事件冒泡\n\n`weex`事件冒泡相关文档 —— [事件冒泡](https://weex.apache.org/zh/docs/events/event-bubbling.html#%E9%98%BB%E6%AD%A2%E5%86%92%E6%B3%A1)\n\n在`weex`原文中，需要给给页面(组件)根元素设置`bubble=\"true\"`才能产生事件冒泡机制，但是在`uni-app`的`nvue`中，已自动加上类似`bubble=\"true\"`的操作，无需用户额外干预，自动就会获得事件冒泡的机制。另外，在 nvue 中，我们可以通过如下方式阻止事件冒泡：\n\n```html\n<template>\n    <view @tap=\"parentClick\">\n        <text @tap=\"childClick\">\n    </view>\n</template>\n\n<script>\n    export default {\n        methods: {\n            childClick(e) {\n                console.log('内部被点击')\n                e.stopPropagation()\n            },\n            parentClick() {\n                console.log('父元素将不会捕获冒泡事件')\n            }\n        }\n    }\n</script>\n```\n\n### line-height\n\n在`nvue`中，`line-height`与字体大小`font-size`无关，如果赋予数值，单位默认为`px`，这意味着不可以如下使用：\n\n```css\n.box {\n  /* vue正常，nvue中会导致行高只有1px */\n  line-height: 1;\n}\n```\n\n### 样式穿透\n\n在`weex`(`nvue`)中有如此描述：[在 Weex 里， 每一个 Vue 组件的样式都是 scoped](https://weex.apache.org/zh/guide/use-vue-in-weex.html#%E5%B9%B3%E5%8F%B0%E7%9A%84%E5%B7%AE%E5%BC%82)，这说明`vue`中的的`/deep/`和`::v-deep`在`nvue`中都是无效，修改子组件样式只能通过传参进行，而不能进行样式穿透。\n\n### 字体引入不能加引号\n\n`nvue`下，`font-family`的字体引入，不能加引号，否则会导致字体图标无法显示，如下：\n\n```css\n/* 错误写法 */\nfont-family: \"uicon-iconfont\";\n\n/* 正确写法 */\nfont-family: uicon-iconfont;\n```\n\n### Scss 中的:export 无效\n\n在`vue`中，我们可以通过`*.scss`中使用[:export](https://www.jianshu.com/p/069f4f79de16)进行变量导出，供`js`和`css`共同使用变量，但是`nvue`中不支持此写法，请勿使用。\n\n### transition 属性不能简写\n\n在`vue`中，我们可以很方便的简写`transition`属性，但是`nvue`中，必须分开写才有效，如下：\n\n- [weex 文档关于 transition 的描述](https://weex.apache.org/zh/docs/styles/common-styles.html#transition)\n\n```css\n/* 如下写法，vue有效，nvue无效 */\ntransition: opacity 0.3s ease-in;\n\n/* nvue页面需要拆分成如下写法 */\ntransition-property: opacity;\ntransition-duration: 0.3s;\ntransition-timing-function: ease-in;\n```\n\n### box-shadow\n\n据关于[weex 关于 box-shadow 文档](https://weex.apache.org/zh/docs/styles/common-styles.html#%E9%98%B4%E5%BD%B1-box-shadow)描述，`weex`不支持`android`上的`box-shadow`属性，但是经实测，在`nvue`(uni-app 改良后台的`weex`)上`android`，是支持的`box-shadow`属性效果的。\n\n需要说明的是，在`IOS`上，目前(2020-10-30)不允许将`box-shadow`值设置为`none`，否则会出现锐利的高亮白色边框，由于`nvue`支持`rgba`透明度，我们可以通过如下方式实现类似`none`的效果：\n\n```css\n.box {\n  box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);\n}\n```\n\n### border-radius\n\n[在`weex`文档中有明确的说明](https://weex.apache.org/zh/docs/styles/common-styles.html#border-radius)，`border-radius`支持简写形式，但是在`nvue`的`android`端，`border-radius`必须分开写才有效，如下：\n\n```css\n/* nvue下，安卓不支持此写法 */\n.box {\n  border-radius: 10px;\n}\n\n/* 必须如下写法才能兼容 */\n.box {\n  border-bottom-left-radius: 10px;\n  border-bottom-right-radius: 10px;\n  border-top-left-radius: 10px;\n  border-top-right-radius: 10px;\n}\n```\n\n### 关于<template\\/> 和 <block\\/>\n\n以下文字取自 uni-app 文档原文，[点此查看](https://uniapp.dcloud.io/frame?id=template-block)：\n\n```\n`<template/>` 和 `<block/>` 并不是一个组件，它们仅仅是一个包装元素，不会在页面中做任何渲染，只接受控制属性。\n`<block/>` 在不同的平台表现存在一定差异，推荐统一使用 `<template/>`。\n```\n\n上面说，二者不会在页面做任何的渲染，但是在`nvue`中，`<block/>`确确实实被渲染成为一个`<block/>`元素，由于`nvue`默认`flex`布局，且为\n`column`竖向布局，这可能会导致`<block/>`标签下存在多个其他元素时，这些元素会竖向排列，您不得不额外对`<block/>`元素设置样式，所以我们建议只要是`nvue`的场景，一律使用`<template/>`而不是`<block/>` 标签\n"
  },
  {
    "path": "src/static/app/markdown/parse.md",
    "content": " ## Parse 富文本解析器 <Badge text=\"该组件已废弃\" type=\"error\" />\n\n 建议使用 `mp-html` 或其他，`mp-html` 开源地址：[https://github.com/jin-yufeng/mp-html](https://github.com/jin-yufeng/mp-html)\n\n<!-- ## Parse 富文本解析器 <to-api/>\n\n<demo-model url=\"/pages/componentsA/parse/index\"></demo-model>\n\n该组件一般用于富文本解析场景，比如解析文章内容，商品详情，带原生 HTML 标签的各类字符串等，此组件和 uni-app 官方的`rich-text`组件功能有重合之处，但是也有不同的地方。\n\n#### 相同点：\n\n- 二者都能解析 HTML 字符串\n\n#### 不同点：\n\n- 对于轻量、简单的字符串，`rich-text`性能更好\n- 对于复杂的字符串，使用`parse`组件效果更好，有更多的自定义属性和效果\n\n总结：如果是简单的场景，比如一段简单的文字和图片内容，可以优先使用`rich-text`组件，在文章内容，商品详情等复杂的文本详情，可以优先使用`parse`组件。\n\n\n此组件源于开源的优秀作品[Parser](https://jin-yufeng.github.io/Parser/#/)，本文档只对重要的功能进行介绍，如果需要更详细的说明，请参考[Parser](https://jin-yufeng.github.io/Parser/#/)官方文档。\n\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ 小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :-------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |     √     |\n\n### 基本使用\n\n通过`html`参数绑定需要解析的内容即可。\n\n```html\n<template>\n  <view class=\"u-content\">\n    <u-parse :html=\"content\"></u-parse>\n  </view>\n</template>\n\n<script>\n  export default {\n    data() {\n      return {\n        content: `\n\t\t\t\t\t<p>露从今夜白，月是故乡明</p>\n\t\t\t\t\t<img src=\"https://cdn.uviewui.com/uview/xxx.jpg\" />\n\t\t\t\t`,\n      };\n    },\n  };\n</script>\n\n<style lang=\"scss\" scoped>\n  .u-content {\n    margin-top: 100rpx;\n  }\n</style>\n```\n\n### 长按复制\n\n可以通过设置`selectable`参数为`true`来实现长按复制的效果\n\n```html\n<u-parse :html=\"content\" :selectable=\"true\"></u-parse>\n```\n\n### 设置样式\n\n可以有两种方法可设置富文本的样式：\n\n- 通过组件的`tag-style`参数可以精细化的对单独的标签设置样式，注意此方式设置的样式为**字符串**的形式，而非**对象**形式：\n\n```html\n<template>\n  <view class=\"u-content\">\n    <u-parse :html=\"content\" :tag-style=\"style\"></u-parse>\n  </view>\n</template>\n\n<script>\n  export default {\n    data() {\n      return {\n        content: `\n\t\t\t\t\t<p>露从今夜白，月是故乡明</p>\n\t\t\t\t\t<img src=\"https://cdn.uviewui.com/uview/xxx.jpg\" />\n\t\t\t\t`,\n        style: {\n          // 字符串的形式\n          p: \"color: red;font-size:32rpx\",\n          span: \"font-size: 30rpx\",\n        },\n      };\n    },\n  };\n</script>\n```\n\n- 通过父元素标签，统一设置全文的颜色，行高，字体大小等，注意这种方式无法对单独的标签设置样式：\n\n```html\n<template>\n  <view class=\"u-content\">\n    <u-parse :html=\"content\"></u-parse>\n  </view>\n</template>\n\n<script>\n  export default {\n    data() {\n      return {\n        content: `\n\t\t\t\t\t<p>露从今夜白，月是故乡明</p>\n\t\t\t\t\t<img src=\"https://cdn.uviewui.com/uview/xxx.jpg\" />\n\t\t\t\t`,\n      };\n    },\n  };\n</script>\n\n<style lang=\"scss\" scoped>\n  .u-content {\n    margin-top: 100rpx;\n    color: $u-content-color;\n    font-size: 32rpx;\n    line-height: 1.8;\n\n    // 标签形式无效\n    p {\n      color: $u-tips-color;\n    }\n  }\n</style>\n```\n\n### 懒加载和占位图\n\n- 设置`lazy-load`为`true`即可开启图片懒加载功能\n- 设置`loading-img`为网络路径或者 base64 图片，可以在图片加载完成前展示占位图\n\n```html\n<u-parse\n  :html=\"content\"\n  :lazy-load=\"true\"\n  :loading-img=\"/xxx/xxx.jpg\"\n></u-parse>\n```\n\n### 渐变动画\n\n设置`show-with-animation`为`true`，可以让内容展示时，获得一个淡入的效果。\n\n```html\n<u-parse :html=\"content\" :show-with-animation=\"true\"></u-parse>\n```\n\n<br>\n\n### 图片预览\n\n无需配置，点击图片，即可获得图片预览功能\n\n<br>\n\n### 链接跳转\n\nH5、App（含 NVUE）外链可以直接打开，小程序端将自动复制链接  \n小程序端`a`标签设置`app-id`后可以跳转到其他小程序\n\n<br>\n\n### 其他配置\n\n本组件还有其他更多的配置功能，如获取页面的所有图片数组，跳转页内锚点，视频播放等，如需更多的配置信息，请移步`parser`插件文档：[parser 文档](https://jin-yufeng.github.io/Parser/#/)\n\n<br>\n\n### API\n\n### Props\n\n| 参数                | 说明                                                | 类型    | 默认值 | 可选值    |\n| ------------------- | --------------------------------------------------- | ------- | ------ | --------- |\n| html                | 要显示的 html 字符串                                | String  | -      | -         |\n| autopause           | 是否允许播放视频时自动暂停其他视频                  | Boolean | true   | false     |\n| autoscroll          | 是否自动给 table 加一个滚动层（使表格可以单独滚动） | Boolean | false  | true      |\n| autosetTitle        | 是否自动将 title 标签的内容设置到页面标题           | Boolean | true   | false     |\n| compress            | 压缩等级，可以选择是否移除 id 和 class(不建议修改)  | Number  | 0      | 1 / 2 / 3 |\n| domain              | 主域名，设置后将给链接自动拼接上主域名或协议名      | String  | -      | -         |\n| lazy-load           | 是否开启图片懒加载                                  | Boolean | false  | true      |\n| loading-img         | 图片加载完成前的占位图，详见 占位图                 | String  | -      | -         |\n| selectable          | 是否允许长按复制内容                                | Boolean | false  | true      |\n| show-with-animation | 是否使用渐显动画                                    | Boolean | false  | true      |\n| tag-style           | 设置标签的默认样式                                  | Object  | -      | -         |\n| use-anchor          | 是否使用页面内锚点                                  | Boolean | false  | true      |\n| use-cache           | 是否使用缓存，设置后多次打开不用重复解析            | Boolean | false  | true      |\n\n### Event\n\n| 事件名    | 说明               | 回调参数                                                                                                                                       |\n| :-------- | :----------------- | :--------------------------------------------------------------------------------------------------------------------------------------------- |\n| parse     | 解析完成时触发     | 返回解析结果，可以对该结果进行自定义修改，将在渲染时生效                                                                                       |\n| load      | dom 加载完成时触发 | 所有节点被添加到节点树中时触发，无返回值，可以调用 api                                                                                         |\n| ready     | 渲染完成时触发     | 返回 boundingClientRect 的查询结果（包含宽高、位置等信息），所有图片（除懒加载）加载完成时才会触发，图片较大时可能 延时较长                    |\n| error     | 出错时触发         | 返回一个 object，其中 source 是错误来源，errMsg 为错误信息，target 包含出错标签的具体信息                                                      |\n| imgtap    | 图片被点击时触发   | 返回一个 object，其中 src 是图片链接，ignore 是一个函数，在事件中调用将不进行预览；可用于阻挡 onShow 的调用                                    |\n| linkpress | 在链接被点击时触发 | 返回一个 object，其中包含了被点击的 a 标签的所有属性，ignore 是一个函数，在事件中调用后将不自动跳转/复制；可在该事件中进行下载文档等进一步操作 |\n\n<style scoped>\nh3[id=event] + table thead tr th:nth-child(2){\n\twidth: 20%;\n}\nh3[id=event] + table thead tr th:nth-child(3){\n\twidth: 60%;\n}\n</style> -->\n"
  },
  {
    "path": "src/static/app/markdown/picker.md",
    "content": "## Picker 选择器 <to-api/>\n\n<demo-model url=\"/pages/componentsB/picker/index\"></demo-model>\n\n\n此选择器有四种弹出模式\n\n1. 一是时间模式，可以配置年，日，月，时，分，秒参数\n2. 二是地区模式，可以配置省，市，区参数\n3. 三是单列模式\n4. 四是多列模式\n\n\n从`1.3.0`版本起，不建议使用此组件的单列和多列模式，因为已经有更友好，简单易用，专门用于处理列选择的[Select 列选择器](/components/select.html)组件，\n以后此组件将专注于时间和地区的选择。\n\n\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |    √     |\n\n### 基本使用\n\n\n- 通过`mode`参数设置为`time`、`region`、`selector`、`multiSelector`，区分时间、地区、单列，多列模式。\n- 通过v-model双向绑定一个值为布尔值的变量，来打开或者收起picker。\n\n```html\n<template>\n\t<view>\n\t\t<u-picker v-model=\"show\" mode=\"time\"></u-picker>\n\t\t<u-button @click=\"show = true\">打开</u-button>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tshow: false\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 一、时间和地区模式\n\n#### 1. 设置默认值\n\n- 如果`mode`为`time`，可以通过`default-time`参数设置打开时的默认时间，格式如\"2025-07-02 13:01:00\"、\"2025-07-02 13:01\"\n- 如果`mode`为`region`，可以通过`default-region`(Array格式)中文的省市区名称，如：`[\"河北省\", \"秦皇岛市\", \"北戴河区\"]`，或者代号的\n省市区，如：`[\"13\", \"1303\", \"130304\"]`。\n\n\n**注意**：这些省市区的名称和代码，须是uView的`Picker`组件自身提供的，否则可能无法匹配\n\n```html\n<template>\n\t<u-picker mode=\"time\" v-model=\"show\"></u-picker>\n\t\n\t<u-picker mode=\"region\" v-model=\"show\" :area-code='[\"13\", \"1303\", \"130304\"]'></u-picker>\n</template>\n```\n\n#### 2. 设置需要显示的参数\n\n- 时间模式时：通过`params`参数传入一个对象给组件，给需要显示的参数属性置为`true`，可选的参数有：`year`、`month`、`day`、`hour`、`minute`、`second`。\n其中，`hour`、`minute`、`second`值默认为`false`，其他值默认为`true`\n- 地区模式时：可选的参数有：`province`、`city`、`area`，默认都为`true`\n\n下方示例时间模式，只会显示年，月，日3个参数可供选择：\n\n```html\n<template>\n\t<u-picker mode=\"time\" v-model=\"show\" :params=\"params\"></u-picker>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tparams: {\n\t\t\t\t\tyear: true,\n\t\t\t\t\tmonth: true,\n\t\t\t\t\tday: true,\n\t\t\t\t\thour: false,\n\t\t\t\t\tminute: false,\n\t\t\t\t\tsecond: false\n\t\t\t\t},\n\t\t\t\tshow: false\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n#### 3. 回调参数\n\n当点击`picker`的\"取消\"或者\"确定\"按钮时，会分别产生回调事件`cancel`和`confirm`，均为会返回组件内部的当前值。回调的参数为一个对象，属性和传递给`picker`组件的`params`对象为`true`的属性一致。   \n\n注意：`mode`为`region`时，回调对象属性为一个对象，分别有`label`和`value`属性，见如下说明：\n\n```js\n// 组件内部parmas参数默认值：\nlet params = {\n\tyear: true,\n\tmonth: true,\n\tday: true,\n\thour: false,\n\tminute: false,\n\tsecond: false,\n\tprovince: true,\n\tcity: true,\n\tarea: true,\n\ttimestamp: true, // 1.3.7版本提供\n}\n\n\n// 如果params值如下(时间选择模式)：：\nlet params = {\n\tyear: true,\n\tmonth: true,\n\tday: true,\n\thour: false,\n\tminute: false,\n\tsecond: false,\n\t// 选择时间的时间戳\n\ttimestamp: true,\n}\n\n// 那么回调的参数可能如下：\n{\n\tyear: '2020',\n\tmonth: '05',\n\tday: '10'\n}\n\n\n// 如果params值如下(地区选择模式)：\nlet params = {\n\tprovince: true,\n\tcity: true,\n\tarea: true\n}\n\n// 那么回调的参数可能如下：\n{\n\tarea: {\n\t\tlabel: \"宝安区\",\n\t\tvalue: \"440306\"\n\t},\n\tcity: {\n\t\tlabel: \"深圳市\",\n\t\tvalue: \"4403\"\n\t},\n\tprovince: {\n\t\tlabel: \"广东省\",\n\t\tvalue: \"44\"\n\t},\n}\n```\n\n### 二、单列和多列模式\n\n**从`1.3.0`版本起，不建议使用此组件的单列和多列模式，因为已经有更友好，简单易用，专门用于处理列选择的[Select 列选择器](/components/select.html)组件。**\n\n#### 1. 设置默认值\n\n- 如果`mode`为`selector`(单列)，可以通过设置`default-selector`为单元素的数组，表示选中单列中的第几个(索引从0开始)，如: `[1]`表示选中单列的第二个。\n- 如果`mode`为`multiSelector`(多列)，可以通过设置`default-selector`为多元素的数组(元素数量等于列数)，分别表示选中每一列的第几个(索引从0开始)，如`[0, 1, 2]`\n表示共有3列，分别选中第一列的第一个，第二列的第二个，第三列的第三个。\n\n```html\n<template>\n\t<u-picker mode=\"selector\" v-model=\"show\"  :default-selector=\"[0]\"></u-picker>\n\t\n\t<u-picker mode=\"multiSelector\" v-model=\"show\"  :default-selector='[0, 1, 3]'></u-picker>\n</template>\n```\n\n\n#### 2. 设置数据\n\n由于单列和多列模式不像时间和地区模式，没有内置数据，故需要您手动传入可选值，通过`range`参数(数组)传入对应的数据，单列时为一维数组，多列时为二维数组。\n\n如果您数组中的元素为对象的话，可以通过指定`range-key`参数，让组件内部知道您想把对象的哪个属性当做要显示的值。\n\n```html\n<template>\n\t<view class=\"\">\n\t\t<u-picker mode=\"selector\" v-model=\"show\"  :default-selector=\"[0]\" :range=\"selector\"></u-picker>\n\t\t\n\t\t<u-picker mode=\"selector\" v-model=\"show\"  :default-selector=\"[0]\" :range=\"selectorObj\" range-key=\"cateName\"></u-picker>\n\t\t\n\t\t<u-picker mode=\"multiSelector\" v-model=\"show\"  :default-selector='[0, 1]' :range=\"multiSelector\"></u-picker>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tshow: true,\n\t\t\t\tselector: [1, 2, 3],\n\t\t\t\tmultiSelector: [\n\t\t\t\t\t[1, 2, 3], \n\t\t\t\t\t[4, 5, 6]\n\t\t\t\t],\n\t\t\t\t// 这种情况需要指定range-key为cateName，否则组件不知道该显示对象的哪个属性\n\t\t\t\tselectorObj: [\n\t\t\t\t\t{\n\t\t\t\t\t\tcateName: '1',\n\t\t\t\t\t\tid: 1\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tcateName: '2',\n\t\t\t\t\t\tid: 2\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n#### 3. 回调参数\n\n当点击`picker`的\"取消\"或者\"确定\"按钮时，会分别产生回调事件`cancel`和`confirm`，均为会返回组件内部的当前值。回调的参数为一个数组，分别表示\n当前各列选中的列索引值(从0开始)。\n\n- 单列模式\n\n回调参数可能为`[3]`，表示选中传入数组的第四个值(从0开始)\n\n- 多列模式\n\n回调参数可能为`[1, 0, 3]`，表示3列中，第一列选中了第二个值，第二列选中了第一个值，第三列选中了第四个值。  \n\n其中，我们使用多列模式，一般都需要联动选择，在多列模式下，有一个`columnchange`事件，任意列改变都会触发该事件，回调参数为`{column: column, index: index}`，\n`column`表示第几列发生了变化(从0开始)，`index`表示当前的下标值，如`{column: 1, index: 2}`表示第二列(从0开始)发生了变化，下标变成了`2`，您可以\n根据这个回调，对应的修改`default-selector`参数，让多列中的其他列联动起来。\n\n此处演示较为复杂，请见uView的演示代码，在[安装](/components/install.html)页下载`演示项目`方式，内有所有演示的示例，是一个完整的HX工程。\n\n\n### API\n\n### Props\n\n注意：props中没有控制Picker打开与收起的参数，因为这是通过v-model绑定变量实现的，见上方说明。\n\n| 参数                   | 说明                                                                                                | 类型             | 默认值  | 可选值                            |\n| ---------------------- | --------------------------------------------------------------------------------------------------- | ---------------- | ------- | --------------------------------- |\n| params                 | 需要显示的参数，见上方说明，mode=region或mode=time时有效                                            | Object           | -       | -                                 |\n| mode                   | 模式选择，region-地区模式，time-时间模式，selector-单列模式，multiSelector-多列模式                 | String           | time    | region / selector / multiSelector |\n| start-year             | 可选的开始年份，mode=time时有效                                                                     | String \\| Number | 1950    | -                                 |\n| end-year               | 可选的结束年份，mode=time时有效                                                                     | String \\| Number | 2050    | -                                 |\n| safe-area-inset-bottom | 是否开启[底部安全区适配](/components/safeAreaInset.html#关于uview某些组件safe-area-inset参数的说明) | Boolean          | false   | true                              |\n| cancel-color           | 取消按钮的颜色                                                                                      | String           | #606266 | -                                 |\n| confirm-color          | 确认按钮的颜色                                                                                      | String           | #2979ff | -                                 | 6 |\n| default-time           | 默认选中的时间，mode=time时有效，需在`onReady`生命周期赋值，见顶部说明                              | String           | -       | -                                 |\n| default-region         | 默认选中的地区，中文形式，mode=region时有效，需在`onReady`生命周期赋值，见顶部说明                  | Array            | -       | -                                 |\n| area-code              | 默认选中的地区，编号形式，mode=region时有效                                                         | Array            | -       | -                                 |\n| default-selector       | 数组形式，其中每一项表示选择了`range`对应项中的第几个(下标从0开始)，见上方说明                      | Array            | []      | -                                 |\n| mask-close-able        | 是否允许通过点击遮罩关闭Picker                                                                      | Boolean          | true    | false                             |\n| show-time-tag          | 时间模式时，是否显示后面的年月日中文提示                                                            | Boolean          | true    | false                             |\n| z-index                | 弹出时的`z-index`值                                                                                 | String \\| Number | 10075   | -                                 |\n| range                  | 自定义选择的数据，mode=selector或mode=multiSelector时有效                                           | Array            | []      | -                                 |\n| range-key              | 当`range`参数的元素为对象时，指定Object中的哪个key的值作为选择器显示内容，见上方说明                | String           | -       | -                                 |\n| title                  | 顶部中间的标题                                                                                      | String           | -       | -                                 |\n| confirm-text           | 确认按钮的文字                                                                                      | String           | 确认    | -                                 |\n| cancel-text            | 取消按钮的文字                                                                                      | String           | 取消    | -                                 |\n\n\n\n### Events\n\n| 事件名       | 说明                                             | 回调参数                                                 | 版本 |\n| :----------- | :----------------------------------------------- | :------------------------------------------------------- | :--- |\n| confirm      | 点击确定按钮，返回当前选择的值                   | Object: 见上方\"回调参数\"部分说明                         | -    |\n| cancel       | 点击取消按钮，返回当前选择的值                   | Object: 见上方\"回调参数\"部分说明                         | -    |\n| columnchange | 列发生改变时触发，只对mode = multiSelector时有效 | {column: column, index: index}: 见上方\"回调参数\"部分说明 | -    |\n\n\n\n<style scoped>\nh3[id=props] + p + table thead tr th:nth-child(2){\n\twidth: 35%;\n}\n\nh3[id=events] + table thead tr th:nth-child(2){\n\twidth: 35%;\n}\n</style>"
  },
  {
    "path": "src/static/app/markdown/popup.md",
    "content": "## Popup 弹出层 <to-api/>\n\n<demo-model url=\"/pages/componentsC/popup/index\"></demo-model>\n\n\n弹出层容器，用于展示弹窗、信息提示等内容，支持上、下、左、右和中部弹出。组件只提供容器，内部内容由用户自定义\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |    √     |\n\n### 基本使用\n\n\n- 弹出层的内容通过`slot`传入，由用户自定义\n- 通过`v-model`绑定一个布尔值的变量控制弹出层的打开和收起\n\n\n```html\n<template>\n\t<view>\n\t\t<u-popup v-model=\"show\">\n\t\t\t<view>出淤泥而不染，濯清涟而不妖</view>\n\t\t</u-popup>\n\t\t<u-button @click=\"show = true\">打开</u-button>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tshow: false\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 设置弹出层的方向\n\n- 可以通过`mode`参数设置，可以设置为`left`、`top`、`right`、`bottom`、`center`\n\n```html\n<template>\n\t<u-popup v-model=\"show\" mode=\"top\">\n\t\t<view>\n\t\t\t人生若只如初见，何事秋风悲画扇\n\t\t</view>\n\t</u-popup>\n</template>\n```\n\n### 设置弹出层的圆角\n\n可以给`border-radius`设置一个值来给弹窗增加圆角，单位rpx。\n\n```html\n<template>\n\t<u-popup v-model=\"show\" mode=\"top\" border-radius=\"14\">\n\t\t<view>\n\t\t\t人生若只如初见，何事秋风悲画扇\n\t\t</view>\n\t</u-popup>\n</template>\n```\n\n\n### 控制弹窗的宽度 | 高度\n\n这里说的宽度，指的是左边，右边，中部弹出的场景，高度指的是顶部和底部弹出的场景(因为这两个场景宽度都是100%)。  \nuView提供了`length`来控制此种情况，此值可以是`数值`(单位rpx)，`auto`，`百分比`等，内部会自动处理对应的逻辑。\n如果为`auto`的时候，表示弹窗的宽度 | 高度由内容撑开。\n\n**1.3.7版本新增`width`和`height`参数：**\n\n1.3.7版本后，优先推荐`width`和`height`参数，并且优先级会高于`length`，这3个参数都可以设置`百分比`、`auto`、`数值`(单位rpx)、或者是带`px`和`rpx`单位的字符串：\n\n- `width`只对`mode = left | center | right`模式有效\n- `height`只对`mode = top | center | bottom`模式有效\n\n\n1.3.7版本后，内置了`scroll-view`元素，内如内容超出容器的高度，将会自动获得**垂直**滚动的特性，如果您因为在`slot`内容做了滚动的处理，而造成了\n冲突的话，请移除自定义关于滚动部分的逻辑。\n\n\n\n```html\n<template>\n\t<u-popup v-model=\"show\" mode=\"top\" length=\"60%\">\n\t\t<view>\n\t\t\t等闲变却故人心，却道故人心易变\n\t\t</view>\n\t</u-popup>\n\t\n\t<u-popup v-model=\"show\" mode=\"center\" width=\"500rpx\" height=\"600px\">\n\t\t<view>\n\t\t\t骊山语罢清宵半，泪雨霖铃终不怨\n\t\t</view>\n\t</u-popup>\n</template>\n```\n\n### 内容局部滚动\n\n如果您需要让弹窗中的内容局部滚动，局部固定，比如商城底部弹出SKU选择的场景，可以按如下思路进行处理： \n\n1. 在弹窗内容中放一个`scroll-view`组件，设置为竖向滚动，并指定高度(必须)\n2. 在`scroll-view`组件下方放一块无需滚动内容，如下：\n\n```html\n<template>\n\t<view class=\"\">\n\t\t<u-button @click=\"show = true;\">打开弹窗</u-button>\n\t\t<u-popup mode=\"bottom\" v-model=\"show\">\n\t\t\t<view class=\"content\">\n\t\t\t\t<scroll-view scroll-y=\"true\" style=\"height: 300rpx;\">\n\t\t\t\t\t<view>\n\t\t\t\t\t\t<view v-for=\"index in 20\" :key=\"index\">\n\t\t\t\t\t\t\t第{{index}}个Item\n\t\t\t\t\t\t</view>\n\t\t\t\t\t</view>\n\t\t\t\t</scroll-view>\n\t\t\t\t<view class=\"confrim-btn\">\n\t\t\t\t\t<u-button @click=\"show = false;\">确定</u-button>\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t</u-popup>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tshow: false\n\t\t\t}\n\t\t}\n\t}\n</script>\n\n<style lang=\"scss\" scoped>\n\t.content {\n\t\tpadding: 24rpx;\n\t\ttext-align: center;\n\t}\n</style>\n```\n\n\n### API\n\n### Props\n\n注意：props中没有控制弹窗打开与收起的参数，因为这是通过v-model绑定变量实现的，见上方说明。\n\n| 参数                   | 说明                                                                                                | 类型             | 默认值    | 可选值                                |\n| ---------------------- | --------------------------------------------------------------------------------------------------- | ---------------- | --------- | ------------------------------------- |\n| mode                   | 弹出方向                                                                                            | String           | left      | top / right / bottom / center         |\n| mask                   | 是否显示遮罩                                                                                        | Boolean          | true      | false                                 |\n| length                 | mode=left \\| 见上方说明                                                                             | String \\| Number | auto      | -                                     |\n| zoom                   | 是否开启缩放动画，只在`mode`为`center`时有效                                                        | Boolean          | true      | false                                 |\n| safe-area-inset-bottom | 是否开启[底部安全区适配](/components/safeAreaInset.html#关于uview某些组件safe-area-inset参数的说明) | Boolean          | false     | true                                  |\n| mask-close-able        | 点击遮罩是否可以关闭弹出层                                                                          | Boolean          | true      | false                                 |\n| custom-style           | 用户自定义样式                                                                                      | Object           | -         | -                                     |\n| border-radius          | 弹窗圆角值                                                                                          | Number \\| String | 0         | -                                     |\n| z-index                | 弹出内容的`z-index`值                                                                               | Number \\| String | 10075     | -                                     |\n| closeable              | 是否显示关闭图标                                                                                    | Boolean          | false     | true                                  |\n| close-icon             | 关闭图标的名称，只能uView的内置图标                                                                 | String           | close     | -                                     |\n| close-icon-pos         | 自定义关闭图标位置，top-left为左上角，top-right为右上角，bottom-left为左下角，bottom-right为右下角  | String           | top-right | top-left / bottom-left / bottom-right |\n| close-icon-color       | 关闭图标的颜色                                                                                      | String           | #909399   | -                                     |\n| close-icon-size        | 关闭图标的大小，单位rpx                                                                             | String \\| Number | 30        | -                                     |\n| width                  | mode = left \\| center \\| right时有效，优先级高于`length`                                            | String \\| Number | -         | -                                     |\n| height                 | mode = top \\| center \\| bottom时有效，优先级高于`length`                                            | String \\| Number | -         | -                                     |\n| negative-top           | 中部弹出时，以避免可能弹出的键盘重合，往上偏移的值，单位任意，数值则默认为rpx单位                   | String \\| Number | 0         | -                                     |\n| mask-custom-style      | 遮罩自定义样式，一般用于修改遮罩透明度对象形式，如：{background: 'rgba(0, 0, 0, 0.5)'}              | Object           | -         | -                                     |\n| duration               | 遮罩打开或收起的动画过渡时间，单位ms                                                                | String \\| Number | 250       | -                                     |\n\n\n### Event\n\n| 事件名 | 说明       | 回调参数 | 版本 |\n| :----- | :--------- | :------- | :--- |\n| open   | 弹出层打开 | -        | -    |\n| close  | 弹出层收起 | -        | -    |\n"
  },
  {
    "path": "src/static/app/markdown/queryParams.md",
    "content": "# queryParams 对象转URL参数\n\n<demo-model url=\"/pages/library/queryParams/index\"></demo-model>\n\n\n该方法，可以将一个对象形式参数转换成`get`传参所需参数形式，如把`{name: 'lisa', age: 20}`转换成`?name=lisa&age=20`  \n用途：可以用于`uni.navigateTo`接口传参等场景，无需自己手动拼接`URL`参数\n\n### queryParams(data, isPrefix = true, arrayFormat = 'brackets')\n\n\n- `data` <Object\\> 对象值，如`{name: 'lisa', age: 20}`  \n- `isPrefix` <Boolean\\> 是否在返回的字符串前加上\"?\"，默认为`true`\n- `arrayFormat` <Boolean\\> 属性为数组的情况下的处理办法，默认为`brackets`，见后面说明\n\n```js\nimport { ref, onMounted } from 'vue';\n\nconst queryParams = ref({\n  name: 'lisa',\n  age: 20\n});\n\nonMounted(() => {\n  console.log(uni.$u.queryParams(queryParams.value));\n  // 结果为：?name=lisa&age=20\n});\n```\n\n\n### arrayFormat参数说明\n \n如果您传入的`data`对象内部某些属性值为数组的情况下，您可能需要留意这个参数的配置：   \n该参数可选值有4个：`indices`，`brackets`，`repeat`，`comma`，具体效果请见下方的演示说明\n\n```js\nimport { ref, onMounted } from 'vue';\n\nconst queryParams = ref({\n  name: '冷月夜',\n  fruits: ['apple', 'banana', 'orange']\n});\n\nonMounted(() => {\n  console.log(uni.$u.queryParams(queryParams.value, true, 'indices'));\n  // 结果为：?name=冷月夜&fruits[0]=apple&fruits[1]=banana&fruits[2]=orange\n  \n  console.log(uni.$u.queryParams(queryParams.value, true, 'brackets'));\n  // 结果为：?name=冷月夜&fruits[]=apple&fruits[]=banana&fruits[]=orange\n  \n  console.log(uni.$u.queryParams(queryParams.value, true, 'repeat'));\n  // 结果为：?name=冷月夜&fruits=apple&fruits=banana&fruits=orange\n  \n  console.log(uni.$u.queryParams(queryParams.value, true, 'comma'));\n  // 结果为：?name=冷月夜&fruits=apple,banana,orange\n});\n```"
  },
  {
    "path": "src/static/app/markdown/quickstart.md",
    "content": "## 快速上手\n\n<demo-model url=\"/\"></demo-model>\n\n### 如何使用\n\n通过 npm 和下载方式的配置之后，在某个页面可以直接使用组件，无需通过`import`引入组件。\n\n```html\n<template>\n  <u-action-sheet :list=\"list\" v-model=\"show\"></u-action-sheet>\n</template>\n\n<script setup lang=\"ts\">\n  import { ref } from \"vue\";\n\n  interface ListItem {\n    text: string;\n    color?: string;\n    fontSize?: number;\n  }\n\n  const list = ref<ListItem[]>([\n    { text: \"点赞\", color: \"blue\", fontSize: 28 },\n    { text: \"分享\" },\n    { text: \"评论\" },\n  ]);\n\n  const show = ref(true);\n</script>\n```\n\n<br>\n\n### 关于 $u\n\nuView Pro 将`$u`对象同时挂载到了`uni`对象上，这意味着您可以在外部的`ts`文件中，通过`uni.$u.xxx`的形式去调用 uView 提供的一些工具方法。\n\n或则您在使用 `$u` 时，先导入再使用：\n\n```html\n<script setup lang=\"ts\">\n  import { $u } from \"uview-pro\";\n\n  function func() {\n    $u.toast(\"hello world\");\n  }\n</script>\n```\n\n<br>\n\n### 如何不使用 easycom 而单独引用某一个组件\n\n某些情况下，您可能不想通过 easycom 引用组件(虽然我们极力推荐您使用 easycom)，那么您可以使用`import`这个常规的引入方式，如下：\n\n```html\n<template>\n  <my-action-sheet :list=\"list\" v-model=\"show\"></my-action-sheet>\n</template>\n\n<script setup lang=\"ts\">\n  // 你如果自定义引入的名称，template 中使用组件名称也需要对应\n  import myActionSheet from \"@/uni_modules/uview-pro/components/u-action-sheet/u-action-sheet.vue\";\n  import { ref } from \"vue\";\n\n  interface ListItem {\n    text: string;\n    color?: string;\n    fontSize?: number;\n  }\n\n  const list = ref<ListItem[]>([\n    { text: \"点赞\", color: \"blue\", fontSize: 28 },\n    { text: \"分享\" },\n    { text: \"评论\" },\n  ]);\n\n  const show = ref(true);\n</script>\n```\n"
  },
  {
    "path": "src/static/app/markdown/radio.md",
    "content": "## Radio 单选框 <to-api/>\n\n<demo-model url=\"/pages/componentsB/radio/index\"></demo-model>\n\n\n单选框用于有一个选择，用户只能选择其中一个的场景。\n\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n- 该组件需要搭配`radioGroup`组件使用，以便用户进行操作时，获得当前单选框组的选中情况，当然，您也可以单独对某个`radio`进行事件监听\n- 通过`v-model`给`radioGroup`组件绑定一个变量，这个绑定的变量是双向的(初始值只能是`true`或者`false`)，也就是说，您可以无需监听`radio`或者`radioGroup`组件的`change`事件，也能知道哪个\n被勾选了\n\n\n**注意：** 由于`radio`组件需要由`radioGroup`组件提供参数值，这些父子组件间通过Vue的\"provide/inject\"特性注入依赖，\n所以您必须使用`radioGroup`包裹`radio`组件才能正常使用。\n\n\n```html\n<template>\n\t<view class=\"\">\n\t\t<u-radio-group v-model=\"value\" @change=\"radioGroupChange\">\n\t\t\t<u-radio \n\t\t\t\t@change=\"radioChange\" \n\t\t\t\tv-for=\"(item, index) in list\" :key=\"index\" \n\t\t\t\t:name=\"item.name\"\n\t\t\t\t:disabled=\"item.disabled\"\n\t\t\t>\n\t\t\t\t{{item.name}}\n\t\t\t</u-radio>\n\t\t</u-radio-group>\n\t</view>\n</template>\n\n<script>\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tlist: [\n\t\t\t\t{\n\t\t\t\t\tname: 'apple',\n\t\t\t\t\tdisabled: false\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'banner',\n\t\t\t\t\tdisabled: false\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'orange',\n\t\t\t\t\tdisabled: false\n\t\t\t\t}\n\t\t\t],\n\t\t\t// u-radio-group的v-model绑定的值如果设置为某个radio的name，就会被默认选中\n\t\t\tvalue: 'orange',\n\t\t};\n\t},\n\tmethods: {\n\t\t// 选中某个单选框时，由radio时触发\n\t\tradioChange(e) {\n\t\t\t// console.log(e);\n\t\t},\n\t\t// 选中任一radio时，由radio-group触发\n\t\tradioGroupChange(e) {\n\t\t\t// console.log(e);\n\t\t}\n\t}\n};\n</script>\n```\n\n### 禁用radio\n\n设置`disabled`为`true`，即可禁用某个组件，让用户无法点击，禁用分为两种状态，一是未勾选前禁用，这时只显示一个灰色的区域。二是已勾选后\n再禁用，会有灰色的勾选的图标，但此时依然是不可操作的。\n\n```html\n<u-radio-group v-model=\"value\">\n\t<u-radio :disabled=\"true\">明月几时有</u-radio>\n</u-radio-group>\n```\n\n### 自定义形状\n\n可以通过设置`shape`为`square`或者`circle`，将单选框设置为方形或者圆形\n\n\n```html\n<u-radio-group v-model=\"value\">\n\t<u-radio shape=\"circle\">月明人倚楼</u-radio>\n</u-radio-group>\n```\n\n\n### 自定义颜色\n\n此处所指的颜色，为`radio`选中时的背景颜色，参数为`active-color`\n\n\n```html\n<u-radio-group v-model=\"value\">\n\t<u-radio active-color=\"red\">思悠悠，恨悠悠，恨到归时方始休</u-radio>\n</u-radio-group>\n```\n\n\n### 文本是否可点击\n\n设置`label-disabled`为`true`，点击文本时，无法操作`radio`\n\n\n```html\n<u-radio-group v-model=\"value\">\n\t<u-radio :label-disabled=\"false\">门掩黄昏，无计留春住</u-radio>\n</u-radio-group>\n```\n\n\n### API\n\n### Radio Props\n\n注意：`radio`和`radio-group`二者同名参数中，`radio`的参数优先级更高。\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| icon-size | 图标大小，单位rpx  | String \\| Number | - | - |\n| label-size | label字体大小，单位rpx  | String \\| Number | - | - |\n| name | `radio`组件的标示符  | String \\| Number | - | - |\n| shape | 形状，见上方说明 | String  | - | circle / square |\n| disabled | 是否禁用 | Boolean  | - | false / true |\n| label-disabled | 是否禁止点击文本操作`radio` | Boolean  | - | true / false |\n| active-color | 选中时的颜色，如设置`radioGroup`的`active-color`将失效 | String  | - | - |\n\n\n\n### radioGroup Props\n\n注意：需要给`radioGroup`组件通过`v-model`绑定一个**变量**，来初始化`radio`的状态，随后该值被双向绑定，\n当用户勾单选框时，该值在`radio`内部被修改为`name`值，并反映到父组件，换言之，您无需监听`radio`的`change`事件，也能知道哪个`radio`被选中了。\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| v-model | 被选中`radio`双向绑定的值，如果初始值为某一个`radio`的`name`，该`radio`将会默认被选中 | String \\ Number | - | - |\n| disabled | 是否禁用所有`radio`  | Boolean | false | true |\n| label-disabled | 是否禁止点击文本操作`radio` | Boolean  | false | true |\n| shape | 形状，见上方说明 | String  | circle | square |\n| icon-size | 图标大小，单位rpx  | String \\ Number | 20 | - |\n| active-color | 选中时的颜色，应用到所有子`Radio`组件 | String  | #2979ff | - |\n| size | radio组件整体的大小，单位rpx  | String \\ Number | 34 | - |\n| width | `radio`的宽度，需带单位，如`50%`，`150rpx` | String \\| Number | auto | - |\n| wrap | 是否每个`radio`占一行 | Boolean  | false | true |\n\n\n### radio Event\n\n|事件名|说明|回调参数|版本|\n|:-|:-|:-|:-|\n| change | 某个`radio`状态发生变化时触发(选中状态) | name: 通过`props`传递的`name`参数 | - |\n\n\n### radioGroup Event\n\n|事件名|说明|回调参数|版本|\n|:-|:-|:-|:-|\n| change | 任一个`radio`状态发生变化时触发 | name: 值为`radio`通过`props`传递的`name`值 | - |\n"
  },
  {
    "path": "src/static/app/markdown/random.md",
    "content": "# random 随机数值\n\n<demo-model url=\"/pages/library/random/index\"></demo-model>\n\n\n## random(min, max)\n\n该方法可以返回在\"min\"和\"max\"之间的数值，要求\"min\"和\"max\"都为数值，且\"max\"大于或等于\"min\"，否则返回0.\n\n- `min` <Number\\> 最小值，最小值可以等于该值\n- `max` <Number\\> 最大值，最大值可以等于该值\n\n\n```js\nconsole.log(uni.$u.random(1, 3));\n```"
  },
  {
    "path": "src/static/app/markdown/randomArray.md",
    "content": "# randomArray 数组乱序\n\n<demo-model url=\"/pages/library/randomArray/index\"></demo-model>\n\n\n## randomArray(array)\n\n该函数可以打乱一维数组元素的顺序，这是随机过程\n\n- `array` <Array\\> 一维数组\n\n```js\nimport { ref, onMounted } from 'vue';\n\nconst array = ref([1, 2, 3, 4, 5]);\n\nonMounted(() => {\n  console.log(uni.$u.randomArray(array.value));\n});\n```"
  },
  {
    "path": "src/static/app/markdown/rate.md",
    "content": "## Rate 评分 <to-api/>\n\n<demo-model url=\"/pages/componentsB/rate/index\"></demo-model>\n\n\n该组件一般用于满意度调查，星型评分的场景。\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n- 通过`count`参数设置总共有多少颗星星可选择\n- 通过`v-model`双向绑定初始化时默认选中的星星数量\n- ~~通过`current`设置初始化时默认选中的星星数量~~(1.4.5后建议使用v-model的方式，此参数为了向前兼容依然有效，但优先级低于`v-model`)\n\n```html\n<template>\n\t<u-rate :count=\"count\" v-model=\"value\"></u-rate>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tcount: 4,\n\t\t\t\tvalue: 2\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 自定义样式\n\n- 通过`active-color`设置选中的星星的颜色\n- 通过`inactive-color`设置未选中时星星的颜色\n- 通过`gutter`设置星星的间距，左右内边距各占`gutter`的一半\n\n```html\n<u-rate active-color=\"#FA3534\" inactive-color=\"#b2b2b2\" gutter=\"20\"></u-rate>\n```\n\n### 自定义图标\n\n- 通过`active-icon`设置激活的图标\n- 通过`inactive-icon`设置未激活的图标\n- 通过`custom-prefix`设置自定义图标，详见：[扩展自定义图标库](https://www.uviewui.com/guide/customIcon.html) \n\n下方示例为使用心形图标替代默认的星星图标：\n\n```html\n<u-rate active-icon=\"heart-fill\" inactive-icon=\"heart\"></u-rate>\n```\n\n### 评分分级分层\n\n- 通过`colors`设置不同颜色区分评分层级\n- 通过`icons`设置不同类型图标区分评分层级\n\n```html\n<template>\n  <view>\n    <u-rate v-model=\"value\" :colors=\"colors\" :icons=\"icons\" inactive-icon=\"thumb-up\"></u-rate>\n  </view>\n</template>\n\n<script>\n  export default {\n    data() {\n      return {\n        value: 2,\n        colors: ['#ffc454', '#ffb409', '#ff9500'],\n        icons: ['thumb-down-fill', 'thumb-down-fill', 'thumb-up-fill', 'thumb-up-fill']\n      }\n    }\n  }\n</script>\n```\n\n### 最少选中的数量\n\n```html\n<u-rate :min-count=\"5\"></u-rate>\n```\n\n### 禁用状态\n\n禁用下，无法点击或者滑动选择，但是可以通过`current`设置默认选中的数量，禁用状态下用来展示分数，允许出现半星\n\n```html\n<u-rate :current=\"3.7\" :disabled=\"true\"></u-rate>\n```\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| v-model | 双向绑定选择星星的数量 | String \\| Number | 0 | - |\n| count | 最多可选的星星数量 | String \\| Number | 5 | - |\n| current | 默认选中的星星数量，1.4.5起建议使用`v-model`方式  | String \\| Number | 0 | - |\n| disabled | 是否禁止用户操作 | Boolean | false | true |\n| size | 星星的大小，单位rpx | String \\| Number | 32 | - |\n| inactive-color | 未选中星星的颜色 | String | #b2b2b2 | - |\n| active-color | 选中的星星颜色 | String | #FA3534 | - |\n| gutter | 星星之间的距离 | String \\| Number | 10 | - |\n| min-count | 最少选中星星的个数 | String \\| Number | 0 | - |\n| active-icon | 选中时的图标名，只能为uView的内置图标 | String | star-fill | - |\n| inactive-icon | 未选中时的图标名，只能为uView的内置图标 | String | star | - |\n| custom-prefix | 自定义字体图标库时，需要写上此值，详见：[扩展自定义图标库](https://www.uviewui.com/guide/customIcon.html) | String  | uicon | - |\n| colors | 颜色分级显示，可以用不同颜色区分评分层级 | Array  | - | - |\n| icons | 图标分级显示，可以用不同类型的icon区分评分层级 | Array  | - | - |\n\n<!-- | allow-half | 是否允许半星选择 | Boolean | false | true | -->\n\n### Events\n\n| 事件名 | 说明 | 回调参数 |\n| :- | :- | :- |\n| change | 选中的星星发生变化时触发 | value：当前选中的星星的数量，如果使用`v-model`双向绑定方式，无需监听此事件|\n"
  },
  {
    "path": "src/static/app/markdown/read.md",
    "content": "<p align=\"center\">\n    <img alt=\"logo\" src=\"https://ik.imagekit.io/anyup/uview-pro/common/logo.png\" width=\"120\" height=\"120\" style=\"margin-bottom: 10px;\">\n</p>\n<h3 align=\"center\" style=\"margin: 30px 0 30px;font-weight: bold;font-size:40px;\">uView</h3>\n<h3 align=\"center\">多平台快速开发的UI框架</h3>\n\n\n## 说明\n\nuView Pro，是[uni-app](https://uniapp.dcloud.io/)生态优秀的UI框架，全面的组件和便捷的工具会让您信手拈来，如鱼得水\n\n## 特性\n\n- 兼容安卓，iOS，微信小程序，H5，QQ小程序，百度小程序，支付宝小程序，头条小程序\n- 70+精选组件，功能丰富，多端兼容，让您快速集成，开箱即用\n- 众多贴心的JS利器，让您飞镖在手，召之即来，百步穿杨\n- 众多的常用页面和布局，让您专注逻辑，事半功倍\n- 详尽的文档支持，现代化的演示效果\n- 按需引入，精简打包体积\n\n\n## 安装\n\n```bash\n# npm方式安装\nnpm i uview-pro\n```\n\n## 快速上手\n\n1. `main.js`引入uView库\n```js\n// main.js\nimport uView from 'uview-pro';\nVue.use(uView);\n```\n\n2. `App.vue`引入基础样式(注意style标签需声明scss属性支持)\n```css\n/* App.vue */\n<style lang=\"scss\">\n@import \"uview-pro/index.scss\";\n</style>\n```\n\n3. `uni.scss`引入全局scss变量文件\n```css\n/* uni.scss */\n@import \"uview-pro/themb.scss\";\n```\n\n4. `pages.json`配置easycom规则(按需引入)\n\n```js\n// pages.json\n{\n\t\"easycom\": {\n\t\t// 注意一定要放在custom里，否则无效，https://ask.dcloud.net.cn/question/131175\n\t\t\"custom\": {\n\t\t\t\"^u-(.*)\": \"uview-pro/components/u-$1/u-$1.vue\"\n\t\t}\n\t},\n\t// 此为本身已有的内容\n\t\"pages\": [\n\t\t// ......\n\t]\n}\n```\n\n请通过[快速上手](https://uview-pro.netlify.app/components/quickstart.html)了解更详细的内容 \n\n## 使用方法\n配置easycom规则后，自动按需引入，无需`import`组件，直接引用即可。\n\n```html\n<template>\n\t<u-buton>按钮</u-buton>\n</template>\n```\n\n请通过[快速上手](https://uview-pro.netlify.app/components/quickstart.html)了解更详细的内容 \n\n## 链接\n\n- [官方文档](https://uview-pro.netlify.app/)\n- [更新日志](https://uview-pro.netlify.app/components/changelog.html)\n- [升级指南](https://uview-pro.netlify.app/components/changelog.html)\n- [交流反馈](https://uview-pro.netlify.app/cooperation/about.html)\n\n## 预览\n\n您可以通过**微信**扫码，查看最佳的演示效果。\n<br>\n<br>\n<img src=\"https://uview-pro.netlify.app/common/weixin_mini_qrcode.png\" width=\"220\" height=\"220\" >\n\n<!-- ## 捐赠uView的研发\n\nuView文档和源码全部开源免费，如果您认为uView帮到了您的开发工作，您可以捐赠uView的研发工作，捐赠无门槛，哪怕是一杯可乐也好(相信这比打赏主播更有意义)。\n\n<img src=\"https://uview-pro.netlify.app/common/wechat.png\" width=\"220\" >\n<img style=\"margin-left: 100px;\" src=\"https://uview-pro.netlify.app/common/alipay.png\" width=\"220\" >\n -->\n## 版权信息\nuView Pro遵循[MIT](https://en.wikipedia.org/wiki/MIT_License)开源协议，意味着您无需支付任何费用，也无需授权，即可将uView应用到您的产品中。\n"
  },
  {
    "path": "src/static/app/markdown/readMore.md",
    "content": "## ReadMore 展开阅读更多 <to-api/>\n\n<demo-model url=\"/pages/componentsB/readMore/index\"></demo-model>\n\n\n该组件一般用于内容较长，预先收起一部分，点击展开全部内容的场景。\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n通过slot传入正文内容\n\n```html\n<template>\n\t<u-read-more>\n\t\t<rich-text :nodes=\"content\"></rich-text>\n\t</u-read-more>\n</template>\n\n<script> \n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\t// 这是一段很长的文字，也可能包含有HTML标签等内容\n\t\t\t\tcontent: `山不在高，有仙则名。水不在深，有龙则灵。斯是陋室，惟吾德馨。\n\t\t\t\t苔痕上阶绿，草色入帘青。谈笑有鸿儒，往来无白丁。可以调素琴，阅金经。\n\t\t\t\t无丝竹之乱耳，无案牍之劳形。南阳诸葛庐，西蜀子云亭。孔子云：何陋之有？`,\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n<!-- ### 兼容性\n\n由于一些微信小程序平台的渲染能力的问题，在解析[u-parse](/components/readMore.html)组件内容时会比较耗时，导致`read-more`组件内部无法准确得知\n内容的高度，而出现计算错误，这种情况下，我们需要借助`u-parse`组件的`@load`(内容多为文字时)或者`@ready`(内容多为图片时，可能会有较大延时)事件，通过`ref`\n重新初始化`read-more`组件的高度，如下：\n\n```html\n<template>\n\t<u-read-more ref=\"uReadMore\">\n\t\t<u-parse :html=\"content\" @load=\"parseLoaded\"></u-parse>\n\t</u-read-more>\n</template>\n\n<script> \n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\t// 这是一段很长的文字，也可能包含有HTML标签等内容\n\t\t\t\tcontent: `山不在高，有仙则名。水不在深，有龙则灵。斯是陋室，惟吾德馨。\n\t\t\t\t苔痕上阶绿，草色入帘青。谈笑有鸿儒，往来无白丁。可以调素琴，阅金经。\n\t\t\t\t无丝竹之乱耳，无案牍之劳形。南阳诸葛庐，西蜀子云亭。孔子云：何陋之有？`,\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\tparseLoaded() {\n\t\t\t\tthis.$refs.uReadMore.init();\n\t\t\t}\n\t\t}\n\t}\n</script>\n``` -->\n\n\n### 展开收起\n\n配置`toggle`为`true`，展开后可以收起，否则展开后没有收起的按钮\n\n```html\n<u-read-more :toggle=\"true\">\n\t<rich-text :nodes=\"content\"></rich-text>\n</u-read-more>\n```\n\n### 配置展开高度\n\n可以配置一个高度，单位rpx，只有slot传入的内容高度超出这个值，才会出现\"展开阅读全文\"字样的按钮\n\n```html\n<u-read-more show-height=\"600\">\n\t<rich-text :nodes=\"content\"></rich-text>\n</u-read-more>\n```\n\n### 异步初始化\n\n有时候需要展示的内容是从后端获取的，组件内部的`mounted`生命周期初始化时，请求尚未回来，会导致\n内容的高度在初始化有误差。可以在请求完毕渲染后(指的是this.$nextTick)，通过`ref`调用组件的`init`方法，重新初始化\n\n```html\n<template>\n\t<u-read-more ref=\"uReadMore\">\n\t\t<rich-text :nodes=\"content\"></rich-text>\n\t</u-read-more>\n</template>\n\n<script> \n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tcontent: '',\n\t\t\t}\n\t\t},\n\t\tonLoad() {\n\t\t\t// 模拟后端请求\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.content = `山不在高，有仙则名。水不在深，有龙则灵。斯是陋室，惟吾德馨。\n\t\t\t\t苔痕上阶绿，草色入帘青。谈笑有鸿儒，往来无白丁。可以调素琴，阅金经。\n\t\t\t\t无丝竹之乱耳，无案牍之劳形。南阳诸葛庐，西蜀子云亭。孔子云：何陋之有？`,\n\t\t\t\t// 请注意上方已在组件中添加ref-uReadMore\n\t\t\t\tthis.$nextTick(() => {\n\t\t\t\t\tthis.$refs.uReadMore.init();\n\t\t\t\t})\n\t\t\t}, 2000);\n\t\t}\n\t}\n</script>\n```\n\n### 自定义样式\n\n此组件上边部分有一个白色虚化的阴影，用以将点击区域与文字内容进行融合，如果您不想要这个阴影，可以调整`shadow-style`对象，此对象内部如下：\n\n```css\n{\n\tbackgroundImage: \"linear-gradient(-180deg, rgba(255, 255, 255, 0) 0%, #fff 80%)\",\n\tpaddingTop: \"300rpx\",\n\tmarginTop: \"-300rpx\"\n}\n```\n\n如果您不想要阴影，将`backgroundImage`设置为`none`即可，关于`paddingTop`和`marginTop`自行调整至合适数值即可。\n\n\n```html\n<template>\n\t<u-read-more ref=\"uReadMore\" :shadow-style=\"shadowStyle\" :show-height=\"200\">\n\t\t<rich-text :nodes=\"content\"></rich-text>\n\t</u-read-more>\n</template>\n\n<script> \n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tcontent: '',\n\t\t\t\tshadowStyle: {\n\t\t\t\t\tbackgroundImage: \"none\",\n\t\t\t\t\tpaddingTop: \"0\",\n\t\t\t\t\tmarginTop: \"20rpx\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| show-height | 内容超出此高度才会显示展开全文按钮，单位rpx | String \\| Number | 400 | - |\n| toggle | 展开后是否显示收起按钮 | Boolean  | false | true |\n| close-text | 关闭时的提示文字 | String  | 展开阅读全文 | - |\n| font-size | 提示文字的大小，单位rpx | String \\| Number  | 28 | - |\n| open-text | 展开时的提示文字 | String  | 收起 | - |\n| color | 提示文字的颜色 | String  | #2979ff | - |\n| shadow-style | 对阴影的自定义处理，对象形式 | Object  | 见上方说明 | - |\n| text-indent | 段落首行缩进的字符个数，无需缩进请设置为0 | String  | 2em | - |\n| index | 用于在`open`和`close`事件中当作回调参数返回 | String \\| Number  | - | - |\n\n\n\n### Methods\n\n此方法如要通过ref手动调用\n\n| 名称          | 说明            |\n|-------------  |---------------- |\n| init | 重新初始化组件内部高度计算过程，如果内嵌[u-parse](/components/readMore.html)组件时可能需要用到 |\n\n\n### Events\n\n\n| 事件名 | 说明 | 回调参数 |\n| :- | :- | :- |\n| open | 内容被展开时触发 | index - props中传入的`index`参数值 |\n| close | 内容被收起时触发 | index - props中传入的`index`参数值 |\n\n\n<style scoped>\nh3[id=events] + table thead tr th:nth-child(2){\n\twidth: 33.3%;\n}\n\nh3[id=methods] + p + table thead tr th:nth-child(2){\n\twidth: 70%;\n}\n</style>"
  },
  {
    "path": "src/static/app/markdown/request.md",
    "content": "<demo-model url=\"/pages/library/http/index\"></demo-model>\n\n# uni-app 轻量级 Http 请求库 <BadgeVersion text=\"0.0.19\" />\n\n支持 TypeScript、Vue3、组合式 API，插件化、全局配置、请求/响应拦截器、toast/loading 灵活控制，开箱即用，适合中小型项目。目前不适用于其他的请求形式，比如上传，下载等。\n\n## 平台兼容性\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |    √     |\n\nput/delete 在某些小程序平台的限制：\n- 1.delete请求，不支持支付宝和头条小程序(HX2.6.15)\n- 2.put请求，不支持支付宝小程序(HX2.6.15)\n---\n\n## 特性亮点\n\n- 支持 get/post/put/delete 四种常用请求\n- 插件化注册，支持全局配置和拦截器\n- toast、loading 可全局/单次请求灵活配置\n- 拦截器支持 token 注入、统一错误处理、登录失效跳转等\n- TypeScript 类型友好，支持组合式 API\n- 可通过 `$u.http.get/post` 方式调用（需 import { $u } from 'uview-pro'）\n- 适配 H5、App、各主流小程序平台\n\n---\n\n## 快速开始\n\n### 1. 注册插件（main.ts）\n\n如何定义全局请求配置和请求/响应拦截器，看下面：[#拦截器最佳实践](#拦截器最佳实践)\n\n```ts\nimport { createSSRApp } from 'vue'\nimport uViewPro, { httpPlugin } from 'uview-pro'\nimport { httpInterceptor, httpRequestConfig } from 'http.interceptor'\n\nexport function createApp() {\n  const app = createSSRApp(App)\n\n  // 注册uView-pro\n  app.use(uViewPro)\n\n  // 注册http插件\n  app.use(httpPlugin, {\n    interceptor: httpInterceptor,\n    requestConfig: httpRequestConfig,\n  })\n\n  return { app }\n}\n```\n\n---\n\n## 全局与动态配置\n\n### 全局配置\n\n```ts\nimport { http } from 'uview-pro'\n\nhttp.setConfig({\n  baseUrl: 'https://api.example.com',\n  meta: {\n    toast: true, // 全局开启错误toast，默认为false关闭\n    loading: true, // 全局开启loading，默认为false关闭\n    originalData: true, // 是否在拦截器中返回服务端的原始数据，默认为true返回的是原始数据\n  },\n})\n```\n\n### 单次请求动态配置\n\n```ts\nhttp.post('/api/login', { username: 'xx' }, {\n  meta: { toast: true, loading: true }\n})\n```\n\n---\n\n## 基本用法\n\n### 组合式 API\n\n```ts\nimport { http } from 'uview-pro'\n\n// GET\nhttp.get('/api/user', { id: 1 }).then(res => { /* ... */ })\n\n// POST\nhttp.post('/api/login', { username: 'xx', password: 'xx' }).then(res => { /* ... */ })\n\n// PUT/DELETE\nhttp.put('/api/user/1', { name: 'new' })\nhttp.delete('/api/user/1')\n```\n\n### await/async\n\n```ts\nconst res = await http.post('/api/login', { username: 'xx' })\n```\n\n### 自定义 header\n\n```ts\nhttp.get('/api/user', {}, {\n  header: { Authorization: 'Bearer token' }\n})\n```\n\n---\n\n## 拦截器最佳实践\n\n### http.interceptor.ts 示例\n\n```ts\nimport type { RequestConfig, RequestInterceptor, RequestMeta } from 'uview-pro'\nimport { useUserStore } from '@/store'\n\n// 全局请求配置\nexport const httpRequestConfig: RequestConfig = {\n    baseUrl,\n    header: {\n        'content-type': 'application/json'\n    },\n    meta: {\n        originalData: true,\n        toast: true,\n        loading: true\n    }\n};\n\n// 全局请求/响应拦截器\nexport const httpInterceptor: RequestInterceptor = {\n  request: (config) => {\n    const meta: RequestMeta = config.meta || {}\n    if (meta.loading) {\n      // 显示loading\n    }\n    const userStore = useUserStore()\n    if (userStore.token) {\n      config.header.Authorization = `Bearer ${userStore.token}`\n    }\n    return config\n  },\n  response: (response) => {\n    const meta: RequestMeta = response.config?.meta || {}\n    if (meta.loading) {\n      // 隐藏loading\n    }\n\n    // 根据业务处理错误、例如登录失效等处理接口返回错误码\n    if (response.data.code !== 200) {\n      if (meta.toast) {\n        // 可以弹出错误toast\n      }\n      throw new Error('接口返回错误码，根据业务处理，可以弹出toast')\n    }\n    return response.data\n  },\n}\n```\n\n---\n\n## $u 工具库用法\n\n> 需 import { $u } from 'uview-pro'\n> \n> $u.http.get/post/put/delete 参数与 http 保持一致\n\n```ts\nimport { $u } from 'uview-pro'\n\n$u.http.get('/api/user', { id: 1 }, { meta: { toast: true } })\n$u.http.post('/api/login', { username: 'xx' }, { meta: { loading: true } })\n\n// 或\nuni.$u.http.get('/api/user', { id: 1 }, { meta: { toast: true } })\n```\n\n---\n\n## API 管理推荐\n\n建议将所有接口统一封装到 `api/index.ts`，便于维护和类型推断：\n\n```ts\n// api/index.ts\nimport { http } from 'uview-pro'\n\nexport const login = (data) => http.post('/api/login', data)\nexport const getUser = (id) => http.get('/api/user', { id })\n```\n\n页面中直接调用：\n\n```ts\nimport { login, getUser } from '@/api'\n\nconst user = await getUser(1)\n```\n\n---\n\n## 进阶用法\n\n### 多实例/多拦截器\n\n```ts\nimport { Request } from 'uview-pro'\n\nconst customHttp = new Request()\ncustomHttp.setConfig({ baseUrl: 'https://other.api.com' })\ncustomHttp.interceptor.request = (config) => {\n  // ...自定义逻辑\n  return config\n}\n```\n\n### 扩展 meta 字段\n\n你可以在 meta 中扩展自定义参数，在拦截器中读取：\n\n```ts\nhttp.get('/api/user', {}, { meta: { toast: true, customFlag: true } })\n// 在拦截器中：config.meta?.customFlag\n```\n\n### 结合 hooks 封装\n\n```ts\n// hooks/useApi.ts\nimport { http } from 'uview-pro'\nexport function useApi() {\n  return {\n    login: (data) => http.post('/api/login', data),\n    getUser: (id) => http.get('/api/user', { id }),\n  }\n}\n```\n\n---\n\n## 类型提示与 TS 支持\n\n- 所有请求方法均有完整类型推断\n- 支持泛型：`http.get<MyResType>(url)`\n- 支持自定义 Request/Response 类型\n- 推荐在 api 层定义类型，页面调用自动推断\n\n---\n\n## 常见问题 FAQ\n\n### 1. 如何全局配置 baseUrl、header、meta？\n\n> 使用 `http.setConfig({ ... })`，建议在 main.ts 或拦截器注册前调用。\n\n### 2. 如何单次请求自定义 toast/loading？\n\n> 通过 meta 字段：`http.post(url, data, { meta: { toast: true, loading: true } })`\n\n### 3. 如何自定义拦截器？\n\n> 参考 http.interceptor.ts，request/response 可灵活扩展。\n\n### 4. 如何在组合式 API 中优雅使用？\n\n> 直接 `import { http }`，无需 getCurrentInstance。\n\n### 5. 如何处理多环境/多 baseUrl？\n\n> 可通过 setConfig 动态切换，或 new Request() 多实例。\n\n### 6. 如何捕获和处理错误？\n\n> 建议统一在 response 拦截器处理，页面可用 try/catch 或 .catch。\n\n### 7. $u.http.get/post 与 http 有什么区别？\n\n> $u.http.get/post 适配 uview-pro 导出的 http，参数与 http 完全一致，底层同一实现。\n> 即以下方式是同等的：\n\n```js\nimport { $u, http } from 'uview-pro'\n\n// 方式一\nhttp.get('/api/user', { id: 1 }, { meta: { toast: true } })\n\n// 方式二\n$u.http.get('/api/user', { id: 1 }, { meta: { toast: true } })\n\n// 方式三\nuni.$u.http.get('/api/user', { id: 1 }, { meta: { toast: true } })\n\n```\n\n### 8. put/delete 在小程序平台有限制吗？\n\n> put/delete 在支付宝、头条等部分平台有限制，详见最上方提示。\n\n---\n\n"
  },
  {
    "path": "src/static/app/markdown/resource.md",
    "content": "## 资源下载\n\n我们会在这里为您提供一些跟 uView Pro 设计相关的资源和设计工具的下载，更多设计资源正在整理和完善中。\n\n### 设计资源\n\n这里我们提供组件的 Sketch 和 Axure 设计资源，您可以根据需要进行下载。\n\n<div class=\"cards\">\n    <ul class=\"container\">   \n        <li >\n            <div class=\"card\">\n                <img src=\"https://ik.imagekit.io/anyup/uview-pro/docs/resource/sketch-template.png\" alt=\"\">\n                <h3>Sketch Template</h3>\n                <p>通过在Sketch中导入uView组件库，可以在交互设计阶段方便地调用常用的组件</p>\n                <a href=\"https://cdn.uviewui.com/uview/resources/sketch.sketch\">下载</a>\n            </div>\n        </li>\n        <li >\n            <div class=\"card\">\n                <img src=\"https://ik.imagekit.io/anyup/uview-pro/docs/resource/axure-template.png\" alt=\"\">\n                <h3>Axure Template</h3>\n                <p>通过在Axure中导入uView组件库，可以在交互设计阶段方便地调用常用的组件</p>\n                <a href=\"https://cdn.uviewui.com/uview/resources/axure.rp\">下载</a>\n            </div>\n        </li>\n    </ul>\n</div>\n\n### 框架资源\n\n这里我们提供了一些跟组件，或者框架相关的下载资源，您可以根据需求进行下载。\n\n<div class=\"cards\">\n    <ul class=\"container\">   \n        <!-- <li >\n            <div class=\"card\">\n                <img src=\"https://ik.imagekit.io/anyup/uview-pro/docs/resource/i18n-demo.png\" alt=\"\">\n                <h3>I18n多语言示例</h3>\n                <p>我们为您制作了一个I18n多语言的示例工程，下载运行即可，注意此版本不适用于nvue</p>\n                <a href=\"https://cdn.uviewui.com/uview/resources/i18n.zip\">下载</a>\n            </div>\n        </li>\n        <li >\n            <div class=\"card\">\n                <img src=\"https://ik.imagekit.io/anyup/uview-pro/docs/resource/scaffold-demo.png\" alt=\"\">\n                <h3>脚手架空白工程</h3>\n                <p>已配置uView的空白项目，适用于新项目或者学习使用，下载后在HX中运行即可</p>\n                <a href=\"https://cdn.uviewui.com/uview/resources/uView-cli.zip\">下载</a>\n            </div>\n        </li>\n        <li >\n            <div class=\"card\">\n                <img src=\"https://ik.imagekit.io/anyup/uview-pro/docs/resource/tabbar-demo.png\" alt=\"\">\n                <h3>Tabbar组件使用示例</h3>\n                <p>请注意配合文档说明使用此组件，这里为组件的使用示例工程，下载即可使用</p>\n                <a href=\"https://cdn.uviewui.com/uview/resources/Tabbar.zip\">下载</a>\n            </div>\n        </li> -->\n        <li >\n            <div class=\"card\">\n                <img src=\"https://ik.imagekit.io/anyup/uview-pro/docs/resource/empty-placeholder.png\" alt=\"\">\n                <h3>Empty组件配套占位图</h3>\n                <p>我们的专业设计师精心为您做了一套精美的缺省图，涵盖各个场景，文件内含图片和Sketch源文件</p>\n                <!-- <a href=\"http://cdn.uviewui.com/uview/resources/Empty.zip\">下载</a> -->\n                <a href=\"https://yanxincloudplatform.oss-cn-beijing.aliyuncs.com/cloudplatform/Empty.zip\">下载</a>\n            </div>\n        </li>\n    </ul>\n</div>\n\n<style lang=\"scss\">\n\t.card {\n\t\tbackground: #fbfcfd;\n\t\theight: 204px;\n\t\ttext-align: center\n\t}\n\n\t.card h4 {\n\t\tfont-size: 18px;\n\t\tcolor: #1f2d3d;\n\t\tfont-weight: 400;\n\t\tmargin: 0\n\t}\n\n\t.card span {\n\t\tfont-size: 14px;\n\t\tcolor: #99a9bf\n    }\n    \n    .card {\n\t\theight: 394px;\n\t\twidth: 100%;\n\t\tbackground: #fff;\n\t\tborder: 1px solid #eaeefb;\n\t\tborder-radius: 5px;\n\t\tbox-sizing: border-box;\n\t\ttext-align: center;\n\t\tposition: relative;\n\t\ttransition: bottom .3s;\n        bottom: 0;\n        transition: box-shadow .3s;\n    }\n    \n    .card:hover {\n        box-shadow: 0 3px 5px -4px rgba(0,0,0,.12), 0 4px 12px 0 rgba(0,0,0,.08), 0 9px 24px 6px rgba(0,0,0,.05);\n    }\n\n\t.card img {\n\t\tmargin: 40px auto 35px;\n        height: 100px;\n        width: 100px\n\t}\n\n\t.card h3 {\n\t\tmargin: 0 0 10px;\n\t\tfont-size: 18px;\n\t\tcolor: #1f2f3d;\n\t\tfont-weight: 400;\n\t\theight: 22px\n\t}\n\n\t.card p {\n\t\tfont-size: 14px;\n\t\tcolor: #99a9bf;\n\t\tpadding: 0 30px;\n\t\tmargin: 0;\n\t\tword-break: break-all;\n\t\tline-height: 1.8\n\t}\n\n\t.card a {\n\t\theight: 42px;\n\t\twidth: 190px;\n\t\tdisplay: inline-block;\n\t\tline-height: 42px;\n\t\tfont-size: 14px;\n\t\tbackground-color: #409eff;\n\t\tcolor: #fff;\n\t\ttext-align: center;\n\t\tborder: 0;\n\t\tpadding: 0;\n\t\tcursor: pointer;\n\t\tborder-radius: 2px;\n\t\ttransition: all .3s;\n\t\ttext-decoration: none;\n        margin-top: 20px;\n        transition: opacity 0.3s;\n    }\n\n    .card a:hover {\n        opacity: 0.75;\n    }\n    \n    .cards {\n\t\tmargin: 0px 0 70px\n        \n\t}\n\n\t.cards .container {\n\t\tpadding: 0;\n\t\tmargin: 0 -11px;\n\t\twidth: auto\n\t}\n\n\t.cards .container:after,\n\t.cards .container:before {\n\t\tdisplay: table;\n\t\tcontent: \"\"\n\t}\n\n\t.cards .container:after {\n\t\tclear: both\n\t}\n\n\t.cards li {\n\t\twidth: 28%;\n\t\tpadding: 0 19px;\n\t\tbox-sizing: border-box;\n\t\tfloat: left;\n\t\tlist-style: none;\n        margin-top: 30px;\n\t}\n\n\t@media (max-width:850px) {\n\t\t.cards li {\n\t\t\tmax-width: 500px;\n\t\t\tfloat: none;\n\t\t\tmargin: 10px auto 30px;\n\t\t\twidth: 80%\n\t\t}\n\n\t\t.cards li .card {\n\t\t\theight: auto;\n\t\t\tpadding-bottom: 20px\n\t\t}\n\n\t\t.cards h3 {\n\t\t\theight: auto\n\t\t}\n\t}\n</style>\n"
  },
  {
    "path": "src/static/app/markdown/route.md",
    "content": "# route 路由跳转\n\n<demo-model url=\"/pages/library/route/index\"></demo-model>\n\n\n### route(Object)\n\n此为一个路由跳转方法，内部是对uni多个路由跳转api的封装，更方便使用\n\nObject参数说明：\n\n| 参数名      |     类型       |      默认值      |   是否必填      |  说明   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| type | String  | navigateTo | false | `navigateTo`或`to`对应`uni.navigateTo`，`redirect`或`redirectTo`对应`uni.redirectTo`，`switchTab`或`tab`对应`uni.switchTab`，`reLaunch`对应`uni.reLaunch`，`navigateBack`或`back`对应`uni.navigateBack`|\n| url | String  | -\t | false | `type`为`navigateTo`，`redirectTo`，`switchTab`，`reLaunch`时为必填 |\n| delta | Number | 1  | false | `type`为`navigateBack`时用到，表示返回的页面数 |\n| params | Object | -  | false | 传递的对象形式的参数，如`{name: 'lisa', age: 18}` |\n| animationType | String | pop-in  | false | 只在APP生效，详见[窗口动画](https://uniapp.dcloud.io/api/router?id=animation) |\n| animationDuration | Number | 300  | false | 动画持续时间，单位ms |\n\n\n<br>\n\n```js\nimport { ref, onMounted } from 'vue';\n\nconst route = ref(null);\n\nonMounted(() => {\n  setTimeout(() => {\n    uni.$u.route({\n      url: 'pages/components/empty/index',\n      params: {\n        name: 'lisa'\n      }\n    });\n  }, 2000);\n});\n```\n\n\n## 简写\n\n注：为了方便简写和调用，可以直接传递一个`url`地址替代`Object`，它只能执行`uni.navigateTo`类型的地址，**不支持跳转到Tabbar页面**，\n如果有参数需要携带，以对象形式写到方法的第二个参数中。\n\n```js\n// 无参数\nuni.$u.route('/pages/components/empty/index');\n\n\n// 带参数\nuni.$u.route('/pages/components/empty/index', {\n\tname: 'lisa',\n\tage: 20\n});\n```\n\n\n<style scoped>\nh4[id=route-object] + p + p + table thead tr th:nth-child(5){\n\twidth: 40%;\n}\n\nh4[id=route-object] + p + p + table thead tr th:nth-child(2){\n\twidth: 12%;\n}\n\n</style>"
  },
  {
    "path": "src/static/app/markdown/safeAreaInset.md",
    "content": "## 底部安全区适配\n\n这个适配，主要是针对IPhone X等一些底部带指示条的机型，指示条的操作区域与页面底部存在重合，容易导致用户误操作，因此我们需要针对这些机型进行底部安全区适配。  \nuView是uni-app态的UI框架uni-app专门针对底部安全区域的解决方案，具体如下(也可见uni官方说明[全面屏、刘海屏适配（iphoneX适配）及安全区设置](https://ask.dcloud.net.cn/article/35564))：\n- 在APP上(以下只对APP生效)，可以通过项目根目录的`mainfest.json`文件`app-plus`节点下配置`safearea`的`bottom`属性为`none`，以此来关闭IPhone X等机型的底部安全区域。\n配置后需要重新编译，并重启调试基座才会生效，具体如下：\n\n``` json\n\"app-plus\": {\n\t\"safearea\": {\n\t\t\"bottom\": {\n\t\t\t\"offset\": \"none\"\n\t\t}\n\t}\n}\n```\n如果`offset`设置为`auto`，那么在IPhone X的底部安全区，APP上就会生成一个原生的元素进行占位，此时也就无需解决安全区指示条引起的问题。\n\n- 在非APP端，诸如小程序，或者微信浏览器(其他浏览器，如UC等手机浏览器，底部有浏览器工具条，不存在安全区指示条引起的问题)，底部是没有安全区占位的，\n这种情况，就要使用css去解决，一般是通过给元素添加底部内边距的形式，如下：\n\n``` html \n<style>  \n\t.list {  \n\t\tpadding-bottom: 0;  \n\t\tpadding-bottom: constant(safe-area-inset-bottom);  \n\t\tpadding-bottom: env(safe-area-inset-bottom);  \n\t}  \n</style>\n```\n\n鉴于以上问题，uView提供了一个样式类`safe-area-inset-bottom`，如果有需要，您可以在任何写元素的地方引用它，它会自动判断在并且在IPhone X等机型的时候，给元素加上一个适当\n底部内边距，在APP上，即使您保留了原生安全区占位(`offset`设置为`auto`)，也不会导致底部出现双倍的空白区域，也即APP上`offset`设置为`auto`时，\n`safe-area-inset-bottom`类自动无效。\n``` html \n<template>\n\t<view class=\"safe-area-inset-bottom\">\n\t\t......\n\t</view>\n</template>\n```\n\n### 关于uView某些组件`safe-area-inset`参数的说明\n\n在uView中，一些组件如`u-popup`、`u-keyboard`组件等，提供了一个`safe-area-inset-bottom`参数(布尔类型)，如果设置为`true`，就会在组件内部元素中添加一个\n`safe-area-inset-bottom`样式类名，从而避免安全区指示条引起的问题，以下为uView的`u-keyboard`组件在`微信浏览器`中分别设置`safe-area-inset-bottom`参数\n为`false`和`true`的表现：\n\n<div>\n\t<img src=\"https://ik.imagekit.io/anyup/uview-pro/docs/common/keyboard.png\" alt=\"uView\" class=\"logo\">\n</div>"
  },
  {
    "path": "src/static/app/markdown/search.md",
    "content": "## Search 搜索 <to-api/>\n\n<demo-model url=\"/pages/componentsB/search/index\"></demo-model>\n\n<custom-block text=\"由于右侧的演示是通过iframe引入的，缺少移动端的@touchstart事件，故清除控件无效，请在真机演示中查看效果。\"></custom-block>\n\n搜索组件，集成了常见搜索框所需功能，用户可以一键引入，开箱即用。\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |    √     |\n\n### 基本使用\n\n- 通过`placeholder`参数设置占位内容\n- 通过`v-model`双向绑定一个**变量**值，设置初始化时搜索框的值，如果初始内容为空，那么请绑定一个值为空字符的变量。\n\n**说明：** 因为是双向绑定的，所以当组件内容输入框内容变化时，也会实时的反映到绑定的`keyword`变量，这意味着，您**无需**监听`change`事件，\n也能实时的得知输入框的内容。\n\n```html\n<template>\n\t<u-search placeholder=\"日照香炉生紫烟\" v-model=\"keyword\"></u-search>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tkeyword: '遥看瀑布挂前川'\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 设置输入框形状\n\n通过`shape`设置输入框两端的形状，`square`-方形带圆角，`round`(默认)-半圆形\n\n```html\n<u-search shape=\"round\"></u-search>\n```\n\n### 是否开启清除控件\n\n`clearabled`(默认为`true`)设置为`true`的话，输入框有内容时，右边会显示一个清除的图标\n\n```html\n<u-search :clearabled=\"true\"></u-search>\n```\n\n### 是否开启右边控件\n\n该控件为类似按钮形式，可以设置为\"搜索\"或者\"取消\"等内容，如果开启动画效果，用户确认搜索后，该控件会自动消失\n\n- `show-action`配置是否开启右边按钮控件\n- `action-text`配置控件内容\n- `animation`(默认为`false`)设置为`true`的话，失去焦点，或者点击控件按钮时，控件自动消失，并且带有动画效果\n\n\n1. 如果不想点击右侧控件时自动消失，请把`animation`设置为`false`\n2. 右侧控件的默认文字为\"搜索\"(它本意为控件，碰巧内容为\"搜索\"二字，并非说它就是一个搜索按钮)，点击它的时候触发的是`custom`事件，而不是`search`事件\n\n\n```html\n<u-search :show-action=\"true\" action-text=\"搜索\" :animation=\"true\"></u-search>\n```\n\n### 自定义样式\n\n- 通过`input-align`设置输入框内容的对其方式，和css的`text-align`同理\n- 通过`border-color`设置整个搜索组件的边框，只要配置了颜色，才会出现边框\n- 通过`height`设置组件高度\n- 通过`disabled`设置是否禁用输入框\n- 通过`bg-color`设置是搜索组件背景颜色\n\n```html\n<u-search input-align=\"center\" height=\"70\"></u-search>\n```\n\n### API\n\n### Props\n\n| 参数              | 说明                                                                                 | 类型             | 默认值       | 可选值         |\n| ----------------- | ------------------------------------------------------------------------------------ | ---------------- | ------------ | -------------- |\n| v-model           | 双向绑定输入框搜索值                                                                 | String           | -            | -              |\n| shape             | 搜索框形状，round-圆形，square-方形                                                  | String           | round        | square         |\n| bg-color          | 搜索框背景颜色                                                                       | String           | #f2f2f2      | -              |\n| border-color      | 边框颜色，配置了颜色，才会有边框                                                     | String           | -            | -              |\n| placeholder       | 占位文字内容                                                                         | String           | 请输入关键字 | -              |\n| clearabled        | 是否启用清除控件                                                                     | Boolean          | true         | false          |\n| focus             | 是否自动获得焦点                                                                     | Boolean          | false        | true           |\n| show-action       | 是否显示右侧控件(右侧的\"搜索\"按钮)                                                   | Boolean          | true         | false          |\n| action-text       | 右侧控件文字                                                                         | String           | 搜索         | -              |\n| action-style      | 右侧控件的样式，对象形式                                                             | Object           | -            | -              |\n| input-align       | 输入框内容水平对齐方式                                                               | String           | left         | center / right |\n| disabled          | 是否启用输入框                                                                       | Boolean          | false        | true           |\n| animation         | 是否开启动画，见上方说明                                                             | Boolean          | false        | true           |\n| height            | 输入框高度，单位rpx                                                                  | String \\| Number | 64           | -              |\n| search-icon-color | 搜索图标的颜色，默认同输入框字体颜色                                                 | String           | -            | -              |\n| color             | 输入框字体颜色                                                                       | String           | #606266      | -              |\n| placeholder-color | placeholder的颜色                                                                    | String           | #909399      | -              |\n| margin            | 组件与其他上下左右元素之间的距离，带单位的字符串形式，如\"30rpx\"、\"30rpx 20rpx\"等写法 | String           | -            | -              |\n| maxlength         | 输入框最大能输入的长度，-1为不限制长度                                               | String \\| Number | -1           | -              |\n| input-style       | 自定义输入框样式，对象形式                                                           | Object           | -            | -              |\n| search-icon       | 输入框左边的图标，可以为uView图标名称或图片路径                                      | String           | search       | -              |\n\n\n### Events\n\n您可以通过监听`change`事件，在回调中将返回的结果绑定一个变量去获得用户的输入内容。  \n但如\"基本使用\"中的说明一样，您双向绑定了一个变量后，无需监听`change`事件也是可以的。\n\n| 事件名 | 说明                                                                 | 回调参数          | 版本 |\n| :----- | :------------------------------------------------------------------- | :---------------- | :--- |\n| change | 输入框内容发生变化时触发                                             | value：输入框的值 | -    |\n| search | 用户确定搜索时触发，用户按回车键，或者手机键盘右下角的\"搜索\"键时触发 | value：输入框的值 | -    |\n| custom | 用户点击右侧控件时触发                                               | value：输入框的值 | -    |\n| blur   | 输入框失去焦点时触发                                                 | value：输入框的值 | -    |\n| focus  | 输入框获得焦点时触发                                                 | value：输入框的值 | -    |\n| clear  | 配置了`clearabled`后，清空内容时会发出此事件                         | -                 | -    |\n| click  | `disabled`为`true`时，点击输入框，发出此事件，用于跳转搜索页         | -                 | -    |\n\n\n<style scoped>\nh3[id=props] + table thead tr th:nth-child(2){\n\twidth: 35%;\n}\n</style>\n"
  },
  {
    "path": "src/static/app/markdown/section.md",
    "content": "## Section 查看更多 <to-api/>\n\n<demo-model url=\"/pages/componentsC/section/index\"></demo-model>\n\n\n该组件一般用于分类信息有很多，但是限于篇幅只能列出一部分，让用户通过\"查看更多\"获得更多信息的场景，实际效果见演示。\n\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n说明：此组件会在最左边显示一个竖条\n\n- 通过`title`参数设置主标题\n- 通过`sub-title`参数设置副标题\n\n```html\n<u-section title=\"今日热门\" sub-title=\"查看更多\"></u-section>\n```\n\n### 是否显示右边内容\n\n可以通过设置`right`为`false`来隐藏右边的内容\n\n```html\n<u-section title=\"今日热门\" :right=\"false\"></u-section>\n```\n\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| title | 左边主标题 | String | - | - |\n| sub-title | 右边副标题 | String  | 更多 | - |\n| right | 是否显示右边的内容 | Boolean  | true | false |\n| show-line | 是否显示左边的竖条 | Boolean  | true | false |\n| font-size | 主标题的字体大小 | String \\| Number  | 28 | - |\n| bold | 主标题是否加粗 | Boolean  | true | false |\n| color | 主标题颜色 | String  | #303133 | - |\n| sub-color | 右边副标题的颜色(右箭头同此颜色) | String  | #909399 | - |\n| line-color | 左边竖线的颜色，默认同`color`参数值 | String  | - | - |\n| arrow | 是否显示右边箭头 | Boolean  | true | false |\n\n\n### Events\n\n\n| 事件名 | 说明 | 回调参数 | 版本 |\n| :- | :- | :- | :- |\n| click | 组件右侧的内容被点击时触发，用于跳转\"更多\" | - | - |\n\n\n### Slot\n\n| 名称          | 说明            |\n|-------------  |---------------- |\n| right | 自定义右侧内容  |\n\n\n<style scoped>\nh3[id=slot] + table thead tr th:nth-child(2){\n\twidth: 50%;\n}\n</style>\n"
  },
  {
    "path": "src/static/app/markdown/select.md",
    "content": "## Select 列选择器 <to-api/>\n\n<demo-model url=\"/pages/componentsA/select/index\"></demo-model>\n\n\n此选择器用于单列，多列，多列联动的选择场景。\n\n**注意：** 从`1.3.0`版本起，不建议使用`Picker`组件的单列和多列模式，`Select`组件是专门为列选择而构造的组件，更简单易用。\n\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n\n### 基本使用\n\n\n所有的配置模式中，都要求传入数组的元素(对象)中含有`value`和`label`属性(可以通过`value-name`和`label-name`参数自定义)，\n`value`用于在回调时，区别选择了哪一个(针对开发者)，`label`用于展示在选择器中，供用户选择和查看(针对用户)。\n\n\n- 通过v-model绑定一个布尔值变量，用于控制组件的弹出与收起。\n- 组件共有3种模式，通过配置`mode`参数实现，如下：\n\n1. mode = single-column，为单列选择模式。\n2. mode = mutil-column，为多列选择模式。\n3. mode = mutil-column-auto，为多列联动模式，多列联动的数据格式比较特殊，见下方说明。\n\n\n```html\n<template>\n\t<view>\n\t\t<u-select v-model=\"show\" :list=\"list\"></u-select>\n\t\t<u-button @click=\"show = true\">打开</u-button>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tshow: false,\n\t\t\t\tlist: [\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue: '1',\n\t\t\t\t\t\tlabel: '江'\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue: '2',\n\t\t\t\t\t\tlabel: '湖'\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n\n### 单列模式\n\n此方式使用较为简单，需要传入一个一维数组，数组的元素为对象，要求必须有`value`和`label`属性，这两个值也将会在回调中被返回。\n\n```html\n<template>\n\t<u-select v-model=\"show\" mode=\"single-column\" :list=\"list\" @confirm=\"confirm\"></u-select>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tshow: true,\n\t\t\t\tlist: [\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue: '1',\n\t\t\t\t\t\tlabel: '江'\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue: '2',\n\t\t\t\t\t\tlabel: '湖'\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\t// 注意返回值为一个数组，单列时取数组的第一个元素即可(只有一个元素)\n\t\t\tconfirm(e) {\n\t\t\t\tconsole.log(e);\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n\n### 多列模式\n\n此模式类似于单列模式，不同之处在于`list`参数为二维数组，同样要求数组的元素必须要有`value`和`label`属性，回调参数为包含多个元素的数组，\n分别表示每一列的选择情况。\n\n```html\n<template>\n\t<u-select v-model=\"show\" mode=\"mutil-column\" :list=\"list\" @confirm=\"confirm\"></u-select>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tshow: true,\n\t\t\t\tlist: [\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue: '1',\n\t\t\t\t\t\t\tlabel: '江'\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue: '2',\n\t\t\t\t\t\t\tlabel: '湖'\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue: '3',\n\t\t\t\t\t\t\tlabel: '夜'\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tvalue: '4',\n\t\t\t\t\t\t\tlabel: '雨'\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\t\n\t\t\t\t],\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\t// 回调参数为包含多个元素的数组，每个元素分别反应每一列的选择情况\n\t\t\tconfirm(e) {\n\t\t\t\tconsole.log(e);\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n\n### 多列联动模式\n\n由于需要多列联动，此模式和上面的\"多列模式\"基本相同，但是也有区别的地方，因为需要\"联动\"，需要在每个对象中多一个`children`属性，用于标识\n它的子列(后一列)的可选值，回调参数和\"多列模式\"一致。\n\n```html\n<template>\n\t<u-select v-model=\"show\" mode=\"mutil-column-auto\" :list=\"list\" @confirm=\"confirm\"></u-select>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tshow: true,\n\t\t\t\tlist: [\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue: 1,\n\t\t\t\t\t\tlabel: '中国',\n\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvalue: 2,\n\t\t\t\t\t\t\t\tlabel: '广东',\n\t\t\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tvalue: 3,\n\t\t\t\t\t\t\t\t\t\tlabel: '深圳'\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tvalue: 4,\n\t\t\t\t\t\t\t\t\t\tlabel: '广州'\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvalue: 5,\n\t\t\t\t\t\t\t\tlabel: '广西',\n\t\t\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tvalue: 6,\n\t\t\t\t\t\t\t\t\t\tlabel: '南宁'\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tvalue: 7,\n\t\t\t\t\t\t\t\t\t\tlabel: '桂林'\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue: 8,\n\t\t\t\t\t\tlabel: '美国',\n\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tvalue: 9,\n\t\t\t\t\t\t\t\tlabel: '纽约',\n\t\t\t\t\t\t\t\tchildren: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tvalue: 10,\n\t\t\t\t\t\t\t\t\t\tlabel: '皇后街区'\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\tconfirm(e) {\n\t\t\t\tconsole.log(e);\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n\n### 默认值\n\n此组件的所有模式，都可以设置默认值，通过`default-value`数组参数配置，数组元素的0表示选中每列的哪个值(从0开始)，下面分别对几种模式进行说明：  \n\n**注意：** `default-value`数组的长度，必须与列数相同，否则无效。\n\n1. 单列模式\n\n如设置`default-value`为`[1]`表示默认选中第2个(从0开始)，`[5]`表示选中第6个。\n\n\n2. 多列模式\n\n如设置`default-value`为`[1, 3]`表示第一列默认选中第2个，第二列默认选中第4个。\n\n\n3. 多列联动模式\n\n配置方法同\"多列模式\"，见上。\n\n<br>\n\n### 回调参数\n\n**注意：** 如果您觉得回调的`value`和`label`属性还无法满足您的需求，您可以在传递给`list`的参数中多带一个`extra`属性，如果有此属性，\n在回调中将会多返回一个`extra`属性值(1.3.6新增)。\n\n1. 单列模式\n\n此模式点击`确定`或`取消`按钮，会返回一个只有一个元素的数组，此元素即为回调结果，数组内容可能如下：  \n\n```js\nres = [\n\t{\n\t\tlabel: '雪月夜',\n\t\tvalue: '1',\n\t\t// 如果传递给\"list\"的对象中有extra属性，将会在此返回\n\t\t// extra: 'xxx'\n\t}\n]\n```\n\n2. 多列模式\n\n此模式点击`确定`或`取消`按钮，会返回一个有多个元素的数组，元素的数量和列数相等，第0个元素(索引从0开始)与第一列(也可以认为是第0列)相匹配，以此类推，\n返回结果可能如下：\n\n```js\nres = [\n\t{\n\t\tlabel: '雪月夜',\n\t\tvalue: '1'\n\t},\n\t{\n\t\tlabel: '冷夜雨',\n\t\tvalue: '2'\n\t},\n]\n```\n\n\n3. 多列联动\n\n返回结果同上方的\"多列模式\"。\n\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| mode | 模式选择，\"single-column\"-单列模式，\"mutil-column\"-多列模式，\"mutil-column-auto\"-多列联动模式  | String\t | single-column | mutil-column / mutil-column-auto |\n| list | 列数据，数组形式，见上方说明 | Array | - | - |\n| v-model | 布尔值变量，用于控制选择器的弹出与收起 | Boolean | false | true |\n| safe-area-inset-bottom | 是否开启[底部安全区适配](/components/safeAreaInset.html#关于uview某些组件safe-area-inset参数的说明) | Boolean  | false | true |\n| cancel-color | 取消按钮的颜色  | String | #606266 | - |\n| confirm-color | 确认按钮的颜色  | String | #2979ff | - |\n| default-value | 提供的默认选中的下标，见上方说明  | Array | - | - |\n| mask-close-able | 是否允许通过点击遮罩关闭Picker  | Boolean | true | false |\n| z-index | 弹出时的`z-index`值 | String \\| Number | 10075 | - |\n| value-name | 自定义`list`数据的`value`属性名 | String | value | - |\n| label-name | 自定义`list`数据的`label`属性名 | String | label | - |\n| child-name | 自定义`list`数据的`children`属性名，只对多列联动模式有效 | String | children | - |\n| title | 顶部中间的标题 | String | - | - |\n| confirm-text  | 确认按钮的文字 | String | 确认 | - |\n| cancel-text  | 取消按钮的文字 | String | 取消 | - |\n\n\n### Events\n\n|事件名|说明|回调参数|版本|\n|:-|:-|:-|:-|\n| confirm | 点击确定按钮，返回当前选择的值 | Array: 见上方\"回调参数\"部分说明 | - |\n| cancel | 点击取消按钮，返回当前选择的值 | Array: 见上方\"回调参数\"部分说明 | - |\n\n\n\n<style scoped>\nh3[id=props] + table thead tr th:nth-child(2){\n\twidth: 30%;\n}\n</style>\n"
  },
  {
    "path": "src/static/app/markdown/setting.md",
    "content": "## 配置\n\nuView Pro 支持 `npm` 和 `uni_modules` 两种主流安装方式，配置方式高度一致。无论采用哪种方式，均可通过 easycom 实现组件自动引入，极大提升开发效率。以下为统一的配置说明：\n\n### 1. 安装 uView Pro\n\n- npm 安装：\n\n```bash\nnpm install uview-pro\n# 或\nyarn add uview-pro\n# 或\npnpm add uview-pro\n```\n\n- uni_modules 安装：\n\n通过 HBuilderX 插件市场或手动下载，将 uView Pro 放入 `uni_modules` 目录。\n\n[插件市场：https://ext.dcloud.net.cn/plugin?id=24633](https://ext.dcloud.net.cn/plugin?id=24633)\n\n### 2. 引入 uView Pro 主库\n\n在 `main.ts` 中引入并注册 uView Pro：\n\n```js\n// main.ts\nimport { createSSRApp } from \"vue\";\n// npm 方式\nimport uViewPro from \"uview-pro\";\n// uni_modules 方式\n// import uViewPro from \"@/uni_modules/uview-pro\";\n\nexport function createApp() {\n  const app = createSSRApp(App);\n  app.use(uViewPro);\n  return {\n    app,\n  };\n}\n```\n\n### 3. 引入全局样式\n\n在 `uni.scss` 中引入主题样式：\n\n```scss\n/* uni.scss */\n// npm 方式\n@import \"uview-pro/theme.scss\";\n// uni_modules 方式\n// @import \"@/uni_modules/uview-pro/theme.scss\";\n```\n\n在 `App.vue` 首行引入基础样式：\n\n```scss\n<style lang=\"scss\">\n  // npm 方式\n  @import \"uview-pro/index.scss\";\n  // uni_modules 方式\n  // @import \"@/uni_modules/uview-pro/index.scss\";\n</style>\n```\n\n### 4. 配置 easycom 自动引入组件\n\n在 `pages.json` 中配置 easycom 规则，实现组件自动引入：\n\n```json\n// pages.json\n{\n  \"easycom\": {\n    \"autoscan\": true,\n    \"custom\": {\n      // npm 方式\n      \"^u-(.*)\": \"uview-pro/components/u-$1/u-$1.vue\",\n      // uni_modules 方式\n      // \"^u-(.*)\": \"@/uni_modules/uview-pro/components/u-$1/u-$1.vue\"\n    }\n  },\n  \"pages\": [\n    // ...\n  ]\n}\n```\n\n\n- 1.修改 `easycom` 规则后需重启 HX 或重新编译项目。\n- 2.请确保 `pages.json` 中只有一个 easycom 字段，否则请自行合并多个规则。\n- 3.一定要放在 `custom` 内，否则无效。\n\n\n### 5. Volar 类型提示支持\n\n如需在 CLI 项目中获得 Volar 的全局类型提示，请在 `tsconfig.json` 中添加：\n\n```json\n{\n  \"compilerOptions\": {\n    // npm 方式\n    \"types\": [\"uview-pro/types\"]\n    // uni_modules 方式\n    // \"types\": [\"@/uni_modules/uview-pro/types\"]\n  }\n}\n```\n\n> HBuilderX 项目暂不支持 tsconfig.json 的 types 配置，CLI 项目推荐配置以获得最佳 TS 体验。\n\n### 6. 组件使用\n\n配置完成后，无需 import 和 components 注册，可直接在 SFC 中使用 uView Pro 组件：\n\n```vue\n<template>\n  <u-button type=\"primary\">按钮</u-button>\n</template>\n```\n\n"
  },
  {
    "path": "src/static/app/markdown/settingDesc.md",
    "content": "## 配置的原理\n\n#### 1. 引入uView主JS库\n\n为何要在`main.js`引入uView的JS库？\n\n因为uView内部集成了很多的便捷JS工具，比如获取随机数的`radnom`方法，调用为`uni.$u.radom(min, max)`，可见这些方法都挂载在`$u`下，\n我们能通过`this`调用`$u`，又是因为`$u`挂载在Vue的原型链上，在这里uView的做法为通过`Vue.use`，以插件的形式在内部进行`Vue.property`的挂载。  \n\n而`main.js`就是整个项目JS的入口，且Vue也是在这里引入的，所以我们自然而然就会想到把uView的JS库在`mian.js`中引入了，如下：\n\n```js\n// main.js\nimport uView from \"uview-pro\";\nVue.use(uView);\n```\n\n注：或许您想知道`Vue.use`的作用是什么，见[简要介绍Vue.use的原理](/components/vueUse.html)\n\n\n#### 2. 引入uView的全局SCSS主题文件\n\nuni-app不支持将SCSS变量相关的样式通过`App.vue`引入，为了统一的主题，以及日后的扩展，\n目前一些跟颜色相关的scss变量定义在全局变量中，这些变量有独特的命名(`u-`开头)，不会与您的类名冲突。  \n\n这些变量需要写入到项目根目录的`uni.scss`中才有效(这是uni-app的机制问题)，它有一个特点是，编译成微信小程序后，不但注入到小程序工程\n根目录的`app.wxss`(全局样式文件)，而且还会同步注入到每一个页面单独的`*.wxss`中，所以如果您在`uni.scss`中的样式很多的话，有可能导致\n微信小程序编译单个包超出限制的`2M`大小，整包超出最大的`12M`大小，从而导致无法真机调试和发布微信小程序。\n\n所以，我们建议，只将一些跟`scss`主题，变量相关的样式写入到`uni.scss`，而其他一般的全局样式文件，通过`App.vue`引入即可，在微信小程序编译的时候，\n它只会编译到小程序根目录的`app.wxss`中，而不会注入到其他的单个页面的样式中。\n \n\n\n#### 3. 引入基础样式\n\n由于目前(2020-04-29)uni-app的V3模式不支持在`main.js`中引入样式文件，故需要在`App.vue`中引入uView的基础全局样式。  \n同时上面第2点也有说明，`App.vue`的样式为全局样式，微信小程序编译后只会注入到小程序根目录的`app.wxss`中。\n\n\n\n#### 4. 配置easycom组件模式\n\neasycom功能可以让用户无需安装、引用、注册，三个步骤后才能使用组件，详见[easycom文档](https://uniapp.dcloud.io/collocation/pages?id=easycom)\n\neasycom的另一个最大的特点是，它是**按需引入**的，所以您引入了整个uView组件，即使只用到了`button`组件，最终打包的时候只会把`button`打包进去，其他的组件都会被剔除。  \n\nHbuilder X自2.5.1版开始正式支持`easycom`特性，**HX2.5.5**版支持自动引入`components/组件名称/组件名称.vue`，考虑到用户的一些自定义组件\n都会放在`components`目录中，为了不和用户的自定义组件混淆，同时也是为了能让用户一键升级uView，所以我们把uView相关的所有内容都放在了根目录的\n`uview-pro`文件夹中。\n\n\nuni-app为了调试性能的原因，修改`easycom`规则不会实时生效，配置完后，您需要重启HX或者重新编译项目才能正常使用uView的功能。\n"
  },
  {
    "path": "src/static/app/markdown/skeleton.md",
    "content": "## Skeleton 骨架屏 <to-api/>\n\n<demo-model url=\"/pages/componentsB/skeleton/index\"></demo-model>\n\n\n骨架屏一般用于页面在请求远程数据尚未完成时，页面用灰色块预显示本来的页面结构，给用户更好的体验。  \n\n\n该组件原理是通过uni的uni.createSelectorQuery接口，查询页面带有指定类名的元素的位置和尺寸，\n通过绝对定位的方式，用同样尺寸的灰色块定位到相同的位置。  \n所以要求在请求数据尚未完成时，填写一些模拟数据，才能让对应的元素有对应的尺寸和位置，供uni.createSelectorQuery查询使用\n\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |    √     |\n\n### 基本使用\n\n该组件的使用，需要有几个类名是必须的，如下：\n- `u-skeleton`(必须)，该类名用于页面的`最外层元素`，供骨架屏组件查询和定位出绘制骨架的位置和尺寸\n- `u-skeleton-circle`(可选)，该类名用于页面的圆形元素，供骨架组件描绘出圆形的骨架块\n- `u-skeleton-rect`(可选)，该类名用于页面的矩形元素，供骨架组件描绘出矩形的骨架块\n- `u-skeleton-fillet`(可选)，该类名用于页面的矩形带圆角元素，供骨架组件描绘出矩形带圆角的骨架块\n\n数据请求完成后，将`loading`设置为`false`，会隐藏骨架组件\n\n```html\n<template>\n\t<view>\n\t\t<view class=\"container u-skeleton\">\n\t\t\t<view class=\"userinfo\">\n\t\t\t\t<block>\n\t\t\t\t\t<!--u-skeleton-circle 绘制圆形-->\n\t\t\t\t\t<image class=\"userinfo-avatar u-skeleton-circle\" :src=\"userInfo.avatarUrl\"></image>\n\t\t\t\t\t<!--u-skeleton-fillet 绘制圆角矩形-->\n\t\t\t\t\t<text class=\"u-skeleton-fillet\">{{userInfo.nickName}}</text>\n\t\t\t\t</block>\n\t\t\t</view>\n\t\t\t<view style=\"margin: 20px 0\">\n\t\t\t\t<view v-for=\"(item,index) in lists\" :key=\"index\" class=\"lists\">\n\t\t\t\t\t<!--u-skeleton-rect 绘制矩形-->\n\t\t\t\t\t<text class=\"u-skeleton-rect\">{{item}}</text>\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t</view>\n\t\t<!--引用组件-->\n\t\t<u-skeleton :loading=\"loading\" :animation=\"true\" bgColor=\"#FFF\"></u-skeleton>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\t// 随意填充一些模拟数据，以撑开元素，供骨架组件查询和模拟块状数据\n\t\t\t\tuserInfo: {\n\t\t\t\t\tavatarUrl: 'https://qlogo2.store.qq.com/qzone/1416956117/1416956117/100?1531323520',\n\t\t\t\t\tnickName: 'uView'\n\t\t\t\t},\n\t\t\t\tlists: [\n\t\t\t\t\t'君不见，黄河之水天上来，奔流到海不复回。君不见，高堂明镜悲白发，朝如青丝暮成雪。',\n\t\t\t\t\t'人生得意须尽欢，莫使金樽空对月',\n\t\t\t\t\t'天生我材必有用，千金散尽还复来',\n\t\t\t\t],\n\t\t\t\tloading: true, // 是否显示骨架屏组件\n\t\t\t}\n\t\t},\n\t\tonLoad() {\n\t\t\t// 通过延时模拟向后端请求数据，调隐藏骨架屏\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.loading = false;\n\t\t\t}, 2000)\n\t\t}\n\t}\n</script>\n\n<style lang=\"scss\" scoped>\n\t.container {\n\t\tpadding: 20rpx 60rpx;\n\t}\n\n\t.userinfo {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\talign-items: center;\n\t}\n\n\t.userinfo-avatar {\n\t\twidth: 128rpx;\n\t\theight: 128rpx;\n\t\tmargin: 20rpx;\n\t\tborder-radius: 50%;\n\t}\n\n\t.lists {\n\t\tmargin: 10px 0;\n\t}\n</style>\n```\n\n### 加载中动画\n\n设置`animation`为`true`，加载中的骨架块将会有一个动画效果，用以加强视觉效果。\n\n```html\n<u-skeleton :loading=\"true\" :animation=\"true\"></u-skeleton>\n```\n\n### 其他设置\n\n- 通过`el-color`参数设置骨架块的背景颜色\n- 通过`bg-color`参数设置整个骨架组件的背景颜色\n\n```html\n<u-skeleton :loading=\"true\" el-color=\"#ddd\" bg-color=\"#fff\"></u-skeleton>\n```\n\n### API\n\n### Props\n\n| 参数          | 说明                                                         | 类型             | 默认值  | 可选值 |\n| ------------- | ------------------------------------------------------------ | ---------------- | ------- | ------ |\n| el-color      | 骨架块状元素的背景颜色                                       | String           | #e5e5e5 | -      |\n| bg-color      | 骨架组件背景颜色                                             | String           | #ffffff | -      |\n| animation     | 骨架块是否显示动画效果                                       | Boolean          | false   | true   |\n| border-radius | `u-skeleton-fillet`类名元素，对应的骨架块的圆角大小，单位rpx | String \\| Number | 10      | -      |\n| loading       | 是否显示骨架组件，请求完成后，将此值设置为`false`            | Boolean          | true    | false  |\n\n"
  },
  {
    "path": "src/static/app/markdown/slider.md",
    "content": "## Slider 滑动选择器 <to-api/>\n      \n<demo-model url=\"/pages/componentsA/slider/index\"></demo-model>\n\n该组件一般用于表单中，手动选择一个区间范围的场景。\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |    √     |\n\n### 基本使用\n\n需要通过`v-model`绑定一个值，来初始化滑块的选择值(0到100之间)，这个值是双向绑定的，您可以通过这个值，实时地得知内部的滑动结果。\n\n\n```html\n<template>\n\t<view class=\"wrap\">\n\t\t<u-slider v-model=\"value\"></u-slider>\n\t</view>\n</template>\n\t\n<script>\n\texport default {\n\t\tdata() {\t\n\t\t\treturn {\n\t\t\t\tvalue: 30\n\t\t\t}\n\t\t}\n\t}\n</script>\n\n<style scoped lang=\"scss\">\n\t.wrap {\n\t\tpadding: 30rpx;\n\t}\n</style>\n```\n\n### 设置最大和最小值\n\n通过`min`和`max`，可以设置滑块所能选择的最大和最小值\n\n```html\n<u-slider v-model=\"value\" min=\"30\" max=\"80\"></u-slider>\n```\n\n\n### 设置步进值\n\n通过`step`参数设置步进值，这个步进值为每次跳变的值，具体表现请见示例。  \n\n\n需要注意的是，这个`step`必须要被`max`值整除，否则会出现无法无法滑动到最大值的情况\n\n\n```html\n<u-slider v-model=\"value\" step=\"20\" min=\"30\" max=\"100\"></u-slider>\n```\n\n\n### 自定义按钮的内容和样式\n\n通过设置`use-slot`为`true`，可以以传入`slot`的形式，替换默认的滑块按钮。\n\n以下示例结合了`value`值，在按钮上实时显示选择的值：\n\n```html\n<template>\n\t<view class=\"wrap\">\n\t\t<u-slider v-model=\"value\" :use-slot=\"true\">\n\t\t\t<!-- 这里外面需要多一层view，否则\".badge-button\"样式可能不生效 -->\n\t\t\t<view class=\"\">\n\t\t\t\t<view class=\"badge-button\">\n\t\t\t\t\t{{value}}\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t</u-slider>\n\t</view>\n</template>\n\t\n<script>\n\texport default {\n\t\tdata() {\t\n\t\t\treturn {\n\t\t\t\tvalue: 30\n\t\t\t}\n\t\t}\n\t}\n</script>\n\n<style scoped lang=\"scss\">\n\t.wrap {\n\t\tpadding: 30rpx;\n\t}\n\t\n\t.badge-button {\n\t\tpadding: 4rpx 6rpx;\n\t\tbackground-color: $u-type-error;\n\t\tcolor: #fff;\n\t\tborder-radius: 10rpx;\n\t\tfont-size: 22rpx;\n\t\tline-height: 1;\n\t}\n</style>\n```\n\n\n### 自定义滑动选择器整体的样式\n\n- 通过`inactive-color`配置底部滑动条背景颜色\n- 通过`active-color`配置底部选择部分的背景颜色\n- 通过`block-width`配置滑块宽度(高等于宽)\n- 通过`block-color`配置滑动按钮按钮的颜色\n- 通过`height`配置滑块条高度，单位rpx\n\n其他更多参数详见底部API\n\n```html\n<u-slider v-model=\"value\" block-width=\"40\" block-color=\"red\"></u-slider>\n```\n\n\n### API\n\n### Props\n\n| 参数           | 说明                              | 类型             | 默认值  | 可选值 |\n| -------------- | --------------------------------- | ---------------- | ------- | ------ |\n| v-model        | 双向绑定滑块选择值                | String \\| Number | 0       | -      |\n| min            | 可选的最小值(0-100之间)           | String \\| Number | 0       | -      |\n| max            | 可选的最大值(0-100之间)           | String \\| Number | 100     | -      |\n| step           | 选择的步长                        | String \\| Number | 1       | -      |\n| block-width    | 滑动按钮的宽度(高等于宽)，单位rpx | String \\| Number | 30      | -      |\n| height         | 滑动选择条的高度，单位rpx         | String \\| Number | 6       | -      |\n| inactive-color | 滑动选择条的底部背景颜色          | String           | #c0c4cc | -      |\n| active-color   | 底部选择部分的背景颜色            | String           | #2979ff | -      |\n| block-color    | 滑块背景颜色                      | String           | #ffffff | -      |\n| block-style    | 给滑块按钮自定义样式，对象形式    | Object           | -       | -      |\n| disabled       | 是否禁用滑块                      | Boolean          | false   | true   |\n| use-slot       | 是否使用slot传入自定义滑块        | Boolean          | false   | true   |\n\n\n### Slot\n\n| 名称 | 说明           |\n| ---- | -------------- |\n| -    | 自定义滑块内容 |\n\n\n\n### Events\n\n| 事件名 | 说明 | 回调参数 |\n| :----- | :--- | :------- ||\n| start  | 触发滑块移动 | -        |\n| moving | 正在滑动中   | -        |\n| end    | 滑动结束     | -        |\n\n"
  },
  {
    "path": "src/static/app/markdown/steps.md",
    "content": "## Steps 步骤条 <to-api/>\n\n<demo-model url=\"/pages/componentsB/steps/index\"></demo-model>\n\n\n该组件一般用于完成一个任务要分几个步骤，标识目前处于第几步的场景。\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n- 通过`list`参数传入一个数组，标识步骤的总数\n- 通过`current`参数标识目前处于第几步，从0开始\n\n```html\n<template>\n\t<view>\n\t\t<u-steps :list=\"numList\" :current=\"1\"></u-steps>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tnumList: [{\n\t\t\t\t\tname: '下单'\n\t\t\t\t}, {\n\t\t\t\t\tname: '出库'\n\t\t\t\t}, {\n\t\t\t\t\tname: '运输'\n\t\t\t\t}, {\n\t\t\t\t\tname: '签收'\n\t\t\t\t}, ],\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 设置步骤条的主题\n\n- `type`值可选的有`primary`(默认)、`success`、`info`、`warning`、`error`\n- `type`值和`active-color`(默认为空)为互斥关系，如果设置了`active-color`，会优先起作用\n\n```html\n<u-steps :list=\"numList\" active-color=\"#fa3534\"></u-steps>\n```\n\n### 设置步骤条的模式\n\n`mode`可以设置为`dot`(圆点，默认值)或者`number`(数字)，二者有不同形式，见示例\n\n```html\n<u-steps :list=\"numList\" mode=\"number\"></u-steps>\n```\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| mode | 设置模式  | String | dot | number |\n| list | 数轴条数据，数组。具体见上方示例  | Array | [ ] | - |\n| type(1.3.7起已废弃) | type主题 | String  | primary | info / success / error / warning |\n| current | 设置当前处于第几步 | Number \\| String  | 0 | - |\n| direction | row-横向，column-竖向 | String  | row | column |\n| active-color | 已完成步骤的激活颜色，如设置，`type`值会失效 | String  | - | - |\n| un-active-color | 未激活的颜色，用于表示未完成步骤的颜色 | String  | #606266 | - |\n| icon | mode = number时的自定义图标  | String  | checkmark | - |"
  },
  {
    "path": "src/static/app/markdown/sticky.md",
    "content": "## Sticky 吸顶 <to-api/>\n\n<demo-model url=\"/pages/componentsB/sticky/index\"></demo-model>\n\n\n该组件与CSS中`position: sticky`属性实现的效果一致，当组件达到预设的到顶部距离时，\n就会固定在指定位置，组件位置大于预设的顶部距离时，会重新按照正常的布局排列。\n\n<custom-block text=\"由于右侧的演示是通过iframe标签引入的，缺少了手机端运行的相关API，所以吸顶是看不到效果的，手机端有不会这些问题，请在右上角的“演示”中用手机扫码查看对应的效果\"></custom-block>\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |    √     |\n\n### 基本使用\n\n通过`slot`，将需要吸顶的内容放在`Sticky`组件中即可，`slot`中只能有一个根元素\n\n\n由于页面依赖相关的原因的，部分页面会出现**Cannot read property 'bottom' of null**的报错，可以参考 [issue #239](https://github.com/YanxinNet/uView/issues/239) 进行处理。\n\n\n```html\n<template>\n\t<view class=\"container\">\n\t\t<u-sticky>\n\t\t\t<!-- 只能有一个根元素 -->\n\t\t\t<view class=\"sticky\">\n\t\t\t\t宝剑锋从磨砺出,梅花香自苦寒来\n\t\t\t</view>\n\t\t</u-sticky>\n\t</view>\n</template>\n\n<style lang=\"scss\" scoped>\n\t.container {\n\t\theight: 200vh;\n\t\tmargin-top: 150rpx;\n\t}\n\t\n\t.sticky {\n\t\twidth: 750rpx;\n\t\theight: 120rpx;\n\t\tbackground-color: #2979ff;\n\t\tcolor: #fff;\n\t\tpadding: 24rpx;\n\t}\n</style>\n```\n\n### 吸顶距离\n\n通过`offset-top`参数设置组件在吸顶时与顶部的距离\n\n```html\n<u-sticky offset-top=\"200\">\n\t<view>\n\t\t塞下秋来风景异，衡阳雁去无留意\n\t</view>\n</u-sticky>\n```\n\n### API\n\n### Props\n\n| 参数          | 说明                                                                        | 类型             | 默认值  | 可选值 |\n| ------------- | --------------------------------------------------------------------------- | ---------------- | ------- | ------ |\n| offset-top    | 吸顶时与顶部的距离，单位rpx                                                 | String \\| Number | 0       | -      |\n| index         | 自定义标识，用于区分是哪一个组件                                            | String \\| Number | -       | -      |\n| enable        | 是否开启吸顶功能                                                            | Boolean          | true    | false  |\n| bg-color      | 组件背景颜色                                                                | String           | #ffffff | -      |\n| z-index       | 吸顶时的`z-index`值                                                         | String \\| Number | 970     | -      |\n| h5-nav-height | 导航栏高度，自定义导航栏时(无导航栏时需设置为`0`)，需要传入此值，单位**px** | String \\| Number | 44      | -      |\n\n### Event\n\n| 事件名  | 说明               | 回调参数                      |\n| :------ | :----------------- | :---------------------------- |\n| fixed   | 组件吸顶时触发     | index: 通过props传递的`index` |\n| unfixed | 组件取消吸顶时触发 | index: 通过props传递的`index` |\n"
  },
  {
    "path": "src/static/app/markdown/subsection.md",
    "content": "## Subsection 分段器 <to-api/>\n\n<demo-model url=\"/pages/componentsC/subsection/index\"></demo-model>\n\n\n该分段器一般用于用户从几个选项中选择某一个的场景\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n- 通过`list`数组参数传递分段的选项\n- 通过`current`指定初始化时激活的选项\n\n```html\n<template>\n\t<u-subsection :list=\"list\" :current=\"1\"></u-subsection>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tlist: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: '待发货'\n\t\t\t\t\t}, \n\t\t\t\t\t{\n\t\t\t\t\t\tname: '待付款'\n\t\t\t\t\t}, \n\t\t\t\t\t{\n\t\t\t\t\t\tname: '待评价'\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\tcurrent: 1\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 模式选择\n\n通过`mode`设置分段器的模式\n- 值为`button`时为按钮类型\n- 值为`subsection`时为分段器形式\n\n```html\n<u-subsection :list=\"list\" :current=\"1\"></u-subsection>\n```\n\n### 是否开启动画效果\n\n`animation`(默认为`true`)设置为`true`的话，分段器的三种模式滑块移动时都会有动画效果\n\n```html\n<u-subsection :animation=\"true\"></u-subsection>\n```\n\n### 颜色配置\n\n- 通过`active-color`配置激活选项的文字颜色，`mode`为`subsection`时无效，此时默认为白色：\n- 通过`bgColor`配置背景颜色\n- 通过`buttonColor`配置按钮颜色，`mode`为`button`时有效\n\n```html\n<u-subsection active-color=\"#ff9900\"></u-subsection>\n```\n\n\n### 注意事项\n\n如果想通过一个变量绑定`current`值，需要在`change`事件回调中修改此值，否则可能会由于`props`的限制，前后两次设置`current`为相同的值，\n而导致无法通过修改`current`值触发分段器的变化。\n\n```html\n<template>\n\t<view>\n\t\t<u-subsection :list=\"list\" :current=\"curNow\" @change=\"sectionChange\"></u-subsection>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tlist: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: '待发货'\n\t\t\t\t\t}, \n\t\t\t\t\t{\n\t\t\t\t\t\tname: '待付款'\n\t\t\t\t\t}, \n\t\t\t\t\t{\n\t\t\t\t\t\tname: '待评价'\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\tcurNow: 0\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\tsectionChange(index) {\n\t\t\t\tthis.curNow = index;\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| list | 选项的数组，形式见上方\"基本使用\" | Array | - | - |\n| current | 初始化时默认选中的选项索引值  | String \\| Number | 0 | - |\n| active-color | 激活时的颜色 | String | #303133 | - |\n| inactive-color | 未激活时的颜色 | String | #606266 | - |\n| mode | 模式选择，见上方\"模式选择\"说明 | String | button | subsection |\n| font-size | 字体大小，单位rpx | String \\| Number | 28 | - |\n| height | 组件高度，单位rpx | String \\| Number | 70 | - |\n| animation | 是否开启动画效果，见上方说明 | Boolean | true | false |\n| bold | 激活选项的字体是否加粗 | Boolean | true | false |\n| bg-color | 组件背景颜色，`mode`为`button`时有效 | String | #eeeeef | - |\n| button-color | 按钮背景颜色，`mode`为`button`时有效 | String | #ffffff | - |\n\n### Events\n\n| 事件名 | 说明 | 回调参数 |\n| :- | :- | :- |\n| change | 分段器选项发生改变时触发 | index：选项的index索引值，从0开始 |\n"
  },
  {
    "path": "src/static/app/markdown/swipeAction.md",
    "content": "## SwipeAction 滑动操作 <to-api/>\n\n<demo-model url=\"/pages/componentsB/swipeAction/index\"></demo-model>\n\n该组件一般用于左滑唤出操作菜单的场景，用的最多的是左滑删除操作。\n\n\n如果把该组件通过 v-for 用于左滑删除的列表，请保证循环的`:key`是一个唯一值，可以用数据的 id 或者 title 替代。\n不能是数组循环的 index，否则删除的时候，可能会出现数据错乱\n\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ 小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :-------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |     √     |\n\n### 基本使用\n\n- 通过 slot 传入内部内容即可，可以将`v-for`的\"index\"索引值传递给`index`参数，用于点击时，在回调方法中对某一个数据进行操作(点击回调时第一个参数会返回此索引值)\n- 内部的按钮通过`options`参数配置，此参数为一个数组，元素为对象，可以配置按钮的文字，背景颜色(建议只配置此两个参数即可)，**请勿配置宽高等属性**。\n\n说明：有时候，我们在打开一个 swipeAction 的同时，需要自动关闭其他的 swipeAction，这时需要通过`open`事件实现，见如下：\n\n```html\n<template>\n  <view>\n    <u-swipe-action\n      :show=\"item.show\"\n      :index=\"index\"\n      v-for=\"(item, index) in list\"\n      :key=\"item.id\"\n      @click=\"click\"\n      @open=\"open\"\n      :options=\"options\"\n    >\n      <view class=\"item u-border-bottom\">\n        <image mode=\"aspectFill\" :src=\"item.images\" />\n        <!-- 此层wrap在此为必写的，否则可能会出现标题定位错误 -->\n        <view class=\"title-wrap\">\n          <text class=\"title u-line-2\">{{ item.title }}</text>\n        </view>\n      </view>\n    </u-swipe-action>\n  </view>\n</template>\n\n<script>\n  export default {\n    data() {\n      return {\n        list: [\n          {\n            id: 1,\n            title:\n              \"长安回望绣成堆，山顶千门次第开，一骑红尘妃子笑，无人知是荔枝来\",\n            images: \"https://ik.imagekit.io/anyup/uview-pro/common/logo.png\",\n            show: false,\n          },\n          {\n            id: 2,\n            title:\n              \"新丰绿树起黄埃，数骑渔阳探使回，霓裳一曲千峰上，舞破中原始下来\",\n            images: \"https://ik.imagekit.io/anyup/uview-pro/common/logo.png\",\n            show: false,\n          },\n          {\n            id: 3,\n            title: \"登临送目，正故国晚秋，天气初肃。千里澄江似练，翠峰如簇\",\n            images: \"https://ik.imagekit.io/anyup/uview-pro/common/logo.png\",\n            show: false,\n          },\n        ],\n        disabled: false,\n        btnWidth: 180,\n        show: false,\n        options: [\n          {\n            text: \"收藏\",\n            style: {\n              backgroundColor: \"#007aff\",\n            },\n          },\n          {\n            text: \"删除\",\n            style: {\n              backgroundColor: \"#dd524d\",\n            },\n          },\n        ],\n      };\n    },\n    methods: {\n      click(index, index1) {\n        if (index1 == 1) {\n          this.list.splice(index, 1);\n          uni.$u.toast(`删除了第${index}个cell`);\n        } else {\n          this.list[index].show = false;\n          uni.$u.toast(`收藏成功`);\n        }\n      },\n      // 如果打开一个的时候，不需要关闭其他，则无需实现本方法\n      open(index) {\n        // 先将正在被操作的swipeAction标记为打开状态，否则由于props的特性限制，\n        // 原本为'false'，再次设置为'false'会无效\n        this.list[index].show = true;\n        this.list.map((val, idx) => {\n          if (index != idx) this.list[idx].show = false;\n        });\n      },\n    },\n  };\n</script>\n\n<style lang=\"scss\" scoped>\n  .item {\n    display: flex;\n    padding: 20rpx;\n  }\n\n  image {\n    width: 120rpx;\n    flex: 0 0 120rpx;\n    height: 120rpx;\n    margin-right: 20rpx;\n    border-radius: 12rpx;\n  }\n\n  .title {\n    text-align: left;\n    font-size: 28rpx;\n    color: $u-content-color;\n    margin-top: 20rpx;\n  }\n</style>\n```\n\n### 修改按钮样式\n\n- 通过`options`参数配置按钮的数量和样式，见上方说明\n- 通过`btn-width`设置按钮的宽度，单位 rpx\n\n```html\n<u-swipe-action btn-width=\"180\" :options=\"options\"> ... </u-swipe-action>\n```\n\n### 点击事件\n\n`click`点击事件回调中，有两个参数，第一个参数为通过 Props 传入的`index`参数，第二个参数为滑动按钮的索引，即`options`数组的索引，\n用于标识第几个按钮被点击。\n\n### API\n\n### Props\n\n| 参数          | 说明                                                                      | 类型             | 默认值  | 可选值 |\n| ------------- | ------------------------------------------------------------------------- | ---------------- | ------- | ------ |\n| bg-color      | 整个组件背景颜色                                                          | String           | #ffffff | -      |\n| index         | 标识符，点击时候用于区分点击了哪一个，用`v-for`循环时的 index 即可        | String \\| Number | -       | -      |\n| btn-width     | 按钮宽度，单位 rpx                                                        | String \\| Number | 180     | -      |\n| disabled      | 是否禁止某个 swipeAction 滑动                                             | Boolean          | false   | true   |\n| vibrate-short | 是否使手机发生短促震动，目前只在 iOS 的微信小程序和微信小程序开发工具有效 | Boolean          | false   | true   |\n| show          | 打开或者关闭某个组件                                                      | Boolean          | false   | true   |\n| options       | 按钮组的配置参数，数组形式，见上方说明                                    | Array            | [ ]     | -      |\n\n### Event\n\n| 事件名        | 说明               | 回调参数                                |\n| :------------ | :----------------- | :-------------------------------------- |\n| click         | 点击组件时触发     | (index1, index)，见上方\"点击事件\"的说明 |\n| close         | 组件触发关闭状态时 | index: 通过 props 传递的`index`         |\n| open          | 组件触发打开状态时 | index: 通过 props 传递的`index`         |\n| content-click | 点击内容时触发     | index: 通过 props 传递的`index`         |\n"
  },
  {
    "path": "src/static/app/markdown/swiper.md",
    "content": "## Swiper 轮播图 <to-api/>\n\n<demo-model url=\"/pages/componentsB/swiper/index\"></demo-model>\n\n该组件一般用于导航轮播，广告展示等场景,可开箱即用，具有如下特点：\n\n- 内置多种指示器模式，可配置指示器位置\n- 3D 轮播图效果\n- 可配置是否显示标题\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ 小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :-------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |     √     |\n\n### 基本使用\n\n通过`list`参数传入轮播图列表值，该值为一个数组，元素为对象，见如下：\n\n- `list`的\"image\"属性为轮播图的图片路径\n- `list`的\"title\"属性为需要显示的标题\n\n**说明：** 某些情况下\n\n1. 您从服务端获取的数据，里面的数组对于图片的属性名不一定为`image`，如果让您再历遍修改为`image`属性，显然是不人性的，\n   所以 uView 提供了一个`name`参数，比如您数组中的图片名称为`img`，您可以设置`u-swiper`组件的`name`参数为`img`值。\n\n2. 您也可以直接传递一个元素为图片路径的数组给`list`参数，如下(1.6.5 支持)：\n\n```html\n<u-swiper :list=\"list\"></u-swiper>\n\nlet list = [ '1.png', '2.png' ];\n```\n\n\n如果需要显示标题，还需要设置`title`参数为`true`\n\n\n```html\n<template>\n  <view class=\"wrap\">\n    <u-swiper :list=\"list\"></u-swiper>\n  </view>\n</template>\n\n<script>\n  export default {\n    data() {\n      return {\n        list: [\n          {\n            image: \"https://cdn.uviewui.com/uview/xxx.jpg\",\n            title: \"昨夜星辰昨夜风，画楼西畔桂堂东\",\n          },\n          {\n            image: \"https://cdn.uviewui.com/uview/xxx.jpg\",\n            title: \"身无彩凤双飞翼，心有灵犀一点通\",\n          },\n          {\n            image: \"https://cdn.uviewui.com/uview/xxx.jpg\",\n            title: \"谁念西风独自凉，萧萧黄叶闭疏窗，沉思往事立残阳\",\n          },\n        ],\n      };\n    },\n    methods: {},\n  };\n</script>\n\n<style lang=\"scss\" scoped>\n  .wrap {\n    padding: 40rpx;\n  }\n</style>\n```\n\n### 指示器类型\n\n本组件内置了多种指示器，通过配置`mode`参数即可，有如下：\n\n- `rect`-指示器为方块状\n- `dot`-指示器为圆点\n- `number`-指示器为数字\n- `round`-激活的指示器为块状，未激活的未点状，为默认值\n- `none`-不显示指示器\n\n通过`indicator-pos`参数配置指示器的位置，有如下值：\n\n- `topLeft`-指示器位于左上角\n- `topCenter`-指示器位于上方中间位置\n- `topRight`-指示器位于右上角\n- `bottomLeft`-指示器位于左下角\n- `bottomCenter`-指示器位于底部中间位置，为默认值\n- `bottomRight`-指示器位于右下角\n\n```html\n<u-swiper :list=\"list\" mode=\"dot\" indicator-pos=\"bottomRight\"></u-swiper>\n```\n\n### 是否开启 3D 效果\n\n配置`effect3d`为`true`即可，该效果左右两边可以缩略形式预览前后一个 swiper-item 的一部分\n\n```html\n<u-swiper :list=\"list\" :effect3d=\"true\"></u-swiper>\n```\n\n### 控制轮播效果\n\n- `autoplay`-是否自动轮播，默认为`true`\n- `interval`-前后两张图自动轮播的时间间隔\n- `duration`-切换一张轮播图所需的时间\n- `circular`-是否衔接滑动，即到最后一张时，是否可以直接转到第一张\n\n```html\n<u-swiper :list=\"list\" duration=\"3000\" :circular=\"false\"></u-swiper>\n```\n\n### API\n\n### Props\n\n| 参数                     | 说明                                                                               | 类型             | 默认值       | 可选值                                                    |\n| ------------------------ | ---------------------------------------------------------------------------------- | ---------------- | ------------ | --------------------------------------------------------- |\n| list                     | 轮播图数据，见上方\"基本使用\"说明                                                   | Array            | -            | -                                                         |\n| title                    | 是否显示标题文字，需要配合`list`参数，见上方说明                                   | Boolean          | false        | true                                                      |\n| mode                     | 指示器模式，见上方说明                                                             | String           | round        | rect / dot / number / none                                |\n| height                   | 轮播图组件高度，单位 rpx                                                           | String \\| Number | 250          | -                                                         |\n| indicator-pos            | 指示器的位置                                                                       | String           | bottomCenter | topLeft / topCenter / topRight / bottomLeft / bottomRight |\n| effect3d                 | 是否开启 3D 效果                                                                   | Boolean          | false        | true                                                      |\n| autoplay                 | 是否自动播放                                                                       | Boolean          | true         | false                                                     |\n| interval                 | 自动轮播时间间隔，单位 ms                                                          | String \\| Number | 2500         | -                                                         |\n| circular                 | 是否衔接播放，见上方说明                                                           | Boolean          | true         | false                                                     |\n| duration                 | 切换一张轮播图所需的时间，单位 ms                                                  | String \\| Number | 500          | -                                                         |\n| border-radius            | 轮播图圆角值，单位 rpx                                                             | String \\| Number | 8            | -                                                         |\n| title-style              | 自定义标题样式                                                                     | Object           | -            | -                                                         |\n| effect3d-previous-margin | effect3d = true 模式的情况下，激活项与前后项之间的距离，单位 rpx                   | String \\| Number | 50           | -                                                         |\n| img-mode                 | 图片的裁剪模式，详见[image 组件裁剪模式](https://uniapp.dcloud.io/component/image) | String           | aspectFill   | -                                                         |\n| name                     | 组件内部读取的`list`参数中的属性名，见上方说明                                     | string           | name         | -                                                         |\n| bg-color                 | 背景颜色                                                                           | string           | #f3f4f6      | -                                                         |\n| current                  | 初始化时，默认显示第几项                                                           | String \\| Number | 0            | -                                                         |\n\n### Events\n\n| 事件名 | 说明                               | 回调参数                             |\n| :----- | :--------------------------------- | :----------------------------------- |\n| click  | 点击轮播图时触发                   | index：点击了第几张图片，从 0 开始   |\n| change | 轮播图切换时触发(自动或者手动切换) | index：切换到了第几张图片，从 0 开始 |\n"
  },
  {
    "path": "src/static/app/markdown/switch.md",
    "content": "## Switch 开关选择器 <to-api/>\n\n<demo-model url=\"/pages/componentsB/switch/index\"></demo-model>\n\n\n选择开关一般用于只有两个选择，且只能选其一的场景。\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |    √     |\n\n### 基本使用\n\n通过`v-model`绑定一个`布尔值`变量，这个变量是双向绑定的，当用户开或关选择器的时候，在父组件的该值也会相应的变为`true`或者`false`，也就是说，\n您不用监听`change`事件，也能知道选择器当前处于**开**或者**关**的状态。\n\n\n```html\n<template>\n\t<u-switch v-model=\"checked\"></u-switch>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tchecked: false,\n\t\t\t};\n\t\t},\n\t\tmethods: {\n\t\t\t// switch打开或者关闭时触发，值为true或者false\n\t\t\t// 即使不监听此事件，this.checked此时也会相应的变成true或者false\n\t\t\tchange(status) {\n\t\t\t\t// console.log(status);\n\t\t\t},\n\t\t}\n\t};\n</script>\n```\n\n### 禁用switch\n\n设置`disabled`为`true`，即可禁用某个组件，让用户无法点击，禁用分为两种状态：\n\n- 一是关闭情况下的禁用，这时只显示一个白色的区域。\n- 二是打开后再禁用，这时会在原有的颜色上加一个`opacity`透明度，但此时依然是不可操作的。\n\n```html\n<u-switch v-model=\"checked\" :disabled=\"true\"></u-switch>\n```\n\n### 加载中\n\n通过设置`loading`变量为`true`，可以让`switch`处于加载中的状态，这时`switch`是不可操作的\n\n```html\n<u-switch v-model=\"checked\" :loading=\"true\"></u-switch>\n\n<!-- 等价于 -->\n<u-switch v-model=\"checked\" loading></u-switch>\n```\n\n### 自定义颜色\n\n```html\n<u-switch v-model=\"checked\" active-color=\"red\" inactive-color=\"#eee\"></u-switch>\n```\n\n### 自定义值\n\n可以通过设置`active-value`和`inactive-value`来控制选择器打开或者关闭时，通过`change`事件发出的回调值。\n\n```html\n<u-switch v-model=\"checked\" active-value=\"1\" inactive-value=\"0\"></u-switch>\n```\n\n\n### 异步控制\n\n这种场景，一般发生在用户打开或者关闭选择器时，需要本地或者向后端请求判断，是否允许用户打开或者关闭的场景。  \n\n- 假设原来是打开状态\n\n1. 您通过`watch`监听`v-model`绑定的`checked`变量，或者通过监听`switch`的`change`事件，得知`checked`变量发生了变化\n2. 这时您可以通过设置`loading`为`true`，同时将`checked`值设置为`true`(因为用户已关闭，这里让它重新打开，并处于加载中)\n3. 等请求结束后，根据判断结果，把`checked`值设置为`true`或者`false`，同时去掉加载中状态(`loading`设置为`false`)，让组件呈现最终的状态\n\n<br>\n\n- 假设原来处于关闭状态\n\n处理方法同上，只不过对应的状态是反过来的  \n\n下面示例为原本是打开状态，用户把它关闭，我们通过异步控制的场景\n\n\n此处示例中，我们通过`watch`监听`checked`变量为`false`的情景，在定时器模拟回调中又将`checked`设置为`false`，会造成无限循环，所以这里\n引入了一个中间变量`controlStatus`来识别\n\n\n\n```html\n<template>\n\t<u-switch v-model=\"checked\" :loading=\"loading\"></u-switch>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tchecked: true,\n\t\t\t\tloading: false,\n\t\t\t\t// 中间变量，避免在watch中多次回调，造成无限循环\n\t\t\t\tcontrolStatus: false\n\t\t\t};\n\t\t},\n\t\twatch: {\n\t\t\tchecked(val) {\n\t\t\t\t// 等于false，意味着用户手动关闭了switch\n\t\t\t\tif (val == false) {\n\t\t\t\t\tif(this.controlStatus == true) {\n\t\t\t\t\t\tthis.controlStatus = false;\n\t\t\t\t\t\treturn ;\n\t\t\t\t\t}\n\t\t\t\t\t// 重新打开switch，并让它处于加载中的状态\n\t\t\t\t\tthis.checked = true;\n\t\t\t\t\tthis.loading = true;\n\t\t\t\t\t// 模拟向后端发起请求\n\t\t\t\t\tthis.getRestultFromServer();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\t// switch打开或者关闭时触发，值为true或者false\n\t\t\tchange(status) {\n\t\t\t\t// console.log(status);\n\t\t\t},\n\t\t\tgetRestultFromServer() {\n\t\t\t\t// 通过定时器模拟向后端请求\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tthis.controlStatus = true;\n\t\t\t\t\t// 后端允许用户关闭switch，设置checked为false，结束loading状态\n\t\t\t\t\tthis.loading = false;\n\t\t\t\t\tthis.checked = false;\n\t\t\t\t}, 1500);\n\t\t\t}\n\t\t}\n\t};\n</script>\n```\n\n\n\n### API\n\n### Switch Props\n\n注意：需要给`switch`组件通过`v-model`绑定一个布尔值，来初始化`switch`的状态，随后该值被双向绑定，\n当用打开选择器时，该值在`switch`组件内部被修改为`true`，并反映到父组件，否则为`false`，换言之，您无需监听`switch`的`change`事件，也能\n知道某一个`switch`是否被选中的状态\n\n| 参数           | 说明                                                                    | 类型                        | 默认值  | 可选值 |\n| -------------- | ----------------------------------------------------------------------- | --------------------------- | ------- | ------ |\n| loading        | 是否处于加载中                                                          | Boolean                     | false   | true   |\n| disabled       | 是否禁用                                                                | Boolean                     | false   | true   |\n| size           | 开关尺寸，单位rpx                                                       | String \\| Number            | 50      | -      |\n| active-color   | 打开时的背景色                                                          | String                      | #2979ff | -      |\n| inactive-color | 关闭时的背景色                                                          | String                      | #ffffff | -      |\n| vibrate-short  | 是否使手机发生短促震动，目前只在iOS的微信小程序和微信小程序开发工具有效 | Boolean                     | false   | true   |\n| active-value   | 打开选择器时通过change事件发出的值                                      | Boolean \\| Number \\| String | true    |        |\n| inactive-value | 关闭选择器时通过change事件发出的值                                      | Boolean \\| Number \\| String | false   |\n\n\n### Switch Event\n\n| 事件名 | 说明 | 回调参数 |\n| :----- | :--- | :------- ||\n| change | 在`switch`打开或关闭时触发 | value：打开时为`active-value`值，关闭时为`inactive-value`值 |\n"
  },
  {
    "path": "src/static/app/markdown/tabbar.md",
    "content": "## Tabbar 底部导航栏 <to-api/>\n\n<demo-model url=\"/pages/componentsB/tabbar/index\"></demo-model>\n\n#### 优点：\n\n此组件一般用于应用的底部导航，具有如下特点：\n\n- 可以设置凸起的按钮，且是全端通用的\n- 图标可以使用字体图标(内置图标和扩展图标)或者图片\n- 可以动态切换菜单的数量以及配置\n- 切换菜单之前，可以进行回调鉴权\n- 可以设置角标\n- 有效防止组件区域高度塌陷，无需给父元素额外的内边距或者外边距来避开导航的区域\n\n#### 缺点：\n\n虽然优点很多，但是如果用此组件模拟 tabbar 页面的话依然是瑜不掩瑕的，因为它同样带来很多难以解决的缺点：\n\n- 首先是性能问题，在 uni-app 的 vue 版本上，自定义 tabbar 让您不得不在一个 webview 内模拟出多个页面，这存在严重的性能问题\n- 相比原生的 uni-app 的 tabbar，自定义 tabbar 让你失去了路由管理的功能\n- 渲染的速度比不上原生的 tabbar，但是这影响不大\n\n\n以上的缺点，是指自定义模拟 tabbar 页面的情形，我们提供了一个解决方案，可以使用 uni-app 自带 tabbar 系统，保证性能的同时，又能尽情自定义 tabbar 导航栏，见下方`实战教程`说明。\n\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ 小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :-------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |     √     |\n\n### 基本使用\n\n在使用的时候，需要注意组件的位置，要将它放在和页面包裹所有内容的元素同级的位置，否则可能会造成组件的高度塌陷，有如下几个需要注意的点：\n\n- 通过`list`参数配置每一个 item 的参数\n- 如果需要配置凸起的按钮，这个按钮的配置需要在`list`数组的**中间位置**，同时需要配置`mid-button`参数为`true`\n- 将组件放在和页面包裹所有内容的元素同级的位置\n- 通过`v-model`绑定一个数值变量，用于指示当前激活项的索引\n\n下面解释`list`数组中元素参数的作用：\n\n```js\nlet list = [\n  {\n    // 非凸起按钮未激活的图标，可以是uView内置图标名或自定义扩展图标库的图标\n    // 或者png图标的【绝对路径】，建议尺寸为80px * 80px\n    // 如果是中间凸起的按钮，只能使用图片，且建议为120px * 120px的png图片\n    iconPath: \"home\",\n    // 激活(选中)的图标，同上\n    selectedIconPath: \"home-fill\",\n    // 显示的提示文字\n    text: \"首页\",\n    // 红色角标显示的数字，如果需要移除角标，配置此参数为0即可\n    count: 2,\n    // 如果配置此值为true，那么角标将会以红点的形式显示\n    isDot: true,\n    // 如果使用自定义扩展的图标库字体，需配置此值为true\n    // 自定义字体图标库教程：https://www.uviewui.com/guide/customIcon.html\n    customIcon: false,\n    // 如果是凸起按钮项，需配置此值为true\n    midButton: false,\n    // 点击某一个item时，跳转的路径，此路径必须是pagees.json中tabBar字段中定义的路径\n    pagePath: \"\", // 1.5.6新增，路径需要以\"/\"开头\n  },\n];\n```\n\n#### 示例代码\n\n```html\n<template>\n  <view>\n    <view class=\"u-page\">\n      <!-- 所有内容的容器 -->\n    </view>\n    <!-- 与包裹页面所有内容的元素u-page同级，且在它的下方 -->\n    <u-tabbar v-model=\"current\" :list=\"list\" :mid-button=\"true\"></u-tabbar>\n  </view>\n</template>\n\n<script>\n  export default {\n    data() {\n      return {\n        list: [\n          {\n            iconPath: \"home\",\n            selectedIconPath: \"home-fill\",\n            text: \"首页\",\n            count: 2,\n            isDot: true,\n            customIcon: false,\n          },\n          {\n            iconPath: \"photo\",\n            selectedIconPath: \"photo-fill\",\n            text: \"放映厅\",\n            customIcon: false,\n          },\n          {\n            iconPath: \"https://cdn.uviewui.com/uview/common/min_button.png\",\n            selectedIconPath: \"https://cdn.uviewui.com/uview/common/min_button_select.png\",\n            text: \"发布\",\n            midButton: true,\n            customIcon: false,\n          },\n          {\n            iconPath: \"play-right\",\n            selectedIconPath: \"play-right-fill\",\n            text: \"直播\",\n            customIcon: false,\n          },\n          {\n            iconPath: \"account\",\n            selectedIconPath: \"account-fill\",\n            text: \"我的\",\n            count: 23,\n            isDot: false,\n            customIcon: false,\n          },\n        ],\n        current: 0,\n      };\n    },\n  };\n</script>\n```\n\n### 外观配置\n\n可以通过以下参数，进行组件的整体外观配置\n\n- `height`配置导航栏高度，建议使用默认值即可，默认为`50px`，与 uni-app 自带系统导航栏高度一致\n- `bg-color`组件的背景颜色\n- `active-color`与`inactive-color`配置提示文字和图标的颜色(如果是字体图标的话)，可以搭配`bg-color`达到自定义导航栏主题的效果\n\n### 切换前的回调\n\n在点击切换之前，如果配置了`before-switch`参数并绑定的是一个方法的话，将会抛出点击项的索引，并执行此方法。\n\n此回调可以返回一个`promise`、`true`，或者`false`，下面分别阐述三者的处理情况：\n\n- `false`——如果返回`false`，将不会切换`tab`项\n- `true`——如果返回`true`，将会切换`tab`项\n- `promise`——如果返回的是一个`promise`，如果进入`then`回调，就会和返回`true`的情况一样，如果进入`catch`回调，就会和返回`false`的情况一样\n\n下面举例说明：\n\n由于篇幅问题，以下示例可不直接运行，仅作举例作用。\n\n#### 1. 普通返回\n\n```html\n<template>\n  <u-tabbar :before-switch=\"beforeSwitch\"></u-tabbar>\n</template>\n\n<script>\n  export default {\n    methods: {\n      beforeSwitch(index) {\n        // 只能切换偶数项\n        if (index % 2 == 0) return true;\n        else return false;\n      },\n    },\n  };\n</script>\n```\n\n#### 2. 请求之后再返回\n\n```html\n<template>\n  <u-tabbar :before-switch=\"beforeSwitch\"></u-tabbar>\n</template>\n\n<script>\n  export default {\n    methods: {\n      async beforeSwitch(index) {\n        // await等待一个请求，请求回来后再返回true，再进行切换\n        let data = await uni.$u.post(\"url\");\n        return true; // 或者根据逻辑返回false\n      },\n    },\n  };\n</script>\n```\n\n#### 3. 返回一个 Promise\n\n```html\n<template>\n  <u-tabbar :before-switch=\"beforeSwitch\"></u-tabbar>\n</template>\n\n<script>\n  export default {\n    methods: {\n      beforeSwitch(index) {\n        // 返回一个promise\n        return new Promise((resolve, reject) => {\n          this.$u\n            .post(\"url\")\n            .then((res) => {\n              // resolve()之后，将会进入promise的组件内部的then回调，相当于返回true\n              resolve();\n            })\n            .catch((err) => {\n              // reject()之后，将会进入promise的组件内部的catch回调，相当于返回false\n              reject();\n            });\n        });\n      },\n    },\n  };\n</script>\n```\n\n### 边框\n\n组件默认带了顶部边框，如果有配置中部凸起按钮的话，此按钮同时也会有外层边框，如果不需要，配置`border-top`为`false`即可。\n\n### 实战教程\n\n自定义 tabbar 场景，我们不建议在一个页面内通过几个组件，用`v-if`切换去模拟各个页面，而应该使用 uni-app 自带的 tabbar 系统，同时隐藏原生的 tabbar，\n再引入自定导航栏，这样可以保证原有性能，同时又能自定义 tabbar，思路如下：\n\n1. 在 pages.json 中正常定义 tabbar 逻辑和字段，只需配置`tabBar`字段`list`中的`pagePath`(需以\"/\"开头)属性即可\n2. 在各个 tabbar 页面引入`u-tabbar`组件，组件会默认自动通过`uni.hideTabBar()`隐藏系统 tabbar\n3. 通过`vuex`引用同一份 tabbar 组件的`list`参数，这样可以做到修改某一个页面的`u-tabbar`数据，其他页面的`u-tabbar`也能同步更新\n4. 组件内部会自动处理各种跳转的逻辑，同时需要注意以下两点：\n\n- 要在`list`参数中配置`pagePath`路径，此路径为`pages.json`中定义的 tabbar 字段的路径\n- 此种方式，无需通过`v-model`绑定活动项，内部会自动进行判断和跳转\n\n我们为此做了一个演示`demo`，您可以在下载页找到对应的资源，下载运行即可，[点此跳转下载页](/components/resource.html)\n\n### API\n\n### Table Props\n\n| 参数            | 说明                                                                                                  | 类型             | 默认值  | 可选值 |\n| --------------- | ----------------------------------------------------------------------------------------------------- | ---------------- | ------- | ------ |\n| list            | 各项的配置参数，见顶部说明，数组形式                                                                  | Array            | -       | -      |\n| show            | 是否显示组件                                                                                          | Boolean          | true    | false  |\n| v-model         | 双向绑定的激活项的索引值                                                                              | String \\| Number | 0       | -      |\n| bg-color        | 组件的背景颜色                                                                                        | String           | #ffffff | -      |\n| height          | 高度，单位任意，数值则为 rpx 单位，不建议修改                                                         | String \\| Number | 50px    | -      |\n| icon-size       | 非中部凸起图标的大小，单位任意，数值则为 rpx 单位                                                     | String \\| Number | 40      | -      |\n| mid-button-size | 凸起的图标的大小，单位任意，数值则为 rpx 单位                                                         | String \\| Number | 90      | -      |\n| active-color    | 文字和字体图标激活时的颜色                                                                            | String           | #303133 | -      |\n| inactive-color  | 文字和字体图标未激活时的颜色                                                                          | String           | #606266 | -      |\n| mid-button      | 是否需要中部凸起的按钮，配置了此值，依然需要配置`list`参数中需凸起项的`midButton`为`true`，见上方说明 | Boolean          | false   | true   |\n| before-switch   | 切换之前的回调钩子，见上方说明                                                                        | Function         | -       | -      |\n| border-top      | 是否显示顶部的边框                                                                                    | Boolean          | true    | false  |\n| hide-tab-bar    | 是否隐藏原生 tabbar                                                                                   | Boolean          | true    | false  |\n\n### Events\n\n| 事件名 | 说明           | 回调参数                  |\n| :----- | :------------- | :------------------------ |\n| change | 切换选项时触发 | index：当前要切换项的索引 |\n\n<style scoped>\nh3[id=table-props] + table thead tr th:nth-child(2){\n\twidth: 40%;\n}\n\nh3[id=td-props] + table thead tr th:nth-child(2){\n\twidth: 43%;\n}\n\nh3[id=th-props] + table thead tr th:nth-child(2){\n\twidth: 43%;\n}\n</style>\n"
  },
  {
    "path": "src/static/app/markdown/table.md",
    "content": "## Table 表格 <to-api/>\n\n<demo-model url=\"/pages/componentsB/table/index\"></demo-model>\n\n\n表格组件一般用于展示大量结构化数据的场景\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |    √     |\n\n### 基本使用\n\n本组件标签类似HTML的table表格，由`table`、`tr`、`th`、`td`四个组件组成\n\n- `table`组件裹在最外层，可以配置一些基础参数\n- `tr`组件用于显示\"行\"数据\n- `th`组件用于显示表头内容，类似`td`，不同之处在于字体加粗了，也带有背景颜色，也可以直接用`td`替代`th`\n- `td`组件不是最小单位，为了合并单元格时，内部可以嵌入`tr`和`td`组件\n\n```html\n<template>\n\t<u-table>\n\t\t<u-tr>\n\t\t\t<u-th>学校</u-th>\n\t\t\t<u-th>班级</u-th>\n\t\t\t<u-th>年龄</u-th>\n\t\t</u-tr>\n\t\t<u-tr>\n\t\t\t<u-td>浙江大学</u-td>\n\t\t\t<u-td>二年级</u-td>\n\t\t\t<u-td>22</u-td>\n\t\t</u-tr>\n\t\t<u-tr>\n\t\t\t<u-td>清华大学</u-td>\n\t\t\t<u-td>05班</u-td>\n\t\t\t<u-td>20</u-td>\n\t\t</u-tr>\n\t</u-table>\n</template>\n```\n\n### 兼容性\n\n由于`头条小程序`的兼容性问题，您需要给表格相关的组件(`u-tr`、`u-th`、`u-td`)写上对应的类名才有效，如下：\n\n```html\n<u-table>\n\t<u-tr class=\"u-tr\">\n\t\t<u-th class=\"u-th\">姓名</u-th>\n\t\t<u-th class=\"u-th\">年龄</u-th>\n\t\t<u-th class=\"u-th\">籍贯</u-th>\n\t\t<u-th class=\"u-th\">性别</u-th>\n\t</u-tr>\n\t<u-tr class=\"u-tr\">\n\t\t<u-td class=\"u-td\">吕布</u-td>\n\t\t<u-td class=\"u-td\">22</u-td>\n\t\t<u-td class=\"u-td\">楚河</u-td>\n\t\t<u-td class=\"u-td\">男</u-td>\n\t</u-tr>\n</u-table>\n```\n\n<!-- ### 合并单元格\n\n\n由于微信小程序编译后特殊的元素结构，目前合并单元格暂不支持微信小程序端\n\n\n\n- 可以在`td`组件嵌入多个`tr`，就会得到多行，`tr`中再嵌入`td`，就可以合并单元格，可以通过`width`参数\n设置单元格的百分比长度，默认为每个单元格平均分`tr`的长度\n\n下面的示例为合并\"行\"单元格的写法，设置`td`的`width`为33.33333%，第一行的第一个`td`宽度占据三分之一\n\n```html\n<u-table>\n\t<u-tr>\n\t\t<u-td width=\"33.33333%\">浙江大学</u-td>\n\t\t<u-td>\n\t\t\t<u-tr>\n\t\t\t\t<u-td>二年级</u-td>\n\t\t\t\t<u-td>22</u-td>\n\t\t\t</u-tr>\n\t\t\t<u-tr>\n\t\t\t\t<u-td>二年级</u-td>\n\t\t\t\t<u-td>22</u-td>\n\t\t\t</u-tr>\n\t\t</u-td>\n\t</u-tr>\n\t<u-tr>\n\t\t<u-td>清华大学</u-td>\n\t\t<u-td>05班</u-td>\n\t\t<u-td>20</u-td>\n\t</u-tr>\n</u-table>\n```\n\n<br>\n\n下面的示例为合并\"列\"单元格的写法，设置`td`的`width`为66.66666%，第一行的第一个`td`宽度占据总宽度的三分之二\n\n```html\n<u-table>\n\t<u-tr>\n\t\t<u-td width=\"66.66666%\">浙江大学</u-td>\n\t\t<u-td>\n\t\t\t二年级\n\t\t</u-td>\n\t</u-tr>\n\t<u-tr>\n\t\t<u-td>清华大学</u-td>\n\t\t<u-td>05班</u-td>\n\t\t<u-td>20</u-td>\n\t</u-tr>\n</u-table>\n``` -->\n\n### API\n\n### Table Props\n\n| 参数         | 说明                                                                                        | 类型             | 默认值  | 可选值       |\n| ------------ | ------------------------------------------------------------------------------------------- | ---------------- | ------- | ------------ |\n| border-color | 表格边框的颜色                                                                              | String           | #e4e7ed | -            |\n| bg-color     | 表格的背景颜色                                                                              | String           | #ffffff | -            |\n| align        | 单元格的内容对齐方式，作用类似css的`text-align`                                             | String           | center  | left / right |\n| padding      | 单元格的内边距，同css的`padding`写法                                                        | String           | 10rpx 0 | -            |\n| font-size    | 单元格字体大小，单位rpx                                                                     | String \\| Number | 28      | -            |\n| color        | 单元格字体颜色                                                                              | String           | #606266 | -            |\n| th-style     | `th`单元格的样式，对象形式(将`th`所需参数放在`table`组件，是为了避免每一个`th`组件要写一遍) | Object           | {}      | -            |\n\n### Td Props\n\n| 参数  | 说明                                                                                                 | 类型             | 默认值 | 可选值 |\n| ----- | ---------------------------------------------------------------------------------------------------- | ---------------- | ------ | ------ |\n| width | 单元格宽度百分比或者具体带单位的值，如30%， 200rpx等，一般使用百分比，单元格宽度默认为均分`tr`的长度 | String \\| Number | auto   | -      |\n\n### Th Props\n\n| 参数  | 说明                                                                                                     | 类型             | 默认值 | 可选值 |\n| ----- | -------------------------------------------------------------------------------------------------------- | ---------------- | ------ | ------ |\n| width | 标题单元格宽度百分比或者具体带单位的值，如30%， 200rpx等，一般使用百分比，单元格宽度默认为均分`tr`的长度 | String \\| Number | -      | -      |\n\n\n\n<style scoped>\nh3[id=table-props] + table thead tr th:nth-child(2){\n\twidth: 40%;\n}\n\nh3[id=td-props] + table thead tr th:nth-child(2){\n\twidth: 43%;\n}\n\nh3[id=th-props] + table thead tr th:nth-child(2){\n\twidth: 43%;\n}\n</style>"
  },
  {
    "path": "src/static/app/markdown/tabs.md",
    "content": "## tabs 标签 <to-api/>\n\n该组件，是一个tabs标签组件，在标签多的时候，可以配置为左右滑动，标签少的时候，可以禁止滑动。 \n该组件的一个特点是配置为滚动模式时，激活的tab会自动移动到组件的中间位置。\n<br>\n\n<demo-model url=\"/pages/componentsA/tabs/index\"></demo-model>\n\nuView中，共有2个组件可以实现tabs标签切换，分别是`tabs`组件，`tabsSwiper`组件，他们的异同点是：  \n\n- `tabs`组件可以不结合uni-app`swiper`轮播组件使用，`tabsSwiper`组件是必须要结uni-app`swiper`轮播组件才能使用的。\n- `tabs`组件使用更简洁明了(这也是其存在的理由)，`tabsSwiper`组件配置相对复杂一些。\n- `tabsSwiper`组件相比`tabs`组件，由于搭配了uni-app`swiper`轮播组件，获得了滑块跟随，标签颜色渐变等效果(请在演示中扫码查看效果)，而`tabs`组件是不具备的。\n\n总的来说，二者配置参数和功能都差不多，看用户的需求自行衡量该使用哪一个组件。\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |    √     |\n\n### 基本使用\n\n- 通过设置`is-scroll`(默认为`true`)，配置tabs组件的内容是否可以左右拖动，一般4个标签以下时，无需拖动，设置为`false`，5个标签以上，建议可以左右拖动。  \n- tabs标签的切换，需要绑定`current`值，在`change`事件回调中可以得到`index`，将其赋值给`current`即可。\n\n具体的标签，通过`list`参数配置，该参数要求为数组，元素为对象，对象要有`name`属性，见示例：\n\n\n`is-scroll`参数很重要，如果您的tabs项只有几个，且不想tabs导航栏可以被左右滑动的话，请一定要设置`is-scroll`为`false`，因为它默认为`true`。\n\n\n\n```html\n<u-tabs :list=\"list\" :is-scroll=\"false\" :current=\"current\" @change=\"change\"></u-tabs>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tlist: [{\n\t\t\t\t\tname: '待收货'\n\t\t\t\t}, {\n\t\t\t\t\tname: '待付款'\n\t\t\t\t}, {\n\t\t\t\t\tname: '待评价',\n\t\t\t\t\tcount: 5\n\t\t\t\t}],\n\t\t\t\tcurrent: 0\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\tchange(index) {\n\t\t\t\tthis.current = index;\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n\n### 控制组件读取的数组元素属性名\n\n某些情况下，数据可能是从后端获取的，`list`所需的数组中不一定会有`name`属性，比如可能为`cate_name`，如果这种情况还需一定要提供`name`属性\n会导致用户需要循环一遍，把`cate_name`改成`name`，显然不人性的，所以uView给tabsSwiper组件提供了一个`name`参数，您可以设置其值为`cate_name`，组件内部会读取数组中的`cate_name`属性，而不是默认的`name`属性。\n\n同理，在1.7.4版本中新增的`count`属性，您可以设置其值为`cate_count`，组件内部会读取数组中的`cate_count`属性，而不是默认的`count`属性。\n\n```html\n<u-tabs name=\"cate_name\" count=\"cate_count\" :list=\"list\" :is-scroll=\"false\" :current=\"current\" @change=\"change\"></u-tabs>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tlist: [{\n\t\t\t\t\tcate_name: '待收货'\n\t\t\t\t}, {\n\t\t\t\t\tcate_name: '待付款'\n\t\t\t\t}, {\n\t\t\t\t\tcate_name: '待评价',\n                    cate_count: 5\n\t\t\t\t}],\n\t\t\t\tcurrent: 0\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\tchange(index) {\n\t\t\t\tthis.current = index;\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n\n### 手动配置激活的标签\n\n可以通过`current`控制tabs当前的第几个tab处于激活状态\n\n```html\n<u-tabs ref=\"tabs\" :list=\"list\" current=\"2\"></u-tabs>\n```\n\n\n### 控制tabs组件的宽度\n\n有时候我们并不想让tabs组件占满整个屏幕的宽度，如果有此需求，可以给tabs外面嵌套一个view元素，控制这个view的宽度或者内外边距，view里面的tabs组件\n宽度也会相应的发生变化。\n\n```html\n<view style=\"width: 400rpx;\">\n\t<u-tabs ref=\"tabs\" :list=\"list\" current=\"2\"></u-tabs>\n</view>\n```\n\n\n### 控制底部滑块的样式\n\n1. 可以通过`active-color`控制颜色(同时为当前活动tab文字颜色和滑块的颜色)。\n2. `bar-width`控制滑块的长度(rpx)。\n3. `bar-height`控制滑块高度。\n\n```html\n<u-tabs ref=\"tabs\" :list=\"list\" bar-height=\"6\" bar-width=\"40\" active-color=\"#2979ff\"></u-tabs>\n```\n\n### 控制tabs组件的活动tab样式\n\n1. 通过`active-color`和`inactive-color`控制tabs的激活和非激活颜色。\n2. `font-size`为tabs文字大小。\n3. `current`为初始化tabs的激活tab索引，默认为0。`gutter`为单个tab标签的左右内边距之和，即左右各占`gutter`的一半。\n\n```html\n<u-tabs ref=\"tabs\" :list=\"list\" active-color=\"#2979ff\" inactive-color=\"#606266\" font-size=\"30\" :current=\"current\"></u-tabs>\n```\n\n\n### API\n\n### Props\n\n| 参数              | 说明                                                                            | 类型             | 默认值              | 可选值 |\n| ----------------- | ------------------------------------------------------------------------------- | ---------------- | ------------------- | ------ |\n| is-scroll         | tabs是否可以左右拖动                                                            | Boolean          | true                | false  |\n| list              | 标签数组，元素为对象，如[{name: '推荐'}]                                        | Array            | -                   | -      |\n| current           | 指定哪个tab为激活状态                                                           | String \\| Number | 0，即`list`的第一项 | -      |\n| height            | 导航栏的高度，单位rpx                                                           | String \\| Number | 80                  | -      |\n| font-size         | tab文字大小，单位rpx                                                            | String \\| Number | 30                  | -      |\n| duration          | 滑块移动一次所需的时间，单位**秒**                                              | String \\| Number | 0.5                 | -      |\n| active-color      | 滑块和激活tab文字的颜色                                                         | String           | #2979ff             | -      |\n| inactive-color    | tabs文字颜色                                                                    | String           | #303133             | -      |\n| bar-width         | 滑块宽度，单位rpx                                                               | String \\| Number | 40                  | -      |\n| bar-height        | 滑块高度，单位rpx                                                               | String \\| Number | 6                   | -      |\n| gutter            | 单个tab标签的左右内边距之和，单位rpx                                            | String \\| Number | 40                  | -      |\n| bg-color          | tabs导航栏的背景颜色                                                            | string           | #ffffff             | -      |\n| name              | 组件内部读取的`list`参数中的属性名（tab名称），见上方说明                       | string           | name                | -      |\n| bold              | 激活选项的字体是否加粗                                                          | Boolean          | true                | false  |\n| show-bar          | 是否显示底部的滑块                                                              | Boolean          | true                | false  |\n| bar-style         | 底部滑块的样式，对象形式                                                        | Object           | {}                  | -      |\n| active-item-style | 当前活动Item的样式，对象形式                                                    | Object           | {}                  | -      |\n| item-width        | 标签的宽度，单位rpx                                                             | String \\| Number | auto                | -      |\n| count             | 组件内部读取的`list`参数中的属性名（badge徽标数），用法与`name`一致，见上方说明 | string           | count               | -      |\n| offset            | 设置badge的位置偏移，格式为 [x, y]，也即设置的为`top`和`right`的值，单位rpx。   | Array            | [5, 20]             | -      |\n\n### Events\n\n| 事件名 | 说明           | 回调参数                            | 版本 |\n| :----- | :------------- | :---------------------------------- | :--- |\n| change | 点击标签时触发 | index: 点击了第几个tab，索引从0开始 | -    |\n"
  },
  {
    "path": "src/static/app/markdown/tabsSwiper.md",
    "content": "## tabsSwiper 全屏选项卡 <to-api/>\n\n<demo-model url=\"/pages/template/order/index\"></demo-model>\n\n该组件内部实现主要依托于uni-app`scroll-view`和`swiper`组件，主要特色是切换过程中，tabsSwiper文字的颜色可以渐变，底部滑块可以\n跟随式滑动，活动tab滚动居中等。应用场景可以用于需要左右切换页面，比如商城的订单中心(待收货-待付款-待评价-已退货)等应用场景。\n<br>\n<br>\nuView中，共有2个组件可以实现tabs标签切换，分别是`tabs`组件，`tabsSwiper`组件，他们的异同点是：  \n\n- `tabs`组件可以不结合uni-app`swiper`轮播组件使用，`tabsSwiper`组件是必须要结uni-app`swiper`轮播组件才能使用的。\n- `tabs`组件使用更简洁明了(这也是其存在的理由)，`tabsSwiper`组件配置相对复杂一些。\n- `tabsSwiper`组件相比`tabs`组件，由于搭配了uni-app`swiper`轮播组件，获得了滑块跟随，标签颜色渐变等效果(请在演示中扫码查看效果)，而`tabs`组件是不具备的。\n\n总的来说，二者配置参数和功能都差不多，看用户的需求自行衡量该使用哪一个组件。\n<br>\n<br>\n\n\n1. 由于支付宝小程序不支持uni的`swiper`组件`transition`事件的`dx`参数，故此组件不支持支付宝小程序\n2. 此组件目前为uView的`vue`版本，非`nvue`版本(制作中)，内部使用uni-app`swiper`组件为基础，`swiper`是单页组件，\n适合做简单列表左右滑动，因为性能问题，用swiper做复杂长列表，需要较高的优化技巧以及接受一些限制。如果要实现类似腾讯新闻APP首页可以左右\n滑动复杂的多个tab切换，不建议使用本组件，如果使用，请自行测试列表很长时的切换流畅度。后续uView会对`nvue`进行兼容，增强此组件在APP上的能力。  \n官方有一个`nvue`新闻模板示例，内有左右滑动tab功能，具体参考：  \n[插件市场新闻模板示例](https://ext.dcloud.net.cn/plugin?id=103)\n\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      x       |     √      |     √      |    √     |\n\n### 基本使用\n\n通过设置`is-scroll`(默认为`true`)，配置tabsSwiper组件的内容是否可以左右拖动，一般4个标签以下时，无需拖动，设置为`false`，5个标签以上，建议可以左右拖动。\n具体的标签，通过`list`参数配置，该参数要求为数组，元素为对象，对象要有`name`属性，见示例：\n\n\n`is-scroll`参数很重要，如果您的tabs项只有几个，且不想tabs导航栏可以被左右滑动的话，请一定要设置`is-scroll`为`false`，因为它默认为`true`。\n\n\n```html\n<u-tabs-swiper ref=\"tabs\" :list=\"list\" :is-scroll=\"false\"></u-tabs-swiper>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tlist: [{\n\t\t\t\t\tname: '待收货'\n\t\t\t\t}, {\n\t\t\t\t\tname: '待付款'\n\t\t\t\t}, {\n\t\t\t\t\tname: '待评价',\n\t\t\t\t\tcount: 5\n\t\t\t\t}],\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 控制组件读取的数组元素属性名\n\n某些情况下，数据可能是从后端获取的，`list`所需的数组中不一定会有`name`属性，比如可能为`cate_name`，如果这种情况还需一定要提供`name`属性\n会导致用户需要循环一遍，把`cate_name`改成`name`，显然不人性的，所以uView给tabsSwiper组件提供了一个`name`参数，您可以设置其值为`cate_name`，组件内部\n会读取数组中的`cate_name`属性，而不是默认的`name`属性。\n\n同理，在1.7.4版本中新增的`count`属性，您可以设置其值为`cate_count`，组件内部会读取数组中的`cate_count`属性，而不是默认的`count`属性。\n\n```html\n<u-tabs-swiper ref=\"tabs\" name=\"cate_name\" count=\"cate_count\" :list=\"list\" :is-scroll=\"false\"></u-tabs-swiper>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tlist: [{\n\t\t\t\t\tcate_name: '待收货'\n\t\t\t\t}, {\n\t\t\t\t\tcate_name: '待付款'\n\t\t\t\t}, {\n\t\t\t\t\tcate_name: '待评价',\n                    cate_count: 5\n\t\t\t\t}],\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n\n### 控制底部滑块的样式\n\n1. 可以通过`active-color`控制颜色(同时为当前活动tab文字颜色和滑块的颜色)。\n2. `bar-width`控制滑块的长度(rpx)。\n3. `bar-height`控制滑块高度。\n\n```html\n<u-tabs-swiper ref=\"tabs\" :list=\"list\" bar-height=\"6\" bar-width=\"40\" active-color=\"#2979ff\"></u-tabs-swiper>\n```\n\n### 控制tabsSwiper组件的活动tab样式\n\n1. 通过`active-color`和`inactive-color`控制tabsSwiper的激活和非激活颜色。\n2. `font-size`为tabsSwiper文字大小。\n3. `current`为初始化tabsSwiper的激活tab索引，默认为0。`gutter`为单个tab标签的左右内边距之和，即左右各占`gutter`的一半。\n\n```html\n<u-tabs-swiper ref=\"tabs\" :list=\"list\" active-color=\"#2979ff\" inactive-color=\"#606266\" font-size=\"30\" current=\"0\"></u-tabs-swiper>\n```\n\n### 使用案例\n\n该组件**必须**搭配uni-app`swiper`组件才能使用，可以实现左右滑动，同时还可以搭配uView的`loadmore`实现底部加载更多的功能，注意：\n\n- 必须要给组件设置`ref`属性，因为结合uni的`swiper`组件时需要调用tabsSwiper内部的方法，详见示例。   \n- 本示例中在`swiper-item`中嵌套了`可选`的uni-app`scroll-view`组件，uni官方不建议在APP-vue和小程序中`scroll-view`中使用map、video等原生组件，\n- 必须将组件的`current`参数，设置为`animationfinish`中的返回值。\n\n具体请参考：[uni的scroll-view组件文档](https://uniapp.dcloud.io/component/scroll-view)    \n\n注意：由于tabsSwiper组件需要结合uni的`swiper`组件使用，过程较为复杂，故此示例代码仅作参考使用，请勿直接复制粘贴使用，\n具体使用方法请下载查阅uView的tabsSwiper案例。\n\n```html\n<template>\n\t<view>\n\t\t<view>\n\t\t\t<u-tabs-swiper ref=\"uTabs\" :list=\"list\" :current=\"current\" @change=\"tabsChange\" :is-scroll=\"false\"\n\t\t\t swiperWidth=\"750\"></u-tabs-swiper>\n\t\t</view>\n\t\t<swiper :current=\"swiperCurrent\" @transition=\"transition\" @animationfinish=\"animationfinish\">\n\t\t\t<swiper-item class=\"swiper-item\" v-for=\"(item, index) in tabs\" :key=\"index\">\n\t\t\t\t<scroll-view scroll-y style=\"height: 800rpx;width: 100%;\" @scrolltolower=\"onreachBottom\">\n\t\t\t\t\t...\n\t\t\t\t</scroll-view>\n\t\t\t</swiper-item>\n\t\t</swiper>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tlist: [{\n\t\t\t\t\tname: '十年'\n\t\t\t\t}, {\n\t\t\t\t\tname: '青春'\n\t\t\t\t}, {\n\t\t\t\t\tname: '之约'\n\t\t\t\t}],\n\t\t\t\t// 因为内部的滑动机制限制，请将tabs组件和swiper组件的current用不同变量赋值\n\t\t\t\tcurrent: 0, // tabs组件的current值，表示当前活动的tab选项\n\t\t\t\tswiperCurrent: 0, // swiper组件的current值，表示当前那个swiper-item是活动的\n\t\t\t};\n\t\t},\n\t\tmethods: {\n\t\t\t// tabs通知swiper切换\n\t\t\ttabsChange(index) {\n\t\t\t\tthis.swiperCurrent = index;\n\t\t\t},\n\t\t\t// swiper-item左右移动，通知tabs的滑块跟随移动\n\t\t\ttransition(e) {\n\t\t\t\tlet dx = e.detail.dx;\n\t\t\t\tthis.$refs.uTabs.setDx(dx);\n\t\t\t},\n\t\t\t// 由于swiper的内部机制问题，快速切换swiper不会触发dx的连续变化，需要在结束时重置状态\n\t\t\t// swiper滑动结束，分别设置tabs和swiper的状态\n\t\t\tanimationfinish(e) {\n\t\t\t\tlet current = e.detail.current;\n\t\t\t\tthis.$refs.uTabs.setFinishCurrent(current);\n\t\t\t\tthis.swiperCurrent = current;\n\t\t\t\tthis.current = current;\n\t\t\t},\n\t\t\t// scroll-view到底部加载更多\n\t\t\tonreachBottom() {\n\t\t\t\t\n\t\t\t}\n\t\t}\n\t};\n</script>\n```\n\n### API\n\n### Props\n\n| 参数              | 说明                                                                            | 类型             | 默认值              | 可选值 |\n| ----------------- | ------------------------------------------------------------------------------- | ---------------- | ------------------- | ------ |\n| is-scroll         | tabs是否可以左右拖动                                                            | Boolean          | true                | false  |\n| list              | 标签数组，元素为对象，如[{name: '推荐'}]                                        | Array            | -                   | -      |\n| current           | 指定哪个tab为激活状态                                                           | String \\| Number | 0，即`list`的第一项 | -      |\n| height            | 导航栏的高度，单位rpx                                                           | String \\| Number | 80                  | -      |\n| font-size         | tab文字大小，单位rpx                                                            | String \\| Number | 30                  | -      |\n| swiper-width      | tabs组件外部swiper的宽度，默认为屏幕宽度，单位rpx                               | string \\| Number | 750                 | -      |\n| active-color      | 滑块和激活tab文字的颜色                                                         | String           | #2979ff             | -      |\n| inactive-color    | tabs文字颜色                                                                    | String           | #303133             | -      |\n| bar-width         | 滑块宽度，单位rpx                                                               | String \\| Number | 40                  | -      |\n| bar-height        | 滑块高度，单位rpx                                                               | String \\| Number | 6                   | -      |\n| gutter            | 单个tab标签的左右内边距之和，单位rpx                                            | String \\| Number | 40                  | -      |\n| bg-color          | tabs导航栏的背景颜色                                                            | string           | #ffffff             | -      |\n| name              | 组件内部读取的`list`参数中的属性名（tab名称），见上方说明                       | string           | name                | -      |\n| bold              | 激活选项的字体是否加粗                                                          | Boolean          | true                | false  |\n| show-bar          | 是否显示底部的滑块                                                              | Boolean          | true                | false  |\n| bar-style         | 底部滑块的样式，对象形式                                                        | Object           | {}                  | -      |\n| active-item-style | 当前活动Item的样式，对象形式                                                    | Object           | {}                  | -      |\n| count             | 组件内部读取的`list`参数中的属性名（badge徽标数），用法与`name`一致，见上方说明 | string           | count               | -      |\n| offset            | 设置badge的位置偏移，格式为 [x, y]，也即设置的为`top`和`right`的值，单位rpx。   | Array            | [5, 20]             | -      |\n\n### Events\n\n| 事件名 | 说明           | 回调参数                            | 版本 |\n| :----- | :------------- | :---------------------------------- | :--- |\n| change | 点击标签时触发 | index: 点击了第几个tab，索引从0开始 | -    |\n"
  },
  {
    "path": "src/static/app/markdown/tag.md",
    "content": "## Tag 标签 <to-api/>\n\n<demo-model url=\"/pages/componentsA/tag/index\"></demo-model>\n\n\n该组件一般用于标记和选择，有如下特点：\n- `mode`参数可以设置3种模式，`dark`(深色背景)、`light`(浅色背景)、`plain`(白色背景)\n- `shape`参数可以设置多种形状，`circle`（两边半圆形）, `square`（方形，带圆角），`circleLeft`（左边半圆），`circleRight`（右边半圆）\n- `type`参数可以设置5种主题，`primary`，`success`，`warning`，`error`，`info`\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n- 通过`type`参数设置主题类型，默认为`primary`\n- `text`设置标签内容\n\n```html\n<u-tag text=\"雪月夜\" type=\"success\" />\n```\n\n### 设置标签的类型\n\n- 通过设置`mode`参数，可以设置标签的类型，`dark`(深色背景)、`light`(浅色背景)、`plain`(白色背景)\n\n```html\n<u-tag text=\"一丘之貉\" mode=\"dark\" />\n<u-tag text=\"沆瀣一气\" mode=\"light\" />\n<u-tag text=\"狼狈为奸\" mode=\"plain\" />\n```\n\n### 设置标签的形状\n\n通过`shape`参数，可以设置标签的形状，默认是`square`（方形，带圆角），可选：`circle`（两边半圆形）, `circleLeft`（左边半圆），`circleRight`（右边半圆）\n\n```html\n<u-tag text=\"主谓宾\" shape=\"circle\" />\n<u-tag text=\"定状补\" shape=\"circleLeft\" />\n```\n\n### 设置标签是否可以关闭\n\n设置`closeable`参数为`true`，会在标签上自动添加一个关闭图标  \n设置可关闭后，点击关闭按钮，会发出`close`事件，回调中手动设置`show`参数为`false`，可以隐藏`Tag`\n\n```html\n<template>\n\t<u-tag text=\"要清楚\" closeable :show=\"show\" @close=\"tagClick\" />\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tshow: true\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\ttagClick(index) {\n\t\t\t\tthis.show = false;\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| type | 主题类型  | String\t | primary | success / info / warning / error |\n| size | 标签大小  | String\t | default | mini |\n| shape | 标签形状 | String | square | circle / circleLeft / circleRight |\n| text | 标签的文字内容 | String | - | - |\n| bg-color | 自定义标签的背景颜色 | String  | - | - |\n| color | 文字的颜色 | String  | - | - |\n| border-color | 标签的边框颜色  | String | - | - |\n| close-color | 关闭按钮的颜色  | String | - | - |\n| index | 点击标签时，会通过`click`事件返回该值  | String \\| Number | - | - |\n| mode | 模式选择，见上方说明 | String | light | dark / plain |\n| closeable | 是否可关闭，设置为`true`，文字右边会出现一个关闭图标  | Boolean | false | true |\n| show | 标签显示与否  | Boolean | true | false |\n\n### Event\n\n|事件名|说明|回调参数|版本|\n|:-|:-|:-|:-|\n| click | 点击标签触发 | index: 传递的`index`参数值 | - |\n| close | `closeable`为`true`时，点击标签关闭按钮触发 | index: 传递的`index`参数值 | - |\n"
  },
  {
    "path": "src/static/app/markdown/test.md",
    "content": "# test 规则校验\n\nuView内置了一些校验规则，如是否手机号，邮箱号，URL等  \n这些规则方法，挂载在`$u.test`下面，如验证是否手机号：`$u.test.mobile('13888889999')`，如果验证通过，返回`true`，否则返回`false`\n\n<demo-model url=\"/pages/library/test/index\"></demo-model>\n\n\n## 是否验证码\n\n### code(value, len = 6)\n\n校验是否验证码(要求为数字)，返回`true`或者`false`。\n\n- `value` <String\\> 验证码字符串\n- `len` <Number\\> 验证码长度，默认为6\n\n```js\nconsole.log(uni.$u.test.code('4567', 4));\n```\n\n\n\n## 是否数组\n\n### array(array)\n\n校验是否数组，返回`true`或者`false`。\n\n- `array` <Array\\> 数组\n\n```js\nconsole.log(uni.$u.test.array([1, 2, 3]));\n```\n\n## 是否Json字符串\n\n### jsonString(json)\n\n校验是否数组，返回`true`或者`false`。\n\n- `json` <Json\\> Json字符串\n\n注意：请留意json字符串的要求：\n1. 整体为一个字符串\n2. 字符串对象内的属性需要用`\"\"`双引号包含\n\n```js\nconsole.log(uni.$u.test.jsonString('{\"a\": 1}'));\n```\n\n\n## 是否对象\n\n### object(object)\n\n校验是否数组，返回`true`或者`false`。\n\n- `object` <Object\\> 对象\n\n```js\nconsole.log(uni.$u.test.object({a: 1}));\n```\n\n## 是否邮箱号\n\n### email(email)\n\n校验是否邮箱号，返回`true`或者`false`。\n\n- `email` <String\\> 字符串\n\n```js\nconsole.log(uni.$u.test.email('123465798@gmail.com'));\n```\n\n\n## 是否手机号\n\n### mobile(mobile)\n\n校验是否手机号，返回`true`或者`false`。\n\n- `mobile` <String\\> 字符串\n\n```js\nconsole.log(uni.$u.test.mobile('13845678900'));\n```\n\n\n## 是否URL\n\n### url(url)\n\n校验是否URL链接，返回`true`或者`false`。\n\n- `url` <String\\> 字符串\n\n```js\nconsole.log(uni.$u.test.url('https://uviewpro.cn'));\n```\n\n\n## 是否为空\n\n这里指的“空”，包含如下几种情况：\n- 值为`undefined`(一种类型)，非字符串`\"undefined\"`\n- 字符串长度为0，也即空字符串\n- 值为`false`(布尔类型)，非字符串`\"false\"`\n- 值为数值`0`(非字符串`\"0\"`)，或者`NaN`\n- 值为`null`，空对象`{}`，或者长度为0的数组\n\n### isEmpty(value)\n\n校验值是否为空，返回`true`或者`false`。  \n此方法等同于`empty`名称，但是为了更语义化，推荐用`isEmpty`名称。\n\n- `value` <any\\> 字符串\n\n```js\nconsole.log(uni.$u.test.isEmpty(false));\n```\n\n\n## 是否普通日期\n\n验证一个字符串是否日期，返回`true`或者`false`，如下行为正确：\n- `2020-02-10`、`2020-02-10 08:32:10`、`2020/02/10 3:10`、`2020/02/10 03:10`、`2020/02-10 3:10`\n\n如下为错误：\n- `2020年02月10日`、`2020-02-10 25:32`\n\n总的来说，年月日之间可以用\"/\"或者\"-\"分隔(不能用中文分隔)，时分秒之间用\":\"分隔，数值不能超出范围，如月份不能为13，则检验成功，否则失败。\n\n### date(date)\n\n- `date` <String\\> 日期字符串\n\n```js\nconsole.log(uni.$u.test.date('2020-02-10 08:32:10'));\n```\n\n\n## 是否十进制数值\n\n整数，小数，负数，带千分位数(2,359.08)等可以检验通过，返回`true`或者`false`。\n\n### number(number)\n\n- `number` <String\\> 数字\n\n```js\nconsole.log(uni.$u.test.number('2020'));\n```\n\n\n## 是否整数\n\n所有字符都在`0-9`之间，才校验通过，结果返回`true`或者`false`。\n\n### digits(number)\n\n- `number` <String\\> 数字\n\n```js\nconsole.log(uni.$u.test.digits('2020'));\n```\n\n\n## 是否身份证号\n\n身份证号，包括尾数为\"X\"的类型，可以校验通过，结果返回`true`或者`false`。\n\n### idCard(idCard)\n\n- `idCard` <String\\> 身份证号\n\n```js\nconsole.log(uni.$u.test.idCard('110101199003070134'));\n```\n\n\n## 是否车牌号\n\n可以校验旧车牌号和新能源类型车牌号，结果返回`true`或者`false`。\n\n### carNo(carNo)\n\n- `carNo` <String\\> 车牌号\n\n```js\nconsole.log(uni.$u.test.carNo('京A88888'));\n```\n\n\n## 是否金额\n\n最多两位小数，可以带千分位，结果返回`true`或者`false`。\n\n### amount(amount)\n\n- `amount` <String\\> 金额字符串\n\n```js\nconsole.log(uni.$u.test.amount('3,233.08'));\n```\n\n\n## 是否汉字\n\n可以为单个汉字，或者汉字组成的字符串，结果返回`true`或者`false`。\n\n### chinese(zh)\n\n- `zh` <String\\> 中文字符串\n\n```js\nconsole.log(uni.$u.test.chinese('更上一层楼'));\n```\n\n\n## 是否字母\n\n只能为\"a-z\"或者\"A-Z\"之间的字符，结果返回`true`或者`false`。\n\n### letter(en)\n\n- `en` <String\\> 字母串\n\n```js\nconsole.log(uni.$u.test.letter('uView'));\n```\n\n## 是否字母或者数字\n\n只能是字母或者数字，结果返回`true`或者`false`。\n\n### enOrNum(str)\n\n- `str` <String\\> 字母或者数字字符串\n\n```js\nconsole.log(uni.$u.test.enOrNum('uView'));\n```\n\n\n## 是否包含某个值\n\n字符串中是否包含某一个子字符串，区分大小写，结果返回`true`或者`false`。\n\n### contains(str, subStr)\n\n- `str` <String\\> 字符串\n- `subStr` <String\\> 子字符串\n\n```js\nconsole.log(uni.$u.test.contains('uView', 'View'));\n```\n\n\n## 数值是否在某个范围内\n\n如30在\"29-35\"这个范围内，不在\"25-28\"这个范围内，结果返回`true`或者`false`。\n\n### range(number, range)\n\n- `number` <Number\\> 数值\n- `range` <Array\\> 如\"[25-35]\"\n\n```js\nconsole.log(uni.$u.test.range(35, [30, 34]));\n```\n\n\n## 字符串长度是否在某个范围内\n\n如\"abc\"长度为3，范围在\"2-5\"这个区间，结果返回`true`或者`false`。\n\n### rangeLength(str, range)\n\n- `str` <String\\> 数值\n- `range` <Array\\> 如\"[25, 35]\"\n\n```js\nconsole.log(uni.$u.test.rangeLength('abc', [3, 10]));\n```"
  },
  {
    "path": "src/static/app/markdown/time.md",
    "content": "# time 时间格式\n\n<demo-model url=\"/pages/library/timeFormat/index\"></demo-model>\n\n\n## 格式化时间\n\n### timeFormat | date(timestamp, format = \"yyyy-mm-dd\")\n\n\n**注意**：date和timeFormat为同功能不同名函数，无论用哪个方法名，都是一样的。\n\n\n该函数必须传入第一个参数，第二个参数是可选的，函数返回一个格式化好的时间。\n\n- `time` <String\\> 任何合法的时间格式、`秒`或`毫秒`的时间戳\n- `format` <String\\> 时间格式，可选。默认为`yyyy-mm-dd`，年为\"yyyy\"，月为\"mm\"，日为\"dd\"，时为\"hh\"，分为\"MM\"，秒为\"ss\"，格式可以自由搭配，如：\n`yyyy:mm:dd`，`yyyy-mm-dd`，`yyyy年mm月dd日`，`yyyy年mm月dd日 hh时MM分ss秒`，`yyyy/mm/dd/`，`MM:ss`等组合\n\n```html\n<template>\n\t<view>\n\t\t<view>\n\t\t\t时间为：{{ $u.timeFormat(timestamp, 'yyyy年mm月dd日') }}\n\t\t</view>\n\t\t<view>\n\t\t\t时间为：{{ time }}\n\t\t</view>\n\t</view>\n</template>\n\n<script setup>\nimport { $u } from 'uview-pro'\nimport { ref, onMounted } from 'vue';\n\nconst time = ref(null);\nconst timestamp = ref('1581170184');\n\nonMounted(() => {\n  time.value = $u.timeFormat(timestamp.value, 'yyyy-mm-dd');\n});\n</script>\n```\n\n## 多久以前\n\n### timeFrom(time, format = String | false)\n\n该函数必须传入第一个参数，格式为任何合法的时间格式、`秒`或`毫秒`的时间戳，第二个参数是可选的，返回的值类似`刚刚`，`25分钟前`，`3小时前`，`7天前`的结果。\n如果第二个参数是时间的格式，当前和传入时间戳相差大于一个月时，返回格式化好的时间；如果第二个参数为`false`，则不会返回格式化好的时间，而是诸如\"xxx年前\"的结果。\n\n- `timestamp` <String\\> 时间戳\n- `format` <String / false\\> 时间格式，默认为`yyyy-mm-dd`，年为\"yyyy\"，月为\"mm\"，日为\"dd\"，时为\"hh\"，分为\"MM\"，秒为\"ss\"，格式可以自由搭配，如：\n`yyyy:mm:dd`，`yyyy-mm-dd`，`yyyy年mm月dd日`，`yyyy年mm月dd日 hh时MM分ss秒`，`yyyy/mm/dd/`，`MM:ss`等组合。\n如果时间戳距离此时的时间，大于一个月，则返回一个格式化好的时间，如果此参数为`false`，返回均为\"多久之前\"的结果。\n\n```html\n<template>\n\t<view>\n\t\t<view>\n\t\t\t时间为：{{ $u.timeFrom(timestamp, 'yyyy年mm月dd日') }}\n\t\t</view>\n\t\t<view>\n\t\t\t时间为：{{ time }}\n\t\t</view>\n\t</view>\n</template>\n\n<script setup>\nimport { ref, onMounted } from 'vue';\nimport { $u } from 'uview-pro';\n\nconst time = ref(null);\nconst timestamp = ref('1581170184');\n\nonMounted(() => {\n  time.value = $u.timeFrom(timestamp.value, 'yyyy年mm月dd日');\n});\n</script>\n```\n"
  },
  {
    "path": "src/static/app/markdown/timeLine.md",
    "content": "## TimeLine 时间轴 <to-api/>\n\n<demo-model url=\"/pages/componentsA/timeLine/index\"></demo-model>\n\n\n时间轴组件一般用于物流信息展示，各种跟时间相关的记录等场景。\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n- 该组件左边图标默认为显示一个点，如需自定义，请通过name为`node`的`slot`传入内容\n- 组件右边内容为了更强的自定义，需要请通过name为`content`的`slot`传入\n\n以下为基本示例，完整示例请见演示部分\n\n```html\n<template>\n\t<u-time-line>\n\t\t<u-time-line-item nodeTop=\"2\">\n\t\t\t<!-- 此处自定义了左边内容，用一个图标替代 -->\n\t\t\t<template v-slot:node>\n\t\t\t\t<view class=\"u-node\" style=\"background: #19be6b;\">\n\t\t\t\t\t<!-- 此处为uView的icon组件 -->\n\t\t\t\t\t<u-icon name=\"pushpin-fill\" color=\"#fff\" :size=\"24\"></u-icon>\n\t\t\t\t</view>\n\t\t\t</template>\n\t\t\t<template v-slot:content>\n\t\t\t\t<view>\n\t\t\t\t\t<view class=\"u-order-title\">待取件</view>\n\t\t\t\t\t<view class=\"u-order-desc\">[自提柜]您的快件已放在楼下侧门，直走前方53.6米，左拐约10步，再右拐直走，见一红灯笼停下，叩门三下，喊“芝麻开门”即可。</view>\n\t\t\t\t\t<view class=\"u-order-time\">2019-05-08 12:12</view>\n\t\t\t\t</view>\n\t\t\t</template>\n\t\t</u-time-line-item>\n\t\t<u-time-line-item>\n\t\t\t<!-- 此处没有自定义左边的内容，会默认显示一个点 -->\n\t\t\t<template v-slot:content>\n\t\t\t\t<view>\n\t\t\t\t\t<view class=\"u-order-desc\">【深圳市】日照香炉生紫烟，遥看瀑布挂前川，飞流直下三千尺，疑是银河落九天。</view>\n\t\t\t\t\t<view class=\"u-order-time\">2019-12-06 22:30</view>\n\t\t\t\t</view>\n\t\t\t</template>\n\t\t</u-time-line-item>\n\t</u-time-line>\n</template>\n\n<style lang=\"scss\" scoped>\n\t.u-node {\n\t\twidth: 44rpx;\n\t\theight: 44rpx;\n\t\tborder-radius: 100rpx;\n\t\tdisplay: flex;\n\t\tjustify-content: center;\n\t\talign-items: center;\n\t\tbackground: #d0d0d0;\n\t}\n\t\n\t.u-order-title {\n\t\tcolor: #333333;\n\t\tfont-weight: bold;\n\t\tfont-size: 32rpx;\n\t}\n\t\n\t.u-order-desc {\n\t\tcolor: rgb(150, 150, 150);\n\t\tfont-size: 28rpx;\n\t\tmargin-bottom: 6rpx;\n\t}\n\t\n\t.u-order-time {\n\t\tcolor: rgb(200, 200, 200);\n\t\tfont-size: 26rpx;\n\t}\n</style>\n```\n\n### 注意事项\n\n如果自定义了左边的图标等内容，有可能左边的图标无法和右边的内容平齐，可以调整`time-line-item`组件的`node-top`参数来达到想要的效果\n\n```html\n<u-time-line-item node-top=\"2\">\n\t<template v-slot:node>\n\t\t<u-icon name=\"pushpin-fill\" color=\"#ddd\" :size=\"24\"></u-icon>\n\t</template>\n\t<template v-slot:content>\n\t\t......\n\t</template>\n</u-time-line-item>\n```\n\n### API\n\n### TiemLimeItem Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| bg-color | 左边节点的背景颜色，一般通过slot内容自定义背景颜色即可 | String | #ffffff | - |\n| node-top | 节点左边图标绝对定位的top值，单位rpx | String \\| Number | - | - |\n\n\n\n<style scoped>\nh3[id=tiemlimeitem-props] + table thead tr th:nth-child(2){\n\twidth: 40%;\n}\n</style>"
  },
  {
    "path": "src/static/app/markdown/toast.md",
    "content": "## Toast 消息提示 <to-api/>\n\n<demo-model url=\"/pages/componentsA/toast/index\"></demo-model>\n\n\n此组件表现形式类似uni的`uni.showToast`API，但也有不同的地方，具体表现在：\n- uView Pro的`toast`有5种主题可选\n- 可以配置toast结束后，跳转相应URL\n- 目前没有加载中的状态，请用uni的`uni.showLoading`，这个需求uni已经做得很好\n\n\n：\n由于uni中无法通过js创建元素，所以需要在页面中调用`<toast />`组件，再通过`ref`开启\n\n\n### 基本使用\n\n以下为一个模拟登录成功后，弹出toast提示，并在一定时间(默认2000ms)后，自动跳转页面到个人中心页(也可以配置跳转的参数)的示例\n\n``` html\n<template>\n\t<view>\n\t\t<u-toast ref=\"uToastRef\" />\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tmethods: {\n\t\t\tshowToast() {\n\t\t\t\tthis.$refs.uToastRef.show({\n\t\t\t\t\ttitle: '登录成功',\n\t\t\t\t\ttype: 'success',\n\t\t\t\t\turl: '/pages/user/index'\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 配置toast主题\n\n一共有6种主题可选，如下：\n- default-灰黑色，最普通的场景，此为默认主题，可以不用填`type`参数\n- error-红色，代表错误\n- success-绿色，代表成功\n- warning-黄色，代表警告\n- info-灰色，比default浅一点\n- primary-蓝色，uView的主色调\n\n除了`default`状态，其他5种主题，都是默认带有一个左边的图标，可以通过配置`icon`参数为`none`来取消\n\n``` js\nthis.$refs.uToastRef.show({\n\ttitle: '操作成功',\n\t// 如果不传此type参数，默认为default，也可以手动写上 type: 'default'\n\t// type: 'success', \n\t// 如果不需要图标，请设置为false\n\t// icon: false\n})\n```\n\n### toast结束跳转URL\n\n- 如果配置了`url`参数，在toast结束的时候，就会用`uni.navigateTo`(默认)或者`uni.switchTab`(需另外设置`isTab`为`true`)\n- 如果配置了`params`参数，就会在跳转时自动在URL后面拼接上这些参数，具体用法如下：\n\n``` js\nthis.$refs.uToastRef.show({\n\ttitle: '操作成功',\n\turl: '/pages/user/index',\n\tparams: {\n\t\tid: 1,\n\t\tmenu: 3\n\t}\n})\n```\n\n### API\n\n### Props\n\n| 参数    | 说明                     | 类型             | 默认值 | 可选值 |\n| ------- | ------------------------ | ---------------- | ------ | ------ |\n| z-index | toast展示时的`z-index`值 | String \\| Number | 10090  | -      |\n\n### Params\n\n这些参数为通过`ref`调用`<toast/>`组件内部的`show`方法时，需要传递参数\n\n| 参数     | 说明                                                 | 类型     | 默认值  | 可选值                                     |\n| -------- | ---------------------------------------------------- | -------- | ------- | ------------------------------------------ |\n| title    | 显示的文本                                           | String   | -       | -                                          |\n| type     | 主题类型，不填默认为`default`                        | String   | default | primary / success / error / warning / info |\n| duration | toast的持续时间，单位ms                              | Nubmer   | 2000    | -                                          |\n| url      | toast结束跳转的url，不填不跳转，优先级高于`back`参数 | String   | -       | -                                          |\n| icon     | 是否显示显示`type`对应的图标，为`false`不显示图标    | Boolean  | true    | false                                      |\n| position | toast出现的位置                                      | String   | center  | top / bottom                               |\n| callback | toast结束后执行的回调方法                            | Function | -       | -                                          |\n| isTab    | toast结束后，跳转tab页面时需要配置为`true`           | Boolean  | false   | true                                       |\n| back     | toast结束后，是否返回上一页，优先级低于`url`参数     | Boolean  | false   | true                                       |\n\n### Methods\n\n方法是通过`ref`调用的，参见上方说明\n注意：所有有关`ref`的调用，都不能在页面的`onLoad`生命周期调用，因为此时组件尚未创建完毕，会报错，应该在`onReady`生命周期调用。\n\n| 方法名 | 说明                                                            | 参数       | 版本 |\n| :----- | :-------------------------------------------------------------- | :--------- | :--- |\n| show   | 显示toast，如需一进入页面就显示toast，请在`onReady`生命周期调用 | 见上方说明 | -    |\n"
  },
  {
    "path": "src/static/app/markdown/topTips.md",
    "content": "## TopTips 顶部提示 <to-api/>\n\n<demo-model url=\"/pages/componentsA/topTips/index\"></demo-model>\n\n\n该组件一般用于页面顶部向下滑出一个提示，尔后自动收起的场景。\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |    √     |\n\n### 基本使用\n\n该组件通过`ref`调用，使用简单，只需`title`参数设置显示的内容即可  \n\n注意：不要在onLoad中调用，应在onReady生命周期调用，因为onLoad生命周期组件尚未创建完成\n\n```html\n<template>\n\t<u-top-tips ref=\"uTips\"></u-top-tips>\n</template>\n\n<script>\n\texport default {\n\t\tonReady() {\n\t\t\tthis.$refs.uTips.show({\n\t\t\t\ttitle: '铁马冰河入梦来',\n\t\t\t\ttype: 'success',\n\t\t\t\tduration: '2300'\n\t\t\t})\n\t\t}\n\t}\n</script>\n```\n\n### 自定义导航栏使用本组件的问题\n\n**注意：** 只有使用了自定义导航栏才需要注意如下事项，否则无需在意，不用处理。\n\n由于本组件是预先将组件隐藏于导航栏底部，调用时显示，内部已兼容处理H5，APP，小程序等的系统导航栏高度问题。  \n但是如果您是使用了自定义导航栏的话，组件内部不知道您的自定义导航栏高度是多少，可能会显示有误，所以您需要传入一个`navbar-height`参数(**单位为px**)。  \n需要注意的是，这个`navbar-height`参数是您自定义导航栏的整个高度，比如在APP和各家小程序上，是“导航栏”+“状态栏”的高度，H5中，“状态栏”无法自定义，高度为0。\n\n\nuView 有推出[Navbar 自定义导航栏](/components/navbar.html)组件，此组件有一个`height`参数(**单位px**，默认44)，这个高度是不包含状态栏的高度的，\n所以您使用uView的自定义导航栏组件的话，您还需要通过\"uni.getSystemInfoSync().statusBarHeight\"(字节跳动小程序不支持)去获得状态栏的高度，\n加上你需要的导航栏高度(也即uView的`navbar`组件的`height`)，即为需要传入`u-top-tips`组件的`navbar-height`参数值。\n\n\n使用uView自定导航栏可进行如下处理，如果是其他的UI框架的导航栏或者自己做的导航栏组件，请以此类推，也能不需要下面的处理。\n\n```html\n<template>\n\t<view class=\"wrap\">\n\t\t<u-navbar title=\"文章列表\"></u-navbar>\n\t\t<u-top-tips ref=\"uTips\" :navbar-height=\"statusBarHeight + navbarHeight\"></u-top-tips>\n\t\t<u-button @click=\"showTips\">弹出Tips</u-button>\n\t</view>\n</template>\n\n<script>\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\t// 状态栏高度，H5中，此值为0，因为H5不可操作状态栏\n\t\t\tstatusBarHeight: uni.getSystemInfoSync().statusBarHeight,\n\t\t\t// 导航栏内容区域高度，不包括状态栏高度在内\n\t\t\tnavbarHeight: 44\n\t\t};\n\t},\n\tmethods: {\n\t\tshowTips() {\n\t\t\tthis.$refs.uTips.show({\n\t\t\t\ttitle: '雨打梨花深闭门，忘了青春，误了青春'\n\t\t\t});\n\t\t}\n\t}\n};\n</script>\n\n<style lang=\"scss\" scoped>\n\t.wrap {\n\t\tpadding: 40rpx;\n\t}\n</style>\n```\n\n### 主题设置\n\n可以通过配置`type`参数设置显示的背景颜色：\n\n- `type`值可选的有`primary`(默认)、`success`、`info`、`warning`、`error`\n\n\n### 显示时间设置\n\n- `duration`值设置显示的时间，单位ms：\n\n\n### API\n\n### Methods\n\n需要注意的是，这里的参数是通过`ref`调用的，调用方法如上方\"基本使用\"中所示\n\n| 参数     | 说明               | 类型             | 默认值  | 可选值                           |\n| -------- | ------------------ | ---------------- | ------- | -------------------------------- |\n| title    | 要显示的内容       | String           | -       | -                                |\n| type     | 主题选择           | String           | primary | success / info / warning / error |\n| duration | 显示的时间，单位ms | String \\| Number | -       |\n\n\n### Props\n\n需要注意到是，这里的参数是需要通过`props`调用的，只有**使用了自定义导航栏**才需要配置，见上方说明。\n\n| 参数          | 说明                                                                   | 类型             | 默认值 | 可选值 |\n| ------------- | ---------------------------------------------------------------------- | ---------------- | ------ | ------ |\n| navbar-height | 导航栏高度(包含状态栏高度在内)，单位<span style=\"color: red\">PX</span> | String \\| Number | -      | -      |\n| z-index       | `z-index`值                                                            | String \\| Number | 975    | -      |\n\n"
  },
  {
    "path": "src/static/app/markdown/trim.md",
    "content": "# trim 去除空格\n\n\n<demo-model url=\"/pages/library/trim/index\"></demo-model>\n\n\n### trim(str, pos)\n\n该方法可以去除空格，分别可以去除所有空格，两端空格，左边空格，右边空格，默认为去除两端空格\n\n- `str` <String\\> 字符串\n- `pos` <String\\> 去除那些位置的空格，可选为：`both`-默认值，去除两端空格，`left`-去除左边空格，`right`-去除右边空格，`all`-去除包括中间和两端的所有空格\n\n```js\nconsole.log(uni.$u.trim('abc    b ', 'all')); // 去除所有空格\nconsole.log(uni.$u.trim(' abc '));\t// 去除两端空格\n```"
  },
  {
    "path": "src/static/app/markdown/uniModulesSetting.md",
    "content": "## uni_modules 安装方式配置\n\nuView Pro 提供了多种安装方式，本文将介绍如何使用 uni_modules 方式进行配置。\n\n### 准备工作\n\n在进行配置之前，请确保您已经根据[安装](/components/install.html)中的步骤对 uView Pro 进行了下载安装，如果没有，请先下载安装。\n\n### 配置步骤\n\n#### 1. 引入 uView 主库\n\n在项目根目录中的`main.ts`中，引入并使用 uView Pro 的工具库，注意这两行要放在`import Vue`之后。\n\n```js\n// main.ts\nimport { createSSRApp } from \"vue\";\nimport uViewPro from \"@/uni_modules/uview-pro\";\n\nexport function createApp() {\n  const app = createSSRApp(App);\n  app.use(uViewPro);\n  // 其他配置\n  return {\n    app,\n  };\n}\n```\n\n#### 2. 在引入 uView Pro 的全局 SCSS 主题文件\n\n在项目根目录的`uni.scss`中引入此文件。\n\n```css\n/* uni.scss */\n@import \"@/uni_modules/uview-pro/theme.scss\";\n```\n\n#### 3. 引入 uView Pro 基础样式\n\n\n在`App.vue`中**首行**的位置引入，注意给 style 标签加入 lang=\"scss\"属性\n\n\n```css\n<style lang=\"scss\">\n\t/* 注意要写在第一行，同时给style标签加入lang=\"scss\"属性 */\n\t@import \"@/uni_modules/uview-pro/index.scss\";\n</style>\n```\n\n#### 4. 配置 easycom 组件模式\n\n此配置需要在项目根目录的`pages.json`中进行。\n\n\n\n1. uni-app 为了调试性能的原因，修改`easycom`规则不会实时生效，配置完后，您需要重启 HX 或者重新编译项目才能正常使用 uView 的功能。\n2. 请确保您的`pages.json`中只有一个`easycom`字段，否则请自行合并多个引入规则。\n3. 注意一定要放在`custom`里，否则无效，https://ask.dcloud.net.cn/question/131175\n\n\n\n```json\n// pages.json\n{\n  \"easycom\": {\n    // 注意一定要放在custom里，否则无效，https://ask.dcloud.net.cn/question/131175\n    \"custom\": {\n      \"^u-(.*)\": \"@/uni_modules/uview-pro/components/u-$1/u-$1.vue\"\n    }\n  },\n  // 此为本身已有的内容\n  \"pages\": [\n    // ......\n  ]\n}\n```\n"
  },
  {
    "path": "src/static/app/markdown/upload.md",
    "content": "## Upload 上传 <to-api/>\n\n<demo-model url=\"/pages/componentsB/upload/index\"></demo-model>\n\n\n该组件用于上传图片场景\n\n### 平台差异说明\n\n|App|H5|微信小程序|支付宝小程序|百度小程序|头条小程序|QQ小程序|\n|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n|√|√|√|√|√|√|√|\n\n### 基本使用\n\n- 可以通过设置`file-list`参数(数组，元素为对象)，显示预置的图片。其中元素的`url`属性为图片路径\n- 设置`action`参数为后端服务器地址，注意H5在浏览器可能会有跨域限制，让后端允许域即可\n\n```html\n<template>\n\t<u-upload :action=\"action\" :file-list=\"fileList\" ></u-upload>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\t// 演示地址，请勿直接使用\n\t\t\t\taction: 'http://www.example.com/upload',\n\t\t\t\tfileList: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'http://pics.sc.chinaz.com/files/pic/pic9/201912/hpic1886.jpg',\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 手动上传\n\n组件默认为自动上传，可以设置`auto-upload`为`false`，然后通过`ref`调用组件的`upload`方法，手动上传图片\n\n```html\n<template>\n\t<view>\n\t\t<u-upload ref=\"uUpload\" :action=\"action\" :auto-upload=\"false\" ></u-upload>\n\t\t<u-button @click=\"submit\">提交</u-button>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\t// 非真实地址\n\t\t\t\taction: 'http://www.example.com/upload',\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\tsubmit() {\n\t\t\t\tthis.$refs.uUpload.upload();\n\t\t\t},\n\t\t}\n\t}\n</script>\n```\n\n### 获取上传的图片列表\n\n图片选择或者上传成功后，会保存在组件内部的`lists`数组中，数组元素为对象，有如下属性：\n- url: 图片地址\n- error：组件内部使用，不应根据此值判断上传是否成功，而应根据`progress`属性\n- progress：如果值为100，表示图片上传成功\n- response：上传成功后，服务器返回的数据，这是最有用的了\n\n为了获得上传的文件列表，可以在提交表单时，通过`ref`获取组件内部的`lists`文件数组，历遍元素筛选出`progress`为100的文件\n\n```html\n<template>\n\t<view>\n\t\t<u-upload ref=\"uUpload\" :action=\"action\" :auto-upload=\"true\" ></u-upload>\n\t\t<u-button @click=\"submit\">提交</u-button>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\taction: 'http://www.example.com/upload',\n\t\t\t\tfilesArr: []\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\tsubmit() {\n\t\t\t\tlet files = [];\n\t\t\t\t// 通过filter，筛选出上传进度为100的文件(因为某些上传失败的文件，进度值不为100，这个是可选的操作)\n\t\t\t\tfiles = this.$refs.uUpload.lists.filter(val => {\n\t\t\t\t\treturn val.progress == 100;\n\t\t\t\t})\n\t\t\t\t// 如果您不需要进行太多的处理，直接如下即可\n\t\t\t\t// files = this.$refs.uUpload.lists;\n\t\t\t\tconsole.log(files)\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 报错提示\n\n在以下几种情况，组件会默认通过toast提示用户信息，可以把`show-tips`设置为`false`取消默认的提示，这时可以通过API\n中的各种事件，进行自定义的个性化提示\n- 超出允许的最大上传数量\n- 图片大小超出最大允许大小\n- 上传图片出错\n- 移除图片\n\n以下示例为屏蔽组件内部的提示，在移除图片时，监听`onRemove`事件，手动提示的情况\n\n```html\n<template>\n\t<u-upload ref=\"uUpload\" :action=\"action\" :show-tips=\"false\" @on-remove=\"onRemove\"></u-upload>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\taction: 'http://www.example.com/upload',\n\t\t\t}\n\t\t},\n\t\tmethods: {\n\t\t\tonRemove(index, lists) {\n\t\t\t\tconsole.log('图片已被移除')\n\t\t\t},\n\t\t}\n\t}\n</script>\n```\n\n### 限制图片数量和大小\n\n- 通过`max-count`可以设置最多可以选择的图片的数量\n- 通过`max-size`设置单张图片最大的大小，单位为B(byte)，默认不限制\n\n下方示例为单张最大为5M，最多选择6张的情况：\n\n```html\n<u-upload :max-size=\"5 * 1024 * 1024\" max-count=\"6\"></u-upload>\n```\n\n\n### 上传前的钩子\n\n某些时候，**每个文件**上传前可能需要动态修改文件名，修改额外参数等，就会需要用到一个叫`before-upload`的钩子(参数注意不要加括号)，也即回调方法，此方法会返回两个参数：\n\n- `index`——即当前上传文件在上传列表中的索引\n- `lists`——当前所有的文件列表\n\n此回调可以返回一个`promise`、`true`，或者`false`，下面分别阐述三者的处理情况：\n\n- `false`——如果返回`false`，将会跳过当前文件，继续上传下一张图片(如果有)，并且再次执行`before-upload`钩子\n- `true`——如果返回`true`，会随即上传当前文件，上传成功后，继续上传下一张图片(如果有)，并且再次执行`before-upload`钩子\n- `promise`——如果返回的是一个`promise`，如果进入`then`回调，就会和返回`true`的情况一样，如果进入`catch`回调，就会和返回`false`的情况一样\n\n下面举例说明：\n\n#### 1. 普通返回\n\n```html\n<template>\n\t<u-upload :before-upload=\"beforeUpload\"></u-upload>\n</template>\n\n<script>\n\texport default {\n\t\tmethods: {\n\t\t\tbeforeUpload(index, list) {\n\t\t\t\t// 只上传偶数索引的文件\n\t\t\t\tif(index % 2 == 0) return true;\n\t\t\t\telse return false;\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n#### 2. 请求之后再返回\n\n```html\n<template>\n\t<u-upload :before-upload=\"beforeUpload\"></u-upload>\n</template>\n\n<script>\n\texport default {\n\t\tmethods: {\n\t\t\tasync beforeUpload(index, list) {\n\t\t\t\t// await等待一个请求，请求回来后再返回true，继续上传文件\n\t\t\t\tlet data = await uni.$u.post('url');\n\t\t\t\treturn true; // 或者根据逻辑返回false\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n#### 3. 返回一个Promise\n\n```html\n<template>\n\t<u-upload :before-upload=\"beforeUpload\"></u-upload>\n</template>\n\n<script>\n\texport default {\n\t\tmethods: {\n\t\t\tbeforeUpload(index, list) {\n\t\t\t\t// 返回一个promise\n\t\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\t\tuni.$u.post('url').then(res => {\n\t\t\t\t\t\t// resolve()之后，将会进入promise的组件内部的then回调，相当于返回true\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t}).catch(err => {\n\t\t\t\t\t\t// reject()之后，将会进入promise的组件内部的catch回调，相当于返回false\n\t\t\t\t\t\treject();\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n</script>\n```\n\n### 移除前的钩子\n\n某些时候，文件被移除前可能需要进行判断是否可以被移除，就会需要用到一个叫`before-remove`的钩子(参数注意不要加括号)，也即回调方法，此方法会返回两个参数：\n\n- `index`——即当前上传文件在上传列表中的索引\n- `lists`——当前所有的文件列表\n\n此回调可以返回一个`promise`、`true`，或者`false`，下面分别阐述三者的处理情况：\n\n- `false`——如果返回`false`，终止移除操作\n- `true`——如果返回`true`，执行移除操作\n- `promise`——如果返回的是一个`promise`，如果进入`then`回调，就会和返回`true`的情况一样，如果进入`catch`回调，就会和返回`false`的情况一样\n\n此处不举例说明，参考`before-upload`的示例即可。\n\n\n### 自定义相关说明\n\n1. 组件内部样式  \n组件默认选取图片会展示预览缩略图，包括默认的选取图片的按钮，他们的宽高都是`200rpx`，`border-radius`值为`10rpx`，\n另外预览图片的盒子有一个默认的边框，值为`border: 1px solid rgb(235, 236, 238)`。如果用户需要自定义上传按钮，可以参考这些值。\n\n2. 自定义上传按钮  \n通过传递名为`addBtn`的`slot`，同时配置`custom-btn`为`true`，可以自定义想要的上传按钮。\n\n如下所示：\n\n```html\n<u-upload :custom-btn=\"true\">\n\t<template #addBtn>\n\t\t<view class=\"slot-btn\" hover-class=\"slot-btn__hover\" hover-stay-time=\"150\">\n\t\t\t<u-icon name=\"photo\" size=\"60\" color=\"#2979ff\"></u-icon>\n\t\t</view>\n\t</template>\n</u-upload>\n\n<style>\n.slot-btn {\n\twidth: 329rpx;\n\theight: 140rpx;\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\tbackground: rgb(244, 245, 246);\n\tborder-radius: 10rpx;\n}\n\n.slot-btn__hover {\n\tbackground-color: rgb(235, 236, 238);\n}\n</style>\n```\n\n3. 自定义预览列表\n首先需要设置`show-upload-list`为`false`来去除组件内部的默认预览列表，其次需要通过`ref`获取组件，进而\n操作组件内部的变量和方法，下面为一些组件内部的方法和变量说明：\n- `lists`(变量)，可以通过此值，构建自定义的预览列表，该变量内部如下：\n\n```js\nlists = [\n\t{\n\t\turl: 'xxx.png', // 预览图片的地址\n\t\terror: false, // 上传失败，此值为true\n\t\tprogress: 100, // 0-100之间的值\n\t},\n\t......\n]\n```\n\n- `deleteItem(index)`(方法)，可以用此方法在自定义列表中通过`ref`删除某一张图片\n\n以下为完整的自定义图片预览列表示例：\n\n```html\n<template>\n\t<view class=\"wrap\">\n\t\t<view class=\"pre-box\" v-if=\"!showUploadList\">\n\t\t\t<view class=\"pre-item\" v-for=\"(item, index) in lists\" :key=\"index\">\n\t\t\t\t<image class=\"pre-item-image\" :src=\"item.url\" mode=\"aspectFill\"></image>\n\t\t\t</view>\n\t\t</view>\n\t\t<u-upload :custom-btn=\"true\" ref=\"uUpload\" :show-upload-list=\"showUploadList\" :action=\"action\">\n\t\t\t<template #addBtn>\n\t\t\t\t<view class=\"slot-btn\" hover-class=\"slot-btn__hover\" hover-stay-time=\"150\">\n\t\t\t\t\t<u-icon name=\"photo\" size=\"60\" color=\"#c0c4cc\"></u-icon>\n\t\t\t\t</view>\n\t\t\t</template>\n\t\t</u-upload>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\taction: 'http://www.example.com', // 演示地址\n\t\t\t\tshowUploadList: false, \n\t\t\t\t// 如果将某个ref的组件实例赋值给data中的变量，在小程序中会因为循环引用而报错\n\t\t\t\t// 这里直接获取内部的lists变量即可\n\t\t\t\tlists: []\n\t\t\t}\n\t\t},\n\t\t// 只有onReady生命周期才能调用refs操作组件\n\t\tonReady() {\n\t\t\t// 得到整个组件对象，内部图片列表变量为\"lists\"\n\t\t\tthis.lists = this.$refs.uUpload.lists;\n\t\t}\n\t}\n</script>\n\n<style lang=\"scss\">\n\t.wrap {\n\t\tpadding: 24rpx;\n\t}\n\t\n\t.slot-btn {\n\t\twidth: 341rpx;\n\t\theight: 140rpx;\n\t\tdisplay: flex;\n\t\tjustify-content: center;\n\t\talign-items: center;\n\t\tbackground: rgb(244, 245, 246);\n\t\tborder-radius: 10rpx;\n\t}\n\n\t.slot-btn__hover {\n\t\tbackground-color: rgb(235, 236, 238);\n\t}\n\n\t.pre-box {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: space-between;\n\t\tflex-wrap: wrap;\n\t}\n\n\t.pre-item {\n\t\tflex: 0 0 48.5%;\n\t\tborder-radius: 10rpx;\n\t\theight: 140rpx;\n\t\toverflow: hidden;\n\t\tposition: relative;\n\t\tmargin-bottom: 20rpx;\n\t}\n\n\t.pre-item-image {\n\t\twidth: 100%;\n\t\theight: 140rpx;\n\t}\n</style>\n```\n\n\n### API\n\n### Props\n\n| 参数          | 说明            | 类型            | 默认值             |  可选值   |\n|-------------  |---------------- |---------------|------------------ |-------- |\n| action | 服务器上传地址  | String | - | - |\n| max-count | 最大选择图片的数量 | String \\| Number | 99 | - |\n| width | 图片预览区域和添加图片按钮的宽度，单位rpx，不能是百分比，或者`auto` | String \\| Number | 200 | - |\n| height | 图片预览区域和添加图片按钮的高度，单位rpx，不能是百分比，或者`auto` | String \\| Number | 200 | - |\n| custom-btn | 如果需要自定义选择图片的按钮，设置为`true` | Boolean | false | true |\n| show-progress | 是否显示进度条 | Boolean  | true | false |\n| disabled | 是否启用(显示/隐藏)组件 | Boolean  | false | true |\n| image-mode | 预览图片等显示模式，可选值为uni的image的`mode`属性值 | String  | aspectFill | - |\n| header | 上传携带的头信息，对象形式 | Object | {} | - |\n| form-data | 上传额外携带的参数 | Object | {} | - |\n| name | 上传文件的字段名，供后端获取使用 | String  | file | - |\n| size-type | original 原图，compressed 压缩图，默认二者都有，H5无效 | Array\\<String\\>  | ['original', 'compressed'] | - |\n| source-type | 选择图片的来源，album-从相册选图，camera-使用相机，默认二者都有 | Array\\<String\\>  | ['album', 'camera'] | - |\n| preview-full-image | 是否可以通过`uni.previewImage`预览已选择的图片 | Boolean  | true | false |\n| multiple | 是否开启图片多选，部分安卓机型不支持  | Boolean  | true | false |\n| deletable | 是否显示删除图片的按钮 | Boolean  | true | false |\n| max-size | 选择单个文件的最大大小，单位B(byte)，默认不限制 | String \\| Number  | Number.MAX_VALUE | - |\n| file-list | 默认显示的图片列表，数组元素为对象，必须提供`url`属性 | Array\\<Object\\>  | - | - |\n| upload-text | 选择图片按钮的提示文字 | String  | 选择图片 | - |\n| auto-upload | 选择完图片是否自动上传，见上方说明 | Boolean  | true | false |\n| show-tips | 特殊情况下是否自动提示toast，见上方说明 | Boolean  | true | false |\n| show-upload-list | 是否显示组件内部的图片预览 | Boolean  | true | false |\n| del-icon | 右上角删除图标名称，只能为uView内置图标 | String  | close | - |\n| del-bg-color | 右上角关闭按钮的背景颜色 | String  | #fa3534 | - |\n| del-color | 右上角关闭按钮图标的颜色 | String  | #ffffff | - |\n| to-json | 如果上传后服务端返回的值为`json`字符串的话，是否自动转为`json` | Boolean | true  | false |\n| before-upload | 每个文件上传前触发的钩子回调函数，见上方说明，注意不要加括号 | Function | - | - |\n| limitType | 允许的图片后缀 | Array | ['png', 'jpg', 'jpeg', 'webp', 'gif'] | - |\n| index  | 在各个回调事件中的最后一个参数返回，用于区别是哪一个组件的事件 | String \\| Number  | - | - |\n\n\n### Methods\n\n此方法如要通过ref手动调用\n\n| 名称          | 说明            |\n|-------------  |---------------- |\n| upload | 调用此方法，手动上传图片  |\n| clear | 调用此方法，清空内部文件列表  |\n| reUpload | 调用此方法，重新上传内部上传失败或者尚未上传的图片  |\n| remove(index) | 手动移除列表的某一个图片，`index`为`lists`数组的索引  |\n\n\n### Slot\n\n|名称|说明|\n|:-|:-|\n| addBtn | 自定义的选择图片按钮 |\n\n\n\n### Events\n\n回调参数中的`lists`参数，为目前组件内的所有图片数组，`index`为当前操作的图片的索引，`name`为通过`props`传递的`index`参数(1.6.1加入)\n\n|事件名|说明|回调参数|\n|:-|:-|:-|:-|\n| on-oversize | 图片大小超出最大允许大小 | (file, lists, name), name为通过`props`传递的`index`参数 |\n| on-preview | 全屏预览图片时触发 | (url, lists, name)，url为当前选中的图片地址，index为通过`props`传递的`index`参数 |\n| on-remove | 移除图片时触发 | (index, lists, name)，name为通过`props`传递的`index`参数 |\n| on-success | 图片上传成功时触发 | (data, index, lists, name)，data为服务器返回的数据，name为通过`props`传递的`index`参数 |\n| on-change | 图片上传后，无论成功或者失败都会触发 | (res, index, lists, name)，res为服务器返回的信息，name为通过`props`传递的`index`参数 |\n| on-error | 图片上传失败时触发 | (res, index, lists, name)，res为服务器返回的信息，name为通过`props`传递的`index`参数 |\n| on-progress | 图片上传过程中的进度变化过程触发 | (res, index, lists, name)，res为服务器返回的信息，具体参数请打印查看，name为通过`props`传递的`index`参数 |\n| on-uploaded | 所有图片上传完毕触发 | (lists, name)，可以通过此事件，将lists参数获取，提交给后端使用，name为通过`props`传递的`index`参数 |\n| on-choose-complete | 每次选择图片后触发，只是让外部可以得知每次选择后，内部的文件列表 | (lists, name)，内部当前的文件列表，name为通过`props`传递的`index`参数 |\n| on-list-change | 当内部文件列表被加入文件、移除文件，或手动调用`clear`方法时触发 | (lists, name)，内部文件变化之后的列表，name为通过`props`传递的`index`参数 |\n| on-choose-fail | 选择文件出错时触发，比如选择文件时取消了操作，只在微信和APP有效 | (error)，错误信息 |\n\n\n<style scoped>\nh3[id=props] + table thead tr th:nth-child(2){\n\twidth: 40%;\n}\n\nh3[id=events] + p + table thead tr th:nth-child(3){\n\twidth: 45%;\n}\n\nh3[id=methods] + p + table thead tr th:nth-child(2){\n\twidth: 50%;\n}\n</style>"
  },
  {
    "path": "src/static/app/markdown/verificationCode.md",
    "content": "## VerificationCode 验证码倒计时 <to-api/>\n\n<demo-model url=\"/pages/componentsA/verificationCode/index\"></demo-model>\n\n\n考虑到用户实际发送验证码的场景，可能是一个按钮，也可能是一段文字，提示语各有不同，所以本组件\n不提供界面显示，只提供提示语，由用户将提示语嵌入到具体的场景\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |    √     |\n\n### 基本使用\n\n通过ref获取组件对象，再执行后面的操作，见下方示例。\n\n1. 通过`seconds`设置需要倒计的秒数(默认`60`)\n2. 通过ref调用组件内部的`start`方法，开始倒计时\n3. 通过监听`change`事件(从开始到结束之间，每秒触发一次)获得提示的文字，可能值如\"获取验证码|12秒后重新获取|重新获取\"，可以自定义\n\n注意：用户可能在倒计时的过程中点击获取验证码的按钮，组件内部提供了通过ref获取的`canGetCode`变量，在倒计时\n过程中，该值为`false`，如果为`false`应该给予提示并不要再次向后端请求验证码，如果为`true`，则为获取验证码\n之前，或者倒计结束之后，可以再次向后端请求验证码。\n\n以下为完整示例，见如下： \n\n```html\n<template>\n\t<view class=\"wrap\">\n\t\t<u-verification-code :seconds=\"seconds\" @end=\"end\" @start=\"start\" ref=\"uCode\" \n\t\t@change=\"codeChange\"></u-verification-code>\n\t\t<u-button @tap=\"getCode\">{{tips}}</u-button>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\ttips: '',\n\t\t\t\t// refCode: null,\n\t\t\t\tseconds: 10,\n\t\t\t}\n\t\t},\n\t\tonReady() {\n\t\t\t// 注意这里不能将一个组件赋值给data的一个变量，否则在微信小程序会\n\t\t\t// 造成循环引用而报错，如果你想这样做，请在非data中定义refCode变量\n\t\t\t// this.refCode = this.$refs.uCode;\n\t\t},\n\t\tmethods: {\n\t\t\tcodeChange(text) {\n\t\t\t\tthis.tips = text;\n\t\t\t},\n\t\t\tgetCode() {\n\t\t\t\tif(this.$refs.uCode.canGetCode) {\n\t\t\t\t\t// 模拟向后端请求验证码\n\t\t\t\t\tuni.showLoading({\n\t\t\t\t\t\ttitle: '正在获取验证码'\n\t\t\t\t\t})\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tuni.hideLoading();\n\t\t\t\t\t\t// 这里此提示会被this.start()方法中的提示覆盖\n\t\t\t\t\t\tuni.$u.toast('验证码已发送');\n\t\t\t\t\t\t// 通知验证码组件内部开始倒计时\n\t\t\t\t\t\tthis.$refs.uCode.start();\n\t\t\t\t\t}, 2000);\n\t\t\t\t} else {\n\t\t\t\t\tuni.$u.toast('倒计时结束后再发送');\n\t\t\t\t}\n\t\t\t},\n\t\t\tend() {\n\t\t\t\tuni.$u.toast('倒计时结束');\n\t\t\t},\n\t\t\tstart() {\n\t\t\t\tuni.$u.toast('倒计时开始');\n\t\t\t}\n\t\t}\n\t}\n</script>\n\n<style lang=\"scss\" scoped>\n\t.wrap {\n\t\tpadding: 24rpx;\n\t}\n</style>\n```\n\n### 自定义提示语\n\n组件内部有内置的提示语，如获取验证码前的提示语为\"获取验证码\"，用户可以通过参数配置自定义的提示：\n- 获取前，参数为`start-text`，默认值为\"获取验证码\"\n- 倒计时期间，参数为`change-text`，默认为\"X秒重新获取\"，这里的\"x\"(大小写均可)，将会被倒计的秒数替代\n- 倒计时结束，参数为`end-text`，默认值为\"重新获取\"\n\n\n### 保持倒计时\n\n一般情况下，在H5刷新浏览器，或者各端返回再进入时，倒计时会消失，导致用户可以再次尝试获取验证码，虽然后端还会对此进行进一步的判断。  \n对于这种情况，uView给出了一个`keep-running`参数(默认为`false`)，为`true`的时候，即使刷新浏览器，或者返回上一个页面，\n倒计时依然会继续(如果还在倒计时间内的话)。\n\n**注意：** 如果您的一个页面或者多个页面同时使用了多个此组件，为了防止多个组件之间，保存在本地的多个继续倒计时的变量之间互相干扰，可以配置\n各个组件的`unique-key`为一个不重复的字符串，以作区分：\n\n```html\n/* A.vue */\n<u-verification-code unique-key=\"page-a\"></u-verification-code>\n\n/* B.vue */\n<u-verification-code unique-key=\"page-b\"></u-verification-code>\n```\n\n\n### API\n\n### Props\n\n| 参数         | 说明                                            | 类型             | 默认值      | 可选值 |\n| ------------ | ----------------------------------------------- | ---------------- | ----------- | ------ |\n| seconds      | 倒计时所需的秒数                                | Number \\| String | 60          | -      |\n| start-text   | 开始前的提示语，见上方说明                      | String           | 获取验证码  | -      |\n| change-text  | 倒计时期间的提示语，必须带有字母\"x\"，见上方说明 | String           | X秒重新获取 | -      |\n| end-text     | 倒计结束的提示语，见上方说明                    | String           | 重新获取    | -      |\n| keep-running | 是否在H5刷新或各端返回再进入时继续倒计时        | Boolean          | false       | true   |\n| unique-key   | 多个组件之间继续倒计时的区分`key`，见上方说明   | String           | -           | -      |\n\n\n### Methods\n\n需要通过ref获取验证码组件才能调用，见上方\"基本使用\"说明\n\n\n| 名称  | 说明                                                           |\n| ----- | -------------------------------------------------------------- |\n| start | 开始倒计时                                                     |\n| reset | 结束当前正在进行中的倒计时，设置组件为可以重新获取验证码的状态 |\n\n\n### Event\n\n| 事件名 | 说明                     | 回调参数                               | 版本 |\n| :----- | :----------------------- | :------------------------------------- | :--- |\n| change | 倒计时期间，每秒触发一次 | text: 当前剩余多少秒的状态，见上方说明 | -    |\n| start  | 开始倒计时触发           | -                                      | -    |\n| end    | 结束倒计时触发           | -                                      | -    |\n\n\n\n<style scoped>\nh3[id=props] + table thead tr th:nth-child(2){\n\twidth: 35%;\n}\n\nh3[id=methods] + p + table thead tr th:nth-child(2){\n\twidth: 60%;\n}\n</style>"
  },
  {
    "path": "src/static/app/markdown/vueUse.md",
    "content": "## 简要介绍Vue.use的原理\n\nuView会努力做好框架的内容，同时我们也希望您能学习到一些更深入的知识，我们坚信授之以鱼，不如授之以渔。\n\n当您使用一些第三方插件或者框架时，经常会看到他们的安装引导处会让您写大概如下的内容：\n\n```js\nimport uView from \"@/uview\";\n\nVue.use(uView);\n```\n\n这里第一句没什么好说的，我们着重讲第二句`Vue.use(uView)`：  \n这里我们把`uView`传递给了`Vue.use`，在`Vue`内部，是有定义一个`use`方法的，大概如下：  \n\n```js\n// 这里的plugin参数就是，就是我们通过Vue.use(uView)引入的\"uView\"\nVue.use = function (plugin: Function | Object) {\n    \n\t// ......\n\t\n\tconst args = toArray(arguments, 1)\n\t// 这一句很重要，这里的this，就是Vue，把他添加到args数组的第一个元素\n\targs.unshift(this)\n\t// 判断我们传递进来的\"uView\"，也即这里的\"plugin\"内部是否有一个叫\"install\"的方法\n\t// 如果有，就执行我们的\"uView\"，也即\"plugin.install\"方法\n    if (typeof plugin.install === 'function') {\n      plugin.install.apply(plugin, args)\n    } else if (typeof plugin === 'function') {\n      plugin.apply(null, args)\n    }\n\t\n\t// ......\n}\n```\n\n从上面，我们可以看出，Vue的`use`方法内部，接受了`uView`这个插件，并判断`uView`内部是否有一个叫`install`的方法，如果有，就执行它，并且\n通过`apply`方法把数组当做参数传递进去(这里数组内部第一个元素`Vue`这个对象，见上方注释，`apply`可以把数组[arg1, agr2]形式拆成(arg1, agr2)的形式)\n\n\n有了上面的分析，我们知道uView内部，肯定定义了一个叫`install`的方法，并且这个方法的第一个参数就是`Vue`这个对象，uView内部如下：\n\n```js\n// 这里我们定义了一个叫\"install\"的变量，它的内容是一个方法(函数)\n// 它的第一个参数是Vue对象(上面有提到传进来的第一个参数就是Vue)，我们把$u挂载到了Vue.prototype中\nconst install = (Vue) => {\n\tVue.prototype.$u = $u;\n}\n\n// 这里我们导出一个对象，内部有一个叫\"install\"的方法，给上面说的Vue.use调用\nexport default {\n\tinstall\n}\n```\n\n从上面我们可以看出，uView把\"$u\"挂载到了`Vue.prototype`上，所以我们在项目的内部可以使用`uni.$u.xxx`这种形式。\n"
  },
  {
    "path": "src/static/app/markdown/vuexDetail.md",
    "content": "## uView简化Vuex写法的基本原理\n\n`vuex`传统写法简单，但是也很繁琐：\n\n1. 我们需要在`vuex`中定义`state`和`mutations`\n2. 我们需要在每个用到`vuex`变量的地方，都引入`mapState`，同时还要解构到`computed`中去\n3. 修改`vuex`变量的时候，还需要通过`commit`提交\n4. 由于`vuex`变量是保存在运行内存中的，刷新浏览器`vuex`变量会消失，还需要通过其他手段实现变量的存续\n\n- 针对上面的第1点，我们写了一个统一的`mutations`，用于更新所有的`state`变量，这样可以免去每个变量都要写一个对应的`mutations`步骤，同时在\n这个统一的`mutations`中，根据配置判断是否在变量更新的时候，把它存进本地`Local Storage`，这样H5刷新或者APP下次启动，就会自动把这些变量赋值给\n`state`\n\n具体实现如下(当然，这可能不是最优的写法)\n\n```js\n// 根目录的/store/index.js\n\n$uStore(state, payload) {\n\t// 判断是否多层级调用，state中为对象存在的情况，诸如user.info.score = 1\n\tlet nameArr = payload.name.split('.');\n\tlet saveKey = '';\n\tlet len = nameArr.length;\n\tif(nameArr.length >= 2) {\n\t\tlet obj = state[nameArr[0]];\n\t\tfor(let i = 1; i < len - 1; i ++) {\n\t\t\tobj = obj[nameArr[i]];\n\t\t}\n\t\tobj[nameArr[len - 1]] = payload.value;\n\t\tsaveKey = nameArr[0];\n\t} else {\n\t\t// 单层级变量，在state就是一个普通变量的情况\n\t\tstate[payload.name] = payload.value;\n\t\tsaveKey = payload.name;\n\t}\n\tsaveLifeData(saveKey, state[saveKey])\n}\n```\n\n- 针对上面第二点，我们通过`Vue.mixin`全局混入的形式，可以很好的解决。`mixin`会把内容注入到每一个页面，所以我们在其中写了`mapState`到`computed`，\n每个页面自然地就获得了从`vuex`的`state`中注入的全局变量，这里我们需要在uni-app目根目录新建一个`store`文件夹(如果没有的话)，\n在其中新建一个`$u.mixin.js`文件，这个文件无需您手动引入和`Vue.mixin`处理，uView会自动处理，只为让您少写两行代码。\n\n```js\n// $u.mixin.js的部分实现\n\nimport { mapState } from 'vuex'\nimport store from \"@/store\"\n\n// 尝试将用户在根目录中的store/index.js的vuex的state变量，全部加载到全局变量中\nlet $uStoreKey = [];\ntry{\n\t$uStoreKey = store.state ? Object.keys(store.state) : [];\n}catch(e){}\n\nmodule.exports = {\n\tcomputed: {\n\t\t// 将vuex的state中的所有变量，解构到全局混入的mixin中\n\t\t...mapState($uStoreKey)\n\t}\n}\n```\n\n\n- 针对上面的第3点，因为我们通过统一的`mutations`的去更新`state`，自然就需要一个统一方法去触发`mutations`，用以替代原来的`commit`方法，\n具体是将此方法顺带写入到`$u.mixin.js`，并挂载到`this.$u`中，命名为`vuex`，见如下：\n\n```js\nmodule.exports = {\n\tcreated() {\n\t\t// 将vuex方法挂在到$u中\n\t\t// 使用方法为：如果要修改vuex的state中的user.name变量为\"史诗\" => uni.$u.vuex('user.name', '史诗')\n\t\t// 如果要修改vuex的state的version变量为1.0.1 => uni.$u.vuex('version', '1.0.1')\n\t\tuni.$u.vuex = (name, value) => {\n\t\t\tthis.$store.commit('$uStore', {\n\t\t\t\tname,value\n\t\t\t})\n\t\t}\n\t}\n}\n```\n\n当我们要修改某一个`state`值的时候，就用`uni.$u.vuex('name', value)`的形式，通过其他办法，也可以实现`this.name = value`的简写，但是这种方式\n不支持对象的修改，同时也会造成其他的问题，这里不做过多讨论。\n\n- 针对第4点，其实已经在第1点中解决了。\n\n上面的做法，只是抛砖引玉的做了一个思路的解析，如果您有更好的思路，也可以和我们分享。\n\n说明：确保您是新项目的情况下，或者您对这个实现方法很清楚，才使用这个方法。"
  },
  {
    "path": "src/static/app/markdown/waterfall.md",
    "content": "## Waterfall 瀑布流 <to-api/>\n\n<demo-model url=\"/pages/componentsB/waterfall/index\"></demo-model>\n\n\n这是一个瀑布流形式的组件，内容分为左右两列，结合uView的`懒加载`组件效果更佳。  \n相较于某些只是奇偶数左右分别，或者没有利用vue作用域插槽的做法，uView Pro的瀑布流实现了真正的\n组件化，搭配[LazyLoad 懒加载](/components/lazyLoad.html)和[loadMore 加载更多](/components/loadMore.html)组件，让您开箱即用，眼前一亮。\n\n<custom-block></custom-block>\n\n\n1. 在微信小程序中，需要hx2.8.11才支持在懒加载中结合其他组件\n2. 从1.2.8版本起，新增了清空列表和移除某条数据的组件方法，原`flow-list`参数，需要改为`v-model`接收传值\n3. 由于hx的问题，支付宝小程序需要hx2.8.2版本及以上才支持本组件\n\n\n### 平台差异说明\n\n|  App  |  H5   | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |\n| :---: | :---: | :--------: | :----------: | :--------: | :--------: | :------: |\n|   √   |   √   |     √      |      √       |     √      |     √      |    √     |\n\n### 基本使用\n\n本组件利用了vue的作用域插槽([详见vue文档](https://cn.vuejs.org/v2/guide/components-slots.html#%E4%BD%9C%E7%94%A8%E5%9F%9F%E6%8F%92%E6%A7%BD))特性，\n将传入`waterfall`内部的数据，通过`slot`(作用域插槽)让用户能在父组件中引用和配置对应的数据，这样做的\n原因是可以让用户自定义列表`item`的结构和样式，达到真正的组件化。  \n\n需要注意的是，组件内部导出的数据，需要使用`template`元素接收，同时通过`v-slot`指定左右两列的`slot`，如\n`v-slot:left=\"list\"`，这里的`list`变量名为用户自定义的(意味着您可以起名叫`data`都是没问题的)，它为一个对象，它内部分别有`leftList`和`rightList`，用于\n渲染左右两列的数据，见如下完整示例：\n\n### 核心代码\n```html\n<u-waterfall v-model=\"flowList\">\n\t<template v-slot:left=\"{leftList}\">\n\t\t<view v-for=\"(item, index) in leftList\" :key=\"index\">\n\t\t\t<!-- 这里编写您的内容，item为您传递给v-model的数组元素 -->\n\t\t</view>\n\t</template>\n\t<template v-slot:right=\"{rightList}\">\n\t\t<view v-for=\"(item, index) in rightList\" :key=\"index\">\n\t\t\t<!-- 这里编写您的内容，item为您传递给v-model的数组元素 -->\n\t\t</view>\n\t</template>\n</u-waterfall>\n```\n\n\n### 移除或清空数据\n\n移除或者清空，都需要通过`ref`调用组件内部的方法。\n\n1. 移除数据\n\n组件内部方法名为`remove`，需要传入\"id\"值，这个\"id\"键值的名称配置参数为`idKey`(默认`id`)，如下：\n\n假设您的数据为:\n\n```js\nlet arr = [\n\t{idx: 1, name: 'lisa'},\n\t{idx: 2, name: 'mary'}\n]\n```\n\n那么您应该配置`idKey`为`idx`。\n\n2. 清空数据\n\n通过`ref`手动调用组件内部的`clear`方法，可以清空左右两列的数据。\n\n说明：具体实现方法，请见下方的示例代码\n\n\n### 完整应用示例\n\n```html\n<template>\n\t<view class=\"wrap\">\n\t\t<u-button @click=\"clear\">清空列表</u-button>\n\t\t<u-waterfall v-model=\"flowList\" ref=\"uWaterfall\">\n\t\t\t<template v-slot:left=\"{leftList}\">\n\t\t\t\t<view class=\"demo-warter\" v-for=\"(item, index) in leftList\" :key=\"index\">\n\t\t\t\t\t<!-- 警告：微信小程序中需要hx2.8.11版本才支持在template中结合其他组件，比如下方的lazy-load组件 -->\n\t\t\t\t\t<u-lazy-load threshold=\"-450\" border-radius=\"10\" :image=\"item.image\" :index=\"index\"></u-lazy-load>\n\t\t\t\t\t<view class=\"demo-title\">\n\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t</view>\n\t\t\t\t\t<view class=\"demo-price\">\n\t\t\t\t\t\t{{item.price}}元\n\t\t\t\t\t</view>\n\t\t\t\t\t<view class=\"demo-tag\">\n\t\t\t\t\t\t<view class=\"demo-tag-owner\">\n\t\t\t\t\t\t\t自营\n\t\t\t\t\t\t</view>\n\t\t\t\t\t\t<view class=\"demo-tag-text\">\n\t\t\t\t\t\t\t放心购\n\t\t\t\t\t\t</view>\n\t\t\t\t\t</view>\n\t\t\t\t\t<view class=\"demo-shop\">\n\t\t\t\t\t\t{{item.shop}}\n\t\t\t\t\t</view>\n\t\t\t\t\t<u-icon name=\"close-circle-fill\" color=\"#fa3534\" size=\"34\" class=\"u-close\" @click=\"remove(item.id)\"></u-icon>\n\t\t\t\t</view>\n\t\t\t</template>\n\t\t\t<template v-slot:right=\"{rightList}\">\n\t\t\t\t<view class=\"demo-warter\" v-for=\"(item, index) in rightList\" :key=\"index\">\n\t\t\t\t\t<u-lazy-load threshold=\"-450\" border-radius=\"10\" :image=\"item.image\" :index=\"index\"></u-lazy-load>\n\t\t\t\t\t<view class=\"demo-title\">\n\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t</view>\n\t\t\t\t\t<view class=\"demo-price\">\n\t\t\t\t\t\t{{item.price}}元\n\t\t\t\t\t</view>\n\t\t\t\t\t<view class=\"demo-tag\">\n\t\t\t\t\t\t<view class=\"demo-tag-owner\">\n\t\t\t\t\t\t\t自营\n\t\t\t\t\t\t</view>\n\t\t\t\t\t\t<view class=\"demo-tag-text\">\n\t\t\t\t\t\t\t放心购\n\t\t\t\t\t\t</view>\n\t\t\t\t\t</view>\n\t\t\t\t\t<view class=\"demo-shop\">\n\t\t\t\t\t\t{{item.shop}}\n\t\t\t\t\t</view>\n\t\t\t\t\t<u-icon name=\"close-circle-fill\" color=\"#fa3534\" size=\"34\" class=\"u-close\" @click=\"remove(item.id)\"></u-icon>\n\t\t\t\t</view>\n\t\t\t</template>\n\t\t</u-waterfall>\n\t\t<u-loadmore bg-color=\"rgb(240, 240, 240)\" :status=\"loadStatus\" @loadmore=\"addRandomData\"></u-loadmore>\n\t</view>\n</template>\n\n<script>\n\texport default {\n\t\tdata() {\n\t\t\treturn {\n\t\t\t\tloadStatus: 'loadmore',\n\t\t\t\tflowList: [],\n\t\t\t\tlist: [\n\t\t\t\t\t{\n\t\t\t\t\t\tprice: 35,\n\t\t\t\t\t\ttitle: '北国风光，千里冰封，万里雪飘',\n\t\t\t\t\t\tshop: '李白杜甫白居易旗舰店',\n\t\t\t\t\t\timage: 'http://pic.sc.chinaz.com/Files/pic/pic9/202002/zzpic23327_s.jpg',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tprice: 75,\n\t\t\t\t\t\ttitle: '望长城内外，惟余莽莽',\n\t\t\t\t\t\tshop: '李白杜甫白居易旗舰店',\n\t\t\t\t\t\timage: 'http://pic.sc.chinaz.com/Files/pic/pic9/202002/zzpic23325_s.jpg',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tprice: 385,\n\t\t\t\t\t\ttitle: '大河上下，顿失滔滔',\n\t\t\t\t\t\tshop: '李白杜甫白居易旗舰店',\n\t\t\t\t\t\timage: 'http://pic2.sc.chinaz.com/Files/pic/pic9/202002/hpic2119_s.jpg',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tprice: 784,\n\t\t\t\t\t\ttitle: '欲与天公试比高',\n\t\t\t\t\t\tshop: '李白杜甫白居易旗舰店',\n\t\t\t\t\t\timage: 'http://pic2.sc.chinaz.com/Files/pic/pic9/202002/zzpic23369_s.jpg',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tprice: 7891,\n\t\t\t\t\t\ttitle: '须晴日，看红装素裹，分外妖娆',\n\t\t\t\t\t\tshop: '李白杜甫白居易旗舰店',\n\t\t\t\t\t\timage: 'http://pic2.sc.chinaz.com/Files/pic/pic9/202002/hpic2130_s.jpg',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tprice: 2341,\n\t\t\t\t\t\tshop: '李白杜甫白居易旗舰店',\n\t\t\t\t\t\ttitle: '江山如此多娇，引无数英雄竞折腰',\n\t\t\t\t\t\timage: 'http://pic1.sc.chinaz.com/Files/pic/pic9/202002/zzpic23346_s.jpg',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tprice: 661,\n\t\t\t\t\t\tshop: '李白杜甫白居易旗舰店',\n\t\t\t\t\t\ttitle: '惜秦皇汉武，略输文采',\n\t\t\t\t\t\timage: 'http://pic1.sc.chinaz.com/Files/pic/pic9/202002/zzpic23344_s.jpg',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tprice: 1654,\n\t\t\t\t\t\ttitle: '唐宗宋祖，稍逊风骚',\n\t\t\t\t\t\tshop: '李白杜甫白居易旗舰店',\n\t\t\t\t\t\timage: 'http://pic1.sc.chinaz.com/Files/pic/pic9/202002/zzpic23343_s.jpg',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tprice: 1678,\n\t\t\t\t\t\ttitle: '一代天骄，成吉思汗',\n\t\t\t\t\t\tshop: '李白杜甫白居易旗舰店',\n\t\t\t\t\t\timage: 'http://pic1.sc.chinaz.com/Files/pic/pic9/202002/zzpic23343_s.jpg',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tprice: 924,\n\t\t\t\t\t\ttitle: '只识弯弓射大雕',\n\t\t\t\t\t\tshop: '李白杜甫白居易旗舰店',\n\t\t\t\t\t\timage: 'http://pic1.sc.chinaz.com/Files/pic/pic9/202002/zzpic23343_s.jpg',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tprice: 8243,\n\t\t\t\t\t\ttitle: '俱往矣，数风流人物，还看今朝',\n\t\t\t\t\t\tshop: '李白杜甫白居易旗舰店',\n\t\t\t\t\t\timage: 'http://pic1.sc.chinaz.com/Files/pic/pic9/202002/zzpic23343_s.jpg',\n\t\t\t\t\t},\n\t\t\t\t]\n\t\t\t}\n\t\t},\n\t\tonLoad() {\n\t\t\tthis.addRandomData();\n\t\t},\n\t\tonReachBottom() {\n\t\t\tthis.loadStatus = 'loading';\n\t\t\t// 模拟数据加载\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.addRandomData();\n\t\t\t\tthis.loadStatus = 'loadmore';\n\t\t\t}, 1000)\n\t\t},\n\t\tmethods: {\n\t\t\taddRandomData() {\n\t\t\t\tfor(let i = 0; i < 10; i++) {\n\t\t\t\t\tlet index = uni.$u.random(0, this.list.length - 1);\n\t\t\t\t\t// 先转成字符串再转成对象，避免数组对象引用导致数据混乱\n\t\t\t\t\tlet item = JSON.parse(JSON.stringify(this.list[index]))\n\t\t\t\t\titem.id = uni.$u.guid();\n\t\t\t\t\tthis.flowList.push(item);\n\t\t\t\t}\n\t\t\t},\n\t\t\tremove(id) {\n\t\t\t\tthis.$refs.uWaterfall.remove(id);\n\t\t\t},\n\t\t\tclear() {\n\t\t\t\tthis.$refs.uWaterfall.clear();\n\t\t\t}\n\t\t}\n\t}\n</script>\n\n<style>\n\t/* page不能写带scope的style标签中，否则无效 */\n\tpage {\n\t\tbackground-color: rgb(240, 240, 240);\n\t}\n</style>\n\n<style lang=\"scss\" scoped>\n\t.demo-warter {\n\t\tborder-radius: 8px;\n\t\tmargin: 5px;\n\t\tbackground-color: #ffffff;\n\t\tpadding: 8px;\n\t\tposition: relative;\n\t}\n\t\n\t.u-close {\n\t\tposition: absolute;\n\t\ttop: 32rpx;\n\t\tright: 32rpx;\n\t}\n\t\n\t.demo-image {\n\t\twidth: 100%;\n\t\tborder-radius: 4px;\n\t}\n\t\n\t.demo-title {\n\t\tfont-size: 30rpx;\n\t\tmargin-top: 5px;\n\t\tcolor: $u-main-color;\n\t}\n\t\n\t.demo-tag {\n\t\tdisplay: flex;\n\t\tmargin-top: 5px;\n\t}\n\t\n\t.demo-tag-owner {\n\t\tbackground-color: $u-type-error;\n\t\tcolor: #FFFFFF;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tpadding: 4rpx 14rpx;\n\t\tborder-radius: 50rpx;\n\t\tfont-size: 20rpx;\n\t\tline-height: 1;\n\t}\n\t\n\t.demo-tag-text {\n\t\tborder: 1px solid $u-type-primary;\n\t\tcolor: $u-type-primary;\n\t\tmargin-left: 10px;\n\t\tborder-radius: 50rpx;\n\t\tline-height: 1;\n\t\tpadding: 4rpx 14rpx;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tborder-radius: 50rpx;\n\t\tfont-size: 20rpx;\n\t}\n\t\n\t.demo-price {\n\t\tfont-size: 30rpx;\n\t\tcolor: $u-type-error;\n\t\tmargin-top: 5px;\n\t}\n\t\n\t.demo-shop {\n\t\tfont-size: 22rpx;\n\t\tcolor: $u-tips-color;\n\t\tmargin-top: 5px;\n\t}\n</style>\n```\n\n### 注意事项\n\n1. 上方的示例中，结合了uView的[lazyload懒加载](/components/lazyLoad.html)和[loadmore加载更多](/components/loadmore.html)组件，具体用法，请见文档。  \n2. 需要通过`v-model`传递参数，将数据传递给组件，组件内部将每次新增的数据，通过动态查询左右列的高度\n添加到高度低的一列。  \n3. 组件有一个`add-time`参数，用于将单条数据添加到队列的时间间隔，因为图片加载是需要时间的，所以瀑布流左右列\n的高度会不定时改变，`add-time`值越大，对程序效果越好，但是对用户来说，越大值可能就是以能感受的速度一个一个添加\n到队列尾部的，所以这是一个双面性的结果。\n4. 由于图片加载完成的时机是不确定的，导致图片加载完成时，队列的高度会发生改变，而且这个时机是无法确定的，\n所以每次添加数据的时候，单次请求的所有数据中最后一个数据不一定能准确添加高度更低的队列一侧，但是可以保证下一次请求数据的第一条\n能准确添加到队列高度低的一侧。\n\n\n### API\n\n### IndexBar Props\n\n注意：1.2.8版本后，通过`v-model`双向绑定传递参数，因为组件内部需要修改父组件的值。\n\n| 参数     | 说明                                                     | 类型             | 默认值 | 可选值 |\n| -------- | -------------------------------------------------------- | ---------------- | ------ | ------ |\n| add-time | 单条数据添加到队列的时间间隔，单位ms，见上方注意事项说明 | String \\| Number | 200    | -      |\n| idKey    | 数据的唯一值的键名，见上方说明                           | String           | id     | -      |\n\n\n\n### Methods\n\n这些为组件内部的方法，需要通过`ref`调用\n\n| 参数       | 说明                           |\n| ---------- | ------------------------------ |\n| clear      | 清空列表数据                   |\n| remove(id) | `id`为唯一的\"id\"值，见上方说明 |\n\n\n\n<style scoped>\nh3[id=methods] + p + table thead tr th:nth-child(2){\n\twidth: 50%;\n}\n</style>"
  },
  {
    "path": "src/static/common/js/touch-emulator.js",
    "content": "(function (window, document, exportName, undefined) {\n    'use strict';\n\n    var isMultiTouch = false;\n    var multiTouchStartPos;\n    var eventTarget;\n    var touchElements = {};\n\n    // polyfills\n    if (!document.createTouch) {\n        document.createTouch = function (view, target, identifier, pageX, pageY, screenX, screenY, clientX, clientY) {\n            // auto set\n            if (clientX == undefined || clientY == undefined) {\n                clientX = pageX - window.pageXOffset;\n                clientY = pageY - window.pageYOffset;\n            }\n\n            return new Touch(target, identifier, {\n                pageX: pageX,\n                pageY: pageY,\n                screenX: screenX,\n                screenY: screenY,\n                clientX: clientX,\n                clientY: clientY\n            });\n        };\n    }\n\n    if (!document.createTouchList) {\n        document.createTouchList = function () {\n            var touchList = new TouchList();\n            for (var i = 0; i < arguments.length; i++) {\n                touchList[i] = arguments[i];\n            }\n            touchList.length = arguments.length;\n            return touchList;\n        };\n    }\n\n    /**\n     * create an touch point\n     * @constructor\n     * @param target\n     * @param identifier\n     * @param pos\n     * @param deltaX\n     * @param deltaY\n     * @returns {Object} touchPoint\n     */\n    function Touch(target, identifier, pos, deltaX, deltaY) {\n        deltaX = deltaX || 0;\n        deltaY = deltaY || 0;\n\n        this.identifier = identifier;\n        this.target = target;\n        this.clientX = pos.clientX + deltaX;\n        this.clientY = pos.clientY + deltaY;\n        this.screenX = pos.screenX + deltaX;\n        this.screenY = pos.screenY + deltaY;\n        this.pageX = pos.pageX + deltaX;\n        this.pageY = pos.pageY + deltaY;\n    }\n\n    /**\n     * create empty touchlist with the methods\n     * @constructor\n     * @returns touchList\n     */\n    function TouchList() {\n        var touchList = [];\n\n        touchList.item = function (index) {\n            return this[index] || null;\n        };\n\n        // specified by Mozilla\n        touchList.identifiedTouch = function (id) {\n            return this[id + 1] || null;\n        };\n\n        return touchList;\n    }\n\n    /**\n     * Simple trick to fake touch event support\n     * this is enough for most libraries like Modernizr and Hammer\n     */\n    function fakeTouchSupport() {\n        var objs = [window, document.documentElement];\n        var props = ['ontouchstart', 'ontouchmove', 'ontouchcancel', 'ontouchend'];\n\n        for (var o = 0; o < objs.length; o++) {\n            for (var p = 0; p < props.length; p++) {\n                if (objs[o] && objs[o][props[p]] == undefined) {\n                    objs[o][props[p]] = null;\n                }\n            }\n        }\n    }\n\n    /**\n     * we don't have to emulate on a touch device\n     * @returns {boolean}\n     */\n    function hasTouchSupport() {\n        return (\n            'ontouchstart' in window || // touch events\n            (window.Modernizr && window.Modernizr.touch) || // modernizr\n            (navigator.msMaxTouchPoints || navigator.maxTouchPoints) > 2\n        ); // pointer events\n    }\n\n    /**\n     * disable mouseevents on the page\n     * @param ev\n     */\n    function preventMouseEvents(ev) {\n        // 注释启用默认事件\n        // ev.preventDefault();\n        // ev.stopPropagation();\n    }\n\n    /**\n     * only trigger touches when the left mousebutton has been pressed\n     * @param touchType\n     * @returns {Function}\n     */\n    function onMouse(touchType) {\n        return function (ev) {\n            // prevent mouse events\n            preventMouseEvents(ev);\n\n            if (ev.which !== 1) {\n                return;\n            }\n\n            // The EventTarget on which the touch point started when it was first placed on the surface,\n            // even if the touch point has since moved outside the interactive area of that element.\n            // also, when the target doesnt exist anymore, we update it\n            if (ev.type == 'mousedown' || !eventTarget || (eventTarget && !eventTarget.dispatchEvent)) {\n                eventTarget = ev.target;\n            }\n\n            // shiftKey has been lost, so trigger a touchend\n            if (isMultiTouch && !ev.shiftKey) {\n                triggerTouch('touchend', ev);\n                isMultiTouch = false;\n            }\n\n            triggerTouch(touchType, ev);\n\n            // we're entering the multi-touch mode!\n            if (!isMultiTouch && ev.shiftKey) {\n                isMultiTouch = true;\n                multiTouchStartPos = {\n                    pageX: ev.pageX,\n                    pageY: ev.pageY,\n                    clientX: ev.clientX,\n                    clientY: ev.clientY,\n                    screenX: ev.screenX,\n                    screenY: ev.screenY\n                };\n                triggerTouch('touchstart', ev);\n            }\n\n            // reset\n            if (ev.type == 'mouseup') {\n                multiTouchStartPos = null;\n                isMultiTouch = false;\n                eventTarget = null;\n            }\n        };\n    }\n\n    /**\n     * trigger a touch event\n     * @param eventName\n     * @param mouseEv\n     */\n    function triggerTouch(eventName, mouseEv) {\n        var touchEvent = document.createEvent('Event');\n        touchEvent.initEvent(eventName, true, true);\n\n        touchEvent.altKey = mouseEv.altKey;\n        touchEvent.ctrlKey = mouseEv.ctrlKey;\n        touchEvent.metaKey = mouseEv.metaKey;\n        touchEvent.shiftKey = mouseEv.shiftKey;\n\n        touchEvent.touches = getActiveTouches(mouseEv, eventName);\n        touchEvent.targetTouches = getActiveTouches(mouseEv, eventName);\n        touchEvent.changedTouches = getChangedTouches(mouseEv, eventName);\n\n        eventTarget.dispatchEvent(touchEvent);\n    }\n\n    /**\n     * create a touchList based on the mouse event\n     * @param mouseEv\n     * @returns {TouchList}\n     */\n    function createTouchList(mouseEv) {\n        var touchList = new TouchList();\n\n        if (isMultiTouch) {\n            var f = TouchEmulator.multiTouchOffset;\n            var deltaX = multiTouchStartPos.pageX - mouseEv.pageX;\n            var deltaY = multiTouchStartPos.pageY - mouseEv.pageY;\n\n            touchList.push(new Touch(eventTarget, 1, multiTouchStartPos, deltaX * -1 - f, deltaY * -1 + f));\n            touchList.push(new Touch(eventTarget, 2, multiTouchStartPos, deltaX + f, deltaY - f));\n        } else {\n            touchList.push(new Touch(eventTarget, 1, mouseEv, 0, 0));\n        }\n\n        return touchList;\n    }\n\n    /**\n     * receive all active touches\n     * @param mouseEv\n     * @returns {TouchList}\n     */\n    function getActiveTouches(mouseEv, eventName) {\n        // empty list\n        if (mouseEv.type == 'mouseup') {\n            return new TouchList();\n        }\n\n        var touchList = createTouchList(mouseEv);\n        if (isMultiTouch && mouseEv.type != 'mouseup' && eventName == 'touchend') {\n            touchList.splice(1, 1);\n        }\n        return touchList;\n    }\n\n    /**\n     * receive a filtered set of touches with only the changed pointers\n     * @param mouseEv\n     * @param eventName\n     * @returns {TouchList}\n     */\n    function getChangedTouches(mouseEv, eventName) {\n        var touchList = createTouchList(mouseEv);\n\n        // we only want to return the added/removed item on multitouch\n        // which is the second pointer, so remove the first pointer from the touchList\n        //\n        // but when the mouseEv.type is mouseup, we want to send all touches because then\n        // no new input will be possible\n        if (isMultiTouch && mouseEv.type != 'mouseup' && (eventName == 'touchstart' || eventName == 'touchend')) {\n            touchList.splice(0, 1);\n        }\n\n        return touchList;\n    }\n\n    /**\n     * show the touchpoints on the screen\n     */\n    function showTouches(ev) {\n        var touch, i, el, styles;\n\n        // first all visible touches\n        for (i = 0; i < ev.touches.length; i++) {\n            touch = ev.touches[i];\n            el = touchElements[touch.identifier];\n            if (!el) {\n                el = touchElements[touch.identifier] = document.createElement('div');\n                document.body.appendChild(el);\n            }\n\n            styles = TouchEmulator.template(touch);\n            for (var prop in styles) {\n                el.style[prop] = styles[prop];\n            }\n        }\n\n        // remove all ended touches\n        if (ev.type == 'touchend' || ev.type == 'touchcancel') {\n            for (i = 0; i < ev.changedTouches.length; i++) {\n                touch = ev.changedTouches[i];\n                el = touchElements[touch.identifier];\n                if (el) {\n                    el.parentNode.removeChild(el);\n                    delete touchElements[touch.identifier];\n                }\n            }\n        }\n    }\n\n    /**\n     * TouchEmulator initializer\n     */\n    function TouchEmulator() {\n        if (hasTouchSupport()) {\n            return;\n        }\n\n        fakeTouchSupport();\n\n        window.addEventListener('mousedown', onMouse('touchstart'), true);\n        window.addEventListener('mousemove', onMouse('touchmove'), true);\n        window.addEventListener('mouseup', onMouse('touchend'), true);\n\n        window.addEventListener('mouseenter', preventMouseEvents, true);\n        window.addEventListener('mouseleave', preventMouseEvents, true);\n        window.addEventListener('mouseout', preventMouseEvents, true);\n        window.addEventListener('mouseover', preventMouseEvents, true);\n\n        // it uses itself!\n        window.addEventListener('touchstart', showTouches, true);\n        window.addEventListener('touchmove', showTouches, true);\n        window.addEventListener('touchend', showTouches, true);\n        window.addEventListener('touchcancel', showTouches, true);\n    }\n\n    // start distance when entering the multitouch mode\n    TouchEmulator.multiTouchOffset = 75;\n\n    /**\n     * css template for the touch rendering\n     * @param touch\n     * @returns object\n     */\n    TouchEmulator.template = function (touch) {\n        var size = 0;\n        var transform = 'translate(' + (touch.clientX - size / 2) + 'px, ' + (touch.clientY - size / 2) + 'px)';\n        return {\n            position: 'fixed',\n            left: 0,\n            top: 0,\n            background: '#fff',\n            border: 'solid 1px #999',\n            opacity: 0.6,\n            borderRadius: '100%',\n            height: size + 'px',\n            width: size + 'px',\n            padding: 0,\n            margin: 0,\n            display: 'block',\n            overflow: 'hidden',\n            pointerEvents: 'none',\n            webkitUserSelect: 'none',\n            mozUserSelect: 'none',\n            userSelect: 'none',\n            webkitTransform: transform,\n            mozTransform: transform,\n            transform: transform,\n            zIndex: 100\n        };\n    };\n\n    // export\n    if (typeof define == 'function' && define.amd) {\n        define(function () {\n            return TouchEmulator;\n        });\n    } else if (typeof module != 'undefined' && module.exports) {\n        module.exports = TouchEmulator;\n    } else {\n        window[exportName] = TouchEmulator;\n    }\n})(window, document, 'TouchEmulator');\n"
  },
  {
    "path": "src/theme.json",
    "content": "{\n    \"light\": {\n        \"bgColor\": \"#fcfcfc\",\n        \"bgColorBottom\": \"#fcfcfc\",\n        \"bgColorTop\": \"#ffffff\",\n        \"bgTxtStyle\": \"dark\",\n        \"navBgColor\": \"#ffffff\",\n        \"navTxtStyle\": \"black\",\n        \"tabBgColor\": \"#fcfcfc\",\n        \"tabBorderStyle\": \"black\",\n        \"tabFontColor\": \"#1f2937\",\n        \"tabSelectedColor\": \"#303133\"\n    },\n    \"dark\": {\n        \"bgColor\": \"#181818\",\n        \"bgColorBottom\": \"#181818\",\n        \"bgColorTop\": \"#0f1115\",\n        \"bgTxtStyle\": \"light\",\n        \"navBgColor\": \"#0f1115\",\n        \"navTxtStyle\": \"white\",\n        \"tabBgColor\": \"#181818\",\n        \"tabBorderStyle\": \"white\",\n        \"tabFontColor\": \"#f3f4f6\",\n        \"tabSelectedColor\": \"#f5f6f7\"\n    }\n}\n"
  },
  {
    "path": "src/uni.scss",
    "content": "/**\r\n * 这里是uni-app内置的常用样式变量\r\n *\r\n * uni-app 官方扩展插件及插件市场（https://ext.dcloud.net.cn）上很多三方插件均使用了这些样式变量\r\n * 如果你是插件开发者，建议你使用scss预处理，并在插件代码中直接使用这些变量（无需 import 这个文件），方便用户通过搭积木的方式开发整体风格一致的App\r\n *\r\n */\r\n\r\n/**\r\n * 如果你是App开发者（插件使用者），你可以通过修改这些变量来定制自己的插件主题，实现自定义主题功能\r\n *\r\n * 如果你的项目同样使用了scss预处理，你也可以直接在你的 scss 代码中使用如下变量，同时无需 import 这个文件\r\n */\r\n\r\n/* 颜色变量 */\r\n\r\n/* 行为相关颜色 */\r\n$uni-color-primary: #007aff;\r\n$uni-color-success: #4cd964;\r\n$uni-color-warning: #f0ad4e;\r\n$uni-color-error: #dd524d;\r\n\r\n/* 文字基本颜色 */\r\n$uni-text-color: #333; // 基本色\r\n$uni-text-color-inverse: #fff; // 反色\r\n$uni-text-color-grey: #999; // 辅助灰色，如加载更多的提示信息\r\n$uni-text-color-placeholder: #808080;\r\n$uni-text-color-disable: #c0c0c0;\r\n\r\n/* 背景颜色 */\r\n$uni-bg-color: #fff;\r\n$uni-bg-color-grey: #f8f8f8;\r\n$uni-bg-color-hover: #f1f1f1; // 点击状态颜色\r\n$uni-bg-color-mask: rgba(0, 0, 0, 0.4); // 遮罩颜色\r\n\r\n/* 边框颜色 */\r\n$uni-border-color: #c8c7cc;\r\n\r\n/* 尺寸变量 */\r\n\r\n/* 文字尺寸 */\r\n$uni-font-size-sm: 12px;\r\n$uni-font-size-base: 14px;\r\n$uni-font-size-lg: 16;\r\n\r\n/* 图片尺寸 */\r\n$uni-img-size-sm: 20px;\r\n$uni-img-size-base: 26px;\r\n$uni-img-size-lg: 40px;\r\n\r\n/* Border Radius */\r\n$uni-border-radius-sm: 2px;\r\n$uni-border-radius-base: 3px;\r\n$uni-border-radius-lg: 6px;\r\n$uni-border-radius-circle: 50%;\r\n\r\n/* 水平间距 */\r\n$uni-spacing-row-sm: 5px;\r\n$uni-spacing-row-base: 10px;\r\n$uni-spacing-row-lg: 15px;\r\n\r\n/* 垂直间距 */\r\n$uni-spacing-col-sm: 4px;\r\n$uni-spacing-col-base: 8px;\r\n$uni-spacing-col-lg: 12px;\r\n\r\n/* 透明度 */\r\n$uni-opacity-disabled: 0.3; // 组件禁用态的透明度\r\n\r\n/* 文章场景相关 */\r\n$uni-color-title: #2c405a; // 文章标题颜色\r\n$uni-font-size-title: 20px;\r\n$uni-color-subtitle: #555; // 二级标题颜色\r\n$uni-font-size-subtitle: 18px;\r\n$uni-color-paragraph: #3f536e; // 文章段落颜色\r\n$uni-font-size-paragraph: 15px;\r\n\r\n@import 'uview-pro/theme.scss';\r\n"
  },
  {
    "path": "src/uni_modules/uview-pro/.npmignore",
    "content": "demo/\n.npmrc\n"
  },
  {
    "path": "src/uni_modules/uview-pro/changelog.md",
    "content": "## 0.6.0-beta.1（2026-05-08）\n\n### ✨ Features | 新功能\n\n- **u-upload:** 新增image-shape属性支持圆形和方形展示 ([fac9414](https://github.com/anyup/uView-Pro/commit/fac941413ba4d944116513934306376a0188fcda))\n- **u-upload:** 新增customChoose属性支持自定义文件选择功能 ([97e17ee](https://github.com/anyup/uView-Pro/commit/97e17eeae15c03a7791bb5eec4159782f3d70d84))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.6.0-beta.0（2026-04-30）\n\n### ✨ Features | 新功能\n\n- **u-upload:** 新增多种上传模式和文件类型支持，支持图片、视频、文档等多种类型，支持网格(grid)和列表(list)两种展示模式 ([f75d34c](https://github.com/anyup/uView-Pro/commit/f75d34c22d551c41e8e873bc5779089ff2b2c0c7))\n- **u-upload:** 新增 v-model 支持并优化文件列表同步逻辑 ([5548d84](https://github.com/anyup/uView-Pro/commit/5548d847b5c442da40775ec06ecfab7f0fddf448))\n- **upload:** 完善上传组件示例页面功能，添加多种上传模式示例：图片上传（网格模式）、文件上传（列表模式）、视频上传 ([d43b3d2](https://github.com/anyup/uView-Pro/commit/d43b3d2c7f0ff7a7fe45467d49d451ca878b7eb1))\n\n### ♻️ Code Refactoring | 代码重构\n\n- **u-divider:** 规范化 slot 标签 ([fccac33](https://github.com/anyup/uView-Pro/commit/fccac33b6adce3395179d5c55b7b8a0a4d25a800))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-upload:** 优化微信小程序平台监听文件列表变化不触发on-list-change事件的场景 ([47fa5c1](https://github.com/anyup/uView-Pro/commit/47fa5c1dfa30214dfc40f7ee01b09f6f95d09b9a))\n- **changelog:** 修复版本标题格式和Unreleased区块处理 ([3a87f47](https://github.com/anyup/uView-Pro/commit/3a87f4739cdebc1aafcb33e3f9b31dd79f9bc3d2))\n\n### 👷 Continuous Integration | CI 配置\n\n- 增强预发布版本支持和发布管理功能 ([86abdaa](https://github.com/anyup/uView-Pro/commit/86abdaad6a618dfa42416138f05baf910f52fba5))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.5.18（2026-04-22）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-calendar:** 修复农历数据响应式访问问题 ([0a88b13](https://github.com/anyup/uView-Pro/commit/0a88b13911fc8c47229f5d9cab0fdfc8ade09ecb))\n- **mp-weixin:** 修复微信小程序演示示例vue-i18n多语言切换后uni.getLocale()始终获取中文的问题 ([30b811f](https://github.com/anyup/uView-Pro/commit/30b811f85db29165cd150bea380dfe44f94fda79))\n- **demo:** 取消底部导航标题配置设置国际化文案 ([7b949ab](https://github.com/anyup/uView-Pro/commit/7b949ab8695fbc3d9db51b96da1b25a1f05c2ed3))\n- **demo:** 修复日历组件demo切换逻辑 ([9aa706a](https://github.com/anyup/uView-Pro/commit/9aa706a0e7b564c2bef75d1d6e7a90023dfc1c17))\n\n### ✨ Features | 新功能\n\n- **u-tabbar:** 底部导航栏支持自定义item宽度配置，优化item平分功能 ([997846f](https://github.com/anyup/uView-Pro/commit/997846fb5f8ba4648e4d0514f0846ce80a217490))\n\n### 📝 Documentation | 文档\n\n- update uview pro desc ([ba65d2e](https://github.com/anyup/uView-Pro/commit/ba65d2e34a1e620b595122a81df48a333c97bbcd))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.5.17（2026-04-15）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **demo:** 修复topTips组件演示示例在小程序中不弹出的问题，需设置自定义navbar高度 ([0c72d24](https://github.com/anyup/uView-Pro/commit/0c72d24cd77f4ba6b6cb411810fcf5f0bd1d3272))\n- **u-table:** 修复表格表头暗黑模式背景色问题 ([c7fd1a5](https://github.com/anyup/uView-Pro/commit/c7fd1a58e87c4efb84ccf737fe9d1e755908ba8f))\n- **u-alert-tips:** 修复关闭按钮颜色样式问题 ([94001cf](https://github.com/anyup/uView-Pro/commit/94001cf79a03ea75695e414a7971e7ec39f445b6))\n\n### ✨ Features | 新功能\n\n- **theme:** 更新主题配置和本地化文本 ([4caa2ed](https://github.com/anyup/uView-Pro/commit/4caa2edf9542f7f2b0a7bb9870585390f0241e80))\n- **u-calendar:** 增强日历组件功能，支持多种日历模式：打卡签到、节假日标记、价格日历等场景，支持自定义插槽功能，动态价格显示；支持选中日期，只读模式设置；修复范围选择背景色样式问题 ([7a9250e](https://github.com/anyup/uView-Pro/commit/7a9250eb49f6694286bb0c3dad7bc9780ae95864))\n- **u-popup:** 新增inline模式支持，允许弹窗组件直接插入页面内容而非传统弹窗形式 ([2e8890c](https://github.com/anyup/uView-Pro/commit/2e8890ca3c9cacb90739b33cb0e38db7e2bdb473))\n- **u-calendar:** 统一日期格式YYYY-MM-DD，确保跨组件日期处理的一致性 ([092cc53](https://github.com/anyup/uView-Pro/commit/092cc5392b64990342c43fcbac9aec1bfa2bf982))\n\n### ♻️ Code Refactoring | 代码重构\n\n- **u-calendar:** 重构日历组件模板，统一页面和弹窗模式的日历组件结构 ([42894b8](https://github.com/anyup/uView-Pro/commit/42894b850f903e2471ca42e02f0379443139838b))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.5.16（2026-03-26）\n\n### ✨ Features | 新功能\n\n- **web:** 浏览器平台添加触摸模拟器支持 ([cf96a73](https://github.com/anyup/uView-Pro/commit/cf96a73e09512291143954401aa7850ac59f1207))\n- **u-button:** 新增 large、small 按钮尺寸选项，丰富按钮尺寸规格 ([053d7e8](https://github.com/anyup/uView-Pro/commit/053d7e8ab92af403cdfde36369f38a2aded27288))\n- **u-input:** u-input添加size属性，支持small/default/large预设值以及自定义尺寸（#137） ([afed961](https://github.com/anyup/uView-Pro/commit/afed961f65c86bd84a2b02828bb361480c7f95b3))\n- **u-textarea:** u-textarea组件新增size属性，支持small/default/large预设值以及自定义数值（#137） ([47296e8](https://github.com/anyup/uView-Pro/commit/47296e8669d419d41959dff01de758a610122d34))\n- **u-checkbox:** u-checkbox，u-checkbox-group支持small/default/large预设尺寸配置，优化组件样式（#137） ([e8918e2](https://github.com/anyup/uView-Pro/commit/e8918e28a413d861e05a213d49f9a1b39af17964))\n- **u-radio:** u-radio，u-radio-group支持small/default/large预设尺寸配置（#137） ([51af7f8](https://github.com/anyup/uView-Pro/commit/51af7f8f86eed99ee159738e43d5dc2d5c6747c8))\n- **u-switch:** u-switch支持small/default/large预设尺寸配置（#137） ([6041d52](https://github.com/anyup/uView-Pro/commit/6041d52338172d40957e3ed7af1dde01aa7de074))\n- **u-form:** 新增表单大小配置功能，u-form支持小、中、大三种尺寸设置（#137） ([324adb9](https://github.com/anyup/uView-Pro/commit/324adb99de9dfbb72a0a0c40748c11323d3b9470))\n- **u-tag:** 为深色模式标签添加边框样式，保持统一性 ([84d0ad6](https://github.com/anyup/uView-Pro/commit/84d0ad6c805d570e216beaa2dc586687a5aae848))\n\n### ♻️ Code Refactoring | 代码重构\n\n- 添加调试模式配置并重构日志系统 ([a52a3f7](https://github.com/anyup/uView-Pro/commit/a52a3f7d6be7d8332a67c1d8458f4e65e0a0204e))\n- **props:** 移除baseProps公共属性并内联到各组件，修复uni_modules引入方式在微信小程序正式打包运行报错的问题 ([f30f779](https://github.com/anyup/uView-Pro/commit/f30f7792a48679afc3cf705a5eb0b182591fe9b5))\n- **form:** 调整表单大小配置位置 ([45ffecd](https://github.com/anyup/uView-Pro/commit/45ffecd3522df85cdaaa62ecb9c33d7839443586))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **useChildren:** 修复组件关系工具子组件ID缓存问题，避免同组件多次调用useChildren时重复注册 ([3a8c659](https://github.com/anyup/uView-Pro/commit/3a8c659ce596b483559cf4b061d0b54d784a902b))\n- **u-form:** 修复移除字段时方法不存在的错误 ([58ada99](https://github.com/anyup/uView-Pro/commit/58ada99a8cbd44874eebfd305a4aeb721add8558))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.5.15（2026-03-25）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-form:** 修复表单项底部边框默认值逻辑 ([d939fbd](https://github.com/anyup/uView-Pro/commit/d939fbd5df85c266f8a8f5e23ebeca251eee94ec))\n- **u-input:** 修复u-input输入框在某些微信小程序平台下，重新获取焦点时会清空输入框的问题 ([cedecfa](https://github.com/anyup/uView-Pro/commit/cedecfa4bf2142046bb512b1d9e87f6c9d77516d))\n- **demo:** 优化微信小程序首页u-sticky使用配置 ([cc4e9ac](https://github.com/anyup/uView-Pro/commit/cc4e9ac9f022e7713b2eb2746038a8481729c0b4))\n\n### ✨ Features | 新功能\n\n- **types:** 添加昵称输入类型支持 ([bd15170](https://github.com/anyup/uView-Pro/commit/bd15170d0ccc76098debb9e37b4acfbe43fef043))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/xaunseus\"><img src=\"https://github.com/xaunseus.png?size=40\" width=\"40\" height=\"40\" alt=\"xaunseus\" title=\"xaunseus\"/></a> \n\n## 0.5.14（2026-03-23）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-toast:** 调整提示框位置和边框样式 ([093e31a](https://github.com/anyup/uView-Pro/commit/093e31a34a26902ced26ac841ddfa738fa796528))\n- **u-form:** 修复表单项错误消息样式显示问题 ([462eb6e](https://github.com/anyup/uView-Pro/commit/462eb6e9e3b4d676ac97877327d93705f53400a5))\n\n### 📝 Documentation | 文档\n\n- **readme:** 添加快速启动模板链接 ([afce866](https://github.com/anyup/uView-Pro/commit/afce866f0e7e20b97132bebcbaf56f9aafc25c5c))\n\n### ✨ Features | 新功能\n\n- **u-form-item:** 增加前后图标前缀自定义配置和插槽支持 ([9f32cf7](https://github.com/anyup/uView-Pro/commit/9f32cf7f32e0697ab6771711bc96bc2d8395c597))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.5.13（2026-03-17）\n\n### ✨ Features | 新功能\n\n- **u-tabs:** tabs标签组件添加徽标圆点配置功能 ([4c9fe9b](https://github.com/anyup/uView-Pro/commit/4c9fe9b36ee9f04721f53e177bea08407c5e6d11))\n- **u-input:** 优化输入框清除图标显示控制逻辑（#141） ([e08bc10](https://github.com/anyup/uView-Pro/commit/e08bc10ffe81945b09f1afc50e273588b346c9d8))\n- **u-textarea:** 优化textarea清空按钮显示逻辑（#141） ([feab6cf](https://github.com/anyup/uView-Pro/commit/feab6cf55c17e655b7a89b9f748ef814b5ff8472))\n- **demo:** 优化微信小程序声明显示条件 ([72a5cd2](https://github.com/anyup/uView-Pro/commit/72a5cd2503bf90e99a9b7379703e7dce284896cc))\n- **toast:** 调整toast组件配置并添加回调功能 ([e9f697f](https://github.com/anyup/uView-Pro/commit/e9f697f58c6cc207bc4df3c16203565762cb860e))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.5.12（2026-03-09）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-tabs:** 延迟初始化tabs组件以确保正确获取尺寸信息，修复在App端滑块偏移问题（#139） ([90f79ff](https://github.com/anyup/uView-Pro/commit/90f79ff8f1e71a2ebc05be7d0318b8107425e09a))\n- **u-upload:** 优化u-upload组件在暗黑模式下的显示效果 ([24955ad](https://github.com/anyup/uView-Pro/commit/24955ad947d6edc736c695f9052344a83fa191ae))\n- **u-calendar:** 优化日历组件设置为range范围选择时，仅当开始、结束时间选择完成时才可点击确定（#136） ([4dee864](https://github.com/anyup/uView-Pro/commit/4dee864abda5e65a755aaaccbaffc430ca463cdd))\n\n### ✨ Features | 新功能\n\n- **demo:** 添加H5平台条件编译控制，优化组件描述文案 ([d482223](https://github.com/anyup/uView-Pro/commit/d4822234e1f0e13a6480732350f884d5034368b5))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.5.11（2026-03-02）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-table:** 修复table文字换行后导致的行高度不一致，边框线错位的问题 ([b6b9c33](https://github.com/anyup/uView-Pro/commit/b6b9c33d41ac3adc6f6a1eb33edd50a355d267bf))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.5.10（2026-02-28）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **useToast:** 修复useToast使用全局弹出时，某场景下弹出失败的问题 ([83b3d7b](https://github.com/anyup/uView-Pro/commit/83b3d7b64995a1801fdf6a33ff2ce0c99ecceaa6))\n- **useModal:** 修复useModal使用全局弹出时，某场景下弹出失败的问题 ([43f98ea](https://github.com/anyup/uView-Pro/commit/43f98ea4adda12e28cd1d906c36279f808b3ea32))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.5.9（2026-02-26）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **calendar:** minDate / maxDate 纳入校验年月范围 ([249c04f](https://github.com/anyup/uView-Pro/commit/249c04f11e8610df4964f2d24d5fbe580e9236f8))\n\n### ✨ Features | 新功能\n\n- **calendar:** 日历选择演示页面新增最小/最大日期切换功能 ([dc8aeae](https://github.com/anyup/uView-Pro/commit/dc8aeae5072774d3d1be1318e4f7b4567c9b0385))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/zakicheung\"><img src=\"https://github.com/zakicheung.png?size=40\" width=\"40\" height=\"40\" alt=\"张淇\" title=\"张淇\"/></a> <a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.5.8（2026-02-10）\n\n### 🚀 Chore | 构建/工程依赖/工具\n\n- **deps:** 更新 uni-app 相关依赖包版本到 4.87，修复更新包后运行到 h5 报错问题 ([b00751b](https://github.com/anyup/uView-Pro/commit/b00751b2643bd582f2d1b9472e245d856352d4ed))\n\n### 📝 Documentation | 文档\n\n- 添加npm下载量统计徽章 ([63971ee](https://github.com/anyup/uView-Pro/commit/63971eead3365d5efe29166b2252e58904c0306c))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **useToast:** 修复使用useToast全局提示会触发多次监听的问题（#130） ([ae56413](https://github.com/anyup/uView-Pro/commit/ae564132604d27c3d92de2f6ece5eaae75980aaa))\n- **useModal:** 修复使用useModal全局弹窗会触发多次监听的问题（#130） ([50da10c](https://github.com/anyup/uView-Pro/commit/50da10c7c19d65885244df5c99634775be088824))\n- **u-upload:** 修复u-upload组件中删除确认弹窗的“取消”和“确认”按钮国际化问题（#128） ([e48ab1d](https://github.com/anyup/uView-Pro/commit/e48ab1d23f50c850b1fd85c9b48860bd1d5105b0))\n\n### ✨ Features | 新功能\n\n- **useToast:** 支持使用useToast页面级弹出时，toast可指定页面ID（#130） ([7d09ffe](https://github.com/anyup/uView-Pro/commit/7d09ffe5f8bbee5a3872dfc716dc7ba013f7e1bc))\n- **useModal:** 支持使用useModal页面级弹出时，modal可指定页面ID（#130） ([63af409](https://github.com/anyup/uView-Pro/commit/63af409370f775bac7ceabe98db8b5225491baa8))\n- **u-button:** 添加按钮文本属性支持 ([72fda47](https://github.com/anyup/uView-Pro/commit/72fda47673f1b099f12dcd88ca20570d20d3d5bc))\n- **router:** 添加路由跳转hooks功能 ([cb5a687](https://github.com/anyup/uView-Pro/commit/cb5a687bd7ec8c863d237f69b5cb486e86016398))\n- **demo:** 添加useModal和useToast示例页面 ([f42ca51](https://github.com/anyup/uView-Pro/commit/f42ca51839b1ebd3f02106da0310f4bbbfbb96cf))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.5.7（2026-02-06）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-tabs:** 修复u-tabs的scroll-view在不同平台会显示滚动条的问题，统一各平台的滚动条隐藏逻辑 ([6ba904b](https://github.com/anyup/uView-Pro/commit/6ba904b85fdc5be69ab8b430878e16fa74674c64))\n- **demo:** 修复演示项目在钉钉小程序调用uni.setTabBarItem报错问题（#125） ([fd4ea39](https://github.com/anyup/uView-Pro/commit/fd4ea3987928039e9dcc3a53dc8bea42fce2b685))\n- **u-input,u-field:** 修复输入框绑定值为undefined和null时的显示异常问题 ([4af659f](https://github.com/anyup/uView-Pro/commit/4af659fb365179e3ed7db26a1d8571c327497f7a))\n\n### ✨ Features | 新功能\n\n- **demo-page:** 所有页面支持小程序分享功能 ([a055904](https://github.com/anyup/uView-Pro/commit/a05590443e898ed076d47a04cb8bfc74c2e73da8))\n- **u-card:** u-card添加圆角配置功能并调整默认边框样式 ([e43c939](https://github.com/anyup/uView-Pro/commit/e43c9396a17fe485305e63895a7ea8d6edf1906b))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.5.6（2026-02-04）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **vue-tsc:** 修复部分定时器ts类型定义错误问题（#124） ([dada764](https://github.com/anyup/uView-Pro/commit/dada764eaa6ea73402e8fa6d96a783ae2a68715a))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.5.5（2026-02-02）\n\n### ✨ Features | 新功能\n\n- **u-toast:** 新增页面级toast功能并优化loading逻辑 ([4eae5b7](https://github.com/anyup/uView-Pro/commit/4eae5b7ef5d4494c4619bee383e62490994b4317))\n- **useModal:** 新增useModal函数式调用API和全局modal功能（#101） ([724edf3](https://github.com/anyup/uView-Pro/commit/724edf3cd69607a6d4e33954f8d2d701f9502ff3))\n- **locale:** 新增语言配置的标签字段label和区域设置字段locale ([49ba6cb](https://github.com/anyup/uView-Pro/commit/49ba6cbea6b53712496e465dd40654af7608a02d))\n\n### ♻️ Code Refactoring | 代码重构\n\n- **demo:** 调整demo演示中吸顶组件默认偏移量为200 ([165da80](https://github.com/anyup/uView-Pro/commit/165da80eb9eec54cf1a5fa8511d82e2b3d11fed1))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.5.4（2026-01-30）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **types:** 优化组件库类型定义和代码健壮性 ([e83eac8](https://github.com/anyup/uView-Pro/commit/e83eac8192476dea5e2d4e5b8b3c68b7da992673))\n- **u-navbar:** 修复状态栏高度获取的条件判断，区分鸿蒙、微信小程序和其他 ([b13d112](https://github.com/anyup/uView-Pro/commit/b13d112be80c46f62bfa343a089f2de70a00f774))\n\n### ✨ Features | 新功能\n\n- **u-loading:** 增强u-loading的自定义样式功能 ([c9151ce](https://github.com/anyup/uView-Pro/commit/c9151ce4bee44c762bd7970ab280184c730e97b1))\n- **u-toast:** 新增函数式调用API和全局toast功能（#101） ([b8c8fbf](https://github.com/anyup/uView-Pro/commit/b8c8fbff70c14fe0a6106794a638e450cecbeddf))\n- **components:** 优化组件类型安全 ([02b638f](https://github.com/anyup/uView-Pro/commit/02b638f6e251c9b52e5e3ebb1e40d644d895308a))\n\n### ♻️ Code Refactoring | 代码重构\n\n- **demo:** 移除多余的toast引用 ([67b2677](https://github.com/anyup/uView-Pro/commit/67b26772eb67e9e2b830c95359688b0116395452))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.5.3（2026-01-26）\n\n### ♻️ Code Refactoring | 代码重构\n\n- **demo-page:** 移除标签栏外层sticky组件 ([ed49275](https://github.com/anyup/uView-Pro/commit/ed49275bc2962426dc4f9185b4b35f6a994cf383))\n\n### 👷 Continuous Integration | CI 配置\n\n- 添加 npm 包测试脚本 ([78c5524](https://github.com/anyup/uView-Pro/commit/78c5524abbbc368949ec58437361c995f5146234))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **locale:** 修复本地运行时locale国际化字段未加载成功的问题 ([10c017a](https://github.com/anyup/uView-Pro/commit/10c017a401232224ca1642274d65f031f74f12f0))\n- **u-picker:** 修复u-picker/u-select选择器在亮色/暗黑模式下背景色显示问题 ([072a6cc](https://github.com/anyup/uView-Pro/commit/072a6cc1095b5f17b0c15c3cd2a3d6a75d8a9f08))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.5.2（2026-01-23）\n\n### ✨ Features | 新功能\n\n- **u-checkbox-group:** 重构u-checkbox多选框组件，group支持v-model双向绑定，标准化使用api ([e4a12f1](https://github.com/anyup/uView-Pro/commit/e4a12f1af6a4d8cae18823b42a918052df36b62d))\n- **hooks:** 新增防抖和节流hook ([4b09373](https://github.com/anyup/uView-Pro/commit/4b09373c31dc3ab7ded01c6ea0cfdf902642b857))\n- **u-search:** 新增adjust-position属性控制键盘弹出时的高度调节 ([3443e7c](https://github.com/anyup/uView-Pro/commit/3443e7cc0d754c10df03134e8bc2c6c977758610))\n- **u-tabbar:** 调整u-tabbar凸起图标上边距以优化显示效果 ([d0963be](https://github.com/anyup/uView-Pro/commit/d0963be197079733779719aae43694ae5b47e6bc))\n- **u-transition:** 新增transition过渡动画组件 ([28ee2c8](https://github.com/anyup/uView-Pro/commit/28ee2c8b0f74bae722f0fe50e498e3407907d2f6))\n- **u-transition:** 添加动画模式切换时的时序控制 ([af4bf0a](https://github.com/anyup/uView-Pro/commit/af4bf0a690128ba16e7660d2ae54c5b93644cfdf))\n- **u-text:** 优化按钮模式在block模式下的样式 ([afda81d](https://github.com/anyup/uView-Pro/commit/afda81d0c8fa7b628b81f8368e6bd2983779b7c9))\n- **u-radio:** 添加label和value属性支持 ([1b824d7](https://github.com/anyup/uView-Pro/commit/1b824d7867dc7fcc3793d7b5d84cbbbcb512dab0))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-checkbox-group:** 修复全选时，u-checkbox-group多次触发change的问题 ([9f813df](https://github.com/anyup/uView-Pro/commit/9f813dfb8a2b8e178b7347223281e09b039f74b0))\n- **u-gap:** 修复 gap 间隔槽传递带单位尺寸无法正确解析的问题 ([cc24efd](https://github.com/anyup/uView-Pro/commit/cc24efd658e510fb9655a189ceaee2647db81528))\n- **u-alert-tips:** 修复微信小程序下组件样式和图标配置不生效的问题 ([d74900e](https://github.com/anyup/uView-Pro/commit/d74900e9e8a61a68b8971abc81e440e8449d3576))\n- **u-navbar:** 修复获取状态栏高度在某些平台失败的问题 ([b8b288e](https://github.com/anyup/uView-Pro/commit/b8b288e33348b78e03be349c6c123e36511342af))\n- **u-toast:** 修复toast提示组件设置prop无效的问题 ([ecd3a0a](https://github.com/anyup/uView-Pro/commit/ecd3a0a23a0ca039fa0abe3a946bfdf1024dd10a))\n- **locale:** 修复注册uview-pro组件库时，未传递locale导致初始化语言包失败的问题 ([d716100](https://github.com/anyup/uView-Pro/commit/d7161000fe9e3d222453603d8fa31d29a1b9a9bb))\n- **u-field:** 修复u-field在禁用状态下，点击输入框无法触发click事件的问题 ([f47761d](https://github.com/anyup/uView-Pro/commit/f47761d00fe2913f0e611577651a3f4108e060b6))\n\n### ♻️ Code Refactoring | 代码重构\n\n- **demo:** 重构u-checkbox复选框演示示例 ([77fc19b](https://github.com/anyup/uView-Pro/commit/77fc19b6f23f8d776b7a56ef9ac27726da7405a1))\n- **demo:** 同步鸿蒙应用功能 ([2ac7050](https://github.com/anyup/uView-Pro/commit/2ac70500004e04bd22442d696e3e869ba33ac355))\n- update release scripts ([818f8b9](https://github.com/anyup/uView-Pro/commit/818f8b9cf6a0a22893305f76e4af2b71409cbc12))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.5.1（2026-01-15）\n\n### ✨ Features | 新功能\n\n- **locale:** 统一组件国际化命名空间，以保持命名的一致性并避免与自定义字段时冲突 ([8bd3cc3](https://github.com/anyup/uView-Pro/commit/8bd3cc32b26349da63f5005cb3c29e575c831142))\n- **u-form:** 支持label插槽功能 ([f82994f](https://github.com/anyup/uView-Pro/commit/f82994f5500ec4509dff64c05e115afb0465d4a2))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.5.0（2026-01-14）\n\n### ✨ Features | 新功能\n\n- **locale:** 添加组件国际化支持和 use locale hooks ([ff96211](https://github.com/anyup/uView-Pro/commit/ff96211423d27bde350a2ea4b9f1d5a5eb72d604))\n- **locale:** 添加中、英文国际化语言字段支持 ([257eb41](https://github.com/anyup/uView-Pro/commit/257eb4143ac39cab4940ab76844d0c3be02b198c))\n- **locale:** 所有组件实现组件国际化显示替换 ([ef52ff7](https://github.com/anyup/uView-Pro/commit/ef52ff7669c8cb7389377b8bdd4da681dddbb0a6))\n- **locale:** 跟随vue-i18n国际化语言切换功能 ([cccecb0](https://github.com/anyup/uView-Pro/commit/cccecb03763990689e6e66d856cf3588157a61b6))\n- **fullScreen:** 优化fullscreen页面配置和实现，支持国际化 ([8518218](https://github.com/anyup/uView-Pro/commit/85182186848fa6443ed74de9af1e3f5cd15fa724))\n- **locale:** 新增locale国际化和vue-i18n切换示例页面 ([da79723](https://github.com/anyup/uView-Pro/commit/da797230005ff130ea66c315921e4d8d9fa613c1))\n- **demo-page:** 添加支付宝小程序navbar兼容性处理 ([75284a4](https://github.com/anyup/uView-Pro/commit/75284a403b9eb7dee9625279ca5cadd14bba3a63))\n- **u-skeleton:** 重构u-skeleton骨架屏组件实现全新设计 ([c39405d](https://github.com/anyup/uView-Pro/commit/c39405dfd8c4e1fe06fd842efde79ebf6706b0d1))\n- **u-tabbar:** 重构u-tabbar组件内部结构，增加图标文字间距配置 ([e5655da](https://github.com/anyup/uView-Pro/commit/e5655da55c515a8288b12e37084dfec093da542b))\n- **mp-weixin:** 添加小程序全局分享功能 ([e4f8bf5](https://github.com/anyup/uView-Pro/commit/e4f8bf5baae237e8dc443de7c90cd751ef045101))\n- **useLocale:** uselocale hooks 支持命名空间功能 ([4d6e8f2](https://github.com/anyup/uView-Pro/commit/4d6e8f26976725cfdf862bd21af3648b864fdc29))\n- **u-tabbar:** 优化u-tabbar文本样式渲染优先级 ([7d73861](https://github.com/anyup/uView-Pro/commit/7d73861b4cbe1266bc4cbfff31b45a57d9ed960f))\n- **locale:** 初始化多语言时添加 isForce 参数支持强制设置默认语言 ([3309017](https://github.com/anyup/uView-Pro/commit/3309017e6fea3bc00f10efcec9f3ec3f83de9a88))\n- **demo:** 优化国际化配置示例并添加多语言支持 ([177b978](https://github.com/anyup/uView-Pro/commit/177b97869f14023daf4bca632093076716b616d6))\n- **theme:** 主题配置支持强制初始化功能 ([95c895d](https://github.com/anyup/uView-Pro/commit/95c895d0cfb1df37aa6285b88a2247f83add7361))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.4.13（2026-01-06）\n\n### ✨ Features | 新功能\n\n- **theme:** 主题初始化时支持默认主题设置 ([f2b61f6](https://github.com/anyup/uView-Pro/commit/f2b61f6caa1c285753b2e02f97309aa55bb77cca))\n- **theme:** 增强主题系统初始化配置，支持在初始化时设置默认主题和暗黑模式 ([d228d10](https://github.com/anyup/uView-Pro/commit/d228d100baf619799b1dc1c8e289e1e8c9a30699))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-number-box:** 修复 u-number-box 步进器 disabled 时字体不显示问题 ([75b3a74](https://github.com/anyup/uView-Pro/commit/75b3a74e6e763dec1a1ee0d3b4d0a62d646ee389))\n- **u-textarea:** 修复u-textarea组件设置props.border='none'无效的问题 ([c5a97ba](https://github.com/anyup/uView-Pro/commit/c5a97ba4c00d226c8c0fd9605660d2654dec9dc2))\n\n### ♻️ Code Refactoring | 代码重构\n\n- **theme:** 调整u-bg-gray-light默认色值，优化演示示例 ([37d6bda](https://github.com/anyup/uView-Pro/commit/37d6bda939f5d7c54aec09960878f236dfa32bb2))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.4.12（2026-01-04）\n\n### ♻️ Code Refactoring | 代码重构\n\n- **u-action-sheet:** 优化u-action-sheet组件的类型定义 ([bc5e474](https://github.com/anyup/uView-Pro/commit/bc5e474e7117e20495504ff0e2397a147595033c))\n- **zIndex:** 统一组件z-index值配置 ([ae1da98](https://github.com/anyup/uView-Pro/commit/ae1da986d307e5b4855fa32e5b2995fdb7be69e8))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **form:** 修复field实例销毁时没有正常移除问题 ([57bfd3b](https://github.com/anyup/uView-Pro/commit/57bfd3bf9315d74c416869cd5a8c41562231166a))\n\n### ✨ Features | 新功能\n\n- **u-tabbar:** 新增z-index属性支持自定义层级 ([c75d45f](https://github.com/anyup/uView-Pro/commit/c75d45f45e237453d0248124cdbe5bb797edb117))\n- **u-modal:** 增加u-modal基础属性支持和自定义样式功能 ([201231e](https://github.com/anyup/uView-Pro/commit/201231ee2e0c25c605f12f582650b048e83213de))\n- **components:** 增加u-pagination和u-picker自定义样式支持 ([eb22265](https://github.com/anyup/uView-Pro/commit/eb222657540179fcf8359133df83da89c10b09b8))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/yoshinosk\"><img src=\"https://github.com/yoshinosk.png?size=40\" width=\"40\" height=\"40\" alt=\"yoshinosk\" title=\"yoshinosk\"/></a> <a href=\"https://github.com/liujiayii\"><img src=\"https://github.com/liujiayii.png?size=40\" width=\"40\" height=\"40\" alt=\"liujiayii\" title=\"liujiayii\"/></a> \n\n## 0.4.11（2025-12-30）\n\n### 📦‍ Build System | 打包构建\n\n- 添加edgeone.json配置 ([ed7ba7d](https://github.com/anyup/uView-Pro/commit/ed7ba7d94dbfa791264a624a03938dc6ac58c0bb))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **theme:** 修复运行时设置 color 与 theme 主题色不同步问题 ([1dcf56a](https://github.com/anyup/uView-Pro/commit/1dcf56a232f5b046e0dce5eb58ec90fb46ce19d5))\n- **u-top-tips:** 修复顶部提示组件zindex显示问题，避免影响其他组件的层级显示 ([91391a8](https://github.com/anyup/uView-Pro/commit/91391a8ca10d505936c0b45488af0a3145cab335))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.4.10（2025-12-26）\n\n### 🚀 Chore | 构建/工程依赖/工具\n\n- **contributors:** 更新贡献者映射配置 ([d496b21](https://github.com/anyup/uView-Pro/commit/d496b21d85bede68fefc9ffd752e31ecde14735a))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-popup:** 修复u-popup设置mode=center，点击遮罩层无法关闭的问题 ([3896019](https://github.com/anyup/uView-Pro/commit/389601965933d9e1dc74d32c370c4e858df86595))\n- **u-upload:** 优化u-upload组件在多个平台的样式兼容性 ([bfb60b5](https://github.com/anyup/uView-Pro/commit/bfb60b5c2f431d14425eceed9c9e5c248e7cfa29))\n\n### ✨ Features | 新功能\n\n- **u-tabbar:** 增强u-tabbar组件能力，支持文字和图标显示隐藏配置功能 ([29f3394](https://github.com/anyup/uView-Pro/commit/29f3394d7e8a5e2a818e397ffe97420855970333))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.4.9（2025-12-24）\n\n### 📝 Documentation | 文档\n\n- **readme:** 修复捐赠页面链接 ([93323ab](https://github.com/anyup/uView-Pro/commit/93323ab414ddc5a4542604928f221a050cbe55c5))\n\n### ✨ Features | 新功能\n\n- **request:** 增强http请求工具，添加请求超时配置和全局配置合并功能 ([54d4a44](https://github.com/anyup/uView-Pro/commit/54d4a448a82d76889524cc2ad0f8f08b758b73fb))\n- **http:** 修改http请求实例和响应拦截器 ([d566496](https://github.com/anyup/uView-Pro/commit/d56649673103b519492033504aa387cd6d037721))\n- **source:** 添加静态资源文件 ([346bce6](https://github.com/anyup/uView-Pro/commit/346bce63126c4cb2c9db1f1665568eb11e26be07))\n- **pages:** 优化多个页面演示样式，统一布局和暗黑模式 ([da68f17](https://github.com/anyup/uView-Pro/commit/da68f17ddf3018f7f5d53a7eebfb3dc1bad550ab))\n- **i18n:** 完善国际化支持文案 ([68accbd](https://github.com/anyup/uView-Pro/commit/68accbd1d864f190e510de380d4ed8d603f8676b))\n- **pages:** 更新iconfont图标 ([bafd4af](https://github.com/anyup/uView-Pro/commit/bafd4af26f6d2ca4dbe6e818b31be84f57c787b0))\n- **demo-page:** 调整演示页面样式并添加tabbar支持 ([f4c5cfc](https://github.com/anyup/uView-Pro/commit/f4c5cfc70920b50602f226220ded4690279cb331))\n\n### 🚀 Chore | 构建/工程依赖/工具\n\n- **harmony:** 添加调试配置并调整harmony兼容版本 ([bd18fd2](https://github.com/anyup/uView-Pro/commit/bd18fd234bf0aec9671663f5b26294b4622bae81))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.4.8（2025-12-23）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-avatar:** 修复 ios 微信小程序默认头像不显示问题 ([9e3420f](https://github.com/anyup/uView-Pro/commit/9e3420fb8d0db533ce7fb3a8e83543b43ac0c7a7))\n- 修复 u-cell 组件中使用 u-icon 样式在微信小程序不生效问题，修复 u-upload 图片上传失败重试是否显示提示配置不生效问题 ([e591d62](https://github.com/anyup/uView-Pro/commit/e591d62befce95c207ca47158549e6fd97f1e58d))\n- **u-cell-item:** 修复图标样式问题并优化组件结构 ([294bf4b](https://github.com/anyup/uView-Pro/commit/294bf4be88fb53a2ccd72fcc8702b09f6d736a30))\n\n### ♻️ Code Refactoring | 代码重构\n\n- **theme:** 修改主题默认为官方内置主题，暗黑模式默认为亮色 ([176b482](https://github.com/anyup/uView-Pro/commit/176b48210209ae362fe30e459e73dff6fc81b53e))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/limes-cloud\"><img src=\"https://github.com/limes-cloud.png?size=40\" width=\"40\" height=\"40\" alt=\"limes-cloud\" title=\"limes-cloud\"/></a> \n\n## 0.4.7（2025-12-19）\n\n### 🚀 Chore | 构建/工程依赖/工具\n\n- 忽略部分文件 ([a8a747f](https://github.com/anyup/uView-Pro/commit/a8a747f97e93ed278a305cd1b2671d2ede5c0fde))\n\n### ✨ Features | 新功能\n\n- **u-tabbar:** u-tabbar 组件支持 custom-icon 直接配置图标 custom-prefix ([e577c2d](https://github.com/anyup/uView-Pro/commit/e577c2d083cf46db7124b0df46b2848ef9bdbe80))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-icon:** 修复图标组件样式和事件处理问题 ([1cadf27](https://github.com/anyup/uView-Pro/commit/1cadf27f8bd2aec3a11fb1befb9255256a2e3b3a))\n- **u-pagination:** 修复分页切换时传递不正确的当前页码值 ([4befe02](https://github.com/anyup/uView-Pro/commit/4befe02c5cbb4e7db6fbf49f04ca68fac0f69a37))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.4.6（2025-12-17）\n\n### 📝 Documentation | 文档\n\n- 添加鸿蒙系统预览说明及二维码 ([7f6199a](https://github.com/anyup/uView-Pro/commit/7f6199a30d5477743c20b27a94711b4605787757))\n\n### ✨ Features | 新功能\n\n- **u-slider:** 增强滑块组件功能与灵活性，支持设置滑块的整体范围起点(start)和终点(end) ([a20c44b](https://github.com/anyup/uView-Pro/commit/a20c44b0270cffde02afd8738a932b2d6bae49f4))\n- **button:** 新增按钮禁用与自定义样式功能演示 ([5f1f482](https://github.com/anyup/uView-Pro/commit/5f1f4823e027dc5ab2e6f49f29fe327c6d4318c6))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **button:** 更新禁用状态下按钮样式优先级 ([b3ff20b](https://github.com/anyup/uView-Pro/commit/b3ff20b59818c8bc8204bb2a489eff42ded7e842))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.4.5（2025-12-10）\n\n### ✨ Features | 新功能\n\n- **u-input:** 为选择类型输入框添加覆盖层以增强交互 ([9b7bac2](https://github.com/anyup/uView-Pro/commit/9b7bac221195d010c31b15915d2927d095bd257f))\n- **u-form:** 增强 u-form 深层校验、动态校验表单 ([97d0ccb](https://github.com/anyup/uView-Pro/commit/97d0ccbe03391f63bed81dcfd1af1432f4f7c77d))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-input:** 修复清空图标点击事件冒泡问题 ([8a214ff](https://github.com/anyup/uView-Pro/commit/8a214ffe8e5588395cdc456e600bc8dd0f03a603))\n- **style:** 修复除H5环境外主题样式作用域问题 ([c02ba3c](https://github.com/anyup/uView-Pro/commit/c02ba3c1454e709b1fa9de817d77b0f2128b5fc0))\n- **u-switch:** 修复开关组件激活颜色默认值的响应式问题 ([3d78647](https://github.com/anyup/uView-Pro/commit/3d78647d75c3201cced2643395ff5dd935d0e7ec))\n- **form:** 修复 form 校验报错问题 ([8d6d60d](https://github.com/anyup/uView-Pro/commit/8d6d60d4af4e5653f7b87afc3f208d0e26809505))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/yoshinosk\"><img src=\"https://github.com/yoshinosk.png?size=40\" width=\"40\" height=\"40\" alt=\"yoshinosk\" title=\"yoshinosk\"/></a> \n\n## 0.4.4（2025-12-08）\n\n### ✨ Features | 新功能\n\n- **u-card:** u-card 组件的默认插槽同 body 插槽 ([ffa13ed](https://github.com/anyup/uView-Pro/commit/ffa13edcf17ff1559e8bdf2260f6b146680f9d07))\n- **u-tag:** 优化自定义样式 custom-style 应用，支持 text 插槽内容 ([5bdb733](https://github.com/anyup/uView-Pro/commit/5bdb73346252850d74165cda0bb00766e5f6f59f))\n- **u-line-progress:** 优化u-line-progress进度条百分比显示方式 ([1c1d979](https://github.com/anyup/uView-Pro/commit/1c1d97958f3c7e5a28943b46ea25d38b50449364))\n- **switch:** 增强开关组件支持自定义值类型 ([2bcb136](https://github.com/anyup/uView-Pro/commit/2bcb1368aa1f3c7fe83799e909b89fc4349b30c3))\n\n### 📝 Documentation | 文档\n\n- 优化 Markdown 文档样式和格式 ([c80ff6d](https://github.com/anyup/uView-Pro/commit/c80ff6df269eb92a88001373aa96344ff4cafb79))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/liujiayii\"><img src=\"https://github.com/liujiayii.png?size=40\" width=\"40\" height=\"40\" alt=\"liujiayii\" title=\"liujiayii\"/></a> \n\n## 0.4.3（2025-12-03）\n\n### 📝 Documentation | 文档\n\n- 更新项目描述和移除冗余信息 ([3d5c105](https://github.com/anyup/uView-Pro/commit/3d5c1053873a1a1dc592e02caf62b5e5f9aba3ad))\n- **readme:** 更新交流反馈和捐赠链接 ([266e788](https://github.com/anyup/uView-Pro/commit/266e7883a4e2f3ea8058e0bba0b7ce07a972bad8))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **theme:** 修复不使用 u-config-privider 全局注入时，部分颜色变量不存在的问题 ([cd82d9d](https://github.com/anyup/uView-Pro/commit/cd82d9da3e8fd6066177e3b78b855583e2756a5f))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.4.2（2025-12-01）\n\n### 📝 Documentation | 文档\n\n- **scripts:** 更新发布指定版本说明文档 ([db6bfe8](https://github.com/anyup/uView-Pro/commit/db6bfe8a7ec2812f34738b5b707240cdfe57e8b3))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **theme:** 修复npm方式加载主题包失效的问题 ([7b9c947](https://github.com/anyup/uView-Pro/commit/7b9c947581697ddbd36632919652689ca8595503))\n- **dark-mode:** 修复 App 平台暗黑模式跟随系统下，切换系统暗黑模式后不即时生效问题 ([880b181](https://github.com/anyup/uView-Pro/commit/880b18153d186f6f5c5f9c81bf12307bd8f00c22))\n- **initTheme:** 优化组件库 install 方法中的主题初始化默认逻辑 ([39e273b](https://github.com/anyup/uView-Pro/commit/39e273b98cd53ec2891c7e68419dd6dfbbeb30c0))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> \n\n## 0.4.1（2025-11-30）\n\n### ✨ Features | 新功能\n\n- **root:** 新增根节点组件支持，优化主题文件 ([12d14f8](https://github.com/anyup/uView-Pro/commit/12d14f8c859bae1e330b246b6eb1f87c2597c2d7))\n- **iconfont:** 新增iconfont实例 ([4d34d25](https://github.com/anyup/uView-Pro/commit/4d34d25f0c124a6622b8b38b7501b85586843a42))\n- **locales:** 新增locales中英文字段 ([2dbad6d](https://github.com/anyup/uView-Pro/commit/2dbad6d38bc5cd2fbe55aa0998d2264782cb4dfe))\n- **markdown-view:** 新增 markdown-view 模块 ([9e21b6a](https://github.com/anyup/uView-Pro/commit/9e21b6af96c17175dd178923ab2f98c595bacb20))\n- **u-config-provider:** 新增 u-config-provider 组件用于全局主题管理 ([f44857c](https://github.com/anyup/uView-Pro/commit/f44857c44f0354b9408bc40c8d586ace1ea40538))\n- **theme:** 实现自定义多主题，主题切换功能 ([9551d26](https://github.com/anyup/uView-Pro/commit/9551d260451d2c21b7fe9dfab4850a57c5601573))\n- **demo:** 新增 demo-page 组件并重构组件演示页面，添加 API 文档展示 ([ecfd77e](https://github.com/anyup/uView-Pro/commit/ecfd77ea3776720e0bbba7f7678896e685adff3a))\n- **demo-page:** 优化代码示例组件文档获取方式 ([50738be](https://github.com/anyup/uView-Pro/commit/50738beafa879e3f95831287a1aa7cb560b59c20))\n- **theme:** 实现暗黑模式并优化多主题管理 ([38f9346](https://github.com/anyup/uView-Pro/commit/38f93464edf7ba3e6a0d28c025e31cfe27a147bb))\n- **u-config-provider:** 完善u-config-provider主题注入和暗黑模式切换 ([726a7f9](https://github.com/anyup/uView-Pro/commit/726a7f96a31c2e6346c9037842963624b22c3f60))\n- **demo:** 优化主题切换示例逻辑和样式 ([d69af6a](https://github.com/anyup/uView-Pro/commit/d69af6a82b639d35ce757abccccb9f8f9aae14a5))\n- **theme:** 优化主题系统，兼容单主题、多主题配置能力 ([d06cd7f](https://github.com/anyup/uView-Pro/commit/d06cd7f592e5ae4f9dae7f0cd90f173f76cc5e62))\n- **theme:** 更新深蓝主题的色彩配置 ([77e8e5c](https://github.com/anyup/uView-Pro/commit/77e8e5c6ca55281253f86dbc5244c807f04324b3))\n- **config-provider:** 增加非 H5 平台系统暗黑模式识别 ([2175dc6](https://github.com/anyup/uView-Pro/commit/2175dc6892f7f559507e19c44638f5c57ac13e4a))\n- **u-button:** 调整u-button按钮节流默认值为0，优化点击逻辑 ([3fa2593](https://github.com/anyup/uView-Pro/commit/3fa2593dba31c05a97e001fda9cd233306f42a9d))\n- **theme:** 优化主题配置中的暗黑模式处理逻辑，按规则自动生成完整暗色方案 ([8246853](https://github.com/anyup/uView-Pro/commit/82468538004c88637b98c9bd2381b0d44aef0d22))\n- **system:** 添加系统主题变更监听 ([9c35243](https://github.com/anyup/uView-Pro/commit/9c3524390847d92c7345e8a27c4603afa8d094f4))\n- **theme:** 多主题配置兼容单主题 ([79d3223](https://github.com/anyup/uView-Pro/commit/79d3223459a306fb4ba320713ed03a4a6579f563))\n- **u-image:** 增强 u-image 组件自定义样式 ([b133c3c](https://github.com/anyup/uView-Pro/commit/b133c3c00f14738eaa0a61eaec19dbe1b5defcfe))\n\n### ♻️ Code Refactoring | 代码重构\n\n- **app:** 添加本地应用资源 ([cd3f020](https://github.com/anyup/uView-Pro/commit/cd3f02074c871772ea0e42fb26336751eeda7c35))\n- **theme:** 重构主题配置和颜色处理逻辑 ([31aa36b](https://github.com/anyup/uView-Pro/commit/31aa36b9207144836be7073a804b8c7ebd68fc6b))\n- **demo:** 修改演示页面功能及样式，调整演示组件整体样式 ([8760b3c](https://github.com/anyup/uView-Pro/commit/8760b3c82ff129bd1695e384abbc762de6c85cd4))\n- **components:** 优化多个组件主题颜色变量使用，兼容多主题和暗黑模式 ([1a2856f](https://github.com/anyup/uView-Pro/commit/1a2856fc98ec3169d29330f9b7470e936d4aa334))\n- **demo:** 优化演示示例 Demo 的功能 ([445878b](https://github.com/anyup/uView-Pro/commit/445878b906475f5dd3bcc9b15efd9aac597f0603))\n- **demo-page:** 优化demo page展示，主题切换逻辑优化 ([c5ecbaa](https://github.com/anyup/uView-Pro/commit/c5ecbaa437e51cf1bf47f84f0f3bc071f37dd413))\n- 更新自定义主题文件 ([cab8be3](https://github.com/anyup/uView-Pro/commit/cab8be38832bca9de1254a06f199e6b3704ee88e))\n- **color:** 重构颜色组件以提升可维护性 ([d92a052](https://github.com/anyup/uView-Pro/commit/d92a0526f7bfa51eeb40bb90eb0e7fc8f24fe488))\n\n### ⚡ Performance Improvements | 性能优化\n\n- 优化微信小程序代码包体积 ([bf56c99](https://github.com/anyup/uView-Pro/commit/bf56c99515e41d067481cd6498187ed5bd37c193))\n\n### 💄 Styles | 风格\n\n- **demo:** 优化演示页面样式 ([ae5de09](https://github.com/anyup/uView-Pro/commit/ae5de091ee1234b4432eb7d2609f77fd5afd27aa))\n- **components:** 使用变量替代硬编码的颜色值 ([cf0044e](https://github.com/anyup/uView-Pro/commit/cf0044e3be68daff91b764eb31a75cf3ecad86aa))\n- **demo:** 优化替代组件颜色硬编码值，保证主题色和暗黑模式 ([291e92b](https://github.com/anyup/uView-Pro/commit/291e92b07d80532b1620f62ae0ac3f4909bdab6a))\n\n### 📦‍ Build System | 打包构建\n\n- 新增颜色替换脚本 ([b160c28](https://github.com/anyup/uView-Pro/commit/b160c28e838a4f27b9bfa2f3ce47e8ad46e807a0))\n- 指定 Node.js 版本 ([7147284](https://github.com/anyup/uView-Pro/commit/714728421527bbd5abed02fe4fdf51cdf3c2a583))\n- **deps:** 更新 dcloudio uni-app 依赖版本至 4.76 ([f92a348](https://github.com/anyup/uView-Pro/commit/f92a34892369facda3d89add34cfbeddc1872a65))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-tabbar:** 修复 u-tabbar 在鸿蒙应用上高度计算错误的问题 ([cc4bc1a](https://github.com/anyup/uView-Pro/commit/cc4bc1add7ef63f6d9eb519e9ee38414ef3c73eb))\n- **clipboard:** 处理未传入可选参数引起的错误 ([1756b53](https://github.com/anyup/uView-Pro/commit/1756b53f8ce2e2a21d288124c257b4729e48d92a))\n- **theme:** 修复获取系统设置的theme不正确的问题 ([58b0cbb](https://github.com/anyup/uView-Pro/commit/58b0cbb3aa666d8f127bc88850b66d469cc1b996))\n- **install:** 优化 install 方法的错误处理和代码结构 ([7edb867](https://github.com/anyup/uView-Pro/commit/7edb8673b0cdf4238c184a480b91fb73908e6c5c))\n\n### 👷 Continuous Integration | CI 配置\n\n- **release:** 支持直接指定版本号发布 ([e4db5f8](https://github.com/anyup/uView-Pro/commit/e4db5f8b349954548ddef37fc02aa5a397cace01))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/lonelyflyer\"><img src=\"https://github.com/lonelyflyer.png?size=40\" width=\"40\" height=\"40\" alt=\"Lonelyflyer\" title=\"Lonelyflyer\"/></a> \n\n## 0.3.16（2025-11-21）\n\n### 📝 Documentation | 文档\n\n- 更新贡献者信息 ([a6d52dc](https://github.com/anyup/uView-Pro/commit/a6d52dc6db9d56ccdf5c5ad4230e32c716e36241))\n\n### ♻️ Code Refactoring | 代码重构\n\n- **u-waterfall:** 优化瀑布流组件性能和代码结构 ([841c465](https://github.com/anyup/uView-Pro/commit/841c465de4f1a1efc43e05248794b566e0051bd8))\n- **pages:** 重构工具和模板页面，优化i18n国际化功能 ([6cfda7f](https://github.com/anyup/uView-Pro/commit/6cfda7f2ecfd6dd60501201d8797fe702b29df4d))\n- **u-dropdown:** 删除无用的测试代码 ([7c06f1f](https://github.com/anyup/uView-Pro/commit/7c06f1f3f0d1dcd5ae2bbd3420a4124c5faec004))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **backTop:** 修复回到顶部组件示例无效的问题 ([5a9b736](https://github.com/anyup/uView-Pro/commit/5a9b7366f5916627815488039327669f424dd0ce))\n- **u-text:** 修复 u-text 组件单行省略号显示无效的问题 ([041ee36](https://github.com/anyup/uView-Pro/commit/041ee36fb60d5a082fbdde7e9334ae42b386944c))\n\n### ✨ Features | 新功能\n\n- **u-link:** 添加自定义点击跳转功能 ([8a521f3](https://github.com/anyup/uView-Pro/commit/8a521f36a9f417aa90263cdcf7978ce48d6ed01e))\n- **u-tabs:** 增强 u-tabs 组件，支持隐藏 tab 项的功能配置 ([9a58964](https://github.com/anyup/uView-Pro/commit/9a58964061a7d18510624fb4c6d009568bd3974c))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\n\n## 0.3.15（2025-11-14）\n\n### ✨ Features | 新功能\n\n- **u-dropdown:** u-dropdown中的u-dropdown-item中新增控制显示隐藏属性 ([e4ee28f](https://github.com/anyup/uView-Pro/commit/e4ee28fd0a66ceb6bbed07b7969862e936e5e573))\n- **u-form:** 支持嵌套属性验证(a.b.c格式) ([1bbead8](https://github.com/anyup/uView-Pro/commit/1bbead8be764491844a7d3909480a360ff2dc4d4))\n- **form:** 添加表单字段的嵌套校验演示示例 ([73b4abe](https://github.com/anyup/uView-Pro/commit/73b4abe98047ac5193b56b71cdacb05957760e93))\n\n### 🚀 Chore | 构建/工程依赖/工具\n\n- 更新应用 logo 和图标 ([38d52e4](https://github.com/anyup/uView-Pro/commit/38d52e4a9e8656bcae89892a5f94a5201a1af7b2))\n\n### ♻️ Code Refactoring | 代码重构\n\n- 更新 logo 图片地址 ([c0fe3d1](https://github.com/anyup/uView-Pro/commit/c0fe3d15d6f4498229feaba860ff78e43a5297e6))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/zuo-wentao\"><img src=\"https://github.com/zuo-wentao.png?size=40\" width=\"40\" height=\"40\" alt=\"zuo-wentao\" title=\"zuo-wentao\"/></a> <a href=\"https://github.com/elkelkelkelkelk\"><img src=\"https://github.com/elkelkelkelkelk.png?size=40\" width=\"40\" height=\"40\" alt=\"elkelkelkelkelk\" title=\"elkelkelkelkelk\"/></a> <a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\n\n## 0.3.14（2025-11-14）\n\n### ✨ Features | 新功能\n\n- **app-harmony:** 更新应用信息并添加鸿蒙签名配置，鸿蒙应用打包差异性编译 ([81a33c1](https://github.com/anyup/uView-Pro/commit/81a33c13a471721848033cc5f7ac1e3b3b30abc6))\n- **u-message-input:** 新增输入框类型prop，支持number，text等模式 ([68a865a](https://github.com/anyup/uView-Pro/commit/68a865a12b7e0b20db458ea403579d28a227aaeb))\n\n### ♻️ Code Refactoring | 代码重构\n\n- **components:** 优化 u-icon 和 u-toast 组件样式和结构 ([3cfb01d](https://github.com/anyup/uView-Pro/commit/3cfb01ddb8612e274e1bccd43fca0b5bb4e0a405))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\n\n## 0.3.13（2025-11-11）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-root-portal:** 修复根节点传送组件运行时报错问题 ([3c24a75](https://github.com/anyup/uView-Pro/commit/3c24a75de00982bbdc1388a413721377de4f1e3d))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\n\n## 0.3.12（2025-11-10）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-dropdown:** 修复下拉菜单激活颜色不正确的问题 ([d3cc1e8](https://github.com/anyup/uView-Pro/commit/d3cc1e87ff0951c5385da5e667a528d30b7fd1cf))\n\n### 📦‍ Build System | 打包构建\n\n- **app-harmony:** 新增 HarmonyOS 构建配置 ([c18a537](https://github.com/anyup/uView-Pro/commit/c18a537d9bf4edcbe626290642225363486cfb1e))\n- 更新项目版本号 ([8eaee77](https://github.com/anyup/uView-Pro/commit/8eaee7784fb348c5637b55b037f62ba51409a4f2))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\n\n## 0.3.10（2025-11-06）\n\n### ♻️ Code Refactoring | 代码重构\n\n- **theme:** 优化动态颜色获取方式 ([26f44dd](https://github.com/anyup/uView-Pro/commit/26f44dd0d03b9cb93a2bc6b94ab6eb15a7b2261e))\n- **types:** 优化类型导入并修复 u-pagination 类型定义 ([c6cbe61](https://github.com/anyup/uView-Pro/commit/c6cbe61242492ddae896ad44482f130da90033dc))\n\n### ✨ Features | 新功能\n\n- **u-pagination:** 新增分页组件及演示示例 ([3915064](https://github.com/anyup/uView-Pro/commit/39150648e599e818ce5c3648b3829f30754e2706))\n- **u-navbar:** 新增左侧插槽 left ([4474e3b](https://github.com/anyup/uView-Pro/commit/4474e3b07d44126dbbcb85957bf1026c602301e7))\n- **u-input:** 新增 focus 发射当前输入值 ([d8082ec](https://github.com/anyup/uView-Pro/commit/d8082ec2d30ae143a2cb223b6a933e5b58e1826b))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **demo:** 修复 u-navbar 演示示例中，因 ref('toast') 和组件名重复问题 ([2bd32a3](https://github.com/anyup/uView-Pro/commit/2bd32a3906fa3dd7ae2a91c8e0382aef7089bba7))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/wjp980108\"><img src=\"https://github.com/wjp980108.png?size=40\" width=\"40\" height=\"40\" alt=\"wjp980108\" title=\"wjp980108\"/></a> <a href=\"https://github.com/wjp\"><img src=\"https://github.com/wjp.png?size=40\" width=\"40\" height=\"40\" alt=\"wjp\" title=\"wjp\"/></a>\n\n## 0.3.9（2025-11-05）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **types:** 修正组件声明文件中uLoadmore的命名大小写问题 ([eb69b18](https://github.com/anyup/uView-Pro/commit/eb69b18d969dac13a75375501018edc4f3097e33))\n- **loadmore:** 修复 u-loadmore 组件使用类型声明报错问题 ([92facfd](https://github.com/anyup/uView-Pro/commit/92facfdb5b2b57bcd634d93412c90661c5f6e59d))\n\n### ✨ Features | 新功能\n\n- **theme:** 新增本地主题文件支持 ([a989314](https://github.com/anyup/uView-Pro/commit/a989314a7b691e94ed81e524100e70d6e9a22a12))\n- **theme:** 实现运行时主题变更功能，新增 setTheme 函数 ([12765d0](https://github.com/anyup/uView-Pro/commit/12765d07244a9d6ca49c4dd34d81f66a61c87c6d))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/liujiayii\"><img src=\"https://github.com/liujiayii.png?size=40\" width=\"40\" height=\"40\" alt=\"liujiayii\" title=\"liujiayii\"/></a> <a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\n\n## 0.3.8（2025-11-04）\n\n### 📦‍ Build System | 打包构建\n\n- 新增钉钉小程序运行和打包命令 ([a5b4ab3](https://github.com/anyup/uView-Pro/commit/a5b4ab3abab95b4c56bf02415f1785371f7f19ee))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-circle-progress:** 修复微信小程序 canvas 2d 环形进度条绘制问题,适配不同平台的 canvas 上下文 ([e7ab701](https://github.com/anyup/uView-Pro/commit/e7ab701bcbd83e7861aeb9a104269265c6b38a56))\n\n### ✨ Features | 新功能\n\n- **u-fab:** 新增悬浮按钮组件及演示示例 ([85848de](https://github.com/anyup/uView-Pro/commit/85848de6bae15d91942a633959459ae8e6ecb857))\n- **u-fab:** 优化悬浮组件功能和交互，新增预设定位position、拖动吸边autoStick属性 ([65a4bde](https://github.com/anyup/uView-Pro/commit/65a4bde2331c8b2a49933bb4c5d7e1f97a11c56a))\n- **u-text:** 新增 u-text 组件默认插槽支持 ([a7b6e59](https://github.com/anyup/uView-Pro/commit/a7b6e5944afbcd48920c25a58c07642544ff3d3e))\n\n### ♻️ Code Refactoring | 代码重构\n\n- **fab:** 优化 fab 组件示例代码 ([ca71fa2](https://github.com/anyup/uView-Pro/commit/ca71fa28fa86baa53384eb366384d97a0b8d84b2))\n- **u-fab:** 重构 gap 属性以支持对象类型 ([bee34bf](https://github.com/anyup/uView-Pro/commit/bee34bffd6a7587e9a82fe3e35cc64c096d8d2b3))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/wjp980108\"><img src=\"https://github.com/wjp980108.png?size=40\" width=\"40\" height=\"40\" alt=\"wjp980108\" title=\"wjp980108\"/></a>\n\n## 0.3.7（2025-10-28）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-index-list:** 修复 u-index-list 组件中 indexList 的响应式，确保数据正确对应，滚动到正确的锚点 ([536479b](https://github.com/anyup/uView-Pro/commit/536479b0c444f50892c789191265b373297ec0b5))\n- **u-form:** 优化 u-form-item 组件样式，修复微信小程序光标样式偏移问题 ([7e6694b](https://github.com/anyup/uView-Pro/commit/7e6694b5db11f654b081d10bb83d53c99437c730))\n- **u-form:** 优化 model 属性的响应式更新，修复 model 对象整体替换导致的表单校验失效问题 ([bc49b5b](https://github.com/anyup/uView-Pro/commit/bc49b5b2fa6f51c803d64252184f5eba93a0d3c1))\n- **u-form:** 修复 u-form 的重置表单方法 resetFields 失效问题 ([a31f800](https://github.com/anyup/uView-Pro/commit/a31f800e206fa9671bdd0d6a46ca7a4afba6aefd))\n- **u-checkbox:** 修复 u-checkbox 单独使用报错的问题 ([dad2832](https://github.com/anyup/uView-Pro/commit/dad2832a2e7219b0454ec97970c9cb8f4fac0625))\n\n### ✨ Features | 新功能\n\n- **u-textarea:** 新增 u-textarea 组件及演示示例，增强 textarea 功能，分离 u-input 的 textarea 模式 ([efbb75e](https://github.com/anyup/uView-Pro/commit/efbb75e21a044a664267930396ce496fd64d33fe))\n- **u-input:** 增强 u-input 的 textarea 字数统计功能 ([5e14354](https://github.com/anyup/uView-Pro/commit/5e14354a2e34768650cd2417f81b14cdbbced132))\n- **u-form:** 增强表单校验功能，发射校验错误，便于自定义提示 ([a553b53](https://github.com/anyup/uView-Pro/commit/a553b53581cc470938030c0f1f8d5f7671d8c25a))\n\n### ♻️ Code Refactoring | 代码重构\n\n- **form:** 优化表单组件的提示文本 ([04b5fc7](https://github.com/anyup/uView-Pro/commit/04b5fc7a071835425786958c5f6de04e233c151c))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\n\n## 0.3.6（2025-10-24）\n\n### ✨ Features | 新功能\n\n- **u-select:** 优化选择器组件 u-select 默认值处理逻辑，添加 preserveSelection 属性，用于控制是否保留用户上次确认的选择 ([8493ff1](https://github.com/anyup/uView-Pro/commit/8493ff16d2eee42fabe926917d940a350b86abe0))\n- **u-picker:** 优化 picker 的初始化和渲染流程，实现多次打开 picker 时保留用户选择的逻辑，新增 preserveSelection 属性支持 ([974872e](https://github.com/anyup/uView-Pro/commit/974872ec944fbb28cdb3c40fda08c9039bf0b960))\n\n### ♻️ Code Refactoring | 代码重构\n\n- **components:** 使用主题色替代硬编码颜色值，统一组件的颜色风格，便于未来主题颜色的调整和维护 ([ec348d4](https://github.com/anyup/uView-Pro/commit/ec348d4a8bff4dee62da78eadd23fc3a292ebdca))\n- **example:** 代码示例中使用主题色替换硬编码颜色值 ([3216497](https://github.com/anyup/uView-Pro/commit/32164973d54cfff3edcbe765a8ed27158f4bec7d))\n- **u-steps:** 新增u-step ([6b86eea](https://github.com/anyup/uView-Pro/commit/6b86eeaf7699eb13f739fc038d86efb4e3b48f8a))\n- **u-step:** 替换步骤条组件中的默认硬编码颜色值 ([f3408ef](https://github.com/anyup/uView-Pro/commit/f3408ef006991702895432e775f266fb196ddf12))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-picker:** 修复使用u-picker组件选择地区不设置默认值报错的问题 ([7941135](https://github.com/anyup/uView-Pro/commit/7941135a87a3511a562ed10e34573ef7f786fb57))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/lonelyflyer\"><img src=\"https://github.com/lonelyflyer.png?size=40\" width=\"40\" height=\"40\" alt=\"Lonelyflyer\" title=\"Lonelyflyer\"/></a>\n\n## 0.3.5（2025-10-21）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-input:** 修复input组件不支持input事件的问题 ([52d6a6a](https://github.com/anyup/uView-Pro/commit/52d6a6aaeec9ec78e4088234ff7ba056cc10fd9c))\n- **u-search:** 修复search组件不支持input事件的问题 ([603b96f](https://github.com/anyup/uView-Pro/commit/603b96f7eeb16d3e54c82b0be7dd03deb930aef5))\n- **u-popup:** 修复微信小程序环境下，u-popup 组件 mode=center 时，设置关闭图标位置无效的问题 ([f08197a](https://github.com/anyup/uView-Pro/commit/f08197aafdc3f874b1efcddf6cc6ff9c9edde954))\n- **u-line-progress:** type 属性设置后仍被 active-color 内联样式覆盖的问题 ([c6f29f9](https://github.com/anyup/uView-Pro/commit/c6f29f9dc8437035a0e698e869af2fd418d0bd65))\n\n### ✨ Features | 新功能\n\n- **useChildren:** 添加子组件索引功能 ([8ad744f](https://github.com/anyup/uView-Pro/commit/8ad744fd51df934cc20c099686cbdc5512b22c79))\n- **addUnit:** 增强 addUnit 函数支持多值空格分隔 ([6d89cd3](https://github.com/anyup/uView-Pro/commit/6d89cd3c5aacc0770f6f2684fd737d0f05a6e929))\n- **u-action-sheet:** 新增自定义 ActionSheet 组件 ([f709523](https://github.com/anyup/uView-Pro/commit/f709523cba5a089eed7c717cc36b9ab199ae24da))\n\n### 📝 Documentation | 文档\n\n- 移除issue模板中的提交格式参考 ([83799e8](https://github.com/anyup/uView-Pro/commit/83799e882f69b0e8787a014cfab9f16ab34ba57c))\n\n### ♻️ Code Refactoring | 代码重构\n\n- **u-popup:** 移除弹窗组件中的冗余代码 ([40c5b64](https://github.com/anyup/uView-Pro/commit/40c5b641539fce56af4f9a4ad2440b9240464a89))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/sunjianwei\"><img src=\"https://github.com/sunjianwei.png?size=40\" width=\"40\" height=\"40\" alt=\"sunjianwei\" title=\"sunjianwei\"/></a> <a href=\"https://github.com/koboshi\"><img src=\"https://github.com/koboshi.png?size=40\" width=\"40\" height=\"40\" alt=\"koboshi\" title=\"koboshi\"/></a>\n\n## 0.3.4（2025-10-20）\n\n### ♻️ Code Refactoring | 代码重构\n\n- **components:** 移除不必要的父组件和事件总线相关代码，优化组件间通信 ([280c2f8](https://github.com/anyup/uView-Pro/commit/280c2f8acc75764a7706ec38c742cc16703c941a))\n- **u-safe-bottom:** 优化底部安全区组件 ([161f2d3](https://github.com/anyup/uView-Pro/commit/161f2d32ff6b9abbb6f8221a4dd99c438a606e94))\n- **u-status-bar:** 优化状态栏组件 ([53c50ab](https://github.com/anyup/uView-Pro/commit/53c50ab8b6314a7d702b90e6b48b79301a334090))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-subsection:** 优化列表和模式变化的监听逻辑，移除不必要的初始化调用 ([f77ee7c](https://github.com/anyup/uView-Pro/commit/f77ee7ccc7521ec2472f72dcf2fb47362ca0abd9))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\n\n## 0.3.3（2025-10-16）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-read-more:** 修复 init 方法无法在外部调用的问题 ([415d401](https://github.com/anyup/uView-Pro/commit/415d401883a3567653ab1f311b28b075b7bb5603))\n- **u-button:** 修复 hover-class 属性被忽略的问题 ([b919c58](https://github.com/anyup/uView-Pro/commit/b919c58cea048f9e559a6448cebe5abbf1490acf))\n\n### ♻️ Code Refactoring | 代码重构\n\n- **component-relation:** 重构组件关系逻辑并添加新功能 ([85d0cd2](https://github.com/anyup/uView-Pro/commit/85d0cd20db839a61733887f82825d47de0a1b1a6))\n- **u-talbe:** 重构u-td和u-th组件，增强u-table的兼容性 ([3fbbc52](https://github.com/anyup/uView-Pro/commit/3fbbc5233bd41b91ca829f9a65cf95ee3b599e36))\n- 修改 uView Pro 日志配置 ([6b9bb68](https://github.com/anyup/uView-Pro/commit/6b9bb6852af3eb24f109207f864145771c3e9c79))\n- **clipboard:** add clipboard function ([efdaa58](https://github.com/anyup/uView-Pro/commit/efdaa58dda923b281d9b764a82a7492f36717ac4))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/koboshi\"><img src=\"https://github.com/koboshi.png?size=40\" width=\"40\" height=\"40\" alt=\"koboshi\" title=\"koboshi\"/></a> <a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a> <a href=\"https://github.com/lonelyflyer\"><img src=\"https://github.com/lonelyflyer.png?size=40\" width=\"40\" height=\"40\" alt=\"Lonelyflyer\" title=\"Lonelyflyer\"/></a>\n\n## 0.3.2（2025-10-15）\n\n### 📝 Documentation | 文档\n\n- **changelog:** 更新 CHANGELOG.md 生成配置 ([27a2609](https://github.com/anyup/uView-Pro/commit/27a26095b92cf8cbc6477c563a68b1557f9fb045))\n- 更新交流群图片链接 ([832815d](https://github.com/anyup/uView-Pro/commit/832815deb63f8b144f525591d16e3ccf900b8632))\n\n### ⚡ Performance Improvements | 性能优化\n\n- **component-relation:** 增强组件间通信功能；修改 broadcast 方法，支持定向广播；移除对子组件名称的强制要求，允许匿名组件 ([28ea814](https://github.com/anyup/uView-Pro/commit/28ea814810055aa4c99b53d676b16da337fdf7d5))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-index-list:** 重构索引锚点组件，兼容多端，修复IndexList索引列表在微信小程序没有吸顶效果 ([ce6a7a3](https://github.com/anyup/uView-Pro/commit/ce6a7a3c01b622cad268779098390c0d593f75bc))\n\n### 👥 Contributors\n\n<a href=\"https://github.com/anyup\"><img src=\"https://github.com/anyup.png?size=40\" width=\"40\" height=\"40\" alt=\"anyup\" title=\"anyup\"/></a>\n\n## 0.3.1（2025-10-14）\n\n### 📝 Documentation | 文档\n\n- 更新 package.json 中的平台支持信息 ([c30da7c](https://github.com/anyup/uView-Pro/commit/c30da7cf32c8c97e740df75166d1d7dfa4016942))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **request:** 修复http request请求拦截器中config.header为undefined的问题 ([8da453a](https://github.com/anyup/uView-Pro/commit/8da453afe193338a53c9f320346acabdb8803a79))\n\n## 0.3.0（2025-10-12）\n\n### 📝 Documentation | 文档\n\n- 更新开源捐赠图片 ([8eb0f00](https://github.com/anyup/uView-Pro/commit/8eb0f00ed5308cd1c3574b66dc752b050bbfcb70))\n- update readme ([c93cdcb](https://github.com/anyup/uView-Pro/commit/c93cdcb1278040b8c5b6232b0d7928edad22af5d))\n\n### ✨ Features | 新功能\n\n- **component-relation:** 添加组件关系管理 Hooks 工具，用于完全替换 provide/inject，全平台兼容 ([927be95](https://github.com/anyup/uView-Pro/commit/927be95e8b1c1bd5e05cf91c00888c314f6431e8))\n\n### ♻️ Code Refactoring | 代码重构\n\n- **components:** 重构复选框checkbox和手风琴collapse组件，使用新版组件关系管理工具，优化兼容性 ([a6b2e86](https://github.com/anyup/uView-Pro/commit/a6b2e86394193a1ff5b58df045cba5518b322d38))\n- **u-radio:** 修复单选框组件，兼容微信、头条小程序 ([6c409dc](https://github.com/anyup/uView-Pro/commit/6c409dc2c0ed116abcdde23a366c7f575fd56a24))\n- **styles:** 优化 u-collapse-item 和 u-text 组件的样式合并逻辑 ([d4436c5](https://github.com/anyup/uView-Pro/commit/d4436c51dc2ddb27d70eeba4cad804504da40013))\n- **layout:** 优化布局组件兼容性 ([285b7a7](https://github.com/anyup/uView-Pro/commit/285b7a73fcd9f8a21521be0d7e7a83690495dc4b))\n- **u-form:** 重构表单组件的错误处理和样式，增强兼容性，支持多种小程序平台 ([587f87d](https://github.com/anyup/uView-Pro/commit/587f87d1b8d3dd6cd98e583b2640bef61bd8f119))\n- **components:** 所有组件允许接受外部样式，允许样式穿透 ([e736e90](https://github.com/anyup/uView-Pro/commit/e736e9014e36c995ba434a56a6ccfee01c56ad35))\n- **u-grid:** 重构宫格组件，支持自定义样式 ([d999ece](https://github.com/anyup/uView-Pro/commit/d999eceed2447ddc99a62a6bdcc57deaa1d1b515))\n- **component-relation:** 优化子组件挂载时连接父组件的逻辑 ([2d038f2](https://github.com/anyup/uView-Pro/commit/2d038f2721e91db2f1773079341473505f2f6836))\n- **u-dropdown:** 重构下拉菜单组件，兼容多平台 ([393caa5](https://github.com/anyup/uView-Pro/commit/393caa57910e9a63484e0c9e852c634fc15ef606))\n- **components:** 优化部分组件中的 customStyle 属性及样式处理 ([3506a5a](https://github.com/anyup/uView-Pro/commit/3506a5a055a7a106311351b4b8b90127b019a061))\n- **components:** 统一使用 customClass 和 customStyle 属性，统一处理组件样式和类名 ([d400997](https://github.com/anyup/uView-Pro/commit/d40099782b97011edc04c5040342b585b8f18fcd))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-collapse:** 修复手风琴模式和非手风琴模式的处理回调时，index错误的问题 ([a5882eb](https://github.com/anyup/uView-Pro/commit/a5882eb17d87fee4e06448ecc353bf4237f25d52))\n\n## 0.2.4（2025-10-08）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **i18n:** 修复切换中英文切换失效问题 ([d61d817](https://github.com/anyup/uView-Pro/commit/d61d81790aecd774435999c9ab8c3672a2df38ad))\n- **style:** 修复文本溢出样式u-line-1生成错误问题 ([5d2bf3c](https://github.com/anyup/uView-Pro/commit/5d2bf3ca080f8c5bc9fe40bb1f421c28f7ee8017))\n\n### ✨ Features | 新功能\n\n- **calendar:** 增加日历组件的页面显示模式 ([af13724](https://github.com/anyup/uView-Pro/commit/af137241e644a5f1e99b07e580c8d3aca9250e9e))\n\n### ♻️ Code Refactoring | 代码重构\n\n- 优化代码格式和可读性 ([2e338d5](https://github.com/anyup/uView-Pro/commit/2e338d5cb2dbf3ce42f38c9581c04164b852f992))\n- **useComponent:** 重构组件事件处理并添加热更新支持 ([80f7e5e](https://github.com/anyup/uView-Pro/commit/80f7e5efaa2b2ab1668969072cb6d18652d00cc2))\n- **u-collapse:** 重构 u-collapse 组件中的事件处理逻辑 ([6aadfd1](https://github.com/anyup/uView-Pro/commit/6aadfd16d5aefd45f022c8da1612ba1921942f6e))\n- **u-checkbox:** 优化复选框组件的父组件事件处理 ([3b597ea](https://github.com/anyup/uView-Pro/commit/3b597ea2833ca71e5752d097b2f07c143869f0d2))\n- **hooks:** 优化 useComponent 以支持页面级别组件关系管理 ([429192f](https://github.com/anyup/uView-Pro/commit/429192f66ba59a26acb957acfc01d5f318d43fb6))\n\n### 📝 Documentation | 文档\n\n- 更新微信交流群图片链接 ([e67588a](https://github.com/anyup/uView-Pro/commit/e67588ae392d5150ec4d271ce45e65fe32372460))\n\n## 0.2.3（2025-10-06）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-collapse:** 修复手风琴组件在头条小程序的兼容性 ([3189dc4](https://github.com/anyup/uView-Pro/commit/3189dc468edd977bc3e20256bd8a6c1b124bc4e6))\n\n### ✨ Features | 新功能\n\n- **util:** 新增日志功能并调整主题配置 ([5e07894](https://github.com/anyup/uView-Pro/commit/5e078945fb64867e4e49be1c9228aac7be8c1104))\n- **components:** 重构复选框和手风琴组件，新增父子组件通信库 ([55b9b60](https://github.com/anyup/uView-Pro/commit/55b9b6069f1a40a6c4190b27952bcf9a489f8923))\n- **util:** 添加自定义事件总线 ([6589f4f](https://github.com/anyup/uView-Pro/commit/6589f4f20b1391a9267670f6622538d4a6db0d82))\n\n### ♻️ Code Refactoring | 代码重构\n\n- **components:** 重构复选框和折叠组件，支持多平台小程序，微信，支付宝，头条 ([0ebc0f5](https://github.com/anyup/uView-Pro/commit/0ebc0f5edcc1df6ccd9baaaf659a0bde7b37d21d))\n- **hooks:** 移除组件关系热更新时的错误日志输出 ([c8a2a3d](https://github.com/anyup/uView-Pro/commit/c8a2a3d041a55f94c8bd86d47eaaee9657cbd597))\n\n### 📝 Documentation | 文档\n\n- **readme:** 更新微信交流群二维码 ([cff3a3d](https://github.com/anyup/uView-Pro/commit/cff3a3dbb035ca365a1ab9839b14f300ef775c16))\n\n## 0.2.2（2025-09-30）\n\n### 🚀 Chore | 构建/工程依赖/工具\n\n- 删除未使用的公共 API 和国际化文件 ([e73d3da](https://github.com/anyup/uView-Pro/commit/e73d3da7ede71584ec8b58a386307747b62f5e7a))\n\n### ♻️ Code Refactoring | 代码重构\n\n- **components:** 提示组件抽离为全局组件 wx-tips ([3fc0111](https://github.com/anyup/uView-Pro/commit/3fc0111f296de37bdb9b56fdfc023537aa6d79c4))\n- **u-collapse:** 优化手风琴模式和样式配置 ([5cff422](https://github.com/anyup/uView-Pro/commit/5cff422a8462403f3c3f23a66f9306a81499a3b0))\n\n### ✨ Features | 新功能\n\n- **components:** 新增 u-root-portal 根节点传送组件 ([891d021](https://github.com/anyup/uView-Pro/commit/891d021faf76ad0248ef21248d89ff1fe1c5b669))\n- **manifest:** 添加支付宝小程序配置 ([cb0b42a](https://github.com/anyup/uView-Pro/commit/cb0b42a9397df1c335d2c5492136efa38dde2ca0))\n\n### 📝 Documentation | 文档\n\n- 添加支付宝小程序二维码并更新微信群聊图片 ([1dc0db3](https://github.com/anyup/uView-Pro/commit/1dc0db340e34675f15a7e83c79c3ac5d453853a2))\n\n## 0.2.1（2025-09-29）\n\n### 🚀 Chore | 构建/工程依赖/工具\n\n- 优化代码格式化和 ESLint 配置 ([771eacd](https://github.com/anyup/uView-Pro/commit/771eacd58d410e468a8aec4225bbe7b402480b2f))\n\n### ⚡ Performance Improvements | 性能优化\n\n- 压缩部分js工具库 ([6615b70](https://github.com/anyup/uView-Pro/commit/6615b7085a51c4fbc9f884ec68e05db1a1e89e27))\n\n### ✨ Features | 新功能\n\n- **u-calendar:** 日历组件增加农历显示功能 ([e2368ac](https://github.com/anyup/uView-Pro/commit/e2368ac88b0abb4493ab12a1785eb2a0e38e502c))\n\n### ♻️ Code Refactoring | 代码重构\n\n- **calendar:** 重构日历组件类型定义 ([0040e9e](https://github.com/anyup/uView-Pro/commit/0040e9e1095446536370e9aca3c135bc05527acb))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-input:** 修复输入框禁用状态时清空按钮仍显示的问题 ([722715f](https://github.com/anyup/uView-Pro/commit/722715f7d6607584c0e158ba2de2342147e3be17))\n\n## 0.2.0（2025-09-28）\n\n### ♻️ Code Refactoring | 代码重构\n\n- **example:** 优化 about 页面中的链接处理 ([d04ba8a](https://github.com/anyup/uView-Pro/commit/d04ba8a26278b6a0ea4f5e906bfec89ce6954459))\n- **css:** 重构 CSS 样式并添加新样式 ([50b2670](https://github.com/anyup/uView-Pro/commit/50b2670a5e09aff9994a97f60a7d376b5b99a544))\n- **libs:** 重构 libs 工具类代码并优化导出方式 ([10a604e](https://github.com/anyup/uView-Pro/commit/10a604e86f8712ee65c658a019c231b56cdcc7e7))\n- **u-icon:** 移除 customStyle 属性并整合全局样式 ([cd52e14](https://github.com/anyup/uView-Pro/commit/cd52e14739604f1f126205e16383f187f1d38e8e))\n- **props:** 优化 Props 类型定义和样式处理 ([c6ca0de](https://github.com/anyup/uView-Pro/commit/c6ca0de0876cb61671c25e58f33e51674edab266))\n- **u-text:** 优化文本组件的样式和布局 ([885a0cf](https://github.com/anyup/uView-Pro/commit/885a0cf3f348184b3546979f1cc1914ded198411))\n- **u-text:** 优化文本组件样式和属性 ([315d437](https://github.com/anyup/uView-Pro/commit/315d4379148fddbed059e55e5f9a0d0268345e62))\n- **pages:** 优化微信小程序多个页面的用户提示展示，审核相关 ([0f3741f](https://github.com/anyup/uView-Pro/commit/0f3741f65d39f74bc3dc27df8514324e02c3582a))\n- **pages:** 添加微信小程序端布局演示提示 ([9eaac70](https://github.com/anyup/uView-Pro/commit/9eaac70cf143327589d56a627160f33c56585d2e))\n\n### ✨ Features | 新功能\n\n- **components:** 添加 input 组件演示页面 ([91baf00](https://github.com/anyup/uView-Pro/commit/91baf0012e381856b79ca49edb60735928d78099))\n- **collapse:** 更新折叠面板组件默认配置和样式 ([a03e0be](https://github.com/anyup/uView-Pro/commit/a03e0be3a9f8ac8b03dbd406d5d8c37227e869bd))\n- **components:** 新增 Text 组件 ([a034f9d](https://github.com/anyup/uView-Pro/commit/a034f9d029ab38dbf1a066978f3c62c1328c96a5))\n- **hooks:** 重构 useParent 并添加父子组件关系管理 ([37e35d8](https://github.com/anyup/uView-Pro/commit/37e35d84112a08b3d28aa8e5caec12a0a2696594))\n- **hooks:** 新增自定义 Hooks 工具库 ([0b3f680](https://github.com/anyup/uView-Pro/commit/0b3f68051b09917fbd39006093291f6dcc4eb0ef))\n\n### 📝 Documentation | 文档\n\n- 添加 Copilot 提示词 ([c10cd20](https://github.com/anyup/uView-Pro/commit/c10cd201214907ae2ac8228498927a59f8411cfb))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-collapse:** 重构手风琴组件并解决手风琴失效问题 ([a64e607](https://github.com/anyup/uView-Pro/commit/a64e6075f556ffeb3f5ad6b9ea443e3a22f83a86))\n- **u-collapse:** 修复折叠面板内容高度在头条小程序适配 ([5fdcd26](https://github.com/anyup/uView-Pro/commit/5fdcd262ab3e134a97a4f25482d188d93222fddf))\n\n### 👷 Continuous Integration | CI 配置\n\n- **vscode:** 设置 Vue 文件默认格式化工具为 Prettier ([84d5259](https://github.com/anyup/uView-Pro/commit/84d52599f2632e814a137e8d553793fb3cdad1f1))\n\n## 0.1.1（2025-09-22）\n\n### ♻️ Code Refactoring | 代码重构\n\n- **theme:** 重构主题颜色定义和导出 ([a58a477](https://github.com/anyup/uView-Pro/commit/a58a477c8af42e466ed544d7737d84de80f3dc27))\n\n### ✨ Features | 新功能\n\n- **i18n:** 优化国际化配置并添加安全措施 ([952dd88](https://github.com/anyup/uView-Pro/commit/952dd887dcadeebccb98a25ec066181904ab727e))\n\n### 📝 Documentation | 文档\n\n- 简化提交 issue 模板结构 ([c818685](https://github.com/anyup/uView-Pro/commit/c818685383ae400b10d6662e7f4b9ba6be5b31f6))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-input:** 解决u-input组件在微信小程序端，开启clearable属性后，focus会自动清空输入问题 ([283551c](https://github.com/anyup/uView-Pro/commit/283551c54cd7006899a66b97afe7137b4bbb14b1))\n\n## 0.1.0（2025-09-21）\n\n### ♻️ Code Refactoring | 代码重构\n\n- **http:** 优化 HTTP 请求和响应拦截器 ([b9ea27f](https://github.com/anyup/uView-Pro/commit/b9ea27f7a2fc3425316211784a07b2cde030282a))\n- 修改路由基础路径 ([23143c8](https://github.com/anyup/uView-Pro/commit/23143c839242fcd19c9c6ca73a8ff1bcfdb8b83b))\n- 移除多个组件中未使用的样式标签 ([f8d353a](https://github.com/anyup/uView-Pro/commit/f8d353a0b99b3d9a2530d8d8a4bd8d0d5fe7dcc5))\n- 更新项目文档链接和基础配置 ([435a1ea](https://github.com/anyup/uView-Pro/commit/435a1ea5b89f8ba850f3cd469f4583d3946f8142))\n\n### 📦‍ Build System | 打包构建\n\n- **vite:** 配置别名和服务器设置 ([b319288](https://github.com/anyup/uView-Pro/commit/b3192882a104963ab6a2c7b6c03e2fb8ee17f609))\n- **vite:** 配置别名和服务器设置 ([9483730](https://github.com/anyup/uView-Pro/commit/9483730b371a5722511cd515d20a1eac28834f04))\n- 添加修复空 CSS 文件的脚本 ([38b943d](https://github.com/anyup/uView-Pro/commit/38b943d0f1234978e90284fa759f13b604160e96))\n\n### ✨ Features | 新功能\n\n- **theme:** 支持自定义的color值传入 ([3de798f](https://github.com/anyup/uView-Pro/commit/3de798f8de48af07774376366f5472f463b07177))\n\n### 💄 Styles | 风格\n\n- 移除多余空格和换行 ([80df4d4](https://github.com/anyup/uView-Pro/commit/80df4d44b631b12adb1ae45a6dd0dfa69a2694b1))\n\n### 📝 Documentation | 文档\n\n- 更新交流群图片 ([3b71cb0](https://github.com/anyup/uView-Pro/commit/3b71cb092efd4c5a89c36ee559028d0fe438a013))\n\n## 0.0.23（2025-09-15）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-collapse:** fix accordion mode ([c411fef](https://github.com/anyup/uView-Pro/commit/c411fef340cff07ab06a64f623741e9c1ad125cb))\n\n### 🚀 Chore | 构建/工程依赖/工具\n\n- revert comments ([3eed330](https://github.com/anyup/uView-Pro/commit/3eed330c27a7026eb87cb9ef285d1ecbe6789552))\n- **docs:** 增加贡献者 ([8b9d44e](https://github.com/anyup/uView-Pro/commit/8b9d44e281c02f639079b77b7c32cc0a566b35a1))\n- **docs:** add contributors ([b4035da](https://github.com/anyup/uView-Pro/commit/b4035da5a39acc5ae9dcb13b06143cda6a73fec3))\n\n### 📝 Documentation | 文档\n\n- 更新交流群二维码图片 ([00c0581](https://github.com/anyup/uView-Pro/commit/00c058159ea9d169219474728e8b31cdc892ab2c))\n\n## 0.0.22（2025-09-11）\n\n### 🚀 Chore | 构建/工程依赖/工具\n\n- 忽略 pnpm-lock.yaml 文件 ([28802d3](https://github.com/anyup/uView-Pro/commit/28802d308d3c1f2d0d6b583b3b27725b6b40b1a9))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **td/th:** fix invalid width setting ([21718fc](https://github.com/anyup/uView-Pro/commit/21718fc3b2f09e1ccf9f1ce8247b78f30e5fe465))\n- **u-modal:** 修复在 modal 组件中添加 clearLoading 方法的暴露，以便外部可以调用 ([34b51a7](https://github.com/anyup/uView-Pro/commit/34b51a7187da296b11f4b5db027a86c41a50a477))\n\n### ✨ Features | 新功能\n\n- **components:** add u-status-bar and u-safe-bottom component ([2085e73](https://github.com/anyup/uView-Pro/commit/2085e73be725f921c436069c27c124e507b24d0e))\n- **u-upload:** 调整上传组件默认值和功能 ([4808627](https://github.com/anyup/uView-Pro/commit/48086274f5fe16f4b3b7554a99038a76aa08e8c5))\n- **pages:** 在多个页面中添加功能说明的弹窗提示 ([5e59855](https://github.com/anyup/uView-Pro/commit/5e59855ff81f21c54cbfa44a3f4641b4b9f1f6bd))\n\n## 0.0.21（2025-09-09）\n\n### ⚡ Performance Improvements | 性能优化\n\n- **pages:** options 语法升级为 composition 语法 ([e38878c](https://github.com/anyup/uView-Pro/commit/e38878c696ffc548374169423613e97c3878bafd))\n- **pages:** options 语法升级为 composition 语法 ([0403545](https://github.com/anyup/uView-Pro/commit/040354507bd187a9bff4371fc4950dfd6412cd5b))\n- **pages:** options 语法升级为 composition 语法 ([514ecb6](https://github.com/anyup/uView-Pro/commit/514ecb6f8e2b133b962a6cbe7609a64e4d973928))\n- **pages:** options 语法升级为 composition 语法 ([ffcc1cb](https://github.com/anyup/uView-Pro/commit/ffcc1cb8993196252535ea6553d7fd999ab57719))\n- **pages:** options 语法升级为 composition 语法 ([2c755e3](https://github.com/anyup/uView-Pro/commit/2c755e3e1f386c3be1ae8955607d64f72b2b6640))\n- 优化首页图标渲染问题 ([a6d4b16](https://github.com/anyup/uView-Pro/commit/a6d4b1690544f3261fb138cb490a10131d4fb749))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-tag:** 修复 u-tag 类型 ([c9071a6](https://github.com/anyup/uView-Pro/commit/c9071a610e08efc4581eff97e4d4998c2d01c9eb))\n- **u-table:** 修复 u-table props style 属性变化时，u-th/t-td 未更新问题 ([b1ee7d6](https://github.com/anyup/uView-Pro/commit/b1ee7d6ade7a59e305d7a4081415418387bb6832))\n- 修复微信小程序环境下 http interceptor 的路径问题 ([a7fe746](https://github.com/anyup/uView-Pro/commit/a7fe7466b3f66644e097ee6be23f231bce77fa5f))\n- 优化checkbox示例页面逻辑 ([9818b20](https://github.com/anyup/uView-Pro/commit/9818b20471e11b96ded606db808f2eda32904f82))\n- 修复微信小程序不支持u-circle-progress绘制canvas失败问题 ([46406c5](https://github.com/anyup/uView-Pro/commit/46406c593260f29b081c6a5d98c48dc97e225600))\n- 修复 u-picker 组件 params 属性默认值设置 ([36a713b](https://github.com/anyup/uView-Pro/commit/36a713b3c84ddb6e9ef40132512063cdde35ea19))\n\n### 📝 Documentation | 文档\n\n- 更新微信交流群图片 ([825b187](https://github.com/anyup/uView-Pro/commit/825b187619ee745a23559bfe0b597b75f90f220d))\n\n### 🚀 Chore | 构建/工程依赖/工具\n\n- update project configuration and add prettier support ([9c0cc6a](https://github.com/anyup/uView-Pro/commit/9c0cc6ae3719b975d702b0283bd0c15ee4f3c374))\n\n### ♻️ Code Refactoring | 代码重构\n\n- **library:** 移除不需要的 globalVariable ([420c40e](https://github.com/anyup/uView-Pro/commit/420c40eac3c67e184924e166edaf4cf2ea904477))\n- 更新 pages.json ([03297ce](https://github.com/anyup/uView-Pro/commit/03297ce219ae9337c1a424b9583fa53c74f0291d))\n\n### 💄 Styles | 风格\n\n- 格式化代码 ([a9e0a38](https://github.com/anyup/uView-Pro/commit/a9e0a387ffa55df740b828ea4a1463d97089c4bd))\n\n### 📦‍ Build System | 打包构建\n\n- mp-alipay 开启 component2 支持 ([430d248](https://github.com/anyup/uView-Pro/commit/430d248ef9e805365dcee0373f6a524bd7084a38))\n\n## 0.0.20（2025-09-08）\n\n### ♻️ Code Refactoring | 代码重构\n\n- 优化http使用示例 ([39d0910](https://github.com/anyup/uView-Pro/commit/39d091056dc1e335625ce884aade35c8bd11ee6f))\n\n### 📝 Documentation | 文档\n\n- 更新微信交流群图片 ([21bbec1](https://github.com/anyup/uView-Pro/commit/21bbec14937ee52b225d1f415d90aecbe4d4950f))\n\n### 🚀 Chore | 构建/工程依赖/工具\n\n- update project configuration and add prettier support ([74a714d](https://github.com/anyup/uView-Pro/commit/74a714ddc30dc0c2c5a6389f254f1e2c922d905e))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- 修复微信小程序环境下 http interceptor 的路径问题 ([6db4db8](https://github.com/anyup/uView-Pro/commit/6db4db89ef1ab22e3051a6ee944ba44430aa3474))\n\n### 👷 Continuous Integration | CI 配置\n\n- update husky pre-commit ([dd04f9a](https://github.com/anyup/uView-Pro/commit/dd04f9a8f2ebdbec37a148e1cf2fa3280c1ab2cd))\n\n## 0.0.19（2025-09-04）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- include uview-pro changelog.md in release commit ([18d902d](https://github.com/anyup/uView-Pro/commit/18d902db2bba4f8f574d7b3b72be218747525bb9))\n\n### 📝 Documentation | 文档\n\n- update uview pro changelog ([31261db](https://github.com/anyup/uView-Pro/commit/31261dbd6b17aea8126a43def1912324b782096e))\n\n### ♻️ Code Refactoring | 代码重构\n\n- 移除 uni-http 模块 ([5f21735](https://github.com/anyup/uView-Pro/commit/5f2173503cc904fb0a7fa2abd3ed3b9dbe09aeb2))\n\n### ✨ Features | 新功能\n\n- 新增http请求模块并实现插件化 ([31c6f88](https://github.com/anyup/uView-Pro/commit/31c6f880d12e586d445faddcc1a3910fda9926bc))\n- 增强 toast 工具函数的灵活性 ([2232054](https://github.com/anyup/uView-Pro/commit/22320540acee36c6c11688387431a4ddba93520f))\n- 添加 HTTP 请求拦截器和配置示例代码 ([aba7cf9](https://github.com/anyup/uView-Pro/commit/aba7cf97ed2424432da51be1841aa17a5a2d7932))\n\n## 0.0.18（2025-09-03）\n\n### 🚀 Chore | 构建/工程依赖/工具\n\n- update release script for better version management ([b64f38f](https://github.com/anyup/uView-Pro/commit/b64f38fea28de39c99cdf84f7e767aa7ceac1344))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- **u-checkbox:** 兼容头条小程序获取父组件数据不支持provide/inject的写法 ([498e12e](https://github.com/anyup/uView-Pro/commit/498e12e2f3aa52021d1be282426536b45f39ca6a))\n\n### 👷 Continuous Integration | CI 配置\n\n- optimize changelog generation and spacing ([3103e7b](https://github.com/anyup/uView-Pro/commit/3103e7b56a0e2dd0392efdb6a85824b11ef6800c))\n\n## 0.0.17（2025-09-02）\n\n### ♻️ Code Refactoring | 代码重构\n\n- 瀑布流组件示例代码重构为 Vue3 ([93949ad](https://github.com/anyup/uView-Pro/commit/93949ad8ae2a36c6130f87340c222ab9ec69d21f))\n\n### ✨ Features | 新功能\n\n- 新增组件 u-loading-popup，一个可以配置的加载提示弹窗 ([6245df9](https://github.com/anyup/uView-Pro/commit/6245df951034b06225ab36d3f18cae8e7ab4b329))\n- 新增 Loading 加载弹窗组件的示例页面 ([1bce868](https://github.com/anyup/uView-Pro/commit/1bce86810863012c5a73104ca0a85ebacb4aa92a))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- 修复瀑布流组件 u-waterfll，暴露 celar/remove/modify 方法 ([240e023](https://github.com/anyup/uView-Pro/commit/240e0238af092d4c6bde86d0db9e49636b806d6f))\n\n## 0.0.15（2025-08-30）\n\n### ✨ Features | 新功能\n\n- 优化 u-image 组件 slot 使用体验，兼容头条小程序 ([a6ca54f](https://github.com/anyup/uView-Pro/commit/a6ca54fce06b20b7a6938d0bef9342954b787641))\n\n### ♻️ Bug Fixes | Bug 修复\n\n- 优化 label 的声明错误问题 ([314c394](https://github.com/anyup/uView-Pro/commit/314c3940145c657b12f16d005af7d271f4ae74e3))\n- 优化头条小程序 form 表单校验的兼容性问题 ([3912fd6](https://github.com/anyup/uView-Pro/commit/3912fd6ade3a1d612f6f5e86ddc0336376ee5618))\n\n## 0.0.14（2025-08-28）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- 修复使用 u-swipe-action 右边会出现一条背景线的 bug ([a5b60c6](https://github.com/anyup/uView-Pro/commit/a5b60c6485120e164c0e0c29eea3b765c10f9aac))\n\n## 0.0.13（2025-08-27）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- 修复 count-down 组件暴露 start 和 end 方法 ([0f42a01](https://github.com/anyup/uView-Pro/commit/0f42a01f55aa6799f57eb93dc5d029b06115b154))\n\n## 0.0.12（2025-08-27）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- 优化 async-validator 文件多余注释导致的问题 ([f06c80d](https://github.com/anyup/uView-Pro/commit/f06c80d57e61e7b75f1384fe89f309b8a0e379fa))\n\n## 0.0.11（2025-08-26）\n\n### ♻️ Code Refactoring | 代码重构\n\n- 取消 async-validator ts 检查 ([772a729](https://github.com/anyup/uView-Pro/commit/772a729164f2cb268a886b6749e4a58846ebb3dc))\n- 移除 u-tr 未使用的类型导入和属性定义 ([46ce459](https://github.com/anyup/uView-Pro/commit/46ce4590166a30a0eb048110efc046095a87f6e8))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- 修复 u-count-down 倒计时符号显示逻辑 ([a4c9498](https://github.com/anyup/uView-Pro/commit/a4c94986b020c5ac0fdf92bde3c7b79cdfbedbe8))\n\n## 0.0.10（2025-08-26）\n\n### ✨ Features | 新功能\n\n- 添加 easycom 组件自动扫描 ([b125039](https://github.com/anyup/uView-Pro/commit/b1250390a4f594f5deaa133d7a92bd6e72707890))\n- 增强 u-select 组件的类型安全和功能 ([38635e9](https://github.com/anyup/uView-Pro/commit/38635e963f9eff6e4c730692e8c97f10b3a092c5))\n\n## 0.0.9（2025-08-25）\n\n### ♻️ Code Refactoring | 代码重构\n\n- 优化全局工具导出方式 ([7a80b6f](https://github.com/anyup/uView-Pro/commit/7a80b6f99ad3022ca995f99f8ec6803af7941eb9))\n\n## 0.0.8（2025-08-25）\n\n### ♻️ Code Refactoring | 代码重构\n\n- 重构组件 Props 属性定义，每个组件具有完善的 ts 类型定义 ([8cc0de7](https://github.com/anyup/uView-Pro/commit/8cc0de7c1527b48dd223d89207135eea01766294))\n- 重构类型定义并统一到全局类型文件 global types ([b0fd010](https://github.com/anyup/uView-Pro/commit/b0fd0107289eb1c6df2f58d91b63d9b25902caee))\n\n## 0.0.7（2025-08-21）\n\n### 🐛 Bug Fixes | Bug 修复\n\n- 修复中 tabbar 布局高度计算错误的问题 ([5c1342c](https://github.com/anyup/uView-Pro/commit/5c1342cb3fb6dd2c7c84fe785953fcaed13e809f))\n\n### 📦‍ Build System | 打包构建\n\n- 更新项目依赖并优化打包构建 ([c172d36](https://github.com/anyup/uView-Pro/commit/c172d368d82404564650756a872cd7c7e29ebfa2))\n\n## 0.0.5（2025-08-19）\n\n### ✨ Features | 新功能\n\n- 新增 u-city-select 城市选择器组件 ([0eb4806](https://github.com/anyup/uView-Pro/commit/0eb4806db3be39e1a6c6f33c9ea511d8445da884))\n- 完善 u-button 的 open-type 支持类型 ([37c0db5](https://github.com/anyup/uView-Pro/commit/37c0db527258bca57dbd55d7013b633230489853))\n\n### 🐛 Bug Fixes | Bug 修复\n\n- u-upload 暴露 lists 属性 ([09f8424](https://github.com/anyup/uView-Pro/commit/09f8424774baaee3b6fc7a42458949f8d5903951))\n- u-upload 深度监听文件列表变化并优化事件触发 ([a41a571](https://github.com/anyup/uView-Pro/commit/a41a5719ddf9d6793b78c55a13025bbdc88fdfe3))\n\n### 🚀 Demos | 示例页面优化\n\n- 优化关于页面布局和内容 ([ad5f6a4](https://github.com/anyup/uView-Pro/commit/ad5f6a47847999268b43b8c5dbf1a34cb8f70802))\n- 删除分类数据文件 ([5ed7a11](https://github.com/anyup/uView-Pro/commit/5ed7a1113db58ff493ad606296a210358348affe))\n- 重构 index list 页面 ([13d780e](https://github.com/anyup/uView-Pro/commit/13d780ea5acc4c8eed72062482735df826d4b37a))\n- 更新商场菜单组件引用 ([a5f1bf3](https://github.com/anyup/uView-Pro/commit/a5f1bf3f256705d6cad028d60701b4b0544332de))\n- 修改图片地址 ([c459893](https://github.com/anyup/uView-Pro/commit/c459893848936aa9a44e7bda3277ab1428109869))\n- 重构 upload 上传组件示例页面 ([686831d](https://github.com/anyup/uView-Pro/commit/686831de357aca67bbf7015e2f0696cf6bf48164))\n- 优化多个组件的代码结构和样式 ([f2af44c](https://github.com/anyup/uView-Pro/commit/f2af44ca1710334495e4c4fad99d04027b3788f8))\n- 添加提交规范相关配置文件 git-cz/husky/changelog ([d93b816](https://github.com/anyup/uView-Pro/commit/d93b816a5a3e468c4bc45e3161d7c006cba5fbf6))\n- 优化 deepClone 和 deepMerge 页面的结果展示 ([b0daa70](https://github.com/anyup/uView-Pro/commit/b0daa700b6a385e037d38dc1f10b3612596e2403))\n- 新增优惠券模板 ([1b77762](https://github.com/anyup/uView-Pro/commit/1b777621615f7ebe9d83606d53650987c8b2c4e0))\n- 更新 easycom 配置说明，一定要放在 custom 里，否则不生效 ([fc14bf9](https://github.com/anyup/uView-Pro/commit/fc14bf90cb77088d258e20e79e3d25820f37e97e))\n- 添加模板示例页面 ([3336af4](https://github.com/anyup/uView-Pro/commit/3336af406161648d18578c988d9b3ad79b86059a))\n- 新增模版相关页面 ([8925a02](https://github.com/anyup/uView-Pro/commit/8925a02f9fa88f4742d984f2ff02909afc6ad0d7))\n- 重构 request 类，优化泛型支持 ([d7b2e6a](https://github.com/anyup/uView-Pro/commit/d7b2e6a224d96f717e5bdbaf09edb19b712ced47))\n\n## 0.0.4（2025-08-14）\n\n### 新增\n\n- `u-icon` 组件新增 `space` 属性，表示`label` 在四周时与图标的距离，权重高于 `margin`，单位 rpx\n- 新增`$u`工具库各类方法，同步文档\n- 组件全部 setup 化，全面支持 TypeScript 和 Vue3\n- 工具库示例页面全部 setup 化\n\n### 优化\n\n- 组件样式兼容多端\n- 代码注释与类型完善\n- 优化演示代码兼容性\n\n### 修复\n\n- 修复类型声明、变量冲突、lint 报错等问题\n\n## 0.0.3（2025-08-06）\n\n- 添加插件使用示例工程\n\n## 0.0.2（2025-08-04）\n\n- 解决一些 npm 包依赖问题\n\n## 0.0.1（2025-08-04）\n\n- 70+精选组件，使用 Vue3+TS 全面重构，功能丰富，多端兼容，让您快速集成，开箱即用\n- 兼容安卓，iOS，微信小程序，H5 等\n- 详尽的文档支持，现代化的演示效果\n- 按需引入，精简打包体积\n\n### 基础组件（8）\n\n- Color 色彩\n- Icon 图标\n- Image 图片\n- Button 按钮\n- Layout 布局\n- Cell 单元格\n- Badge 徽标数\n- Tag 标签\n\n---\n\n### 表单组件（15）\n\n- Form 表单\n- Calendar 日历\n- Select 列选择器\n- Keyboard 键盘\n- Picker 选择器\n- Rate 评分\n- Search 搜索\n- NumberBox 步进器\n- Upload 上传\n- VerificationCode 验证码倒计时\n- Field 输入框\n- Checkbox 复选框\n- Radio 单选框\n- Switch 开关选择器\n- Slider 滑动选择器\n\n---\n\n### 数据组件（4）\n\n- Progress 进度条\n- Table 表格\n- CountDown 倒计时\n- CountTo 数字滚动\n\n---\n\n### 反馈组件（10）\n\n- ActionSheet 操作菜单\n- AlertTips 警告提示\n- Toast 消息提示\n- NoticeBar 滚动通知\n- TopTips 顶部提示\n- SwipeAction 滑动单元格\n- Collapse 折叠面板\n- Popup 弹出层\n- Modal 模态框\n- fullScreen 压窗屏\n\n---\n\n### 布局组件（11）\n\n- Line 线条\n- Card 卡片\n- Mask 遮罩层\n- NoNetwork 无网络提示\n- Grid 宫格布局\n- Swiper 轮播图\n- TimeLine 时间轴\n- Skeleton 骨架屏\n- Sticky 吸顶\n- Waterfall 瀑布流\n- Divider 分割线\n\n---\n\n### 导航组件（11）\n\n- Dropdown 下拉菜单\n- Tabbar 底部导航栏\n- BackTop 返回顶部\n- Navbar 导航栏\n- Tabs 标签\n- TabsSwiper 全屏选项卡\n- Subsection 分段器\n- IndexList 索引列表\n- Steps 步骤条\n- Empty 内容为空\n- Section 查看更多\n\n---\n\n### 其他组件（8）\n\n- MessageInput 验证码输入\n- Loadmore 加载更多\n- ReadMore 展开阅读更多\n- LazyLoad 懒加载\n- Gap 间隔槽\n- Avatar 头像\n- Link 超链接\n- Loading 加载动画\n\n---\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-action-sheet/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { ActionSheetItem, ActionSheetTips } from '../../types/global';\nimport { getColor, useLocale } from '../../';\n\nconst { t } = useLocale();\n\n/**\n * actionSheet 操作菜单\n * @description 本组件用于从底部弹出一个操作菜单，供用户选择并返回结果。本组件功能类似于uni的uni.showActionSheetAPI，配置更加灵活，所有平台都表现一致。\n */\nexport const ActionSheetProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 点击遮罩是否可以关闭actionSheet */\n    maskCloseAble: { type: Boolean, default: true },\n    /** 按钮的文字数组，可以自定义颜色和字体大小，字体单位为rpx */\n    list: {\n        type: Array as unknown as PropType<ActionSheetItem[]>,\n        default: () => []\n    },\n    /** 顶部的提示文字 */\n    tips: {\n        type: Object as unknown as PropType<ActionSheetTips>,\n        default: () => ({ text: '', color: getColor('tipsColor'), fontSize: '26rpx' })\n    },\n    /** 底部的取消按钮 */\n    cancelBtn: { type: Boolean, default: true },\n    /** 是否开启底部安全区适配，开启的话，会在iPhoneX机型底部添加一定的内边距 */\n    safeAreaInsetBottom: { type: Boolean, default: false },\n    /** 通过双向绑定控制组件的弹出与收起 */\n    modelValue: { type: Boolean, default: false },\n    /** 弹出的顶部圆角值 */\n    borderRadius: { type: [String, Number], default: 0 },\n    /** 弹出的z-index值 */\n    zIndex: { type: [String, Number], default: 0 },\n    /** 取消按钮的文字提示 */\n    cancelText: { type: String, default: () => t('uActionSheet.cancelText') },\n    /** 字体颜色 */\n    color: { type: String, default: () => getColor('mainColor') },\n    /** 字体大小 */\n    fontSize: { type: [String, Number], default: '32rpx' },\n    /** 是否异步关闭 */\n    asyncClose: { type: Boolean, default: false }\n};\n\nexport type ActionSheetProps = ExtractPropTypes<typeof ActionSheetProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-action-sheet/u-action-sheet.vue",
    "content": "<template>\n    <u-popup\n        mode=\"bottom\"\n        :border-radius=\"borderRadius\"\n        :popup=\"false\"\n        v-model=\"popupValue\"\n        :maskCloseAble=\"maskCloseAble\"\n        length=\"auto\"\n        :safeAreaInsetBottom=\"safeAreaInsetBottom\"\n        @close=\"popupClose\"\n        :z-index=\"uZIndex\"\n        :custom-class=\"customClass\"\n        :custom-style=\"customStyle\"\n    >\n        <view class=\"u-tips u-border-bottom\" v-if=\"tips.text\" :style=\"[tipsStyle]\">\n            {{ tips.text }}\n        </view>\n        <block v-if=\"list && list.length > 0\" v-for=\"(item, index) in list\" :key=\"index\">\n            <view\n                @touchmove.stop.prevent\n                @tap=\"itemClick(index)\"\n                :style=\"[itemStyle(index)]\"\n                class=\"u-action-sheet-item u-line-1\"\n                :class=\"[index < list.length - 1 ? 'u-border-bottom' : '']\"\n                :hover-stay-time=\"150\"\n            >\n                <text>{{ item.text }}</text>\n                <text class=\"u-action-sheet-item__subtext u-line-1\" v-if=\"item.subText\">{{ item.subText }}</text>\n            </view>\n        </block>\n        <template v-else>\n            <slot></slot>\n        </template>\n        <view class=\"u-gab\" v-if=\"cancelBtn\"> </view>\n        <view\n            @touchmove.stop.prevent\n            class=\"u-action-sheet-cancel u-action-sheet-item\"\n            hover-class=\"u-hover-class\"\n            :hover-stay-time=\"150\"\n            v-if=\"cancelBtn\"\n            @tap=\"close\"\n        >\n            {{ cancelText }}\n        </view>\n    </u-popup>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-action-sheet',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { $u, useParent } from '../..';\nimport { ActionSheetProps } from './types';\n\n/**\n * actionSheet 操作菜单\n * @description 本组件用于从底部弹出一个操作菜单，供用户选择并返回结果。本组件功能类似于uni的uni.showActionSheetAPI，配置更加灵活，所有平台都表现一致。\n * @tutorial https://uviewpro.cn/zh/components/actionSheet.html\n * @property {Array<{ text: string; subText?: string; color?: string; fontSize?: string; disabled?: boolean }>} list 按钮的文字数组，见官方文档示例\n * @property {{text: string; color?: string; fontSize?: string}} tips 顶部的提示文字，见官方文档示例\n * @property {String} cancel-text 取消按钮的提示文字\n * @property {Boolean} cancel-btn 是否显示底部的取消按钮（默认true）\n * @property {Number String} border-radius 弹出部分顶部左右的圆角值，单位rpx（默认0）\n * @property {Boolean} mask-close-able 点击遮罩是否可以关闭（默认true）\n * @property {Boolean} safe-area-inset-bottom 是否开启底部安全区适配（默认false）\n * @property {Number String} z-index z-index值（默认1075）\n * @property {String} cancel-text 取消按钮的提示文字\n * @event {Function} click 点击ActionSheet列表项时触发\n * @event {Function} close 点击取消按钮时触发\n * @example <u-action-sheet :list=\"list\" @click=\"click\" v-model=\"show\"></u-action-sheet>\n */\n\nconst props = defineProps(ActionSheetProps);\n\nconst emit = defineEmits(['update:modelValue', 'click', 'close']);\n\nuseParent('u-action-sheet');\n\nconst popupValue = computed({\n    get: () => props.modelValue,\n    set: (val: boolean) => emit('update:modelValue', val)\n});\n\n// 顶部提示的样式\nconst tipsStyle = computed(() => {\n    let style: Record<string, string> = {};\n    style.color = String(props.tips?.color || $u.color.tipsColor);\n    style.fontSize = $u.addUnit(String(props.tips?.fontSize || '26rpx'));\n    return style;\n});\n\n// 操作项目的样式\nconst itemStyle = (index: number) => {\n    let style: Record<string, string> = {};\n    style.color = String(props.list[index]?.color || props.color);\n    style.fontSize = $u.addUnit(String(props.list[index]?.fontSize || props.fontSize));\n    // 选项被禁用的样式\n    if (props.list[index]?.disabled) style.color = String($u.color.lightColor || '');\n    return style;\n};\n\n// 计算z-index\nconst uZIndex = computed(() => {\n    // 如果用户有传递z-index值，优先使用\n    return props.zIndex ? props.zIndex : $u.zIndex.popup;\n});\n\n/**\n * 点击取消按钮\n */\nfunction close() {\n    // 发送input事件，并不会作用于父组件，而是要设置组件内部通过props传递的value参数\n    // 这是一个vue发送事件的特殊用法\n    popupClose();\n    emit('close');\n}\n\n/**\n * 弹窗关闭\n */\nfunction popupClose() {\n    emit('update:modelValue', false);\n}\n\n/**\n * 点击某一个item\n * @param index 选项索引\n */\nfunction itemClick(index: number) {\n    // disabled的项禁止点击\n    if (props.list[index]?.disabled) return;\n    emit('click', index);\n    if (props.asyncClose) return;\n    emit('update:modelValue', false);\n}\n\ndefineExpose({\n    props,\n    close,\n    itemClick\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-tips {\n    font-size: 26rpx;\n    text-align: center;\n    padding: 34rpx 0;\n    line-height: 1;\n    color: $u-tips-color;\n}\n\n.u-action-sheet-item {\n    @include vue-flex;\n    line-height: 1;\n    justify-content: center;\n    align-items: center;\n    font-size: 32rpx;\n    padding: 34rpx 0;\n    flex-direction: column;\n}\n\n.u-action-sheet-item__subtext {\n    font-size: 24rpx;\n    color: $u-tips-color;\n    margin-top: 20rpx;\n}\n\n.u-gab {\n    height: 12rpx;\n    background-color: rgb(234, 234, 236);\n}\n\n.u-action-sheet-cancel {\n    color: $u-main-color;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-action-sheet-item/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport { getColor } from '../../';\n\n/**\n * actionSheet 操作菜单\n * @description 本组件用于从底部弹出一个操作菜单，供用户选择并返回结果。本组件功能类似于uni的uni.showActionSheetAPI，配置更加灵活，所有平台都表现一致。\n */\nexport const ActionSheetItemProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 标题 */\n    text: { type: String, default: '' },\n    /** 描述 */\n    subText: { type: String, default: '' },\n    /** 边距 */\n    padding: { type: [Number, String] as PropType<number | string>, default: '34rpx 0' },\n    /** 字体颜色 */\n    color: { type: String, default: () => getColor('mainColor') },\n    /** 字体大小 */\n    fontSize: { type: [String, Number], default: '32rpx' },\n    /** 是否禁用 */\n    disabled: { type: Boolean, default: false },\n    /** 是否异步关闭 */\n    asyncClose: { type: Boolean, default: false }\n};\n\nexport type ActionSheetItemProps = ExtractPropTypes<typeof ActionSheetItemProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-action-sheet-item/u-action-sheet-item.vue",
    "content": "<template>\n    <view\n        class=\"u-action-sheet-item u-line-1\"\n        :class=\"[!isLast ? 'u-border-bottom' : '', disabled ? 'u-action-sheet-item--disabled' : '', customClass]\"\n        :style=\"$u.toStyle(itemStyle, customStyle)\"\n        @click=\"handleClick\"\n        @touchmove.stop.prevent\n        hover-class=\"u-hover-class\"\n        :hover-stay-time=\"150\"\n    >\n        <slot>\n            <text>{{ text }}</text>\n            <text class=\"u-action-sheet-item__subtext u-line-1\" v-if=\"subText\">{{ subText }}</text>\n        </slot>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-action-sheet-item',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { ActionSheetItemProps } from './types';\nimport { $u, useChildren } from '../../libs';\n\nconst props = defineProps(ActionSheetItemProps);\nconst emit = defineEmits(['click']);\n\nconst { parent, parentExposed, childIndex, emitToParent } = useChildren('u-action-sheet-item', 'u-action-sheet');\n\nconst isLast = computed(() => {\n    return (childIndex?.value ?? 0) + 1 >= (parent?.value?.getChildren()?.length ?? 0);\n});\n\nconst itemStyle = computed(() => {\n    const style: Record<string, string> = {};\n    style.color = props.color || parentExposed?.value?.props?.color;\n    style.fontSize = $u.addUnit(props.fontSize || parentExposed?.value?.props?.fontSize);\n    style.padding = $u.addUnit(props.padding);\n    if (props.disabled) style.color = 'var(--u-light-color)';\n    return style;\n});\n\nfunction handleClick() {\n    if (props.disabled) return;\n    emit('click', childIndex?.value || 0);\n    if (!props.asyncClose && !parentExposed?.value?.props?.asyncClose) {\n        emitToParent('itemClick', childIndex?.value || 0);\n    }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-action-sheet-item {\n    @include vue-flex;\n    line-height: 1;\n    justify-content: center;\n    align-items: center;\n    font-size: 32rpx;\n    padding: 34rpx 0;\n    flex-direction: column;\n}\n\n.u-action-sheet-item--disabled {\n    color: $u-light-color;\n}\n\n.u-action-sheet-item__subtext {\n    font-size: 24rpx;\n    color: $u-tips-color;\n    margin-top: 20rpx;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-alert-tips/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { ThemeType } from '../../types/global';\n\n/**\n * alertTips 警告提示\n * @description 警告提示，展现需要关注的信息\n */\nexport const AlertTipsProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 显示文字 */\n    title: { type: String, default: '' },\n    /** 主题，success/warning/info/error */\n    type: { type: String as PropType<ThemeType>, default: 'warning' },\n    /** 辅助性文字 */\n    description: { type: String, default: '' },\n    /** 是否可关闭 */\n    closeAble: { type: Boolean, default: false },\n    /** 关闭按钮自定义文本 */\n    closeText: { type: String, default: '' },\n    /** 是否显示图标 */\n    showIcon: { type: Boolean, default: false },\n    /** 文字颜色，如果定义了color值，icon会失效 */\n    color: { type: String, default: '' },\n    /** 背景颜色 */\n    bgColor: { type: String, default: '' },\n    /** 边框颜色 */\n    borderColor: { type: String, default: '' },\n    /** 是否显示 */\n    show: { type: Boolean, default: true },\n    /** 左边显示的icon */\n    icon: { type: String, default: '' },\n    /** icon的样式 */\n    iconStyle: { type: Object, default: () => ({}) },\n    /** 标题的样式 */\n    titleStyle: { type: Object, default: () => ({}) },\n    /** 描述文字的样式 */\n    descStyle: { type: Object, default: () => ({}) }\n};\n\nexport type AlertTipsProps = ExtractPropTypes<typeof AlertTipsProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-alert-tips/u-alert-tips.vue",
    "content": "<template>\n    <view\n        class=\"u-alert-tips\"\n        v-if=\"show\"\n        :class=\"[\n            !show ? 'u-close-alert-tips' : '',\n            type ? 'u-alert-tips--bg--' + type + '-light' : '',\n            type ? 'u-alert-tips--border--' + type + '-disabled' : '',\n            customClass\n        ]\"\n        :style=\"\n            $u.toStyle(\n                {\n                    backgroundColor: bgColor,\n                    borderColor: borderColor\n                },\n                customStyle\n            )\n        \"\n    >\n        <view class=\"u-icon-wrap\">\n            <u-icon\n                v-if=\"showIcon\"\n                :name=\"uIconName\"\n                :size=\"description ? 40 : 32\"\n                :color=\"uIconType\"\n                :custom-style=\"iconStyle\"\n                custom-class=\"u-tips-icon\"\n            ></u-icon>\n        </view>\n        <view class=\"u-alert-content\" @tap.stop=\"onClick\">\n            <view class=\"u-alert-title\" :style=\"uTitleStyle\">\n                {{ title }}\n            </view>\n            <view v-if=\"description\" class=\"u-alert-desc\" :style=\"descStyle\">\n                {{ description }}\n            </view>\n        </view>\n        <view class=\"u-icon-wrap\">\n            <u-icon\n                @click=\"onClose\"\n                v-if=\"closeAble && !closeText\"\n                hoverClass=\"u-type-error-hover-color\"\n                name=\"close\"\n                color=\"var(--u-tips-color)\"\n                :size=\"22\"\n                :custom-style=\"{\n                    top: description ? '18rpx' : '24rpx'\n                }\"\n                custom-class=\"u-close-icon\"\n            ></u-icon>\n        </view>\n        <text\n            v-if=\"closeAble && closeText\"\n            class=\"u-close-text\"\n            :style=\"{\n                top: description ? '18rpx' : '24rpx'\n            }\"\n        >\n            {{ closeText }}\n        </text>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-alert-tips',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { $u } from '../..';\nimport { AlertTipsProps } from './types';\n\n/**\n * alertTips 警告提示\n * @description 警告提示，展现需要关注的信息\n * @tutorial https://uviewpro.cn/zh/components/alertTips.html\n * @property {String} title 显示的标题文字\n * @property {String} description 辅助性文字，颜色比title浅一点，字号也小一点，可选\n * @property {String} type 关闭按钮(默认为叉号icon图标)\n * @property {String} icon 图标名称\n * @property {Object} icon-style 图标的样式，对象形式\n * @property {Object} title-style 标题的样式，对象形式\n * @property {Object} desc-style 描述的样式，对象形式\n * @property {String} close-able 用文字替代关闭图标，close-able为true时有效\n * @property {Boolean} show-icon 是否显示左边的辅助图标\n * @property {Boolean} show 显示或隐藏组件\n * @event {Function} click 点击组件时触发\n * @event {Function} close 点击关闭按钮时触发\n */\n\nconst props = defineProps(AlertTipsProps);\n\nconst emit = defineEmits(['click', 'close']);\n\n/**\n * 标题样式，合并加粗和用户自定义样式\n */\nconst uTitleStyle = computed(() => {\n    let style: Record<string, any> = {};\n    // 如果有描述文字的话，标题进行加粗\n    style.fontWeight = props.description ? 500 : 'normal';\n    // 将用户传入样式对象和style合并，传入的优先级比style高，同属性会被覆盖\n    return $u.deepMerge(style, props.titleStyle);\n});\n\n/**\n * 图标名称，优先使用用户传入，否则根据type主题推定默认图标\n */\nconst uIconName = computed(() => {\n    // 如果有设置icon名称就使用，否则根据type主题，推定一个默认的图标\n    return props.icon ? props.icon : $u.type2icon(props.type as any);\n});\n\n/**\n * 图标类型，优先使用iconStyle，否则用type\n */\nconst uIconType = computed(() => {\n    // 如果有设置图标的样式，优先使用，没有的话，则用type的样式\n    return Object.keys(props.iconStyle).length ? '' : props.type;\n});\n\n/**\n * 点击内容\n */\nfunction onClick() {\n    emit('click');\n}\n\n/**\n * 点击关闭按钮\n */\nfunction onClose() {\n    emit('close');\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-alert-tips {\n    @include vue-flex;\n    align-items: center;\n    padding: 16rpx 30rpx;\n    border-radius: 8rpx;\n    position: relative;\n    transition: all 0.3s linear;\n    border: 1px solid var(--u-white-color);\n\n    &--bg--primary-light {\n        background-color: $u-type-primary-light;\n    }\n\n    &--bg--info-light {\n        background-color: $u-type-info-light;\n    }\n\n    &--bg--success-light {\n        background-color: $u-type-success-light;\n    }\n\n    &--bg--warning-light {\n        background-color: $u-type-warning-light;\n    }\n\n    &--bg--error-light {\n        background-color: $u-type-error-light;\n    }\n\n    &--border--primary-disabled {\n        border-color: $u-type-primary-disabled;\n    }\n\n    &--border--success-disabled {\n        border-color: $u-type-success-disabled;\n    }\n\n    &--border--error-disabled {\n        border-color: $u-type-error-disabled;\n    }\n\n    &--border--warning-disabled {\n        border-color: $u-type-warning-disabled;\n    }\n\n    &--border--info-disabled {\n        border-color: $u-type-info-disabled;\n    }\n\n    :deep(.u-tips-icon) {\n        margin-right: 16rpx;\n    }\n\n    :deep(.u-close-icon) {\n        position: absolute;\n        right: 20rpx;\n        cursor: pointer;\n    }\n}\n\n.u-close-alert-tips {\n    opacity: 0;\n    visibility: hidden;\n}\n\n.u-alert-title {\n    font-size: 28rpx;\n    color: $u-main-color;\n}\n\n.u-alert-desc {\n    font-size: 26rpx;\n    text-align: left;\n    color: $u-content-color;\n}\n\n.u-close-hover {\n    color: red;\n}\n\n.u-close-text {\n    font-size: 24rpx;\n    color: $u-tips-color;\n    position: absolute;\n    top: 20rpx;\n    right: 20rpx;\n    line-height: 1;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-avatar/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { ImgMode } from '../../types/global';\n\n// u-avatar 组件 props\nexport const AvatarProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 背景颜色 */\n    bgColor: { type: String, default: 'transparent' },\n    /** 头像路径 */\n    src: { type: String, default: '' },\n    /** 尺寸，large-大，default-中等，mini-小，如果为数值，则单位为rpx，宽度等于高度 */\n    size: { type: [String, Number], default: 'default' },\n    /** 头像模型，square-带圆角方形，circle-圆形 */\n    mode: { type: String, default: 'circle' },\n    /** 文字内容 */\n    text: { type: String, default: '' },\n    /** 图片的裁剪模型 */\n    imgMode: { type: String as PropType<ImgMode>, default: 'aspectFill' },\n    /** 标识符 */\n    index: { type: [String, Number], default: '' },\n    /** 右上角性别角标，man-男，woman-女 */\n    sexIcon: { type: String as PropType<'man' | 'woman'>, default: 'man' },\n    /** 右下角的等级图标 */\n    levelIcon: { type: String, default: 'level' },\n    /** 右下角等级图标背景颜色 */\n    levelBgColor: { type: String, default: '' },\n    /** 右上角性别图标的背景颜色 */\n    sexBgColor: { type: String, default: '' },\n    /** 是否显示性别图标 */\n    showSex: { type: Boolean, default: false },\n    /** 是否显示等级图标 */\n    showLevel: { type: Boolean, default: false }\n};\n\nexport type AvatarProps = ExtractPropTypes<typeof AvatarProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-avatar/u-avatar.vue",
    "content": "<template>\n    <view class=\"u-avatar\" :class=\"customClass\" :style=\"$u.toStyle(wrapStyle, customStyle)\" @tap=\"onClick\">\n        <image\n            @error=\"onLoadError\"\n            :style=\"imgStyle\"\n            class=\"u-avatar__img\"\n            v-if=\"!uText && avatar\"\n            :src=\"avatar\"\n            :mode=\"imgMode\"\n        ></image>\n        <text class=\"u-line-1\" v-else-if=\"uText\" :style=\"{ fontSize: '38rpx' }\">{{ uText }}</text>\n        <slot v-else></slot>\n        <view class=\"u-avatar__sex\" v-if=\"showSex\" :class=\"['u-avatar__sex--' + sexIcon]\" :style=\"uSexStyle\">\n            <u-icon :name=\"sexIcon\" size=\"20\"></u-icon>\n        </view>\n        <view class=\"u-avatar__level\" v-if=\"showLevel\" :style=\"uLevelStyle\">\n            <u-icon :name=\"levelIcon\" size=\"20\"></u-icon>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-avatar',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch } from 'vue';\nimport { AvatarProps } from './types';\nimport { $u } from '../..';\n\nconst base64Avatar =\n    'data:image/jpg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAA8AAD/4QMraHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjMtYzAxMSA2Ni4xNDU2NjEsIDIwMTIvMDIvMDYtMTQ6NTY6MjcgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzYgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjREMEQwRkY0RjgwNDExRUE5OTY2RDgxODY3NkJFODMxIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjREMEQwRkY1RjgwNDExRUE5OTY2RDgxODY3NkJFODMxIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NEQwRDBGRjJGODA0MTFFQTk5NjZEODE4Njc2QkU4MzEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NEQwRDBGRjNGODA0MTFFQTk5NjZEODE4Njc2QkU4MzEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAAGBAQEBQQGBQUGCQYFBgkLCAYG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';\n\n/**\n * avatar 头像\n * @description 本组件一般用于展示头像的地方，如个人中心，或者评论列表页的用户头像展示等场所。\n * @tutorial https://uviewpro.cn/zh/components/avatar.html\n * @property {String} bg-color 背景颜色，一般显示文字时用（默认var(--u-bg-white)）\n * @property {String} src 头像路径，如加载失败，将会显示默认头像\n * @property {String Number} size 头像尺寸，可以为指定字符串(large, default, mini)，或者数值，单位rpx（默认default）\n * @property {String} mode 显示类型，见上方说明（默认circle）\n * @property {String} sex-icon 性别图标，man-男，woman-女（默认man）\n * @property {String} level-icon 等级图标（默认level）\n * @property {String} sex-bg-color 性别图标背景颜色\n * @property {String} level-bg-color 等级图标背景颜色\n * @property {String} show-sex 是否显示性别图标（默认false）\n * @property {String} show-level 是否显示等级图标（默认false）\n * @property {String} img-mode 头像图片的裁剪类型，与uni的image组件的mode参数一致，如效果达不到需求，可尝试传widthFix值（默认aspectFill）\n * @property {String} index 用户传递的标识符值，如果是列表循环，可穿v-for的index值\n * @event {Function} click 头像被点击\n * @example <u-avatar :src=\"src\"></u-avatar>\n */\nconst props = defineProps(AvatarProps);\nconst emit = defineEmits(['click']);\n\n// 头像的地址，因为如果加载错误，需要赋值为默认图片，props值无法修改，所以需要一个中间值\nconst avatar = ref(props.src ? props.src : base64Avatar);\nconst error = ref(false);\n\n// 用户可能会在头像加载失败时，再次修改头像值，所以需要重新赋值\nwatch(\n    () => props.src,\n    n => {\n        if (!n) {\n            // 如果传入null或者''，或者undefined，显示默认头像\n            avatar.value = base64Avatar;\n            error.value = true;\n        } else {\n            avatar.value = n;\n            error.value = false;\n        }\n    }\n);\n\n/**\n * 头像外层样式\n */\nconst wrapStyle = computed(() => {\n    let style: Record<string, string> = {};\n    style.height =\n        props.size === 'large'\n            ? '120rpx'\n            : props.size === 'default'\n              ? '90rpx'\n              : props.size === 'mini'\n                ? '70rpx'\n                : props.size + 'rpx';\n    style.width = style.height;\n    style.flex = `0 0 ${style.height}`;\n    style.backgroundColor = props.bgColor;\n    style.borderRadius = props.mode === 'circle' ? '500px' : '5px';\n    if (props.text) style.padding = '0 6rpx';\n    return style;\n});\n\n/**\n * 图片样式\n */\nconst imgStyle = computed(() => {\n    let style: Record<string, string> = {};\n    style.borderRadius = props.mode === 'circle' ? '500px' : '5px';\n    return style;\n});\n\n/**\n * 取字符串的第一个字符\n */\nconst uText = computed(() => {\n    return String(props.text)[0];\n});\n\n/**\n * 性别图标的自定义样式\n */\nconst uSexStyle = computed(() => {\n    let style: Record<string, string> = {};\n    if (props.sexBgColor) style.backgroundColor = props.sexBgColor;\n    return style;\n});\n\n/**\n * 等级图标的自定义样式\n */\nconst uLevelStyle = computed(() => {\n    let style: Record<string, string> = {};\n    if (props.levelBgColor) style.backgroundColor = props.levelBgColor;\n    return style;\n});\n\n/**\n * 图片加载错误时，显示默认头像\n */\nfunction onLoadError() {\n    error.value = true;\n    avatar.value = base64Avatar;\n}\n\n/**\n * 头像被点击\n */\nfunction onClick() {\n    emit('click', props.index);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-avatar {\n    /* #ifndef APP-NVUE */\n    display: inline-flex;\n    /* #endif */\n    align-items: center;\n    justify-content: center;\n    font-size: 28rpx;\n    color: $u-content-color;\n    border-radius: 10px;\n    position: relative;\n\n    &__img {\n        width: 100%;\n        height: 100%;\n    }\n\n    &__sex {\n        position: absolute;\n        width: 32rpx;\n        color: var(--u-white-color);\n        height: 32rpx;\n        @include vue-flex;\n        justify-content: center;\n        align-items: center;\n        border-radius: 100rpx;\n        top: 5%;\n        z-index: 1;\n        right: -7%;\n        border: 1px var(--u-white-color) solid;\n\n        &--man {\n            background-color: $u-type-primary;\n        }\n\n        &--woman {\n            background-color: $u-type-error;\n        }\n\n        &--none {\n            background-color: $u-type-warning;\n        }\n    }\n\n    &__level {\n        position: absolute;\n        width: 32rpx;\n        color: var(--u-white-color);\n        height: 32rpx;\n        @include vue-flex;\n        justify-content: center;\n        align-items: center;\n        border-radius: 100rpx;\n        bottom: 5%;\n        z-index: 1;\n        right: -7%;\n        border: 1px var(--u-white-color) solid;\n        background-color: $u-type-warning;\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-avatar-cropper/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { AvatarCropperBoundStyle } from '../../types/global';\n\nexport const AvatarCropperProps = {\n    /** 裁剪矩形框的样式 */\n    boundStyle: {\n        type: Object as PropType<AvatarCropperBoundStyle>,\n        default: (): AvatarCropperBoundStyle => ({\n            lineWidth: 4,\n            borderColor: 'rgb(245, 245, 245)',\n            mask: 'rgba(0, 0, 0, 0.35)'\n        })\n    }\n    // 其他 props 可参考注释，后续如需开放直接补充\n    // rectWidth: { type: [String, Number], default: 400 },\n    // rectHeight: { type: [String, Number], default: 400 },\n    // destWidth: { type: [String, Number], default: 400 },\n    // destHeight: { type: [String, Number], default: 400 },\n    // fileType: { type: String, default: 'jpg' },\n    // quality: { type: [Number, String], default: 1 }\n};\n\nexport type AvatarCropperProps = ExtractPropTypes<typeof AvatarCropperProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-avatar-cropper/u-avatar-cropper.vue",
    "content": "<template>\n    <view class=\"content\">\n        <view class=\"cropper-wrapper\" :style=\"{ height: cropperOpt.height + 'px' }\">\n            <canvas\n                class=\"cropper\"\n                :disable-scroll=\"true\"\n                @touchstart=\"touchStart\"\n                @touchmove=\"touchMove\"\n                @touchend=\"touchEnd\"\n                :style=\"{ width: cropperOpt.width, height: cropperOpt.height, backgroundColor: 'rgba(0, 0, 0, 0.8)' }\"\n                canvas-id=\"cropper\"\n                id=\"cropper\"\n            ></canvas>\n            <canvas\n                class=\"cropper\"\n                :disable-scroll=\"true\"\n                :style=\"{\n                    position: 'fixed',\n                    top: `-${cropperOpt.width * cropperOpt.pixelRatio}px`,\n                    left: `-${cropperOpt.height * cropperOpt.pixelRatio}px`,\n                    width: `${cropperOpt.width * cropperOpt.pixelRatio}px`,\n                    height: `${cropperOpt.height * cropperOpt.pixelRatio}`\n                }\"\n                canvas-id=\"targetId\"\n                id=\"targetId\"\n            ></canvas>\n        </view>\n        <view class=\"cropper-buttons safe-area-padding\" :style=\"{ height: bottomNavHeight + 'px' }\">\n            <!-- #ifdef H5 -->\n            <view class=\"upload\" @tap=\"uploadTap\">{{ t('avatarCropper.select') }}</view>\n            <!-- #endif -->\n            <!-- #ifndef H5 -->\n            <view class=\"upload\" @tap=\"uploadTap\">{{ t('avatarCropper.reselect') }}</view>\n            <!-- #endif -->\n            <view class=\"getCropperImage\" @tap=\"() => getCropperImage(false)\">{{ t('avatarCropper.confirm') }}</view>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-avatar-cropper',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\n// @ts-nocheck\nimport { ref, reactive, onMounted } from 'vue';\nimport { $u, useLocale } from '../..';\n// 兼容 UMD/ESM 导入 weCropper.js\nimport WeCropper from './weCropper';\nimport { AvatarCropperProps } from './types';\n\n/**\n * 裁剪矩形框的样式，其中可包含的属性为lineWidth-边框宽度(单位rpx)，color: 边框颜色，\n * mask-遮罩颜色，一般设置为一个rgba的透明度，如\"rgba(0, 0, 0, 0.35)\"\n */\nconst props = defineProps(AvatarCropperProps);\n\nconst { t } = useLocale();\n\n/**\n * 组合式API变量声明\n * 保留所有说明注释\n */\nconst bottomNavHeight = ref(50); // 底部导航的高度\nconst originWidth = ref(200);\nconst width = ref(0);\nconst height = ref(0);\nconst src = ref(''); // 选择的图片路径，用于在点击确定时，判断是否选择了图片\nconst destWidth = ref(200); // 输出图片宽度，单位px\nconst rectWidth = ref(200); // 裁剪框宽度，单位px\nconst fileType = ref('jpg'); // 输出的图片类型，如果'png'类型发现裁剪的图片太大，改成\"jpg\"即可\n\n// cropperOpt 需响应式，且类型安全\nconst cropperOpt = reactive({\n    id: 'cropper',\n    targetId: 'targetCropper',\n    pixelRatio: 1,\n    width: 0,\n    height: 0,\n    scale: 2.5,\n    zoom: 8,\n    cut: {\n        x: 0,\n        y: 0,\n        width: originWidth.value,\n        height: originWidth.value\n    },\n    boundStyle: {\n        lineWidth: 0,\n        mask: '',\n        color: ''\n    }\n});\n\nlet cropper: any = null; // WeCropper 实例，类型 any，建议后续补充类型声明\n\n/**\n * 组件挂载时初始化 cropper\n * 保留所有说明注释\n */\nonMounted(() => {\n    // 获取系统信息\n    const rectInfo = uni.getSystemInfoSync();\n    width.value = rectInfo.windowWidth;\n    height.value = rectInfo.windowHeight - bottomNavHeight.value;\n    cropperOpt.width = width.value;\n    cropperOpt.height = height.value;\n    cropperOpt.pixelRatio = rectInfo.pixelRatio;\n\n    // 初始化裁剪框\n    cropperOpt.cut = {\n        x: (width.value - originWidth.value) / 2,\n        y: (height.value - originWidth.value) / 2,\n        width: originWidth.value,\n        height: originWidth.value\n    };\n    cropperOpt.boundStyle = {\n        lineWidth: uni.upx2px(props.boundStyle.lineWidth),\n        mask: props.boundStyle.mask,\n        color: props.boundStyle.borderColor\n    };\n\n    // 设置导航栏样式，以免用户在page.json中没有设置为黑色背景\n    uni.setNavigationBarColor({\n        frontColor: 'var(--u-white-color)',\n        backgroundColor: 'var(--u-bg-black)'\n    });\n\n    // 初始化 cropper 实例\n    cropper = new WeCropper(cropperOpt)\n        .on('ready', (ctx: any) => {\n            // wecropper is ready for work!\n        })\n        .on('beforeImageLoad', (ctx: any) => {\n            // before picture loaded, i can do something\n        })\n        .on('imageLoad', (ctx: any) => {\n            // picture loaded\n        })\n        .on('beforeDraw', (ctx: any, instance: any) => {\n            // before canvas draw,i can do something\n        });\n\n    // 选择图片\n    uni.chooseImage({\n        count: 1, // 默认9\n        sizeType: ['compressed'], // 可以指定是原图还是压缩图，默认二者都有\n        sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机，默认二者都有\n        success: (res: UniApp.ChooseImageSuccessCallbackResult) => {\n            src.value = res.tempFilePaths[0];\n            //  获取裁剪图片资源后，给data添加src属性及其值\n            cropper.pushOrign(src.value);\n        }\n    });\n});\n\n/**\n * 触摸开始事件\n * @param e 事件对象\n */\nfunction touchStart(e: any) {\n    cropper && cropper.touchStart(e);\n}\n\n/**\n * 触摸移动事件\n * @param e 事件对象\n */\nfunction touchMove(e: any) {\n    cropper && cropper.touchMove(e);\n}\n\n/**\n * 触摸结束事件\n * @param e 事件对象\n */\nfunction touchEnd(e: any) {\n    cropper && cropper.touchEnd(e);\n}\n\n/**\n * 获取裁剪后的图片\n * @param isPre 是否预览\n */\nfunction getCropperImage(isPre = false) {\n    if (!src.value) return $u.toast(t('avatarCropper.noSelect'));\n\n    const cropper_opt = {\n        destHeight: Number(destWidth.value), // uni.canvasToTempFilePath要求这些参数为数值\n        destWidth: Number(destWidth.value),\n        fileType: fileType.value\n    };\n    cropper.getCropperImage(cropper_opt, (path: string, err: any) => {\n        if (err) {\n            uni.showModal({\n                title: t('avatarCropper.modalTitle'),\n                content: err.message\n            });\n        } else {\n            if (isPre) {\n                uni.previewImage({\n                    current: '', // 当前显示图片的 http 链接\n                    urls: [path] // 需要预览的图片 http 链接列表\n                });\n            } else {\n                uni.$emit('uAvatarCropper', path);\n                $u.route({\n                    type: 'back'\n                });\n            }\n        }\n    });\n}\n\n/**\n * 重新选择图片\n */\nfunction uploadTap() {\n    uni.chooseImage({\n        count: 1, // 默认9\n        sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图，默认二者都有\n        sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机，默认二者都有\n        success: (res: UniApp.ChooseImageSuccessCallbackResult) => {\n            src.value = res.tempFilePaths[0];\n            //  获取裁剪图片资源后，给data添加src属性及其值\n            cropper.pushOrign(src.value);\n        }\n    });\n}\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n\n.content {\n    background: rgba(255, 255, 255, 1);\n}\n\n.cropper {\n    position: absolute;\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%;\n    z-index: 11;\n}\n\n.cropper-buttons {\n    background-color: var(--u-bg-black);\n    color: var(--u-divider-color);\n}\n\n.cropper-wrapper {\n    position: relative;\n    @include vue-flex;\n    flex-direction: row;\n    justify-content: space-between;\n    align-items: center;\n    width: 100%;\n    background-color: var(--u-bg-black);\n}\n\n.cropper-buttons {\n    width: 100vw;\n    @include vue-flex;\n    flex-direction: row;\n    justify-content: space-between;\n    align-items: center;\n    position: fixed;\n    bottom: 0;\n    left: 0;\n    font-size: 28rpx;\n}\n\n.cropper-buttons .upload,\n.cropper-buttons .getCropperImage {\n    width: 50%;\n    text-align: center;\n}\n\n.cropper-buttons .upload {\n    text-align: left;\n    padding-left: 50rpx;\n}\n\n.cropper-buttons .getCropperImage {\n    text-align: right;\n    padding-right: 50rpx;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-avatar-cropper/weCropper.d.ts",
    "content": "// @ts-nocheck\n/**\n * we-cropper 类型声明文件\n * 适用于 Vue3 + TypeScript 项目中 weCropper.js 的类型提示\n */\n\nexport interface WeCropperOptions {\n    id?: string;\n    targetId?: string;\n    pixelRatio?: number;\n    width?: number;\n    height?: number;\n    scale?: number;\n    zoom?: number;\n    cut?: {\n        x?: number;\n        y?: number;\n        width?: number;\n        height?: number;\n    };\n    boundStyle?: {\n        lineWidth?: number;\n        borderColor?: string;\n        mask?: string;\n        color?: string;\n    };\n    [key: string]: any;\n}\n\nexport type WeCropperEvent = (ctx: any, instance?: any) => void;\n\nexport interface WeCropperInstance {\n    pushOrign(src: string): Promise<void>;\n    pushOrigin(src: string): Promise<void>;\n    removeImage(): Promise<void>;\n    getCropperBase64(done?: (base64: string) => void): void;\n    getCropperImage(opt: any, fn: (path: string, err: any) => void): void;\n    update(): void;\n    touchStart(e: any): void;\n    touchMove(e: any): void;\n    touchEnd(e: any): void;\n    on(event: 'ready' | 'beforeImageLoad' | 'imageLoad' | 'beforeDraw', fn: WeCropperEvent): WeCropperInstance;\n    // 其它动态方法\n    [key: string]: any;\n}\n\n// WeCropper 类型声明文件\ndeclare class WeCropper {\n    constructor(params: any);\n\n    // 事件方法\n    on(event: string, callback: (ctx?: any) => void): WeCropper;\n\n    // 其他方法\n    pushOrign(src: string): void;\n    getCropperImage(callback?: (tempFilePath: string) => void): void;\n\n    // 属性\n    [key: string]: any;\n}\n\nexport default WeCropper;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-avatar-cropper/weCropper.js",
    "content": "// @ts-nocheck\n/**\n * we-cropper v1.3.9\n * (c) 2020 dlhandsome\n * @license MIT\n */\n(function (global, factory) {\n    typeof exports === 'object' && typeof module !== 'undefined'\n        ? (module.exports = factory())\n        : typeof define === 'function' && define.amd\n          ? define(factory)\n          : (global.WeCropper = factory());\n})(this, function () {\n    'use strict';\n\n    var device = void 0;\n    var TOUCH_STATE = ['touchstarted', 'touchmoved', 'touchended'];\n\n    function firstLetterUpper(str) {\n        return str.charAt(0).toUpperCase() + str.slice(1);\n    }\n\n    function setTouchState(instance) {\n        var arg = [],\n            len = arguments.length - 1;\n        while (len-- > 0) arg[len] = arguments[len + 1];\n\n        TOUCH_STATE.forEach(function (key, i) {\n            if (arg[i] !== undefined) {\n                instance[key] = arg[i];\n            }\n        });\n    }\n\n    function validator(instance, o) {\n        Object.defineProperties(instance, o);\n    }\n\n    function getDevice() {\n        if (!device) {\n            device = uni.getSystemInfoSync();\n        }\n        return device;\n    }\n\n    var tmp = {};\n\n    var ref = getDevice();\n    var pixelRatio = ref.pixelRatio;\n\n    var DEFAULT = {\n        id: {\n            default: 'cropper',\n            get: function get() {\n                return tmp.id;\n            },\n            set: function set(value) {\n                if (typeof value !== 'string') {\n                    console.error('id：' + value + ' is invalid');\n                }\n                tmp.id = value;\n            }\n        },\n        width: {\n            default: 750,\n            get: function get() {\n                return tmp.width;\n            },\n            set: function set(value) {\n                if (typeof value !== 'number') {\n                    console.error('width：' + value + ' is invalid');\n                }\n                tmp.width = value;\n            }\n        },\n        height: {\n            default: 750,\n            get: function get() {\n                return tmp.height;\n            },\n            set: function set(value) {\n                if (typeof value !== 'number') {\n                    console.error('height：' + value + ' is invalid');\n                }\n                tmp.height = value;\n            }\n        },\n        pixelRatio: {\n            default: pixelRatio,\n            get: function get() {\n                return tmp.pixelRatio;\n            },\n            set: function set(value) {\n                if (typeof value !== 'number') {\n                    console.error('pixelRatio：' + value + ' is invalid');\n                }\n                tmp.pixelRatio = value;\n            }\n        },\n        scale: {\n            default: 2.5,\n            get: function get() {\n                return tmp.scale;\n            },\n            set: function set(value) {\n                if (typeof value !== 'number') {\n                    console.error('scale：' + value + ' is invalid');\n                }\n                tmp.scale = value;\n            }\n        },\n        zoom: {\n            default: 5,\n            get: function get() {\n                return tmp.zoom;\n            },\n            set: function set(value) {\n                if (typeof value !== 'number') {\n                    console.error('zoom：' + value + ' is invalid');\n                } else if (value < 0 || value > 10) {\n                    console.error('zoom should be ranged in 0 ~ 10');\n                }\n                tmp.zoom = value;\n            }\n        },\n        src: {\n            default: '',\n            get: function get() {\n                return tmp.src;\n            },\n            set: function set(value) {\n                if (typeof value !== 'string') {\n                    console.error('src：' + value + ' is invalid');\n                }\n                tmp.src = value;\n            }\n        },\n        cut: {\n            default: {},\n            get: function get() {\n                return tmp.cut;\n            },\n            set: function set(value) {\n                if (typeof value !== 'object') {\n                    console.error('cut：' + value + ' is invalid');\n                }\n                tmp.cut = value;\n            }\n        },\n        boundStyle: {\n            default: {},\n            get: function get() {\n                return tmp.boundStyle;\n            },\n            set: function set(value) {\n                if (typeof value !== 'object') {\n                    console.error('boundStyle：' + value + ' is invalid');\n                }\n                tmp.boundStyle = value;\n            }\n        },\n        onReady: {\n            default: null,\n            get: function get() {\n                return tmp.ready;\n            },\n            set: function set(value) {\n                tmp.ready = value;\n            }\n        },\n        onBeforeImageLoad: {\n            default: null,\n            get: function get() {\n                return tmp.beforeImageLoad;\n            },\n            set: function set(value) {\n                tmp.beforeImageLoad = value;\n            }\n        },\n        onImageLoad: {\n            default: null,\n            get: function get() {\n                return tmp.imageLoad;\n            },\n            set: function set(value) {\n                tmp.imageLoad = value;\n            }\n        },\n        onBeforeDraw: {\n            default: null,\n            get: function get() {\n                return tmp.beforeDraw;\n            },\n            set: function set(value) {\n                tmp.beforeDraw = value;\n            }\n        }\n    };\n\n    var ref$1 = getDevice();\n    var windowWidth = ref$1.windowWidth;\n\n    function prepare() {\n        var self = this;\n\n        // v1.4.0 版本中将不再自动绑定we-cropper实例\n        self.attachPage = function () {\n            var pages = getCurrentPages();\n            // 获取到当前page上下文\n            var pageContext = pages[pages.length - 1];\n            // 把this依附在Page上下文的wecropper属性上，便于在page钩子函数中访问\n            Object.defineProperty(pageContext, 'wecropper', {\n                get: function get() {\n                    console.warn(\n                        'Instance will not be automatically bound to the page after v1.4.0\\n\\n' +\n                            'Please use a custom instance name instead\\n\\n' +\n                            'Example: \\n' +\n                            'this.mycropper = new WeCropper(options)\\n\\n' +\n                            '// ...\\n' +\n                            'this.mycropper.getCropperImage()'\n                    );\n                    return self;\n                },\n                configurable: true\n            });\n        };\n\n        self.createCtx = function () {\n            var id = self.id;\n            var targetId = self.targetId;\n\n            if (id) {\n                self.ctx = self.ctx || uni.createCanvasContext(id);\n                self.targetCtx = self.targetCtx || uni.createCanvasContext(targetId);\n            } else {\n                console.error(\"constructor: create canvas context failed, 'id' must be valuable\");\n            }\n        };\n\n        self.deviceRadio = windowWidth / 750;\n    }\n\n    var commonjsGlobal =\n        typeof window !== 'undefined'\n            ? window\n            : typeof global !== 'undefined'\n              ? global\n              : typeof self !== 'undefined'\n                ? self\n                : {};\n\n    function createCommonjsModule(fn, module) {\n        return (\n            (module = {\n                exports: {}\n            }),\n            fn(module, module.exports),\n            module.exports\n        );\n    }\n\n    var tools = createCommonjsModule(function (module, exports) {\n        /**\n         * String type check\n         */\n        exports.isStr = function (v) {\n            return typeof v === 'string';\n        };\n        /**\n         * Number type check\n         */\n        exports.isNum = function (v) {\n            return typeof v === 'number';\n        };\n        /**\n         * Array type check\n         */\n        exports.isArr = Array.isArray;\n        /**\n         * undefined type check\n         */\n        exports.isUndef = function (v) {\n            return v === undefined;\n        };\n\n        exports.isTrue = function (v) {\n            return v === true;\n        };\n\n        exports.isFalse = function (v) {\n            return v === false;\n        };\n        /**\n         * Function type check\n         */\n        exports.isFunc = function (v) {\n            return typeof v === 'function';\n        };\n        /**\n         * Quick object check - this is primarily used to tell\n         * Objects from primitive values when we know the value\n         * is a JSON-compliant type.\n         */\n        exports.isObj = exports.isObject = function (obj) {\n            return obj !== null && typeof obj === 'object';\n        };\n\n        /**\n         * Strict object type check. Only returns true\n         * for plain JavaScript objects.\n         */\n        var _toString = Object.prototype.toString;\n        exports.isPlainObject = function (obj) {\n            return _toString.call(obj) === '[object Object]';\n        };\n\n        /**\n         * Check whether the object has the property.\n         */\n        var hasOwnProperty = Object.prototype.hasOwnProperty;\n        exports.hasOwn = function (obj, key) {\n            return hasOwnProperty.call(obj, key);\n        };\n\n        /**\n         * Perform no operation.\n         * Stubbing args to make Flow happy without leaving useless transpiled code\n         * with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/)\n         */\n        exports.noop = function (a, b, c) {};\n\n        /**\n         * Check if val is a valid array index.\n         */\n        exports.isValidArrayIndex = function (val) {\n            var n = parseFloat(String(val));\n            return n >= 0 && Math.floor(n) === n && isFinite(val);\n        };\n    });\n\n    var tools_7 = tools.isFunc;\n    var tools_10 = tools.isPlainObject;\n\n    var EVENT_TYPE = ['ready', 'beforeImageLoad', 'beforeDraw', 'imageLoad'];\n\n    function observer() {\n        var self = this;\n\n        self.on = function (event, fn) {\n            if (EVENT_TYPE.indexOf(event) > -1) {\n                if (tools_7(fn)) {\n                    event === 'ready' ? fn(self) : (self['on' + firstLetterUpper(event)] = fn);\n                }\n            } else {\n                console.error('event: ' + event + ' is invalid');\n            }\n            return self;\n        };\n    }\n\n    function wxPromise(fn) {\n        return function (obj) {\n            var args = [],\n                len = arguments.length - 1;\n            while (len-- > 0) args[len] = arguments[len + 1];\n\n            if (obj === void 0) obj = {};\n            return new Promise(function (resolve, reject) {\n                obj.success = function (res) {\n                    resolve(res);\n                };\n                obj.fail = function (err) {\n                    reject(err);\n                };\n                fn.apply(void 0, [obj].concat(args));\n            });\n        };\n    }\n\n    function draw(ctx, reserve) {\n        if (reserve === void 0) reserve = false;\n\n        return new Promise(function (resolve) {\n            ctx.draw(reserve, resolve);\n        });\n    }\n\n    var getImageInfo = wxPromise(uni.getImageInfo);\n\n    var canvasToTempFilePath = wxPromise(uni.canvasToTempFilePath);\n\n    var base64 = createCommonjsModule(function (module, exports) {\n        /*! http://mths.be/base64 v0.1.0 by @mathias | MIT license */\n        (function (root) {\n            // Detect free variables `exports`.\n            var freeExports = 'object' == 'object' && exports;\n\n            // Detect free variable `module`.\n            var freeModule = 'object' == 'object' && module && module.exports == freeExports && module;\n\n            // Detect free variable `global`, from Node.js or Browserified code, and use\n            // it as `root`.\n            var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal;\n            if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {\n                root = freeGlobal;\n            }\n\n            /*--------------------------------------------------------------------------*/\n\n            var InvalidCharacterError = function (message) {\n                this.message = message;\n            };\n            InvalidCharacterError.prototype = new Error();\n            InvalidCharacterError.prototype.name = 'InvalidCharacterError';\n\n            var error = function (message) {\n                // Note: the error messages used throughout this file match those used by\n                // the native `atob`/`btoa` implementation in Chromium.\n                throw new InvalidCharacterError(message);\n            };\n\n            var TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n            // http://whatwg.org/html/common-microsyntaxes.html#space-character\n            var REGEX_SPACE_CHARACTERS = /[\\t\\n\\f\\r ]/g;\n\n            // `decode` is designed to be fully compatible with `atob` as described in the\n            // HTML Standard. http://whatwg.org/html/webappapis.html#dom-windowbase64-atob\n            // The optimized base64-decoding algorithm used is based on @atk’s excellent\n            // implementation. https://gist.github.com/atk/1020396\n            var decode = function (input) {\n                input = String(input).replace(REGEX_SPACE_CHARACTERS, '');\n                var length = input.length;\n                if (length % 4 == 0) {\n                    input = input.replace(/==?$/, '');\n                    length = input.length;\n                }\n                if (\n                    length % 4 == 1 ||\n                    // http://whatwg.org/C#alphanumeric-ascii-characters\n                    /[^+a-zA-Z0-9/]/.test(input)\n                ) {\n                    error('Invalid character: the string to be decoded is not correctly encoded.');\n                }\n                var bitCounter = 0;\n                var bitStorage;\n                var buffer;\n                var output = '';\n                var position = -1;\n                while (++position < length) {\n                    buffer = TABLE.indexOf(input.charAt(position));\n                    bitStorage = bitCounter % 4 ? bitStorage * 64 + buffer : buffer;\n                    // Unless this is the first of a group of 4 characters…\n                    if (bitCounter++ % 4) {\n                        // …convert the first 8 bits to a single ASCII character.\n                        output += String.fromCharCode(0xff & (bitStorage >> ((-2 * bitCounter) & 6)));\n                    }\n                }\n                return output;\n            };\n\n            // `encode` is designed to be fully compatible with `btoa` as described in the\n            // HTML Standard: http://whatwg.org/html/webappapis.html#dom-windowbase64-btoa\n            var encode = function (input) {\n                input = String(input);\n                if (/[^\\0-\\xFF]/.test(input)) {\n                    // Note: no need to special-case astral symbols here, as surrogates are\n                    // matched, and the input is supposed to only contain ASCII anyway.\n                    error('The string to be encoded contains characters outside of the ' + 'Latin1 range.');\n                }\n                var padding = input.length % 3;\n                var output = '';\n                var position = -1;\n                var a;\n                var b;\n                var c;\n                var buffer;\n                // Make sure any padding is handled outside of the loop.\n                var length = input.length - padding;\n\n                while (++position < length) {\n                    // Read three bytes, i.e. 24 bits.\n                    a = input.charCodeAt(position) << 16;\n                    b = input.charCodeAt(++position) << 8;\n                    c = input.charCodeAt(++position);\n                    buffer = a + b + c;\n                    // Turn the 24 bits into four chunks of 6 bits each, and append the\n                    // matching character for each of them to the output.\n                    output +=\n                        TABLE.charAt((buffer >> 18) & 0x3f) +\n                        TABLE.charAt((buffer >> 12) & 0x3f) +\n                        TABLE.charAt((buffer >> 6) & 0x3f) +\n                        TABLE.charAt(buffer & 0x3f);\n                }\n\n                if (padding == 2) {\n                    a = input.charCodeAt(position) << 8;\n                    b = input.charCodeAt(++position);\n                    buffer = a + b;\n                    output +=\n                        TABLE.charAt(buffer >> 10) +\n                        TABLE.charAt((buffer >> 4) & 0x3f) +\n                        TABLE.charAt((buffer << 2) & 0x3f) +\n                        '=';\n                } else if (padding == 1) {\n                    buffer = input.charCodeAt(position);\n                    output += TABLE.charAt(buffer >> 2) + TABLE.charAt((buffer << 4) & 0x3f) + '==';\n                }\n\n                return output;\n            };\n\n            var base64 = {\n                encode: encode,\n                decode: decode,\n                version: '0.1.0'\n            };\n\n            // Some AMD build optimizers, like r.js, check for specific condition patterns\n            // like the following:\n            if (typeof undefined == 'function' && typeof undefined.amd == 'object' && undefined.amd) {\n                undefined(function () {\n                    return base64;\n                });\n            } else if (freeExports && !freeExports.nodeType) {\n                if (freeModule) {\n                    // in Node.js or RingoJS v0.8.0+\n                    freeModule.exports = base64;\n                } else {\n                    // in Narwhal or RingoJS v0.7.0-\n                    for (var key in base64) {\n                        base64.hasOwnProperty(key) && (freeExports[key] = base64[key]);\n                    }\n                }\n            } else {\n                // in Rhino or a web browser\n                root.base64 = base64;\n            }\n        })(commonjsGlobal);\n    });\n\n    function makeURI(strData, type) {\n        return 'data:' + type + ';base64,' + strData;\n    }\n\n    function fixType(type) {\n        type = type.toLowerCase().replace(/jpg/i, 'jpeg');\n        var r = type.match(/png|jpeg|bmp|gif/)[0];\n        return 'image/' + r;\n    }\n\n    function encodeData(data) {\n        var str = '';\n        if (typeof data === 'string') {\n            str = data;\n        } else {\n            for (var i = 0; i < data.length; i++) {\n                str += String.fromCharCode(data[i]);\n            }\n        }\n        return base64.encode(str);\n    }\n\n    /**\n     * 获取图像区域隐含的像素数据\n     * @param canvasId canvas标识\n     * @param x 将要被提取的图像数据矩形区域的左上角 x 坐标\n     * @param y 将要被提取的图像数据矩形区域的左上角 y 坐标\n     * @param width 将要被提取的图像数据矩形区域的宽度\n     * @param height 将要被提取的图像数据矩形区域的高度\n     * @param done 完成回调\n     */\n    function getImageData(canvasId, x, y, width, height, done) {\n        uni.canvasGetImageData({\n            canvasId: canvasId,\n            x: x,\n            y: y,\n            width: width,\n            height: height,\n            success: function success(res) {\n                done(res, null);\n            },\n            fail: function fail(res) {\n                done(null, res);\n            }\n        });\n    }\n\n    /**\n     * 生成bmp格式图片\n     * 按照规则生成图片响应头和响应体\n     * @param oData 用来描述 canvas 区域隐含的像素数据 { data, width, height } = oData\n     * @returns {*} base64字符串\n     */\n    function genBitmapImage(oData) {\n        //\n        // BITMAPFILEHEADER: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx\n        // BITMAPINFOHEADER: http://msdn.microsoft.com/en-us/library/dd183376.aspx\n        //\n        var biWidth = oData.width;\n        var biHeight = oData.height;\n        var biSizeImage = biWidth * biHeight * 3;\n        var bfSize = biSizeImage + 54; // total header size = 54 bytes\n\n        //\n        //  typedef struct tagBITMAPFILEHEADER {\n        //  \tWORD bfType;\n        //  \tDWORD bfSize;\n        //  \tWORD bfReserved1;\n        //  \tWORD bfReserved2;\n        //  \tDWORD bfOffBits;\n        //  } BITMAPFILEHEADER;\n        //\n        var BITMAPFILEHEADER = [\n            // WORD bfType -- The file type signature; must be \"BM\"\n            0x42,\n            0x4d,\n            // DWORD bfSize -- The size, in bytes, of the bitmap file\n            bfSize & 0xff,\n            (bfSize >> 8) & 0xff,\n            (bfSize >> 16) & 0xff,\n            (bfSize >> 24) & 0xff,\n            // WORD bfReserved1 -- Reserved; must be zero\n            0,\n            0,\n            // WORD bfReserved2 -- Reserved; must be zero\n            0,\n            0,\n            // DWORD bfOffBits -- The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.\n            54,\n            0,\n            0,\n            0\n        ];\n\n        //\n        //  typedef struct tagBITMAPINFOHEADER {\n        //  \tDWORD biSize;\n        //  \tLONG  biWidth;\n        //  \tLONG  biHeight;\n        //  \tWORD  biPlanes;\n        //  \tWORD  biBitCount;\n        //  \tDWORD biCompression;\n        //  \tDWORD biSizeImage;\n        //  \tLONG  biXPelsPerMeter;\n        //  \tLONG  biYPelsPerMeter;\n        //  \tDWORD biClrUsed;\n        //  \tDWORD biClrImportant;\n        //  } BITMAPINFOHEADER, *PBITMAPINFOHEADER;\n        //\n        var BITMAPINFOHEADER = [\n            // DWORD biSize -- The number of bytes required by the structure\n            40,\n            0,\n            0,\n            0,\n            // LONG biWidth -- The width of the bitmap, in pixels\n            biWidth & 0xff,\n            (biWidth >> 8) & 0xff,\n            (biWidth >> 16) & 0xff,\n            (biWidth >> 24) & 0xff,\n            // LONG biHeight -- The height of the bitmap, in pixels\n            biHeight & 0xff,\n            (biHeight >> 8) & 0xff,\n            (biHeight >> 16) & 0xff,\n            (biHeight >> 24) & 0xff,\n            // WORD biPlanes -- The number of planes for the target device. This value must be set to 1\n            1,\n            0,\n            // WORD biBitCount -- The number of bits-per-pixel, 24 bits-per-pixel -- the bitmap\n            // has a maximum of 2^24 colors (16777216, Truecolor)\n            24,\n            0,\n            // DWORD biCompression -- The type of compression, BI_RGB (code 0) -- uncompressed\n            0,\n            0,\n            0,\n            0,\n            // DWORD biSizeImage -- The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps\n            biSizeImage & 0xff,\n            (biSizeImage >> 8) & 0xff,\n            (biSizeImage >> 16) & 0xff,\n            (biSizeImage >> 24) & 0xff,\n            // LONG biXPelsPerMeter, unused\n            0,\n            0,\n            0,\n            0,\n            // LONG biYPelsPerMeter, unused\n            0,\n            0,\n            0,\n            0,\n            // DWORD biClrUsed, the number of color indexes of palette, unused\n            0,\n            0,\n            0,\n            0,\n            // DWORD biClrImportant, unused\n            0,\n            0,\n            0,\n            0\n        ];\n\n        var iPadding = (4 - ((biWidth * 3) % 4)) % 4;\n\n        var aImgData = oData.data;\n\n        var strPixelData = '';\n        var biWidth4 = biWidth << 2;\n        var y = biHeight;\n        var fromCharCode = String.fromCharCode;\n\n        do {\n            var iOffsetY = biWidth4 * (y - 1);\n            var strPixelRow = '';\n            for (var x = 0; x < biWidth; x++) {\n                var iOffsetX = x << 2;\n                strPixelRow +=\n                    fromCharCode(aImgData[iOffsetY + iOffsetX + 2]) +\n                    fromCharCode(aImgData[iOffsetY + iOffsetX + 1]) +\n                    fromCharCode(aImgData[iOffsetY + iOffsetX]);\n            }\n\n            for (var c = 0; c < iPadding; c++) {\n                strPixelRow += String.fromCharCode(0);\n            }\n\n            strPixelData += strPixelRow;\n        } while (--y);\n\n        var strEncoded = encodeData(BITMAPFILEHEADER.concat(BITMAPINFOHEADER)) + encodeData(strPixelData);\n\n        return strEncoded;\n    }\n\n    /**\n     * 转换为图片base64\n     * @param canvasId canvas标识\n     * @param x 将要被提取的图像数据矩形区域的左上角 x 坐标\n     * @param y 将要被提取的图像数据矩形区域的左上角 y 坐标\n     * @param width 将要被提取的图像数据矩形区域的宽度\n     * @param height 将要被提取的图像数据矩形区域的高度\n     * @param type 转换图片类型\n     * @param done 完成回调\n     */\n    function convertToImage(canvasId, x, y, width, height, type, done) {\n        if (done === void 0) done = function () {};\n\n        if (type === undefined) {\n            type = 'png';\n        }\n        type = fixType(type);\n        if (/bmp/.test(type)) {\n            getImageData(canvasId, x, y, width, height, function (data, err) {\n                var strData = genBitmapImage(data);\n                tools_7(done) && done(makeURI(strData, 'image/' + type), err);\n            });\n        } else {\n            console.error(\"暂不支持生成'\" + type + \"'类型的base64图片\");\n        }\n    }\n\n    var CanvasToBase64 = {\n        convertToImage: convertToImage,\n        // convertToPNG: function (width, height, done) {\n        //   return convertToImage(width, height, 'png', done)\n        // },\n        // convertToJPEG: function (width, height, done) {\n        //   return convertToImage(width, height, 'jpeg', done)\n        // },\n        // convertToGIF: function (width, height, done) {\n        //   return convertToImage(width, height, 'gif', done)\n        // },\n        convertToBMP: function (ref, done) {\n            if (ref === void 0) ref = {};\n            var canvasId = ref.canvasId;\n            var x = ref.x;\n            var y = ref.y;\n            var width = ref.width;\n            var height = ref.height;\n            if (done === void 0) done = function () {};\n\n            return convertToImage(canvasId, x, y, width, height, 'bmp', done);\n        }\n    };\n\n    function methods() {\n        var self = this;\n\n        var boundWidth = self.width; // 裁剪框默认宽度，即整个画布宽度\n        var boundHeight = self.height; // 裁剪框默认高度，即整个画布高度\n\n        var id = self.id;\n        var targetId = self.targetId;\n        var pixelRatio = self.pixelRatio;\n\n        var ref = self.cut;\n        var x = ref.x;\n        if (x === void 0) x = 0;\n        var y = ref.y;\n        if (y === void 0) y = 0;\n        var width = ref.width;\n        if (width === void 0) width = boundWidth;\n        var height = ref.height;\n        if (height === void 0) height = boundHeight;\n\n        self.updateCanvas = function (done) {\n            if (self.croperTarget) {\n                //  画布绘制图片\n                self.ctx.drawImage(self.croperTarget, self.imgLeft, self.imgTop, self.scaleWidth, self.scaleHeight);\n            }\n            tools_7(self.onBeforeDraw) && self.onBeforeDraw(self.ctx, self);\n\n            self.setBoundStyle(self.boundStyle); //\t设置边界样式\n\n            self.ctx.draw(false, done);\n            return self;\n        };\n\n        self.pushOrigin = self.pushOrign = function (src) {\n            self.src = src;\n\n            tools_7(self.onBeforeImageLoad) && self.onBeforeImageLoad(self.ctx, self);\n\n            return getImageInfo({\n                src: src\n            })\n                .then(function (res) {\n                    var innerAspectRadio = res.width / res.height;\n                    var customAspectRadio = width / height;\n\n                    self.croperTarget = res.path;\n\n                    if (innerAspectRadio < customAspectRadio) {\n                        self.rectX = x;\n                        self.baseWidth = width;\n                        self.baseHeight = width / innerAspectRadio;\n                        self.rectY = y - Math.abs((height - self.baseHeight) / 2);\n                    } else {\n                        self.rectY = y;\n                        self.baseWidth = height * innerAspectRadio;\n                        self.baseHeight = height;\n                        self.rectX = x - Math.abs((width - self.baseWidth) / 2);\n                    }\n\n                    self.imgLeft = self.rectX;\n                    self.imgTop = self.rectY;\n                    self.scaleWidth = self.baseWidth;\n                    self.scaleHeight = self.baseHeight;\n\n                    self.update();\n\n                    return new Promise(function (resolve) {\n                        self.updateCanvas(resolve);\n                    });\n                })\n                .then(function () {\n                    tools_7(self.onImageLoad) && self.onImageLoad(self.ctx, self);\n                });\n        };\n\n        self.removeImage = function () {\n            self.src = '';\n            self.croperTarget = '';\n            return draw(self.ctx);\n        };\n\n        self.getCropperBase64 = function (done) {\n            if (done === void 0) done = function () {};\n\n            CanvasToBase64.convertToBMP(\n                {\n                    canvasId: id,\n                    x: x,\n                    y: y,\n                    width: width,\n                    height: height\n                },\n                done\n            );\n        };\n\n        self.getCropperImage = function (opt, fn) {\n            var customOptions = opt;\n\n            var canvasOptions = {\n                canvasId: id,\n                x: x,\n                y: y,\n                width: width,\n                height: height\n            };\n\n            var task = function () {\n                return Promise.resolve();\n            };\n\n            if (tools_10(customOptions) && customOptions.original) {\n                // original mode\n                task = function () {\n                    self.targetCtx.drawImage(\n                        self.croperTarget,\n                        self.imgLeft * pixelRatio,\n                        self.imgTop * pixelRatio,\n                        self.scaleWidth * pixelRatio,\n                        self.scaleHeight * pixelRatio\n                    );\n\n                    canvasOptions = {\n                        canvasId: targetId,\n                        x: x * pixelRatio,\n                        y: y * pixelRatio,\n                        width: width * pixelRatio,\n                        height: height * pixelRatio\n                    };\n\n                    return draw(self.targetCtx);\n                };\n            }\n\n            return task()\n                .then(function () {\n                    if (tools_10(customOptions)) {\n                        canvasOptions = Object.assign({}, canvasOptions, customOptions);\n                    }\n\n                    if (tools_7(customOptions)) {\n                        fn = customOptions;\n                    }\n\n                    var arg = canvasOptions.componentContext\n                        ? [canvasOptions, canvasOptions.componentContext]\n                        : [canvasOptions];\n\n                    return canvasToTempFilePath.apply(null, arg);\n                })\n                .then(function (res) {\n                    var tempFilePath = res.tempFilePath;\n\n                    return tools_7(fn) ? fn.call(self, tempFilePath, null) : tempFilePath;\n                })\n                .catch(function (err) {\n                    if (tools_7(fn)) {\n                        fn.call(self, null, err);\n                    } else {\n                        throw err;\n                    }\n                });\n        };\n    }\n\n    /**\n     * 获取最新缩放值\n     * @param oldScale 上一次触摸结束后的缩放值\n     * @param oldDistance 上一次触摸结束后的双指距离\n     * @param zoom 缩放系数\n     * @param touch0 第一指touch对象\n     * @param touch1 第二指touch对象\n     * @returns {*}\n     */\n    var getNewScale = function (oldScale, oldDistance, zoom, touch0, touch1) {\n        var xMove, yMove, newDistance;\n        // 计算二指最新距离\n        xMove = Math.round(touch1.x - touch0.x);\n        yMove = Math.round(touch1.y - touch0.y);\n        newDistance = Math.round(Math.sqrt(xMove * xMove + yMove * yMove));\n\n        return oldScale + 0.001 * zoom * (newDistance - oldDistance);\n    };\n\n    function update() {\n        var self = this;\n\n        if (!self.src) {\n            return;\n        }\n\n        self.__oneTouchStart = function (touch) {\n            self.touchX0 = Math.round(touch.x);\n            self.touchY0 = Math.round(touch.y);\n        };\n\n        self.__oneTouchMove = function (touch) {\n            var xMove, yMove;\n            // 计算单指移动的距离\n            if (self.touchended) {\n                return self.updateCanvas();\n            }\n            xMove = Math.round(touch.x - self.touchX0);\n            yMove = Math.round(touch.y - self.touchY0);\n\n            var imgLeft = Math.round(self.rectX + xMove);\n            var imgTop = Math.round(self.rectY + yMove);\n\n            self.outsideBound(imgLeft, imgTop);\n\n            self.updateCanvas();\n        };\n\n        self.__twoTouchStart = function (touch0, touch1) {\n            var xMove, yMove, oldDistance;\n\n            self.touchX1 = Math.round(self.rectX + self.scaleWidth / 2);\n            self.touchY1 = Math.round(self.rectY + self.scaleHeight / 2);\n\n            // 计算两指距离\n            xMove = Math.round(touch1.x - touch0.x);\n            yMove = Math.round(touch1.y - touch0.y);\n            oldDistance = Math.round(Math.sqrt(xMove * xMove + yMove * yMove));\n\n            self.oldDistance = oldDistance;\n        };\n\n        self.__twoTouchMove = function (touch0, touch1) {\n            var oldScale = self.oldScale;\n            var oldDistance = self.oldDistance;\n            var scale = self.scale;\n            var zoom = self.zoom;\n\n            self.newScale = getNewScale(oldScale, oldDistance, zoom, touch0, touch1);\n\n            //  设定缩放范围\n            self.newScale <= 1 && (self.newScale = 1);\n            self.newScale >= scale && (self.newScale = scale);\n\n            self.scaleWidth = Math.round(self.newScale * self.baseWidth);\n            self.scaleHeight = Math.round(self.newScale * self.baseHeight);\n            var imgLeft = Math.round(self.touchX1 - self.scaleWidth / 2);\n            var imgTop = Math.round(self.touchY1 - self.scaleHeight / 2);\n\n            self.outsideBound(imgLeft, imgTop);\n\n            self.updateCanvas();\n        };\n\n        self.__xtouchEnd = function () {\n            self.oldScale = self.newScale;\n            self.rectX = self.imgLeft;\n            self.rectY = self.imgTop;\n        };\n    }\n\n    var handle = {\n        //  图片手势初始监测\n        touchStart: function touchStart(e) {\n            var self = this;\n            var ref = e.touches;\n            var touch0 = ref[0];\n            var touch1 = ref[1];\n\n            if (!self.src) {\n                return;\n            }\n\n            setTouchState(self, true, null, null);\n\n            // 计算第一个触摸点的位置，并参照改点进行缩放\n            self.__oneTouchStart(touch0);\n\n            // 两指手势触发\n            if (e.touches.length >= 2) {\n                self.__twoTouchStart(touch0, touch1);\n            }\n        },\n\n        //  图片手势动态缩放\n        touchMove: function touchMove(e) {\n            var self = this;\n            var ref = e.touches;\n            var touch0 = ref[0];\n            var touch1 = ref[1];\n\n            if (!self.src) {\n                return;\n            }\n\n            setTouchState(self, null, true);\n\n            // 单指手势时触发\n            if (e.touches.length === 1) {\n                self.__oneTouchMove(touch0);\n            }\n            // 两指手势触发\n            if (e.touches.length >= 2) {\n                self.__twoTouchMove(touch0, touch1);\n            }\n        },\n\n        touchEnd: function touchEnd(e) {\n            var self = this;\n\n            if (!self.src) {\n                return;\n            }\n\n            setTouchState(self, false, false, true);\n            self.__xtouchEnd();\n        }\n    };\n\n    function cut() {\n        var self = this;\n        var boundWidth = self.width; // 裁剪框默认宽度，即整个画布宽度\n        var boundHeight = self.height;\n        // 裁剪框默认高度，即整个画布高度\n        var ref = self.cut;\n        var x = ref.x;\n        if (x === void 0) x = 0;\n        var y = ref.y;\n        if (y === void 0) y = 0;\n        var width = ref.width;\n        if (width === void 0) width = boundWidth;\n        var height = ref.height;\n        if (height === void 0) height = boundHeight;\n\n        /**\n         * 设置边界\n         * @param imgLeft 图片左上角横坐标值\n         * @param imgTop 图片左上角纵坐标值\n         */\n        self.outsideBound = function (imgLeft, imgTop) {\n            self.imgLeft =\n                imgLeft >= x ? x : self.scaleWidth + imgLeft - x <= width ? x + width - self.scaleWidth : imgLeft;\n\n            self.imgTop =\n                imgTop >= y ? y : self.scaleHeight + imgTop - y <= height ? y + height - self.scaleHeight : imgTop;\n        };\n\n        /**\n         * 设置边界样式\n         * @param color\t边界颜色\n         */\n        self.setBoundStyle = function (ref) {\n            if (ref === void 0) ref = {};\n            var color = ref.color;\n            if (color === void 0) color = 'var(--u-type-success-dark)';\n            var mask = ref.mask;\n            if (mask === void 0) mask = 'rgba(0, 0, 0, 0.3)';\n            var lineWidth = ref.lineWidth;\n            if (lineWidth === void 0) lineWidth = 1;\n\n            var half = lineWidth / 2;\n            var boundOption = [\n                {\n                    start: {\n                        x: x - half,\n                        y: y + 10 - half\n                    },\n                    step1: {\n                        x: x - half,\n                        y: y - half\n                    },\n                    step2: {\n                        x: x + 10 - half,\n                        y: y - half\n                    }\n                },\n                {\n                    start: {\n                        x: x - half,\n                        y: y + height - 10 + half\n                    },\n                    step1: {\n                        x: x - half,\n                        y: y + height + half\n                    },\n                    step2: {\n                        x: x + 10 - half,\n                        y: y + height + half\n                    }\n                },\n                {\n                    start: {\n                        x: x + width - 10 + half,\n                        y: y - half\n                    },\n                    step1: {\n                        x: x + width + half,\n                        y: y - half\n                    },\n                    step2: {\n                        x: x + width + half,\n                        y: y + 10 - half\n                    }\n                },\n                {\n                    start: {\n                        x: x + width + half,\n                        y: y + height - 10 + half\n                    },\n                    step1: {\n                        x: x + width + half,\n                        y: y + height + half\n                    },\n                    step2: {\n                        x: x + width - 10 + half,\n                        y: y + height + half\n                    }\n                }\n            ];\n\n            // 绘制半透明层\n            self.ctx.beginPath();\n            self.ctx.setFillStyle(mask);\n            self.ctx.fillRect(0, 0, x, boundHeight);\n            self.ctx.fillRect(x, 0, width, y);\n            self.ctx.fillRect(x, y + height, width, boundHeight - y - height);\n            self.ctx.fillRect(x + width, 0, boundWidth - x - width, boundHeight);\n            self.ctx.fill();\n\n            boundOption.forEach(function (op) {\n                self.ctx.beginPath();\n                self.ctx.setStrokeStyle(color);\n                self.ctx.setLineWidth(lineWidth);\n                self.ctx.moveTo(op.start.x, op.start.y);\n                self.ctx.lineTo(op.step1.x, op.step1.y);\n                self.ctx.lineTo(op.step2.x, op.step2.y);\n                self.ctx.stroke();\n            });\n        };\n    }\n\n    var version = '1.3.9';\n\n    var WeCropper = function WeCropper(params) {\n        var self = this;\n        var _default = {};\n\n        validator(self, DEFAULT);\n\n        Object.keys(DEFAULT).forEach(function (key) {\n            _default[key] = DEFAULT[key].default;\n        });\n        Object.assign(self, _default, params);\n\n        self.prepare();\n        self.attachPage();\n        self.createCtx();\n        self.observer();\n        self.cutt();\n        self.methods();\n        self.init();\n        self.update();\n\n        return self;\n    };\n\n    WeCropper.prototype.init = function init() {\n        var self = this;\n        var src = self.src;\n\n        self.version = version;\n\n        typeof self.onReady === 'function' && self.onReady(self.ctx, self);\n\n        if (src) {\n            self.pushOrign(src);\n        } else {\n            self.updateCanvas();\n        }\n        setTouchState(self, false, false, false);\n\n        self.oldScale = 1;\n        self.newScale = 1;\n\n        return self;\n    };\n\n    Object.assign(WeCropper.prototype, handle);\n\n    WeCropper.prototype.prepare = prepare;\n    WeCropper.prototype.observer = observer;\n    WeCropper.prototype.methods = methods;\n    WeCropper.prototype.cutt = cut;\n    WeCropper.prototype.update = update;\n\n    return WeCropper;\n});\n\nexports.default = WeCropper;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-avatar-cropper/weCropper.ts",
    "content": "// @ts-nocheck\n/**\n * we-cropper v1.3.9\n * (c) 2020 dlhandsome\n * @license MIT\n * TypeScript 兼容导出版本，移除UMD包裹，导出WeCropper构造函数\n */\n\n// 部分类型声明\nexport interface WeCropperOptions {\n    id?: string;\n    targetId?: string;\n    pixelRatio?: number;\n    width?: number;\n    height?: number;\n    scale?: number;\n    zoom?: number;\n    cut?: any;\n    boundStyle?: any;\n    [key: string]: any;\n}\n\nvar device: any = void 0;\nvar TOUCH_STATE: any[] = ['touchstarted', 'touchmoved', 'touchended'];\n\nfunction firstLetterUpper(str: any): any {\n    return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\nfunction setTouchState(instance: any, ...arg: any[]): void {\n    TOUCH_STATE.forEach(function (key: any, i: number) {\n        if (arg[i] !== undefined) {\n            instance[key] = arg[i];\n        }\n    });\n}\n\nfunction validator(instance: any, o: any): void {\n    Object.defineProperties(instance, o);\n}\n\nfunction getDevice(): any {\n    if (!device) {\n        device = uni.getSystemInfoSync();\n    }\n    return device as any;\n}\n\nvar tmp: any = {};\n\nvar ref: any = getDevice();\nvar pixelRatio: any = ref.pixelRatio;\n\nvar DEFAULT: any = {\n    id: {\n        default: 'cropper',\n        get: function get(): any {\n            return tmp.id;\n        },\n        set: function set(value: any): void {\n            if (typeof value !== 'string') {\n                console.error('id：' + value + ' is invalid');\n            }\n            tmp.id = value;\n        }\n    },\n    width: {\n        default: 750,\n        get: function get(): any {\n            return tmp.width;\n        },\n        set: function set(value: any): void {\n            if (typeof value !== 'number') {\n                console.error('width：' + value + ' is invalid');\n            }\n            tmp.width = value;\n        }\n    },\n    height: {\n        default: 750,\n        get: function get(): any {\n            return tmp.height;\n        },\n        set: function set(value: any): void {\n            if (typeof value !== 'number') {\n                console.error('height：' + value + ' is invalid');\n            }\n            tmp.height = value;\n        }\n    },\n    pixelRatio: {\n        default: pixelRatio,\n        get: function get(): any {\n            return tmp.pixelRatio;\n        },\n        set: function set(value: any): void {\n            if (typeof value !== 'number') {\n                console.error('pixelRatio：' + value + ' is invalid');\n            }\n            tmp.pixelRatio = value;\n        }\n    },\n    scale: {\n        default: 2.5,\n        get: function get(): any {\n            return tmp.scale;\n        },\n        set: function set(value: any): void {\n            if (typeof value !== 'number') {\n                console.error('scale：' + value + ' is invalid');\n            }\n            tmp.scale = value;\n        }\n    },\n    zoom: {\n        default: 5,\n        get: function get(): any {\n            return tmp.zoom;\n        },\n        set: function set(value: any): void {\n            if (typeof value !== 'number') {\n                console.error('zoom：' + value + ' is invalid');\n            } else if (value < 0 || value > 10) {\n                console.error('zoom should be ranged in 0 ~ 10');\n            }\n            tmp.zoom = value;\n        }\n    },\n    src: {\n        default: '',\n        get: function get(): any {\n            return tmp.src;\n        },\n        set: function set(value: any): void {\n            if (typeof value !== 'string') {\n                console.error('src：' + value + ' is invalid');\n            }\n            tmp.src = value;\n        }\n    },\n    cut: {\n        default: {},\n        get: function get(): any {\n            return tmp.cut;\n        },\n        set: function set(value: any): void {\n            if (typeof value !== 'object') {\n                console.error('cut：' + value + ' is invalid');\n            }\n            tmp.cut = value;\n        }\n    },\n    boundStyle: {\n        default: {},\n        get: function get(): any {\n            return tmp.boundStyle;\n        },\n        set: function set(value: any): void {\n            if (typeof value !== 'object') {\n                console.error('boundStyle：' + value + ' is invalid');\n            }\n            tmp.boundStyle = value;\n        }\n    },\n    onReady: {\n        default: null,\n        get: function get(): any {\n            return tmp.ready;\n        },\n        set: function set(value: any): void {\n            tmp.ready = value;\n        }\n    },\n    onBeforeImageLoad: {\n        default: null,\n        get: function get(): any {\n            return tmp.beforeImageLoad;\n        },\n        set: function set(value: any): void {\n            tmp.beforeImageLoad = value;\n        }\n    },\n    onImageLoad: {\n        default: null,\n        get: function get(): any {\n            return tmp.imageLoad;\n        },\n        set: function set(value: any): void {\n            tmp.imageLoad = value;\n        }\n    },\n    onBeforeDraw: {\n        default: null,\n        get: function get(): any {\n            return tmp.beforeDraw;\n        },\n        set: function set(value: any): void {\n            tmp.beforeDraw = value;\n        }\n    }\n};\n\nvar ref$1: any = getDevice();\nvar windowWidth: any = ref$1.windowWidth;\n\nfunction prepare(this: any): void {\n    var self: any = this;\n\n    // v1.4.0 版本中将不再自动绑定we-cropper实例\n    self.attachPage = function () {\n        var pages = getCurrentPages();\n        // 获取到当前page上下文\n        var pageContext = pages[pages.length - 1];\n        // 把this依附在Page上下文的wecropper属性上，便于在page钩子函数中访问\n        Object.defineProperty(pageContext, 'wecropper', {\n            get: function get() {\n                console.warn(\n                    'Instance will not be automatically bound to the page after v1.4.0\\n\\n' +\n                        'Please use a custom instance name instead\\n\\n' +\n                        'Example: \\n' +\n                        'this.mycropper = new WeCropper(options)\\n\\n' +\n                        '// ...\\n' +\n                        'this.mycropper.getCropperImage()'\n                );\n                return self;\n            },\n            configurable: true\n        });\n    };\n\n    self.createCtx = function () {\n        var id = self.id;\n        var targetId = self.targetId;\n\n        if (id) {\n            self.ctx = self.ctx || uni.createCanvasContext(id);\n            self.targetCtx = self.targetCtx || uni.createCanvasContext(targetId);\n        } else {\n            console.error(\"constructor: create canvas context failed, 'id' must be valuable\");\n        }\n    };\n\n    self.deviceRadio = windowWidth / 750;\n}\n\nvar commonjsGlobal = typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {};\n\nfunction createCommonjsModule(fn: any, module: any): any {\n    return (\n        (module = {\n            exports: {}\n        }),\n        fn(module, module.exports),\n        module.exports\n    );\n}\n\n// tools 初始化补全参数\nvar tools = createCommonjsModule(function (module: any, exports: any) {\n    /**\n     * String type check\n     */\n    exports.isStr = function (v: any) {\n        return typeof v === 'string';\n    };\n    /**\n     * Number type check\n     */\n    exports.isNum = function (v: any) {\n        return typeof v === 'number';\n    };\n    /**\n     * Array type check\n     */\n    exports.isArr = Array.isArray;\n    /**\n     * undefined type check\n     */\n    exports.isUndef = function (v: any) {\n        return v === undefined;\n    };\n\n    exports.isTrue = function (v: any) {\n        return v === true;\n    };\n\n    exports.isFalse = function (v: any) {\n        return v === false;\n    };\n    /**\n     * Function type check\n     */\n    exports.isFunc = function (v: any) {\n        return typeof v === 'function';\n    };\n    /**\n     * Quick object check - this is primarily used to tell\n     * Objects from primitive values when we know the value\n     * is a JSON-compliant type.\n     */\n    exports.isObj = exports.isObject = function (obj: any) {\n        return obj !== null && typeof obj === 'object';\n    };\n\n    /**\n     * Strict object type check. Only returns true\n     * for plain JavaScript objects.\n     */\n    var _toString = Object.prototype.toString;\n    exports.isPlainObject = function (obj: any) {\n        return _toString.call(obj) === '[object Object]';\n    };\n\n    /**\n     * Check whether the object has the property.\n     */\n    var hasOwnProperty = Object.prototype.hasOwnProperty;\n    exports.hasOwn = function (obj: any, key: any) {\n        return hasOwnProperty.call(obj, key);\n    };\n\n    /**\n     * Perform no operation.\n     * Stubbing args to make Flow happy without leaving useless transpiled code\n     * with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/)\n     */\n    exports.noop = function (a: any, b: any, c: any) {};\n\n    /**\n     * Check if val is a valid array index.\n     */\n    exports.isValidArrayIndex = function (val: any) {\n        var n = parseFloat(String(val));\n        return n >= 0 && Math.floor(n) === n && isFinite(val);\n    };\n}, {});\n\nvar tools_7 = tools.isFunc;\nvar tools_10 = tools.isPlainObject;\n\nvar EVENT_TYPE = ['ready', 'beforeImageLoad', 'beforeDraw', 'imageLoad'];\n\nfunction observer(this: any) {\n    var self = this;\n\n    self.on = function (event: any, fn: any) {\n        if (EVENT_TYPE.indexOf(event) > -1) {\n            if (tools_7(fn)) {\n                event === 'ready' ? fn(self) : (self['on' + firstLetterUpper(event)] = fn);\n            }\n        } else {\n            console.error('event: ' + event + ' is invalid');\n        }\n        return self;\n    };\n}\n\nfunction wxPromise(this: any, fn: any) {\n    return function (this: any, obj: any) {\n        var args = [],\n            len = arguments.length - 1;\n        while (len-- > 0) args[len] = arguments[len + 1];\n\n        if (obj === void 0) obj = {};\n        return new Promise(function (resolve, reject) {\n            obj.success = function (res: any) {\n                resolve(res);\n            };\n            obj.fail = function (err: any) {\n                reject(err);\n            };\n            fn.apply(void 0, [obj].concat(args));\n        });\n    };\n}\n\nfunction draw(this: any, ctx: any, reserve: any) {\n    if (reserve === void 0) reserve = false;\n\n    return new Promise(function (resolve) {\n        ctx.draw(reserve, resolve);\n    });\n}\n\nvar getImageInfo = wxPromise(uni.getImageInfo);\n\nvar canvasToTempFilePath = wxPromise(uni.canvasToTempFilePath);\n\nvar base64 = createCommonjsModule(function (module, exports) {\n    /*! http://mths.be/base64 v0.1.0 by @mathias | MIT license */\n    (function (root) {\n        // Detect free variables `exports`.\n        var freeExports = 'object' == 'object' && exports;\n\n        // Detect free variable `module`.\n        var freeModule = 'object' == 'object' && module && module.exports == freeExports && module;\n\n        // Detect free variable `global`, from Node.js or Browserified code, and use\n        // it as `root`.\n        var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal;\n        if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {\n            root = freeGlobal;\n        }\n\n        /*--------------------------------------------------------------------------*/\n\n        var InvalidCharacterError = function (message: any) {\n            this.message = message;\n        };\n        InvalidCharacterError.prototype = new Error();\n        InvalidCharacterError.prototype.name = 'InvalidCharacterError';\n\n        var error = function (message: any) {\n            // Note: the error messages used throughout this file match those used by\n            // the native `atob`/`btoa` implementation in Chromium.\n            throw new InvalidCharacterError(message);\n        };\n\n        var TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n        // http://whatwg.org/html/common-microsyntaxes.html#space-character\n        var REGEX_SPACE_CHARACTERS = /[\\t\\n\\f\\r ]/g;\n\n        // `decode` is designed to be fully compatible with `atob` as described in the\n        // HTML Standard. http://whatwg.org/html/webappapis.html#dom-windowbase64-atob\n        // The optimized base64-decoding algorithm used is based on @atk’s excellent\n        // implementation. https://gist.github.com/atk/1020396\n        var decode = function (input: any) {\n            input = String(input).replace(REGEX_SPACE_CHARACTERS, '');\n            var length = input.length;\n            if (length % 4 == 0) {\n                input = input.replace(/==?$/, '');\n                length = input.length;\n            }\n            if (\n                length % 4 == 1 ||\n                // http://whatwg.org/C#alphanumeric-ascii-characters\n                /[^+a-zA-Z0-9/]/.test(input)\n            ) {\n                error('Invalid character: the string to be decoded is not correctly encoded.');\n            }\n            var bitCounter = 0;\n            var bitStorage;\n            var buffer;\n            var output = '';\n            var position = -1;\n            while (++position < length) {\n                buffer = TABLE.indexOf(input.charAt(position));\n                bitStorage = bitCounter % 4 ? bitStorage * 64 + buffer : buffer;\n                // Unless this is the first of a group of 4 characters…\n                if (bitCounter++ % 4) {\n                    // …convert the first 8 bits to a single ASCII character.\n                    output += String.fromCharCode(0xff & (bitStorage >> ((-2 * bitCounter) & 6)));\n                }\n            }\n            return output;\n        };\n\n        // `encode` is designed to be fully compatible with `btoa` as described in the\n        // HTML Standard: http://whatwg.org/html/webappapis.html#dom-windowbase64-btoa\n        var encode = function (input: any) {\n            input = String(input);\n            if (/[^\\0-\\xFF]/.test(input)) {\n                // Note: no need to special-case astral symbols here, as surrogates are\n                // matched, and the input is supposed to only contain ASCII anyway.\n                error('The string to be encoded contains characters outside of the ' + 'Latin1 range.');\n            }\n            var padding = input.length % 3;\n            var output = '';\n            var position = -1;\n            var a;\n            var b;\n            var c;\n            var buffer;\n            // Make sure any padding is handled outside of the loop.\n            var length = input.length - padding;\n\n            while (++position < length) {\n                // Read three bytes, i.e. 24 bits.\n                a = input.charCodeAt(position) << 16;\n                b = input.charCodeAt(++position) << 8;\n                c = input.charCodeAt(++position);\n                buffer = a + b + c;\n                // Turn the 24 bits into four chunks of 6 bits each, and append the\n                // matching character for each of them to the output.\n                output +=\n                    TABLE.charAt((buffer >> 18) & 0x3f) +\n                    TABLE.charAt((buffer >> 12) & 0x3f) +\n                    TABLE.charAt((buffer >> 6) & 0x3f) +\n                    TABLE.charAt(buffer & 0x3f);\n            }\n\n            if (padding == 2) {\n                a = input.charCodeAt(position) << 8;\n                b = input.charCodeAt(++position);\n                buffer = a + b;\n                output +=\n                    TABLE.charAt(buffer >> 10) +\n                    TABLE.charAt((buffer >> 4) & 0x3f) +\n                    TABLE.charAt((buffer << 2) & 0x3f) +\n                    '=';\n            } else if (padding == 1) {\n                buffer = input.charCodeAt(position);\n                output += TABLE.charAt(buffer >> 2) + TABLE.charAt((buffer << 4) & 0x3f) + '==';\n            }\n\n            return output;\n        };\n\n        var base64 = {\n            encode: encode,\n            decode: decode,\n            version: '0.1.0'\n        };\n\n        // Some AMD build optimizers, like r.js, check for specific condition patterns\n        // like the following:\n        if (typeof undefined == 'function' && typeof undefined.amd == 'object' && undefined.amd) {\n            undefined(function () {\n                return base64;\n            });\n        } else if (freeExports && !freeExports.nodeType) {\n            if (freeModule) {\n                // in Node.js or RingoJS v0.8.0+\n                freeModule.exports = base64;\n            } else {\n                // in Narwhal or RingoJS v0.7.0-\n                for (var key in base64) {\n                    base64.hasOwnProperty(key) && (freeExports[key] = base64[key]);\n                }\n            }\n        } else {\n            // in Rhino or a web browser\n            root.base64 = base64;\n        }\n    })(commonjsGlobal);\n});\n\nfunction makeURI(strData, type) {\n    return 'data:' + type + ';base64,' + strData;\n}\n\nfunction fixType(type) {\n    type = type.toLowerCase().replace(/jpg/i, 'jpeg');\n    var r = type.match(/png|jpeg|bmp|gif/)[0];\n    return 'image/' + r;\n}\n\nfunction encodeData(data) {\n    var str = '';\n    if (typeof data === 'string') {\n        str = data;\n    } else {\n        for (var i = 0; i < data.length; i++) {\n            str += String.fromCharCode(data[i]);\n        }\n    }\n    return base64.encode(str);\n}\n\n/**\n * 获取图像区域隐含的像素数据\n * @param canvasId canvas标识\n * @param x 将要被提取的图像数据矩形区域的左上角 x 坐标\n * @param y 将要被提取的图像数据矩形区域的左上角 y 坐标\n * @param width 将要被提取的图像数据矩形区域的宽度\n * @param height 将要被提取的图像数据矩形区域的高度\n * @param done 完成回调\n */\nfunction getImageData(canvasId: any, x: any, y: any, width: any, height: any, done: any) {\n    uni.canvasGetImageData({\n        canvasId: canvasId,\n        x: x,\n        y: y,\n        width: width,\n        height: height,\n        success: function success(res: any) {\n            done(res, null);\n        },\n        fail: function fail(res: any) {\n            done(null, res);\n        }\n    });\n}\n\n/**\n * 生成bmp格式图片\n * 按照规则生成图片响应头和响应体\n * @param oData 用来描述 canvas 区域隐含的像素数据 { data, width, height } = oData\n * @returns {*} base64字符串\n */\nfunction genBitmapImage(oData: any) {\n    //\n    // BITMAPFILEHEADER: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx\n    // BITMAPINFOHEADER: http://msdn.microsoft.com/en-us/library/dd183376.aspx\n    //\n    var biWidth = oData.width;\n    var biHeight = oData.height;\n    var biSizeImage = biWidth * biHeight * 3;\n    var bfSize = biSizeImage + 54; // total header size = 54 bytes\n\n    //\n    //  typedef struct tagBITMAPFILEHEADER {\n    //  \tWORD bfType;\n    //  \tDWORD bfSize;\n    //  \tWORD bfReserved1;\n    //  \tWORD bfReserved2;\n    //  \tDWORD bfOffBits;\n    //  } BITMAPFILEHEADER;\n    //\n    var BITMAPFILEHEADER = [\n        // WORD bfType -- The file type signature; must be \"BM\"\n        0x42,\n        0x4d,\n        // DWORD bfSize -- The size, in bytes, of the bitmap file\n        bfSize & 0xff,\n        (bfSize >> 8) & 0xff,\n        (bfSize >> 16) & 0xff,\n        (bfSize >> 24) & 0xff,\n        // WORD bfReserved1 -- Reserved; must be zero\n        0,\n        0,\n        // WORD bfReserved2 -- Reserved; must be zero\n        0,\n        0,\n        // DWORD bfOffBits -- The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.\n        54,\n        0,\n        0,\n        0\n    ];\n\n    //\n    //  typedef struct tagBITMAPINFOHEADER {\n    //  \tDWORD biSize;\n    //  \tLONG  biWidth;\n    //  \tLONG  biHeight;\n    //  \tWORD  biPlanes;\n    //  \tWORD  biBitCount;\n    //  \tDWORD biCompression;\n    //  \tDWORD biSizeImage;\n    //  \tLONG  biXPelsPerMeter;\n    //  \tLONG  biYPelsPerMeter;\n    //  \tDWORD biClrUsed;\n    //  \tDWORD biClrImportant;\n    //  } BITMAPINFOHEADER, *PBITMAPINFOHEADER;\n    //\n    var BITMAPINFOHEADER = [\n        // DWORD biSize -- The number of bytes required by the structure\n        40,\n        0,\n        0,\n        0,\n        // LONG biWidth -- The width of the bitmap, in pixels\n        biWidth & 0xff,\n        (biWidth >> 8) & 0xff,\n        (biWidth >> 16) & 0xff,\n        (biWidth >> 24) & 0xff,\n        // LONG biHeight -- The height of the bitmap, in pixels\n        biHeight & 0xff,\n        (biHeight >> 8) & 0xff,\n        (biHeight >> 16) & 0xff,\n        (biHeight >> 24) & 0xff,\n        // WORD biPlanes -- The number of planes for the target device. This value must be set to 1\n        1,\n        0,\n        // WORD biBitCount -- The number of bits-per-pixel, 24 bits-per-pixel -- the bitmap\n        // has a maximum of 2^24 colors (16777216, Truecolor)\n        24,\n        0,\n        // DWORD biCompression -- The type of compression, BI_RGB (code 0) -- uncompressed\n        0,\n        0,\n        0,\n        0,\n        // DWORD biSizeImage -- The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps\n        biSizeImage & 0xff,\n        (biSizeImage >> 8) & 0xff,\n        (biSizeImage >> 16) & 0xff,\n        (biSizeImage >> 24) & 0xff,\n        // LONG biXPelsPerMeter, unused\n        0,\n        0,\n        0,\n        0,\n        // LONG biYPelsPerMeter, unused\n        0,\n        0,\n        0,\n        0,\n        // DWORD biClrUsed, the number of color indexes of palette, unused\n        0,\n        0,\n        0,\n        0,\n        // DWORD biClrImportant, unused\n        0,\n        0,\n        0,\n        0\n    ];\n\n    var iPadding = (4 - ((biWidth * 3) % 4)) % 4;\n\n    var aImgData = oData.data;\n\n    var strPixelData = '';\n    var biWidth4 = biWidth << 2;\n    var y = biHeight;\n    var fromCharCode = String.fromCharCode;\n\n    do {\n        var iOffsetY = biWidth4 * (y - 1);\n        var strPixelRow = '';\n        for (var x = 0; x < biWidth; x++) {\n            var iOffsetX = x << 2;\n            strPixelRow +=\n                fromCharCode(aImgData[iOffsetY + iOffsetX + 2]) +\n                fromCharCode(aImgData[iOffsetY + iOffsetX + 1]) +\n                fromCharCode(aImgData[iOffsetY + iOffsetX]);\n        }\n\n        for (var c = 0; c < iPadding; c++) {\n            strPixelRow += String.fromCharCode(0);\n        }\n\n        strPixelData += strPixelRow;\n    } while (--y);\n\n    var strEncoded = encodeData(BITMAPFILEHEADER.concat(BITMAPINFOHEADER)) + encodeData(strPixelData);\n\n    return strEncoded;\n}\n\n/**\n * 转换为图片base64\n * @param canvasId canvas标识\n * @param x 将要被提取的图像数据矩形区域的左上角 x 坐标\n * @param y 将要被提取的图像数据矩形区域的左上角 y 坐标\n * @param width 将要被提取的图像数据矩形区域的宽度\n * @param height 将要被提取的图像数据矩形区域的高度\n * @param type 转换图片类型\n * @param done 完成回调\n */\nfunction convertToImage(canvasId: any, x: any, y: any, width: any, height: any, type: any, done: any) {\n    if (done === void 0) done = function () {};\n\n    if (type === undefined) {\n        type = 'png';\n    }\n    type = fixType(type);\n    if (/bmp/.test(type)) {\n        getImageData(canvasId, x, y, width, height, function (data: any, err: any) {\n            var strData = genBitmapImage(data);\n            tools_7(done) && done(makeURI(strData, 'image/' + type), err);\n        });\n    } else {\n        console.error(\"暂不支持生成'\" + type + \"'类型的base64图片\");\n    }\n}\n\nvar CanvasToBase64 = {\n    convertToImage: convertToImage,\n    // convertToPNG: function (width, height, done) {\n    //   return convertToImage(width, height, 'png', done)\n    // },\n    // convertToJPEG: function (width, height, done) {\n    //   return convertToImage(width, height, 'jpeg', done)\n    // },\n    // convertToGIF: function (width, height, done) {\n    //   return convertToImage(width, height, 'gif', done)\n    // },\n    convertToBMP: function (ref: any, done: any) {\n        if (ref === void 0) ref = {};\n        var canvasId = ref.canvasId;\n        var x = ref.x;\n        var y = ref.y;\n        var width = ref.width;\n        var height = ref.height;\n        if (done === void 0) done = function () {};\n\n        return convertToImage(canvasId, x, y, width, height, 'bmp', done);\n    }\n};\n\nfunction methods(this: any) {\n    var self = this;\n\n    var boundWidth = self.width; // 裁剪框默认宽度，即整个画布宽度\n    var boundHeight = self.height; // 裁剪框默认高度，即整个画布高度\n\n    var id = self.id;\n    var targetId = self.targetId;\n    var pixelRatio = self.pixelRatio;\n\n    var ref = self.cut;\n    var x = ref.x;\n    if (x === void 0) x = 0;\n    var y = ref.y;\n    if (y === void 0) y = 0;\n    var width = ref.width;\n    if (width === void 0) width = boundWidth;\n    var height = ref.height;\n    if (height === void 0) height = boundHeight;\n\n    self.updateCanvas = function (done: any) {\n        if (self.croperTarget) {\n            //  画布绘制图片\n            self.ctx.drawImage(self.croperTarget, self.imgLeft, self.imgTop, self.scaleWidth, self.scaleHeight);\n        }\n        tools_7(self.onBeforeDraw) && self.onBeforeDraw(self.ctx, self);\n\n        self.setBoundStyle(self.boundStyle); //\t设置边界样式\n\n        self.ctx.draw(false, done);\n        return self;\n    };\n\n    self.pushOrigin = self.pushOrign = function (src: any) {\n        self.src = src;\n\n        tools_7(self.onBeforeImageLoad) && self.onBeforeImageLoad(self.ctx, self);\n\n        return getImageInfo({\n            src: src\n        })\n            .then(function (res: any) {\n                var innerAspectRadio = res.width / res.height;\n                var customAspectRadio = width / height;\n\n                self.croperTarget = res.path;\n\n                if (innerAspectRadio < customAspectRadio) {\n                    self.rectX = x;\n                    self.baseWidth = width;\n                    self.baseHeight = width / innerAspectRadio;\n                    self.rectY = y - Math.abs((height - self.baseHeight) / 2);\n                } else {\n                    self.rectY = y;\n                    self.baseWidth = height * innerAspectRadio;\n                    self.baseHeight = height;\n                    self.rectX = x - Math.abs((width - self.baseWidth) / 2);\n                }\n\n                self.imgLeft = self.rectX;\n                self.imgTop = self.rectY;\n                self.scaleWidth = self.baseWidth;\n                self.scaleHeight = self.baseHeight;\n\n                self.update();\n\n                return new Promise(function (resolve) {\n                    self.updateCanvas(resolve);\n                });\n            })\n            .then(function () {\n                tools_7(self.onImageLoad) && self.onImageLoad(self.ctx, self);\n            });\n    };\n\n    self.removeImage = function () {\n        self.src = '';\n        self.croperTarget = '';\n        return draw(self.ctx);\n    };\n\n    self.getCropperBase64 = function (done: any) {\n        if (done === void 0) done = function () {};\n\n        CanvasToBase64.convertToBMP(\n            {\n                canvasId: id,\n                x: x,\n                y: y,\n                width: width,\n                height: height\n            },\n            done\n        );\n    };\n\n    self.getCropperImage = function (opt: any, fn: any) {\n        var customOptions = opt;\n\n        var canvasOptions = {\n            canvasId: id,\n            x: x,\n            y: y,\n            width: width,\n            height: height\n        };\n\n        var task = function () {\n            return Promise.resolve();\n        };\n\n        if (tools_10(customOptions) && customOptions.original) {\n            // original mode\n            task = function () {\n                self.targetCtx.drawImage(\n                    self.croperTarget,\n                    self.imgLeft * pixelRatio,\n                    self.imgTop * pixelRatio,\n                    self.scaleWidth * pixelRatio,\n                    self.scaleHeight * pixelRatio\n                );\n\n                canvasOptions = {\n                    canvasId: targetId,\n                    x: x * pixelRatio,\n                    y: y * pixelRatio,\n                    width: width * pixelRatio,\n                    height: height * pixelRatio\n                };\n\n                return draw(self.targetCtx);\n            };\n        }\n\n        return task()\n            .then(function () {\n                if (tools_10(customOptions)) {\n                    canvasOptions = Object.assign({}, canvasOptions, customOptions);\n                }\n\n                if (tools_7(customOptions)) {\n                    fn = customOptions;\n                }\n\n                var arg = canvasOptions.componentContext\n                    ? [canvasOptions, canvasOptions.componentContext]\n                    : [canvasOptions];\n\n                return canvasToTempFilePath.apply(null, arg);\n            })\n            .then(function (res: any) {\n                var tempFilePath = res.tempFilePath;\n\n                return tools_7(fn) ? fn.call(self, tempFilePath, null) : tempFilePath;\n            })\n            .catch(function (err: any) {\n                if (tools_7(fn)) {\n                    fn.call(self, null, err);\n                } else {\n                    throw err;\n                }\n            });\n    };\n}\n\n/**\n * 获取最新缩放值\n * @param oldScale 上一次触摸结束后的缩放值\n * @param oldDistance 上一次触摸结束后的双指距离\n * @param zoom 缩放系数\n * @param touch0 第一指touch对象\n * @param touch1 第二指touch对象\n * @returns {*}\n */\nvar getNewScale = function (oldScale: any, oldDistance: any, zoom: any, touch0: any, touch1: any) {\n    var xMove, yMove, newDistance;\n    // 计算二指最新距离\n    xMove = Math.round(touch1.x - touch0.x);\n    yMove = Math.round(touch1.y - touch0.y);\n    newDistance = Math.round(Math.sqrt(xMove * xMove + yMove * yMove));\n\n    return oldScale + 0.001 * zoom * (newDistance - oldDistance);\n};\n\nfunction update(this: any) {\n    var self = this;\n\n    if (!self.src) {\n        return;\n    }\n\n    self.__oneTouchStart = function (touch: any) {\n        self.touchX0 = Math.round(touch.x);\n        self.touchY0 = Math.round(touch.y);\n    };\n\n    self.__oneTouchMove = function (touch: any) {\n        var xMove, yMove;\n        // 计算单指移动的距离\n        if (self.touchended) {\n            return self.updateCanvas();\n        }\n        xMove = Math.round(touch.x - self.touchX0);\n        yMove = Math.round(touch.y - self.touchY0);\n\n        var imgLeft = Math.round(self.rectX + xMove);\n        var imgTop = Math.round(self.rectY + yMove);\n\n        self.outsideBound(imgLeft, imgTop);\n\n        self.updateCanvas();\n    };\n\n    self.__twoTouchStart = function (touch0: any, touch1: any) {\n        var xMove, yMove, oldDistance;\n\n        self.touchX1 = Math.round(self.rectX + self.scaleWidth / 2);\n        self.touchY1 = Math.round(self.rectY + self.scaleHeight / 2);\n\n        // 计算两指距离\n        xMove = Math.round(touch1.x - touch0.x);\n        yMove = Math.round(touch1.y - touch0.y);\n        oldDistance = Math.round(Math.sqrt(xMove * xMove + yMove * yMove));\n\n        self.oldDistance = oldDistance;\n    };\n\n    self.__twoTouchMove = function (touch0: any, touch1: any) {\n        var oldScale = self.oldScale;\n        var oldDistance = self.oldDistance;\n        var scale = self.scale;\n        var zoom = self.zoom;\n\n        self.newScale = getNewScale(oldScale, oldDistance, zoom, touch0, touch1);\n\n        //  设定缩放范围\n        self.newScale <= 1 && (self.newScale = 1);\n        self.newScale >= scale && (self.newScale = scale);\n\n        self.scaleWidth = Math.round(self.newScale * self.baseWidth);\n        self.scaleHeight = Math.round(self.newScale * self.baseHeight);\n        var imgLeft = Math.round(self.touchX1 - self.scaleWidth / 2);\n        var imgTop = Math.round(self.touchY1 - self.scaleHeight / 2);\n\n        self.outsideBound(imgLeft, imgTop);\n\n        self.updateCanvas();\n    };\n\n    self.__xtouchEnd = function () {\n        self.oldScale = self.newScale;\n        self.rectX = self.imgLeft;\n        self.rectY = self.imgTop;\n    };\n}\n\nvar handle = {\n    //  图片手势初始监测\n    touchStart: function touchStart(e: any) {\n        var self = this;\n        var ref = e.touches;\n        var touch0 = ref[0];\n        var touch1 = ref[1];\n\n        if (!self.src) {\n            return;\n        }\n\n        setTouchState(self, true, null, null);\n\n        // 计算第一个触摸点的位置，并参照改点进行缩放\n        self.__oneTouchStart(touch0);\n\n        // 两指手势触发\n        if (e.touches.length >= 2) {\n            self.__twoTouchStart(touch0, touch1);\n        }\n    },\n\n    //  图片手势动态缩放\n    touchMove: function touchMove(e: any) {\n        var self = this;\n        var ref = e.touches;\n        var touch0 = ref[0];\n        var touch1 = ref[1];\n\n        if (!self.src) {\n            return;\n        }\n\n        setTouchState(self, null, true);\n\n        // 单指手势时触发\n        if (e.touches.length === 1) {\n            self.__oneTouchMove(touch0);\n        }\n        // 两指手势触发\n        if (e.touches.length >= 2) {\n            self.__twoTouchMove(touch0, touch1);\n        }\n    },\n\n    touchEnd: function touchEnd(e: any) {\n        var self = this;\n\n        if (!self.src) {\n            return;\n        }\n\n        setTouchState(self, false, false, true);\n        self.__xtouchEnd();\n    }\n};\n\nfunction cut(this: any) {\n    var self = this;\n    var boundWidth = self.width; // 裁剪框默认宽度，即整个画布宽度\n    var boundHeight = self.height;\n    // 裁剪框默认高度，即整个画布高度\n    var ref = self.cut;\n    var x = ref.x;\n    if (x === void 0) x = 0;\n    var y = ref.y;\n    if (y === void 0) y = 0;\n    var width = ref.width;\n    if (width === void 0) width = boundWidth;\n    var height = ref.height;\n    if (height === void 0) height = boundHeight;\n\n    /**\n     * 设置边界\n     * @param imgLeft 图片左上角横坐标值\n     * @param imgTop 图片左上角纵坐标值\n     */\n    self.outsideBound = function (imgLeft: any, imgTop: any) {\n        self.imgLeft =\n            imgLeft >= x ? x : self.scaleWidth + imgLeft - x <= width ? x + width - self.scaleWidth : imgLeft;\n\n        self.imgTop =\n            imgTop >= y ? y : self.scaleHeight + imgTop - y <= height ? y + height - self.scaleHeight : imgTop;\n    };\n\n    /**\n     * 设置边界样式\n     * @param color\t边界颜色\n     */\n    self.setBoundStyle = function (ref: any) {\n        if (ref === void 0) ref = {};\n        var color = ref.color;\n        if (color === void 0) color = 'var(--u-type-success-dark)';\n        var mask = ref.mask;\n        if (mask === void 0) mask = 'rgba(0, 0, 0, 0.3)';\n        var lineWidth = ref.lineWidth;\n        if (lineWidth === void 0) lineWidth = 1;\n\n        var half = lineWidth / 2;\n        var boundOption = [\n            {\n                start: {\n                    x: x - half,\n                    y: y + 10 - half\n                },\n                step1: {\n                    x: x - half,\n                    y: y - half\n                },\n                step2: {\n                    x: x + 10 - half,\n                    y: y - half\n                }\n            },\n            {\n                start: {\n                    x: x - half,\n                    y: y + height - 10 + half\n                },\n                step1: {\n                    x: x - half,\n                    y: y + height + half\n                },\n                step2: {\n                    x: x + 10 - half,\n                    y: y + height + half\n                }\n            },\n            {\n                start: {\n                    x: x + width - 10 + half,\n                    y: y - half\n                },\n                step1: {\n                    x: x + width + half,\n                    y: y - half\n                },\n                step2: {\n                    x: x + width + half,\n                    y: y + 10 - half\n                }\n            },\n            {\n                start: {\n                    x: x + width + half,\n                    y: y + height - 10 + half\n                },\n                step1: {\n                    x: x + width + half,\n                    y: y + height + half\n                },\n                step2: {\n                    x: x + width - 10 + half,\n                    y: y + height + half\n                }\n            }\n        ];\n\n        // 绘制半透明层\n        self.ctx.beginPath();\n        self.ctx.setFillStyle(mask);\n        self.ctx.fillRect(0, 0, x, boundHeight);\n        self.ctx.fillRect(x, 0, width, y);\n        self.ctx.fillRect(x, y + height, width, boundHeight - y - height);\n        self.ctx.fillRect(x + width, 0, boundWidth - x - width, boundHeight);\n        self.ctx.fill();\n\n        boundOption.forEach(function (op: any) {\n            self.ctx.beginPath();\n            self.ctx.setStrokeStyle(color);\n            self.ctx.setLineWidth(lineWidth);\n            self.ctx.moveTo(op.start.x, op.start.y);\n            self.ctx.lineTo(op.step1.x, op.step1.y);\n            self.ctx.lineTo(op.step2.x, op.step2.y);\n            self.ctx.stroke();\n        });\n    };\n}\n\nvar version = '1.3.9';\n\nvar WeCropper = function WeCropper(params: any) {\n    var self = this;\n    var _default: any = {};\n\n    validator(self, DEFAULT);\n\n    Object.keys(DEFAULT).forEach(function (key: any) {\n        _default[key] = DEFAULT[key].default;\n    });\n    Object.assign(self, _default, params);\n\n    self.prepare();\n    self.attachPage();\n    self.createCtx();\n    self.observer();\n    self.cutt();\n    self.methods();\n    self.init();\n    self.update();\n\n    return self;\n};\n\nWeCropper.prototype.init = function init() {\n    var self = this;\n    var src = self.src;\n\n    self.version = version;\n\n    typeof self.onReady === 'function' && self.onReady(self.ctx, self);\n\n    if (src) {\n        self.pushOrign(src);\n    } else {\n        self.updateCanvas();\n    }\n    setTouchState(self, false, false, false);\n\n    self.oldScale = 1;\n    self.newScale = 1;\n\n    return self;\n};\n\nObject.assign(WeCropper.prototype, handle);\n\nWeCropper.prototype.prepare = prepare;\nWeCropper.prototype.observer = observer;\nWeCropper.prototype.methods = methods;\nWeCropper.prototype.cutt = cut;\nWeCropper.prototype.update = update;\n\n// 结尾导出 WeCropper\nexport default WeCropper;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-back-top/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { Shape } from '../../types/global';\n\n// u-back-top 组件 props\nexport const BackTopProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 返回顶部的形状，circle-圆形，square-方形 */\n    mode: { type: String as PropType<Shape>, default: 'circle' },\n    /** 自定义图标 */\n    icon: { type: String, default: 'arrow-upward' },\n    /** 提示文字 */\n    tips: { type: String, default: '' },\n    /** 返回顶部滚动时间 */\n    duration: { type: [Number, String], default: 100 },\n    /** 滚动距离 */\n    scrollTop: { type: [Number, String], default: 0 },\n    /** 距离顶部多少距离显示，单位rpx */\n    top: { type: [Number, String], default: 400 },\n    /** 返回顶部按钮到底部的距离，单位rpx */\n    bottom: { type: [Number, String], default: 200 },\n    /** 返回顶部按钮到右边的距离，单位rpx */\n    right: { type: [Number, String], default: 40 },\n    /** 层级 */\n    zIndex: { type: [Number, String], default: '9' },\n    /** 图标的样式，对象形式 */\n    iconStyle: {\n        type: Object as PropType<Record<string, any>>,\n        default: () => ({\n            color: 'var(--u-tips-color)',\n            fontSize: '38rpx'\n        })\n    }\n};\n\nexport type BackTopProps = ExtractPropTypes<typeof BackTopProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-back-top/u-back-top.vue",
    "content": "<template>\n    <view\n        @tap=\"backToTop\"\n        class=\"u-back-top\"\n        :class=\"['u-back-top--mode--' + mode, customClass]\"\n        :style=\"\n            $u.toStyle(\n                {\n                    bottom: bottom + 'rpx',\n                    right: right + 'rpx',\n                    borderRadius: mode == 'circle' ? '10000rpx' : '8rpx',\n                    zIndex: uZIndex,\n                    opacity: opacity\n                },\n                customStyle\n            )\n        \"\n    >\n        <view class=\"u-back-top__content\" v-if=\"!slots.default\">\n            <u-icon @click=\"backToTop\" :name=\"icon\" :custom-style=\"iconStyle\"></u-icon>\n            <view class=\"u-back-top__content__tips\">\n                {{ tips }}\n            </view>\n        </view>\n        <slot v-else />\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-back-top',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, useSlots } from 'vue';\nimport { BackTopProps } from './types';\nimport { $u } from '../../';\n\n/**\n * back-top 返回顶部按钮\n * @description 页面滚动时显示的返回顶部按钮\n * @property {String} mode 返回顶部的形状，circle-圆形，square-方形\n * @property {String} icon 自定义图标\n * @property {String} tips 提示文字\n * @property {Number|String} duration 返回顶部滚动时间\n * @property {Number|String} scrollTop 滚动距离\n * @property {Number|String} top 距离顶部多少距离显示，单位rpx\n * @property {Number|String} bottom 返回顶部按钮到底部的距离，单位rpx\n * @property {Number|String} right 返回顶部按钮到右边的距离，单位rpx\n * @property {Number|String} zIndex 层级\n * @property {Object} iconStyle 图标的样式，对象形式\n * @property {Object} customStyle 整个组件的样式\n */\nconst props = defineProps(BackTopProps);\n\nconst slots = useSlots();\n\n// 不透明度，为了让组件有一个显示和隐藏的过渡动画\nconst opacity = ref(0);\n// 组件的z-index值，隐藏时设置为-1，就会看不到\nconst uZIndex = ref(-1);\n\n/**\n * 计算是否显示返回顶部按钮\n * 由于scrollTop为页面的滚动距离，默认为px单位，这里将用于传入的top(rpx)值\n * 转为px用于比较，如果滚动条到顶的距离大于设定的距离，就显示返回顶部的按钮\n */\nconst showBackTop = computed(() => {\n    // uni.upx2px 用于将 rpx 转为 px\n    return (\n        Number(props.scrollTop) >\n        (typeof uni !== 'undefined' && uni.upx2px ? uni.upx2px(Number(props.top)) : Number(props.top))\n    );\n    // #else\n    // return Number(props.scrollTop) > Number(props.top)\n});\n\n// 监听组件的显示与隐藏状态，修改组件的层级和不透明度\n// 让组件有显示和消失的动画效果，如果用v-if控制组件状态，将无设置动画效果\nwatch(showBackTop, nVal => {\n    if (nVal) {\n        uZIndex.value = Number(props.zIndex);\n        opacity.value = 1;\n    } else {\n        uZIndex.value = -1;\n        opacity.value = 0;\n    }\n});\n\n/**\n * 返回顶部方法\n */\nfunction backToTop() {\n    // uni.pageScrollTo 用于页面滚动到顶部\n    if (typeof uni !== 'undefined' && uni.pageScrollTo) {\n        uni.pageScrollTo({\n            scrollTop: 0,\n            duration: Number(props.duration)\n        });\n    }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-back-top {\n    width: 80rpx;\n    height: 80rpx;\n    position: fixed;\n    z-index: 9;\n    @include vue-flex;\n    flex-direction: column;\n    justify-content: center;\n    background-color: var(--u-divider-color);\n    color: $u-content-color;\n    align-items: center;\n    transition: opacity 0.4s;\n\n    &__content {\n        @include vue-flex;\n        flex-direction: column;\n        align-items: center;\n\n        &__tips {\n            font-size: 24rpx;\n            transform: scale(0.8);\n            line-height: 1;\n        }\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-badge/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { BadgeSize, ThemeType } from '../../types/global';\n\n/**\n * badge 角标类型定义\n * @description 供 u-badge 组件 props 使用\n */\n\nexport const BadgeProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 使用预设的背景颜色 primary,warning,success,error,info */\n    type: { type: String as PropType<ThemeType>, default: 'error' },\n    /** Badge的尺寸，default, mini */\n    size: { type: String as PropType<BadgeSize>, default: 'default' },\n    /** 是否是圆点 */\n    isDot: { type: Boolean, default: false },\n    /** 显示的数值内容 */\n    count: { type: [Number, String], default: undefined },\n    /** 展示封顶的数字值 */\n    overflowCount: { type: Number, default: 99 },\n    /** 当数值为 0 时，是否展示 Badge */\n    showZero: { type: Boolean, default: false },\n    /** 位置偏移 [number, number] */\n    offset: { type: Array as unknown as PropType<[number, number]>, default: () => [20, 20] },\n    /** 是否开启绝对定位，开启了offset才会起作用 */\n    absolute: { type: Boolean, default: true },\n    /** 字体大小 */\n    fontSize: { type: [String, Number], default: '24' },\n    /** 字体颜色 */\n    color: { type: String, default: 'var(--u-white-color)' },\n    /** badge的背景颜色 */\n    bgColor: { type: String, default: '' },\n    /** 是否让badge组件的中心点和父组件右上角重合，配置的话，offset将会失效 */\n    isCenter: { type: Boolean, default: false }\n};\n\nexport type BadgeProps = ExtractPropTypes<typeof BadgeProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-badge/u-badge.vue",
    "content": "<template>\n    <view\n        v-if=\"show\"\n        class=\"u-badge\"\n        :class=\"[\n            isDot ? 'u-badge-dot' : '',\n            size === 'mini' ? 'u-badge-mini' : '',\n            type ? 'u-badge--bg--' + type : '',\n            customClass\n        ]\"\n        :style=\"\n            $u.toStyle(\n                {\n                    top: (offset as number[])[0] + 'rpx',\n                    right: (offset as number[])[1] + 'rpx',\n                    fontSize: fontSize + 'rpx',\n                    position: absolute ? 'absolute' : 'static',\n                    color: color,\n                    backgroundColor: bgColor\n                },\n                boxStyle,\n                customStyle\n            )\n        \"\n    >\n        {{ showText }}\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-badge',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { BadgeProps } from './types';\nimport { $u } from '../..';\n\n/**\n * badge 角标\n * @description 本组件一般用于展示头像的地方，如个人中心，或者评论列表页的用户头像展示等场所。\n * @tutorial https://uviewpro.cn/zh/components/badge.html\n * @property {String|Number} count 展示的数字，大于 overflowCount 时显示为 ${overflowCount}+，为0且show-zero为false时隐藏\n * @property {Boolean} is-dot 不展示数字，只有一个小点（默认false）\n * @property {Boolean} absolute 组件是否绝对定位，为true时，offset参数才有效（默认true）\n * @property {String|Number} overflow-count 展示封顶的数字值（默认99）\n * @property {String} type 使用预设的背景颜色（默认error）\n * @property {Boolean} show-zero 当数值为 0 时，是否展示 Badge（默认false）\n * @property {String} size Badge的尺寸，设为mini会得到小一号的Badge（默认default）\n * @property {Array} offset 设置badge的位置偏移，格式为 [x, y]，也即设置的为top和right的值，单位rpx。absolute为true时有效（默认[20, 20]）\n * @property {String} color 字体颜色（默认var(--u-white-color)）\n * @property {String} bgColor 背景颜色，优先级比type高，如设置，type参数会失效\n * @property {Boolean} is-center 组件中心点是否和父组件右上角重合，优先级比offset高，如设置，offset参数会失效（默认false）\n * @example <u-badge type=\"error\" count=\"7\"></u-badge>\n */\n\nconst props = defineProps(BadgeProps);\n\n/**\n * 计算 badge 的定位和变换样式\n */\nconst boxStyle = computed(() => {\n    let style: Record<string, any> = {};\n    if (props.isCenter) {\n        style.top = 0;\n        style.right = 0;\n        // Y轴-50%，意味着badge向上移动了badge自身高度一半，X轴50%，意味着向右移动了自身宽度一半\n        style.transform = 'translateY(-50%) translateX(50%)';\n    } else {\n        style.top = (props.offset as number[])[0] + 'rpx';\n        style.right = (props.offset as number[])[1] + 'rpx';\n        style.transform = 'translateY(0) translateX(0)';\n    }\n    // 如果尺寸为mini，后接上scale()\n    if (props.size === 'mini') {\n        style.transform = style.transform + ' scale(0.8)';\n    }\n    return style;\n});\n\n/**\n * 计算显示的文本内容\n */\nconst showText = computed(() => {\n    if (props.isDot) return '';\n    else {\n        if (Number(props.count) > props.overflowCount) return `${props.overflowCount}+`;\n        else return props.count;\n    }\n});\n\n/**\n * 是否显示组件\n */\nconst show = computed(() => {\n    // 如果count的值为0，并且showZero设置为false，不显示组件\n    if (Number(props.count) === 0 && props.showZero === false) return false;\n    else return true;\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-badge {\n    /* #ifndef APP-NVUE */\n    display: inline-flex;\n    /* #endif */\n    justify-content: center;\n    align-items: center;\n    line-height: 24rpx;\n    padding: 4rpx 8rpx;\n    border-radius: 100rpx;\n    z-index: 9;\n\n    &--bg--primary {\n        background-color: $u-type-primary;\n    }\n    &--bg--error {\n        background-color: $u-type-error;\n    }\n    &--bg--success {\n        background-color: $u-type-success;\n    }\n    &--bg--info {\n        background-color: $u-type-info;\n    }\n    &--bg--warning {\n        background-color: $u-type-warning;\n    }\n}\n\n.u-badge-dot {\n    height: 16rpx;\n    width: 16rpx;\n    border-radius: 100rpx;\n    line-height: 1;\n}\n\n.u-badge-mini {\n    transform: scale(0.8);\n    transform-origin: center center;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-button/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { ButtonFormType, ButtonOpenType, ButtonScope, ButtonSize, ButtonType, Shape } from '../../types/global';\n\n/**\n * button 按钮类型定义\n * @description 供 u-button 组件 props 使用\n */\n\nexport const ButtonProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 按钮文本 */\n    text: { type: String, default: '' },\n    /** 是否细边框 */\n    hairLine: { type: Boolean, default: true },\n    /** 按钮的预置样式，default，primary，error，warning，success */\n    type: { type: String as PropType<ButtonType>, default: 'default' },\n    /** 按钮尺寸，default，large, medium=small，mini */\n    size: { type: String as PropType<ButtonSize>, default: 'default' },\n    /** 按钮形状，circle（两边为半圆），square（带圆角） */\n    shape: { type: String as PropType<Shape>, default: 'square' },\n    /** 按钮是否镂空 */\n    plain: { type: Boolean, default: false },\n    /** 是否禁止状态 */\n    disabled: { type: Boolean, default: false },\n    /** 是否加载中 */\n    loading: { type: Boolean, default: false },\n    /** 支付宝小程序，当 open-type 为 getAuthorize 时有效 */\n    scope: { type: String as PropType<ButtonScope>, default: '' },\n    /** 开放能力，具体请看uniapp稳定关于button组件部分说明 */\n    openType: { type: String as PropType<ButtonOpenType>, default: '' },\n    /** 用于 <form> 组件，点击分别会触发 <form> 组件的 submit/reset 事件 */\n    formType: { type: String as PropType<ButtonFormType>, default: '' },\n    /** 打开 APP 时，向 APP 传递的参数，open-type=launchApp时有效 */\n    appParameter: { type: String, default: '' },\n    /** 指定是否阻止本节点的祖先节点出现点击态，微信小程序有效 */\n    hoverStopPropagation: { type: Boolean, default: false },\n    /** 指定返回用户信息的语言，zh_CN 简体中文，zh_TW 繁体中文，en 英文。只微信小程序有效 */\n    lang: { type: String, default: 'en' },\n    /** 会话来源，open-type=\"contact\"时有效。只微信小程序有效 */\n    sessionFrom: { type: String, default: '' },\n    /** 会话内消息卡片标题，open-type=\"contact\"时有效 */\n    sendMessageTitle: { type: String, default: '' },\n    /** 会话内消息卡片点击跳转小程序路径，open-type=\"contact\"时有效 */\n    sendMessagePath: { type: String, default: '' },\n    /** 会话内消息卡片图片，open-type=\"contact\"时有效 */\n    sendMessageImg: { type: String, default: '' },\n    /** 是否显示会话内消息卡片，open-type=\"contact\"时有效 */\n    showMessageCard: { type: Boolean, default: false },\n    /** 手指按（触摸）按钮时按钮时的背景颜色 */\n    hoverBgColor: { type: String, default: '' },\n    /** 水波纹的背景颜色 */\n    rippleBgColor: { type: String, default: '' },\n    /** 是否开启水波纹效果 */\n    ripple: { type: Boolean, default: false },\n    /** 按下的类名 */\n    hoverClass: { type: String, default: '' },\n    /** 额外传参参数，用于小程序的data-xxx属性，通过target.dataset.name获取 */\n    dataName: { type: String, default: '' },\n    /** 节流，一定时间内只能触发一次 */\n    throttleTime: { type: [String, Number], default: 0 },\n    /** 按住后多久出现点击态，单位毫秒 */\n    hoverStartTime: { type: [String, Number], default: 20 },\n    /** 手指松开后点击态保留时间，单位毫秒 */\n    hoverStayTime: { type: [String, Number], default: 150 }\n};\n\nexport type ButtonProps = ExtractPropTypes<typeof ButtonProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-button/u-button.vue",
    "content": "<template>\n    <!-- prettier-ignore -->\n    <button\n        id=\"u-wave-btn\"\n        class=\"u-btn u-line-1 u-fix-ios-appearance\"\n        :class=\"[\n            'u-size-' + size,\n            plain ? 'u-btn--' + type + '--plain' : '',\n            loading ? 'u-loading' : '',\n            shape === 'circle' ? 'u-round-circle' : '',\n            hairLine ? showHairLineBorder : 'u-btn--bold-border',\n            'u-btn--' + type,\n            disabled ? `u-btn--${type}--disabled` : '',\n            customClass\n        ]\"\n        :hover-start-time=\"Number(hoverStartTime)\"\n        :hover-stay-time=\"Number(hoverStayTime)\"\n        :disabled=\"disabled\"\n        :form-type=\"(formType as any)\"\n        :open-type=\"disabled || loading ? undefined : openType\"\n        :app-parameter=\"appParameter\"\n        :hover-stop-propagation=\"hoverStopPropagation\"\n        :send-message-title=\"sendMessageTitle\"\n        :send-message-path=\"sendMessagePath\"\n        :lang=\"(lang as any)\"\n        :data-name=\"dataName\"\n        :session-from=\"sessionFrom\"\n        :send-message-img=\"sendMessageImg\"\n        :show-message-card=\"showMessageCard\"\n        @getAuthorize=\"getAuthorize\"\n        @getuserinfo=\"getuserinfo\"\n        @contact=\"contact\"\n        @getphonenumber=\"getphonenumber\"\n        @error=\"error\"\n        @launchapp=\"launchapp\"\n        @opensetting=\"opensetting\"\n        @chooseavatar=\"chooseavatar\"\n        @agreeprivacyauthorization=\"agreeprivacyauthorization\"\n        :style=\"\n            $u.toStyle(\n                {\n                    overflow: ripple ? 'hidden' : 'visible'\n                },\n                customStyle\n            )\n        \"\n        @tap.stop=\"click($event)\"\n        :hover-class=\"getHoverClass\"\n        :loading=\"loading\"\n    >\n        <slot>{{ props.text }}</slot>\n        <view\n            v-if=\"ripple\"\n            class=\"u-wave-ripple\"\n            :class=\"[waveActive ? 'u-wave-active' : '']\"\n            :style=\"{\n                top: rippleTop + 'px',\n                left: rippleLeft + 'px',\n                width: fields.targetWidth + 'px',\n                height: fields.targetWidth + 'px',\n                'background-color': rippleBgColor || 'rgba(0, 0, 0, 0.15)'\n            }\"\n        ></view>\n    </button>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-button',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, nextTick } from 'vue';\nimport { $u } from '../../';\nimport { ButtonProps } from './types';\n\n/**\n * button 按钮\n * @description Button 按钮\n * @tutorial https://uviewpro.cn/zh/components/button.html\n * @property {String} size 按钮的大小\n * @property {Boolean} ripple 是否开启点击水波纹效果\n * @property {String} ripple-bg-color 水波纹的背景色，ripple为true时有效\n * @property {String} type 按钮的样式类型\n * @property {Boolean} plain 按钮是否镂空，背景色透明\n * @property {Boolean} disabled 是否禁用\n * @property {Boolean} hair-line 是否显示按钮的细边框(默认true)\n * @property {String} shape 按钮外观形状，见文档说明\n * @property {Boolean} loading 按钮名称前是否带 loading 图标(App-nvue 平台，在 ios 上为雪花，Android上为圆圈)\n * @property {String} form-type 用于 <form> 组件，点击分别会触发 <form> 组件的 submit/reset 事件\n * @property {String} open-type 开放能力\n * @property {String} data-name 额外传参参数，用于小程序的data-xxx属性，通过target.dataset.name获取\n * @property {String} hover-class 指定按钮按下去的样式类。当 hover-class=\"none\" 时，没有点击态效果(App-nvue 平台暂不支持)\n * @property {Number} hover-start-time 按住后多久出现点击态，单位毫秒\n * @property {Number} hover-stay-time 手指松开后点击态保留时间，单位毫秒\n * @property {Object} custom-style 对按钮的自定义样式，对象形式，见文档说明\n * @property {String} app-parameter 打开 APP 时，向 APP 传递的参数，open-type=launchApp时有效\n * @property {Boolean} hover-stop-propagation 指定是否阻止本节点的祖先节点出现点击态，微信小程序有效\n * @property {String} lang 指定返回用户信息的语言，zh_CN 简体中文，zh_TW 繁体中文，en 英文。只微信小程序有效\n * @property {String} session-from 会话来源，open-type=\"contact\"时有效。只微信小程序有效\n * @property {String} send-message-title 会话内消息卡片标题，open-type=\"contact\"时有效\n * @property {String} send-message-path 会话内消息卡片点击跳转小程序路径，open-type=\"contact\"时有效\n * @property {String} send-message-img 会话内消息卡片图片，open-type=\"contact\"时有效\n * @property {Boolean} show-message-card 是否显示会话内消息卡片，open-type=\"contact\"时有效\n * @property {Number|String} throttle-time 节流，一定时间内只能触发一次，单位毫秒\n * @property {String} scope 支付宝小程序，当 open-type 为 getAuthorize 时有效。可选值：'phoneNumber' | 'userInfo'\n * @event {Function} click 按钮点击\n * @event {Function} getphonenumber open-type=\"getPhoneNumber\"时有效\n * @event {Function} getuserinfo 用户点击该按钮时，会返回获取到的用户信息，从返回参数的detail中获取到的值同uni.getUserInfo\n * @event {Function} error 当使用开放能力时，发生错误的回调\n * @event {Function} opensetting 在打开授权设置页并关闭后回调\n * @event {Function} launchapp 打开 APP 成功的回调\n * @event {Function} contact 客服消息回调\n * @event {Function} chooseavatar 头像选择回调\n * @event {Function} agreeprivacyauthorization 用户点击允许授权回调\n * @example <u-button>月落</u-button>\n */\n\nconst emit = defineEmits([\n    'click',\n    'getuserinfo',\n    'contact',\n    'getphonenumber',\n    'error',\n    'launchapp',\n    'opensetting',\n    'chooseavatar',\n    'agreeprivacyauthorization'\n]);\n\nconst props = defineProps(ButtonProps);\n\n/**\n * 按钮水波纹相关状态\n */\nconst rippleTop = ref(0); // 水波纹的起点Y坐标到按钮上边界的距离\nconst rippleLeft = ref(0); // 水波纹起点X坐标到按钮左边界的距离\nconst fields = ref<Record<string, any>>({}); // 波纹按钮节点信息\nconst waveActive = ref(false); // 激活水波纹\n\n/**\n * 当没有传bgColor变量时，按钮按下去的颜色类名\n * @returns {string}\n */\nconst getHoverClass = computed(() => {\n    // 如果开启水波纹效果，则不启用hover-class效果\n    if (props.loading || props.disabled || props.ripple) return '';\n    // 如果用户传了 hoverClass，优先使用用户的\n    if (props.hoverClass) return props.hoverClass;\n    let hoverClass = '';\n    hoverClass = props.plain ? 'u-' + props.type + '-plain-hover' : 'u-' + props.type + '-hover';\n    return hoverClass;\n});\n\n/**\n * 在'primary', 'success', 'error', 'warning'类型下，不显示边框，否则会造成四角有毛刺现象\n * @returns {string}\n */\nconst showHairLineBorder = computed(() => {\n    if (['primary', 'success', 'error', 'warning'].indexOf(props.type) >= 0 && !props.plain) {\n        return '';\n    } else {\n        return 'u-hairline-border';\n    }\n});\n\n/**\n * 按钮点击\n * @param e 事件对象\n * @emits click\n */\nfunction click(e: any) {\n    if (Number(props.throttleTime)) {\n        $u.throttle(() => {\n            clickAction(e);\n        }, Number(props.throttleTime));\n    } else {\n        clickAction(e);\n    }\n}\n\nfunction clickAction(e: any) {\n    // 如果按钮时disabled和loading状态，不触发水波纹效果\n    if (props.loading === true || props.disabled === true) return;\n    // 是否开启水波纹效果\n    if (props.ripple) {\n        // 每次点击时，移除上一次的类，再次添加，才能触发动画效果\n        waveActive.value = false;\n        nextTick(() => {\n            getWaveQuery(e);\n        });\n    }\n    emit('click', e);\n}\n\n/**\n * 查询按钮的节点信息\n * @param e 事件对象\n */\nfunction getWaveQuery(e: any) {\n    getElQuery().then((res: any[]) => {\n        // 查询返回的是一个数组节点\n        let data = res[0];\n        // 查询不到节点信息，不操作\n        if (!data.width || !data.width) return;\n        // 水波纹的最终形态是一个正方形(通过border-radius让其变为一个圆形)，这里要保证正方形的边长等于按钮的最长边\n        // 最终的方形（变换后的圆形）才能覆盖整个按钮\n        data.targetWidth = data.height > data.width ? data.height : data.width;\n        if (!data.targetWidth) return;\n        fields.value = data;\n        let touchesX = '',\n            touchesY = '';\n        // #ifdef MP-BAIDU\n        // @ts-ignore\n        touchesX = e.changedTouches[0].clientX;\n        touchesY = e.changedTouches[0].clientY;\n        // #endif\n        // #ifdef MP-ALIPAY\n        // @ts-ignore\n        touchesX = e.detail.clientX;\n        touchesY = e.detail.clientY;\n        // #endif\n        // #ifndef MP-BAIDU || MP-ALIPAY\n        // @ts-ignore\n        touchesX = e.touches[0].clientX;\n        touchesY = e.touches[0].clientY;\n        // #endif\n        // 获取触摸点相对于按钮上边和左边的x和y坐标，原理是通过屏幕的触摸点（touchesY），减去按钮的上边界data.top\n        // 但是由于`transform-origin`默认是center，所以这里再减去半径才是水波纹view应该的位置\n        // 总的来说，就是把水波纹的矩形（变换后的圆形）的中心点，移动到我们的触摸点位置\n        rippleTop.value = Number(touchesY) - data.top - data.targetWidth / 2;\n        rippleLeft.value = Number(touchesX) - data.left - data.targetWidth / 2;\n        nextTick(() => {\n            waveActive.value = true;\n        });\n    });\n}\n\n/**\n * 获取节点信息\n * @returns {Promise<any[]>}\n */\nfunction getElQuery(): Promise<any[]> {\n    return new Promise(resolve => {\n        let queryInfo: any = '';\n        // 获取元素节点信息，请查看uniapp相关文档\n        // https://uniapp.dcloud.io/api/ui/nodes-info?id=nodesrefboundingclientrect\n        // @ts-ignore\n        queryInfo = uni.createSelectorQuery().in(null);\n        // #ifdef MP-ALIPAY\n        // @ts-ignore\n        queryInfo = uni.createSelectorQuery();\n        // #endif\n        queryInfo.select('.u-btn').boundingClientRect();\n        queryInfo.exec((data: any) => {\n            resolve(data);\n        });\n    });\n}\n\n// 下面为对接uniapp官方按钮开放能力事件回调的对接\n/**\n * open-type=\"getPhoneNumber\"时有效\n */\nfunction getphonenumber(event: any) {\n    emit('getphonenumber', event);\n}\n/**\n * 用户点击该按钮时，会返回获取到的用户信息，从返回参数的detail中获取到的值同uni.getUserInfo\n */\nfunction getuserinfo(event: any) {\n    emit('getuserinfo', event);\n}\n/**\n * 当使用开放能力时，发生错误的回调\n */\nfunction error(event: any) {\n    emit('error', event);\n}\n/**\n * 在打开授权设置页并关闭后回调\n */\nfunction opensetting(event: any) {\n    emit('opensetting', event);\n}\n/**\n * 打开 APP 成功的回调\n */\nfunction launchapp(event: any) {\n    emit('launchapp', event);\n}\n\n/**\n * 支付宝小程序授权\n * @param event\n */\nfunction getAuthorize(event: any) {\n    if (props.scope === 'phoneNumber') {\n        getphonenumber(event);\n    } else if (props.scope === 'userInfo') {\n        getuserinfo(event);\n    }\n}\n\n/**\n * 客服消息回调\n * @param event\n */\nfunction contact(event: any) {\n    emit('contact', event);\n}\n/**\n * 头像选择回调\n * @param event\n */\nfunction chooseavatar(event: any) {\n    emit('chooseavatar', event);\n}\n/**\n * 用户点击允许授权回调\n * @param event\n */\nfunction agreeprivacyauthorization(event: any) {\n    emit('agreeprivacyauthorization', event);\n}\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n.u-btn::after {\n    border: none;\n}\n\n.u-btn {\n    position: relative;\n    border: 0;\n    //border-radius: 10rpx;\n    /* #ifndef APP-NVUE */\n    display: inline-flex;\n    /* #endif */\n    // 避免边框某些场景可能被“裁剪”，不能设置为hidden\n    overflow: visible;\n    line-height: 1;\n    @include vue-flex;\n    align-items: center;\n    justify-content: center;\n    cursor: pointer;\n    padding: 0 40rpx;\n    z-index: 1;\n    box-sizing: border-box;\n    transition: all 0.15s;\n\n    &--bold-border {\n        border: 1px solid var(--u-white-color);\n    }\n\n    &--default {\n        color: $u-content-color;\n        border-color: var(--u-light-color);\n        background-color: var(--u-bg-white);\n    }\n\n    &--primary {\n        color: var(--u-white-color);\n        border-color: $u-type-primary;\n        background-color: $u-type-primary;\n    }\n\n    &--success {\n        color: var(--u-white-color);\n        border-color: $u-type-success;\n        background-color: $u-type-success;\n    }\n\n    &--error {\n        color: var(--u-white-color);\n        border-color: $u-type-error;\n        background-color: $u-type-error;\n    }\n\n    &--warning {\n        color: var(--u-white-color);\n        border-color: $u-type-warning;\n        background-color: $u-type-warning;\n    }\n\n    &--default--disabled {\n        color: var(--u-white-color);\n        border-color: var(--u-border-color);\n        background-color: var(--u-bg-white);\n    }\n\n    &--primary--disabled {\n        color: var(--u-white-color) !important;\n        border-color: $u-type-primary-disabled !important;\n        background-color: $u-type-primary-disabled !important;\n    }\n\n    &--success--disabled {\n        color: var(--u-white-color) !important;\n        border-color: $u-type-success-disabled !important;\n        background-color: $u-type-success-disabled !important;\n    }\n\n    &--error--disabled {\n        color: var(--u-white-color) !important;\n        border-color: $u-type-error-disabled !important;\n        background-color: $u-type-error-disabled !important;\n    }\n\n    &--warning--disabled {\n        color: var(--u-white-color) !important;\n        border-color: $u-type-warning-disabled !important;\n        background-color: $u-type-warning-disabled !important;\n    }\n\n    &--primary--plain {\n        color: $u-type-primary !important;\n        border-color: $u-type-primary-disabled !important;\n        background-color: $u-type-primary-light !important;\n    }\n\n    &--success--plain {\n        color: $u-type-success !important;\n        border-color: $u-type-success-disabled !important;\n        background-color: $u-type-success-light !important;\n    }\n\n    &--error--plain {\n        color: $u-type-error !important;\n        border-color: $u-type-error-disabled !important;\n        background-color: $u-type-error-light !important;\n    }\n\n    &--warning--plain {\n        color: $u-type-warning !important;\n        border-color: $u-type-warning-disabled !important;\n        background-color: $u-type-warning-light !important;\n    }\n}\n\n.u-hairline-border:after {\n    content: ' ';\n    position: absolute;\n    pointer-events: none;\n    // 设置为border-box，意味着下面的scale缩小为0.5，实际上缩小的是伪元素的内容（border-box意味着内容不含border）\n    box-sizing: border-box;\n    // 中心点作为变形(scale())的原点\n    -webkit-transform-origin: 0 0;\n    transform-origin: 0 0;\n    left: 0;\n    top: 0;\n    width: 199.8%;\n    height: 199.7%;\n    -webkit-transform: scale(0.5, 0.5);\n    transform: scale(0.5, 0.5);\n    border: 1px solid currentColor;\n    z-index: 1;\n}\n\n.u-wave-ripple {\n    z-index: 0;\n    position: absolute;\n    border-radius: 100%;\n    background-clip: padding-box;\n    pointer-events: none;\n    user-select: none;\n    transform: scale(0);\n    opacity: 1;\n    transform-origin: center;\n}\n\n.u-wave-ripple.u-wave-active {\n    opacity: 0;\n    transform: scale(2);\n    transition:\n        opacity 1s linear,\n        transform 0.4s linear;\n}\n\n.u-round-circle {\n    border-radius: 100rpx;\n}\n\n.u-round-circle::after {\n    border-radius: 100rpx;\n}\n\n.u-loading::after {\n    background-color: hsla(0, 0%, 100%, 0.35);\n}\n\n.u-size-large {\n    font-size: 36rpx;\n    height: 100rpx;\n    line-height: 100rpx;\n}\n\n.u-size-default {\n    font-size: 30rpx;\n    height: 80rpx;\n    line-height: 80rpx;\n}\n\n.u-size-medium {\n    /* #ifndef APP-NVUE */\n    display: inline-flex;\n    /* #endif */\n    width: auto;\n    font-size: 26rpx;\n    height: 70rpx;\n    line-height: 70rpx;\n    padding: 0 80rpx;\n}\n\n.u-size-small {\n    /* #ifndef APP-NVUE */\n    display: inline-flex;\n    /* #endif */\n    width: auto;\n    font-size: 24rpx;\n    height: 60rpx;\n    line-height: 60rpx;\n    padding: 0 30rpx;\n}\n\n.u-size-mini {\n    /* #ifndef APP-NVUE */\n    display: inline-flex;\n    /* #endif */\n    width: auto;\n    font-size: 22rpx;\n    padding-top: 1px;\n    height: 50rpx;\n    line-height: 50rpx;\n    padding: 0 20rpx;\n}\n\n.u-primary-plain-hover {\n    color: var(--u-white-color) !important;\n    background: $u-type-primary-dark !important;\n}\n\n.u-default-plain-hover {\n    color: $u-type-primary-dark !important;\n    background: $u-type-primary-light !important;\n}\n\n.u-success-plain-hover {\n    color: var(--u-white-color) !important;\n    background: $u-type-success-dark !important;\n}\n\n.u-warning-plain-hover {\n    color: var(--u-white-color) !important;\n    background: $u-type-warning-dark !important;\n}\n\n.u-error-plain-hover {\n    color: var(--u-white-color) !important;\n    background: $u-type-error-dark !important;\n}\n\n.u-info-plain-hover {\n    color: var(--u-white-color) !important;\n    background: $u-type-info-dark !important;\n}\n\n.u-default-hover {\n    color: $u-type-primary-dark !important;\n    border-color: $u-type-primary-dark !important;\n    background-color: $u-type-primary-light !important;\n}\n\n.u-primary-hover {\n    background: $u-type-primary-dark !important;\n    color: var(--u-white-color);\n}\n\n.u-success-hover {\n    background: $u-type-success-dark !important;\n    color: var(--u-white-color);\n}\n\n.u-info-hover {\n    background: $u-type-info-dark !important;\n    color: var(--u-white-color);\n}\n\n.u-warning-hover {\n    background: $u-type-warning-dark !important;\n    color: var(--u-white-color);\n}\n\n.u-error-hover {\n    background: $u-type-error-dark !important;\n    color: var(--u-white-color);\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-calendar/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { CalendarChangeDate, CalendarChangeRange, CalendarMode, ThemeType } from '../../types/global';\nimport { getColor, useLocale } from '../../';\n\nconst { t } = useLocale();\n\n/**\n * calendar 日历类型定义\n * @description 供 u-calendar 组件 props 使用\n */\nexport const CalendarProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 是否开启底部安全区适配 */\n    safeAreaInsetBottom: { type: Boolean, default: false },\n    /** 是否允许通过点击遮罩关闭Picker */\n    maskCloseAble: { type: Boolean, default: true },\n    /** 通过双向绑定控制组件的弹出与收起 */\n    modelValue: { type: Boolean, default: false },\n    /** 弹出的z-index值 */\n    zIndex: { type: [String, Number], default: 0 },\n    /** 是否允许切换年份 */\n    changeYear: { type: Boolean, default: true },\n    /** 是否允许切换月份 */\n    changeMonth: { type: Boolean, default: true },\n    /** date-单个日期选择，range-开始日期+结束日期选择 */\n    mode: { type: String as PropType<CalendarMode>, default: 'date' },\n    /** 可切换的最大年份 */\n    maxYear: { type: [Number, String], default: 2050 },\n    /** 可切换的最小年份 */\n    minYear: { type: [Number, String], default: 1950 },\n    /** 最小可选日期(不在范围内日期禁用不可选) */\n    minDate: { type: [Number, String], default: '1950-01-01' },\n    /** 最大可选日期，默认最大值为今天，之后的日期不可选 */\n    maxDate: { type: [Number, String], default: '' },\n    /** 弹窗顶部左右两边的圆角值 */\n    borderRadius: { type: [String, Number], default: 20 },\n    /** 月份切换按钮箭头颜色 */\n    monthArrowColor: { type: String, default: 'var(--u-content-color)' },\n    /** 年份切换按钮箭头颜色 */\n    yearArrowColor: { type: String, default: 'var(--u-tips-color)' },\n    /** 默认日期字体颜色 */\n    color: { type: String, default: 'var(--u-main-color)' },\n    /** 选中|起始结束日期背景色 */\n    activeBgColor: { type: String, default: () => getColor('primary') },\n    /** 选中|起始结束日期字体颜色 */\n    activeColor: { type: String, default: 'var(--u-white-color)' },\n    /** 范围内日期背景色 */\n    rangeBgColor: { type: String, default: 'var(--u-type-primary-light)' },\n    /** 范围内日期字体颜色 */\n    rangeColor: { type: String, default: () => getColor('primary') },\n    /** mode=range时生效，起始日期自定义文案 */\n    startText: { type: String, default: () => t('uCalendar.startText') },\n    /** mode=range时生效，结束日期自定义文案 */\n    endText: { type: String, default: () => t('uCalendar.endText') },\n    /** 按钮样式类型 */\n    btnType: { type: String as PropType<ThemeType>, default: 'primary' },\n    /** 当前选中日期带选中效果 */\n    isActiveCurrent: { type: Boolean, default: true },\n    /** 初始化时是否默认选中今天，优先级低于 defaultDate/startDate/endDate */\n    defaultSelectToday: { type: Boolean, default: true },\n    /** 切换年月是否触发事件 mode=date时生效 */\n    isChange: { type: Boolean, default: false },\n    /** 是否显示右上角的关闭图标 */\n    closeable: { type: Boolean, default: true },\n    /** 顶部的提示文字 */\n    toolTip: { type: String, default: () => t('uCalendar.toolTip') },\n    /** 是否显示农历 */\n    showLunar: { type: Boolean, default: false },\n    /** 是否在页面中显示 */\n    isPage: { type: Boolean, default: false },\n    /** 默认选中的日期，mode=date时生效，格式：2024-01-01 */\n    defaultDate: { type: String, default: '' },\n    /** 默认选中的开始日期，mode=range时生效，格式：2024-01-01 */\n    startDate: { type: String, default: '' },\n    /** 默认选中的结束日期，mode=range时生效，格式：2024-01-01 */\n    endDate: { type: String, default: '' },\n    /** 是否只读，只读模式下禁止点击选择日期 */\n    readonly: { type: Boolean, default: false },\n    /** 已打卡日期列表，格式：['2024-01-01', '2024-01-02'] */\n    checkedDates: { type: Array as PropType<string[]>, default: () => [] },\n    /** 打卡日期背景色 */\n    checkedBgColor: { type: String, default: 'var(--u-type-warning)' },\n    /** 打卡日期字体颜色 */\n    checkedColor: { type: String, default: 'var(--u-white-color)' },\n    /** 今日是否已打卡 */\n    todayChecked: { type: Boolean, default: false },\n    /** 今日已打卡背景色 */\n    todayCheckedBgColor: { type: String, default: 'var(--u-type-success)' },\n    /** 未打卡日期背景色 */\n    uncheckedBgColor: { type: String, default: 'var(--u-light-color)' },\n    /** 未打卡日期字体颜色 */\n    uncheckedColor: { type: String, default: 'var(--u-white-color)' },\n    /** 是否启用打卡签到模式（未打卡日期显示灰色） */\n    checkinMode: { type: Boolean, default: false },\n    /** 节假日列表，格式：['2024-01-01', '2024-01-02'] */\n    holidays: { type: Array as PropType<string[]>, default: () => [] },\n    /** 节假日文字颜色 */\n    holidayColor: { type: String, default: 'var(--u-type-error)' },\n    /** 加班日列表，格式：['2024-01-06', '2024-01-07'] */\n    workdays: { type: Array as PropType<string[]>, default: () => [] },\n    /** 加班日文字颜色 */\n    workdayColor: { type: String, default: 'var(--u-type-primary)' },\n    /** 节日配置，格式：{ '2024-04-04': '清明节', '2024-04-01': '愚人节' } */\n    festivals: { type: Object as PropType<Record<string, string>>, default: () => ({}) },\n    /** 节日文字颜色 */\n    festivalColor: { type: String, default: 'var(--u-type-primary)' },\n    /** 是否显示内置节日（中国传统节日） */\n    showFestival: { type: Boolean, default: false },\n    /** 是否启用自定义日期内容插槽（微信小程序需要显式声明） */\n    useDateSlot: { type: Boolean, default: false }\n};\n\nexport type CalendarProps = ExtractPropTypes<typeof CalendarProps>;\n\nexport type CalendarEmits = {\n    (e: 'update:modelValue', value: boolean): void;\n    (e: 'input', value: boolean): void;\n    (e: 'change', value: CalendarChangeDate | CalendarChangeRange): void;\n};\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-calendar/u-calendar.vue",
    "content": "<template>\n    <u-popup\n        v-model=\"popupValue\"\n        length=\"auto\"\n        :maskCloseAble=\"maskCloseAble\"\n        :mode=\"props.isPage ? 'inline' : 'bottom'\"\n        :popup=\"false\"\n        :safeAreaInsetBottom=\"safeAreaInsetBottom\"\n        :z-index=\"uZIndex\"\n        :border-radius=\"borderRadius\"\n        :closeable=\"closeable\"\n        @close=\"close\"\n    >\n        <view\n            class=\"u-calendar\"\n            :class=\"[props.customClass, { 'u-calendar--page': props.isPage }]\"\n            :style=\"$u.toStyle(customStyle)\"\n        >\n            <view class=\"u-calendar__header\" v-if=\"!props.isPage\">\n                <view class=\"u-calendar__header__text\" v-if=\"!slots.tooltip\">\n                    {{ toolTip }}\n                </view>\n                <slot v-else name=\"tooltip\" />\n            </view>\n            <view class=\"u-calendar__action u-flex u-row-center\">\n                <view class=\"u-calendar__action__icon\">\n                    <u-icon\n                        v-if=\"changeYear\"\n                        name=\"arrow-left-double\"\n                        :color=\"yearArrowColor\"\n                        @click=\"changeYearHandler(0)\"\n                    ></u-icon>\n                </view>\n                <view class=\"u-calendar__action__icon\">\n                    <u-icon\n                        v-if=\"changeMonth\"\n                        name=\"arrow-left\"\n                        :color=\"monthArrowColor\"\n                        @click=\"changeMonthHandler(0)\"\n                    ></u-icon>\n                </view>\n                <view class=\"u-calendar__action__text\">{{ showTitle }}</view>\n                <view class=\"u-calendar__action__icon\">\n                    <u-icon\n                        v-if=\"changeMonth\"\n                        name=\"arrow-right\"\n                        :color=\"monthArrowColor\"\n                        @click=\"changeMonthHandler(1)\"\n                    ></u-icon>\n                </view>\n                <view class=\"u-calendar__action__icon\">\n                    <u-icon\n                        v-if=\"changeYear\"\n                        name=\"arrow-right-double\"\n                        :color=\"yearArrowColor\"\n                        @click=\"changeYearHandler(1)\"\n                    ></u-icon>\n                </view>\n            </view>\n            <view class=\"u-calendar__week-day\">\n                <view class=\"u-calendar__week-day__text\" v-for=\"(item, index) in weekDayZh\" :key=\"index\">\n                    {{ item }}\n                </view>\n            </view>\n            <view class=\"u-calendar__content\">\n                <!-- 前置空白部分 -->\n                <block v-for=\"(item, index) in weekdayArr\" :key=\"index\">\n                    <view class=\"u-calendar__content__item\"></view>\n                </block>\n                <view\n                    class=\"u-calendar__content__item\"\n                    :class=\"{\n                        'u-hover-class': openDisAbled(year, month, index + 1),\n                        'u-calendar__content--start-date':\n                            (mode == 'range' && startDate == `${year}-${formatNum(month)}-${formatNum(index + 1)}`) ||\n                            mode == 'date',\n                        'u-calendar__content--end-date':\n                            (mode == 'range' && endDate == `${year}-${formatNum(month)}-${formatNum(index + 1)}`) ||\n                            mode == 'date',\n                        'u-calendar__content--checked': isCheckedDate(index + 1),\n                        'u-calendar__content--today-checked': isTodayChecked(index + 1),\n                        'u-calendar__content--checkin-mode': props.checkinMode\n                    }\"\n                    :style=\"{\n                        backgroundColor:\n                            !props.checkinMode && props.checkedDates.length === 0 && !props.todayChecked\n                                ? getColor(index, 1)\n                                : ''\n                    }\"\n                    v-for=\"(item, index) in daysArr\"\n                    :key=\"index\"\n                    @tap=\"dateClick(index)\"\n                >\n                    <view\n                        class=\"u-calendar__content__item__inner\"\n                        :class=\"{ 'u-calendar__content__item__inner--today-checked': isTodayChecked(index + 1) }\"\n                        :style=\"{\n                            color: getCheckinTextColor(index + 1) || getColor(index, 2),\n                            backgroundColor: getCheckinColor(index + 1)\n                        }\"\n                    >\n                        <!-- 今日已打卡时显示对勾，否则显示日期 -->\n                        <view v-if=\"isTodayChecked(index + 1)\" class=\"u-calendar__content__item__checkmark\">\n                            <u-icon name=\"checkmark\" size=\"36\" :color=\"props.checkedColor\"></u-icon>\n                        </view>\n                        <template v-else>\n                            <!-- 自定义日期内容插槽 - 优先级最高 -->\n                            <template v-if=\"props.useDateSlot\">\n                                <view class=\"u-calendar__content__item__day\">{{ index + 1 }}</view>\n                                <view\n                                    class=\"u-calendar__content__item__lunar\"\n                                    :style=\"{ color: getSlotColor(index + 1) }\"\n                                >\n                                    <slot name=\"date\" :date=\"getDateInfo(index + 1)\"></slot>\n                                </view>\n                            </template>\n                            <template v-else>\n                                <!-- 日期数字右上角标记：休/班 -->\n                                <view\n                                    v-if=\"isHoliday(index + 1)\"\n                                    class=\"u-calendar__content__item__mark u-calendar__content__item__mark--holiday\"\n                                    :style=\"{ color: getHolidayWorkdayColor(index + 1, props.holidayColor) }\"\n                                >\n                                    {{ t('uCalendar.holiday') }}\n                                </view>\n                                <view\n                                    v-else-if=\"isWorkday(index + 1)\"\n                                    class=\"u-calendar__content__item__mark u-calendar__content__item__mark--workday\"\n                                    :style=\"{ color: getHolidayWorkdayColor(index + 1, props.workdayColor) }\"\n                                >\n                                    {{ t('uCalendar.workday') }}\n                                </view>\n                                <view class=\"u-calendar__content__item__day\">{{ index + 1 }}</view>\n                                <!-- 范围选择开始日期显示\"开始\" -->\n                                <view\n                                    v-if=\"\n                                        mode == 'range' &&\n                                        startDate == `${year}-${formatNum(month)}-${formatNum(index + 1)}` &&\n                                        startDate != endDate\n                                    \"\n                                    class=\"u-calendar__content__item__lunar\"\n                                    :style=\"{ color: activeColor }\"\n                                >\n                                    {{ startText }}\n                                </view>\n                                <!-- 范围选择结束日期显示\"结束\" -->\n                                <view\n                                    v-else-if=\"\n                                        mode == 'range' &&\n                                        endDate == `${year}-${formatNum(month)}-${formatNum(index + 1)}`\n                                    \"\n                                    class=\"u-calendar__content__item__lunar\"\n                                    :style=\"{ color: activeColor }\"\n                                >\n                                    {{ endText }}\n                                </view>\n                                <!-- 节日名称 -->\n                                <view\n                                    v-else-if=\"getFestival(index + 1)\"\n                                    class=\"u-calendar__content__item__lunar u-calendar__content__item__festival\"\n                                    :style=\"{ color: getHolidayWorkdayColor(index + 1, props.festivalColor) }\"\n                                >\n                                    {{ getFestival(index + 1) }}\n                                </view>\n                                <!-- 农历 -->\n                                <view\n                                    v-else-if=\"props.showLunar\"\n                                    class=\"u-calendar__content__item__lunar\"\n                                    :style=\"{ color: getCheckinLunarColor(index + 1) || getColor(index, 2) }\"\n                                >\n                                    {{\n                                        lunarArr[index]?.dayCn === '初一'\n                                            ? lunarArr[index].monthCn\n                                            : (lunarArr[index]?.dayCn ?? '')\n                                    }}\n                                </view>\n                                <!-- 占位元素：当有节日/农历数据时保持高度一致 -->\n                                <view\n                                    v-else-if=\"props.showFestival\"\n                                    class=\"u-calendar__content__item__lunar u-calendar__content__item__placeholder\"\n                                ></view>\n                            </template>\n                        </template>\n                    </view>\n                </view>\n                <view class=\"u-calendar__content__bg-month\">{{ month }}</view>\n            </view>\n            <!-- 页面模式下不显示确定按钮，选择完成自动触发change事件 -->\n            <view class=\"u-calendar__bottom\" v-if=\"!props.isPage\">\n                <view class=\"u-calendar__bottom__choose\">\n                    <text>{{ mode == 'date' ? activeDate : startDate }}</text>\n                    <text v-if=\"endDate\">{{ t('uCalendar.to') }}{{ endDate }}</text>\n                </view>\n                <view class=\"u-calendar__bottom__btn\">\n                    <u-button\n                        :type=\"btnType\"\n                        :disabled=\"btnDisable\"\n                        shape=\"circle\"\n                        size=\"default\"\n                        @click=\"btnFix(false)\"\n                    >\n                        {{ t('uCalendar.confirmText') }}\n                    </u-button>\n                </view>\n            </view>\n        </view>\n    </u-popup>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-calendar',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, onMounted, useSlots } from 'vue';\nimport { $u, useLocale } from '../..';\nimport { CalendarProps, type CalendarEmits } from './types';\nimport Calendar from '../../libs/util/calendar';\n\n/**\n * calendar 日历\n * @description 此组件用于单个选择日期，范围选择日期等，日历被包裹在底部弹起的容器中。\n * @tutorial https://uviewpro.cn/zh/components/calendar.html\n * @property {String} mode 选择日期的模式，date-为单个日期，range-为选择日期范围\n * @property {Boolean} v-model 布尔值变量，用于控制日历的弹出与收起\n * @property {Boolean} safe-area-inset-bottom 是否开启底部安全区适配(默认false)\n * @property {Boolean} change-year 是否显示顶部的切换年份方向的按钮(默认true)\n * @property {Boolean} change-month 是否显示顶部的切换月份方向的按钮(默认true)\n * @property {String Number} max-year 可切换的最大年份(默认2050)\n * @property {String Number} min-year 可切换的最小年份(默认1950)\n * @property {String Number} min-date 最小可选日期(默认1950-01-01)\n * @property {String Number} max-date 最大可选日期(默认当前日期)\n * @property {String Number} 弹窗顶部左右两边的圆角值，单位rpx(默认20)\n * @property {Boolean} mask-close-able 是否允许通过点击遮罩关闭日历(默认true)\n * @property {String} month-arrow-color 月份切换按钮箭头颜色(默认var(--u-content-color))\n * @property {String} year-arrow-color 年份切换按钮箭头颜色(默认var(--u-tips-color))\n * @property {String} color 日期字体的默认颜色(默认var(--u-main-color))\n * @property {String} active-bg-color 起始/结束日期按钮的背景色(默认主题色primary)\n * @property {String Number} z-index 弹出时的z-index值(默认10075)\n * @property {String} active-color 起始/结束日期按钮的字体颜色(默认var(--u-white-color))\n * @property {String} range-bg-color 起始/结束日期之间的区域的背景颜色(默认rgba(41,121,255,0.13))\n * @property {String} range-color 选择范围内字体颜色(默认主题色primary)\n * @property {String} start-text 起始日期底部的提示文字(默认 '开始')\n * @property {String} end-text 结束日期底部的提示文字(默认 '结束')\n * @property {String} btn-type 底部确定按钮的主题(默认 'primary')\n * @property {String} toolTip 顶部提示文字，如设置名为tooltip的slot，此参数将失效(默认 '选择日期')\n * @property {Boolean} closeable 是否显示右上角的关闭图标(默认true)\n * @property {Boolean} is-page 是否在页面中直接显示，不使用弹窗(默认false)\n * @property {String} default-date 默认选中的日期，mode=date时生效，格式：2024-01-01\n * @property {String} start-date 默认选中的开始日期，mode=range时生效，格式：2024-01-01\n * @property {String} end-date 默认选中的结束日期，mode=range时生效，格式：2024-01-01\n * @property {Boolean} readonly 是否只读，只读模式下禁止点击选择日期(默认false)\n * @example <u-calendar v-model=\"show\" :mode=\"mode\"></u-calendar>\n */\n\nconst props = defineProps(CalendarProps);\nconst emit = defineEmits<CalendarEmits>();\nconst slots = useSlots();\n\nconst { t } = useLocale();\n\n// 组件内部状态\n// 星期几,值为1-7\nconst weekday = ref(1);\nconst weekdayArr = ref<number[]>([]);\nconst days = ref(0);\nconst daysArr = ref<number[]>([]);\nconst lunarArr = ref<any[]>([]);\nconst showTitle = ref('');\nconst year = ref(2020);\nconst month = ref(0);\n// 当前月有多少天\nconst day = ref(0);\nconst startYear = ref(0);\nconst startMonth = ref(0);\nconst startDay = ref(0);\nconst endYear = ref(0);\nconst endMonth = ref(0);\nconst endDay = ref(0);\nconst today = ref('');\nconst activeDate = ref('');\nconst startDate = ref('');\nconst endDate = ref('');\nconst isStart = ref(true);\nconst min = ref<{ year: number; month: number; day: number } | null>(null);\nconst max = ref<{ year: number; month: number; day: number } | null>(null);\nconst weekDayZh = ref([\n    t('uCalendar.sun'),\n    t('uCalendar.mon'),\n    t('uCalendar.tue'),\n    t('uCalendar.wed'),\n    t('uCalendar.thu'),\n    t('uCalendar.fri'),\n    t('uCalendar.sat')\n]);\n\n// 内置中国传统节日（公历日期，格式：MM-DD）\nconst builtInFestivals: Record<string, string> = {\n    '01-01': '元旦',\n    '02-14': '情人节',\n    '03-08': '妇女节',\n    '03-12': '植树节',\n    '04-01': '愚人节',\n    '05-01': '劳动节',\n    '05-04': '青年节',\n    '06-01': '儿童节',\n    '07-01': '建党节',\n    '08-01': '建军节',\n    '09-10': '教师节',\n    '10-01': '国庆节',\n    '11-11': '光棍节',\n    '12-25': '圣诞节'\n};\n\nconst dataChange = computed(() => `${props.mode}-${props.minDate}-${props.maxDate}`);\nconst lunarChange = computed(() => props.showLunar);\nconst defaultDateChange = computed(\n    () => `${props.defaultDate}-${props.startDate}-${props.endDate}-${props.defaultSelectToday}`\n);\n// 如果用户有传递z-index值，优先使用\nconst uZIndex = computed(() => (props.zIndex ? props.zIndex : $u.zIndex.popup));\nconst popupValue = computed({\n    get: () => props.modelValue,\n    set: (val: boolean) => emit('update:modelValue', val)\n});\n\nconst btnDisable = computed(() => {\n    let disable = false;\n    if (props.mode == 'range') {\n        if (!startDate.value || !endDate.value) {\n            disable = true;\n        }\n    } else {\n        if (!activeDate.value) {\n            disable = true;\n        }\n    }\n    return disable;\n});\n\nwatch([dataChange, lunarChange], () => {\n    init();\n});\n\nwatch(defaultDateChange, () => {\n    init();\n});\n\nonMounted(() => {\n    init();\n});\n\n/**\n * 获取日期颜色\n * @param index\n * @param type 1 背景色 2 字体色\n */\nfunction getColor(index: number, type: number) {\n    let color = type == 1 ? '' : props.color;\n    let dayNum = index + 1;\n    let date = `${year.value}-${formatNum(month.value)}-${formatNum(dayNum)}`;\n    let timestamp = new Date(date.replace(/\\-/g, '/')).getTime();\n    let start = startDate.value.replace(/\\-/g, '/');\n    let end = endDate.value.replace(/\\-/g, '/');\n    if ((props.isActiveCurrent && activeDate.value == date) || startDate.value == date || endDate.value == date) {\n        color = type == 1 ? props.activeBgColor : props.activeColor;\n    } else if (endDate.value && timestamp > new Date(start).getTime() && timestamp < new Date(end).getTime()) {\n        color = type == 1 ? props.rangeBgColor : props.rangeColor;\n    }\n    return color;\n}\n\n/**\n * 判断日期是否已打卡\n */\nfunction isCheckedDate(dayNum: number) {\n    const date = `${year.value}-${formatNum(month.value)}-${formatNum(dayNum)}`;\n    return props.checkedDates.includes(date);\n}\n\n/**\n * 判断是否是今日且已打卡\n * 优先级：1. todayChecked 属性 2. 自动判断 checkedDates 中是否包含今天\n */\nfunction isTodayChecked(dayNum: number) {\n    const date = `${year.value}-${formatNum(month.value)}-${formatNum(dayNum)}`;\n    // 首先检查是否是今天\n    if (date !== today.value) {\n        return false;\n    }\n    // 优先级1：手动设置的 todayChecked\n    if (props.todayChecked) {\n        return true;\n    }\n    // 优先级2：自动判断 checkedDates 中是否包含今天\n    if (props.checkedDates.includes(date)) {\n        return true;\n    }\n    return false;\n}\n\n/**\n * 获取打卡日期背景色\n */\nfunction getCheckinColor(dayNum: number) {\n    const date = `${year.value}-${formatNum(month.value)}-${formatNum(dayNum)}`;\n    const isToday = date === today.value;\n    const isInCheckedDates = props.checkedDates.includes(date);\n\n    // 只有在打卡签到模式下或设置了打卡数据时才返回颜色\n    if (!props.checkinMode && props.checkedDates.length === 0 && !props.todayChecked) {\n        return '';\n    }\n\n    // 今日已打卡显示绿色（优先级：todayChecked > 自动判断）\n    if (isToday && (props.todayChecked || isInCheckedDates)) {\n        return props.todayCheckedBgColor;\n    }\n\n    // 其他已打卡日期显示橙色\n    if (isInCheckedDates) {\n        return props.checkedBgColor;\n    }\n\n    // 打卡签到模式下，未打卡日期显示灰色\n    if (props.checkinMode) {\n        return props.uncheckedBgColor;\n    }\n    return '';\n}\n\n/**\n * 获取打卡日期文字颜色\n */\nfunction getCheckinTextColor(dayNum: number) {\n    // 只有在打卡签到模式下或设置了打卡数据时才返回颜色\n    if (!props.checkinMode && props.checkedDates.length === 0 && !props.todayChecked) {\n        return '';\n    }\n    const date = `${year.value}-${formatNum(month.value)}-${formatNum(dayNum)}`;\n    // 已打卡日期显示白色文字\n    if (props.checkedDates.includes(date) || (date === today.value && props.todayChecked)) {\n        return props.checkedColor;\n    }\n    // 打卡签到模式下，未打卡日期显示白色文字\n    if (props.checkinMode) {\n        return props.uncheckedColor;\n    }\n    return '';\n}\n\n/**\n * 获取打卡日期农历文字颜色\n */\nfunction getCheckinLunarColor(dayNum: number) {\n    // 只有在打卡签到模式下或设置了打卡数据时才返回颜色\n    if (!props.checkinMode && props.checkedDates.length === 0 && !props.todayChecked) {\n        return '';\n    }\n    const date = `${year.value}-${formatNum(month.value)}-${formatNum(dayNum)}`;\n    // 已打卡日期的农历显示白色文字\n    if (props.checkedDates.includes(date) || (date === today.value && props.todayChecked)) {\n        return props.checkedColor;\n    }\n    // 打卡签到模式下，未打卡日期的农历显示白色文字\n    if (props.checkinMode) {\n        return props.uncheckedColor;\n    }\n    return '';\n}\n\n/**\n * 获取自定义插槽的颜色\n * 当选中日期时显示白色，否则显示默认颜色\n */\nfunction getSlotColor(dayNum: number) {\n    const date = `${year.value}-${formatNum(month.value)}-${formatNum(dayNum)}`;\n    // 选中日期的自定义内容显示白色（仅在 isActiveCurrent 为 true 时）\n    if (props.isActiveCurrent && (activeDate.value === date || startDate.value === date || endDate.value === date)) {\n        return props.activeColor;\n    }\n    // 打卡签到模式下使用对应的颜色\n    if (props.checkinMode || props.checkedDates.length > 0 || props.todayChecked) {\n        return getCheckinLunarColor(dayNum) || props.color;\n    }\n    return props.color;\n}\n\n/**\n * 获取日期信息，用于自定义插槽\n */\nfunction getDateInfo(dayNum: number) {\n    const dateStr = `${year.value}-${formatNum(month.value)}-${formatNum(dayNum)}`;\n    const dateObj = new Date(dateStr.replace(/\\-/g, '/'));\n    const dayOfWeek = dateObj.getDay();\n    const weekNames = [\n        t('uCalendar.sun'),\n        t('uCalendar.mon'),\n        t('uCalendar.tue'),\n        t('uCalendar.wed'),\n        t('uCalendar.thu'),\n        t('uCalendar.fri'),\n        t('uCalendar.sat')\n    ];\n\n    const isSelected = activeDate.value === dateStr || startDate.value === dateStr || endDate.value === dateStr;\n\n    return {\n        year: year.value,\n        month: month.value,\n        day: dayNum,\n        date: dateStr,\n        week: weekNames[dayOfWeek],\n        weekNum: dayOfWeek,\n        isToday: dateStr === today.value,\n        isHoliday: props.holidays.includes(dateStr),\n        isWorkday: props.workdays.includes(dateStr),\n        isChecked: props.checkedDates.includes(dateStr),\n        isSelected,\n        isTodayChecked: dateStr === today.value && props.todayChecked,\n        lunar: lunarArr.value[dayNum - 1] || null\n    };\n}\n\n/**\n * 判断是否是节假日\n */\nfunction isHoliday(dayNum: number) {\n    const date = `${year.value}-${formatNum(month.value)}-${formatNum(dayNum)}`;\n    return props.holidays.includes(date);\n}\n\n/**\n * 判断是否是加班日\n */\nfunction isWorkday(dayNum: number) {\n    const date = `${year.value}-${formatNum(month.value)}-${formatNum(dayNum)}`;\n    return props.workdays.includes(date);\n}\n\n/**\n * 获取节日名称（合并内置节日和用户自定义节日）\n * 用户传入空字符串可覆盖内置节日，表示不显示该节日\n * 支持两种格式：\n * 1. 年-月-日：特定年份的节日，如 '2024-04-04': '清明节'\n * 2. 月-日：每年的固定节日，如 '04-04': '清明节'\n */\nfunction getFestival(dayNum: number) {\n    if (!props.showFestival && Object.keys(props.festivals).length === 0) {\n        return '';\n    }\n    const date = `${year.value}-${formatNum(month.value)}-${formatNum(dayNum)}`;\n    const monthDay = `${formatNum(month.value)}-${formatNum(dayNum)}`;\n\n    // 优先检查用户自定义节日（特定年份格式）\n    if (date in props.festivals) {\n        return props.festivals[date];\n    }\n\n    // 然后检查用户自定义节日（每年固定格式，月-日）\n    if (monthDay in props.festivals) {\n        return props.festivals[monthDay];\n    }\n\n    // 最后检查内置节日（如果启用了 showFestival）\n    if (props.showFestival && builtInFestivals[monthDay]) {\n        return builtInFestivals[monthDay];\n    }\n    return '';\n}\n\n/**\n * 获取节假日/加班日文字颜色\n * 当选中日期时显示白色，否则显示对应的颜色\n */\nfunction getHolidayWorkdayColor(dayNum: number, defaultColor: string) {\n    const date = `${year.value}-${formatNum(month.value)}-${formatNum(dayNum)}`;\n    // 选中日期的节假日/加班日显示白色\n    if (activeDate.value === date || startDate.value === date || endDate.value === date) {\n        return props.activeColor;\n    }\n    return defaultColor;\n}\n\n/**\n * 初始化日历数据\n */\nfunction init() {\n    let now = new Date();\n    let minDateObj = new Date(String(props.minDate));\n    let maxDateObj = new Date(String(props.maxDate || ''));\n    if (isNaN(maxDateObj.getTime())) maxDateObj = new Date();\n    if (now < minDateObj) now = minDateObj;\n    if (now > maxDateObj) now = maxDateObj;\n    year.value = now.getFullYear();\n    month.value = now.getMonth() + 1;\n    day.value = now.getDate();\n    today.value = `${now.getFullYear()}-${formatNum(month.value)}-${formatNum(day.value)}`;\n    min.value = initDate(String(props.minDate));\n    max.value = initDate(String(props.maxDate) || today.value);\n\n    // 处理默认选中日期\n    // 优先级1: defaultDate / startDate / endDate（显式指定日期）\n    // 优先级2: defaultSelectToday（默认选中今天）\n    // 优先级3: 不选中任何日期\n    if (props.mode === 'date' && props.defaultDate) {\n        // 单选模式：使用 defaultDate（优先级1）\n        const defaultDateObj = new Date(props.defaultDate.replace(/\\-/g, '/'));\n        if (!isNaN(defaultDateObj.getTime())) {\n            year.value = defaultDateObj.getFullYear();\n            month.value = defaultDateObj.getMonth() + 1;\n            day.value = defaultDateObj.getDate();\n            // 统一格式为 YYYY-MM-DD，与 getColor 中的格式一致\n            activeDate.value = `${year.value}-${formatNum(month.value)}-${formatNum(day.value)}`;\n        } else if (props.defaultSelectToday) {\n            activeDate.value = today.value;\n        } else {\n            activeDate.value = '';\n        }\n    } else if (props.mode === 'range' && (props.startDate || props.endDate)) {\n        // 范围模式：使用 startDate 和 endDate（优先级1）\n        const startDateObj = props.startDate ? new Date(props.startDate.replace(/\\-/g, '/')) : null;\n        const endDateObj = props.endDate ? new Date(props.endDate.replace(/\\-/g, '/')) : null;\n\n        if (startDateObj && !isNaN(startDateObj.getTime())) {\n            // 设置当前显示月份为开始日期所在月份\n            year.value = startDateObj.getFullYear();\n            month.value = startDateObj.getMonth() + 1;\n\n            // 设置开始日期 - 统一格式为 YYYY-MM-DD\n            startYear.value = startDateObj.getFullYear();\n            startMonth.value = startDateObj.getMonth() + 1;\n            startDay.value = startDateObj.getDate();\n            startDate.value = `${startYear.value}-${formatNum(startMonth.value)}-${formatNum(startDay.value)}`;\n        }\n\n        if (endDateObj && !isNaN(endDateObj.getTime())) {\n            // 设置结束日期 - 统一格式为 YYYY-MM-DD\n            endYear.value = endDateObj.getFullYear();\n            endMonth.value = endDateObj.getMonth() + 1;\n            endDay.value = endDateObj.getDate();\n            endDate.value = `${endYear.value}-${formatNum(endMonth.value)}-${formatNum(endDay.value)}`;\n        }\n\n        isStart.value = true;\n        activeDate.value = '';\n    } else if (props.defaultSelectToday) {\n        // 优先级2：默认选中今天\n        activeDate.value = today.value;\n        resetRangeState();\n    } else {\n        // 优先级3：不选中任何日期\n        activeDate.value = '';\n        resetRangeState();\n    }\n\n    changeData();\n}\n\n/**\n * 重置范围选择状态\n */\nfunction resetRangeState() {\n    startDate.value = '';\n    startYear.value = 0;\n    startMonth.value = 0;\n    startDay.value = 0;\n    endYear.value = 0;\n    endMonth.value = 0;\n    endDay.value = 0;\n    endDate.value = '';\n    isStart.value = true;\n}\n\n/**\n * 日期字符串转对象\n */\nfunction initDate(date: string) {\n    let fdate = date.split('-');\n    return {\n        year: Number(fdate[0] || 1920),\n        month: Number(fdate[1] || 1),\n        day: Number(fdate[2] || 1)\n    };\n}\n\n/**\n * 判断日期是否可选\n */\nfunction openDisAbled(yearNum: number, monthNum: number, dayNum: number) {\n    let bool = true;\n    let date = `${yearNum}/${formatNum(monthNum)}/${formatNum(dayNum)}`;\n    // let today = this.today.replace(/\\-/g, '/');\n    let minStr = min.value ? `${min.value.year}/${formatNum(min.value.month)}/${formatNum(min.value.day)}` : '';\n    let maxStr = max.value ? `${max.value.year}/${formatNum(max.value.month)}/${formatNum(max.value.day)}` : '';\n    let timestamp = new Date(date).getTime();\n    if (min.value && max.value && timestamp >= new Date(minStr).getTime() && timestamp <= new Date(maxStr).getTime()) {\n        bool = false;\n    }\n    return bool;\n}\n\n/**\n * 生成数组\n */\nfunction generateArray(start: number, end: number) {\n    return Array.from(new Array(end + 1).keys()).slice(start);\n}\n\n/**\n * 格式化数字\n */\nfunction formatNum(num: number) {\n    return num < 10 ? '0' + num : num + '';\n}\n\n/**\n * 获取某月天数\n */\nfunction getMonthDay(yearNum: number, monthNum: number) {\n    return new Date(yearNum, monthNum, 0).getDate();\n}\n\n/**\n * 获取某月第一天星期几\n */\nfunction getWeekday(yearNum: number, monthNum: number) {\n    let date = new Date(`${yearNum}/${monthNum}/01 00:00:00`);\n    return date.getDay();\n}\n\n/**\n * 检查年月是否超出范围\n */\nfunction checkRange(yearNum: number, monthNum: number) {\n    if (yearNum < Number(props.minYear) || yearNum > Number(props.maxYear)) {\n        uni.showToast({ title: t('uCalendar.outOfRange'), icon: 'none' });\n        return true;\n    }\n\n    const beforeMin =\n        min.value && (yearNum < min.value.year || (yearNum === min.value.year && monthNum < min.value.month));\n    const afterMax =\n        max.value && (yearNum > max.value.year || (yearNum === max.value.year && monthNum > max.value.month));\n\n    if (beforeMin || afterMax) {\n        uni.showToast({ title: t('uCalendar.outOfRange'), icon: 'none' });\n        return true;\n    }\n\n    return false;\n}\n\n/**\n * 切换月份\n */\nfunction changeMonthHandler(isAdd: number) {\n    if (isAdd) {\n        let m = month.value + 1;\n        let y = m > 12 ? year.value + 1 : year.value;\n        m = m > 12 ? 1 : m;\n        if (!checkRange(y, m)) {\n            month.value = m;\n            year.value = y;\n            changeData();\n        }\n    } else {\n        let m = month.value - 1;\n        let y = m < 1 ? year.value - 1 : year.value;\n        m = m < 1 ? 12 : m;\n        if (!checkRange(y, m)) {\n            month.value = m;\n            year.value = y;\n            changeData();\n        }\n    }\n}\n\n/**\n * 切换年份：若 minDate/maxDate 的月份在当前年超出，则切换到该年的最小/最大有效月\n */\nfunction changeYearHandler(isAdd: number) {\n    let y = isAdd ? year.value + 1 : year.value - 1;\n    let m = month.value;\n    if (min.value && y === min.value.year && m < min.value.month) {\n        m = min.value.month;\n    }\n    if (max.value && y === max.value.year && m > max.value.month) {\n        m = max.value.month;\n    }\n    if (!checkRange(y, m)) {\n        year.value = y;\n        month.value = m;\n        changeData();\n    }\n}\n\n/**\n * 更新日历数据\n */\nfunction changeData() {\n    days.value = getMonthDay(year.value, month.value);\n    daysArr.value = generateArray(1, days.value);\n    weekday.value = getWeekday(year.value, month.value);\n    weekdayArr.value = generateArray(1, weekday.value);\n    showTitle.value = `${year.value}${t('uCalendar.year')}${month.value}${t('uCalendar.month')}`;\n    if (props.showLunar) {\n        lunarArr.value = [];\n        daysArr.value.forEach(d => {\n            lunarArr.value.push(getLunar(year.value, month.value, d));\n        });\n    }\n    if (props.isChange && props.mode == 'date') {\n        btnFix(true);\n    }\n}\n\n/**\n * 获取农历\n */\nfunction getLunar(year: any, month: any, day: any) {\n    const val = Calendar.solar2lunar(year, month, day);\n    return {\n        dayCn: val.IDayCn,\n        weekCn: val.ncWeek,\n        monthCn: val.IMonthCn,\n        day: val.lDay,\n        week: val.nWeek,\n        month: val.lMonth,\n        year: val.lYear\n    };\n}\n\n/**\n * 日期点击事件\n */\nfunction dateClick(dayIdx: number) {\n    // 只读模式下禁止点击\n    if (props.readonly) return;\n\n    const d = dayIdx + 1;\n    if (!openDisAbled(year.value, month.value, d)) {\n        day.value = d;\n        let date = `${year.value}-${formatNum(month.value)}-${formatNum(d)}`;\n        if (props.mode == 'date') {\n            activeDate.value = date;\n            // 页面模式下，单选日期选择完成自动触发change事件\n            // 打卡签到模式下，弹窗模式也立即触发change事件\n            if (props.isPage || props.checkinMode) {\n                btnFix(true);\n            }\n        } else {\n            let compare =\n                new Date(date.replace(/\\-/g, '/')).getTime() < new Date(startDate.value.replace(/\\-/g, '/')).getTime();\n            if (isStart.value || compare) {\n                startDate.value = date;\n                startYear.value = year.value;\n                startMonth.value = month.value;\n                startDay.value = day.value;\n                endYear.value = 0;\n                endMonth.value = 0;\n                endDay.value = 0;\n                endDate.value = '';\n                activeDate.value = '';\n                isStart.value = false;\n            } else {\n                endDate.value = date;\n                endYear.value = year.value;\n                endMonth.value = month.value;\n                endDay.value = day.value;\n                isStart.value = true;\n                // 页面模式下，范围选择完成（选了结束日期）自动触发change事件\n                if (props.isPage) {\n                    btnFix(true);\n                }\n            }\n        }\n    }\n}\n\n/**\n * 关闭弹窗\n */\nfunction close() {\n    emit('input', false);\n    emit('update:modelValue', false);\n}\n\n/**\n * 获取星期文本\n */\nfunction getWeekText(date: string) {\n    const d = new Date(`${date.replace(/\\-/g, '/')} 00:00:00`);\n    let week = d.getDay();\n    return '星期' + ['日', '一', '二', '三', '四', '五', '六'][week];\n}\n\n/**\n * 确定按钮事件\n */\nfunction btnFix(show: boolean) {\n    // 页面模式下不关闭，弹窗模式下关闭\n    if (!show && !props.isPage) {\n        close();\n    }\n    if (props.mode == 'date') {\n        let arr = activeDate.value.split('-');\n        let y = props.isChange ? year.value : Number(arr[0]);\n        let m = props.isChange ? month.value : Number(arr[1]);\n        let d = props.isChange ? day.value : Number(arr[2]);\n        let daysNum = getMonthDay(y, m);\n        let result = `${y}-${formatNum(m)}-${formatNum(d)}`;\n        let weekText = getWeekText(result);\n        let isToday = false;\n        if (result == today.value) {\n            // 今天\n            isToday = true;\n        }\n        const lunar = props.showLunar ? getLunar(y, m, d) : null;\n        emit('change', {\n            year: y,\n            month: m,\n            day: d,\n            days: daysNum,\n            result: result,\n            week: weekText,\n            isToday: isToday,\n            lunar: lunar\n            // switch: show //是否是切换年月操作\n        });\n    } else {\n        if (!startDate.value || !endDate.value) return;\n        let startMonthStr = formatNum(startMonth.value);\n        let startDayStr = formatNum(startDay.value);\n        let startDateStr = `${startYear.value}-${startMonthStr}-${startDayStr}`;\n        let startWeek = getWeekText(startDateStr);\n        let endMonthStr = formatNum(endMonth.value);\n        let endDayStr = formatNum(endDay.value);\n        let endDateStr = `${endYear.value}-${endMonthStr}-${endDayStr}`;\n        let endWeek = getWeekText(endDateStr);\n        let startLunar = null;\n        let endLunar = null;\n        if (props.showLunar) {\n            startLunar = getLunar(startYear.value, startMonth.value, startDay.value);\n            endLunar = getLunar(endYear.value, endMonth.value, endDay.value);\n        }\n        emit('change', {\n            startYear: startYear.value,\n            startMonth: startMonth.value,\n            startDay: startDay.value,\n            startDate: startDateStr,\n            startWeek: startWeek,\n            endYear: endYear.value,\n            endMonth: endMonth.value,\n            endDay: endDay.value,\n            endDate: endDateStr,\n            endWeek: endWeek,\n            startLunar: startLunar,\n            endLunar: endLunar\n        });\n    }\n}\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n\n.u-calendar {\n    color: $u-content-color;\n\n    &--page {\n        background-color: var(--u-bg-white);\n        border-radius: 16rpx;\n    }\n\n    &__header {\n        width: 100%;\n        box-sizing: border-box;\n        font-size: 30rpx;\n        background-color: var(--u-bg-white);\n        color: $u-main-color;\n\n        &__text {\n            margin-top: 30rpx;\n            padding: 0 60rpx;\n            @include vue-flex;\n            justify-content: center;\n            align-items: center;\n        }\n    }\n\n    &__action {\n        padding: 40rpx 0 40rpx 0;\n\n        &__icon {\n            margin: 0 16rpx;\n        }\n\n        &__text {\n            padding: 0 16rpx;\n            color: $u-main-color;\n            font-size: 32rpx;\n            line-height: 32rpx;\n            font-weight: bold;\n        }\n    }\n\n    &__week-day {\n        @include vue-flex;\n        align-items: center;\n        justify-content: center;\n        padding: 6px 0;\n        overflow: hidden;\n\n        &__text {\n            flex: 1;\n            text-align: center;\n        }\n    }\n\n    &__content {\n        width: 100%;\n        @include vue-flex;\n        flex-wrap: wrap;\n        padding: 6px 0;\n        box-sizing: border-box;\n        background-color: var(--u-bg-white);\n        position: relative;\n\n        &--end-date {\n            border-top-right-radius: 8rpx;\n            border-bottom-right-radius: 8rpx;\n        }\n\n        &--start-date {\n            border-top-left-radius: 8rpx;\n            border-bottom-left-radius: 8rpx;\n        }\n\n        &--checked {\n            .u-calendar__content__item__inner {\n                width: 80rpx;\n                height: 80rpx;\n                border-radius: 50%;\n                display: flex;\n                align-items: center;\n                justify-content: center;\n            }\n        }\n\n        &--today-checked {\n            .u-calendar__content__item__inner {\n                width: 80rpx;\n                height: 80rpx;\n                border-radius: 50%;\n                display: flex;\n                align-items: center;\n                justify-content: center;\n            }\n        }\n\n        &--checkin-mode {\n            .u-calendar__content__item__inner {\n                width: 80rpx;\n                height: 80rpx;\n                border-radius: 50%;\n                display: flex;\n                align-items: center;\n                justify-content: center;\n            }\n        }\n\n        &__item {\n            width: 14.2857%;\n            @include vue-flex;\n            align-items: center;\n            justify-content: center;\n            padding: 6px 0;\n            overflow: hidden;\n            position: relative;\n            z-index: 2;\n\n            &__inner {\n                height: 84rpx;\n                @include vue-flex;\n                align-items: center;\n                justify-content: center;\n                flex-direction: column;\n                font-size: 32rpx;\n\n                &__desc {\n                    width: 100%;\n                    font-size: 24rpx;\n                    line-height: 24rpx;\n                    transform: scale(0.75);\n                    transform-origin: center center;\n                    position: absolute;\n                    left: 0;\n                    text-align: center;\n                    bottom: 2rpx;\n                }\n            }\n\n            &__day {\n                font-size: 32rpx;\n                line-height: 1;\n            }\n\n            &__lunar {\n                font-size: 22rpx;\n                line-height: 1;\n                margin-top: 2rpx;\n                transform: scale(0.85);\n            }\n\n            // 节假日/加班日标签样式\n            &__holiday,\n            &__workday {\n                font-size: 22rpx;\n                line-height: 1;\n                margin-top: 2rpx;\n                transform: scale(0.85);\n            }\n\n            // 右上角标记样式（休/班）\n            &__mark {\n                position: absolute;\n                top: 8rpx;\n                right: 8rpx;\n                font-size: 24rpx;\n                line-height: 1;\n                transform: scale(0.75);\n                z-index: 1;\n\n                &--holiday {\n                    color: var(--u-type-error);\n                }\n\n                &--workday {\n                    color: var(--u-type-primary);\n                }\n            }\n\n            // 节日名称样式（与农历保持一致）\n            &__festival {\n                font-size: 22rpx;\n                line-height: 1;\n                transform: scale(0.85);\n                color: var(--u-type-primary);\n            }\n\n            // 占位元素样式\n            &__placeholder {\n                min-height: 22rpx;\n                margin-top: 2rpx;\n                opacity: 0;\n            }\n\n            &__tips {\n                width: 100%;\n                font-size: 24rpx;\n                line-height: 24rpx;\n                position: absolute;\n                left: 0;\n                transform: scale(0.8);\n                transform-origin: center center;\n                text-align: center;\n                bottom: 8rpx;\n                z-index: 2;\n            }\n\n            &__check-icon {\n                position: absolute;\n                right: 4rpx;\n                top: 4rpx;\n                z-index: 3;\n            }\n\n            &__checkmark {\n                @include vue-flex;\n                align-items: center;\n                justify-content: center;\n                width: 100%;\n                height: 100%;\n            }\n\n            &__inner--today-checked {\n                @include vue-flex;\n                align-items: center;\n                justify-content: center;\n            }\n        }\n\n        &__bg-month {\n            position: absolute;\n            font-size: 130px;\n            line-height: 130px;\n            left: 50%;\n            top: 50%;\n            transform: translate(-50%, -50%);\n            color: var(--u-border-color);\n            z-index: 1;\n        }\n    }\n\n    &__bottom {\n        width: 100%;\n        @include vue-flex;\n        align-items: center;\n        justify-content: center;\n        flex-direction: column;\n        background-color: var(--u-bg-white);\n        padding: 0 40rpx 30rpx;\n        box-sizing: border-box;\n        font-size: 24rpx;\n        color: $u-tips-color;\n\n        &__choose {\n            height: 50rpx;\n        }\n\n        &__btn {\n            width: 100%;\n        }\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-car-keyboard/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\n/**\n * u-car-keyboard 车牌号键盘类型定义\n * @description 供 u-car-keyboard 组件 props 使用\n */\nexport const CarKeyboardProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 是否打乱键盘按键的顺序 */\n    random: { type: Boolean, default: false }\n};\n\nexport type CarKeyboardProps = ExtractPropTypes<typeof CarKeyboardProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-car-keyboard/u-car-keyboard.vue",
    "content": "<template>\n    <view class=\"u-keyboard\" :class=\"customClass\" :style=\"$u.toStyle(customStyle)\" @touchmove.stop.prevent=\"() => {}\">\n        <view class=\"u-keyboard-grids\">\n            <view>\n                <view class=\"u-keyboard-grids-item\" v-for=\"(group, i) in abc ? EngKeyBoardList : areaList\" :key=\"i\">\n                    <view\n                        :hover-stay-time=\"100\"\n                        @tap=\"carInputClick(i, j)\"\n                        hover-class=\"u-carinput-hover\"\n                        class=\"u-keyboard-grids-btn\"\n                        v-for=\"(item, j) in group\"\n                        :key=\"j\"\n                    >\n                        {{ item }}\n                    </view>\n                </view>\n                <view\n                    @touchstart=\"backspaceClick\"\n                    @touchend=\"clearTimer\"\n                    :hover-stay-time=\"100\"\n                    class=\"u-keyboard-back\"\n                    hover-class=\"u-hover-class\"\n                >\n                    <u-icon :size=\"38\" name=\"backspace\" :bold=\"true\"></u-icon>\n                </view>\n                <view\n                    :hover-stay-time=\"100\"\n                    class=\"u-keyboard-change\"\n                    hover-class=\"u-carinput-hover\"\n                    @tap=\"changeCarInputMode\"\n                >\n                    <text class=\"zh\" :class=\"[!abc ? 'active' : 'inactive']\">中</text>\n                    /\n                    <text class=\"en\" :class=\"[abc ? 'active' : 'inactive']\">英</text>\n                </view>\n            </view>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-car-keyboard',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed } from 'vue';\nimport { $u } from '../..';\nimport { CarKeyboardProps } from './types';\n\n/**\n * u-car-keyboard 车牌号键盘\n * @description 车牌号输入专用键盘，支持省份简称和字母数字切换，支持按键顺序打乱。\n * @property {Boolean} random 是否打乱键盘按键的顺序（默认false）\n * @event {Function} change 按键被点击\n * @event {Function} backspace 退格键被点击\n */\n\nconst props = defineProps(CarKeyboardProps);\nconst emit = defineEmits(['change', 'backspace']);\n\n// 车牌输入时，abc=true为输入车牌号码，abc=false为输入省份中文简称\nconst abc = ref(false);\nlet timer: ReturnType<typeof setInterval> | null = null;\n\nconst areaList = computed(() => {\n    let data = [\n        '京',\n        '沪',\n        '粤',\n        '津',\n        '冀',\n        '豫',\n        '云',\n        '辽',\n        '黑',\n        '湘',\n        '皖',\n        '鲁',\n        '苏',\n        '浙',\n        '赣',\n        '鄂',\n        '桂',\n        '甘',\n        '晋',\n        '陕',\n        '蒙',\n        '吉',\n        '闽',\n        '贵',\n        '渝',\n        '川',\n        '青',\n        '琼',\n        '宁',\n        '挂',\n        '藏',\n        '港',\n        '澳',\n        '新',\n        '使',\n        '学'\n    ];\n    let tmp: string[][] = [];\n    // 打乱顺序\n    if (props.random) {\n        data = $u.randomArray(data);\n    }\n    tmp[0] = data.slice(0, 10);\n    tmp[1] = data.slice(10, 20);\n    tmp[2] = data.slice(20, 30);\n    tmp[3] = data.slice(30, 36);\n    return tmp;\n});\n\nconst EngKeyBoardList = computed(() => {\n    // prettier-ignore\n    let data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'Z', 'X', 'C', 'V', 'B', 'N', 'M'];\n    let tmp: (string | number)[][] = [];\n    if (props.random) {\n        data = $u.randomArray(data);\n    }\n    tmp[0] = data.slice(0, 10);\n    tmp[1] = data.slice(10, 20);\n    tmp[2] = data.slice(20, 30);\n    tmp[3] = data.slice(30, 36);\n    return tmp;\n});\n\n/**\n * 点击键盘按钮\n */\nfunction carInputClick(i: number, j: number) {\n    let value = '';\n    // 不同模式，获取不同数组的值\n    if (abc.value) value = String(EngKeyBoardList.value[i][j]);\n    else value = String(areaList.value[i][j]);\n    emit('change', value);\n}\n\n/**\n * 修改汽车牌键盘的输入模式，中文|英文\n */\nfunction changeCarInputMode() {\n    abc.value = !abc.value;\n}\n\n/**\n * 点击退格键\n */\nfunction backspaceClick() {\n    emit('backspace');\n    if (timer) clearInterval(timer);\n    timer = setInterval(() => {\n        emit('backspace');\n    }, 250);\n}\n\nfunction clearTimer() {\n    if (timer) clearInterval(timer);\n    timer = null;\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-keyboard-grids {\n    background: rgb(215, 215, 217);\n    padding: 24rpx 0;\n    position: relative;\n}\n\n.u-keyboard-grids-item {\n    @include vue-flex;\n    align-items: center;\n    justify-content: center;\n}\n\n.u-keyboard-grids-btn {\n    text-decoration: none;\n    width: 62rpx;\n    flex: 0 0 64rpx;\n    height: 80rpx;\n    /* #ifndef APP-NVUE */\n    display: inline-flex;\n    /* #endif */\n    font-size: 36rpx;\n    text-align: center;\n    line-height: 80rpx;\n    background-color: var(--u-bg-white);\n    margin: 8rpx 5rpx;\n    border-radius: 8rpx;\n    box-shadow: 0 2rpx 0rpx var(--u-tips-color);\n    font-weight: 500;\n    justify-content: center;\n}\n\n.u-carinput-hover {\n    background-color: rgb(185, 188, 195) !important;\n}\n\n.u-keyboard-back {\n    position: absolute;\n    width: 96rpx;\n    right: 22rpx;\n    bottom: 32rpx;\n    height: 80rpx;\n    background-color: rgb(185, 188, 195);\n    @include vue-flex;\n    align-items: center;\n    border-radius: 8rpx;\n    justify-content: center;\n    box-shadow: 0 2rpx 0rpx var(--u-tips-color);\n}\n\n.u-keyboard-change {\n    font-size: 24rpx;\n    box-shadow: 0 2rpx 0rpx var(--u-tips-color);\n    position: absolute;\n    width: 96rpx;\n    left: 22rpx;\n    line-height: 1;\n    bottom: 32rpx;\n    height: 80rpx;\n    background-color: var(--u-bg-white);\n    @include vue-flex;\n    align-items: center;\n    border-radius: 8rpx;\n    justify-content: center;\n}\n\n.u-keyboard-change .inactive.zh {\n    transform: scale(0.85) translateY(-10rpx);\n}\n\n.u-keyboard-change .inactive.en {\n    transform: scale(0.85) translateY(10rpx);\n}\n\n.u-keyboard-change .active {\n    color: rgb(237, 112, 64);\n    font-size: 30rpx;\n}\n\n.u-keyboard-change .zh {\n    transform: translateY(-10rpx);\n}\n\n.u-keyboard-change .en {\n    transform: translateY(10rpx);\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-card/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\n/**\n * card 卡片类型定义\n * @description 供 u-card 组件 props 使用\n */\nexport type CardIndex = string | number | Record<string, any>;\nexport type CardStyle = Record<string, any>;\n\nexport const CardProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 与屏幕两侧是否留空隙 */\n    full: { type: Boolean, default: false },\n    /** 标题 */\n    title: { type: String, default: '' },\n    /** 标题颜色 */\n    titleColor: { type: String, default: 'var(--u-main-color)' },\n    /** 标题字体大小，单位rpx */\n    titleSize: { type: [Number, String], default: '30' },\n    /** 副标题 */\n    subTitle: { type: String, default: '' },\n    /** 副标题颜色 */\n    subTitleColor: { type: String, default: 'var(--u-tips-color)' },\n    /** 副标题字体大小，单位rpx */\n    subTitleSize: { type: [Number, String], default: '26' },\n    /** 是否显示外部边框，只对full=false时有效(卡片与边框有空隙时) */\n    border: { type: Boolean, default: false },\n    /** 用于标识点击了第几个 */\n    index: { type: [String, Number, Object] as PropType<CardIndex>, default: '' },\n    /** 用于隔开上下左右的边距，带单位的写法，如：\"30rpx 30rpx\"，\"20rpx 20rpx 30rpx 30rpx\" */\n    margin: { type: String, default: '30rpx' },\n    /** card卡片的圆角 */\n    borderRadius: { type: [Number, String], default: '16' },\n    /** 头部自定义样式，对象形式 */\n    headStyle: { type: Object as PropType<CardStyle>, default: () => ({}) },\n    /** 主体自定义样式，对象形式 */\n    bodyStyle: { type: Object as PropType<CardStyle>, default: () => ({}) },\n    /** 底部自定义样式，对象形式 */\n    footStyle: { type: Object as PropType<CardStyle>, default: () => ({}) },\n    /** 头部是否下边框 */\n    headBorderBottom: { type: Boolean, default: true },\n    /** 底部是否有上边框 */\n    footBorderTop: { type: Boolean, default: true },\n    /** 标题左边的缩略图 */\n    thumb: { type: String, default: '' },\n    /** 缩略图宽高，单位rpx */\n    thumbWidth: { type: [String, Number], default: '60' },\n    /** 缩略图是否为圆形 */\n    thumbCircle: { type: Boolean, default: false },\n    /** 给head，body，foot的内边距 */\n    padding: { type: [String, Number], default: '30' },\n    /** 是否显示头部 */\n    showHead: { type: Boolean, default: true },\n    /** 是否显示尾部 */\n    showFoot: { type: Boolean, default: true },\n    /** 卡片外围阴影，字符串形式 */\n    boxShadow: { type: String, default: 'none' }\n};\n\nexport type CardProps = ExtractPropTypes<typeof CardProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-card/u-card.vue",
    "content": "<template>\n    <view\n        class=\"u-card\"\n        @tap.stop=\"onClick\"\n        :class=\"[{ 'u-border': border, 'u-card-full': full, 'u-card--border': Number(borderRadius) > 0 }, customClass]\"\n        :style=\"\n            $u.toStyle(\n                {\n                    borderRadius: borderRadius + 'rpx',\n                    margin: margin,\n                    boxShadow: boxShadow\n                },\n                customStyle\n            )\n        \"\n    >\n        <view\n            v-if=\"showHead\"\n            class=\"u-card__head\"\n            :style=\"[{ padding: padding + 'rpx' }, headStyle]\"\n            :class=\"{\n                'u-border-bottom': headBorderBottom\n            }\"\n            @tap=\"onHeadClick\"\n        >\n            <view v-if=\"!slots.head\" class=\"u-flex u-row-between\">\n                <view class=\"u-card__head--left u-flex u-line-1\" v-if=\"title\">\n                    <image\n                        :src=\"thumb\"\n                        class=\"u-card__head--left__thumb\"\n                        mode=\"aspectFill\"\n                        v-if=\"thumb\"\n                        :style=\"{\n                            height: thumbWidth + 'rpx',\n                            width: thumbWidth + 'rpx',\n                            borderRadius: thumbCircle ? '100rpx' : '6rpx'\n                        }\"\n                    ></image>\n                    <text\n                        class=\"u-card__head--left__title u-line-1\"\n                        :style=\"{\n                            fontSize: titleSize + 'rpx',\n                            color: titleColor\n                        }\"\n                    >\n                        {{ title }}\n                    </text>\n                </view>\n                <view class=\"u-card__head--right u-line-1\" v-if=\"subTitle\">\n                    <text\n                        class=\"u-card__head__title__text\"\n                        :style=\"{\n                            fontSize: subTitleSize + 'rpx',\n                            color: subTitleColor\n                        }\"\n                    >\n                        {{ subTitle }}\n                    </text>\n                </view>\n            </view>\n            <slot name=\"head\" v-else />\n        </view>\n        <view @tap=\"onBodyClick\" class=\"u-card__body\" :style=\"[{ padding: padding + 'rpx' }, bodyStyle]\">\n            <slot />\n            <slot name=\"body\" />\n        </view>\n        <view\n            v-if=\"showFoot\"\n            class=\"u-card__foot\"\n            @tap=\"onFootClick\"\n            :style=\"[{ padding: slots.foot ? padding + 'rpx' : 0 }, footStyle]\"\n            :class=\"{\n                'u-border-top': footBorderTop\n            }\"\n        >\n            <slot name=\"foot\" />\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-card',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { useSlots } from 'vue';\nimport { CardProps } from './types';\nimport { $u } from '../..';\n\n/**\n * card 卡片\n * @description 卡片组件一般用于多个列表条目，且风格统一的场景\n * @tutorial https://uviewpro.cn/zh/components/card.html\n * @property {Boolean} full 卡片与屏幕两侧是否留空隙（默认false）\n * @property {String} title 头部左边的标题\n * @property {String} title-color 标题颜色（默认var(--u-main-color)）\n * @property {String | Number} title-size 标题字体大小，单位rpx（默认30）\n * @property {String} sub-title 头部右边的副标题\n * @property {String} sub-title-color 副标题颜色（默认var(--u-tips-color)）\n * @property {String | Number} sub-title-size 副标题字体大小（默认26）\n * @property {Boolean} border 是否显示边框（默认true）\n * @property {String | Number} index 用于标识点击了第几个卡片\n * @property {String} box-shadow 卡片外围阴影，字符串形式（默认none）\n * @property {String} margin 卡片与屏幕两边和上下元素的间距，需带单位，如\"30rpx 20rpx\"（默认30rpx）\n * @property {String | Number} border-radius 卡片整体的圆角值，单位rpx（默认16）\n * @property {Object} head-style 头部自定义样式，对象形式\n * @property {Object} body-style 中部自定义样式，对象形式\n * @property {Object} foot-style 底部自定义样式，对象形式\n * @property {Boolean} head-border-bottom 是否显示头部的下边框（默认true）\n * @property {Boolean} foot-border-top 是否显示底部的上边框（默认true）\n * @property {Boolean} show-head 是否显示头部（默认true）\n * @property {Boolean} show-foot 是否显示尾部（默认true）\n * @property {String} thumb 缩略图路径，如设置将显示在标题的左边，不建议使用相对路径\n * @property {String | Number} thumb-width 缩略图的宽度，高等于宽，单位rpx（默认60）\n * @property {Boolean} thumb-circle 缩略图是否为圆形（默认false）\n * @event {Function} click 整个卡片任意位置被点击时触发\n * @event {Function} head-click 卡片头部被点击时触发\n * @event {Function} body-click 卡片主体部分被点击时触发\n * @event {Function} foot-click 卡片底部部分被点击时触发\n * @example <u-card padding=\"30\" title=\"card\"></u-card>\n */\nconst props = defineProps(CardProps);\n\nconst emit = defineEmits(['click', 'head-click', 'body-click', 'foot-click']);\nconst slots = useSlots();\n\n/**\n * 整个卡片任意位置被点击时触发\n */\nfunction onClick() {\n    emit('click', props.index);\n}\n/**\n * 卡片头部被点击时触发\n */\nfunction onHeadClick() {\n    emit('head-click', props.index);\n}\n/**\n * 卡片主体部分被点击时触发\n */\nfunction onBodyClick() {\n    emit('body-click', props.index);\n}\n/**\n * 卡片底部部分被点击时触发\n */\nfunction onFootClick() {\n    emit('foot-click', props.index);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-card {\n    position: relative;\n    overflow: hidden;\n    font-size: 28rpx;\n    background-color: var(--u-bg-white);\n    box-sizing: border-box;\n\n    &-full {\n        // 如果是与屏幕之间不留空隙，应该设置左右边距为0\n        margin-left: 0 !important;\n        margin-right: 0 !important;\n        width: 100%;\n    }\n\n    &--border:after {\n        border-radius: 16rpx;\n    }\n\n    &__head {\n        &--left {\n            color: $u-main-color;\n\n            &__thumb {\n                margin-right: 16rpx;\n            }\n\n            &__title {\n                max-width: 400rpx;\n            }\n        }\n\n        &--right {\n            color: $u-tips-color;\n            margin-left: 6rpx;\n        }\n    }\n\n    &__body {\n        color: $u-content-color;\n    }\n\n    &__foot {\n        color: $u-tips-color;\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-cell-group/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\n/**\n * cell-group 组件 props 类型定义\n * @description 供 u-cell-group 组件 props 使用\n */\n\nexport const CellGroupProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 分组标题 */\n    title: { type: String, default: '' },\n    /** 是否显示分组list上下边框 */\n    border: { type: Boolean, default: true },\n    /** 分组标题的样式，对象形式，注意驼峰属性写法 */\n    titleStyle: { type: Object as PropType<Record<string, any>>, default: () => ({}) }\n};\n\nexport type CellGroupProps = ExtractPropTypes<typeof CellGroupProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-cell-group/u-cell-group.vue",
    "content": "<template>\n    <view class=\"u-cell-box\" :class=\"customClass\" :style=\"$u.toStyle(customStyle)\">\n        <view class=\"u-cell-title\" v-if=\"title\" :style=\"[titleStyle]\">\n            {{ title }}\n        </view>\n        <view class=\"u-cell-item-box\" :class=\"{ 'u-border-bottom u-border-top': border }\">\n            <slot />\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-cell-group',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { CellGroupProps } from './types';\nimport { $u } from '../..';\n\n/**\n * cellGroup 单元格父组件Group\n * @description cell单元格一般用于一组列表的情况，比如个人中心页，设置页等。搭配u-cell-item\n * @tutorial https://uviewpro.cn/zh/components/cell.html\n * @property {String} title 分组标题\n * @property {Boolean} border 是否显示外边框（默认true）\n * @property {Object} title-style 分组标题的的样式，对象形式，如{'font-size': '24rpx'} 或 {'fontSize': '24rpx'}\n * @example <u-cell-group title=\"设置喜好\">\n */\n\ndefineProps(CellGroupProps);\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-cell-box {\n    width: 100%;\n}\n\n.u-cell-title {\n    padding: 30rpx 32rpx 10rpx 32rpx;\n    font-size: 30rpx;\n    text-align: left;\n    color: $u-tips-color;\n}\n\n.u-cell-item-box {\n    background-color: var(--u-bg-white);\n    flex-direction: row;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-cell-item/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { CellItemArrowDirection } from '../../types/global';\n\n/**\n * cell-item 组件 props 类型定义\n * @description 供 u-cell-item 组件 props 使用\n */\nexport type CellItemIndex = string | number;\nexport type CellItemStyle = Record<string, any>;\n\nexport const CellItemProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 左侧图标名称(只能uView内置图标)，或者图标src */\n    icon: { type: String, default: '' },\n    /** 左侧标题 */\n    title: { type: [String, Number], default: '' },\n    /** 右侧内容 */\n    value: { type: [String, Number], default: '' },\n    /** 标题下方的描述信息 */\n    label: { type: [String, Number], default: '' },\n    /** 是否显示下边框 */\n    borderBottom: { type: Boolean, default: true },\n    /** 是否显示上边框 */\n    borderTop: { type: Boolean, default: false },\n    /** 是否开启点击反馈，即点击时cell背景为灰色，none为无效果 */\n    hoverClass: { type: String, default: 'u-cell-hover' },\n    /** 是否显示右侧箭头 */\n    arrow: { type: Boolean, default: true },\n    /** 内容是否垂直居中 */\n    center: { type: Boolean, default: false },\n    /** 是否显示左边表示必填的星号 */\n    required: { type: Boolean, default: false },\n    /** 标题的宽度，单位rpx */\n    titleWidth: { type: [Number, String], default: '' },\n    /** 右侧箭头方向，可选值：right|up|down，默认为right */\n    arrowDirection: { type: String as PropType<CellItemArrowDirection>, default: 'right' },\n    /** 控制标题的样式 */\n    titleStyle: { type: Object as PropType<CellItemStyle>, default: () => ({}) },\n    /** 右侧显示内容的样式 */\n    valueStyle: { type: Object as PropType<CellItemStyle>, default: () => ({}) },\n    /** 描述信息的样式 */\n    labelStyle: { type: Object as PropType<CellItemStyle>, default: () => ({}) },\n    /** 背景颜色 */\n    bgColor: { type: String, default: 'transparent' },\n    /** 用于识别被点击的是第几个cell */\n    index: { type: [String, Number] as PropType<CellItemIndex>, default: '' },\n    /** 是否使用label插槽 */\n    useLabelSlot: { type: Boolean, default: false },\n    /** 左边图标的大小，单位rpx，只对传入icon字段时有效 */\n    iconSize: { type: [Number, String], default: 34 },\n    /** 左边图标的样式，对象形式 */\n    iconStyle: { type: Object as PropType<CellItemStyle>, default: () => ({}) }\n};\n\nexport type CellItemProps = ExtractPropTypes<typeof CellItemProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-cell-item/u-cell-item.vue",
    "content": "<template>\n    <view\n        @tap=\"onClick\"\n        class=\"u-cell\"\n        :class=\"[\n            {\n                'u-border-bottom': borderBottom,\n                'u-border-top': borderTop,\n                'u-col-center': center,\n                'u-cell--required': required\n            },\n            customClass\n        ]\"\n        hover-stay-time=\"150\"\n        :hover-class=\"hoverClass\"\n        :style=\"$u.toStyle({ backgroundColor: bgColor }, customStyle)\"\n    >\n        <view v-if=\"icon\" class=\"u-cell__left-icon-wrap\">\n            <u-icon :size=\"iconSize\" :name=\"icon\" :custom-style=\"iconStyle\"></u-icon>\n        </view>\n\n        <view class=\"u-flex\" v-else>\n            <slot name=\"icon\"></slot>\n        </view>\n        <view class=\"u-cell_title\" :style=\"[{ width: titleWidth ? titleWidth + 'rpx' : 'auto' }, titleStyle]\">\n            <template v-if=\"title !== ''\">{{ title }}</template>\n            <slot name=\"title\" v-else></slot>\n            <view class=\"u-cell__label\" v-if=\"label || $slots.label\" :style=\"[labelStyle]\">\n                <template v-if=\"label !== ''\">{{ label }}</template>\n                <slot name=\"label\" v-else></slot>\n            </view>\n        </view>\n        <view class=\"u-cell__value\" :style=\"[valueStyle]\">\n            <template v-if=\"value !== ''\">{{ value }}</template>\n            <slot v-else></slot>\n        </view>\n        <view class=\"u-flex u-cell_right\" v-if=\"$slots['right-icon']\">\n            <slot name=\"right-icon\"></slot>\n        </view>\n        <view v-if=\"arrow\" class=\"u-icon-wrap u-cell__right-icon-wrap\">\n            <u-icon name=\"arrow-right\" :style=\"[arrowStyle]\"></u-icon>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-cell-item',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, useSlots } from 'vue';\nimport { CellItemProps } from './types';\nimport { $u } from '../..';\n\n/**\n * cellItem 单元格Item\n * @description cell单元格一般用于一组列表的情况，比如个人中心页，设置页等。搭配u-cell-group使用\n * @tutorial https://uviewpro.cn/zh/components/cell.html\n * @property {String} title 左侧标题\n * @property {String} icon 左侧图标名，只支持uView内置图标，见Icon 图标\n * @property {Object} icon-style 左边图标的样式，对象形式\n * @property {String} value 右侧内容\n * @property {String} label 标题下方的描述信息\n * @property {Boolean} border-bottom 是否显示cell的下边框（默认true）\n * @property {Boolean} border-top 是否显示cell的上边框（默认false）\n * @property {Boolean} center 是否使内容垂直居中（默认false）\n * @property {String} hover-class 是否开启点击反馈，none为无效果（默认true）\n * // @property {Boolean} border-gap border-bottom为true时，Cell列表中间的条目的下边框是否与左边有一个间隔（默认true）\n * @property {Boolean} arrow 是否显示右侧箭头（默认true）\n * @property {Boolean} required 箭头方向，可选值（默认right）\n * @property {Boolean} arrow-direction 是否显示左边表示必填的星号（默认false）\n * @property {Object} title-style 标题样式，对象形式\n * @property {Object} value-style 右侧内容样式，对象形式\n * @property {Object} label-style 标题下方描述信息的样式，对象形式\n * @property {String} bg-color 背景颜色（默认transparent）\n * @property {String|Number} index 用于在click事件回调中返回，标识当前是第几个Item\n * @property {String|Number} title-width 标题的宽度，单位rpx\n * @example <u-cell-item icon=\"integral-fill\" title=\"会员等级\" value=\"新版本\"></u-cell-item>\n */\n\nconst emit = defineEmits<{ (e: 'click', index: string | number): void }>();\n\nconst props = defineProps(CellItemProps);\n\nconst $slots = useSlots();\n\n/**\n * 箭头样式\n */\nconst arrowStyle = computed(() => {\n    let style: Record<string, any> = {};\n    if (props.arrowDirection === 'up') style.transform = 'rotate(-90deg)';\n    else if (props.arrowDirection === 'down') style.transform = 'rotate(90deg)';\n    else style.transform = 'rotate(0deg)';\n    return style;\n});\n\n/**\n * 点击事件\n */\nfunction onClick() {\n    emit('click', props.index);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n.u-cell {\n    @include vue-flex;\n    align-items: center;\n    position: relative;\n    /* #ifndef APP-NVUE */\n    box-sizing: border-box;\n    /* #endif */\n    width: 100%;\n    padding: 26rpx 32rpx;\n    font-size: 28rpx;\n    line-height: 54rpx;\n    color: $u-content-color;\n    background-color: var(--u-bg-white);\n    text-align: left;\n}\n\n.u-cell_title {\n    font-size: 28rpx;\n}\n\n.u-cell__left-icon-wrap {\n    margin-right: 10rpx;\n    font-size: 32rpx;\n}\n\n.u-cell__right-icon-wrap {\n    margin-left: 10rpx;\n    color: var(--u-tips-color);\n    font-size: 28rpx;\n}\n\n.u-cell__left-icon-wrap,\n.u-cell__right-icon-wrap {\n    @include vue-flex;\n    align-items: center;\n    height: 48rpx;\n}\n\n.u-cell-border:after {\n    position: absolute;\n    /* #ifndef APP-NVUE */\n    box-sizing: border-box;\n    content: ' ';\n    pointer-events: none;\n    border-bottom: 1px solid $u-border-color;\n    /* #endif */\n    right: 0;\n    left: 0;\n    top: 0;\n    transform: scaleY(0.5);\n}\n\n.u-cell-border {\n    position: relative;\n}\n\n.u-cell__label {\n    margin-top: 6rpx;\n    font-size: 26rpx;\n    line-height: 36rpx;\n    color: $u-tips-color;\n    /* #ifndef APP-NVUE */\n    word-wrap: break-word;\n    /* #endif */\n}\n\n.u-cell__value {\n    overflow: hidden;\n    text-align: right;\n    /* #ifndef APP-NVUE */\n    vertical-align: middle;\n    /* #endif */\n    color: $u-tips-color;\n    font-size: 26rpx;\n}\n\n.u-cell__title,\n.u-cell__value {\n    flex: 1;\n}\n\n.u-cell--required {\n    /* #ifndef APP-NVUE */\n    overflow: visible;\n    /* #endif */\n    @include vue-flex;\n    align-items: center;\n}\n\n.u-cell--required:before {\n    position: absolute;\n    /* #ifndef APP-NVUE */\n    content: '*';\n    /* #endif */\n    left: 8px;\n    margin-top: 4rpx;\n    font-size: 14px;\n    color: $u-type-error;\n}\n\n.u-cell_right {\n    line-height: 1;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-checkbox/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { Shape, SizeType } from '../../types/global';\n\n/**\n * checkbox 复选框类型定义\n * @description 供 u-checkbox 组件 props 使用\n */\nexport type CheckboxValue = string | number | boolean;\n\nexport const CheckboxProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** checkbox的标签 */\n    label: { type: String, default: '' },\n    /** checkbox的值 */\n    name: { type: [String, Number], default: '' },\n    /** checkbox的值，不传递时为name的属性 */\n    value: { type: [String, Number], default: '' },\n    /** 形状，square为方形，circle为原型 */\n    shape: { type: String as PropType<Shape>, default: '' },\n    /** 是否为选中状态 */\n    modelValue: { type: Boolean, default: false },\n    /** 是否禁用 */\n    disabled: { type: [String, Boolean], default: '' },\n    /** 是否禁止点击提示语选中复选框 */\n    labelDisabled: { type: [String, Boolean], default: '' },\n    /** 选中状态下的颜色，如设置此值，将会覆盖checkboxGroup的activeColor值 */\n    activeColor: { type: String, default: '' },\n    /** 图标的大小，单位rpx */\n    iconSize: { type: [String, Number], default: '' },\n    /** label的字体大小，rpx单位 */\n    labelSize: { type: [String, Number], default: '' },\n    /** 组件的整体大小 */\n    size: { type: [String, Number] as PropType<SizeType | string | number>, default: '' }\n};\n\nexport type CheckboxProps = ExtractPropTypes<typeof CheckboxProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-checkbox/u-checkbox.vue",
    "content": "<template>\n    <view class=\"u-checkbox\" :style=\"$u.toStyle(checkboxStyle, customStyle)\" :class=\"customClass\">\n        <view class=\"u-checkbox__icon-wrap\" @tap=\"toggle\" :class=\"iconClass\" :style=\"$u.toStyle(iconStyle)\">\n            <u-icon\n                custom-class=\"u-checkbox__icon-wrap__icon\"\n                name=\"checkbox-mark\"\n                :size=\"checkboxIconSize\"\n                :color=\"iconColor\"\n            />\n        </view>\n        <view\n            class=\"u-checkbox__label\"\n            @tap=\"onClickLabel\"\n            :style=\"{\n                fontSize: labelFontSize\n            }\"\n        >\n            <slot>\n                {{ label }}\n            </slot>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-checkbox',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch } from 'vue';\nimport { $u, useChildren } from '../..';\nimport { CheckboxProps } from './types';\nimport type { SizeType } from '../../types/global';\n\n/**\n * checkbox 复选框\n * @description 该组件需要搭配checkboxGroup组件使用，以便用户进行操作时，获得当前复选框组的选中情况。\n * @tutorial https://uviewpro.cn/zh/components/checkbox.html\n * @property {String Number} icon-size 图标大小，单位rpx（默认20）\n * @property {String Number} label-size label字体大小，单位rpx（默认28）\n * @property {String Number} name checkbox组件的标示符\n * @property {String} shape 形状，见官网说明（默认circle）\n * @property {Boolean} disabled 是否禁用\n * @property {Boolean} label-disabled 是否禁止点击文本操作checkbox\n * @property {String} active-color 选中时的颜色，如设置CheckboxGroup的active-color将失效\n * @event {Function} change 某个checkbox状态发生变化时触发，回调为一个对象\n * @example <u-checkbox v-model=\"checked\" :disabled=\"false\">天涯</u-checkbox>\n */\n\nconst props = defineProps(CheckboxProps);\nconst emit = defineEmits(['change', 'update:modelValue']);\n// checkbox 是否选中，true/false\nconst checkedValue = ref(props.modelValue);\n// 使用子组件Hook\nconst { parentExposed } = useChildren('u-checkbox', 'u-checkbox-group');\nconst { parentExposed: formExposed } = useChildren('u-checkbox', 'u-form');\n\n// checkbox 的value值，id\nconst checkboxValue = computed(() => {\n    if (props.value !== '') return props.value;\n    return props.name;\n});\n\nwatch(\n    () => props.modelValue,\n    (newVal: boolean) => {\n        checkedValue.value = newVal;\n    }\n);\n\nwatch(\n    () => checkedValue.value,\n    (newVal: boolean) => {\n        emit('update:modelValue', newVal);\n    },\n    { immediate: true }\n);\n\n// 根据 size 定义不同的配置\nconst sizeConfig = {\n    small: {\n        size: 28,\n        fontSize: 24,\n        iconSize: 16\n    },\n    default: {\n        size: 34,\n        fontSize: 28,\n        iconSize: 20\n    },\n    large: {\n        size: 40,\n        fontSize: 32,\n        iconSize: 24\n    }\n};\n\n// 获取实际使用的 size 值（优先级：props.size > u-form.size）\nconst actualSize = computed(() => {\n    // 优先使用 props 的 size 属性\n    if (props.size !== '') {\n        return String(props.size);\n    }\n    // 次优先：使用 u-checkbox-group 的 size 属性\n    if (parentExposed.value?.props?.size) {\n        return String(parentExposed.value.props.size);\n    }\n    // 最后：使用 u-form 的 size 属性（u-form 的 size 只支持预设值）\n    if (formExposed.value?.props?.size) {\n        return String(formExposed.value.props.size);\n    }\n    // 默认值\n    return 'default';\n});\n\n// 判断实际使用的 size 是否在预设配置中\nconst isInSizeConfig = computed(() => actualSize.value in sizeConfig);\n\n// 获取预设 size（用于查找 sizeConfig 配置，如图标大小、高度等）\nconst presetSize = computed(() => {\n    return (isInSizeConfig.value ? actualSize.value : 'default') as SizeType;\n});\n\n// 获取当前尺寸配置\nconst currentSizeConfig = computed(() => sizeConfig[presetSize.value]);\n\n// 是否禁用，如果父组件u-checkbox-group禁用的话，将会忽略子组件的配置\nconst isDisabled = computed(() => {\n    return props.disabled !== '' ? props.disabled : (parentExposed.value?.props?.disabled ?? false);\n});\n\n// 是否禁用label点击\nconst isLabelDisabled = computed(() => {\n    return props.labelDisabled !== '' ? props.labelDisabled : (parentExposed.value?.props?.labelDisabled ?? false);\n});\n\n// 组件尺寸，对应size的值，默认值为34rpx\nconst checkboxSize = computed(() => currentSizeConfig.value.size);\n\n// 组件的勾选图标的尺寸，默认20rpx\nconst checkboxIconSize = computed(() => {\n    if (props.iconSize) {\n        return props.iconSize;\n    }\n    if (parentExposed.value?.props?.iconSize) {\n        return parentExposed.value?.props?.iconSize;\n    }\n    if (isInSizeConfig.value) {\n        return currentSizeConfig.value.iconSize;\n    }\n    return 20;\n});\n\n// label字体大小，默认28rpx\nconst labelFontSize = computed(() => {\n    if (isInSizeConfig.value) {\n        return $u.addUnit(currentSizeConfig.value.fontSize);\n    }\n    return $u.addUnit(props.labelSize);\n});\n\n// 组件选中激活时的颜色\nconst elActiveColor = computed(() => {\n    return props.activeColor ? props.activeColor : (parentExposed.value?.props?.activeColor ?? 'primary');\n});\n\n// 组件的形状\nconst elShape = computed(() => {\n    return props.shape ? props.shape : (parentExposed.value?.props?.shape ?? 'square');\n});\n\n// 图标样式\nconst iconStyle = computed(() => {\n    let style: Record<string, string> = {};\n    if (elActiveColor.value && checkedValue.value && !isDisabled.value) {\n        style.borderColor = elActiveColor.value;\n        style.backgroundColor = elActiveColor.value;\n    }\n    style.width = $u.addUnit(checkboxSize.value);\n    style.height = $u.addUnit(checkboxSize.value);\n    return style;\n});\n\n// checkbox内部的勾选图标，如果选中状态，为白色，否则为透明色即可\nconst iconColor = computed(() => {\n    return checkedValue.value ? 'var(--u-white-color)' : 'transparent';\n});\n\nconst iconClass = computed(() => {\n    let classes: string[] = [];\n    classes.push('u-checkbox__icon-wrap--' + elShape.value);\n    if (checkedValue.value == true) classes.push('u-checkbox__icon-wrap--checked');\n    if (isDisabled.value) classes.push('u-checkbox__icon-wrap--disabled');\n    if (checkedValue.value && isDisabled.value) classes.push('u-checkbox__icon-wrap--disabled--checked');\n    return classes.join(' ');\n});\n\nconst checkboxStyle = computed(() => {\n    let style: Record<string, string> = {};\n    if (parentExposed.value?.props?.width) {\n        style.width = parentExposed.value.props.width;\n        // #ifdef MP\n        style.float = 'left';\n        // #endif\n        // #ifndef MP\n        style.flex = `0 0 ${parentExposed.value.props.width}`;\n        // #endif\n    }\n    if (parentExposed.value?.props?.wrap) {\n        style.width = '100%';\n        // #ifndef MP\n        style.flex = '0 0 100%';\n        // #endif\n    }\n    return style;\n});\n\n/**\n * 点击label\n */\nfunction onClickLabel() {\n    if (!isLabelDisabled.value && !isDisabled.value) {\n        setValue();\n    }\n}\n\n/**\n * 点击icon\n */\nfunction toggle() {\n    if (!isDisabled.value) {\n        setValue();\n    }\n}\n\n/**\n * 触发change事件\n */\nfunction emitEvent() {\n    emit('change', !checkedValue.value);\n    // 通知父组件状态变化\n    setTimeout(() => {\n        if (parentExposed.value?.emitEvent) {\n            parentExposed.value.emitEvent();\n        }\n    }, 80);\n}\n\n/**\n * 设置通过v-model绑定的组件的值\n */\nfunction setValue() {\n    // 判断是否超过了可选的最大数量\n    if (checkedValue.value == true) {\n        emitEvent();\n        checkedValue.value = false;\n    } else {\n        if (parentExposed?.value?.validateSelection && !parentExposed?.value?.validateSelection()) {\n            return;\n        }\n        emitEvent();\n        checkedValue.value = true;\n    }\n}\n\n// 设置组件的modelValue值\nfunction setChecked(data: any) {\n    if (!isDisabled.value) {\n        const needEmit = checkedValue.value !== data.checked;\n        checkedValue.value = data.checked;\n        if (needEmit) {\n            emitEvent();\n        }\n    }\n}\n\ndefineExpose({\n    isChecked: computed(() => checkedValue.value),\n    label: props.label,\n    name: props.name,\n    value: checkboxValue.value,\n    setValue,\n    emitEvent,\n    props,\n    setChecked\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-checkbox {\n    /* #ifndef APP-NVUE */\n    display: inline-flex;\n    /* #endif */\n    align-items: center;\n    overflow: hidden;\n    user-select: none;\n    line-height: 1.8;\n\n    &__icon-wrap {\n        color: $u-content-color;\n        flex: none;\n        display: -webkit-flex;\n        @include vue-flex;\n        align-items: center;\n        justify-content: center;\n        box-sizing: border-box;\n        width: 42rpx;\n        height: 42rpx;\n        color: transparent;\n        text-align: center;\n        transition-property: color, border-color, background-color;\n        font-size: 20px;\n        border: 1px solid var(--u-border-color);\n        transition-duration: 0.2s;\n\n        /* #ifdef MP-TOUTIAO */\n        &__icon {\n            line-height: 0;\n        }\n        /* #endif */\n\n        &--circle {\n            border-radius: 100%;\n        }\n\n        &--square {\n            border-radius: 6rpx;\n        }\n\n        &--checked {\n            color: var(--u-white-color);\n            background-color: $u-type-primary;\n            border-color: $u-type-primary;\n        }\n\n        &--disabled {\n            background-color: var(--u-bg-gray-light);\n            border-color: var(--u-border-color);\n        }\n\n        &--disabled--checked {\n            color: var(--u-bg-gray-light) !important;\n        }\n    }\n\n    &__label {\n        word-wrap: break-word;\n        margin-left: 10rpx;\n        margin-right: 24rpx;\n        color: $u-content-color;\n        font-size: 30rpx;\n\n        &--disabled {\n            color: var(--u-bg-gray-light);\n        }\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-checkbox-group/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { Shape } from '../../types/global';\nimport { getColor } from '../../';\n\n/**\n * checkbox-group 复选框组类型定义\n * @description 供 u-checkbox-group 组件 props 使用\n */\n\nexport const CheckboxGroupProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 绑定值，选中的复选框name组成的数组 */\n    modelValue: { type: Array as PropType<(string | number)[]>, default: undefined },\n    /** 最多能选中多少个checkbox */\n    max: { type: Number, default: 999 },\n    /** 是否禁用所有复选框 */\n    disabled: { type: Boolean, default: false },\n    /** 在表单内提交时的标识符 */\n    name: { type: [Boolean, String], default: '' },\n    /** 是否禁止点击提示语选中复选框 */\n    labelDisabled: { type: Boolean, default: false },\n    /** 形状，square为方形，circle为原型 */\n    shape: { type: String as PropType<Shape>, default: 'square' },\n    /** 选中状态下的颜色 */\n    activeColor: { type: String, default: () => getColor('primary') },\n    /** 组件的整体大小，单位rpx，默认34rpx */\n    size: { type: [String, Number], default: '' },\n    /** 每个checkbox占u-checkbox-group的宽度 */\n    width: { type: String, default: 'auto' },\n    /** 是否每个checkbox都换行 */\n    wrap: { type: Boolean, default: false },\n    /** 图标的大小，单位rpx，默认20rpx */\n    iconSize: { type: [String, Number], default: '' }\n};\n\nexport type CheckboxGroupProps = ExtractPropTypes<typeof CheckboxGroupProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-checkbox-group/u-checkbox-group.vue",
    "content": "<template>\n    <view class=\"u-checkbox-group u-clearfix\" :class=\"customClass\" :style=\"$u.toStyle(customStyle)\">\n        <slot></slot>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-checkbox-group',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, watch, nextTick, onMounted } from 'vue';\nimport { $u, useParent, useChildren, useDebounce } from '../..';\nimport { CheckboxGroupProps } from './types';\n\n/**\n * checkboxGroup 开关选择器父组件Group\n * @description 复选框组件一般用于需要多个选择的场景，该组件功能完整，使用方便\n * @tutorial https://uviewpro.cn/zh/components/checkbox.html\n * @property {Array} modelValue 绑定值，选中的复选框name组成的数组（支持v-model双向绑定）\n * @property {String Number} max 最多能选中多少个checkbox（默认999）\n * @property {String Number} size 组件整体的大小，单位rpx（默认40）\n * @property {Boolean} disabled 是否禁用所有checkbox（默认false）\n * @property {String Number} icon-size 图标大小，单位rpx（默认20）\n * @property {Boolean} label-disabled 是否禁止点击文本操作checkbox(默认false)\n * @property {String} width 宽度，需带单位\n * @property {String} shape 外观形状，shape-方形，circle-圆形(默认circle)\n * @property {Boolean} wrap 是否每个checkbox都换行（默认false）\n * @property {String} active-color 选中时的颜色，应用到所有子Checkbox组件（默认主题色primary）\n * @event {Function} change 任一个checkbox状态发生变化时触发，回调为选中的name数组\n * @example <u-checkbox-group v-model=\"selectedValues\">\n *              <u-checkbox name=\"apple\">苹果</u-checkbox>\n *              <u-checkbox name=\"banana\">香蕉</u-checkbox>\n *          </u-checkbox-group>\n */\nconst props = defineProps(CheckboxGroupProps);\nconst emit = defineEmits(['update:modelValue', 'change']);\n\n// 使用父组件Hook\nconst { children, broadcast } = useParent('u-checkbox-group');\nconst { emitToParent } = useChildren('u-checkbox-group', 'u-form-item');\nconst { debounce } = useDebounce(1);\n\n/**\n * 根据modelValue设置子组件状态\n */\nfunction syncChildrenSelection() {\n    if (!children || children.length === 0 || !props.modelValue) return;\n    const modelValueSet = new Set(props.modelValue);\n    children.forEach((child: any) => {\n        const childValue = child.getExposed?.()?.value;\n        const shouldBeChecked = modelValueSet.has(childValue);\n        const isCurrentlyChecked = child.getExposed?.()?.isChecked.value;\n\n        if (shouldBeChecked !== isCurrentlyChecked) {\n            child.getExposed?.()?.setChecked({ checked: shouldBeChecked });\n        }\n    });\n}\n\n/**\n * 监听modelValue变化，同步子组件状态\n */\nwatch(\n    () => props.modelValue,\n    () => {\n        syncChildrenSelection();\n    }\n);\n\n/**\n * 派发 change 事件和表单校验\n */\nfunction emitEvent() {\n    debounce(() => {\n        // 收集所有选中的 name\n        let values: any[] = [];\n        children.forEach((child: any) => {\n            if (child.getExposed?.()?.isChecked.value) {\n                values.push(child.getExposed?.()?.value);\n            }\n        });\n        emit('change', values);\n        emit('update:modelValue', values);\n        setTimeout(() => {\n            emitToParent('onFormChange', values);\n        }, 60);\n    });\n}\n\n/**\n * 全选/全不选方法\n */\nfunction setAllChecked(checked: boolean) {\n    if (props.disabled) {\n        console.warn('u-checkbox-group已禁用，无法操作');\n        return;\n    }\n    broadcast('setChecked', { checked });\n}\n\n/**\n * 获取选中的值\n */\nfunction getSelectedValues() {\n    return children\n        .filter(child => child.getExposed?.()?.isChecked.value)\n        .map(child => child.getExposed?.()?.name)\n        .filter(Boolean);\n}\n\n/**\n * 验证选择是否超过最大数量\n */\nfunction validateSelection() {\n    const selectedCount = children.filter(child => child.getExposed?.()?.isChecked.value).length;\n    if (props.max && selectedCount >= props.max) {\n        $u.toast(`超过最大选择数量: ${props.max}`);\n        return false;\n    }\n    return true;\n}\n\nonMounted(() => {\n    nextTick(() => {\n        syncChildrenSelection();\n    });\n});\n\n// 使用defineExpose暴露给外部\ndefineExpose({\n    // props\n    props,\n\n    // 方法\n    emitEvent,\n    setAllChecked,\n    getSelectedValues,\n    validateSelection,\n    syncChildrenSelection,\n\n    // 计算属性\n    selectedCount: computed(() => children.filter(child => child.getExposed?.()?.isChecked.value).length),\n    isFull: computed(() => {\n        const selectedCount = children.filter(child => child.getExposed?.()?.isChecked.value).length;\n        return props.max && selectedCount >= props.max;\n    }),\n    isEmpty: computed(() => children.filter(child => child.getExposed?.()?.isChecked.value).length === 0),\n    // 工具方法\n    getChildrenCount: () => children.length\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-checkbox-group {\n    /* #ifndef MP || APP-NVUE */\n    display: inline-flex;\n    flex-wrap: wrap;\n    /* #endif */\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-circle-progress/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { ThemeType } from '../../types/global';\nimport { $u } from '../../libs';\n\n/**\n * circleProgress 环形进度条 Props\n * @description 展示操作或任务的当前进度，比如上传文件，是一个圆形的进度条。注意：此组件的percent值只能动态增加，不能动态减少。\n */\nexport const CircleProgressProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 圆环进度百分比值 */\n    percent: {\n        type: Number,\n        default: 0,\n        validator: (val: number) => val >= 0 && val <= 100\n    },\n    /** 底部圆环的颜色（灰色的圆环） */\n    inactiveColor: {\n        type: String,\n        default: () => $u.getColor('dividerColor')\n    },\n    /** 圆环激活部分的颜色 */\n    activeColor: {\n        type: String,\n        default: 'var(--u-type-success)'\n    },\n    /** 圆环线条的宽度，单位rpx */\n    borderWidth: {\n        type: [Number, String] as PropType<number | string>,\n        default: 14\n    },\n    /** 整个圆形的宽度，单位rpx */\n    width: {\n        type: [Number, String] as PropType<number | string>,\n        default: 200\n    },\n    /** 整个圆环执行一圈的时间，单位ms */\n    duration: {\n        type: [Number, String] as PropType<number | string>,\n        default: 1500\n    },\n    /** 主题类型 */\n    type: {\n        type: String as PropType<ThemeType>,\n        default: ''\n    },\n    /** 整个圆环进度区域的背景色 */\n    bgColor: {\n        type: String,\n        default: 'var(--u-bg-white)'\n    }\n};\n\nexport type CircleProgressProps = ExtractPropTypes<typeof CircleProgressProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-circle-progress/u-circle-progress.vue",
    "content": "<template>\n    <view\n        class=\"u-circle-progress\"\n        :class=\"customClass\"\n        :style=\"\n            $u.toStyle(\n                {\n                    width: widthPx + 'px',\n                    height: widthPx + 'px',\n                    backgroundColor: bgColor\n                },\n                customStyle\n            )\n        \"\n    >\n        <!-- 支付宝小程序不支持canvas-id属性，必须用id属性 -->\n        <!-- #ifdef MP-WEIXIN || MP-TOUTIAO -->\n        <canvas\n            class=\"u-canvas-bg\"\n            type=\"2d\"\n            :canvas-id=\"elBgId\"\n            :id=\"elBgId\"\n            :style=\"{\n                width: widthPx + 'px',\n                height: widthPx + 'px'\n            }\"\n        ></canvas>\n        <canvas\n            class=\"u-canvas\"\n            type=\"2d\"\n            :canvas-id=\"elId\"\n            :id=\"elId\"\n            :style=\"{\n                width: widthPx + 'px',\n                height: widthPx + 'px'\n            }\"\n        ></canvas>\n        <!-- #endif -->\n        <!-- #ifndef MP-WEIXIN || MP-TOUTIAO -->\n        <canvas\n            class=\"u-canvas-bg\"\n            :canvas-id=\"elBgId\"\n            :id=\"elBgId\"\n            :style=\"{\n                width: widthPx + 'px',\n                height: widthPx + 'px'\n            }\"\n        ></canvas>\n        <canvas\n            class=\"u-canvas\"\n            :canvas-id=\"elId\"\n            :id=\"elId\"\n            :style=\"{\n                width: widthPx + 'px',\n                height: widthPx + 'px'\n            }\"\n        ></canvas>\n        <!-- #endif -->\n        <slot></slot>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-circle-progress',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, onMounted, getCurrentInstance, onBeforeMount } from 'vue';\nimport { $u } from '../..';\nimport { CircleProgressProps } from './types';\n// #ifdef MP-WEIXIN || MP-TOUTIAO\nimport { canvas2d } from '../../libs/util/canvas-2d';\n// #endif\n\n/**\n * circleProgress 环形进度条\n * @description 展示操作或任务的当前进度，比如上传文件，是一个圆形的进度条。注意：此组件的percent值只能动态增加，不能动态减少。\n * @tutorial https://uviewpro.cn/zh/components/circleProgress.html\n * @property {String Number} percent 圆环进度百分比值，为数值类型，0-100\n * @property {String} inactive-color 圆环的底色，默认为灰色(该值无法动态变更)（默认var(--u-divider-color)）\n * @property {String} active-color 圆环激活部分的颜色(该值无法动态变更)（默认var(--u-type-success)）\n * @property {String Number} width 整个圆环组件的宽度，高度默认等于宽度值，单位rpx（默认200）\n * @property {String Number} border-width 圆环的边框宽度，单位rpx（默认14）\n * @property {String Number} duration 整个圆环执行一圈的时间，单位ms（默认呢1500）\n * @property {String} type 如设置，active-color值将会失效\n * @property {String} bg-color 整个组件背景颜色，默认为白色\n * @example <u-circle-progress active-color=\"var(--u-type-primary)\" :percent=\"80\"></u-circle-progress>\n */\nconst props = defineProps(CircleProgressProps);\n\nlet elBgId = $u.guid(); // 非微信端的时候，需用动态的id，否则一个页面多个圆形进度条组件数据会混乱\nlet elId = $u.guid();\n// #ifdef MP-WEIXIN || MP-TOUTIAO\n// elBgId = 'uCircleProgressBgId'; // 微信小程序中不能使用$u.guid()形式动态生成id值，否则会报错\n// elId = 'uCircleProgressElId';\n// #endif\nconst instance = getCurrentInstance();\n\nconst pixelRatio = ref<number>(1); // 像素比\n\n// 存储 MP-WEIXIN 下通过 selectorQuery 获取到的 canvas node，方便在绘制前清空\nconst canvasNodeMap = new Map<string, any>();\n\nconst widthPx = computed(() =>\n    typeof uni !== 'undefined' && uni.upx2px ? uni.upx2px(Number(props.width)) : Number(props.width)\n);\nconst borderWidthPx = computed(() =>\n    typeof uni !== 'undefined' && uni.upx2px ? uni.upx2px(Number(props.borderWidth)) : Number(props.borderWidth)\n);\nconst startAngle = -Math.PI / 2; // canvas画圆的起始角度，默认为3点钟方向，定位到12点钟方向\nconst progressContext = ref<any>(null); // 活动圆的canvas上下文\nconst newPercent = ref(props.percent); // 当动态修改进度值的时候，保存进度值的变化前后值，用于比较用\nconst oldPercent = ref(0); // 当动态修改进度值的时候，保存进度值的变化前后值，用于比较用\n\n/**\n * 有type主题时，优先起作用\n */\nconst circleColor = computed(() => {\n    if (props.type && ['success', 'error', 'info', 'primary', 'warning'].includes(props.type)) {\n        return $u.color[props.type as keyof typeof $u.color] as string;\n    }\n    return props.activeColor;\n});\n\nonBeforeMount(() => {\n    pixelRatio.value = uni.getSystemInfoSync().pixelRatio;\n});\n\n// 监听percent变化，动态绘制进度\nwatch(\n    () => props.percent,\n    (nVal, oVal = 0) => {\n        let next = nVal > 100 ? 100 : nVal;\n        let prev = oVal < 0 ? 0 : oVal;\n        newPercent.value = next;\n        oldPercent.value = prev;\n        setTimeout(() => {\n            // 无论是百分比值增加还是减少，需要操作还是原来的旧的百分比值\n            // 将此值减少或者新增到新的百分比值\n            drawCircleByProgress(prev);\n        }, 50);\n    }\n);\n\nonMounted(() => {\n    // 赋值，用于加载后第一个画圆使用\n    newPercent.value = props.percent;\n    oldPercent.value = 0;\n    // 在h5端，必须要做一点延时才起作用，this.$nextTick()无效(HX2.4.7)\n    setTimeout(() => {\n        drawProgressBg();\n        drawCircleByProgress(oldPercent.value);\n    }, 50);\n});\n\n/**\n * 获取canvas上下文\n */\nfunction getContext(canvasId: any) {\n    return new Promise<UniApp.CanvasContext>(resolve => {\n        let ctx = null;\n        // #ifndef MP-WEIXIN || MP-TOUTIAO\n        ctx = uni.createCanvasContext(canvasId, instance);\n        resolve(ctx);\n        // #endif\n        // #ifdef MP-WEIXIN || MP-TOUTIAO\n        uni.createSelectorQuery()\n            .in(instance?.proxy)\n            .select(`#${canvasId}`)\n            .node(res => {\n                if (res && res.node) {\n                    const canvas = res.node;\n                    ctx = canvas2d(canvas.getContext('2d') as CanvasRenderingContext2D);\n                    canvas.width = widthPx.value * pixelRatio.value;\n                    canvas.height = widthPx.value * pixelRatio.value;\n                    ctx.scale(pixelRatio.value, pixelRatio.value);\n                    // 存储 canvas node，后续绘制时用于清空画布\n                    canvasNodeMap.set(canvasId, canvas);\n                    resolve(ctx);\n                }\n            })\n            .exec();\n        // #endif\n    });\n}\n\n/**\n * 绘制底部灰色圆环\n */\nasync function drawProgressBg() {\n    const ctx = await getContext(elBgId);\n    // #ifdef MP-WEIXIN || MP-TOUTIAO\n    // 清空背景画布（如果可用）以确保绘制一致性\n    try {\n        if (typeof ctx.clearRect === 'function') {\n            const node = canvasNodeMap.get(elBgId);\n            const w = node ? node.width : widthPx.value * pixelRatio.value;\n            const h = node ? node.height : widthPx.value * pixelRatio.value;\n            ctx.clearRect(0, 0, w, h);\n        }\n    } catch (e) {\n        // ignore\n    }\n    // #endif\n    ctx.setLineWidth(borderWidthPx.value); // 设置圆环宽度\n    ctx.setStrokeStyle(props.inactiveColor); // 线条颜色\n    ctx.beginPath(); // 开始描绘路径\n    const radius = widthPx.value / 2; // 设置一个原点(110,110)，半径为100的圆的路径到当前路径\n    ctx.arc(radius, radius, radius - borderWidthPx.value, 0, 2 * Math.PI, false);\n    ctx.stroke(); // 对路径进行描绘\n    ctx.draw();\n}\n\n/**\n * 绘制进度圆环\n * @param progress 当前进度\n */\nasync function drawCircleByProgress(progress: number) {\n    // 第一次操作进度环时将上下文保存到了this.data中，直接使用即可\n    let ctx = progressContext.value;\n    if (!ctx) {\n        ctx = await getContext(elId);\n        progressContext.value = ctx;\n    }\n    // #ifdef MP-WEIXIN || MP-TOUTIAO\n    // 清空进度画布，避免旧的更大进度残留，导致无法降低的视觉错误\n    try {\n        if (typeof ctx.clearRect === 'function') {\n            const node = canvasNodeMap.get(elId);\n            const w = node ? node.width : widthPx.value * pixelRatio.value;\n            const h = node ? node.height : widthPx.value * pixelRatio.value;\n            ctx.clearRect(0, 0, w, h);\n        }\n    } catch (e) {\n        // ignore\n    }\n    // #endif\n    // 表示进度的两端为圆形\n    ctx.setLineCap('round');\n    // 设置线条的宽度和颜色\n    ctx.setLineWidth(borderWidthPx.value);\n    ctx.setStrokeStyle(circleColor.value);\n    // 将总过渡时间除以100，得出每修改百分之一进度所需的时间\n    let time = Math.floor(Number(props.duration) / 100);\n    // 结束角的计算依据为：将2π分为100份，乘以当前的进度值，得出终止点的弧度值，加起始角，为整个圆从默认的\n    // 3点钟方向开始画图，转为更好理解的12点钟方向开始作图，这需要起始角和终止角同时加上this.startAngle值\n    let endAngle = ((2 * Math.PI) / 100) * progress + startAngle;\n    ctx.beginPath();\n    // 半径为整个canvas宽度的一半\n    let radius = widthPx.value / 2;\n    ctx.arc(radius, radius, radius - borderWidthPx.value, startAngle, endAngle, false);\n    ctx.stroke();\n    ctx.draw();\n    // 如果变更后新值大于旧值，意味着增大了百分比\n    if (newPercent.value > oldPercent.value) {\n        // 每次递增百分之一\n        progress++;\n        // 如果新增后的值，大于需要设置的值百分比值，停止继续增加\n        if (progress > newPercent.value) return;\n    } else {\n        // 同理于上面\n        progress--;\n        if (progress < newPercent.value) return;\n    }\n    setTimeout(() => {\n        // 定时器，每次操作间隔为time值，为了让进度条有动画效果\n        drawCircleByProgress(progress);\n    }, time);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n.u-circle-progress {\n    position: relative;\n    /* #ifndef APP-NVUE */\n    display: inline-flex;\n    /* #endif */\n    align-items: center;\n    justify-content: center;\n}\n\n.u-canvas-bg {\n    position: absolute;\n}\n\n.u-canvas {\n    position: absolute;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-city-select/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\n/**\n * u-city-select 城市选择器 Props\n * @description 用于选择省、市、区三级行政区域，支持回显和自定义初始值。\n */\nexport const CitySelectProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 控制弹窗显示与隐藏（v-model） */\n    modelValue: { type: Boolean, default: false },\n    /** 默认选中的省市区名称数组 */\n    defaultRegion: { type: Array as PropType<string[]>, default: () => [] },\n    /** 默认选中的省市区编码数组 */\n    areaCode: { type: Array as PropType<string[]>, default: () => [] },\n    /** 是否允许点击遮罩关闭弹窗 */\n    maskCloseAble: { type: Boolean, default: true },\n    /** 弹窗层级 */\n    zIndex: { type: [String, Number] as PropType<string | number>, default: 0 }\n};\n\nexport type CitySelectProps = ExtractPropTypes<typeof CitySelectProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-city-select/u-city-select.vue",
    "content": "<template>\n    <u-popup\n        v-model=\"popupValue\"\n        :class=\"customClass\"\n        :style=\"$u.toStyle(customStyle)\"\n        mode=\"bottom\"\n        :popup=\"false\"\n        :mask=\"true\"\n        :closeable=\"true\"\n        :safe-area-inset-bottom=\"true\"\n        close-icon-color=\"var(--u-white-color)\"\n        :z-index=\"uZIndex\"\n        :maskCloseAble=\"props.maskCloseAble\"\n        @close=\"close\"\n    >\n        <u-tabs\n            v-if=\"popupValue\"\n            :list=\"genTabsList\"\n            :is-scroll=\"true\"\n            :current=\"tabsIndex\"\n            @change=\"tabsChange\"\n            ref=\"tabs\"\n        ></u-tabs>\n        <view class=\"area-box\">\n            <view class=\"u-flex\" :class=\"{ change: isChange }\">\n                <!-- 省 -->\n                <view class=\"area-item\">\n                    <view class=\"u-padding-10 u-bg-gray\" style=\"height: 100%\">\n                        <scroll-view :scroll-y=\"true\" style=\"height: 100%\">\n                            <u-cell-group>\n                                <u-cell-item\n                                    v-for=\"(item, index) in provincesList\"\n                                    :title=\"item.label\"\n                                    :arrow=\"false\"\n                                    :index=\"index\"\n                                    :key=\"index\"\n                                    @click=\"provinceChange(index)\"\n                                >\n                                    <template v-if=\"isChooseP && province === index\" #right-icon>\n                                        <u-icon size=\"34\" name=\"checkbox-mark\"></u-icon>\n                                    </template>\n                                </u-cell-item>\n                            </u-cell-group>\n                        </scroll-view>\n                    </view>\n                </view>\n                <!-- 市 -->\n                <view class=\"area-item\">\n                    <view class=\"u-padding-10 u-bg-gray\" style=\"height: 100%\">\n                        <scroll-view :scroll-y=\"true\" style=\"height: 100%\">\n                            <u-cell-group v-if=\"isChooseP\">\n                                <u-cell-item\n                                    v-for=\"(item, index) in citys\"\n                                    :title=\"item.label\"\n                                    :arrow=\"false\"\n                                    :index=\"index\"\n                                    :key=\"index\"\n                                    @click=\"cityChange(index)\"\n                                >\n                                    <template v-if=\"isChooseC && city === index\" #right-icon>\n                                        <u-icon size=\"34\" name=\"checkbox-mark\"></u-icon>\n                                    </template>\n                                </u-cell-item>\n                            </u-cell-group>\n                        </scroll-view>\n                    </view>\n                </view>\n                <!-- 区 -->\n                <view class=\"area-item\">\n                    <view class=\"u-padding-10 u-bg-gray\" style=\"height: 100%\">\n                        <scroll-view :scroll-y=\"true\" style=\"height: 100%\">\n                            <u-cell-group v-if=\"isChooseC\">\n                                <u-cell-item\n                                    v-for=\"(item, index) in areas\"\n                                    :title=\"item.label\"\n                                    :arrow=\"false\"\n                                    :index=\"index\"\n                                    :key=\"index\"\n                                    @click=\"areaChange(index)\"\n                                >\n                                    <template v-if=\"isChooseA && area === index\" #right-icon>\n                                        <u-icon size=\"34\" name=\"checkbox-mark\"></u-icon>\n                                    </template>\n                                </u-cell-item>\n                            </u-cell-group>\n                        </scroll-view>\n                    </view>\n                </view>\n            </view>\n        </view>\n    </u-popup>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-city-select',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted } from 'vue';\nimport provinces from '../../libs/util/province';\nimport citysData from '../../libs/util/city';\nimport areasData from '../../libs/util/area';\nimport { CitySelectProps } from './types';\nimport { $u } from '../..';\n\n/**\n * u-city-select 城市选择器\n * @description 用于选择省、市、区三级行政区域，支持回显和自定义初始值。\n * @property {Boolean} modelValue 控制弹窗显示与隐藏（v-model）\n * @property {Array} defaultRegion 默认选中的省市区名称数组，如 ['山东省', '青岛市', '崂山区']\n * @property {Array} areaCode 默认选中的省市区编码数组，如 ['440000', '440100', '440106']\n * @property {Boolean} maskCloseAble 是否允许点击遮罩关闭弹窗（默认 true）\n * @property {String|Number} zIndex 弹窗层级（默认 0，自动适配）\n * @event update:modelValue v-model 绑定值变化时触发\n * @event city-change 选择省市区后触发，返回选中的省市区对象\n * @example <u-city-select v-model=\"show\" :defaultRegion=\"['山东省', '青岛市', '崂山区']\" @city-change=\"onChange\"></u-city-select>\n */\nconst props = defineProps(CitySelectProps);\n\n// emits 定义\nconst emit = defineEmits(['update:modelValue', 'city-change']);\n\n// 省市区选择相关响应式数据\nconst cityValue = ref('');\nconst isChooseP = ref(false); // 是否已选省\nconst province = ref(0); // 省下标\nconst provincesList = ref(provinces);\nconst isChooseC = ref(false); // 是否已选市\nconst city = ref(0); // 市下标\nconst citys = ref(citysData[0]);\nconst isChooseA = ref(false); // 是否已选区\nconst area = ref(0); // 区下标\nconst areas = ref(areasData[0][0]);\nconst tabsIndex = ref(0);\n\n// v-model 双向绑定\nconst popupValue = computed({\n    get: () => props.modelValue,\n    set: val => emit('update:modelValue', val)\n});\n\n// 是否切换到区级\nconst isChange = computed(() => tabsIndex.value > 1);\n\n// 顶部 tab 列表\nconst genTabsList = computed(() => {\n    const tabsList = [{ name: '请选择' }];\n    if (isChooseP.value) {\n        tabsList[0].name = provincesList.value[province.value].label;\n        tabsList[1] = { name: '请选择' };\n    }\n    if (isChooseC.value) {\n        tabsList[1].name = citys.value[city.value].label;\n        tabsList[2] = { name: '请选择' };\n    }\n    if (isChooseA.value) {\n        tabsList[2].name = areas.value[area.value].label;\n    }\n    return tabsList;\n});\n\n// z-index 计算\nconst uZIndex = computed(() => (props.zIndex ? props.zIndex : (uni as any).$u?.zIndex?.popup || 1075));\n\n// 初始化选中项\nfunction init() {\n    if (props.areaCode.length === 3) {\n        setProvince('', props.areaCode[0]);\n        setCity('', props.areaCode[1]);\n        setArea('', props.areaCode[2]);\n    } else if (props.defaultRegion.length === 3) {\n        setProvince(props.defaultRegion[0], '');\n        setCity(props.defaultRegion[1], '');\n        setArea(props.defaultRegion[2], '');\n    }\n}\n\n// 选中省\nfunction setProvince(label = '', value = '') {\n    provincesList.value.forEach((v, k) => {\n        if (value ? v.value == value : v.label == label) {\n            provinceChange(k);\n        }\n    });\n}\n// 选中市\nfunction setCity(label = '', value = '') {\n    citys.value.forEach((v, k) => {\n        if (value ? v.value == value : v.label == label) {\n            cityChange(k);\n        }\n    });\n}\n// 选中区\nfunction setArea(label = '', value = '') {\n    areas.value.forEach((v, k) => {\n        if (value ? v.value == value : v.label == label) {\n            isChooseA.value = true;\n            area.value = k;\n        }\n    });\n}\n\n// 关闭弹窗\nfunction close() {\n    emit('update:modelValue', false);\n}\n// tab 切换\nfunction tabsChange(index: number) {\n    tabsIndex.value = index;\n}\n// 省点击\nfunction provinceChange(index: number) {\n    isChooseP.value = true;\n    isChooseC.value = false;\n    isChooseA.value = false;\n    province.value = index;\n    citys.value = citysData[index];\n    tabsIndex.value = 1;\n}\n// 市点击\nfunction cityChange(index: number) {\n    isChooseC.value = true;\n    isChooseA.value = false;\n    city.value = index;\n    areas.value = areasData[province.value][index];\n    tabsIndex.value = 2;\n}\n// 区点击\nfunction areaChange(index: number) {\n    isChooseA.value = true;\n    area.value = index;\n    const result = {\n        province: provincesList.value[province.value],\n        city: citys.value[city.value],\n        area: areas.value[area.value]\n    };\n    emit('city-change', result);\n    close();\n}\n\n// 挂载时初始化\nonMounted(init);\n</script>\n\n<style lang=\"scss\">\n.area-box {\n    width: 100%;\n    overflow: hidden;\n    height: 800rpx;\n\n    > view {\n        width: 150%;\n        transition: transform 0.3s ease-in-out 0s;\n        transform: translateX(0);\n\n        &.change {\n            transform: translateX(-33.3333333%);\n        }\n    }\n\n    .area-item {\n        width: 33.3333333%;\n        height: 800rpx;\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-col/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { AlignType, JustifyType } from '../../types/global';\n\n/**\n * u-col 布局单元格 Props\n * @description 通过基础的 12 分栏，迅速简便地创建布局（搭配<u-row>使用）\n * @property {String|Number} span 栅格占据的列数，总12等分（默认12）\n * @property {String|Number} offset 分栏左边偏移，计算方式与span相同（默认0）\n * @property {JustifyType} justify 水平排列方式，可选值为start、end、center、around、between（默认start）\n * @property {AlignType} align 垂直对齐方式，可选值为top、center、bottom（默认center）\n * @property {String} textAlign 文字对齐方式（默认left）\n * @property {Boolean} stop 是否阻止事件传播（默认true）\n */\n\nexport const ColProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 占父容器宽度的多少等分，总分为12份 */\n    span: { type: [Number, String] as PropType<number | string>, default: 12 },\n    /** 指定栅格左侧的间隔数(总12栏) */\n    offset: { type: [Number, String] as PropType<number | string>, default: 0 },\n    /** 水平排列方式 */\n    justify: { type: String as PropType<JustifyType>, default: 'start' },\n    /** 垂直对齐方式 */\n    align: { type: String as PropType<AlignType>, default: 'center' },\n    /** 文字对齐方式 */\n    textAlign: { type: String, default: 'left' },\n    /** 是否阻止事件传播 */\n    stop: { type: Boolean, default: true }\n};\n\nexport type ColProps = ExtractPropTypes<typeof ColProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-col/u-col.vue",
    "content": "<template>\n    <view\n        class=\"u-col\"\n        :class=\"['u-col-' + span, customClass]\"\n        :style=\"$u.toStyle(colStyle, customStyle)\"\n        @tap=\"onClick\"\n    >\n        <slot></slot>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-col',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { ColProps } from './types';\nimport { $u, useChildren } from '../../';\n\n/**\n * col 布局单元格\n * @description 通过基础的 12 分栏，迅速简便地创建布局（搭配<u-row>使用）\n * @tutorial https://uviewpro.cn/zh/components/layout.html\n * @property {String|Number} span 栅格占据的列数，总12等分（默认0）\n * @property {String} text-align 文字水平对齐方式（默认left）\n * @property {String|Number} offset 分栏左边偏移，计算方式与span相同（默认0）\n * @example <u-col span=\"3\"><view class=\"demo-layout bg-purple\"></view></u-col>\n */\n\nconst emit = defineEmits<{ (e: 'click'): void }>();\n\nconst props = defineProps(ColProps);\n\nconst { parentExposed } = useChildren('u-col', 'u-row');\n\n/**\n * gutter 给col添加间距，左右边距各占一半，从父组件u-row获取\n */\nconst gutter = computed(() => {\n    return parentExposed?.value?.props?.gutter ?? 20;\n});\n\n/**\n * 计算水平排列方式\n * @returns {string}\n */\nconst uJustify = computed(() => {\n    if (props.justify === 'end' || props.justify === 'start') return 'flex-' + props.justify;\n    else if (props.justify === 'around' || props.justify === 'between') return 'space-' + props.justify;\n    else return props.justify;\n});\n\n/**\n * 计算垂直对齐方式\n * @returns {string}\n */\nconst uAlignItem = computed(() => {\n    if (props.align === 'top') return 'flex-start';\n    if (props.align === 'bottom') return 'flex-end';\n    else return props.align;\n});\n\n/**\n * 计算样式对象\n */\nconst colStyle = computed<any>(() => ({\n    padding: `0 ${Number(gutter.value) / 2}px`,\n    marginLeft: `${(100 / 12) * Number(props.offset)}%`,\n    flex: `0 0 ${(100 / 12) * Number(props.span)}%`,\n    alignItems: uAlignItem.value,\n    justifyContent: uJustify.value,\n    textAlign: props.textAlign\n}));\n\n/**\n * 点击事件\n * @param e 事件对象\n */\nfunction onClick(e: Event) {\n    emit('click');\n}\n</script>\n\n<style lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n\n.u-col {\n    /* #ifdef MP-WEIXIN || MP-QQ || MP-TOUTIAO */\n    float: left;\n    /* #endif */\n}\n\n.u-col-0 {\n    width: 0;\n}\n.u-col-1 {\n    width: calc(100% / 12);\n}\n.u-col-2 {\n    width: calc(100% / 12 * 2);\n}\n.u-col-3 {\n    width: calc(100% / 12 * 3);\n}\n.u-col-4 {\n    width: calc(100% / 12 * 4);\n}\n.u-col-5 {\n    width: calc(100% / 12 * 5);\n}\n.u-col-6 {\n    width: calc(100% / 12 * 6);\n}\n.u-col-7 {\n    width: calc(100% / 12 * 7);\n}\n.u-col-8 {\n    width: calc(100% / 12 * 8);\n}\n.u-col-9 {\n    width: calc(100% / 12 * 9);\n}\n.u-col-10 {\n    width: calc(100% / 12 * 10);\n}\n.u-col-11 {\n    width: calc(100% / 12 * 11);\n}\n.u-col-12 {\n    width: calc(100% / 12 * 12);\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-collapse/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\n/**\n * u-collapse 手风琴 Props\n * @description 通过折叠面板收纳内容区域\n * @property {Boolean} accordion 是否手风琴模式（默认true）\n * @property {Object} headStyle 标题自定义样式，对象形式\n * @property {Object} bodyStyle 主体自定义样式，对象形式\n * @property {Object} itemStyle 每一个item的样式，对象形式\n * @property {Boolean} arrow 是否显示标题右侧的箭头（默认true）\n * @property {String} arrowColor 标题右侧箭头的颜色（默认var(--u-tips-color)）\n * @property {String} hoverClass 样式类名，按下时有效（默认u-hover-class）\n */\nexport const CollapseProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 是否手风琴模式 */\n    accordion: { type: Boolean, default: true },\n    /** 头部的样式 */\n    headStyle: { type: Object as PropType<Record<string, any>>, default: () => ({}) },\n    /** 主体的样式 */\n    bodyStyle: { type: Object as PropType<Record<string, any>>, default: () => ({}) },\n    /** 每一个item的样式 */\n    itemStyle: { type: Object as PropType<Record<string, any>>, default: () => ({}) },\n    /** 是否显示右侧的箭头 */\n    arrow: { type: Boolean, default: true },\n    /** 箭头的颜色 */\n    arrowColor: { type: String, default: 'var(--u-tips-color)' },\n    /** 标题部分按压时的样式类，\"none\"为无效果 */\n    hoverClass: { type: String, default: 'u-hover-class' }\n};\n\nexport type CollapseProps = ExtractPropTypes<typeof CollapseProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-collapse/u-collapse.vue",
    "content": "<template>\n    <view class=\"u-collapse\" :style=\"$u.toStyle(customStyle)\" :class=\"customClass\">\n        <slot />\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-collapse',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { nextTick, onMounted, ref } from 'vue';\nimport { CollapseProps } from './types';\nimport { $u, useParent } from '../../';\n\n/**\n * collapse 手风琴\n * @description 通过折叠面板收纳内容区域\n * @tutorial https://uviewpro.cn/zh/components/collapse.html\n * @property {Boolean} accordion 是否手风琴模式（默认true）\n * @property {Boolean} arrow 是否显示标题右侧的箭头（默认true）\n * @property {String} arrow-color 标题右侧箭头的颜色（默认var(--u-tips-color)）\n * @property {Object} head-style 标题自定义样式，对象形式\n * @property {Object} body-style 主体自定义样式，对象形式\n * @property {String} hover-class 样式类名，按下时有效（默认u-hover-class）\n * @event {Function} change 当前激活面板展开时触发(如果是手风琴模式，参数activeNames类型为String，否则为Array)\n * @example <u-collapse></u-collapse>\n */\nconst props = defineProps(CollapseProps);\nconst emit = defineEmits(['change']);\n\n// 使用通信库的父组件Hook\nconst { children, broadcast, getChildrenExposed } = useParent('u-collapse');\n\n// 当前激活的面板 - 只在手风琴模式下使用\nconst activeName = ref<string | number>('');\n\nonMounted(() => {\n    nextTick(() => {\n        // 初始化：收集所有open为true的项\n        setTimeout(() => {\n            initializeActiveName();\n        }, 100);\n    });\n});\n\n/**\n * 初始化activeName - 找到第一个open为true的项\n */\nfunction initializeActiveName() {\n    if (props.accordion) {\n        // 手风琴模式下，取第一个open为true的项作为初始激活项\n        const childrenExposed = getChildrenExposed();\n        const openChild = childrenExposed.find(child => child.exposed.isShow === true);\n        if (openChild) {\n            activeName.value = openChild.exposed.itemName || '';\n        }\n    }\n}\n\n/**\n * collapse item被点击，由collapse item调用父组件方法\n */\nfunction onChange(name: string | number) {\n    if (props.accordion) {\n        // 手风琴模式\n        const childrenExposed = getChildrenExposed();\n        const targetChild = childrenExposed.find(child => child.exposed.itemName === name);\n        if (targetChild?.exposed.isShow.value === true) {\n            // 目标项当前是展开状态，点击后要关闭它\n            activeName.value = '';\n            broadcast('closeAll', {});\n        } else {\n            // 目标项当前是关闭状态，点击后要展开它并关闭其他\n            activeName.value = name;\n            broadcast('openSingle', { targetName: name });\n        }\n    } else {\n        // 非手风琴模式 - 只通知目标项切换状态\n        broadcast('toggleSingle', { targetName: name });\n    }\n\n    // 收集当前所有展开的项\n    let currentActiveNames: (string | number)[] = [];\n    if (props.accordion) {\n        currentActiveNames = activeName.value === 0 || activeName.value ? [activeName.value] : [];\n    } else {\n        // 对于非手风琴模式，我们不知道所有项的状态\n        currentActiveNames = [];\n        children.forEach(child => {\n            if (child.getExposed().isShow.value) {\n                currentActiveNames.push(child.getExposed().itemName);\n            }\n        });\n    }\n    currentActiveNames.length > 0 && emit('change', props.accordion ? activeName.value || '' : currentActiveNames);\n}\n\n/**\n * 设置激活的面板\n */\nfunction setActiveNames(names: string | number | (string | number)[]) {\n    if (props.accordion) {\n        // 手风琴模式\n        const name = Array.isArray(names) ? names[0] : names;\n        activeName.value = name || '';\n        if (name) {\n            broadcast('openSingle', { targetName: name });\n        } else {\n            broadcast('closeAll', {});\n        }\n    } else {\n        // 非手风琴模式\n        const namesArray = Array.isArray(names) ? names : [names];\n        broadcast('setMultiple', { targetNames: namesArray });\n    }\n}\n\n/**\n * 打开所有面板\n */\nfunction openAll() {\n    if (props.accordion) {\n        console.warn('手风琴模式下不能打开所有面板');\n        return;\n    }\n    const childrenExposed = getChildrenExposed();\n    const allNames = childrenExposed.map(child => child.exposed.itemName).filter(Boolean);\n    broadcast('setMultiple', { targetNames: allNames });\n}\n\n/**\n * 关闭所有面板\n */\nfunction closeAll() {\n    broadcast('closeAll', {});\n    if (props.accordion) {\n        activeName.value = '';\n    }\n}\n\n/**\n * 重新初始化，用于动态内容变化\n */\nfunction init() {\n    const childrenExposed = getChildrenExposed();\n    childrenExposed.forEach(child => {\n        if (child.exposed.init) {\n            child.exposed.init();\n        }\n    });\n\n    // 重新初始化activeName\n    setTimeout(() => {\n        initializeActiveName();\n    }, 150);\n}\n\n// 使用defineExpose暴露给外部\ndefineExpose({\n    // props\n    props,\n\n    // 状态\n    activeName,\n\n    // 方法\n    onChange,\n    setActiveNames,\n    openAll,\n    closeAll,\n    init,\n\n    // 计算属性\n    childrenCount: () => children.length\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-collapse-item/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { TextAlign } from '../../types/global';\n\n/**\n * u-collapse-item 手风琴Item Props\n * @description 通过折叠面板收纳内容区域（搭配u-collapse使用）\n */\nexport const CollapseItemProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 标题 */\n    title: { type: String, default: '' },\n    /** 标题的对齐方式 */\n    align: { type: String as PropType<TextAlign>, default: 'left' },\n    /** 是否可以点击收起 */\n    disabled: { type: Boolean, default: false },\n    /** collapse显示与否 */\n    open: { type: Boolean, default: false },\n    /** 唯一标识符 */\n    name: { type: [Number, String] as PropType<number | string>, default: '' },\n    /** 活动样式 */\n    activeStyle: { type: Object as PropType<Record<string, any>>, default: () => ({}) },\n    /** 标识当前为第几个 */\n    index: { type: [String, Number] as PropType<string | number>, default: '' }\n};\n\nexport type CollapseItemProps = ExtractPropTypes<typeof CollapseItemProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-collapse-item/u-collapse-item.vue",
    "content": "<template>\n    <view class=\"u-collapse-item\" :style=\"$u.toStyle(itemStyle, customStyle)\" :class=\"customClass\">\n        <view\n            :hover-stay-time=\"200\"\n            class=\"u-collapse-head\"\n            @tap.stop=\"headClick\"\n            :hover-class=\"hoverClass\"\n            :style=\"headStyle\"\n        >\n            <template v-if=\"!slots['title-all']\">\n                <view v-if=\"!slots['title']\" class=\"u-collapse-title u-line-1\" :style=\"titleStyle\">\n                    {{ title }}\n                </view>\n                <slot v-else name=\"title\" />\n                <view class=\"u-icon-wrap\">\n                    <u-icon v-if=\"showArrow\" :color=\"arrowColor\" :name=\"isShow ? 'arrow-up' : 'arrow-down'\" />\n                </view>\n            </template>\n            <slot v-else name=\"title-all\" />\n        </view>\n\n        <view class=\"u-collapse-body\" :style=\"{ height: isShow ? height : '0' }\">\n            <view class=\"u-collapse-content\" :id=\"elId\" :style=\"bodyStyle\">\n                <slot></slot>\n            </view>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-collapse-item',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, watch, onMounted, useSlots, getCurrentInstance, nextTick, computed } from 'vue';\nimport { $u, useChildren } from '../..';\nimport { CollapseItemProps } from './types';\n\n/**\n * collapseItem 手风琴Item\n * @description 通过折叠面板收纳内容区域（搭配u-collapse使用）\n * @tutorial https://uviewpro.cn/zh/components/collapse.html\n * @property {String} title 面板标题\n * @property {String Number} index 主要用于事件的回调，标识那个Item被点击\n * @property {Boolean} disabled 面板是否可以打开或收起（默认false）\n * @property {Boolean} open 设置某个面板的初始状态是否打开（默认false）\n * @property {String Number} name 唯一标识符，如不设置，默认用当前collapse-item的索引值\n * @property {String} align 标题的对齐方式（默认left）\n * @property {Object} active-style 不显示箭头时，可以添加当前选择的collapse-item活动样式，对象形式\n * @event {Function} change 某个item被打开或者收起时触发\n * @example <u-collapse-item :title=\"item.head\" v-for=\"(item, index) in itemList\" :key=\"index\">{{item.body}}</u-collapse-item>\n */\nconst props = defineProps(CollapseItemProps);\nconst emit = defineEmits(['change']);\nconst slots = useSlots();\nconst instance = getCurrentInstance();\n\nconst isShow = ref(false);\nconst elId = ref('');\nconst height = ref('0');\nconst headStyle = ref<Record<string, any>>({});\nconst bodyStyle = ref<Record<string, any>>({});\nconst itemStyle = ref<Record<string, any>>({});\nconst arrowColor = ref('');\nconst hoverClass = ref('');\n\n// 使用通信库的子组件Hook\nconst { childId, parentExposed } = useChildren('u-collapse-item', 'u-collapse');\n\n// 计算属性\nconst showArrow = computed(() => {\n    return parentExposed.value?.props ? parentExposed.value.props.arrow : true;\n});\n\nconst titleStyle = computed(() => {\n    let style = { textAlign: props.align ? props.align : 'left' };\n\n    if (isShow.value && props.activeStyle && !showArrow.value) {\n        style = $u.deepMerge(style, props.activeStyle);\n    }\n    return $u.toStyle(style);\n});\n\n// 获取唯一标识符\nconst itemName = computed(() => {\n    // 优先级：name > index > childId\n    if (props.name !== undefined && props.name !== '') {\n        return props.name;\n    } else if (props.index !== undefined && props.index !== '') {\n        return props.index;\n    } else {\n        return childId;\n    }\n});\n\n/**\n * 设置显示状态\n */\nfunction setShowState(show: boolean) {\n    if (isShow.value !== show) {\n        isShow.value = show;\n\n        // 如果展开，需要重新计算高度\n        if (show) {\n            nextTick(() => {\n                queryRect();\n            });\n        }\n\n        // 本地触发change事件\n        emit('change', {\n            index: props.index,\n            name: itemName.value,\n            show: isShow.value\n        });\n    }\n}\n\n/**\n * 异步获取内容，或者动态修改了内容时，需要重新初始化\n */\nfunction init() {\n    if (parentExposed.value?.props) {\n        headStyle.value = parentExposed.value.props.headStyle || {};\n        bodyStyle.value = parentExposed.value.props.bodyStyle || {};\n        arrowColor.value = parentExposed.value.props.arrowColor || 'var(--u-tips-color)';\n        hoverClass.value = parentExposed.value.props.hoverClass || 'u-hover-class';\n        itemStyle.value = parentExposed.value.props.itemStyle || {};\n    }\n\n    elId.value = $u.guid();\n    nextTick(() => {\n        queryRect();\n    });\n}\n\n/**\n * 点击collapse head头部\n */\nfunction headClick() {\n    if (props.disabled) return;\n    // 通知父组件状态变化\n    parentExposed?.value?.onChange(itemName.value);\n}\n\n/**\n * 查询内容高度\n */\nfunction queryRect() {\n    $u.getRect('#' + elId.value, instance)\n        .then((res: any) => {\n            if (res && res.height) {\n                height.value = res.height + 'px';\n            }\n            // #ifdef MP-TOUTIAO\n            if (isShow.value) {\n                height.value = 'auto';\n            }\n            // #endif\n        })\n        .catch((err: any) => {\n            console.warn('queryRect error:', err);\n            height.value = 'auto';\n        });\n}\n\n// 单选\nfunction openSingle(data: any) {\n    // 只有目标项展开，其他都关闭\n    const shouldShow = data.targetName === itemName.value;\n    setShowState(shouldShow);\n}\n\n// 关闭所有\nfunction closeAll() {\n    setShowState(false);\n}\n\n// 多选\nfunction setMultiple(data: any) {\n    const shouldShow = data.targetNames.includes(itemName.value);\n    setShowState(shouldShow);\n}\n\n// 切换单个\nfunction toggleSingle(data: any) {\n    // 只有目标项才切换状态\n    if (data.targetName === itemName.value) {\n        setShowState(!isShow.value);\n    }\n}\n\nonMounted(() => {\n    // 关键修复：根据 open 属性设置初始状态\n    setShowState(props.open);\n    // 初始化\n    init();\n});\n\n// 监听 open 属性变化\nwatch(\n    () => props.open,\n    newVal => {\n        setShowState(newVal);\n    }\n);\n\n// 监听父组件exposed的变化\nwatch(\n    parentExposed,\n    newExposed => {\n        if (newExposed) {\n            init();\n        }\n    },\n    { deep: true, immediate: true }\n);\n\ndefineExpose({\n    init,\n    isShow,\n    elId,\n    height,\n    headStyle,\n    bodyStyle,\n    itemStyle,\n    arrowColor,\n    hoverClass,\n    itemName: itemName.value,\n    queryRect,\n    setShowState,\n    openSingle,\n    closeAll,\n    setMultiple,\n    toggleSingle\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-collapse-head {\n    position: relative;\n    @include vue-flex;\n    justify-content: space-between;\n    align-items: center;\n    color: $u-main-color;\n    font-size: 30rpx;\n    line-height: 1;\n    padding: 24rpx 0;\n    text-align: left;\n}\n\n.u-collapse-title {\n    flex: 1;\n    overflow: hidden;\n}\n\n.u-arrow-down-icon {\n    transition: all 0.3s;\n    margin-right: 20rpx;\n    margin-left: 14rpx;\n}\n\n.u-arrow-down-icon-active {\n    transform: rotate(180deg);\n    transform-origin: center center;\n}\n\n.u-collapse-body {\n    overflow: hidden;\n    transition: all 0.3s;\n}\n\n.u-collapse-content {\n    overflow: hidden;\n    font-size: 28rpx;\n    color: $u-tips-color;\n    text-align: left;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-column-notice/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { Direction, PlayState, ScrollDirection, ThemeType } from '../../types/global';\n\n/**\n * u-column-notice 通告栏 Props\n */\nexport const ColumnNoticeProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 显示的内容，数组 */\n    list: { type: Array as PropType<string[]>, default: () => [] },\n    /** 显示的主题，success|error|primary|info|warning */\n    type: { type: String as PropType<ThemeType | 'none'>, default: 'warning' },\n    /** 是否显示左侧的音量图标 */\n    volumeIcon: { type: Boolean, default: true },\n    /** 是否显示右侧的右箭头图标 */\n    moreIcon: { type: Boolean, default: false },\n    /** 是否显示右侧的关闭图标 */\n    closeIcon: { type: Boolean, default: false },\n    /** 是否自动播放 */\n    autoplay: { type: Boolean, default: true },\n    /** 文字颜色，各图标也会使用文字颜色 */\n    color: { type: String, default: '' },\n    /** 背景颜色 */\n    bgColor: { type: String, default: '' },\n    /** 滚动方向，row-水平滚动，column-垂直滚动 */\n    direction: { type: String as PropType<ScrollDirection>, default: 'row' },\n    /** 是否显示 */\n    show: { type: Boolean, default: true },\n    /** 字体大小，单位rpx */\n    fontSize: { type: [Number, String] as PropType<number | string>, default: 26 },\n    /** 滚动一个周期的时间长，单位ms */\n    duration: { type: [Number, String] as PropType<number | string>, default: 2000 },\n    /** 音量喇叭的大小 */\n    volumeSize: { type: [Number, String] as PropType<number | string>, default: 34 },\n    /** 水平滚动时的滚动速度，即每秒滚动多少rpx，这有利于控制文字无论多少时，都能有一个恒定的速度 */\n    speed: { type: Number, default: 160 },\n    /** 水平滚动时，是否采用衔接形式滚动 */\n    isCircular: { type: Boolean, default: true },\n    /** 滚动方向，horizontal-水平滚动，vertical-垂直滚动 */\n    mode: { type: String as PropType<Direction>, default: 'horizontal' },\n    /** 播放状态，play-播放，paused-暂停 */\n    playState: { type: String as PropType<PlayState>, default: 'play' },\n    /** 是否禁止用手滑动切换 */\n    disableTouch: { type: Boolean, default: true },\n    /** 通知的边距 */\n    padding: { type: [Number, String] as PropType<number | string>, default: '18rpx 24rpx' }\n};\n\nexport type ColumnNoticeProps = ExtractPropTypes<typeof ColumnNoticeProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-column-notice/u-column-notice.vue",
    "content": "<template>\n    <view\n        class=\"u-notice-bar\"\n        :style=\"$u.toStyle({ background: computeBgColor, padding: props.padding }, customStyle)\"\n        :class=\"[props.type ? `u-type-${props.type}-light-bg` : '', customClass]\"\n    >\n        <view class=\"u-icon-wrap\">\n            <u-icon\n                class=\"u-left-icon\"\n                v-if=\"props.volumeIcon\"\n                name=\"volume-fill\"\n                :size=\"props.volumeSize\"\n                :color=\"computeColor\"\n            ></u-icon>\n        </view>\n        <swiper\n            :disable-touch=\"props.disableTouch\"\n            @change=\"change\"\n            :autoplay=\"props.autoplay && props.playState === 'play'\"\n            :vertical=\"vertical\"\n            circular\n            :interval=\"props.duration\"\n            class=\"u-swiper\"\n        >\n            <swiper-item v-for=\"(item, index) in props.list\" :key=\"index\" class=\"u-swiper-item\">\n                <view\n                    class=\"u-news-item u-line-1\"\n                    :style=\"textStyle\"\n                    @tap=\"click(index)\"\n                    :class=\"['u-type-' + props.type]\"\n                >\n                    {{ item }}\n                </view>\n            </swiper-item>\n        </swiper>\n        <view class=\"u-icon-wrap\">\n            <u-icon\n                @click=\"getMore\"\n                class=\"u-right-icon\"\n                v-if=\"props.moreIcon\"\n                name=\"arrow-right\"\n                :size=\"26\"\n                :color=\"computeColor\"\n            ></u-icon>\n            <u-icon\n                @click=\"close\"\n                class=\"u-right-icon\"\n                v-if=\"props.closeIcon\"\n                name=\"close\"\n                :size=\"24\"\n                :color=\"computeColor\"\n            ></u-icon>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-column-notice',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { ColumnNoticeProps } from './types';\nimport { $u } from '../../';\n\n/**\n * u-column-notice 通告栏\n * @property {Array} list 显示的内容，数组\n * @property {String} type 显示的主题，success|error|primary|info|warning\n * @property {Boolean} volumeIcon 是否显示左侧的音量图标\n * @property {Boolean} moreIcon 是否显示右侧的右箭头图标\n * @property {Boolean} closeIcon 是否显示右侧的关闭图标\n * @property {Boolean} autoplay 是否自动播放\n * @property {String} color 文字颜色，各图标也会使用文字颜色\n * @property {String} bgColor 背景颜色\n * @property {String} direction 滚动方向，row-水平滚动，column-垂直滚动\n * @property {Boolean} show 是否显示\n * @property {String|Number} fontSize 字体大小，单位rpx\n * @property {String|Number} duration 滚动一个周期的时间长，单位ms\n * @property {String|Number} volumeSize 音量喇叭的大小\n * @property {Number} speed 水平滚动时的滚动速度，即每秒滚动多少rpx\n * @property {Boolean} isCircular 水平滚动时，是否采用衔接形式滚动\n * @property {String} mode 滚动方向，horizontal-水平滚动，vertical-垂直滚动\n * @property {String} playState 播放状态，play-播放，paused-暂停\n * @property {Boolean} disableTouch 是否禁止用手滑动切换\n * @property {String|Number} padding 通知的边距\n */\n\nconst props = defineProps(ColumnNoticeProps);\n\nconst emit = defineEmits<{\n    (e: 'click', index: number): void;\n    (e: 'close'): void;\n    (e: 'getMore'): void;\n    (e: 'end'): void;\n}>();\n\n/**\n * 计算字体颜色，如果没有自定义的，就用uview主题颜色\n */\nconst computeColor = computed(() => {\n    if (props.color) return props.color;\n    // 如果是无主题，就默认使用content-color\n    else if (props.type === 'none') return 'var(--u-content-color)';\n    else return props.type;\n});\n\n/**\n * 文字内容的样式\n */\nconst textStyle = computed(() => {\n    const style: Record<string, any> = {};\n    if (props.color) style.color = props.color;\n    else if (props.type === 'none') style.color = 'var(--u-content-color)';\n    style.fontSize = props.fontSize + 'rpx';\n    return style;\n});\n\n/**\n * 垂直或者水平滚动\n */\nconst vertical = computed(() => {\n    return props.mode !== 'horizontal';\n});\n\n/**\n * 计算背景颜色\n */\nconst computeBgColor = computed(() => {\n    if (props.bgColor) return props.bgColor;\n    else if (props.type === 'none') return 'transparent';\n    else return '';\n});\n\n/**\n * 点击通告栏\n */\nfunction click(index: number) {\n    emit('click', index);\n}\n\n/**\n * 点击关闭按钮\n */\nfunction close() {\n    emit('close');\n}\n\n/**\n * 点击更多箭头按钮\n */\nfunction getMore() {\n    emit('getMore');\n}\n\n/**\n * swiper 切换事件\n */\nfunction change(e: { detail: { current: number } }) {\n    const index = e.detail.current;\n    if (index === props.list.length - 1) {\n        emit('end');\n    }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-notice-bar {\n    width: 100%;\n    @include vue-flex;\n    align-items: center;\n    justify-content: center;\n    flex-wrap: nowrap;\n    padding: 18rpx 24rpx;\n    overflow: hidden;\n}\n\n.u-swiper {\n    font-size: 26rpx;\n    height: 32rpx;\n    @include vue-flex;\n    align-items: center;\n    flex: 1;\n    margin-left: 12rpx;\n}\n\n.u-swiper-item {\n    @include vue-flex;\n    align-items: center;\n    overflow: hidden;\n}\n\n.u-news-item {\n    overflow: hidden;\n}\n\n.u-right-icon {\n    margin-left: 12rpx;\n    /* #ifndef APP-NVUE */\n    display: inline-flex;\n    /* #endif */\n    align-items: center;\n}\n\n.u-left-icon {\n    /* #ifndef APP-NVUE */\n    display: inline-flex;\n    /* #endif */\n    align-items: center;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-config-provider/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport { config, configProvider } from '../../libs';\nimport type { Theme } from '../../types/global';\n\nexport const ConfigProviderProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /**\n     * 主题风格，可选值：\n     * - 'light': 强制亮色模式（默认）\n     * - 'dark': 强制暗黑模式\n     * - 'auto': 自动跟随系统设置\n     */\n    darkMode: {\n        type: String as PropType<'light' | 'dark' | 'auto'>,\n        default: () => config.defaultDarkMode\n    },\n    /**\n     * 当前主题名称（用于多主题切换）\n     */\n    currentTheme: {\n        type: String,\n        default: () => configProvider.getCurrentTheme()?.name ?? config.defaultTheme\n    },\n    /**\n     * 自定义主题列表\n     */\n    themes: {\n        type: Array as PropType<Theme[]>,\n        default: () => configProvider.getThemes()\n    },\n    /**\n     * 国际化配置：传入 locale 列表（数组）并可指定默认语言 currentLocale\n     */\n    locales: {\n        type: Array as PropType<any[]>,\n        default: () => []\n    },\n    currentLocale: {\n        type: String,\n        default: () => configProvider.getCurrentLocale()?.name ?? ''\n    }\n};\n\nexport type ConfigProviderProps = ExtractPropTypes<typeof ConfigProviderProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-config-provider/u-config-provider.vue",
    "content": "<template>\n    <view :class=\"['u-config-provider', `u-theme-${darkMode}`, customClass]\" :style=\"mergedThemeStyle\">\n        <slot />\n    </view>\n</template>\n\n<script lang=\"ts\">\n/**\n * u-config-provider\n *\n * 说明（简要）：\n * - 初始化场景（推荐在应用入口执行）：使用 `useTheme().initTheme(themes)` 进行一次性初始化与全局设置（例如在 `main.ts` 或 `App.vue` 中）。\n * - 组件/页面场景（推荐）：使用 `useTheme()` 组合式函数在组件内部读取响应式 `currentTheme`、`themes`、`darkMode` 并通过 `setTheme()` 和 `setDarkMode()` 切换主题/模式。\n *\n * 该组件的行为：\n * - 如果在挂载时传入 `themes`，会调用 `configProvider.initTheme(themes)`\n * - 如果传入 `currentTheme`，会优先设置当前主题\n * - 如果传入 `darkMode`，会设置当前的暗黑模式状态，同时在 document 上添加 `u-theme-dark` 或 `u-theme-light` 类名\n *\n * 详尽说明请参考：`docs/config-provider-usage.md`\n */\nexport default {\n    name: 'u-config-provider',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script lang=\"ts\" setup>\nimport { computed, watch, onMounted } from 'vue';\nimport { ConfigProviderProps } from './types';\nimport { $u, configProvider } from '../../libs';\nimport { useTheme } from '../../libs/hooks/useTheme';\nimport { useLocale } from '../../libs/hooks/useLocale';\n\nconst props = defineProps(ConfigProviderProps);\n\nconst emit = defineEmits<{\n    'theme-change': [themeName: string];\n    'mode-change': [mode: 'light' | 'dark'];\n}>();\n\n// 计算当前的主题模式（亮色/暗黑）\nconst darkMode = computed(() => (configProvider.isInDarkMode() ? 'dark' : 'light'));\n\nconst bootstrapTheme = () => {\n    // 如果已经初始化过主题，不再重复初始化，只更新 props 相关配置\n    const existingThemes = configProvider.getThemes();\n    if (existingThemes.length > 0) {\n        // 已初始化，只更新当前主题和暗黑模式\n        if (props.currentTheme) {\n            configProvider.setTheme(props.currentTheme as string);\n        }\n        if (props.darkMode) {\n            configProvider.setDarkMode(props.darkMode);\n        }\n        return;\n    }\n\n    // 未初始化，进行初始化\n    if (props.themes && props.themes.length) {\n        configProvider.initTheme(props.themes, props.currentTheme as any);\n    } else {\n        // 使用 useTheme 的 initTheme，它会处理默认主题\n        const { initTheme } = useTheme();\n        initTheme(undefined, props.currentTheme as any);\n    }\n\n    if (props.currentTheme) {\n        configProvider.setTheme(props.currentTheme as string);\n    }\n    if (props.darkMode) {\n        configProvider.setDarkMode(props.darkMode);\n    }\n};\n\nconst bootstrapLocale = () => {\n    // 初始化国际化\n    try {\n        const { initLocales, setLocale, getLocales } = useLocale();\n        const existingLocales = getLocales();\n        if (existingLocales.length > 0) {\n            if (props.currentLocale) {\n                setLocale(props.currentLocale as string);\n            }\n        } else {\n            if (props.locales && props.locales.length) {\n                initLocales(props.locales, props.currentLocale as any);\n            } else {\n                initLocales(undefined, props.currentLocale as any);\n            }\n        }\n    } catch (e) {\n        console.warn('[u-config-provider] init locales failed', e);\n    }\n};\n\n// 当传入自定义 themes 时，初始化全局 configProvider（覆盖已有）\nonMounted(() => {\n    bootstrapTheme();\n    bootstrapLocale();\n});\n\n// 监听外部 props 变化（如果上层修改 prop）\nwatch(\n    () => props.themes,\n    val => {\n        // 如果传入的 themes 来自于 configProvider 自身（常见于模板中使用 useTheme() 直接透传），\n        // 那么对其做深度监听会在我们内部更新主题对象时触发该回调，进而再次调用 init 导致循环更新。\n        // 为避免该情况，先做简单保护：当传入对象正是 configProvider.themesRef.value 时不重复初始化。\n        if (val && val.length && val !== configProvider.themesRef.value) {\n            configProvider.initTheme(val, props.currentTheme as any);\n        }\n    },\n    { deep: true }\n);\n\nwatch(\n    () => props.currentTheme,\n    val => {\n        if (val) {\n            configProvider.setTheme(val);\n        }\n    }\n);\n\nwatch(\n    () => props.darkMode,\n    val => {\n        if (val && val !== configProvider.getDarkMode()) {\n            configProvider.setDarkMode(val);\n            emit('mode-change', darkMode.value);\n        }\n    }\n);\n\n// 监听 locales prop 变化\nwatch(\n    () => props.locales,\n    val => {\n        if (val && val.length) {\n            const { initLocales } = useLocale();\n            initLocales(val, props.currentLocale as any);\n        }\n    },\n    { deep: true }\n);\n\nwatch(\n    () => props.currentLocale,\n    val => {\n        if (val) {\n            const { setLocale } = useLocale();\n            setLocale(val);\n        }\n    }\n);\n\n// 监听全局主题变更并触发事件\nwatch(\n    () => configProvider.currentThemeRef.value,\n    (val, oldVal) => {\n        if (val && val.name !== (oldVal as any)?.name) {\n            emit('theme-change', val.name);\n        }\n    },\n    { immediate: true }\n);\n\n// 监听暗黑模式变更并触发事件\nwatch(\n    () => configProvider.darkModeRef.value,\n    () => {\n        emit('mode-change', darkMode.value);\n    }\n);\n\n// 计算合并样式（作为局部 fallback），configProvider 已经会把变量注入到 document 上\nconst mergedThemeStyle = computed(() => {\n    return $u.toStyle(configProvider.cssVarsRef.value, props.customStyle);\n});\n</script>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-count-down/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\n/**\n * u-count-down 倒计时 Props\n * @description 该组件一般使用于某个活动的截止时间上，通过数字的变化，给用户明确的时间感受，提示用户进行某一个行为操作。\n */\nexport const CountDownProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 倒计时的时间，秒为单位 */\n    timestamp: { type: [Number, String] as PropType<number | string>, default: 0 },\n    /** 是否自动开始倒计时 */\n    autoplay: { type: Boolean, default: true },\n    /** 分隔符 */\n    separator: { type: String, default: 'colon' },\n    /** 分隔符的大小，单位rpx */\n    separatorSize: { type: [Number, String] as PropType<number | string>, default: 30 },\n    /** 分隔符颜色 */\n    separatorColor: { type: String, default: 'var(--u-main-color)' },\n    /** 字体颜色 */\n    color: { type: String, default: 'var(--u-main-color)' },\n    /** 字体大小，单位rpx */\n    fontSize: { type: [Number, String] as PropType<number | string>, default: 30 },\n    /** 背景颜色 */\n    bgColor: { type: String, default: 'var(--u-bg-white)' },\n    /** 数字框高度，单位rpx */\n    height: { type: [Number, String] as PropType<number | string>, default: 'auto' },\n    /** 是否显示数字框 */\n    showBorder: { type: Boolean, default: false },\n    /** 边框颜色 */\n    borderColor: { type: String, default: 'var(--u-main-color)' },\n    /** 是否显示秒 */\n    showSeconds: { type: Boolean, default: true },\n    /** 是否显示分钟 */\n    showMinutes: { type: Boolean, default: true },\n    /** 是否显示小时 */\n    showHours: { type: Boolean, default: true },\n    /** 是否显示“天” */\n    showDays: { type: Boolean, default: true },\n    /** 当\"天\"的部分为0时，不显示 */\n    hideZeroDay: { type: Boolean, default: false }\n};\n\nexport type CountDownProps = ExtractPropTypes<typeof CountDownProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-count-down/u-count-down.vue",
    "content": "<template>\n    <view class=\"u-countdown\" :class=\"customClass\" :style=\"$u.toStyle(customStyle)\">\n        <view\n            class=\"u-countdown-item\"\n            :style=\"$u.toStyle(itemStyle)\"\n            v-if=\"props.showDays && (props.hideZeroDay || (!props.hideZeroDay && d != '00'))\"\n        >\n            <view class=\"u-countdown-time\" :style=\"$u.toStyle(letterStyle)\">\n                {{ d }}\n            </view>\n        </view>\n        <view\n            class=\"u-countdown-colon\"\n            :style=\"{\n                fontSize: props.separatorSize + 'rpx',\n                color: props.separatorColor,\n                paddingBottom: props.separator == 'colon' ? '4rpx' : 0\n            }\"\n            v-if=\"props.showDays && (props.hideZeroDay || (!props.hideZeroDay && d != '00'))\"\n        >\n            {{ props.separator == 'colon' && props.showHours ? ':' : t('uCountDown.day') }}\n        </view>\n        <view class=\"u-countdown-item\" :style=\"$u.toStyle(itemStyle)\" v-if=\"props.showHours\">\n            <view class=\"u-countdown-time\" :style=\"{ fontSize: props.fontSize + 'rpx', color: props.color }\">\n                {{ h }}\n            </view>\n        </view>\n        <view\n            class=\"u-countdown-colon\"\n            :style=\"{\n                fontSize: props.separatorSize + 'rpx',\n                color: props.separatorColor,\n                paddingBottom: props.separator == 'colon' ? '4rpx' : 0\n            }\"\n            v-if=\"props.showHours\"\n        >\n            {{ props.separator == 'colon' && props.showMinutes ? ':' : t('uCountDown.hour') }}\n        </view>\n        <view class=\"u-countdown-item\" :style=\"$u.toStyle(itemStyle)\" v-if=\"props.showMinutes\">\n            <view class=\"u-countdown-time\" :style=\"{ fontSize: props.fontSize + 'rpx', color: props.color }\">\n                {{ i }}\n            </view>\n        </view>\n        <view\n            class=\"u-countdown-colon\"\n            :style=\"{\n                fontSize: props.separatorSize + 'rpx',\n                color: props.separatorColor,\n                paddingBottom: props.separator == 'colon' ? '4rpx' : 0\n            }\"\n            v-if=\"props.showMinutes\"\n        >\n            {{ props.separator == 'colon' && props.showSeconds ? ':' : t('uCountDown.minute') }}\n        </view>\n        <view class=\"u-countdown-item\" :style=\"$u.toStyle(itemStyle)\" v-if=\"props.showSeconds\">\n            <view class=\"u-countdown-time\" :style=\"{ fontSize: props.fontSize + 'rpx', color: props.color }\">\n                {{ s }}\n            </view>\n        </view>\n        <view\n            class=\"u-countdown-colon\"\n            :style=\"{ fontSize: props.separatorSize + 'rpx', color: props.separatorColor, paddingBottom: 0 }\"\n            v-if=\"props.showSeconds && props.separator == 'zh'\"\n        >\n            {{ t('uCountDown.second') }}\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-count-down',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, onMounted } from 'vue';\nimport { CountDownProps } from './types';\nimport { $u, useLocale } from '../../';\n\nconst { t } = useLocale();\n\n/**\n * countDown 倒计时\n * @description 该组件一般使用于某个活动的截止时间上，通过数字的变化，给用户明确的时间感受，提示用户进行某一个行为操作。\n * @tutorial https://uviewpro.cn/zh/components/countDown.html\n * @property {String | Number} timestamp 倒计时，单位为秒\n * @property {Boolean} autoplay 是否自动开始倒计时，如果为false，需手动调用开始方法。见官网说明（默认true）\n * @property {String} separator 分隔符，colon为英文冒号，zh为中文（默认colon）\n * @property {String | Number} separator-size 分隔符的字体大小，单位rpx（默认30）\n * @property {String} separator-color 分隔符的颜色（默认var(--u-main-color)）\n * @property {String | Number} font-size 倒计时字体大小，单位rpx（默认30）\n * @property {Boolean} show-border 是否显示倒计时数字的边框（默认false）\n * @property {Boolean} hide-zero-day 当\"天\"的部分为0时，隐藏该字段 （默认true）\n * @property {String} border-color 数字边框的颜色（默认var(--u-main-color)）\n * @property {String} bg-color 倒计时数字的背景颜色（默认var(--u-bg-white)）\n * @property {String} color 倒计时数字的颜色（默认var(--u-main-color)）\n * @property {String | Number} height 数字高度值(宽度等同此值)，设置边框时看情况是否需要设置此值，单位rpx（默认auto）\n * @property {Boolean} show-days 是否显示倒计时的\"天\"部分（默认true）\n * @property {Boolean} show-hours 是否显示倒计时的\"时\"部分（默认true）\n * @property {Boolean} show-minutes 是否显示倒计时的\"分\"部分（默认true）\n * @property {Boolean} show-seconds 是否显示倒计时的\"秒\"部分（默认true）\n * @event {Function} end 倒计时结束\n * @event {Function} change 每秒触发一次，回调为当前剩余的倒计秒数\n * @example <u-count-down ref=\"uCountDown\" :timestamp=\"86400\" :autoplay=\"false\"></u-count-down>\n */\n\nconst emit = defineEmits(['end', 'change']);\n\nconst props = defineProps(CountDownProps);\n\nconst d = ref('00'); // 天\nconst h = ref('00'); // 小时\nconst i = ref('00'); // 分钟\nconst s = ref('00'); // 秒\nconst timer = ref<number | ReturnType<typeof setInterval> | null>(null); // 定时器\nconst seconds = ref(0);\n\n/**\n * 倒计时item的样式，item为分别的时分秒部分的数字\n */\nconst itemStyle = computed(() => {\n    const style: Record<string, string> = {};\n    if (props.height) {\n        style.height = props.height + 'rpx';\n        style.width = props.height + 'rpx';\n    }\n    if (props.showBorder) {\n        style.borderStyle = 'solid';\n        style.borderColor = props.borderColor;\n        style.borderWidth = '1px';\n    }\n    if (props.bgColor) {\n        style.backgroundColor = props.bgColor;\n    }\n    return style;\n});\n\n/**\n * 倒计时数字的样式\n */\nconst letterStyle = computed(() => {\n    const style: Record<string, string> = {};\n    if (props.fontSize) style.fontSize = props.fontSize + 'rpx';\n    if (props.color) style.color = props.color;\n    return style;\n});\n\n// 监听时间戳的变化\nwatch(\n    () => props.timestamp,\n    (newVal, oldVal) => {\n        // 如果倒计时间发生变化，清除定时器，重新开始倒计时\n        clearTimer();\n        start();\n    }\n);\n\nonMounted(() => {\n    // 如果自动倒计时\n    if (props.autoplay && props.timestamp) {\n        start();\n    }\n});\n\n/**\n * 倒计时\n */\nfunction start() {\n    // 避免可能出现的倒计时重叠情况\n    clearTimer();\n    if (Number(props.timestamp) <= 0) return;\n    seconds.value = Number(props.timestamp);\n    formatTime(seconds.value);\n    timer.value = setInterval(() => {\n        seconds.value--;\n        // 发出change事件\n        emit('change', seconds.value);\n        if (seconds.value < 0) {\n            end();\n            return;\n        }\n        formatTime(seconds.value);\n    }, 1000);\n}\n\n/**\n * 格式化时间\n */\nfunction formatTime(sec: number) {\n    // 小于等于0的话，结束倒计时\n    if (sec <= 0) end();\n    let dayNum = Math.floor(sec / (60 * 60 * 24));\n    let hourNum = Math.floor(sec / (60 * 60)) - dayNum * 24;\n    // showHour为需要显示的小时\n    let showHour: string;\n    // 判断是否显示“天”参数，如果不显示，将天部分的值，加入到小时中\n    // hour为给后面计算秒和分等用的(基于显示天的前提下计算)\n    if (props.showDays) {\n        showHour = hourNum < 10 ? '0' + hourNum : String(hourNum);\n    } else {\n        // 如果不显示天数，将“天”部分的时间折算到小时中去\n        // 如果小于10，在前面补上一个\"0\"\n        const hourTotal = Math.floor(sec / (60 * 60));\n        showHour = hourTotal < 10 ? '0' + hourTotal : String(hourTotal);\n    }\n    let minuteNum = Math.floor(sec / 60) - hourNum * 60 - dayNum * 24 * 60;\n    let secondNum = Math.floor(sec) - dayNum * 24 * 60 * 60 - hourNum * 60 * 60 - minuteNum * 60;\n    const minute = minuteNum < 10 ? '0' + minuteNum : String(minuteNum);\n    const second = secondNum < 10 ? '0' + secondNum : String(secondNum);\n    const day = dayNum < 10 ? '0' + dayNum : String(dayNum);\n    d.value = day;\n    h.value = showHour;\n    i.value = minute;\n    s.value = second;\n}\n\n/**\n * 停止倒计时\n */\nfunction end() {\n    clearTimer();\n    emit('end', {});\n}\n\n/**\n * 清除定时器\n */\nfunction clearTimer() {\n    if (timer.value) {\n        clearInterval(timer.value);\n        timer.value = null;\n    }\n}\n\ndefineExpose({\n    start,\n    end\n});\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n\n.u-countdown {\n    /* #ifndef APP-NVUE */\n    display: inline-flex;\n    /* #endif */\n    align-items: center;\n}\n\n.u-countdown-item {\n    @include vue-flex;\n    align-items: center;\n    justify-content: center;\n    padding: 2rpx;\n    border-radius: 6rpx;\n    white-space: nowrap;\n    transform: translateZ(0);\n}\n\n.u-countdown-time {\n    margin: 0;\n    padding: 0;\n    line-height: 1;\n}\n\n.u-countdown-colon {\n    @include vue-flex;\n    justify-content: center;\n    padding: 0 5rpx;\n    line-height: 1;\n    align-items: center;\n    padding-bottom: 4rpx;\n}\n\n.u-countdown-scale {\n    transform: scale(0.9);\n    transform-origin: center center;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-count-to/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\n/**\n * u-count-to 数字滚动 Props\n * @description 该组件一般用于需要滚动数字到某一个值的场景，目标要求是一个递增的值。\n */\nexport const CountToProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 开始的数值，默认从0增长到某一个数 */\n    startVal: { type: [Number, String] as PropType<number | string>, default: 0 },\n    /** 要滚动的目标数值，必须 */\n    endVal: { type: [Number, String] as PropType<number | string>, default: 0, required: true },\n    /** 滚动到目标数值的动画持续时间，单位为毫秒（ms） */\n    duration: { type: [Number, String] as PropType<number | string>, default: 2000 },\n    /** 设置数值后是否自动开始滚动 */\n    autoplay: { type: Boolean, default: true },\n    /** 要显示的小数位数 */\n    decimals: { type: [Number, String] as PropType<number | string>, default: 0 },\n    /** 是否在即将到达目标数值的时候，使用缓慢滚动的效果 */\n    useEasing: { type: Boolean, default: true },\n    /** 十进制分割符号 */\n    decimal: { type: [Number, String] as PropType<number | string>, default: '.' },\n    /** 字体颜色 */\n    color: { type: String, default: 'var(--u-main-color)' },\n    /** 字体大小 */\n    fontSize: { type: [Number, String] as PropType<number | string>, default: 50 },\n    /** 是否加粗字体 */\n    bold: { type: Boolean, default: false },\n    /** 千位分隔符，类似金额的分割(￥23,321.05中的\",\") */\n    separator: { type: String, default: '' }\n};\n\nexport type CountToProps = ExtractPropTypes<typeof CountToProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-count-to/u-count-to.vue",
    "content": "<template>\n    <view\n        class=\"u-count-num\"\n        :class=\"customClass\"\n        :style=\"\n            $u.toStyle(\n                {\n                    fontSize: props.fontSize + 'rpx',\n                    fontWeight: props.bold ? 'bold' : 'normal',\n                    color: props.color\n                },\n                customStyle\n            )\n        \"\n    >\n        {{ displayValue }}\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-count-to',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, onMounted, onUnmounted } from 'vue';\nimport { CountToProps } from './types';\nimport { $u } from '../../';\n\n/**\n * countTo 数字滚动\n * @description 该组件一般用于需要滚动数字到某一个值的场景，目标要求是一个递增的值。\n * @tutorial https://uviewpro.cn/zh/components/countTo.html\n * @property {String | Number} start-val 开始值\n * @property {String | Number} end-val 结束值\n * @property {String | Number} duration 滚动过程所需的时间，单位ms（默认2000）\n * @property {Boolean} autoplay 是否自动开始滚动（默认true）\n * @property {String | Number} decimals 要显示的小数位数，见官网说明（默认0）\n * @property {Boolean} use-easing 滚动结束时，是否缓动结尾，见官网说明（默认true）\n * @property {String} separator 千位分隔符，见官网说明\n * @property {String} color 字体颜色（默认var(--u-main-color)）\n * @property {String | Number} font-size 字体大小，单位rpx（默认50）\n * @property {Boolean} bold 字体是否加粗（默认false）\n * @event {Function} end 数值滚动到目标值时触发\n * @example <u-count-to ref=\"uCountTo\" :end-val=\"endVal\" :autoplay=\"autoplay\"></u-count-to>\n */\n\nconst emit = defineEmits(['end']);\n\nconst props = defineProps(CountToProps);\n\nconst localStartVal = ref(Number(props.startVal));\nconst displayValue = ref(formatNumber(props.startVal));\nconst printVal = ref<number | null>(null);\nconst paused = ref(false); // 是否暂停\nconst localDuration = ref(Number(props.duration));\nconst startTime = ref<number | null>(null); // 开始的时间\nconst timestamp = ref<number | null>(null); // 时间戳\nconst remaining = ref<number | null>(null); // 停留的时间\nconst rAF = ref<number | null>(null);\nconst lastTime = ref(0); // 上一次的时间\n\n/**\n * 是否倒计时\n */\nconst countDown = computed(() => Number(props.startVal) > Number(props.endVal));\n\nwatch(\n    () => props.startVal,\n    () => {\n        if (props.autoplay) start();\n    }\n);\nwatch(\n    () => props.endVal,\n    () => {\n        if (props.autoplay) start();\n    }\n);\n\nonMounted(() => {\n    if (props.autoplay) start();\n});\n\n/**\n * 缓动函数\n */\nfunction easingFn(t: number, b: number, c: number, d: number): number {\n    return (c * (-Math.pow(2, (-10 * t) / d) + 1) * 1024) / 1023 + b;\n}\n\n/**\n * requestAnimationFrame polyfill\n */\nfunction requestAnimationFrame(callback: (ts: number) => void): number {\n    const currTime = new Date().getTime();\n    // 为了使setTimteout的尽可能的接近每秒60帧的效果\n    const timeToCall = Math.max(0, 16 - (currTime - lastTime.value));\n    const id = setTimeout(() => {\n        callback(currTime + timeToCall);\n    }, timeToCall);\n    lastTime.value = currTime + timeToCall;\n    return id as unknown as number;\n}\n\n/**\n * 取消动画帧\n */\nfunction cancelAnimationFrame(id: number | null) {\n    if (id) clearTimeout(id);\n}\n\n/**\n * 开始滚动数字\n */\nfunction start() {\n    localStartVal.value = Number(props.startVal);\n    startTime.value = null;\n    localDuration.value = Number(props.duration);\n    paused.value = false;\n    rAF.value = requestAnimationFrame(count);\n}\n\n/**\n * 暂停/恢复滚动\n * 暂定状态，重新再开始滚动；或者滚动状态下，暂停\n */\nfunction reStart() {\n    if (paused.value) {\n        resume();\n        paused.value = false;\n    } else {\n        stop();\n        paused.value = true;\n    }\n}\n\n/**\n * 暂停\n */\nfunction stop() {\n    cancelAnimationFrame(rAF.value);\n}\n\n/**\n * 重新开始(暂停的情况下)\n */\nfunction resume() {\n    startTime.value = null;\n    localDuration.value = remaining.value || Number(props.duration);\n    localStartVal.value = printVal.value || Number(props.startVal);\n    rAF.value = requestAnimationFrame(count);\n}\n\n/**\n * 重置\n */\nfunction reset() {\n    startTime.value = null;\n    cancelAnimationFrame(rAF.value);\n    displayValue.value = formatNumber(props.startVal);\n}\n\n/**\n * 数字滚动动画主逻辑\n */\nfunction count(ts: number) {\n    if (!startTime.value) startTime.value = ts;\n    timestamp.value = ts;\n    const progress = ts - (startTime.value || 0);\n    remaining.value = localDuration.value - progress;\n    let val: number;\n    if (props.useEasing) {\n        if (countDown.value) {\n            val =\n                localStartVal.value -\n                easingFn(progress, 0, localStartVal.value - Number(props.endVal), localDuration.value);\n        } else {\n            val = easingFn(\n                progress,\n                localStartVal.value,\n                Number(props.endVal) - localStartVal.value,\n                localDuration.value\n            );\n        }\n    } else {\n        if (countDown.value) {\n            val = localStartVal.value - (localStartVal.value - Number(props.endVal)) * (progress / localDuration.value);\n        } else {\n            val = localStartVal.value + (Number(props.endVal) - localStartVal.value) * (progress / localDuration.value);\n        }\n    }\n    if (countDown.value) {\n        val = val < Number(props.endVal) ? Number(props.endVal) : val;\n    } else {\n        val = val > Number(props.endVal) ? Number(props.endVal) : val;\n    }\n    printVal.value = val;\n    displayValue.value = formatNumber(val);\n    if (progress < localDuration.value) {\n        rAF.value = requestAnimationFrame(count);\n    } else {\n        emit('end');\n    }\n}\n\n/**\n * 判断是否数字\n */\nfunction isNumber(val: unknown): boolean {\n    return !isNaN(parseFloat(String(val)));\n}\n\n/**\n * 格式化数字\n */\nfunction formatNumber(num: unknown): string {\n    // 将num转为Number类型，因为其值可能为字符串数值，调用toFixed会报错\n    let n = Number(num);\n    n = Number(n.toFixed(Number(props.decimals)));\n    let str = n + '';\n    const x = str.split('.');\n    let x1 = x[0];\n    const x2 = x.length > 1 ? String(props.decimal) + x[1] : '';\n    const rgx = /(\\d+)(\\d{3})/;\n    if (props.separator && !isNumber(props.separator)) {\n        while (rgx.test(x1)) {\n            x1 = x1.replace(rgx, '$1' + props.separator + '$2');\n        }\n    }\n    return x1 + x2;\n}\n\n// 销毁时清理动画帧\nonUnmounted(() => {\n    cancelAnimationFrame(rAF.value);\n});\n\n// 暴露给父组件的函数\ndefineExpose({\n    start,\n    stop,\n    reStart,\n    resume,\n    reset\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-count-num {\n    /* #ifndef APP-NVUE */\n    display: inline-flex;\n    /* #endif */\n    text-align: center;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-divider/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { ThemeType } from '../../types/global';\n\n/**\n * u-divider 分割线 Props\n * @description 区隔内容的分割线，一般用于页面底部\"没有更多\"的提示。\n */\nexport const DividerProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 单一边divider横线的宽度(数值)，单位rpx。或者百分比 */\n    halfWidth: { type: [Number, String] as PropType<number | string>, default: 150 },\n    /** divider横线的颜色，如设置 */\n    borderColor: { type: String, default: 'var(--u-border-color)' },\n    /** 主题色，可以是primary|info|success|warning|error之一值 */\n    type: { type: String as PropType<ThemeType>, default: 'primary' },\n    /** 文字颜色 */\n    color: { type: String, default: 'var(--u-tips-color)' },\n    /** 文字大小，单位rpx */\n    fontSize: { type: [Number, String] as PropType<number | string>, default: 26 },\n    /** 整个divider的背景颜色 */\n    bgColor: { type: String, default: 'var(--u-bg-white)' },\n    /** 整个divider的高度单位rpx */\n    height: { type: [Number, String] as PropType<number | string>, default: 'auto' },\n    /** 上边距 */\n    marginTop: { type: [String, Number] as PropType<string | number>, default: 0 },\n    /** 下边距 */\n    marginBottom: { type: [String, Number] as PropType<string | number>, default: 0 },\n    /** 是否使用slot传入内容，如果不用slot传入内容，先的中间就不会有空隙 */\n    useSlot: { type: Boolean, default: true }\n};\n\nexport type DividerProps = ExtractPropTypes<typeof DividerProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-divider/u-divider.vue",
    "content": "<template>\n    <view\n        class=\"u-divider\"\n        :class=\"customClass\"\n        :style=\"\n            $u.toStyle(\n                {\n                    height: height === 'auto' ? 'auto' : height + 'rpx',\n                    backgroundColor: bgColor,\n                    marginBottom: marginBottom + 'rpx',\n                    marginTop: marginTop + 'rpx'\n                },\n                customStyle\n            )\n        \"\n        @tap=\"onClick\"\n    >\n        <view\n            class=\"u-divider-line\"\n            :class=\"[type ? 'u-divider-line--bordercolor--' + type : '']\"\n            :style=\"lineStyle\"\n        ></view>\n        <view\n            v-if=\"useSlot\"\n            class=\"u-divider-text\"\n            :style=\"{\n                color: color,\n                fontSize: fontSize + 'rpx'\n            }\"\n        >\n            <slot />\n        </view>\n        <view\n            class=\"u-divider-line\"\n            :class=\"[type ? 'u-divider-line--bordercolor--' + type : '']\"\n            :style=\"lineStyle\"\n        ></view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-divider',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { DividerProps } from './types';\nimport { $u } from '../../';\n\n/**\n * divider 分割线\n * @description 区隔内容的分割线，一般用于页面底部\"没有更多\"的提示。\n * @tutorial https://uviewpro.cn/zh/components/divider.html\n * @property {String Number} half-width 文字左或右边线条宽度，数值或百分比，数值时单位为rpx\n * @property {String} border-color 线条颜色，优先级高于type（默认var(--u-border-color)）\n * @property {String} color 文字颜色（默认var(--u-tips-color)）\n * @property {String Number} fontSize 字体大小，单位rpx（默认26）\n * @property {String} bg-color 整个divider的背景颜色（默认呢var(--u-bg-white)）\n * @property {String Number} height 整个divider的高度，单位rpx（默认40）\n * @property {String} type 将线条设置主题色（默认primary）\n * @property {Boolean} useSlot 是否使用slot传入内容，如果不传入，中间不会有空隙（默认true）\n * @property {String Number} margin-top 与前一个组件的距离，单位rpx（默认0）\n * @property {String Number} margin-bottom 与后一个组件的距离，单位rpx（0）\n * @event {Function} click divider组件被点击时触发\n * @example <u-divider color=\"var(--u-type-error)\">长河落日圆</u-divider>\n */\nconst props = defineProps(DividerProps);\n\nconst emit = defineEmits(['click']);\n\n/**\n * divider横线样式\n */\nconst lineStyle = computed(() => {\n    let style: Record<string, string> = {};\n    if (String(props.halfWidth).indexOf('%') !== -1) style.width = String(props.halfWidth);\n    else style.width = props.halfWidth + 'rpx';\n    // borderColor优先级高于type值\n    if (props.borderColor) style.borderColor = props.borderColor;\n    return style;\n});\n\n/**\n * divider组件被点击时触发\n */\nfunction onClick() {\n    emit('click');\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n.u-divider {\n    width: 100%;\n    position: relative;\n    text-align: center;\n    @include vue-flex;\n    justify-content: center;\n    align-items: center;\n    overflow: hidden;\n    flex-direction: row;\n}\n\n.u-divider-line {\n    border-bottom: 1px solid $u-border-color;\n    transform: scale(1, 0.5);\n    transform-origin: center;\n\n    &--bordercolor--primary {\n        border-color: $u-type-primary;\n    }\n\n    &--bordercolor--success {\n        border-color: $u-type-success;\n    }\n\n    &--bordercolor--error {\n        border-color: $u-type-primary;\n    }\n\n    &--bordercolor--info {\n        border-color: $u-type-info;\n    }\n\n    &--bordercolor--warning {\n        border-color: $u-type-warning;\n    }\n}\n\n.u-divider-text {\n    white-space: nowrap;\n    padding: 0 16rpx;\n    /* #ifndef APP-NVUE */\n    display: inline-flex;\n    /* #endif */\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-dropdown/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport { getColor } from '../../';\n\n/**\n * u-dropdown 下拉菜单 Props\n * @description 该组件一般用于向下展开菜单，同时可切换多个选项卡的场景\n */\nexport const DropdownProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 菜单标题和选项的激活态颜色 */\n    activeColor: { type: String, default: () => getColor('primary') },\n    /** 菜单标题和选项的未激活态颜色 */\n    inactiveColor: { type: String, default: () => getColor('contentColor') },\n    /** 点击遮罩是否关闭菜单 */\n    closeOnClickMask: { type: Boolean, default: true },\n    /** 点击当前激活项标题是否关闭菜单 */\n    closeOnClickSelf: { type: Boolean, default: true },\n    /** 过渡时间 */\n    duration: { type: [Number, String] as PropType<number | string>, default: 300 },\n    /** 标题菜单的高度，单位任意，数值默认为rpx单位 */\n    height: { type: [Number, String] as PropType<number | string>, default: 80 },\n    /** 是否显示下边框 */\n    borderBottom: { type: Boolean, default: false },\n    /** 标题的字体大小 */\n    titleSize: { type: [Number, String] as PropType<number | string>, default: 28 },\n    /** 下拉出来的内容部分的圆角值 */\n    borderRadius: { type: [Number, String] as PropType<number | string>, default: 0 },\n    /** 菜单右侧的icon图标 */\n    menuIcon: { type: String, default: 'arrow-down' },\n    /** 菜单右侧图标的大小 */\n    menuIconSize: { type: [Number, String] as PropType<number | string>, default: 26 }\n};\n\nexport type DropdownProps = ExtractPropTypes<typeof DropdownProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-dropdown/u-dropdown.vue",
    "content": "<template>\n    <view class=\"u-dropdown\" :style=\"$u.toStyle(styles, customStyle)\" :class=\"customClass\">\n        <view\n            class=\"u-dropdown__menu\"\n            :style=\"{ height: $u.addUnit(height) }\"\n            :class=\"{ 'u-border-bottom': borderBottom }\"\n        >\n            <view\n                class=\"u-dropdown__menu__item\"\n                v-for=\"(item, index) in menuList\"\n                :key=\"index\"\n                @tap.stop=\"menuClick(index)\"\n            >\n                <view class=\"u-flex\">\n                    <text\n                        class=\"u-dropdown__menu__item__text\"\n                        :style=\"{\n                            color: item.disabled\n                                ? 'var(--u-light-color)'\n                                : index === current || highlightIndex == index\n                                  ? activeColor\n                                  : inactiveColor,\n                            fontSize: $u.addUnit(titleSize)\n                        }\"\n                        >{{ item.title }}</text\n                    >\n                    <view\n                        class=\"u-dropdown__menu__item__arrow\"\n                        :class=\"{\n                            'u-dropdown__menu__item__arrow--rotate': index === current\n                        }\"\n                    >\n                        <u-icon\n                            :custom-style=\"{ display: 'flex' }\"\n                            :name=\"menuIcon\"\n                            :size=\"$u.addUnit(menuIconSize)\"\n                            :color=\"index === current || highlightIndex == index ? activeColor : 'var(--u-light-color)'\"\n                        ></u-icon>\n                    </view>\n                </view>\n            </view>\n        </view>\n        <view\n            class=\"u-dropdown__content\"\n            :style=\"[\n                contentStyle,\n                {\n                    transition: `opacity ${Number(duration) / 1000}s linear`,\n                    top: $u.addUnit(height),\n                    height: contentHeight + 'px'\n                }\n            ]\"\n            @tap=\"maskClick\"\n            @touchmove.stop.prevent\n        >\n            <view @tap.stop.prevent class=\"u-dropdown__content__popup\" :style=\"[popupStyle]\">\n                <slot></slot>\n            </view>\n            <view class=\"u-dropdown__content__mask\"></view>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-dropdown',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted, getCurrentInstance, nextTick } from 'vue';\nimport { $u, useParent } from '../..';\nimport { DropdownProps } from './types';\n\n/**\n * dropdown 下拉菜单\n * @description 该组件一般用于向下展开菜单，同时可切换多个选项卡的场景\n * @tutorial https://uviewpro.cn/zh/components/dropdown.html\n * @property {String} active-color 标题和选项卡选中的颜色（默认主题色primary）\n * @property {String} inactive-color 标题和选项卡未选中的颜色（默认var(--u-content-color)）\n * @property {Boolean} close-on-click-mask 点击遮罩是否关闭菜单（默认true）\n * @property {Boolean} close-on-click-self 点击当前激活项标题是否关闭菜单（默认true）\n * @property {String | Number} duration 选项卡展开和收起的过渡时间，单位ms（默认300）\n * @property {String | Number} height 标题菜单的高度，单位任意（默认80）\n * @property {String | Number} border-radius 菜单展开内容下方的圆角值，单位任意（默认0）\n * @property {Boolean} border-bottom 标题菜单是否显示下边框（默认false）\n * @property {String | Number} title-size 标题的字体大小，单位任意，数值默认为rpx单位（默认28）\n * @event {Function} open 下拉菜单被打开时触发\n * @event {Function} close 下拉菜单被关闭时触发\n * @example <u-dropdown></u-dropdown>\n */\n\nconst props = defineProps(DropdownProps);\nconst emit = defineEmits(['open', 'close']);\n\nconst { children } = useParent('u-dropdown');\n// 菜单列表\nconst menuList = ref<any[]>([]);\n// 下拉菜单的状态\nconst active = ref(false);\n// 当前激活菜单索引\n// 当前是第几个菜单处于激活状态，小程序中此处不能写成false或者\"\"，否则后续将current赋值为0，\n// 无能的TX没有使用===而是使用==判断，导致程序认为前后二者没有变化，从而不会触发视图更新\nconst current = ref<number>(99999);\n// 外层内容样式\nconst contentStyle = ref<any>({ zIndex: -1, opacity: 0 });\n// 高亮菜单索引\nconst highlightIndex = ref<number>(99999);\n// 下拉内容高度\nconst contentHeight = ref<number>(0);\n// 子组件引用\nconst instance = getCurrentInstance();\n// 兼容头条样式\nconst styles = computed(() => {\n    const style: any = {};\n    // #ifdef MP-TOUTIAO\n    style.width = '100vw';\n    // #endif\n    return style;\n});\n\n// 下拉出来部分的样式\nconst popupStyle = computed<any>(() => {\n    const style: any = {};\n    // 进行Y轴位移，展开状态时，恢复原位。收齐状态时，往上位移100%，进行隐藏\n    style.transform = `translateY(${active.value ? 0 : '-100%'})`;\n    style['transition-duration'] = Number(props.duration) / 1000 + 's';\n    style.borderRadius = `0 0 ${$u.addUnit(props.borderRadius)} ${$u.addUnit(props.borderRadius)}`;\n    return style;\n});\n\n// 生命周期\nonMounted(() => {\n    getContentHeight();\n});\n\n/**\n * 初始化所有子组件\n * 当某个子组件内容变化时，触发父组件的init，父组件再让每一个子组件重新初始化一遍\n * 以保证数据的正确性\n */\nfunction init() {\n    menuList.value = [];\n    children.forEach(child => {\n        // 过滤不显示的项\n        const show = child?.getExposed()?.props.show !== false;\n        if (!show) return;\n\n        menuList.value.push({\n            title: child?.getExposed()?.props.title ?? '',\n            disabled: child?.getExposed()?.props.disabled ?? false,\n            childIndex: children.indexOf(child)\n        });\n    });\n}\n\n/**\n * 点击菜单\n * @param index 菜单索引\n */\nfunction menuClick(index: number) {\n    // 判断是否被禁用\n    if (menuList.value[index]?.disabled) return;\n    // 如果点击时的索引和当前激活项索引相同，意味着点击了激活项，需要收起下拉菜单\n    if (index === current.value && props.closeOnClickSelf) {\n        close();\n        // 等动画结束后，再移除下拉菜单中的内容，否则直接移除，也就没有下拉菜单收起的效果了\n        const childIndex = menuList.value[index]?.childIndex; //避免访问到show为false的项\n        setTimeout(() => {\n            if (childIndex !== undefined && children[childIndex]) {\n                children[childIndex]?.getExposed()?.setActive(false);\n            }\n        }, Number(props.duration));\n        return;\n    }\n    open(index);\n}\n\n/**\n * 打开下拉菜单\n * @param index 菜单索引\n */\nfunction open(index: number) {\n    // 嵌套popup使用时可能获取不到正确的高度，重新计算\n    if (contentHeight.value < 1) getContentHeight();\n    // 重置高亮索引，否则会造成多个菜单同时高亮\n    // highlightIndex.value = 9999;\n    // 展开时，设置下拉内容的样式\n    contentStyle.value = { zIndex: 11 };\n    // 标记展开状态以及当前展开项的索引\n    active.value = true;\n    current.value = index;\n    // 历遍所有的子元素，将索引匹配的项标记为激活状态，因为子元素是通过v-if控制切换的\n    // 之所以不是因display: none，是因为nvue没有display这个属性\n    const childIndex = menuList.value[index]?.childIndex; //避免访问到show为false的项\n    children.forEach((child, idx) => {\n        child?.getExposed()?.setActive(childIndex === idx ? true : false);\n    });\n    emit('open', current.value);\n}\n\n/**\n * 设置下拉菜单处于收起状态\n */\nfunction close() {\n    emit('close', current.value);\n    // 设置为收起状态，同时current归位，设置为空字符串\n    active.value = false;\n    current.value = 99999;\n    // 下拉内容的样式进行调整，不透明度设置为0\n    contentStyle.value = { zIndex: -1, opacity: 0 };\n}\n\n/**\n * 点击遮罩\n */\nfunction maskClick() {\n    // 如果不允许点击遮罩，直接返回\n    if (!props.closeOnClickMask) return;\n    close();\n}\n\n/**\n * 外部手动设置某个菜单高亮\n * @param index 菜单索引\n */\nfunction highlight(index?: number) {\n    highlightIndex.value = index !== undefined ? index : 99999;\n}\n\n/**\n * 获取下拉菜单内容的高度\n * 这里的原理为，因为dropdown组件是相对定位的，它的下拉出来的内容，必须给定一个高度\n * 才能让遮罩占满菜单一下，直到屏幕底部的高度\n * this.$u.sys()为uView封装的获取设备信息的方法\n */\nfunction getContentHeight() {\n    const windowHeight = $u.sys().windowHeight;\n\n    $u.getRect('.u-dropdown__menu', instance).then((res: any) => {\n        // 这里获取的是dropdown的尺寸，在H5上，uniapp获取尺寸是有bug的(以前提出修复过，后来又出现了此bug，目前hx2.8.11版本)\n        // H5端bug表现为元素尺寸的top值为导航栏底部到到元素的上边沿的距离，但是元素的bottom值确是导航栏顶部到元素底部的距离\n        // 二者是互相矛盾的，本质原因是H5端导航栏非原生，uni的开发者大意造成\n        // 这里取菜单栏的botton值合理的，不能用res.top，否则页面会造成滚动\n        contentHeight.value = windowHeight - res.bottom;\n    });\n}\n\nonMounted(() => {\n    nextTick(() => {\n        init();\n    });\n});\n\n// 暴露方法\ndefineExpose({\n    props,\n    init,\n    close,\n    open,\n    highlight,\n    getContentHeight,\n    children,\n    menuList\n});\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n\n.u-dropdown {\n    flex: 1;\n    width: 100%;\n    position: relative;\n\n    &__menu {\n        @include vue-flex;\n        position: relative;\n        z-index: 11;\n        height: 80rpx;\n\n        &__item {\n            flex: 1;\n            @include vue-flex;\n            justify-content: center;\n            align-items: center;\n\n            &__text {\n                font-size: 28rpx;\n                color: $u-content-color;\n            }\n\n            &__arrow {\n                margin-left: 6rpx;\n                transition: transform 0.3s;\n                align-items: center;\n                @include vue-flex;\n\n                &--rotate {\n                    transform: rotate(180deg);\n                }\n            }\n        }\n    }\n\n    &__content {\n        position: absolute;\n        z-index: 8;\n        width: 100%;\n        left: 0px;\n        bottom: 0;\n        overflow: hidden;\n\n        &__mask {\n            position: absolute;\n            z-index: 9;\n            background: rgba(0, 0, 0, 0.3);\n            width: 100%;\n            left: 0;\n            top: 0;\n            bottom: 0;\n        }\n\n        &__popup {\n            position: relative;\n            z-index: 10;\n            transition: all 0.3s;\n            transform: translate3D(0, -100%, 0);\n            overflow: hidden;\n        }\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-dropdown-item/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { OptionType } from '../../types/global';\n\n/**\n * u-dropdown-item 下拉菜单项 Props\n * @description 该组件一般用于向下展开菜单，同时可切换多个选项卡的场景\n * @property {String|Number|Array} modelValue 双向绑定选项卡选择值\n * @property {String|Number} title 菜单项标题\n * @property {OptionType[]} options 选项数据，如果传入了默认slot，此参数无效\n * @property {Boolean} disabled 是否禁用此选项卡（默认false）\n * @property {String|Number} height 弹窗下拉内容的高度(内容超出将会滚动)（默认auto）\n * @property {Boolean} show 控制是否显示菜单项（默认true）\n */\n\nexport const DropdownItemProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 当前选中项的value值 */\n    modelValue: { type: [Number, String, Array] as PropType<number | string | any[]>, default: '' },\n    /** 菜单项标题 */\n    title: { type: [String, Number] as PropType<string | number>, default: '' },\n    /** 选项数据，如果传入了默认slot，此参数无效 */\n    options: { type: Array as PropType<OptionType[]>, default: () => [] },\n    /** 是否禁用此菜单项 */\n    disabled: { type: Boolean, default: false },\n    /** 下拉弹窗的高度 */\n    height: { type: [Number, String] as PropType<number | string>, default: 'auto' },\n    /** 控制是否显示菜单项 */\n    show: { type: Boolean, default: true }\n};\n\nexport type DropdownItemProps = ExtractPropTypes<typeof DropdownItemProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-dropdown-item/u-dropdown-item.vue",
    "content": "<template>\n    <view\n        v-if=\"show && active\"\n        class=\"u-dropdown-item\"\n        :class=\"customClass\"\n        :style=\"$u.toStyle(customStyle)\"\n        @touchmove.stop.prevent\n        @tap.stop.prevent\n    >\n        <block v-if=\"!slots.default && !slots.$default\">\n            <scroll-view :scroll-y=\"true\" :style=\"{ height: $u.addUnit(String(height)) }\">\n                <view class=\"u-dropdown-item__options\">\n                    <u-cell-group>\n                        <u-cell-item\n                            @click=\"cellClick(item.value)\"\n                            :arrow=\"false\"\n                            :title=\"item.label\"\n                            v-for=\"(item, index) in options\"\n                            :key=\"index\"\n                            :title-style=\"{ color: modelValue == item.value ? activeColor : inactiveColor }\"\n                        >\n                            <u-icon\n                                v-if=\"modelValue == item.value\"\n                                name=\"checkbox-mark\"\n                                :color=\"activeColor\"\n                                size=\"32\"\n                            ></u-icon>\n                        </u-cell-item>\n                    </u-cell-group>\n                </view>\n            </scroll-view>\n        </block>\n        <slot v-else />\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-dropdown-item',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, useSlots, watch } from 'vue';\nimport { $u, useChildren } from '../..';\nimport { DropdownItemProps } from './types';\n\n/**\n * dropdown-item 下拉菜单\n * @description 该组件一般用于向下展开菜单，同时可切换多个选项卡的场景\n * @tutorial https://uviewpro.cn/zh/components/dropdown.html\n * @property {String | Number} v-model 双向绑定选项卡选择值\n * @property {String} title 菜单项标题\n * @property {Array[Object]} options 选项数据，如果传入了默认slot，此参数无效\n * @property {Boolean} disabled 是否禁用此选项卡（默认false）\n * @property {String | Number} duration 选项卡展开和收起的过渡时间，单位ms（默认300）\n * @property {String | Number} height 弹窗下拉内容的高度(内容超出将会滚动)（默认auto）\n * @property {Boolean} show 控制是否显示菜单项（默认true）\n * @example <u-dropdown-item title=\"标题\"></u-dropdown-item>\n */\n\n// props 定义\nconst props = defineProps(DropdownItemProps);\n\n// emits 定义\nconst emit = defineEmits(['update:modelValue', 'change']);\n\n// 插槽\nconst slots = useSlots();\n\nconst { parentExposed, emitToParent } = useChildren('u-dropdown-item', 'u-dropdown');\n\n// 当前项是否处于展开状态\nconst active = ref(false);\n// 激活时左边文字和右边对勾图标的颜色\nconst activeColor = computed(() => parentExposed.value?.props?.activeColor || $u.color.primary);\n// 未激活时左边文字和右边对勾图标的颜色\nconst inactiveColor = computed(() => parentExposed.value?.props?.inactiveColor || $u.color.contentColor);\n\n// 监听props变化，通知父组件重新初始化\nconst propsChange = computed(() => `${props.title}-${props.disabled}-${props.show}`);\n\n// 监听propsChange变化，通知父组件重新init\nwatch(propsChange, () => {\n    emitToParent('init');\n});\n\n/**\n * cell被点击\n * @param value 选中值\n */\nfunction cellClick(value: string | number | any) {\n    // 修改通过v-model绑定的值\n    emit('update:modelValue', value);\n    // 通知父组件(u-dropdown)收起菜单\n    emitToParent('close');\n    // 发出事件，抛出当前勾选项的value\n    emit('change', value);\n}\n\nfunction setActive(value: boolean) {\n    active.value = value;\n}\n\ndefineExpose({\n    cellClick,\n    setActive,\n    props\n});\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-empty/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\n/**\n * u-empty 组件 Props 类型定义\n */\nexport const EmptyProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 图标路径 */\n    src: { type: String, default: '' },\n    /** 提示文字 */\n    text: { type: String, default: '' },\n    /** 文字颜色 */\n    color: { type: String, default: 'var(--u-light-color)' },\n    /** 图标的颜色 */\n    iconColor: { type: String, default: 'var(--u-light-color)' },\n    /** 图标的大小 */\n    iconSize: { type: [String, Number] as PropType<string | number>, default: 120 },\n    /** 文字大小，单位rpx */\n    fontSize: { type: [String, Number] as PropType<string | number>, default: 26 },\n    /** 选择预置的图标类型 */\n    mode: { type: String, default: 'data' },\n    /** 图标宽度，单位rpx */\n    imgWidth: { type: [String, Number] as PropType<string | number>, default: 120 },\n    /** 图标高度，单位rpx */\n    imgHeight: { type: [String, Number] as PropType<string | number>, default: 'auto' },\n    /** 是否显示组件 */\n    show: { type: Boolean, default: true },\n    /** 组件距离上一个元素之间的距离 */\n    marginTop: { type: [String, Number] as PropType<string | number>, default: 0 },\n    /** 图标自定义样式 */\n    iconStyle: { type: Object as PropType<Record<string, any>>, default: () => ({}) }\n};\n\n/**\n * u-empty 组件 Props 类型\n */\nexport type EmptyProps = ExtractPropTypes<typeof EmptyProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-empty/u-empty.vue",
    "content": "<template>\n    <view\n        v-if=\"show\"\n        class=\"u-empty\"\n        :class=\"customClass\"\n        :style=\"$u.toStyle({ marginTop: marginTop + 'rpx' }, customStyle)\"\n    >\n        <u-icon\n            :name=\"src ? src : 'empty-' + mode\"\n            :custom-style=\"iconStyle\"\n            :label=\"text ? text : (icons as any)[mode]\"\n            label-pos=\"bottom\"\n            :label-color=\"color\"\n            :label-size=\"fontSize\"\n            :size=\"iconSize\"\n            :color=\"iconColor\"\n            margin-top=\"14\"\n        ></u-icon>\n        <view class=\"u-slot-wrap\">\n            <slot name=\"bottom\"></slot>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-empty',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { EmptyProps } from './types';\nimport { $u, useLocale } from '../../';\nimport { computed } from 'vue';\n\nconst { t } = useLocale();\n\n/**\n * empty 内容为空\n * @description 该组件用于需要加载内容，但是加载的第一页数据就为空，提示一个\"没有内容\"的场景， 我们精心挑选了十几个场景的图标，方便您使用。\n * @tutorial https://uviewpro.cn/zh/components/empty.html\n * @property {String} color 文字颜色（默认var(--u-light-color)）\n * @property {String} text 文字提示（默认“无内容”）\n * @property {String} src 自定义图标路径，如定义，mode参数会失效\n * @property {String Number} font-size 提示文字的大小，单位rpx（默认28）\n * @property {String} mode 内置的图标，见官网说明（默认data）\n * @property {String Number} img-width 图标的宽度，单位rpx（默认240）\n * @property {String} img-height 图标的高度，单位rpx（默认auto）\n * @property {String Number} margin-top 组件距离上一个元素之间的距离（默认0）\n * @property {Boolean} show 是否显示组件（默认true）\n * @event {Function} click 点击组件时触发\n * @event {Function} close 点击关闭按钮时触发\n * @example <u-empty text=\"所谓伊人，在水一方\" mode=\"list\"></u-empty>\n */\nconst props = defineProps(EmptyProps);\n\n/**\n * 预置图标对应的提示文字\n */\nconst icons = computed(() => {\n    return {\n        car: t('uEmpty.car'),\n        page: t('uEmpty.page'),\n        search: t('uEmpty.search'),\n        address: t('uEmpty.address'),\n        wifi: t('uEmpty.wifi'),\n        order: t('uEmpty.order'),\n        coupon: t('uEmpty.coupon'),\n        favor: t('uEmpty.favor'),\n        permission: t('uEmpty.permission'),\n        history: t('uEmpty.history'),\n        news: t('uEmpty.news'),\n        message: t('uEmpty.message'),\n        list: t('uEmpty.list'),\n        data: t('uEmpty.data')\n    };\n});\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n\n.u-empty {\n    @include vue-flex;\n    flex-direction: column;\n    justify-content: center;\n    align-items: center;\n    height: 100%;\n}\n\n.u-image {\n    margin-bottom: 20rpx;\n}\n\n.u-slot-wrap {\n    @include vue-flex;\n    justify-content: center;\n    align-items: center;\n    margin-top: 20rpx;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-fab/types.ts",
    "content": "import type { CSSProperties, ExtractPropTypes, PropType } from 'vue';\nimport type { FabDirection, FabGap, FabPosition, ThemeType } from '../../types/global';\n\n/**\n * fab 悬浮按钮类型定义\n * @description 供 u-fab 组件 props 使用\n */\n\nexport const FabProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 按钮的预置样式，primary，info，error，warning，success */\n    type: { type: String as PropType<ThemeType>, default: 'primary' },\n    /** 是否禁止状态 */\n    disabled: { type: Boolean, default: false },\n    /** 按钮能否可以拖动 */\n    draggable: { type: Boolean, default: false },\n    /** 按钮与边缘的间距，单位 px。支持 number 或对象 {top,left,right,bottom}，优先级按键存在顺序 */\n    gap: {\n        type: Object as PropType<FabGap>,\n        default: () => ({\n            top: 16,\n            left: 16,\n            right: 16,\n            bottom: 16\n        })\n    },\n    /** 拖动结束时是否自动吸边（仅当 draggable 为 true 时生效） */\n    autoStick: { type: Boolean, default: true },\n    /** 预设定位：控制组件默认停靠位置 */\n    position: {\n        type: String as PropType<FabPosition>,\n        default: 'right-bottom'\n    },\n    /** 菜单出现的方向 */\n    direction: { type: String as PropType<FabDirection>, default: 'top' },\n    /** 按钮自定义层级 */\n    zIndex: { type: Number, default: 99 }\n};\n\nexport type FabProps = ExtractPropTypes<typeof FabProps>;\n\ninterface DirectionConfig {\n    opposite: keyof CSSProperties;\n    sizeKey: 'width' | 'height';\n    positionKey: 'left' | 'top';\n    flexBase: 'row' | 'row-reverse' | 'column' | 'column-reverse';\n}\n\nexport const directionConfig: Record<FabDirection, DirectionConfig> = {\n    top: {\n        opposite: 'bottom',\n        sizeKey: 'width',\n        positionKey: 'left',\n        flexBase: 'column'\n    },\n    bottom: {\n        opposite: 'top',\n        sizeKey: 'width',\n        positionKey: 'left',\n        flexBase: 'column-reverse'\n    },\n    left: {\n        opposite: 'right',\n        sizeKey: 'height',\n        positionKey: 'top',\n        flexBase: 'row'\n    },\n    right: {\n        opposite: 'left',\n        sizeKey: 'height',\n        positionKey: 'top',\n        flexBase: 'row-reverse'\n    }\n};\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-fab/u-fab.vue",
    "content": "<template>\n    <view\n        class=\"u-fab\"\n        :style=\"$u.toStyle(fabStyle, customStyle)\"\n        :class=\"[customClass]\"\n        @touchstart=\"handleTouchstart\"\n        @touchmove.stop.prevent=\"handleTouchmove\"\n        @touchend=\"handleTouchend\"\n    >\n        <view class=\"u-fab-trigger\" id=\"trigger\">\n            <slot name=\"trigger\">\n                <u-button\n                    custom-class=\"u-fab-trigger-btn\"\n                    custom-style=\"width:112rpx;height:112rpx;border-radius:112rpx;\"\n                    :type=\"type\"\n                    :disabled=\"disabled\"\n                    :throttle-time=\"0\"\n                    @click=\"handleBtnClick\"\n                >\n                    <u-icon :name=\"expansion ? 'close' : 'plus'\" size=\"36rpx\"></u-icon>\n                </u-button>\n            </slot>\n        </view>\n        <view class=\"u-fab-actions\" id=\"actions\" :class=\"{ 'u-fab-actions__show': expansion }\" :style=\"actionsStyle\">\n            <slot></slot>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-fab',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { directionConfig, FabProps } from './types';\nimport { computed, getCurrentInstance, onMounted, reactive, ref, useSlots, watch } from 'vue';\nimport { $u } from '../../';\n\nconst props = defineProps(FabProps);\nconst emit = defineEmits(['trigger']);\n\nconst slots = useSlots();\nconst instance = getCurrentInstance();\nconst sysInfo = $u.sys();\nconst dragging = ref(true);\nconst minLeft = ref(0);\nconst maxLeft = ref(0);\nconst minTop = ref(0);\nconst maxTop = ref(0);\nconst expansion = ref(false);\nconst direction = ref(props.direction);\nconst effectiveWindowHeight = ref(sysInfo.windowHeight);\n// #ifdef H5\neffectiveWindowHeight.value = sysInfo.windowTop + sysInfo.windowHeight;\n// #endif\nconst position = reactive({\n    top: 0,\n    left: 0\n});\nconst actions = ref();\nconst btnInfo = ref({\n    width: 56,\n    height: 56\n});\nconst start = reactive({\n    x: 0,\n    y: 0\n});\n\n// 计算悬浮按钮样式\nconst fabStyle = computed(() => {\n    const style: Record<string, any> = {\n        transition: dragging.value ? 'none' : 'all 0.3s ease',\n        zIndex: props.zIndex,\n        left: `${position.left}px`,\n        top: `${position.top}px`\n    };\n    return style;\n});\n\n// 动画样式\nconst actionsStyle = computed(() => {\n    const config = directionConfig[direction.value];\n    const base: Record<string, any> = {\n        [config.opposite]: '100%',\n        [config.sizeKey]: '100%',\n        [config.positionKey]: 0,\n        flexDirection: config.flexBase,\n        transition: 'all 0.28s cubic-bezier(0.3, 0, 0.2, 1)'\n    };\n\n    // 展开/收缩动画：根据方向设置初始偏移\n    const offset = 12; // rpx/px 相对轻微偏移，视觉更顺滑\n    if (expansion.value) {\n        base.transform = 'translate3d(0,0,0) scale(1)';\n        base.opacity = 1;\n    } else {\n        // 隐藏时做一个方向上的微位移并缩放以优化动画感\n        if (direction.value === 'top') base.transform = `translate3d(0, ${offset}px, 0) scale(0.96)`;\n        else if (direction.value === 'bottom') base.transform = `translate3d(0, -${offset}px, 0) scale(0.96)`;\n        else if (direction.value === 'left') base.transform = `translate3d(${offset}px, 0, 0) scale(0.96)`;\n        else base.transform = `translate3d(-${offset}px, 0, 0) scale(0.96)`;\n        base.opacity = 0;\n    }\n\n    return base;\n});\n\nwatch(\n    () => [props.position, props.gap],\n    () => {\n        initPosition();\n    }\n);\n\nwatch(\n    () => props.direction,\n    () => {\n        if (expansion.value) direction.value = calcDirection();\n    }\n);\n\n// helper：支持 gap 为 number 或对象形式\nfunction getGap(side: 'top' | 'left' | 'right' | 'bottom') {\n    const g = props.gap as any;\n    if (typeof g === 'number') return g;\n    if (g && typeof g === 'object' && g[side] !== undefined) return Number(g[side]);\n    return 0;\n}\n\n// 拖动开始事件\nfunction handleTouchstart(e: TouchEvent) {\n    if (props.disabled || !props.draggable) return;\n\n    const touches = e.touches[0];\n    start.x = touches.clientX;\n    start.y = touches.clientY;\n    dragging.value = true;\n}\n\n// 拖动移动事件\nfunction handleTouchmove(e: TouchEvent) {\n    if (props.disabled || !props.draggable) return;\n\n    const touches = e.touches[0];\n    const deltaX = touches.clientX - start.x;\n    const deltaY = touches.clientY - start.y;\n\n    position.left += deltaX;\n    position.top += deltaY;\n\n    start.x = touches.clientX;\n    start.y = touches.clientY;\n\n    // 设置边界，防止拖出边界\n    position.left = Math.max(minLeft.value, Math.min(maxLeft.value, position.left));\n    position.top = Math.max(minTop.value, Math.min(maxTop.value, position.top));\n}\n\n// 拖动结束事件\nfunction handleTouchend() {\n    if (props.disabled || !props.draggable) return;\n\n    dragging.value = false;\n\n    // 如果 autoStick 为 false，则释放后不进行自动吸边，仅做边界限制\n    if (props.autoStick === false) {\n        position.left = Math.max(minLeft.value, Math.min(maxLeft.value, position.left));\n        position.top = Math.max(minTop.value, Math.min(maxTop.value, position.top));\n        return;\n    }\n\n    const middle = sysInfo.windowWidth / 2;\n    const buttonCenter = position.left + btnInfo.value.width / 2;\n\n    // 自动吸边，按钮中心位置大于视口的一半时，自动依附在右边，不然就是左边\n    position.left =\n        buttonCenter > middle ? sysInfo.windowWidth - btnInfo.value.width - getGap('right') : getGap('left');\n\n    if (expansion.value) direction.value = calcDirection();\n}\n\n// 按钮点击事件\nfunction handleBtnClick() {\n    if (slots?.default) {\n        expansion.value = !expansion.value;\n        if (expansion.value) direction.value = calcDirection();\n    } else {\n        emit('trigger');\n    }\n}\n\n// 计算方向\nfunction calcDirection() {\n    if (!actions.value) return props.direction;\n\n    let dir = props.direction;\n\n    const actionsHeight = actions.value?.height || 0;\n    const actionsWidth = actions.value?.width || 0;\n\n    // 菜单展开时，如果位置不够，则反转方向\n    if (dir === 'top') {\n        // 按钮上方剩余空间: 按钮顶部 - 顶部边距\n        if (position.top - minTop.value < actionsHeight) dir = 'bottom';\n    } else if (dir === 'bottom') {\n        // 按钮下方剩余空间: 有效窗口高度 - (按钮顶部 + 按钮高 + 边距)\n        const bottom = effectiveWindowHeight.value - (position.top + btnInfo.value.height + getGap('bottom'));\n        if (bottom < actionsHeight) dir = 'top';\n    } else if (dir === 'left') {\n        // 按钮左侧剩余空间: 有效窗口宽度 - 边距\n        if (position.left - getGap('left') < actionsWidth) dir = 'right';\n    } else if (dir === 'right') {\n        // 按钮右侧剩余空间: 有效窗口宽度 - (按钮左侧 + 按钮宽 + 边距)\n        const right = sysInfo.windowWidth - (position.left + btnInfo.value.width + getGap('right'));\n        if (right < actionsWidth) dir = 'left';\n    }\n\n    return dir;\n}\n\n// 初始化位置\nfunction initPosition() {\n    // 根据 props.position 计算初始 left/top\n    const pos = props.position || 'right-bottom';\n    const winW = sysInfo.windowWidth;\n    const winH = effectiveWindowHeight.value;\n\n    switch (pos) {\n        case 'left-top':\n            position.left = getGap('left');\n            position.top = getGap('top') + sysInfo.windowTop;\n            break;\n        case 'right-top':\n            position.left = winW - btnInfo.value.width - getGap('right');\n            position.top = getGap('top') + sysInfo.windowTop;\n            break;\n        case 'left-bottom':\n            position.left = getGap('left');\n            position.top = winH - btnInfo.value.height - getGap('bottom');\n            break;\n        case 'right-bottom':\n            position.left = winW - btnInfo.value.width - getGap('right');\n            position.top = winH - btnInfo.value.height - getGap('bottom');\n            break;\n        case 'left-center':\n            position.left = getGap('left');\n            position.top = Math.round((winH - btnInfo.value.height) / 2);\n            break;\n        case 'right-center':\n            position.left = winW - btnInfo.value.width - getGap('right');\n            position.top = Math.round((winH - btnInfo.value.height) / 2);\n            break;\n        case 'top-center':\n            position.left = Math.round((winW - btnInfo.value.width) / 2);\n            position.top = getGap('top') + sysInfo.windowTop;\n            break;\n        case 'bottom-center':\n            position.left = Math.round((winW - btnInfo.value.width) / 2);\n            position.top = winH - btnInfo.value.height - getGap('bottom');\n            break;\n        default:\n            position.left = winW - btnInfo.value.width - getGap('right');\n            position.top = winH - btnInfo.value.height - getGap('bottom');\n            break;\n    }\n}\n\nonMounted(async () => {\n    btnInfo.value = await $u.getRect('#trigger', instance);\n    actions.value = await $u.getRect('#actions', instance);\n\n    initPosition();\n\n    minLeft.value = getGap('left');\n    minTop.value = getGap('top') + sysInfo.windowTop;\n    maxLeft.value = sysInfo.windowWidth - btnInfo.value.width - getGap('right');\n    maxTop.value = effectiveWindowHeight.value - btnInfo.value.height - getGap('bottom');\n});\n\ndefineExpose({\n    toggle: handleBtnClick\n});\n</script>\n\n<style scoped lang=\"scss\">\n.u-fab {\n    position: fixed;\n\n    .u-fab-trigger {\n        :deep(.u-fab-trigger-btn) {\n            width: 112rpx;\n            height: 112rpx;\n            border-radius: 112rpx;\n\n            &::after {\n                border-radius: 112rpx;\n            }\n        }\n    }\n\n    .u-fab-actions {\n        position: absolute;\n        display: flex;\n        justify-content: center;\n        align-items: center;\n        visibility: hidden;\n        opacity: 0;\n        transform-origin: center;\n        will-change: transform, opacity;\n        transition: all 0.28s cubic-bezier(0.3, 0, 0.2, 1);\n\n        &.u-fab-actions__show {\n            visibility: visible;\n            opacity: 1;\n        }\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-field/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { InputAlign, InputConfirmType, InputLabelPosition, InputType } from '../../types/global';\n\n/**\n * u-field 组件 Props 类型定义\n * @description 表单输入框属性\n */\nexport const FieldProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** label左边的图标，限uView的图标名称 */\n    icon: { type: String, default: '' },\n    /** 输入框右边的图标名称，限uView的图标名称（默认false） */\n    rightIcon: { type: String, default: '' },\n    /** 方向属性 */\n    arrowDirection: { type: String, default: 'right' },\n    /** 是否必填，左边显示红色\"*\"号（默认false） */\n    required: { type: Boolean, default: false },\n    /** 输入框左边的文字提示 */\n    label: { type: String, default: '' },\n    /** 是否密码输入方式(用点替换文字)，type为text时有效（默认false） */\n    password: { type: Boolean, default: false },\n    /** 是否显示右侧清空内容的图标控件（默认true） */\n    clearable: { type: Boolean, default: true },\n    /** label的宽度，单位rpx（默认130） */\n    labelWidth: { type: [Number, String] as PropType<string | number>, default: 130 },\n    /** label的文字对齐方式（默认left） */\n    labelAlign: { type: String as PropType<InputAlign>, default: 'left' },\n    /** 输入框内容对齐方式（默认left） */\n    inputAlign: { type: String as PropType<InputAlign>, default: 'left' },\n    /** 左边通过icon配置的图标的颜色（默认var(--u-content-color)） */\n    iconColor: { type: String, default: 'var(--u-content-color)' },\n    /** 是否自动增高输入区域，type为textarea时有效（默认true） */\n    autoHeight: { type: Boolean, default: true },\n    /** 显示的错误提示内容，如果为空字符串或者false，则不显示错误信息 */\n    errorMessage: { type: [String, Boolean] as PropType<string | boolean>, default: '' },\n    /** 输入框的提示文字 */\n    placeholder: { type: String, default: '' },\n    /** placeholder的样式(内联样式，字符串)，如\"color: var(--u-divider-color)\" */\n    placeholderStyle: { type: String, default: '' },\n    /** 是否自动获得焦点（默认false） */\n    focus: { type: Boolean, default: false },\n    /** 如果type为textarea，且在一个\"position:fixed\"的区域，需要指明为true（默认false） */\n    fixed: { type: Boolean, default: false },\n    /** 输入框绑定值 */\n    modelValue: [Number, String],\n    /** 输入框类型（text/textarea/password等，默认text） */\n    type: { type: String as PropType<InputType>, default: 'text' },\n    /** 是否不可输入（默认false） */\n    disabled: { type: Boolean, default: false },\n    /** 最大输入长度，设置为 -1 的时候不限制最大长度（默认140） */\n    maxlength: { type: [Number, String] as PropType<string | number>, default: 140 },\n    /** 设置键盘右下角按钮的文字，仅在type=\"text\"时生效（默认done） */\n    confirmType: { type: String as PropType<InputConfirmType>, default: 'done' },\n    /** label位置（默认left）left-左边，top-上边 */\n    labelPosition: { type: String as PropType<InputLabelPosition>, default: 'left' },\n    /** 自定义输入框的样式，对象形式 */\n    fieldStyle: { type: Object as PropType<Record<string, any>>, default: () => ({}) },\n    /** 清除图标的大小，单位rpx（默认30） */\n    clearSize: { type: [Number, String] as PropType<string | number>, default: 30 },\n    /** 左侧图标样式 */\n    iconStyle: { type: Object as PropType<Record<string, any>>, default: () => ({}) },\n    /** 是否显示field的上边框（默认false） */\n    borderTop: { type: Boolean, default: false },\n    /** 是否显示field的下边框（默认true） */\n    borderBottom: { type: Boolean, default: true },\n    /** 是否自动去除输入内容首尾空格（默认true） */\n    trim: { type: Boolean, default: true }\n};\n\nexport type FieldProps = ExtractPropTypes<typeof FieldProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-field/u-field.vue",
    "content": "<template>\n    <view\n        class=\"u-field\"\n        :class=\"[{ 'u-border-top': props.borderTop, 'u-border-bottom': props.borderBottom }, customClass]\"\n        :style=\"$u.toStyle(customStyle)\"\n    >\n        <view\n            class=\"u-field-inner\"\n            :class=\"[props.type === 'textarea' ? 'u-textarea-inner' : '', 'u-label-postion-' + props.labelPosition]\"\n        >\n            <view\n                class=\"u-label\"\n                :class=\"[props.required ? 'u-required' : '']\"\n                :style=\"{\n                    justifyContent: justifyContent,\n                    flex: props.labelPosition === 'left' ? `0 0 ${props.labelWidth}rpx` : '1'\n                }\"\n            >\n                <view class=\"u-icon-wrap\" v-if=\"props.icon\">\n                    <u-icon\n                        size=\"32\"\n                        :custom-style=\"props.iconStyle\"\n                        :name=\"props.icon\"\n                        :color=\"props.iconColor\"\n                        class=\"u-icon\"\n                    ></u-icon>\n                </view>\n                <slot name=\"icon\"></slot>\n                <text class=\"u-label-text\" :class=\"[$slots.icon || props.icon ? 'u-label-left-gap' : '']\">\n                    {{ props.label }}\n                </text>\n            </view>\n            <view class=\"fild-body\">\n                <view class=\"u-flex-1 u-flex u-field-input-wrap\" :style=\"[inputWrapStyle]\">\n                    <textarea\n                        v-if=\"props.type === 'textarea'\"\n                        class=\"u-flex-1 u-textarea-class\"\n                        :style=\"$u.toStyle(props.fieldStyle)\"\n                        :value=\"inputValue\"\n                        :placeholder=\"String(props.placeholder)\"\n                        :placeholderStyle=\"props.placeholderStyle\"\n                        :disabled=\"props.disabled\"\n                        :maxlength=\"inputMaxlength\"\n                        :focus=\"props.focus\"\n                        :autoHeight=\"props.autoHeight\"\n                        :fixed=\"props.fixed\"\n                        @input=\"onInput\"\n                        @blur=\"onBlur\"\n                        @focus=\"onFocus\"\n                        @confirm=\"onConfirm\"\n                        @tap=\"fieldClick\"\n                    />\n                    <!-- prettier-ignore -->\n                    <input\n                        v-else\n                        class=\"u-flex-1 u-field__input-wrap\"\n                        :style=\"$u.toStyle(props.fieldStyle)\"\n                        :type=\"(props.type as any)\"\n                        :value=\"inputValue\"\n                        :password=\"props.password || props.type === 'password'\"\n                        :placeholder=\"String(props.placeholder)\"\n                        :placeholderStyle=\"props.placeholderStyle\"\n                        :disabled=\"props.disabled\"\n                        :maxlength=\"inputMaxlength\"\n                        :focus=\"props.focus\"\n                        :confirmType=\"props.confirmType\"\n                        @focus=\"onFocus\"\n                        @blur=\"onBlur\"\n                        @input=\"onInput\"\n                        @confirm=\"onConfirm\"\n                        @tap=\"fieldClick\"\n                    />\n                    <!-- 透明遮罩，只在disabled时显示，用于响应点击事件 -->\n                    <view v-if=\"props.disabled\" class=\"u-field-disabled-overlay\" @tap=\"fieldClick\"></view>\n                </view>\n                <u-icon\n                    v-if=\"props.clearable && inputValue !== '' && focused && !props.disabled\"\n                    :size=\"props.clearSize\"\n                    name=\"close-circle-fill\"\n                    color=\"var(--u-light-color)\"\n                    class=\"u-clear-icon\"\n                    @click=\"onClear\"\n                />\n                <view class=\"u-button-wrap\"><slot name=\"right\" /></view>\n                <u-icon\n                    v-if=\"props.rightIcon\"\n                    @click=\"rightIconClick\"\n                    :name=\"props.rightIcon\"\n                    color=\"var(--u-light-color)\"\n                    :style=\"[rightIconStyle]\"\n                    size=\"26\"\n                    class=\"u-arror-right\"\n                />\n            </view>\n        </view>\n        <view\n            v-if=\"props.errorMessage !== false && props.errorMessage != ''\"\n            class=\"u-error-message\"\n            :style=\"{\n                paddingLeft: props.labelWidth + 'rpx'\n            }\"\n            >{{ props.errorMessage }}</view\n        >\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-field',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { FieldProps } from './types';\nimport { ref, computed } from 'vue';\nimport { $u } from '../..';\n\n/**\n * field 输入框\n * @description 借助此组件，可以实现表单的输入， 有\"text\"和\"textarea\"类型的，此外，借助uView的picker和actionSheet组件可以快速实现上拉菜单，时间，地区选择等， 为表单解决方案的利器。\n * @tutorial https://uviewpro.cn/zh/components/field.html\n * @property {String} type 输入框的类型（默认text）\n * @property {String} icon label左边的图标，限uView的图标名称\n * @property {Object} icon-style 左边图标的样式，对象形式\n * @property {Boolean} right-icon 输入框右边的图标名称，限uView的图标名称（默认false）\n * @property {Boolean} required 是否必填，左侧显示红色\"*\"号（默认false）\n * @property {String} label 输入框左边的文字提示\n * @property {Boolean} password 是否密码输入方式(用点替换文字)，type为text时有效（默认false）\n * @property {Boolean} clearable 是否显示右侧清空内容的图标控件(输入框有内容，且获得焦点时才显示)，点击可清空输入框内容（默认true）\n * @property {Number | String} label-width label的宽度，单位rpx（默认130）\n * @property {String} label-align label的文字对齐方式（默认left）\n * @property {Object} field-style 自定义输入框的样式，对象形式\n * @property {Number | String} clear-size 清除图标的大小，单位rpx（默认30）\n * @property {String} input-align 输入框内容对齐方式（默认left）\n * @property {Boolean} border-bottom 是否显示field的下边框（默认true）\n * @property {Boolean} border-top 是否显示field的上边框（默认false）\n * @property {String} icon-color 左边通过icon配置的图标的颜色（默认var(--u-content-color)）\n * @property {Boolean} auto-height 是否自动增高输入区域，type为textarea时有效（默认true）\n * @property {String Boolean} error-message 显示的错误提示内容，如果为空字符串或者false，则不显示错误信息\n * @property {String} placeholder 输入框的提示文字\n * @property {String} placeholder-style placeholder的样式(内联样式，字符串)，如\"color: var(--u-divider-color)\"\n * @property {Boolean} focus 是否自动获得焦点（默认false）\n * @property {Boolean} fixed 如果type为textarea，且在一个\"position:fixed\"的区域，需要指明为true（默认false）\n * @property {Boolean} disabled 是否不可输入（默认false）\n * @property {Number String} maxlength 最大输入长度，设置为 -1 的时候不限制最大长度（默认140）\n * @property {String} confirm-type 设置键盘右下角按钮的文字，仅在type=\"text\"时生效（默认done）\n * @event {Function} input 输入框内容发生变化时触发\n * @event {Function} focus 输入框获得焦点时触发\n * @event {Function} blur 输入框失去焦点时触发\n * @event {Function} confirm 点击完成按钮时触发\n * @event {Function} right-icon-click 通过right-icon生成的图标被点击时触发\n * @event {Function} click 输入框被点击或者通过right-icon生成的图标被点击时触发，这样设计是考虑到传递右边的图标，一般都为需要弹出\"picker\"等操作时的场景，点击倒三角图标，理应发出此事件，见上方说明\n * @example <u-field v-model=\"mobile\" label=\"手机号\" required :error-message=\"errorMessage\"></u-field>\n */\n\nconst emit = defineEmits(['update:modelValue', 'input', 'focus', 'blur', 'confirm', 'right-icon-click', 'click']);\n\nconst props = defineProps(FieldProps);\n\nconst focused = ref(false);\n\nconst inputValue = computed<string>(() => {\n    if (props.modelValue === undefined || props.modelValue === null) return '';\n    return String(props.modelValue);\n});\n\nconst inputWrapStyle = computed(() => {\n    const style: Record<string, string> = {};\n    style.textAlign = props.inputAlign;\n    // 判断label的位置，如果是left的话，让input左边两边有间隙\n    if (props.labelPosition === 'left') {\n        style.margin = '0 8rpx';\n    } else {\n        // 如果label是top的，input的左边就没必要有间隙了\n        style.marginRight = '8rpx';\n    }\n    return style;\n});\n\nconst rightIconStyle = computed(() => {\n    const style: Record<string, string> = {};\n    // 方向属性已注释，保留原有逻辑\n    if (props.arrowDirection === 'top') style.transform = 'rotate(-90deg)';\n    if (props.arrowDirection === 'bottom') style.transform = 'rotate(90deg)';\n    else style.transform = 'rotate(0deg)';\n    return style;\n});\n\nconst labelStyle = computed(() => {\n    const style: Record<string, string> = {};\n    if (props.labelAlign === 'left') style.justifyContent = 'flex-start';\n    if (props.labelAlign === 'center') style.justifyContent = 'center';\n    if (props.labelAlign === 'right') style.justifyContent = 'flex-end';\n    return style;\n});\n\n// uni不支持在computed中写style.justifyContent = 'center'的形式，故用此方法\nconst justifyContent = computed(() => {\n    if (props.labelAlign === 'left') return 'flex-start';\n    if (props.labelAlign === 'center') return 'center';\n    if (props.labelAlign === 'right') return 'flex-end';\n    return 'flex-start';\n});\n\n// 因为uniapp的input组件的maxlength组件必须要数值，这里转为数值，给用户可以传入字符串数值\nconst inputMaxlength = computed(() => Number(props.maxlength));\n\n// label的位置\nconst fieldInnerStyle = computed(() => {\n    const style: Record<string, string> = {};\n    style.flexDirection = props.labelPosition === 'left' ? 'row' : 'column';\n    return style;\n});\n\nfunction onInput(event: any) {\n    // 兼容 uni-app input/textarea 事件参数\n    let value = event?.detail?.value ?? '';\n    // 判断是否去除空格\n    if (props.trim) value = $u.trim(value);\n    emit('update:modelValue', value);\n    emit('input', value);\n}\n\nfunction onFocus(event: any) {\n    focused.value = true;\n    emit('focus', event);\n}\n\nfunction onBlur(event: any) {\n    // 最开始使用的是监听图标@touchstart事件，自从hx2.8.4后，此方法在微信小程序出错\n    // 这里改为监听点击事件，手点击清除图标时，同时也发生了@blur事件，导致图标消失而无法点击，这里做一个延时\n    setTimeout(() => {\n        focused.value = false;\n    }, 100);\n    emit('blur', event);\n}\n\nfunction onConfirm(e: any) {\n    emit('confirm', e?.detail?.value ?? '');\n}\n\nfunction onClear() {\n    emit('update:modelValue', '');\n}\n\nfunction rightIconClick() {\n    emit('right-icon-click');\n    emit('click');\n}\n\nfunction fieldClick() {\n    emit('click');\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-field {\n    font-size: 28rpx;\n    padding: 20rpx 28rpx;\n    text-align: left;\n    position: relative;\n    color: $u-main-color;\n}\n\n.u-field-inner {\n    @include vue-flex;\n    align-items: center;\n}\n\n.u-textarea-inner {\n    align-items: flex-start;\n}\n\n.u-textarea-class {\n    min-height: 96rpx;\n    width: auto;\n    font-size: 28rpx;\n}\n\n.fild-body {\n    @include vue-flex;\n    flex: 1;\n    align-items: center;\n}\n\n.u-arror-right {\n    margin-left: 8rpx;\n}\n\n.u-label-text {\n    /* #ifndef APP-NVUE */\n    display: inline-flex;\n    /* #endif */\n}\n\n.u-label-left-gap {\n    margin-left: 6rpx;\n}\n\n.u-label-postion-top {\n    flex-direction: column;\n    align-items: flex-start;\n}\n\n.u-label {\n    width: 130rpx;\n    flex: 1 1 130rpx;\n    text-align: left;\n    position: relative;\n    @include vue-flex;\n    align-items: center;\n}\n\n.u-required::before {\n    content: '*';\n    position: absolute;\n    left: -16rpx;\n    font-size: 14px;\n    color: $u-type-error;\n    height: 9px;\n    line-height: 1;\n}\n\n.u-field__input-wrap {\n    position: relative;\n    overflow: hidden;\n    font-size: 28rpx;\n    height: 48rpx;\n    flex: 1;\n    width: auto;\n}\n\n.u-clear-icon {\n    @include vue-flex;\n    align-items: center;\n}\n\n.u-error-message {\n    color: $u-type-error;\n    font-size: 26rpx;\n    text-align: left;\n}\n\n.placeholder-style {\n    color: rgb(150, 151, 153);\n}\n\n.u-input-class {\n    font-size: 28rpx;\n}\n\n.u-button-wrap {\n    margin-left: 8rpx;\n}\n\n.u-field-input-wrap {\n    position: relative;\n}\n\n.u-field-disabled-overlay {\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    background-color: transparent;\n    z-index: 1;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-form/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { FormRules, InputAlign, FormErrorType, InputLabelPosition, SizeType } from '../../types/global';\n\n/**\n * u-form 组件 Props 类型定义\n * @description 表单组件属性\n */\nexport const FormProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 当前form的需要验证字段的集合 */\n    model: { type: Object as PropType<Record<string, any>>, default: () => ({}) },\n    /** 表单验证规则 */\n    rules: { type: Object as PropType<FormRules>, default: () => ({}) },\n    /** 有错误时的提示方式，message-提示信息，border-如果input设置了边框，变成呈红色，border-bottom-下边框呈现红色，none-无提示 */\n    errorType: { type: Array as PropType<FormErrorType[]>, default: () => ['message', 'toast'] },\n    /** 是否显示表单域的下划线边框 */\n    borderBottom: { type: Boolean, default: true },\n    /** label的位置，left-左边，top-上边 */\n    labelPosition: { type: String as PropType<InputLabelPosition>, default: 'left' },\n    /** label的宽度，单位rpx */\n    labelWidth: { type: [String, Number] as PropType<string | number>, default: 90 },\n    /** label字体的对齐方式 */\n    labelAlign: { type: String as PropType<InputAlign>, default: 'left' },\n    /** label的样式，对象形式 */\n    labelStyle: { type: Object as PropType<Record<string, any>>, default: () => ({}) },\n    /** 表单内组件的大小，仅支持预设值 default/small/large（默认 default） */\n    size: { type: String as PropType<SizeType>, default: 'default' }\n};\n\nexport type FormProps = ExtractPropTypes<typeof FormProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-form/u-form.vue",
    "content": "<template>\n    <view class=\"u-form\" :class=\"customClass\" :style=\"$u.toStyle(customStyle)\">\n        <slot />\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-form',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { FormProps } from './types';\nimport { computed, ref } from 'vue';\nimport { $u, useParent } from '../..';\n\n/**\n * form 表单\n * @description 此组件一般用于表单场景，可以配置Input输入框，Select弹出框，进行表单验证等。\n * @tutorial https://uviewpro.cn/zh/components/form.html\n * @property {Object} model 表单数据对象\n * @property {Boolean} border-bottom 是否显示表单域的下划线边框\n * @property {String} label-position 表单域提示文字的位置，left-左侧，top-上方\n * @property {String Number} label-width 提示文字的宽度，单位rpx（默认90）\n * @property {Object} label-style label的样式，对象形式\n * @property {String} label-align label的对齐方式\n * @property {Object} rules 通过ref设置，见官网说明\n * @property {Array} error-type 错误的提示方式，数组形式，见上方说明(默认['message'])\n * @example <u-form :model=\"form\" ref=\"uForm\"></u-form>\n */\n\nconst props = defineProps(FormProps);\n\nuseParent('u-form');\n\ninterface ErrorItem {\n    prop: string;\n    message: string;\n}\n\n// 存储当前form下的所有u-form-item的实例\nconst fields = ref<any[]>([]);\n\n// 校验规则\nconst rules = ref<Record<string, any>>(props.rules);\n\n/**\n * 设置校验规则\n * @param newRules 校验规则对象\n */\nfunction setRules(newRules: Record<string, any>) {\n    rules.value = newRules;\n}\n\n/**\n * 清空所有u-form-item组件的内容，本质上是调用了u-form-item组件中的resetField()方法\n */\nfunction resetFields() {\n    fields.value.forEach((field: any) => {\n        field.resetField && field.resetField();\n    });\n}\n\n/**\n * 校验全部数据\n * @param callback 校验回调\n * @returns Promise<boolean>\n */\nfunction validate(callback?: (valid: boolean, errorArr: ErrorItem[]) => void): Promise<boolean> {\n    return new Promise(resolve => {\n        // 对所有的u-form-item进行校验\n        let valid = true; // 默认通过\n        let count = 0; // 用于标记是否检查完毕\n        let errorArr: ErrorItem[] = []; // 存放错误信息\n        if (fields.value.length === 0) {\n            resolve(true);\n            if (typeof callback === 'function') callback(true, []);\n            return;\n        }\n        // 调用每一个u-form-item实例的validation的校验方法\n        fields.value.forEach((field: any) => {\n            // 如果任意一个u-form-item校验不通过，就意味着整个表单不通过\n            field.validation &&\n                field.validation('', (error: any) => {\n                    if (error) {\n                        valid = false;\n                        errorArr.push({ prop: field.prop, message: error });\n                    }\n                    // 当历遍了所有的u-form-item时，调用promise的then方法\n                    if (++count === fields.value.length) {\n                        resolve(valid); // 进入promise的then方法\n                        // 判断是否设置了toast的提示方式，只提示最前面的表单域的第一个错误信息\n                        if (\n                            props.errorType.indexOf('none') === -1 &&\n                            props.errorType.indexOf('toast') >= 0 &&\n                            errorArr.length > 0\n                        ) {\n                            errorArr[0].message && $u.toast(errorArr[0].message);\n                        }\n                        // 调用回调方法\n                        if (typeof callback === 'function') callback(valid, errorArr);\n                    }\n                });\n        });\n    });\n}\n\ndefineExpose({\n    setRules,\n    resetFields,\n    validate,\n    addField(field: any) {\n        if (!fields.value.includes(field)) fields.value.push(field);\n    },\n    removeField(field: any) {\n        fields.value = fields.value.filter(f => f.prop !== field.prop);\n    },\n    fields,\n    rules,\n    props,\n    model: computed(() => props.model)\n});\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-form-item/types.ts",
    "content": "import type { PropType, ExtractPropTypes } from 'vue';\nimport type { InputAlign, InputLabelPosition, SizeType } from '../../types/global';\n\n/**\n * form-item 表单item Props\n */\nexport const FormItemProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** input的label提示语 */\n    label: {\n        type: String,\n        default: ''\n    },\n    /** 绑定的值 */\n    prop: {\n        type: String,\n        default: ''\n    },\n    /** 是否显示表单域的下划线边框 */\n    borderBottom: {\n        type: [String, Boolean] as PropType<string | boolean>,\n        default: ''\n    },\n    /** label的位置，left-左边，top-上边 */\n    labelPosition: {\n        type: String as PropType<InputLabelPosition>,\n        default: ''\n    },\n    /** label的宽度，单位rpx */\n    labelWidth: {\n        type: [String, Number] as PropType<string | number>,\n        default: ''\n    },\n    /** label的样式，对象形式 */\n    labelStyle: {\n        type: Object as PropType<Record<string, any>>,\n        default: () => ({})\n    },\n    /** label字体的对齐方式 */\n    labelAlign: {\n        type: String as PropType<InputAlign>,\n        default: ''\n    },\n    /** 右侧图标 */\n    rightIcon: {\n        type: String,\n        default: ''\n    },\n    /** 左侧图标 */\n    leftIcon: {\n        type: String,\n        default: ''\n    },\n    /** 左侧图标的自定义前缀 */\n    leftIconPrefix: {\n        type: String,\n        default: 'uicon'\n    },\n    /** 右侧图标的自定义前缀 */\n    rightIconPrefix: {\n        type: String,\n        default: 'uicon'\n    },\n    /** 左侧图标的样式 */\n    leftIconStyle: {\n        type: Object as PropType<Record<string, any>>,\n        default: () => ({})\n    },\n    /** 右侧图标的样式 */\n    rightIconStyle: {\n        type: Object as PropType<Record<string, any>>,\n        default: () => ({})\n    },\n    /** 是否显示左边的必填星号，只作显示用，具体校验必填的逻辑，请在rules中配置 */\n    required: {\n        type: Boolean,\n        default: false\n    },\n    /** 表单内组件的大小，仅支持预设值 default/small/large */\n    size: {\n        type: String as PropType<SizeType | string>,\n        default: ''\n    }\n};\n\nexport type FormItemProps = ExtractPropTypes<typeof FormItemProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-form-item/u-form-item.vue",
    "content": "<template>\n    <view\n        class=\"u-form-item\"\n        :class=\"[\n            {\n                'u-border-bottom': elBorderBottom,\n                'u-form-item__border-bottom--error': validateState === 'error' && showError('border-bottom'),\n                'u-form-item__border--error': validateState === 'error' && showError('border')\n            },\n            customClass\n        ]\"\n        :style=\"$u.toStyle(customStyle)\"\n    >\n        <view\n            class=\"u-form-item__body\"\n            :style=\"{\n                flexDirection: elLabelPosition == 'left' ? 'row' : 'column'\n            }\"\n        >\n            <!-- 微信小程序中，将一个参数设置空字符串，结果会变成字符串\"true\" -->\n            <view\n                class=\"u-form-item--left\"\n                :style=\"{\n                    width: uLabelWidth,\n                    flex: `0 0 ${uLabelWidth}`,\n                    marginBottom: elLabelPosition == 'left' ? 0 : '10rpx'\n                }\"\n            >\n                <!-- 为了块对齐 -->\n                <view\n                    v-if=\"required || leftIcon || label || $slots.label || $slots.leftIcon\"\n                    class=\"u-form-item--left__content\"\n                >\n                    <!-- nvue不支持伪元素before -->\n                    <text v-if=\"required\" class=\"u-form-item--left__content--required\">*</text>\n                    <view class=\"u-form-item--left__content__icon\" v-if=\"leftIcon || $slots.leftIcon\">\n                        <slot name=\"leftIcon\">\n                            <u-icon\n                                :name=\"leftIcon\"\n                                :size=\"currentIconSize\"\n                                :custom-prefix=\"leftIconPrefix\"\n                                :custom-style=\"leftIconStyle\"\n                            ></u-icon>\n                        </slot>\n                    </view>\n                    <view\n                        class=\"u-form-item--left__content__label\"\n                        :style=\"[\n                            elLabelStyle,\n                            { 'font-size': actualFontSize },\n                            {\n                                'justify-content':\n                                    elLabelAlign == 'left'\n                                        ? 'flex-start'\n                                        : elLabelAlign == 'center'\n                                          ? 'center'\n                                          : 'flex-end'\n                            }\n                        ]\"\n                    >\n                        <slot name=\"label\">\n                            {{ label }}\n                        </slot>\n                    </view>\n                </view>\n            </view>\n            <view class=\"u-form-item--right u-flex\">\n                <view class=\"u-form-item--right__content\">\n                    <view class=\"u-form-item--right__content__slot\">\n                        <slot />\n                    </view>\n                    <view\n                        class=\"u-form-item--right__content__icon u-flex\"\n                        v-if=\"$slots.right || $slots.rightIcon || rightIcon\"\n                    >\n                        <slot name=\"rightIcon\">\n                            <u-icon\n                                v-if=\"rightIcon\"\n                                :name=\"rightIcon\"\n                                :size=\"currentIconSize\"\n                                :custom-prefix=\"rightIconPrefix\"\n                                :custom-style=\"rightIconStyle\"\n                            ></u-icon>\n                        </slot>\n                        <slot name=\"right\" />\n                    </view>\n                </view>\n            </view>\n        </view>\n        <view\n            class=\"u-form-item__message\"\n            v-if=\"validateState === 'error' && showError('message')\"\n            :style=\"{\n                paddingLeft: elLabelPosition == 'left' && label ? $u.addUnit(elLabelWidth) : '0',\n                fontSize: $u.addUnit(currentSizeConfig.messageSize),\n                lineHeight: $u.addUnit(currentSizeConfig.messageSize)\n            }\"\n        >\n            {{ validateMessage }}\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-form-item',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted, onBeforeUnmount, watch, nextTick, useSlots } from 'vue';\nimport { $u, useChildren, useParent } from '../..';\n// @ts-ignore\nimport schema from '../../libs/util/async-validator';\nimport { FormItemProps } from './types';\nimport type { SizeType } from '../../types/global';\n// 去除警告信息\nschema.warning = function () {};\n\n/**\n * form-item 表单item\n * @description 此组件一般用于表单场景，可以配置Input输入框，Select弹出框，进行表单验证等。\n * @tutorial https://uviewpro.cn/zh/components/form.html\n * @property {String} label 左侧提示文字\n * @property {Object} prop 表单域model对象的属性名，在使用 validate、resetFields 方法的情况下，该属性是必填的\n * @property {Boolean} border-bottom 是否显示表单域的下划线边框\n * @property {String} label-position 表单域提示文字的位置，left-左侧，top-上方\n * @property {String Number} label-width 提示文字的宽度，单位rpx（默认90）\n * @property {Object} label-style label的样式，对象形式\n * @property {String} label-align label的对齐方式\n * @property {String} right-icon 右侧自定义字体图标(限uView内置图标)或图片地址\n * @property {String} left-icon 左侧自定义字体图标(限uView内置图标)或图片地址\n * @property {Object} left-icon-style 左侧图标的样式，对象形式\n * @property {Object} right-icon-style 右侧图标的样式，对象形式\n * @property {Boolean} required 是否显示左边的\"*\"号，这里仅起展示作用，如需校验必填，请通过rules配置必填规则(默认false)\n * @example <u-form-item label=\"姓名\"><u-input v-model=\"form.name\" /></u-form-item>\n */\n\nconst props = defineProps(FormItemProps);\n\n// 插槽\nconst $slots = useSlots();\n\nconst { broadcast } = useParent('u-form-item');\nconst { parentExposed } = useChildren('u-form-item', 'u-form');\n\n// 组件状态\nconst initialValue = ref(''); // 存储初始值，用于重置\nconst validateState = ref(''); // 校验状态 success/error/validating\nconst validateMessage = ref(''); // 校验失败的提示语\nconst errorType = ref<string[]>(['message']); // 错误提示方式，默认 message\nconst fieldValue = ref(''); // 当前表单项的值\nconst parentData = ref({\n    borderBottom: true, // 父表单下划线边框\n    labelWidth: 90, // 父表单 label 宽度\n    labelPosition: 'left', // 父表单 label 位置\n    labelStyle: {}, // 父表单 label 样式\n    labelAlign: 'left' // 父表单 label 对齐\n});\n\n// 显示错误提示\n// errorType: ['message', 'toast', 'border-bottom', 'none']\nconst showError = computed(() => (type: string) => {\n    // 如果errorType数组中含有none，或者toast提示类型\n    if (errorType.value.indexOf('none') >= 0) return false;\n    else if (errorType.value.indexOf(type) >= 0) return true;\n    else return false;\n});\n\n// 根据 size 定义不同的配置\nconst sizeConfig = {\n    small: {\n        fontSize: 24,\n        iconSize: 28,\n        messageSize: 20\n    },\n    default: {\n        fontSize: 28,\n        iconSize: 32,\n        messageSize: 24\n    },\n    large: {\n        fontSize: 32,\n        iconSize: 36,\n        messageSize: 28\n    }\n};\n\n// 获取实际使用的 size 值（优先级：u-textarea.size > u-form.size）\nconst actualSize = computed(() => {\n    // 优先使用 props 的 size 属性\n    if (props.size !== '') {\n        return String(props.size);\n    }\n    // 次优先：使用 u-form 的 size 属性（u-form 的 size 只支持预设值）\n    if (parentExposed.value?.props?.size) {\n        return String(parentExposed.value.props.size);\n    }\n    // 默认值\n    return 'default';\n});\n\n// 判断实际使用的 size 是否在预设配置中\nconst isInSizeConfig = computed(() => actualSize.value in sizeConfig);\n\n// 获取预设 size（用于查找 sizeConfig 配置，如图标大小、高度等）\nconst presetSize = computed(() => {\n    return (isInSizeConfig.value ? actualSize.value : 'default') as SizeType;\n});\n\n// 获取当前尺寸配置\nconst currentSizeConfig = computed(() => sizeConfig[presetSize.value]);\n\n// 获取实际要使用的 font-size（如果是预设值使用配置值，否则作为自定义值处理）\nconst actualFontSize = computed(() => {\n    if (isInSizeConfig.value) {\n        return $u.addUnit(currentSizeConfig.value.fontSize);\n    }\n    // 自定义size值，直接作为fontSize处理\n    return $u.addUnit(actualSize.value);\n});\n\n// 计算当前图标大小\nconst currentIconSize = computed(() => currentSizeConfig.value.iconSize);\n\n// 监听校验状态和父表单 errorType 变化\nwatch(validateState, () => {\n    broadcastInputError();\n});\n\n// 监听u-form组件的errorType的变化\nwatch(\n    () => parentExposed?.value?.props?.errorType,\n    val => {\n        if (val) errorType.value = val;\n        broadcastInputError();\n    },\n    { immediate: true }\n);\n\n// 计算属性\nconst uLabelWidth = computed(() => {\n    // 如果用户设置label为空字符串(微信小程序空字符串最终会变成字符串的'true')，意味着要将label的位置宽度设置为auto\n    return elLabelPosition.value == 'left'\n        ? (props.label === 'true' || props.label === '') && !$slots.label\n            ? 'auto'\n            : $u.addUnit(elLabelWidth.value)\n        : '100%';\n});\n\n// label的宽度\nconst elLabelWidth = computed(() => {\n    // label默认宽度为90，优先使用本组件的值，如果没有(如果设置为0，也算是配置了值，依然起效)，则用u-form的值\n    return props.labelWidth != 0 && props.labelWidth !== ''\n        ? props.labelWidth\n        : parentData.value.labelWidth\n          ? parentData.value.labelWidth\n          : 90;\n});\n\n// label的样式\nconst elLabelStyle = computed(() => {\n    return Object.keys(props.labelStyle).length\n        ? props.labelStyle\n        : parentData.value.labelStyle\n          ? parentData.value.labelStyle\n          : {};\n});\n\n// label的位置，左侧或者上方\nconst elLabelPosition = computed(() => {\n    return props.labelPosition\n        ? props.labelPosition\n        : parentData.value.labelPosition\n          ? parentData.value.labelPosition\n          : 'left';\n});\n\n// label的对齐方式\nconst elLabelAlign = computed(() => {\n    return props.labelAlign ? props.labelAlign : parentData.value.labelAlign ? parentData.value.labelAlign : 'left';\n});\n\n// label的下划线\nconst elBorderBottom = computed(() => {\n    // 子组件的borderBottom默认为空字符串，如果不等于空字符串，意味着子组件设置了值，优先使用子组件的值\n    return props.borderBottom !== ''\n        ? props.borderBottom\n        : parentData.value.borderBottom\n          ? parentData.value.borderBottom\n          : false;\n});\n\n// 事件派发/广播工具\nfunction broadcastInputError() {\n    // 子组件发出事件，参数为true或者false，true代表有错误\n    broadcast('onFormItemError', validateState.value === 'error' && showError.value('border'));\n}\n\n/**\n * 根据路径获取对象的值（支持嵌套路径，如 'a.b.c'）\n * @param obj 对象\n * @param path 路径字符串\n */\nfunction getPropByPath(obj: any, path: string) {\n    if (!obj || !path) return { o: obj, k: '', v: undefined };\n\n    const paths = path.split('.');\n    let current = obj;\n    let key = '';\n\n    for (let i = 0; i < paths.length; i++) {\n        key = paths[i];\n        if (!current) break;\n\n        if (i === paths.length - 1) {\n            return { o: current, k: key, v: current[key] };\n        }\n        current = current[key];\n    }\n\n    return { o: current, k: key, v: undefined };\n}\n\n/**\n * 获取当前u-form-item的校验规则\n */\nfunction getRules() {\n    // 父组件的所有规则\n    let rules = parentExposed?.value?.rules?.value || {};\n    rules = rules\n        ? rules[props.prop] || getPropByPath(rules, props.prop.replace(/(\\.|^)(\\d+)\\./, '.defaultField.fields.')).v\n        : [];\n    // 保证返回的是一个数组形式\n    return [].concat(rules || []);\n}\n\n// blur事件时进行表单校验\nfunction onFieldBlur() {\n    validation('blur');\n}\n\n// change事件进行表单校验\nfunction onFieldChange() {\n    validation('change');\n}\n\nfunction onFormBlur() {\n    onFieldBlur();\n}\n\nfunction onFormChange() {\n    onFieldChange();\n}\n\n/**\n * 过滤出符合要求的rule规则\n * @param triggerType 触发类型\n */\nfunction getFilteredRule(triggerType = '') {\n    // 获取所有规则\n    const rules = getRules();\n    // 整体验证表单时，triggerType为空字符串，此时返回所有规则进行验证\n    if (!triggerType) return rules;\n    // 历遍判断规则是否有对应的事件，比如blur，change触发等的事件\n    // 使用indexOf判断，是因为某些时候设置的验证规则的trigger属性可能为多个，比如['blur','change']\n    // 某些场景可能的判断规则，可能不存在trigger属性，故先判断是否存在此属性\n    return rules.filter((res: any) => res.trigger && res.trigger.indexOf(triggerType) !== -1);\n}\n\n/**\n * 校验数据\n * @param trigger 触发类型\n * @param callback 校验回调\n */\nfunction validation(trigger: string, callback: (msg: string) => void = () => {}) {\n    // 检验之前，先获取需要校验的值（支持嵌套路径）\n    const propPath = getPropByPath(parentExposed?.value?.model?.value, props.prop);\n    fieldValue.value = propPath.v;\n\n    // blur和change是否有当前方式的校验规则\n    let rules = getFilteredRule(trigger);\n    // 判断是否有验证规则，如果没有规则，也调用回调方法，否则父组件u-form会因为\n    // 对count变量的统计错误而无法进入上一层的回调\n    if (!rules || rules.length === 0) {\n        callback('');\n        return;\n    }\n    // 设置当前的状态，标识为校验中\n    validateState.value = 'validating';\n    // 调用async-validator的方法\n    let validator = new schema({ [props.prop]: rules });\n    validator.validate({ [props.prop]: fieldValue.value }, { firstFields: true }, (errors: any) => {\n        // 记录状态和报错信息\n        validateState.value = !errors ? 'success' : 'error';\n        validateMessage.value = errors ? errors[0].message : '';\n        // 调用回调方法\n        callback(validateMessage.value);\n    });\n}\n\n/**\n * 清空当前的u-form-item\n */\nfunction resetField() {\n    if (parentExposed?.value?.model?.value && props.prop) {\n        // 支持嵌套路径的重置\n        const propPath = getPropByPath(parentExposed.value.model.value, props.prop);\n        if (propPath.o && propPath.k) {\n            propPath.o[propPath.k] = initialValue.value;\n        }\n    }\n    // 设置为`success`状态，只是为了清空错误标记\n    // 延时50毫秒，如果立即清空状态，则无法清空错误标记\n    setTimeout(() => {\n        validateState.value = 'success';\n    }, 50);\n}\n\n// 组件挂载时注册到父表单\nonMounted(() => {\n    nextTick(() => {\n        if (parentExposed.value) {\n            // 继承父表单配置\n            // 历遍parentData中的属性，将parent中的同名属性赋值给parentData\n            Object.keys(parentData.value).forEach(key => {\n                (parentData.value as any)[key] = parentExposed?.value?.props[key];\n            });\n            // 如果没有传入prop，或者uForm为空(如果u-form-input单独使用，就不会有uForm注入)，就不进行校验\n            if (props.prop) {\n                // 将本实例添加到父组件中\n                parentExposed?.value?.addField &&\n                    parentExposed?.value?.addField({\n                        validation,\n                        resetField,\n                        prop: props.prop\n                    });\n                errorType.value = parentExposed?.value?.errorType || errorType.value;\n                // 设置初始值（支持嵌套路径）\n                const propPath = getPropByPath(parentExposed?.value?.model?.value, props.prop);\n                fieldValue.value = propPath.v;\n                // 设置初始值\n                initialValue.value = fieldValue.value;\n            }\n        }\n    });\n});\n// 组件销毁前，将实例从u-form的缓存中移除\nonBeforeUnmount(() => {\n    // 如果当前没有prop的话表示当前不要进行删除（因为没有注入）\n    if (parentExposed?.value && props.prop) {\n        parentExposed?.value?.removeField && parentExposed?.value?.removeField({ prop: props.prop });\n    }\n});\n\ndefineExpose({\n    validation,\n    resetField,\n    onFormBlur,\n    onFormChange\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-form-item {\n    @include vue-flex;\n    // align-items: flex-start;\n    padding: 20rpx 0;\n    font-size: 28rpx;\n    color: $u-main-color;\n    box-sizing: border-box;\n    // line-height: 70rpx;\n    flex-direction: column;\n\n    &__border-bottom--error:after {\n        border-color: $u-type-error;\n    }\n\n    &__border--error {\n        :deep(.u-input--border) {\n            border-color: $u-type-error !important;\n        }\n    }\n\n    &__body {\n        @include vue-flex;\n    }\n\n    &--left {\n        @include vue-flex;\n        align-items: center;\n\n        &__content {\n            position: relative;\n            @include vue-flex;\n            align-items: center;\n            padding-right: 10rpx;\n            flex: 1;\n\n            &__icon {\n                margin-right: 8rpx;\n                @include vue-flex;\n                align-items: center;\n            }\n\n            &--required {\n                position: absolute;\n                left: -16rpx;\n                vertical-align: middle;\n                color: $u-type-error;\n                padding-top: 6rpx;\n            }\n\n            &__label {\n                @include vue-flex;\n                align-items: center;\n                flex: 1;\n            }\n        }\n    }\n\n    &--right {\n        flex: 1;\n\n        &__content {\n            @include vue-flex;\n            align-items: center;\n            flex: 1;\n\n            &__slot {\n                flex: 1;\n                @include vue-flex;\n                align-items: center;\n            }\n\n            &__icon {\n                margin-left: 10rpx;\n                color: $u-light-color;\n                font-size: 30rpx;\n                @include vue-flex;\n                align-items: center;\n            }\n        }\n    }\n\n    &__message {\n        font-size: 24rpx;\n        line-height: 24rpx;\n        color: $u-type-error;\n        margin-top: 12rpx;\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-full-screen/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\n/**\n * u-full-screen 组件 Props 类型定义\n * @description 用于APP弹窗遮盖导航栏和底部tabbar，提示新版本升级内容\n */\nexport const FullScreenProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 是否显示弹窗 */\n    show: { type: Boolean, default: false },\n    /** 弹窗标题 */\n    title: { type: String, default: '' },\n    /** 升级内容，支持富文本 */\n    content: { type: String, default: '' }\n};\n\nexport type FullScreenProps = ExtractPropTypes<typeof FullScreenProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-full-screen/u-full-screen.vue",
    "content": "<template>\n    <u-modal\n        v-model=\"show\"\n        :class=\"customClass\"\n        :style=\"$u.toStyle(customStyle)\"\n        :show-cancel-button=\"true\"\n        :confirm-text=\"t('uFullScreen.upgrade')\"\n        :title=\"title || t('uFullScreen.title')\"\n        @cancel=\"cancel\"\n        @confirm=\"confirm\"\n    >\n        <view class=\"u-update-content\">\n            <rich-text :nodes=\"content\"></rich-text>\n        </view>\n    </u-modal>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-full-screen',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { FullScreenProps } from './types';\nimport { ref, onMounted } from 'vue';\nimport { $u, useLocale } from '../../';\n\n/**\n * 压窗屏升级弹窗组件\n * @description 用于APP弹窗遮盖导航栏和底部tabbar，提示新版本升级内容\n * @property {boolean} show 是否显示弹窗\n * @property {string} content 升级内容，支持富文本\n */\ndefineProps(FullScreenProps);\n\n/**\n * 是否显示弹窗\n */\nconst show = ref(false);\n/**\n * 升级内容，支持富文本\n */\n\nconst { t } = useLocale();\n\n/**\n * 页面加载完成后自动显示弹窗\n */\nonMounted(() => {\n    show.value = true;\n});\n\n/**\n * 取消按钮点击事件\n * @description 关闭弹窗并返回上一页\n */\nfunction cancel() {\n    closeModal();\n}\n\n/**\n * 升级按钮点击事件\n * @description 关闭弹窗并返回上一页\n */\nfunction confirm() {\n    closeModal();\n}\n\n/**\n * 关闭弹窗方法\n * @description 返回上一页\n */\nfunction closeModal() {\n    uni.navigateBack();\n}\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n\n.u-full-content {\n    background-color: var(--u-type-success);\n}\n\n.u-update-content {\n    font-size: 26rpx;\n    color: $u-content-color;\n    line-height: 1.7;\n    padding: 30rpx;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-gap/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\n/**\n * u-gap 组件 Props 类型定义\n * @description 间隔槽组件属性\n */\nexport const GapProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 背景颜色 */\n    bgColor: { type: String, default: 'transparent' },\n    /** 高度 */\n    height: { type: [String, Number] as PropType<string | number>, default: 30 },\n    /** 与上一个组件的距离 */\n    marginTop: { type: [String, Number] as PropType<string | number>, default: 0 },\n    /** 与下一个组件的距离 */\n    marginBottom: { type: [String, Number] as PropType<string | number>, default: 0 }\n};\n\nexport type GapProps = ExtractPropTypes<typeof GapProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-gap/u-gap.vue",
    "content": "<template>\n    <view class=\"u-gap\" :style=\"$u.toStyle(gapStyle, customStyle)\"></view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-gap',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { GapProps } from './types';\nimport { computed } from 'vue';\nimport { $u } from '../../';\n\n/**\n * gap 间隔槽\n * @description 该组件一般用于内容块之间的用一个灰色块隔开的场景，方便用户风格统一，减少工作量\n * @tutorial https://uviewpro.cn/zh/components/gap.html\n * @property {String} bg-color 背景颜色（默认var(--u-bg-color)）\n * @property {String Number} height 分割槽高度，单位rpx（默认30）\n * @property {String Number} margin-top 与前一个组件的距离，单位rpx（默认0）\n * @property {String Number} margin-bottom 与后一个组件的距离，单位rpx（0）\n * @example <u-gap height=\"80\" bg-color=\"var(--u-light-color)\"></u-gap>\n */\nconst props = defineProps(GapProps);\n\n/**\n * 间隔槽样式\n */\nconst gapStyle = computed(() => {\n    return {\n        backgroundColor: props.bgColor,\n        height: $u.addUnit(props.height),\n        marginTop: $u.addUnit(props.marginTop),\n        marginBottom: $u.addUnit(props.marginBottom)\n    };\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-grid/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { InputAlign } from '../../types/global';\n\n/**\n * u-grid 组件 Props 类型定义\n * @description 宫格组件属性\n */\nexport const GridProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 分成几列 */\n    col: { type: [Number, String] as PropType<string | number>, default: 3 },\n    /** 是否显示边框 */\n    border: { type: Boolean, default: true },\n    /** 宫格对齐方式，表现为数量少的时候，靠左，居中，还是靠右 */\n    align: { type: String as PropType<InputAlign>, default: 'left' },\n    /** 宫格按压时的样式类，\"none\"为无效果 */\n    hoverClass: { type: String, default: 'u-hover-class' }\n};\n\nexport type GridProps = ExtractPropTypes<typeof GridProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-grid/u-grid.vue",
    "content": "<template>\n    <view\n        class=\"u-grid\"\n        :class=\"{ 'u-border-top u-border-left': border, customClass }\"\n        :style=\"$u.toStyle(gridStyle, customStyle)\"\n    >\n        <slot />\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-grid',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { useParent, $u } from '../../';\nimport { GridProps } from './types';\nimport { computed } from 'vue';\n\n/**\n * grid 宫格布局\n * @description 宫格组件一般用于同时展示多个同类项目的场景，可以给宫格的项目设置徽标组件(badge)，或者图标等，也可以扩展为左右滑动的轮播形式。\n * @tutorial https://uviewpro.cn/zh/components/grid.html\n * @property {String|Number} col 宫格的列数（默认3）\n * @property {Boolean} border 是否显示宫格的边框（默认true）\n * @property {Boolean} hover-class 点击宫格的时候，是否显示按下的灰色背景（默认false）\n * @event {Function} click 点击宫格触发\n * @example <u-grid :col=\"3\" @click=\"click\"></u-grid>\n */\n\nconst props = defineProps(GridProps);\nconst emit = defineEmits(['click']);\nuseParent('u-grid');\n\n// 宫格对齐方式\nconst gridStyle = computed(() => {\n    const style: Record<string, string> = {};\n    switch (props.align) {\n        case 'left':\n            style.justifyContent = 'flex-start';\n            break;\n        case 'center':\n            style.justifyContent = 'center';\n            break;\n        case 'right':\n            style.justifyContent = 'flex-end';\n            break;\n        default:\n            style.justifyContent = 'flex-start';\n    }\n    return style;\n});\n\n/**\n * 点击宫格\n * @param index 子项索引\n */\nfunction click(index: number) {\n    emit('click', index);\n}\n\ndefineExpose({ click, props });\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n\n.u-grid {\n    width: 100%;\n    /* #ifdef MP */\n    position: relative;\n    box-sizing: border-box;\n    overflow: hidden;\n    /* #endif */\n\n    /* #ifndef MP */\n    @include vue-flex;\n    flex-wrap: wrap;\n    align-items: center;\n    /* #endif */\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-grid-item/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\n/**\n * u-grid-item 组件 Props 类型定义\n * @description 宫格项组件属性\n */\nexport const GridItemProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 背景颜色 */\n    bgColor: { type: String, default: 'var(--u-bg-white)' },\n    /** 点击时返回的index */\n    index: { type: [Number, String] as PropType<string | number>, default: '' }\n};\n\nexport type GridItemProps = ExtractPropTypes<typeof GridItemProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-grid-item/u-grid-item.vue",
    "content": "<template>\n    <view\n        class=\"u-grid-item\"\n        :class=\"customClass\"\n        :hover-class=\"hoverClass\"\n        :hover-stay-time=\"200\"\n        @tap=\"click\"\n        :style=\"\n            $u.toStyle(\n                {\n                    background: bgColor,\n                    width: width\n                },\n                customStyle\n            )\n        \"\n    >\n        <view class=\"u-grid-item-box\" :style=\"[customStyle]\" :class=\"[border ? 'u-border-right u-border-bottom' : '']\">\n            <slot />\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-grid-item',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { GridItemProps } from './types';\nimport { computed } from 'vue';\nimport { $u, useChildren } from '../..';\n\n/**\n * gridItem 宫格项\n * @description 宫格组件一般用于同时展示多个同类项目的场景，可以给宫格的项目设置徽标组件(badge)，或者图标等，也可以扩展为左右滑动的轮播形式。搭配u-grid使用\n * @tutorial https://uviewpro.cn/zh/components/grid.html\n * @property {String} bg-color 宫格的背景颜色（默认var(--u-bg-white)）\n * @property {String|Number} index 点击宫格时，返回的值\n * @property {Object} custom-style 自定义样式，对象形式\n * @event {Function} click 点击宫格触发\n * @example <u-grid-item></u-grid-item>\n */\n\nconst props = defineProps(GridItemProps);\nconst { parentExposed } = useChildren('u-grid-item', 'u-grid');\nconst emit = defineEmits(['click']);\n\n// 宫格按压时的样式类，\"none\"为无效果\nconst hoverClass = computed(() => {\n    return parentExposed?.value?.props?.hoverClass ?? '';\n});\n\n// 是否显示边框\nconst border = computed(() => {\n    return parentExposed?.value?.props?.border ?? true;\n});\n\n// 分成几列\nconst col = computed(() => {\n    return parentExposed?.value?.props?.col ?? 3;\n});\n\n// 计算每个grid-item的宽度\nconst width = computed(() => 100 / Number(col.value) + '%');\n\n/**\n * 点击宫格\n */\nfunction click() {\n    emit('click', props.index);\n    parentExposed?.value?.click(props.index);\n}\n\ndefineExpose({ click });\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n\n.u-grid-item {\n    box-sizing: border-box;\n    background-color: var(--u-bg-white);\n    @include vue-flex;\n    align-items: center;\n    justify-content: center;\n    position: relative;\n    flex-direction: column;\n\n    /* #ifdef MP */\n    position: relative;\n    float: left;\n    /* #endif */\n}\n\n.u-grid-item-hover {\n    background: var(--u-bg-gray-light) !important;\n}\n\n.u-grid-marker-box {\n    position: absolute;\n    /* #ifndef APP-NVUE */\n    display: inline-flex;\n    /* #endif */\n    line-height: 0;\n}\n\n.u-grid-marker-wrap {\n    position: absolute;\n}\n\n.u-grid-item-box {\n    padding: 30rpx 0;\n    @include vue-flex;\n    align-items: center;\n    justify-content: center;\n    flex-direction: column;\n    flex: 1;\n    width: 100%;\n    height: 100%;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-icon/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { IconLabelPosition, ImgMode } from '../../types/global';\n\n/**\n * u-icon 组件 Props 类型定义\n */\nexport const IconProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 图标名称，见示例图标集 */\n    name: { type: String, default: '' },\n    /** 图标颜色，可接受主题色 */\n    color: { type: String, default: '' },\n    /** 字体大小，单位rpx（默认32） */\n    size: { type: [Number, String] as PropType<string | number>, default: 'inherit' },\n    /** 是否显示粗体 */\n    bold: { type: Boolean, default: false },\n    /** 点击图标的时候传递事件出去的index（用于区分点击了哪一个） */\n    index: { type: [Number, String] as PropType<string | number>, default: '' },\n    /** 触摸图标时的类名 */\n    hoverClass: { type: String, default: '' },\n    /** 自定义扩展前缀，方便用户扩展自己的图标库 */\n    customPrefix: { type: String, default: 'uicon' },\n    /** 图标右边或者下面的文字 */\n    label: { type: [String, Number] as PropType<string | number>, default: '' },\n    /** label的位置，只能右边或者下边 */\n    labelPos: { type: String as PropType<IconLabelPosition>, default: 'right' },\n    /** label的大小，单位rpx（默认28） */\n    labelSize: { type: [String, Number] as PropType<string | number>, default: '28' },\n    /** label的颜色 */\n    labelColor: { type: String, default: 'var(--u-content-color)' },\n    /** label与图标的距离(横向排列)，单位rpx（默认6） */\n    marginLeft: { type: [String, Number] as PropType<string | number>, default: '6' },\n    /** label与图标的距离(竖向排列)，单位rpx（默认6） */\n    marginTop: { type: [String, Number] as PropType<string | number>, default: '6' },\n    /** label与图标的距离(竖向排列)，单位rpx（默认6） */\n    marginRight: { type: [String, Number] as PropType<string | number>, default: '6' },\n    /** label与图标的距离(竖向排列)，单位rpx（默认6） */\n    marginBottom: { type: [String, Number] as PropType<string | number>, default: '6' },\n    /** label与图标的距离，单位rpx，权重高于 margin */\n    space: { type: [String, Number] as PropType<string | number>, default: '' },\n    /** 图片的mode，参考uni-app image组件 */\n    imgMode: { type: String as PropType<ImgMode>, default: 'widthFix' },\n    /** 用于显示图片小图标时，图片的宽度，单位rpx */\n    width: { type: [String, Number] as PropType<string | number>, default: '' },\n    /** 用于显示图片小图标时，图片的高度，单位rpx */\n    height: { type: [String, Number] as PropType<string | number>, default: '' },\n    /** 用于解决某些情况下，让图标垂直居中的用途，单位rpx */\n    top: { type: [String, Number] as PropType<string | number>, default: 0 },\n    /** 是否为DecimalIcon */\n    showDecimalIcon: { type: Boolean, default: false },\n    /** 背景颜色，可接受主题色，仅Decimal时有效 */\n    inactiveColor: { type: String, default: 'var(--u-divider-color)' },\n    /** 显示的百分比，仅Decimal时有效 */\n    percent: { type: [Number, String] as PropType<string | number>, default: '50' }\n};\n\n/**\n * u-icon 组件 Props 类型\n */\nexport type IconProps = ExtractPropTypes<typeof IconProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-icon/u-icon.vue",
    "content": "<template>\n    <view\n        :style=\"$u.toStyle(customStyle)\"\n        class=\"u-icon\"\n        @click=\"onClick\"\n        :class=\"['u-icon--' + labelPos, customClass]\"\n    >\n        <image class=\"u-icon__img\" v-if=\"isImg\" :src=\"props.name\" :mode=\"imgMode\" :style=\"[imgStyle]\" />\n        <text\n            v-else\n            class=\"u-icon__icon\"\n            :class=\"iconClass\"\n            :style=\"$u.toStyle(iconStyle)\"\n            :hover-class=\"hoverClass\"\n            @touchstart=\"onTouchstart\"\n        >\n            <text\n                v-if=\"showDecimalIcon\"\n                :style=\"$u.toStyle(decimalIconStyle)\"\n                :class=\"decimalIconClass\"\n                :hover-class=\"hoverClass\"\n                class=\"u-icon__decimal\"\n            ></text>\n        </text>\n        <text v-if=\"label !== ''\" class=\"u-icon__label\" :style=\"labelStyle\">\n            {{ label }}\n        </text>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-icon',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { $u } from '../..';\nimport { IconProps } from './types';\n\n/**\n * icon 图标\n * @description 基于字体的图标集，包含了大多数常见场景的图标。\n * @tutorial https://uviewpro.cn/zh/components/icon.html\n * @property {String} name 图标名称，见示例图标集\n * @property {String} color 图标颜色（默认inherit）\n * @property {String | Number} size 图标字体大小，单位rpx（默认32）\n * @property {String | Number} label-size label字体大小，单位rpx（默认28）\n * @property {String} label 图标右侧的label文字（默认28）\n * @property {String} label-pos label文字相对于图标的位置，只能right或bottom（默认right）\n * @property {String} label-color label字体颜色（默认var(--u-content-color)）\n * @property {Object} custom-style icon的样式，对象形式\n * @property {String} custom-prefix 自定义字体图标库时，需要写上此值\n * @property {String | Number} margin-left label在右侧时与图标的距离，单位rpx（默认6）\n * @property {String | Number} margin-top label在下方时与图标的距离，单位rpx（默认6）\n * @property {String | Number} margin-bottom label在上方时与图标的距离，单位rpx（默认6）\n * @property {String | Number} margin-right label在左侧时与图标的距离，单位rpx（默认6）\n * @property {String | Number} space label与图标的距离，单位rpx，权重高于 margin\n * @property {String} index 一个用于区分多个图标的值，点击图标时通过click事件传出\n * @property {String} hover-class 图标按下去的样式类，用法同uni的view组件的hover-class参数，详情见官网\n * @property {String} width 显示图片小图标时的宽度\n * @property {String} height 显示图片小图标时的高度\n * @property {String | Number} top 图标在垂直方向上的定位\n * @property {Boolean} show-decimal-icon 是否为DecimalIcon\n * @property {String} inactive-color 背景颜色，可接受主题色，仅Decimal时有效\n * @property {String | Number} percent 显示的百分比，仅Decimal时有效\n * @event {Function} click 点击图标时触发\n * @event {Function} touchstart 图标触摸时触发\n * @example <u-icon name=\"photo\" color=\"var(--u-type-primary)\" size=\"28\"></u-icon>\n */\n\nconst emit = defineEmits<{\n    (e: 'click', index: string | number): void;\n    (e: 'touchstart', index: string | number): void;\n}>();\n\nconst props = defineProps(IconProps);\n\n/**\n * 计算图标的类名集合\n * @returns {string[]}\n */\nconst iconClass = computed(() => {\n    let classes: string[] | string = [];\n    classes.push(props.customPrefix + '-' + props.name);\n    // uView的自定义图标类名为u-iconfont\n    if (props.customPrefix === 'uicon') {\n        classes.push('u-iconfont');\n    } else {\n        classes.push(props.customPrefix);\n    }\n    // 主题色，通过类配置\n    if (props.showDecimalIcon && props.inactiveColor && $u.config.type.includes(props.inactiveColor)) {\n        classes.push('u-icon__icon--' + props.inactiveColor);\n    } else if (props.color && $u.config.type.includes(props.color)) {\n        classes.push('u-icon__icon--' + props.color);\n    }\n    // 阿里，头条，百度小程序通过数组绑定类名时，无法直接使用[a, b, c]的形式，否则无法识别\n    // 故需将其拆成一个字符串的形式，通过空格隔开各个类名\n    // #ifdef MP-ALIPAY || MP-TOUTIAO || MP-BAIDU\n    classes = (classes as string[]).join(' ');\n    // #endif\n    return classes;\n});\n\n/**\n * 计算图标的样式\n * @returns {CSSProperties}\n */\nconst iconStyle = computed(() => {\n    const style: Record<string, any> = {\n        fontSize: props.size === 'inherit' ? 'inherit' : $u.addUnit(props.size),\n        fontWeight: props.bold ? 'bold' : 'normal',\n        // 某些特殊情况需要设置一个到顶部的距离，才能更好的垂直居中\n        top: $u.addUnit(props.top)\n    };\n    // 非主题色值时，才当作颜色值\n    if (props.showDecimalIcon && props.inactiveColor && !$u.config.type.includes(props.inactiveColor)) {\n        style.color = props.inactiveColor;\n    } else if (props.color && !$u.config.type.includes(props.color)) {\n        style.color = props.color;\n    }\n    return style;\n});\n\n/**\n * 判断传入的name属性是否为图片路径\n * @returns {boolean}\n */\nconst isImg = computed(() => {\n    return props.name.indexOf('/') !== -1;\n});\n\n/**\n * 计算图片图标的样式\n * @returns {any}\n */\nconst imgStyle = computed(() => {\n    // 如果设置width和height属性，则优先使用，否则使用size属性\n    const style: any = {\n        width: props.width ? $u.addUnit(props.width) : $u.addUnit(props.size),\n        height: props.height ? $u.addUnit(props.height) : $u.addUnit(props.size)\n    };\n    return style;\n});\n\n/**\n * 计算小数图标的样式，仅DecimalIcon时有效\n * @returns {CSSProperties}\n */\nconst decimalIconStyle = computed(() => {\n    const style: any = {\n        fontSize: props.size === 'inherit' ? 'inherit' : $u.addUnit(props.size),\n        fontWeight: props.bold ? 'bold' : 'normal',\n        // 某些特殊情况需要设置一个到顶部的距离，才能更好的垂直居中\n        top: $u.addUnit(props.top),\n        width: props.percent + '%'\n    };\n    // 非主题色值时，才当作颜色值\n    if (props.color && !$u.config.type.includes(props.color)) {\n        style.color = props.color;\n    }\n    return style;\n});\n\n/**\n * 计算小数图标的类名，仅DecimalIcon时有效\n * @returns {string | string[]}\n */\nconst decimalIconClass = computed(() => {\n    let classes: string[] | string = [];\n    classes.push(props.customPrefix + '-' + props.name);\n    // uView的自定义图标类名为u-iconfont\n    if (props.customPrefix === 'uicon') {\n        classes.push('u-iconfont');\n    } else {\n        classes.push(props.customPrefix);\n    }\n    if (props.color && $u.config.type.includes(props.color)) {\n        classes.push('u-icon__icon--' + props.color);\n    } else {\n        classes.push('u-icon__icon--primary');\n    }\n    // 阿里，头条，百度小程序通过数组绑定类名时，无法直接使用[a, b, c]的形式，否则无法识别\n    // 故需将其拆成一个字符串的形式，通过空格隔开各个类名\n    // #ifdef MP-ALIPAY || MP-TOUTIAO || MP-BAIDU\n    classes = (classes as string[]).join(' ');\n    // #endif\n    return classes;\n});\n\n/**\n * 计算label的样式\n * @returns {any}\n */\nconst labelStyle = computed(() => {\n    return {\n        color: props.labelColor,\n        fontSize: $u.addUnit(props.labelSize),\n        marginLeft: props.labelPos === 'right' ? $u.addUnit(props.space || props.marginLeft) : 0,\n        marginTop: props.labelPos === 'bottom' ? $u.addUnit(props.space || props.marginTop) : 0,\n        marginRight: props.labelPos === 'left' ? $u.addUnit(props.space || props.marginRight) : 0,\n        marginBottom: props.labelPos === 'top' ? $u.addUnit(props.space || props.marginBottom) : 0\n    };\n});\n\n/**\n * 点击图标时触发\n * @emits click(index)\n */\nfunction onClick(event: any) {\n    emit('click', props.index || event);\n}\n\n/**\n * 图标触摸时触发\n * @emits touchstart(index)\n */\nfunction onTouchstart(event: any) {\n    emit('touchstart', props.index || event);\n}\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n@import '../../iconfont.css';\n\n.u-icon {\n    display: inline-flex;\n    align-items: center;\n\n    &--left {\n        flex-direction: row-reverse;\n        align-items: center;\n    }\n\n    &--right {\n        flex-direction: row;\n        align-items: center;\n    }\n\n    &--top {\n        flex-direction: column-reverse;\n        justify-content: center;\n    }\n\n    &--bottom {\n        flex-direction: column;\n        justify-content: center;\n    }\n\n    &__icon {\n        position: relative;\n\n        &--primary {\n            color: $u-type-primary;\n        }\n\n        &--success {\n            color: $u-type-success;\n        }\n\n        &--error {\n            color: $u-type-error;\n        }\n\n        &--warning {\n            color: $u-type-warning;\n        }\n\n        &--info {\n            color: $u-type-info;\n        }\n    }\n\n    &__decimal {\n        position: absolute;\n        top: 0;\n        left: 0;\n        display: inline-block;\n        overflow: hidden;\n    }\n\n    &__img {\n        height: auto;\n        will-change: transform;\n    }\n\n    &__label {\n        line-height: 1;\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-image/types.ts",
    "content": "import type { ComponentPublicInstance, ExtractPropTypes, PropType } from 'vue';\nimport type { ImgMode, Shape } from '../../types/global';\n\n// 定义 ImageProps 的类型\nexport const ImageProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 图片地址 */\n    src: { type: String, default: '' },\n    /** 裁剪模式 */\n    mode: { type: String as PropType<ImgMode>, default: 'aspectFill' },\n    /** 宽度，单位任意，如果为数值，则为rpx单位（默认100%） */\n    width: { type: [String, Number], default: '100%' },\n    /** 高度，单位任意，如果为数值，则为rpx单位（默认 auto） */\n    height: { type: [String, Number], default: 'auto' },\n    /** 图片形状，circle-圆形，square-方形（默认square） */\n    shape: { type: String as PropType<Shape>, default: 'square' },\n    /** 圆角值，单位任意，如果为数值，则为rpx单位（默认 0） */\n    borderRadius: { type: [String, Number], default: 0 },\n    /** 是否懒加载，仅微信小程序、App、百度小程序、字节跳动小程序有效（默认 true） */\n    lazyLoad: { type: Boolean, default: true },\n    /** 是否开启长按图片显示识别小程序码菜单，仅微信小程序有效（默认 true） */\n    showMenuByLongpress: { type: Boolean, default: true },\n    /** 加载中的图标，或者小图片（默认 photo） */\n    loadingIcon: { type: String, default: 'photo' },\n    /** 加载失败的图标，或者小图片（默认 error-circle） */\n    errorIcon: { type: String, default: 'error-circle' },\n    /** 是否显示加载中的图标或者自定义的slot（默认 true） */\n    showLoading: { type: Boolean, default: true },\n    /** 是否显示加载错误的图标或者自定义的slot（默认 true） */\n    showError: { type: Boolean, default: true },\n    /** 是否需要淡入效果（默认 true） */\n    fade: { type: Boolean, default: true },\n    /** 只支持网络资源，只对微信小程序有效（默认 false） */\n    webp: { type: Boolean, default: false },\n    /** 搭配fade参数的过渡时间，单位ms（默认 500） */\n    duration: { type: [String, Number], default: 500 },\n    /** 背景颜色，用于深色页面加载图片时，为了和背景色融合（默认 var(--u-bg-color)） */\n    bgColor: { type: String, default: 'var(--u-bg-color)' },\n    /** 使用插槽名称对象，用于自定义插槽，默认 undefined，当动态切换slot隐藏时，需要使用useSlots使用，兼容头条小程序 */\n    useSlots: { type: Object as PropType<Record<string, boolean>>, default: undefined }\n};\n\n// 将 ImageProps 转换为类型\nexport type ImageProps = ExtractPropTypes<typeof ImageProps>;\n\n// 暴露的组件实例方法\nexport type ImageExpose = {\n    changeStatus: (status: 'loading' | 'error' | 'normal') => void;\n};\n\n// 组件实例类型\nexport type ImageInstance = ComponentPublicInstance<ImageProps, ImageExpose>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-image/u-image.vue",
    "content": "<template>\n    <view\n        class=\"u-image\"\n        @tap=\"onClick\"\n        :style=\"$u.toStyle(wrapStyle, backgroundStyle, customStyle)\"\n        :class=\"customClass\"\n    >\n        <image\n            v-if=\"!isError\"\n            :src=\"src\"\n            :mode=\"mode\"\n            @error=\"onErrorHandler\"\n            @load=\"onLoadHandler\"\n            :lazy-load=\"lazyLoad\"\n            class=\"u-image__image\"\n            :show-menu-by-longpress=\"showMenuByLongpress\"\n            :style=\"{ borderRadius: shape === 'circle' ? '50%' : $u.addUnit(borderRadius) }\"\n        ></image>\n        <view\n            v-if=\"showLoading && loading\"\n            class=\"u-image__loading\"\n            :style=\"{ borderRadius: shape === 'circle' ? '50%' : $u.addUnit(borderRadius), backgroundColor: bgColor }\"\n        >\n            <slot v-if=\"hasSlot('loading')\" name=\"loading\" />\n            <u-icon v-else :name=\"loadingIcon\" :width=\"width\" :height=\"height\"></u-icon>\n        </view>\n        <view\n            v-if=\"showError && isError && !loading\"\n            class=\"u-image__error\"\n            :style=\"{ borderRadius: shape === 'circle' ? '50%' : $u.addUnit(borderRadius) }\"\n        >\n            <slot v-if=\"hasSlot('error')\" name=\"error\" />\n            <u-icon v-else :name=\"errorIcon\" :width=\"width\" :height=\"height\"></u-icon>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-image',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, useSlots } from 'vue';\nimport { type ImageExpose, ImageProps } from './types';\nimport { $u } from '../..';\n\n/**\n * Image 图片\n * @description 此组件为uni-app的image组件的加强版，在继承了原有功能外，还支持淡入动画、加载中、加载失败提示、圆角值和形状等。\n * @tutorial https://uviewpro.cn/zh/components/image.html\n * @property {String} src 图片地址\n * @property {String} mode 裁剪模式，见官网说明\n * @property {String | Number} width 宽度，单位任意，如果为数值，则为rpx单位（默认100%）\n * @property {String | Number} height 高度，单位任意，如果为数值，则为rpx单位（默认 auto）\n * @property {String} shape 图片形状，circle-圆形，square-方形（默认square）\n * @property {String | Number} border-radius 圆角值，单位任意，如果为数值，则为rpx单位（默认 0）\n * @property {Boolean} lazy-load 是否懒加载，仅微信小程序、App、百度小程序、字节跳动小程序有效（默认 true）\n * @property {Boolean} show-menu-by-longpress 是否开启长按图片显示识别小程序码菜单，仅微信小程序有效（默认 false）\n * @property {String} loading-icon 加载中的图标，或者小图片（默认 photo）\n * @property {String} error-icon 加载失败的图标，或者小图片（默认 error-circle）\n * @property {Boolean} show-loading 是否显示加载中的图标或者自定义的slot（默认 true）\n * @property {Boolean} show-error 是否显示加载错误的图标或者自定义的slot（默认 true）\n * @property {Boolean} fade 是否需要淡入效果（默认 true）\n * @property {Boolean} webp 只支持网络资源，只对微信小程序有效（默认 false）\n * @property {String | Number} duration 搭配fade参数的过渡时间，单位ms（默认 500）\n * @property {String} bg-color 背景颜色，用于深色页面加载图片时，为了和背景色融合（默认 var(--u-bg-color)）\n * @event {Function} click 点击图片时触发\n * @event {Function} error 图片加载失败时触发\n * @event {Function} load 图片加载成功时触发\n * @example <u-image width=\"100%\" height=\"300rpx\" :src=\"src\"></u-image>\n */\n\nconst emit = defineEmits<{\n    (e: 'click'): void;\n    (e: 'error', err: any): void;\n    (e: 'load'): void;\n}>();\n\nconst props = defineProps(ImageProps);\n\n// 图片是否加载错误，如果是，则显示错误占位图\nconst isError = ref(false);\n// 初始化组件时，默认为加载中状态\nconst loading = ref(true);\n// 不透明度，为了实现淡入淡出的效果\nconst opacity = ref(1);\n// 过渡时间，因为props的值无法修改，故需要一个中间值\nconst durationTime = ref(props.duration);\n// 图片加载完成时，去掉背景颜色，因为如果是png图片，就会显示灰色的背景\nconst backgroundStyle = ref<Record<string, any>>({});\n\n// 监听src变化，处理加载状态\nwatch(\n    () => props.src,\n    n => {\n        if (!n) {\n            // 如果传入null或者''，或者false，或者undefined，标记为错误状态\n            isError.value = true;\n            loading.value = false;\n        } else {\n            isError.value = false;\n            loading.value = true;\n        }\n    },\n    { immediate: true }\n);\n\n/**\n * 计算图片外层包裹样式\n * @returns {Record<string, any>}\n */\nconst wrapStyle = computed(() => {\n    let style: Record<string, any> = {};\n    // 通过调用addUnit()方法，如果有单位，如百分比，px单位等，直接返回，如果是纯粹的数值，则加上rpx单位\n    style.width = $u.addUnit(props.width);\n    style.height = $u.addUnit(props.height);\n    // 如果是配置了圆形，设置50%的圆角，否则按照默认的配置值\n    style.borderRadius = props.shape === 'circle' ? '50%' : $u.addUnit(props.borderRadius);\n    // 如果设置圆角，必须要有hidden，否则可能圆角无效\n    style.overflow = Number(props.borderRadius) > 0 ? 'hidden' : 'visible';\n    if (props.fade) {\n        style.opacity = opacity.value;\n        style.transition = `opacity ${Number(durationTime.value) / 1000}s ease-in-out`;\n    }\n    return style;\n});\n\n/**\n * 点击图片\n * @emits click\n */\nfunction onClick() {\n    emit('click');\n}\n\n/**\n * 图片加载失败\n * @param err 失败事件对象\n * @emits error\n */\nfunction onErrorHandler(err: any) {\n    loading.value = false;\n    isError.value = true;\n    emit('error', err);\n}\n\n/**\n * 图片加载完成，标记loading结束\n * @emits load\n */\nfunction onLoadHandler() {\n    loading.value = false;\n    isError.value = false;\n    emit('load');\n    // 如果不需要动画效果，就不执行下方代码，同时移除加载时的背景颜色\n    // 否则无需fade效果时，png图片依然能看到下方的背景色\n    if (!props.fade) return removeBgColor();\n    // 原来opacity为1(不透明，是为了显示占位图)，改成0(透明，意味着该元素显示的是背景颜色，默认的灰色)，再改成1，是为了获得过渡效果\n    opacity.value = 0;\n    // 这里设置为0，是为了图片展示到背景全透明这个过程时间为0，延时之后延时之后重新设置为duration，是为了获得背景透明(灰色)\n    // 到图片展示的过程中的淡入效果\n    durationTime.value = 0;\n    // 延时50ms，否则在浏览器H5，过渡效果无效\n    setTimeout(() => {\n        durationTime.value = props.duration;\n        opacity.value = 1;\n        setTimeout(() => {\n            removeBgColor();\n        }, Number(durationTime.value));\n    }, 50);\n}\n\n/**\n * 移除图片的背景色\n * 淡入动画过渡完成后，将背景设置为透明色，否则png图片会看到灰色的背景\n */\nfunction removeBgColor() {\n    backgroundStyle.value = {\n        backgroundColor: 'transparent'\n    };\n}\n\nfunction changeStatus(status: 'loading' | 'error' | 'normal') {\n    if (status === 'loading') {\n        loading.value = true;\n        isError.value = false;\n    } else if (status === 'error') {\n        loading.value = false;\n        isError.value = true;\n    } else {\n        loading.value = false;\n        isError.value = false;\n    }\n}\n\n// 暴露给模板\nconst $slots = useSlots();\n\nfunction hasSlot(name: string) {\n    return props.useSlots ? !!$slots[name] && props.useSlots[name] : !!$slots[name];\n}\n\ndefineExpose<ImageExpose>({\n    changeStatus\n});\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n\n.u-image {\n    position: relative;\n    transition: opacity 0.5s ease-in-out;\n\n    &__image {\n        width: 100%;\n        height: 100%;\n    }\n\n    &__loading,\n    &__error {\n        position: absolute;\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 100%;\n        @include vue-flex;\n        align-items: center;\n        justify-content: center;\n        background-color: $u-bg-color;\n        color: $u-tips-color;\n        font-size: 46rpx;\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-index-anchor/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\n/**\n * u-index-anchor 组件 Props 类型定义\n * @description 索引锚点属性\n */\nexport const IndexAnchorProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 是否使用自定义内容的插槽 */\n    useSlot: { type: Boolean, default: false },\n    /** 索引字符，如果定义了use-slot，此参数自动失效 */\n    index: { type: String, default: '' }\n};\n\nexport type IndexAnchorProps = ExtractPropTypes<typeof IndexAnchorProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-index-anchor/u-index-anchor.vue",
    "content": "<template>\n    <!-- 支付宝小程序使用$u.getRect()获取组件的根元素尺寸，所以在外面套一个\"壳\" -->\n    <view>\n        <view class=\"u-index-anchor-wrapper\" :id=\"$u.guid()\" :style=\"wrapperStyle\">\n            <view\n                class=\"u-index-anchor\"\n                :class=\"[active ? 'u-index-anchor--active' : '', customClass]\"\n                :style=\"$u.toStyle(anchorStyle, customStyle)\"\n            >\n                <slot v-if=\"useSlot\" />\n                <template v-else>\n                    <text>{{ index }}</text>\n                </template>\n            </view>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-index-anchor',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { IndexAnchorProps } from './types';\nimport { ref, onMounted } from 'vue';\nimport { $u, useChildren } from '../..';\n\n/**\n * indexAnchor 索引列表锚点\n * @description 通过折叠面板收纳内容区域,搭配<u-index-anchor>使用\n * @tutorial https://uviewpro.cn/zh/components/indexList.html#indexanchor-props\n * @property {Boolean} use-slot 是否使用自定义内容的插槽（默认false）\n * @property {String|Number} index 索引字符，如果定义了use-slot，此参数自动失效\n * @property {Object} customStyle 自定义样式，对象形式，如\"{color: 'red'}\"\n * @event {Function} default 锚点位置显示内容，默认为索引字符\n * @example <u-index-anchor :index=\"item\" />\n */\n\nconst props = defineProps(IndexAnchorProps);\nconst { parentExposed } = useChildren('u-index-anchor', 'u-index-list');\n\n// 响应式变量\nconst active = ref(false);\nconst wrapperStyle = ref<Record<string, any>>({});\nconst anchorStyle = ref<Record<string, any>>({});\nconst top = ref(0);\nconst height = ref(0);\n\n// 挂载时查找父组件并注册\nonMounted(() => {\n    if (parentExposed) {\n        parentExposed?.value?.updateData();\n    }\n});\n\nfunction setTop(val: any) {\n    top.value = val;\n}\n\nfunction setHeight(val: any) {\n    height.value = val;\n}\n\nfunction setActive(val: any) {\n    active.value = val;\n}\n\nfunction setAnchorStyle(val: any) {\n    anchorStyle.value = val;\n}\n\nfunction setWrapperStyle(val: any) {\n    wrapperStyle.value = val;\n}\n\ndefineExpose({\n    props,\n    top,\n    height,\n    active,\n    wrapperStyle,\n    anchorStyle,\n    setTop,\n    setHeight,\n    setActive,\n    setAnchorStyle,\n    setWrapperStyle\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-index-anchor {\n    box-sizing: border-box;\n    padding: 14rpx 24rpx;\n    color: var(--u-content-color);\n    width: 100%;\n    font-weight: 500;\n    font-size: 28rpx;\n    line-height: 1.2;\n    background-color: $u-bg-color;\n}\n\n.u-index-anchor--active {\n    right: 0;\n    left: 0;\n    color: $u-type-primary;\n    background-color: var(--u-bg-white);\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-index-list/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport { getColor } from '../../';\n\n/**\n * u-index-list 组件 props 类型定义\n * @description 通过折叠面板收纳内容区域,搭配<u-index-anchor>使用\n */\nexport const IndexListProps = {\n    /** 是否开启锚点自动吸顶 */\n    sticky: {\n        type: Boolean,\n        default: true\n    },\n    /** 锚点吸顶时的层级 */\n    zIndex: {\n        type: [Number, String] as PropType<number | string>,\n        default: ''\n    },\n    /** 当前滚动高度 */\n    scrollTop: {\n        type: [Number, String] as PropType<number | string>,\n        default: 0\n    },\n    /** 锚点自动吸顶时与顶部的距离 */\n    offsetTop: {\n        type: [Number, String] as PropType<number | string>,\n        default: 0\n    },\n    /** 索引字符列表 */\n    indexList: {\n        type: Array as PropType<string[]>,\n        default: undefined // 组件内用 getIndexList() 兜底\n    },\n    /** 锚点和右边索引字符高亮颜色 */\n    activeColor: {\n        type: String,\n        default: () => getColor('primary')\n    }\n};\n\n/**\n * u-index-list 组件 props 类型\n */\nexport type IndexListProps = ExtractPropTypes<typeof IndexListProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-index-list/u-index-list.vue",
    "content": "<template>\n    <!-- 支付宝小程序使用$u.getRect()获取组件的根元素尺寸，所以在外面套一个\"壳\" -->\n    <view>\n        <view class=\"u-index-bar\">\n            <slot />\n            <view\n                v-if=\"showSidebar\"\n                class=\"u-index-bar__sidebar\"\n                @touchstart.stop.prevent=\"onTouchMove\"\n                @touchmove.stop.prevent=\"onTouchMove\"\n                @touchend.stop.prevent=\"onTouchStop\"\n                @touchcancel.stop.prevent=\"onTouchStop\"\n            >\n                <view\n                    v-for=\"(item, index) in indexList\"\n                    :key=\"index\"\n                    class=\"u-index-bar__index\"\n                    :style=\"{ zIndex: Number(zIndex) + 1, color: activeAnchorIndex === index ? activeColor : '' }\"\n                    :data-index=\"index\"\n                >\n                    {{ item }}\n                </view>\n            </view>\n            <view\n                class=\"u-indexed-list-alert\"\n                v-if=\"touchmove && indexList[touchmoveIndex]\"\n                :style=\"{\n                    zIndex: alertZIndex\n                }\"\n            >\n                <text>{{ indexList[touchmoveIndex] }}</text>\n            </view>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-index-list',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, reactive, computed, watch, onMounted, getCurrentInstance } from 'vue';\nimport { $u, useParent } from '../..';\nimport { IndexListProps } from './types';\n\n/**\n * indexList 索引列表\n * @description 通过折叠面板收纳内容区域,搭配<u-index-anchor>使用\n * @tutorial https://uviewpro.cn/zh/components/indexList.html#indexanchor-props\n * @property {Number|String} scroll-top 当前滚动高度，自定义组件无法获得滚动条事件，所以依赖接入方传入\n * @property {Array} index-list 索引字符列表，数组（默认A-Z）\n * @property {Number|String} z-index 锚点吸顶时的层级（默认965）\n * @property {Boolean} sticky 是否开启锚点自动吸顶（默认true）\n * @property {Number|String} offset-top 锚点自动吸顶时与顶部的距离（默认0）\n * @property {String} highlight-color 锚点和右边索引字符高亮颜色（默认主题色primary）\n * @event {Function} select 选中右边索引字符时触发\n * @example <u-index-list :scrollTop=\"scrollTop\"></u-index-list>\n */\nconst props = defineProps(IndexListProps);\nconst emit = defineEmits(['select']);\nconst instance = getCurrentInstance();\n\n// 索引列表生成函数\nfunction getIndexList() {\n    const indexList: string[] = [];\n    const charCodeOfA = 'A'.charCodeAt(0);\n    for (let i = 0; i < 26; i++) {\n        indexList.push(String.fromCharCode(charCodeOfA + i));\n    }\n    return indexList;\n}\n\n// 变量定义\nconst activeAnchorIndex = ref(0);\nconst showSidebar = ref(true);\nconst touchmove = ref(false);\nconst touchmoveIndex = ref(0);\nconst sidebar = reactive<{ height: number; top: number }>({ height: 0, top: 0 });\nconst scrollToAnchorIndex = ref<number | null>(null);\nconst timer = ref<any>(null);\nconst top = ref(0);\nconst height = ref(0);\nconst stickyOffsetTop = ref(0);\n\n// 计算属性\n// 弹出toast的z-index值\nconst alertZIndex = computed(() => $u.zIndex.toast).value;\n// indexList 响应式\nconst indexList = computed(() => props?.indexList ?? getIndexList());\nconst zIndex = computed(() => props.zIndex).value;\nconst activeColor = computed(() => props.activeColor).value;\n\nconst { children, broadcast } = useParent('u-index-anchor');\n\n// 兼容 H5/非H5 stickyOffsetTop\nonMounted(() => {\n    const offsetTopNum = typeof props.offsetTop === 'string' ? Number(props.offsetTop) : props.offsetTop;\n    // #ifdef H5\n    stickyOffsetTop.value = offsetTopNum ? uni.upx2px(offsetTopNum) : 44;\n    // #endif\n    // #ifndef H5\n    stickyOffsetTop.value = offsetTopNum ? uni.upx2px(offsetTopNum) : 0;\n    // #endif\n});\n\n// 监听 scrollTop\nwatch(\n    () => props.scrollTop,\n    () => {\n        updateData();\n    }\n);\n\nfunction updateData() {\n    if (timer.value) clearTimeout(timer.value);\n    timer.value = setTimeout(() => {\n        showSidebar.value = !!children.length;\n        setRect().then(() => {\n            onScroll();\n        });\n    }, 0);\n}\n\n/**\n * 获取各区域尺寸\n */\nfunction setRect() {\n    return Promise.all([setAnchorsRect(), setListRect(), setSiderbarRect()]);\n}\n\n/**\n * 获取锚点尺寸\n */\nfunction setAnchorsRect() {\n    return Promise.all(\n        children.map((anchor, index) => {\n            $u.getRect('.u-index-anchor-wrapper', anchor.getInstance()).then((rect: any) => {\n                broadcast('setTop', rect.top, anchor.id);\n                broadcast('setHeight', rect.height, anchor.id);\n            });\n        })\n    );\n}\n\n/**\n * 获取列表尺寸\n */\nfunction setListRect() {\n    return $u.getRect('.u-index-bar', instance).then((rect: any) => {\n        height.value = rect.height;\n        top.value = rect.top + Number(props.scrollTop);\n    });\n}\n\n/**\n * 获取侧边栏尺寸\n */\nfunction setSiderbarRect() {\n    return $u.getRect('.u-index-bar__sidebar', instance).then((rect: any) => {\n        sidebar.height = rect.height;\n        sidebar.top = rect.top;\n    });\n}\n\n/**\n * 获取当前激活锚点索引\n */\nfunction getActiveAnchorIndex() {\n    const sticky = props.sticky;\n    for (let i = children.length - 1; i >= 0; i--) {\n        const preAnchorHeight = i > 0 ? children[i - 1].getExposed().height.value : 0;\n        const reachTop = sticky ? preAnchorHeight : 0;\n        if (reachTop >= children[i].getExposed().top.value) {\n            return i;\n        }\n    }\n    return -1;\n}\n\n/**\n * 滚动时处理锚点吸顶和样式\n */\nfunction onScroll() {\n    if (!children.length) return;\n    const sticky = props.sticky;\n    const scrollTopNum = Number(props.scrollTop);\n    const active = getActiveAnchorIndex();\n    activeAnchorIndex.value = active;\n    if (sticky) {\n        let isActiveAnchorSticky = false;\n        if (active !== -1) {\n            isActiveAnchorSticky = children[active].getExposed().top.value <= 0;\n        }\n        children.forEach((item, index) => {\n            if (index === active) {\n                let wrapperStyle: any = '';\n                let anchorStyle: any = {\n                    color: `${activeColor}`\n                };\n                if (isActiveAnchorSticky) {\n                    wrapperStyle = { height: `${children[index].getExposed().height.value}px` };\n                    anchorStyle = {\n                        position: 'fixed',\n                        top: `${stickyOffsetTop.value}px`,\n                        zIndex: `${zIndex ? zIndex : $u.zIndex.indexListSticky}`,\n                        color: `${activeColor}`\n                    };\n                }\n                broadcast('setActive', active, item.id);\n                broadcast('setAnchorStyle', anchorStyle, item.id);\n                broadcast('setWrapperStyle', wrapperStyle, item.id);\n            } else if (index === active - 1) {\n                const currentAnchor = children[index];\n                const currentOffsetTop = currentAnchor.getExposed().top.value;\n                const targetOffsetTop =\n                    index === children.length - 1 ? top.value : children[index + 1].getExposed().top.value;\n                const parentOffsetHeight = targetOffsetTop - currentOffsetTop;\n                const translateY = parentOffsetHeight - currentAnchor.getExposed().height.value;\n                const anchorStyle = {\n                    position: 'relative',\n                    transform: `translate3d(0, ${translateY}px, 0)`,\n                    zIndex: `${zIndex ? zIndex : $u.zIndex.indexListSticky}`,\n                    color: `${activeColor}`\n                };\n                broadcast('setActive', active, currentAnchor.id);\n                broadcast('setAnchorStyle', anchorStyle, currentAnchor.id);\n                broadcast('setWrapperStyle', '', item.id);\n            } else {\n                broadcast('setActive', false, item.id);\n                broadcast('setAnchorStyle', '', item.id);\n                broadcast('setWrapperStyle', '', item.id);\n            }\n        });\n    }\n}\n\n/**\n * 侧边栏触摸移动\n */\nfunction onTouchMove(event: TouchEvent) {\n    touchmove.value = true;\n    const sidebarLength = children.length;\n    const touch = event.touches[0];\n    const itemHeight = sidebar.height / sidebarLength;\n    let clientY = touch.clientY;\n    let index = Math.floor((clientY - sidebar.top) / itemHeight);\n    if (index < 0) {\n        index = 0;\n    } else if (index > sidebarLength - 1) {\n        index = sidebarLength - 1;\n    }\n    touchmoveIndex.value = index;\n    scrollToAnchor(index);\n}\n\n/**\n * 侧边栏触摸结束\n */\nfunction onTouchStop() {\n    touchmove.value = false;\n    scrollToAnchorIndex.value = null;\n}\n\n/**\n * 滚动到指定锚点\n */\nfunction scrollToAnchor(index: number) {\n    if (scrollToAnchorIndex.value === index) {\n        return;\n    }\n    scrollToAnchorIndex.value = index;\n    const anchor = children.find(item => item.getExposed().props.index === indexList.value[index]);\n    if (anchor) {\n        emit('select', anchor.getExposed().props.index);\n        uni.pageScrollTo({\n            duration: 0,\n            scrollTop: anchor.getExposed().top.value + Number(props.scrollTop)\n        });\n    }\n}\n\ndefineExpose({\n    updateData,\n    setRect,\n    onScroll,\n    children\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-index-bar {\n    position: relative;\n}\n\n.u-index-bar__sidebar {\n    position: fixed;\n    top: 50%;\n    right: 0;\n    @include vue-flex;\n    flex-direction: column;\n    text-align: center;\n    transform: translateY(-50%);\n    user-select: none;\n    z-index: 99;\n}\n\n.u-index-bar__index {\n    font-weight: 500;\n    padding: 8rpx 18rpx;\n    font-size: 22rpx;\n    line-height: 1;\n}\n\n.u-indexed-list-alert {\n    position: fixed;\n    width: 120rpx;\n    height: 120rpx;\n    right: 90rpx;\n    top: 50%;\n    margin-top: -60rpx;\n    border-radius: 24rpx;\n    font-size: 50rpx;\n    color: var(--u-white-color);\n    background-color: rgba(0, 0, 0, 0.65);\n    @include vue-flex;\n    justify-content: center;\n    align-items: center;\n    padding: 0;\n    z-index: 9999999;\n}\n\n.u-indexed-list-alert text {\n    line-height: 50rpx;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-input/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { InputAlign, InputConfirmType, InputType, SizeType } from '../../types/global';\nimport { useLocale } from '../../';\n\nconst { t } = useLocale();\n\n/**\n * u-input 组件 props 类型定义\n * @description 此组件为一个输入框，默认没有边框和样式，是专门为配合表单组件u-form而设计的，利用它可以快速实现表单验证，输入内容，下拉选择等功能。\n */\n\nexport const InputProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 用于双向绑定输入框的值 */\n    modelValue: {\n        type: [String, Number] as PropType<string | number>,\n        default: ''\n    },\n    /** 输入框的类型，textarea，text，number */\n    type: {\n        type: String as PropType<InputType>,\n        default: 'text'\n    },\n    /** 输入框文字的对齐方式(默认left) */\n    inputAlign: {\n        type: String as PropType<InputAlign>,\n        default: 'left'\n    },\n    /** 输入框文字的大小(默认default)，支持 small/default/large 预设值，也支持 16/16px/16rpx 等自定义值 */\n    size: {\n        type: [String, Number] as PropType<SizeType | string | number>,\n        default: ''\n    },\n    /** placeholder显示值(默认 '请输入内容') */\n    placeholder: {\n        type: String,\n        default: () => t('uInput.placeholder')\n    },\n    /** 是否禁用输入框(默认false) */\n    disabled: {\n        type: Boolean,\n        default: false\n    },\n    /** 输入框的最大可输入长度(默认140) */\n    maxlength: {\n        type: [Number, String] as PropType<number | string>,\n        default: 140\n    },\n    // 是否显示统计字数，仅textarea有效\n    count: {\n        type: Boolean,\n        default: false\n    },\n    /** placeholder的样式，字符串形式，如\"color: red;\"(默认 \"color: var(--u-light-color);\") */\n    placeholderStyle: {\n        type: String,\n        default: 'color: var(--u-light-color);'\n    },\n    /** 设置键盘右下角按钮的文字，仅在type为text时生效(默认done) */\n    confirmType: {\n        type: String as PropType<InputConfirmType>,\n        default: 'done'\n    },\n    /** 如果 textarea 是在一个 position:fixed 的区域，需要显示指定属性 fixed 为 true */\n    fixed: {\n        type: Boolean,\n        default: false\n    },\n    /** 是否自动获得焦点(默认false) */\n    focus: {\n        type: Boolean,\n        default: false\n    },\n    /** 密码类型时，是否显示右侧的密码图标(默认true) */\n    passwordIcon: {\n        type: Boolean,\n        default: true\n    },\n    /** input|textarea是否显示边框(默认false) */\n    border: {\n        type: Boolean,\n        default: false\n    },\n    /** 输入框的边框颜色(默认var(--u-border-color)) */\n    borderColor: {\n        type: String,\n        default: 'var(--u-border-color)'\n    },\n    /** 是否自动增高输入区域，type为textarea时有效(默认true) */\n    autoHeight: {\n        type: Boolean,\n        default: true\n    },\n    /** type=select时，旋转右侧的图标，标识当前处于打开还是关闭select的状态 */\n    selectOpen: {\n        type: Boolean,\n        default: false\n    },\n    /** 高度，单位rpx */\n    height: {\n        type: [Number, String] as PropType<number | string>,\n        default: ''\n    },\n    /** 是否可清空(默认true) */\n    clearable: {\n        type: Boolean,\n        default: true\n    },\n    /** 指定光标与键盘的距离，单位 px(默认0) */\n    cursorSpacing: {\n        type: [Number, String] as PropType<number | string>,\n        default: 0\n    },\n    /** 光标起始位置，自动聚焦时有效，需与selection-end搭配使用（默认-1） */\n    selectionStart: {\n        type: [Number, String] as PropType<number | string>,\n        default: -1\n    },\n    /** 光标结束位置，自动聚焦时有效，需与selection-start搭配使用（默认-1） */\n    selectionEnd: {\n        type: [Number, String] as PropType<number | string>,\n        default: -1\n    },\n    /** 是否自动去除两端的空格(默认true) */\n    trim: {\n        type: Boolean,\n        default: true\n    },\n    /** 是否显示键盘上方带有”完成“按钮那一栏(默认true) */\n    showConfirmbar: {\n        type: Boolean,\n        default: true\n    },\n    /** 弹出键盘时是否自动调节高度，uni-app默认值是true */\n    adjustPosition: {\n        type: Boolean,\n        default: true\n    },\n    /** 输入框的验证状态，用于错误时，边框是否改为红色 */\n    validateState: {\n        type: Boolean,\n        default: false\n    }\n};\n\n/**\n * u-input 组件 props 类型\n */\nexport type InputProps = ExtractPropTypes<typeof InputProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-input/u-input.vue",
    "content": "<template>\n    <view\n        class=\"u-input\"\n        :class=\"[\n            {\n                'u-input--border': border,\n                'u-input--error': validateState\n            },\n            customClass\n        ]\"\n        :style=\"{\n            padding: type === 'textarea' ? (border ? '20rpx' : '0') : `0 ${border ? 20 : 0}rpx`,\n            borderColor: borderColor,\n            textAlign: inputAlign\n        }\"\n        @tap.stop=\"inputClick\"\n    >\n        <textarea\n            v-if=\"type == 'textarea'\"\n            class=\"u-input__input u-input__textarea\"\n            :style=\"getStyle\"\n            :value=\"inputValue\"\n            :placeholder=\"placeholder\"\n            :placeholderStyle=\"getPlaceholderStyle\"\n            :disabled=\"disabled\"\n            :maxlength=\"inputMaxlength\"\n            :fixed=\"fixed\"\n            :focus=\"focus\"\n            :autoHeight=\"autoHeight\"\n            :selection-end=\"Number(uSelectionEnd)\"\n            :selection-start=\"Number(uSelectionStart)\"\n            :cursor-spacing=\"getCursorSpacing\"\n            :show-confirm-bar=\"showConfirmbar\"\n            :adjust-position=\"adjustPosition\"\n            @input=\"handleInput\"\n            @blur=\"handleBlur\"\n            @focus=\"onFocus\"\n            @confirm=\"onConfirm\"\n        />\n        <!-- prettier-ignore -->\n        <input\n            v-else\n            class=\"u-input__input\"\n            :type=\"((type == 'password' ? 'text' : type) as any)\"\n            :style=\"getStyle\"\n            :value=\"inputValue\"\n            :password=\"type == 'password' && !showPassword\"\n            :placeholder=\"placeholder\"\n            :placeholderStyle=\"getPlaceholderStyle\"\n            :disabled=\"disabled || type === 'select'\"\n            :maxlength=\"inputMaxlength\"\n            :focus=\"focus\"\n            :confirmType=\"confirmType\"\n            :cursor-spacing=\"getCursorSpacing\"\n            :selection-end=\"Number(uSelectionEnd)\"\n            :selection-start=\"Number(uSelectionStart)\"\n            :show-confirm-bar=\"showConfirmbar\"\n            :adjust-position=\"adjustPosition\"\n            @focus=\"onFocus\"\n            @blur=\"handleBlur\"\n            @input=\"handleInput\"\n            @confirm=\"onConfirm\"\n        />\n        <view class=\"u-input__select-overlay\" v-if=\"type === 'select'\" @tap.stop=\"inputClick\"></view>\n        <view class=\"u-input__right-icon u-flex\">\n            <view\n                class=\"u-input__right-icon__clear u-input__right-icon__item\"\n                v-if=\"clearable && inputValue !== '' && !disabled\"\n                :style=\"{ marginLeft: $u.addUnit(iconSpacing) }\"\n                :class=\"{ 'u-hidden': !focused && type !== 'select' }\"\n                @click.stop=\"onClear\"\n            >\n                <u-icon :size=\"currentIconSize\" name=\"close-circle-fill\" color=\"var(--u-light-color)\" />\n            </view>\n            <view\n                class=\"u-input__right-icon__clear u-input__right-icon__item\"\n                v-if=\"passwordIcon && type == 'password'\"\n                :style=\"{ marginLeft: $u.addUnit(iconSpacing) }\"\n            >\n                <u-icon\n                    :size=\"currentIconSize\"\n                    :name=\"!showPassword ? 'eye' : 'eye-fill'\"\n                    color=\"var(--u-light-color)\"\n                    @click=\"showPassword = !showPassword\"\n                />\n            </view>\n            <view\n                class=\"u-input__right-icon--select u-input__right-icon__item\"\n                v-if=\"type == 'select'\"\n                :class=\"{\n                    'u-input__right-icon--select--reverse': selectOpen\n                }\"\n                :style=\"{ marginLeft: $u.addUnit(iconSpacing) }\"\n            >\n                <u-icon name=\"arrow-down-fill\" :size=\"selectIconSize\" color=\"var(--u-light-color)\"></u-icon>\n            </view>\n        </view>\n        <text\n            class=\"u-input__count\"\n            :style=\"{\n                'background-color': props.disabled ? 'transparent' : 'var(--u-bg-white)'\n            }\"\n            v-if=\"props.type === 'textarea' && props.count\"\n        >\n            {{ inputValue.length }}/{{ props.maxlength }}\n        </text>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-input',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch } from 'vue';\nimport { $u, useChildren } from '../..';\nimport { InputProps } from './types';\nimport type { SizeType } from '../../types/global';\n\nconst props = defineProps(InputProps);\nconst emit = defineEmits(['update:modelValue', 'input', 'blur', 'focus', 'confirm', 'click']);\n\nconst { emitToParent } = useChildren('u-input', 'u-form-item');\nconst { parentExposed } = useChildren('u-input', 'u-form');\n\nconst validateState = ref(props.validateState); // 当前input的验证状态，用于错误时，边框是否改为红色\nconst focused = ref(false); // 当前是否处于获得焦点的状态\nconst showPassword = ref(false); // 是否预览密码\nconst lastValue = ref(''); // 用于头条小程序，判断@input中，前后的值是否发生了变化\n\n// 根据 size 定义不同的配置\nconst sizeConfig = {\n    small: {\n        inputHeight: 56,\n        textareaHeight: 70,\n        fontSize: 24,\n        iconSize: 28,\n        iconSpacing: 6\n    },\n    default: {\n        inputHeight: 70,\n        textareaHeight: 100,\n        fontSize: 28,\n        iconSize: 32,\n        iconSpacing: 10\n    },\n    large: {\n        inputHeight: 84,\n        textareaHeight: 130,\n        fontSize: 32,\n        iconSize: 36,\n        iconSpacing: 14\n    }\n};\n\n// 获取实际使用的 size 值（优先级：props.size > u-form.size）\nconst actualSize = computed(() => {\n    // 优先使用 props 的 size 属性\n    if (props.size !== '') {\n        return String(props.size);\n    }\n    // 次优先：使用 u-form 的 size 属性（u-form 的 size 只支持预设值）\n    if (parentExposed.value?.props?.size) {\n        return String(parentExposed.value.props.size);\n    }\n    // 默认值\n    return 'default';\n});\n\n// 判断实际使用的 size 是否在预设配置中\nconst isInSizeConfig = computed(() => actualSize.value in sizeConfig);\n\n// 获取预设 size（用于查找 sizeConfig 配置，如图标大小、高度等）\nconst presetSize = computed(() => {\n    return (isInSizeConfig.value ? actualSize.value : 'default') as SizeType;\n});\n\n// 获取当前尺寸配置\nconst currentSizeConfig = computed(() => sizeConfig[presetSize.value]);\n\n// 获取实际要使用的 font-size（如果是预设值使用配置值，否则作为自定义值处理）\nconst actualFontSize = computed(() => {\n    if (isInSizeConfig.value) {\n        return $u.addUnit(currentSizeConfig.value.fontSize);\n    }\n    // 自定义size值，直接作为fontSize处理\n    return $u.addUnit(actualSize.value);\n});\n\n// 计算当前图标大小\nconst currentIconSize = computed(() => currentSizeConfig.value.iconSize);\n\n// 计算 select 图标大小（比常规图标稍小）\nconst selectIconSize = computed(() => currentSizeConfig.value.iconSize - 4);\n\n// 计算图标间距\nconst iconSpacing = computed(() => currentSizeConfig.value.iconSpacing);\n\nconst inputValue = computed<string>(() => {\n    if (props.modelValue === undefined || props.modelValue === null) return '';\n    return String(props.modelValue);\n});\n\n// 监听 value 变化\nwatch(\n    () => inputValue.value,\n    (nVal, oVal) => {\n        // 当值发生变化，且为select类型时(此时input被设置为disabled，不会触发@input事件)，模拟触发@input事件\n        if (nVal != oVal && props.type == 'select') handleInput({ detail: { value: nVal } });\n    }\n);\n\n// 监听 validateState 变化\nwatch(\n    () => props.validateState,\n    val => {\n        validateState.value = val;\n    }\n);\n\n// 计算属性\nconst inputMaxlength = computed(() => Number(props.maxlength));\n\nconst getStyle = computed(() => {\n    let style: Record<string, any> = {};\n    // 如果没有自定义高度，就根据type为input还是textarea来分配一个默认的高度\n    style.minHeight = props.height\n        ? $u.addUnit(props.height)\n        : props.type === 'textarea'\n          ? $u.addUnit(currentSizeConfig.value.textareaHeight)\n          : $u.addUnit(currentSizeConfig.value.inputHeight);\n    // 根据 size 属性设置字体大小\n    style.fontSize = actualFontSize.value;\n    return $u.toStyle(style, props.customStyle);\n});\n\nconst getPlaceholderStyle = computed(() => {\n    return $u.toStyle(\n        {\n            fontSize: actualFontSize.value\n        },\n        props.placeholderStyle\n    );\n});\n\n// 计算光标与键盘的距离\nconst getCursorSpacing = computed(() => Number(props.cursorSpacing));\n// 光标起始位置\nconst uSelectionStart = computed(() => String(props.selectionStart));\n// 光标结束位置\nconst uSelectionEnd = computed(() => String(props.selectionEnd));\n\n/**\n * change 事件\n * @param event\n */\nfunction handleInput(event: any) {\n    let value = event.detail.value;\n    // 判断是否去除空格\n    if (props.trim) value = $u.trim(value);\n    emit('update:modelValue', value);\n    emit('input', value);\n    // 过一个生命周期再发送事件给u-form-item，否则this.$emit('update:modelValue')更新了父组件的值，但是微信小程序上\n    // 尚未更新到u-form-item，导致获取的值为空，从而校验混论\n    // 这里不能延时时间太短，或者使用this.$nextTick，否则在头条上，会造成混乱\n    setTimeout(() => {\n        // 头条小程序由于自身bug，导致中文下，每按下一个键(尚未完成输入)，都会触发一次@input，导致错误，这里进行判断处理\n        // #ifdef MP-TOUTIAO\n        if ($u.trim(value) == lastValue.value) return;\n        lastValue.value = value;\n        // #endif\n        // 通过 emitter 派发事件\n        emitToParent('onFormChange', value);\n    }, 40);\n}\n\n/**\n * blur 事件\n * @param event\n */\nfunction handleBlur(event: any) {\n    // 最开始使用的是监听图标@touchstart事件，自从hx2.8.4后，此方法在微信小程序出错\n    // 这里改为监听点击事件，手点击清除图标时，同时也发生了@blur事件，导致图标消失而无法点击，这里做一个延时\n    setTimeout(() => {\n        focused.value = false;\n    }, 100);\n    setTimeout(() => {\n        let value = inputValue.value;\n        emit('blur', value);\n        // 头条小程序由于自身bug，导致中文下，每按下一个键(尚未完成输入)，都会触发一次@input，导致错误，这里进行判断处理\n        // #ifdef MP-TOUTIAO\n        if ($u.trim(value) == lastValue.value) return;\n        lastValue.value = value;\n        // #endif\n        emitToParent('onFormBlur', value);\n    }, 40);\n}\n\nfunction onFormItemError(status: boolean) {\n    validateState.value = status;\n}\n\nfunction onFocus(e: any) {\n    focused.value = true;\n    emit('focus', e.detail.value);\n}\n\nfunction onConfirm(e: any) {\n    emit('confirm', e.detail.value);\n}\n\nfunction onClear(event: any) {\n    try {\n        event.stopPropagation();\n    } catch (e) {\n        console.log(e);\n    }\n    handleInput({ detail: { value: '' } });\n}\n\nfunction inputClick() {\n    emit('click');\n}\n\ndefineExpose({\n    onFormItemError\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-input {\n    position: relative;\n    flex: 1;\n    @include vue-flex;\n    align-items: center;\n\n    &__select-overlay {\n        position: absolute;\n        inset: 0;\n        z-index: 1;\n    }\n\n    &__input {\n        //height: 70rpx;\n        font-size: 28rpx;\n        color: $u-main-color;\n        flex: 1;\n        align-self: center;\n        line-height: normal;\n    }\n\n    &__textarea {\n        width: auto;\n        font-size: 28rpx;\n        color: $u-main-color;\n        // padding: 10rpx 0;\n        line-height: normal;\n        flex: 1;\n    }\n\n    &__count {\n        position: absolute;\n        right: 1px;\n        bottom: 0;\n        font-size: 12px;\n        color: $u-tips-color;\n        background-color: var(--u-bg-white);\n        padding: 1px 4px;\n        border-radius: 10px;\n        line-height: 16px;\n        z-index: 2;\n    }\n\n    &--border {\n        border-radius: 4px;\n        border: 1px solid $u-border-color;\n    }\n\n    &--error {\n        border-color: $u-type-error !important;\n    }\n\n    &__right-icon {\n        position: relative;\n        z-index: 2;\n\n        &--select {\n            transition: transform 0.4s;\n\n            &--reverse {\n                transform: rotate(-180deg);\n            }\n        }\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-keyboard/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport { useLocale } from '../../';\n\nconst { t } = useLocale();\n\n/**\n * u-keyboard 组件 Props 类型定义\n * @description 自定义键盘面板属性\n */\nexport const KeyboardProps = {\n    /** 键盘的类型，number-数字键盘，card-身份证键盘，car-车牌号键盘 */\n    mode: { type: String, default: 'number' },\n    /** 是否显示键盘的\".\"符号 */\n    dotEnabled: { type: Boolean, default: true },\n    /** 是否显示顶部工具条 */\n    tooltip: { type: Boolean, default: true },\n    /** 是否显示工具条中间的提示 */\n    showTips: { type: Boolean, default: true },\n    /** 工具条中间的提示文字 */\n    tips: { type: String, default: '' },\n    /** 是否显示工具条左边的\"取消\"按钮 */\n    cancelBtn: { type: Boolean, default: true },\n    /** 是否显示工具条右边的\"完成\"按钮 */\n    confirmBtn: { type: Boolean, default: true },\n    /** 是否打乱键盘按键的顺序 */\n    random: { type: Boolean, default: false },\n    /** 是否开启底部安全区适配 */\n    safeAreaInsetBottom: { type: Boolean, default: false },\n    /** 是否允许通过点击遮罩关闭键盘 */\n    maskCloseAble: { type: Boolean, default: true },\n    /** 通过双向绑定控制键盘的弹出与收起 */\n    modelValue: { type: Boolean, default: false },\n    /** 是否显示遮罩 */\n    mask: { type: Boolean, default: true },\n    /** z-index值 */\n    zIndex: { type: [Number, String] as PropType<string | number>, default: '' },\n    /** 取消按钮的文字 */\n    cancelText: { type: String, default: () => t('uKeyboard.cancelText') },\n    /** 确认按钮的文字 */\n    confirmText: { type: String, default: () => t('uKeyboard.confirmText') }\n};\n\nexport type KeyboardProps = ExtractPropTypes<typeof KeyboardProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-keyboard/u-keyboard.vue",
    "content": "<template>\n    <u-popup\n        :mask=\"mask\"\n        :maskCloseAble=\"maskCloseAble\"\n        mode=\"bottom\"\n        :popup=\"false\"\n        v-model=\"popupValue\"\n        length=\"auto\"\n        :safeAreaInsetBottom=\"safeAreaInsetBottom\"\n        @close=\"popupClose\"\n        :zIndex=\"uZIndex\"\n    >\n        <slot />\n        <view class=\"u-tooltip\" v-if=\"tooltip\">\n            <view class=\"u-tooltip-item u-tooltip-cancel\" hover-class=\"u-tooltip-cancel-hover\" @tap=\"onCancel\">\n                {{ cancelBtn ? cancelText : '' }}\n            </view>\n            <view v-if=\"showTips\" class=\"u-tooltip-item u-tooltip-tips\">\n                {{\n                    tips\n                        ? tips\n                        : mode == 'number'\n                          ? t('uKeyboard.number')\n                          : mode == 'card'\n                            ? t('uKeyboard.idCard')\n                            : t('uKeyboard.plate')\n                }}\n            </view>\n            <view\n                v-if=\"confirmBtn\"\n                @tap=\"onConfirm\"\n                class=\"u-tooltip-item u-tooltips-submit\"\n                hover-class=\"u-tooltips-submit-hover\"\n            >\n                {{ confirmBtn ? confirmText : '' }}\n            </view>\n        </view>\n        <block v-if=\"mode == 'number' || mode == 'card'\">\n            <u-number-keyboard\n                :random=\"random\"\n                @backspace=\"backspace\"\n                @change=\"change\"\n                :mode=\"mode\"\n                :dotEnabled=\"dotEnabled\"\n            ></u-number-keyboard>\n        </block>\n        <block v-else>\n            <u-car-keyboard :random=\"random\" @backspace=\"backspace\" @change=\"change\"></u-car-keyboard>\n        </block>\n    </u-popup>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-keyboard',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { KeyboardProps } from './types';\nimport { computed } from 'vue';\nimport { $u, useLocale } from '../..';\n\n/**\n * keyboard 键盘\n * @description 此为uViw自定义的键盘面板，内含了数字键盘，车牌号键，身份证号键盘3中模式，都有可以打乱按键顺序的选项。\n * @tutorial https://uviewpro.cn/zh/components/keyboard.html\n * @property {String} mode 键盘类型，见官网基本使用的说明（默认number）\n * @property {Boolean} dot-enabled 是否显示\".\"按键，只在mode=number时有效（默认true）\n * @property {Boolean} tooltip 是否显示键盘顶部工具条（默认true）\n * @property {String} tips 工具条中间的提示文字，见上方基本使用的说明，如不需要，请传\"\"空字符\n * @property {Boolean} cancel-btn 是否显示工具条左边的\"取消\"按钮（默认true）\n * @property {Boolean} confirm-btn 是否显示工具条右边的\"完成\"按钮（默认true）\n * @property {Boolean} mask 是否显示遮罩（默认true）\n * @property {String} confirm-text 确认按钮的文字\n * @property {String} cancel-text 取消按钮的文字\n * @property {Number String} z-index 弹出键盘的z-index值（默认1075）\n * @property {Boolean} random 是否打乱键盘按键的顺序（默认false）\n * @property {Boolean} safe-area-inset-bottom 是否开启底部安全区适配（默认false）\n * @property {Boolean} mask-close-able 是否允许点击遮罩收起键盘（默认true）\n * @event {Function} change 按键被点击(不包含退格键被点击)\n * @event {Function} cancel 键盘顶部工具条左边的\"取消\"按钮被点击\n * @event {Function} confirm 键盘顶部工具条右边的\"完成\"按钮被点击\n * @event {Function} backspace 键盘退格键被点击\n * @example <u-keyboard mode=\"number\" v-model=\"show\"></u-keyboard>\n */\n\nconst props = defineProps(KeyboardProps);\nconst emit = defineEmits(['change', 'update:modelValue', 'confirm', 'cancel', 'backspace']);\n\nconst { t } = useLocale();\n\nconst uZIndex = computed(() => (props.zIndex ? props.zIndex : $u.zIndex.popup));\n\nconst popupValue = computed({\n    get: () => props.modelValue,\n    set: (val: boolean) => emit('update:modelValue', val)\n});\n\n/**\n * 按键被点击(不包含退格键被点击)\n */\nfunction change(e: any) {\n    emit('change', e);\n}\n\n/**\n * 键盘关闭\n */\nfunction popupClose() {\n    emit('update:modelValue', false);\n}\n\n/**\n * 输入完成\n */\nfunction onConfirm() {\n    popupClose();\n    emit('confirm');\n}\n\n/**\n * 取消输入\n */\nfunction onCancel() {\n    popupClose();\n    emit('cancel');\n}\n\n/**\n * 退格键\n */\nfunction backspace() {\n    emit('backspace');\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-keyboard {\n    position: relative;\n    z-index: 1003;\n}\n\n.u-tooltip {\n    @include vue-flex;\n    justify-content: space-between;\n}\n\n.u-tooltip-item {\n    color: var(--u-main-color);\n    flex: 0 0 30%;\n    text-align: center;\n    padding: 20rpx 10rpx;\n    font-size: 28rpx;\n}\n\n.u-tooltip-tips {\n    flex-basis: 40%;\n    word-break: break-all;\n}\n\n.u-tooltips-submit {\n    text-align: right;\n    flex-grow: 1;\n    flex-wrap: 0;\n    padding-right: 40rpx;\n    color: $u-type-primary;\n}\n\n.u-tooltip-cancel {\n    text-align: left;\n    flex-grow: 1;\n    flex-wrap: 0;\n    padding-left: 40rpx;\n    color: var(--u-tips-color);\n}\n\n.u-tooltips-submit-hover {\n    color: $u-type-success;\n}\n\n.u-tooltip-cancel-hover {\n    color: var(--u-main-color);\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-lazy-load/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { Effect, ImgMode } from '../../types/global';\n\n/**\n * u-lazy-load 组件 Props 类型定义\n * @description 懒加载图片组件属性\n */\nexport const LazyLoadProps = {\n    /** 用户自定义值，在事件触发时回调，用以区分是哪个图片 */\n    index: [Number, String],\n    /** 要显示的图片 */\n    image: { type: String, default: '' },\n    /** 图片裁剪模式 */\n    imgMode: { type: String as PropType<ImgMode>, default: 'widthFix' },\n    /** 占位图片路径 */\n    loadingImg: {\n        type: String,\n        default:\n            'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAMAAAC3Ycb+AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1zbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1zbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OUM0QjNBQjkyQUQ2MTFFQTlCNUQ4RTIzNDE5RUIxNjciIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OUM0QjNBQkEyQUQ2MTFFQTlCNUQ4RTIzNDE5RUIxNjciPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo5QzRCM0FCNzJBRDYxMUVBOUI1RDhFMjM0MTlFQjE2NyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo5QzRCM0FCODJBRDYxMUVBOUI1RDhFMjM0MTlFQjE2NyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PtRHfPcAAAAzUExURZWVldfX18PD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'\n    },\n    /** 加载失败的错误占位图 */\n    errorImg: { type: String },\n    /** 图片进入可见区域前多少像素时，单位rpx，开始加载图片 */\n    threshold: { type: [String, Number] as PropType<string | number>, default: 100 },\n    /** 淡入淡出动画的过渡时间 */\n    duration: { type: [String, Number] as PropType<string | number>, default: 500 },\n    /** 渡效果的速度曲线 */\n    effect: { type: String as PropType<Effect>, default: 'ease-in-out' },\n    /** 是否使用过渡效果 */\n    isEffect: { type: Boolean, default: true },\n    /** 圆角值 */\n    borderRadius: { type: [String, Number] as PropType<string | number>, default: 0 },\n    /** 图片高度，单位rpx */\n    height: { type: [String, Number] as PropType<string | number>, default: 450 }\n};\n\nexport type LazyLoadProps = ExtractPropTypes<typeof LazyLoadProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-lazy-load/u-lazy-load.vue",
    "content": "<template>\n    <view\n        class=\"u-wrap\"\n        :style=\"{\n            opacity: Number(opacity),\n            borderRadius: props.borderRadius + 'rpx',\n            // 因为time值需要改变,所以不直接用duration值(不能改变父组件prop传过来的值)\n            transition: `opacity ${Number(time) / 1000}s ${props.effect}`\n        }\"\n        :class=\"'u-lazy-item-' + elIndex\"\n    >\n        <view :class=\"'u-lazy-item-' + elIndex\">\n            <image\n                :style=\"{ borderRadius: props.borderRadius + 'rpx', height: imgHeight }\"\n                v-if=\"!isError\"\n                class=\"u-lazy-item\"\n                :src=\"isShow ? props.image : props.loadingImg\"\n                :mode=\"props.imgMode\"\n                @load=\"imgLoaded\"\n                @error=\"loadError\"\n                @tap=\"clickImg\"\n            ></image>\n            <image\n                :style=\"{ borderRadius: props.borderRadius + 'rpx', height: imgHeight }\"\n                class=\"u-lazy-item error\"\n                v-else\n                :src=\"props.errorImg\"\n                :mode=\"props.imgMode\"\n                @load=\"errorImgLoaded\"\n                @tap=\"clickImg\"\n            ></image>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-lazy-load',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { LazyLoadProps } from './types';\nimport { ref, computed, watch, onMounted, nextTick, getCurrentInstance } from 'vue';\nimport { $u } from '../..';\n\n/**\n * lazyLoad 懒加载\n * @description 懒加载使用的场景为：页面有很多图片时，APP会同时加载所有的图片，导致页面卡顿，各个位置的图片出现前后不一致等.\n * @tutorial https://uviewpro.cn/zh/components/lazyLoad.html\n * @property {String | Number} index 用户自定义值，在事件触发时回调，用以区分是哪个图片\n * @property {String} image 图片路径\n * @property {String} loading-img 预加载时的占位图\n * @property {String} error-img 图片加载出错时的占位图\n * @property {String | Number} threshold 触发加载时的位置，单位 rpx（默认300）\n * @property {String | Number} duration 图片加载成功时，淡入淡出时间，单位ms（默认）\n * @property {String} effect 图片加载成功时，淡入淡出的css动画效果（默认ease-in-out）\n * @property {Boolean} is-effect 图片加载成功时，是否启用淡入淡出效果（默认true）\n * @property {String | Number} border-radius 图片圆角值，单位rpx（默认0）\n * @property {String | Number} height 图片高度，注意：实际高度可能受img-mode参数影响（默认450）\n * @property {String} img-mode 图片的裁剪模式，详见image组件裁剪模式（默认widthFix）\n * @event {Function} click 点击图片时触发\n * @event {Function} load 图片加载成功时触发\n * @event {Function} error 图片加载失败时触发\n * @example <u-lazy-load :image=\"image\" :loading-img=\"loadingImg\" :error-img=\"errorImg\"></u-lazy-load>\n */\n\nconst emit = defineEmits(['click', 'load', 'error']);\n\nconst props = defineProps(LazyLoadProps);\n\nconst instance = getCurrentInstance();\n// 懒加载相关响应式变量\nconst isShow = ref(false);\nconst opacity = ref(1);\nconst time = ref(Number(props.duration));\nconst loadStatus = ref(''); // 默认是懒加载中的状态\nconst isError = ref(false); // 图片加载失败\nconst elIndex = ref('');\n\n// IntersectionObserver 实例\nlet contentObserver: any = null;\n\n/**\n * 将 threshold 从 rpx 转为 px\n */\nconst getThreshold = computed(() => {\n    // 先取绝对值，因为 threshold 可能是负数，最后根据 props.threshold 是正数或者负数，重新还原\n    const thresholdPx = uni.upx2px(Math.abs(Number(props.threshold)));\n    return Number(props.threshold) < 0 ? -thresholdPx : thresholdPx;\n});\n\n/**\n * 计算图片的高度，可能为 auto，带 %，或者直接数值\n */\nconst imgHeight = computed(() => {\n    return $u.addUnit(props.height);\n});\n\n// 监听 isShow 变化，处理淡入淡出动画\nwatch(isShow, nVal => {\n    // 如果是不开启过渡效果，直接返回\n    if (!props.isEffect) return;\n    time.value = 0;\n    // 原来opacity为1(不透明，是为了显示占位图)，改成0(透明，意味着该元素显示的是背景颜色，默认的白色)，再改成1，是为了获得过渡效果\n    opacity.value = 0;\n    // 延时30ms，否则在浏览器H5，过渡效果无效\n    setTimeout(() => {\n        time.value = Number(props.duration);\n        opacity.value = 1;\n    }, 30);\n});\n\n// 监听图片路径变化，重置状态，图片路径发生变化时，需要重新标记一些变量，否则会一直卡在某一个状态，比如isError\nwatch(\n    () => props.image,\n    n => {\n        if (!n) {\n            // 如果传入null或者''，或者undefined，标记为错误状态\n            isError.value = true;\n        } else {\n            init();\n            isError.value = false;\n        }\n    }\n);\n\n/**\n * 用于重新初始化\n */\nfunction init() {\n    isError.value = false;\n    loadStatus.value = '';\n}\n\n/**\n * 点击图片触发的事件\n * loadlazy-还是懒加载中状态，loading-图片正在加载，loaded-图片加加载完成\n */\nfunction clickImg() {\n    let whichImg = '';\n    // 如果isShow为false，意味着图片还没开始加载，点击的只能是最开始的占位图\n    if (!isShow.value) whichImg = 'lazyImg';\n    // 如果isError为true，意味着图片加载失败，这是只剩下错误的占位图，所以点击的只能是错误占位图\n    // 当然，也可以给错误的占位图元素绑定点击事件，看你喜欢~\n    else if (isError.value) whichImg = 'errorImg';\n    // 总共三张图片，除了两个占位图，剩下的只能是正常的那张图片了\n    else whichImg = 'realImg';\n    // 只通知当前图片的index\n    emit('click', props.index);\n}\n\n/**\n * 图片加载完成事件\n * 可能是加载占位图时触发，也可能是加载真正的图片完成时触发，通过 isShow 区分\n */\nfunction imgLoaded() {\n    // 占位图加载完成\n    if (loadStatus.value === '') {\n        loadStatus.value = 'lazyed';\n    } else if (loadStatus.value === 'lazyed') {\n        // 真正的图片加载完成\n        loadStatus.value = 'loaded';\n        emit('load', props.index);\n    }\n}\n\n/**\n * 错误的图片加载完成\n */\nfunction errorImgLoaded() {\n    emit('error', props.index);\n}\n\n/**\n * 图片加载失败\n */\nfunction loadError() {\n    isError.value = true;\n}\n\n/**\n * 断开 IntersectionObserver\n */\nfunction disconnectObserver(observerName: string) {\n    if (observerName === 'contentObserver' && contentObserver) {\n        contentObserver.disconnect();\n        contentObserver = null;\n    }\n}\n\nonMounted(() => {\n    // 生成唯一 id\n    elIndex.value = $u.guid();\n    nextTick(() => {\n        uni.$once('uOnReachBottom', () => {\n            if (!isShow.value) isShow.value = true;\n        });\n        // mounted的时候，不一定挂载了这个元素，延时30ms，否则会报错或者不报错，但是也没有效果\n        setTimeout(() => {\n            // 这里是组件内获取布局状态，不能用uni.createIntersectionObserver，而必须用this.createIntersectionObserver\n            disconnectObserver('contentObserver');\n            contentObserver = uni.createIntersectionObserver(instance?.proxy);\n            // 要理解这里怎么计算的，请看这个：\n            // https://blog.csdn.net/qq_25324335/article/details/83687695\n            contentObserver\n                .relativeToViewport({ bottom: getThreshold.value })\n                .observe('.u-lazy-item-' + elIndex.value, (res: any) => {\n                    if (res.intersectionRatio > 0) {\n                        // 懒加载状态改变\n                        isShow.value = true;\n                        // 如果图片已经加载，去掉监听，减少性能的消耗\n                        disconnectObserver('contentObserver');\n                    }\n                });\n        }, 30);\n    });\n});\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n\n.u-wrap {\n    background-color: var(--u-divider-color);\n    overflow: hidden;\n}\n\n.u-lazy-item {\n    width: 100%;\n    // 骗系统开启硬件加速\n    transform: transition3d(0, 0, 0);\n    // 防止图片加载“闪一下”\n    will-change: transform;\n    /* #ifndef APP-NVUE */\n    display: block;\n    /* #endif */\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-line/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { LineBorderStyle, LineDirection } from '../../types/global';\n\n/**\n * u-line 组件 props 类型定义\n * @description 此组件一般用于显示一根线条，用于分隔内容块，有横向和竖向两种模式，且能设置0.5px线条，使用也很简单\n */\nexport const LineProps = {\n    /** 线条的颜色 */\n    color: {\n        type: String,\n        default: 'var(--u-border-color)'\n    },\n    /** 长度，竖向时表现为高度，横向时表现为长度，可以为百分比，带rpx单位的值等 */\n    length: {\n        type: String,\n        default: '100%'\n    },\n    /** 线条方向，col-竖向，row-横向 */\n    direction: {\n        type: String as PropType<LineDirection>,\n        default: 'row'\n    },\n    /** 是否显示细边框 */\n    hairLine: {\n        type: Boolean,\n        default: true\n    },\n    /** 线条与上下左右元素的间距，字符串形式，如\"30rpx\"、\"20rpx 30rpx\" */\n    margin: {\n        type: String,\n        default: '0'\n    },\n    /** 线条的类型，solid-实线，dashed-方形虚线，dotted-圆点虚线 */\n    borderStyle: {\n        type: String as PropType<LineBorderStyle>,\n        default: 'solid'\n    }\n};\n\n/**\n * u-line 组件 props 类型\n */\nexport type LineProps = ExtractPropTypes<typeof LineProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-line/u-line.vue",
    "content": "<template>\n    <view class=\"u-line\" :style=\"lineStyle\"></view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-line',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { $u } from '../..';\nimport { LineProps } from './types';\n\n/**\n * line 线条\n * @description 此组件一般用于显示一根线条，用于分隔内容块，有横向和竖向两种模式，且能设置0.5px线条，使用也很简单\n * @tutorial https://uviewpro.cn/zh/components/line.html\n * @property {String} color 线条的颜色(默认var(--u-border-color))\n * @property {String} length 长度，竖向时表现为高度，横向时表现为长度，可以为百分比，带rpx单位的值等\n * @property {String} direction 线条的方向，row-横向，col-竖向(默认row)\n * @property {String} border-style 线条的类型，solid-实线，dashed-方形虚线，dotted-圆点虚线(默认solid)\n * @property {Boolean} hair-line 是否显示细线条(默认true)\n * @property {String} margin 线条与上下左右元素的间距，字符串形式，如\"30rpx\"\n * @example <u-line color=\"red\"></u-line>\n */\nconst props = defineProps(LineProps);\n\n/**\n * 线条样式\n */\nconst lineStyle = computed(() => {\n    let style: Record<string, string> = {};\n    style.margin = props.margin;\n    // 如果是水平线条，边框高度为1px，再通过transform缩小一半，就是0.5px了\n    if (props.direction === 'row') {\n        // 此处采用兼容分开写，兼容nvue的写法\n        style.borderBottomWidth = '1px';\n        style.borderBottomStyle = props.borderStyle;\n        style.width = $u.addUnit(props.length);\n        if (props.hairLine) style.transform = 'scaleY(0.5)';\n    } else {\n        // 如果是竖向线条，边框宽度为1px，再通过transform缩小一半，就是0.5px了\n        style.borderLeftWidth = '1px';\n        style.borderLeftStyle = props.borderStyle;\n        style.height = $u.addUnit(props.length);\n        if (props.hairLine) style.transform = 'scaleX(0.5)';\n    }\n    style.borderColor = props.color;\n    return style;\n});\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n\n.u-line {\n    vertical-align: middle;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-line-progress/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\n/**\n * u-line-progress 组件 props 类型定义\n * @description 线型进度条，支持多种样式\n */\nexport const LineProgressProps = {\n    /** 两端是否显示半圆形 */\n    round: {\n        type: Boolean,\n        default: true\n    },\n    /** 主题颜色 */\n    type: {\n        type: String,\n        default: ''\n    },\n    /** 激活部分的颜色 */\n    activeColor: {\n        type: String,\n        default: 'var(--u-type-success)'\n    },\n    /** 进度条的底色 */\n    inactiveColor: {\n        type: String,\n        default: 'var(--u-divider-color)'\n    },\n    /** 进度百分比，数值 */\n    percent: {\n        type: [Number, String] as PropType<number | string>,\n        default: 0\n    },\n    /** 是否在进度条内部显示百分比的值 */\n    showPercent: {\n        type: Boolean,\n        default: true\n    },\n    /** 进度条的高度，单位rpx */\n    height: {\n        type: [Number, String] as PropType<number | string>,\n        default: 28\n    },\n    /** 是否显示条纹 */\n    striped: {\n        type: Boolean,\n        default: false\n    },\n    /** 条纹是否显示活动状态 */\n    stripedActive: {\n        type: Boolean,\n        default: false\n    }\n};\n\n/**\n * u-line-progress 组件 props 类型\n */\nexport type LineProgressProps = ExtractPropTypes<typeof LineProgressProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-line-progress/u-line-progress.vue",
    "content": "<template>\n    <view\n        class=\"u-progress\"\n        :style=\"{\n            borderRadius: round ? '100rpx' : 0,\n            height: height + 'rpx',\n            backgroundColor: inactiveColor\n        }\"\n    >\n        <view\n            :class=\"[\n                type ? `u-type-${type}-bg` : '',\n                striped ? 'u-striped' : '',\n                striped && stripedActive ? 'u-striped-active' : ''\n            ]\"\n            class=\"u-active\"\n            :style=\"progressStyle\"\n        >\n            <slot v-if=\"slots.default\" />\n            <text class=\"u-progress-text\" v-else-if=\"showPercent\">\n                {{ percent + '%' }}\n            </text>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-line-progress',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, useSlots } from 'vue';\nimport { LineProgressProps } from './types';\n\n/**\n * lineProgress 线型进度条\n * @description 展示操作或任务的当前进度，比如上传文件，是一个线形的进度条。\n * @tutorial https://uviewpro.cn/zh/components/lineProgress.html\n * @property {String Number} percent 进度条百分比值，为数值类型，0-100\n * @property {Boolean} round 进度条两端是否为半圆（默认true）\n * @property {String} type 如设置，active-color值将会失效\n * @property {String} active-color 进度条激活部分的颜色（默认var(--u-type-success)）\n * @property {String} inactive-color 进度条的底色（默认var(--u-divider-color)）\n * @property {Boolean} show-percent 是否在进度条内部显示当前的百分比值数值（默认true）\n * @property {String Number} height 进度条的高度，单位rpx（默认28）\n * @property {Boolean} striped 是否显示进度条激活部分的条纹（默认false）\n * @property {Boolean} striped-active 条纹是否具有动态效果（默认false）\n * @example <u-line-progress :percent=\"70\" :show-percent=\"true\"></u-line-progress>\n */\nconst props = defineProps(LineProgressProps);\nconst slots = useSlots();\n\n/**\n * 进度条激活部分的样式\n */\nconst progressStyle = computed(() => {\n    let style: Record<string, string> = {};\n    style.width = props.percent + '%';\n    if (!props.type && props.activeColor) style.backgroundColor = props.activeColor;\n    return style;\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-progress {\n    overflow: hidden;\n    height: 15px;\n    /* #ifndef APP-NVUE */\n    display: inline-flex;\n    /* #endif */\n    align-items: center;\n    width: 100%;\n    border-radius: 100rpx;\n}\n\n.u-active {\n    width: 0;\n    height: 100%;\n    align-items: center;\n    @include vue-flex;\n    justify-items: flex-end;\n    justify-content: space-around;\n    font-size: 20rpx;\n    color: var(--u-white-color);\n    transition: all 0.4s ease;\n}\n\n.u-striped {\n    background-image: linear-gradient(\n        45deg,\n        rgba(255, 255, 255, 0.15) 25%,\n        transparent 25%,\n        transparent 50%,\n        rgba(255, 255, 255, 0.15) 50%,\n        rgba(255, 255, 255, 0.15) 75%,\n        transparent 75%,\n        transparent\n    );\n    background-size: 39px 39px;\n}\n\n.u-striped-active {\n    animation: progress-stripes 2s linear infinite;\n}\n\n.u-progress-text {\n    color: var(--u-light-color);\n    padding: 0 10rpx;\n}\n\n@keyframes progress-stripes {\n    0% {\n        background-position: 0 0;\n    }\n\n    100% {\n        background-position: 39px 0;\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-link/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport { getColor, useLocale } from '../../';\n\nconst { t } = useLocale();\n\n/**\n * u-link 组件 props 类型定义\n * @description 超链接组件，支持多端跳转/复制/提示\n */\nexport const LinkProps = {\n    /** 文字颜色 */\n    color: {\n        type: String,\n        default: () => getColor('primary')\n    },\n    /** 字体大小，单位rpx */\n    fontSize: {\n        type: [String, Number] as PropType<string | number>,\n        default: 28\n    },\n    /** 是否显示下划线 */\n    underLine: {\n        type: Boolean,\n        default: false\n    },\n    /** 要跳转的链接 */\n    href: {\n        type: String,\n        default: ''\n    },\n    /** 小程序中复制到粘贴板的提示语 */\n    mpTips: {\n        type: String,\n        default: () => t('uLink.mpTips')\n    },\n    /** 下划线颜色 */\n    lineColor: {\n        type: String,\n        default: ''\n    },\n    /** 是否默认点击跳转 */\n    defaultClick: {\n        type: Boolean,\n        default: true\n    }\n};\n\n/**\n * u-link 组件 props 类型\n */\nexport type LinkProps = ExtractPropTypes<typeof LinkProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-link/u-link.vue",
    "content": "<template>\n    <text\n        class=\"u-link\"\n        @tap.stop=\"openLink\"\n        :style=\"{\n            color: color,\n            fontSize: fontSize + 'rpx',\n            borderBottom: underLine ? `1px solid ${lineColor ? lineColor : color}` : 'none',\n            paddingBottom: underLine ? '0rpx' : '0'\n        }\"\n    >\n        <slot></slot>\n    </text>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-link',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { $u } from '../..';\nimport { LinkProps } from './types';\n\n/**\n * link 超链接\n * @description 该组件为超链接组件，在不同平台有不同表现形式：在APP平台会通过plus环境打开内置浏览器，在小程序中把链接复制到粘贴板，同时提示信息，在H5中通过window.open打开链接。\n * @tutorial https://uviewpro.cn/zh/components/link.html\n * @property {String} color 文字颜色（默认var(--u-content-color)）\n * @property {String Number} font-size 字体大小，单位rpx（默认28）\n * @property {Boolean} under-line 是否显示下划线（默认false）\n * @property {String} href 跳转的链接，要带上http(s)\n * @property {String} line-color 下划线颜色，默认同color参数颜色\n * @property {String} mp-tips 各个小程序平台把链接复制到粘贴板后的提示语（默认“链接已复制，请在浏览器打开”）\n * @example <u-link href=\"https://uviewpro.cn\">蜀道难，难于上青天</u-link>\n */\nconst props = defineProps(LinkProps);\nconst emit = defineEmits(['click']);\n\n/**\n * 打开链接方法\n * 不同平台有不同表现形式\n */\nfunction openLink() {\n    if (!props.defaultClick) {\n        emit('click', props.href);\n        return;\n    }\n    // #ifdef APP-PLUS\n    if (typeof plus !== 'undefined' && plus.runtime) {\n        plus.runtime.openURL(props.href);\n    }\n    // #endif\n    // #ifdef H5\n    if (typeof window !== 'undefined') {\n        window.open(props.href);\n    }\n    // #endif\n    // #ifdef MP\n    if (typeof uni !== 'undefined' && uni.setClipboardData) {\n        uni.setClipboardData({\n            data: props.href,\n            success: () => {\n                uni.hideToast();\n                if (typeof $u !== 'undefined' && $u.toast && props.mpTips) {\n                    $u.toast(props.mpTips);\n                }\n            }\n        });\n    }\n    // #endif\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-link {\n    line-height: 1;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-loading/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\ntype LoadingMode = 'circle' | 'flower';\n\n/**\n * u-loading 组件 props 类型定义\n * @description 加载动画，支持多种模式\n */\nexport const LoadingProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 动画的类型 */\n    mode: {\n        type: String as PropType<LoadingMode>,\n        default: 'circle'\n    },\n    /** 动画的颜色 */\n    color: {\n        type: String,\n        default: 'var(--u-light-color)'\n    },\n    /** 加载图标的大小，单位rpx */\n    size: {\n        type: [String, Number] as PropType<string | number>,\n        default: '34'\n    },\n    /** 是否显示动画 */\n    show: {\n        type: Boolean,\n        default: true\n    }\n};\n\n/**\n * u-loading 组件 props 类型\n */\nexport type LoadingProps = ExtractPropTypes<typeof LoadingProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-loading/u-loading.vue",
    "content": "<template>\n    <view\n        v-if=\"show\"\n        class=\"u-loading\"\n        :class=\"[mode === 'circle' ? 'u-loading-circle' : 'u-loading-flower', customClass]\"\n        :style=\"$u.toStyle(cricleStyle, customStyle)\"\n    >\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-loading',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { LoadingProps } from './types';\nimport { $u } from '../../';\n\n/**\n * loading 加载动画\n * @description 此组件为一个小动画，目前用在uView的loadmore加载更多和switch开关等组件的正在加载状态场景。\n * @tutorial https://uviewpro.cn/zh/components/loading.html\n * @property {String} mode 模式选择，见官网说明（默认circle）\n * @property {String} color 动画活动区域的颜色，只对 mode = flower 模式有效（默认var(--u-light-color)）\n * @property {String|Number} size 加载图标的大小，单位rpx（默认34）\n * @property {Boolean} show 是否显示动画（默认true）\n * @example <u-loading mode=\"circle\"></u-loading>\n */\nconst props = defineProps(LoadingProps);\n\n/**\n * 加载中圆圈动画的样式\n * @returns {Record<string, any>}\n */\nconst cricleStyle = computed(() => {\n    let style: Record<string, any> = {};\n    style.width = props.size + 'rpx';\n    style.height = props.size + 'rpx';\n    // 只对圆圈模式生效\n    if (props.mode === 'circle') {\n        style.borderColor = `var(--u-divider-color) var(--u-divider-color) var(--u-divider-color) ${props.color ? props.color : 'var(--u-light-color)'}`;\n    }\n    return style;\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-loading-circle {\n    /* #ifndef APP-NVUE */\n    display: inline-flex;\n    /* #endif */\n    vertical-align: middle;\n    width: 28rpx;\n    height: 28rpx;\n    background: 0 0;\n    border-radius: 50%;\n    border: 2px solid;\n    border-color: var(--u-divider-color) var(--u-divider-color) var(--u-divider-color) var(--u-tips-color);\n    animation: u-circle 1s linear infinite;\n}\n\n.u-loading-flower {\n    width: 20px;\n    height: 20px;\n    display: inline-block;\n    vertical-align: middle;\n    -webkit-animation: u-flower 1s steps(12) infinite;\n    animation: u-flower 1s steps(12) infinite;\n    background: transparent\n        url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAiIGhlaWdodD0iMTIwIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgxMDB2MTAwSDB6Ii8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTlFOUU5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgLTMwKSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iIzk4OTY5NyIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgzMCAxMDUuOTggNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjOUI5OTlBIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDYwIDc1Ljk4IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0EzQTFBMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSg5MCA2NSA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNBQkE5QUEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoMTIwIDU4LjY2IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0IyQjJCMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgxNTAgNTQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjQkFCOEI5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDE4MCA1MCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDMkMwQzEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTE1MCA0NS45OCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDQkNCQ0IiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTEyMCA0MS4zNCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNEMkQyRDIiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTkwIDM1IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0RBREFEQSIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgtNjAgMjQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTJFMkUyIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKC0zMCAtNS45OCA2NSkiLz48L3N2Zz4=)\n        no-repeat;\n    background-size: 100%;\n}\n\n@keyframes u-flower {\n    0% {\n        -webkit-transform: rotate(0deg);\n        transform: rotate(0deg);\n    }\n    to {\n        -webkit-transform: rotate(1turn);\n        transform: rotate(1turn);\n    }\n}\n\n@keyframes u-circle {\n    0% {\n        transform: rotate(0);\n    }\n    100% {\n        transform: rotate(360deg);\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-loading-popup/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\ntype LoadingMode = 'circle' | 'flower';\n\n/**\n * u-loading-popup 组件 props 类型定义\n */\nexport const LoadingPopupProps = {\n    /** 是否显示加载弹窗 */\n    modelValue: { type: Boolean, default: false },\n    /** 加载提示文本 */\n    text: { type: String, default: '' },\n    /** 方向，可选 'vertical' | 'horizontal' */\n    direction: { type: String as PropType<'vertical' | 'horizontal'>, default: 'vertical' },\n    /** 自动关闭的持续时间(ms)，0为不自动关闭 */\n    duration: { type: Number, default: 0 },\n    /** 允许点击遮罩关闭的最短时间(ms) */\n    cancelTime: { type: Number, default: 10000 },\n    /** 动画的类型 */\n    mode: { type: String as PropType<LoadingMode>, default: 'circle' },\n    /** 动画的颜色 */\n    color: { type: String, default: 'var(--u-light-color)' },\n    /** 加载图标的大小，单位rpx */\n    size: { type: [String, Number] as PropType<string | number>, default: '48' }\n};\n\nexport type LoadingPopupProps = ExtractPropTypes<typeof LoadingPopupProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-loading-popup/u-loading-popup.vue",
    "content": "<template>\n    <view @touchmove.stop.prevent>\n        <view v-if=\"popupValue\" class=\"u-loading-init\" :class=\"[direction]\">\n            <u-loading :mode=\"mode\" :color=\"color\" :size=\"size\" />\n            <view v-if=\"currentText\" class=\"u-loading-tips\">\n                {{ currentText }}\n            </view>\n        </view>\n        <view class=\"u-loading-mask\" :class=\"[popupValue ? 'u-mask-show' : '']\" @click=\"onMaskClick\" />\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-loading-popup',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script lang=\"ts\" setup>\nimport { computed, onUnmounted, ref, watch } from 'vue';\nimport { LoadingPopupProps } from './types';\n\n// 组件props类型\nconst props = defineProps(LoadingPopupProps);\nconst emit = defineEmits(['update:modelValue', 'cancel']);\n\n// 自动关闭的持续时间定时器\nlet durationTimer: ReturnType<typeof setTimeout> | null = null;\n// 关闭按钮倒计时定时器\nlet cancelTimer: ReturnType<typeof setTimeout> | null = null;\n// 记录弹窗显示的时间戳\nconst now = ref(0);\n// 点击遮罩层是否可关闭（超时后）\nconst canClose = ref(false);\n// 当前显示的text，优先级：loading参数 > props.text\nconst currentText = ref(props.text);\n\nconst popupValue = computed({\n    get: () => props.modelValue,\n    set: (val: boolean) => emit('update:modelValue', val)\n});\n\nwatch(\n    () => popupValue.value,\n    val => {\n        if (val) {\n            doOpen(currentText.value);\n        } else {\n            doClose();\n        }\n    }\n);\n\n// 响应 props 变更，自动刷新当前 text\nwatch(\n    () => props.text,\n    val => {\n        currentText.value = val;\n    }\n);\n\n// 响应 cancelTime/duration 变化，重启定时器\nwatch(\n    () => [props.cancelTime, props.duration],\n    () => {\n        if (popupValue.value) {\n            clearDurationTimer();\n            startCancelTime();\n            startDurationTime();\n        }\n    }\n);\n\n/**\n * 启动超时关闭按钮计时\n */\nfunction startCancelTime() {\n    clearCancelTimer();\n    canClose.value = false;\n    if (props.cancelTime > 0) {\n        cancelTimer = setTimeout(() => {\n            canClose.value = true;\n        }, props.cancelTime);\n    }\n}\n\n/**\n * 启动持续时间计时\n */\nfunction startDurationTime() {\n    clearDurationTimer();\n    if (props.duration) {\n        durationTimer = setTimeout(() => {\n            close();\n        }, props.duration);\n    }\n}\n\n/**\n * 内部显示逻辑，初始化所有状态\n */\nfunction doOpen(text?: string) {\n    canClose.value = false;\n    clearDurationTimer();\n    clearCancelTimer();\n    now.value = Date.now();\n    if (typeof text === 'string' && text !== '') {\n        currentText.value = text;\n    } else {\n        currentText.value = props.text;\n    }\n    startCancelTime();\n    startDurationTime();\n}\n\n/**\n * 内部关闭逻辑，重置所有状态\n */\nfunction doClose() {\n    canClose.value = false;\n    currentText.value = props.text;\n    clearDurationTimer();\n    clearCancelTimer();\n}\n\n/**\n * 显示弹窗\n * @param text 可选，优先显示的文案\n */\nfunction open(text?: string) {\n    currentText.value = text || props.text;\n    popupValue.value = true;\n}\n\n/**\n * 隐藏弹窗\n */\nfunction close() {\n    popupValue.value = false;\n}\n\n// 清理定时器\nfunction clearDurationTimer() {\n    if (durationTimer) {\n        clearTimeout(durationTimer);\n        durationTimer = null;\n    }\n}\nfunction clearCancelTimer() {\n    if (cancelTimer) {\n        clearTimeout(cancelTimer);\n        cancelTimer = null;\n    }\n}\n\n// 遮罩点击事件\nfunction onMaskClick() {\n    // 只有显示关闭按钮时才允许关闭\n    if (canClose.value) {\n        emit('cancel');\n        close();\n    }\n}\n\nonUnmounted(() => {\n    clearDurationTimer();\n    clearCancelTimer();\n});\n\ndefineExpose({\n    open,\n    close\n});\n</script>\n\n<style lang=\"scss\">\n.u-loading-mask {\n    position: fixed;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    background: rgba(0, 0, 0, 0);\n    z-index: 9999996;\n    transition: all 0.3s ease-in-out;\n    opacity: 0;\n    visibility: hidden;\n}\n\n.u-mask-show {\n    visibility: visible;\n    opacity: 1;\n}\n\n.u-loading-init {\n    position: relative;\n    min-width: 200rpx;\n    min-height: 200rpx;\n    max-width: 500rpx;\n    padding: 15rpx 0;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    flex-direction: column;\n    position: fixed;\n    top: 50%;\n    left: 50%;\n    transform: translate(-50%, -50%);\n    z-index: 9999;\n    font-size: 30rpx;\n    color: var(--u-white-color);\n    background: rgba(0, 0, 0, 0.7);\n    border-radius: 7px;\n\n    .u-icon-close {\n        position: absolute;\n        top: 4rpx;\n        right: 2rpx;\n        color: var(--u-white-color);\n        opacity: 0.8;\n    }\n\n    &.horizontal {\n        flex-direction: row;\n        align-items: center;\n        justify-content: left;\n        width: 600rpx;\n        max-width: 600rpx;\n        min-height: 150rpx;\n        padding-left: 40rpx;\n\n        .u-loading-tips {\n            margin-top: 0;\n            margin-left: 20rpx;\n            font-size: 32rpx;\n        }\n    }\n}\n\n.u-loading-tips {\n    text-align: center;\n    padding: 0 20rpx;\n    box-sizing: border-box;\n    margin-top: 36rpx;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-loadmore/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { LoadmoreIconType, LoadmoreStatus, LoadmoreText } from '../../types/global';\nimport { useLocale } from '../../';\n\nconst { t } = useLocale();\n\n/**\n * u-loadmore 组件 props 类型定义\n * @description 加载更多，支持多种状态和自定义文字\n */\n\nexport const LoadmoreProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 组件背景色 */\n    bgColor: {\n        type: String,\n        default: 'transparent'\n    },\n    /** 是否显示加载中的图标 */\n    icon: {\n        type: Boolean,\n        default: true\n    },\n    /** 字体大小 */\n    fontSize: {\n        type: String,\n        default: '28'\n    },\n    /** 字体颜色 */\n    color: {\n        type: String,\n        default: 'var(--u-content-color)'\n    },\n    /** 组件状态，loadmore-加载前，loading-加载中，nomore-没有更多 */\n    status: {\n        type: String as PropType<LoadmoreStatus>,\n        default: 'loadmore'\n    },\n    /** 加载中状态的图标，flower-花朵状，circle-圆圈状 */\n    iconType: {\n        type: String as PropType<LoadmoreIconType>,\n        default: 'circle'\n    },\n    /** 显示的文字 */\n    loadText: {\n        type: Object as PropType<LoadmoreText>,\n        default: () => ({\n            loadmore: t('uLoadmore.loadmore'),\n            loading: t('uLoadmore.loading'),\n            nomore: t('uLoadmore.nomore')\n        })\n    },\n    /** 在“没有更多”状态下，是否显示粗点 */\n    isDot: {\n        type: Boolean,\n        default: false\n    },\n    /** 加载中显示圆圈动画时，动画的颜色 */\n    iconColor: {\n        type: String,\n        default: 'var(--u-light-color)'\n    },\n    /** 上边距 */\n    marginTop: {\n        type: [String, Number] as PropType<string | number>,\n        default: 0\n    },\n    /** 下边距 */\n    marginBottom: {\n        type: [String, Number] as PropType<string | number>,\n        default: 0\n    },\n    /** 高度，单位rpx */\n    height: {\n        type: [String, Number] as PropType<string | number>,\n        default: 'auto'\n    }\n};\n\n/**\n * u-loadmore 组件 props 类型\n */\nexport type LoadmoreProps = ExtractPropTypes<typeof LoadmoreProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-loadmore/u-loadmore.vue",
    "content": "<template>\n    <view\n        class=\"u-load-more-wrap\"\n        :class=\"props.customClass\"\n        :style=\"\n            $u.toStyle(props.customStyle, {\n                backgroundColor: props.bgColor,\n                marginBottom: props.marginBottom + 'rpx',\n                marginTop: props.marginTop + 'rpx',\n                height: $u.addUnit(props.height)\n            })\n        \"\n    >\n        <u-line color=\"var(--u-divider-color)\" length=\"50\"></u-line>\n        <!-- 加载中和没有更多的状态才显示两边的横线 -->\n        <view :class=\"props.status == 'loadmore' || props.status == 'nomore' ? 'u-more' : ''\" class=\"u-load-more-inner\">\n            <view class=\"u-loadmore-icon-wrap\">\n                <u-loading\n                    class=\"u-loadmore-icon\"\n                    :color=\"props.iconColor\"\n                    :mode=\"props.iconType == 'circle' ? 'circle' : 'flower'\"\n                    :show=\"props.status == 'loading' && props.icon\"\n                ></u-loading>\n            </view>\n            <!-- 如果没有更多的状态下，显示内容为dot（粗点），加载特定样式 -->\n            <view\n                class=\"u-line-1\"\n                :style=\"$u.toStyle(loadTextStyle)\"\n                :class=\"[props.status == 'nomore' && props.isDot == true ? 'u-dot-text' : 'u-more-text']\"\n                @tap=\"loadMore\"\n            >\n                {{ showText }}\n            </view>\n        </view>\n        <u-line color=\"var(--u-divider-color)\" length=\"50\"></u-line>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-loadmore',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed } from 'vue';\nimport { $u } from '../..';\nimport { LoadmoreProps } from './types';\n\n/**\n * loadmore 加载更多\n * @description 此组件一般用于标识页面底部加载数据时的状态。\n * @tutorial https://uviewpro.cn/zh/components/loadMore.html\n * @property {String} status 组件状态（默认loadmore）\n * @property {String} bg-color 组件背景颜色，在页面是非白色时会用到（默认var(--u-bg-white)）\n * @property {Boolean} icon 加载中时是否显示图标（默认true）\n * @property {String} icon-type 加载中时的图标类型（默认circle）\n * @property {String} icon-color icon-type为circle时有效，加载中的动画图标的颜色（默认var(--u-light-color)）\n * @property {Boolean} is-dot status为nomore时，内容显示为一个\"●\"（默认false）\n * @property {String} color 字体颜色（默认var(--u-content-color)）\n * @property {String|Number} margin-top 到上一个相邻元素的距离\n * @property {String|Number} margin-bottom 到下一个相邻元素的距离\n * @property {Object} load-text 自定义显示的文字，见上方说明示例\n * @event {Function} loadmore status为loadmore时，点击组件会发出此事件\n * @example <u-loadmore :status=\"status\" icon-type=\"iconType\" load-text=\"loadText\" />\n */\nconst props = defineProps(LoadmoreProps);\nconst emits = defineEmits(['loadmore']);\n\n// 粗点\nconst dotText = ref('●');\n\n// 加载的文字显示的样式\nconst loadTextStyle = computed(() => {\n    return {\n        color: props.color,\n        fontSize: props.fontSize + 'rpx',\n        position: 'relative' as const,\n        zIndex: 1,\n        backgroundColor: props.bgColor\n        // 如果是加载中状态，动画和文字需要距离近一点\n    };\n});\n\n// 加载中圆圈动画的样式\nconst cricleStyle = computed(() => {\n    return {\n        borderColor: `var(--u-divider-color) var(--u-divider-color) var(--u-divider-color) ${props.iconColor}`\n    };\n});\n\n// 加载中花朵动画形式\n// 动画由base64图片生成，暂不支持修改\nconst flowerStyle = computed(() => {\n    return {};\n});\n\n// 显示的提示文字\nconst showText = computed(() => {\n    let text = '';\n    if (props.status === 'loadmore') text = props.loadText.loadmore;\n    else if (props.status === 'loading') text = props.loadText.loading;\n    else if (props.status === 'nomore' && props.isDot) text = dotText.value;\n    else text = props.loadText.nomore;\n    return text;\n});\n\n/**\n * 只有在“加载更多”的状态下才发送点击事件，内容不满一屏时无法触发底部上拉事件，所以需要点击来触发\n */\nfunction loadMore() {\n    if (props.status === 'loadmore') emits('loadmore');\n}\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n/* #ifdef MP */\n// 在mp.scss中，赋予了u-line为flex: 1，这里需要一个明确的长度，所以重置掉它\n// 在组件内部，把组件名(u-line)当做选择器，在微信开发工具会提示不合法，但不影响使用\nu-line {\n    flex: none;\n}\n/* #endif */\n.u-load-more-wrap {\n    @include vue-flex;\n    justify-content: center;\n    align-items: center;\n}\n.u-load-more-inner {\n    @include vue-flex;\n    justify-content: center;\n    align-items: center;\n    padding: 0 12rpx;\n}\n.u-more {\n    position: relative;\n    @include vue-flex;\n    justify-content: center;\n}\n.u-dot-text {\n    font-size: 28rpx;\n}\n.u-loadmore-icon-wrap {\n    margin-right: 8rpx;\n}\n.u-loadmore-icon {\n    @include vue-flex;\n    align-items: center;\n    justify-content: center;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-mask/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\n/**\n * u-mask 组件 props 类型定义\n * @description 遮罩层，支持自定义样式、缩放、动画等\n */\nexport const MaskProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 是否显示遮罩 */\n    show: {\n        type: Boolean,\n        default: false\n    },\n    /** 层级z-index */\n    zIndex: {\n        type: [Number, String] as PropType<number | string>,\n        default: ''\n    },\n    /** 遮罩的动画样式，是否使用zoom进行scale进行缩放 */\n    zoom: {\n        type: Boolean,\n        default: true\n    },\n    /** 遮罩的过渡时间，单位为ms */\n    duration: {\n        type: [Number, String] as PropType<number | string>,\n        default: 300\n    },\n    /** 是否可以通过点击遮罩进行关闭 */\n    maskClickAble: {\n        type: Boolean,\n        default: true\n    }\n};\n\n/**\n * u-mask 组件 props 类型\n */\nexport type MaskProps = ExtractPropTypes<typeof MaskProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-mask/u-mask.vue",
    "content": "<template>\n    <view\n        class=\"u-mask\"\n        hover-stop-propagation\n        :style=\"$u.toStyle(maskStyle, zoomStyle, customStyle)\"\n        @tap=\"click\"\n        @touchmove.stop.prevent=\"() => {}\"\n        :class=\"[\n            {\n                'u-mask-zoom': props.zoom,\n                'u-mask-show': props.show\n            },\n            customClass\n        ]\"\n    >\n        <slot />\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-mask',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch } from 'vue';\nimport { $u } from '../..';\nimport { MaskProps } from './types';\n\n/**\n * mask 遮罩\n * @description 创建一个遮罩层，用于强调特定的页面元素，并阻止用户对遮罩下层的内容进行操作，一般用于弹窗场景\n * @tutorial https://uviewpro.cn/zh/components/mask.html\n * @property {Boolean} show 是否显示遮罩（默认false）\n * @property {String|Number} z-index z-index 层级（默认1070）\n * @property {Object} custom-style 自定义样式对象，见上方说明\n * @property {String|Number} duration 动画时长，单位毫秒（默认300）\n * @property {Boolean} zoom 是否使用scale对遮罩进行缩放（默认true）\n * @property {Boolean} mask-click-able 遮罩是否可点击，为false时点击不会发送click事件（默认true）\n * @event {Function} click mask-click-able为true时，点击遮罩发送此事件\n * @example <u-mask :show=\"show\" @click=\"show = false\"></u-mask>\n */\nconst props = defineProps(MaskProps);\nconst emit = defineEmits(['click']);\n\n// 缩放动画样式\nconst zoomStyle = ref<{ transform: string }>({ transform: '' });\n// scale值\nconst scale = 'scale(1.2, 1.2)';\n\n// 监听遮罩显示状态，动态设置缩放动画\nwatch(\n    () => props.show,\n    n => {\n        if (n && props.zoom) {\n            // 当展示遮罩的时候，设置scale为1，达到缩小(原来为1.2)的效果\n            zoomStyle.value.transform = 'scale(1, 1)';\n        } else if (!n && props.zoom) {\n            // 当隐藏遮罩的时候，设置scale为1.2，达到放大(因为显示遮罩时已重置为1)的效果\n            zoomStyle.value.transform = scale;\n        }\n    }\n);\n\n// 遮罩样式\nconst maskStyle = computed(() => {\n    let style: Record<string, any> = {};\n    style.backgroundColor = 'rgba(0, 0, 0, 0.6)';\n    if (props.show) style.zIndex = props.zIndex ? props.zIndex : $u.zIndex.mask;\n    else style.zIndex = -1;\n    style.transition = `all ${Number(props.duration) / 1000}s ease-in-out`;\n    return style;\n});\n\n/**\n * 遮罩点击事件\n * maskClickAble为true时，点击遮罩发送click事件\n */\nfunction click() {\n    if (!props.maskClickAble) return;\n    emit('click');\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-mask {\n    position: fixed;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    opacity: 0;\n    transition: transform 0.3s;\n}\n\n.u-mask-show {\n    opacity: 1;\n}\n\n.u-mask-zoom {\n    transform: scale(1.2, 1.2);\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-message-input/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { InputType, MessageInputMode } from '../../types/global';\nimport { getColor } from '../../';\n\n/**\n * u-message-input 组件 props 类型定义\n * @description 验证码/短信输入框，支持多种样式\n */\nexport const MessageInputProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 输入框的类型，textarea，text，number */\n    type: {\n        type: String as PropType<InputType>,\n        default: 'number'\n    },\n    /** 最大输入长度 */\n    maxlength: {\n        type: [Number, String] as PropType<number | string>,\n        default: 4\n    },\n    /** 是否用圆点填充 */\n    dotFill: {\n        type: Boolean,\n        default: false\n    },\n    /** 显示模式，box-盒子，bottomLine-底部横线，middleLine-中部横线 */\n    mode: {\n        type: String as PropType<MessageInputMode>,\n        default: 'box'\n    },\n    /** 预置值 */\n    value: {\n        type: [String, Number] as PropType<string | number>,\n        default: ''\n    },\n    /** 当前激活输入item，是否带有呼吸效果 */\n    breathe: {\n        type: Boolean,\n        default: true\n    },\n    /** 是否自动获取焦点 */\n    focus: {\n        type: Boolean,\n        default: false\n    },\n    /** 字体是否加粗 */\n    bold: {\n        type: Boolean,\n        default: false\n    },\n    /** 字体大小 */\n    fontSize: {\n        type: [String, Number] as PropType<string | number>,\n        default: 60\n    },\n    /** 激活样式 */\n    activeColor: {\n        type: String,\n        default: () => getColor('primary')\n    },\n    /** 未激活的样式 */\n    inactiveColor: {\n        type: String,\n        default: () => getColor('contentColor')\n    },\n    /** 输入框的大小，单位rpx，宽等于高 */\n    width: {\n        type: [Number, String] as PropType<number | string>,\n        default: '80'\n    },\n    /** 是否隐藏原生键盘 */\n    disabledKeyboard: {\n        type: Boolean,\n        default: false\n    }\n};\n\n/**\n * u-message-input 组件 props 类型\n */\nexport type MessageInputProps = ExtractPropTypes<typeof MessageInputProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-message-input/u-message-input.vue",
    "content": "<template>\n    <view class=\"u-char-box\" :class=\"customClass\" :style=\"$u.toStyle(customStyle)\">\n        <view class=\"u-char-flex\">\n            <!-- prettier-ignore -->\n            <input\n                :disabled=\"props.disabledKeyboard\"\n                :value=\"valueModel\"\n                :type=\"(type as any)\"\n                :focus=\"props.focus\"\n                :maxlength=\"Number(props.maxlength)\"\n                class=\"u-input\"\n                @input=\"getVal\"\n            />\n            <view v-for=\"(item, index) in loopCharArr\" :key=\"index\">\n                <view\n                    :class=\"[\n                        props.breathe && charArrLength === index ? 'u-breathe' : '',\n                        'u-char-item',\n                        charArrLength === index && props.mode == 'box' ? 'u-box-active' : '',\n                        props.mode === 'box' ? 'u-box' : ''\n                    ]\"\n                    :style=\"{\n                        fontWeight: props.bold ? 'bold' : 'normal',\n                        fontSize: props.fontSize + 'rpx',\n                        width: props.width + 'rpx',\n                        height: props.width + 'rpx',\n                        color: props.inactiveColor,\n                        borderColor:\n                            charArrLength === index && props.mode == 'box' ? props.activeColor : props.inactiveColor\n                    }\"\n                >\n                    <view\n                        class=\"u-placeholder-line\"\n                        :style=\"{\n                            display: charArrLength === index ? 'block' : 'none',\n                            height: Number(props.width) * 0.5 + 'rpx'\n                        }\"\n                        v-if=\"props.mode !== 'middleLine'\"\n                    ></view>\n                    <view\n                        v-if=\"props.mode === 'middleLine' && charArrLength <= index\"\n                        :class=\"[\n                            props.breathe && charArrLength === index ? 'u-breathe' : '',\n                            charArrLength === index ? 'u-middle-line-active' : ''\n                        ]\"\n                        class=\"u-middle-line\"\n                        :style=\"{\n                            height: props.bold ? '4px' : '2px',\n                            background: charArrLength === index ? props.activeColor : props.inactiveColor\n                        }\"\n                    ></view>\n                    <view\n                        v-if=\"props.mode === 'bottomLine'\"\n                        :class=\"[\n                            props.breathe && charArrLength === index ? 'u-breathe' : '',\n                            charArrLength === index ? 'u-bottom-line-active' : ''\n                        ]\"\n                        class=\"u-bottom-line\"\n                        :style=\"{\n                            height: props.bold ? '4px' : '2px',\n                            background: charArrLength === index ? props.activeColor : props.inactiveColor\n                        }\"\n                    ></view>\n                    <block v-if=\"!props.dotFill\"> {{ charArr[index] ? charArr[index] : '' }}</block>\n                    <block v-else>\n                        <text class=\"u-dot\">{{ charArr[index] ? '●' : '' }}</text>\n                    </block>\n                </view>\n            </view>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-message-input',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch } from 'vue';\nimport { MessageInputProps } from './types';\nimport { $u } from '../../';\n\n/**\n * messageInput 验证码输入框\n * @description 该组件一般用于验证用户短信验证码的场景，也可以结合uView的键盘组件使用\n * @tutorial https://uviewpro.cn/zh/components/messageInput.html\n * @property {String|Number} maxlength 输入字符个数（默认4）\n * @property {Boolean} dot-fill 是否用圆点填充（默认false）\n * @property {String} mode 模式选择，见上方\"基本使用\"说明（默认box）\n * @property {String|Number} value 预置值\n * @property {Boolean} breathe 是否开启呼吸效果，见上方说明（默认true）\n * @property {Boolean} focus 是否自动获取焦点（默认false）\n * @property {Boolean} bold 字体和输入横线是否加粗（默认true）\n * @property {String|Number} font-size 字体大小，单位rpx（默认60）\n * @property {String} active-color 当前激活输入框的样式（默认主题色primary）\n * @property {String} inactive-color 非激活输入框的样式，文字颜色同此值（默认var(--u-content-color)）\n * @property {String|Number} width 输入框宽度，单位rpx，高等于宽（默认80）\n * @property {Boolean} disabled-keyboard 禁止点击输入框唤起系统键盘（默认false）\n * @event {Function} change 输入内容发生改变时触发，具体见官网说明\n * @event {Function} finish 输入字符个数达maxlength值时触发，见官网说明\n * @example <u-message-input mode=\"bottomLine\"></u-message-input>\n */\nconst props = defineProps(MessageInputProps);\n\nconst emit = defineEmits(['change', 'finish']);\n\n// 输入框实际值\nconst valueModel = ref('');\n\n// 监听 value 变化，自动同步 valueModel，超出部分截掉\nwatch(\n    () => props.value,\n    val => {\n        // 转为字符串\n        const strVal = String(val);\n        // 超出部分截掉\n        valueModel.value = strVal.substring(0, Number(props.maxlength));\n    },\n    { immediate: true }\n);\n\n// 用于显示字符\nconst charArr = computed(() => valueModel.value.split(''));\nconst charArrLength = computed(() => charArr.value.length);\n// 根据长度，循环输入框的个数，因为头条小程序数值不能用于v-for\nconst loopCharArr = computed(() => new Array(Number(props.maxlength)));\n\n/**\n * 输入事件处理\n * @param e input事件对象\n */\nfunction getVal(e: any) {\n    const { value } = e.detail;\n    valueModel.value = value;\n    // 判断长度是否超出了maxlength值，理论上不会发生，因为input组件设置了maxlength属性值\n    if (String(value).length > Number(props.maxlength)) return;\n    // 未达到maxlength之前，发送change事件，达到后发送finish事件\n    emit('change', value);\n    if (String(value).length === Number(props.maxlength)) {\n        emit('finish', value);\n    }\n}\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n\n@keyframes breathe {\n    0% {\n        opacity: 0.3;\n    }\n\n    50% {\n        opacity: 1;\n    }\n\n    100% {\n        opacity: 0.3;\n    }\n}\n\n.u-char-box {\n    text-align: center;\n}\n\n.u-char-flex {\n    @include vue-flex;\n    justify-content: center;\n    flex-wrap: wrap;\n    position: relative;\n}\n\n.u-input {\n    position: absolute;\n    top: 0;\n    left: -100%;\n    width: 200%;\n    height: 100%;\n    text-align: left;\n    z-index: 9;\n    opacity: 0;\n    background: none;\n}\n\n.u-char-item {\n    position: relative;\n    width: 90rpx;\n    height: 90rpx;\n    margin: 10rpx 10rpx;\n    font-size: 60rpx;\n    font-weight: bold;\n    color: $u-main-color;\n    line-height: 90rpx;\n    @include vue-flex;\n    justify-content: center;\n    align-items: center;\n}\n\n.u-middle-line {\n    border: none;\n}\n\n.u-box {\n    box-sizing: border-box;\n    border: 2rpx solid var(--u-light-color);\n    border-radius: 6rpx;\n}\n\n.u-box-active {\n    overflow: hidden;\n    animation-timing-function: ease-in-out;\n    animation-duration: 1500ms;\n    animation-iteration-count: infinite;\n    animation-direction: alternate;\n    border: 2rpx solid $u-type-primary;\n}\n\n.u-middle-line-active {\n    background: $u-type-primary;\n}\n\n.u-breathe {\n    animation: breathe 2s infinite ease;\n}\n\n.u-placeholder-line {\n    /* #ifndef APP-NVUE */\n    display: none;\n    /* #endif */\n    position: absolute;\n    left: 50%;\n    top: 50%;\n    transform: translate(-50%, -50%);\n    width: 2rpx;\n    height: 40rpx;\n    background: var(--u-main-color);\n    animation: twinkling 1.5s infinite ease;\n}\n\n.u-animation-breathe {\n    animation-name: breathe;\n}\n\n.u-dot {\n    font-size: 34rpx;\n    line-height: 34rpx;\n}\n\n.u-middle-line {\n    height: 4px;\n    background: var(--u-bg-black);\n    width: 80%;\n    position: absolute;\n    border-radius: 2px;\n    top: 50%;\n    left: 50%;\n    transform: translate(-50%, -50%);\n}\n\n.u-bottom-line-active {\n    background: $u-type-primary;\n}\n\n.u-bottom-line {\n    height: 4px;\n    background: var(--u-bg-black);\n    width: 80%;\n    position: absolute;\n    border-radius: 2px;\n    bottom: 0;\n    left: 50%;\n    transform: translate(-50%);\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-modal/service.ts",
    "content": "/**\n * u-modal 函数式调用事件名（全平台）\n * @description\n * - useModal() 通过 uni.$emit 派发事件\n * - <u-modal /> 通过 uni.$on 监听事件并转调自身 show/hide\n */\n\nimport type { ModalProps } from './types';\n\n// 普通（页面级）modal 事件\nexport const U_MODAL_EVENT_SHOW = 'uview-pro:u-modal:show:';\nexport const U_MODAL_EVENT_HIDE = 'uview-pro:u-modal:hide:';\nexport const U_MODAL_EVENT_CLEAR_LOADING = 'uview-pro:u-modal:clear-loading:';\n\n// 全局（App 根部）modal 事件，供 useModal() 使用\nexport const U_MODAL_GLOBAL_EVENT_SHOW = 'uview-pro:u-modal:global:show';\nexport const U_MODAL_GLOBAL_EVENT_HIDE = 'uview-pro:u-modal:global:hide';\nexport const U_MODAL_GLOBAL_EVENT_CLEAR_LOADING = 'uview-pro:u-modal:global:clear-loading';\n\n// 根据当前页面获取事件名\nexport function getEventWithCurrentPage(event: string, page?: string | boolean) {\n    if (page && typeof page === 'string' && page !== '') {\n        return event + page;\n    }\n    return event + getCurrentPage();\n}\n\n// 获取当前页面路由\nfunction getCurrentPage() {\n    try {\n        const pages = getCurrentPages();\n        const currentPage = pages[pages.length - 1].route as string;\n        return currentPage || '';\n    } catch (error) {\n        return '';\n    }\n}\n\n/**\n * u-modal 函数式调用载荷类型\n * @description 完整覆盖 u-modal 的所有 props（除 modelValue 外）\n */\nexport type ModalPayload = Partial<Omit<ModalProps, 'modelValue'>> & {\n    /** 确认回调 */\n    onConfirm?: () => void;\n    /** 取消回调 */\n    onCancel?: () => void;\n};\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-modal/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport { getColor, useLocale } from '../../';\n\nconst { t } = useLocale();\n\n/**\n * u-modal 组件 props 类型定义\n * @description 弹窗模态框，支持多种样式和交互\n */\nexport const ModalProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 是否显示模态框 */\n    modelValue: {\n        type: Boolean,\n        default: false\n    },\n    /** 层级z-index */\n    zIndex: {\n        type: [Number, String] as PropType<number | string>,\n        default: ''\n    },\n    /** 标题 */\n    title: {\n        type: String,\n        default: () => t('uModal.title')\n    },\n    /** 弹窗宽度 */\n    width: {\n        type: [Number, String] as PropType<number | string>,\n        default: 600\n    },\n    /** 弹窗内容 */\n    content: {\n        type: String,\n        default: ''\n    },\n    /** 是否显示标题 */\n    showTitle: {\n        type: Boolean,\n        default: true\n    },\n    /** 是否显示确认按钮 */\n    showConfirmButton: {\n        type: Boolean,\n        default: true\n    },\n    /** 是否显示取消按钮 */\n    showCancelButton: {\n        type: Boolean,\n        default: false\n    },\n    /** 确认文案 */\n    confirmText: {\n        type: String,\n        default: () => t('uModal.confirmText')\n    },\n    /** 取消文案 */\n    cancelText: {\n        type: String,\n        default: () => t('uModal.cancelText')\n    },\n    /** 确认按钮颜色 */\n    confirmColor: {\n        type: String,\n        default: () => getColor('primary')\n    },\n    /** 取消文字颜色 */\n    cancelColor: {\n        type: String,\n        default: () => getColor('contentColor')\n    },\n    /** 圆角值 */\n    borderRadius: {\n        type: [Number, String] as PropType<number | string>,\n        default: 16\n    },\n    /** 标题的样式 */\n    titleStyle: {\n        type: Object as PropType<Record<string, any>>,\n        default: () => ({})\n    },\n    /** 内容的样式 */\n    contentStyle: {\n        type: Object as PropType<Record<string, any>>,\n        default: () => ({})\n    },\n    /** 取消按钮的样式 */\n    cancelStyle: {\n        type: Object as PropType<Record<string, any>>,\n        default: () => ({})\n    },\n    /** 确定按钮的样式 */\n    confirmStyle: {\n        type: Object as PropType<Record<string, any>>,\n        default: () => ({})\n    },\n    /** 是否开启缩放效果 */\n    zoom: {\n        type: Boolean,\n        default: true\n    },\n    /** 是否异步关闭，只对确定按钮有效 */\n    asyncClose: {\n        type: Boolean,\n        default: false\n    },\n    /** 是否允许点击遮罩关闭modal */\n    maskCloseAble: {\n        type: Boolean,\n        default: false\n    },\n    /** 给一个负的margin-top，往上偏移，避免和键盘重合的情况 */\n    negativeTop: {\n        type: [String, Number] as PropType<number | string>,\n        default: 0\n    },\n    /** 是否作为全局根部 modal（通常放在 App.vue 中，给 useModal() 使用） */\n    global: {\n        type: Boolean,\n        default: false\n    },\n    /** 是否作为页面级 modal（通常放在页面中，给 useModal({ page: true }) 使用） */\n    page: {\n        type: [Boolean, String] as PropType<boolean | string>,\n        default: false\n    }\n};\n\n/**\n * u-modal 组件 props 类型\n */\nexport type ModalProps = ExtractPropTypes<typeof ModalProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-modal/u-modal.vue",
    "content": "<template>\n    <view>\n        <u-popup\n            v-model=\"popupValue\"\n            mode=\"center\"\n            :zoom=\"effectiveConfig.zoom\"\n            :popup=\"false\"\n            :z-index=\"uZIndex\"\n            :length=\"effectiveConfig.width\"\n            :mask-close-able=\"effectiveConfig.maskCloseAble\"\n            :border-radius=\"effectiveConfig.borderRadius\"\n            :negative-top=\"effectiveConfig.negativeTop\"\n            :custom-class=\"effectiveConfig.customClass\"\n            @close=\"popupClose\"\n        >\n            <view class=\"u-model\" :style=\"$u.toStyle(effectiveConfig.customStyle)\">\n                <view\n                    v-if=\"effectiveConfig.showTitle\"\n                    class=\"u-model__title u-line-1\"\n                    :style=\"$u.toStyle(effectiveConfig.titleStyle)\"\n                >\n                    {{ effectiveConfig.title }}\n                </view>\n                <view class=\"u-model__content\">\n                    <view v-if=\"slots.default\" :style=\"$u.toStyle(effectiveConfig.contentStyle)\">\n                        <slot />\n                    </view>\n                    <view v-else class=\"u-model__content__message\" :style=\"$u.toStyle(effectiveConfig.contentStyle)\">\n                        <text>{{ effectiveConfig.content }}</text>\n                    </view>\n                </view>\n                <view\n                    v-if=\"effectiveConfig.showCancelButton || effectiveConfig.showConfirmButton\"\n                    class=\"u-model__footer u-border-top\"\n                >\n                    <view\n                        v-if=\"effectiveConfig.showCancelButton\"\n                        :hover-stay-time=\"100\"\n                        hover-class=\"u-model__btn--hover\"\n                        class=\"u-model__footer__button\"\n                        :style=\"$u.toStyle(cancelBtnStyle)\"\n                        @tap=\"cancel\"\n                    >\n                        {{ effectiveConfig.cancelText }}\n                    </view>\n                    <view\n                        v-if=\"effectiveConfig.showConfirmButton || slots['confirm-button']\"\n                        class=\"u-model__footer__button hairline-left\"\n                        :hover-stay-time=\"100\"\n                        :hover-class=\"effectiveConfig.asyncClose ? 'none' : 'u-model__btn--hover'\"\n                        :style=\"[confirmBtnStyle]\"\n                        @tap=\"confirm\"\n                    >\n                        <slot v-if=\"slots['confirm-button']\" name=\"confirm-button\"></slot>\n                        <template v-else>\n                            <u-loading mode=\"circle\" :color=\"effectiveConfig.confirmColor\" v-if=\"loading\"></u-loading>\n                            <template v-else>\n                                {{ effectiveConfig.confirmText }}\n                            </template>\n                        </template>\n                    </view>\n                </view>\n            </view>\n        </u-popup>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-modal',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, useSlots, onMounted, onBeforeUnmount } from 'vue';\nimport { onPageHide, onPageShow } from '@dcloudio/uni-app';\nimport { $u } from '../..';\nimport { ModalProps } from './types';\nimport {\n    U_MODAL_EVENT_CLEAR_LOADING,\n    U_MODAL_EVENT_HIDE,\n    U_MODAL_EVENT_SHOW,\n    U_MODAL_GLOBAL_EVENT_CLEAR_LOADING,\n    U_MODAL_GLOBAL_EVENT_HIDE,\n    U_MODAL_GLOBAL_EVENT_SHOW,\n    getEventWithCurrentPage,\n    type ModalPayload\n} from './service';\n\n/**\n * modal 模态框\n * @description 弹出模态框，常用于消息提示、消息确认、在当前页面内完成特定的交互操作\n * @tutorial https://uviewpro.cn/zh/components/modal.html\n * @property {Boolean} value 是否显示模态框\n * @property {String | Number} z-index 层级\n * @property {String} title 模态框标题（默认\"提示\"）\n * @property {String | Number} width 模态框宽度（默认600）\n * @property {String} content 模态框内容（默认\"内容\"）\n * @property {Boolean} show-title 是否显示标题（默认true）\n * @property {Boolean} async-close 是否异步关闭，只对确定按钮有效（默认false）\n * @property {Boolean} show-confirm-button 是否显示确认按钮（默认true）\n * @property {String | Number} negative-top modal往上偏移的值\n * @property {Boolean} show-cancel-button 是否显示取消按钮（默认false）\n * @property {Boolean} mask-close-able 是否允许点击遮罩关闭modal（默认false）\n * @property {String} confirm-text 确认按钮的文字内容（默认\"确认\"）\n * @property {String} cancel-text 取消按钮的文字内容（默认\"取消\"）\n * @property {String} cancel-color 取消按钮的颜色（默认\"var(--u-content-color)\"）\n * @property {String} confirm-color 确认按钮的文字内容（默认主题色primary）\n * @property {String | Number} border-radius 模态框圆角值，单位rpx（默认16）\n * @property {Object} title-style 自定义标题样式，对象形式\n * @property {Object} content-style 自定义内容样式，对象形式\n * @property {Object} cancel-style 自定义取消按钮样式，对象形式\n * @property {Object} confirm-style 自定义确认按钮样式，对象形式\n * @property {Boolean} zoom 是否开启缩放模式（默认true）\n * @event {Function} confirm 确认按钮被点击\n * @event {Function} cancel 取消按钮被点击\n * @example <u-modal :src=\"title\" :content=\"content\"></u-modal>\n */\n\nconst props = defineProps(ModalProps);\nconst emit = defineEmits(['update:modelValue', 'confirm', 'cancel']);\nconst slots = useSlots();\n// 是否已经初始化事件监听\nconst isInit = ref(false);\n// 确认按钮是否正在加载中\nconst loading = ref(false);\nconst isGlobal = computed(() => !!props.global);\nconst isPage = computed(() => !!props.page);\nconst showEvent = computed(() =>\n    isGlobal.value\n        ? U_MODAL_GLOBAL_EVENT_SHOW\n        : isPage.value\n          ? getEventWithCurrentPage(U_MODAL_EVENT_SHOW, props.page)\n          : ''\n);\nconst hideEvent = computed(() =>\n    isGlobal.value\n        ? U_MODAL_GLOBAL_EVENT_HIDE\n        : isPage.value\n          ? getEventWithCurrentPage(U_MODAL_EVENT_HIDE, props.page)\n          : ''\n);\nconst clearLoadingEvent = computed(() =>\n    isGlobal.value\n        ? U_MODAL_GLOBAL_EVENT_CLEAR_LOADING\n        : isPage.value\n          ? getEventWithCurrentPage(U_MODAL_EVENT_CLEAR_LOADING, props.page)\n          : ''\n);\n\n// 存储用户传入的回调函数\nlet userOnConfirm: (() => void) | null = null;\nlet userOnCancel: (() => void) | null = null;\n\n// 需要与 effectiveConfig 合并的 props 键名列表（用于函数式调用）\nconst MERGE_PROPS_KEYS = [\n    'title',\n    'content',\n    'showTitle',\n    'showConfirmButton',\n    'showCancelButton',\n    'confirmText',\n    'cancelText',\n    'confirmColor',\n    'cancelColor',\n    'confirmStyle',\n    'cancelStyle',\n    'titleStyle',\n    'contentStyle',\n    'asyncClose',\n    'borderRadius',\n    'width',\n    'zoom',\n    'maskCloseAble',\n    'negativeTop',\n    'zIndex',\n    'customStyle',\n    'customClass'\n] as const;\n\n// 函数式调用时的临时配置\nconst tempConfig = ref<Partial<ModalPayload>>({});\n\n// 函数式调用时的内部显示状态（用于 global 模式）\nconst internalShow = ref(false);\n\n// 有效的配置（函数式调用时合并 tempConfig 和 props，v-model 时使用 props）\nconst effectiveConfig = computed(() => {\n    // 如果有临时配置（函数式调用），合并用户配置与 props 默认值\n    if (Object.keys(tempConfig.value).length > 0) {\n        const result: Record<string, any> = {};\n        for (const key of MERGE_PROPS_KEYS) {\n            // 用户配置优先，否则使用 props 默认值\n            result[key] = (tempConfig.value as Record<string, any>)[key] ?? (props as Record<string, any>)[key];\n        }\n        result.zIndex = tempConfig.value.zIndex ?? props.zIndex ?? $u.zIndex.popup;\n        return result;\n    }\n    // v-model 直接控制时使用 props\n    return props;\n});\n// 取消按钮样式\nconst cancelBtnStyle = computed(() => {\n    return Object.assign({ color: effectiveConfig.value.cancelColor }, effectiveConfig.value.cancelStyle);\n});\n// 确认按钮样式\nconst confirmBtnStyle = computed(() => {\n    return Object.assign({ color: effectiveConfig.value.confirmColor }, effectiveConfig.value.confirmStyle);\n});\n// 弹窗的样式\nconst uZIndex = computed(() => effectiveConfig.value.zIndex ?? $u.zIndex.popup);\n// 是否使用内部状态控制显示（global 模式）\nconst useInternalShow = computed(() => isGlobal.value || isPage.value);\n// 最终显示状态\nconst finalShow = computed(() => {\n    if (useInternalShow.value) {\n        return internalShow.value;\n    }\n    return props.modelValue;\n});\n// u-popup 绑定的值\nconst popupValue = computed({\n    get: () => finalShow.value,\n    set: (val: boolean) => {\n        if (useInternalShow.value) {\n            internalShow.value = val;\n        } else {\n            emit('update:modelValue', val);\n        }\n    }\n});\n\n// 如果是异步关闭时，外部修改v-model的值为false时，重置内部的loading状态，避免下次打开的时候，状态混乱\nwatch(\n    () => popupValue.value,\n    n => {\n        if (n === true) loading.value = false;\n    }\n);\n\n/**\n * 确认按钮点击事件\n */\nfunction confirm() {\n    // 先调用回调，再重置配置\n    const onConfirm = userOnConfirm;\n    // 异步关闭\n    if (effectiveConfig.value.asyncClose) {\n        loading.value = true;\n    } else {\n        popupValue.value = false;\n        // 延迟重置配置，避免闪屏\n        setTimeout(() => resetTempConfig(), 300);\n    }\n    emit('confirm');\n    // 调用函数式调用时用户传入的回调\n    onConfirm?.();\n}\n\n/**\n * 取消按钮点击事件\n */\nfunction cancel() {\n    // 先调用回调，再重置配置\n    const onCancel = userOnCancel;\n    // 延迟重置配置，避免闪屏\n    setTimeout(() => resetTempConfig(), 300);\n    emit('cancel');\n    popupValue.value = false;\n    // 调用函数式调用时用户传入的回调\n    onCancel?.();\n    // 目前popup弹窗关闭有一个延时操作，此处做一个延时\n    // 避免确认按钮文字变成了\"确定\"字样，modal还没消失，造成视觉不好的效果\n    setTimeout(() => {\n        loading.value = false;\n    }, 300);\n}\n\n/**\n * 点击遮罩关闭modal，设置v-model的值为false，否则无法第二次弹起modal\n */\nfunction popupClose() {\n    popupValue.value = false;\n    resetTempConfig();\n}\n\n/**\n * 清除加载中的状态\n */\nfunction clearLoading() {\n    loading.value = false;\n}\n\n/**\n * 函数式调用显示 modal\n */\nfunction onServiceShow(payload: ModalPayload) {\n    // 保存回调函数\n    userOnConfirm = payload.onConfirm ?? null;\n    userOnCancel = payload.onCancel ?? null;\n\n    // 只保存用户传入的配置（过滤掉回调）\n    const { onConfirm, onCancel, ...rest } = payload;\n    tempConfig.value = rest;\n\n    // 使用内部状态控制显示\n    internalShow.value = true;\n}\n\n/**\n * 函数式调用关闭 modal\n */\nfunction onServiceHide() {\n    internalShow.value = false;\n    resetTempConfig();\n}\n\n/**\n * 重置临时配置\n */\nfunction resetTempConfig() {\n    tempConfig.value = {};\n    userOnConfirm = null;\n    userOnCancel = null;\n}\n\n// 开始监听事件\nfunction startListeners() {\n    if (isInit.value) {\n        return;\n    }\n    isInit.value = true;\n    if (showEvent.value) {\n        uni?.$on && uni.$on(showEvent.value, onServiceShow);\n    }\n    if (hideEvent.value) {\n        uni?.$on && uni.$on(hideEvent.value, onServiceHide);\n    }\n    if (clearLoadingEvent.value) {\n        uni?.$on && uni.$on(clearLoadingEvent.value, clearLoading);\n    }\n}\n\n// 停止监听事件\nfunction stopListeners() {\n    if (!isInit.value) {\n        return;\n    }\n    isInit.value = false;\n    if (showEvent.value) {\n        uni?.$off && uni.$off(showEvent.value, onServiceShow);\n    }\n    if (hideEvent.value) {\n        uni?.$off && uni.$off(hideEvent.value, onServiceHide);\n    }\n    if (clearLoadingEvent.value) {\n        uni?.$off && uni.$off(clearLoadingEvent.value, clearLoading);\n    }\n}\n\n// 移除所有事件监听\nfunction removeAllListeners() {\n    if (showEvent.value) {\n        uni?.$off && uni.$off(showEvent.value);\n    }\n    if (hideEvent.value) {\n        uni?.$off && uni.$off(hideEvent.value);\n    }\n    if (clearLoadingEvent.value) {\n        uni?.$off && uni.$off(clearLoadingEvent.value);\n    }\n}\n\nonPageShow(() => {\n    startListeners();\n});\n\nonPageHide(() => {\n    stopListeners();\n});\n\nonMounted(() => {\n    startListeners();\n});\n\nonBeforeUnmount(() => {\n    stopListeners();\n});\n\ndefineExpose({\n    clearLoading\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-model {\n    height: auto;\n    overflow: hidden;\n    font-size: 32rpx;\n    background-color: var(--u-bg-white);\n\n    &__btn--hover {\n        background-color: rgb(230, 230, 230);\n    }\n\n    &__title {\n        padding-top: 48rpx;\n        font-weight: 500;\n        text-align: center;\n        color: $u-main-color;\n    }\n\n    &__content {\n        &__message {\n            padding: 48rpx;\n            font-size: 30rpx;\n            text-align: center;\n            color: $u-content-color;\n        }\n    }\n\n    &__footer {\n        @include vue-flex;\n\n        &__button {\n            flex: 1;\n            height: 100rpx;\n            line-height: 100rpx;\n            font-size: 32rpx;\n            box-sizing: border-box;\n            cursor: pointer;\n            text-align: center;\n            border-radius: 4rpx;\n        }\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-navbar/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport zIndex from '../../libs/config/zIndex';\n\n/**\n * u-navbar 组件 props 类型定义\n * @description 自定义导航栏，支持多种样式\n */\nexport const NavbarProps = {\n    /** 导航栏高度，单位px，非rpx */\n    height: {\n        type: [String, Number] as PropType<string | number>,\n        default: ''\n    },\n    /** 返回箭头的颜色 */\n    backIconColor: {\n        type: String,\n        default: 'var(--u-content-color)'\n    },\n    /** 左边返回的图标 */\n    backIconName: {\n        type: String,\n        default: 'nav-back'\n    },\n    /** 左边返回图标的大小，rpx */\n    backIconSize: {\n        type: [String, Number] as PropType<string | number>,\n        default: '44'\n    },\n    /** 返回的文字提示 */\n    backText: {\n        type: String,\n        default: ''\n    },\n    /** 返回的文字的 样式 */\n    backTextStyle: {\n        type: Object as PropType<Record<string, any>>,\n        default: () => ({ color: 'var(--u-content-color)' })\n    },\n    /** 导航栏标题 */\n    title: {\n        type: String,\n        default: ''\n    },\n    /** 标题的宽度，单位rpx */\n    titleWidth: {\n        type: [String, Number] as PropType<string | number>,\n        default: '250'\n    },\n    /** 标题的颜色 */\n    titleColor: {\n        type: String,\n        default: 'var(--u-content-color)'\n    },\n    /** 标题字体是否加粗 */\n    titleBold: {\n        type: Boolean,\n        default: false\n    },\n    /** 标题的字体大小 */\n    titleSize: {\n        type: [String, Number] as PropType<string | number>,\n        default: 32\n    },\n    /** 是否显示导航栏左边返回图标和辅助文字 */\n    isBack: {\n        type: [Boolean, String] as PropType<boolean | string>,\n        default: true\n    },\n    /** 导航栏背景设置 */\n    background: {\n        type: Object as PropType<Record<string, any>>,\n        default: () => ({ background: 'var(--u-bg-white)' })\n    },\n    /** 导航栏是否固定在顶部 */\n    isFixed: {\n        type: Boolean,\n        default: true\n    },\n    /** 是否沉浸式，允许fixed定位后导航栏塌陷，仅fixed定位下生效 */\n    immersive: {\n        type: Boolean,\n        default: false\n    },\n    /** 是否显示导航栏的下边框 */\n    borderBottom: {\n        type: Boolean,\n        default: true\n    },\n    /** 固定在顶部时的z-index值 */\n    zIndex: {\n        type: [String, Number] as PropType<string | number>,\n        default: zIndex.navbar\n    },\n    /** 自定义返回逻辑方法 */\n    customBack: {\n        type: Function as PropType<() => void>,\n        default: null\n    }\n};\n\n/**\n * u-navbar 组件 props 类型\n */\nexport type NavbarProps = ExtractPropTypes<typeof NavbarProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-navbar/u-navbar.vue",
    "content": "<template>\n    <view>\n        <view\n            class=\"u-navbar\"\n            :style=\"navbarStyle\"\n            :class=\"{ 'u-navbar-fixed': props.isFixed, 'u-border-bottom': props.borderBottom }\"\n        >\n            <view class=\"u-status-bar\" :style=\"{ height: statusBarHeight + 'px' }\"></view>\n            <view class=\"u-navbar-inner\" :style=\"navbarInnerStyle\">\n                <view class=\"u-back-wrap\" v-if=\"props.isBack\" @tap=\"goBack\">\n                    <view class=\"u-icon-wrap\">\n                        <u-icon\n                            :name=\"props.backIconName\"\n                            :color=\"props.backIconColor\"\n                            :size=\"props.backIconSize\"\n                        ></u-icon>\n                    </view>\n                    <view class=\"u-icon-wrap u-back-text u-line-1\" v-if=\"props.backText\" :style=\"props.backTextStyle\">\n                        {{ props.backText }}\n                    </view>\n                </view>\n                <view class=\"u-slot-left\">\n                    <slot name=\"left\"></slot>\n                </view>\n                <view class=\"u-navbar-content-title\" v-if=\"props.title\" :style=\"titleStyle\">\n                    <view\n                        class=\"u-title u-line-1\"\n                        :style=\"{\n                            color: props.titleColor,\n                            fontSize: props.titleSize + 'rpx',\n                            fontWeight: props.titleBold ? 'bold' : 'normal'\n                        }\"\n                    >\n                        {{ props.title }}\n                    </view>\n                </view>\n                <view class=\"u-slot-content\">\n                    <slot></slot>\n                </view>\n                <view class=\"u-slot-right\">\n                    <slot name=\"right\"></slot>\n                </view>\n            </view>\n        </view>\n        <!-- 解决fixed定位后导航栏塌陷的问题 -->\n        <view\n            class=\"u-navbar-placeholder\"\n            v-if=\"props.isFixed && !props.immersive\"\n            :style=\"{ width: '100%', height: `${Number(navbarPlaceholderHeight)}px` }\"\n        ></view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-navbar',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed } from 'vue';\nimport { $u } from '../..';\nimport { NavbarProps } from './types';\n\n/**\n * navbar 自定义导航栏\n * @description 此组件一般用于在特殊情况下，需要自定义导航栏的时候用到，一般建议使用uniapp自带的导航栏。\n * @tutorial https://uviewpro.cn/zh/components/navbar.html\n * @property {String|Number} height 导航栏高度(不包括状态栏高度在内，内部自动加上)，注意这里的单位是px（默认44）\n * @property {String} back-icon-color 左边返回图标的颜色（默认var(--u-content-color)）\n * @property {String} back-icon-name 左边返回图标的名称，只能为uView自带的图标（默认arrow-left）\n * @property {String|Number} back-icon-size 左边返回图标的大小，单位rpx（默认30）\n * @property {String} back-text 返回图标右边的辅助提示文字\n * @property {Object} back-text-style 返回图标右边的辅助提示文字的样式，对象形式（默认{ color: 'var(--u-content-color)' }）\n * @property {String} title 导航栏标题，如设置为空字符，将会隐藏标题占位区域\n * @property {String|Number} title-width 导航栏标题的最大宽度，内容超出会以省略号隐藏，单位rpx（默认250）\n * @property {String} title-color 标题的颜色（默认var(--u-content-color)）\n * @property {String|Number} title-size 导航栏标题字体大小，单位rpx（默认32）\n * @property {Function} custom-back 自定义返回逻辑方法\n * @property {String|Number} z-index 固定在顶部时的z-index值（默认980）\n * @property {Boolean} is-back 是否显示导航栏左边返回图标和辅助文字（默认true）\n * @property {Object} background 导航栏背景设置，见官网说明（默认{ background: 'var(--u-bg-white)' }）\n * @property {Boolean} is-fixed 导航栏是否固定在顶部（默认true）\n * @property {Boolean} immersive 沉浸式，允许fixed定位后导航栏塌陷，仅fixed定位下生效（默认false）\n * @property {Boolean} border-bottom 导航栏底部是否显示下边框，如定义了较深的背景颜色，可取消此值（默认true）\n * @example <u-navbar back-text=\"返回\" title=\"剑未配妥，出门已是江湖\"></u-navbar>\n */\nconst props = defineProps(NavbarProps);\n// 获取系统状态栏的高度\nconst systemInfo = uni.getSystemInfoSync();\n\nlet menuButtonInfo: any = {};\n// 如果是小程序，获取右上角胶囊的尺寸信息，避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API，尚未兼容)\n// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ\nmenuButtonInfo = uni.getMenuButtonBoundingClientRect();\n// #endif\n\n// 状态栏高度\nconst statusBarHeight = ref(0);\n// #ifdef APP-HARMONY || MP-WEIXIN\nconst windowInfo = uni.getWindowInfo();\nstatusBarHeight.value = windowInfo.statusBarHeight || 0;\n// #endif\n// #ifndef APP-HARMONY || MP-WEIXIN\nstatusBarHeight.value = systemInfo.statusBarHeight || 0;\n// #endif\n\n// 转换字符数值为真正的数值\nconst navbarHeight = computed(() => {\n    // #ifdef APP || H5\n    return props.height ? props.height : 44;\n    // #endif\n    // #ifdef MP\n    // 小程序特别处理，让导航栏高度 = 胶囊高度 + 两倍胶囊顶部与状态栏底部的距离之差(相当于同时获得了导航栏底部与胶囊底部的距离)\n    // 此方法有缺陷，暂不用(会导致少了几个px)，采用直接固定值的方式\n    // return menuButtonInfo.height + (menuButtonInfo.top - this.statusBarHeight) * 2;//导航高度\n    let height = systemInfo.platform == 'ios' ? 44 : 48;\n    return props.height ? props.height : height;\n    // #endif\n});\n\n// 导航栏高度加上状态栏高度\nconst navbarPlaceholderHeight = computed(() => {\n    return Number(navbarHeight.value) + Number(statusBarHeight.value);\n});\n\n// 导航栏内部盒子的样式\nconst navbarInnerStyle = computed(() => {\n    let style: Record<string, any> = {};\n    // 导航栏宽度，如果在小程序下，导航栏宽度为胶囊的左边到屏幕左边的距离\n    style.height = String(navbarHeight.value) + 'px';\n    // 如果是各家小程序，导航栏内部的宽度需要减少右边胶囊的宽度\n    // #ifdef MP\n    let rightButtonWidth = systemInfo.windowWidth - menuButtonInfo.left;\n    style.marginRight = rightButtonWidth + 'px';\n    // #endif\n    return style;\n});\n\n// 整个导航栏的样式\nconst navbarStyle = computed(() => {\n    let style: Record<string, any> = {};\n    style.zIndex = props.zIndex ? props.zIndex : $u.zIndex.navbar;\n    // 合并用户传递的背景色对象\n    Object.assign(style, props.background);\n    return style;\n});\n\n// 导航中间的标题的样式\nconst titleStyle = computed(() => {\n    let style: Record<string, any> = {};\n    // #ifndef MP\n    style.left = (systemInfo.windowWidth - uni.upx2px(Number(props.titleWidth))) / 2 + 'px';\n    style.right = (systemInfo.windowWidth - uni.upx2px(Number(props.titleWidth))) / 2 + 'px';\n    // #endif\n    // #ifdef MP\n    // 此处是为了让标题显示区域即使在小程序有右侧胶囊的情况下也能处于屏幕的中间，是通过绝对定位实现的\n    let rightButtonWidth = systemInfo.windowWidth - menuButtonInfo.left;\n    style.left = (systemInfo.windowWidth - uni.upx2px(Number(props.titleWidth))) / 2 + 'px';\n    style.right =\n        rightButtonWidth -\n        (systemInfo.windowWidth - uni.upx2px(Number(props.titleWidth))) / 2 +\n        rightButtonWidth +\n        'px';\n    // #endif\n    style.width = uni.upx2px(Number(props.titleWidth)) + 'px';\n    return style;\n});\n\n/**\n * 返回按钮点击事件\n * 如果自定义了点击返回按钮的函数，则执行，否则执行返回逻辑\n */\nfunction goBack() {\n    if (typeof props.customBack === 'function') {\n        // 在微信，支付宝等环境(H5正常)，会导致父组件定义的customBack()函数体中的this变成子组件的this\n        // 通过bind()方法，绑定父组件的this，让this.customBack()的this为父组件的上下文\n        // props.customBack.bind($u.$parent.call(getCurrentInstance()?.proxy))();\n        props.customBack();\n    } else {\n        uni.navigateBack();\n    }\n}\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n\n.u-navbar {\n    width: 100%;\n}\n\n.u-navbar-fixed {\n    position: fixed;\n    left: 0;\n    right: 0;\n    top: 0;\n    z-index: 991;\n}\n\n.u-status-bar {\n    width: 100%;\n}\n\n.u-navbar-inner {\n    @include vue-flex;\n    justify-content: space-between;\n    position: relative;\n    align-items: center;\n}\n\n.u-back-wrap {\n    @include vue-flex;\n    align-items: center;\n    flex: 1;\n    flex-grow: 0;\n    padding: 14rpx 14rpx 14rpx 24rpx;\n}\n\n.u-back-text {\n    padding-left: 4rpx;\n    font-size: 30rpx;\n}\n\n.u-navbar-content-title {\n    @include vue-flex;\n    align-items: center;\n    justify-content: center;\n    flex: 1;\n    position: absolute;\n    left: 0;\n    right: 0;\n    height: 60rpx;\n    text-align: center;\n    flex-shrink: 0;\n}\n\n.u-navbar-centent-slot {\n    flex: 1;\n}\n\n.u-title {\n    line-height: 60rpx;\n    font-size: 32rpx;\n    flex: 1;\n}\n\n.u-navbar-right {\n    flex: 1;\n    @include vue-flex;\n    align-items: center;\n    justify-content: flex-end;\n}\n\n.u-slot-content {\n    flex: 1;\n    @include vue-flex;\n    align-items: center;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-no-network/image.ts",
    "content": "export const imageSrc =\n    'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAEYCAMAAABFglBLAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6M0U3MjVFMzQwNEY1MTFFQUE4MTNDOUEzMTVBREMxQjIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6M0U3MjVFMzUwNEY1MTFFQUE4MTNDOUEzMTVBREMxQjIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDozRTcyNUUzMjA0RjUxMUVBQTgxM0M5QTMxNUFEQzFCMiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDozRTcyNUUzMzA0RjUxMUVBQTgxM0M5QTMxNUFEQzFCMiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PkHIU9QAAAMAUExURdHW2OWiou7u7tve4dnc3/vw8N3g4sPCwvjn5+jo6M7Q0u6+vtyEhPXY2Li+wuikpPXW1uXo6dba3Pbg4Na5u+qurqqyt/HJydjb3fjo6LrAxO7Bwey1td6MjOrs7fbc3OTn6Maytf7+/vz19eqqqrzCxvzz87a8wLO6vuqxsf78/PDFxenr7L/FyNTY26+2u/z09MjMzqy0udnZ2dvb27G4vMjN0O7v8P339+Ll5u3v8NDS1ODj5frt7bC3vP76+u24uOKamtTW2MTIy9zc3N7e3vPQ0OCTk8DGyfDDw9LR0c7S1LussNbY2fPOztLU1cLHyrK6vvji4vrv78bKzPX29/np6crP0vjk5Ozu78bLzuepqczR1MHFyMDEyOq1tfTS0vP09cLIy9DU173Ex8bGxvHy88/U18vO0LK4vM7OzsTKzcPJzPLMzM/T1sbMz8HJy+7FxbW8wNTW18XKzvb3+MjLzczP0d3e3+Dh4r3Dxtna29zd3rK5vdPU1cfM0Prq6uOenuPm58HGyfHz8/ro6Lq/w8nO0bzCxcrKytjZ2uXm5vTU1LvBxbW7v+rp6eefn/39/eLi4u3t7Ozs7Pj4+Pr6+vX19fHx8erq6vPz8+Xl5ff39+fn5/v7+/z8/PLx8fX09Pb29ri4uOTk5PHw8OPj4/Py8ubm5vn5+e3s7Pb19fTz8/f29tfX1+7t7cvQ0+zr6/Ly8u3t7fr5+efm5quzuOvq6vT19uvr6/j5+a61uuy6uvb39/T09Ojn5+jq6621uvn6+t/i5KyzuPn4+Le+wvv6+s3S1fj4+fDw8OHk5vv7/Pr7++Xk5LS7v7y8vObl5fz9/ff4+OTj48DEx8XJy+Hk5euysu/x8re9wfn5+v38/Pv8/Pr6++vt7uLi4+Pi4ubl5uXk5dPV1tbV1fHMzNPX2e7u7ejn6PT19fX19PDw7/b29f39/vnr6+Hh4a+3u+7t7q61uePi48PHyf35+enp6fLz9PPz8qmxtuDg4N/f3/Dv7////////1cfN/UAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAlqElEQVR42uydCXwUVZrAk5CEJBAQshACCGyjIRwBJR0It6JBGZZBkRtm5PBgFXAXHBghqAMz6LjGTrd9n7lvwn0JQhARxYNxVJTMwcwOM+7uzK6Z3VXcrnTXVr2q6q7urrvfq26c+n4egXTSVfXv993veym4JkklKdoj0IBoogHRgGiiAdGAaKIB0YBoogHRgGiiAdFEA6IBUVuwx+vqet/v1YAkhxwmcNT9gvjnsAYkGcT7eN1TtThe+1TdL2o1IEkg+rrvUV90MF9oQBIqv6ijF4a3d51XA5J4jVVXx3z587ojGpDEm/QwkO9pQJJB2CvksAYk8fJUXT31xZG63ppRTwI5QgcgR35Rd1MDkgxSX1f31P33P1V3i3u936HUyc3edWSsjuEakKRRW3r9kVv+JrRsrwbklpKTnXs+z0wfONOtAUm8rJu55oqfkZ0TOzUgCZS3Zh7s54+S5RqQhNGYMsnPISkakCSiQcjkNzUgasvUDaVsBF1fb9GXd//B0ziliPzjEA2IujLqGRaMST+cawgLNpn4q30aEDV1Va+dYRqzNy00RMoYUmdpQNTzcb8sCtuKH8w9Z4iWLuIbVzQgapmOBedDOO6c0WjgENK2vKwBUUUmvBSiUbrqxwZuOU18d5MGhEe/dI6a2WvIxA0HX1hfvH7V8gUpA9Mz3x/VuVTRLxvwdAhH5aJjBj4hv39QAxIl743ITHm6azBPnOCfVLwlc6pR3upYFbLjvIuDlEUqRYZo38JYS4gVt5rNZhMQO46byksoMeG4w8QIjtvMpJA/wP1EdZ0bKvkitkh555mBA3zSLnBlSFnNnlJvEJJ95ItW3pJAamvtZhy3m/T0g7fhthJGiG+EviYgmEJ/wHFP6GsbnlZSoicoucxmGwHVguPTBz543C9LHky/Jnql1w5KxWGo8KsThsAFYneYMOb5mlnP11ZCrwOPjfgGI8RqsZuZtUOsFmbllFhZP+zEbc8vGcqzMibv7qos3rd7Mg+TrQv2vCVkiLYc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';\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-no-network/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport zIndex from '../../libs/config/zIndex';\nimport { useLocale } from '../../';\n\nconst { t } = useLocale();\n\n/**\n * u-no-network 组件 props 类型定义\n * @description 无网络提示，支持自定义图片、提示语、z-index\n */\nexport const NoNetworkProps = {\n    /** 页面文字提示 */\n    tips: {\n        type: String,\n        default: () => t('uNoNetwork.tips')\n    },\n    /** 一个z-index值，用于设置没有网络这个组件的层次 */\n    zIndex: {\n        type: [Number, String] as PropType<number | string>,\n        default: zIndex.noNetwork\n    },\n    /** 没有网络的图片提示 */\n    image: {\n        type: String,\n        default: ''\n    }\n};\n\n/**\n * u-no-network 组件 props 类型\n */\nexport type NoNetworkProps = ExtractPropTypes<typeof NoNetworkProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-no-network/u-no-network.vue",
    "content": "<template>\n    <view class=\"u-no-network\" v-if=\"!isConnected\" :style=\"{ 'z-index': uZIndex }\" @touchmove.stop.prevent=\"() => {}\">\n        <view class=\"u-inner\">\n            <image class=\"u-error-icon\" :src=\"image\" mode=\"widthFix\"></image>\n            <view class=\"u-tips\">\n                {{ tips }}\n            </view>\n            <!-- 只有APP平台，才能跳转设置页，因为需要调用plus环境 -->\n            <!-- #ifdef APP-PLUS -->\n            <view class=\"u-to-setting\">\n                {{ t('uNoNetwork.checkNetwork') }}\n                <text class=\"u-setting-btn\" @tap=\"openSettings\">\n                    {{ t('uNoNetwork.setting') }}\n                </text>\n            </view>\n            <!-- #endif -->\n            <view class=\"u-retry\" :hover-stay-time=\"150\" @tap=\"retry\" hover-class=\"u-retry-hover\">\n                {{ t('uNoNetwork.retry') }}\n            </view>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-no-network',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted } from 'vue';\nimport { imageSrc } from './image';\nimport { $u, useLocale } from '../..';\nimport { NoNetworkProps } from './types';\n\n/**\n * noNetwork 无网络提示\n * @description 该组件无需任何配置，引入即可，内部自动处理所有功能和事件。\n * @tutorial https://uviewpro.cn/zh/components/noNetwork.html\n * @property {String} tips 没有网络时的提示语（默认哎呀，网络信号丢失）\n * @property {String | Number} zIndex 组件的z-index值（默认1080）\n * @property {String} image 无网络的图片提示，可用的src地址或base64图片\n * @event {Function} retry 用户点击页面的\"重试\"按钮时触发\n * @example <u-no-network></u-no-network>\n */\n\nconst props = defineProps(NoNetworkProps);\n\nconst { t } = useLocale();\n\nconst isConnected = ref(true); // 是否有网络连接\nconst networkType = ref<string>('none'); // 网络类型\nconst isIOS = ref(false); // 是否iOS平台\n\n/**\n * 计算z-index，优先使用props，否则取$u.zIndex.noNetwork\n */\nconst uZIndex = computed(() => {\n    return props.zIndex ? props.zIndex : $u.zIndex.noNetwork;\n});\n\n/**\n * 组件挂载时初始化网络监听\n * 保留所有说明注释\n */\nonMounted(() => {\n    isIOS.value = uni.getSystemInfoSync().platform === 'ios';\n    uni.onNetworkStatusChange(res => {\n        isConnected.value = res.isConnected;\n        networkType.value = res.networkType;\n    });\n    uni.getNetworkType({\n        success: res => {\n            networkType.value = res.networkType;\n            if (res.networkType == 'none') {\n                isConnected.value = false;\n            } else {\n                isConnected.value = true;\n            }\n        }\n    });\n});\n\n/**\n * 重新检查网络\n * @event retry 用户点击页面的\"重试\"按钮时触发\n */\nfunction retry() {\n    uni.getNetworkType({\n        success: res => {\n            networkType.value = res.networkType;\n            if (res.networkType == 'none') {\n                uni.showToast({\n                    title: t('uNoNetwork.noConnection'),\n                    icon: 'none',\n                    position: 'top'\n                });\n                isConnected.value = false;\n            } else {\n                uni.showToast({\n                    title: t('uNoNetwork.connected'),\n                    icon: 'none',\n                    position: 'top'\n                });\n                isConnected.value = true;\n            }\n        }\n    });\n    emit('retry');\n}\n\n/**\n * 打开系统设置页（仅APP平台）\n */\nfunction openSettings() {\n    if (networkType.value == 'none') {\n        openSystemSettings();\n        return;\n    }\n}\n\n/**\n * 打开APP设置页（仅APP平台）\n */\nfunction openAppSettings() {\n    gotoAppSetting();\n}\n\n/**\n * 打开系统设置页（仅APP平台）\n */\nfunction openSystemSettings() {\n    // 以下方法来自5+范畴，如需深究，请自行查阅相关文档\n    // https://ask.dcloud.net.cn/docs/\n    if (isIOS.value) {\n        gotoiOSSetting();\n    } else {\n        gotoAndroidSetting();\n    }\n}\n\n/**\n * 获取蜂窝网络权限（仅APP平台）\n */\nfunction network() {\n    // 该方法仅供参考，实际使用请查阅5+文档\n    let result: number | null = null;\n    const cellularData = plus.ios.newObject('CTCellularData');\n    const state = cellularData.plusGetAttribute('restrictedState');\n    if (state == 0) {\n        result = null;\n    } else if (state == 2) {\n        result = 1;\n    } else if (state == 1) {\n        result = 2;\n    }\n    plus.ios.deleteObject(cellularData);\n    return result;\n}\n\n/**\n * 跳转到APP设置页（仅APP平台）\n */\nfunction gotoAppSetting() {\n    if (isIOS.value) {\n        // @ts-ignore\n        const UIApplication = plus.ios.import('UIApplication');\n        // @ts-ignore\n        const application2 = UIApplication.sharedApplication();\n        // @ts-ignore\n        const NSURL2 = plus.ios.import('NSURL');\n        // @ts-ignore\n        const setting2 = NSURL2.URLWithString('app-settings:');\n        application2.openURL(setting2);\n        // @ts-ignore\n        plus.ios.deleteObject(setting2);\n        // @ts-ignore\n        plus.ios.deleteObject(NSURL2);\n        // @ts-ignore\n        plus.ios.deleteObject(application2);\n    } else {\n        // @ts-ignore\n        const Intent = plus.android.importClass('android.content.Intent');\n        // @ts-ignore\n        const Settings = plus.android.importClass('android.provider.Settings');\n        // @ts-ignore\n        const Uri = plus.android.importClass('android.net.Uri');\n        // @ts-ignore\n        const mainActivity = plus.android.runtimeMainActivity();\n        // @ts-ignore\n        const intent = new Intent();\n        // @ts-ignore\n        intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);\n        // @ts-ignore\n        const uri = Uri.fromParts('package', mainActivity.getPackageName(), null);\n        intent.setData(uri);\n        // @ts-ignore\n        mainActivity.startActivity(intent);\n    }\n}\n\n/**\n * 跳转到iOS设置页（仅APP平台）\n */\nfunction gotoiOSSetting() {\n    // @ts-ignore\n    const UIApplication = plus.ios.import('UIApplication');\n    // @ts-ignore\n    const application2 = UIApplication.sharedApplication();\n    // @ts-ignore\n    const NSURL2 = plus.ios.import('NSURL');\n    // @ts-ignore\n    const setting2 = NSURL2.URLWithString('App-prefs:root=General');\n    application2.openURL(setting2);\n    // @ts-ignore\n    plus.ios.deleteObject(setting2);\n    // @ts-ignore\n    plus.ios.deleteObject(NSURL2);\n    // @ts-ignore\n    plus.ios.deleteObject(application2);\n}\n\n/**\n * 跳转到Android设置页（仅APP平台）\n */\nfunction gotoAndroidSetting() {\n    // @ts-ignore\n    const Intent = plus.android.importClass('android.content.Intent');\n    // @ts-ignore\n    const Settings = plus.android.importClass('android.provider.Settings');\n    // @ts-ignore\n    const mainActivity = plus.android.runtimeMainActivity();\n    // @ts-ignore\n    const intent = new Intent(Settings.ACTION_SETTINGS);\n    // @ts-ignore\n    mainActivity.startActivity(intent);\n}\n\n// 组合式API emit\nconst emit = defineEmits(['retry']);\n\ndefineExpose({\n    retry,\n    openSettings,\n    openAppSettings\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-no-network {\n    background-color: var(--u-bg-white);\n    position: fixed;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n}\n\n.u-inner {\n    height: 100vh;\n    @include vue-flex;\n    flex-direction: column;\n    align-items: center;\n    justify-content: center;\n    margin-top: -15%;\n}\n\n.u-tips {\n    color: $u-tips-color;\n    font-size: 28rpx;\n    padding: 30rpx 0;\n}\n\n.u-error-icon {\n    width: 300rpx;\n}\n\n.u-to-setting {\n    color: $u-light-color;\n    font-size: 26rpx;\n}\n\n.u-setting-btn {\n    font-size: 26rpx;\n    color: $u-type-primary;\n}\n\n.u-retry {\n    margin-top: 30rpx;\n    border: 1px solid $u-tips-color;\n    color: $u-tips-color;\n    font-size: 28rpx;\n    padding: 6rpx 30rpx;\n    border-radius: 3px;\n}\n\n.u-retry-hover {\n    color: var(--u-white-color);\n    background-color: $u-tips-color;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-notice-bar/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { Direction, PlayState, ThemeType } from '../../types/global';\n\n/**\n * NoticeBarProps 滚动通知 props 类型定义\n * @description 滚动通告场景，有多种模式可供选择\n */\nexport const NoticeBarProps = {\n    /** 滚动内容，数组形式 */\n    list: {\n        type: Array as PropType<string[]>,\n        default: () => []\n    },\n    /** 显示的主题，success|error|primary|info|warning */\n    type: {\n        type: String as PropType<ThemeType>,\n        default: 'warning'\n    },\n    /** 是否显示左侧的音量图标 */\n    volumeIcon: {\n        type: Boolean,\n        default: true\n    },\n    /** 音量喇叭的大小 */\n    volumeSize: {\n        type: [Number, String] as PropType<number | string>,\n        default: 34\n    },\n    /** 是否显示右侧的右箭头图标 */\n    moreIcon: {\n        type: Boolean,\n        default: false\n    },\n    /** 是否显示右侧的关闭图标 */\n    closeIcon: {\n        type: Boolean,\n        default: false\n    },\n    /** 是否自动播放 */\n    autoplay: {\n        type: Boolean,\n        default: true\n    },\n    /** 文字颜色，各图标也会使用文字颜色 */\n    color: {\n        type: String,\n        default: ''\n    },\n    /** 背景颜色 */\n    bgColor: {\n        type: String,\n        default: ''\n    },\n    /** 滚动方向，horizontal-水平滚动，vertical-垂直滚动 */\n    mode: {\n        type: String as PropType<Direction>,\n        default: 'horizontal'\n    },\n    /** 是否显示 */\n    show: {\n        type: Boolean,\n        default: true\n    },\n    /** 字体大小，单位rpx */\n    fontSize: {\n        type: [Number, String] as PropType<number | string>,\n        default: 28\n    },\n    /** 滚动一个周期的时间长，单位ms */\n    duration: {\n        type: [Number, String] as PropType<number | string>,\n        default: 2000\n    },\n    /** 水平滚动时的滚动速度，即每秒滚动多少rpx */\n    speed: {\n        type: [Number, String] as PropType<number | string>,\n        default: 160\n    },\n    /** 水平滚动时，是否采用衔接形式滚动 */\n    isCircular: {\n        type: Boolean,\n        default: true\n    },\n    /** 播放状态，play-播放，paused-暂停 */\n    playState: {\n        type: String as PropType<PlayState>,\n        default: 'play'\n    },\n    /** 是否禁止用手滑动切换 */\n    disableTouch: {\n        type: Boolean,\n        default: true\n    },\n    /** 滚动通知设置圆角 */\n    borderRadius: {\n        type: [Number, String] as PropType<number | string>,\n        default: 0\n    },\n    /** 通知的边距 */\n    padding: {\n        type: [Number, String] as PropType<number | string>,\n        default: '18rpx 24rpx'\n    },\n    /** list列表为空时，是否显示组件 */\n    noListHidden: {\n        type: Boolean,\n        default: true\n    }\n};\n\nexport type NoticeBarProps = ExtractPropTypes<typeof NoticeBarProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-notice-bar/u-notice-bar.vue",
    "content": "<template>\n    <view class=\"u-notice-bar-wrap\" v-if=\"isShow\" :style=\"{ borderRadius: props.borderRadius + 'rpx' }\">\n        <block v-if=\"props.mode === 'horizontal' && props.isCircular\">\n            <u-row-notice\n                :type=\"props.type\"\n                :color=\"props.color\"\n                :bgColor=\"props.bgColor\"\n                :list=\"props.list\"\n                :volumeIcon=\"props.volumeIcon\"\n                :moreIcon=\"props.moreIcon\"\n                :volumeSize=\"props.volumeSize\"\n                :closeIcon=\"props.closeIcon\"\n                :mode=\"props.mode\"\n                :fontSize=\"props.fontSize\"\n                :speed=\"props.speed\"\n                :playState=\"props.playState\"\n                :padding=\"props.padding\"\n                @getMore=\"getMore\"\n                @close=\"close\"\n                @click=\"click\"\n            ></u-row-notice>\n        </block>\n        <block v-if=\"props.mode === 'vertical' || (props.mode === 'horizontal' && !props.isCircular)\">\n            <u-column-notice\n                :type=\"props.type\"\n                :color=\"props.color\"\n                :bgColor=\"props.bgColor\"\n                :list=\"props.list\"\n                :volumeIcon=\"props.volumeIcon\"\n                :moreIcon=\"props.moreIcon\"\n                :closeIcon=\"props.closeIcon\"\n                :mode=\"props.mode\"\n                :volumeSize=\"props.volumeSize\"\n                :disable-touch=\"props.disableTouch\"\n                :fontSize=\"props.fontSize\"\n                :duration=\"props.duration\"\n                :playState=\"props.playState\"\n                :padding=\"props.padding\"\n                @getMore=\"getMore\"\n                @close=\"close\"\n                @click=\"click\"\n                @end=\"end\"\n            ></u-column-notice>\n        </block>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-notice-bar',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { NoticeBarProps } from './types';\n\n/**\n * noticeBar 滚动通知\n * @description 该组件用于滚动通告场景，有多种模式可供选择\n * @tutorial https://uviewpro.cn/zh/components/noticeBar.html\n * @property {Array} list 滚动内容，数组形式，见上方说明\n * @property {String} type 显示的主题（默认warning）\n * @property {Boolean} volumeIcon 是否显示小喇叭图标（默认true）\n * @property {Boolean} moreIcon 是否显示右边的向右箭头（默认false）\n * @property {Boolean} closeIcon 是否显示关闭图标（默认false）\n * @property {Boolean} autoplay 是否自动播放（默认true）\n * @property {String} color 文字颜色\n * @property {String|Number} bgColor 背景颜色\n * @property {String} mode 滚动模式（默认horizontal）\n * @property {Boolean} show 是否显示（默认true）\n * @property {String|Number} fontSize 字体大小，单位rpx（默认28）\n * @property {String|Number} volumeSize 左边喇叭的大小（默认34）\n * @property {String|Number} duration 滚动周期时长，只对步进模式有效，横向衔接模式无效，单位ms（默认2000）\n * @property {String|Number} speed 水平滚动时的滚动速度，即每秒移动多少距离，只对水平衔接方式有效，单位rpx（默认160）\n * @property {Boolean} isCircular mode为horizontal时，指明是否水平衔接滚动（默认true）\n * @property {String} playState 播放状态，play - 播放，paused - 暂停（默认play）\n * @property {String|Number} borderRadius 通知栏圆角（默认为0）\n * @property {String|Number} padding 内边距，字符串，与普通的内边距css写法一致（默认\"18rpx 24rpx\"）\n * @property {Boolean} noListHidden 列表为空时，是否显示组件（默认false）\n * @property {Boolean} disableTouch 是否禁止通过手动滑动切换通知，只有mode = vertical，或者mode = horizontal且isCircular = false时有效（默认true）\n * @event {Function} click 点击通告文字触发，只有mode = vertical，或者mode = horizontal且isCircular = false时有效\n * @event {Function} close 点击右侧关闭图标触发\n * @event {Function} getMore 点击右侧向右图标触发\n * @event {Function} end 列表的消息每次被播放一个周期时触发，只有mode = vertical，或者mode = horizontal且isCircular = false时有效\n * @example <u-notice-bar :more-icon=\"true\" :list=\"list\"></u-notice-bar>\n */\n\nconst props = defineProps(NoticeBarProps);\n\nconst emit = defineEmits<{\n    (e: 'click', index: number | undefined): void;\n    (e: 'close'): void;\n    (e: 'getMore'): void;\n    (e: 'end'): void;\n}>();\n\n/**\n * 是否显示组件\n * 如果设置show为false，或者设置了noListHidden为true，且list长度又为零的话，隐藏组件\n */\nconst isShow = computed(() => {\n    if (!props.show || (props.noListHidden && props.list.length === 0)) return false;\n    return true;\n});\n\n/**\n * 点击通告栏\n */\nfunction click(index?: number) {\n    emit('click', index);\n}\n\n/**\n * 点击关闭按钮\n */\nfunction close() {\n    emit('close');\n}\n\n/**\n * 点击更多箭头按钮\n */\nfunction getMore() {\n    emit('getMore');\n}\n\n/**\n * 滚动一个周期结束，只对垂直，或者水平步进形式有效\n */\nfunction end() {\n    emit('end');\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n.u-notice-bar-wrap {\n    overflow: hidden;\n}\n.u-notice-bar {\n    padding: 18rpx 24rpx;\n    overflow: hidden;\n}\n.u-direction-row {\n    @include vue-flex;\n    align-items: center;\n    justify-content: space-between;\n}\n.u-left-icon {\n    @include vue-flex;\n    align-items: center;\n}\n.u-notice-box {\n    flex: 1;\n    @include vue-flex;\n    overflow: hidden;\n    margin-left: 12rpx;\n}\n.u-right-icon {\n    margin-left: 12rpx;\n    @include vue-flex;\n    align-items: center;\n}\n.u-notice-content {\n    line-height: 1;\n    white-space: nowrap;\n    font-size: 26rpx;\n    animation: u-loop-animation 10s linear infinite both;\n    text-align: right;\n    // 这一句很重要，为了能让滚动左右连接起来\n    padding-left: 100%;\n}\n@keyframes u-loop-animation {\n    0% {\n        transform: translate3d(0, 0, 0);\n    }\n    100% {\n        transform: translate3d(-100%, 0, 0);\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-number-box/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\n/**\n * NumberBoxProps 步进器 props 类型定义\n * @description 商城购物选择物品数量，支持正整数、禁用、长按等\n */\nexport const NumberBoxProps = {\n    /** 输入框初始值（默认1） */\n    modelValue: { type: Number, default: 1 },\n    /** 输入框和按钮的背景颜色（默认var(--u-bg-gray-light)） */\n    bgColor: { type: String, default: 'var(--u-bg-gray-light)' },\n    /** 用户可输入的最小值（默认0） */\n    min: { type: Number, default: 0 },\n    /** 用户可输入的最大值（默认99999） */\n    max: { type: Number, default: 99999 },\n    /** 步长，每次加或减的值（默认1） */\n    step: { type: Number, default: 1 },\n    /** 是否禁用操作，禁用后无法加减或手动修改输入框的值（默认false） */\n    disabled: { type: Boolean, default: false },\n    /** 输入框文字和按钮字体大小，单位rpx（默认26） */\n    size: { type: [Number, String] as PropType<number | string>, default: 26 },\n    /** 输入框文字和加减按钮图标的颜色（默认var(--u-main-color)） */\n    color: { type: String, default: 'var(--u-main-color)' },\n    /** 输入框宽度，单位rpx（默认80） */\n    inputWidth: { type: [Number, String] as PropType<number | string>, default: 80 },\n    /** 输入框和按钮的高度，单位rpx（默认50） */\n    inputHeight: { type: [Number, String] as PropType<number | string>, default: 50 },\n    /** 事件回调时用以区分当前发生变化的是哪个输入框 */\n    index: { type: [Number, String] as PropType<number | string>, default: '' },\n    /** 是否禁止输入框手动输入值（默认false） */\n    disabledInput: { type: Boolean, default: false },\n    /** 指定光标于键盘的距离，避免键盘遮挡输入框，单位rpx（默认100） */\n    cursorSpacing: { type: [Number, String] as PropType<number | string>, default: 100 },\n    /** 是否开启长按连续递增或递减(默认true) */\n    longPress: { type: Boolean, default: true },\n    /** 开启长按触发后，每触发一次需要多久，单位ms(默认250) */\n    pressTime: { type: [Number, String] as PropType<number | string>, default: 250 },\n    /** 是否只能输入大于或等于0的整数(正整数)（默认true） */\n    positiveInteger: { type: Boolean, default: true }\n};\n\nexport type NumberBoxProps = ExtractPropTypes<typeof NumberBoxProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-number-box/u-number-box.vue",
    "content": "<template>\n    <view class=\"u-numberbox\">\n        <view\n            class=\"u-icon-minus\"\n            @touchstart.stop.prevent=\"btnTouchStart('minus')\"\n            @touchend.stop.prevent=\"clearTimer\"\n            :class=\"{ 'u-icon-disabled': disabled || inputVal <= min }\"\n            :style=\"{\n                background: bgColor,\n                height: inputHeight + 'rpx',\n                color: color\n            }\"\n        >\n            <u-icon name=\"minus\" :size=\"size\"></u-icon>\n        </view>\n        <input\n            :disabled=\"disabledInput || disabled\"\n            :cursor-spacing=\"getCursorSpacing\"\n            :class=\"{ 'u-input-disabled': disabled }\"\n            v-model=\"inputVal\"\n            class=\"u-number-input\"\n            @blur=\"onBlur\"\n            @focus=\"onFocus\"\n            type=\"digit\"\n            :style=\"{\n                color: color,\n                fontSize: size + 'rpx',\n                background: bgColor,\n                height: inputHeight + 'rpx',\n                width: inputWidth + 'rpx'\n            }\"\n        />\n        <view\n            class=\"u-icon-plus\"\n            @touchstart.stop.prevent=\"btnTouchStart('plus')\"\n            @touchend.stop.prevent=\"clearTimer\"\n            :class=\"{ 'u-icon-disabled': disabled || inputVal >= max }\"\n            :style=\"{\n                background: bgColor,\n                height: inputHeight + 'rpx',\n                color: color\n            }\"\n        >\n            <u-icon name=\"plus\" :size=\"size\"></u-icon>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-number-box',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, watch, computed, nextTick } from 'vue';\nimport { NumberBoxProps } from './types';\n\n/**\n * numberBox 步进器\n * @description 该组件一般用于商城购物选择物品数量的场景。注意：该输入框只能输入大于或等于0的整数，不支持小数输入\n * @tutorial https://uviewpro.cn/zh/components/numberBox.html\n * @property {Number} modelValue 输入框初始值（默认1）\n * @property {String} bg-color 输入框和按钮的背景颜色（默认var(--u-bg-gray-light)）\n * @property {Number} min 用户可输入的最小值（默认0）\n * @property {Number} max 用户可输入的最大值（默认99999）\n * @property {Number} step 步长，每次加或减的值（默认1）\n * @property {Boolean} disabled 是否禁用操作，禁用后无法加减或手动修改输入框的值（默认false）\n * @property {Boolean} disabled-input 是否禁止输入框手动输入值（默认false）\n * @property {Boolean} positive-integer 是否只能输入正整数（默认true）\n * @property {String | Number} size 输入框文字和按钮字体大小，单位rpx（默认26）\n * @property {String} color 输入框文字和加减按钮图标的颜色（默认var(--u-main-color)）\n * @property {String | Number} input-width 输入框宽度，单位rpx（默认80）\n * @property {String | Number} input-height 输入框和按钮的高度，单位rpx（默认50）\n * @property {String | Number} index 事件回调时用以区分当前发生变化的是哪个输入框\n * @property {Boolean} long-press 是否开启长按连续递增或递减(默认true)\n * @property {String | Number} press-time 开启长按触发后，每触发一次需要多久，单位ms(默认250)\n * @property {String | Number} cursor-spacing 指定光标于键盘的距离，避免键盘遮挡输入框，单位rpx（默认200）\n * @event {Function} change 输入框内容发生变化时触发，对象形式\n * @event {Function} blur 输入框失去焦点时触发，对象形式\n * @event {Function} minus 点击减少按钮时触发(按钮可点击情况下)，对象形式\n * @event {Function} plus 点击增加按钮时触发(按钮可点击情况下)，对象形式\n * @example <u-number-box :min=\"1\" :max=\"100\"></u-number-box>\n */\nconst props = defineProps(NumberBoxProps);\nconst emit = defineEmits(['update:modelValue', 'change', 'blur', 'focus', 'minus', 'plus']);\n\n// 响应式变量\nconst inputVal = ref<number>(props.modelValue); // 输入框中的值，不能直接使用props中的value，因为应该改变props的状态\nconst timer = ref<any>(null); // 用作长按的定时器\nconst changeFromInner = ref(false); // 值发生变化，是来自内部还是外部\nconst innerChangeTimer = ref<any>(null); // 内部定时器\n\n// 计算属性\nconst getCursorSpacing = computed(() => {\n    const spacing = typeof props.cursorSpacing === 'string' ? Number(props.cursorSpacing) : props.cursorSpacing;\n    return Number(uni.upx2px(spacing));\n});\n\n// 监听外部 value 变化\nwatch(\n    () => props.modelValue,\n    (v1, v2) => {\n        // 只有value的改变是来自外部的时候，才去同步inputVal的值，否则会造成循环错误\n        if (!changeFromInner.value) {\n            inputVal.value = v1;\n            // 延时保证 changeFromInner 在运行周期最后处重置\n            // 因为inputVal变化后，会触发this.handleChange()，在其中changeFromInner会再次被设置为true，\n            // 造成外面修改值，也导致被认为是内部修改的混乱，这里进行this.$nextTick延时，保证在运行周期的最后处\n            // 将changeFromInner设置为false\n            nextTick(() => {\n                changeFromInner.value = false;\n            });\n        }\n    }\n);\n\n// 监听 inputVal 变化\nwatch(inputVal, (v1, v2) => {\n    // 为了让用户能够删除所有输入值，重新输入内容，删除所有值后，内容为空字符串\n    if (typeof v1 !== 'number' || isNaN(v1)) return;\n    let value = 0;\n    // 首先判断是否数值，并且在min和max之间，如果不是，使用原来值\n    let tmp = typeof v1 === 'number' && !isNaN(v1);\n    if (tmp && v1 >= props.min && v1 <= props.max) value = Number(v1);\n    else value = Number(v2);\n    // 判断是否只能输入大于等于0的整数\n    if (props.positiveInteger) {\n        // 小于0，或者带有小数点，\n        if (value < 0 || String(v1).indexOf('.') !== -1) {\n            value = Number(v2);\n            // 双向绑定input的值，必须要使用$nextTick修改显示的值\n            nextTick(() => {\n                inputVal.value = value;\n            });\n        }\n    }\n    // 发出change事件\n    handleChange(value, 'change');\n});\n\nfunction btnTouchStart(callback: 'minus' | 'plus') {\n    // 先执行一遍方法，否则会造成松开手时，就执行了clearTimer，导致无法实现功能\n    if (callback === 'minus') minus();\n    else plus();\n    // 如果没开启长按功能，直接返回\n    if (!props.longPress) return;\n    // 再次清空定时器，防止重复注册定时器\n    clearInterval(timer.value);\n    timer.value = setInterval(() => {\n        // 执行加或减函数\n        if (callback === 'minus') minus();\n        else plus();\n    }, Number(props.pressTime));\n}\n\nfunction clearTimer() {\n    // 清除长按定时器\n    nextTick(() => {\n        clearInterval(timer.value);\n        timer.value = null;\n    });\n}\n\nfunction minus() {\n    // 执行减法操作\n    computeVal('minus');\n}\nfunction plus() {\n    // 执行加法操作\n    computeVal('plus');\n}\n\n// 为了保证小数相加减出现精度溢出的问题\nfunction calcPlus(num1: number, num2: number) {\n    let baseNum, baseNum1, baseNum2;\n    try {\n        baseNum1 = num1.toString().split('.')[1].length;\n    } catch (e) {\n        baseNum1 = 0;\n    }\n    try {\n        baseNum2 = num2.toString().split('.')[1].length;\n    } catch (e) {\n        baseNum2 = 0;\n    }\n    baseNum = Math.pow(10, Math.max(baseNum1, baseNum2));\n    let precision = baseNum1 >= baseNum2 ? baseNum1 : baseNum2; //精度\n    return Number(((num1 * baseNum + num2 * baseNum) / baseNum).toFixed(precision));\n}\n\n// 为了保证小数相加减出现精度溢出的问题\nfunction calcMinus(num1: number, num2: number) {\n    let baseNum, baseNum1, baseNum2;\n    try {\n        baseNum1 = num1.toString().split('.')[1].length;\n    } catch (e) {\n        baseNum1 = 0;\n    }\n    try {\n        baseNum2 = num2.toString().split('.')[1].length;\n    } catch (e) {\n        baseNum2 = 0;\n    }\n    baseNum = Math.pow(10, Math.max(baseNum1, baseNum2));\n    let precision = baseNum1 >= baseNum2 ? baseNum1 : baseNum2;\n    return Number(((num1 * baseNum - num2 * baseNum) / baseNum).toFixed(precision));\n}\n\n// 处理加减按钮点击逻辑\nfunction computeVal(type: 'minus' | 'plus') {\n    uni.hideKeyboard();\n    if (props.disabled) return;\n    let value = 0;\n    // 减\n    if (type === 'minus') {\n        value = calcMinus(Number(inputVal.value), props.step);\n    } else if (type === 'plus') {\n        value = calcPlus(Number(inputVal.value), props.step);\n    }\n    // 判断是否小于最小值和大于最大值\n    if (value < props.min || value > props.max) return;\n    inputVal.value = value;\n    handleChange(value, type);\n}\n\n// 处理用户手动输入的情况\nfunction onBlur(event: any) {\n    let val = 0;\n    let value = event.detail.value;\n    // 如果为非0-9数字组成，或者其第一位数值为0，直接让其等于min值\n    // 这里不直接判断是否正整数，是因为用户传递的props min值可能为0\n    if (!/(^\\d+$)/.test(value) || value[0] == 0) val = props.min;\n    else val = +value;\n    if (val > props.max) val = props.max;\n    else if (val < props.min) val = props.min;\n    nextTick(() => {\n        inputVal.value = val;\n    });\n    handleChange(val, 'blur');\n}\n\n// 输入框获得焦点事件\nfunction onFocus() {\n    emit('focus');\n}\n\n// 处理值变化的统一逻辑\nfunction handleChange(value: number, type: 'update:modelValue' | 'change' | 'blur' | 'focus' | 'minus' | 'plus') {\n    if (props.disabled) return;\n    // 清除定时器，避免造成混乱\n    if (innerChangeTimer.value) {\n        clearTimeout(innerChangeTimer.value);\n        innerChangeTimer.value = null;\n    }\n    // 发出input事件，修改通过v-model绑定的值，达到双向绑定的效果\n    changeFromInner.value = true;\n    // 一定时间内，清除changeFromInner标记，否则内部值改变后外部通过程序修改value值，将会无效\n    innerChangeTimer.value = setTimeout(() => {\n        changeFromInner.value = false;\n    }, 150);\n    emit('update:modelValue', Number(value));\n    emit(type, {\n        // 转为Number类型\n        value: Number(value),\n        index: props.index\n    });\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-numberbox {\n    display: inline-flex;\n    align-items: center;\n}\n\n.u-number-input {\n    position: relative;\n    text-align: center;\n    padding: 0;\n    margin: 0 6rpx;\n    @include vue-flex;\n    align-items: center;\n    justify-content: center;\n}\n\n.u-icon-plus,\n.u-icon-minus {\n    width: 60rpx;\n    @include vue-flex;\n    justify-content: center;\n    align-items: center;\n}\n\n.u-icon-plus {\n    border-radius: 0 8rpx 8rpx 0;\n}\n\n.u-icon-minus {\n    border-radius: 8rpx 0 0 8rpx;\n}\n\n.u-icon-disabled {\n    color: var(--u-type-info-disabled) !important;\n    background: var(--u-bg-gray-light) !important;\n}\n\n.u-input-disabled {\n    color: var(--u-type-info-disabled) !important;\n    background-color: var(--u-bg-gray-light) !important;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-number-keyboard/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { NumberKeyboardMode } from '../../types/global';\n\n/**\n * NumberKeyboardProps 数字/身份证键盘 props 类型定义\n * @description 支持数字、身份证、带小数点等多种模式，支持乱序，支持长按退格。\n */\nexport const NumberKeyboardProps = {\n    /** 键盘的类型，number-数字键盘，card-身份证键盘 */\n    mode: {\n        type: String as PropType<NumberKeyboardMode>,\n        default: 'number'\n    },\n    /** 是否显示键盘的\".\"符号 */\n    dotEnabled: {\n        type: Boolean,\n        default: true\n    },\n    /** 是否打乱键盘按键的顺序 */\n    random: {\n        type: Boolean,\n        default: false\n    }\n};\n\nexport type NumberKeyboardProps = ExtractPropTypes<typeof NumberKeyboardProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-number-keyboard/u-number-keyboard.vue",
    "content": "<template>\n    <view class=\"u-keyboard\" @touchmove.stop.prevent=\"() => {}\">\n        <view class=\"u-keyboard-grids\">\n            <view\n                class=\"u-keyboard-grids-item\"\n                :class=\"[\n                    btnBgGray(index) ? 'u-bg-gray' : '',\n                    index <= 2 ? 'u-border-top' : '',\n                    index < 9 ? 'u-border-bottom' : '',\n                    (index + 1) % 3 != 0 ? 'u-border-right' : ''\n                ]\"\n                :style=\"[itemStyle(index)]\"\n                v-for=\"(item, index) in numList\"\n                :key=\"index\"\n                :hover-class=\"hoverClass(index)\"\n                :hover-stay-time=\"100\"\n                @tap=\"keyboardClick(item)\"\n            >\n                <view class=\"u-keyboard-grids-btn\">{{ item }}</view>\n            </view>\n            <view\n                class=\"u-keyboard-grids-item u-bg-gray\"\n                hover-class=\"u-hover-class\"\n                :hover-stay-time=\"100\"\n                @touchstart.stop=\"backspaceClick\"\n                @touchend=\"clearTimer\"\n            >\n                <view class=\"u-keyboard-back u-keyboard-grids-btn\">\n                    <u-icon name=\"backspace\" :size=\"38\" :bold=\"true\"></u-icon>\n                </view>\n            </view>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-number-keyboard',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { $u } from '../..';\nimport { NumberKeyboardProps } from './types';\n\n/**\n * u-number-keyboard 数字/身份证键盘\n * @description 支持数字、身份证、带小数点等多种模式，支持乱序，支持长按退格。\n * @property {String} mode 键盘的类型，number-数字键盘，card-身份证键盘\n * @property {Boolean} dotEnabled 是否显示\".\"按键，只在mode=number时有效（默认true）\n * @property {Boolean} random 是否打乱键盘按键的顺序（默认false）\n * @event {Function} change 按键被点击\n * @event {Function} backspace 退格键被点击\n */\nconst props = defineProps(NumberKeyboardProps);\n\nconst emit = defineEmits(['change', 'backspace']);\n\nconst backspace = 'backspace'; // 退格键内容\nconst dot = '.'; // 点\nconst cardX = 'X'; // 身份证的X符号\nlet timer: ReturnType<typeof setInterval> | null = null;\n\n/**\n * 键盘需要显示的内容\n */\nconst numList = computed(() => {\n    if (!props.dotEnabled && props.mode == 'number') {\n        if (!props.random) {\n            return [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];\n        } else {\n            return $u.randomArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);\n        }\n    } else if (props.dotEnabled && props.mode == 'number') {\n        if (!props.random) {\n            return [1, 2, 3, 4, 5, 6, 7, 8, 9, dot, 0];\n        } else {\n            return $u.randomArray([1, 2, 3, 4, 5, 6, 7, 8, 9, dot, 0]);\n        }\n    } else if (props.mode == 'card') {\n        if (!props.random) {\n            return [1, 2, 3, 4, 5, 6, 7, 8, 9, cardX, 0];\n        } else {\n            return $u.randomArray([1, 2, 3, 4, 5, 6, 7, 8, 9, cardX, 0]);\n        }\n    }\n    // 默认返回数字键盘\n    return [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];\n});\n\n/**\n * 按键的样式，在非乱序&&数字键盘&&不显示点按钮时，index为9时，按键占位两个空间\n */\nconst itemStyle = (index: number) => {\n    let style: Record<string, string> = {};\n    if (props.mode == 'number' && !props.dotEnabled && index == 9) style.flex = '0 0 66.6666666666%';\n    return style;\n};\n\n/**\n * 是否让按键显示灰色，只在非乱序&&数字键盘&&且允许点按键的时候\n */\nconst btnBgGray = (index: number) => {\n    if (!props.random && index == 9 && (props.mode != 'number' || (props.mode == 'number' && props.dotEnabled))) {\n        return true;\n    } else return false;\n};\n\n/**\n * 按键 hover class\n */\nconst hoverClass = (index: number) => {\n    if (!props.random && index == 9 && ((props.mode == 'number' && props.dotEnabled) || props.mode == 'card')) {\n        return 'u-hover-class';\n    } else return 'u-keyboard-hover';\n};\n\n/**\n * 点击退格键\n */\nfunction backspaceClick() {\n    emit('backspace');\n    if (timer) clearInterval(timer); //再次清空定时器，防止重复注册定时器\n    timer = setInterval(() => {\n        emit('backspace');\n    }, 250);\n}\n\nfunction clearTimer() {\n    if (timer) clearInterval(timer);\n    timer = null;\n}\n\n/**\n * 获取键盘显示的内容\n */\nfunction keyboardClick(val: string | number) {\n    // 允许键盘显示点模式和触发非点按键时，将内容转为数字类型\n    if (props.dotEnabled && val != dot && val != cardX) val = Number(val);\n    emit('change', val);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-keyboard {\n    position: relative;\n    z-index: 1003;\n}\n\n.u-keyboard-grids {\n    @include vue-flex;\n    flex-wrap: wrap;\n}\n\n.u-keyboard-grids-item {\n    flex: 0 0 33.3333333333%;\n    text-align: center;\n    font-size: 50rpx;\n    color: var(--u-main-color);\n    @include vue-flex;\n    align-items: center;\n    justify-content: center;\n    height: 110rpx;\n    font-weight: 500;\n}\n\n.u-bg-gray {\n    background-color: $u-border-color;\n}\n\n.u-keyboard-back {\n    font-size: 36rpx;\n}\n\n.u-keyboard-hover {\n    background-color: var(--u-divider-color);\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-pagination/types.ts",
    "content": "import type { PaginationChangePayload } from '../../types/global';\nimport { useLocale } from '../../';\nimport type { PropType } from 'vue';\n\nconst { t } = useLocale();\n\n/**\n * pagination 分页类型定义\n * @description 供 u-pagination 组件 props 使用\n */\n\nexport const PaginationProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 左侧按钮文字 */\n    prevText: { type: String, default: () => t('uPagination.prevText') },\n    /** 右侧按钮文字 */\n    nextText: { type: String, default: () => t('uPagination.nextText') },\n    /** 总条目数 */\n    total: Number,\n    /** 每页数据量 */\n    pageSize: { type: Number, default: 10 },\n    /** 是否以 icon 形式展示按钮 */\n    showIcon: { type: Boolean, default: false },\n    /** 左侧按钮图标，仅支持内置图标 */\n    prevIcon: { type: String, default: 'arrow-left' },\n    /** 右侧按钮图标，仅支持内置图标 */\n    nextIcon: { type: String, default: 'arrow-right' }\n};\n\nexport type PaginationEmits = {\n    (e: 'change', payload: PaginationChangePayload): void;\n};\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-pagination/u-pagination.vue",
    "content": "<template>\n    <view class=\"u-pagination\" :style=\"$u.toStyle(customStyle)\" :class=\"customClass\">\n        <u-button\n            custom-class=\"custom-class\"\n            shape=\"circle\"\n            type=\"info\"\n            size=\"medium\"\n            :throttle-time=\"0\"\n            :disabled=\"current <= 1\"\n            @click=\"handleChange('prev')\"\n        >\n            <u-icon v-if=\"showIcon\" :name=\"prevIcon\"></u-icon>\n            <text v-else>{{ prevText }}</text>\n        </u-button>\n        <view class=\"u-pagination-text\">\n            <slot>\n                <u-text type=\"primary\" :text=\"current\"></u-text>\n                <text> / </text>\n                <text>{{ totalPages }}</text>\n            </slot>\n        </view>\n        <u-button\n            custom-class=\"custom-class\"\n            shape=\"circle\"\n            type=\"info\"\n            size=\"medium\"\n            :throttle-time=\"0\"\n            :disabled=\"current >= totalPages\"\n            @click=\"handleChange('next')\"\n        >\n            <u-icon v-if=\"showIcon\" :name=\"nextIcon\"></u-icon>\n            <text v-else>{{ nextText }}</text>\n        </u-button>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-pagination',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { type PaginationEmits, PaginationProps } from './types';\nimport type { PaginationDirection } from '../../types/global';\nimport { $u } from '../../';\n\nconst props = defineProps(PaginationProps);\nconst emit = defineEmits<PaginationEmits>();\n\nconst current = defineModel({ type: Number, default: 1 });\n\n// 自动计算总页数\nconst totalPages = computed(() => {\n    const size = props.pageSize || 10;\n    return Math.ceil((props.total || 0) / size);\n});\n\n// 切换分页\nfunction handleChange(type: PaginationDirection) {\n    // 先计算新值，确保获取到的是更新后的值\n    const newCurrent = type === 'prev' ? current.value - 1 : current.value + 1;\n\n    // 更新 current 值\n    current.value = newCurrent;\n\n    // current为当前页，type值为：next/prev，表示点击的是上一页还是下一页\n    // 使用计算后的新值，而不是 current.value，避免异步更新导致的值不同步问题\n    emit('change', { type, current: newCurrent });\n}\n</script>\n\n<style scoped lang=\"scss\">\n.u-pagination {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n\n    :deep(.custom-class) {\n        margin: 0;\n        padding: 0 30rpx;\n        min-width: 120rpx;\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-picker/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { PickerMode, PickerParams } from '../../types/global';\nimport { getColor, useLocale } from '../../';\nimport zIndex from '../../libs/config/zIndex';\n\nconst { t } = useLocale();\n\nconst defaultParams: PickerParams = {\n    year: true,\n    month: true,\n    day: true,\n    hour: false,\n    minute: false,\n    second: false,\n    province: true,\n    city: true,\n    area: true,\n    timestamp: true\n};\n/**\n * PickerProps 选择器 props 类型定义\n * @description 支持时间、地区、单列、多列等多种模式\n */\nexport const PickerProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** picker中需要显示的参数 */\n    params: {\n        type: Object as PropType<PickerParams>,\n        default: () => defaultParams\n    },\n    /** 当mode=selector或者mode=multiSelector时，提供的数组 */\n    range: {\n        type: Array as PropType<any[]>,\n        default: () => []\n    },\n    /** 当mode=selector或者mode=multiSelector时，提供的默认选中的下标 */\n    defaultSelector: {\n        type: Array as PropType<any[]>,\n        default: () => [0]\n    },\n    /** 是否保留用户上次确认的选择（true：优先使用已保存选择；false：优先使用外部传入的 defaultSelector/defaultTime/defaultRegion） */\n    preserveSelection: {\n        type: Boolean,\n        default: true\n    },\n    /** 当 range 是一个 Array<Object> 时，通过 range-key 来指定 Object 中 key 的值作为选择器显示内容 */\n    rangeKey: {\n        type: String,\n        default: ''\n    },\n    /** 模式选择，region-地区类型，time-时间类型，selector-单列模式，multiSelector-多列模式 */\n    mode: {\n        type: String as PropType<PickerMode>,\n        default: 'time'\n    },\n    /** 年份开始时间 */\n    startYear: {\n        type: [String, Number] as PropType<number | string>,\n        default: 1950\n    },\n    /** 年份结束时间 */\n    endYear: {\n        type: [String, Number] as PropType<number | string>,\n        default: 2050\n    },\n    /** \"取消\"按钮的颜色 */\n    cancelColor: {\n        type: String,\n        default: () => getColor('contentColor')\n    },\n    /** \"确定\"按钮的颜色 */\n    confirmColor: {\n        type: String,\n        default: () => getColor('primary')\n    },\n    /** 默认显示的时间，2025-07-02 || 2025-07-02 13:01:00 || 2025/07/02 */\n    defaultTime: {\n        type: String,\n        default: ''\n    },\n    /** 默认显示的地区，可传类似[\"河北省\", \"秦皇岛市\", \"北戴河区\"] */\n    defaultRegion: {\n        type: Array as PropType<any[]>,\n        default: () => []\n    },\n    /** 时间模式时，是否显示后面的年月日中文提示 */\n    showTimeTag: {\n        type: Boolean,\n        default: true\n    },\n    /** 默认显示地区的编码，defaultRegion和areaCode同时存在，areaCode优先，可传类似[\"13\", \"1303\", \"130304\"] */\n    areaCode: {\n        type: Array as PropType<any[]>,\n        default: () => []\n    },\n    /** 是否开启底部安全区适配 */\n    safeAreaInsetBottom: {\n        type: Boolean,\n        default: false\n    },\n    /** 是否允许通过点击遮罩关闭Picker */\n    maskCloseAble: {\n        type: Boolean,\n        default: true\n    },\n    /** 通过双向绑定控制组件的弹出与收起 */\n    modelValue: {\n        type: [Boolean, String, Number, Array, Object] as PropType<any>,\n        default: false\n    },\n    /** 弹出的z-index值 */\n    zIndex: {\n        type: [String, Number] as PropType<number | string>,\n        default: zIndex.popup\n    },\n    /** 顶部标题 */\n    title: {\n        type: String,\n        default: ''\n    },\n    /** 取消按钮的文字 */\n    cancelText: {\n        type: String,\n        default: () => t('uPicker.cancelText')\n    },\n    /** 确认按钮的文字 */\n    confirmText: {\n        type: String,\n        default: () => t('uPicker.confirmText')\n    }\n};\n\nexport type PickerProps = ExtractPropTypes<typeof PickerProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-picker/u-picker.vue",
    "content": "<template>\n    <u-popup\n        :maskCloseAble=\"maskCloseAble\"\n        mode=\"bottom\"\n        :popup=\"false\"\n        v-model=\"popupValue\"\n        length=\"auto\"\n        :safeAreaInsetBottom=\"safeAreaInsetBottom\"\n        @close=\"close\"\n        :z-index=\"uZIndex\"\n        :custom-class=\"customClass\"\n    >\n        <view class=\"u-datetime-picker\" :style=\"$u.toStyle(customStyle)\">\n            <view class=\"u-picker-header\" @touchmove.stop.prevent=\"\">\n                <view\n                    class=\"u-btn-picker u-btn-picker--tips\"\n                    :style=\"{ color: cancelColor }\"\n                    hover-class=\"u-opacity\"\n                    :hover-stay-time=\"150\"\n                    @tap=\"getResult('cancel')\"\n                >\n                    {{ cancelText }}\n                </view>\n                <view class=\"u-picker__title u-line-1\">{{ title }}</view>\n                <view\n                    class=\"u-btn-picker u-btn-picker--primary\"\n                    :style=\"{ color: moving ? cancelColor : confirmColor }\"\n                    hover-class=\"u-opacity\"\n                    :hover-stay-time=\"150\"\n                    @touchmove.stop=\"\"\n                    @tap.stop=\"getResult('confirm')\"\n                >\n                    {{ confirmText }}\n                </view>\n            </view>\n            <view class=\"u-picker-body\">\n                <template v-if=\"readyToRender\">\n                    <picker-view\n                        v-if=\"mode == 'region'\"\n                        :value=\"valueArr\"\n                        class=\"u-picker-view\"\n                        mask-class=\"u-picker-view-mask\"\n                        indicator-class=\"u-picker-view-indicator\"\n                        @pickstart=\"pickstart\"\n                        @pickend=\"pickend\"\n                        @change=\"change\"\n                    >\n                        <picker-view-column v-if=\"params.province\">\n                            <view class=\"u-column-item\" v-for=\"(item, index) in provinces\" :key=\"index\">\n                                <view class=\"u-line-1\">{{ item.label }}</view>\n                            </view>\n                        </picker-view-column>\n                        <picker-view-column v-if=\"params.city\">\n                            <view class=\"u-column-item\" v-for=\"(item, index) in citysRef\" :key=\"index\">\n                                <view class=\"u-line-1\">{{ item.label }}</view>\n                            </view>\n                        </picker-view-column>\n                        <picker-view-column v-if=\"params.area\">\n                            <view class=\"u-column-item\" v-for=\"(item, index) in areasRef\" :key=\"index\">\n                                <view class=\"u-line-1\">{{ item.label }}</view>\n                            </view>\n                        </picker-view-column>\n                    </picker-view>\n                    <picker-view\n                        v-else-if=\"mode == 'time'\"\n                        :value=\"valueArr\"\n                        class=\"u-picker-view\"\n                        mask-class=\"u-picker-view-mask\"\n                        indicator-class=\"u-picker-view-indicator\"\n                        @pickstart=\"pickstart\"\n                        @pickend=\"pickend\"\n                        @change=\"change\"\n                    >\n                        <picker-view-column v-if=\"params.year\">\n                            <view class=\"u-column-item\" v-for=\"(item, index) in years\" :key=\"index\">\n                                {{ item }}\n                                <text class=\"u-text\" v-if=\"showTimeTag\">年</text>\n                            </view>\n                        </picker-view-column>\n                        <picker-view-column v-if=\"params.month\">\n                            <view class=\"u-column-item\" v-for=\"(item, index) in months\" :key=\"index\">\n                                {{ formatNumber(item) }}\n                                <text class=\"u-text\" v-if=\"showTimeTag\">月</text>\n                            </view>\n                        </picker-view-column>\n                        <picker-view-column v-if=\"params.day\">\n                            <view class=\"u-column-item\" v-for=\"(item, index) in days\" :key=\"index\">\n                                {{ formatNumber(item) }}\n                                <text class=\"u-text\" v-if=\"showTimeTag\">日</text>\n                            </view>\n                        </picker-view-column>\n                        <picker-view-column v-if=\"params.hour\">\n                            <view class=\"u-column-item\" v-for=\"(item, index) in hours\" :key=\"index\">\n                                {{ formatNumber(item) }}\n                                <text class=\"u-text\" v-if=\"showTimeTag\">时</text>\n                            </view>\n                        </picker-view-column>\n                        <picker-view-column v-if=\"params.minute\">\n                            <view class=\"u-column-item\" v-for=\"(item, index) in minutes\" :key=\"index\">\n                                {{ formatNumber(item) }}\n                                <text class=\"u-text\" v-if=\"showTimeTag\">分</text>\n                            </view>\n                        </picker-view-column>\n                        <picker-view-column v-if=\"params.second\">\n                            <view class=\"u-column-item\" v-for=\"(item, index) in seconds\" :key=\"index\">\n                                {{ formatNumber(item) }}\n                                <text class=\"u-text\" v-if=\"showTimeTag\">秒</text>\n                            </view>\n                        </picker-view-column>\n                    </picker-view>\n                    <picker-view\n                        v-else-if=\"mode == 'selector'\"\n                        :value=\"valueArr\"\n                        class=\"u-picker-view\"\n                        mask-class=\"u-picker-view-mask\"\n                        indicator-class=\"u-picker-view-indicator\"\n                        @pickstart=\"pickstart\"\n                        @pickend=\"pickend\"\n                        @change=\"change\"\n                    >\n                        <picker-view-column>\n                            <view class=\"u-column-item\" v-for=\"(item, index) in range\" :key=\"index\">\n                                <view class=\"u-line-1\">{{ getItemValue(item, 'selector') }}</view>\n                            </view>\n                        </picker-view-column>\n                    </picker-view>\n                    <picker-view\n                        v-else-if=\"mode == 'multiSelector'\"\n                        :value=\"valueArr\"\n                        class=\"u-picker-view\"\n                        mask-class=\"u-picker-view-mask\"\n                        indicator-class=\"u-picker-view-indicator\"\n                        @pickstart=\"pickstart\"\n                        @pickend=\"pickend\"\n                        @change=\"change\"\n                    >\n                        <picker-view-column v-for=\"(item, index) in range\" :key=\"index\">\n                            <view class=\"u-column-item\" v-for=\"(item1, index1) in item\" :key=\"index1\">\n                                <view class=\"u-line-1\">{{ getItemValue(item1, 'multiSelector') }}</view>\n                            </view>\n                        </picker-view-column>\n                    </picker-view>\n                </template>\n            </view>\n        </view>\n    </u-popup>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-picker',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, onMounted, nextTick } from 'vue';\nimport provinces from '../../libs/util/province';\nimport citys from '../../libs/util/city';\nimport areas from '../../libs/util/area';\nimport { PickerProps } from './types';\nimport { $u } from '../..';\n\n/**\n * picker picker弹出选择器\n * @description 此选择器有两种弹出模式：一是时间模式，可以配置年，日，月，时，分，秒参数 二是地区模式，可以配置省，市，区参数\n * @tutorial https://uviewpro.cn/zh/components/picker.html\n * @property {Object} params 需要显示的参数，见官网说明\n * @property {String} mode 模式选择，region-地区类型，time-时间类型（默认time）\n * @property {String Number} start-year 可选的开始年份，mode=time时有效（默认1950）\n * @property {String Number} end-year 可选的结束年份，mode=time时有效（默认2050）\n * @property {Boolean} safe-area-inset-bottom 是否开启底部安全区适配（默认false）\n * @property {Boolean} show-time-tag 时间模式时，是否显示后面的年月日中文提示\n * @property {String} cancel-color 取消按钮的颜色（默认var(--u-content-color)）\n * @property {String} confirm-color 确认按钮的颜色（默认主题色primary）\n * @property {String} default-time 默认选中的时间，mode=time时有效\n * @property {String} confirm-text 确认按钮的文字\n * @property {String} cancel-text 取消按钮的文字\n * @property {String} default-region 默认选中的地区，中文形式，mode=region时有效\n * @property {String} default-code 默认选中的地区，编号形式，mode=region时有效\n * @property {Boolean} mask-close-able 是否允许通过点击遮罩关闭Picker（默认true）\n * @property {String Number} z-index 弹出时的z-index值（默认1075）\n * @property {Array} default-selector 数组形式，其中每一项表示选择了range对应项中的第几个\n * @property {Array} range 自定义选择的数据，mode=selector或mode=multiSelector时有效\n * @property {String} range-key 当range参数的元素为对象时，指定Object中的哪个key的值作为选择器显示内容\n * @event {Function} confirm 点击确定按钮，返回当前选择的值\n * @event {Function} cancel 点击取消按钮，返回当前选择的值\n * @example <u-picker v-model=\"show\" mode=\"time\"></u-picker>\n */\nconst props = defineProps(PickerProps);\n\nconst popupValue = computed({\n    get: () => props.modelValue,\n    set: (val: boolean) => emit('update:modelValue', val)\n});\n\nconst emit = defineEmits(['update:modelValue', 'confirm', 'cancel', 'columnchange']);\n\n// 主要数据\nconst years = ref<number[]>([]);\nconst months = ref<number[]>([]);\nconst days = ref<number[]>([]);\nconst hours = ref<number[]>([]);\nconst minutes = ref<number[]>([]);\nconst seconds = ref<number[]>([]);\nconst year = ref<number>(0);\nconst month = ref<number>(0);\nconst day = ref<number>(0);\nconst hour = ref<number>(0);\nconst minute = ref<number>(0);\nconst second = ref<number>(0);\nconst startDate = ref('');\nconst endDate = ref('');\nconst valueArr = ref<number[]>([]);\nconst provincesRef = ref<any[]>(provinces);\nconst citysRef = ref<any[]>(citys[0]);\nconst areasRef = ref<any[]>(areas[0][0]);\nconst province = ref<number>(0);\nconst city = ref<number>(0);\nconst area = ref<number>(0);\n// 列是否还在滑动中，微信小程序如果在滑动中就点确定，结果可能不准确\nconst moving = ref(false);\nconst multiSelectorValue = ref<number[]>([]);\n// 控制 picker-view 是否渲染（等待 init 完成以避免 APP-PLUS 首次渲染时获取不到默认值）\nconst readyToRender = ref(false);\n\n// 保存用户上次确认的值（如果用户从未确认过，则为 null）\nconst savedDefaultSelector = ref<number[] | null>(\n    props.defaultSelector && (props.defaultSelector as any[]).length ? (props.defaultSelector as any[]).slice() : null\n);\nconst savedDefaultTime = ref<string | null>(props.defaultTime ? props.defaultTime : null);\nconst savedDefaultRegion = ref<any[] | null>(\n    props.defaultRegion && props.defaultRegion.length ? props.defaultRegion.slice() : null\n);\n\n// Helper: get effective defaults according to preserveSelection\nfunction getEffectiveDefaultSelector(): number[] {\n    // 计算生效的 selector 默认值，并打印调试信息\n    let res: number[] = [];\n    if (props.preserveSelection) {\n        if (savedDefaultSelector && savedDefaultSelector.value && savedDefaultSelector.value.length)\n            res = savedDefaultSelector.value.slice();\n        else res = (props.defaultSelector as number[]) || [0];\n    } else {\n        if (props.defaultSelector && (props.defaultSelector as any[]).length) res = props.defaultSelector as number[];\n        else res = savedDefaultSelector.value ?? [0];\n    }\n    return res;\n}\n\nfunction getEffectiveDefaultTime(): string {\n    let res: string;\n    if (props.preserveSelection) res = savedDefaultTime.value ?? props.defaultTime ?? '';\n    else res = props.defaultTime ?? savedDefaultTime.value ?? '';\n    return res;\n}\n\nfunction getEffectiveDefaultRegion(): any[] {\n    let res: any[] = [];\n    if (props.preserveSelection) {\n        if (savedDefaultRegion.value && savedDefaultRegion.value.length) res = savedDefaultRegion.value.slice();\n        else res = props.defaultRegion || [];\n    } else {\n        if (props.defaultRegion && props.defaultRegion.length) res = props.defaultRegion.slice();\n        else res = savedDefaultRegion.value ?? [];\n    }\n    return res;\n}\n\n// 计算属性\n// 引用这几个变量，是为了监听其变化\nconst propsChange = computed(\n    () =>\n        `${props.mode}-${props.defaultTime}-${props.startYear}-${props.endYear}-${props.defaultRegion}-${props.areaCode}`\n);\n// 引用这几个变量，是为了监听其变化\nconst regionChange = computed(() => `${province.value}-${city.value}`);\n\nconst yearAndMonth = computed(() => `${year.value}-${month.value}`);\n// 如果用户有传递z-index值，优先使用\nconst uZIndex = computed(() => (props.zIndex ? props.zIndex : $u.zIndex.popup));\n\n// 当外部的默认值被动态修改时，如果 preserveSelection 为 false，应把外部值视为新的 saved 值并在打开时生效\nwatch(\n    () => props.defaultSelector,\n    async n => {\n        if (!props.preserveSelection) {\n            savedDefaultSelector.value = n && (n as any[]).length ? (n as any[]).slice() : null;\n            if (props.modelValue) {\n                // reinit while open\n                readyToRender.value = false;\n                await nextTick();\n                // #ifdef APP-PLUS\n                await new Promise(resolve => setTimeout(resolve, 20));\n                // #endif\n                await init();\n                readyToRender.value = true;\n            }\n        }\n    },\n    { deep: true }\n);\n\nwatch(\n    () => props.defaultTime,\n    async n => {\n        if (!props.preserveSelection) {\n            savedDefaultTime.value = n || null;\n            if (props.modelValue) {\n                readyToRender.value = false;\n                await nextTick();\n                // #ifdef APP-PLUS\n                await new Promise(resolve => setTimeout(resolve, 20));\n                // #endif\n                await init();\n                readyToRender.value = true;\n            }\n        }\n    }\n);\n\nwatch(\n    () => props.defaultRegion,\n    async n => {\n        if (!props.preserveSelection) {\n            savedDefaultRegion.value = n && (n as any[]).length ? (n as any[]).slice() : null;\n            if (props.modelValue) {\n                readyToRender.value = false;\n                await nextTick();\n                // #ifdef APP-PLUS\n                await new Promise(resolve => setTimeout(resolve, 20));\n                // #endif\n                await init();\n                readyToRender.value = true;\n            }\n        }\n    },\n    { deep: true }\n);\n\n// 如果地区发生变化，为了让picker联动起来，必须重置this.citys和this.areas\nwatch(regionChange, () => {\n    citysRef.value = citys[province.value];\n    areasRef.value = areas[province.value][city.value];\n});\n\n// watch监听月份的变化，实时变更日的天数，因为不同月份，天数不一样\n// 一个月可能有30，31天，甚至闰年2月的29天，平年2月28天\nwatch(yearAndMonth, () => {\n    if (props.params.year) setDays();\n});\nwatch(\n    () => props.modelValue,\n    async n => {\n        if (n) {\n            // 等待一次 DOM 更新\n            await nextTick();\n            // APP-PLUS 原生控件可能需要更长的原生初始化时间，先短延迟以提高稳定性\n            // #ifdef APP-PLUS\n            await new Promise(resolve => setTimeout(resolve, 20));\n            // #endif\n            // 初始化数据并在完成后再渲染 picker-view\n            await init();\n            readyToRender.value = true;\n        } else {\n            // 关闭时隐藏 picker，保留已保存的值\n            readyToRender.value = false;\n        }\n    }\n);\n\n// 方法区\n/**\n * 标识滑动开始，只有微信小程序才有这样的事件\n */\nfunction pickstart() {\n    // #ifdef MP-WEIXIN\n    moving.value = true;\n    // #endif\n}\n/**\n * 标识滑动结束\n */\nfunction pickend() {\n    // #ifdef MP-WEIXIN\n    moving.value = false;\n    // #endif\n}\n/**\n * 对单列和多列形式的判断是否有传入变量的情况\n * @param item 当前项\n * @param mode 模式\n */\nfunction getItemValue(item: any, mode: string) {\n    // 目前(2020-05-25)uni-app对微信小程序编译有错误，导致v-if为false中的内容也执行，错误导致\n    // 单列模式或者多列模式中的getItemValue同时被执行，故在这里再加一层判断\n    if (props.mode == mode) {\n        return typeof item == 'object' ? item[props.rangeKey] : item;\n    }\n}\n/**\n * 小于10前面补0，用于月份，日期，时分秒等\n */\nfunction formatNumber(num: number | string) {\n    return +num < 10 ? '0' + num : String(num);\n}\n/**\n * 生成递进的数组\n */\nfunction generateArray(start: number, end: number) {\n    // 转为数值格式，否则用户给end-year等传递字符串值时，下面的end+1会导致字符串拼接，而不是相加\n    start = Number(start);\n    end = Number(end);\n    end = end > start ? end : start;\n    // 生成数组，获取其中的索引，并剪出来\n    return [...Array(end + 1).keys()].slice(start);\n}\n/**\n * 获取数组中指定值的索引\n */\nfunction getIndex(arr: any[], val: any) {\n    let index = arr.indexOf(val);\n    // 如果index为-1(即找不到index值)，~(-1)=-(-1)-1=0，导致条件不成立\n    return ~index ? index : 0;\n}\n/**\n * 日期时间处理，初始化各时间字段\n */\nfunction initTimeValue() {\n    // 格式化时间，在IE浏览器(uni不存在此情况)，无法识别日期间的\"-\"间隔符号\n    const effectiveTime = getEffectiveDefaultTime() || '';\n    let fdate = effectiveTime.replace(/\\-/g, '/');\n    fdate = fdate && fdate.indexOf('/') == -1 ? `2020/01/01 ${fdate}` : fdate;\n    let time: Date;\n    if (fdate) time = new Date(fdate);\n    else time = new Date();\n    // 获取年日月时分秒\n    year.value = time.getFullYear();\n    month.value = Number(time.getMonth()) + 1;\n    day.value = time.getDate();\n    hour.value = time.getHours();\n    minute.value = time.getMinutes();\n    second.value = time.getSeconds();\n}\n/**\n * 初始化picker各列数据\n */\nasync function init() {\n    valueArr.value = [];\n    if (props.mode == 'time') {\n        initTimeValue();\n        if (props.params.year) {\n            valueArr.value.push(0);\n            setYears();\n        }\n        if (props.params.month) {\n            valueArr.value.push(0);\n            setMonths();\n        }\n        if (props.params.day) {\n            valueArr.value.push(0);\n            setDays();\n        }\n        if (props.params.hour) {\n            valueArr.value.push(0);\n            setHours();\n        }\n        if (props.params.minute) {\n            valueArr.value.push(0);\n            setMinutes();\n        }\n        if (props.params.second) {\n            valueArr.value.push(0);\n            setSeconds();\n        }\n    } else if (props.mode == 'region') {\n        if (props.params.province) {\n            valueArr.value.push(0);\n            setProvinces();\n        }\n        if (props.params.city) {\n            valueArr.value.push(0);\n            setCitys();\n        }\n        if (props.params.area) {\n            valueArr.value.push(0);\n            setAreas();\n        }\n    } else if (props.mode == 'selector') {\n        // use effective default selector according to preserveSelection\n        valueArr.value = getEffectiveDefaultSelector();\n    } else if (props.mode == 'multiSelector') {\n        valueArr.value = getEffectiveDefaultSelector();\n        multiSelectorValue.value = getEffectiveDefaultSelector();\n    }\n    // 等待 DOM 与 Vue 响应式更新完成，确保在原生组件挂载时数据已就绪\n    await nextTick();\n}\n/**\n * 设置年份列\n */\nfunction setYears() {\n    // 获取年份集合\n    years.value = generateArray(props.startYear as number, props.endYear as number);\n    // 设置this.valueArr某一项的值，是为了让picker预选中某一个值\n    valueArr.value.splice(valueArr.value.length - 1, 1, getIndex(years.value, year.value));\n}\n/**\n * 设置月份列\n */\nfunction setMonths() {\n    months.value = generateArray(1, 12);\n    valueArr.value.splice(valueArr.value.length - 1, 1, getIndex(months.value, month.value));\n}\n/**\n * 设置天数列\n */\nfunction setDays() {\n    let totalDays = new Date(year.value, month.value, 0).getDate();\n    days.value = generateArray(1, totalDays);\n    let index = 0;\n    // 这里不能使用类似setMonths()中的this.valueArr.splice(this.valueArr.length - 1, 1, xxx)做法\n    // 因为this.month和this.year变化时，会触发watch中的this.setDays()，导致this.valueArr.length计算有误\n    if (props.params.year && props.params.month) index = 2;\n    else if (props.params.month) index = 1;\n    else if (props.params.year) index = 1;\n    else index = 0;\n    // 当月份变化时，会导致日期的天数也会变化，如果原来选的天数大于变化后的天数，则重置为变化后的最大值\n    // 比如原来选中3月31日，调整为2月后，日期变为最大29，这时如果day值继续为31显然不合理，于是将其置为29(picker-column从1开始)\n    if (day.value > days.value.length) day.value = days.value.length;\n    valueArr.value.splice(index, 1, getIndex(days.value, day.value));\n}\n/**\n * 设置小时列\n */\nfunction setHours() {\n    hours.value = generateArray(0, 23);\n    valueArr.value.splice(valueArr.value.length - 1, 1, getIndex(hours.value, hour.value));\n}\n/**\n * 设置分钟列\n */\nfunction setMinutes() {\n    minutes.value = generateArray(0, 59);\n    valueArr.value.splice(valueArr.value.length - 1, 1, getIndex(minutes.value, minute.value));\n}\n/**\n * 设置秒数列\n */\nfunction setSeconds() {\n    seconds.value = generateArray(0, 59);\n    valueArr.value.splice(valueArr.value.length - 1, 1, getIndex(seconds.value, second.value));\n}\n/**\n * 设置省份列\n */\nfunction setProvinces() {\n    // 判断是否需要province参数\n    if (!props.params.province) return;\n    let tmp: any = 0;\n    let useCode = false;\n    // 如果同时配置了defaultRegion和areaCode，优先使用areaCode参数\n    if (props.areaCode.length) {\n        tmp = props.areaCode[0];\n        useCode = true;\n    } else {\n        const effRegion = getEffectiveDefaultRegion();\n        if (effRegion && effRegion.length) tmp = effRegion[0];\n    }\n    // 历遍省份数组匹配\n    provinces.map((v: any, k: number) => {\n        if (useCode ? v.value == tmp : v.label == tmp) {\n            tmp = k;\n        }\n    });\n    province.value = tmp;\n    provincesRef.value = provinces;\n    // 设置默认省份的值\n    valueArr.value.splice(0, 1, province.value);\n}\n/**\n * 设置城市列\n */\nfunction setCitys() {\n    if (!props.params.city) return;\n    let tmp: any = 0;\n    let useCode = false;\n    if (props.areaCode.length) {\n        tmp = props.areaCode[1];\n        useCode = true;\n    } else {\n        const effRegion = getEffectiveDefaultRegion();\n        if (effRegion && effRegion.length) tmp = effRegion[1];\n    }\n    // 历遍城市数组匹配\n    citys[province.value].map((v: any, k: number) => {\n        if (useCode ? v.value == tmp : v.label == tmp) {\n            tmp = k;\n        }\n    });\n    city.value = tmp;\n    citysRef.value = citys[province.value];\n    // 设置默认城市的值\n    valueArr.value.splice(1, 1, city.value);\n}\n/**\n * 设置区县列\n */\nfunction setAreas() {\n    if (!props.params.area) return;\n    let tmp: any = 0;\n    let useCode = false;\n    if (props.areaCode.length) {\n        tmp = props.areaCode[2];\n        useCode = true;\n    } else {\n        const effRegion = getEffectiveDefaultRegion();\n        if (effRegion && effRegion.length) tmp = effRegion[2];\n    }\n    // 历遍区县数组匹配\n    areas[province.value][city.value].map((v: any, k: number) => {\n        if (useCode ? v.value == tmp : v.label == tmp) {\n            tmp = k;\n        }\n    });\n    area.value = tmp;\n    areasRef.value = areas[province.value][city.value];\n    // 设置默认区县的值\n    valueArr.value.splice(2, 1, area.value);\n}\n/**\n * 关闭picker弹窗\n */\nfunction close() {\n    emit('update:modelValue', false);\n}\n/**\n * 用户更改picker的列选项\n * @param e 事件对象\n */\nfunction change(e: any) {\n    valueArr.value = e.detail.value;\n    let i = 0;\n    if (props.mode == 'time') {\n        // 这里使用i++，是因为valueArr数组的长度是不确定长度的，它根据params的值来配置长度\n        // 进入if规则，i会加1，保证了能获取准确的值\n        if (props.params.year) year.value = years.value[valueArr.value[i++]];\n        if (props.params.month) month.value = months.value[valueArr.value[i++]];\n        if (props.params.day) day.value = days.value[valueArr.value[i++]];\n        if (props.params.hour) hour.value = hours.value[valueArr.value[i++]];\n        if (props.params.minute) minute.value = minutes.value[valueArr.value[i++]];\n        if (props.params.second) second.value = seconds.value[valueArr.value[i++]];\n    } else if (props.mode == 'region') {\n        if (props.params.province) province.value = valueArr.value[i++];\n        if (props.params.city) city.value = valueArr.value[i++];\n        if (props.params.area) area.value = valueArr.value[i++];\n    } else if (props.mode == 'multiSelector') {\n        let index: number | null = null;\n        // 对比前后两个数组，寻找变更的是哪一列，如果某一个元素不同，即可判定该列发生了变化\n        (props.defaultSelector as number[]).map((val: number, idx: number) => {\n            if (val != e.detail.value[idx]) index = idx;\n        });\n        // 为了让用户对多列变化时，对动态设置其他列的变更\n        if (index != null) {\n            emit('columnchange', {\n                column: index,\n                index: e.detail.value[index]\n            });\n        }\n    }\n}\n/**\n * 用户点击确定/取消按钮，获取结果\n * @param event 事件名\n */\nfunction getResult(event: string | null = null) {\n    // #ifdef MP-WEIXIN\n    // 微信小程序滑动中不允许点击确定，防止取值不准确\n    if (moving.value) return;\n    // #endif\n    let result: any = {};\n    // 只返回用户在params中配置了为true的字段\n    if (props.mode == 'time') {\n        if (props.params.year) result.year = formatNumber(year.value || 0); // 年\n        if (props.params.month) result.month = formatNumber(month.value || 0); // 月\n        if (props.params.day) result.day = formatNumber(day.value || 0); // 日\n        if (props.params.hour) result.hour = formatNumber(hour.value || 0); // 时\n        if (props.params.minute) result.minute = formatNumber(minute.value || 0); // 分\n        if (props.params.second) result.second = formatNumber(second.value || 0); // 秒\n        if (props.params.timestamp) result.timestamp = getTimestamp(); // 时间戳\n    } else if (props.mode == 'region') {\n        // 地区模式，返回省市区对象\n        if (props.params.province) result.province = provinces[province.value];\n        if (props.params.city) result.city = citys[province.value][city.value];\n        if (props.params.area) result.area = areas[province.value][city.value][area.value];\n    } else if (props.mode == 'selector') {\n        // 单列选择器，直接返回选中下标数组\n        result = valueArr.value;\n    } else if (props.mode == 'multiSelector') {\n        // 多列选择器，直接返回选中下标数组\n        result = valueArr.value;\n    }\n    // 只允许 emit 已声明的事件类型\n    // 保存用户确认的选择为下次默认（如果用户点了确认）\n    if (event === 'confirm') {\n        // time 模式保存字符串\n        if (props.mode == 'time') {\n            // 构造时间字符串，按 year-month-day [hour:minute:second]\n            const pad = (n: number) => (n < 10 ? '0' + n : '' + n);\n            let timeStr = `${year.value}-${pad(month.value)}-${pad(day.value)}`;\n            if (props.params.hour)\n                timeStr +=\n                    ` ${pad(hour.value)}:${pad(minute.value)}` + (props.params.second ? `:${pad(second.value)}` : '');\n            savedDefaultTime.value = timeStr;\n        } else if (props.mode == 'region') {\n            // 保存为 label 数组，便于 later 使用 defaultRegion\n            const prov = provinces[province.value] ? provinces[province.value].label : undefined;\n            const cit =\n                citys[province.value] && citys[province.value][city.value]\n                    ? citys[province.value][city.value].label\n                    : undefined;\n            const are =\n                areas[province.value] &&\n                areas[province.value][city.value] &&\n                areas[province.value][city.value][area.value]\n                    ? areas[province.value][city.value][area.value].label\n                    : undefined;\n            const arr: any[] = [];\n            if (prov !== undefined) arr.push(prov);\n            if (cit !== undefined) arr.push(cit);\n            if (are !== undefined) arr.push(are);\n            savedDefaultRegion.value = arr;\n        } else if (props.mode == 'selector' || props.mode == 'multiSelector') {\n            savedDefaultSelector.value = valueArr.value ? valueArr.value.slice() : null;\n        }\n    }\n\n    if (event && ['update:modelValue', 'confirm', 'cancel', 'columnchange'].includes(event))\n        emit(event as 'update:modelValue' | 'confirm' | 'cancel' | 'columnchange', result);\n    close();\n}\n/**\n * 获取时间戳（秒）\n * @returns {number} 时间戳\n */\nfunction getTimestamp() {\n    // yyyy-mm-dd为安卓写法，不支持iOS，需要使用\"/\"分隔，才能二者兼容\n    let time =\n        year.value + '/' + month.value + '/' + day.value + ' ' + hour.value + ':' + minute.value + ':' + second.value;\n    return new Date(time).getTime() / 1000;\n}\n\n// 组件挂载时初始化\nonMounted(() => {\n    init();\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-datetime-picker {\n    position: relative;\n    z-index: 999;\n}\n\n.u-picker-view {\n    height: 100%;\n    box-sizing: border-box;\n}\n\n.u-picker-header {\n    width: 100%;\n    height: 90rpx;\n    @include vue-flex;\n    justify-content: space-between;\n    align-items: center;\n    box-sizing: border-box;\n    font-size: 30rpx;\n    background-color: var(--u-bg-white);\n    position: relative;\n}\n\n.u-picker-header::after {\n    content: '';\n    position: absolute;\n    border-bottom: 1rpx solid var(--u-border-color);\n    -webkit-transform: scaleY(0.5);\n    transform: scaleY(0.5);\n    bottom: 0;\n    right: 0;\n    left: 0;\n}\n\n.u-picker__title {\n    color: $u-content-color;\n}\n\n.u-picker-body {\n    width: 100%;\n    height: 500rpx;\n    overflow: hidden;\n    background-color: var(--u-bg-white);\n}\n\n.u-column-item {\n    @include vue-flex;\n    align-items: center;\n    justify-content: center;\n    font-size: 32rpx;\n    color: $u-main-color;\n    padding: 0 8rpx;\n}\n\n.u-text {\n    font-size: 24rpx;\n    padding-left: 8rpx;\n}\n\n.u-btn-picker {\n    min-width: 150rpx;\n    padding: 20rpx 30rpx;\n    box-sizing: border-box;\n    text-align: center;\n    text-decoration: none;\n}\n\n.u-opacity {\n    opacity: 0.5;\n}\n\n.u-btn-picker--primary {\n    color: $u-type-primary;\n}\n\n.u-btn-picker--tips {\n    color: $u-tips-color;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-popup/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { PopupCloseIconPos, PopupMode } from '../../types/global';\nimport zIndex from '../../libs/config/zIndex';\n\n/**\n * PopupProps 弹窗 props 类型定义\n * @description 弹出层容器，支持多种弹出方向和自定义内容\n */\nexport const PopupProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 显示状态 */\n    show: { type: Boolean, default: false },\n    /** 弹出方向，left|right|top|bottom|center */\n    mode: { type: String as PropType<PopupMode>, default: 'left' },\n    /** 是否显示遮罩 */\n    mask: { type: Boolean, default: true },\n    /** 抽屉的宽度(mode=left|right)，或者高度(mode=top|bottom)，单位rpx，或者\"auto\"，或者百分比\"50%\"，表示由内容撑开高度或者宽度 */\n    length: { type: [Number, String] as PropType<number | string>, default: 'auto' },\n    /** 是否开启缩放动画，只在mode=center时有效 */\n    zoom: { type: Boolean, default: true },\n    /** 是否开启底部安全区适配，开启的话，会在iPhoneX机型底部添加一定的内边距 */\n    safeAreaInsetBottom: { type: Boolean, default: false },\n    /** 是否可以通过点击遮罩进行关闭 */\n    maskCloseAble: { type: Boolean, default: true },\n    /** v-model 控制弹窗显示 */\n    modelValue: { type: Boolean, default: false },\n    /** 内部参数，解决多层调用报错不能修改props值的问题 */\n    popup: { type: Boolean, default: true },\n    /** 圆角 */\n    borderRadius: { type: [Number, String] as PropType<number | string>, default: 0 },\n    /** 弹窗z-index */\n    zIndex: { type: [Number, String] as PropType<number | string>, default: zIndex.popup },\n    /** 是否显示关闭图标 */\n    closeable: { type: Boolean, default: false },\n    /** 关闭图标的名称，只能uView的内置图标 */\n    closeIcon: { type: String, default: 'close' },\n    /** 自定义关闭图标位置，top-left为左上角，top-right为右上角，bottom-left为左下角，bottom-right为右下角 */\n    closeIconPos: { type: String as PropType<PopupCloseIconPos>, default: 'top-right' },\n    /** 关闭图标的颜色 */\n    closeIconColor: { type: String, default: 'var(--u-tips-color)' },\n    /** 关闭图标的大小，单位rpx */\n    closeIconSize: { type: [String, Number] as PropType<number | string>, default: '30' },\n    /** 弹窗宽度 */\n    width: { type: String, default: '' },\n    /** 弹窗高度 */\n    height: { type: String, default: '' },\n    /** 负top定位，支持rpx/px/百分比 */\n    negativeTop: { type: [String, Number] as PropType<number | string>, default: 0 },\n    /** 遮罩自定义样式 */\n    maskCustomStyle: { type: Object as PropType<Record<string, any>>, default: () => ({}) },\n    /** 动画时长，单位ms */\n    duration: { type: [String, Number] as PropType<number | string>, default: 250 }\n};\n\nexport type PopupProps = ExtractPropTypes<typeof PopupProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-popup/u-popup.vue",
    "content": "<template>\n    <!-- inline 模式：直接渲染内容，不显示为弹窗 -->\n    <view v-if=\"props.mode === 'inline'\" class=\"u-popup-inline\" :class=\"customClass\" :style=\"inlineStyle\">\n        <slot />\n    </view>\n    <!-- 弹窗模式 -->\n    <view\n        v-else-if=\"visibleSync\"\n        class=\"u-drawer\"\n        :style=\"$u.toStyle({ zIndex: Number(uZIndex) - 1 }, customStyle)\"\n        :class=\"customClass\"\n        hover-stop-propagation\n    >\n        <u-mask\n            :duration=\"duration\"\n            :custom-style=\"maskCustomStyle\"\n            :maskClickAble=\"maskCloseAble\"\n            :z-index=\"Number(uZIndex) - 2\"\n            :show=\"showDrawer && mask\"\n            @click=\"maskClick\"\n        ></u-mask>\n        <view\n            class=\"u-drawer-content\"\n            @tap=\"modeCenterClose(mode)\"\n            :class=\"[\n                safeAreaInsetBottom ? 'safe-area-inset-bottom' : '',\n                'u-drawer-' + mode,\n                showDrawer ? 'u-drawer-content-visible' : '',\n                zoom && mode == 'center' ? 'u-animation-zoom' : ''\n            ]\"\n            @touchmove.stop.prevent\n            :style=\"[style]\"\n        >\n            <view\n                v-if=\"mode == 'center'\"\n                class=\"u-mode-center-box\"\n                @tap.stop.prevent\n                @touchmove.stop.prevent\n                :style=\"[centerStyle]\"\n            >\n                <view v-if=\"closeable\" @click=\"close\" class=\"u-close\" :class=\"['u-close--' + closeIconPos]\">\n                    <u-icon :name=\"closeIcon\" :color=\"closeIconColor\" :size=\"closeIconSize\"></u-icon>\n                </view>\n\n                <scroll-view class=\"u-drawer__scroll-view\" :scroll-y=\"true\">\n                    <slot />\n                </scroll-view>\n            </view>\n            <scroll-view class=\"u-drawer__scroll-view\" :scroll-y=\"true\" v-else>\n                <slot />\n            </scroll-view>\n            <view\n                v-if=\"mode != 'center' && closeable\"\n                @click=\"close\"\n                class=\"u-close\"\n                :class=\"['u-close--' + closeIconPos]\"\n            >\n                <u-icon :name=\"closeIcon\" :color=\"closeIconColor\" :size=\"closeIconSize\"></u-icon>\n            </view>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-popup',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, onMounted, nextTick } from 'vue';\nimport { $u } from '../..';\nimport { PopupProps } from './types';\n\n/**\n * popup 弹窗\n * @description 弹出层容器，用于展示弹窗、信息提示等内容，支持上、下、左、右和中部弹出。组件只提供容器，内部内容由用户自定义\n * @tutorial https://uviewpro.cn/zh/components/popup.html\n * @property {String} mode 弹出方向（默认left），新增 inline 模式可直接插入页面\n * @property {Boolean} mask 是否显示遮罩（默认true）\n * @property {Stringr | Number} length mode=left | 见官网说明（默认auto）\n * @property {Boolean} zoom 是否开启缩放动画，只在mode为center时有效（默认true）\n * @property {Boolean} safe-area-inset-bottom 是否开启底部安全区适配（默认false）\n * @property {Boolean} mask-close-able 点击遮罩是否可以关闭弹出层（默认true）\n * @property {Object} custom-style 用户自定义样式\n * @property {Stringr | Number} negative-top 中部弹出时，往上偏移的值\n * @property {Numberr | String} border-radius 弹窗圆角值（默认0）\n * @property {Numberr | String} z-index 弹出内容的z-index值（默认1075）\n * @property {Boolean} closeable 是否显示关闭图标（默认false）\n * @property {String} close-icon 关闭图标的名称，只能uView的内置图标\n * @property {String} close-icon-pos 自定义关闭图标位置（默认top-right）\n * @property {String} close-icon-color 关闭图标的颜色（默认var(--u-tips-color)）\n * @property {Number | String} close-icon-size 关闭图标的大小，单位rpx（默认30）\n * @event {Function} open 弹出层打开\n * @event {Function} close 弹出层收起\n * @example <u-popup v-model=\"show\"><view>出淤泥而不染，濯清涟而不妖</view></u-popup>\n * @example <u-popup mode=\"inline\"><view>直接插入页面内容</view></u-popup>\n */\n\nconst props = defineProps(PopupProps);\nconst emit = defineEmits(['update:modelValue', 'open', 'close']);\n\n// 组件内部状态\nconst visibleSync = ref(false);\nconst showDrawer = ref(false);\nconst timer = ref<ReturnType<typeof setTimeout> | null>(null);\nconst closeFromInner = ref(false); // value的值改变，是发生在内部还是外部\n\n// inline 模式的样式\nconst inlineStyle = computed(() => {\n    let style: Record<string, any> = {};\n    if (props.width) style.width = getUnitValue(props.width);\n    if (props.height) style.height = getUnitValue(props.height);\n    if (props.borderRadius) style.borderRadius = `${props.borderRadius}rpx`;\n    // 合并用户自定义样式\n    if (props.customStyle) {\n        if (typeof props.customStyle === 'string') {\n            // 简单处理字符串样式\n            style = { ...style };\n        } else {\n            Object.assign(style, props.customStyle);\n        }\n    }\n    return style;\n});\n\n// 根据mode的位置，设定其弹窗的宽度(mode = left|right)，或者高度(mode = top|bottom)\nconst style = computed(() => {\n    let style: Record<string, any> = {};\n    // 如果是左边或者上边弹出时，需要给translate设置为负值，用于隐藏\n    if (props.mode == 'left' || props.mode == 'right') {\n        style = {\n            width: props.width ? getUnitValue(props.width) : getUnitValue(props.length),\n            height: '100%',\n            transform: `translate3D(${props.mode == 'left' ? '-100%' : '100%'},0px,0px)`\n        };\n    } else if (props.mode == 'top' || props.mode == 'bottom') {\n        style = {\n            width: '100%',\n            height: props.height ? getUnitValue(props.height) : getUnitValue(props.length),\n            transform: `translate3D(0px,${props.mode == 'top' ? '-100%' : '100%'},0px)`\n        };\n    }\n    // 如果用户设置了borderRadius值，添加弹窗的圆角\n    style.zIndex = uZIndex.value;\n    if (props.borderRadius) {\n        switch (props.mode) {\n            case 'left':\n                style.borderRadius = `0 ${props.borderRadius}rpx ${props.borderRadius}rpx 0`;\n                break;\n            case 'top':\n                style.borderRadius = `0 0 ${props.borderRadius}rpx ${props.borderRadius}rpx`;\n                break;\n            case 'right':\n                style.borderRadius = `${props.borderRadius}rpx 0 0 ${props.borderRadius}rpx`;\n                break;\n            case 'bottom':\n                style.borderRadius = `${props.borderRadius}rpx ${props.borderRadius}rpx 0 0`;\n                break;\n            default:\n        }\n        // 不加可能圆角无效\n        style.overflow = 'hidden';\n    }\n    if (props.duration) style.transition = `all ${Number(props.duration) / 1000}s linear`;\n    return style;\n});\n\n// 中部弹窗的特有样式\nconst centerStyle = computed(() => {\n    let style: Record<string, any> = {};\n    style.width = props.width ? getUnitValue(props.width) : getUnitValue(props.length);\n\n    // 中部弹出的模式，如果没有设置高度，就用auto值，由内容撑开高度\n    style.height = props.height ? getUnitValue(props.height) : 'auto';\n    style.zIndex = uZIndex.value;\n    style.marginTop = `-${$u.addUnit(props.negativeTop)}`;\n    if (props.borderRadius) {\n        style.borderRadius = `${props.borderRadius}rpx`;\n        // 不加可能圆角无效\n        style.overflow = 'hidden';\n    }\n    return style;\n});\n\n// 计算整理后的z-index值\nconst uZIndex = computed(() => (props.zIndex ? props.zIndex : $u.zIndex.popup));\n\nwatch(\n    () => props.modelValue,\n    val => {\n        // inline 模式下不响应 modelValue 变化\n        if (props.mode === 'inline') return;\n        if (val) {\n            open();\n        } else if (!closeFromInner.value) {\n            close();\n        }\n        closeFromInner.value = false;\n    }\n);\n\nonMounted(() => {\n    // inline 模式下不执行弹窗逻辑\n    if (props.mode === 'inline') return;\n    if (props.modelValue) open();\n});\n\n/**\n * 判断传入的值，是否带有单位，如果没有，就默认用rpx单位\n */\nfunction getUnitValue(val: string | number) {\n    if (/(%|px|rpx|auto)$/.test(String(val))) return val;\n    else return val + 'rpx';\n}\n\n/**\n * 遮罩被点击\n */\nfunction maskClick() {\n    close();\n}\n\n/**\n * 关闭弹窗\n */\nfunction close() {\n    // inline 模式下不执行关闭逻辑\n    if (props.mode === 'inline') return;\n    // 标记关闭是内部发生的，否则修改了value值，导致watch中对value检测，导致再执行一遍close\n    // 造成@close事件触发两次\n    closeFromInner.value = true;\n    change('showDrawer', 'visibleSync', false);\n}\n\n/**\n * 中部弹出时，点击内容区域关闭弹窗\n */\nfunction modeCenterClose(mode: string) {\n    // inline 模式下不执行关闭逻辑\n    if (props.mode === 'inline') return;\n    // 中部弹出时，需要.u-drawer-content将居中内容，此元素会铺满屏幕，点击需要关闭弹窗\n    // 让其只在mode=center时起作用\n    if (mode != 'center' || !props.maskCloseAble) return;\n    close();\n}\n\n/**\n * 打开弹窗\n */\nfunction open() {\n    // inline 模式下不执行打开逻辑\n    if (props.mode === 'inline') return;\n    change('visibleSync', 'showDrawer', true);\n}\n\n/**\n * 控制弹窗显示/隐藏的动画和状态\n * 此处的原理是，关闭时先通过动画隐藏弹窗和遮罩，再移除整个组件\n * 打开时，先渲染组件，延时一定时间再让遮罩和弹窗的动画起作用\n */\nfunction change(param1: 'showDrawer' | 'visibleSync', param2: 'visibleSync' | 'showDrawer', status: boolean) {\n    // inline 模式下不执行状态变更\n    if (props.mode === 'inline') return;\n    // 如果this.popup为false，意味着为picker，actionsheet等组件调用了popup组件\n    if (props.popup === true) {\n        emit('update:modelValue', status);\n    }\n    (param1 === 'showDrawer' ? showDrawer : visibleSync).value = status;\n    if (status) {\n        // #ifdef H5 || MP\n        timer.value = setTimeout(() => {\n            (param2 === 'showDrawer' ? showDrawer : visibleSync).value = status;\n            emit(status ? 'open' : 'close');\n        }, 50);\n        // #endif\n        // #ifndef H5 || MP\n        nextTick(() => {\n            (param2 === 'showDrawer' ? showDrawer : visibleSync).value = status;\n            emit(status ? 'open' : 'close');\n        });\n        // #endif\n    } else {\n        timer.value = setTimeout(() => {\n            (param2 === 'showDrawer' ? showDrawer : visibleSync).value = status;\n            emit(status ? 'open' : 'close');\n        }, Number(props.duration));\n    }\n}\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n\n// inline 模式样式\n.u-popup-inline {\n    /* #ifndef APP-NVUE */\n    display: block;\n    /* #endif */\n    position: relative;\n    background-color: var(--u-bg-white);\n}\n\n.u-drawer {\n    /* #ifndef APP-NVUE */\n    display: block;\n    /* #endif */\n    position: fixed;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    overflow: hidden;\n}\n\n.u-drawer-content {\n    /* #ifndef APP-NVUE */\n    display: block;\n    /* #endif */\n    position: absolute;\n    z-index: 1003;\n    transition: all 0.25s linear;\n}\n\n.u-drawer__scroll-view {\n    width: 100%;\n    height: 100%;\n}\n\n.u-drawer-left {\n    top: 0;\n    bottom: 0;\n    left: 0;\n    background-color: var(--u-bg-white);\n}\n\n.u-drawer-right {\n    right: 0;\n    top: 0;\n    bottom: 0;\n    background-color: var(--u-bg-white);\n}\n\n.u-drawer-top {\n    top: 0;\n    left: 0;\n    right: 0;\n    background-color: var(--u-bg-white);\n}\n\n.u-drawer-bottom {\n    bottom: 0;\n    left: 0;\n    right: 0;\n    background-color: var(--u-bg-white);\n}\n\n.u-drawer-center {\n    @include vue-flex;\n    flex-direction: column;\n    bottom: 0;\n    left: 0;\n    right: 0;\n    top: 0;\n    justify-content: center;\n    align-items: center;\n    opacity: 0;\n    z-index: 99999;\n}\n\n.u-mode-center-box {\n    min-width: 100rpx;\n    min-height: 100rpx;\n    /* #ifndef APP-NVUE */\n    display: block;\n    /* #endif */\n    position: relative;\n    background-color: var(--u-bg-white);\n}\n\n.u-drawer-content-visible.u-drawer-center {\n    transform: scale(1);\n    opacity: 1;\n}\n\n.u-animation-zoom {\n    transform: scale(1.15);\n}\n\n.u-drawer-content-visible {\n    transform: translate3D(0px, 0px, 0px) !important;\n}\n\n.u-close {\n    position: absolute;\n    z-index: 3;\n}\n\n.u-close--top-left {\n    top: 30rpx;\n    left: 30rpx;\n}\n\n.u-close--top-right {\n    top: 30rpx;\n    right: 30rpx;\n}\n\n.u-close--bottom-left {\n    bottom: 30rpx;\n    left: 30rpx;\n}\n\n.u-close--bottom-right {\n    right: 30rpx;\n    bottom: 30rpx;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-radio/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { Shape, SizeType } from '../../types/global';\n\n/**\n * RadioProps 单选框 props 类型定义\n * @description 单选框用于有一个选择，用户只能选择其中一个的场景。搭配u-radio-group使用\n */\nexport const RadioProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    label: { type: String, default: '' },\n    value: { type: [String, Number] as PropType<string | number>, default: '' },\n    /** radio的名称 */\n    name: { type: [String, Number] as PropType<string | number>, default: '' },\n    /** 形状，square为方形，circle为圆形 */\n    shape: { type: String as PropType<Shape>, default: '' },\n    /** 是否禁用 */\n    disabled: { type: [String, Boolean] as PropType<string | boolean>, default: '' },\n    /** 是否禁止点击提示语选中复选框 */\n    labelDisabled: { type: [String, Boolean] as PropType<string | boolean>, default: '' },\n    /** 选中状态下的颜色，如设置此值，将会覆盖parent的activeColor值 */\n    activeColor: { type: String, default: '' },\n    /** 图标的大小，单位rpx */\n    iconSize: { type: [String, Number] as PropType<number | string>, default: '' },\n    /** label的字体大小，rpx单位 */\n    labelSize: { type: [String, Number] as PropType<number | string>, default: '' },\n    /** 组件的整体大小 */\n    size: { type: [String, Number] as PropType<SizeType | string | number>, default: '' }\n};\n\nexport type RadioProps = ExtractPropTypes<typeof RadioProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-radio/u-radio.vue",
    "content": "<template>\n    <view class=\"u-radio\" :style=\"$u.toStyle(radioStyle, customStyle)\" :class=\"customClass\">\n        <view class=\"u-radio__icon-wrap\" @tap=\"toggle\" :class=\"iconClass\" :style=\"$u.toStyle(iconStyle)\">\n            <u-icon\n                custom-class=\"u-radio__icon-wrap__icon\"\n                name=\"checkbox-mark\"\n                :size=\"elIconSize\"\n                :color=\"iconColor\"\n            />\n        </view>\n        <view\n            class=\"u-radio__label\"\n            @tap=\"onClickLabel\"\n            :style=\"{\n                fontSize: labelFontSize\n            }\"\n        >\n            <slot>\n                {{ label }}\n            </slot>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-radio',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { $u, useChildren } from '../..';\nimport { RadioProps } from './types';\nimport type { SizeType } from '../../types/global';\n\n/**\n * radio 单选框\n * @description 单选框用于有一个选择，用户只能选择其中一个的场景。搭配u-radio-group使用\n * @tutorial https://uviewpro.cn/zh/components/radio.html\n * @property {String|Number} icon-size 图标大小，单位rpx（默认24）\n * @property {String|Number} label-size label字体大小，单位rpx（默认28）\n * @property {String|Number} name radio组件的标示符\n * @property {String} shape 形状，见上方说明（默认circle）\n * @property {Boolean} disabled 是否禁用（默认false）\n * @property {Boolean} label-disabled 点击文本是否可以操作radio（默认true）\n * @property {String} active-color 选中时的颜色，如设置parent的active-color将失效\n * @event {Function} change 某个radio状态发生变化时触发(选中状态)\n * @example <u-radio :label-disabled=\"false\">门掩黄昏，无计留春住</u-radio>\n */\n\nconst props = defineProps(RadioProps);\n\nconst emit = defineEmits(['change']);\n\n// 使用组件关系 hooks 获取父组件\nconst { parentExposed } = useChildren('u-radio', 'u-radio-group');\nconst { parentExposed: formExposed } = useChildren('u-radio', 'u-form');\n\n// radio 的value值，id\nconst radioValue = computed(() => {\n    if (props.value !== '') return props.value;\n    return props.name;\n});\n\n// 父组件的默认值（兼容没有父组件的场景）\nconst parentData = computed(() => {\n    return (\n        parentExposed?.value?.getData?.() || {\n            iconSize: null,\n            labelDisabled: null,\n            disabled: null,\n            shape: null,\n            activeColor: null,\n            size: null,\n            width: null,\n            height: null,\n            value: null,\n            wrap: null\n        }\n    );\n});\n\n// 根据 size 定义不同的配置\nconst sizeConfig = {\n    small: {\n        size: 28,\n        fontSize: 24,\n        iconSize: 16\n    },\n    default: {\n        size: 34,\n        fontSize: 28,\n        iconSize: 20\n    },\n    large: {\n        size: 40,\n        fontSize: 32,\n        iconSize: 24\n    }\n};\n\n// 获取实际使用的 size 值（优先级：props.size > u-radio-group.size > u-form.size）\nconst actualSize = computed(() => {\n    // 优先使用 props 的 size 属性\n    if (props.size !== '') {\n        return String(props.size);\n    }\n    // 次优先：使用 u-radio-group 的 size 属性\n    if (parentExposed.value?.props?.size) {\n        return String(parentExposed.value.props.size);\n    }\n    // 最后：使用 u-form 的 size 属性（u-form 的 size 只支持预设值）\n    if (formExposed.value?.props?.size) {\n        return String(formExposed.value.props.size);\n    }\n    // 默认值\n    return 'default';\n});\n\n// 判断实际使用的 size 是否在预设配置中\nconst isInSizeConfig = computed(() => actualSize.value in sizeConfig);\n\n// 获取预设 size（用于查找 sizeConfig 配置，如图标大小、高度等）\nconst presetSize = computed(() => {\n    return (isInSizeConfig.value ? actualSize.value : 'default') as SizeType;\n});\n\n// 获取当前尺寸配置\nconst currentSizeConfig = computed(() => sizeConfig[presetSize.value]);\n\n/**\n * 是否禁用，如果父组件u-radio-group禁用的话，将会忽略子组件的配置\n */\nconst elDisabled = computed(() =>\n    props.disabled !== '' ? props.disabled : parentData.value.disabled !== null ? parentData.value.disabled : false\n);\n\n/**\n * 是否禁用label点击\n */\nconst elLabelDisabled = computed(() =>\n    props.labelDisabled !== ''\n        ? props.labelDisabled\n        : parentData.value.labelDisabled !== null\n          ? parentData.value.labelDisabled\n          : false\n);\n\n/**\n * 组件尺寸，对应size的值，默认值为34rpx\n * 兼容无size属性场景\n */\nconst elSize = computed(() => currentSizeConfig.value.size);\n\n/**\n * 组件的勾选图标的尺寸，默认20\n */\nconst elIconSize = computed(() => {\n    if (props.iconSize) {\n        return props.iconSize;\n    }\n    if (parentExposed.value?.props?.iconSize) {\n        return parentExposed.value?.props?.iconSize;\n    }\n    if (isInSizeConfig.value) {\n        return currentSizeConfig.value.iconSize;\n    }\n    return 20;\n});\n\n// label字体大小，默认28\nconst labelFontSize = computed(() => {\n    if (isInSizeConfig.value) {\n        return $u.addUnit(currentSizeConfig.value.fontSize);\n    }\n    return $u.addUnit(props.labelSize);\n});\n\n/**\n * 组件选中激活时的颜色\n */\nconst elActiveColor = computed(() =>\n    props.activeColor ? props.activeColor : parentData.value.activeColor ? parentData.value.activeColor : 'primary'\n);\n\n/**\n * 组件的形状\n */\nconst elShape = computed(() =>\n    props.shape ? props.shape : parentData.value.shape ? parentData.value.shape : 'circle'\n);\n\n/**\n * 设置radio的状态，要求radio的name等于parent的value时才为选中状态\n */\nconst iconStyle = computed(() => {\n    let style: Record<string, string> = {};\n    if (elActiveColor.value && parentData.value.value == radioValue.value && !elDisabled.value) {\n        style.borderColor = elActiveColor.value;\n        style.backgroundColor = elActiveColor.value;\n    }\n    style.width = $u.addUnit(elSize.value);\n    style.height = $u.addUnit(elSize.value);\n    return style;\n});\n\nconst iconColor = computed(() => (radioValue.value == parentData.value.value ? 'var(--u-white-color)' : 'transparent'));\n\nconst iconClass = computed(() => {\n    let classes: string[] = [];\n    classes.push('u-radio__icon-wrap--' + elShape.value);\n    if (radioValue.value == parentData.value.value) classes.push('u-radio__icon-wrap--checked');\n    if (elDisabled.value) classes.push('u-radio__icon-wrap--disabled');\n    if (radioValue.value == parentData.value.value && elDisabled.value)\n        classes.push('u-radio__icon-wrap--disabled--checked');\n    // 支付宝小程序无法动态绑定一个数组类名，否则解析出来的结果会带有\",\"，而导致失效\n    return classes.join(' ');\n});\n\nconst radioStyle = computed(() => {\n    let style: Record<string, string> = {};\n    if (parentData.value.width) {\n        style.width = $u.addUnit(parentData.value.width);\n        // #ifdef MP\n        // 各家小程序因为它们特殊的编译结构，使用float布局\n        style.float = 'left';\n        // #endif\n        // #ifndef MP\n        // H5和APP使用flex布局\n        style.flex = `0 0 ${$u.addUnit(parentData.value.width)}`;\n        // #endif\n    }\n    if (parentData.value.wrap) {\n        style.width = '100%';\n        // #ifndef MP\n        // H5和APP使用flex布局，将宽度设置100%，即可自动换行\n        style.flex = '0 0 100%';\n        // #endif\n    }\n    return style;\n});\n\n/**\n * 点击label\n */\nfunction onClickLabel() {\n    if (!elLabelDisabled.value && !elDisabled.value) {\n        setRadioCheckedStatus();\n    }\n}\n/**\n * 点击icon\n */\nfunction toggle() {\n    if (!elDisabled.value) {\n        setRadioCheckedStatus();\n    }\n}\n/**\n * 发出事件\n */\nfunction emitEvent() {\n    // u-radio的name不等于父组件的v-model的值时(意味着未选中)，才发出事件，避免多次点击触发事件\n    if (parentData.value.value != radioValue.value) emit('change', radioValue.value);\n}\n/**\n * 改变组件选中状态\n * 这里的改变的依据是，更改本组件的parentData.value值为本组件的name值，同时通过父组件遍历所有u-radio实例\n * 将本组件外的其他u-radio的parentData.value都设置为空(由computed计算后，都被取消选中状态)，因而只剩下一个为选中状态\n */\nfunction setRadioCheckedStatus() {\n    emitEvent();\n    parentExposed?.value?.setValue(radioValue.value);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-radio {\n    /* #ifndef APP-NVUE */\n    display: inline-flex;\n    /* #endif */\n    align-items: center;\n    overflow: hidden;\n    user-select: none;\n    line-height: 1.8;\n\n    &__icon-wrap {\n        color: $u-content-color;\n        @include vue-flex;\n        flex: none;\n        align-items: center;\n        justify-content: center;\n        box-sizing: border-box;\n        width: 42rpx;\n        height: 42rpx;\n        color: transparent;\n        text-align: center;\n        transition-property: color, border-color, background-color;\n        font-size: 20px;\n        border: 1px solid var(--u-border-color);\n        transition-duration: 0.2s;\n\n        /* #ifdef MP-TOUTIAO */\n        // 头条小程序兼容性问题，需要设置行高为0，否则图标偏下\n        &__icon {\n            line-height: 0;\n        }\n        /* #endif */\n\n        &--circle {\n            border-radius: 100%;\n        }\n\n        &--square {\n            border-radius: 3px;\n        }\n\n        &--checked {\n            color: var(--u-white-color);\n            background-color: $u-type-primary;\n            border-color: $u-type-primary;\n        }\n\n        &--disabled {\n            background-color: var(--u-bg-gray-light);\n            border-color: var(--u-border-color);\n        }\n\n        &--disabled--checked {\n            color: var(--u-bg-gray-light) !important;\n        }\n    }\n\n    &__label {\n        word-wrap: break-word;\n        margin-left: 10rpx;\n        margin-right: 24rpx;\n        color: $u-content-color;\n        font-size: 30rpx;\n\n        &--disabled {\n            color: var(--u-bg-gray-light);\n        }\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-radio-group/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { Shape } from '../../types/global';\nimport { getColor } from '../../';\n\n/**\n * RadioGroupProps 单选框组 props 类型定义\n * @description 单选框用于有一个选择，用户只能选择其中一个的场景。搭配u-radio使用\n */\nexport const RadioGroupProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 是否禁用所有单选框 */\n    disabled: { type: Boolean, default: false },\n    /** 匹配某一个radio组件，如果某个radio的name值等于此值，那么这个radio就被会选中 */\n    modelValue: { type: [String, Number] as PropType<string | number>, default: '' },\n    /** 选中状态下的颜色 */\n    activeColor: { type: String, default: () => getColor('primary') },\n    /** 组件的整体大小 */\n    size: { type: [String, Number] as PropType<number | string>, default: '' },\n    /** 是否禁止点击提示语选中复选框 */\n    labelDisabled: { type: Boolean, default: false },\n    /** 形状，square为方形，circle为原型 */\n    shape: { type: String as PropType<Shape>, default: 'circle' },\n    /** 图标的大小，单位rpx */\n    iconSize: { type: [String, Number] as PropType<number | string>, default: '' },\n    /** 每个checkbox占u-checkbox-group的宽度 */\n    width: { type: [String, Number] as PropType<number | string>, default: 'auto' },\n    /** 是否每个checkbox都换行 */\n    wrap: { type: Boolean, default: false }\n};\n\nexport type RadioGroupProps = ExtractPropTypes<typeof RadioGroupProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-radio-group/u-radio-group.vue",
    "content": "<template>\n    <view class=\"u-radio-group u-clearfix\" :style=\"$u.toStyle(customStyle)\" :class=\"customClass\">\n        <slot></slot>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-radio-group',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { $u, useParent, useChildren } from '../..';\nimport { RadioGroupProps } from './types';\n\n/**\n * radioGroup 单选框父组件\n * @description 单选框用于有一个选择，用户只能选择其中一个的场景。搭配u-radio使用\n * @tutorial https://uviewpro.cn/zh/components/radio.html\n * @property {Boolean} disabled 是否禁用所有radio（默认false）\n * @property {String|Number} size 组件整体的大小，单位rpx（默认40）\n * @property {String} active-color 选中时的颜色，应用到所有子Radio组件（默认主题色primary）\n * @property {String|Number} icon-size 图标大小，单位rpx（默认20）\n * @property {String} shape 外观形状，shape-方形，circle-圆形(默认circle)\n * @property {Boolean} label-disabled 是否禁止点击文本操作checkbox(默认false)\n * @property {String|Number} width 宽度，需带单位\n * @property {Boolean} wrap 是否每个radio都换行（默认false）\n * @event {Function} change 任一个radio状态发生变化时触发\n * @example <u-radio-group v-model=\"value\"></u-radio-group>\n */\n\nconst props = defineProps(RadioGroupProps);\n\nconst emit = defineEmits(['update:modelValue', 'change']);\n\nconst { emitToParent } = useChildren('u-radio-group', 'u-form-item');\nuseParent('u-radio-group');\n\n/**\n * 父组件数据，供子组件使用\n */\nfunction getData() {\n    return {\n        iconSize: props.iconSize,\n        labelDisabled: props.labelDisabled,\n        disabled: props.disabled,\n        shape: props.shape,\n        activeColor: props.activeColor,\n        size: props.size,\n        width: props.width,\n        wrap: props.wrap,\n        value: props.modelValue\n    };\n}\n\n/**\n * 设置选中值\n * @param val 选中的 radio 的 value 值\n */\nfunction setValue(val: string | number) {\n    // 通过emit事件，设置父组件通过v-model双向绑定的值\n    emit('update:modelValue', val);\n    emit('change', val);\n    // 等待下一个周期再执行，因为emit作用于父组件，再反馈到子组件内部，需要时间\n    // 由于头条小程序执行迟钝，故需要用几十毫秒的延时\n    setTimeout(() => {\n        // 将当前的值发送到 u-form-item 进行校验\n        emitToParent('onFormChange', val);\n    }, 60);\n}\n\ndefineExpose({\n    props,\n    getData,\n    setValue\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-radio-group {\n    /* #ifndef MP || APP-NVUE */\n    display: inline-flex;\n    flex-wrap: wrap;\n    /* #endif */\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-rate/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\n/**\n * RateProps 评分组件 props 类型定义\n * @description 满意度调查、星型评分场景\n */\nexport const RateProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** v-model双向绑定选中的星星数量 */\n    modelValue: { type: [Number, String] as PropType<number | string>, default: -1 },\n    /** 要显示的星星数量 */\n    count: { type: [Number, String] as PropType<number | string>, default: 5 },\n    /** 当前需要默认选中的星星(选中的个数) */\n    current: { type: [Number, String] as PropType<number | string>, default: 0 },\n    /** 是否不可选中 */\n    disabled: { type: Boolean, default: false },\n    /** 星星的大小，单位rpx */\n    size: { type: [Number, String] as PropType<number | string>, default: 32 },\n    /** 未选中时的颜色 */\n    inactiveColor: { type: String, default: 'var(--u-light-color)' },\n    /** 选中的颜色 */\n    activeColor: { type: String, default: 'var(--u-type-error)' },\n    /** 星星之间的间距，单位rpx */\n    gutter: { type: [Number, String] as PropType<number | string>, default: 10 },\n    /** 最少能选择的星星个数 */\n    minCount: { type: [Number, String] as PropType<number | string>, default: 0 },\n    /** 是否允许半星 */\n    allowHalf: { type: Boolean, default: false },\n    /** 选中时的图标(星星) */\n    activeIcon: { type: String, default: 'star-fill' },\n    /** 未选中时的图标(星星) */\n    inactiveIcon: { type: String, default: 'star' },\n    /** 自定义扩展前缀，方便用户扩展自己的图标库 */\n    customPrefix: { type: String, default: 'uicon' },\n    /** 分段颜色 */\n    colors: { type: Array as PropType<string[]>, default: () => [] },\n    /** 分段图标 */\n    icons: { type: Array as PropType<string[]>, default: () => [] }\n};\n\nexport type RateProps = ExtractPropTypes<typeof RateProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-rate/u-rate.vue",
    "content": "<template>\n    <view\n        class=\"u-rate\"\n        :class=\"customClass\"\n        :style=\"$u.toStyle(customStyle)\"\n        :id=\"elId\"\n        @touchmove.stop.prevent=\"touchMove\"\n    >\n        <view class=\"u-star-wrap\" v-for=\"(item, index) in count\" :key=\"index\" :class=\"[elClass]\">\n            <u-icon\n                :name=\"String(Number(activeIndex) > Number(index) ? elActiveIcon : inactiveIcon)\"\n                @click=\"click(Number(index) + 1, $event)\"\n                :color=\"String(Number(activeIndex) > Number(index) ? elActiveColor : inactiveColor)\"\n                :custom-style=\"{\n                    fontSize: size + 'rpx',\n                    padding: `0 ${Number(gutter) / 2 + 'rpx'}`\n                }\"\n                :custom-prefix=\"customPrefix\"\n                :show-decimal-icon=\"showDecimalIcon(Number(index))\"\n                :percent=\"decimal\"\n                :inactive-color=\"inactiveColor\"\n            ></u-icon>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-rate',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, onMounted, getCurrentInstance } from 'vue';\nimport { $u } from '../..';\nimport { RateProps } from './types';\n\n/**\n * rate 评分\n * @description 该组件一般用于满意度调查，星型评分的场景\n * @tutorial https://uviewpro.cn/zh/components/rate.html\n * @property {String|Number} count 最多可选的星星数量（默认5）\n * @property {String|Number} current 默认选中的星星数量（默认0）\n * @property {Boolean} disabled 是否禁止用户操作（默认false）\n * @property {String|Number} size 星星的大小，单位rpx（默认32）\n * @property {String} inactive-color 未选中星星的颜色（默认var(--u-light-color)）\n * @property {String} active-color 选中的星星颜色（默认var(--u-type-error)）\n * @property {String} active-icon 选中时的图标名，只能为uView的内置图标（默认star-fill）\n * @property {String} inactive-icon 未选中时的图标名，只能为uView的内置图标（默认star）\n * @property {String|Number} gutter 星星之间的距离（默认10）\n * @property {String|Number} min-count 最少选中星星的个数（默认0）\n * @property {Boolean} allow-half 是否允许半星选择（默认false）\n * @event {Function} change 选中的星星发生变化时触发\n * @example <u-rate :count=\"count\" :current=\"2\"></u-rate>\n */\nconst props = defineProps(RateProps);\n\nconst emit = defineEmits(['update:modelValue', 'change']);\nconst instance = getCurrentInstance();\n// 生成唯一id，防止页面多个评分组件冲突\nconst elId = ref($u.guid());\nconst elClass = ref($u.guid());\nconst starBoxLeft = ref(0); // 评分盒子左边到屏幕左边的距离\nconst starWidth = ref(0); // 每个星星的宽度\nconst starWidthArr = ref<number[]>([]); //每个星星最右边到组件盒子最左边的距离\n// 当前激活的星星的index，如果存在value，优先使用value，因为它可以双向绑定(1.4.5新增)\nconst activeIndex = ref(Number(props.modelValue) !== -1 ? Number(props.modelValue) : Number(props.current));\n\n// 监听props变化，保持activeIndex同步\nwatch(\n    () => props.current,\n    val => {\n        activeIndex.value = Number(val);\n    }\n);\nwatch(\n    () => props.modelValue,\n    val => {\n        activeIndex.value = Number(val);\n    }\n);\n\n/**\n * 计算当前星星的显示小数部分（半星）\n */\nconst decimal = computed((): number => {\n    if (props.disabled) {\n        // 只在允许半星时才返回小数部分，否则始终为0\n        if (props.allowHalf) {\n            // 计算当前激活星星的小数部分（如3.5星，返回50）\n            const val = Number(activeIndex.value);\n            return (val - Math.floor(val)) * 100;\n        }\n        return 0;\n    } else if (props.allowHalf) {\n        // 允许半星时，返回50，否则0\n        return 50;\n    }\n    return 0;\n});\n/**\n * 计算当前激活的图标\n */\nconst elActiveIcon = computed(() => {\n    const len = props.icons.length;\n    // 此处规则类似于下方的elActiveColor参数，都是根据一定的规则，显示不同的图标\n    // 结果可能如此：icons参数传递了3个图标，当选中两个时，用第一个图标，4个时，用第二个图标\n    // 第三个时，用第三个图标作为激活的图标\n    if (len && len <= Number(props.count)) {\n        const step = Math.round(Number(activeIndex.value) / Math.round(Number(props.count) / len));\n        if (step < 1) return props.icons[0];\n        if (step > len) return props.icons[len - 1];\n        return props.icons[step - 1];\n    }\n    return props.activeIcon;\n});\n/**\n * 计算当前激活的颜色\n */\nconst elActiveColor = computed(() => {\n    const len = props.colors.length;\n    // 如果有设置colors参数(此参数用于将图标分段，比如一共5颗星，colors传3个颜色值，那么根据一定的规则，2颗星可能为第一个颜色\n    // 4颗星为第二个颜色值，5颗星为第三个颜色值)\n    if (len && len <= Number(props.count)) {\n        const step = Math.round(Number(activeIndex.value) / Math.round(Number(props.count) / len));\n        if (step < 1) return props.colors[0];\n        if (step > len) return props.colors[len - 1];\n        return props.colors[step - 1];\n    }\n    return props.activeColor;\n});\n\n/**\n * 获取评分组件盒子的布局信息\n */\nfunction getElRectById() {\n    // uView封装的获取节点的方法，详见文档\n    $u.getRect('#' + elId.value, instance).then((res: any) => {\n        starBoxLeft.value = res.left;\n    });\n}\n/**\n * 获取单个星星的尺寸\n */\nfunction getElRectByClass() {\n    // uView封装的获取节点的方法，详见文档\n    $u.getRect('.' + elClass.value, instance).then((res: any) => {\n        starWidth.value = res.width;\n        // 把每个星星右边到组件盒子左边的距离放入数组中\n        for (let i = 0; i < Number(props.count); i++) {\n            starWidthArr.value[i] = (i + 1) * starWidth.value;\n        }\n    });\n}\n/**\n * 手指滑动评分\n */\nfunction touchMove(e: any) {\n    if (props.disabled) {\n        return;\n    }\n    if (!e.changedTouches[0]) {\n        return;\n    }\n    const movePageX = e.changedTouches[0].pageX;\n    // 滑动点相对于评分盒子左边的距离\n    const distance = movePageX - starBoxLeft.value;\n    // 如果滑动到了评分盒子的左边界，就设置为0星\n    if (distance <= 0) {\n        activeIndex.value = 0;\n    }\n    // 滑动的距离，相当于多少颗星星\n    let index = Math.ceil(distance / starWidth.value);\n    activeIndex.value = index > Number(props.count) ? Number(props.count) : index;\n    // 对最少颗星星的限制\n    if (activeIndex.value < Number(props.minCount)) activeIndex.value = Number(props.minCount);\n    emitEvent();\n}\n/**\n * 通过点击，直接选中\n */\nfunction click(index: number, e: any) {\n    if (props.disabled) {\n        return;\n    }\n    // 半星选择，尚未实现\n    if (props.allowHalf) {\n        // 预留半星实现\n    }\n    // 对第一个星星特殊处理，只有一个的时候，点击可以取消，否则无法作0星评价\n    if (index == 1) {\n        if (activeIndex.value == 1) {\n            activeIndex.value = 0;\n        } else {\n            activeIndex.value = 1;\n        }\n    } else {\n        activeIndex.value = index;\n    }\n    // 对最少颗星星的限制\n    if (activeIndex.value < Number(props.minCount)) activeIndex.value = Number(props.minCount);\n    emitEvent();\n}\n/**\n * 发出事件\n */\nfunction emitEvent() {\n    // 发出change事件\n    emit('change', activeIndex.value);\n    // 同时修改双向绑定的value的值\n    if (Number(props.modelValue) !== -1) {\n        emit('update:modelValue', activeIndex.value);\n    }\n}\n/**\n * 是否显示半星图标\n */\nfunction showDecimalIcon(index: number) {\n    return props.disabled && parseInt(String(activeIndex.value)) === index;\n}\n\nonMounted(() => {\n    getElRectById();\n    getElRectByClass();\n});\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n\n.u-rate {\n    display: -webkit-inline-flex;\n    display: inline-flex;\n    align-items: center;\n    margin: 0;\n    padding: 0;\n}\n\n.u-icon {\n    box-sizing: border-box;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-read-more/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport { getColor, useLocale } from '../../';\n\nconst { t } = useLocale();\n\n/**\n * ReadMoreProps 阅读更多 props 类型定义\n * @description 内容较长时收起/展开的场景\n */\nexport const ReadMoreProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 默认的显示占位高度，单位为rpx */\n    showHeight: { type: [Number, String] as PropType<number | string>, default: 400 },\n    /** 展开后是否显示\"收起\"按钮 */\n    toggle: { type: Boolean, default: false },\n    /** 关闭时的提示文字 */\n    closeText: { type: String, default: () => t('uReadMore.closeText') },\n    /** 展开时的提示文字 */\n    openText: { type: String, default: () => t('uReadMore.openText') },\n    /** 提示的文字颜色 */\n    color: { type: String, default: () => getColor('primary') },\n    /** 提示文字的大小 */\n    fontSize: { type: [String, Number] as PropType<number | string>, default: 28 },\n    /** 是否显示阴影 */\n    shadowStyle: {\n        type: Object as PropType<Record<string, any>>,\n        default: () => ({\n            backgroundImage: 'linear-gradient(-180deg, rgba(255, 255, 255, 0) 0%, var(--u-bg-white) 80%)',\n            paddingTop: '300rpx',\n            marginTop: '-300rpx'\n        })\n    },\n    /** 段落首行缩进的字符个数 */\n    textIndent: { type: String, default: '2em' },\n    /** open和close事件时，将此参数返回在回调参数中 */\n    index: { type: [Number, String] as PropType<number | string>, default: '' }\n};\n\nexport type ReadMoreProps = ExtractPropTypes<typeof ReadMoreProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-read-more/u-read-more.vue",
    "content": "<template>\n    <view>\n        <view\n            class=\"u-content\"\n            :class=\"[elId, customClass]\"\n            :style=\"\n                $u.toStyle(\n                    {\n                        height: isLongContent && !showMore ? showHeight + 'rpx' : 'auto',\n                        textIndent: textIndent\n                    },\n                    customStyle\n                )\n            \"\n        >\n            <slot></slot>\n        </view>\n        <view\n            @tap=\"toggleReadMore\"\n            v-if=\"isLongContent\"\n            class=\"u-content__showmore-wrap\"\n            :class=\"{ 'u-content__show-more': showMore }\"\n            :style=\"[innerShadowStyle]\"\n        >\n            <text\n                class=\"u-content__showmore-wrap__readmore-btn\"\n                :style=\"{\n                    fontSize: fontSize + 'rpx',\n                    color: color\n                }\"\n            >\n                {{ showMore ? openText : closeText }}\n            </text>\n            <view class=\"u-content__showmore-wrap__readmore-btn__icon u-flex\">\n                <u-icon :color=\"color\" :size=\"fontSize\" :name=\"showMore ? 'arrow-up' : 'arrow-down'\"></u-icon>\n            </view>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-read-more',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, onMounted, nextTick, getCurrentInstance } from 'vue';\nimport { $u } from '../..';\nimport { ReadMoreProps } from './types';\n\n/**\n * readMore 阅读更多\n * @description 该组件一般用于内容较长，预先收起一部分，点击展开全部内容的场景。\n * @tutorial https://uviewpro.cn/zh/components/readMore.html\n * @property {String|Number} showHeight 内容超出此高度才会显示展开全文按钮，单位rpx（默认400）\n * @property {Boolean} toggle 展开后是否显示收起按钮（默认false）\n * @property {String} closeText 关闭时的提示文字（默认“展开阅读全文”）\n * @property {String|Number} fontSize 提示文字的大小，单位rpx（默认28）\n * @property {String} textIndent 段落首行缩进的字符个数（默认2em）\n * @property {String} openText 展开时的提示文字（默认“收起”）\n * @property {String} color 提示文字的颜色（默认主题色primary）\n * @property {Object} shadowStyle 是否显示阴影，样式对象\n * @property {String|Number} index open和close事件时，将此参数返回在回调参数中\n * @event open 展开时触发\n * @event close 收起时触发\n * @example <u-read-more><rich-text :nodes=\"content\"></rich-text></u-read-more>\n */\n\nconst props = defineProps(ReadMoreProps);\n\nconst emit = defineEmits(['open', 'close']);\n\n// 是否需要隐藏一部分内容\nconst isLongContent = ref(false);\n// 当前隐藏与显示的状态，true-显示，false-收起\nconst showMore = ref(false);\n// 生成唯一class\nconst elId = ref('');\nconst instance = getCurrentInstance();\n\n// 展开后无需阴影，收起时才需要阴影样式\nconst innerShadowStyle = computed(() => {\n    return showMore.value ? {} : props.shadowStyle;\n});\n\n// 监听 toggle 和 showHeight 变化，重新初始化\nwatch(\n    () => `${props.toggle}-${props.showHeight}`,\n    () => {\n        init();\n    }\n);\n\nonMounted(() => {\n    elId.value = $u.guid();\n    nextTick(() => {\n        init();\n    });\n});\n\n/**\n * 初始化内容高度判断\n * @description 判断内容是否超出指定高度，决定是否显示展开/收起按钮\n */\nfunction init() {\n    $u.getRect('.' + elId.value, instance).then((res: { height: number }) => {\n        // 判断高度，如果真实内容高度大于占位高度，则显示收起与展开的控制按钮\n        if (res.height > uni.upx2px(Number(props.showHeight))) {\n            isLongContent.value = true;\n            showMore.value = false;\n        }\n    });\n}\n// 显式暴露init方法\ndefineExpose({\n    init\n});\n\n/**\n * 展开或者收起内容\n * @description 切换显示状态，发出 open/close 事件\n */\nfunction toggleReadMore() {\n    showMore.value = !showMore.value;\n    // 如果toggle为false，隐藏\"收起\"部分的内容\n    if (props.toggle == false) isLongContent.value = false;\n    // 发出打开或者收齐的事件\n    emit(showMore.value ? 'open' : 'close', props.index);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-content {\n    font-size: 30rpx;\n    color: $u-content-color;\n    line-height: 1.8;\n    text-align: left;\n    overflow: hidden;\n\n    &__show-more {\n        padding-top: 0;\n        background: none;\n        margin-top: 20rpx;\n    }\n\n    &__showmore-wrap {\n        position: relative;\n        width: 100%;\n        padding-bottom: 26rpx;\n        @include vue-flex;\n        align-items: center;\n        justify-content: center;\n\n        &__readmore-btn {\n            @include vue-flex;\n            align-items: center;\n            justify-content: center;\n            line-height: 1;\n\n            &__icon {\n                margin-left: 14rpx;\n            }\n        }\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-root-portal/u-root-portal.vue",
    "content": "<template>\n    <!-- #ifdef H5 -->\n    <teleport to=\"body\">\n        <!-- #endif -->\n        <!-- #ifdef MP-WEIXIN || MP-ALIPAY -->\n        <!-- #ifndef MP-DINGTALK -->\n        <root-portal>\n            <!-- #endif -->\n            <!-- #endif -->\n            <slot />\n            <!-- #ifdef MP-WEIXIN || MP-ALIPAY -->\n            <!-- #ifndef MP-DINGTALK -->\n        </root-portal>\n        <!-- #endif -->\n        <!-- #endif -->\n        <!-- #ifdef H5 -->\n    </teleport>\n    <!-- #endif -->\n</template>\n<script>\n/**\n * rootPortal 根节点传送\n * @description 该组件一般用于使整个子树从页面中脱离出来，类似于在 CSS 中使用 fixed position 的效果。主要用于制作弹窗、弹出层等。\n * @tutorial https://uviewpro.cn/zh/components/rootPortal.html\n * @example <u-root-portal><view class=\"modal\">这是一个全局弹窗</view></u-root-portal>\n */\nexport default {\n    name: 'u-root-portal',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n<script lang=\"ts\" setup></script>\n\n<!-- #ifdef APP-PLUS -->\n<script module=\"render\" lang=\"renderjs\">\nexport default {\n  mounted() {\n    if (this.$ownerInstance.$el) {\n      (document.querySelector('uni-app') || document.body).appendChild(this.$ownerInstance.$el)\n    }\n  },\n  beforeDestroy() {\n    if (this.$ownerInstance.$el) {\n      (document.querySelector('uni-app') || document.body).removeChild(this.$ownerInstance.$el)\n    }\n  }\n}\n</script>\n<!-- #endif -->\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-row/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { RowAlign, RowJustify } from '../../types/global';\n\n/**\n * RowProps 行布局 props 类型定义\n * @description 12分栏布局，快速创建布局\n */\n\nexport const RowProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 给col添加间距，左右边距各占一半 */\n    gutter: { type: [String, Number] as PropType<number | string>, default: 20 },\n    /** 水平排列方式，可选值为`start`(或`flex-start`)、`end`(或`flex-end`)、`center`、`around`(或`space-around`)、`between`(或`space-between`) */\n    justify: { type: String as PropType<RowJustify>, default: 'start' },\n    /** 垂直对齐方式，可选值为top、center、bottom */\n    align: { type: String as PropType<RowAlign>, default: 'center' },\n    /** 是否阻止事件传播 */\n    stop: { type: Boolean, default: true }\n};\n\nexport type RowProps = ExtractPropTypes<typeof RowProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-row/u-row.vue",
    "content": "<template>\n    <view\n        class=\"u-row\"\n        :style=\"\n            $u.toStyle(\n                {\n                    alignItems: uAlignItem,\n                    justifyContent: uJustify\n                },\n                customStyle\n            )\n        \"\n        @tap=\"onClick\"\n    >\n        <slot />\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-row',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { RowProps } from './types';\nimport { $u, useParent } from '../../';\n\n/**\n * row 行布局\n * @description 通过基础的 12 分栏，迅速简便地创建布局。\n * @tutorial https://uviewpro.cn/zh/components/layout.html#row-props\n * @property {String|Number} gutter 栅格间隔，左右各为此值的一半，单位rpx（默认0）\n * @property {String} justify 水平排列方式(微信小程序暂不支持)默认（start(或flex-start)）\n * @property {String} align 垂直排列方式（默认center）\n * @example <u-row gutter=\"16\"></u-row>\n */\n\nconst emit = defineEmits<{ (e: 'click'): void }>();\n\nconst props = defineProps(RowProps);\n\nuseParent('u-row');\n\n/**\n * 计算水平排列方式\n * @returns {string}\n */\nconst uJustify = computed(() => {\n    if (props.justify === 'end' || props.justify === 'start') return 'flex-' + props.justify;\n    else if (props.justify === 'around' || props.justify === 'between') return 'space-' + props.justify;\n    else return props.justify;\n});\n\n/**\n * 计算垂直对齐方式\n * @returns {string}\n */\nconst uAlignItem = computed(() => {\n    if (props.align === 'top') return 'flex-start';\n    if (props.align === 'bottom') return 'flex-end';\n    else return props.align;\n});\n\n/**\n * 点击事件\n * @param e 事件对象\n */\nfunction onClick(e: Event) {\n    // 触发 click 事件\n    emit('click');\n}\n\ndefineExpose({\n    props\n});\n</script>\n\n<style lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n\n.u-row {\n    // 由于微信小程序编译后奇怪的页面结构，只能使用float布局实现，flex无法实现\n    /* #ifndef MP-WEIXIN || MP-QQ || MP-TOUTIAO */\n    @include vue-flex;\n    /* #endif */\n    flex-wrap: wrap;\n}\n\n.u-row:after {\n    /* #ifdef MP-WEIXIN || MP-QQ || MP-TOUTIAO */\n    display: table;\n    clear: both;\n    content: '';\n    /* #endif */\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-row-notice/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { PlayState, ThemeType } from '../../types/global';\n\n/**\n * RowNoticeProps 水平滚动通告栏 props 类型定义\n * @description 水平滚动通告栏，支持主题、图标、关闭等\n */\nexport const RowNoticeProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 显示的内容，数组 */\n    list: { type: Array as PropType<string[]>, default: () => [] },\n    /** 显示的主题，success|error|primary|info|warning|none */\n    type: { type: String as PropType<ThemeType | 'none'>, default: 'warning' },\n    /** 是否显示左侧的音量图标 */\n    volumeIcon: { type: Boolean, default: true },\n    /** 是否显示右侧的右箭头图标 */\n    moreIcon: { type: Boolean, default: false },\n    /** 是否显示右侧的关闭图标 */\n    closeIcon: { type: Boolean, default: false },\n    /** 是否自动播放 */\n    autoplay: { type: Boolean, default: true },\n    /** 文字颜色，各图标也会使用文字颜色 */\n    color: { type: String, default: '' },\n    /** 背景颜色 */\n    bgColor: { type: String, default: '' },\n    /** 是否显示 */\n    show: { type: Boolean, default: true },\n    /** 字体大小，单位rpx */\n    fontSize: { type: [Number, String] as PropType<number | string>, default: 26 },\n    /** 音量喇叭的大小 */\n    volumeSize: { type: [Number, String] as PropType<number | string>, default: 34 },\n    /** 水平滚动时的滚动速度，即每秒滚动多少rpx */\n    speed: { type: [Number, String] as PropType<number | string>, default: 160 },\n    /** 播放状态，play-播放，paused-暂停 */\n    playState: { type: String as PropType<PlayState>, default: 'play' },\n    /** 通知的边距 */\n    padding: { type: [Number, String] as PropType<number | string>, default: '18rpx 24rpx' }\n};\n\nexport type RowNoticeProps = ExtractPropTypes<typeof RowNoticeProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-row-notice/u-row-notice.vue",
    "content": "<template>\n    <view\n        v-if=\"props.show\"\n        class=\"u-notice-bar\"\n        :style=\"$u.toStyle({ background: computeBgColor, padding: props.padding }, customStyle)\"\n        :class=\"[props.type ? `u-type-${props.type}-light-bg` : '', customClass]\"\n    >\n        <view class=\"u-direction-row\">\n            <view class=\"u-icon-wrap\">\n                <u-icon\n                    class=\"u-left-icon\"\n                    v-if=\"props.volumeIcon\"\n                    name=\"volume-fill\"\n                    :size=\"props.volumeSize\"\n                    :color=\"computeColor\"\n                ></u-icon>\n            </view>\n            <view class=\"u-notice-box\" id=\"u-notice-box\">\n                <view\n                    class=\"u-notice-content\"\n                    id=\"u-notice-content\"\n                    :style=\"{ animationDuration: animationDuration, animationPlayState: animationPlayState }\"\n                >\n                    <text class=\"u-notice-text\" @tap=\"click\" :style=\"textStyle\" :class=\"['u-type-' + props.type]\">\n                        {{ showText }}\n                    </text>\n                </view>\n            </view>\n            <view class=\"u-icon-wrap\">\n                <u-icon\n                    @click=\"getMore\"\n                    class=\"u-right-icon\"\n                    v-if=\"props.moreIcon\"\n                    name=\"arrow-right\"\n                    :size=\"26\"\n                    :color=\"computeColor\"\n                ></u-icon>\n                <u-icon\n                    @click=\"close\"\n                    class=\"u-right-icon\"\n                    v-if=\"props.closeIcon\"\n                    name=\"close\"\n                    :size=\"24\"\n                    :color=\"computeColor\"\n                ></u-icon>\n            </view>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-row-notice',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, onMounted, nextTick, getCurrentInstance } from 'vue';\nimport { RowNoticeProps } from './types';\nimport { $u } from '../..';\n\n/**\n * u-row-notice 水平滚动通告栏\n * @property {Array} list 显示的内容，数组\n * @property {String} type 显示的主题，success|error|primary|info|warning|none\n * @property {Boolean} volumeIcon 是否显示左侧的音量图标\n * @property {Boolean} moreIcon 是否显示右侧的右箭头图标\n * @property {Boolean} closeIcon 是否显示右侧的关闭图标\n * @property {Boolean} autoplay 是否自动播放\n * @property {String} color 文字颜色，各图标也会使用文字颜色\n * @property {String} bgColor 背景颜色\n * @property {Boolean} show 是否显示\n * @property {String|Number} fontSize 字体大小，单位rpx\n * @property {String|Number} volumeSize 音量喇叭的大小\n * @property {String|Number} speed 水平滚动时的滚动速度，即每秒滚动多少rpx\n * @property {String} playState 播放状态，play-播放，paused-暂停\n * @property {String|Number} padding 通知的边距\n */\n\nconst props = defineProps(RowNoticeProps);\n\nconst emit = defineEmits<{ (e: 'click'): void; (e: 'close'): void; (e: 'getMore'): void }>();\nconst instance = getCurrentInstance();\nconst textWidth = ref(0); // 滚动的文字宽度\nconst animationDuration = ref('10s'); // 动画执行时间\nconst animationPlayState = ref('paused'); // 动画的开始和结束执行\nconst showText = ref(''); // 显示的文本\n\n/**\n * 计算字体颜色，如果没有自定义的，就用uview主题颜色\n */\nconst computeColor = computed(() => {\n    if (props.color) return props.color;\n    // 如果是无主题，就默认使用content-color\n    else if (props.type === 'none') return 'var(--u-content-color)';\n    else return props.type;\n});\n\n/**\n * 文字内容的样式\n */\nconst textStyle = computed(() => {\n    const style: Record<string, any> = {};\n    if (props.color) style.color = props.color;\n    else if (props.type === 'none') style.color = 'var(--u-content-color)';\n    style.fontSize = props.fontSize + 'rpx';\n    return style;\n});\n\n/**\n * 计算背景颜色\n */\nconst computeBgColor = computed(() => {\n    if (props.bgColor) return props.bgColor;\n    else if (props.type === 'none') return 'transparent';\n    else return '';\n});\n\n/**\n * 初始化滚动宽度和动画\n */\nfunction initSize() {\n    nextTick(() => {\n        uni.createSelectorQuery()\n            .in(instance?.proxy)\n            .select('#u-notice-content')\n            .boundingClientRect()\n            .exec(ret => {\n                textWidth.value = ret[0]?.width || 0;\n                // 根据t=s/v(时间=路程/速度)，这里为何不需要加上#u-notice-box的宽度，因为中设置了.u-notice-content样式中设置了padding-left: 100%\n                // 恰巧计算出来的结果中已经包含了#u-notice-box的宽度\n                animationDuration.value = `${textWidth.value / uni.upx2px(Number(props.speed))}s`;\n                // 这里必须这样开始动画，否则在APP上动画速度不会改变(HX版本2.4.6，IOS13)\n                animationPlayState.value = 'paused';\n                setTimeout(() => {\n                    if (props.playState === 'play' && props.autoplay) animationPlayState.value = 'running';\n                }, 10);\n            });\n    });\n}\n\nwatch(\n    () => props.list,\n    val => {\n        showText.value = val.join('，');\n        initSize();\n    },\n    { immediate: true }\n);\n\nwatch(\n    () => props.playState,\n    val => {\n        animationPlayState.value = val === 'play' ? 'running' : 'paused';\n    }\n);\n\nwatch(\n    () => props.speed,\n    () => {\n        initSize();\n    }\n);\n\nonMounted(() => {\n    initSize();\n});\n\n/**\n * 点击通告栏\n */\nfunction click() {\n    emit('click');\n}\n\n/**\n * 点击关闭按钮\n */\nfunction close() {\n    emit('close');\n}\n\n/**\n * 点击更多箭头按钮\n */\nfunction getMore() {\n    emit('getMore');\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-notice-bar {\n    padding: 18rpx 24rpx;\n    overflow: hidden;\n}\n\n.u-direction-row {\n    @include vue-flex;\n    align-items: center;\n    justify-content: space-between;\n}\n\n.u-left-icon {\n    /* #ifndef APP-NVUE */\n    display: inline-flex;\n    /* #endif */\n    align-items: center;\n}\n\n.u-notice-box {\n    flex: 1;\n    @include vue-flex;\n    overflow: hidden;\n    margin-left: 12rpx;\n}\n\n.u-right-icon {\n    margin-left: 12rpx;\n    display: inline-flex;\n    align-items: center;\n}\n\n.u-notice-content {\n    animation: u-loop-animation 10s linear infinite both;\n    text-align: right;\n    // 这一句很重要，为了能让滚动左右连接起来\n    padding-left: 100%;\n    @include vue-flex;\n    flex-wrap: nowrap;\n}\n\n.u-notice-text {\n    font-size: 26rpx;\n    word-break: keep-all;\n    white-space: nowrap;\n}\n\n@keyframes u-loop-animation {\n    0% {\n        transform: translate3d(0, 0, 0);\n    }\n\n    100% {\n        transform: translate3d(-100%, 0, 0);\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-safe-bottom/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\n/**\n * SafeBottomProps SafeBottom 底部安全区\n */\nexport const SafeBottomProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    }\n};\n\nexport type SafeBottomProps = ExtractPropTypes<typeof SafeBottomProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-safe-bottom/u-safe-bottom.vue",
    "content": "<template>\n    <view\n        class=\"u-safe-bottom\"\n        :style=\"$u.toStyle(style, customStyle)\"\n        :class=\"[!isNVue && 'safe-area-inset-bottom', customClass]\"\n    ></view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-safe-bottom',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted, type CSSProperties } from 'vue';\nimport { SafeBottomProps } from './types';\nimport { $u } from '../../';\n\n/**\n * SafeBottom 底部安全区\n * @description 这个适配，主要是针对IPhone X等一些底部带指示条的机型，指示条的操作区域与页面底部存在重合，容易导致用户误操作，因此我们需要针对这些机型进行底部安全区适配。\n * @property {String | Object} customStyle 自定义样式\n * @example <u-safe-bottom></u-safe-bottom>\n */\nconst props = defineProps(SafeBottomProps);\n\nconst isNVue = ref(false);\n\nconst style = computed(() => {\n    let result: CSSProperties = {};\n    // #ifdef APP-NVUE || MP-TOUTIAO\n    // nvue下，高度使用js计算填充\n    const safeAreaInsets = $u.sys()?.safeAreaInsets;\n    if (safeAreaInsets?.bottom) {\n        result.height = $u.addUnit(safeAreaInsets.bottom, 'px');\n    }\n    // #endif\n    return result;\n});\n\nonMounted(() => {\n    // #ifdef APP-NVUE\n    // 标识为是否nvue\n    isNVue.value = true;\n    // #endif\n});\n</script>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-search/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { InputAlign, SearchShape } from '../../types/global';\nimport { useLocale } from '../../';\n\nconst { t } = useLocale();\n\n/**\n * SearchProps 搜索框 props 类型定义\n * @description 集成常见搜索框功能，开箱即用\n */\nexport const SearchProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 搜索框形状，round-圆形，square-方形 */\n    shape: { type: String as PropType<SearchShape>, default: 'round' },\n    /** 搜索框背景色，默认值var(--u-bg-gray-light) */\n    bgColor: { type: String, default: 'var(--u-bg-gray-light)' },\n    /** 占位提示文字 */\n    placeholder: { type: String, default: () => t('uSearch.placeholder') },\n    /** 是否启用清除控件 */\n    clearabled: { type: Boolean, default: true },\n    /** 是否自动聚焦 */\n    focus: { type: Boolean, default: false },\n    /** 是否在搜索框右侧显示取消按钮 */\n    showAction: { type: Boolean, default: true },\n    /** 右边控件的样式 */\n    actionStyle: { type: Object as PropType<Record<string, any>>, default: () => ({}) },\n    /** 取消按钮文字 */\n    actionText: { type: String, default: () => t('uSearch.actionText') },\n    /** 输入框内容对齐方式，可选值为 left|center|right */\n    inputAlign: { type: String as PropType<InputAlign>, default: 'left' },\n    /** 是否启用输入框 */\n    disabled: { type: Boolean, default: false },\n    /** 开启showAction时，是否在input获取焦点时才显示 */\n    animation: { type: Boolean, default: false },\n    /** 边框颜色，只要配置了颜色，才会有边框 */\n    borderColor: { type: String, default: 'none' },\n    /** 输入框的初始化内容 */\n    modelValue: { type: String, default: '' },\n    /** 搜索框高度，单位rpx */\n    height: { type: [Number, String] as PropType<number | string>, default: 64 },\n    /** input输入框的样式，可以定义文字颜色，大小等，对象形式 */\n    inputStyle: { type: Object as PropType<Record<string, any>>, default: () => ({}) },\n    /** 输入框最大能输入的长度，-1为不限制长度(来自uniapp文档) */\n    maxlength: { type: [Number, String] as PropType<number | string>, default: '-1' },\n    /** 搜索图标的颜色，默认同输入框字体颜色 */\n    searchIconColor: { type: String, default: '' },\n    /** 输入框字体颜色 */\n    color: { type: String, default: 'var(--u-content-color)' },\n    /** placeholder的颜色 */\n    placeholderColor: { type: String, default: 'var(--u-tips-color)' },\n    /** 组件与其他上下左右元素之间的距离，带单位的字符串形式，如\"30rpx\"、\"30rpx 20rpx\"等写法 */\n    margin: { type: String, default: '0' },\n    /** 左边输入框的图标，可以为uView图标名称或图片路径 */\n    searchIcon: { type: String, default: 'search' },\n    /** 弹出键盘时是否自动调节高度，uni-app默认值是true */\n    adjustPosition: { type: Boolean, default: true }\n};\n\nexport type SearchProps = ExtractPropTypes<typeof SearchProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-search/u-search.vue",
    "content": "<template>\n    <view\n        class=\"u-search\"\n        @tap=\"clickHandler\"\n        :class=\"customClass\"\n        :style=\"$u.toStyle({ margin: margin }, customStyle)\"\n    >\n        <view\n            class=\"u-content\"\n            :style=\"{\n                backgroundColor: bgColor,\n                borderRadius: shape == 'round' ? '100rpx' : '10rpx',\n                border: borderStyle,\n                height: height + 'rpx'\n            }\"\n        >\n            <view class=\"u-icon-wrap\">\n                <u-icon\n                    class=\"u-clear-icon\"\n                    :size=\"30\"\n                    :name=\"searchIcon\"\n                    :color=\"searchIconColor ? searchIconColor : color\"\n                ></u-icon>\n            </view>\n            <input\n                confirm-type=\"search\"\n                @blur=\"blur\"\n                :value=\"modelValue\"\n                @confirm=\"search\"\n                @input=\"inputChange\"\n                @focus=\"getFocus\"\n                :focus=\"focus\"\n                :maxlength=\"Number(maxlength)\"\n                placeholder-class=\"u-placeholder-class\"\n                :placeholder=\"placeholder\"\n                :placeholder-style=\"`color: ${placeholderColor}`\"\n                :adjust-position=\"adjustPosition\"\n                class=\"u-input\"\n                type=\"text\"\n                :style=\"[\n                    {\n                        textAlign: inputAlign,\n                        color: color,\n                        backgroundColor: bgColor,\n                        pointerEvents: disabled ? 'none' : 'auto'\n                    },\n                    inputStyle\n                ]\"\n            />\n            <view class=\"u-close-wrap\" v-if=\"keyword && clearabled && focused\" @tap=\"clear\">\n                <u-icon class=\"u-clear-icon\" name=\"close-circle-fill\" size=\"34\" color=\"var(--u-light-color)\"></u-icon>\n            </view>\n        </view>\n        <view\n            :style=\"[actionStyle]\"\n            class=\"u-action\"\n            :class=\"[showActionBtn || show ? 'u-action-active' : '']\"\n            @tap.stop.prevent=\"custom\"\n        >\n            {{ actionText }}\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-search',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, nextTick } from 'vue';\nimport { SearchProps } from './types';\nimport { $u } from '../..';\n\n/**\n * search 搜索框\n * @description 搜索组件，集成了常见搜索框所需功能，用户可以一键引入，开箱即用。\n * @tutorial https://uviewpro.cn/zh/components/search.html\n * @property {String} shape 搜索框形状，round-圆形，square-方形（默认round）\n * @property {String} bg-color 搜索框背景颜色（默认var(--u-bg-gray-light)）\n * @property {String} border-color 边框颜色，配置了颜色，才会有边框\n * @property {String} placeholder 占位文字内容（默认“请输入关键字”）\n * @property {Boolean} clearabled 是否启用清除控件（默认true）\n * @property {Boolean} focus 是否自动获得焦点（默认false）\n * @property {Boolean} show-action 是否显示右侧控件（默认true）\n * @property {String} action-text 右侧控件文字（默认“搜索”）\n * @property {Object} action-style 右侧控件的样式，对象形式\n * @property {String} input-align 输入框内容水平对齐方式（默认left）\n * @property {Object} input-style 自定义输入框样式，对象形式\n * @property {Boolean} disabled 是否启用输入框（默认false）\n * @property {String} search-icon-color 搜索图标的颜色，默认同输入框字体颜色\n * @property {String} color 输入框字体颜色（默认var(--u-content-color)）\n * @property {String} placeholder-color placeholder的颜色（默认var(--u-tips-color)）\n * @property {String} search-icon 输入框左边的图标，可以为uView图标名称或图片路径\n * @property {String} margin 组件与其他上下左右元素之间的距离，带单位的字符串形式，如\"30rpx\"\n * @property {Boolean} animation 是否开启动画，见上方说明（默认false）\n * @property {String} value 输入框初始值\n * @property {String | Number} maxlength 输入框最大能输入的长度，-1为不限制长度\n * @property {Boolean} input-style input输入框的样式，可以定义文字颜色，大小等，对象形式\n * @property {String | Number} height 输入框高度，单位rpx（默认64）\n * @event {Function} change 输入框内容发生变化时触发\n * @event {Function} search 用户确定搜索时触发，用户按回车键，或者手机键盘右下角的\"搜索\"键时触发\n * @event {Function} custom 用户点击右侧控件时触发\n * @event {Function} clear 用户点击清除按钮时触发\n * @example <u-search placeholder=\"日照香炉生紫烟\" v-model=\"keyword\"></u-search>\n */\n\nconst props = defineProps(SearchProps);\n\nconst emit = defineEmits([\n    'update:modelValue',\n    'input',\n    'change',\n    'search',\n    'custom',\n    'clear',\n    'focus',\n    'blur',\n    'click'\n]);\n\n// 绑定输入框的值\nconst keyword = ref(props.modelValue);\n// 是否显示右边的清除图标\nconst showClear = ref(false);\n// 控制右侧动画展开\nconst show = ref(false);\n// 标记input当前状态是否处于聚焦中，如果是，才会显示右侧的清除控件\nconst focused = ref(props.focus);\n\n// 监听v-model和props.value变化\nwatch(\n    () => props.modelValue,\n    nVal => {\n        keyword.value = nVal;\n    }\n);\nwatch(keyword, nVal => {\n    emit('update:modelValue', nVal);\n    emit('input', nVal);\n    emit('change', nVal);\n});\n\n/**\n * 是否显示右侧action按钮\n */\nconst showActionBtn = computed(() => {\n    if (!props.animation && props.showAction) return true;\n    else return false;\n});\n/**\n * 边框样式\n */\nconst borderStyle = computed(() => {\n    if (props.borderColor) return `1px solid ${props.borderColor}`;\n    else return 'none';\n});\n\n/**\n * 监听input事件获取输入框内容的变化\n */\nfunction inputChange(e: any) {\n    keyword.value = e.detail.value;\n}\n/**\n * 清空输入\n * 也可以作为用户通过ref形式调用清空输入框内容\n */\nfunction clear() {\n    keyword.value = '';\n    // 延后发出事件，避免在父组件监听clear事件时，value为更新前的值(不为空)\n    nextTick(() => {\n        emit('clear');\n    });\n}\n/**\n * 确定搜索\n */\nfunction search(e: any) {\n    emit('search', e.detail.value);\n    try {\n        // #ifdef H5 || MP\n        uni.hideKeyboard();\n        // #endif\n    } catch (e) {}\n}\n/**\n * 点击右边自定义按钮的事件\n */\nfunction custom() {\n    emit('custom', keyword.value);\n    try {\n        // #ifdef H5 || MP\n        uni.hideKeyboard();\n        // #endif\n    } catch (e) {}\n}\n/**\n * 获取焦点\n */\nfunction getFocus() {\n    focused.value = true;\n    // 开启右侧搜索按钮展开的动画效果\n    if (props.animation && props.showAction) show.value = true;\n    emit('focus', keyword.value);\n}\n/**\n * 失去焦点\n */\nfunction blur() {\n    // 最开始使用的是监听图标@touchstart事件，自从hx2.8.4后，此方法在微信小程序出错\n    // 这里改为监听点击事件，手点击清除图标时，同时也发生了@blur事件，导致图标消失而无法点击，这里做一个延时\n    setTimeout(() => {\n        focused.value = false;\n    }, 100);\n    show.value = false;\n    emit('blur', keyword.value);\n}\n/**\n * 点击搜索框，只有disabled=true时才发出事件，因为禁止了输入，意味着是想跳转真正的搜索页\n */\nfunction clickHandler() {\n    if (props.disabled) emit('click');\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-search {\n    @include vue-flex;\n    align-items: center;\n    flex: 1;\n}\n\n.u-content {\n    @include vue-flex;\n    align-items: center;\n    padding: 0 18rpx;\n    flex: 1;\n}\n\n.u-clear-icon {\n    @include vue-flex;\n    align-items: center;\n}\n\n.u-input {\n    flex: 1;\n    font-size: 28rpx;\n    line-height: 1;\n    margin: 0 10rpx;\n    color: $u-tips-color;\n}\n\n.u-close-wrap {\n    width: 40rpx;\n    height: 100%;\n    @include vue-flex;\n    align-items: center;\n    justify-content: center;\n    border-radius: 50%;\n}\n\n.u-placeholder-class {\n    color: $u-tips-color;\n}\n\n.u-action {\n    font-size: 28rpx;\n    color: $u-main-color;\n    width: 0;\n    overflow: hidden;\n    transition: all 0.3s;\n    white-space: nowrap;\n    text-align: center;\n}\n\n.u-action-active {\n    width: 80rpx;\n    margin-left: 10rpx;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-section/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport { useLocale } from '../../';\n\nconst { t } = useLocale();\n\n/**\n * section 组件 props 类型定义\n * @description 供 u-section 组件 props 使用\n */\nexport type FontSize = string | number;\n\nexport const SectionProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 标题信息 */\n    title: { type: String, default: '' },\n    /** 右边副标题内容 */\n    subTitle: { type: String, default: () => t('uSection.subTitle') },\n    /** 是否显示右边的内容 */\n    right: { type: Boolean, default: true },\n    /** 主标题的字体大小 */\n    fontSize: { type: [Number, String] as PropType<FontSize>, default: 28 },\n    /** 主标题是否加粗 */\n    bold: { type: Boolean, default: true },\n    /** 主标题的颜色 */\n    color: { type: String, default: 'var(--u-main-color)' },\n    /** 右边副标题的颜色 */\n    subColor: { type: String, default: 'var(--u-tips-color)' },\n    /** 是否显示左边的竖条 */\n    showLine: { type: Boolean, default: true },\n    /** 左边竖线的颜色 */\n    lineColor: { type: String, default: '' },\n    /** 是否显示右边箭头 */\n    arrow: { type: Boolean, default: true }\n};\n\nexport type SectionProps = ExtractPropTypes<typeof SectionProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-section/u-section.vue",
    "content": "<template>\n    <view class=\"u-section\">\n        <view\n            class=\"u-section__title\"\n            :style=\"\n                $u.toStyle(\n                    {\n                        fontWeight: bold ? 'bold' : 'normal',\n                        color: color,\n                        fontSize: fontSize + 'rpx',\n                        paddingLeft: showLine ? Number(fontSize) * 0.7 + 'rpx' : 0\n                    },\n                    customStyle\n                )\n            \"\n            :class=\"[\n                {\n                    'u-section--line': showLine\n                },\n                customClass\n            ]\"\n        >\n            <view class=\"u-section__title__icon-wrap u-flex\" :style=\"$u.toStyle(lineStyle)\" v-if=\"showLine\">\n                <u-icon\n                    top=\"0\"\n                    name=\"column-line\"\n                    :size=\"Number(fontSize) * 1.25\"\n                    bold\n                    :color=\"lineColor ? lineColor : color\"\n                ></u-icon>\n            </view>\n            <text class=\"u-flex u-section__title__text\">{{ title }}</text>\n        </view>\n        <view\n            class=\"u-section__right-info\"\n            v-if=\"right || $slots.right\"\n            :style=\"{\n                color: subColor\n            }\"\n            @tap=\"rightClick\"\n        >\n            <slot name=\"right\" v-if=\"$slots.right\" />\n            <template v-else>\n                {{ subTitle }}\n                <view class=\"u-section__right-info__icon-arrow u-flex\" v-if=\"arrow\">\n                    <u-icon name=\"arrow-right\" size=\"24\" :color=\"subColor\"></u-icon>\n                </view>\n            </template>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-section',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { SectionProps } from './types';\nimport { $u } from '../..';\n\n/**\n * section 查看更多\n * @description 该组件一般用于分类信息有很多，但是限于篇幅只能列出一部分，让用户通过\"查看更多\"获得更多信息的场景，实际效果见演示。\n * @tutorial https://uviewpro.cn/zh/components/section.html\n * @property {String} title 左边主标题\n * @property {String} subTitle 右边副标题（默认更多）\n * @property {Boolean} right 是否显示右边的内容（默认true）\n * @property {Boolean} showLine 是否显示左边的竖条（默认true）\n * @property {Boolean} arrow 是否显示右边箭头（默认true）\n * @property {String|Number} fontSize 主标题的字体大小（默认28）\n * @property {Boolean} bold 主标题是否加粗（默认true）\n * @property {String} color 主标题颜色（默认var(--u-main-color)）\n * @property {String} subColor 右边副标题颜色（默认var(--u-tips-color)）\n * @property {String} lineColor 左边竖线的颜色\n * @event click 组件右侧的内容被点击时触发，用于跳转\"更多\"\n * @example <u-section title=\"今日热门\" :right=\"false\"></u-section>\n */\n\nconst props = defineProps(SectionProps);\n\nconst emit = defineEmits(['click']);\n\n/**\n * 左边竖条的样式\n * @description 由于安卓和iOS的，需要稍微调整绝对定位的top值，才能让左边的竖线和右边的文字垂直居中\n */\nconst lineStyle = computed(() => {\n    let isIOS = $u.os && $u.os() === 'ios';\n    return {\n        // 由于竖线为字体图标，具有比实际线宽更宽的宽度，所以也需要根据字体打下动态调整\n        left: -(Number(props.fontSize) * 0.9) + 'rpx',\n        top: -(Number(props.fontSize) * (isIOS ? 0.14 : 0.15)) + 'rpx'\n    };\n});\n\n/**\n * 组件右侧的内容被点击时触发，用于跳转\"更多\"\n */\nfunction rightClick() {\n    emit('click');\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-section {\n    @include vue-flex;\n    justify-content: space-between;\n    align-items: center;\n    width: 100%;\n\n    &__title {\n        position: relative;\n        font-size: 28rpx;\n        padding-left: 20rpx;\n        @include vue-flex;\n        align-items: center;\n\n        &__icon-wrap {\n            position: absolute;\n        }\n\n        &__text {\n            line-height: 1;\n        }\n    }\n\n    &__right-info {\n        color: $u-tips-color;\n        font-size: 26rpx;\n        @include vue-flex;\n        align-items: center;\n\n        &__icon-arrow {\n            margin-left: 6rpx;\n        }\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-select/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { SelectListItem, SelectMode } from '../../types/global';\nimport { getColor, useLocale } from '../../';\n\nconst { t } = useLocale();\n\n/**\n * SelectProps 列选择器 props 类型定义\n * @description 用于单列、多列、多列联动的选择场景\n */\nexport const SelectProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 列数据 */\n    list: { type: Array as PropType<SelectListItem[] | SelectListItem[][]>, default: () => [] },\n    /** 是否显示边框 */\n    border: { type: Boolean, default: true },\n    /** 通过双向绑定控制组件的弹出与收起 */\n    modelValue: { type: Boolean, default: false },\n    /** \"取消\"按钮的颜色 */\n    cancelColor: { type: String, default: () => getColor('contentColor') },\n    /** \"确定\"按钮的颜色 */\n    confirmColor: { type: String, default: () => getColor('primary') },\n    /** 弹出的z-index值 */\n    zIndex: { type: [String, Number] as PropType<string | number>, default: 0 },\n    /** 是否开启底部安全区适配 */\n    safeAreaInsetBottom: { type: Boolean, default: false },\n    /** 是否允许通过点击遮罩关闭Picker */\n    maskCloseAble: { type: Boolean, default: true },\n    /** 提供的默认选中的下标 */\n    defaultValue: { type: Array as PropType<number[]>, default: () => [0] },\n    /** 是否保留用户上次确认的选择（true：优先使用已保存的选择；false：优先使用外部传入的 defaultValue） */\n    preserveSelection: { type: Boolean, default: true },\n    /** 模式选择，single-column-单列，mutil-column-多列，mutil-column-auto-多列联动 */\n    mode: { type: String as PropType<SelectMode>, default: 'single-column' },\n    /** 自定义value属性名 */\n    valueName: { type: String, default: 'value' },\n    /** 自定义label属性名 */\n    labelName: { type: String, default: 'label' },\n    /** 自定义多列联动模式的children属性名 */\n    childName: { type: String, default: 'children' },\n    /** 顶部标题 */\n    title: { type: String, default: '' },\n    /** 取消按钮的文字 */\n    cancelText: { type: String, default: () => t('uSelect.cancelText') },\n    /** 确认按钮的文字 */\n    confirmText: { type: String, default: () => t('uSelect.confirmText') }\n};\n\nexport type SelectProps = ExtractPropTypes<typeof SelectProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-select/u-select.vue",
    "content": "<template>\n    <view class=\"u-select\" :class=\"customClass\" :style=\"$u.toStyle(customStyle)\">\n        <!-- <view class=\"u-select__action\" :class=\"{\n\t\t'u-select--border': border\n\t}\" @tap.stop=\"selectHandler\">\n\t\t<view class=\"u-select__action__icon\" :class=\"{\n\t\t\t'u-select__action__icon--reverse': value == true\n\t\t}\">\n\t\t\t<u-icon name=\"arrow-down-fill\" size=\"26\" color=\"var(--u-light-color)\"></u-icon>\n\t\t</view>\n\t</view> -->\n        <u-popup\n            :maskCloseAble=\"maskCloseAble\"\n            mode=\"bottom\"\n            :popup=\"false\"\n            v-model=\"popupValue\"\n            length=\"auto\"\n            :safeAreaInsetBottom=\"safeAreaInsetBottom\"\n            @close=\"close\"\n            :z-index=\"uZIndex\"\n        >\n            <view class=\"u-select\">\n                <view class=\"u-select__header\" @touchmove.stop.prevent=\"\">\n                    <view\n                        class=\"u-select__header__cancel u-select__header__btn\"\n                        :style=\"{ color: cancelColor }\"\n                        hover-class=\"u-hover-class\"\n                        :hover-stay-time=\"150\"\n                        @tap=\"getResult('cancel')\"\n                    >\n                        {{ cancelText }}\n                    </view>\n                    <view class=\"u-select__header__title u-line-1\"> {{ title }}</view>\n                    <view\n                        class=\"u-select__header__confirm u-select__header__btn\"\n                        :style=\"{ color: moving ? cancelColor : confirmColor }\"\n                        hover-class=\"u-hover-class\"\n                        :hover-stay-time=\"150\"\n                        @touchmove.stop=\"\"\n                        @tap.stop=\"getResult('confirm')\"\n                    >\n                        {{ confirmText }}\n                    </view>\n                </view>\n                <view class=\"u-select__body\">\n                    <picker-view\n                        v-if=\"modelValue && readyToRender\"\n                        :value=\"defaultSelector\"\n                        class=\"u-select__body__picker-view\"\n                        mask-class=\"u-picker-view-mask\"\n                        indicator-class=\"u-picker-view-indicator\"\n                        @pickstart=\"pickstart\"\n                        @pickend=\"pickend\"\n                        @change=\"columnChange\"\n                    >\n                        <picker-view-column v-for=\"(item, index) in columnData\" :key=\"index\">\n                            <view\n                                class=\"u-select__body__picker-view__item\"\n                                v-for=\"(item1, index1) in item\"\n                                :key=\"index1\"\n                            >\n                                <view class=\"u-line-1\">{{ item1[labelName] }}</view>\n                            </view>\n                        </picker-view-column>\n                    </picker-view>\n                </view>\n            </view>\n        </u-popup>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-select',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, nextTick } from 'vue';\nimport { SelectProps } from './types';\nimport type { SelectListItem } from '../../types/global';\nimport { $u } from '../..';\n\n/**\n * select 列选择器\n * @description 此选择器用于单列，多列，多列联动的选择场景。(从1.3.0版本起，不建议使用Picker组件的单列和多列模式，Select组件是专门为列选择而构造的组件，更简单易用。)\n * @tutorial https://uviewpro.cn/zh/components/select.html\n * @property {String} mode 模式选择，\"single-column\"-单列模式，\"mutil-column\"-多列模式，\"mutil-column-auto\"-多列联动模式\n * @property {Array} list 列数据，数组形式，见官网说明\n * @property {Boolean} v-model 布尔值变量，用于控制选择器的弹出与收起\n * @property {Boolean} safe-area-inset-bottom 是否开启底部安全区适配(默认false)\n * @property {String} cancel-color 取消按钮的颜色（默认var(--u-content-color)）\n * @property {String} confirm-color 确认按钮的颜色(默认主题色primary)\n * @property {String} confirm-text 确认按钮的文字\n * @property {String} cancel-text 取消按钮的文字\n * @property {String} default-value 提供的默认选中的下标，见官网说明\n * @property {Boolean} mask-close-able 是否允许通过点击遮罩关闭Picker(默认true)\n * @property {String Number} z-index 弹出时的z-index值(默认10075)\n * @property {String} value-name 自定义list数据的value属性名 1.3.6\n * @property {String} label-name 自定义list数据的label属性名 1.3.6\n * @property {String} child-name 自定义list数据的children属性名，只对多列联动模式有效 1.3.7\n * @event {Function} confirm 点击确定按钮，返回当前选择的值\n * @example <u-select v-model=\"show\" :list=\"list\"></u-select>\n */\n\nconst props = defineProps(SelectProps);\nconst emit = defineEmits(['update:modelValue', 'confirm', 'cancel', 'click']);\n// 用于列改变时，保存当前的索引，下一次变化时比较得出是哪一列发生了变化\n\nconst defaultSelector = ref<number[]>([0]);\n// picker-view的数据\nconst columnData = ref<SelectListItem[][]>([]);\n// 控制 picker 是否渲染（等待初始化完成）\nconst readyToRender = ref(false);\n// 保存用户上次确认的索引，如果用户未确认过，则为 null，首次打开会使用 props.defaultValue\nconst savedSelector = ref<number[] | null>(\n    props.defaultValue && props.defaultValue.length ? props.defaultValue.slice() : null\n);\n// 每次队列发生变化时，保存选择的结果\nconst selectValue = ref<SelectListItem[]>([]);\n// 上一次列变化时的index\nconst lastSelectIndex = ref<number[]>([]);\n// 列数\nconst columnNum = ref(0);\n// 列是否还在滑动中，微信小程序如果在滑动中就点确定，结果可能不准确\nconst moving = ref(false);\n// 如果用户有传递z-index值，优先使用\nconst uZIndex = computed(() => (props.zIndex ? props.zIndex : $u.zIndex.popup));\n\nconst popupValue = computed({\n    get: () => props.modelValue,\n    set: (val: boolean) => emit('update:modelValue', val)\n});\n\nwatch(\n    () => props.modelValue,\n    async val => {\n        if (val) {\n            // 等待一次 DOM 更新\n            await nextTick();\n            // 在 App（APP-PLUS）平台上，原生 picker 可能需要更长时间初始化\n            // 我们先执行 init，并在 init 完成后将 readyToRender 置为 true，保证 picker 在数据就绪后渲染\n            // #ifdef APP-PLUS\n            await new Promise(resolve => setTimeout(resolve, 20));\n            // #endif\n            init();\n            readyToRender.value = true;\n        } else {\n            // 关闭弹窗时复位\n            readyToRender.value = false;\n        }\n    },\n    { immediate: true }\n);\n// 标识滑动开始，只有微信小程序才有这样的事件\nfunction pickstart() {\n    // #ifdef MP-WEIXIN\n    moving.value = true;\n    // #endif\n}\nfunction pickend() {\n    // #ifdef MP-WEIXIN\n    moving.value = false;\n    // #endif\n}\n\nfunction init() {\n    // 先计算列数\n    setColumnNum();\n    // 根据 columnData 和 columnNum 设置默认选中\n    setDefaultSelector();\n    // 准备列数据（部分模式需要依赖 defaultSelector 的值，但我们将先生成columnData的结构）\n    setColumnData();\n    // 清空并设置 selectValue\n    selectValue.value = [];\n    setSelectValue();\n}\n\n// 获取默认选中列下标\nfunction setDefaultSelector() {\n    // 根据 preserveSelection 决定优先级：\n    // - 如果 preserveSelection 为 true（默认），优先使用用户已确认的选择 savedSelector（如果存在），否则使用 props.defaultValue\n    // - 如果 preserveSelection 为 false，则优先使用外部 props.defaultValue（如果存在），否则使用 savedSelector\n    let useDefault: number[] | null = null;\n    if (props.preserveSelection) {\n        useDefault = savedSelector.value && savedSelector.value.length ? savedSelector.value : props.defaultValue;\n    } else {\n        useDefault = props.defaultValue && props.defaultValue.length ? props.defaultValue : savedSelector.value;\n    }\n    // 如果没有传入默认选中的值，生成长度为 columnNum，用0填充的数组\n    defaultSelector.value =\n        useDefault && useDefault.length == columnNum.value ? useDefault.slice() : Array(columnNum.value).fill(0);\n    lastSelectIndex.value = [...defaultSelector.value];\n}\n// 计算列数\nfunction setColumnNum() {\n    // 单列的列数为1\n    if (props.mode == 'single-column') columnNum.value = 1;\n    // 多列时，this.list数组长度就是列数\n    else if (props.mode == 'mutil-column') columnNum.value = props.list.length;\n    // 多列联动时，通过历遍this.list的第一个元素，得出有多少列\n    else if (props.mode == 'mutil-column-auto') {\n        let num = 1;\n        let column: any = props.list;\n        // 只要有元素并且第一个元素有children属性，继续遍历\n        while (Array.isArray(column) && column[0] && typeof column[0] === 'object' && props.childName in column[0]) {\n            column = column[0][props.childName];\n            num++;\n        }\n        columnNum.value = num;\n    }\n}\n\n// 获取需要展示在picker中的列数据\nfunction setColumnData() {\n    let data: SelectListItem[][] = [];\n    selectValue.value = [];\n    if (props.mode == 'mutil-column-auto') {\n        // 获得所有数据中的第一个元素\n        let column: any = props.list[defaultSelector.value.length ? defaultSelector.value[0] : 0];\n        // 通过循环所有的列数，再根据设定列的数组，得出当前需要渲染的整个列数组\n        for (let i = 0; i < columnNum.value; i++) {\n            // 第一列默认为整个list数组\n            if (i == 0) {\n                data[i] = is2DList(props.list) ? props.list[i] || [] : (props.list as SelectListItem[]);\n                column = column && typeof column === 'object' ? column[props.childName] : [];\n            } else {\n                // 大于第一列时，判断是否有默认选中的，如果没有就用该列的第一项\n                data[i] = Array.isArray(column) ? column : [];\n                column =\n                    Array.isArray(column) &&\n                    column[defaultSelector.value[i]] &&\n                    typeof column[defaultSelector.value[i]] === 'object'\n                        ? column[defaultSelector.value[i]][props.childName]\n                        : [];\n            }\n        }\n    } else if (props.mode == 'single-column') {\n        data[0] = Array.isArray(props.list) && !is2DList(props.list) ? (props.list as SelectListItem[]) : [];\n    } else if (props.mode == 'mutil-column') {\n        data = is2DList(props.list) ? props.list : [props.list as SelectListItem[]];\n    }\n    columnData.value = data;\n}\n\n// 获取默认选中的值，如果没有设置defaultValue，就默认选中每列的第一个\nfunction setSelectValue() {\n    for (let i = 0; i < columnNum.value; i++) {\n        const tmp = columnData.value[i][defaultSelector.value[i]];\n        let data: any = {\n            value: tmp ? tmp[props.valueName] : null,\n            label: tmp ? tmp[props.labelName] : null\n        };\n\n        // 判断是否存在额外的参数，如果存在，就返回\n        if (tmp && tmp.extra !== undefined) data.extra = tmp.extra;\n        selectValue.value.push(data);\n    }\n}\n\n// 列选项\nfunction columnChange(e: any) {\n    let index: number = -1;\n    const columnIndex = e.detail.value;\n    // 由于后面是需要push进数组的，所以需要先清空数组\n    selectValue.value = [];\n    defaultSelector.value = columnIndex;\n    if (props.mode == 'mutil-column-auto') {\n        // 对比前后两个数组，寻找变更的是哪一列，如果某一个元素不同，即可判定该列发生了变化\n        lastSelectIndex.value.map((val, idx) => {\n            if (val != columnIndex[idx]) index = idx;\n        });\n        for (let i = index + 1; i < columnNum.value; i++) {\n            // 当前变化列的下一列的数据，需要获取上一列的数据，同时需要指定是上一列的第几个的children，再往后的\n            // 默认是队列的第一个为默认选项\n            const prevCol = columnData.value[i - 1];\n            const prevIdx = i - 1 == index ? columnIndex[index] : 0;\n            columnData.value[i] =\n                Array.isArray(prevCol) && prevCol[prevIdx] && typeof prevCol[prevIdx] === 'object'\n                    ? prevCol[prevIdx][props.childName]\n                    : [];\n            // 改变的列之后的所有列，默认选中第一个\n            defaultSelector.value[i] = 0;\n        }\n        // 在历遍的过程中，可能由于上一步修改this.columnData，导致产生连锁反应，程序触发columnChange，会有多次调用\n        // 只有在最后一次数据稳定后的结果是正确的，此前的历遍中，可能会产生undefined，故需要判断\n        columnIndex.map((item: any, idx: number) => {\n            let data = columnData.value[idx][columnIndex[idx]];\n            let tmp: any = {\n                value: data ? data[props.valueName] : null,\n                label: data ? data[props.labelName] : null\n            };\n            // 判断是否有需要额外携带的参数\n            if (data && data.extra !== undefined) tmp.extra = data.extra;\n            selectValue.value.push(tmp);\n        });\n        // 保存这一次的结果，用于下次列发生变化时作比较\n        lastSelectIndex.value = [...columnIndex];\n    } else if (props.mode == 'single-column') {\n        let data = columnData.value[0][columnIndex[0]];\n        // 初始默认选中值\n        let tmp: any = {\n            value: data ? data[props.valueName] : null,\n            label: data ? data[props.labelName] : null\n        };\n        // 判断是否有需要额外携带的参数\n        if (data && data.extra !== undefined) tmp.extra = data.extra;\n        selectValue.value.push(tmp);\n    } else if (props.mode == 'mutil-column') {\n        // 初始默认选中值\n        columnIndex.map((item: any, idx: number) => {\n            let data = columnData.value[idx][columnIndex[idx]];\n            // 初始默认选中值\n            let tmp: any = {\n                value: data ? data[props.valueName] : null,\n                label: data ? data[props.labelName] : null\n            };\n            // 判断是否有需要额外携带的参数\n            if (data && data.extra !== undefined) tmp.extra = data.extra;\n            selectValue.value.push(tmp);\n        });\n    }\n}\n\nfunction close() {\n    emit('update:modelValue', false);\n    // 重置default-value默认值\n    // defaultSelector.value = [0];\n}\n// 点击确定或者取消\nfunction getResult(event: 'update:modelValue' | 'confirm' | 'cancel' | 'click' | null = null) {\n    // #ifdef MP-WEIXIN\n    if (moving.value) return;\n    // #endif\n\n    if (event) emit(event, selectValue.value);\n    // 如果是用户确认，则保存已确认的索引，作为下次打开时的默认值\n    if (event === 'confirm') {\n        // deep copy\n        savedSelector.value = defaultSelector.value ? defaultSelector.value.slice() : null;\n    }\n    close();\n}\n\nfunction selectHandler() {\n    emit('click');\n}\n\n// 类型守卫提前声明\nfunction is2DList(list: SelectListItem[] | SelectListItem[][]): list is SelectListItem[][] {\n    return Array.isArray(list) && list.length > 0 && Array.isArray(list[0]);\n}\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n\n.u-select {\n    &__action {\n        position: relative;\n        line-height: 70rpx;\n        height: 70rpx;\n\n        &__icon {\n            position: absolute;\n            right: 20rpx;\n            top: 50%;\n            transition: transform 0.4s;\n            transform: translateY(-50%);\n            z-index: 1;\n\n            &--reverse {\n                transform: rotate(-180deg) translateY(50%);\n            }\n        }\n    }\n\n    &--border {\n        border-radius: 6rpx;\n        border-radius: 4px;\n        border: 1px solid $u-border-color;\n    }\n\n    &__header {\n        @include vue-flex;\n        align-items: center;\n        justify-content: space-between;\n        height: 80rpx;\n        position: relative;\n\n        &__title {\n            color: $u-content-color;\n        }\n\n        &__btn {\n            min-width: 150rpx;\n            padding: 20rpx 30rpx;\n        }\n    }\n\n    &__header::after {\n        content: '';\n        position: absolute;\n        border-bottom: 1rpx solid var(--u-border-color);\n        -webkit-transform: scaleY(0.5);\n        transform: scaleY(0.5);\n        bottom: 0;\n        right: 0;\n        left: 0;\n    }\n\n    &__body {\n        width: 100%;\n        height: 500rpx;\n        overflow: hidden;\n        background-color: var(--u-bg-white);\n\n        &__picker-view {\n            height: 100%;\n            box-sizing: border-box;\n\n            &__item {\n                @include vue-flex;\n                align-items: center;\n                justify-content: center;\n                font-size: 32rpx;\n                color: $u-main-color;\n                padding: 0 8rpx;\n            }\n        }\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-skeleton/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\nconst skeleton = {\n    loading: true,\n    animate: true,\n    rows: 0,\n    rowsWidth: '100%',\n    rowsHeight: 18,\n    title: true,\n    titleWidth: '50%',\n    titleHeight: 18,\n    avatar: false,\n    avatarSize: 32,\n    avatarShape: 'circle'\n};\n\n/**\n * SkeletonProps 骨架屏 props 类型定义\n * @description 骨架屏用于页面数据加载时的占位\n */\nexport const SkeletonProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    // 是否展示骨架组件\n    loading: {\n        type: Boolean,\n        default: skeleton.loading\n    },\n    // 是否开启动画效果\n    animate: {\n        type: Boolean,\n        default: skeleton.animate\n    },\n    // 段落占位图行数\n    rows: {\n        type: [String, Number],\n        default: skeleton.rows\n    },\n    // 段落占位图的宽度\n    rowsWidth: {\n        type: [String, Number, Array],\n        default: skeleton.rowsWidth\n    },\n    // 段落占位图的高度\n    rowsHeight: {\n        type: [String, Number, Array],\n        default: skeleton.rowsHeight\n    },\n    // 是否展示标题占位图\n    title: {\n        type: Boolean,\n        default: skeleton.title\n    },\n    // 段落标题的宽度\n    titleWidth: {\n        type: [String, Number],\n        default: skeleton.titleWidth\n    },\n    // 段落标题的高度\n    titleHeight: {\n        type: [String, Number],\n        default: skeleton.titleHeight\n    },\n    // 是否展示头像占位图\n    avatar: {\n        type: Boolean,\n        default: skeleton.avatar\n    },\n    // 头像占位图大小\n    avatarSize: {\n        type: [String, Number],\n        default: skeleton.avatarSize\n    },\n    // 头像占位图的形状，circle-圆形，square-方形\n    avatarShape: {\n        type: String,\n        default: skeleton.avatarShape\n    }\n};\n\nexport type SkeletonProps = ExtractPropTypes<typeof SkeletonProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-skeleton/u-skeleton.vue",
    "content": "<template>\n    <view class=\"u-skeleton\" :class=\"customClass\" :style=\"$u.toStyle(customStyle)\">\n        <view class=\"u-skeleton__wrapper\" ref=\"skeletonRef\" v-if=\"loading\" style=\"display: flex; flex-direction: row\">\n            <view\n                class=\"u-skeleton__wrapper__avatar\"\n                v-if=\"avatar\"\n                :class=\"[`u-skeleton__wrapper__avatar--${avatarShape}`, animate && 'animate']\"\n                :style=\"{\n                    height: $u.addUnit(avatarSize, 'px'),\n                    width: $u.addUnit(avatarSize, 'px')\n                }\"\n            ></view>\n            <view class=\"u-skeleton__wrapper__content\" ref=\"contentRef\" style=\"flex: 1\">\n                <view\n                    class=\"u-skeleton__wrapper__content__title\"\n                    v-if=\"title\"\n                    :style=\"{\n                        width: uTitleWidth,\n                        height: $u.addUnit(titleHeight, 'px')\n                    }\"\n                    :class=\"[animate && 'animate']\"\n                ></view>\n                <view\n                    class=\"u-skeleton__wrapper__content__rows\"\n                    :class=\"[animate && 'animate']\"\n                    v-for=\"(item, index) in rowsArray\"\n                    :key=\"index\"\n                    :style=\"{\n                        width: item.width,\n                        height: item.height,\n                        marginTop: item.marginTop\n                    }\"\n                >\n                </view>\n            </view>\n        </view>\n        <slot v-else />\n    </view>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref, computed, onMounted, watch, getCurrentInstance } from 'vue';\nimport { SkeletonProps } from './types';\nimport { $u } from '../../libs';\n// #ifdef APP-NVUE\n// 由于weex为阿里的KPI业绩考核的产物，所以不支持百分比单位，这里需要通过dom查询组件的宽度\nconst dom = uni.requireNativePlugin('dom');\nconst animation = uni.requireNativePlugin('animation');\n// #endif\n/**\n * Skeleton 骨架屏\n * @description 骨架屏一般用于页面在请求远程数据尚未完成时，页面用灰色块预显示本来的页面结构，给用户更好的体验。\n * @tutorial https://uviewpro.cn/zh/components/skeleton.html\n * @property {Boolean}\t\t\t\t\tloading\t\t是否显示骨架占位图，设置为false将会展示子组件内容 (默认 true )\n * @property {Boolean}\t\t\t\t\tanimate\t\t是否开启动画效果 (默认 true )\n * @property {String | Number}\t\t\trows\t\t段落占位图行数 (默认 0 )\n * @property {String | Number | Array}\trowsWidth\t段落占位图的宽度，可以为百分比，数值，带单位字符串等，可通过数组传入指定每个段落行的宽度 (默认 '100%' )\n * @property {String | Number | Array}\trowsHeight\t段落的高度 (默认 18 )\n * @property {Boolean}\t\t\t\t\ttitle\t\t是否展示标题占位图 (默认 true )\n * @property {String | Number}\t\t\ttitleWidth\t标题的宽度 (默认 '50%' )\n * @property {String | Number}\t\t\ttitleHeight\t标题的高度 (默认 18 )\n * @property {Boolean}\t\t\t\t\tavatar\t\t是否展示头像占位图 (默认 false )\n * @property {String | Number}\t\t\tavatarSize\t头像占位图大小 (默认 32 )\n * @property {String}\t\t\t\t\tavatarShape\t头像占位图的形状，circle-圆形，square-方形 (默认 'circle' )\n * @example <u-skeleton rows=\"3\" title loading></u-skeleton>\n */\n\nconst props = defineProps(SkeletonProps);\n\nconst instance = getCurrentInstance();\n\nconst width = ref<number>(0);\nconst skeletonRef = ref<any>(null);\nconst contentRef = ref<any>(null);\n\nwatch(\n    () => [props.loading],\n    () => {\n        getComponentWidth();\n    }\n);\n\nconst rowsArray = computed(() => {\n    if (/%$/.test(props.rowsHeight as any)) {\n        console.error('rowsHeight参数不支持百分比单位');\n    }\n    const resultRows: Array<Record<string, any>> = [];\n    const rowsCount = Number(props.rows) || 0;\n    for (let i = 0; i < rowsCount; i++) {\n        let item: Record<string, any> = {};\n        // 需要预防超出数组边界的情况\n        const rowWidth = $u.test.array(props.rowsWidth)\n            ? (props.rowsWidth as any[])[i] || (i === rowsCount - 1 ? '70%' : '100%')\n            : i === rowsCount - 1\n              ? '70%'\n              : props.rowsWidth;\n        const rowHeight = $u.test.array(props.rowsHeight) ? (props.rowsHeight as any[])[i] || '18px' : props.rowsHeight;\n        // 如果有title占位图，第一个段落占位图的外边距需要大一些，如果没有title占位图，第一个段落占位图则无需外边距\n        // 之所以需要这么做，是因为weex的无能，以提升性能为借口不支持css的一些伪类\n        item.marginTop = !props.title && i === 0 ? 0 : props.title && i === 0 ? '20px' : '12px';\n        // 如果设置的为百分比的宽度，转换为px值，因为nvue不支持百分比单位\n        if (/%$/.test(rowWidth)) {\n            // 通过parseInt提取出百分比单位中的数值部分，除以100得到百分比的小数值\n            item.width = $u.addUnit((width.value * parseInt(String(rowWidth))) / 100, 'px');\n        } else {\n            item.width = $u.addUnit(rowWidth, 'px');\n        }\n        item.height = $u.addUnit(rowHeight, 'px');\n        resultRows.push(item);\n    }\n    return resultRows;\n});\n\nconst uTitleWidth = computed(() => {\n    let tWidth: any = 0;\n    if (/%$/.test(props.titleWidth as any)) {\n        // 通过parseInt提取出百分比单位中的数值部分，除以100得到百分比的小数值\n        tWidth = $u.addUnit((width.value * parseInt(String(props.titleWidth))) / 100, 'px');\n    } else {\n        tWidth = $u.addUnit(props.titleWidth, 'px');\n    }\n    return $u.addUnit(tWidth, 'px');\n});\n\nfunction init() {\n    getComponentWidth();\n    // #ifdef APP-NVUE\n    props.loading && props.animate && setNvueAnimation();\n    // #endif\n}\n\nasync function setNvueAnimation() {\n    // #ifdef APP-NVUE\n    // 为了让opacity:1的状态保持一定时间，这里做一个延时\n    await $u.sleep(500);\n    const skeleton = skeletonRef.value;\n    skeleton &&\n        props.loading &&\n        props.animate &&\n        animation.transition(\n            skeleton,\n            {\n                styles: {\n                    opacity: 0.5\n                },\n                duration: 600\n            },\n            () => {\n                // 这里无需判断是否loading和开启动画状态，因为最终的状态必须达到opacity: 1，否则可能\n                // 会停留在opacity: 0.5的状态中\n                animation.transition(\n                    skeleton,\n                    {\n                        styles: {\n                            opacity: 1\n                        },\n                        duration: 600\n                    },\n                    () => {\n                        // 只有在loading中时，才执行动画\n                        props.loading && props.animate && setNvueAnimation();\n                    }\n                );\n            }\n        );\n    // #endif\n}\n\n// 获取组件的宽度\nasync function getComponentWidth() {\n    // 延时一定时间，以获取dom尺寸\n    await $u.sleep(20);\n    // #ifndef APP-NVUE\n    $u.getRect('.u-skeleton__wrapper__content', instance).then((res: any) => {\n        width.value = res.width;\n    });\n    // #endif\n\n    // #ifdef APP-NVUE\n    const ref = contentRef.value;\n    ref &&\n        dom.getComponentRect(ref, (res: any) => {\n            width.value = res.size.width;\n        });\n    // #endif\n}\n\nonMounted(() => {\n    init();\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n@mixin background {\n    /* #ifdef APP-NVUE */\n    background-color: #f1f2f4;\n    /* #endif */\n    /* #ifndef APP-NVUE */\n    background: linear-gradient(90deg, #f1f2f4 25%, #e6e6e6 37%, #f1f2f4 50%);\n    background-size: 400% 100%;\n    /* #endif */\n}\n\n.u-skeleton {\n    flex: 1;\n\n    &__wrapper {\n        @include flex(row);\n\n        &__avatar {\n            @include background;\n            margin-right: 15px;\n\n            &--circle {\n                border-radius: 100px;\n            }\n\n            &--square {\n                border-radius: 4px;\n            }\n        }\n\n        &__content {\n            flex: 1;\n\n            &__rows,\n            &__title {\n                @include background;\n                border-radius: 3px;\n            }\n        }\n    }\n}\n\n/* #ifndef APP-NVUE */\n.animate {\n    animation: skeleton 1.8s ease infinite;\n}\n\n@keyframes skeleton {\n    0% {\n        background-position: 100% 50%;\n    }\n\n    100% {\n        background-position: 0 50%;\n    }\n}\n\n/* #endif */\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-slider/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport { getColor } from '../../';\n\n/**\n * SliderProps 滑块选择器 props 类型定义\n * @description 滑块选择器，支持自定义样式、步长、禁用等\n */\nexport const SliderProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 当前进度百分比值，范围0-100 */\n    modelValue: { type: [Number, String] as PropType<number | string>, default: 0 },\n    /** 是否禁用滑块 */\n    disabled: { type: Boolean, default: false },\n    /** 滑块宽度，高等于宽，单位rpx */\n    blockWidth: { type: [Number, String] as PropType<number | string>, default: 30 },\n    /** 滑块总体范围起点值 */\n    start: { type: [Number, String] as PropType<number | string>, default: 0 },\n    /** 滑块总体范围终点值 */\n    end: { type: [Number, String] as PropType<number | string>, default: 100 },\n    /** 最小值 */\n    min: { type: [Number, String] as PropType<number | string>, default: 0 },\n    /** 最大值 */\n    max: { type: [Number, String] as PropType<number | string>, default: 100 },\n    /** 步进值 */\n    step: { type: [Number, String] as PropType<number | string>, default: 1 },\n    /** 滑块条高度，单位rpx */\n    height: { type: [Number, String] as PropType<number | string>, default: 6 },\n    /** 进度条的激活部分颜色 */\n    activeColor: { type: String, default: () => getColor('primary') },\n    /** 进度条的背景颜色 */\n    inactiveColor: { type: String, default: () => getColor('lightColor') },\n    /** 滑块的背景颜色 */\n    blockColor: { type: String, default: 'var(--u-bg-white)' },\n    /** 用户对滑块的自定义颜色 */\n    blockStyle: { type: Object as PropType<Record<string, any>>, default: () => ({}) },\n    /** 是否在滑块上方/下方显示当前数值 */\n    showValue: { type: Boolean, default: false },\n    /** 滑块数值显示位置，top-上方，bottom-下方 */\n    valuePosition: { type: String as PropType<'top' | 'bottom'>, default: 'top' },\n    /** 是否在起始和结束位置显示数值 */\n    showEdgeValue: { type: Boolean, default: false },\n    /** 起始和结束数值显示位置，top-上方，bottom-下方 */\n    edgeValuePosition: { type: String as PropType<'top' | 'bottom'>, default: 'top' }\n};\n\nexport type SliderProps = ExtractPropTypes<typeof SliderProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-slider/u-slider.vue",
    "content": "<template>\n    <view\n        class=\"u-slider\"\n        @tap=\"onClick\"\n        :class=\"[disabled ? 'u-slider--disabled' : '', customClass]\"\n        :style=\"$u.toStyle(sliderStyle, customStyle)\"\n    >\n        <view\n            v-if=\"showEdgeValue\"\n            class=\"u-slider__edge u-slider__edge--start\"\n            :class=\"`u-slider__edge--${edgeValuePosition}`\"\n        >\n            {{ startLabel }}\n        </view>\n        <view\n            v-if=\"showEdgeValue\"\n            class=\"u-slider__edge u-slider__edge--end\"\n            :class=\"`u-slider__edge--${edgeValuePosition}`\"\n        >\n            {{ endLabel }}\n        </view>\n        <view\n            class=\"u-slider__gap\"\n            :style=\"\n                $u.toStyle(barStyle, {\n                    height: height + 'rpx',\n                    backgroundColor: activeColor\n                })\n            \"\n        >\n            <view\n                class=\"u-slider__button-wrap\"\n                @touchstart=\"onTouchStart\"\n                @touchmove=\"onTouchMove\"\n                @touchend=\"onTouchEnd\"\n                @touchcancel=\"onTouchEnd\"\n            >\n                <slot v-if=\"slots.default\" />\n                <view\n                    v-else\n                    class=\"u-slider__button\"\n                    :style=\"\n                        $u.toStyle(blockStyle, {\n                            height: blockWidth + 'rpx',\n                            width: blockWidth + 'rpx',\n                            backgroundColor: blockColor\n                        })\n                    \"\n                />\n                <view v-if=\"showValue\" class=\"u-slider__value\" :class=\"`u-slider__value--${valuePosition}`\">\n                    {{ displayValue }}\n                </view>\n            </view>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-slider',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, watch, onMounted, useSlots, getCurrentInstance } from 'vue';\nimport { $u } from '../..';\nimport { SliderProps } from './types';\n\n/**\n * slider 滑块选择器\n * @tutorial https://uviewpro.cn/zh/components/slider.html\n * @property {Number | String} value 滑块当前值，位于[start, end]范围内（默认0）\n * @property {Number | String} start 整体范围起点值（默认0）\n * @property {Number | String} end 整体范围终点值（默认100）\n * @property {Number | String} min 有效拖动最小值，需在[start, end]中（默认0）\n * @property {Number | String} max 有效拖动最大值，需在[start, end]中（默认100）\n * @property {Number | String} step 步长（默认1）\n * @property {Number | String} blockWidth 滑块宽度，高等于宽（30）\n * @property {Number | String} height 滑块条高度，单位rpx（默认6）\n * @property {String} inactiveColor 底部条背景颜色（默认var(--u-light-color)）\n * @property {String} activeColor 底部选择部分的背景颜色（默认主题色primary）\n * @property {String} blockColor 滑块颜色（默认var(--u-bg-white)）\n * @property {Object} blockStyle 给滑块自定义样式，对象形式\n * @property {Boolean} disabled 是否禁用滑块(默认为false)\n * @property {Boolean} showValue 是否在滑块上方/下方显示当前数值\n * @property {String} valuePosition 当前数值显示位置，top-上方，bottom-下方（默认top）\n * @property {Boolean} showEdgeValue 是否在起始和结束位置显示数值\n * @property {String} edgeValuePosition 起始和结束数值显示位置，top-上方，bottom-下方（默认top）\n * @event start 滑动触发\n * @event moving 正在滑动中\n * @event end 滑动结束\n * @example <u-slider v-model=\"value\" />\n */\n\nconst emit = defineEmits(['update:modelValue', 'start', 'moving', 'end']);\n\nconst props = defineProps(SliderProps);\n\nconst slots = useSlots();\nconst instance = getCurrentInstance();\n\n// 滑块条的尺寸信息\nconst sliderRect = ref<{ left: number; width: number }>({ left: 0, width: 0 });\nconst startX = ref(0);\nconst status = ref<'start' | 'moving' | 'end'>('end');\nconst newValue = ref(0);\nconst distanceX = ref(0);\nconst startValue = ref(0);\nconst barStyle = ref<Record<string, any>>({});\nconst innerValue = ref<number>(0);\n\nconst rangeStart = computed(() => Number(props.start));\nconst rangeEnd = computed(() => Number(props.end));\nconst rangeTotal = computed(() => {\n    const total = rangeEnd.value - rangeStart.value;\n    return total === 0 ? 1 : total;\n});\n\nconst sliderStyle = computed(() => {\n    const style = {\n        backgroundColor: props.inactiveColor\n    } as Record<string, any>;\n    if (\n        (props.showValue && props.valuePosition === 'top') ||\n        (props.showEdgeValue && props.edgeValuePosition === 'top')\n    ) {\n        style.marginTop = '80rpx';\n    }\n    if (\n        (props.showValue && props.valuePosition === 'bottom') ||\n        (props.showEdgeValue && props.edgeValuePosition === 'bottom')\n    ) {\n        style.marginBottom = '80rpx';\n    }\n    return style;\n});\n\n// 限制min和max在start和end范围内\nconst effectiveMin = computed(() => {\n    const min = Number(props.min);\n    return Math.max(rangeStart.value, Math.min(min, rangeEnd.value));\n});\n\nconst effectiveMax = computed(() => {\n    const max = Number(props.max);\n    return Math.min(rangeEnd.value, Math.max(max, rangeStart.value));\n});\n\nconst startLabel = computed(() => props.start);\nconst endLabel = computed(() => props.end);\nconst showValue = computed(() => props.showValue);\nconst valuePosition = computed(() => props.valuePosition || 'top');\nconst showEdgeValue = computed(() => props.showEdgeValue);\nconst edgeValuePosition = computed(() => props.edgeValuePosition || 'top');\n\nconst displayValue = computed(() => innerValue.value);\n\n// 监听 value 变化，非滑动状态时才更新滑块值\nwatch(\n    () => props.modelValue,\n    n => {\n        // 只有在非滑动状态时，才可以通过modelValue更新滑块值，这里监听，是为了让用户触发\n        if (status.value === 'end') updateValue(n, false);\n    }\n);\n\nwatch(\n    () => [props.start, props.end, props.min, props.max],\n    () => {\n        updateValue(innerValue.value, false);\n    },\n    { deep: true }\n);\n\nonMounted(() => {\n    // 获取滑块条的尺寸信息\n    $u.getRect('.u-slider', instance).then((rect: { left: number; width: number }) => {\n        sliderRect.value = rect;\n    });\n    updateValue(props.modelValue, false);\n});\n\n/**\n * 触摸开始\n */\nfunction onTouchStart(event: TouchEvent) {\n    if (props.disabled) return;\n    startX.value = 0;\n    // 触摸点集\n    const touches = event.touches[0];\n    // 触摸点到屏幕左边的距离\n    startX.value = touches.clientX;\n    // 此处的props.modelValue虽为props值，但是通过emit('update:modelValue')进行了修改\n    startValue.value = format(props.modelValue);\n    // 标示当前的状态为开始触摸滑动\n    status.value = 'start';\n}\n\n/**\n * 触摸移动\n */\nfunction onTouchMove(event: TouchEvent) {\n    if (props.disabled) return;\n    // 连续触摸的过程会一直触发本方法，但只有手指触发且移动了才被认为是拖动了，才发出事件\n    // 触摸后第一次移动已经将status设置为moving状态，故触摸第二次移动不会触发本事件\n    if (status.value === 'start') emit('start');\n    const touches = event.touches[0];\n    // 滑块的左边不一定跟屏幕左边接壤，所以需要减去最外层父元素的左边值\n    distanceX.value = touches.clientX - sliderRect.value.left;\n    const ratio = distanceX.value / sliderRect.value.width;\n    const raw = rangeStart.value + ratio * rangeTotal.value;\n    newValue.value = raw;\n    status.value = 'moving';\n    // 发出moving事件\n    emit('moving');\n    updateValue(newValue.value, true);\n}\n\n/**\n * 触摸结束\n */\nfunction onTouchEnd() {\n    if (props.disabled) return;\n    if (status.value === 'moving') {\n        updateValue(newValue.value, false);\n        emit('end');\n    }\n    status.value = 'end';\n}\n\n/**\n * 更新滑块值\n * @param value 新值\n * @param drag 是否为拖动\n */\nfunction updateValue(value: number | string, drag: boolean) {\n    // 处理为有效值（步进 + min/max 约束），支持负数\n    const formatted = format(value);\n    innerValue.value = formatted;\n\n    // 计算相对于[start, end]的百分比宽度\n    const ratio = (formatted - rangeStart.value) / rangeTotal.value;\n    let percent = ratio * 100;\n    if (percent < 0) percent = 0;\n    if (percent > 100) percent = 100;\n\n    const style: Record<string, any> = {\n        width: percent + '%'\n    };\n    // 移动期间无需过渡动画\n    if (drag === true) {\n        style.transition = 'none';\n    } else {\n        // 非移动期间，删掉对过渡为空的声明，让css中的声明起效\n        delete style.transition;\n    }\n    // 修改value值（为实际值而非百分比）\n    emit('update:modelValue', formatted);\n    barStyle.value = style;\n}\n\n/**\n * 格式化滑块值\n * @param value 输入值\n * @returns 处理后的值\n */\nfunction format(value: number | string): number {\n    const numeric = Number(value);\n    const step = Number(props.step) || 1;\n    // 在有效范围内裁剪（effectiveMin和effectiveMax已限制在start和end范围内），支持负数\n    const clipped = Math.max(effectiveMin.value, Math.min(numeric, effectiveMax.value));\n    // 将值按步长取整，减少对视图的频繁更新\n    return Math.round(clipped / step) * step;\n}\n\n/**\n * 点击滑块条\n */\nfunction onClick(event: any) {\n    if (props.disabled) return;\n    // 直接点击滑块的情况，计算为整体[start, end]范围内的值\n    const ratio = (event.detail.x - sliderRect.value.left) / sliderRect.value.width;\n    const value = rangeStart.value + ratio * rangeTotal.value;\n    updateValue(value, false);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-slider {\n    position: relative;\n    border-radius: 999px;\n    background-color: var(--u-bg-gray-light);\n}\n\n.u-slider:before {\n    position: absolute;\n    right: 0;\n    left: 0;\n    content: '';\n    top: -8px;\n    bottom: -8px;\n    z-index: -1;\n}\n\n.u-slider__gap {\n    position: relative;\n    border-radius: inherit;\n    transition: width 0.2s;\n    background-color: $u-type-primary;\n}\n\n.u-slider__button {\n    width: 24px;\n    height: 24px;\n    border-radius: 50%;\n    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);\n    background-color: var(--u-bg-white);\n    cursor: pointer;\n}\n\n.u-slider__button-wrap {\n    position: absolute;\n    top: 50%;\n    right: 0;\n    transform: translate3d(50%, -50%, 0);\n}\n\n.u-slider__value {\n    position: absolute;\n    left: 50%;\n    transform: translateX(-50%);\n    font-size: 22rpx;\n    font-weight: 500;\n    color: #333;\n    white-space: nowrap;\n    min-width: 40rpx;\n    height: 56rpx;\n    line-height: 56rpx;\n    padding: 0 10rpx;\n    border-radius: 28rpx;\n    background-color: #ffffff;\n    box-shadow: 0 1px 6px rgba(0, 0, 0, 0.15);\n    z-index: 10;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n}\n\n.u-slider__value--top {\n    bottom: 100%;\n    margin-bottom: 12rpx;\n}\n\n.u-slider__value--top::after {\n    content: '';\n    position: absolute;\n    left: 50%;\n    top: 100%;\n    transform: translateX(-50%);\n    width: 0;\n    height: 0;\n    border-width: 4px 3px 0 3px;\n    border-style: solid;\n    border-color: #ffffff transparent transparent transparent;\n}\n\n.u-slider__value--bottom {\n    top: 100%;\n    margin-top: 12rpx;\n}\n\n.u-slider__value--bottom::after {\n    content: '';\n    position: absolute;\n    left: 50%;\n    bottom: 100%;\n    transform: translateX(-50%);\n    width: 0;\n    height: 0;\n    border-width: 0 6rpx 8rpx 6rpx;\n    border-style: solid;\n    border-color: transparent transparent #ffffff transparent;\n}\n\n.u-slider__edge {\n    position: absolute;\n    font-size: 24rpx;\n    color: $u-tips-color;\n    white-space: nowrap;\n}\n\n.u-slider__edge--start {\n    left: 0;\n}\n\n.u-slider__edge--end {\n    right: 0;\n}\n\n.u-slider__edge--top {\n    bottom: 100%;\n    margin-bottom: 8rpx;\n}\n\n.u-slider__edge--bottom {\n    top: 100%;\n    margin-top: 8rpx;\n}\n\n.u-slider--disabled {\n    opacity: 0.5;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-status-bar/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\nexport const StatusBarProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 背景设置 */\n    background: {\n        type: String,\n        default: 'transparent'\n    }\n};\n\nexport type StatusBarProps = ExtractPropTypes<typeof StatusBarProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-status-bar/u-status-bar.vue",
    "content": "<template>\n    <view\n        :style=\"$u.toStyle(style, customStyle)\"\n        :class=\"['u-status-bar', { 'safe-area-inset-top': noBar }, customClass]\"\n    >\n        <slot />\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-status-bar',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted, type CSSProperties } from 'vue';\nimport { StatusBarProps } from './types';\nimport { $u } from '../../';\n\n/**\n * StatusBar 状态栏\n * @property {String | Object} customStyle 自定义样式\n * @property {String} background 背景颜色\n * @example <u-status-bar></u-status-bar>\n */\nconst props = defineProps(StatusBarProps);\nconst noBar = ref(false);\n\nconst style = computed(() => {\n    let result: CSSProperties = {\n        background: props.background\n    };\n    const statusBarHeight = $u.sys().statusBarHeight;\n    if (statusBarHeight === 0) {\n        noBar.value = true;\n    } else {\n        result.height = $u.addUnit(statusBarHeight, 'px');\n    }\n    return result;\n});\n\nonMounted(() => {\n    // #ifdef H5\n    noBar.value = true;\n    // #endif\n});\n</script>\n\n<style scoped>\n.u-status-bar {\n    /* #ifndef APP-NVUE */\n    /* nvue会默认100%，如果nvue下，显式写100%的话，会导致宽度不为100%而异常 */\n    width: 100%;\n    /* #endif */\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-step/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { StepMode, ThemeType } from '../../types/global';\nimport { getColor } from '../../';\n\n/**\n * StepProps 步骤条 props 类型定义\n * @description 步骤条，支持横向/竖向、主题色、激活色等\n */\n\nexport const StepProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 步骤条的类型，dot|number */\n    mode: { type: String as PropType<StepMode>, default: 'dot' },\n    /** 主题类型, primary|success|info|warning|error */\n    type: { type: String as PropType<ThemeType>, default: 'primary' },\n    /** 激活步骤的颜色 */\n    activeColor: { type: String, default: () => getColor('primary') },\n    /** 未激活的颜色 */\n    unActiveColor: { type: String, default: () => getColor('info') },\n    /** 自定义图标 */\n    icon: { type: String, default: 'checkmark' },\n    /** 标题 */\n    name: { type: String, default: '' },\n    /** 描述 */\n    desc: { type: String, default: '' }\n};\n\nexport type StepProps = ExtractPropTypes<typeof StepProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-step/u-step.vue",
    "content": "<template>\n    <view class=\"u-steps__item\" :class=\"[customClass, 'u-steps__item--' + direction]\" :style=\"$u.toStyle(customStyle)\">\n        <view class=\"u-steps__item__num--wrap\" v-if=\"mode == 'number'\">\n            <view class=\"u-steps__item__num\">\n                <view\n                    class=\"u-steps__item__num--text\"\n                    v-if=\"currentIndex < childIndex\"\n                    :style=\"numberStyle(childIndex)\"\n                >\n                    <text :style=\"textStyle(childIndex)\">\n                        {{ childIndex + 1 }}\n                    </text>\n                </view>\n                <view v-else class=\"u-steps__item__num--circle\">\n                    <slot name=\"icon\">\n                        <view class=\"u-steps__item__num--icon\" :style=\"numberStyle(childIndex)\">\n                            <u-icon size=\"22\" color=\"var(--u-white-color)\" :name=\"iconName\"></u-icon>\n                        </view>\n                    </slot>\n                </view>\n            </view>\n        </view>\n        <view class=\"u-steps__item__dot\" v-else-if=\"mode == 'dot'\">\n            <view class=\"u-steps__item__dot--box\" :style=\"dotStyle(childIndex)\"></view>\n        </view>\n        <view>\n            <view class=\"u-line-1\" :style=\"textStyle(childIndex)\" :class=\"['u-steps__item__text--' + direction]\">\n                <slot name=\"name\">\n                    <text>\n                        {{ name }}\n                    </text>\n                </slot>\n            </view>\n            <view v-if=\"hasDesc\" :class=\"['u-steps__item__desc--' + direction]\">\n                <slot name=\"desc\">\n                    <text>\n                        {{ desc }}\n                    </text>\n                </slot>\n            </view>\n        </view>\n        <view class=\"u-steps__item__line\" :class=\"['u-steps__item__line--' + mode]\" v-if=\"showLine\">\n            <u-line :direction=\"direction\" length=\"100%\" :hair-line=\"false\" :color=\"unActiveColor\"></u-line>\n        </view>\n    </view>\n</template>\n<script lang=\"ts\">\nexport default {\n    name: 'u-step',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { $u, useChildren } from '../..';\nimport { StepProps } from './types';\n\nconst props = defineProps(StepProps);\n\n// 使用组件关系 hooks 获取父组件\nconst { childIndex, parentExposed } = useChildren('u-step', 'u-steps');\n\n// 父组件的默认值（兼容没有父组件的场景）\nconst parentData = computed(() => {\n    return (\n        parentExposed?.value?.props || {\n            mode: 'dot',\n            list: [],\n            type: 'primary',\n            current: 0,\n            activeColor: $u.color.primary,\n            unActiveColor: $u.color.info,\n            icon: 'checkmark',\n            direction: 'row'\n        }\n    );\n});\n\nconst childLen = computed(() => {\n    if (parentExposed?.value?.childLen && typeof parentExposed?.value?.childLen === 'function') {\n        return parentExposed?.value?.childLen();\n    }\n    return 0;\n});\n\nconst showLine = computed(() => childIndex.value < childLen.value - 1);\n\n// 计算属性，计算当前步骤的索引值\n// 如果 current 是字符串，则转换为数字，否则直接使用数字\nconst currentIndex = computed(() =>\n    typeof parentData.value.current === 'string' ? Number(parentData.value.current) : parentData.value.current\n);\nconst mode = computed(() => parentData.value.mode);\nconst direction = computed(() => parentData.value.direction);\n// 计算方向样式\n\nconst activeColor = computed(() => props.activeColor || parentData.value.activeColor);\nconst unActiveColor = computed(() => props.unActiveColor || parentData.value.unActiveColor);\n\nconst name = computed(() => props.name || '');\nconst desc = computed(() => props.desc || '');\nconst hasDesc = computed(() => !$u.test.isEmpty(desc));\nconst iconName = computed(() => {\n    if (props.icon !== parentData.value.icon) {\n        if (props.icon !== 'checkmark') {\n            return props.icon;\n        } else if (parentData.value.icon !== 'checkmark') {\n            return parentData.value.icon;\n        }\n    }\n    return props.icon || parentData.value.icon;\n});\n\n// 计算当前步骤的样式\nconst numberStyle = (index: number) => ({\n    backgroundColor: currentIndex.value < index ? 'var(--u-white-color)' : activeColor.value,\n    borderColor: currentIndex.value < index ? unActiveColor.value : activeColor.value\n});\n\n// 计算当前步骤的样式\nconst dotStyle = (index: number) => ({\n    backgroundColor: index <= currentIndex.value ? activeColor.value : unActiveColor.value\n});\n\n// 计算当前步骤的文字样式\nconst textStyle = (index: number) => ({\n    color: index <= currentIndex.value ? activeColor.value : unActiveColor.value\n});\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n\n$u-steps-item-number-width: 44rpx;\n$u-steps-item-dot-width: 20rpx;\n\n.inline-block {\n    display: inline-block;\n}\n.u-steps__item {\n    flex: 1;\n    text-align: center;\n    position: relative;\n    min-width: 100rpx;\n    font-size: 26rpx;\n    color: var(--u-tips-color);\n    @include vue-flex;\n    flex-direction: column;\n\n    &--row {\n        align-items: center;\n        @include vue-flex;\n        flex-direction: column;\n\n        .u-steps__item__line {\n            position: absolute;\n            z-index: 0;\n\n            &--dot {\n                width: calc(100% - #{$u-steps-item-dot-width});\n                top: calc(#{$u-steps-item-dot-width} / 2);\n                left: calc(#{$u-steps-item-dot-width} / 2 + 50%);\n            }\n\n            &--number {\n                width: calc(100% - $u-steps-item-number-width);\n                top: calc(#{$u-steps-item-number-width} / 2);\n                left: calc(#{$u-steps-item-number-width} / 2 + 50%);\n            }\n        }\n    }\n\n    &--column {\n        @include vue-flex;\n        flex-direction: row;\n        justify-content: flex-start;\n        min-height: 120rpx;\n        padding-bottom: 6rpx;\n\n        .u-steps__item__line {\n            position: absolute;\n            z-index: 0;\n\n            &--dot {\n                height: calc(100% - #{$u-steps-item-dot-width});\n                top: calc(#{$u-steps-item-dot-width} + 6rpx);\n                left: calc(#{$u-steps-item-dot-width} / 2);\n            }\n\n            &--number {\n                height: calc(100% - #{$u-steps-item-number-width});\n                top: #{$u-steps-item-number-width};\n                left: calc(#{$u-steps-item-number-width} / 2);\n            }\n        }\n\n        .u-steps__item__dot {\n            margin-top: 6rpx;\n        }\n    }\n\n    &__num {\n        &--wrap {\n            width: $u-steps-item-number-width;\n            height: $u-steps-item-number-width;\n        }\n        &--text,\n        &--icon,\n        &--circle {\n            @include vue-flex;\n            align-items: center;\n            justify-content: center;\n            width: $u-steps-item-number-width;\n            height: $u-steps-item-number-width;\n            overflow: hidden;\n        }\n        &--text,\n        &--icon {\n            border: 1px solid var(--u-tips-color);\n            border-radius: 50%;\n        }\n    }\n\n    &__dot {\n        display: inline-block;\n        width: $u-steps-item-dot-width;\n        height: $u-steps-item-dot-width;\n        // @include vue-flex;\n        &--box {\n            width: $u-steps-item-dot-width;\n            height: $u-steps-item-dot-width;\n            border-radius: 50%;\n            overflow: hidden;\n        }\n    }\n\n    &__text--row {\n        margin-top: 14rpx;\n    }\n\n    &__text--column {\n        margin-left: 14rpx;\n        text-align: left;\n    }\n\n    &__desc--row {\n        color: $u-type-info;\n        font-size: 24rpx;\n    }\n\n    &__desc--column {\n        margin-left: 14rpx;\n        text-align: left;\n        color: $u-type-info;\n        font-size: 24rpx;\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-steps/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { StepDirection, StepMode, StepsListItem, ThemeType } from '../../types/global';\nimport { getColor } from '../../';\n\n/**\n * StepsProps 步骤条 props 类型定义\n * @description 步骤条，支持横向/竖向、主题色、激活色等\n */\n\nexport const StepsProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 步骤条的类型，dot|number */\n    mode: { type: String as PropType<StepMode>, default: 'dot' },\n    /** 步骤条的数据 */\n    list: { type: Array as PropType<StepsListItem[]>, default: () => [] },\n    /** 主题类型, primary|success|info|warning|error */\n    type: { type: String as PropType<ThemeType>, default: 'primary' },\n    /** 当前哪一步是激活的 */\n    current: { type: [Number, String] as PropType<number | string>, default: 0 },\n    /** 激活步骤的颜色 */\n    activeColor: { type: String, default: () => getColor('primary') },\n    /** 未激活的颜色 */\n    unActiveColor: { type: String, default: () => getColor('info') },\n    /** 自定义图标 */\n    icon: { type: String, default: 'checkmark' },\n    /** step的排列方向，row-横向，column-竖向 */\n    direction: { type: String as PropType<StepDirection>, default: 'row' }\n};\n\nexport type StepsProps = ExtractPropTypes<typeof StepsProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-steps/u-steps.vue",
    "content": "<template>\n    <view>\n        <view class=\"u-steps\" :class=\"customClass\" :style=\"$u.toStyle(directionStyle, customStyle)\">\n            <slot>\n                <u-step\n                    :name=\"item.name\"\n                    :desc=\"item.desc\"\n                    :icon=\"item.icon\"\n                    v-for=\"(item, index) in list\"\n                    :key=\"index\"\n                ></u-step>\n            </slot>\n            <!-- <view\n                class=\"u-steps__item\"\n                :class=\"['u-steps__item--' + direction]\"\n                v-for=\"(item, index) in list\"\n                :key=\"index\"\n            >\n                <view class=\"u-steps__item__num\" v-if=\"mode == 'number'\" :style=\"numberStyle(index)\">\n                    <text v-if=\"currentIndex < index\" :style=\"textStyle(index)\">\n                        {{ index + 1 }}\n                    </text>\n                    <u-icon v-else size=\"22\" color=\"var(--u-white-color)\" :name=\"icon\"></u-icon>\n                </view>\n                <view class=\"u-steps__item__dot\" v-if=\"mode == 'dot'\" :style=\"dotStyle(index)\"></view>\n                <text class=\"u-line-1\" :style=\"textStyle(index)\" :class=\"['u-steps__item__text--' + direction]\">\n                    {{ item.name }}\n                </text>\n                <view\n                    class=\"u-steps__item__line\"\n                    :class=\"['u-steps__item__line--' + mode]\"\n                    v-if=\"index < list.length - 1\"\n                >\n                    <u-line :direction=\"direction\" length=\"100%\" :hair-line=\"false\" :color=\"unActiveColor\"></u-line>\n                </view>\n            </view> -->\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-steps',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, getCurrentInstance } from 'vue';\nimport { StepsProps } from './types';\nimport { $u, useParent } from '../..';\n\n/**\n * steps 步骤条\n * @description 该组件一般用于完成一个任务要分几个步骤，标识目前处于第几步的场景。\n * @tutorial https://uviewpro.cn/zh/components/steps.html\n * @property {String} mode 设置模式（默认dot）\n * @property {Array<{name: string}>} list 数轴条数据，数组。具体见上方示例\n * @property {String} type type主题（默认primary）\n * @property {String} direction row-横向，column-竖向（默认row）\n * @property {Number|String} current 设置当前处于第几步\n * @property {String} activeColor 已完成步骤的激活颜色，如设置，type值会失效\n * @property {String} unActiveColor 未激活的颜色，用于表示未完成步骤的颜色（默认var(--u-content-color)）\n * @property {String} icon 自定义图标\n * @example <u-steps :list=\"numList\" active-color=\"var(--u-type-error)\"></u-steps>\n */\n\nconst props = defineProps(StepsProps);\n\nconst { children } = useParent('u-steps');\n// 计算方向样式\nconst directionStyle = computed(() => ({ flexDirection: props.direction as 'row' | 'column' }));\n\ndefineExpose({\n    props,\n    childLen: () => children.length\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-steps {\n    @include vue-flex;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-sticky/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport zIndex from '../../libs/config/zIndex';\n\n/**\n * StickyProps 吸顶组件 props 类型定义\n * @description 吸顶组件，支持自定义吸顶距离、z-index、背景色等\n */\nexport const StickyProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 吸顶容器到顶部某个距离的时候，进行吸顶，在H5平台，NavigationBar为44px */\n    offsetTop: { type: [Number, String] as PropType<number | string>, default: 0 },\n    /** 列表中的索引值 */\n    index: { type: [Number, String] as PropType<number | string>, default: '' },\n    /** 是否开启吸顶功能 */\n    enable: { type: Boolean, default: true },\n    /** h5顶部导航栏的高度 */\n    h5NavHeight: { type: [Number, String] as PropType<number | string>, default: 44 },\n    /** 吸顶区域的背景颜色 */\n    bgColor: { type: String, default: 'var(--u-bg-white)' },\n    /** z-index值 */\n    zIndex: { type: [Number, String] as PropType<number | string>, default: zIndex.sticky }\n};\n\nexport type StickyProps = ExtractPropTypes<typeof StickyProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-sticky/u-sticky.vue",
    "content": "<template>\n    <view>\n        <view\n            class=\"u-sticky-wrap\"\n            :class=\"[elClass, customClass]\"\n            :style=\"\n                $u.toStyle(\n                    {\n                        height: fixed ? height + 'px' : 'auto',\n                        backgroundColor: bgColor\n                    },\n                    customStyle\n                )\n            \"\n        >\n            <view\n                class=\"u-sticky\"\n                :style=\"{\n                    position: fixed ? 'fixed' : 'static',\n                    top: stickyTop + 'px',\n                    left: left + 'px',\n                    width: width == 'auto' ? 'auto' : width + 'px',\n                    zIndex: uZIndex\n                }\"\n            >\n                <slot></slot>\n            </view>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-sticky',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, nextTick, onMounted, onBeforeUnmount, getCurrentInstance } from 'vue';\nimport { $u } from '../..';\nimport { StickyProps } from './types';\n\n/**\n * sticky 吸顶\n * @description 该组件与CSS中position: sticky属性实现的效果一致，当组件达到预设的到顶部距离时， 就会固定在指定位置，组件位置大于预设的顶部距离时，会重新按照正常的布局排列。\n * @tutorial https://uviewpro.cn/zh/components/sticky.html\n * @property {String|Number} offsetTop 吸顶时与顶部的距离，单位rpx（默认0）\n * @property {String|Number} index 自定义标识，用于区分是哪一个组件\n * @property {Boolean} enable 是否开启吸顶功能（默认true）\n * @property {String} bgColor 组件背景颜色（默认var(--u-bg-white)）\n * @property {String|Number} zIndex 吸顶时的z-index值（默认970）\n * @property {String|Number} h5NavHeight 导航栏高度，自定义导航栏时(无导航栏时需设置为0)，需要传入此值，单位px（默认44）\n * @event fixed 组件吸顶时触发\n * @event unfixed 组件取消吸顶时触发\n * @example <u-sticky offset-top=\"200\"><view>塞下秋来风景异，衡阳雁去无留意</view></u-sticky>\n */\nconst props = defineProps(StickyProps);\n\nconst emit = defineEmits(['fixed', 'unfixed']);\n\nconst instance = getCurrentInstance();\nconst fixed = ref(false);\nconst height = ref<'auto' | number>('auto');\nconst stickyTop = ref(0);\nconst elClass = ref('');\nconst left = ref(0);\nconst width = ref<'auto' | number>('auto');\nlet contentObserver: any = null;\n\nelClass.value = $u.guid();\n\nconst uZIndex = computed(() => (props.zIndex ? props.zIndex : ($u?.zIndex?.sticky ?? 970)));\n\nwatch(\n    () => props.offsetTop,\n    () => {\n        initObserver();\n    }\n);\n\nwatch(\n    () => props.enable,\n    val => {\n        if (val == false) {\n            fixed.value = false;\n            disconnectObserver('contentObserver');\n        } else {\n            initObserver();\n        }\n    }\n);\n\nonMounted(() => {\n    initObserver();\n});\n\nonBeforeUnmount(() => {\n    disconnectObserver('contentObserver');\n});\n\n/**\n * 初始化 IntersectionObserver 监听\n */\nfunction initObserver() {\n    if (!props.enable) return;\n    // #ifdef H5\n    stickyTop.value =\n        Number(props.offsetTop) !== 0\n            ? uni.upx2px(Number(props.offsetTop)) + Number(props.h5NavHeight)\n            : Number(props.h5NavHeight);\n    // #endif\n    // #ifndef H5\n    stickyTop.value = Number(props.offsetTop) !== 0 ? uni.upx2px(Number(props.offsetTop)) : 0;\n    // #endif\n    disconnectObserver('contentObserver');\n    $u.getRect('.' + elClass.value, instance).then((res: any) => {\n        height.value = res.height;\n        left.value = res.left;\n        width.value = res.width;\n        nextTick(() => {\n            observeContent();\n        });\n    });\n}\n\n/**\n * 创建 IntersectionObserver 监听内容区域\n */\nfunction observeContent() {\n    disconnectObserver('contentObserver');\n\n    contentObserver = uni.createIntersectionObserver(instance?.proxy, {\n        thresholds: [0.95, 0.98, 1]\n    });\n    contentObserver.relativeToViewport({\n        top: -stickyTop.value\n    });\n    contentObserver.observe('.' + elClass.value, (res: any) => {\n        if (!props.enable) return;\n        setFixed(res.boundingClientRect.top);\n    });\n}\n\n/**\n * 设置 fixed 状态\n */\nfunction setFixed(top: number) {\n    const isFixed = top < stickyTop.value;\n    if (isFixed) emit('fixed', props.index);\n    else if (fixed.value) emit('unfixed', props.index);\n    fixed.value = isFixed;\n}\n\n/**\n * 断开 observer\n */\nfunction disconnectObserver(observerName: string) {\n    if (observerName === 'contentObserver' && contentObserver) {\n        contentObserver.disconnect();\n        contentObserver = null;\n    }\n}\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n.u-sticky {\n    z-index: 9999999999;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-subsection/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { SubsectionListItem, SubsectionMode } from '../../types/global';\n\n/**\n * SubsectionProps 分段器 props 类型定义\n * @description 分段器，支持按钮/分段模式、动画、颜色等\n */\n\nexport const SubsectionProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** tab的数据 */\n    list: { type: Array as PropType<Array<string | SubsectionListItem>>, default: () => [] },\n    /** 当前活动的tab的index */\n    current: { type: [Number, String] as PropType<number | string>, default: 0 },\n    /** 激活的颜色 */\n    activeColor: { type: String, default: 'var(--u-main-color)' },\n    /** 未激活的颜色 */\n    inactiveColor: { type: String, default: 'var(--u-content-color)' },\n    /** 模式选择，mode=button为按钮形式，mode=subsection时为分段模式 */\n    mode: { type: String as PropType<SubsectionMode>, default: 'button' },\n    /** 字体大小，单位rpx */\n    fontSize: { type: [Number, String] as PropType<number | string>, default: 28 },\n    /** 是否开启动画效果 */\n    animation: { type: Boolean, default: true },\n    /** 组件的高度，单位rpx */\n    height: { type: [Number, String] as PropType<number | string>, default: 70 },\n    /** 激活tab的字体是否加粗 */\n    bold: { type: Boolean, default: true },\n    /** mode=button时，组件背景颜色 */\n    bgColor: { type: String, default: 'var(--u-divider-color)' },\n    /** mode = button时，滑块背景颜色 */\n    buttonColor: { type: String, default: 'var(--u-bg-white)' },\n    /** 在切换分段器的时候，是否让设备震一下 */\n    vibrateShort: { type: Boolean, default: false }\n};\n\nexport type SubsectionProps = ExtractPropTypes<typeof SubsectionProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-subsection/u-subsection.vue",
    "content": "<template>\n    <view :id=\"instanceId\" class=\"u-subsection\" :class=\"customClass\" :style=\"$u.toStyle(subsectionStyle, customStyle)\">\n        <view\n            class=\"u-item u-line-1\"\n            :style=\"itemStyle(index)\"\n            @tap=\"click(index)\"\n            :class=\"[noBorderRight(index), `u-item-${index}`]\"\n            v-for=\"(item, index) in listInfo\"\n            :key=\"index\"\n        >\n            <view :style=\"textStyle(index)\" class=\"u-item-text u-line-1\">{{ item.name }}</view>\n        </view>\n        <view class=\"u-item-bg\" :style=\"itemBarStyle\"></view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-subsection',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, getCurrentInstance, nextTick } from 'vue';\nimport { $u } from '../..';\nimport { SubsectionProps } from './types';\n\n/**\n * subsection 分段器\n * @description 该分段器一般用于用户从几个选项中选择某一个的场景\n * @tutorial https://uviewpro.cn/zh/components/subsection.html\n * @property {Array} list 选项的数组，形式见上方\"基本使用\"\n * @property {String | Number} current 初始化时默认选中的选项索引值（默认0）\n * @property {String} activeColor 激活时的颜色，mode为subsection时固定为白色（默认var(--u-main-color)）\n * @property {String} inactiveColor 未激活时字体的颜色，mode为subsection时无效（默认var(--u-content-color)）\n * @property {String} mode 模式选择，见官网\"模式选择\"说明（默认button）\n * @property {String | Number} fontSize 字体大小，单位rpx（默认28）\n * @property {String | Number} height 组件高度，单位rpx（默认70）\n * @property {Boolean} animation 是否开启动画效果，见上方说明（默认true）\n * @property {Boolean} bold 激活选项的字体是否加粗（默认true）\n * @property {String} bgColor 组件背景颜色，mode为button时有效（默认var(--u-divider-color)）\n * @property {String} buttonColor 按钮背景颜色，mode为button时有效（默认var(--u-bg-white)）\n * @property {Boolean} vibrateShort 在切换分段器的时候，是否让设备震一下（默认false）\n * @event {Function} change 分段器选项发生改变时触发\n * @example <u-subsection active-color=\"var(--u-type-warning)\"></u-subsection>\n */\n\ninterface ListItem {\n    name: string;\n    width?: number;\n    [key: string]: any;\n}\n\nconst props = defineProps(SubsectionProps);\n\nconst emit = defineEmits<{ (e: 'change', index: number): void }>();\n\n// 组件内部状态\nconst listInfo = ref<ListItem[]>([]);\nconst itemBgStyle = ref<{ [key: string]: any }>({\n    width: 0,\n    left: 0,\n    backgroundColor: 'var(--u-bg-white)',\n    height: '100%',\n    transition: ''\n});\nconst currentIndex = ref(Number(props.current));\nconst buttonPadding = 3; // mode = button 时，组件的内边距\nconst borderRadius = 5; // 圆角值\nconst firstTimeVibrateShort = ref(true); // 组件初始化时，会触发current变化，此时不应震动\nconst instanceId = $u.guid(); // 组件唯一 id\nconst instance = getCurrentInstance();\n\n// 监听 current 变化\nwatch(\n    () => props.current,\n    nVal => {\n        currentIndex.value = Number(nVal);\n        changeSectionStatus(currentIndex.value);\n    },\n    { immediate: true }\n);\n\nwatch(\n    () => props.list,\n    () => {\n        if (!props.list || !props.list.length) return;\n        initListInfo();\n        // 重新获取各个tab的宽度信息\n        nextTick(() => {\n            setTimeout(() => {\n                getTabsInfo();\n            }, 10);\n        });\n    },\n    { deep: true, immediate: true }\n);\n\nwatch(\n    () => props.mode,\n    () => {\n        // 重新获取各个tab的宽度信息\n        nextTick(() => {\n            setTimeout(() => {\n                getTabsInfo();\n            }, 10);\n        });\n    }\n);\n\n// 初始化 listInfo\nfunction initListInfo() {\n    // 将list的数据，传入listInfo数组，因为不能修改props传递的list值\n    // 可以接受直接数组形式，或者数组元素为对象的形式，如：['简介', '评论'],或者[{name: '简介'}, {name: '评论'}]\n    listInfo.value = props.list.map(val => {\n        if (typeof val !== 'object') {\n            return { width: 0, name: val };\n        } else {\n            return { ...val, width: 0 };\n        }\n    });\n}\n\n/**\n * 设置mode=subsection时，滑块特有的样式\n */\nconst noBorderRight = computed<(index: number) => string>(() => {\n    return (index: number) => {\n        if (props.mode !== 'subsection') return '';\n        let classs = '';\n        // 不显示右边的边框\n        if (index < props.list.length - 1) classs += ' u-none-border-right';\n        // 显示整个组件的左右边圆角\n        if (index === 0) classs += ' u-item-first';\n        if (index === props.list.length - 1) classs += ' u-item-last';\n        return classs;\n    };\n});\n\n/**\n * 文字的样式\n */\nconst textStyle = computed<(index: number) => Record<string, any>>(() => {\n    return (index: number) => {\n        const style: Record<string, any> = {};\n        // 设置字体颜色\n        if (props.mode === 'subsection') {\n            style.color = index === currentIndex.value ? 'var(--u-white-color)' : props.activeColor;\n        } else {\n            style.color = index === currentIndex.value ? props.activeColor : props.inactiveColor;\n        }\n        // 字体加粗\n        if (index === currentIndex.value && props.bold) style.fontWeight = 'bold';\n        // 文字大小\n        style.fontSize = props.fontSize + 'rpx';\n        return style;\n    };\n});\n\n/**\n * 每个分段器item的样式\n */\nconst itemStyle = computed<(index: number) => Record<string, any>>(() => {\n    return (index: number) => {\n        const style: Record<string, any> = {};\n        if (props.mode === 'subsection') {\n            style.borderColor = props.activeColor;\n            style.borderWidth = '1px';\n            style.borderStyle = 'solid';\n        }\n        return style;\n    };\n});\n\n/**\n * mode=button时，外层view的样式\n */\nconst subsectionStyle = computed<Record<string, any>>(() => {\n    const style: Record<string, any> = {};\n    style.height = uni.upx2px(Number(props.height)) + 'px';\n    if (props.mode === 'button') {\n        style.backgroundColor = props.bgColor;\n        style.padding = `${buttonPadding}px`;\n        style.borderRadius = `${borderRadius}px`;\n    }\n    return style;\n});\n\n/**\n * 滑块的样式\n */\nconst itemBarStyle = computed<Record<string, any>>(() => {\n    const style: Record<string, any> = {};\n    style.backgroundColor = props.activeColor;\n    style.zIndex = 1;\n    if (props.mode === 'button') {\n        style.backgroundColor = props.buttonColor;\n        style.borderRadius = `${borderRadius}px`;\n        style.bottom = `${buttonPadding}px`;\n        style.height = uni.upx2px(Number(props.height)) - buttonPadding * 2 + 'px';\n        style.zIndex = 0;\n    }\n    return Object.assign({}, itemBgStyle.value, style);\n});\n\n/**\n * 改变滑块的样式\n * @param nVal 当前选中索引\n */\nfunction changeSectionStatus(nVal: number) {\n    if (props.mode === 'subsection') {\n        // 根据滑块在最左边和最右边时，显示左边和右边的圆角\n        if (nVal === props.list.length - 1) {\n            itemBgStyle.value.borderRadius = `0 ${buttonPadding}px ${buttonPadding}px 0`;\n        }\n        if (nVal === 0) {\n            itemBgStyle.value.borderRadius = `${buttonPadding}px 0 0 ${buttonPadding}px`;\n        }\n        if (nVal > 0 && nVal < props.list.length - 1) {\n            itemBgStyle.value.borderRadius = '0';\n        }\n    }\n    // 更新滑块的位置\n    setTimeout(() => {\n        itemBgLeft();\n    }, 10);\n    if (props.vibrateShort && !firstTimeVibrateShort.value) {\n        // 使手机产生短促震动，微信小程序有效，APP(HX 2.6.8)和H5无效\n        // #ifndef H5\n        uni.vibrateShort();\n        // #endif\n    }\n    // 第一次过后，设置firstTimeVibrateShort为false，让其下一次可以震动(如果允许震动的话)\n    firstTimeVibrateShort.value = false;\n}\n\n/**\n * 点击分段器选项\n * @param index 当前点击索引\n */\nfunction click(index: number) {\n    // 不允许点击当前激活选项\n    if (index === currentIndex.value) return;\n    currentIndex.value = index;\n    changeSectionStatus(index);\n    emit('change', index);\n}\n\n/**\n * 获取各个tab的节点信息\n */\nfunction getTabsInfo() {\n    const view = uni.createSelectorQuery().in(instance?.proxy);\n    for (let i = 0; i < props.list.length; i++) {\n        view.select(`#${instanceId} .u-item-${i}`).boundingClientRect();\n    }\n    view.exec((res: any[]) => {\n        if (!res.length) {\n            setTimeout(() => {\n                getTabsInfo();\n                return;\n            }, 10);\n        }\n        // 将分段器每个item的宽度，放入listInfo数组\n        res.map((val, index) => {\n            listInfo.value[index].width = val.width;\n        });\n        // 初始化滑块的宽度\n        if (props.mode === 'subsection' || props.mode === 'button') {\n            itemBgStyle.value.width = listInfo.value[0]?.width + 'px';\n        }\n        // 初始化滑块的位置\n        itemBgLeft();\n    });\n}\n\n/**\n * 计算滑块左侧距离\n */\nfunction itemBgLeft() {\n    // 根据是否开启动画效果\n    if (props.animation) {\n        itemBgStyle.value.transition = 'all 0.35s';\n    } else {\n        itemBgStyle.value.transition = 'all 0s';\n    }\n    let left = 0;\n    // 计算当前活跃item到组件左边的距离\n    listInfo.value.forEach((val, index) => {\n        if (index < currentIndex.value) left += val.width ?? 0;\n    });\n    // 根据mode不同模式，计算滑块需要移动的距离\n    if (props.mode === 'subsection') {\n        itemBgStyle.value.left = left + 'px';\n    } else if (props.mode === 'button') {\n        itemBgStyle.value.left = left + buttonPadding + 'px';\n    }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-subsection {\n    @include vue-flex;\n    align-items: center;\n    overflow: hidden;\n    position: relative;\n}\n\n.u-item {\n    flex: 1;\n    text-align: center;\n    font-size: 26rpx;\n    height: 100%;\n    @include vue-flex;\n    align-items: center;\n    justify-content: center;\n    color: $u-main-color;\n    padding: 0 6rpx;\n}\n\n.u-item-bg {\n    background-color: $u-type-primary;\n    position: absolute;\n    z-index: -1;\n}\n\n.u-none-border-right {\n    border-right: none !important;\n}\n\n.u-item-first {\n    border-top-left-radius: 8rpx;\n    border-bottom-left-radius: 8rpx;\n}\n\n.u-item-last {\n    border-top-right-radius: 8rpx;\n    border-bottom-right-radius: 8rpx;\n}\n\n.u-item-text {\n    transition: all 0.35s;\n    color: $u-main-color;\n    @include vue-flex;\n    align-items: center;\n    position: relative;\n    z-index: 3;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-swipe-action/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { SwipeActionOption } from '../../types/global';\n\n/**\n * swipeAction 左滑单元格 props 类型定义\n * @description 该组件一般用于左滑唤出操作菜单的场景，用的最多的是左滑删除操作。\n */\n\nexport const SwipeActionProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** index值，用于得知点击删除的是哪个按钮 */\n    index: {\n        type: [Number, String] as PropType<string | number>,\n        default: ''\n    },\n    /** 滑动按钮的宽度，单位为rpx */\n    btnWidth: {\n        type: [String, Number] as PropType<string | number>,\n        default: 180\n    },\n    /** 是否禁止某个action滑动 */\n    disabled: {\n        type: Boolean,\n        default: false\n    },\n    /** 打开或者关闭组件 */\n    show: {\n        type: Boolean,\n        default: false\n    },\n    /** 组件背景颜色 */\n    bgColor: {\n        type: String,\n        default: 'var(--u-bg-white)'\n    },\n    /** 是否使手机发生短促震动，目前只在iOS的微信小程序有效(2020-05-06) */\n    vibrateShort: {\n        type: Boolean,\n        default: false\n    },\n    /** 按钮操作参数 */\n    options: {\n        type: Array as PropType<SwipeActionOption[]>,\n        default: () => []\n    }\n};\n\n/**\n * swipeAction 组件 props 类型\n */\nexport type SwipeActionProps = ExtractPropTypes<typeof SwipeActionProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-swipe-action/u-swipe-action.vue",
    "content": "<template>\n    <view>\n        <movable-area\n            class=\"u-swipe-action\"\n            :style=\"$u.toStyle({ backgroundColor: props.bgColor }, customStyle)\"\n            :class=\"customClass\"\n            :id=\"elId\"\n        >\n            <movable-view\n                class=\"u-swipe-view\"\n                @change=\"change\"\n                @touchend=\"touchend\"\n                @touchstart=\"touchstart\"\n                direction=\"horizontal\"\n                :disabled=\"props.disabled\"\n                :inertia=\"true\"\n                :x=\"moveX\"\n                :style=\"{ width: movableViewWidth ? movableViewWidth : '100%' }\"\n            >\n                <view class=\"u-swipe-content\" @tap.stop=\"contentClick\">\n                    <slot></slot>\n                </view>\n                <view\n                    class=\"u-swipe-del\"\n                    v-if=\"showBtn\"\n                    @tap.stop=\"btnClick(index)\"\n                    :style=\"btnStyle(item.style)\"\n                    v-for=\"(item, index) in props.options\"\n                    :key=\"index\"\n                >\n                    <view class=\"u-btn-text\">{{ item.text }}</view>\n                </view>\n            </movable-view>\n        </movable-area>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-swipe-action',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script lang=\"ts\" setup>\nimport { ref, computed, watch, nextTick, onMounted } from 'vue';\nimport { $u } from '../..';\nimport { SwipeActionProps } from './types';\n\n/**\n * swipeAction 左滑单元格\n * @description 该组件一般用于左滑唤出操作菜单的场景，用的最多的是左滑删除操作。\n * @tutorial https://uviewpro.cn/zh/components/swipeAction.html\n * @property {String} bg-color 整个组件背景颜色（默认var(--u-bg-white)）\n * @property {Array} options 数组形式，可以配置背景颜色和文字\n * @property {String|Number} index 标识符，点击时候用于区分点击了哪一个，用v-for循环时的index即可\n * @property {String|Number} btn-width 按钮宽度，单位rpx（默认180）\n * @property {Boolean} disabled 是否禁止某个swipeAction滑动（默认false）\n * @property {Boolean} show 打开或者关闭某个组件（默认false）\n * @event {Function} click 点击组件时触发\n * @event {Function} close 组件触发关闭状态时\n * @event {Function} content-click 点击内容时触发\n * @event {Function} open 组件触发打开状态时\n * @example <u-swipe-action btn-text=\"收藏\">...</u-swipe-action>\n */\nconst props = defineProps(SwipeActionProps);\nconst emit = defineEmits(['click', 'close', 'content-click', 'open']);\n\n// 组件内部状态\nconst moveX = ref(0); // movable-view元素在x轴上需要移动的目标移动距离，用于展开或收起滑动的按钮\nconst scrollX = ref(0); // movable-view移动过程中产生的change事件中的x轴移动值\nconst status = ref(false); // 滑动的状态，表示当前是展开还是关闭按钮的状态\nconst movableAreaWidth = ref(0); // 滑动区域\nconst elId = ref($u.guid()); // id，用于通知另外组件关闭时的识别\nconst showBtn = ref(false); // 刚开始渲染视图时不显示右边的按钮，避免视图闪动\n\n// 计算属性\nconst movableViewWidth = computed(() => {\n    return movableAreaWidth.value + allBtnWidth.value + 'px';\n});\nconst innerBtnWidth = computed(() => {\n    // 保证类型安全，btnWidth 转为 number\n    return uni.upx2px(Number(props.btnWidth));\n});\nconst allBtnWidth = computed(() => {\n    return uni.upx2px(Number(props.btnWidth)) * props.options.length;\n});\nconst btnStyle = (style: Record<string, any> = {}) => {\n    // 按钮样式处理\n    style.width = props.btnWidth + 'rpx';\n    return style;\n};\n\n// 监听 show 属性变化，控制展开/收起\nwatch(\n    () => props.show,\n    nVal => {\n        if (nVal) {\n            open();\n        } else {\n            close();\n        }\n    },\n    { immediate: true, deep: true }\n);\n\n// 生命周期\nonMounted(() => {\n    getActionRect();\n});\n\n/**\n * 点击按钮\n * @param index 当前按钮索引\n */\nfunction btnClick(index: number) {\n    status.value = false;\n    // this.index为点击的几个组件，index为点击某个组件的第几个按钮(options数组的索引)\n    emit('click', props.index, index);\n}\n\n/**\n * movable-view元素移动事件\n */\nfunction change(e: { detail: { x: number } }) {\n    scrollX.value = e.detail.x;\n}\n\n/**\n * 关闭按钮状态\n */\nfunction close() {\n    moveX.value = 0;\n    status.value = false;\n}\n\n/**\n * 打开按钮的状态\n */\nfunction open() {\n    if (props.disabled) return;\n    moveX.value = -allBtnWidth.value;\n    status.value = true;\n}\n\n/**\n * 用户手指离开movable-view元素，停止触摸\n */\nfunction touchend() {\n    moveX.value = scrollX.value;\n    // 停止触摸时候，判断当前是展开还是关闭状态\n    // 关闭状态\n    // 这一步很重要，需要先给moveX一个变化的随机值，否则因为前后设置的为同一个值\n    // props单向数据流的原因，导致movable-view元素不会发生变化，切记，详见文档：\n    // https://uniapp.dcloud.io/use?id=%e5%b8%b8%e8%a7%81%e9%97%ae%e9%a2%98\n    // https://uniapp.dcloud.net.cn/tutorial/vue-api.html#componentsolutions\n    nextTick(() => {\n        if (status.value == false) {\n            // 关闭状态左滑，产生的x轴位移为负值，也就是说滑动的距离大于按钮的四分之一宽度，自动展开按钮\n            if (scrollX.value <= -allBtnWidth.value / 4) {\n                moveX.value = -allBtnWidth.value; // 按钮宽度的负值，即为展开状态movable-view元素左滑的距离\n                status.value = true; // 标志当前为展开状态\n                emitOpenEvent();\n                // 产生震动效果\n                if (props.vibrateShort) uni.vibrateShort();\n            } else {\n                moveX.value = 0; // 如果距离没有按钮宽度的四分之一，自动收起\n                status.value = false;\n                emitCloseEvent();\n            }\n        } else {\n            // 如果在打开的状态下，右滑动的距离X轴偏移超过按钮的四分之一(负值反过来的四分之三)，自动收起按钮\n            if (scrollX.value > (-allBtnWidth.value * 3) / 4) {\n                moveX.value = 0;\n                nextTick(() => {\n                    moveX.value = 101;\n                });\n                status.value = false;\n                emitCloseEvent();\n            } else {\n                moveX.value = -allBtnWidth.value;\n                status.value = true;\n                emitOpenEvent();\n            }\n        }\n    });\n}\n\n/**\n * 触发 open 事件\n */\nfunction emitOpenEvent() {\n    emit('open', props.index);\n}\n\n/**\n * 触发 close 事件\n */\nfunction emitCloseEvent() {\n    emit('close', props.index);\n}\n\n/**\n * 开始触摸\n */\nfunction touchstart() {\n    // ...可扩展触摸逻辑\n}\n\n/**\n * 获取滑动区域宽度\n */\nfunction getActionRect() {\n    $u.getRect('.u-swipe-action').then((res: { width: number }) => {\n        // 解决使用u-swipe-action右边会出现一条背景线的bug，增加 1 像素\n        movableAreaWidth.value = res.width + 1;\n        // 等视图更新完后，再显示右边的可滑动按钮，防止这些按钮会\"闪一下\"\n        nextTick(() => {\n            showBtn.value = true;\n        });\n    });\n}\n\n/**\n * 点击内容触发事件\n */\nfunction contentClick() {\n    // 点击内容时，如果当前为打开状态，收起组件\n    if (status.value == true) {\n        status.value = false;\n        moveX.value = 0;\n    }\n    emit('content-click', props.index);\n}\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n\n.u-swipe-action {\n    width: auto;\n    height: initial;\n    position: relative;\n    overflow: hidden;\n}\n\n.u-swipe-view {\n    @include vue-flex;\n    height: initial;\n    position: relative;\n    /* 这一句很关键，覆盖默认的绝对定位 */\n}\n\n.u-swipe-content {\n    flex: 1;\n}\n\n.u-swipe-del {\n    position: relative;\n    font-size: 30rpx;\n    color: var(--u-white-color);\n}\n\n.u-btn-text {\n    position: absolute;\n    top: 50%;\n    left: 50%;\n    transform: translate(-50%, -50%);\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-swiper/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { ImgMode, SwiperIndicatorPosition, SwiperMode } from '../../types/global';\n\n/**\n * SwiperProps 轮播图 props 类型定义\n * @description 轮播图，支持多种指示器、3D、自动播放等\n */\nexport const SwiperProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 轮播数据列表，数组对象 */\n    list: { type: Array as PropType<Array<Record<string, any>>>, default: () => [] },\n    /** 是否显示标题 */\n    title: { type: Boolean, default: false },\n    /** 指示器配置对象 */\n    indicator: { type: Object as PropType<Record<string, any>>, default: () => ({}) },\n    /** 圆角，单位rpx */\n    borderRadius: { type: [Number, String] as PropType<number | string>, default: 8 },\n    /** 自动切换时间间隔，单位ms */\n    interval: { type: [String, Number] as PropType<number | string>, default: 3000 },\n    /** 指示器类型，round/dot/line等 */\n    mode: { type: String as PropType<SwiperMode>, default: 'round' },\n    /** 轮播高度，单位rpx */\n    height: { type: [Number, String] as PropType<number | string>, default: 250 },\n    /** 指示器位置 */\n    indicatorPos: { type: String as PropType<SwiperIndicatorPosition>, default: 'bottomCenter' },\n    /** 是否开启3D效果 */\n    effect3d: { type: Boolean, default: false },\n    /** 3D模式下前一项的边距，单位rpx */\n    effect3dPreviousMargin: { type: [Number, String] as PropType<number | string>, default: 50 },\n    /** 是否自动播放 */\n    autoplay: { type: Boolean, default: true },\n    /** 切换动画时长，单位ms */\n    duration: { type: [Number, String] as PropType<number | string>, default: 500 },\n    /** 是否循环播放 */\n    circular: { type: Boolean, default: true },\n    /** 图片裁剪模式 */\n    imgMode: { type: String as PropType<ImgMode>, default: 'aspectFill' },\n    /** 轮播项对象的图片字段名 */\n    name: { type: String, default: 'image' },\n    /** 轮播背景色 */\n    bgColor: { type: String, default: 'var(--u-bg-color)' },\n    /** 当前激活项索引 */\n    current: { type: [Number, String] as PropType<number | string>, default: 0 },\n    /** 标题样式对象 */\n    titleStyle: { type: Object as PropType<Record<string, any>>, default: () => ({}) }\n};\n\nexport type SwiperProps = ExtractPropTypes<typeof SwiperProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-swiper/u-swiper.vue",
    "content": "<template>\n    <view\n        class=\"u-swiper-wrap\"\n        :style=\"$u.toStyle({ borderRadius: `${borderRadius}rpx` }, customStyle)\"\n        :class=\"customClass\"\n    >\n        <swiper\n            :current=\"elCurrent\"\n            @change=\"change\"\n            @animationfinish=\"animationfinish\"\n            :interval=\"interval\"\n            :circular=\"circular\"\n            :duration=\"duration\"\n            :autoplay=\"autoplay\"\n            :previous-margin=\"effect3d ? effect3dPreviousMargin + 'rpx' : '0'\"\n            :next-margin=\"effect3d ? effect3dPreviousMargin + 'rpx' : '0'\"\n            :style=\"{ height: height + 'rpx', backgroundColor: bgColor }\"\n        >\n            <swiper-item class=\"u-swiper-item\" v-for=\"(item, index) in list\" :key=\"index\">\n                <view\n                    class=\"u-list-image-wrap\"\n                    @tap.stop.prevent=\"listClick(index)\"\n                    :class=\"[uCurrent != index ? 'u-list-scale' : '']\"\n                    :style=\"{\n                        borderRadius: `${borderRadius}rpx`,\n                        transform: effect3d && uCurrent != index ? 'scaleY(0.9)' : 'scaleY(1)',\n                        margin: effect3d && uCurrent != index ? '0 20rpx' : 0\n                    }\"\n                >\n                    <image class=\"u-swiper-image\" :src=\"item[name] || item\" :mode=\"imgMode\"></image>\n                    <view\n                        v-if=\"title && item.title\"\n                        class=\"u-swiper-title u-line-1\"\n                        :style=\"[{ 'padding-bottom': titlePaddingBottom }, titleStyle]\"\n                    >\n                        {{ item.title }}\n                    </view>\n                </view>\n            </swiper-item>\n        </swiper>\n        <view\n            class=\"u-swiper-indicator\"\n            :style=\"{\n                top:\n                    indicatorPos == 'topLeft' || indicatorPos == 'topCenter' || indicatorPos == 'topRight'\n                        ? '12rpx'\n                        : 'auto',\n                bottom:\n                    indicatorPos == 'bottomLeft' || indicatorPos == 'bottomCenter' || indicatorPos == 'bottomRight'\n                        ? '12rpx'\n                        : 'auto',\n                justifyContent: justifyContent,\n                padding: `0 ${effect3d ? '74rpx' : '24rpx'}`\n            }\"\n        >\n            <block v-if=\"mode == 'rect'\">\n                <view\n                    class=\"u-indicator-item-rect\"\n                    :class=\"{ 'u-indicator-item-rect-active': index == uCurrent }\"\n                    v-for=\"(item, index) in list\"\n                    :key=\"index\"\n                ></view>\n            </block>\n            <block v-if=\"mode == 'dot'\">\n                <view\n                    class=\"u-indicator-item-dot\"\n                    :class=\"{ 'u-indicator-item-dot-active': index == uCurrent }\"\n                    v-for=\"(item, index) in list\"\n                    :key=\"index\"\n                ></view>\n            </block>\n            <block v-if=\"mode == 'round'\">\n                <view\n                    class=\"u-indicator-item-round\"\n                    :class=\"{ 'u-indicator-item-round-active': index == uCurrent }\"\n                    v-for=\"(item, index) in list\"\n                    :key=\"index\"\n                ></view>\n            </block>\n            <block v-if=\"mode == 'number'\">\n                <view class=\"u-indicator-item-number\">{{ uCurrent + 1 }}/{{ list.length }}</view>\n            </block>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-swiper',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch } from 'vue';\nimport { SwiperProps } from './types';\nimport { $u } from '../..';\n\n/**\n * swiper 轮播图\n * @description 该组件一般用于导航轮播，广告展示等场景,可开箱即用\n * @tutorial https://uviewpro.cn/zh/components/swiper.html\n * @property {Array} list 轮播图数据，见官网\"基本使用\"说明\n * @property {Boolean} title 是否显示标题文字，需要配合list参数，见官网说明（默认false）\n * @property {String} mode 指示器模式，见官网说明（默认round）\n * @property {String|Number} height 轮播图组件高度，单位rpx（默认250）\n * @property {String} indicator-pos 指示器的位置（默认bottomCenter）\n * @property {Boolean} effect3d 是否开启3D效果（默认false）\n * @property {Boolean} autoplay 是否自动播放（默认true）\n * @property {String|Number} interval 自动轮播时间间隔，单位ms（默认2500）\n * @property {Boolean} circular 是否衔接播放，见官网说明（默认true）\n * @property {String} bg-color 背景颜色（默认var(--u-bg-color)）\n * @property {String|Number} border-radius 轮播图圆角值，单位rpx（默认8）\n * @property {Object} title-style 自定义标题样式\n * @property {String|Number} effect3d-previous-margin mode = true模式的情况下，激活项与前后项之间的距离，单位rpx（默认50）\n * @property {String} img-mode 图片的裁剪模式，详见image组件裁剪模式（默认aspectFill）\n * @event {Function} click 点击轮播图时触发\n * @example <u-swiper :list=\"list\" mode=\"dot\" indicator-pos=\"bottomRight\"></u-swiper>\n */\n\nconst props = defineProps(SwiperProps);\nconst emit = defineEmits(['click', 'change']);\n\n// 当前活跃的swiper-item的index\nconst uCurrent = ref(Number(props.current));\n\n// 监听list变化，重置uCurrent值，避免溢出\nwatch(\n    () => props.list,\n    (nVal, oVal) => {\n        if (nVal.length !== oVal.length) uCurrent.value = 0;\n    }\n);\n// 监听外部current的变化，实时修改内部依赖于此测uCurrent值\nwatch(\n    () => props.current,\n    n => {\n        uCurrent.value = Number(n);\n    }\n);\n\n// 容器 justifyContent\nconst justifyContent = computed(() => {\n    if (props.indicatorPos == 'topLeft' || props.indicatorPos == 'bottomLeft') return 'flex-start';\n    if (props.indicatorPos == 'topCenter' || props.indicatorPos == 'bottomCenter') return 'center';\n    if (props.indicatorPos == 'topRight' || props.indicatorPos == 'bottomRight') return 'flex-end';\n    return 'center';\n});\n\n// 标题下边距\nconst titlePaddingBottom = computed(() => {\n    if (props.mode == 'none') return '12rpx';\n    if (['bottomLeft', 'bottomCenter', 'bottomRight'].includes(props.indicatorPos) && props.mode == 'number') {\n        return '60rpx';\n    } else if (['bottomLeft', 'bottomCenter', 'bottomRight'].includes(props.indicatorPos) && props.mode != 'number') {\n        return '40rpx';\n    } else {\n        return '12rpx';\n    }\n});\n\n// swiper组件current参数只接受Number类型\nconst elCurrent = computed(() => Number(props.current));\n\n/**\n * 点击轮播图项\n */\nfunction listClick(index: number) {\n    emit('click', index);\n}\n\n/**\n * swiper change事件\n */\nfunction change(e: any) {\n    const current = e.detail.current;\n    uCurrent.value = current;\n    emit('change', current);\n}\n\n/**\n * swiper animationfinish事件\n * 头条小程序不支持animationfinish事件，改由change事件\n * 暂不监听此事件，因为不再给swiper绑定uCurrent属性\n */\nfunction animationfinish(e: any) {\n    // #ifndef MP-TOUTIAO\n    // uCurrent.value = e.detail.current\n    // #endif\n}\n\ndefineExpose({ listClick, change, animationfinish });\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-swiper-wrap {\n    position: relative;\n    overflow: hidden;\n    transform: translateY(0);\n}\n\n.u-swiper-image {\n    width: 100%;\n    will-change: transform;\n    height: 100%;\n    /* #ifndef APP-NVUE */\n    display: block;\n    /* #endif */\n    /* #ifdef H5 */\n    pointer-events: none;\n    /* #endif */\n}\n\n.u-swiper-indicator {\n    padding: 0 24rpx;\n    position: absolute;\n    @include vue-flex;\n    width: 100%;\n    z-index: 1;\n}\n\n.u-indicator-item-rect {\n    width: 26rpx;\n    height: 8rpx;\n    margin: 0 6rpx;\n    transition: all 0.5s;\n    background-color: rgba(0, 0, 0, 0.3);\n}\n\n.u-indicator-item-rect-active {\n    background-color: rgba(255, 255, 255, 0.8);\n}\n\n.u-indicator-item-dot {\n    width: 14rpx;\n    height: 14rpx;\n    margin: 0 6rpx;\n    border-radius: 20rpx;\n    transition: all 0.5s;\n    background-color: rgba(0, 0, 0, 0.3);\n}\n\n.u-indicator-item-dot-active {\n    background-color: rgba(255, 255, 255, 0.8);\n}\n\n.u-indicator-item-round {\n    width: 14rpx;\n    height: 14rpx;\n    margin: 0 6rpx;\n    border-radius: 20rpx;\n    transition: all 0.5s;\n    background-color: rgba(0, 0, 0, 0.3);\n}\n\n.u-indicator-item-round-active {\n    width: 34rpx;\n    background-color: rgba(255, 255, 255, 0.8);\n}\n\n.u-indicator-item-number {\n    padding: 6rpx 16rpx;\n    line-height: 1;\n    background-color: rgba(0, 0, 0, 0.3);\n    border-radius: 100rpx;\n    font-size: 26rpx;\n    color: rgba(255, 255, 255, 0.8);\n}\n\n.u-list-scale {\n    transform-origin: center center;\n}\n\n.u-list-image-wrap {\n    width: 100%;\n    height: 100%;\n    flex: 1;\n    transition: all 0.5s;\n    overflow: hidden;\n    box-sizing: content-box;\n    position: relative;\n}\n\n.u-swiper-title {\n    position: absolute;\n    background-color: rgba(0, 0, 0, 0.3);\n    bottom: 0;\n    left: 0;\n    width: 100%;\n    font-size: 28rpx;\n    padding: 12rpx 24rpx;\n    color: rgba(255, 255, 255, 0.9);\n}\n\n.u-swiper-item {\n    @include vue-flex;\n    overflow: hidden;\n    align-items: center;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-switch/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { SizeType } from '../../types/global';\n\n/**\n * SwitchProps 开关选择器 props 类型定义\n * @description 选择开关，支持自定义颜色、尺寸、值等\n */\nexport const SwitchProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 是否显示加载中状态 */\n    loading: { type: Boolean, default: false },\n    /** 是否禁用 */\n    disabled: { type: Boolean, default: false },\n    /** 开关尺寸，单位rpx */\n    size: { type: [Number, String] as PropType<number | string | SizeType>, default: '' },\n    /** 打开时的颜色 */\n    activeColor: { type: String, default: 'var(--u-type-primary)' },\n    /** 关闭时的颜色 */\n    inactiveColor: { type: String, default: 'var(--u-white-color)' },\n    /** v-model 绑定值，开关状态值 */\n    modelValue: { type: [Number, String, Boolean] as PropType<number | string | boolean>, default: false },\n    /** 是否开启轻微震动反馈 */\n    vibrateShort: { type: Boolean, default: false },\n    /** 打开时的值 */\n    activeValue: { type: [Number, String, Boolean] as PropType<number | string | boolean>, default: true },\n    /** 关闭时的值 */\n    inactiveValue: { type: [Number, String, Boolean] as PropType<number | string | boolean>, default: false }\n};\n\nexport type SwitchProps = ExtractPropTypes<typeof SwitchProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-switch/u-switch.vue",
    "content": "<template>\n    <view\n        class=\"u-switch\"\n        :class=\"[isChecked ? 'u-switch--on' : '', disabled ? 'u-switch--disabled' : '', customClass]\"\n        @tap=\"onClick\"\n        :style=\"$u.toStyle(switchStyle, customStyle)\"\n    >\n        <view\n            class=\"u-switch__node node-class\"\n            :style=\"{\n                width: currentSize,\n                height: currentSize\n            }\"\n        >\n            <u-loading :show=\"loading\" class=\"u-switch__loading\" :size=\"loadingSize\" :color=\"loadingColor\" />\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-switch',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick } from 'vue';\nimport { $u, useChildren } from '../..';\nimport { SwitchProps } from './types';\nimport type { SizeType } from '../../types/global';\n\n/**\n * switch 开关选择器\n * @description 选择开关一般用于只有两个选择，且只能选其一的场景。\n * @tutorial https://uviewpro.cn/zh/components/switch.html\n * @property {Boolean} loading 是否处于加载中（默认false）\n * @property {Boolean} disabled 是否禁用（默认false）\n * @property {String|Number} size 开关尺寸，单位rpx（默认50）\n * @property {String} active-color 打开时的背景色（默认主题色primary）\n * @property {String} inactive-color 关闭时的背景色（默认var(--u-bg-white)）\n * @property {Boolean|Number|String} active-value 打开选择器时通过change事件发出的值（默认true）\n * @property {Boolean|Number|String} inactive-value 关闭选择器时通过change事件发出的值（默认false）\n * @event {Function} change 在switch打开或关闭时触发\n * @example <u-switch v-model=\"checked\" active-color=\"red\" inactive-color=\"var(--u-divider-color)\"></u-switch>\n */\nconst props = defineProps(SwitchProps);\n\nconst emit = defineEmits(['update:modelValue', 'change']);\nconst { parentExposed } = useChildren('u-switch', 'u-form');\n\n// 根据 size 定义不同的配置\nconst sizeConfig = {\n    small: {\n        size: 40\n    },\n    default: {\n        size: 50\n    },\n    large: {\n        size: 60\n    }\n};\n\n// 获取实际使用的 size 值（优先级：props.size > u-form.size）\nconst actualSize = computed(() => {\n    // 优先使用 props 的 size 属性\n    if (props.size !== '') {\n        return String(props.size);\n    }\n    // 次优先：使用 u-form 的 size 属性\n    if (parentExposed.value?.props?.size) {\n        return String(parentExposed.value.props.size);\n    }\n    // 默认值\n    return 'default';\n});\n\n// 判断实际使用的 size 是否在预设配置中\nconst isInSizeConfig = computed(() => actualSize.value in sizeConfig);\n\n// 获取预设 size（用于查找 sizeConfig 配置，如图标大小、高度等）\nconst presetSize = computed(() => {\n    return (isInSizeConfig.value ? actualSize.value : 'default') as SizeType;\n});\n\n// 获取当前尺寸配置\nconst currentSizeConfig = computed(() => sizeConfig[presetSize.value]);\n\n// 获取实际要使用的 size（如果是预设值使用配置值，否则作为自定义值处理）\nconst currentSize = computed(() => {\n    if (isInSizeConfig.value) {\n        return $u.addUnit(currentSizeConfig.value.size);\n    }\n    // 自定义size值，直接作为fontSize处理\n    return $u.addUnit(actualSize.value);\n});\n\n// 加载动画尺寸，取当前size的60%\nconst loadingSize = computed(() => {\n    const sizeNum = Number(currentSize.value.replace('rpx', ''));\n    return sizeNum * 0.6;\n});\n\n/**\n * 计算属性：是否处于激活状态\n * 通过比较modelValue和activeValue来确定开关的真实状态\n */\nconst isChecked = computed(() => {\n    return props.modelValue === props.activeValue;\n});\n\n/**\n * 计算开关样式\n */\nconst switchStyle = computed(() => {\n    let style: Record<string, string> = {};\n    style.fontSize = currentSize.value;\n    style.backgroundColor = isChecked.value ? props.activeColor : props.inactiveColor;\n    return style;\n});\n/**\n * 计算加载动画颜色\n */\nconst loadingColor = computed(() => {\n    return isChecked.value ? props.activeColor : undefined;\n});\n\n/**\n * 点击开关\n */\nfunction onClick() {\n    if (!props.disabled && !props.loading) {\n        // 使手机产生短促震动，微信小程序有效，APP(HX 2.6.8)和H5无效\n        if (props.vibrateShort) uni.vibrateShort();\n\n        // 根据当前状态切换到另一个值\n        const newValue = isChecked.value ? props.inactiveValue : props.activeValue;\n        emit('update:modelValue', newValue);\n        // 放到下一个生命周期，因为双向绑定的value修改父组件状态需要时间，且是异步的\n        nextTick(() => {\n            emit('change', newValue);\n        });\n    }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-switch {\n    position: relative;\n    /* #ifndef APP-NVUE */\n    display: inline-block;\n    /* #endif */\n    box-sizing: initial;\n    width: 2em;\n    height: 1em;\n    background-color: var(--u-bg-white);\n    border: 1px solid rgba(0, 0, 0, 0.1);\n    border-radius: 1em;\n    transition: background-color 0.3s;\n    font-size: 50rpx;\n}\n\n.u-switch__node {\n    @include vue-flex;\n    align-items: center;\n    justify-content: center;\n    position: absolute;\n    top: 0;\n    left: 0;\n    border-radius: 100%;\n    z-index: 1;\n    background-color: var(--u-bg-white);\n    box-shadow:\n        0 3px 1px 0 rgba(0, 0, 0, 0.05),\n        0 2px 2px 0 rgba(0, 0, 0, 0.1),\n        0 3px 3px 0 rgba(0, 0, 0, 0.05);\n    transition: transform 0.3s cubic-bezier(0.3, 1.05, 0.4, 1.05);\n    transition:\n        transform 0.3s cubic-bezier(0.3, 1.05, 0.4, 1.05),\n        -webkit-transform 0.3s cubic-bezier(0.3, 1.05, 0.4, 1.05);\n    transition: transform cubic-bezier(0.3, 1.05, 0.4, 1.05);\n    transition: transform 0.3s cubic-bezier(0.3, 1.05, 0.4, 1.05);\n}\n\n.u-switch__loading {\n    @include vue-flex;\n    align-items: center;\n    justify-content: center;\n}\n\n.u-switch--on {\n    background-color: $u-type-primary;\n}\n\n.u-switch--on .u-switch__node {\n    transform: translateX(100%);\n}\n\n.u-switch--disabled {\n    opacity: 0.4;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-tabbar/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { TabbarItem } from '../../types/global';\nimport zIndex from '../../libs/config/zIndex';\n\n/**\n * TabbarProps 底部导航栏 props 类型定义\n * @description 底部导航栏，支持凸起按钮、徽标、切换前回调等\n */\nexport const TabbarProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 是否显示tabbar */\n    show: { type: Boolean, default: true },\n    /** v-model绑定当前激活项的值 */\n    modelValue: { type: [String, Number] as PropType<string | number>, default: 0 },\n    /** tabbar背景色 */\n    bgColor: { type: String, default: 'var(--u-bg-white)' },\n    /** tabbar高度，单位任意，数值默认rpx */\n    height: { type: [String, Number] as PropType<string | number>, default: '50px' },\n    /** 非凸起图标的大小，单位任意，数值默认rpx */\n    iconSize: { type: [String, Number] as PropType<string | number>, default: 40 },\n    /** 凸起图标的大小，单位任意，数值默认rpx */\n    midButtonSize: { type: [String, Number] as PropType<string | number>, default: 100 },\n    /** 文本大小，单位任意，数值默认rpx */\n    textSize: { type: [String, Number] as PropType<string | number>, default: 26 },\n    /** 激活时的颜色 */\n    activeColor: { type: String, default: 'var(--u-main-color)' },\n    /** 未激活时的颜色 */\n    inactiveColor: { type: String, default: 'var(--u-content-color)' },\n    /** 是否显示中部凸起按钮 */\n    midButton: { type: Boolean, default: false },\n    /** tabbar配置项数组 */\n    list: { type: Array as PropType<TabbarItem[]>, default: () => [] },\n    /** 切换前回调，返回true或Promise */\n    beforeSwitch: {\n        type: Function as unknown as PropType<((index: number) => boolean | Promise<any>) | null>,\n        default: null\n    },\n    /** 是否显示顶部横线 */\n    borderTop: { type: Boolean, default: true },\n    /** 是否隐藏原生tabbar */\n    hideTabBar: { type: Boolean, default: true },\n    /** z-index层级 */\n    zIndex: { type: [String, Number] as PropType<string | number>, default: zIndex.tabbar },\n    /** icon和text的间距，单位任意，数值默认rpx */\n    gap: { type: [String, Number] as PropType<string | number>, default: 8 }\n};\n\nexport type TabbarProps = ExtractPropTypes<typeof TabbarProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-tabbar/u-tabbar.vue",
    "content": "<template>\n    <view\n        v-if=\"props.show\"\n        class=\"u-tabbar\"\n        :class=\"customClass\"\n        :style=\"$u.toStyle(customStyle)\"\n        @touchmove.stop.prevent=\"() => {}\"\n    >\n        <view\n            class=\"u-tabbar__content safe-area-inset-bottom\"\n            :style=\"{ height: $u.addUnit(props.height), backgroundColor: props.bgColor, zIndex: uZIndex }\"\n            :class=\"{ 'u-border-top': props.borderTop }\"\n        >\n            <view\n                class=\"u-tabbar__content__item\"\n                v-for=\"(item, index) in props.list\"\n                :key=\"index\"\n                :class=\"{ 'u-tabbar__content__circle': props.midButton && item.midButton }\"\n                @tap.stop=\"clickHandler(index)\"\n                :style=\"$u.toStyle(getItemStyle(item))\"\n            >\n                <view\n                    class=\"u-tabbar__content__item__container\"\n                    :class=\"{ 'u-tabbar__content__circle__container': props.midButton && item.midButton }\"\n                    :style=\"containerStyle(index)\"\n                >\n                    <view\n                        v-if=\"item.iconPath || item.selectedIconPath\"\n                        :class=\"[\n                            props.midButton && item.midButton\n                                ? 'u-tabbar__content__circle__icon'\n                                : 'u-tabbar__content__item__icon'\n                        ]\"\n                    >\n                        <!-- 凸起按钮边框 -->\n                        <view\n                            v-if=\"props.midButton && item.midButton && props.borderTop\"\n                            class=\"u-tabbar__content__circle__border\"\n                            :style=\"{ backgroundColor: props.bgColor }\"\n                        ></view>\n                        <u-icon\n                            :size=\"getIconSize(index)\"\n                            :name=\"elIconPath(index)\"\n                            img-mode=\"scaleToFill\"\n                            :color=\"elColor(index)\"\n                            :custom-prefix=\"getCustomPrefix(index)\"\n                        ></u-icon>\n                        <u-badge\n                            :count=\"item.count\"\n                            :is-dot=\"item.isDot\"\n                            v-if=\"item.count || item.isDot\"\n                            :offset=\"[\n                                getBadgeOffsetTop(item.count || 0, item.isDot || false),\n                                getOffsetRight(item.count || 0, item.isDot || false)\n                            ]\"\n                        ></u-badge>\n                    </view>\n                    <!-- #ifdef APP-PLUS -->\n                    <u-gap :height=\"gap\"></u-gap>\n                    <!-- #endif -->\n                    <view\n                        v-if=\"item.text\"\n                        class=\"u-tabbar__content__item__text\"\n                        :class=\"{\n                            'u-tabbar__content__item__text--center':\n                                item.text && !(item.iconPath || item.selectedIconPath)\n                        }\"\n                    >\n                        <text\n                            class=\"u-line-1\"\n                            :style=\"{ color: elColor(index), fontSize: $u.addUnit(getTextSize(index)) }\"\n                        >\n                            {{ item.text }}\n                        </text>\n                    </view>\n                </view>\n            </view>\n        </view>\n        <!-- 这里加上一个48rpx的高度,是为了增高有凸起按钮时的防塌陷高度(也即按钮凸出来部分的高度) -->\n        <!-- calc 计算0时单位不一致会计算失败，这里+1px -->\n        <view\n            class=\"u-fixed-placeholder safe-area-inset-bottom\"\n            :style=\"{ height: `calc(${$u.addUnit(props.height)} + ${props.midButton ? '60rpx' : '1px'})` }\"\n        ></view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-tabbar',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted } from 'vue';\nimport { $u } from '../..';\nimport { TabbarProps } from './types';\nimport type { TabbarItem } from '../../types/global';\n\n/**\n * u-tabbar 底部导航栏\n * @property {Boolean} show 显示与否\n * @property {String|Number} value 通过v-model绑定current值\n * @property {String} bgColor 整个tabbar的背景颜色\n * @property {String|Number} height tabbar的高度，默认50px，单位任意，如果为数值，则为rpx单位\n * @property {String|Number} iconSize 非凸起图标的大小，单位任意，数值默认rpx\n * @property {String|Number} midButtonSize 凸起的图标的大小，单位任意，数值默认rpx\n * @property {String} activeColor 激活时的演示，包括字体图标，提示文字等的演示\n * @property {String} inactiveColor 未激活时的颜色\n * @property {Boolean} midButton 是否显示中部的凸起按钮\n * @property {Array} list 配置参数\n * @property {Function} beforeSwitch 切换前的回调\n * @property {Boolean} borderTop 是否显示顶部的横线\n * @property {Boolean} hideTabBar 是否隐藏原生tabbar\n * @property {String|Number} gap icon和text的间距，单位任意，数值默认rpx\n */\n\nconst props = defineProps(TabbarProps);\n\nconst emit = defineEmits<{ (e: 'change', index: number): void; (e: 'update:modelValue', index: number): void }>();\n\n// 计算z-index值\nconst uZIndex = computed(() => props?.zIndex ?? $u.zIndex.tabbar);\n\n/**\n * 检查是否有任意item设置了width\n */\nconst hasCustomWidth = computed(() => {\n    return props.list?.some(item => item.width !== undefined && item.width !== null && item.width !== '') || false;\n});\n\n/**\n * 计算每个item的宽度，根据list数量平分\n * 如果任意item设置了width，则不自动计算，返回auto\n */\nconst autoItemWidth = computed(() => {\n    // 如果用户设置了任意一个width，就不自动计算\n    if (hasCustomWidth.value) return 'auto';\n\n    const count = props.list?.length || 0;\n    if (count === 0) return 'auto';\n    return `${100 / count}%`;\n});\n\n/**\n * 获取单个item的样式\n * 使用 flex 简写属性设置宽度，与原有样式保持一致\n */\nfunction getItemStyle(item: TabbarItem): Record<string, any> {\n    const style: Record<string, any> = {};\n    // 背景色\n    style.backgroundColor = props.bgColor;\n    // flex宽度设置\n    if (item.width !== undefined && item.width !== null && item.width !== '') {\n        // 固定宽度：不伸缩\n        style.flex = `0 0 ${$u.addUnit(item.width)}`;\n        style.width = $u.addUnit(item.width);\n    } else if (hasCustomWidth.value) {\n        // 如果其他item设置了width，未设置的自动填充剩余空间\n        style.flex = '1 1 auto';\n        style.width = 'auto';\n    } else {\n        // 自动平分：不伸缩，按百分比分配\n        style.flex = `0 0 ${autoItemWidth.value}`;\n        style.width = autoItemWidth.value;\n    }\n    return style;\n}\n\nconst pageUrl = ref(''); // 当前页面URL\n\nonMounted(() => {\n    // 是否隐藏原生tabbar\n    // 注意：如果当前页面不是tabbar页面，浏览器控制台会报错：{errMsg: 'hideTabBar:fail not TabBar page'}\n    if (props.hideTabBar) uni.hideTabBar();\n    // 获取引入了u-tabbar页面的路由地址，该地址没有路径前面的\"/\"\n    const pages = getCurrentPages();\n    // 页面栈中的最后一个即为项为当前页面，route属性为页面路径\n    pageUrl.value = pages[pages.length - 1].route as string;\n});\n\n/**\n * 计算当前item的icon路径\n */\nconst elIconPath = computed<(index: number) => string | undefined>(() => {\n    return (index: number) => {\n        // 历遍u-tabbar的每一项item时，判断是否传入了pagePath参数，如果传入了\n        // 和data中的pageUrl参数对比，如果相等，即可判断当前的item对应当前的tabbar页面，设置高亮图标\n        // 采用这个方法，可以无需使用v-model绑定的value值\n        const pagePath = props.list[index]?.pagePath;\n        // 如果定义了pagePath属性，意味着使用系统自带tabbar方案，否则使用一个页面用几个组件模拟tabbar页面的方案\n        // 这两个方案对处理tabbar item的激活与否方式不一样\n        if (pagePath) {\n            if (pagePath === pageUrl.value || pagePath === '/' + pageUrl.value) {\n                return props.list[index].selectedIconPath;\n            } else {\n                return props.list[index].iconPath;\n            }\n        } else {\n            // 普通方案中，索引等于v-model值时，即为激活项\n            return index == props.modelValue ? props.list[index].selectedIconPath : props.list[index].iconPath;\n        }\n    };\n});\n\n/**\n * 计算当前item的颜色\n */\nconst elColor = computed<(index: number) => string>(() => {\n    return (index: number) => {\n        // 判断方法同理于elIconPath\n        const pagePath = props.list[index]?.pagePath;\n        if (pagePath) {\n            if (pagePath === pageUrl.value || pagePath === '/' + pageUrl.value) return props.activeColor;\n            else return props.inactiveColor;\n        } else {\n            return index == props.modelValue ? props.activeColor : props.inactiveColor;\n        }\n    };\n});\n\n/**\n * 计算当前item的custom-prefix\n * customIcon为boolean时：true为\"custom-icon\"，false为\"uicon\"\n * customIcon为string时：直接使用该值\n * customIcon为空时：默认\"uicon\"\n */\nfunction getCustomPrefix(index: number): string {\n    const customIcon = props.list[index]?.customIcon;\n\n    // 如果为空（undefined/null），返回默认值\n    if (customIcon === undefined || customIcon === null || customIcon === '') {\n        return 'uicon';\n    }\n\n    // 如果是字符串类型，直接返回\n    if (typeof customIcon === 'string') {\n        return customIcon;\n    }\n\n    // 如果是boolean类型\n    if (typeof customIcon === 'boolean') {\n        return customIcon ? 'custom-icon' : 'uicon';\n    }\n\n    // 默认返回uicon\n    return 'uicon';\n}\n\n/**\n * 点击tabbar item\n */\nasync function clickHandler(index: number) {\n    if (props.beforeSwitch && typeof props.beforeSwitch === 'function') {\n        // 执行回调，同时传入索引当作参数\n        let beforeSwitchResult = props.beforeSwitch(index);\n        // 判断是否返回了promise\n        if (\n            typeof beforeSwitchResult === 'object' &&\n            beforeSwitchResult !== null &&\n            typeof beforeSwitchResult.then === 'function'\n        ) {\n            await beforeSwitchResult\n                .then(() => {\n                    // promise返回成功，\n                    switchTab(index);\n                })\n                .catch(() => {});\n        } else if (beforeSwitchResult === true) {\n            // 如果返回true\n            switchTab(index);\n        }\n    } else {\n        switchTab(index);\n    }\n}\n\n/**\n * 切换tab\n */\nfunction switchTab(index: number) {\n    // 发出事件和修改v-model绑定的值\n    emit('change', index);\n    // 如果有配置pagePath属性，使用uni.switchTab进行跳转\n    if (props.list[index]?.pagePath) {\n        uni.switchTab({ url: props.list[index].pagePath as string });\n    } else {\n        // 如果配置了papgePath属性，将不会双向绑定v-model传入的value值\n        // 因为这个模式下，不再需要v-model绑定的value值了，而是通过getCurrentPages()适配\n        emit('update:modelValue', index);\n    }\n}\n\n/**\n * 计算角标的right值\n */\nfunction getOffsetRight(count: number, isDot: boolean): number {\n    // 点类型，count大于9(两位数)，分别设置不同的right值，避免位置太挤\n    if (isDot) {\n        return -20;\n    } else if (count > 9) {\n        return -40;\n    } else {\n        return -30;\n    }\n}\n\n/**\n * 计算角标的top值，在垂直布局下调整位置\n */\nfunction getBadgeOffsetTop(count: number, isDot: boolean): number {\n    // 在垂直布局下，角标相对于icon的top偏移需要调整\n    // 由于icon现在在flex容器中，需要更小的top偏移\n    return -2;\n}\n\n/**\n * 获取单项icon尺寸（单项优先级高于props）\n */\nfunction getIconSize(index: number) {\n    const item = props.list[index] || {};\n    if (props.midButton && item.midButton) {\n        return props.midButtonSize;\n    }\n    if (item.iconSize !== undefined && item.iconSize !== null && item.iconSize !== '') {\n        return item.iconSize;\n    }\n    return props.iconSize;\n}\n\n/**\n * 获取单项text尺寸（单项优先级高于props）\n */\nfunction getTextSize(index: number) {\n    const item = props.list[index] || {};\n    if (item.textSize !== undefined && item.textSize !== null && item.textSize !== '') {\n        return item.textSize;\n    }\n    return props.textSize;\n}\n\n/**\n * 图标和文字间距\n */\nfunction containerStyle(index: number) {\n    const style: Record<string, any> = {};\n    const item = props.list[index] || {};\n    // #ifndef APP-PLUS\n    if (item.gap !== undefined && item.gap !== null && item.gap !== '') {\n        style.gap = $u.addUnit(item.gap);\n    } else {\n        style.gap = $u.addUnit(props.gap);\n    }\n    // #endif\n    // 如果是中间凸起按钮，为容器增加上内边距，避免文字被绝对定位的图标遮挡\n    if (props.midButton && item.midButton) {\n        const iconSizeRaw = getIconSize(index);\n        const numericSize = parseFloat(String(iconSizeRaw)) || parseFloat(String(props.midButtonSize as any)) || 100;\n        // paddingTop: 半个图标高度 + 10rpx 的缓冲间距\n        style.paddingTop = $u.addUnit(numericSize / 2 + 8);\n        style.boxSizing = 'border-box';\n    }\n    return $u.toStyle(style);\n}\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n.u-fixed-placeholder {\n    /* #ifndef APP-NVUE */\n    box-sizing: content-box;\n    /* #endif */\n    height: 50px;\n}\n.u-tabbar {\n    &__content {\n        @include vue-flex;\n        align-items: center;\n        position: relative;\n        position: fixed;\n        bottom: 0;\n        left: 0;\n        width: 100%;\n        z-index: 998;\n        /* #ifndef APP-NVUE */\n        box-sizing: content-box;\n        /* #endif */\n\n        &__item {\n            flex: 1;\n            justify-content: center;\n            height: 100%;\n            padding: 12rpx 0;\n            @include vue-flex;\n            flex-direction: column;\n            align-items: center;\n            position: relative;\n            &__container {\n                @include vue-flex;\n                flex-direction: column;\n                align-items: center;\n                justify-content: center;\n                height: 100%;\n                width: 100%;\n                position: relative;\n            }\n            &__icon {\n                position: relative;\n                @include vue-flex;\n                align-items: center;\n                justify-content: center;\n            }\n            &__text {\n                color: $u-content-color;\n                font-size: 26rpx;\n                line-height: 28rpx;\n                text-align: center;\n                width: 100%;\n                z-index: 6;\n            }\n        }\n        &__circle {\n            position: relative;\n            @include vue-flex;\n            flex-direction: column;\n            justify-content: space-between;\n            z-index: 10;\n            /* #ifndef APP-NVUE */\n            height: calc(100% - 1px);\n            /* #endif */\n            &__container {\n                @include vue-flex;\n                flex-direction: column;\n                align-items: center;\n                justify-content: center;\n                height: 100%;\n                width: 100%;\n                position: relative;\n                box-sizing: border-box;\n            }\n            &__icon {\n                width: 100rpx;\n                height: 100rpx;\n                border-radius: 100%;\n                @include vue-flex;\n                justify-content: center;\n                align-items: center;\n                background-color: var(--u-bg-white);\n                /* 将凸起图标上移，与顶部边框线对齐 */\n                position: absolute;\n                top: -55rpx;\n                left: 50%;\n                z-index: 6;\n                transform: translateX(-50%);\n            }\n            &__border {\n                position: absolute;\n                top: -18rpx;\n                width: 130rpx;\n                height: 130rpx;\n                border-radius: 100%;\n                border-top: 1px solid var(--u-border-color);\n                background-color: var(--u-bg-white);\n                z-index: 0;\n                pointer-events: none;\n            }\n        }\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-table/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { TextAlign } from '../../types/global';\n\n/**\n * TableProps 表格 props 类型定义\n * @description 表格组件，支持自定义边框、背景、对齐方式等\n */\nexport const TableProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 表格边框的颜色 */\n    borderColor: { type: String, default: 'var(--u-border-color)' },\n    /** 单元格的内容对齐方式，作用类似css的text-align */\n    align: { type: String as PropType<TextAlign>, default: 'center' },\n    /** 单元格的内边距，同css的padding写法 */\n    padding: { type: String, default: '10rpx 6rpx' },\n    /** 单元格字体大小，单位rpx */\n    fontSize: { type: [String, Number] as PropType<number | string>, default: 28 },\n    /** 单元格字体颜色 */\n    color: { type: String, default: 'var(--u-content-color)' },\n    /** th单元格的样式，对象形式(将th所需参数放在table组件，是为了避免每一个th组件要写一遍） */\n    thStyle: { type: Object as PropType<Record<string, any>>, default: () => ({}) },\n    /** 表格的背景颜色 */\n    bgColor: { type: String, default: 'var(--u-bg-white)' }\n};\n\nexport type TableProps = ExtractPropTypes<typeof TableProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-table/u-table.vue",
    "content": "<template>\n    <view class=\"u-table\" :style=\"$u.toStyle(tableStyle, customStyle)\" :class=\"customClass\">\n        <slot />\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-table',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { TableProps } from './types';\nimport { $u } from '../..';\n\n/**\n * table 表格\n * @description 表格组件一般用于展示大量结构化数据的场景\n * @tutorial https://uviewpro.cn/zh/components/table.html\n * @property {String} border-color 表格边框的颜色（默认var(--u-border-color)）\n * @property {String} bg-color 表格的背景颜色（默认var(--u-bg-white)）\n * @property {String} align 单元格的内容对齐方式，作用类似css的text-align（默认center）\n * @property {String} padding 单元格的内边距，同css的padding写法（默认10rpx 0）\n * @property {String | Number} font-size 单元格字体大小，单位rpx（默认28）\n * @property {String} color 单元格字体颜色（默认var(--u-content-color)）\n * @property {Object} th-style th单元格的样式，对象形式(将th所需参数放在table组件，是为了避免每一个th组件要写一遍）\n * @event {Function} click 点击组件时触发\n * @event {Function} close 点击关闭按钮时触发\n * @example <u-table></u-table>\n */\n\nconst props = defineProps(TableProps);\n\n/**\n * 计算表格样式\n */\nconst tableStyle = computed(() => {\n    const style: Record<string, any> = {};\n    style.borderLeft = `solid 1px ${props.borderColor}`;\n    style.borderTop = `solid 1px ${props.borderColor}`;\n    style.backgroundColor = props.bgColor;\n    return style;\n});\n\ndefineExpose({\n    props,\n    tableStyle\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-table {\n    width: 100%;\n    box-sizing: border-box;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-tabs/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { TabsItem } from '../../types/global';\nimport { getColor } from '../../';\n\n/**\n * TabsProps tabs标签 props 类型定义\n * @description 标签组件，支持横向滚动、滑块、徽标等\n */\nexport const TabsProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** tabs是否可以左右拖动 */\n    isScroll: { type: Boolean, default: true },\n    /** 标签数组 */\n    list: { type: Array as PropType<Array<TabsItem>>, default: () => [] },\n    /** 当前活动tab的索引 */\n    current: { type: [Number, String] as PropType<number | string>, default: 0 },\n    /** 导航栏的高度和行高 */\n    height: { type: [String, Number] as PropType<number | string>, default: 80 },\n    /** 字体大小 */\n    fontSize: { type: [String, Number] as PropType<number | string>, default: 30 },\n    /** 过渡动画时长, 单位s */\n    duration: { type: [String, Number] as PropType<number | string>, default: 0.5 },\n    /** 选中项的主题颜色 */\n    activeColor: { type: String, default: () => getColor('primary') },\n    /** 未选中项的颜色 */\n    inactiveColor: { type: String, default: () => getColor('mainColor') },\n    /** 菜单底部移动的bar的宽度，单位rpx */\n    barWidth: { type: [String, Number] as PropType<number | string>, default: 40 },\n    /** 移动bar的高度 */\n    barHeight: { type: [String, Number] as PropType<number | string>, default: 6 },\n    /** 单个tab的左右内边距之和，单位rpx */\n    gutter: { type: [String, Number] as PropType<number | string>, default: 30 },\n    /** 导航栏的背景颜色 */\n    bgColor: { type: String, default: 'var(--u-bg-white)' },\n    /** 读取传入的数组对象的属性(tab名称) */\n    name: { type: String, default: 'name' },\n    /** 读取传入的数组对象的属性(徽标数) */\n    count: { type: String, default: 'count' },\n    /** 徽标数位置偏移 */\n    offset: { type: Array as unknown as PropType<[number, number]>, default: () => [5, 20] },\n    /** 徽标是否是圆点 */\n    isDot: { type: Boolean, default: false },\n    /** 活动tab字体是否加粗 */\n    bold: { type: Boolean, default: true },\n    /** 当前活动tab item的样式 */\n    activeItemStyle: { type: Object as PropType<Record<string, any>>, default: () => ({}) },\n    /** 是否显示底部的滑块 */\n    showBar: { type: Boolean, default: true },\n    /** 底部滑块的自定义样式 */\n    barStyle: { type: Object as PropType<Record<string, any>>, default: () => ({}) },\n    /** 标签的宽度 */\n    itemWidth: { type: [String, Number] as PropType<number | string>, default: 'auto' }\n};\n\nexport type TabsProps = ExtractPropTypes<typeof TabsProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-tabs/u-tabs.vue",
    "content": "<template>\n    <view class=\"u-tabs\" :style=\"$u.toStyle({ background: bgColor }, customStyle)\" :class=\"customClass\">\n        <!-- $u.getRect()对组件根节点无效，因为写了.in(this)，故这里获取内层接点尺寸 -->\n        <view>\n            <scroll-view\n                scroll-x\n                class=\"u-scroll-view\"\n                :scroll-left=\"scrollLeft\"\n                :show-scrollbar=\"false\"\n                scroll-with-animation\n            >\n                <view class=\"u-scroll-box\" :id=\"id\" :class=\"{ 'u-tabs-scroll-flex': !isScroll }\">\n                    <view\n                        class=\"u-tab-item u-line-1\"\n                        :class=\"[item.hidden ? 'u-tab-item-hidden' : '']\"\n                        :id=\"'u-tab-item-' + index\"\n                        v-for=\"(item, index) in list\"\n                        :key=\"index\"\n                        @tap=\"clickTab(index)\"\n                        :style=\"tabItemStyle(index)\"\n                    >\n                        <u-badge\n                            :count=\"item[count] || item['count'] || 0\"\n                            :offset=\"offset\"\n                            :is-dot=\"isDot\"\n                            size=\"mini\"\n                        ></u-badge>\n                        {{ item[name] || item['name'] }}\n                    </view>\n                    <view v-if=\"showBar\" class=\"u-tab-bar\" :style=\"tabBarStyle\"></view>\n                </view>\n            </scroll-view>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-tabs',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, onMounted, nextTick, getCurrentInstance } from 'vue';\nimport { $u } from '../..';\nimport { TabsProps } from './types';\n\n/**\n * tabs 标签\n * @description 该组件，是一个tabs标签组件，在标签多的时候，可以配置为左右滑动，标签少的时候，可以禁止滑动。 该组件的一个特点是配置为滚动模式时，激活的tab会自动移动到组件的中间位置。\n * @tutorial https://uviewpro.cn/zh/components/tabs.html\n * @property {Boolean} is-scroll tabs是否可以左右拖动（默认true）\n * @property {Array} list 标签数组，元素为对象，如[{name: '推荐'}]\n * @property {String|Number} current 指定哪个tab为激活状态（默认0）\n * @property {String|Number} height 导航栏的高度，单位rpx（默认80）\n * @property {String|Number} font-size tab文字大小，单位rpx（默认30）\n * @property {String|Number} duration 滑块移动一次所需的时间，单位秒（默认0.5）\n * @property {String} active-color 滑块和激活tab文字的颜色（默认主题色primary）\n * @property {String} inactive-color tabs文字颜色（默认var(--u-main-color)）\n * @property {String|Number} bar-width 滑块宽度，单位rpx（默认40）\n * @property {Object} active-item-style 活动tabs item的样式，对象形式\n * @property {Object} bar-style 底部滑块的样式，对象形式\n * @property {Boolean} show-bar 是否显示底部的滑块（默认true）\n * @property {String|Number} bar-height 滑块高度，单位rpx（默认6）\n * @property {String|Number} item-width 标签的宽度（默认auto）\n * @property {String|Number} gutter 单个tab标签的左右内边距之和，单位rpx（默认40）\n * @property {String} bg-color tabs导航栏的背景颜色（默认var(--u-bg-white)）\n * @property {String} name 组件内部读取的list参数中的属性名（tab名称），见官网说明（默认name）\n * @property {String} count 组件内部读取的list参数中的属性名（badge徽标数），同name属性的使用，见官网说明（默认count）\n * @property {Array} offset 设置badge徽标数的位置偏移，格式为 [x, y]，也即设置的为top和right的值，单位rpx（默认[5, 20]）\n * @property {Boolean} bold 激活选项的字体是否加粗（默认true）\n * @event {Function} change 点击标签时触发\n * @example <u-tabs ref=\"tabs\" :list=\"list\" :is-scroll=\"false\"></u-tabs>\n */\n\n// props 定义\nconst props = defineProps(TabsProps);\n\n/**\n * emits 定义\n */\nconst emit = defineEmits(['change']);\nconst instance = getCurrentInstance();\n// 滚动scroll-view的左边滚动距离\nconst scrollLeft = ref(0);\n// 存放对tab菜单查询后的节点信息\nconst tabQueryInfo = ref<any[]>([]);\n// 屏幕宽度，单位为px\nconst componentWidth = ref(0);\n// 移动bar需要通过translateX()移动的距离\nconst scrollBarLeft = ref(0);\n// 父元素(tabs组件)到屏幕左边的距离\nconst parentLeft = ref(0);\n// id值\nconst id = ref($u.guid());\n// 当前活动tab索引\nconst currentIndex = ref(props.current);\n// 滑块第一次移动时(页面刚生成时)，无需动画，否则给人怪异的感觉\nconst barFirstTimeMove = ref(true);\n\n// 监听list变化，重置索引并重新布局\n// 监听tab的变化，重新计算tab菜单的布局信息，因为实际使用中菜单可能是通过\n// 后台获取的（如新闻app顶部的菜单），获取返回需要一定时间，所以list变化时，重新获取布局信息\nwatch(\n    () => props.list,\n    (n, o) => {\n        // list变动时，重制内部索引，否则可能导致超出数组边界的情况\n        if (n.length !== o.length) currentIndex.value = 0;\n        // 用$nextTick等待视图更新完毕后再计算tab的局部信息，否则可能因为tab还没生成就获取，就会有问题\n        nextTick(() => {\n            init();\n        });\n    }\n);\n\n// 监听current变化，自动滚动\nwatch(\n    () => props.current,\n    nVal => {\n        // 视图更新后再执行移动操作\n        nextTick(() => {\n            currentIndex.value = nVal;\n            scrollByIndex();\n        });\n    },\n    { immediate: true }\n);\n\n// 移动bar的样式\nconst tabBarStyle = computed(() => {\n    const style: Record<string, any> = {\n        width: props.barWidth + 'rpx',\n        transform: `translate(${scrollBarLeft.value}px, -100%)`,\n        // 滑块在页面渲染后第一次滑动时，无需动画效果\n        'transition-duration': `${barFirstTimeMove.value ? 0 : props.duration}s`,\n        'background-color': props.activeColor,\n        height: props.barHeight + 'rpx',\n        opacity: barFirstTimeMove.value ? 0 : 1,\n        // 设置一个很大的值，它会自动取能用的最大值，不用高度的一半，是因为高度可能是单数，会有小数出现\n        'border-radius': `${Number(props.barHeight) / 2}px`\n    };\n    Object.assign(style, props.barStyle);\n    return style;\n});\n\n// tab的样式\nfunction tabItemStyle(index: number) {\n    let style: Record<string, any> = {\n        height: props.height + 'rpx',\n        'line-height': props.height + 'rpx',\n        'font-size': props.fontSize + 'rpx',\n        'transition-duration': `${props.duration}s`,\n        padding: props.isScroll ? `0 ${props.gutter}rpx` : '',\n        flex: props.isScroll ? 'auto' : '1',\n        width: $u.addUnit(props.itemWidth)\n    };\n    // 字体加粗\n    if (index == Number(currentIndex.value) && props.bold) style.fontWeight = 'bold';\n    if (index == Number(currentIndex.value)) {\n        style.color = props.activeColor;\n        // 给选中的tab item添加外部自定义的样式\n        style = Object.assign(style, props.activeItemStyle);\n    } else {\n        style.color = props.inactiveColor;\n    }\n    return style;\n}\n\n/**\n * 初始化tab布局信息\n */\nasync function init() {\n    // 获取tabs组件的尺寸信息\n    const tabRect = await $u.getRect('#' + id.value, instance);\n    // tabs组件距离屏幕左边的宽度\n    parentLeft.value = tabRect.left;\n    // tabs组件的宽度\n    componentWidth.value = tabRect.width;\n    getTabRect();\n}\n\n/**\n * 点击某一个tab菜单\n */\nfunction clickTab(index: number) {\n    // 点击当前活动tab，不触发事件\n    if (index == currentIndex.value) return;\n    // 发送事件给父组件\n    emit('change', index);\n}\n\n/**\n * 查询tab的布局信息\n */\nfunction getTabRect() {\n    // 创建节点查询\n    const query = uni.createSelectorQuery().in(instance?.proxy);\n    // 历遍所有tab，这里是执行了查询，最终使用exec()会一次性返回查询的数组结果\n    for (let i = 0; i < props.list.length; i++) {\n        // 只要size和rect两个参数\n        query.select(`#u-tab-item-${i}`).fields({ size: true, rect: true }, () => {});\n    }\n    // 执行查询，一次性获取多个结果\n    query.exec((res: any[]) => {\n        tabQueryInfo.value = res;\n        // 初始化滚动条和移动bar的位置\n        scrollByIndex();\n    });\n}\n\n/**\n * 滚动scroll-view，让活动的tab处于屏幕的中间位置\n */\nfunction scrollByIndex() {\n    // 当前活动tab的布局信息，有tab菜单的width和left(为元素左边界到父元素左边界的距离)等信息\n    const tabInfo = tabQueryInfo.value[Number(currentIndex.value)];\n    if (!tabInfo) return;\n    // 活动tab的宽度\n    const tabWidth = tabInfo.width;\n    // 活动item的左边到tabs组件左边的距离，用item的left减去tabs的left\n    const offsetLeft = tabInfo.left - parentLeft.value;\n    // 将活动的tabs-item移动到屏幕正中间，实际上是对scroll-view的移动\n    const scrollL = offsetLeft - (componentWidth.value - tabWidth) / 2;\n    scrollLeft.value = scrollL < 0 ? 0 : scrollL;\n    // 当前活动item的中点点到左边的距离减去滑块宽度的一半，即可得到滑块所需的移动距离\n    const left = tabInfo.left + tabInfo.width / 2 - parentLeft.value;\n    // 计算当前活跃item到组件左边的距离\n    scrollBarLeft.value = left - uni.upx2px(Number(props.barWidth)) / 2;\n    // 第一次移动滑块的时候，barFirstTimeMove为true，放到延时中将其设置false\n    // 延时是因为scrollBarLeft作用于computed计算时，需要一个过程需，否则导致出错\n    if (barFirstTimeMove.value) {\n        setTimeout(() => {\n            barFirstTimeMove.value = false;\n        }, 100);\n    }\n}\n\nonMounted(() => {\n    nextTick(() => {\n        // 延时获取tabs的尺寸信息\n        setTimeout(() => {\n            init();\n        }, 500);\n    });\n});\n\ndefineExpose({ init, clickTab, scrollByIndex });\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\nview,\nscroll-view {\n    box-sizing: border-box;\n}\n\n// 隐藏滚动条样式，支持App、H5、小程序等平台\n::-webkit-scrollbar {\n    display: none;\n    width: 0 !important;\n    height: 0 !important;\n    -webkit-appearance: none;\n    background: transparent;\n}\n\n.u-scroll-box {\n    position: relative;\n    /* #ifdef MP-TOUTIAO */\n    white-space: nowrap;\n    /* #endif */\n}\n\n/* #ifdef H5 */\n// 通过样式穿透，隐藏H5下，scroll-view下的滚动条\nscroll-view ::v-deep ::-webkit-scrollbar {\n    display: none;\n    width: 0 !important;\n    height: 0 !important;\n    -webkit-appearance: none;\n    background: transparent;\n}\n/* #endif */\n\n// App-nvue 平台使用特殊的滚动条隐藏方式\n/* #ifdef APP-NVUE */\n.scroll-view-nvue {\n    -webkit-scrollbar: none;\n}\n/* #endif */\n\n.u-scroll-view {\n    width: 100%;\n    white-space: nowrap;\n    position: relative;\n}\n\n.u-tab-item {\n    position: relative;\n    /* #ifndef APP-NVUE */\n    display: inline-block;\n    /* #endif */\n    text-align: center;\n    transition-property: background-color, color;\n}\n\n.u-tab-item-hidden {\n    display: none;\n}\n\n.u-tab-bar {\n    position: absolute;\n    bottom: 0;\n}\n\n.u-tabs-scroll-flex {\n    @include vue-flex;\n    justify-content: space-between;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-tabs-swiper/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { TabsSwiperAutoCenterMode, TabsSwiperListItem } from '../../types/global';\nimport { getColor } from '../../';\n\n/**\n * TabsSwiperProps 全屏选项卡 props 类型定义\n * @description 全屏选项卡，支持滑块、渐变色、滚动居中等\n */\nexport const TabsSwiperProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** tabs是否可以左右拖动 */\n    isScroll: { type: Boolean, default: true },\n    /** 标签数组，元素为对象，如[{name: '推荐'}] */\n    list: { type: Array as PropType<Array<TabsSwiperListItem>>, default: () => [] },\n    /** 指定哪个tab为激活状态 */\n    current: { type: [Number, String] as PropType<number | string>, default: 0 },\n    /** 导航栏的高度，单位rpx */\n    height: { type: [Number, String] as PropType<number | string>, default: 80 },\n    /** tab文字大小，单位rpx */\n    fontSize: { type: [Number, String] as PropType<number | string>, default: 30 },\n    /** tabs组件外部swiper的宽度，单位rpx */\n    swiperWidth: { type: [String, Number] as PropType<number | string>, default: 750 },\n    /** 滑块和激活tab文字的颜色 */\n    activeColor: { type: String, default: () => getColor('primary') },\n    /** tabs文字颜色 */\n    inactiveColor: { type: String, default: () => getColor('mainColor') },\n    /** 滑块宽度，单位rpx */\n    barWidth: { type: [Number, String] as PropType<number | string>, default: 40 },\n    /** 滑块高度，单位rpx */\n    barHeight: { type: [Number, String] as PropType<number | string>, default: 6 },\n    /** 单个tab标签的左右内边距之和，单位rpx */\n    gutter: { type: [Number, String] as PropType<number | string>, default: 40 },\n    /** z-index 层级 */\n    zIndex: { type: [Number, String] as PropType<number | string>, default: 1 },\n    /** tabs导航栏的背景颜色 */\n    bgColor: { type: String, default: 'var(--u-bg-white)' },\n    /** 居中模式，window/组件宽度 */\n    autoCenterMode: { type: String as unknown as PropType<TabsSwiperAutoCenterMode>, default: 'window' },\n    /** 组件内部读取的list参数中的属性名（tab名称） */\n    name: { type: String, default: 'name' },\n    /** 组件内部读取的list参数中的属性名（badge徽标数） */\n    count: { type: String, default: 'count' },\n    /** 设置badge徽标数的位置偏移，格式为 [x, y]，单位rpx */\n    offset: { type: Array as unknown as PropType<[number, number]>, default: () => [5, 20] },\n    /** 激活选项的字体是否加粗 */\n    bold: { type: Boolean, default: true },\n    /** 活动tabs item的样式，对象形式 */\n    activeItemStyle: { type: Object as PropType<Record<string, any>>, default: () => ({}) },\n    /** 是否显示底部的滑块 */\n    showBar: { type: Boolean, default: true },\n    /** 底部滑块的样式，对象形式 */\n    barStyle: { type: Object as PropType<Record<string, any>>, default: () => ({}) }\n};\n\nexport type TabsSwiperProps = ExtractPropTypes<typeof TabsSwiperProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-tabs-swiper/u-tabs-swiper.vue",
    "content": "<template>\n    <view class=\"u-tabs\" :style=\"$u.toStyle({ zIndex: zIndex, background: bgColor }, customStyle)\" :class=\"customClass\">\n        <scroll-view\n            scroll-x\n            class=\"u-scroll-view\"\n            :scroll-left=\"scrollLeft\"\n            :show-scrollbar=\"false\"\n            scroll-with-animation\n            :style=\"{ zIndex: Number(zIndex) + 1 }\"\n        >\n            <view class=\"u-tabs-scroll-box\" :class=\"{ 'u-tabs-scroll-flex': !isScroll }\">\n                <view\n                    class=\"u-tabs-item\"\n                    :style=\"tabItemStyle(index)\"\n                    v-for=\"(item, index) in getTabs\"\n                    :key=\"index\"\n                    :class=\"[preId + index]\"\n                    @tap=\"emitTabChange(index)\"\n                >\n                    <u-badge :count=\"item[count] || item['count'] || 0\" :offset=\"offset\" size=\"mini\"></u-badge>\n                    {{ item[name] || item['name'] }}\n                </view>\n                <view v-if=\"showBar\" class=\"u-scroll-bar\" :style=\"tabBarStyle\"></view>\n            </view>\n        </scroll-view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-tabs-swiper',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, nextTick, onMounted, getCurrentInstance } from 'vue';\nimport colorGradient from '../../libs/function/colorGradient';\nimport { TabsSwiperProps } from './types';\nimport { $u } from '../..';\n\n/**\n * tabsSwiper 全屏选项卡\n * @description 该组件内部实现主要依托于uniapp的scroll-view和swiper组件，主要特色是切换过程中，tabsSwiper文字的颜色可以渐变，底部滑块可以 跟随式滑动，活动tab滚动居中等。应用场景可以用于需要左右切换页面，比如商城的订单中心(待收货-待付款-待评价-已退货)等应用场景。\n * @tutorial https://uviewpro.cn/zh/components/tabsSwiper.html\n * @property {Boolean} is-scroll tabs是否可以左右拖动（默认true）\n * @property {Array} list 标签数组，元素为对象，如[{name: '推荐'}]\n * @property {String|Number} current 指定哪个tab为激活状态（默认0）\n * @property {String|Number} height 导航栏的高度，单位rpx（默认80）\n * @property {String|Number} font-size tab文字大小，单位rpx（默认30）\n * @property {String|Number} swiper-width tabs组件外部swiper的宽度，默认为屏幕宽度，单位rpx（默认750）\n * @property {String} active-color 滑块和激活tab文字的颜色（默认主题色primary）\n * @property {String} inactive-color tabs文字颜色（默认var(--u-main-color)）\n * @property {String|Number} bar-width 滑块宽度，单位rpx（默认40）\n * @property {String|Number} bar-height 滑块高度，单位rpx（默认6）\n * @property {Object} bar-style 底部滑块的样式，对象形式\n * @property {Object} active-item-style 活动tabs item的样式，对象形式\n * @property {Boolean} show-bar 是否显示底部的滑块（默认true）\n * @property {String|Number} gutter 单个tab标签的左右内边距之和，单位rpx（默认40）\n * @property {String} bg-color tabs导航栏的背景颜色（默认var(--u-bg-white)）\n * @property {String} name 组件内部读取的list参数中的属性名，见官网说明（默认name）\n * @property {String} count 组件内部读取的list参数中的属性名（badge徽标数），同name属性的使用，见官网说明（默认count）\n * @property {Array} offset 设置badge徽标数的位置偏移，格式为 [x, y]，也即设置的为top和right的值，单位rpx（默认[5, 20]）\n * @property {Boolean} bold 激活选项的字体是否加粗（默认true）\n * @event {Function} change 点击标签时触发\n * @example <u-tabs-swiper ref=\"tabs\" :list=\"list\" :is-scroll=\"false\"></u-tabs-swiper>\n */\n\n// props 定义\nconst props = defineProps(TabsSwiperProps);\n\nconst color = colorGradient;\nconst { windowWidth } = uni.getSystemInfoSync();\nconst preId = 'UEl_';\n\n// emits 定义\nconst emit = defineEmits(['change']);\nconst instance = getCurrentInstance();\n// 滚动scroll-view的左边滚动距离\nconst scrollLeft = ref(0);\n// 存放对tab菜单查询后的节点信息\nconst tabQueryInfo = ref<any[]>([]);\n// 屏幕宽度，单位为px\nconst componentsWidth = ref(0);\n// 滑块需要通过translateX()移动的距离\nconst line3Dx = ref(0);\nconst line3AddDx = ref(0);\nconst animationFinishCurrent = ref(Number(props.current));\n// 两个颜色之间的渐变等分\nconst colorStep = ref(100);\nconst colorGradientArr = ref<string[]>([]);\nconst tabsInfo = ref<any[]>([]);\nconst sW = ref(uni.upx2px(Number(props.swiperWidth)));\n\n// 计算当前活跃tab索引\nconst getCurrent = computed(() => {\n    const current = Number(props.current);\n    // 判断是否超出边界\n    if (current > getTabs.value.length - 1) return getTabs.value.length - 1;\n    if (current < 0) return 0;\n    return current;\n});\n\n// 获取tabs数组\nconst getTabs = computed(() => props.list);\n\n// 滑块需要移动的距离\nconst scrollBarLeft = computed(() => Number(line3Dx.value) + Number(line3AddDx.value));\n\n// 滑块宽度转为px单位\nconst barWidthPx = computed(() => uni.upx2px(Number(props.barWidth)));\n\n// tab的样式\nfunction tabItemStyle(index: number) {\n    let style: Record<string, any> = {\n        height: props.height + 'rpx',\n        lineHeight: props.height + 'rpx',\n        padding: `0 ${Number(props.gutter) / 2}rpx`,\n        color:\n            tabsInfo.value.length > 0\n                ? tabsInfo.value[index]\n                    ? tabsInfo.value[index].color\n                    : props.activeColor\n                : props.inactiveColor,\n        fontSize: props.fontSize + 'rpx',\n        zIndex: Number(props.zIndex) + 2,\n        fontWeight: index == getCurrent.value && props.bold ? 'bold' : 'normal'\n    };\n    if (index == getCurrent.value) {\n        // 给选中的tab item添加外部自定义的样式\n        style = Object.assign(style, props.activeItemStyle);\n    }\n    return style;\n}\n\n// 底部滑块的样式\nconst tabBarStyle = computed(() => {\n    let style: Record<string, any> = {\n        width: barWidthPx.value + 'px',\n        height: props.barHeight + 'rpx',\n        borderRadius: '100px',\n        backgroundColor: props.activeColor,\n        left: scrollBarLeft.value + 'px'\n    };\n    return Object.assign(style, props.barStyle);\n});\n\n// 颜色渐变过程数组\nfunction updateColorGradientArr() {\n    colorGradientArr.value = color.colorGradient(props.inactiveColor, props.activeColor, colorStep.value);\n}\n\n// tabsInfo 计算\nasync function getTabsInfo() {\n    return new Promise<void>(resolve => {\n        const view = uni.createSelectorQuery().in(instance?.proxy);\n        for (let i = 0; i < props.list.length; i++) {\n            view.select('.' + preId + i).boundingClientRect();\n        }\n        view.exec((res: any[]) => {\n            const arr: any[] = [];\n            for (let i = 0; i < res.length; i++) {\n                // 给每个tab添加其文字颜色属性\n                res[i].color = props.inactiveColor;\n                // 当前tab直接赋予activeColor\n                if (i == getCurrent.value) res[i].color = props.activeColor;\n                arr.push(res[i]);\n            }\n            tabsInfo.value = arr;\n            resolve();\n        });\n    });\n}\n\n// 当swiper滑动结束，计算滑块最终要停留的位置\nfunction countLine3Dx() {\n    const tab = tabsInfo.value[animationFinishCurrent.value];\n    // 让滑块中心点和当前tab中心重合\n    if (tab) line3Dx.value = tab.left + tab.width / 2 - barWidthPx.value / 2 - tabsInfo.value[0].left;\n}\n\n// swiper宽度由rpx转为px单位\nfunction countPx() {\n    // swiper宽度由rpx转为px单位，因为dx等，都是px单位\n    sW.value = uni.upx2px(Number(props.swiperWidth));\n}\n\n// 触发change事件\nfunction emitTabChange(index: number) {\n    emit('change', index);\n}\n\n// 滚动居中\nfunction setScrollViewToCenter() {\n    const tab = tabsInfo.value[animationFinishCurrent.value];\n    if (tab) {\n        const tabCenter = tab.left + tab.width / 2;\n        let fatherWidth;\n        if (props.autoCenterMode === 'window') fatherWidth = windowWidth;\n        else fatherWidth = componentsWidth.value;\n        scrollLeft.value = tabCenter - fatherWidth / 2;\n    }\n}\n\n// 查询tab组件宽度\nfunction getQuery(cb?: (data: any) => void) {\n    try {\n        const view = uni.createSelectorQuery().in(instance?.proxy).select('.u-tabs');\n        view.fields({ size: true }, (data: any) => {\n            if (data) {\n                componentsWidth.value = data.width;\n                if (cb) cb(data);\n            } else {\n                getQuery(cb);\n            }\n        }).exec();\n    } catch (e) {\n        componentsWidth.value = windowWidth;\n    }\n}\n\n// 颜色渐变tab滑动\nfunction setDx(dx: number) {\n    let nextTabIndex = dx > 0 ? animationFinishCurrent.value + 1 : animationFinishCurrent.value - 1;\n    // 判断索引是否超出边界\n    nextTabIndex = nextTabIndex <= 0 ? 0 : nextTabIndex;\n    nextTabIndex = nextTabIndex >= props.list.length ? props.list.length - 1 : nextTabIndex;\n    const tab = tabsInfo.value[nextTabIndex];\n    // 当前tab中心点x轴坐标\n    const nowTab = tabsInfo.value[animationFinishCurrent.value];\n    const nowTabX = nowTab.left + nowTab.width / 2;\n    // 下一个tab\n    const nextTabX = tab.left + tab.width / 2;\n    // 两个tab之间的距离，因为下一个tab可能在当前tab的左边或者右边，取绝对值即可\n    const distanceX = Math.abs(nextTabX - nowTabX);\n    line3AddDx.value = (dx / sW.value) * distanceX;\n    setTabColor(animationFinishCurrent.value, nextTabIndex, dx);\n}\n\n// 设置tab的颜色\nfunction setTabColor(nowTabIndex: number, nextTabIndex: number, dx: number) {\n    let colorIndex = Math.abs(Math.ceil((dx / sW.value) * 100));\n    const colorLength = colorGradientArr.value.length;\n    // 处理超出索引边界的情况\n    colorIndex = colorIndex >= colorLength ? colorLength - 1 : colorIndex <= 0 ? 0 : colorIndex;\n    // 设置下一个tab的颜色\n    tabsInfo.value[nextTabIndex].color = colorGradientArr.value[colorIndex];\n    // 设置当前tab的颜色\n    tabsInfo.value[nowTabIndex].color = colorGradientArr.value[colorLength - 1 - colorIndex];\n}\n\n// swiper结束滑动\nfunction setFinishCurrent(current: number) {\n    // 如果滑动的索引不一致，修改tab颜色变化，因为可能会有直接点击tab的情况\n    tabsInfo.value = tabsInfo.value.map((val, index) => {\n        val.color = current == index ? props.activeColor : props.inactiveColor;\n        return val;\n    });\n    line3AddDx.value = 0;\n    animationFinishCurrent.value = current;\n    countLine3Dx();\n}\n\n// 监听current变化\nwatch(\n    () => props.current,\n    n => {\n        setFinishCurrent(Number(n));\n    }\n);\n\n// 监听list变化\nwatch(\n    () => props.list,\n    () => {\n        nextTick(() => {\n            init();\n        });\n    }\n);\n\n// 初始化\nasync function init() {\n    countPx();\n    await getTabsInfo();\n    countLine3Dx();\n    getQuery(() => {\n        setScrollViewToCenter();\n    });\n    updateColorGradientArr();\n}\n\nonMounted(() => {\n    init();\n});\n\ndefineExpose({ init, emit, setDx, setFinishCurrent, setTabColor, setScrollViewToCenter });\n</script>\n\n<style scoped lang=\"scss\">\n@import '../../libs/css/style.components.scss';\n\nview,\nscroll-view {\n    box-sizing: border-box;\n}\n\n.u-tabs {\n    width: 100%;\n    transition-property: background-color, color;\n}\n\n::-webkit-scrollbar {\n    display: none;\n    width: 0 !important;\n    height: 0 !important;\n    -webkit-appearance: none;\n    background: transparent;\n}\n\n/* #ifdef H5 */\n// 通过样式穿透，隐藏H5下，scroll-view下的滚动条\nscroll-view ::v-deep ::-webkit-scrollbar {\n    display: none;\n    width: 0 !important;\n    height: 0 !important;\n    -webkit-appearance: none;\n    background: transparent;\n}\n\n/* #endif */\n\n.u-scroll-view {\n    width: 100%;\n    white-space: nowrap;\n    position: relative;\n}\n\n.u-tabs-scroll-box {\n    position: relative;\n}\n\n.u-tabs-scroll-flex {\n    @include vue-flex;\n    justify-content: space-between;\n}\n\n.u-tabs-scroll-flex .u-tabs-item {\n    flex: 1;\n}\n\n.u-tabs-item {\n    position: relative;\n    display: inline-block;\n    text-align: center;\n    transition-property: background-color, color, font-weight;\n}\n\n.content {\n    overflow: hidden;\n    white-space: nowrap;\n    text-overflow: ellipsis;\n}\n\n.boxStyle {\n    pointer-events: none;\n    position: absolute;\n    transition-property: all;\n}\n\n.boxStyle2 {\n    pointer-events: none;\n    position: absolute;\n    bottom: 0;\n    transition-property: all;\n    transform: translateY(-100%);\n}\n\n.itemBackgroundBox {\n    pointer-events: none;\n    position: absolute;\n    top: 0;\n    transition-property: left, background-color;\n    @include vue-flex;\n    flex-direction: row;\n    justify-content: center;\n    align-items: center;\n}\n\n.itemBackground {\n    height: 100%;\n    width: 100%;\n    transition-property: all;\n}\n\n.u-scroll-bar {\n    position: absolute;\n    bottom: 4rpx;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-tag/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { TagShape, TagMode, TagSize, ThemeType } from '../../types/global';\n\n/**\n * TagProps tag props 类型定义\n * @description 标签组件，支持多种类型、尺寸、形状、可关闭等\n */\nexport const TagProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 类型，primary、success、info、warning、error */\n    type: { type: String as PropType<ThemeType>, default: 'primary' },\n    /** 是否禁用 */\n    disabled: { type: [Boolean, String] as PropType<boolean | string>, default: false },\n    /** 尺寸，default/mini/medium */\n    size: { type: String as PropType<TagSize>, default: 'default' },\n    /** 形状，square为方形，circle为圆形 */\n    shape: { type: String as PropType<TagShape>, default: 'square' },\n    /** 显示的文本内容 */\n    text: { type: [String, Number] as PropType<string | number>, default: '' },\n    /** 文字颜色 */\n    color: { type: String, default: '' },\n    /** 背景颜色 */\n    bgColor: { type: String, default: '' },\n    /** 边框颜色 */\n    borderColor: { type: String, default: '' },\n    /** 关闭按钮颜色 */\n    closeColor: { type: String, default: '' },\n    /** 索引值 */\n    index: { type: [String, Number] as PropType<string | number>, default: '' },\n    /** 模式，light/dark/plain等 */\n    mode: { type: String as PropType<TagMode>, default: 'light' },\n    /** 是否可关闭 */\n    closeable: { type: Boolean, default: false },\n    /** 是否显示 */\n    show: { type: Boolean, default: true }\n};\n\nexport type TagProps = ExtractPropTypes<typeof TagProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-tag/u-tag.vue",
    "content": "<template>\n    <view\n        v-if=\"show\"\n        :class=\"[\n            disabled ? 'u-disabled' : '',\n            'u-size-' + size,\n            'u-shape-' + shape,\n            'u-mode-' + mode + '-' + type,\n            customClass\n        ]\"\n        class=\"u-tag\"\n        :style=\"$u.toStyle(tagStyle, customStyle)\"\n        @tap=\"clickTag\"\n    >\n        <slot>\n            {{ text }}\n        </slot>\n        <view class=\"u-icon-wrap\" @tap.stop>\n            <u-icon\n                @click=\"close\"\n                size=\"22\"\n                v-if=\"closeable\"\n                :color=\"closeIconColor\"\n                name=\"close\"\n                class=\"u-close-icon\"\n                :style=\"[iconStyle]\"\n            ></u-icon>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-tag',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { TagProps } from './types';\nimport { $u } from '../../';\n\n/**\n * tag 提示\n * @description 该组件一般用于标记和选择\n * @tutorial https://uviewpro.cn/zh/components/tag.html\n * @property {String} type 主题类型（默认primary）\n * @property {String} size 标签大小（默认default）\n * @property {String} shape 标签形状（默认square）\n * @property {String} text 标签的文字内容\n * @property {String} bg-color 自定义标签的背景颜色\n * @property {String} border-color 标签的边框颜色\n * @property {String} close-color 关闭按钮的颜色\n * @property {String|Number} index 点击标签时，会通过click事件返回该值\n * @property {String} mode 模式选择，见官网说明（默认light）\n * @property {Boolean} closeable 是否可关闭，设置为true，文字右边会出现一个关闭图标（默认false）\n * @property {Boolean} show 标签显示与否（默认true）\n * @event {Function} click 点击标签触发\n * @event {Function} close closeable为true时，点击标签关闭按钮触发\n * @example <u-tag text=\"雪月夜\" type=\"success\" />\n */\n\nconst emit = defineEmits<{\n    (e: 'click', index: string | number): void;\n    (e: 'close', index: string | number): void;\n}>();\n\nconst props = defineProps(TagProps);\n\n/**\n * 计算 tag 的自定义样式\n */\nconst tagStyle = computed(() => {\n    let style: Record<string, any> = {};\n    // 文字颜色（如果有此值，会覆盖type值的颜色）\n    if (props.color) style.color = props.color;\n    // tag的背景颜色（如果有此值，会覆盖type值的颜色）\n    if (props.bgColor) style.backgroundColor = props.bgColor;\n    // 如果是镂空型tag，没有传递边框颜色（borderColor）的话，使用文字的颜色（color属性）\n    if (props.mode === 'plain' && props.color && !props.borderColor) style.borderColor = props.color;\n    else style.borderColor = props.borderColor;\n    return style;\n});\n\n/**\n * 计算关闭图标的样式\n */\nconst iconStyle = computed(() => {\n    if (!props.closeable) return undefined;\n    let style: Record<string, any> = {};\n    if (props.size === 'mini') style.fontSize = '20rpx';\n    else style.fontSize = '22rpx';\n    if (props.mode === 'plain' || props.mode === 'light') style.color = props.type;\n    else if (props.mode === 'dark') style.color = 'var(--u-white-color)';\n    if (props.closeColor) style.color = props.closeColor;\n    return style;\n});\n\n/**\n * 关闭图标的颜色\n */\nconst closeIconColor = computed(() => {\n    // 如果定义了关闭图标的颜色，就用此值，否则用字体颜色的值\n    // 如果上面的二者都没有，如果是dark深色模式，图标就为白色\n    // 最后如果上面的三者都不合适，就返回type值给图标获取颜色\n    if (props.closeColor) return props.closeColor;\n    else if (props.color) return props.color;\n    else if (props.mode === 'dark') return 'var(--u-white-color)';\n    else return props.type;\n});\n\n/**\n * 标签被点击\n */\nfunction clickTag() {\n    // 如果是disabled状态，不发送点击事件\n    if (props.disabled) return;\n    emit('click', props.index);\n}\n\n/**\n * 点击标签关闭按钮\n */\nfunction close() {\n    emit('close', props.index);\n}\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-tag {\n    box-sizing: border-box;\n    align-items: center;\n    border-radius: 6rpx;\n    /* #ifndef APP-NVUE */\n    display: inline-block;\n    /* #endif */\n    line-height: 1;\n}\n\n.u-size-default {\n    font-size: 22rpx;\n    padding: 12rpx 22rpx;\n}\n\n.u-size-mini {\n    font-size: 20rpx;\n    padding: 6rpx 12rpx;\n}\n\n.u-mode-light-primary {\n    background-color: $u-type-primary-light;\n    color: $u-type-primary;\n    border: 1px solid $u-type-primary-disabled;\n}\n\n.u-mode-light-success {\n    background-color: $u-type-success-light;\n    color: $u-type-success;\n    border: 1px solid $u-type-success-disabled;\n}\n\n.u-mode-light-error {\n    background-color: $u-type-error-light;\n    color: $u-type-error;\n    border: 1px solid $u-type-error-disabled;\n}\n\n.u-mode-light-warning {\n    background-color: $u-type-warning-light;\n    color: $u-type-warning;\n    border: 1px solid $u-type-warning-disabled;\n}\n\n.u-mode-light-info {\n    background-color: $u-type-info-light;\n    color: $u-type-info;\n    border: 1px solid $u-type-info-disabled;\n}\n\n.u-mode-dark-primary {\n    background-color: $u-type-primary;\n    color: var(--u-white-color);\n    border: 1px solid $u-type-primary;\n}\n\n.u-mode-dark-success {\n    background-color: $u-type-success;\n    color: var(--u-white-color);\n    border: 1px solid $u-type-success;\n}\n\n.u-mode-dark-error {\n    background-color: $u-type-error;\n    color: var(--u-white-color);\n    border: 1px solid $u-type-error;\n}\n\n.u-mode-dark-warning {\n    background-color: $u-type-warning;\n    color: var(--u-white-color);\n    border: 1px solid $u-type-warning;\n}\n\n.u-mode-dark-info {\n    background-color: $u-type-info;\n    color: var(--u-white-color);\n    border: 1px solid $u-type-info;\n}\n\n.u-mode-plain-primary {\n    background-color: var(--u-bg-white);\n    color: $u-type-primary;\n    border: 1px solid $u-type-primary;\n}\n\n.u-mode-plain-success {\n    background-color: var(--u-bg-white);\n    color: $u-type-success;\n    border: 1px solid $u-type-success;\n}\n\n.u-mode-plain-error {\n    background-color: var(--u-bg-white);\n    color: $u-type-error;\n    border: 1px solid $u-type-error;\n}\n\n.u-mode-plain-warning {\n    background-color: var(--u-bg-white);\n    color: $u-type-warning;\n    border: 1px solid $u-type-warning;\n}\n\n.u-mode-plain-info {\n    background-color: var(--u-bg-white);\n    color: $u-type-info;\n    border: 1px solid $u-type-info;\n}\n\n.u-disabled {\n    opacity: 0.55;\n}\n\n.u-shape-circle {\n    border-radius: 100rpx;\n}\n\n.u-shape-circleRight {\n    border-radius: 0 100rpx 100rpx 0;\n}\n\n.u-shape-circleLeft {\n    border-radius: 100rpx 0 0 100rpx;\n}\n\n.u-close-icon {\n    margin-left: 14rpx;\n    font-size: 22rpx;\n    color: $u-type-success;\n}\n\n.u-icon-wrap {\n    display: inline-flex;\n    transform: scale(0.86);\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-td/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\n/**\n * TdProps td props 类型定义\n * @description 表格单元格组件，支持宽度自定义\n */\nexport const TdProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 宽度，百分比或者具体带单位的值，如30%， 200rpx等，一般使用百分比 */\n    width: { type: [Number, String] as PropType<number | string>, default: 'auto' }\n};\n\nexport type TdProps = ExtractPropTypes<typeof TdProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-td/u-td.vue",
    "content": "<template>\n    <view class=\"u-td\" :style=\"$u.toStyle(tdStyle, customStyle)\" :class=\"customClass\">\n        <slot></slot>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-td',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { $u, useChildren } from '../..';\nimport { TdProps } from './types';\n\n/**\n * td td单元格\n * @description 表格组件一般用于展示大量结构化数据的场景（搭配u-table使用）\n * @tutorial https://uviewpro.cn/zh/components/table.html#td-props\n * @property {String | Number} width 单元格宽度百分比或者具体带单位的值，如30%， 200rpx等，一般使用百分比，单元格宽度默认为均分tr的长度（默认auto）\n * @example <u-td>二年级</u-td>\n */\n\nconst props = defineProps(TdProps);\n\nconst { parentExposed } = useChildren('u-td', 'u-table');\n\nconst tdStyle = computed(() => {\n    const style: Record<string, any> = {};\n    if (props.width && props.width !== 'auto') style.width = props.width;\n    else style.flex = '1';\n    style.textAlign = parentExposed.value?.props?.align;\n    style.fontSize = parentExposed.value?.props?.fontSize + 'rpx';\n    style.padding = parentExposed.value?.props?.padding;\n    style.borderBottom = `solid 1px ${parentExposed.value?.props?.borderColor}`;\n    style.borderRight = `solid 1px ${parentExposed.value?.props?.borderColor}`;\n    style.color = parentExposed.value?.props?.color;\n    return style;\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-td {\n    @include vue-flex;\n    flex-direction: column;\n    // flex: 1;\n    justify-content: center;\n    font-size: 28rpx;\n    color: $u-content-color;\n    align-self: stretch;\n    box-sizing: border-box;\n    // height: 100%;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-text/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { ThemeType } from '../../types/global';\n\nexport const TextProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    // 主题颜色\n    type: { type: String as PropType<ThemeType>, default: '' },\n    /** 是否显示文本 */\n    show: { type: Boolean, default: true },\n    /** 显示的值 */\n    text: { type: [String, Number] as PropType<string | number>, default: '' },\n    /** 前置图标 */\n    prefixIcon: { type: String, default: '' },\n    /** 后置图标 */\n    suffixIcon: { type: String, default: '' },\n    /** 文本处理模式 */\n    mode: { type: String as PropType<'text' | 'price' | 'phone' | 'name' | 'date' | 'link'>, default: 'text' },\n    /** 链接地址 */\n    href: { type: String, default: '' },\n    /** 格式化规则 */\n    format: { type: [String, Function] as PropType<string | ((val: any) => any)>, default: '' },\n    /** 是否拨打电话 */\n    call: { type: Boolean, default: false },\n    /** 小程序打开方式 */\n    openType: { type: String, default: '' },\n    /** 是否粗体 */\n    bold: { type: Boolean, default: false },\n    /** 是否块状 */\n    block: { type: Boolean, default: false },\n    /** 显示行数，超出省略号 */\n    lines: { type: [String, Number] as PropType<string | number>, default: '' },\n    /** 文本颜色 */\n    color: { type: String, default: 'var(--u-main-color)' },\n    /** 字体大小 */\n    size: { type: [String, Number] as PropType<string | number>, default: 28 },\n    /** 图标样式 */\n    iconStyle: {\n        type: [Object, String] as PropType<Record<string, any> | string>,\n        default: () => ({ fontSize: '15px' })\n    },\n    /** 文字样式 */\n    textStyle: { type: [Object, String] as PropType<Record<string, any> | string>, default: () => ({}) },\n    /** 文字装饰 */\n    decoration: { type: String as PropType<'none' | 'underline' | 'line-through'>, default: 'none' },\n    /** 外边距 */\n    margin: { type: [Object, String, Number] as PropType<Record<string, any> | string | number>, default: 0 },\n    /** 行高 */\n    lineHeight: { type: [String, Number] as PropType<string | number>, default: '' },\n    /** 对齐方式 */\n    align: { type: String as PropType<'left' | 'center' | 'right'>, default: 'left' },\n    /** 换行方式 */\n    wordWrap: { type: String as PropType<'break-word' | 'normal' | 'anywhere'>, default: 'normal' },\n    /** 语言 */\n    lang: { type: String, default: '' },\n    /** 会话来源 */\n    sessionFrom: { type: String, default: '' },\n    /** 消息标题 */\n    sendMessageTitle: { type: String, default: '' },\n    /** 消息路径 */\n    sendMessagePath: { type: String, default: '' },\n    /** 消息图片 */\n    sendMessageImg: { type: String, default: '' },\n    /** 是否显示消息卡片 */\n    showMessageCard: { type: Boolean, default: false },\n    /** app参数 */\n    appParameter: { type: String, default: '' },\n    /** 表单类型 */\n    formType: { type: String, default: '' }\n};\n\nexport type TextProps = ExtractPropTypes<typeof TextProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-text/u-text.vue",
    "content": "<template>\n    <view\n        v-if=\"props.show\"\n        class=\"u-text\"\n        :class=\"[\n            props.bold ? 'u-text--bold' : '',\n            props.block ? 'u-text--block' : 'u-text--inline',\n            props.lines ? 'u-text--ellipsis u-text--block' : '',\n            `u-text--align-${props.align}`,\n            customClass\n        ]\"\n        :style=\"$u.toStyle(textStyle, customStyle)\"\n        @click=\"onClick\"\n    >\n        <!-- prefixIcon -->\n        <view class=\"u-text__icon u-text__prefix-icon\" v-if=\"props.prefixIcon\">\n            <u-icon :name=\"props.prefixIcon\" :custom-style=\"$u.toStyle(props.iconStyle)\"></u-icon>\n        </view>\n        <!-- 价格模式 -->\n        <text\n            v-if=\"props.mode === 'price'\"\n            :class=\"['u-text__price', props.type && `u-text__value--${props.type}`]\"\n            :style=\"textValueStyle\"\n        >\n            <slot>￥{{ displayValue }}</slot>\n        </text>\n        <!-- link 模式 -->\n        <u-link v-else-if=\"props.mode === 'link'\" :href=\"props.href\" underLine>\n            <slot>{{ displayValue }}</slot>\n        </u-link>\n        <template v-else-if=\"props.openType\">\n            <!-- prettier-ignore -->\n            <button\n                class=\"u-reset-button u-text__value u-text__button\"\n                :class=\"props.type && `u-text__value--${props.type}`\"\n                :style=\"textValueStyle\"\n                :openType=\"(props.openType as any)\"\n                :lang=\"(props.lang as any)\"\n                :session-from=\"props.sessionFrom\"\n                :send-message-title=\"props.sendMessageTitle\"\n                :send-message-path=\"props.sendMessagePath\"\n                :send-message-img=\"props.sendMessageImg\"\n                :show-message-card=\"props.showMessageCard\"\n                :app-parameter=\"props.appParameter\"\n                @getuserinfo=\"onGetUserInfo\"\n                @contact=\"onContact\"\n                @getphonenumber=\"onGetPhoneNumber\"\n                @error=\"onError\"\n                @launchapp=\"onLaunchApp\"\n                @opensetting=\"onOpenSetting\"\n            >\n                <slot>{{ displayValue }}</slot>\n            </button>\n        </template>\n        <!-- 默认模式 -->\n        <text\n            v-else\n            class=\"u-text__value\"\n            :style=\"textValueStyle\"\n            :class=\"[props.type && `u-text__value--${props.type}`, props.lines ? `u-line-${props.lines}` : '']\"\n        >\n            <slot>{{ displayValue }}</slot>\n        </text>\n        <!-- 后缀图标 -->\n        <view class=\"u-text__icon u-text__suffix-icon\" v-if=\"props.suffixIcon\">\n            <u-icon :name=\"props.suffixIcon\" :custom-style=\"$u.toStyle(props.iconStyle)\"></u-icon>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-text',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { TextProps } from './types';\nimport { $u } from '../../';\n\n/**\n * Text 文本\n * @description 此组件集成了文本类在项目中的常用功能，包括状态，拨打电话，格式化日期，*替换，超链接...等功能。 您大可不必在使用特殊文本时自己定义，text组件几乎涵盖您能使用的大部分场景。\n * @tutorial https://uviewpro.cn/zh/components/text.html\n * @property {String} \t\t\t\t\ttype\t\t主题颜色\n * @property {Boolean} \t\t\t\t\tshow\t\t是否显示（默认 true ）\n * @property {String | Number}\t\t\ttext\t\t显示的值\n * @property {String}\t\t\t\t\tprefixIcon\t前置图标\n * @property {String} \t\t\t\t\tsuffixIcon\t后置图标\n * @property {String} \t\t\t\t\tmode\t\t文本处理的匹配模式 text-普通文本，price-价格，phone-手机号，name-姓名，date-日期，link-超链接\n * @property {String} \t\t\t\t\thref\t\tmode=link下，配置的链接\n * @property {String | Function} \t\tformat\t\t格式化规则\n * @property {Boolean} \t\t\t\t\tcall\t\tmode=phone时，点击文本是否拨打电话（默认 false ）\n * @property {String} \t\t\t\t\topenType\t小程序的打开方式\n * @property {Boolean} \t\t\t\t\tbold\t\t是否粗体，默认normal（默认 false ）\n * @property {Boolean} \t\t\t\t\tblock\t\t是否块状（默认 false ）\n * @property {String | Number} \t\t\tlines\t\t文本显示的行数，如果设置，超出此行数，将会显示省略号\n * @property {String} \t\t\t\t\tcolor\t\t文本颜色（默认 'var(--u-main-color)' ）\n * @property {String | Number} \t\t\tsize\t\t字体大小（默认 15 ）\n * @property {Object | String} \t\t\ticonStyle\t图标的样式 （默认 {fontSize: '15px'} ）\n * @property {String} \t\t\t\t\tdecoration\t文字装饰，下划线，中划线等，可选值 none|underline|line-through（默认 'none' ）\n * @property {Object | String | Number}\tmargin\t\t外边距，对象、字符串，数值形式均可（默认 0 ）\n * @property {String | Number} \t\t\tlineHeight\t文本行高\n * @property {String} \t\t\t\t\talign\t\t文本对齐方式，可选值left|center|right（默认 'left' ）\n * @property {String} \t\t\t\t\twordWrap\t文字换行，可选值break-word|normal|anywhere（默认 'normal' ）\n * @event {Function} click  点击触发事件\n * @example <u-text text=\"我用十年青春,赴你最后之约\"></u-text>\n */\n\nconst props = defineProps(TextProps);\nconst emit = defineEmits(['click', 'getuserinfo', 'contact', 'getphonenumber', 'error', 'launchapp', 'opensetting']);\n\n// 是否小程序环境\nconst isMp = computed(() => {\n    let mp = false;\n    // #ifdef MP\n    mp = true;\n    // #endif\n    return mp;\n});\n\nconst isNvue = computed(() => {\n    let nvue = false;\n    // #ifdef APP-NVUE\n    nvue = true;\n    // #endif\n    return nvue;\n});\n\n// 处理显示的值（参考原value.js逻辑，简化实现）\nconst displayValue = computed(() => {\n    const { format, text, href, mode } = props;\n    let val = text;\n    if (typeof format === 'function') {\n        val = format(val);\n    } else if (typeof format === 'string' && format) {\n        // 可扩展字符串格式化\n    }\n    switch (mode) {\n        case 'price':\n            if (!/^\\d+(\\.\\d+)?$/.test(String(val))) return val;\n            // 如果format非正则，非函数，则使用默认的金额格式化方法进行操作\n            val = $u.formatPrice(val, 2);\n            break;\n        case 'phone':\n            // 判断是否合法的手机号\n            if (format === 'encrypt') {\n                // 如果format为encrypt，则将手机号进行星号加密处理\n                val = String(val).replace(/(\\d{3})\\d{4}(\\d{4})/, '$1****$2');\n            }\n            break;\n        case 'name':\n            // 判断是否合法的字符串\n            if (!$u.test.string(val)) return val;\n            if (format === 'encrypt') {\n                // 如果format为encrypt，则将姓名进行星号加密处理\n                return $u.formatName(String(val));\n            }\n            break;\n        case 'date':\n            // 进行格式化，判断用户传入的format参数为正则，或者函数，如果没有传入format，则使用默认的格式化处理\n            if ($u.test.string(format) && !$u.test.empty(format)) {\n                // 如果format非正则，非函数，则使用默认的时间格式化方法进行操作\n                return $u.timeFormat(val, format as string);\n            }\n            // 如果没有设置format，则设置为默认的时间格式化形式\n            return $u.timeFormat(val, 'yyyy-mm-dd');\n        case 'link':\n            if (!$u.test.url(href)) return val;\n            break;\n    }\n    return val;\n});\n\n/**\n * 获取文本样式\n */\nconst textStyle = computed(() => {\n    const style: Record<string, any> = {\n        margin: typeof props.margin === 'number' ? `${props.margin}px` : props.margin,\n        justifyContent: props.align === 'left' ? 'flex-start' : props.align === 'center' ? 'center' : 'flex-end'\n    };\n    return $u.toStyle(style);\n});\n\n/**\n * 获取文本值样式\n */\nconst textValueStyle = computed(() => {\n    const style: Record<string, any> = {\n        textDecoration: props.decoration,\n        fontWeight: props.bold ? 'bold' : 'normal',\n        wordWrap: props.wordWrap,\n        fontSize: $u.addUnit(props.size),\n        lineHeight: props.lineHeight\n            ? typeof props.lineHeight === 'number'\n                ? `${props.lineHeight}px`\n                : props.lineHeight\n            : undefined\n    };\n    if (props.lines) {\n        if (props.lines == 1) {\n            style['display'] = 'block';\n        } else {\n            style['display'] = '-webkit-box';\n            style['-webkit-box-orient'] = 'vertical';\n        }\n    }\n    if (!props.type) style.color = props.color;\n    if (isNvue.value && props.lines) style.lines = props.lines;\n    if (props.lineHeight) style.lineHeight = $u.addUnit(props.lineHeight);\n\n    // 合并 textStyle，优先对象，其次字符串\n    if ($u.test.object(props.textStyle)) {\n        // 只合并对象类型，防止类型错误\n        return $u.toStyle($u.deepMerge(style, props.textStyle as Record<string, any>));\n    }\n    if ($u.test.string(props.textStyle)) {\n        return $u.toStyle(style, props.textStyle);\n    }\n    return $u.toStyle(style);\n});\n\n/**\n * 点击事件\n */\nfunction onClick() {\n    // 如果为手机号模式，拨打电话\n    if (props.call && props.mode === 'phone') {\n        uni.makePhoneCall({\n            phoneNumber: String(props.text)\n        });\n    }\n    emit('click');\n}\nfunction onGetUserInfo(event: any) {\n    emit('getuserinfo', event.detail);\n}\nfunction onContact(event: any) {\n    emit('contact', event.detail);\n}\nfunction onGetPhoneNumber(event: any) {\n    emit('getphonenumber', event.detail);\n}\nfunction onError(event: any) {\n    emit('error', event.detail);\n}\nfunction onLaunchApp(event: any) {\n    emit('launchapp', event.detail);\n}\nfunction onOpenSetting(event: any) {\n    emit('opensetting', event.detail);\n}\n</script>\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-text {\n    @include vue-flex;\n    align-items: center;\n    flex-wrap: nowrap;\n    flex: 1;\n    word-break: break-all;\n\n    &--bold {\n        font-weight: bold;\n    }\n\n    &--inline {\n        display: inline-flex;\n    }\n\n    &--inline &__value {\n        display: inline-flex;\n    }\n\n    &--inline &__icon {\n        display: inline-flex;\n    }\n\n    &--block {\n        display: flex;\n        /* #ifndef APP-NVUE */\n        width: 100%;\n        /* #endif */\n    }\n\n    &--block &__value {\n        display: flex;\n    }\n\n    &--block &__button {\n        display: block;\n        width: 100%;\n    }\n\n    &__price {\n        font-size: 14px;\n        color: $u-content-color;\n    }\n\n    &__value {\n        font-size: 14px;\n        @include vue-flex;\n        color: $u-content-color;\n        flex-wrap: wrap;\n        text-overflow: ellipsis;\n        align-items: center;\n\n        &--primary {\n            color: $u-type-primary;\n        }\n\n        &--warning {\n            color: $u-type-warning;\n        }\n\n        &--success {\n            color: $u-type-success;\n        }\n\n        &--info {\n            color: $u-type-info;\n        }\n\n        &--error {\n            color: $u-type-error;\n        }\n\n        &--main {\n            color: $u-main-color;\n        }\n\n        &--content {\n            color: $u-content-color;\n        }\n\n        &--tips {\n            color: $u-tips-color;\n        }\n\n        &--light {\n            color: $u-light-color;\n        }\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-textarea/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { TextareaBorder, SizeType } from '../../types/global';\n\nconst textarea = {\n    value: '',\n    placeholder: '',\n    placeholderClass: 'input-placeholder',\n    placeholderStyle: 'color: var(--u-light-color)',\n    height: '',\n    confirmType: 'done',\n    disabled: false,\n    count: false,\n    focus: false,\n    autoHeight: false,\n    fixed: false,\n    cursorSpacing: 0,\n    cursor: '',\n    showConfirmBar: true,\n    selectionStart: -1,\n    selectionEnd: -1,\n    adjustPosition: true,\n    disableDefaultPadding: false,\n    holdKeyboard: false,\n    maxlength: 140,\n    border: 'surround',\n    formatter: null,\n    size: ''\n};\n\nexport const TextareaProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    // 输入框的内容\n    modelValue: { type: [String, Number] as PropType<string | number>, default: textarea.value },\n    // 输入框为空时占位符\n    placeholder: { type: [String, Number] as PropType<string | number>, default: textarea.placeholder },\n    // 指定placeholder的样式类，注意页面或组件的style中写了scoped时，需要在类名前写/deep/\n    placeholderClass: { type: String as PropType<string>, default: textarea.placeholderClass },\n    // 指定placeholder的样式\n    placeholderStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: textarea.placeholderStyle\n    },\n    // 输入框高度\n    height: { type: [String, Number] as PropType<string | number>, default: textarea.height },\n    // 设置键盘右下角按钮的文字，仅微信小程序，App-vue和H5有效\n    confirmType: { type: String as PropType<string>, default: textarea.confirmType },\n    // 是否禁用\n    disabled: { type: Boolean as PropType<boolean>, default: textarea.disabled },\n    // 是否显示统计字数\n    count: { type: Boolean as PropType<boolean>, default: textarea.count },\n    // 是否自动获取焦点，nvue不支持，H5取决于浏览器的实现\n    focus: { type: Boolean as PropType<boolean>, default: textarea.focus },\n    // 是否自动增加高度\n    autoHeight: { type: Boolean as PropType<boolean>, default: textarea.autoHeight },\n    // 如果textarea是在一个position:fixed的区域，需要显示指定属性fixed为true\n    fixed: { type: Boolean as PropType<boolean>, default: textarea.fixed },\n    // 指定光标与键盘的距离\n    cursorSpacing: { type: Number as PropType<number>, default: textarea.cursorSpacing },\n    // 指定focus时的光标位置\n    cursor: { type: [String, Number] as PropType<string | number>, default: textarea.cursor },\n    // 是否显示键盘上方带有”完成“按钮那一栏，\n    showConfirmBar: { type: Boolean as PropType<boolean>, default: textarea.showConfirmBar },\n    // 光标起始位置，自动聚焦时有效，需与selection-end搭配使用\n    selectionStart: { type: Number as PropType<number>, default: textarea.selectionStart },\n    // 光标结束位置，自动聚焦时有效，需与selection-start搭配使用\n    selectionEnd: { type: Number as PropType<number>, default: textarea.selectionEnd },\n    // 键盘弹起时，是否自动上推页面\n    adjustPosition: { type: Boolean as PropType<boolean>, default: textarea.adjustPosition },\n    // 是否去掉 iOS 下的默认内边距，只微信小程序有效\n    disableDefaultPadding: { type: Boolean as PropType<boolean>, default: textarea.disableDefaultPadding },\n    // focus时，点击页面的时候不收起键盘，只微信小程序有效\n    holdKeyboard: { type: Boolean as PropType<boolean>, default: textarea.holdKeyboard },\n    // 最大输入长度，设置为 -1 的时候不限制最大长度\n    maxlength: { type: [String, Number] as PropType<string | number>, default: textarea.maxlength },\n    // 边框类型，surround-四周边框，bottom-底部边框\n    border: { type: [String, Boolean] as PropType<TextareaBorder | boolean>, default: textarea.border },\n    // 用于处理或者过滤输入框内容的方法\n    formatter: { type: Function as unknown as PropType<((val: any) => any) | null>, default: textarea.formatter },\n    // 是否忽略组件内对文本合成系统事件的处理\n    ignoreCompositionEvent: { type: Boolean as PropType<boolean>, default: true },\n    /** 文本域文字大小(默认default)，支持 small/default/large 预设值，也支持 16/16px/16rpx 等自定义值 */\n    size: { type: [String, Number] as PropType<SizeType | string | number>, default: textarea.size },\n    /** 是否可清空(默认true) */\n    clearable: { type: Boolean, default: true },\n    /** 输入框的验证状态，用于错误时，边框是否改为红色 */\n    validateState: { type: Boolean, default: false }\n};\n\nexport type TextareaProps = ExtractPropTypes<typeof TextareaProps>;\n\nexport default TextareaProps;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-textarea/u-textarea.vue",
    "content": "<template>\n    <view\n        class=\"u-textarea\"\n        :class=\"[\n            {\n                'u-textarea--error': validateState\n            },\n            textareaClass,\n            customClass\n        ]\"\n        :style=\"$u.toStyle(textareaStyle, customStyle)\"\n    >\n        <!-- prettier-ignore -->\n        <textarea\n            class=\"u-textarea__field\"\n            :value=\"innerValue\"\n            :style=\"getStyle\"\n            :placeholder=\"String(props.placeholder)\"\n            :placeholder-style=\"getPlaceholderStyle\"\n            :placeholder-class=\"props.placeholderClass\"\n            :disabled=\"props.disabled\"\n            :focus=\"props.focus\"\n            :autoHeight=\"props.autoHeight\"\n            :fixed=\"props.fixed\"\n            :cursorSpacing=\"props.cursorSpacing\"\n            :cursor=\"Number(props.cursor)\"\n            :showConfirmBar=\"props.showConfirmBar\"\n            :selectionStart=\"props.selectionStart\"\n            :selectionEnd=\"props.selectionEnd\"\n            :adjustPosition=\"props.adjustPosition\"\n            :disableDefaultPadding=\"props.disableDefaultPadding\"\n            :holdKeyboard=\"props.holdKeyboard\"\n            :maxlength=\"Number(props.maxlength)\"\n            :confirmType=\"(props.confirmType as any)\"\n            :ignoreCompositionEvent=\"props.ignoreCompositionEvent\"\n            @focus=\"onFocus\"\n            @blur=\"onBlur\"\n            @linechange=\"onLinechange\"\n            @input=\"onInput\"\n            @confirm=\"onConfirm\"\n            @keyboardheightchange=\"onKeyboardheightchange\"\n        ></textarea>\n        <text\n            class=\"u-textarea__count\"\n            :style=\"{\n                'background-color': props.disabled ? 'transparent' : 'var(--u-bg-white)',\n                'font-size': currentCountSize\n            }\"\n            v-if=\"props.count\"\n        >\n            {{ innerValue.length }}/{{ props.maxlength }}\n        </text>\n\n        <view class=\"u-textarea__right-icon u-flex\">\n            <view\n                class=\"u-textarea__right-icon__clear u-textarea__right-icon__item\"\n                v-if=\"clearable && modelValue != '' && !disabled\"\n                :class=\"{ 'u-hidden': !focused }\"\n            >\n                <u-icon\n                    name=\"close-circle-fill\"\n                    color=\"var(--u-light-color)\"\n                    :size=\"currentIconSize\"\n                    @click=\"onClear\"\n                />\n            </view>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-textarea',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, nextTick } from 'vue';\nimport { TextareaProps } from './types';\nimport { $u, useChildren } from '../../';\nimport type { SizeType } from '../../types/global';\n\n/**\n * Textarea 文本域\n * @description 文本域此组件满足了可能出现的表单信息补充，编辑等实际逻辑的功能，内置了字数校验等\n * @tutorial https://uviewpro.cn/zh/components/textarea.html\n * @property {String | Number} \t\tvalue\t\t\t\t\t输入框的内容\n * @property {String | Number}\t\tplaceholder\t\t\t\t输入框为空时占位符\n * @property {String}\t\t\t    placeholderClass\t\t指定placeholder的样式类，注意页面或组件的style中写了scoped时，需要在类名前写/deep/ （ 默认 'input-placeholder' ）\n * @property {String | Object}\t    placeholderStyle\t\t指定placeholder的样式，字符串/对象形式，如\"color: red;\"\n * @property {String | Number}\t\theight\t\t\t\t\t输入框高度（默认 70 ）\n * @property {String}\t\t\t\tconfirmType\t\t\t\t设置键盘右下角按钮的文字，仅微信小程序，App-vue和H5有效（默认 'done' ）\n * @property {Boolean}\t\t\t\tdisabled\t\t\t\t是否禁用（默认 false ）\n * @property {Boolean}\t\t\t\tcount\t\t\t\t\t是否显示统计字数（默认 false ）\n * @property {Boolean}\t\t\t\tfocus\t\t\t\t\t是否自动获取焦点，nvue不支持，H5取决于浏览器的实现（默认 false ）\n * @property {Boolean | Function}\tautoHeight\t\t\t\t是否自动增加高度（默认 false ）\n * @property {Boolean}\t\t\t\tfixed\t\t\t\t\t如果textarea是在一个position:fixed的区域，需要显示指定属性fixed为true（默认 false ）\n * @property {Number}\t\t\t\tcursorSpacing\t\t\t指定光标与键盘的距离（默认 0 ）\n * @property {String | Number}\t\tcursor\t\t\t\t\t指定focus时的光标位置\n * @property {Function}\t\t\t    formatter\t\t\t    内容式化函数\n * @property {Boolean}\t\t\t\tshowConfirmBar\t\t\t是否显示键盘上方带有”完成“按钮那一栏，（默认 true ）\n * @property {Number}\t\t\t\tselectionStart\t\t\t光标起始位置，自动聚焦时有效，需与selection-end搭配使用，（默认 -1 ）\n * @property {Number | Number}\t\tselectionEnd\t\t\t光标结束位置，自动聚焦时有效，需与selection-start搭配使用（默认 -1 ）\n * @property {Boolean}\t\t\t\tadjustPosition\t\t\t键盘弹起时，是否自动上推页面（默认 true ）\n * @property {Boolean | Number}\t\tdisableDefaultPadding\t是否去掉 iOS 下的默认内边距，只微信小程序有效（默认 false ）\n * @property {Boolean}\t\t\t\tholdKeyboard\t\t\tfocus时，点击页面的时候不收起键盘，只微信小程序有效（默认 false ）\n * @property {String | Number}\t\tmaxlength\t\t\t\t最大输入长度，设置为 -1 的时候不限制最大长度（默认 140 ）\n * @property {String}\t\t\t\tborder\t\t\t\t\t边框类型，surround-四周边框，none-无边框，bottom-底部边框（默认 'surround' ）\n * @property {Boolean}\t\t\t\tignoreCompositionEvent\t是否忽略组件内对文本合成系统事件的处理\n * @event {Function(e)} focus\t\t\t\t\t输入框聚焦时触发，event.detail = { value, height }，height 为键盘高度\n * @event {Function(e)} blur\t\t\t\t\t输入框失去焦点时触发，event.detail = {value, cursor}\n * @event {Function(e)} linechange\t\t\t\t输入框行数变化时调用，event.detail = {height: 0, heightRpx: 0, lineCount: 0}\n * @event {Function(e)} input\t\t\t\t\t当键盘输入时，触发 input 事件\n * @event {Function(e)} confirm\t\t\t\t\t点击完成时， 触发 confirm 事件\n * @event {Function(e)} keyboardheightchange\t键盘高度发生变化的时候触发此事件\n * @example <u-textarea v-model=\"value1\" placeholder=\"请输入内容\" ></u-textarea>\n */\n\nconst props = defineProps(TextareaProps);\nconst emit = defineEmits([\n    'update:modelValue',\n    'focus',\n    'blur',\n    'linechange',\n    'input',\n    'confirm',\n    'keyboardheightchange',\n    'change'\n]);\n\nconst { emitToParent } = useChildren('u-textarea', 'u-form-item');\nconst { parentExposed } = useChildren('u-textarea', 'u-form');\n\n// state\nconst innerValue = ref('');\nconst focused = ref(false);\nconst firstChange = ref(true);\nconst changeFromInner = ref(false);\nconst innerFormatter = ref((v: any) => v);\nconst validateState = ref(props.validateState); // 当前input的验证状态，用于错误时，边框是否改为红色\n\n// 根据 size 定义不同的配置\nconst sizeConfig = {\n    small: {\n        fontSize: 24,\n        iconSize: 28,\n        countSize: 20,\n        textareaHeight: 70\n    },\n    default: {\n        fontSize: 28,\n        iconSize: 32,\n        countSize: 24,\n        textareaHeight: 100\n    },\n    large: {\n        fontSize: 32,\n        iconSize: 36,\n        countSize: 24,\n        textareaHeight: 130\n    }\n};\n\n// 获取实际使用的 size 值（优先级：props.size > u-form.size）\nconst actualSize = computed(() => {\n    // 优先使用 props 的 size 属性\n    if (props.size !== '') {\n        return String(props.size);\n    }\n    // 次优先：使用 u-form 的 size 属性（u-form 的 size 只支持预设值）\n    if (parentExposed.value?.props?.size) {\n        return String(parentExposed.value.props.size);\n    }\n    // 默认值\n    return 'default';\n});\n\n// 判断实际使用的 size 是否在预设配置中\nconst isInSizeConfig = computed(() => actualSize.value in sizeConfig);\n\n// 获取预设 size（用于查找 sizeConfig 配置，如图标大小、高度等）\nconst presetSize = computed(() => {\n    return (isInSizeConfig.value ? actualSize.value : 'default') as SizeType;\n});\n\n// 获取当前尺寸配置\nconst currentSizeConfig = computed(() => sizeConfig[presetSize.value]);\n\n// 获取实际要使用的 font-size（如果是预设值使用配置值，否则作为自定义值处理）\nconst actualFontSize = computed(() => {\n    if (isInSizeConfig.value) {\n        return $u.addUnit(currentSizeConfig.value.fontSize);\n    }\n    // 自定义size值，直接作为fontSize处理\n    return $u.addUnit(actualSize.value);\n});\n\n// 计算当前图标大小\nconst currentIconSize = computed(() => currentSizeConfig.value.iconSize);\n// 计算统计显示的字体大小\nconst currentCountSize = computed(() => $u.addUnit(currentSizeConfig.value.countSize));\n\n// watch value prop\nwatch(\n    () => props.modelValue,\n    (newVal: any) => {\n        innerValue.value = newVal;\n        /* #ifdef H5 */\n        // 在H5中，外部value变化后，修改input中的值，不会触发@input事件，此时手动调用值变化方法\n        if (firstChange.value === false && changeFromInner.value === false) {\n            valueChange();\n        }\n        /* #endif */\n        firstChange.value = false;\n        // 重置changeFromInner的值为false，标识下一次引起默认为外部引起的\n        changeFromInner.value = false;\n    },\n    { immediate: true }\n);\n\n// 监听 validateState 变化\nwatch(\n    () => props.validateState,\n    val => {\n        validateState.value = val;\n    }\n);\n\n// 组件的类名\nconst textareaClass = computed(() => {\n    let classes: string[] = [];\n    if (props.border && props.border !== 'none') {\n        if (props.border === 'surround') {\n            classes = classes.concat(['u-textarea--border', 'u-textarea--radius']);\n        } else if (props.border === 'bottom') {\n            classes = classes.concat(['u-border-bottom', 'u-textarea--no-radius']);\n        } else {\n            classes = classes.concat(['u-textarea--border', 'u-textarea--radius']);\n        }\n    }\n    props.disabled && classes.push('u-textarea--disabled');\n    return classes.join(' ');\n});\n\n// 组件的样式\nconst textareaStyle = computed(() => {\n    const style: Record<string, any> = {};\n    if (props.border && props.border !== 'none') {\n        style.padding = `${props.border ? 20 : 0}rpx`;\n    }\n    // #ifdef APP-NVUE\n    if ($u.os() === 'android') {\n        style.paddingTop = '6px';\n        style.paddingLeft = '9px';\n        style.paddingBottom = '3px';\n        style.paddingRight = '6px';\n    }\n    // #endif\n    return style;\n});\n\nconst getStyle = computed(() => {\n    let style: Record<string, any> = {};\n    // 如果没有自定义高度，就根据textarea来分配一个默认的高度\n    if (props.autoHeight) {\n        style.minHeight = $u.addUnit(props.height ? props.height : currentSizeConfig.value.textareaHeight);\n        style.height = 'auto';\n    } else {\n        style.height = $u.addUnit(props.height ? props.height : currentSizeConfig.value.textareaHeight);\n    }\n    // 根据 size 属性设置字体大小\n    style.fontSize = actualFontSize.value;\n    return $u.toStyle(style, props.customStyle);\n});\n\nconst getPlaceholderStyle = computed(() => {\n    return $u.toStyle(\n        {\n            fontSize: actualFontSize.value\n        },\n        props.placeholderStyle\n    );\n});\n\nfunction onFormItemError(status: boolean) {\n    validateState.value = status;\n}\n\n// methods\nfunction setFormatter(e: any) {\n    innerFormatter.value = e;\n}\n\nfunction onFocus(e: any) {\n    focused.value = true;\n    emit('focus', e);\n}\n\nfunction onBlur(e: any) {\n    setTimeout(() => {\n        e.detail.value = innerValue.value;\n        let value = e.detail.value;\n        focused.value = false;\n        emit('blur', e);\n        emitToParent('onFormBlur', value);\n    }, 40);\n}\n\nfunction onLinechange(e: any) {\n    emit('linechange', e);\n}\n\nfunction onInput(e: any) {\n    let { value = '' } = e.detail || {};\n    // 格式化过滤方法\n    const formatter = props.formatter || innerFormatter.value;\n    const formatValue = typeof formatter === 'function' ? formatter(value) : value;\n    // 为了避免props的单向数据流特性，需要先将innerValue值设置为当前值，再在$nextTick中重新赋予设置后的值才有效\n    innerValue.value = value;\n    nextTick(() => {\n        innerValue.value = formatValue;\n        valueChange();\n    });\n}\n\nfunction valueChange() {\n    const value = innerValue.value;\n    nextTick(() => {\n        emit('input', value);\n        emit('update:modelValue', value);\n        // 标识value值的变化是由内部引起的\n        changeFromInner.value = true;\n        emit('change', value);\n        emitToParent('onFormChange', value);\n    });\n}\n\nfunction onConfirm(e: any) {\n    emit('confirm', e);\n}\n\nfunction onKeyboardheightchange(e: any) {\n    emit('keyboardheightchange', e);\n}\nfunction onClear(event: any) {\n    try {\n        event.stopPropagation();\n    } catch (e) {\n        console.log(e);\n    }\n    innerValue.value = '';\n    valueChange();\n}\n\ndefineExpose({\n    onFormItemError\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-textarea {\n    border-radius: 4px;\n    background-color: var(--u-bg-white);\n    position: relative;\n    @include flex;\n    flex: 1;\n\n    &--border {\n        border-radius: 4px;\n        border: 1px solid $u-border-color;\n    }\n\n    &--error {\n        border-color: $u-type-error !important;\n    }\n\n    &--radius {\n        border-radius: 4px;\n    }\n\n    &--no-radius {\n        border-radius: 0;\n    }\n\n    &--disabled {\n        background-color: $u-bg-gray-light;\n    }\n\n    &__field {\n        flex: 1;\n        font-size: 28rpx;\n        color: $u-content-color;\n        width: 100%;\n    }\n\n    &__count {\n        position: absolute;\n        right: 1px;\n        bottom: 0;\n        font-size: 12px;\n        color: $u-tips-color;\n        background-color: var(--u-bg-white);\n        padding: 1px 4px;\n        border-radius: 10px;\n        line-height: 16px;\n    }\n\n    &__right-icon {\n        &__item {\n            margin-left: 10rpx;\n        }\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-th/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\n/**\n * ThProps th props 类型定义\n * @description 表格表头单元格组件，支持宽度自定义\n */\nexport const ThProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 宽度，百分比或者具体带单位的值，如30%， 200rpx等，一般使用百分比 */\n    width: { type: [Number, String] as PropType<number | string>, default: 'auto' }\n};\n\nexport type ThProps = ExtractPropTypes<typeof ThProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-th/u-th.vue",
    "content": "<template>\n    <view class=\"u-th\" :style=\"$u.toStyle(thStyle, customStyle)\" :class=\"customClass\">\n        <slot></slot>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-th',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { $u, useChildren } from '../..';\nimport { ThProps } from './types';\n\n/**\n * th th单元格\n * @description 表格组件一般用于展示大量结构化数据的场景（搭配u-table使用）\n * @tutorial https://uviewpro.cn/zh/components/table.html#td-props\n * @property {String | Number} width 标题单元格宽度百分比或者具体带单位的值，如30%，200rpx等，一般使用百分比，单元格宽度默认为均分tr的长度\n * @example 暂无示例\n */\n\nconst props = defineProps(ThProps);\n\nconst { parentExposed } = useChildren('u-th', 'u-table');\n\nconst thStyle = computed(() => {\n    const style: Record<string, any> = {};\n    if (props.width && props.width !== 'auto') style.width = props.width;\n    else style.flex = '1';\n    style.textAlign = parentExposed.value?.props?.align;\n    style.padding = parentExposed.value?.props?.padding;\n    style.borderBottom = `solid 1px ${parentExposed.value?.props?.borderColor}`;\n    style.borderRight = `solid 1px ${parentExposed.value?.props?.borderColor}`;\n    Object.assign(style, parentExposed.value?.props?.thStyle);\n    return style;\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-th {\n    @include vue-flex;\n    flex-direction: column;\n    // flex: 1;\n    justify-content: center;\n    font-size: 28rpx;\n    color: $u-main-color;\n    font-weight: bold;\n    background-color: $u-bg-color;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-time-line/u-time-line.vue",
    "content": "<template>\n    <view class=\"u-time-axis\" :class=\"customClass\" :style=\"$u.toStyle(customStyle)\">\n        <slot />\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-time-line',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport type { PropType } from 'vue';\nimport { $u } from '../../';\n\n/**\n * timeLine 时间轴\n * @description 时间轴组件一般用于物流信息展示，各种跟时间相关的记录等场景。\n * @tutorial https://uviewpro.cn/zh/components/timeLine.html\n * @example <u-time-line></u-time-line>\n */\n\nconst props = defineProps({\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    }\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-time-axis {\n    padding-left: 40rpx;\n    position: relative;\n}\n\n.u-time-axis::before {\n    content: ' ';\n    position: absolute;\n    left: 0;\n    top: 12rpx;\n    width: 1px;\n    bottom: 0;\n    border-left: 1px solid var(--u-divider-color);\n    transform-origin: 0 0;\n    transform: scaleX(0.5);\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-time-line-item/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\n/**\n * TimeLineItemProps 时间轴节点 props 类型定义\n * @description 时间轴节点组件，支持自定义节点颜色、位置\n */\nexport const TimeLineItemProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 节点的背景颜色 */\n    bgColor: { type: String, default: 'var(--u-bg-white)' },\n    /** 节点左边图标绝对定位的top值，单位rpx */\n    nodeTop: { type: [String, Number] as PropType<string | number>, default: '' }\n};\n\nexport type TimeLineItemProps = ExtractPropTypes<typeof TimeLineItemProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-time-line-item/u-time-line-item.vue",
    "content": "<template>\n    <view class=\"u-time-axis-item\" :class=\"customClass\" :style=\"$u.toStyle(customStyle)\">\n        <slot name=\"content\" />\n        <view class=\"u-time-axis-node\" :style=\"[nodeStyle]\">\n            <slot name=\"node\">\n                <view class=\"u-dot\"> </view>\n            </slot>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-time-line-item',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { TimeLineItemProps } from './types';\nimport { $u } from '../../';\n\n/**\n * timeLineItem 时间轴Item\n * @description 时间轴组件一般用于物流信息展示，各种跟时间相关的记录等场景。(搭配u-time-line使用)\n * @tutorial https://uviewpro.cn/zh/components/timeLine.html\n * @property {String} bg-color 左边节点的背景颜色，一般通过slot内容自定义背景颜色即可（默认var(--u-bg-white)）\n * @property {String | Number} node-top 节点左边图标绝对定位的top值，单位rpx\n * @example <u-time-line-item node-top=\"2\">...</u-time-line-item>\n */\n\n/**\n * 节点的背景颜色\n */\nconst props = defineProps(TimeLineItemProps);\n\n/**\n * 计算节点样式\n * @returns 节点样式对象\n */\nconst nodeStyle = computed(() => {\n    // 生成节点样式对象\n    const style: Record<string, string> = {\n        backgroundColor: props.bgColor\n    };\n    // 如果设置了 nodeTop，则添加 top 属性\n    if (props.nodeTop !== '') style.top = String(props.nodeTop) + 'rpx';\n    return style;\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-time-axis-item {\n    @include vue-flex;\n    flex-direction: column;\n    width: 100%;\n    position: relative;\n    margin-bottom: 32rpx;\n}\n\n.u-time-axis-node {\n    position: absolute;\n    top: 12rpx;\n    left: -40rpx;\n    transform-origin: 0;\n    transform: translateX(-50%);\n    @include vue-flex;\n    align-items: center;\n    justify-content: center;\n    z-index: 1;\n    font-size: 24rpx;\n}\n\n.u-dot {\n    height: 16rpx;\n    width: 16rpx;\n    border-radius: 100rpx;\n    background: var(--u-divider-color);\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-toast/service.ts",
    "content": "/**\n * u-toast 函数式调用事件名（全平台）\n * @description\n * - useToast() 通过 uni.$emit 派发事件\n * - <u-toast /> 通过 uni.$on 监听事件并转调自身 show/hide\n */\n\nimport type { ToastProps } from './types';\n\n// 普通（页面级）toast 事件\nexport const U_TOAST_EVENT_SHOW = 'uview-pro:u-toast:show:';\nexport const U_TOAST_EVENT_HIDE = 'uview-pro:u-toast:hide:';\n\n// 全局（App 根部）toast 事件，供 useToast() 使用\nexport const U_TOAST_GLOBAL_EVENT_SHOW = 'uview-pro:u-toast:global:show';\nexport const U_TOAST_GLOBAL_EVENT_HIDE = 'uview-pro:u-toast:global:hide';\n\n// 根据当前页面获取事件名\nexport function getEventWithCurrentPage(event: string, page?: string | boolean) {\n    if (page && typeof page === 'string' && page !== '') {\n        return event + page;\n    }\n    return event + getCurrentPage();\n}\n\n// 获取当前页面路由\nfunction getCurrentPage() {\n    try {\n        const pages = getCurrentPages();\n        const currentPage = pages[pages.length - 1].route as string;\n        return currentPage || '';\n    } catch (error) {\n        return '';\n    }\n}\n\nexport type ToastPayload = Partial<ToastProps> & {\n    /** 文案（兼容 toast.show('xxx')） */\n    title?: string;\n};\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-toast/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { ThemeType, ToastPosition } from '../../types/global';\nimport zIndex from '../../libs/config/zIndex';\n\n/**\n * ToastProps toast props 类型定义\n * @description 消息提示组件，支持 z-index 及多种配置项\n */\nexport const ToastProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 层级 z-index */\n    zIndex: { type: [Number, String] as PropType<number | string>, default: zIndex.toast },\n    /** 提示类型，success/warning/error/loading 等 */\n    type: { type: String as PropType<ThemeType | 'default'>, default: '' },\n    /** 显示时长，单位ms。设为 0 表示不自动关闭，需手动调用 hide/close 方法 */\n    duration: { type: Number, default: 2000 },\n    /** 是否显示图标 */\n    icon: { type: Boolean, default: true },\n    /** 显示位置，center/top/bottom */\n    position: { type: String as PropType<ToastPosition>, default: 'center' },\n    /** 关闭时的回调函数 */\n    callback: { type: Function as unknown as PropType<(() => void) | null>, default: null },\n    /** 是否返回上一页 */\n    back: { type: Boolean, default: false },\n    /** 是否为tab页面跳转 */\n    isTab: { type: Boolean, default: false },\n    /** 跳转的url */\n    url: { type: String, default: '' },\n    /** 跳转参数对象 */\n    params: { type: Object as PropType<Record<string, any>>, default: () => ({}) },\n    /** 是否作为全局根部 toast（通常放在 App.vue 中，给 useToast() 使用） */\n    global: { type: Boolean, default: false },\n    /** 是否作为页面级 toast（通常放在页面中，给 useToast({ page: true }) 使用） */\n    page: { type: [Boolean, String] as PropType<boolean | string>, default: false },\n    /** 是否为loading “常驻” */\n    loading: { type: Boolean, default: false }\n};\n\nexport type ToastProps = ExtractPropTypes<typeof ToastProps>;\n\nexport type ToastExpose = {\n    show: (options: Record<string, any>) => void;\n    hide: () => void;\n    close: () => void;\n};\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-toast/u-toast.vue",
    "content": "<template>\n    <u-mask :z-index=\"uZIndex\" :show=\"isShow\" custom-style=\"background-color:transparent;\">\n        <view\n            class=\"u-toast\"\n            :class=\"[\n                isShow ? 'u-show' : '',\n                'u-type-' + tmpConfig.type,\n                'u-position-' + tmpConfig.position,\n                customClass\n            ]\"\n            :style=\"$u.toStyle({ zIndex: uZIndex }, customStyle)\"\n        >\n            <view class=\"u-icon-wrap\">\n                <!-- loading 类型走独立的加载动画组件 -->\n                <u-loading\n                    v-if=\"tmpConfig.loading\"\n                    mode=\"circle\"\n                    custom-style=\"margin-right: 16rpx;\"\n                    :color=\"($u.color as any)[tmpConfig.type]\"\n                ></u-loading>\n                <!-- 其它类型仍然使用图标 -->\n                <u-icon\n                    v-else-if=\"tmpConfig.icon && iconName\"\n                    custom-class=\"u-toast_icon\"\n                    custom-style=\"margin-right: 10rpx;\"\n                    :name=\"iconName\"\n                    :size=\"40\"\n                    :color=\"tmpConfig.type\"\n                ></u-icon>\n            </view>\n            <text class=\"u-text\">{{ tmpConfig.title }}</text>\n        </view>\n    </u-mask>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-toast',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, onMounted, onBeforeUnmount } from 'vue';\nimport { onPageHide, onPageShow } from '@dcloudio/uni-app';\nimport { $u } from '../..';\nimport type { ToastExpose } from './types';\nimport { ToastProps } from './types';\nimport {\n    U_TOAST_EVENT_HIDE,\n    U_TOAST_EVENT_SHOW,\n    U_TOAST_GLOBAL_EVENT_HIDE,\n    U_TOAST_GLOBAL_EVENT_SHOW,\n    getEventWithCurrentPage,\n    type ToastPayload\n} from './service';\n\n/**\n * toast 消息提示\n * @description 此组件表现形式类似uni的uni.showToastAPI，但也有不同的地方。\n * @tutorial https://uviewpro.cn/zh/components/toast.html\n * @property {String|Number} z-index toast展示时的z-index值\n * @event {Function} show 显示toast，如需一进入页面就显示toast，请在onReady生命周期调用\n * @example <u-toast ref=\"uToast\" />\n */\nconst props = defineProps(ToastProps);\n// 是否已经初始化事件监听\nconst isInit = ref(false);\n// 是否显示toast\nconst isShow = ref(false);\n// 定时器\nlet timer: ReturnType<typeof setTimeout> | null = null;\n// 内置配置\nconst config = computed(() => {\n    return {\n        zIndex: props.zIndex, // z-index值\n        type: props.type, // 主题类型，primary，success，error，warning，black\n        duration: props.duration, // 显示的时间，毫秒\n        icon: props.icon, // 显示的图标\n        position: props.position, // toast出现的位置\n        callback: props.callback, // 执行完后的回调函数\n        back: props.back, // 结束toast是否自动返回上一页\n        isTab: props.isTab, // 是否跳转tab页面\n        url: props.url, // toast消失后是否跳转页面，有则跳转，优先级高于back参数\n        params: props.params, // URL跳转的参数，对象\n        loading: props.loading,\n        title: '' // 显示文本\n    };\n});\n// 合并后的临时配置变量\nconst tmpConfig = ref<any>({ ...config.value });\n\n/**\n * 只有不为none，并且type为error|warning|success|info时候，才显示图标\n */\nconst iconName = computed(() => {\n    if (['error', 'warning', 'success', 'info'].indexOf(tmpConfig.value.type) >= 0 && tmpConfig.value.icon) {\n        let icon = $u.type2icon(tmpConfig.value.type);\n        return icon;\n    }\n    return '';\n});\n/**\n * 显示toast时候，如果用户有传递z-index值，优先使用\n */\nconst uZIndex = computed(() => {\n    return isShow.value ? (props.zIndex ? props.zIndex : $u.zIndex.toast) : '999999';\n});\n\n/**\n * 显示toast组件，由父组件通过ref.show(options)形式调用\n * @description 当 duration 为 0 或不传时，表示不自动关闭，需要手动调用 hide/close 方法关闭\n */\nfunction show(options: any) {\n    // 不将结果合并到config变量，避免多次调用u-toast，前后的配置造成混乱\n    tmpConfig.value = $u.deepMerge(config.value, options);\n    if (timer) {\n        // 清除定时器\n        clearTimeout(timer);\n        timer = null;\n    }\n    isShow.value = true;\n    // duration 为 0、undefined 或小于等于 0 时，表示不自动关闭，需要手动调用 hide/close\n    if (tmpConfig.value.duration > 0) {\n        timer = setTimeout(() => {\n            // 倒计时结束，清除定时器，隐藏toast组件\n            isShow.value = false;\n            clearTimeout(timer!);\n            timer = null;\n            // 判断是否存在callback方法，如果存在就执行\n            typeof tmpConfig.value.callback === 'function' && tmpConfig.value.callback();\n            timeEnd();\n        }, tmpConfig.value.duration);\n    }\n}\n/**\n * 隐藏toast组件，由父组件通过ref.hide()形式调用\n */\nfunction hide() {\n    isShow.value = false;\n    if (timer) {\n        // 清除定时器\n        clearTimeout(timer);\n        timer = null;\n    }\n}\n/**\n * 倒计时结束之后，进行的一些操作\n */\nfunction timeEnd() {\n    // 如果带有url值，根据isTab为true或者false进行跳转\n    if (tmpConfig.value.url) {\n        // 如果url没有\"/\"开头，添加上，因为uni的路由跳转需要\"/\"开头\n        if (tmpConfig.value.url[0] != '/') tmpConfig.value.url = '/' + tmpConfig.value.url;\n        // 判断是否有传递显式的参数\n        if (Object.keys(tmpConfig.value.params).length) {\n            // 判断用户传递的url中，是否带有参数\n            // 使用正则匹配，主要依据是判断是否有\"/\",\"?\",\"=\"等，如“/page/index/index?name=mary\"\n            // 如果有params参数，转换后无需带上\"?\"\n            let query = '';\n            if (/.*\\/.*\\?.*=.*/.test(tmpConfig.value.url)) {\n                // object对象转为get类型的参数\n                query = $u.queryParams(tmpConfig.value.params, false);\n                tmpConfig.value.url = tmpConfig.value.url + '&' + query;\n            } else {\n                query = $u.queryParams(tmpConfig.value.params);\n                tmpConfig.value.url += query;\n            }\n        }\n        // 如果是跳转tab页面，就使用uni.switchTab\n        if (tmpConfig.value.isTab) {\n            uni.switchTab({ url: tmpConfig.value.url });\n        } else {\n            uni.navigateTo({ url: tmpConfig.value.url });\n        }\n    } else if (tmpConfig.value.back) {\n        // 回退到上一页\n        $u.route({ type: 'back' });\n    }\n}\n\n/**\n * @description\n * 函数式调用支持：\n * - useToast() 内部通过 uni.$emit 派发「全局」事件，仅由 App 根部的 <u-toast global /> 承接\n * - 普通页面级 <u-toast /> 监听「页面级」事件（当前版本暂未开放对应函数式 API，仅支持 ref 调用）\n * - 不影响原有 ref.show()/ref.hide() 使用方式\n */\nfunction onServiceShow(payload: ToastPayload) {\n    show(payload || {});\n}\nfunction onServiceHide() {\n    hide();\n}\n\n// 是否为 App 根部的“全局 toast”\nconst isGlobal = computed(() => !!props.global);\n// 是否为页面级 toast\nconst isPage = computed(() => !!props.page);\n\n// 显示事件\nconst showEvent = computed(() =>\n    isGlobal.value\n        ? U_TOAST_GLOBAL_EVENT_SHOW\n        : isPage.value\n          ? getEventWithCurrentPage(U_TOAST_EVENT_SHOW, props.page)\n          : ''\n);\n\n// 隐藏事件\nconst hideEvent = computed(() =>\n    isGlobal.value\n        ? U_TOAST_GLOBAL_EVENT_HIDE\n        : isPage.value\n          ? getEventWithCurrentPage(U_TOAST_EVENT_HIDE, props.page)\n          : ''\n);\n\n// 开始监听事件\nfunction startListeners() {\n    if (isInit.value) {\n        return;\n    }\n    isInit.value = true;\n    if (showEvent.value) {\n        uni?.$on && uni.$on(showEvent.value, onServiceShow);\n    }\n    if (hideEvent.value) {\n        uni?.$on && uni.$on(hideEvent.value, onServiceHide);\n    }\n}\n\n// 停止监听事件\nfunction stopListeners() {\n    if (!isInit.value) {\n        return;\n    }\n    isInit.value = false;\n    if (showEvent.value) {\n        uni?.$off && uni.$off(showEvent.value, onServiceShow);\n    }\n    if (hideEvent.value) {\n        uni?.$off && uni.$off(hideEvent.value, onServiceHide);\n    }\n}\n\n// 移除所有事件监听\nfunction removeAllListeners() {\n    if (showEvent.value) {\n        uni?.$off && uni.$off(showEvent.value);\n    }\n    if (hideEvent.value) {\n        uni?.$off && uni.$off(hideEvent.value);\n    }\n}\n\nonPageShow(() => {\n    startListeners();\n});\n\nonPageHide(() => {\n    stopListeners();\n});\n\nonMounted(() => {\n    startListeners();\n});\n\nonBeforeUnmount(() => {\n    stopListeners();\n});\n\ndefineExpose<ToastExpose>({\n    show,\n    hide,\n    close: hide\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-toast {\n    position: fixed;\n    z-index: -1;\n    transition: opacity 0.3s;\n    text-align: center;\n    color: var(--u-white-color);\n    border-radius: 8rpx;\n    background: var(--u-content-color);\n    @include vue-flex;\n    align-items: center;\n    justify-content: center;\n    font-size: 28rpx;\n    opacity: 0;\n    pointer-events: none;\n    padding: 30rpx 40rpx;\n}\n\n.u-toast.u-show {\n    opacity: 1;\n}\n\n.u-icon-wrap {\n    /* #ifdef H5 */\n    padding-top: 6rpx;\n    /* #endif */\n}\n\n.u-text {\n    word-break: break-all;\n}\n\n:deep(.u-toast_icon) {\n    margin-right: 10rpx;\n    @include vue-flex;\n    align-items: center;\n    line-height: normal;\n}\n\n.u-position-center {\n    left: 50%;\n    top: 50%;\n    transform: translate(-50%, -50%);\n    /* #ifndef APP-NVUE */\n    max-width: 70%;\n    /* #endif */\n}\n\n.u-position-top {\n    left: 50%;\n    top: 20%;\n    transform: translate(-50%, -50%);\n}\n\n.u-position-bottom {\n    left: 50%;\n    bottom: 20%;\n    transform: translate(-50%, -50%);\n}\n\n.u-type-primary {\n    color: $u-type-primary;\n    background-color: $u-type-primary-light;\n    border: 1px solid var(--u-type-primary-light);\n}\n\n.u-type-success {\n    color: $u-type-success;\n    background-color: $u-type-success-light;\n    border: 1px solid var(--u-type-success-light);\n}\n\n.u-type-error {\n    color: $u-type-error;\n    background-color: $u-type-error-light;\n    border: 1px solid var(--u-type-error-light);\n}\n\n.u-type-warning {\n    color: $u-type-warning;\n    background-color: $u-type-warning-light;\n    border: 1px solid var(--u-type-warning-light);\n}\n\n.u-type-info {\n    color: $u-type-info;\n    background-color: $u-type-info-light;\n    border: 1px solid var(--u-bg-gray-light);\n}\n\n.u-type-default {\n    color: var(--u-white-color);\n    background-color: var(--u-content-color);\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-top-tips/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport zIndex from '../../libs/config/zIndex';\n\n/**\n * TopTipsProps top-tips props 类型定义\n * @description 顶部提示组件，支持导航栏高度、z-index\n */\nexport const TopTipsProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 导航栏高度，用于提示的初始化 */\n    navbarHeight: { type: [Number, String] as PropType<number | string>, default: 0 },\n    /** z-index值 */\n    zIndex: { type: [Number, String] as PropType<number | string>, default: zIndex.topTips }\n};\n\nexport type TopTipsProps = ExtractPropTypes<typeof TopTipsProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-top-tips/u-top-tips.vue",
    "content": "<template>\n    <view\n        class=\"u-tips\"\n        :class=\"['u-' + type, isShow ? 'u-tip-show' : '', customClass]\"\n        :style=\"$u.toStyle(tipStyle, customStyle)\"\n    >\n        {{ title }}\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-top-tips',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed } from 'vue';\nimport { $u } from '../..';\nimport { TopTipsProps } from './types';\n\n/**\n * topTips 顶部提示\n * @description 该组件一般用于页面顶部向下滑出一个提示，尔后自动收起的场景。\n * @tutorial https://uviewpro.cn/zh/components/topTips.html\n * @property {String|Number} navbarHeight 导航栏高度(包含状态栏高度在内)，单位PX\n * @property {String|Number} zIndex z-index值（默认975）\n * @example <u-top-tips ref=\"uTips\"></u-top-tips>\n */\n\nconst props = defineProps(TopTipsProps);\n\nlet timer: number | ReturnType<typeof setTimeout> | null = null; // 定时器\nconst isShow = ref(false); // 是否显示消息组件\nconst title = ref(''); // 组件中显示的消息内容\nconst type = ref<'primary' | 'success' | 'error' | 'warning' | 'info'>('primary'); // 消息的类型（颜色不同），primary，success，error，warning，info\nconst duration = ref(2000); // 组件显示的时间，单位为毫秒\n\nconst uZIndex = computed(() => (props.zIndex ? props.zIndex : $u.zIndex.topTips));\n\nconst uNavbarHeight = computed(() => {\n    if (props.navbarHeight) {\n        return props.navbarHeight;\n    }\n    let height = 0;\n    // #ifndef H5\n    height = 0;\n    // #endif\n    // #ifdef H5\n    height = 44;\n    // #endif\n    return height;\n});\n\nconst tipStyle = computed(() => ({\n    top: Number(uNavbarHeight.value) + 'px',\n    zIndex: isShow.value ? uZIndex.value : -1\n}));\n\n/**\n * 显示顶部提示\n * @param config 配置项 { title, type, duration }\n */\nfunction show(config: { title: string; type?: string; duration?: number } = { title: '' }) {\n    // 先清除定时器（可能是上一次定义的，需要清除了再开始新的）\n    if (timer) clearTimeout(timer);\n    // 时间，内容，类型主题(type)等参数\n    if (config.duration) duration.value = config.duration;\n    if (config.type) type.value = config.type as any;\n    title.value = config.title;\n    isShow.value = true;\n    // 倒计时\n    timer = setTimeout(() => {\n        isShow.value = false;\n        if (timer) clearTimeout(timer);\n        timer = null;\n    }, duration.value);\n}\ndefineExpose({ show });\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\nview {\n    box-sizing: border-box;\n}\n.u-tips {\n    width: 100%;\n    position: fixed;\n    z-index: 1;\n    padding: 20rpx 30rpx;\n    color: var(--u-white-color);\n    font-size: 28rpx;\n    left: 0;\n    right: 0;\n    @include vue-flex;\n    align-items: center;\n    justify-content: center;\n    opacity: 0;\n    transform: translateY(-100%);\n    transition: all 0.35s linear;\n}\n.u-tip-show {\n    transform: translateY(0);\n    opacity: 1;\n    z-index: 99;\n}\n.u-primary {\n    background: $u-type-primary;\n}\n.u-success {\n    background: $u-type-success;\n}\n.u-warning {\n    background: $u-type-warning;\n}\n.u-error {\n    background: $u-type-error;\n}\n.u-info {\n    background: $u-type-info;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-tr/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\n/**\n * TrProps tr props 类型定义\n * @description 表格行组件，无特殊 props\n */\nexport const TrProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    }\n};\nexport type TrProps = ExtractPropTypes<typeof TrProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-tr/u-tr.vue",
    "content": "<template>\n    <view class=\"u-tr\" :class=\"customClass\" :style=\"$u.toStyle(customStyle)\">\n        <slot></slot>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-tr',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { TrProps } from './types';\nimport { $u } from '../../';\n\n/**\n * tr 表格行标签\n * @description 表格组件一般用于展示大量结构化数据的场景（搭配<u-table>使用）\n * @tutorial https://uviewpro.cn/zh/components/table.html\n * @example <u-tr></u-tr>\n */\nconst props = defineProps(TrProps);\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-tr {\n    @include vue-flex;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-transition/types.ts",
    "content": "import type { PropType } from 'vue';\nimport type { TransitionDuration, TransitionPreset } from '../../types/global';\n\nexport const TransitionProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    show: {\n        type: Boolean,\n        default: true\n    },\n    name: {\n        type: String as PropType<TransitionPreset>,\n        default: 'fade'\n    },\n    mode: {\n        type: String as PropType<'out-in' | 'in-out' | ''>,\n        default: ''\n    },\n    duration: {\n        type: [Number, Object] as PropType<number | TransitionDuration>,\n        default: 300\n    },\n    timingFunction: {\n        type: String,\n        default: 'cubic-bezier(0.2, 0.8, 0.2, 1)'\n    },\n    delay: {\n        type: Number,\n        default: 0\n    },\n    appear: {\n        type: Boolean,\n        default: false\n    }\n};\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-transition/u-transition.vue",
    "content": "<template>\n    <view\n        v-if=\"rendered\"\n        ref=\"rootRef\"\n        class=\"u-transition\"\n        :class=\"[customClass, animationClass]\"\n        :style=\"$u.toStyle(animationStyle, customStyle)\"\n        @animationstart=\"handleAnimationStart\"\n        @animationend=\"handleAnimationEnd\"\n    >\n        <slot />\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-transition',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, ref, watch } from 'vue';\nimport { TransitionProps } from './types';\nimport { $u } from '../..';\nimport type { TransitionDuration } from '../../types/global';\n\n/**\n * transition 过渡动画\n * @description 统一的过渡与进出场动效封装，支持多种预设动画和自定义时长。\n * @tutorial https://uviewpro.cn/zh/components/transition.html\n * @property {Boolean} show 是否展示内容（默认true）\n * @property {String} name 预设动画名，可选 fade/slide-up/slide-down/slide-left/slide-right/zoom-in/zoom-out（默认fade）\n * @property {String} mode 进入/离开过渡模式，等同于原生 transition 的 mode（默认空）\n * @property {Number|Object} duration 进入/离开动画时长，单位ms，支持 { enter, leave }（默认300）\n * @property {String} timing-function 动画曲线（默认cubic-bezier(0.2,0.8,0.2,1)）\n * @property {Number} delay 动画延迟，单位ms（默认0）\n * @property {Boolean} appear 首次渲染时是否执行动画（默认false）\n * @property {String} custom-class 自定义 class\n * @property {String|Object} custom-style 自定义样式\n * @example <u-transition :show=\"visible\" name=\"slide-up\"><view>content</view></u-transition>\n */\n\nconst props = defineProps(TransitionProps);\n\nconst emit = defineEmits([\n    'before-enter',\n    'enter',\n    'after-enter',\n    'enter-cancelled',\n    'before-leave',\n    'leave',\n    'after-leave',\n    'leave-cancelled'\n]);\n\nconst normalizeDuration = (duration: number | TransitionDuration) => {\n    if (typeof duration === 'number') {\n        return {\n            enter: duration,\n            leave: duration\n        };\n    }\n    return {\n        enter: duration?.enter ?? 300,\n        leave: duration?.leave ?? duration?.enter ?? 300\n    };\n};\n\nconst rootRef = ref();\nconst rendered = ref<boolean>(props.show);\nconst animationPhase = ref<'enter' | 'leave' | ''>('');\nconst animating = ref(false);\nconst initialized = ref(false);\n\nconst transitionDuration = computed(() => normalizeDuration(props.duration));\n\nconst animationStyle = computed(() => {\n    const currentDuration =\n        animationPhase.value === 'leave' ? transitionDuration.value.leave : transitionDuration.value.enter;\n    return {\n        '--u-transition-duration-enter': `${transitionDuration.value.enter}ms`,\n        '--u-transition-duration-leave': `${transitionDuration.value.leave}ms`,\n        '--u-transition-delay': `${props.delay}ms`,\n        '--u-transition-timing': props.timingFunction,\n        animationDuration: `${currentDuration}ms`,\n        animationDelay: `${props.delay}ms`,\n        animationTimingFunction: props.timingFunction\n    };\n});\n\nconst animationClass = computed(() => {\n    if (!animationPhase.value) {\n        return '';\n    }\n    return `u-transition-${props.name}-${animationPhase.value}`;\n});\n\nconst getEl = () => rootRef.value as any;\n\nconst startEnter = () => {\n    if (animating.value && animationPhase.value === 'enter') {\n        return;\n    }\n    if (animating.value && animationPhase.value === 'leave') {\n        emit('leave-cancelled', getEl());\n    }\n    rendered.value = true;\n    animationPhase.value = 'enter';\n    animating.value = true;\n    emit('before-enter', getEl());\n};\n\nconst startLeave = () => {\n    if (!rendered.value) {\n        return;\n    }\n    if (animating.value && animationPhase.value === 'leave') {\n        return;\n    }\n    if (animating.value && animationPhase.value === 'enter') {\n        emit('enter-cancelled', getEl());\n    }\n    animationPhase.value = 'leave';\n    animating.value = true;\n    emit('before-leave', getEl());\n};\n\nconst handleAnimationStart = () => {\n    if (animationPhase.value === 'enter') {\n        emit('enter', getEl());\n    } else if (animationPhase.value === 'leave') {\n        emit('leave', getEl());\n    }\n};\n\nconst handleAnimationEnd = () => {\n    if (animationPhase.value === 'enter') {\n        animating.value = false;\n        animationPhase.value = '';\n        emit('after-enter', getEl());\n        return;\n    }\n    if (animationPhase.value === 'leave') {\n        animating.value = false;\n        animationPhase.value = '';\n        rendered.value = false;\n        emit('after-leave', getEl());\n    }\n};\n\n// 根据mode处理动画顺序（主要用于快速切换时的时序控制）\nconst shouldWaitForAnimation = (newPhase: 'enter' | 'leave') => {\n    if (!animating.value) return false;\n\n    const currentPhase = animationPhase.value;\n\n    // 如果当前正在进行相反的动画，根据mode决定是否需要等待\n    if (props.mode === 'out-in' && currentPhase === 'leave' && newPhase === 'enter') {\n        return true; // 等待离开动画完成\n    }\n    if (props.mode === 'in-out' && currentPhase === 'enter' && newPhase === 'leave') {\n        return true; // 等待进入动画完成\n    }\n\n    return false;\n};\n\nwatch(\n    () => props.show,\n    value => {\n        if (!initialized.value) {\n            initialized.value = true;\n            if (value) {\n                rendered.value = true;\n                if (props.appear) {\n                    nextTick(() => startEnter());\n                }\n            } else {\n                rendered.value = false;\n            }\n            return;\n        }\n        if (value) {\n            if (shouldWaitForAnimation('enter')) {\n                // 根据mode等待当前动画完成后再开始进入动画\n                // 简单的方式：延迟到下一个tick检查\n                nextTick(() => {\n                    if (!animating.value) {\n                        startEnter();\n                    }\n                });\n            } else {\n                startEnter();\n            }\n        } else {\n            if (shouldWaitForAnimation('leave')) {\n                // 根据mode等待当前动画完成后再开始离开动画\n                nextTick(() => {\n                    if (!animating.value) {\n                        startLeave();\n                    }\n                });\n            } else {\n                startLeave();\n            }\n        }\n    },\n    { immediate: true }\n);\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-transition {\n    // display: inline-flex;\n    // width: auto;\n}\n\n@mixin animation-base {\n    animation-fill-mode: both;\n}\n\n.u-transition-fade-enter {\n    @include animation-base;\n    animation-name: u-transition-fade-in;\n}\n.u-transition-fade-leave {\n    @include animation-base;\n    animation-name: u-transition-fade-out;\n}\n\n.u-transition-slide-up-enter {\n    @include animation-base;\n    animation-name: u-transition-slide-up-in;\n}\n.u-transition-slide-up-leave {\n    @include animation-base;\n    animation-name: u-transition-slide-up-out;\n}\n\n.u-transition-slide-down-enter {\n    @include animation-base;\n    animation-name: u-transition-slide-down-in;\n}\n.u-transition-slide-down-leave {\n    @include animation-base;\n    animation-name: u-transition-slide-down-out;\n}\n\n.u-transition-slide-left-enter {\n    @include animation-base;\n    animation-name: u-transition-slide-left-in;\n}\n.u-transition-slide-left-leave {\n    @include animation-base;\n    animation-name: u-transition-slide-left-out;\n}\n\n.u-transition-slide-right-enter {\n    @include animation-base;\n    animation-name: u-transition-slide-right-in;\n}\n.u-transition-slide-right-leave {\n    @include animation-base;\n    animation-name: u-transition-slide-right-out;\n}\n\n.u-transition-zoom-in-enter {\n    @include animation-base;\n    animation-name: u-transition-zoom-in-in;\n}\n.u-transition-zoom-in-leave {\n    @include animation-base;\n    animation-name: u-transition-zoom-in-out;\n}\n\n.u-transition-zoom-out-enter {\n    @include animation-base;\n    animation-name: u-transition-zoom-out-in;\n}\n.u-transition-zoom-out-leave {\n    @include animation-base;\n    animation-name: u-transition-zoom-out-out;\n}\n\n@keyframes u-transition-fade-in {\n    0% {\n        opacity: 0;\n    }\n    100% {\n        opacity: 1;\n    }\n}\n\n@keyframes u-transition-fade-out {\n    0% {\n        opacity: 1;\n    }\n    100% {\n        opacity: 0;\n    }\n}\n\n@keyframes u-transition-slide-up-in {\n    0% {\n        opacity: 0;\n        transform: translate3d(0, 40rpx, 0);\n    }\n    100% {\n        opacity: 1;\n        transform: translate3d(0, 0, 0);\n    }\n}\n@keyframes u-transition-slide-up-out {\n    0% {\n        opacity: 1;\n        transform: translate3d(0, 0, 0);\n    }\n    100% {\n        opacity: 0;\n        transform: translate3d(0, 40rpx, 0);\n    }\n}\n\n@keyframes u-transition-slide-down-in {\n    0% {\n        opacity: 0;\n        transform: translate3d(0, -40rpx, 0);\n    }\n    100% {\n        opacity: 1;\n        transform: translate3d(0, 0, 0);\n    }\n}\n@keyframes u-transition-slide-down-out {\n    0% {\n        opacity: 1;\n        transform: translate3d(0, 0, 0);\n    }\n    100% {\n        opacity: 0;\n        transform: translate3d(0, -40rpx, 0);\n    }\n}\n\n@keyframes u-transition-slide-left-in {\n    0% {\n        opacity: 0;\n        transform: translate3d(40rpx, 0, 0);\n    }\n    100% {\n        opacity: 1;\n        transform: translate3d(0, 0, 0);\n    }\n}\n@keyframes u-transition-slide-left-out {\n    0% {\n        opacity: 1;\n        transform: translate3d(0, 0, 0);\n    }\n    100% {\n        opacity: 0;\n        transform: translate3d(40rpx, 0, 0);\n    }\n}\n\n@keyframes u-transition-slide-right-in {\n    0% {\n        opacity: 0;\n        transform: translate3d(-40rpx, 0, 0);\n    }\n    100% {\n        opacity: 1;\n        transform: translate3d(0, 0, 0);\n    }\n}\n@keyframes u-transition-slide-right-out {\n    0% {\n        opacity: 1;\n        transform: translate3d(0, 0, 0);\n    }\n    100% {\n        opacity: 0;\n        transform: translate3d(-40rpx, 0, 0);\n    }\n}\n\n@keyframes u-transition-zoom-in-in {\n    0% {\n        opacity: 0;\n        transform: scale(0.85);\n    }\n    100% {\n        opacity: 1;\n        transform: scale(1);\n    }\n}\n@keyframes u-transition-zoom-in-out {\n    0% {\n        opacity: 1;\n        transform: scale(1);\n    }\n    100% {\n        opacity: 0;\n        transform: scale(0.85);\n    }\n}\n\n@keyframes u-transition-zoom-out-in {\n    0% {\n        opacity: 0;\n        transform: scale(1.1);\n    }\n    100% {\n        opacity: 1;\n        transform: scale(1);\n    }\n}\n@keyframes u-transition-zoom-out-out {\n    0% {\n        opacity: 1;\n        transform: scale(1);\n    }\n    100% {\n        opacity: 0;\n        transform: scale(1.1);\n    }\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-upload/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport type { ImgMode, UploadSizeType, UploadSourceType, UploadAcceptType, UploadFileItem } from '../../types/global';\nimport { useLocale } from '../../';\n\nconst { t } = useLocale();\n\n/**\n * UploadProps upload props 类型定义\n * @description 文件上传组件，支持多种自定义参数\n */\nexport const UploadProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 选择器宽度，单位rpx */\n    width: { type: [Number, String] as PropType<number | string>, default: 200 },\n    /** 选择器高度，单位rpx */\n    height: { type: [Number, String] as PropType<number | string>, default: 200 },\n    /** 最大上传数量 */\n    maxCount: { type: [Number, String] as PropType<number | string>, default: 52 },\n    /** 是否可删除 */\n    deletable: { type: Boolean, default: true },\n    /**\n     * 上传组件的展示模式\n     * @description grid-网格模式(默认), list-列表模式\n     * @default 'grid'\n     */\n    mode: { type: String as PropType<'grid' | 'list'>, default: 'grid' },\n    /** 是否显示上传列表 */\n    showUploadList: { type: Boolean, default: true },\n    /** 是否显示上传进度 */\n    showProgress: { type: Boolean, default: true },\n    /** 删除按钮背景色 */\n    delBgColor: { type: String, default: 'var(--u-type-error)' },\n    /** 删除按钮图标 */\n    delIcon: { type: String, default: 'close' },\n    /** 删除按钮颜色 */\n    delColor: { type: String, default: 'var(--u-white-color)' },\n    /** 图片裁剪模式 */\n    imageMode: { type: String as PropType<ImgMode>, default: 'aspectFill' },\n    /** 是否自定义上传按钮 */\n    customBtn: { type: Boolean, default: false },\n    /** 上传按钮文字 */\n    uploadText: { type: String, default: () => t('uUpload.uploadText') },\n    /** 上传地址 */\n    action: { type: String, default: '' },\n    /** 是否禁用 */\n    disabled: { type: Boolean, default: false },\n    /** 索引值，在各个回调事件中的最后一个参数返回，用于区别是哪一个组件的事件 */\n    index: { type: [String, Number] as PropType<string | number>, default: '' },\n    /** 请求头对象 */\n    header: { type: Object as PropType<Record<string, any>>, default: () => ({}) },\n    /** formData对象 */\n    formData: { type: Object as PropType<Record<string, any>>, default: () => ({}) },\n    /** 文件字段名 */\n    name: { type: String, default: 'file' },\n    /** 压缩/原图，微信小程序有效 */\n    sizeType: { type: Array as PropType<UploadSizeType[]>, default: () => ['original', 'compressed'] },\n    /** 来源，相册/相机 */\n    sourceType: { type: Array as PropType<UploadSourceType[]>, default: () => ['album', 'camera'] },\n    /** 是否可预览大图 */\n    previewFullImage: { type: Boolean, default: true },\n    /** 是否可预览文件 */\n    previewFile: { type: Boolean, default: true },\n    /** 是否支持多选 */\n    multiple: { type: Boolean, default: true },\n    /** 单个文件最大大小，单位B(byte)，默认不限制 */\n    maxSize: { type: [Number, String] as PropType<number | string>, default: Number.MAX_VALUE },\n    /**\n     * 文件列表（v-model 双向绑定）\n     * @description 推荐使用 v-model 替代 :file-list\n     */\n    modelValue: { type: Array as PropType<UploadFileItem[]>, default: () => [] },\n    /**\n     * 文件列表（初始值，向后兼容）\n     * @deprecated 请使用 v-model\n     */\n    fileList: { type: Array as PropType<UploadFileItem[]>, default: () => [] },\n    /** 限制文件类型 */\n    /** 允许上传的文件后缀 */\n    /** 支付宝小程序真机选择图片的后缀为\"image\" */\n    /** https://opendocs.alipay.com/mini/api/media-image */\n    limitType: { type: Array as PropType<string[]>, default: () => [] },\n    /** 是否自动上传 */\n    autoUpload: { type: Boolean, default: true },\n    /** 是否显示提示 */\n    showTips: { type: Boolean, default: true },\n    /** 是否显示确认弹窗 */\n    showConfirm: { type: Boolean, default: true },\n    /** 上传前钩子，返回true或Promise */\n    beforeUpload: {\n        type: Function as unknown as PropType<\n            ((index: number, files: UploadFileItem[]) => boolean | Promise<any>) | null\n        >,\n        default: null\n    },\n    /** 删除前钩子，返回true或Promise */\n    beforeRemove: {\n        type: Function as unknown as PropType<\n            ((index: number, files: UploadFileItem[]) => boolean | Promise<any>) | null\n        >,\n        default: null\n    },\n    /** 如果上传后的返回值为json字符串，是否转为json格式 */\n    toJson: { type: Boolean, default: true },\n    /**\n     * 接受上传的文件类型\n     * @description image-图片(默认), video-视频, file-文件, media-媒体(图片+视频), all-所有文件\n     * @default 'image'\n     */\n    accept: { type: String as PropType<UploadAcceptType>, default: 'image' },\n    /**\n     * 是否显示文件名\n     * @default true\n     */\n    showFileName: { type: Boolean, default: true },\n    /**\n     * 是否显示文件大小\n     * @default false\n     */\n    showFileSize: { type: Boolean, default: false },\n    /**\n     * 文件类型图标映射配置\n     * @description 用于自定义不同文件类型的图标\n     */\n    fileIconMap: {\n        type: Object as PropType<Record<string, { name: string; color?: string }>>,\n        default: () => ({})\n    },\n    /**\n     * 选择视频时是否压缩\n     * @default true\n     */\n    compressed: { type: Boolean, default: true },\n    /**\n     * 选择视频时拍摄最长时长，单位秒\n     * @default 60\n     */\n    maxDuration: { type: Number, default: 60 },\n    /**\n     * 选择视频时，是前置还是后置摄像头\n     * @default 'back'\n     */\n    camera: { type: String as PropType<'front' | 'back'>, default: 'back' },\n    /**\n     * 选择文件时的扩展名过滤\n     * @description 仅在 accept='file' 或 accept='all' 时有效\n     */\n    extension: { type: Array as PropType<string[]>, default: () => [] },\n    /**\n     * 图片/图标展示形状\n     * @description 可选值：square-方形(默认), circle-圆形。在 grid 模式下作用于图片和添加按钮，在 list 模式下作用于图标\n     * @default 'square'\n     */\n    imageShape: { type: String as PropType<'square' | 'circle'>, default: 'square' },\n    /**\n     * 是否使用自定义选择文件\n     * @description 设置为 true 时，点击选择文件会触发 on-choose 事件，不会调用默认的文件选择 API，用户可自行处理文件选择逻辑，然后通过 addFiles 方法将文件添加到列表\n     * @default false\n     */\n    customChoose: { type: Boolean, default: false }\n};\n\nexport type UploadProps = ExtractPropTypes<typeof UploadProps>;\n\n// 重新导出全局类型，方便从组件入口导入\nexport type { UploadAcceptType, UploadFileItem } from '../../types/global';\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-upload/u-upload.vue",
    "content": "<template>\n    <view\n        v-if=\"!disabled\"\n        class=\"u-upload\"\n        :class=\"[customClass, { 'u-upload--list': props.mode === 'list' }]\"\n        :style=\"$u.toStyle(customStyle)\"\n    >\n        <!-- 列表模式 -->\n        <template v-if=\"props.mode === 'list'\">\n            <view v-if=\"showUploadList\" class=\"u-upload-list\">\n                <view\n                    v-for=\"(item, index) in lists\"\n                    class=\"u-upload-list__item\"\n                    :key=\"index\"\n                    :class=\"{ 'u-upload-list__item--error': item.error }\"\n                >\n                    <!-- 左侧：图片缩略图或文件图标 -->\n                    <view class=\"u-upload-list__left\" @tap.stop=\"handlePreview(item, index)\">\n                        <!-- 图片类型：显示缩略图 -->\n                        <template v-if=\"isImageFile(item)\">\n                            <image\n                                class=\"u-upload-list__thumb\"\n                                :class=\"{ 'u-upload-list__thumb--circle': props.imageShape === 'circle' }\"\n                                :src=\"item.url || item.path\"\n                                :mode=\"imageMode\"\n                            />\n                        </template>\n                        <!-- 非图片类型：显示文件图标 -->\n                        <template v-else>\n                            <view\n                                class=\"u-upload-list__icon\"\n                                :class=\"{ 'u-upload-list__icon--circle': props.imageShape === 'circle' }\"\n                                :style=\"{ background: getFileIcon(item).bgColor }\"\n                            >\n                                <u-icon :name=\"getFileIcon(item).name\" size=\"32\" color=\"var(--u-white-color)\"></u-icon>\n                            </view>\n                        </template>\n                    </view>\n\n                    <!-- 中间：文件名和大小 -->\n                    <view class=\"u-upload-list__center\" @tap.stop=\"handlePreview(item, index)\">\n                        <text\n                            v-if=\"showFileName && item.name\"\n                            class=\"u-upload-list__name\"\n                            :class=\"{ 'u-upload-list__name--error': item.error }\"\n                        >\n                            {{ getFileName(item) }}\n                        </text>\n                        <text v-if=\"showFileSize && item.size\" class=\"u-upload-list__size\">\n                            {{ formatFileSize(item.size) }}\n                        </text>\n                        <!-- 进度条 -->\n                        <view\n                            v-if=\"showProgress && item.progress > 0 && item.progress < 100 && !item.error\"\n                            class=\"u-upload-list__progress\"\n                        >\n                            <u-line-progress\n                                height=\"4\"\n                                :show-percent=\"false\"\n                                :percent=\"item.progress\"\n                            ></u-line-progress>\n                        </view>\n                        <view\n                            v-if=\"item.error\"\n                            class=\"u-upload-list__retry\"\n                            hover-class=\"u-upload-list__retry--hover\"\n                            hover-stay-time=\"150\"\n                            @tap.stop=\"retry(index)\"\n                        >\n                            <u-icon name=\"reload\" size=\"24\" color=\"var(--u-type-error)\"></u-icon>\n                            <text class=\"u-upload-list__retry-text\">{{ t('uUpload.retry') }}</text>\n                        </view>\n                    </view>\n\n                    <!-- 右侧：删除按钮 -->\n                    <view\n                        v-if=\"deletable\"\n                        class=\"u-upload-list__right\"\n                        @tap.stop=\"deleteItem(index)\"\n                        :style=\"{\n                            backgroundColor: delBgColor\n                        }\"\n                    >\n                        <u-icon :name=\"delIcon\" size=\"20\" :color=\"delColor\"></u-icon>\n                    </view>\n                </view>\n            </view>\n\n            <!-- 列表模式：自定义文件列表插槽 -->\n            <slot name=\"file\" :file=\"lists\"></slot>\n\n            <!-- 列表模式：添加按钮 -->\n            <view v-if=\"Number(maxCount) > lists.length\" class=\"u-upload-list__add\" @tap=\"selectFile\">\n                <slot name=\"addBtn\"></slot>\n                <view\n                    v-if=\"!customBtn\"\n                    class=\"u-upload-list__add-btn\"\n                    hover-class=\"u-upload-list__add-btn--hover\"\n                    hover-stay-time=\"150\"\n                >\n                    <u-icon name=\"plus\" size=\"32\" :color=\"$u.color.primary\"></u-icon>\n                    <text class=\"u-upload-list__add-text\">{{ uploadBtnText }}</text>\n                </view>\n            </view>\n        </template>\n\n        <!-- 网格模式（默认） -->\n        <template v-else>\n            <template v-if=\"showUploadList\">\n                <view\n                    v-for=\"(item, index) in lists\"\n                    class=\"u-upload-grid__item u-upload-grid__preview\"\n                    :class=\"{ 'u-upload-grid__item--circle': props.imageShape === 'circle' }\"\n                    :key=\"index\"\n                    :style=\"{\n                        width: $u.addUnit(width),\n                        height: $u.addUnit(height)\n                    }\"\n                >\n                    <view\n                        v-if=\"deletable\"\n                        class=\"u-upload-grid__delete\"\n                        @tap.stop=\"deleteItem(index)\"\n                        :style=\"{\n                            backgroundColor: delBgColor\n                        }\"\n                    >\n                        <u-icon :name=\"delIcon\" size=\"20\" :color=\"delColor\"></u-icon>\n                    </view>\n                    <view class=\"u-upload-grid__progress\">\n                        <u-line-progress\n                            v-if=\"showProgress && item.progress > 0 && item.progress !== 100 && !item.error\"\n                            :show-percent=\"false\"\n                            height=\"16\"\n                            :percent=\"item.progress\"\n                        ></u-line-progress>\n                    </view>\n                    <view @tap.stop=\"retry(index)\" v-if=\"item.error\" class=\"u-upload-grid__error\">{{\n                        t('uUpload.retry')\n                    }}</view>\n\n                    <!-- 图片类型预览 -->\n                    <template v-if=\"isImageFile(item)\">\n                        <image\n                            class=\"u-upload-grid__image\"\n                            :class=\"{ 'u-upload-grid__image--circle': props.imageShape === 'circle' }\"\n                            :src=\"item.url || item.path\"\n                            :mode=\"imageMode\"\n                            @tap.stop=\"handlePreview(item, index)\"\n                        ></image>\n                    </template>\n\n                    <!-- 视频类型预览 -->\n                    <template v-else-if=\"isVideoFile(item)\">\n                        <view class=\"u-upload-grid__file\" @tap.stop=\"doPreviewFile(item, index)\">\n                            <view class=\"u-upload-grid__file-icon\" :style=\"{ background: getFileIcon(item).bgColor }\">\n                                <u-icon :name=\"getFileIcon(item).name\" size=\"48\" color=\"var(--u-white-color)\"></u-icon>\n                            </view>\n                            <view class=\"u-upload-grid__file-info\" v-if=\"showFileName || showFileSize\">\n                                <text\n                                    v-if=\"showFileName && item.name\"\n                                    class=\"u-upload-grid__file-name\"\n                                    :style=\"{ color: item.error ? 'var(--u-type-error)' : 'var(--u-content-color)' }\"\n                                >\n                                    {{ getFileName(item) }}\n                                </text>\n                                <text v-if=\"showFileSize && item.size\" class=\"u-upload-grid__file-size\">{{\n                                    formatFileSize(item.size)\n                                }}</text>\n                            </view>\n                        </view>\n                    </template>\n\n                    <!-- 其他文件类型预览 -->\n                    <template v-else>\n                        <view class=\"u-upload-grid__file\" @tap.stop=\"doPreviewFile(item, index)\">\n                            <view class=\"u-upload-grid__file-icon\" :style=\"{ background: getFileIcon(item).bgColor }\">\n                                <u-icon :name=\"getFileIcon(item).name\" size=\"48\" color=\"var(--u-white-color)\"></u-icon>\n                            </view>\n                            <view class=\"u-upload-grid__file-info\" v-if=\"showFileName || showFileSize\">\n                                <text\n                                    v-if=\"showFileName && item.name\"\n                                    class=\"u-upload-grid__file-name\"\n                                    :style=\"{ color: item.error ? 'var(--u-type-error)' : 'var(--u-content-color)' }\"\n                                >\n                                    {{ getFileName(item) }}\n                                </text>\n                                <text v-if=\"showFileSize && item.size\" class=\"u-upload-grid__file-size\">\n                                    {{ formatFileSize(item.size) }}\n                                </text>\n                            </view>\n                        </view>\n                    </template>\n                </view>\n            </template>\n            <slot name=\"file\" :file=\"lists\"></slot>\n            <view style=\"display: inline-block\" @tap=\"selectFile\" v-if=\"Number(maxCount) > lists.length\">\n                <slot name=\"addBtn\"></slot>\n                <view\n                    v-if=\"!customBtn\"\n                    class=\"u-upload-grid__item u-upload-grid__add\"\n                    hover-class=\"u-upload-grid__add--hover\"\n                    hover-stay-time=\"150\"\n                    :class=\"{ 'u-upload-grid__item--circle': props.imageShape === 'circle' }\"\n                    :style=\"{\n                        width: $u.addUnit(width),\n                        height: $u.addUnit(height)\n                    }\"\n                >\n                    <u-icon name=\"plus\" class=\"u-upload-grid__add-icon\" size=\"40\"></u-icon>\n                    <view class=\"u-upload-grid__add-text\">{{ uploadBtnText }}</view>\n                </view>\n            </view>\n        </template>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-upload',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, watch, computed } from 'vue';\nimport { $u, useLocale } from '../..';\nimport { UploadProps } from './types';\nimport type { UploadFileItem } from '../../types/global';\n\n/**\n * upload 文件上传\n * @description 该组件用于上传文件场景，支持图片、视频、文档等多种类型，支持网格和列表两种展示模式\n * @tutorial https://uviewpro.cn/zh/components/upload.html\n *\n * @property {String} action 服务器上传地址\n * @property {String} accept 接受上传的文件类型，可选值：image|video|file|media|all，默认image\n * @property {String} mode 上传组件的展示模式，可选值：grid|list，默认grid\n * @property {String Number} max-count 最大选择文件的数量（默认52）\n * @property {String Number} max-size 选择单个文件的最大大小，单位B(byte)，默认不限制（默认Number.MAX_VALUE）\n * @property {Boolean} multiple 是否开启文件多选（默认true）\n * @property {Boolean} disabled 是否禁用组件（默认false）\n * @property {Boolean} auto-upload 选择完文件是否自动上传（默认true）\n * @property {Boolean} deletable 是否显示删除文件的按钮（默认true）\n * @property {Boolean} show-confirm 删除文件前是否显示确认弹窗（默认true）\n * @property {Boolean} show-tips 特殊情况下是否自动提示toast（默认true）\n * @property {Boolean} show-progress 是否显示上传进度条（默认true）\n * @property {Boolean} show-upload-list 是否显示组件内部的文件预览列表（默认true）\n * @property {Boolean} show-file-name 是否显示文件名（默认true）\n * @property {Boolean} show-file-size 是否显示文件大小（默认false）\n * @property {Boolean} preview-full-image 是否可以通过uni.previewImage预览已选择的图片（默认true）\n * @property {Boolean} preview-file 是否可预览文件（非图片类型）（默认true）\n * @property {Boolean} custom-btn 是否自定义选择文件的按钮，设置为true可使用addBtn插槽（默认false）\n * @property {String} upload-text 选择文件按钮的提示文字（默认根据accept自动显示）\n * @property {String} image-mode 预览图片的显示模式，可选值为uni的image的mode属性值（默认aspectFill）\n * @property {String} del-icon 右上角删除图标名称，只能为uView内置图标（默认'close'）\n * @property {String} del-bg-color 右上角删除按钮的背景颜色（默认'var(--u-type-error)'）\n * @property {String} del-color 右上角删除按钮图标的颜色（默认'var(--u-white-color)'）\n * @property {String | Number} index 在各个回调事件中的最后一个参数返回，用于区别是哪一个组件的事件\n * @property {Object} header 上传携带的请求头信息，对象形式\n * @property {Object} form-data 上传额外携带的参数\n * @property {String} name 上传文件的字段名，供后端获取使用（默认'file'）\n * @property {Array<String>} size-type original 原图，compressed 压缩图，默认二者都有（默认['original', 'compressed']）\n * @property {Array<String>} source-type 选择文件的来源，album-从相册选图，camera-使用相机，默认二者都有（默认['album', 'camera']）\n * @property {Array<String>} limit-type 限制允许上传的文件后缀，如['png', 'jpg']。优先级高于accept内置的格式限制\n * @property {Array<String>} extension 选择文件时的扩展名过滤，仅在H5和微信小程序accept='file'时有效，如['.pdf', '.docx']\n * @property {Object} file-icon-map 文件类型图标映射配置，用于自定义不同文件类型的图标和颜色\n * @property {Boolean} compressed 选择视频时是否压缩（默认true）\n * @property {Number} max-duration 选择视频时拍摄最长时长，单位秒（默认60）\n * @property {String} camera 选择视频时摄像头方向，可选值：front|back（默认'back'）\n * @property {String} image-shape 图片/图标展示形状，可选值：square|circle（默认'square'），在grid模式下作用于图片和添加按钮，在list模式下作用于图标\n * @property {Array<Object>} file-list 默认显示的文件列表，数组元素为对象，必须提供url属性\n * @property {Function} before-upload 上传前钩子，返回false或Promise.reject则跳过当前文件上传\n * @property {Function} before-remove 删除前钩子，返回false或Promise.reject则阻止删除\n * @property {Boolean} to-json 如果上传后的返回值为json字符串，是否自动转为json格式（默认true）\n * @property {Boolean} custom-choose 是否使用自定义文件选择，开启后点击选择文件会触发 on-choose 事件而不调用默认选择API（默认false）\n *\n * @event {Function} on-oversize 文件大小超出max-size限制时触发\n * @event {Function} on-exceed 文件数量超出max-count限制时触发\n * @event {Function} on-choose-complete 每次选择文件后触发，返回当前文件列表\n * @event {Function} on-choose-fail 文件选择失败时触发\n * @event {Function} on-uploaded 所有文件上传完毕时触发\n * @event {Function} on-success 单个文件上传成功时触发\n * @event {Function} on-error 单个文件上传失败时触发\n * @event {Function} on-change 单个文件上传状态改变时触发（无论成功或失败）\n * @event {Function} on-progress 文件上传过程中的进度变化时触发\n * @event {Function} on-remove 移除文件时触发\n * @event {Function} on-preview 预览文件时触发\n * @event {Function} on-list-change 文件列表发生变化时触发\n * @event {Function} on-choose 启用 custom-choose 时触发，参数为 { accept, maxCount, fileList, index }，用户可自定义文件选择逻辑\n *\n * @example <u-upload :action=\"action\" :file-list=\"fileList\" accept=\"image\"></u-upload>\n * @example <u-upload :action=\"action\" accept=\"file\" mode=\"list\" :show-file-name=\"true\"></u-upload>\n */\n\nconst props = defineProps(UploadProps);\n\nconst { t } = useLocale();\n\nconst emit = defineEmits([\n    'on-list-change',\n    'on-oversize',\n    'on-exceed',\n    'on-choose',\n    'on-choose-complete',\n    'on-choose-fail',\n    'on-uploaded',\n    'on-success',\n    'on-error',\n    'on-change',\n    'on-progress',\n    'on-remove',\n    'on-preview',\n    'update:modelValue'\n]);\n\nconst lists = ref<UploadFileItem[]>([]);\nconst uploading = ref(false);\n\n// 默认文件图标映射\nconst defaultFileIconMap: Record<string, { name: string; bgColor: string }> = {\n    image: { name: 'photo', bgColor: 'var(--u-type-primary)' },\n    video: { name: 'play-circle', bgColor: 'var(--u-type-error)' },\n    pdf: { name: 'file-text', bgColor: 'var(--u-type-error)' },\n    word: { name: 'file-text', bgColor: 'var(--u-type-primary)' },\n    excel: { name: 'file-text', bgColor: 'var(--u-type-success)' },\n    ppt: { name: 'file-text', bgColor: 'var(--u-type-warning)' },\n    zip: { name: 'folder', bgColor: 'var(--u-tips-color)' },\n    audio: { name: 'volume-up', bgColor: 'var(--u-type-info)' },\n    file: { name: 'file-text', bgColor: 'var(--u-tips-color)' }\n};\n\n// 文件扩展名到类型的映射\nconst extTypeMap: Record<string, string> = {\n    // 图片\n    png: 'image',\n    jpg: 'image',\n    jpeg: 'image',\n    gif: 'image',\n    bmp: 'image',\n    webp: 'image',\n    svg: 'image',\n    // 视频\n    mp4: 'video',\n    avi: 'video',\n    mov: 'video',\n    wmv: 'video',\n    flv: 'video',\n    mkv: 'video',\n    rmvb: 'video',\n    '3gp': 'video',\n    m3u8: 'video',\n    // PDF\n    pdf: 'pdf',\n    // Word\n    doc: 'word',\n    docx: 'word',\n    // Excel\n    xls: 'excel',\n    xlsx: 'excel',\n    csv: 'excel',\n    // PPT\n    ppt: 'ppt',\n    pptx: 'ppt',\n    // 压缩包\n    zip: 'zip',\n    rar: 'zip',\n    '7z': 'zip',\n    tar: 'zip',\n    gz: 'zip',\n    // 音频\n    mp3: 'audio',\n    wav: 'audio',\n    wma: 'audio',\n    ogg: 'audio',\n    aac: 'audio',\n    flac: 'audio'\n};\n\n/**\n * 根据 accept 类型获取上传按钮文字\n */\nconst uploadBtnText = computed(() => {\n    // 如果用户自定义了 uploadText，优先使用\n    if (props.uploadText !== t('uUpload.uploadText')) {\n        return props.uploadText;\n    }\n    // 根据 accept 类型返回对应的国际化文本\n    switch (props.accept) {\n        case 'image':\n            return t('uUpload.uploadImage');\n        case 'video':\n            return t('uUpload.uploadVideo');\n        case 'file':\n            return t('uUpload.uploadFile');\n        case 'media':\n            return t('uUpload.uploadMedia');\n        case 'all':\n        default:\n            return t('uUpload.uploadFile');\n    }\n});\n\n/**\n * 同步外部列表到内部 lists\n * @param val 外部传入的文件列表\n * @param isModelValue 是否来自 modelValue\n */\nfunction syncToInternal(val: UploadFileItem[], isModelValue: boolean = false) {\n    // 只有当不是由内部变化触发时才同步（避免循环更新）\n    const externalList = isModelValue ? props.modelValue : props.fileList;\n    const externalSet = new Set(externalList.map((item: UploadFileItem) => item.url || item.path).filter(Boolean));\n    const internalSet = new Set(lists.value.map(item => item.url || item.path).filter(Boolean));\n\n    // 检查是否需要同步（简单比较长度和关键属性）\n    const needSync =\n        externalList.length !== lists.value.length ||\n        !externalList.every(\n            (item: UploadFileItem) => externalSet.has(item.url || item.path) && internalSet.has(item.url || item.path)\n        );\n\n    if (!needSync) return;\n\n    // 清空并重新填充（保持数据一致性）\n    lists.value = val.map((value: UploadFileItem) => {\n        const fileType = value.fileType || detectFileType(value);\n        return {\n            ...value,\n            url: value.url,\n            path: value.path,\n            name: value.name || getFileNameFromPath(value.url || value.path || ''),\n            size: value.size || 0,\n            fileType,\n            error: value.error || false,\n            progress: value.progress ?? 100\n        };\n    });\n}\n\n// 监听 modelValue 变化，自动同步内部 lists（v-model 模式，优先级更高）\nwatch(\n    () => props.modelValue,\n    val => {\n        if (val && val.length > 0) {\n            syncToInternal(val, true);\n        }\n    },\n    { immediate: true, deep: true }\n);\n\n// 监听 fileList 变化，自动同步内部 lists（向后兼容模式，仅在 modelValue 为空时生效）\nwatch(\n    () => props.fileList,\n    val => {\n        // 如果 modelValue 有值，优先使用 modelValue，忽略 fileList\n        if (props.modelValue && props.modelValue.length > 0) return;\n        syncToInternal(val, false);\n    },\n    { immediate: true, deep: true }\n);\n\n// 监听 lists 变化，自动触发事件\nwatch(\n    lists,\n    n => {\n        // 触发 v-model 更新\n        emit('update:modelValue', n);\n        // 触发 on-list-change 事件（向后兼容）\n        emit('on-list-change', n, props.index);\n    },\n    { deep: true }\n);\n\n/**\n * 从路径中获取文件名\n */\nfunction getFileNameFromPath(path: string): string {\n    if (!path) return '';\n    const arr = path.split('/');\n    return arr[arr.length - 1] || '';\n}\n\n/**\n * 根据扩展名检测文件类型\n */\nfunction getFileTypeByExt(ext: string): 'image' | 'video' | 'file' {\n    const lowerExt = ext.toLowerCase();\n    if (['png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp', 'svg'].includes(lowerExt)) {\n        return 'image';\n    }\n    if (['mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv', 'rmvb', '3gp', 'm3u8'].includes(lowerExt)) {\n        return 'video';\n    }\n    return 'file';\n}\n\n/**\n * 检测文件类型\n */\nfunction detectFileType(file: UploadFileItem): 'image' | 'video' | 'file' {\n    return getFileTypeByExt(getFileExt(file));\n}\n\n/**\n * 获取文件扩展名\n */\nfunction getFileExt(file: UploadFileItem): string {\n    const path = file.url || file.path || file.name || '';\n    if (!path) return '';\n    const reg = /\\.([^.]+)$/;\n    const match = path.match(reg);\n    return match ? match[1].toLowerCase() : '';\n}\n\n/**\n * 判断是否为图片文件\n */\nfunction isImageFile(file: UploadFileItem): boolean {\n    if (file.fileType) return file.fileType === 'image';\n    const ext = getFileExt(file);\n    return ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp', 'svg', 'image'].includes(ext);\n}\n\n/**\n * 判断是否为视频文件\n */\nfunction isVideoFile(file: UploadFileItem): boolean {\n    if (file.fileType) return file.fileType === 'video';\n    const ext = getFileExt(file);\n    return ['mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv', 'rmvb', '3gp', 'm3u8'].includes(ext);\n}\n\n/**\n * 获取文件图标配置\n */\nfunction getFileIcon(file: UploadFileItem): { name: string; bgColor: string } {\n    const ext = getFileExt(file);\n    const type = extTypeMap[ext] || 'file';\n\n    // 优先使用用户自定义配置\n    if (props.fileIconMap && props.fileIconMap[type]) {\n        const customIcon = props.fileIconMap[type];\n        return {\n            name: customIcon.name,\n            bgColor: customIcon.color || defaultFileIconMap[type]?.bgColor || 'var(--u-tips-color)'\n        };\n    }\n\n    return defaultFileIconMap[type] || defaultFileIconMap.file;\n}\n\n/**\n * 获取文件名（处理过长的情况）\n */\nfunction getFileName(file: UploadFileItem): string {\n    const name = file.name || getFileNameFromPath(file.url || file.path || '');\n    if (!name) return '未知文件';\n    // 如果文件名过长，截断显示\n    if (name.length > 15) {\n        const ext = getFileExt(file);\n        return name.substring(0, 12) + '...' + (ext ? '.' + ext : '');\n    }\n    return name;\n}\n\n/**\n * 格式化文件大小（简化版，避免 Math.log 计算）\n */\nfunction formatFileSize(size: number): string {\n    if (size === 0) return '0 B';\n\n    const KB = 1024;\n    const MB = KB * 1024;\n    const GB = MB * 1024;\n\n    if (size < KB) {\n        return size + ' B';\n    } else if (size < MB) {\n        return (size / KB).toFixed(2) + ' KB';\n    } else if (size < GB) {\n        return (size / MB).toFixed(2) + ' MB';\n    } else {\n        return (size / GB).toFixed(2) + ' GB';\n    }\n}\n\n/**\n * 清除列表\n */\nfunction clear() {\n    lists.value = [];\n}\n\n/**\n * 重新上传队列中上传失败的所有文件\n */\nfunction reUpload() {\n    uploadFile();\n}\n\n/**\n * 选择文件\n */\nfunction selectFile() {\n    if (props.disabled) return;\n\n    // 如果启用了自定义选择，触发 on-choose 事件，由用户自行处理文件选择\n    if (props.customChoose) {\n        emit('on-choose', {\n            accept: props.accept,\n            maxCount: props.maxCount,\n            fileList: lists.value,\n            index: props.index\n        });\n        return;\n    }\n\n    // 根据 accept 类型选择不同的文件选择方式\n    switch (props.accept) {\n        case 'image':\n            chooseImage();\n            break;\n        case 'video':\n            chooseVideo();\n            break;\n        case 'media':\n            chooseMedia();\n            break;\n        case 'file':\n        case 'all':\n            chooseFile();\n            break;\n        default:\n            chooseImage();\n    }\n}\n\n/**\n * 选择图片\n */\nfunction chooseImage() {\n    const newMaxCount = Number(props.maxCount) - lists.value.length;\n\n    uni.chooseImage({\n        count: props.multiple ? (newMaxCount > 9 ? 9 : newMaxCount) : 1,\n        sourceType: props.sourceType,\n        sizeType: props.sizeType as string[],\n        success: (res: any) => {\n            handleFilesSelected(res.tempFiles, 'image');\n        },\n        fail: (error: any) => {\n            emit('on-choose-fail', error);\n        }\n    });\n}\n\n/**\n * 选择视频\n */\nfunction chooseVideo() {\n    uni.chooseVideo({\n        sourceType: props.sourceType,\n        compressed: props.compressed,\n        maxDuration: props.maxDuration,\n        camera: props.camera as 'front' | 'back',\n        success: (res: any) => {\n            const file = {\n                path: res.tempFilePath,\n                name: res.name || getFileNameFromPath(res.tempFilePath),\n                size: res.size || 0,\n                width: res.width,\n                height: res.height,\n                duration: res.duration\n            };\n            handleFilesSelected([file], 'video');\n        },\n        fail: (error: any) => {\n            emit('on-choose-fail', error);\n        }\n    });\n}\n\n/**\n * 选择媒体文件（图片+视频）\n */\nfunction chooseMedia() {\n    // #ifdef MP-WEIXIN || MP-TOUTIAO || APP\n    const newMaxCount = Number(props.maxCount) - lists.value.length;\n    uni.chooseMedia({\n        count: props.multiple ? (newMaxCount > 9 ? 9 : newMaxCount) : 1,\n        mediaType: ['image', 'video'],\n        sourceType: props.sourceType,\n        maxDuration: props.maxDuration,\n        camera: props.camera as 'front' | 'back',\n        success: (res: any) => {\n            const files = res.tempFiles.map((file: any) => ({\n                path: file.tempFilePath,\n                name: file.name || getFileNameFromPath(file.tempFilePath),\n                size: file.size || 0,\n                thumb: file.thumbTempFilePath,\n                duration: file.duration,\n                width: file.width,\n                height: file.height\n            }));\n            handleFilesSelected(files, 'media');\n        },\n        fail: (error: any) => {\n            emit('on-choose-fail', error);\n        }\n    });\n    // #endif\n\n    // #ifndef MP-WEIXIN || MP-TOUTIAO || APP\n    // 非支持平台回退到选择图片\n    chooseImage();\n    // #endif\n}\n\n/**\n * 选择文件\n */\nfunction chooseFile() {\n    // #ifdef H5 || MP-WEIXIN\n    const newMaxCount = Number(props.maxCount) - lists.value.length;\n\n    // #ifdef H5\n    // H5 使用 chooseFile\n    if (typeof uni.chooseFile === 'function') {\n        uni.chooseFile({\n            count: props.multiple ? (newMaxCount > 100 ? 100 : newMaxCount) : 1,\n            type: 'all',\n            extension: props.extension.length > 0 ? props.extension : undefined,\n            success: (res: any) => {\n                handleFilesSelected(res.tempFiles, 'file');\n            },\n            fail: (error: any) => {\n                emit('on-choose-fail', error);\n            }\n        });\n    }\n    // #endif\n\n    // #ifdef MP-WEIXIN\n    // 微信小程序使用 chooseMessageFile\n    if (typeof uni.chooseMessageFile === 'function') {\n        uni.chooseMessageFile({\n            count: props.multiple ? (newMaxCount > 100 ? 100 : newMaxCount) : 1,\n            type: 'all',\n            extension: props.extension.length > 0 ? props.extension : undefined,\n            success: (res: any) => {\n                const files = res.tempFiles.map((file: any) => ({\n                    path: file.path,\n                    name: file.name,\n                    size: file.size,\n                    type: file.type\n                }));\n                handleFilesSelected(files, 'file');\n            },\n            fail: (error: any) => {\n                emit('on-choose-fail', error);\n            }\n        });\n    }\n    // #endif\n    // #endif\n\n    // #ifndef H5 || MP-WEIXIN\n    // 其他平台暂不支持文件选择，提示用户\n    showToast(t('uUpload.fileNotSupported') || '当前平台暂不支持文件选择');\n    // #endif\n}\n\n/**\n * 处理选中的文件\n * @param files 文件数组\n * @param sourceType 文件来源类型\n */\nfunction handleFilesSelected(files: any[], sourceType: 'image' | 'video' | 'media' | 'file') {\n    let listOldLength = lists.value.length;\n\n    files.forEach((val: any, index: number) => {\n        // 检查文件后缀是否允许\n        if (!checkFileExt(val)) return;\n\n        // 如果是非多选，index大于等于1或者超出最大限制数量时，不处理\n        if (!props.multiple && index >= 1) return;\n\n        if (val.size > Number(props.maxSize)) {\n            emit('on-oversize', val, lists.value, props.index);\n            showToast(t('uUpload.overSize'));\n        } else {\n            if (Number(props.maxCount) <= lists.value.length) {\n                emit('on-exceed', val, lists.value, props.index);\n                showToast(t('uUpload.overMaxCount'));\n                return;\n            }\n\n            // 根据 accept 和 sourceType 确定 fileType\n            let fileType: 'image' | 'video' | 'file';\n            if (props.accept === 'image') {\n                fileType = 'image';\n            } else if (props.accept === 'video') {\n                fileType = 'video';\n            } else if (props.accept === 'file') {\n                fileType = 'file';\n            } else {\n                // media 或 all 时，根据 sourceType 或路径检测\n                if (sourceType === 'image' || sourceType === 'video') {\n                    fileType = sourceType;\n                } else {\n                    fileType = detectFileTypeFromPath(val.path || val.name || '');\n                }\n            }\n\n            lists.value.push({\n                url: val.path,\n                path: val.path,\n                name: val.name || getFileNameFromPath(val.path || ''),\n                size: val.size || 0,\n                progress: 0,\n                error: false,\n                file: val,\n                fileType,\n                thumb: val.thumb || '',\n                width: val.width,\n                height: val.height,\n                duration: val.duration,\n                type: val.type\n            });\n        }\n    });\n\n    // 每次文件选择完，抛出一个事件，并将当前内部选择的文件数组抛出去\n    emit('on-choose-complete', lists.value, props.index);\n    // 使用 props.autoUpload 是否立即上传\n    if (props.autoUpload) uploadFile(listOldLength);\n}\n\n/**\n * 添加文件到列表（供外部调用，配合 custom-choose 使用）\n * @param files 文件数组，格式为 { path: string, name?: string, size?: number, fileType?: 'image'|'video'|'file', ... }\n */\nfunction addFiles(files: any[]) {\n    if (!files || !Array.isArray(files) || files.length === 0) return;\n    handleFilesSelected(files, props.accept as 'image' | 'video' | 'media' | 'file');\n}\n\n/**\n * 从路径中获取文件扩展名\n */\nfunction getExtFromPath(path: string): string {\n    if (!path) return '';\n    return path.split('.').pop() || '';\n}\n\n/**\n * 根据路径检测文件类型\n */\nfunction detectFileTypeFromPath(path: string): 'image' | 'video' | 'file' {\n    return getFileTypeByExt(getExtFromPath(path));\n}\n\n/**\n * 提示用户消息\n */\nfunction showToast(message: string, force = false) {\n    if (props.showTips || force) {\n        uni.showToast({ title: message, icon: 'none' });\n    }\n}\n\n/**\n * 该方法供用户通过ref调用，手动上传\n */\nfunction upload() {\n    uploadFile();\n}\n\n/**\n * 对失败的文件重新上传\n */\nfunction retry(index: number) {\n    lists.value[index].progress = 0;\n    lists.value[index].error = false;\n    lists.value[index].response = null;\n    if (props.showTips) {\n        uni.showLoading({ title: t('uUpload.reUpload') });\n    }\n    uploadFile(index);\n}\n\n/**\n * 上传文件\n */\nasync function uploadFile(index = 0): Promise<void> {\n    if (props.disabled) return;\n    if (uploading.value) return;\n\n    // 全部上传完成\n    if (index >= lists.value.length) {\n        emit('on-uploaded', lists.value, props.index);\n        return;\n    }\n\n    // 检查是否是已上传或者正在上传中\n    if (lists.value[index].progress === 100) {\n        if (props.autoUpload === false) uploadFile(index + 1);\n        return;\n    }\n\n    // 执行before-upload钩子\n    if (props.beforeUpload && typeof props.beforeUpload === 'function') {\n        let beforeResponse = props.beforeUpload(index, lists.value);\n        if (\n            typeof beforeResponse === 'object' &&\n            beforeResponse !== null &&\n            typeof (beforeResponse as Promise<any>).then === 'function'\n        ) {\n            await (beforeResponse as Promise<any>)\n                .then(() => {\n                    // promise返回成功，不进行动作，继续上传\n                })\n                .catch(() => {\n                    // 进入catch回调的话，继续下一个\n                    return uploadFile(index + 1);\n                });\n        } else if (beforeResponse === false) {\n            return uploadFile(index + 1);\n        }\n    }\n\n    // 检查上传地址\n    if (!props.action) {\n        showToast(t('uUpload.noAction'), true);\n        return;\n    }\n\n    lists.value[index].error = false;\n    uploading.value = true;\n\n    // 创建上传对象\n    const uploadTask = uni.uploadFile({\n        url: props.action,\n        filePath: lists.value[index].url || lists.value[index].path || '',\n        name: props.name,\n        formData: props.formData,\n        header: props.header,\n        // #ifdef MP-ALIPAY\n        fileType: isImageFile(lists.value[index]) ? 'image' : 'video',\n        // #endif\n        success: (res: any) => {\n            // 判断是否json字符串，将其转为json格式\n            let data = props.toJson && $u.test.jsonString(res.data) ? JSON.parse(res.data) : res.data;\n            if (![200, 201, 204].includes(res.statusCode)) {\n                uploadError(index, data);\n            } else {\n                // 上传成功\n                lists.value[index].response = data;\n                lists.value[index].progress = 100;\n                lists.value[index].error = false;\n                emit('on-success', data, index, lists.value, props.index);\n            }\n        },\n        fail: (e: any) => {\n            uploadError(index, e);\n        },\n        complete: (res: any) => {\n            // 上传完成后清除任务引用\n            lists.value[index].uploadTask = undefined;\n            uni.hideLoading();\n            uploading.value = false;\n            uploadFile(index + 1);\n            emit('on-change', res, index, lists.value, props.index);\n        }\n    });\n\n    // 保存上传任务引用，用于后续取消上传\n    lists.value[index].uploadTask = uploadTask as unknown as UniApp.UploadTask;\n\n    uploadTask.onProgressUpdate((res: any) => {\n        if (res.progress > 0) {\n            lists.value[index].progress = res.progress;\n            emit('on-progress', res, index, lists.value, props.index);\n        }\n    });\n}\n\n/**\n * 上传失败\n */\nfunction uploadError(index: number, err: any) {\n    lists.value[index].progress = 0;\n    lists.value[index].error = true;\n    lists.value[index].response = null;\n    emit('on-error', err, index, lists.value, props.index);\n    showToast(t('uUpload.uploadFailed'));\n}\n\n/**\n * 删除一个文件\n */\nfunction deleteItem(index: number) {\n    // 如果需要确认弹窗，显示 uni.showModal\n    if (props.showConfirm) {\n        uni.showModal({\n            title: t('uUpload.modalTitle'),\n            content: t('uUpload.deleteConfirm'),\n            cancelText: t('uUpload.modalCancelText'),\n            confirmText: t('uUpload.modalConfirmText'),\n            success: async (res: any) => {\n                if (res.confirm) {\n                    await executeBeforeRemove(index);\n                }\n            }\n        });\n    } else {\n        // 不需要确认弹窗，直接执行删除\n        executeBeforeRemove(index);\n    }\n}\n\n/**\n * 执行删除前的钩子并删除文件\n */\nasync function executeBeforeRemove(index: number) {\n    // 执行before-remove钩子\n    if (props.beforeRemove && typeof props.beforeRemove === 'function') {\n        let beforeResponse = props.beforeRemove(index, lists.value);\n        if (\n            typeof beforeResponse === 'object' &&\n            beforeResponse !== null &&\n            typeof (beforeResponse as Promise<any>).then === 'function'\n        ) {\n            await (beforeResponse as Promise<any>)\n                .then(() => {\n                    handlerDeleteItem(index);\n                })\n                .catch(() => {\n                    showToast(t('uUpload.terminatedRemove'));\n                });\n        } else if (beforeResponse === false) {\n            showToast(t('uUpload.terminatedRemove'));\n        } else {\n            handlerDeleteItem(index);\n        }\n    } else {\n        handlerDeleteItem(index);\n    }\n}\n\n/**\n * 执行移除文件的动作\n */\nfunction handlerDeleteItem(index: number) {\n    // 如果文件正在上传中，终止上传任务\n    if (lists.value[index].progress < 100 && lists.value[index].progress > 0) {\n        typeof lists.value[index].uploadTask != 'undefined' && lists.value[index].uploadTask?.abort?.();\n    }\n    lists.value.splice(index, 1);\n    emit('on-remove', index, lists.value, props.index);\n    showToast(t('uUpload.removeSuccess'));\n}\n\n/**\n * 用户通过ref手动的形式，移除一个文件\n */\nfunction remove(index: number) {\n    // 判断索引的合法范围\n    if (index >= 0 && index < lists.value.length) {\n        lists.value.splice(index, 1);\n    }\n}\n\n/**\n * 预览/打开文件\n */\nfunction doPreviewFile(item: string | UploadFileItem, index: number) {\n    // 处理字符串类型的文件\n    if (typeof item === 'string') {\n        item = { url: item };\n    }\n    // 图片文件预览\n    if (isImageFile(item)) {\n        doPreviewImage(item.url || item.path || '', index);\n        return;\n    }\n    // 视频文件不支持预览\n    if (isVideoFile(item)) {\n        return;\n    }\n    // 尝试打开文档\n    openDocument(item);\n}\n\n/**\n * 预览图片\n */\nfunction doPreviewImage(url: string, index: number) {\n    // 获取所有图片的url\n    const images = lists.value.filter(item => isImageFile(item)).map(item => item.url || item.path || '');\n    uni.previewImage({\n        urls: images,\n        current: url,\n        success: () => {\n            console.log('预览图片成功');\n        },\n        fail: () => {\n            showToast(t('uUpload.previewFailed'));\n        }\n    });\n}\n\n/**\n * 打开文档\n */\nfunction openDocument(item: UploadFileItem) {\n    // #ifdef H5\n    // H5 环境直接在新标签页打开\n    if (item.url) {\n        window.open(item.url, '_blank');\n    }\n    // #endif\n\n    // #ifndef H5\n    // 其他环境尝试使用 uni.openDocument\n    if (item.path || item.url) {\n        uni.openDocument({\n            filePath: item.path || item.url || '',\n            showMenu: true,\n            success: () => {\n                console.log('打开文档成功');\n            },\n            fail: err => {\n                console.error('打开文档失败', err);\n                showToast(t('uUpload.openFailed') || '无法打开此文件');\n            }\n        });\n    }\n    // #endif\n}\n\n/**\n * 统一处理预览\n */\nfunction handlePreview(item: UploadFileItem, index: number) {\n    emit('on-preview', item.url || item.path, lists.value, props.index);\n    // 判断是否允许预览\n    if (!props.previewFile) return;\n    // 图片文件预览\n    if (isImageFile(item) && props.previewFullImage) {\n        doPreviewImage(item.url || item.path || '', index);\n        return;\n    }\n    // 文件预览\n    doPreviewFile(item, index);\n}\n\n/**\n * 从文件名或路径中提取扩展名（简化版，避免正则表达式）\n */\nfunction extractExt(file: { name?: string; path?: string }): string {\n    let source: string;\n    // #ifdef H5\n    source = file.name || file.path || '';\n    // #endif\n    // #ifndef H5\n    source = file.path || file.name || '';\n    // #endif\n\n    if (!source) return '';\n    const lastDotIndex = source.lastIndexOf('.');\n    return lastDotIndex > -1 ? source.slice(lastDotIndex + 1).toLowerCase() : '';\n}\n\n/**\n * 判断文件后缀是否允许\n */\nfunction checkFileExt(file: { name?: string; path?: string }): boolean {\n    const fileExt = extractExt(file);\n\n    // 根据 accept 类型确定允许的后缀\n    let allowedExts: string[] = [];\n    if (props.limitType && props.limitType.length > 0) {\n        allowedExts = props.limitType;\n    } else if (props.accept === 'image') {\n        allowedExts = ['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp', 'svg', 'image'];\n    } else if (props.accept === 'video') {\n        allowedExts = ['mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv', 'rmvb', '3gp', 'm3u8'];\n    } else if (props.accept === 'file') {\n        // file 类型使用用户设置的 extension 或允许所有文件\n        allowedExts = props.extension.length > 0 ? (props.extension as string[]) : [];\n    } else if (props.accept === 'media') {\n        // media 类型，合并图片和视频格式\n        allowedExts = [\n            'png',\n            'jpg',\n            'jpeg',\n            'gif',\n            'webp',\n            'bmp',\n            'svg',\n            'mp4',\n            'avi',\n            'mov',\n            'wmv',\n            'flv',\n            'mkv',\n            'rmvb',\n            '3gp',\n            'm3u8'\n        ];\n    } else {\n        // all 类型，允许所有文件\n        return true;\n    }\n\n    // 如果没有限制类型（空数组），允许所有\n    if (allowedExts.length === 0) return true;\n\n    // 使用数组的some方法，只要符合allowedExts中的一个，就返回true\n    const isValid = allowedExts.some(ext => ext.toLowerCase() === fileExt);\n\n    if (!isValid) showToast(t('uUpload.notAllowedExt', { ext: fileExt || '未知' }));\n    return isValid;\n}\n\ndefineExpose({\n    lists,\n    clear,\n    reUpload,\n    selectFile,\n    upload,\n    retry,\n    remove,\n    previewImage: doPreviewImage,\n    previewFile: doPreviewFile,\n    addFiles\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-upload {\n    @include vue-flex;\n    flex-wrap: wrap;\n    align-items: center;\n}\n\n// ==================== Grid 模式样式 ====================\n.u-upload-grid__item {\n    width: 200rpx;\n    height: 200rpx;\n    overflow: hidden;\n    margin: 10rpx;\n    background: var(--u-bg-gray-light);\n    position: relative;\n    border-radius: 10rpx;\n    /* #ifndef APP-NVUE */\n    display: flex;\n    /* #endif */\n    align-items: center;\n    justify-content: center;\n}\n\n.u-upload-grid__preview {\n    border: 1px solid var(--u-border-color);\n}\n\n.u-upload-grid__add {\n    flex-direction: column;\n    color: $u-content-color;\n    font-size: 26rpx;\n}\n\n.u-upload-grid__add-text {\n    margin-top: 20rpx;\n    line-height: 40rpx;\n}\n\n.u-upload-grid__add--hover {\n    background-color: var(--u-bg-gray-light);\n}\n\n.u-upload-grid__image {\n    display: block;\n    width: 100%;\n    height: 100%;\n    border-radius: 10rpx;\n}\n\n.u-upload-grid__image--circle {\n    border-radius: 50%;\n}\n\n.u-upload-grid__item--circle {\n    border-radius: 50%;\n}\n\n.u-upload-grid__item--circle .u-upload-grid__delete {\n    top: 20rpx;\n    right: 30rpx;\n    width: 36rpx;\n    height: 36rpx;\n}\n\n.u-upload-grid__item--circle .u-upload-grid__progress {\n    bottom: 16rpx;\n    left: 16rpx;\n    right: 16rpx;\n}\n\n.u-upload-grid__delete {\n    position: absolute;\n    top: 10rpx;\n    right: 10rpx;\n    z-index: 10;\n    background-color: $u-type-error;\n    border-radius: 100rpx;\n    width: 44rpx;\n    height: 44rpx;\n    @include vue-flex;\n    align-items: center;\n    justify-content: center;\n}\n\n.u-upload-grid__progress {\n    position: absolute;\n    bottom: 10rpx;\n    left: 8rpx;\n    right: 8rpx;\n    z-index: 9;\n    width: auto;\n}\n\n.u-upload-grid__error {\n    color: var(--u-white-color);\n    background-color: $u-type-error;\n    font-size: 20rpx;\n    padding: 4px 0;\n    text-align: center;\n    position: absolute;\n    bottom: 0;\n    left: 0;\n    right: 0;\n    z-index: 9;\n    line-height: 1;\n}\n\n// Grid 模式：文件预览样式\n.u-upload-grid__file {\n    width: 100%;\n    height: 100%;\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    justify-content: center;\n    padding: 16rpx;\n    box-sizing: border-box;\n    position: relative;\n}\n\n.u-upload-grid__file-icon {\n    width: 80rpx;\n    height: 80rpx;\n    border-radius: 16rpx;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    margin-bottom: 12rpx;\n}\n\n.u-upload-grid__file-play {\n    position: absolute;\n    top: 50%;\n    left: 50%;\n    transform: translate(-50%, -50%);\n    margin-top: -20rpx;\n    opacity: 0.9;\n}\n\n.u-upload-grid__file-info {\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    width: 100%;\n}\n\n.u-upload-grid__file-name {\n    font-size: 22rpx;\n    line-height: 1.4;\n    text-align: center;\n    max-width: 100%;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n}\n\n.u-upload-grid__file-size {\n    font-size: 20rpx;\n    color: var(--u-tips-color);\n    margin-top: 4rpx;\n}\n\n// ==================== 列表模式样式 ====================\n.u-upload--list {\n    flex-direction: column;\n    align-items: stretch;\n}\n\n// 列表模式容器\n.u-upload-list {\n    display: flex;\n    flex-direction: column;\n    width: 100%;\n}\n\n// 列表项\n.u-upload-list__item {\n    display: flex;\n    align-items: center;\n    padding: 20rpx;\n    background: var(--u-bg-white);\n    border-radius: 12rpx;\n    margin-bottom: 16rpx;\n    border: 1rpx solid var(--u-border-color);\n    position: relative;\n}\n\n.u-upload-list__item--error {\n    border-color: var(--u-type-error);\n    position: relative;\n}\n\n.u-upload-list__item--error::before {\n    content: '';\n    position: absolute;\n    inset: 0;\n    background-color: var(--u-type-error);\n    opacity: 0.05;\n    border-radius: inherit;\n    pointer-events: none;\n}\n\n.u-upload-list__item:last-child {\n    margin-bottom: 0;\n}\n\n// 左侧：缩略图/图标\n.u-upload-list__left {\n    flex-shrink: 0;\n    margin-right: 20rpx;\n}\n\n.u-upload-list__thumb {\n    width: 80rpx;\n    height: 80rpx;\n    border-radius: 8rpx;\n    background: var(--u-bg-gray-light);\n}\n\n.u-upload-list__thumb--circle {\n    border-radius: 50%;\n}\n\n.u-upload-list__icon {\n    width: 80rpx;\n    height: 80rpx;\n    border-radius: 8rpx;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n}\n\n.u-upload-list__icon--circle {\n    border-radius: 50%;\n}\n\n// 中间：文件名信息\n.u-upload-list__center {\n    flex: 1;\n    display: flex;\n    flex-direction: column;\n    min-width: 0;\n    overflow: hidden;\n}\n\n.u-upload-list__name {\n    font-size: 28rpx;\n    color: var(--u-content-color);\n    line-height: 1.4;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n    text-align: left;\n}\n\n.u-upload-list__name--error {\n    color: var(--u-type-error);\n}\n\n.u-upload-list__size {\n    font-size: 24rpx;\n    color: var(--u-tips-color);\n    margin-top: 8rpx;\n    text-align: left;\n}\n\n.u-upload-list__progress {\n    margin-top: 12rpx;\n    width: 100%;\n}\n\n// 重试按钮\n.u-upload-list__retry {\n    display: flex;\n    align-items: center;\n    margin-top: 8rpx;\n    padding: 8rpx 16rpx;\n    border-radius: 8rpx;\n    align-self: flex-start;\n    position: relative;\n}\n\n.u-upload-list__retry::before {\n    content: '';\n    position: absolute;\n    inset: 0;\n    background-color: var(--u-type-error);\n    opacity: 0.1;\n    border-radius: inherit;\n    pointer-events: none;\n}\n\n.u-upload-list__retry--hover::before {\n    opacity: 0.2;\n}\n\n.u-upload-list__retry-text {\n    font-size: 24rpx;\n    color: var(--u-type-error);\n    margin-left: 8rpx;\n}\n\n// 右侧：删除按钮\n.u-upload-list__right {\n    flex-shrink: 0;\n    margin-left: 20rpx;\n    background-color: $u-type-error;\n    border-radius: 100rpx;\n    width: 44rpx;\n    height: 44rpx;\n    @include vue-flex;\n    align-items: center;\n    justify-content: center;\n}\n\n// 列表模式添加按钮\n.u-upload-list__add {\n    margin-top: 16rpx;\n}\n\n.u-upload-list__add-btn {\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    padding: 24rpx;\n    background: var(--u-bg-white);\n    border: 2rpx dashed var(--u-border-color);\n    border-radius: 12rpx;\n    transition: all 0.3s;\n}\n\n.u-upload-list__add-btn--hover {\n    background: var(--u-bg-gray-light);\n    border-color: var(--u-type-primary);\n}\n\n.u-upload-list__add-text {\n    margin-left: 16rpx;\n    font-size: 28rpx;\n    color: var(--u-type-primary);\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-verification-code/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\nimport { useLocale } from '../../';\n\nconst { t } = useLocale();\n\n/**\n * VerificationCodeProps 验证码输入框 props 类型定义\n * @description 验证码输入倒计时组件\n */\nexport const VerificationCodeProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 倒计时时长，单位秒 */\n    seconds: { type: [String, Number] as PropType<string | number>, default: 60 },\n    /** 开始时按钮文字 */\n    startText: { type: String, default: () => t('uVerificationCode.startText') },\n    /** 倒计时进行中按钮文字，X为剩余秒数 */\n    changeText: { type: String, default: () => t('uVerificationCode.changeText') },\n    /** 结束时按钮文字 */\n    endText: { type: String, default: () => t('uVerificationCode.endText') },\n    /** 是否保持倒计时不中断（如页面切换） */\n    keepRunning: { type: Boolean, default: false },\n    /** 唯一标识key，用于区分多个验证码组件 */\n    uniqueKey: { type: String, default: '' }\n};\n\nexport type VerificationCodeProps = ExtractPropTypes<typeof VerificationCodeProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-verification-code/u-verification-code.vue",
    "content": "<template>\n    <view class=\"u-code-wrap\" :class=\"customClass\" :style=\"$u.toStyle(customStyle)\">\n        <!-- 此组件功能由js完成，无需写html逻辑 -->\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-verification-code',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, watch, onMounted, onBeforeUnmount } from 'vue';\nimport { VerificationCodeProps } from './types';\nimport { $u } from '../../';\n\n/**\n * verificationCode 验证码输入框\n * @description 考虑到用户实际发送验证码的场景，可能是一个按钮，也可能是一段文字，提示语各有不同，所以本组件不提供界面显示，只提供提示语，由用户将提示语嵌入到具体的场景\n * @tutorial https://uviewpro.cn/zh/components/verificationCode.html\n * @property {Number|String} seconds 倒计时所需的秒数（默认60）\n * @property {String} startText 开始前的提示语，见官网说明（默认获取验证码）\n * @property {String} changeText 倒计时期间的提示语，必须带有字母\"x\"，见官网说明（默认X秒重新获取）\n * @property {String} endText 倒计时结束的提示语，见官网说明（默认重新获取）\n * @property {Boolean} keepRunning 是否在H5刷新或各端返回再进入时继续倒计时（默认false）\n * @property {String} uniqueKey 区分多个页面或多个倒计时组件本地存储的key\n * @event change 倒计时期间，每秒触发一次\n * @event start 开始倒计时触发\n * @event end 结束倒计时触发\n * @example <u-verification-code :seconds=\"seconds\" @end=\"end\" @start=\"start\" ref=\"uCode\" />\n */\n\nconst emit = defineEmits(['change', 'start', 'end']);\n\nconst props = defineProps(VerificationCodeProps);\n\n/** 当前倒计时秒数 */\nconst secNum = ref(Number(props.seconds));\n/** 定时器句柄 */\nlet timer: ReturnType<typeof setInterval> | null = null;\n/** 是否可以执行验证码操作 */\nconst canGetCode = ref(true);\n\n// 监听 seconds 变化，重置倒计时秒数\nwatch(\n    () => props.seconds,\n    n => {\n        secNum.value = Number(n);\n    },\n    { immediate: true }\n);\n\nonMounted(() => {\n    checkKeepRunning();\n});\n\nonBeforeUnmount(() => {\n    setTimeToStorage();\n    if (timer) clearTimeout(timer);\n    timer = null;\n});\n\n/**\n * 检查是否需要继续上一次的倒计时\n * @description 用于H5刷新或各端返回再进入时继续倒计时\n */\nfunction checkKeepRunning() {\n    // 获取上一次退出页面(H5还包括刷新)时的时间戳，如果没有上次的保存，此值可能为空\n    const lastTimestamp = Number(uni.getStorageSync(props.uniqueKey + '_$uCountDownTimestamp'));\n    if (!lastTimestamp) return changeEvent(props.startText);\n    // 当前秒的时间戳\n    const nowTimestamp = Math.floor(+new Date() / 1000);\n    // 判断当前的时间戳，是否小于上一次的本该按设定结束，却提前结束的时间戳\n    if (props.keepRunning && lastTimestamp && lastTimestamp > nowTimestamp) {\n        // 剩余尚未执行完的倒计秒数\n        secNum.value = lastTimestamp - nowTimestamp;\n        // 清除本地保存的变量\n        uni.removeStorageSync(props.uniqueKey + '_$uCountDownTimestamp');\n        // 开始倒计时\n        start();\n    } else {\n        // 如果不存在需要继续上一次的倒计时，执行正常的逻辑\n        changeEvent(props.startText);\n    }\n}\n\n/**\n * 开始倒计时\n * @description 防止快速点击获取验证码的按钮而导致内部产生多个定时器导致混乱\n */\nfunction start() {\n    if (timer) {\n        clearInterval(timer);\n        timer = null;\n    }\n    emit('start');\n    canGetCode.value = false;\n    // 一开始时就提示，否则要等setInterval的1秒后才会有提示\n    changeEvent(props.changeText.replace(/x|X/, String(secNum.value)));\n    setTimeToStorage();\n    timer = setInterval(() => {\n        if (--secNum.value) {\n            // 用当前倒计时的秒数替换提示字符串中的\"x\"字母\n            changeEvent(props.changeText.replace(/x|X/, String(secNum.value)));\n        } else {\n            clearInterval(timer!);\n            timer = null;\n            changeEvent(props.endText);\n            secNum.value = Number(props.seconds);\n            emit('end');\n            canGetCode.value = true;\n        }\n    }, 1000);\n}\n\n/**\n * 重置，可以让用户再次获取验证码\n */\nfunction reset() {\n    canGetCode.value = true;\n    if (timer) clearInterval(timer);\n    timer = null;\n    secNum.value = Number(props.seconds);\n    changeEvent(props.endText);\n}\n\n/**\n * 触发 change 事件\n * @param text 当前提示文本\n */\nfunction changeEvent(text: string) {\n    emit('change', text);\n}\n\n/**\n * 保存时间戳，为了防止倒计时尚未结束，H5刷新或者各端的右上角返回上一页再进来\n */\nfunction setTimeToStorage() {\n    if (!props.keepRunning || !timer) return;\n    // 记录当前的时间戳，为了下次进入页面，如果还在倒计时内的话，继续倒计时\n    // 倒计时尚未结束，结果大于0；倒计时已经开始，就会小于初始值，如果等于初始值，说明没有开始倒计时，无需处理\n    if (secNum.value > 0 && secNum.value <= Number(props.seconds)) {\n        // 获取当前时间戳(+ new Date()为特殊写法)，除以1000变成秒，再去除小数部分\n        const nowTimestamp = Math.floor(+new Date() / 1000);\n        // 将本该结束时候的时间戳保存起来 => 当前时间戳 + 剩余的秒数\n        uni.setStorage({\n            key: props.uniqueKey + '_$uCountDownTimestamp',\n            data: nowTimestamp + Number(secNum.value)\n        });\n    }\n}\ndefineExpose({\n    start,\n    reset,\n    canGetCode\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-code-wrap {\n    width: 0;\n    height: 0;\n    position: fixed;\n    z-index: -1;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-waterfall/types.ts",
    "content": "import type { ExtractPropTypes, PropType } from 'vue';\n\n/**\n * WaterfallProps waterfall props 类型定义\n * @description 瀑布流组件，支持数据、间隔、idKey\n */\nexport const WaterfallProps = {\n    /** 自定义根节点样式 */\n    customStyle: {\n        type: [String, Object] as PropType<string | Record<string, any>>,\n        default: () => ({})\n    },\n    /** 自定义根节点样式类 */\n    customClass: {\n        type: String as unknown as PropType<string>,\n        default: ''\n    },\n    /** 瀑布流数据数组，必填 */\n    modelValue: { type: Array as PropType<any[]>, required: true, default: () => [] },\n    /** 新增数据的动画间隔，单位ms */\n    addTime: { type: [Number, String] as PropType<number | string>, default: 200 },\n    /** 数据项的唯一标识key */\n    idKey: { type: String, default: 'id' }\n};\n\nexport type WaterfallProps = ExtractPropTypes<typeof WaterfallProps>;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/components/u-waterfall/u-waterfall.vue",
    "content": "<template>\n    <view class=\"u-waterfall\" :class=\"customClass\" :style=\"$u.toStyle(customStyle)\">\n        <view id=\"u-left-column\" class=\"u-column\">\n            <slot name=\"left\" :leftList=\"leftList\"></slot>\n        </view>\n        <view id=\"u-right-column\" class=\"u-column\">\n            <slot name=\"right\" :rightList=\"rightList\"></slot>\n        </view>\n    </view>\n</template>\n\n<script lang=\"ts\">\nexport default {\n    name: 'u-waterfall',\n    options: {\n        addGlobalClass: true,\n        // #ifndef MP-TOUTIAO\n        virtualHost: true,\n        // #endif\n        styleIsolation: 'shared'\n    }\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { ref, computed, watch, onMounted } from 'vue';\nimport { WaterfallProps } from './types';\nimport { useRect, $u } from '../../';\n\nconst { getRect } = useRect();\n\n/**\n * waterfall 瀑布流\n * @description 这是一个瀑布流形式的组件，内容分为左右两列，结合uView的懒加载组件效果更佳。相较于某些只是奇偶数左右分别，或者没有利用vue作用域插槽的做法，uView的瀑布流实现了真正的 组件化，搭配LazyLoad 懒加载和loadMore 加载更多组件，让您开箱即用，眼前一亮。\n * @tutorial https://uviewpro.cn/zh/components/waterfall.html\n * @property {Array} flow-list 用于渲染的数据\n * @property {String | Number} add-time 单条数据添加到队列的时间间隔，单位ms，见上方注意事项说明（默认200）\n * @example <u-waterfall :flowList=\"flowList\"></u-waterfall>\n */\n\nconst emit = defineEmits(['update:modelValue']);\n\nconst props = defineProps(WaterfallProps);\n\nconst leftList = ref<any[]>([]);\nconst rightList = ref<any[]>([]);\nconst tempList = ref<any[]>([]);\n\n/**\n * 破坏 flowList 变量的引用，否则 watch 的结果新旧值是一样的\n */\nconst copyFlowList = computed(() => cloneData(props.modelValue));\n\nwatch(copyFlowList, (nVal, oVal) => {\n    // 取差值，即这一次数组变化新增的部分\n    const startIndex = Array.isArray(oVal) && oVal.length > 0 ? oVal.length : 0;\n    // 拼接上原有数据\n    tempList.value = tempList.value.concat(cloneData(nVal.slice(startIndex)));\n    splitData();\n});\n\nonMounted(() => {\n    tempList.value = cloneData(copyFlowList.value);\n    splitData();\n});\n\n/**\n * 复制而不是引用对象和数组\n */\nfunction cloneData(data: any) {\n    return $u.deepClone(data);\n}\n\n/**\n * 异步分配数据到左右列\n */\nasync function splitData() {\n    if (!tempList.value.length) return;\n    const leftRect = await getRect('#u-left-column');\n    const rightRect = await getRect('#u-right-column');\n    // 如果左边小于或等于右边，就添加到左边，否则添加到右边\n    const item = tempList.value[0];\n    // 解决多次快速上拉后，可能数据会乱的问题，因为经过上面的两个await节点查询阻塞一定时间，加上后面的定时器干扰\n    // 数组可能变成[]，导致此item值可能为undefined\n    if (!item) return;\n    if (leftRect.height < rightRect.height) {\n        leftList.value.push(item);\n    } else if (leftRect.height > rightRect.height) {\n        rightList.value.push(item);\n    } else {\n        // 这里是为了保证第一和第二张添加时，左右都能有内容\n        // 因为添加第一张，实际队列的高度可能还是0，这时需要根据队列元素长度判断下一个该放哪边\n        if (leftList.value.length <= rightList.value.length) {\n            leftList.value.push(item);\n        } else {\n            rightList.value.push(item);\n        }\n    }\n    // 移除临时列表的第一项\n    tempList.value.splice(0, 1);\n    // 如果临时数组还有数据，继续循环\n    if (tempList.value.length) {\n        setTimeout(() => {\n            splitData();\n        }, Number(props.addTime));\n    }\n}\n\n/**\n * 清空数据列表\n */\nfunction clear() {\n    leftList.value = [];\n    rightList.value = [];\n    // 同时清除父组件列表中的数据\n    emit('update:modelValue', []);\n    tempList.value = [];\n}\n\n/**\n * 清除某一条指定的数据，根据 id 实现\n */\nfunction remove(id: string | number) {\n    let index = leftList.value.findIndex(val => val[props.idKey] == id);\n    if (index !== -1) {\n        // 如果index不等于-1，说明已经找到了要找的id，根据index索引删除这一条数据\n        leftList.value.splice(index, 1);\n    } else {\n        // 同理于上方面的方法\n        index = rightList.value.findIndex(val => val[props.idKey] == id);\n        if (index !== -1) rightList.value.splice(index, 1);\n    }\n    // 同时清除父组件的数据中的对应id的条目\n    index = props.modelValue.findIndex((val: any) => val[props.idKey] == id);\n    if (index !== -1) emit('update:modelValue', props.modelValue.splice(index, 1));\n}\n\n/**\n * 修改某条数据的某个属性\n */\nfunction modify(id: string | number, key: string, value: any) {\n    let index = leftList.value.findIndex(val => val[props.idKey] == id);\n    if (index !== -1) {\n        // 如果index不等于-1，说明已经找到了要找的id，修改对应key的值\n        leftList.value[index][key] = value;\n    } else {\n        // 同理于上方面的方法\n        index = rightList.value.findIndex(val => val[props.idKey] == id);\n        if (index !== -1) rightList.value[index][key] = value;\n    }\n    // 修改父组件的数据中的对应id的条目\n    index = props.modelValue.findIndex((val: any) => val[props.idKey] == id);\n    if (index !== -1) {\n        // 首先复制一份value的数据\n        const data = cloneData(props.modelValue);\n        // 修改对应索引的key属性的值为value\n        data[index][key] = value;\n        // 修改父组件通过v-model绑定的变量的值\n        emit('update:modelValue', data);\n    }\n}\ndefineExpose({\n    clear,\n    remove,\n    modify\n});\n</script>\n\n<style lang=\"scss\" scoped>\n@import '../../libs/css/style.components.scss';\n\n.u-waterfall {\n    @include vue-flex;\n    flex-direction: row;\n    align-items: flex-start;\n}\n\n.u-column {\n    @include vue-flex;\n    flex: 1;\n    flex-direction: column;\n    height: auto;\n}\n\n.u-image {\n    width: 100%;\n}\n</style>\n"
  },
  {
    "path": "src/uni_modules/uview-pro/iconfont.css",
    "content": "/* #ifdef APP-PLUS */\n@font-face {\n    font-family: 'uicon-iconfont';\n    font-weight: normal;\n    font-style: normal;\n    font-display: auto;\n    src: url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAGQYAAsAAAAAw2gAAGPEAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCdAAqCv3SB/XABNgIkA4ZoC4M2AAQgBYRtB5cNG+OfdYacxwEA9eYzEqHbAaXC+ZFZWS8oKTr7/09LKmNsu7DdEEVL04JkStgZyOKZ/ILQ2JzQooY+O2mlDm88cwprtIUJRYoVp8q1MEe1Ow/WIUjUNfnNH9HJV5m92kW8dnj/3pEhB8aSgR+4kj24yOevPzf/ix2t5Ij79FHJAsd5EFJ2EoByUZPNHtWZ1VUw8TCKNsPzc+v9/WVQI8dGjhpsRMkSRg/YRimMGiDhCBkIyggFLMAzAAsVA/BOjAJUrBMVFTk9PQUPK0D0ro1REM/4bck0GjGLMBKwOzEqMDrm/+DNvwEAhTsoAAkoYGpB7e4LMInq4Z7d2/lSHmrkiVCowgFOGC/4BjLdjqZBMK9fkWmEJpgKgx8EK9nAPEPOk30pNCLq0BlSKNLexDrvFnL/EBcKlB/2YPqlzm92rMBKbxWxIXacD0TdMTTllTdfbtWnkEtVgBUaVkW6e6oqLSvgq84luVauJUGaMQg240CPmETe+8e/tZabTzHZvWtZycoqHH//BQBFFJvYg6cSCAPK0P/lViVvbmTWIzDi0N0rLjdoVkyOXJIrXJMg1hJIpYJpuwL9q2rensSOdFq7rfav29kR3LEgWD1R08h27tjxMauRWqk1yAqQxIEnxwk/k9Xvp4mNJ5uJLShAeP9ebatUY0naCgW0UITh59azOqqoboMT35k+wU5MV6BC/qWqJ5UnA9vtHQlfnOYXH0EGqAuWT9o/uCI/R6qH5JFb21r+/3mKC2j3fzlyPaQSlCkmTghdBueFPOIgIuD/pjV7uSVUtRJH3r1Qi793yiERbvfPn1kmfye50j+ht+xRakKdXWpRyFaEW2p3vgqDx5kmUV5C/ceN8zDBBaE/Jw+cu0rV+oKmNmRq88X0i/W3q7b+l373+kzPkBYGICUCkGiCVIIo+wTKgQBlF0E6BXIjpfPl9IoRIB0I0nsFUA6kfAHcKG6W9/JrN1/Mz5Ce9/jc+327ryVoKss14vz/aVtEFGJxKA6zw9isAcvQsULlmCICMkSMr7y8H5v/3H7HKsRIsIE7JNR0v68Ola+NidPXgYK7d4y5/kTrx1YiH3ACHY721PpPEwB52aopNP+2724kpHhSAITxv1FDjHzpgDzZMsCCoCevzA4ZdNuGwWaub2JsOr5/+GfTAhbIQEXxzM4jWww363cwcBfD37CDtobhdX241wMioCayVW4+bY0NiYeueRB+9rkNjZPR3SzDmPy+DZuAipEDJ95srvX1+/VHZ73km/Ct/p2utNSVpqu82hqCBAuZNq+8ATmVfJVWWHeYbwS/04tPTM/uwnx5/WrZyVW5K5oTo3NVqPm14m2BMjTemmu9rddzuzLfe3tb7nMPuIeaD4waumN34v8dT1ljigt5jIEn4Cl4Bp6D5ra9AG3NcPfedF1NNsxLUJuXzqNjHXsFxnkN7h/femLnVG/A/n11YXjrmqOdt2C8CXIrtGdHJTfBu2Cm98D7IK87oI0PwYGTB7d/BKbooLKD+cRp72PwCfgUPJjtMzDN5ocTVRGvs6Za+Bx8Ab4ErbS26yswyKFJmhmlgAJ7RxhpsHpyne6mux7O9NRLF7310VdL/fQ3QBlk9lgsrTBPIVaoHNDQMdRZoDhTZtCYLJhDgOkttEgOhiVZjcuWr1i5qiSi1jWlrF23fsPGoarqPdJQmPaAzQefgK8sZ8+dH+jCxUuXr1y9dv3GzVu37zTWRAX+AgQKEixEKFdcbtx5AINyGjgWYHT9vvZfIDCqgylAED4WAqOAYHwChMSnQCh8BoTG50AYfAGExVaEw53C40sgAnYgIs4mEt4TGe+LgrOIij2IhtOIjiOJga+ATLA2kCnWATLD7TLH47LACcTEE7LE10BWOJGs8Q2QDT6QLZ6UHe4QC0/JHveIjTOIg2+BHPCgHPGAnLAukDNGALlgPSBX3Ccuzic37Eju+A7IAyeRJ04mL4wE4uF48sZc+eBu8bESkADfA/niByA/nEP++BEoAD8BBWI0UBB+BgrG9hSCX4BC8ZAW4WmF4WEJcZdE+BVIjNNJgp1JipWBZHhG4RgDFIFdSI6dKBK/AUXhd6Bo/AEUgw8Vi/MoDn8CxeNMUuA2JeAjJeIUSsIqQErsSirsRmrMoWRsTSn4CygVfwOl4R+gdGxLi7EdLcG9ysC/QJmPNw0eURZOpWxsSTk4lnIxDigPx5EW9yv/nFXgqND5XUthfaAiHEXFeFYl2JNKsRctw96kw3Mqwz5Ujn2pArtTJfaj5difqnAA6bENVeNAqsFBtAIHUy2WBarDeKCVWA5oFaYC1WNJIAMuoAZcSI2YANSEpYCaMRFoNVYEWoNJQC2YDNSKhYDacBGtxcW0DgsDrcciQBuwKNBGDAdqxxJAHVgcqBOLAW3CYKAfMARoM86lLbiEtuJS2oZhQD24TNtxuXZgKFAvrtAeXKk+XKX9uFoHcI0O4lodwtJA/RgLNIDrNIjrNYRlgI7iBh3DjTqDm3QWN2sYt2gUR9AvWBXoBR7VOzxmPozNgflIbAHMx82tPbwZJFOzvJzMNDmb6fIyM8Q3M5VgDlereV4PzAv63byo53AICxLwkgUqvGyBel5RqXlVOvOays3rWmHeUK15Uw3mLa0289Ri3labeUdrzbv6yczSFTNb/8MKwIAcGwADKmwIDOTORsozG0trNlG+2VQVZjNVmtVUY1bXCrOG1pk1tcEfawH4D2DQdYP/N20SmD0zvuG/kuhhSdB/fz0IEhYaHmrTyNGHgpHDaUQyEvylEiPhpvAsgAdcUqDhBAzjoxDBamWWHEXLRUk3zQIxJnRqcWaNC1AmhIpAAVyaA7hpHlAPTAEsEAikPkuF4ArAbE4NKENRV7oFAztaGpkyLioJfbF3cbQNo6FblBgH+xgUe1gRDVZjE0h+jmFKOA1ZH2aGqUo1CNuTLdrewl6g5gToj+dRS0ckZ5JyNwz5Vguh2Wa0tKjj/kJ0Pi8Q8yPlTocrnq4hEa3FCDocKYsubQ9jkix6OMlKQVSKzZhMfyUP+hh8LpsQPaxNgRhujI5YpMtinZ4414eSNeBbw1Ls6Gp2amgIjjunapxZgSPKLKeXY1BBiz3kxFjZLCmGrd20fav4lvWoCFiF0i7H/rBPPxcbTXmpffcEi0en9a4TrZ3b29250myHaYrEbXJ2IQIbKp61FYJT8MxSGdedJsFuVe2162qscnZbu93dHb9dtt/tHxOSmhwU4liXKB6sThZdbqZB68SUGFIUHO9hC4V931S2mW42m7B+S/EEgYKUJasluMCKgWG0syNq01mLLImeKX+CQedh0gE8PQ1oajBrg1UqguHfLBI4fLvEHTNqQ01rZq/1J39onmem5XFG2PmFXDN/f7C8Zl/Cq6X+CZJlshonJDsrE/AIu0EMC9sGlTQsLrgq4vVMLdh5NKgO4rC/QGaKWGIacOw8l5RuOgcchkMH1+90IOa/2N+azrACjLEvwNZsit0UF7BcoRWCbK67FLt24V0TPbgcxG39QNk1uUNKGPRZcS7Y7J5ktZljwx4ATLywmxph7hHqvPNfk+GdpPwQNMgQwXQYO54MZiiwuRQE2xAwOQgOAqGgE/RQl5+FfF7eDYfm2jFIhuuoz9XThdADbICBfGs1rTkfbCtCEhxC5FEhFdA8I68xxB3fDFU9JZjRqUMNKcPlXD7pCm4sIH8q20pngJRErVfT2Iahf+8X8Lvg3AOBsOtwuevJxeXm2SYvAbmlbDkExXPQNDIWTadUAEa98rqioP2RNAsLylBYAMEHqJgBVgaLpgzMHbjbBA2L39wEpEXjzCY7s00W1LgT1EwRxSjjxoJ/oFoKjHPON5aDfedhXl8dmckO1uIN10j1HFmyxd2SFOnC0Vh9kVKwrAGJr0OuGlYpYquJrxYtQ2mlzzGVcVCL8swKGkTQ64kagF8j100W718Q8VopCopjK6C4i689URK20A+IJnQuzXMmR52pWYXM9Hpi04bbbujXXkyI4rNVaAWkKSDXORDJu/7z0pirFs1kEmQzXpT6cfjEUGba5thBeu5/cVtb3kINXO93sNeGlXdWDqW8Hfe6osCwCoqrx2W+Y7uOkVA5lLKlGFBqiITEw/FVPIzO4oLVG5FIN0RNBuV1nGh7JMPZTXV5Ho4HjtjKUErsFtxU6QAwTFvFtdCrDy/vjtdR1yFyq7L59XcVnfG+Rx8fNugzG5n4hSR8dfVxQtOPLXnV3U7typyHRy8KvUrEizAGooABJbOhIKbfJpjGMVh3UtTP7zGK1rIRZfTb3Lsw1r2mC4I6QtKc6cFxOj0gJi8doJz3ht3QfkJJ1wL/kAGhczPEyF41Y2VGn1I5pc51d/6ovdWl/R++PzjbHq1PH8agTYWXvDKFjYlQtx/giou9Kijc3D51Ry9CZgqZoq2SRhVnwZlZRRRgBmkvlgBUl9aIk4EYz0Ld31USbuBrAuX2cHRLqLkvaB/EQt/dhAhuSvI+lWsRSEvUWC1eFNI9VBWo8ByVBbcPhCMpx9csfloGoIYWdabz1qC15pKm5GcSYKDyBZPDbdrU6okbWL/G04cmkqLK7na4JW3mTtSQ1lp4KzldOg7Q+7J3YEJwv/wuuru5bNkSevbx0X4pjyaLxzTIFpb2bTClTaYAK5VDU4gwIQ0oaMJgscXpMtSQPWSJnFlqSYHUQjHGOGRKUH8O36cNr9+SoNKjs5XxSJ5Ky+n2FS3j8cepyIBkSzCnH/K07s6pmXizamV/7UUOgEJDBqRBqHOygXBIIVHwVooRWC7qBIzPMuxeDuU5bMWvt3V8Ap51RNVMI+ghOGnGhok7t75QDbfX+hlVr7KXA93sSUUvdVq8g4hMktX8uiXrkdWyjmawkwnROjZ/yWSORHT1kZOeOU918lDEm08fmk5fQovOZw48n6lB0JwiejPCVQHNy+Yi3nStRNdRYsk3/KCdyzDOBPdT3RcSEWTnMhc1KtuAJeNCExCwxbvSEd+EWSLpqAokpBRDybILw0GWJ5WICLUxnrU3v70ZJFQ6snWeJKejBykXDXRK7poBRMxK96reuvm9SPI/uFVG+LeyL1wIiFdJFAobVU4sITsEjSkVvZSt9hFPFAmCMGfPWo+WrkRm1j/ICLuKrhjPMQCAxQTKRWMjcRloQoArUYtA9LrztibHkNO7kgft3xgnNF1DGixWcOCk/e6DuVeL37stucRVKA/8tjsTiaXlZu7soX8nyS/8SmuVRmdrVllccLKGEN7vqCrtcczv14jfmVyQykAf3ig1GTo1M8FzhXwRSOzZwpns4LloG9+SyHQgpVxK5LcGVeV6pUQuJDV6UqZP5MkoIO0/JAKD/mzgNHlCvngeFWPrYIiGTcW9SEAwPFJGZ6TF+fgrVBZjsLkB8oTbAUODXA/7t+eKQiDtdeVpWOCq06nj9NZEmQio7UC7ockeAm2JYyQQaaNj8MbMoZqyT4S40BUhJ5uwQyw3OepOW1Q2rITt1Hg3eCuYEDuDTlIiEoYSMSjSVHju3rK8Uj2/kPfI72reEEn5D77TsyRz46rb4Fwc49qev2NsROWSHfmmHx37briuXDtZPWbFaIaLrcdcUJnH1U2G8dkk24tVhjReHe3rCwhsStxxo6p1qZ5LW+u1kvD+DTsrFg4DdfyQCrTDuzdHOz6DNoWyqXOoncD8KLT+C8pNiqE0DdeyTpqd6z2CJn5jBu8mzsXQA4U0spwOkrV6VaYE3+8guIKg0kAD1yJoh6/vRtCpKHpfFxKlhjI5PlM5Nk6lDuQUPIkNdEWaXk/i9tdWDppsyTsM9t29y+sA7BtYHER5q2gbOYvRtmZjbLgnghKmHeSXKhrKGznO7v1Eg7jmvq4svo1Wl0/E20tH9qGyx5eeVJtr275eqrjRPVcplxx1P7Cq5W7s0FP/lsU8hM3qRNNylTBTwnbYbc0a5+ldB5M8UxzyV0VQ2r2Wg4zfxR3GBMGon5T36dCTMsX4GiqF/2wXk3OhUJR6gtdB19zBwOF5L7zh/8rK8dSB8rJGolYqjTme+17uQDY7tl/rLMiR+mJwqEUbS09a55yo2r4QRFC27tgamxxwCXrHW2OjKwwyZhwJVkQHojOMhCbV+OtExBzqWz144bIAwPXJWSDl9V/AT3gt/FvV9DLpa4kkcYPK75GNRA1aDiHjMMPATTRifViXHA909in81q1XvX+wfHiN61JXFECEqzYQEfv/HDFYFFItyUjz4zKqm7ovloZwWPTQH71LMd61qsNBMTe7JemSwyHp4larXRNCn7NMfu4U+NORlgAJjug7eX/XAHRQQxoCfDGwzf5gri3/qvYmu7pPq5YEDVaz+2trZMgC7pVtVTd2HRgFfPM2kY25Ll6SOc3Q2RIFUZaVzcL54q+Ozo4NM1XwLvi2osPGiWJUn9QSdlnqyZgbcO9yM4yiNIMijGdQ2zBUHF4UV6om7EWCKS5wS/J3xb8d+SONy9jOLvu2JoP60VwkMQN07ZQ5qqpMcd+CE4QRPn+dX0mvvNZkpVdfQfhPev1V0Z36wWachYYQ3eRmvw0y5MasO0b1iibPof8wcWiEbOXhB4XAP4S+B49q+gJmXzNGTQqCDxbw5WD66y/fHrPfyuT7YW7l8KdnE4Ps4t73zz+61KxOMOujxFj2aTTFe7gnp7kgABgVsD10CvwGqmAErcCqtHZWG+BT5s+IIwhUDu4iJAp4v4qLHTwU5tngUJrx4C5XWBI23qzM6zIhlfuU7P1CPqfrZ+QDVmmC4NoKNzL1OD2aSWC06s0Wn0fqZSMduphiyNC+okatppSEAPWk8qD+oix8EYiCJd+LNRAbStUos1rq14goRTgeVh4i0l4+RWmMVWQEJEhBtL4II0We6UBxmCHgYSS+LBCQU8pQbV3TwVaX+wVBsQ+CD091vUEfaANTl4fgzGu/c4rlFhh5y2Q07snSbzpu5QJgNLSolAGsz6U/0ZOhppppp0fLAwFMVBlmnVJFptBgpmVKGECEzg3aOPJmH1hIpGl91Lks8E+gcjD64gSTrluWWAARj6UXHhQnDNuB7keTt0mgXKCeVVsHBa0uFyMaKifSUUCyd020gBEpAb6cmV5IqOJ6xtw4G2jPFbVgdh94xis61hMVglUA7TV5Les9yNoiyN47XnFo5mqwv2Lglp5uzMELnNQ8kG3j/b3t+IjFV9cFIGsHsutjg6YbFMqPW13VdIxED5cwOv8Em0DAIUcRoon26OQP923iA49DobDctXYKxcR3AKUJsEnfYIiAn4NKPVZ25AZ2olE50nWtLWP/kn+rSQF84pbKtRCV+d0BLBrgJWuQ4Rh168LgfjctiRyqQ1nj+noGt/yUwhg5HkeEy4dwIc7Cvlm6ytQZ8L0D7/xRjz0whoJnHH5CH3tndWVoqNwmaLzQysMQvA+24yGzYD4ZwCbfT+thJ8klKI0fJlDw1RwxKDKWLUZCNoPssMf0o2Ws2PfiDG3cvgcILQ38kCGuiVAMWNZtfhAopddem+UJQj4OntsYGkIChGZlSC/o/UnkTV3yEDKDJBvAqAyZDcg7JPlmB3z/NuQx0bF3Ifcg98jZltCjGDAGpPw4QEwRwfgSJYvjatCyzG8y1NlMxL4o5HikxKOlh1VYlTzj9mnkl9RBc4ahQtI0wyMFXYJMc0Pge/jcwBPdRCLc+aJU3CWaqstAufCIeomrsJ1AFGY6/mwHPahHVh/xmfX2SZhV6gYEJhinHPjs/DwX2d77BhWFhvFvVr4jSuh3oin6ljQRfvjP+b/SlEj5odhpCCi4ehNhzBhLdLnKEP7BjR+Zhd/Y2SFIcV1rgKJwye1srRKZ5bHOxzNG2hgGxC+/0+P80WKyfY+qQZdbpRXue1R2KxSl2i00ZKA6kHU43MWiqyeAPwoAVbMwHnjk+CI3aPO5jrmHJGp++vAeWjEqU/aSkkip4n42UurvLMWqP+J+riFu6uxlpQlxxlpQGH9ZjptOKfaG0P9VeAyeGC+iqds18Q30QM2KhCXhHrokaLjPkmX8OKlSFU1D81hxS/d3AKcw3Ap0SgT6j9kX6AoW0VZCUSnE4w+jhJSm5m5EMFCP4V/I8RHzC0F+INjYCIVklYlSuUqNclnUOgtEmcoeWhwgldjKqhRP+plqNmICWyZufBov1/ZAsZQGuZP+nhwDvPJMeX8cwuo6oJfX6hV2FD9941s1rBQ6n7DAdI15y6+X74vQHtP5ytb3r8nJtZmaC5EcaBSLaANCXkwDKznaqFDKRwdl7b/Pu6So1X090akA1oTr0bEENqZmibeYBhvSUtw2gilHjQyl2Q/cuv6S4630xlYF8z9rkB+ZTDEvphEaVKZmMiwayg4SIHlhApIxEVX4q1ESoY0xg7pnKHauYTLwYkOFumLLuB/Iu8D5SIa+wZToNxJPGONdZEoLIv1xLjIJNo4K0wOHhjVjcmxHSsnOjO44yPwj5lpLOwJpINT8kWjT4WNwePOXADWeUepOyYP9ByhwoN7FZsU2vYcAGo3sJjEbT06dnVOKBwADocztZ50ekLFu25iQ5Ey6luygQRVUSxkZPZCg0hgd0l7xc+zFjiS+I5iWDIKxL7EIhwrcS5BLGgwiGJcPxj4e5h42pMjDLM8WQ5Te9YVf2TORuKL1oBck8gYY9kPWfPh55ynVii+ZI6T8vOnXgUQWJAINiPj1rkcDLdj7xI8xVSJI/NNdT6bR+QZO/q6sRMc7x+CifRr9ksSc57WoDOisla8Sm+VicLG9W/Wjn2SSQInxS52bIq7igDSTqCiS6g6VHv9GSh+Lb9KFgt3EbcE5lf6pSRWuDNsnzVFrsLoectCnXeOq4X3Wtd37AxxkO2o6QBGAhR09CkBMpESSRyN0OsDQBsIWCXWU5qDWewgqIxXQDp7q5uc6oYaeCF6zpjBCUZKGSLikTk1DZNb3f2khif0PTQCePvgV5Ap88EtMcUnEsBjxRbl4VX78/181nbbsAnR9pO7l1ns+4dY09vyk6xNJ8uOKcyT8X3j38KQ3OMgMhBqudT8NtadUCaoOwAiFAmttJC2uOHkMFtcGzl2JFqHtf7iaR6Ee1CBYFfz4TmjoWh1NwhNxWnKAdyozJ3DJvXD0O5jvA/UbJ7O2zR7j/Ma8zXWelB8Hxu9VnIEZ8K3Qp7FU0K03UoNmpzm2V9ewkctSvh8tvztZHP1WcN9gTxJMBBXiiieN5HX0qAX3WdJmM+Cg+LXLLHUMM9J4NZU0EKDQ5y3ZSXaKnUwHeVGVcW+O6GuWtgWa68FueXHPdCv1btld9de9DVs237UXFSFPu7C2uY2a5BZpyXzPt+HE/PDojq2sfzO5V6+zitZovjspcwG10LYGLRyDsUXeFKi3MbWuv1jnV1mTymNokNXj5kyegqNFKpKiAH2bwMAB+jQLxqlREBxqBU4rQuZO7Nw3IsBTeyICjSb2xEpzCKXOuH9doTUNshIBYRghJGAQprcbSgwtnlWe1jEiDCSUW7pbG/4lNn6P9a9b2B+ROjE61602C3dJuEmRBMAmafG96cuBzIpBn8bcs5OHfJulnFHMDqImCr8FPE019EJolMQNWebj+MZgdaooJdzqmaYUAxj8EVvi4gte1c/Pv0BmhKSZeipETqYs0wgMutcyaWGzQcNoCoU0I4zxFoTcm/dmQXdCSIOJGWzxZSV8PjSjyUnaC8qWLmSJG4Rrg5K/v3gz4kHcDkl5eHvGMDncEPfowxkgQqQT5mJ/PE27QqW1cQlV2Fg5L7h8VwqMyUIgZJS9nxfNewC06r/osk+IKyHWbu2QEc0ix2rrUW/m2ClM92zwr67lWnsuOEjI2RPNKgLrK9gIobDYqVy/rKxMn98GQTE/vv6tTo88CuGgHf0dlTVnXmwN+tijuS1roWz7DLDkRm3HOZxzM52Vc2nizruHB4UWrp0ZOwDgEu0h/skNdMNDwAx12D+iIWCajOMqiQYOwJNJhmAnBcO9wKkZQBWKPr+1bM5cOYHENjJ22vnLstPaVCU0g7lPud7tFppO5waQFjnIpfszDqTOuSTivW5XkerIsnjSvaGjIitzG892JwZ3cgO6i8c81IBKRWncjRQluGbU024NcCuNUqXf5gWbskkW28kBD971BIf2baAQbAJ5SjmXJqvLg48Ojg4gw8UbbsDOnfTgMw8rt8JmrjRpbeXyCoBWbe/7gBdPk243O1n1bNRaYwQ8y5GcMNYtBBL8FO/9T4Y7nXJebV/NIp4I+52EjYDu0B6l4gMPvKaq+LhSuMUdxE35PjcwYumtF0mKqNyHpjR4uglKPRtvex4WWLGMvJkqC6j48dwwjyWAxsGtiBLMEW3OOiWbKpZuVqTy27tLYK02PZluf9ZmJmDR3F2c4EjQVKwm75MPbusDCmQm3+JIN8OZqN238yGmXxqt2zvX+uMfHWQCSXNvSIMg2qnlU2htZUhlD6DuC4Q2cSGl6eOaT7Xj0cD2XdgHt5/7PGH4j8HFE73l/JZ9miWbCWm8//5Hnrd03uczmEBhI5O9/f27WdLYMMXGlvUbOToh11ztPEsX7zDLTQz7XO0H7+ygAm2xwzomNvZQQ5EgPXfbmD7+yZOfjR+UV8kWINsavhmQ1qMvbClbh57CRndTbytt/t+IlUM2cxsPPBrw83rbYUIveu0shyQDbG37gEOgv/NUZB7SrdcNOiIz/vTx4zP/i8+OqiKV01kK39MSzxiz/74i4ByvAwlB4LQM96HxCa2tJ2Z7P9y742U3IKkc3JyHDolnzESo9pSEqfOAbgMYPEq+sVD8goApBR5iZ0Th/0rQ+Qo1KhI9XzWQmhG6YnYJwBt4gtvZX35E/AbsTJHWAssmANx4d5Xlm8xN1Oxx+sLOq8sxlBgoPgvxUzDKB5+jKJV4nr8LCxaX6N7DpJ7h1MnITu+rLh5sas1ZDVppROoChQ5qt/Hm5sW1XXAypIkk2TCykwqBn9wWYXIGXau7W9ZVwu2scKr0o7Hg1a09J8+jVJBwFNn2OyucEj9xMXjT6WZezTSwCafUbTTd3eFgiFmVp+5FAU04C5BqkjAj2hYfuSG2C4WsQCHdQbNzcONmiGDe2twRmcbcVzlPOz2dvavXsFmBBFeBiDhmt7K2qiAKw8RoEJkh5f+V7NpApcnTYxo7Crs00VRPIx8i6V0gS52b1mne6MdttBzpvGZt72dkoMM6jByHgkDoBMIjj4Z5Zm6bsfOJfWOAbH5h/oqz8M54SQVoec3oIrBY+4qRfAJtZWIuFKTquOcAZby3OmKSTaKXOVvq9/ydsQP0nXBwpuSuAFupbqX/WLHUB0qjAyLZ+3pnbFJTSvtAMypOJ6nEElyeYDwlxg+CjU7fDVP6UuoPjczP6D1oOkVQVV5Z+nkepPSpr6Dn2/XtCE1msNbJSw3XyNsdqapYfZ4vy9VKgcB6xBXZTqQAivsJ54wxQJM7AF37VIPoUG9eU2rYQKui0A9zMaHShvtQ3m1TZUmfDPRoi3E988P9DmqjwV99YIg1NAMpHVJSLTe/Wp3dx6bajzhJ73ogv5IbLRDB9BhWRhYcRZGv3JYJDZyVSQNltW43IxhA11edZyGx7mm3fFdYxlR28lkgdRfM+5krv+JkWTUZ5bPzT+fMzUpr5pTK5PwapRXTeY/Q/8SPV/ZVrr4srVAreTIBbZdOrtKNiyEvvB+nDtkOfGm6zp+Exdfqoc5PI3k82P8i9VXhqm6V0XHMDRXVD1Ah/Mb+J/Q+qr2sjbqFvTq9ubph3Lt7qgpxw8wKPRi634f1obUcLKtmojKN87Bf50JkTFTaHJJ2EH8KDP4QlYHWc3o/YUPU2tlbLPjynfqo2tXMxdak1elHslskjmEkcQpRKbRlpdsnq9nTv7/MhttLe9VNOo/3b3u7XhvFYosW7f5zq/POMv8lTeLGL1RhroJoCYuw8DYXZ9a8hWwlH4OGW6WHB1+0PVKrgoZ/zAMjL0kFL2Y5n4izhSr5Iymmt8Hoqc7rZ5Tbob25k02c7b52ekb4PuEGv6xLK5bpQCqLkleLY+jqARs5k4LZN+LSBXssJ1usPp6RIEhIORUb9MdwA9xX2xpoOygT85EpSjkIBlFTl/s2P+cXPo33ihjerxjDfHR4Jy9fu9WQZ3ycya1spDKvpZ9wRLveYw1tFTzFMyzKYOogdg/v7Dwn2p84aI+Cb8g99hCqeTvo3k5PvDI8r3aTIiVXp5f2GUZS2+NBY9PU6nxTU9eotMgEhxlZ5PjA63QmoxikRzf41DSVFk9fSmmehDlHVWbTb2LGP5gRBTT2v0aEAWgSe9eh+SMaZ+eIsDF7NWdV6kqKoqajB7l4Lh0n2tqJx2RhXJktGpwVe7nNFq7aWJG1TAgEAoCjnrjAbas5Be8myuMRoPeFUhvpjc8pT9ux1lvqMb091AUsR3QeZNElBVzA+c2Zoe0ErjJlQqTQ+UDVo7aNIdIH54RtD+SgpjY4xpcJFo57Jnw+WDrUUAoNT7X8Djp9Jm+wCCHoDou0AJ5sjTncGxpshtfeEQhbL7SZeZUYT3ZfUkwSxHG5NAEGZQJNSIu7X9edFp8MoypP63hmS+WK7hMjD2JnK+QpKop9K+vNnWVoGNJrZuTNBOljPj9qj1Y84j0jAwuZYRjsGlpskyg+4DFbQrV0YIW0n9h7EQKucYF1FqjI1EKVDaBc7W2+mxopdX6QggduaFp11N2ek0uLImtCzfN/oyKGo//jLb4yZ3L4GDxsIkaklZNawo7uPizPiQqZunpon9N9BQ8QQPvVyQUXKYvSF1tNddo0b+2sz36gII1HakljwleeKESuApdIZvh7Si+vTlIynk9hJ7s91KqNTFaaaJ0VKsNAR+xkFJLMQ5bT6Og4rrNp19Rtrc4Z5ZnuWLbayzdZwJ3RqpXG7OEP0XJdTUCwHMrMr9TZuj87Xu3FjPJgeqT/nmijEZM/VnHS7W7Mi0rGvQZkNJmai+k8ExO7VnFuwyDpLqtamIdtiXxlmdIi00knRnaUtD9jbVKdV9qVOuKO0vItsodgR5wE7tz8lERgZXAWw4ov9LwsYee8h9Qmw8agNWL/K+9dQaXICLvqeQlUJTKKXFOE26e35d2oAKcDhynz4ZGb8v42CzZ/uEExKjPtyOsDfitDG/RLKcaN02KoyG44hg/K6hPthImDmpZAAZzA7XNE5hDKpFiuTK3pz1cD522bnaC0Kn6NytNzO+ZnpQ+teWCYWwNHq2dJiqlWqRrYJS1XXrIqt5FqlE6x+Bt+zVAU3EVz3x0CKA6XgN60oz/NTuA6QguEU3Y55pOune6iiINsj1Gz4QzZnMX3i8638sCvlpyAJ0+5HXPn3Fa2gqim7z1p9a+ZW4+0Ifgem+94lP5jLC7N40cdLHBONWWKfa6bZ3HekdhIQuHeHRT6JQIemMa06RoNKb5NFaTG+QGlulwI0bpIdEBKm51cFBvApVFkL+t/nzuqgUlo+RYkGoSHTUsr78N+AqJyqpmNXxsVe3se2z6nxjUclUGLz7N08URhKOXiPiNZvdCIsN6IwN3t6HJRJ+ZddcZcpfw/Z7+e39h4Hrk8m2TP4sU/mFaadJpUmf6wCjfLnsSv2m5a5Says0rHQ2uXrR1f1rhMkMiK1etjWQr7IUOFbi0rlq04yo5PWa6aqTazjz8akgzvmpraCRNlFN7VV/IcYHQ8hpybQwZ7TAG2Ixl+3fDNmzDYbgXoIz8g/7djLuZwfRqiLO0oBeS11RatK0gZqOYj3pSGODUmgrSi1aJ6LWkfcYWegD1dUihYG1U/9M1Eu2aoXt0+RDYlDx1cOLuD8pxQbt67d2ir1kS7bQgEl78wMcEeoq18l7AVIbWVnnVca3vErGhEMylma3fn9DTk5GmxtvIrL0xNwPGbLRlZtLpOKA9Rvm1beWMRHSEK5X3djyxaRguj26mb0dLLXJEPReflRTcW6mVQNG8JBH5+SvZ9+huFmm3nt7AG19t7utRN2IY4fRpeS9TQ5NeSVgS2Sw5u24qtofgtwBQxhfI7AGSGu0ya5pRvqOJO6Vr0SYyjA08AQnweopDQTgiFIreGtZIbvPciUZTrBT6Tg1QVlU+SzprOSknZzDMDVclSUo+BAVYtawBcowws1C4MULQUWar65YKUJaO+pKpYSspQi8gEK1WZeWzcgJ3KbiDum/RjsXExCAnc/oB3Vz2+dGyQSLTmhSimzavNZ8w+U/NpJvnUz0MjxGriyFCoJXESmpr6Bn6cXTi3czvP2gY9Y7aU7HSMMG82T6CJ+p2hntwb2gu6O6FQVE7uxEOIQlG6krcdJiMax/rGjPkBYYHUR1ogWI0ELQfeRMrbI7ZH3tq9cdp7I+NxXzF38d8yua+lHxImOFyKSdXGHDduBuJKZ9I33JkzFTUS+zrRkvUI4CcYEx2PINpqHmbcITGzy5LydrcNh7vf0A6Fqnw7TDriOnAwI0zl08HoiLo1iIPrQtW+3ubxHXgAMxapvNNMkVcaU1fGYlpJrZjyzMRAKE56nXz8UJFbNEWaVjzwb0A3ogW6zFf9lDFK/6tMnQAdj+HrRrp9Y4A2H4px48gHHwGalhZPywPR/23ljHG2/hcN8mi5N+xjIa0WisV9wLl92/uniwcz6wQLHSnPop5/PfL9h0dCl3o/4hOzJ0S/cSfgOwW/eRPm87yDgEy3ok2CSZoVvQbeFOcJ9Ez8BokYI3sUQ5wftgOTY+yLdwEQrbkXghK6Z/v0NLxz2N0oJTdgET2+2xBd8ERggt0bTmk4InjUOaz18UAKfwlZE0ted4017LEMrPAsHdak/Gvs8IiCFa/aI9fsVpC/xq9KDGm32aTlHzUyulU10Ya+FiluOS/W3SGWHi8JTqOksPhinGVyjPix7ZfMPZurc/7FQw3AqFb4Hi4cknrFrQUJyE1PLh+EFSWa0J26dHDVJkTYwCtBdFyd2AWUV8iq3WPMAUT0n8ZHLRzmjsDbGH4EwiUgBMOur7HP1RwWbissVHdfhbQalHLsyROWd335Ku3tieMbeP9JPjXBXSjpkWfLGYbg8Z863zQvz0t42OaF5h8fsJ3Xa5eX/x1p4VyAaFuL0CLy167NjwCirc2tq0VkyWXnWKggH8SB2IKCWCgOyi+Aeq7z80F6U23VGibHqqu2vM2q7UBnN7Zrz1aCVq+7rDjMNSVLEIN4mjWNhDpEopOPCt8OIBCDsnpWY2DxZgKV+A0Pg8gF2PIbgSaelQc2deICBqUw/B5BY73jAfgVfNahIrC5I5wACO+IRuJ17IdI30y793zAgcDJWdwx+DurjzcPH8Mt9Iv6F3C74Xme08Xao5PYBuT0EespGu+ILes7vBvHGqH0k481ZXiIktxFpTriArGPCIi6Uve33iaCEbkj1EuljZIELAFJ6UoCTEByVRFLgYgqG8/cEhD5EfJqC4ipX5xBQ4sFzaI1Qs7PXBqfMmqawFQAC4V/79qf4ANJfy7vUwEfiZNhUQD2MglqWGSFutx2g0Oiujy/qOAYFrlgbmCfN+oipCXQpk2IEkTpps4Sgg7HUClUsmlTySLfFB9Ber4gLYXvmwiVlEDBJuDFKkLH7EkgK9va2p7USHXxrCXRxqSTk1UmN5LiyliDgSxIk42ZkrQB/LLaALWUFxmWLQmKc91K+G7+nZAe+MXgc8MXscC4wg9X872rodycVD2bzmWlrGIWRh6kYMmnu+OVzH2XZ6nVdH+2rWoSCspWRf27hMuF3IL9924hMBuatFXb+0MF1IpPDE4ERuxbnn+w1aOkxDt2UF/mixVHFJnuAksLwhLzF6WwN8B+gE8P8VqPkeru6wSYDoxAl81qHcDwz0AdcDfvPq8bvoBU4TxDkL2QXl02supoUTG+CeF/YivwHb346D83uAqUtjO616w3jB2GKSrChNmHkalolBpV4c434vytEq0TnXRQgwWlHLe3g4sTm0udKH5RGyt2JWzCUcotCtv0+BmTGXxnbkWx+l552nS6Qz/28zVilb5jOtEb0rWfgZvuP+5/wJLtyrYE/3PxwMqey8bzu4ZtdyQOjDxb7XUY/2cGP/1IrpFiEeJ4fQztH+j00f5R9qNd+xAKOR0pED7Jp/pvBLW+3pU+agU0TFFPDoPYiGxXb9/lFkLo7tLVEidvt3CH/WB4Uk3+u0AUbUjpDRUGggFKOKsLWFX7iJAPHKPDLcug4bvJNgNAI7YBPn84pYmY222rBtQkm3kRzKim86G0mhXpEPcBDpyW/KPox2bTdERNDZTeQUBZA0qD0mtq0kNdpc4uEfGGKtP1k0ppBwlj/DbyY0rrLnj/l83lWUb0eecL+Ci4g9o7HbZ93uVvl6fB9dp/XO4Ghx5/yoi643QHFw1bUTumPXcA/6x9mKi7V0Ji7r7XOanZWNIHkw4EI/q289a0Z1cWx0zNu/zjfDeE/IVnSLkB7wD4T5iVHXZ0kqDB5umEBhVWQ5zdkx4WWSMJDA6UkWgkIcme7ATbJVv9Tra3opFnSfZjwrl9fJZMs4KjWYzqTegYzYpGEkRHdlmyDd0x8svYxfTBtkVG8snvk5NClpCBC8sDAlGtJWQBb6qYzZJI6ClF+hCLptDvrrMWPFKoM6Z/z6aY8o3G/Z9qDAenv/LCI1qv+eq1CUmY9N4Hpo9704Aws+MjPDWUaUe2sYbwrIzeu+bfqclgPwZ2icXmAN/nU8CQPzNkyM4wg03HzhgcO35kHWB67NnB3NYb3ukrh2oEFwypgcNBNT4B8mvxl2i1LrXUiyxqq7lMkS78IJRKhD9QpWCALCQXpHYwG5x+M/fPqtj14GGPlcCqn0YrpYdG639ne95011bQSAenMEQfy27Ft0m3pQ+zKz+/zbItFq0LbO2cOkB4iqhorwz7l2NAhqneL7KfXt4iBR77DjNMb/KShSPciUN/TPnc7f8bAiGfK3+wqA2vFWdWPIOLgQdanhHdt4ZXL3wcYeXbHa7xwVna4DF12E5vN4KWqsPXhLzE9dv6+2FCooAkCLfISW7bXyaXoxMw2mGR93EHvC86GNL1K26aJSBHzfqZn4GwmI7tpvRT+ynd3BujyP+/IM8hR798GQX2vwcA4Zh3kohgzGSISrpJog6ZjAFinxvmkCa8LMVQFlNGoo4xxsK/Qj6GVkx0a/Rozq0Rf0k5VywN+yomsx/7iqXu0qZAyUQJwsqq8sqS5wN82e66j5jfMR95RovfLYwjQMd4XryhCGxltNJ96jBGLyOmLrkuzUmdD7UFsbV5ykPsd1rmJYP9dM/STHbaz0NcI0uL/BwZU2bxQ98tyMyL10FIzf0s8JfQWhrgLKFvqxC++bFxLRSu6SMzVPZRs3xZ5pwsnCUxJfrKqv/nAClIT4ekmBmvGYyfS3ZMTJaLpqPArUbGzgRmjCAU5wniDuIJC8WaZ+XzdrIbzh3OPFhUr1B8cgfulIQEociuLyyIvtkFvKgHRShKSKC0vgD+px7+Y0vY4ffa99Vmm92IjPM80S7UBZsjdWSUX7GNjZuihllpDPKZp9L1UDxRWv27OigIcXScpqXRHXXceOkAkd1YBvO46In1W0k/XvqRtPXmOvD49xGWnjVSXz/I1rKHt012e4qgHi9hOfWuwZltLoCTxmi57VUFRIiRp4VNuHrfXIfwno3x8WnWc/Kpkvh40HshGqUT9gYpto4YuoFx74Je+KO1y1rQU15SQkwXC7gHpqnSfYryoqhd2DTCSnt/LkvN4/qziKtQysa2LepgZ0dut96aHevKAd60x9fSoRitNkbxgWdmTDqioru7AixCEYzpGja62EnqxPZfshjNng5ldDMW56WbdLEWs7pMTHdb+UrmcN9GMXWR8SdtKGYXU38mvMbuHK4FFgzUkx6LPTzTPWgdj3RPEFK+2VGqeKiQOg5AH/q2AX+M5QVpg9RY/cQR3ARO8fSNULCypgPJwgJRXLJZQeOhAvOCMcgXA/wuLTwsKsQMjhG4W6aF14m5njUcLDDNF8flm+WvO5ZiOoH/8NB+l2nWsvwZ/d+mpjZqwIJtk6HKSijY5A6wHTeBj0BvK+Hk/JB8oGEG6t0175Q4pXpADYT4iQHVVcOolINMDRQByTMz5RBRQvDWIjI1eut/HzCoDL+7p29ilNd5lZJKDlQeUDRyaheWIOpqoSUU6uocFuqEN1+7RG2ArycsCd0bumQ8oeFP8z0LTHMgEgHfhTlzYQ8IhOyqZ6tBHq2Dpn2xFXApnU1ivuv19jgJ7OftldQlte5RHqSjeWsnqWAbISE/o9Yt2p20h6Y16ChtnenQbwLZL0lyzsK58qS/FOfLGErAoJTkeDtsQEdn7xzFv8yzVggVYNmdUoLQB8yekhOIvqMfvTs0kP8FzAOPpfGfuM64fLfnz7kOz+c57I8ucy7z3pzvhicuH+1Wh2SGeZSa6ZRKnWmpe1hmCJRYXLz8tXAACbdfuNCOIEo0W0cOCMGyAFoTobXGuoFkXecuMhcyQ5aTJZ70aZlsmu4paHu8EjJF5nXu1iTrhprWJgLN+Pw5W2Qlw03gSTitBSY/I/zS9QckIQYI1/R4zx/juBkRvI/H+FZGzHYtjoSfwMmsROyBQY0GPF+L2pd6NIOwxj0JM+kqCveuR7QpQQS/MSe/wT8CWO/b0xiw3Pmagc3Yh6/5BSG7FNzkHLjcOSNX7BjdEBuNm8GZG27i4iBNZu8CbGZ1qcmZ4gDnpqCcDBffIClu5m5rJMsr/HNOVLMg+XVcyC9NmIDlLvVFLtgbOHPcCJZy5/LHLNLSYw6YO6NntgUh/ZPgJGWxLgkZBy3NQ8fipjU6fhPnECkWisWRyPRYdbWcqTtjpoJhEghOqKoxucm7xBsxIeBm8J/xMziC6TDv0tg0q7FRSqOi5hhBjLmylSoB5l5oyG2EfBPHZMTEwZ/ibJIjbr+HHDSZgk3NOKefjfTm+N6BXry5NMK7aYKhAd703FbzlTrisXJjlmneyupq2lzFt9nUxcp48oGKzdW/9NIOtha3prmSzT2KPVDf+lYjKUX1dpgutiH0/efLTWRz8eOZk4HxwaBqNc1UIYrbO4ohorRCFKt4RljNoXGAD+ww7AGgBkoVV839zQEdL6lUlb0qvKXJ7GVOSZL9kclIxGylmcSseRJGJgdK93e3oaqvF7KAfWr1DZMa4D+FqLhMMz7VRLLf5JRQwjs1fpJ9jl4OUf6S/Wdp1hIbWr9+uYhuPwnq/z1M5AGVjAOHjvh8Qg0aGV8/RiNupYlE1KXUsKFtJdLGWD1h3QskGmlLikhbCnSLdLQL3WE9SyOhIPn7GtS8YqliHlXzPkie273YbKnZBwj4id9s9LPKe7MTA6Aeb0YaADU0BX57HsbxK43KZsF6iyqNt/M4twFnOSQSU6liMSTHPk6Pd02Rtha6VaFbrXxuijD9MVbuWDAX1vK4q9LQ0eSsWDTZGtI6uYh6a4dhCF9xJmyJbfR7V7nzQG8/3O3cDcsR9M0RzRGCFUA00vXUA1S9QxWkqrx/uPJ3cx6yMGL66XqHfOgq5fvsEroe6rcwWvSDKgc9uPrpO+UqlG+zrV9nNO+HFOwXrtL0DvpHeLqe3o826g7Rv5L0KwtqmUAA+ZhehbQLQuYrao9O8Yj6iiQ8wO4zJVeTTfdDlD7hm+Evy37gWe64hLr6eVfu+qwa+0tzL4VXOFey2wBndhIoxFW+uUNGAxO+E3NriRQmhVSbS5SR64Zy+fVD8+GfndiWnVuNBpqWmJjomBYLqkWrRtM2ZMRw8zF4bg55/AIuc9wWGBuEYQP8Y5y1yzhJ/huLHzC5T+3+hOJF67n5rr/EqZTKjsHG7szkbRrNiAEzHBkdE9OiAejqrKzWcnHZ9et984gfCUgChZBXSwRMQKifAY8kGIm5glUhQAPg86lSM8smJ5LZFA2ZaTOz5jBtGLKvzAlt0bRDvDlMN8bb6+Dx8i9ohZ9IgcZX1AY3gCDDuhzLeLS/CK0gZB8/aBhtITVhH4UhtPixHoIQICKPWD7k/12ZAC3nfvX57j9UTlzuDwTlmwqytv1KxtRKMV0acpayIDuKlqJpxQCfzmLlpD05GsteSaaTokk0szRMF8Ye04rhalB7faeuzBerPm3+go7zFcah8TlrA1cFrVqRg3+s/YTouC99n0qfT7JJzfWgW43TzST6uw3Qnv/yr+W9ft+k2aCc+54LEpXf/IayiXn+gK9bcqJD7S3TnBKofUkLBtP8saKfSeNe559NPTvvNU66Wmy5n74d0XMACBAtRYV7ny5Hi5duA3lsLe2nhXnKT7Q8dh5tjKaVf1CmyPOfhJ/myULK/MIUTc1WgSkyjSwk0SaFkzQSIEgo0w7DDk+MqZ2cGx2dR/7HmCacBhxn1qHHtDZweDh69ybk2f1vuJIDYmGMXLA41SIt8dmrcRIhGgq3jghPbf9X+e7dTUwnbRURkapRdPfaTXpKGhYr901PwwBjo5DA9+P7+7fFDbuC1otjtnkDeXYka6VSLIyQeqtSzVPD7j0YJRLCIZGlo3mV/hLpqTKJTLLeslUu9clShY8fX8C4XjGx0qry8gl2N3s0MytK7u93bfwmp5UDWLD7CeTCR+RJ5ImFhRMwu7KwgDwBVGE91dU9QpWxABzSuWics5yvRkZHyX92znLKdNUdBIWIjrEL1C/0aghAegc9nVVNFwAz7IHzMZEnFz6eQOLrv3TAY2OIDmOhA+bMhbZlPrUaTZ2PwIy8RacxszPN8v+VMpS4faM0RHKh94m+1BL1HBgDhiIkH8I5loZpudEoTIF3VH0p98ck2Kjmg+3tYmvqfecsU5Zplm7r99WxJASYV1ifcpSiTqH4ilMavtMpZ59pyqnL+hr1lMbH+ZQTX3NKwc9JSB9RU1785CmFD/oUUiqcS+qod6azj14oRZ5C+zwGMxAULiTxuEJMIyZMw/al4GOahVnNIc3ZVU9Bs/w/vcwVDEVa0RTNIofNwvroFPy+MF3H5K3jpbx0YLzn5kbXO7TQ3YAbvcVBT18zFPIINEBFIAEkBFAAPbdvkgJMFQ8G1ANQNU0J6HoIqAGkH+3nEvYFmQftM98bbB68t952EKBHBweqXQ0CPx3D/Nb088S6G9Zr/rpRMcxqR6xOWI7UpjKdft7drbG6ubbQwulXzG9fYVfEP1D3f7f3XQ9mgoC9RyZ+Ls9EGm58Zb/W5AMni0Ic5ZoTMzWsdMLq5uuP/93+7/rOLtou4HN4Y122tIEid24irpySjkxDLqbMsQWGIvd+mu0O52RIN8ktvpf9km2Az3G7rCQct8i9h07Sh+pJE9AsvafI3SBgz3nVotJQtXmHU2xSzMEZd+PpBF2ALgFVKrPLybWbA+Gu7DnbuiWNrLMtT0QChTPLFDeXAZg9972k02Mu4fIMlzpUuEtY9Qi41KHGXsKpOi4Z8nCXMHrSi35El4hziVqkw8wxCPg8NidEb0Y97CDODM793cd8QzR1NyWW6b8ulisGZ4gdqIdvXKft9jniFHEOBF9sY77ZLETPyZCKnUrrnlhPWT9Zt8LS9Q2COLcdgm+tgyA63sJ8wHb41CmRaZjeJeAGdfTWrT//FKCCsD3Y4xjpx8tbt4cp9HNfnTdi5adPD9h+PTDol/p699eOzvT8jz5UKOf48d9+A189CJtf13DxTjZktli7G4dPtiZXe12EHcvepi+2XJxe8QbheJGXn9w2fNLd6L5NQ3zSu2UwjXXBn9Ky+ryVcrOqX6J9OYq2wwA/u9GBtH3gqycas2Y58Ow36UsslzAOFxYktzIerQMWLG6Fb/U6NppxwrFALE8RAjKf/Jk0dcxpyZ7SPISi/H5xXnJpivSZzKf07ktmR+0KutikRsHC24lQ2ZEI1K4xKHFGNnTgRPff61yds33/tpeaYznhZpzm23uB/544JpTs0875JGYuUy+anU1elClhfuJ4twM1a+JNkXLUz92CWbSrvhxUAPlfb4si2C7x9x9KLAsW2QRGV0XGYMesGZ2WnQz6qiDU0Tcf9clWqrZsDYBWIrbtgBoo1rLEQj42NmK84EbutXjbXwAE+Asmq1hdzt2MVYxu566OdNQo9Y+87u61kKy7rm6bGJzs7laH0UdN56df1tXWpqXU1AQHGr+drfj+vZVgqAVGoSei20nT3qnL/Y6HgvV9xmHQYXrz0s3TzKOZ7wqW+/MksC1sxwzyhvDWk+XeTVXet6dZYyXdgd2HtwlzvS4eW7AXO8fuoT0+0DXwHhOOg0h7t4swRaVaVtrdNeMw4jDz5ODBcNnAwC2nAadpD2Sq+ln6yoIsVmRkmz0+Qps14bgd5g9FRFIszd8r1ezlBGtySX9k2+AWYRLALF0qZ9ZFfUmuRKrF3ORAJSsqMlDby8sdZ0D9PbDGEelg7ZOkqQzCMsN8Hn96bXyX6ma2bA5tZjBDzy0zm3RbGqMaeyrrVZMOpE2cScM01oCdNrxZ4yOUstdvOX4MINgbNXrvFkOlWDaPNh2kyjvavWEDVe+gp9Jy2vdCT9Cm/y5MWbN7ABiLs7DaRG1SXmLecVeyXEQVEHhRFmCg+lANzvsBWLDbzmX1if87EFs5OhYQnpD61DnJ4HpQB0Jhv/xHOeXnj5pwn0D5+5lNu8+YSe+KGfdpdEml2gGiIoXsKO2mtVmCyTrtrspuW/5R+Z8/rLIyUYmsxq1EKhMrPh6YZveAQob9HJ7JGFV8OWN7JuRRRre2783laqH1tbPUjDMZatNr1kK1iWWa8839FvvRVfCSa4YpK8OYQUmlpUkQ9a8XBeGBRtkCw1ViJysslLEc93pTlMbAvOVx8VRE4rJi22+z82TUJ7H4E6r/hyz5qvup6dvdRc67dzkWH/x2a6n7VWt7fyo8RVtvMKQHIT118MUbEJywb/JQhcMvYgx/Ch63vtWDN1XLA1KgaF+m8j37nYUy0i/F0FPnfzyrm3EKlepW0Tp7Lb81Bf6xf15ZPP7X+MkW0qvuzfzI/gzypNuH1maz6XbMhJ3a0CvLLYDF8iujxat267qYt5ld6+wiOIg1utu6NQ4EP22o7w8wgH/wlRw/woqbFD5lt/O2NItc6G06zL2t3D4Q9opLnHPRaMFPt2xvs1i3rY/cFmDQlcPJJLY1m/yWDBqSfY5wxO3HAXcCBOls+/rKXavFcN/jR32wCI8eBYG+R4+diatdnfv6ZlwmXHidexAr+vpWIGoRjSI8BFoLCIsA1NMubBpG6ZkB3c+KKTNr5dKKzzvmOkrKxIPmm+2Bv8LcxvlwL8cLcRz++BF5Anlc6HFAuBw+Dp9w0zMd0JudN5+b+eleaFK57qvsK8+/x28bhYPQ1i5sD5ykdovtMehiMU4J/CNJAsDOfZ473HxQ7CFSU6rfSoOz/rFa5pFpgROJfM6T7YhCsFAoZFCXhocGicbSWEvMavxyDhx1DHDvcaQKCgSo+vCCLH5EiUkaDXmcgXCcRTEEpU9UapIsNjmDFflQIirV+IhEqRssUEZpcMuDrMV4FTNhiWsiiMXUmCcRoW1DFK94W7UgJbS/MfEqmnPIh1/Lio0V3LZqkOBouwWN3Fgg2CG4M4p2j963lx3PdGZHyUEExiQfeCZ5tCrcXzhmbWVsa1y9c3VTV5NOs7QgJQaw4EXn4C9XVphzEAwguUdwxblIYh5Rsljib/FECKKWeDKPQSQlLh2EHn33g5WVSaIOefSon0KJJpZW+1b9OvpeHGRWZ/tPOw7/d+ezMvYwLYrVSEiHkiSICATtpstrQQRKgxD+0YpVQbGIKiqLfklgUhYFNQKeG97qw/2RjaAijwVpYK+0ulq2Lw3UVV3LCSGW244tAbuk0wlJYc9tq107Xx3bgWDUMHkVhYJkACBX5IEIX6sjK3giqgq9m9i0Ad3EQIL/ikqiMdX0NtMtOYxlKBQGi+SbVVY0xm1JPimkmZjBVjvK8+39vmIQEkLvJlqY4Q7G3tfXwZUORE17Gc1VUCXnkF+/TgLp/NfJwXxlzt+RX78qLn07daanjbSqabVpWfOmpxQW9s/zv8fFpaR+W5+5dqBt7HXzGmEpWDXJOmhLgXXC0e+x8clpk0s2GtRbY1Zm+NZn/5TCwf554WNs90XXZawbaJ18cAcvWwkmLaXmzqPfYuNT0sb4tlQHsNl9kSs9A1XPippcSTkeL1Bn2ER/CHRdlEGvR0XZrbx7nCKIz1BH2wR+0Hk1dlF3L2WtnMT7X8p55LdvI8KeTwj6+A3tEZGrOboFj+ITYFcFFakgKJBUhStM4KPwW4Y0OSd97w7vPY4x3YUgyOBwZfpZO8+S0mGZExbeZYo+sXf4ki9Yv6gGlcL9Od3te8lZOxO7RO6sIZ69jr69eaCbTeJSTCjXS74HR//MRaXUuF33xyP+RVKLkRVt26oRekQ/VVAVxVTkvwi8/3XwdENna7A2YdVSILOm5njt8QUVB4TJaqPMEIzSza7cBM6iHu2GUumi4MSActweJS4KGb2xvIxYjt2TRJbkhvLUiEm9wwSYerW4dOqMkhkWTlXfAKFnzqwPBW7mK9bYJe+5f+xyivslMDUesTgUBPfpo4I2jOh/Kc5zb9c4pWR3FHs0STySSzYNFXs1JCxe1BDVLl0Iqfsf21ZBrym4evbflJ7x//KvAeFeh6gton2prl60Ufj//5GjRAlBP5L/oPxxBSrqS0cm4n0ynggX1XheH/Gv5kKQIA6FxbrkZT34YgqJdleWqoGr70I45433roakHZ/X5bq8Nl1lsAOuFrIG7q4Lz56/2oMX9HZeT7YUymmpjzeiQSKuIMlPWxWahE7C5if5h08gCEeAabz9YIm1kB0RZVe9zg50mWz6uzGP3g8iofjA7M2OsdPBK+QJYHR+XWBUn8aFudhf0JtZ4+sJDNiEgL+n6i+JkIl0koiUFf4jL/WvGL77Qgqh1iSaOWOR+NSUvzNvpy/Lb42ag31rbGalZogm6/ufelcvP7YY4+uEWLmfaig44Xsib9HcucigNxO6IwlHSq6sfTn2uzHz848W6W89IxHO75bZuARsikpPMmugZUEyWt3Kv4BXIvrbjTs/Lt73nfZb4hmbs4m/2fuX8LrNeOJZKgDz6uPOhinde7f3vC9uX8Ld1/m7pKgESSnJ3udnkUIXR9drarbfpQzzolPQ6cOFi4hCwXTYUupSR4nFQOeQl4ansdBoGP+favRy1f52iJfGigLRKKxO7hxNp6alOOMAQBRXW1TzGD635ol0qM/c2Uyfcci9ABVnGhnV8cyvPGsdldgCQtjbTKvGNu/O/LBdaqNr7dQxKA7Fr0BfypUq2/g8t/jUu0oEJEnI/pbHpCOc02UXX1a6iMwSft24gX4oGHEEMRizUAOjbNTuoUFeIts0Ak0AaU6ILGO9UdsGdzeDnpE84EAyuEV4iGvjVFg1MtcBRqj4dlSW0EIILkEL9iJns/s6iGGfkcjrhMAdkOxJDrMMs/po+bEzkGS0JEj7YSov7p5mzTNVS+KdzaQ/ecV6QUpDiQZSgVWp1PBeQiJUrIVimdoOmQL3lElNgoqXQBFQeHFGEhQHLctAhKPdJOqTuFv0WzjSN/q3tbgZ+sxcnDn6HBh0oX4yzz25shZqhc5sh6uAWFLyiJVdFni/0IY628FBlPR0+KdTlU4qp6tO9+4qGClccSLaASScs3u1bqPQoZ7ViBxEbk+zHqHDrknhmStMFmWWZJI4TPYYNZGZtIfIZ/oMscgpAsR/+Yh8Yj4pKiYhBJ595/cOltWtJ/VlQfNyHcFsPbLahGbbEH7C9kQg+iSDyIs8a3s2/AcIit61li094fOjpMrUUQmyN/BkY9+34X8CUwEu5Iemjrb7Xw7zi7eetU+MKa0kMc23yO1WR8LpYL2nV7rzavi3JAQHUVtV+47zLukaZwuSwSez4jiP449a32nSlV7O2mF3XyNVr2kQsTtle2OGyq6H/U8vb5qEj+aQG/8stRvxCHfqAIWKk3YIaKe7NSJtC6w+joEZSd/5MdbmUSZxJfst9oWn3E+AyiE59qDtXcSFFEby+8CgtHgRC1++J9rx5Acr2ckdJ2k3Wisb6/Ci37QVYsuo8qiOColn9OLQEvO3v4KccbYrs5JJTJYeQb79Cz5LlLOOIPm3nWISQO4NikVREVlAmZ/7Wvd99UUk9eSfB3R7nAoQtV1pJBwQeZT+fOIu8uPZw4/a7RuOIDZmeSES4RoV1ISY6ol79I5TcB5EDXmSPb2QXkD/8IY9UZ5Q8lKwBLXl3qSfi5nFP1tehfhVnvHMulrCLLlqCQRwGm+Zv9lFM88YT0+0J+H/8KgHCB5oi8QJRr9PQSl3oTFF9B8+JmtPSoWZaJ0pppQjO8MuFW+0F8dUfVG+X2DgcfmdJZqbMy9MifT5x+J3jqb3HLPZG8T2Sw/ay0obnUa2SHf1ZhFi/lOJvqbkoY6E91IVsz/t7EXysSPDMRF96F9x8dlSojRN6tPJ2KmRchR2D9FFcBrYyWKJpe+RTEK0WUxNSXlClCOr0PQH7xfp0cR/GL+yRGgSWo8qRuej8S72kgdKCwWxjpXIYJeaRSZGH5hVKslk52ZZoa1qQGVzr5fv9+MN8Bv7JybmAljWuqeU/qCSk5HgvYw0HhPzpPofJ9N2ClKqSZYCQfkvLKSU0m7q9E+1Q1XYPxD0TxhloFBJb0WMu3NiRUEJzJOxJE05iB9DVLPxfqhAs0dHvlv1cm4WosQxJzkuYTDcSuMaZTcxiNhRokgAnd6/QHxIY+oX8PCPfK+dfv415j6ThHxFwkVY+T0RYRUfv9ZCjIi0ER4alNlo2ONV8YnTjgMOt+MTpEucQDA998QaXQRTG19GS2e1LL/xAuum4huoPaSY9M3czdZPuWlRVE9rvJSoDtIG5QWpcNZShu1nh8+2js52xk8Na6AufoWVU2GzlzvoSnjauw+xDFHbaMvRcziDds6HTGcSDjl/Gl7kanHNjZkMbx2VGib0j5PNunZNBpWW6yP8xwr20fba2gJ8MjAJ/pZpjulJblmMYDlE0fZuKwbbCosLeznaXgozJqazU8/E4Y4UOD6Z0R/J7+t5SUa0BRcJZ3e/upw2WdpNN6eaMroBC44YQwKAHKMAQLAdl6YY523STj2W73wv4UQR6fk7U2f6t35Gn5mFbXXuMiHHJz94kRl+68eQPIxcIsOzB56YgHuIGgSENxnp16zVNvvJ61jbJmpYJl3OrdisTH3rDl5XBBR0GN/OUE3tdnVUyB9nkKCA0yJ9F1mYAKdf7EVM3GK7k8Clt+Bu+aQnbEidEbLcVzO6ES+wge6D+v6x4U0ZfBaZeZv/QHK+ZMOk+9071AuSV4LbSFmvbjndGhi4IIYqMe00IJFLYhjAnq10HZjd6mcQNAiwWbm5Wdi+xuC3ZRZaN/JXx2g10KTNL5PbX8orLR3hOVPr758I8dz0vH9S8alpk2mBxvqJLdUh1b85wFivhioqoDalrihXI4iScLMKdX4FU0vMyxfkqxlTC5T1UESGJhxSLzIyIXkWVUl2XEL1g9KAjOKYSVZSNz8BH2dnPwJ8OCfAx1btDlB9DTVQxDyNpPBV9pmdnpv8m4N8aj2dSkOQh8DsrE/OIg/xlEJn5P3IN4Eh9Hlf8jvQ1QRHNQX2we8KrAJ3w5Mn4DVAObgb5ieRERhr7jIkqrJzb3VrDCgP8qogcLRY5K6Fu1euEneRu6DwUVT/gVP8oqVSUrvP0o/yYKf1hgcU9IzHzBMz33N6g/XOB7bxXGBE74enp+H9RArBdvxqSBaNwjfdA9ceSFfWqUhqyDrAosLIE0bzwHsukrvf2t4xIQNjlEHYOLf3GcM8kBprtVgY8tTCBHPBHVmYtehnAO7J33feME/ObjwTcI1VSTtOXc649mxAh6KhaSgd/8NMeN/58H1PqlWh7QfkhdUKhdZNW9VAq59nJ2ayE+YZ5UPG5ieGLwgvWfqMeA4hnaXAS0D64/VP4Az46fXzlgeU7TqKhdqCottOebCVPOqpW+VZNtKiAeatAsf0AjUVtJpB5g3LJFL5T1cEVW6LOTDXT4T1HIYwoeeegoCpI7VBkf2qPHAMfv8BeRQ+9uHDMWQbdHer5wp0YlOWU8bOjIzf/l////XMOX5k/ZGdSq9LLf32cW7svA9T+BOXp0SCE6gm4F/e2WmvCSQQ5NZyoL2mU2hEvoKNwnmhEX6FNFoFYbDzWMwrjO6aaxVRPuyaDlMf1LiLNB5Z2eirRXJvN57Q1dvbRcB3g+DsSlFstJYbGA+kLv89evRfthYPArXc2Gi3vEC/ZDsgiEtNjJEtT0rcvdxk+e7E0VqMLDVREAfskv0CJxDV0Wbm/VBSWakS6l0SuHu3x3uV0PZZCCWZ90ebIavAH2bMXkdOzZJpZJJJop07gMHoTMNDa3QadN4ANT1IXujcQbSmqyvO06ALoZQn6UAQHWthcWvo7NPiQOANuxe6/ecfAnTgq9Id18inBm0n9xXdUL795Rgthsa0i0NafFtKW3JrSiswfnqYUE8k+7eh+vHlIP+gy3kiF4gZgYO0cGO05V42OR470YmIIkWS4IYJC3I8fVOMZSNDTcNbhEMu3svvRflF3lO3sQhnQmqTxhjLTWxSvMVTZnh0OKJzwmKxYO+Ntmw0UUM45muuqI0rgxYvBjKiHJNB4dwpCBLd2d7/vtpd7HwwGahBQ45V3M/J1+IxtSFbDWmATFi3snlTcEoDmGj0K/JIve+R4lc80dAApXT6Zz0U7wM5niBwyuuzmdoJ5I17HYvfil4Ydd6xZ3nhzUhRXa9X8n1eBxCiGq4Q6kR9S7ALa8C9tZ4rp5XL4TDiOvV6s2bvu6YW4Usq/mqQtad6bkJGF2VEgyhQnIGMdlXellqw3XLdbSiSnqACDfhfC4pygv3jl2EUWU7Z5Sr7BjVobYSb4qweBco5Gon2Edl+uuRelEViS/o8033sVxTFaAixLLHccd1OqwiXLBkHFNbbJSV9+iQRO3bv8M78j+gBb+NKxvnP66z3dCTnu+9NPRDBcagFYrj/zse9VmVP4oirI65UldJPJy/pjCuzDswGx5KE8a13LSMb4gELFpw/3/cdDm3ue9rs9YcQG5eF9o5j/bW85meBIv2yrKmrgJFRDmKj/71FEvuNyV1kNvU2XVJOhx9JeAsbDWIzywsYtFCrMnRgR4vXgafQFuT5L1/AyRzW4n88VodlNFMxE7emj6Z2OLICvlTCXkeiYzayPYU1TFlldFSvwwoJpxiNCIct47/ulqY02wkDi0zUzdpERBa3hIkxvVNuT4x8WddxnDnpehx5w3tZnHe4k8OiIbgaQvRaZpXvFbY+clAu/9BQ3fChHMiBd6L9N5ks1x/I/d9X8arei10Oeumu5szXAZYBjmnA2Ppgyw0beON8QuQX1A2FhYIcJrCQCau9rECHlbWJVdak66SjBvE8M+4zOvhb8GHRx7ErBLXb4QvnkO2003ivoRu2N8ZwXndNZPuFc+0fXp1+j61FFLe3FweL6Ag67IrTHxaRG2uwFKdPWQHFVtWvtrln1dgDNQ0IKO/09Dygq9iG8PQwaXNu5Xl4wHtxoofnjUJvMM8CUoO5+SaFcfGFJvnc4FQMFKvVLhnntSHgNceOtyDWII4fD0eMbhYIKBvhcIY/HXJOmDF1PmQ3uAh6aTMm72rEjyzm9RoFN2GZfk7gJwAB3qfbry08C4o9PsuI5jBgcaBJIELC4OBHR3SwvpBD7l5baDf/6PkR1Ml1RGe2exURbo5/lu/sZZuFa5uD757fzdsXrnnuuxdMjma88fN7kxbkEJDqb2Ybxv9jvDan+FPSoEJ6Vd91vxtUvW4E+HfsNidP7lbjBf+KedWetu621YE8MewEeq/+vu/b0xEt6pb7LZR2mJGajgZ880M8dHJ6qLfn1yDwmcnqZqB7kPfPCYXHIdP4Wy9NUT3EEzEW+xHtC5v2//eFuP/+cmQMJh8+AcMRGGTUJf1+EEJraIWzYZTy28MnLXTmM0p59PB2msXoxx+QZ/a/sfmppxX3bO7x4/ZN1RIoNRWIgUQlCcR7JUAsPRXub7ei0JjaaEEAPZb6xHHCaYZCnXMadXpCpd52GjmfZAfNKVZ9Wzn1Ll1qoq0cQ9FwYtlxbBAtdSzqivCaw8BMBkJTX6+BiFJGaBgRmMJv/OPH54+g9U1ifWKkDkVvYGsDpDHUZ6KHnRcghOqIpvsRbqeHDEOn3SLuX+2r53bf0kPwzHLA8pnAw/K+W/x37KsI1BmcAXcGFTGg5NJbqAPUFvp9cLuswQpS7DY5vbnmBRnSW/TfHuN/pccFjFNuXIbeoYXBBVxGi4OewXVr2BJTgMYujWZdSLFdcvvKtnskeosEXFcjTVeq6Eu+qwchPd2N2wIGBieAQOm4u1eV351Q2CXjB6538pt+8r7K+FGW0nuvMCLberVjobosnB5tO6XczM+/2dOPVlWNsrvZEgDCbpoIuMl64muBMJySwfDlpkOuMP7PH7Hkhvn7z49Nr+2/Kv6PU+uHKKMC1IbzDvF4wJtmeQNelneWgP4AfAehBwDRttmfKeMXWwkqjRa/v6KvlqA0qL9e7LhO0QgHkM3IAS7dGB4Fxnoh/vKBzXOU8PH0BcwRysSN4VSzBmS+h3RIYgbmHNh92aEh2FgFHMdt45NfPc+QzZx42S7u+HzPHa6wUJhXovcfwLBqprtqB+rrhx/kmEe+/UeqQsn4amxu6iK3bbGRu+gboMLmrgKqUiEk8sBCc7thYDTZoyi5f3BBiFRxaAJNQWl6fVqwUMcAEUtE2fq9y2ipaRQVBedH8CyalvoD/dzNU7rYJv3xFNCYR9qtzzFgfNe+br8WOazfcXN3e+YwuYcOkG3VjYBfo25c4lLhWu1a4SIZN6y6yxkLK9pRiw6WRII4U9olMS5GHcRV4w6iJL3gtLfqHNQxOjjV5L5jP5zS4EhiK59Kd3gsCwVRwqbzZ6cCrG/84pP3JMwH3+EqXL5ft5ufT5VSEQd19GPf1iGsTTDYD9tqbV+DpaCfJWX1gPcYQV9jXDNeYNJkSaCfu7UZeTyXKJM5Kj7v95RTx7adFzaBKAmf2NeVrq6fDozm2TJIRgFve6TlFE2xxUax1S4ZE8u3UHJUca5ptACpF2WSW6nNC9eG52krT37myC675DZRZD050lb+DtSXBmnb/tgkywk+pJYDnCDe7sUkBnnInJUO3sJuFvU7LmOTQhfwB14sj7MX2Y/h8UZ5ebQskjUX6xFFUD+5ruQ/+TLIHQevZRVhbh23tJNNQ6+Y5tas+VoNjfJNMGuKDMx4cmtXA/YB24+Ku2qZdO8BHJD2rvaSxt/1E6r3c5cnZc88z0GrIFcJJ4GyKV5UnjEk7vFKfwsmufbwtoWZx9POTTKL5MtcSt4bYErIwSTE132kTybxbnbkRZ/3EI6TFMOC9ER02QiGMXEORLBhQeAgc6Q7QvnpnmnMygBXW07yRzEmTAcEnFKbqtc8lg2chHiu/5Pfl/rOutLrOMCVPRU66TZpu9CcHnngXBFblDLXHHWg+0p4XfQmYCAlCNLoFDiebubEjhsv9ej0MJxSwiREhAseHjNwg/i4gwN+0jnazisISAG9z3IgHHMsDD7cdJIvxDfdsR3P1s6iwzLZdz2N9jDwMO2KDy0Q7HSlFY6ECOfD3JkOloDUOkubJog37g66+MsbMenqid3syX1B4RNmDtAbmvmRVf1j2rkTQqbEDyU+68sS/RTqzIZTvugF+jl6uTZ23OlVG23l5M5hJNQ0mYl82yJMY6iAzpPMuCSqv22TiATxbX/R4nMCbW9NphE60LzL6BJvP+4yThA/R+oLCrmzZIg/Q/n+7n04JNXuNnXRjfrwkhQ5ZmpB0MQqAQ70uIpnxmygIA/09gE8c9LGMWbc5xE5xJEiaU6FZJCe2lzPRKNLjRIi1kdgKG3D/pvXgUiiUzzOxXX0DdH2Nsp/+Me2qce4uY0+IWK0ae5ANY0O94H6zSIUL7fj+m7j4ZekpofyJkmqhNiSHrR9NoxBcKklxJsR7yeR1dFD1ysfVbZRtuKvYVn6jQl2Pa1u4/1qD2QkiHdLcRWV9PXxjKQt8+sGSDomSomslSIOGPqIA/R5PtYImrcaC3Y0iGlMH3P1itsQka2VCWv2OtBAfKBfMD0E8VyEj3bzY8Dob+6OvpD/mzAUwDd1HPiKBDzz8kduCCA1fmybvXKohuz/E7Xt/NqLQ3wwQ/GJ6MjbD9Do8Mj+K0bH8wE4mkBmaP/YBVywiwD4mnkfeGYTGUDe3UnARwxaUNT3bdOUSL2KAEvg2M/AsPEjLAcn67r7ORAI/Jywwvy83LR6fT4MUw0BZUcBqlsx8CFUl3wEsgs+jOo9B+l+56OY+c9HowbYx1MHBpNDAqcwolpIQAsxbL+gi7VUsXU6bfqD/Sg0blfiZ/7HmLomvKQy0fWfaBgibOZ7f12aQhKr4WNwbCjFgov9gtej6PK3p/QWrY1H5vpwggZoIYbtFr6ssrX01tcp9sD/YD8KDcZOly/7H2PqJx5eHp9T+D75lmqnuhjneX9dUE0hjWWr58gHqoZSLDi92i94PQqH6m9PuytLaflH+ZH6qYGvfbvcNibL/0LBFGXZ2nkmeVe3x+vzA4gw+ZUMfVGhU1UqbazzQRjFSZrlRVnVTdv1wzjNy7rtx3ndz/v9AAjBP1aHn/mLxLONifSzNllxvCBKb2KWp2q68Twxettxf3b0AxSEUZykWV6UVd20XT+M07ys236c1/283w+AEIygGE6QFM2wHC+Ikqy8soeqG8/i3R3bcT0/CKM4SbO8KKu6abt+GKd5+YOw7u72h+PpfLne8AQiiUyh0ugMJovN4fL4AqFI7Pml25LJtbSv7tJB/tBMwRuzudgO1ByO07HlupMvSmhRD/15p/Xy3EgK4ySTuOEMGwFlnmxMMQiWMqEVQcaeaaMJkGXLsC7RmyVxI7Z6MM1fTrQoy++ic8ieSqsOSV/d8CmXp100JloyZFxpCH8cCFF9tPrMeIutGbpuo/tkB4J3Wl6oZ5jlk+ZsTNCcGr39RuF9xv7h1nxmweX15K+vJLegUOlwrvAZpqJ9aMKNd9OSb0O8UwvCKXhWWTKu+6c4Xjc79AOLJibjVAsaLlxwPNufYt4Re7a3FFttkQ2GsFyK6WbGWnMkFEBjBFBjm7AurDwns6iciBeuZOLjrlWpFu/gQ5vLXLxETJ/2LucldX+WyrJkeb5I48Nh8+ibQwqTj8ioOX1Sw4e6pLSiHJJIR7GdGrTnl93FqqwZSvFCOc6jMR6N5dRztiZcBXI4EOWu5pTdETV8r4xYPcYOqZ0M1Iz6PB8yFWBZcrN216hjIKir58345V60wkPuUoEinHFzwO7eDs2JsCdpqjIpZJ3zAr9r1TVRWbjEECDR7iMFSxH1k8bLJxVEHZgyUgCZBj6JAsu4Fawee5s5HT6ZfECmdIqKegsoOglC/0zJQAAFo07pPAWouhaIFniwH2U7ErVzgYyBSKpwE/LGq2t3rEQDYlJfXeokwGbtRWMagrd5S3FMmtEvfPV0RttXVhP00QgyNZWmULkKPDVwgXrMGUa6Nqdh0qBCyjYstQkmtAAjAXvZgIZJBi7b7v2FhBKtExYJ5a4Hu+d1oxRq/iK2eki0oPeEj1OWneh3JryGGVrlvdqOpOqOwGz6+CWn3u/T/a3IJ3FBevI1zIBdukX8BL4ds1y7rUtSRbnjDP1etwvSN1HUdbC5r8ddUqyiwiFBmxNv9RpmfXt10aJDAFX5oH5CNdHabugdixB1rUtLYdnmKXwcTy3yTOLZGQJzetKitZgpIPjoLzMF1Ton0NRLyhu6dNyiQUuG6GMlWO60RaOWzTX67usKiuFECGN5oxXp5rRsZAG14Eyuzsqi0lcsIXbhZXfE6EcNZIbQMe0oYAQgasNMBz3b7BUkHTFTg0RHoQhMlFZGGU/ejdeMfwpLflT1HFiEd7znbVfdav94mdP3O1MIyQDLftKTl4cVRG0qHVMl62E/A27D/FIprv6AhPMnZyCtkyiY2+6pcPhsG04nYIZDR726wQ2tPPykY/qi72XWgLJd/QA7GNW5ClDzf93Ax5/xDwF6LH+Ojcb7g0HTgZkhDLg1su2qLt5SbLB98Sv0n7jS8XkU1BIX6/wZHi1U+twvu9VQ3N3+DwAAAA==')\n        format('woff2');\n}\n\n/* #endif */\n\n/* 支付宝，百度，头条小程序目前读取大的本地字体文件，导致无法显示图标，故用在线加载的方式-2020-05-12 */\n/* #ifndef APP-PLUS */\n@font-face {\n    font-family: 'uicon-iconfont';\n    src: url('//at.alicdn.com/t/font_1529455_k4s6di1d1.eot?t=1596960292384');\n    /* IE9 */\n    src:\n        url('//at.alicdn.com/t/font_1529455_k4s6di1d1.eot?t=1596960292384#iefix') format('embedded-opentype'),\n        /* IE6-IE8 */\n            url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAGQYAAsAAAAAw2gAAGPEAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCdAAqCv3SB/XABNgIkA4ZoC4M2AAQgBYRtB5cNG+OfdYacxwEA9eYzEqHbAaXC+ZFZWS8oKTr7/09LKmNsu7DdEEVL04JkStgZyOKZ/ILQ2JzQooY+O2mlDm88cwprtIUJRYoVp8q1MEe1Ow/WIUjUNfnNH9HJV5m92kW8dnj/3pEhB8aSgR+4kj24yOevPzf/ix2t5Ij79FHJAsd5EFJ2EoByUZPNHtWZ1VUw8TCKNsPzc+v9/WVQI8dGjhpsRMkSRg/YRimMGiDhCBkIyggFLMAzAAsVA/BOjAJUrBMVFTk9PQUPK0D0ro1REM/4bck0GjGLMBKwOzEqMDrm/+DNvwEAhTsoAAkoYGpB7e4LMInq4Z7d2/lSHmrkiVCowgFOGC/4BjLdjqZBMK9fkWmEJpgKgx8EK9nAPEPOk30pNCLq0BlSKNLexDrvFnL/EBcKlB/2YPqlzm92rMBKbxWxIXacD0TdMTTllTdfbtWnkEtVgBUaVkW6e6oqLSvgq84luVauJUGaMQg240CPmETe+8e/tZabTzHZvWtZycoqHH//BQBFFJvYg6cSCAPK0P/lViVvbmTWIzDi0N0rLjdoVkyOXJIrXJMg1hJIpYJpuwL9q2rensSOdFq7rfav29kR3LEgWD1R08h27tjxMauRWqk1yAqQxIEnxwk/k9Xvp4mNJ5uJLShAeP9ebatUY0naCgW0UITh59azOqqoboMT35k+wU5MV6BC/qWqJ5UnA9vtHQlfnOYXH0EGqAuWT9o/uCI/R6qH5JFb21r+/3mKC2j3fzlyPaQSlCkmTghdBueFPOIgIuD/pjV7uSVUtRJH3r1Qi793yiERbvfPn1kmfye50j+ht+xRakKdXWpRyFaEW2p3vgqDx5kmUV5C/ceN8zDBBaE/Jw+cu0rV+oKmNmRq88X0i/W3q7b+l373+kzPkBYGICUCkGiCVIIo+wTKgQBlF0E6BXIjpfPl9IoRIB0I0nsFUA6kfAHcKG6W9/JrN1/Mz5Ce9/jc+327ryVoKss14vz/aVtEFGJxKA6zw9isAcvQsULlmCICMkSMr7y8H5v/3H7HKsRIsIE7JNR0v68Ola+NidPXgYK7d4y5/kTrx1YiH3ACHY721PpPEwB52aopNP+2724kpHhSAITxv1FDjHzpgDzZMsCCoCevzA4ZdNuGwWaub2JsOr5/+GfTAhbIQEXxzM4jWww363cwcBfD37CDtobhdX241wMioCayVW4+bY0NiYeueRB+9rkNjZPR3SzDmPy+DZuAipEDJ95srvX1+/VHZ73km/Ct/p2utNSVpqu82hqCBAuZNq+8ATmVfJVWWHeYbwS/04tPTM/uwnx5/WrZyVW5K5oTo3NVqPm14m2BMjTemmu9rddzuzLfe3tb7nMPuIeaD4waumN34v8dT1ljigt5jIEn4Cl4Bp6D5ra9AG3NcPfedF1NNsxLUJuXzqNjHXsFxnkN7h/femLnVG/A/n11YXjrmqOdt2C8CXIrtGdHJTfBu2Cm98D7IK87oI0PwYGTB7d/BKbooLKD+cRp72PwCfgUPJjtMzDN5ocTVRGvs6Za+Bx8Ab4ErbS26yswyKFJmhmlgAJ7RxhpsHpyne6mux7O9NRLF7310VdL/fQ3QBlk9lgsrTBPIVaoHNDQMdRZoDhTZtCYLJhDgOkttEgOhiVZjcuWr1i5qiSi1jWlrF23fsPGoarqPdJQmPaAzQefgK8sZ8+dH+jCxUuXr1y9dv3GzVu37zTWRAX+AgQKEixEKFdcbtx5AINyGjgWYHT9vvZfIDCqgylAED4WAqOAYHwChMSnQCh8BoTG50AYfAGExVaEw53C40sgAnYgIs4mEt4TGe+LgrOIij2IhtOIjiOJga+ATLA2kCnWATLD7TLH47LACcTEE7LE10BWOJGs8Q2QDT6QLZ6UHe4QC0/JHveIjTOIg2+BHPCgHPGAnLAukDNGALlgPSBX3Ccuzic37Eju+A7IAyeRJ04mL4wE4uF48sZc+eBu8bESkADfA/niByA/nEP++BEoAD8BBWI0UBB+BgrG9hSCX4BC8ZAW4WmF4WEJcZdE+BVIjNNJgp1JipWBZHhG4RgDFIFdSI6dKBK/AUXhd6Bo/AEUgw8Vi/MoDn8CxeNMUuA2JeAjJeIUSsIqQErsSirsRmrMoWRsTSn4CygVfwOl4R+gdGxLi7EdLcG9ysC/QJmPNw0eURZOpWxsSTk4lnIxDigPx5EW9yv/nFXgqND5XUthfaAiHEXFeFYl2JNKsRctw96kw3Mqwz5Ujn2pArtTJfaj5difqnAA6bENVeNAqsFBtAIHUy2WBarDeKCVWA5oFaYC1WNJIAMuoAZcSI2YANSEpYCaMRFoNVYEWoNJQC2YDNSKhYDacBGtxcW0DgsDrcciQBuwKNBGDAdqxxJAHVgcqBOLAW3CYKAfMARoM86lLbiEtuJS2oZhQD24TNtxuXZgKFAvrtAeXKk+XKX9uFoHcI0O4lodwtJA/RgLNIDrNIjrNYRlgI7iBh3DjTqDm3QWN2sYt2gUR9AvWBXoBR7VOzxmPozNgflIbAHMx82tPbwZJFOzvJzMNDmb6fIyM8Q3M5VgDlereV4PzAv63byo53AICxLwkgUqvGyBel5RqXlVOvOays3rWmHeUK15Uw3mLa0289Ri3labeUdrzbv6yczSFTNb/8MKwIAcGwADKmwIDOTORsozG0trNlG+2VQVZjNVmtVUY1bXCrOG1pk1tcEfawH4D2DQdYP/N20SmD0zvuG/kuhhSdB/fz0IEhYaHmrTyNGHgpHDaUQyEvylEiPhpvAsgAdcUqDhBAzjoxDBamWWHEXLRUk3zQIxJnRqcWaNC1AmhIpAAVyaA7hpHlAPTAEsEAikPkuF4ArAbE4NKENRV7oFAztaGpkyLioJfbF3cbQNo6FblBgH+xgUe1gRDVZjE0h+jmFKOA1ZH2aGqUo1CNuTLdrewl6g5gToj+dRS0ckZ5JyNwz5Vguh2Wa0tKjj/kJ0Pi8Q8yPlTocrnq4hEa3FCDocKYsubQ9jkix6OMlKQVSKzZhMfyUP+hh8LpsQPaxNgRhujI5YpMtinZ4414eSNeBbw1Ls6Gp2amgIjjunapxZgSPKLKeXY1BBiz3kxFjZLCmGrd20fav4lvWoCFiF0i7H/rBPPxcbTXmpffcEi0en9a4TrZ3b29250myHaYrEbXJ2IQIbKp61FYJT8MxSGdedJsFuVe2162qscnZbu93dHb9dtt/tHxOSmhwU4liXKB6sThZdbqZB68SUGFIUHO9hC4V931S2mW42m7B+S/EEgYKUJasluMCKgWG0syNq01mLLImeKX+CQedh0gE8PQ1oajBrg1UqguHfLBI4fLvEHTNqQ01rZq/1J39onmem5XFG2PmFXDN/f7C8Zl/Cq6X+CZJlshonJDsrE/AIu0EMC9sGlTQsLrgq4vVMLdh5NKgO4rC/QGaKWGIacOw8l5RuOgcchkMH1+90IOa/2N+azrACjLEvwNZsit0UF7BcoRWCbK67FLt24V0TPbgcxG39QNk1uUNKGPRZcS7Y7J5ktZljwx4ATLywmxph7hHqvPNfk+GdpPwQNMgQwXQYO54MZiiwuRQE2xAwOQgOAqGgE/RQl5+FfF7eDYfm2jFIhuuoz9XThdADbICBfGs1rTkfbCtCEhxC5FEhFdA8I68xxB3fDFU9JZjRqUMNKcPlXD7pCm4sIH8q20pngJRErVfT2Iahf+8X8Lvg3AOBsOtwuevJxeXm2SYvAbmlbDkExXPQNDIWTadUAEa98rqioP2RNAsLylBYAMEHqJgBVgaLpgzMHbjbBA2L39wEpEXjzCY7s00W1LgT1EwRxSjjxoJ/oFoKjHPON5aDfedhXl8dmckO1uIN10j1HFmyxd2SFOnC0Vh9kVKwrAGJr0OuGlYpYquJrxYtQ2mlzzGVcVCL8swKGkTQ64kagF8j100W718Q8VopCopjK6C4i689URK20A+IJnQuzXMmR52pWYXM9Hpi04bbbujXXkyI4rNVaAWkKSDXORDJu/7z0pirFs1kEmQzXpT6cfjEUGba5thBeu5/cVtb3kINXO93sNeGlXdWDqW8Hfe6osCwCoqrx2W+Y7uOkVA5lLKlGFBqiITEw/FVPIzO4oLVG5FIN0RNBuV1nGh7JMPZTXV5Ho4HjtjKUErsFtxU6QAwTFvFtdCrDy/vjtdR1yFyq7L59XcVnfG+Rx8fNugzG5n4hSR8dfVxQtOPLXnV3U7typyHRy8KvUrEizAGooABJbOhIKbfJpjGMVh3UtTP7zGK1rIRZfTb3Lsw1r2mC4I6QtKc6cFxOj0gJi8doJz3ht3QfkJJ1wL/kAGhczPEyF41Y2VGn1I5pc51d/6ovdWl/R++PzjbHq1PH8agTYWXvDKFjYlQtx/giou9Kijc3D51Ry9CZgqZoq2SRhVnwZlZRRRgBmkvlgBUl9aIk4EYz0Ld31USbuBrAuX2cHRLqLkvaB/EQt/dhAhuSvI+lWsRSEvUWC1eFNI9VBWo8ByVBbcPhCMpx9csfloGoIYWdabz1qC15pKm5GcSYKDyBZPDbdrU6okbWL/G04cmkqLK7na4JW3mTtSQ1lp4KzldOg7Q+7J3YEJwv/wuuru5bNkSevbx0X4pjyaLxzTIFpb2bTClTaYAK5VDU4gwIQ0oaMJgscXpMtSQPWSJnFlqSYHUQjHGOGRKUH8O36cNr9+SoNKjs5XxSJ5Ky+n2FS3j8cepyIBkSzCnH/K07s6pmXizamV/7UUOgEJDBqRBqHOygXBIIVHwVooRWC7qBIzPMuxeDuU5bMWvt3V8Ap51RNVMI+ghOGnGhok7t75QDbfX+hlVr7KXA93sSUUvdVq8g4hMktX8uiXrkdWyjmawkwnROjZ/yWSORHT1kZOeOU918lDEm08fmk5fQovOZw48n6lB0JwiejPCVQHNy+Yi3nStRNdRYsk3/KCdyzDOBPdT3RcSEWTnMhc1KtuAJeNCExCwxbvSEd+EWSLpqAokpBRDybILw0GWJ5WICLUxnrU3v70ZJFQ6snWeJKejBykXDXRK7poBRMxK96reuvm9SPI/uFVG+LeyL1wIiFdJFAobVU4sITsEjSkVvZSt9hFPFAmCMGfPWo+WrkRm1j/ICLuKrhjPMQCAxQTKRWMjcRloQoArUYtA9LrztibHkNO7kgft3xgnNF1DGixWcOCk/e6DuVeL37stucRVKA/8tjsTiaXlZu7soX8nyS/8SmuVRmdrVllccLKGEN7vqCrtcczv14jfmVyQykAf3ig1GTo1M8FzhXwRSOzZwpns4LloG9+SyHQgpVxK5LcGVeV6pUQuJDV6UqZP5MkoIO0/JAKD/mzgNHlCvngeFWPrYIiGTcW9SEAwPFJGZ6TF+fgrVBZjsLkB8oTbAUODXA/7t+eKQiDtdeVpWOCq06nj9NZEmQio7UC7ockeAm2JYyQQaaNj8MbMoZqyT4S40BUhJ5uwQyw3OepOW1Q2rITt1Hg3eCuYEDuDTlIiEoYSMSjSVHju3rK8Uj2/kPfI72reEEn5D77TsyRz46rb4Fwc49qev2NsROWSHfmmHx37briuXDtZPWbFaIaLrcdcUJnH1U2G8dkk24tVhjReHe3rCwhsStxxo6p1qZ5LW+u1kvD+DTsrFg4DdfyQCrTDuzdHOz6DNoWyqXOoncD8KLT+C8pNiqE0DdeyTpqd6z2CJn5jBu8mzsXQA4U0spwOkrV6VaYE3+8guIKg0kAD1yJoh6/vRtCpKHpfFxKlhjI5PlM5Nk6lDuQUPIkNdEWaXk/i9tdWDppsyTsM9t29y+sA7BtYHER5q2gbOYvRtmZjbLgnghKmHeSXKhrKGznO7v1Eg7jmvq4svo1Wl0/E20tH9qGyx5eeVJtr275eqrjRPVcplxx1P7Cq5W7s0FP/lsU8hM3qRNNylTBTwnbYbc0a5+ldB5M8UxzyV0VQ2r2Wg4zfxR3GBMGon5T36dCTMsX4GiqF/2wXk3OhUJR6gtdB19zBwOF5L7zh/8rK8dSB8rJGolYqjTme+17uQDY7tl/rLMiR+mJwqEUbS09a55yo2r4QRFC27tgamxxwCXrHW2OjKwwyZhwJVkQHojOMhCbV+OtExBzqWz144bIAwPXJWSDl9V/AT3gt/FvV9DLpa4kkcYPK75GNRA1aDiHjMMPATTRifViXHA909in81q1XvX+wfHiN61JXFECEqzYQEfv/HDFYFFItyUjz4zKqm7ovloZwWPTQH71LMd61qsNBMTe7JemSwyHp4larXRNCn7NMfu4U+NORlgAJjug7eX/XAHRQQxoCfDGwzf5gri3/qvYmu7pPq5YEDVaz+2trZMgC7pVtVTd2HRgFfPM2kY25Ll6SOc3Q2RIFUZaVzcL54q+Ozo4NM1XwLvi2osPGiWJUn9QSdlnqyZgbcO9yM4yiNIMijGdQ2zBUHF4UV6om7EWCKS5wS/J3xb8d+SONy9jOLvu2JoP60VwkMQN07ZQ5qqpMcd+CE4QRPn+dX0mvvNZkpVdfQfhPev1V0Z36wWachYYQ3eRmvw0y5MasO0b1iibPof8wcWiEbOXhB4XAP4S+B49q+gJmXzNGTQqCDxbw5WD66y/fHrPfyuT7YW7l8KdnE4Ps4t73zz+61KxOMOujxFj2aTTFe7gnp7kgABgVsD10CvwGqmAErcCqtHZWG+BT5s+IIwhUDu4iJAp4v4qLHTwU5tngUJrx4C5XWBI23qzM6zIhlfuU7P1CPqfrZ+QDVmmC4NoKNzL1OD2aSWC06s0Wn0fqZSMduphiyNC+okatppSEAPWk8qD+oix8EYiCJd+LNRAbStUos1rq14goRTgeVh4i0l4+RWmMVWQEJEhBtL4II0We6UBxmCHgYSS+LBCQU8pQbV3TwVaX+wVBsQ+CD091vUEfaANTl4fgzGu/c4rlFhh5y2Q07snSbzpu5QJgNLSolAGsz6U/0ZOhppppp0fLAwFMVBlmnVJFptBgpmVKGECEzg3aOPJmH1hIpGl91Lks8E+gcjD64gSTrluWWAARj6UXHhQnDNuB7keTt0mgXKCeVVsHBa0uFyMaKifSUUCyd020gBEpAb6cmV5IqOJ6xtw4G2jPFbVgdh94xis61hMVglUA7TV5Les9yNoiyN47XnFo5mqwv2Lglp5uzMELnNQ8kG3j/b3t+IjFV9cFIGsHsutjg6YbFMqPW13VdIxED5cwOv8Em0DAIUcRoon26OQP923iA49DobDctXYKxcR3AKUJsEnfYIiAn4NKPVZ25AZ2olE50nWtLWP/kn+rSQF84pbKtRCV+d0BLBrgJWuQ4Rh168LgfjctiRyqQ1nj+noGt/yUwhg5HkeEy4dwIc7Cvlm6ytQZ8L0D7/xRjz0whoJnHH5CH3tndWVoqNwmaLzQysMQvA+24yGzYD4ZwCbfT+thJ8klKI0fJlDw1RwxKDKWLUZCNoPssMf0o2Ws2PfiDG3cvgcILQ38kCGuiVAMWNZtfhAopddem+UJQj4OntsYGkIChGZlSC/o/UnkTV3yEDKDJBvAqAyZDcg7JPlmB3z/NuQx0bF3Ifcg98jZltCjGDAGpPw4QEwRwfgSJYvjatCyzG8y1NlMxL4o5HikxKOlh1VYlTzj9mnkl9RBc4ahQtI0wyMFXYJMc0Pge/jcwBPdRCLc+aJU3CWaqstAufCIeomrsJ1AFGY6/mwHPahHVh/xmfX2SZhV6gYEJhinHPjs/DwX2d77BhWFhvFvVr4jSuh3oin6ljQRfvjP+b/SlEj5odhpCCi4ehNhzBhLdLnKEP7BjR+Zhd/Y2SFIcV1rgKJwye1srRKZ5bHOxzNG2hgGxC+/0+P80WKyfY+qQZdbpRXue1R2KxSl2i00ZKA6kHU43MWiqyeAPwoAVbMwHnjk+CI3aPO5jrmHJGp++vAeWjEqU/aSkkip4n42UurvLMWqP+J+riFu6uxlpQlxxlpQGH9ZjptOKfaG0P9VeAyeGC+iqds18Q30QM2KhCXhHrokaLjPkmX8OKlSFU1D81hxS/d3AKcw3Ap0SgT6j9kX6AoW0VZCUSnE4w+jhJSm5m5EMFCP4V/I8RHzC0F+INjYCIVklYlSuUqNclnUOgtEmcoeWhwgldjKqhRP+plqNmICWyZufBov1/ZAsZQGuZP+nhwDvPJMeX8cwuo6oJfX6hV2FD9941s1rBQ6n7DAdI15y6+X74vQHtP5ytb3r8nJtZmaC5EcaBSLaANCXkwDKznaqFDKRwdl7b/Pu6So1X090akA1oTr0bEENqZmibeYBhvSUtw2gilHjQyl2Q/cuv6S4630xlYF8z9rkB+ZTDEvphEaVKZmMiwayg4SIHlhApIxEVX4q1ESoY0xg7pnKHauYTLwYkOFumLLuB/Iu8D5SIa+wZToNxJPGONdZEoLIv1xLjIJNo4K0wOHhjVjcmxHSsnOjO44yPwj5lpLOwJpINT8kWjT4WNwePOXADWeUepOyYP9ByhwoN7FZsU2vYcAGo3sJjEbT06dnVOKBwADocztZ50ekLFu25iQ5Ey6luygQRVUSxkZPZCg0hgd0l7xc+zFjiS+I5iWDIKxL7EIhwrcS5BLGgwiGJcPxj4e5h42pMjDLM8WQ5Te9YVf2TORuKL1oBck8gYY9kPWfPh55ynVii+ZI6T8vOnXgUQWJAINiPj1rkcDLdj7xI8xVSJI/NNdT6bR+QZO/q6sRMc7x+CifRr9ksSc57WoDOisla8Sm+VicLG9W/Wjn2SSQInxS52bIq7igDSTqCiS6g6VHv9GSh+Lb9KFgt3EbcE5lf6pSRWuDNsnzVFrsLoectCnXeOq4X3Wtd37AxxkO2o6QBGAhR09CkBMpESSRyN0OsDQBsIWCXWU5qDWewgqIxXQDp7q5uc6oYaeCF6zpjBCUZKGSLikTk1DZNb3f2khif0PTQCePvgV5Ap88EtMcUnEsBjxRbl4VX78/181nbbsAnR9pO7l1ns+4dY09vyk6xNJ8uOKcyT8X3j38KQ3OMgMhBqudT8NtadUCaoOwAiFAmttJC2uOHkMFtcGzl2JFqHtf7iaR6Ee1CBYFfz4TmjoWh1NwhNxWnKAdyozJ3DJvXD0O5jvA/UbJ7O2zR7j/Ma8zXWelB8Hxu9VnIEZ8K3Qp7FU0K03UoNmpzm2V9ewkctSvh8tvztZHP1WcN9gTxJMBBXiiieN5HX0qAX3WdJmM+Cg+LXLLHUMM9J4NZU0EKDQ5y3ZSXaKnUwHeVGVcW+O6GuWtgWa68FueXHPdCv1btld9de9DVs237UXFSFPu7C2uY2a5BZpyXzPt+HE/PDojq2sfzO5V6+zitZovjspcwG10LYGLRyDsUXeFKi3MbWuv1jnV1mTymNokNXj5kyegqNFKpKiAH2bwMAB+jQLxqlREBxqBU4rQuZO7Nw3IsBTeyICjSb2xEpzCKXOuH9doTUNshIBYRghJGAQprcbSgwtnlWe1jEiDCSUW7pbG/4lNn6P9a9b2B+ROjE61602C3dJuEmRBMAmafG96cuBzIpBn8bcs5OHfJulnFHMDqImCr8FPE019EJolMQNWebj+MZgdaooJdzqmaYUAxj8EVvi4gte1c/Pv0BmhKSZeipETqYs0wgMutcyaWGzQcNoCoU0I4zxFoTcm/dmQXdCSIOJGWzxZSV8PjSjyUnaC8qWLmSJG4Rrg5K/v3gz4kHcDkl5eHvGMDncEPfowxkgQqQT5mJ/PE27QqW1cQlV2Fg5L7h8VwqMyUIgZJS9nxfNewC06r/osk+IKyHWbu2QEc0ix2rrUW/m2ClM92zwr67lWnsuOEjI2RPNKgLrK9gIobDYqVy/rKxMn98GQTE/vv6tTo88CuGgHf0dlTVnXmwN+tijuS1roWz7DLDkRm3HOZxzM52Vc2nizruHB4UWrp0ZOwDgEu0h/skNdMNDwAx12D+iIWCajOMqiQYOwJNJhmAnBcO9wKkZQBWKPr+1bM5cOYHENjJ22vnLstPaVCU0g7lPud7tFppO5waQFjnIpfszDqTOuSTivW5XkerIsnjSvaGjIitzG892JwZ3cgO6i8c81IBKRWncjRQluGbU024NcCuNUqXf5gWbskkW28kBD971BIf2baAQbAJ5SjmXJqvLg48Ojg4gw8UbbsDOnfTgMw8rt8JmrjRpbeXyCoBWbe/7gBdPk243O1n1bNRaYwQ8y5GcMNYtBBL8FO/9T4Y7nXJebV/NIp4I+52EjYDu0B6l4gMPvKaq+LhSuMUdxE35PjcwYumtF0mKqNyHpjR4uglKPRtvex4WWLGMvJkqC6j48dwwjyWAxsGtiBLMEW3OOiWbKpZuVqTy27tLYK02PZluf9ZmJmDR3F2c4EjQVKwm75MPbusDCmQm3+JIN8OZqN238yGmXxqt2zvX+uMfHWQCSXNvSIMg2qnlU2htZUhlD6DuC4Q2cSGl6eOaT7Xj0cD2XdgHt5/7PGH4j8HFE73l/JZ9miWbCWm8//5Hnrd03uczmEBhI5O9/f27WdLYMMXGlvUbOToh11ztPEsX7zDLTQz7XO0H7+ygAm2xwzomNvZQQ5EgPXfbmD7+yZOfjR+UV8kWINsavhmQ1qMvbClbh57CRndTbytt/t+IlUM2cxsPPBrw83rbYUIveu0shyQDbG37gEOgv/NUZB7SrdcNOiIz/vTx4zP/i8+OqiKV01kK39MSzxiz/74i4ByvAwlB4LQM96HxCa2tJ2Z7P9y742U3IKkc3JyHDolnzESo9pSEqfOAbgMYPEq+sVD8goApBR5iZ0Th/0rQ+Qo1KhI9XzWQmhG6YnYJwBt4gtvZX35E/AbsTJHWAssmANx4d5Xlm8xN1Oxx+sLOq8sxlBgoPgvxUzDKB5+jKJV4nr8LCxaX6N7DpJ7h1MnITu+rLh5sas1ZDVppROoChQ5qt/Hm5sW1XXAypIkk2TCykwqBn9wWYXIGXau7W9ZVwu2scKr0o7Hg1a09J8+jVJBwFNn2OyucEj9xMXjT6WZezTSwCafUbTTd3eFgiFmVp+5FAU04C5BqkjAj2hYfuSG2C4WsQCHdQbNzcONmiGDe2twRmcbcVzlPOz2dvavXsFmBBFeBiDhmt7K2qiAKw8RoEJkh5f+V7NpApcnTYxo7Crs00VRPIx8i6V0gS52b1mne6MdttBzpvGZt72dkoMM6jByHgkDoBMIjj4Z5Zm6bsfOJfWOAbH5h/oqz8M54SQVoec3oIrBY+4qRfAJtZWIuFKTquOcAZby3OmKSTaKXOVvq9/ydsQP0nXBwpuSuAFupbqX/WLHUB0qjAyLZ+3pnbFJTSvtAMypOJ6nEElyeYDwlxg+CjU7fDVP6UuoPjczP6D1oOkVQVV5Z+nkepPSpr6Dn2/XtCE1msNbJSw3XyNsdqapYfZ4vy9VKgcB6xBXZTqQAivsJ54wxQJM7AF37VIPoUG9eU2rYQKui0A9zMaHShvtQ3m1TZUmfDPRoi3E988P9DmqjwV99YIg1NAMpHVJSLTe/Wp3dx6bajzhJ73ogv5IbLRDB9BhWRhYcRZGv3JYJDZyVSQNltW43IxhA11edZyGx7mm3fFdYxlR28lkgdRfM+5krv+JkWTUZ5bPzT+fMzUpr5pTK5PwapRXTeY/Q/8SPV/ZVrr4srVAreTIBbZdOrtKNiyEvvB+nDtkOfGm6zp+Exdfqoc5PI3k82P8i9VXhqm6V0XHMDRXVD1Ah/Mb+J/Q+qr2sjbqFvTq9ubph3Lt7qgpxw8wKPRi634f1obUcLKtmojKN87Bf50JkTFTaHJJ2EH8KDP4QlYHWc3o/YUPU2tlbLPjynfqo2tXMxdak1elHslskjmEkcQpRKbRlpdsnq9nTv7/MhttLe9VNOo/3b3u7XhvFYosW7f5zq/POMv8lTeLGL1RhroJoCYuw8DYXZ9a8hWwlH4OGW6WHB1+0PVKrgoZ/zAMjL0kFL2Y5n4izhSr5Iymmt8Hoqc7rZ5Tbob25k02c7b52ekb4PuEGv6xLK5bpQCqLkleLY+jqARs5k4LZN+LSBXssJ1usPp6RIEhIORUb9MdwA9xX2xpoOygT85EpSjkIBlFTl/s2P+cXPo33ihjerxjDfHR4Jy9fu9WQZ3ycya1spDKvpZ9wRLveYw1tFTzFMyzKYOogdg/v7Dwn2p84aI+Cb8g99hCqeTvo3k5PvDI8r3aTIiVXp5f2GUZS2+NBY9PU6nxTU9eotMgEhxlZ5PjA63QmoxikRzf41DSVFk9fSmmehDlHVWbTb2LGP5gRBTT2v0aEAWgSe9eh+SMaZ+eIsDF7NWdV6kqKoqajB7l4Lh0n2tqJx2RhXJktGpwVe7nNFq7aWJG1TAgEAoCjnrjAbas5Be8myuMRoPeFUhvpjc8pT9ux1lvqMb091AUsR3QeZNElBVzA+c2Zoe0ErjJlQqTQ+UDVo7aNIdIH54RtD+SgpjY4xpcJFo57Jnw+WDrUUAoNT7X8Djp9Jm+wCCHoDou0AJ5sjTncGxpshtfeEQhbL7SZeZUYT3ZfUkwSxHG5NAEGZQJNSIu7X9edFp8MoypP63hmS+WK7hMjD2JnK+QpKop9K+vNnWVoGNJrZuTNBOljPj9qj1Y84j0jAwuZYRjsGlpskyg+4DFbQrV0YIW0n9h7EQKucYF1FqjI1EKVDaBc7W2+mxopdX6QggduaFp11N2ek0uLImtCzfN/oyKGo//jLb4yZ3L4GDxsIkaklZNawo7uPizPiQqZunpon9N9BQ8QQPvVyQUXKYvSF1tNddo0b+2sz36gII1HakljwleeKESuApdIZvh7Si+vTlIynk9hJ7s91KqNTFaaaJ0VKsNAR+xkFJLMQ5bT6Og4rrNp19Rtrc4Z5ZnuWLbayzdZwJ3RqpXG7OEP0XJdTUCwHMrMr9TZuj87Xu3FjPJgeqT/nmijEZM/VnHS7W7Mi0rGvQZkNJmai+k8ExO7VnFuwyDpLqtamIdtiXxlmdIi00knRnaUtD9jbVKdV9qVOuKO0vItsodgR5wE7tz8lERgZXAWw4ov9LwsYee8h9Qmw8agNWL/K+9dQaXICLvqeQlUJTKKXFOE26e35d2oAKcDhynz4ZGb8v42CzZ/uEExKjPtyOsDfitDG/RLKcaN02KoyG44hg/K6hPthImDmpZAAZzA7XNE5hDKpFiuTK3pz1cD522bnaC0Kn6NytNzO+ZnpQ+teWCYWwNHq2dJiqlWqRrYJS1XXrIqt5FqlE6x+Bt+zVAU3EVz3x0CKA6XgN60oz/NTuA6QguEU3Y55pOune6iiINsj1Gz4QzZnMX3i8638sCvlpyAJ0+5HXPn3Fa2gqim7z1p9a+ZW4+0Ifgem+94lP5jLC7N40cdLHBONWWKfa6bZ3HekdhIQuHeHRT6JQIemMa06RoNKb5NFaTG+QGlulwI0bpIdEBKm51cFBvApVFkL+t/nzuqgUlo+RYkGoSHTUsr78N+AqJyqpmNXxsVe3se2z6nxjUclUGLz7N08URhKOXiPiNZvdCIsN6IwN3t6HJRJ+ZddcZcpfw/Z7+e39h4Hrk8m2TP4sU/mFaadJpUmf6wCjfLnsSv2m5a5Says0rHQ2uXrR1f1rhMkMiK1etjWQr7IUOFbi0rlq04yo5PWa6aqTazjz8akgzvmpraCRNlFN7VV/IcYHQ8hpybQwZ7TAG2Ixl+3fDNmzDYbgXoIz8g/7djLuZwfRqiLO0oBeS11RatK0gZqOYj3pSGODUmgrSi1aJ6LWkfcYWegD1dUihYG1U/9M1Eu2aoXt0+RDYlDx1cOLuD8pxQbt67d2ir1kS7bQgEl78wMcEeoq18l7AVIbWVnnVca3vErGhEMylma3fn9DTk5GmxtvIrL0xNwPGbLRlZtLpOKA9Rvm1beWMRHSEK5X3djyxaRguj26mb0dLLXJEPReflRTcW6mVQNG8JBH5+SvZ9+huFmm3nt7AG19t7utRN2IY4fRpeS9TQ5NeSVgS2Sw5u24qtofgtwBQxhfI7AGSGu0ya5pRvqOJO6Vr0SYyjA08AQnweopDQTgiFIreGtZIbvPciUZTrBT6Tg1QVlU+SzprOSknZzDMDVclSUo+BAVYtawBcowws1C4MULQUWar65YKUJaO+pKpYSspQi8gEK1WZeWzcgJ3KbiDum/RjsXExCAnc/oB3Vz2+dGyQSLTmhSimzavNZ8w+U/NpJvnUz0MjxGriyFCoJXESmpr6Bn6cXTi3czvP2gY9Y7aU7HSMMG82T6CJ+p2hntwb2gu6O6FQVE7uxEOIQlG6krcdJiMax/rGjPkBYYHUR1ogWI0ELQfeRMrbI7ZH3tq9cdp7I+NxXzF38d8yua+lHxImOFyKSdXGHDduBuJKZ9I33JkzFTUS+zrRkvUI4CcYEx2PINpqHmbcITGzy5LydrcNh7vf0A6Fqnw7TDriOnAwI0zl08HoiLo1iIPrQtW+3ubxHXgAMxapvNNMkVcaU1fGYlpJrZjyzMRAKE56nXz8UJFbNEWaVjzwb0A3ogW6zFf9lDFK/6tMnQAdj+HrRrp9Y4A2H4px48gHHwGalhZPywPR/23ljHG2/hcN8mi5N+xjIa0WisV9wLl92/uniwcz6wQLHSnPop5/PfL9h0dCl3o/4hOzJ0S/cSfgOwW/eRPm87yDgEy3ok2CSZoVvQbeFOcJ9Ez8BokYI3sUQ5wftgOTY+yLdwEQrbkXghK6Z/v0NLxz2N0oJTdgET2+2xBd8ERggt0bTmk4InjUOaz18UAKfwlZE0ted4017LEMrPAsHdak/Gvs8IiCFa/aI9fsVpC/xq9KDGm32aTlHzUyulU10Ya+FiluOS/W3SGWHi8JTqOksPhinGVyjPix7ZfMPZurc/7FQw3AqFb4Hi4cknrFrQUJyE1PLh+EFSWa0J26dHDVJkTYwCtBdFyd2AWUV8iq3WPMAUT0n8ZHLRzmjsDbGH4EwiUgBMOur7HP1RwWbissVHdfhbQalHLsyROWd335Ku3tieMbeP9JPjXBXSjpkWfLGYbg8Z863zQvz0t42OaF5h8fsJ3Xa5eX/x1p4VyAaFuL0CLy167NjwCirc2tq0VkyWXnWKggH8SB2IKCWCgOyi+Aeq7z80F6U23VGibHqqu2vM2q7UBnN7Zrz1aCVq+7rDjMNSVLEIN4mjWNhDpEopOPCt8OIBCDsnpWY2DxZgKV+A0Pg8gF2PIbgSaelQc2deICBqUw/B5BY73jAfgVfNahIrC5I5wACO+IRuJ17IdI30y793zAgcDJWdwx+DurjzcPH8Mt9Iv6F3C74Xme08Xao5PYBuT0EespGu+ILes7vBvHGqH0k481ZXiIktxFpTriArGPCIi6Uve33iaCEbkj1EuljZIELAFJ6UoCTEByVRFLgYgqG8/cEhD5EfJqC4ipX5xBQ4sFzaI1Qs7PXBqfMmqawFQAC4V/79qf4ANJfy7vUwEfiZNhUQD2MglqWGSFutx2g0Oiujy/qOAYFrlgbmCfN+oipCXQpk2IEkTpps4Sgg7HUClUsmlTySLfFB9Ber4gLYXvmwiVlEDBJuDFKkLH7EkgK9va2p7USHXxrCXRxqSTk1UmN5LiyliDgSxIk42ZkrQB/LLaALWUFxmWLQmKc91K+G7+nZAe+MXgc8MXscC4wg9X872rodycVD2bzmWlrGIWRh6kYMmnu+OVzH2XZ6nVdH+2rWoSCspWRf27hMuF3IL9924hMBuatFXb+0MF1IpPDE4ERuxbnn+w1aOkxDt2UF/mixVHFJnuAksLwhLzF6WwN8B+gE8P8VqPkeru6wSYDoxAl81qHcDwz0AdcDfvPq8bvoBU4TxDkL2QXl02supoUTG+CeF/YivwHb346D83uAqUtjO616w3jB2GKSrChNmHkalolBpV4c434vytEq0TnXRQgwWlHLe3g4sTm0udKH5RGyt2JWzCUcotCtv0+BmTGXxnbkWx+l552nS6Qz/28zVilb5jOtEb0rWfgZvuP+5/wJLtyrYE/3PxwMqey8bzu4ZtdyQOjDxb7XUY/2cGP/1IrpFiEeJ4fQztH+j00f5R9qNd+xAKOR0pED7Jp/pvBLW+3pU+agU0TFFPDoPYiGxXb9/lFkLo7tLVEidvt3CH/WB4Uk3+u0AUbUjpDRUGggFKOKsLWFX7iJAPHKPDLcug4bvJNgNAI7YBPn84pYmY222rBtQkm3kRzKim86G0mhXpEPcBDpyW/KPox2bTdERNDZTeQUBZA0qD0mtq0kNdpc4uEfGGKtP1k0ppBwlj/DbyY0rrLnj/l83lWUb0eecL+Ci4g9o7HbZ93uVvl6fB9dp/XO4Ghx5/yoi643QHFw1bUTumPXcA/6x9mKi7V0Ji7r7XOanZWNIHkw4EI/q289a0Z1cWx0zNu/zjfDeE/IVnSLkB7wD4T5iVHXZ0kqDB5umEBhVWQ5zdkx4WWSMJDA6UkWgkIcme7ATbJVv9Tra3opFnSfZjwrl9fJZMs4KjWYzqTegYzYpGEkRHdlmyDd0x8svYxfTBtkVG8snvk5NClpCBC8sDAlGtJWQBb6qYzZJI6ClF+hCLptDvrrMWPFKoM6Z/z6aY8o3G/Z9qDAenv/LCI1qv+eq1CUmY9N4Hpo9704Aws+MjPDWUaUe2sYbwrIzeu+bfqclgPwZ2icXmAN/nU8CQPzNkyM4wg03HzhgcO35kHWB67NnB3NYb3ukrh2oEFwypgcNBNT4B8mvxl2i1LrXUiyxqq7lMkS78IJRKhD9QpWCALCQXpHYwG5x+M/fPqtj14GGPlcCqn0YrpYdG639ne95011bQSAenMEQfy27Ft0m3pQ+zKz+/zbItFq0LbO2cOkB4iqhorwz7l2NAhqneL7KfXt4iBR77DjNMb/KShSPciUN/TPnc7f8bAiGfK3+wqA2vFWdWPIOLgQdanhHdt4ZXL3wcYeXbHa7xwVna4DF12E5vN4KWqsPXhLzE9dv6+2FCooAkCLfISW7bXyaXoxMw2mGR93EHvC86GNL1K26aJSBHzfqZn4GwmI7tpvRT+ynd3BujyP+/IM8hR798GQX2vwcA4Zh3kohgzGSISrpJog6ZjAFinxvmkCa8LMVQFlNGoo4xxsK/Qj6GVkx0a/Rozq0Rf0k5VywN+yomsx/7iqXu0qZAyUQJwsqq8sqS5wN82e66j5jfMR95RovfLYwjQMd4XryhCGxltNJ96jBGLyOmLrkuzUmdD7UFsbV5ykPsd1rmJYP9dM/STHbaz0NcI0uL/BwZU2bxQ98tyMyL10FIzf0s8JfQWhrgLKFvqxC++bFxLRSu6SMzVPZRs3xZ5pwsnCUxJfrKqv/nAClIT4ekmBmvGYyfS3ZMTJaLpqPArUbGzgRmjCAU5wniDuIJC8WaZ+XzdrIbzh3OPFhUr1B8cgfulIQEociuLyyIvtkFvKgHRShKSKC0vgD+px7+Y0vY4ffa99Vmm92IjPM80S7UBZsjdWSUX7GNjZuihllpDPKZp9L1UDxRWv27OigIcXScpqXRHXXceOkAkd1YBvO46In1W0k/XvqRtPXmOvD49xGWnjVSXz/I1rKHt012e4qgHi9hOfWuwZltLoCTxmi57VUFRIiRp4VNuHrfXIfwno3x8WnWc/Kpkvh40HshGqUT9gYpto4YuoFx74Je+KO1y1rQU15SQkwXC7gHpqnSfYryoqhd2DTCSnt/LkvN4/qziKtQysa2LepgZ0dut96aHevKAd60x9fSoRitNkbxgWdmTDqioru7AixCEYzpGja62EnqxPZfshjNng5ldDMW56WbdLEWs7pMTHdb+UrmcN9GMXWR8SdtKGYXU38mvMbuHK4FFgzUkx6LPTzTPWgdj3RPEFK+2VGqeKiQOg5AH/q2AX+M5QVpg9RY/cQR3ARO8fSNULCypgPJwgJRXLJZQeOhAvOCMcgXA/wuLTwsKsQMjhG4W6aF14m5njUcLDDNF8flm+WvO5ZiOoH/8NB+l2nWsvwZ/d+mpjZqwIJtk6HKSijY5A6wHTeBj0BvK+Hk/JB8oGEG6t0175Q4pXpADYT4iQHVVcOolINMDRQByTMz5RBRQvDWIjI1eut/HzCoDL+7p29ilNd5lZJKDlQeUDRyaheWIOpqoSUU6uocFuqEN1+7RG2ArycsCd0bumQ8oeFP8z0LTHMgEgHfhTlzYQ8IhOyqZ6tBHq2Dpn2xFXApnU1ivuv19jgJ7OftldQlte5RHqSjeWsnqWAbISE/o9Yt2p20h6Y16ChtnenQbwLZL0lyzsK58qS/FOfLGErAoJTkeDtsQEdn7xzFv8yzVggVYNmdUoLQB8yekhOIvqMfvTs0kP8FzAOPpfGfuM64fLfnz7kOz+c57I8ucy7z3pzvhicuH+1Wh2SGeZSa6ZRKnWmpe1hmCJRYXLz8tXAACbdfuNCOIEo0W0cOCMGyAFoTobXGuoFkXecuMhcyQ5aTJZ70aZlsmu4paHu8EjJF5nXu1iTrhprWJgLN+Pw5W2Qlw03gSTitBSY/I/zS9QckIQYI1/R4zx/juBkRvI/H+FZGzHYtjoSfwMmsROyBQY0GPF+L2pd6NIOwxj0JM+kqCveuR7QpQQS/MSe/wT8CWO/b0xiw3Pmagc3Yh6/5BSG7FNzkHLjcOSNX7BjdEBuNm8GZG27i4iBNZu8CbGZ1qcmZ4gDnpqCcDBffIClu5m5rJMsr/HNOVLMg+XVcyC9NmIDlLvVFLtgbOHPcCJZy5/LHLNLSYw6YO6NntgUh/ZPgJGWxLgkZBy3NQ8fipjU6fhPnECkWisWRyPRYdbWcqTtjpoJhEghOqKoxucm7xBsxIeBm8J/xMziC6TDv0tg0q7FRSqOi5hhBjLmylSoB5l5oyG2EfBPHZMTEwZ/ibJIjbr+HHDSZgk3NOKefjfTm+N6BXry5NMK7aYKhAd703FbzlTrisXJjlmneyupq2lzFt9nUxcp48oGKzdW/9NIOtha3prmSzT2KPVDf+lYjKUX1dpgutiH0/efLTWRz8eOZk4HxwaBqNc1UIYrbO4ohorRCFKt4RljNoXGAD+ww7AGgBkoVV839zQEdL6lUlb0qvKXJ7GVOSZL9kclIxGylmcSseRJGJgdK93e3oaqvF7KAfWr1DZMa4D+FqLhMMz7VRLLf5JRQwjs1fpJ9jl4OUf6S/Wdp1hIbWr9+uYhuPwnq/z1M5AGVjAOHjvh8Qg0aGV8/RiNupYlE1KXUsKFtJdLGWD1h3QskGmlLikhbCnSLdLQL3WE9SyOhIPn7GtS8YqliHlXzPkie273YbKnZBwj4id9s9LPKe7MTA6Aeb0YaADU0BX57HsbxK43KZsF6iyqNt/M4twFnOSQSU6liMSTHPk6Pd02Rtha6VaFbrXxuijD9MVbuWDAX1vK4q9LQ0eSsWDTZGtI6uYh6a4dhCF9xJmyJbfR7V7nzQG8/3O3cDcsR9M0RzRGCFUA00vXUA1S9QxWkqrx/uPJ3cx6yMGL66XqHfOgq5fvsEroe6rcwWvSDKgc9uPrpO+UqlG+zrV9nNO+HFOwXrtL0DvpHeLqe3o826g7Rv5L0KwtqmUAA+ZhehbQLQuYrao9O8Yj6iiQ8wO4zJVeTTfdDlD7hm+Evy37gWe64hLr6eVfu+qwa+0tzL4VXOFey2wBndhIoxFW+uUNGAxO+E3NriRQmhVSbS5SR64Zy+fVD8+GfndiWnVuNBpqWmJjomBYLqkWrRtM2ZMRw8zF4bg55/AIuc9wWGBuEYQP8Y5y1yzhJ/huLHzC5T+3+hOJF67n5rr/EqZTKjsHG7szkbRrNiAEzHBkdE9OiAejqrKzWcnHZ9et984gfCUgChZBXSwRMQKifAY8kGIm5glUhQAPg86lSM8smJ5LZFA2ZaTOz5jBtGLKvzAlt0bRDvDlMN8bb6+Dx8i9ohZ9IgcZX1AY3gCDDuhzLeLS/CK0gZB8/aBhtITVhH4UhtPixHoIQICKPWD7k/12ZAC3nfvX57j9UTlzuDwTlmwqytv1KxtRKMV0acpayIDuKlqJpxQCfzmLlpD05GsteSaaTokk0szRMF8Ye04rhalB7faeuzBerPm3+go7zFcah8TlrA1cFrVqRg3+s/YTouC99n0qfT7JJzfWgW43TzST6uw3Qnv/yr+W9ft+k2aCc+54LEpXf/IayiXn+gK9bcqJD7S3TnBKofUkLBtP8saKfSeNe559NPTvvNU66Wmy5n74d0XMACBAtRYV7ny5Hi5duA3lsLe2nhXnKT7Q8dh5tjKaVf1CmyPOfhJ/myULK/MIUTc1WgSkyjSwk0SaFkzQSIEgo0w7DDk+MqZ2cGx2dR/7HmCacBhxn1qHHtDZweDh69ybk2f1vuJIDYmGMXLA41SIt8dmrcRIhGgq3jghPbf9X+e7dTUwnbRURkapRdPfaTXpKGhYr901PwwBjo5DA9+P7+7fFDbuC1otjtnkDeXYka6VSLIyQeqtSzVPD7j0YJRLCIZGlo3mV/hLpqTKJTLLeslUu9clShY8fX8C4XjGx0qry8gl2N3s0MytK7u93bfwmp5UDWLD7CeTCR+RJ5ImFhRMwu7KwgDwBVGE91dU9QpWxABzSuWics5yvRkZHyX92znLKdNUdBIWIjrEL1C/0aghAegc9nVVNFwAz7IHzMZEnFz6eQOLrv3TAY2OIDmOhA+bMhbZlPrUaTZ2PwIy8RacxszPN8v+VMpS4faM0RHKh94m+1BL1HBgDhiIkH8I5loZpudEoTIF3VH0p98ck2Kjmg+3tYmvqfecsU5Zplm7r99WxJASYV1ifcpSiTqH4ilMavtMpZ59pyqnL+hr1lMbH+ZQTX3NKwc9JSB9RU1785CmFD/oUUiqcS+qod6azj14oRZ5C+zwGMxAULiTxuEJMIyZMw/al4GOahVnNIc3ZVU9Bs/w/vcwVDEVa0RTNIofNwvroFPy+MF3H5K3jpbx0YLzn5kbXO7TQ3YAbvcVBT18zFPIINEBFIAEkBFAAPbdvkgJMFQ8G1ANQNU0J6HoIqAGkH+3nEvYFmQftM98bbB68t952EKBHBweqXQ0CPx3D/Nb088S6G9Zr/rpRMcxqR6xOWI7UpjKdft7drbG6ubbQwulXzG9fYVfEP1D3f7f3XQ9mgoC9RyZ+Ls9EGm58Zb/W5AMni0Ic5ZoTMzWsdMLq5uuP/93+7/rOLtou4HN4Y122tIEid24irpySjkxDLqbMsQWGIvd+mu0O52RIN8ktvpf9km2Az3G7rCQct8i9h07Sh+pJE9AsvafI3SBgz3nVotJQtXmHU2xSzMEZd+PpBF2ALgFVKrPLybWbA+Gu7DnbuiWNrLMtT0QChTPLFDeXAZg9972k02Mu4fIMlzpUuEtY9Qi41KHGXsKpOi4Z8nCXMHrSi35El4hziVqkw8wxCPg8NidEb0Y97CDODM793cd8QzR1NyWW6b8ulisGZ4gdqIdvXKft9jniFHEOBF9sY77ZLETPyZCKnUrrnlhPWT9Zt8LS9Q2COLcdgm+tgyA63sJ8wHb41CmRaZjeJeAGdfTWrT//FKCCsD3Y4xjpx8tbt4cp9HNfnTdi5adPD9h+PTDol/p699eOzvT8jz5UKOf48d9+A189CJtf13DxTjZktli7G4dPtiZXe12EHcvepi+2XJxe8QbheJGXn9w2fNLd6L5NQ3zSu2UwjXXBn9Ky+ryVcrOqX6J9OYq2wwA/u9GBtH3gqycas2Y58Ow36UsslzAOFxYktzIerQMWLG6Fb/U6NppxwrFALE8RAjKf/Jk0dcxpyZ7SPISi/H5xXnJpivSZzKf07ktmR+0KutikRsHC24lQ2ZEI1K4xKHFGNnTgRPff61yds33/tpeaYznhZpzm23uB/544JpTs0875JGYuUy+anU1elClhfuJ4twM1a+JNkXLUz92CWbSrvhxUAPlfb4si2C7x9x9KLAsW2QRGV0XGYMesGZ2WnQz6qiDU0Tcf9clWqrZsDYBWIrbtgBoo1rLEQj42NmK84EbutXjbXwAE+Asmq1hdzt2MVYxu566OdNQo9Y+87u61kKy7rm6bGJzs7laH0UdN56df1tXWpqXU1AQHGr+drfj+vZVgqAVGoSei20nT3qnL/Y6HgvV9xmHQYXrz0s3TzKOZ7wqW+/MksC1sxwzyhvDWk+XeTVXet6dZYyXdgd2HtwlzvS4eW7AXO8fuoT0+0DXwHhOOg0h7t4swRaVaVtrdNeMw4jDz5ODBcNnAwC2nAadpD2Sq+ln6yoIsVmRkmz0+Qps14bgd5g9FRFIszd8r1ezlBGtySX9k2+AWYRLALF0qZ9ZFfUmuRKrF3ORAJSsqMlDby8sdZ0D9PbDGEelg7ZOkqQzCMsN8Hn96bXyX6ma2bA5tZjBDzy0zm3RbGqMaeyrrVZMOpE2cScM01oCdNrxZ4yOUstdvOX4MINgbNXrvFkOlWDaPNh2kyjvavWEDVe+gp9Jy2vdCT9Cm/y5MWbN7ABiLs7DaRG1SXmLecVeyXEQVEHhRFmCg+lANzvsBWLDbzmX1if87EFs5OhYQnpD61DnJ4HpQB0Jhv/xHOeXnj5pwn0D5+5lNu8+YSe+KGfdpdEml2gGiIoXsKO2mtVmCyTrtrspuW/5R+Z8/rLIyUYmsxq1EKhMrPh6YZveAQob9HJ7JGFV8OWN7JuRRRre2783laqH1tbPUjDMZatNr1kK1iWWa8839FvvRVfCSa4YpK8OYQUmlpUkQ9a8XBeGBRtkCw1ViJysslLEc93pTlMbAvOVx8VRE4rJi22+z82TUJ7H4E6r/hyz5qvup6dvdRc67dzkWH/x2a6n7VWt7fyo8RVtvMKQHIT118MUbEJywb/JQhcMvYgx/Ch63vtWDN1XLA1KgaF+m8j37nYUy0i/F0FPnfzyrm3EKlepW0Tp7Lb81Bf6xf15ZPP7X+MkW0qvuzfzI/gzypNuH1maz6XbMhJ3a0CvLLYDF8iujxat267qYt5ld6+wiOIg1utu6NQ4EP22o7w8wgH/wlRw/woqbFD5lt/O2NItc6G06zL2t3D4Q9opLnHPRaMFPt2xvs1i3rY/cFmDQlcPJJLY1m/yWDBqSfY5wxO3HAXcCBOls+/rKXavFcN/jR32wCI8eBYG+R4+diatdnfv6ZlwmXHidexAr+vpWIGoRjSI8BFoLCIsA1NMubBpG6ZkB3c+KKTNr5dKKzzvmOkrKxIPmm+2Bv8LcxvlwL8cLcRz++BF5Anlc6HFAuBw+Dp9w0zMd0JudN5+b+eleaFK57qvsK8+/x28bhYPQ1i5sD5ykdovtMehiMU4J/CNJAsDOfZ473HxQ7CFSU6rfSoOz/rFa5pFpgROJfM6T7YhCsFAoZFCXhocGicbSWEvMavxyDhx1DHDvcaQKCgSo+vCCLH5EiUkaDXmcgXCcRTEEpU9UapIsNjmDFflQIirV+IhEqRssUEZpcMuDrMV4FTNhiWsiiMXUmCcRoW1DFK94W7UgJbS/MfEqmnPIh1/Lio0V3LZqkOBouwWN3Fgg2CG4M4p2j963lx3PdGZHyUEExiQfeCZ5tCrcXzhmbWVsa1y9c3VTV5NOs7QgJQaw4EXn4C9XVphzEAwguUdwxblIYh5Rsljib/FECKKWeDKPQSQlLh2EHn33g5WVSaIOefSon0KJJpZW+1b9OvpeHGRWZ/tPOw7/d+ezMvYwLYrVSEiHkiSICATtpstrQQRKgxD+0YpVQbGIKiqLfklgUhYFNQKeG97qw/2RjaAijwVpYK+0ulq2Lw3UVV3LCSGW244tAbuk0wlJYc9tq107Xx3bgWDUMHkVhYJkACBX5IEIX6sjK3giqgq9m9i0Ad3EQIL/ikqiMdX0NtMtOYxlKBQGi+SbVVY0xm1JPimkmZjBVjvK8+39vmIQEkLvJlqY4Q7G3tfXwZUORE17Gc1VUCXnkF+/TgLp/NfJwXxlzt+RX78qLn07daanjbSqabVpWfOmpxQW9s/zv8fFpaR+W5+5dqBt7HXzGmEpWDXJOmhLgXXC0e+x8clpk0s2GtRbY1Zm+NZn/5TCwf554WNs90XXZawbaJ18cAcvWwkmLaXmzqPfYuNT0sb4tlQHsNl9kSs9A1XPippcSTkeL1Bn2ER/CHRdlEGvR0XZrbx7nCKIz1BH2wR+0Hk1dlF3L2WtnMT7X8p55LdvI8KeTwj6+A3tEZGrOboFj+ITYFcFFakgKJBUhStM4KPwW4Y0OSd97w7vPY4x3YUgyOBwZfpZO8+S0mGZExbeZYo+sXf4ki9Yv6gGlcL9Od3te8lZOxO7RO6sIZ69jr69eaCbTeJSTCjXS74HR//MRaXUuF33xyP+RVKLkRVt26oRekQ/VVAVxVTkvwi8/3XwdENna7A2YdVSILOm5njt8QUVB4TJaqPMEIzSza7cBM6iHu2GUumi4MSActweJS4KGb2xvIxYjt2TRJbkhvLUiEm9wwSYerW4dOqMkhkWTlXfAKFnzqwPBW7mK9bYJe+5f+xyivslMDUesTgUBPfpo4I2jOh/Kc5zb9c4pWR3FHs0STySSzYNFXs1JCxe1BDVLl0Iqfsf21ZBrym4evbflJ7x//KvAeFeh6gton2prl60Ufj//5GjRAlBP5L/oPxxBSrqS0cm4n0ynggX1XheH/Gv5kKQIA6FxbrkZT34YgqJdleWqoGr70I45433roakHZ/X5bq8Nl1lsAOuFrIG7q4Lz56/2oMX9HZeT7YUymmpjzeiQSKuIMlPWxWahE7C5if5h08gCEeAabz9YIm1kB0RZVe9zg50mWz6uzGP3g8iofjA7M2OsdPBK+QJYHR+XWBUn8aFudhf0JtZ4+sJDNiEgL+n6i+JkIl0koiUFf4jL/WvGL77Qgqh1iSaOWOR+NSUvzNvpy/Lb42ag31rbGalZogm6/ufelcvP7YY4+uEWLmfaig44Xsib9HcucigNxO6IwlHSq6sfTn2uzHz848W6W89IxHO75bZuARsikpPMmugZUEyWt3Kv4BXIvrbjTs/Lt73nfZb4hmbs4m/2fuX8LrNeOJZKgDz6uPOhinde7f3vC9uX8Ld1/m7pKgESSnJ3udnkUIXR9drarbfpQzzolPQ6cOFi4hCwXTYUupSR4nFQOeQl4ansdBoGP+favRy1f52iJfGigLRKKxO7hxNp6alOOMAQBRXW1TzGD635ol0qM/c2Uyfcci9ABVnGhnV8cyvPGsdldgCQtjbTKvGNu/O/LBdaqNr7dQxKA7Fr0BfypUq2/g8t/jUu0oEJEnI/pbHpCOc02UXX1a6iMwSft24gX4oGHEEMRizUAOjbNTuoUFeIts0Ak0AaU6ILGO9UdsGdzeDnpE84EAyuEV4iGvjVFg1MtcBRqj4dlSW0EIILkEL9iJns/s6iGGfkcjrhMAdkOxJDrMMs/po+bEzkGS0JEj7YSov7p5mzTNVS+KdzaQ/ecV6QUpDiQZSgVWp1PBeQiJUrIVimdoOmQL3lElNgoqXQBFQeHFGEhQHLctAhKPdJOqTuFv0WzjSN/q3tbgZ+sxcnDn6HBh0oX4yzz25shZqhc5sh6uAWFLyiJVdFni/0IY628FBlPR0+KdTlU4qp6tO9+4qGClccSLaASScs3u1bqPQoZ7ViBxEbk+zHqHDrknhmStMFmWWZJI4TPYYNZGZtIfIZ/oMscgpAsR/+Yh8Yj4pKiYhBJ595/cOltWtJ/VlQfNyHcFsPbLahGbbEH7C9kQg+iSDyIs8a3s2/AcIit61li094fOjpMrUUQmyN/BkY9+34X8CUwEu5Iemjrb7Xw7zi7eetU+MKa0kMc23yO1WR8LpYL2nV7rzavi3JAQHUVtV+47zLukaZwuSwSez4jiP449a32nSlV7O2mF3XyNVr2kQsTtle2OGyq6H/U8vb5qEj+aQG/8stRvxCHfqAIWKk3YIaKe7NSJtC6w+joEZSd/5MdbmUSZxJfst9oWn3E+AyiE59qDtXcSFFEby+8CgtHgRC1++J9rx5Acr2ckdJ2k3Wisb6/Ci37QVYsuo8qiOColn9OLQEvO3v4KccbYrs5JJTJYeQb79Cz5LlLOOIPm3nWISQO4NikVREVlAmZ/7Wvd99UUk9eSfB3R7nAoQtV1pJBwQeZT+fOIu8uPZw4/a7RuOIDZmeSES4RoV1ISY6ol79I5TcB5EDXmSPb2QXkD/8IY9UZ5Q8lKwBLXl3qSfi5nFP1tehfhVnvHMulrCLLlqCQRwGm+Zv9lFM88YT0+0J+H/8KgHCB5oi8QJRr9PQSl3oTFF9B8+JmtPSoWZaJ0pppQjO8MuFW+0F8dUfVG+X2DgcfmdJZqbMy9MifT5x+J3jqb3HLPZG8T2Sw/ay0obnUa2SHf1ZhFi/lOJvqbkoY6E91IVsz/t7EXysSPDMRF96F9x8dlSojRN6tPJ2KmRchR2D9FFcBrYyWKJpe+RTEK0WUxNSXlClCOr0PQH7xfp0cR/GL+yRGgSWo8qRuej8S72kgdKCwWxjpXIYJeaRSZGH5hVKslk52ZZoa1qQGVzr5fv9+MN8Bv7JybmAljWuqeU/qCSk5HgvYw0HhPzpPofJ9N2ClKqSZYCQfkvLKSU0m7q9E+1Q1XYPxD0TxhloFBJb0WMu3NiRUEJzJOxJE05iB9DVLPxfqhAs0dHvlv1cm4WosQxJzkuYTDcSuMaZTcxiNhRokgAnd6/QHxIY+oX8PCPfK+dfv415j6ThHxFwkVY+T0RYRUfv9ZCjIi0ER4alNlo2ONV8YnTjgMOt+MTpEucQDA998QaXQRTG19GS2e1LL/xAuum4huoPaSY9M3czdZPuWlRVE9rvJSoDtIG5QWpcNZShu1nh8+2js52xk8Na6AufoWVU2GzlzvoSnjauw+xDFHbaMvRcziDds6HTGcSDjl/Gl7kanHNjZkMbx2VGib0j5PNunZNBpWW6yP8xwr20fba2gJ8MjAJ/pZpjulJblmMYDlE0fZuKwbbCosLeznaXgozJqazU8/E4Y4UOD6Z0R/J7+t5SUa0BRcJZ3e/upw2WdpNN6eaMroBC44YQwKAHKMAQLAdl6YY523STj2W73wv4UQR6fk7U2f6t35Gn5mFbXXuMiHHJz94kRl+68eQPIxcIsOzB56YgHuIGgSENxnp16zVNvvJ61jbJmpYJl3OrdisTH3rDl5XBBR0GN/OUE3tdnVUyB9nkKCA0yJ9F1mYAKdf7EVM3GK7k8Clt+Bu+aQnbEidEbLcVzO6ES+wge6D+v6x4U0ZfBaZeZv/QHK+ZMOk+9071AuSV4LbSFmvbjndGhi4IIYqMe00IJFLYhjAnq10HZjd6mcQNAiwWbm5Wdi+xuC3ZRZaN/JXx2g10KTNL5PbX8orLR3hOVPr758I8dz0vH9S8alpk2mBxvqJLdUh1b85wFivhioqoDalrihXI4iScLMKdX4FU0vMyxfkqxlTC5T1UESGJhxSLzIyIXkWVUl2XEL1g9KAjOKYSVZSNz8BH2dnPwJ8OCfAx1btDlB9DTVQxDyNpPBV9pmdnpv8m4N8aj2dSkOQh8DsrE/OIg/xlEJn5P3IN4Eh9Hlf8jvQ1QRHNQX2we8KrAJ3w5Mn4DVAObgb5ieRERhr7jIkqrJzb3VrDCgP8qogcLRY5K6Fu1euEneRu6DwUVT/gVP8oqVSUrvP0o/yYKf1hgcU9IzHzBMz33N6g/XOB7bxXGBE74enp+H9RArBdvxqSBaNwjfdA9ceSFfWqUhqyDrAosLIE0bzwHsukrvf2t4xIQNjlEHYOLf3GcM8kBprtVgY8tTCBHPBHVmYtehnAO7J33feME/ObjwTcI1VSTtOXc649mxAh6KhaSgd/8NMeN/58H1PqlWh7QfkhdUKhdZNW9VAq59nJ2ayE+YZ5UPG5ieGLwgvWfqMeA4hnaXAS0D64/VP4Az46fXzlgeU7TqKhdqCottOebCVPOqpW+VZNtKiAeatAsf0AjUVtJpB5g3LJFL5T1cEVW6LOTDXT4T1HIYwoeeegoCpI7VBkf2qPHAMfv8BeRQ+9uHDMWQbdHer5wp0YlOWU8bOjIzf/l////XMOX5k/ZGdSq9LLf32cW7svA9T+BOXp0SCE6gm4F/e2WmvCSQQ5NZyoL2mU2hEvoKNwnmhEX6FNFoFYbDzWMwrjO6aaxVRPuyaDlMf1LiLNB5Z2eirRXJvN57Q1dvbRcB3g+DsSlFstJYbGA+kLv89evRfthYPArXc2Gi3vEC/ZDsgiEtNjJEtT0rcvdxk+e7E0VqMLDVREAfskv0CJxDV0Wbm/VBSWakS6l0SuHu3x3uV0PZZCCWZ90ebIavAH2bMXkdOzZJpZJJJop07gMHoTMNDa3QadN4ANT1IXujcQbSmqyvO06ALoZQn6UAQHWthcWvo7NPiQOANuxe6/ecfAnTgq9Id18inBm0n9xXdUL795Rgthsa0i0NafFtKW3JrSiswfnqYUE8k+7eh+vHlIP+gy3kiF4gZgYO0cGO05V42OR470YmIIkWS4IYJC3I8fVOMZSNDTcNbhEMu3svvRflF3lO3sQhnQmqTxhjLTWxSvMVTZnh0OKJzwmKxYO+Ntmw0UUM45muuqI0rgxYvBjKiHJNB4dwpCBLd2d7/vtpd7HwwGahBQ45V3M/J1+IxtSFbDWmATFi3snlTcEoDmGj0K/JIve+R4lc80dAApXT6Zz0U7wM5niBwyuuzmdoJ5I17HYvfil4Ydd6xZ3nhzUhRXa9X8n1eBxCiGq4Q6kR9S7ALa8C9tZ4rp5XL4TDiOvV6s2bvu6YW4Usq/mqQtad6bkJGF2VEgyhQnIGMdlXellqw3XLdbSiSnqACDfhfC4pygv3jl2EUWU7Z5Sr7BjVobYSb4qweBco5Gon2Edl+uuRelEViS/o8033sVxTFaAixLLHccd1OqwiXLBkHFNbbJSV9+iQRO3bv8M78j+gBb+NKxvnP66z3dCTnu+9NPRDBcagFYrj/zse9VmVP4oirI65UldJPJy/pjCuzDswGx5KE8a13LSMb4gELFpw/3/cdDm3ue9rs9YcQG5eF9o5j/bW85meBIv2yrKmrgJFRDmKj/71FEvuNyV1kNvU2XVJOhx9JeAsbDWIzywsYtFCrMnRgR4vXgafQFuT5L1/AyRzW4n88VodlNFMxE7emj6Z2OLICvlTCXkeiYzayPYU1TFlldFSvwwoJpxiNCIct47/ulqY02wkDi0zUzdpERBa3hIkxvVNuT4x8WddxnDnpehx5w3tZnHe4k8OiIbgaQvRaZpXvFbY+clAu/9BQ3fChHMiBd6L9N5ks1x/I/d9X8arei10Oeumu5szXAZYBjmnA2Ppgyw0beON8QuQX1A2FhYIcJrCQCau9rECHlbWJVdak66SjBvE8M+4zOvhb8GHRx7ErBLXb4QvnkO2003ivoRu2N8ZwXndNZPuFc+0fXp1+j61FFLe3FweL6Ag67IrTHxaRG2uwFKdPWQHFVtWvtrln1dgDNQ0IKO/09Dygq9iG8PQwaXNu5Xl4wHtxoofnjUJvMM8CUoO5+SaFcfGFJvnc4FQMFKvVLhnntSHgNceOtyDWII4fD0eMbhYIKBvhcIY/HXJOmDF1PmQ3uAh6aTMm72rEjyzm9RoFN2GZfk7gJwAB3qfbry08C4o9PsuI5jBgcaBJIELC4OBHR3SwvpBD7l5baDf/6PkR1Ml1RGe2exURbo5/lu/sZZuFa5uD757fzdsXrnnuuxdMjma88fN7kxbkEJDqb2Ybxv9jvDan+FPSoEJ6Vd91vxtUvW4E+HfsNidP7lbjBf+KedWetu621YE8MewEeq/+vu/b0xEt6pb7LZR2mJGajgZ880M8dHJ6qLfn1yDwmcnqZqB7kPfPCYXHIdP4Wy9NUT3EEzEW+xHtC5v2//eFuP/+cmQMJh8+AcMRGGTUJf1+EEJraIWzYZTy28MnLXTmM0p59PB2msXoxx+QZ/a/sfmppxX3bO7x4/ZN1RIoNRWIgUQlCcR7JUAsPRXub7ei0JjaaEEAPZb6xHHCaYZCnXMadXpCpd52GjmfZAfNKVZ9Wzn1Ll1qoq0cQ9FwYtlxbBAtdSzqivCaw8BMBkJTX6+BiFJGaBgRmMJv/OPH54+g9U1ifWKkDkVvYGsDpDHUZ6KHnRcghOqIpvsRbqeHDEOn3SLuX+2r53bf0kPwzHLA8pnAw/K+W/x37KsI1BmcAXcGFTGg5NJbqAPUFvp9cLuswQpS7DY5vbnmBRnSW/TfHuN/pccFjFNuXIbeoYXBBVxGi4OewXVr2BJTgMYujWZdSLFdcvvKtnskeosEXFcjTVeq6Eu+qwchPd2N2wIGBieAQOm4u1eV351Q2CXjB6538pt+8r7K+FGW0nuvMCLberVjobosnB5tO6XczM+/2dOPVlWNsrvZEgDCbpoIuMl64muBMJySwfDlpkOuMP7PH7Hkhvn7z49Nr+2/Kv6PU+uHKKMC1IbzDvF4wJtmeQNelneWgP4AfAehBwDRttmfKeMXWwkqjRa/v6KvlqA0qL9e7LhO0QgHkM3IAS7dGB4Fxnoh/vKBzXOU8PH0BcwRysSN4VSzBmS+h3RIYgbmHNh92aEh2FgFHMdt45NfPc+QzZx42S7u+HzPHa6wUJhXovcfwLBqprtqB+rrhx/kmEe+/UeqQsn4amxu6iK3bbGRu+gboMLmrgKqUiEk8sBCc7thYDTZoyi5f3BBiFRxaAJNQWl6fVqwUMcAEUtE2fq9y2ipaRQVBedH8CyalvoD/dzNU7rYJv3xFNCYR9qtzzFgfNe+br8WOazfcXN3e+YwuYcOkG3VjYBfo25c4lLhWu1a4SIZN6y6yxkLK9pRiw6WRII4U9olMS5GHcRV4w6iJL3gtLfqHNQxOjjV5L5jP5zS4EhiK59Kd3gsCwVRwqbzZ6cCrG/84pP3JMwH3+EqXL5ft5ufT5VSEQd19GPf1iGsTTDYD9tqbV+DpaCfJWX1gPcYQV9jXDNeYNJkSaCfu7UZeTyXKJM5Kj7v95RTx7adFzaBKAmf2NeVrq6fDozm2TJIRgFve6TlFE2xxUax1S4ZE8u3UHJUca5ptACpF2WSW6nNC9eG52krT37myC675DZRZD050lb+DtSXBmnb/tgkywk+pJYDnCDe7sUkBnnInJUO3sJuFvU7LmOTQhfwB14sj7MX2Y/h8UZ5ebQskjUX6xFFUD+5ruQ/+TLIHQevZRVhbh23tJNNQ6+Y5tas+VoNjfJNMGuKDMx4cmtXA/YB24+Ku2qZdO8BHJD2rvaSxt/1E6r3c5cnZc88z0GrIFcJJ4GyKV5UnjEk7vFKfwsmufbwtoWZx9POTTKL5MtcSt4bYErIwSTE132kTybxbnbkRZ/3EI6TFMOC9ER02QiGMXEORLBhQeAgc6Q7QvnpnmnMygBXW07yRzEmTAcEnFKbqtc8lg2chHiu/5Pfl/rOutLrOMCVPRU66TZpu9CcHnngXBFblDLXHHWg+0p4XfQmYCAlCNLoFDiebubEjhsv9ej0MJxSwiREhAseHjNwg/i4gwN+0jnazisISAG9z3IgHHMsDD7cdJIvxDfdsR3P1s6iwzLZdz2N9jDwMO2KDy0Q7HSlFY6ECOfD3JkOloDUOkubJog37g66+MsbMenqid3syX1B4RNmDtAbmvmRVf1j2rkTQqbEDyU+68sS/RTqzIZTvugF+jl6uTZ23OlVG23l5M5hJNQ0mYl82yJMY6iAzpPMuCSqv22TiATxbX/R4nMCbW9NphE60LzL6BJvP+4yThA/R+oLCrmzZIg/Q/n+7n04JNXuNnXRjfrwkhQ5ZmpB0MQqAQ70uIpnxmygIA/09gE8c9LGMWbc5xE5xJEiaU6FZJCe2lzPRKNLjRIi1kdgKG3D/pvXgUiiUzzOxXX0DdH2Nsp/+Me2qce4uY0+IWK0ae5ANY0O94H6zSIUL7fj+m7j4ZekpofyJkmqhNiSHrR9NoxBcKklxJsR7yeR1dFD1ysfVbZRtuKvYVn6jQl2Pa1u4/1qD2QkiHdLcRWV9PXxjKQt8+sGSDomSomslSIOGPqIA/R5PtYImrcaC3Y0iGlMH3P1itsQka2VCWv2OtBAfKBfMD0E8VyEj3bzY8Dob+6OvpD/mzAUwDd1HPiKBDzz8kduCCA1fmybvXKohuz/E7Xt/NqLQ3wwQ/GJ6MjbD9Do8Mj+K0bH8wE4mkBmaP/YBVywiwD4mnkfeGYTGUDe3UnARwxaUNT3bdOUSL2KAEvg2M/AsPEjLAcn67r7ORAI/Jywwvy83LR6fT4MUw0BZUcBqlsx8CFUl3wEsgs+jOo9B+l+56OY+c9HowbYx1MHBpNDAqcwolpIQAsxbL+gi7VUsXU6bfqD/Sg0blfiZ/7HmLomvKQy0fWfaBgibOZ7f12aQhKr4WNwbCjFgov9gtej6PK3p/QWrY1H5vpwggZoIYbtFr6ssrX01tcp9sD/YD8KDcZOly/7H2PqJx5eHp9T+D75lmqnuhjneX9dUE0hjWWr58gHqoZSLDi92i94PQqH6m9PuytLaflH+ZH6qYGvfbvcNibL/0LBFGXZ2nkmeVe3x+vzA4gw+ZUMfVGhU1UqbazzQRjFSZrlRVnVTdv1wzjNy7rtx3ndz/v9AAjBP1aHn/mLxLONifSzNllxvCBKb2KWp2q68Twxettxf3b0AxSEUZykWV6UVd20XT+M07ys236c1/283w+AEIygGE6QFM2wHC+Ikqy8soeqG8/i3R3bcT0/CKM4SbO8KKu6abt+GKd5+YOw7u72h+PpfLne8AQiiUyh0ugMJovN4fL4AqFI7Pml25LJtbSv7tJB/tBMwRuzudgO1ByO07HlupMvSmhRD/15p/Xy3EgK4ySTuOEMGwFlnmxMMQiWMqEVQcaeaaMJkGXLsC7RmyVxI7Z6MM1fTrQoy++ic8ieSqsOSV/d8CmXp100JloyZFxpCH8cCFF9tPrMeIutGbpuo/tkB4J3Wl6oZ5jlk+ZsTNCcGr39RuF9xv7h1nxmweX15K+vJLegUOlwrvAZpqJ9aMKNd9OSb0O8UwvCKXhWWTKu+6c4Xjc79AOLJibjVAsaLlxwPNufYt4Re7a3FFttkQ2GsFyK6WbGWnMkFEBjBFBjm7AurDwns6iciBeuZOLjrlWpFu/gQ5vLXLxETJ/2LucldX+WyrJkeb5I48Nh8+ibQwqTj8ioOX1Sw4e6pLSiHJJIR7GdGrTnl93FqqwZSvFCOc6jMR6N5dRztiZcBXI4EOWu5pTdETV8r4xYPcYOqZ0M1Iz6PB8yFWBZcrN216hjIKir58345V60wkPuUoEinHFzwO7eDs2JsCdpqjIpZJ3zAr9r1TVRWbjEECDR7iMFSxH1k8bLJxVEHZgyUgCZBj6JAsu4Fawee5s5HT6ZfECmdIqKegsoOglC/0zJQAAFo07pPAWouhaIFniwH2U7ErVzgYyBSKpwE/LGq2t3rEQDYlJfXeokwGbtRWMagrd5S3FMmtEvfPV0RttXVhP00QgyNZWmULkKPDVwgXrMGUa6Nqdh0qBCyjYstQkmtAAjAXvZgIZJBi7b7v2FhBKtExYJ5a4Hu+d1oxRq/iK2eki0oPeEj1OWneh3JryGGVrlvdqOpOqOwGz6+CWn3u/T/a3IJ3FBevI1zIBdukX8BL4ds1y7rUtSRbnjDP1etwvSN1HUdbC5r8ddUqyiwiFBmxNv9RpmfXt10aJDAFX5oH5CNdHabugdixB1rUtLYdnmKXwcTy3yTOLZGQJzetKitZgpIPjoLzMF1Ton0NRLyhu6dNyiQUuG6GMlWO60RaOWzTX67usKiuFECGN5oxXp5rRsZAG14Eyuzsqi0lcsIXbhZXfE6EcNZIbQMe0oYAQgasNMBz3b7BUkHTFTg0RHoQhMlFZGGU/ejdeMfwpLflT1HFiEd7znbVfdav94mdP3O1MIyQDLftKTl4cVRG0qHVMl62E/A27D/FIprv6AhPMnZyCtkyiY2+6pcPhsG04nYIZDR726wQ2tPPykY/qi72XWgLJd/QA7GNW5ClDzf93Ax5/xDwF6LH+Ojcb7g0HTgZkhDLg1su2qLt5SbLB98Sv0n7jS8XkU1BIX6/wZHi1U+twvu9VQ3N3+DwAAAA==')\n            format('woff2'),\n        url('//at.alicdn.com/t/font_1529455_k4s6di1d1.woff?t=1596960292384') format('woff'),\n        url('//at.alicdn.com/t/font_1529455_k4s6di1d1.ttf?t=1596960292384') format('truetype'),\n        /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */\n            url('//at.alicdn.com/t/font_1529455_k4s6di1d1.svg?t=1596960292384#iconfont') format('svg');\n}\n\n/* #endif */\n\n.u-iconfont {\n    position: relative;\n    display: flex;\n    font: normal normal normal 14px/1 'uicon-iconfont';\n    font-size: inherit;\n    text-rendering: auto;\n    -webkit-font-smoothing: antialiased;\n    -moz-osx-font-smoothing: grayscale;\n}\n\n.u-iconfont::before {\n    display: flex;\n    align-items: center;\n}\n\n.uicon-en:before {\n    content: '\\e70a';\n}\n\n.uicon-zh:before {\n    content: '\\e692';\n}\n\n.uicon-level:before {\n    content: '\\e693';\n}\n\n.uicon-woman:before {\n    content: '\\e69c';\n}\n\n.uicon-man:before {\n    content: '\\e697';\n}\n\n.uicon-column-line:before {\n    content: '\\e68e';\n}\n\n.uicon-empty-page:before {\n    content: '\\e627';\n}\n\n.uicon-empty-data:before {\n    content: '\\e62f';\n}\n\n.uicon-empty-car:before {\n    content: '\\e602';\n}\n\n.uicon-empty-order:before {\n    content: '\\e639';\n}\n\n.uicon-empty-address:before {\n    content: '\\e646';\n}\n\n.uicon-empty-message:before {\n    content: '\\e6a9';\n}\n\n.uicon-empty-search:before {\n    content: '\\e664';\n}\n\n.uicon-empty-favor:before {\n    content: '\\e67c';\n}\n\n.uicon-empty-coupon:before {\n    content: '\\e682';\n}\n\n.uicon-empty-history:before {\n    content: '\\e684';\n}\n\n.uicon-empty-permission:before {\n    content: '\\e686';\n}\n\n.uicon-empty-news:before {\n    content: '\\e687';\n}\n\n.uicon-empty-wifi:before {\n    content: '\\e688';\n}\n\n.uicon-empty-list:before {\n    content: '\\e68b';\n}\n\n.uicon-arrow-left-double:before {\n    content: '\\e68c';\n}\n\n.uicon-arrow-right-double:before {\n    content: '\\e68d';\n}\n\n.uicon-red-packet:before {\n    content: '\\e691';\n}\n\n.uicon-red-packet-fill:before {\n    content: '\\e690';\n}\n\n.uicon-order:before {\n    content: '\\e68f';\n}\n\n.uicon-nav-back-arrow:before {\n    content: '\\e67f';\n}\n\n.uicon-nav-back:before {\n    content: '\\e683';\n}\n\n.uicon-checkbox-mark:before {\n    content: '\\e6a8';\n}\n\n.uicon-arrow-up-fill:before {\n    content: '\\e6b0';\n}\n\n.uicon-arrow-down-fill:before {\n    content: '\\e600';\n}\n\n.uicon-backspace:before {\n    content: '\\e67b';\n}\n\n.uicon-android-circle-fill:before {\n    content: '\\e67e';\n}\n\n.uicon-android-fill:before {\n    content: '\\e67d';\n}\n\n.uicon-question:before {\n    content: '\\e715';\n}\n\n.uicon-pause:before {\n    content: '\\e8fa';\n}\n\n.uicon-close:before {\n    content: '\\e685';\n}\n\n.uicon-volume-up:before {\n    content: '\\e633';\n}\n\n.uicon-volume-off:before {\n    content: '\\e644';\n}\n\n.uicon-info:before {\n    content: '\\e653';\n}\n\n.uicon-error:before {\n    content: '\\e6d3';\n}\n\n.uicon-lock-opened-fill:before {\n    content: '\\e974';\n}\n\n.uicon-lock-fill:before {\n    content: '\\e979';\n}\n\n.uicon-lock:before {\n    content: '\\e97a';\n}\n\n.uicon-photo-fill:before {\n    content: '\\e98b';\n}\n\n.uicon-photo:before {\n    content: '\\e98d';\n}\n\n.uicon-account-fill:before {\n    content: '\\e614';\n}\n\n.uicon-minus-people-fill:before {\n    content: '\\e615';\n}\n\n.uicon-plus-people-fill:before {\n    content: '\\e626';\n}\n\n.uicon-account:before {\n    content: '\\e628';\n}\n\n.uicon-thumb-down-fill:before {\n    content: '\\e726';\n}\n\n.uicon-thumb-down:before {\n    content: '\\e727';\n}\n\n.uicon-thumb-up-fill:before {\n    content: '\\e72f';\n}\n\n.uicon-thumb-up:before {\n    content: '\\e733';\n}\n\n.uicon-person-delete-fill:before {\n    content: '\\e66a';\n}\n\n.uicon-cut:before {\n    content: '\\e948';\n}\n\n.uicon-fingerprint:before {\n    content: '\\e955';\n}\n\n.uicon-home-fill:before {\n    content: '\\e964';\n}\n\n.uicon-home:before {\n    content: '\\e965';\n}\n\n.uicon-hourglass-half-fill:before {\n    content: '\\e966';\n}\n\n.uicon-hourglass:before {\n    content: '\\e967';\n}\n\n.uicon-lock-open:before {\n    content: '\\e973';\n}\n\n.uicon-integral-fill:before {\n    content: '\\e703';\n}\n\n.uicon-integral:before {\n    content: '\\e704';\n}\n\n.uicon-coupon:before {\n    content: '\\e8ae';\n}\n\n.uicon-coupon-fill:before {\n    content: '\\e8c4';\n}\n\n.uicon-kefu-ermai:before {\n    content: '\\e656';\n}\n\n.uicon-scan:before {\n    content: '\\e662';\n}\n\n.uicon-rmb:before {\n    content: '\\e608';\n}\n\n.uicon-rmb-circle-fill:before {\n    content: '\\e657';\n}\n\n.uicon-rmb-circle:before {\n    content: '\\e677';\n}\n\n.uicon-gift:before {\n    content: '\\e65b';\n}\n\n.uicon-gift-fill:before {\n    content: '\\e65c';\n}\n\n.uicon-bookmark-fill:before {\n    content: '\\e63b';\n}\n\n.uicon-zhuanfa:before {\n    content: '\\e60b';\n}\n\n.uicon-eye-off-outline:before {\n    content: '\\e62b';\n}\n\n.uicon-eye-off:before {\n    content: '\\e648';\n}\n\n.uicon-pause-circle:before {\n    content: '\\e643';\n}\n\n.uicon-play-circle:before {\n    content: '\\e647';\n}\n\n.uicon-pause-circle-fill:before {\n    content: '\\e654';\n}\n\n.uicon-play-circle-fill:before {\n    content: '\\e655';\n}\n\n.uicon-grid:before {\n    content: '\\e673';\n}\n\n.uicon-play-right:before {\n    content: '\\e610';\n}\n\n.uicon-play-left:before {\n    content: '\\e66d';\n}\n\n.uicon-calendar:before {\n    content: '\\e66e';\n}\n\n.uicon-rewind-right:before {\n    content: '\\e66f';\n}\n\n.uicon-rewind-left:before {\n    content: '\\e671';\n}\n\n.uicon-skip-forward-right:before {\n    content: '\\e672';\n}\n\n.uicon-skip-back-left:before {\n    content: '\\e674';\n}\n\n.uicon-play-left-fill:before {\n    content: '\\e675';\n}\n\n.uicon-play-right-fill:before {\n    content: '\\e676';\n}\n\n.uicon-grid-fill:before {\n    content: '\\e678';\n}\n\n.uicon-rewind-left-fill:before {\n    content: '\\e679';\n}\n\n.uicon-rewind-right-fill:before {\n    content: '\\e67a';\n}\n\n.uicon-pushpin:before {\n    content: '\\e7e3';\n}\n\n.uicon-star:before {\n    content: '\\e65f';\n}\n\n.uicon-star-fill:before {\n    content: '\\e669';\n}\n\n.uicon-server-fill:before {\n    content: '\\e751';\n}\n\n.uicon-server-man:before {\n    content: '\\e6bc';\n}\n\n.uicon-edit-pen:before {\n    content: '\\e612';\n}\n\n.uicon-edit-pen-fill:before {\n    content: '\\e66b';\n}\n\n.uicon-wifi:before {\n    content: '\\e667';\n}\n\n.uicon-wifi-off:before {\n    content: '\\e668';\n}\n\n.uicon-file-text:before {\n    content: '\\e663';\n}\n\n.uicon-file-text-fill:before {\n    content: '\\e665';\n}\n\n.uicon-more-dot-fill:before {\n    content: '\\e630';\n}\n\n.uicon-minus:before {\n    content: '\\e618';\n}\n\n.uicon-minus-circle:before {\n    content: '\\e61b';\n}\n\n.uicon-plus:before {\n    content: '\\e62d';\n}\n\n.uicon-plus-circle:before {\n    content: '\\e62e';\n}\n\n.uicon-minus-circle-fill:before {\n    content: '\\e652';\n}\n\n.uicon-plus-circle-fill:before {\n    content: '\\e661';\n}\n\n.uicon-email:before {\n    content: '\\e611';\n}\n\n.uicon-email-fill:before {\n    content: '\\e642';\n}\n\n.uicon-phone:before {\n    content: '\\e622';\n}\n\n.uicon-phone-fill:before {\n    content: '\\e64f';\n}\n\n.uicon-clock:before {\n    content: '\\e60f';\n}\n\n.uicon-car:before {\n    content: '\\e60c';\n}\n\n.uicon-car-fill:before {\n    content: '\\e636';\n}\n\n.uicon-warning:before {\n    content: '\\e694';\n}\n\n.uicon-warning-fill:before {\n    content: '\\e64d';\n}\n\n.uicon-search:before {\n    content: '\\e62a';\n}\n\n.uicon-baidu-circle-fill:before {\n    content: '\\e680';\n}\n\n.uicon-baidu:before {\n    content: '\\e681';\n}\n\n.uicon-facebook:before {\n    content: '\\e689';\n}\n\n.uicon-facebook-circle-fill:before {\n    content: '\\e68a';\n}\n\n.uicon-qzone:before {\n    content: '\\e695';\n}\n\n.uicon-qzone-circle-fill:before {\n    content: '\\e696';\n}\n\n.uicon-moments-circel-fill:before {\n    content: '\\e69a';\n}\n\n.uicon-moments:before {\n    content: '\\e69b';\n}\n\n.uicon-qq-circle-fill:before {\n    content: '\\e6a0';\n}\n\n.uicon-qq-fill:before {\n    content: '\\e6a1';\n}\n\n.uicon-weibo:before {\n    content: '\\e6a4';\n}\n\n.uicon-weibo-circle-fill:before {\n    content: '\\e6a5';\n}\n\n.uicon-taobao:before {\n    content: '\\e6a6';\n}\n\n.uicon-taobao-circle-fill:before {\n    content: '\\e6a7';\n}\n\n.uicon-twitter:before {\n    content: '\\e6aa';\n}\n\n.uicon-twitter-circle-fill:before {\n    content: '\\e6ab';\n}\n\n.uicon-weixin-circle-fill:before {\n    content: '\\e6b1';\n}\n\n.uicon-weixin-fill:before {\n    content: '\\e6b2';\n}\n\n.uicon-zhifubao-circle-fill:before {\n    content: '\\e6b8';\n}\n\n.uicon-zhifubao:before {\n    content: '\\e6b9';\n}\n\n.uicon-zhihu:before {\n    content: '\\e6ba';\n}\n\n.uicon-zhihu-circle-fill:before {\n    content: '\\e709';\n}\n\n.uicon-list:before {\n    content: '\\e650';\n}\n\n.uicon-list-dot:before {\n    content: '\\e616';\n}\n\n.uicon-setting:before {\n    content: '\\e61f';\n}\n\n.uicon-bell:before {\n    content: '\\e609';\n}\n\n.uicon-bell-fill:before {\n    content: '\\e640';\n}\n\n.uicon-attach:before {\n    content: '\\e632';\n}\n\n.uicon-shopping-cart:before {\n    content: '\\e621';\n}\n\n.uicon-shopping-cart-fill:before {\n    content: '\\e65d';\n}\n\n.uicon-tags:before {\n    content: '\\e629';\n}\n\n.uicon-share:before {\n    content: '\\e631';\n}\n\n.uicon-question-circle-fill:before {\n    content: '\\e666';\n}\n\n.uicon-question-circle:before {\n    content: '\\e625';\n}\n\n.uicon-error-circle:before {\n    content: '\\e624';\n}\n\n.uicon-checkmark-circle:before {\n    content: '\\e63d';\n}\n\n.uicon-close-circle:before {\n    content: '\\e63f';\n}\n\n.uicon-info-circle:before {\n    content: '\\e660';\n}\n\n.uicon-md-person-add:before {\n    content: '\\e6e4';\n}\n\n.uicon-md-person-fill:before {\n    content: '\\e6ea';\n}\n\n.uicon-bag-fill:before {\n    content: '\\e617';\n}\n\n.uicon-bag:before {\n    content: '\\e619';\n}\n\n.uicon-chat-fill:before {\n    content: '\\e61e';\n}\n\n.uicon-chat:before {\n    content: '\\e620';\n}\n\n.uicon-more-circle:before {\n    content: '\\e63e';\n}\n\n.uicon-more-circle-fill:before {\n    content: '\\e645';\n}\n\n.uicon-volume:before {\n    content: '\\e66c';\n}\n\n.uicon-volume-fill:before {\n    content: '\\e670';\n}\n\n.uicon-reload:before {\n    content: '\\e788';\n}\n\n.uicon-camera:before {\n    content: '\\e7d7';\n}\n\n.uicon-heart:before {\n    content: '\\e7df';\n}\n\n.uicon-heart-fill:before {\n    content: '\\e851';\n}\n\n.uicon-minus-square-fill:before {\n    content: '\\e855';\n}\n\n.uicon-plus-square-fill:before {\n    content: '\\e856';\n}\n\n.uicon-pushpin-fill:before {\n    content: '\\e86e';\n}\n\n.uicon-camera-fill:before {\n    content: '\\e870';\n}\n\n.uicon-setting-fill:before {\n    content: '\\e872';\n}\n\n.uicon-google:before {\n    content: '\\e87a';\n}\n\n.uicon-ie:before {\n    content: '\\e87b';\n}\n\n.uicon-apple-fill:before {\n    content: '\\e881';\n}\n\n.uicon-chrome-circle-fill:before {\n    content: '\\e885';\n}\n\n.uicon-github-circle-fill:before {\n    content: '\\e887';\n}\n\n.uicon-IE-circle-fill:before {\n    content: '\\e889';\n}\n\n.uicon-google-circle-fill:before {\n    content: '\\e88a';\n}\n\n.uicon-arrow-down:before {\n    content: '\\e60d';\n}\n\n.uicon-arrow-left:before {\n    content: '\\e60e';\n}\n\n.uicon-map:before {\n    content: '\\e61d';\n}\n\n.uicon-man-add-fill:before {\n    content: '\\e64c';\n}\n\n.uicon-tags-fill:before {\n    content: '\\e651';\n}\n\n.uicon-arrow-leftward:before {\n    content: '\\e601';\n}\n\n.uicon-arrow-rightward:before {\n    content: '\\e603';\n}\n\n.uicon-arrow-downward:before {\n    content: '\\e604';\n}\n\n.uicon-arrow-right:before {\n    content: '\\e605';\n}\n\n.uicon-arrow-up:before {\n    content: '\\e606';\n}\n\n.uicon-arrow-upward:before {\n    content: '\\e607';\n}\n\n.uicon-bookmark:before {\n    content: '\\e60a';\n}\n\n.uicon-eye:before {\n    content: '\\e613';\n}\n\n.uicon-man-delete:before {\n    content: '\\e61a';\n}\n\n.uicon-man-add:before {\n    content: '\\e61c';\n}\n\n.uicon-trash:before {\n    content: '\\e623';\n}\n\n.uicon-error-circle-fill:before {\n    content: '\\e62c';\n}\n\n.uicon-calendar-fill:before {\n    content: '\\e634';\n}\n\n.uicon-checkmark-circle-fill:before {\n    content: '\\e635';\n}\n\n.uicon-close-circle-fill:before {\n    content: '\\e637';\n}\n\n.uicon-clock-fill:before {\n    content: '\\e638';\n}\n\n.uicon-checkmark:before {\n    content: '\\e63a';\n}\n\n.uicon-download:before {\n    content: '\\e63c';\n}\n\n.uicon-eye-fill:before {\n    content: '\\e641';\n}\n\n.uicon-mic-off:before {\n    content: '\\e649';\n}\n\n.uicon-mic:before {\n    content: '\\e64a';\n}\n\n.uicon-info-circle-fill:before {\n    content: '\\e64b';\n}\n\n.uicon-map-fill:before {\n    content: '\\e64e';\n}\n\n.uicon-trash-fill:before {\n    content: '\\e658';\n}\n\n.uicon-volume-off-fill:before {\n    content: '\\e659';\n}\n\n.uicon-volume-up-fill:before {\n    content: '\\e65a';\n}\n\n.uicon-share-fill:before {\n    content: '\\e65e';\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/index.scss",
    "content": "// 引入公共基础类\n@import './libs/css/style.theme.scss';\n@import './libs/css/common.scss';\n@import './libs/css/color.scss';\n\n// 非nvue的样式\n/* #ifndef APP-NVUE */\n@import './libs/css/style.vue.scss';\n/* #endif */\n\n// nvue的特有样式\n/* #ifdef APP-NVUE */\n@import './libs/css/style.nvue.scss';\n/* #endif */\n\n// 小程序特有的样式\n/* #ifdef MP */\n@import './libs/css/style.mp.scss';\n/* #endif */\n\n// H5特有的样式\n/* #ifdef H5 */\n@import './libs/css/style.h5.scss';\n/* #endif */\n\n@import './libs/css/style.components.scss';\n"
  },
  {
    "path": "src/uni_modules/uview-pro/index.ts",
    "content": "import { $u, type RequestOptions, initTheme, configProvider } from './libs';\nimport type { UViewProOptions, Theme } from './types/global';\nimport { defaultThemes } from './libs/config/theme-tokens';\nimport { setConfig } from './libs/config/config';\n\ndeclare const uni: {\n    [key: string]: any;\n    $u?: typeof $u;\n    createSelectorQuery: () => any;\n    hideLoading: () => void;\n    showLoading: (options: any) => void;\n    request: (options: RequestOptions) => any;\n};\n\n// $u挂载到uni对象上\nconst install = (app: any, options?: UViewProOptions): void => {\n    try {\n        if (options) {\n            // 配置主题：统一使用 useTheme 的 initTheme 初始化，避免重复初始化\n            if (options?.theme) {\n                const optTheme = options.theme as any;\n                // 1.如果是数组，则为多主题配置\n                if (Array.isArray(optTheme)) {\n                    initTheme(optTheme);\n                } else if (typeof optTheme === 'object' && optTheme.themes) {\n                    // 2.如果为对象且有themes，则为多主题配置+设置默认主题\n                    initTheme(\n                        optTheme.themes,\n                        {\n                            defaultTheme: optTheme.defaultTheme,\n                            defaultDarkMode: optTheme.defaultDarkMode\n                        },\n                        optTheme.isForce\n                    );\n                } else {\n                    // 3.兼容之前只有一套样式的情况,需要覆盖默认主题，默认系统主题（uviewpro）\n                    const defaultTheme = defaultThemes[0];\n                    if (defaultTheme) {\n                        // 创建新主题对象，用用户的 theme 覆盖默认主题的 color\n                        const mergedTheme: Theme = {\n                            ...defaultTheme,\n                            color: {\n                                ...defaultTheme.color,\n                                ...optTheme\n                            }\n                        };\n                        // 初始化主题（只包含覆盖后的默认主题）\n                        initTheme([mergedTheme], defaultTheme.name);\n                    }\n                }\n            } else {\n                // 默认初始化系统主题\n                initTheme();\n            }\n            // 初始化国际化（如果提供 options.locale 或使用内置语言包）\n            try {\n                // options.locale 可以是 string（默认语言名） | any[]（locale 列表） | { locales: any[], defaultLocale?: string }\n                if (options?.locale) {\n                    const optLocale: any = options.locale as any;\n                    if (typeof optLocale === 'string') {\n                        configProvider.initLocales(undefined, optLocale);\n                    } else if (Array.isArray(optLocale)) {\n                        configProvider.initLocales(optLocale);\n                    } else if (optLocale && typeof optLocale === 'object') {\n                        configProvider.initLocales(optLocale.locales, optLocale.defaultLocale, optLocale.isForce);\n                    } else {\n                        configProvider.initLocales();\n                    }\n                } else {\n                    // 无 locale 配置，仍然初始化内置语言包以保证可用\n                    configProvider.initLocales();\n                }\n            } catch (e) {\n                console.error('[install locales] Error:', e);\n            }\n            // 设置调试模式\n            setConfig({\n                debugMode: options?.debugMode ?? false\n            });\n        } else {\n            // 默认初始化系统主题\n            initTheme();\n            // 默认初始化内置语言包以保证可用\n            configProvider.initLocales();\n        }\n    } catch (error) {\n        console.error('[install options] Error:', error);\n    }\n    uni.$u = $u;\n    // 可扩展更多配置项\n    app.config.globalProperties.$u = $u;\n};\n\nexport default {\n    install\n};\n\nexport * from './libs';\n\nexport type { UViewProOptions };\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/config/color.ts",
    "content": "import { reactive } from 'vue';\nimport { lightPalette } from './theme-tokens';\nimport type { ThemeColor } from '../../types/global';\n\n// 使用 reactive 包装颜色对象，使其在运行时可被响应式读取与更新\n// 这个对象会被 configProvider 在主题切换时更新\nexport const color = reactive<ThemeColor>({ ...lightPalette });\n\nexport default color;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/config/config.ts",
    "content": "/**\n * 组件库配置项类型定义\n */\nimport { reactive } from 'vue';\nimport { version } from '../../package.json';\nimport type { DarkMode, DebugMode } from '../../types/global';\n\nexport type AppConfig = {\n    /** 版本号 */\n    v: string;\n    /** 版本号（冗余字段） */\n    version: string;\n    /** 主题名称列表 */\n    type: string[];\n    /** 默认主题名称 */\n    defaultTheme: string;\n    /** 默认暗黑主题 */\n    defaultDarkMode: DarkMode;\n    /** 默认语言 */\n    defaultLocale: string;\n    /** 是否开启调试模式 */\n    debugMode?: boolean | DebugMode | DebugMode[];\n};\n\nexport const config = reactive<AppConfig>({\n    v: version,\n    version: version,\n    // 主题名称\n    type: ['primary', 'success', 'info', 'error', 'warning'],\n    // 默认为官方主题名称\n    defaultTheme: 'uviewpro',\n    // 默认为亮色模式\n    defaultDarkMode: 'light',\n    // 默认为中文\n    defaultLocale: 'zh-CN',\n    // 默认不开启调试模式\n    debugMode: false\n});\n\nexport const isDebugMode = (debug: DebugMode = 'log'): boolean => {\n    if (config.debugMode === false) return false;\n    if (config.debugMode === true) return true;\n    if (Array.isArray(config.debugMode)) return config.debugMode.includes(debug);\n    return config.debugMode === debug;\n};\n\nexport const setConfig = (options: Partial<AppConfig>) => {\n    try {\n        Object.keys(options).forEach(key => {\n            if (key in config) {\n                (config as any)[key] = options[key as keyof AppConfig];\n            }\n        });\n    } catch (e) {\n        if (isDebugMode('error')) console.error('Failed to set config:', e);\n    }\n};\n\nexport default config;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/config/theme-tokens.ts",
    "content": "import type { Theme, ThemeColor } from '../../types/global';\nimport config from './config';\n\nexport const lightPalette: ThemeColor = {\n    primary: '#2979ff',\n    primaryDark: '#2b85e4',\n    primaryDisabled: '#a0cfff',\n    primaryLight: '#ecf5ff',\n    success: '#19be6b',\n    successDark: '#18b566',\n    successDisabled: '#71d5a1',\n    successLight: '#dbf1e1',\n    warning: '#ff9900',\n    warningDark: '#f29100',\n    warningDisabled: '#fcbd71',\n    warningLight: '#fdf6ec',\n    error: '#fa3534',\n    errorDark: '#dd6161',\n    errorDisabled: '#fab6b6',\n    errorLight: '#fef0f0',\n    info: '#909399',\n    infoDark: '#82848a',\n    infoDisabled: '#c8c9cc',\n    infoLight: '#f4f4f5',\n    whiteColor: '#ffffff',\n    blackColor: '#000000',\n    mainColor: '#303133',\n    contentColor: '#606266',\n    tipsColor: '#909399',\n    lightColor: '#c0c4cc',\n    borderColor: '#dcdfe6',\n    dividerColor: '#e4e7ed',\n    maskColor: 'rgba(0, 0, 0, 0.4)',\n    shadowColor: 'rgba(0, 0, 0, 0.1)',\n    bgColor: '#f3f4f6',\n    bgWhite: '#ffffff',\n    bgGrayLight: '#f1f1f1',\n    bgGrayDark: '#2f343c',\n    bgBlack: '#000000'\n};\n\nexport const darkPalette: ThemeColor = {\n    primary: '#8ab4ff',\n    primaryDark: '#5f8dff',\n    primaryDisabled: '#3d4f74',\n    primaryLight: '#1d273f',\n    success: '#4ade80',\n    successDark: '#1f9d57',\n    successDisabled: '#2f4d3d',\n    successLight: '#10291f',\n    warning: '#fbbf24',\n    warningDark: '#c88f00',\n    warningDisabled: '#4a3b17',\n    warningLight: '#2b1f05',\n    error: '#ff6b6b',\n    errorDark: '#d83a3a',\n    errorDisabled: '#4f2323',\n    errorLight: '#2d1414',\n    info: '#a0a7b8',\n    infoDark: '#7c8394',\n    infoDisabled: '#3b3f4c',\n    infoLight: '#1d2029',\n    whiteColor: '#f5f6f7',\n    blackColor: '#f5f6f7',\n    mainColor: '#f5f6f7',\n    contentColor: '#cfd3dc',\n    tipsColor: '#9aa1af',\n    lightColor: '#6b7082',\n    borderColor: '#3a4251',\n    dividerColor: '#3a4251',\n    maskColor: 'rgba(0, 0, 0, 0.6)',\n    shadowColor: 'rgba(0, 0, 0, 0.3)',\n    bgColor: '#111827',\n    bgWhite: '#000000',\n    bgGrayLight: '#1a1a1a',\n    bgGrayDark: '#f5f7fa',\n    bgBlack: '#ffffff'\n};\n\nconst lightCss: Record<string, string> = {\n    '--u-background': '#ffffff',\n    '--u-surface': '#f7f8fa',\n    '--u-text': '#303133'\n};\n\nconst darkCss: Record<string, string> = {\n    '--u-background': '#0f1115',\n    '--u-surface': '#1c2233',\n    '--u-text': '#f5f6f7'\n};\n\nexport const defaultThemes: Theme[] = [\n    {\n        name: config.defaultTheme,\n        label: '默认蓝',\n        description: 'uView Pro 默认主题，支持亮色与暗黑模式',\n        color: lightPalette,\n        darkColor: darkPalette,\n        css: lightCss,\n        darkCss: darkCss\n    }\n];\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/config/zIndex.ts",
    "content": "/**\n * 组件库 z-index 配置项类型定义\n */\nexport interface ZIndexConfig {\n    toast: number;\n    noNetwork: number;\n    /** popup包含popup，actionSheet，keyboard，picker的值 */\n    popup: number;\n    mask: number;\n    navbar: number;\n    topTips: number;\n    sticky: number;\n    indexListSticky: number;\n    tabbar: number;\n}\n\nconst zIndex: ZIndexConfig = {\n    toast: 10090,\n    noNetwork: 10080,\n    // popup包含popup，actionSheet，keyboard，picker的值\n    popup: 10075,\n    mask: 10070,\n    navbar: 980,\n    topTips: 975,\n    sticky: 970,\n    indexListSticky: 965,\n    tabbar: 998\n};\n\nexport default zIndex;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/css/color.scss",
    "content": ".u-type-primary-light {\n    color: $u-type-primary-light;\n}\n\n.u-type-warning-light {\n    color: $u-type-warning-light;\n}\n\n.u-type-success-light {\n    color: $u-type-success-light;\n}\n\n.u-type-error-light {\n    color: $u-type-error-light;\n}\n\n.u-type-info-light {\n    color: $u-type-info-light;\n}\n\n.u-type-primary-light-bg {\n    background-color: $u-type-primary-light;\n}\n\n.u-type-warning-light-bg {\n    background-color: $u-type-warning-light;\n}\n\n.u-type-success-light-bg {\n    background-color: $u-type-success-light;\n}\n\n.u-type-error-light-bg {\n    background-color: $u-type-error-light;\n}\n\n.u-type-info-light-bg {\n    background-color: $u-type-info-light;\n}\n\n.u-type-primary-dark {\n    color: $u-type-primary-dark;\n}\n\n.u-type-warning-dark {\n    color: $u-type-warning-dark;\n}\n\n.u-type-success-dark {\n    color: $u-type-success-dark;\n}\n\n.u-type-error-dark {\n    color: $u-type-error-dark;\n}\n\n.u-type-info-dark {\n    color: $u-type-info-dark;\n}\n\n.u-type-primary-dark-bg {\n    background-color: $u-type-primary-dark;\n}\n\n.u-type-warning-dark-bg {\n    background-color: $u-type-warning-dark;\n}\n\n.u-type-success-dark-bg {\n    background-color: $u-type-success-dark;\n}\n\n.u-type-error-dark-bg {\n    background-color: $u-type-error-dark;\n}\n\n.u-type-info-dark-bg {\n    background-color: $u-type-info-dark;\n}\n\n.u-type-primary-disabled {\n    color: $u-type-primary-disabled;\n}\n\n.u-type-warning-disabled {\n    color: $u-type-warning-disabled;\n}\n\n.u-type-success-disabled {\n    color: $u-type-success-disabled;\n}\n\n.u-type-error-disabled {\n    color: $u-type-error-disabled;\n}\n\n.u-type-info-disabled {\n    color: $u-type-info-disabled;\n}\n\n.u-type-primary {\n    color: $u-type-primary;\n}\n\n.u-type-warning {\n    color: $u-type-warning;\n}\n\n.u-type-success {\n    color: $u-type-success;\n}\n\n.u-type-error {\n    color: $u-type-error;\n}\n\n.u-type-info {\n    color: $u-type-info;\n}\n\n.u-type-primary-bg {\n    background-color: $u-type-primary;\n}\n\n.u-type-warning-bg {\n    background-color: $u-type-warning;\n}\n\n.u-type-success-bg {\n    background-color: $u-type-success;\n}\n\n.u-type-error-bg {\n    background-color: $u-type-error;\n}\n\n.u-type-info-bg {\n    background-color: $u-type-info;\n}\n\n.u-main-color {\n    color: $u-main-color;\n}\n\n.u-content-color {\n    color: $u-content-color;\n}\n\n.u-tips-color {\n    color: $u-tips-color;\n}\n\n.u-light-color {\n    color: $u-light-color;\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/css/common.scss",
    "content": ".u-relative,\n.u-rela {\n    position: relative;\n}\n\n.u-absolute,\n.u-abso {\n    position: absolute;\n}\n\n// nvue不能用标签命名样式，不能放在微信组件中，否则微信开发工具会报警告，无法使用标签名当做选择器\n/* #ifndef APP-NVUE */\nimage {\n    display: inline-block;\n}\n\n// 在weex，也即nvue中，所有元素默认为border-box\nview,\ntext {\n    box-sizing: border-box;\n}\n/* #endif */\n\n.u-font-xs {\n    font-size: 22rpx;\n}\n\n.u-font-sm {\n    font-size: 26rpx;\n}\n\n.u-font-md {\n    font-size: 28rpx;\n}\n\n.u-font-lg {\n    font-size: 30rpx;\n}\n\n.u-font-xl {\n    font-size: 34rpx;\n}\n\n.u-flex {\n    /* #ifndef APP-NVUE */\n    display: flex;\n    /* #endif */\n    flex-direction: row;\n    align-items: center;\n}\n\n.u-flex-wrap {\n    flex-wrap: wrap;\n}\n\n.u-flex-nowrap {\n    flex-wrap: nowrap;\n}\n\n.u-col-center {\n    align-items: center;\n}\n\n.u-col-top {\n    align-items: flex-start;\n}\n\n.u-col-bottom {\n    align-items: flex-end;\n}\n\n.u-row-center {\n    justify-content: center;\n}\n\n.u-row-left {\n    justify-content: flex-start;\n}\n\n.u-row-right {\n    justify-content: flex-end;\n}\n\n.u-row-between {\n    justify-content: space-between;\n}\n\n.u-row-around {\n    justify-content: space-around;\n}\n\n.u-text-left {\n    text-align: left;\n}\n\n.u-text-center {\n    text-align: center;\n}\n\n.u-text-right {\n    text-align: right;\n}\n\n.u-flex-col {\n    /* #ifndef APP-NVUE */\n    display: flex;\n    /* #endif */\n    flex-direction: column;\n}\n\n.u-hidden {\n    opacity: 0;\n    visibility: hidden;\n}\n\n// 定义flex等分\n@for $i from 0 through 12 {\n    .u-flex-#{$i} {\n        flex: $i;\n    }\n}\n\n// 定义字体(px)单位，小于20都为px单位字体\n@for $i from 9 to 20 {\n    .u-font-#{$i} {\n        font-size: $i + px;\n    }\n}\n\n// 定义字体(rpx)单位，大于或等于20的都为rpx单位字体\n@for $i from 20 through 40 {\n    .u-font-#{$i} {\n        font-size: $i + rpx;\n    }\n}\n\n// 定义内外边距，历遍1-80\n@for $i from 0 through 80 {\n    // 只要双数和能被5除尽的数\n    @if $i % 2 == 0 or $i % 5 == 0 {\n        // 得出：u-margin-30或者u-m-30\n        .u-margin-#{$i},\n        .u-m-#{$i} {\n            margin: $i + rpx !important;\n        }\n\n        // 得出：u-padding-30或者u-p-30\n        .u-padding-#{$i},\n        .u-p-#{$i} {\n            padding: $i + rpx !important;\n        }\n\n        @each $short, $long in l left, t top, r right, b bottom {\n            // 缩写版，结果如： u-m-l-30\n            // 定义外边距\n            .u-m-#{$short}-#{$i} {\n                margin-#{$long}: $i + rpx !important;\n            }\n\n            // 定义内边距\n            .u-p-#{$short}-#{$i} {\n                padding-#{$long}: $i + rpx !important;\n            }\n\n            // 完整版，结果如：u-margin-left-30\n            // 定义外边距\n            .u-margin-#{$long}-#{$i} {\n                margin-#{$long}: $i + rpx !important;\n            }\n\n            // 定义内边距\n            .u-padding-#{$long}-#{$i} {\n                padding-#{$long}: $i + rpx !important;\n            }\n        }\n    }\n}\n\n// 重置nvue的默认关于flex的样式\n.u-reset-nvue {\n    flex-direction: row;\n    align-items: center;\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/css/style.components.scss",
    "content": "// 定义混入指令，用于在非nvue环境下的flex定义，因为nvue没有display属性，会报错\n@mixin vue-flex($direction: row) {\n    /* #ifndef APP-NVUE */\n    display: flex;\n    flex-direction: $direction;\n    /* #endif */\n}\n\n// 通过scss的mixin功能，把原来需要写4行的css，变成一行\n// 目的是保持代码干净整洁，不至于在nvue下，到处都要写display:flex的条件编译\n@mixin flex($direction: row) {\n    /* #ifndef APP-NVUE */\n    display: flex;\n    /* #endif */\n    flex-direction: $direction;\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/css/style.h5.scss",
    "content": "/* H5的时候，隐藏滚动条 */\n::-webkit-scrollbar {\n    display: none;\n    width: 0 !important;\n    height: 0 !important;\n    -webkit-appearance: none;\n    background: transparent;\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/css/style.mp.scss",
    "content": "/* start--微信小程序编译后页面有组件名的元素，特别处理--start */\n/* #ifdef MP-WEIXIN || MP-QQ */\nu-td,\nu-th {\n    flex: 1;\n    align-self: stretch;\n}\n\nu-icon {\n    display: inline-flex;\n    align-items: center;\n}\n\n// 各家小程序宫格组件外层设置为100%，避免受到父元素display: flex;的影响\nu-grid {\n    width: 100%;\n    flex: 0 0 100%;\n}\n\n// 避免小程序线条组件因为父组件display: flex;而失效\nu-line {\n    flex: 1;\n}\n\nu-switch {\n    display: inline-flex;\n    align-items: center;\n}\n\nu-dropdown {\n    flex: 1;\n}\n/* #endif */\n/* end-微信小程序编译后页面有组件名的元素，特别处理--end */\n\n/* #ifdef MP-QQ || MP-TOUTIAO */\n// 需要做这一切额外的兼容，都是因为TX的无能\nu-icon {\n    line-height: 0;\n}\n/* #endif */\n\n/* start--头条小程序编译后页面有组件名的元素，特别处理--start */\n// 由于头条小程序不支持直接组件名形式写样式，目前只能在写组件的时候给组件加上对应的类名\n/* #ifdef MP-TOUTIAO */\n.u-td,\n.u-th,\n.u-tr {\n    flex: 1;\n    align-self: stretch;\n}\n\n.u-row,\n.u-col {\n    flex: 1;\n    align-self: stretch;\n}\n\n// 避免小程序线条组件因为父组件display: flex;而失效\n.u-line {\n    flex: 1;\n}\n\n.u-dropdown {\n    flex: 1;\n}\n/* #endif */\n/* end-头条小程序编译后页面有组件名的元素，特别处理--end */\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/css/style.nvue.scss",
    "content": ".nvue {\n    font-size: 24rpx;\n}\n\nview,\nscroll-view,\nswiper-item {\n    display: flex;\n    flex-direction: column;\n    flex-shrink: 0;\n    flex-grow: 0;\n    flex-basis: auto;\n    align-items: stretch;\n    align-content: flex-start;\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/css/style.theme.scss",
    "content": "/* #ifdef H5 */\n:root {\n    color-scheme: light;\n}\n\n:root.u-theme-dark,\n:root[data-u-theme-mode='dark'] {\n    color-scheme: dark;\n}\n/* #endif */\n\npage {\n    color: $u-main-color;\n    background-color: $u-bg-color;\n    font-size: 28rpx;\n}\n\npage.u-theme-dark,\n:root.u-theme-dark page,\n:root[data-u-theme-mode='dark'] page {\n    background-color: $u-bg-color;\n    color: $u-main-color;\n}\n\n.u-config-provider {\n    color: $u-main-color;\n    background-color: var(--u-bg-white, #ffffff);\n}\n\n.u-config-provider.u-theme-dark {\n    background-color: var(--u-bg-white, #0f1115);\n    color: $u-main-color;\n}\n\n// picker-view遮罩层背景色\n.u-picker-view-mask,\n.uni-picker-view-mask {\n    background-image:\n        linear-gradient(180deg, rgba(var(--u-bg-white-rgb), 0.95), rgba(var(--u-bg-white-rgb), 0.6)),\n        linear-gradient(0deg, rgba(var(--u-bg-white-rgb), 0.95), rgba(var(--u-bg-white-rgb), 0.6)) !important;\n}\n\n.u-picker-view-indicator {\n    border: rgba(var(--u-bg-white-rgb), 0.6) !important;\n}\n\n// picker-view指示器边框色\n.u-picker-view-indicator::before,\n.uni-picker-view-indicator::before {\n    border-top: 1px solid var(--u-border-color) !important;\n}\n\n.u-picker-view-indicator::after,\n.uni-picker-view-indicator::after {\n    border-bottom: 1px solid var(--u-border-color) !important;\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/css/style.vue.scss",
    "content": "page {\n    color: $u-main-color;\n    font-size: 28rpx;\n}\n\n/* start--去除webkit的默认样式--start */\n.u-fix-ios-appearance {\n    -webkit-appearance: none;\n}\n/* end--去除webkit的默认样式--end */\n\n/* start--icon图标外层套一个view，让其达到更好的垂直居中的效果--start */\n.u-icon-wrap {\n    display: flex;\n    align-items: center;\n}\n/* end-icon图标外层套一个view，让其达到更好的垂直居中的效果--end */\n\n/* start--iPhoneX底部安全区定义--start */\n@each $d in top, right, bottom, left {\n    .safe-area-inset-#{$d} {\n        padding-#{$d}: 0;\n        padding-#{$d}: constant(safe-area-inset-#{$d});\n        padding-#{$d}: env(safe-area-inset-#{$d});\n    }\n}\n/* end-iPhoneX底部安全区定义--end */\n\n/* start--各种hover点击反馈相关的类名-start */\n.u-hover-class {\n    // background-color: #f7f8f9!important;\n    opacity: 0.6;\n}\n\n.u-cell-hover {\n    background-color: $u-bg-gray-light !important;\n}\n/* end--各种hover点击反馈相关的类名--end */\n\n/* start--文本行数限制--start */\n// 超出行数，自动显示行尾省略号，最多5行\n// 来自uView的温馨提示：当您在控制台看到此报错，说明需要在App.vue的style标签加上【lang=\"scss\"】\n@for $i from 1 through 5 {\n    .u-line-#{$i} {\n        /* #ifdef APP-NVUE */\n        // nvue下，可以直接使用lines属性，这是weex特有样式\n        lines: $i;\n        text-overflow: ellipsis;\n        overflow: hidden;\n        flex: 1;\n        /* #endif */\n\n        /* #ifndef APP-NVUE */\n        // vue下，单行和多行显示省略号需要单独处理\n        @if $i == 1 {\n            overflow: hidden;\n            white-space: nowrap;\n            text-overflow: ellipsis;\n        } @else {\n            display: -webkit-box;\n            overflow: hidden;\n            text-overflow: ellipsis;\n            word-break: break-all;\n            -webkit-line-clamp: $i;\n            -webkit-box-orient: vertical;\n        }\n        /* #endif */\n    }\n}\n\n.u-line-force {\n    display: -webkit-box !important;\n    -webkit-box-orient: vertical !important;\n}\n\n/* end--文本行数限制--end */\n\n/* start--Retina 屏幕下的 1px 边框--start */\n.u-border,\n.u-border-bottom,\n.u-border-left,\n.u-border-right,\n.u-border-top,\n.u-border-top-bottom {\n    position: relative;\n}\n\n.u-border-bottom:after,\n.u-border-left:after,\n.u-border-right:after,\n.u-border-top-bottom:after,\n.u-border-top:after,\n.u-border:after {\n    /* #ifndef APP-NVUE */\n    content: ' ';\n    /* #endif */\n    position: absolute;\n    left: 0;\n    top: 0;\n    pointer-events: none;\n    box-sizing: border-box;\n    -webkit-transform-origin: 0 0;\n    transform-origin: 0 0;\n    // 多加0.1%，能解决有时候边框缺失的问题\n    width: 199.8%;\n    height: 199.7%;\n    transform: scale(0.5, 0.5);\n    border: 0 solid $u-border-color;\n    z-index: 2;\n}\n\n.u-border-top:after {\n    border-top-width: 1px;\n}\n\n.u-border-left:after {\n    border-left-width: 1px;\n}\n\n.u-border-right:after {\n    border-right-width: 1px;\n}\n\n.u-border-bottom:after {\n    border-bottom-width: 1px;\n}\n\n.u-border-top-bottom:after {\n    border-width: 1px 0;\n}\n\n.u-border:after {\n    border-width: 1px;\n}\n/* end--Retina 屏幕下的 1px 边框--end */\n\n/* start--clearfix--start */\n.u-clearfix:after,\n.clearfix:after {\n    /* #ifndef APP-NVUE */\n    content: '';\n    /* #endif */\n    display: table;\n    clear: both;\n}\n/* end--clearfix--end */\n\n/* start--高斯模糊tabbar底部处理--start */\n.u-blur-effect-inset {\n    width: 750rpx;\n    height: var(--window-bottom);\n    background-color: #ffffff;\n}\n/* end--高斯模糊tabbar底部处理--end */\n\n/* start--提升H5端uni.toast()的层级，避免被uView的modal等遮盖--start */\n/* #ifdef H5 */\nuni-toast {\n    z-index: 10090;\n}\nuni-toast .uni-toast {\n    z-index: 10090;\n}\n/* #endif */\n/* end--提升H5端uni.toast()的层级，避免被uView的modal等遮盖--end */\n\n/* start--去除button的所有默认样式--start */\n// 去除button的所有默认样式，让其表现跟普通的view、text元素一样\n.u-reset-button {\n    padding: 0;\n    margin: 0;\n    background-color: transparent;\n    /* #ifndef APP-PLUS */\n    font-size: inherit;\n    line-height: inherit;\n    color: inherit;\n    /* #endif */\n    /* #ifdef APP-NVUE */\n    border-width: 0;\n    /* #endif */\n}\n\n/* #ifndef APP-NVUE */\n.u-reset-button::after {\n    border: none;\n}\n/* #endif */\n/* end--去除button的所有默认样式--end */\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/$parent.ts",
    "content": "// 获取父组件的参数，因为支付宝小程序不支持provide/inject的写法\n// this.$parent在非H5中，可以准确获取到父组件，但是在H5中，需要多次this.$parent.$parent.xxx\n// 这里默认值等于undefined有它的含义，因为最顶层元素(组件)的$parent就是undefined，意味着不传name\n// 值(默认为undefined)，就是查找最顶层的$parent\nimport { type ComponentInternalInstance, getCurrentInstance } from 'vue';\n\nexport default function $parent(\n    componentName?: string,\n    _instance: ComponentInternalInstance | null | undefined = null\n) {\n    const instance: ComponentInternalInstance | null | undefined = _instance || getCurrentInstance();\n    let parent = instance && (instance.parent as ComponentInternalInstance | null | undefined);\n\n    if (!componentName) return parent;\n\n    while (parent) {\n        const name = (parent.type as any)?.name as string | undefined;\n        if (name === componentName) {\n            return parent;\n        }\n        parent = parent.parent;\n    }\n    return null;\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/addUnit.ts",
    "content": "import validation from './test';\n\n/**\n * 添加单位，支持以下场景：\n * 1. 单值：如果有rpx、%、px等单位结尾或者值为auto，直接返回，否则加上rpx单位结尾\n * 2. 多值（空格分隔）：分别处理每个值，如 \"10 20\" => \"10rpx 20rpx\"\n *\n * @example\n * ```ts\n * addUnit(10) => \"10rpx\"\n * addUnit('10px') => \"10px\"\n * addUnit('auto') => \"auto\"\n * addUnit('10 20') => \"10rpx 20rpx\"\n * addUnit('10rpx 20') => \"10rpx 20rpx\"\n * ```\n *\n * @param value 输入值，可以为字符串或数字，默认'auto'。支持空格分隔的多值（用于 padding、margin 等）\n * @param unit 单位，默认'rpx'\n * @returns 添加单位后的字符串\n */\nexport default function addUnit(value: string | number = 'auto', unit: string = 'rpx'): string {\n    // 若传入 number 类型，转为 string\n    const strValue = String(value);\n\n    // 如果是空值，直接返回\n    if (!strValue) return '';\n\n    // auto 直接返回\n    if (strValue === 'auto') return strValue;\n\n    // 检查是否包含空格（多值场景）\n    if (strValue.includes(' ')) {\n        // 分割每个值并单独处理\n        return strValue\n            .split(' ')\n            .map(s => {\n                // 如果当前值已有单位或为 auto，直接返回\n                if (s === 'auto' || /^-?\\d*\\.?\\d+(%|px|rpx|em|rem|vh|vw)$/.test(s)) return s;\n                // 数字类型的值添加单位\n                return validation.number(s) ? `${s}${unit}` : s;\n            })\n            .join(' ');\n    }\n\n    // 单值场景：如果已有单位或为 auto，直接返回\n    if (/^-?\\d*\\.?\\d+(%|px|rpx|em|rem|vh|vw)$/.test(strValue)) return strValue;\n\n    // 用 uView 内置验证规则判断是否为数值，是则加上单位\n    return validation.number(strValue) ? `${strValue}${unit}` : strValue;\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/clipboard.ts",
    "content": "function H5Copy(text: string, config: TClipboardOptions) {\n    const success = (result: string) => {\n        if (config.showToast) {\n            uni.showToast({\n                title: '复制成功',\n                icon: 'none'\n            });\n        }\n        config.success?.(result);\n        config.complete?.(result);\n    };\n    const fail = (err: string) => {\n        if (config.showToast) {\n            uni.showToast({\n                title: '复制失败',\n                icon: 'none'\n            });\n        }\n        config.fail?.(err);\n        config.complete?.(err);\n    };\n\n    const textarea = document.createElement('textarea');\n    textarea.value = text;\n    textarea.readOnly = true;\n    textarea.style.position = 'absolute';\n    textarea.style.left = '-9999px';\n    document.body.appendChild(textarea);\n\n    textarea.select();\n    textarea.setSelectionRange(0, text.length);\n\n    try {\n        const result = document.execCommand('copy');\n        if (result) {\n            success('复制成功');\n        } else {\n            // console.error(`复制失败，可能不是用户主动触发点击的方式调用,因web安全性，不能js直接调用!`);\n            fail('复制失败，可能不是用户主动触发点击的方式调用,因browser安全性，不能js直接调用!');\n        }\n    } catch (err) {\n        // console.error('【Clipboard Error】:', err);\n        fail(String(err));\n    } finally {\n        document.body.removeChild(textarea);\n    }\n}\n\nfunction UniCopy(text: string, config: TClipboardOptions) {\n    const opt = Object.assign({ data: text }, config);\n    uni.setClipboardData(opt);\n}\n\ntype TClipboardOptions = Omit<UniNamespace.SetClipboardDataOptions, 'data'>;\n\nexport function clipboard(content: string, options?: TClipboardOptions) {\n    const text = String(content);\n    const defaultOpt = {\n        showToast: true,\n        success: () => {},\n        fail: () => {},\n        complete: () => {}\n    };\n    const config = Object.assign(defaultOpt, options);\n\n    // #ifdef H5\n    H5Copy(text, config);\n    // #endif\n\n    // #ifndef H5\n    UniCopy(text, config);\n    // #endif\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/color.ts",
    "content": "import type { ColorType, ThemeColor } from '../../types/global';\nimport { color } from '../config/color';\nimport { lightPalette } from '../config/theme-tokens';\nimport configProvider from '../util/config-provider';\n\n/**\n * 获取颜色值（响应式）\n * 优先从 configProvider 获取当前主题颜色，否则返回默认值\n * @param name 颜色名称\n * @returns 颜色值\n */\nexport function getColor(name: ColorType): string {\n    // 从响应式 color 对象获取（会被 configProvider 更新）\n    if (color[name]) {\n        return color[name] as string;\n    }\n\n    // 兜底返回默认值\n    return lightPalette[name] || '';\n}\n\nexport function setColor(theme: Partial<ThemeColor> | undefined) {\n    if (theme) {\n        configProvider.setThemeColor(theme);\n    }\n}\n\nexport default color;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/colorGradient.ts",
    "content": "/**\n * 求两个颜色之间的渐变值\n * @param startColor 开始的颜色\n * @param endColor 结束的颜色\n * @param step 颜色等分的份额\n * @returns 渐变色数组\n */\nfunction colorGradient(\n    startColor: string = 'rgb(0, 0, 0)',\n    endColor: string = 'rgb(255, 255, 255)',\n    step: number = 10\n): string[] {\n    const startRGB = hexToRgb(startColor, false) as [number, number, number]; // 转换为rgb数组模式\n    const [startR, startG, startB] = startRGB;\n    const endRGB = hexToRgb(endColor, false) as [number, number, number];\n    const [endR, endG, endB] = endRGB;\n\n    const sR = (endR - startR) / step; // 总差值\n    const sG = (endG - startG) / step;\n    const sB = (endB - startB) / step;\n    const colorArr: string[] = [];\n    for (let i = 0; i < step; i++) {\n        // 计算每一步的hex值\n        const hex = rgbToHex(\n            `rgb(${Math.round(sR * i + startR)},${Math.round(sG * i + startG)},${Math.round(sB * i + startB)})`\n        );\n        colorArr.push(hex as string);\n    }\n    return colorArr;\n}\n\n/**\n * 将hex表示方式转换为rgb表示方式(返回rgb数组或字符串)\n * @param sColor hex或rgb字符串\n * @param str 是否返回字符串\n * @returns rgb数组或字符串\n */\nfunction hexToRgb(sColor: string, str: boolean = true): [number, number, number] | string {\n    const reg = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;\n    sColor = sColor.toLowerCase();\n    if (sColor && reg.test(sColor)) {\n        if (sColor.length === 4) {\n            let sColorNew = '#';\n            for (let i = 1; i < 4; i += 1) {\n                sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1));\n            }\n            sColor = sColorNew;\n        }\n        // 处理六位的颜色值\n        const sColorChange: [number, number, number] = [\n            parseInt('0x' + sColor.slice(1, 3)),\n            parseInt('0x' + sColor.slice(3, 5)),\n            parseInt('0x' + sColor.slice(5, 7))\n        ];\n        if (!str) {\n            return sColorChange;\n        } else {\n            return `rgb(${sColorChange[0]},${sColorChange[1]},${sColorChange[2]})`;\n        }\n    } else if (/^(rgb|RGB)/.test(sColor)) {\n        const arr = sColor.replace(/(?:\\(|\\)|rgb|RGB)*/g, '').split(',');\n        return arr.map(val => Number(val)) as [number, number, number];\n    } else {\n        return sColor;\n    }\n}\n\n/**\n * rgb转hex\n * @param rgb rgb字符串或hex字符串\n * @returns hex字符串\n */\nfunction rgbToHex(rgb: string): string | undefined {\n    const reg = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;\n    if (/^(rgb|RGB)/.test(rgb)) {\n        const aColor = rgb.replace(/(?:\\(|\\)|rgb|RGB)*/g, '').split(',');\n        let strHex = '#';\n        for (let i = 0; i < aColor.length; i++) {\n            let hex = Number(aColor[i]).toString(16);\n            hex = hex.length == 1 ? '0' + hex : hex; // 保证每个rgb的值为2位\n            strHex += hex;\n        }\n        if (strHex.length !== 7) {\n            strHex = rgb;\n        }\n        return strHex;\n    } else if (reg.test(rgb)) {\n        const aNum = rgb.replace(/#/, '').split('');\n        if (aNum.length === 6) {\n            return rgb;\n        } else if (aNum.length === 3) {\n            let numHex = '#';\n            for (let i = 0; i < aNum.length; i += 1) {\n                numHex += aNum[i] + aNum[i];\n            }\n            return numHex;\n        }\n    } else {\n        return rgb;\n    }\n    // 默认返回原始值\n    return rgb;\n}\n\n/**\n * JS颜色十六进制转换为rgb或rgba,返回的格式为 rgba（255，255，255，0.5）字符串\n * @param color 十六进制色值或rgb字符串\n * @param alpha 透明度\n * @returns rgba字符串\n */\nfunction colorToRgba(color: string, alpha: number = 0.3): string {\n    color = rgbToHex(color) as string; // 确保是hex格式\n    const reg = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;\n    let sColor = color.toLowerCase();\n    if (sColor && reg.test(sColor)) {\n        if (sColor.length === 4) {\n            let sColorNew = '#';\n            for (let i = 1; i < 4; i += 1) {\n                sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1));\n            }\n            sColor = sColorNew;\n        }\n        const sColorChange: [number, number, number] = [\n            parseInt('0x' + sColor.slice(1, 3)),\n            parseInt('0x' + sColor.slice(3, 5)),\n            parseInt('0x' + sColor.slice(5, 7))\n        ];\n        return `rgba(${sColorChange.join(',')},${alpha})`;\n    } else {\n        return sColor;\n    }\n}\n\nexport default {\n    colorGradient,\n    hexToRgb,\n    rgbToHex,\n    colorToRgba\n};\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/debounce.ts",
    "content": "let timeout: ReturnType<typeof setTimeout> | null = null;\n\n/**\n * 防抖原理：一定时间内，只有最后一次操作，再过wait毫秒后才执行函数\n * @param func 要执行的回调函数\n * @param wait 延时的时间，单位ms，默认500\n * @param immediate 是否立即执行，默认false\n * @returns void\n */\nfunction debounce(func: () => void, wait: number = 500, immediate: boolean = false): void {\n    // 清除定时器\n    if (timeout !== null) clearTimeout(timeout);\n    // 立即执行，此类情况一般用不到\n    if (immediate) {\n        const callNow = !timeout;\n        timeout = setTimeout(() => {\n            timeout = null;\n        }, wait);\n        if (callNow) typeof func === 'function' && func();\n    } else {\n        // 设置定时器，当最后一次操作后，timeout不会再被清除，所以在延时wait毫秒后执行func回调方法\n        timeout = setTimeout(() => {\n            typeof func === 'function' && func();\n        }, wait);\n    }\n}\n\nexport default debounce;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/deepClone.ts",
    "content": "// 判断arr是否为一个数组，返回一个bool值\nfunction isArray(arr: any): arr is any[] {\n    return Object.prototype.toString.call(arr) === '[object Array]';\n}\n\n/**\n * 深度克隆\n * @param obj 需要克隆的对象\n * @param cache 用于处理循环引用的 WeakMap\n * @returns 克隆后的对象\n */\nfunction deepClone<T>(obj: T, cache: WeakMap<any, any> = new WeakMap()): T {\n    if (obj === null || typeof obj !== 'object') return obj;\n    if (cache.has(obj)) return cache.get(obj);\n    let clone: any;\n    if (obj instanceof Date) {\n        clone = new Date(obj.getTime());\n    } else if (obj instanceof RegExp) {\n        clone = new RegExp(obj);\n    } else if (obj instanceof Map) {\n        clone = new Map(Array.from(obj, ([key, value]) => [key, deepClone(value, cache)]));\n    } else if (obj instanceof Set) {\n        clone = new Set(Array.from(obj, value => deepClone(value, cache)));\n    } else if (Array.isArray(obj)) {\n        clone = obj.map(value => deepClone(value, cache));\n    } else if (Object.prototype.toString.call(obj) === '[object Object]') {\n        clone = Object.create(Object.getPrototypeOf(obj));\n        cache.set(obj, clone);\n        for (const [key, value] of Object.entries(obj)) {\n            clone[key] = deepClone(value, cache);\n        }\n    } else {\n        clone = Object.assign({}, obj);\n    }\n    cache.set(obj, clone);\n    return clone;\n}\n\nexport default deepClone;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/deepMerge.ts",
    "content": "import deepClone from './deepClone';\n\n/**\n * JS对象深度合并\n * @param target 目标对象\n * @param source 源对象\n * @returns 合并后的对象\n */\nfunction deepMerge<T extends object, S extends object>(target: T = {} as T, source: S = {} as S): T & S {\n    target = deepClone(target);\n    if (typeof target !== 'object' || target === null || typeof source !== 'object' || source === null)\n        return target as T & S;\n    const merged: any = Array.isArray(target) ? target.slice() : Object.assign({}, target);\n    for (const prop in source) {\n        if (!Object.prototype.hasOwnProperty.call(source, prop)) continue;\n        const sourceValue = (source as any)[prop];\n        const targetValue = merged[prop];\n        if (sourceValue instanceof Date) {\n            merged[prop] = new Date(sourceValue);\n        } else if (sourceValue instanceof RegExp) {\n            merged[prop] = new RegExp(sourceValue);\n        } else if (sourceValue instanceof Map) {\n            merged[prop] = new Map(sourceValue);\n        } else if (sourceValue instanceof Set) {\n            merged[prop] = new Set(sourceValue);\n        } else if (typeof sourceValue === 'object' && sourceValue !== null) {\n            merged[prop] = deepMerge(targetValue, sourceValue);\n        } else {\n            merged[prop] = sourceValue;\n        }\n    }\n    return merged as T & S;\n}\n\nexport default deepMerge;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/getParent.ts",
    "content": "// 获取父组件的参数，因为支付宝小程序不支持provide/inject的写法\n// this.$parent在非H5中，可以准确获取到父组件，但是在H5中，需要多次this.$parent.$parent.xxx\ninterface VueInstance {\n    $parent?: VueInstance;\n    $options?: { name?: string };\n    [key: string]: any;\n}\n\n/**\n * 获取父组件参数\n * @param this 当前组件实例\n * @param name 父组件name\n * @param keys 需要获取的参数名数组或对象\n * @returns 父组件参数对象\n */\nexport default function getParent(\n    this: VueInstance,\n    name: string,\n    keys: string[] | Record<string, any>\n): Record<string, any> {\n    let parent = this.$parent;\n    // 通过while历遍，这里主要是为了H5需要多层解析的问题\n    while (parent) {\n        // 父组件\n        if (parent.$options?.name !== name) {\n            // 如果组件的name不相等，继续上一级寻找\n            parent = parent.$parent;\n        } else {\n            const data: Record<string, any> = {};\n            // 判断keys是否数组，如果传过来的是一个数组，那么直接使用数组元素值当做键值去父组件寻找\n            if (Array.isArray(keys)) {\n                keys.forEach(val => {\n                    data[val] = parent?.[val] ? parent[val] : '';\n                });\n            } else {\n                // 历遍传过来的对象参数\n                for (const i in keys) {\n                    // 如果子组件有此值则用，无此值则用父组件的值\n                    // 判断是否空数组，如果是，则用父组件的值，否则用子组件的值\n                    if (Array.isArray(keys[i])) {\n                        if (keys[i].length) {\n                            data[i] = keys[i];\n                        } else {\n                            data[i] = parent[i];\n                        }\n                    } else if (keys[i] && keys[i].constructor === Object) {\n                        // 判断是否对象，如果是对象，且有属性，那么使用子组件的值，否则使用父组件的值\n                        if (Object.keys(keys[i]).length) {\n                            data[i] = keys[i];\n                        } else {\n                            data[i] = parent[i];\n                        }\n                    } else {\n                        // 只要子组件有传值，即使是false值，也是“传值”了，也需要覆盖父组件的同名参数\n                        data[i] = keys[i] || keys[i] === false ? keys[i] : parent[i];\n                    }\n                }\n            }\n            return data;\n        }\n    }\n    return {};\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/getRect.ts",
    "content": "/**\n * 获取元素的位置信息\n * @param {any} selector 选择器\n * @param {boolean} all 是否获取所有匹配元素\n * @returns {Promise<any>} 返回一个 Promise，解析为元素的位置信息\n */\n\nimport { getCurrentInstance } from 'vue';\n\nexport default function (selector: any, _instance: any = null, all: boolean = false): Promise<any> {\n    const instance = _instance || getCurrentInstance();\n    return new Promise(resolve => {\n        uni.createSelectorQuery()\n            .in(instance?.proxy)\n            [all ? 'selectAll' : 'select'](selector)\n            .boundingClientRect((rect: any) => {\n                if (all && Array.isArray(rect) && rect.length) {\n                    resolve(rect);\n                }\n                if (!all && rect) {\n                    resolve(rect);\n                }\n            })\n            .exec();\n    });\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/guid.ts",
    "content": "/**\n * 本算法来源于简书开源代码，详见：https://www.jianshu.com/p/fdbf293d0a85\n * 全局唯一标识符（uuid，Globally Unique Identifier）,也称作 uuid(Universally Unique IDentifier)\n * 一般用于多个组件之间,给它一个唯一的标识符,或者v-for循环的时候,如果使用数组的index可能会导致更新列表出现问题\n * 最可能的情况是左滑删除item或者对某条信息流\"不喜欢\"并去掉它的时候,会导致组件内的数据可能出现错乱\n * v-for的时候,推荐使用后端返回的id而不是循环的index\n * @param len uuid的长度，默认32\n * @param firstU 将返回的首字母置为\"u\"，默认true\n * @param radix 生成uuid的基数(意味着返回的字符串都是这个基数),2-二进制,8-八进制,10-十进制,16-十六进制\n * @returns 生成的uuid字符串\n */\nfunction guid(len: number = 32, firstU: boolean = true, radix?: number): string {\n    const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');\n    const uuid: string[] = [];\n    const base = radix || chars.length;\n\n    if (len) {\n        // 如果指定uuid长度,只是取随机的字符,0|x为位运算,能去掉x的小数位,返回整数位\n        for (let i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * base)];\n    } else {\n        let r: number;\n        // rfc4122标准要求返回的uuid中,某些位为固定的字符\n        uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';\n        uuid[14] = '4';\n\n        for (let i = 0; i < 36; i++) {\n            if (!uuid[i]) {\n                r = 0 | (Math.random() * 16);\n                uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r];\n            }\n        }\n    }\n    // 移除第一个字符,并用u替代,因为第一个字符为数值时,该guid不能用作id或者class\n    if (firstU) {\n        uuid.shift();\n        return 'u' + uuid.join('');\n    } else {\n        return uuid.join('');\n    }\n}\n\nexport default guid;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/md5.ts",
    "content": "/*\n * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message\n * Digest Algorithm, as defined in RFC 1321.\n * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009\n * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet\n * Distributed under the BSD License\n * See http://pajhome.org.uk/crypt/md5 for more info.\n */\n\n/*\n * Configurable variables. You may need to tweak these to be compatible with\n * the server-side, but the defaults work in most cases.\n */\nlet hexcase: number = 0; /* hex output format. 0 - lowercase; 1 - uppercase        */\nlet b64pad: string = ''; /* base-64 pad character. \"=\" for strict RFC compliance   */\n\n/**\n * 这些是通常需要调用的函数\n * @param s 输入字符串\n * @returns 十六进制/BASE64/任意编码的MD5字符串\n */\nfunction hex_md5(s: string): string {\n    return rstr2hex(rstr_md5(str2rstr_utf8(s)));\n}\nfunction b64_md5(s: string): string {\n    return rstr2b64(rstr_md5(str2rstr_utf8(s)));\n}\nfunction any_md5(s: string, e: string): string {\n    return rstr2any(rstr_md5(str2rstr_utf8(s)), e);\n}\nfunction hex_hmac_md5(k: string, d: string): string {\n    return rstr2hex(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)));\n}\nfunction b64_hmac_md5(k: string, d: string): string {\n    return rstr2b64(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)));\n}\nfunction any_hmac_md5(k: string, d: string, e: string): string {\n    return rstr2any(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)), e);\n}\n\n/**\n * 执行简单自测，判断 VM 是否正常\n * @returns 是否通过测试\n */\nfunction md5_vm_test(): boolean {\n    return hex_md5('abc').toLowerCase() == '900150983cd24fb0d6963f7d28e17f72';\n}\n\n/**\n * 计算原始字符串的 MD5\n * @param s 原始字符串\n * @returns MD5 结果字符串\n */\nfunction rstr_md5(s: string): string {\n    return binl2rstr(binl_md5(rstr2binl(s), s.length * 8));\n}\n\n/**\n * 计算 HMAC-MD5\n * @param key 密钥\n * @param data 数据\n * @returns HMAC-MD5 结果字符串\n */\nfunction rstr_hmac_md5(key: string, data: string): string {\n    let bkey: number[] = rstr2binl(key);\n    if (bkey.length > 16) bkey = binl_md5(bkey, key.length * 8);\n\n    const ipad: number[] = Array(16),\n        opad: number[] = Array(16);\n    for (let i = 0; i < 16; i++) {\n        ipad[i] = bkey[i] ^ 0x36363636;\n        opad[i] = bkey[i] ^ 0x5c5c5c5c;\n    }\n\n    const hash: number[] = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);\n    return binl2rstr(binl_md5(opad.concat(hash), 512 + 128));\n}\n\n/**\n * 原始字符串转十六进制字符串\n * @param input 输入字符串\n * @returns 十六进制字符串\n */\nfunction rstr2hex(input: string): string {\n    try {\n        hexcase;\n    } catch (e) {\n        hexcase = 0;\n    }\n    const hex_tab: string = hexcase ? '0123456789ABCDEF' : '0123456789abcdef';\n    let output = '';\n    let x: number;\n    for (let i = 0; i < input.length; i++) {\n        x = input.charCodeAt(i);\n        output += hex_tab.charAt((x >>> 4) & 0x0f) + hex_tab.charAt(x & 0x0f);\n    }\n    return output;\n}\n\n/**\n * 原始字符串转 BASE64 字符串\n * @param input 输入字符串\n * @returns BASE64 字符串\n */\nfunction rstr2b64(input: string): string {\n    try {\n        b64pad;\n    } catch (e) {\n        b64pad = '';\n    }\n    const tab: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n    let output = '';\n    const len: number = input.length;\n    for (let i = 0; i < len; i += 3) {\n        const triplet: number =\n            (input.charCodeAt(i) << 16) |\n            (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) |\n            (i + 2 < len ? input.charCodeAt(i + 2) : 0);\n        for (let j = 0; j < 4; j++) {\n            if (i * 8 + j * 6 > input.length * 8) output += b64pad;\n            else output += tab.charAt((triplet >>> (6 * (3 - j))) & 0x3f);\n        }\n    }\n    return output;\n}\n\n/**\n * 原始字符串转任意编码字符串\n * @param input 输入字符串\n * @param encoding 编码表\n * @returns 编码后的字符串\n */\nfunction rstr2any(input: string, encoding: string): string {\n    const divisor: number = encoding.length;\n    let i: number, j: number, q: number, x: number, quotient: number[];\n\n    /* Convert to an array of 16-bit big-endian values, forming the dividend */\n    let dividend: number[] = Array(Math.ceil(input.length / 2));\n    for (i = 0; i < dividend.length; i++) {\n        dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);\n    }\n\n    /*\n     * Repeatedly perform a long division. The binary array forms the dividend,\n     * the length of the encoding is the divisor. Once computed, the quotient\n     * forms the dividend for the next step. All remainders are stored for later\n     * use.\n     */\n    const full_length: number = Math.ceil((input.length * 8) / (Math.log(encoding.length) / Math.log(2)));\n    const remainders: number[] = Array(full_length);\n    for (j = 0; j < full_length; j++) {\n        quotient = [];\n        x = 0;\n        for (i = 0; i < dividend.length; i++) {\n            x = (x << 16) + dividend[i];\n            q = Math.floor(x / divisor);\n            x -= q * divisor;\n            if (quotient.length > 0 || q > 0) quotient[quotient.length] = q;\n        }\n        remainders[j] = x;\n        dividend = quotient;\n    }\n\n    /* Convert the remainders to the output string */\n    let output = '';\n    for (i = remainders.length - 1; i >= 0; i--) output += encoding.charAt(remainders[i]);\n\n    return output;\n}\n\n/**\n * 字符串转 UTF-8 编码\n * @param input 输入字符串\n * @returns UTF-8 编码字符串\n */\nfunction str2rstr_utf8(input: string): string {\n    let output = '';\n    let i = -1;\n    let x: number, y: number;\n\n    while (++i < input.length) {\n        /* Decode utf-16 surrogate pairs */\n        x = input.charCodeAt(i);\n        y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;\n        if (0xd800 <= x && x <= 0xdbff && 0xdc00 <= y && y <= 0xdfff) {\n            x = 0x10000 + ((x & 0x03ff) << 10) + (y & 0x03ff);\n            i++;\n        }\n\n        /* Encode output as utf-8 */\n        if (x <= 0x7f) output += String.fromCharCode(x);\n        else if (x <= 0x7ff) output += String.fromCharCode(0xc0 | ((x >>> 6) & 0x1f), 0x80 | (x & 0x3f));\n        else if (x <= 0xffff)\n            output += String.fromCharCode(0xe0 | ((x >>> 12) & 0x0f), 0x80 | ((x >>> 6) & 0x3f), 0x80 | (x & 0x3f));\n        else if (x <= 0x1fffff)\n            output += String.fromCharCode(\n                0xf0 | ((x >>> 18) & 0x07),\n                0x80 | ((x >>> 12) & 0x3f),\n                0x80 | ((x >>> 6) & 0x3f),\n                0x80 | (x & 0x3f)\n            );\n    }\n    return output;\n}\n\n/**\n * 字符串转 UTF-16LE 编码\n * @param input 输入字符串\n * @returns UTF-16LE 编码字符串\n */\nfunction str2rstr_utf16le(input: string): string {\n    let output = '';\n    for (let i = 0; i < input.length; i++)\n        output += String.fromCharCode(input.charCodeAt(i) & 0xff, (input.charCodeAt(i) >>> 8) & 0xff);\n    return output;\n}\n\n/**\n * 字符串转 UTF-16BE 编码\n * @param input 输入字符串\n * @returns UTF-16BE 编码字符串\n */\nfunction str2rstr_utf16be(input: string): string {\n    let output = '';\n    for (let i = 0; i < input.length; i++)\n        output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xff, input.charCodeAt(i) & 0xff);\n    return output;\n}\n\n/**\n * 原始字符串转小端字数组\n * @param input 输入字符串\n * @returns 小端字数组\n */\nfunction rstr2binl(input: string): number[] {\n    const output: number[] = Array(input.length >> 2);\n    for (let i = 0; i < output.length; i++) output[i] = 0;\n    for (let i = 0; i < input.length * 8; i += 8) output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << i % 32;\n    return output;\n}\n\n/**\n * 小端字数组转字符串\n * @param input 小端字数组\n * @returns 字符串\n */\nfunction binl2rstr(input: number[]): string {\n    let output = '';\n    for (let i = 0; i < input.length * 32; i += 8) output += String.fromCharCode((input[i >> 5] >>> i % 32) & 0xff);\n    return output;\n}\n\n/**\n * 计算小端字数组的 MD5\n * @param x 小端字数组\n * @param len 位长度\n * @returns MD5 结果数组\n */\nfunction binl_md5(x: number[], len: number): number[] {\n    /* append padding */\n    x[len >> 5] |= 0x80 << len % 32;\n    x[(((len + 64) >>> 9) << 4) + 14] = len;\n\n    let a = 1732584193;\n    let b = -271733879;\n    let c = -1732584194;\n    let d = 271733878;\n\n    for (let i = 0; i < x.length; i += 16) {\n        const olda = a;\n        const oldb = b;\n        const oldc = c;\n        const oldd = d;\n\n        a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936);\n        d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);\n        c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);\n        b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);\n        a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);\n        d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);\n        c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);\n        b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);\n        a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);\n        d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);\n        c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);\n        b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);\n        a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);\n        d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);\n        c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);\n        b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);\n\n        a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);\n        d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);\n        c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);\n        b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302);\n        a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);\n        d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);\n        c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);\n        b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);\n        a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);\n        d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);\n        c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);\n        b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);\n        a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);\n        d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);\n        c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);\n        b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);\n\n        a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);\n        d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);\n        c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);\n        b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);\n        a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);\n        d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);\n        c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);\n        b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);\n        a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);\n        d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222);\n        c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);\n        b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);\n        a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);\n        d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);\n        c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);\n        b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);\n\n        a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844);\n        d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);\n        c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);\n        b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);\n        a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);\n        d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);\n        c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);\n        b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);\n        a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);\n        d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);\n        c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);\n        b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);\n        a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);\n        d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);\n        c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);\n        b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);\n\n        a = safe_add(a, olda);\n        b = safe_add(b, oldb);\n        c = safe_add(c, oldc);\n        d = safe_add(d, oldd);\n    }\n    return [a, b, c, d];\n}\n\n/**\n * 四种基本操作\n */\nfunction md5_cmn(q: number, a: number, b: number, x: number, s: number, t: number): number {\n    return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);\n}\nfunction md5_ff(a: number, b: number, c: number, d: number, x: number, s: number, t: number): number {\n    return md5_cmn((b & c) | (~b & d), a, b, x, s, t);\n}\nfunction md5_gg(a: number, b: number, c: number, d: number, x: number, s: number, t: number): number {\n    return md5_cmn((b & d) | (c & ~d), a, b, x, s, t);\n}\nfunction md5_hh(a: number, b: number, c: number, d: number, x: number, s: number, t: number): number {\n    return md5_cmn(b ^ c ^ d, a, b, x, s, t);\n}\nfunction md5_ii(a: number, b: number, c: number, d: number, x: number, s: number, t: number): number {\n    return md5_cmn(c ^ (b | ~d), a, b, x, s, t);\n}\n\n/**\n * 安全整数加法，防止溢出\n * @param x 整数\n * @param y 整数\n * @returns 加法结果\n */\nfunction safe_add(x: number, y: number): number {\n    const lsw: number = (x & 0xffff) + (y & 0xffff);\n    const msw: number = (x >> 16) + (y >> 16) + (lsw >> 16);\n    return (msw << 16) | (lsw & 0xffff);\n}\n\n/**\n * 左移位操作\n * @param num 数字\n * @param cnt 位数\n * @returns 结果\n */\nfunction bit_rol(num: number, cnt: number): number {\n    return (num << cnt) | (num >>> (32 - cnt));\n}\n\n/**\n * 计算字符串的 MD5 值\n * @param str 输入字符串\n * @returns MD5 十六进制字符串\n */\nfunction md5(str: string): string {\n    return hex_md5(str);\n}\n\nexport default {\n    md5\n};\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/parent.ts",
    "content": "import { type ComponentInternalInstance, getCurrentInstance } from 'vue';\n\nexport function parent(componentName?: string, _instance: ComponentInternalInstance | null | undefined = null) {\n    const instance = _instance || getCurrentInstance();\n\n    let parent = instance && (instance.parent as ComponentInternalInstance | null | undefined);\n\n    while (parent) {\n        const name = (parent.type as any)?.name as string | undefined;\n        if (name === componentName) {\n            return parent;\n        }\n        parent = parent.parent;\n    }\n    return null;\n}\nexport function parentData(componentName?: string, _instance: ComponentInternalInstance | null | undefined = null) {\n    const instance = _instance || getCurrentInstance();\n    const findParent = parent(componentName, instance);\n    return findParent ? findParent.exposed : null;\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/queryParams.ts",
    "content": "/**\n * 对象转url参数\n * @param data 对象参数\n * @param isPrefix 是否自动加上\"?\"，默认true\n * @param arrayFormat 数组参数格式，indices/brackets/repeat/comma，默认brackets\n * @returns url参数字符串\n */\nfunction queryParams(\n    data: Record<string, any> = {},\n    isPrefix: boolean = true,\n    arrayFormat: 'indices' | 'brackets' | 'repeat' | 'comma' = 'brackets'\n): string {\n    const prefix = isPrefix ? '?' : '';\n    const _result: string[] = [];\n    if (!['indices', 'brackets', 'repeat', 'comma'].includes(arrayFormat)) arrayFormat = 'brackets';\n    for (const key in data) {\n        const value = data[key];\n        // 去掉为空的参数\n        if (['', undefined, null].includes(value)) {\n            continue;\n        }\n        // 如果值为数组，另行处理\n        if (Array.isArray(value)) {\n            // e.g. {ids: [1, 2, 3]}\n            switch (arrayFormat) {\n                case 'indices':\n                    // 结果: ids[0]=1&ids[1]=2&ids[2]=3\n                    for (let i = 0; i < value.length; i++) {\n                        _result.push(`${key}[${i}]=${value[i]}`);\n                    }\n                    break;\n                case 'brackets':\n                    // 结果: ids[]=1&ids[]=2&ids[]=3\n                    value.forEach((_value: any) => {\n                        _result.push(`${key}[]=${_value}`);\n                    });\n                    break;\n                case 'repeat':\n                    // 结果: ids=1&ids=2&ids=3\n                    value.forEach((_value: any) => {\n                        _result.push(`${key}=${_value}`);\n                    });\n                    break;\n                case 'comma':\n                    // 结果: ids=1,2,3\n                    let commaStr = '';\n                    value.forEach((_value: any) => {\n                        commaStr += (commaStr ? ',' : '') + _value;\n                    });\n                    _result.push(`${key}=${commaStr}`);\n                    break;\n                default:\n                    value.forEach((_value: any) => {\n                        _result.push(`${key}[]=${_value}`);\n                    });\n            }\n        } else {\n            _result.push(`${key}=${value}`);\n        }\n    }\n    return _result.length ? prefix + _result.join('&') : '';\n}\n\nexport default queryParams;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/random.ts",
    "content": "/**\n * 生成指定范围的随机整数\n * @param min 最小值（包含）\n * @param max 最大值（包含）\n * @returns 随机整数\n */\nfunction random(min: number, max: number): number {\n    if (min >= 0 && max > 0 && max >= min) {\n        const gab = max - min + 1;\n        return Math.floor(Math.random() * gab + min);\n    } else {\n        return 0;\n    }\n}\n\nexport default random;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/randomArray.ts",
    "content": "/**\n * 打乱数组顺序\n * @param array 需要打乱的数组\n * @returns 打乱后的新数组\n */\nfunction randomArray<T>(array: T[] = []): T[] {\n    // 原理是sort排序,Math.random()产生0<= x < 1之间的数,会导致x-0.5大于或者小于0\n    return array.sort(() => Math.random() - 0.5);\n}\n\nexport default randomArray;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/route.ts",
    "content": "/**\n * 路由跳转方法，该方法相对于直接使用uni.xxx的好处是使用更加简单快捷\n * 并且带有路由拦截功能\n */\n\ninterface RouterConfig {\n    type?: string;\n    url?: string;\n    delta?: number;\n    params?: Record<string, any>;\n    animationType?: string;\n    animationDuration?: number;\n    intercept?: boolean;\n}\n\ndeclare const uni: any; // 声明uni对象，避免ts报错\n\nclass Router {\n    config: RouterConfig;\n    // route: (options?: string | RouterConfig, params?: Record<string, any>) => Promise<void>;\n\n    constructor() {\n        // 原始属性定义\n        this.config = {\n            type: 'navigateTo',\n            url: '',\n            delta: 1, // navigateBack页面后退时,回退的层数\n            params: {}, // 传递的参数\n            animationType: 'pop-in', // 窗口动画,只在APP有效\n            animationDuration: 300, // 窗口动画持续时间,单位毫秒,只在APP有效\n            intercept: false // 是否需要拦截\n        };\n        // 因为route方法是需要对外赋值给另外的对象使用，同时route内部有使用this，会导致route失去上下文\n        // 这里在构造函数中进行this绑定\n        this.route = this.route.bind(this);\n    }\n\n    // 判断url前面是否有\"/\"，如果没有则加上，否则无法跳转\n    addRootPath(url: string): string {\n        return url[0] === '/' ? url : `/${url}`;\n    }\n\n    // 整合路由参数\n    mixinParam(url: string, params: Record<string, any>): string {\n        url = url && this.addRootPath(url);\n        // 使用正则匹配，主要依据是判断是否有\"/\",\"?\",\"=\"等，如“/page/index/index?name=mary\"\n        // 如果有url中有get参数，转换后无需带上\"?\"\n        let query = '';\n        if (/.*\\/.*\\?.*=.*/.test(url)) {\n            // object对象转为get类型的参数\n            query = uni.$u.queryParams(params, false);\n            // 因为已有get参数,所以后面拼接的参数需要带上\"&\"隔开\n            return url + '&' + query;\n        } else {\n            // 直接拼接参数，因为此处url中没有后面的query参数，也就没有\"?/&\"之类的符号\n            query = uni.$u.queryParams(params);\n            return url + query;\n        }\n    }\n\n    /**\n     * 路由跳转主方法\n     * @param options 跳转配置或url字符串\n     * @param params 跳转参数\n     */\n    async route(options: string | RouterConfig = {}, params: Record<string, any> = {}): Promise<void> {\n        let mergeConfig: RouterConfig = {};\n        if (typeof options === 'string') {\n            // 如果options为字符串，则为route(url, params)的形式\n            mergeConfig.url = this.mixinParam(options, params);\n            mergeConfig.type = 'navigateTo';\n        } else {\n            mergeConfig = uni.$u.deepMerge(this.config, options);\n            // 否则正常使用mergeConfig中的url和params进行拼接\n            mergeConfig.url = this.mixinParam(options.url || '', options.params || {});\n        }\n        if (params.intercept) {\n            this.config.intercept = params.intercept;\n        }\n        // params参数也带给拦截器\n        mergeConfig.params = params;\n        // 合并内外部参数\n        mergeConfig = uni.$u.deepMerge(this.config, mergeConfig);\n        // 判断用户是否定义了拦截器\n        if (uni.$u.routeIntercept && typeof uni.$u.routeIntercept === 'function') {\n            // 定一个promise，根据用户执行resolve(true)或者resolve(false)来决定是否进行路由跳转\n            const isNext = await new Promise<boolean>(resolve => {\n                uni.$u.routeIntercept(mergeConfig, resolve);\n            });\n            // 如果isNext为true，则执行路由跳转\n            isNext && this.openPage(mergeConfig);\n        } else {\n            this.openPage(mergeConfig);\n        }\n    }\n\n    // 执行路由跳转\n    openPage(config: RouterConfig): void {\n        const { url = '', type = '', delta = 1, animationDuration = 300 } = config;\n        if (type == 'navigateTo' || type == 'to') {\n            uni.navigateTo({ url, animationDuration });\n        }\n        if (type == 'redirectTo' || type == 'redirect') {\n            uni.redirectTo({ url });\n        }\n        if (type == 'switchTab' || type == 'tab') {\n            uni.switchTab({ url });\n        }\n        if (type == 'reLaunch' || type == 'launch') {\n            uni.reLaunch({ url });\n        }\n        if (type == 'navigateBack' || type == 'back') {\n            uni.navigateBack({ delta });\n        }\n    }\n}\n\nexport default new Router().route;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/styleUtils.ts",
    "content": "import type { CSSProperties } from 'vue';\nimport trim from './trim';\nimport test from './test';\n\nfunction isValidValue(value: any): boolean {\n    if (test.isEmpty(value)) return false;\n    if (typeof value === 'string') {\n        const trimmed = trim(value).toLowerCase();\n        return trimmed !== 'null' && trimmed !== 'undefined' && trimmed !== '';\n    }\n    return true;\n}\n\n/**\n * 将 CSS 字符串解析为对象\n */\nfunction cssStrToObj(str: string): object {\n    const result = {};\n    if (!isValidValue(str)) return result;\n    const styleStr = trim(String(str));\n    if (!isValidValue(styleStr)) return result;\n    const declarations = styleStr.split(';');\n    declarations.forEach(decl => {\n        const [prop, ...values] = decl.split(':').map(s => s.trim());\n        const value = values.join(':');\n        if (prop && value) {\n            const camelProp = prop.replace(/-([a-z])/g, (match, letter) => letter.toUpperCase());\n            (result as Record<string, string>)[camelProp] = value;\n        }\n    });\n    return result;\n}\n\n/**\n * 将 CSS 对象转换为 CSS 字符串\n */\nfunction cssObjToStr(obj: object): string {\n    if (!isValidValue(obj) || typeof obj !== 'object') return '';\n    return (\n        Object.entries(obj)\n            .map(([key, value]) => {\n                if (!isValidValue(value)) return '';\n                // 驼峰转短横线\n                const kebab = key.replace(/([A-Z])/g, '-$1').toLowerCase();\n                return `${kebab}: ${value}`;\n            })\n            .filter(Boolean)\n            .join('; ') + ';'\n    );\n}\n\n/**\n * 合并多个 CSS 输入（对象或字符串），返回一个 CSS 对象\n */\nexport function mergeStyles(...args: (object | string)[]): CSSProperties {\n    const result = {} as Record<string, any>;\n    for (let i = 0; i < args.length; i++) {\n        const arg = args[i];\n        if (!isValidValue(arg)) return result as CSSProperties;\n        if (typeof arg === 'string') {\n            Object.assign(result, cssStrToObj(arg));\n        } else if (test.object(arg)) {\n            const cleanedObj: Record<string, any> = {};\n            Object.keys(arg).forEach(key => {\n                const value = (arg as Record<string, any>)[key];\n                if (isValidValue(value)) {\n                    // 有效\n                    cleanedObj[key] = value;\n                }\n            });\n            Object.assign(result, cleanedObj);\n        }\n    }\n    return result;\n}\n\n/**\n * 合并为 CSS 字符串\n */\nexport function mergeCssStrings(...args: (object | string)[]): string {\n    const obj = mergeStyles(...args);\n    return cssObjToStr(obj);\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/sys.ts",
    "content": "/**\n * 获取当前操作系统平台\n * @returns 平台字符串，如 'ios'、'android'、'windows' 等\n */\nexport function os(): string {\n    return uni.getSystemInfoSync().platform;\n}\n\n/**\n * 获取系统信息\n * @returns uniapp 系统信息对象\n */\nexport function sys(): UniApp.GetSystemInfoResult {\n    return uni.getSystemInfoSync();\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/test.ts",
    "content": "/**\n * 验证电子邮箱格式\n */\nfunction email(value: string): boolean {\n    return /[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])?/.test(\n        value\n    );\n}\n\n/**\n * 验证手机格式\n */\nfunction mobile(value: string): boolean {\n    return /^1[3-9]\\d{9}$/.test(value);\n}\n\n/**\n * 验证URL格式\n */\nfunction url(value: string): boolean {\n    return /http(s)?:\\/\\/([\\w-]+\\.)+[\\w-]+(\\/[\\w-.\\/?%&=]*)?/.test(value);\n}\n\n/**\n * 验证日期格式\n */\nfunction date(value: string): boolean {\n    return !/Invalid|NaN/.test(new Date(value).toString());\n}\n\n/**\n * 验证ISO类型的日期格式\n */\nfunction dateISO(value: string): boolean {\n    return /^\\d{4}[\\/\\-](0?[1-9]|1[012])[\\/\\-](0?[1-9]|[12][0-9]|3[01])$/.test(value);\n}\n\n/**\n * 验证十进制数字\n */\nfunction number(value: string): boolean {\n    return /^[\\+-]?(\\d+\\.?\\d*|\\.\\d+|\\d\\.\\d+e\\+\\d+)$/.test(value);\n}\n\n/**\n * 验证整数\n */\nfunction digits(value: string): boolean {\n    return /^\\d+$/.test(value);\n}\n\n/**\n * 验证身份证号码\n */\nfunction idCard(value: string): boolean {\n    return /^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9]|X)$/.test(value);\n}\n\n/**\n * 是否车牌号\n */\nfunction carNo(value: string): boolean {\n    // 新能源车牌\n    const xreg =\n        /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/;\n    // 旧车牌\n    const creg =\n        /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/;\n    if (value.length === 7) {\n        return creg.test(value);\n    } else if (value.length === 8) {\n        return xreg.test(value);\n    } else {\n        return false;\n    }\n}\n\n/**\n * 金额,只允许2位小数\n */\nfunction amount(value: string): boolean {\n    //金额，只允许保留两位小数\n    return /^[1-9]\\d*(,\\d{3})*(\\.\\d{1,2})?$|^0\\.\\d{1,2}$/.test(value);\n}\n\n/**\n * 中文\n */\nfunction chinese(value: string): boolean {\n    let reg = /^[\\u4e00-\\u9fa5]+$/gi;\n    return reg.test(value);\n}\n\n/**\n * 只能输入字母\n */\nfunction letter(value: string): boolean {\n    return /^[a-zA-Z]*$/.test(value);\n}\n\n/**\n * 只能是字母或者数字\n */\nfunction enOrNum(value: string): boolean {\n    //英文或者数字\n    let reg = /^[0-9a-zA-Z]*$/g;\n    return reg.test(value);\n}\n\n/**\n * 验证是否包含某个值\n */\nfunction contains(value: string, param: string): boolean {\n    return value.indexOf(param) >= 0;\n}\n\n/**\n * 验证一个值范围[min, max]\n */\nfunction range(value: number, param: [number, number]): boolean {\n    return value >= param[0] && value <= param[1];\n}\n\n/**\n * 验证一个长度范围[min, max]\n */\nfunction rangeLength(value: string, param: [number, number]): boolean {\n    return value.length >= param[0] && value.length <= param[1];\n}\n\n/**\n * 是否固定电话\n */\nfunction landline(value: string): boolean {\n    let reg = /^\\d{3,4}-\\d{7,8}(-\\d{3,4})?$/;\n    return reg.test(value);\n}\n\n/**\n * 判断是否为空\n */\nfunction empty(value: any): boolean {\n    switch (typeof value) {\n        case 'undefined':\n            return true;\n        case 'string':\n            if (value.replace(/(^[ \\t\\n\\r]*)|([ \\t\\n\\r]*$)/g, '').length == 0) return true;\n            break;\n        case 'boolean':\n            if (!value) return true;\n            break;\n        case 'number':\n            if (0 === value || isNaN(value)) return true;\n            break;\n        case 'object':\n            if (null === value || value.length === 0) return true;\n            for (var i in value) {\n                return false;\n            }\n            return true;\n    }\n    return false;\n}\n\n/**\n * 是否json字符串\n */\nfunction jsonString(value: string): boolean {\n    if (typeof value == 'string') {\n        try {\n            var obj = JSON.parse(value);\n            if (typeof obj == 'object' && obj) {\n                return true;\n            } else {\n                return false;\n            }\n        } catch (e) {\n            return false;\n        }\n    }\n    return false;\n}\n\n/**\n * 是否数组\n */\nfunction array(value: any): boolean {\n    if (typeof Array.isArray === 'function') {\n        return Array.isArray(value);\n    } else {\n        return Object.prototype.toString.call(value) === '[object Array]';\n    }\n}\n\n/**\n * 是否对象\n */\nfunction object(value: any): boolean {\n    return Object.prototype.toString.call(value) === '[object Object]';\n}\n\n/**\n * 是否短信验证码\n */\nfunction code(value: string, len: number = 6): boolean {\n    return new RegExp(`^\\\\d{${len}}$`).test(value);\n}\n\n/**\n * 是否函数方法\n * @param {Object} value\n */\nfunction func(value: any) {\n    return typeof value === 'function';\n}\n\n/**\n * 是否promise对象\n * @param {Object} value\n */\nfunction promise(value: any) {\n    return object(value) && func(value.then) && func(value.catch);\n}\n\n/** 是否图片格式\n * @param {Object} value\n */\nfunction image(value: any) {\n    const newValue = value.split('?')[0];\n    const IMAGE_REGEXP = /\\.(jpeg|jpg|gif|png|svg|webp|jfif|bmp|dpg)/i;\n    return IMAGE_REGEXP.test(newValue);\n}\n\n/**\n * 是否视频格式\n * @param {Object} value\n */\nfunction video(value: any) {\n    const VIDEO_REGEXP = /\\.(mp4|mpg|mpeg|dat|asf|avi|rm|rmvb|mov|wmv|flv|mkv|m3u8)/i;\n    return VIDEO_REGEXP.test(value);\n}\n\n/**\n * 是否为正则对象\n * @param {Object}\n * @return {Boolean}\n */\nfunction regExp(o: any) {\n    return o && Object.prototype.toString.call(o) === '[object RegExp]';\n}\n\n/**\n * 验证字符串\n */\nfunction string(value: any) {\n    return typeof value === 'string';\n}\n\nexport default {\n    email,\n    mobile,\n    url,\n    date,\n    dateISO,\n    number,\n    digits,\n    idCard,\n    carNo,\n    amount,\n    chinese,\n    letter,\n    enOrNum,\n    contains,\n    range,\n    rangeLength,\n    empty,\n    isEmpty: empty,\n    jsonString,\n    landline,\n    object,\n    array,\n    code,\n    func,\n    promise,\n    video,\n    image,\n    regExp,\n    string\n};\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/throttle.ts",
    "content": "let timer: ReturnType<typeof setTimeout> | undefined;\nlet flag: boolean | undefined;\n/**\n * 节流原理：在一定时间内，只能触发一次\n * @param func 要执行的回调函数\n * @param wait 延时的时间，单位ms，默认500\n * @param immediate 是否立即执行，默认true\n * @returns void\n */\nfunction throttle(func: () => void, wait: number = 500, immediate: boolean = true): void {\n    if (immediate) {\n        if (!flag) {\n            flag = true;\n            // 如果是立即执行，则在wait毫秒内开始时执行\n            typeof func === 'function' && func();\n            timer = setTimeout(() => {\n                flag = false;\n            }, wait);\n        }\n    } else {\n        if (!flag) {\n            flag = true;\n            // 如果是非立即执行，则在wait毫秒内的结束处执行\n            timer = setTimeout(() => {\n                flag = false;\n                typeof func === 'function' && func();\n            }, wait);\n        }\n    }\n}\nexport default throttle;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/timeFormat.ts",
    "content": "// padStart 的 polyfill，因为某些机型或情况，还无法支持es7的padStart，比如电脑版的微信小程序\n// 所以这里做一个兼容polyfill的兼容处理\nif (!String.prototype.padStart) {\n    // 为了方便表示这里 fillString 用了ES6 的默认参数，不影响理解\n    String.prototype.padStart = function (this: string, maxLength: number, fillString: string = ' '): string {\n        if (Object.prototype.toString.call(fillString) !== '[object String]')\n            throw new TypeError('fillString must be String');\n        let str = this;\n        if (str.length >= maxLength) return String(str);\n        let fillLength = maxLength - str.length,\n            times = Math.ceil(fillLength / fillString.length);\n        while ((times >>= 1)) {\n            fillString += fillString;\n            if (times === 1) {\n                fillString += fillString;\n            }\n        }\n        return fillString.slice(0, fillLength) + str;\n    };\n}\n\n/**\n * 时间格式化\n * @param dateTime 时间戳、Date对象或null，默认当前时间\n * @param fmt 格式化字符串，默认 'yyyy-mm-dd'\n * @returns 格式化后的时间字符串\n */\nfunction timeFormat(dateTime: number | string | Date | null = null, fmt: string = 'yyyy-mm-dd'): string {\n    // 如果为null,则格式化当前时间\n    if (!dateTime) dateTime = Number(new Date());\n    // 如果dateTime长度为10或者13，则为秒和毫秒的时间戳，如果超过13位，则为其他的时间格式\n    if (typeof dateTime === 'number' || typeof dateTime === 'string') {\n        if (dateTime.toString().length == 10) dateTime = Number(dateTime) * 1000;\n    }\n    const date = new Date(dateTime);\n    let ret: RegExpExecArray | null;\n    const opt: Record<string, string> = {\n        'y+': date.getFullYear().toString(), // 年\n        'm+': (date.getMonth() + 1).toString(), // 月\n        'd+': date.getDate().toString(), // 日\n        'h+': date.getHours().toString(), // 时\n        'M+': date.getMinutes().toString(), // 分\n        's+': date.getSeconds().toString() // 秒\n        // 有其他格式化字符需求可以继续添加，必须转化成字符串\n    };\n    for (const k in opt) {\n        ret = new RegExp('(' + k + ')').exec(fmt);\n        if (ret) {\n            fmt = fmt.replace(ret[1], ret[1].length == 1 ? opt[k] : opt[k].padStart(ret[1].length, '0'));\n        }\n    }\n    return fmt;\n}\n\nexport default timeFormat;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/timeFrom.ts",
    "content": "import timeFormat from './timeFormat';\n\n/**\n * 时间戳转为多久之前\n * @param dateTime 时间戳、Date对象或null，默认当前时间\n * @param format 时间格式字符串或false，超出范围时返回指定格式，否则返回多久以前\n * @returns 格式化后的时间字符串\n */\nfunction timeFrom(dateTime: number | string | Date | null = null, format: string | false = 'yyyy-mm-dd'): string {\n    // 如果为null,则格式化当前时间\n    if (!dateTime) dateTime = Number(new Date());\n    // 如果dateTime长度为10或者13，则为秒和毫秒的时间戳，如果超过13位，则为其他的时间格式\n    if (typeof dateTime === 'number' || typeof dateTime === 'string') {\n        if (dateTime.toString().length == 10) dateTime = Number(dateTime) * 1000;\n    }\n    const timestamp = +new Date(Number(dateTime));\n    const timer = (Number(new Date()) - timestamp) / 1000;\n    // 如果小于5分钟,则返回\"刚刚\",其他以此类推\n    let tips = '';\n    switch (true) {\n        case timer < 300:\n            tips = '刚刚';\n            break;\n        case timer >= 300 && timer < 3600:\n            tips = parseInt(String(timer / 60)) + '分钟前';\n            break;\n        case timer >= 3600 && timer < 86400:\n            tips = parseInt(String(timer / 3600)) + '小时前';\n            break;\n        case timer >= 86400 && timer < 2592000:\n            tips = parseInt(String(timer / 86400)) + '天前';\n            break;\n        default:\n            // 如果format为false，则无论什么时间戳，都显示xx之前\n            if (format === false) {\n                if (timer >= 2592000 && timer < 365 * 86400) {\n                    tips = parseInt(String(timer / (86400 * 30))) + '个月前';\n                } else {\n                    tips = parseInt(String(timer / (86400 * 365))) + '年前';\n                }\n            } else {\n                tips = timeFormat(timestamp, format as string);\n            }\n    }\n    return tips;\n}\n\nexport default timeFrom;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/toast.ts",
    "content": "/**\n * 显示无图标的 Toast 提示\n * @param title 提示文本\n * @param option 显示时长（毫秒）默认1500 /显示图标，默认为none，\n */\nfunction toast(title: string, option: number | string | Record<string, any> = 1500): void {\n    uni.showToast({\n        title: title,\n        icon: typeof option === 'string' ? option : typeof option === 'object' ? option.icon || 'none' : 'none',\n        duration: typeof option === 'number' ? option : typeof option === 'object' ? option.duration || '1500' : 1500\n    });\n}\n\nexport default toast;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/trim.ts",
    "content": "/**\n * 去除字符串空格\n * @param str 输入字符串\n * @param pos 去除位置，'both' | 'left' | 'right' | 'all'，默认'both'\n * @returns 去除空格后的字符串\n */\nfunction trim(str: string, pos: 'both' | 'left' | 'right' | 'all' = 'both'): string {\n    if (pos === 'both') {\n        return str.replace(/^\\s+|\\s+$/g, '');\n    } else if (pos === 'left') {\n        return str.replace(/^\\s*/, '');\n    } else if (pos === 'right') {\n        return str.replace(/(\\s*$)/g, '');\n    } else if (pos === 'all') {\n        return str.replace(/\\s+/g, '');\n    } else {\n        return str;\n    }\n}\n\nexport default trim;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/function/type2icon.ts",
    "content": "import type { ThemeType } from '../../types/global';\n\n/**\n * 根据主题type值,获取对应的图标\n * @param type 主题名称, primary|info|error|warning|success，默认success\n * @param fill 是否使用fill填充实体的图标，默认false\n * @returns 图标名称字符串\n */\nfunction type2icon(type: ThemeType = 'success', fill: boolean = false): string {\n    // 如果非预置值,默认为success\n    if (!['primary', 'info', 'error', 'warning', 'success'].includes(type)) type = 'success';\n    let iconName = '';\n    // 目前(2019-12-12),info和primary使用同一个图标\n    switch (type) {\n        case 'primary':\n            iconName = 'info-circle';\n            break;\n        case 'info':\n            iconName = 'info-circle';\n            break;\n        case 'error':\n            iconName = 'close-circle';\n            break;\n        case 'warning':\n            iconName = 'error-circle';\n            break;\n        case 'success':\n            iconName = 'checkmark-circle';\n            break;\n        default:\n            iconName = 'checkmark-circle';\n    }\n    // 是否是实体类型,加上-fill,在icon组件库中,实体的类名是后面加-fill的\n    if (fill) iconName += '-fill';\n    return iconName;\n}\n\nexport default type2icon;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/hooks/index.ts",
    "content": "export * from './useEmitter';\nexport * from './useRect';\nexport * from './useCompRelation';\nexport * from './useTheme';\nexport * from './useColor';\nexport * from './useLocale';\nexport * from './useDebounce';\nexport * from './useThrottle';\nexport * from './useToast';\nexport * from './useModal';\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/hooks/useColor.ts",
    "content": "/**\n * 响应式颜色管理 composable\n * 提供响应式的颜色访问，支持主题切换和暗黑模式\n *\n * 使用方式：\n * const { color, getColor } = useColor()\n * // color 是响应式的，可以直接在模板中使用\n * // getColor('primary') 返回响应式的颜色值\n */\n\nimport { computed, type ComputedRef } from 'vue';\nimport type { ColorType } from '../../types/global';\nimport configProvider from '../util/config-provider';\n\n/**\n * 响应式颜色 composable\n * 返回响应式的颜色对象和获取颜色的方法\n */\nexport function useColor() {\n    // 从 configProvider 获取当前主题的响应式引用\n    const currentTheme = configProvider.currentThemeRef;\n    const darkModeRef = configProvider.darkModeRef;\n\n    /**\n     * 获取当前激活模式下的颜色对象（响应式）\n     */\n    const color = computed(() => {\n        const theme = currentTheme.value;\n        if (!theme) return {} as Record<ColorType, string>;\n\n        const isDark = configProvider.isInDarkMode();\n        const palette =\n            isDark && theme.darkColor && Object.keys(theme.darkColor).length ? theme.darkColor : theme.color || {};\n\n        // 合并默认值，确保所有颜色都有值\n        const defaultPalette = isDark\n            ? (configProvider as any).baseDarkColorTokens || {}\n            : (configProvider as any).baseColorTokens || {};\n\n        return {\n            ...defaultPalette,\n            ...palette\n        } as Record<ColorType, string>;\n    });\n\n    /**\n     * 获取指定颜色（响应式）\n     * @param name 颜色名称\n     * @returns 颜色值\n     */\n    const getColor = (name: ColorType): ComputedRef<string> => {\n        return computed(() => {\n            return color.value[name] || '';\n        });\n    };\n\n    return {\n        color,\n        getColor\n    };\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/hooks/useCompRelation.ts",
    "content": "import { ref, reactive, getCurrentInstance, onUnmounted, nextTick, computed, onMounted } from 'vue';\nimport { isDebugMode } from '../config/config';\n\n// 类型定义\ninterface ParentContext {\n    name: string;\n    addChild: (child: ChildContext) => void;\n    removeChild: (childId: string) => void;\n    broadcast: (event: string, data?: any, childIds?: string | string[]) => void;\n    broadcastToChildren: (componentName: string, event: string, data?: any) => void;\n    getChildren: () => ChildContext[];\n    getExposed: () => Record<string, any>;\n    getChildExposed: (childId: string) => Record<string, any>;\n    getChildrenExposed: () => Array<{ id: string; name: string; exposed: Record<string, any> }>;\n    getInstance: () => any;\n}\n\ninterface ChildContext {\n    id: string;\n    name: string;\n    getChildIndex: () => number;\n    emitToParent: (event: string, data?: any) => void;\n    getParentExposed: () => Record<string, any>;\n    getInstance: () => any;\n    getExposed: () => Record<string, any>;\n}\n\n// 符号定义\nconst PARENT_CONTEXT_SYMBOL = Symbol('parent_context');\n// 每个组件实例的 child id 缓存，避免同个组件中多次调用 useChildren 时生成不同 id\nconst CHILD_ID_SYMBOL = Symbol('child_id');\n\n/**\n * 生成实例唯一ID\n */\nfunction generateInstanceId(componentName: string): string {\n    return `${componentName}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n}\n\n/**\n * 查找父组件实例\n */\nfunction findParentInstance(name: string, instance: any): any {\n    if (!instance) return null;\n\n    let parent = instance.parent;\n    while (parent) {\n        const parentName = parent.type?.name || parent.type?.__name;\n        if (parentName === name) {\n            return parent;\n        }\n        parent = parent.parent;\n    }\n    return null;\n}\n\n/**\n * 获取父组件上下文\n */\nfunction getParentContext(name: string, instance: any): ParentContext | null {\n    const parentInstance = findParentInstance(name, instance);\n    return parentInstance?.proxy?.[PARENT_CONTEXT_SYMBOL] || null;\n}\n\n/**\n * 递归查找所有指定名称的子组件\n */\nfunction findAllChildComponents(componentName: string, instance: any): any[] {\n    const components: any[] = [];\n\n    function traverse(currentInstance: any) {\n        if (!currentInstance?.subTree) return;\n\n        const subTree = currentInstance.subTree?.children || [];\n        const children = Array.isArray(subTree) ? subTree : [subTree];\n\n        children.forEach((vnode: any) => {\n            const child = vnode.component;\n            if (!child) return;\n\n            const name = child.type?.name || child.type?.__name;\n            if (name === componentName) {\n                components.push(child);\n            }\n            traverse(child);\n        });\n    }\n\n    traverse(instance);\n    if (isDebugMode()) console.log(`Found ${components.length} ${componentName} components`);\n    return components;\n}\n\n/**\n * 父组件 Hook\n */\nexport function useParent(componentName?: string) {\n    const instance = getCurrentInstance();\n    if (!instance) {\n        throw new Error('useParent must be called within setup function');\n    }\n\n    const name = componentName || instance.type.name || instance.type.__name;\n    if (!name) {\n        throw new Error('Component name is required for useParent');\n    }\n\n    const children = reactive<ChildContext[]>([]);\n    const childrenMap = new Map<string, ChildContext>();\n\n    const broadcast = (event: string, data?: any, childIds?: string | string[]) => {\n        const targetChildren = childIds\n            ? ((Array.isArray(childIds) ? childIds : [childIds])\n                  .map(id => childrenMap.get(id))\n                  .filter(Boolean) as ChildContext[])\n            : Array.from(childrenMap.values());\n\n        if (isDebugMode())\n            console.log(`Parent ${name} broadcasting event: ${event} to ${targetChildren.length} children`);\n\n        targetChildren.forEach(child => {\n            const exposed = child.getExposed();\n            if (exposed && typeof exposed[event] === 'function') {\n                try {\n                    exposed[event](data);\n                } catch (error) {\n                    if (isDebugMode('error')) console.error(`Error calling child method ${event}:`, error);\n                }\n            }\n        });\n    };\n\n    const broadcastToChildren = (componentName: string, event: string, data?: any) => {\n        if (isDebugMode())\n            console.log(`Parent ${name} broadcasting event: ${event} to all ${componentName} components`);\n\n        const childComponents = findAllChildComponents(componentName, instance);\n        let successCount = 0;\n\n        childComponents.forEach(childComponent => {\n            const exposed = childComponent.exposed || childComponent.proxy;\n            if (exposed && typeof exposed[event] === 'function') {\n                try {\n                    exposed[event](data);\n                    successCount++;\n                } catch (error) {\n                    if (isDebugMode('error')) console.error(`Error calling ${componentName} method ${event}:`, error);\n                }\n            }\n        });\n\n        if (isDebugMode())\n            console.log(\n                `Parent ${name} successfully called ${successCount} of ${childComponents.length} ${componentName} components`\n            );\n    };\n\n    const parentContext: ParentContext = {\n        name,\n        addChild(child: ChildContext) {\n            if (!childrenMap.has(child.id)) {\n                childrenMap.set(child.id, child);\n                children.push(child);\n                if (isDebugMode()) console.log(`Parent ${name} added child: ${child.name}`);\n            }\n        },\n        removeChild(childId: string) {\n            if (childrenMap.has(childId)) {\n                const child = childrenMap.get(childId)!;\n                childrenMap.delete(childId);\n                const index = children.findIndex(c => c.id === childId);\n                if (index > -1) children.splice(index, 1);\n                if (isDebugMode()) console.log(`Parent ${name} removed child: ${childId}`);\n            }\n        },\n        broadcast,\n        broadcastToChildren,\n        getChildren: () => Array.from(childrenMap.values()),\n        getExposed: () => instance.exposed || {},\n        getChildExposed(childId: string) {\n            const child = childrenMap.get(childId);\n            return child?.getExposed?.() || {};\n        },\n        getChildrenExposed() {\n            return Array.from(childrenMap.values())\n                .filter(child => child.getExposed)\n                .map(child => ({\n                    id: child.id,\n                    name: child.name,\n                    exposed: child.getExposed()\n                }))\n                .filter(item => Object.keys(item.exposed).length > 0);\n        },\n        getInstance: () => instance\n    };\n\n    if (instance.proxy) {\n        (instance.proxy as any)[PARENT_CONTEXT_SYMBOL] = parentContext;\n    }\n\n    onUnmounted(() => {\n        childrenMap.forEach((_, childId) => parentContext.removeChild(childId));\n        if (instance.proxy) {\n            delete (instance.proxy as any)[PARENT_CONTEXT_SYMBOL];\n        }\n        if (isDebugMode()) console.log(`Parent ${name} unmounted and cleaned up`);\n    });\n\n    return {\n        parentName: name,\n        children,\n        broadcast,\n        broadcastToChildren,\n        getChildren: parentContext.getChildren,\n        getChildExposed: parentContext.getChildExposed,\n        getChildrenExposed: parentContext.getChildrenExposed,\n        getExposed: parentContext.getExposed,\n        getInstance: parentContext.getInstance\n    };\n}\n\n/**\n * 子组件 Hook\n */\nexport function useChildren(componentName?: string, parentName?: string) {\n    const instance = getCurrentInstance();\n    if (!instance) {\n        throw new Error('useChildren must be called within setup function');\n    }\n\n    const name = componentName || instance.type.name || instance.type.__name;\n    // 生成实例ID，同组件多次使用useChildren会重复创建\n    // const instanceId = generateInstanceId(name || 'anonymous');\n    // 尝试从实例上复用已有的 child id，避免同个组件内多次调用 useChildren 导致重复注册\n    let instanceId: string | undefined = (instance.proxy as any)?.[CHILD_ID_SYMBOL];\n    if (!instanceId) {\n        instanceId = generateInstanceId(name || 'anonymous');\n        if (instance.proxy) (instance.proxy as any)[CHILD_ID_SYMBOL] = instanceId;\n    }\n    const parentRef = ref<any | null>(null);\n    const parentExposed = ref<Record<string, any>>({});\n\n    const createSimulatedParentContext = (parentInstance: any): ParentContext => ({\n        name: parentInstance?.type?.name || parentInstance?.type?.__name || 'unknown',\n        addChild: () => isDebugMode() && console.log('Simulated parent added child'),\n        removeChild: () => isDebugMode() && console.log('Simulated parent removed child'),\n        broadcast: () => isDebugMode() && console.log('Simulated parent broadcasting'),\n        broadcastToChildren: () => isDebugMode() && console.log('Simulated parent broadcasting to children'),\n        getChildren: () => [],\n        getExposed: () => parentInstance?.exposed || {},\n        getChildExposed: () => ({}),\n        getChildrenExposed: () => [],\n        getInstance: () => parentInstance\n    });\n\n    const getParentExposed = (): Record<string, any> => {\n        if (parentRef.value) {\n            const exposed = parentRef.value.getExposed();\n            parentExposed.value = exposed;\n            return exposed;\n        }\n        return {};\n    };\n\n    const getExposed = (): Record<string, any> => instance.exposed || {};\n\n    const findParent = (): ParentContext | null => {\n        if (parentName) {\n            const parentContext = getParentContext(parentName, instance);\n            if (parentContext) {\n                if (!parentContext.getInstance) {\n                    parentContext.getInstance = () => findParentInstance(parentName, instance);\n                }\n                return parentContext;\n            }\n\n            const parentInstance = findParentInstance(parentName, instance);\n            if (parentInstance) {\n                return createSimulatedParentContext(parentInstance);\n            }\n        }\n\n        let current = instance.parent;\n        while (current) {\n            const context = (current.proxy as any)?.[PARENT_CONTEXT_SYMBOL];\n            if (context) {\n                if (!context.getInstance) {\n                    context.getInstance = () => current;\n                }\n                return context;\n            }\n            current = current.parent;\n        }\n\n        return instance.parent ? createSimulatedParentContext(instance.parent) : null;\n    };\n\n    const linkParent = (): boolean => {\n        const parent = findParent();\n        if (parent) {\n            parentRef.value = parent;\n            if (parent.addChild && childContext) {\n                parent.addChild(childContext);\n            }\n            getParentExposed();\n            if (isDebugMode()) console.log(`Child ${name || 'anonymous'} linked to parent ${parent.name}`);\n            return true;\n        }\n        if (isDebugMode()) console.log(`Child ${name || 'anonymous'} no parent found, working in standalone mode`);\n        return false;\n    };\n\n    const emitToParent = (event: string, data?: any) => {\n        if (parentRef.value) {\n            const exposed = getParentExposed();\n            if (exposed && typeof exposed[event] === 'function') {\n                try {\n                    exposed[event](data, instanceId, name);\n                } catch (error) {\n                    if (isDebugMode('error')) console.error(`Error calling parent method ${event}:`, error);\n                }\n            }\n        }\n    };\n\n    const getChildIndex = () => {\n        if (!parentRef.value) return -1;\n        try {\n            const children = parentRef.value.getChildren();\n            return children.findIndex((child: ChildContext) => child.id === instanceId);\n        } catch (error) {\n            return -1;\n        }\n    };\n\n    const childContext: ChildContext = {\n        id: instanceId,\n        name: name || 'anonymous',\n        getChildIndex,\n        emitToParent,\n        getParentExposed,\n        getInstance: () => instance,\n        getExposed\n    };\n\n    if (isDebugMode()) console.log(`Child ${name || 'anonymous'} registered, looking for parent`);\n\n    onMounted(() => {\n        let connected = linkParent();\n        nextTick(() => {\n            connected = linkParent();\n            if (!connected) {\n                setTimeout(linkParent, 500);\n            }\n        });\n    });\n\n    onUnmounted(() => {\n        if (parentRef.value?.removeChild) {\n            parentRef.value.removeChild(instanceId);\n        }\n        if (isDebugMode()) console.log(`Child ${name || 'anonymous'} unmounted`);\n    });\n\n    return {\n        childId: instanceId,\n        childName: name || 'anonymous',\n        childIndex: computed(getChildIndex),\n        parent: parentRef,\n        emitToParent,\n        getParentExposed,\n        parentExposed: computed(() => parentExposed.value),\n        getExposed\n    };\n}\n\n/**\n * 检查父组件是否存在\n */\nexport function hasParent(parentName?: string): boolean {\n    const instance = getCurrentInstance();\n    if (!instance) return false;\n\n    if (parentName) {\n        return getParentContext(parentName, instance) !== null;\n    }\n\n    let current = instance.parent;\n    while (current) {\n        if ((current.proxy as any)?.[PARENT_CONTEXT_SYMBOL]) return true;\n        current = current.parent;\n    }\n    return false;\n}\n\n/**\n * 获取父组件上下文\n */\nexport function getParentContextByName(parentName: string): ParentContext | null {\n    const instance = getCurrentInstance();\n    return instance ? getParentContext(parentName, instance) : null;\n}\n\n/**\n * 热更新清理函数\n */\nexport function cleanupComponentRelations(): void {\n    if (isDebugMode()) console.log('Cleaning up component relations for hot reload');\n}\n\n// 热更新处理\nif (import.meta.hot) {\n    import.meta.hot.accept(() => {\n        if (isDebugMode()) console.log('Hot reload detected, relations will be automatically reconnected');\n    });\n}\n\nexport default {\n    useParent,\n    useChildren,\n    hasParent,\n    getParentContextByName,\n    cleanupComponentRelations\n};\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/hooks/useDebounce.ts",
    "content": "export function useDebounce(delay: number = 500) {\n    let timeout: ReturnType<typeof setTimeout> | null = null;\n    // 防抖函数\n    function debounce(callback: () => void, debounceTime?: number) {\n        debounceTime = debounceTime || delay;\n        if (timeout) clearTimeout(timeout);\n        timeout = setTimeout(() => {\n            callback();\n        }, debounceTime);\n    }\n\n    return {\n        debounce\n    };\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/hooks/useEmitter.ts",
    "content": "import { type ComponentInternalInstance, getCurrentInstance } from 'vue';\n\n/**\n * 将事件名转换为驼峰格式\n * @param str 需要转换的字符串\n * @description 例如：on-form-change -> onFormChange\n * @returns\n */\nfunction formatToCamelCase(str: string): string {\n    return str.replace(/-([a-z])/g, function (g) {\n        return g[1].toUpperCase();\n    });\n}\n\nexport function useEmitter(name: string) {\n    const instance: ComponentInternalInstance | null | undefined = getCurrentInstance();\n\n    /** * 向上查找父组件并派发事件\n     * @param instance 当前组件实例（setup中可用getCurrentInstance()）\n     * @param componentName 目标组件名\n     * @param eventName 事件名\n     * @param params 参数\n     */\n    function dispatch(componentName: string, eventName: string, ...params: any[]) {\n        let parent = instance && (instance.parent as ComponentInternalInstance | null | undefined);\n        while (parent) {\n            const name = (parent.type as any)?.name as string | undefined;\n            if (name === componentName) {\n                // 找到目标组件，派发事件\n                // Vue3未解决，目标组件事件监听失效，待优化，暂时使用下面的方式解决，如果你有好的方式也可以告诉我或者提PR\n                parent.emit && parent.emit(eventName, ...params);\n                // 如果有对应的方法，执行方法\n                // 这里可以考虑将 eventName 转换为驼峰格式\n                // 例如：on-form-change -> onFormChange\n                parent.exposed?.[formatToCamelCase(eventName)] &&\n                    parent.exposed[formatToCamelCase(eventName)](...params);\n                break;\n            }\n            parent = parent.parent;\n        }\n    }\n\n    /**\n     * 向下递归查找子组件并广播事件\n     * @param instance 当前组件实例（setup中可用getCurrentInstance()）\n     * @param componentName 目标组件名\n     * @param eventName 事件名\n     * @param params 参数\n     */\n    function broadcast(componentName: string, eventName: string, ...params: any[]) {\n        if (!instance) return;\n        const subTree = (instance.subTree as any)?.children || [];\n        const children = Array.isArray(subTree) ? subTree : [subTree];\n        children.forEach((vnode: any) => {\n            const child = vnode.component as ComponentInternalInstance | undefined;\n\n            if (child) {\n                const name = (child.type as any)?.name as string | undefined;\n                if (name === componentName) {\n                    // 找到目标组件，广播事件\n                    // Vue3未解决，目标组件事件监听失效，待优化，暂时使用下面的方式解决，如果你有好的方式也可以告诉我或者提PR\n                    child.emit && child.emit(eventName, ...params);\n                    // 如果有对应的方法，执行方法\n                    // 这里可以考虑将 eventName 转换为驼峰格式\n                    // 例如：on-form-change -> onFormChange\n                    child.exposed?.[formatToCamelCase(eventName)] &&\n                        child.exposed[formatToCamelCase(eventName)](...params);\n                } else {\n                    broadcast.call(child, componentName, eventName, ...params);\n                }\n            }\n        });\n    }\n\n    return {\n        dispatch,\n        broadcast\n    };\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/hooks/useLocale.ts",
    "content": "import configProvider from '../util/config-provider';\n\n/**\n * 国际化 composable\n * 提供：\n * - currentLocale / locales 响应式引用\n * - t(key, replacements) 翻译方法\n * - setLocale(name) 切换语言\n * - initLocales(locales?, defaultName?) 初始化语言包\n */\nexport function useLocale(namespace?: string) {\n    // 创建翻译函数，支持命名空间\n    const createTranslateFunction = (ns?: string) => {\n        return (key: string, replacements?: any, localeName?: string): string => {\n            // 如果有命名空间，自动添加前缀\n            const fullKey = ns ? `${ns}.${key}` : key;\n            return configProvider.t(fullKey, replacements, localeName);\n        };\n    };\n\n    return {\n        // 响应式引用\n        currentLocale: configProvider.currentLocaleRef,\n        locales: configProvider.localesRef,\n\n        // 方法\n        t: createTranslateFunction(namespace),\n        setLocale: (name: string) => configProvider.setLocale(name),\n        getLocales: () => configProvider.getLocales(),\n        getCurrentLocale: () => configProvider.getCurrentLocale(),\n        initLocales: (locales?: any[], defaultLocaleName?: string, isForce?: boolean) =>\n            configProvider.initLocales(locales, defaultLocaleName, isForce)\n    };\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/hooks/useModal.ts",
    "content": "import {\n    U_MODAL_EVENT_SHOW,\n    U_MODAL_EVENT_HIDE,\n    U_MODAL_EVENT_CLEAR_LOADING,\n    U_MODAL_GLOBAL_EVENT_SHOW,\n    U_MODAL_GLOBAL_EVENT_HIDE,\n    U_MODAL_GLOBAL_EVENT_CLEAR_LOADING,\n    getEventWithCurrentPage,\n    type ModalPayload\n} from '../../components/u-modal/service';\n\nexport type UseModalShowOptions = ModalPayload;\n\nexport type UseModal = {\n    /**\n     * 显示 modal\n     * - show('标题')\n     * - show({ title, content, showCancelButton, ... })\n     */\n    show: (contentOrOptions: string | UseModalShowOptions) => void;\n    /**\n     * 显示 confirm 类型的 modal（带确认和取消按钮）\n     * - confirm('标题')\n     * - confirm({ title, content, onConfirm, onCancel })\n     */\n    confirm: (contentOrOptions: string | UseModalShowOptions) => void;\n    /** 关闭 modal */\n    close: () => void;\n    /** 清除 loading 状态 */\n    clearLoading: () => void;\n};\n\nexport type UseModalOptions = {\n    /** 是否使用全局根部 <u-modal global /> */\n    global?: boolean;\n    /** 是否使用页面级 <u-modal page /> 或某个页面的 <u-modal page=\"pageId\" /> */\n    page?: boolean | string;\n};\n\nfunction normalize(contentOrOptions: string | UseModalShowOptions): UseModalShowOptions {\n    if (typeof contentOrOptions === 'string') {\n        // 如果是简单的字符串，可能是标题或内容\n        return { content: contentOrOptions };\n    }\n    return contentOrOptions || {};\n}\n\nfunction getPage(optionsOrGlobal: UseModalOptions | boolean): string {\n    if (typeof optionsOrGlobal === 'boolean') {\n        return '';\n    }\n    if (optionsOrGlobal.page && typeof optionsOrGlobal.page === 'string' && optionsOrGlobal.page !== '') {\n        return optionsOrGlobal.page;\n    }\n    return '';\n}\n\n/**\n * Modal 函数式调用\n * @description 需要页面/应用中至少存在一个 <u-modal global /> 或 <u-modal page /> 实例用于承接事件；不影响原 ref 调用方式。\n *\n * 支持两种调用方式：\n * - 应用级 useModal() / useModal(true) / useModal({ global: true })\n * - 页面级 useModal(false) / useModal({ page: true }) / useModal({ page: 'pageId' }) （pageId 应和页面中 <u-modal page=\"pageId\" /> 的 page 属性一致）\n */\nexport function useModal(optionsOrGlobal: UseModalOptions | boolean = true): UseModal {\n    const isGlobal = typeof optionsOrGlobal === 'boolean' ? optionsOrGlobal === true : !!optionsOrGlobal.global;\n    const isPage = typeof optionsOrGlobal === 'boolean' ? optionsOrGlobal === false : !!optionsOrGlobal.page;\n\n    const showEvent = isGlobal\n        ? U_MODAL_GLOBAL_EVENT_SHOW\n        : isPage\n          ? getEventWithCurrentPage(U_MODAL_EVENT_SHOW, getPage(optionsOrGlobal))\n          : '';\n    const hideEvent = isGlobal\n        ? U_MODAL_GLOBAL_EVENT_HIDE\n        : isPage\n          ? getEventWithCurrentPage(U_MODAL_EVENT_HIDE, getPage(optionsOrGlobal))\n          : '';\n    const clearLoadingEvent = isGlobal\n        ? U_MODAL_GLOBAL_EVENT_CLEAR_LOADING\n        : isPage\n          ? getEventWithCurrentPage(U_MODAL_EVENT_CLEAR_LOADING, getPage(optionsOrGlobal))\n          : '';\n\n    function emitShow(payload: UseModalShowOptions) {\n        if (showEvent) {\n            uni?.$emit && uni.$emit(showEvent, payload);\n        }\n    }\n\n    function emitHide() {\n        if (hideEvent) {\n            uni?.$emit && uni.$emit(hideEvent);\n        }\n    }\n\n    function emitClearLoading() {\n        if (clearLoadingEvent) {\n            uni?.$emit && uni.$emit(clearLoadingEvent);\n        }\n    }\n\n    function show(contentOrOptions: string | UseModalShowOptions) {\n        emitShow(normalize(contentOrOptions));\n    }\n\n    function confirm(contentOrOptions: string | UseModalShowOptions) {\n        const options = normalize(contentOrOptions);\n        emitShow({\n            ...options,\n            showCancelButton: options.showCancelButton ?? true,\n            showConfirmButton: options.showConfirmButton ?? true\n        });\n    }\n\n    function clearLoading() {\n        emitClearLoading();\n    }\n\n    function close() {\n        emitHide();\n    }\n\n    return {\n        show,\n        confirm,\n        close,\n        clearLoading\n    };\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/hooks/useRect.ts",
    "content": "import { getCurrentInstance, nextTick, ref } from 'vue';\n\n/**\n * useRect - 获取元素的位置信息（响应式，原生实现）\n * @param selector 选择器（如 #id 或 .class）\n * @param all 是否获取所有匹配元素\n * @returns rect 响应式的节点信息，refresh 主动刷新方法\n */\nexport function useRect(selector: string | null = null, all = false) {\n    const rect = ref<any>(all ? [] : null);\n    const instance = getCurrentInstance();\n\n    async function getRect(realSelector: string | null = null, delay = 0): Promise<any> {\n        realSelector = realSelector || selector;\n        if (!realSelector) return rect.value;\n        await nextTick();\n        return new Promise(resolve => {\n            setTimeout(() => {\n                uni.createSelectorQuery()\n                    .in(instance?.proxy)\n                    [all ? 'selectAll' : 'select'](realSelector as string)\n                    .boundingClientRect((res: any) => {\n                        rect.value = res;\n                        resolve(res);\n                    })\n                    .exec();\n            }, delay);\n        });\n    }\n\n    function refresh(selector?: string | null, delay?: number): Promise<any> {\n        return getRect(selector, delay);\n    }\n\n    return {\n        rect,\n        getRect,\n        refresh\n    };\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/hooks/useRouter.ts",
    "content": "/**\n * 路由跳转 hooks，基于 route.ts 的 Router 类实现\n * 提供 Vue Composition API 风格的路由跳转方法\n */\n\nimport { ref } from 'vue';\n\ninterface RouterConfig {\n    type?: string;\n    url?: string;\n    delta?: number;\n    params?: Record<string, any>;\n    animationType?: string;\n    animationDuration?: number;\n    intercept?: boolean;\n}\n\ndeclare const uni: any;\n\nconst config: RouterConfig = {\n    type: 'navigateTo',\n    url: '',\n    delta: 1,\n    params: {},\n    animationType: 'pop-in',\n    animationDuration: 300,\n    intercept: false\n};\n\n// 响应式配置，支持动态修改\nconst configRef = ref({ ...config });\n\n/**\n * 判断 url 前面是否有 \"/\"，如果没有则加上\n */\nconst addRootPath = (url: string): string => {\n    return url[0] === '/' ? url : `/${url}`;\n};\n\n/**\n * 整合路由参数\n */\nconst mixinParam = (url: string, params: Record<string, any>): string => {\n    url = url && addRootPath(url);\n    let query = '';\n    if (/.*\\/.*\\?.*=.*/.test(url)) {\n        query = uni.$u.queryParams(params, false);\n        return url + '&' + query;\n    } else {\n        query = uni.$u.queryParams(params);\n        return url + query;\n    }\n};\n\n/**\n * 执行路由跳转\n */\nconst openPage = (cfg: RouterConfig): void => {\n    const { url = '', type = '', delta = 1, animationDuration = 300 } = cfg;\n    if (type === 'navigateTo' || type === 'to') {\n        uni.navigateTo({ url, animationDuration });\n    }\n    if (type === 'redirectTo' || type === 'redirect') {\n        uni.redirectTo({ url });\n    }\n    if (type === 'switchTab' || type === 'tab') {\n        uni.switchTab({ url });\n    }\n    if (type === 'reLaunch' || type === 'launch') {\n        uni.reLaunch({ url });\n    }\n    if (type === 'navigateBack' || type === 'back') {\n        uni.navigateBack({ delta });\n    }\n};\n\n/**\n * 路由跳转主方法\n */\nconst route = async (options: string | RouterConfig = {}, params: Record<string, any> = {}): Promise<void> => {\n    let mergeConfig: RouterConfig = {};\n\n    if (typeof options === 'string') {\n        mergeConfig.url = mixinParam(options, params);\n        mergeConfig.type = 'navigateTo';\n    } else {\n        mergeConfig = uni.$u.deepMerge(configRef.value, options);\n        mergeConfig.url = mixinParam(options.url || '', options.params || {});\n    }\n\n    if (params.intercept !== undefined) {\n        configRef.value.intercept = params.intercept;\n    }\n\n    mergeConfig.params = params;\n    mergeConfig = uni.$u.deepMerge(configRef.value, mergeConfig);\n\n    if (uni.$u.routeIntercept && typeof uni.$u.routeIntercept === 'function') {\n        const isNext = await new Promise<boolean>(resolve => {\n            uni.$u.routeIntercept(mergeConfig, resolve);\n        });\n        isNext && openPage(mergeConfig);\n    } else {\n        openPage(mergeConfig);\n    }\n};\n\n/**\n * 跳转到指定页面\n */\nconst to = (url: string, params?: Record<string, any>): Promise<void> => {\n    return route({ url, type: 'navigateTo' }, params || {});\n};\n\n/**\n * 关闭当前页面，跳转到指定页面\n */\nconst redirect = (url: string, params?: Record<string, any>): Promise<void> => {\n    return route({ url, type: 'redirectTo' }, params || {});\n};\n\n/**\n * 跳转到 tabBar 页面\n */\nconst tab = (url: string, params?: Record<string, any>): Promise<void> => {\n    return route({ url, type: 'switchTab' }, params || {});\n};\n\n/**\n * 关闭所有页面，跳转到指定页面\n */\nconst reLaunch = (url: string, params?: Record<string, any>): Promise<void> => {\n    return route({ url, type: 'reLaunch' }, params || {});\n};\n\n/**\n * 返回上一页\n */\nconst back = (delta: number = 1): Promise<void> => {\n    return route({ type: 'navigateBack', delta });\n};\n\n/**\n * 设置默认路由配置\n */\nconst setConfig = (newConfig: Partial<RouterConfig>): void => {\n    configRef.value = uni.$u.deepMerge(configRef.value, newConfig);\n};\n\n/**\n * 获取当前路由配置\n */\nconst getConfig = (): RouterConfig => {\n    return { ...configRef.value };\n};\n\nexport function useRouter() {\n    return {\n        // 核心跳转方法\n        route,\n        // 便捷方法\n        to,\n        redirect,\n        tab,\n        reLaunch,\n        back,\n        // 配置方法\n        setConfig,\n        getConfig\n    };\n}\n\nexport default useRouter;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/hooks/useTheme.ts",
    "content": "/**\n * 主题管理 composable\n * 提供主题切换、持久化、CSS 变量注入、暗黑模式等功能\n *\n * 使用方式：\n * const { currentTheme, themes, setTheme, getDarkMode, setDarkMode, isInDarkMode, getAvailableThemes, initTheme } = useTheme()\n */\n\nimport type { DarkMode, Theme } from '../../types/global';\nimport configProvider, { type DefaultThemeConfig } from '../util/config-provider';\nimport { defaultThemes } from '../config/theme-tokens';\n\nconst THEME_STORAGE_KEY = 'uview-pro-theme';\nconst DARK_MODE_STORAGE_KEY = 'uview-pro-dark-mode';\nconst themesRef = configProvider.themesRef;\nconst currentTheme = configProvider.currentThemeRef;\nconst darkModeRef = configProvider.darkModeRef;\n\n/**\n * 保存主题到 Storage\n */\nfunction saveThemeToStorage(themeName: string) {\n    try {\n        uni.setStorageSync(THEME_STORAGE_KEY, themeName);\n    } catch (e) {\n        console.warn('[useTheme] failed to write storage', e);\n    }\n}\n\n/**\n * 保存暗黑模式设置到 Storage\n */\nfunction saveDarkModeToStorage(mode: DarkMode) {\n    try {\n        uni.setStorageSync(DARK_MODE_STORAGE_KEY, mode);\n    } catch (e) {\n        console.warn('[useTheme] failed to write storage', e);\n    }\n}\n\n/**\n * 设置主题\n */\nfunction setTheme(themeName: string) {\n    configProvider.setTheme(themeName);\n    currentTheme.value = configProvider.getCurrentTheme();\n    saveThemeToStorage(themeName);\n}\n\n/**\n * 获取当前主题\n */\nfunction getCurrentTheme(): Theme | null {\n    return currentTheme.value || configProvider.getCurrentTheme();\n}\n\n/**\n * 获取所有可用主题\n */\nfunction getAvailableThemes() {\n    return configProvider.getThemes();\n}\n\n/**\n * 初始化主题系统\n * @param themes 可选的主题列表，如果未提供则尝试从 uni.$u.themes 读取\n * @param defaultConfig 可选的默认主题配置，支持字符串（默认主题名）或对象（{ defaultTheme?, defaultDarkMode? }）\n */\nexport function initTheme(themes?: Theme[], defaultConfig?: string | DefaultThemeConfig, isForce?: boolean) {\n    // 如果有传入主题列表，使用传入的\n    if (Array.isArray(themes) && themes.length > 0) {\n        configProvider.initTheme(themes, defaultConfig, isForce);\n        return;\n    }\n\n    // // 若已通过插件或其他方式完成初始化，则不再覆盖，最多按需切换默认主题\n    // const existingThemes = configProvider.getThemes();\n    // if (existingThemes.length > 0) {\n    //     if (typeof defaultConfig === 'string') {\n    //         configProvider.setTheme(defaultConfig);\n    //     } else if (defaultConfig && typeof defaultConfig === 'object' && (defaultConfig as any).defaultTheme) {\n    //         configProvider.setTheme(defaultConfig.defaultTheme);\n    //     } else if (!configProvider.getCurrentTheme()) {\n    //         configProvider.setTheme(existingThemes[0].name);\n    //     } else {\n    //         // 触发一次 apply，便于初始化 CSS 变量\n    //         configProvider.setTheme(configProvider.getCurrentTheme()!.name);\n    //     }\n    //     return;\n    // }\n\n    // // 初始化 configProvider（如果运行时提供了内置主题）\n    // try {\n    //     const builtin = (typeof uni !== 'undefined' && (uni as any).$u && (uni as any).$u.themes) || [];\n    //     if (Array.isArray(builtin) && builtin.length > 0) {\n    //         configProvider.initTheme(builtin as Theme[], defaultConfig);\n    //         return;\n    //     }\n    // } catch (e) {\n    //     // ignore\n    // }\n\n    // 回退到内置默认主题\n    configProvider.initTheme(defaultThemes as Theme[], defaultConfig);\n}\n\n/**\n * 初始化暗黑模式\n * @param darkMode 暗黑模式设置\n * @param isForce 是否强制初始化\n */\nfunction initDarkMode(darkMode?: DarkMode, isForce?: boolean) {\n    configProvider.initDarkMode(darkMode, isForce);\n}\n/**\n * 获取当前暗黑模式设置\n */\nfunction getDarkMode(): DarkMode {\n    return configProvider.getDarkMode();\n}\n\n/**\n * 设置暗黑模式\n * @param mode 'auto' (跟随系统) | 'light' (强制亮色) | 'dark' (强制暗黑)\n */\nfunction setDarkMode(mode: DarkMode) {\n    configProvider.setDarkMode(mode);\n    darkModeRef.value = mode;\n    saveDarkModeToStorage(mode);\n}\n\n/**\n * 检查当前是否处于暗黑模式\n */\nfunction isInDarkMode(): boolean {\n    return configProvider.isInDarkMode();\n}\n\n/**\n * 切换暗黑模式（在当前模式的基础上切换）\n */\nfunction toggleDarkMode() {\n    const current = getDarkMode();\n    const nextMode = current === 'dark' ? 'light' : 'dark';\n    setDarkMode(nextMode);\n}\n\n/**\n * 使用主题的 composable\n * 返回所有主题相关的响应式引用和方法\n */\nexport function useTheme() {\n    return {\n        // 响应式引用\n        currentTheme,\n        themes: themesRef,\n        darkMode: darkModeRef,\n        cssVars: configProvider.cssVarsRef,\n\n        // 主题相关方法\n        initTheme,\n        setTheme,\n        getCurrentTheme,\n        getAvailableThemes,\n\n        // 暗黑模式相关方法\n        initDarkMode,\n        getDarkMode,\n        setDarkMode,\n        isInDarkMode,\n        toggleDarkMode\n    };\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/hooks/useThrottle.ts",
    "content": "export function useThrottle(delay: number = 500) {\n    let previous: number = 0;\n    // 节流函数\n    function throttle(callback: () => void, throttleTime?: number) {\n        throttleTime = throttleTime || delay;\n        let now = Date.now();\n        if (now - previous > throttleTime) {\n            callback();\n            previous = now;\n        }\n    }\n\n    return {\n        throttle\n    };\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/hooks/useToast.ts",
    "content": "import {\n    U_TOAST_EVENT_HIDE,\n    U_TOAST_EVENT_SHOW,\n    U_TOAST_GLOBAL_EVENT_HIDE,\n    U_TOAST_GLOBAL_EVENT_SHOW,\n    getEventWithCurrentPage,\n    type ToastPayload\n} from '../../components/u-toast/service';\nimport type { ThemeType } from '../../types/global';\n\nexport type UseToastShowOptions = ToastPayload;\n\nexport type UseToast = {\n    /**\n     * 显示 toast\n     * - show('文本')\n     * - show({ title, type, duration, ... })\n     */\n    show: (titleOrOptions: string | UseToastShowOptions) => void;\n    /** 关闭 toast */\n    close: () => void;\n    /** 成功 */\n    success: (titleOrOptions: string | UseToastShowOptions) => void;\n    /** 错误 */\n    error: (titleOrOptions: string | UseToastShowOptions) => void;\n    /** 警告 */\n    warning: (titleOrOptions: string | UseToastShowOptions) => void;\n    /** 信息 */\n    info: (titleOrOptions: string | UseToastShowOptions) => void;\n    /** 加载中（默认常驻，需 close 关闭） */\n    loading: (titleOrOptions: string | UseToastShowOptions) => void;\n};\n\nexport type UseToastOptions = {\n    /** 是否使用全局根部 <u-toast global />，默认 true；为 false 时走页面级 <u-toast /> */\n    global?: boolean;\n    /** 是否使用页面级 <u-toast page /> 或某个页面的 <u-toast page=\"pageId\" /> */\n    page?: boolean | string;\n};\n\nfunction normalize(titleOrOptions: string | UseToastShowOptions): UseToastShowOptions {\n    if (typeof titleOrOptions === 'string') return { title: titleOrOptions };\n    return titleOrOptions || {};\n}\n\nfunction getPage(optionsOrGlobal: UseToastOptions | boolean): string {\n    if (typeof optionsOrGlobal === 'boolean') {\n        return '';\n    }\n    if (optionsOrGlobal.page && typeof optionsOrGlobal.page === 'string' && optionsOrGlobal.page !== '') {\n        return optionsOrGlobal.page;\n    }\n    return '';\n}\n\n/**\n * Toast 函数式调用\n * @description 需要页面/应用中至少存在一个 <u-toast global /> 或 <u-toast page /> 实例用于承接事件；不影响原 ref 调用方式。\n *\n * 支持两种调用方式：\n * - 应用级 useToast() / useToast(true) / useToast({ global: true })\n * - 页面级 useToast(false) / useToast({ page: true }) / useToast({ page: 'pageId' }) （pageId 应和页面中 <u-toast page=\"pageId\" /> 的 page 属性一致）\n */\nexport function useToast(optionsOrGlobal: UseToastOptions | boolean = true): UseToast {\n    const isGlobal = typeof optionsOrGlobal === 'boolean' ? optionsOrGlobal === true : !!optionsOrGlobal.global;\n    const isPage = typeof optionsOrGlobal === 'boolean' ? optionsOrGlobal === false : !!optionsOrGlobal.page;\n    const showEvent = isGlobal\n        ? U_TOAST_GLOBAL_EVENT_SHOW\n        : isPage\n          ? getEventWithCurrentPage(U_TOAST_EVENT_SHOW, getPage(optionsOrGlobal))\n          : '';\n    const hideEvent = isGlobal\n        ? U_TOAST_GLOBAL_EVENT_HIDE\n        : isPage\n          ? getEventWithCurrentPage(U_TOAST_EVENT_HIDE, getPage(optionsOrGlobal))\n          : '';\n\n    function emitShow(payload: UseToastShowOptions) {\n        if (showEvent) {\n            uni?.$emit && uni.$emit(showEvent, payload);\n        }\n    }\n\n    function emitHide() {\n        if (hideEvent) {\n            uni?.$emit && uni.$emit(hideEvent);\n        }\n    }\n    function show(titleOrOptions: string | UseToastShowOptions) {\n        emitShow(normalize(titleOrOptions));\n    }\n\n    function close() {\n        emitHide();\n    }\n\n    function withType(type: ThemeType, titleOrOptions: string | UseToastShowOptions) {\n        const options = normalize(titleOrOptions);\n        emitShow({ ...options, type });\n    }\n\n    return {\n        show,\n        close,\n        success: (v: any) => withType('success', v),\n        error: (v: any) => withType('error', v),\n        warning: (v: any) => withType('warning', v),\n        info: (v: any) => withType('info', v),\n        loading: (v: any) => {\n            const options = normalize(v);\n            // loading 通常需要常驻，除非用户显式传 duration\n            emitShow({ ...options, loading: true, duration: options.duration ?? 0 });\n        }\n    };\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/index.ts",
    "content": "// post类型对象参数转为get类型url参数\nimport queryParams from './function/queryParams';\n// 路由封装\nimport route from './function/route';\n// 时间格式化\nimport timeFormat from './function/timeFormat';\n// 时间戳格式化,返回多久之前\nimport timeFrom from './function/timeFrom';\n// 颜色渐变相关,colorGradient-颜色渐变,hexToRgb-十六进制颜色转rgb颜色,rgbToHex-rgb转十六进制\nimport colorGradients from './function/colorGradient';\n// 生成全局唯一guid字符串\nimport guid from './function/guid';\n// 主题相关颜色,info|success|warning|primary|default|error,此颜色已在uview.scss中定义,但是为js中也能使用,故也定义一份\nimport { color } from './config/color';\nimport { getColor, setColor } from './function/color';\n// 根据type获取图标名称\nimport type2icon from './function/type2icon';\n// 打乱数组的顺序\nimport randomArray from './function/randomArray';\n// 对象和数组的深度克隆\nimport deepClone from './function/deepClone';\n// 对象深度拷贝\nimport deepMerge from './function/deepMerge';\n// 添加单位\nimport addUnit from './function/addUnit';\n// 规则检验\nimport test from './function/test';\n// 随机数\nimport random from './function/random';\n// 去除空格\nimport trim from './function/trim';\n// toast提示，对uni.showToast的封装\nimport toast from './function/toast';\n// 获取父组件参数\nimport getParent from './function/getParent';\n// 获取整个父组件\nimport $parent from './function/$parent';\n// 获取sys()和os()工具方法\n// 获取设备信息，挂载到$u的sys()(system的缩写)属性中，\n// 同时把安卓和ios平台的名称\"ios\"和\"android\"挂到$u.os()中，方便取用\nimport { sys, os } from './function/sys';\n// 防抖方法\nimport debounce from './function/debounce';\n// 节流方法\nimport throttle from './function/throttle';\n// 获取元素的位置信息\nimport getRect from './function/getRect';\n// 剪贴板\nimport { clipboard } from './function/clipboard';\n// 配置信息\nimport config from './config/config';\n// 各个需要fixed的地方的z-index配置文件\nimport zIndex from './config/zIndex';\nimport { mitt } from './util/mitt';\n// http相关\nimport httpPlugin, {\n    Request,\n    http,\n    type RequestOptions,\n    type RequestConfig,\n    type RequestInterceptor,\n    type RequestMeta\n} from './request/index';\n\n/**\n * @description 数字格式化\n * @param number 要格式化的数字\n * @param decimals 保留几位小数\n * @param decimalPoint 小数点符号\n * @param thousandsSeparator 千分位符号\n * @returns 格式化后的数字\n */\nexport function formatPrice(\n    number: number | string,\n    decimals: number = 0,\n    decimalPoint: string = '.',\n    thousandsSeparator: string = ','\n): string {\n    // 辅助函数：四舍五入到指定小数位\n    function round(num: number, precision: number): string {\n        const factor = Math.pow(10, precision);\n        return (Math.round(num * factor) / factor).toFixed(precision);\n    }\n\n    let numStr = String(number).replace(/[^0-9+\\-Ee.]/g, '');\n    const n = !isFinite(+numStr) ? 0 : +numStr;\n    const prec = !isFinite(+decimals) ? 0 : Math.abs(decimals);\n    const sep = thousandsSeparator ?? ',';\n    const dec = decimalPoint ?? '.';\n    let s: string[] = [];\n\n    s = (prec ? round(n, prec) : Math.round(n).toString()).split('.');\n    const re = /(-?\\d+)(\\d{3})/;\n    while (re.test(s[0])) {\n        s[0] = s[0].replace(re, `$1${sep}$2`);\n    }\n\n    if ((s[1] || '').length < prec) {\n        s[1] = s[1] || '';\n        s[1] += '0'.repeat(prec - s[1].length);\n    }\n    return s.join(dec);\n}\n\n// 默认的姓名脱敏规则\nexport function formatName(name: string): string {\n    if (name.length === 2) {\n        return name.charAt(0) + '*';\n    } else if (name.length > 2) {\n        const masked = '*'.repeat(name.length - 2);\n        return name.charAt(0) + masked + name.charAt(name.length - 1);\n    } else {\n        return name;\n    }\n}\n\n/**\n * @description 样式转换\n * 对象转字符串，或者字符串转对象\n * @param {object | string} customStyle 需要转换的目标\n * @param {String} target 转换的目的，object-转为对象，string-转为字符串\n * @returns {object|string}\n */\nexport function addStyle(\n    customStyle: Record<string, string> | string,\n    target: 'object' | 'string' = 'object'\n): Record<string, string> | string {\n    // 字符串转字符串，对象转对象情形，直接返回\n    if (\n        test.empty(customStyle) ||\n        (typeof customStyle === 'object' && target === 'object') ||\n        (target === 'string' && typeof customStyle === 'string')\n    ) {\n        return customStyle;\n    }\n    // 字符串转对象\n    if (target === 'object') {\n        // 去除字符串样式中的两端空格\n        const trimmedStyle = trim(customStyle as string);\n        const styleArray = trimmedStyle.split(';');\n        const style: Record<string, string> = {};\n        for (let i = 0; i < styleArray.length; i++) {\n            if (styleArray[i]) {\n                const item = styleArray[i].split(':');\n                if (item.length === 2) {\n                    style[trim(item[0])] = trim(item[1]);\n                }\n            }\n        }\n        return style;\n    }\n    // 对象转字符串\n    let string = '';\n    for (const i in customStyle as Record<string, string>) {\n        if (Object.prototype.hasOwnProperty.call(customStyle, i)) {\n            const key = i.replace(/([A-Z])/g, '-$1').toLowerCase();\n            string += `${key}:${(customStyle as Record<string, string>)[i]};`;\n        }\n    }\n    return trim(string);\n}\n\n/**\n * 将外部传入的样式格式化为可读的 CSS 样式。\n * @param {object | object[]} styles 外部传入的样式对象或数组\n * @returns {string} 格式化后的 CSS 样式字符串\n */\nexport function toStyle(...styles: Array<Record<string, any> | string | null | undefined>): string {\n    // 支持多参数：每个参数可以是 object 或 string，后面的参数优先级更高，会覆盖同名样式\n    // 如果传入单个数组（兼容旧调用），解构展开\n    if (styles.length === 1 && Array.isArray(styles[0])) {\n        styles = (styles[0] as any[]).slice();\n    }\n\n    // 用于合并样式的 Map，key 使用 kebab-case\n    const map = new Map<string, any>();\n\n    const processString = (str: string) => {\n        if (!str) return;\n        // 移除可能的末尾分号，再按分号分割\n        const parts = str.split(';');\n        for (let part of parts) {\n            part = part.trim();\n            if (!part) continue;\n            const idx = part.indexOf(':');\n            if (idx === -1) continue;\n            const key = trim(part.slice(0, idx));\n            const val = trim(part.slice(idx + 1));\n            if (key === '' || val === '') continue;\n            const k = kebabCase(key);\n            map.set(k, val);\n        }\n    };\n\n    const processObject = (obj: Record<string, any>) => {\n        if (!obj) return;\n        Object.keys(obj).forEach(key => {\n            const val = obj[key];\n            if (val == null || val === '') return;\n            const k = kebabCase(key);\n            map.set(k, val);\n        });\n    };\n\n    for (const item of styles) {\n        if (item == null || item === '') continue;\n        if (test.string(item)) {\n            processString(item as string);\n        } else if (test.array(item)) {\n            // 若传入数组作为参数，递归处理数组元素\n            (item as any[]).forEach(el => {\n                if (test.string(el)) processString(el as string);\n                else if (test.object(el)) processObject(el as Record<string, any>);\n            });\n        } else if (test.object(item)) {\n            processObject(item as Record<string, any>);\n        }\n    }\n\n    if (map.size === 0) return '';\n\n    // 按插入顺序构造样式字符串，值转成字符串\n    const result = Array.from(map.entries())\n        .map(([k, v]) => `${k}:${String(v)}`)\n        .join(';');\n\n    return result ? (result.endsWith(';') ? result : result + ';') : '';\n}\n\n/**\n * 将驼峰命名转换为短横线命名。\n * @param {string} word 待转换的词条\n * @returns {string} 转换后的结果\n */\nexport function kebabCase(word: string): string {\n    // 使用正则表达式匹配所有大写字母，并在前面加上短横线，然后转换为小写\n    const newWord: string = word\n        .replace(/[A-Z]/g, function (match) {\n            return '-' + match;\n        })\n        .toLowerCase();\n\n    return newWord;\n}\n\n/**\n * @description 进行延时，以达到可以简写代码的目的 比如: await uni.$u.sleep(20)将会阻塞20ms\n * @param {number} value 堵塞时间 单位ms 毫秒\n * @returns {Promise} 返回promise\n */\nexport function sleep(value: number = 30): Promise<boolean> {\n    return new Promise(resolve => {\n        setTimeout(() => {\n            resolve(true);\n        }, value);\n    });\n}\n\nexport {\n    queryParams,\n    route,\n    timeFormat,\n    timeFrom,\n    guid,\n    color,\n    getColor,\n    setColor,\n    sys,\n    os,\n    type2icon,\n    randomArray,\n    deepClone,\n    deepMerge,\n    addUnit,\n    test,\n    random,\n    trim,\n    toast,\n    debounce,\n    throttle,\n    getRect,\n    getParent,\n    $parent,\n    clipboard,\n    config,\n    zIndex,\n    mitt\n};\n\nexport const $u = {\n    queryParams: queryParams,\n    route: route,\n    timeFormat: timeFormat,\n    date: timeFormat, // 另名date\n    timeFrom,\n    colorGradient: colorGradients.colorGradient,\n    colorToRgba: colorGradients.colorToRgba,\n    guid,\n    color,\n    getColor,\n    setColor,\n    sys,\n    os,\n    type2icon,\n    randomArray,\n    hexToRgb: colorGradients.hexToRgb,\n    rgbToHex: colorGradients.rgbToHex,\n    test,\n    random,\n    deepClone,\n    deepMerge,\n    getParent,\n    $parent,\n    clipboard,\n    addUnit,\n    trim,\n    type: ['primary', 'success', 'error', 'warning', 'info'],\n    http,\n    toast,\n    config, // uView配置信息相关，比如版本号\n    zIndex,\n    debounce,\n    throttle,\n    mitt: mitt(),\n    getRect,\n    formatPrice,\n    formatName,\n    addStyle,\n    toStyle,\n    kebabCase,\n    sleep\n};\n\n// 颜色相关方法单独导出\nexport const { colorGradient, colorToRgba, hexToRgb, rgbToHex } = colorGradients;\n// http相关导出\nexport {\n    Request,\n    httpPlugin,\n    http,\n    type RequestOptions,\n    type RequestConfig,\n    type RequestInterceptor,\n    type RequestMeta\n};\n\nexport * from './hooks';\n\nexport * from './util/config-provider';\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/request/auto-http.ts",
    "content": "import deepMerge from '../function/deepMerge';\n\nexport function isFunction(f: any): boolean {\n    return typeof f === 'function';\n}\n\nexport function isPromise(p: any): boolean {\n    return !!(p && p.then && p.catch);\n}\n\nexport function isArray(arr: any) {\n    return Object.prototype.toString.call(arr) === '[object Array]';\n}\n\n/**\n * 构建基础类\n */\nclass Builder<T> {\n    instance: any;\n\n    constructor(instance: any) {\n        this.instance = instance;\n    }\n    /**\n     *\n     * @param urlConfig url 配置表\n     * @param extra 其他请求方法对象\n     * @returns Object\n     */\n    dispatch(urlConfig: Record<string, any>, extra: Record<string, any> = {}): Record<string, any> {\n        const builder: Record<string, any> = {};\n        // 创建 API\n        Object.keys(urlConfig).forEach(name => {\n            builder[name] = this.use.bind(this, urlConfig[name]);\n        });\n        return { ...builder, ...extra };\n    }\n    /**\n     * 发送请求\n     * @param {*} urlConfig : url 配置表\n     * @demo urlConfig = { login: { url: '/user/login', method: 'GET', loading: true } }\n     * @param {*} config : 开放配置，用户主动配置的\n     * @demo api.login({ params: { username: \"admin\" } })\n     * @returns Promise\n     */\n    use(urlConfig: Record<string, any>, config: Record<string, any> = {}): Promise<T> {\n        // 请求地址\n        let url = config?.url ?? urlConfig.url;\n        // 兼容 restful url，如果是使用url为function，则为restful格式\n        if (config.url && isFunction(config.url)) {\n            url = `${urlConfig.url}${config.url()}`;\n        }\n        // 请求类型，get,post,put,delete\n        const method = config?.method ?? urlConfig?.method ?? 'GET';\n        // 如果有自定义的工厂函数基础类\n        const options = { ...deepMerge(urlConfig, config), url, method };\n        if (isFunction(this.instance) || isPromise(this.instance)) {\n            return this.instance(options);\n        }\n        // 如果是使用的 instance\n        // 默认的请求基础类\n        return this.instance.request(options);\n    }\n}\n\n/**\n * Http 基础类\n */\nclass AutoHttp {\n    static get Builder() {\n        return Builder;\n    }\n    constructor() {}\n}\n\nexport { AutoHttp };\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/request/index.ts",
    "content": "import deepMerge from '../function/deepMerge';\n\n/**\n * 请求配置项Meta类型定义\n */\nexport interface RequestMeta {\n    toast?: boolean;\n    loading?: boolean;\n    originalData?: boolean;\n    [key: string]: any;\n}\n\n/**\n * 请求配置项类型定义\n */\nexport interface RequestConfig {\n    baseUrl?: string;\n    header?: Record<string, any>;\n    method?: string;\n    dataType?: string;\n    responseType?: string;\n    timeout?: number;\n    meta?: RequestMeta;\n    [key: string]: any;\n}\n\n/**\n * 忽略的请求参数类型定义\n */\nconst IGNORE_REQUEST_KEYS = ['baseUrl', 'meta'];\n\n/**\n * 请求拦截器类型定义\n */\nexport interface RequestInterceptor {\n    request?: ((options: RequestOptions) => RequestOptions | false) | null;\n    response?: ((response: any) => any | false) | null;\n}\n\n/**\n * 请求参数类型定义\n */\nexport interface RequestOptions {\n    url: string;\n    header: Record<string, any>;\n    method: 'GET' | 'POST' | 'OPTIONS' | 'HEAD' | 'PUT' | 'DELETE' | 'TRACE' | 'CONNECT';\n    data?: any;\n    dataType?: string;\n    responseType?: string;\n    params?: Record<string, any>;\n    complete?: (response: any) => void;\n    meta?: RequestMeta;\n    [key: string]: any;\n}\n\nexport class Request {\n    public config: RequestConfig;\n    public interceptor: RequestInterceptor;\n    public options?: RequestOptions;\n\n    constructor() {\n        this.config = {\n            baseUrl: '', // 请求的根域名\n            header: {}, // 默认的请求头\n            method: 'POST', // 请求方式\n            dataType: 'json', // 设置为json，返回后uni.request会对数据进行一次JSON.parse\n            responseType: 'text', // 此参数无需处理，因为5+和支付宝小程序不支持，默认为text即可\n            timeout: 60000,\n            meta: {\n                originalData: true, // 是否在拦截器中返回服务端的原始数据，见文档说明\n                toast: false, // 是否在请求出错时，弹出toast\n                loading: false // 是否显示加载中\n            }\n        };\n        this.interceptor = {\n            request: null,\n            response: null\n        };\n    }\n    /**\n     * 将全局配置合并到本次请求的 options 中\n     * - 忽略 IGNORE_REQUEST_KEYS 中的字段（如 meta）\n     * - 对 header 使用深合并（全局 header 为默认，options.header 优先）\n     * - 对对象类型的字段尝试深合并，基础类型以 options 值优先\n     * - 处理 baseUrl：若存在全局 baseUrl 且 options.url 非完整 url（非 http 开头），则合并成完整 URL\n     */\n    private mergeGlobalConfigToOptions(options: RequestOptions): RequestOptions {\n        const mergedOptions: RequestOptions = { ...options };\n        for (const key of Object.keys(this.config)) {\n            if (IGNORE_REQUEST_KEYS.includes(key)) {\n                continue;\n            }\n            const cfgVal = this.config[key];\n            const optVal = options[key];\n\n            // 跳过未设置的全局配置\n            if (cfgVal === undefined) continue;\n\n            // header 需要做深合并，且以 options.header 为准覆盖同名属性\n            if (key === 'header') {\n                mergedOptions.header = deepMerge(cfgVal || {}, optVal || {});\n                continue;\n            }\n\n            // 针对 method 等枚举字符串，优先使用 options 中的值，否则使用全局配置\n            if (typeof cfgVal === 'string' || typeof cfgVal === 'number' || typeof cfgVal === 'boolean') {\n                mergedOptions[key] = optVal !== undefined ? optVal : cfgVal;\n                continue;\n            }\n\n            // 对对象类型的配置（如自定义扩展）尝试做深合并\n            if (typeof cfgVal === 'object' && !Array.isArray(cfgVal)) {\n                mergedOptions[key] = deepMerge(cfgVal || {}, optVal || {});\n                continue;\n            }\n\n            // 其他类型，若 options 未传入则使用全局配置\n            if (optVal === undefined) {\n                mergedOptions[key] = cfgVal;\n            }\n        }\n        // 如果存在 baseUrl，并且 options.url 为相对地址，则拼接成完整 url\n        const baseUrl = this.config.baseUrl;\n        if (\n            baseUrl &&\n            mergedOptions.url &&\n            typeof mergedOptions.url === 'string' &&\n            mergedOptions.url.indexOf('http') !== 0\n        ) {\n            mergedOptions.url =\n                baseUrl + (mergedOptions.url.indexOf('/') === 0 ? mergedOptions.url : `/${mergedOptions.url}`);\n        }\n        // 确保 url 存在，且为 string\n        if (!mergedOptions.url) {\n            mergedOptions.url = '';\n        }\n        return mergedOptions;\n    }\n    /**\n     * 设置全局默认配置\n     * @param customConfig 自定义配置\n     */\n    setConfig(customConfig: Partial<RequestConfig>): void {\n        this.config = deepMerge(this.config, customConfig);\n    }\n\n    /**\n     * 主要请求部分\n     * @param options 请求参数\n     */\n    request<T = unknown>(options: RequestOptions): Promise<T> {\n        // 合并 meta 配置，优先级：单次请求 > 全局\n        const mergedMeta: RequestMeta = {\n            ...this.config.meta,\n            ...(options.meta || {})\n        };\n        // 让 options.meta 传递到拦截器\n        options.meta = mergedMeta;\n        options.url = options.url || '';\n        options.params = options.params || {};\n        // 将全局配置合并到本次请求 options 中（注意忽略一些特殊字段如 baseUrl/meta）\n        options = this.mergeGlobalConfigToOptions(options);\n\n        if (this.interceptor.request && typeof this.interceptor.request === 'function') {\n            const interceptorRequest = this.interceptor.request(options);\n            if (!interceptorRequest) {\n                // 返回一个处于pending状态中的Promise，来取消原promise，避免进入then()回调\n                return new Promise(() => {});\n            }\n            this.options = interceptorRequest;\n        }\n\n        return new Promise<T>((resolve, reject) => {\n            options.complete = (response: any) => {\n                // 读取 meta 配置\n                const meta = options.meta || this.config.meta || {};\n                const originalData = meta.originalData ?? false;\n                // 拦截器处理，加入request的配置参数\n                response.config = options;\n                if (originalData) {\n                    // 判断是否存在拦截器\n                    if (this.interceptor.response && typeof this.interceptor.response === 'function') {\n                        const resInterceptors = this.interceptor.response(response);\n                        // 如果拦截器不返回false，就将拦截器返回的内容给请求的then回调\n                        if (resInterceptors !== false) {\n                            resolve(resInterceptors);\n                        } else {\n                            // 如果拦截器返回false，意味着拦截器定义者认为返回有问题，直接接入catch回调\n                            reject(response);\n                        }\n                    } else {\n                        // 如果要求返回原始数据，就算没有拦截器，也返回最原始的数据\n                        resolve(response);\n                    }\n                } else {\n                    if (response.statusCode === 200) {\n                        if (this.interceptor.response && typeof this.interceptor.response === 'function') {\n                            const resInterceptors = this.interceptor.response(response.data);\n                            if (resInterceptors !== false) {\n                                resolve(resInterceptors);\n                            } else {\n                                reject(response.data);\n                            }\n                        } else {\n                            // 如果不是返回原始数据(originalData=false)，且没有拦截器的情况下，返回纯数据给then回调\n                            resolve(response.data);\n                        }\n                    } else {\n                        reject(response);\n                    }\n                }\n            };\n            uni.request(options);\n        });\n    }\n\n    get<T = unknown>(\n        url: string,\n        data: any = {},\n        options: { header?: Record<string, any>; meta?: RequestMeta } = {}\n    ): Promise<T> {\n        return this.request<T>({\n            method: 'GET',\n            url,\n            data,\n            header: options.header || {},\n            meta: options.meta\n        });\n    }\n\n    post<T = unknown>(\n        url: string,\n        data: any = {},\n        options: { header?: Record<string, any>; meta?: RequestMeta } = {}\n    ): Promise<T> {\n        return this.request<T>({\n            url,\n            method: 'POST',\n            data,\n            header: options.header || {},\n            meta: options.meta\n        });\n    }\n\n    put<T = unknown>(\n        url: string,\n        data: any = {},\n        options: { header?: Record<string, any>; meta?: RequestMeta } = {}\n    ): Promise<T> {\n        return this.request<T>({\n            url,\n            method: 'PUT',\n            data,\n            header: options.header || {},\n            meta: options.meta\n        });\n    }\n\n    delete<T = unknown>(\n        url: string,\n        data: any = {},\n        options: { header?: Record<string, any>; meta?: RequestMeta } = {}\n    ): Promise<T> {\n        return this.request<T>({\n            url,\n            method: 'DELETE',\n            data,\n            header: options.header || {},\n            meta: options.meta\n        });\n    }\n}\n\n// 插件化导出，支持 app.use(http, { interceptor })\nconst httpInstance = new Request();\n\ninterface HttpPluginOptions {\n    requestConfig?: Partial<RequestConfig>;\n    interceptor?: RequestInterceptor;\n}\n\n// 全局导出，支持 import { httpPlugin } from 'uview-pro'\nconst httpPlugin = {\n    install(app: any, options: HttpPluginOptions = {}) {\n        if (options.interceptor) {\n            const { request, response } = options.interceptor;\n            if (request) httpInstance.interceptor.request = request;\n            if (response) httpInstance.interceptor.response = response;\n        }\n        if (options.requestConfig) {\n            httpInstance.setConfig(options.requestConfig);\n        }\n        app.config.globalProperties.$http = httpInstance;\n    }\n};\n\n// 全局导出，支持 import { http } from 'uview-pro'\nexport { httpInstance as http };\n\n// 插件化导出，支持 app.use(http, { interceptor })\nexport default httpPlugin;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/store/index.ts",
    "content": "/**\n * 支持通过 name 路径批量/单项赋值 Pinia store 的工具方法\n * @param store Pinia store 实例\n * @param params { name: string, value: any }\n * name 支持 a.b.c 形式嵌套赋值\n */\n/**\n * 用法示例：\n * setStoreValue(userStore, { name: 'profile.avatar', value: 'xxx.png' })\n * setStoreValueTyped(userStore, 'token', 'xxxx')\n * setStoreValues(userStore, [{ name: 'token', value: 'xxx' }, { name: 'profile.avatar', value: 'img.png' }])\n * getStoreValue(userStore, 'profile.avatar')\n * resetStore(userStore, { token: '', profile: { avatar: '' } })\n */\nexport function setStoreValue<T extends object>(store: T, params: { name: string; value: any }): void {\n    const nameArr = params.name.split('.');\n    let obj: any = store;\n    if (nameArr.length >= 2) {\n        for (let i = 0; i < nameArr.length - 1; i++) {\n            if (!(nameArr[i] in obj)) {\n                obj[nameArr[i]] = {};\n            }\n            obj = obj[nameArr[i]];\n        }\n        obj[nameArr[nameArr.length - 1]] = params.value;\n    } else {\n        (store as any)[params.name] = params.value;\n    }\n}\n\n/**\n * 类型安全的嵌套属性赋值工具\n * @param store Pinia store 实例\n * @param path 属性路径（如 profile.avatar）\n * @param value 赋值内容\n */\nexport function setStoreValueTyped<T, K extends keyof T>(store: T, path: K, value: T[K]): void;\nexport function setStoreValueTyped<T>(store: T, path: string, value: any): void {\n    const nameArr = path.split('.');\n    let obj: any = store;\n    if (nameArr.length >= 2) {\n        for (let i = 0; i < nameArr.length - 1; i++) {\n            if (!(nameArr[i] in obj)) {\n                obj[nameArr[i]] = {};\n            }\n            obj = obj[nameArr[i]];\n        }\n        obj[nameArr[nameArr.length - 1]] = value;\n    } else {\n        (store as any)[path] = value;\n    }\n}\n\n/**\n * 批量赋值 Pinia store 工具方法\n * @param store Pinia store 实例\n * @param values { name: string, value: any }[]\n */\nexport function setStoreValues<T extends object>(store: T, values: Array<{ name: string; value: any }>): void {\n    values.forEach(item => setStoreValue(store, item));\n}\n\n/**\n * 获取嵌套属性值\n * @param store Pinia store 实例\n * @param path 属性路径（如 profile.avatar）\n * @returns 属性值\n */\nexport function getStoreValue<T>(store: T, path: string): any {\n    const nameArr = path.split('.');\n    let obj: any = store;\n    for (let i = 0; i < nameArr.length; i++) {\n        if (obj == null) return undefined;\n        obj = obj[nameArr[i]];\n    }\n    return obj;\n}\n\n/**\n * 重置 Pinia store 为初始值\n * @param store Pinia store 实例\n * @param initial 初始值对象\n */\nexport function resetStore<T extends object>(store: T, initial: Partial<T>): void {\n    Object.keys(initial).forEach(key => {\n        (store as any)[key] = (initial as any)[key];\n    });\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/util/area.ts",
    "content": "export default [[[{label:\"东城区\",value:\"110101\"},{label:\"西城区\",value:\"110102\"},{label:\"朝阳区\",value:\"110105\"},{label:\"丰台区\",value:\"110106\"},{label:\"石景山区\",value:\"110107\"},{label:\"海淀区\",value:\"110108\"},{label:\"门头沟区\",value:\"110109\"},{label:\"房山区\",value:\"110111\"},{label:\"通州区\",value:\"110112\"},{label:\"顺义区\",value:\"110113\"},{label:\"昌平区\",value:\"110114\"},{label:\"大兴区\",value:\"110115\"},{label:\"怀柔区\",value:\"110116\"},{label:\"平谷区\",value:\"110117\"},{label:\"密云区\",value:\"110118\"},{label:\"延庆区\",value:\"110119\"}]],[[{label:\"和平区\",value:\"120101\"},{label:\"河东区\",value:\"120102\"},{label:\"河西区\",value:\"120103\"},{label:\"南开区\",value:\"120104\"},{label:\"河北区\",value:\"120105\"},{label:\"红桥区\",value:\"120106\"},{label:\"东丽区\",value:\"120110\"},{label:\"西青区\",value:\"120111\"},{label:\"津南区\",value:\"120112\"},{label:\"北辰区\",value:\"120113\"},{label:\"武清区\",value:\"120114\"},{label:\"宝坻区\",value:\"120115\"},{label:\"滨海新区\",value:\"120116\"},{label:\"宁河区\",value:\"120117\"},{label:\"静海区\",value:\"120118\"},{label:\"蓟州区\",value:\"120119\"}]],[[{label:\"长安区\",value:\"130102\"},{label:\"桥西区\",value:\"130104\"},{label:\"新华区\",value:\"130105\"},{label:\"井陉矿区\",value:\"130107\"},{label:\"裕华区\",value:\"130108\"},{label:\"藁城区\",value:\"130109\"},{label:\"鹿泉区\",value:\"130110\"},{label:\"栾城区\",value:\"130111\"},{label:\"井陉县\",value:\"130121\"},{label:\"正定县\",value:\"130123\"},{label:\"行唐县\",value:\"130125\"},{label:\"灵寿县\",value:\"130126\"},{label:\"高邑县\",value:\"130127\"},{label:\"深泽县\",value:\"130128\"},{label:\"赞皇县\",value:\"130129\"},{label:\"无极县\",value:\"130130\"},{label:\"平山县\",value:\"130131\"},{label:\"元氏县\",value:\"130132\"},{label:\"赵县\",value:\"130133\"},{label:\"石家庄高新技术产业开发区\",value:\"130171\"},{label:\"石家庄循环化工园区\",value:\"130172\"},{label:\"辛集市\",value:\"130181\"},{label:\"晋州市\",value:\"130183\"},{label:\"新乐市\",value:\"130184\"}],[{label:\"路南区\",value:\"130202\"},{label:\"路北区\",value:\"130203\"},{label:\"古冶区\",value:\"130204\"},{label:\"开平区\",value:\"130205\"},{label:\"丰南区\",value:\"130207\"},{label:\"丰润区\",value:\"130208\"},{label:\"曹妃甸区\",value:\"130209\"},{label:\"滦县\",value:\"130223\"},{label:\"滦南县\",value:\"130224\"},{label:\"乐亭县\",value:\"130225\"},{label:\"迁西县\",value:\"130227\"},{label:\"玉田县\",value:\"130229\"},{label:\"唐山市芦台经济技术开发区\",value:\"130271\"},{label:\"唐山市汉沽管理区\",value:\"130272\"},{label:\"唐山高新技术产业开发区\",value:\"130273\"},{label:\"河北唐山海港经济开发区\",value:\"130274\"},{label:\"遵化市\",value:\"130281\"},{label:\"迁安市\",value:\"130283\"}],[{label:\"海港区\",value:\"130302\"},{label:\"山海关区\",value:\"130303\"},{label:\"北戴河区\",value:\"130304\"},{label:\"抚宁区\",value:\"130306\"},{label:\"青龙满族自治县\",value:\"130321\"},{label:\"昌黎县\",value:\"130322\"},{label:\"卢龙县\",value:\"130324\"},{label:\"秦皇岛市经济技术开发区\",value:\"130371\"},{label:\"北戴河新区\",value:\"130372\"}],[{label:\"邯山区\",value:\"130402\"},{label:\"丛台区\",value:\"130403\"},{label:\"复兴区\",value:\"130404\"},{label:\"峰峰矿区\",value:\"130406\"},{label:\"肥乡区\",value:\"130407\"},{label:\"永年区\",value:\"130408\"},{label:\"临漳县\",value:\"130423\"},{label:\"成安县\",value:\"130424\"},{label:\"大名县\",value:\"130425\"},{label:\"涉县\",value:\"130426\"},{label:\"磁县\",value:\"130427\"},{label:\"邱县\",value:\"130430\"},{label:\"鸡泽县\",value:\"130431\"},{label:\"广平县\",value:\"130432\"},{label:\"馆陶县\",value:\"130433\"},{label:\"魏县\",value:\"130434\"},{label:\"曲周县\",value:\"130435\"},{label:\"邯郸经济技术开发区\",value:\"130471\"},{label:\"邯郸冀南新区\",value:\"130473\"},{label:\"武安市\",value:\"130481\"}],[{label:\"桥东区\",value:\"130502\"},{label:\"桥西区\",value:\"130503\"},{label:\"邢台县\",value:\"130521\"},{label:\"临城县\",value:\"130522\"},{label:\"内丘县\",value:\"130523\"},{label:\"柏乡县\",value:\"130524\"},{label:\"隆尧县\",value:\"130525\"},{label:\"任县\",value:\"130526\"},{label:\"南和县\",value:\"130527\"},{label:\"宁晋县\",value:\"130528\"},{label:\"巨鹿县\",value:\"130529\"},{label:\"新河县\",value:\"130530\"},{label:\"广宗县\",value:\"130531\"},{label:\"平乡县\",value:\"130532\"},{label:\"威县\",value:\"130533\"},{label:\"清河县\",value:\"130534\"},{label:\"临西县\",value:\"130535\"},{label:\"河北邢台经济开发区\",value:\"130571\"},{label:\"南宫市\",value:\"130581\"},{label:\"沙河市\",value:\"130582\"}],[{label:\"竞秀区\",value:\"130602\"},{label:\"莲池区\",value:\"130606\"},{label:\"满城区\",value:\"130607\"},{label:\"清苑区\",value:\"130608\"},{label:\"徐水区\",value:\"130609\"},{label:\"涞水县\",value:\"130623\"},{label:\"阜平县\",value:\"130624\"},{label:\"定兴县\",value:\"130626\"},{label:\"唐县\",value:\"130627\"},{label:\"高阳县\",value:\"130628\"},{label:\"容城县\",value:\"130629\"},{label:\"涞源县\",value:\"130630\"},{label:\"望都县\",value:\"130631\"},{label:\"安新县\",value:\"130632\"},{label:\"易县\",value:\"130633\"},{label:\"曲阳县\",value:\"130634\"},{label:\"蠡县\",value:\"130635\"},{label:\"顺平县\",value:\"130636\"},{label:\"博野县\",value:\"130637\"},{label:\"雄县\",value:\"130638\"},{label:\"保定高新技术产业开发区\",value:\"130671\"},{label:\"保定白沟新城\",value:\"130672\"},{label:\"涿州市\",value:\"130681\"},{label:\"定州市\",value:\"130682\"},{label:\"安国市\",value:\"130683\"},{label:\"高碑店市\",value:\"130684\"}],[{label:\"桥东区\",value:\"130702\"},{label:\"桥西区\",value:\"130703\"},{label:\"宣化区\",value:\"130705\"},{label:\"下花园区\",value:\"130706\"},{label:\"万全区\",value:\"130708\"},{label:\"崇礼区\",value:\"130709\"},{label:\"张北县\",value:\"130722\"},{label:\"康保县\",value:\"130723\"},{label:\"沽源县\",value:\"130724\"},{label:\"尚义县\",value:\"130725\"},{label:\"蔚县\",value:\"130726\"},{label:\"阳原县\",value:\"130727\"},{label:\"怀安县\",value:\"130728\"},{label:\"怀来县\",value:\"130730\"},{label:\"涿鹿县\",value:\"130731\"},{label:\"赤城县\",value:\"130732\"},{label:\"张家口市高新技术产业开发区\",value:\"130771\"},{label:\"张家口市察北管理区\",value:\"130772\"},{label:\"张家口市塞北管理区\",value:\"130773\"}],[{label:\"双桥区\",value:\"130802\"},{label:\"双滦区\",value:\"130803\"},{label:\"鹰手营子矿区\",value:\"130804\"},{label:\"承德县\",value:\"130821\"},{label:\"兴隆县\",value:\"130822\"},{label:\"滦平县\",value:\"130824\"},{label:\"隆化县\",value:\"130825\"},{label:\"丰宁满族自治县\",value:\"130826\"},{label:\"宽城满族自治县\",value:\"130827\"},{label:\"围场满族蒙古族自治县\",value:\"130828\"},{label:\"承德高新技术产业开发区\",value:\"130871\"},{label:\"平泉市\",value:\"130881\"}],[{label:\"新华区\",value:\"130902\"},{label:\"运河区\",value:\"130903\"},{label:\"沧县\",value:\"130921\"},{label:\"青县\",value:\"130922\"},{label:\"东光县\",value:\"130923\"},{label:\"海兴县\",value:\"130924\"},{label:\"盐山县\",value:\"130925\"},{label:\"肃宁县\",value:\"130926\"},{label:\"南皮县\",value:\"130927\"},{label:\"吴桥县\",value:\"130928\"},{label:\"献县\",value:\"130929\"},{label:\"孟村回族自治县\",value:\"130930\"},{label:\"河北沧州经济开发区\",value:\"130971\"},{label:\"沧州高新技术产业开发区\",value:\"130972\"},{label:\"沧州渤海新区\",value:\"130973\"},{label:\"泊头市\",value:\"130981\"},{label:\"任丘市\",value:\"130982\"},{label:\"黄骅市\",value:\"130983\"},{label:\"河间市\",value:\"130984\"}],[{label:\"安次区\",value:\"131002\"},{label:\"广阳区\",value:\"131003\"},{label:\"固安县\",value:\"131022\"},{label:\"永清县\",value:\"131023\"},{label:\"香河县\",value:\"131024\"},{label:\"大城县\",value:\"131025\"},{label:\"文安县\",value:\"131026\"},{label:\"大厂回族自治县\",value:\"131028\"},{label:\"廊坊经济技术开发区\",value:\"131071\"},{label:\"霸州市\",value:\"131081\"},{label:\"三河市\",value:\"131082\"}],[{label:\"桃城区\",value:\"131102\"},{label:\"冀州区\",value:\"131103\"},{label:\"枣强县\",value:\"131121\"},{label:\"武邑县\",value:\"131122\"},{label:\"武强县\",value:\"131123\"},{label:\"饶阳县\",value:\"131124\"},{label:\"安平县\",value:\"131125\"},{label:\"故城县\",value:\"131126\"},{label:\"景县\",value:\"131127\"},{label:\"阜城县\",value:\"131128\"},{label:\"河北衡水经济开发区\",value:\"131171\"},{label:\"衡水滨湖新区\",value:\"131172\"},{label:\"深州市\",value:\"131182\"}]],[[{label:\"小店区\",value:\"140105\"},{label:\"迎泽区\",value:\"140106\"},{label:\"杏花岭区\",value:\"140107\"},{label:\"尖草坪区\",value:\"140108\"},{label:\"万柏林区\",value:\"140109\"},{label:\"晋源区\",value:\"140110\"},{label:\"清徐县\",value:\"140121\"},{label:\"阳曲县\",value:\"140122\"},{label:\"娄烦县\",value:\"140123\"},{label:\"山西转型综合改革示范区\",value:\"140171\"},{label:\"古交市\",value:\"140181\"}],[{label:\"城区\",value:\"140202\"},{label:\"矿区\",value:\"140203\"},{label:\"南郊区\",value:\"140211\"},{label:\"新荣区\",value:\"140212\"},{label:\"阳高县\",value:\"140221\"},{label:\"天镇县\",value:\"140222\"},{label:\"广灵县\",value:\"140223\"},{label:\"灵丘县\",value:\"140224\"},{label:\"浑源县\",value:\"140225\"},{label:\"左云县\",value:\"140226\"},{label:\"大同县\",value:\"140227\"},{label:\"山西大同经济开发区\",value:\"140271\"}],[{label:\"城区\",value:\"140302\"},{label:\"矿区\",value:\"140303\"},{label:\"郊区\",value:\"140311\"},{label:\"平定县\",value:\"140321\"},{label:\"盂县\",value:\"140322\"},{label:\"山西阳泉经济开发区\",value:\"140371\"}],[{label:\"城区\",value:\"140402\"},{label:\"郊区\",value:\"140411\"},{label:\"长治县\",value:\"140421\"},{label:\"襄垣县\",value:\"140423\"},{label:\"屯留县\",value:\"140424\"},{label:\"平顺县\",value:\"140425\"},{label:\"黎城县\",value:\"140426\"},{label:\"壶关县\",value:\"140427\"},{label:\"长子县\",value:\"140428\"},{label:\"武乡县\",value:\"140429\"},{label:\"沁县\",value:\"140430\"},{label:\"沁源县\",value:\"140431\"},{label:\"山西长治高新技术产业园区\",value:\"140471\"},{label:\"潞城市\",value:\"140481\"}],[{label:\"城区\",value:\"140502\"},{label:\"沁水县\",value:\"140521\"},{label:\"阳城县\",value:\"140522\"},{label:\"陵川县\",value:\"140524\"},{label:\"泽州县\",value:\"140525\"},{label:\"高平市\",value:\"140581\"}],[{label:\"朔城区\",value:\"140602\"},{label:\"平鲁区\",value:\"140603\"},{label:\"山阴县\",value:\"140621\"},{label:\"应县\",value:\"140622\"},{label:\"右玉县\",value:\"140623\"},{label:\"怀仁县\",value:\"140624\"},{label:\"山西朔州经济开发区\",value:\"140671\"}],[{label:\"榆次区\",value:\"140702\"},{label:\"榆社县\",value:\"140721\"},{label:\"左权县\",value:\"140722\"},{label:\"和顺县\",value:\"140723\"},{label:\"昔阳县\",value:\"140724\"},{label:\"寿阳县\",value:\"140725\"},{label:\"太谷县\",value:\"140726\"},{label:\"祁县\",value:\"140727\"},{label:\"平遥县\",value:\"140728\"},{label:\"灵石县\",value:\"140729\"},{label:\"介休市\",value:\"140781\"}],[{label:\"盐湖区\",value:\"140802\"},{label:\"临猗县\",value:\"140821\"},{label:\"万荣县\",value:\"140822\"},{label:\"闻喜县\",value:\"140823\"},{label:\"稷山县\",value:\"140824\"},{label:\"新绛县\",value:\"140825\"},{label:\"绛县\",value:\"140826\"},{label:\"垣曲县\",value:\"140827\"},{label:\"夏县\",value:\"140828\"},{label:\"平陆县\",value:\"140829\"},{label:\"芮城县\",value:\"140830\"},{label:\"永济市\",value:\"140881\"},{label:\"河津市\",value:\"140882\"}],[{label:\"忻府区\",value:\"140902\"},{label:\"定襄县\",value:\"140921\"},{label:\"五台县\",value:\"140922\"},{label:\"代县\",value:\"140923\"},{label:\"繁峙县\",value:\"140924\"},{label:\"宁武县\",value:\"140925\"},{label:\"静乐县\",value:\"140926\"},{label:\"神池县\",value:\"140927\"},{label:\"五寨县\",value:\"140928\"},{label:\"岢岚县\",value:\"140929\"},{label:\"河曲县\",value:\"140930\"},{label:\"保德县\",value:\"140931\"},{label:\"偏关县\",value:\"140932\"},{label:\"五台山风景名胜区\",value:\"140971\"},{label:\"原平市\",value:\"140981\"}],[{label:\"尧都区\",value:\"141002\"},{label:\"曲沃县\",value:\"141021\"},{label:\"翼城县\",value:\"141022\"},{label:\"襄汾县\",value:\"141023\"},{label:\"洪洞县\",value:\"141024\"},{label:\"古县\",value:\"141025\"},{label:\"安泽县\",value:\"141026\"},{label:\"浮山县\",value:\"141027\"},{label:\"吉县\",value:\"141028\"},{label:\"乡宁县\",value:\"141029\"},{label:\"大宁县\",value:\"141030\"},{label:\"隰县\",value:\"141031\"},{label:\"永和县\",value:\"141032\"},{label:\"蒲县\",value:\"141033\"},{label:\"汾西县\",value:\"141034\"},{label:\"侯马市\",value:\"141081\"},{label:\"霍州市\",value:\"141082\"}],[{label:\"离石区\",value:\"141102\"},{label:\"文水县\",value:\"141121\"},{label:\"交城县\",value:\"141122\"},{label:\"兴县\",value:\"141123\"},{label:\"临县\",value:\"141124\"},{label:\"柳林县\",value:\"141125\"},{label:\"石楼县\",value:\"141126\"},{label:\"岚县\",value:\"141127\"},{label:\"方山县\",value:\"141128\"},{label:\"中阳县\",value:\"141129\"},{label:\"交口县\",value:\"141130\"},{label:\"孝义市\",value:\"141181\"},{label:\"汾阳市\",value:\"141182\"}]],[[{label:\"新城区\",value:\"150102\"},{label:\"回民区\",value:\"150103\"},{label:\"玉泉区\",value:\"150104\"},{label:\"赛罕区\",value:\"150105\"},{label:\"土默特左旗\",value:\"150121\"},{label:\"托克托县\",value:\"150122\"},{label:\"和林格尔县\",value:\"150123\"},{label:\"清水河县\",value:\"150124\"},{label:\"武川县\",value:\"150125\"},{label:\"呼和浩特金海工业园区\",value:\"150171\"},{label:\"呼和浩特经济技术开发区\",value:\"150172\"}],[{label:\"东河区\",value:\"150202\"},{label:\"昆都仑区\",value:\"150203\"},{label:\"青山区\",value:\"150204\"},{label:\"石拐区\",value:\"150205\"},{label:\"白云鄂博矿区\",value:\"150206\"},{label:\"九原区\",value:\"150207\"},{label:\"土默特右旗\",value:\"150221\"},{label:\"固阳县\",value:\"150222\"},{label:\"达尔罕茂明安联合旗\",value:\"150223\"},{label:\"包头稀土高新技术产业开发区\",value:\"150271\"}],[{label:\"海勃湾区\",value:\"150302\"},{label:\"海南区\",value:\"150303\"},{label:\"乌达区\",value:\"150304\"}],[{label:\"红山区\",value:\"150402\"},{label:\"元宝山区\",value:\"150403\"},{label:\"松山区\",value:\"150404\"},{label:\"阿鲁科尔沁旗\",value:\"150421\"},{label:\"巴林左旗\",value:\"150422\"},{label:\"巴林右旗\",value:\"150423\"},{label:\"林西县\",value:\"150424\"},{label:\"克什克腾旗\",value:\"150425\"},{label:\"翁牛特旗\",value:\"150426\"},{label:\"喀喇沁旗\",value:\"150428\"},{label:\"宁城县\",value:\"150429\"},{label:\"敖汉旗\",value:\"150430\"}],[{label:\"科尔沁区\",value:\"150502\"},{label:\"科尔沁左翼中旗\",value:\"150521\"},{label:\"科尔沁左翼后旗\",value:\"150522\"},{label:\"开鲁县\",value:\"150523\"},{label:\"库伦旗\",value:\"150524\"},{label:\"奈曼旗\",value:\"150525\"},{label:\"扎鲁特旗\",value:\"150526\"},{label:\"通辽经济技术开发区\",value:\"150571\"},{label:\"霍林郭勒市\",value:\"150581\"}],[{label:\"东胜区\",value:\"150602\"},{label:\"康巴什区\",value:\"150603\"},{label:\"达拉特旗\",value:\"150621\"},{label:\"准格尔旗\",value:\"150622\"},{label:\"鄂托克前旗\",value:\"150623\"},{label:\"鄂托克旗\",value:\"150624\"},{label:\"杭锦旗\",value:\"150625\"},{label:\"乌审旗\",value:\"150626\"},{label:\"伊金霍洛旗\",value:\"150627\"}],[{label:\"海拉尔区\",value:\"150702\"},{label:\"扎赉诺尔区\",value:\"150703\"},{label:\"阿荣旗\",value:\"150721\"},{label:\"莫力达瓦达斡尔族自治旗\",value:\"150722\"},{label:\"鄂伦春自治旗\",value:\"150723\"},{label:\"鄂温克族自治旗\",value:\"150724\"},{label:\"陈巴尔虎旗\",value:\"150725\"},{label:\"新巴尔虎左旗\",value:\"150726\"},{label:\"新巴尔虎右旗\",value:\"150727\"},{label:\"满洲里市\",value:\"150781\"},{label:\"牙克石市\",value:\"150782\"},{label:\"扎兰屯市\",value:\"150783\"},{label:\"额尔古纳市\",value:\"150784\"},{label:\"根河市\",value:\"150785\"}],[{label:\"临河区\",value:\"150802\"},{label:\"五原县\",value:\"150821\"},{label:\"磴口县\",value:\"150822\"},{label:\"乌拉特前旗\",value:\"150823\"},{label:\"乌拉特中旗\",value:\"150824\"},{label:\"乌拉特后旗\",value:\"150825\"},{label:\"杭锦后旗\",value:\"150826\"}],[{label:\"集宁区\",value:\"150902\"},{label:\"卓资县\",value:\"150921\"},{label:\"化德县\",value:\"150922\"},{label:\"商都县\",value:\"150923\"},{label:\"兴和县\",value:\"150924\"},{label:\"凉城县\",value:\"150925\"},{label:\"察哈尔右翼前旗\",value:\"150926\"},{label:\"察哈尔右翼中旗\",value:\"150927\"},{label:\"察哈尔右翼后旗\",value:\"150928\"},{label:\"四子王旗\",value:\"150929\"},{label:\"丰镇市\",value:\"150981\"}],[{label:\"乌兰浩特市\",value:\"152201\"},{label:\"阿尔山市\",value:\"152202\"},{label:\"科尔沁右翼前旗\",value:\"152221\"},{label:\"科尔沁右翼中旗\",value:\"152222\"},{label:\"扎赉特旗\",value:\"152223\"},{label:\"突泉县\",value:\"152224\"}],[{label:\"二连浩特市\",value:\"152501\"},{label:\"锡林浩特市\",value:\"152502\"},{label:\"阿巴嘎旗\",value:\"152522\"},{label:\"苏尼特左旗\",value:\"152523\"},{label:\"苏尼特右旗\",value:\"152524\"},{label:\"东乌珠穆沁旗\",value:\"152525\"},{label:\"西乌珠穆沁旗\",value:\"152526\"},{label:\"太仆寺旗\",value:\"152527\"},{label:\"镶黄旗\",value:\"152528\"},{label:\"正镶白旗\",value:\"152529\"},{label:\"正蓝旗\",value:\"152530\"},{label:\"多伦县\",value:\"152531\"},{label:\"乌拉盖管委会\",value:\"152571\"}],[{label:\"阿拉善左旗\",value:\"152921\"},{label:\"阿拉善右旗\",value:\"152922\"},{label:\"额济纳旗\",value:\"152923\"},{label:\"内蒙古阿拉善经济开发区\",value:\"152971\"}]],[[{label:\"和平区\",value:\"210102\"},{label:\"沈河区\",value:\"210103\"},{label:\"大东区\",value:\"210104\"},{label:\"皇姑区\",value:\"210105\"},{label:\"铁西区\",value:\"210106\"},{label:\"苏家屯区\",value:\"210111\"},{label:\"浑南区\",value:\"210112\"},{label:\"沈北新区\",value:\"210113\"},{label:\"于洪区\",value:\"210114\"},{label:\"辽中区\",value:\"210115\"},{label:\"康平县\",value:\"210123\"},{label:\"法库县\",value:\"210124\"},{label:\"新民市\",value:\"210181\"}],[{label:\"中山区\",value:\"210202\"},{label:\"西岗区\",value:\"210203\"},{label:\"沙河口区\",value:\"210204\"},{label:\"甘井子区\",value:\"210211\"},{label:\"旅顺口区\",value:\"210212\"},{label:\"金州区\",value:\"210213\"},{label:\"普兰店区\",value:\"210214\"},{label:\"长海县\",value:\"210224\"},{label:\"瓦房店市\",value:\"210281\"},{label:\"庄河市\",value:\"210283\"}],[{label:\"铁东区\",value:\"210302\"},{label:\"铁西区\",value:\"210303\"},{label:\"立山区\",value:\"210304\"},{label:\"千山区\",value:\"210311\"},{label:\"台安县\",value:\"210321\"},{label:\"岫岩满族自治县\",value:\"210323\"},{label:\"海城市\",value:\"210381\"}],[{label:\"新抚区\",value:\"210402\"},{label:\"东洲区\",value:\"210403\"},{label:\"望花区\",value:\"210404\"},{label:\"顺城区\",value:\"210411\"},{label:\"抚顺县\",value:\"210421\"},{label:\"新宾满族自治县\",value:\"210422\"},{label:\"清原满族自治县\",value:\"210423\"}],[{label:\"平山区\",value:\"210502\"},{label:\"溪湖区\",value:\"210503\"},{label:\"明山区\",value:\"210504\"},{label:\"南芬区\",value:\"210505\"},{label:\"本溪满族自治县\",value:\"210521\"},{label:\"桓仁满族自治县\",value:\"210522\"}],[{label:\"元宝区\",value:\"210602\"},{label:\"振兴区\",value:\"210603\"},{label:\"振安区\",value:\"210604\"},{label:\"宽甸满族自治县\",value:\"210624\"},{label:\"东港市\",value:\"210681\"},{label:\"凤城市\",value:\"210682\"}],[{label:\"古塔区\",value:\"210702\"},{label:\"凌河区\",value:\"210703\"},{label:\"太和区\",value:\"210711\"},{label:\"黑山县\",value:\"210726\"},{label:\"义县\",value:\"210727\"},{label:\"凌海市\",value:\"210781\"},{label:\"北镇市\",value:\"210782\"}],[{label:\"站前区\",value:\"210802\"},{label:\"西市区\",value:\"210803\"},{label:\"鲅鱼圈区\",value:\"210804\"},{label:\"老边区\",value:\"210811\"},{label:\"盖州市\",value:\"210881\"},{label:\"大石桥市\",value:\"210882\"}],[{label:\"海州区\",value:\"210902\"},{label:\"新邱区\",value:\"210903\"},{label:\"太平区\",value:\"210904\"},{label:\"清河门区\",value:\"210905\"},{label:\"细河区\",value:\"210911\"},{label:\"阜新蒙古族自治县\",value:\"210921\"},{label:\"彰武县\",value:\"210922\"}],[{label:\"白塔区\",value:\"211002\"},{label:\"文圣区\",value:\"211003\"},{label:\"宏伟区\",value:\"211004\"},{label:\"弓长岭区\",value:\"211005\"},{label:\"太子河区\",value:\"211011\"},{label:\"辽阳县\",value:\"211021\"},{label:\"灯塔市\",value:\"211081\"}],[{label:\"双台子区\",value:\"211102\"},{label:\"兴隆台区\",value:\"211103\"},{label:\"大洼区\",value:\"211104\"},{label:\"盘山县\",value:\"211122\"}],[{label:\"银州区\",value:\"211202\"},{label:\"清河区\",value:\"211204\"},{label:\"铁岭县\",value:\"211221\"},{label:\"西丰县\",value:\"211223\"},{label:\"昌图县\",value:\"211224\"},{label:\"调兵山市\",value:\"211281\"},{label:\"开原市\",value:\"211282\"}],[{label:\"双塔区\",value:\"211302\"},{label:\"龙城区\",value:\"211303\"},{label:\"朝阳县\",value:\"211321\"},{label:\"建平县\",value:\"211322\"},{label:\"喀喇沁左翼蒙古族自治县\",value:\"211324\"},{label:\"北票市\",value:\"211381\"},{label:\"凌源市\",value:\"211382\"}],[{label:\"连山区\",value:\"211402\"},{label:\"龙港区\",value:\"211403\"},{label:\"南票区\",value:\"211404\"},{label:\"绥中县\",value:\"211421\"},{label:\"建昌县\",value:\"211422\"},{label:\"兴城市\",value:\"211481\"}]],[[{label:\"南关区\",value:\"220102\"},{label:\"宽城区\",value:\"220103\"},{label:\"朝阳区\",value:\"220104\"},{label:\"二道区\",value:\"220105\"},{label:\"绿园区\",value:\"220106\"},{label:\"双阳区\",value:\"220112\"},{label:\"九台区\",value:\"220113\"},{label:\"农安县\",value:\"220122\"},{label:\"长春经济技术开发区\",value:\"220171\"},{label:\"长春净月高新技术产业开发区\",value:\"220172\"},{label:\"长春高新技术产业开发区\",value:\"220173\"},{label:\"长春汽车经济技术开发区\",value:\"220174\"},{label:\"榆树市\",value:\"220182\"},{label:\"德惠市\",value:\"220183\"}],[{label:\"昌邑区\",value:\"220202\"},{label:\"龙潭区\",value:\"220203\"},{label:\"船营区\",value:\"220204\"},{label:\"丰满区\",value:\"220211\"},{label:\"永吉县\",value:\"220221\"},{label:\"吉林经济开发区\",value:\"220271\"},{label:\"吉林高新技术产业开发区\",value:\"220272\"},{label:\"吉林中国新加坡食品区\",value:\"220273\"},{label:\"蛟河市\",value:\"220281\"},{label:\"桦甸市\",value:\"220282\"},{label:\"舒兰市\",value:\"220283\"},{label:\"磐石市\",value:\"220284\"}],[{label:\"铁西区\",value:\"220302\"},{label:\"铁东区\",value:\"220303\"},{label:\"梨树县\",value:\"220322\"},{label:\"伊通满族自治县\",value:\"220323\"},{label:\"公主岭市\",value:\"220381\"},{label:\"双辽市\",value:\"220382\"}],[{label:\"龙山区\",value:\"220402\"},{label:\"西安区\",value:\"220403\"},{label:\"东丰县\",value:\"220421\"},{label:\"东辽县\",value:\"220422\"}],[{label:\"东昌区\",value:\"220502\"},{label:\"二道江区\",value:\"220503\"},{label:\"通化县\",value:\"220521\"},{label:\"辉南县\",value:\"220523\"},{label:\"柳河县\",value:\"220524\"},{label:\"梅河口市\",value:\"220581\"},{label:\"集安市\",value:\"220582\"}],[{label:\"浑江区\",value:\"220602\"},{label:\"江源区\",value:\"220605\"},{label:\"抚松县\",value:\"220621\"},{label:\"靖宇县\",value:\"220622\"},{label:\"长白朝鲜族自治县\",value:\"220623\"},{label:\"临江市\",value:\"220681\"}],[{label:\"宁江区\",value:\"220702\"},{label:\"前郭尔罗斯蒙古族自治县\",value:\"220721\"},{label:\"长岭县\",value:\"220722\"},{label:\"乾安县\",value:\"220723\"},{label:\"吉林松原经济开发区\",value:\"220771\"},{label:\"扶余市\",value:\"220781\"}],[{label:\"洮北区\",value:\"220802\"},{label:\"镇赉县\",value:\"220821\"},{label:\"通榆县\",value:\"220822\"},{label:\"吉林白城经济开发区\",value:\"220871\"},{label:\"洮南市\",value:\"220881\"},{label:\"大安市\",value:\"220882\"}],[{label:\"延吉市\",value:\"222401\"},{label:\"图们市\",value:\"222402\"},{label:\"敦化市\",value:\"222403\"},{label:\"珲春市\",value:\"222404\"},{label:\"龙井市\",value:\"222405\"},{label:\"和龙市\",value:\"222406\"},{label:\"汪清县\",value:\"222424\"},{label:\"安图县\",value:\"222426\"}]],[[{label:\"道里区\",value:\"230102\"},{label:\"南岗区\",value:\"230103\"},{label:\"道外区\",value:\"230104\"},{label:\"平房区\",value:\"230108\"},{label:\"松北区\",value:\"230109\"},{label:\"香坊区\",value:\"230110\"},{label:\"呼兰区\",value:\"230111\"},{label:\"阿城区\",value:\"230112\"},{label:\"双城区\",value:\"230113\"},{label:\"依兰县\",value:\"230123\"},{label:\"方正县\",value:\"230124\"},{label:\"宾县\",value:\"230125\"},{label:\"巴彦县\",value:\"230126\"},{label:\"木兰县\",value:\"230127\"},{label:\"通河县\",value:\"230128\"},{label:\"延寿县\",value:\"230129\"},{label:\"尚志市\",value:\"230183\"},{label:\"五常市\",value:\"230184\"}],[{label:\"龙沙区\",value:\"230202\"},{label:\"建华区\",value:\"230203\"},{label:\"铁锋区\",value:\"230204\"},{label:\"昂昂溪区\",value:\"230205\"},{label:\"富拉尔基区\",value:\"230206\"},{label:\"碾子山区\",value:\"230207\"},{label:\"梅里斯达斡尔族区\",value:\"230208\"},{label:\"龙江县\",value:\"230221\"},{label:\"依安县\",value:\"230223\"},{label:\"泰来县\",value:\"230224\"},{label:\"甘南县\",value:\"230225\"},{label:\"富裕县\",value:\"230227\"},{label:\"克山县\",value:\"230229\"},{label:\"克东县\",value:\"230230\"},{label:\"拜泉县\",value:\"230231\"},{label:\"讷河市\",value:\"230281\"}],[{label:\"鸡冠区\",value:\"230302\"},{label:\"恒山区\",value:\"230303\"},{label:\"滴道区\",value:\"230304\"},{label:\"梨树区\",value:\"230305\"},{label:\"城子河区\",value:\"230306\"},{label:\"麻山区\",value:\"230307\"},{label:\"鸡东县\",value:\"230321\"},{label:\"虎林市\",value:\"230381\"},{label:\"密山市\",value:\"230382\"}],[{label:\"向阳区\",value:\"230402\"},{label:\"工农区\",value:\"230403\"},{label:\"南山区\",value:\"230404\"},{label:\"兴安区\",value:\"230405\"},{label:\"东山区\",value:\"230406\"},{label:\"兴山区\",value:\"230407\"},{label:\"萝北县\",value:\"230421\"},{label:\"绥滨县\",value:\"230422\"}],[{label:\"尖山区\",value:\"230502\"},{label:\"岭东区\",value:\"230503\"},{label:\"四方台区\",value:\"230505\"},{label:\"宝山区\",value:\"230506\"},{label:\"集贤县\",value:\"230521\"},{label:\"友谊县\",value:\"230522\"},{label:\"宝清县\",value:\"230523\"},{label:\"饶河县\",value:\"230524\"}],[{label:\"萨尔图区\",value:\"230602\"},{label:\"龙凤区\",value:\"230603\"},{label:\"让胡路区\",value:\"230604\"},{label:\"红岗区\",value:\"230605\"},{label:\"大同区\",value:\"230606\"},{label:\"肇州县\",value:\"230621\"},{label:\"肇源县\",value:\"230622\"},{label:\"林甸县\",value:\"230623\"},{label:\"杜尔伯特蒙古族自治县\",value:\"230624\"},{label:\"大庆高新技术产业开发区\",value:\"230671\"}],[{label:\"伊春区\",value:\"230702\"},{label:\"南岔区\",value:\"230703\"},{label:\"友好区\",value:\"230704\"},{label:\"西林区\",value:\"230705\"},{label:\"翠峦区\",value:\"230706\"},{label:\"新青区\",value:\"230707\"},{label:\"美溪区\",value:\"230708\"},{label:\"金山屯区\",value:\"230709\"},{label:\"五营区\",value:\"230710\"},{label:\"乌马河区\",value:\"230711\"},{label:\"汤旺河区\",value:\"230712\"},{label:\"带岭区\",value:\"230713\"},{label:\"乌伊岭区\",value:\"230714\"},{label:\"红星区\",value:\"230715\"},{label:\"上甘岭区\",value:\"230716\"},{label:\"嘉荫县\",value:\"230722\"},{label:\"铁力市\",value:\"230781\"}],[{label:\"向阳区\",value:\"230803\"},{label:\"前进区\",value:\"230804\"},{label:\"东风区\",value:\"230805\"},{label:\"郊区\",value:\"230811\"},{label:\"桦南县\",value:\"230822\"},{label:\"桦川县\",value:\"230826\"},{label:\"汤原县\",value:\"230828\"},{label:\"同江市\",value:\"230881\"},{label:\"富锦市\",value:\"230882\"},{label:\"抚远市\",value:\"230883\"}],[{label:\"新兴区\",value:\"230902\"},{label:\"桃山区\",value:\"230903\"},{label:\"茄子河区\",value:\"230904\"},{label:\"勃利县\",value:\"230921\"}],[{label:\"东安区\",value:\"231002\"},{label:\"阳明区\",value:\"231003\"},{label:\"爱民区\",value:\"231004\"},{label:\"西安区\",value:\"231005\"},{label:\"林口县\",value:\"231025\"},{label:\"牡丹江经济技术开发区\",value:\"231071\"},{label:\"绥芬河市\",value:\"231081\"},{label:\"海林市\",value:\"231083\"},{label:\"宁安市\",value:\"231084\"},{label:\"穆棱市\",value:\"231085\"},{label:\"东宁市\",value:\"231086\"}],[{label:\"爱辉区\",value:\"231102\"},{label:\"嫩江县\",value:\"231121\"},{label:\"逊克县\",value:\"231123\"},{label:\"孙吴县\",value:\"231124\"},{label:\"北安市\",value:\"231181\"},{label:\"五大连池市\",value:\"231182\"}],[{label:\"北林区\",value:\"231202\"},{label:\"望奎县\",value:\"231221\"},{label:\"兰西县\",value:\"231222\"},{label:\"青冈县\",value:\"231223\"},{label:\"庆安县\",value:\"231224\"},{label:\"明水县\",value:\"231225\"},{label:\"绥棱县\",value:\"231226\"},{label:\"安达市\",value:\"231281\"},{label:\"肇东市\",value:\"231282\"},{label:\"海伦市\",value:\"231283\"}],[{label:\"加格达奇区\",value:\"232701\"},{label:\"松岭区\",value:\"232702\"},{label:\"新林区\",value:\"232703\"},{label:\"呼中区\",value:\"232704\"},{label:\"呼玛县\",value:\"232721\"},{label:\"塔河县\",value:\"232722\"},{label:\"漠河县\",value:\"232723\"}]],[[{label:\"黄浦区\",value:\"310101\"},{label:\"徐汇区\",value:\"310104\"},{label:\"长宁区\",value:\"310105\"},{label:\"静安区\",value:\"310106\"},{label:\"普陀区\",value:\"310107\"},{label:\"虹口区\",value:\"310109\"},{label:\"杨浦区\",value:\"310110\"},{label:\"闵行区\",value:\"310112\"},{label:\"宝山区\",value:\"310113\"},{label:\"嘉定区\",value:\"310114\"},{label:\"浦东新区\",value:\"310115\"},{label:\"金山区\",value:\"310116\"},{label:\"松江区\",value:\"310117\"},{label:\"青浦区\",value:\"310118\"},{label:\"奉贤区\",value:\"310120\"},{label:\"崇明区\",value:\"310151\"}]],[[{label:\"玄武区\",value:\"320102\"},{label:\"秦淮区\",value:\"320104\"},{label:\"建邺区\",value:\"320105\"},{label:\"鼓楼区\",value:\"320106\"},{label:\"浦口区\",value:\"320111\"},{label:\"栖霞区\",value:\"320113\"},{label:\"雨花台区\",value:\"320114\"},{label:\"江宁区\",value:\"320115\"},{label:\"六合区\",value:\"320116\"},{label:\"溧水区\",value:\"320117\"},{label:\"高淳区\",value:\"320118\"}],[{label:\"锡山区\",value:\"320205\"},{label:\"惠山区\",value:\"320206\"},{label:\"滨湖区\",value:\"320211\"},{label:\"梁溪区\",value:\"320213\"},{label:\"新吴区\",value:\"320214\"},{label:\"江阴市\",value:\"320281\"},{label:\"宜兴市\",value:\"320282\"}],[{label:\"鼓楼区\",value:\"320302\"},{label:\"云龙区\",value:\"320303\"},{label:\"贾汪区\",value:\"320305\"},{label:\"泉山区\",value:\"320311\"},{label:\"铜山区\",value:\"320312\"},{label:\"丰县\",value:\"320321\"},{label:\"沛县\",value:\"320322\"},{label:\"睢宁县\",value:\"320324\"},{label:\"徐州经济技术开发区\",value:\"320371\"},{label:\"新沂市\",value:\"320381\"},{label:\"邳州市\",value:\"320382\"}],[{label:\"天宁区\",value:\"320402\"},{label:\"钟楼区\",value:\"320404\"},{label:\"新北区\",value:\"320411\"},{label:\"武进区\",value:\"320412\"},{label:\"金坛区\",value:\"320413\"},{label:\"溧阳市\",value:\"320481\"}],[{label:\"虎丘区\",value:\"320505\"},{label:\"吴中区\",value:\"320506\"},{label:\"相城区\",value:\"320507\"},{label:\"姑苏区\",value:\"320508\"},{label:\"吴江区\",value:\"320509\"},{label:\"苏州工业园区\",value:\"320571\"},{label:\"常熟市\",value:\"320581\"},{label:\"张家港市\",value:\"320582\"},{label:\"昆山市\",value:\"320583\"},{label:\"太仓市\",value:\"320585\"}],[{label:\"崇川区\",value:\"320602\"},{label:\"港闸区\",value:\"320611\"},{label:\"通州区\",value:\"320612\"},{label:\"海安县\",value:\"320621\"},{label:\"如东县\",value:\"320623\"},{label:\"南通经济技术开发区\",value:\"320671\"},{label:\"启东市\",value:\"320681\"},{label:\"如皋市\",value:\"320682\"},{label:\"海门市\",value:\"320684\"}],[{label:\"连云区\",value:\"320703\"},{label:\"海州区\",value:\"320706\"},{label:\"赣榆区\",value:\"320707\"},{label:\"东海县\",value:\"320722\"},{label:\"灌云县\",value:\"320723\"},{label:\"灌南县\",value:\"320724\"},{label:\"连云港经济技术开发区\",value:\"320771\"},{label:\"连云港高新技术产业开发区\",value:\"320772\"}],[{label:\"淮安区\",value:\"320803\"},{label:\"淮阴区\",value:\"320804\"},{label:\"清江浦区\",value:\"320812\"},{label:\"洪泽区\",value:\"320813\"},{label:\"涟水县\",value:\"320826\"},{label:\"盱眙县\",value:\"320830\"},{label:\"金湖县\",value:\"320831\"},{label:\"淮安经济技术开发区\",value:\"320871\"}],[{label:\"亭湖区\",value:\"320902\"},{label:\"盐都区\",value:\"320903\"},{label:\"大丰区\",value:\"320904\"},{label:\"响水县\",value:\"320921\"},{label:\"滨海县\",value:\"320922\"},{label:\"阜宁县\",value:\"320923\"},{label:\"射阳县\",value:\"320924\"},{label:\"建湖县\",value:\"320925\"},{label:\"盐城经济技术开发区\",value:\"320971\"},{label:\"东台市\",value:\"320981\"}],[{label:\"广陵区\",value:\"321002\"},{label:\"邗江区\",value:\"321003\"},{label:\"江都区\",value:\"321012\"},{label:\"宝应县\",value:\"321023\"},{label:\"扬州经济技术开发区\",value:\"321071\"},{label:\"仪征市\",value:\"321081\"},{label:\"高邮市\",value:\"321084\"}],[{label:\"京口区\",value:\"321102\"},{label:\"润州区\",value:\"321111\"},{label:\"丹徒区\",value:\"321112\"},{label:\"镇江新区\",value:\"321171\"},{label:\"丹阳市\",value:\"321181\"},{label:\"扬中市\",value:\"321182\"},{label:\"句容市\",value:\"321183\"}],[{label:\"海陵区\",value:\"321202\"},{label:\"高港区\",value:\"321203\"},{label:\"姜堰区\",value:\"321204\"},{label:\"泰州医药高新技术产业开发区\",value:\"321271\"},{label:\"兴化市\",value:\"321281\"},{label:\"靖江市\",value:\"321282\"},{label:\"泰兴市\",value:\"321283\"}],[{label:\"宿城区\",value:\"321302\"},{label:\"宿豫区\",value:\"321311\"},{label:\"沭阳县\",value:\"321322\"},{label:\"泗阳县\",value:\"321323\"},{label:\"泗洪县\",value:\"321324\"},{label:\"宿迁经济技术开发区\",value:\"321371\"}]],[[{label:\"上城区\",value:\"330102\"},{label:\"下城区\",value:\"330103\"},{label:\"江干区\",value:\"330104\"},{label:\"拱墅区\",value:\"330105\"},{label:\"西湖区\",value:\"330106\"},{label:\"滨江区\",value:\"330108\"},{label:\"萧山区\",value:\"330109\"},{label:\"余杭区\",value:\"330110\"},{label:\"富阳区\",value:\"330111\"},{label:\"临安区\",value:\"330112\"},{label:\"桐庐县\",value:\"330122\"},{label:\"淳安县\",value:\"330127\"},{label:\"建德市\",value:\"330182\"}],[{label:\"海曙区\",value:\"330203\"},{label:\"江北区\",value:\"330205\"},{label:\"北仑区\",value:\"330206\"},{label:\"镇海区\",value:\"330211\"},{label:\"鄞州区\",value:\"330212\"},{label:\"奉化区\",value:\"330213\"},{label:\"象山县\",value:\"330225\"},{label:\"宁海县\",value:\"330226\"},{label:\"余姚市\",value:\"330281\"},{label:\"慈溪市\",value:\"330282\"}],[{label:\"鹿城区\",value:\"330302\"},{label:\"龙湾区\",value:\"330303\"},{label:\"瓯海区\",value:\"330304\"},{label:\"洞头区\",value:\"330305\"},{label:\"永嘉县\",value:\"330324\"},{label:\"平阳县\",value:\"330326\"},{label:\"苍南县\",value:\"330327\"},{label:\"文成县\",value:\"330328\"},{label:\"泰顺县\",value:\"330329\"},{label:\"温州经济技术开发区\",value:\"330371\"},{label:\"瑞安市\",value:\"330381\"},{label:\"乐清市\",value:\"330382\"}],[{label:\"南湖区\",value:\"330402\"},{label:\"秀洲区\",value:\"330411\"},{label:\"嘉善县\",value:\"330421\"},{label:\"海盐县\",value:\"330424\"},{label:\"海宁市\",value:\"330481\"},{label:\"平湖市\",value:\"330482\"},{label:\"桐乡市\",value:\"330483\"}],[{label:\"吴兴区\",value:\"330502\"},{label:\"南浔区\",value:\"330503\"},{label:\"德清县\",value:\"330521\"},{label:\"长兴县\",value:\"330522\"},{label:\"安吉县\",value:\"330523\"}],[{label:\"越城区\",value:\"330602\"},{label:\"柯桥区\",value:\"330603\"},{label:\"上虞区\",value:\"330604\"},{label:\"新昌县\",value:\"330624\"},{label:\"诸暨市\",value:\"330681\"},{label:\"嵊州市\",value:\"330683\"}],[{label:\"婺城区\",value:\"330702\"},{label:\"金东区\",value:\"330703\"},{label:\"武义县\",value:\"330723\"},{label:\"浦江县\",value:\"330726\"},{label:\"磐安县\",value:\"330727\"},{label:\"兰溪市\",value:\"330781\"},{label:\"义乌市\",value:\"330782\"},{label:\"东阳市\",value:\"330783\"},{label:\"永康市\",value:\"330784\"}],[{label:\"柯城区\",value:\"330802\"},{label:\"衢江区\",value:\"330803\"},{label:\"常山县\",value:\"330822\"},{label:\"开化县\",value:\"330824\"},{label:\"龙游县\",value:\"330825\"},{label:\"江山市\",value:\"330881\"}],[{label:\"定海区\",value:\"330902\"},{label:\"普陀区\",value:\"330903\"},{label:\"岱山县\",value:\"330921\"},{label:\"嵊泗县\",value:\"330922\"}],[{label:\"椒江区\",value:\"331002\"},{label:\"黄岩区\",value:\"331003\"},{label:\"路桥区\",value:\"331004\"},{label:\"三门县\",value:\"331022\"},{label:\"天台县\",value:\"331023\"},{label:\"仙居县\",value:\"331024\"},{label:\"温岭市\",value:\"331081\"},{label:\"临海市\",value:\"331082\"},{label:\"玉环市\",value:\"331083\"}],[{label:\"莲都区\",value:\"331102\"},{label:\"青田县\",value:\"331121\"},{label:\"缙云县\",value:\"331122\"},{label:\"遂昌县\",value:\"331123\"},{label:\"松阳县\",value:\"331124\"},{label:\"云和县\",value:\"331125\"},{label:\"庆元县\",value:\"331126\"},{label:\"景宁畲族自治县\",value:\"331127\"},{label:\"龙泉市\",value:\"331181\"}]],[[{label:\"瑶海区\",value:\"340102\"},{label:\"庐阳区\",value:\"340103\"},{label:\"蜀山区\",value:\"340104\"},{label:\"包河区\",value:\"340111\"},{label:\"长丰县\",value:\"340121\"},{label:\"肥东县\",value:\"340122\"},{label:\"肥西县\",value:\"340123\"},{label:\"庐江县\",value:\"340124\"},{label:\"合肥高新技术产业开发区\",value:\"340171\"},{label:\"合肥经济技术开发区\",value:\"340172\"},{label:\"合肥新站高新技术产业开发区\",value:\"340173\"},{label:\"巢湖市\",value:\"340181\"}],[{label:\"镜湖区\",value:\"340202\"},{label:\"弋江区\",value:\"340203\"},{label:\"鸠江区\",value:\"340207\"},{label:\"三山区\",value:\"340208\"},{label:\"芜湖县\",value:\"340221\"},{label:\"繁昌县\",value:\"340222\"},{label:\"南陵县\",value:\"340223\"},{label:\"无为县\",value:\"340225\"},{label:\"芜湖经济技术开发区\",value:\"340271\"},{label:\"安徽芜湖长江大桥经济开发区\",value:\"340272\"}],[{label:\"龙子湖区\",value:\"340302\"},{label:\"蚌山区\",value:\"340303\"},{label:\"禹会区\",value:\"340304\"},{label:\"淮上区\",value:\"340311\"},{label:\"怀远县\",value:\"340321\"},{label:\"五河县\",value:\"340322\"},{label:\"固镇县\",value:\"340323\"},{label:\"蚌埠市高新技术开发区\",value:\"340371\"},{label:\"蚌埠市经济开发区\",value:\"340372\"}],[{label:\"大通区\",value:\"340402\"},{label:\"田家庵区\",value:\"340403\"},{label:\"谢家集区\",value:\"340404\"},{label:\"八公山区\",value:\"340405\"},{label:\"潘集区\",value:\"340406\"},{label:\"凤台县\",value:\"340421\"},{label:\"寿县\",value:\"340422\"}],[{label:\"花山区\",value:\"340503\"},{label:\"雨山区\",value:\"340504\"},{label:\"博望区\",value:\"340506\"},{label:\"当涂县\",value:\"340521\"},{label:\"含山县\",value:\"340522\"},{label:\"和县\",value:\"340523\"}],[{label:\"杜集区\",value:\"340602\"},{label:\"相山区\",value:\"340603\"},{label:\"烈山区\",value:\"340604\"},{label:\"濉溪县\",value:\"340621\"}],[{label:\"铜官区\",value:\"340705\"},{label:\"义安区\",value:\"340706\"},{label:\"郊区\",value:\"340711\"},{label:\"枞阳县\",value:\"340722\"}],[{label:\"迎江区\",value:\"340802\"},{label:\"大观区\",value:\"340803\"},{label:\"宜秀区\",value:\"340811\"},{label:\"怀宁县\",value:\"340822\"},{label:\"潜山县\",value:\"340824\"},{label:\"太湖县\",value:\"340825\"},{label:\"宿松县\",value:\"340826\"},{label:\"望江县\",value:\"340827\"},{label:\"岳西县\",value:\"340828\"},{label:\"安徽安庆经济开发区\",value:\"340871\"},{label:\"桐城市\",value:\"340881\"}],[{label:\"屯溪区\",value:\"341002\"},{label:\"黄山区\",value:\"341003\"},{label:\"徽州区\",value:\"341004\"},{label:\"歙县\",value:\"341021\"},{label:\"休宁县\",value:\"341022\"},{label:\"黟县\",value:\"341023\"},{label:\"祁门县\",value:\"341024\"}],[{label:\"琅琊区\",value:\"341102\"},{label:\"南谯区\",value:\"341103\"},{label:\"来安县\",value:\"341122\"},{label:\"全椒县\",value:\"341124\"},{label:\"定远县\",value:\"341125\"},{label:\"凤阳县\",value:\"341126\"},{label:\"苏滁现代产业园\",value:\"341171\"},{label:\"滁州经济技术开发区\",value:\"341172\"},{label:\"天长市\",value:\"341181\"},{label:\"明光市\",value:\"341182\"}],[{label:\"颍州区\",value:\"341202\"},{label:\"颍东区\",value:\"341203\"},{label:\"颍泉区\",value:\"341204\"},{label:\"临泉县\",value:\"341221\"},{label:\"太和县\",value:\"341222\"},{label:\"阜南县\",value:\"341225\"},{label:\"颍上县\",value:\"341226\"},{label:\"阜阳合肥现代产业园区\",value:\"341271\"},{label:\"阜阳经济技术开发区\",value:\"341272\"},{label:\"界首市\",value:\"341282\"}],[{label:\"埇桥区\",value:\"341302\"},{label:\"砀山县\",value:\"341321\"},{label:\"萧县\",value:\"341322\"},{label:\"灵璧县\",value:\"341323\"},{label:\"泗县\",value:\"341324\"},{label:\"宿州马鞍山现代产业园区\",value:\"341371\"},{label:\"宿州经济技术开发区\",value:\"341372\"}],[{label:\"金安区\",value:\"341502\"},{label:\"裕安区\",value:\"341503\"},{label:\"叶集区\",value:\"341504\"},{label:\"霍邱县\",value:\"341522\"},{label:\"舒城县\",value:\"341523\"},{label:\"金寨县\",value:\"341524\"},{label:\"霍山县\",value:\"341525\"}],[{label:\"谯城区\",value:\"341602\"},{label:\"涡阳县\",value:\"341621\"},{label:\"蒙城县\",value:\"341622\"},{label:\"利辛县\",value:\"341623\"}],[{label:\"贵池区\",value:\"341702\"},{label:\"东至县\",value:\"341721\"},{label:\"石台县\",value:\"341722\"},{label:\"青阳县\",value:\"341723\"}],[{label:\"宣州区\",value:\"341802\"},{label:\"郎溪县\",value:\"341821\"},{label:\"广德县\",value:\"341822\"},{label:\"泾县\",value:\"341823\"},{label:\"绩溪县\",value:\"341824\"},{label:\"旌德县\",value:\"341825\"},{label:\"宣城市经济开发区\",value:\"341871\"},{label:\"宁国市\",value:\"341881\"}]],[[{label:\"鼓楼区\",value:\"350102\"},{label:\"台江区\",value:\"350103\"},{label:\"仓山区\",value:\"350104\"},{label:\"马尾区\",value:\"350105\"},{label:\"晋安区\",value:\"350111\"},{label:\"闽侯县\",value:\"350121\"},{label:\"连江县\",value:\"350122\"},{label:\"罗源县\",value:\"350123\"},{label:\"闽清县\",value:\"350124\"},{label:\"永泰县\",value:\"350125\"},{label:\"平潭县\",value:\"350128\"},{label:\"福清市\",value:\"350181\"},{label:\"长乐市\",value:\"350182\"}],[{label:\"思明区\",value:\"350203\"},{label:\"海沧区\",value:\"350205\"},{label:\"湖里区\",value:\"350206\"},{label:\"集美区\",value:\"350211\"},{label:\"同安区\",value:\"350212\"},{label:\"翔安区\",value:\"350213\"}],[{label:\"城厢区\",value:\"350302\"},{label:\"涵江区\",value:\"350303\"},{label:\"荔城区\",value:\"350304\"},{label:\"秀屿区\",value:\"350305\"},{label:\"仙游县\",value:\"350322\"}],[{label:\"梅列区\",value:\"350402\"},{label:\"三元区\",value:\"350403\"},{label:\"明溪县\",value:\"350421\"},{label:\"清流县\",value:\"350423\"},{label:\"宁化县\",value:\"350424\"},{label:\"大田县\",value:\"350425\"},{label:\"尤溪县\",value:\"350426\"},{label:\"沙县\",value:\"350427\"},{label:\"将乐县\",value:\"350428\"},{label:\"泰宁县\",value:\"350429\"},{label:\"建宁县\",value:\"350430\"},{label:\"永安市\",value:\"350481\"}],[{label:\"鲤城区\",value:\"350502\"},{label:\"丰泽区\",value:\"350503\"},{label:\"洛江区\",value:\"350504\"},{label:\"泉港区\",value:\"350505\"},{label:\"惠安县\",value:\"350521\"},{label:\"安溪县\",value:\"350524\"},{label:\"永春县\",value:\"350525\"},{label:\"德化县\",value:\"350526\"},{label:\"金门县\",value:\"350527\"},{label:\"石狮市\",value:\"350581\"},{label:\"晋江市\",value:\"350582\"},{label:\"南安市\",value:\"350583\"}],[{label:\"芗城区\",value:\"350602\"},{label:\"龙文区\",value:\"350603\"},{label:\"云霄县\",value:\"350622\"},{label:\"漳浦县\",value:\"350623\"},{label:\"诏安县\",value:\"350624\"},{label:\"长泰县\",value:\"350625\"},{label:\"东山县\",value:\"350626\"},{label:\"南靖县\",value:\"350627\"},{label:\"平和县\",value:\"350628\"},{label:\"华安县\",value:\"350629\"},{label:\"龙海市\",value:\"350681\"}],[{label:\"延平区\",value:\"350702\"},{label:\"建阳区\",value:\"350703\"},{label:\"顺昌县\",value:\"350721\"},{label:\"浦城县\",value:\"350722\"},{label:\"光泽县\",value:\"350723\"},{label:\"松溪县\",value:\"350724\"},{label:\"政和县\",value:\"350725\"},{label:\"邵武市\",value:\"350781\"},{label:\"武夷山市\",value:\"350782\"},{label:\"建瓯市\",value:\"350783\"}],[{label:\"新罗区\",value:\"350802\"},{label:\"永定区\",value:\"350803\"},{label:\"长汀县\",value:\"350821\"},{label:\"上杭县\",value:\"350823\"},{label:\"武平县\",value:\"350824\"},{label:\"连城县\",value:\"350825\"},{label:\"漳平市\",value:\"350881\"}],[{label:\"蕉城区\",value:\"350902\"},{label:\"霞浦县\",value:\"350921\"},{label:\"古田县\",value:\"350922\"},{label:\"屏南县\",value:\"350923\"},{label:\"寿宁县\",value:\"350924\"},{label:\"周宁县\",value:\"350925\"},{label:\"柘荣县\",value:\"350926\"},{label:\"福安市\",value:\"350981\"},{label:\"福鼎市\",value:\"350982\"}]],[[{label:\"东湖区\",value:\"360102\"},{label:\"西湖区\",value:\"360103\"},{label:\"青云谱区\",value:\"360104\"},{label:\"湾里区\",value:\"360105\"},{label:\"青山湖区\",value:\"360111\"},{label:\"新建区\",value:\"360112\"},{label:\"南昌县\",value:\"360121\"},{label:\"安义县\",value:\"360123\"},{label:\"进贤县\",value:\"360124\"}],[{label:\"昌江区\",value:\"360202\"},{label:\"珠山区\",value:\"360203\"},{label:\"浮梁县\",value:\"360222\"},{label:\"乐平市\",value:\"360281\"}],[{label:\"安源区\",value:\"360302\"},{label:\"湘东区\",value:\"360313\"},{label:\"莲花县\",value:\"360321\"},{label:\"上栗县\",value:\"360322\"},{label:\"芦溪县\",value:\"360323\"}],[{label:\"濂溪区\",value:\"360402\"},{label:\"浔阳区\",value:\"360403\"},{label:\"柴桑区\",value:\"360404\"},{label:\"武宁县\",value:\"360423\"},{label:\"修水县\",value:\"360424\"},{label:\"永修县\",value:\"360425\"},{label:\"德安县\",value:\"360426\"},{label:\"都昌县\",value:\"360428\"},{label:\"湖口县\",value:\"360429\"},{label:\"彭泽县\",value:\"360430\"},{label:\"瑞昌市\",value:\"360481\"},{label:\"共青城市\",value:\"360482\"},{label:\"庐山市\",value:\"360483\"}],[{label:\"渝水区\",value:\"360502\"},{label:\"分宜县\",value:\"360521\"}],[{label:\"月湖区\",value:\"360602\"},{label:\"余江县\",value:\"360622\"},{label:\"贵溪市\",value:\"360681\"}],[{label:\"章贡区\",value:\"360702\"},{label:\"南康区\",value:\"360703\"},{label:\"赣县区\",value:\"360704\"},{label:\"信丰县\",value:\"360722\"},{label:\"大余县\",value:\"360723\"},{label:\"上犹县\",value:\"360724\"},{label:\"崇义县\",value:\"360725\"},{label:\"安远县\",value:\"360726\"},{label:\"龙南县\",value:\"360727\"},{label:\"定南县\",value:\"360728\"},{label:\"全南县\",value:\"360729\"},{label:\"宁都县\",value:\"360730\"},{label:\"于都县\",value:\"360731\"},{label:\"兴国县\",value:\"360732\"},{label:\"会昌县\",value:\"360733\"},{label:\"寻乌县\",value:\"360734\"},{label:\"石城县\",value:\"360735\"},{label:\"瑞金市\",value:\"360781\"}],[{label:\"吉州区\",value:\"360802\"},{label:\"青原区\",value:\"360803\"},{label:\"吉安县\",value:\"360821\"},{label:\"吉水县\",value:\"360822\"},{label:\"峡江县\",value:\"360823\"},{label:\"新干县\",value:\"360824\"},{label:\"永丰县\",value:\"360825\"},{label:\"泰和县\",value:\"360826\"},{label:\"遂川县\",value:\"360827\"},{label:\"万安县\",value:\"360828\"},{label:\"安福县\",value:\"360829\"},{label:\"永新县\",value:\"360830\"},{label:\"井冈山市\",value:\"360881\"}],[{label:\"袁州区\",value:\"360902\"},{label:\"奉新县\",value:\"360921\"},{label:\"万载县\",value:\"360922\"},{label:\"上高县\",value:\"360923\"},{label:\"宜丰县\",value:\"360924\"},{label:\"靖安县\",value:\"360925\"},{label:\"铜鼓县\",value:\"360926\"},{label:\"丰城市\",value:\"360981\"},{label:\"樟树市\",value:\"360982\"},{label:\"高安市\",value:\"360983\"}],[{label:\"临川区\",value:\"361002\"},{label:\"东乡区\",value:\"361003\"},{label:\"南城县\",value:\"361021\"},{label:\"黎川县\",value:\"361022\"},{label:\"南丰县\",value:\"361023\"},{label:\"崇仁县\",value:\"361024\"},{label:\"乐安县\",value:\"361025\"},{label:\"宜黄县\",value:\"361026\"},{label:\"金溪县\",value:\"361027\"},{label:\"资溪县\",value:\"361028\"},{label:\"广昌县\",value:\"361030\"}],[{label:\"信州区\",value:\"361102\"},{label:\"广丰区\",value:\"361103\"},{label:\"上饶县\",value:\"361121\"},{label:\"玉山县\",value:\"361123\"},{label:\"铅山县\",value:\"361124\"},{label:\"横峰县\",value:\"361125\"},{label:\"弋阳县\",value:\"361126\"},{label:\"余干县\",value:\"361127\"},{label:\"鄱阳县\",value:\"361128\"},{label:\"万年县\",value:\"361129\"},{label:\"婺源县\",value:\"361130\"},{label:\"德兴市\",value:\"361181\"}]],[[{label:\"历下区\",value:\"370102\"},{label:\"市中区\",value:\"370103\"},{label:\"槐荫区\",value:\"370104\"},{label:\"天桥区\",value:\"370105\"},{label:\"历城区\",value:\"370112\"},{label:\"长清区\",value:\"370113\"},{label:\"章丘区\",value:\"370114\"},{label:\"平阴县\",value:\"370124\"},{label:\"济阳县\",value:\"370125\"},{label:\"商河县\",value:\"370126\"},{label:\"济南高新技术产业开发区\",value:\"370171\"}],[{label:\"市南区\",value:\"370202\"},{label:\"市北区\",value:\"370203\"},{label:\"黄岛区\",value:\"370211\"},{label:\"崂山区\",value:\"370212\"},{label:\"李沧区\",value:\"370213\"},{label:\"城阳区\",value:\"370214\"},{label:\"即墨区\",value:\"370215\"},{label:\"青岛高新技术产业开发区\",value:\"370271\"},{label:\"胶州市\",value:\"370281\"},{label:\"平度市\",value:\"370283\"},{label:\"莱西市\",value:\"370285\"}],[{label:\"淄川区\",value:\"370302\"},{label:\"张店区\",value:\"370303\"},{label:\"博山区\",value:\"370304\"},{label:\"临淄区\",value:\"370305\"},{label:\"周村区\",value:\"370306\"},{label:\"桓台县\",value:\"370321\"},{label:\"高青县\",value:\"370322\"},{label:\"沂源县\",value:\"370323\"}],[{label:\"市中区\",value:\"370402\"},{label:\"薛城区\",value:\"370403\"},{label:\"峄城区\",value:\"370404\"},{label:\"台儿庄区\",value:\"370405\"},{label:\"山亭区\",value:\"370406\"},{label:\"滕州市\",value:\"370481\"}],[{label:\"东营区\",value:\"370502\"},{label:\"河口区\",value:\"370503\"},{label:\"垦利区\",value:\"370505\"},{label:\"利津县\",value:\"370522\"},{label:\"广饶县\",value:\"370523\"},{label:\"东营经济技术开发区\",value:\"370571\"},{label:\"东营港经济开发区\",value:\"370572\"}],[{label:\"芝罘区\",value:\"370602\"},{label:\"福山区\",value:\"370611\"},{label:\"牟平区\",value:\"370612\"},{label:\"莱山区\",value:\"370613\"},{label:\"长岛县\",value:\"370634\"},{label:\"烟台高新技术产业开发区\",value:\"370671\"},{label:\"烟台经济技术开发区\",value:\"370672\"},{label:\"龙口市\",value:\"370681\"},{label:\"莱阳市\",value:\"370682\"},{label:\"莱州市\",value:\"370683\"},{label:\"蓬莱市\",value:\"370684\"},{label:\"招远市\",value:\"370685\"},{label:\"栖霞市\",value:\"370686\"},{label:\"海阳市\",value:\"370687\"}],[{label:\"潍城区\",value:\"370702\"},{label:\"寒亭区\",value:\"370703\"},{label:\"坊子区\",value:\"370704\"},{label:\"奎文区\",value:\"370705\"},{label:\"临朐县\",value:\"370724\"},{label:\"昌乐县\",value:\"370725\"},{label:\"潍坊滨海经济技术开发区\",value:\"370772\"},{label:\"青州市\",value:\"370781\"},{label:\"诸城市\",value:\"370782\"},{label:\"寿光市\",value:\"370783\"},{label:\"安丘市\",value:\"370784\"},{label:\"高密市\",value:\"370785\"},{label:\"昌邑市\",value:\"370786\"}],[{label:\"任城区\",value:\"370811\"},{label:\"兖州区\",value:\"370812\"},{label:\"微山县\",value:\"370826\"},{label:\"鱼台县\",value:\"370827\"},{label:\"金乡县\",value:\"370828\"},{label:\"嘉祥县\",value:\"370829\"},{label:\"汶上县\",value:\"370830\"},{label:\"泗水县\",value:\"370831\"},{label:\"梁山县\",value:\"370832\"},{label:\"济宁高新技术产业开发区\",value:\"370871\"},{label:\"曲阜市\",value:\"370881\"},{label:\"邹城市\",value:\"370883\"}],[{label:\"泰山区\",value:\"370902\"},{label:\"岱岳区\",value:\"370911\"},{label:\"宁阳县\",value:\"370921\"},{label:\"东平县\",value:\"370923\"},{label:\"新泰市\",value:\"370982\"},{label:\"肥城市\",value:\"370983\"}],[{label:\"环翠区\",value:\"371002\"},{label:\"文登区\",value:\"371003\"},{label:\"威海火炬高技术产业开发区\",value:\"371071\"},{label:\"威海经济技术开发区\",value:\"371072\"},{label:\"威海临港经济技术开发区\",value:\"371073\"},{label:\"荣成市\",value:\"371082\"},{label:\"乳山市\",value:\"371083\"}],[{label:\"东港区\",value:\"371102\"},{label:\"岚山区\",value:\"371103\"},{label:\"五莲县\",value:\"371121\"},{label:\"莒县\",value:\"371122\"},{label:\"日照经济技术开发区\",value:\"371171\"},{label:\"日照国际海洋城\",value:\"371172\"}],[{label:\"莱城区\",value:\"371202\"},{label:\"钢城区\",value:\"371203\"}],[{label:\"兰山区\",value:\"371302\"},{label:\"罗庄区\",value:\"371311\"},{label:\"河东区\",value:\"371312\"},{label:\"沂南县\",value:\"371321\"},{label:\"郯城县\",value:\"371322\"},{label:\"沂水县\",value:\"371323\"},{label:\"兰陵县\",value:\"371324\"},{label:\"费县\",value:\"371325\"},{label:\"平邑县\",value:\"371326\"},{label:\"莒南县\",value:\"371327\"},{label:\"蒙阴县\",value:\"371328\"},{label:\"临沭县\",value:\"371329\"},{label:\"临沂高新技术产业开发区\",value:\"371371\"},{label:\"临沂经济技术开发区\",value:\"371372\"},{label:\"临沂临港经济开发区\",value:\"371373\"}],[{label:\"德城区\",value:\"371402\"},{label:\"陵城区\",value:\"371403\"},{label:\"宁津县\",value:\"371422\"},{label:\"庆云县\",value:\"371423\"},{label:\"临邑县\",value:\"371424\"},{label:\"齐河县\",value:\"371425\"},{label:\"平原县\",value:\"371426\"},{label:\"夏津县\",value:\"371427\"},{label:\"武城县\",value:\"371428\"},{label:\"德州经济技术开发区\",value:\"371471\"},{label:\"德州运河经济开发区\",value:\"371472\"},{label:\"乐陵市\",value:\"371481\"},{label:\"禹城市\",value:\"371482\"}],[{label:\"东昌府区\",value:\"371502\"},{label:\"阳谷县\",value:\"371521\"},{label:\"莘县\",value:\"371522\"},{label:\"茌平县\",value:\"371523\"},{label:\"东阿县\",value:\"371524\"},{label:\"冠县\",value:\"371525\"},{label:\"高唐县\",value:\"371526\"},{label:\"临清市\",value:\"371581\"}],[{label:\"滨城区\",value:\"371602\"},{label:\"沾化区\",value:\"371603\"},{label:\"惠民县\",value:\"371621\"},{label:\"阳信县\",value:\"371622\"},{label:\"无棣县\",value:\"371623\"},{label:\"博兴县\",value:\"371625\"},{label:\"邹平县\",value:\"371626\"}],[{label:\"牡丹区\",value:\"371702\"},{label:\"定陶区\",value:\"371703\"},{label:\"曹县\",value:\"371721\"},{label:\"单县\",value:\"371722\"},{label:\"成武县\",value:\"371723\"},{label:\"巨野县\",value:\"371724\"},{label:\"郓城县\",value:\"371725\"},{label:\"鄄城县\",value:\"371726\"},{label:\"东明县\",value:\"371728\"},{label:\"菏泽经济技术开发区\",value:\"371771\"},{label:\"菏泽高新技术开发区\",value:\"371772\"}]],[[{label:\"中原区\",value:\"410102\"},{label:\"二七区\",value:\"410103\"},{label:\"管城回族区\",value:\"410104\"},{label:\"金水区\",value:\"410105\"},{label:\"上街区\",value:\"410106\"},{label:\"惠济区\",value:\"410108\"},{label:\"中牟县\",value:\"410122\"},{label:\"郑州经济技术开发区\",value:\"410171\"},{label:\"郑州高新技术产业开发区\",value:\"410172\"},{label:\"郑州航空港经济综合实验区\",value:\"410173\"},{label:\"巩义市\",value:\"410181\"},{label:\"荥阳市\",value:\"410182\"},{label:\"新密市\",value:\"410183\"},{label:\"新郑市\",value:\"410184\"},{label:\"登封市\",value:\"410185\"}],[{label:\"龙亭区\",value:\"410202\"},{label:\"顺河回族区\",value:\"410203\"},{label:\"鼓楼区\",value:\"410204\"},{label:\"禹王台区\",value:\"410205\"},{label:\"祥符区\",value:\"410212\"},{label:\"杞县\",value:\"410221\"},{label:\"通许县\",value:\"410222\"},{label:\"尉氏县\",value:\"410223\"},{label:\"兰考县\",value:\"410225\"}],[{label:\"老城区\",value:\"410302\"},{label:\"西工区\",value:\"410303\"},{label:\"瀍河回族区\",value:\"410304\"},{label:\"涧西区\",value:\"410305\"},{label:\"吉利区\",value:\"410306\"},{label:\"洛龙区\",value:\"410311\"},{label:\"孟津县\",value:\"410322\"},{label:\"新安县\",value:\"410323\"},{label:\"栾川县\",value:\"410324\"},{label:\"嵩县\",value:\"410325\"},{label:\"汝阳县\",value:\"410326\"},{label:\"宜阳县\",value:\"410327\"},{label:\"洛宁县\",value:\"410328\"},{label:\"伊川县\",value:\"410329\"},{label:\"洛阳高新技术产业开发区\",value:\"410371\"},{label:\"偃师市\",value:\"410381\"}],[{label:\"新华区\",value:\"410402\"},{label:\"卫东区\",value:\"410403\"},{label:\"石龙区\",value:\"410404\"},{label:\"湛河区\",value:\"410411\"},{label:\"宝丰县\",value:\"410421\"},{label:\"叶县\",value:\"410422\"},{label:\"鲁山县\",value:\"410423\"},{label:\"郏县\",value:\"410425\"},{label:\"平顶山高新技术产业开发区\",value:\"410471\"},{label:\"平顶山市新城区\",value:\"410472\"},{label:\"舞钢市\",value:\"410481\"},{label:\"汝州市\",value:\"410482\"}],[{label:\"文峰区\",value:\"410502\"},{label:\"北关区\",value:\"410503\"},{label:\"殷都区\",value:\"410505\"},{label:\"龙安区\",value:\"410506\"},{label:\"安阳县\",value:\"410522\"},{label:\"汤阴县\",value:\"410523\"},{label:\"滑县\",value:\"410526\"},{label:\"内黄县\",value:\"410527\"},{label:\"安阳高新技术产业开发区\",value:\"410571\"},{label:\"林州市\",value:\"410581\"}],[{label:\"鹤山区\",value:\"410602\"},{label:\"山城区\",value:\"410603\"},{label:\"淇滨区\",value:\"410611\"},{label:\"浚县\",value:\"410621\"},{label:\"淇县\",value:\"410622\"},{label:\"鹤壁经济技术开发区\",value:\"410671\"}],[{label:\"红旗区\",value:\"410702\"},{label:\"卫滨区\",value:\"410703\"},{label:\"凤泉区\",value:\"410704\"},{label:\"牧野区\",value:\"410711\"},{label:\"新乡县\",value:\"410721\"},{label:\"获嘉县\",value:\"410724\"},{label:\"原阳县\",value:\"410725\"},{label:\"延津县\",value:\"410726\"},{label:\"封丘县\",value:\"410727\"},{label:\"长垣县\",value:\"410728\"},{label:\"新乡高新技术产业开发区\",value:\"410771\"},{label:\"新乡经济技术开发区\",value:\"410772\"},{label:\"新乡市平原城乡一体化示范区\",value:\"410773\"},{label:\"卫辉市\",value:\"410781\"},{label:\"辉县市\",value:\"410782\"}],[{label:\"解放区\",value:\"410802\"},{label:\"中站区\",value:\"410803\"},{label:\"马村区\",value:\"410804\"},{label:\"山阳区\",value:\"410811\"},{label:\"修武县\",value:\"410821\"},{label:\"博爱县\",value:\"410822\"},{label:\"武陟县\",value:\"410823\"},{label:\"温县\",value:\"410825\"},{label:\"焦作城乡一体化示范区\",value:\"410871\"},{label:\"沁阳市\",value:\"410882\"},{label:\"孟州市\",value:\"410883\"}],[{label:\"华龙区\",value:\"410902\"},{label:\"清丰县\",value:\"410922\"},{label:\"南乐县\",value:\"410923\"},{label:\"范县\",value:\"410926\"},{label:\"台前县\",value:\"410927\"},{label:\"濮阳县\",value:\"410928\"},{label:\"河南濮阳工业园区\",value:\"410971\"},{label:\"濮阳经济技术开发区\",value:\"410972\"}],[{label:\"魏都区\",value:\"411002\"},{label:\"建安区\",value:\"411003\"},{label:\"鄢陵县\",value:\"411024\"},{label:\"襄城县\",value:\"411025\"},{label:\"许昌经济技术开发区\",value:\"411071\"},{label:\"禹州市\",value:\"411081\"},{label:\"长葛市\",value:\"411082\"}],[{label:\"源汇区\",value:\"411102\"},{label:\"郾城区\",value:\"411103\"},{label:\"召陵区\",value:\"411104\"},{label:\"舞阳县\",value:\"411121\"},{label:\"临颍县\",value:\"411122\"},{label:\"漯河经济技术开发区\",value:\"411171\"}],[{label:\"湖滨区\",value:\"411202\"},{label:\"陕州区\",value:\"411203\"},{label:\"渑池县\",value:\"411221\"},{label:\"卢氏县\",value:\"411224\"},{label:\"河南三门峡经济开发区\",value:\"411271\"},{label:\"义马市\",value:\"411281\"},{label:\"灵宝市\",value:\"411282\"}],[{label:\"宛城区\",value:\"411302\"},{label:\"卧龙区\",value:\"411303\"},{label:\"南召县\",value:\"411321\"},{label:\"方城县\",value:\"411322\"},{label:\"西峡县\",value:\"411323\"},{label:\"镇平县\",value:\"411324\"},{label:\"内乡县\",value:\"411325\"},{label:\"淅川县\",value:\"411326\"},{label:\"社旗县\",value:\"411327\"},{label:\"唐河县\",value:\"411328\"},{label:\"新野县\",value:\"411329\"},{label:\"桐柏县\",value:\"411330\"},{label:\"南阳高新技术产业开发区\",value:\"411371\"},{label:\"南阳市城乡一体化示范区\",value:\"411372\"},{label:\"邓州市\",value:\"411381\"}],[{label:\"梁园区\",value:\"411402\"},{label:\"睢阳区\",value:\"411403\"},{label:\"民权县\",value:\"411421\"},{label:\"睢县\",value:\"411422\"},{label:\"宁陵县\",value:\"411423\"},{label:\"柘城县\",value:\"411424\"},{label:\"虞城县\",value:\"411425\"},{label:\"夏邑县\",value:\"411426\"},{label:\"豫东综合物流产业聚集区\",value:\"411471\"},{label:\"河南商丘经济开发区\",value:\"411472\"},{label:\"永城市\",value:\"411481\"}],[{label:\"浉河区\",value:\"411502\"},{label:\"平桥区\",value:\"411503\"},{label:\"罗山县\",value:\"411521\"},{label:\"光山县\",value:\"411522\"},{label:\"新县\",value:\"411523\"},{label:\"商城县\",value:\"411524\"},{label:\"固始县\",value:\"411525\"},{label:\"潢川县\",value:\"411526\"},{label:\"淮滨县\",value:\"411527\"},{label:\"息县\",value:\"411528\"},{label:\"信阳高新技术产业开发区\",value:\"411571\"}],[{label:\"川汇区\",value:\"411602\"},{label:\"扶沟县\",value:\"411621\"},{label:\"西华县\",value:\"411622\"},{label:\"商水县\",value:\"411623\"},{label:\"沈丘县\",value:\"411624\"},{label:\"郸城县\",value:\"411625\"},{label:\"淮阳县\",value:\"411626\"},{label:\"太康县\",value:\"411627\"},{label:\"鹿邑县\",value:\"411628\"},{label:\"河南周口经济开发区\",value:\"411671\"},{label:\"项城市\",value:\"411681\"}],[{label:\"驿城区\",value:\"411702\"},{label:\"西平县\",value:\"411721\"},{label:\"上蔡县\",value:\"411722\"},{label:\"平舆县\",value:\"411723\"},{label:\"正阳县\",value:\"411724\"},{label:\"确山县\",value:\"411725\"},{label:\"泌阳县\",value:\"411726\"},{label:\"汝南县\",value:\"411727\"},{label:\"遂平县\",value:\"411728\"},{label:\"新蔡县\",value:\"411729\"},{label:\"河南驻马店经济开发区\",value:\"411771\"}],[{label:\"济源市\",value:\"419001\"}]],[[{label:\"江岸区\",value:\"420102\"},{label:\"江汉区\",value:\"420103\"},{label:\"硚口区\",value:\"420104\"},{label:\"汉阳区\",value:\"420105\"},{label:\"武昌区\",value:\"420106\"},{label:\"青山区\",value:\"420107\"},{label:\"洪山区\",value:\"420111\"},{label:\"东西湖区\",value:\"420112\"},{label:\"汉南区\",value:\"420113\"},{label:\"蔡甸区\",value:\"420114\"},{label:\"江夏区\",value:\"420115\"},{label:\"黄陂区\",value:\"420116\"},{label:\"新洲区\",value:\"420117\"}],[{label:\"黄石港区\",value:\"420202\"},{label:\"西塞山区\",value:\"420203\"},{label:\"下陆区\",value:\"420204\"},{label:\"铁山区\",value:\"420205\"},{label:\"阳新县\",value:\"420222\"},{label:\"大冶市\",value:\"420281\"}],[{label:\"茅箭区\",value:\"420302\"},{label:\"张湾区\",value:\"420303\"},{label:\"郧阳区\",value:\"420304\"},{label:\"郧西县\",value:\"420322\"},{label:\"竹山县\",value:\"420323\"},{label:\"竹溪县\",value:\"420324\"},{label:\"房县\",value:\"420325\"},{label:\"丹江口市\",value:\"420381\"}],[{label:\"西陵区\",value:\"420502\"},{label:\"伍家岗区\",value:\"420503\"},{label:\"点军区\",value:\"420504\"},{label:\"猇亭区\",value:\"420505\"},{label:\"夷陵区\",value:\"420506\"},{label:\"远安县\",value:\"420525\"},{label:\"兴山县\",value:\"420526\"},{label:\"秭归县\",value:\"420527\"},{label:\"长阳土家族自治县\",value:\"420528\"},{label:\"五峰土家族自治县\",value:\"420529\"},{label:\"宜都市\",value:\"420581\"},{label:\"当阳市\",value:\"420582\"},{label:\"枝江市\",value:\"420583\"}],[{label:\"襄城区\",value:\"420602\"},{label:\"樊城区\",value:\"420606\"},{label:\"襄州区\",value:\"420607\"},{label:\"南漳县\",value:\"420624\"},{label:\"谷城县\",value:\"420625\"},{label:\"保康县\",value:\"420626\"},{label:\"老河口市\",value:\"420682\"},{label:\"枣阳市\",value:\"420683\"},{label:\"宜城市\",value:\"420684\"}],[{label:\"梁子湖区\",value:\"420702\"},{label:\"华容区\",value:\"420703\"},{label:\"鄂城区\",value:\"420704\"}],[{label:\"东宝区\",value:\"420802\"},{label:\"掇刀区\",value:\"420804\"},{label:\"京山县\",value:\"420821\"},{label:\"沙洋县\",value:\"420822\"},{label:\"钟祥市\",value:\"420881\"}],[{label:\"孝南区\",value:\"420902\"},{label:\"孝昌县\",value:\"420921\"},{label:\"大悟县\",value:\"420922\"},{label:\"云梦县\",value:\"420923\"},{label:\"应城市\",value:\"420981\"},{label:\"安陆市\",value:\"420982\"},{label:\"汉川市\",value:\"420984\"}],[{label:\"沙市区\",value:\"421002\"},{label:\"荆州区\",value:\"421003\"},{label:\"公安县\",value:\"421022\"},{label:\"监利县\",value:\"421023\"},{label:\"江陵县\",value:\"421024\"},{label:\"荆州经济技术开发区\",value:\"421071\"},{label:\"石首市\",value:\"421081\"},{label:\"洪湖市\",value:\"421083\"},{label:\"松滋市\",value:\"421087\"}],[{label:\"黄州区\",value:\"421102\"},{label:\"团风县\",value:\"421121\"},{label:\"红安县\",value:\"421122\"},{label:\"罗田县\",value:\"421123\"},{label:\"英山县\",value:\"421124\"},{label:\"浠水县\",value:\"421125\"},{label:\"蕲春县\",value:\"421126\"},{label:\"黄梅县\",value:\"421127\"},{label:\"龙感湖管理区\",value:\"421171\"},{label:\"麻城市\",value:\"421181\"},{label:\"武穴市\",value:\"421182\"}],[{label:\"咸安区\",value:\"421202\"},{label:\"嘉鱼县\",value:\"421221\"},{label:\"通城县\",value:\"421222\"},{label:\"崇阳县\",value:\"421223\"},{label:\"通山县\",value:\"421224\"},{label:\"赤壁市\",value:\"421281\"}],[{label:\"曾都区\",value:\"421303\"},{label:\"随县\",value:\"421321\"},{label:\"广水市\",value:\"421381\"}],[{label:\"恩施市\",value:\"422801\"},{label:\"利川市\",value:\"422802\"},{label:\"建始县\",value:\"422822\"},{label:\"巴东县\",value:\"422823\"},{label:\"宣恩县\",value:\"422825\"},{label:\"咸丰县\",value:\"422826\"},{label:\"来凤县\",value:\"422827\"},{label:\"鹤峰县\",value:\"422828\"}],[{label:\"仙桃市\",value:\"429004\"},{label:\"潜江市\",value:\"429005\"},{label:\"天门市\",value:\"429006\"},{label:\"神农架林区\",value:\"429021\"}]],[[{label:\"芙蓉区\",value:\"430102\"},{label:\"天心区\",value:\"430103\"},{label:\"岳麓区\",value:\"430104\"},{label:\"开福区\",value:\"430105\"},{label:\"雨花区\",value:\"430111\"},{label:\"望城区\",value:\"430112\"},{label:\"长沙县\",value:\"430121\"},{label:\"浏阳市\",value:\"430181\"},{label:\"宁乡市\",value:\"430182\"}],[{label:\"荷塘区\",value:\"430202\"},{label:\"芦淞区\",value:\"430203\"},{label:\"石峰区\",value:\"430204\"},{label:\"天元区\",value:\"430211\"},{label:\"株洲县\",value:\"430221\"},{label:\"攸县\",value:\"430223\"},{label:\"茶陵县\",value:\"430224\"},{label:\"炎陵县\",value:\"430225\"},{label:\"云龙示范区\",value:\"430271\"},{label:\"醴陵市\",value:\"430281\"}],[{label:\"雨湖区\",value:\"430302\"},{label:\"岳塘区\",value:\"430304\"},{label:\"湘潭县\",value:\"430321\"},{label:\"湖南湘潭高新技术产业园区\",value:\"430371\"},{label:\"湘潭昭山示范区\",value:\"430372\"},{label:\"湘潭九华示范区\",value:\"430373\"},{label:\"湘乡市\",value:\"430381\"},{label:\"韶山市\",value:\"430382\"}],[{label:\"珠晖区\",value:\"430405\"},{label:\"雁峰区\",value:\"430406\"},{label:\"石鼓区\",value:\"430407\"},{label:\"蒸湘区\",value:\"430408\"},{label:\"南岳区\",value:\"430412\"},{label:\"衡阳县\",value:\"430421\"},{label:\"衡南县\",value:\"430422\"},{label:\"衡山县\",value:\"430423\"},{label:\"衡东县\",value:\"430424\"},{label:\"祁东县\",value:\"430426\"},{label:\"衡阳综合保税区\",value:\"430471\"},{label:\"湖南衡阳高新技术产业园区\",value:\"430472\"},{label:\"湖南衡阳松木经济开发区\",value:\"430473\"},{label:\"耒阳市\",value:\"430481\"},{label:\"常宁市\",value:\"430482\"}],[{label:\"双清区\",value:\"430502\"},{label:\"大祥区\",value:\"430503\"},{label:\"北塔区\",value:\"430511\"},{label:\"邵东县\",value:\"430521\"},{label:\"新邵县\",value:\"430522\"},{label:\"邵阳县\",value:\"430523\"},{label:\"隆回县\",value:\"430524\"},{label:\"洞口县\",value:\"430525\"},{label:\"绥宁县\",value:\"430527\"},{label:\"新宁县\",value:\"430528\"},{label:\"城步苗族自治县\",value:\"430529\"},{label:\"武冈市\",value:\"430581\"}],[{label:\"岳阳楼区\",value:\"430602\"},{label:\"云溪区\",value:\"430603\"},{label:\"君山区\",value:\"430611\"},{label:\"岳阳县\",value:\"430621\"},{label:\"华容县\",value:\"430623\"},{label:\"湘阴县\",value:\"430624\"},{label:\"平江县\",value:\"430626\"},{label:\"岳阳市屈原管理区\",value:\"430671\"},{label:\"汨罗市\",value:\"430681\"},{label:\"临湘市\",value:\"430682\"}],[{label:\"武陵区\",value:\"430702\"},{label:\"鼎城区\",value:\"430703\"},{label:\"安乡县\",value:\"430721\"},{label:\"汉寿县\",value:\"430722\"},{label:\"澧县\",value:\"430723\"},{label:\"临澧县\",value:\"430724\"},{label:\"桃源县\",value:\"430725\"},{label:\"石门县\",value:\"430726\"},{label:\"常德市西洞庭管理区\",value:\"430771\"},{label:\"津市市\",value:\"430781\"}],[{label:\"永定区\",value:\"430802\"},{label:\"武陵源区\",value:\"430811\"},{label:\"慈利县\",value:\"430821\"},{label:\"桑植县\",value:\"430822\"}],[{label:\"资阳区\",value:\"430902\"},{label:\"赫山区\",value:\"430903\"},{label:\"南县\",value:\"430921\"},{label:\"桃江县\",value:\"430922\"},{label:\"安化县\",value:\"430923\"},{label:\"益阳市大通湖管理区\",value:\"430971\"},{label:\"湖南益阳高新技术产业园区\",value:\"430972\"},{label:\"沅江市\",value:\"430981\"}],[{label:\"北湖区\",value:\"431002\"},{label:\"苏仙区\",value:\"431003\"},{label:\"桂阳县\",value:\"431021\"},{label:\"宜章县\",value:\"431022\"},{label:\"永兴县\",value:\"431023\"},{label:\"嘉禾县\",value:\"431024\"},{label:\"临武县\",value:\"431025\"},{label:\"汝城县\",value:\"431026\"},{label:\"桂东县\",value:\"431027\"},{label:\"安仁县\",value:\"431028\"},{label:\"资兴市\",value:\"431081\"}],[{label:\"零陵区\",value:\"431102\"},{label:\"冷水滩区\",value:\"431103\"},{label:\"祁阳县\",value:\"431121\"},{label:\"东安县\",value:\"431122\"},{label:\"双牌县\",value:\"431123\"},{label:\"道县\",value:\"431124\"},{label:\"江永县\",value:\"431125\"},{label:\"宁远县\",value:\"431126\"},{label:\"蓝山县\",value:\"431127\"},{label:\"新田县\",value:\"431128\"},{label:\"江华瑶族自治县\",value:\"431129\"},{label:\"永州经济技术开发区\",value:\"431171\"},{label:\"永州市金洞管理区\",value:\"431172\"},{label:\"永州市回龙圩管理区\",value:\"431173\"}],[{label:\"鹤城区\",value:\"431202\"},{label:\"中方县\",value:\"431221\"},{label:\"沅陵县\",value:\"431222\"},{label:\"辰溪县\",value:\"431223\"},{label:\"溆浦县\",value:\"431224\"},{label:\"会同县\",value:\"431225\"},{label:\"麻阳苗族自治县\",value:\"431226\"},{label:\"新晃侗族自治县\",value:\"431227\"},{label:\"芷江侗族自治县\",value:\"431228\"},{label:\"靖州苗族侗族自治县\",value:\"431229\"},{label:\"通道侗族自治县\",value:\"431230\"},{label:\"怀化市洪江管理区\",value:\"431271\"},{label:\"洪江市\",value:\"431281\"}],[{label:\"娄星区\",value:\"431302\"},{label:\"双峰县\",value:\"431321\"},{label:\"新化县\",value:\"431322\"},{label:\"冷水江市\",value:\"431381\"},{label:\"涟源市\",value:\"431382\"}],[{label:\"吉首市\",value:\"433101\"},{label:\"泸溪县\",value:\"433122\"},{label:\"凤凰县\",value:\"433123\"},{label:\"花垣县\",value:\"433124\"},{label:\"保靖县\",value:\"433125\"},{label:\"古丈县\",value:\"433126\"},{label:\"永顺县\",value:\"433127\"},{label:\"龙山县\",value:\"433130\"},{label:\"湖南吉首经济开发区\",value:\"433172\"},{label:\"湖南永顺经济开发区\",value:\"433173\"}]],[[{label:\"荔湾区\",value:\"440103\"},{label:\"越秀区\",value:\"440104\"},{label:\"海珠区\",value:\"440105\"},{label:\"天河区\",value:\"440106\"},{label:\"白云区\",value:\"440111\"},{label:\"黄埔区\",value:\"440112\"},{label:\"番禺区\",value:\"440113\"},{label:\"花都区\",value:\"440114\"},{label:\"南沙区\",value:\"440115\"},{label:\"从化区\",value:\"440117\"},{label:\"增城区\",value:\"440118\"}],[{label:\"武江区\",value:\"440203\"},{label:\"浈江区\",value:\"440204\"},{label:\"曲江区\",value:\"440205\"},{label:\"始兴县\",value:\"440222\"},{label:\"仁化县\",value:\"440224\"},{label:\"翁源县\",value:\"440229\"},{label:\"乳源瑶族自治县\",value:\"440232\"},{label:\"新丰县\",value:\"440233\"},{label:\"乐昌市\",value:\"440281\"},{label:\"南雄市\",value:\"440282\"}],[{label:\"罗湖区\",value:\"440303\"},{label:\"福田区\",value:\"440304\"},{label:\"南山区\",value:\"440305\"},{label:\"宝安区\",value:\"440306\"},{label:\"龙岗区\",value:\"440307\"},{label:\"盐田区\",value:\"440308\"},{label:\"龙华区\",value:\"440309\"},{label:\"坪山区\",value:\"440310\"}],[{label:\"香洲区\",value:\"440402\"},{label:\"斗门区\",value:\"440403\"},{label:\"金湾区\",value:\"440404\"}],[{label:\"龙湖区\",value:\"440507\"},{label:\"金平区\",value:\"440511\"},{label:\"濠江区\",value:\"440512\"},{label:\"潮阳区\",value:\"440513\"},{label:\"潮南区\",value:\"440514\"},{label:\"澄海区\",value:\"440515\"},{label:\"南澳县\",value:\"440523\"}],[{label:\"禅城区\",value:\"440604\"},{label:\"南海区\",value:\"440605\"},{label:\"顺德区\",value:\"440606\"},{label:\"三水区\",value:\"440607\"},{label:\"高明区\",value:\"440608\"}],[{label:\"蓬江区\",value:\"440703\"},{label:\"江海区\",value:\"440704\"},{label:\"新会区\",value:\"440705\"},{label:\"台山市\",value:\"440781\"},{label:\"开平市\",value:\"440783\"},{label:\"鹤山市\",value:\"440784\"},{label:\"恩平市\",value:\"440785\"}],[{label:\"赤坎区\",value:\"440802\"},{label:\"霞山区\",value:\"440803\"},{label:\"坡头区\",value:\"440804\"},{label:\"麻章区\",value:\"440811\"},{label:\"遂溪县\",value:\"440823\"},{label:\"徐闻县\",value:\"440825\"},{label:\"廉江市\",value:\"440881\"},{label:\"雷州市\",value:\"440882\"},{label:\"吴川市\",value:\"440883\"}],[{label:\"茂南区\",value:\"440902\"},{label:\"电白区\",value:\"440904\"},{label:\"高州市\",value:\"440981\"},{label:\"化州市\",value:\"440982\"},{label:\"信宜市\",value:\"440983\"}],[{label:\"端州区\",value:\"441202\"},{label:\"鼎湖区\",value:\"441203\"},{label:\"高要区\",value:\"441204\"},{label:\"广宁县\",value:\"441223\"},{label:\"怀集县\",value:\"441224\"},{label:\"封开县\",value:\"441225\"},{label:\"德庆县\",value:\"441226\"},{label:\"四会市\",value:\"441284\"}],[{label:\"惠城区\",value:\"441302\"},{label:\"惠阳区\",value:\"441303\"},{label:\"博罗县\",value:\"441322\"},{label:\"惠东县\",value:\"441323\"},{label:\"龙门县\",value:\"441324\"}],[{label:\"梅江区\",value:\"441402\"},{label:\"梅县区\",value:\"441403\"},{label:\"大埔县\",value:\"441422\"},{label:\"丰顺县\",value:\"441423\"},{label:\"五华县\",value:\"441424\"},{label:\"平远县\",value:\"441426\"},{label:\"蕉岭县\",value:\"441427\"},{label:\"兴宁市\",value:\"441481\"}],[{label:\"城区\",value:\"441502\"},{label:\"海丰县\",value:\"441521\"},{label:\"陆河县\",value:\"441523\"},{label:\"陆丰市\",value:\"441581\"}],[{label:\"源城区\",value:\"441602\"},{label:\"紫金县\",value:\"441621\"},{label:\"龙川县\",value:\"441622\"},{label:\"连平县\",value:\"441623\"},{label:\"和平县\",value:\"441624\"},{label:\"东源县\",value:\"441625\"}],[{label:\"江城区\",value:\"441702\"},{label:\"阳东区\",value:\"441704\"},{label:\"阳西县\",value:\"441721\"},{label:\"阳春市\",value:\"441781\"}],[{label:\"清城区\",value:\"441802\"},{label:\"清新区\",value:\"441803\"},{label:\"佛冈县\",value:\"441821\"},{label:\"阳山县\",value:\"441823\"},{label:\"连山壮族瑶族自治县\",value:\"441825\"},{label:\"连南瑶族自治县\",value:\"441826\"},{label:\"英德市\",value:\"441881\"},{label:\"连州市\",value:\"441882\"}],[{label:\"东莞市\",value:\"441900\"}],[{label:\"中山市\",value:\"442000\"}],[{label:\"湘桥区\",value:\"445102\"},{label:\"潮安区\",value:\"445103\"},{label:\"饶平县\",value:\"445122\"}],[{label:\"榕城区\",value:\"445202\"},{label:\"揭东区\",value:\"445203\"},{label:\"揭西县\",value:\"445222\"},{label:\"惠来县\",value:\"445224\"},{label:\"普宁市\",value:\"445281\"}],[{label:\"云城区\",value:\"445302\"},{label:\"云安区\",value:\"445303\"},{label:\"新兴县\",value:\"445321\"},{label:\"郁南县\",value:\"445322\"},{label:\"罗定市\",value:\"445381\"}]],[[{label:\"兴宁区\",value:\"450102\"},{label:\"青秀区\",value:\"450103\"},{label:\"江南区\",value:\"450105\"},{label:\"西乡塘区\",value:\"450107\"},{label:\"良庆区\",value:\"450108\"},{label:\"邕宁区\",value:\"450109\"},{label:\"武鸣区\",value:\"450110\"},{label:\"隆安县\",value:\"450123\"},{label:\"马山县\",value:\"450124\"},{label:\"上林县\",value:\"450125\"},{label:\"宾阳县\",value:\"450126\"},{label:\"横县\",value:\"450127\"}],[{label:\"城中区\",value:\"450202\"},{label:\"鱼峰区\",value:\"450203\"},{label:\"柳南区\",value:\"450204\"},{label:\"柳北区\",value:\"450205\"},{label:\"柳江区\",value:\"450206\"},{label:\"柳城县\",value:\"450222\"},{label:\"鹿寨县\",value:\"450223\"},{label:\"融安县\",value:\"450224\"},{label:\"融水苗族自治县\",value:\"450225\"},{label:\"三江侗族自治县\",value:\"450226\"}],[{label:\"秀峰区\",value:\"450302\"},{label:\"叠彩区\",value:\"450303\"},{label:\"象山区\",value:\"450304\"},{label:\"七星区\",value:\"450305\"},{label:\"雁山区\",value:\"450311\"},{label:\"临桂区\",value:\"450312\"},{label:\"阳朔县\",value:\"450321\"},{label:\"灵川县\",value:\"450323\"},{label:\"全州县\",value:\"450324\"},{label:\"兴安县\",value:\"450325\"},{label:\"永福县\",value:\"450326\"},{label:\"灌阳县\",value:\"450327\"},{label:\"龙胜各族自治县\",value:\"450328\"},{label:\"资源县\",value:\"450329\"},{label:\"平乐县\",value:\"450330\"},{label:\"荔浦县\",value:\"450331\"},{label:\"恭城瑶族自治县\",value:\"450332\"}],[{label:\"万秀区\",value:\"450403\"},{label:\"长洲区\",value:\"450405\"},{label:\"龙圩区\",value:\"450406\"},{label:\"苍梧县\",value:\"450421\"},{label:\"藤县\",value:\"450422\"},{label:\"蒙山县\",value:\"450423\"},{label:\"岑溪市\",value:\"450481\"}],[{label:\"海城区\",value:\"450502\"},{label:\"银海区\",value:\"450503\"},{label:\"铁山港区\",value:\"450512\"},{label:\"合浦县\",value:\"450521\"}],[{label:\"港口区\",value:\"450602\"},{label:\"防城区\",value:\"450603\"},{label:\"上思县\",value:\"450621\"},{label:\"东兴市\",value:\"450681\"}],[{label:\"钦南区\",value:\"450702\"},{label:\"钦北区\",value:\"450703\"},{label:\"灵山县\",value:\"450721\"},{label:\"浦北县\",value:\"450722\"}],[{label:\"港北区\",value:\"450802\"},{label:\"港南区\",value:\"450803\"},{label:\"覃塘区\",value:\"450804\"},{label:\"平南县\",value:\"450821\"},{label:\"桂平市\",value:\"450881\"}],[{label:\"玉州区\",value:\"450902\"},{label:\"福绵区\",value:\"450903\"},{label:\"容县\",value:\"450921\"},{label:\"陆川县\",value:\"450922\"},{label:\"博白县\",value:\"450923\"},{label:\"兴业县\",value:\"450924\"},{label:\"北流市\",value:\"450981\"}],[{label:\"右江区\",value:\"451002\"},{label:\"田阳县\",value:\"451021\"},{label:\"田东县\",value:\"451022\"},{label:\"平果县\",value:\"451023\"},{label:\"德保县\",value:\"451024\"},{label:\"那坡县\",value:\"451026\"},{label:\"凌云县\",value:\"451027\"},{label:\"乐业县\",value:\"451028\"},{label:\"田林县\",value:\"451029\"},{label:\"西林县\",value:\"451030\"},{label:\"隆林各族自治县\",value:\"451031\"},{label:\"靖西市\",value:\"451081\"}],[{label:\"八步区\",value:\"451102\"},{label:\"平桂区\",value:\"451103\"},{label:\"昭平县\",value:\"451121\"},{label:\"钟山县\",value:\"451122\"},{label:\"富川瑶族自治县\",value:\"451123\"}],[{label:\"金城江区\",value:\"451202\"},{label:\"宜州区\",value:\"451203\"},{label:\"南丹县\",value:\"451221\"},{label:\"天峨县\",value:\"451222\"},{label:\"凤山县\",value:\"451223\"},{label:\"东兰县\",value:\"451224\"},{label:\"罗城仫佬族自治县\",value:\"451225\"},{label:\"环江毛南族自治县\",value:\"451226\"},{label:\"巴马瑶族自治县\",value:\"451227\"},{label:\"都安瑶族自治县\",value:\"451228\"},{label:\"大化瑶族自治县\",value:\"451229\"}],[{label:\"兴宾区\",value:\"451302\"},{label:\"忻城县\",value:\"451321\"},{label:\"象州县\",value:\"451322\"},{label:\"武宣县\",value:\"451323\"},{label:\"金秀瑶族自治县\",value:\"451324\"},{label:\"合山市\",value:\"451381\"}],[{label:\"江州区\",value:\"451402\"},{label:\"扶绥县\",value:\"451421\"},{label:\"宁明县\",value:\"451422\"},{label:\"龙州县\",value:\"451423\"},{label:\"大新县\",value:\"451424\"},{label:\"天等县\",value:\"451425\"},{label:\"凭祥市\",value:\"451481\"}]],[[{label:\"秀英区\",value:\"460105\"},{label:\"龙华区\",value:\"460106\"},{label:\"琼山区\",value:\"460107\"},{label:\"美兰区\",value:\"460108\"}],[{label:\"海棠区\",value:\"460202\"},{label:\"吉阳区\",value:\"460203\"},{label:\"天涯区\",value:\"460204\"},{label:\"崖州区\",value:\"460205\"}],[{label:\"西沙群岛\",value:\"460321\"},{label:\"南沙群岛\",value:\"460322\"},{label:\"中沙群岛的岛礁及其海域\",value:\"460323\"}],[{label:\"儋州市\",value:\"460400\"}],[{label:\"五指山市\",value:\"469001\"},{label:\"琼海市\",value:\"469002\"},{label:\"文昌市\",value:\"469005\"},{label:\"万宁市\",value:\"469006\"},{label:\"东方市\",value:\"469007\"},{label:\"定安县\",value:\"469021\"},{label:\"屯昌县\",value:\"469022\"},{label:\"澄迈县\",value:\"469023\"},{label:\"临高县\",value:\"469024\"},{label:\"白沙黎族自治县\",value:\"469025\"},{label:\"昌江黎族自治县\",value:\"469026\"},{label:\"乐东黎族自治县\",value:\"469027\"},{label:\"陵水黎族自治县\",value:\"469028\"},{label:\"保亭黎族苗族自治县\",value:\"469029\"},{label:\"琼中黎族苗族自治县\",value:\"469030\"}]],[[{label:\"万州区\",value:\"500101\"},{label:\"涪陵区\",value:\"500102\"},{label:\"渝中区\",value:\"500103\"},{label:\"大渡口区\",value:\"500104\"},{label:\"江北区\",value:\"500105\"},{label:\"沙坪坝区\",value:\"500106\"},{label:\"九龙坡区\",value:\"500107\"},{label:\"南岸区\",value:\"500108\"},{label:\"北碚区\",value:\"500109\"},{label:\"綦江区\",value:\"500110\"},{label:\"大足区\",value:\"500111\"},{label:\"渝北区\",value:\"500112\"},{label:\"巴南区\",value:\"500113\"},{label:\"黔江区\",value:\"500114\"},{label:\"长寿区\",value:\"500115\"},{label:\"江津区\",value:\"500116\"},{label:\"合川区\",value:\"500117\"},{label:\"永川区\",value:\"500118\"},{label:\"南川区\",value:\"500119\"},{label:\"璧山区\",value:\"500120\"},{label:\"铜梁区\",value:\"500151\"},{label:\"潼南区\",value:\"500152\"},{label:\"荣昌区\",value:\"500153\"},{label:\"开州区\",value:\"500154\"},{label:\"梁平区\",value:\"500155\"},{label:\"武隆区\",value:\"500156\"}],[{label:\"城口县\",value:\"500229\"},{label:\"丰都县\",value:\"500230\"},{label:\"垫江县\",value:\"500231\"},{label:\"忠县\",value:\"500233\"},{label:\"云阳县\",value:\"500235\"},{label:\"奉节县\",value:\"500236\"},{label:\"巫山县\",value:\"500237\"},{label:\"巫溪县\",value:\"500238\"},{label:\"石柱土家族自治县\",value:\"500240\"},{label:\"秀山土家族苗族自治县\",value:\"500241\"},{label:\"酉阳土家族苗族自治县\",value:\"500242\"},{label:\"彭水苗族土家族自治县\",value:\"500243\"}]],[[{label:\"锦江区\",value:\"510104\"},{label:\"青羊区\",value:\"510105\"},{label:\"金牛区\",value:\"510106\"},{label:\"武侯区\",value:\"510107\"},{label:\"成华区\",value:\"510108\"},{label:\"龙泉驿区\",value:\"510112\"},{label:\"青白江区\",value:\"510113\"},{label:\"新都区\",value:\"510114\"},{label:\"温江区\",value:\"510115\"},{label:\"双流区\",value:\"510116\"},{label:\"郫都区\",value:\"510117\"},{label:\"金堂县\",value:\"510121\"},{label:\"大邑县\",value:\"510129\"},{label:\"蒲江县\",value:\"510131\"},{label:\"新津县\",value:\"510132\"},{label:\"都江堰市\",value:\"510181\"},{label:\"彭州市\",value:\"510182\"},{label:\"邛崃市\",value:\"510183\"},{label:\"崇州市\",value:\"510184\"},{label:\"简阳市\",value:\"510185\"}],[{label:\"自流井区\",value:\"510302\"},{label:\"贡井区\",value:\"510303\"},{label:\"大安区\",value:\"510304\"},{label:\"沿滩区\",value:\"510311\"},{label:\"荣县\",value:\"510321\"},{label:\"富顺县\",value:\"510322\"}],[{label:\"东区\",value:\"510402\"},{label:\"西区\",value:\"510403\"},{label:\"仁和区\",value:\"510411\"},{label:\"米易县\",value:\"510421\"},{label:\"盐边县\",value:\"510422\"}],[{label:\"江阳区\",value:\"510502\"},{label:\"纳溪区\",value:\"510503\"},{label:\"龙马潭区\",value:\"510504\"},{label:\"泸县\",value:\"510521\"},{label:\"合江县\",value:\"510522\"},{label:\"叙永县\",value:\"510524\"},{label:\"古蔺县\",value:\"510525\"}],[{label:\"旌阳区\",value:\"510603\"},{label:\"罗江区\",value:\"510604\"},{label:\"中江县\",value:\"510623\"},{label:\"广汉市\",value:\"510681\"},{label:\"什邡市\",value:\"510682\"},{label:\"绵竹市\",value:\"510683\"}],[{label:\"涪城区\",value:\"510703\"},{label:\"游仙区\",value:\"510704\"},{label:\"安州区\",value:\"510705\"},{label:\"三台县\",value:\"510722\"},{label:\"盐亭县\",value:\"510723\"},{label:\"梓潼县\",value:\"510725\"},{label:\"北川羌族自治县\",value:\"510726\"},{label:\"平武县\",value:\"510727\"},{label:\"江油市\",value:\"510781\"}],[{label:\"利州区\",value:\"510802\"},{label:\"昭化区\",value:\"510811\"},{label:\"朝天区\",value:\"510812\"},{label:\"旺苍县\",value:\"510821\"},{label:\"青川县\",value:\"510822\"},{label:\"剑阁县\",value:\"510823\"},{label:\"苍溪县\",value:\"510824\"}],[{label:\"船山区\",value:\"510903\"},{label:\"安居区\",value:\"510904\"},{label:\"蓬溪县\",value:\"510921\"},{label:\"射洪县\",value:\"510922\"},{label:\"大英县\",value:\"510923\"}],[{label:\"市中区\",value:\"511002\"},{label:\"东兴区\",value:\"511011\"},{label:\"威远县\",value:\"511024\"},{label:\"资中县\",value:\"511025\"},{label:\"内江经济开发区\",value:\"511071\"},{label:\"隆昌市\",value:\"511083\"}],[{label:\"市中区\",value:\"511102\"},{label:\"沙湾区\",value:\"511111\"},{label:\"五通桥区\",value:\"511112\"},{label:\"金口河区\",value:\"511113\"},{label:\"犍为县\",value:\"511123\"},{label:\"井研县\",value:\"511124\"},{label:\"夹江县\",value:\"511126\"},{label:\"沐川县\",value:\"511129\"},{label:\"峨边彝族自治县\",value:\"511132\"},{label:\"马边彝族自治县\",value:\"511133\"},{label:\"峨眉山市\",value:\"511181\"}],[{label:\"顺庆区\",value:\"511302\"},{label:\"高坪区\",value:\"511303\"},{label:\"嘉陵区\",value:\"511304\"},{label:\"南部县\",value:\"511321\"},{label:\"营山县\",value:\"511322\"},{label:\"蓬安县\",value:\"511323\"},{label:\"仪陇县\",value:\"511324\"},{label:\"西充县\",value:\"511325\"},{label:\"阆中市\",value:\"511381\"}],[{label:\"东坡区\",value:\"511402\"},{label:\"彭山区\",value:\"511403\"},{label:\"仁寿县\",value:\"511421\"},{label:\"洪雅县\",value:\"511423\"},{label:\"丹棱县\",value:\"511424\"},{label:\"青神县\",value:\"511425\"}],[{label:\"翠屏区\",value:\"511502\"},{label:\"南溪区\",value:\"511503\"},{label:\"宜宾县\",value:\"511521\"},{label:\"江安县\",value:\"511523\"},{label:\"长宁县\",value:\"511524\"},{label:\"高县\",value:\"511525\"},{label:\"珙县\",value:\"511526\"},{label:\"筠连县\",value:\"511527\"},{label:\"兴文县\",value:\"511528\"},{label:\"屏山县\",value:\"511529\"}],[{label:\"广安区\",value:\"511602\"},{label:\"前锋区\",value:\"511603\"},{label:\"岳池县\",value:\"511621\"},{label:\"武胜县\",value:\"511622\"},{label:\"邻水县\",value:\"511623\"},{label:\"华蓥市\",value:\"511681\"}],[{label:\"通川区\",value:\"511702\"},{label:\"达川区\",value:\"511703\"},{label:\"宣汉县\",value:\"511722\"},{label:\"开江县\",value:\"511723\"},{label:\"大竹县\",value:\"511724\"},{label:\"渠县\",value:\"511725\"},{label:\"达州经济开发区\",value:\"511771\"},{label:\"万源市\",value:\"511781\"}],[{label:\"雨城区\",value:\"511802\"},{label:\"名山区\",value:\"511803\"},{label:\"荥经县\",value:\"511822\"},{label:\"汉源县\",value:\"511823\"},{label:\"石棉县\",value:\"511824\"},{label:\"天全县\",value:\"511825\"},{label:\"芦山县\",value:\"511826\"},{label:\"宝兴县\",value:\"511827\"}],[{label:\"巴州区\",value:\"511902\"},{label:\"恩阳区\",value:\"511903\"},{label:\"通江县\",value:\"511921\"},{label:\"南江县\",value:\"511922\"},{label:\"平昌县\",value:\"511923\"},{label:\"巴中经济开发区\",value:\"511971\"}],[{label:\"雁江区\",value:\"512002\"},{label:\"安岳县\",value:\"512021\"},{label:\"乐至县\",value:\"512022\"}],[{label:\"马尔康市\",value:\"513201\"},{label:\"汶川县\",value:\"513221\"},{label:\"理县\",value:\"513222\"},{label:\"茂县\",value:\"513223\"},{label:\"松潘县\",value:\"513224\"},{label:\"九寨沟县\",value:\"513225\"},{label:\"金川县\",value:\"513226\"},{label:\"小金县\",value:\"513227\"},{label:\"黑水县\",value:\"513228\"},{label:\"壤塘县\",value:\"513230\"},{label:\"阿坝县\",value:\"513231\"},{label:\"若尔盖县\",value:\"513232\"},{label:\"红原县\",value:\"513233\"}],[{label:\"康定市\",value:\"513301\"},{label:\"泸定县\",value:\"513322\"},{label:\"丹巴县\",value:\"513323\"},{label:\"九龙县\",value:\"513324\"},{label:\"雅江县\",value:\"513325\"},{label:\"道孚县\",value:\"513326\"},{label:\"炉霍县\",value:\"513327\"},{label:\"甘孜县\",value:\"513328\"},{label:\"新龙县\",value:\"513329\"},{label:\"德格县\",value:\"513330\"},{label:\"白玉县\",value:\"513331\"},{label:\"石渠县\",value:\"513332\"},{label:\"色达县\",value:\"513333\"},{label:\"理塘县\",value:\"513334\"},{label:\"巴塘县\",value:\"513335\"},{label:\"乡城县\",value:\"513336\"},{label:\"稻城县\",value:\"513337\"},{label:\"得荣县\",value:\"513338\"}],[{label:\"西昌市\",value:\"513401\"},{label:\"木里藏族自治县\",value:\"513422\"},{label:\"盐源县\",value:\"513423\"},{label:\"德昌县\",value:\"513424\"},{label:\"会理县\",value:\"513425\"},{label:\"会东县\",value:\"513426\"},{label:\"宁南县\",value:\"513427\"},{label:\"普格县\",value:\"513428\"},{label:\"布拖县\",value:\"513429\"},{label:\"金阳县\",value:\"513430\"},{label:\"昭觉县\",value:\"513431\"},{label:\"喜德县\",value:\"513432\"},{label:\"冕宁县\",value:\"513433\"},{label:\"越西县\",value:\"513434\"},{label:\"甘洛县\",value:\"513435\"},{label:\"美姑县\",value:\"513436\"},{label:\"雷波县\",value:\"513437\"}]],[[{label:\"南明区\",value:\"520102\"},{label:\"云岩区\",value:\"520103\"},{label:\"花溪区\",value:\"520111\"},{label:\"乌当区\",value:\"520112\"},{label:\"白云区\",value:\"520113\"},{label:\"观山湖区\",value:\"520115\"},{label:\"开阳县\",value:\"520121\"},{label:\"息烽县\",value:\"520122\"},{label:\"修文县\",value:\"520123\"},{label:\"清镇市\",value:\"520181\"}],[{label:\"钟山区\",value:\"520201\"},{label:\"六枝特区\",value:\"520203\"},{label:\"水城县\",value:\"520221\"},{label:\"盘州市\",value:\"520281\"}],[{label:\"红花岗区\",value:\"520302\"},{label:\"汇川区\",value:\"520303\"},{label:\"播州区\",value:\"520304\"},{label:\"桐梓县\",value:\"520322\"},{label:\"绥阳县\",value:\"520323\"},{label:\"正安县\",value:\"520324\"},{label:\"道真仡佬族苗族自治县\",value:\"520325\"},{label:\"务川仡佬族苗族自治县\",value:\"520326\"},{label:\"凤冈县\",value:\"520327\"},{label:\"湄潭县\",value:\"520328\"},{label:\"余庆县\",value:\"520329\"},{label:\"习水县\",value:\"520330\"},{label:\"赤水市\",value:\"520381\"},{label:\"仁怀市\",value:\"520382\"}],[{label:\"西秀区\",value:\"520402\"},{label:\"平坝区\",value:\"520403\"},{label:\"普定县\",value:\"520422\"},{label:\"镇宁布依族苗族自治县\",value:\"520423\"},{label:\"关岭布依族苗族自治县\",value:\"520424\"},{label:\"紫云苗族布依族自治县\",value:\"520425\"}],[{label:\"七星关区\",value:\"520502\"},{label:\"大方县\",value:\"520521\"},{label:\"黔西县\",value:\"520522\"},{label:\"金沙县\",value:\"520523\"},{label:\"织金县\",value:\"520524\"},{label:\"纳雍县\",value:\"520525\"},{label:\"威宁彝族回族苗族自治县\",value:\"520526\"},{label:\"赫章县\",value:\"520527\"}],[{label:\"碧江区\",value:\"520602\"},{label:\"万山区\",value:\"520603\"},{label:\"江口县\",value:\"520621\"},{label:\"玉屏侗族自治县\",value:\"520622\"},{label:\"石阡县\",value:\"520623\"},{label:\"思南县\",value:\"520624\"},{label:\"印江土家族苗族自治县\",value:\"520625\"},{label:\"德江县\",value:\"520626\"},{label:\"沿河土家族自治县\",value:\"520627\"},{label:\"松桃苗族自治县\",value:\"520628\"}],[{label:\"兴义市\",value:\"522301\"},{label:\"兴仁县\",value:\"522322\"},{label:\"普安县\",value:\"522323\"},{label:\"晴隆县\",value:\"522324\"},{label:\"贞丰县\",value:\"522325\"},{label:\"望谟县\",value:\"522326\"},{label:\"册亨县\",value:\"522327\"},{label:\"安龙县\",value:\"522328\"}],[{label:\"凯里市\",value:\"522601\"},{label:\"黄平县\",value:\"522622\"},{label:\"施秉县\",value:\"522623\"},{label:\"三穗县\",value:\"522624\"},{label:\"镇远县\",value:\"522625\"},{label:\"岑巩县\",value:\"522626\"},{label:\"天柱县\",value:\"522627\"},{label:\"锦屏县\",value:\"522628\"},{label:\"剑河县\",value:\"522629\"},{label:\"台江县\",value:\"522630\"},{label:\"黎平县\",value:\"522631\"},{label:\"榕江县\",value:\"522632\"},{label:\"从江县\",value:\"522633\"},{label:\"雷山县\",value:\"522634\"},{label:\"麻江县\",value:\"522635\"},{label:\"丹寨县\",value:\"522636\"}],[{label:\"都匀市\",value:\"522701\"},{label:\"福泉市\",value:\"522702\"},{label:\"荔波县\",value:\"522722\"},{label:\"贵定县\",value:\"522723\"},{label:\"瓮安县\",value:\"522725\"},{label:\"独山县\",value:\"522726\"},{label:\"平塘县\",value:\"522727\"},{label:\"罗甸县\",value:\"522728\"},{label:\"长顺县\",value:\"522729\"},{label:\"龙里县\",value:\"522730\"},{label:\"惠水县\",value:\"522731\"},{label:\"三都水族自治县\",value:\"522732\"}]],[[{label:\"五华区\",value:\"530102\"},{label:\"盘龙区\",value:\"530103\"},{label:\"官渡区\",value:\"530111\"},{label:\"西山区\",value:\"530112\"},{label:\"东川区\",value:\"530113\"},{label:\"呈贡区\",value:\"530114\"},{label:\"晋宁区\",value:\"530115\"},{label:\"富民县\",value:\"530124\"},{label:\"宜良县\",value:\"530125\"},{label:\"石林彝族自治县\",value:\"530126\"},{label:\"嵩明县\",value:\"530127\"},{label:\"禄劝彝族苗族自治县\",value:\"530128\"},{label:\"寻甸回族彝族自治县\",value:\"530129\"},{label:\"安宁市\",value:\"530181\"}],[{label:\"麒麟区\",value:\"530302\"},{label:\"沾益区\",value:\"530303\"},{label:\"马龙县\",value:\"530321\"},{label:\"陆良县\",value:\"530322\"},{label:\"师宗县\",value:\"530323\"},{label:\"罗平县\",value:\"530324\"},{label:\"富源县\",value:\"530325\"},{label:\"会泽县\",value:\"530326\"},{label:\"宣威市\",value:\"530381\"}],[{label:\"红塔区\",value:\"530402\"},{label:\"江川区\",value:\"530403\"},{label:\"澄江县\",value:\"530422\"},{label:\"通海县\",value:\"530423\"},{label:\"华宁县\",value:\"530424\"},{label:\"易门县\",value:\"530425\"},{label:\"峨山彝族自治县\",value:\"530426\"},{label:\"新平彝族傣族自治县\",value:\"530427\"},{label:\"元江哈尼族彝族傣族自治县\",value:\"530428\"}],[{label:\"隆阳区\",value:\"530502\"},{label:\"施甸县\",value:\"530521\"},{label:\"龙陵县\",value:\"530523\"},{label:\"昌宁县\",value:\"530524\"},{label:\"腾冲市\",value:\"530581\"}],[{label:\"昭阳区\",value:\"530602\"},{label:\"鲁甸县\",value:\"530621\"},{label:\"巧家县\",value:\"530622\"},{label:\"盐津县\",value:\"530623\"},{label:\"大关县\",value:\"530624\"},{label:\"永善县\",value:\"530625\"},{label:\"绥江县\",value:\"530626\"},{label:\"镇雄县\",value:\"530627\"},{label:\"彝良县\",value:\"530628\"},{label:\"威信县\",value:\"530629\"},{label:\"水富县\",value:\"530630\"}],[{label:\"古城区\",value:\"530702\"},{label:\"玉龙纳西族自治县\",value:\"530721\"},{label:\"永胜县\",value:\"530722\"},{label:\"华坪县\",value:\"530723\"},{label:\"宁蒗彝族自治县\",value:\"530724\"}],[{label:\"思茅区\",value:\"530802\"},{label:\"宁洱哈尼族彝族自治县\",value:\"530821\"},{label:\"墨江哈尼族自治县\",value:\"530822\"},{label:\"景东彝族自治县\",value:\"530823\"},{label:\"景谷傣族彝族自治县\",value:\"530824\"},{label:\"镇沅彝族哈尼族拉祜族自治县\",value:\"530825\"},{label:\"江城哈尼族彝族自治县\",value:\"530826\"},{label:\"孟连傣族拉祜族佤族自治县\",value:\"530827\"},{label:\"澜沧拉祜族自治县\",value:\"530828\"},{label:\"西盟佤族自治县\",value:\"530829\"}],[{label:\"临翔区\",value:\"530902\"},{label:\"凤庆县\",value:\"530921\"},{label:\"云县\",value:\"530922\"},{label:\"永德县\",value:\"530923\"},{label:\"镇康县\",value:\"530924\"},{label:\"双江拉祜族佤族布朗族傣族自治县\",value:\"530925\"},{label:\"耿马傣族佤族自治县\",value:\"530926\"},{label:\"沧源佤族自治县\",value:\"530927\"}],[{label:\"楚雄市\",value:\"532301\"},{label:\"双柏县\",value:\"532322\"},{label:\"牟定县\",value:\"532323\"},{label:\"南华县\",value:\"532324\"},{label:\"姚安县\",value:\"532325\"},{label:\"大姚县\",value:\"532326\"},{label:\"永仁县\",value:\"532327\"},{label:\"元谋县\",value:\"532328\"},{label:\"武定县\",value:\"532329\"},{label:\"禄丰县\",value:\"532331\"}],[{label:\"个旧市\",value:\"532501\"},{label:\"开远市\",value:\"532502\"},{label:\"蒙自市\",value:\"532503\"},{label:\"弥勒市\",value:\"532504\"},{label:\"屏边苗族自治县\",value:\"532523\"},{label:\"建水县\",value:\"532524\"},{label:\"石屏县\",value:\"532525\"},{label:\"泸西县\",value:\"532527\"},{label:\"元阳县\",value:\"532528\"},{label:\"红河县\",value:\"532529\"},{label:\"金平苗族瑶族傣族自治县\",value:\"532530\"},{label:\"绿春县\",value:\"532531\"},{label:\"河口瑶族自治县\",value:\"532532\"}],[{label:\"文山市\",value:\"532601\"},{label:\"砚山县\",value:\"532622\"},{label:\"西畴县\",value:\"532623\"},{label:\"麻栗坡县\",value:\"532624\"},{label:\"马关县\",value:\"532625\"},{label:\"丘北县\",value:\"532626\"},{label:\"广南县\",value:\"532627\"},{label:\"富宁县\",value:\"532628\"}],[{label:\"景洪市\",value:\"532801\"},{label:\"勐海县\",value:\"532822\"},{label:\"勐腊县\",value:\"532823\"}],[{label:\"大理市\",value:\"532901\"},{label:\"漾濞彝族自治县\",value:\"532922\"},{label:\"祥云县\",value:\"532923\"},{label:\"宾川县\",value:\"532924\"},{label:\"弥渡县\",value:\"532925\"},{label:\"南涧彝族自治县\",value:\"532926\"},{label:\"巍山彝族回族自治县\",value:\"532927\"},{label:\"永平县\",value:\"532928\"},{label:\"云龙县\",value:\"532929\"},{label:\"洱源县\",value:\"532930\"},{label:\"剑川县\",value:\"532931\"},{label:\"鹤庆县\",value:\"532932\"}],[{label:\"瑞丽市\",value:\"533102\"},{label:\"芒市\",value:\"533103\"},{label:\"梁河县\",value:\"533122\"},{label:\"盈江县\",value:\"533123\"},{label:\"陇川县\",value:\"533124\"}],[{label:\"泸水市\",value:\"533301\"},{label:\"福贡县\",value:\"533323\"},{label:\"贡山独龙族怒族自治县\",value:\"533324\"},{label:\"兰坪白族普米族自治县\",value:\"533325\"}],[{label:\"香格里拉市\",value:\"533401\"},{label:\"德钦县\",value:\"533422\"},{label:\"维西傈僳族自治县\",value:\"533423\"}]],[[{label:\"城关区\",value:\"540102\"},{label:\"堆龙德庆区\",value:\"540103\"},{label:\"林周县\",value:\"540121\"},{label:\"当雄县\",value:\"540122\"},{label:\"尼木县\",value:\"540123\"},{label:\"曲水县\",value:\"540124\"},{label:\"达孜县\",value:\"540126\"},{label:\"墨竹工卡县\",value:\"540127\"},{label:\"格尔木藏青工业园区\",value:\"540171\"},{label:\"拉萨经济技术开发区\",value:\"540172\"},{label:\"西藏文化旅游创意园区\",value:\"540173\"},{label:\"达孜工业园区\",value:\"540174\"}],[{label:\"桑珠孜区\",value:\"540202\"},{label:\"南木林县\",value:\"540221\"},{label:\"江孜县\",value:\"540222\"},{label:\"定日县\",value:\"540223\"},{label:\"萨迦县\",value:\"540224\"},{label:\"拉孜县\",value:\"540225\"},{label:\"昂仁县\",value:\"540226\"},{label:\"谢通门县\",value:\"540227\"},{label:\"白朗县\",value:\"540228\"},{label:\"仁布县\",value:\"540229\"},{label:\"康马县\",value:\"540230\"},{label:\"定结县\",value:\"540231\"},{label:\"仲巴县\",value:\"540232\"},{label:\"亚东县\",value:\"540233\"},{label:\"吉隆县\",value:\"540234\"},{label:\"聂拉木县\",value:\"540235\"},{label:\"萨嘎县\",value:\"540236\"},{label:\"岗巴县\",value:\"540237\"}],[{label:\"卡若区\",value:\"540302\"},{label:\"江达县\",value:\"540321\"},{label:\"贡觉县\",value:\"540322\"},{label:\"类乌齐县\",value:\"540323\"},{label:\"丁青县\",value:\"540324\"},{label:\"察雅县\",value:\"540325\"},{label:\"八宿县\",value:\"540326\"},{label:\"左贡县\",value:\"540327\"},{label:\"芒康县\",value:\"540328\"},{label:\"洛隆县\",value:\"540329\"},{label:\"边坝县\",value:\"540330\"}],[{label:\"巴宜区\",value:\"540402\"},{label:\"工布江达县\",value:\"540421\"},{label:\"米林县\",value:\"540422\"},{label:\"墨脱县\",value:\"540423\"},{label:\"波密县\",value:\"540424\"},{label:\"察隅县\",value:\"540425\"},{label:\"朗县\",value:\"540426\"}],[{label:\"乃东区\",value:\"540502\"},{label:\"扎囊县\",value:\"540521\"},{label:\"贡嘎县\",value:\"540522\"},{label:\"桑日县\",value:\"540523\"},{label:\"琼结县\",value:\"540524\"},{label:\"曲松县\",value:\"540525\"},{label:\"措美县\",value:\"540526\"},{label:\"洛扎县\",value:\"540527\"},{label:\"加查县\",value:\"540528\"},{label:\"隆子县\",value:\"540529\"},{label:\"错那县\",value:\"540530\"},{label:\"浪卡子县\",value:\"540531\"}],[{label:\"那曲县\",value:\"542421\"},{label:\"嘉黎县\",value:\"542422\"},{label:\"比如县\",value:\"542423\"},{label:\"聂荣县\",value:\"542424\"},{label:\"安多县\",value:\"542425\"},{label:\"申扎县\",value:\"542426\"},{label:\"索县\",value:\"542427\"},{label:\"班戈县\",value:\"542428\"},{label:\"巴青县\",value:\"542429\"},{label:\"尼玛县\",value:\"542430\"},{label:\"双湖县\",value:\"542431\"}],[{label:\"普兰县\",value:\"542521\"},{label:\"札达县\",value:\"542522\"},{label:\"噶尔县\",value:\"542523\"},{label:\"日土县\",value:\"542524\"},{label:\"革吉县\",value:\"542525\"},{label:\"改则县\",value:\"542526\"},{label:\"措勤县\",value:\"542527\"}]],[[{label:\"新城区\",value:\"610102\"},{label:\"碑林区\",value:\"610103\"},{label:\"莲湖区\",value:\"610104\"},{label:\"灞桥区\",value:\"610111\"},{label:\"未央区\",value:\"610112\"},{label:\"雁塔区\",value:\"610113\"},{label:\"阎良区\",value:\"610114\"},{label:\"临潼区\",value:\"610115\"},{label:\"长安区\",value:\"610116\"},{label:\"高陵区\",value:\"610117\"},{label:\"鄠邑区\",value:\"610118\"},{label:\"蓝田县\",value:\"610122\"},{label:\"周至县\",value:\"610124\"}],[{label:\"王益区\",value:\"610202\"},{label:\"印台区\",value:\"610203\"},{label:\"耀州区\",value:\"610204\"},{label:\"宜君县\",value:\"610222\"}],[{label:\"渭滨区\",value:\"610302\"},{label:\"金台区\",value:\"610303\"},{label:\"陈仓区\",value:\"610304\"},{label:\"凤翔县\",value:\"610322\"},{label:\"岐山县\",value:\"610323\"},{label:\"扶风县\",value:\"610324\"},{label:\"眉县\",value:\"610326\"},{label:\"陇县\",value:\"610327\"},{label:\"千阳县\",value:\"610328\"},{label:\"麟游县\",value:\"610329\"},{label:\"凤县\",value:\"610330\"},{label:\"太白县\",value:\"610331\"}],[{label:\"秦都区\",value:\"610402\"},{label:\"杨陵区\",value:\"610403\"},{label:\"渭城区\",value:\"610404\"},{label:\"三原县\",value:\"610422\"},{label:\"泾阳县\",value:\"610423\"},{label:\"乾县\",value:\"610424\"},{label:\"礼泉县\",value:\"610425\"},{label:\"永寿县\",value:\"610426\"},{label:\"彬县\",value:\"610427\"},{label:\"长武县\",value:\"610428\"},{label:\"旬邑县\",value:\"610429\"},{label:\"淳化县\",value:\"610430\"},{label:\"武功县\",value:\"610431\"},{label:\"兴平市\",value:\"610481\"}],[{label:\"临渭区\",value:\"610502\"},{label:\"华州区\",value:\"610503\"},{label:\"潼关县\",value:\"610522\"},{label:\"大荔县\",value:\"610523\"},{label:\"合阳县\",value:\"610524\"},{label:\"澄城县\",value:\"610525\"},{label:\"蒲城县\",value:\"610526\"},{label:\"白水县\",value:\"610527\"},{label:\"富平县\",value:\"610528\"},{label:\"韩城市\",value:\"610581\"},{label:\"华阴市\",value:\"610582\"}],[{label:\"宝塔区\",value:\"610602\"},{label:\"安塞区\",value:\"610603\"},{label:\"延长县\",value:\"610621\"},{label:\"延川县\",value:\"610622\"},{label:\"子长县\",value:\"610623\"},{label:\"志丹县\",value:\"610625\"},{label:\"吴起县\",value:\"610626\"},{label:\"甘泉县\",value:\"610627\"},{label:\"富县\",value:\"610628\"},{label:\"洛川县\",value:\"610629\"},{label:\"宜川县\",value:\"610630\"},{label:\"黄龙县\",value:\"610631\"},{label:\"黄陵县\",value:\"610632\"}],[{label:\"汉台区\",value:\"610702\"},{label:\"南郑区\",value:\"610703\"},{label:\"城固县\",value:\"610722\"},{label:\"洋县\",value:\"610723\"},{label:\"西乡县\",value:\"610724\"},{label:\"勉县\",value:\"610725\"},{label:\"宁强县\",value:\"610726\"},{label:\"略阳县\",value:\"610727\"},{label:\"镇巴县\",value:\"610728\"},{label:\"留坝县\",value:\"610729\"},{label:\"佛坪县\",value:\"610730\"}],[{label:\"榆阳区\",value:\"610802\"},{label:\"横山区\",value:\"610803\"},{label:\"府谷县\",value:\"610822\"},{label:\"靖边县\",value:\"610824\"},{label:\"定边县\",value:\"610825\"},{label:\"绥德县\",value:\"610826\"},{label:\"米脂县\",value:\"610827\"},{label:\"佳县\",value:\"610828\"},{label:\"吴堡县\",value:\"610829\"},{label:\"清涧县\",value:\"610830\"},{label:\"子洲县\",value:\"610831\"},{label:\"神木市\",value:\"610881\"}],[{label:\"汉滨区\",value:\"610902\"},{label:\"汉阴县\",value:\"610921\"},{label:\"石泉县\",value:\"610922\"},{label:\"宁陕县\",value:\"610923\"},{label:\"紫阳县\",value:\"610924\"},{label:\"岚皋县\",value:\"610925\"},{label:\"平利县\",value:\"610926\"},{label:\"镇坪县\",value:\"610927\"},{label:\"旬阳县\",value:\"610928\"},{label:\"白河县\",value:\"610929\"}],[{label:\"商州区\",value:\"611002\"},{label:\"洛南县\",value:\"611021\"},{label:\"丹凤县\",value:\"611022\"},{label:\"商南县\",value:\"611023\"},{label:\"山阳县\",value:\"611024\"},{label:\"镇安县\",value:\"611025\"},{label:\"柞水县\",value:\"611026\"}]],[[{label:\"城关区\",value:\"620102\"},{label:\"七里河区\",value:\"620103\"},{label:\"西固区\",value:\"620104\"},{label:\"安宁区\",value:\"620105\"},{label:\"红古区\",value:\"620111\"},{label:\"永登县\",value:\"620121\"},{label:\"皋兰县\",value:\"620122\"},{label:\"榆中县\",value:\"620123\"},{label:\"兰州新区\",value:\"620171\"}],[{label:\"嘉峪关市\",value:\"620201\"}],[{label:\"金川区\",value:\"620302\"},{label:\"永昌县\",value:\"620321\"}],[{label:\"白银区\",value:\"620402\"},{label:\"平川区\",value:\"620403\"},{label:\"靖远县\",value:\"620421\"},{label:\"会宁县\",value:\"620422\"},{label:\"景泰县\",value:\"620423\"}],[{label:\"秦州区\",value:\"620502\"},{label:\"麦积区\",value:\"620503\"},{label:\"清水县\",value:\"620521\"},{label:\"秦安县\",value:\"620522\"},{label:\"甘谷县\",value:\"620523\"},{label:\"武山县\",value:\"620524\"},{label:\"张家川回族自治县\",value:\"620525\"}],[{label:\"凉州区\",value:\"620602\"},{label:\"民勤县\",value:\"620621\"},{label:\"古浪县\",value:\"620622\"},{label:\"天祝藏族自治县\",value:\"620623\"}],[{label:\"甘州区\",value:\"620702\"},{label:\"肃南裕固族自治县\",value:\"620721\"},{label:\"民乐县\",value:\"620722\"},{label:\"临泽县\",value:\"620723\"},{label:\"高台县\",value:\"620724\"},{label:\"山丹县\",value:\"620725\"}],[{label:\"崆峒区\",value:\"620802\"},{label:\"泾川县\",value:\"620821\"},{label:\"灵台县\",value:\"620822\"},{label:\"崇信县\",value:\"620823\"},{label:\"华亭县\",value:\"620824\"},{label:\"庄浪县\",value:\"620825\"},{label:\"静宁县\",value:\"620826\"},{label:\"平凉工业园区\",value:\"620871\"}],[{label:\"肃州区\",value:\"620902\"},{label:\"金塔县\",value:\"620921\"},{label:\"瓜州县\",value:\"620922\"},{label:\"肃北蒙古族自治县\",value:\"620923\"},{label:\"阿克塞哈萨克族自治县\",value:\"620924\"},{label:\"玉门市\",value:\"620981\"},{label:\"敦煌市\",value:\"620982\"}],[{label:\"西峰区\",value:\"621002\"},{label:\"庆城县\",value:\"621021\"},{label:\"环县\",value:\"621022\"},{label:\"华池县\",value:\"621023\"},{label:\"合水县\",value:\"621024\"},{label:\"正宁县\",value:\"621025\"},{label:\"宁县\",value:\"621026\"},{label:\"镇原县\",value:\"621027\"}],[{label:\"安定区\",value:\"621102\"},{label:\"通渭县\",value:\"621121\"},{label:\"陇西县\",value:\"621122\"},{label:\"渭源县\",value:\"621123\"},{label:\"临洮县\",value:\"621124\"},{label:\"漳县\",value:\"621125\"},{label:\"岷县\",value:\"621126\"}],[{label:\"武都区\",value:\"621202\"},{label:\"成县\",value:\"621221\"},{label:\"文县\",value:\"621222\"},{label:\"宕昌县\",value:\"621223\"},{label:\"康县\",value:\"621224\"},{label:\"西和县\",value:\"621225\"},{label:\"礼县\",value:\"621226\"},{label:\"徽县\",value:\"621227\"},{label:\"两当县\",value:\"621228\"}],[{label:\"临夏市\",value:\"622901\"},{label:\"临夏县\",value:\"622921\"},{label:\"康乐县\",value:\"622922\"},{label:\"永靖县\",value:\"622923\"},{label:\"广河县\",value:\"622924\"},{label:\"和政县\",value:\"622925\"},{label:\"东乡族自治县\",value:\"622926\"},{label:\"积石山保安族东乡族撒拉族自治县\",value:\"622927\"}],[{label:\"合作市\",value:\"623001\"},{label:\"临潭县\",value:\"623021\"},{label:\"卓尼县\",value:\"623022\"},{label:\"舟曲县\",value:\"623023\"},{label:\"迭部县\",value:\"623024\"},{label:\"玛曲县\",value:\"623025\"},{label:\"碌曲县\",value:\"623026\"},{label:\"夏河县\",value:\"623027\"}]],[[{label:\"城东区\",value:\"630102\"},{label:\"城中区\",value:\"630103\"},{label:\"城西区\",value:\"630104\"},{label:\"城北区\",value:\"630105\"},{label:\"大通回族土族自治县\",value:\"630121\"},{label:\"湟中县\",value:\"630122\"},{label:\"湟源县\",value:\"630123\"}],[{label:\"乐都区\",value:\"630202\"},{label:\"平安区\",value:\"630203\"},{label:\"民和回族土族自治县\",value:\"630222\"},{label:\"互助土族自治县\",value:\"630223\"},{label:\"化隆回族自治县\",value:\"630224\"},{label:\"循化撒拉族自治县\",value:\"630225\"}],[{label:\"门源回族自治县\",value:\"632221\"},{label:\"祁连县\",value:\"632222\"},{label:\"海晏县\",value:\"632223\"},{label:\"刚察县\",value:\"632224\"}],[{label:\"同仁县\",value:\"632321\"},{label:\"尖扎县\",value:\"632322\"},{label:\"泽库县\",value:\"632323\"},{label:\"河南蒙古族自治县\",value:\"632324\"}],[{label:\"共和县\",value:\"632521\"},{label:\"同德县\",value:\"632522\"},{label:\"贵德县\",value:\"632523\"},{label:\"兴海县\",value:\"632524\"},{label:\"贵南县\",value:\"632525\"}],[{label:\"玛沁县\",value:\"632621\"},{label:\"班玛县\",value:\"632622\"},{label:\"甘德县\",value:\"632623\"},{label:\"达日县\",value:\"632624\"},{label:\"久治县\",value:\"632625\"},{label:\"玛多县\",value:\"632626\"}],[{label:\"玉树市\",value:\"632701\"},{label:\"杂多县\",value:\"632722\"},{label:\"称多县\",value:\"632723\"},{label:\"治多县\",value:\"632724\"},{label:\"囊谦县\",value:\"632725\"},{label:\"曲麻莱县\",value:\"632726\"}],[{label:\"格尔木市\",value:\"632801\"},{label:\"德令哈市\",value:\"632802\"},{label:\"乌兰县\",value:\"632821\"},{label:\"都兰县\",value:\"632822\"},{label:\"天峻县\",value:\"632823\"},{label:\"大柴旦行政委员会\",value:\"632857\"},{label:\"冷湖行政委员会\",value:\"632858\"},{label:\"茫崖行政委员会\",value:\"632859\"}]],[[{label:\"兴庆区\",value:\"640104\"},{label:\"西夏区\",value:\"640105\"},{label:\"金凤区\",value:\"640106\"},{label:\"永宁县\",value:\"640121\"},{label:\"贺兰县\",value:\"640122\"},{label:\"灵武市\",value:\"640181\"}],[{label:\"大武口区\",value:\"640202\"},{label:\"惠农区\",value:\"640205\"},{label:\"平罗县\",value:\"640221\"}],[{label:\"利通区\",value:\"640302\"},{label:\"红寺堡区\",value:\"640303\"},{label:\"盐池县\",value:\"640323\"},{label:\"同心县\",value:\"640324\"},{label:\"青铜峡市\",value:\"640381\"}],[{label:\"原州区\",value:\"640402\"},{label:\"西吉县\",value:\"640422\"},{label:\"隆德县\",value:\"640423\"},{label:\"泾源县\",value:\"640424\"},{label:\"彭阳县\",value:\"640425\"}],[{label:\"沙坡头区\",value:\"640502\"},{label:\"中宁县\",value:\"640521\"},{label:\"海原县\",value:\"640522\"}]],[[{label:\"天山区\",value:\"650102\"},{label:\"沙依巴克区\",value:\"650103\"},{label:\"新市区\",value:\"650104\"},{label:\"水磨沟区\",value:\"650105\"},{label:\"头屯河区\",value:\"650106\"},{label:\"达坂城区\",value:\"650107\"},{label:\"米东区\",value:\"650109\"},{label:\"乌鲁木齐县\",value:\"650121\"},{label:\"乌鲁木齐经济技术开发区\",value:\"650171\"},{label:\"乌鲁木齐高新技术产业开发区\",value:\"650172\"}],[{label:\"独山子区\",value:\"650202\"},{label:\"克拉玛依区\",value:\"650203\"},{label:\"白碱滩区\",value:\"650204\"},{label:\"乌尔禾区\",value:\"650205\"}],[{label:\"高昌区\",value:\"650402\"},{label:\"鄯善县\",value:\"650421\"},{label:\"托克逊县\",value:\"650422\"}],[{label:\"伊州区\",value:\"650502\"},{label:\"巴里坤哈萨克自治县\",value:\"650521\"},{label:\"伊吾县\",value:\"650522\"}],[{label:\"昌吉市\",value:\"652301\"},{label:\"阜康市\",value:\"652302\"},{label:\"呼图壁县\",value:\"652323\"},{label:\"玛纳斯县\",value:\"652324\"},{label:\"奇台县\",value:\"652325\"},{label:\"吉木萨尔县\",value:\"652327\"},{label:\"木垒哈萨克自治县\",value:\"652328\"}],[{label:\"博乐市\",value:\"652701\"},{label:\"阿拉山口市\",value:\"652702\"},{label:\"精河县\",value:\"652722\"},{label:\"温泉县\",value:\"652723\"}],[{label:\"库尔勒市\",value:\"652801\"},{label:\"轮台县\",value:\"652822\"},{label:\"尉犁县\",value:\"652823\"},{label:\"若羌县\",value:\"652824\"},{label:\"且末县\",value:\"652825\"},{label:\"焉耆回族自治县\",value:\"652826\"},{label:\"和静县\",value:\"652827\"},{label:\"和硕县\",value:\"652828\"},{label:\"博湖县\",value:\"652829\"},{label:\"库尔勒经济技术开发区\",value:\"652871\"}],[{label:\"阿克苏市\",value:\"652901\"},{label:\"温宿县\",value:\"652922\"},{label:\"库车县\",value:\"652923\"},{label:\"沙雅县\",value:\"652924\"},{label:\"新和县\",value:\"652925\"},{label:\"拜城县\",value:\"652926\"},{label:\"乌什县\",value:\"652927\"},{label:\"阿瓦提县\",value:\"652928\"},{label:\"柯坪县\",value:\"652929\"}],[{label:\"阿图什市\",value:\"653001\"},{label:\"阿克陶县\",value:\"653022\"},{label:\"阿合奇县\",value:\"653023\"},{label:\"乌恰县\",value:\"653024\"}],[{label:\"喀什市\",value:\"653101\"},{label:\"疏附县\",value:\"653121\"},{label:\"疏勒县\",value:\"653122\"},{label:\"英吉沙县\",value:\"653123\"},{label:\"泽普县\",value:\"653124\"},{label:\"莎车县\",value:\"653125\"},{label:\"叶城县\",value:\"653126\"},{label:\"麦盖提县\",value:\"653127\"},{label:\"岳普湖县\",value:\"653128\"},{label:\"伽师县\",value:\"653129\"},{label:\"巴楚县\",value:\"653130\"},{label:\"塔什库尔干塔吉克自治县\",value:\"653131\"}],[{label:\"和田市\",value:\"653201\"},{label:\"和田县\",value:\"653221\"},{label:\"墨玉县\",value:\"653222\"},{label:\"皮山县\",value:\"653223\"},{label:\"洛浦县\",value:\"653224\"},{label:\"策勒县\",value:\"653225\"},{label:\"于田县\",value:\"653226\"},{label:\"民丰县\",value:\"653227\"}],[{label:\"伊宁市\",value:\"654002\"},{label:\"奎屯市\",value:\"654003\"},{label:\"霍尔果斯市\",value:\"654004\"},{label:\"伊宁县\",value:\"654021\"},{label:\"察布查尔锡伯自治县\",value:\"654022\"},{label:\"霍城县\",value:\"654023\"},{label:\"巩留县\",value:\"654024\"},{label:\"新源县\",value:\"654025\"},{label:\"昭苏县\",value:\"654026\"},{label:\"特克斯县\",value:\"654027\"},{label:\"尼勒克县\",value:\"654028\"}],[{label:\"塔城市\",value:\"654201\"},{label:\"乌苏市\",value:\"654202\"},{label:\"额敏县\",value:\"654221\"},{label:\"沙湾县\",value:\"654223\"},{label:\"托里县\",value:\"654224\"},{label:\"裕民县\",value:\"654225\"},{label:\"和布克赛尔蒙古自治县\",value:\"654226\"}],[{label:\"阿勒泰市\",value:\"654301\"},{label:\"布尔津县\",value:\"654321\"},{label:\"富蕴县\",value:\"654322\"},{label:\"福海县\",value:\"654323\"},{label:\"哈巴河县\",value:\"654324\"},{label:\"青河县\",value:\"654325\"},{label:\"吉木乃县\",value:\"654326\"}],[{label:\"石河子市\",value:\"659001\"},{label:\"阿拉尔市\",value:\"659002\"},{label:\"图木舒克市\",value:\"659003\"},{label:\"五家渠市\",value:\"659004\"},{label:\"铁门关市\",value:\"659006\"}]],[[{label:\"台北\",value:\"660101\"}],[{label:\"高雄\",value:\"660201\"}],[{label:\"基隆\",value:\"660301\"}],[{label:\"台中\",value:\"660401\"}],[{label:\"台南\",value:\"660501\"}],[{label:\"新竹\",value:\"660601\"}],[{label:\"嘉义\",value:\"660701\"}],[{label:\"宜兰\",value:\"660801\"}],[{label:\"桃园\",value:\"660901\"}],[{label:\"苗栗\",value:\"661001\"}],[{label:\"彰化\",value:\"661101\"}],[{label:\"南投\",value:\"661201\"}],[{label:\"云林\",value:\"661301\"}],[{label:\"屏东\",value:\"661401\"}],[{label:\"台东\",value:\"661501\"}],[{label:\"花莲\",value:\"661601\"}],[{label:\"澎湖\",value:\"661701\"}]],[[{label:\"香港岛\",value:\"670101\"}],[{label:\"九龙\",value:\"670201\"}],[{label:\"新界\",value:\"670301\"}]],[[{label:\"澳门半岛\",value:\"680101\"}],[{label:\"氹仔岛\",value:\"680201\"}],[{label:\"路环岛\",value:\"680301\"}],[{label:\"路氹城\",value:\"680401\"}]]];"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/util/async-validator.d.ts",
    "content": "/**\n * async-validator 类型声明文件\n * 适用于 uView Pro 内置 async-validator.js\n * 支持 Schema、规则、校验回调、辅助类型等\n */\n\ndeclare type ValidateError = {\n    message: string;\n    field?: string;\n    [key: string]: any;\n};\n\ndeclare type ValidateCallback = (\n    errors?: ValidateError[] | null,\n    fields?: Record<string, ValidateError[]> | null\n) => void;\n\ndeclare interface ValidateRule {\n    type?: string;\n    required?: boolean;\n    message?: string;\n    validator?: (\n        rule: ValidateRule,\n        value: any,\n        callback: ValidateCallback,\n        source: Record<string, any>,\n        options: ValidateOptions\n    ) => void | boolean | string | Error | string[] | Promise<any>;\n    asyncValidator?: (\n        rule: ValidateRule,\n        value: any,\n        callback: ValidateCallback,\n        source: Record<string, any>,\n        options: ValidateOptions\n    ) => Promise<any>;\n    enum?: any[];\n    len?: number;\n    min?: number;\n    max?: number;\n    pattern?: RegExp | string;\n    whitespace?: boolean;\n    fields?: Record<string, ValidateRule | ValidateRule[]>;\n    defaultField?: ValidateRule | ValidateRule[];\n    transform?: (value: any) => any;\n    [key: string]: any;\n}\n\ndeclare interface ValidateOptions {\n    messages?: Record<string, any>;\n    suppressWarning?: boolean;\n    first?: boolean;\n    firstFields?: boolean | string[];\n    keys?: string[];\n    error?: (rule: ValidateRule, msg: string) => ValidateError;\n    [key: string]: any;\n}\n\ndeclare class Schema {\n    constructor(descriptor: Record<string, ValidateRule | ValidateRule[]>);\n    messages(messages?: Record<string, any>): Record<string, any>;\n    define(rules: Record<string, ValidateRule | ValidateRule[]>): void;\n    validate(\n        source: Record<string, any>,\n        options?: ValidateOptions | ValidateCallback,\n        callback?: ValidateCallback\n    ): Promise<void>;\n    getType(rule: ValidateRule): string;\n    getValidationMethod(rule: ValidateRule): Function | false;\n    static register(type: string, validator: Function): void;\n    static warning: (...args: any[]) => void;\n    static messages: Record<string, any>;\n}\n\nexport = Schema;\nexport as namespace Schema;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/util/async-validator.js",
    "content": "function _extends(){return(_extends=Object.assign||function(e){for(var r=1;r<arguments.length;r++){var t,n=arguments[r];for(t in n)Object.prototype.hasOwnProperty.call(n,t)&&(e[t]=n[t])}return e}).apply(this,arguments)}var formatRegExp=/%[sdj%]/g,warning=function(){};function convertFieldsError(e){if(!e||!e.length)return null;var t={};return e.forEach(function(e){var r=e.field;t[r]=t[r]||[],t[r].push(e)}),t}function format(){for(var e=arguments.length,r=new Array(e),t=0;t<e;t++)r[t]=arguments[t];var n=1,a=r[0],i=r.length;if(\"function\"==typeof a)return a.apply(null,r.slice(1));if(\"string\"!=typeof a)return a;for(var s=String(a).replace(formatRegExp,function(e){if(\"%%\"===e)return\"%\";if(i<=n)return e;switch(e){case\"%s\":return String(r[n++]);case\"%d\":return Number(r[n++]);case\"%j\":try{return JSON.stringify(r[n++])}catch(e){return\"[Circular]\"}break;default:return e}}),u=r[n];n<i;u=r[++n])s+=\" \"+u;return s}function isNativeStringType(e){return\"string\"===e||\"url\"===e||\"hex\"===e||\"email\"===e||\"pattern\"===e}function isEmptyValue(e,r){return null==e||(!(\"array\"!==r||!Array.isArray(e)||e.length)||!(!isNativeStringType(r)||\"string\"!=typeof e||e))}function asyncParallelArray(e,r,t){var n=[],a=0,i=e.length;function s(e){n.push.apply(n,e),++a===i&&t(n)}e.forEach(function(e){r(e,s)})}function asyncSerialArray(t,n,a){var i=0,s=t.length;!function e(r){r&&r.length?a(r):(r=i,i+=1,r<s?n(t[r],e):a([]))}([])}function flattenObjArr(r){var t=[];return Object.keys(r).forEach(function(e){t.push.apply(t,r[e])}),t}function asyncMap(a,e,i,s){if(e.first){var r=new Promise(function(r,t){asyncSerialArray(flattenObjArr(a),i,function(e){return s(e),e.length?t({errors:e,fields:convertFieldsError(e)}):r()})});return r.catch(function(e){return e}),r}var u=e.firstFields||[];!0===u&&(u=Object.keys(a));var o=Object.keys(a),l=o.length,f=0,p=[],e=new Promise(function(r,t){function n(e){if(p.push.apply(p,e),++f===l)return s(p),p.length?t({errors:p,fields:convertFieldsError(p)}):r()}o.length||(s(p),r()),o.forEach(function(e){var r=a[e];(-1!==u.indexOf(e)?asyncSerialArray:asyncParallelArray)(r,i,n)})});return e.catch(function(e){return e}),e}function complementError(r){return function(e){return e&&e.message?(e.field=e.field||r.fullField,e):{message:\"function\"==typeof e?e():e,field:e.field||r.fullField}}}function deepMerge(e,r){if(r)for(var t in r){var n;r.hasOwnProperty(t)&&(\"object\"==typeof(n=r[t])&&\"object\"==typeof e[t]?e[t]=_extends({},e[t],{},n):e[t]=n)}return e}function required(e,r,t,n,a,i){!e.required||t.hasOwnProperty(e.field)&&!isEmptyValue(r,i||e.type)||n.push(format(a.messages.required,e.fullField))}function whitespace(e,r,t,n,a){!/^\\s+$/.test(r)&&\"\"!==r||n.push(format(a.messages.whitespace,e.fullField))}\"undefined\"!=typeof process&&process.env&&\"production\"!==process.env.NODE_ENV&&\"undefined\"!=typeof window&&\"undefined\"!=typeof document&&(warning=function(e,r){\"undefined\"!=typeof console&&console.warn&&r.every(function(e){return\"string\"==typeof e})&&console.warn(e,r)});var pattern={email:/^(([^<>()\\[\\]\\\\.,;:\\s@\"]+(\\.[^<>()\\[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/,url:new RegExp(\"^(?!mailto:)(?:(?:http|https|ftp)://|//)(?:\\\\S+(?::\\\\S*)?@)?(?:(?:(?:[1-9]\\\\d?|1\\\\d\\\\d|2[01]\\\\d|22[0-3])(?:\\\\.(?:1?\\\\d{1,2}|2[0-4]\\\\d|25[0-5])){2}(?:\\\\.(?:[0-9]\\\\d?|1\\\\d\\\\d|2[0-4]\\\\d|25[0-4]))|(?:(?:[a-z\\\\u00a1-\\\\uffff0-9]+-*)*[a-z\\\\u00a1-\\\\uffff0-9]+)(?:\\\\.(?:[a-z\\\\u00a1-\\\\uffff0-9]+-*)*[a-z\\\\u00a1-\\\\uffff0-9]+)*(?:\\\\.(?:[a-z\\\\u00a1-\\\\uffff]{2,})))|localhost)(?::\\\\d{2,5})?(?:(/|\\\\?|#)[^\\\\s]*)?$\",\"i\"),hex:/^#?([a-f0-9]{6}|[a-f0-9]{3})$/i},types={integer:function(e){return types.number(e)&&parseInt(e,10)===e},float:function(e){return types.number(e)&&!types.integer(e)},array:function(e){return Array.isArray(e)},regexp:function(e){if(e instanceof RegExp)return!0;try{return!!new RegExp(e)}catch(e){return!1}},date:function(e){return\"function\"==typeof e.getTime&&\"function\"==typeof e.getMonth&&\"function\"==typeof e.getYear},number:function(e){return!isNaN(e)&&\"number\"==typeof+e},object:function(e){return\"object\"==typeof e&&!types.array(e)},method:function(e){return\"function\"==typeof e},email:function(e){return\"string\"==typeof e&&!!e.match(pattern.email)&&e.length<255},url:function(e){return\"string\"==typeof e&&!!e.match(pattern.url)},hex:function(e){return\"string\"==typeof e&&!!e.match(pattern.hex)}};function type(e,r,t,n,a){e.required&&void 0===r?required(e,r,t,n,a):(t=e.type,-1<[\"integer\",\"float\",\"array\",\"regexp\",\"object\",\"method\",\"email\",\"number\",\"date\",\"url\",\"hex\"].indexOf(t)?types[t](r)||n.push(format(a.messages.types[t],e.fullField,e.type)):t&&typeof r!==e.type&&n.push(format(a.messages.types[t],e.fullField,e.type)))}function range(e,r,t,n,a){var i=\"number\"==typeof e.len,s=\"number\"==typeof e.min,u=\"number\"==typeof e.max,o=r,l=null,f=\"number\"==typeof r,p=\"string\"==typeof r,d=Array.isArray(r);if(f?l=\"number\":p?l=\"string\":d&&(l=\"array\"),!l)return!1;d&&(o=r.length),p&&(o=r.replace(/[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g,\"_\").length),i?o!==e.len&&n.push(format(a.messages[l].len,e.fullField,e.len)):s&&!u&&o<e.min?n.push(format(a.messages[l].min,e.fullField,e.min)):u&&!s&&o>e.max?n.push(format(a.messages[l].max,e.fullField,e.max)):s&&u&&(o<e.min||o>e.max)&&n.push(format(a.messages[l].range,e.fullField,e.min,e.max))}var ENUM=\"enum\";function enumerable(e,r,t,n,a){e[ENUM]=Array.isArray(e[ENUM])?e[ENUM]:[],-1===e[ENUM].indexOf(r)&&n.push(format(a.messages[ENUM],e.fullField,e[ENUM].join(\", \")))}function pattern$1(e,r,t,n,a){e.pattern&&(e.pattern instanceof RegExp?(e.pattern.lastIndex=0,e.pattern.test(r)||n.push(format(a.messages.pattern.mismatch,e.fullField,r,e.pattern))):\"string\"==typeof e.pattern&&(new RegExp(e.pattern).test(r)||n.push(format(a.messages.pattern.mismatch,e.fullField,r,e.pattern))))}var rules={required:required,whitespace:whitespace,type:type,range:range,enum:enumerable,pattern:pattern$1};function string(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r,\"string\")&&!e.required)return t();rules.required(e,r,n,i,a,\"string\"),isEmptyValue(r,\"string\")||(rules.type(e,r,n,i,a),rules.range(e,r,n,i,a),rules.pattern(e,r,n,i,a),!0===e.whitespace&&rules.whitespace(e,r,n,i,a))}t(i)}function method(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r)&&!e.required)return t();rules.required(e,r,n,i,a),void 0!==r&&rules.type(e,r,n,i,a)}t(i)}function number(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(\"\"===r&&(r=void 0),isEmptyValue(r)&&!e.required)return t();rules.required(e,r,n,i,a),void 0!==r&&(rules.type(e,r,n,i,a),rules.range(e,r,n,i,a))}t(i)}function _boolean(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r)&&!e.required)return t();rules.required(e,r,n,i,a),void 0!==r&&rules.type(e,r,n,i,a)}t(i)}function regexp(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r)&&!e.required)return t();rules.required(e,r,n,i,a),isEmptyValue(r)||rules.type(e,r,n,i,a)}t(i)}function integer(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r)&&!e.required)return t();rules.required(e,r,n,i,a),void 0!==r&&(rules.type(e,r,n,i,a),rules.range(e,r,n,i,a))}t(i)}function floatFn(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r)&&!e.required)return t();rules.required(e,r,n,i,a),void 0!==r&&(rules.type(e,r,n,i,a),rules.range(e,r,n,i,a))}t(i)}function array(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r,\"array\")&&!e.required)return t();rules.required(e,r,n,i,a,\"array\"),isEmptyValue(r,\"array\")||(rules.type(e,r,n,i,a),rules.range(e,r,n,i,a))}t(i)}function object(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r)&&!e.required)return t();rules.required(e,r,n,i,a),void 0!==r&&rules.type(e,r,n,i,a)}t(i)}var ENUM$1=\"enum\";function enumerable$1(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r)&&!e.required)return t();rules.required(e,r,n,i,a),void 0!==r&&rules[ENUM$1](e,r,n,i,a)}t(i)}function pattern$2(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r,\"string\")&&!e.required)return t();rules.required(e,r,n,i,a),isEmptyValue(r,\"string\")||rules.pattern(e,r,n,i,a)}t(i)}function date(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r)&&!e.required)return t();rules.required(e,r,n,i,a),isEmptyValue(r)||(r=\"number\"==typeof r?new Date(r):r,rules.type(e,r,n,i,a),r&&rules.range(e,r.getTime(),n,i,a))}t(i)}function required$1(e,r,t,n,a){var i=[],s=Array.isArray(r)?\"array\":typeof r;rules.required(e,r,n,i,a,s),t(i)}function type$1(e,r,t,n,a){var i=e.type,s=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r,i)&&!e.required)return t();rules.required(e,r,n,s,a,i),isEmptyValue(r,i)||rules.type(e,r,n,s,a)}t(s)}function any(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r)&&!e.required)return t();rules.required(e,r,n,i,a)}t(i)}var validators={string:string,method:method,number:number,boolean:_boolean,regexp:regexp,integer:integer,float:floatFn,array:array,object:object,enum:enumerable$1,pattern:pattern$2,date:date,url:type$1,hex:type$1,email:type$1,required:required$1,any:any};function newMessages(){return{default:\"Validation error on field %s\",required:\"%s is required\",enum:\"%s must be one of %s\",whitespace:\"%s cannot be empty\",date:{format:\"%s date %s is invalid for format %s\",parse:\"%s date could not be parsed, %s is invalid \",invalid:\"%s date %s is invalid\"},types:{string:\"%s is not a %s\",method:\"%s is not a %s (function)\",array:\"%s is not an %s\",object:\"%s is not an %s\",number:\"%s is not a %s\",date:\"%s is not a %s\",boolean:\"%s is not a %s\",integer:\"%s is not an %s\",float:\"%s is not a %s\",regexp:\"%s is not a valid %s\",email:\"%s is not a valid %s\",url:\"%s is not a valid %s\",hex:\"%s is not a valid %s\"},string:{len:\"%s must be exactly %s characters\",min:\"%s must be at least %s characters\",max:\"%s cannot be longer than %s characters\",range:\"%s must be between %s and %s characters\"},number:{len:\"%s must equal %s\",min:\"%s cannot be less than %s\",max:\"%s cannot be greater than %s\",range:\"%s must be between %s and %s\"},array:{len:\"%s must be exactly %s in length\",min:\"%s cannot be less than %s in length\",max:\"%s cannot be greater than %s in length\",range:\"%s must be between %s and %s in length\"},pattern:{mismatch:\"%s value %s does not match pattern %s\"},clone:function(){var e=JSON.parse(JSON.stringify(this));return e.clone=this.clone,e}}}var messages=newMessages();function Schema(e){this.rules=null,this._messages=messages,this.define(e)}Schema.prototype={messages:function(e){return e&&(this._messages=deepMerge(newMessages(),e)),this._messages},define:function(e){if(!e)throw new Error(\"Cannot configure a schema with no rules\");if(\"object\"!=typeof e||Array.isArray(e))throw new Error(\"Rules must be an object\");var r,t;for(r in this.rules={},e)e.hasOwnProperty(r)&&(t=e[r],this.rules[r]=Array.isArray(t)?t:[t])},validate:function(t,e,r){var n=this;void 0===e&&(e={}),void 0===r&&(r=function(){});var a,i,s=t,p=e,u=r;if(\"function\"==typeof p&&(u=p,p={}),!this.rules||0===Object.keys(this.rules).length)return u&&u(),Promise.resolve();p.messages?((r=this.messages())===messages&&(r=newMessages()),deepMerge(r,p.messages),p.messages=r):p.messages=this.messages();var o={};(p.keys||Object.keys(this.rules)).forEach(function(r){a=n.rules[r],i=s[r],a.forEach(function(e){\"function\"==typeof e.transform&&(s===t&&(s=_extends({},s)),i=s[r]=e.transform(i)),(e=\"function\"==typeof e?{validator:e}:_extends({},e)).validator=n.getValidationMethod(e),e.field=r,e.fullField=e.fullField||r,e.type=n.getType(e),e.validator&&(o[r]=o[r]||[],o[r].push({rule:e,value:i,source:s,field:r}))})});var d={};return asyncMap(o,p,function(s,u){var e,o=s.rule,l=!(\"object\"!==o.type&&\"array\"!==o.type||\"object\"!=typeof o.fields&&\"object\"!=typeof o.defaultField);function f(e,r){return _extends({},r,{fullField:o.fullField+\".\"+e})}function r(e){void 0===e&&(e=[]);var t=e;if(Array.isArray(t)||(t=[t]),!p.suppressWarning&&t.length&&Schema.warning(\"async-validator:\",t),t.length&&o.message&&(t=[].concat(o.message)),t=t.map(complementError(o)),p.first&&t.length)return d[o.field]=1,u(t);if(l){if(o.required&&!s.value)return t=o.message?[].concat(o.message).map(complementError(o)):p.error?[p.error(o,format(p.messages.required,o.field))]:[],u(t);var r,n,a={};if(o.defaultField)for(var i in s.value)s.value.hasOwnProperty(i)&&(a[i]=o.defaultField);for(r in a=_extends({},a,{},s.rule.fields))a.hasOwnProperty(r)&&(n=Array.isArray(a[r])?a[r]:[a[r]],a[r]=n.map(f.bind(null,r)));e=new Schema(a);e.messages(p.messages),s.rule.options&&(s.rule.options.messages=p.messages,s.rule.options.error=p.error),e.validate(s.value,s.rule.options||p,function(e){var r=[];t&&t.length&&r.push.apply(r,t),e&&e.length&&r.push.apply(r,e),u(r.length?r:null)})}else u(t)}l=l&&(o.required||!o.required&&s.value),o.field=s.field,o.asyncValidator?e=o.asyncValidator(o,s.value,r,s.source,p):o.validator&&(!0===(e=o.validator(o,s.value,r,s.source,p))?r():!1===e?r(o.message||o.field+\" fails\"):e instanceof Array?r(e):e instanceof Error&&r(e.message)),e&&e.then&&e.then(function(){return r()},r)},function(e){!function(e){var r,t,n=[],a={};for(r=0;r<e.length;r++)t=e[r],Array.isArray(t)?n=n.concat.apply(n,t):n.push(t);a=n.length?convertFieldsError(n):n=null,u(n,a)}(e)})},getType:function(e){if(void 0===e.type&&e.pattern instanceof RegExp&&(e.type=\"pattern\"),\"function\"!=typeof e.validator&&e.type&&!validators.hasOwnProperty(e.type))throw new Error(format(\"Unknown rule type %s\",e.type));return e.type||\"string\"},getValidationMethod:function(e){if(\"function\"==typeof e.validator)return e.validator;var r=Object.keys(e),t=r.indexOf(\"message\");return-1!==t&&r.splice(t,1),1===r.length&&\"required\"===r[0]?validators.required:validators[this.getType(e)]||!1}},Schema.register=function(e,r){if(\"function\"!=typeof r)throw new Error(\"Cannot register a validator by type, validator is not a function\");validators[e]=r},Schema.warning=warning,Schema.messages=messages;export default Schema;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/util/calendar.d.ts",
    "content": "// Type definitions for calendar.js (农历/公历互转)\n// Project: https://github.com/jjonline/calendar.js\n\nexport interface Solar2LunarResult {\n    lYear: number; // 农历年\n    lMonth: number; // 农历月\n    lDay: number; // 农历日\n    Animal: string; // 生肖\n    IMonthCn: string; // 农历月中文\n    IDayCn: string; // 农历日中文\n    cYear: number; // 公历年\n    cMonth: number; // 公历月\n    cDay: number; // 公历日\n    gzYear: string; // 干支年\n    gzMonth: string; // 干支月\n    gzDay: string; // 干支日\n    isToday: boolean; // 是否今天\n    isLeap: boolean; // 是否闰月\n    nWeek: number; // 星期几（1-7，周一为1）\n    ncWeek: string; // 星期几中文\n    isTerm: boolean; // 是否节气\n    Term: string | null; // 节气名\n    astro: string; // 星座\n}\n\nexport interface Lunar2SolarResult extends Solar2LunarResult {}\n\nexport interface Calendar {\n    lunarInfo: number[];\n    solarMonth: number[];\n    Gan: string[];\n    Zhi: string[];\n    Animals: string[];\n    solarTerm: string[];\n    sTermInfo: string[];\n    nStr1: string[];\n    nStr2: string[];\n    nStr3: string[];\n\n    lYearDays(y: number): number;\n    leapMonth(y: number): number;\n    leapDays(y: number): number;\n    monthDays(y: number, m: number): number;\n    solarDays(y: number, m: number): number;\n    toGanZhiYear(lYear: number): string;\n    toAstro(cMonth: number, cDay: number): string;\n    toGanZhi(offset: number): string;\n    getTerm(y: number, n: number): number;\n    toChinaMonth(m: number): string;\n    toChinaDay(d: number): string;\n    getAnimal(y: number): string;\n    solar2lunar(y: number, m: number, d: number): Solar2LunarResult;\n    lunar2solar(y: number, m: number, d: number, isLeapMonth?: boolean): Lunar2SolarResult;\n}\n\ndeclare const calendar: Calendar;\nexport default calendar;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/util/calendar.js",
    "content": "export default {lunarInfo:[19416,19168,42352,21717,53856,55632,91476,22176,39632,21970,19168,42422,42192,53840,119381,46400,54944,44450,38320,84343,18800,42160,46261,27216,27968,109396,11104,38256,21234,18800,25958,54432,59984,28309,23248,11104,100067,37600,116951,51536,54432,120998,46416,22176,107956,9680,37584,53938,43344,46423,27808,46416,86869,19872,42416,83315,21168,43432,59728,27296,44710,43856,19296,43748,42352,21088,62051,55632,23383,22176,38608,19925,19152,42192,54484,53840,54616,46400,46752,103846,38320,18864,43380,42160,45690,27216,27968,44870,43872,38256,19189,18800,25776,29859,59984,27480,23232,43872,38613,37600,51552,55636,54432,55888,30034,22176,43959,9680,37584,51893,43344,46240,47780,44368,21977,19360,42416,86390,21168,43312,31060,27296,44368,23378,19296,42726,42208,53856,60005,54576,23200,30371,38608,19195,19152,42192,118966,53840,54560,56645,46496,22224,21938,18864,42359,42160,43600,111189,27936,44448,84835,37744,18936,18800,25776,92326,59984,27424,108228,43744,41696,53987,51552,54615,54432,55888,23893,22176,42704,21972,21200,43448,43344,46240,46758,44368,21920,43940,42416,21168,45683,26928,29495,27296,44368,84821,19296,42352,21732,53600,59752,54560,55968,92838,22224,19168,43476,41680,53584,62034,54560],solarMonth:[31,28,31,30,31,30,31,31,30,31,30,31],Gan:[\"甲\",\"乙\",\"丙\",\"丁\",\"戊\",\"己\",\"庚\",\"辛\",\"壬\",\"癸\"],Zhi:[\"子\",\"丑\",\"寅\",\"卯\",\"辰\",\"巳\",\"午\",\"未\",\"申\",\"酉\",\"戌\",\"亥\"],Animals:[\"鼠\",\"牛\",\"虎\",\"兔\",\"龙\",\"蛇\",\"马\",\"羊\",\"猴\",\"鸡\",\"狗\",\"猪\"],solarTerm:[\"小寒\",\"大寒\",\"立春\",\"雨水\",\"惊蛰\",\"春分\",\"清明\",\"谷雨\",\"立夏\",\"小满\",\"芒种\",\"夏至\",\"小暑\",\"大暑\",\"立秋\",\"处暑\",\"白露\",\"秋分\",\"寒露\",\"霜降\",\"立冬\",\"小雪\",\"大雪\",\"冬至\"],sTermInfo:[\"9778397bd097c36b0b6fc9274c91aa\",\"97b6b97bd19801ec9210c965cc920e\",\"97bcf97c3598082c95f8c965cc920f\",\"97bd0b06bdb0722c965ce1cfcc920f\",\"b027097bd097c36b0b6fc9274c91aa\",\"97b6b97bd19801ec9210c965cc920e\",\"97bcf97c359801ec95f8c965cc920f\",\"97bd0b06bdb0722c965ce1cfcc920f\",\"b027097bd097c36b0b6fc9274c91aa\",\"97b6b97bd19801ec9210c965cc920e\",\"97bcf97c359801ec95f8c965cc920f\",\"97bd0b06bdb0722c965ce1cfcc920f\",\"b027097bd097c36b0b6fc9274c91aa\",\"9778397bd19801ec9210c965cc920e\",\"97b6b97bd19801ec95f8c965cc920f\",\"97bd09801d98082c95f8e1cfcc920f\",\"97bd097bd097c36b0b6fc9210c8dc2\",\"9778397bd197c36c9210c9274c91aa\",\"97b6b97bd19801ec95f8c965cc920e\",\"97bd09801d98082c95f8e1cfcc920f\",\"97bd097bd097c36b0b6fc9210c8dc2\",\"9778397bd097c36c9210c9274c91aa\",\"97b6b97bd19801ec95f8c965cc920e\",\"97bcf97c3598082c95f8e1cfcc920f\",\"97bd097bd097c36b0b6fc9210c8dc2\",\"9778397bd097c36c9210c9274c91aa\",\"97b6b97bd19801ec9210c965cc920e\",\"97bcf97c3598082c95f8c965cc920f\",\"97bd097bd097c35b0b6fc920fb0722\",\"9778397bd097c36b0b6fc9274c91aa\",\"97b6b97bd19801ec9210c965cc920e\",\"97bcf97c3598082c95f8c965cc920f\",\"97bd097bd097c35b0b6fc920fb0722\",\"9778397bd097c36b0b6fc9274c91aa\",\"97b6b97bd19801ec9210c965cc920e\",\"97bcf97c359801ec95f8c965cc920f\",\"97bd097bd097c35b0b6fc920fb0722\",\"9778397bd097c36b0b6fc9274c91aa\",\"97b6b97bd19801ec9210c965cc920e\",\"97bcf97c359801ec95f8c965cc920f\",\"97bd097bd097c35b0b6fc920fb0722\",\"9778397bd097c36b0b6fc9274c91aa\",\"97b6b97bd19801ec9210c965cc920e\",\"97bcf97c359801ec95f8c965cc920f\",\"97bd097bd07f595b0b6fc920fb0722\",\"9778397bd097c36b0b6fc9210c8dc2\",\"9778397bd19801ec9210c9274c920e\",\"97b6b97bd19801ec95f8c965cc920f\",\"97bd07f5307f595b0b0bc920fb0722\",\"7f0e397bd097c36b0b6fc9210c8dc2\",\"9778397bd097c36c9210c9274c920e\",\"97b6b97bd19801ec95f8c965cc920f\",\"97bd07f5307f595b0b0bc920fb0722\",\"7f0e397bd097c36b0b6fc9210c8dc2\",\"9778397bd097c36c9210c9274c91aa\",\"97b6b97bd19801ec9210c965cc920e\",\"97bd07f1487f595b0b0bc920fb0722\",\"7f0e397bd097c36b0b6fc9210c8dc2\",\"9778397bd097c36b0b6fc9274c91aa\",\"97b6b97bd19801ec9210c965cc920e\",\"97bcf7f1487f595b0b0bb0b6fb0722\",\"7f0e397bd097c35b0b6fc920fb0722\",\"9778397bd097c36b0b6fc9274c91aa\",\"97b6b97bd19801ec9210c965cc920e\",\"97bcf7f1487f595b0b0bb0b6fb0722\",\"7f0e397bd097c35b0b6fc920fb0722\",\"9778397bd097c36b0b6fc9274c91aa\",\"97b6b97bd19801ec9210c965cc920e\",\"97bcf7f1487f531b0b0bb0b6fb0722\",\"7f0e397bd097c35b0b6fc920fb0722\",\"9778397bd097c36b0b6fc9274c91aa\",\"97b6b97bd19801ec9210c965cc920e\",\"97bcf7f1487f531b0b0bb0b6fb0722\",\"7f0e397bd07f595b0b6fc920fb0722\",\"9778397bd097c36b0b6fc9274c91aa\",\"97b6b97bd19801ec9210c9274c920e\",\"97bcf7f0e47f531b0b0bb0b6fb0722\",\"7f0e397bd07f595b0b0bc920fb0722\",\"9778397bd097c36b0b6fc9210c91aa\",\"97b6b97bd197c36c9210c9274c920e\",\"97bcf7f0e47f531b0b0bb0b6fb0722\",\"7f0e397bd07f595b0b0bc920fb0722\",\"9778397bd097c36b0b6fc9210c8dc2\",\"9778397bd097c36c9210c9274c920e\",\"97b6b7f0e47f531b0723b0b6fb0722\",\"7f0e37f5307f595b0b0bc920fb0722\",\"7f0e397bd097c36b0b6fc9210c8dc2\",\"9778397bd097c36b0b70c9274c91aa\",\"97b6b7f0e47f531b0723b0b6fb0721\",\"7f0e37f1487f595b0b0bb0b6fb0722\",\"7f0e397bd097c35b0b6fc9210c8dc2\",\"9778397bd097c36b0b6fc9274c91aa\",\"97b6b7f0e47f531b0723b0b6fb0721\",\"7f0e27f1487f595b0b0bb0b6fb0722\",\"7f0e397bd097c35b0b6fc920fb0722\",\"9778397bd097c36b0b6fc9274c91aa\",\"97b6b7f0e47f531b0723b0b6fb0721\",\"7f0e27f1487f531b0b0bb0b6fb0722\",\"7f0e397bd097c35b0b6fc920fb0722\",\"9778397bd097c36b0b6fc9274c91aa\",\"97b6b7f0e47f531b0723b0b6fb0721\",\"7f0e27f1487f531b0b0bb0b6fb0722\",\"7f0e397bd097c35b0b6fc920fb0722\",\"9778397bd097c36b0b6fc9274c91aa\",\"97b6b7f0e47f531b0723b0b6fb0721\",\"7f0e27f1487f531b0b0bb0b6fb0722\",\"7f0e397bd07f595b0b0bc920fb0722\",\"9778397bd097c36b0b6fc9274c91aa\",\"97b6b7f0e47f531b0723b0787b0721\",\"7f0e27f0e47f531b0b0bb0b6fb0722\",\"7f0e397bd07f595b0b0bc920fb0722\",\"9778397bd097c36b0b6fc9210c91aa\",\"97b6b7f0e47f149b0723b0787b0721\",\"7f0e27f0e47f531b0723b0b6fb0722\",\"7f0e397bd07f595b0b0bc920fb0722\",\"9778397bd097c36b0b6fc9210c8dc2\",\"977837f0e37f149b0723b0787b0721\",\"7f07e7f0e47f531b0723b0b6fb0722\",\"7f0e37f5307f595b0b0bc920fb0722\",\"7f0e397bd097c35b0b6fc9210c8dc2\",\"977837f0e37f14998082b0787b0721\",\"7f07e7f0e47f531b0723b0b6fb0721\",\"7f0e37f1487f595b0b0bb0b6fb0722\",\"7f0e397bd097c35b0b6fc9210c8dc2\",\"977837f0e37f14998082b0787b06bd\",\"7f07e7f0e47f531b0723b0b6fb0721\",\"7f0e27f1487f531b0b0bb0b6fb0722\",\"7f0e397bd097c35b0b6fc920fb0722\",\"977837f0e37f14998082b0787b06bd\",\"7f07e7f0e47f531b0723b0b6fb0721\",\"7f0e27f1487f531b0b0bb0b6fb0722\",\"7f0e397bd097c35b0b6fc920fb0722\",\"977837f0e37f14998082b0787b06bd\",\"7f07e7f0e47f531b0723b0b6fb0721\",\"7f0e27f1487f531b0b0bb0b6fb0722\",\"7f0e397bd07f595b0b0bc920fb0722\",\"977837f0e37f14998082b0787b06bd\",\"7f07e7f0e47f531b0723b0b6fb0721\",\"7f0e27f1487f531b0b0bb0b6fb0722\",\"7f0e397bd07f595b0b0bc920fb0722\",\"977837f0e37f14998082b0787b06bd\",\"7f07e7f0e47f149b0723b0787b0721\",\"7f0e27f0e47f531b0b0bb0b6fb0722\",\"7f0e397bd07f595b0b0bc920fb0722\",\"977837f0e37f14998082b0723b06bd\",\"7f07e7f0e37f149b0723b0787b0721\",\"7f0e27f0e47f531b0723b0b6fb0722\",\"7f0e397bd07f595b0b0bc920fb0722\",\"977837f0e37f14898082b0723b02d5\",\"7ec967f0e37f14998082b0787b0721\",\"7f07e7f0e47f531b0723b0b6fb0722\",\"7f0e37f1487f595b0b0bb0b6fb0722\",\"7f0e37f0e37f14898082b0723b02d5\",\"7ec967f0e37f14998082b0787b0721\",\"7f07e7f0e47f531b0723b0b6fb0722\",\"7f0e37f1487f531b0b0bb0b6fb0722\",\"7f0e37f0e37f14898082b0723b02d5\",\"7ec967f0e37f14998082b0787b06bd\",\"7f07e7f0e47f531b0723b0b6fb0721\",\"7f0e37f1487f531b0b0bb0b6fb0722\",\"7f0e37f0e37f14898082b072297c35\",\"7ec967f0e37f14998082b0787b06bd\",\"7f07e7f0e47f531b0723b0b6fb0721\",\"7f0e27f1487f531b0b0bb0b6fb0722\",\"7f0e37f0e37f14898082b072297c35\",\"7ec967f0e37f14998082b0787b06bd\",\"7f07e7f0e47f531b0723b0b6fb0721\",\"7f0e27f1487f531b0b0bb0b6fb0722\",\"7f0e37f0e366aa89801eb072297c35\",\"7ec967f0e37f14998082b0787b06bd\",\"7f07e7f0e47f149b0723b0787b0721\",\"7f0e27f1487f531b0b0bb0b6fb0722\",\"7f0e37f0e366aa89801eb072297c35\",\"7ec967f0e37f14998082b0723b06bd\",\"7f07e7f0e47f149b0723b0787b0721\",\"7f0e27f0e47f531b0723b0b6fb0722\",\"7f0e37f0e366aa89801eb072297c35\",\"7ec967f0e37f14998082b0723b06bd\",\"7f07e7f0e37f14998083b0787b0721\",\"7f0e27f0e47f531b0723b0b6fb0722\",\"7f0e37f0e366aa89801eb072297c35\",\"7ec967f0e37f14898082b0723b02d5\",\"7f07e7f0e37f14998082b0787b0721\",\"7f07e7f0e47f531b0723b0b6fb0722\",\"7f0e36665b66aa89801e9808297c35\",\"665f67f0e37f14898082b0723b02d5\",\"7ec967f0e37f14998082b0787b0721\",\"7f07e7f0e47f531b0723b0b6fb0722\",\"7f0e36665b66a449801e9808297c35\",\"665f67f0e37f14898082b0723b02d5\",\"7ec967f0e37f14998082b0787b06bd\",\"7f07e7f0e47f531b0723b0b6fb0721\",\"7f0e36665b66a449801e9808297c35\",\"665f67f0e37f14898082b072297c35\",\"7ec967f0e37f14998082b0787b06bd\",\"7f07e7f0e47f531b0723b0b6fb0721\",\"7f0e26665b66a449801e9808297c35\",\"665f67f0e37f1489801eb072297c35\",\"7ec967f0e37f14998082b0787b06bd\",\"7f07e7f0e47f531b0723b0b6fb0721\",\"7f0e27f1487f531b0b0bb0b6fb0722\"],nStr1:[\"日\",\"一\",\"二\",\"三\",\"四\",\"五\",\"六\",\"七\",\"八\",\"九\",\"十\"],nStr2:[\"初\",\"十\",\"廿\",\"卅\"],nStr3:[\"正\",\"二\",\"三\",\"四\",\"五\",\"六\",\"七\",\"八\",\"九\",\"十\",\"冬\",\"腊\"],lYearDays:function(b){for(var f=348,c=32768;8<c;c>>=1)f+=this.lunarInfo[b-1900]&c?1:0;return f+this.leapDays(b)},leapMonth:function(b){return 15&this.lunarInfo[b-1900]},leapDays:function(b){return this.leapMonth(b)?65536&this.lunarInfo[b-1900]?30:29:0},monthDays:function(b,f){return 12<f||f<1?-1:this.lunarInfo[b-1900]&65536>>f?30:29},solarDays:function(b,f){if(12<f||f<1)return-1;--f;return 1==f?b%4==0&&b%100!=0||b%400==0?29:28:this.solarMonth[f]},toGanZhiYear:function(b){var f=(b-3)%10,b=(b-3)%12;return 0==f&&(f=10),0==b&&(b=12),this.Gan[f-1]+this.Zhi[b-1]},toAstro:function(b,f){return\"魔羯水瓶双鱼白羊金牛双子巨蟹狮子处女天秤天蝎射手魔羯\".substr(2*b-(f<[20,19,21,21,21,22,23,23,23,23,22,22][b-1]?2:0),2)+\"座\"},toGanZhi:function(b){return this.Gan[b%10]+this.Zhi[b%12]},getTerm:function(b,f){if(b<1900||2100<b)return-1;if(f<1||24<f)return-1;b=this.sTermInfo[b-1900],b=[parseInt(\"0x\"+b.substr(0,5)).toString(),parseInt(\"0x\"+b.substr(5,5)).toString(),parseInt(\"0x\"+b.substr(10,5)).toString(),parseInt(\"0x\"+b.substr(15,5)).toString(),parseInt(\"0x\"+b.substr(20,5)).toString(),parseInt(\"0x\"+b.substr(25,5)).toString()],b=[b[0].substr(0,1),b[0].substr(1,2),b[0].substr(3,1),b[0].substr(4,2),b[1].substr(0,1),b[1].substr(1,2),b[1].substr(3,1),b[1].substr(4,2),b[2].substr(0,1),b[2].substr(1,2),b[2].substr(3,1),b[2].substr(4,2),b[3].substr(0,1),b[3].substr(1,2),b[3].substr(3,1),b[3].substr(4,2),b[4].substr(0,1),b[4].substr(1,2),b[4].substr(3,1),b[4].substr(4,2),b[5].substr(0,1),b[5].substr(1,2),b[5].substr(3,1),b[5].substr(4,2)];return parseInt(b[f-1])},toChinaMonth:function(b){if(12<b||b<1)return-1;b=this.nStr3[b-1];return b+=\"月\"},toChinaDay:function(b){var f;switch(b){case 10:f=\"初十\";break;case 20:f=\"二十\";break;case 30:f=\"三十\";break;default:f=this.nStr2[Math.floor(b/10)],f+=this.nStr1[b%10]}return f},getAnimal:function(b){return this.Animals[(b-4)%12]},solar2lunar:function(b,f,c){if(b<1900||2100<b)return-1;if(1900==b&&1==f&&c<31)return-1;for(var e=0,b=(M=b?new Date(b,parseInt(f)-1,c):new Date).getFullYear(),f=M.getMonth()+1,c=M.getDate(),t=(Date.UTC(M.getFullYear(),M.getMonth(),M.getDate())-Date.UTC(1900,0,31))/864e5,a=1900;a<2101&&0<t;a++)t-=e=this.lYearDays(a);t<0&&(t+=e,a--);var r=new Date,s=!1;r.getFullYear()==b&&r.getMonth()+1==f&&r.getDate()==c&&(s=!0);var d=M.getDay(),n=this.nStr1[d];0==d&&(d=7);var i=a,u=this.leapMonth(a),o=!1;for(a=1;a<13&&0<t;a++)e=0<u&&a==u+1&&0==o?(--a,o=!0,this.leapDays(i)):this.monthDays(i,a),1==o&&a==u+1&&(o=!1),t-=e;0==t&&0<u&&a==u+1&&(o?o=!1:(o=!0,--a)),t<0&&(t+=e,--a);var h=a,l=t+1,D=f-1,g=this.toGanZhiYear(i),y=this.getTerm(b,2*f-1),p=this.getTerm(b,2*f),m=this.toGanZhi(12*(b-1900)+f+11);y<=c&&(m=this.toGanZhi(12*(b-1900)+f+12));var r=!1,M=null;y==c&&(r=!0,M=this.solarTerm[2*f-2]),p==c&&(r=!0,M=this.solarTerm[2*f-1]);p=Date.UTC(b,D,1,0,0,0,0)/864e5+25567+10,D=this.toGanZhi(p+c-1),p=this.toAstro(f,c);return{lYear:i,lMonth:h,lDay:l,Animal:this.getAnimal(i),IMonthCn:(o?\"闰\":\"\")+this.toChinaMonth(h),IDayCn:this.toChinaDay(l),cYear:b,cMonth:f,cDay:c,gzYear:g,gzMonth:m,gzDay:D,isToday:s,isLeap:o,nWeek:d,ncWeek:\"星期\"+n,isTerm:r,Term:M,astro:p}},lunar2solar:function(b,f,c,e){var e=!!e,t=this.leapMonth(b);this.leapDays(b);if(e&&t!=f)return-1;if(2100==b&&12==f&&1<c||1900==b&&1==f&&c<31)return-1;var a=this.monthDays(b,f),t=a;if(e&&(t=this.leapDays(b,f)),b<1900||2100<b||t<c)return-1;for(var r=0,s=1900;s<b;s++)r+=this.lYearDays(s);for(var d,n=!1,s=1;s<f;s++)d=this.leapMonth(b),n||d<=s&&0<d&&(r+=this.leapDays(b),n=!0),r+=this.monthDays(b,s);e&&(r+=a);e=Date.UTC(1900,1,30,0,0,0),a=new Date(864e5*(r+c-31)+e),c=a.getUTCFullYear(),e=a.getUTCMonth()+1,a=a.getUTCDate();return this.solar2lunar(c,e,a)}};"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/util/canvas-2d.ts",
    "content": "/**\n * 适配 canvas 2d 上下文\n * @param ctx canvas 2d 上下文\n * @returns\n */\nexport function canvas2d(ctx: CanvasRenderingContext2D): UniApp.CanvasContext {\n    return Object.assign(ctx, {\n        setFillStyle(color: string | CanvasGradient) {\n            ctx.fillStyle = color;\n        },\n        setStrokeStyle(color: string | CanvasGradient | CanvasPattern) {\n            ctx.strokeStyle = color;\n        },\n        setLineWidth(lineWidth: number) {\n            ctx.lineWidth = lineWidth;\n        },\n        setLineCap(lineCap: 'butt' | 'round' | 'square') {\n            ctx.lineCap = lineCap;\n        },\n\n        setFontSize(font: string) {\n            ctx.font = font;\n        },\n        setGlobalAlpha(alpha: number) {\n            ctx.globalAlpha = alpha;\n        },\n        setLineJoin(lineJoin: 'bevel' | 'round' | 'miter') {\n            ctx.lineJoin = lineJoin;\n        },\n        setTextAlign(align: 'left' | 'center' | 'right') {\n            ctx.textAlign = align;\n        },\n        setMiterLimit(miterLimit: number) {\n            ctx.miterLimit = miterLimit;\n        },\n        setShadow(offsetX: number, offsetY: number, blur: number, color: string) {\n            ctx.shadowOffsetX = offsetX;\n            ctx.shadowOffsetY = offsetY;\n            ctx.shadowBlur = blur;\n            ctx.shadowColor = color;\n        },\n        setTextBaseline(textBaseline: 'top' | 'bottom' | 'middle') {\n            ctx.textBaseline = textBaseline;\n        },\n        createCircularGradient() {},\n        draw() {},\n        addColorStop() {}\n    }) as unknown as UniApp.CanvasContext;\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/util/city.ts",
    "content": "export default [[{label:\"市辖区\",value:\"1101\"}],[{label:\"市辖区\",value:\"1201\"}],[{label:\"石家庄市\",value:\"1301\"},{label:\"唐山市\",value:\"1302\"},{label:\"秦皇岛市\",value:\"1303\"},{label:\"邯郸市\",value:\"1304\"},{label:\"邢台市\",value:\"1305\"},{label:\"保定市\",value:\"1306\"},{label:\"张家口市\",value:\"1307\"},{label:\"承德市\",value:\"1308\"},{label:\"沧州市\",value:\"1309\"},{label:\"廊坊市\",value:\"1310\"},{label:\"衡水市\",value:\"1311\"}],[{label:\"太原市\",value:\"1401\"},{label:\"大同市\",value:\"1402\"},{label:\"阳泉市\",value:\"1403\"},{label:\"长治市\",value:\"1404\"},{label:\"晋城市\",value:\"1405\"},{label:\"朔州市\",value:\"1406\"},{label:\"晋中市\",value:\"1407\"},{label:\"运城市\",value:\"1408\"},{label:\"忻州市\",value:\"1409\"},{label:\"临汾市\",value:\"1410\"},{label:\"吕梁市\",value:\"1411\"}],[{label:\"呼和浩特市\",value:\"1501\"},{label:\"包头市\",value:\"1502\"},{label:\"乌海市\",value:\"1503\"},{label:\"赤峰市\",value:\"1504\"},{label:\"通辽市\",value:\"1505\"},{label:\"鄂尔多斯市\",value:\"1506\"},{label:\"呼伦贝尔市\",value:\"1507\"},{label:\"巴彦淖尔市\",value:\"1508\"},{label:\"乌兰察布市\",value:\"1509\"},{label:\"兴安盟\",value:\"1522\"},{label:\"锡林郭勒盟\",value:\"1525\"},{label:\"阿拉善盟\",value:\"1529\"}],[{label:\"沈阳市\",value:\"2101\"},{label:\"大连市\",value:\"2102\"},{label:\"鞍山市\",value:\"2103\"},{label:\"抚顺市\",value:\"2104\"},{label:\"本溪市\",value:\"2105\"},{label:\"丹东市\",value:\"2106\"},{label:\"锦州市\",value:\"2107\"},{label:\"营口市\",value:\"2108\"},{label:\"阜新市\",value:\"2109\"},{label:\"辽阳市\",value:\"2110\"},{label:\"盘锦市\",value:\"2111\"},{label:\"铁岭市\",value:\"2112\"},{label:\"朝阳市\",value:\"2113\"},{label:\"葫芦岛市\",value:\"2114\"}],[{label:\"长春市\",value:\"2201\"},{label:\"吉林市\",value:\"2202\"},{label:\"四平市\",value:\"2203\"},{label:\"辽源市\",value:\"2204\"},{label:\"通化市\",value:\"2205\"},{label:\"白山市\",value:\"2206\"},{label:\"松原市\",value:\"2207\"},{label:\"白城市\",value:\"2208\"},{label:\"延边朝鲜族自治州\",value:\"2224\"}],[{label:\"哈尔滨市\",value:\"2301\"},{label:\"齐齐哈尔市\",value:\"2302\"},{label:\"鸡西市\",value:\"2303\"},{label:\"鹤岗市\",value:\"2304\"},{label:\"双鸭山市\",value:\"2305\"},{label:\"大庆市\",value:\"2306\"},{label:\"伊春市\",value:\"2307\"},{label:\"佳木斯市\",value:\"2308\"},{label:\"七台河市\",value:\"2309\"},{label:\"牡丹江市\",value:\"2310\"},{label:\"黑河市\",value:\"2311\"},{label:\"绥化市\",value:\"2312\"},{label:\"大兴安岭地区\",value:\"2327\"}],[{label:\"市辖区\",value:\"3101\"}],[{label:\"南京市\",value:\"3201\"},{label:\"无锡市\",value:\"3202\"},{label:\"徐州市\",value:\"3203\"},{label:\"常州市\",value:\"3204\"},{label:\"苏州市\",value:\"3205\"},{label:\"南通市\",value:\"3206\"},{label:\"连云港市\",value:\"3207\"},{label:\"淮安市\",value:\"3208\"},{label:\"盐城市\",value:\"3209\"},{label:\"扬州市\",value:\"3210\"},{label:\"镇江市\",value:\"3211\"},{label:\"泰州市\",value:\"3212\"},{label:\"宿迁市\",value:\"3213\"}],[{label:\"杭州市\",value:\"3301\"},{label:\"宁波市\",value:\"3302\"},{label:\"温州市\",value:\"3303\"},{label:\"嘉兴市\",value:\"3304\"},{label:\"湖州市\",value:\"3305\"},{label:\"绍兴市\",value:\"3306\"},{label:\"金华市\",value:\"3307\"},{label:\"衢州市\",value:\"3308\"},{label:\"舟山市\",value:\"3309\"},{label:\"台州市\",value:\"3310\"},{label:\"丽水市\",value:\"3311\"}],[{label:\"合肥市\",value:\"3401\"},{label:\"芜湖市\",value:\"3402\"},{label:\"蚌埠市\",value:\"3403\"},{label:\"淮南市\",value:\"3404\"},{label:\"马鞍山市\",value:\"3405\"},{label:\"淮北市\",value:\"3406\"},{label:\"铜陵市\",value:\"3407\"},{label:\"安庆市\",value:\"3408\"},{label:\"黄山市\",value:\"3410\"},{label:\"滁州市\",value:\"3411\"},{label:\"阜阳市\",value:\"3412\"},{label:\"宿州市\",value:\"3413\"},{label:\"六安市\",value:\"3415\"},{label:\"亳州市\",value:\"3416\"},{label:\"池州市\",value:\"3417\"},{label:\"宣城市\",value:\"3418\"}],[{label:\"福州市\",value:\"3501\"},{label:\"厦门市\",value:\"3502\"},{label:\"莆田市\",value:\"3503\"},{label:\"三明市\",value:\"3504\"},{label:\"泉州市\",value:\"3505\"},{label:\"漳州市\",value:\"3506\"},{label:\"南平市\",value:\"3507\"},{label:\"龙岩市\",value:\"3508\"},{label:\"宁德市\",value:\"3509\"}],[{label:\"南昌市\",value:\"3601\"},{label:\"景德镇市\",value:\"3602\"},{label:\"萍乡市\",value:\"3603\"},{label:\"九江市\",value:\"3604\"},{label:\"新余市\",value:\"3605\"},{label:\"鹰潭市\",value:\"3606\"},{label:\"赣州市\",value:\"3607\"},{label:\"吉安市\",value:\"3608\"},{label:\"宜春市\",value:\"3609\"},{label:\"抚州市\",value:\"3610\"},{label:\"上饶市\",value:\"3611\"}],[{label:\"济南市\",value:\"3701\"},{label:\"青岛市\",value:\"3702\"},{label:\"淄博市\",value:\"3703\"},{label:\"枣庄市\",value:\"3704\"},{label:\"东营市\",value:\"3705\"},{label:\"烟台市\",value:\"3706\"},{label:\"潍坊市\",value:\"3707\"},{label:\"济宁市\",value:\"3708\"},{label:\"泰安市\",value:\"3709\"},{label:\"威海市\",value:\"3710\"},{label:\"日照市\",value:\"3711\"},{label:\"莱芜市\",value:\"3712\"},{label:\"临沂市\",value:\"3713\"},{label:\"德州市\",value:\"3714\"},{label:\"聊城市\",value:\"3715\"},{label:\"滨州市\",value:\"3716\"},{label:\"菏泽市\",value:\"3717\"}],[{label:\"郑州市\",value:\"4101\"},{label:\"开封市\",value:\"4102\"},{label:\"洛阳市\",value:\"4103\"},{label:\"平顶山市\",value:\"4104\"},{label:\"安阳市\",value:\"4105\"},{label:\"鹤壁市\",value:\"4106\"},{label:\"新乡市\",value:\"4107\"},{label:\"焦作市\",value:\"4108\"},{label:\"濮阳市\",value:\"4109\"},{label:\"许昌市\",value:\"4110\"},{label:\"漯河市\",value:\"4111\"},{label:\"三门峡市\",value:\"4112\"},{label:\"南阳市\",value:\"4113\"},{label:\"商丘市\",value:\"4114\"},{label:\"信阳市\",value:\"4115\"},{label:\"周口市\",value:\"4116\"},{label:\"驻马店市\",value:\"4117\"},{label:\"省直辖县级行政区划\",value:\"4190\"}],[{label:\"武汉市\",value:\"4201\"},{label:\"黄石市\",value:\"4202\"},{label:\"十堰市\",value:\"4203\"},{label:\"宜昌市\",value:\"4205\"},{label:\"襄阳市\",value:\"4206\"},{label:\"鄂州市\",value:\"4207\"},{label:\"荆门市\",value:\"4208\"},{label:\"孝感市\",value:\"4209\"},{label:\"荆州市\",value:\"4210\"},{label:\"黄冈市\",value:\"4211\"},{label:\"咸宁市\",value:\"4212\"},{label:\"随州市\",value:\"4213\"},{label:\"恩施土家族苗族自治州\",value:\"4228\"},{label:\"省直辖县级行政区划\",value:\"4290\"}],[{label:\"长沙市\",value:\"4301\"},{label:\"株洲市\",value:\"4302\"},{label:\"湘潭市\",value:\"4303\"},{label:\"衡阳市\",value:\"4304\"},{label:\"邵阳市\",value:\"4305\"},{label:\"岳阳市\",value:\"4306\"},{label:\"常德市\",value:\"4307\"},{label:\"张家界市\",value:\"4308\"},{label:\"益阳市\",value:\"4309\"},{label:\"郴州市\",value:\"4310\"},{label:\"永州市\",value:\"4311\"},{label:\"怀化市\",value:\"4312\"},{label:\"娄底市\",value:\"4313\"},{label:\"湘西土家族苗族自治州\",value:\"4331\"}],[{label:\"广州市\",value:\"4401\"},{label:\"韶关市\",value:\"4402\"},{label:\"深圳市\",value:\"4403\"},{label:\"珠海市\",value:\"4404\"},{label:\"汕头市\",value:\"4405\"},{label:\"佛山市\",value:\"4406\"},{label:\"江门市\",value:\"4407\"},{label:\"湛江市\",value:\"4408\"},{label:\"茂名市\",value:\"4409\"},{label:\"肇庆市\",value:\"4412\"},{label:\"惠州市\",value:\"4413\"},{label:\"梅州市\",value:\"4414\"},{label:\"汕尾市\",value:\"4415\"},{label:\"河源市\",value:\"4416\"},{label:\"阳江市\",value:\"4417\"},{label:\"清远市\",value:\"4418\"},{label:\"东莞市\",value:\"4419\"},{label:\"中山市\",value:\"4420\"},{label:\"潮州市\",value:\"4451\"},{label:\"揭阳市\",value:\"4452\"},{label:\"云浮市\",value:\"4453\"}],[{label:\"南宁市\",value:\"4501\"},{label:\"柳州市\",value:\"4502\"},{label:\"桂林市\",value:\"4503\"},{label:\"梧州市\",value:\"4504\"},{label:\"北海市\",value:\"4505\"},{label:\"防城港市\",value:\"4506\"},{label:\"钦州市\",value:\"4507\"},{label:\"贵港市\",value:\"4508\"},{label:\"玉林市\",value:\"4509\"},{label:\"百色市\",value:\"4510\"},{label:\"贺州市\",value:\"4511\"},{label:\"河池市\",value:\"4512\"},{label:\"来宾市\",value:\"4513\"},{label:\"崇左市\",value:\"4514\"}],[{label:\"海口市\",value:\"4601\"},{label:\"三亚市\",value:\"4602\"},{label:\"三沙市\",value:\"4603\"},{label:\"儋州市\",value:\"4604\"},{label:\"省直辖县级行政区划\",value:\"4690\"}],[{label:\"市辖区\",value:\"5001\"},{label:\"县\",value:\"5002\"}],[{label:\"成都市\",value:\"5101\"},{label:\"自贡市\",value:\"5103\"},{label:\"攀枝花市\",value:\"5104\"},{label:\"泸州市\",value:\"5105\"},{label:\"德阳市\",value:\"5106\"},{label:\"绵阳市\",value:\"5107\"},{label:\"广元市\",value:\"5108\"},{label:\"遂宁市\",value:\"5109\"},{label:\"内江市\",value:\"5110\"},{label:\"乐山市\",value:\"5111\"},{label:\"南充市\",value:\"5113\"},{label:\"眉山市\",value:\"5114\"},{label:\"宜宾市\",value:\"5115\"},{label:\"广安市\",value:\"5116\"},{label:\"达州市\",value:\"5117\"},{label:\"雅安市\",value:\"5118\"},{label:\"巴中市\",value:\"5119\"},{label:\"资阳市\",value:\"5120\"},{label:\"阿坝藏族羌族自治州\",value:\"5132\"},{label:\"甘孜藏族自治州\",value:\"5133\"},{label:\"凉山彝族自治州\",value:\"5134\"}],[{label:\"贵阳市\",value:\"5201\"},{label:\"六盘水市\",value:\"5202\"},{label:\"遵义市\",value:\"5203\"},{label:\"安顺市\",value:\"5204\"},{label:\"毕节市\",value:\"5205\"},{label:\"铜仁市\",value:\"5206\"},{label:\"黔西南布依族苗族自治州\",value:\"5223\"},{label:\"黔东南苗族侗族自治州\",value:\"5226\"},{label:\"黔南布依族苗族自治州\",value:\"5227\"}],[{label:\"昆明市\",value:\"5301\"},{label:\"曲靖市\",value:\"5303\"},{label:\"玉溪市\",value:\"5304\"},{label:\"保山市\",value:\"5305\"},{label:\"昭通市\",value:\"5306\"},{label:\"丽江市\",value:\"5307\"},{label:\"普洱市\",value:\"5308\"},{label:\"临沧市\",value:\"5309\"},{label:\"楚雄彝族自治州\",value:\"5323\"},{label:\"红河哈尼族彝族自治州\",value:\"5325\"},{label:\"文山壮族苗族自治州\",value:\"5326\"},{label:\"西双版纳傣族自治州\",value:\"5328\"},{label:\"大理白族自治州\",value:\"5329\"},{label:\"德宏傣族景颇族自治州\",value:\"5331\"},{label:\"怒江傈僳族自治州\",value:\"5333\"},{label:\"迪庆藏族自治州\",value:\"5334\"}],[{label:\"拉萨市\",value:\"5401\"},{label:\"日喀则市\",value:\"5402\"},{label:\"昌都市\",value:\"5403\"},{label:\"林芝市\",value:\"5404\"},{label:\"山南市\",value:\"5405\"},{label:\"那曲地区\",value:\"5424\"},{label:\"阿里地区\",value:\"5425\"}],[{label:\"西安市\",value:\"6101\"},{label:\"铜川市\",value:\"6102\"},{label:\"宝鸡市\",value:\"6103\"},{label:\"咸阳市\",value:\"6104\"},{label:\"渭南市\",value:\"6105\"},{label:\"延安市\",value:\"6106\"},{label:\"汉中市\",value:\"6107\"},{label:\"榆林市\",value:\"6108\"},{label:\"安康市\",value:\"6109\"},{label:\"商洛市\",value:\"6110\"}],[{label:\"兰州市\",value:\"6201\"},{label:\"嘉峪关市\",value:\"6202\"},{label:\"金昌市\",value:\"6203\"},{label:\"白银市\",value:\"6204\"},{label:\"天水市\",value:\"6205\"},{label:\"武威市\",value:\"6206\"},{label:\"张掖市\",value:\"6207\"},{label:\"平凉市\",value:\"6208\"},{label:\"酒泉市\",value:\"6209\"},{label:\"庆阳市\",value:\"6210\"},{label:\"定西市\",value:\"6211\"},{label:\"陇南市\",value:\"6212\"},{label:\"临夏回族自治州\",value:\"6229\"},{label:\"甘南藏族自治州\",value:\"6230\"}],[{label:\"西宁市\",value:\"6301\"},{label:\"海东市\",value:\"6302\"},{label:\"海北藏族自治州\",value:\"6322\"},{label:\"黄南藏族自治州\",value:\"6323\"},{label:\"海南藏族自治州\",value:\"6325\"},{label:\"果洛藏族自治州\",value:\"6326\"},{label:\"玉树藏族自治州\",value:\"6327\"},{label:\"海西蒙古族藏族自治州\",value:\"6328\"}],[{label:\"银川市\",value:\"6401\"},{label:\"石嘴山市\",value:\"6402\"},{label:\"吴忠市\",value:\"6403\"},{label:\"固原市\",value:\"6404\"},{label:\"中卫市\",value:\"6405\"}],[{label:\"乌鲁木齐市\",value:\"6501\"},{label:\"克拉玛依市\",value:\"6502\"},{label:\"吐鲁番市\",value:\"6504\"},{label:\"哈密市\",value:\"6505\"},{label:\"昌吉回族自治州\",value:\"6523\"},{label:\"博尔塔拉蒙古自治州\",value:\"6527\"},{label:\"巴音郭楞蒙古自治州\",value:\"6528\"},{label:\"阿克苏地区\",value:\"6529\"},{label:\"克孜勒苏柯尔克孜自治州\",value:\"6530\"},{label:\"喀什地区\",value:\"6531\"},{label:\"和田地区\",value:\"6532\"},{label:\"伊犁哈萨克自治州\",value:\"6540\"},{label:\"塔城地区\",value:\"6542\"},{label:\"阿勒泰地区\",value:\"6543\"},{label:\"自治区直辖县级行政区划\",value:\"6590\"}],[{label:\"台北\",value:\"6601\"},{label:\"高雄\",value:\"6602\"},{label:\"基隆\",value:\"6603\"},{label:\"台中\",value:\"6604\"},{label:\"台南\",value:\"6605\"},{label:\"新竹\",value:\"6606\"},{label:\"嘉义\",value:\"6607\"},{label:\"宜兰\",value:\"6608\"},{label:\"桃园\",value:\"6609\"},{label:\"苗栗\",value:\"6610\"},{label:\"彰化\",value:\"6611\"},{label:\"南投\",value:\"6612\"},{label:\"云林\",value:\"6613\"},{label:\"屏东\",value:\"6614\"},{label:\"台东\",value:\"6615\"},{label:\"花莲\",value:\"6616\"},{label:\"澎湖\",value:\"6617\"}],[{label:\"香港岛\",value:\"6701\"},{label:\"九龙\",value:\"6702\"},{label:\"新界\",value:\"6703\"}],[{label:\"澳门半岛\",value:\"6801\"},{label:\"氹仔岛\",value:\"6802\"},{label:\"路环岛\",value:\"6803\"},{label:\"路氹城\",value:\"6804\"}]];"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/util/config-provider.ts",
    "content": "// libs/util/config-provider.ts\n\n// 全局配置类：管理 Theme 的初始化、切换、持久化\n\nimport { ref } from 'vue';\nimport type { DarkMode, Theme, ThemeColor } from '../../types/global';\nimport config, { isDebugMode } from '../config/config';\nimport { defaultThemes } from '../config/theme-tokens';\nimport { color as reactiveColor } from '../config/color';\nimport { getSystemDarkMode as getNativeSystemDarkMode } from './system-theme';\nimport * as localePack from '../../locale';\n\ndeclare const uni: any;\n\nconst THEME_STORAGE_KEY = 'uview-pro-theme';\nconst DARK_MODE_STORAGE_KEY = 'uview-pro-dark-mode';\nconst LOCALE_STORAGE_KEY = 'uview-pro-locale';\nconst DEFAULT_LIGHT_TOKENS = (defaultThemes[0]?.color || {}) as Partial<ThemeColor>;\nconst DEFAULT_DARK_TOKENS = (defaultThemes[0]?.darkColor || {}) as Partial<ThemeColor>;\nconst STRUCTURAL_TOKENS = new Set([\n    'bgColor',\n    'bgWhite',\n    'bgGrayLight',\n    'bgGrayDark',\n    'bgBlack',\n    'borderColor',\n    'lightColor',\n    'mainColor',\n    'contentColor',\n    'tipsColor',\n    'whiteColor',\n    'blackColor',\n    'dividerColor',\n    'maskColor',\n    'shadowColor'\n]);\n\nexport type DefaultThemeConfig = {\n    /**\n     * 默认主题\n     */\n    defaultTheme?: string;\n    /**\n     * 默认暗黑模式\n     */\n    defaultDarkMode?: DarkMode;\n};\n\n/**\n * ConfigProvider: 管理全局主题\n * - init(themes, defaultName): 初始化主题系统\n * - setTheme(name): 切换主题并持久化\n * - getThemes/getCurrentTheme: 读取当前数据\n * - setDarkMode/getDarkMode: 管理暗黑模式\n */\nexport class ConfigProvider {\n    // 响应式状态，供外部直接引用\n    public themesRef = ref<Theme[]>([]);\n    public currentThemeRef = ref<Theme | null>(null);\n    public darkModeRef = ref<DarkMode>(config.defaultDarkMode);\n    public cssVarsRef = ref<Record<string, string>>({});\n    // 国际化 i18n 状态\n    public localesRef = ref<any[]>([]);\n    public currentLocaleRef = ref<any | null>(null);\n    private baseColorTokens: Partial<ThemeColor> = DEFAULT_LIGHT_TOKENS;\n    private baseDarkColorTokens: Partial<ThemeColor> = DEFAULT_DARK_TOKENS;\n    private systemDarkModeMediaQuery: MediaQueryList | null = null;\n    private lastAppliedCssKeys: string[] = [];\n    private interval: ReturnType<typeof setInterval> | number = 0;\n\n    constructor() {\n        // 默认不自动初始化，调用 init 以传入主题列表\n        this.initSystemDarkModeListener();\n    }\n\n    /**\n     * 初始化系统暗黑模式监听器\n     * 支持 H5、App、小程序等平台\n     */\n    private initSystemDarkModeListener() {\n        // H5 平台：使用 matchMedia API\n        try {\n            if (typeof window !== 'undefined' && window.matchMedia) {\n                this.systemDarkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n                const listener = () => {\n                    if (this.darkModeRef.value === 'auto') {\n                        this.applyTheme(this.currentThemeRef.value);\n                    }\n                };\n                if (this.systemDarkModeMediaQuery.addEventListener) {\n                    this.systemDarkModeMediaQuery.addEventListener('change', listener);\n                } else if (this.systemDarkModeMediaQuery.addListener) {\n                    this.systemDarkModeMediaQuery.addListener(listener);\n                }\n            }\n        } catch (e) {\n            if (isDebugMode('error')) console.error('[ConfigProvider] H5 system dark mode listener failed', e);\n        }\n\n        // uni-app 平台：使用 uni.onThemeChange API\n        try {\n            if (typeof uni !== 'undefined' && typeof uni.onThemeChange === 'function') {\n                uni.onThemeChange((res: { theme: string }) => {\n                    console.log('[ConfigProvider] system theme changed', res);\n                    if (this.darkModeRef.value === 'auto') {\n                        // 系统主题变化时，重新应用主题\n                        this.applyTheme(this.currentThemeRef.value);\n                    }\n                });\n            }\n        } catch (e) {\n            if (isDebugMode('error')) console.error('[ConfigProvider] uni-app system dark mode listener failed', e);\n        }\n        this.initAppEvent();\n    }\n\n    /**\n     * App 平台事件监听\n     * 经测试 uni.onThemeChange 在 App 平台目前没生效，暂时只能通过定时检查\n     */\n    private initAppEvent(): void {\n        // #ifdef APP\n        try {\n            if (this.interval) clearInterval(this.interval);\n\n            this.interval = setInterval(() => {\n                if (this.darkModeRef.value === 'auto') {\n                    // 系统主题变化时，重新应用主题\n                    this.applyTheme(this.currentThemeRef.value);\n                }\n            }, 5000);\n        } catch (e) {\n            if (isDebugMode('error')) console.error('[ConfigProvider] setInterval failed', e);\n        }\n        // #endif\n    }\n    /**\n     * 检测当前是否应该使用暗黑模式\n     */\n    private isSystemDarkMode(): boolean {\n        try {\n            if (this.systemDarkModeMediaQuery) {\n                return this.systemDarkModeMediaQuery.matches;\n            }\n        } catch (e) {\n            if (isDebugMode('error')) console.error('[ConfigProvider] matchMedia check failed', e);\n        }\n        try {\n            return getNativeSystemDarkMode() === 'dark';\n        } catch (e) {\n            if (isDebugMode('error')) console.error('[ConfigProvider] native system theme check failed', e);\n            return false;\n        }\n    }\n\n    /**\n     * 初始化主题系统\n     * @param themes 可用主题数组\n     * @param defaultTheme 可选默认主题名\n     */\n    initTheme(themes?: Theme[], defaultConfig?: string | DefaultThemeConfig, isForce?: boolean) {\n        const normalizedThemes = this.normalizeThemes(themes);\n        if (!normalizedThemes.length) {\n            if (isDebugMode('warn')) console.warn('[ConfigProvider] init called with empty themes');\n            return;\n        }\n\n        // 配置默认主题\n        if (defaultConfig) {\n            if (typeof defaultConfig === 'string') {\n                config.defaultTheme = defaultConfig || config.defaultTheme;\n            } else if (typeof defaultConfig === 'object') {\n                const { defaultTheme, defaultDarkMode } = defaultConfig;\n                config.defaultTheme = defaultTheme || config.defaultTheme;\n                config.defaultDarkMode = defaultDarkMode || config.defaultDarkMode;\n            }\n        }\n\n        // 设置主题列表，响应式\n        this.themesRef.value = normalizedThemes.slice();\n\n        // 先尝试从 Storage 读取已保存主题名\n        const saved = this.readStorage<string>(THEME_STORAGE_KEY);\n        let initialName = saved || config.defaultTheme || this.themesRef.value[0].name;\n        if (isForce && config.defaultTheme) initialName = config.defaultTheme;\n        let found = this.themesRef.value.find(t => t.name === initialName);\n        if (!found) found = this.themesRef.value.find(t => t.name === config.defaultTheme);\n        if (!found) found = this.themesRef.value[0];\n\n        // 设置当前主题，响应式\n        this.currentThemeRef.value = found;\n\n        // 初始化暗黑模式设置\n        this.initDarkMode(config.defaultDarkMode, isForce);\n\n        // 应用主题\n        this.applyTheme(found);\n\n        if (isDebugMode())\n            console.log('[ConfigProvider] initialized, theme=', found.name, 'darkMode=', this.darkModeRef.value);\n\n        return this;\n    }\n\n    /**\n     * 初始化暗黑模式设置\n     * @param darkMode\n     */\n    initDarkMode(darkMode?: DarkMode, isForce?: boolean) {\n        // 尝试从 Storage 读取暗黑模式设置\n        const savedDarkMode = this.readStorage<DarkMode>(DARK_MODE_STORAGE_KEY);\n        let darkModeValue = savedDarkMode || darkMode || config.defaultDarkMode;\n        if (isForce && darkMode) darkModeValue = darkMode;\n        this.darkModeRef.value = darkModeValue;\n    }\n\n    /**\n     * 初始化国际化数据\n     * @param locales 可选的 locale 列表（对象数组，包含 name 字段）\n     * @param defaultLocaleName 可选默认 locale 名称\n     */\n    initLocales(locales?: any[], defaultLocaleName?: string, isForce?: boolean) {\n        const normalized = this.normalizeLocales(locales);\n        if (!normalized.length) {\n            if (isDebugMode('warn')) console.warn('[ConfigProvider] initLocales called with empty locales');\n            return;\n        }\n\n        this.localesRef.value = normalized.slice();\n\n        // 尝试从 Storage 读取已保存 locale 名称\n        const saved = this.readStorage<string>(LOCALE_STORAGE_KEY);\n\n        // 根据传入的 defaultLocaleName 或 saved 或 config.defaultLocale 查找 locale\n        let initialName = saved || defaultLocaleName || config.defaultLocale;\n        if (isForce && defaultLocaleName) initialName = defaultLocaleName;\n        let found = this.localesRef.value.find((l: any) => l.name === initialName);\n        if (!found) found = this.localesRef.value.find(l => l.name === config.defaultLocale);\n        if (!found) found = this.localesRef.value[0];\n\n        this.currentLocaleRef.value = found;\n\n        if (isDebugMode()) console.log('[ConfigProvider] locales initialized, locale=', found?.name);\n\n        return this;\n    }\n\n    /**\n     * 归一化 locale 配置，保证始终至少有一个默认 locale\n     */\n    private normalizeLocales(locales?: any[]) {\n        // 获取内置语言包（可能包含 zh-CN / en-US 等）\n        let builtinList: any[] = [];\n        try {\n            builtinList = Object.values(localePack || {}).filter(v => v && typeof v === 'object');\n        } catch (e) {\n            if (isDebugMode('error')) console.error('[ConfigProvider] normalizeLocales read builtin failed', e);\n        }\n\n        // 如果没有传入自定义 locales，直接返回内置列表\n        if (!Array.isArray(locales) || !locales.length) {\n            return builtinList.slice();\n        }\n\n        // 将 builtin 按 name 映射，便于合并\n        const map = new Map<string, any>();\n        builtinList.forEach(item => {\n            if (item && item.name) {\n                map.set(item.name, { ...(item || {}) });\n            }\n        });\n\n        // 合并用户传入的 locales：若 name 相同则对对象字段进行浅合并（嵌套对象尝试合并）\n        locales.forEach(loc => {\n            if (!loc || !loc.name) return;\n            const existing = map.get(loc.name);\n            if (!existing) {\n                // 新增语言直接加入\n                map.set(loc.name, { ...(loc || {}) });\n                return;\n            }\n            // 合并：对每个 key，如果是对象且现有为对象，则进行浅合并，否则覆盖\n            const merged: any = { ...existing };\n            Object.keys(loc).forEach(k => {\n                const v = (loc as any)[k];\n                if (v != null && typeof v === 'object' && !Array.isArray(v) && typeof merged[k] === 'object') {\n                    merged[k] = { ...(merged[k] || {}), ...(v || {}) };\n                } else {\n                    merged[k] = v;\n                }\n            });\n            map.set(loc.name, merged);\n        });\n\n        return Array.from(map.values());\n    }\n\n    /**\n     * 获取所有可用 locale\n     */\n    getLocales() {\n        return this.localesRef.value.slice();\n    }\n\n    /**\n     * 获取当前 locale 对象\n     */\n    getCurrentLocale() {\n        return this.currentLocaleRef.value;\n    }\n\n    /**\n     * 切换 locale 并持久化\n     */\n    setLocale(localeName: string) {\n        if (!this.localesRef.value || this.localesRef.value.length === 0) {\n            if (isDebugMode('warn')) console.warn('[ConfigProvider] setLocale called but locales list empty');\n            return;\n        }\n        const locale = this.localesRef.value.find(l => l.name === localeName);\n        if (!locale) {\n            if (isDebugMode('warn')) console.warn('[ConfigProvider] locale not found:', localeName);\n            return;\n        }\n        this.currentLocaleRef.value = locale;\n        this.writeStorage(LOCALE_STORAGE_KEY, localeName);\n        if (isDebugMode()) console.log('[ConfigProvider] setLocale ->', localeName);\n    }\n\n    /**\n     * 翻译函数\n     * 支持 key 路径，例如 'calendar.placeholder'\n     * replacements 支持数组或对象替换占位符 {0} 或 {name}\n     */\n    t(key: string, replacements?: any, localeName?: string): string {\n        // 如果 locales 尚未初始化，尝试懒初始化，使用内置语言包作为回退\n        try {\n            if (!Array.isArray(this.localesRef.value) || this.localesRef.value.length === 0) {\n                this.initLocales();\n            }\n        } catch (e) {\n            if (isDebugMode('error')) console.error('[ConfigProvider] lazy initLocales failed', e);\n        }\n\n        const localeObj =\n            (localeName && this.localesRef.value.find(l => l.name === localeName)) || this.currentLocaleRef.value;\n        if (!localeObj) return key;\n        const parts = key.split('.');\n        let cur: any = localeObj;\n        for (let i = 0; i < parts.length; i++) {\n            if (cur == null) break;\n            cur = cur[parts[i]];\n        }\n        let text = typeof cur === 'string' ? cur : key;\n        if (replacements != null) {\n            if (Array.isArray(replacements)) {\n                replacements.forEach((val, idx) => {\n                    text = text.split(`{${idx}}`).join(String(val));\n                });\n            } else if (typeof replacements === 'object') {\n                Object.keys(replacements).forEach(k => {\n                    text = text.split(`{${k}}`).join(String(replacements[k]));\n                });\n            }\n        }\n        return text;\n    }\n\n    /**\n     * 获取所有可用主题\n     */\n    getThemes(): Theme[] {\n        return this.themesRef.value.slice();\n    }\n\n    /**\n     * 获取当前主题\n     */\n    getCurrentTheme(): Theme | null {\n        return this.currentThemeRef.value;\n    }\n\n    /**\n     * 切换主题并持久化\n     */\n    setTheme(themeName: string) {\n        if (!this.themesRef.value || this.themesRef.value.length === 0) {\n            if (isDebugMode('warn')) console.warn('[ConfigProvider] setTheme called but themes list empty');\n            return;\n        }\n\n        const theme = this.themesRef.value.find(t => t.name === themeName);\n        if (!theme) {\n            if (isDebugMode('warn')) console.warn('[ConfigProvider] theme not found:', themeName);\n            return;\n        }\n\n        this.currentThemeRef.value = theme;\n\n        // 应用\n        this.applyTheme(theme);\n\n        // 持久化\n        this.writeStorage(THEME_STORAGE_KEY, themeName);\n\n        if (isDebugMode()) console.log('[ConfigProvider] setTheme ->', themeName);\n    }\n\n    /**\n     * 运行时更新当前主题颜色并应用（不持久化）\n     * @param colors 主题颜色键值，支持部分更新\n     */\n    public setThemeColor(colors: Partial<ThemeColor>) {\n        if (!colors || Object.keys(colors).length === 0) return;\n        if (!this.currentThemeRef.value) {\n            if (isDebugMode('warn')) console.warn('[ConfigProvider] setThemeColor called but no current theme');\n            return;\n        }\n\n        const mode = this.getActiveMode();\n\n        if (mode === 'dark') {\n            const existing = this.currentThemeRef.value.darkColor || {};\n            this.currentThemeRef.value.darkColor = {\n                ...existing,\n                ...colors\n            };\n        } else {\n            const existing = this.currentThemeRef.value.color || {};\n            this.currentThemeRef.value.color = {\n                ...existing,\n                ...colors\n            };\n        }\n\n        // 重新应用当前主题以同步运行时 color、CSS 变量等\n        this.applyTheme(this.currentThemeRef.value);\n\n        if (isDebugMode()) console.log('[ConfigProvider] setThemeColor ->', colors);\n    }\n\n    /**\n     * 获取当前暗黑模式设置\n     */\n    getDarkMode(): DarkMode {\n        return this.darkModeRef.value;\n    }\n\n    /**\n     * 设置暗黑模式\n     * @param mode 'auto' (跟随系统) | 'light' (强制亮色) | 'dark' (强制暗黑)\n     */\n    setDarkMode(mode: DarkMode) {\n        this.darkModeRef.value = mode;\n        // 持久化\n        this.writeStorage(DARK_MODE_STORAGE_KEY, mode);\n\n        // 重新应用主题\n        this.applyTheme(this.currentThemeRef.value);\n\n        if (isDebugMode()) console.log('[ConfigProvider] setDarkMode ->', mode);\n    }\n\n    /**\n     * 检查当前是否处于暗黑模式\n     */\n    isInDarkMode(): boolean {\n        const mode = this.darkModeRef.value;\n        if (mode === 'dark') return true;\n        if (mode === 'light') return false;\n        // auto 模式下检查系统设置\n        return this.isSystemDarkMode();\n    }\n\n    /**\n     * 归一化主题配置，保证始终至少有一个默认主题\n     */\n    private normalizeThemes(themes?: Theme[]): Theme[] {\n        if (Array.isArray(themes) && themes.length) {\n            return this.mergeThemes(defaultThemes, themes);\n        }\n        return defaultThemes.slice();\n    }\n\n    private mergeThemes(...lists: Array<Theme[] | undefined>): Theme[] {\n        const map = new Map<string, Theme>();\n        lists\n            .filter((list): list is Theme[] => Array.isArray(list) && list.length > 0)\n            .forEach(list => {\n                list.forEach(theme => {\n                    const normalized = this.ensureDarkVariant({\n                        ...theme,\n                        color: this.applyColorFallbacks(theme.color),\n                        darkColor: theme.darkColor ? { ...theme.darkColor } : undefined,\n                        css: theme.css ? { ...theme.css } : undefined,\n                        darkCss: theme.darkCss ? { ...theme.darkCss } : undefined\n                    });\n                    map.set(normalized.name, normalized);\n                });\n            });\n        return Array.from(map.values());\n    }\n\n    private ensureDarkVariant(theme: Theme): Theme {\n        const finalDark = this.buildDarkPalette(theme);\n        return {\n            ...theme,\n            darkColor: this.applyDarkFallbacks(finalDark)\n        };\n    }\n\n    private buildDarkPalette(theme: Theme): Partial<ThemeColor> {\n        const provided = theme.darkColor || {};\n        const generated = this.generateDarkFromLight(theme.color || {}, provided);\n        return {\n            ...generated,\n            ...provided\n        };\n    }\n\n    /**\n     * 应用亮色主题\n     */\n    private applyColorFallbacks(color?: Partial<ThemeColor>): Partial<ThemeColor> {\n        return {\n            ...(this.baseColorTokens || {}),\n            ...(color || {})\n        };\n    }\n\n    /**\n     * 应用暗黑主题\n     */\n    private applyDarkFallbacks(color?: Partial<ThemeColor>): Partial<ThemeColor> {\n        return {\n            ...(this.baseDarkColorTokens || {}),\n            ...(color || {})\n        };\n    }\n\n    private filterNonStructuralTokens(palette: Partial<ThemeColor>): Partial<ThemeColor> {\n        const result: Partial<ThemeColor> = {};\n        Object.entries(palette || {}).forEach(([key, value]) => {\n            if (!this.isStructuralToken(key)) {\n                (result as any)[key] = value;\n            }\n        });\n        return result;\n    }\n\n    private generateDarkFromLight(palette: Partial<ThemeColor>, provided: Partial<ThemeColor>): Partial<ThemeColor> {\n        const result: Partial<ThemeColor> = {};\n        const nonStructural = this.filterNonStructuralTokens(palette);\n        Object.entries(nonStructural).forEach(([key, value]) => {\n            if (typeof value !== 'string') return;\n            if (provided && Object.prototype.hasOwnProperty.call(provided, key)) {\n                return;\n            }\n            const fallback = (this.baseDarkColorTokens as any)?.[key];\n            (result as any)[key] = this.createDarkVariantFromLight(value, fallback);\n        });\n        return result;\n    }\n\n    private createDarkVariantFromLight(color: string, fallback?: string): string {\n        const normalized = this.normalizeHex(color);\n        const fallbackHex = fallback ? this.normalizeHex(fallback) : null;\n        if (normalized && fallbackHex) {\n            return this.mixHex(normalized, fallbackHex, 0.6);\n        }\n        if (fallbackHex) return fallbackHex;\n        return normalized || color;\n    }\n\n    private normalizeHex(color: string): string | null {\n        if (!color) return null;\n        const hex = color.trim();\n        if (/^#([0-9a-fA-F]{6})$/.test(hex)) return hex.toLowerCase();\n        return null;\n    }\n\n    private mixHex(fromHex: string, toHex: string, ratio: number): string {\n        const from = this.hexToRgb(fromHex);\n        const to = this.hexToRgb(toHex);\n        if (!from || !to) return toHex;\n        const clamp = (val: number) => Math.min(255, Math.max(0, Math.round(val)));\n        const r = clamp(from.r * (1 - ratio) + to.r * ratio);\n        const g = clamp(from.g * (1 - ratio) + to.g * ratio);\n        const b = clamp(from.b * (1 - ratio) + to.b * ratio);\n        return this.rgbToHex(r, g, b);\n    }\n\n    private hexToRgb(hex: string): { r: number; g: number; b: number } | null {\n        const match = /^#([0-9a-fA-F]{6})$/.exec(hex);\n        if (!match) return null;\n        return {\n            r: parseInt(match[1].slice(0, 2), 16),\n            g: parseInt(match[1].slice(2, 4), 16),\n            b: parseInt(match[1].slice(4, 6), 16)\n        };\n    }\n\n    private rgbToHex(r: number, g: number, b: number): string {\n        const toHex = (val: number) => val.toString(16).padStart(2, '0');\n        return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\n    }\n\n    private isStructuralToken(token: string): boolean {\n        return STRUCTURAL_TOKENS.has(token);\n    }\n\n    /**\n     * 运行时同步主题颜色（$u.color）\n     * 更新响应式 color 对象，确保所有使用 $u.color 的地方都能响应式更新\n     */\n    private syncRuntimeTheme(palette: Partial<ThemeColor>) {\n        try {\n            // 合并默认值，确保所有颜色都有值\n            const defaultPalette = this.getActiveMode() === 'dark' ? this.baseDarkColorTokens : this.baseColorTokens;\n\n            const mergedPalette = {\n                ...defaultPalette,\n                ...palette\n            };\n\n            // 更新响应式 color 对象\n            Object.keys(mergedPalette).forEach(key => {\n                const value = (mergedPalette as any)[key];\n                if (value != null) {\n                    (reactiveColor as any)[key] = value;\n                }\n            });\n\n            // 同步到 uni.$u.color（如果存在）\n            if (typeof uni !== 'undefined' && uni?.$u?.color) {\n                uni.$u.color = reactiveColor;\n            }\n        } catch (e) {\n            if (isDebugMode('error')) console.error('[ConfigProvider] sync runtime theme failed', e);\n        }\n    }\n\n    /**\n     * 获取当前激活的模式\n     */\n    private getActiveMode(): 'light' | 'dark' {\n        return this.isInDarkMode() ? 'dark' : 'light';\n    }\n\n    /**\n     * 获取当前主题的配色方案\n     */\n    private getPaletteForMode(theme: Theme, mode: 'light' | 'dark') {\n        if (mode === 'dark') {\n            return theme.darkColor && Object.keys(theme.darkColor).length ? theme.darkColor : theme.color || {};\n        }\n        return theme.color || {};\n    }\n\n    /**\n     * 获取当前主题的CSS变量覆盖\n     */\n    private getCssOverrides(theme: Theme, mode: 'light' | 'dark') {\n        if (mode === 'dark') {\n            return (theme.darkCss && Object.keys(theme.darkCss).length ? theme.darkCss : theme.css) || {};\n        }\n        return theme.css || {};\n    }\n\n    /**\n     * 读取Storage key\n     */\n    private readStorage<T>(key: string): T | null {\n        try {\n            if (typeof uni === 'undefined' || typeof uni.getStorageSync !== 'function') return null;\n            const value = uni.getStorageSync(key);\n            return (value ?? null) as T | null;\n        } catch (e) {\n            if (isDebugMode('error')) console.error('[ConfigProvider] failed to read storage', e);\n            return null;\n        }\n    }\n\n    /**\n     * 写入Storage key value\n     */\n    private writeStorage(key: string, value: any) {\n        try {\n            if (typeof uni === 'undefined' || typeof uni.setStorageSync !== 'function') return;\n            uni.setStorageSync(key, value);\n        } catch (e) {\n            if (isDebugMode('error')) console.error('[ConfigProvider] failed to write storage', e);\n        }\n    }\n\n    /**\n     * 更新文档主题模式 H5\n     */\n    private updateDocumentMode(mode: 'light' | 'dark') {\n        if (typeof document === 'undefined' || !document.documentElement) return;\n        const root = document.documentElement;\n        root.dataset.uThemeMode = mode;\n        root.classList.remove('u-theme-light', 'u-theme-dark');\n        root.classList.add(`u-theme-${mode}`);\n    }\n\n    /**\n     * 转换为 CSS 变量名称\n     */\n    private toCssVarName(key: string, prefix: string = '--u'): string {\n        const types = config.type;\n        if (types.some(type => key.startsWith(type))) {\n            prefix += '-type';\n        }\n        const kebab = key\n            .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n            .replace(/[\\s_]+/g, '-')\n            .toLowerCase();\n        return `${prefix}-${kebab}`;\n    }\n\n    /**\n     * 添加 RGB 值\n     */\n    private attachRgbVar(target: Record<string, string>, varName: string, value: string) {\n        if (typeof value !== 'string') return;\n        const hex = value.startsWith('#') ? value.slice(1) : '';\n        if (!/^[0-9a-fA-F]{6}$/.test(hex)) return;\n        const r = parseInt(hex.slice(0, 2), 16);\n        const g = parseInt(hex.slice(2, 4), 16);\n        const b = parseInt(hex.slice(4, 6), 16);\n        target[`${varName}-rgb`] = `${r}, ${g}, ${b}`;\n    }\n\n    /**\n     * 构建 CSS 变量映射表\n     * 生成格式：\n     */\n    private buildCssVarMap(theme: Theme, mode: 'light' | 'dark'): Record<string, string> {\n        const map: Record<string, string> = {\n            '--u-theme-mode': mode\n        };\n        const palette = this.getPaletteForMode(theme, mode);\n        const cssOverrides = this.getCssOverrides(theme, mode);\n\n        const applyEntry = (key: string, value: string | number | undefined | null) => {\n            if (value == null) return;\n            const strValue = String(value);\n            if (key.startsWith('--')) {\n                map[key] = strValue;\n                this.attachRgbVar(map, key, strValue);\n                return;\n            }\n            const cssVarName = this.toCssVarName(key);\n            // const typeVarName = this.toCssVarName(key, '--u-type');\n            map[cssVarName] = strValue;\n            // map[typeVarName] = strValue;\n            this.attachRgbVar(map, cssVarName, strValue);\n            // this.attachRgbVar(map, typeVarName, strValue);\n        };\n\n        Object.entries(palette || {}).forEach(([key, value]) => applyEntry(key, value as any));\n        Object.entries(cssOverrides || {}).forEach(([key, value]) => applyEntry(key, value as any));\n\n        return map;\n    }\n\n    /**\n     * 刷新 CSS 变量 H5\n     */\n    private flushCssVars(vars: Record<string, string>) {\n        if (typeof document === 'undefined' || !document.documentElement) return;\n        const root = document.documentElement;\n        this.lastAppliedCssKeys.forEach(key => {\n            root.style.removeProperty(key);\n        });\n        Object.entries(vars).forEach(([key, value]) => {\n            root.style.setProperty(key, value);\n        });\n        this.lastAppliedCssKeys = Object.keys(vars);\n    }\n\n    /**\n     * 将主题应用到运行时：\n     * - 1) 调用 uni.$u.setColor(theme.color) 如果存在\n     * - 2) 在 H5 环境中，将 css map 注入到 document.documentElement 的 CSS 变量中\n     * - 3) 支持暗黑模式：根据 darkColor 或 color 应用相应的颜色\n     */\n    private applyTheme(theme: Theme | null) {\n        if (!theme) return;\n        const mode = this.getActiveMode();\n        const palette = this.getPaletteForMode(theme, mode);\n        this.syncRuntimeTheme(palette);\n\n        const cssVarMap = this.buildCssVarMap(theme, mode);\n        this.cssVarsRef.value = cssVarMap;\n        this.flushCssVars(cssVarMap);\n        this.updateDocumentMode(mode);\n    }\n}\n\n// 单例导出\nexport const configProvider = new ConfigProvider();\nexport default configProvider;\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/util/emitter.ts",
    "content": "import { getCurrentInstance, type ComponentInternalInstance } from 'vue';\n\n/**\n * 适用于 uni-app Vue3 的事件派发/广播工具\n * 用法：import { dispatch, broadcast } from './emitter'\n */\n\n/**\n * 向上查找父组件并派发事件\n * @param instance 当前组件实例（setup中可用getCurrentInstance()）\n * @param componentName 目标组件名\n * @param eventName 事件名\n * @param params 参数\n */\n\n// 将事件名转换为驼峰格式\n// 例如：on-form-change -> onFormChange\nfunction formatToCamelCase(str: string): string {\n    return str.replace(/-([a-z])/g, function (g) {\n        return g[1].toUpperCase();\n    });\n}\n\n/**\n * 向上查找父组件\n * @param instance 当前组件实例（setup中可用getCurrentInstance()）\n * @param componentName 目标组件名\n * @returns 父组件实例\n */\nfunction parent(instance: ComponentInternalInstance | null | undefined = undefined, componentName: string = '') {\n    if (!instance) {\n        instance = getCurrentInstance();\n    }\n    let parent = instance && (instance.parent as ComponentInternalInstance | null | undefined);\n\n    if (!componentName) return parent;\n    while (parent) {\n        const name = (parent.type as any)?.name as string | undefined;\n        if (name === componentName) {\n            return parent;\n        }\n        parent = parent.parent;\n    }\n    return null;\n}\n\n/** * 向上查找父组件并派发事件\n * @param instance 当前组件实例（setup中可用getCurrentInstance()）\n * @param componentName 目标组件名\n * @param eventName 事件名\n * @param params 参数\n */\nfunction dispatch(\n    instance: ComponentInternalInstance | null | undefined,\n    componentName: string,\n    eventName: string,\n    ...params: any[]\n) {\n    let parent = instance && (instance.parent as ComponentInternalInstance | null | undefined);\n    while (parent) {\n        const name = (parent.type as any)?.name as string | undefined;\n        if (name === componentName) {\n            // 找到目标组件，派发事件\n            // Vue3未解决，目标组件事件监听失效，待优化，暂时使用下面的方式解决，如果你有好的方式也可以告诉我或者提PR\n            parent.emit && parent.emit(eventName, ...params);\n            // 如果有对应的方法，执行方法\n            // 这里可以考虑将 eventName 转换为驼峰格式\n            // 例如：on-form-change -> onFormChange\n            parent.exposed?.[formatToCamelCase(eventName)] && parent.exposed[formatToCamelCase(eventName)](...params);\n            break;\n        }\n        parent = parent.parent;\n    }\n}\n\n/**\n * 向下递归查找子组件并广播事件\n * @param instance 当前组件实例（setup中可用getCurrentInstance()）\n * @param componentName 目标组件名\n * @param eventName 事件名\n * @param params 参数\n */\nfunction broadcast(\n    instance: ComponentInternalInstance | null | undefined,\n    componentName: string,\n    eventName: string,\n    ...params: any[]\n) {\n    if (!instance) return;\n    const subTree = (instance.subTree as any)?.children || [];\n    const children = Array.isArray(subTree) ? subTree : [subTree];\n    children.forEach((vnode: any) => {\n        const child = vnode.component as ComponentInternalInstance | undefined;\n\n        if (child) {\n            const name = (child.type as any)?.name as string | undefined;\n            if (name === componentName) {\n                // 找到目标组件，广播事件\n                // Vue3未解决，目标组件事件监听失效，待优化，暂时使用下面的方式解决，如果你有好的方式也可以告诉我或者提PR\n                child.emit && child.emit(eventName, ...params);\n                // 如果有对应的方法，执行方法\n                // 这里可以考虑将 eventName 转换为驼峰格式\n                // 例如：on-form-change -> onFormChange\n                child.exposed?.[formatToCamelCase(eventName)] && child.exposed[formatToCamelCase(eventName)](...params);\n            } else {\n                broadcast(child, componentName, eventName, ...params);\n            }\n        }\n    });\n}\n\nexport { dispatch, broadcast, parent };\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/util/mitt.ts",
    "content": "/* eslint-disable @typescript-eslint/no-non-null-assertion */\n/**\n * copy to https://github.com/developit/mitt\n * Expand clear method\n */\nexport type EventType = string | symbol;\n\n// An event handler can take an optional event argument\n// and should not return a value\nexport type Handler<T = unknown> = (event: T) => void;\nexport type WildcardHandler<T = Record<string, unknown>> = (type: keyof T, event: T[keyof T]) => void;\n\n// An array of all currently registered event handlers for a type\nexport type EventHandlerList<T = unknown> = Array<Handler<T>>;\nexport type WildCardEventHandlerList<T = Record<string, unknown>> = Array<WildcardHandler<T>>;\n\n// A map of event types and their corresponding event handlers.\nexport type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<\n    '*' | keyof Events,\n    EventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>\n>;\n\nexport interface Emitter<Events extends Record<EventType, unknown>> {\n    all: EventHandlerMap<Events>;\n\n    on<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void;\n    on(type: '*', handler: WildcardHandler<Events>): void;\n\n    off<Key extends keyof Events>(type: Key, handler?: Handler<Events[Key]>): void;\n    off(type: '*', handler: WildcardHandler<Events>): void;\n\n    emit<Key extends keyof Events>(type: Key, event: Events[Key]): void;\n    emit<Key extends keyof Events>(type: undefined extends Events[Key] ? Key : never): void;\n    clear(): void;\n}\n\n/**\n * Mitt: Tiny (~200b) functional event emitter / pubsub.\n * @name mitt\n * @returns {Mitt}\n */\nexport function mitt<Events extends Record<EventType, unknown>>(all?: EventHandlerMap<Events>): Emitter<Events> {\n    type GenericEventHandler = Handler<Events[keyof Events]> | WildcardHandler<Events>;\n    all = all || new Map();\n\n    return {\n        /**\n         * A Map of event names to registered handler functions.\n         */\n        all,\n\n        /**\n         * Register an event handler for the given type.\n         * @param {string|symbol} type Type of event to listen for, or `'*'` for all events\n         * @param {Function} handler Function to call in response to given event\n         * @memberOf mitt\n         */\n        on<Key extends keyof Events>(type: Key, handler: GenericEventHandler) {\n            const handlers: Array<GenericEventHandler> | undefined = all!.get(type);\n            if (handlers) {\n                handlers.push(handler);\n            } else {\n                all!.set(type, [handler] as EventHandlerList<Events[keyof Events]>);\n            }\n        },\n\n        /**\n         * Remove an event handler for the given type.\n         * If `handler` is omitted, all handlers of the given type are removed.\n         * @param {string|symbol} type Type of event to unregister `handler` from (`'*'` to remove a wildcard handler)\n         * @param {Function} [handler] Handler function to remove\n         * @memberOf mitt\n         */\n        off<Key extends keyof Events>(type: Key, handler?: GenericEventHandler) {\n            const handlers: Array<GenericEventHandler> | undefined = all!.get(type);\n            if (handlers) {\n                if (handler) {\n                    handlers.splice(handlers.indexOf(handler) >>> 0, 1);\n                } else {\n                    all!.set(type, []);\n                }\n            }\n        },\n\n        /**\n         * Invoke all handlers for the given type.\n         * If present, `'*'` handlers are invoked after type-matched handlers.\n         *\n         * Note: Manually firing '*' handlers is not supported.\n         *\n         * @param {string|symbol} type The event type to invoke\n         * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler\n         * @memberOf mitt\n         */\n        emit<Key extends keyof Events>(type: Key, evt?: Events[Key]) {\n            let handlers = all!.get(type);\n            if (handlers) {\n                [...(handlers as EventHandlerList<Events[keyof Events]>)].forEach(handler => {\n                    handler(evt as Events[Key]);\n                });\n            }\n\n            handlers = all!.get('*');\n            if (handlers) {\n                [...(handlers as WildCardEventHandlerList<Events>)].forEach(handler => {\n                    handler(type, evt as Events[Key]);\n                });\n            }\n        },\n\n        /**\n         * Clear all\n         */\n        clear() {\n            this.all.clear();\n        }\n    };\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/util/province.ts",
    "content": "export default [{label:\"北京市\",value:\"11\"},{label:\"天津市\",value:\"12\"},{label:\"河北省\",value:\"13\"},{label:\"山西省\",value:\"14\"},{label:\"内蒙古自治区\",value:\"15\"},{label:\"辽宁省\",value:\"21\"},{label:\"吉林省\",value:\"22\"},{label:\"黑龙江省\",value:\"23\"},{label:\"上海市\",value:\"31\"},{label:\"江苏省\",value:\"32\"},{label:\"浙江省\",value:\"33\"},{label:\"安徽省\",value:\"34\"},{label:\"福建省\",value:\"35\"},{label:\"江西省\",value:\"36\"},{label:\"山东省\",value:\"37\"},{label:\"河南省\",value:\"41\"},{label:\"湖北省\",value:\"42\"},{label:\"湖南省\",value:\"43\"},{label:\"广东省\",value:\"44\"},{label:\"广西壮族自治区\",value:\"45\"},{label:\"海南省\",value:\"46\"},{label:\"重庆市\",value:\"50\"},{label:\"四川省\",value:\"51\"},{label:\"贵州省\",value:\"52\"},{label:\"云南省\",value:\"53\"},{label:\"西藏自治区\",value:\"54\"},{label:\"陕西省\",value:\"61\"},{label:\"甘肃省\",value:\"62\"},{label:\"青海省\",value:\"63\"},{label:\"宁夏回族自治区\",value:\"64\"},{label:\"新疆维吾尔自治区\",value:\"65\"},{label:\"台湾\",value:\"66\"},{label:\"香港\",value:\"67\"},{label:\"澳门\",value:\"68\"}];"
  },
  {
    "path": "src/uni_modules/uview-pro/libs/util/system-theme.ts",
    "content": "declare const uni: any;\n\ntype SystemTheme = 'light' | 'dark';\n\n/**\n * 非 H5 平台获取当前系统主题\n */\nexport function getSystemDarkMode(): SystemTheme {\n    try {\n        if (typeof uni !== 'undefined' && typeof uni.getSystemInfoSync === 'function') {\n            const systemInfo = uni.getSystemInfoSync();\n            const theme = systemInfo.osTheme || systemInfo.theme || 'light';\n            if (theme === 'dark') {\n                return 'dark';\n            }\n            if (theme === 'light') {\n                return 'light';\n            }\n        }\n    } catch (e) {\n        // 获取失败时默认返回亮色\n        console.warn('[system-theme] getSystemDarkMode failed', e);\n    }\n    return 'light';\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/locale/index.ts",
    "content": "export { default as zhCN } from './lang/zh-CN';\nexport { default as enUS } from './lang/en-US';\n"
  },
  {
    "path": "src/uni_modules/uview-pro/locale/lang/en-US.ts",
    "content": "export default {\n    name: 'en-US',\n    label: 'English',\n    locale: 'en',\n    uActionSheet: {\n        cancelText: 'Cancel'\n    },\n    uUpload: {\n        uploadText: 'Select File',\n        uploadImage: 'Select Image',\n        uploadVideo: 'Select Video',\n        uploadFile: 'Select File',\n        uploadMedia: 'Select Media',\n        retry: 'Retry',\n        overSize: 'File size exceeds allowed limit',\n        overMaxCount: 'Exceeds maximum allowed number of files',\n        reUpload: 'Re-upload',\n        uploadFailed: 'Upload failed, please try again',\n        modalTitle: 'Notice',\n        modalCancelText: 'Cancel',\n        modalConfirmText: 'Confirm',\n        deleteConfirm: 'Are you sure you want to delete this item?',\n        terminatedRemove: 'Removal cancelled',\n        removeSuccess: 'Removed successfully',\n        previewFailed: 'Failed to preview image',\n        notAllowedExt: 'Files with {ext} format are not allowed',\n        noAction: 'Please configure upload address',\n        fileNotSupported: 'File selection is not supported on this platform',\n        openFailed: 'Unable to open this file'\n    },\n    uVerificationCode: {\n        startText: 'Get Code',\n        changeText: 'Retry in Xs',\n        endText: 'Retry'\n    },\n    uSection: {\n        subTitle: 'More'\n    },\n    uSelect: {\n        cancelText: 'Cancel',\n        confirmText: 'Confirm'\n    },\n    uSearch: {\n        placeholder: 'Please enter keywords',\n        actionText: 'Search'\n    },\n    uNoNetwork: {\n        tips: 'Ooops, network disconnected',\n        checkNetwork: 'Please check network or go to',\n        setting: 'Settings',\n        retry: 'Retry',\n        noConnection: 'No network connection',\n        connected: 'Network connected'\n    },\n    uReadMore: {\n        closeText: 'Read More',\n        openText: 'Collapse'\n    },\n    uPagination: {\n        prevText: 'Prev',\n        nextText: 'Next'\n    },\n    uPicker: {\n        cancelText: 'Cancel',\n        confirmText: 'Confirm'\n    },\n    uModal: {\n        title: 'Notice',\n        content: 'Content',\n        confirmText: 'Confirm',\n        cancelText: 'Cancel'\n    },\n    uLoadmore: {\n        loadmore: 'Load more',\n        loading: 'Loading...',\n        nomore: 'No more'\n    },\n    uLink: {\n        mpTips: 'Link copied, please open it in browser'\n    },\n    uKeyboard: {\n        cancelText: 'Cancel',\n        confirmText: 'Confirm',\n        number: 'Number Keyboard',\n        idCard: 'ID Card Keyboard',\n        plate: 'Plate Keyboard'\n    },\n    uInput: {\n        placeholder: 'Please enter'\n    },\n    uCalendar: {\n        startText: 'Start',\n        endText: 'End',\n        toolTip: 'Select date',\n        outOfRange: 'Date out of range',\n        year: '',\n        month: '',\n        sun: 'Sun',\n        mon: 'Mon',\n        tue: 'Tue',\n        wed: 'Wed',\n        thu: 'Thu',\n        fri: 'Fri',\n        sat: 'Sat',\n        confirmText: 'Confirm',\n        to: ' to ',\n        holiday: '休',\n        workday: '班'\n    },\n    uEmpty: {\n        car: 'Shopping cart is empty',\n        page: 'Page not found',\n        search: 'No search results',\n        address: 'No shipping address',\n        wifi: 'No WiFi',\n        order: 'No orders',\n        coupon: 'No coupons',\n        favor: 'No favorites',\n        permission: 'No permission',\n        history: 'No history',\n        news: 'No news',\n        message: 'No messages',\n        list: 'No list',\n        data: 'No data'\n    },\n    uCountDown: {\n        day: 'days',\n        hour: 'hours',\n        minute: 'minutes',\n        second: 'Second'\n    },\n    uFullScreen: {\n        title: 'New Version Available',\n        upgrade: 'Upgrade'\n    }\n};\n"
  },
  {
    "path": "src/uni_modules/uview-pro/locale/lang/zh-CN.ts",
    "content": "export default {\n    name: 'zh-CN',\n    label: '简体中文',\n    locale: 'zh-Hans',\n    uActionSheet: {\n        cancelText: '取消'\n    },\n    uUpload: {\n        uploadText: '选择文件',\n        uploadImage: '选择图片',\n        uploadVideo: '选择视频',\n        uploadFile: '选择文件',\n        uploadMedia: '选择媒体',\n        retry: '点击重试',\n        overSize: '超出允许的文件大小',\n        overMaxCount: '超出最大允许的文件个数',\n        reUpload: '重新上传',\n        uploadFailed: '上传失败，请重试',\n        modalTitle: '提示',\n        modalCancelText: '取消',\n        modalConfirmText: '确定',\n        deleteConfirm: '您确定要删除此项吗？',\n        terminatedRemove: '已终止移除',\n        removeSuccess: '移除成功',\n        previewFailed: '预览图片失败',\n        notAllowedExt: '不允许选择{ext}格式的文件',\n        noAction: '请配置上传地址',\n        fileNotSupported: '当前平台暂不支持文件选择',\n        openFailed: '无法打开此文件'\n    },\n    uVerificationCode: {\n        startText: '获取验证码',\n        changeText: 'X秒重新获取',\n        endText: '重新获取'\n    },\n    uSection: {\n        subTitle: '更多'\n    },\n    uSelect: {\n        cancelText: '取消',\n        confirmText: '确认'\n    },\n    uSearch: {\n        placeholder: '请输入关键字',\n        actionText: '搜索'\n    },\n    uNoNetwork: {\n        tips: '哎呀，网络信号丢失',\n        checkNetwork: '请检查网络，或前往',\n        setting: '设置',\n        retry: '重试',\n        noConnection: '无网络连接',\n        connected: '网络已连接'\n    },\n    uReadMore: {\n        closeText: '展开阅读全文',\n        openText: '收起'\n    },\n    uPagination: {\n        prevText: '上一页',\n        nextText: '下一页'\n    },\n    uPicker: {\n        cancelText: '取消',\n        confirmText: '确认'\n    },\n    uModal: {\n        title: '提示',\n        content: '内容',\n        confirmText: '确认',\n        cancelText: '取消'\n    },\n    uLoadmore: {\n        loadmore: '加载更多',\n        loading: '正在加载...',\n        nomore: '没有更多了'\n    },\n    uLink: {\n        mpTips: '链接已复制，请在浏览器打开'\n    },\n    uKeyboard: {\n        cancelText: '取消',\n        confirmText: '确认',\n        number: '数字键盘',\n        idCard: '身份证键盘',\n        plate: '车牌号键盘'\n    },\n    uInput: {\n        placeholder: '请输入内容'\n    },\n    uCalendar: {\n        startText: '开始',\n        endText: '结束',\n        toolTip: '选择日期',\n        outOfRange: '日期超出范围啦~',\n        year: '年',\n        month: '月',\n        sun: '日',\n        mon: '一',\n        tue: '二',\n        wed: '三',\n        thu: '四',\n        fri: '五',\n        sat: '六',\n        confirmText: '确定',\n        to: '至',\n        holiday: '休',\n        workday: '班'\n    },\n    uEmpty: {\n        car: '购物车为空',\n        page: '页面不存在',\n        search: '没有搜索结果',\n        address: '没有收货地址',\n        wifi: '没有WiFi',\n        order: '订单为空',\n        coupon: '没有优惠券',\n        favor: '暂无收藏',\n        permission: '无权限',\n        history: '无历史记录',\n        news: '无新闻列表',\n        message: '消息列表为空',\n        list: '列表为空',\n        data: '数据为空'\n    },\n    uCountDown: {\n        day: '天',\n        hour: '时',\n        minute: '分',\n        second: '秒'\n    },\n    uFullScreen: {\n        title: '发现新版本',\n        upgrade: '升级'\n    }\n};\n"
  },
  {
    "path": "src/uni_modules/uview-pro/package.json",
    "content": "{\n    \"id\": \"uview-pro\",\n    \"name\": \"uview-pro\",\n    \"displayName\": \"【支持鸿蒙】uView Pro｜基于Vue3+TS的高质量UI组件库，支持多主题、暗黑模式、多语言\",\n    \"version\": \"0.6.0-beta.1\",\n    \"description\": \"uView Pro是基于Vue3+TS的多平台UI框架，提供80+高质量组件、便捷工具和常用模板，支持多主题、暗黑模式、多语言，支持H5/APP/鸿蒙/小程序多端开发。已在鸿蒙应用商店上架，欢迎体验！\",\n    \"main\": \"index.ts\",\n    \"module\": \"index.ts\",\n    \"browser\": \"index.ts\",\n    \"keywords\": [\n        \"uview-pro\",\n        \"vue3\",\n        \"多主题\",\n        \"暗黑模式\",\n        \"多语言\"\n    ],\n    \"author\": \"anyup\",\n    \"license\": \"MIT\",\n    \"repository\": \"https://github.com/anyup/uview-pro\",\n    \"engines\": {\n        \"HBuilderX\": \"^4.07\",\n        \"uni-app\": \"^4.07\",\n        \"uni-app-x\": \"\"\n    },\n    \"dcloudext\": {\n        \"type\": \"component-vue\",\n        \"sale\": {\n            \"regular\": {\n                \"price\": \"0.00\"\n            },\n            \"sourcecode\": {\n                \"price\": \"0.00\"\n            }\n        },\n        \"contact\": {\n            \"qq\": \"491302297\"\n        },\n        \"declaration\": {\n            \"ads\": \"无\",\n            \"data\": \"无\",\n            \"permissions\": \"无\"\n        },\n        \"npmurl\": \"https://www.npmjs.com/package/uview-pro\",\n        \"darkmode\": \"√\",\n        \"i18n\": \"√\",\n        \"widescreen\": \"√\"\n    },\n    \"uni_modules\": {\n        \"dependencies\": [],\n        \"encrypt\": [],\n        \"platforms\": {\n            \"cloud\": {\n                \"tcb\": \"√\",\n                \"aliyun\": \"√\",\n                \"alipay\": \"√\"\n            },\n            \"client\": {\n                \"uni-app\": {\n                    \"vue\": {\n                        \"vue2\": \"x\",\n                        \"vue3\": \"√\"\n                    },\n                    \"web\": {\n                        \"safari\": \"√\",\n                        \"chrome\": \"√\"\n                    },\n                    \"app\": {\n                        \"vue\": \"√\",\n                        \"nvue\": \"-\",\n                        \"android\": \"√\",\n                        \"ios\": \"√\",\n                        \"harmony\": \"√\"\n                    },\n                    \"mp\": {\n                        \"weixin\": \"√\",\n                        \"alipay\": \"√\",\n                        \"toutiao\": \"√\",\n                        \"baidu\": \"-\",\n                        \"kuaishou\": \"-\",\n                        \"jd\": \"-\",\n                        \"harmony\": \"√\",\n                        \"qq\": \"√\",\n                        \"lark\": \"-\",\n                        \"xhs\": \"-\"\n                    },\n                    \"quickapp\": {\n                        \"huawei\": \"-\",\n                        \"union\": \"-\"\n                    }\n                },\n                \"uni-app-x\": {\n                    \"web\": {\n                        \"safari\": \"-\",\n                        \"chrome\": \"-\"\n                    },\n                    \"app\": {\n                        \"android\": \"-\",\n                        \"ios\": \"-\",\n                        \"harmony\": \"-\"\n                    },\n                    \"mp\": {\n                        \"weixin\": \"-\"\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/uni_modules/uview-pro/readme.md",
    "content": "<p align=\"center\">\n    <img alt=\"logo\" src=\"https://ik.imagekit.io/anyup/uview-pro/common/logo-new.png\" width=\"120\" height=\"120\" style=\"margin-bottom: 10px;\">\n</p>\n<h3 align=\"center\" style=\"margin: 30px 0 30px;font-weight: bold;font-size:40px;\">uView Pro</h3>\n<h3 align=\"center\">uni-app Vue3 多平台快速开发的 UI 框架</h3>\n\n[![star](https://gitee.com/anyup/uView-Pro/badge/star.svg)](https://gitee.com/anyup/uView-Pro)\n[![fork](https://gitee.com/anyup/uView-Pro/badge/fork.svg)](https://gitee.com/anyup/uView-Pro)\n[![stars](https://img.shields.io/github/stars/anyup/uView-Pro?style=flat-square&logo=GitHub)](https://github.com/anyup/uView-Pro)\n[![forks](https://img.shields.io/github/forks/anyup/uView-Pro?style=flat-square&logo=GitHub)](https://github.com/anyup/uView-Pro)\n[![issues](https://img.shields.io/github/issues/anyup/uView-Pro?style=flat-square&logo=GitHub)](https://github.com/anyup/uView-Pro/issues)\n[![downloads](https://img.shields.io/npm/dm/uview-pro?logo=npm&link=https%3A%2F%2Fwww.npmjs.com%2Fpackage%2Fuview-pro&style=flat-square)](https://www.npmjs.com/package/uview-pro)\n[![npm version](https://img.shields.io/npm/v/uview-pro)](https://www.npmjs.com/package/uview-pro)\n[![Website](https://img.shields.io/badge/uView%20Pro-docs-blue?style=flat-square)](https://uviewpro.cn)\n[![node version](https://img.shields.io/badge/node-%3E%3D18-green)](https://nodejs.org/)\n[![pnpm version](https://img.shields.io/badge/pnpm-%3E%3D7.30-green)](https://pnpm.io/)\n[![license](https://img.shields.io/github/license/anyup/uView-Pro?style=flat-square)](https://en.wikipedia.org/wiki/MIT_License)\n\n## 说明\n\n`uView UI`，是 [uni-app](https://uniapp.dcloud.io/) 生态优秀的 UI 框架，全面的组件和便捷的工具会让您信手拈来，如鱼得水。\n\n`uView Pro`，是全面支持 Vue3.0、TypeScript 的 uni-app 生态框架，uView Pro 的基线版本是基于 uView 1.8.8 修改，使用 TypeScript 完全重构，已覆盖 Android、iOS、鸿蒙以及微信/头条/支付宝等主流小程序平台，真正实现“一套代码，多端运行”，支持多主题系统、暗黑模式与国际化（i18n）。\n\n## [官方文档：https://uviewpro.cn](https://uviewpro.cn)\n\n## [快速启动模板：https://starter.uviewpro.cn](https://starter.uviewpro.cn)\n\n## 特性\n\n- 兼容安卓，iOS，微信小程序，H5，QQ 小程序，百度小程序，支付宝小程序，头条小程序\n- 70+精选组件，功能丰富，多端兼容，让您快速集成，开箱即用\n- 众多贴心的 JS 利器，让您飞镖在手，召之即来，百步穿杨\n- 众多的常用页面和布局，让您专注逻辑，事半功倍\n- 详尽的文档支持，现代化的演示效果\n- 按需引入，精简打包体积\n\n## 鸿蒙预览\n\n🎉🎉 uView Pro 鸿蒙端应用已正式上线华为鸿蒙应用市场，为您提供完整的业务场景演示平台，包含组件库、模板示例、场景案例等，支持一键复制下载，帮助开发者快速上手并体验组件的实际应用价值！\n\n> 系统要求：仅支持 HarmonyOS 5.0 及以上版本设备\n\n<table>\n    <tr align=\"center\">\n        <td><img src=\"https://ik.imagekit.io/anyup/images/social/qr_harmony.png\" width=\"180\" height=\"180\" ></td>\n    </tr>\n    <tr>\n        <td align=\"center\"><strong>鸿蒙应用</strong><br>（浏览器扫码）</td>\n    </tr>\n</table>\n\n## 手机预览\n\n您可以通过**微信**或**手机浏览器**扫描以下二维码，查看最佳的演示效果。\n\n<table class=\"table\">\n    <tr>\n        <td><img src=\"https://ik.imagekit.io/anyup/images/social/qr_uview_pro_wx.jpg\" width=\"150\" height=\"150\" ></td>\n        <td><img src=\"https://ik.imagekit.io/anyup/images/social/qr_uview_pro_alipay.png\" width=\"150\" height=\"150\" ></td>\n        <td><img src=\"https://ik.imagekit.io/anyup/images/social/qr_uview_pro_h5.png\" width=\"150\" height=\"150\" ></td>\n        <td><img src=\"https://ik.imagekit.io/anyup/images/social/qr_uview_pro_android.png\" width=\"150\" height=\"150\" ></td>\n    </tr>\n    <tr>\n        <td align=\"center\"><strong>微信小程序</strong><br>（微信扫码）</td>\n        <td align=\"center\"><strong>支付宝小程序</strong><br>（支付宝扫码）</td>\n        <td align=\"center\"><strong>H5</strong><br>（浏览器扫码）</td>\n        <td align=\"center\"><strong>Android</strong><br>（浏览器扫码）</td>\n    </tr>\n</table>\n\n运行示例工程，请[下载源码](https://github.com/anyup/uview-pro)后，在项目根目录执行以下命令：\n\n```bash\npnpm install\npnpm dev\n```\n\n## 链接\n\n- [Github](https://github.com/anyup/uview-pro)\n- [Gitee](https://gitee.com/anyup/uview-pro)\n- [官方文档](https://uviewpro.cn)\n- [更新日志](https://github.com/anyup/uView-Pro/blob/master/src/uni_modules/uview-pro/changelog.md)\n\n## 交流反馈\n\n欢迎通过各种方式来交流反馈，让 uView Pro 更好的为大家服务：\n\n[欢迎交流反馈](https://uviewpro.cn/zh/resource/about.html)\n\n## 捐赠 uView Pro\n\n开源不易，如果您认为 `uView Pro` 帮到了您的开发工作，您可以捐赠 `uView Pro`：\n\n[欢迎捐赠留名](https://uviewpro.cn/zh/reward/donation.html)\n\n## 关于 PR\n\n我们非常乐意接受各位的优质 PR，但在此之前我希望您了解 `uView Pro` 是一个需要兼容多个平台的（小程序、h5、iOS App、Android App）包括 nvue 页面、vue 页面。\n\n所以希望在您修复 bug 并提交之前尽可能的去这些平台测试一下兼容性。最好能携带测试截图以方便审核。非常感谢！\n\n## 安装配置\n\n`uView Pro` 支持 `npm` 和 `uni_modules` 两种主流安装方式，配置方式高度一致。无论采用哪种方式，均可通过 `easycom` 实现组件自动引入，极大提升开发效率。以下为统一的配置说明：\n\n### 1. 安装 uView Pro\n\n- npm 安装：\n\n```bash\nnpm install uview-pro\n# 或\nyarn add uview-pro\n# 或\npnpm add uview-pro\n```\n\n- uni_modules 安装：\n\n通过 HBuilderX 插件市场或手动下载，将 uView Pro 放入 `uni_modules` 目录。\n\n[插件市场：https://ext.dcloud.net.cn/plugin?id=24633](https://ext.dcloud.net.cn/plugin?id=24633)\n\n### 2. 引入 uView Pro 主库\n\n在 `main.ts` 中引入并注册 uView Pro：\n\n```js\nimport { createSSRApp } from 'vue';\n// npm 方式\nimport uViewPro from 'uview-pro';\n// uni_modules 方式\n// import uViewPro from \"@/uni_modules/uview-pro\";\n\nexport function createApp() {\n    const app = createSSRApp(App);\n    app.use(uViewPro);\n    return {\n        app\n    };\n}\n```\n\n### 3. 引入全局样式\n\n在 `uni.scss` 中引入主题样式：\n\n```scss\n/* npm 方式 */\n@import 'uview-pro/theme.scss';\n/* uni_modules 方式 */\n/* @import \"@/uni_modules/uview-pro/theme.scss\"; */\n```\n\n在 `App.vue` 首行引入基础样式：\n\n```scss\n<style lang=\"scss\">\n  /* npm 方式 */\n  @import \"uview-pro/index.scss\";\n  /* uni_modules 方式 */\n  /* @import \"@/uni_modules/uview-pro/index.scss\"; */\n</style>\n```\n\n### 4. 配置 easycom 自动引入组件\n\n在 `pages.json` 中配置 `easycom` 规则，实现组件自动引入：\n\n```json\n{\n    \"easycom\": {\n        \"autoscan\": true,\n        \"custom\": {\n            // npm 方式\n            \"^u-(.*)\": \"uview-pro/components/u-$1/u-$1.vue\"\n            // uni_modules 方式\n            // \"^u-(.*)\": \"@/uni_modules/uview-pro/components/u-$1/u-$1.vue\"\n        }\n    },\n    \"pages\": []\n}\n```\n\n**温馨提示**\n\n- 1.修改 `easycom` 规则后需重启 HX 或重新编译项目。\n- 2.请确保 `pages.json` 中只有一个 easycom 字段，否则请自行合并多个规则。\n- 3.一定要放在 `custom` 内，否则无效。\n\n### 5. Volar 类型提示支持\n\n如需在 `CLI` 项目中获得 `Volar` 的全局类型提示，请在 `tsconfig.json` 中添加：\n\n```json\n{\n    \"compilerOptions\": {\n        // npm 方式\n        \"types\": [\"uview-pro/types\"]\n        // uni_modules 方式\n        // \"types\": [\"@/uni_modules/uview-pro/types\"]\n    }\n}\n```\n\n> HBuilderX 项目暂不支持 `tsconfig.json` 的 `types` 配置，`CLI` 项目推荐配置以获得最佳 `TS` 体验。\n\n### 6. 组件使用\n\n配置完成后，无需 `import` 和 `components` 注册，可直接在 `SFC` 中使用 `uView Pro` 组件：\n\n```vue\n<template>\n    <u-button type=\"primary\">按钮</u-button>\n</template>\n```\n\n请通过[快速上手](https://uviewpro.cn/zh/components/quickstart.html)了解更详细的内容\n\n## 贡献者\n\n<a href=\"https://github.com/anyup/uView-Pro/graphs/contributors\">\n  <img alt=\"Contributors\" src=\"https://contrib.rocks/image?repo=anyup/uView-Pro\" />\n</a>\n\n## 版权信息\n\n`uView Pro` 遵循[MIT](https://en.wikipedia.org/wiki/MIT_License)开源协议，意味着您无需支付任何费用，也无需授权，即可将 `uView Pro` 应用到您的产品中。\n\n## 鸣谢\n\n再次感谢 `uView UI` 开发团队，以及所有为 `uView UI` 的贡献者，以及所有为 `uView Pro` 的贡献者。\n\n- [Github](https://github.com/anyup/uview-pro)\n- [Gitee](https://gitee.com/anyup/uview-pro)\n- [uView UI 1.0](https://github.com/umicro/uView)\n- [uView UI 2.0](https://github.com/umicro/uView2.0)\n"
  },
  {
    "path": "src/uni_modules/uview-pro/theme.scss",
    "content": "// 此文件为uView的主题变量，这些变量目前只能通过uni.scss引入才有效，另外由于\n// uni.scss中引入的样式会同时混入到全局样式文件和单独每一个页面的样式中，造成微信程序包太大，\n// 故uni.scss只建议放scss变量名相关样式，其他的样式可以通过main.js或者App.vue引入\n\n:root,\npage {\n    /* 纯色 */\n    --u-white-color: #ffffff;\n    --u-white-color-rgb: 255, 255, 255;\n    --u-black-color: #000000;\n    --u-black-color-rgb: 0, 0, 0;\n\n    // 字体色\n    --u-main-color: #303133;\n    --u-main-color-rgb: 48, 49, 51;\n    --u-content-color: #606266;\n    --u-content-color-rgb: 96, 98, 102;\n    --u-tips-color: #909399;\n    --u-tips-color-rgb: 144, 147, 153;\n    --u-light-color: #c0c4cc;\n    --u-light-color-rgb: 192, 196, 204;\n\n    // 边框色\n    --u-border-color: #dcdfe6;\n    --u-border-color-rgb: 220, 223, 230;\n    --u-divider-color: #e4e7ed;\n    --u-divider-color-rgb: 228, 231, 237;\n\n    // 遮罩色\n    --u-mask-color: rgba(0, 0, 0, 0.4);\n    --u-shadow-color: rgba(0, 0, 0, 0.1);\n\n    /* 背景色 */\n    --u-bg-color: #f3f4f6;\n    --u-bg-color-rgb: 243, 244, 246;\n    --u-bg-white: #ffffff;\n    --u-bg-white-rgb: 255, 255, 255;\n    --u-bg-gray-light: #f1f1f1;\n    --u-bg-gray-light-rgb: 241, 241, 241;\n    --u-bg-gray-dark: #2f343c;\n    --u-bg-gray-dark-rgb: 47, 52, 60;\n    --u-bg-black: #000000;\n    --u-bg-black-rgb: 0, 0, 0;\n\n    /* 主色 */\n    --u-type-primary: #2979ff;\n    --u-type-primary-rgb: 41, 121, 255;\n    --u-type-primary-disabled: #a0cfff;\n    --u-type-primary-disabled-rgb: 160, 207, 255;\n    --u-type-primary-dark: #2b85e4;\n    --u-type-primary-dark-rgb: 43, 133, 228;\n    --u-type-primary-light: #ecf5ff;\n    --u-type-primary-light-rgb: 236, 245, 255;\n\n    /* 警告色 */\n    --u-type-warning: #ff9900;\n    --u-type-warning-rgb: 255, 153, 0;\n    --u-type-warning-disabled: #fcbd71;\n    --u-type-warning-disabled-rgb: 252, 189, 113;\n    --u-type-warning-dark: #f29100;\n    --u-type-warning-dark-rgb: 242, 145, 0;\n    --u-type-warning-light: #fdf6ec;\n    --u-type-warning-light-rgb: 253, 246, 236;\n\n    /* 成功色 */\n    --u-type-success: #19be6b;\n    --u-type-success-rgb: 25, 190, 107;\n    --u-type-success-disabled: #71d5a1;\n    --u-type-success-disabled-rgb: 113, 213, 161;\n    --u-type-success-dark: #18b566;\n    --u-type-success-dark-rgb: 24, 181, 102;\n    --u-type-success-light: #dbf1e1;\n    --u-type-success-light-rgb: 219, 241, 225;\n\n    /* 错误色 */\n    --u-type-error: #fa3534;\n    --u-type-error-rgb: 250, 53, 52;\n    --u-type-error-disabled: #fab6b6;\n    --u-type-error-disabled-rgb: 250, 182, 182;\n    --u-type-error-dark: #dd6161;\n    --u-type-error-dark-rgb: 221, 97, 97;\n    --u-type-error-light: #fef0f0;\n    --u-type-error-light-rgb: 254, 240, 240;\n\n    /* 信息色 */\n    --u-type-info: #909399;\n    --u-type-info-rgb: 144, 147, 153;\n    --u-type-info-disabled: #c8c9cc;\n    --u-type-info-disabled-rgb: 200, 201, 204;\n    --u-type-info-dark: #82848a;\n    --u-type-info-dark-rgb: 130, 132, 138;\n    --u-type-info-light: #f4f4f5;\n    --u-type-info-light-rgb: 244, 244, 245;\n}\n\n// 纯色\n$u-white-color: var(--u-white-color);\n$u-black-color: var(--u-black-color);\n\n// 字体色\n$u-main-color: var(--u-main-color);\n$u-content-color: var(--u-content-color);\n$u-tips-color: var(--u-tips-color);\n$u-light-color: var(--u-light-color);\n\n// 边框色\n$u-border-color: var(--u-border-color);\n$u-divider-color: var(--u-divider-color);\n\n// 遮罩色\n$u-mask-color: var(--u-mask-color);\n$u-shadow-color: var(--u-shadow-color);\n\n// 背景色\n$u-bg-color: var(--u-bg-color);\n$u-bg-white: var(--u-bg-white);\n$u-bg-gray-light: var(--u-bg-gray-light);\n$u-bg-gray-dark: var(--u-bg-gray-dark);\n$u-bg-black: var(--u-bg-black);\n\n// 主色\n$u-type-primary: var(--u-type-primary);\n$u-type-primary-light: var(--u-type-primary-light);\n$u-type-primary-disabled: var(--u-type-primary-disabled);\n$u-type-primary-dark: var(--u-type-primary-dark);\n\n// 警告色\n$u-type-warning: var(--u-type-warning);\n$u-type-warning-disabled: var(--u-type-warning-disabled);\n$u-type-warning-dark: var(--u-type-warning-dark);\n$u-type-warning-light: var(--u-type-warning-light);\n\n// 成功色\n$u-type-success: var(--u-type-success);\n$u-type-success-disabled: var(--u-type-success-disabled);\n$u-type-success-dark: var(--u-type-success-dark);\n$u-type-success-light: var(--u-type-success-light);\n\n// 错误色\n$u-type-error: var(--u-type-error);\n$u-type-error-disabled: var(--u-type-error-disabled);\n$u-type-error-dark: var(--u-type-error-dark);\n$u-type-error-light: var(--u-type-error-light);\n\n// 信息色\n$u-type-info: var(--u-type-info);\n$u-type-info-disabled: var(--u-type-info-disabled);\n$u-type-info-dark: var(--u-type-info-dark);\n$u-type-info-light: var(--u-type-info-light);\n"
  },
  {
    "path": "src/uni_modules/uview-pro/types/components.d.ts",
    "content": "declare module 'vue' {\n    export interface GlobalComponents {\n        uActionSheet: (typeof import('../components/u-action-sheet/u-action-sheet.vue'))['default'];\n        uActionSheetItem: (typeof import('../components/u-action-sheet-item/u-action-sheet-item.vue'))['default'];\n        uAlertTips: (typeof import('../components/u-alert-tips/u-alert-tips.vue'))['default'];\n        uAvatar: (typeof import('../components/u-avatar/u-avatar.vue'))['default'];\n        uAvatarCropper: (typeof import('../components/u-avatar-cropper/u-avatar-cropper.vue'))['default'];\n        uBackTop: (typeof import('../components/u-back-top/u-back-top.vue'))['default'];\n        uBadge: (typeof import('../components/u-badge/u-badge.vue'))['default'];\n        uButton: (typeof import('../components/u-button/u-button.vue'))['default'];\n        uCalendar: (typeof import('../components/u-calendar/u-calendar.vue'))['default'];\n        uCard: (typeof import('../components/u-card/u-card.vue'))['default'];\n        uCarKeyboard: (typeof import('../components/u-car-keyboard/u-car-keyboard.vue'))['default'];\n        uCellGroup: (typeof import('../components/u-cell-group/u-cell-group.vue'))['default'];\n        uCellItem: (typeof import('../components/u-cell-item/u-cell-item.vue'))['default'];\n        uCheckbox: (typeof import('../components/u-checkbox/u-checkbox.vue'))['default'];\n        uCheckboxGroup: (typeof import('../components/u-checkbox-group/u-checkbox-group.vue'))['default'];\n        uCircleProgress: (typeof import('../components/u-circle-progress/u-circle-progress.vue'))['default'];\n        uCitySelect: (typeof import('../components/u-city-select/u-city-select.vue'))['default'];\n        uCol: (typeof import('../components/u-col/u-col.vue'))['default'];\n        uCollapse: (typeof import('../components/u-collapse/u-collapse.vue'))['default'];\n        uCollapseItem: (typeof import('../components/u-collapse-item/u-collapse-item.vue'))['default'];\n        uColumnNotice: (typeof import('../components/u-column-notice/u-column-notice.vue'))['default'];\n        uCountDown: (typeof import('../components/u-count-down/u-count-down.vue'))['default'];\n        uCountTo: (typeof import('../components/u-count-to/u-count-to.vue'))['default'];\n        uDivider: (typeof import('../components/u-divider/u-divider.vue'))['default'];\n        uDropdown: (typeof import('../components/u-dropdown/u-dropdown.vue'))['default'];\n        uDropdownItem: (typeof import('../components/u-dropdown-item/u-dropdown-item.vue'))['default'];\n        uEmpty: (typeof import('../components/u-empty/u-empty.vue'))['default'];\n        uField: (typeof import('../components/u-field/u-field.vue'))['default'];\n        uForm: (typeof import('../components/u-form/u-form.vue'))['default'];\n        uFormItem: (typeof import('../components/u-form-item/u-form-item.vue'))['default'];\n        uFullScreen: (typeof import('../components/u-full-screen/u-full-screen.vue'))['default'];\n        uGap: (typeof import('../components/u-gap/u-gap.vue'))['default'];\n        uGrid: (typeof import('../components/u-grid/u-grid.vue'))['default'];\n        uGridItem: (typeof import('../components/u-grid-item/u-grid-item.vue'))['default'];\n        uIcon: (typeof import('../components/u-icon/u-icon.vue'))['default'];\n        uImage: (typeof import('../components/u-image/u-image.vue'))['default'];\n        uIndexAnchor: (typeof import('../components/u-index-anchor/u-index-anchor.vue'))['default'];\n        uIndexList: (typeof import('../components/u-index-list/u-index-list.vue'))['default'];\n        uInput: (typeof import('../components/u-input/u-input.vue'))['default'];\n        uKeyboard: (typeof import('../components/u-keyboard/u-keyboard.vue'))['default'];\n        uLazyLoad: (typeof import('../components/u-lazy-load/u-lazy-load.vue'))['default'];\n        uLine: (typeof import('../components/u-line/u-line.vue'))['default'];\n        uLineProgress: (typeof import('../components/u-line-progress/u-line-progress.vue'))['default'];\n        uLink: (typeof import('../components/u-link/u-link.vue'))['default'];\n        uLoadmore: (typeof import('../components/u-loadmore/u-loadmore.vue'))['default'];\n        uLoading: (typeof import('../components/u-loading/u-loading.vue'))['default'];\n        uLoadingPopup: (typeof import('../components/u-loading-popup/u-loading-popup.vue'))['default'];\n        uMask: (typeof import('../components/u-mask/u-mask.vue'))['default'];\n        uMessageInput: (typeof import('../components/u-message-input/u-message-input.vue'))['default'];\n        uModal: (typeof import('../components/u-modal/u-modal.vue'))['default'];\n        uNavbar: (typeof import('../components/u-navbar/u-navbar.vue'))['default'];\n        uNoNetwork: (typeof import('../components/u-no-network/u-no-network.vue'))['default'];\n        uNoticeBar: (typeof import('../components/u-notice-bar/u-notice-bar.vue'))['default'];\n        uNumberBox: (typeof import('../components/u-number-box/u-number-box.vue'))['default'];\n        uNumberKeyboard: (typeof import('../components/u-number-keyboard/u-number-keyboard.vue'))['default'];\n        uPicker: (typeof import('../components/u-picker/u-picker.vue'))['default'];\n        uPopup: (typeof import('../components/u-popup/u-popup.vue'))['default'];\n        uRadio: (typeof import('../components/u-radio/u-radio.vue'))['default'];\n        uRadioGroup: (typeof import('../components/u-radio-group/u-radio-group.vue'))['default'];\n        uRate: (typeof import('../components/u-rate/u-rate.vue'))['default'];\n        uReadMore: (typeof import('../components/u-read-more/u-read-more.vue'))['default'];\n        uRow: (typeof import('../components/u-row/u-row.vue'))['default'];\n        uRowNotice: (typeof import('../components/u-row-notice/u-row-notice.vue'))['default'];\n        uSearch: (typeof import('../components/u-search/u-search.vue'))['default'];\n        uSection: (typeof import('../components/u-section/u-section.vue'))['default'];\n        uSelect: (typeof import('../components/u-select/u-select.vue'))['default'];\n        uSkeleton: (typeof import('../components/u-skeleton/u-skeleton.vue'))['default'];\n        uSlider: (typeof import('../components/u-slider/u-slider.vue'))['default'];\n        uStep: (typeof import('../components/u-steps/u-step.vue'))['default'];\n        uSteps: (typeof import('../components/u-steps/u-steps.vue'))['default'];\n        uSticky: (typeof import('../components/u-sticky/u-sticky.vue'))['default'];\n        uSubsection: (typeof import('../components/u-subsection/u-subsection.vue'))['default'];\n        uSwipeAction: (typeof import('../components/u-swipe-action/u-swipe-action.vue'))['default'];\n        uSwiper: (typeof import('../components/u-swiper/u-swiper.vue'))['default'];\n        uSwitch: (typeof import('../components/u-switch/u-switch.vue'))['default'];\n        uTabbar: (typeof import('../components/u-tabbar/u-tabbar.vue'))['default'];\n        uTable: (typeof import('../components/u-table/u-table.vue'))['default'];\n        uTabs: (typeof import('../components/u-tabs/u-tabs.vue'))['default'];\n        uTabsSwiper: (typeof import('../components/u-tabs-swiper/u-tabs-swiper.vue'))['default'];\n        uTag: (typeof import('../components/u-tag/u-tag.vue'))['default'];\n        uTd: (typeof import('../components/u-td/u-td.vue'))['default'];\n        uTh: (typeof import('../components/u-th/u-th.vue'))['default'];\n        uTimeLine: (typeof import('../components/u-time-line/u-time-line.vue'))['default'];\n        uTimeLineItem: (typeof import('../components/u-time-line-item/u-time-line-item.vue'))['default'];\n        uToast: (typeof import('../components/u-toast/u-toast.vue'))['default'];\n        uTopTips: (typeof import('../components/u-top-tips/u-top-tips.vue'))['default'];\n        uTransition: (typeof import('../components/u-transition/u-transition.vue'))['default'];\n        uTr: (typeof import('../components/u-tr/u-tr.vue'))['default'];\n        uUpload: (typeof import('../components/u-upload/u-upload.vue'))['default'];\n        uVerificationCode: (typeof import('../components/u-verification-code/u-verification-code.vue'))['default'];\n        uWaterfall: (typeof import('../components/u-waterfall/u-waterfall.vue'))['default'];\n        uText: (typeof import('../components/u-text/u-text.vue'))['default'];\n        uRootPortal: (typeof import('../components/u-root-portal/u-root-portal.vue'))['default'];\n        uStatusBar: (typeof import('../components/u-status-bar/u-status-bar.vue'))['default'];\n        uSafeBottom: (typeof import('../components/u-safe-bottom/u-safe-bottom.vue'))['default'];\n        uTextarea: (typeof import('../components/u-textarea/u-textarea.vue'))['default'];\n        uFab: (typeof import('../components/u-fab/u-fab.vue'))['default'];\n        uPagination: (typeof import('../components/u-pagination/u-pagination.vue'))['default'];\n        uConfigProvider: (typeof import('../components/u-config-provider/u-config-provider.vue'))['default'];\n    }\n}\n\nexport {};\n"
  },
  {
    "path": "src/uni_modules/uview-pro/types/global.d.ts",
    "content": "export type ThemeType = 'primary' | 'info' | 'error' | 'warning' | 'success' | 'default';\n\nexport type SizeType = 'default' | 'small' | 'large';\n\nexport type ImgMode = 'aspectFit' | 'aspectFill' | 'widthFix' | 'top' | 'bottom' | 'center' | 'scaleToFill';\n\nexport type Direction = 'horizontal' | 'vertical';\n\nexport type Sex = 'man' | 'woman';\n\nexport type Shape = 'circle' | 'square';\nexport type Effect = 'linear' | 'ease' | 'ease-in' | 'ease-in-out' | 'ease-out' | 'step-start' | 'step-end';\n\nexport type TextAlign = 'left' | 'center' | 'right';\nexport type JustifyType = 'start' | 'end' | 'center' | 'around' | 'between';\nexport type AlignType = 'top' | 'center' | 'bottom';\nexport type ScrollDirection = 'row' | 'column';\nexport type PlayState = 'play' | 'paused';\nexport type OptionType = { label: string; value: any };\n\n// action-sheet 操作项类型\nexport type ActionSheetItem = {\n    text: string;\n    subText?: string;\n    color?: string;\n    fontSize?: string | number;\n    disabled?: boolean;\n};\n\n// action-sheet 底部提示类型\nexport type ActionSheetTips = {\n    text: string;\n    color?: string;\n    fontSize?: string | number;\n};\n\n// avatar-cropper 裁剪矩形框的样式\nexport type AvatarCropperBoundStyle = {\n    lineWidth: number;\n    borderColor: string;\n    mask: string;\n};\n// badge 角标类型\nexport type BadgeSize = 'default' | 'mini';\n// button 按钮类型\nexport type ButtonType = 'primary' | 'info' | 'error' | 'warning' | 'success' | 'default';\n// button 按钮尺寸\nexport type ButtonSize = SizeType | 'default' | 'medium' | 'mini';\n// button 按钮 form-type\nexport type ButtonFormType = '' | 'submit' | 'reset';\n// button 按钮 scope\nexport type ButtonScope = 'phoneNumber' | 'userInfo';\n// button 按钮open-type\nexport type ButtonOpenType =\n    | 'feedback'\n    | 'share'\n    | 'getUserInfo'\n    | 'contact'\n    | 'getPhoneNumber'\n    | 'launchApp'\n    | 'openSetting'\n    | 'chooseAvatar'\n    | 'getAuthorize'\n    | 'lifestyle'\n    | 'contactShare'\n    | 'openGroupProfile'\n    | 'openGuildProfile'\n    | 'openPublicProfile'\n    | 'shareMessageToFriend'\n    | 'addFriend'\n    | 'addColorSign'\n    | 'addGroupApp'\n    | 'addToFavorites'\n    | 'chooseAddress'\n    | 'chooseInvoiceTitle'\n    | 'login'\n    | 'subscribe'\n    | 'favorite'\n    | 'watchLater'\n    | 'openProfile'\n    | 'agreePrivacyAuthorization';\n\n// calendar 组件 mode\nexport type CalendarMode = 'date' | 'range';\n\n// calendar 农历数据类型定义\nexport type CalendarLunarItem = {\n    dayCn: string;\n    weekCn: string;\n    monthCn: string;\n    day: number;\n    week: number;\n    month: number;\n    year: number;\n};\n\n// calendar 事件类型定义，单个日期\nexport type CalendarChangeDate = {\n    year: number;\n    month: number;\n    day: number;\n    days: number;\n    result: string;\n    week: string;\n    isToday: boolean;\n    lunar: CalendarLunarItem | null; // getLunar 返回类型，建议后续补充具体类型\n};\n\n// calendar 事件类型定义，范围选择\nexport type CalendarChangeRange = {\n    startYear: number;\n    startMonth: number;\n    startDay: number;\n    startDate: string;\n    startWeek: string;\n    endYear: number;\n    endMonth: number;\n    endDay: number;\n    endDate: string;\n    endWeek: string;\n    startLunar: CalendarLunarItem | null;\n    endLunar: CalendarLunarItem | null;\n};\n\n// CellItem 右侧箭头方向，可选值：right|up|down，默认为right\nexport type CellItemArrowDirection = 'right' | 'up' | 'down';\n\nexport type FormRuleItem = {\n    required?: boolean;\n    message?: string;\n    trigger?: string | string[];\n    min?: number;\n    max?: number;\n    pattern?: RegExp;\n    type?: string;\n    validator?: (rule: any, value: any, callback: any) => boolean;\n    asyncValidator?: (rule: any, value: any, callback: any) => void;\n    fields?: FormRules;\n    defaultField?: FormRuleItem;\n};\nexport type FormRules = Record<string, FormRuleItem | FormRuleItem[]>;\n\nexport type InputType =\n    | 'text'\n    | 'number'\n    | 'idcard'\n    | 'digit'\n    | 'password'\n    | 'textarea'\n    | 'phone'\n    | 'url'\n    | 'email'\n    | 'safe-password'\n    | 'name'\n    | 'nickname'\n    | 'bank-card'\n    | 'tel'\n    | 'select';\n\nexport type InputAlign = 'left' | 'center' | 'right';\n\nexport type InputConfirmType = 'send' | 'search' | 'next' | 'go' | 'done';\n\nexport type InputLabelPosition = 'left' | 'top';\n\nexport type TextareaBorder = 'surround' | 'none' | 'bottom';\n\nexport type FormErrorType = 'message' | 'border' | 'border-bottom' | 'none' | 'toast';\n\nexport type IconLabelPosition = 'left' | 'top' | 'right' | 'bottom';\n\nexport type LineDirection = 'row' | 'column';\n\nexport type LineBorderStyle = 'solid' | 'dashed' | 'dotted';\n\nexport type LoadmoreText = {\n    loadmore: string;\n    loading: string;\n    nomore: string;\n};\n\nexport type LoadmoreStatus = 'loadmore' | 'loading' | 'nomore';\n\nexport type LoadmoreIconType = 'circle' | 'flower';\n\nexport type MessageInputMode = 'box' | 'bottomLine' | 'middleLine';\n\nexport type NumberKeyboardMode = 'number' | 'card';\n\n/**\n * PickerMode 选择器模式类型\n * 模式选择，region-地区类型，time-时间类型，selector-单列模式，multiSelector-多列模\n */\nexport type PickerMode = 'region' | 'time' | 'selector' | 'multiSelector';\n\n/**\n * PickerParams 选择器参数类型\n */\nexport type PickerParams = {\n    year?: boolean;\n    month?: boolean;\n    day?: boolean;\n    hour?: boolean;\n    minute?: boolean;\n    second?: boolean;\n    province?: boolean;\n    city?: boolean;\n    area?: boolean;\n    timestamp?: boolean;\n};\n\nexport type PopupMode = 'left' | 'right' | 'top' | 'bottom' | 'center' | 'inline';\nexport type PopupCloseIconPos = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\n\n// Row水平排列方式，可选值为`start`(或`flex-start`)、`end`(或`flex-end`)、`center`、`around`(或`space-around`)、`between`(或`space-between`)\nexport type RowJustify =\n    | 'start'\n    | 'flex-start'\n    | 'end'\n    | 'flex-end'\n    | 'center'\n    | 'around'\n    | 'space-around'\n    | 'between'\n    | 'space-between';\n// Row垂直对齐方式，可选值为top、center、bottom\nexport type RowAlign = 'top' | 'center' | 'bottom';\n// search 组件形状\nexport type SearchShape = 'round' | 'square';\n// select 组件 mode single-column-单列，mutil-column-多列，mutil-column-auto-多列联动\nexport type SelectMode = 'single-column' | 'mutil-column' | 'mutil-column-auto';\n// select 组件 list item\nexport type SelectListItem = {\n    label: string;\n    value: string | number;\n    children?: SelectListItem[];\n    extra?: any;\n    [key: string]: any;\n};\n// Step 组件 mode\nexport type StepsListItem = {\n    name: string;\n    icon?: string;\n    desc?: string;\n    [key: string]: any;\n};\n// Step 组件 mode\nexport type StepMode = 'dot' | 'number';\n// Step 组件 direction\nexport type StepDirection = 'row' | 'column';\n// Subsection 组件 list item\nexport type SubsectionListItem = {\n    name: string;\n    width?: number;\n    [key: string]: any;\n};\n// Subsection 组件 mode\nexport type SubsectionMode = 'button' | 'subsection';\n// swipeAction 操作项类型\nexport type SwipeActionOption = {\n    /** 按钮显示的文字 */\n    text: string;\n    /** 按钮自定义样式 */\n    style?: Record<string, any>;\n};\n// swiper 组件 mode\nexport type SwiperMode = 'round' | 'dot' | 'rect' | 'number' | 'none';\n// swiper 组件 indicatorPos\nexport type SwiperIndicatorPosition =\n    | 'topLeft'\n    | 'topCenter'\n    | 'topRight'\n    | 'bottomLeft'\n    | 'bottomCenter'\n    | 'bottomRight';\n// tabs 组件 props\nexport type TabsItem = {\n    [key: string]: any;\n    name?: string | number;\n    count?: string | number;\n    hidden?: boolean;\n};\n// tabs-swiper 组件 list item\nexport type TabsSwiperListItem = {\n    [key: string]: any;\n    name?: string | number;\n    count?: string | number;\n};\n// tabs-swiper 组件 autoCenterMode\nexport type TabsSwiperAutoCenterMode = 'window';\n// tag 组件 mode\nexport type TagMode = 'light' | 'dark' | 'plain';\n// tag 组件 shape\nexport type TagShape = 'square' | 'circle' | 'circleLeft' | 'circleRight';\n// tag 组件 size\nexport type TagSize = 'default' | 'mini';\n// toast 组件 position\nexport type ToastPosition = 'top' | 'center' | 'bottom';\nexport type UploadSizeType = 'original' | 'compressed';\nexport type UploadSourceType = 'album' | 'camera';\n\n/**\n * 上传文件类型\n * @description image-图片, video-视频, file-文件, media-媒体(图片+视频), all-所有文件\n */\nexport type UploadAcceptType = 'image' | 'video' | 'file' | 'media' | 'all';\n\n/**\n * 上传文件项\n */\nexport interface UploadFileItem {\n    url?: string;\n    path?: string;\n    name?: string;\n    size?: number;\n    type?: string;\n    fileType?: 'image' | 'video' | 'file';\n    progress?: number;\n    error?: boolean;\n    response?: any;\n    uploadTask?: any;\n    file?: any;\n    thumb?: string;\n    [key: string]: any;\n}\n// fab 组件 position\nexport type FabPosition =\n    | 'left-top'\n    | 'right-top'\n    | 'left-bottom'\n    | 'right-bottom'\n    | 'left-center'\n    | 'right-center'\n    | 'top-center'\n    | 'bottom-center';\n// fab 组件 direction\nexport type FabDirection = 'top' | 'bottom' | 'left' | 'right';\n// fab 组件 gap\nexport type FabGap = Partial<Record<'top' | 'left' | 'right' | 'bottom', number>>;\n// Transition 组件\nexport type TransitionPreset =\n    | 'fade'\n    | 'slide-up'\n    | 'slide-down'\n    | 'slide-left'\n    | 'slide-right'\n    | 'zoom-in'\n    | 'zoom-out';\n// Transition 组件 duration\nexport type TransitionDuration = {\n    enter?: number;\n    leave?: number;\n};\n\nexport type ColorType =\n    | 'primary'\n    | 'primaryDark'\n    | 'primaryDisabled'\n    | 'primaryLight'\n    | 'bgColor'\n    | 'bgWhite'\n    | 'bgGrayLight'\n    | 'bgGrayDark'\n    | 'bgBlack'\n    | 'info'\n    | 'infoDark'\n    | 'infoDisabled'\n    | 'infoLight'\n    | 'warning'\n    | 'warningDark'\n    | 'warningDisabled'\n    | 'warningLight'\n    | 'error'\n    | 'errorDark'\n    | 'errorDisabled'\n    | 'errorLight'\n    | 'success'\n    | 'successDark'\n    | 'successDisabled'\n    | 'successLight'\n    | 'mainColor'\n    | 'contentColor'\n    | 'tipsColor'\n    | 'lightColor'\n    | 'borderColor'\n    | 'whiteColor'\n    | 'blackColor'\n    | 'dividerColor'\n    | 'maskColor'\n    | 'shadowColor';\n\n// 自定义主题色\nexport type ThemeColor = Partial<Record<ColorType, string>>;\n\nexport type DarkMode = 'auto' | 'light' | 'dark';\n\nexport type Theme = {\n    name: string;\n    label?: string;\n    description?: string;\n    /**\n     * 亮色模式下的令牌（会同步到 $u.color 和 CSS 变量）\n     */\n    color: Partial<ThemeColor>;\n    /**\n     * 暗黑模式下的令牌，未提供时回退到 color\n     */\n    darkColor?: Partial<ThemeColor>;\n    /**\n     * 需要直接注入的 CSS 变量（亮色）\n     */\n    css?: Record<string, string>;\n    /**\n     * 需要直接注入的 CSS 变量（暗黑）\n     */\n    darkCss?: Record<string, string>;\n};\n\nexport type Themes = {\n    themes: Theme[];\n    defaultTheme?: string;\n    defaultDarkMode?: DarkMode;\n    isForce?: boolean;\n};\n\nexport type Locales = {\n    locales: Locale[];\n    defaultLocale?: string;\n    isForce?: boolean;\n};\n\nexport type Locale = {\n    name: string;\n    [key: string]: any;\n};\n\nexport type DebugMode = 'log' | 'warn' | 'error' | 'info';\n\nexport interface UViewProOptions {\n    theme?: ThemeColor | Theme[] | Themes;\n    locale?: string | Locale[] | Locales;\n    debugMode?: boolean | DebugMode | DebugMode[];\n    // 可扩展更多配置项\n}\n\n// pagination 组件，分页方向\nexport type PaginationDirection = 'prev' | 'next';\n\n// pagination 组件，change 参数\nexport type PaginationChangePayload = {\n    type: PaginationDirection;\n    current: number;\n};\n\n// tabbar 组件 Item\nexport type TabbarItem = {\n    text?: string;\n    pagePath?: string;\n    iconPath?: string;\n    selectedIconPath?: string;\n    count?: number;\n    isDot?: boolean;\n    customIcon?: boolean | string;\n    midButton?: boolean;\n    iconSize?: string | number;\n    textSize?: string | number;\n    gap?: string | number;\n    /** 自定义宽度，优先级高于自动计算的宽度 */\n    width?: string | number;\n};\n"
  },
  {
    "path": "src/uni_modules/uview-pro/types/ignore-errors.d.ts",
    "content": "// 忽略 uview-pro 组件库内部的 TypeScript 错误\n// 这些错误不影响组件的正常使用和类型提示\n\n// 忽略 WeCropper 相关的类型错误\ndeclare module 'weCropper' {\n    export class WeCropper {\n        constructor(params: any);\n        [key: string]: any;\n    }\n}\n\n// 忽略 base64 模块的类型错误\ndeclare module 'base64' {\n    export function encode(data: any): string;\n    export function decode(data: string): any;\n}\n\n// 忽略其他内部模块的类型错误\ndeclare module 'uview-pro/components/*' {\n    const component: any;\n    export default component;\n}\n\n// 忽略工具函数的类型错误\ndeclare module 'uview-pro/libs/function/*' {\n    const func: any;\n    export default func;\n}\n\nexport {};\n"
  },
  {
    "path": "src/uni_modules/uview-pro/types/index.d.ts",
    "content": "/// <reference path=\"./components.d.ts\" />\n/// <reference path=\"./uni-app.d.ts\" />\n\nimport { $u } from '../libs';\n\n// uview-pro 模块类型声明\ndeclare module 'uview-pro' {\n    // 导出安装函数\n    export function install(): void;\n}\n\n// 全局类型扩展\ndeclare global {\n    interface Uni {\n        $u: typeof $u;\n    }\n}\n\nexport {};\n"
  },
  {
    "path": "src/uni_modules/uview-pro/types/uni-app.d.ts",
    "content": "// /src/uni_modules/uview-pro/types/uni-app.d.ts\n// 扩展全局 HTMLAttributes 以支持 uni-app/小程序自定义属性\nimport 'vue';\n\ndeclare module 'vue' {\n    export interface GlobalComponents {\n        // UniApp core/native tags\n        view: any;\n        'scroll-view': any;\n        swiper: any;\n        'swiper-item': any;\n        image: any;\n        'rich-text': any;\n        canvas: any;\n        block: any;\n\n        // Basic HTML shims often used by uni-app compiler\n        text: any;\n    }\n    interface HTMLAttributes {\n        // 支持小程序/uni-app 特有属性\n        'hover-class'?: string;\n        'hover-stop-propagation'?: boolean;\n        'hover-start-time'?: number;\n        'hover-stay-time'?: number;\n        animation?: string;\n        'data-*'?: any;\n        catchtap?: (e: any) => void;\n        catchlongpress?: (e: any) => void;\n        catchtouchstart?: (e: any) => void;\n        catchtouchmove?: (e: any) => void;\n        catchtouchend?: (e: any) => void;\n        catchtouchcancel?: (e: any) => void;\n        // 其他常用 uni-app 事件和属性可按需补充\n        src?: string;\n    }\n}\n\n// 兼容 JSX/TSX 场景\ndeclare global {\n    namespace JSX {\n        interface IntrinsicAttributes {\n            'hover-class'?: string;\n            'hover-stop-propagation'?: boolean;\n            'hover-start-time'?: number;\n            'hover-stay-time'?: number;\n            animation?: string;\n            'data-*'?: any;\n            catchtap?: (e: any) => void;\n            catchlongpress?: (e: any) => void;\n            catchtouchstart?: (e: any) => void;\n            catchtouchmove?: (e: any) => void;\n            catchtouchend?: (e: any) => void;\n            catchtouchcancel?: (e: any) => void;\n            src?: string;\n        }\n        interface IntrinsicElements {\n            [elem: string]: any;\n        }\n    }\n}\n\nexport {};\n"
  },
  {
    "path": "src/uni_modules/zero-markdown-view/changelog.md",
    "content": "## 3.0.0（2025-07-17）\n### 新增 aiMode 模式\n### aiMode模式 优化流式输出以及排版\n## 2.1.0（2025-05-23）\n- 新增latex公式支持\n- 代码块高亮支持增加除js外的语法\n- 注意:包体积增加了,建议在分包内使用\n## 2.0.5（2024-04-24）\n- 流式输出代码块解决方案\n## 2.0.4（2023-12-06）\n- 长按复制代码改为点击代码块复制\n## 2.0.3（2023-10-30）\ndoc: 文档说明\n## 2.0.2（2023-10-30）\n- 新增长按复制代码-仅小程序可用\n- 新增代码块语言显示\n## 2.0.1（2023-10-27）\n##支持vue2,vue3\n## 2.0.0（2022-11-01）\n使用mp-html自带的插件,重新生成uniapp包,大幅减少插件体积\n## 1.0.0（2022-09-13）\n首次发布\n"
  },
  {
    "path": "src/uni_modules/zero-markdown-view/components/mp-html/highlight/config.js",
    "content": "export default {\n  // copyByLongPress: false, // 是否需要长按代码块时显示复制代码内容菜单\n  copyByClickCode: true, // 点击代码块复制\n  showLanguageName: true, // 是否在代码块右上角显示语言的名称\n  // showLineNumber: false // 是否显示行号,需要重新打包mp-html\n}\n"
  },
  {
    "path": "src/uni_modules/zero-markdown-view/components/mp-html/highlight/index.js",
    "content": "/**\n * @fileoverview highlight 插件\n * Include prismjs (https://prismjs.com)\n */\nimport prism from \"./prism.min\";\nimport config from \"./config\";\nimport Parser from \"../parser\";\n\nfunction Highlight(vm) {\n  this.vm = vm;\n}\n\nHighlight.prototype.onParse = function (node, vm) {\n  if (node.name === \"pre\") {\n    if (vm.options.editable) {\n      node.attrs.class = (node.attrs.class || \"\") + \" hl-pre\";\n      return;\n    }\n    let i;\n    for (i = node.children.length; i--; ) {\n      if (node.children[i].name === \"code\") break;\n    }\n    if (i === -1) return;\n    const code = node.children[i];\n    let className = code.attrs.class + \" \" + node.attrs.class;\n    i = className.indexOf(\"language-\");\n    if (i === -1) {\n      i = className.indexOf(\"lang-\");\n      if (i === -1) {\n        className = \"language-text\";\n        i = 9;\n      } else {\n        i += 5;\n      }\n    } else {\n      i += 9;\n    }\n    let j;\n    for (j = i; j < className.length; j++) {\n      if (className[j] === \" \") break;\n    }\n    const lang = className.substring(i, j);\n    if (code.children.length) {\n      const text = this.vm.getText(code.children).replace(/&amp;/g, \"&\");\n      if (!text) return;\n      if (node.c) {\n        node.c = undefined;\n      }\n      if (prism.languages[lang]) {\n        code.children = new Parser(this.vm).parse(\n          // 加一层 pre 保留空白符\n          \"<pre>\" +\n            prism\n              .highlight(text, prism.languages[lang], lang)\n              .replace(/token /g, \"hl-\") +\n            \"</pre>\"\n        )[0].children;\n      }\n      node.attrs.class = \"hl-pre\";\n      code.attrs.class = \"hl-code\";\n      code.attrs.style = \"display:block;overflow: auto;\";\n\n      if (config.showLanguageName) {\n        node.children.push({\n          name: \"div\",\n          attrs: {\n            class: \"hl-language\",\n            style:\n              \"user-select:none;position:absolute;top:0;right:2px;font-size:10px;\",\n          },\n          children: [\n            {\n              type: \"text\",\n              text: lang,\n            },\n          ],\n        });\n      }\n      if (config.copyByClickCode) {\n        node.attrs.style += (node.attrs.style || \"\") + \";user-select:none\";\n        node.attrs[\"data-content\"] = text;\n        node.children.push({\n          name: \"div\",\n          attrs: {\n            class: \"hl-copy\",\n            style:\n              \"user-select:none;position:absolute;top:0;right:3px;font-size:10px;\",\n          },\n          // children: [{\n          //   type: 'text',\n          //   text: '复制'\n          // }]\n        });\n        vm.expose();\n      }\n      if (config.showLineNumber) {\n        const line = text.split(\"\\n\").length;\n        const children = [];\n        for (let k = line; k--; ) {\n          children.push({\n            name: \"span\",\n            attrs: {\n              class: \"span\",\n            },\n          });\n        }\n        node.children.push({\n          name: \"span\",\n          attrs: {\n            class: \"line-numbers-rows\",\n          },\n          children,\n        });\n      }\n    }\n  }\n};\n\nexport default Highlight;\n"
  },
  {
    "path": "src/uni_modules/zero-markdown-view/components/mp-html/latex/index.js",
    "content": "/**\n * @fileoverview latex 插件\n * katex.min.js来源 https://github.com/rojer95/katex-mini\n */\nimport parse from './katex.min'\n\nfunction Latex () {\n\n}\n\nLatex.prototype.onParse = function (node, vm) {\n  // $...$包裹的内容为latex公式\n  if (!vm.options.editable && node.type === 'text' && node.text.includes('$')) {\n    const part = node.text.split(/(\\${1,2})/)\n    const children = []\n    let status = 0\n    for (let i = 0; i < part.length; i++) {\n      if (i % 2 === 0) {\n        // 文本内容\n        if (part[i]) {\n          if (status === 0) {\n            children.push({\n              type: 'text',\n              text: part[i]\n            })\n          } else {\n            if (status === 1) {\n              // 行内公式\n              const nodes = parse.default(part[i])\n              children.push({\n                name: 'span',\n                attrs: {},\n                l: 'T',\n                f: 'display:inline-block',\n                children: nodes\n              })\n            } else {\n              // 块公式\n              const nodes = parse.default(part[i], {\n                displayMode: true\n              })\n              children.push({\n                name: 'div',\n                attrs: {\n                  style: 'text-align:center'\n                },\n                children: nodes\n              })\n            }\n          }\n        }\n      } else {\n        // 分隔符\n        if (part[i] === '$' && part[i + 2] === '$') {\n          // 行内公式\n          status = 1\n          part[i + 2] = ''\n        } else if (part[i] === '$$' && part[i + 2] === '$$') {\n          // 块公式\n          status = 2\n          part[i + 2] = ''\n        } else {\n          if (part[i] && part[i] !== '$$') {\n            // 普通$符号\n            part[i + 1] = part[i] + part[i + 1]\n          }\n          // 重置状态\n          status = 0\n        }\n      }\n    }\n    delete node.type\n    delete node.text\n    node.name = 'span'\n    node.attrs = {}\n    node.children = children\n  }\n}\n\nexport default Latex\n"
  },
  {
    "path": "src/uni_modules/zero-markdown-view/components/mp-html/markdown/index.js",
    "content": "/**\n * @fileoverview markdown 插件\n * Include marked (https://github.com/markedjs/marked)\n * Include github-markdown-css (https://github.com/sindresorhus/github-markdown-css)\n */\nimport marked from './marked.min'\nlet index = 0\n\nfunction Markdown (vm) {\n  this.vm = vm\n  vm._ids = {}\n}\n\nMarkdown.prototype.onUpdate = function (content) {\n  if (this.vm.markdown) {\n    return marked(content)\n  }\n}\n\nMarkdown.prototype.onParse = function (node, vm) {\n  if (vm.options.markdown) {\n    // 中文 id 需要转换，否则无法跳转\n    if (vm.options.useAnchor && node.attrs && /[\\u4e00-\\u9fa5]/.test(node.attrs.id)) {\n      const id = 't' + index++\n      this.vm._ids[node.attrs.id] = id\n      node.attrs.id = id\n    }\n    if (node.name === 'p' || node.name === 'table' || node.name === 'tr' || node.name === 'th' || node.name === 'td' || node.name === 'blockquote' || node.name === 'pre' || node.name === 'code') {\n      node.attrs.class = `md-${node.name} ${node.attrs.class || ''}`\n    }\n  }\n}\n\nexport default Markdown\n"
  },
  {
    "path": "src/uni_modules/zero-markdown-view/components/mp-html/mp-html.vue",
    "content": "<template>\n  <view id=\"_root\" :class=\"(selectable?'_select ':'')+'_root'\" :style=\"containerStyle\">\n    <slot v-if=\"!nodes[0]\" />\n    <!-- #ifndef APP-PLUS-NVUE -->\n    <node v-else :childs=\"nodes\" :opts=\"[lazyLoad,loadingImg,errorImg,showImgMenu,selectable]\" name=\"span\" />\n    <!-- #endif -->\n    <!-- #ifdef APP-PLUS-NVUE -->\n    <web-view ref=\"web\" src=\"/static/app-plus/mp-html/local.html\" :style=\"'margin-top:-2px;height:' + height + 'px'\" @onPostMessage=\"_onMessage\" />\n    <!-- #endif -->\n  </view>\n</template>\n\n<script>\n/**\n * mp-html v2.5.1\n * @description 富文本组件\n * @tutorial https://github.com/jin-yufeng/mp-html\n * @property {String} container-style 容器的样式\n * @property {String} content 用于渲染的 html 字符串\n * @property {Boolean} copy-link 是否允许外部链接被点击时自动复制\n * @property {String} domain 主域名，用于拼接链接\n * @property {String} error-img 图片出错时的占位图链接\n * @property {Boolean} lazy-load 是否开启图片懒加载\n * @property {string} loading-img 图片加载过程中的占位图链接\n * @property {Boolean} pause-video 是否在播放一个视频时自动暂停其他视频\n * @property {Boolean} preview-img 是否允许图片被点击时自动预览\n * @property {Boolean} scroll-table 是否给每个表格添加一个滚动层使其能单独横向滚动\n * @property {Boolean | String} selectable 是否开启长按复制\n * @property {Boolean} set-title 是否将 title 标签的内容设置到页面标题\n * @property {Boolean} show-img-menu 是否允许图片被长按时显示菜单\n * @property {Object} tag-style 标签的默认样式\n * @property {Boolean | Number} use-anchor 是否使用锚点链接\n * @event {Function} load dom 结构加载完毕时触发\n * @event {Function} ready 所有图片加载完毕时触发\n * @event {Function} imgtap 图片被点击时触发\n * @event {Function} linktap 链接被点击时触发\n * @event {Function} play 音视频播放时触发\n * @event {Function} error 媒体加载出错时触发\n */\n// #ifndef APP-PLUS-NVUE\nimport node from './node/node'\n// #endif\nimport Parser from './parser'\nimport markdown from './markdown/index.js'\nimport highlight from './highlight/index.js'\nimport latex from './latex/index.js'\nimport style from './style/index.js'\nconst plugins=[markdown,highlight,latex,style,]\n// #ifdef APP-PLUS-NVUE\nconst dom = weex.requireModule('dom')\n// #endif\nexport default {\n  name: 'mp-html',\n  data () {\n    return {\n      nodes: [],\n      // #ifdef APP-PLUS-NVUE\n      height: 3\n      // #endif\n    }\n  },\n  props: {\n    markdown: Boolean,\n    containerStyle: {\n      type: String,\n      default: ''\n    },\n    content: {\n      type: String,\n      default: ''\n    },\n    copyLink: {\n      type: [Boolean, String],\n      default: true\n    },\n    domain: String,\n    errorImg: {\n      type: String,\n      default: ''\n    },\n    lazyLoad: {\n      type: [Boolean, String],\n      default: false\n    },\n    loadingImg: {\n      type: String,\n      default: ''\n    },\n    pauseVideo: {\n      type: [Boolean, String],\n      default: true\n    },\n    previewImg: {\n      type: [Boolean, String],\n      default: true\n    },\n    scrollTable: [Boolean, String],\n    selectable: [Boolean, String],\n    setTitle: {\n      type: [Boolean, String],\n      default: true\n    },\n    showImgMenu: {\n      type: [Boolean, String],\n      default: true\n    },\n    tagStyle: Object,\n    useAnchor: [Boolean, Number]\n  },\n  // #ifdef VUE3\n  emits: ['load', 'ready', 'imgtap', 'linktap', 'play', 'error'],\n  // #endif\n  // #ifndef APP-PLUS-NVUE\n  components: {\n    node\n  },\n  // #endif\n  watch: {\n    content (content) {\n      this.setContent(content)\n    }\n  },\n  created () {\n    this.plugins = []\n    for (let i = plugins.length; i--;) {\n      this.plugins.push(new plugins[i](this))\n    }\n  },\n  mounted () {\n    if (this.content && !this.nodes.length) {\n      this.setContent(this.content)\n    }\n  },\n  beforeDestroy () {\n    this._hook('onDetached')\n  },\n  methods: {\n    /**\n     * @description 将锚点跳转的范围限定在一个 scroll-view 内\n     * @param {Object} page scroll-view 所在页面的示例\n     * @param {String} selector scroll-view 的选择器\n     * @param {String} scrollTop scroll-view scroll-top 属性绑定的变量名\n     */\n    in (page, selector, scrollTop) {\n      // #ifndef APP-PLUS-NVUE\n      if (page && selector && scrollTop) {\n        this._in = {\n          page,\n          selector,\n          scrollTop\n        }\n      }\n      // #endif\n    },\n\n    /**\n     * @description 锚点跳转\n     * @param {String} id 要跳转的锚点 id\n     * @param {Number} offset 跳转位置的偏移量\n     * @returns {Promise}\n     */\n    navigateTo (id, offset) {\n      id = this._ids[decodeURI(id)] || id\n      return new Promise((resolve, reject) => {\n        if (!this.useAnchor) {\n          reject(Error('Anchor is disabled'))\n          return\n        }\n        offset = offset || parseInt(this.useAnchor) || 0\n        // #ifdef APP-PLUS-NVUE\n        if (!id) {\n          dom.scrollToElement(this.$refs.web, {\n            offset\n          })\n          resolve()\n        } else {\n          this._navigateTo = {\n            resolve,\n            reject,\n            offset\n          }\n          this.$refs.web.evalJs('uni.postMessage({data:{action:\"getOffset\",offset:(document.getElementById(' + id + ')||{}).offsetTop}})')\n        }\n        // #endif\n        // #ifndef APP-PLUS-NVUE\n        let deep = ' '\n        // #ifdef MP-WEIXIN || MP-QQ || MP-TOUTIAO\n        deep = '>>>'\n        // #endif\n        const selector = uni.createSelectorQuery()\n          // #ifndef MP-ALIPAY\n          .in(this._in ? this._in.page : this)\n          // #endif\n          .select((this._in ? this._in.selector : '._root') + (id ? `${deep}#${id}` : '')).boundingClientRect()\n        if (this._in) {\n          selector.select(this._in.selector).scrollOffset()\n            .select(this._in.selector).boundingClientRect()\n        } else {\n          // 获取 scroll-view 的位置和滚动距离\n          selector.selectViewport().scrollOffset() // 获取窗口的滚动距离\n        }\n        selector.exec(res => {\n          if (!res[0]) {\n            reject(Error('Label not found'))\n            return\n          }\n          const scrollTop = res[1].scrollTop + res[0].top - (res[2] ? res[2].top : 0) + offset\n          if (this._in) {\n            // scroll-view 跳转\n            this._in.page[this._in.scrollTop] = scrollTop\n          } else {\n            // 页面跳转\n            uni.pageScrollTo({\n              scrollTop,\n              duration: 300\n            })\n          }\n          resolve()\n        })\n        // #endif\n      })\n    },\n\n    /**\n     * @description 获取文本内容\n     * @return {String}\n     */\n    getText (nodes) {\n      let text = '';\n      (function traversal (nodes) {\n        for (let i = 0; i < nodes.length; i++) {\n          const node = nodes[i]\n          if (node.type === 'text') {\n            text += node.text.replace(/&amp;/g, '&')\n          } else if (node.name === 'br') {\n            text += '\\n'\n          } else {\n            // 块级标签前后加换行\n            const isBlock = node.name === 'p' || node.name === 'div' || node.name === 'tr' || node.name === 'li' || (node.name[0] === 'h' && node.name[1] > '0' && node.name[1] < '7')\n            if (isBlock && text && text[text.length - 1] !== '\\n') {\n              text += '\\n'\n            }\n            // 递归获取子节点的文本\n            if (node.children) {\n              traversal(node.children)\n            }\n            if (isBlock && text[text.length - 1] !== '\\n') {\n              text += '\\n'\n            } else if (node.name === 'td' || node.name === 'th') {\n              text += '\\t'\n            }\n          }\n        }\n      })(nodes || this.nodes)\n      return text\n    },\n\n    /**\n     * @description 获取内容大小和位置\n     * @return {Promise}\n     */\n    getRect () {\n      return new Promise((resolve, reject) => {\n        uni.createSelectorQuery()\n          // #ifndef MP-ALIPAY\n          .in(this)\n          // #endif\n          .select('#_root').boundingClientRect().exec(res => res[0] ? resolve(res[0]) : reject(Error('Root label not found')))\n      })\n    },\n\n    /**\n     * @description 暂停播放媒体\n     */\n    pauseMedia () {\n      for (let i = (this._videos || []).length; i--;) {\n        this._videos[i].pause()\n      }\n      // #ifdef APP-PLUS\n      const command = 'for(var e=document.getElementsByTagName(\"video\"),i=e.length;i--;)e[i].pause()'\n      // #ifndef APP-PLUS-NVUE\n      let page = this.$parent\n      while (!page.$scope) page = page.$parent\n      page.$scope.$getAppWebview().evalJS(command)\n      // #endif\n      // #ifdef APP-PLUS-NVUE\n      this.$refs.web.evalJs(command)\n      // #endif\n      // #endif\n    },\n\n    /**\n     * @description 设置媒体播放速率\n     * @param {Number} rate 播放速率\n     */\n    setPlaybackRate (rate) {\n      this.playbackRate = rate\n      for (let i = (this._videos || []).length; i--;) {\n        this._videos[i].playbackRate(rate)\n      }\n      // #ifdef APP-PLUS\n      const command = 'for(var e=document.getElementsByTagName(\"video\"),i=e.length;i--;)e[i].playbackRate=' + rate\n      // #ifndef APP-PLUS-NVUE\n      let page = this.$parent\n      while (!page.$scope) page = page.$parent\n      page.$scope.$getAppWebview().evalJS(command)\n      // #endif\n      // #ifdef APP-PLUS-NVUE\n      this.$refs.web.evalJs(command)\n      // #endif\n      // #endif\n    },\n\n    /**\n     * @description 设置内容\n     * @param {String} content html 内容\n     * @param {Boolean} append 是否在尾部追加\n     */\n    setContent (content, append) {\n      if (!append || !this.imgList) {\n        this.imgList = []\n      }\n      const nodes = new Parser(this).parse(content)\n      // #ifdef APP-PLUS-NVUE\n      if (this._ready) {\n        this._set(nodes, append)\n      }\n      // #endif\n      this.$set(this, 'nodes', append ? (this.nodes || []).concat(nodes) : nodes)\n\n      // #ifndef APP-PLUS-NVUE\n      this._videos = []\n      this.$nextTick(() => {\n        this._hook('onLoad')\n        this.$emit('load')\n      })\n\n      if (this.lazyLoad || this.imgList._unloadimgs < this.imgList.length / 2) {\n        // 设置懒加载，每 350ms 获取高度，不变则认为加载完毕\n        let height = 0\n        const callback = rect => {\n          if (!rect || !rect.height) rect = {}\n          // 350ms 总高度无变化就触发 ready 事件\n          if (rect.height === height) {\n            this.$emit('ready', rect)\n          } else {\n            height = rect.height\n            setTimeout(() => {\n              this.getRect().then(callback).catch(callback)\n            }, 350)\n          }\n        }\n        this.getRect().then(callback).catch(callback)\n      } else {\n        // 未设置懒加载，等待所有图片加载完毕\n        if (!this.imgList._unloadimgs) {\n          this.getRect().then(rect => {\n            this.$emit('ready', rect)\n          }).catch(() => {\n            this.$emit('ready', {})\n          })\n        }\n      }\n      // #endif\n    },\n\n    /**\n     * @description 调用插件钩子函数\n     */\n    _hook (name) {\n      for (let i = plugins.length; i--;) {\n        if (this.plugins[i][name]) {\n          this.plugins[i][name]()\n        }\n      }\n    },\n\n    // #ifdef APP-PLUS-NVUE\n    /**\n     * @description 设置内容\n     */\n    _set (nodes, append) {\n      this.$refs.web.evalJs('setContent(' + JSON.stringify(nodes).replace(/%22/g, '') + ',' + JSON.stringify([this.containerStyle.replace(/(?:margin|padding)[^;]+/g, ''), this.errorImg, this.loadingImg, this.pauseVideo, this.scrollTable, this.selectable]) + ',' + append + ')')\n    },\n\n    /**\n     * @description 接收到 web-view 消息\n     */\n    _onMessage (e) {\n      const message = e.detail.data[0]\n      switch (message.action) {\n        // web-view 初始化完毕\n        case 'onJSBridgeReady':\n          this._ready = true\n          if (this.nodes) {\n            this._set(this.nodes)\n          }\n          break\n        // 内容 dom 加载完毕\n        case 'onLoad':\n          this.height = message.height\n          this._hook('onLoad')\n          this.$emit('load')\n          break\n        // 所有图片加载完毕\n        case 'onReady':\n          this.getRect().then(res => {\n            this.$emit('ready', res)\n          }).catch(() => {\n            this.$emit('ready', {})\n          })\n          break\n        // 总高度发生变化\n        case 'onHeightChange':\n          this.height = message.height\n          break\n        // 图片点击\n        case 'onImgTap':\n          this.$emit('imgtap', message.attrs)\n          if (this.previewImg) {\n            uni.previewImage({\n              current: parseInt(message.attrs.i),\n              urls: this.imgList\n            })\n          }\n          break\n        // 链接点击\n        case 'onLinkTap': {\n          const href = message.attrs.href\n          this.$emit('linktap', message.attrs)\n          if (href) {\n            // 锚点跳转\n            if (href[0] === '#') {\n              if (this.useAnchor) {\n                dom.scrollToElement(this.$refs.web, {\n                  offset: message.offset\n                })\n              }\n            } else if (href.includes('://')) {\n              // 打开外链\n              if (this.copyLink) {\n                plus.runtime.openWeb(href)\n              }\n            } else {\n              uni.navigateTo({\n                url: href,\n                fail () {\n                  uni.switchTab({\n                    url: href\n                  })\n                }\n              })\n            }\n          }\n          break\n        }\n        case 'onPlay':\n          this.$emit('play')\n          break\n        // 获取到锚点的偏移量\n        case 'getOffset':\n          if (typeof message.offset === 'number') {\n            dom.scrollToElement(this.$refs.web, {\n              offset: message.offset + this._navigateTo.offset\n            })\n            this._navigateTo.resolve()\n          } else {\n            this._navigateTo.reject(Error('Label not found'))\n          }\n          break\n        // 点击\n        case 'onClick':\n          this.$emit('tap')\n          this.$emit('click')\n          break\n        // 出错\n        case 'onError':\n          this.$emit('error', {\n            source: message.source,\n            attrs: message.attrs\n          })\n      }\n    }\n    // #endif\n  }\n}\n</script>\n\n<style>\n/* #ifndef APP-PLUS-NVUE */\n/* 根节点样式 */\n._root {\n  padding: 1px 0;\n  overflow-x: auto;\n  overflow-y: hidden;\n  -webkit-overflow-scrolling: touch;\n}\n\n/* 长按复制 */\n._select {\n  user-select: text;\n}\n/* #endif */\n</style>\n"
  },
  {
    "path": "src/uni_modules/zero-markdown-view/components/mp-html/node/node.vue",
    "content": "<template>\n  <view :id=\"attrs.id\" :class=\"'_block _'+name+' '+attrs.class\" :style=\"attrs.style\">\n    <block v-for=\"(n, i) in childs\" v-bind:key=\"i\">\n      <!-- 图片 -->\n      <!-- 占位图 -->\n      <image v-if=\"n.name==='img'&&!n.t&&((opts[1]&&!ctrl[i])||ctrl[i]<0)\" class=\"_img\" :style=\"n.attrs.style\" :src=\"ctrl[i]<0?opts[2]:opts[1]\" mode=\"widthFix\" />\n      <!-- 显示图片 -->\n      <!-- #ifdef H5 || (APP-PLUS && VUE2) -->\n      <img v-if=\"n.name==='img'\" :id=\"n.attrs.id\" :class=\"'_img '+n.attrs.class\" :style=\"(ctrl[i]===-1?'display:none;':'')+n.attrs.style\" :src=\"n.attrs.src||(ctrl.load?n.attrs['data-src']:'')\" :data-i=\"i\" @load=\"imgLoad\" @error=\"mediaError\" @tap.stop=\"imgTap\" @longpress=\"imgLongTap\" />\n      <!-- #endif -->\n      <!-- #ifndef H5 || (APP-PLUS && VUE2) -->\n      <!-- 表格中的图片，使用 rich-text 防止大小不正确 -->\n      <rich-text v-if=\"n.name==='img'&&n.t\" :style=\"'display:'+n.t\" :nodes=\"[{attrs:{style:n.attrs.style||'',src:n.attrs.src},name:'img'}]\" :data-i=\"i\" @tap.stop=\"imgTap\" />\n      <!-- #endif -->\n      <!-- #ifdef APP-HARMONY -->\n      <image v-else-if=\"n.name==='img'\" :id=\"n.attrs.id\" :class=\"'_img '+n.attrs.class\" :style=\"(ctrl[i]===-1?'display:none;':'')+'width:'+ctrl[i]+'px;'+n.attrs.style\" :src=\"n.attrs.src||(ctrl.load?n.attrs['data-src']:'')\" :mode=\"!n.h?'widthFix':(!n.w?'heightFix':(n.m||'scaleToFill'))\" :data-i=\"i\" @load=\"imgLoad\" @error=\"mediaError\" @tap.stop=\"imgTap\" @longpress=\"imgLongTap\" />\n      <!-- #endif -->\n      <!-- #ifndef H5 || APP-PLUS || MP-KUAISHOU -->\n      <image v-else-if=\"n.name==='img'\" :id=\"n.attrs.id\" :class=\"'_img '+n.attrs.class\" :style=\"(ctrl[i]===-1?'display:none;':'')+'width:'+(ctrl[i]||1)+'px;height:1px;'+n.attrs.style\" :src=\"n.attrs.src\" :mode=\"!n.h?'widthFix':(!n.w?'heightFix':(n.m||'scaleToFill'))\" :lazy-load=\"opts[0]\" :webp=\"n.webp\" :show-menu-by-longpress=\"opts[3]&&!n.attrs.ignore\" :image-menu-prevent=\"!opts[3]||n.attrs.ignore\" :data-i=\"i\" @load=\"imgLoad\" @error=\"mediaError\" @tap.stop=\"imgTap\" @longpress=\"imgLongTap\" />\n      <!-- #endif -->\n      <!-- #ifdef MP-KUAISHOU -->\n      <image v-else-if=\"n.name==='img'\" :id=\"n.attrs.id\" :class=\"'_img '+n.attrs.class\" :style=\"(ctrl[i]===-1?'display:none;':'')+n.attrs.style\" :src=\"n.attrs.src\" :lazy-load=\"opts[0]\" :data-i=\"i\" @load=\"imgLoad\" @error=\"mediaError\" @tap.stop=\"imgTap\"></image>\n      <!-- #endif -->\n      <!-- #ifdef APP-PLUS && VUE3 -->\n      <image v-else-if=\"n.name==='img'\" :id=\"n.attrs.id\" :class=\"'_img '+n.attrs.class\" :style=\"(ctrl[i]===-1?'display:none;':'')+'width:'+(ctrl[i]||1)+'px;'+n.attrs.style\" :src=\"n.attrs.src||(ctrl.load?n.attrs['data-src']:'')\" :mode=\"!n.h?'widthFix':(!n.w?'heightFix':(n.m||''))\" :data-i=\"i\" @load=\"imgLoad\" @error=\"mediaError\" @tap.stop=\"imgTap\" @longpress=\"imgLongTap\" />\n      <!-- #endif -->\n      <!-- 文本 -->\n      <!-- #ifdef MP-WEIXIN -->\n      <text v-else-if=\"n.text\" :user-select=\"opts[4]=='force'&&isiOS\" decode>{{n.text}}</text>\n      <!-- #endif -->\n      <!-- #ifndef MP-WEIXIN || MP-BAIDU || MP-ALIPAY || MP-TOUTIAO -->\n      <text v-else-if=\"n.text\" decode>{{n.text}}</text>\n      <!-- #endif -->\n      <text v-else-if=\"n.name==='br'\">\\n</text>\n      <!-- 链接 -->\n      <view v-else-if=\"n.name==='a'\" :id=\"n.attrs.id\" :class=\"(n.attrs.href?'_a ':'')+n.attrs.class\" hover-class=\"_hover\" :style=\"'display:inline;'+n.attrs.style\" :data-i=\"i\" @tap.stop=\"linkTap\">\n        <node name=\"span\" :childs=\"n.children\" :opts=\"opts\" style=\"display:inherit\" />\n      </view>\n      <!-- 视频 -->\n      <!-- #ifdef APP-PLUS -->\n      <view v-else-if=\"n.html\" :id=\"n.attrs.id\" :class=\"'_video '+n.attrs.class\" :style=\"n.attrs.style\" v-html=\"n.html\" :data-i=\"i\" @vplay.stop=\"play\" />\n      <!-- #endif -->\n      <!-- #ifndef APP-PLUS -->\n      <video v-else-if=\"n.name==='video'\" :id=\"n.attrs.id\" :class=\"n.attrs.class\" :style=\"n.attrs.style\" :autoplay=\"n.attrs.autoplay\" :controls=\"n.attrs.controls\" :loop=\"n.attrs.loop\" :muted=\"n.attrs.muted\" :object-fit=\"n.attrs['object-fit']\" :poster=\"n.attrs.poster\" :src=\"n.src[ctrl[i]||0]\" :data-i=\"i\" @play=\"play\" @error=\"mediaError\" />\n      <!-- #endif -->\n      <!-- #ifdef H5 || APP-PLUS -->\n      <iframe v-else-if=\"n.name==='iframe'\" :style=\"n.attrs.style\" :allowfullscreen=\"n.attrs.allowfullscreen\" :frameborder=\"n.attrs.frameborder\" :src=\"n.attrs.src\" />\n      <embed v-else-if=\"n.name==='embed'\" :style=\"n.attrs.style\" :src=\"n.attrs.src\" />\n      <!-- #endif -->\n      <!-- #ifndef MP-TOUTIAO || ((H5 || APP-PLUS) && VUE3) -->\n      <!-- 音频 -->\n      <audio v-else-if=\"n.name==='audio'\" :id=\"n.attrs.id\" :class=\"n.attrs.class\" :style=\"n.attrs.style\" :author=\"n.attrs.author\" :controls=\"n.attrs.controls\" :loop=\"n.attrs.loop\" :name=\"n.attrs.name\" :poster=\"n.attrs.poster\" :src=\"n.src[ctrl[i]||0]\" :data-i=\"i\" @play=\"play\" @error=\"mediaError\" />\n      <!-- #endif -->\n      <view v-else-if=\"(n.name==='table'&&n.c)||n.name==='li'\" :id=\"n.attrs.id\" :class=\"'_'+n.name+' '+n.attrs.class\" :style=\"n.attrs.style\">\n        <node v-if=\"n.name==='li'\" :childs=\"n.children\" :opts=\"opts\" />\n        <view v-else v-for=\"(tbody, x) in n.children\" v-bind:key=\"x\" :class=\"'_'+tbody.name+' '+tbody.attrs.class\" :style=\"tbody.attrs.style\">\n          <node v-if=\"tbody.name==='td'||tbody.name==='th'\" :childs=\"tbody.children\" :opts=\"opts\" />\n          <block v-else v-for=\"(tr, y) in tbody.children\" v-bind:key=\"y\">\n            <view v-if=\"tr.name==='td'||tr.name==='th'\" :class=\"'_'+tr.name+' '+tr.attrs.class\" :style=\"tr.attrs.style\">\n              <node :childs=\"tr.children\" :opts=\"opts\" />\n            </view>\n            <view v-else :class=\"'_'+tr.name+' '+tr.attrs.class\" :style=\"tr.attrs.style\">\n              <view v-for=\"(td, z) in tr.children\" v-bind:key=\"z\" :class=\"'_'+td.name+' '+td.attrs.class\" :style=\"td.attrs.style\">\n                <node :childs=\"td.children\" :opts=\"opts\" />\n              </view>\n            </view>\n          </block>\n        </view>\n      </view>\n      \n      <!-- 富文本 -->\n      <!-- #ifdef H5 || ((MP-WEIXIN || MP-QQ || APP-PLUS || MP-360) && VUE2) -->\n      <rich-text v-else-if=\"!n.c&&(n.l||!handler.isInline(n.name, n.attrs.style))\" :id=\"n.attrs.id\" :style=\"n.f\" :user-select=\"opts[4]\" :nodes=\"[n]\" @tap.stop='handleNodeClick(n)'/>\n      <!-- #endif -->\n      <!-- #ifndef H5 || ((MP-WEIXIN || MP-QQ || APP-PLUS || MP-360) && VUE2) -->\n      <rich-text v-else-if=\"!n.c\" :id=\"n.attrs.id\" :style=\"'display:inline;'+n.f\" :preview=\"false\" :selectable=\"opts[4]\" :user-select=\"opts[4]\" :nodes=\"[n]\" @tap.stop='handleNodeClick(n)'/>\n      <!-- #endif -->\n      <!-- 继续递归 -->\n      <view v-else-if=\"n.c===2\" :id=\"n.attrs.id\" :class=\"'_block _'+n.name+' '+n.attrs.class\" :style=\"n.f+';'+n.attrs.style\">\n        <node v-for=\"(n2, j) in n.children\" v-bind:key=\"j\" :style=\"n2.f\" :name=\"n2.name\" :attrs=\"n2.attrs\" :childs=\"n2.children\" :opts=\"opts\" />\n      </view>\n      <node v-else :style=\"n.f\" :name=\"n.name\" :attrs=\"n.attrs\" :childs=\"n.children\" :opts=\"opts\" />\n    </block>\n  </view>\n</template>\n<script module=\"handler\" lang=\"wxs\">\n// 行内标签列表\nvar inlineTags = {\n  abbr: true,\n  b: true,\n  big: true,\n  code: true,\n  del: true,\n  em: true,\n  i: true,\n  ins: true,\n  label: true,\n  q: true,\n  small: true,\n  span: true,\n  strong: true,\n  sub: true,\n  sup: true\n}\n/**\n * @description 判断是否为行内标签\n */\nmodule.exports = {\n  isInline: function (tagName, style) {\n    return inlineTags[tagName] || (style || '').indexOf('display:inline') !== -1\n  }\n}\n</script>\n<script>\n\nimport node from './node'\nexport default {\n  name: 'node',\n  options: {\n    // #ifdef MP-WEIXIN\n    virtualHost: true,\n    // #endif\n    // #ifdef MP-TOUTIAO\n    addGlobalClass: false\n    // #endif\n  },\n  data () {\n    return {\n      ctrl: {},\n      // #ifdef MP-WEIXIN\n      isiOS: uni.getSystemInfoSync().system.includes('iOS')\n      // #endif\n    }\n  },\n  props: {\n    name: String,\n    attrs: {\n      type: Object,\n      default () {\n        return {}\n      }\n    },\n    childs: Array,\n    opts: Array\n  },\n  components: {\n\n    // #ifndef ((H5 || APP-PLUS) && VUE3) || APP-HARMONY\n    node\n    // #endif\n  },\n  mounted () {\n    this.$nextTick(() => {\n      for (this.root = this.$parent; this.root.$options.name !== 'mp-html'; this.root = this.root.$parent);\n    })\n    // #ifdef H5 || APP-PLUS\n    if (this.opts[0]) {\n      let i\n      for (i = this.childs.length; i--;) {\n        if (this.childs[i].name === 'img') break\n      }\n      if (i !== -1) {\n        this.observer = uni.createIntersectionObserver(this).relativeToViewport({\n          top: 500,\n          bottom: 500\n        })\n        this.observer.observe('._img', res => {\n          if (res.intersectionRatio) {\n            this.$set(this.ctrl, 'load', 1)\n            this.observer.disconnect()\n          }\n        })\n      }\n    }\n    // #endif\n  },\n  beforeDestroy () {\n    // #ifdef H5 || APP-PLUS\n    if (this.observer) {\n      this.observer.disconnect()\n    }\n    // #endif\n  },\n  methods:{\n    \t  \t  handleNodeClick(e){\n\t  \t  \tif(e.attrs.class=='hl-pre'){\n\t  \t\t\tuni.setClipboardData({\n\t  \t\t\t\tdata: e.attrs['data-content'],\n\t  \t\t\t\tshowToast:false,\n\t  \t\t\t\tsuccess: () => {\n\t  \t\t\t\t\tuni.showToast({\n\t  \t\t\t\t\t\ttitle: '代码复制成功',\n\t  \t\t\t\t\t\tduration: 1000\n\t  \t\t\t\t\t});\n\t  \t\t\t\t},\n\t  \t\t\t\tfail: (err) => {\n\t  \t\t\t\t\tconsole.log('err', err);\n\t  \t\t\t\t}\n\t  \t\t\t});\n\t  \t  \t}\n\t  \t  },\n    // #ifdef MP-WEIXIN\n    toJSON () { return this },\n    // #endif\n    /**\n     * @description 播放视频事件\n     * @param {Event} e\n     */\n    play (e) {\n      const i = e.currentTarget.dataset.i\n      const node = this.childs[i]\n      this.root.$emit('play', {\n        source: node.name,\n        attrs: {\n          ...node.attrs,\n          src: node.src[this.ctrl[i] || 0]\n        }\n      })\n      // #ifndef APP-PLUS\n      if (this.root.pauseVideo) {\n        let flag = false\n        const id = e.target.id\n        for (let i = this.root._videos.length; i--;) {\n          if (this.root._videos[i].id === id) {\n            flag = true\n          } else {\n            this.root._videos[i].pause() // 自动暂停其他视频\n          }\n        }\n        // 将自己加入列表\n        if (!flag) {\n          const ctx = uni.createVideoContext(id\n            // #ifndef MP-BAIDU\n            , this\n            // #endif\n          )\n          ctx.id = id\n          if (this.root.playbackRate) {\n            ctx.playbackRate(this.root.playbackRate)\n          }\n          this.root._videos.push(ctx)\n        }\n      }\n      // #endif\n    },\n\n    /**\n     * @description 图片点击事件\n     * @param {Event} e\n     */\n    imgTap (e) {\n      const node = this.childs[e.currentTarget.dataset.i]\n      if (node.a) {\n        this.linkTap(node.a)\n        return\n      }\n      if (node.attrs.ignore) return\n      // #ifdef H5 || APP-PLUS\n      node.attrs.src = node.attrs.src || node.attrs['data-src']\n      // #endif\n      // #ifndef APP-HARMONY\n      this.root.$emit('imgtap', node.attrs)\n      // #endif\n      // #ifdef APP-HARMONY\n      this.root.$emit('imgtap', {\n        ...node.attrs\n      })\n      // #endif\n      // 自动预览图片\n      if (this.root.previewImg) {\n        uni.previewImage({\n          // #ifdef MP-WEIXIN\n          showmenu: this.root.showImgMenu,\n          // #endif\n          // #ifdef MP-ALIPAY\n          enablesavephoto: this.root.showImgMenu,\n          enableShowPhotoDownload: this.root.showImgMenu,\n          // #endif\n          current: parseInt(node.attrs.i),\n          urls: this.root.imgList\n        })\n      }\n    },\n\n    /**\n     * @description 图片长按\n     */\n    imgLongTap (e) {\n      // #ifdef APP-PLUS\n      const attrs = this.childs[e.currentTarget.dataset.i].attrs\n      if (this.opts[3] && !attrs.ignore) {\n        uni.showActionSheet({\n          itemList: ['保存图片'],\n          success: () => {\n            const save = path => {\n              uni.saveImageToPhotosAlbum({\n                filePath: path,\n                success () {\n                  uni.showToast({\n                    title: '保存成功'\n                  })\n                }\n              })\n            }\n            if (this.root.imgList[attrs.i].startsWith('http')) {\n              uni.downloadFile({\n                url: this.root.imgList[attrs.i],\n                success: res => save(res.tempFilePath)\n              })\n            } else {\n              save(this.root.imgList[attrs.i])\n            }\n          }\n        })\n      }\n      // #endif\n    },\n\n    /**\n     * @description 图片加载完成事件\n     * @param {Event} e\n     */\n    imgLoad (e) {\n      const i = e.currentTarget.dataset.i\n      /* #ifndef H5 || (APP-PLUS && VUE2) */\n      if (!this.childs[i].w) {\n        // 设置原宽度\n        this.$set(this.ctrl, i, e.detail.width)\n      } else /* #endif */ if ((this.opts[1] && !this.ctrl[i]) || this.ctrl[i] === -1) {\n        // 加载完毕，取消加载中占位图\n        this.$set(this.ctrl, i, 1)\n      }\n      this.checkReady()\n    },\n\n    /**\n     * @description 检查是否所有图片加载完毕\n     */\n    checkReady () {\n      if (this.root && !this.root.lazyLoad) {\n        this.root._unloadimgs -= 1\n        if (!this.root._unloadimgs) {\n          setTimeout(() => {\n            this.root.getRect().then(rect => {\n              this.root.$emit('ready', rect)\n            }).catch(() => {\n              this.root.$emit('ready', {})\n            })\n          }, 350)\n        }\n      }\n    },\n\n    /**\n     * @description 链接点击事件\n     * @param {Event} e\n     */\n    linkTap (e) {\n      const node = e.currentTarget ? this.childs[e.currentTarget.dataset.i] : {}\n      const attrs = node.attrs || e\n      const href = attrs.href\n      this.root.$emit('linktap', Object.assign({\n        innerText: this.root.getText(node.children || []) // 链接内的文本内容\n      }, attrs))\n      if (href) {\n        if (href[0] === '#') {\n          // 跳转锚点\n          this.root.navigateTo(href.substring(1)).catch(() => { })\n        } else if (href.split('?')[0].includes('://')) {\n          // 复制外部链接\n          if (this.root.copyLink) {\n            // #ifdef H5\n            window.open(href)\n            // #endif\n            // #ifdef MP\n            uni.setClipboardData({\n              data: href,\n              success: () =>\n                uni.showToast({\n                  title: '链接已复制'\n                })\n            })\n            // #endif\n            // #ifdef APP-PLUS\n            plus.runtime.openWeb(href)\n            // #endif\n          }\n        } else {\n          // 跳转页面\n          uni.navigateTo({\n            url: href,\n            fail () {\n              uni.switchTab({\n                url: href,\n                fail () { }\n              })\n            }\n          })\n        }\n      }\n    },\n\n    /**\n     * @description 错误事件\n     * @param {Event} e\n     */\n    mediaError (e) {\n      const i = e.currentTarget.dataset.i\n      const node = this.childs[i]\n      // 加载其他源\n      if (node.name === 'video' || node.name === 'audio') {\n        let index = (this.ctrl[i] || 0) + 1\n        if (index > node.src.length) {\n          index = 0\n        }\n        if (index < node.src.length) {\n          this.$set(this.ctrl, i, index)\n          return\n        }\n      } else if (node.name === 'img') {\n        // #ifdef H5 && VUE3\n        if (this.opts[0] && !this.ctrl.load) return\n        // #endif\n        // 显示错误占位图\n        if (this.opts[2]) {\n          this.$set(this.ctrl, i, -1)\n        }\n        this.checkReady()\n      }\n      if (this.root) {\n        this.root.$emit('error', {\n          source: node.name,\n          attrs: node.attrs,\n          // #ifndef H5 && VUE3\n          errMsg: e.detail.errMsg\n          // #endif\n        })\n      }\n    }\n  }\n}\n</script>\n<style>/deep/ .hl-code,/deep/ .hl-pre{color:#ccc;background:0 0;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}/deep/ .hl-pre{padding:1em;margin:.5em 0;overflow:auto}/deep/ .hl-pre{background:#2d2d2d}/deep/ .hl-block-comment,/deep/ .hl-cdata,/deep/ .hl-comment,/deep/ .hl-doctype,/deep/ .hl-prolog{color:#999}/deep/ .hl-punctuation{color:#ccc}/deep/ .hl-attr-name,/deep/ .hl-deleted,/deep/ .hl-namespace,/deep/ .hl-tag{color:#e2777a}/deep/ .hl-function-name{color:#6196cc}/deep/ .hl-boolean,/deep/ .hl-function,/deep/ .hl-number{color:#f08d49}/deep/ .hl-class-name,/deep/ .hl-constant,/deep/ .hl-property,/deep/ .hl-symbol{color:#f8c555}/deep/ .hl-atrule,/deep/ .hl-builtin,/deep/ .hl-important,/deep/ .hl-keyword,/deep/ .hl-selector{color:#cc99cd}/deep/ .hl-attr-value,/deep/ .hl-char,/deep/ .hl-regex,/deep/ .hl-string,/deep/ .hl-variable{color:#7ec699}/deep/ .hl-entity,/deep/ .hl-operator,/deep/ .hl-url{color:#67cdcc}/deep/ .hl-bold,/deep/ .hl-important{font-weight:700}/deep/ .hl-italic{font-style:italic}/deep/ .hl-entity{cursor:help}/deep/ .hl-inserted{color:green}@font-face{font-family:KaTeX_AMS;src:url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_AMS-Regular.woff2) format(\"woff2\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_AMS-Regular.woff) format(\"woff\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_AMS-Regular.ttf) format(\"truetype\");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Caligraphic;src:url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Caligraphic-Bold.woff2) format(\"woff2\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Caligraphic-Bold.woff) format(\"woff\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Caligraphic-Bold.ttf) format(\"truetype\");font-weight:700;font-style:normal}@font-face{font-family:KaTeX_Caligraphic;src:url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Caligraphic-Regular.woff2) format(\"woff2\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Caligraphic-Regular.woff) format(\"woff\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Caligraphic-Regular.ttf) format(\"truetype\");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Fraktur;src:url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Fraktur-Bold.woff2) format(\"woff2\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Fraktur-Bold.woff) format(\"woff\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Fraktur-Bold.ttf) format(\"truetype\");font-weight:700;font-style:normal}@font-face{font-family:KaTeX_Fraktur;src:url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Fraktur-Regular.woff2) format(\"woff2\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Fraktur-Regular.woff) format(\"woff\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Fraktur-Regular.ttf) format(\"truetype\");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Main;src:url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Main-Bold.woff2) format(\"woff2\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Main-Bold.woff) format(\"woff\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Main-Bold.ttf) format(\"truetype\");font-weight:700;font-style:normal}@font-face{font-family:KaTeX_Main;src:url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Main-BoldItalic.woff2) format(\"woff2\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Main-BoldItalic.woff) format(\"woff\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Main-BoldItalic.ttf) format(\"truetype\");font-weight:700;font-style:italic}@font-face{font-family:KaTeX_Main;src:url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Main-Italic.woff2) format(\"woff2\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Main-Italic.woff) format(\"woff\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Main-Italic.ttf) format(\"truetype\");font-weight:400;font-style:italic}@font-face{font-family:KaTeX_Main;src:url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Main-Regular.woff2) format(\"woff2\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Main-Regular.woff) format(\"woff\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Main-Regular.ttf) format(\"truetype\");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Math;src:url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Math-BoldItalic.woff2) format(\"woff2\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Math-BoldItalic.woff) format(\"woff\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Math-BoldItalic.ttf) format(\"truetype\");font-weight:700;font-style:italic}@font-face{font-family:KaTeX_Math;src:url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Math-Italic.woff2) format(\"woff2\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Math-Italic.woff) format(\"woff\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Math-Italic.ttf) format(\"truetype\");font-weight:400;font-style:italic}@font-face{font-family:KaTeX_SansSerif;src:url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_SansSerif-Bold.woff2) format(\"woff2\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_SansSerif-Bold.woff) format(\"woff\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_SansSerif-Bold.ttf) format(\"truetype\");font-weight:700;font-style:normal}@font-face{font-family:KaTeX_SansSerif;src:url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_SansSerif-Italic.woff2) format(\"woff2\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_SansSerif-Italic.woff) format(\"woff\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_SansSerif-Italic.ttf) format(\"truetype\");font-weight:400;font-style:italic}@font-face{font-family:KaTeX_SansSerif;src:url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_SansSerif-Regular.woff2) format(\"woff2\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_SansSerif-Regular.woff) format(\"woff\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_SansSerif-Regular.ttf) format(\"truetype\");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Script;src:url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Script-Regular.woff2) format(\"woff2\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Script-Regular.woff) format(\"woff\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Script-Regular.ttf) format(\"truetype\");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Size1;src:url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Size1-Regular.woff2) format(\"woff2\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Size1-Regular.woff) format(\"woff\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Size1-Regular.ttf) format(\"truetype\");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Size2;src:url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Size2-Regular.woff2) format(\"woff2\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Size2-Regular.woff) format(\"woff\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Size2-Regular.ttf) format(\"truetype\");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Size3;src:url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Size3-Regular.woff2) format(\"woff2\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Size3-Regular.woff) format(\"woff\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Size3-Regular.ttf) format(\"truetype\");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Size4;src:url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Size4-Regular.woff2) format(\"woff2\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Size4-Regular.woff) format(\"woff\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Size4-Regular.ttf) format(\"truetype\");font-weight:400;font-style:normal}@font-face{font-family:KaTeX_Typewriter;src:url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Typewriter-Regular.woff2) format(\"woff2\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Typewriter-Regular.woff) format(\"woff\"), url(https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/KaTeX/0.13.16/fonts/KaTeX_Typewriter-Regular.ttf) format(\"truetype\");font-weight:400;font-style:normal}/deep/ .katex{counter-reset:katexEqnNo mmlEqnNo;font:normal 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;text-indent:0;text-rendering:auto}/deep/ .katex text,/deep/ .katex view{-ms-high-contrast-adjust:none!important;border-color:currentColor}/deep/ .katex .katex-mathml{position:absolute;clip:rect(1px,1px,1px,1px);padding:0;border:0;height:1px;width:1px;overflow:hidden}/deep/ .katex .katex-html>.newline{display:block}/deep/ .katex .base{position:relative;display:inline-block;white-space:nowrap;width:min-content}/deep/ .katex .strut{display:inline-block}/deep/ .katex .textbf{font-weight:700}/deep/ .katex .textit{font-style:italic}/deep/ .katex .textrm{font-family:KaTeX_Main}/deep/ .katex .textsf{font-family:KaTeX_SansSerif}/deep/ .katex .texttt{font-family:KaTeX_Typewriter}/deep/ .katex .mathnormal{font-family:KaTeX_Math;font-style:italic}/deep/ .katex .mathit{font-family:KaTeX_Main;font-style:italic}/deep/ .katex .mathrm{font-style:normal}/deep/ .katex .mathbf{font-family:KaTeX_Main;font-weight:700}/deep/ .katex .boldsymbol{font-family:KaTeX_Math;font-weight:700;font-style:italic}/deep/ .katex .amsrm{font-family:KaTeX_AMS}/deep/ .katex .mathbb,/deep/ .katex .textbb{font-family:KaTeX_AMS}/deep/ .katex .mathcal{font-family:KaTeX_Caligraphic}/deep/ .katex .mathfrak,/deep/ .katex .textfrak{font-family:KaTeX_Fraktur}/deep/ .katex .mathtt{font-family:KaTeX_Typewriter}/deep/ .katex .mathscr,/deep/ .katex .textscr{font-family:KaTeX_Script}/deep/ .katex .mathsf,/deep/ .katex .textsf{font-family:KaTeX_SansSerif}/deep/ .katex .mathboldsf,/deep/ .katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}/deep/ .katex .mathitsf,/deep/ .katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}/deep/ .katex .mainrm{font-family:KaTeX_Main;font-style:normal}/deep/ .katex .vlist-t{display:inline-table;table-layout:fixed;border-collapse:collapse}/deep/ .katex .vlist-r{display:table-row}/deep/ .katex .vlist{display:table-cell;vertical-align:bottom;position:relative}/deep/ .katex .vlist>.katex-span{display:block;height:0;position:relative}/deep/ .katex .vlist>.katex-span>.katex-span{display:inline-block}/deep/ .katex .vlist>.katex-span>.pstrut{overflow:hidden;width:0}/deep/ .katex .vlist-t2{margin-right:-2px}/deep/ .katex .vlist-s{display:table-cell;vertical-align:bottom;font-size:1px;width:2px;min-width:2px}/deep/ .katex .vbox{display:inline-flex;flex-direction:column;align-items:baseline}/deep/ .katex .hbox{display:inline-flex;flex-direction:row;width:100%}/deep/ .katex .thinbox{display:inline-flex;flex-direction:row;width:0;max-width:0}/deep/ .katex .msupsub{text-align:left}/deep/ .katex .mfrac>.katex-span>.katex-span{text-align:center}/deep/ .katex .mfrac .frac-line{display:inline-block;width:100%;border-bottom-style:solid}/deep/ .katex .hdashline,/deep/ .katex .hline,/deep/ .katex .mfrac .frac-line,/deep/ .katex .overline .overline-line,/deep/ .katex .rule,/deep/ .katex .underline .underline-line{min-height:1px}/deep/ .katex .mspace{display:inline-block}/deep/ .katex .clap,/deep/ .katex .llap,/deep/ .katex .rlap{width:0;position:relative}/deep/ .katex .clap>.inner,/deep/ .katex .llap>.inner,/deep/ .katex .rlap>.inner{position:absolute}/deep/ .katex .clap>.fix,/deep/ .katex .llap>.fix,/deep/ .katex .rlap>.fix{display:inline-block}/deep/ .katex .llap>.inner{right:0}/deep/ .katex .clap>.inner,/deep/ .katex .rlap>.inner{left:0}/deep/ .katex .clap>.inner>.katex-span{margin-left:-50%;margin-right:50%}/deep/ .katex .rule{display:inline-block;border:solid 0;position:relative}/deep/ .katex .hline,/deep/ .katex .overline .overline-line,/deep/ .katex .underline .underline-line{display:inline-block;width:100%;border-bottom-style:solid}/deep/ .katex .hdashline{display:inline-block;width:100%;border-bottom-style:dashed}/deep/ .katex .sqrt>.root{margin-left:.27777778em;margin-right:-.55555556em}/deep/ .katex .fontsize-ensurer.reset-size1.size1,/deep/ .katex .sizing.reset-size1.size1{font-size:1em}/deep/ .katex .fontsize-ensurer.reset-size1.size2,/deep/ .katex .sizing.reset-size1.size2{font-size:1.2em}/deep/ .katex .fontsize-ensurer.reset-size1.size3,/deep/ .katex .sizing.reset-size1.size3{font-size:1.4em}/deep/ .katex .fontsize-ensurer.reset-size1.size4,/deep/ .katex .sizing.reset-size1.size4{font-size:1.6em}/deep/ .katex .fontsize-ensurer.reset-size1.size5,/deep/ .katex .sizing.reset-size1.size5{font-size:1.8em}/deep/ .katex .fontsize-ensurer.reset-size1.size6,/deep/ .katex .sizing.reset-size1.size6{font-size:2em}/deep/ .katex .fontsize-ensurer.reset-size1.size7,/deep/ .katex .sizing.reset-size1.size7{font-size:2.4em}/deep/ .katex .fontsize-ensurer.reset-size1.size8,/deep/ .katex .sizing.reset-size1.size8{font-size:2.88em}/deep/ .katex .fontsize-ensurer.reset-size1.size9,/deep/ .katex .sizing.reset-size1.size9{font-size:3.456em}/deep/ .katex .fontsize-ensurer.reset-size1.size10,/deep/ .katex .sizing.reset-size1.size10{font-size:4.148em}/deep/ .katex .fontsize-ensurer.reset-size1.size11,/deep/ .katex .sizing.reset-size1.size11{font-size:4.976em}/deep/ .katex .fontsize-ensurer.reset-size2.size1,/deep/ .katex .sizing.reset-size2.size1{font-size:.83333333em}/deep/ .katex .fontsize-ensurer.reset-size2.size2,/deep/ .katex .sizing.reset-size2.size2{font-size:1em}/deep/ .katex .fontsize-ensurer.reset-size2.size3,/deep/ .katex .sizing.reset-size2.size3{font-size:1.16666667em}/deep/ .katex .fontsize-ensurer.reset-size2.size4,/deep/ .katex .sizing.reset-size2.size4{font-size:1.33333333em}/deep/ .katex .fontsize-ensurer.reset-size2.size5,/deep/ .katex .sizing.reset-size2.size5{font-size:1.5em}/deep/ .katex .fontsize-ensurer.reset-size2.size6,/deep/ .katex .sizing.reset-size2.size6{font-size:1.66666667em}/deep/ .katex .fontsize-ensurer.reset-size2.size7,/deep/ .katex .sizing.reset-size2.size7{font-size:2em}/deep/ .katex .fontsize-ensurer.reset-size2.size8,/deep/ .katex .sizing.reset-size2.size8{font-size:2.4em}/deep/ .katex .fontsize-ensurer.reset-size2.size9,/deep/ .katex .sizing.reset-size2.size9{font-size:2.88em}/deep/ .katex .fontsize-ensurer.reset-size2.size10,/deep/ .katex .sizing.reset-size2.size10{font-size:3.45666667em}/deep/ .katex .fontsize-ensurer.reset-size2.size11,/deep/ .katex .sizing.reset-size2.size11{font-size:4.14666667em}/deep/ .katex .fontsize-ensurer.reset-size3.size1,/deep/ .katex .sizing.reset-size3.size1{font-size:.71428571em}/deep/ .katex .fontsize-ensurer.reset-size3.size2,/deep/ .katex .sizing.reset-size3.size2{font-size:.85714286em}/deep/ .katex .fontsize-ensurer.reset-size3.size3,/deep/ .katex .sizing.reset-size3.size3{font-size:1em}/deep/ .katex .fontsize-ensurer.reset-size3.size4,/deep/ .katex .sizing.reset-size3.size4{font-size:1.14285714em}/deep/ .katex .fontsize-ensurer.reset-size3.size5,/deep/ .katex .sizing.reset-size3.size5{font-size:1.28571429em}/deep/ .katex .fontsize-ensurer.reset-size3.size6,/deep/ .katex .sizing.reset-size3.size6{font-size:1.42857143em}/deep/ .katex .fontsize-ensurer.reset-size3.size7,/deep/ .katex .sizing.reset-size3.size7{font-size:1.71428571em}/deep/ .katex .fontsize-ensurer.reset-size3.size8,/deep/ .katex .sizing.reset-size3.size8{font-size:2.05714286em}/deep/ .katex .fontsize-ensurer.reset-size3.size9,/deep/ .katex .sizing.reset-size3.size9{font-size:2.46857143em}/deep/ .katex .fontsize-ensurer.reset-size3.size10,/deep/ .katex .sizing.reset-size3.size10{font-size:2.96285714em}/deep/ .katex .fontsize-ensurer.reset-size3.size11,/deep/ .katex .sizing.reset-size3.size11{font-size:3.55428571em}/deep/ .katex .fontsize-ensurer.reset-size4.size1,/deep/ .katex .sizing.reset-size4.size1{font-size:.625em}/deep/ .katex .fontsize-ensurer.reset-size4.size2,/deep/ .katex .sizing.reset-size4.size2{font-size:.75em}/deep/ .katex .fontsize-ensurer.reset-size4.size3,/deep/ .katex .sizing.reset-size4.size3{font-size:.875em}/deep/ .katex .fontsize-ensurer.reset-size4.size4,/deep/ .katex .sizing.reset-size4.size4{font-size:1em}/deep/ .katex .fontsize-ensurer.reset-size4.size5,/deep/ .katex .sizing.reset-size4.size5{font-size:1.125em}/deep/ .katex .fontsize-ensurer.reset-size4.size6,/deep/ .katex .sizing.reset-size4.size6{font-size:1.25em}/deep/ .katex .fontsize-ensurer.reset-size4.size7,/deep/ .katex .sizing.reset-size4.size7{font-size:1.5em}/deep/ .katex .fontsize-ensurer.reset-size4.size8,/deep/ .katex .sizing.reset-size4.size8{font-size:1.8em}/deep/ .katex .fontsize-ensurer.reset-size4.size9,/deep/ .katex .sizing.reset-size4.size9{font-size:2.16em}/deep/ .katex .fontsize-ensurer.reset-size4.size10,/deep/ .katex .sizing.reset-size4.size10{font-size:2.5925em}/deep/ .katex .fontsize-ensurer.reset-size4.size11,/deep/ .katex .sizing.reset-size4.size11{font-size:3.11em}/deep/ .katex .fontsize-ensurer.reset-size5.size1,/deep/ .katex .sizing.reset-size5.size1{font-size:.55555556em}/deep/ .katex .fontsize-ensurer.reset-size5.size2,/deep/ .katex .sizing.reset-size5.size2{font-size:.66666667em}/deep/ .katex .fontsize-ensurer.reset-size5.size3,/deep/ .katex .sizing.reset-size5.size3{font-size:.77777778em}/deep/ .katex .fontsize-ensurer.reset-size5.size4,/deep/ .katex .sizing.reset-size5.size4{font-size:.88888889em}/deep/ .katex .fontsize-ensurer.reset-size5.size5,/deep/ .katex .sizing.reset-size5.size5{font-size:1em}/deep/ .katex .fontsize-ensurer.reset-size5.size6,/deep/ .katex .sizing.reset-size5.size6{font-size:1.11111111em}/deep/ .katex .fontsize-ensurer.reset-size5.size7,/deep/ .katex .sizing.reset-size5.size7{font-size:1.33333333em}/deep/ .katex .fontsize-ensurer.reset-size5.size8,/deep/ .katex .sizing.reset-size5.size8{font-size:1.6em}/deep/ .katex .fontsize-ensurer.reset-size5.size9,/deep/ .katex .sizing.reset-size5.size9{font-size:1.92em}/deep/ .katex .fontsize-ensurer.reset-size5.size10,/deep/ .katex .sizing.reset-size5.size10{font-size:2.30444444em}/deep/ .katex .fontsize-ensurer.reset-size5.size11,/deep/ .katex .sizing.reset-size5.size11{font-size:2.76444444em}/deep/ .katex .fontsize-ensurer.reset-size6.size1,/deep/ .katex .sizing.reset-size6.size1{font-size:.5em}/deep/ .katex .fontsize-ensurer.reset-size6.size2,/deep/ .katex .sizing.reset-size6.size2{font-size:.6em}/deep/ .katex .fontsize-ensurer.reset-size6.size3,/deep/ .katex .sizing.reset-size6.size3{font-size:.7em}/deep/ .katex .fontsize-ensurer.reset-size6.size4,/deep/ .katex .sizing.reset-size6.size4{font-size:.8em}/deep/ .katex .fontsize-ensurer.reset-size6.size5,/deep/ .katex .sizing.reset-size6.size5{font-size:.9em}/deep/ .katex .fontsize-ensurer.reset-size6.size6,/deep/ .katex .sizing.reset-size6.size6{font-size:1em}/deep/ .katex .fontsize-ensurer.reset-size6.size7,/deep/ .katex .sizing.reset-size6.size7{font-size:1.2em}/deep/ .katex .fontsize-ensurer.reset-size6.size8,/deep/ .katex .sizing.reset-size6.size8{font-size:1.44em}/deep/ .katex .fontsize-ensurer.reset-size6.size9,/deep/ .katex .sizing.reset-size6.size9{font-size:1.728em}/deep/ .katex .fontsize-ensurer.reset-size6.size10,/deep/ .katex .sizing.reset-size6.size10{font-size:2.074em}/deep/ .katex .fontsize-ensurer.reset-size6.size11,/deep/ .katex .sizing.reset-size6.size11{font-size:2.488em}/deep/ .katex .fontsize-ensurer.reset-size7.size1,/deep/ .katex .sizing.reset-size7.size1{font-size:.41666667em}/deep/ .katex .fontsize-ensurer.reset-size7.size2,/deep/ .katex .sizing.reset-size7.size2{font-size:.5em}/deep/ .katex .fontsize-ensurer.reset-size7.size3,/deep/ .katex .sizing.reset-size7.size3{font-size:.58333333em}/deep/ .katex .fontsize-ensurer.reset-size7.size4,/deep/ .katex .sizing.reset-size7.size4{font-size:.66666667em}/deep/ .katex .fontsize-ensurer.reset-size7.size5,/deep/ .katex .sizing.reset-size7.size5{font-size:.75em}/deep/ .katex .fontsize-ensurer.reset-size7.size6,/deep/ .katex .sizing.reset-size7.size6{font-size:.83333333em}/deep/ .katex .fontsize-ensurer.reset-size7.size7,/deep/ .katex .sizing.reset-size7.size7{font-size:1em}/deep/ .katex .fontsize-ensurer.reset-size7.size8,/deep/ .katex .sizing.reset-size7.size8{font-size:1.2em}/deep/ .katex .fontsize-ensurer.reset-size7.size9,/deep/ .katex .sizing.reset-size7.size9{font-size:1.44em}/deep/ .katex .fontsize-ensurer.reset-size7.size10,/deep/ .katex .sizing.reset-size7.size10{font-size:1.72833333em}/deep/ .katex .fontsize-ensurer.reset-size7.size11,/deep/ .katex .sizing.reset-size7.size11{font-size:2.07333333em}/deep/ .katex .fontsize-ensurer.reset-size8.size1,/deep/ .katex .sizing.reset-size8.size1{font-size:.34722222em}/deep/ .katex .fontsize-ensurer.reset-size8.size2,/deep/ .katex .sizing.reset-size8.size2{font-size:.41666667em}/deep/ .katex .fontsize-ensurer.reset-size8.size3,/deep/ .katex .sizing.reset-size8.size3{font-size:.48611111em}/deep/ .katex .fontsize-ensurer.reset-size8.size4,/deep/ .katex .sizing.reset-size8.size4{font-size:.55555556em}/deep/ .katex .fontsize-ensurer.reset-size8.size5,/deep/ .katex .sizing.reset-size8.size5{font-size:.625em}/deep/ .katex .fontsize-ensurer.reset-size8.size6,/deep/ .katex .sizing.reset-size8.size6{font-size:.69444444em}/deep/ .katex .fontsize-ensurer.reset-size8.size7,/deep/ .katex .sizing.reset-size8.size7{font-size:.83333333em}/deep/ .katex .fontsize-ensurer.reset-size8.size8,/deep/ .katex .sizing.reset-size8.size8{font-size:1em}/deep/ .katex .fontsize-ensurer.reset-size8.size9,/deep/ .katex .sizing.reset-size8.size9{font-size:1.2em}/deep/ .katex .fontsize-ensurer.reset-size8.size10,/deep/ .katex .sizing.reset-size8.size10{font-size:1.44027778em}/deep/ .katex .fontsize-ensurer.reset-size8.size11,/deep/ .katex .sizing.reset-size8.size11{font-size:1.72777778em}/deep/ .katex .fontsize-ensurer.reset-size9.size1,/deep/ .katex .sizing.reset-size9.size1{font-size:.28935185em}/deep/ .katex .fontsize-ensurer.reset-size9.size2,/deep/ .katex .sizing.reset-size9.size2{font-size:.34722222em}/deep/ .katex .fontsize-ensurer.reset-size9.size3,/deep/ .katex .sizing.reset-size9.size3{font-size:.40509259em}/deep/ .katex .fontsize-ensurer.reset-size9.size4,/deep/ .katex .sizing.reset-size9.size4{font-size:.46296296em}/deep/ .katex .fontsize-ensurer.reset-size9.size5,/deep/ .katex .sizing.reset-size9.size5{font-size:.52083333em}/deep/ .katex .fontsize-ensurer.reset-size9.size6,/deep/ .katex .sizing.reset-size9.size6{font-size:.5787037em}/deep/ .katex .fontsize-ensurer.reset-size9.size7,/deep/ .katex .sizing.reset-size9.size7{font-size:.69444444em}/deep/ .katex .fontsize-ensurer.reset-size9.size8,/deep/ .katex .sizing.reset-size9.size8{font-size:.83333333em}/deep/ .katex .fontsize-ensurer.reset-size9.size9,/deep/ .katex .sizing.reset-size9.size9{font-size:1em}/deep/ .katex .fontsize-ensurer.reset-size9.size10,/deep/ .katex .sizing.reset-size9.size10{font-size:1.20023148em}/deep/ .katex .fontsize-ensurer.reset-size9.size11,/deep/ .katex .sizing.reset-size9.size11{font-size:1.43981481em}/deep/ .katex .fontsize-ensurer.reset-size10.size1,/deep/ .katex .sizing.reset-size10.size1{font-size:.24108004em}/deep/ .katex .fontsize-ensurer.reset-size10.size2,/deep/ .katex .sizing.reset-size10.size2{font-size:.28929605em}/deep/ .katex .fontsize-ensurer.reset-size10.size3,/deep/ .katex .sizing.reset-size10.size3{font-size:.33751205em}/deep/ .katex .fontsize-ensurer.reset-size10.size4,/deep/ .katex .sizing.reset-size10.size4{font-size:.38572806em}/deep/ .katex .fontsize-ensurer.reset-size10.size5,/deep/ .katex .sizing.reset-size10.size5{font-size:.43394407em}/deep/ .katex .fontsize-ensurer.reset-size10.size6,/deep/ .katex .sizing.reset-size10.size6{font-size:.48216008em}/deep/ .katex .fontsize-ensurer.reset-size10.size7,/deep/ .katex .sizing.reset-size10.size7{font-size:.57859209em}/deep/ .katex .fontsize-ensurer.reset-size10.size8,/deep/ .katex .sizing.reset-size10.size8{font-size:.69431051em}/deep/ .katex .fontsize-ensurer.reset-size10.size9,/deep/ .katex .sizing.reset-size10.size9{font-size:.83317261em}/deep/ .katex .fontsize-ensurer.reset-size10.size10,/deep/ .katex .sizing.reset-size10.size10{font-size:1em}/deep/ .katex .fontsize-ensurer.reset-size10.size11,/deep/ .katex .sizing.reset-size10.size11{font-size:1.19961427em}/deep/ .katex .fontsize-ensurer.reset-size11.size1,/deep/ .katex .sizing.reset-size11.size1{font-size:.20096463em}/deep/ .katex .fontsize-ensurer.reset-size11.size2,/deep/ .katex .sizing.reset-size11.size2{font-size:.24115756em}/deep/ .katex .fontsize-ensurer.reset-size11.size3,/deep/ .katex .sizing.reset-size11.size3{font-size:.28135048em}/deep/ .katex .fontsize-ensurer.reset-size11.size4,/deep/ .katex .sizing.reset-size11.size4{font-size:.32154341em}/deep/ .katex .fontsize-ensurer.reset-size11.size5,/deep/ .katex .sizing.reset-size11.size5{font-size:.36173633em}/deep/ .katex .fontsize-ensurer.reset-size11.size6,/deep/ .katex .sizing.reset-size11.size6{font-size:.40192926em}/deep/ .katex .fontsize-ensurer.reset-size11.size7,/deep/ .katex .sizing.reset-size11.size7{font-size:.48231511em}/deep/ .katex .fontsize-ensurer.reset-size11.size8,/deep/ .katex .sizing.reset-size11.size8{font-size:.57877814em}/deep/ .katex .fontsize-ensurer.reset-size11.size9,/deep/ .katex .sizing.reset-size11.size9{font-size:.69453376em}/deep/ .katex .fontsize-ensurer.reset-size11.size10,/deep/ .katex .sizing.reset-size11.size10{font-size:.83360129em}/deep/ .katex .fontsize-ensurer.reset-size11.size11,/deep/ .katex .sizing.reset-size11.size11{font-size:1em}/deep/ .katex .delimsizing.size1{font-family:KaTeX_Size1}/deep/ .katex .delimsizing.size2{font-family:KaTeX_Size2}/deep/ .katex .delimsizing.size3{font-family:KaTeX_Size3}/deep/ .katex .delimsizing.size4{font-family:KaTeX_Size4}/deep/ .katex .delimsizing.mult .delim-size1>.katex-span{font-family:KaTeX_Size1}/deep/ .katex .delimsizing.mult .delim-size4>.katex-span{font-family:KaTeX_Size4}/deep/ .katex .nulldelimiter{display:inline-block;width:.12em}/deep/ .katex .delimcenter{position:relative}/deep/ .katex .op-symbol{position:relative}/deep/ .katex .op-symbol.small-op{font-family:KaTeX_Size1}/deep/ .katex .op-symbol.large-op{font-family:KaTeX_Size2}/deep/ .katex .op-limits>.vlist-t{text-align:center}/deep/ .katex .accent>.vlist-t{text-align:center}/deep/ .katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}/deep/ .katex .overlay{display:block}/deep/ .katex .mtable .vertical-separator{display:inline-block;min-width:1px}/deep/ .katex .mtable .arraycolsep{display:inline-block}/deep/ .katex .mtable .col-align-c>.vlist-t{text-align:center}/deep/ .katex .mtable .col-align-l>.vlist-t{text-align:left}/deep/ .katex .mtable .col-align-r>.vlist-t{text-align:right}/deep/ .katex .svg-align{text-align:left}/deep/ .katex .katex-svg{display:block;position:absolute;width:100%;height:inherit;fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1}/deep/ .katex .katex-svg path{stroke:none}/deep/ .katex img{border-style:none;min-width:0;min-height:0;max-width:none;max-height:none}/deep/ .katex .stretchy{width:100%;display:block;position:relative;overflow:hidden}/deep/ .katex .stretchy::after,/deep/ .katex .stretchy::before{content:\"\"}/deep/ .katex .hide-tail{width:100%;position:relative;overflow:hidden}/deep/ .katex .halfarrow-left{position:absolute;left:0;width:50.2%;overflow:hidden}/deep/ .katex .halfarrow-right{position:absolute;right:0;width:50.2%;overflow:hidden}/deep/ .katex .brace-left{position:absolute;left:0;width:25.1%;overflow:hidden}/deep/ .katex .brace-center{position:absolute;left:25%;width:50%;overflow:hidden}/deep/ .katex .brace-right{position:absolute;right:0;width:25.1%;overflow:hidden}/deep/ .katex .x-arrow-pad{padding:0 .5em}/deep/ .katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}/deep/ .katex .mover,/deep/ .katex .munder,/deep/ .katex .x-arrow{text-align:center}/deep/ .katex .boxpad{padding:0 .3em}/deep/ .katex .fbox,/deep/ .katex .fcolorbox{box-sizing:border-box;border:.04em solid}/deep/ .katex .cancel-pad{padding:0 .2em}/deep/ .katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}/deep/ .katex .sout{border-bottom-style:solid;border-bottom-width:.08em}/deep/ .katex .angl{box-sizing:border-box;border-top:.049em solid;border-right:.049em solid;margin-right:.03889em}/deep/ .katex .anglpad{padding:0 .03889em}/deep/ .katex .eqn-num::before{counter-increment:katexEqnNo;content:\"(\" counter(katexEqnNo) \")\"}/deep/ .katex .mml-eqn-num::before{counter-increment:mmlEqnNo;content:\"(\" counter(mmlEqnNo) \")\"}/deep/ .katex .mtr-glue{width:50%}/deep/ .katex .cd-vert-arrow{display:inline-block;position:relative}/deep/ .katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}/deep/ .katex .cd-label-right{display:inline-block;position:absolute;left:calc(50% + .3em);text-align:right}/deep/ .katex-display{display:block;margin:1em 0;text-align:center}/deep/ .katex-display>.katex{display:block;text-align:center;white-space:nowrap}/deep/ .katex-display>.katex>.katex-html{display:block;position:relative}/deep/ .katex-display>.katex>.katex-html>.tag{position:absolute;right:0}/deep/ .katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}/deep/ .katex-display.fleqn>.katex{text-align:left;padding-left:2em}/deep/ .md-p {\n  margin-block-start: 1em;\n  margin-block-end: 1em;\n}\n\n/deep/ .md-table,\n/deep/ .md-blockquote {\n  margin-bottom: 16px;\n}\n\n/deep/ .md-table {\n  box-sizing: border-box;\n  width: 100%;\n  overflow: auto;\n  border-spacing: 0;\n  border-collapse: collapse;\n}\n\n/deep/ .md-tr {\n  background-color: #fff;\n  border-top: 1px solid #c6cbd1;\n}\n\n.md-table .md-tr:nth-child(2n) {\n  background-color: #f6f8fa;\n}\n\n/deep/ .md-th,\n/deep/ .md-td {\n  padding: 6px 13px !important;\n  border: 1px solid #dfe2e5;\n}\n\n/deep/ .md-th {\n  font-weight: 600;\n}\n\n/deep/ .md-blockquote {\n  padding: 0 1em;\n  color: #6a737d;\n  border-left: 0.25em solid #dfe2e5;\n}\n\n/deep/ .md-code {\n  padding: 0.2em 0.4em;\n  font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;\n  font-size: 85%;\n  background-color: rgba(27, 31, 35, 0.05);\n  border-radius: 3px;\n}\n\n/deep/ .md-pre .md-code {\n  padding: 0;\n  font-size: 100%;\n  background: transparent;\n  border: 0;\n}\n/* a 标签默认效果 */\n._a {\n  padding: 1.5px 0 1.5px 0;\n  color: #366092;\n  word-break: break-all;\n}\n\n/* a 标签点击态效果 */\n._hover {\n  text-decoration: underline;\n  opacity: 0.7;\n}\n\n/* 图片默认效果 */\n._img {\n  max-width: 100%;\n  -webkit-touch-callout: none;\n}\n\n/* 内部样式 */\n\n._block {\n  display: block;\n}\n\n._b,\n._strong {\n  font-weight: bold;\n}\n\n._code {\n  font-family: monospace;\n}\n\n._del {\n  text-decoration: line-through;\n}\n\n._em,\n._i {\n  font-style: italic;\n}\n\n._h1 {\n  font-size: 2em;\n}\n\n._h2 {\n  font-size: 1.5em;\n}\n\n._h3 {\n  font-size: 1.17em;\n}\n\n._h5 {\n  font-size: 0.83em;\n}\n\n._h6 {\n  font-size: 0.67em;\n}\n\n._h1,\n._h2,\n._h3,\n._h4,\n._h5,\n._h6 {\n  display: block;\n  font-weight: bold;\n}\n\n._image {\n  height: 1px;\n}\n\n._ins {\n  text-decoration: underline;\n}\n\n._li {\n  display: list-item;\n}\n\n._ol {\n  list-style-type: decimal;\n}\n\n._ol,\n._ul {\n  display: block;\n  padding-left: 40px;\n  margin: 1em 0;\n}\n\n._q::before {\n  content: '\"';\n}\n\n._q::after {\n  content: '\"';\n}\n\n._sub {\n  font-size: smaller;\n  vertical-align: sub;\n}\n\n._sup {\n  font-size: smaller;\n  vertical-align: super;\n}\n\n._thead,\n._tbody,\n._tfoot {\n  display: table-row-group;\n}\n\n._tr {\n  display: table-row;\n}\n\n._td,\n._th {\n  display: table-cell;\n  vertical-align: middle;\n}\n\n._th {\n  font-weight: bold;\n  text-align: center;\n}\n\n._ul {\n  list-style-type: disc;\n}\n\n._ul ._ul {\n  margin: 0;\n  list-style-type: circle;\n}\n\n._ul ._ul ._ul {\n  list-style-type: square;\n}\n\n._abbr,\n._b,\n._code,\n._del,\n._em,\n._i,\n._ins,\n._label,\n._q,\n._span,\n._strong,\n._sub,\n._sup {\n  display: inline;\n}\n\n/* #ifdef APP-PLUS */\n._video {\n  width: 300px;\n  height: 225px;\n}\n/* #endif */\n</style>"
  },
  {
    "path": "src/uni_modules/zero-markdown-view/components/mp-html/parser.js",
    "content": "/**\n * @fileoverview html 解析器\n */\n\n// 配置\nconst config = {\n  // 信任的标签（保持标签名不变）\n  trustTags: makeMap('a,abbr,ad,audio,b,blockquote,br,code,col,colgroup,dd,del,dl,dt,div,em,fieldset,h1,h2,h3,h4,h5,h6,hr,i,img,ins,label,legend,li,ol,p,q,ruby,rt,source,span,strong,sub,sup,table,tbody,td,tfoot,th,thead,tr,title,ul,video'),\n\n  // 块级标签（转为 div，其他的非信任标签转为 span）\n  blockTags: makeMap('address,article,aside,body,caption,center,cite,footer,header,html,nav,pre,section'),\n\n  // #ifdef (MP-WEIXIN || MP-QQ || APP-PLUS || MP-360) && VUE3\n  // 行内标签\n  inlineTags: makeMap('abbr,b,big,code,del,em,i,ins,label,q,small,span,strong,sub,sup'),\n  // #endif\n\n  // 要移除的标签\n  ignoreTags: makeMap('area,base,canvas,embed,frame,head,iframe,input,link,map,meta,param,rp,script,source,style,textarea,title,track,wbr'),\n\n  // 自闭合的标签\n  voidTags: makeMap('area,base,br,col,circle,ellipse,embed,frame,hr,img,input,line,link,meta,param,path,polygon,rect,source,track,use,wbr'),\n\n  // html 实体\n  entities: {\n    lt: '<',\n    gt: '>',\n    quot: '\"',\n    apos: \"'\",\n    ensp: '\\u2002',\n    emsp: '\\u2003',\n    nbsp: '\\xA0',\n    semi: ';',\n    ndash: '–',\n    mdash: '—',\n    middot: '·',\n    lsquo: '‘',\n    rsquo: '’',\n    ldquo: '“',\n    rdquo: '”',\n    bull: '•',\n    hellip: '…',\n    larr: '←',\n    uarr: '↑',\n    rarr: '→',\n    darr: '↓'\n  },\n\n  // 默认的标签样式\n  tagStyle: {\n    // #ifndef APP-PLUS-NVUE\n    address: 'font-style:italic',\n    big: 'display:inline;font-size:1.2em',\n    caption: 'display:table-caption;text-align:center',\n    center: 'text-align:center',\n    cite: 'font-style:italic',\n    dd: 'margin-left:40px',\n    mark: 'background-color:yellow',\n    pre: 'font-family:monospace;white-space:pre',\n    s: 'text-decoration:line-through',\n    small: 'display:inline;font-size:0.8em',\n    strike: 'text-decoration:line-through',\n    u: 'text-decoration:underline'\n    // #endif\n  },\n\n  // svg 大小写对照表\n  svgDict: {\n    animatetransform: 'animateTransform',\n    lineargradient: 'linearGradient',\n    viewbox: 'viewBox',\n    attributename: 'attributeName',\n    repeatcount: 'repeatCount',\n    repeatdur: 'repeatDur',\n    foreignobject: 'foreignObject'\n  }\n}\nconst tagSelector={}\nlet windowWidth, system\n// #ifdef MP-WEIXIN\nif (uni.canIUse('getWindowInfo')) {\n  windowWidth = uni.getWindowInfo().windowWidth\n  system = uni.getDeviceInfo().system\n} else {\n// #endif\n  const systemInfo = uni.getSystemInfoSync()\n  windowWidth = systemInfo.windowWidth\n  // #ifdef MP-WEIXIN\n  system = systemInfo.system\n}\n// #endif\nconst blankChar = makeMap(' ,\\r,\\n,\\t,\\f')\nlet idIndex = 0\n\n// #ifdef H5 || APP-PLUS\nconfig.ignoreTags.iframe = undefined\nconfig.trustTags.iframe = true\nconfig.ignoreTags.embed = undefined\nconfig.trustTags.embed = true\n// #endif\n// #ifdef APP-PLUS-NVUE\nconfig.ignoreTags.source = undefined\nconfig.ignoreTags.style = undefined\n// #endif\n\n/**\n * @description 创建 map\n * @param {String} str 逗号分隔\n */\nfunction makeMap (str) {\n  const map = Object.create(null)\n  const list = str.split(',')\n  for (let i = list.length; i--;) {\n    map[list[i]] = true\n  }\n  return map\n}\n\n/**\n * @description 解码 html 实体\n * @param {String} str 要解码的字符串\n * @param {Boolean} amp 要不要解码 &amp;\n * @returns {String} 解码后的字符串\n */\nfunction decodeEntity (str, amp) {\n  let i = str.indexOf('&')\n  while (i !== -1) {\n    const j = str.indexOf(';', i + 3)\n    let code\n    if (j === -1) break\n    if (str[i + 1] === '#') {\n      // &#123; 形式的实体\n      code = parseInt((str[i + 2] === 'x' ? '0' : '') + str.substring(i + 2, j))\n      if (!isNaN(code)) {\n        str = str.substr(0, i) + String.fromCharCode(code) + str.substr(j + 1)\n      }\n    } else {\n      // &nbsp; 形式的实体\n      code = str.substring(i + 1, j)\n      if (config.entities[code] || (code === 'amp' && amp)) {\n        str = str.substr(0, i) + (config.entities[code] || '&') + str.substr(j + 1)\n      }\n    }\n    i = str.indexOf('&', i + 1)\n  }\n  return str\n}\n\n/**\n * @description 合并多个块级标签，加快长内容渲染\n * @param {Array} nodes 要合并的标签数组\n */\nfunction mergeNodes (nodes) {\n  let i = nodes.length - 1\n  for (let j = i; j >= -1; j--) {\n    if (j === -1 || nodes[j].c || !nodes[j].name || (nodes[j].name !== 'div' && nodes[j].name !== 'p' && nodes[j].name[0] !== 'h') || (nodes[j].attrs.style || '').includes('inline')) {\n      if (i - j >= 5) {\n        nodes.splice(j + 1, i - j, {\n          name: 'div',\n          attrs: {},\n          children: nodes.slice(j + 1, i + 1)\n        })\n      }\n      i = j - 1\n    }\n  }\n}\n\n/**\n * @description html 解析器\n * @param {Object} vm 组件实例\n */\nfunction Parser (vm) {\n  this.options = vm || {}\n  this.tagStyle = Object.assign({}, config.tagStyle, this.options.tagStyle)\n  this.imgList = vm.imgList || []\n  this.imgList._unloadimgs = 0\n  this.plugins = vm.plugins || []\n  this.attrs = Object.create(null)\n  this.stack = []\n  this.nodes = []\n  this.pre = (this.options.containerStyle || '').includes('white-space') && this.options.containerStyle.includes('pre') ? 2 : 0\n}\n\n/**\n * @description 执行解析\n * @param {String} content 要解析的文本\n */\nParser.prototype.parse = function (content) {\n  // 插件处理\n  for (let i = this.plugins.length; i--;) {\n    if (this.plugins[i].onUpdate) {\n      content = this.plugins[i].onUpdate(content, config) || content\n    }\n  }\n\n  new Lexer(this).parse(content)\n  // 出栈未闭合的标签\n  while (this.stack.length) {\n    this.popNode()\n  }\n  if (this.nodes.length > 50) {\n    mergeNodes(this.nodes)\n  }\n  return this.nodes\n}\n\n/**\n * @description 将标签暴露出来（不被 rich-text 包含）\n */\nParser.prototype.expose = function () {\n  // #ifndef APP-PLUS-NVUE\n  for (let i = this.stack.length; i--;) {\n    const item = this.stack[i]\n    if (item.c || item.name === 'a' || item.name === 'video' || item.name === 'audio') return\n    item.c = 1\n  }\n  // #endif\n}\n\n/**\n * @description 处理插件\n * @param {Object} node 要处理的标签\n * @returns {Boolean} 是否要移除此标签\n */\nParser.prototype.hook = function (node) {\n  for (let i = this.plugins.length; i--;) {\n    if (this.plugins[i].onParse && this.plugins[i].onParse(node, this) === false) {\n      return false\n    }\n  }\n  return true\n}\n\n/**\n * @description 将链接拼接上主域名\n * @param {String} url 需要拼接的链接\n * @returns {String} 拼接后的链接\n */\nParser.prototype.getUrl = function (url) {\n  const domain = this.options.domain\n  if (url[0] === '/') {\n    if (url[1] === '/') {\n      // // 开头的补充协议名\n      url = (domain ? domain.split('://')[0] : 'http') + ':' + url\n    } else if (domain) {\n      // 否则补充整个域名\n      url = domain + url\n    } /* #ifdef APP-PLUS */ else {\n      url = plus.io.convertLocalFileSystemURL(url)\n    } /* #endif */\n  } else if (!url.includes('data:') && !url.includes('://')) {\n    if (domain) {\n      url = domain + '/' + url\n    } /* #ifdef APP-PLUS */ else {\n      url = plus.io.convertLocalFileSystemURL(url)\n    } /* #endif */\n  }\n  return url\n}\n\n/**\n * @description 解析样式表\n * @param {Object} node 标签\n * @returns {Object}\n */\nParser.prototype.parseStyle = function (node) {\n  const attrs = node.attrs\n  const list = (this.tagStyle[node.name] || '').split(';').concat((attrs.style || '').split(';'))\n  const styleObj = {}\n  let tmp = ''\n\n  if (attrs.id && !this.xml) {\n    // 暴露锚点\n    if (this.options.useAnchor) {\n      this.expose()\n    } else if (node.name !== 'img' && node.name !== 'a' && node.name !== 'video' && node.name !== 'audio') {\n      attrs.id = undefined\n    }\n  }\n\n  // 转换 width 和 height 属性\n  if (attrs.width) {\n    styleObj.width = parseFloat(attrs.width) + (attrs.width.includes('%') ? '%' : 'px')\n    attrs.width = undefined\n  }\n  if (attrs.height) {\n    styleObj.height = parseFloat(attrs.height) + (attrs.height.includes('%') ? '%' : 'px')\n    attrs.height = undefined\n  }\n\n  for (let i = 0, len = list.length; i < len; i++) {\n    const info = list[i].split(':')\n    if (info.length < 2) continue\n    const key = info.shift().trim().toLowerCase()\n    let value = info.join(':').trim()\n    if ((value[0] === '-' && value.lastIndexOf('-') > 0) || value.includes('safe')) {\n      // 兼容性的 css 不压缩\n      tmp += `;${key}:${value}`\n    } else if (!styleObj[key] || value.includes('import') || !styleObj[key].includes('import')) {\n      // 重复的样式进行覆盖\n      if (value.includes('url')) {\n        // 填充链接\n        let j = value.indexOf('(') + 1\n        if (j) {\n          while (value[j] === '\"' || value[j] === \"'\" || blankChar[value[j]]) {\n            j++\n          }\n          value = value.substr(0, j) + this.getUrl(value.substr(j))\n        }\n      } else if (value.includes('rpx')) {\n        // 转换 rpx（rich-text 内部不支持 rpx）\n        value = value.replace(/[0-9.]+\\s*rpx/g, $ => parseFloat($) * windowWidth / 750 + 'px')\n      }\n      styleObj[key] = value\n    }\n  }\n\n  node.attrs.style = tmp\n  return styleObj\n}\n\n/**\n * @description 解析到标签名\n * @param {String} name 标签名\n * @private\n */\nParser.prototype.onTagName = function (name) {\n  this.tagName = this.xml ? name : name.toLowerCase()\n  if (this.tagName === 'svg') {\n    this.xml = (this.xml || 0) + 1 // svg 标签内大小写敏感\n    config.ignoreTags.style = undefined // svg 标签内 style 可用\n  }\n}\n\n/**\n * @description 解析到属性名\n * @param {String} name 属性名\n * @private\n */\nParser.prototype.onAttrName = function (name) {\n  name = this.xml ? name : name.toLowerCase()\n  // #ifdef (VUE3 && (H5 || APP-PLUS)) || APP-PLUS-NVUE\n  if (name.includes('?') || name.includes(';')) {\n    this.attrName = undefined\n    return\n  }\n  // #endif\n  if (name.substr(0, 5) === 'data-') {\n    if (name === 'data-src' && !this.attrs.src) {\n      // data-src 自动转为 src\n      this.attrName = 'src'\n    } else if (this.tagName === 'img' || this.tagName === 'a') {\n      // a 和 img 标签保留 data- 的属性，可以在 imgtap 和 linktap 事件中使用\n      this.attrName = name\n    } else {\n      // 剩余的移除以减小大小\n      this.attrName = undefined\n    }\n  } else {\n    this.attrName = name\n    this.attrs[name] = 'T' // boolean 型属性缺省设置\n  }\n}\n\n/**\n * @description 解析到属性值\n * @param {String} val 属性值\n * @private\n */\nParser.prototype.onAttrVal = function (val) {\n  const name = this.attrName || ''\n  if (name === 'style' || name === 'href') {\n    // 部分属性进行实体解码\n    this.attrs[name] = decodeEntity(val, true)\n  } else if (name.includes('src')) {\n    // 拼接主域名\n    this.attrs[name] = this.getUrl(decodeEntity(val, true))\n  } else if (name) {\n    this.attrs[name] = val\n  }\n}\n\n/**\n * @description 解析到标签开始\n * @param {Boolean} selfClose 是否有自闭合标识 />\n * @private\n */\nParser.prototype.onOpenTag = function (selfClose) {\n  // 拼装 node\n  const node = Object.create(null)\n  node.name = this.tagName\n  node.attrs = this.attrs\n  // 避免因为自动 diff 使得 type 被设置为 null 导致部分内容不显示\n  if (this.options.nodes.length) {\n    node.type = 'node'\n  }\n  this.attrs = Object.create(null)\n\n  const attrs = node.attrs\n  const parent = this.stack[this.stack.length - 1]\n  const siblings = parent ? parent.children : this.nodes\n  const close = this.xml ? selfClose : config.voidTags[node.name]\n\n  // 替换标签名选择器\n  if (tagSelector[node.name]) {\n    attrs.class = tagSelector[node.name] + (attrs.class ? ' ' + attrs.class : '')\n  }\n\n  // 转换 embed 标签\n  if (node.name === 'embed') {\n    // #ifndef H5 || APP-PLUS\n    const src = attrs.src || ''\n    // 按照后缀名和 type 将 embed 转为 video 或 audio\n    if (src.includes('.mp4') || src.includes('.3gp') || src.includes('.m3u8') || (attrs.type || '').includes('video')) {\n      node.name = 'video'\n    } else if (src.includes('.mp3') || src.includes('.wav') || src.includes('.aac') || src.includes('.m4a') || (attrs.type || '').includes('audio')) {\n      node.name = 'audio'\n    }\n    if (attrs.autostart) {\n      attrs.autoplay = 'T'\n    }\n    attrs.controls = 'T'\n    // #endif\n    // #ifdef H5 || APP-PLUS\n    this.expose()\n    // #endif\n  }\n\n  // #ifndef APP-PLUS-NVUE\n  // 处理音视频\n  if (node.name === 'video' || node.name === 'audio') {\n    // 设置 id 以便获取 context\n    if (node.name === 'video' && !attrs.id) {\n      attrs.id = 'v' + idIndex++\n    }\n    // 没有设置 controls 也没有设置 autoplay 的自动设置 controls\n    if (!attrs.controls && !attrs.autoplay) {\n      attrs.controls = 'T'\n    }\n    // 用数组存储所有可用的 source\n    node.src = []\n    if (attrs.src) {\n      node.src.push(attrs.src)\n      attrs.src = undefined\n    }\n    this.expose()\n  }\n  // #endif\n\n  // 处理自闭合标签\n  if (close) {\n    if (!this.hook(node) || config.ignoreTags[node.name]) {\n      // 通过 base 标签设置主域名\n      if (node.name === 'base' && !this.options.domain) {\n        this.options.domain = attrs.href\n      } /* #ifndef APP-PLUS-NVUE */ else if (node.name === 'source' && parent && (parent.name === 'video' || parent.name === 'audio') && attrs.src) {\n        // 设置 source 标签（仅父节点为 video 或 audio 时有效）\n        parent.src.push(attrs.src)\n      } /* #endif */\n      return\n    }\n\n    // 解析 style\n    const styleObj = this.parseStyle(node)\n\n    // 处理图片\n    if (node.name === 'img') {\n      if (attrs.src) {\n        // 标记 webp\n        if (attrs.src.includes('webp')) {\n          node.webp = 'T'\n        }\n        // data url 图片如果没有设置 original-src 默认为不可预览的小图片\n        if (attrs.src.includes('data:') && this.options.previewImg !== 'all' && !attrs['original-src']) {\n          attrs.ignore = 'T'\n        }\n        if (!attrs.ignore || node.webp || attrs.src.includes('cloud://')) {\n          for (let i = this.stack.length; i--;) {\n            const item = this.stack[i]\n            if (item.name === 'a') {\n              node.a = item.attrs\n            }\n            if (item.name === 'table' && !node.webp && !attrs.src.includes('cloud://')) {\n              if (!styleObj.display || styleObj.display.includes('inline')) {\n                node.t = 'inline-block'\n              } else {\n                node.t = styleObj.display\n              }\n              styleObj.display = undefined\n            }\n            // #ifndef H5 || APP-PLUS\n            const style = item.attrs.style || ''\n            if (style.includes('flex:') && !style.includes('flex:0') && !style.includes('flex: 0') && (!styleObj.width || parseInt(styleObj.width) > 100)) {\n              styleObj.width = '100% !important'\n              styleObj.height = ''\n              for (let j = i + 1; j < this.stack.length; j++) {\n                this.stack[j].attrs.style = (this.stack[j].attrs.style || '').replace('inline-', '')\n              }\n            } else if (style.includes('flex') && styleObj.width === '100%') {\n              for (let j = i + 1; j < this.stack.length; j++) {\n                const style = this.stack[j].attrs.style || ''\n                if (!style.includes(';width') && !style.includes(' width') && style.indexOf('width') !== 0) {\n                  styleObj.width = ''\n                  break\n                }\n              }\n            } else if (style.includes('inline-block')) {\n              if (styleObj.width && styleObj.width[styleObj.width.length - 1] === '%') {\n                item.attrs.style += ';max-width:' + styleObj.width\n                styleObj.width = ''\n              } else {\n                item.attrs.style += ';max-width:100%'\n              }\n            }\n            // #endif\n            item.c = 1\n          }\n          attrs.i = this.imgList.length.toString()\n          let src = attrs['original-src'] || attrs.src\n          // #ifndef H5 || MP-ALIPAY || APP-PLUS || MP-360\n          if (this.imgList.includes(src)) {\n            // 如果有重复的链接则对域名进行随机大小写变换避免预览时错位\n            let i = src.indexOf('://')\n            if (i !== -1) {\n              i += 3\n              let newSrc = src.substr(0, i)\n              for (; i < src.length; i++) {\n                if (src[i] === '/') break\n                newSrc += Math.random() > 0.5 ? src[i].toUpperCase() : src[i]\n              }\n              newSrc += src.substr(i)\n              src = newSrc\n            }\n          }\n          // #endif\n          this.imgList.push(src)\n          if (!node.t) {\n            this.imgList._unloadimgs += 1\n          }\n          // #ifdef H5 || APP-PLUS\n          if (this.options.lazyLoad) {\n            attrs['data-src'] = attrs.src\n            attrs.src = undefined\n          }\n          // #endif\n        }\n      }\n      if (styleObj.display === 'inline') {\n        styleObj.display = ''\n      }\n      // #ifndef APP-PLUS-NVUE\n      if (attrs.ignore) {\n        styleObj['max-width'] = styleObj['max-width'] || '100%'\n        attrs.style += ';-webkit-touch-callout:none'\n      }\n      // #endif\n      // 设置的宽度超出屏幕，为避免变形，高度转为自动\n      if (parseInt(styleObj.width) > windowWidth) {\n        styleObj.height = undefined\n      }\n      // 记录是否设置了宽高\n      if (!isNaN(parseInt(styleObj.width))) {\n        node.w = 'T'\n      }\n      if (!isNaN(parseInt(styleObj.height)) && (!styleObj.height.includes('%') || (parent && (parent.attrs.style || '').includes('height')))) {\n        node.h = 'T'\n      }\n      if (node.w && node.h && styleObj['object-fit']) {\n        if (styleObj['object-fit'] === 'contain') {\n          node.m = 'aspectFit'\n        } else if (styleObj['object-fit'] === 'cover') {\n          node.m = 'aspectFill'\n        }\n      }\n    } else if (node.name === 'svg') {\n      siblings.push(node)\n      this.stack.push(node)\n      this.popNode()\n      return\n    }\n    for (const key in styleObj) {\n      if (styleObj[key]) {\n        attrs.style += `;${key}:${styleObj[key].replace(' !important', '')}`\n      }\n    }\n    attrs.style = attrs.style.substr(1) || undefined\n    // #ifdef (MP-WEIXIN || MP-QQ) && VUE3\n    if (!attrs.style) {\n      delete attrs.style\n    }\n    // #endif\n  } else {\n    if ((node.name === 'pre' || ((attrs.style || '').includes('white-space') && attrs.style.includes('pre'))) && this.pre !== 2) {\n      this.pre = node.pre = 1\n    }\n    node.children = []\n    this.stack.push(node)\n  }\n\n  // 加入节点树\n  siblings.push(node)\n}\n\n/**\n * @description 解析到标签结束\n * @param {String} name 标签名\n * @private\n */\nParser.prototype.onCloseTag = function (name) {\n  // 依次出栈到匹配为止\n  name = this.xml ? name : name.toLowerCase()\n  let i\n  for (i = this.stack.length; i--;) {\n    if (this.stack[i].name === name) break\n  }\n  if (i !== -1) {\n    while (this.stack.length > i) {\n      this.popNode()\n    }\n  } else if (name === 'p' || name === 'br') {\n    const siblings = this.stack.length ? this.stack[this.stack.length - 1].children : this.nodes\n    siblings.push({\n      name,\n      attrs: {\n        class: tagSelector[name] || '',\n        style: this.tagStyle[name] || ''\n      }\n    })\n  }\n}\n\n/**\n * @description 处理标签出栈\n * @private\n */\nParser.prototype.popNode = function () {\n  const node = this.stack.pop()\n  let attrs = node.attrs\n  const children = node.children\n  const parent = this.stack[this.stack.length - 1]\n  const siblings = parent ? parent.children : this.nodes\n\n  if (!this.hook(node) || config.ignoreTags[node.name]) {\n    // 获取标题\n    if (node.name === 'title' && children.length && children[0].type === 'text' && this.options.setTitle) {\n      uni.setNavigationBarTitle({\n        title: children[0].text\n      })\n    }\n    siblings.pop()\n    return\n  }\n\n  if (node.pre && this.pre !== 2) {\n    // 是否合并空白符标识\n    this.pre = node.pre = undefined\n    for (let i = this.stack.length; i--;) {\n      if (this.stack[i].pre) {\n        this.pre = 1\n      }\n    }\n  }\n\n  const styleObj = {}\n\n  // 转换 svg\n  if (node.name === 'svg') {\n    if (this.xml > 1) {\n      // 多层 svg 嵌套\n      this.xml--\n      return\n    }\n    // #ifdef APP-PLUS-NVUE\n    (function traversal (node) {\n      if (node.name) {\n        // 调整 svg 的大小写\n        node.name = config.svgDict[node.name] || node.name\n        for (const item in node.attrs) {\n          if (config.svgDict[item]) {\n            node.attrs[config.svgDict[item]] = node.attrs[item]\n            node.attrs[item] = undefined\n          }\n        }\n        for (let i = 0; i < (node.children || []).length; i++) {\n          traversal(node.children[i])\n        }\n      }\n    })(node)\n    // #endif\n    // #ifndef APP-PLUS-NVUE\n    let src = ''\n    const style = attrs.style\n    attrs.style = ''\n    attrs.xmlns = 'http://www.w3.org/2000/svg';\n    (function traversal (node) {\n      if (node.type === 'text') {\n        src += node.text\n        return\n      }\n      const name = config.svgDict[node.name] || node.name\n      if (name === 'foreignObject') {\n        for (const child of (node.children || [])) {\n          if (child.attrs && !child.attrs.xmlns) {\n            child.attrs.xmlns = 'http://www.w3.org/1999/xhtml'\n            break\n          }\n        }\n      }\n      src += '<' + name\n      for (const item in node.attrs) {\n        const val = node.attrs[item]\n        if (val) {\n          src += ` ${config.svgDict[item] || item}=\"${val.replace(/\"/g, '')}\"`\n        }\n      }\n      if (!node.children) {\n        src += '/>'\n      } else {\n        src += '>'\n        for (let i = 0; i < node.children.length; i++) {\n          traversal(node.children[i])\n        }\n        src += '</' + name + '>'\n      }\n    })(node)\n    node.name = 'img'\n    node.attrs = {\n      src: 'data:image/svg+xml;utf8,' + src.replace(/#/g, '%23'),\n      style,\n      ignore: 'T'\n    }\n    node.children = undefined\n    // #endif\n    this.xml = false\n    config.ignoreTags.style = true\n    return\n  }\n\n  // #ifndef APP-PLUS-NVUE\n  // 转换 align 属性\n  if (attrs.align) {\n    if (node.name === 'table') {\n      if (attrs.align === 'center') {\n        styleObj['margin-inline-start'] = styleObj['margin-inline-end'] = 'auto'\n      } else {\n        styleObj.float = attrs.align\n      }\n    } else {\n      styleObj['text-align'] = attrs.align\n    }\n    attrs.align = undefined\n  }\n\n  // 转换 dir 属性\n  if (attrs.dir) {\n    styleObj.direction = attrs.dir\n    attrs.dir = undefined\n  }\n\n  // 转换 font 标签的属性\n  if (node.name === 'font') {\n    if (attrs.color) {\n      styleObj.color = attrs.color\n      attrs.color = undefined\n    }\n    if (attrs.face) {\n      styleObj['font-family'] = attrs.face\n      attrs.face = undefined\n    }\n    if (attrs.size) {\n      let size = parseInt(attrs.size)\n      if (!isNaN(size)) {\n        if (size < 1) {\n          size = 1\n        } else if (size > 7) {\n          size = 7\n        }\n        styleObj['font-size'] = ['x-small', 'small', 'medium', 'large', 'x-large', 'xx-large', 'xxx-large'][size - 1]\n      }\n      attrs.size = undefined\n    }\n  }\n  // #endif\n\n  // 一些编辑器的自带 class\n  if ((attrs.class || '').includes('align-center')) {\n    styleObj['text-align'] = 'center'\n  }\n\n  Object.assign(styleObj, this.parseStyle(node))\n\n  if (node.name !== 'table' && parseInt(styleObj.width) > windowWidth) {\n    styleObj['max-width'] = '100%'\n    styleObj['box-sizing'] = 'border-box'\n  }\n\n  // #ifndef APP-PLUS-NVUE\n  if (config.blockTags[node.name]) {\n    node.name = 'div'\n  } else if (!config.trustTags[node.name] && !this.xml) {\n    // 未知标签转为 span，避免无法显示\n    node.name = 'span'\n  }\n\n  if (node.name === 'a' || node.name === 'ad'\n    // #ifdef H5 || APP-PLUS\n    || node.name === 'iframe' // eslint-disable-line\n    // #endif\n  ) {\n    this.expose()\n  } else if (node.name === 'video') {\n    if ((styleObj.height || '').includes('auto')) {\n      styleObj.height = undefined\n    }\n    /* #ifdef APP-PLUS */\n    let str = '<video style=\"width:100%;height:100%\"'\n    for (const item in attrs) {\n      if (attrs[item]) {\n        str += ' ' + item + '=\"' + attrs[item] + '\"'\n      }\n    }\n    if (this.options.pauseVideo) {\n      str += ' onplay=\"this.dispatchEvent(new CustomEvent(\\'vplay\\',{bubbles:!0}));for(var e=document.getElementsByTagName(\\'video\\'),t=0;t<e.length;t++)e[t]!=this&&e[t].pause()\"'\n    }\n    str += '>'\n    for (let i = 0; i < node.src.length; i++) {\n      str += '<source src=\"' + node.src[i] + '\">'\n    }\n    str += '</video>'\n    node.html = str\n    /* #endif */\n  } else if ((node.name === 'ul' || node.name === 'ol') && node.c) {\n    // 列表处理\n    const types = {\n      a: 'lower-alpha',\n      A: 'upper-alpha',\n      i: 'lower-roman',\n      I: 'upper-roman'\n    }\n    if (types[attrs.type]) {\n      attrs.style += ';list-style-type:' + types[attrs.type]\n      attrs.type = undefined\n    }\n    for (let i = children.length; i--;) {\n      if (children[i].name === 'li') {\n        children[i].c = 1\n      }\n    }\n  } else if (node.name === 'table') {\n    // 表格处理\n    // cellpadding、cellspacing、border 这几个常用表格属性需要通过转换实现\n    let padding = parseFloat(attrs.cellpadding)\n    let spacing = parseFloat(attrs.cellspacing)\n    const border = parseFloat(attrs.border)\n    const bordercolor = styleObj['border-color']\n    const borderstyle = styleObj['border-style']\n    if (node.c) {\n      // padding 和 spacing 默认 2\n      if (isNaN(padding)) {\n        padding = 2\n      }\n      if (isNaN(spacing)) {\n        spacing = 2\n      }\n    }\n    if (border) {\n      attrs.style += `;border:${border}px ${borderstyle || 'solid'} ${bordercolor || 'gray'}`\n    }\n    if (node.flag && node.c) {\n      // 有 colspan 或 rowspan 且含有链接的表格通过 grid 布局实现\n      styleObj.display = 'grid'\n      if (styleObj['border-collapse'] === 'collapse') {\n        styleObj['border-collapse'] = undefined\n        spacing = 0\n      }\n      if (spacing) {\n        styleObj['grid-gap'] = spacing + 'px'\n        styleObj.padding = spacing + 'px'\n      } else if (border) {\n        // 无间隔的情况下避免边框重叠\n        attrs.style += ';border-left:0;border-top:0'\n      }\n\n      const width = [] // 表格的列宽\n      const trList = [] // tr 列表\n      const cells = [] // 保存新的单元格\n      const map = {}; // 被合并单元格占用的格子\n\n      (function traversal (nodes) {\n        for (let i = 0; i < nodes.length; i++) {\n          if (nodes[i].name === 'tr') {\n            trList.push(nodes[i])\n          } else if (nodes[i].name === 'colgroup') {\n            let colI = 1\n            for (const col of (nodes[i].children || [])) {\n              if (col.name === 'col') {\n                const style = col.attrs.style || ''\n                const start = style.indexOf('width') ? style.indexOf(';width') : 0\n                // 提取出宽度\n                if (start !== -1) {\n                  let end = style.indexOf(';', start + 6)\n                  if (end === -1) {\n                    end = style.length\n                  }\n                  width[colI] = style.substring(start ? start + 7 : 6, end)\n                }\n                colI += 1\n              }\n            }\n          } else {\n            traversal(nodes[i].children || [])\n          }\n        }\n      })(children)\n\n      for (let row = 1; row <= trList.length; row++) {\n        let col = 1\n        for (let j = 0; j < trList[row - 1].children.length; j++) {\n          const td = trList[row - 1].children[j]\n          if (td.name === 'td' || td.name === 'th') {\n            // 这个格子被上面的单元格占用，则列号++\n            while (map[row + '.' + col]) {\n              col++\n            }\n            let style = td.attrs.style || ''\n            let start = style.indexOf('width') ? style.indexOf(';width') : 0\n            // 提取出 td 的宽度\n            if (start !== -1) {\n              let end = style.indexOf(';', start + 6)\n              if (end === -1) {\n                end = style.length\n              }\n              if (!td.attrs.colspan) {\n                width[col] = style.substring(start ? start + 7 : 6, end)\n              }\n              style = style.substr(0, start) + style.substr(end)\n            }\n            // 设置竖直对齐\n            style += ';display:flex'\n            start = style.indexOf('vertical-align')\n            if (start !== -1) {\n              const val = style.substr(start + 15, 10)\n              if (val.includes('middle')) {\n                style += ';align-items:center'\n              } else if (val.includes('bottom')) {\n                style += ';align-items:flex-end'\n              }\n            } else {\n              style += ';align-items:center'\n            }\n            // 设置水平对齐\n            start = style.indexOf('text-align')\n            if (start !== -1) {\n              const val = style.substr(start + 11, 10)\n              if (val.includes('center')) {\n                style += ';justify-content: center'\n              } else if (val.includes('right')) {\n                style += ';justify-content: right'\n              }\n            }\n            style = (border ? `;border:${border}px ${borderstyle || 'solid'} ${bordercolor || 'gray'}` + (spacing ? '' : ';border-right:0;border-bottom:0') : '') + (padding ? `;padding:${padding}px` : '') + ';' + style\n            // 处理列合并\n            if (td.attrs.colspan) {\n              style += `;grid-column-start:${col};grid-column-end:${col + parseInt(td.attrs.colspan)}`\n              if (!td.attrs.rowspan) {\n                style += `;grid-row-start:${row};grid-row-end:${row + 1}`\n              }\n              col += parseInt(td.attrs.colspan) - 1\n            }\n            // 处理行合并\n            if (td.attrs.rowspan) {\n              style += `;grid-row-start:${row};grid-row-end:${row + parseInt(td.attrs.rowspan)}`\n              if (!td.attrs.colspan) {\n                style += `;grid-column-start:${col};grid-column-end:${col + 1}`\n              }\n              // 记录下方单元格被占用\n              for (let rowspan = 1; rowspan < td.attrs.rowspan; rowspan++) {\n                for (let colspan = 0; colspan < (td.attrs.colspan || 1); colspan++) {\n                  map[(row + rowspan) + '.' + (col - colspan)] = 1\n                }\n              }\n            }\n            if (style) {\n              td.attrs.style = style\n            }\n            cells.push(td)\n            col++\n          }\n        }\n        if (row === 1) {\n          let temp = ''\n          for (let i = 1; i < col; i++) {\n            temp += (width[i] ? width[i] : 'auto') + ' '\n          }\n          styleObj['grid-template-columns'] = temp\n        }\n      }\n      node.children = cells\n    } else {\n      // 没有使用合并单元格的表格通过 table 布局实现\n      if (node.c) {\n        styleObj.display = 'table'\n      }\n      if (!isNaN(spacing)) {\n        styleObj['border-spacing'] = spacing + 'px'\n      }\n      if (border || padding) {\n        // 遍历\n        (function traversal (nodes) {\n          for (let i = 0; i < nodes.length; i++) {\n            const td = nodes[i]\n            if (td.name === 'th' || td.name === 'td') {\n              if (border) {\n                td.attrs.style = `border:${border}px ${borderstyle || 'solid'} ${bordercolor || 'gray'};${td.attrs.style || ''}`\n              }\n              if (padding) {\n                td.attrs.style = `padding:${padding}px;${td.attrs.style || ''}`\n              }\n            } else if (td.children) {\n              traversal(td.children)\n            }\n          }\n        })(children)\n      }\n    }\n    // 给表格添加一个单独的横向滚动层\n    if (this.options.scrollTable && !(attrs.style || '').includes('inline')) {\n      const table = Object.assign({}, node)\n      node.name = 'div'\n      node.attrs = {\n        style: 'overflow:auto'\n      }\n      node.children = [table]\n      attrs = table.attrs\n    }\n  } else if ((node.name === 'tbody' || node.name === 'tr') && node.flag && node.c) {\n    node.flag = undefined;\n    (function traversal (nodes) {\n      for (let i = 0; i < nodes.length; i++) {\n        if (nodes[i].name === 'td') {\n          // 颜色样式设置给单元格避免丢失\n          for (const style of ['color', 'background', 'background-color']) {\n            if (styleObj[style]) {\n              nodes[i].attrs.style = style + ':' + styleObj[style] + ';' + (nodes[i].attrs.style || '')\n            }\n          }\n        } else {\n          traversal(nodes[i].children || [])\n        }\n      }\n    })(children)\n  } else if ((node.name === 'td' || node.name === 'th') && (attrs.colspan || attrs.rowspan)) {\n    for (let i = this.stack.length; i--;) {\n      if (this.stack[i].name === 'table' || this.stack[i].name === 'tbody' || this.stack[i].name === 'tr') {\n        this.stack[i].flag = 1 // 指示含有合并单元格\n      }\n    }\n  } else if (node.name === 'ruby') {\n    // 转换 ruby\n    node.name = 'span'\n    for (let i = 0; i < children.length - 1; i++) {\n      if (children[i].type === 'text' && children[i + 1].name === 'rt') {\n        children[i] = {\n          name: 'div',\n          attrs: {\n            style: 'display:inline-block;text-align:center'\n          },\n          children: [{\n            name: 'div',\n            attrs: {\n              style: 'font-size:50%;' + (children[i + 1].attrs.style || '')\n            },\n            children: children[i + 1].children\n          }, children[i]]\n        }\n        children.splice(i + 1, 1)\n      }\n    }\n  } else if (node.c) {\n    (function traversal (node) {\n      node.c = 2\n      for (let i = node.children.length; i--;) {\n        const child = node.children[i]\n        // #ifdef (MP-WEIXIN || MP-QQ || APP-PLUS || MP-360) && VUE3\n        if (child.name && (config.inlineTags[child.name] || ((child.attrs.style || '').includes('inline') && child.children)) && !child.c) {\n          traversal(child)\n        }\n        // #endif\n        if (!child.c || child.name === 'table') {\n          node.c = 1\n        }\n      }\n    })(node)\n  }\n\n  if ((styleObj.display || '').includes('flex') && !node.c) {\n    for (let i = children.length; i--;) {\n      const item = children[i]\n      if (item.f) {\n        item.attrs.style = (item.attrs.style || '') + item.f\n        item.f = undefined\n      }\n    }\n  }\n  // flex 布局时部分样式需要提取到 rich-text 外层\n  const flex = parent && ((parent.attrs.style || '').includes('flex') || (parent.attrs.style || '').includes('grid'))\n    // #ifdef MP-WEIXIN\n    // 检查基础库版本 virtualHost 是否可用\n    && !(node.c && wx.getNFCAdapter) // eslint-disable-line\n    // #endif\n    // #ifndef MP-WEIXIN || MP-QQ || MP-BAIDU || MP-TOUTIAO\n    && !node.c // eslint-disable-line\n  // #endif\n  if (flex) {\n    node.f = ';max-width:100%'\n  }\n\n  if (children.length >= 50 && node.c && !(styleObj.display || '').includes('flex')) {\n    mergeNodes(children)\n  }\n  // #endif\n\n  for (const key in styleObj) {\n    if (styleObj[key]) {\n      const val = `;${key}:${styleObj[key].replace(' !important', '')}`\n      /* #ifndef APP-PLUS-NVUE */\n      if (flex && ((key.includes('flex') && key !== 'flex-direction') || key === 'align-self' || key.includes('grid') || styleObj[key][0] === '-' || (key.includes('width') && val.includes('%')))) {\n        node.f += val\n        if (key === 'width') {\n          attrs.style += ';width:100%'\n        }\n      } else /* #endif */ {\n        attrs.style += val\n      }\n    }\n  }\n  attrs.style = attrs.style.substr(1) || undefined\n  // #ifdef (MP-WEIXIN || MP-QQ) && VUE3\n  for (const key in attrs) {\n    if (!attrs[key]) {\n      delete attrs[key]\n    }\n  }\n  // #endif\n}\n\n/**\n * @description 解析到文本\n * @param {String} text 文本内容\n */\nParser.prototype.onText = function (text) {\n  if (!this.pre) {\n    // 合并空白符\n    let trim = ''\n    let flag\n    for (let i = 0, len = text.length; i < len; i++) {\n      if (!blankChar[text[i]]) {\n        trim += text[i]\n      } else {\n        if (trim[trim.length - 1] !== ' ') {\n          trim += ' '\n        }\n        if (text[i] === '\\n' && !flag) {\n          flag = true\n        }\n      }\n    }\n    // 去除含有换行符的空串\n    if (trim === ' ') {\n      if (flag) return\n      // #ifdef VUE3\n      else {\n        const parent = this.stack[this.stack.length - 1]\n        if (parent && parent.name[0] === 't') return\n      }\n      // #endif\n    }\n    text = trim\n  }\n  const node = Object.create(null)\n  node.type = 'text'\n  // #ifdef (MP-BAIDU || MP-ALIPAY || MP-TOUTIAO) && VUE3\n  node.attrs = {}\n  // #endif\n  node.text = decodeEntity(text)\n  if (this.hook(node)) {\n    // #ifdef MP-WEIXIN\n    if (this.options.selectable === 'force' && system.includes('iOS') && !uni.canIUse('rich-text.user-select')) {\n      this.expose()\n    }\n    // #endif\n    const siblings = this.stack.length ? this.stack[this.stack.length - 1].children : this.nodes\n    siblings.push(node)\n  }\n}\n\n/**\n * @description html 词法分析器\n * @param {Object} handler 高层处理器\n */\nfunction Lexer (handler) {\n  this.handler = handler\n}\n\n/**\n * @description 执行解析\n * @param {String} content 要解析的文本\n */\nLexer.prototype.parse = function (content) {\n  this.content = content || ''\n  this.i = 0 // 标记解析位置\n  this.start = 0 // 标记一个单词的开始位置\n  this.state = this.text // 当前状态\n  for (let len = this.content.length; this.i !== -1 && this.i < len;) {\n    this.state()\n  }\n}\n\n/**\n * @description 检查标签是否闭合\n * @param {String} method 如果闭合要进行的操作\n * @returns {Boolean} 是否闭合\n * @private\n */\nLexer.prototype.checkClose = function (method) {\n  const selfClose = this.content[this.i] === '/'\n  if (this.content[this.i] === '>' || (selfClose && this.content[this.i + 1] === '>')) {\n    if (method) {\n      this.handler[method](this.content.substring(this.start, this.i))\n    }\n    this.i += selfClose ? 2 : 1\n    this.start = this.i\n    this.handler.onOpenTag(selfClose)\n    if (this.handler.tagName === 'script') {\n      this.i = this.content.indexOf('</', this.i)\n      if (this.i !== -1) {\n        this.i += 2\n        this.start = this.i\n      }\n      this.state = this.endTag\n    } else {\n      this.state = this.text\n    }\n    return true\n  }\n  return false\n}\n\n/**\n * @description 文本状态\n * @private\n */\nLexer.prototype.text = function () {\n  this.i = this.content.indexOf('<', this.i) // 查找最近的标签\n  if (this.i === -1) {\n    // 没有标签了\n    if (this.start < this.content.length) {\n      this.handler.onText(this.content.substring(this.start, this.content.length))\n    }\n    return\n  }\n  const c = this.content[this.i + 1]\n  if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {\n    // 标签开头\n    if (this.start !== this.i) {\n      this.handler.onText(this.content.substring(this.start, this.i))\n    }\n    this.start = ++this.i\n    this.state = this.tagName\n  } else if (c === '/' || c === '!' || c === '?') {\n    if (this.start !== this.i) {\n      this.handler.onText(this.content.substring(this.start, this.i))\n    }\n    const next = this.content[this.i + 2]\n    if (c === '/' && ((next >= 'a' && next <= 'z') || (next >= 'A' && next <= 'Z'))) {\n      // 标签结尾\n      this.i += 2\n      this.start = this.i\n      this.state = this.endTag\n      return\n    }\n    // 处理注释\n    let end = '-->'\n    if (c !== '!' || this.content[this.i + 2] !== '-' || this.content[this.i + 3] !== '-') {\n      end = '>'\n    }\n    this.i = this.content.indexOf(end, this.i)\n    if (this.i !== -1) {\n      this.i += end.length\n      this.start = this.i\n    }\n  } else {\n    this.i++\n  }\n}\n\n/**\n * @description 标签名状态\n * @private\n */\nLexer.prototype.tagName = function () {\n  if (blankChar[this.content[this.i]]) {\n    // 解析到标签名\n    this.handler.onTagName(this.content.substring(this.start, this.i))\n    while (blankChar[this.content[++this.i]]);\n    if (this.i < this.content.length && !this.checkClose()) {\n      this.start = this.i\n      this.state = this.attrName\n    }\n  } else if (!this.checkClose('onTagName')) {\n    this.i++\n  }\n}\n\n/**\n * @description 属性名状态\n * @private\n */\nLexer.prototype.attrName = function () {\n  let c = this.content[this.i]\n  if (blankChar[c] || c === '=') {\n    // 解析到属性名\n    this.handler.onAttrName(this.content.substring(this.start, this.i))\n    let needVal = c === '='\n    const len = this.content.length\n    while (++this.i < len) {\n      c = this.content[this.i]\n      if (!blankChar[c]) {\n        if (this.checkClose()) return\n        if (needVal) {\n          // 等号后遇到第一个非空字符\n          this.start = this.i\n          this.state = this.attrVal\n          return\n        }\n        if (this.content[this.i] === '=') {\n          needVal = true\n        } else {\n          this.start = this.i\n          this.state = this.attrName\n          return\n        }\n      }\n    }\n  } else if (!this.checkClose('onAttrName')) {\n    this.i++\n  }\n}\n\n/**\n * @description 属性值状态\n * @private\n */\nLexer.prototype.attrVal = function () {\n  const c = this.content[this.i]\n  const len = this.content.length\n  if (c === '\"' || c === \"'\") {\n    // 有冒号的属性\n    this.start = ++this.i\n    this.i = this.content.indexOf(c, this.i)\n    if (this.i === -1) return\n    this.handler.onAttrVal(this.content.substring(this.start, this.i))\n  } else {\n    // 没有冒号的属性\n    for (; this.i < len; this.i++) {\n      if (blankChar[this.content[this.i]]) {\n        this.handler.onAttrVal(this.content.substring(this.start, this.i))\n        break\n      } else if (this.checkClose('onAttrVal')) return\n    }\n  }\n  while (blankChar[this.content[++this.i]]);\n  if (this.i < len && !this.checkClose()) {\n    this.start = this.i\n    this.state = this.attrName\n  }\n}\n\n/**\n * @description 结束标签状态\n * @returns {String} 结束的标签名\n * @private\n */\nLexer.prototype.endTag = function () {\n  const c = this.content[this.i]\n  if (blankChar[c] || c === '>' || c === '/') {\n    this.handler.onCloseTag(this.content.substring(this.start, this.i))\n    if (c !== '>') {\n      this.i = this.content.indexOf('>', this.i)\n      if (this.i === -1) return\n    }\n    this.start = ++this.i\n    this.state = this.text\n  } else {\n    this.i++\n  }\n}\n\nexport default Parser\n"
  },
  {
    "path": "src/uni_modules/zero-markdown-view/components/mp-html/style/index.js",
    "content": "/**\n * @fileoverview style 插件\n */\n// #ifndef APP-PLUS-NVUE\nimport Parser from './parser'\n// #endif\n\nfunction Style () {\n  this.styles = []\n}\n\n// #ifndef APP-PLUS-NVUE\nStyle.prototype.onParse = function (node, vm) {\n  // 获取样式\n  if (node.name === 'style' && node.children.length && node.children[0].type === 'text') {\n    this.styles = this.styles.concat(new Parser().parse(node.children[0].text))\n  } else if (node.name) {\n    // 匹配样式（对非文本标签）\n    // 存储不同优先级的样式 name < class < id < 后代\n    let matched = ['', '', '', '']\n    for (let i = 0, len = this.styles.length; i < len; i++) {\n      const item = this.styles[i]\n      let res = match(node, item.key || item.list[item.list.length - 1])\n      let j\n      if (res) {\n        // 后代选择器\n        if (!item.key) {\n          j = item.list.length - 2\n          for (let k = vm.stack.length; j >= 0 && k--;) {\n            // 子选择器\n            if (item.list[j] === '>') {\n              // 错误情况\n              if (j < 1 || j > item.list.length - 2) break\n              if (match(vm.stack[k], item.list[j - 1])) {\n                j -= 2\n              } else {\n                j++\n              }\n            } else if (match(vm.stack[k], item.list[j])) {\n              j--\n            }\n          }\n          res = 4\n        }\n        if (item.key || j < 0) {\n          // 添加伪类\n          if (item.pseudo && node.children) {\n            let text\n            item.style = item.style.replace(/content:([^;]+)/, (_, $1) => {\n              text = $1.replace(/['\"]/g, '')\n                // 处理 attr 函数\n                .replace(/attr\\((.+?)\\)/, (_, $1) => node.attrs[$1.trim()] || '')\n                // 编码 \\xxx\n                .replace(/\\\\(\\w{4})/, (_, $1) => String.fromCharCode(parseInt($1, 16)))\n              return ''\n            })\n            const pseudo = {\n              name: 'span',\n              attrs: {\n                style: item.style\n              },\n              children: [{\n                type: 'text',\n                text\n              }]\n            }\n            if (item.pseudo === 'before') {\n              node.children.unshift(pseudo)\n            } else {\n              node.children.push(pseudo)\n            }\n          } else {\n            matched[res - 1] += item.style + (item.style[item.style.length - 1] === ';' ? '' : ';')\n          }\n        }\n      }\n    }\n    matched = matched.join('')\n    if (matched.length > 2) {\n      node.attrs.style = matched + (node.attrs.style || '')\n    }\n  }\n}\n\n/**\n * @description 匹配样式\n * @param {object} node 要匹配的标签\n * @param {string|string[]} keys 选择器\n * @returns {number} 0：不匹配；1：name 匹配；2：class 匹配；3：id 匹配\n */\nfunction match (node, keys) {\n  function matchItem (key) {\n    if (key[0] === '#') {\n      // 匹配 id\n      if (node.attrs.id && node.attrs.id.trim() === key.substr(1)) return 3\n    } else if (key[0] === '.') {\n      // 匹配 class\n      key = key.substr(1)\n      const selectors = (node.attrs.class || '').split(' ')\n      for (let i = 0; i < selectors.length; i++) {\n        if (selectors[i].trim() === key) return 2\n      }\n    } else if (node.name === key) {\n      // 匹配 name\n      return 1\n    }\n    return 0\n  }\n\n  // 多选择器交集\n  if (keys instanceof Array) {\n    let res = 0\n    for (let j = 0; j < keys.length; j++) {\n      const tmp = matchItem(keys[j])\n      // 任意一个不匹配就失败\n      if (!tmp) return 0\n      // 优先级最大的一个作为最终优先级\n      if (tmp > res) {\n        res = tmp\n      }\n    }\n    return res\n  }\n\n  return matchItem(keys)\n}\n// #endif\n\nexport default Style\n"
  },
  {
    "path": "src/uni_modules/zero-markdown-view/components/mp-html/style/parser.js",
    "content": "const blank = {\n  ' ': true,\n  '\\n': true,\n  '\\t': true,\n  '\\r': true,\n  '\\f': true\n}\n\nfunction Parser () {\n  this.styles = []\n  this.selectors = []\n}\n\n/**\n * @description 解析 css 字符串\n * @param {string} content css 内容\n */\nParser.prototype.parse = function (content) {\n  new Lexer(this).parse(content)\n  return this.styles\n}\n\n/**\n * @description 解析到一个选择器\n * @param {string} name 名称\n */\nParser.prototype.onSelector = function (name) {\n  // 不支持的选择器\n  if (name.includes('[') || name.includes('*') || name.includes('@')) return\n  const selector = {}\n  // 伪类\n  if (name.includes(':')) {\n    const info = name.split(':')\n    const pseudo = info.pop()\n    if (pseudo === 'before' || pseudo === 'after') {\n      selector.pseudo = pseudo\n      name = info[0]\n    } else return\n  }\n\n  // 分割交集选择器\n  function splitItem (str) {\n    const arr = []\n    let i, start\n    for (i = 1, start = 0; i < str.length; i++) {\n      if (str[i] === '.' || str[i] === '#') {\n        arr.push(str.substring(start, i))\n        start = i\n      }\n    }\n    if (!arr.length) {\n      return str\n    } else {\n      arr.push(str.substring(start, i))\n      return arr\n    }\n  }\n\n  // 后代选择器\n  if (name.includes(' ')) {\n    selector.list = []\n    const list = name.split(' ')\n    for (let i = 0; i < list.length; i++) {\n      if (list[i].length) {\n        // 拆分子选择器\n        const arr = list[i].split('>')\n        for (let j = 0; j < arr.length; j++) {\n          selector.list.push(splitItem(arr[j]))\n          if (j < arr.length - 1) {\n            selector.list.push('>')\n          }\n        }\n      }\n    }\n  } else {\n    selector.key = splitItem(name)\n  }\n\n  this.selectors.push(selector)\n}\n\n/**\n * @description 解析到选择器内容\n * @param {string} content 内容\n */\nParser.prototype.onContent = function (content) {\n  // 并集选择器\n  for (let i = 0; i < this.selectors.length; i++) {\n    this.selectors[i].style = content\n  }\n  this.styles = this.styles.concat(this.selectors)\n  this.selectors = []\n}\n\n/**\n * @description css 词法分析器\n * @param {object} handler 高层处理器\n */\nfunction Lexer (handler) {\n  this.selector = ''\n  this.style = ''\n  this.handler = handler\n}\n\nLexer.prototype.parse = function (content) {\n  this.i = 0\n  this.content = content\n  this.state = this.blank\n  for (let len = content.length; this.i < len; this.i++) {\n    this.state(content[this.i])\n  }\n}\n\nLexer.prototype.comment = function () {\n  this.i = this.content.indexOf('*/', this.i) + 1\n  if (!this.i) {\n    this.i = this.content.length\n  }\n}\n\nLexer.prototype.blank = function (c) {\n  if (!blank[c]) {\n    if (c === '/' && this.content[this.i + 1] === '*') {\n      this.comment()\n      return\n    }\n    this.selector += c\n    this.state = this.name\n  }\n}\n\nLexer.prototype.name = function (c) {\n  if (c === '/' && this.content[this.i + 1] === '*') {\n    this.comment()\n    return\n  }\n  if (c === '{' || c === ',' || c === ';') {\n    this.handler.onSelector(this.selector.trimEnd())\n    this.selector = ''\n    if (c !== '{') {\n      while (blank[this.content[++this.i]]);\n    }\n    if (this.content[this.i] === '{') {\n      this.floor = 1\n      this.state = this.val\n    } else {\n      this.selector += this.content[this.i]\n    }\n  } else if (blank[c]) {\n    this.selector += ' '\n  } else {\n    this.selector += c\n  }\n}\n\nLexer.prototype.val = function (c) {\n  if (c === '/' && this.content[this.i + 1] === '*') {\n    this.comment()\n    return\n  }\n  if (c === '{') {\n    this.floor++\n  } else if (c === '}') {\n    this.floor--\n    if (!this.floor) {\n      this.handler.onContent(this.style)\n      this.style = ''\n      this.state = this.blank\n      return\n    }\n  }\n  this.style += c\n}\n\nexport default Parser\n"
  },
  {
    "path": "src/uni_modules/zero-markdown-view/components/zero-markdown-view/zero-markdown-view.vue",
    "content": "<template>\n\t<view class=\"zero-markdown-view\">\n\t\t<mp-html :key=\"mpkey\" :selectable=\"selectable\" :scroll-table='scrollTable' :tag-style=\"tagStyle\"\n\t\t\t:markdown=\"true\" :content=\"contentAi\">\n\t\t</mp-html>\n\t</view>\n</template>\n\n<script>\nimport mpHtml from '../mp-html/mp-html';\n\n\nexport default {\n\tname: 'zero-markdown-view',\n\tcomponents: {\n\t\tmpHtml\n\t},\n\tprops: {\n\t\tmarkdown: {\n\t\t\ttype: String,\n\t\t\tdefault: ''\n\t\t},\n\t\tselectable: {\n\t\t\ttype: [Boolean, String],\n\t\t\tdefault: true\n\t\t},\n\t\tscrollTable: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true\n\t\t},\n\t\tthemeColor: {\n\t\t\ttype: String,\n\t\t\tdefault: '#007AFF'\n\t\t},\n\t\tcodeBgColor: {\n\t\t\ttype: String,\n\t\t\tdefault: '#2d2d2d'\n\t\t},\n\t\taiMode: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false\n\t\t}\n\t},\n\tdata() {\n\t\treturn {\n\t\t\tcontent: '',\n\t\t\ttagStyle: '',\n\t\t\tmpkey: 'zero'\n\t\t};\n\t},\n\tcomputed: {\n\t\tcontentAi() {\n\t\t\tif (!this.content) {\n\t\t\t\treturn //处理特殊情况，比如网络异常导致的响应的 content 的值为空\n\t\t\t}\n\t\t\tlet htmlString = ''\n\t\t\t// 检查是否有未闭合的代码块\n\t\t\tconst codeBlocks = this.content.match(/```[\\s\\S]*?```|```[\\s\\S]*?$/g) || []\n\t\t\tconst lastBlock = codeBlocks[codeBlocks.length - 1]\n\t\t\tif (lastBlock && !lastBlock.endsWith('```')) {\n\t\t\t\t// 最后一个代码块未闭合,需要补上结束标识符\n\t\t\t\thtmlString = this.content + '\\n'\n\t\t\t} else {\n\t\t\t\thtmlString = this.content\n\t\t\t}\n\t\t\treturn htmlString\n\t\t},\n\t},\n\twatch: {\n\t\tmarkdown: function (val) {\n\t\t\tthis.content = this.markdown\n\t\t}\n\t},\n\tcreated() {\n\t\tif (this.aiMode) {\n\t\t\tthis.initTagStyleForAi();\n\t\t} else {\n\t\t\tthis.initTagStyle();\n\t\t}\n\t},\n\tmounted() {\n\t\tthis.content = this.markdown\n\t},\n\n\tmethods: {\n\n\t\tinitTagStyle() {\n\t\t\tconst themeColor = this.themeColor\n\t\t\tconst codeBgColor = this.codeBgColor\n\t\t\tlet zeroStyle = {\n\t\t\t\tp: `\n\t\t\t\tmargin:5px 5px;\n\t\t\t\tfont-size: 15px;\n\t\t\t\tline-height:1.75;\n\t\t\t\tletter-spacing:0.2em;\n\t\t\t\tword-spacing:0.1em;\n\t\t\t\t`,\n\t\t\t\t// 一级标题\n\t\t\t\th1: `\n\t\t\t\tmargin:25px 0;\n\t\t\t\tfont-size: 24px;\n\t\t\t\ttext-align: center;\n\t\t\t\tfont-weight: bold;\n\t\t\t\tcolor: ${themeColor};\n\t\t\t\tpadding:3px 10px 1px;\n\t\t\t\tborder-bottom: 2px solid ${themeColor};\n\t\t\t\tborder-top-right-radius:3px;\n\t\t\t\tborder-top-left-radius:3px;\n\t\t\t\t`,\n\t\t\t\t// 二级标题\n\t\t\t\th2: `\n\t\t\t\tmargin:40px 0 20px 0;\t\n\t\t\t\tfont-size: 20px;\n\t\t\t\ttext-align:center;\n\t\t\t\tcolor:${themeColor};\n\t\t\t\tfont-weight:bolder;\n\t\t\t\tpadding-left:10px;\n\t\t\t\t// border:1px solid ${themeColor};\n\t\t\t\t`,\n\t\t\t\t// 三级标题\n\t\t\t\th3: `\n\t\t\t\tmargin:30px 0 10px 0;\n\t\t\t\tfont-size: 18px;\n\t\t\t\tcolor: ${themeColor};\n\t\t\t\tpadding-left:10px;\n\t\t\t\tborder-left:3px solid ${themeColor};\n\t\t\t\t`,\n\t\t\t\t// 引用\n\t\t\t\tblockquote: `\n\t\t\t\tmargin:15px 0;\n\t\t\t\tfont-size:15px;\n\t\t\t\tcolor: #777777;\n\t\t\t\tborder-left: 4px solid #dddddd;\n\t\t\t\tpadding: 0 10px;\n\t\t\t\t `,\n\t\t\t\t// 列表 \n\t\t\t\tul: `\n\t\t\t\tmargin: 10px 0;\n\t\t\t\tcolor: #555;\n\t\t\t\t`,\n\t\t\t\tli: `\n\t\t\t\tmargin: 5px 0;\n\t\t\t\tcolor: #555;\n\t\t\t\t`,\n\t\t\t\t// 链接\n\t\t\t\ta: `\n\t\t\t\t// color: ${themeColor};\n\t\t\t\t`,\n\t\t\t\t// 加粗\n\t\t\t\tstrong: `\n\t\t\t\tfont-weight: border;\n\t\t\t\tcolor: ${themeColor};\n\t\t\t\t`,\n\t\t\t\t// 斜体\n\t\t\t\tem: `\n\t\t\t\tcolor: ${themeColor};\n\t\t\t\tletter-spacing:0.3em;\n\t\t\t\t`,\n\t\t\t\t// 分割线\n\t\t\t\thr: `\n\t\t\t\theight:1px;\n\t\t\t\tpadding:0;\n\t\t\t\tborder:none;\n\t\t\t\ttext-align:center;\n\t\t\t\tbackground-image:linear-gradient(to right,rgba(248,57,41,0),${themeColor},rgba(248,57,41,0));\n\t\t\t\tmargin:10px 0;\n\t\t\t\t`,\n\t\t\t\t// 表格\n\t\t\t\ttable: `\n\t\t\t\tborder-spacing:0;\n\t\t\t\toverflow:auto;\n\t\t\t\tmin-width:100%;\n\t\t\t\tmargin:10px 0;\n\t\t\t\tborder-collapse: collapse;\n\t\t\t\t`,\n\t\t\t\tth: `\n\t\t\t\tborder: 1px solid #202121;\n\t\t\t\tcolor: #555;\n\t\t\t\t`,\n\t\t\t\ttd: `\n\t\t\t\tcolor:#555;\n\t\t\t\tborder: 1px solid #555555;\n\t\t\t\t`,\n\t\t\t\tpre: `\n\t\t\t\tborder-radius: 5px;\n\t\t\t\twhite-space: pre;\n\t\t\t\tbackground: ${codeBgColor};\n\t\t\t\tfont-size:12px;\n\t\t\t\tposition: relative;\n\t\t\t\t`,\n\t\t\t}\n\t\t\tthis.tagStyle = zeroStyle\n\t\t},\n\t\tinitTagStyleForAi() {\n\t\t\tconst themeColor = this.themeColor\n\t\t\tconst codeBgColor = this.codeBgColor\n\t\t\tlet zeroStyle = {\n\t\t\t\tp: `\n\t\t\t\tfont-size: 16px;\n\t\t\t\t`,\n\t\t\t\t// 一级标题\n\t\t\t\th1: `\n\t\t\t\tmargin:18px 0 10px 0;\n\t\t\t\tfont-size: 24px;\n\t\t\t\tcolor: ${themeColor};\n\t\t\t\t`,\n\t\t\t\t// 二级标题\n\t\t\t\th2: `\n\t\t\t\tmargin:14px 0 10px 0;\n\t\t\t\tfont-size: 20px;\n\t\t\t\tcolor: ${themeColor};\n\t\t\t\t`,\n\t\t\t\t// 三级标题\n\t\t\t\th3: `\n\t\t\t\tmargin:12x 0 8px 0;\n\t\t\t\tfont-size: 18px;\n\t\t\t\tcolor: ${themeColor};\n\t\t\t\t`,\n\t\t\t\t// 四级标题\n\t\t\t\th4: `\n\t\t\t\tmargin:12px 0 8px 0;\n\t\t\t\t\tfont-size: 16px;\n\t\t\t\tcolor: ${themeColor};\n\t\t\t\t`,\n\t\t\t\t// 五级标题\n\t\t\t\th5: `\n\t\t\t\tmargin:10px 0 8px 0;\n\t\t\t\t\tfont-size: 16px;\n\t\t\t\tcolor: ${themeColor};\n\t\t\t\t`,\n\t\t\t\t// 六级标题\n\t\t\t\th6: `\n\t\t\t\tmargin:8px 0 8px 0;\n\t\t\t\t\tfont-size: 16px;\n\t\t\t\tcolor: ${themeColor}\n\t\t\t\t`,\n\t\t\t\t// 引用\n\t\t\t\tblockquote: `\n\t\t\t\tmargin:15px 0;\n\t\t\t\tfont-size:15px;\n\t\t\t\tcolor: #777777;\n\t\t\t\tborder-left: 4px solid #dddddd;\n\t\t\t\tpadding: 0 10px;\n\t\t\t\t `,\n\t\t\t\t// 列表 \n\t\t\t\tul: `\n\t\t\t\tmargin: 10px 0;\n\t\t\t\tcolor: #555;\n\t\t\t\t`,\n\t\t\t\tli: `\n\t\t\t\tmargin: 5px 0;\n\t\t\t\tcolor: #555;\n\t\t\t\t`,\n\t\t\t\t// 链接\n\t\t\t\ta: `\n\t\t\t\t// color: ${themeColor};\n\t\t\t\t`,\n\t\t\t\t// 加粗\n\t\t\t\tstrong: `\n\t\t\t\tfont-weight: border;\n\t\t\t\tcolor: ${themeColor};\n\t\t\t\t`,\n\t\t\t\t// 斜体\n\t\t\t\tem: `\n\t\t\t\tcolor: ${themeColor};\n\t\t\t\tletter-spacing:0.3em;\n\t\t\t\t`,\n\t\t\t\t// 分割线\n\t\t\t\thr: `\n\t\t\t\theight:1px;\n\t\t\t\tpadding:0;\n\t\t\t\tborder:none;\n\t\t\t\ttext-align:center;\n\t\t\t\tbackground-image:linear-gradient(to right,rgba(248,57,41,0),${themeColor},rgba(248,57,41,0));\n\t\t\t\tmargin:10px 0;\n\t\t\t\t`,\n\t\t\t\t// 表格\n\t\t\t\ttable: `\n\t\t\t\tborder-spacing:0;\n\t\t\t\toverflow:auto;\n\t\t\t\tmin-width:100%;\n\t\t\t\tmargin:10px 0;\n\t\t\t\tborder-collapse: collapse;\n\t\t\t\t`,\n\t\t\t\tth: `\n\t\t\t\tborder: 1px solid #202121;\n\t\t\t\tcolor: #555;\n\t\t\t\t`,\n\t\t\t\ttd: `\n\t\t\t\tcolor:#555;\n\t\t\t\tborder: 1px solid #555555;\n\t\t\t\t`,\n\t\t\t\tpre: `\n\t\t\t\tborder-radius: 5px;\n\t\t\t\twhite-space: pre;\n\t\t\t\tbackground: ${codeBgColor};\n\t\t\t\tfont-size:12px;\n\t\t\t\tposition: relative;\n\t\t\t\t`,\n\t\t\t}\n\t\t\tthis.tagStyle = zeroStyle\n\t\t},\n\t}\n};\n</script>\n\n<style lang=\"scss\">\n.zero-markdown-view {\n\tpadding: 15rpx;\n\tposition: relative;\n}\n</style>"
  },
  {
    "path": "src/uni_modules/zero-markdown-view/package.json",
    "content": "{\n  \"id\": \"zero-markdown-view\",\n  \"displayName\": \"zero-markdown-view(markdown解析)\",\n  \"version\": \"3.0.0\",\n  \"description\": \"一行代码即可实现markdown解析,支持自定义主题色,支持vue2,vue3，支持流式输出。\",\n  \"keywords\": [\n    \"markdown\",\n    \"markdown解析\",\n    \"代码块\",\n    \"代码高亮\",\n    \"mp-html\"\n],\n  \"repository\": \"\",\n\"engines\": {\n  },\n  \"dcloudext\": {\n    \"type\": \"component-vue\",\n    \"sale\": {\n      \"regular\": {\n        \"price\": \"0.00\"\n      },\n      \"sourcecode\": {\n        \"price\": \"0.00\"\n      }\n    },\n    \"contact\": {\n      \"qq\": \"\"\n    },\n    \"declaration\": {\n      \"ads\": \"无\",\n      \"data\": \"插件不采集任何数据\",\n      \"permissions\": \"无\"\n    },\n    \"npmurl\": \"\"\n  },\n  \"uni_modules\": {\n    \"dependencies\": [],\n    \"encrypt\": [],\n    \"platforms\": {\n      \"cloud\": {\n        \"tcb\": \"y\",\n        \"aliyun\": \"y\",\n        \"alipay\": \"n\"\n      },\n      \"client\": {\n        \"Vue\": {\n          \"vue2\": \"y\",\n          \"vue3\": \"y\"\n        },\n        \"App\": {\n            \"app-vue\": \"u\",\n            \"app-nvue\": \"u\",\n            \"app-harmony\": \"u\",\n            \"app-uvue\": \"u\"\n        },\n        \"H5-mobile\": {\n          \"Safari\": \"y\",\n          \"Android Browser\": \"y\",\n          \"微信浏览器(Android)\": \"y\",\n          \"QQ浏览器(Android)\": \"y\"\n        },\n        \"H5-pc\": {\n          \"Chrome\": \"y\",\n          \"IE\": \"u\",\n          \"Edge\": \"y\",\n          \"Firefox\": \"y\",\n          \"Safari\": \"y\"\n        },\n        \"小程序\": {\n          \"微信\": \"y\",\n          \"阿里\": \"u\",\n          \"百度\": \"u\",\n          \"字节跳动\": \"u\",\n          \"QQ\": \"u\",\n          \"钉钉\": \"u\",\n          \"快手\": \"u\",\n          \"飞书\": \"u\",\n          \"京东\": \"u\"\n        },\n        \"快应用\": {\n          \"华为\": \"u\",\n          \"联盟\": \"u\"\n        }\n      }\n    }\n  }\n}"
  },
  {
    "path": "src/uni_modules/zero-markdown-view/readme.md",
    "content": "# zero-markdown-view\n\n## 一. 重要更新说明\n\n### v3.0.0\n\n- 优化了代码块流式输出\n- 增加aiMode模式（内容靠左对齐的，样式区别于普通模式）\n\n\n### v2.1.0\n\n- 新增 latex 公式支持\n- 代码块高亮支持: languages=markup+css+clike+javascript+c+cpp+go+java+markup-templating+php+python+rust\n- 代码包体积增加了不少(注意)\n\n### v2.0.4 (仅需要基础功能可以使用此版本)\n\n- 新增点击代码块复制代码-仅小程序可用\n\n### v2.0.0\n\n- 省去了 npm install marked\n- 省去了 npm install highlight.js\n- 使用 mp-html 自带的插件,重新生成 uniapp 包,大幅减少插件体积\n  传送门: [优化思路及详细过程](https://juejin.cn/post/7160995270476431373/) https://juejin.cn/post/7160995270476431373/\n\n## 二. 使用方法\n\n> 建议放到分包里手动引入该插件\n\n**符合`easycom`组件模式, 导入 `uni_modules` 后直接使用即可 **\n\n```html\n<template>\n  <view class=\"container\">\n    <!-- 默认用法 直接传入md文本即可 普通md展示-->\n    <zero-markdown-view :markdown=\"content\"></zero-markdown-view>\n\n\t<!-- ai对话模式 -->\n\t <zero-markdown-view :markdown=\"msgContent\" :aiMode='true'></zero-markdown-view>\n  </view>\n</template>\n<script>\n  export default {\n    data() {\n      return {\n        content: \"## md格式的文本内容\",\n\t\tmsgContent: \"## ai回复的内容，兼容流式输出\",\n      };\n    },\n    created() {},\n    methods: {},\n  };\n</script>\n<style lang=\"scss\" scoped></style>\n```\n\n## 三. 参数说明\n\n| 参数        | 类型   | 默认值    | 描述          |\n| ----------- | ------ | --------- | ------------- |\n| markdown    | String |           | markdown 文本 |\n| themeColor  | String | '#007AFF' | 主题色        |\n| codeBgColor | String | '#2d2d2d' | 代码块背景色  |\n| aiMode      | Boolean| false     | 是否为 AI 模式（内容靠左对齐） |\n\n\n## 四. 注意事项\n\n### 关于代码块高亮\n\n如果需要更多语言或更换主题请前往 prism 官网 下载对应的 prism.min.js 和 prism.css 并替换 plugins/highlight/ 目录下的文件,重新运行打包命令并替换 mp-html. 不建议这样做,因为本插件还修改过其他地方,可能会导致插件不能正常使用.\n具体请参考 mp-html 的文档,在文末有链接\n\n### 关于代码块流式输出闪烁,可以尝试 给代码块后增加 `\\n`\n\n#### 已经在组件内的 `aiMode` 解决，不需要自行处理,也就是说，如何你是是用在ai上，直接把ai回复内容传给组件就可以了\n#### 已经在组件内的 `aiMode` 解决，不需要自行处理,也就是说，如何你是是用在ai上，直接把ai回复内容传给组件就可以了\n#### 已经在组件内的 `aiMode` 解决，不需要自行处理,也就是说，如何你是是用在ai上，直接把ai回复内容传给组件就可以了\n\n\n> 注意小程序上的流逝输出需要结合unipush2使用\n\n> 感谢评论区的一个朋友提供的代码\n\n````javascript\n\t\tcomputed: {\n\t\t\t\t\t\t// 流式输出时代码块处理 , 这时候请使用 msgContent 传入组件中\n\t\tmsgContent() {\n\t\t\tif (!this.markdown) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tlet htmlString = ''\n\t\t\t// 检查是否有未闭合的代码块\n\t\t\tconst codeBlocks = this.markdown.match(/```[\\s\\S]*?```|```[\\s\\S]*?$/g) || []\n\t\t\tconst lastBlock = codeBlocks[codeBlocks.length - 1]\n\t\t\tif (lastBlock && !lastBlock.endsWith('```')) {\n\t\t\t\t// 最后一个代码块未闭合,需要补上结束标识符\n\t\t\t\thtmlString = this.markdown + '\\n'\n\t\t\t} else {\n\t\t\t\thtmlString = this.markdown\n\t\t\t}\n\t\t\treturn htmlString\n\t\t},\n\t\t},\n````\n\n### 如何关闭点击代码块复制功能?\n\n找到组件文件夹 `zero-markdown-view`-`mp-html`-`highlight`-`config.js`\n\n**把 `copyByClickCode` 改成 false 即可**\n\n```\nexport default {\n  copyByClickCode: true, // 点击代码块复制\n  showLanguageName: true, // 是否在代码块右上角显示语言的名称\n}\n```\n\n### 感谢 mp-html 插件\n\n插件地址: [https://ext.dcloud.net.cn/plugin?id=805](https://ext.dcloud.net.cn/plugin?id=805)\n\n文档地址: [https://jin-yufeng.gitee.io/mp-html/#/overview/quickstart](https://jin-yufeng.gitee.io/mp-html/#/overview/quickstart)\n\n插件预览:\n![code](https://cdn.zerojs.cn/image/common/code-z_1722414660881_1.jpg?imageMogr2/thumbnail/200x)\n\n> 小程序搜索: 零技术\n\n> 预览的小程序不一定能及时更新当前插件\n"
  },
  {
    "path": "src/uview-pro.theme.ts",
    "content": "// 此自定义uView Pro主题生成于2025-11-29 13:18\n// 地址：https://uviewpro.cn/zh/guide/themeGenerate.html\n\nexport default [\n    // {\n    //     \"name\": \"uviewpro\",\n    //     \"label\": \"官方蓝\",\n    //     \"description\": \"\",\n    //     \"color\": {\n    //         \"primary\": \"#2979ff\",\n    //         \"primaryDark\": \"#2b85e4\",\n    //         \"primaryDisabled\": \"#a0cfff\",\n    //         \"primaryLight\": \"#ecf5ff\",\n    //         \"bgColor\": \"#f3f4f6\",\n    //         \"bgWhite\": \"#ffffff\",\n    //         \"bgGrayLight\": \"#f1f1f1\",\n    //         \"bgGrayDark\": \"#2f343c\",\n    //         \"bgBlack\": \"#000000\",\n    //         \"info\": \"#909399\",\n    //         \"infoDark\": \"#82848a\",\n    //         \"infoDisabled\": \"#c8c9cc\",\n    //         \"infoLight\": \"#f4f4f5\",\n    //         \"warning\": \"#ff9900\",\n    //         \"warningDark\": \"#f29100\",\n    //         \"warningDisabled\": \"#fcbd71\",\n    //         \"warningLight\": \"#fdf6ec\",\n    //         \"error\": \"#fa3534\",\n    //         \"errorDark\": \"#dd6161\",\n    //         \"errorDisabled\": \"#fab6b6\",\n    //         \"errorLight\": \"#fef0f0\",\n    //         \"success\": \"#19be6b\",\n    //         \"successDark\": \"#18b566\",\n    //         \"successDisabled\": \"#71d5a1\",\n    //         \"successLight\": \"#dbf1e1\",\n    //         \"mainColor\": \"#303133\",\n    //         \"contentColor\": \"#606266\",\n    //         \"tipsColor\": \"#909399\",\n    //         \"lightColor\": \"#c0c4cc\",\n    //         \"borderColor\": \"#dcdfe6\",\n    //         \"whiteColor\": \"#ffffff\",\n    //         \"blackColor\": \"#000000\",\n    //         \"dividerColor\": \"#ebeef5\",\n    //         \"maskColor\": \"rgba(0, 0, 0, 0.4)\",\n    //         \"shadowColor\": \"rgba(0, 0, 0, 0.1)\"\n    //     }\n    // },\n    // 主题 1: 紫色\n    {\n        name: 'purple',\n        label: '霞光紫',\n        color: {\n            primary: '#7c3aed',\n            error: '#f43f5e',\n            warning: '#f59e0b',\n            success: '#10b981',\n            info: '#6b7280',\n            primaryLight: '#f3e8ff',\n            errorLight: '#ffe4e6',\n            warningLight: '#fef3c7',\n            successLight: '#d1fae5',\n            infoLight: '#f3f4f6',\n            primaryDark: '#6d28d9',\n            errorDark: '#e11d48',\n            warningDark: '#d97706',\n            successDark: '#059669',\n            infoDark: '#4b5563',\n            primaryDisabled: '#c4b5fd',\n            errorDisabled: '#fbcfe8',\n            warningDisabled: '#fde68a',\n            successDisabled: '#a7f3d0',\n            infoDisabled: '#d1d5db'\n        }\n    },\n\n    // 主题 2: 绿色\n    {\n        name: 'green',\n        label: '清翠绿',\n        color: {\n            primary: '#059669',\n            error: '#dc2626',\n            warning: '#eab308',\n            success: '#16a34a',\n            info: '#78716c',\n            primaryLight: '#ecfdf5',\n            errorLight: '#fee2e2',\n            warningLight: '#fefce8',\n            successLight: '#dcfce7',\n            infoLight: '#fafaf9',\n            primaryDark: '#047857',\n            errorDark: '#b91c1c',\n            warningDark: '#ca8a04',\n            successDark: '#15803d',\n            infoDark: '#57534e',\n            primaryDisabled: '#6ee7b7',\n            errorDisabled: '#fca5a5',\n            warningDisabled: '#facc15',\n            successDisabled: '#86efac',\n            infoDisabled: '#e7e5e4'\n        }\n    },\n\n    // 主题 3: 橙色\n    {\n        name: 'orange',\n        label: '暖阳橙',\n        color: {\n            primary: '#ff6b35',\n            error: '#dc2626',\n            warning: '#f59e0b',\n            success: '#059669',\n            info: '#2563eb',\n            primaryLight: '#fed7aa',\n            errorLight: '#fee2e2',\n            warningLight: '#fef3c7',\n            successLight: '#dcfce7',\n            infoLight: '#dbeafe',\n            primaryDark: '#ea580c',\n            errorDark: '#b91c1c',\n            warningDark: '#d97706',\n            successDark: '#047857',\n            infoDark: '#1d4ed8',\n            primaryDisabled: '#fed7aa',\n            errorDisabled: '#fca5a5',\n            warningDisabled: '#fcd34d',\n            successDisabled: '#6ee7b7',\n            infoDisabled: '#93c5fd'\n        }\n    },\n\n    // 主题 4: 深蓝色\n    {\n        name: 'dark',\n        label: '深邃蓝',\n        color: {\n            primary: '#1e3a8a',\n            error: '#dc2626',\n            warning: '#d97706',\n            success: '#059669',\n            info: '#2563eb',\n            primaryLight: '#dbeafe',\n            errorLight: '#fee2e2',\n            warningLight: '#fef3c7',\n            successLight: '#dcfce7',\n            infoLight: '#dbeafe',\n            primaryDark: '#1e40af',\n            errorDark: '#b91c1c',\n            warningDark: '#b45309',\n            successDark: '#047857',\n            infoDark: '#1d4ed8',\n            primaryDisabled: '#93c5fd',\n            errorDisabled: '#fca5a5',\n            warningDisabled: '#fcd34d',\n            successDisabled: '#6ee7b7',\n            infoDisabled: '#93c5fd'\n        }\n    }\n];\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n    \"extends\": \"@vue/tsconfig/tsconfig.json\",\n    \"compilerOptions\": {\n        \"verbatimModuleSyntax\": true,\n        \"sourceMap\": true,\n        \"baseUrl\": \".\",\n        \"paths\": {\n            \"@/*\": [\"./src/*\"],\n            \"uview-pro\": [\"./src/uni_modules/uview-pro\"],\n            \"uview-pro/*\": [\"./src/uni_modules/uview-pro/*\"]\n        },\n        \"lib\": [\"esnext\", \"dom\"],\n        \"types\": [\"@dcloudio/types\"],\n        \"typeRoots\": [\"./types\", \"./src/uni_modules/uview-pro/types\", \"./node_modules/@types\"],\n        \"skipLibCheck\": true,\n        \"allowJs\": true,\n        \"jsx\": \"preserve\",\n        \"strict\": false,\n        \"noImplicitAny\": false,\n        \"strictNullChecks\": false,\n        \"noImplicitReturns\": false,\n        \"noFallthroughCasesInSwitch\": false,\n        \"exactOptionalPropertyTypes\": false,\n        \"noUnusedLocals\": false,\n        \"noUnusedParameters\": false,\n        \"noUncheckedIndexedAccess\": false\n    },\n    \"vueCompilerOptions\": {\n        \"strictTemplates\": false,\n        \"target\": 3\n    },\n    \"include\": [\"src/**/*.ts\", \"src/**/*.d.ts\", \"src/**/*.tsx\", \"src/**/*.vue\", \"types/**/*.d.ts\", \"*.d.ts\"],\n    \"exclude\": [\"src/**/*.js\", \"src/uni_modules/**/*.js\", \"node_modules\"]\n}\n"
  },
  {
    "path": "vite.config.ts",
    "content": "import { defineConfig } from 'vite';\nimport Uni from '@dcloudio/vite-plugin-uni';\nimport path from 'path';\nimport UniKuRoot from '@uni-ku/root';\n\n// https://vitejs.dev/config/\nexport default defineConfig({\n    plugins: [UniKuRoot(), Uni()],\n    resolve: {\n        alias: {\n            '@': path.join(process.cwd(), './src'),\n            'uview-pro': path.join(process.cwd(), './src/uni_modules/uview-pro'),\n            'uview-pro/': path.join(process.cwd(), './src/uni_modules/uview-pro/')\n        }\n    },\n    optimizeDeps: {\n        exclude: ['vue-i18n']\n    },\n    server: {\n        port: 5173,\n        fs: {\n            // Allow serving files from one level up to the project root\n            allow: ['..']\n        }\n    }\n});\n"
  }
]