Full Code of vbenjs/vue-vben-admin for AI

main 0c300d040ce5 cached
1652 files
3.0 MB
869.6k tokens
1098 symbols
1 requests
Download .txt
Showing preview only (3,430K chars total). Download the full file or copy to clipboard to get everything.
Repository: vbenjs/vue-vben-admin
Branch: main
Commit: 0c300d040ce5
Files: 1652
Total size: 3.0 MB

Directory structure:
gitextract_e_asnnwg/

├── .browserslistrc
├── .changeset/
│   ├── README.md
│   └── config.json
├── .commitlintrc.js
├── .dockerignore
├── .editorconfig
├── .gitattributes
├── .gitconfig
├── .github/
│   ├── CODEOWNERS
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug-report.yml
│   │   ├── docs.yml
│   │   └── feature-request.yml
│   ├── actions/
│   │   └── setup-node/
│   │       └── action.yml
│   ├── commit-convention.md
│   ├── config.yml
│   ├── contributing.md
│   ├── dependabot.yml
│   ├── pull_request_template.md
│   ├── release-drafter.yml
│   ├── semantic.yml
│   └── workflows/
│       ├── build.yml
│       ├── changeset-version.yml
│       ├── ci.yml
│       ├── codeql.yml
│       ├── deploy.yml
│       ├── draft.yml
│       ├── issue-close-require.yml
│       ├── issue-labeled.yml
│       ├── lock.yml
│       ├── release-tag.yml
│       ├── rerun.yml
│       ├── semantic-pull-request.yml
│       └── stale.yml
├── .gitignore
├── .gitpod.yml
├── .node-version
├── .npmrc
├── .stylelintignore
├── .vscode/
│   ├── extensions.json
│   ├── global.code-snippets
│   ├── launch.json
│   └── settings.json
├── LICENSE
├── README.ja-JP.md
├── README.md
├── README.zh-CN.md
├── apps/
│   ├── backend-mock/
│   │   ├── README.md
│   │   ├── api/
│   │   │   ├── auth/
│   │   │   │   ├── codes.ts
│   │   │   │   ├── login.post.ts
│   │   │   │   ├── logout.post.ts
│   │   │   │   └── refresh.post.ts
│   │   │   ├── demo/
│   │   │   │   └── bigint.ts
│   │   │   ├── menu/
│   │   │   │   └── all.ts
│   │   │   ├── status.ts
│   │   │   ├── system/
│   │   │   │   ├── dept/
│   │   │   │   │   ├── .post.ts
│   │   │   │   │   ├── [id].delete.ts
│   │   │   │   │   ├── [id].put.ts
│   │   │   │   │   └── list.ts
│   │   │   │   ├── menu/
│   │   │   │   │   ├── list.ts
│   │   │   │   │   ├── name-exists.ts
│   │   │   │   │   └── path-exists.ts
│   │   │   │   └── role/
│   │   │   │       └── list.ts
│   │   │   ├── table/
│   │   │   │   └── list.ts
│   │   │   ├── test.get.ts
│   │   │   ├── test.post.ts
│   │   │   ├── timezone/
│   │   │   │   ├── getTimezone.ts
│   │   │   │   ├── getTimezoneOptions.ts
│   │   │   │   └── setTimezone.ts
│   │   │   ├── upload.ts
│   │   │   └── user/
│   │   │       └── info.ts
│   │   ├── error.ts
│   │   ├── middleware/
│   │   │   └── 1.api.ts
│   │   ├── nitro.config.ts
│   │   ├── package.json
│   │   ├── routes/
│   │   │   └── [...].ts
│   │   ├── tsconfig.build.json
│   │   ├── tsconfig.json
│   │   └── utils/
│   │       ├── cookie-utils.ts
│   │       ├── jwt-utils.ts
│   │       ├── mock-data.ts
│   │       ├── response.ts
│   │       └── timezone-utils.ts
│   ├── web-antd/
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── adapter/
│   │   │   │   ├── component/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── form.ts
│   │   │   │   └── vxe-table.ts
│   │   │   ├── api/
│   │   │   │   ├── core/
│   │   │   │   │   ├── auth.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu.ts
│   │   │   │   │   └── user.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── request.ts
│   │   │   ├── app.vue
│   │   │   ├── bootstrap.ts
│   │   │   ├── layouts/
│   │   │   │   ├── auth.vue
│   │   │   │   ├── basic.vue
│   │   │   │   └── index.ts
│   │   │   ├── locales/
│   │   │   │   ├── README.md
│   │   │   │   ├── index.ts
│   │   │   │   └── langs/
│   │   │   │       ├── en-US/
│   │   │   │       │   ├── demos.json
│   │   │   │       │   └── page.json
│   │   │   │       └── zh-CN/
│   │   │   │           ├── demos.json
│   │   │   │           └── page.json
│   │   │   ├── main.ts
│   │   │   ├── preferences.ts
│   │   │   ├── router/
│   │   │   │   ├── access.ts
│   │   │   │   ├── guard.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── routes/
│   │   │   │       ├── core.ts
│   │   │   │       ├── index.ts
│   │   │   │       └── modules/
│   │   │   │           ├── dashboard.ts
│   │   │   │           ├── demos.ts
│   │   │   │           └── vben.ts
│   │   │   ├── store/
│   │   │   │   ├── auth.ts
│   │   │   │   └── index.ts
│   │   │   └── views/
│   │   │       ├── _core/
│   │   │       │   ├── README.md
│   │   │       │   ├── about/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── authentication/
│   │   │       │   │   ├── code-login.vue
│   │   │       │   │   ├── forget-password.vue
│   │   │       │   │   ├── login.vue
│   │   │       │   │   ├── qrcode-login.vue
│   │   │       │   │   └── register.vue
│   │   │       │   ├── fallback/
│   │   │       │   │   ├── coming-soon.vue
│   │   │       │   │   ├── forbidden.vue
│   │   │       │   │   ├── internal-error.vue
│   │   │       │   │   ├── not-found.vue
│   │   │       │   │   └── offline.vue
│   │   │       │   └── profile/
│   │   │       │       ├── base-setting.vue
│   │   │       │       ├── index.vue
│   │   │       │       ├── notification-setting.vue
│   │   │       │       ├── password-setting.vue
│   │   │       │       └── security-setting.vue
│   │   │       ├── dashboard/
│   │   │       │   ├── analytics/
│   │   │       │   │   ├── analytics-trends.vue
│   │   │       │   │   ├── analytics-visits-data.vue
│   │   │       │   │   ├── analytics-visits-sales.vue
│   │   │       │   │   ├── analytics-visits-source.vue
│   │   │       │   │   ├── analytics-visits.vue
│   │   │       │   │   └── index.vue
│   │   │       │   └── workspace/
│   │   │       │       └── index.vue
│   │   │       └── demos/
│   │   │           └── antd/
│   │   │               └── index.vue
│   │   ├── tsconfig.json
│   │   ├── tsconfig.node.json
│   │   └── vite.config.ts
│   ├── web-antdv-next/
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── adapter/
│   │   │   │   ├── component/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── form.ts
│   │   │   │   └── vxe-table.ts
│   │   │   ├── api/
│   │   │   │   ├── core/
│   │   │   │   │   ├── auth.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu.ts
│   │   │   │   │   └── user.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── request.ts
│   │   │   ├── app.vue
│   │   │   ├── bootstrap.ts
│   │   │   ├── layouts/
│   │   │   │   ├── auth.vue
│   │   │   │   ├── basic.vue
│   │   │   │   └── index.ts
│   │   │   ├── locales/
│   │   │   │   ├── README.md
│   │   │   │   ├── index.ts
│   │   │   │   └── langs/
│   │   │   │       ├── en-US/
│   │   │   │       │   ├── demos.json
│   │   │   │       │   └── page.json
│   │   │   │       └── zh-CN/
│   │   │   │           ├── demos.json
│   │   │   │           └── page.json
│   │   │   ├── main.ts
│   │   │   ├── preferences.ts
│   │   │   ├── router/
│   │   │   │   ├── access.ts
│   │   │   │   ├── guard.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── routes/
│   │   │   │       ├── core.ts
│   │   │   │       ├── index.ts
│   │   │   │       └── modules/
│   │   │   │           ├── dashboard.ts
│   │   │   │           ├── demos.ts
│   │   │   │           └── vben.ts
│   │   │   ├── store/
│   │   │   │   ├── auth.ts
│   │   │   │   └── index.ts
│   │   │   └── views/
│   │   │       ├── _core/
│   │   │       │   ├── README.md
│   │   │       │   ├── about/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── authentication/
│   │   │       │   │   ├── code-login.vue
│   │   │       │   │   ├── forget-password.vue
│   │   │       │   │   ├── login.vue
│   │   │       │   │   ├── qrcode-login.vue
│   │   │       │   │   └── register.vue
│   │   │       │   ├── fallback/
│   │   │       │   │   ├── coming-soon.vue
│   │   │       │   │   ├── forbidden.vue
│   │   │       │   │   ├── internal-error.vue
│   │   │       │   │   ├── not-found.vue
│   │   │       │   │   └── offline.vue
│   │   │       │   └── profile/
│   │   │       │       ├── base-setting.vue
│   │   │       │       ├── index.vue
│   │   │       │       ├── notification-setting.vue
│   │   │       │       ├── password-setting.vue
│   │   │       │       └── security-setting.vue
│   │   │       ├── dashboard/
│   │   │       │   ├── analytics/
│   │   │       │   │   ├── analytics-trends.vue
│   │   │       │   │   ├── analytics-visits-data.vue
│   │   │       │   │   ├── analytics-visits-sales.vue
│   │   │       │   │   ├── analytics-visits-source.vue
│   │   │       │   │   ├── analytics-visits.vue
│   │   │       │   │   └── index.vue
│   │   │       │   └── workspace/
│   │   │       │       └── index.vue
│   │   │       └── demos/
│   │   │           └── antd/
│   │   │               └── index.vue
│   │   ├── tsconfig.json
│   │   ├── tsconfig.node.json
│   │   └── vite.config.ts
│   ├── web-ele/
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── adapter/
│   │   │   │   ├── component/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── form.ts
│   │   │   │   └── vxe-table.ts
│   │   │   ├── api/
│   │   │   │   ├── core/
│   │   │   │   │   ├── auth.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu.ts
│   │   │   │   │   └── user.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── request.ts
│   │   │   ├── app.vue
│   │   │   ├── bootstrap.ts
│   │   │   ├── layouts/
│   │   │   │   ├── auth.vue
│   │   │   │   ├── basic.vue
│   │   │   │   └── index.ts
│   │   │   ├── locales/
│   │   │   │   ├── README.md
│   │   │   │   ├── index.ts
│   │   │   │   └── langs/
│   │   │   │       ├── en-US/
│   │   │   │       │   ├── demos.json
│   │   │   │       │   └── page.json
│   │   │   │       └── zh-CN/
│   │   │   │           ├── demos.json
│   │   │   │           └── page.json
│   │   │   ├── main.ts
│   │   │   ├── preferences.ts
│   │   │   ├── router/
│   │   │   │   ├── access.ts
│   │   │   │   ├── guard.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── routes/
│   │   │   │       ├── core.ts
│   │   │   │       ├── index.ts
│   │   │   │       └── modules/
│   │   │   │           ├── dashboard.ts
│   │   │   │           ├── demos.ts
│   │   │   │           └── vben.ts
│   │   │   ├── store/
│   │   │   │   ├── auth.ts
│   │   │   │   └── index.ts
│   │   │   ├── types/
│   │   │   │   └── element-plus-style-css.d.ts
│   │   │   └── views/
│   │   │       ├── _core/
│   │   │       │   ├── README.md
│   │   │       │   ├── about/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── authentication/
│   │   │       │   │   ├── code-login.vue
│   │   │       │   │   ├── forget-password.vue
│   │   │       │   │   ├── login.vue
│   │   │       │   │   ├── qrcode-login.vue
│   │   │       │   │   └── register.vue
│   │   │       │   ├── fallback/
│   │   │       │   │   ├── coming-soon.vue
│   │   │       │   │   ├── forbidden.vue
│   │   │       │   │   ├── internal-error.vue
│   │   │       │   │   ├── not-found.vue
│   │   │       │   │   └── offline.vue
│   │   │       │   └── profile/
│   │   │       │       ├── base-setting.vue
│   │   │       │       ├── index.vue
│   │   │       │       ├── notification-setting.vue
│   │   │       │       ├── password-setting.vue
│   │   │       │       └── security-setting.vue
│   │   │       ├── dashboard/
│   │   │       │   ├── analytics/
│   │   │       │   │   ├── analytics-trends.vue
│   │   │       │   │   ├── analytics-visits-data.vue
│   │   │       │   │   ├── analytics-visits-sales.vue
│   │   │       │   │   ├── analytics-visits-source.vue
│   │   │       │   │   ├── analytics-visits.vue
│   │   │       │   │   └── index.vue
│   │   │       │   └── workspace/
│   │   │       │       └── index.vue
│   │   │       └── demos/
│   │   │           ├── element/
│   │   │           │   └── index.vue
│   │   │           └── form/
│   │   │               └── basic.vue
│   │   ├── tsconfig.json
│   │   ├── tsconfig.node.json
│   │   └── vite.config.ts
│   ├── web-naive/
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── adapter/
│   │   │   │   ├── component/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── form.ts
│   │   │   │   ├── naive.ts
│   │   │   │   └── vxe-table.ts
│   │   │   ├── api/
│   │   │   │   ├── core/
│   │   │   │   │   ├── auth.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu.ts
│   │   │   │   │   └── user.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── request.ts
│   │   │   ├── app.vue
│   │   │   ├── bootstrap.ts
│   │   │   ├── layouts/
│   │   │   │   ├── auth.vue
│   │   │   │   ├── basic.vue
│   │   │   │   └── index.ts
│   │   │   ├── locales/
│   │   │   │   ├── README.md
│   │   │   │   ├── index.ts
│   │   │   │   └── langs/
│   │   │   │       ├── en-US/
│   │   │   │       │   ├── demos.json
│   │   │   │       │   └── page.json
│   │   │   │       └── zh-CN/
│   │   │   │           ├── demos.json
│   │   │   │           └── page.json
│   │   │   ├── main.ts
│   │   │   ├── preferences.ts
│   │   │   ├── router/
│   │   │   │   ├── access.ts
│   │   │   │   ├── guard.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── routes/
│   │   │   │       ├── core.ts
│   │   │   │       ├── index.ts
│   │   │   │       └── modules/
│   │   │   │           ├── dashboard.ts
│   │   │   │           ├── demos.ts
│   │   │   │           └── vben.ts
│   │   │   ├── store/
│   │   │   │   ├── auth.ts
│   │   │   │   └── index.ts
│   │   │   └── views/
│   │   │       ├── _core/
│   │   │       │   ├── README.md
│   │   │       │   ├── about/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── authentication/
│   │   │       │   │   ├── code-login.vue
│   │   │       │   │   ├── forget-password.vue
│   │   │       │   │   ├── login.vue
│   │   │       │   │   ├── qrcode-login.vue
│   │   │       │   │   └── register.vue
│   │   │       │   ├── fallback/
│   │   │       │   │   ├── coming-soon.vue
│   │   │       │   │   ├── forbidden.vue
│   │   │       │   │   ├── internal-error.vue
│   │   │       │   │   ├── not-found.vue
│   │   │       │   │   └── offline.vue
│   │   │       │   └── profile/
│   │   │       │       ├── base-setting.vue
│   │   │       │       ├── index.vue
│   │   │       │       ├── notification-setting.vue
│   │   │       │       ├── password-setting.vue
│   │   │       │       └── security-setting.vue
│   │   │       ├── dashboard/
│   │   │       │   ├── analytics/
│   │   │       │   │   ├── analytics-trends.vue
│   │   │       │   │   ├── analytics-visits-data.vue
│   │   │       │   │   ├── analytics-visits-sales.vue
│   │   │       │   │   ├── analytics-visits-source.vue
│   │   │       │   │   ├── analytics-visits.vue
│   │   │       │   │   └── index.vue
│   │   │       │   └── workspace/
│   │   │       │       └── index.vue
│   │   │       └── demos/
│   │   │           ├── form/
│   │   │           │   ├── basic.vue
│   │   │           │   └── modal.vue
│   │   │           ├── naive/
│   │   │           │   └── index.vue
│   │   │           └── table/
│   │   │               └── index.vue
│   │   ├── tsconfig.json
│   │   ├── tsconfig.node.json
│   │   └── vite.config.ts
│   └── web-tdesign/
│       ├── index.html
│       ├── package.json
│       ├── src/
│       │   ├── adapter/
│       │   │   ├── component/
│       │   │   │   └── index.ts
│       │   │   ├── form.ts
│       │   │   ├── tdesign.ts
│       │   │   └── vxe-table.ts
│       │   ├── api/
│       │   │   ├── core/
│       │   │   │   ├── auth.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── menu.ts
│       │   │   │   └── user.ts
│       │   │   ├── index.ts
│       │   │   └── request.ts
│       │   ├── app.vue
│       │   ├── bootstrap.ts
│       │   ├── layouts/
│       │   │   ├── auth.vue
│       │   │   ├── basic.vue
│       │   │   └── index.ts
│       │   ├── locales/
│       │   │   ├── README.md
│       │   │   ├── index.ts
│       │   │   └── langs/
│       │   │       ├── en-US/
│       │   │       │   ├── demos.json
│       │   │       │   └── page.json
│       │   │       └── zh-CN/
│       │   │           ├── demos.json
│       │   │           └── page.json
│       │   ├── main.ts
│       │   ├── preferences.ts
│       │   ├── router/
│       │   │   ├── access.ts
│       │   │   ├── guard.ts
│       │   │   ├── index.ts
│       │   │   └── routes/
│       │   │       ├── core.ts
│       │   │       ├── index.ts
│       │   │       └── modules/
│       │   │           ├── dashboard.ts
│       │   │           ├── demos.ts
│       │   │           └── vben.ts
│       │   ├── store/
│       │   │   ├── auth.ts
│       │   │   └── index.ts
│       │   └── views/
│       │       ├── _core/
│       │       │   ├── README.md
│       │       │   ├── about/
│       │       │   │   └── index.vue
│       │       │   ├── authentication/
│       │       │   │   ├── code-login.vue
│       │       │   │   ├── forget-password.vue
│       │       │   │   ├── login.vue
│       │       │   │   ├── qrcode-login.vue
│       │       │   │   └── register.vue
│       │       │   ├── fallback/
│       │       │   │   ├── coming-soon.vue
│       │       │   │   ├── forbidden.vue
│       │       │   │   ├── internal-error.vue
│       │       │   │   ├── not-found.vue
│       │       │   │   └── offline.vue
│       │       │   └── profile/
│       │       │       ├── base-setting.vue
│       │       │       ├── index.vue
│       │       │       ├── notification-setting.vue
│       │       │       ├── password-setting.vue
│       │       │       └── security-setting.vue
│       │       ├── dashboard/
│       │       │   ├── analytics/
│       │       │   │   ├── analytics-trends.vue
│       │       │   │   ├── analytics-visits-data.vue
│       │       │   │   ├── analytics-visits-sales.vue
│       │       │   │   ├── analytics-visits-source.vue
│       │       │   │   ├── analytics-visits.vue
│       │       │   │   └── index.vue
│       │       │   └── workspace/
│       │       │       └── index.vue
│       │       └── demos/
│       │           └── tdesign/
│       │               └── index.vue
│       ├── tsconfig.json
│       ├── tsconfig.node.json
│       └── vite.config.ts
├── cspell.json
├── docs/
│   ├── .vitepress/
│   │   ├── components/
│   │   │   ├── demo-preview.vue
│   │   │   ├── index.ts
│   │   │   └── preview-group.vue
│   │   ├── config/
│   │   │   ├── en.mts
│   │   │   ├── index.mts
│   │   │   ├── plugins/
│   │   │   │   └── demo-preview.ts
│   │   │   ├── shared.mts
│   │   │   └── zh.mts
│   │   └── theme/
│   │       ├── components/
│   │       │   ├── site-layout.vue
│   │       │   └── vben-contributors.vue
│   │       ├── index.ts
│   │       ├── plugins/
│   │       │   └── hm.ts
│   │       └── styles/
│   │           ├── base.css
│   │           ├── index.ts
│   │           └── variables.css
│   ├── package.json
│   ├── src/
│   │   ├── _env/
│   │   │   ├── adapter/
│   │   │   │   ├── component.ts
│   │   │   │   ├── form.ts
│   │   │   │   └── vxe-table.ts
│   │   │   └── node/
│   │   │       └── adapter/
│   │   │           ├── form.ts
│   │   │           └── vxe-table.ts
│   │   ├── commercial/
│   │   │   ├── community.md
│   │   │   ├── customized.md
│   │   │   └── technical-support.md
│   │   ├── components/
│   │   │   ├── common-ui/
│   │   │   │   ├── vben-alert.md
│   │   │   │   ├── vben-api-component.md
│   │   │   │   ├── vben-count-to-animator.md
│   │   │   │   ├── vben-drawer.md
│   │   │   │   ├── vben-ellipsis-text.md
│   │   │   │   ├── vben-form.md
│   │   │   │   ├── vben-modal.md
│   │   │   │   └── vben-vxe-table.md
│   │   │   ├── introduction.md
│   │   │   └── layout-ui/
│   │   │       └── page.md
│   │   ├── demos/
│   │   │   ├── vben-alert/
│   │   │   │   ├── alert/
│   │   │   │   │   └── index.vue
│   │   │   │   ├── confirm/
│   │   │   │   │   └── index.vue
│   │   │   │   └── prompt/
│   │   │   │       └── index.vue
│   │   │   ├── vben-api-component/
│   │   │   │   └── cascader/
│   │   │   │       └── index.vue
│   │   │   ├── vben-count-to-animator/
│   │   │   │   ├── basic/
│   │   │   │   │   └── index.vue
│   │   │   │   └── custom/
│   │   │   │       └── index.vue
│   │   │   ├── vben-drawer/
│   │   │   │   ├── auto-height/
│   │   │   │   │   ├── drawer.vue
│   │   │   │   │   └── index.vue
│   │   │   │   ├── basic/
│   │   │   │   │   └── index.vue
│   │   │   │   ├── dynamic/
│   │   │   │   │   ├── drawer.vue
│   │   │   │   │   └── index.vue
│   │   │   │   ├── extra/
│   │   │   │   │   ├── drawer.vue
│   │   │   │   │   └── index.vue
│   │   │   │   └── shared-data/
│   │   │   │       ├── drawer.vue
│   │   │   │       └── index.vue
│   │   │   ├── vben-ellipsis-text/
│   │   │   │   ├── auto-display/
│   │   │   │   │   └── index.vue
│   │   │   │   ├── expand/
│   │   │   │   │   └── index.vue
│   │   │   │   ├── line/
│   │   │   │   │   └── index.vue
│   │   │   │   └── tooltip/
│   │   │   │       └── index.vue
│   │   │   ├── vben-form/
│   │   │   │   ├── api/
│   │   │   │   │   └── index.vue
│   │   │   │   ├── basic/
│   │   │   │   │   └── index.vue
│   │   │   │   ├── custom/
│   │   │   │   │   └── index.vue
│   │   │   │   ├── dynamic/
│   │   │   │   │   └── index.vue
│   │   │   │   ├── query/
│   │   │   │   │   └── index.vue
│   │   │   │   └── rules/
│   │   │   │       └── index.vue
│   │   │   ├── vben-modal/
│   │   │   │   ├── animation-type/
│   │   │   │   │   └── index.vue
│   │   │   │   ├── auto-height/
│   │   │   │   │   ├── index.vue
│   │   │   │   │   └── modal.vue
│   │   │   │   ├── basic/
│   │   │   │   │   └── index.vue
│   │   │   │   ├── draggable/
│   │   │   │   │   ├── index.vue
│   │   │   │   │   └── modal.vue
│   │   │   │   ├── dynamic/
│   │   │   │   │   ├── index.vue
│   │   │   │   │   └── modal.vue
│   │   │   │   ├── extra/
│   │   │   │   │   ├── index.vue
│   │   │   │   │   └── modal.vue
│   │   │   │   └── shared-data/
│   │   │   │       ├── index.vue
│   │   │   │       └── modal.vue
│   │   │   └── vben-vxe-table/
│   │   │       ├── basic/
│   │   │       │   └── index.vue
│   │   │       ├── custom-cell/
│   │   │       │   └── index.vue
│   │   │       ├── edit-cell/
│   │   │       │   └── index.vue
│   │   │       ├── edit-row/
│   │   │       │   └── index.vue
│   │   │       ├── fixed/
│   │   │       │   └── index.vue
│   │   │       ├── form/
│   │   │       │   └── index.vue
│   │   │       ├── mock-api.ts
│   │   │       ├── remote/
│   │   │       │   └── index.vue
│   │   │       ├── table-data.ts
│   │   │       ├── tree/
│   │   │       │   └── index.vue
│   │   │       └── virtual/
│   │   │           └── index.vue
│   │   ├── en/
│   │   │   ├── components/
│   │   │   │   ├── common-ui/
│   │   │   │   │   ├── vben-alert.md
│   │   │   │   │   ├── vben-api-component.md
│   │   │   │   │   ├── vben-count-to-animator.md
│   │   │   │   │   ├── vben-drawer.md
│   │   │   │   │   ├── vben-ellipsis-text.md
│   │   │   │   │   ├── vben-form.md
│   │   │   │   │   ├── vben-modal.md
│   │   │   │   │   └── vben-vxe-table.md
│   │   │   │   ├── introduction.md
│   │   │   │   └── layout-ui/
│   │   │   │       └── page.md
│   │   │   ├── guide/
│   │   │   │   ├── essentials/
│   │   │   │   │   ├── build.md
│   │   │   │   │   ├── concept.md
│   │   │   │   │   ├── development.md
│   │   │   │   │   ├── external-module.md
│   │   │   │   │   ├── icons.md
│   │   │   │   │   ├── route.md
│   │   │   │   │   ├── server.md
│   │   │   │   │   ├── settings.md
│   │   │   │   │   └── styles.md
│   │   │   │   ├── in-depth/
│   │   │   │   │   ├── access.md
│   │   │   │   │   ├── check-updates.md
│   │   │   │   │   ├── features.md
│   │   │   │   │   ├── layout.md
│   │   │   │   │   ├── loading.md
│   │   │   │   │   ├── locale.md
│   │   │   │   │   ├── login.md
│   │   │   │   │   ├── theme.md
│   │   │   │   │   └── ui-framework.md
│   │   │   │   ├── introduction/
│   │   │   │   │   ├── changelog.md
│   │   │   │   │   ├── quick-start.md
│   │   │   │   │   ├── roadmap.md
│   │   │   │   │   ├── thin.md
│   │   │   │   │   ├── vben.md
│   │   │   │   │   └── why.md
│   │   │   │   ├── other/
│   │   │   │   │   ├── faq.md
│   │   │   │   │   ├── project-update.md
│   │   │   │   │   └── remove-code.md
│   │   │   │   └── project/
│   │   │   │       ├── changeset.md
│   │   │   │       ├── cli.md
│   │   │   │       ├── dir.md
│   │   │   │       ├── standard.md
│   │   │   │       ├── tailwindcss.md
│   │   │   │       ├── test.md
│   │   │   │       └── vite.md
│   │   │   └── index.md
│   │   ├── friend-links/
│   │   │   └── index.md
│   │   ├── guide/
│   │   │   ├── essentials/
│   │   │   │   ├── build.md
│   │   │   │   ├── concept.md
│   │   │   │   ├── development.md
│   │   │   │   ├── external-module.md
│   │   │   │   ├── icons.md
│   │   │   │   ├── route.md
│   │   │   │   ├── server.md
│   │   │   │   ├── settings.md
│   │   │   │   └── styles.md
│   │   │   ├── in-depth/
│   │   │   │   ├── access.md
│   │   │   │   ├── check-updates.md
│   │   │   │   ├── features.md
│   │   │   │   ├── layout.md
│   │   │   │   ├── loading.md
│   │   │   │   ├── locale.md
│   │   │   │   ├── login.md
│   │   │   │   ├── theme.md
│   │   │   │   └── ui-framework.md
│   │   │   ├── introduction/
│   │   │   │   ├── changelog.md
│   │   │   │   ├── quick-start.md
│   │   │   │   ├── roadmap.md
│   │   │   │   ├── thin.md
│   │   │   │   ├── vben.md
│   │   │   │   └── why.md
│   │   │   ├── other/
│   │   │   │   ├── faq.md
│   │   │   │   ├── project-update.md
│   │   │   │   └── remove-code.md
│   │   │   └── project/
│   │   │       ├── changeset.md
│   │   │       ├── cli.md
│   │   │       ├── dir.md
│   │   │       ├── standard.md
│   │   │       ├── tailwindcss.md
│   │   │       ├── test.md
│   │   │       └── vite.md
│   │   ├── index.md
│   │   └── sponsor/
│   │       └── personal.md
│   └── tsconfig.json
├── eslint.config.mjs
├── internal/
│   ├── lint-configs/
│   │   ├── commitlint-config/
│   │   │   ├── index.mjs
│   │   │   └── package.json
│   │   ├── eslint-config/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── configs/
│   │   │   │   │   ├── ignores.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── javascript.ts
│   │   │   │   │   ├── jsonc.ts
│   │   │   │   │   ├── node.ts
│   │   │   │   │   ├── perfectionist.ts
│   │   │   │   │   ├── pnpm.ts
│   │   │   │   │   ├── typescript.ts
│   │   │   │   │   ├── unicorn.ts
│   │   │   │   │   ├── vue.ts
│   │   │   │   │   └── yaml.ts
│   │   │   │   ├── custom-config.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── util.ts
│   │   │   ├── tsconfig.json
│   │   │   └── tsdown.config.ts
│   │   ├── oxfmt-config/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   └── index.ts
│   │   │   ├── tsconfig.json
│   │   │   └── tsdown.config.ts
│   │   ├── oxlint-config/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── configs/
│   │   │   │   │   ├── command.ts
│   │   │   │   │   ├── comments.ts
│   │   │   │   │   ├── ignores.ts
│   │   │   │   │   ├── import.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── javascript.ts
│   │   │   │   │   ├── node.ts
│   │   │   │   │   ├── overrides.ts
│   │   │   │   │   ├── plugins.ts
│   │   │   │   │   ├── tailwindcss.ts
│   │   │   │   │   ├── test.ts
│   │   │   │   │   ├── typescript.ts
│   │   │   │   │   ├── unicorn.ts
│   │   │   │   │   └── vue.ts
│   │   │   │   └── index.ts
│   │   │   ├── tsconfig.json
│   │   │   └── tsdown.config.ts
│   │   └── stylelint-config/
│   │       ├── index.mjs
│   │       └── package.json
│   ├── node-utils/
│   │   ├── package.json
│   │   ├── scripts/
│   │   │   └── build.mjs
│   │   ├── src/
│   │   │   ├── __tests__/
│   │   │   │   ├── hash.test.ts
│   │   │   │   └── path.test.ts
│   │   │   ├── constants.ts
│   │   │   ├── date.ts
│   │   │   ├── formatter.ts
│   │   │   ├── fs.ts
│   │   │   ├── git.ts
│   │   │   ├── hash.ts
│   │   │   ├── index.ts
│   │   │   ├── monorepo.ts
│   │   │   ├── path.ts
│   │   │   └── spinner.ts
│   │   ├── tsconfig.build.json
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   ├── tailwind-config/
│   │   ├── package.json
│   │   └── src/
│   │       ├── index.ts
│   │       └── theme.css
│   ├── tsconfig/
│   │   ├── base.json
│   │   ├── library.json
│   │   ├── node.json
│   │   ├── package.json
│   │   ├── web-app.json
│   │   └── web.json
│   └── vite-config/
│       ├── package.json
│       ├── src/
│       │   ├── config/
│       │   │   ├── application.ts
│       │   │   ├── common.ts
│       │   │   ├── index.ts
│       │   │   └── library.ts
│       │   ├── index.ts
│       │   ├── options.ts
│       │   ├── plugins/
│       │   │   ├── archiver.ts
│       │   │   ├── extra-app-config.ts
│       │   │   ├── importmap.ts
│       │   │   ├── index.ts
│       │   │   ├── inject-app-loading/
│       │   │   │   ├── README.md
│       │   │   │   ├── default-loading-antd.html
│       │   │   │   ├── default-loading.html
│       │   │   │   └── index.ts
│       │   │   ├── inject-metadata.ts
│       │   │   ├── license.ts
│       │   │   ├── nitro-mock.ts
│       │   │   ├── print.ts
│       │   │   ├── tailwind-reference.ts
│       │   │   └── vxe-table.ts
│       │   ├── typing.ts
│       │   └── utils/
│       │       └── env.ts
│       ├── tsconfig.json
│       └── tsdown.config.ts
├── lefthook.yml
├── oxfmt.config.ts
├── oxlint.config.ts
├── package.json
├── packages/
│   ├── @core/
│   │   ├── README.md
│   │   ├── base/
│   │   │   ├── README.md
│   │   │   ├── design/
│   │   │   │   ├── package.json
│   │   │   │   ├── src/
│   │   │   │   │   ├── css/
│   │   │   │   │   │   ├── global.css
│   │   │   │   │   │   ├── nprogress.css
│   │   │   │   │   │   ├── transition.css
│   │   │   │   │   │   └── ui.css
│   │   │   │   │   ├── design-tokens/
│   │   │   │   │   │   ├── dark.css
│   │   │   │   │   │   ├── default.css
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── scss-bem/
│   │   │   │   │       ├── bem.scss
│   │   │   │   │       └── constants.scss
│   │   │   │   ├── tsconfig.json
│   │   │   │   └── vite.config.ts
│   │   │   ├── icons/
│   │   │   │   ├── package.json
│   │   │   │   ├── src/
│   │   │   │   │   ├── create-icon.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── lucide.ts
│   │   │   │   ├── tsconfig.json
│   │   │   │   └── tsdown.config.ts
│   │   │   ├── shared/
│   │   │   │   ├── package.json
│   │   │   │   ├── src/
│   │   │   │   │   ├── cache/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   └── storage-manager.test.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── storage-manager.ts
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   ├── color/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   └── convert.test.ts
│   │   │   │   │   │   ├── color.ts
│   │   │   │   │   │   ├── convert.ts
│   │   │   │   │   │   ├── generator.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── constants/
│   │   │   │   │   │   ├── globals.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── vben.ts
│   │   │   │   │   ├── global-state.ts
│   │   │   │   │   ├── store.ts
│   │   │   │   │   └── utils/
│   │   │   │   │       ├── __tests__/
│   │   │   │   │       │   ├── date.test.ts
│   │   │   │   │       │   ├── diff.test.ts
│   │   │   │   │       │   ├── dom.test.ts
│   │   │   │   │       │   ├── inference.test.ts
│   │   │   │   │       │   ├── letter.test.ts
│   │   │   │   │       │   ├── resources.test.ts
│   │   │   │   │       │   ├── stack.test.ts
│   │   │   │   │       │   ├── state-handler.test.ts
│   │   │   │   │       │   ├── tree.test.ts
│   │   │   │   │       │   ├── unique.test.ts
│   │   │   │   │       │   ├── update-css-variables.test.ts
│   │   │   │   │       │   ├── util.test.ts
│   │   │   │   │       │   └── window.test.ts
│   │   │   │   │       ├── cn.ts
│   │   │   │   │       ├── date.ts
│   │   │   │   │       ├── diff.ts
│   │   │   │   │       ├── dom.ts
│   │   │   │   │       ├── download.ts
│   │   │   │   │       ├── index.ts
│   │   │   │   │       ├── inference.ts
│   │   │   │   │       ├── letter.ts
│   │   │   │   │       ├── merge.ts
│   │   │   │   │       ├── nprogress.ts
│   │   │   │   │       ├── resources.ts
│   │   │   │   │       ├── stack.ts
│   │   │   │   │       ├── state-handler.ts
│   │   │   │   │       ├── to.ts
│   │   │   │   │       ├── tree.ts
│   │   │   │   │       ├── unique.ts
│   │   │   │   │       ├── update-css-variables.ts
│   │   │   │   │       ├── util.ts
│   │   │   │   │       └── window.ts
│   │   │   │   ├── tsconfig.json
│   │   │   │   └── tsdown.config.ts
│   │   │   └── typings/
│   │   │       ├── package.json
│   │   │       ├── src/
│   │   │       │   ├── app.d.ts
│   │   │       │   ├── basic.d.ts
│   │   │       │   ├── helper.d.ts
│   │   │       │   ├── index.ts
│   │   │       │   ├── menu-record.ts
│   │   │       │   ├── tabs.ts
│   │   │       │   └── vue-router.d.ts
│   │   │       ├── tsconfig.json
│   │   │       ├── tsdown.config.ts
│   │   │       └── vue-router.d.ts
│   │   ├── composables/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── __tests__/
│   │   │   │   │   └── use-sortable.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── use-is-mobile.ts
│   │   │   │   ├── use-layout-style.ts
│   │   │   │   ├── use-namespace.ts
│   │   │   │   ├── use-priority-value.ts
│   │   │   │   ├── use-scroll-lock.ts
│   │   │   │   ├── use-simple-locale/
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── messages.ts
│   │   │   │   └── use-sortable.ts
│   │   │   ├── tsconfig.json
│   │   │   └── tsdown.config.ts
│   │   ├── preferences/
│   │   │   ├── __tests__/
│   │   │   │   ├── __snapshots__/
│   │   │   │   │   └── config.test.ts.snap
│   │   │   │   ├── config.test.ts
│   │   │   │   └── preferences.test.ts
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── config.ts
│   │   │   │   ├── constants.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── preferences.ts
│   │   │   │   ├── types.ts
│   │   │   │   ├── update-css-variables.ts
│   │   │   │   └── use-preferences.ts
│   │   │   ├── tsconfig.json
│   │   │   └── tsdown.config.ts
│   │   └── ui-kit/
│   │       ├── README.md
│   │       ├── form-ui/
│   │       │   ├── __tests__/
│   │       │   │   └── form-api.test.ts
│   │       │   ├── package.json
│   │       │   ├── src/
│   │       │   │   ├── components/
│   │       │   │   │   └── form-actions.vue
│   │       │   │   ├── config.ts
│   │       │   │   ├── form-api.ts
│   │       │   │   ├── form-render/
│   │       │   │   │   ├── context.ts
│   │       │   │   │   ├── dependencies.ts
│   │       │   │   │   ├── expandable.ts
│   │       │   │   │   ├── form-field.vue
│   │       │   │   │   ├── form-label.vue
│   │       │   │   │   ├── form.vue
│   │       │   │   │   ├── helper.ts
│   │       │   │   │   └── index.ts
│   │       │   │   ├── index.ts
│   │       │   │   ├── types.ts
│   │       │   │   ├── use-form-context.ts
│   │       │   │   ├── use-vben-form.ts
│   │       │   │   ├── vben-form.vue
│   │       │   │   └── vben-use-form.vue
│   │       │   ├── tsconfig.json
│   │       │   └── tsdown.config.ts
│   │       ├── layout-ui/
│   │       │   ├── package.json
│   │       │   ├── src/
│   │       │   │   ├── components/
│   │       │   │   │   ├── index.ts
│   │       │   │   │   ├── layout-content.vue
│   │       │   │   │   ├── layout-footer.vue
│   │       │   │   │   ├── layout-header.vue
│   │       │   │   │   ├── layout-sidebar.vue
│   │       │   │   │   ├── layout-tabbar.vue
│   │       │   │   │   └── widgets/
│   │       │   │   │       ├── index.ts
│   │       │   │   │       ├── sidebar-collapse-button.vue
│   │       │   │   │       └── sidebar-fixed-button.vue
│   │       │   │   ├── hooks/
│   │       │   │   │   ├── use-layout.ts
│   │       │   │   │   └── use-sidebar-drag.ts
│   │       │   │   ├── index.ts
│   │       │   │   ├── vben-layout.ts
│   │       │   │   └── vben-layout.vue
│   │       │   ├── tsconfig.json
│   │       │   └── tsdown.config.ts
│   │       ├── menu-ui/
│   │       │   ├── README.md
│   │       │   ├── package.json
│   │       │   ├── src/
│   │       │   │   ├── components/
│   │       │   │   │   ├── collapse-transition.vue
│   │       │   │   │   ├── index.ts
│   │       │   │   │   ├── menu-badge-dot.vue
│   │       │   │   │   ├── menu-badge.vue
│   │       │   │   │   ├── menu-item.vue
│   │       │   │   │   ├── menu.vue
│   │       │   │   │   ├── normal-menu/
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   ├── normal-menu.ts
│   │       │   │   │   │   └── normal-menu.vue
│   │       │   │   │   ├── sub-menu-content.vue
│   │       │   │   │   └── sub-menu.vue
│   │       │   │   ├── hooks/
│   │       │   │   │   ├── index.ts
│   │       │   │   │   ├── use-menu-context.ts
│   │       │   │   │   ├── use-menu-scroll.ts
│   │       │   │   │   └── use-menu.ts
│   │       │   │   ├── index.ts
│   │       │   │   ├── menu.vue
│   │       │   │   ├── sub-menu.vue
│   │       │   │   ├── types.ts
│   │       │   │   └── utils/
│   │       │   │       └── index.ts
│   │       │   ├── tsconfig.json
│   │       │   └── tsdown.config.ts
│   │       ├── popup-ui/
│   │       │   ├── package.json
│   │       │   ├── src/
│   │       │   │   ├── alert/
│   │       │   │   │   ├── AlertBuilder.ts
│   │       │   │   │   ├── alert.ts
│   │       │   │   │   ├── alert.vue
│   │       │   │   │   └── index.ts
│   │       │   │   ├── drawer/
│   │       │   │   │   ├── __tests__/
│   │       │   │   │   │   └── drawer-api.test.ts
│   │       │   │   │   ├── drawer-api.ts
│   │       │   │   │   ├── drawer.ts
│   │       │   │   │   ├── drawer.vue
│   │       │   │   │   ├── index.ts
│   │       │   │   │   └── use-drawer.ts
│   │       │   │   ├── index.ts
│   │       │   │   └── modal/
│   │       │   │       ├── __tests__/
│   │       │   │       │   └── modal-api.test.ts
│   │       │   │       ├── index.ts
│   │       │   │       ├── modal-api.ts
│   │       │   │       ├── modal.ts
│   │       │   │       ├── modal.vue
│   │       │   │       ├── use-modal-draggable.ts
│   │       │   │       └── use-modal.ts
│   │       │   ├── tsconfig.json
│   │       │   └── tsdown.config.ts
│   │       ├── shadcn-ui/
│   │       │   ├── components.json
│   │       │   ├── package.json
│   │       │   ├── src/
│   │       │   │   ├── assets/
│   │       │   │   │   └── index.css
│   │       │   │   ├── components/
│   │       │   │   │   ├── avatar/
│   │       │   │   │   │   ├── avatar.vue
│   │       │   │   │   │   └── index.ts
│   │       │   │   │   ├── back-top/
│   │       │   │   │   │   ├── back-top.vue
│   │       │   │   │   │   ├── backtop.ts
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   └── use-backtop.ts
│   │       │   │   │   ├── breadcrumb/
│   │       │   │   │   │   ├── breadcrumb-background.vue
│   │       │   │   │   │   ├── breadcrumb-view.vue
│   │       │   │   │   │   ├── breadcrumb.vue
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   └── types.ts
│   │       │   │   │   ├── button/
│   │       │   │   │   │   ├── button-group.vue
│   │       │   │   │   │   ├── button.ts
│   │       │   │   │   │   ├── button.vue
│   │       │   │   │   │   ├── check-button-group.vue
│   │       │   │   │   │   ├── icon-button.vue
│   │       │   │   │   │   └── index.ts
│   │       │   │   │   ├── checkbox/
│   │       │   │   │   │   ├── checkbox.vue
│   │       │   │   │   │   └── index.ts
│   │       │   │   │   ├── context-menu/
│   │       │   │   │   │   ├── context-menu.vue
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   └── interface.ts
│   │       │   │   │   ├── count-to-animator/
│   │       │   │   │   │   ├── count-to-animator.vue
│   │       │   │   │   │   └── index.ts
│   │       │   │   │   ├── dropdown-menu/
│   │       │   │   │   │   ├── dropdown-menu.vue
│   │       │   │   │   │   ├── dropdown-radio-menu.vue
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   └── interface.ts
│   │       │   │   │   ├── expandable-arrow/
│   │       │   │   │   │   ├── expandable-arrow.vue
│   │       │   │   │   │   └── index.ts
│   │       │   │   │   ├── full-screen/
│   │       │   │   │   │   ├── full-screen.vue
│   │       │   │   │   │   └── index.ts
│   │       │   │   │   ├── hover-card/
│   │       │   │   │   │   ├── hover-card.vue
│   │       │   │   │   │   └── index.ts
│   │       │   │   │   ├── icon/
│   │       │   │   │   │   ├── icon.vue
│   │       │   │   │   │   └── index.ts
│   │       │   │   │   ├── index.ts
│   │       │   │   │   ├── input-password/
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   ├── input-password.vue
│   │       │   │   │   │   └── password-strength.vue
│   │       │   │   │   ├── logo/
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   └── logo.vue
│   │       │   │   │   ├── pin-input/
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   ├── input.vue
│   │       │   │   │   │   └── types.ts
│   │       │   │   │   ├── popover/
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   └── popover.vue
│   │       │   │   │   ├── render-content/
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   └── render-content.vue
│   │       │   │   │   ├── scrollbar/
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   └── scrollbar.vue
│   │       │   │   │   ├── segmented/
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   ├── segmented.vue
│   │       │   │   │   │   ├── tabs-indicator.vue
│   │       │   │   │   │   └── types.ts
│   │       │   │   │   ├── select/
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   └── select.vue
│   │       │   │   │   ├── spine-text/
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   └── spine-text.vue
│   │       │   │   │   ├── spinner/
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   ├── loading.vue
│   │       │   │   │   │   └── spinner.vue
│   │       │   │   │   └── tooltip/
│   │       │   │   │       ├── help-tooltip.vue
│   │       │   │   │       ├── index.ts
│   │       │   │   │       └── tooltip.vue
│   │       │   │   ├── index.ts
│   │       │   │   └── ui/
│   │       │   │       ├── accordion/
│   │       │   │       │   ├── Accordion.vue
│   │       │   │       │   ├── AccordionContent.vue
│   │       │   │       │   ├── AccordionItem.vue
│   │       │   │       │   ├── AccordionTrigger.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── alert-dialog/
│   │       │   │       │   ├── AlertDialog.vue
│   │       │   │       │   ├── AlertDialogAction.vue
│   │       │   │       │   ├── AlertDialogCancel.vue
│   │       │   │       │   ├── AlertDialogContent.vue
│   │       │   │       │   ├── AlertDialogDescription.vue
│   │       │   │       │   ├── AlertDialogOverlay.vue
│   │       │   │       │   ├── AlertDialogTitle.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── avatar/
│   │       │   │       │   ├── Avatar.vue
│   │       │   │       │   ├── AvatarFallback.vue
│   │       │   │       │   ├── AvatarImage.vue
│   │       │   │       │   ├── avatar.ts
│   │       │   │       │   └── index.ts
│   │       │   │       ├── badge/
│   │       │   │       │   ├── Badge.vue
│   │       │   │       │   ├── badge.ts
│   │       │   │       │   └── index.ts
│   │       │   │       ├── breadcrumb/
│   │       │   │       │   ├── Breadcrumb.vue
│   │       │   │       │   ├── BreadcrumbEllipsis.vue
│   │       │   │       │   ├── BreadcrumbItem.vue
│   │       │   │       │   ├── BreadcrumbLink.vue
│   │       │   │       │   ├── BreadcrumbList.vue
│   │       │   │       │   ├── BreadcrumbPage.vue
│   │       │   │       │   ├── BreadcrumbSeparator.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── button/
│   │       │   │       │   ├── Button.vue
│   │       │   │       │   ├── button.ts
│   │       │   │       │   ├── index.ts
│   │       │   │       │   └── types.ts
│   │       │   │       ├── card/
│   │       │   │       │   ├── Card.vue
│   │       │   │       │   ├── CardContent.vue
│   │       │   │       │   ├── CardDescription.vue
│   │       │   │       │   ├── CardFooter.vue
│   │       │   │       │   ├── CardHeader.vue
│   │       │   │       │   ├── CardTitle.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── checkbox/
│   │       │   │       │   ├── Checkbox.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── context-menu/
│   │       │   │       │   ├── ContextMenu.vue
│   │       │   │       │   ├── ContextMenuCheckboxItem.vue
│   │       │   │       │   ├── ContextMenuContent.vue
│   │       │   │       │   ├── ContextMenuGroup.vue
│   │       │   │       │   ├── ContextMenuItem.vue
│   │       │   │       │   ├── ContextMenuLabel.vue
│   │       │   │       │   ├── ContextMenuPortal.vue
│   │       │   │       │   ├── ContextMenuRadioGroup.vue
│   │       │   │       │   ├── ContextMenuRadioItem.vue
│   │       │   │       │   ├── ContextMenuSeparator.vue
│   │       │   │       │   ├── ContextMenuShortcut.vue
│   │       │   │       │   ├── ContextMenuSub.vue
│   │       │   │       │   ├── ContextMenuSubContent.vue
│   │       │   │       │   ├── ContextMenuSubTrigger.vue
│   │       │   │       │   ├── ContextMenuTrigger.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── dialog/
│   │       │   │       │   ├── Dialog.vue
│   │       │   │       │   ├── DialogClose.vue
│   │       │   │       │   ├── DialogContent.vue
│   │       │   │       │   ├── DialogDescription.vue
│   │       │   │       │   ├── DialogFooter.vue
│   │       │   │       │   ├── DialogHeader.vue
│   │       │   │       │   ├── DialogOverlay.vue
│   │       │   │       │   ├── DialogScrollContent.vue
│   │       │   │       │   ├── DialogTitle.vue
│   │       │   │       │   ├── DialogTrigger.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── dropdown-menu/
│   │       │   │       │   ├── DropdownMenu.vue
│   │       │   │       │   ├── DropdownMenuCheckboxItem.vue
│   │       │   │       │   ├── DropdownMenuContent.vue
│   │       │   │       │   ├── DropdownMenuGroup.vue
│   │       │   │       │   ├── DropdownMenuItem.vue
│   │       │   │       │   ├── DropdownMenuLabel.vue
│   │       │   │       │   ├── DropdownMenuRadioGroup.vue
│   │       │   │       │   ├── DropdownMenuRadioItem.vue
│   │       │   │       │   ├── DropdownMenuSeparator.vue
│   │       │   │       │   ├── DropdownMenuShortcut.vue
│   │       │   │       │   ├── DropdownMenuSub.vue
│   │       │   │       │   ├── DropdownMenuSubContent.vue
│   │       │   │       │   ├── DropdownMenuSubTrigger.vue
│   │       │   │       │   ├── DropdownMenuTrigger.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── form/
│   │       │   │       │   ├── FormControl.vue
│   │       │   │       │   ├── FormDescription.vue
│   │       │   │       │   ├── FormItem.vue
│   │       │   │       │   ├── FormLabel.vue
│   │       │   │       │   ├── FormMessage.vue
│   │       │   │       │   ├── index.ts
│   │       │   │       │   ├── injectionKeys.ts
│   │       │   │       │   └── useFormField.ts
│   │       │   │       ├── hover-card/
│   │       │   │       │   ├── HoverCard.vue
│   │       │   │       │   ├── HoverCardContent.vue
│   │       │   │       │   ├── HoverCardTrigger.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── index.ts
│   │       │   │       ├── input/
│   │       │   │       │   ├── Input.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── label/
│   │       │   │       │   ├── Label.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── number-field/
│   │       │   │       │   ├── NumberField.vue
│   │       │   │       │   ├── NumberFieldContent.vue
│   │       │   │       │   ├── NumberFieldDecrement.vue
│   │       │   │       │   ├── NumberFieldIncrement.vue
│   │       │   │       │   ├── NumberFieldInput.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── pagination/
│   │       │   │       │   ├── PaginationEllipsis.vue
│   │       │   │       │   ├── PaginationFirst.vue
│   │       │   │       │   ├── PaginationLast.vue
│   │       │   │       │   ├── PaginationNext.vue
│   │       │   │       │   ├── PaginationPrev.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── pin-input/
│   │       │   │       │   ├── PinInput.vue
│   │       │   │       │   ├── PinInputGroup.vue
│   │       │   │       │   ├── PinInputInput.vue
│   │       │   │       │   ├── PinInputSeparator.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── popover/
│   │       │   │       │   ├── Popover.vue
│   │       │   │       │   ├── PopoverContent.vue
│   │       │   │       │   ├── PopoverTrigger.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── radio-group/
│   │       │   │       │   ├── RadioGroup.vue
│   │       │   │       │   ├── RadioGroupItem.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── resizable/
│   │       │   │       │   ├── ResizableHandle.vue
│   │       │   │       │   ├── ResizablePanelGroup.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── scroll-area/
│   │       │   │       │   ├── ScrollArea.vue
│   │       │   │       │   ├── ScrollBar.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── select/
│   │       │   │       │   ├── Select.vue
│   │       │   │       │   ├── SelectContent.vue
│   │       │   │       │   ├── SelectGroup.vue
│   │       │   │       │   ├── SelectItem.vue
│   │       │   │       │   ├── SelectItemText.vue
│   │       │   │       │   ├── SelectLabel.vue
│   │       │   │       │   ├── SelectScrollDownButton.vue
│   │       │   │       │   ├── SelectScrollUpButton.vue
│   │       │   │       │   ├── SelectSeparator.vue
│   │       │   │       │   ├── SelectTrigger.vue
│   │       │   │       │   ├── SelectValue.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── separator/
│   │       │   │       │   ├── Separator.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── sheet/
│   │       │   │       │   ├── Sheet.vue
│   │       │   │       │   ├── SheetClose.vue
│   │       │   │       │   ├── SheetContent.vue
│   │       │   │       │   ├── SheetDescription.vue
│   │       │   │       │   ├── SheetFooter.vue
│   │       │   │       │   ├── SheetHeader.vue
│   │       │   │       │   ├── SheetOverlay.vue
│   │       │   │       │   ├── SheetTitle.vue
│   │       │   │       │   ├── SheetTrigger.vue
│   │       │   │       │   ├── index.ts
│   │       │   │       │   └── sheet.ts
│   │       │   │       ├── switch/
│   │       │   │       │   ├── Switch.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── tabs/
│   │       │   │       │   ├── Tabs.vue
│   │       │   │       │   ├── TabsContent.vue
│   │       │   │       │   ├── TabsList.vue
│   │       │   │       │   ├── TabsTrigger.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── textarea/
│   │       │   │       │   ├── Textarea.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── toggle/
│   │       │   │       │   ├── Toggle.vue
│   │       │   │       │   ├── index.ts
│   │       │   │       │   └── toggle.ts
│   │       │   │       ├── toggle-group/
│   │       │   │       │   ├── ToggleGroup.vue
│   │       │   │       │   ├── ToggleGroupItem.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── tooltip/
│   │       │   │       │   ├── Tooltip.vue
│   │       │   │       │   ├── TooltipContent.vue
│   │       │   │       │   ├── TooltipProvider.vue
│   │       │   │       │   ├── TooltipTrigger.vue
│   │       │   │       │   └── index.ts
│   │       │   │       └── tree/
│   │       │   │           ├── index.ts
│   │       │   │           ├── tree.vue
│   │       │   │           └── types.ts
│   │       │   └── tsconfig.json
│   │       └── tabs-ui/
│   │           ├── package.json
│   │           ├── src/
│   │           │   ├── components/
│   │           │   │   ├── index.ts
│   │           │   │   ├── tabs/
│   │           │   │   │   └── tabs.vue
│   │           │   │   ├── tabs-chrome/
│   │           │   │   │   └── tabs.vue
│   │           │   │   └── widgets/
│   │           │   │       ├── index.ts
│   │           │   │       ├── tool-more.vue
│   │           │   │       ├── tool-refresh.vue
│   │           │   │       └── tool-screen.vue
│   │           │   ├── index.ts
│   │           │   ├── tabs-view.vue
│   │           │   ├── types.ts
│   │           │   ├── use-tabs-drag.ts
│   │           │   └── use-tabs-view-scroll.ts
│   │           ├── tsconfig.json
│   │           └── tsdown.config.ts
│   ├── constants/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── core.ts
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   ├── effects/
│   │   ├── README.md
│   │   ├── access/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── access-control.vue
│   │   │   │   ├── accessible.ts
│   │   │   │   ├── directive.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── use-access.ts
│   │   │   └── tsconfig.json
│   │   ├── common-ui/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── components/
│   │   │   │   │   ├── api-component/
│   │   │   │   │   │   ├── api-component.vue
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── captcha/
│   │   │   │   │   │   ├── hooks/
│   │   │   │   │   │   │   └── useCaptchaPoints.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── point-selection-captcha/
│   │   │   │   │   │   │   ├── index.vue
│   │   │   │   │   │   │   └── point-selection-captcha-card.vue
│   │   │   │   │   │   ├── slider-captcha/
│   │   │   │   │   │   │   ├── index.vue
│   │   │   │   │   │   │   ├── slider-captcha-action.vue
│   │   │   │   │   │   │   ├── slider-captcha-bar.vue
│   │   │   │   │   │   │   └── slider-captcha-content.vue
│   │   │   │   │   │   ├── slider-rotate-captcha/
│   │   │   │   │   │   │   └── index.vue
│   │   │   │   │   │   ├── slider-translate-captcha/
│   │   │   │   │   │   │   └── index.vue
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   ├── col-page/
│   │   │   │   │   │   ├── col-page.vue
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   ├── count-to/
│   │   │   │   │   │   ├── count-to.vue
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   ├── cropper/
│   │   │   │   │   │   ├── cropper.vue
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── ellipsis-text/
│   │   │   │   │   │   ├── ellipsis-text.vue
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── icon-picker/
│   │   │   │   │   │   ├── icon-picker.vue
│   │   │   │   │   │   ├── icons.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── json-viewer/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── index.vue
│   │   │   │   │   │   ├── style.scss
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   ├── loading/
│   │   │   │   │   │   ├── directive.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── loading.vue
│   │   │   │   │   │   └── spinner.vue
│   │   │   │   │   ├── page/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   └── page.test.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── page.vue
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   ├── resize/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── resize.vue
│   │   │   │   │   ├── tippy/
│   │   │   │   │   │   ├── directive.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   └── tree/
│   │   │   │   │       ├── index.ts
│   │   │   │   │       └── tree.vue
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── about/
│   │   │   │       │   ├── about.ts
│   │   │   │       │   ├── about.vue
│   │   │   │       │   └── index.ts
│   │   │   │       ├── authentication/
│   │   │   │       │   ├── auth-title.vue
│   │   │   │       │   ├── code-login.vue
│   │   │   │       │   ├── dingding-login.vue
│   │   │   │       │   ├── forget-password.vue
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── login-expired-modal.vue
│   │   │   │       │   ├── login.vue
│   │   │   │       │   ├── qrcode-login.vue
│   │   │   │       │   ├── register.vue
│   │   │   │       │   ├── third-party-login.vue
│   │   │   │       │   └── types.ts
│   │   │   │       ├── dashboard/
│   │   │   │       │   ├── analysis/
│   │   │   │       │   │   ├── analysis-chart-card.vue
│   │   │   │       │   │   ├── analysis-charts-tabs.vue
│   │   │   │       │   │   ├── analysis-overview.vue
│   │   │   │       │   │   └── index.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── typing.ts
│   │   │   │       │   └── workbench/
│   │   │   │       │       ├── index.ts
│   │   │   │       │       ├── workbench-header.vue
│   │   │   │       │       ├── workbench-project.vue
│   │   │   │       │       ├── workbench-quick-nav.vue
│   │   │   │       │       ├── workbench-todo.vue
│   │   │   │       │       └── workbench-trends.vue
│   │   │   │       ├── fallback/
│   │   │   │       │   ├── fallback.ts
│   │   │   │       │   ├── fallback.vue
│   │   │   │       │   ├── icons/
│   │   │   │       │   │   ├── icon-403.vue
│   │   │   │       │   │   ├── icon-404.vue
│   │   │   │       │   │   ├── icon-500.vue
│   │   │   │       │   │   ├── icon-coming-soon.vue
│   │   │   │       │   │   └── icon-offline.vue
│   │   │   │       │   └── index.ts
│   │   │   │       ├── index.ts
│   │   │   │       └── profile/
│   │   │   │           ├── base-setting.vue
│   │   │   │           ├── index.ts
│   │   │   │           ├── notification-setting.vue
│   │   │   │           ├── password-setting.vue
│   │   │   │           ├── profile.vue
│   │   │   │           ├── security-setting.vue
│   │   │   │           └── types.ts
│   │   │   └── tsconfig.json
│   │   ├── hooks/
│   │   │   ├── README.md
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── index.ts
│   │   │   │   ├── use-app-config.ts
│   │   │   │   ├── use-content-maximize.ts
│   │   │   │   ├── use-design-tokens.ts
│   │   │   │   ├── use-hover-toggle.ts
│   │   │   │   ├── use-pagination.ts
│   │   │   │   ├── use-refresh.ts
│   │   │   │   ├── use-tabs.ts
│   │   │   │   └── use-watermark.ts
│   │   │   └── tsconfig.json
│   │   ├── layouts/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── authentication/
│   │   │   │   │   ├── authentication.vue
│   │   │   │   │   ├── form.vue
│   │   │   │   │   ├── icons/
│   │   │   │   │   │   └── slogan.vue
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── toolbar.vue
│   │   │   │   │   └── types.ts
│   │   │   │   ├── basic/
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── content/
│   │   │   │   │   │   ├── content-spinner.vue
│   │   │   │   │   │   ├── content.vue
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── use-content-spinner.ts
│   │   │   │   │   ├── copyright/
│   │   │   │   │   │   ├── copyright.vue
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── footer/
│   │   │   │   │   │   ├── footer.vue
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── header/
│   │   │   │   │   │   ├── header.vue
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── layout.vue
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── extra-menu.vue
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── menu.vue
│   │   │   │   │   │   ├── mixed-menu.vue
│   │   │   │   │   │   ├── use-extra-menu.ts
│   │   │   │   │   │   ├── use-mixed-menu.ts
│   │   │   │   │   │   └── use-navigation.ts
│   │   │   │   │   └── tabbar/
│   │   │   │   │       ├── index.ts
│   │   │   │   │       ├── tabbar.vue
│   │   │   │   │       └── use-tabbar.ts
│   │   │   │   ├── hooks/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── iframe/
│   │   │   │   │   ├── iframe-router-view.vue
│   │   │   │   │   ├── iframe-view.vue
│   │   │   │   │   └── index.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── route-cached/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── route-cached-page.vue
│   │   │   │   │   └── route-cached-view.vue
│   │   │   │   └── widgets/
│   │   │   │       ├── breadcrumb.vue
│   │   │   │       ├── check-updates/
│   │   │   │       │   ├── check-updates.vue
│   │   │   │       │   └── index.ts
│   │   │   │       ├── color-toggle.vue
│   │   │   │       ├── global-search/
│   │   │   │       │   ├── global-search.vue
│   │   │   │       │   ├── index.ts
│   │   │   │       │   └── search-panel.vue
│   │   │   │       ├── index.ts
│   │   │   │       ├── language-toggle.vue
│   │   │   │       ├── layout-toggle.vue
│   │   │   │       ├── lock-screen/
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── lock-screen-modal.vue
│   │   │   │       │   └── lock-screen.vue
│   │   │   │       ├── notification/
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── notification.vue
│   │   │   │       │   └── types.ts
│   │   │   │       ├── preferences/
│   │   │   │       │   ├── blocks/
│   │   │   │       │   │   ├── block.vue
│   │   │   │       │   │   ├── checkbox-item.vue
│   │   │   │       │   │   ├── general/
│   │   │   │       │   │   │   ├── animation.vue
│   │   │   │       │   │   │   └── general.vue
│   │   │   │       │   │   ├── index.ts
│   │   │   │       │   │   ├── input-item.vue
│   │   │   │       │   │   ├── layout/
│   │   │   │       │   │   │   ├── breadcrumb.vue
│   │   │   │       │   │   │   ├── content.vue
│   │   │   │       │   │   │   ├── copyright.vue
│   │   │   │       │   │   │   ├── footer.vue
│   │   │   │       │   │   │   ├── header.vue
│   │   │   │       │   │   │   ├── layout.vue
│   │   │   │       │   │   │   ├── navigation.vue
│   │   │   │       │   │   │   ├── sidebar.vue
│   │   │   │       │   │   │   ├── tabbar.vue
│   │   │   │       │   │   │   └── widget.vue
│   │   │   │       │   │   ├── number-field-item.vue
│   │   │   │       │   │   ├── select-item.vue
│   │   │   │       │   │   ├── shortcut-keys/
│   │   │   │       │   │   │   └── global.vue
│   │   │   │       │   │   ├── switch-item.vue
│   │   │   │       │   │   ├── theme/
│   │   │   │       │   │   │   ├── builtin.vue
│   │   │   │       │   │   │   ├── color-mode.vue
│   │   │   │       │   │   │   ├── font-size.vue
│   │   │   │       │   │   │   ├── radius.vue
│   │   │   │       │   │   │   └── theme.vue
│   │   │   │       │   │   └── toggle-item.vue
│   │   │   │       │   ├── icons/
│   │   │   │       │   │   ├── content-compact.vue
│   │   │   │       │   │   ├── full-content.vue
│   │   │   │       │   │   ├── header-mixed-nav.vue
│   │   │   │       │   │   ├── header-nav.vue
│   │   │   │       │   │   ├── header-sidebar-nav.vue
│   │   │   │       │   │   ├── index.ts
│   │   │   │       │   │   ├── mixed-nav.vue
│   │   │   │       │   │   ├── setting.vue
│   │   │   │       │   │   ├── sidebar-mixed-nav.vue
│   │   │   │       │   │   └── sidebar-nav.vue
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── preferences-button.vue
│   │   │   │       │   ├── preferences-drawer.vue
│   │   │   │       │   ├── preferences.vue
│   │   │   │       │   └── use-open-preferences.ts
│   │   │   │       ├── theme-toggle/
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── theme-button.vue
│   │   │   │       │   └── theme-toggle.vue
│   │   │   │       ├── timezone/
│   │   │   │       │   ├── index.ts
│   │   │   │       │   └── timezone-button.vue
│   │   │   │       └── user-dropdown/
│   │   │   │           ├── index.ts
│   │   │   │           └── user-dropdown.vue
│   │   │   └── tsconfig.json
│   │   ├── plugins/
│   │   │   ├── README.md
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── echarts/
│   │   │   │   │   ├── echarts-ui.vue
│   │   │   │   │   ├── echarts.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── use-echarts.ts
│   │   │   │   ├── motion/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── types.ts
│   │   │   │   └── vxe-table/
│   │   │   │       ├── api.ts
│   │   │   │       ├── extends.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── init.ts
│   │   │   │       ├── style.css
│   │   │   │       ├── types.ts
│   │   │   │       ├── use-vxe-grid.ts
│   │   │   │       └── use-vxe-grid.vue
│   │   │   └── tsconfig.json
│   │   └── request/
│   │       ├── package.json
│   │       ├── src/
│   │       │   ├── index.ts
│   │       │   └── request-client/
│   │       │       ├── index.ts
│   │       │       ├── modules/
│   │       │       │   ├── downloader.test.ts
│   │       │       │   ├── downloader.ts
│   │       │       │   ├── interceptor.ts
│   │       │       │   ├── sse.test.ts
│   │       │       │   ├── sse.ts
│   │       │       │   ├── uploader.test.ts
│   │       │       │   └── uploader.ts
│   │       │       ├── preset-interceptors.ts
│   │       │       ├── request-client.test.ts
│   │       │       ├── request-client.ts
│   │       │       └── types.ts
│   │       └── tsconfig.json
│   ├── icons/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── iconify/
│   │   │   │   └── index.ts
│   │   │   ├── icons/
│   │   │   │   └── empty-icon.vue
│   │   │   ├── index.ts
│   │   │   └── svg/
│   │   │       ├── index.ts
│   │   │       └── load.ts
│   │   └── tsconfig.json
│   ├── locales/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── i18n.ts
│   │   │   ├── index.ts
│   │   │   ├── langs/
│   │   │   │   ├── en-US/
│   │   │   │   │   ├── authentication.json
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── preferences.json
│   │   │   │   │   ├── profile.json
│   │   │   │   │   └── ui.json
│   │   │   │   └── zh-CN/
│   │   │   │       ├── authentication.json
│   │   │   │       ├── common.json
│   │   │   │       ├── preferences.json
│   │   │   │       ├── profile.json
│   │   │   │       └── ui.json
│   │   │   └── typing.ts
│   │   └── tsconfig.json
│   ├── preferences/
│   │   ├── package.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   ├── stores/
│   │   ├── package.json
│   │   ├── shim-pinia.d.ts
│   │   ├── src/
│   │   │   ├── index.ts
│   │   │   ├── modules/
│   │   │   │   ├── access.test.ts
│   │   │   │   ├── access.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── tabbar.test.ts
│   │   │   │   ├── tabbar.ts
│   │   │   │   ├── timezone.ts
│   │   │   │   ├── user.test.ts
│   │   │   │   └── user.ts
│   │   │   └── setup.ts
│   │   └── tsconfig.json
│   ├── styles/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── antd/
│   │   │   │   └── index.css
│   │   │   ├── antdv-next/
│   │   │   │   └── index.css
│   │   │   ├── ele/
│   │   │   │   └── index.css
│   │   │   ├── global/
│   │   │   │   └── index.scss
│   │   │   ├── index.ts
│   │   │   └── naive/
│   │   │       └── index.css
│   │   └── tsconfig.json
│   ├── types/
│   │   ├── README.md
│   │   ├── global.d.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── index.ts
│   │   │   └── user.ts
│   │   └── tsconfig.json
│   └── utils/
│       ├── README.md
│       ├── package.json
│       ├── src/
│       │   ├── helpers/
│       │   │   ├── __tests__/
│       │   │   │   ├── find-menu-by-path.test.ts
│       │   │   │   ├── generate-menus.test.ts
│       │   │   │   ├── generate-routes-frontend.test.ts
│       │   │   │   └── merge-route-modules.test.ts
│       │   │   ├── find-menu-by-path.ts
│       │   │   ├── generate-menus.ts
│       │   │   ├── generate-routes-backend.ts
│       │   │   ├── generate-routes-frontend.ts
│       │   │   ├── get-popup-container.ts
│       │   │   ├── index.ts
│       │   │   ├── merge-route-modules.ts
│       │   │   ├── reset-routes.ts
│       │   │   └── unmount-global-loading.ts
│       │   └── index.ts
│       └── tsconfig.json
├── playground/
│   ├── __tests__/
│   │   └── e2e/
│   │       ├── auth-login.spec.ts
│   │       └── common/
│   │           └── auth.ts
│   ├── index.html
│   ├── package.json
│   ├── playwright.config.ts
│   ├── src/
│   │   ├── adapter/
│   │   │   ├── component/
│   │   │   │   └── index.ts
│   │   │   ├── form.ts
│   │   │   └── vxe-table.ts
│   │   ├── api/
│   │   │   ├── core/
│   │   │   │   ├── auth.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── menu.ts
│   │   │   │   ├── timezone.ts
│   │   │   │   └── user.ts
│   │   │   ├── examples/
│   │   │   │   ├── download.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── json-bigint.ts
│   │   │   │   ├── params.ts
│   │   │   │   ├── status.ts
│   │   │   │   ├── table.ts
│   │   │   │   └── upload.ts
│   │   │   ├── index.ts
│   │   │   ├── request.ts
│   │   │   └── system/
│   │   │       ├── dept.ts
│   │   │       ├── index.ts
│   │   │       ├── menu.ts
│   │   │       └── role.ts
│   │   ├── app.vue
│   │   ├── bootstrap.ts
│   │   ├── layouts/
│   │   │   ├── auth.vue
│   │   │   ├── basic.vue
│   │   │   └── index.ts
│   │   ├── locales/
│   │   │   ├── README.md
│   │   │   ├── index.ts
│   │   │   └── langs/
│   │   │       ├── en-US/
│   │   │       │   ├── demos.json
│   │   │       │   ├── examples.json
│   │   │       │   ├── page.json
│   │   │       │   └── system.json
│   │   │       └── zh-CN/
│   │   │           ├── demos.json
│   │   │           ├── examples.json
│   │   │           ├── page.json
│   │   │           └── system.json
│   │   ├── main.ts
│   │   ├── preferences.ts
│   │   ├── router/
│   │   │   ├── access.ts
│   │   │   ├── guard.ts
│   │   │   ├── index.ts
│   │   │   └── routes/
│   │   │       ├── core.ts
│   │   │       ├── index.ts
│   │   │       └── modules/
│   │   │           ├── dashboard.ts
│   │   │           ├── demos.ts
│   │   │           ├── examples.ts
│   │   │           ├── system.ts
│   │   │           └── vben.ts
│   │   ├── store/
│   │   │   ├── auth.ts
│   │   │   └── index.ts
│   │   ├── timezone-init.ts
│   │   └── views/
│   │       ├── _core/
│   │       │   ├── README.md
│   │       │   ├── about/
│   │       │   │   └── index.vue
│   │       │   ├── authentication/
│   │       │   │   ├── code-login.vue
│   │       │   │   ├── forget-password.vue
│   │       │   │   ├── login.vue
│   │       │   │   ├── qrcode-login.vue
│   │       │   │   └── register.vue
│   │       │   ├── fallback/
│   │       │   │   ├── coming-soon.vue
│   │       │   │   ├── forbidden.vue
│   │       │   │   ├── internal-error.vue
│   │       │   │   ├── not-found.vue
│   │       │   │   └── offline.vue
│   │       │   └── profile/
│   │       │       ├── base-setting.vue
│   │       │       ├── index.vue
│   │       │       ├── notification-setting.vue
│   │       │       ├── password-setting.vue
│   │       │       └── security-setting.vue
│   │       ├── dashboard/
│   │       │   ├── analytics/
│   │       │   │   ├── analytics-trends.vue
│   │       │   │   ├── analytics-visits-data.vue
│   │       │   │   ├── analytics-visits-sales.vue
│   │       │   │   ├── analytics-visits-source.vue
│   │       │   │   ├── analytics-visits.vue
│   │       │   │   └── index.vue
│   │       │   └── workspace/
│   │       │       └── index.vue
│   │       ├── demos/
│   │       │   ├── access/
│   │       │   │   ├── admin-visible.vue
│   │       │   │   ├── button-control.vue
│   │       │   │   ├── index.vue
│   │       │   │   ├── menu-visible-403.vue
│   │       │   │   ├── super-visible.vue
│   │       │   │   └── user-visible.vue
│   │       │   ├── active-icon/
│   │       │   │   └── index.vue
│   │       │   ├── badge/
│   │       │   │   └── index.vue
│   │       │   ├── breadcrumb/
│   │       │   │   ├── lateral-detail.vue
│   │       │   │   ├── lateral.vue
│   │       │   │   └── level-detail.vue
│   │       │   ├── features/
│   │       │   │   ├── clipboard/
│   │       │   │   │   └── index.vue
│   │       │   │   ├── file-download/
│   │       │   │   │   ├── base64.ts
│   │       │   │   │   └── index.vue
│   │       │   │   ├── full-screen/
│   │       │   │   │   └── index.vue
│   │       │   │   ├── hide-menu-children/
│   │       │   │   │   ├── children.vue
│   │       │   │   │   └── parent.vue
│   │       │   │   ├── icons/
│   │       │   │   │   └── index.vue
│   │       │   │   ├── json-bigint/
│   │       │   │   │   └── index.vue
│   │       │   │   ├── login-expired/
│   │       │   │   │   └── index.vue
│   │       │   │   ├── menu-query/
│   │       │   │   │   └── index.vue
│   │       │   │   ├── new-window/
│   │       │   │   │   └── index.vue
│   │       │   │   ├── request-params-serializer/
│   │       │   │   │   └── index.vue
│   │       │   │   ├── tabs/
│   │       │   │   │   ├── index.vue
│   │       │   │   │   └── tab-detail.vue
│   │       │   │   ├── vue-query/
│   │       │   │   │   ├── concurrency-caching.vue
│   │       │   │   │   ├── index.vue
│   │       │   │   │   ├── infinite-queries.vue
│   │       │   │   │   ├── paginated-queries.vue
│   │       │   │   │   ├── query-retries.vue
│   │       │   │   │   └── typing.ts
│   │       │   │   └── watermark/
│   │       │   │       └── index.vue
│   │       │   └── nested/
│   │       │       ├── menu-1.vue
│   │       │       ├── menu-2-1.vue
│   │       │       ├── menu-3-1.vue
│   │       │       └── menu-3-2-1.vue
│   │       ├── examples/
│   │       │   ├── button-group/
│   │       │   │   └── index.vue
│   │       │   ├── captcha/
│   │       │   │   ├── point-selection-captcha.vue
│   │       │   │   ├── slider-captcha.vue
│   │       │   │   ├── slider-rotate-captcha.vue
│   │       │   │   └── slider-translate-captcha.vue
│   │       │   ├── context-menu/
│   │       │   │   └── index.vue
│   │       │   ├── count-to/
│   │       │   │   └── index.vue
│   │       │   ├── cropper/
│   │       │   │   └── index.vue
│   │       │   ├── doc-button.vue
│   │       │   ├── drawer/
│   │       │   │   ├── auto-height-demo.vue
│   │       │   │   ├── base-demo.vue
│   │       │   │   ├── dynamic-demo.vue
│   │       │   │   ├── form-drawer-demo.vue
│   │       │   │   ├── in-content-demo.vue
│   │       │   │   ├── index.vue
│   │       │   │   └── shared-data-demo.vue
│   │       │   ├── ellipsis/
│   │       │   │   └── index.vue
│   │       │   ├── form/
│   │       │   │   ├── api.vue
│   │       │   │   ├── basic.vue
│   │       │   │   ├── custom-layout.vue
│   │       │   │   ├── custom.vue
│   │       │   │   ├── dynamic.vue
│   │       │   │   ├── merge.vue
│   │       │   │   ├── modules/
│   │       │   │   │   └── two-fields.vue
│   │       │   │   ├── query.vue
│   │       │   │   ├── rules.vue
│   │       │   │   └── scroll-to-error-test.vue
│   │       │   ├── json-viewer/
│   │       │   │   ├── data.ts
│   │       │   │   └── index.vue
│   │       │   ├── layout/
│   │       │   │   └── col-page.vue
│   │       │   ├── loading/
│   │       │   │   └── index.vue
│   │       │   ├── modal/
│   │       │   │   ├── auto-height-demo.vue
│   │       │   │   ├── base-demo.vue
│   │       │   │   ├── blur-demo.vue
│   │       │   │   ├── drag-demo.vue
│   │       │   │   ├── dynamic-demo.vue
│   │       │   │   ├── form-modal-demo.vue
│   │       │   │   ├── in-content-demo.vue
│   │       │   │   ├── index.vue
│   │       │   │   ├── nested-demo.vue
│   │       │   │   └── shared-data-demo.vue
│   │       │   ├── motion/
│   │       │   │   └── index.vue
│   │       │   ├── resize/
│   │       │   │   └── basic.vue
│   │       │   ├── tippy/
│   │       │   │   └── index.vue
│   │       │   └── vxe-table/
│   │       │       ├── basic.vue
│   │       │       ├── custom-cell.vue
│   │       │       ├── edit-cell.vue
│   │       │       ├── edit-row.vue
│   │       │       ├── fixed.vue
│   │       │       ├── form.vue
│   │       │       ├── remote.vue
│   │       │       ├── table-data.ts
│   │       │       ├── tree.vue
│   │       │       └── virtual.vue
│   │       └── system/
│   │           ├── dept/
│   │           │   ├── data.ts
│   │           │   ├── list.vue
│   │           │   └── modules/
│   │           │       └── form.vue
│   │           ├── menu/
│   │           │   ├── data.ts
│   │           │   ├── list.vue
│   │           │   └── modules/
│   │           │       └── form.vue
│   │           └── role/
│   │               ├── data.ts
│   │               ├── list.vue
│   │               └── modules/
│   │                   └── form.vue
│   ├── tsconfig.json
│   ├── tsconfig.node.json
│   └── vite.config.ts
├── pnpm-workspace.yaml
├── scripts/
│   ├── clean.mjs
│   ├── deploy/
│   │   ├── Dockerfile
│   │   ├── build-local-docker-image.sh
│   │   └── nginx.conf
│   ├── turbo-run/
│   │   ├── README.md
│   │   ├── bin/
│   │   │   └── turbo-run.mjs
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── index.ts
│   │   │   └── run.ts
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   └── vsh/
│       ├── README.md
│       ├── bin/
│       │   └── vsh.mjs
│       ├── env.d.ts
│       ├── package.json
│       ├── src/
│       │   ├── check-circular/
│       │   │   └── index.ts
│       │   ├── check-dep/
│       │   │   └── index.ts
│       │   ├── code-workspace/
│       │   │   └── index.ts
│       │   ├── index.ts
│       │   ├── lint/
│       │   │   └── index.ts
│       │   └── publint/
│       │       └── index.ts
│       ├── tsconfig.json
│       └── tsdown.config.ts
├── stylelint.config.mjs
├── tea.yaml
├── turbo.json
├── vben-admin.code-workspace
└── vitest.config.ts

================================================
FILE CONTENTS
================================================

================================================
FILE: .browserslistrc
================================================
> 1%
last 2 versions
not dead
not ie 11


================================================
FILE: .changeset/README.md
================================================
# Changesets

Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works with multi-package repos, or single-package repos to help you version and publish your code. You can find the full documentation for it [in our repository](https://github.com/changesets/changesets)

We have a quick list of common questions to get you started engaging with this project in [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)


================================================
FILE: .changeset/config.json
================================================
{
  "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
  "changelog": [
    "@changesets/changelog-github",
    { "repo": "vbenjs/vue-vben-admin" }
  ],
  "commit": false,
  "fixed": [["@vben-core/*", "@vben/*"]],
  "snapshot": {
    "prereleaseTemplate": "{tag}-{datetime}"
  },
  "privatePackages": { "version": true, "tag": true },
  "linked": [],
  "access": "public",
  "baseBranch": "main",
  "updateInternalDependencies": "patch",
  "ignore": []
}


================================================
FILE: .commitlintrc.js
================================================
export { default } from '@vben/commitlint-config';


================================================
FILE: .dockerignore
================================================
node_modules
.git
.gitignore
*.md
dist
.turbo
dist.zip


================================================
FILE: .editorconfig
================================================
root = true

[*]
charset=utf-8
end_of_line=lf
insert_final_newline=true
indent_style=space
indent_size=2
max_line_length = 100
trim_trailing_whitespace = true
quote_type = single

[*.{yml,yaml,json}]
indent_style = space
indent_size = 2

[*.md]
trim_trailing_whitespace = false


================================================
FILE: .gitattributes
================================================
# https://docs.github.com/cn/get-started/getting-started-with-git/configuring-git-to-handle-line-endings

# Automatically normalize line endings (to LF) for all text-based files.
* text=auto eol=lf

# Declare files that will always have CRLF line endings on checkout.
*.{cmd,[cC][mM][dD]} text eol=crlf
*.{bat,[bB][aA][tT]} text eol=crlf

# Denote all files that are truly binary and should not be modified.
*.{ico,png,jpg,jpeg,gif,webp,svg,woff,woff2} binary

================================================
FILE: .gitconfig
================================================
[core]
    ignorecase = false


================================================
FILE: .github/CODEOWNERS
================================================
# default onwer
* anncwb@126.com vince292007@gmail.com netfan@foxmail.com jinmao88@qq.com

# vben core onwer
/.github/ anncwb@126.com vince292007@gmail.com netfan@foxmail.com jinmao88@qq.com
/.vscode/ anncwb@126.com vince292007@gmail.com netfan@foxmail.com jinmao88@qq.com
/packages/ anncwb@126.com vince292007@gmail.com netfan@foxmail.com jinmao88@qq.com
/packages/@core/ anncwb@126.com vince292007@gmail.com netfan@foxmail.com jinmao88@qq.com
/internal/ anncwb@126.com vince292007@gmail.com netfan@foxmail.com jinmao88@qq.com
/scripts/ anncwb@126.com vince292007@gmail.com netfan@foxmail.com jinmao88@qq.com

# vben team onwer
apps/ anncwb@126.com vince292007@gmail.com netfan@foxmail.com @vbenjs/team-v5 jinmao88@qq.com
docs/ anncwb@126.com vince292007@gmail.com netfan@foxmail.com @vbenjs/team-v5 jinmao88@qq.com


================================================
FILE: .github/ISSUE_TEMPLATE/bug-report.yml
================================================
name: 🐞 Bug Report
description: Report an issue with Vben Admin to help us make it better.
title: 'Bug: '
labels: ['bug: pending triage']

body:
  - type: markdown
    attributes:
      value: |
        Thanks for taking the time to fill out this bug report!
  - type: dropdown
    id: version
    attributes:
      label: Version
      description: What version of our software are you running?
      options:
        - Vben Admin V5
        - Vben Admin V2
      default: 0
    validations:
      required: true

  - type: textarea
    id: bug-desc
    attributes:
      label: Describe the bug?
      description: A clear and concise description of what the bug is. If you intend to submit a PR for this issue, tell us in the description. Thanks!
      placeholder: Bug Description
    validations:
      required: true

  - type: textarea
    id: reproduction
    attributes:
      label: Reproduction
      description: Please provide a link to [StackBlitz](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/basic?initialPath=__vitest__/) (you can also use [examples](https://github.com/vitest-dev/vitest/tree/main/examples)) or a github repo that can reproduce the problem you ran into. A [minimal reproduction](https://stackoverflow.com/help/minimal-reproducible-example) is required unless you are absolutely sure that the issue is obvious and the provided information is enough to understand the problem. If a report is vague (e.g. just a generic error message) and has no reproduction, it will receive a "needs reproduction" label. If no reproduction is provided after 3 days, it will be auto-closed.
      placeholder: Reproduction
    validations:
      required: true

  - type: textarea
    id: system-info
    attributes:
      label: System Info
      description: Output of `npx envinfo --system --npmPackages '{vue}' --binaries --browsers`
      render: shell
      placeholder: System, Binaries, Browsers
    validations:
      required: true

  - type: textarea
    id: logs
    attributes:
      label: Relevant log output
      description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
      render: shell

  - type: checkboxes
    id: terms
    attributes:
      label: Validations
      description: Before submitting the issue, please make sure you do the following
      # description: By submitting this issue, you agree to follow our [Code of Conduct](https://example.com).
      options:
        - label: Read the [docs](https://doc.vben.pro/)
          required: true
        - label: Ensure the code is up to date. (Some issues have been fixed in the latest version)
          required: true
        - label: I have searched the [existing issues](https://github.com/vbenjs/vue-vben-admin/issues) and checked that my issue does not duplicate any existing issues.
          required: true
        - label: Check that this is a concrete bug. For Q&A open a [GitHub Discussion](https://github.com/vbenjs/vue-vben-admin/discussions) or join our [Discord Chat Server](https://discord.gg/8GuAdwDhj6).
          required: true
        - label: The provided reproduction is a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) of the bug.
          required: true


================================================
FILE: .github/ISSUE_TEMPLATE/docs.yml
================================================
name: 📚 Documentation
description: Report an issue with Vben Admin Website to help us make it better.
title: 'Docs: '
labels: [documentation]
body:
  - type: markdown
    attributes:
      value: |
        Thanks for taking the time to fill out this issue!
  - type: checkboxes
    id: documentation_is
    attributes:
      label: Documentation is
      options:
        - label: Missing
        - label: Outdated
        - label: Confusing
        - label: Not sure?
  - type: textarea
    id: description
    attributes:
      label: Explain in Detail
      description: A clear and concise description of your suggestion. If you intend to submit a PR for this issue, tell us in the description. Thanks!
      placeholder: The description of ... page is not clear. I thought it meant ... but it wasn't.
    validations:
      required: true
  - type: textarea
    id: suggestion
    attributes:
      label: Your Suggestion for Changes
    validations:
      required: true
  - type: textarea
    id: reproduction-steps
    attributes:
      label: Steps to reproduce
      description: Please provide any reproduction steps that may need to be described. E.g. if it happens only when running the dev or build script make sure it's clear which one to use.
      placeholder: Run `pnpm install` followed by `pnpm run docs:dev`


================================================
FILE: .github/ISSUE_TEMPLATE/feature-request.yml
================================================
name: ✨ New Feature Proposal
description: Propose a new feature to be added to Vben Admin
title: 'FEATURE: '
labels: ['enhancement: pending triage']
body:
  - type: markdown
    attributes:
      value: |
        Thank you for suggesting a feature for our project! Please fill out the information below to help us understand and implement your request!
  - type: dropdown
    id: version
    attributes:
      label: Version
      description: What version of our software are you running?
      options:
        - Vben Admin V5
        - Vben Admin V2
      default: 0
    validations:
      required: true

  - type: textarea
    id: description
    attributes:
      label: Description
      description: A detailed description of the feature request.
      placeholder: Please describe the feature you would like to see, and why it would be useful.
    validations:
      required: true

  - type: textarea
    id: proposed-solution
    attributes:
      label: Proposed Solution
      description: A clear and concise description of what you want to happen.
      placeholder: Describe the solution you'd like to see
    validations:
      required: true

  - type: textarea
    id: alternatives
    attributes:
      label: Alternatives Considered
      description: |
        A clear and concise description of any alternative solutions or features you've considered.
      placeholder: Describe any alternative solutions or features you've considered
    validations:
      required: false

  - type: input
    id: additional-context
    attributes:
      label: Additional Context
      description: Add any other context or screenshots about the feature request here.
      placeholder: Any additional information
    validations:
      required: false

  - type: checkboxes
    id: checkboxes
    attributes:
      label: Validations
      description: Before submitting the issue, please make sure you do the following
      options:
        - label: Read the [docs](https://doc.vben.pro/)
          required: true
        - label: Ensure the code is up to date. (Some issues have been fixed in the latest version)
          required: true
        - label: I have searched the [existing issues](https://github.com/vbenjs/vue-vben-admin/issues) and checked that my issue does not duplicate any existing issues.
          required: true


================================================
FILE: .github/actions/setup-node/action.yml
================================================
name: 'Setup Node'

description: 'Setup node and pnpm'

runs:
  using: 'composite'
  steps:
    - name: Install pnpm
      uses: pnpm/action-setup@v4

    - name: Install Node.js
      uses: actions/setup-node@v6
      with:
        node-version-file: .node-version
        cache: 'pnpm'

    - name: Get pnpm store directory
      shell: bash
      run: |
        echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV

    - uses: actions/cache@v4
      name: Setup pnpm cache
      if: ${{ github.ref_name == 'main' }}
      with:
        path: ${{ env.STORE_PATH }}
        key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
        restore-keys: |
          ${{ runner.os }}-pnpm-store-

    - uses: actions/cache/restore@v4
      if: ${{ github.ref_name != 'main' }}
      with:
        path: ${{ env.STORE_PATH }}
        key: |
          ${{ runner.os }}-pnpm-store-

    - name: Install dependencies
      shell: bash
      run: pnpm install --frozen-lockfile


================================================
FILE: .github/commit-convention.md
================================================
## Git Commit Message Convention

> This is adapted from [Angular's commit convention](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular).

#### TL;DR:

Messages must be matched by the following regex:

```js
/^(revert: )?(feat|fix|docs|style|refactor|perf|test|workflow|build|ci|chore|types|wip): .{1,50}/;
```

#### Examples

Appears under "Features" header, `dev` subheader:

```
feat(dev): add 'comments' option
```

Appears under "Bug Fixes" header, `dev` subheader, with a link to issue #28:

```
fix(dev): fix dev error

close #28
```

Appears under "Performance Improvements" header, and under "Breaking Changes" with the breaking change explanation:

```
perf(build): remove 'foo' option

BREAKING CHANGE: The 'foo' option has been removed.
```

The following commit and commit `667ecc1` do not appear in the changelog if they are under the same release. If not, the revert commit appears under the "Reverts" header.

```
revert: feat(compiler): add 'comments' option

This reverts commit 667ecc1654a317a13331b17617d973392f415f02.
```

### Full Message Format

A commit message consists of a **header**, **body** and **footer**. The header has a **type**, **scope** and **subject**:

```
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
```

The **header** is mandatory and the **scope** of the header is optional.

### Revert

If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit. In the body, it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.

### Type

If the prefix is `feat`, `fix` or `perf`, it will appear in the changelog. However, if there is any [BREAKING CHANGE](#footer), the commit will always appear in the changelog.

Other prefixes are up to your discretion. Suggested prefixes are `docs`, `chore`, `style`, `refactor`, and `test` for non-changelog related tasks.

### Scope

The scope could be anything specifying the place of the commit change. For example `dev`, `build`, `workflow`, `cli` etc...

### Subject

The subject contains a succinct description of the change:

- use the imperative, present tense: "change" not "changed" nor "changes"
- don't capitalize the first letter
- no dot (.) at the end

### Body

Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes". The body should include the motivation for the change and contrast this with previous behavior.

### Footer

The footer should contain any information about **Breaking Changes** and is also the place to reference GitHub issues that this commit **Closes**.

**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this.


================================================
FILE: .github/config.yml
================================================
# Prevent issues being created without using the template
blank_issues_enabled: false
checkIssueTemplate: true
checkPullRequestTemplate: true

contact_links:
  - name: 💬 Discord Chat
    url: https://discord.gg/8GuAdwDhj6
    about: Ask questions and discuss with other Vben users in real time.

  - name: ❓ Questions & Discussions
    url: https://github.com/@vbenjs/vue-vben-admin/discussions
    about: Use GitHub discussions for message-board style questions and discussions.

# Comment to be posted to on PRs from first time contributors in your repository
newPRWelcomeComment: |
  💖 Thanks for opening this pull request! 💖
  Please be patient and we will get back to you as soon as we can.

# Comment to be posted to on pull requests merged by a first time user
firstPRMergeComment: >
  Thanks for your contribution!  🎉🎉🎉


# Comment to be posted to on first time issues
newIssueWelcomeComment: >
  Thanks for opening your first issue! Be sure to follow the issue template and provide every bit of information to help the developers!


# *OPTIONAL* default titles to check against for lack of descriptiveness
# MUST BE ALL LOWERCASE
requestInfoDefaultTitles:
  - update readme.md
  - updates

# *Required* Comment to reply with
requestInfoReplyComment: >
  Thanks for filing this issue/PR! It would be much appreciated if you could provide us with more information so we can effectively analyze the situation in context.



================================================
FILE: .github/contributing.md
================================================
# Vben Admin Contributing Guide

Hi! We're really excited that you are interested in contributing to Vben Admin. Before submitting your contribution, please make sure to take a moment and read through the following guidelines:

- [Pull Request Guidelines](#pull-request-guidelines)

## Contributor Code of Conduct

As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.

We are committed to making participation in this project a harassment-free experience for everyone, regardless of the level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion.

Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.

## Pull Request Guidelines

- Checkout a topic branch from the relevant branch, e.g. main, and merge back against that branch.

- If adding a new feature:
  - Provide a convincing reason to add this feature. Ideally, you should open a suggestion issue first and have it approved before working on it.

- If fixing bug:
  - Provide a detailed description of the bug in the PR. Live demo preferred.

- It's OK to have multiple small commits as you work on the PR - GitHub can automatically squash them before merging.

## Development Setup

You will need [pnpm](https://pnpm.io/)

After cloning the repo, run:

```bash
# install the dependencies of the project
$ pnpm install
# start the project
$ pnpm run dev
```


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  - package-ecosystem: npm
    directory: '/'
    schedule:
      interval: daily
    groups:
      non-breaking-changes:
        update-types: [minor, patch]

  - package-ecosystem: github-actions
    directory: '/'
    schedule:
      interval: weekly
    groups:
      non-breaking-changes:
        update-types: [minor, patch]


================================================
FILE: .github/pull_request_template.md
================================================
## Description

<!-- Please describe the change as necessary. If it's a feature or enhancement please be as detailed as possible. If it's a bug fix, please link the issue that it fixes or describe the bug in as much detail.

 -->

<!-- You can also add additional context here -->

## Type of change

Please delete options that are not relevant.

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] This change requires a documentation update
- [ ] Please, don't make changes to `pnpm-lock.yaml` unless you introduce a new test example.

## Checklist

> ℹ️ Check all checkboxes - this will indicate that you have done everything in accordance with the rules in [CONTRIBUTING](contributing.md).

- [ ] If you introduce new functionality, document it. You can run documentation with `pnpm run docs:dev` command.
- [ ] Run the tests with `pnpm test`.
- [ ] Changes in changelog are generated from PR name. Please, make sure that it explains your changes in an understandable manner. Please, prefix changeset messages with `feat:`, `fix:`, `perf:`, `docs:`, or `chore:`.
- [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream modules


================================================
FILE: .github/release-drafter.yml
================================================
name-template: 'v$RESOLVED_VERSION'
tag-template: 'v$RESOLVED_VERSION'
version-template: $MAJOR.$MINOR.$PATCH
change-template: '* $TITLE (#$NUMBER) @$AUTHOR'
template: |
  # What's Changed

  $CHANGES

  **Full Changelog**: https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION

categories:
  - title: '🚀 Features'
    labels:
      - 'feature'
  - title: '🐞 Bug Fixes'
    labels:
      - 'bug'
  - title: '📈 Performance & Enhancement'
    labels:
      - 'perf'
      - 'enhancement'
  - title: 📝 Documentation
    labels:
      - 'documentation'
  - title: 👻 Maintenance
    labels:
      - 'chore'
      - 'dependencies'
    # collapse-after: 12
  - title: 🚦 Tests
    labels:
      - 'tests'
  - title: 'Breaking'
    label: 'breaking'

version-resolver:
  major:
    labels:
      - 'major'
      - 'breaking'
  minor:
    labels:
      - 'minor'
  patch:
    labels:
      - 'feature'
      - 'patch'
      - 'bug'
      - 'maintenance'
      - 'docs'
      - 'dependencies'
      - 'security'

exclude-labels:
  - 'skip-changelog'
  - 'no-changelog'
  - 'changelog'
  - 'bump versions'
  - 'reverted'
  - 'invalid'


================================================
FILE: .github/semantic.yml
================================================
titleAndCommits: true
types:
  - feat
  - fix
  - docs
  - chore
  - style
  - refactor
  - perf
  - test
  - build
  - ci
  - revert


================================================
FILE: .github/workflows/build.yml
================================================
# name: Dependabot post-update
name: Build detection
on:
  pull_request_target:
    types: [opened, synchronize, reopened]
    branches:
      - main

env:
  HUSKY: '0'

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
  cancel-in-progress: true

permissions:
  contents: read
  pull-requests: write

jobs:
  post-update:
    if: github.repository == 'vbenjs/vue-vben-admin'
    # if: ${{ github.actor == 'dependabot[bot]' }}
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os:
          - ubuntu-latest
          # - macos-latest
          - windows-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Checkout out pull request
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh pr checkout ${{ github.event.pull_request.number }}

      - name: Setup Node
        uses: ./.github/actions/setup-node

      - name: Build
        run: |
          pnpm run build


================================================
FILE: .github/workflows/changeset-version.yml
================================================
# https://github.com/changesets/action
name: Changeset version

on:
  workflow_dispatch:
  pull_request:
    types:
      - closed
    branches:
      - main

permissions:
  pull-requests: write
  contents: write

env:
  CI: true

jobs:
  version:
    if: (github.event.pull_request.merged || github.event_name == 'workflow_dispatch') && github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]') && github.repository == 'vbenjs/vue-vben-admin'
    # if: github.repository == 'vbenjs/vue-vben-admin'
    timeout-minutes: 15
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Setup Node
        uses: ./.github/actions/setup-node

      - name: Create Release Pull Request
        uses: changesets/action@v1
        with:
          version: pnpm run version
          commit: 'chore: bump versions'
          title: 'chore: bump versions'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/ci.yml
================================================
name: CI

on:
  pull_request:
  push:
    branches:
      - main
      - 'releases/*'

permissions:
  contents: read

env:
  CI: true
  TZ: Asia/Shanghai

jobs:
  test:
    name: Test
    if: github.repository == 'vbenjs/vue-vben-admin'
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os:
          - ubuntu-latest
          # - macos-latest
          - windows-latest
    timeout-minutes: 20
    steps:
      - name: Checkout code
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Install pnpm
        uses: pnpm/action-setup@v4
        with:
          run_install: false

      - name: Setup Node
        uses: ./.github/actions/setup-node

      # - name: Check Git version
      #   run: git --version

      # - name: Setup mock Git user
      #   run: git config --global user.email "you@example.com" && git config --global user.name "Your Name"

      - name: Vitest tests
        run: pnpm run test:unit

      # - name: Upload coverage
      #   uses: codecov/codecov-action@v4
      #   with:
      #     token: ${{ secrets.CODECOV_TOKEN }}

  lint:
    name: Lint
    if: github.repository == 'vbenjs/vue-vben-admin'
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os:
          - ubuntu-latest
          # - macos-latest
          - windows-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Setup Node
        uses: ./.github/actions/setup-node

      - name: Lint
        run: pnpm run lint

  check:
    name: Check
    if: github.repository == 'vbenjs/vue-vben-admin'
    runs-on: ${{ matrix.os }}
    timeout-minutes: 20
    strategy:
      matrix:
        os:
          - ubuntu-latest
          # - macos-latest
          - windows-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Setup Node
        uses: ./.github/actions/setup-node

      - name: Typecheck
        run: pnpm check:type

      # From https://github.com/rhysd/actionlint/blob/main/docs/usage.md#use-actionlint-on-github-actions
      - name: Check workflow files
        if: runner.os == 'Linux'
        run: |
          bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)
          ./actionlint -color -shellcheck=""

  ci-ok:
    name: CI OK
    if: github.repository == 'vbenjs/vue-vben-admin'
    runs-on: ubuntu-latest
    needs: [test, check, lint]
    env:
      FAILURE: ${{ contains(join(needs.*.result, ','), 'failure') }}
    steps:
      - name: Check for failure
        run: |
          echo $FAILURE
          if [ "$FAILURE" = "false" ]; then
            exit 0
          else
            exit 1
          fi


================================================
FILE: .github/workflows/codeql.yml
================================================
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: 'CodeQL'

on:
  push:
    branches: ['main']
  pull_request:
    branches: ['main']
  schedule:
    - cron: '35 0 * * 0'

jobs:
  analyze:
    name: Analyze (${{ matrix.language }})
    if: github.repository == 'vbenjs/vue-vben-admin'
    # Runner size impacts CodeQL analysis time. To learn more, please see:
    #   - https://gh.io/recommended-hardware-resources-for-running-codeql
    #   - https://gh.io/supported-runners-and-hardware-resources
    #   - https://gh.io/using-larger-runners (GitHub.com only)
    # Consider using larger runners or machines with greater resources for possible analysis time improvements.
    runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
    timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
    permissions:
      # required for all workflows
      security-events: write

      # required to fetch internal or private CodeQL packs
      packages: read

      # only required for workflows in private repositories
      actions: read
      contents: read

    strategy:
      fail-fast: false
      matrix:
        include:
          - language: javascript-typescript
            build-mode: none
        # CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift'
        # Use `c-cpp` to analyze code written in C, C++ or both
        # Use 'java-kotlin' to analyze code written in Java, Kotlin or both
        # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
        # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
        # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
        # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
        # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6

      # Initializes the CodeQL tools for scanning.
      - name: Initialize CodeQL
        uses: github/codeql-action/init@v3
        with:
          languages: ${{ matrix.language }}
          build-mode: ${{ matrix.build-mode }}
          # If you wish to specify custom queries, you can do so here or in a config file.
          # By default, queries listed here will override any specified in a config file.
          # Prefix the list here with "+" to use these queries and those in the config file.

          # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
          # queries: security-extended,security-and-quality

      # If the analyze step fails for one of the languages you are analyzing with
      # "We were unable to automatically build your code", modify the matrix above
      # to set the build mode to "manual" for that language. Then modify this step
      # to build your code.
      # ℹ️ Command-line programs to run using the OS shell.
      # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
      - if: matrix.build-mode == 'manual'
        shell: bash
        run: |
          echo 'If you are using a "manual" build mode for one or more of the' \
            'languages you are analyzing, replace this with the commands to build' \
            'your code, for example:'
          echo '  make bootstrap'
          echo '  make release'
          exit 1

      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@v3
        with:
          category: '/language:${{matrix.language}}'


================================================
FILE: .github/workflows/deploy.yml
================================================
name: Deploy Website on push

on:
  push:
    branches:
      - main

jobs:
  deploy-playground-ftp:
    name: Deploy Push Playground Ftp
    if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]') && github.repository == 'vbenjs/vue-vben-admin'
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Sed Config Base
        shell: bash
        run: |
          sed -i  "s#VITE_COMPRESS\s*=.*#VITE_COMPRESS = gzip#g" ./playground/.env.production
          sed -i  "s#VITE_PWA\s*=.*#VITE_PWA = true#g" ./playground/.env.production
          cat ./playground/.env.production

      - name: Setup Node
        uses: ./.github/actions/setup-node

      - name: Build
        run: pnpm build:play

      - name: Sync Playground files
        uses: SamKirkland/FTP-Deploy-Action@v4.3.6
        with:
          server: ${{ secrets.PRO_FTP_HOST }}
          username: ${{ secrets.WEB_PLAYGROUND_FTP_ACCOUNT }}
          password: ${{ secrets.WEB_PLAYGROUND_FTP_PWSSWORD }}
          local-dir: ./playground/dist/

  deploy-docs-ftp:
    name: Deploy Push Docs Ftp
    if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]') && github.repository == 'vbenjs/vue-vben-admin'
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Setup Node
        uses: ./.github/actions/setup-node

      - name: Build
        run: pnpm build:docs

      - name: Sync Docs files
        uses: SamKirkland/FTP-Deploy-Action@v4.3.6
        with:
          server: ${{ secrets.PRO_FTP_HOST }}
          username: ${{ secrets.WEBSITE_FTP_ACCOUNT }}
          password: ${{ secrets.WEBSITE_FTP_PASSWORD }}
          local-dir: ./docs/.vitepress/dist/

  deploy-antd-ftp:
    name: Deploy Push Antd Ftp
    if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]') && github.repository == 'vbenjs/vue-vben-admin'
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Sed Config Base
        shell: bash
        run: |
          sed -i  "s#VITE_COMPRESS\s*=.*#VITE_COMPRESS = gzip#g" ./apps/web-antd/.env.production
          sed -i  "s#VITE_PWA\s*=.*#VITE_PWA = true#g" ./apps/web-antd/.env.production
          cat ./apps/web-antd/.env.production

      - name: Setup Node
        uses: ./.github/actions/setup-node

      - name: Build
        run: pnpm run build:antd

      - name: Sync files
        uses: SamKirkland/FTP-Deploy-Action@v4.3.6
        with:
          server: ${{ secrets.PRO_FTP_HOST }}
          username: ${{ secrets.WEB_ANTD_FTP_ACCOUNT }}
          password: ${{ secrets.WEB_ANTD_FTP_PASSWORD }}
          local-dir: ./apps/web-antd/dist/

  deploy-ele-ftp:
    name: Deploy Push Element Ftp
    if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]') && github.repository == 'vbenjs/vue-vben-admin'
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Sed Config Base
        shell: bash
        run: |
          sed -i  "s#VITE_COMPRESS\s*=.*#VITE_COMPRESS = gzip#g" ./apps/web-ele/.env.production
          sed -i  "s#VITE_PWA\s*=.*#VITE_PWA = true#g" ./apps/web-ele/.env.production
          cat ./apps/web-ele/.env.production

      - name: Setup Node
        uses: ./.github/actions/setup-node

      - name: Build
        run: pnpm run build:ele

      - name: Sync files
        uses: SamKirkland/FTP-Deploy-Action@v4.3.6
        with:
          server: ${{ secrets.PRO_FTP_HOST }}
          username: ${{ secrets.WEB_ELE_FTP_ACCOUNT }}
          password: ${{ secrets.WEB_ELE_FTP_PASSWORD }}
          local-dir: ./apps/web-ele/dist/

  deploy-naive-ftp:
    name: Deploy Push Naive Ftp
    if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]') && github.repository == 'vbenjs/vue-vben-admin'
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Sed Config Base
        shell: bash
        run: |
          sed -i  "s#VITE_COMPRESS\s*=.*#VITE_COMPRESS = gzip#g" ./apps/web-naive/.env.production
          sed -i  "s#VITE_PWA\s*=.*#VITE_PWA = true#g" ./apps/web-naive/.env.production
          cat ./apps/web-naive/.env.production

      - name: Setup Node
        uses: ./.github/actions/setup-node

      - name: Build
        run: pnpm run build:naive

      - name: Sync files
        uses: SamKirkland/FTP-Deploy-Action@v4.3.6
        with:
          server: ${{ secrets.PRO_FTP_HOST }}
          username: ${{ secrets.WEB_NAIVE_FTP_ACCOUNT }}
          password: ${{ secrets.WEB_NAIVE_FTP_PASSWORD }}
          local-dir: ./apps/web-naive/dist/

  rerun-on-failure:
    name: Rerun on failure
    needs:
      - deploy-playground-ftp
      - deploy-docs-ftp
      - deploy-antd-ftp
      - deploy-ele-ftp
      - deploy-naive-ftp
    if: failure() && fromJSON(github.run_attempt) < 10
    runs-on: ubuntu-latest
    steps:
      - name: Retry ${{ fromJSON(github.run_attempt) }} of 10
        env:
          GH_REPO: ${{ github.repository }}
          GH_TOKEN: ${{ github.token }}
        run: gh workflow run rerun.yml -F run_id=${{ github.run_id }}


================================================
FILE: .github/workflows/draft.yml
================================================
name: Release Drafter

on:
  push:
    branches:
      - main

permissions:
  contents: read
  pull-requests: write

jobs:
  update_release_draft:
    permissions:
      # write permission is required to create a github release
      contents: write
      # write permission is required for autolabeler
      # otherwise, read permission is required at least
      pull-requests: write
    if: github.repository == 'vbenjs/vue-vben-admin'
    runs-on: ubuntu-latest
    steps:
      - uses: release-drafter/release-drafter@v6
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/issue-close-require.yml
================================================
# 每天零点运行一次,它会检查所有带有 "need reproduction" 标签的 Issues。如果这些 Issues 在过去的 3 天内没有任何活动,它们将会被自动关闭。这有助于保持 Issue 列表的整洁,并且提醒用户在必要时提供更多的信息。
name: Issue Close Require

# 触发条件:每天零点
on:
  workflow_dispatch:
  schedule:
    - cron: '0 0 * * *'

permissions:
  pull-requests: write
  contents: write
  issues: write

jobs:
  close-issues:
    if: github.repository == 'vbenjs/vue-vben-admin'
    runs-on: ubuntu-latest
    steps:
      # 关闭未活动的 Issues
      - name: Close Inactive Issues
        uses: actions/stale@v9
        with:
          days-before-stale: -1 # Issues and PR will never be flagged stale automatically.
          stale-issue-label: needs-reproduction # Label that flags an issue as stale.
          only-labels: needs-reproduction # Only process these issues
          days-before-issue-close: 3
          ignore-updates: true
          remove-stale-when-updated: false
          close-issue-message: This issue was closed because it was open for 3 days without a valid reproduction.
          close-issue-label: closed-by-action


================================================
FILE: .github/workflows/issue-labeled.yml
================================================
name: Label Based Actions

on:
  issues:
    types: [labeled]
  # pull_request:
  #   types: [labeled]

permissions:
  issues: write
  pull-requests: write
  contents: write

jobs:
  reply-labeled:
    if: github.repository == 'vbenjs/vue-vben-admin'
    runs-on: ubuntu-latest
    steps:
      - name: remove enhancement pending
        if: github.event.label.name == 'enhancement'
        uses: actions-cool/issues-helper@v3
        with:
          actions: 'remove-labels'
          token: ${{ secrets.GITHUB_TOKEN }}
          issue-number: ${{ github.event.issue.number }}
          labels: 'enhancement: pending triage'

      - name: remove bug pending
        if: github.event.label.name == 'bug'
        uses: actions-cool/issues-helper@v3
        with:
          actions: 'remove-labels'
          token: ${{ secrets.GITHUB_TOKEN }}
          issue-number: ${{ github.event.issue.number }}
          labels: 'bug: pending triage'

      - name: needs reproduction
        if: github.event.label.name == 'needs reproduction'
        uses: actions-cool/issues-helper@v3
        with:
          actions: 'create-comment, remove-labels'
          token: ${{ secrets.GITHUB_TOKEN }}
          issue-number: ${{ github.event.issue.number }}
          body: |
            Hello @${{ github.event.issue.user.login }}. Please provide the complete reproduction steps and code. Issues labeled by `needs reproduction` will be closed if no activities in 3 days.
          labels: 'bug: pending triage'


================================================
FILE: .github/workflows/lock.yml
================================================
name: Lock Threads

on:
  schedule:
    - cron: '0 0 * * *'
  workflow_dispatch:

permissions:
  issues: write
  pull-requests: write

jobs:
  action:
    if: github.repository == 'vbenjs/vue-vben-admin'
    runs-on: ubuntu-latest
    steps:
      - uses: dessant/lock-threads@v5
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          issue-inactive-days: '14'
          issue-lock-reason: ''
          pr-inactive-days: '30'
          pr-lock-reason: ''
          process-only: 'issues, prs'


================================================
FILE: .github/workflows/release-tag.yml
================================================
name: Create Release Tag

on:
  push:
    tags:
      - 'v*.*.*' # Push events to matching v*, i.e. v1.0, v20.15.10

env:
  HUSKY: '0'

permissions:
  pull-requests: write
  contents: write

jobs:
  build:
    name: Create Release
    if: github.repository == 'vbenjs/vue-vben-admin'
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [22]
    steps:
      - name: Checkout code
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

      # - name: Checkout code
      #   uses: actions/checkout@v6
      #   with:
      #     fetch-depth: 0

      # - name: Install pnpm
      #   uses: pnpm/action-setup@v4

      # - name: Use Node.js ${{ matrix.node-version }}
      #   uses: actions/setup-node@v4
      #   with:
      #     node-version: ${{ matrix.node-version }}
      #     cache: "pnpm"

      # - name: Install dependencies
      #   run: pnpm install --frozen-lockfile

      # - name: Test and Build
      #   run: |
      #     pnpm run test
      #     pnpm run build

      - name: version
        id: version
        run: |
          tag=${GITHUB_REF/refs\/tags\//}
          version=${tag#v}
          major=${version%%.*}
          echo "tag=${tag}" >> $GITHUB_OUTPUT
          echo "version=${version}" >> $GITHUB_OUTPUT
          echo "major=${major}" >> $GITHUB_OUTPUT

      - uses: release-drafter/release-drafter@v6
        with:
          version: ${{ steps.version.outputs.version }}
          publish: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      # - name: force update major tag
      #   run: |
      #     git tag v${{ steps.version.outputs.major }} ${{ steps.version.outputs.tag }} -f
      #     git push origin refs/tags/v${{ steps.version.outputs.major }} -f

      # - name: Create Release for Tag
      #   id: release_tag
      #   uses: ncipollo/release-action@v1
      #   with:
      #     token: ${{ secrets.GITHUB_TOKEN }}
      #     generateReleaseNotes: "true"
      #     body: |
      #       > Please refer to [CHANGELOG.md](https://github.com/vbenjs/vue-vben-admin/blob/main/CHANGELOG.md) for details.


================================================
FILE: .github/workflows/rerun.yml
================================================
name: Rerun workflow

on:
  workflow_dispatch:
    inputs:
      run_id:
        description: The workflow id to relanch
        required: true
jobs:
  rerun:
    runs-on: ubuntu-latest
    steps:
      - name: rerun ${{ inputs.run_id }}
        env:
          GH_REPO: ${{ github.repository }}
          GH_TOKEN: ${{ github.token }}
        run: |
          gh run watch ${{ inputs.run_id }} > /dev/null 2>&1
          gh run rerun ${{ inputs.run_id }} --failed


================================================
FILE: .github/workflows/semantic-pull-request.yml
================================================
name: Semantic Pull Request

on:
  pull_request_target:
    types:
      - opened
      - edited
      - synchronize

jobs:
  main:
    name: Semantic Pull Request
    if: github.repository == 'vbenjs/vue-vben-admin'
    runs-on: ubuntu-latest
    steps:
      - name: Validate PR title
        uses: amannn/action-semantic-pull-request@v5
        with:
          wip: true
          subjectPattern: ^(?![A-Z]).+$
          subjectPatternError: |
            The subject "{subject}" found in the pull request title "{title}"
            didn't match the configured pattern. Please ensure that the subject
            doesn't start with an uppercase character.
          requireScope: false
          types: |
            fix
            feat
            docs
            style
            refactor
            perf
            test
            build
            ci
            chore
            revert
            types
            release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/stale.yml
================================================
name: 'Close stale issues'

on:
  schedule:
    - cron: '0 1 * * *'

jobs:
  stale:
    if: github.repository == 'vbenjs/vue-vben-admin'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/stale@v9
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days'
          stale-pr-message: 'This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days'
          exempt-issue-labels: 'bug,enhancement'
          days-before-stale: 60
          days-before-close: 7


================================================
FILE: .gitignore
================================================
node_modules
.DS_Store
dist
dist-ssr
dist.zip
dist.tar
dist.war
.nitro
.output
*-dist.zip
*-dist.tar
*-dist.war
coverage
*.local
**/.vitepress/cache
.cache
.turbo
.temp
dev-dist
.stylelintcache
yarn.lock
package-lock.json
.VSCodeCounter
**/backend-mock/data

# local env files
.env.local
.env.*.local
.eslintcache

logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
vite.config.mts.*
vite.config.mjs.*
vite.config.js.*
vite.config.ts.*

# Editor directories and files
.idea
# .vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
.history
.cursor

# AI
.agent
.agents
.claude
.codex
skills-lock.json


================================================
FILE: .gitpod.yml
================================================
ports:
  - port: 5555
    onOpen: open-preview
tasks:
  - init: npm i -g corepack && pnpm install
    command: pnpm run dev:play


================================================
FILE: .node-version
================================================
22.22.0


================================================
FILE: .npmrc
================================================
registry=https://registry.npmmirror.com
public-hoist-pattern[]=lefthook
public-hoist-pattern[]=eslint
public-hoist-pattern[]=oxfmt
public-hoist-pattern[]=oxlint
public-hoist-pattern[]=stylelint
public-hoist-pattern[]=*postcss*
public-hoist-pattern[]=@commitlint/*
public-hoist-pattern[]=czg

strict-peer-dependencies=false
auto-install-peers=true
dedupe-peer-dependents=true


================================================
FILE: .stylelintignore
================================================
dist
public
__tests__
coverage
.codex
.claude
.agent
.agents


================================================
FILE: .vscode/extensions.json
================================================
{
  "recommendations": [
    // Vue 3 的语言支持
    "Vue.volar",
    // 将 eslint 集成到 VS Code 中。
    "dbaeumer.vscode-eslint",
    // 将 oxlint 集成到 VS Code 中。
    "oxc.oxc-vscode",
    // Visual Studio Code 的官方 Stylelint 扩展
    "stylelint.vscode-stylelint",
    // 使用 oxfmt 的代码格式化程序
    "oxc.oxc-vscode",
    // 支持 dotenv 文件语法
    "mikestead.dotenv",
    // YAML 语言支持,供 ESLint 校验 pnpm-workspace.yaml 等文件
    "redhat.vscode-yaml",
    // 源代码的拼写检查器
    "streetsidesoftware.code-spell-checker",
    // Tailwind CSS 的官方 VS Code 插件
    "bradlc.vscode-tailwindcss",
    // iconify 图标插件
    "antfu.iconify",
    // i18n 插件
    "Lokalise.i18n-ally",
    // CSS 变量提示
    "vunguyentuan.vscode-css-variables",
    // 在 package.json 中显示 PNPM catalog 的版本
    "antfu.pnpm-catalog-lens"
  ],
  "unwantedRecommendations": [
    // 和 volar 冲突
    "octref.vetur"
  ]
}


================================================
FILE: .vscode/global.code-snippets
================================================
{
  "import": {
    "scope": "javascript,typescript",
    "prefix": "im",
    "body": ["import { $2 } from '$1';"],
    "description": "Import a module",
  },
  "export-all": {
    "scope": "javascript,typescript",
    "prefix": "ex",
    "body": ["export * from '$1';"],
    "description": "Export a module",
  },
  "vue-script-setup": {
    "scope": "vue",
    "prefix": "<sc",
    "body": [
      "<script setup lang=\"ts\">",
      "const props = defineProps<{",
      "  modelValue?: boolean,",
      "}>()",
      "$1",
      "</script>",
      "",
      "<template>",
      "  <div>",
      "    <slot/>",
      "  </div>",
      "</template>",
    ],
  },
  "vue-computed": {
    "scope": "javascript,typescript,vue",
    "prefix": "com",
    "body": ["computed(() => { $1 })"],
  },
}


================================================
FILE: .vscode/launch.json
================================================
{
  "$schema": "https://json.schemastore.org/launchsettings.json",
  "version": "0.2.0",
  "configurations": [
    {
      "type": "chrome",
      "name": "vben admin playground dev",
      "request": "launch",
      "url": "http://localhost:5555",
      "env": { "NODE_ENV": "development" },
      "sourceMaps": true,
      "webRoot": "${workspaceFolder}/playground"
    },
    {
      "type": "chrome",
      "name": "vben admin antd dev",
      "request": "launch",
      "url": "http://localhost:5666",
      "env": { "NODE_ENV": "development" },
      "sourceMaps": true,
      "webRoot": "${workspaceFolder}/apps/web-antd"
    },
    {
      "type": "chrome",
      "name": "vben admin ele dev",
      "request": "launch",
      "url": "http://localhost:5777",
      "env": { "NODE_ENV": "development" },
      "sourceMaps": true,
      "webRoot": "${workspaceFolder}/apps/web-ele"
    },
    {
      "type": "chrome",
      "name": "vben admin naive dev",
      "request": "launch",
      "url": "http://localhost:5888",
      "env": { "NODE_ENV": "development" },
      "sourceMaps": true,
      "webRoot": "${workspaceFolder}/apps/web-naive"
    }
  ]
}


================================================
FILE: .vscode/settings.json
================================================
{
  "tailwindCSS.experimental.configFile": "internal/tailwind-config/src/theme.css",
  "tailwindCSS.lint.suggestCanonicalClasses": "ignore",
  // workbench
  "workbench.list.smoothScrolling": true,
  "workbench.startupEditor": "newUntitledFile",
  "workbench.tree.indent": 10,
  "workbench.editor.highlightModifiedTabs": true,
  "workbench.editor.closeOnFileDelete": true,
  "workbench.editor.limit.enabled": true,
  "workbench.editor.limit.perEditorGroup": true,
  "workbench.editor.limit.value": 5,

  // editor
  "editor.tabSize": 2,
  "editor.detectIndentation": false,
  "editor.cursorBlinking": "expand",
  "editor.largeFileOptimizations": true,
  "editor.accessibilitySupport": "off",
  "editor.cursorSmoothCaretAnimation": "on",
  "editor.guides.bracketPairs": "active",
  "editor.inlineSuggest.enabled": true,
  "editor.suggestSelection": "recentlyUsedByPrefix",
  "editor.acceptSuggestionOnEnter": "smart",
  "editor.suggest.snippetsPreventQuickSuggestions": false,
  "editor.stickyScroll.enabled": true,
  "editor.hover.sticky": true,
  "editor.suggest.insertMode": "replace",
  "editor.bracketPairColorization.enabled": true,
  "editor.autoClosingBrackets": "beforeWhitespace",
  "editor.autoClosingDelete": "always",
  "editor.autoClosingOvertype": "always",
  "editor.autoClosingQuotes": "beforeWhitespace",
  "editor.wordSeparators": "`~!@#%^&*()=+[{]}\\|;:'\",.<>/?",
  "editor.quickSuggestions": {
    "strings": "on"
  },

  // lint && format
  "oxc.enable": true,
  "oxc.typeAware": true,
  "oxc.configPath": "oxlint.config.ts",
  "oxc.fmt.configPath": "oxfmt.config.ts",
  "eslint.useFlatConfig": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit",
    "source.fixAll.oxc": "explicit",
    "source.fixAll.stylelint": "explicit",
    "source.organizeImports": "never"
  },
  "editor.defaultFormatter": "oxc.oxc-vscode",
  "[html]": {
    "editor.defaultFormatter": "oxc.oxc-vscode"
  },
  "[css]": {
    "editor.defaultFormatter": "oxc.oxc-vscode"
  },
  "[scss]": {
    "editor.defaultFormatter": "oxc.oxc-vscode"
  },
  "[javascript]": {
    "editor.defaultFormatter": "oxc.oxc-vscode"
  },
  "[typescript]": {
    "editor.defaultFormatter": "oxc.oxc-vscode"
  },
  "[json]": {
    "editor.defaultFormatter": "oxc.oxc-vscode"
  },
  "[markdown]": {
    "editor.defaultFormatter": "oxc.oxc-vscode"
  },
  "[jsonc]": {
    "editor.defaultFormatter": "oxc.oxc-vscode"
  },
  "[vue]": {
    "editor.defaultFormatter": "oxc.oxc-vscode"
  },

  // extensions
  "extensions.ignoreRecommendations": true,

  // terminal
  "terminal.integrated.cursorBlinking": true,
  "terminal.integrated.persistentSessionReviveProcess": "never",
  "terminal.integrated.tabs.enabled": true,
  "terminal.integrated.scrollback": 10000,
  "terminal.integrated.stickyScroll.enabled": true,

  // files
  "files.eol": "\n",
  "files.insertFinalNewline": true,
  "files.simpleDialog.enable": true,
  "files.associations": {
    "*.css": "tailwindcss",
    "*.ejs": "html",
    "*.art": "html",
    "**/tsconfig.json": "jsonc",
    "*.json": "jsonc",
    "package.json": "json"
  },

  "files.exclude": {
    "**/.eslintcache": true,
    "**/bower_components": true,
    "**/.turbo": true,
    "**/.idea": true,
    "**/.vitepress": true,
    "**/tmp": true,
    "**/.git": true,
    "**/.svn": true,
    "**/.hg": true,
    "**/CVS": true,
    "**/.stylelintcache": true,
    "**/.DS_Store": true,
    "**/vite.config.mts.*": true,
    "**/tea.yaml": true
  },
  "files.watcherExclude": {
    "**/.git/objects/**": true,
    "**/.git/subtree-cache/**": true,
    "**/.vscode/**": true,
    "**/node_modules/**": true,
    "**/tmp/**": true,
    "**/bower_components/**": true,
    "**/dist/**": true,
    "**/yarn.lock": true
  },

  "typescript.tsserver.exclude": ["**/node_modules", "**/dist", "**/.turbo"],

  // search
  "search.searchEditor.singleClickBehaviour": "peekDefinition",
  "search.followSymlinks": false,
  // 使用搜索功能时,将这些文件和文件夹排除在外
  "search.exclude": {
    "**/node_modules": true,
    "**/*.log": true,
    "**/*.log*": true,
    "**/bower_components": true,
    "**/dist": true,
    "**/elehukouben": true,
    "**/.git": true,
    "**/.github": true,
    "**/.gitignore": true,
    "**/.svn": true,
    "**/.DS_Store": true,
    "**/.vitepress/cache": true,
    "**/.idea": true,
    "**/.vscode": false,
    "**/.yarn": true,
    "**/tmp": true,
    "*.xml": true,
    "out": true,
    "dist": true,
    "node_modules": true,
    "CHANGELOG.md": true,
    "**/pnpm-lock.yaml": true,
    "**/yarn.lock": true
  },

  "debug.onTaskErrors": "debugAnyway",
  "diffEditor.ignoreTrimWhitespace": false,
  "npm.packageManager": "pnpm",

  "css.validate": false,
  "less.validate": false,
  "scss.validate": false,

  // extension
  "emmet.showSuggestionsAsSnippets": true,
  "emmet.triggerExpansionOnTab": false,

  "errorLens.enabledDiagnosticLevels": ["warning", "error"],
  "errorLens.excludeBySource": ["cSpell", "Grammarly"],

  "stylelint.enable": true,
  "stylelint.packageManager": "pnpm",
  "stylelint.validate": ["css", "less", "postcss", "scss", "vue"],
  "stylelint.customSyntax": "postcss-html",
  "stylelint.snippet": ["css", "less", "postcss", "scss", "vue"],

  "typescript.inlayHints.enumMemberValues.enabled": true,
  "typescript.preferences.preferTypeOnlyAutoImports": true,
  "typescript.preferences.includePackageJsonAutoImports": "on",

  "eslint.validate": [
    "javascript",
    "typescript",
    "javascriptreact",
    "typescriptreact",
    "vue",
    "html",
    "markdown",
    "json",
    "jsonc",
    "json5",
    "yaml"
  ],

  "tailwindCSS.experimental.classRegex": [
    ["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]
  ],

  "github.copilot.enable": {
    "*": true,
    "markdown": true,
    "plaintext": false,
    "yaml": false
  },

  "cssVariables.lookupFiles": ["packages/@core/base/design/src/**/*.css"],

  "i18n-ally.localesPaths": [
    "packages/locales/src/langs",
    "playground/src/locales/langs",
    "apps/*/src/locales/langs"
  ],
  "i18n-ally.pathMatcher": "{locale}/{namespace}.{ext}",
  "i18n-ally.enabledParsers": ["json"],
  "i18n-ally.sourceLanguage": "en",
  "i18n-ally.displayLanguage": "zh-CN",
  "i18n-ally.enabledFrameworks": ["vue", "react"],
  "i18n-ally.keystyle": "nested",
  "i18n-ally.sortKeys": true,
  "i18n-ally.namespace": true,

  // 控制相关文件嵌套展示
  "explorer.fileNesting.enabled": true,
  "explorer.fileNesting.expand": false,
  "explorer.fileNesting.patterns": {
    "*.ts": "$(capture).test.ts, $(capture).test.tsx, $(capture).spec.ts, $(capture).spec.tsx, $(capture).d.ts",
    "*.tsx": "$(capture).test.ts, $(capture).test.tsx, $(capture).spec.ts, $(capture).spec.tsx,$(capture).d.ts",
    "*.env": "$(capture).env.*",
    "README.md": "README*,CHANGELOG*,LICENSE,CNAME",
    "package.json": "pnpm-lock.yaml,pnpm-workspace.yaml,.gitattributes,.gitignore,.gitpod.yml,.npmrc,.browserslistrc,.node-version,.git*,.tazerc.json",
    "oxlint.config.ts": ".eslintignore,.stylelintignore,.commitlintrc.*,stylelint.config.*,.lintstagedrc.mjs,cspell.json,lefthook.yml,oxfmt.config.*,eslint.config.*"
  },
  "commentTranslate.hover.enabled": false,
  "commentTranslate.multiLineMerge": true,
  "vue.server.hybridMode": true,
  "typescript.tsdk": "node_modules/typescript/lib"
}


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2024-present, Vben

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.ja-JP.md
================================================
<div align="center">
  <a href="https://github.com/anncwb/vue-vben-admin">
    <img alt="VbenAdmin Logo" width="215" src="https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp">
  </a>
  <br>
  <br>

[![license](https://img.shields.io/github/license/anncwb/vue-vben-admin.svg)](LICENSE)

  <h1>Vue Vben Admin</h1>
</div>

[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=vbenjs_vue-vben-admin&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=vbenjs_vue-vben-admin) ![codeql](https://github.com/vbenjs/vue-vben-admin/actions/workflows/codeql.yml/badge.svg) ![build](https://github.com/vbenjs/vue-vben-admin/actions/workflows/build.yml/badge.svg) ![ci](https://github.com/vbenjs/vue-vben-admin/actions/workflows/ci.yml/badge.svg) ![deploy](https://github.com/vbenjs/vue-vben-admin/actions/workflows/deploy.yml/badge.svg)

**日本語** | [English](./README.md) | [中文](./README.zh-CN.md)

## 紹介

Vue Vben Adminは、最新の`vue3`、`vite`、`TypeScript`などの主流技術を使用して開発された、無料でオープンソースの中・後端テンプレートです。すぐに使える中・後端のフロントエンドソリューションとして、学習の参考にもなります。

## アップグレード通知

これは最新バージョン `5.0` であり、以前のバージョンとは互換性がありません。新しいプロジェクトを開始する場合は、最新バージョンを使用することをお勧めします。古いバージョンを表示したい場合は、[v2ブランチ](https://github.com/vbenjs/vue-vben-admin/tree/v2)を使用してください。

## 特徴

- **最新技術スタック**:Vue 3やViteなどの最先端フロントエンド技術で開発
- **TypeScript**:アプリケーション規模のJavaScriptのための言語
- **テーマ**:複数のテーマカラーが利用可能で、カスタマイズオプションも豊富
- **国際化**:完全な内蔵国際化サポート
- **権限管理**:動的ルートベースの権限生成ソリューションを内蔵

## プレビュー

- [Vben Admin](https://vben.pro/) - フルバージョンの中国語サイト

テストアカウント:vben/123456

<div align="center">
  <img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview1.png">
  <img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview2.png">
  <img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview3.png">
</div>

### Gitpodを使用

Gitpod(GitHub用の無料オンライン開発環境)でプロジェクトを開き、すぐにコーディングを開始します。

[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/vbenjs/vue-vben-admin)

## ドキュメント

[ドキュメント](https://doc.vben.pro/)

## インストールと使用

1. プロジェクトコードを取得

```bash
git clone https://github.com/vbenjs/vue-vben-admin.git
```

2. 依存関係のインストール

```bash
cd vue-vben-admin
npm i -g corepack
pnpm install
```

3. 実行

```bash
pnpm dev
```

4. ビルド

```bash
pnpm build
```

## 変更ログ

[CHANGELOG](https://github.com/vbenjs/vue-vben-admin/releases)

## 貢献方法

ご参加をお待ちしております![Issueを提出](https://github.com/anncwb/vue-vben-admin/issues/new/choose)するか、Pull Requestを送信してください。

**Pull Request プロセス:**

1. コードをフォーク
2. 自分のブランチを作成:`git checkout -b feat/xxxx`
3. 変更をコミット:`git commit -am 'feat(function): add xxxxx'`
4. ブランチをプッシュ:`git push origin feat/xxxx`
5. `pull request`を送信

## Git貢献提出規則

参考 [vue](https://github.com/vuejs/vue/blob/dev/.github/COMMIT_CONVENTION.md) 規則 ([Angular](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular))

- `feat` 新機能の追加
- `fix` 問題/バグの修正
- `style` コードスタイルに関連し、実行結果に影響しない
- `perf` 最適化/パフォーマンス向上
- `refactor` リファクタリング
- `revert` 変更の取り消し
- `test` テスト関連
- `docs` ドキュメント/注釈
- `chore` 依存関係の更新/スキャフォールディング設定の変更など
- `ci` 継続的インテグレーション
- `types` 型定義ファイルの変更

## ブラウザサポート

ローカル開発には `Chrome 80+` ブラウザを推奨します

モダンブラウザをサポートし、IEはサポートしません

| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
| :-: | :-: | :-: | :-: |
| 最新2バージョン | 最新2バージョン | 最新2バージョン | 最新2バージョン |

## メンテナー

[@Vben](https://github.com/anncwb)

## スター歴史

[![Star History Chart](https://api.star-history.com/svg?repos=vbenjs/vue-vben-admin&type=Date)](https://star-history.com/#vbenjs/vue-vben-admin&Date)

## 寄付

このプロジェクトが役に立つと思われた場合、作者にコーヒーを一杯おごってサポートを示すことができます!

![donate](https://unpkg.com/@vbenjs/static-source@0.1.7/source/sponsor.png)

<a style="display: block;width: 100px;height: 50px;line-height: 50px; color: #fff;text-align: center; background: #408aed;border-radius: 4px;" href="https://www.paypal.com/paypalme/cvvben">Paypal Me</a>

## 貢献者

<a href="https://openomy.app/github/vbenjs/vue-vben-admin" target="_blank" style="display: block; width: 100%;" align="center">
  <img src="https://openomy.app/svg?repo=vbenjs/vue-vben-admin&chart=bubble&latestMonth=3" target="_blank" alt="Contribution Leaderboard" style="display: block; width: 100%;" />
 </a>

<a href="https://github.com/vbenjs/vue-vben-admin/graphs/contributors">
  <img alt="Contributors" src="https://contrib.rocks/image?repo=vbenjs/vue-vben-admin" />
</a>

## Discord

- [Github Discussions](https://github.com/anncwb/vue-vben-admin/discussions)

## ライセンス

[MIT © Vben-2020](./LICENSE)


================================================
FILE: README.md
================================================
<div align="center">
  <a href="https://github.com/anncwb/vue-vben-admin">
    <img alt="VbenAdmin Logo" width="215" src="https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp">
  </a>
  <br>
  <br>

[![license](https://img.shields.io/github/license/anncwb/vue-vben-admin.svg)](LICENSE)

  <h1>Vue Vben Admin</h1>
</div>

[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=vbenjs_vue-vben-admin&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=vbenjs_vue-vben-admin) [![codeql](https://github.com/vbenjs/vue-vben-admin/actions/workflows/codeql.yml/badge.svg)](https://github.com/vbenjs/vue-vben-admin/actions/workflows/codeql.yml) [![build](https://github.com/vbenjs/vue-vben-admin/actions/workflows/build.yml/badge.svg)](https://github.com/vbenjs/vue-vben-admin/actions/workflows/build.yml) [![ci](https://github.com/vbenjs/vue-vben-admin/actions/workflows/ci.yml/badge.svg)](https://github.com/vbenjs/vue-vben-admin/actions/workflows/ci.yml) [![deploy](https://github.com/vbenjs/vue-vben-admin/actions/workflows/deploy.yml/badge.svg)](https://github.com/vbenjs/vue-vben-admin/actions/workflows/deploy.yml)

**English** | [中文](./README.zh-CN.md) | [日本語](./README.ja-JP.md)

## Introduction

Vue Vben Admin is a free and open source middle and back-end template. Using the latest `vue3`, `vite`, `TypeScript` and other mainstream technology development, the out-of-the-box middle and back-end front-end solutions can also be used for learning reference.

## Upgrade Notice

This is the latest version, 5.0, and it is not compatible with previous versions. If you are starting a new project, it is recommended to use the latest version. If you wish to view the old version, please use the [v2 branch](https://github.com/vbenjs/vue-vben-admin/tree/v2).

## Features

- **Latest Technology Stack**: Developed with cutting-edge front-end technologies like Vue 3 and Vite
- **TypeScript**: A language for application-scale JavaScript
- **Themes**: Multiple theme colors available with customizable options
- **Internationalization**: Comprehensive built-in internationalization support
- **Permissions**: Built-in solution for dynamic route-based permission generation

## Preview

- [Vben Admin](https://vben.pro/) - Full version Chinese site

Test Account: vben/123456

<div align="center">
  <img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview1.png">
  <img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview2.png">
  <img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview3.png">
</div>

### Use Gitpod

Open the project in Gitpod (free online dev environment for GitHub) and start coding immediately.

[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/vbenjs/vue-vben-admin)

## Documentation

[Document](https://doc.vben.pro/)

## Install and Use

1. Get the project code

```bash
git clone https://github.com/vbenjs/vue-vben-admin.git
```

2. Install dependencies

```bash
cd vue-vben-admin
npm i -g corepack
pnpm install
```

3. Run

```bash
pnpm dev
```

4. Build

```bash
pnpm build
```

## Change Log

[CHANGELOG](https://github.com/vbenjs/vue-vben-admin/releases)

## How to Contribute

You are very welcome to join! [Raise an issue](https://github.com/anncwb/vue-vben-admin/issues/new/choose) or submit a Pull Request.

**Pull Request Process:**

1. Fork the code
2. Create your branch: `git checkout -b feat/xxxx`
3. Submit your changes: `git commit -am 'feat(function): add xxxxx'`
4. Push your branch: `git push origin feat/xxxx`
5. Submit `pull request`

## Git Contribution Submission Specification

Reference [vue](https://github.com/vuejs/vue/blob/dev/.github/COMMIT_CONVENTION.md) specification ([Angular](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular))

- `feat` Add new features
- `fix` Fix the problem/BUG
- `style` The code style is related and does not affect the running result
- `perf` Optimization/performance improvement
- `refactor` Refactor
- `revert` Undo edit
- `test` Test related
- `docs` Documentation/notes
- `chore` Dependency update/scaffolding configuration modification etc.
- `ci` Continuous integration
- `types` Type definition file changes

## Browser Support

The `Chrome 80+` browser is recommended for local development

Support modern browsers, not IE

| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
| :-: | :-: | :-: | :-: |
| last 2 versions | last 2 versions | last 2 versions | last 2 versions |

## Maintainer

[@Vben](https://github.com/anncwb)

## Star History

[![Star History Chart](https://api.star-history.com/svg?repos=vbenjs/vue-vben-admin&type=Date)](https://star-history.com/#vbenjs/vue-vben-admin&Date)

## Donate

If you think this project is helpful to you, you can help the author buy a cup of coffee to show your support!

![donate](https://unpkg.com/@vbenjs/static-source@0.1.7/source/sponsor.png)

<a style="display: block;width: 100px;height: 50px;line-height: 50px; color: #fff;text-align: center; background: #408aee;border-radius: 4px;" href="https://www.paypal.com/paypalme/cvvben">Paypal Me</a>

## Contributors

<a href="https://openomy.app/github/vbenjs/vue-vben-admin" target="_blank" style="display: block; width: 100%;" align="center">
  <img src="https://openomy.app/svg?repo=vbenjs/vue-vben-admin&chart=bubble&latestMonth=3" target="_blank" alt="Contribution Leaderboard" style="display: block; width: 100%;" />
 </a>

<a href="https://github.com/vbenjs/vue-vben-admin/graphs/contributors">
  <img alt="Contributors" src="https://contrib.rocks/image?repo=vbenjs/vue-vben-admin" />
</a>

## Discord

- [Github Discussions](https://github.com/anncwb/vue-vben-admin/discussions)

## License

[MIT © Vben-2020](./LICENSE)


================================================
FILE: README.zh-CN.md
================================================
<div align="center">
  <a href="https://github.com/anncwb/vue-vben-admin">
    <img alt="VbenAdmin Logo" width="215" src="https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp">
  </a>
  <br>
  <br>

[![license](https://img.shields.io/github/license/anncwb/vue-vben-admin.svg)](LICENSE)

  <h1>Vue Vben Admin</h1>
</div>

[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=vbenjs_vue-vben-admin&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=vbenjs_vue-vben-admin) ![codeql](https://github.com/vbenjs/vue-vben-admin/actions/workflows/codeql.yml/badge.svg) ![build](https://github.com/vbenjs/vue-vben-admin/actions/workflows/build.yml/badge.svg) ![ci](https://github.com/vbenjs/vue-vben-admin/actions/workflows/ci.yml/badge.svg) ![deploy](https://github.com/vbenjs/vue-vben-admin/actions/workflows/deploy.yml/badge.svg)

**中文** | [English](./README.md) | [日本語](./README.ja-JP.md)

## 简介

Vue Vben Admin 是 Vue Vben Admin 的升级版本。作为一个免费开源的中后台模板,它采用了最新的 Vue 3、Vite、TypeScript 等主流技术开发,开箱即用,可用于中后台前端开发,也适合学习参考。

## 升级提示

该版本为最新版本 `5.0`,与其他版本不兼容,如果你是新项目,建议使用最新版本。如果你想查看旧版本,请使用 [v2 分支](https://github.com/vbenjs/vue-vben-admin/tree/v2)

## 特性

- **最新技术栈**:使用 Vue3/vite 等前端前沿技术开发
- **TypeScript**:应用程序级 JavaScript 的语言
- **主题**:提供多套主题色彩,可配置自定义主题
- **国际化**:内置完善的国际化方案
- **权限**:内置完善的动态路由权限生成方案

## 预览

- [Vben Admin](https://vben.pro/) - 完整版中文站点

测试账号:vben/123456

<div align="center">
  <img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview1.png">
  <img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview2.png">
  <img alt="VbenAdmin Logo" width="100%" src="https://anncwb.github.io/anncwb/images/preview3.png">
</div>

### 使用 Gitpod

在 Gitpod(适用于 GitHub 的免费在线开发环境)中打开项目,并立即开始编码。

[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/vbenjs/vue-vben-admin)

## 文档

[文档地址](https://doc.vben.pro/)

## 安装使用

1. 获取项目代码

```bash
git clone https://github.com/vbenjs/vue-vben-admin.git
```

2. 安装依赖

```bash
cd vue-vben-admin
npm i -g corepack
pnpm install
```

3. 运行

```bash
pnpm dev
```

4. 打包

```bash
pnpm build
```

## 更新日志

[CHANGELOG](https://github.com/vbenjs/vue-vben-admin/releases)

## 如何贡献

非常欢迎你的加入![提一个 Issue](https://github.com/anncwb/vue-vben-admin/issues/new/choose) 或者提交一个 Pull Request。

**Pull Request 流程:**

1. Fork 代码
2. 创建自己的分支:`git checkout -b feature/xxxx`
3. 提交你的修改:`git commit -am 'feat(function): add xxxxx'`
4. 推送您的分支:`git push origin feature/xxxx`
5. 提交 `pull request`

## Git 贡献提交规范

参考 [vue](https://github.com/vuejs/vue/blob/dev/.github/COMMIT_CONVENTION.md) 规范 ([Angular](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular))

- `feat` 增加新功能
- `fix` 修复问题/BUG
- `style` 代码风格相关无影响运行结果的
- `perf` 优化/性能提升
- `refactor` 重构
- `revert` 撤销修改
- `test` 测试相关
- `docs` 文档/注释
- `chore` 依赖更新/脚手架配置修改等
- `ci` 持续集成
- `types` 类型定义文件更改

## 浏览器支持

本地开发推荐使用 `Chrome 80+` 浏览器

支持现代浏览器,不支持 IE

| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
| :-: | :-: | :-: | :-: |
| last 2 versions | last 2 versions | last 2 versions | last 2 versions |

## 维护者

[@Vben](https://github.com/anncwb)

## Star 历史

[![Star History Chart](https://api.star-history.com/svg?repos=vbenjs/vue-vben-admin&type=Date)](https://star-history.com/#vbenjs/vue-vben-admin&Date)

## 捐赠

如果你觉得这个项目对你有帮助,你可以帮作者买一杯咖啡表示支持!

![donate](https://unpkg.com/@vbenjs/static-source@0.1.7/source/sponsor.png)

<a style="display: block;width: 100px;height: 50px;line-height: 50px; color: #fff;text-align: center; background: #408aed;border-radius: 4px;" href="https://www.paypal.com/paypalme/cvvben">Paypal Me</a>

## 贡献者

<a href="https://openomy.app/github/vbenjs/vue-vben-admin" target="_blank" style="display: block; width: 100%;" align="center">
  <img src="https://openomy.app/svg?repo=vbenjs/vue-vben-admin&chart=bubble&latestMonth=3" target="_blank" alt="Contribution Leaderboard" style="display: block; width: 100%;" />
 </a>

<a href="https://github.com/vbenjs/vue-vben-admin/graphs/contributors">
  <img alt="Contributors" src="https://contrib.rocks/image?repo=vbenjs/vue-vben-admin" />
</a>

## Discord

- [Github Discussions](https://github.com/anncwb/vue-vben-admin/discussions)

## 许可证

[MIT © Vben-2020](./LICENSE)


================================================
FILE: apps/backend-mock/README.md
================================================
# @vben/backend-mock

## Description

Vben Admin 数据 mock 服务,没有对接任何的数据库,所有数据都是模拟的,用于前端开发时提供数据支持。线上环境不再提供 mock 集成,可自行部署服务或者对接真实数据,由于 `mock.js` 等工具有一些限制,比如上传文件不行、无法模拟复杂的逻辑等,所以这里使用了真实的后端服务来实现。唯一麻烦的是本地需要同时启动后端服务和前端服务,但是这样可以更好的模拟真实环境。该服务不需要手动启动,已经集成在 vite 插件内,随应用一起启用。

## Running the app

```bash
# development
$ pnpm run start

# production mode
$ pnpm run build
```


================================================
FILE: apps/backend-mock/api/auth/codes.ts
================================================
import { eventHandler } from 'h3';
import { verifyAccessToken } from '~/utils/jwt-utils';
import { MOCK_CODES } from '~/utils/mock-data';
import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';

export default eventHandler((event) => {
  const userinfo = verifyAccessToken(event);
  if (!userinfo) {
    return unAuthorizedResponse(event);
  }

  const codes =
    MOCK_CODES.find((item) => item.username === userinfo.username)?.codes ?? [];

  return useResponseSuccess(codes);
});


================================================
FILE: apps/backend-mock/api/auth/login.post.ts
================================================
import { defineEventHandler, readBody, setResponseStatus } from 'h3';
import {
  clearRefreshTokenCookie,
  setRefreshTokenCookie,
} from '~/utils/cookie-utils';
import { generateAccessToken, generateRefreshToken } from '~/utils/jwt-utils';
import { MOCK_USERS } from '~/utils/mock-data';
import {
  forbiddenResponse,
  useResponseError,
  useResponseSuccess,
} from '~/utils/response';

export default defineEventHandler(async (event) => {
  const { password, username } = await readBody(event);
  if (!password || !username) {
    setResponseStatus(event, 400);
    return useResponseError(
      'BadRequestException',
      'Username and password are required',
    );
  }

  const findUser = MOCK_USERS.find(
    (item) => item.username === username && item.password === password,
  );

  if (!findUser) {
    clearRefreshTokenCookie(event);
    return forbiddenResponse(event, 'Username or password is incorrect.');
  }

  const accessToken = generateAccessToken(findUser);
  const refreshToken = generateRefreshToken(findUser);

  setRefreshTokenCookie(event, refreshToken);

  return useResponseSuccess({
    ...findUser,
    accessToken,
  });
});


================================================
FILE: apps/backend-mock/api/auth/logout.post.ts
================================================
import { defineEventHandler } from 'h3';
import {
  clearRefreshTokenCookie,
  getRefreshTokenFromCookie,
} from '~/utils/cookie-utils';
import { useResponseSuccess } from '~/utils/response';

export default defineEventHandler(async (event) => {
  const refreshToken = getRefreshTokenFromCookie(event);
  if (!refreshToken) {
    return useResponseSuccess('');
  }

  clearRefreshTokenCookie(event);

  return useResponseSuccess('');
});


================================================
FILE: apps/backend-mock/api/auth/refresh.post.ts
================================================
import { defineEventHandler } from 'h3';
import {
  clearRefreshTokenCookie,
  getRefreshTokenFromCookie,
  setRefreshTokenCookie,
} from '~/utils/cookie-utils';
import { generateAccessToken, verifyRefreshToken } from '~/utils/jwt-utils';
import { MOCK_USERS } from '~/utils/mock-data';
import { forbiddenResponse } from '~/utils/response';

export default defineEventHandler(async (event) => {
  const refreshToken = getRefreshTokenFromCookie(event);
  if (!refreshToken) {
    return forbiddenResponse(event);
  }

  clearRefreshTokenCookie(event);

  const userinfo = verifyRefreshToken(refreshToken);
  if (!userinfo) {
    return forbiddenResponse(event);
  }

  const findUser = MOCK_USERS.find(
    (item) => item.username === userinfo.username,
  );
  if (!findUser) {
    return forbiddenResponse(event);
  }
  const accessToken = generateAccessToken(findUser);

  setRefreshTokenCookie(event, refreshToken);

  return accessToken;
});


================================================
FILE: apps/backend-mock/api/demo/bigint.ts
================================================
import { eventHandler, setHeader } from 'h3';
import { verifyAccessToken } from '~/utils/jwt-utils';
import { unAuthorizedResponse } from '~/utils/response';

export default eventHandler(async (event) => {
  const userinfo = verifyAccessToken(event);
  if (!userinfo) {
    return unAuthorizedResponse(event);
  }
  const data = `
  {
    "code": 0,
    "message": "success",
    "data": [
              {
                "id": 123456789012345678901234567890123456789012345678901234567890,
                "name": "John Doe",
                "age": 30,
                "email": "john-doe@demo.com"
                },
                {
                "id": 987654321098765432109876543210987654321098765432109876543210,
                "name": "Jane Smith",
                "age": 25,
                "email": "jane@demo.com"
                }
            ]
  }
  `;
  setHeader(event, 'Content-Type', 'application/json');
  return data;
});


================================================
FILE: apps/backend-mock/api/menu/all.ts
================================================
import { eventHandler } from 'h3';
import { verifyAccessToken } from '~/utils/jwt-utils';
import { MOCK_MENUS } from '~/utils/mock-data';
import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';

export default eventHandler(async (event) => {
  const userinfo = verifyAccessToken(event);
  if (!userinfo) {
    return unAuthorizedResponse(event);
  }

  const menus =
    MOCK_MENUS.find((item) => item.username === userinfo.username)?.menus ?? [];
  return useResponseSuccess(menus);
});


================================================
FILE: apps/backend-mock/api/status.ts
================================================
import { eventHandler, getQuery, setResponseStatus } from 'h3';
import { useResponseError } from '~/utils/response';

export default eventHandler((event) => {
  const { status } = getQuery(event);
  setResponseStatus(event, Number(status));
  return useResponseError(`${status}`);
});


================================================
FILE: apps/backend-mock/api/system/dept/.post.ts
================================================
import { eventHandler } from 'h3';
import { verifyAccessToken } from '~/utils/jwt-utils';
import {
  sleep,
  unAuthorizedResponse,
  useResponseSuccess,
} from '~/utils/response';

export default eventHandler(async (event) => {
  const userinfo = verifyAccessToken(event);
  if (!userinfo) {
    return unAuthorizedResponse(event);
  }
  await sleep(600);
  return useResponseSuccess(null);
});


================================================
FILE: apps/backend-mock/api/system/dept/[id].delete.ts
================================================
import { eventHandler } from 'h3';
import { verifyAccessToken } from '~/utils/jwt-utils';
import {
  sleep,
  unAuthorizedResponse,
  useResponseSuccess,
} from '~/utils/response';

export default eventHandler(async (event) => {
  const userinfo = verifyAccessToken(event);
  if (!userinfo) {
    return unAuthorizedResponse(event);
  }
  await sleep(1000);
  return useResponseSuccess(null);
});


================================================
FILE: apps/backend-mock/api/system/dept/[id].put.ts
================================================
import { eventHandler } from 'h3';
import { verifyAccessToken } from '~/utils/jwt-utils';
import {
  sleep,
  unAuthorizedResponse,
  useResponseSuccess,
} from '~/utils/response';

export default eventHandler(async (event) => {
  const userinfo = verifyAccessToken(event);
  if (!userinfo) {
    return unAuthorizedResponse(event);
  }
  await sleep(2000);
  return useResponseSuccess(null);
});


================================================
FILE: apps/backend-mock/api/system/dept/list.ts
================================================
import { faker } from '@faker-js/faker';
import { eventHandler } from 'h3';
import { verifyAccessToken } from '~/utils/jwt-utils';
import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';

const formatterCN = new Intl.DateTimeFormat('zh-CN', {
  timeZone: 'Asia/Shanghai',
  year: 'numeric',
  month: '2-digit',
  day: '2-digit',
  hour: '2-digit',
  minute: '2-digit',
  second: '2-digit',
});

function generateMockDataList(count: number) {
  const dataList = [];

  for (let i = 0; i < count; i++) {
    const dataItem: Record<string, any> = {
      id: faker.string.uuid(),
      pid: 0,
      name: faker.commerce.department(),
      status: faker.helpers.arrayElement([0, 1]),
      createTime: formatterCN.format(
        faker.date.between({ from: '2021-01-01', to: '2022-12-31' }),
      ),
      remark: faker.lorem.sentence(),
    };
    if (faker.datatype.boolean()) {
      dataItem.children = Array.from(
        { length: faker.number.int({ min: 1, max: 5 }) },
        () => ({
          id: faker.string.uuid(),
          pid: dataItem.id,
          name: faker.commerce.department(),
          status: faker.helpers.arrayElement([0, 1]),
          createTime: formatterCN.format(
            faker.date.between({ from: '2023-01-01', to: '2023-12-31' }),
          ),
          remark: faker.lorem.sentence(),
        }),
      );
    }
    dataList.push(dataItem);
  }

  return dataList;
}

const mockData = generateMockDataList(10);

export default eventHandler(async (event) => {
  const userinfo = verifyAccessToken(event);
  if (!userinfo) {
    return unAuthorizedResponse(event);
  }

  const listData = structuredClone(mockData);

  return useResponseSuccess(listData);
});


================================================
FILE: apps/backend-mock/api/system/menu/list.ts
================================================
import { eventHandler } from 'h3';
import { verifyAccessToken } from '~/utils/jwt-utils';
import { MOCK_MENU_LIST } from '~/utils/mock-data';
import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';

export default eventHandler(async (event) => {
  const userinfo = verifyAccessToken(event);
  if (!userinfo) {
    return unAuthorizedResponse(event);
  }

  return useResponseSuccess(MOCK_MENU_LIST);
});


================================================
FILE: apps/backend-mock/api/system/menu/name-exists.ts
================================================
import { eventHandler, getQuery } from 'h3';
import { verifyAccessToken } from '~/utils/jwt-utils';
import { MOCK_MENU_LIST } from '~/utils/mock-data';
import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';

const namesMap: Record<string, any> = {};

function getNames(menus: any[]) {
  menus.forEach((menu) => {
    namesMap[menu.name] = String(menu.id);
    if (menu.children) {
      getNames(menu.children);
    }
  });
}
getNames(MOCK_MENU_LIST);

export default eventHandler(async (event) => {
  const userinfo = verifyAccessToken(event);
  if (!userinfo) {
    return unAuthorizedResponse(event);
  }
  const { id, name } = getQuery(event);

  return (name as string) in namesMap &&
    (!id || namesMap[name as string] !== String(id))
    ? useResponseSuccess(true)
    : useResponseSuccess(false);
});


================================================
FILE: apps/backend-mock/api/system/menu/path-exists.ts
================================================
import { eventHandler, getQuery } from 'h3';
import { verifyAccessToken } from '~/utils/jwt-utils';
import { MOCK_MENU_LIST } from '~/utils/mock-data';
import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';

const pathMap: Record<string, any> = { '/': 0 };

function getPaths(menus: any[]) {
  menus.forEach((menu) => {
    pathMap[menu.path] = String(menu.id);
    if (menu.children) {
      getPaths(menu.children);
    }
  });
}
getPaths(MOCK_MENU_LIST);

export default eventHandler(async (event) => {
  const userinfo = verifyAccessToken(event);
  if (!userinfo) {
    return unAuthorizedResponse(event);
  }
  const { id, path } = getQuery(event);

  return (path as string) in pathMap &&
    (!id || pathMap[path as string] !== String(id))
    ? useResponseSuccess(true)
    : useResponseSuccess(false);
});


================================================
FILE: apps/backend-mock/api/system/role/list.ts
================================================
import { faker } from '@faker-js/faker';
import { eventHandler, getQuery } from 'h3';
import { verifyAccessToken } from '~/utils/jwt-utils';
import { getMenuIds, MOCK_MENU_LIST } from '~/utils/mock-data';
import { unAuthorizedResponse, usePageResponseSuccess } from '~/utils/response';

const formatterCN = new Intl.DateTimeFormat('zh-CN', {
  timeZone: 'Asia/Shanghai',
  year: 'numeric',
  month: '2-digit',
  day: '2-digit',
  hour: '2-digit',
  minute: '2-digit',
  second: '2-digit',
});

const menuIds = getMenuIds(MOCK_MENU_LIST);

function generateMockDataList(count: number) {
  const dataList = [];

  for (let i = 0; i < count; i++) {
    const dataItem: Record<string, any> = {
      id: faker.string.uuid(),
      name: faker.commerce.product(),
      status: faker.helpers.arrayElement([0, 1]),
      createTime: formatterCN.format(
        faker.date.between({ from: '2022-01-01', to: '2025-01-01' }),
      ),
      permissions: faker.helpers.arrayElements(menuIds),
      remark: faker.lorem.sentence(),
    };

    dataList.push(dataItem);
  }

  return dataList;
}

const mockData = generateMockDataList(100);

export default eventHandler(async (event) => {
  const userinfo = verifyAccessToken(event);
  if (!userinfo) {
    return unAuthorizedResponse(event);
  }

  const {
    page = 1,
    pageSize = 20,
    name,
    id,
    remark,
    startTime,
    endTime,
    status,
  } = getQuery(event);
  let listData = structuredClone(mockData);
  if (name) {
    listData = listData.filter((item) =>
      item.name.toLowerCase().includes(String(name).toLowerCase()),
    );
  }
  if (id) {
    listData = listData.filter((item) =>
      item.id.toLowerCase().includes(String(id).toLowerCase()),
    );
  }
  if (remark) {
    listData = listData.filter((item) =>
      item.remark?.toLowerCase()?.includes(String(remark).toLowerCase()),
    );
  }
  if (startTime) {
    listData = listData.filter((item) => item.createTime >= startTime);
  }
  if (endTime) {
    listData = listData.filter((item) => item.createTime <= endTime);
  }
  if (['0', '1'].includes(status as string)) {
    listData = listData.filter((item) => item.status === Number(status));
  }
  return usePageResponseSuccess(page as string, pageSize as string, listData);
});


================================================
FILE: apps/backend-mock/api/table/list.ts
================================================
import { faker } from '@faker-js/faker';
import { eventHandler, getQuery } from 'h3';
import { verifyAccessToken } from '~/utils/jwt-utils';
import {
  sleep,
  unAuthorizedResponse,
  usePageResponseSuccess,
} from '~/utils/response';

function generateMockDataList(count: number) {
  const dataList = [];

  for (let i = 0; i < count; i++) {
    const dataItem = {
      id: faker.string.uuid(),
      imageUrl: faker.image.avatar(),
      imageUrl2: faker.image.avatar(),
      open: faker.datatype.boolean(),
      status: faker.helpers.arrayElement(['success', 'error', 'warning']),
      productName: faker.commerce.productName(),
      price: faker.commerce.price(),
      currency: faker.finance.currencyCode(),
      quantity: faker.number.int({ min: 1, max: 100 }),
      available: faker.datatype.boolean(),
      category: faker.commerce.department(),
      releaseDate: faker.date.past(),
      rating: faker.number.float({ min: 1, max: 5 }),
      description: faker.commerce.productDescription(),
      weight: faker.number.float({ min: 0.1, max: 10 }),
      color: faker.color.human(),
      inProduction: faker.datatype.boolean(),
      tags: Array.from({ length: 3 }, () => faker.commerce.productAdjective()),
    };

    dataList.push(dataItem);
  }

  return dataList;
}

const mockData = generateMockDataList(100);

export default eventHandler(async (event) => {
  const userinfo = verifyAccessToken(event);
  if (!userinfo) {
    return unAuthorizedResponse(event);
  }

  await sleep(600);

  const { page, pageSize, sortBy, sortOrder } = getQuery(event);
  // 规范化分页参数,处理 string[]
  const pageRaw = Array.isArray(page) ? page[0] : page;
  const pageSizeRaw = Array.isArray(pageSize) ? pageSize[0] : pageSize;
  const pageNumber = Math.max(
    1,
    Number.parseInt(String(pageRaw ?? '1'), 10) || 1,
  );
  const pageSizeNumber = Math.min(
    100,
    Math.max(1, Number.parseInt(String(pageSizeRaw ?? '10'), 10) || 10),
  );
  const listData = structuredClone(mockData);

  // 规范化 query 入参,兼容 string[]
  const sortKeyRaw = Array.isArray(sortBy) ? sortBy[0] : sortBy;
  const sortOrderRaw = Array.isArray(sortOrder) ? sortOrder[0] : sortOrder;
  // 检查 sortBy 是否是 listData 元素的合法属性键
  if (
    typeof sortKeyRaw === 'string' &&
    listData[0] &&
    Object.prototype.hasOwnProperty.call(listData[0], sortKeyRaw)
  ) {
    // 定义数组元素的类型
    type ItemType = (typeof listData)[0];
    const sortKey = sortKeyRaw as keyof ItemType; // 将 sortBy 断言为合法键
    const isDesc = sortOrderRaw === 'desc';
    listData.sort((a, b) => {
      const aValue = a[sortKey] as unknown;
      const bValue = b[sortKey] as unknown;

      let result: number;

      if (typeof aValue === 'number' && typeof bValue === 'number') {
        result = aValue - bValue;
      } else if (aValue instanceof Date && bValue instanceof Date) {
        result = aValue.getTime() - bValue.getTime();
      } else if (typeof aValue === 'boolean' && typeof bValue === 'boolean') {
        if (aValue === bValue) {
          result = 0;
        } else {
          result = aValue ? 1 : -1;
        }
      } else {
        const aStr = String(aValue);
        const bStr = String(bValue);
        const aNum = Number(aStr);
        const bNum = Number(bStr);
        result =
          Number.isFinite(aNum) && Number.isFinite(bNum)
            ? aNum - bNum
            : aStr.localeCompare(bStr, undefined, {
                numeric: true,
                sensitivity: 'base',
              });
      }

      return isDesc ? -result : result;
    });
  }

  return usePageResponseSuccess(
    String(pageNumber),
    String(pageSizeNumber),
    listData,
  );
});


================================================
FILE: apps/backend-mock/api/test.get.ts
================================================
import { defineEventHandler } from 'h3';

export default defineEventHandler(() => 'Test get handler');


================================================
FILE: apps/backend-mock/api/test.post.ts
================================================
import { defineEventHandler } from 'h3';

export default defineEventHandler(() => 'Test post handler');


================================================
FILE: apps/backend-mock/api/timezone/getTimezone.ts
================================================
import { eventHandler } from 'h3';
import { verifyAccessToken } from '~/utils/jwt-utils';
import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';
import { getTimezone } from '~/utils/timezone-utils';

export default eventHandler((event) => {
  const userinfo = verifyAccessToken(event);
  if (!userinfo) {
    return unAuthorizedResponse(event);
  }
  return useResponseSuccess(getTimezone());
});


================================================
FILE: apps/backend-mock/api/timezone/getTimezoneOptions.ts
================================================
import { eventHandler } from 'h3';
import { TIME_ZONE_OPTIONS } from '~/utils/mock-data';
import { useResponseSuccess } from '~/utils/response';

export default eventHandler(() => {
  const data = TIME_ZONE_OPTIONS.map((o) => ({
    label: `${o.timezone} (GMT${o.offset >= 0 ? `+${o.offset}` : o.offset})`,
    value: o.timezone,
  }));
  return useResponseSuccess(data);
});


================================================
FILE: apps/backend-mock/api/timezone/setTimezone.ts
================================================
import { eventHandler, readBody } from 'h3';
import { verifyAccessToken } from '~/utils/jwt-utils';
import { TIME_ZONE_OPTIONS } from '~/utils/mock-data';
import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';
import { setTimezone } from '~/utils/timezone-utils';

export default eventHandler(async (event) => {
  const userinfo = verifyAccessToken(event);
  if (!userinfo) {
    return unAuthorizedResponse(event);
  }
  const body = await readBody<{ timezone?: unknown }>(event);
  const timezone =
    typeof body?.timezone === 'string' ? body.timezone : undefined;
  const allowed = TIME_ZONE_OPTIONS.some((o) => o.timezone === timezone);
  if (!timezone || !allowed) {
    setResponseStatus(event, 400);
    return useResponseError('Bad Request', 'Invalid timezone');
  }
  setTimezone(timezone);
  return useResponseSuccess({});
});


================================================
FILE: apps/backend-mock/api/upload.ts
================================================
import { eventHandler } from 'h3';
import { verifyAccessToken } from '~/utils/jwt-utils';
import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';

export default eventHandler((event) => {
  const userinfo = verifyAccessToken(event);
  if (!userinfo) {
    return unAuthorizedResponse(event);
  }
  return useResponseSuccess({
    url: 'https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp',
  });
  // return useResponseError("test")
});


================================================
FILE: apps/backend-mock/api/user/info.ts
================================================
import { eventHandler } from 'h3';
import { verifyAccessToken } from '~/utils/jwt-utils';
import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';

export default eventHandler((event) => {
  const userinfo = verifyAccessToken(event);
  if (!userinfo) {
    return unAuthorizedResponse(event);
  }
  return useResponseSuccess(userinfo);
});


================================================
FILE: apps/backend-mock/error.ts
================================================
import type { NitroErrorHandler } from 'nitropack';

const errorHandler: NitroErrorHandler = function (error, event) {
  event.node.res.end(`[Error Handler] ${error.stack}`);
};

export default errorHandler;


================================================
FILE: apps/backend-mock/middleware/1.api.ts
================================================
import { defineEventHandler } from 'h3';
import { forbiddenResponse, sleep } from '~/utils/response';

export default defineEventHandler(async (event) => {
  event.node.res.setHeader(
    'Access-Control-Allow-Origin',
    event.headers.get('Origin') ?? '*',
  );
  if (event.method === 'OPTIONS') {
    event.node.res.statusCode = 204;
    event.node.res.statusMessage = 'No Content.';
    return 'OK';
  } else if (
    ['DELETE', 'PATCH', 'POST', 'PUT'].includes(event.method) &&
    event.path.startsWith('/api/system/')
  ) {
    await sleep(Math.floor(Math.random() * 2000));
    return forbiddenResponse(event, '演示环境,禁止修改');
  }
});


================================================
FILE: apps/backend-mock/nitro.config.ts
================================================
import errorHandler from './error';

process.env.COMPATIBILITY_DATE = new Date().toISOString();
export default defineNitroConfig({
  devErrorHandler: errorHandler,
  errorHandler: '~/error',
  routeRules: {
    '/api/**': {
      cors: true,
      headers: {
        'Access-Control-Allow-Credentials': 'true',
        'Access-Control-Allow-Headers':
          'Accept, Authorization, Content-Length, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-CSRF-TOKEN, X-Requested-With',
        'Access-Control-Allow-Methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Expose-Headers': '*',
      },
    },
  },
});


================================================
FILE: apps/backend-mock/package.json
================================================
{
  "name": "@vben/backend-mock",
  "version": "5.7.0",
  "description": "",
  "private": true,
  "license": "MIT",
  "author": "",
  "scripts": {
    "build": "nitro build",
    "start": "nitro dev"
  },
  "dependencies": {
    "@faker-js/faker": "catalog:",
    "jsonwebtoken": "catalog:",
    "nitropack": "catalog:"
  },
  "devDependencies": {
    "@types/jsonwebtoken": "catalog:",
    "h3": "catalog:"
  }
}


================================================
FILE: apps/backend-mock/routes/[...].ts
================================================
import { defineEventHandler } from 'h3';

export default defineEventHandler(() => {
  return `
<h1>Hello Vben Admin</h1>
<h2>Mock service is starting</h2>
<ul>
<li><a href="/api/user">/api/user/info</a></li>
<li><a href="/api/menu">/api/menu/all</a></li>
<li><a href="/api/auth/codes">/api/auth/codes</a></li>
<li><a href="/api/auth/login">/api/auth/login</a></li>
<li><a href="/api/upload">/api/upload</a></li>
</ul>
`;
});


================================================
FILE: apps/backend-mock/tsconfig.build.json
================================================
{
  "extends": "./tsconfig.json",
  "exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
}


================================================
FILE: apps/backend-mock/tsconfig.json
================================================
{
  "extends": "./.nitro/types/tsconfig.json"
}


================================================
FILE: apps/backend-mock/utils/cookie-utils.ts
================================================
import type { EventHandlerRequest, H3Event } from 'h3';

import { deleteCookie, getCookie, setCookie } from 'h3';

export function clearRefreshTokenCookie(event: H3Event<EventHandlerRequest>) {
  deleteCookie(event, 'jwt', {
    httpOnly: true,
    sameSite: 'none',
    secure: true,
  });
}

export function setRefreshTokenCookie(
  event: H3Event<EventHandlerRequest>,
  refreshToken: string,
) {
  setCookie(event, 'jwt', refreshToken, {
    httpOnly: true,
    maxAge: 24 * 60 * 60, // unit: seconds
    sameSite: 'none',
    secure: true,
  });
}

export function getRefreshTokenFromCookie(event: H3Event<EventHandlerRequest>) {
  const refreshToken = getCookie(event, 'jwt');
  return refreshToken;
}


================================================
FILE: apps/backend-mock/utils/jwt-utils.ts
================================================
import type { EventHandlerRequest, H3Event } from 'h3';

import type { UserInfo } from './mock-data';

import { getHeader } from 'h3';
import jwt from 'jsonwebtoken';

import { MOCK_USERS } from './mock-data';

// TODO: Replace with your own secret key
const ACCESS_TOKEN_SECRET = 'access_token_secret';
const REFRESH_TOKEN_SECRET = 'refresh_token_secret';

export interface UserPayload extends UserInfo {
  iat: number;
  exp: number;
}

export function generateAccessToken(user: UserInfo) {
  return jwt.sign(user, ACCESS_TOKEN_SECRET, { expiresIn: '7d' });
}

export function generateRefreshToken(user: UserInfo) {
  return jwt.sign(user, REFRESH_TOKEN_SECRET, {
    expiresIn: '30d',
  });
}

export function verifyAccessToken(
  event: H3Event<EventHandlerRequest>,
): null | Omit<UserInfo, 'password'> {
  const authHeader = getHeader(event, 'Authorization');
  if (!authHeader?.startsWith('Bearer')) {
    return null;
  }

  const tokenParts = authHeader.split(' ');
  if (tokenParts.length !== 2) {
    return null;
  }
  const token = tokenParts[1] as string;
  try {
    const decoded = jwt.verify(
      token,
      ACCESS_TOKEN_SECRET,
    ) as unknown as UserPayload;

    const username = decoded.username;
    const user = MOCK_USERS.find((item) => item.username === username);
    if (!user) {
      return null;
    }
    const { password: _pwd, ...userinfo } = user;
    return userinfo;
  } catch {
    return null;
  }
}

export function verifyRefreshToken(
  token: string,
): null | Omit<UserInfo, 'password'> {
  try {
    const decoded = jwt.verify(token, REFRESH_TOKEN_SECRET) as UserPayload;
    const username = decoded.username;
    const user = MOCK_USERS.find(
      (item) => item.username === username,
    ) as UserInfo;
    if (!user) {
      return null;
    }
    const { password: _pwd, ...userinfo } = user;
    return userinfo;
  } catch {
    return null;
  }
}


================================================
FILE: apps/backend-mock/utils/mock-data.ts
================================================
export interface UserInfo {
  id: number;
  password: string;
  realName: string;
  roles: string[];
  username: string;
  homePath?: string;
}

export interface TimezoneOption {
  offset: number;
  timezone: string;
}

export const MOCK_USERS: UserInfo[] = [
  {
    id: 0,
    password: '123456',
    realName: 'Vben',
    roles: ['super'],
    username: 'vben',
  },
  {
    id: 1,
    password: '123456',
    realName: 'Admin',
    roles: ['admin'],
    username: 'admin',
    homePath: '/workspace',
  },
  {
    id: 2,
    password: '123456',
    realName: 'Jack',
    roles: ['user'],
    username: 'jack',
    homePath: '/analytics',
  },
];

export const MOCK_CODES = [
  // super
  {
    codes: ['AC_100100', 'AC_100110', 'AC_100120', 'AC_100010'],
    username: 'vben',
  },
  {
    // admin
    codes: ['AC_100010', 'AC_100020', 'AC_100030'],
    username: 'admin',
  },
  {
    // user
    codes: ['AC_1000001', 'AC_1000002'],
    username: 'jack',
  },
];

const dashboardMenus = [
  {
    meta: {
      order: -1,
      title: 'page.dashboard.title',
    },
    name: 'Dashboard',
    path: '/dashboard',
    redirect: '/analytics',
    children: [
      {
        name: 'Analytics',
        path: '/analytics',
        component: '/dashboard/analytics/index',
        meta: {
          affixTab: true,
          title: 'page.dashboard.analytics',
        },
      },
      {
        name: 'Workspace',
        path: '/workspace',
        component: '/dashboard/workspace/index',
        meta: {
          title: 'page.dashboard.workspace',
        },
      },
    ],
  },
];

const createDemosMenus = (role: 'admin' | 'super' | 'user') => {
  const roleWithMenus = {
    admin: {
      component: '/demos/access/admin-visible',
      meta: {
        icon: 'mdi:button-cursor',
        title: 'demos.access.adminVisible',
      },
      name: 'AccessAdminVisibleDemo',
      path: '/demos/access/admin-visible',
    },
    super: {
      component: '/demos/access/super-visible',
      meta: {
        icon: 'mdi:button-cursor',
        title: 'demos.access.superVisible',
      },
      name: 'AccessSuperVisibleDemo',
      path: '/demos/access/super-visible',
    },
    user: {
      component: '/demos/access/user-visible',
      meta: {
        icon: 'mdi:button-cursor',
        title: 'demos.access.userVisible',
      },
      name: 'AccessUserVisibleDemo',
      path: '/demos/access/user-visible',
    },
  };

  return [
    {
      meta: {
        icon: 'ic:baseline-view-in-ar',
        keepAlive: true,
        order: 1000,
        title: 'demos.title',
      },
      name: 'Demos',
      path: '/demos',
      redirect: '/demos/access',
      children: [
        {
          name: 'AccessDemos',
          path: '/demosaccess',
          meta: {
            icon: 'mdi:cloud-key-outline',
            title: 'demos.access.backendPermissions',
          },
          redirect: '/demos/access/page-control',
          children: [
            {
              name: 'AccessPageControlDemo',
              path: '/demos/access/page-control',
              component: '/demos/access/index',
              meta: {
                icon: 'mdi:page-previous-outline',
                title: 'demos.access.pageAccess',
              },
            },
            {
              name: 'AccessButtonControlDemo',
              path: '/demos/access/button-control',
              component: '/demos/access/button-control',
              meta: {
                icon: 'mdi:button-cursor',
                title: 'demos.access.buttonControl',
              },
            },
            {
              name: 'AccessMenuVisible403Demo',
              path: '/demos/access/menu-visible-403',
              component: '/demos/access/menu-visible-403',
              meta: {
                authority: ['no-body'],
                icon: 'mdi:button-cursor',
                menuVisibleWithForbidden: true,
                title: 'demos.access.menuVisible403',
              },
            },
            roleWithMenus[role],
          ],
        },
      ],
    },
  ];
};

export const MOCK_MENUS = [
  {
    menus: [...dashboardMenus, ...createDemosMenus('super')],
    username: 'vben',
  },
  {
    menus: [...dashboardMenus, ...createDemosMenus('admin')],
    username: 'admin',
  },
  {
    menus: [...dashboardMenus, ...createDemosMenus('user')],
    username: 'jack',
  },
];

export const MOCK_MENU_LIST = [
  {
    id: 1,
    name: 'Workspace',
    status: 1,
    type: 'menu',
    icon: 'mdi:dashboard',
    path: '/workspace',
    component: '/dashboard/workspace/index',
    meta: {
      icon: 'carbon:workspace',
      title: 'page.dashboard.workspace',
      affixTab: true,
      order: 0,
    },
  },
  {
    id: 2,
    meta: {
      icon: 'carbon:settings',
      order: 9997,
      title: 'system.title',
      badge: 'new',
      badgeType: 'normal',
      badgeVariants: 'primary',
    },
    status: 1,
    type: 'catalog',
    name: 'System',
    path: '/system',
    children: [
      {
        id: 201,
        pid: 2,
        path: '/system/menu',
        name: 'SystemMenu',
        authCode: 'System:Menu:List',
        status: 1,
        type: 'menu',
        meta: {
          icon: 'carbon:menu',
          title: 'system.menu.title',
        },
        component: '/system/menu/list',
        children: [
          {
            id: 20_101,
            pid: 201,
            name: 'SystemMenuCreate',
            status: 1,
            type: 'button',
            authCode: 'System:Menu:Create',
            meta: { title: 'common.create' },
          },
          {
            id: 20_102,
            pid: 201,
            name: 'SystemMenuEdit',
            status: 1,
            type: 'button',
            authCode: 'System:Menu:Edit',
            meta: { title: 'common.edit' },
          },
          {
            id: 20_103,
            pid: 201,
            name: 'SystemMenuDelete',
            status: 1,
            type: 'button',
            authCode: 'System:Menu:Delete',
            meta: { title: 'common.delete' },
          },
        ],
      },
      {
        id: 202,
        pid: 2,
        path: '/system/dept',
        name: 'SystemDept',
        status: 1,
        type: 'menu',
        authCode: 'System:Dept:List',
        meta: {
          icon: 'carbon:container-services',
          title: 'system.dept.title',
        },
        component: '/system/dept/list',
        children: [
          {
            id: 20_401,
            pid: 202,
            name: 'SystemDeptCreate',
            status: 1,
            type: 'button',
            authCode: 'System:Dept:Create',
            meta: { title: 'common.create' },
          },
          {
            id: 20_402,
            pid: 202,
            name: 'SystemDeptEdit',
            status: 1,
            type: 'button',
            authCode: 'System:Dept:Edit',
            meta: { title: 'common.edit' },
          },
          {
            id: 20_403,
            pid: 202,
            name: 'SystemDeptDelete',
            status: 1,
            type: 'button',
            authCode: 'System:Dept:Delete',
            meta: { title: 'common.delete' },
          },
        ],
      },
    ],
  },
  {
    id: 9,
    meta: {
      badgeType: 'dot',
      order: 9998,
      title: 'demos.vben.title',
      icon: 'carbon:data-center',
    },
    name: 'Project',
    path: '/vben-admin',
    type: 'catalog',
    status: 1,
    children: [
      {
        id: 901,
        pid: 9,
        name: 'VbenDocument',
        path: '/vben-admin/document',
        component: 'IFrameView',
        type: 'embedded',
        status: 1,
        meta: {
          icon: 'carbon:book',
          iframeSrc: 'https://doc.vben.pro',
          title: 'demos.vben.document',
        },
      },
      {
        id: 902,
        pid: 9,
        name: 'VbenGithub',
        path: '/vben-admin/github',
        component: 'IFrameView',
        type: 'link',
        status: 1,
        meta: {
          icon: 'carbon:logo-github',
          link: 'https://github.com/vbenjs/vue-vben-admin',
          title: 'Github',
        },
      },
      {
        id: 903,
        pid: 9,
        name: 'VbenAntdv',
        path: '/vben-admin/antdv',
        component: 'IFrameView',
        type: 'link',
        status: 0,
        meta: {
          icon: 'carbon:hexagon-vertical-solid',
          badgeType: 'dot',
          link: 'https://ant.vben.pro',
          title: 'demos.vben.antdv',
        },
      },
    ],
  },
  {
    id: 10,
    component: '_core/about/index',
    type: 'menu',
    status: 1,
    meta: {
      icon: 'lucide:copyright',
      order: 9999,
      title: 'demos.vben.about',
    },
    name: 'About',
    path: '/about',
  },
];

export function getMenuIds(menus: any[]) {
  const ids: number[] = [];
  menus.forEach((item) => {
    ids.push(item.id);
    if (item.children && item.children.length > 0) {
      ids.push(...getMenuIds(item.children));
    }
  });
  return ids;
}

/**
 * 时区选项
 */
export const TIME_ZONE_OPTIONS: TimezoneOption[] = [
  {
    offset: -5,
    timezone: 'America/New_York',
  },
  {
    offset: 0,
    timezone: 'Europe/London',
  },
  {
    offset: 8,
    timezone: 'Asia/Shanghai',
  },
  {
    offset: 9,
    timezone: 'Asia/Tokyo',
  },
  {
    offset: 9,
    timezone: 'Asia/Seoul',
  },
];


================================================
FILE: apps/backend-mock/utils/response.ts
================================================
import type { EventHandlerRequest, H3Event } from 'h3';

import { setResponseStatus } from 'h3';

export function useResponseSuccess<T = any>(data: T) {
  return {
    code: 0,
    data,
    error: null,
    message: 'ok',
  };
}

export function usePageResponseSuccess<T = any>(
  page: number | string,
  pageSize: number | string,
  list: T[],
  { message = 'ok' } = {},
) {
  const pageData = pagination(
    Number.parseInt(`${page}`),
    Number.parseInt(`${pageSize}`),
    list,
  );

  return {
    ...useResponseSuccess({
      items: pageData,
      total: list.length,
    }),
    message,
  };
}

export function useResponseError(message: string, error: any = null) {
  return {
    code: -1,
    data: null,
    error,
    message,
  };
}

export function forbiddenResponse(
  event: H3Event<EventHandlerRequest>,
  message = 'Forbidden Exception',
) {
  setResponseStatus(event, 403);
  return useResponseError(message, message);
}

export function unAuthorizedResponse(event: H3Event<EventHandlerRequest>) {
  setResponseStatus(event, 401);
  return useResponseError('Unauthorized Exception', 'Unauthorized Exception');
}

export function sleep(ms: number) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

export function pagination<T = any>(
  pageNo: number,
  pageSize: number,
  array: T[],
): T[] {
  const offset = (pageNo - 1) * Number(pageSize);
  return offset + Number(pageSize) >= array.length
    ? array.slice(offset)
    : array.slice(offset, offset + Number(pageSize));
}


================================================
FILE: apps/backend-mock/utils/timezone-utils.ts
================================================
let mockTimeZone: null | string = null;

export const setTimezone = (timeZone: string) => {
  mockTimeZone = timeZone;
};

export const getTimezone = () => {
  return mockTimeZone;
};


================================================
FILE: apps/web-antd/index.html
================================================
<!doctype html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="renderer" content="webkit" />
    <meta name="description" content="A Modern Back-end Management System" />
    <meta name="keywords" content="Vben Admin Vue3 Vite" />
    <meta name="author" content="Vben" />
    <meta
      name="viewport"
      content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0"
    />
    <!-- 由 vite 注入 VITE_APP_TITLE 变量,在 .env 文件内配置 -->
    <title><%= VITE_APP_TITLE %></title>
    <link rel="icon" href="/favicon.ico" />
    <script>
      // 生产环境下注入百度统计
      if (window._VBEN_ADMIN_PRO_APP_CONF_) {
        var _hmt = _hmt || [];
        (function () {
          var hm = document.createElement('script');
          hm.src =
            'https://hm.baidu.com/hm.js?b38e689f40558f20a9a686d7f6f33edf';
          var s = document.getElementsByTagName('script')[0];
          s.parentNode.insertBefore(hm, s);
        })();
      }
    </script>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>


================================================
FILE: apps/web-antd/package.json
================================================
{
  "name": "@vben/web-antd",
  "version": "5.7.0",
  "homepage": "https://vben.pro",
  "bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/vbenjs/vue-vben-admin.git",
    "directory": "apps/web-antd"
  },
  "license": "MIT",
  "author": {
    "name": "vben",
    "email": "ann.vben@gmail.com",
    "url": "https://github.com/anncwb"
  },
  "type": "module",
  "scripts": {
    "build": "pnpm vite build --mode production",
    "build:analyze": "pnpm vite build --mode analyze",
    "dev": "pnpm vite --mode development",
    "preview": "vite preview",
    "typecheck": "vue-tsc --noEmit --skipLibCheck"
  },
  "imports": {
    "#/*": "./src/*"
  },
  "dependencies": {
    "@vben/access": "workspace:*",
    "@vben/common-ui": "workspace:*",
    "@vben/constants": "workspace:*",
    "@vben/hooks": "workspace:*",
    "@vben/icons": "workspace:*",
    "@vben/layouts": "workspace:*",
    "@vben/locales": "workspace:*",
    "@vben/plugins": "workspace:*",
    "@vben/preferences": "workspace:*",
    "@vben/request": "workspace:*",
    "@vben/stores": "workspace:*",
    "@vben/styles": "workspace:*",
    "@vben/types": "workspace:*",
    "@vben/utils": "workspace:*",
    "@vueuse/core": "catalog:",
    "ant-design-vue": "catalog:",
    "dayjs": "catalog:",
    "pinia": "catalog:",
    "vue": "catalog:",
    "vue-router": "catalog:"
  }
}


================================================
FILE: apps/web-antd/src/adapter/component/index.ts
================================================
/**
 * 通用组件共同的使用的基础组件,原先放在 adapter/form 内部,限制了使用范围,这里提取出来,方便其他地方使用
 * 可用于 vben-form、vben-modal、vben-drawer 等组件使用,
 */

/* eslint-disable vue/one-component-per-file */

import type {
  UploadChangeParam,
  UploadFile,
  UploadProps,
} from 'ant-design-vue';

import type { Component, Ref } from 'vue';

import type { BaseFormComponentType } from '@vben/common-ui';
import type { Sortable } from '@vben/hooks';
import type { Recordable } from '@vben/types';

import {
  computed,
  defineAsyncComponent,
  defineComponent,
  h,
  nextTick,
  onMounted,
  onUnmounted,
  ref,
  render,
  unref,
  watch,
} from 'vue';

import {
  ApiComponent,
  globalShareState,
  IconPicker,
  VCropper,
} from '@vben/common-ui';
import { useSortable } from '@vben/hooks';
import { IconifyIcon } from '@vben/icons';
import { $t } from '@vben/locales';
import { isEmpty } from '@vben/utils';

import { message, Modal, notification } from 'ant-design-vue';

const AutoComplete = defineAsyncComponent(
  () => import('ant-design-vue/es/auto-complete'),
);
const Button = defineAsyncComponent(() => import('ant-design-vue/es/button'));
const Checkbox = defineAsyncComponent(
  () => import('ant-design-vue/es/checkbox'),
);
const CheckboxGroup = defineAsyncComponent(() =>
  import('ant-design-vue/es/checkbox').then((res) => res.CheckboxGroup),
);
const DatePicker = defineAsyncComponent(
  () => import('ant-design-vue/es/date-picker'),
);
const Divider = defineAsyncComponent(() => import('ant-design-vue/es/divider'));
const Input = defineAsyncComponent(() => import('ant-design-vue/es/input'));
const InputNumber = defineAsyncComponent(
  () => import('ant-design-vue/es/input-number'),
);
const InputPassword = defineAsyncComponent(() =>
  import('ant-design-vue/es/input').then((res) => res.InputPassword),
);
const Mentions = defineAsyncComponent(
  () => import('ant-design-vue/es/mentions'),
);
const Radio = defineAsyncComponent(() => import('ant-design-vue/es/radio'));
const RadioGroup = defineAsyncComponent(() =>
  import('ant-design-vue/es/radio').then((res) => res.RadioGroup),
);
const RangePicker = defineAsyncComponent(() =>
  import('ant-design-vue/es/date-picker').then((res) => res.RangePicker),
);
const Rate = defineAsyncComponent(() => import('ant-design-vue/es/rate'));
const Select = defineAsyncComponent(() => import('ant-design-vue/es/select'));
const Space = defineAsyncComponent(() => import('ant-design-vue/es/space'));
const Switch = defineAsyncComponent(() => import('ant-design-vue/es/switch'));
const Textarea = defineAsyncComponent(() =>
  import('ant-design-vue/es/input').then((res) => res.Textarea),
);
const TimePicker = defineAsyncComponent(
  () => import('ant-design-vue/es/time-picker'),
);
const TreeSelect = defineAsyncComponent(
  () => import('ant-design-vue/es/tree-select'),
);
const Cascader = defineAsyncComponent(
  () => import('ant-design-vue/es/cascader'),
);
const Upload = defineAsyncComponent(() => import('ant-design-vue/es/upload'));
const Image = defineAsyncComponent(() => import('ant-design-vue/es/image'));
const PreviewGroup = defineAsyncComponent(() =>
  import('ant-design-vue/es/image').then((res) => res.ImagePreviewGroup),
);

const withDefaultPlaceholder = <T extends Component>(
  component: T,
  type: 'input' | 'select',
  componentProps: Recordable<any> = {},
) => {
  return defineComponent({
    name: component.name,
    inheritAttrs: false,
    setup: (props: any, { attrs, expose, slots }) => {
      const placeholder =
        props?.placeholder ||
        attrs?.placeholder ||
        $t(`ui.placeholder.${type}`);
      // 透传组件暴露的方法
      const innerRef = ref();
      expose(
        new Proxy(
          {},
          {
            get: (_target, key) => innerRef.value?.[key],
            has: (_target, key) => key in (innerRef.value || {}),
          },
        ),
      );
      return () =>
        h(
          component,
          { ...componentProps, placeholder, ...props, ...attrs, ref: innerRef },
          slots,
        );
    },
  });
};

const IMAGE_EXTENSIONS = new Set([
  'bmp',
  'gif',
  'jpeg',
  'jpg',
  'png',
  'svg',
  'webp',
]);

/**
 * 检查是否为图片文件
 */
function isImageFile(file: UploadFile): boolean {
  if (file.url) {
    try {
      const pathname = new URL(file.url, 'http://localhost').pathname;
      const ext = pathname.split('.').pop()?.toLowerCase();
      return ext ? IMAGE_EXTENSIONS.has(ext) : false;
    } catch {
      const ext = file.url?.split('.').pop()?.toLowerCase();
      return ext ? IMAGE_EXTENSIONS.has(ext) : false;
    }
  }
  if (!file.type) {
    const ext = file.name?.split('.').pop()?.toLowerCase();
    return ext ? IMAGE_EXTENSIONS.has(ext) : false;
  }
  return file.type.startsWith('image/');
}

/**
 * 创建默认的上传按钮插槽
 */
function createDefaultUploadSlots(listType: string, placeholder: string) {
  if (listType === 'picture-card') {
    return { default: () => placeholder };
  }
  return {
    default: () =>
      h(
        Button,
        {
          icon: h(IconifyIcon, {
            icon: 'ant-design:upload-outlined',
            class: 'mb-1 size-4',
          }),
        },
        () => placeholder,
      ),
  };
}

/**
 * 获取文件的 Base64
 */
function getBase64(file: File): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.addEventListener('load', () => resolve(reader.result as string));
    reader.addEventListener('error', reject);
  });
}

/**
 * 预览图片
 */
async function previewImage(
  file: UploadFile,
  visible: Ref<boolean>,
  fileList: Ref<UploadProps['fileList']>,
) {
  // 非图片文件直接打开链接
  if (!isImageFile(file)) {
    const url = file.url || file.preview;
    if (url) {
      window.open(url, '_blank');
    } else {
      message.error($t('ui.formRules.previewWarning'));
    }
    return;
  }

  const [ImageComponent, PreviewGroupComponent] = await Promise.all([
    Image,
    PreviewGroup,
  ]);

  // 过滤图片文件并生成预览
  const imageFiles = (unref(fileList) || []).filter((f) => isImageFile(f));

  for (const imgFile of imageFiles) {
    if (!imgFile.url && !imgFile.preview && imgFile.originFileObj) {
      imgFile.preview = await getBase64(imgFile.originFileObj);
    }
  }

  const container = document.createElement('div');
  document.body.append(container);
  let isUnmounted = false;

  const currentIndex = imageFiles.findIndex((f) => f.uid === file.uid);

  const PreviewWrapper = {
    setup() {
      return () => {
        if (isUnmounted) return null;
        return h(
          PreviewGroupComponent,
          {
            class: 'hidden',
            preview: {
              visible: visible.value,
              current: currentIndex,
              onVisibleChange: (value: boolean) => {
                visible.value = value;
                if (!value) {
                  setTimeout(() => {
                    if (!isUnmounted && container) {
                      isUnmounted = true;
                      render(null, container);
                      container.remove();
                    }
                  }, 300);
                }
              },
            },
          },
          () =>
            imageFiles.map((imgFile) =>
              h(ImageComponent, {
                key: imgFile.uid,
                src: imgFile.url || imgFile.preview,
              }),
            ),
        );
      };
    },
  };

  render(h(PreviewWrapper), container);
}

/**
 * 图片裁剪操作
 */
function cropImage(file: File, aspectRatio: string | undefined) {
  return new Promise<Blob | string | undefined>((resolve, reject) => {
    const container = document.createElement('div');
    document.body.append(container);

    let isUnmounted = false;
    let objectUrl: null | string = null;

    const open = ref<boolean>(true);
    const cropperRef = ref<InstanceType<typeof VCropper> | null>(null);

    const closeModal = () => {
      open.value = false;
      setTimeout(() => {
        if (!isUnmounted && container) {
          if (objectUrl) {
            URL.revokeObjectURL(objectUrl);
          }
          isUnmounted = true;
          render(null, container);
          container.remove();
        }
      }, 300);
    };

    const CropperWrapper = {
      setup() {
        return () => {
          if (isUnmounted) return null;
          if (!objectUrl) {
            objectUrl = URL.createObjectURL(file);
          }
          return h(
            Modal,
            {
              open: open.value,
              title: h('div', {}, [
                $t('ui.crop.title'),
                h(
                  'span',
                  {
                    class: `${aspectRatio ? '' : 'hidden'} ml-2 text-sm text-gray-400 font-normal`,
                  },
                  $t('ui.crop.titleTip', [aspectRatio]),
                ),
              ]),
              centered: true,
              width: 548,
              keyboard: false,
              maskClosable: false,
              closable: false,
              cancelText: $t('common.cancel'),
              okText: $t('ui.crop.confirm'),
              destroyOnClose: true,
              onOk: async () => {
                const cropper = cropperRef.value;
                if (!cropper) {
                  reject(new Error('Cropper not found'));
                  closeModal();
                  return;
                }
                try {
                  const dataUrl = await cropper.getCropImage();
                  if (dataUrl) {
                    resolve(dataUrl);
                  } else {
                    reject(new Error($t('ui.crop.errorTip')));
                  }
                } catch {
                  reject(new Error($t('ui.crop.errorTip')));
                } finally {
                  closeModal();
                }
              },
              onCancel() {
                resolve('');
                closeModal();
              },
            },
            () =>
              h(VCropper, {
                ref: (ref: any) => (cropperRef.value = ref),
                img: objectUrl as string,
                aspectRatio,
              }),
          );
        };
      },
    };

    render(h(CropperWrapper), container);
  });
}

/**
 * 带预览功能的上传组件
 */
const withPreviewUpload = () => {
  return defineComponent({
    name: Upload.name,
    emits: ['update:modelValue'],
    setup(
      props: any,
      { attrs, slots, emit }: { attrs: any; emit: any; slots: any },
    ) {
      const previewVisible = ref<boolean>(false);
      const placeholder = attrs?.placeholder || $t('ui.placeholder.upload');
      const listType = attrs?.listType || attrs?.['list-type'] || 'text';
      const fileList = ref<UploadProps['fileList']>(
        attrs?.fileList || attrs?.['file-list'] || [],
      );

      const maxSize = computed(() => attrs?.maxSize ?? attrs?.['max-size']);
      const aspectRatio = computed(
        () => attrs?.aspectRatio ?? attrs?.['aspect-ratio'],
      );

      const handleBeforeUpload = async (
        file: UploadFile,
        originFileList: Array<File>,
      ) => {
        // 文件大小限制
        if (maxSize.value && (file.size || 0) / 1024 / 1024 > maxSize.value) {
          message.error($t('ui.formRules.sizeLimit', [maxSize.value]));
          file.status = 'removed';
          return false;
        }

        // 图片裁剪处理
        if (
          attrs.crop &&
          !attrs.multiple &&
          originFileList[0] &&
          isImageFile(file)
        ) {
          file.status = 'removed';
          const blob = await cropImage(originFileList[0], aspectRatio.value);
          if (!blob) {
            throw new Error($t('ui.crop.errorTip'));
          }
          return blob;
        }

        return attrs.beforeUpload?.(file) ?? true;
      };

      const handleChange = (event: UploadChangeParam) => {
        try {
          attrs.handleChange?.(event);
          attrs.onHandleChange?.(event);
        } catch (error) {
          console.error(error);
        }
        fileList.value = event.fileList.filter(
          (file) => file.status !== 'removed',
        );
        emit(
          'update:modelValue',
          event.fileList?.length ? fileList.value : undefined,
        );
      };

      const handlePreview = async (file: UploadFile) => {
        previewVisible.value = true;
        await previewImage(file, previewVisible, fileList);
      };

      const renderUploadButton = () => {
        if (attrs.disabled) return null;
        return isEmpty(slots)
          ? createDefaultUploadSlots(listType, placeholder)
          : slots;
      };

      // 拖拽排序
      const draggable = computed(
        () => (attrs.draggable ?? false) && !attrs.disabled,
      );
      const uploadId = `upload-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
      const sortableInstance = ref<null | Sortable>(null);

      const styleId = `upload-drag-style-${uploadId}`;

      function injectDragStyle() {
        if (!document.querySelector(`[id="${styleId}"]`)) {
          const style = document.createElement('style');
          style.id = styleId;
          style.textContent = `
            [data-upload-id="${uploadId}"] .ant-upload-list-item { cursor: move; }
            [data-upload-id="${uploadId}"] .ant-upload-list-item:hover { box-shadow: 0 2px 8px rgba(0,0,0,0.15); }
          `;
          document.head.append(style);
        }
      }

      function removeDragStyle() {
        document.querySelector(`[id="${styleId}"]`)?.remove();
      }

      async function initSortable(retryCount = 0) {
        if (!draggable.value) return;

        injectDragStyle();
        await nextTick();
        await new Promise((resolve) => setTimeout(resolve, 100));

        const container = document.querySelector(
          `[data-upload-id="${uploadId}"] .ant-upload-list`,
        ) as HTMLElement;

        if (!container) {
          if (retryCount < 5) {
            setTimeout(() => initSortable(retryCount + 1), 200);
          }
          return;
        }

        const { initializeSortable } = useSortable(container, {
          animation: 300,
          delay: 400,
          delayOnTouchOnly: true,
          filter:
            '.ant-upload-select, .ant-upload-list-item-error, .ant-upload-list-item-uploading',
          onEnd: (evt) => {
            const { oldIndex, newIndex } = evt;
            if (
              oldIndex === undefined ||
              newIndex === undefined ||
              oldIndex === newIndex
            ) {
              return;
            }

            const list = [...(fileList.value || [])];
            const [movedItem] = list.splice(oldIndex, 1);
            if (movedItem) {
              list.splice(newIndex, 0, movedItem);
              fileList.value = list;
            }

            attrs.onDragSort?.(oldIndex, newIndex);
            emit('update:modelValue', fileList.value);
          },
        });

        sortableInstance.value = await initializeSortable();
      }

      // 监听表单值变化
      watch(
        () => attrs.modelValue,
        (res) => {
          fileList.value = res;
        },
      );

      onMounted(initSortable);
      onUnmounted(() => {
        sortableInstance.value?.destroy();
        removeDragStyle();
      });

      return () =>
        h(
          'div',
          { 'data-upload-id': uploadId, class: 'w-full' },
          h(
            Upload,
            {
              ...props,
              ...attrs,
              fileList: fileList.value,
              beforeUpload: handleBeforeUpload,
              onChange: handleChange,
              onPreview: handlePreview,
            },
            renderUploadButton() as any,
          ),
        );
    },
  });
};

// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
export type ComponentType =
  | 'ApiCascader'
  | 'ApiSelect'
  | 'ApiTreeSelect'
  | 'AutoComplete'
  | 'Cascader'
  | 'Checkbox'
  | 'CheckboxGroup'
  | 'DatePicker'
  | 'DefaultButton'
  | 'Divider'
  | 'IconPicker'
  | 'Input'
  | 'InputNumber'
  | 'InputPassword'
  | 'Mentions'
  | 'PrimaryButton'
  | 'Radio'
  | 'RadioGroup'
  | 'RangePicker'
  | 'Rate'
  | 'Select'
  | 'Space'
  | 'Switch'
  | 'Textarea'
  | 'TimePicker'
  | 'TreeSelect'
  | 'Upload'
  | BaseFormComponentType;

async function initComponentAdapter() {
  const components: Partial<Record<ComponentType, Component>> = {
    // 如果你的组件体积比较大,可以使用异步加载
    // Button: () =>
    // import('xxx').then((res) => res.Button),

    ApiCascader: withDefaultPlaceholder(ApiComponent, 'select', {
      component: Cascader,
      fieldNames: { label: 'label', value: 'value', children: 'children' },
      loadingSlot: 'suffixIcon',
      modelPropName: 'value',
      visibleEvent: 'onVisibleChange',
    }),
    ApiSelect: withDefaultPlaceholder(ApiComponent, 'select', {
      component: Select,
      loadingSlot: 'suffixIcon',
      modelPropName: 'value',
      visibleEvent: 'onVisibleChange',
    }),
    ApiTreeSelect: withDefaultPlaceholder(ApiComponent, 'select', {
      component: TreeSelect,
      fieldNames: { label: 'label', value: 'value', children: 'children' },
      loadingSlot: 'suffixIcon',
      modelPropName: 'value',
      optionsPropName: 'treeData',
      visibleEvent: 'onVisibleChange',
    }),
    AutoComplete,
    Cascader,
    Checkbox,
    CheckboxGroup,
    DatePicker,
    // 自定义默认按钮
    DefaultButton: (props, { attrs, slots }) => {
      return h(Button, { ...props, attrs, type: 'default' }, slots);
    },
    Divider,
    IconPicker: withDefaultPlaceholder(IconPicker, 'select', {
      iconSlot: 'addonAfter',
      inputComponent: Input,
      modelValueProp: 'value',
    }),
    Input: withDefaultPlaceholder(Input, 'input'),
    InputNumber: withDefaultPlaceholder(InputNumber, 'input'),
    InputPassword: withDefaultPlaceholder(InputPassword, 'input'),
    Mentions: withDefaultPlaceholder(Mentions, 'input'),
    // 自定义主要按钮
    PrimaryButton: (props, { attrs, slots }) => {
      return h(Button, { ...props, attrs, type: 'primary' }, slots);
    },
    Radio,
    RadioGroup,
    RangePicker,
    Rate,
    Select: withDefaultPlaceholder(Select, 'select'),
    Space,
    Switch,
    Textarea: withDefaultPlaceholder(Textarea, 'input'),
    TimePicker,
    TreeSelect: withDefaultPlaceholder(TreeSelect, 'select'),
    Upload: withPreviewUpload(),
  };

  // 将组件注册到全局共享状态中
  globalShareState.setComponents(components);

  // 定义全局共享状态中的消息提示
  globalShareState.defineMessage({
    // 复制成功消息提示
    copyPreferencesSuccess: (title, content) => {
      notification.success({
        description: content,
        message: title,
        placement: 'bottomRight',
      });
    },
  });
}

export { initComponentAdapter };


================================================
FILE: apps/web-antd/src/adapter/form.ts
================================================
import type {
  VbenFormSchema as FormSchema,
  VbenFormProps,
} from '@vben/common-ui';

import type { ComponentType } from './component';

import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
import { $t } from '@vben/locales';

async function initSetupVbenForm() {
  setupVbenForm<ComponentType>({
    config: {
      // ant design vue组件库默认都是 v-model:value
      baseModelPropName: 'value',

      // 一些组件是 v-model:checked 或者 v-model:fileList
      modelPropNameMap: {
        Checkbox: 'checked',
        Radio: 'checked',
        Switch: 'checked',
        Upload: 'fileList',
      },
    },
    defineRules: {
      // 输入项目必填国际化适配
      required: (value, _params, ctx) => {
        if (value === undefined || value === null || value.length === 0) {
          return $t('ui.formRules.required', [ctx.label]);
        }
        return true;
      },
      // 选择项目必填国际化适配
      selectRequired: (value, _params, ctx) => {
        if (value === undefined || value === null) {
          return $t('ui.formRules.selectRequired', [ctx.label]);
        }
        return true;
      },
    },
  });
}

const useVbenForm = useForm<ComponentType>;

export { initSetupVbenForm, useVbenForm, z };

export type VbenFormSchema = FormSchema<ComponentType>;
export type { VbenFormProps };


================================================
FILE: apps/web-antd/src/adapter/vxe-table.ts
================================================
import type { VxeTableGridOptions } from '@vben/plugins/vxe-table';

import { h } from 'vue';

import { setupVbenVxeTable, useVbenVxeGrid } from '@vben/plugins/vxe-table';

import { Button, Image } from 'ant-design-vue';

import { useVbenForm } from './form';

setupVbenVxeTable({
  configVxeTable: (vxeUI) => {
    vxeUI.setConfig({
      grid: {
        align: 'center',
        border: false,
        columnConfig: {
          resizable: true,
        },
        minHeight: 180,
        formConfig: {
          // 全局禁用vxe-table的表单配置,使用formOptions
          enabled: false,
        },
        proxyConfig: {
          autoLoad: true,
          response: {
            result: 'items',
            total: 'total',
            list: 'items',
          },
          showActiveMsg: true,
          showResponseMsg: false,
        },
        round: true,
        showOverflow: true,
        size: 'small',
      } as VxeTableGridOptions,
    });

    // 表格配置项可以用 cellRender: { name: 'CellImage' },
    vxeUI.renderer.add('CellImage', {
      renderTableDefault(renderOpts, params) {
        const { props } = renderOpts;
        const { column, row } = params;
        return h(Image, { src: row[column.field], ...props });
      },
    });

    // 表格配置项可以用 cellRender: { name: 'CellLink' },
    vxeUI.renderer.add('CellLink', {
      renderTableDefault(renderOpts) {
        const { props } = renderOpts;
        return h(
          Button,
          { size: 'small', type: 'link' },
          { default: () => props?.text },
        );
      },
    });

    // 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化
    // vxeUI.formats.add
  },
  useVbenForm,
});

export { useVbenVxeGrid };

export type * from '@vben/plugins/vxe-table';


================================================
FILE: apps/web-antd/src/api/core/auth.ts
================================================
import { baseRequestClient, requestClient } from '#/api/request';

export namespace AuthApi {
  /** 登录接口参数 */
  export interface LoginParams {
    password?: string;
    username?: string;
  }

  /** 登录接口返回值 */
  export interface LoginResult {
    accessToken: string;
  }

  export interface RefreshTokenResult {
    data: string;
    status: number;
  }
}

/**
 * 登录
 */
export async function loginApi(data: AuthApi.LoginParams) {
  return requestClient.post<AuthApi.LoginResult>('/auth/login', data);
}

/**
 * 刷新accessToken
 */
export async function refreshTokenApi() {
  return baseRequestClient.post<AuthApi.RefreshTokenResult>('/auth/refresh', {
    withCredentials: true,
  });
}

/**
 * 退出登录
 */
export async function logoutApi() {
  return baseRequestClient.post('/auth/logout', {
    withCredentials: true,
  });
}

/**
 * 获取用户权限码
 */
export async function getAccessCodesApi() {
  return requestClient.get<string[]>('/auth/codes');
}


================================================
FILE: apps/web-antd/src/api/core/index.ts
================================================
export * from './auth';
export * from './menu';
export * from './user';


================================================
FILE: apps/web-antd/src/api/core/menu.ts
================================================
import type { RouteRecordStringComponent } from '@vben/types';

import { requestClient } from '#/api/request';

/**
 * 获取用户所有菜单
 */
export async function getAllMenusApi() {
  return requestClient.get<RouteRecordStringComponent[]>('/menu/all');
}


================================================
FILE: apps/web-antd/src/api/core/user.ts
================================================
import type { UserInfo } from '@vben/types';

import { requestClient } from '#/api/request';

/**
 * 获取用户信息
 */
export async function getUserInfoApi() {
  return requestClient.get<UserInfo>('/user/info');
}


================================================
FILE: apps/web-antd/src/api/index.ts
================================================
export * from './core';


================================================
FILE: apps/web-antd/src/api/request.ts
================================================
/**
 * 该文件可自行根据业务逻辑进行调整
 */
import type { RequestClientOptions } from '@vben/request';

import { useAppConfig } from '@vben/hooks';
import { preferences } from '@vben/preferences';
import {
  authenticateResponseInterceptor,
  defaultResponseInterceptor,
  errorMessageResponseInterceptor,
  RequestClient,
} from '@vben/request';
import { useAccessStore } from '@vben/stores';

import { message } from 'ant-design-vue';

import { useAuthStore } from '#/store';

import { refreshTokenApi } from './core';

const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD);

function createRequestClient(baseURL: string, options?: RequestClientOptions) {
  const client = new RequestClient({
    ...options,
    baseURL,
  });

  /**
   * 重新认证逻辑
   */
  async function doReAuthenticate() {
    console.warn('Access token or refresh token is invalid or expired. ');
    const accessStore = useAccessStore();
    const authStore = useAuthStore();
    accessStore.setAccessToken(null);
    if (
      preferences.app.loginExpiredMode === 'modal' &&
      accessStore.isAccessChecked
    ) {
      accessStore.setLoginExpired(true);
    } else {
      await authStore.logout();
    }
  }

  /**
   * 刷新token逻辑
   */
  async function doRefreshToken() {
    const accessStore = useAccessStore();
    const resp = await refreshTokenApi();
    const newToken = resp.data;
    accessStore.setAccessToken(newToken);
    return newToken;
  }

  function formatToken(token: null | string) {
    return token ? `Bearer ${token}` : null;
  }

  // 请求头处理
  client.addRequestInterceptor({
    fulfilled: async (config) => {
      const accessStore = useAccessStore();

      config.headers.Authorization = formatToken(accessStore.accessToken);
      config.headers['Accept-Language'] = preferences.app.locale;
      return config;
    },
  });

  // 处理返回的响应数据格式
  client.addResponseInterceptor(
    defaultResponseInterceptor({
      codeField: 'code',
      dataField: 'data',
      successCode: 0,
    }),
  );

  // token过期的处理
  client.addResponseInterceptor(
    authenticateResponseInterceptor({
      client,
      doReAuthenticate,
      doRefreshToken,
      enableRefreshToken: preferences.app.enableRefreshToken,
      formatToken,
    }),
  );

  // 通用的错误处理,如果没有进入上面的错误处理逻辑,就会进入这里
  client.addResponseInterceptor(
    errorMessageResponseInterceptor((msg: string, error) => {
      // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg
      // 当前mock接口返回的错误字段是 error 或者 message
      const responseData = error?.response?.data ?? {};
      const errorMessage = responseData?.error ?? responseData?.message ?? '';
      // 如果没有错误信息,则会根据状态码进行提示
      message.error(errorMessage || msg);
    }),
  );

  return client;
}

export const requestClient = createRequestClient(apiURL, {
  responseReturn: 'data',
});

export const baseRequestClient = new RequestClient({ baseURL: apiURL });


================================================
FILE: apps/web-antd/src/app.vue
================================================
<script lang="ts" setup>
import { computed } from 'vue';

import { useAntdDesignTokens } from '@vben/hooks';
import { preferences, usePreferences } from '@vben/preferences';

import { App, ConfigProvider, theme } from 'ant-design-vue';

import { antdLocale } from '#/locales';

defineOptions({ name: 'App' });

const { isDark } = usePreferences();
const { tokens } = useAntdDesignTokens();

const tokenTheme = computed(() => {
  const algorithm = isDark.value
    ? [theme.darkAlgorithm]
    : [theme.defaultAlgorithm];

  // antd 紧凑模式算法
  if (preferences.app.compact) {
    algorithm.push(theme.compactAlgorithm);
  }

  return {
    algorithm,
    token: tokens,
  };
});
</script>

<template>
  <ConfigProvider :locale="antdLocale" :theme="tokenTheme">
    <App>
      <RouterView />
    </App>
  </ConfigProvider>
</template>


================================================
FILE: apps/web-antd/src/bootstrap.ts
================================================
import { createApp, watchEffect } from 'vue';

import { registerAccessDirective } from '@vben/access';
import { registerLoadingDirective } from '@vben/common-ui/es/loading';
import { preferences } from '@vben/preferences';
import { initStores } from '@vben/stores';
import '@vben/styles';
import '@vben/styles/antd';

import { useTitle } from '@vueuse/core';

import { $t, setupI18n } from '#/locales';

import { initComponentAdapter } from './adapter/component';
import { initSetupVbenForm } from './adapter/form';
import App from './app.vue';
import { router } from './router';

async function bootstrap(namespace: string) {
  // 初始化组件适配器
  await initComponentAdapter();

  // 初始化表单组件
  await initSetupVbenForm();

  // // 设置弹窗的默认配置
  // setDefaultModalProps({
  //   fullscreenButton: false,
  // });
  // // 设置抽屉的默认配置
  // setDefaultDrawerProps({
  //   zIndex: 1020,
  // });

  const app = createApp(App);

  // 注册v-loading指令
  registerLoadingDirective(app, {
    loading: 'loading', // 在这里可以自定义指令名称,也可以明确提供false表示不注册这个指令
    spinning: 'spinning',
  });

  // 国际化 i18n 配置
  await setupI18n(app);

  // 配置 pinia-tore
  await initStores(app, { namespace });

  // 安装权限指令
  registerAccessDirective(app);

  // 初始化 tippy
  const { initTippy } = await import('@vben/common-ui/es/tippy');
  initTippy(app);

  // 配置路由及路由守卫
  app.use(router);

  // 配置Motion插件
  const { MotionPlugin } = await import('@vben/plugins/motion');
  app.use(MotionPlugin);

  // 动态更新标题
  watchEffect(() => {
    if (preferences.app.dynamicTitle) {
      const routeTitle = router.currentRoute.value.meta?.title;
      const pageTitle =
        (routeTitle ? `${$t(routeTitle)} - ` : '') + preferences.app.name;
      useTitle(pageTitle);
    }
  });

  app.mount('#app');
}

export { bootstrap };


================================================
FILE: apps/web-antd/src/layouts/auth.vue
================================================
<script lang="ts" setup>
import { computed } from 'vue';

import { AuthPageLayout } from '@vben/layouts';
import { preferences } from '@vben/preferences';

import { $t } from '#/locales';

const appName = computed(() => preferences.app.name);
const logo = computed(() => preferences.logo.source);
const logoDark = computed(() => preferences.logo.sourceDark);
</script>

<template>
  <AuthPageLayout
    :app-name="appName"
    :logo="logo"
    :logo-dark="logoDark"
    :page-description="$t('authentication.pageDesc')"
    :page-title="$t('authentication.pageTitle')"
  >
    <!-- 自定义工具栏 -->
    <!-- <template #toolbar></template> -->
  </AuthPageLayout>
</template>


================================================
FILE: apps/web-antd/src/layouts/basic.vue
================================================
<script lang="ts" setup>
import type { NotificationItem } from '@vben/layouts';

import { computed, ref, watch } from 'vue';
import { useRouter } from 'vue-router';

import { AuthenticationLoginExpiredModal } from '@vben/common-ui';
import { VBEN_DOC_URL, VBEN_GITHUB_URL } from '@vben/constants';
import { useWatermark } from '@vben/hooks';
import { BookOpenText, CircleHelp, SvgGithubIcon } from '@vben/icons';
import {
  BasicLayout,
  LockScreen,
  Notification,
  UserDropdown,
} from '@vben/layouts';
import { preferences } from '@vben/preferences';
import { useAccessStore, useUserStore } from '@vben/stores';
import { openWindow } from '@vben/utils';

import { $t } from '#/locales';
import { useAuthStore } from '#/store';
import LoginForm from '#/views/_core/authentication/login.vue';

const notifications = ref<NotificationItem[]>([
  {
    id: 1,
    avatar: 'https://avatar.vercel.sh/vercel.svg?text=VB',
    date: '3小时前',
    isRead: true,
    message: '描述信息描述信息描述信息',
    title: '收到了 14 份新周报',
  },
  {
    id: 2,
    avatar: 'https://avatar.vercel.sh/1',
    date: '刚刚',
    isRead: false,
    message: '描述信息描述信息描述信息',
    title: '朱偏右 回复了你',
  },
  {
    id: 3,
    avatar: 'https://avatar.vercel.sh/1',
    date: '2024-01-01',
    isRead: false,
    message: '描述信息描述信息描述信息',
    title: '曲丽丽 评论了你',
  },
  {
    id: 4,
    avatar: 'https://avatar.vercel.sh/satori',
    date: '1天前',
    isRead: false,
    message: '描述信息描述信息描述信息',
    title: '代办提醒',
  },
  {
    id: 5,
    avatar: 'https://avatar.vercel.sh/satori',
    date: '1天前',
    isRead: false,
    message: '描述信息描述信息描述信息',
    title: '跳转Workspace示例',
    link: '/workspace',
  },
  {
    id: 6,
    avatar: 'https://avatar.vercel.sh/satori',
    date: '1天前',
    isRead: false,
    message: '描述信息描述信息描述信息',
    title: '跳转外部链接示例',
    link: 'https://doc.vben.pro',
  },
]);

const router = useRouter();
const userStore = useUserStore();
const authStore = useAuthStore();
const accessStore = useAccessStore();
const { destroyWatermark, updateWatermark } = useWatermark();
const showDot = computed(() =>
  notifications.value.some((item) => !item.isRead),
);

const menus = computed(() => [
  {
    handler: () => {
      router.push({ name: 'Profile' });
    },
    icon: 'lucide:user',
    text: $t('page.auth.profile'),
  },
  {
    handler: () => {
      openWindow(VBEN_DOC_URL, {
        target: '_blank',
      });
    },
    icon: BookOpenText,
    text: $t('ui.widgets.document'),
  },
  {
    handler: () => {
      openWindow(VBEN_GITHUB_URL, {
        target: '_blank',
      });
    },
    icon: SvgGithubIcon,
    text: 'GitHub',
  },
  {
    handler: () => {
      openWindow(`${VBEN_GITHUB_URL}/issues`, {
        target: '_blank',
      });
    },
    icon: CircleHelp,
    text: $t('ui.widgets.qa'),
  },
]);

const avatar = computed(() => {
  return userStore.userInfo?.avatar ?? preferences.app.defaultAvatar;
});

async function handleLogout() {
  await authStore.logout(false);
}

function handleNoticeClear() {
  notifications.value = [];
}

function markRead(id: number | string) {
  const item = notifications.value.find((item) => item.id === id);
  if (item) {
    item.isRead = true;
  }
}

function remove(id: number | string) {
  notifications.value = notifications.value.filter((item) => item.id !== id);
}

function handleMakeAll() {
  notifications.value.forEach((item) => (item.isRead = true));
}
watch(
  () => ({
    enable: preferences.app.watermark,
    content: preferences.app.watermarkContent,
  }),
  async ({ enable, content }) => {
    if (enable) {
      await updateWatermark({
        content:
          content ||
          `${userStore.userInfo?.username} - ${userStore.userInfo?.realName}`,
      });
    } else {
      destroyWatermark();
    }
  },
  {
    immediate: true,
  },
);
</script>

<template>
  <BasicLayout @clear-preferences-and-logout="handleLogout">
    <template #user-dropdown>
      <UserDropdown
        :avatar
        :menus
        :text="userStore.userInfo?.realName"
        description="ann.vben@gmail.com"
        tag-text="Pro"
        @logout="handleLogout"
      />
    </template>
    <template #notification>
      <Notification
        :dot="showDot"
        :notifications="notifications"
        @clear="handleNoticeClear"
        @read="(item) => item.id && markRead(item.id)"
        @remove="(item) => item.id && remove(item.id)"
        @make-all="handleMakeAll"
      />
    </template>
    <template #extra>
      <AuthenticationLoginExpiredModal
        v-model:open="accessStore.loginExpired"
        :avatar
      >
        <LoginForm />
      </AuthenticationLoginExpiredModal>
    </template>
    <template #lock-screen>
      <LockScreen :avatar @to-login="handleLogout" />
    </template>
  </BasicLayout>
</template>


================================================
FILE: apps/web-antd/src/layouts/index.ts
================================================
const BasicLayout = () => import('./basic.vue');
const AuthPageLayout = () => import('./auth.vue');

const IFrameView = () => import('@vben/layouts').then((m) => m.IFrameView);

export { AuthPageLayout, BasicLayout, IFrameView };


================================================
FILE: apps/web-antd/src/locales/README.md
================================================
# locale

每个app使用的国际化可能不同,这里用于扩展国际化的功能,例如扩展 dayjs、antd组件库的多语言切换,以及app本身的国际化文件。


================================================
FILE: apps/web-antd/src/locales/index.ts
================================================
import type { Locale } from 'ant-design-vue/es/locale';

import type { App } from 'vue';

import type { LocaleSetupOptions, SupportedLanguagesType } from '@vben/locales';

import { ref } from 'vue';

import {
  $t,
  setupI18n as coreSetup,
  loadLocalesMapFromDir,
} from '@vben/locales';
import { preferences } from '@vben/preferences';

import antdEnLocale from 'ant-design-vue/es/locale/en_US';
import antdDefaultLocale from 'ant-design-vue/es/locale/zh_CN';
import dayjs from 'dayjs';

const antdLocale = ref<Locale>(antdDefaultLocale);

const modules = import.meta.glob('./langs/**/*.json');

const localesMap = loadLocalesMapFromDir(
  /\.\/langs\/([^/]+)\/(.*)\.json$/,
  modules,
);
/**
 * 加载应用特有的语言包
 * 这里也可以改造为从服务端获取翻译数据
 * @param lang
 */
async function loadMessages(lang: SupportedLanguagesType) {
  const [appLocaleMessages] = await Promise.all([
    localesMap[lang]?.(),
    loadThirdPartyMessage(lang),
  ]);
  return appLocaleMessages?.default;
}

/**
 * 加载第三方组件库的语言包
 * @param lang
 */
async function loadThirdPartyMessage(lang: SupportedLanguagesType) {
  await Promise.all([loadAntdLocale(lang), loadDayjsLocale(lang)]);
}

/**
 * 加载dayjs的语言包
 * @param lang
 */
async function loadDayjsLocale(lang: SupportedLanguagesType) {
  let locale;
  switch (lang) {
    case 'en-US': {
      locale = await import('dayjs/locale/en');
      break;
    }
    case 'zh-CN': {
      locale = await import('dayjs/locale/zh-cn');
      break;
    }
    // 默认使用英语
    default: {
      locale = await import('dayjs/locale/en');
    }
  }
  if (locale) {
    dayjs.locale(locale);
  } else {
    console.error(`Failed to load dayjs locale for ${lang}`);
  }
}

/**
 * 加载antd的语言包
 * @param lang
 */
async function loadAntdLocale(lang: SupportedLanguagesType) {
  switch (lang) {
    case 'en-US': {
      antdLocale.value = antdEnLocale;
      break;
    }
    case 'zh-CN': {
      antdLocale.value = antdDefaultLocale;
      break;
    }
  }
}

async function setupI18n(app: App, options: LocaleSetupOptions = {}) {
  await coreSetup(app, {
    defaultLocale: preferences.app.locale,
    loadMessages,
    missingWarn: !import.meta.env.PROD,
    ...options,
  });
}

export { $t, antdLocale, setupI18n };


================================================
FILE: apps/web-antd/src/locales/langs/en-US/demos.json
================================================
{
  "title": "Demos",
  "antd": "Ant Design Vue",
  "vben": {
    "title": "Project",
    "about": "About",
    "document": "Document",
    "antdv": "Ant Design Vue Version",
    "antdv-next": "Antdv Next Version",
    "naive-ui": "Naive UI Version",
    "element-plus": "Element Plus Version",
    "tdesign": "TDesign Vue Version"
  }
}


================================================
FILE: apps/web-antd/src/locales/langs/en-US/page.json
================================================
{
  "auth": {
    "login": "Login",
    "register": "Register",
    "codeLogin": "Code Login",
    "qrcodeLogin": "Qr Code Login",
    "forgetPassword": "Forget Password",
    "profile": "Profile"
  },
  "dashboard": {
    "title": "Dashboard",
    "analytics": "Analytics",
    "workspace": "Workspace"
  }
}


================================================
FILE: apps/web-antd/src/locales/langs/zh-CN/demos.json
================================================
{
  "title": "演示",
  "antd": "Ant Design Vue",
  "vben": {
    "title": "项目",
    "about": "关于",
    "document": "文档",
    "antdv": "Ant Design Vue 版本",
    "antdv-next": "Antdv Next 版本",
    "naive-ui": "Naive UI 版本",
    "element-plus": "Element Plus 版本",
    "tdesign": "TDesign Vue 版本"
  }
}


================================================
FILE: apps/web-antd/src/locales/langs/zh-CN/page.json
================================================
{
  "auth": {
    "login": "登录",
    "register": "注册",
    "codeLogin": "验证码登录",
    "qrcodeLogin": "二维码登录",
    "forgetPassword": "忘记密码",
    "profile": "个人中心"
  },
  "dashboard": {
    "title": "概览",
    "analytics": "分析页",
    "workspace": "工作台"
  }
}


================================================
FILE: apps/web-antd/src/main.ts
================================================
import { initPreferences } from '@vben/preferences';
import { unmountGlobalLoading } from '@vben/utils';

import { overridesPreferences } from './preferences';

/**
 * 应用初始化完成之后再进行页面加载渲染
 */
async function initApplication() {
  // name用于指定项目唯一标识
  // 用于区分不同项目的偏好设置以及存储数据的key前缀以及其他一些需要隔离的数据
  const env = import.meta.env.PROD ? 'prod' : 'dev';
  const appVersion = import.meta.env.VITE_APP_VERSION;
  const namespace = `${import.meta.env.VITE_APP_NAMESPACE}-${appVersion}-${env}`;

  // app偏好设置初始化
  await initPreferences({
    namespace,
    overrides: overridesPreferences,
  });

  // 启动应用并挂载
  // vue应用主要逻辑及视图
  const { bootstrap } = await import('./bootstrap');
  await bootstrap(namespace);

  // 移除并销毁loading
  unmountGlobalLoading();
}

initApplication();


================================================
FILE: apps/web-antd/src/preferences.ts
================================================
import { defineOverridesPreferences } from '@vben/preferences';

/**
 * @description 项目配置文件
 * 只需要覆盖项目中的一部分配置,不需要的配置不用覆盖,会自动使用默认配置
 * !!! 更改配置后请清空缓存,否则可能不生效
 */
export const overridesPreferences = defineOverridesPreferences({
  // overrides
  app: {
    name: import.meta.env.VITE_APP_TITLE,
  },
});


================================================
FILE: apps/web-antd/src/router/access.ts
================================================
import type {
  ComponentRecordType,
  GenerateMenuAndRoutesOptions,
} from '@vben/types';

import { generateAccessible } from '@vben/access';
import { preferences } from '@vben/preferences';

import { message } from 'ant-design-vue';

import { getAllMenusApi } from '#/api';
import { BasicLayout, IFrameView } from '#/layouts';
import { $t } from '#/locales';

const forbiddenComponent = () => import('#/views/_core/fallback/forbidden.vue');

async function generateAccess(options: GenerateMenuAndRoutesOptions) {
  const pageMap: ComponentRecordType = import.meta.glob('../views/**/*.vue');

  const layoutMap: ComponentRecordType = {
    BasicLayout,
    IFrameView,
  };

  return await generateAccessible(preferences.app.accessMode, {
    ...options,
    fetchMenuListAsync: async () => {
      message.loading({
        content: `${$t('common.loadingMenu')}...`,
        duration: 1.5,
      });
      return await getAllMenusApi();
    },
    // 可以指定没有权限跳转403页面
    forbiddenComponent,
    // 如果 route.meta.menuVisibleWithForbidden = true
    layoutMap,
    pageMap,
  });
}

export { generateAccess };


================================================
FILE: apps/web-antd/src/router/guard.ts
================================================
import type { Router } from 'vue-router';

import { LOGIN_PATH } from '@vben/constants';
import { preferences } from '@vben/preferences';
import { useAccessStore, useUserStore } from '@vben/stores';
import { startProgress, stopProgress } from '@vben/utils';

import { accessRoutes, coreRouteNames } from '#/router/routes';
import { useAuthStore } from '#/store';

import { generateAccess } from './access';

/**
 * 通用守卫配置
 * @param router
 */
function setupCommonGuard(router: Router) {
  // 记录已经加载的页面
  const loadedPaths = new Set<string>();

  router.beforeEach((to) => {
    to.meta.loaded = loadedPaths.has(to.path);

    // 页面加载进度条
    if (!to.meta.loaded && preferences.transition.progress) {
      startProgress();
    }
    return true;
  });

  router.afterEach((to) => {
    // 记录页面是否加载,如果已经加载,后续的页面切换动画等效果不在重复执行

    loadedPaths.add(to.path);

    // 关闭页面加载进度条
    if (preferences.transition.progress) {
      stopProgress();
    }
  });
}

/**
 * 权限访问守卫配置
 * @param router
 */
function setupAccessGuard(router: Router) {
  router.beforeEach(async (to, from) => {
    const accessStore = useAccessStore();
    const userStore = useUserStore();
    const authStore = useAuthStore();

    // 基本路由,这些路由不需要进入权限拦截
    if (coreRouteNames.includes(to.name as string)) {
      if (to.path === LOGIN_PATH && accessStore.accessToken) {
        return decodeURIComponent(
          (to.query?.redirect as string) ||
            userStore.userInfo?.homePath ||
            preferences.app.defaultHomePath,
        );
      }
      return true;
    }

    // accessToken 检查
    if (!accessStore.accessToken) {
      // 明确声明忽略权限访问权限,则可以访问
      if (to.meta.ignoreAccess) {
        return true;
      }

      // 没有访问权限,跳转登录页面
      if (to.fullPath !== LOGIN_PATH) {
        return {
          path: LOGIN_PATH,
          // 如不需要,直接删除 query
          query:
            to.fullPath === preferences.app.defaultHomePath
              ? {}
              : { redirect: encodeURIComponent(to.fullPath) },
          // 携带当前跳转的页面,登录后重新跳转该页面
          replace: true,
        };
      }
      return to;
    }

    // 是否已经生成过动态路由
    if (accessStore.isAccessChecked) {
      return true;
    }

    // 生成路由表
    // 当前登录用户拥有的角色标识列表
    const userInfo = userStore.userInfo || (await authStore.fetchUserInfo());
    const userRoles = userInfo.roles ?? [];

    // 生成菜单和路由
    const { accessibleMenus, accessibleRoutes } = await generateAccess({
      roles: userRoles,
      router,
      // 则会在菜单中显示,但是访问会被重定向到403
      routes: accessRoutes,
    });

    // 保存菜单信息和路由信息
    accessStore.setAccessMenus(accessibleMenus);
    accessStore.setAccessRoutes(accessibleRoutes);
    accessStore.setIsAccessChecked(true);
    const redirectPath = (from.query.redirect ??
      (to.path === preferences.app.defaultHomePath
        ? userInfo.homePath || preferences.app.defaultHomePath
        : to.fullPath)) as string;

    return {
      ...router.resolve(decodeURIComponent(redirectPath)),
      replace: true,
    };
  });
}

/**
 * 项目守卫配置
 * @param router
 */
function createRouterGuard(router: Router) {
  /** 通用 */
  setupCommonGuard(router);
  /** 权限访问 */
  setupAccessGuard(router);
}

export { createRouterGuard };


================================================
FILE: apps/web-antd/src/router/index.ts
================================================
import {
  createRouter,
  createWebHashHistory,
  createWebHistory,
} from 'vue-router';

import { resetStaticRoutes } from '@vben/utils';

import { createRouterGuard } from './guard';
import { routes } from './routes';

/**
 *  @zh_CN 创建vue-router实例
 */
const router = createRouter({
  history:
    import.meta.env.VITE_ROUTER_HISTORY === 'hash'
      ? createWebHashHistory(import.meta.env.VITE_BASE)
      : createWebHistory(import.meta.env.VITE_BASE),
  // 应该添加到路由的初始路由列表。
  routes,
  scrollBehavior: (to, _from, savedPosition) => {
    if (savedPosition) {
      return savedPosition;
    }
    return to.hash ? { behavior: 'smooth', el: to.hash } : { left: 0, top: 0 };
  },
  // 是否应该禁止尾部斜杠。
  // strict: true,
});

const resetRoutes = () => resetStaticRoutes(router, routes);

// 创建路由守卫
createRouterGuard(router);

export { resetRoutes, router };


================================================
FILE: apps/web-antd/src/router/routes/core.ts
================================================
import type { RouteRecordRaw } from 'vue-router';

import { LOGIN_PATH } from '@vben/constants';
import { preferences } from '@vben/preferences';

import { $t } from '#/locales';

const BasicLayout = () => import('#/layouts/basic.vue');
const AuthPageLayout = () => import('#/layouts/auth.vue');
/** 全局404页面 */
const fallbackNotFoundRoute: RouteRecordRaw = {
  component: () => import('#/views/_core/fallback/not-found.vue'),
  meta: {
    hideInBreadcrumb: true,
    hideInMenu: true,
    hideInTab: true,
    title: '404',
  },
  name: 'FallbackNotFound',
  path: '/:path(.*)*',
};

/** 基本路由,这些路由是必须存在的 */
const coreRoutes: RouteRecordRaw[] = [
  /**
   * 根路由
   * 使用基础布局,作为所有页面的父级容器,子级就不必配置BasicLayout。
   * 此路由必须存在,且不应修改
   */
  {
    component: BasicLayout,
    meta: {
      hideInBreadcrumb: true,
      title: 'Root',
    },
    name: 'Root',
    path: '/',
    redirect: preferences.app.defaultHomePath,
    children: [],
  },
  {
    component: AuthPageLayout,
    meta: {
      hideInTab: true,
      title: 'Authentication',
    },
    name: 'Authentication',
    path: '/auth',
    redirect: LOGIN_PATH,
    children: [
      {
        name: 'Login',
        path: 'login',
        component: () => import('#/views/_core/authentication/login.vue'),
        meta: {
          title: $t('page.auth.login'),
        },
      },
      {
        name: 'CodeLogin',
        path: 'code-login',
        component: () => import('#/views/_core/authentication/code-login.vue'),
        meta: {
          title: $t('page.auth.codeLogin'),
        },
      },
      {
        name: 'QrCodeLogin',
        path: 'qrcode-login',
        component: () =>
          import('#/views/_core/authentication/qrcode-login.vue'),
        meta: {
          title: $t('page.auth.qrcodeLogin'),
        },
      },
      {
        name: 'ForgetPassword',
        path: 'forget-password',
        component: () =>
          import('#/views/_core/authentication/forget-password.vue'),
        meta: {
          title: $t('page.auth.forgetPassword'),
        },
      },
      {
        name: 'Register',
        path: 'register',
        component: () => import('#/views/_core/authentication/register.vue'),
        meta: {
          title: $t('page.auth.register'),
        },
      },
    ],
  },
];

export { coreRoutes, fallbackNotFoundRoute };


================================================
FILE: apps/web-antd/src/router/routes/index.ts
================================================
import type { RouteRecordRaw } from 'vue-router';

import { mergeRouteModules, traverseTreeValues } from '@vben/utils';

import { coreRoutes, fallbackNotFoundRoute } from './core';

const dynamicRouteFiles = import.meta.glob('./modules/**/*.ts', {
  eager: true,
});

// 有需要可以自行打开注释,并创建文件夹
// const externalRouteFiles = import.meta.glob('./external/**/*.ts', { eager: true });
// const staticRouteFiles = import.meta.glob('./static/**/*.ts', { eager: true });

/** 动态路由 */
const dynamicRoutes: RouteRecordRaw[] = mergeRouteModules(dynamicRouteFiles);

/** 外部路由列表,访问这些页面可以不需要Layout,可能用于内嵌在别的系统(不会显示在菜单中) */
// const externalRoutes: RouteRecordRaw[] = mergeRouteModules(externalRouteFiles);
// const staticRoutes: RouteRecordRaw[] = mergeRouteModules(staticRouteFiles);
const staticRoutes: RouteRecordRaw[] = [];
const externalRoutes: RouteRecordRaw[] = [];

/** 路由列表,由基本路由、外部路由和404兜底路由组成
 *  无需走权限验证(会一直显示在菜单中) */
const routes: RouteRecordRaw[] = [
  ...coreRoutes,
  ...externalRoutes,
  fallbackNotFoundRoute,
];

/** 基本路由列表,这些路由不需要进入权限拦截 */
const coreRouteNames = traverseTreeValues(coreRoutes, (route) => route.name);

/** 有权限校验的路由列表,包含动态路由和静态路由 */
const accessRoutes = [...dynamicRoutes, ...staticRoutes];
export { accessRoutes, coreRouteNames, routes };


================================================
FILE: apps/web-antd/src/router/routes/modules/dashboard.ts
================================================
import type { RouteRecordRaw } from 'vue-router';

import { $t } from '#/locales';

const routes: RouteRecordRaw[] = [
  {
    meta: {
      icon: 'lucide:layout-dashboard',
      order: -1,
      title: $t('page.dashboard.title'),
    },
    name: 'Dashboard',
    path: '/dashboard',
    children: [
      {
        name: 'Analytics',
        path: '/analytics',
        component: () => import('#/views/dashboard/analytics/index.vue'),
        meta: {
          affixTab: true,
          icon: 'lucide:area-chart',
          title: $t('page.dashboard.analytics'),
        },
      },
      {
        name: 'Workspace',
        path: '/workspace',
        component: () => import('#/views/dashboard/workspace/index.vue'),
        meta: {
          icon: 'carbon:workspace',
          title: $t('page.dashboard.workspace'),
        },
      },
    ],
  },
];

export default routes;


================================================
FILE: apps/web-antd/src/router/routes/modules/demos.ts
================================================
import type { RouteRecordRaw } from 'vue-router';

import { $t } from '#/locales';

const routes: RouteRecordRaw[] = [
  {
    meta: {
      icon: 'ic:baseline-view-in-ar',
      keepAlive: true,
      order: 1000,
      title: $t('demos.title'),
    },
    name: 'Demos',
    path: '/demos',
    children: [
      {
        meta: {
          title: $t('demos.antd'),
        },
        name: 'AntDesignDemos',
        path: '/demos/ant-design',
        component: () => import('#/views/demos/antd/index.vue'),
      },
    ],
  },
];

export default routes;


================================================
FILE: apps/web-antd/src/router/routes/modules/vben.ts
================================================
import type { RouteRecordRaw } from 'vue-router';

import {
  VBEN_ANTDV_NEXT_PREVIEW_URL,
  VBEN_DOC_URL,
  VBEN_ELE_PREVIEW_URL,
  VBEN_GITHUB_URL,
  VBEN_LOGO_URL,
  VBEN_NAIVE_PREVIEW_URL,
  VBEN_TD_PREVIEW_URL,
} from '@vben/constants';
import { SvgAntdvNextLogoIcon, SvgTDesignIcon } from '@vben/icons';

import { IFrameView } from '#/layouts';
import { $t } from '#/locales';

const routes: RouteRecordRaw[] = [
  {
    meta: {
      badgeType: 'dot',
      icon: VBEN_LOGO_URL,
      order: 9998,
      title: $t('demos.vben.title'),
    },
    name: 'VbenProject',
    path: '/vben-admin',
    children: [
      {
        name: 'VbenDocument',
        path: '/vben-admin/document',
        component: IFrameView,
        meta: {
          icon: 'lucide:book-open-text',
          link: VBEN_DOC_URL,
          title: $t('demos.vben.document'),
        },
      },
      {
        name: 'VbenGithub',
        path: '/vben-admin/github',
        component: IFrameView,
        meta: {
          icon: 'mdi:github',
          link: VBEN_GITHUB_URL,
          title: 'Github',
        },
      },
      {
        name: 'VbenAntdVNext',
        path: '/vben-admin/antdv-next',
        component: IFrameView,
        meta: {
          badgeType: 'dot',
          icon: SvgAntdvNextLogoIcon,
          link: VBEN_ANTDV_NEXT_PREVIEW_URL,
          title: $t('demos.vben.antdv-next'),
        },
      },
      {
        name: 'VbenNaive',
        path: '/vben-admin/naive',
        component: IFrameView,
        meta: {
          badgeType: 'dot',
          icon: 'logos:naiveui',
          link: VBEN_NAIVE_PREVIEW_URL,
          title: $t('demos.vben.naive-ui'),
        },
      },
      {
        name: 'VbenTDesign',
        path: '/vben-admin/tdesign',
        component: IFrameView,
        meta: {
          badgeType: 'dot',
          icon: SvgTDesignIcon,
          link: VBEN_TD_PREVIEW_URL,
          title: $t('demos.vben.tdesign'),
        },
      },
      {
        name: 'VbenElementPlus',
        path: '/vben-admin/ele',
        component: IFrameView,
        meta: {
          badgeType: 'dot',
          icon: 'logos:element',
          link: VBEN_ELE_PREVIEW_URL,
          title: $t('demos.vben.element-plus'),
        },
      },
    ],
  },
  {
    name: 'VbenAbout',
    path: '/vben-admin/about',
    component: () => import('#/views/_core/about/index.vue'),
    meta: {
      icon: 'lucide:copyright',
      title: $t('demos.vben.about'),
      order: 9999,
    },
  },
  {
    name: 'Profile',
    path: '/profile',
    component: () => import('#/views/_core/profile/index.vue'),
    meta: {
      icon: 'lucide:user',
      hideInMenu: true,
      title: $t('page.auth.profile'),
    },
  },
];

export default routes;


================================================
FILE: apps/web-antd/src/store/auth.ts
================================================
import type { Recordable, UserInfo } from '@vben/types';

import { ref } from 'vue';
import { useRouter } from 'vue-router';

import { LOGIN_PATH } from '@vben/constants';
import { preferences } from '@vben/preferences';
import { resetAllStores, useAccessStore, useUserStore } from '@vben/stores';

import { notification } from 'ant-design-vue';
import { defineStore } from 'pinia';

import { getAccessCodesApi, getUserInfoApi, loginApi, logoutApi } from '#/api';
import { $t } from '#/locales';

export const useAuthStore = defineStore('auth', () => {
  const accessStore = useAccessStore();
  const userStore = useUserStore();
  const router = useRouter();

  const loginLoading = ref(false);

  /**
   * 异步处理登录操作
   * Asynchronously handle the login process
   * @param params 登录表单数据
   */
  async function authLogin(
    params: Recordable<any>,
    onSuccess?: () => Promise<void> | void,
  ) {
    // 异步处理用户登录操作并获取 accessToken
    let userInfo: null | UserInfo = null;
    try {
      loginLoading.value = true;
      const { accessToken } = await loginApi(params);

      // 如果成功获取到 accessToken
      if (accessToken) {
        accessStore.setAccessToken(accessToken);

        // 获取用户信息并存储到 accessStore 中
        const [fetchUserInfoResult, accessCodes] = await Promise.all([
          fetchUserInfo(),
          getAccessCodesApi(),
        ]);

        userInfo = fetchUserInfoResult;

        userStore.setUserInfo(userInfo);
        accessStore.setAccessCodes(accessCodes);

        if (accessStore.loginExpired) {
          accessStore.setLoginExpired(false);
        } else {
          onSuccess
            ? await onSuccess?.()
            : await router.push(
                userInfo.homePath || preferences.app.defaultHomePath,
              );
        }

        if (userInfo?.realName) {
          notification.success({
            description: `${$t('authentication.loginSuccessDesc')}:${userInfo?.realName}`,
            duration: 3,
            message: $t('authentication.loginSuccess'),
          });
        }
      }
    } finally {
      loginLoading.value = false;
    }

    return {
      userInfo,
    };
  }

  async function logout(redirect: boolean = true) {
    try {
      await logoutApi();
    } catch {
      // 不做任何处理
    }
    resetAllStores();
    accessStore.setLoginExpired(false);

    // 回登录页带上当前路由地址
    await router.replace({
      path: LOGIN_PATH,
      query: redirect
        ? {
            redirect: encodeURIComponent(router.currentRoute.value.fullPath),
          }
        : {},
    });
  }

  async function fetchUserInfo() {
    const userInfo = await getUserInfoApi();
    userStore.setUserInfo(userInfo);
    return userInfo;
  }

  function $reset() {
    loginLoading.value = false;
  }

  return {
    $reset,
    authLogin,
    fetchUserInfo,
    loginLoading,
    logout,
  };
});


================================================
FILE: apps/web-antd/src/store/index.ts
================================================
export * from './auth';


================================================
FILE: apps/web-antd/src/views/_core/README.md
================================================
# \_core

此目录包含应用程序正常运行所需的基本视图。这些视图是应用程序布局中使用的视图。


================================================
FILE: apps/web-antd/src/views/_core/about/index.vue
================================================
<script lang="ts" setup>
import { About } from '@vben/common-ui';

defineOptions({ name: 'About' });
</script>

<template>
  <About />
</template>


================================================
FILE: apps/web-antd/src/views/_core/authentication/code-login.vue
================================================
<script lang="ts" setup>
import type { VbenFormSchema } from '@vben/common-ui';
import type { Recordable } from '@vben/types';

import { computed, ref } from 'vue';

import { AuthenticationCodeLogin, z } from '@vben/common-ui';
import { $t } from '@vben/locales';

defineOptions({ name: 'CodeLogin' });

const loading = ref(false);
const CODE_LENGTH = 6;

const formSchema = computed((): VbenFormSchema[] => {
  return [
    {
      component: 'VbenInput',
      componentProps: {
        placeholder: $t('authentication.mobile'),
      },
      fieldName: 'phoneNumber',
      label: $t('authentication.mobile'),
      rules: z
        .string()
        .min(1, { message: $t('authentication.mobileTip') })
        .refine((v) => /^\d{11}$/.test(v), {
          message: $t('authentication.mobileErrortip'),
        }),
    },
    {
      component: 'VbenPinInput',
      componentProps: {
        codeLength: CODE_LENGTH,
        createText: (countdown: number) => {
          const text =
            countdown > 0
              ? $t('authentication.sendText', [countdown])
              : $t('authentication.sendCode');
          return text;
        },
        placeholder: $t('authentication.code'),
      },
      fieldName: 'code',
      label: $t('authentication.code'),
      rules: z.string().length(CODE_LENGTH, {
        message: $t('authentication.codeTip', [CODE_LENGTH]),
      }),
    },
  ];
});
/**
 * 异步处理登录操作
 * Asynchronously handle the login process
 * @param values 登录表单数据
 */
async function handleLogin(values: Recordable<any>) {
  void values;
}
</script>

<template>
  <AuthenticationCodeLogin
    :form-schema="formSchema"
    :loading="loading"
    @submit="handleLogin"
  />
</template>


================================================
FILE: apps/web-antd/src/views/_core/authentication/forget-password.vue
================================================
<script lang="ts" setup>
import type { VbenFormSchema } from '@vben/common-ui';
import type { Recordable } from '@vben/types';

import { computed, ref } from 'vue';

import { AuthenticationForgetPassword, z } from '@vben/common-ui';
import { $t } from '@vben/locales';

defineOptions({ name: 'ForgetPassword' });

const loading = ref(false);

const formSchema = computed((): VbenFormSchema[] => {
  return [
    {
      component: 'VbenInput',
      componentProps: {
        placeholder: 'example@example.com',
      },
      fieldName: 'email',
      label: $t('authentication.email'),
      rules: z
        .string()
        .min(1, { message: $t('authentication.emailTip') })
        .email($t('authentication.emailValidErrorTip')),
    },
  ];
});

function handleSubmit(value: Recordable<any>) {
  void value;
}
</script>

<template>
  <AuthenticationForgetPassword
    :form-schema="formSchema"
    :loading="loading"
    @submit="handleSubmit"
  />
</template>


================================================
FILE: apps/web-antd/src/views/_core/authentication/login.vue
================================================
<script lang="ts" setup>
import type { VbenFormSchema } from '@vben/common-ui';
import type { BasicOption } from '@vben/types';

import { computed, markRaw } from 'vue';

import { AuthenticationLogin, SliderCaptcha, z } from '@vben/common-ui';
import { $t } from '@vben/locales';

import { useAuthStore } from '#/store';

defineOptions({ name: 'Login' });

const authStore = useAuthStore();

const MOCK_USER_OPTIONS: BasicOption[] = [
  {
    label: 'Super',
    value: 'vben',
  },
  {
    label: 'Admin',
    value: 'admin',
  },
  {
    label: 'User',
    value: 'jack',
  },
];

const formSchema = computed((): VbenFormSchema[] => {
  return [
    {
      component: 'VbenSelect',
      componentProps: {
        options: MOCK_USER_OPTIONS,
        placeholder: $t('authentication.selectAccount'),
      },
      fieldName: 'selectAccount',
      label: $t('authentication.selectAccount'),
      rules: z
        .string()
        .min(1, { message: $t('authentication.selectAccount') })
        .optional()
        .default('vben'),
    },
    {
      component: 'VbenInput',
      componentProps: {
        placeholder: $t('authentication.usernameTip'),
      },
      dependencies: {
        trigger(values, form) {
          if (values.selectAccount) {
            const findUser = MOCK_USER_OPTIONS.find(
              (item) => item.value === values.selectAccount,
            );
            if (findUser) {
              form.setValues({
                password: '123456',
                username: findUser.value,
              });
            }
          }
        },
        triggerFields: ['selectAccount'],
      },
      fieldName: 'username',
      label: $t('authentication.username'),
      rules: z.string().min(1, { message: $t('authentication.usernameTip') }),
    },
    {
      component: 'VbenInputPassword',
      componentProps: {
        placeholder: $t('authentication.password'),
      },
      fieldName: 'password',
      label: $t('authentication.password'),
      rules: z.string().min(1, { message: $t('authentication.passwordTip') }),
    },
    {
      component: markRaw(SliderCaptcha),
      fieldName: 'captcha',
      rules: z.boolean().refine((value) => value, {
        message: $t('authentication.verifyRequiredTip'),
      }),
    },
  ];
});
</script>

<template>
  <AuthenticationLogin
    :form-schema="formSchema"
    :loading="authStore.loginLoading"
    @submit="authStore.authLogin"
  />
</template>


================================================
FILE: apps/web-antd/src/views/_core/authentication/qrcode-login.vue
================================================
<script lang="ts" setup>
import { AuthenticationQrCodeLogin } from '@vben/common-ui';
import { LOGIN_PATH } from '@vben/constants';

defineOptions({ name: 'QrCodeLogin' });
</script>

<template>
  <AuthenticationQrCodeLogin :login-path="LOGIN_PATH" />
</template>


================================================
FILE: apps/web-antd/src/views/_core/authentication/register.vue
================================================
<script lang="ts" setup>
import type { VbenFormSchema } from '@vben/common-ui';
import type { Recordable } from '@vben/types';

import { computed, h, ref } from 'vue';

import { AuthenticationRegister, z } from '@vben/common-ui';
import { $t } from '@vben/locales';

defineOptions({ name: 'Register' });

const loading = ref(false);

const formSchema = computed((): VbenFormSchema[] => {
  return [
    {
      component: 'VbenInput',
      componentProps: {
        placeholder: $t('authentication.usernameTip'),
      },
      fieldName: 'username',
      label: $t('authentication.username'),
      rules: z.string().min(1, { message: $t('authentication.usernameTip') }),
    },
    {
      component: 'VbenInputPassword',
      componentProps: {
        passwordStrength: true,
        placeholder: $t('authentication.password'),
      },
      fieldName: 'password',
      label: $t('authentication.password'),
      renderComponentContent() {
        return {
          strengthText: () => $t('authentication.passwordStrength'),
        };
      },
      rules: z.string().min(1, { message: $t('authentication.passwordTip') }),
    },
    {
      component: 'VbenInputPassword',
      componentProps: {
        placeholder: $t('authentication.confirmPassword'),
      },
      dependencies: {
        rules(values) {
          const { password } = values;
          return z
            .string({ required_error: $t('authentication.passwordTip') })
            .min(1, { message: $t('authentication.passwordTip') })
            .refine((value) => value === password, {
              message: $t('authentication.confirmPasswordTip'),
            });
        },
        triggerFields: ['password'],
      },
      fieldName: 'confirmPassword',
      label: $t('authentication.confirmPassword'),
    },
    {
      component: 'VbenCheckbox',
      fieldName: 'agreePolicy',
      renderComponentContent: () => ({
        default: () =>
          h('span', [
            $t('authentication.agree'),
            h(
              'a',
              {
                class: 'vben-link ml-1 ',
                href: '',
              },
              `${$t('authentication.privacyPolicy')} & ${$t('authentication.terms')}`,
            ),
          ]),
      }),
      rules: z.boolean().refine((value) => !!value, {
        message: $t('authentication.agreeTip'),
      }),
    },
  ];
});

function handleSubmit(value: Recordable<any>) {
  void value;
}
</script>

<template>
  <AuthenticationRegister
    :form-schema="formSchema"
    :loading="loading"
    @submit="handleSubmit"
  />
</template>


================================================
FILE: apps/web-antd/src/views/_core/fallback/coming-soon.vue
================================================
<script lang="ts" setup>
import { Fallback } from '@vben/common-ui';
</script>

<template>
  <Fallback status="coming-soon" />
</template>


================================================
FILE: apps/web-antd/src/views/_core/fallback/forbidden.vue
================================================
<script lang="ts" setup>
import { Fallback } from '@vben/common-ui';

defineOptions({ name: 'Fallback403Demo' });
</script>

<template>
  <Fallback status="403" />
</template>


================================================
FILE: apps/web-antd/src/views/_core/fallback/internal-error.vue
================================================
<script lang="ts" setup>
import { Fallback } from '@vben/common-ui';

defineOptions({ name: 'Fallback500Demo' });
</script>

<template>
  <Fallback status="500" />
</template>


================================================
FILE: apps/web-antd/src/views/_core/fallback/not-found.vue
================================================
<script lang="ts" setup>
import { Fallback } from '@vben/common-ui';

defineOptions({ name: 'Fallback404Demo' });
</script>

<template>
  <Fallback status="404" />
</template>


================================================
FILE: apps/web-antd/src/views/_core/fallback/offline.vue
================================================
<script lang="ts" setup>
import { Fallback } from '@vben/common-ui';

defineOptions({ name: 'FallbackOfflineDemo' });
</script>

<template>
  <Fallback status="offline" />
</template>


================================================
FILE: apps/web-antd/src/views/_core/profile/base-setting.vue
================================================
<script setup lang="ts">
import type { BasicOption } from '@vben/types';

import type { VbenFormSchema } from '#/adapter/form';

import { computed, onMounted, ref } from 'vue';

import { ProfileBaseSetting } from '@vben/common-ui';

import { getUserInfoApi } from '#/api';

const profileBaseSettingRef = ref();

const MOCK_ROLES_OPTIONS: BasicOption[] = [
  {
    label: '管理员',
    value: 'super',
  },
  {
    label: '用户',
    value: 'user',
  },
  {
    label: '测试',
    value: 'test',
  },
];

const formSchema = computed((): VbenFormSchema[] => {
  return [
    {
      fieldName: 'realName',
      component: 'Input',
      label: '姓名',
    },
    {
      fieldName: 'username',
      component: 'Input',
      label: '用户名',
    },
    {
      fieldName: 'roles',
      component: 'Select',
      componentProps: {
        mode: 'tags',
        options: MOCK_ROLES_OPTIONS,
      },
      label: '角色',
    },
    {
      fieldName: 'introduction',
      component: 'Textarea',
      label: '个人简介',
    },
  ];
});

onMounted(async () => {
  const data = await getUserInfoApi();
  profileBaseSettingRef.value.getFormApi().setValues(data);
});
</script>
<template>
  <ProfileBaseSetting ref="profileBaseSettingRef" :form-schema="formSchema" />
</template>


================================================
FILE: apps/web-antd/src/views/_core/profile/index.vue
================================================
<script setup lang="ts">
import { ref } from 'vue';

import { Profile } from '@vben/common-ui';
import { useUserStore } from '@vben/stores';

import ProfileBase from './base-setting.vue';
import ProfileNotificationSetting from './notification-setting.vue';
import ProfilePasswordSetting from './password-setting.vue';
import ProfileSecuritySetting from './security-setting.vue';

const userStore = useUserStore();

const tabsValue = ref<string>('basic');

const tabs = ref([
  {
    label: '基本设置',
    value: 'basic',
  },
  {
    label: '安全设置',
    value: 'security',
  },
  {
    label: '修改密码',
    value: 'password',
  },
  {
    label: '新消息提醒',
    value: 'notice',
  },
]);
</script>
<template>
  <Profile
    v-model:model-value="tabsValue"
    title="个人中心"
    :user-info="userStore.userInfo"
    :tabs="tabs"
  >
    <template #content>
      <ProfileBase v-if="tabsValue === 'basic'" />
      <ProfileSecuritySetting v-if="tabsValue === 'security'" />
      <ProfilePasswordSetting v-if="tabsValue === 'password'" />
      <ProfileNotificationSetting v-if="tabsValue === 'notice'" />
    </template>
  </Profile>
</template>


================================================
FILE: apps/web-antd/src/views/_core/profile/notification-setting.vue
================================================
<script setup lang="ts">
import { computed } from 'vue';

import { ProfileNotificationSetting } from '@vben/common-ui';

const formSchema = computed(() => {
  return [
    {
      value: true,
      fieldName: 'accountPassword',
      label: '账户密码',
      description: '其他用户的消息将以站内信的形式通知',
    },
    {
      value: true,
      fieldName: 'systemMessage',
      label: '系统消息',
      description: '系统消息将以站内信的形式通知',
    },
    {
      value: true,
      fieldName: 'todoTask',
      label: '待办任务',
      description: '待办任务将以站内信的形式通知',
    },
  ];
});
</script>
<template>
  <ProfileNotificationSetting :form-schema="formSchema" />
</template>


================================================
FILE: apps/web-antd/src/views/_core/profile/password-setting.vue
================================================
<script setup lang="ts">
import type { VbenFormSchema } from '#/adapter/form';

import { computed } from 'vue';

import { ProfilePasswordSetting, z } from '@vben/common-ui';

import { message } from 'ant-design-vue';

const formSchema = computed((): VbenFormSchema[] => {
  return [
    {
      fieldName: 'oldPassword',
      label: '旧密码',
      component: 'VbenInputPassword',
      componentProps: {
        placeholder: '请输入旧密码',
      },
    },
    {
      fieldName: 'newPassword',
      label: '新密码',
      component: 'VbenInputPassword',
      componentProps: {
        passwordStrength: true,
        placeholder: '请输入新密码',
      },
    },
    {
      fieldName: 'confirmPassword',
      label: '确认密码',
      component: 'VbenInputPassword',
      componentProps: {
        passwordStrength: true,
        placeholder: '请再次输入新密码',
      },
      dependencies: {
        rules(values) {
          const { newPassword } = values;
          return z
            .string({ required_error: '请再次输入新密码' })
            .min(1, { message: '请再次输入新密码' })
            .refine((value) => value === newPassword, {
              message: '两次输入的密码不一致',
            });
        },
        triggerFields: ['newPassword'],
      },
    },
  ];
});

function handleSubmit() {
  message.success('密码修改成功');
}
</script>
<template>
  <ProfilePasswordSetting
    class="w-1/3"
    :form-schema="formSchema"
    @submit="handleSubmit"
  />
</template>


================================================
FILE: apps/web-antd/src/views/_core/profile/security-setting.vue
================================================
<script setup lang="ts">
import { computed } from 'vue';

import { ProfileSecuritySetting } from '@vben/common-ui';

const formSchema = computed(() => {
  return [
    {
      value: true,
      fieldName: 'accountPassword',
      label: '账户密码',
      description: '当前密码强度:强',
    },
    {
      value: true,
      fieldName: 'securityPhone',
      label: '密保手机',
      description: '已绑定手机:138****8293',
    },
    {
      value: true,
      fieldName: 'securityQuestion',
      label: '密保问题',
      description: '未设置密保问题,密保问题可有效保护账户安全',
    },
    {
      value: true,
      fieldName: 'securityEmail',
      label: '备用邮箱',
      description: '已绑定邮箱:ant***sign.com',
    },
    {
      value: false,
      fieldName: 'securityMfa',
      label: 'MFA 设备',
      description: '未绑定 MFA 设备,绑定后,可以进行二次确认',
    },
  ];
});
</script>
<template>
  <ProfileSecuritySetting :form-schema="formSchema" />
</template>


================================================
FILE: apps/web-antd/src/views/dashboard/analytics/analytics-trends.vue
================================================
<script lang="ts" setup>
import type { EchartsUIType } from '@vben/plugins/echarts';

import { onMounted, ref } from 'vue';

import { EchartsUI, useEcharts } from '@vben/plugins/echarts';

const chartRef = ref<EchartsUIType>();
const { renderEcharts } = useEcharts(chartRef);

onMounted(() => {
  renderEcharts({
    grid: {
      bottom: 0,
      containLabel: true,
      left: '1%',
      right: '1%',
      top: '2 %',
    },
    series: [
      {
        areaStyle: {},
        data: [
          111, 2000, 6000, 16_000, 33_333, 55_555, 64_000, 33_333, 18_000,
          36_000, 70_000, 42_444, 23_222, 13_000, 8000, 4000, 1200, 333, 222,
          111,
        ],
        itemStyle: {
          color: '#5ab1ef',
        },
        smooth: true,
        type: 'line',
      },
      {
        areaStyle: {},
        data: [
          33, 66, 88, 333, 3333, 6200, 20_000, 3000, 1200, 13_000, 22_000,
          11_000, 2221, 1201, 390, 198, 60, 30, 22, 11,
        ],
        itemStyle: {
          color: '#019680',
        },
        smooth: true,
        type: 'line',
      },
    ],
    tooltip: {
      axisPointer: {
        lineStyle: {
          color: '#019680',
          width: 1,
        },
      },
      trigger: 'axis',
    },
    // xAxis: {
    //   axisTick: {
    //     show: false,
    //   },
    //   boundaryGap: false,
    //   data: Array.from({ length: 18 }).map((_item, in
Download .txt
gitextract_e_asnnwg/

├── .browserslistrc
├── .changeset/
│   ├── README.md
│   └── config.json
├── .commitlintrc.js
├── .dockerignore
├── .editorconfig
├── .gitattributes
├── .gitconfig
├── .github/
│   ├── CODEOWNERS
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug-report.yml
│   │   ├── docs.yml
│   │   └── feature-request.yml
│   ├── actions/
│   │   └── setup-node/
│   │       └── action.yml
│   ├── commit-convention.md
│   ├── config.yml
│   ├── contributing.md
│   ├── dependabot.yml
│   ├── pull_request_template.md
│   ├── release-drafter.yml
│   ├── semantic.yml
│   └── workflows/
│       ├── build.yml
│       ├── changeset-version.yml
│       ├── ci.yml
│       ├── codeql.yml
│       ├── deploy.yml
│       ├── draft.yml
│       ├── issue-close-require.yml
│       ├── issue-labeled.yml
│       ├── lock.yml
│       ├── release-tag.yml
│       ├── rerun.yml
│       ├── semantic-pull-request.yml
│       └── stale.yml
├── .gitignore
├── .gitpod.yml
├── .node-version
├── .npmrc
├── .stylelintignore
├── .vscode/
│   ├── extensions.json
│   ├── global.code-snippets
│   ├── launch.json
│   └── settings.json
├── LICENSE
├── README.ja-JP.md
├── README.md
├── README.zh-CN.md
├── apps/
│   ├── backend-mock/
│   │   ├── README.md
│   │   ├── api/
│   │   │   ├── auth/
│   │   │   │   ├── codes.ts
│   │   │   │   ├── login.post.ts
│   │   │   │   ├── logout.post.ts
│   │   │   │   └── refresh.post.ts
│   │   │   ├── demo/
│   │   │   │   └── bigint.ts
│   │   │   ├── menu/
│   │   │   │   └── all.ts
│   │   │   ├── status.ts
│   │   │   ├── system/
│   │   │   │   ├── dept/
│   │   │   │   │   ├── .post.ts
│   │   │   │   │   ├── [id].delete.ts
│   │   │   │   │   ├── [id].put.ts
│   │   │   │   │   └── list.ts
│   │   │   │   ├── menu/
│   │   │   │   │   ├── list.ts
│   │   │   │   │   ├── name-exists.ts
│   │   │   │   │   └── path-exists.ts
│   │   │   │   └── role/
│   │   │   │       └── list.ts
│   │   │   ├── table/
│   │   │   │   └── list.ts
│   │   │   ├── test.get.ts
│   │   │   ├── test.post.ts
│   │   │   ├── timezone/
│   │   │   │   ├── getTimezone.ts
│   │   │   │   ├── getTimezoneOptions.ts
│   │   │   │   └── setTimezone.ts
│   │   │   ├── upload.ts
│   │   │   └── user/
│   │   │       └── info.ts
│   │   ├── error.ts
│   │   ├── middleware/
│   │   │   └── 1.api.ts
│   │   ├── nitro.config.ts
│   │   ├── package.json
│   │   ├── routes/
│   │   │   └── [...].ts
│   │   ├── tsconfig.build.json
│   │   ├── tsconfig.json
│   │   └── utils/
│   │       ├── cookie-utils.ts
│   │       ├── jwt-utils.ts
│   │       ├── mock-data.ts
│   │       ├── response.ts
│   │       └── timezone-utils.ts
│   ├── web-antd/
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── adapter/
│   │   │   │   ├── component/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── form.ts
│   │   │   │   └── vxe-table.ts
│   │   │   ├── api/
│   │   │   │   ├── core/
│   │   │   │   │   ├── auth.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu.ts
│   │   │   │   │   └── user.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── request.ts
│   │   │   ├── app.vue
│   │   │   ├── bootstrap.ts
│   │   │   ├── layouts/
│   │   │   │   ├── auth.vue
│   │   │   │   ├── basic.vue
│   │   │   │   └── index.ts
│   │   │   ├── locales/
│   │   │   │   ├── README.md
│   │   │   │   ├── index.ts
│   │   │   │   └── langs/
│   │   │   │       ├── en-US/
│   │   │   │       │   ├── demos.json
│   │   │   │       │   └── page.json
│   │   │   │       └── zh-CN/
│   │   │   │           ├── demos.json
│   │   │   │           └── page.json
│   │   │   ├── main.ts
│   │   │   ├── preferences.ts
│   │   │   ├── router/
│   │   │   │   ├── access.ts
│   │   │   │   ├── guard.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── routes/
│   │   │   │       ├── core.ts
│   │   │   │       ├── index.ts
│   │   │   │       └── modules/
│   │   │   │           ├── dashboard.ts
│   │   │   │           ├── demos.ts
│   │   │   │           └── vben.ts
│   │   │   ├── store/
│   │   │   │   ├── auth.ts
│   │   │   │   └── index.ts
│   │   │   └── views/
│   │   │       ├── _core/
│   │   │       │   ├── README.md
│   │   │       │   ├── about/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── authentication/
│   │   │       │   │   ├── code-login.vue
│   │   │       │   │   ├── forget-password.vue
│   │   │       │   │   ├── login.vue
│   │   │       │   │   ├── qrcode-login.vue
│   │   │       │   │   └── register.vue
│   │   │       │   ├── fallback/
│   │   │       │   │   ├── coming-soon.vue
│   │   │       │   │   ├── forbidden.vue
│   │   │       │   │   ├── internal-error.vue
│   │   │       │   │   ├── not-found.vue
│   │   │       │   │   └── offline.vue
│   │   │       │   └── profile/
│   │   │       │       ├── base-setting.vue
│   │   │       │       ├── index.vue
│   │   │       │       ├── notification-setting.vue
│   │   │       │       ├── password-setting.vue
│   │   │       │       └── security-setting.vue
│   │   │       ├── dashboard/
│   │   │       │   ├── analytics/
│   │   │       │   │   ├── analytics-trends.vue
│   │   │       │   │   ├── analytics-visits-data.vue
│   │   │       │   │   ├── analytics-visits-sales.vue
│   │   │       │   │   ├── analytics-visits-source.vue
│   │   │       │   │   ├── analytics-visits.vue
│   │   │       │   │   └── index.vue
│   │   │       │   └── workspace/
│   │   │       │       └── index.vue
│   │   │       └── demos/
│   │   │           └── antd/
│   │   │               └── index.vue
│   │   ├── tsconfig.json
│   │   ├── tsconfig.node.json
│   │   └── vite.config.ts
│   ├── web-antdv-next/
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── adapter/
│   │   │   │   ├── component/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── form.ts
│   │   │   │   └── vxe-table.ts
│   │   │   ├── api/
│   │   │   │   ├── core/
│   │   │   │   │   ├── auth.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu.ts
│   │   │   │   │   └── user.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── request.ts
│   │   │   ├── app.vue
│   │   │   ├── bootstrap.ts
│   │   │   ├── layouts/
│   │   │   │   ├── auth.vue
│   │   │   │   ├── basic.vue
│   │   │   │   └── index.ts
│   │   │   ├── locales/
│   │   │   │   ├── README.md
│   │   │   │   ├── index.ts
│   │   │   │   └── langs/
│   │   │   │       ├── en-US/
│   │   │   │       │   ├── demos.json
│   │   │   │       │   └── page.json
│   │   │   │       └── zh-CN/
│   │   │   │           ├── demos.json
│   │   │   │           └── page.json
│   │   │   ├── main.ts
│   │   │   ├── preferences.ts
│   │   │   ├── router/
│   │   │   │   ├── access.ts
│   │   │   │   ├── guard.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── routes/
│   │   │   │       ├── core.ts
│   │   │   │       ├── index.ts
│   │   │   │       └── modules/
│   │   │   │           ├── dashboard.ts
│   │   │   │           ├── demos.ts
│   │   │   │           └── vben.ts
│   │   │   ├── store/
│   │   │   │   ├── auth.ts
│   │   │   │   └── index.ts
│   │   │   └── views/
│   │   │       ├── _core/
│   │   │       │   ├── README.md
│   │   │       │   ├── about/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── authentication/
│   │   │       │   │   ├── code-login.vue
│   │   │       │   │   ├── forget-password.vue
│   │   │       │   │   ├── login.vue
│   │   │       │   │   ├── qrcode-login.vue
│   │   │       │   │   └── register.vue
│   │   │       │   ├── fallback/
│   │   │       │   │   ├── coming-soon.vue
│   │   │       │   │   ├── forbidden.vue
│   │   │       │   │   ├── internal-error.vue
│   │   │       │   │   ├── not-found.vue
│   │   │       │   │   └── offline.vue
│   │   │       │   └── profile/
│   │   │       │       ├── base-setting.vue
│   │   │       │       ├── index.vue
│   │   │       │       ├── notification-setting.vue
│   │   │       │       ├── password-setting.vue
│   │   │       │       └── security-setting.vue
│   │   │       ├── dashboard/
│   │   │       │   ├── analytics/
│   │   │       │   │   ├── analytics-trends.vue
│   │   │       │   │   ├── analytics-visits-data.vue
│   │   │       │   │   ├── analytics-visits-sales.vue
│   │   │       │   │   ├── analytics-visits-source.vue
│   │   │       │   │   ├── analytics-visits.vue
│   │   │       │   │   └── index.vue
│   │   │       │   └── workspace/
│   │   │       │       └── index.vue
│   │   │       └── demos/
│   │   │           └── antd/
│   │   │               └── index.vue
│   │   ├── tsconfig.json
│   │   ├── tsconfig.node.json
│   │   └── vite.config.ts
│   ├── web-ele/
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── adapter/
│   │   │   │   ├── component/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── form.ts
│   │   │   │   └── vxe-table.ts
│   │   │   ├── api/
│   │   │   │   ├── core/
│   │   │   │   │   ├── auth.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu.ts
│   │   │   │   │   └── user.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── request.ts
│   │   │   ├── app.vue
│   │   │   ├── bootstrap.ts
│   │   │   ├── layouts/
│   │   │   │   ├── auth.vue
│   │   │   │   ├── basic.vue
│   │   │   │   └── index.ts
│   │   │   ├── locales/
│   │   │   │   ├── README.md
│   │   │   │   ├── index.ts
│   │   │   │   └── langs/
│   │   │   │       ├── en-US/
│   │   │   │       │   ├── demos.json
│   │   │   │       │   └── page.json
│   │   │   │       └── zh-CN/
│   │   │   │           ├── demos.json
│   │   │   │           └── page.json
│   │   │   ├── main.ts
│   │   │   ├── preferences.ts
│   │   │   ├── router/
│   │   │   │   ├── access.ts
│   │   │   │   ├── guard.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── routes/
│   │   │   │       ├── core.ts
│   │   │   │       ├── index.ts
│   │   │   │       └── modules/
│   │   │   │           ├── dashboard.ts
│   │   │   │           ├── demos.ts
│   │   │   │           └── vben.ts
│   │   │   ├── store/
│   │   │   │   ├── auth.ts
│   │   │   │   └── index.ts
│   │   │   ├── types/
│   │   │   │   └── element-plus-style-css.d.ts
│   │   │   └── views/
│   │   │       ├── _core/
│   │   │       │   ├── README.md
│   │   │       │   ├── about/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── authentication/
│   │   │       │   │   ├── code-login.vue
│   │   │       │   │   ├── forget-password.vue
│   │   │       │   │   ├── login.vue
│   │   │       │   │   ├── qrcode-login.vue
│   │   │       │   │   └── register.vue
│   │   │       │   ├── fallback/
│   │   │       │   │   ├── coming-soon.vue
│   │   │       │   │   ├── forbidden.vue
│   │   │       │   │   ├── internal-error.vue
│   │   │       │   │   ├── not-found.vue
│   │   │       │   │   └── offline.vue
│   │   │       │   └── profile/
│   │   │       │       ├── base-setting.vue
│   │   │       │       ├── index.vue
│   │   │       │       ├── notification-setting.vue
│   │   │       │       ├── password-setting.vue
│   │   │       │       └── security-setting.vue
│   │   │       ├── dashboard/
│   │   │       │   ├── analytics/
│   │   │       │   │   ├── analytics-trends.vue
│   │   │       │   │   ├── analytics-visits-data.vue
│   │   │       │   │   ├── analytics-visits-sales.vue
│   │   │       │   │   ├── analytics-visits-source.vue
│   │   │       │   │   ├── analytics-visits.vue
│   │   │       │   │   └── index.vue
│   │   │       │   └── workspace/
│   │   │       │       └── index.vue
│   │   │       └── demos/
│   │   │           ├── element/
│   │   │           │   └── index.vue
│   │   │           └── form/
│   │   │               └── basic.vue
│   │   ├── tsconfig.json
│   │   ├── tsconfig.node.json
│   │   └── vite.config.ts
│   ├── web-naive/
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── adapter/
│   │   │   │   ├── component/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── form.ts
│   │   │   │   ├── naive.ts
│   │   │   │   └── vxe-table.ts
│   │   │   ├── api/
│   │   │   │   ├── core/
│   │   │   │   │   ├── auth.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── menu.ts
│   │   │   │   │   └── user.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── request.ts
│   │   │   ├── app.vue
│   │   │   ├── bootstrap.ts
│   │   │   ├── layouts/
│   │   │   │   ├── auth.vue
│   │   │   │   ├── basic.vue
│   │   │   │   └── index.ts
│   │   │   ├── locales/
│   │   │   │   ├── README.md
│   │   │   │   ├── index.ts
│   │   │   │   └── langs/
│   │   │   │       ├── en-US/
│   │   │   │       │   ├── demos.json
│   │   │   │       │   └── page.json
│   │   │   │       └── zh-CN/
│   │   │   │           ├── demos.json
│   │   │   │           └── page.json
│   │   │   ├── main.ts
│   │   │   ├── preferences.ts
│   │   │   ├── router/
│   │   │   │   ├── access.ts
│   │   │   │   ├── guard.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── routes/
│   │   │   │       ├── core.ts
│   │   │   │       ├── index.ts
│   │   │   │       └── modules/
│   │   │   │           ├── dashboard.ts
│   │   │   │           ├── demos.ts
│   │   │   │           └── vben.ts
│   │   │   ├── store/
│   │   │   │   ├── auth.ts
│   │   │   │   └── index.ts
│   │   │   └── views/
│   │   │       ├── _core/
│   │   │       │   ├── README.md
│   │   │       │   ├── about/
│   │   │       │   │   └── index.vue
│   │   │       │   ├── authentication/
│   │   │       │   │   ├── code-login.vue
│   │   │       │   │   ├── forget-password.vue
│   │   │       │   │   ├── login.vue
│   │   │       │   │   ├── qrcode-login.vue
│   │   │       │   │   └── register.vue
│   │   │       │   ├── fallback/
│   │   │       │   │   ├── coming-soon.vue
│   │   │       │   │   ├── forbidden.vue
│   │   │       │   │   ├── internal-error.vue
│   │   │       │   │   ├── not-found.vue
│   │   │       │   │   └── offline.vue
│   │   │       │   └── profile/
│   │   │       │       ├── base-setting.vue
│   │   │       │       ├── index.vue
│   │   │       │       ├── notification-setting.vue
│   │   │       │       ├── password-setting.vue
│   │   │       │       └── security-setting.vue
│   │   │       ├── dashboard/
│   │   │       │   ├── analytics/
│   │   │       │   │   ├── analytics-trends.vue
│   │   │       │   │   ├── analytics-visits-data.vue
│   │   │       │   │   ├── analytics-visits-sales.vue
│   │   │       │   │   ├── analytics-visits-source.vue
│   │   │       │   │   ├── analytics-visits.vue
│   │   │       │   │   └── index.vue
│   │   │       │   └── workspace/
│   │   │       │       └── index.vue
│   │   │       └── demos/
│   │   │           ├── form/
│   │   │           │   ├── basic.vue
│   │   │           │   └── modal.vue
│   │   │           ├── naive/
│   │   │           │   └── index.vue
│   │   │           └── table/
│   │   │               └── index.vue
│   │   ├── tsconfig.json
│   │   ├── tsconfig.node.json
│   │   └── vite.config.ts
│   └── web-tdesign/
│       ├── index.html
│       ├── package.json
│       ├── src/
│       │   ├── adapter/
│       │   │   ├── component/
│       │   │   │   └── index.ts
│       │   │   ├── form.ts
│       │   │   ├── tdesign.ts
│       │   │   └── vxe-table.ts
│       │   ├── api/
│       │   │   ├── core/
│       │   │   │   ├── auth.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── menu.ts
│       │   │   │   └── user.ts
│       │   │   ├── index.ts
│       │   │   └── request.ts
│       │   ├── app.vue
│       │   ├── bootstrap.ts
│       │   ├── layouts/
│       │   │   ├── auth.vue
│       │   │   ├── basic.vue
│       │   │   └── index.ts
│       │   ├── locales/
│       │   │   ├── README.md
│       │   │   ├── index.ts
│       │   │   └── langs/
│       │   │       ├── en-US/
│       │   │       │   ├── demos.json
│       │   │       │   └── page.json
│       │   │       └── zh-CN/
│       │   │           ├── demos.json
│       │   │           └── page.json
│       │   ├── main.ts
│       │   ├── preferences.ts
│       │   ├── router/
│       │   │   ├── access.ts
│       │   │   ├── guard.ts
│       │   │   ├── index.ts
│       │   │   └── routes/
│       │   │       ├── core.ts
│       │   │       ├── index.ts
│       │   │       └── modules/
│       │   │           ├── dashboard.ts
│       │   │           ├── demos.ts
│       │   │           └── vben.ts
│       │   ├── store/
│       │   │   ├── auth.ts
│       │   │   └── index.ts
│       │   └── views/
│       │       ├── _core/
│       │       │   ├── README.md
│       │       │   ├── about/
│       │       │   │   └── index.vue
│       │       │   ├── authentication/
│       │       │   │   ├── code-login.vue
│       │       │   │   ├── forget-password.vue
│       │       │   │   ├── login.vue
│       │       │   │   ├── qrcode-login.vue
│       │       │   │   └── register.vue
│       │       │   ├── fallback/
│       │       │   │   ├── coming-soon.vue
│       │       │   │   ├── forbidden.vue
│       │       │   │   ├── internal-error.vue
│       │       │   │   ├── not-found.vue
│       │       │   │   └── offline.vue
│       │       │   └── profile/
│       │       │       ├── base-setting.vue
│       │       │       ├── index.vue
│       │       │       ├── notification-setting.vue
│       │       │       ├── password-setting.vue
│       │       │       └── security-setting.vue
│       │       ├── dashboard/
│       │       │   ├── analytics/
│       │       │   │   ├── analytics-trends.vue
│       │       │   │   ├── analytics-visits-data.vue
│       │       │   │   ├── analytics-visits-sales.vue
│       │       │   │   ├── analytics-visits-source.vue
│       │       │   │   ├── analytics-visits.vue
│       │       │   │   └── index.vue
│       │       │   └── workspace/
│       │       │       └── index.vue
│       │       └── demos/
│       │           └── tdesign/
│       │               └── index.vue
│       ├── tsconfig.json
│       ├── tsconfig.node.json
│       └── vite.config.ts
├── cspell.json
├── docs/
│   ├── .vitepress/
│   │   ├── components/
│   │   │   ├── demo-preview.vue
│   │   │   ├── index.ts
│   │   │   └── preview-group.vue
│   │   ├── config/
│   │   │   ├── en.mts
│   │   │   ├── index.mts
│   │   │   ├── plugins/
│   │   │   │   └── demo-preview.ts
│   │   │   ├── shared.mts
│   │   │   └── zh.mts
│   │   └── theme/
│   │       ├── components/
│   │       │   ├── site-layout.vue
│   │       │   └── vben-contributors.vue
│   │       ├── index.ts
│   │       ├── plugins/
│   │       │   └── hm.ts
│   │       └── styles/
│   │           ├── base.css
│   │           ├── index.ts
│   │           └── variables.css
│   ├── package.json
│   ├── src/
│   │   ├── _env/
│   │   │   ├── adapter/
│   │   │   │   ├── component.ts
│   │   │   │   ├── form.ts
│   │   │   │   └── vxe-table.ts
│   │   │   └── node/
│   │   │       └── adapter/
│   │   │           ├── form.ts
│   │   │           └── vxe-table.ts
│   │   ├── commercial/
│   │   │   ├── community.md
│   │   │   ├── customized.md
│   │   │   └── technical-support.md
│   │   ├── components/
│   │   │   ├── common-ui/
│   │   │   │   ├── vben-alert.md
│   │   │   │   ├── vben-api-component.md
│   │   │   │   ├── vben-count-to-animator.md
│   │   │   │   ├── vben-drawer.md
│   │   │   │   ├── vben-ellipsis-text.md
│   │   │   │   ├── vben-form.md
│   │   │   │   ├── vben-modal.md
│   │   │   │   └── vben-vxe-table.md
│   │   │   ├── introduction.md
│   │   │   └── layout-ui/
│   │   │       └── page.md
│   │   ├── demos/
│   │   │   ├── vben-alert/
│   │   │   │   ├── alert/
│   │   │   │   │   └── index.vue
│   │   │   │   ├── confirm/
│   │   │   │   │   └── index.vue
│   │   │   │   └── prompt/
│   │   │   │       └── index.vue
│   │   │   ├── vben-api-component/
│   │   │   │   └── cascader/
│   │   │   │       └── index.vue
│   │   │   ├── vben-count-to-animator/
│   │   │   │   ├── basic/
│   │   │   │   │   └── index.vue
│   │   │   │   └── custom/
│   │   │   │       └── index.vue
│   │   │   ├── vben-drawer/
│   │   │   │   ├── auto-height/
│   │   │   │   │   ├── drawer.vue
│   │   │   │   │   └── index.vue
│   │   │   │   ├── basic/
│   │   │   │   │   └── index.vue
│   │   │   │   ├── dynamic/
│   │   │   │   │   ├── drawer.vue
│   │   │   │   │   └── index.vue
│   │   │   │   ├── extra/
│   │   │   │   │   ├── drawer.vue
│   │   │   │   │   └── index.vue
│   │   │   │   └── shared-data/
│   │   │   │       ├── drawer.vue
│   │   │   │       └── index.vue
│   │   │   ├── vben-ellipsis-text/
│   │   │   │   ├── auto-display/
│   │   │   │   │   └── index.vue
│   │   │   │   ├── expand/
│   │   │   │   │   └── index.vue
│   │   │   │   ├── line/
│   │   │   │   │   └── index.vue
│   │   │   │   └── tooltip/
│   │   │   │       └── index.vue
│   │   │   ├── vben-form/
│   │   │   │   ├── api/
│   │   │   │   │   └── index.vue
│   │   │   │   ├── basic/
│   │   │   │   │   └── index.vue
│   │   │   │   ├── custom/
│   │   │   │   │   └── index.vue
│   │   │   │   ├── dynamic/
│   │   │   │   │   └── index.vue
│   │   │   │   ├── query/
│   │   │   │   │   └── index.vue
│   │   │   │   └── rules/
│   │   │   │       └── index.vue
│   │   │   ├── vben-modal/
│   │   │   │   ├── animation-type/
│   │   │   │   │   └── index.vue
│   │   │   │   ├── auto-height/
│   │   │   │   │   ├── index.vue
│   │   │   │   │   └── modal.vue
│   │   │   │   ├── basic/
│   │   │   │   │   └── index.vue
│   │   │   │   ├── draggable/
│   │   │   │   │   ├── index.vue
│   │   │   │   │   └── modal.vue
│   │   │   │   ├── dynamic/
│   │   │   │   │   ├── index.vue
│   │   │   │   │   └── modal.vue
│   │   │   │   ├── extra/
│   │   │   │   │   ├── index.vue
│   │   │   │   │   └── modal.vue
│   │   │   │   └── shared-data/
│   │   │   │       ├── index.vue
│   │   │   │       └── modal.vue
│   │   │   └── vben-vxe-table/
│   │   │       ├── basic/
│   │   │       │   └── index.vue
│   │   │       ├── custom-cell/
│   │   │       │   └── index.vue
│   │   │       ├── edit-cell/
│   │   │       │   └── index.vue
│   │   │       ├── edit-row/
│   │   │       │   └── index.vue
│   │   │       ├── fixed/
│   │   │       │   └── index.vue
│   │   │       ├── form/
│   │   │       │   └── index.vue
│   │   │       ├── mock-api.ts
│   │   │       ├── remote/
│   │   │       │   └── index.vue
│   │   │       ├── table-data.ts
│   │   │       ├── tree/
│   │   │       │   └── index.vue
│   │   │       └── virtual/
│   │   │           └── index.vue
│   │   ├── en/
│   │   │   ├── components/
│   │   │   │   ├── common-ui/
│   │   │   │   │   ├── vben-alert.md
│   │   │   │   │   ├── vben-api-component.md
│   │   │   │   │   ├── vben-count-to-animator.md
│   │   │   │   │   ├── vben-drawer.md
│   │   │   │   │   ├── vben-ellipsis-text.md
│   │   │   │   │   ├── vben-form.md
│   │   │   │   │   ├── vben-modal.md
│   │   │   │   │   └── vben-vxe-table.md
│   │   │   │   ├── introduction.md
│   │   │   │   └── layout-ui/
│   │   │   │       └── page.md
│   │   │   ├── guide/
│   │   │   │   ├── essentials/
│   │   │   │   │   ├── build.md
│   │   │   │   │   ├── concept.md
│   │   │   │   │   ├── development.md
│   │   │   │   │   ├── external-module.md
│   │   │   │   │   ├── icons.md
│   │   │   │   │   ├── route.md
│   │   │   │   │   ├── server.md
│   │   │   │   │   ├── settings.md
│   │   │   │   │   └── styles.md
│   │   │   │   ├── in-depth/
│   │   │   │   │   ├── access.md
│   │   │   │   │   ├── check-updates.md
│   │   │   │   │   ├── features.md
│   │   │   │   │   ├── layout.md
│   │   │   │   │   ├── loading.md
│   │   │   │   │   ├── locale.md
│   │   │   │   │   ├── login.md
│   │   │   │   │   ├── theme.md
│   │   │   │   │   └── ui-framework.md
│   │   │   │   ├── introduction/
│   │   │   │   │   ├── changelog.md
│   │   │   │   │   ├── quick-start.md
│   │   │   │   │   ├── roadmap.md
│   │   │   │   │   ├── thin.md
│   │   │   │   │   ├── vben.md
│   │   │   │   │   └── why.md
│   │   │   │   ├── other/
│   │   │   │   │   ├── faq.md
│   │   │   │   │   ├── project-update.md
│   │   │   │   │   └── remove-code.md
│   │   │   │   └── project/
│   │   │   │       ├── changeset.md
│   │   │   │       ├── cli.md
│   │   │   │       ├── dir.md
│   │   │   │       ├── standard.md
│   │   │   │       ├── tailwindcss.md
│   │   │   │       ├── test.md
│   │   │   │       └── vite.md
│   │   │   └── index.md
│   │   ├── friend-links/
│   │   │   └── index.md
│   │   ├── guide/
│   │   │   ├── essentials/
│   │   │   │   ├── build.md
│   │   │   │   ├── concept.md
│   │   │   │   ├── development.md
│   │   │   │   ├── external-module.md
│   │   │   │   ├── icons.md
│   │   │   │   ├── route.md
│   │   │   │   ├── server.md
│   │   │   │   ├── settings.md
│   │   │   │   └── styles.md
│   │   │   ├── in-depth/
│   │   │   │   ├── access.md
│   │   │   │   ├── check-updates.md
│   │   │   │   ├── features.md
│   │   │   │   ├── layout.md
│   │   │   │   ├── loading.md
│   │   │   │   ├── locale.md
│   │   │   │   ├── login.md
│   │   │   │   ├── theme.md
│   │   │   │   └── ui-framework.md
│   │   │   ├── introduction/
│   │   │   │   ├── changelog.md
│   │   │   │   ├── quick-start.md
│   │   │   │   ├── roadmap.md
│   │   │   │   ├── thin.md
│   │   │   │   ├── vben.md
│   │   │   │   └── why.md
│   │   │   ├── other/
│   │   │   │   ├── faq.md
│   │   │   │   ├── project-update.md
│   │   │   │   └── remove-code.md
│   │   │   └── project/
│   │   │       ├── changeset.md
│   │   │       ├── cli.md
│   │   │       ├── dir.md
│   │   │       ├── standard.md
│   │   │       ├── tailwindcss.md
│   │   │       ├── test.md
│   │   │       └── vite.md
│   │   ├── index.md
│   │   └── sponsor/
│   │       └── personal.md
│   └── tsconfig.json
├── eslint.config.mjs
├── internal/
│   ├── lint-configs/
│   │   ├── commitlint-config/
│   │   │   ├── index.mjs
│   │   │   └── package.json
│   │   ├── eslint-config/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── configs/
│   │   │   │   │   ├── ignores.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── javascript.ts
│   │   │   │   │   ├── jsonc.ts
│   │   │   │   │   ├── node.ts
│   │   │   │   │   ├── perfectionist.ts
│   │   │   │   │   ├── pnpm.ts
│   │   │   │   │   ├── typescript.ts
│   │   │   │   │   ├── unicorn.ts
│   │   │   │   │   ├── vue.ts
│   │   │   │   │   └── yaml.ts
│   │   │   │   ├── custom-config.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── util.ts
│   │   │   ├── tsconfig.json
│   │   │   └── tsdown.config.ts
│   │   ├── oxfmt-config/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   └── index.ts
│   │   │   ├── tsconfig.json
│   │   │   └── tsdown.config.ts
│   │   ├── oxlint-config/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── configs/
│   │   │   │   │   ├── command.ts
│   │   │   │   │   ├── comments.ts
│   │   │   │   │   ├── ignores.ts
│   │   │   │   │   ├── import.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── javascript.ts
│   │   │   │   │   ├── node.ts
│   │   │   │   │   ├── overrides.ts
│   │   │   │   │   ├── plugins.ts
│   │   │   │   │   ├── tailwindcss.ts
│   │   │   │   │   ├── test.ts
│   │   │   │   │   ├── typescript.ts
│   │   │   │   │   ├── unicorn.ts
│   │   │   │   │   └── vue.ts
│   │   │   │   └── index.ts
│   │   │   ├── tsconfig.json
│   │   │   └── tsdown.config.ts
│   │   └── stylelint-config/
│   │       ├── index.mjs
│   │       └── package.json
│   ├── node-utils/
│   │   ├── package.json
│   │   ├── scripts/
│   │   │   └── build.mjs
│   │   ├── src/
│   │   │   ├── __tests__/
│   │   │   │   ├── hash.test.ts
│   │   │   │   └── path.test.ts
│   │   │   ├── constants.ts
│   │   │   ├── date.ts
│   │   │   ├── formatter.ts
│   │   │   ├── fs.ts
│   │   │   ├── git.ts
│   │   │   ├── hash.ts
│   │   │   ├── index.ts
│   │   │   ├── monorepo.ts
│   │   │   ├── path.ts
│   │   │   └── spinner.ts
│   │   ├── tsconfig.build.json
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   ├── tailwind-config/
│   │   ├── package.json
│   │   └── src/
│   │       ├── index.ts
│   │       └── theme.css
│   ├── tsconfig/
│   │   ├── base.json
│   │   ├── library.json
│   │   ├── node.json
│   │   ├── package.json
│   │   ├── web-app.json
│   │   └── web.json
│   └── vite-config/
│       ├── package.json
│       ├── src/
│       │   ├── config/
│       │   │   ├── application.ts
│       │   │   ├── common.ts
│       │   │   ├── index.ts
│       │   │   └── library.ts
│       │   ├── index.ts
│       │   ├── options.ts
│       │   ├── plugins/
│       │   │   ├── archiver.ts
│       │   │   ├── extra-app-config.ts
│       │   │   ├── importmap.ts
│       │   │   ├── index.ts
│       │   │   ├── inject-app-loading/
│       │   │   │   ├── README.md
│       │   │   │   ├── default-loading-antd.html
│       │   │   │   ├── default-loading.html
│       │   │   │   └── index.ts
│       │   │   ├── inject-metadata.ts
│       │   │   ├── license.ts
│       │   │   ├── nitro-mock.ts
│       │   │   ├── print.ts
│       │   │   ├── tailwind-reference.ts
│       │   │   └── vxe-table.ts
│       │   ├── typing.ts
│       │   └── utils/
│       │       └── env.ts
│       ├── tsconfig.json
│       └── tsdown.config.ts
├── lefthook.yml
├── oxfmt.config.ts
├── oxlint.config.ts
├── package.json
├── packages/
│   ├── @core/
│   │   ├── README.md
│   │   ├── base/
│   │   │   ├── README.md
│   │   │   ├── design/
│   │   │   │   ├── package.json
│   │   │   │   ├── src/
│   │   │   │   │   ├── css/
│   │   │   │   │   │   ├── global.css
│   │   │   │   │   │   ├── nprogress.css
│   │   │   │   │   │   ├── transition.css
│   │   │   │   │   │   └── ui.css
│   │   │   │   │   ├── design-tokens/
│   │   │   │   │   │   ├── dark.css
│   │   │   │   │   │   ├── default.css
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── scss-bem/
│   │   │   │   │       ├── bem.scss
│   │   │   │   │       └── constants.scss
│   │   │   │   ├── tsconfig.json
│   │   │   │   └── vite.config.ts
│   │   │   ├── icons/
│   │   │   │   ├── package.json
│   │   │   │   ├── src/
│   │   │   │   │   ├── create-icon.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── lucide.ts
│   │   │   │   ├── tsconfig.json
│   │   │   │   └── tsdown.config.ts
│   │   │   ├── shared/
│   │   │   │   ├── package.json
│   │   │   │   ├── src/
│   │   │   │   │   ├── cache/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   └── storage-manager.test.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── storage-manager.ts
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   ├── color/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   └── convert.test.ts
│   │   │   │   │   │   ├── color.ts
│   │   │   │   │   │   ├── convert.ts
│   │   │   │   │   │   ├── generator.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── constants/
│   │   │   │   │   │   ├── globals.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── vben.ts
│   │   │   │   │   ├── global-state.ts
│   │   │   │   │   ├── store.ts
│   │   │   │   │   └── utils/
│   │   │   │   │       ├── __tests__/
│   │   │   │   │       │   ├── date.test.ts
│   │   │   │   │       │   ├── diff.test.ts
│   │   │   │   │       │   ├── dom.test.ts
│   │   │   │   │       │   ├── inference.test.ts
│   │   │   │   │       │   ├── letter.test.ts
│   │   │   │   │       │   ├── resources.test.ts
│   │   │   │   │       │   ├── stack.test.ts
│   │   │   │   │       │   ├── state-handler.test.ts
│   │   │   │   │       │   ├── tree.test.ts
│   │   │   │   │       │   ├── unique.test.ts
│   │   │   │   │       │   ├── update-css-variables.test.ts
│   │   │   │   │       │   ├── util.test.ts
│   │   │   │   │       │   └── window.test.ts
│   │   │   │   │       ├── cn.ts
│   │   │   │   │       ├── date.ts
│   │   │   │   │       ├── diff.ts
│   │   │   │   │       ├── dom.ts
│   │   │   │   │       ├── download.ts
│   │   │   │   │       ├── index.ts
│   │   │   │   │       ├── inference.ts
│   │   │   │   │       ├── letter.ts
│   │   │   │   │       ├── merge.ts
│   │   │   │   │       ├── nprogress.ts
│   │   │   │   │       ├── resources.ts
│   │   │   │   │       ├── stack.ts
│   │   │   │   │       ├── state-handler.ts
│   │   │   │   │       ├── to.ts
│   │   │   │   │       ├── tree.ts
│   │   │   │   │       ├── unique.ts
│   │   │   │   │       ├── update-css-variables.ts
│   │   │   │   │       ├── util.ts
│   │   │   │   │       └── window.ts
│   │   │   │   ├── tsconfig.json
│   │   │   │   └── tsdown.config.ts
│   │   │   └── typings/
│   │   │       ├── package.json
│   │   │       ├── src/
│   │   │       │   ├── app.d.ts
│   │   │       │   ├── basic.d.ts
│   │   │       │   ├── helper.d.ts
│   │   │       │   ├── index.ts
│   │   │       │   ├── menu-record.ts
│   │   │       │   ├── tabs.ts
│   │   │       │   └── vue-router.d.ts
│   │   │       ├── tsconfig.json
│   │   │       ├── tsdown.config.ts
│   │   │       └── vue-router.d.ts
│   │   ├── composables/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── __tests__/
│   │   │   │   │   └── use-sortable.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── use-is-mobile.ts
│   │   │   │   ├── use-layout-style.ts
│   │   │   │   ├── use-namespace.ts
│   │   │   │   ├── use-priority-value.ts
│   │   │   │   ├── use-scroll-lock.ts
│   │   │   │   ├── use-simple-locale/
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── messages.ts
│   │   │   │   └── use-sortable.ts
│   │   │   ├── tsconfig.json
│   │   │   └── tsdown.config.ts
│   │   ├── preferences/
│   │   │   ├── __tests__/
│   │   │   │   ├── __snapshots__/
│   │   │   │   │   └── config.test.ts.snap
│   │   │   │   ├── config.test.ts
│   │   │   │   └── preferences.test.ts
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── config.ts
│   │   │   │   ├── constants.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── preferences.ts
│   │   │   │   ├── types.ts
│   │   │   │   ├── update-css-variables.ts
│   │   │   │   └── use-preferences.ts
│   │   │   ├── tsconfig.json
│   │   │   └── tsdown.config.ts
│   │   └── ui-kit/
│   │       ├── README.md
│   │       ├── form-ui/
│   │       │   ├── __tests__/
│   │       │   │   └── form-api.test.ts
│   │       │   ├── package.json
│   │       │   ├── src/
│   │       │   │   ├── components/
│   │       │   │   │   └── form-actions.vue
│   │       │   │   ├── config.ts
│   │       │   │   ├── form-api.ts
│   │       │   │   ├── form-render/
│   │       │   │   │   ├── context.ts
│   │       │   │   │   ├── dependencies.ts
│   │       │   │   │   ├── expandable.ts
│   │       │   │   │   ├── form-field.vue
│   │       │   │   │   ├── form-label.vue
│   │       │   │   │   ├── form.vue
│   │       │   │   │   ├── helper.ts
│   │       │   │   │   └── index.ts
│   │       │   │   ├── index.ts
│   │       │   │   ├── types.ts
│   │       │   │   ├── use-form-context.ts
│   │       │   │   ├── use-vben-form.ts
│   │       │   │   ├── vben-form.vue
│   │       │   │   └── vben-use-form.vue
│   │       │   ├── tsconfig.json
│   │       │   └── tsdown.config.ts
│   │       ├── layout-ui/
│   │       │   ├── package.json
│   │       │   ├── src/
│   │       │   │   ├── components/
│   │       │   │   │   ├── index.ts
│   │       │   │   │   ├── layout-content.vue
│   │       │   │   │   ├── layout-footer.vue
│   │       │   │   │   ├── layout-header.vue
│   │       │   │   │   ├── layout-sidebar.vue
│   │       │   │   │   ├── layout-tabbar.vue
│   │       │   │   │   └── widgets/
│   │       │   │   │       ├── index.ts
│   │       │   │   │       ├── sidebar-collapse-button.vue
│   │       │   │   │       └── sidebar-fixed-button.vue
│   │       │   │   ├── hooks/
│   │       │   │   │   ├── use-layout.ts
│   │       │   │   │   └── use-sidebar-drag.ts
│   │       │   │   ├── index.ts
│   │       │   │   ├── vben-layout.ts
│   │       │   │   └── vben-layout.vue
│   │       │   ├── tsconfig.json
│   │       │   └── tsdown.config.ts
│   │       ├── menu-ui/
│   │       │   ├── README.md
│   │       │   ├── package.json
│   │       │   ├── src/
│   │       │   │   ├── components/
│   │       │   │   │   ├── collapse-transition.vue
│   │       │   │   │   ├── index.ts
│   │       │   │   │   ├── menu-badge-dot.vue
│   │       │   │   │   ├── menu-badge.vue
│   │       │   │   │   ├── menu-item.vue
│   │       │   │   │   ├── menu.vue
│   │       │   │   │   ├── normal-menu/
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   ├── normal-menu.ts
│   │       │   │   │   │   └── normal-menu.vue
│   │       │   │   │   ├── sub-menu-content.vue
│   │       │   │   │   └── sub-menu.vue
│   │       │   │   ├── hooks/
│   │       │   │   │   ├── index.ts
│   │       │   │   │   ├── use-menu-context.ts
│   │       │   │   │   ├── use-menu-scroll.ts
│   │       │   │   │   └── use-menu.ts
│   │       │   │   ├── index.ts
│   │       │   │   ├── menu.vue
│   │       │   │   ├── sub-menu.vue
│   │       │   │   ├── types.ts
│   │       │   │   └── utils/
│   │       │   │       └── index.ts
│   │       │   ├── tsconfig.json
│   │       │   └── tsdown.config.ts
│   │       ├── popup-ui/
│   │       │   ├── package.json
│   │       │   ├── src/
│   │       │   │   ├── alert/
│   │       │   │   │   ├── AlertBuilder.ts
│   │       │   │   │   ├── alert.ts
│   │       │   │   │   ├── alert.vue
│   │       │   │   │   └── index.ts
│   │       │   │   ├── drawer/
│   │       │   │   │   ├── __tests__/
│   │       │   │   │   │   └── drawer-api.test.ts
│   │       │   │   │   ├── drawer-api.ts
│   │       │   │   │   ├── drawer.ts
│   │       │   │   │   ├── drawer.vue
│   │       │   │   │   ├── index.ts
│   │       │   │   │   └── use-drawer.ts
│   │       │   │   ├── index.ts
│   │       │   │   └── modal/
│   │       │   │       ├── __tests__/
│   │       │   │       │   └── modal-api.test.ts
│   │       │   │       ├── index.ts
│   │       │   │       ├── modal-api.ts
│   │       │   │       ├── modal.ts
│   │       │   │       ├── modal.vue
│   │       │   │       ├── use-modal-draggable.ts
│   │       │   │       └── use-modal.ts
│   │       │   ├── tsconfig.json
│   │       │   └── tsdown.config.ts
│   │       ├── shadcn-ui/
│   │       │   ├── components.json
│   │       │   ├── package.json
│   │       │   ├── src/
│   │       │   │   ├── assets/
│   │       │   │   │   └── index.css
│   │       │   │   ├── components/
│   │       │   │   │   ├── avatar/
│   │       │   │   │   │   ├── avatar.vue
│   │       │   │   │   │   └── index.ts
│   │       │   │   │   ├── back-top/
│   │       │   │   │   │   ├── back-top.vue
│   │       │   │   │   │   ├── backtop.ts
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   └── use-backtop.ts
│   │       │   │   │   ├── breadcrumb/
│   │       │   │   │   │   ├── breadcrumb-background.vue
│   │       │   │   │   │   ├── breadcrumb-view.vue
│   │       │   │   │   │   ├── breadcrumb.vue
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   └── types.ts
│   │       │   │   │   ├── button/
│   │       │   │   │   │   ├── button-group.vue
│   │       │   │   │   │   ├── button.ts
│   │       │   │   │   │   ├── button.vue
│   │       │   │   │   │   ├── check-button-group.vue
│   │       │   │   │   │   ├── icon-button.vue
│   │       │   │   │   │   └── index.ts
│   │       │   │   │   ├── checkbox/
│   │       │   │   │   │   ├── checkbox.vue
│   │       │   │   │   │   └── index.ts
│   │       │   │   │   ├── context-menu/
│   │       │   │   │   │   ├── context-menu.vue
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   └── interface.ts
│   │       │   │   │   ├── count-to-animator/
│   │       │   │   │   │   ├── count-to-animator.vue
│   │       │   │   │   │   └── index.ts
│   │       │   │   │   ├── dropdown-menu/
│   │       │   │   │   │   ├── dropdown-menu.vue
│   │       │   │   │   │   ├── dropdown-radio-menu.vue
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   └── interface.ts
│   │       │   │   │   ├── expandable-arrow/
│   │       │   │   │   │   ├── expandable-arrow.vue
│   │       │   │   │   │   └── index.ts
│   │       │   │   │   ├── full-screen/
│   │       │   │   │   │   ├── full-screen.vue
│   │       │   │   │   │   └── index.ts
│   │       │   │   │   ├── hover-card/
│   │       │   │   │   │   ├── hover-card.vue
│   │       │   │   │   │   └── index.ts
│   │       │   │   │   ├── icon/
│   │       │   │   │   │   ├── icon.vue
│   │       │   │   │   │   └── index.ts
│   │       │   │   │   ├── index.ts
│   │       │   │   │   ├── input-password/
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   ├── input-password.vue
│   │       │   │   │   │   └── password-strength.vue
│   │       │   │   │   ├── logo/
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   └── logo.vue
│   │       │   │   │   ├── pin-input/
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   ├── input.vue
│   │       │   │   │   │   └── types.ts
│   │       │   │   │   ├── popover/
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   └── popover.vue
│   │       │   │   │   ├── render-content/
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   └── render-content.vue
│   │       │   │   │   ├── scrollbar/
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   └── scrollbar.vue
│   │       │   │   │   ├── segmented/
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   ├── segmented.vue
│   │       │   │   │   │   ├── tabs-indicator.vue
│   │       │   │   │   │   └── types.ts
│   │       │   │   │   ├── select/
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   └── select.vue
│   │       │   │   │   ├── spine-text/
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   └── spine-text.vue
│   │       │   │   │   ├── spinner/
│   │       │   │   │   │   ├── index.ts
│   │       │   │   │   │   ├── loading.vue
│   │       │   │   │   │   └── spinner.vue
│   │       │   │   │   └── tooltip/
│   │       │   │   │       ├── help-tooltip.vue
│   │       │   │   │       ├── index.ts
│   │       │   │   │       └── tooltip.vue
│   │       │   │   ├── index.ts
│   │       │   │   └── ui/
│   │       │   │       ├── accordion/
│   │       │   │       │   ├── Accordion.vue
│   │       │   │       │   ├── AccordionContent.vue
│   │       │   │       │   ├── AccordionItem.vue
│   │       │   │       │   ├── AccordionTrigger.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── alert-dialog/
│   │       │   │       │   ├── AlertDialog.vue
│   │       │   │       │   ├── AlertDialogAction.vue
│   │       │   │       │   ├── AlertDialogCancel.vue
│   │       │   │       │   ├── AlertDialogContent.vue
│   │       │   │       │   ├── AlertDialogDescription.vue
│   │       │   │       │   ├── AlertDialogOverlay.vue
│   │       │   │       │   ├── AlertDialogTitle.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── avatar/
│   │       │   │       │   ├── Avatar.vue
│   │       │   │       │   ├── AvatarFallback.vue
│   │       │   │       │   ├── AvatarImage.vue
│   │       │   │       │   ├── avatar.ts
│   │       │   │       │   └── index.ts
│   │       │   │       ├── badge/
│   │       │   │       │   ├── Badge.vue
│   │       │   │       │   ├── badge.ts
│   │       │   │       │   └── index.ts
│   │       │   │       ├── breadcrumb/
│   │       │   │       │   ├── Breadcrumb.vue
│   │       │   │       │   ├── BreadcrumbEllipsis.vue
│   │       │   │       │   ├── BreadcrumbItem.vue
│   │       │   │       │   ├── BreadcrumbLink.vue
│   │       │   │       │   ├── BreadcrumbList.vue
│   │       │   │       │   ├── BreadcrumbPage.vue
│   │       │   │       │   ├── BreadcrumbSeparator.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── button/
│   │       │   │       │   ├── Button.vue
│   │       │   │       │   ├── button.ts
│   │       │   │       │   ├── index.ts
│   │       │   │       │   └── types.ts
│   │       │   │       ├── card/
│   │       │   │       │   ├── Card.vue
│   │       │   │       │   ├── CardContent.vue
│   │       │   │       │   ├── CardDescription.vue
│   │       │   │       │   ├── CardFooter.vue
│   │       │   │       │   ├── CardHeader.vue
│   │       │   │       │   ├── CardTitle.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── checkbox/
│   │       │   │       │   ├── Checkbox.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── context-menu/
│   │       │   │       │   ├── ContextMenu.vue
│   │       │   │       │   ├── ContextMenuCheckboxItem.vue
│   │       │   │       │   ├── ContextMenuContent.vue
│   │       │   │       │   ├── ContextMenuGroup.vue
│   │       │   │       │   ├── ContextMenuItem.vue
│   │       │   │       │   ├── ContextMenuLabel.vue
│   │       │   │       │   ├── ContextMenuPortal.vue
│   │       │   │       │   ├── ContextMenuRadioGroup.vue
│   │       │   │       │   ├── ContextMenuRadioItem.vue
│   │       │   │       │   ├── ContextMenuSeparator.vue
│   │       │   │       │   ├── ContextMenuShortcut.vue
│   │       │   │       │   ├── ContextMenuSub.vue
│   │       │   │       │   ├── ContextMenuSubContent.vue
│   │       │   │       │   ├── ContextMenuSubTrigger.vue
│   │       │   │       │   ├── ContextMenuTrigger.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── dialog/
│   │       │   │       │   ├── Dialog.vue
│   │       │   │       │   ├── DialogClose.vue
│   │       │   │       │   ├── DialogContent.vue
│   │       │   │       │   ├── DialogDescription.vue
│   │       │   │       │   ├── DialogFooter.vue
│   │       │   │       │   ├── DialogHeader.vue
│   │       │   │       │   ├── DialogOverlay.vue
│   │       │   │       │   ├── DialogScrollContent.vue
│   │       │   │       │   ├── DialogTitle.vue
│   │       │   │       │   ├── DialogTrigger.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── dropdown-menu/
│   │       │   │       │   ├── DropdownMenu.vue
│   │       │   │       │   ├── DropdownMenuCheckboxItem.vue
│   │       │   │       │   ├── DropdownMenuContent.vue
│   │       │   │       │   ├── DropdownMenuGroup.vue
│   │       │   │       │   ├── DropdownMenuItem.vue
│   │       │   │       │   ├── DropdownMenuLabel.vue
│   │       │   │       │   ├── DropdownMenuRadioGroup.vue
│   │       │   │       │   ├── DropdownMenuRadioItem.vue
│   │       │   │       │   ├── DropdownMenuSeparator.vue
│   │       │   │       │   ├── DropdownMenuShortcut.vue
│   │       │   │       │   ├── DropdownMenuSub.vue
│   │       │   │       │   ├── DropdownMenuSubContent.vue
│   │       │   │       │   ├── DropdownMenuSubTrigger.vue
│   │       │   │       │   ├── DropdownMenuTrigger.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── form/
│   │       │   │       │   ├── FormControl.vue
│   │       │   │       │   ├── FormDescription.vue
│   │       │   │       │   ├── FormItem.vue
│   │       │   │       │   ├── FormLabel.vue
│   │       │   │       │   ├── FormMessage.vue
│   │       │   │       │   ├── index.ts
│   │       │   │       │   ├── injectionKeys.ts
│   │       │   │       │   └── useFormField.ts
│   │       │   │       ├── hover-card/
│   │       │   │       │   ├── HoverCard.vue
│   │       │   │       │   ├── HoverCardContent.vue
│   │       │   │       │   ├── HoverCardTrigger.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── index.ts
│   │       │   │       ├── input/
│   │       │   │       │   ├── Input.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── label/
│   │       │   │       │   ├── Label.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── number-field/
│   │       │   │       │   ├── NumberField.vue
│   │       │   │       │   ├── NumberFieldContent.vue
│   │       │   │       │   ├── NumberFieldDecrement.vue
│   │       │   │       │   ├── NumberFieldIncrement.vue
│   │       │   │       │   ├── NumberFieldInput.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── pagination/
│   │       │   │       │   ├── PaginationEllipsis.vue
│   │       │   │       │   ├── PaginationFirst.vue
│   │       │   │       │   ├── PaginationLast.vue
│   │       │   │       │   ├── PaginationNext.vue
│   │       │   │       │   ├── PaginationPrev.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── pin-input/
│   │       │   │       │   ├── PinInput.vue
│   │       │   │       │   ├── PinInputGroup.vue
│   │       │   │       │   ├── PinInputInput.vue
│   │       │   │       │   ├── PinInputSeparator.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── popover/
│   │       │   │       │   ├── Popover.vue
│   │       │   │       │   ├── PopoverContent.vue
│   │       │   │       │   ├── PopoverTrigger.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── radio-group/
│   │       │   │       │   ├── RadioGroup.vue
│   │       │   │       │   ├── RadioGroupItem.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── resizable/
│   │       │   │       │   ├── ResizableHandle.vue
│   │       │   │       │   ├── ResizablePanelGroup.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── scroll-area/
│   │       │   │       │   ├── ScrollArea.vue
│   │       │   │       │   ├── ScrollBar.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── select/
│   │       │   │       │   ├── Select.vue
│   │       │   │       │   ├── SelectContent.vue
│   │       │   │       │   ├── SelectGroup.vue
│   │       │   │       │   ├── SelectItem.vue
│   │       │   │       │   ├── SelectItemText.vue
│   │       │   │       │   ├── SelectLabel.vue
│   │       │   │       │   ├── SelectScrollDownButton.vue
│   │       │   │       │   ├── SelectScrollUpButton.vue
│   │       │   │       │   ├── SelectSeparator.vue
│   │       │   │       │   ├── SelectTrigger.vue
│   │       │   │       │   ├── SelectValue.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── separator/
│   │       │   │       │   ├── Separator.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── sheet/
│   │       │   │       │   ├── Sheet.vue
│   │       │   │       │   ├── SheetClose.vue
│   │       │   │       │   ├── SheetContent.vue
│   │       │   │       │   ├── SheetDescription.vue
│   │       │   │       │   ├── SheetFooter.vue
│   │       │   │       │   ├── SheetHeader.vue
│   │       │   │       │   ├── SheetOverlay.vue
│   │       │   │       │   ├── SheetTitle.vue
│   │       │   │       │   ├── SheetTrigger.vue
│   │       │   │       │   ├── index.ts
│   │       │   │       │   └── sheet.ts
│   │       │   │       ├── switch/
│   │       │   │       │   ├── Switch.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── tabs/
│   │       │   │       │   ├── Tabs.vue
│   │       │   │       │   ├── TabsContent.vue
│   │       │   │       │   ├── TabsList.vue
│   │       │   │       │   ├── TabsTrigger.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── textarea/
│   │       │   │       │   ├── Textarea.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── toggle/
│   │       │   │       │   ├── Toggle.vue
│   │       │   │       │   ├── index.ts
│   │       │   │       │   └── toggle.ts
│   │       │   │       ├── toggle-group/
│   │       │   │       │   ├── ToggleGroup.vue
│   │       │   │       │   ├── ToggleGroupItem.vue
│   │       │   │       │   └── index.ts
│   │       │   │       ├── tooltip/
│   │       │   │       │   ├── Tooltip.vue
│   │       │   │       │   ├── TooltipContent.vue
│   │       │   │       │   ├── TooltipProvider.vue
│   │       │   │       │   ├── TooltipTrigger.vue
│   │       │   │       │   └── index.ts
│   │       │   │       └── tree/
│   │       │   │           ├── index.ts
│   │       │   │           ├── tree.vue
│   │       │   │           └── types.ts
│   │       │   └── tsconfig.json
│   │       └── tabs-ui/
│   │           ├── package.json
│   │           ├── src/
│   │           │   ├── components/
│   │           │   │   ├── index.ts
│   │           │   │   ├── tabs/
│   │           │   │   │   └── tabs.vue
│   │           │   │   ├── tabs-chrome/
│   │           │   │   │   └── tabs.vue
│   │           │   │   └── widgets/
│   │           │   │       ├── index.ts
│   │           │   │       ├── tool-more.vue
│   │           │   │       ├── tool-refresh.vue
│   │           │   │       └── tool-screen.vue
│   │           │   ├── index.ts
│   │           │   ├── tabs-view.vue
│   │           │   ├── types.ts
│   │           │   ├── use-tabs-drag.ts
│   │           │   └── use-tabs-view-scroll.ts
│   │           ├── tsconfig.json
│   │           └── tsdown.config.ts
│   ├── constants/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── core.ts
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   ├── effects/
│   │   ├── README.md
│   │   ├── access/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── access-control.vue
│   │   │   │   ├── accessible.ts
│   │   │   │   ├── directive.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── use-access.ts
│   │   │   └── tsconfig.json
│   │   ├── common-ui/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── components/
│   │   │   │   │   ├── api-component/
│   │   │   │   │   │   ├── api-component.vue
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── captcha/
│   │   │   │   │   │   ├── hooks/
│   │   │   │   │   │   │   └── useCaptchaPoints.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── point-selection-captcha/
│   │   │   │   │   │   │   ├── index.vue
│   │   │   │   │   │   │   └── point-selection-captcha-card.vue
│   │   │   │   │   │   ├── slider-captcha/
│   │   │   │   │   │   │   ├── index.vue
│   │   │   │   │   │   │   ├── slider-captcha-action.vue
│   │   │   │   │   │   │   ├── slider-captcha-bar.vue
│   │   │   │   │   │   │   └── slider-captcha-content.vue
│   │   │   │   │   │   ├── slider-rotate-captcha/
│   │   │   │   │   │   │   └── index.vue
│   │   │   │   │   │   ├── slider-translate-captcha/
│   │   │   │   │   │   │   └── index.vue
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   ├── col-page/
│   │   │   │   │   │   ├── col-page.vue
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   ├── count-to/
│   │   │   │   │   │   ├── count-to.vue
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   ├── cropper/
│   │   │   │   │   │   ├── cropper.vue
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── ellipsis-text/
│   │   │   │   │   │   ├── ellipsis-text.vue
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── icon-picker/
│   │   │   │   │   │   ├── icon-picker.vue
│   │   │   │   │   │   ├── icons.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── json-viewer/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── index.vue
│   │   │   │   │   │   ├── style.scss
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   ├── loading/
│   │   │   │   │   │   ├── directive.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── loading.vue
│   │   │   │   │   │   └── spinner.vue
│   │   │   │   │   ├── page/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   └── page.test.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── page.vue
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   ├── resize/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── resize.vue
│   │   │   │   │   ├── tippy/
│   │   │   │   │   │   ├── directive.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   └── tree/
│   │   │   │   │       ├── index.ts
│   │   │   │   │       └── tree.vue
│   │   │   │   ├── index.ts
│   │   │   │   └── ui/
│   │   │   │       ├── about/
│   │   │   │       │   ├── about.ts
│   │   │   │       │   ├── about.vue
│   │   │   │       │   └── index.ts
│   │   │   │       ├── authentication/
│   │   │   │       │   ├── auth-title.vue
│   │   │   │       │   ├── code-login.vue
│   │   │   │       │   ├── dingding-login.vue
│   │   │   │       │   ├── forget-password.vue
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── login-expired-modal.vue
│   │   │   │       │   ├── login.vue
│   │   │   │       │   ├── qrcode-login.vue
│   │   │   │       │   ├── register.vue
│   │   │   │       │   ├── third-party-login.vue
│   │   │   │       │   └── types.ts
│   │   │   │       ├── dashboard/
│   │   │   │       │   ├── analysis/
│   │   │   │       │   │   ├── analysis-chart-card.vue
│   │   │   │       │   │   ├── analysis-charts-tabs.vue
│   │   │   │       │   │   ├── analysis-overview.vue
│   │   │   │       │   │   └── index.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── typing.ts
│   │   │   │       │   └── workbench/
│   │   │   │       │       ├── index.ts
│   │   │   │       │       ├── workbench-header.vue
│   │   │   │       │       ├── workbench-project.vue
│   │   │   │       │       ├── workbench-quick-nav.vue
│   │   │   │       │       ├── workbench-todo.vue
│   │   │   │       │       └── workbench-trends.vue
│   │   │   │       ├── fallback/
│   │   │   │       │   ├── fallback.ts
│   │   │   │       │   ├── fallback.vue
│   │   │   │       │   ├── icons/
│   │   │   │       │   │   ├── icon-403.vue
│   │   │   │       │   │   ├── icon-404.vue
│   │   │   │       │   │   ├── icon-500.vue
│   │   │   │       │   │   ├── icon-coming-soon.vue
│   │   │   │       │   │   └── icon-offline.vue
│   │   │   │       │   └── index.ts
│   │   │   │       ├── index.ts
│   │   │   │       └── profile/
│   │   │   │           ├── base-setting.vue
│   │   │   │           ├── index.ts
│   │   │   │           ├── notification-setting.vue
│   │   │   │           ├── password-setting.vue
│   │   │   │           ├── profile.vue
│   │   │   │           ├── security-setting.vue
│   │   │   │           └── types.ts
│   │   │   └── tsconfig.json
│   │   ├── hooks/
│   │   │   ├── README.md
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── index.ts
│   │   │   │   ├── use-app-config.ts
│   │   │   │   ├── use-content-maximize.ts
│   │   │   │   ├── use-design-tokens.ts
│   │   │   │   ├── use-hover-toggle.ts
│   │   │   │   ├── use-pagination.ts
│   │   │   │   ├── use-refresh.ts
│   │   │   │   ├── use-tabs.ts
│   │   │   │   └── use-watermark.ts
│   │   │   └── tsconfig.json
│   │   ├── layouts/
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── authentication/
│   │   │   │   │   ├── authentication.vue
│   │   │   │   │   ├── form.vue
│   │   │   │   │   ├── icons/
│   │   │   │   │   │   └── slogan.vue
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── toolbar.vue
│   │   │   │   │   └── types.ts
│   │   │   │   ├── basic/
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── content/
│   │   │   │   │   │   ├── content-spinner.vue
│   │   │   │   │   │   ├── content.vue
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── use-content-spinner.ts
│   │   │   │   │   ├── copyright/
│   │   │   │   │   │   ├── copyright.vue
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── footer/
│   │   │   │   │   │   ├── footer.vue
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── header/
│   │   │   │   │   │   ├── header.vue
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── layout.vue
│   │   │   │   │   ├── menu/
│   │   │   │   │   │   ├── extra-menu.vue
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── menu.vue
│   │   │   │   │   │   ├── mixed-menu.vue
│   │   │   │   │   │   ├── use-extra-menu.ts
│   │   │   │   │   │   ├── use-mixed-menu.ts
│   │   │   │   │   │   └── use-navigation.ts
│   │   │   │   │   └── tabbar/
│   │   │   │   │       ├── index.ts
│   │   │   │   │       ├── tabbar.vue
│   │   │   │   │       └── use-tabbar.ts
│   │   │   │   ├── hooks/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── iframe/
│   │   │   │   │   ├── iframe-router-view.vue
│   │   │   │   │   ├── iframe-view.vue
│   │   │   │   │   └── index.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── route-cached/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── route-cached-page.vue
│   │   │   │   │   └── route-cached-view.vue
│   │   │   │   └── widgets/
│   │   │   │       ├── breadcrumb.vue
│   │   │   │       ├── check-updates/
│   │   │   │       │   ├── check-updates.vue
│   │   │   │       │   └── index.ts
│   │   │   │       ├── color-toggle.vue
│   │   │   │       ├── global-search/
│   │   │   │       │   ├── global-search.vue
│   │   │   │       │   ├── index.ts
│   │   │   │       │   └── search-panel.vue
│   │   │   │       ├── index.ts
│   │   │   │       ├── language-toggle.vue
│   │   │   │       ├── layout-toggle.vue
│   │   │   │       ├── lock-screen/
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── lock-screen-modal.vue
│   │   │   │       │   └── lock-screen.vue
│   │   │   │       ├── notification/
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── notification.vue
│   │   │   │       │   └── types.ts
│   │   │   │       ├── preferences/
│   │   │   │       │   ├── blocks/
│   │   │   │       │   │   ├── block.vue
│   │   │   │       │   │   ├── checkbox-item.vue
│   │   │   │       │   │   ├── general/
│   │   │   │       │   │   │   ├── animation.vue
│   │   │   │       │   │   │   └── general.vue
│   │   │   │       │   │   ├── index.ts
│   │   │   │       │   │   ├── input-item.vue
│   │   │   │       │   │   ├── layout/
│   │   │   │       │   │   │   ├── breadcrumb.vue
│   │   │   │       │   │   │   ├── content.vue
│   │   │   │       │   │   │   ├── copyright.vue
│   │   │   │       │   │   │   ├── footer.vue
│   │   │   │       │   │   │   ├── header.vue
│   │   │   │       │   │   │   ├── layout.vue
│   │   │   │       │   │   │   ├── navigation.vue
│   │   │   │       │   │   │   ├── sidebar.vue
│   │   │   │       │   │   │   ├── tabbar.vue
│   │   │   │       │   │   │   └── widget.vue
│   │   │   │       │   │   ├── number-field-item.vue
│   │   │   │       │   │   ├── select-item.vue
│   │   │   │       │   │   ├── shortcut-keys/
│   │   │   │       │   │   │   └── global.vue
│   │   │   │       │   │   ├── switch-item.vue
│   │   │   │       │   │   ├── theme/
│   │   │   │       │   │   │   ├── builtin.vue
│   │   │   │       │   │   │   ├── color-mode.vue
│   │   │   │       │   │   │   ├── font-size.vue
│   │   │   │       │   │   │   ├── radius.vue
│   │   │   │       │   │   │   └── theme.vue
│   │   │   │       │   │   └── toggle-item.vue
│   │   │   │       │   ├── icons/
│   │   │   │       │   │   ├── content-compact.vue
│   │   │   │       │   │   ├── full-content.vue
│   │   │   │       │   │   ├── header-mixed-nav.vue
│   │   │   │       │   │   ├── header-nav.vue
│   │   │   │       │   │   ├── header-sidebar-nav.vue
│   │   │   │       │   │   ├── index.ts
│   │   │   │       │   │   ├── mixed-nav.vue
│   │   │   │       │   │   ├── setting.vue
│   │   │   │       │   │   ├── sidebar-mixed-nav.vue
│   │   │   │       │   │   └── sidebar-nav.vue
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── preferences-button.vue
│   │   │   │       │   ├── preferences-drawer.vue
│   │   │   │       │   ├── preferences.vue
│   │   │   │       │   └── use-open-preferences.ts
│   │   │   │       ├── theme-toggle/
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── theme-button.vue
│   │   │   │       │   └── theme-toggle.vue
│   │   │   │       ├── timezone/
│   │   │   │       │   ├── index.ts
│   │   │   │       │   └── timezone-button.vue
│   │   │   │       └── user-dropdown/
│   │   │   │           ├── index.ts
│   │   │   │           └── user-dropdown.vue
│   │   │   └── tsconfig.json
│   │   ├── plugins/
│   │   │   ├── README.md
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── echarts/
│   │   │   │   │   ├── echarts-ui.vue
│   │   │   │   │   ├── echarts.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── use-echarts.ts
│   │   │   │   ├── motion/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── types.ts
│   │   │   │   └── vxe-table/
│   │   │   │       ├── api.ts
│   │   │   │       ├── extends.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── init.ts
│   │   │   │       ├── style.css
│   │   │   │       ├── types.ts
│   │   │   │       ├── use-vxe-grid.ts
│   │   │   │       └── use-vxe-grid.vue
│   │   │   └── tsconfig.json
│   │   └── request/
│   │       ├── package.json
│   │       ├── src/
│   │       │   ├── index.ts
│   │       │   └── request-client/
│   │       │       ├── index.ts
│   │       │       ├── modules/
│   │       │       │   ├── downloader.test.ts
│   │       │       │   ├── downloader.ts
│   │       │       │   ├── interceptor.ts
│   │       │       │   ├── sse.test.ts
│   │       │       │   ├── sse.ts
│   │       │       │   ├── uploader.test.ts
│   │       │       │   └── uploader.ts
│   │       │       ├── preset-interceptors.ts
│   │       │       ├── request-client.test.ts
│   │       │       ├── request-client.ts
│   │       │       └── types.ts
│   │       └── tsconfig.json
│   ├── icons/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── iconify/
│   │   │   │   └── index.ts
│   │   │   ├── icons/
│   │   │   │   └── empty-icon.vue
│   │   │   ├── index.ts
│   │   │   └── svg/
│   │   │       ├── index.ts
│   │   │       └── load.ts
│   │   └── tsconfig.json
│   ├── locales/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── i18n.ts
│   │   │   ├── index.ts
│   │   │   ├── langs/
│   │   │   │   ├── en-US/
│   │   │   │   │   ├── authentication.json
│   │   │   │   │   ├── common.json
│   │   │   │   │   ├── preferences.json
│   │   │   │   │   ├── profile.json
│   │   │   │   │   └── ui.json
│   │   │   │   └── zh-CN/
│   │   │   │       ├── authentication.json
│   │   │   │       ├── common.json
│   │   │   │       ├── preferences.json
│   │   │   │       ├── profile.json
│   │   │   │       └── ui.json
│   │   │   └── typing.ts
│   │   └── tsconfig.json
│   ├── preferences/
│   │   ├── package.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   ├── stores/
│   │   ├── package.json
│   │   ├── shim-pinia.d.ts
│   │   ├── src/
│   │   │   ├── index.ts
│   │   │   ├── modules/
│   │   │   │   ├── access.test.ts
│   │   │   │   ├── access.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── tabbar.test.ts
│   │   │   │   ├── tabbar.ts
│   │   │   │   ├── timezone.ts
│   │   │   │   ├── user.test.ts
│   │   │   │   └── user.ts
│   │   │   └── setup.ts
│   │   └── tsconfig.json
│   ├── styles/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── antd/
│   │   │   │   └── index.css
│   │   │   ├── antdv-next/
│   │   │   │   └── index.css
│   │   │   ├── ele/
│   │   │   │   └── index.css
│   │   │   ├── global/
│   │   │   │   └── index.scss
│   │   │   ├── index.ts
│   │   │   └── naive/
│   │   │       └── index.css
│   │   └── tsconfig.json
│   ├── types/
│   │   ├── README.md
│   │   ├── global.d.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── index.ts
│   │   │   └── user.ts
│   │   └── tsconfig.json
│   └── utils/
│       ├── README.md
│       ├── package.json
│       ├── src/
│       │   ├── helpers/
│       │   │   ├── __tests__/
│       │   │   │   ├── find-menu-by-path.test.ts
│       │   │   │   ├── generate-menus.test.ts
│       │   │   │   ├── generate-routes-frontend.test.ts
│       │   │   │   └── merge-route-modules.test.ts
│       │   │   ├── find-menu-by-path.ts
│       │   │   ├── generate-menus.ts
│       │   │   ├── generate-routes-backend.ts
│       │   │   ├── generate-routes-frontend.ts
│       │   │   ├── get-popup-container.ts
│       │   │   ├── index.ts
│       │   │   ├── merge-route-modules.ts
│       │   │   ├── reset-routes.ts
│       │   │   └── unmount-global-loading.ts
│       │   └── index.ts
│       └── tsconfig.json
├── playground/
│   ├── __tests__/
│   │   └── e2e/
│   │       ├── auth-login.spec.ts
│   │       └── common/
│   │           └── auth.ts
│   ├── index.html
│   ├── package.json
│   ├── playwright.config.ts
│   ├── src/
│   │   ├── adapter/
│   │   │   ├── component/
│   │   │   │   └── index.ts
│   │   │   ├── form.ts
│   │   │   └── vxe-table.ts
│   │   ├── api/
│   │   │   ├── core/
│   │   │   │   ├── auth.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── menu.ts
│   │   │   │   ├── timezone.ts
│   │   │   │   └── user.ts
│   │   │   ├── examples/
│   │   │   │   ├── download.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── json-bigint.ts
│   │   │   │   ├── params.ts
│   │   │   │   ├── status.ts
│   │   │   │   ├── table.ts
│   │   │   │   └── upload.ts
│   │   │   ├── index.ts
│   │   │   ├── request.ts
│   │   │   └── system/
│   │   │       ├── dept.ts
│   │   │       ├── index.ts
│   │   │       ├── menu.ts
│   │   │       └── role.ts
│   │   ├── app.vue
│   │   ├── bootstrap.ts
│   │   ├── layouts/
│   │   │   ├── auth.vue
│   │   │   ├── basic.vue
│   │   │   └── index.ts
│   │   ├── locales/
│   │   │   ├── README.md
│   │   │   ├── index.ts
│   │   │   └── langs/
│   │   │       ├── en-US/
│   │   │       │   ├── demos.json
│   │   │       │   ├── examples.json
│   │   │       │   ├── page.json
│   │   │       │   └── system.json
│   │   │       └── zh-CN/
│   │   │           ├── demos.json
│   │   │           ├── examples.json
│   │   │           ├── page.json
│   │   │           └── system.json
│   │   ├── main.ts
│   │   ├── preferences.ts
│   │   ├── router/
│   │   │   ├── access.ts
│   │   │   ├── guard.ts
│   │   │   ├── index.ts
│   │   │   └── routes/
│   │   │       ├── core.ts
│   │   │       ├── index.ts
│   │   │       └── modules/
│   │   │           ├── dashboard.ts
│   │   │           ├── demos.ts
│   │   │           ├── examples.ts
│   │   │           ├── system.ts
│   │   │           └── vben.ts
│   │   ├── store/
│   │   │   ├── auth.ts
│   │   │   └── index.ts
│   │   ├── timezone-init.ts
│   │   └── views/
│   │       ├── _core/
│   │       │   ├── README.md
│   │       │   ├── about/
│   │       │   │   └── index.vue
│   │       │   ├── authentication/
│   │       │   │   ├── code-login.vue
│   │       │   │   ├── forget-password.vue
│   │       │   │   ├── login.vue
│   │       │   │   ├── qrcode-login.vue
│   │       │   │   └── register.vue
│   │       │   ├── fallback/
│   │       │   │   ├── coming-soon.vue
│   │       │   │   ├── forbidden.vue
│   │       │   │   ├── internal-error.vue
│   │       │   │   ├── not-found.vue
│   │       │   │   └── offline.vue
│   │       │   └── profile/
│   │       │       ├── base-setting.vue
│   │       │       ├── index.vue
│   │       │       ├── notification-setting.vue
│   │       │       ├── password-setting.vue
│   │       │       └── security-setting.vue
│   │       ├── dashboard/
│   │       │   ├── analytics/
│   │       │   │   ├── analytics-trends.vue
│   │       │   │   ├── analytics-visits-data.vue
│   │       │   │   ├── analytics-visits-sales.vue
│   │       │   │   ├── analytics-visits-source.vue
│   │       │   │   ├── analytics-visits.vue
│   │       │   │   └── index.vue
│   │       │   └── workspace/
│   │       │       └── index.vue
│   │       ├── demos/
│   │       │   ├── access/
│   │       │   │   ├── admin-visible.vue
│   │       │   │   ├── button-control.vue
│   │       │   │   ├── index.vue
│   │       │   │   ├── menu-visible-403.vue
│   │       │   │   ├── super-visible.vue
│   │       │   │   └── user-visible.vue
│   │       │   ├── active-icon/
│   │       │   │   └── index.vue
│   │       │   ├── badge/
│   │       │   │   └── index.vue
│   │       │   ├── breadcrumb/
│   │       │   │   ├── lateral-detail.vue
│   │       │   │   ├── lateral.vue
│   │       │   │   └── level-detail.vue
│   │       │   ├── features/
│   │       │   │   ├── clipboard/
│   │       │   │   │   └── index.vue
│   │       │   │   ├── file-download/
│   │       │   │   │   ├── base64.ts
│   │       │   │   │   └── index.vue
│   │       │   │   ├── full-screen/
│   │       │   │   │   └── index.vue
│   │       │   │   ├── hide-menu-children/
│   │       │   │   │   ├── children.vue
│   │       │   │   │   └── parent.vue
│   │       │   │   ├── icons/
│   │       │   │   │   └── index.vue
│   │       │   │   ├── json-bigint/
│   │       │   │   │   └── index.vue
│   │       │   │   ├── login-expired/
│   │       │   │   │   └── index.vue
│   │       │   │   ├── menu-query/
│   │       │   │   │   └── index.vue
│   │       │   │   ├── new-window/
│   │       │   │   │   └── index.vue
│   │       │   │   ├── request-params-serializer/
│   │       │   │   │   └── index.vue
│   │       │   │   ├── tabs/
│   │       │   │   │   ├── index.vue
│   │       │   │   │   └── tab-detail.vue
│   │       │   │   ├── vue-query/
│   │       │   │   │   ├── concurrency-caching.vue
│   │       │   │   │   ├── index.vue
│   │       │   │   │   ├── infinite-queries.vue
│   │       │   │   │   ├── paginated-queries.vue
│   │       │   │   │   ├── query-retries.vue
│   │       │   │   │   └── typing.ts
│   │       │   │   └── watermark/
│   │       │   │       └── index.vue
│   │       │   └── nested/
│   │       │       ├── menu-1.vue
│   │       │       ├── menu-2-1.vue
│   │       │       ├── menu-3-1.vue
│   │       │       └── menu-3-2-1.vue
│   │       ├── examples/
│   │       │   ├── button-group/
│   │       │   │   └── index.vue
│   │       │   ├── captcha/
│   │       │   │   ├── point-selection-captcha.vue
│   │       │   │   ├── slider-captcha.vue
│   │       │   │   ├── slider-rotate-captcha.vue
│   │       │   │   └── slider-translate-captcha.vue
│   │       │   ├── context-menu/
│   │       │   │   └── index.vue
│   │       │   ├── count-to/
│   │       │   │   └── index.vue
│   │       │   ├── cropper/
│   │       │   │   └── index.vue
│   │       │   ├── doc-button.vue
│   │       │   ├── drawer/
│   │       │   │   ├── auto-height-demo.vue
│   │       │   │   ├── base-demo.vue
│   │       │   │   ├── dynamic-demo.vue
│   │       │   │   ├── form-drawer-demo.vue
│   │       │   │   ├── in-content-demo.vue
│   │       │   │   ├── index.vue
│   │       │   │   └── shared-data-demo.vue
│   │       │   ├── ellipsis/
│   │       │   │   └── index.vue
│   │       │   ├── form/
│   │       │   │   ├── api.vue
│   │       │   │   ├── basic.vue
│   │       │   │   ├── custom-layout.vue
│   │       │   │   ├── custom.vue
│   │       │   │   ├── dynamic.vue
│   │       │   │   ├── merge.vue
│   │       │   │   ├── modules/
│   │       │   │   │   └── two-fields.vue
│   │       │   │   ├── query.vue
│   │       │   │   ├── rules.vue
│   │       │   │   └── scroll-to-error-test.vue
│   │       │   ├── json-viewer/
│   │       │   │   ├── data.ts
│   │       │   │   └── index.vue
│   │       │   ├── layout/
│   │       │   │   └── col-page.vue
│   │       │   ├── loading/
│   │       │   │   └── index.vue
│   │       │   ├── modal/
│   │       │   │   ├── auto-height-demo.vue
│   │       │   │   ├── base-demo.vue
│   │       │   │   ├── blur-demo.vue
│   │       │   │   ├── drag-demo.vue
│   │       │   │   ├── dynamic-demo.vue
│   │       │   │   ├── form-modal-demo.vue
│   │       │   │   ├── in-content-demo.vue
│   │       │   │   ├── index.vue
│   │       │   │   ├── nested-demo.vue
│   │       │   │   └── shared-data-demo.vue
│   │       │   ├── motion/
│   │       │   │   └── index.vue
│   │       │   ├── resize/
│   │       │   │   └── basic.vue
│   │       │   ├── tippy/
│   │       │   │   └── index.vue
│   │       │   └── vxe-table/
│   │       │       ├── basic.vue
│   │       │       ├── custom-cell.vue
│   │       │       ├── edit-cell.vue
│   │       │       ├── edit-row.vue
│   │       │       ├── fixed.vue
│   │       │       ├── form.vue
│   │       │       ├── remote.vue
│   │       │       ├── table-data.ts
│   │       │       ├── tree.vue
│   │       │       └── virtual.vue
│   │       └── system/
│   │           ├── dept/
│   │           │   ├── data.ts
│   │           │   ├── list.vue
│   │           │   └── modules/
│   │           │       └── form.vue
│   │           ├── menu/
│   │           │   ├── data.ts
│   │           │   ├── list.vue
│   │           │   └── modules/
│   │           │       └── form.vue
│   │           └── role/
│   │               ├── data.ts
│   │               ├── list.vue
│   │               └── modules/
│   │                   └── form.vue
│   ├── tsconfig.json
│   ├── tsconfig.node.json
│   └── vite.config.ts
├── pnpm-workspace.yaml
├── scripts/
│   ├── clean.mjs
│   ├── deploy/
│   │   ├── Dockerfile
│   │   ├── build-local-docker-image.sh
│   │   └── nginx.conf
│   ├── turbo-run/
│   │   ├── README.md
│   │   ├── bin/
│   │   │   └── turbo-run.mjs
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── index.ts
│   │   │   └── run.ts
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   └── vsh/
│       ├── README.md
│       ├── bin/
│       │   └── vsh.mjs
│       ├── env.d.ts
│       ├── package.json
│       ├── src/
│       │   ├── check-circular/
│       │   │   └── index.ts
│       │   ├── check-dep/
│       │   │   └── index.ts
│       │   ├── code-workspace/
│       │   │   └── index.ts
│       │   ├── index.ts
│       │   ├── lint/
│       │   │   └── index.ts
│       │   └── publint/
│       │       └── index.ts
│       ├── tsconfig.json
│       └── tsdown.config.ts
├── stylelint.config.mjs
├── tea.yaml
├── turbo.json
├── vben-admin.code-workspace
└── vitest.config.ts
Download .txt
SYMBOL INDEX (1098 symbols across 324 files)

FILE: apps/backend-mock/api/system/dept/list.ts
  function generateMockDataList (line 16) | function generateMockDataList(count: number) {

FILE: apps/backend-mock/api/system/menu/name-exists.ts
  function getNames (line 8) | function getNames(menus: any[]) {

FILE: apps/backend-mock/api/system/menu/path-exists.ts
  function getPaths (line 8) | function getPaths(menus: any[]) {

FILE: apps/backend-mock/api/system/role/list.ts
  function generateMockDataList (line 19) | function generateMockDataList(count: number) {

FILE: apps/backend-mock/api/table/list.ts
  function generateMockDataList (line 10) | function generateMockDataList(count: number) {
  type ItemType (line 75) | type ItemType = (typeof listData)[0];

FILE: apps/backend-mock/utils/cookie-utils.ts
  function clearRefreshTokenCookie (line 5) | function clearRefreshTokenCookie(event: H3Event<EventHandlerRequest>) {
  function setRefreshTokenCookie (line 13) | function setRefreshTokenCookie(
  function getRefreshTokenFromCookie (line 25) | function getRefreshTokenFromCookie(event: H3Event<EventHandlerRequest>) {

FILE: apps/backend-mock/utils/jwt-utils.ts
  constant ACCESS_TOKEN_SECRET (line 11) | const ACCESS_TOKEN_SECRET = 'access_token_secret';
  constant REFRESH_TOKEN_SECRET (line 12) | const REFRESH_TOKEN_SECRET = 'refresh_token_secret';
  type UserPayload (line 14) | interface UserPayload extends UserInfo {
  function generateAccessToken (line 19) | function generateAccessToken(user: UserInfo) {
  function generateRefreshToken (line 23) | function generateRefreshToken(user: UserInfo) {
  function verifyAccessToken (line 29) | function verifyAccessToken(
  function verifyRefreshToken (line 60) | function verifyRefreshToken(

FILE: apps/backend-mock/utils/mock-data.ts
  type UserInfo (line 1) | interface UserInfo {
  type TimezoneOption (line 10) | interface TimezoneOption {
  constant MOCK_USERS (line 15) | const MOCK_USERS: UserInfo[] = [
  constant MOCK_CODES (line 41) | const MOCK_CODES = [
  constant MOCK_MENUS (line 179) | const MOCK_MENUS = [
  constant MOCK_MENU_LIST (line 194) | const MOCK_MENU_LIST = [
  function getMenuIds (line 386) | function getMenuIds(menus: any[]) {
  constant TIME_ZONE_OPTIONS (line 400) | const TIME_ZONE_OPTIONS: TimezoneOption[] = [

FILE: apps/backend-mock/utils/response.ts
  function useResponseSuccess (line 5) | function useResponseSuccess<T = any>(data: T) {
  function usePageResponseSuccess (line 14) | function usePageResponseSuccess<T = any>(
  function useResponseError (line 35) | function useResponseError(message: string, error: any = null) {
  function forbiddenResponse (line 44) | function forbiddenResponse(
  function unAuthorizedResponse (line 52) | function unAuthorizedResponse(event: H3Event<EventHandlerRequest>) {
  function sleep (line 57) | function sleep(ms: number) {
  function pagination (line 61) | function pagination<T = any>(

FILE: apps/web-antd/src/adapter/component/index.ts
  constant IMAGE_EXTENSIONS (line 134) | const IMAGE_EXTENSIONS = new Set([
  function isImageFile (line 147) | function isImageFile(file: UploadFile): boolean {
  function createDefaultUploadSlots (line 168) | function createDefaultUploadSlots(listType: string, placeholder: string) {
  function getBase64 (line 190) | function getBase64(file: File): Promise<string> {
  function previewImage (line 202) | async function previewImage(
  function cropImage (line 281) | function cropImage(file: File, aspectRatio: string | undefined) {
  method setup (line 382) | setup(
  type ComponentType (line 565) | type ComponentType =
  function initComponentAdapter (line 595) | async function initComponentAdapter() {

FILE: apps/web-antd/src/adapter/form.ts
  function initSetupVbenForm (line 11) | async function initSetupVbenForm() {
  type VbenFormSchema (line 48) | type VbenFormSchema = FormSchema<ComponentType>;

FILE: apps/web-antd/src/adapter/vxe-table.ts
  method renderTableDefault (line 43) | renderTableDefault(renderOpts, params) {
  method renderTableDefault (line 52) | renderTableDefault(renderOpts) {

FILE: apps/web-antd/src/api/core/auth.ts
  type LoginParams (line 5) | interface LoginParams {
  type LoginResult (line 11) | interface LoginResult {
  type RefreshTokenResult (line 15) | interface RefreshTokenResult {
  function loginApi (line 24) | async function loginApi(data: AuthApi.LoginParams) {
  function refreshTokenApi (line 31) | async function refreshTokenApi() {
  function logoutApi (line 40) | async function logoutApi() {
  function getAccessCodesApi (line 49) | async function getAccessCodesApi() {

FILE: apps/web-antd/src/api/core/menu.ts
  function getAllMenusApi (line 8) | async function getAllMenusApi() {

FILE: apps/web-antd/src/api/core/user.ts
  function getUserInfoApi (line 8) | async function getUserInfoApi() {

FILE: apps/web-antd/src/api/request.ts
  function createRequestClient (line 24) | function createRequestClient(baseURL: string, options?: RequestClientOpt...

FILE: apps/web-antd/src/bootstrap.ts
  function bootstrap (line 19) | async function bootstrap(namespace: string) {

FILE: apps/web-antd/src/locales/index.ts
  function loadMessages (line 33) | async function loadMessages(lang: SupportedLanguagesType) {
  function loadThirdPartyMessage (line 45) | async function loadThirdPartyMessage(lang: SupportedLanguagesType) {
  function loadDayjsLocale (line 53) | async function loadDayjsLocale(lang: SupportedLanguagesType) {
  function loadAntdLocale (line 80) | async function loadAntdLocale(lang: SupportedLanguagesType) {
  function setupI18n (line 93) | async function setupI18n(app: App, options: LocaleSetupOptions = {}) {

FILE: apps/web-antd/src/main.ts
  function initApplication (line 9) | async function initApplication() {

FILE: apps/web-antd/src/router/access.ts
  function generateAccess (line 17) | async function generateAccess(options: GenerateMenuAndRoutesOptions) {

FILE: apps/web-antd/src/router/guard.ts
  function setupCommonGuard (line 17) | function setupCommonGuard(router: Router) {
  function setupAccessGuard (line 47) | function setupAccessGuard(router: Router) {
  function createRouterGuard (line 126) | function createRouterGuard(router: Router) {

FILE: apps/web-antd/src/store/auth.ts
  function authLogin (line 28) | async function authLogin(
  function logout (line 80) | async function logout(redirect: boolean = true) {
  function fetchUserInfo (line 100) | async function fetchUserInfo() {
  function $reset (line 106) | function $reset() {

FILE: apps/web-antdv-next/src/adapter/component/index.ts
  method setup (line 243) | setup() {
  method setup (line 314) | setup() {
  type ComponentType (line 494) | type ComponentType =
  function initComponentAdapter (line 524) | async function initComponentAdapter() {

FILE: apps/web-antdv-next/src/adapter/form.ts
  function initSetupVbenForm (line 11) | async function initSetupVbenForm() {
  type VbenFormSchema (line 48) | type VbenFormSchema = FormSchema<ComponentType>;

FILE: apps/web-antdv-next/src/adapter/vxe-table.ts
  method renderTableDefault (line 43) | renderTableDefault(renderOpts, params) {
  method renderTableDefault (line 52) | renderTableDefault(renderOpts) {

FILE: apps/web-antdv-next/src/api/core/auth.ts
  type LoginParams (line 5) | interface LoginParams {
  type LoginResult (line 11) | interface LoginResult {
  type RefreshTokenResult (line 15) | interface RefreshTokenResult {
  function loginApi (line 24) | async function loginApi(data: AuthApi.LoginParams) {
  function refreshTokenApi (line 31) | async function refreshTokenApi() {
  function logoutApi (line 40) | async function logoutApi() {
  function getAccessCodesApi (line 49) | async function getAccessCodesApi() {

FILE: apps/web-antdv-next/src/api/core/menu.ts
  function getAllMenusApi (line 8) | async function getAllMenusApi() {

FILE: apps/web-antdv-next/src/api/core/user.ts
  function getUserInfoApi (line 8) | async function getUserInfoApi() {

FILE: apps/web-antdv-next/src/api/request.ts
  function createRequestClient (line 24) | function createRequestClient(baseURL: string, options?: RequestClientOpt...

FILE: apps/web-antdv-next/src/bootstrap.ts
  function bootstrap (line 19) | async function bootstrap(namespace: string) {

FILE: apps/web-antdv-next/src/locales/index.ts
  function loadMessages (line 33) | async function loadMessages(lang: SupportedLanguagesType) {
  function loadThirdPartyMessage (line 45) | async function loadThirdPartyMessage(lang: SupportedLanguagesType) {
  function loadDayjsLocale (line 53) | async function loadDayjsLocale(lang: SupportedLanguagesType) {
  function loadAntdLocale (line 80) | async function loadAntdLocale(lang: SupportedLanguagesType) {
  function setupI18n (line 93) | async function setupI18n(app: App, options: LocaleSetupOptions = {}) {

FILE: apps/web-antdv-next/src/main.ts
  function initApplication (line 9) | async function initApplication() {

FILE: apps/web-antdv-next/src/router/access.ts
  function generateAccess (line 17) | async function generateAccess(options: GenerateMenuAndRoutesOptions) {

FILE: apps/web-antdv-next/src/router/guard.ts
  function setupCommonGuard (line 17) | function setupCommonGuard(router: Router) {
  function setupAccessGuard (line 47) | function setupAccessGuard(router: Router) {
  function createRouterGuard (line 126) | function createRouterGuard(router: Router) {

FILE: apps/web-antdv-next/src/store/auth.ts
  function authLogin (line 28) | async function authLogin(
  function logout (line 80) | async function logout(redirect: boolean = true) {
  function fetchUserInfo (line 100) | async function fetchUserInfo() {
  function $reset (line 106) | function $reset() {

FILE: apps/web-ele/src/adapter/component/index.ts
  type ComponentType (line 156) | type ComponentType =
  function initComponentAdapter (line 175) | async function initComponentAdapter() {

FILE: apps/web-ele/src/adapter/form.ts
  function initSetupVbenForm (line 11) | async function initSetupVbenForm() {
  type VbenFormSchema (line 40) | type VbenFormSchema = FormSchema<ComponentType>;

FILE: apps/web-ele/src/adapter/vxe-table.ts
  method renderTableDefault (line 43) | renderTableDefault(renderOpts, params) {
  method renderTableDefault (line 53) | renderTableDefault(renderOpts) {

FILE: apps/web-ele/src/api/core/auth.ts
  type LoginParams (line 5) | interface LoginParams {
  type LoginResult (line 11) | interface LoginResult {
  type RefreshTokenResult (line 15) | interface RefreshTokenResult {
  function loginApi (line 24) | async function loginApi(data: AuthApi.LoginParams) {
  function refreshTokenApi (line 31) | async function refreshTokenApi() {
  function logoutApi (line 40) | async function logoutApi() {
  function getAccessCodesApi (line 49) | async function getAccessCodesApi() {

FILE: apps/web-ele/src/api/core/menu.ts
  function getAllMenusApi (line 8) | async function getAllMenusApi() {

FILE: apps/web-ele/src/api/core/user.ts
  function getUserInfoApi (line 8) | async function getUserInfoApi() {

FILE: apps/web-ele/src/api/request.ts
  function createRequestClient (line 24) | function createRequestClient(baseURL: string, options?: RequestClientOpt...

FILE: apps/web-ele/src/bootstrap.ts
  function bootstrap (line 20) | async function bootstrap(namespace: string) {

FILE: apps/web-ele/src/locales/index.ts
  function loadMessages (line 33) | async function loadMessages(lang: SupportedLanguagesType) {
  function loadThirdPartyMessage (line 45) | async function loadThirdPartyMessage(lang: SupportedLanguagesType) {
  function loadDayjsLocale (line 53) | async function loadDayjsLocale(lang: SupportedLanguagesType) {
  function loadElementLocale (line 80) | async function loadElementLocale(lang: SupportedLanguagesType) {
  function setupI18n (line 93) | async function setupI18n(app: App, options: LocaleSetupOptions = {}) {

FILE: apps/web-ele/src/main.ts
  function initApplication (line 9) | async function initApplication() {

FILE: apps/web-ele/src/router/access.ts
  function generateAccess (line 17) | async function generateAccess(options: GenerateMenuAndRoutesOptions) {

FILE: apps/web-ele/src/router/guard.ts
  function setupCommonGuard (line 17) | function setupCommonGuard(router: Router) {
  function setupAccessGuard (line 47) | function setupAccessGuard(router: Router) {
  function createRouterGuard (line 126) | function createRouterGuard(router: Router) {

FILE: apps/web-ele/src/store/auth.ts
  function authLogin (line 28) | async function authLogin(
  function logout (line 81) | async function logout(redirect: boolean = true) {
  function fetchUserInfo (line 101) | async function fetchUserInfo() {
  function $reset (line 107) | function $reset() {

FILE: apps/web-naive/src/adapter/component/index.ts
  type ComponentType (line 102) | type ComponentType =
  function initComponentAdapter (line 121) | async function initComponentAdapter() {

FILE: apps/web-naive/src/adapter/form.ts
  function initSetupVbenForm (line 11) | async function initSetupVbenForm() {
  type VbenFormSchema (line 44) | type VbenFormSchema = FormSchema<ComponentType>;

FILE: apps/web-naive/src/adapter/vxe-table.ts
  method renderTableDefault (line 43) | renderTableDefault(renderOpts, params) {
  method renderTableDefault (line 52) | renderTableDefault(renderOpts) {

FILE: apps/web-naive/src/api/core/auth.ts
  type LoginParams (line 5) | interface LoginParams {
  type LoginResult (line 11) | interface LoginResult {
  type RefreshTokenResult (line 15) | interface RefreshTokenResult {
  function loginApi (line 24) | async function loginApi(data: AuthApi.LoginParams) {
  function refreshTokenApi (line 31) | async function refreshTokenApi() {
  function logoutApi (line 40) | async function logoutApi() {
  function getAccessCodesApi (line 49) | async function getAccessCodesApi() {

FILE: apps/web-naive/src/api/core/menu.ts
  function getAllMenusApi (line 8) | async function getAllMenusApi() {

FILE: apps/web-naive/src/api/core/user.ts
  function getUserInfoApi (line 8) | async function getUserInfoApi() {

FILE: apps/web-naive/src/api/request.ts
  function createRequestClient (line 23) | function createRequestClient(baseURL: string, options?: RequestClientOpt...

FILE: apps/web-naive/src/bootstrap.ts
  function bootstrap (line 19) | async function bootstrap(namespace: string) {

FILE: apps/web-naive/src/locales/index.ts
  function loadMessages (line 24) | async function loadMessages(lang: SupportedLanguagesType) {
  function setupI18n (line 29) | async function setupI18n(app: App, options: LocaleSetupOptions = {}) {

FILE: apps/web-naive/src/main.ts
  function initApplication (line 9) | async function initApplication() {

FILE: apps/web-naive/src/router/access.ts
  function generateAccess (line 16) | async function generateAccess(options: GenerateMenuAndRoutesOptions) {

FILE: apps/web-naive/src/router/guard.ts
  function setupCommonGuard (line 17) | function setupCommonGuard(router: Router) {
  function setupAccessGuard (line 47) | function setupAccessGuard(router: Router) {
  function createRouterGuard (line 125) | function createRouterGuard(router: Router) {

FILE: apps/web-naive/src/store/auth.ts
  function authLogin (line 28) | async function authLogin(
  function logout (line 81) | async function logout(redirect: boolean = true) {
  function fetchUserInfo (line 101) | async function fetchUserInfo() {
  function $reset (line 107) | function $reset() {

FILE: apps/web-tdesign/src/adapter/component/index.ts
  type ComponentType (line 101) | type ComponentType =
  function initComponentAdapter (line 129) | async function initComponentAdapter() {

FILE: apps/web-tdesign/src/adapter/form.ts
  function initSetupVbenForm (line 11) | async function initSetupVbenForm() {
  type VbenFormSchema (line 48) | type VbenFormSchema = FormSchema<ComponentType>;

FILE: apps/web-tdesign/src/adapter/vxe-table.ts
  method renderTableDefault (line 43) | renderTableDefault(renderOpts, params) {
  method renderTableDefault (line 52) | renderTableDefault(renderOpts) {

FILE: apps/web-tdesign/src/api/core/auth.ts
  type LoginParams (line 5) | interface LoginParams {
  type LoginResult (line 11) | interface LoginResult {
  type RefreshTokenResult (line 15) | interface RefreshTokenResult {
  function loginApi (line 24) | async function loginApi(data: AuthApi.LoginParams) {
  function refreshTokenApi (line 31) | async function refreshTokenApi() {
  function logoutApi (line 40) | async function logoutApi() {
  function getAccessCodesApi (line 49) | async function getAccessCodesApi() {

FILE: apps/web-tdesign/src/api/core/menu.ts
  function getAllMenusApi (line 8) | async function getAllMenusApi() {

FILE: apps/web-tdesign/src/api/core/user.ts
  function getUserInfoApi (line 8) | async function getUserInfoApi() {

FILE: apps/web-tdesign/src/api/request.ts
  function createRequestClient (line 23) | function createRequestClient(baseURL: string, options?: RequestClientOpt...

FILE: apps/web-tdesign/src/bootstrap.ts
  function bootstrap (line 22) | async function bootstrap(namespace: string) {

FILE: apps/web-tdesign/src/locales/index.ts
  function loadMessages (line 25) | async function loadMessages(lang: SupportedLanguagesType) {
  function loadThirdPartyMessage (line 37) | async function loadThirdPartyMessage(lang: SupportedLanguagesType) {
  function loadDayjsLocale (line 45) | async function loadDayjsLocale(lang: SupportedLanguagesType) {
  function setupI18n (line 68) | async function setupI18n(app: App, options: LocaleSetupOptions = {}) {

FILE: apps/web-tdesign/src/main.ts
  function initApplication (line 9) | async function initApplication() {

FILE: apps/web-tdesign/src/router/access.ts
  function generateAccess (line 16) | async function generateAccess(options: GenerateMenuAndRoutesOptions) {

FILE: apps/web-tdesign/src/router/guard.ts
  function setupCommonGuard (line 17) | function setupCommonGuard(router: Router) {
  function setupAccessGuard (line 47) | function setupAccessGuard(router: Router) {
  function createRouterGuard (line 126) | function createRouterGuard(router: Router) {

FILE: apps/web-tdesign/src/store/auth.ts
  function authLogin (line 28) | async function authLogin(
  function logout (line 79) | async function logout(redirect: boolean = true) {
  function fetchUserInfo (line 99) | async function fetchUserInfo() {
  function $reset (line 105) | function $reset() {

FILE: docs/.vitepress/config/plugins/demo-preview.ts
  function rawPathToToken (line 10) | function rawPathToToken(rawPath: string) {
  function generateContentHash (line 136) | function generateContentHash(input: string, length: number = 10): string {

FILE: docs/.vitepress/theme/index.ts
  method enhanceApp (line 18) | async enhanceApp(ctx: EnhanceAppContext) {

FILE: docs/.vitepress/theme/plugins/hm.ts
  constant SITE_ID (line 3) | const SITE_ID = '2e443a834727c065877c01d89921545e';
  type Window (line 6) | interface Window {
  function registerAnalytics (line 11) | function registerAnalytics() {
  function initHmPlugin (line 24) | function initHmPlugin() {

FILE: docs/src/_env/adapter/component.ts
  type ComponentType (line 51) | type ComponentType =
  function initComponentAdapter (line 76) | async function initComponentAdapter() {

FILE: docs/src/_env/adapter/form.ts
  type VbenFormSchema (line 47) | type VbenFormSchema = FormSchema<ComponentType>;

FILE: docs/src/_env/adapter/vxe-table.ts
  method renderTableDefault (line 43) | renderTableDefault(renderOpts, params) {
  method renderTableDefault (line 52) | renderTableDefault(renderOpts) {

FILE: docs/src/_env/node/adapter/form.ts
  type VbenFormSchema (line 3) | type VbenFormSchema = any;
  type VbenFormProps (line 4) | type VbenFormProps = any;

FILE: docs/src/demos/vben-vxe-table/mock-api.ts
  type PageFetchParams (line 4) | interface PageFetchParams {
  function sleep (line 11) | function sleep(time = 1000) {
  function getExampleTableApi (line 22) | async function getExampleTableApi(params: DemoTableApi.PageFetchParams) {

FILE: docs/src/demos/vben-vxe-table/table-data.ts
  type TableRowData (line 1) | interface TableRowData {
  constant MOCK_TABLE_DATA (line 12) | const MOCK_TABLE_DATA: TableRowData[] = (() => {
  constant MOCK_TREE_TABLE_DATA (line 27) | const MOCK_TREE_TABLE_DATA = [
  constant MOCK_API_DATA (line 174) | const MOCK_API_DATA = [

FILE: internal/lint-configs/eslint-config/src/configs/ignores.ts
  function ignores (line 3) | async function ignores(): Promise<Linter.Config[]> {

FILE: internal/lint-configs/eslint-config/src/configs/javascript.ts
  function javascript (line 67) | async function javascript(): Promise<Linter.Config[]> {

FILE: internal/lint-configs/eslint-config/src/configs/jsonc.ts
  function jsonc (line 5) | async function jsonc(): Promise<Linter.Config[]> {
  function sortPackageJson (line 50) | function sortPackageJson(): Linter.Config {
  function sortCspellJson (line 129) | function sortCspellJson(): Linter.Config {
  function sortTsconfig (line 144) | function sortTsconfig(): Linter.Config {

FILE: internal/lint-configs/eslint-config/src/configs/node.ts
  function node (line 5) | async function node(): Promise<Linter.Config[]> {

FILE: internal/lint-configs/eslint-config/src/configs/perfectionist.ts
  function perfectionist (line 5) | async function perfectionist(): Promise<Linter.Config[]> {

FILE: internal/lint-configs/eslint-config/src/configs/pnpm.ts
  function pnpm (line 5) | async function pnpm(): Promise<Linter.Config[]> {

FILE: internal/lint-configs/eslint-config/src/configs/typescript.ts
  function typescript (line 13) | async function typescript(): Promise<Linter.Config[]> {

FILE: internal/lint-configs/eslint-config/src/configs/unicorn.ts
  function unicorn (line 12) | async function unicorn(): Promise<Linter.Config[]> {

FILE: internal/lint-configs/eslint-config/src/configs/vue.ts
  function vue (line 5) | async function vue(): Promise<Linter.Config[]> {

FILE: internal/lint-configs/eslint-config/src/configs/yaml.ts
  function yaml (line 5) | async function yaml(): Promise<Linter.Config[]> {

FILE: internal/lint-configs/eslint-config/src/index.ts
  type FlatConfig (line 17) | type FlatConfig = Linter.Config;
  type FlatConfigPromise (line 19) | type FlatConfigPromise =
  function defineConfig (line 25) | async function defineConfig(config: FlatConfig[] = []) {

FILE: internal/lint-configs/eslint-config/src/util.ts
  type Awaitable (line 1) | type Awaitable<T> = Promise<T> | T;
  function interopDefault (line 3) | async function interopDefault<T>(

FILE: internal/lint-configs/oxfmt-config/src/index.ts
  type OxfmtConfig (line 3) | type OxfmtConfig = Parameters<typeof defineOxfmtConfig>[0];
  function defineConfig (line 31) | function defineConfig(config: OxfmtConfig = {}): OxfmtConfig {

FILE: internal/lint-configs/oxlint-config/src/configs/index.ts
  function mergeOxlintConfigs (line 19) | function mergeOxlintConfigs(...configs: OxlintConfig[]): OxlintConfig {

FILE: internal/lint-configs/oxlint-config/src/index.ts
  type VbenOxlintConfig (line 7) | type VbenOxlintConfig = Omit<OxlintConfig, 'extends'> & {
  function defineConfig (line 11) | function defineConfig(config: VbenOxlintConfig = {}) {

FILE: internal/node-utils/src/constants.ts
  type UNICODE (line 1) | enum UNICODE {

FILE: internal/node-utils/src/formatter.ts
  function formatFile (line 5) | async function formatFile(filepath: string) {

FILE: internal/node-utils/src/fs.ts
  function outputJSON (line 4) | async function outputJSON(
  function ensureFile (line 20) | async function ensureFile(filePath: string) {
  function readJSON (line 31) | async function readJSON(filePath: string) {

FILE: internal/node-utils/src/git.ts
  function getStagedFiles (line 10) | async function getStagedFiles(): Promise<string[]> {

FILE: internal/node-utils/src/hash.ts
  function generatorContentHash (line 8) | function generatorContentHash(content: string, hashLSize?: number) {

FILE: internal/node-utils/src/monorepo.ts
  function findMonorepoRoot (line 14) | function findMonorepoRoot(cwd: string = process.cwd()) {
  function getPackagesSync (line 34) | function getPackagesSync() {
  function getPackages (line 42) | async function getPackages() {
  function getPackage (line 51) | async function getPackage(pkgName: string) {

FILE: internal/node-utils/src/path.ts
  function toPosixPath (line 7) | function toPosixPath(pathname: string) {

FILE: internal/node-utils/src/spinner.ts
  type SpinnerOptions (line 5) | interface SpinnerOptions {
  function spinner (line 10) | async function spinner<T>(

FILE: internal/vite-config/src/config/application.ts
  function defineApplicationConfig (line 17) | function defineApplicationConfig(userConfigPromise?: DefineApplicationOp...
  function createCssOptions (line 101) | function createCssOptions(injectGlobalScss = true): CSSOptions {

FILE: internal/vite-config/src/config/common.ts
  function getCommonConfig (line 3) | async function getCommonConfig(): Promise<UserConfig> {

FILE: internal/vite-config/src/config/index.ts
  function defineConfig (line 12) | function defineConfig(

FILE: internal/vite-config/src/config/library.ts
  function defineLibraryConfig (line 12) | function defineLibraryConfig(userConfigPromise?: DefineLibraryOptions) {

FILE: internal/vite-config/src/plugins/archiver.ts
  method handler (line 17) | handler() {
  function zipFolder (line 46) | async function zipFolder(

FILE: internal/vite-config/src/plugins/extra-app-config.ts
  type PluginOptions (line 11) | interface PluginOptions {
  constant GLOBAL_CONFIG_FILE_NAME (line 16) | const GLOBAL_CONFIG_FILE_NAME = '_app.config.js';
  constant VBEN_ADMIN_PRO_APP_CONF (line 17) | const VBEN_ADMIN_PRO_APP_CONF = '_VBEN_ADMIN_PRO_APP_CONF_';
  function viteExtraAppConfigPlugin (line 24) | async function viteExtraAppConfigPlugin({
  function getConfigSource (line 73) | async function getConfigSource() {
  function ensureTrailingSlash (line 88) | function ensureTrailingSlash(path: string) {

FILE: internal/vite-config/src/plugins/importmap.ts
  constant DEFAULT_PROVIDER (line 11) | const DEFAULT_PROVIDER = 'jspm.io';
  type pluginOptions (line 13) | type pluginOptions = GeneratorOptions & {
  function getShimsUrl (line 25) | async function getShimsUrl(provide: string) {
  function viteImportMapPlugin (line 44) | async function viteImportMapPlugin(
  function injectShimsToHtml (line 194) | async function injectShimsToHtml(html: string, esModuleShimUrl: string) {

FILE: internal/vite-config/src/plugins/index.ts
  function loadConditionPlugins (line 36) | async function loadConditionPlugins(conditionPlugins: ConditionPlugin[]) {
  function loadCommonPlugins (line 50) | async function loadCommonPlugins(
  function loadApplicationPlugins (line 94) | async function loadApplicationPlugins(
  function loadLibraryPlugins (line 228) | async function loadLibraryPlugins(

FILE: internal/vite-config/src/plugins/inject-app-loading/index.ts
  function viteInjectAppLoadingPlugin (line 14) | async function viteInjectAppLoadingPlugin(
  function getLoadingRawByHtmlTemplate (line 54) | async function getLoadingRawByHtmlTemplate(loadingTemplate: string) {

FILE: internal/vite-config/src/plugins/inject-metadata.ts
  function resolvePackageVersion (line 12) | function resolvePackageVersion(
  function resolveMonorepoDependencies (line 29) | async function resolveMonorepoDependencies() {
  function viteMetadataPlugin (line 70) | async function viteMetadataPlugin(

FILE: internal/vite-config/src/plugins/license.ts
  function viteLicensePlugin (line 17) | async function viteLicensePlugin(

FILE: internal/vite-config/src/plugins/nitro-mock.ts
  method configureServer (line 18) | async configureServer(server) {
  function runNitroServer (line 48) | async function runNitroServer(rootDir: string, port: number, verbose: bo...

FILE: internal/vite-config/src/plugins/print.ts
  method configureServer (line 13) | configureServer(server) {

FILE: internal/vite-config/src/plugins/tailwind-reference.ts
  constant REFERENCE_LINE (line 3) | const REFERENCE_LINE = '@reference "@vben/tailwind-config/theme";\n';
  function viteTailwindReferencePlugin (line 14) | function viteTailwindReferencePlugin(): Plugin {

FILE: internal/vite-config/src/plugins/vxe-table.ts
  function viteVxeTableImportsPlugin (line 5) | async function viteVxeTableImportsPlugin(): Promise<PluginOption> {

FILE: internal/vite-config/src/typing.ts
  type IImportMap (line 28) | interface IImportMap {
  type PrintPluginOptions (line 41) | interface PrintPluginOptions {
  type NitroMockPluginOptions (line 60) | interface NitroMockPluginOptions {
  type ArchiverPluginOptions (line 84) | interface ArchiverPluginOptions {
  type ImportmapPluginOptions (line 101) | interface ImportmapPluginOptions {
  type ConditionPlugin (line 131) | interface ConditionPlugin {
  type CommonPluginOptions (line 148) | interface CommonPluginOptions {
  type ApplicationPluginOptions (line 186) | interface ApplicationPluginOptions extends CommonPluginOptions {
  type LibraryPluginOptions (line 288) | interface LibraryPluginOptions extends CommonPluginOptions {
  type ApplicationOptions (line 300) | type ApplicationOptions = ApplicationPluginOptions;
  type LibraryOptions (line 305) | type LibraryOptions = LibraryPluginOptions;
  type DefineApplicationOptions (line 311) | type DefineApplicationOptions = (config?: ConfigEnv) => Promise<{
  type DefineLibraryOptions (line 322) | type DefineLibraryOptions = (config?: ConfigEnv) => Promise<{
  type DefineConfig (line 333) | type DefineConfig = DefineApplicationOptions | DefineLibraryOptions;
  type VbenViteConfig (line 335) | type VbenViteConfig = Promise<UserConfig> | UserConfig | UserConfigFnPro...

FILE: internal/vite-config/src/utils/env.ts
  function getConfFiles (line 21) | function getConfFiles() {
  function loadEnv (line 37) | async function loadEnv<T = Record<string, string>>(
  function loadAndConvertEnv (line 66) | async function loadAndConvertEnv(

FILE: packages/@core/base/icons/src/create-icon.ts
  function createIconifyIcon (line 5) | function createIconifyIcon(icon: string) {

FILE: packages/@core/base/shared/src/cache/storage-manager.ts
  type StorageType (line 1) | type StorageType = 'localStorage' | 'sessionStorage';
  type StorageManagerOptions (line 3) | interface StorageManagerOptions {
  type StorageItem (line 8) | interface StorageItem<T> {
  class StorageManager (line 13) | class StorageManager {
    method constructor (line 17) | constructor({
    method clear (line 31) | clear(): void {
    method clearExpiredItems (line 45) | clearExpiredItems(): void {
    method getItem (line 61) | getItem<T>(key: string, defaultValue: null | T = null): null | T {
    method removeItem (line 86) | removeItem(key: string): void {
    method setItem (line 97) | setItem<T>(key: string, value: T, ttl?: number): void {
    method getFullKey (line 113) | private getFullKey(key: string): string {

FILE: packages/@core/base/shared/src/cache/types.ts
  type StorageType (line 1) | type StorageType = 'localStorage' | 'sessionStorage';
  type StorageValue (line 3) | interface StorageValue<T> {
  type IStorageCache (line 8) | interface IStorageCache {

FILE: packages/@core/base/shared/src/color/color.ts
  function isDarkColor (line 3) | function isDarkColor(color: string) {
  function isLightColor (line 7) | function isLightColor(color: string) {

FILE: packages/@core/base/shared/src/color/convert.ts
  function convertToHsl (line 11) | function convertToHsl(color: string): string {
  function convertToHslCssVar (line 26) | function convertToHslCssVar(color: string): string {
  function convertToRgb (line 40) | function convertToRgb(str: string): string {
  function isValidColor (line 49) | function isValidColor(color?: string) {

FILE: packages/@core/base/shared/src/color/generator.ts
  type ColorItem (line 5) | interface ColorItem {
  function generatorColorVariables (line 11) | function generatorColorVariables(colorItems: ColorItem[]) {

FILE: packages/@core/base/shared/src/constants/globals.ts
  constant CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT (line 2) | const CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT = `--vben-content-height`;
  constant CSS_VARIABLE_LAYOUT_CONTENT_WIDTH (line 4) | const CSS_VARIABLE_LAYOUT_CONTENT_WIDTH = `--vben-content-width`;
  constant CSS_VARIABLE_LAYOUT_HEADER_HEIGHT (line 6) | const CSS_VARIABLE_LAYOUT_HEADER_HEIGHT = `--vben-header-height`;
  constant CSS_VARIABLE_LAYOUT_FOOTER_HEIGHT (line 8) | const CSS_VARIABLE_LAYOUT_FOOTER_HEIGHT = `--vben-footer-height`;
  constant ELEMENT_ID_MAIN_CONTENT (line 11) | const ELEMENT_ID_MAIN_CONTENT = `__vben_main_content`;
  constant DEFAULT_NAMESPACE (line 16) | const DEFAULT_NAMESPACE = 'vben';

FILE: packages/@core/base/shared/src/constants/vben.ts
  constant VBEN_GITHUB_URL (line 4) | const VBEN_GITHUB_URL = 'https://github.com/vbenjs/vue-vben-admin';
  constant VBEN_DOC_URL (line 9) | const VBEN_DOC_URL = 'https://doc.vben.pro';
  constant VBEN_LOGO_URL (line 14) | const VBEN_LOGO_URL =
  constant VBEN_PREVIEW_URL (line 20) | const VBEN_PREVIEW_URL = 'https://www.vben.pro';
  constant VBEN_ANTDV_NEXT_PREVIEW_URL (line 22) | const VBEN_ANTDV_NEXT_PREVIEW_URL = 'https://antdv-next.vben.pro';
  constant VBEN_ELE_PREVIEW_URL (line 24) | const VBEN_ELE_PREVIEW_URL = 'https://ele.vben.pro';
  constant VBEN_NAIVE_PREVIEW_URL (line 26) | const VBEN_NAIVE_PREVIEW_URL = 'https://naive.vben.pro';
  constant VBEN_ANT_PREVIEW_URL (line 28) | const VBEN_ANT_PREVIEW_URL = 'https://ant.vben.pro';
  constant VBEN_TD_PREVIEW_URL (line 30) | const VBEN_TD_PREVIEW_URL = 'https://tdesign.vben.pro';

FILE: packages/@core/base/shared/src/global-state.ts
  type ComponentsState (line 6) | interface ComponentsState {
  type MessageState (line 10) | interface MessageState {
  type IGlobalSharedState (line 14) | interface IGlobalSharedState {
  class GlobalShareState (line 19) | class GlobalShareState {
    method defineMessage (line 26) | public defineMessage({ copyPreferencesSuccess }: MessageState) {
    method getComponents (line 32) | public getComponents(): ComponentsState {
    method getMessage (line 36) | public getMessage(): MessageState {
    method setComponents (line 40) | public setComponents(value: ComponentsState) {

FILE: packages/@core/base/shared/src/utils/__tests__/tree.test.ts
  type Node (line 6) | interface Node {
  type NodeValue (line 11) | type NodeValue = string;

FILE: packages/@core/base/shared/src/utils/__tests__/util.test.ts
  class TestClass (line 5) | class TestClass {
    method constructor (line 8) | constructor(value: string) {
    method getValue (line 13) | getValue() {
    method setValue (line 17) | setValue(newValue: string) {
  class TestWithGetterSetter (line 58) | class TestWithGetterSetter {
    method value (line 59) | get value() {
    method value (line 63) | set value(newValue: string) {
    method constructor (line 69) | constructor() {
  type UserProfile (line 83) | interface UserProfile {
  type UserSettings (line 88) | interface UserSettings {
  type Data (line 92) | interface Data {

FILE: packages/@core/base/shared/src/utils/cn.ts
  function cn (line 6) | function cn(...inputs: ClassValue[]) {

FILE: packages/@core/base/shared/src/utils/date.ts
  type FormatDate (line 8) | type FormatDate = Date | dayjs.Dayjs | number | string;
  type Format (line 10) | type Format =
  function formatDate (line 22) | function formatDate(time?: FormatDate, format: Format = 'YYYY-MM-DD') {
  function formatDateTime (line 35) | function formatDateTime(time?: FormatDate) {
  function isDate (line 39) | function isDate(value: any): value is Date {
  function isDayjsObject (line 43) | function isDayjsObject(value: any): value is dayjs.Dayjs {

FILE: packages/@core/base/shared/src/utils/diff.ts
  function arraysEqual (line 5) | function arraysEqual<T>(a: T[], b: T[]): boolean {
  type DiffResult (line 58) | type DiffResult<T> = Partial<{
  function diff (line 62) | function diff<T extends Record<string, any>>(obj1: T, obj2: T): DiffResu...

FILE: packages/@core/base/shared/src/utils/dom.ts
  type VisibleDomRect (line 1) | interface VisibleDomRect {
  function getElementVisibleRect (line 14) | function getElementVisibleRect(
  function getScrollbarWidth (line 66) | function getScrollbarWidth() {
  function needsScrollbar (line 85) | function needsScrollbar() {
  function triggerWindowResize (line 101) | function triggerWindowResize(): void {

FILE: packages/@core/base/shared/src/utils/download.ts
  type DownloadOptions (line 3) | interface DownloadOptions<T = string> {
  constant DEFAULT_FILENAME (line 9) | const DEFAULT_FILENAME = 'downloaded_file';
  function downloadFileFromUrl (line 15) | async function downloadFileFromUrl({
  function downloadFileFromBase64 (line 46) | function downloadFileFromBase64({ fileName, source }: DownloadOptions) {
  function downloadFileFromImageUrl (line 58) | async function downloadFileFromImageUrl({
  function downloadFileFromBlob (line 69) | function downloadFileFromBlob({
  function downloadFileFromBlobPart (line 84) | function downloadFileFromBlobPart({
  function urlToBase64 (line 103) | function urlToBase64(url: string, mineType?: string): Promise<string> {
  function triggerDownload (line 130) | function triggerDownload(
  function resolveFileName (line 155) | function resolveFileName(url: string, fileName?: string): string {

FILE: packages/@core/base/shared/src/utils/inference.ts
  function isUndefined (line 9) | function isUndefined(value?: unknown): value is undefined {
  function isBoolean (line 18) | function isBoolean(value: unknown): value is boolean {
  function isEmpty (line 36) | function isEmpty<T = unknown>(value?: T): value is T {
  function isHttpUrl (line 62) | function isHttpUrl(url?: string): boolean {
  function isWindow (line 77) | function isWindow(value: any): value is Window {
  function isMacOs (line 91) | function isMacOs(): boolean {
  function isWindowsOs (line 104) | function isWindowsOs(): boolean {
  function isNumber (line 113) | function isNumber(value: any): value is number {
  function getFirstNonNullOrUndefined (line 140) | function getFirstNonNullOrUndefined<T>(

FILE: packages/@core/base/shared/src/utils/letter.ts
  function capitalizeFirstLetter (line 5) | function capitalizeFirstLetter(string: string): string {
  function toLowerCaseFirstLetter (line 15) | function toLowerCaseFirstLetter(str: string): string {
  function toCamelCase (line 25) | function toCamelCase(key: string, parentKey: string): string {
  function kebabToCamelCase (line 32) | function kebabToCamelCase(str: string): string {

FILE: packages/@core/base/shared/src/utils/nprogress.ts
  function loadNprogress (line 13) | async function loadNprogress() {
  function startProgress (line 29) | async function startProgress() {
  function stopProgress (line 38) | async function stopProgress() {

FILE: packages/@core/base/shared/src/utils/resources.ts
  function loadScript (line 5) | function loadScript(src: string) {

FILE: packages/@core/base/shared/src/utils/stack.ts
  class Stack (line 4) | class Stack<T> {
    method size (line 8) | get size() {
    method constructor (line 25) | constructor(dedup = true, maxSize?: number) {
    method clear (line 33) | clear() {
    method peek (line 41) | peek(): T | undefined {
    method pop (line 49) | pop(): T | undefined {
    method push (line 57) | push(...items: T[]) {
    method remove (line 76) | remove(...itemList: T[]) {
    method retain (line 83) | retain(itemList: T[]) {
    method toArray (line 91) | toArray(): T[] {

FILE: packages/@core/base/shared/src/utils/state-handler.ts
  class StateHandler (line 1) | class StateHandler {
    method isConditionTrue (line 6) | isConditionTrue(): boolean {
    method reset (line 10) | reset() {
    method setConditionFalse (line 16) | setConditionFalse() {
    method setConditionTrue (line 25) | setConditionTrue() {
    method waitForCondition (line 34) | waitForCondition(): Promise<void> {
    method clearPromises (line 46) | private clearPromises() {

FILE: packages/@core/base/shared/src/utils/to.ts
  function to (line 6) | async function to<T, U = Error>(

FILE: packages/@core/base/shared/src/utils/tree.ts
  type TreeConfigOptions (line 1) | interface TreeConfigOptions {
  function traverseTreeValues (line 13) | function traverseTreeValues<T, V>(
  function filterTree (line 50) | function filterTree<T extends Record<string, any>>(
  function mapTree (line 80) | function mapTree<T, V extends Record<string, any>>(
  function sortTree (line 104) | function sortTree<T extends Record<string, any>>(

FILE: packages/@core/base/shared/src/utils/unique.ts
  function uniqueByField (line 7) | function uniqueByField<T>(arr: T[], key: keyof T): T[] {

FILE: packages/@core/base/shared/src/utils/update-css-variables.ts
  function updateCSSVariables (line 5) | function updateCSSVariables(

FILE: packages/@core/base/shared/src/utils/util.ts
  function bindMethods (line 1) | function bindMethods<T extends object>(instance: T): void {
  function getNestedValue (line 27) | function getNestedValue<T>(obj: T, path: string): any {

FILE: packages/@core/base/shared/src/utils/window.ts
  type OpenWindowOptions (line 1) | interface OpenWindowOptions {
  function openWindow (line 13) | function openWindow(url: string, options: OpenWindowOptions = {}): void {
  function openRouteInNewWindow (line 30) | function openRouteInNewWindow(path: string) {

FILE: packages/@core/base/typings/src/app.d.ts
  type LayoutType (line 1) | type LayoutType =
  type ThemeModeType (line 10) | type ThemeModeType = 'auto' | 'dark' | 'light';
  type PreferencesButtonPositionType (line 18) | type PreferencesButtonPositionType = 'auto' | 'fixed' | 'header';
  type BuiltinThemeType (line 20) | type BuiltinThemeType =
  type ContentCompactType (line 40) | type ContentCompactType = 'compact' | 'wide';
  type LayoutHeaderModeType (line 42) | type LayoutHeaderModeType = 'auto' | 'auto-scroll' | 'fixed' | 'static';
  type LayoutHeaderMenuAlignType (line 43) | type LayoutHeaderMenuAlignType = 'center' | 'end' | 'start';
  type LoginExpiredModeType (line 50) | type LoginExpiredModeType = 'modal' | 'page';
  type BreadcrumbStyleType (line 57) | type BreadcrumbStyleType = 'background' | 'normal';
  type AccessModeType (line 65) | type AccessModeType = 'backend' | 'frontend' | 'mixed';
  type NavigationStyleType (line 72) | type NavigationStyleType = 'plain' | 'rounded';
  type TabsStyleType (line 81) | type TabsStyleType = 'brisk' | 'card' | 'chrome' | 'plain';
  type PageTransitionType (line 86) | type PageTransitionType = 'fade' | 'fade-down' | 'fade-slide' | 'fade-up';
  type AuthPageLayoutType (line 94) | type AuthPageLayoutType = 'panel-center' | 'panel-left' | 'panel-right';
  type TimezoneOption (line 99) | interface TimezoneOption {

FILE: packages/@core/base/typings/src/basic.d.ts
  type BasicOption (line 1) | interface BasicOption {
  type SelectOption (line 6) | type SelectOption = BasicOption;
  type TabOption (line 8) | type TabOption = BasicOption;
  type BasicUserInfo (line 10) | interface BasicUserInfo {
  type ClassType (line 33) | type ClassType =

FILE: packages/@core/base/typings/src/helper.d.ts
  type Increment (line 6) | type Increment<A extends unknown[]> = [...A, unknown];
  type DeepPartial (line 10) | type DeepPartial<
  type DeepReadonly (line 25) | type DeepReadonly<
  type AnyPromiseFunction (line 41) | type AnyPromiseFunction<T extends any[] = any[], R = void> = (
  type AnyNormalFunction (line 48) | type AnyNormalFunction<T extends any[] = any[], R = void> = (...arg: T) ...
  type AnyFunction (line 53) | type AnyFunction<T extends any[] = any[], R = void> =
  type Nullable (line 60) | type Nullable<T> = null | T;
  type NonNullable (line 65) | type NonNullable<T> = T extends null | undefined ? never : T;
  type Recordable (line 70) | type Recordable<T> = Record<string, T>;
  type ReadonlyRecordable (line 75) | interface ReadonlyRecordable<T = any> {
  type TimeoutHandle (line 82) | type TimeoutHandle = ReturnType<typeof setTimeout>;
  type IntervalHandle (line 87) | type IntervalHandle = ReturnType<typeof setInterval>;
  type MaybeReadonlyRef (line 93) | type MaybeReadonlyRef<T> = (() => T) | ComputedRef<T>;
  type MaybeComputedRef (line 99) | type MaybeComputedRef<T> = MaybeReadonlyRef<T> | MaybeRef<T>;
  type Merge (line 101) | type Merge<O extends object, T extends object> = {
  type MergeAll (line 121) | type MergeAll<
  type EmitType (line 128) | type EmitType = (name: Name, ...args: any[]) => void;
  type MaybePromise (line 130) | type MaybePromise<T> = Promise<T> | T;

FILE: packages/@core/base/typings/src/menu-record.ts
  type ExRouteRecordRaw (line 9) | type ExRouteRecordRaw = RouteRecordRaw & {
  type MenuRecordBadgeRaw (line 15) | interface MenuRecordBadgeRaw {
  type MenuRecordRaw (line 33) | interface MenuRecordRaw extends MenuRecordBadgeRaw {

FILE: packages/@core/base/typings/src/tabs.ts
  type TabDefinition (line 3) | interface TabDefinition extends RouteLocationNormalized {

FILE: packages/@core/base/typings/src/vue-router.d.ts
  type RouteMeta (line 4) | interface RouteMeta {
  type RouteRecordStringComponent (line 131) | type RouteRecordStringComponent<T = string> = Omit<
  type ComponentRecordType (line 139) | type ComponentRecordType = Record<string, () => Promise<Component>>;
  type GenerateMenuAndRoutesOptions (line 141) | interface GenerateMenuAndRoutesOptions {

FILE: packages/@core/base/typings/vue-router.d.ts
  type RouteMeta (line 7) | interface RouteMeta extends IRouteMeta {}

FILE: packages/@core/composables/src/use-is-mobile.ts
  function useIsMobile (line 3) | function useIsMobile() {

FILE: packages/@core/composables/src/use-layout-style.ts
  function useLayoutContentStyle (line 20) | function useLayoutContentStyle() {
  function useLayoutHeaderStyle (line 63) | function useLayoutHeaderStyle() {
  function useLayoutFooterStyle (line 76) | function useLayoutFooterStyle() {

FILE: packages/@core/composables/src/use-namespace.ts
  type UseNamespaceReturn (line 103) | type UseNamespaceReturn = ReturnType<typeof useNamespace>;

FILE: packages/@core/composables/src/use-priority-value.ts
  function usePriorityValue (line 16) | function usePriorityValue<
  function usePriorityValues (line 55) | function usePriorityValues<
  function useForwardPriorityValues (line 73) | function useForwardPriorityValues<

FILE: packages/@core/composables/src/use-scroll-lock.ts
  constant SCROLL_FIXED_CLASS (line 9) | const SCROLL_FIXED_CLASS = `_scroll__fixed_`;
  function useScrollLock (line 11) | function useScrollLock() {

FILE: packages/@core/composables/src/use-simple-locale/messages.ts
  type Locale (line 1) | type Locale = 'en-US' | 'zh-CN';

FILE: packages/@core/composables/src/use-sortable.ts
  function useSortable (line 4) | function useSortable<T extends HTMLElement>(

FILE: packages/@core/preferences/src/constants.ts
  type BuiltinThemePreset (line 3) | interface BuiltinThemePreset {
  constant BUILT_IN_THEME_PRESETS (line 10) | const BUILT_IN_THEME_PRESETS: BuiltinThemePreset[] = [
  constant DEFAULT_TIME_ZONE_OPTIONS (line 84) | const DEFAULT_TIME_ZONE_OPTIONS: TimezoneOption[] = [
  constant COLOR_PRESETS (line 112) | const COLOR_PRESETS = [...BUILT_IN_THEME_PRESETS].slice(0, 7);

FILE: packages/@core/preferences/src/preferences.ts
  constant STORAGE_KEYS (line 19) | const STORAGE_KEYS = {
  class PreferenceManager (line 25) | class PreferenceManager {
    method constructor (line 32) | constructor() {
    method handleUpdates (line 136) | private handleUpdates(updates: DeepPartial<Preferences>) {
    method initPlatform (line 157) | private initPlatform() {
    method loadFromCache (line 165) | private loadFromCache(): null | Preferences {
    method saveToCache (line 173) | private saveToCache(preference: Preferences) {
    method setupWatcher (line 182) | private setupWatcher() {
    method updateColorMode (line 223) | private updateColorMode(preference: Preferences) {

FILE: packages/@core/preferences/src/types.ts
  type SupportedLanguagesType (line 19) | type SupportedLanguagesType = 'en-US' | 'zh-CN';
  type AppPreferences (line 21) | interface AppPreferences {
  type BreadcrumbPreferences (line 92) | interface BreadcrumbPreferences {
  type CopyrightPreferences (line 105) | interface CopyrightPreferences {
  type FooterPreferences (line 122) | interface FooterPreferences {
  type HeaderPreferences (line 131) | interface HeaderPreferences {
  type LogoPreferences (line 144) | interface LogoPreferences {
  type NavigationPreferences (line 155) | interface NavigationPreferences {
  type SidebarPreferences (line 164) | interface SidebarPreferences {
  type ShortcutKeyPreferences (line 195) | interface ShortcutKeyPreferences {
  type TabbarPreferences (line 208) | interface TabbarPreferences {
  type ThemePreferences (line 239) | interface ThemePreferences {
  type TransitionPreferences (line 264) | interface TransitionPreferences {
  type WidgetPreferences (line 275) | interface WidgetPreferences {
  type Preferences (line 296) | interface Preferences {
  type PreferencesKeys (line 325) | type PreferencesKeys = keyof Preferences;
  type InitialOptions (line 327) | interface InitialOptions {

FILE: packages/@core/preferences/src/update-css-variables.ts
  function updateCSSVariables (line 12) | function updateCSSVariables(preferences: Preferences) {
  function updateMainColorVariables (line 88) | function updateMainColorVariables(preference: Preferences) {
  function isDarkTheme (line 121) | function isDarkTheme(theme: string) {

FILE: packages/@core/preferences/src/use-preferences.ts
  function usePreferences (line 8) | function usePreferences() {

FILE: packages/@core/ui-kit/form-ui/src/config.ts
  constant DEFAULT_MODEL_PROP_NAME (line 23) | const DEFAULT_MODEL_PROP_NAME = 'modelValue';
  constant DEFAULT_FORM_COMMON_CONFIG (line 25) | const DEFAULT_FORM_COMMON_CONFIG: FormCommonConfig = {};
  constant COMPONENT_MAP (line 27) | const COMPONENT_MAP: Record<BaseFormComponentType, Component> = {
  constant COMPONENT_BIND_EVENT_MAP (line 37) | const COMPONENT_BIND_EVENT_MAP: Partial<
  function setupVbenForm (line 43) | function setupVbenForm<

FILE: packages/@core/ui-kit/form-ui/src/form-api.ts
  function getDefaultState (line 29) | function getDefaultState(): VbenFormProps {
  class FormApi (line 53) | class FormApi {
    method constructor (line 73) | constructor(options: VbenFormProps = {}) {
    method getFieldComponentRef (line 99) | getFieldComponentRef<T = ComponentPublicInstance>(
    method getFocusedField (line 127) | getFocusedField() {
    method getLatestSubmissionValues (line 151) | getLatestSubmissionValues() {
    method getState (line 155) | getState() {
    method getValues (line 159) | async getValues<T = Recordable<any>>() {
    method isFieldValid (line 164) | async isFieldValid(fieldName: string) {
    method merge (line 169) | merge(formApi: FormApi) {
    method mount (line 209) | mount(formActions: FormActions, componentRefMap: Map<string, unknown>) {
    method removeSchemaByFields (line 225) | async removeSchemaByFields(fields: string[]) {
    method resetForm (line 239) | async resetForm(
    method resetValidate (line 247) | async resetValidate() {
    method scrollToFirstError (line 259) | scrollToFirstError(errors: Record<string, any> | string) {
    method setFieldValue (line 290) | async setFieldValue(field: string, value: any, shouldValidate?: boolea...
    method setLatestSubmissionValues (line 295) | setLatestSubmissionValues(values: null | Recordable<any>) {
    method setState (line 299) | setState(
    method setValues (line 319) | async setValues(
    method submitForm (line 352) | async submitForm(e?: Event) {
    method unmount (line 363) | unmount() {
    method updateSchema (line 371) | updateSchema(schema: Partial<FormSchema>[]) {
    method validate (line 405) | async validate(opts?: Partial<ValidationOptions>) {
    method validateAndSubmitForm (line 420) | async validateAndSubmitForm() {
    method validateField (line 432) | async validateField(fieldName: string, opts?: Partial<ValidationOption...
    method getForm (line 446) | private async getForm() {
    method updateState (line 578) | private updateState() {

FILE: packages/@core/ui-kit/form-ui/src/form-render/dependencies.ts
  function resolveValueByFieldName (line 20) | function resolveValueByFieldName(
  function useDependencies (line 33) | function useDependencies(

FILE: packages/@core/ui-kit/form-ui/src/form-render/expandable.ts
  function useExpandable (line 14) | function useExpandable(props: FormRenderProps) {

FILE: packages/@core/ui-kit/form-ui/src/form-render/helper.ts
  function getBaseRules (line 16) | function getBaseRules<
  function getDefaultValueInZodStack (line 32) | function getDefaultValueInZodStack(schema: ZodTypeAny): any {
  function isEventObjectLike (line 55) | function isEventObjectLike(obj: any) {

FILE: packages/@core/ui-kit/form-ui/src/types.ts
  type FormLayout (line 11) | type FormLayout = 'horizontal' | 'inline' | 'vertical';
  type BaseFormComponentType (line 13) | type BaseFormComponentType =
  type Breakpoints (line 23) | type Breakpoints = '2xl:' | '3xl:' | '' | 'lg:' | 'md:' | 'sm:' | 'xl:';
  type GridCols (line 25) | type GridCols = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13;
  type WrapperClassType (line 27) | type WrapperClassType =
  type FormItemClassType (line 31) | type FormItemClassType =
  type FormFieldOptions (line 38) | type FormFieldOptions = Partial<
  type FormShape (line 47) | interface FormShape {
  type MaybeComponentPropKey (line 57) | type MaybeComponentPropKey =
  type MaybeComponentProps (line 64) | type MaybeComponentProps = { [K in MaybeComponentPropKey]?: any };
  type FormActions (line 66) | type FormActions = FormContext<GenericObject>;
  type CustomRenderType (line 68) | type CustomRenderType = (() => Component | string) | string;
  type FormSchemaRuleType (line 70) | type FormSchemaRuleType =
  type FormItemDependenciesCondition (line 77) | type FormItemDependenciesCondition<T = boolean | PromiseLike<boolean>> = (
  type FormItemDependenciesConditionWithRules (line 82) | type FormItemDependenciesConditionWithRules = (
  type FormItemDependenciesConditionWithProps (line 87) | type FormItemDependenciesConditionWithProps = (
  type FormItemDependencies (line 92) | interface FormItemDependencies {
  type ComponentProps (line 132) | type ComponentProps =
  type FormCommonConfig (line 139) | interface FormCommonConfig {
  type RenderComponentContentType (line 211) | type RenderComponentContentType = (
  type HandleSubmitFn (line 216) | type HandleSubmitFn = (
  type HandleResetFn (line 220) | type HandleResetFn = (
  type FieldMappingTime (line 224) | type FieldMappingTime = [
  type ArrayToStringFields (line 235) | type ArrayToStringFields = Array<
  type FormSchema (line 241) | interface FormSchema<
  type FormFieldProps (line 270) | interface FormFieldProps extends FormSchema {
  type FormRenderProps (line 274) | interface FormRenderProps<
  type ActionButtonOptions (line 344) | interface ActionButtonOptions extends VbenButtonProps {
  type VbenFormProps (line 350) | interface VbenFormProps<
  type ExtendedFormApi (line 436) | type ExtendedFormApi = FormApi & {
  type VbenFormAdapterOptions (line 442) | interface VbenFormAdapterOptions<

FILE: packages/@core/ui-kit/form-ui/src/use-form-context.ts
  type ExtendFormProps (line 16) | type ExtendFormProps = VbenFormProps & { formApi?: ExtendedFormApi };
  function useFormInitial (line 26) | function useFormInitial(

FILE: packages/@core/ui-kit/form-ui/src/use-vben-form.ts
  function useVbenForm (line 14) | function useVbenForm<

FILE: packages/@core/ui-kit/layout-ui/src/hooks/use-layout.ts
  function useLayout (line 7) | function useLayout(props: VbenLayoutProps) {

FILE: packages/@core/ui-kit/layout-ui/src/hooks/use-sidebar-drag.ts
  type DragOptions (line 3) | interface DragOptions {
  type DragElements (line 8) | interface DragElements {
  type DragCallback (line 13) | type DragCallback = (newWidth: number) => void;
  function useSidebarDrag (line 15) | function useSidebarDrag() {

FILE: packages/@core/ui-kit/layout-ui/src/vben-layout.ts
  type VbenLayoutProps (line 8) | interface VbenLayoutProps {

FILE: packages/@core/ui-kit/menu-ui/src/components/normal-menu/normal-menu.ts
  type NormalMenuProps (line 3) | interface NormalMenuProps {

FILE: packages/@core/ui-kit/menu-ui/src/hooks/use-menu-context.ts
  function createMenuContext (line 12) | function createMenuContext(injectMenuData: MenuProvider) {
  function createSubMenuContext (line 19) | function createSubMenuContext(injectSubMenuData: SubMenuProvider) {
  function useMenuContext (line 28) | function useMenuContext() {
  function useSubMenuContext (line 40) | function useSubMenuContext() {

FILE: packages/@core/ui-kit/menu-ui/src/hooks/use-menu-scroll.ts
  type UseMenuScrollOptions (line 7) | interface UseMenuScrollOptions {
  function useMenuScroll (line 12) | function useMenuScroll(

FILE: packages/@core/ui-kit/menu-ui/src/hooks/use-menu.ts
  function useMenu (line 7) | function useMenu() {
  function useMenuStyle (line 39) | function useMenuStyle(menu?: SubMenuProvider) {

FILE: packages/@core/ui-kit/menu-ui/src/types.ts
  type MenuProps (line 9) | interface MenuProps {
  type SubMenuProps (line 62) | interface SubMenuProps extends MenuRecordBadgeRaw {
  type MenuItemProps (line 81) | interface MenuItemProps extends MenuRecordBadgeRaw {
  type MenuItemRegistered (line 104) | interface MenuItemRegistered {
  type MenuItemClicked (line 111) | interface MenuItemClicked {
  type MenuProvider (line 116) | interface MenuProvider {
  type SubMenuProvider (line 138) | interface SubMenuProvider {

FILE: packages/@core/ui-kit/menu-ui/src/utils/index.ts
  type VNodeChildAtom (line 10) | type VNodeChildAtom = Exclude<VNodeChild, Array<any>>;
  type RawSlots (line 11) | type RawSlots = Exclude<VNodeNormalizedChildren, Array<any> | null | str...
  type FlattenVNodes (line 13) | type FlattenVNodes = Array<RawSlots | VNodeChildAtom>;
  function findComponentUpward (line 20) | function findComponentUpward(

FILE: packages/@core/ui-kit/popup-ui/src/alert/AlertBuilder.ts
  function vbenAlert (line 30) | function vbenAlert(
  function vbenConfirm (line 109) | function vbenConfirm(
  function vbenPrompt (line 132) | async function vbenPrompt<T = any>(
  function clearAllAlerts (line 237) | function clearAllAlerts() {

FILE: packages/@core/ui-kit/popup-ui/src/alert/alert.ts
  type IconType (line 7) | type IconType = 'error' | 'info' | 'question' | 'success' | 'warning';
  type BeforeCloseScope (line 9) | type BeforeCloseScope = {
  type AlertProps (line 13) | type AlertProps = {
  type PromptProps (line 54) | type PromptProps<T = any> = {
  type AlertContext (line 79) | type AlertContext = {
  function useAlertContext (line 93) | function useAlertContext() {

FILE: packages/@core/ui-kit/popup-ui/src/drawer/__tests__/drawer-api.test.ts
  method state (line 12) | get state() {
  method constructor (line 18) | constructor(initialState: DrawerState) {
  method setState (line 22) | setState(fn: (prev: DrawerState) => DrawerState) {
  method subscribe (line 27) | subscribe(fn: (state: DrawerState) => void) {

FILE: packages/@core/ui-kit/popup-ui/src/drawer/drawer-api.ts
  class DrawerApi (line 6) | class DrawerApi {
    method constructor (line 26) | constructor(options: DrawerApiOptions = {}) {
    method close (line 87) | async close() {
    method getData (line 100) | getData<T extends object = Record<string, any>>() {
    method lock (line 109) | lock(isLocked: boolean = true) {
    method onCancel (line 116) | onCancel() {
    method onClosed (line 127) | onClosed() {
    method onConfirm (line 136) | onConfirm() {
    method onOpened (line 143) | onOpened() {
    method open (line 149) | open() {
    method setData (line 153) | setData<T>(payload: T) {
    method setState (line 158) | setState(
    method unlock (line 175) | unlock() {

FILE: packages/@core/ui-kit/popup-ui/src/drawer/drawer.ts
  type DrawerPlacement (line 7) | type DrawerPlacement = 'bottom' | 'left' | 'right' | 'top';
  type CloseIconPlacement (line 9) | type CloseIconPlacement = 'left' | 'right';
  type DrawerProps (line 11) | interface DrawerProps {
  type DrawerState (line 130) | interface DrawerState extends DrawerProps {
  type ExtendedDrawerApi (line 139) | type ExtendedDrawerApi = DrawerApi & {
  type DrawerApiOptions (line 145) | interface DrawerApiOptions extends DrawerState {

FILE: packages/@core/ui-kit/popup-ui/src/drawer/use-drawer.ts
  constant USER_DRAWER_INJECT_KEY (line 22) | const USER_DRAWER_INJECT_KEY = Symbol('VBEN_DRAWER_INJECT');
  constant DEFAULT_DRAWER_PROPS (line 24) | const DEFAULT_DRAWER_PROPS: Partial<DrawerProps> = {};
  function setDefaultDrawerProps (line 26) | function setDefaultDrawerProps(props: Partial<DrawerProps>) {
  function useVbenDrawer (line 30) | function useVbenDrawer<
  function checkProps (line 120) | async function checkProps(api: ExtendedDrawerApi, attrs: Record<string, ...

FILE: packages/@core/ui-kit/popup-ui/src/modal/__tests__/modal-api.test.ts
  method state (line 11) | get state() {
  method constructor (line 17) | constructor(initialState: ModalState) {
  method setState (line 21) | setState(fn: (prev: ModalState) => ModalState) {
  method subscribe (line 26) | subscribe(fn: (state: ModalState) => void) {

FILE: packages/@core/ui-kit/popup-ui/src/modal/modal-api.ts
  class ModalApi (line 6) | class ModalApi {
    method constructor (line 26) | constructor(options: ModalApiOptions = {}) {
    method close (line 96) | async close() {
    method getData (line 108) | getData<T extends object = Record<string, any>>() {
    method lock (line 117) | lock(isLocked = true) {
    method onCancel (line 124) | onCancel() {
    method onClosed (line 135) | onClosed() {
    method onConfirm (line 144) | onConfirm() {
    method onOpened (line 151) | onOpened() {
    method open (line 157) | open() {
    method setData (line 165) | setData<T>(payload: T) {
    method setState (line 170) | setState(
    method unlock (line 187) | unlock() {

FILE: packages/@core/ui-kit/popup-ui/src/modal/modal.ts
  type ModalProps (line 7) | interface ModalProps {
  type ModalState (line 145) | interface ModalState extends ModalProps {
  type ExtendedModalApi (line 154) | type ExtendedModalApi = ModalApi & {
  type ModalApiOptions (line 160) | interface ModalApiOptions extends ModalState {

FILE: packages/@core/ui-kit/popup-ui/src/modal/use-modal-draggable.ts
  function useModalDraggable (line 12) | function useModalDraggable(

FILE: packages/@core/ui-kit/popup-ui/src/modal/use-modal.ts
  constant USER_MODAL_INJECT_KEY (line 18) | const USER_MODAL_INJECT_KEY = Symbol('VBEN_MODAL_INJECT');
  constant DEFAULT_MODAL_PROPS (line 20) | const DEFAULT_MODAL_PROPS: Partial<ModalProps> = {};
  function setDefaultModalProps (line 22) | function setDefaultModalProps(props: Partial<ModalProps>) {
  function useVbenModal (line 26) | function useVbenModal<TParentModalProps extends ModalProps = ModalProps>(
  function checkProps (line 137) | async function checkProps(api: ExtendedModalApi, attrs: Record<string, a...

FILE: packages/@core/ui-kit/shadcn-ui/src/components/back-top/backtop.ts
  type BacktopProps (line 32) | interface BacktopProps {

FILE: packages/@core/ui-kit/shadcn-ui/src/components/breadcrumb/types.ts
  type IBreadcrumb (line 5) | interface IBreadcrumb {
  type BreadcrumbProps (line 13) | interface BreadcrumbProps {

FILE: packages/@core/ui-kit/shadcn-ui/src/components/button/button.ts
  type VbenButtonProps (line 7) | interface VbenButtonProps {
  type CustomRenderType (line 26) | type CustomRenderType = (() => Component | string) | string;
  type ValueType (line 28) | type ValueType = boolean | number | string;
  type VbenButtonGroupProps (line 30) | interface VbenButtonGroupProps extends Pick<

FILE: packages/@core/ui-kit/shadcn-ui/src/components/context-menu/interface.ts
  type IContextMenuItem (line 3) | interface IContextMenuItem {

FILE: packages/@core/ui-kit/shadcn-ui/src/components/dropdown-menu/interface.ts
  type VbenDropdownMenuItem (line 3) | interface VbenDropdownMenuItem {
  type DropdownMenuProps (line 28) | interface DropdownMenuProps {

FILE: packages/@core/ui-kit/shadcn-ui/src/components/pin-input/types.ts
  type PinInputProps (line 1) | interface PinInputProps {

FILE: packages/@core/ui-kit/shadcn-ui/src/components/segmented/types.ts
  type SegmentedItem (line 1) | interface SegmentedItem {

FILE: packages/@core/ui-kit/shadcn-ui/src/ui/avatar/avatar.ts
  type AvatarVariants (line 22) | type AvatarVariants = VariantProps<typeof avatarVariant>;

FILE: packages/@core/ui-kit/shadcn-ui/src/ui/badge/badge.ts
  type BadgeVariants (line 25) | type BadgeVariants = VariantProps<typeof badgeVariants>;

FILE: packages/@core/ui-kit/shadcn-ui/src/ui/button/types.ts
  type ButtonVariantSize (line 1) | type ButtonVariantSize =
  type ButtonVariants (line 10) | type ButtonVariants =

FILE: packages/@core/ui-kit/shadcn-ui/src/ui/form/injectionKeys.ts
  constant FORM_ITEM_INJECTION_KEY (line 3) | const FORM_ITEM_INJECTION_KEY = Symbol() as InjectionKey<string>;

FILE: packages/@core/ui-kit/shadcn-ui/src/ui/form/useFormField.ts
  function useFormField (line 13) | function useFormField() {

FILE: packages/@core/ui-kit/shadcn-ui/src/ui/sheet/sheet.ts
  type SheetVariants (line 24) | type SheetVariants = VariantProps<typeof sheetVariants>;

FILE: packages/@core/ui-kit/shadcn-ui/src/ui/toggle/toggle.ts
  type ToggleVariants (line 27) | type ToggleVariants = VariantProps<typeof toggleVariants>;

FILE: packages/@core/ui-kit/shadcn-ui/src/ui/tree/types.ts
  type TreeProps (line 6) | interface TreeProps {
  function treePropsDefaults (line 44) | function treePropsDefaults() {

FILE: packages/@core/ui-kit/tabs-ui/src/types.ts
  type TabsEmits (line 4) | type TabsEmits = {
  type TabsProps (line 10) | interface TabsProps {
  type TabConfig (line 67) | interface TabConfig extends TabDefinition {

FILE: packages/@core/ui-kit/tabs-ui/src/use-tabs-drag.ts
  function findParentElement (line 11) | function findParentElement(element: HTMLElement) {
  function useTabsDrag (line 18) | function useTabsDrag(props: TabsProps, emit: EmitType) {

FILE: packages/@core/ui-kit/tabs-ui/src/use-tabs-view-scroll.ts
  type DomElement (line 9) | type DomElement = Element | null | undefined;
  function useTabsViewScroll (line 11) | function useTabsViewScroll(props: TabsProps) {

FILE: packages/constants/src/core.ts
  constant LOGIN_PATH (line 4) | const LOGIN_PATH = '/auth/login';
  type LanguageOption (line 6) | interface LanguageOption {
  constant SUPPORT_LANGUAGES (line 14) | const SUPPORT_LANGUAGES: LanguageOption[] = [

FILE: packages/effects/access/src/accessible.ts
  function generateAccessible (line 21) | async function generateAccessible(
  function generateRoutes (line 80) | async function generateRoutes(
  function mergeRoutesByName (line 164) | function mergeRoutesByName(

FILE: packages/effects/access/src/directive.ts
  function isAccessible (line 11) | function isAccessible(
  function registerAccessDirective (line 40) | function registerAccessDirective(app: App) {

FILE: packages/effects/access/src/use-access.ts
  function useAccess (line 6) | function useAccess() {

FILE: packages/effects/common-ui/src/components/captcha/hooks/useCaptchaPoints.ts
  function useCaptchaPoints (line 5) | function useCaptchaPoints() {

FILE: packages/effects/common-ui/src/components/captcha/types.ts
  type CaptchaData (line 5) | interface CaptchaData {
  type CaptchaPoint (line 19) | interface CaptchaPoint extends CaptchaData {
  type PointSelectionCaptchaCardProps (line 25) | interface PointSelectionCaptchaCardProps {
  type PointSelectionCaptchaProps (line 57) | interface PointSelectionCaptchaProps extends PointSelectionCaptchaCardPr...
  type SliderCaptchaProps (line 75) | interface SliderCaptchaProps {
  type SliderRotateCaptchaProps (line 120) | interface SliderRotateCaptchaProps {
  type SliderTranslateCaptchaProps (line 161) | interface SliderTranslateCaptchaProps {
  type CaptchaVerifyPassingData (line 197) | interface CaptchaVerifyPassingData {
  type SliderCaptchaActionType (line 202) | interface SliderCaptchaActionType {
  type SliderRotateVerifyPassingData (line 206) | interface SliderRotateVerifyPassingData {

FILE: packages/effects/common-ui/src/components/col-page/types.ts
  type ColPageProps (line 3) | interface ColPageProps extends PageProps {

FILE: packages/effects/common-ui/src/components/count-to/types.ts
  type TransitionPresets (line 7) | type TransitionPresets = keyof typeof TransitionPresetsData;
  type CountToProps (line 13) | interface CountToProps {

FILE: packages/effects/common-ui/src/components/icon-picker/icons.ts
  constant ICONS_MAP (line 6) | const ICONS_MAP: Recordable<string[]> = {};
  type IconifyResponse (line 8) | interface IconifyResponse {
  constant PENDING_REQUESTS (line 17) | const PENDING_REQUESTS: Recordable<Promise<string[]>> = {};
  function fetchIconsData (line 26) | async function fetchIconsData(prefix: string): Promise<string[]> {

FILE: packages/effects/common-ui/src/components/json-viewer/types.ts
  type JsonViewerProps (line 1) | interface JsonViewerProps {
  type JsonViewerAction (line 26) | interface JsonViewerAction {
  type JsonViewerValue (line 32) | interface JsonViewerValue {
  type JsonViewerToggle (line 39) | interface JsonViewerToggle {

FILE: packages/effects/common-ui/src/components/loading/directive.ts
  constant LOADING_INSTANCE_KEY (line 8) | const LOADING_INSTANCE_KEY = Symbol('loading');
  constant SPINNER_INSTANCE_KEY (line 9) | const SPINNER_INSTANCE_KEY = Symbol('spinner');
  constant CLASS_NAME_RELATIVE (line 11) | const CLASS_NAME_RELATIVE = 'spinner-parent--relative';
  method mounted (line 14) | mounted(el, binding) {
  method unmounted (line 21) | unmounted(el) {
  method updated (line 30) | updated(el, binding) {
  function getOptions (line 49) | function getOptions(binding: DirectiveBinding) {
  method mounted (line 60) | mounted(el, binding) {
  method unmounted (line 67) | unmounted(el) {
  method updated (line 76) | updated(el, binding) {
  type loadingDirectiveParams (line 95) | type loadingDirectiveParams = {
  function registerLoadingDirective (line 107) | function registerLoadingDirective(

FILE: packages/effects/common-ui/src/components/page/types.ts
  type PageProps (line 1) | interface PageProps {

FILE: packages/effects/common-ui/src/components/tippy/directive.ts
  function useTippyDirective (line 5) | function useTippyDirective(isDark: ComputedRef<boolean>) {

FILE: packages/effects/common-ui/src/components/tippy/index.ts
  type TippyProps (line 21) | type TippyProps = Partial<
  function initTippy (line 34) | function initTippy(app: App<Element>, options?: DefaultProps) {

FILE: packages/effects/common-ui/src/ui/about/about.ts
  type AboutProps (line 3) | interface AboutProps {
  type DescriptionItem (line 9) | interface DescriptionItem {

FILE: packages/effects/common-ui/src/ui/authentication/types.ts
  type AuthenticationProps (line 1) | interface AuthenticationProps {

FILE: packages/effects/common-ui/src/ui/dashboard/typing.ts
  type AnalysisOverviewItem (line 3) | interface AnalysisOverviewItem {
  type WorkbenchProjectItem (line 11) | interface WorkbenchProjectItem {
  type WorkbenchTrendItem (line 21) | interface WorkbenchTrendItem {
  type WorkbenchTodoItem (line 28) | interface WorkbenchTodoItem {
  type WorkbenchQuickNavItem (line 35) | interface WorkbenchQuickNavItem {

FILE: packages/effects/common-ui/src/ui/fallback/fallback.ts
  type FallbackProps (line 1) | interface FallbackProps {

FILE: packages/effects/common-ui/src/ui/profile/types.ts
  type Props (line 3) | interface Props {
  type FormSchemaItem (line 12) | interface FormSchemaItem {
  type SettingProps (line 19) | interface SettingProps {

FILE: packages/effects/hooks/src/use-app-config.ts
  function useAppConfig (line 9) | function useAppConfig(

FILE: packages/effects/hooks/src/use-content-maximize.ts
  function useContentMaximize (line 5) | function useContentMaximize() {

FILE: packages/effects/hooks/src/use-design-tokens.ts
  function useAntdDesignTokens (line 10) | function useAntdDesignTokens() {
  function useNaiveDesignTokens (line 77) | function useNaiveDesignTokens() {
  function useElementPlusDesignTokens (line 163) | function useElementPlusDesignTokens() {

FILE: packages/effects/hooks/src/use-hover-toggle.ts
  type HoverDelayOptions (line 11) | interface HoverDelayOptions {
  constant DEFAULT_LEAVE_DELAY (line 18) | const DEFAULT_LEAVE_DELAY = 500;
  constant DEFAULT_ENTER_DELAY (line 19) | const DEFAULT_ENTER_DELAY = 0;
  function useHoverToggle (line 27) | function useHoverToggle(

FILE: packages/effects/hooks/src/use-pagination.ts
  function pagination (line 13) | function pagination<T = any>(list: T[], pageNo: number, pageSize: number...
  function usePagination (line 25) | function usePagination<T = any>(

FILE: packages/effects/hooks/src/use-refresh.ts
  function useRefresh (line 5) | function useRefresh() {

FILE: packages/effects/hooks/src/use-tabs.ts
  function useTabs (line 8) | function useTabs() {

FILE: packages/effects/hooks/src/use-watermark.ts
  function useWatermark (line 40) | function useWatermark() {

FILE: packages/effects/layouts/src/authentication/types.ts
  type ToolbarType (line 1) | type ToolbarType = 'color' | 'language' | 'layout' | 'theme';

FILE: packages/effects/layouts/src/basic/content/use-content-spinner.ts
  function useContentSpinner (line 6) | function useContentSpinner() {

FILE: packages/effects/layouts/src/basic/menu/use-extra-menu.ts
  function useExtraMenu (line 14) | function useExtraMenu(useRootMenus?: ComputedRef<MenuRecordRaw[]>) {

FILE: packages/effects/layouts/src/basic/menu/use-mixed-menu.ts
  function useMixedMenu (line 12) | function useMixedMenu() {

FILE: packages/effects/layouts/src/basic/menu/use-navigation.ts
  function useNavigation (line 7) | function useNavigation() {

FILE: packages/effects/layouts/src/basic/tabbar/use-tabbar.ts
  function useTabbar (line 28) | function useTabbar() {

FILE: packages/effects/layouts/src/hooks/index.ts
  function transformComponent (line 16) | function transformComponent(
  function useLayoutHook (line 55) | function useLayoutHook() {

FILE: packages/effects/layouts/src/widgets/notification/types.ts
  type NotificationItem (line 1) | interface NotificationItem {

FILE: packages/effects/layouts/src/widgets/preferences/use-open-preferences.ts
  function useOpenPreferences (line 5) | function useOpenPreferences() {

FILE: packages/effects/plugins/src/echarts/echarts.ts
  type ECOption (line 36) | type ECOption = ComposeOption<

FILE: packages/effects/plugins/src/echarts/use-echarts.ts
  type EchartsUIType (line 33) | type EchartsUIType = typeof EchartsUI | undefined;
  type EchartsThemeType (line 35) | type EchartsThemeType = 'dark' | 'light' | null;
  function useEcharts (line 37) | function useEcharts(chartRef: Ref<EchartsUIType>) {

FILE: packages/effects/plugins/src/motion/types.ts
  type MotionPreset (line 26) | type MotionPreset = (typeof MotionPresets)[number];

FILE: packages/effects/plugins/src/vxe-table/api.ts
  function getDefaultState (line 18) | function getDefaultState(): VxeGridProps {
  class VxeGridApi (line 29) | class VxeGridApi<T extends Record<string, any> = any> {
    method constructor (line 42) | constructor(options: VxeGridProps = {}) {
    method mount (line 60) | mount(instance: null | VxeGridInstance, formApi: ExtendedFormApi) {
    method query (line 69) | async query(params: Record<string, any> = {}) {
    method reload (line 77) | async reload(params: Record<string, any> = {}) {
    method setGridOptions (line 85) | setGridOptions(options: Partial<VxeGridProps['gridOptions']>) {
    method setLoading (line 91) | setLoading(isLoading: boolean) {
    method setState (line 99) | setState(
    method toggleSearchForm (line 113) | toggleSearchForm(show?: boolean) {
    method unmount (line 123) | unmount() {

FILE: packages/effects/plugins/src/vxe-table/extends.ts
  function extendProxyOptions (line 9) | function extendProxyOptions(
  function extendProxyOption (line 26) | function extendProxyOption(
  function extendsDefaultFormatter (line 69) | function extendsDefaultFormatter(vxeUI: VxeUIExport) {

FILE: packages/effects/plugins/src/vxe-table/init.ts
  function normalizeVxeLocale (line 55) | function normalizeVxeLocale<T extends Record<string, any>>(localeModule:...
  function initVxeTable (line 80) | function initVxeTable() {
  function setupVbenVxeTable (line 120) | function setupVbenVxeTable(setupOptions: SetupVxeTable) {

FILE: packages/effects/plugins/src/vxe-table/types.ts
  type VxePaginationInfo (line 18) | interface VxePaginationInfo {
  type ToolbarConfigOptions (line 24) | interface ToolbarConfigOptions extends VxeGridPropTypes.ToolbarConfig {
  type VxeTableGridOptions (line 29) | interface VxeTableGridOptions<T = any> extends VxeTableGridProps<T> {
  type SeparatorOptions (line 34) | interface SeparatorOptions {
  type VxeGridProps (line 39) | interface VxeGridProps<
  type ExtendedVxeGridApi (line 81) | type ExtendedVxeGridApi<
  type SetupVxeTable (line 90) | interface SetupVxeTable {

FILE: packages/effects/plugins/src/vxe-table/use-vxe-grid.ts
  type FilteredSlots (line 16) | type FilteredSlots<T> = {
  function useVbenVxeGrid (line 22) | function useVbenVxeGrid<
  type UseVbenVxeGrid (line 70) | type UseVbenVxeGrid = typeof useVbenVxeGrid;

FILE: packages/effects/request/src/request-client/modules/downloader.ts
  type DownloadRequestConfig (line 4) | type DownloadRequestConfig = {
  class FileDownloader (line 13) | class FileDownloader {
    method constructor (line 16) | constructor(client: RequestClient) {
    method download (line 25) | public async download<T = Blob>(

FILE: packages/effects/request/src/request-client/modules/interceptor.ts
  class InterceptorManager (line 18) | class InterceptorManager {
    method constructor (line 21) | constructor(instance: AxiosInstance) {
    method addRequestInterceptor (line 25) | addRequestInterceptor({
    method addResponseInterceptor (line 32) | addResponseInterceptor<T = any>({

FILE: packages/effects/request/src/request-client/modules/sse.test.ts
  method decode (line 15) | decode(value: Uint8Array, opts?: any) {

FILE: packages/effects/request/src/request-client/modules/sse.ts
  class SSE (line 9) | class SSE {
    method constructor (line 12) | constructor(client: RequestClient) {
    method postSSE (line 16) | public async postSSE(
    method requestSSE (line 33) | public async requestSSE(
  function safeJoinUrl (line 115) | function safeJoinUrl(baseUrl: string | undefined, url: string): string {

FILE: packages/effects/request/src/request-client/modules/uploader.ts
  class FileUploader (line 6) | class FileUploader {
    method constructor (line 9) | constructor(client: RequestClient) {
    method upload (line 13) | public async upload<T = any>(

FILE: packages/effects/request/src/request-client/request-client.ts
  function getParamsSerializer (line 15) | function getParamsSerializer(
  class RequestClient (line 39) | class RequestClient {
    method constructor (line 58) | constructor(options: RequestClientOptions = {}) {
    method delete (line 99) | public delete<T = any>(
    method get (line 109) | public get<T = any>(url: string, config?: RequestClientConfig): Promis...
    method getBaseUrl (line 116) | public getBaseUrl() {
    method post (line 123) | public post<T = any>(
    method put (line 134) | public put<T = any>(
    method request (line 145) | public async request<T>(

FILE: packages/effects/request/src/request-client/types.ts
  type ExtendOptions (line 8) | type ExtendOptions<T = any> = {
  type RequestClientConfig (line 30) | type RequestClientConfig<T = any> = AxiosRequestConfig<T> & ExtendOption...
  type RequestResponse (line 32) | type RequestResponse<T = any> = AxiosResponse<T> & {
  type RequestContentType (line 36) | type RequestContentType =
  type RequestClientOptions (line 42) | type RequestClientOptions = CreateAxiosDefaults & ExtendOptions;
  type SseRequestOptions (line 47) | interface SseRequestOptions extends RequestInit {
  type RequestInterceptorConfig (line 52) | interface RequestInterceptorConfig {
  type ResponseInterceptorConfig (line 61) | interface ResponseInterceptorConfig<T = any> {
  type MakeErrorMessageFn (line 68) | type MakeErrorMessageFn = (message: string, error: any) => void;
  type HttpResponse (line 70) | interface HttpResponse<T = any> {

FILE: packages/icons/src/svg/load.ts
  function parseSvg (line 7) | function parseSvg(svgData: string): IconifyIconStructure {
  function loadSvgIcons (line 55) | async function loadSvgIcons() {

FILE: packages/locales/src/i18n.ts
  function loadLocalesMap (line 37) | function loadLocalesMap(modules: Record<string, () => Promise<unknown>>) {
  function loadLocalesMapFromDir (line 55) | function loadLocalesMapFromDir(
  function setI18nLanguage (line 96) | function setI18nLanguage(locale: Locale) {
  function setupI18n (line 102) | async function setupI18n(app: App, options: LocaleSetupOptions = {}) {
  function loadLocaleMessages (line 123) | async function loadLocaleMessages(lang: SupportedLanguagesType) {

FILE: packages/locales/src/typing.ts
  type SupportedLanguagesType (line 1) | type SupportedLanguagesType = 'en-US' | 'zh-CN';
  type ImportLocaleFn (line 3) | type ImportLocaleFn = () => Promise<{ default: Record<string, string> }>;
  type LoadMessageFn (line 5) | type LoadMessageFn = (
  type LocaleSetupOptions (line 9) | interface LocaleSetupOptions {

FILE: packages/preferences/src/index.ts
  function defineOverridesPreferences (line 11) | function defineOverridesPreferences(preferences: DeepPartial<Preferences...

FILE: packages/stores/src/modules/access.ts
  type AccessToken (line 7) | type AccessToken = null | string;
  type AccessState (line 9) | interface AccessState {
  method getMenuByPath (line 53) | getMenuByPath(path: string) {
  method lockScreen (line 72) | lockScreen(password: string) {
  method setAccessCodes (line 76) | setAccessCodes(codes: string[]) {
  method setAccessMenus (line 79) | setAccessMenus(menus: MenuRecordRaw[]) {
  method setAccessRoutes (line 82) | setAccessRoutes(routes: RouteRecordRaw[]) {
  method setAccessToken (line 85) | setAccessToken(token: AccessToken) {
  method setIsAccessChecked (line 88) | setIsAccessChecked(isAccessChecked: boolean) {
  method setLoginExpired (line 91) | setLoginExpired(loginExpired: boolean) {
  method setRefreshToken (line 94) | setRefreshToken(token: AccessToken) {
  method unlockScreen (line 97) | unlockScreen() {

FILE: packages/stores/src/modules/tabbar.ts
  type RouteCached (line 25) | interface RouteCached {
  type TabbarState (line 31) | interface TabbarState {
  constant MAX_VISIT_HISTORY (line 70) | const MAX_VISIT_HISTORY = 50;
  method _bulkCloseByKeys (line 80) | async _bulkCloseByKeys(keys: string[]) {
  method _close (line 95) | _close(tab: TabDefinition) {
  method _goToDefaultTab (line 105) | async _goToDefaultTab(router: Router) {
  method _goToTab (line 119) | async _goToTab(tab: TabDefinition, router: Router) {
  method addTab (line 132) | addTab(routeTab: TabDefinition): TabDefinition {
  method closeAllTabs (line 201) | async closeAllTabs(router: Router) {
  method closeLeftTabs (line 217) | async closeLeftTabs(tab: TabDefinition) {
  method closeOtherTabs (line 238) | async closeOtherTabs(tab: TabDefinition) {
  method closeRightTabs (line 262) | async closeRightTabs(tab: TabDefinition) {
  method closeTab (line 283) | async closeTab(tab: TabDefinition, router: Router) {
  method closeTabByKey (line 346) | async closeTabByKey(key: string, router: Router) {
  method getTabByKey (line 365) | getTabByKey(key: string) {
  method openTabInNewWindow (line 374) | async openTabInNewWindow(tab: TabDefinition) {
  method pinTab (line 382) | async pinTab(tab: TabDefinition) {
  method refresh (line 403) | async refresh(router: Router | string) {
  method refreshByName (line 427) | async refreshByName(name: string) {
  method resetTabTitle (line 436) | async resetTabTitle(tab: TabDefinition) {
  method setAffixTabs (line 451) | setAffixTabs(tabs: RouteRecordNormalized[]) {
  method setMenuList (line 462) | setMenuList(list: string[]) {
  method setTabTitle (line 484) | async setTabTitle(tab: TabDefinition, title: ComputedRef<string> | strin...
  method setUpdateTime (line 493) | setUpdateTime() {
  method sortTabs (line 501) | async sortTabs(oldIndex: number, newIndex: number) {
  method toggleTabPin (line 515) | async toggleTabPin(tab: TabDefinition) {
  method unpinTab (line 525) | async unpinTab(tab: TabDefinition) {
  method updateCacheTabs (line 545) | async updateCacheTabs() {
  method addCachedRoute (line 570) | addCachedRoute(component: VNode, route: RouteLocationNormalizedLoaded) {
  method removeCachedRoute (line 581) | removeCachedRoute(key: string) {
  method affixTabs (line 586) | affixTabs(): TabDefinition[] {
  method getCachedTabs (line 595) | getCachedTabs(): string[] {
  method getExcludeCachedTabs (line 598) | getExcludeCachedTabs(): string[] {
  method getMenuList (line 601) | getMenuList(): string[] {
  method getTabs (line 604) | getTabs(): TabDefinition[] {
  method getCachedRoutes (line 608) | getCachedRoutes(): Map<string, RouteCached> {
  method deserialize (line 619) | deserialize(value: string) {
  function cloneTab (line 669) | function cloneTab(route: TabDefinition): TabDefinition {
  function isAffixTab (line 694) | function isAffixTab(tab: TabDefinition) {
  function isTabShown (line 702) | function isTabShown(tab: TabDefinition) {
  function getTabKey (line 711) | function getTabKey(tab: RouteLocationNormalized | RouteRecordNormalized) {
  function isVisitHistory (line 738) | function isVisitHistory() {
  function getTabKeyFromTab (line 747) | function getTabKeyFromTab(tab: TabDefinition): string {
  function equalTab (line 756) | function equalTab(a: TabDefinition, b: TabDefinition) {
  function routeToTab (line 760) | function routeToTab(route: RouteRecordNormalized) {

FILE: packages/stores/src/modules/timezone.ts
  type TimezoneHandler (line 11) | interface TimezoneHandler {
  function initTimezone (line 71) | async function initTimezone() {
  function setTimezone (line 86) | async function setTimezone(timezone: string) {
  function getTimezoneOptions (line 98) | async function getTimezoneOptions() {
  function $reset (line 107) | function $reset() {

FILE: packages/stores/src/modules/user.ts
  type BasicUserInfo (line 3) | interface BasicUserInfo {
  type AccessState (line 27) | interface AccessState {
  method setUserInfo (line 43) | setUserInfo(userInfo: BasicUserInfo | null) {
  method setUserRoles (line 50) | setUserRoles(roles: string[]) {

FILE: packages/stores/src/setup.ts
  type SecureLSStorage (line 10) | type SecureLSStorage = {
  type SecureLSCtor (line 15) | type SecureLSCtor = new (config?: {
  type InitStoreOptions (line 32) | interface InitStoreOptions {
  function initStores (line 42) | async function initStores(app: App, options: InitStoreOptions) {
  function resetAllStores (line 72) | function resetAllStores() {

FILE: packages/types/global.d.ts
  type RouteMeta (line 7) | interface RouteMeta extends IRouteMeta {}
  type VbenAdminProAppConfigRaw (line 10) | interface VbenAdminProAppConfigRaw {
  type AuthConfig (line 16) | interface AuthConfig {
  type ApplicationConfig (line 23) | interface ApplicationConfig {
  type Window (line 29) | interface Window {

FILE: packages/types/src/user.ts
  type UserInfo (line 4) | interface UserInfo extends BasicUserInfo {

FILE: packages/utils/src/helpers/find-menu-by-path.ts
  function findMenuByPath (line 3) | function findMenuByPath(
  function findRootMenuByPath (line 24) | function findRootMenuByPath(menus: MenuRecordRaw[], path?: string, level...

FILE: packages/utils/src/helpers/generate-menus.ts
  function generateMenus (line 17) | function generateMenus(

FILE: packages/utils/src/helpers/generate-routes-backend.ts
  function menuHasVisibleWithForbidden (line 14) | function menuHasVisibleWithForbidden(route: RouteRecordRaw): boolean {
  function generateRoutesByBackend (line 22) | async function generateRoutesByBackend(
  function convertRoutes (line 62) | function convertRoutes(
  function normalizeViewPath (line 96) | function normalizeViewPath(path: string): string {

FILE: packages/utils/src/helpers/generate-routes-frontend.ts
  function generateRoutesByFrontend (line 8) | async function generateRoutesByFrontend(
  function hasAuthority (line 36) | function hasAuthority(route: RouteRecordRaw, access: string[]) {
  function menuHasVisibleWithForbidden (line 50) | function menuHasVisibleWithForbidden(route: RouteRecordRaw) {

FILE: packages/utils/src/helpers/get-popup-container.ts
  function getPopupContainer (line 6) | function getPopupContainer(node?: HTMLElement): HTMLElement {

FILE: packages/utils/src/helpers/merge-route-modules.ts
  type RouteModuleType (line 4) | interface RouteModuleType {
  function mergeRouteModules (line 13) | function mergeRouteModules(

FILE: packages/utils/src/helpers/reset-routes.ts
  function resetStaticRoutes (line 8) | function resetStaticRoutes(router: Router, routes: RouteRecordRaw[]) {

FILE: packages/utils/src/helpers/unmount-global-loading.ts
  function unmountGlobalLoading (line 8) | function unmountGlobalLoading() {

FILE: playground/__tests__/e2e/common/auth.ts
  function authLogin (line 5) | async function authLogin(page: Page) {

FILE: playground/src/adapter/component/index.ts
  constant IMAGE_EXTENSIONS (line 134) | const IMAGE_EXTENSIONS = new Set([
  function isImageFile (line 147) | function isImageFile(file: UploadFile): boolean {
  function createDefaultUploadSlots (line 168) | function createDefaultUploadSlots(listType: string, placeholder: string) {
  function getBase64 (line 190) | function getBase64(file: File): Promise<string> {
  function previewImage (line 202) | async function previewImage(
  function cropImage (line 281) | function cropImage(file: File, aspectRatio: string | undefined) {
  method setup (line 382) | setup(
  type ComponentType (line 565) | type ComponentType =
  function initComponentAdapter (line 595) | async function initComponentAdapter() {

FILE: playground/src/adapter/form.ts
  function initSetupVbenForm (line 11) | async function initSetupVbenForm() {
  type VbenFormSchema (line 46) | type VbenFormSchema = FormSchema<ComponentType>;

FILE: playground/src/adapter/vxe-table.ts
  method renderTableDefault (line 65) | renderTableDefault(renderOpts, params) {
  method renderTableDefault (line 74) | renderTableDefault(renderOpts) {
  method renderTableDefault (line 86) | renderTableDefault({ options, props }, { column, row }) {
  method renderTableDefault (line 105) | renderTableDefault({ attrs, props }, { column, row }) {
  method renderTableDefault (line 136) | renderTableDefault({ attrs, options, props }, { column, row }) {
  type OnActionClickParams (line 291) | type OnActionClickParams<T = Recordable<any>> = {
  type OnActionClickFn (line 295) | type OnActionClickFn<T = Recordable<any>> = (

FILE: playground/src/api/core/auth.ts
  type LoginParams (line 5) | interface LoginParams {
  type LoginResult (line 11) | interface LoginResult {
  type RefreshTokenResult (line 15) | interface RefreshTokenResult {
  function loginApi (line 24) | async function loginApi(data: AuthApi.LoginParams) {
  function refreshTokenApi (line 33) | async function refreshTokenApi() {
  function logoutApi (line 46) | async function logoutApi() {
  function getAccessCodesApi (line 55) | async function getAccessCodesApi() {

FILE: playground/src/api/core/menu.ts
  function getAllMenusApi (line 8) | async function getAllMenusApi() {

FILE: playground/src/api/core/timezone.ts
  function getTimezoneOptionsApi (line 6) | async function getTimezoneOptionsApi() {
  function getTimezoneApi (line 17) | async function getTimezoneApi(): Promise<null | string | undefined> {
  function setTimezoneApi (line 24) | async function setTimezoneApi(timezone: string): Promise<void> {

FILE: playground/src/api/core/user.ts
  function getUserInfoApi (line 8) | async function getUserInfoApi() {

FILE: playground/src/api/examples/download.ts
  function downloadFile1 (line 9) | async function downloadFile1() {
  function downloadFile2 (line 19) | async function downloadFile2() {

FILE: playground/src/api/examples/json-bigint.ts
  function getBigIntData (line 6) | async function getBigIntData() {

FILE: playground/src/api/examples/params.ts
  function getParamsData (line 8) | async function getParamsData(

FILE: playground/src/api/examples/status.ts
  function getMockStatusApi (line 6) | async function getMockStatusApi(status: string) {

FILE: playground/src/api/examples/table.ts
  type PageFetchParams (line 4) | interface PageFetchParams {
  function getExampleTableApi (line 14) | async function getExampleTableApi(params: DemoTableApi.PageFetchParams) {

FILE: playground/src/api/examples/upload.ts
  type UploadFileParams (line 3) | interface UploadFileParams {
  function upload_file (line 9) | async function upload_file({

FILE: playground/src/api/request.ts
  function createRequestClient (line 26) | function createRequestClient(baseURL: string, options?: RequestClientOpt...
  type PageFetchParams (line 129) | interface PageFetchParams {

FILE: playground/src/api/system/dept.ts
  type SystemDept (line 4) | interface SystemDept {
  function getDeptList (line 17) | async function getDeptList() {
  function createDept (line 27) | async function createDept(
  function updateDept (line 39) | async function updateDept(
  function deleteDept (line 50) | async function deleteDept(id: string) {

FILE: playground/src/api/system/menu.ts
  type SystemMenu (line 25) | interface SystemMenu {
  function getMenuList (line 96) | async function getMenuList() {
  function isMenuNameExists (line 102) | async function isMenuNameExists(
  function isMenuPathExists (line 111) | async function isMenuPathExists(
  function createMenu (line 124) | async function createMenu(
  function updateMenu (line 136) | async function updateMenu(
  function deleteMenu (line 147) | async function deleteMenu(id: string) {

FILE: playground/src/api/system/role.ts
  type SystemRole (line 6) | interface SystemRole {
  function getRoleList (line 19) | async function getRoleList(params: Recordable<any>) {
  function createRole (line 30) | async function createRole(data: Omit<SystemRoleApi.SystemRole, 'id'>) {
  function updateRole (line 40) | async function updateRole(
  function deleteRole (line 51) | async function deleteRole(id: string) {

FILE: playground/src/bootstrap.ts
  function bootstrap (line 20) | async function bootstrap(namespace: string) {

FILE: playground/src/locales/index.ts
  function loadMessages (line 33) | async function loadMessages(lang: SupportedLanguagesType) {
  function loadThirdPartyMessage (line 45) | async function loadThirdPartyMessage(lang: SupportedLanguagesType) {
  function loadDayjsLocale (line 53) | async function loadDayjsLocale(lang: SupportedLanguagesType) {
  function loadAntdLocale (line 80) | async function loadAntdLocale(lang: SupportedLanguagesType) {
  function setupI18n (line 93) | async function setupI18n(app: App, options: LocaleSetupOptions = {}) {

FILE: playground/src/main.ts
  function initApplication (line 9) | async function initApplication() {

FILE: playground/src/router/access.ts
  function generateAccess (line 17) | async function generateAccess(options: GenerateMenuAndRoutesOptions) {

FILE: playground/src/router/guard.ts
  function setupCommonGuard (line 17) | function setupCommonGuard(router: Router) {
  function setupAccessGuard (line 46) | function setupAccessGuard(router: Router) {
  function createRouterGuard (line 129) | function createRouterGuard(router: Router) {

FILE: playground/src/store/auth.ts
  function authLogin (line 29) | async function authLogin(
  function logout (line 83) | async function logout(redirect: boolean = true) {
  function fetchUserInfo (line 109) | async function fetchUserInfo() {
  function $reset (line 115) | function $reset() {

FILE: playground/src/timezone-init.ts
  function initTimezone (line 8) | function initTimezone() {

FILE: playground/src/views/demos/features/vue-query/typing.ts
  type IProducts (line 1) | interface IProducts {

FILE: playground/src/views/examples/vxe-table/table-data.ts
  type TableRowData (line 1) | interface TableRowData {
  constant MOCK_TABLE_DATA (line 12) | const MOCK_TABLE_DATA: TableRowData[] = (() => {
  constant MOCK_TREE_TABLE_DATA (line 27) | const MOCK_TREE_TABLE_DATA = [

FILE: playground/src/views/system/dept/data.ts
  function useSchema (line 14) | function useSchema(): VbenFormSchema[] {
  function useColumns (line 77) | function useColumns(

FILE: playground/src/views/system/menu/data.ts
  function getMenuTypeOptions (line 6) | function getMenuTypeOptions() {
  function useColumns (line 24) | function useColumns(

FILE: playground/src/views/system/role/data.ts
  function useFormSchema (line 7) | function useFormSchema(): VbenFormSchema[] {
  function useGridFormSchema (line 44) | function useGridFormSchema(): VbenFormSchema[] {
  function useColumns (line 77) | function useColumns<T = SystemRoleApi.SystemRole>(

FILE: scripts/clean.mjs
  constant CONCURRENCY_LIMIT (line 7) | const CONCURRENCY_LIMIT = 10;
  constant SKIP_DIRS (line 10) | const SKIP_DIRS = new Set(['.DS_Store', '.git', '.idea', '.vscode']);
  function processItem (line 20) | async function processItem(currentDir, item, targets, _depth) {
  function cleanTargetsRecursively (line 60) | async function cleanTargetsRecursively(currentDir, targets, depth = 0) {

FILE: scripts/turbo-run/src/run.ts
  type RunOptions (line 5) | interface RunOptions {
  function run (line 9) | async function run(options: RunOptions) {

FILE: scripts/vsh/src/check-circular/index.ts
  constant DEFAULT_CONFIG (line 15) | const DEFAULT_CONFIG = {
  type CircularDependencyResult (line 32) | type CircularDependencyResult = string[];
  type CheckCircularConfig (line 34) | interface CheckCircularConfig {
  type CommandOptions (line 40) | interface CommandOptions {
  function detectCircularDependencies (line 49) | async function detectCircularDependencies({
  function formatCircles (line 91) | function formatCircles(circles: CircularDependencyResult[]): void {
  function checkCircular (line 112) | async function checkCircular({
  function defineCheckCircularCommand (line 193) | function defineCheckCircularCommand(cac: CAC): void {

FILE: scripts/vsh/src/check-dep/index.ts
  constant DEFAULT_CONFIG (line 8) | const DEFAULT_CONFIG = {
  type DepcheckResult (line 37) | interface DepcheckResult {
  type DepcheckConfig (line 43) | interface DepcheckConfig {
  type PackageInfo (line 49) | interface PackageInfo {
  function cleanDepcheckResult (line 60) | function cleanDepcheckResult(unused: DepcheckResult): void {
  function formatDepcheckResult (line 80) | function formatDepcheckResult(pkgName: string, unused: DepcheckResult): ...
  function runDepcheck (line 115) | async function runDepcheck(config: DepcheckConfig = {}): Promise<void> {
  function defineDepcheckCommand (line 167) | function defineDepcheckCommand(cac: CAC): void {

FILE: scripts/vsh/src/code-workspace/index.ts
  constant CODE_WORKSPACE_FILE (line 16) | const CODE_WORKSPACE_FILE = join('vben-admin.code-workspace');
  type CodeWorkspaceCommandOptions (line 18) | interface CodeWorkspaceCommandOptions {
  function createCodeWorkspace (line 23) | async function createCodeWorkspace({
  function runCodeWorkspace (line 49) | async function runCodeWorkspace({
  function defineCodeWorkspaceCommand (line 65) | function defineCodeWorkspaceCommand(cac: CAC) {

FILE: scripts/vsh/src/index.ts
  constant COMMAND_DESCRIPTIONS (line 13) | const COMMAND_DESCRIPTIONS = {
  function main (line 24) | async function main(): Promise<void> {

FILE: scripts/vsh/src/lint/index.ts
  type LintCommandOptions (line 5) | interface LintCommandOptions {
  function runLint (line 12) | async function runLint({ format }: LintCommandOptions) {
  function defineLintCommand (line 46) | function defineLintCommand(cac: CAC) {

FILE: scripts/vsh/src/publint/index.ts
  constant CACHE_FILE (line 21) | const CACHE_FILE = join(
  type PubLintCommandOptions (line 28) | interface PubLintCommandOptions {
  function getLintFiles (line 39) | async function getLintFiles(files: string[] = []) {
  function getCacheFile (line 54) | function getCacheFile() {
  function readCache (line 59) | async function readCache(cacheFile: string) {
  function runPublint (line 68) | async function runPublint(files: string[], { check }: PubLintCommandOpti...
  function printResult (line 115) | function printResult(
  function definePubLintCommand (line 177) | function definePubLintCommand(cac: CAC) {
Condensed preview — 1652 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,382K chars).
[
  {
    "path": ".browserslistrc",
    "chars": 40,
    "preview": "> 1%\nlast 2 versions\nnot dead\nnot ie 11\n"
  },
  {
    "path": ".changeset/README.md",
    "chars": 510,
    "preview": "# Changesets\n\nHello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that wo"
  },
  {
    "path": ".changeset/config.json",
    "chars": 473,
    "preview": "{\n  \"$schema\": \"https://unpkg.com/@changesets/config@3.0.0/schema.json\",\n  \"changelog\": [\n    \"@changesets/changelog-git"
  },
  {
    "path": ".commitlintrc.js",
    "chars": 51,
    "preview": "export { default } from '@vben/commitlint-config';\n"
  },
  {
    "path": ".dockerignore",
    "chars": 55,
    "preview": "node_modules\n.git\n.gitignore\n*.md\ndist\n.turbo\ndist.zip\n"
  },
  {
    "path": ".editorconfig",
    "chars": 278,
    "preview": "root = true\n\n[*]\ncharset=utf-8\nend_of_line=lf\ninsert_final_newline=true\nindent_style=space\nindent_size=2\nmax_line_length"
  },
  {
    "path": ".gitattributes",
    "chars": 459,
    "preview": "# https://docs.github.com/cn/get-started/getting-started-with-git/configuring-git-to-handle-line-endings\n\n# Automaticall"
  },
  {
    "path": ".gitconfig",
    "chars": 30,
    "preview": "[core]\n    ignorecase = false\n"
  },
  {
    "path": ".github/CODEOWNERS",
    "chars": 817,
    "preview": "# default onwer\n* anncwb@126.com vince292007@gmail.com netfan@foxmail.com jinmao88@qq.com\n\n# vben core onwer\n/.github/ a"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug-report.yml",
    "chars": 3325,
    "preview": "name: 🐞 Bug Report\ndescription: Report an issue with Vben Admin to help us make it better.\ntitle: 'Bug: '\nlabels: ['bug:"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/docs.yml",
    "chars": 1329,
    "preview": "name: 📚 Documentation\ndescription: Report an issue with Vben Admin Website to help us make it better.\ntitle: 'Docs: '\nla"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature-request.yml",
    "chars": 2347,
    "preview": "name: ✨ New Feature Proposal\ndescription: Propose a new feature to be added to Vben Admin\ntitle: 'FEATURE: '\nlabels: ['e"
  },
  {
    "path": ".github/actions/setup-node/action.yml",
    "chars": 995,
    "preview": "name: 'Setup Node'\n\ndescription: 'Setup node and pnpm'\n\nruns:\n  using: 'composite'\n  steps:\n    - name: Install pnpm\n   "
  },
  {
    "path": ".github/commit-convention.md",
    "chars": 2859,
    "preview": "## Git Commit Message Convention\n\n> This is adapted from [Angular's commit convention](https://github.com/conventional-c"
  },
  {
    "path": ".github/config.yml",
    "chars": 1428,
    "preview": "# Prevent issues being created without using the template\nblank_issues_enabled: false\ncheckIssueTemplate: true\ncheckPull"
  },
  {
    "path": ".github/contributing.md",
    "chars": 2042,
    "preview": "# Vben Admin Contributing Guide\n\nHi! We're really excited that you are interested in contributing to Vben Admin. Before "
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 351,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: npm\n    directory: '/'\n    schedule:\n      interval: daily\n    groups:\n      "
  },
  {
    "path": ".github/pull_request_template.md",
    "chars": 1758,
    "preview": "## Description\n\n<!-- Please describe the change as necessary. If it's a feature or enhancement please be as detailed as "
  },
  {
    "path": ".github/release-drafter.yml",
    "chars": 1150,
    "preview": "name-template: 'v$RESOLVED_VERSION'\ntag-template: 'v$RESOLVED_VERSION'\nversion-template: $MAJOR.$MINOR.$PATCH\nchange-tem"
  },
  {
    "path": ".github/semantic.yml",
    "chars": 134,
    "preview": "titleAndCommits: true\ntypes:\n  - feat\n  - fix\n  - docs\n  - chore\n  - style\n  - refactor\n  - perf\n  - test\n  - build\n  - "
  },
  {
    "path": ".github/workflows/build.yml",
    "chars": 1040,
    "preview": "# name: Dependabot post-update\nname: Build detection\non:\n  pull_request_target:\n    types: [opened, synchronize, reopene"
  },
  {
    "path": ".github/workflows/changeset-version.yml",
    "chars": 1042,
    "preview": "# https://github.com/changesets/action\nname: Changeset version\n\non:\n  workflow_dispatch:\n  pull_request:\n    types:\n    "
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 2805,
    "preview": "name: CI\n\non:\n  pull_request:\n  push:\n    branches:\n      - main\n      - 'releases/*'\n\npermissions:\n  contents: read\n\nen"
  },
  {
    "path": ".github/workflows/codeql.yml",
    "chars": 4488,
    "preview": "# For most projects, this workflow file will not need changing; you simply need\n# to commit it to your repository.\n#\n# Y"
  },
  {
    "path": ".github/workflows/deploy.yml",
    "chars": 5570,
    "preview": "name: Deploy Website on push\n\non:\n  push:\n    branches:\n      - main\n\njobs:\n  deploy-playground-ftp:\n    name: Deploy Pu"
  },
  {
    "path": ".github/workflows/draft.yml",
    "chars": 591,
    "preview": "name: Release Drafter\n\non:\n  push:\n    branches:\n      - main\n\npermissions:\n  contents: read\n  pull-requests: write\n\njob"
  },
  {
    "path": ".github/workflows/issue-close-require.yml",
    "chars": 1033,
    "preview": "# 每天零点运行一次,它会检查所有带有 \"need reproduction\" 标签的 Issues。如果这些 Issues 在过去的 3 天内没有任何活动,它们将会被自动关闭。这有助于保持 Issue 列表的整洁,并且提醒用户在必要时提供"
  },
  {
    "path": ".github/workflows/issue-labeled.yml",
    "chars": 1499,
    "preview": "name: Label Based Actions\n\non:\n  issues:\n    types: [labeled]\n  # pull_request:\n  #   types: [labeled]\n\npermissions:\n  i"
  },
  {
    "path": ".github/workflows/lock.yml",
    "chars": 514,
    "preview": "name: Lock Threads\n\non:\n  schedule:\n    - cron: '0 0 * * *'\n  workflow_dispatch:\n\npermissions:\n  issues: write\n  pull-re"
  },
  {
    "path": ".github/workflows/release-tag.yml",
    "chars": 2131,
    "preview": "name: Create Release Tag\n\non:\n  push:\n    tags:\n      - 'v*.*.*' # Push events to matching v*, i.e. v1.0, v20.15.10\n\nenv"
  },
  {
    "path": ".github/workflows/rerun.yml",
    "chars": 464,
    "preview": "name: Rerun workflow\n\non:\n  workflow_dispatch:\n    inputs:\n      run_id:\n        description: The workflow id to relanch"
  },
  {
    "path": ".github/workflows/semantic-pull-request.yml",
    "chars": 1005,
    "preview": "name: Semantic Pull Request\n\non:\n  pull_request_target:\n    types:\n      - opened\n      - edited\n      - synchronize\n\njo"
  },
  {
    "path": ".github/workflows/stale.yml",
    "chars": 710,
    "preview": "name: 'Close stale issues'\n\non:\n  schedule:\n    - cron: '0 1 * * *'\n\njobs:\n  stale:\n    if: github.repository == 'vbenjs"
  },
  {
    "path": ".gitignore",
    "chars": 630,
    "preview": "node_modules\n.DS_Store\ndist\ndist-ssr\ndist.zip\ndist.tar\ndist.war\n.nitro\n.output\n*-dist.zip\n*-dist.tar\n*-dist.war\ncoverage"
  },
  {
    "path": ".gitpod.yml",
    "chars": 129,
    "preview": "ports:\n  - port: 5555\n    onOpen: open-preview\ntasks:\n  - init: npm i -g corepack && pnpm install\n    command: pnpm run "
  },
  {
    "path": ".node-version",
    "chars": 8,
    "preview": "22.22.0\n"
  },
  {
    "path": ".npmrc",
    "chars": 375,
    "preview": "registry=https://registry.npmmirror.com\npublic-hoist-pattern[]=lefthook\npublic-hoist-pattern[]=eslint\npublic-hoist-patte"
  },
  {
    "path": ".stylelintignore",
    "chars": 61,
    "preview": "dist\npublic\n__tests__\ncoverage\n.codex\n.claude\n.agent\n.agents\n"
  },
  {
    "path": ".vscode/extensions.json",
    "chars": 845,
    "preview": "{\n  \"recommendations\": [\n    // Vue 3 的语言支持\n    \"Vue.volar\",\n    // 将 eslint 集成到 VS Code 中。\n    \"dbaeumer.vscode-eslint\""
  },
  {
    "path": ".vscode/global.code-snippets",
    "chars": 794,
    "preview": "{\n  \"import\": {\n    \"scope\": \"javascript,typescript\",\n    \"prefix\": \"im\",\n    \"body\": [\"import { $2 } from '$1';\"],\n    "
  },
  {
    "path": ".vscode/launch.json",
    "chars": 1163,
    "preview": "{\n  \"$schema\": \"https://json.schemastore.org/launchsettings.json\",\n  \"version\": \"0.2.0\",\n  \"configurations\": [\n    {\n   "
  },
  {
    "path": ".vscode/settings.json",
    "chars": 7278,
    "preview": "{\n  \"tailwindCSS.experimental.configFile\": \"internal/tailwind-config/src/theme.css\",\n  \"tailwindCSS.lint.suggestCanonica"
  },
  {
    "path": "LICENSE",
    "chars": 1070,
    "preview": "MIT License\n\nCopyright (c) 2024-present, Vben\n\nPermission is hereby granted, free of charge, to any person obtaining a c"
  },
  {
    "path": "README.ja-JP.md",
    "chars": 5348,
    "preview": "<div align=\"center\">\n  <a href=\"https://github.com/anncwb/vue-vben-admin\">\n    <img alt=\"VbenAdmin Logo\" width=\"215\" src"
  },
  {
    "path": "README.md",
    "chars": 6671,
    "preview": "<div align=\"center\">\n  <a href=\"https://github.com/anncwb/vue-vben-admin\">\n    <img alt=\"VbenAdmin Logo\" width=\"215\" src"
  },
  {
    "path": "README.zh-CN.md",
    "chars": 5107,
    "preview": "<div align=\"center\">\n  <a href=\"https://github.com/anncwb/vue-vben-admin\">\n    <img alt=\"VbenAdmin Logo\" width=\"215\" src"
  },
  {
    "path": "apps/backend-mock/README.md",
    "chars": 363,
    "preview": "# @vben/backend-mock\n\n## Description\n\nVben Admin 数据 mock 服务,没有对接任何的数据库,所有数据都是模拟的,用于前端开发时提供数据支持。线上环境不再提供 mock 集成,可自行部署服务或"
  },
  {
    "path": "apps/backend-mock/api/auth/codes.ts",
    "chars": 504,
    "preview": "import { eventHandler } from 'h3';\nimport { verifyAccessToken } from '~/utils/jwt-utils';\nimport { MOCK_CODES } from '~/"
  },
  {
    "path": "apps/backend-mock/api/auth/login.post.ts",
    "chars": 1158,
    "preview": "import { defineEventHandler, readBody, setResponseStatus } from 'h3';\nimport {\n  clearRefreshTokenCookie,\n  setRefreshTo"
  },
  {
    "path": "apps/backend-mock/api/auth/logout.post.ts",
    "chars": 438,
    "preview": "import { defineEventHandler } from 'h3';\nimport {\n  clearRefreshTokenCookie,\n  getRefreshTokenFromCookie,\n} from '~/util"
  },
  {
    "path": "apps/backend-mock/api/auth/refresh.post.ts",
    "chars": 945,
    "preview": "import { defineEventHandler } from 'h3';\nimport {\n  clearRefreshTokenCookie,\n  getRefreshTokenFromCookie,\n  setRefreshTo"
  },
  {
    "path": "apps/backend-mock/api/demo/bigint.ts",
    "chars": 941,
    "preview": "import { eventHandler, setHeader } from 'h3';\nimport { verifyAccessToken } from '~/utils/jwt-utils';\nimport { unAuthoriz"
  },
  {
    "path": "apps/backend-mock/api/menu/all.ts",
    "chars": 509,
    "preview": "import { eventHandler } from 'h3';\nimport { verifyAccessToken } from '~/utils/jwt-utils';\nimport { MOCK_MENUS } from '~/"
  },
  {
    "path": "apps/backend-mock/api/status.ts",
    "chars": 285,
    "preview": "import { eventHandler, getQuery, setResponseStatus } from 'h3';\nimport { useResponseError } from '~/utils/response';\n\nex"
  },
  {
    "path": "apps/backend-mock/api/system/dept/.post.ts",
    "chars": 396,
    "preview": "import { eventHandler } from 'h3';\nimport { verifyAccessToken } from '~/utils/jwt-utils';\nimport {\n  sleep,\n  unAuthoriz"
  },
  {
    "path": "apps/backend-mock/api/system/dept/[id].delete.ts",
    "chars": 397,
    "preview": "import { eventHandler } from 'h3';\nimport { verifyAccessToken } from '~/utils/jwt-utils';\nimport {\n  sleep,\n  unAuthoriz"
  },
  {
    "path": "apps/backend-mock/api/system/dept/[id].put.ts",
    "chars": 397,
    "preview": "import { eventHandler } from 'h3';\nimport { verifyAccessToken } from '~/utils/jwt-utils';\nimport {\n  sleep,\n  unAuthoriz"
  },
  {
    "path": "apps/backend-mock/api/system/dept/list.ts",
    "chars": 1720,
    "preview": "import { faker } from '@faker-js/faker';\nimport { eventHandler } from 'h3';\nimport { verifyAccessToken } from '~/utils/j"
  },
  {
    "path": "apps/backend-mock/api/system/menu/list.ts",
    "chars": 425,
    "preview": "import { eventHandler } from 'h3';\nimport { verifyAccessToken } from '~/utils/jwt-utils';\nimport { MOCK_MENU_LIST } from"
  },
  {
    "path": "apps/backend-mock/api/system/menu/name-exists.ts",
    "chars": 833,
    "preview": "import { eventHandler, getQuery } from 'h3';\nimport { verifyAccessToken } from '~/utils/jwt-utils';\nimport { MOCK_MENU_L"
  },
  {
    "path": "apps/backend-mock/api/system/menu/path-exists.ts",
    "chars": 837,
    "preview": "import { eventHandler, getQuery } from 'h3';\nimport { verifyAccessToken } from '~/utils/jwt-utils';\nimport { MOCK_MENU_L"
  },
  {
    "path": "apps/backend-mock/api/system/role/list.ts",
    "chars": 2264,
    "preview": "import { faker } from '@faker-js/faker';\nimport { eventHandler, getQuery } from 'h3';\nimport { verifyAccessToken } from "
  },
  {
    "path": "apps/backend-mock/api/table/list.ts",
    "chars": 3652,
    "preview": "import { faker } from '@faker-js/faker';\nimport { eventHandler, getQuery } from 'h3';\nimport { verifyAccessToken } from "
  },
  {
    "path": "apps/backend-mock/api/test.get.ts",
    "chars": 103,
    "preview": "import { defineEventHandler } from 'h3';\n\nexport default defineEventHandler(() => 'Test get handler');\n"
  },
  {
    "path": "apps/backend-mock/api/test.post.ts",
    "chars": 104,
    "preview": "import { defineEventHandler } from 'h3';\n\nexport default defineEventHandler(() => 'Test post handler');\n"
  },
  {
    "path": "apps/backend-mock/api/timezone/getTimezone.ts",
    "chars": 419,
    "preview": "import { eventHandler } from 'h3';\nimport { verifyAccessToken } from '~/utils/jwt-utils';\nimport { unAuthorizedResponse,"
  },
  {
    "path": "apps/backend-mock/api/timezone/getTimezoneOptions.ts",
    "chars": 376,
    "preview": "import { eventHandler } from 'h3';\nimport { TIME_ZONE_OPTIONS } from '~/utils/mock-data';\nimport { useResponseSuccess } "
  },
  {
    "path": "apps/backend-mock/api/timezone/setTimezone.ts",
    "chars": 861,
    "preview": "import { eventHandler, readBody } from 'h3';\nimport { verifyAccessToken } from '~/utils/jwt-utils';\nimport { TIME_ZONE_O"
  },
  {
    "path": "apps/backend-mock/api/upload.ts",
    "chars": 472,
    "preview": "import { eventHandler } from 'h3';\nimport { verifyAccessToken } from '~/utils/jwt-utils';\nimport { unAuthorizedResponse,"
  },
  {
    "path": "apps/backend-mock/api/user/info.ts",
    "chars": 360,
    "preview": "import { eventHandler } from 'h3';\nimport { verifyAccessToken } from '~/utils/jwt-utils';\nimport { unAuthorizedResponse,"
  },
  {
    "path": "apps/backend-mock/error.ts",
    "chars": 208,
    "preview": "import type { NitroErrorHandler } from 'nitropack';\n\nconst errorHandler: NitroErrorHandler = function (error, event) {\n "
  },
  {
    "path": "apps/backend-mock/middleware/1.api.ts",
    "chars": 640,
    "preview": "import { defineEventHandler } from 'h3';\nimport { forbiddenResponse, sleep } from '~/utils/response';\n\nexport default de"
  },
  {
    "path": "apps/backend-mock/nitro.config.ts",
    "chars": 702,
    "preview": "import errorHandler from './error';\n\nprocess.env.COMPATIBILITY_DATE = new Date().toISOString();\nexport default defineNit"
  },
  {
    "path": "apps/backend-mock/package.json",
    "chars": 414,
    "preview": "{\n  \"name\": \"@vben/backend-mock\",\n  \"version\": \"5.7.0\",\n  \"description\": \"\",\n  \"private\": true,\n  \"license\": \"MIT\",\n  \"a"
  },
  {
    "path": "apps/backend-mock/routes/[...].ts",
    "chars": 425,
    "preview": "import { defineEventHandler } from 'h3';\n\nexport default defineEventHandler(() => {\n  return `\n<h1>Hello Vben Admin</h1>"
  },
  {
    "path": "apps/backend-mock/tsconfig.build.json",
    "chars": 97,
    "preview": "{\n  \"extends\": \"./tsconfig.json\",\n  \"exclude\": [\"node_modules\", \"test\", \"dist\", \"**/*spec.ts\"]\n}\n"
  },
  {
    "path": "apps/backend-mock/tsconfig.json",
    "chars": 48,
    "preview": "{\n  \"extends\": \"./.nitro/types/tsconfig.json\"\n}\n"
  },
  {
    "path": "apps/backend-mock/utils/cookie-utils.ts",
    "chars": 708,
    "preview": "import type { EventHandlerRequest, H3Event } from 'h3';\n\nimport { deleteCookie, getCookie, setCookie } from 'h3';\n\nexpor"
  },
  {
    "path": "apps/backend-mock/utils/jwt-utils.ts",
    "chars": 1904,
    "preview": "import type { EventHandlerRequest, H3Event } from 'h3';\n\nimport type { UserInfo } from './mock-data';\n\nimport { getHeade"
  },
  {
    "path": "apps/backend-mock/utils/mock-data.ts",
    "chars": 9371,
    "preview": "export interface UserInfo {\n  id: number;\n  password: string;\n  realName: string;\n  roles: string[];\n  username: string;"
  },
  {
    "path": "apps/backend-mock/utils/response.ts",
    "chars": 1519,
    "preview": "import type { EventHandlerRequest, H3Event } from 'h3';\n\nimport { setResponseStatus } from 'h3';\n\nexport function useRes"
  },
  {
    "path": "apps/backend-mock/utils/timezone-utils.ts",
    "chars": 184,
    "preview": "let mockTimeZone: null | string = null;\n\nexport const setTimezone = (timeZone: string) => {\n  mockTimeZone = timeZone;\n}"
  },
  {
    "path": "apps/web-antd/index.html",
    "chars": 1189,
    "preview": "<!doctype html>\n<html lang=\"zh\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"I"
  },
  {
    "path": "apps/web-antd/package.json",
    "chars": 1424,
    "preview": "{\n  \"name\": \"@vben/web-antd\",\n  \"version\": \"5.7.0\",\n  \"homepage\": \"https://vben.pro\",\n  \"bugs\": \"https://github.com/vben"
  },
  {
    "path": "apps/web-antd/src/adapter/component/index.ts",
    "chars": 18710,
    "preview": "/**\n * 通用组件共同的使用的基础组件,原先放在 adapter/form 内部,限制了使用范围,这里提取出来,方便其他地方使用\n * 可用于 vben-form、vben-modal、vben-drawer 等组件使用,\n */\n\n/"
  },
  {
    "path": "apps/web-antd/src/adapter/form.ts",
    "chars": 1301,
    "preview": "import type {\n  VbenFormSchema as FormSchema,\n  VbenFormProps,\n} from '@vben/common-ui';\n\nimport type { ComponentType } "
  },
  {
    "path": "apps/web-antd/src/adapter/vxe-table.ts",
    "chars": 1718,
    "preview": "import type { VxeTableGridOptions } from '@vben/plugins/vxe-table';\n\nimport { h } from 'vue';\n\nimport { setupVbenVxeTabl"
  },
  {
    "path": "apps/web-antd/src/api/core/auth.ts",
    "chars": 945,
    "preview": "import { baseRequestClient, requestClient } from '#/api/request';\n\nexport namespace AuthApi {\n  /** 登录接口参数 */\n  export i"
  },
  {
    "path": "apps/web-antd/src/api/core/index.ts",
    "chars": 72,
    "preview": "export * from './auth';\nexport * from './menu';\nexport * from './user';\n"
  },
  {
    "path": "apps/web-antd/src/api/core/menu.ts",
    "chars": 246,
    "preview": "import type { RouteRecordStringComponent } from '@vben/types';\n\nimport { requestClient } from '#/api/request';\n\n/**\n * 获"
  },
  {
    "path": "apps/web-antd/src/api/core/user.ts",
    "chars": 207,
    "preview": "import type { UserInfo } from '@vben/types';\n\nimport { requestClient } from '#/api/request';\n\n/**\n * 获取用户信息\n */\nexport a"
  },
  {
    "path": "apps/web-antd/src/api/index.ts",
    "chars": 24,
    "preview": "export * from './core';\n"
  },
  {
    "path": "apps/web-antd/src/api/request.ts",
    "chars": 2915,
    "preview": "/**\n * 该文件可自行根据业务逻辑进行调整\n */\nimport type { RequestClientOptions } from '@vben/request';\n\nimport { useAppConfig } from '@v"
  },
  {
    "path": "apps/web-antd/src/app.vue",
    "chars": 830,
    "preview": "<script lang=\"ts\" setup>\nimport { computed } from 'vue';\n\nimport { useAntdDesignTokens } from '@vben/hooks';\nimport { pr"
  },
  {
    "path": "apps/web-antd/src/bootstrap.ts",
    "chars": 1773,
    "preview": "import { createApp, watchEffect } from 'vue';\n\nimport { registerAccessDirective } from '@vben/access';\nimport { register"
  },
  {
    "path": "apps/web-antd/src/layouts/auth.vue",
    "chars": 669,
    "preview": "<script lang=\"ts\" setup>\nimport { computed } from 'vue';\n\nimport { AuthPageLayout } from '@vben/layouts';\nimport { prefe"
  },
  {
    "path": "apps/web-antd/src/layouts/basic.vue",
    "chars": 4789,
    "preview": "<script lang=\"ts\" setup>\nimport type { NotificationItem } from '@vben/layouts';\n\nimport { computed, ref, watch } from 'v"
  },
  {
    "path": "apps/web-antd/src/layouts/index.ts",
    "chars": 230,
    "preview": "const BasicLayout = () => import('./basic.vue');\nconst AuthPageLayout = () => import('./auth.vue');\n\nconst IFrameView = "
  },
  {
    "path": "apps/web-antd/src/locales/README.md",
    "chars": 79,
    "preview": "# locale\n\n每个app使用的国际化可能不同,这里用于扩展国际化的功能,例如扩展 dayjs、antd组件库的多语言切换,以及app本身的国际化文件。\n"
  },
  {
    "path": "apps/web-antd/src/locales/index.ts",
    "chars": 2209,
    "preview": "import type { Locale } from 'ant-design-vue/es/locale';\n\nimport type { App } from 'vue';\n\nimport type { LocaleSetupOptio"
  },
  {
    "path": "apps/web-antd/src/locales/langs/en-US/demos.json",
    "chars": 338,
    "preview": "{\n  \"title\": \"Demos\",\n  \"antd\": \"Ant Design Vue\",\n  \"vben\": {\n    \"title\": \"Project\",\n    \"about\": \"About\",\n    \"documen"
  },
  {
    "path": "apps/web-antd/src/locales/langs/en-US/page.json",
    "chars": 310,
    "preview": "{\n  \"auth\": {\n    \"login\": \"Login\",\n    \"register\": \"Register\",\n    \"codeLogin\": \"Code Login\",\n    \"qrcodeLogin\": \"Qr Co"
  },
  {
    "path": "apps/web-antd/src/locales/langs/zh-CN/demos.json",
    "chars": 296,
    "preview": "{\n  \"title\": \"演示\",\n  \"antd\": \"Ant Design Vue\",\n  \"vben\": {\n    \"title\": \"项目\",\n    \"about\": \"关于\",\n    \"document\": \"文档\",\n "
  },
  {
    "path": "apps/web-antd/src/locales/langs/zh-CN/page.json",
    "chars": 255,
    "preview": "{\n  \"auth\": {\n    \"login\": \"登录\",\n    \"register\": \"注册\",\n    \"codeLogin\": \"验证码登录\",\n    \"qrcodeLogin\": \"二维码登录\",\n    \"forget"
  },
  {
    "path": "apps/web-antd/src/main.ts",
    "chars": 763,
    "preview": "import { initPreferences } from '@vben/preferences';\nimport { unmountGlobalLoading } from '@vben/utils';\n\nimport { overr"
  },
  {
    "path": "apps/web-antd/src/preferences.ts",
    "chars": 301,
    "preview": "import { defineOverridesPreferences } from '@vben/preferences';\n\n/**\n * @description 项目配置文件\n * 只需要覆盖项目中的一部分配置,不需要的配置不用覆盖"
  },
  {
    "path": "apps/web-antd/src/router/access.ts",
    "chars": 1110,
    "preview": "import type {\n  ComponentRecordType,\n  GenerateMenuAndRoutesOptions,\n} from '@vben/types';\n\nimport { generateAccessible "
  },
  {
    "path": "apps/web-antd/src/router/guard.ts",
    "chars": 3200,
    "preview": "import type { Router } from 'vue-router';\n\nimport { LOGIN_PATH } from '@vben/constants';\nimport { preferences } from '@v"
  },
  {
    "path": "apps/web-antd/src/router/index.ts",
    "chars": 855,
    "preview": "import {\n  createRouter,\n  createWebHashHistory,\n  createWebHistory,\n} from 'vue-router';\n\nimport { resetStaticRoutes } "
  },
  {
    "path": "apps/web-antd/src/router/routes/core.ts",
    "chars": 2334,
    "preview": "import type { RouteRecordRaw } from 'vue-router';\n\nimport { LOGIN_PATH } from '@vben/constants';\nimport { preferences } "
  },
  {
    "path": "apps/web-antd/src/router/routes/index.ts",
    "chars": 1259,
    "preview": "import type { RouteRecordRaw } from 'vue-router';\n\nimport { mergeRouteModules, traverseTreeValues } from '@vben/utils';\n"
  },
  {
    "path": "apps/web-antd/src/router/routes/modules/dashboard.ts",
    "chars": 884,
    "preview": "import type { RouteRecordRaw } from 'vue-router';\n\nimport { $t } from '#/locales';\n\nconst routes: RouteRecordRaw[] = [\n "
  },
  {
    "path": "apps/web-antd/src/router/routes/modules/demos.ts",
    "chars": 559,
    "preview": "import type { RouteRecordRaw } from 'vue-router';\n\nimport { $t } from '#/locales';\n\nconst routes: RouteRecordRaw[] = [\n "
  },
  {
    "path": "apps/web-antd/src/router/routes/modules/vben.ts",
    "chars": 2751,
    "preview": "import type { RouteRecordRaw } from 'vue-router';\n\nimport {\n  VBEN_ANTDV_NEXT_PREVIEW_URL,\n  VBEN_DOC_URL,\n  VBEN_ELE_PR"
  },
  {
    "path": "apps/web-antd/src/store/auth.ts",
    "chars": 2850,
    "preview": "import type { Recordable, UserInfo } from '@vben/types';\n\nimport { ref } from 'vue';\nimport { useRouter } from 'vue-rout"
  },
  {
    "path": "apps/web-antd/src/store/index.ts",
    "chars": 24,
    "preview": "export * from './auth';\n"
  },
  {
    "path": "apps/web-antd/src/views/_core/README.md",
    "chars": 50,
    "preview": "# \\_core\n\n此目录包含应用程序正常运行所需的基本视图。这些视图是应用程序布局中使用的视图。\n"
  },
  {
    "path": "apps/web-antd/src/views/_core/about/index.vue",
    "chars": 147,
    "preview": "<script lang=\"ts\" setup>\nimport { About } from '@vben/common-ui';\n\ndefineOptions({ name: 'About' });\n</script>\n\n<templat"
  },
  {
    "path": "apps/web-antd/src/views/_core/authentication/code-login.vue",
    "chars": 1717,
    "preview": "<script lang=\"ts\" setup>\nimport type { VbenFormSchema } from '@vben/common-ui';\nimport type { Recordable } from '@vben/t"
  },
  {
    "path": "apps/web-antd/src/views/_core/authentication/forget-password.vue",
    "chars": 970,
    "preview": "<script lang=\"ts\" setup>\nimport type { VbenFormSchema } from '@vben/common-ui';\nimport type { Recordable } from '@vben/t"
  },
  {
    "path": "apps/web-antd/src/views/_core/authentication/login.vue",
    "chars": 2454,
    "preview": "<script lang=\"ts\" setup>\nimport type { VbenFormSchema } from '@vben/common-ui';\nimport type { BasicOption } from '@vben/"
  },
  {
    "path": "apps/web-antd/src/views/_core/authentication/qrcode-login.vue",
    "chars": 264,
    "preview": "<script lang=\"ts\" setup>\nimport { AuthenticationQrCodeLogin } from '@vben/common-ui';\nimport { LOGIN_PATH } from '@vben/"
  },
  {
    "path": "apps/web-antd/src/views/_core/authentication/register.vue",
    "chars": 2600,
    "preview": "<script lang=\"ts\" setup>\nimport type { VbenFormSchema } from '@vben/common-ui';\nimport type { Recordable } from '@vben/t"
  },
  {
    "path": "apps/web-antd/src/views/_core/fallback/coming-soon.vue",
    "chars": 139,
    "preview": "<script lang=\"ts\" setup>\nimport { Fallback } from '@vben/common-ui';\n</script>\n\n<template>\n  <Fallback status=\"coming-so"
  },
  {
    "path": "apps/web-antd/src/views/_core/fallback/forbidden.vue",
    "chars": 176,
    "preview": "<script lang=\"ts\" setup>\nimport { Fallback } from '@vben/common-ui';\n\ndefineOptions({ name: 'Fallback403Demo' });\n</scri"
  },
  {
    "path": "apps/web-antd/src/views/_core/fallback/internal-error.vue",
    "chars": 176,
    "preview": "<script lang=\"ts\" setup>\nimport { Fallback } from '@vben/common-ui';\n\ndefineOptions({ name: 'Fallback500Demo' });\n</scri"
  },
  {
    "path": "apps/web-antd/src/views/_core/fallback/not-found.vue",
    "chars": 176,
    "preview": "<script lang=\"ts\" setup>\nimport { Fallback } from '@vben/common-ui';\n\ndefineOptions({ name: 'Fallback404Demo' });\n</scri"
  },
  {
    "path": "apps/web-antd/src/views/_core/fallback/offline.vue",
    "chars": 184,
    "preview": "<script lang=\"ts\" setup>\nimport { Fallback } from '@vben/common-ui';\n\ndefineOptions({ name: 'FallbackOfflineDemo' });\n</"
  },
  {
    "path": "apps/web-antd/src/views/_core/profile/base-setting.vue",
    "chars": 1259,
    "preview": "<script setup lang=\"ts\">\nimport type { BasicOption } from '@vben/types';\n\nimport type { VbenFormSchema } from '#/adapter"
  },
  {
    "path": "apps/web-antd/src/views/_core/profile/index.vue",
    "chars": 1134,
    "preview": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\n\nimport { Profile } from '@vben/common-ui';\nimport { useUserStore } "
  },
  {
    "path": "apps/web-antd/src/views/_core/profile/notification-setting.vue",
    "chars": 641,
    "preview": "<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\nimport { ProfileNotificationSetting } from '@vben/common-ui';\n"
  },
  {
    "path": "apps/web-antd/src/views/_core/profile/password-setting.vue",
    "chars": 1434,
    "preview": "<script setup lang=\"ts\">\nimport type { VbenFormSchema } from '#/adapter/form';\n\nimport { computed } from 'vue';\n\nimport "
  },
  {
    "path": "apps/web-antd/src/views/_core/profile/security-setting.vue",
    "chars": 906,
    "preview": "<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\nimport { ProfileSecuritySetting } from '@vben/common-ui';\n\ncon"
  },
  {
    "path": "apps/web-antd/src/views/dashboard/analytics/analytics-trends.vue",
    "chars": 2082,
    "preview": "<script lang=\"ts\" setup>\nimport type { EchartsUIType } from '@vben/plugins/echarts';\n\nimport { onMounted, ref } from 'vu"
  },
  {
    "path": "apps/web-antd/src/views/dashboard/analytics/analytics-visits-data.vue",
    "chars": 1563,
    "preview": "<script lang=\"ts\" setup>\nimport type { EchartsUIType } from '@vben/plugins/echarts';\n\nimport { onMounted, ref } from 'vu"
  },
  {
    "path": "apps/web-antd/src/views/dashboard/analytics/analytics-visits-sales.vue",
    "chars": 1061,
    "preview": "<script lang=\"ts\" setup>\nimport type { EchartsUIType } from '@vben/plugins/echarts';\n\nimport { onMounted, ref } from 'vu"
  },
  {
    "path": "apps/web-antd/src/views/dashboard/analytics/analytics-visits-source.vue",
    "chars": 1448,
    "preview": "<script lang=\"ts\" setup>\nimport type { EchartsUIType } from '@vben/plugins/echarts';\n\nimport { onMounted, ref } from 'vu"
  },
  {
    "path": "apps/web-antd/src/views/dashboard/analytics/analytics-visits.vue",
    "chars": 1104,
    "preview": "<script lang=\"ts\" setup>\nimport type { EchartsUIType } from '@vben/plugins/echarts';\n\nimport { onMounted, ref } from 'vu"
  },
  {
    "path": "apps/web-antd/src/views/dashboard/analytics/index.vue",
    "chars": 2074,
    "preview": "<script lang=\"ts\" setup>\nimport type { AnalysisOverviewItem } from '@vben/common-ui';\nimport type { TabOption } from '@v"
  },
  {
    "path": "apps/web-antd/src/views/dashboard/workspace/index.vue",
    "chars": 6007,
    "preview": "<script lang=\"ts\" setup>\nimport type {\n  WorkbenchProjectItem,\n  WorkbenchQuickNavItem,\n  WorkbenchTodoItem,\n  Workbench"
  },
  {
    "path": "apps/web-antd/src/views/demos/antd/index.vue",
    "chars": 1658,
    "preview": "<script lang=\"ts\" setup>\nimport { Page } from '@vben/common-ui';\n\nimport { Button, Card, message, notification, Space } "
  },
  {
    "path": "apps/web-antd/tsconfig.json",
    "chars": 291,
    "preview": "{\n  \"$schema\": \"https://json.schemastore.org/tsconfig\",\n  \"extends\": \"@vben/tsconfig/web-app.json\",\n  \"compilerOptions\":"
  },
  {
    "path": "apps/web-antd/tsconfig.node.json",
    "chars": 274,
    "preview": "{\n  \"$schema\": \"https://json.schemastore.org/tsconfig\",\n  \"extends\": \"@vben/tsconfig/node.json\",\n  \"compilerOptions\": {\n"
  },
  {
    "path": "apps/web-antd/vite.config.ts",
    "chars": 427,
    "preview": "import { defineConfig } from '@vben/vite-config';\n\nexport default defineConfig(async () => {\n  return {\n    application:"
  },
  {
    "path": "apps/web-antdv-next/index.html",
    "chars": 1189,
    "preview": "<!doctype html>\n<html lang=\"zh\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"I"
  },
  {
    "path": "apps/web-antdv-next/package.json",
    "chars": 1432,
    "preview": "{\n  \"name\": \"@vben/web-antdv-next\",\n  \"version\": \"5.7.0\",\n  \"homepage\": \"https://vben.pro\",\n  \"bugs\": \"https://github.co"
  },
  {
    "path": "apps/web-antdv-next/src/adapter/component/index.ts",
    "chars": 17076,
    "preview": "/**\n * 通用组件共同的使用的基础组件,原先放在 adapter/form 内部,限制了使用范围,这里提取出来,方便其他地方使用\n * 可用于 vben-form、vben-modal、vben-drawer 等组件使用,\n */\n\n/"
  },
  {
    "path": "apps/web-antdv-next/src/adapter/form.ts",
    "chars": 1301,
    "preview": "import type {\n  VbenFormSchema as FormSchema,\n  VbenFormProps,\n} from '@vben/common-ui';\n\nimport type { ComponentType } "
  },
  {
    "path": "apps/web-antdv-next/src/adapter/vxe-table.ts",
    "chars": 1714,
    "preview": "import type { VxeTableGridOptions } from '@vben/plugins/vxe-table';\n\nimport { h } from 'vue';\n\nimport { setupVbenVxeTabl"
  },
  {
    "path": "apps/web-antdv-next/src/api/core/auth.ts",
    "chars": 945,
    "preview": "import { baseRequestClient, requestClient } from '#/api/request';\n\nexport namespace AuthApi {\n  /** 登录接口参数 */\n  export i"
  },
  {
    "path": "apps/web-antdv-next/src/api/core/index.ts",
    "chars": 72,
    "preview": "export * from './auth';\nexport * from './menu';\nexport * from './user';\n"
  },
  {
    "path": "apps/web-antdv-next/src/api/core/menu.ts",
    "chars": 246,
    "preview": "import type { RouteRecordStringComponent } from '@vben/types';\n\nimport { requestClient } from '#/api/request';\n\n/**\n * 获"
  },
  {
    "path": "apps/web-antdv-next/src/api/core/user.ts",
    "chars": 207,
    "preview": "import type { UserInfo } from '@vben/types';\n\nimport { requestClient } from '#/api/request';\n\n/**\n * 获取用户信息\n */\nexport a"
  },
  {
    "path": "apps/web-antdv-next/src/api/index.ts",
    "chars": 24,
    "preview": "export * from './core';\n"
  },
  {
    "path": "apps/web-antdv-next/src/api/request.ts",
    "chars": 2911,
    "preview": "/**\n * 该文件可自行根据业务逻辑进行调整\n */\nimport type { RequestClientOptions } from '@vben/request';\n\nimport { useAppConfig } from '@v"
  },
  {
    "path": "apps/web-antdv-next/src/app.vue",
    "chars": 826,
    "preview": "<script lang=\"ts\" setup>\nimport { computed } from 'vue';\n\nimport { useAntdDesignTokens } from '@vben/hooks';\nimport { pr"
  },
  {
    "path": "apps/web-antdv-next/src/bootstrap.ts",
    "chars": 1779,
    "preview": "import { createApp, watchEffect } from 'vue';\n\nimport { registerAccessDirective } from '@vben/access';\nimport { register"
  },
  {
    "path": "apps/web-antdv-next/src/layouts/auth.vue",
    "chars": 669,
    "preview": "<script lang=\"ts\" setup>\nimport { computed } from 'vue';\n\nimport { AuthPageLayout } from '@vben/layouts';\nimport { prefe"
  },
  {
    "path": "apps/web-antdv-next/src/layouts/basic.vue",
    "chars": 4789,
    "preview": "<script lang=\"ts\" setup>\nimport type { NotificationItem } from '@vben/layouts';\n\nimport { computed, ref, watch } from 'v"
  },
  {
    "path": "apps/web-antdv-next/src/layouts/index.ts",
    "chars": 230,
    "preview": "const BasicLayout = () => import('./basic.vue');\nconst AuthPageLayout = () => import('./auth.vue');\n\nconst IFrameView = "
  },
  {
    "path": "apps/web-antdv-next/src/locales/README.md",
    "chars": 79,
    "preview": "# locale\n\n每个app使用的国际化可能不同,这里用于扩展国际化的功能,例如扩展 dayjs、antd组件库的多语言切换,以及app本身的国际化文件。\n"
  },
  {
    "path": "apps/web-antdv-next/src/locales/index.ts",
    "chars": 2209,
    "preview": "import type { Locale } from 'antdv-next/dist/locale/index';\n\nimport type { App } from 'vue';\n\nimport type { LocaleSetupO"
  },
  {
    "path": "apps/web-antdv-next/src/locales/langs/en-US/demos.json",
    "chars": 334,
    "preview": "{\n  \"title\": \"Demos\",\n  \"antd\": \"Antdv Next\",\n  \"vben\": {\n    \"title\": \"Project\",\n    \"about\": \"About\",\n    \"document\": "
  },
  {
    "path": "apps/web-antdv-next/src/locales/langs/en-US/page.json",
    "chars": 310,
    "preview": "{\n  \"auth\": {\n    \"login\": \"Login\",\n    \"register\": \"Register\",\n    \"codeLogin\": \"Code Login\",\n    \"qrcodeLogin\": \"Qr Co"
  },
  {
    "path": "apps/web-antdv-next/src/locales/langs/zh-CN/demos.json",
    "chars": 292,
    "preview": "{\n  \"title\": \"演示\",\n  \"antd\": \"Antdv Next\",\n  \"vben\": {\n    \"title\": \"项目\",\n    \"about\": \"关于\",\n    \"document\": \"文档\",\n    \""
  },
  {
    "path": "apps/web-antdv-next/src/locales/langs/zh-CN/page.json",
    "chars": 255,
    "preview": "{\n  \"auth\": {\n    \"login\": \"登录\",\n    \"register\": \"注册\",\n    \"codeLogin\": \"验证码登录\",\n    \"qrcodeLogin\": \"二维码登录\",\n    \"forget"
  },
  {
    "path": "apps/web-antdv-next/src/main.ts",
    "chars": 763,
    "preview": "import { initPreferences } from '@vben/preferences';\nimport { unmountGlobalLoading } from '@vben/utils';\n\nimport { overr"
  },
  {
    "path": "apps/web-antdv-next/src/preferences.ts",
    "chars": 301,
    "preview": "import { defineOverridesPreferences } from '@vben/preferences';\n\n/**\n * @description 项目配置文件\n * 只需要覆盖项目中的一部分配置,不需要的配置不用覆盖"
  },
  {
    "path": "apps/web-antdv-next/src/router/access.ts",
    "chars": 1106,
    "preview": "import type {\n  ComponentRecordType,\n  GenerateMenuAndRoutesOptions,\n} from '@vben/types';\n\nimport { generateAccessible "
  },
  {
    "path": "apps/web-antdv-next/src/router/guard.ts",
    "chars": 3200,
    "preview": "import type { Router } from 'vue-router';\n\nimport { LOGIN_PATH } from '@vben/constants';\nimport { preferences } from '@v"
  },
  {
    "path": "apps/web-antdv-next/src/router/index.ts",
    "chars": 855,
    "preview": "import {\n  createRouter,\n  createWebHashHistory,\n  createWebHistory,\n} from 'vue-router';\n\nimport { resetStaticRoutes } "
  },
  {
    "path": "apps/web-antdv-next/src/router/routes/core.ts",
    "chars": 2334,
    "preview": "import type { RouteRecordRaw } from 'vue-router';\n\nimport { LOGIN_PATH } from '@vben/constants';\nimport { preferences } "
  },
  {
    "path": "apps/web-antdv-next/src/router/routes/index.ts",
    "chars": 1259,
    "preview": "import type { RouteRecordRaw } from 'vue-router';\n\nimport { mergeRouteModules, traverseTreeValues } from '@vben/utils';\n"
  },
  {
    "path": "apps/web-antdv-next/src/router/routes/modules/dashboard.ts",
    "chars": 884,
    "preview": "import type { RouteRecordRaw } from 'vue-router';\n\nimport { $t } from '#/locales';\n\nconst routes: RouteRecordRaw[] = [\n "
  },
  {
    "path": "apps/web-antdv-next/src/router/routes/modules/demos.ts",
    "chars": 564,
    "preview": "import type { RouteRecordRaw } from 'vue-router';\n\nimport { $t } from '#/locales';\n\nconst routes: RouteRecordRaw[] = [\n "
  },
  {
    "path": "apps/web-antdv-next/src/router/routes/modules/vben.ts",
    "chars": 2713,
    "preview": "import type { RouteRecordRaw } from 'vue-router';\n\nimport {\n  VBEN_ANT_PREVIEW_URL,\n  VBEN_DOC_URL,\n  VBEN_ELE_PREVIEW_U"
  },
  {
    "path": "apps/web-antdv-next/src/store/auth.ts",
    "chars": 2844,
    "preview": "import type { Recordable, UserInfo } from '@vben/types';\n\nimport { ref } from 'vue';\nimport { useRouter } from 'vue-rout"
  },
  {
    "path": "apps/web-antdv-next/src/store/index.ts",
    "chars": 24,
    "preview": "export * from './auth';\n"
  },
  {
    "path": "apps/web-antdv-next/src/views/_core/README.md",
    "chars": 50,
    "preview": "# \\_core\n\n此目录包含应用程序正常运行所需的基本视图。这些视图是应用程序布局中使用的视图。\n"
  },
  {
    "path": "apps/web-antdv-next/src/views/_core/about/index.vue",
    "chars": 147,
    "preview": "<script lang=\"ts\" setup>\nimport { About } from '@vben/common-ui';\n\ndefineOptions({ name: 'About' });\n</script>\n\n<templat"
  },
  {
    "path": "apps/web-antdv-next/src/views/_core/authentication/code-login.vue",
    "chars": 1717,
    "preview": "<script lang=\"ts\" setup>\nimport type { VbenFormSchema } from '@vben/common-ui';\nimport type { Recordable } from '@vben/t"
  },
  {
    "path": "apps/web-antdv-next/src/views/_core/authentication/forget-password.vue",
    "chars": 970,
    "preview": "<script lang=\"ts\" setup>\nimport type { VbenFormSchema } from '@vben/common-ui';\nimport type { Recordable } from '@vben/t"
  },
  {
    "path": "apps/web-antdv-next/src/views/_core/authentication/login.vue",
    "chars": 2454,
    "preview": "<script lang=\"ts\" setup>\nimport type { VbenFormSchema } from '@vben/common-ui';\nimport type { BasicOption } from '@vben/"
  },
  {
    "path": "apps/web-antdv-next/src/views/_core/authentication/qrcode-login.vue",
    "chars": 264,
    "preview": "<script lang=\"ts\" setup>\nimport { AuthenticationQrCodeLogin } from '@vben/common-ui';\nimport { LOGIN_PATH } from '@vben/"
  },
  {
    "path": "apps/web-antdv-next/src/views/_core/authentication/register.vue",
    "chars": 2600,
    "preview": "<script lang=\"ts\" setup>\nimport type { VbenFormSchema } from '@vben/common-ui';\nimport type { Recordable } from '@vben/t"
  },
  {
    "path": "apps/web-antdv-next/src/views/_core/fallback/coming-soon.vue",
    "chars": 139,
    "preview": "<script lang=\"ts\" setup>\nimport { Fallback } from '@vben/common-ui';\n</script>\n\n<template>\n  <Fallback status=\"coming-so"
  },
  {
    "path": "apps/web-antdv-next/src/views/_core/fallback/forbidden.vue",
    "chars": 176,
    "preview": "<script lang=\"ts\" setup>\nimport { Fallback } from '@vben/common-ui';\n\ndefineOptions({ name: 'Fallback403Demo' });\n</scri"
  },
  {
    "path": "apps/web-antdv-next/src/views/_core/fallback/internal-error.vue",
    "chars": 176,
    "preview": "<script lang=\"ts\" setup>\nimport { Fallback } from '@vben/common-ui';\n\ndefineOptions({ name: 'Fallback500Demo' });\n</scri"
  },
  {
    "path": "apps/web-antdv-next/src/views/_core/fallback/not-found.vue",
    "chars": 176,
    "preview": "<script lang=\"ts\" setup>\nimport { Fallback } from '@vben/common-ui';\n\ndefineOptions({ name: 'Fallback404Demo' });\n</scri"
  },
  {
    "path": "apps/web-antdv-next/src/views/_core/fallback/offline.vue",
    "chars": 184,
    "preview": "<script lang=\"ts\" setup>\nimport { Fallback } from '@vben/common-ui';\n\ndefineOptions({ name: 'FallbackOfflineDemo' });\n</"
  },
  {
    "path": "apps/web-antdv-next/src/views/_core/profile/base-setting.vue",
    "chars": 1259,
    "preview": "<script setup lang=\"ts\">\nimport type { BasicOption } from '@vben/types';\n\nimport type { VbenFormSchema } from '#/adapter"
  },
  {
    "path": "apps/web-antdv-next/src/views/_core/profile/index.vue",
    "chars": 1134,
    "preview": "<script setup lang=\"ts\">\nimport { ref } from 'vue';\n\nimport { Profile } from '@vben/common-ui';\nimport { useUserStore } "
  },
  {
    "path": "apps/web-antdv-next/src/views/_core/profile/notification-setting.vue",
    "chars": 641,
    "preview": "<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\nimport { ProfileNotificationSetting } from '@vben/common-ui';\n"
  },
  {
    "path": "apps/web-antdv-next/src/views/_core/profile/password-setting.vue",
    "chars": 1430,
    "preview": "<script setup lang=\"ts\">\nimport type { VbenFormSchema } from '#/adapter/form';\n\nimport { computed } from 'vue';\n\nimport "
  },
  {
    "path": "apps/web-antdv-next/src/views/_core/profile/security-setting.vue",
    "chars": 906,
    "preview": "<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\nimport { ProfileSecuritySetting } from '@vben/common-ui';\n\ncon"
  },
  {
    "path": "apps/web-antdv-next/src/views/dashboard/analytics/analytics-trends.vue",
    "chars": 2082,
    "preview": "<script lang=\"ts\" setup>\nimport type { EchartsUIType } from '@vben/plugins/echarts';\n\nimport { onMounted, ref } from 'vu"
  },
  {
    "path": "apps/web-antdv-next/src/views/dashboard/analytics/analytics-visits-data.vue",
    "chars": 1563,
    "preview": "<script lang=\"ts\" setup>\nimport type { EchartsUIType } from '@vben/plugins/echarts';\n\nimport { onMounted, ref } from 'vu"
  },
  {
    "path": "apps/web-antdv-next/src/views/dashboard/analytics/analytics-visits-sales.vue",
    "chars": 1061,
    "preview": "<script lang=\"ts\" setup>\nimport type { EchartsUIType } from '@vben/plugins/echarts';\n\nimport { onMounted, ref } from 'vu"
  },
  {
    "path": "apps/web-antdv-next/src/views/dashboard/analytics/analytics-visits-source.vue",
    "chars": 1448,
    "preview": "<script lang=\"ts\" setup>\nimport type { EchartsUIType } from '@vben/plugins/echarts';\n\nimport { onMounted, ref } from 'vu"
  },
  {
    "path": "apps/web-antdv-next/src/views/dashboard/analytics/analytics-visits.vue",
    "chars": 1104,
    "preview": "<script lang=\"ts\" setup>\nimport type { EchartsUIType } from '@vben/plugins/echarts';\n\nimport { onMounted, ref } from 'vu"
  }
]

// ... and 1452 more files (download for full content)

About this extraction

This page contains the full source code of the vbenjs/vue-vben-admin GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1652 files (3.0 MB), approximately 869.6k tokens, and a symbol index with 1098 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!