浏览代码

wip: docs developing

kailong321200875 3 年之前
父节点
当前提交
e86bc1e13c
共有 83 个文件被更改,包括 10043 次插入1 次删除
  1. 17 0
      .gitignore
  2. 9 0
      .prettierignore
  3. 211 0
      .vitepress/config.js
  4. 200 0
      .vitepress/theme-default/Layout.vue
  5. 20 0
      .vitepress/theme-default/NotFound.vue
  6. 181 0
      .vitepress/theme-default/components/AlgoliaSearchBox.vue
  7. 148 0
      .vitepress/theme-default/components/BuySellAds.vue
  8. 99 0
      .vitepress/theme-default/components/CarbonAds.vue
  9. 13 0
      .vitepress/theme-default/components/DarkModeSwitch.vue
  10. 38 0
      .vitepress/theme-default/components/EditLink.vue
  11. 38 0
      .vitepress/theme-default/components/Home.vue
  12. 138 0
      .vitepress/theme-default/components/HomeFeatures.vue
  13. 44 0
      .vitepress/theme-default/components/HomeFooter.vue
  14. 168 0
      .vitepress/theme-default/components/HomeHero.vue
  15. 59 0
      .vitepress/theme-default/components/LastUpdated.vue
  16. 95 0
      .vitepress/theme-default/components/NavBar.vue
  17. 33 0
      .vitepress/theme-default/components/NavBarTitle.vue
  18. 135 0
      .vitepress/theme-default/components/NavDropdownLink.vue
  19. 76 0
      .vitepress/theme-default/components/NavDropdownLinkItem.vue
  20. 61 0
      .vitepress/theme-default/components/NavLink.vue
  21. 55 0
      .vitepress/theme-default/components/NavLinks.vue
  22. 87 0
      .vitepress/theme-default/components/NextAndPrevLinks.vue
  23. 58 0
      .vitepress/theme-default/components/Page.vue
  24. 41 0
      .vitepress/theme-default/components/PageFooter.vue
  25. 65 0
      .vitepress/theme-default/components/SideBar.vue
  26. 93 0
      .vitepress/theme-default/components/SideBarLink.ts
  27. 12 0
      .vitepress/theme-default/components/SideBarLinks.vue
  28. 75 0
      .vitepress/theme-default/components/Slugs.vue
  29. 46 0
      .vitepress/theme-default/components/ToggleSideBarButton.vue
  30. 7 0
      .vitepress/theme-default/components/icons/ArrowLeft.vue
  31. 7 0
      .vitepress/theme-default/components/icons/ArrowRight.vue
  32. 31 0
      .vitepress/theme-default/components/icons/OutboundLink.vue
  33. 134 0
      .vitepress/theme-default/composables/activeSidebarLink.ts
  34. 6 0
      .vitepress/theme-default/composables/dark.ts
  35. 91 0
      .vitepress/theme-default/composables/editLink.ts
  36. 61 0
      .vitepress/theme-default/composables/nav.ts
  37. 51 0
      .vitepress/theme-default/composables/navLink.ts
  38. 49 0
      .vitepress/theme-default/composables/nextAndPrevLinks.ts
  39. 51 0
      .vitepress/theme-default/composables/repo.ts
  40. 77 0
      .vitepress/theme-default/composables/sideBar.ts
  41. 13 0
      .vitepress/theme-default/composables/url.ts
  42. 146 0
      .vitepress/theme-default/config.ts
  43. 16 0
      .vitepress/theme-default/index.ts
  44. 294 0
      .vitepress/theme-default/styles/code.css
  45. 70 0
      .vitepress/theme-default/styles/custom-blocks.css
  46. 236 0
      .vitepress/theme-default/styles/layout.css
  47. 107 0
      .vitepress/theme-default/styles/sidebar-links.css
  48. 74 0
      .vitepress/theme-default/styles/vars.css
  49. 66 0
      .vitepress/theme-default/support/sideBar.ts
  50. 83 0
      .vitepress/theme-default/utils.ts
  51. 14 0
      .vitepress/theme/index.ts
  52. 292 0
      .vitepress/theme/styles/code-theme.css
  53. 125 0
      .vitepress/theme/styles/custom.css
  54. 63 0
      .vitepress/theme/styles/layout.css
  55. 55 0
      .vitepress/theme/styles/var.css
  56. 14 0
      README.md
  57. 160 0
      components/form.md
  58. 34 0
      components/icon.md
  59. 5 0
      components/introduction.md
  60. 5 0
      dep/dark.md
  61. 165 0
      dep/i18n.md
  62. 154 0
      dep/lint.md
  63. 二进制
      favicon.ico
  64. 221 0
      guide/auth.md
  65. 70 0
      guide/component.md
  66. 57 0
      guide/deploy.md
  67. 38 0
      guide/design.md
  68. 151 0
      guide/index.md
  69. 93 0
      guide/introduction.md
  70. 251 0
      guide/mock.md
  71. 235 0
      guide/router.md
  72. 327 0
      guide/settings.md
  73. 0 1
      index.html
  74. 24 0
      index.md
  75. 25 0
      package.json
  76. 1927 0
      pnpm-lock.yaml
  77. 20 0
      prettier.config.js
  78. 二进制
      public/images/i18n.png
  79. 二进制
      public/logo.png
  80. 19 0
      tsconfig.json
  81. 27 0
      vite.config.ts
  82. 30 0
      windi.config.ts
  83. 1457 0
      yarn.lock

+ 17 - 0
.gitignore

@@ -0,0 +1,17 @@
+node_modules
+.DS_Store
+dist
+.npmrc
+Thumbs.db
+db.json
+*.log
+.deploy*/
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Editor directories and files
+.idea

+ 9 - 0
.prettierignore

@@ -0,0 +1,9 @@
+/dist/*
+.local
+.output.js
+/node_modules/**
+
+**/*.svg
+**/*.sh
+
+/public/*

+ 211 - 0
.vitepress/config.js

@@ -0,0 +1,211 @@
+// @ts-check
+/**
+ * @type {import('vitepress').UserConfig}
+ */
+module.exports = {
+  base: '/',
+  title: 'vue-element-plus-admin',
+  lang: 'zh-CN',
+  description: '一套基于vue3、element-plus、typesScript4、vite2的后台集成方案',
+  head: createHead(),
+  themeConfig: {
+    repo: 'kailong321200875/vue-element-plus-adminc',
+    docsRepo: 'kailong321200875/vue-element-plus-admin-doc',
+    logo: '/logo.png',
+    docsBranch: 'main',
+    editLinks: true,
+    editLinkText: '为此页提供修改建议',
+    nav: createNav(),
+    sidebar: createSidebar(),
+  },
+};
+
+/**
+ * @type {()=>import('vitepress').HeadConfig[]}
+ */
+
+function createHead() {
+  return [
+    ['meta', { name: 'author', content: 'Archer' }],
+    [
+      'meta',
+      {
+        name: 'keywords',
+        content: 'vue-element-plus-admin, vitejs, vite, element-plus, vue',
+      },
+    ],
+    ['link', { rel: 'icon', type: 'image/svg+xml', href: '/logo.svg' }],
+    [
+      'meta',
+      {
+        name: 'viewport',
+        content:
+          'width=device-width,initial-scale=1,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no',
+      },
+    ],
+    ['meta', { name: 'keywords', content: 'vue-element-plus-admin-doc' }],
+    ['link', { rel: 'icon', href: '/favicon.ico' }],
+  ];
+}
+
+/**
+ * @type {()=>import('./theme-default/config').DefaultTheme.NavItem[]}
+ */
+function createNav() {
+  return [
+    {
+      text: '指南',
+      link: '/guide/',
+      items: [
+        {
+          text: '指南',
+          link: '/guide/introduction',
+        },
+        {
+          text: '深入',
+          link: '/dep/i18n',
+        },
+      ],
+    },
+    {
+      text: '组件',
+      link: '/components/',
+      items: [
+        {
+          text: '介绍',
+          link: '/components/introduction',
+        },
+        {
+          text: '功能组件',
+          link: '/components/icon',
+        },
+      ],
+    },
+    {
+      text: '相关链接',
+      items: [
+        {
+          text: '完整版预览',
+          link: 'https://element-plus-admin.cn/',
+        },
+        {
+          text: '完整版源码',
+          link: 'https://github.com/kailong321200875/vue-element-plus-admin',
+        },
+        {
+          text: '文档源码',
+          link: 'https://github.com/kailong321200875/vue-element-plus-admin-doc',
+        },
+        {
+          text: '更新日志',
+          link: 'https://github.com/kailong321200875/vue-element-plus-admin/blob/master/CHANGELOG.zh_CN.md',
+        },
+      ],
+    },
+  ];
+}
+
+function createSidebar() {
+  return {
+    '/components/': [
+      {
+        text: '组件',
+        children: [
+          {
+            text: '前言',
+            link: '/components/introduction',
+          },
+        ],
+      },
+      {
+        text: '全局组件',
+        children: [
+          {
+            text: 'Icon 图标组件',
+            link: '/components/icon',
+          },
+        ],
+      },
+      {
+        text: '常用组件',
+        children: [
+          {
+            text: 'Form 表单组件',
+            link: '/components/form',
+          },
+        ],
+      },
+    ],
+    '/': [
+      {
+        text: '指南',
+        children: [
+          {
+            text: '介绍',
+            link: '/guide/introduction',
+          },
+          {
+            text: '开始',
+            link: '/guide/',
+          },
+          {
+            text: '项目配置',
+            link: '/guide/settings',
+          },
+          {
+            text: '路由',
+            link: '/guide/router',
+          },
+          {
+            text: '权限',
+            link: '/guide/auth',
+          },
+          {
+            text: 'Mock&联调',
+            link: '/guide/mock',
+          },
+          {
+            text: '组件注册',
+            link: '/guide/component',
+          },
+          {
+            text: '样式',
+            link: '/guide/design',
+          },
+          {
+            text: '构建&部署',
+            link: '/guide/deploy',
+          },
+        ],
+      },
+      {
+        text: '深入',
+        children: [
+          {
+            text: '国际化',
+            link: '/dep/i18n',
+          },
+          {
+            text: '项目规范',
+            link: '/dep/lint',
+          },
+          {
+            text: '黑暗主题',
+            link: '/dep/dark',
+          },
+        ],
+      },
+    ],
+  };
+}
+
+// /**
+//  * @type {(namespace:string,items:string[])=>string[]}
+//  */
+// function urlWrapper(namespace, items) {
+//   return items.map((item) => namespace + item);
+// }
+
+// function getGuildNav() {
+//   return urlWrapper('/guide', ['/']);
+// }

+ 200 - 0
.vitepress/theme-default/Layout.vue

@@ -0,0 +1,200 @@
+<template>
+  <div class="theme" :class="pageClasses">
+    <NavBar v-if="showNavbar" @toggle="toggleSidebar">
+      <template #search>
+        <slot name="navbar-search">
+          <AlgoliaSearchBox
+            v-if="theme.algolia"
+            :options="theme.algolia"
+            :multilang="!!theme.locales"
+            :key="siteRouteData.lang"
+          />
+        </slot>
+      </template>
+    </NavBar>
+
+    <SideBar :open="openSideBar">
+      <template #sidebar-top>
+        <slot name="sidebar-top" />
+      </template>
+      <template #sidebar-bottom>
+        <slot name="sidebar-bottom" />
+      </template>
+    </SideBar>
+    <!-- TODO: make this button accessible -->
+    <div class="sidebar-mask" @click="toggleSidebar(false)" />
+
+    <Content v-if="isCustomLayout" />
+
+    <Home v-else-if="enableHome">
+      <template #hero>
+        <slot name="home-hero" />
+      </template>
+      <template #features>
+        <slot name="home-features" />
+      </template>
+      <template #footer>
+        <slot name="home-footer" />
+      </template>
+    </Home>
+
+    <Page v-else>
+      <template #top>
+        <slot name="page-top-ads">
+          <div
+            id="ads-container"
+            v-if="theme.carbonAds && theme.carbonAds.carbon"
+          >
+            <CarbonAds
+              :key="'carbon' + page.relativePath"
+              :code="theme.carbonAds.carbon"
+              :placement="theme.carbonAds.placement"
+            />
+          </div>
+        </slot>
+        <slot name="page-top" />
+      </template>
+      <template #bottom>
+        <slot name="page-bottom" />
+        <slot name="page-bottom-ads">
+          <BuySellAds
+            v-if="theme.carbonAds && theme.carbonAds.custom"
+            :key="'custom' + page.relativePath"
+            :code="theme.carbonAds.custom"
+            :placement="theme.carbonAds.placement"
+          />
+        </slot>
+      </template>
+    </Page>
+  </div>
+
+  <Debug />
+</template>
+
+<script setup lang="ts">
+import { ref, computed, watch, defineAsyncComponent } from 'vue'
+import {
+  useRoute,
+  useSiteData,
+  usePageData,
+  useSiteDataByRoute
+} from 'vitepress'
+import { isSideBarEmpty, getSideBarConfig } from './support/sideBar'
+import type { DefaultTheme } from './config'
+
+// components
+import NavBar from './components/NavBar.vue'
+import SideBar from './components/SideBar.vue'
+import Page from './components/Page.vue'
+
+const Home = defineAsyncComponent(() => import('./components/Home.vue'))
+
+const NoopComponent = () => null
+
+const CarbonAds = __CARBON__
+  ? defineAsyncComponent(() => import('./components/CarbonAds.vue'))
+  : NoopComponent
+const BuySellAds = __BSA__
+  ? defineAsyncComponent(() => import('./components/BuySellAds.vue'))
+  : NoopComponent
+const AlgoliaSearchBox = __ALGOLIA__
+  ? defineAsyncComponent(() => import('./components/AlgoliaSearchBox.vue'))
+  : NoopComponent
+
+// generic state
+const route = useRoute()
+const siteData = useSiteData<DefaultTheme.Config>()
+const siteRouteData = useSiteDataByRoute()
+const theme = computed(() => siteData.value.themeConfig)
+const page = usePageData()
+
+// custom layout
+const isCustomLayout = computed(() => !!route.data.frontmatter.customLayout)
+// home
+const enableHome = computed(() => !!route.data.frontmatter.home)
+
+// navbar
+const showNavbar = computed(() => {
+  const { themeConfig } = siteRouteData.value
+  const { frontmatter } = route.data
+  if (frontmatter.navbar === false || themeConfig.navbar === false) {
+    return false
+  }
+  return (
+    siteData.value.title ||
+    themeConfig.logo ||
+    themeConfig.repo ||
+    themeConfig.nav
+  )
+})
+
+// sidebar
+const openSideBar = ref(false)
+
+const showSidebar = computed(() => {
+  const { frontmatter } = route.data
+
+  if (frontmatter.home || frontmatter.sidebar === false) {
+    return false
+  }
+
+  const { themeConfig } = siteRouteData.value
+
+  return !isSideBarEmpty(
+    getSideBarConfig(themeConfig.sidebar, route.data.relativePath)
+  )
+})
+
+const toggleSidebar = (to?: boolean) => {
+  openSideBar.value = typeof to === 'boolean' ? to : !openSideBar.value
+}
+
+const hideSidebar = toggleSidebar.bind(null, false)
+// close the sidebar when navigating to a different location
+watch(route, hideSidebar)
+// TODO: route only changes when the pathname changes
+// listening to hashchange does nothing because it's prevented in router
+
+// page classes
+const pageClasses = computed(() => {
+  return [
+    {
+      'no-navbar': !showNavbar.value,
+      'sidebar-open': openSideBar.value,
+      'no-sidebar': !showSidebar.value
+    }
+  ]
+})
+</script>
+
+<style>
+#ads-container {
+  margin: 0 auto;
+}
+
+@media (min-width: 420px) {
+  #ads-container {
+    position: relative;
+    right: 0;
+    float: right;
+    margin: -8px -8px 24px 24px;
+    width: 146px;
+  }
+}
+
+@media (max-width: 420px) {
+  #ads-container {
+    /* Avoid layout shift */
+    height: 105px;
+    margin: 1.75rem 0;
+  }
+}
+
+@media (min-width: 1400px) {
+  #ads-container {
+    position: fixed;
+    right: 8px;
+    bottom: 8px;
+  }
+}
+</style>

+ 20 - 0
.vitepress/theme-default/NotFound.vue

@@ -0,0 +1,20 @@
+<template>
+  <div class="theme">
+    <h1>404</h1>
+    <blockquote>{{ getMsg() }}</blockquote>
+    <a :href="$site.base" aria-label="go to home">Take me home.</a>
+  </div>
+</template>
+
+<script setup lang="ts">
+const msgs = [
+  `There's nothing here.`,
+  `How did we get here?`,
+  `That's a Four-Oh-Four.`,
+  `Looks like we've got some broken links.`
+]
+
+function getMsg() {
+  return msgs[Math.floor(Math.random() * msgs.length)]
+}
+</script>

+ 181 - 0
.vitepress/theme-default/components/AlgoliaSearchBox.vue

@@ -0,0 +1,181 @@
+<template>
+  <div class="algolia-search-box" id="docsearch" />
+</template>
+
+<script setup lang="ts">
+import '@docsearch/css'
+import { useRoute, useRouter } from 'vitepress'
+import { defineProps, getCurrentInstance, onMounted, watch } from 'vue'
+import docsearch from '@docsearch/js'
+import type { DefaultTheme } from '../config'
+import type { DocSearchHit } from '@docsearch/react/dist/esm/types'
+import { useSiteDataByRoute } from 'vitepress'
+
+const siteData = useSiteDataByRoute()
+
+const props = defineProps<{
+  options: DefaultTheme.AlgoliaSearchOptions
+  multilang?: boolean
+}>()
+
+const vm = getCurrentInstance()
+const route = useRoute()
+const router = useRouter()
+
+watch(
+  () => props.options,
+  (value) => {
+    update(value)
+  }
+)
+
+onMounted(() => {
+  initialize(props.options)
+})
+
+function isSpecialClick(event: MouseEvent) {
+  return (
+    event.button === 1 ||
+    event.altKey ||
+    event.ctrlKey ||
+    event.metaKey ||
+    event.shiftKey
+  )
+}
+
+function getRelativePath(absoluteUrl: string) {
+  const { pathname, hash } = new URL(absoluteUrl)
+
+  return pathname + hash
+}
+
+function update(options: any) {
+  if (vm && vm.vnode.el) {
+    vm.vnode.el.innerHTML =
+      '<div class="algolia-search-box" id="docsearch"></div>'
+    initialize(options)
+  }
+}
+
+function initialize(userOptions: any) {
+  // if the user has multiple locales, the search results should be filtered
+  // based on the language
+  const facetFilters = props.multilang
+    ? ['language:' + siteData.value.lang]
+    : []
+
+  docsearch(
+    Object.assign({}, userOptions, {
+      container: '#docsearch',
+
+      searchParameters: Object.assign({}, userOptions.searchParameters, {
+        // pass a custom lang facetFilter to allow multiple language search
+        // https://github.com/algolia/docsearch-configs/pull/3942
+        facetFilters: facetFilters.concat(
+          userOptions.searchParameters?.facetFilters || []
+        )
+      }),
+
+      navigator: {
+        navigate: ({ suggestionUrl }: { suggestionUrl: string }) => {
+          const { pathname: hitPathname } = new URL(
+            window.location.origin + suggestionUrl
+          )
+
+          // Router doesn't handle same-page navigation so we use the native
+          // browser location API for anchor navigation
+          if (route.path === hitPathname) {
+            window.location.assign(window.location.origin + suggestionUrl)
+          } else {
+            router.go(suggestionUrl)
+          }
+        }
+      },
+
+      transformItems: (items: DocSearchHit[]) => {
+        return items.map((item) => {
+          return Object.assign({}, item, {
+            url: getRelativePath(item.url)
+          })
+        })
+      },
+
+      hitComponent: ({
+        hit,
+        children
+      }: {
+        hit: DocSearchHit
+        children: any
+      }) => {
+        const relativeHit = hit.url.startsWith('http')
+          ? getRelativePath(hit.url as string)
+          : hit.url
+
+        return {
+          type: 'a',
+          ref: undefined,
+          constructor: undefined,
+          key: undefined,
+          props: {
+            href: hit.url,
+            onClick: (event: MouseEvent) => {
+              if (isSpecialClick(event)) {
+                return
+              }
+
+              // we rely on the native link scrolling when user is already on
+              // the right anchor because Router doesn't support duplicated
+              // history entries
+              if (route.path === relativeHit) {
+                return
+              }
+
+              // if the hits goes to another page, we prevent the native link
+              // behavior to leverage the Router loading feature
+              if (route.path !== relativeHit) {
+                event.preventDefault()
+              }
+
+              router.go(relativeHit)
+            },
+            children
+          }
+        }
+      }
+    })
+  )
+}
+</script>
+
+<style>
+.algolia-search-box {
+  padding-top: 1px;
+}
+
+@media (min-width: 720px) {
+  .algolia-search-box {
+    padding-left: 8px;
+  }
+}
+
+@media (min-width: 751px) {
+  .algolia-search-box {
+    min-width: 176.3px; /* avoid layout shift */
+  }
+
+  .algolia-search-box .DocSearch-Button-Placeholder {
+    padding-left: 8px;
+    font-size: 0.9rem;
+    font-weight: 500;
+  }
+}
+
+.DocSearch {
+  --docsearch-primary-color: var(--c-brand);
+  --docsearch-highlight-color: var(--docsearch-primary-color);
+  --docsearch-searchbox-shadow: inset 0 0 0 2px var(--docsearch-primary-color);
+  --docsearch-text-color: var(--c-text-light);
+  --docsearch-muted-color: var(--c-text-lighter);
+  --docsearch-searchbox-background: #f2f2f2;
+}
+</style>

+ 148 - 0
.vitepress/theme-default/components/BuySellAds.vue

@@ -0,0 +1,148 @@
+<template>
+  <div class="buy-sell-ads">
+    <div class="bsa-cpc" />
+  </div>
+</template>
+
+<script setup lang="ts">
+import { defineProps, onMounted } from 'vue'
+
+// global _bsa
+const ID = 'bsa-cpc-script'
+
+declare global {
+  var _bsa: BSA | undefined
+
+  interface BSA {
+    init(
+      name: string,
+      code: string,
+      placement: string,
+      options: {
+        target: string
+        align: string
+        disable_css?: 'true' | 'false'
+      }
+    ): void
+  }
+}
+
+const { code, placement } = defineProps<{
+  code: string
+  placement: string
+}>()
+
+onMounted(() => {
+  if (!document.getElementById(ID)) {
+    const s = document.createElement('script')
+
+    s.id = ID
+    s.src = '//m.servedby-buysellads.com/monetization.js'
+
+    document.head.appendChild(s)
+
+    s.onload = () => {
+      load()
+    }
+  } else {
+    load()
+  }
+})
+
+function load() {
+  if (typeof _bsa !== 'undefined' && _bsa) {
+    _bsa.init('default', code, `placement:${placement}`, {
+      target: '.bsa-cpc',
+      align: 'horizontal',
+      disable_css: 'true'
+    })
+  }
+}
+</script>
+
+<style scoped>
+.buy-sell-ads {
+  margin: 0 auto;
+  padding-top: 2rem;
+  font-size: 0.85rem;
+}
+
+.bsa-cpc {
+  border-radius: 6px;
+  background-color: var(--c-bg-accent);
+}
+
+.bsa-cpc ::v-deep(a._default_) {
+  display: flex;
+  flex-wrap: wrap;
+  align-items: flex-start;
+  margin-bottom: 20px;
+  padding: 12px;
+  text-decoration: none;
+  line-height: 1.4;
+  font-weight: 400;
+  color: var(--c-text-light);
+}
+
+@media (min-width: 512px) {
+  .bsa-cpc ::v-deep(a._default_) {
+    flex-wrap: nowrap;
+  }
+}
+
+.bsa-cpc ::v-deep(.default-ad) {
+  display: none;
+}
+
+.bsa-cpc ::v-deep(a._default_ .default-image) {
+  flex-shrink: 0;
+  margin-right: 12px;
+  width: 24px;
+}
+
+.bsa-cpc ::v-deep(a._default_ .default-image img) {
+  border-radius: 4px;
+  height: 24px;
+  vertical-align: middle;
+}
+
+.bsa-cpc ::v-deep(._default_::after) {
+  border: 1px solid #1c90f3;
+  border-radius: 4px;
+  margin-top: 8px;
+  margin-left: 36px;
+  padding: 0 8px;
+  line-height: 22px;
+  font-size: 0.85em;
+  font-weight: 500;
+  color: #1c90f3;
+  content: 'Sponsored';
+}
+
+@media (min-width: 512px) {
+  .bsa-cpc ::v-deep(._default_::after) {
+    margin-top: 0px;
+    margin-left: 12px;
+  }
+}
+
+.bsa-cpc ::v-deep(.default-text) {
+  flex-grow: 1;
+  align-self: center;
+  width: calc(100% - 36px);
+}
+
+@media (min-width: 512px) {
+  .bsa-cpc ::v-deep(.default-text) {
+    width: auto;
+  }
+}
+
+.bsa-cpc ::v-deep(.default-title) {
+  font-weight: 600;
+}
+
+.bsa-cpc ::v-deep(.default-description) {
+  padding-left: 8px;
+}
+</style>

+ 99 - 0
.vitepress/theme-default/components/CarbonAds.vue

@@ -0,0 +1,99 @@
+<template>
+  <div class="carbon-ads" ref="el" />
+</template>
+
+<script setup lang="ts">
+import { defineProps, ref, onMounted } from 'vue'
+
+const { code, placement } = defineProps<{
+  code: string
+  placement: string
+}>()
+
+const el = ref()
+
+onMounted(() => {
+  const s = document.createElement('script')
+  s.id = '_carbonads_js'
+  s.src = `//cdn.carbonads.com/carbon.js?serve=${code}&placement=${placement}`
+  el.value.appendChild(s)
+})
+</script>
+
+<style scoped>
+.carbon-ads {
+  border-radius: 4px;
+  margin: 0 auto;
+  max-width: 280px;
+  font-size: 0.75rem;
+  background-color: var(--c-bg-accent);
+  min-height: 105.38px; /* avoid layout shift on mobile */
+}
+
+.carbon-ads::after {
+  clear: both;
+  display: block;
+  content: '';
+}
+
+@media (min-width: 420px) {
+  .carbon-ads {
+    z-index: 1;
+    float: right;
+    margin: -8px -8px 24px 24px;
+    padding: 8px;
+    width: 146px;
+    max-width: 100%;
+    min-height: 200px;
+  }
+}
+
+@media (min-width: 1400px) {
+  .carbon-ads {
+    right: 8px;
+    float: none;
+    margin: 0;
+  }
+}
+
+.carbon-ads :deep(.carbon-img) {
+  float: left;
+  margin-right: 0.75rem;
+  max-width: 110px;
+  border: 1px solid var(--c-divider);
+}
+
+@media (min-width: 420px) {
+  .carbon-ads :deep(.carbon-img) {
+    float: none;
+    display: block;
+    margin-right: 0;
+    max-width: 130px;
+  }
+}
+
+.carbon-ads :deep(.carbon-img img) {
+  display: block;
+  width: 100%;
+  height: auto;
+}
+
+@media (min-width: 420px) {
+  .carbon-ads :deep(.carbon-text) {
+    padding-top: 8px;
+  }
+}
+
+.carbon-ads :deep(.carbon-text) {
+  display: block;
+  font-weight: 400;
+  color: var(--c-text-light);
+}
+
+.carbon-ads :deep(.carbon-poweredby) {
+  display: block;
+  padding-top: 2px;
+  font-weight: 400;
+  color: var(--c-text-lighter);
+}
+</style>

+ 13 - 0
.vitepress/theme-default/components/DarkModeSwitch.vue

@@ -0,0 +1,13 @@
+<script setup lang="ts">
+  import { useToggle } from '@vueuse/core';
+  import { isDark } from '../composables/dark';
+
+  const toggle = useToggle(isDark);
+</script>
+
+<template>
+  <button class="nav-btn" aria-label="Toggle Theme" @click="toggle">
+    <ri-moon-line v-show="isDark" />
+    <ri-sun-line v-show="!isDark" />
+  </button>
+</template>

+ 38 - 0
.vitepress/theme-default/components/EditLink.vue

@@ -0,0 +1,38 @@
+<template>
+  <div class="edit-link">
+    <a
+      v-if="url"
+      class="link"
+      :href="url"
+      target="_blank"
+      rel="noopener noreferrer"
+    >
+      {{ text }} <OutboundLink class="icon" />
+    </a>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { useEditLink } from '../composables/editLink'
+import OutboundLink from './icons/OutboundLink.vue'
+
+const { url, text } = useEditLink()
+</script>
+
+<style scoped>
+.link {
+  display: inline-block;
+  font-size: 1rem;
+  font-weight: 500;
+  color: var(--c-text-light);
+}
+
+.link:hover {
+  text-decoration: none;
+  color: var(--c-brand);
+}
+
+.icon {
+  margin-left: 4px;
+}
+</style>

+ 38 - 0
.vitepress/theme-default/components/Home.vue

@@ -0,0 +1,38 @@
+<template>
+  <main class="home" aria-labelledby="main-title">
+    <HomeHero />
+    <slot name="hero" />
+    <HomeFeatures />
+    <div class="home-content">
+      <Content />
+    </div>
+    <slot name="features" />
+    <HomeFooter />
+    <slot name="footer" />
+  </main>
+</template>
+
+<script setup lang="ts">
+import HomeHero from './HomeHero.vue'
+import HomeFeatures from './HomeFeatures.vue'
+import HomeFooter from './HomeFooter.vue'
+</script>
+
+<style scoped>
+.home {
+  padding-top: var(--header-height);
+}
+
+.home-content {
+  max-width: 960px;
+  margin: 0px auto;
+  padding: 0 1.5rem;
+}
+
+@media (max-width: 720px) {
+  .home-content {
+    max-width: 392px;
+    padding: 0;
+  }
+}
+</style>

+ 138 - 0
.vitepress/theme-default/components/HomeFeatures.vue

@@ -0,0 +1,138 @@
+<template>
+  <div v-if="hasFeatures" class="home-features">
+    <div class="wrapper">
+      <div class="container">
+        <div class="features">
+          <section
+            v-for="(feature, index) in features"
+            :key="index"
+            class="feature"
+          >
+            <h2 class="title" v-if="feature.title">{{ feature.title }}</h2>
+            <p class="details" v-if="feature.details">{{ feature.details }}</p>
+          </section>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { computed } from 'vue'
+import { useSiteDataByRoute, useFrontmatter } from 'vitepress'
+
+const data = useFrontmatter()
+
+const hasFeatures = computed(() => {
+  return data.value.features && data.value.features.length > 0
+})
+
+const features = computed(() => {
+  return data.value.features ? data.value.features : []
+})
+</script>
+
+<style scoped>
+.home-features {
+  margin: 0 auto;
+  padding: 2.5rem 0 2.75rem;
+  max-width: 960px;
+}
+
+.home-hero + .home-features {
+  padding-top: 0;
+}
+
+@media (min-width: 420px) {
+  .home-features {
+    padding: 3.25rem 0 3.5rem;
+  }
+
+  .home-hero + .home-features {
+    padding-top: 0;
+  }
+}
+
+@media (min-width: 720px) {
+  .home-features {
+    padding-right: 1.5rem;
+    padding-left: 1.5rem;
+  }
+}
+
+.wrapper {
+  padding: 0 1.5rem;
+}
+
+.home-hero + .home-features .wrapper {
+  border-top: 1px solid var(--c-divider);
+  padding-top: 2.5rem;
+}
+
+@media (min-width: 420px) {
+  .home-hero + .home-features .wrapper {
+    padding-top: 3.25rem;
+  }
+}
+
+@media (min-width: 720px) {
+  .wrapper {
+    padding-right: 0;
+    padding-left: 0;
+  }
+}
+
+.container {
+  margin: 0 auto;
+  max-width: 392px;
+}
+
+@media (min-width: 720px) {
+  .container {
+    max-width: 960px;
+  }
+}
+
+.features {
+  display: flex;
+  flex-wrap: wrap;
+  margin: -20px -24px;
+}
+
+.feature {
+  flex-shrink: 0;
+  padding: 20px 24px;
+  width: 100%;
+}
+
+@media (min-width: 720px) {
+  .feature {
+    width: calc(100% / 3);
+  }
+}
+
+.title {
+  margin: 0;
+  border-bottom: 0;
+  line-height: 1.4;
+  font-size: 1.25rem;
+  font-weight: 500;
+}
+
+@media (min-width: 420px) {
+  .title {
+    font-size: 1.4rem;
+  }
+}
+
+.details {
+  margin: 0;
+  line-height: 1.6;
+  font-size: 1rem;
+  color: var(--c-text-light);
+}
+
+.title + .details {
+  padding-top: 0.25rem;
+}
+</style>

+ 44 - 0
.vitepress/theme-default/components/HomeFooter.vue

@@ -0,0 +1,44 @@
+<template>
+  <footer v-if="$frontmatter.footer" class="footer">
+    <div class="container">
+      <p class="text">{{ $frontmatter.footer }}</p>
+    </div>
+  </footer>
+</template>
+
+<style scoped>
+.footer {
+  margin: 0 auto;
+  max-width: 960px;
+}
+
+@media (min-width: 720px) {
+  .footer {
+    padding: 0 1.5rem;
+  }
+}
+
+.container {
+  padding: 2rem 1.5rem 2.25rem;
+}
+
+.home-hero + .footer .container,
+.home-features + .footer .container,
+.home-content + .footer .container {
+  border-top: 1px solid var(--c-divider);
+}
+
+@media (min-width: 420px) {
+  .container {
+    padding: 3rem 1.5rem 3.25rem;
+  }
+}
+
+.text {
+  margin: 0;
+  text-align: center;
+  line-height: 1.4;
+  font-size: 0.9rem;
+  color: var(--c-text-light);
+}
+</style>

+ 168 - 0
.vitepress/theme-default/components/HomeHero.vue

@@ -0,0 +1,168 @@
+<template>
+  <header v-if="showHero" class="home-hero">
+    <figure v-if="$frontmatter.heroImage" class="figure">
+      <img
+        class="image"
+        :src="$withBase($frontmatter.heroImage)"
+        :alt="$frontmatter.heroAlt"
+      />
+    </figure>
+
+    <h1 v-if="hasHeroText" id="main-title" class="title">{{ heroText }}</h1>
+    <p v-if="hasTagline" class="description">{{ tagline }}</p>
+
+    <NavLink
+      v-if="hasAction"
+      :item="{ link: data.actionLink, text: data.actionText }"
+      class="action"
+    />
+
+    <NavLink
+      v-if="hasAltAction"
+      :item="{ link: data.altActionLink, text: data.altActionText }"
+      class="action alt"
+    />
+  </header>
+</template>
+
+<script setup lang="ts">
+import { computed } from 'vue'
+import { useSiteDataByRoute, useFrontmatter } from 'vitepress'
+import NavLink from './NavLink.vue'
+
+const site = useSiteDataByRoute()
+const data = useFrontmatter()
+
+const showHero = computed(() => {
+  return (
+    data.value.heroImage ||
+    hasHeroText.value ||
+    hasTagline.value ||
+    hasAction.value
+  )
+})
+
+const hasHeroText = computed(() => data.value.heroText !== null)
+const heroText = computed(() => data.value.heroText || site.value.title)
+
+const hasTagline = computed(() => data.value.tagline !== null)
+const tagline = computed(() => data.value.tagline || site.value.description)
+
+const hasAction = computed(() => data.value.actionLink && data.value.actionText)
+const hasAltAction = computed(
+  () => data.value.altActionLink && data.value.altActionText
+)
+</script>
+
+<style scoped>
+.home-hero {
+  margin: 2.5rem 0 2.75rem;
+  padding: 0 1.5rem;
+  text-align: center;
+}
+
+@media (min-width: 420px) {
+  .home-hero {
+    margin: 3.5rem 0;
+  }
+}
+
+@media (min-width: 720px) {
+  .home-hero {
+    margin: 4rem 0 4.25rem;
+  }
+}
+
+.figure {
+  padding: 0 1.5rem;
+}
+
+.image {
+  display: block;
+  margin: 0 auto;
+  width: auto;
+  max-width: 100%;
+  max-height: 280px;
+}
+
+.title {
+  margin-top: 1.5rem;
+  font-size: 2rem;
+}
+
+@media (min-width: 420px) {
+  .title {
+    font-size: 3rem;
+  }
+}
+
+@media (min-width: 720px) {
+  .title {
+    margin-top: 2rem;
+  }
+}
+
+.description {
+  margin: 0;
+  margin-top: 0.25rem;
+  line-height: 1.3;
+  font-size: 1.2rem;
+  color: var(--c-text-light);
+}
+
+@media (min-width: 420px) {
+  .description {
+    line-height: 1.2;
+    font-size: 1.6rem;
+  }
+}
+
+.action {
+  margin-top: 1.5rem;
+  display: inline-block;
+}
+
+.action.alt {
+  margin-left: 1.5rem;
+}
+
+@media (min-width: 420px) {
+  .action {
+    margin-top: 2rem;
+    display: inline-block;
+  }
+}
+
+.action :deep(.item) {
+  display: inline-block;
+  border-radius: 6px;
+  padding: 0 20px;
+  line-height: 44px;
+  font-size: 1rem;
+  font-weight: 500;
+  color: var(--c-bg);
+  background-color: var(--c-brand);
+  border: 2px solid var(--c-brand);
+  transition: background-color 0.1s ease;
+}
+
+.action.alt :deep(.item) {
+  background-color: var(--c-bg);
+  color: var(--c-brand);
+}
+
+.action :deep(.item:hover) {
+  text-decoration: none;
+  color: var(--c-bg);
+  background-color: var(--c-brand-light);
+}
+
+@media (min-width: 420px) {
+  .action :deep(.item) {
+    padding: 0 24px;
+    line-height: 52px;
+    font-size: 1.2rem;
+    font-weight: 500;
+  }
+}
+</style>

+ 59 - 0
.vitepress/theme-default/components/LastUpdated.vue

@@ -0,0 +1,59 @@
+<template>
+  <p v-if="hasLastUpdated" class="last-updated">
+    <span class="prefix">{{ prefix }}:</span>
+    <span class="datetime">{{ datetime }}</span>
+  </p>
+</template>
+
+<script setup lang="ts">
+import { ref, computed, onMounted } from 'vue'
+import { useSiteDataByRoute, usePageData } from 'vitepress'
+
+const site = useSiteDataByRoute()
+const page = usePageData()
+
+const hasLastUpdated = computed(() => {
+  const lu = site.value.themeConfig.lastUpdated
+
+  return lu !== undefined && lu !== false
+})
+
+const prefix = computed(() => {
+  const p = site.value.themeConfig.lastUpdated
+  return p === true ? 'Last Updated' : p
+})
+
+const datetime = ref('')
+onMounted(() => {
+  // locale string might be different based on end user
+  // and will lead to potential hydration mismatch if calculated at build time
+  datetime.value = new Date(page.value.lastUpdated).toLocaleString('en-US')
+})
+</script>
+
+<style scoped>
+.last-updated {
+  display: inline-block;
+  margin: 0;
+  line-height: 1.4;
+  font-size: 0.9rem;
+  color: var(--c-text-light);
+}
+
+@media (min-width: 960px) {
+  .last-updated {
+    font-size: 1rem;
+  }
+}
+
+.prefix {
+  display: inline-block;
+  font-weight: 500;
+}
+
+.datetime {
+  display: inline-block;
+  margin-left: 6px;
+  font-weight: 400;
+}
+</style>

+ 95 - 0
.vitepress/theme-default/components/NavBar.vue

@@ -0,0 +1,95 @@
+<template>
+  <header class="nav-bar">
+    <ToggleSideBarButton @toggle="$emit('toggle')" />
+
+    <NavBarTitle />
+
+    <div class="flex-grow" />
+
+    <div class="nav">
+      <NavLinks />
+    </div>
+
+    <div class="nav-icons">
+      <div class="item">
+        <dark-mode-switch />
+      </div>
+      <div v-if="repo" class="item">
+        <a
+          class="nav-btn"
+          href="https://github.com/kailong321200875/vue-element-plus-admin"
+          target="_blank"
+          aria-label="View GitHub Repo"
+        >
+          <ri-github-line />
+        </a>
+      </div>
+    </div>
+    <slot name="search" />
+  </header>
+</template>
+
+<script setup lang="ts">
+  import { defineEmit } from 'vue';
+  import NavBarTitle from './NavBarTitle.vue';
+  import NavLinks from './NavLinks.vue';
+  import ToggleSideBarButton from './ToggleSideBarButton.vue';
+  import DarkModeSwitch from './DarkModeSwitch.vue';
+  import { useRepo } from '../composables/repo';
+
+  defineEmit(['toggle']);
+
+  const repo = useRepo();
+</script>
+
+<style scoped>
+  .nav-bar {
+    position: fixed;
+    top: 0;
+    right: 0;
+    left: 0;
+    z-index: var(--z-index-navbar);
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    border-bottom: 1px solid var(--c-divider);
+    padding: 0.7rem 1.5rem 0.7rem 4rem;
+    height: var(--header-height);
+    background-color: var(--c-bg);
+  }
+
+  @media (min-width: 720px) {
+    .nav-bar {
+      padding: 0.7rem 1.5rem;
+    }
+  }
+
+  .flex-grow {
+    flex-grow: 1;
+  }
+
+  .nav {
+    display: none;
+  }
+
+  @media (min-width: 720px) {
+    .nav {
+      display: flex;
+    }
+    .navbar__dark-mode {
+      display: none;
+    }
+  }
+
+  .nav-icons {
+    display: flex;
+    padding: 2px 0 0;
+    align-items: center;
+    border-bottom: 0;
+    margin-left: 12px;
+  }
+
+  .nav-icons .item {
+    padding-left: 12px;
+  }
+</style>

+ 33 - 0
.vitepress/theme-default/components/NavBarTitle.vue

@@ -0,0 +1,33 @@
+<template>
+  <a
+    class="nav-bar-title"
+    :href="$withBase($localePath)"
+    :aria-label="`${$siteByRoute.title}, back to home`"
+  >
+    <img
+      v-if="$themeConfig.logo"
+      class="logo"
+      :src="$withBase($themeConfig.logo)"
+      alt="Logo"
+    />
+    {{ $site.title }}
+  </a>
+</template>
+
+<style scoped>
+.nav-bar-title {
+  font-size: 1.3rem;
+  font-weight: 600;
+  color: var(--c-text);
+}
+
+.nav-bar-title:hover {
+  text-decoration: none;
+}
+
+.logo {
+  margin-right: 0.75rem;
+  height: 1.3rem;
+  vertical-align: bottom;
+}
+</style>

+ 135 - 0
.vitepress/theme-default/components/NavDropdownLink.vue

@@ -0,0 +1,135 @@
+<template>
+  <div class="nav-dropdown-link" :class="{ open }">
+    <button class="button" :aria-label="item.ariaLabel" @click="toggle">
+      <span class="button-text">{{ item.text }}</span>
+      <span class="button-arrow" :class="open ? 'down' : 'right'" />
+    </button>
+
+    <ul class="dialog">
+      <li v-for="item in item.items" :key="item.text" class="dialog-item">
+        <NavDropdownLinkItem :item="item" />
+      </li>
+    </ul>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { defineProps, ref, watch } from 'vue'
+import { useRoute } from 'vitepress'
+import type { DefaultTheme } from '../config'
+import NavDropdownLinkItem from './NavDropdownLinkItem.vue'
+
+defineProps<{
+  item: DefaultTheme.NavItemWithChildren
+}>()
+
+const route = useRoute()
+
+const open = ref(false)
+
+watch(
+  () => route.path,
+  () => {
+    open.value = false
+  }
+)
+
+function toggle() {
+  open.value = !open.value
+}
+</script>
+
+<style scoped>
+.nav-dropdown-link {
+  position: relative;
+  height: 36px;
+  overflow: hidden;
+  cursor: pointer;
+}
+
+@media (min-width: 720px) {
+  .nav-dropdown-link {
+    height: auto;
+    overflow: visible;
+  }
+
+  .nav-dropdown-link:hover .dialog {
+    display: block;
+  }
+}
+
+.nav-dropdown-link.open {
+  height: auto;
+}
+
+.button {
+  display: block;
+  border: 0;
+  padding: 0 1.5rem;
+  width: 100%;
+  text-align: left;
+  line-height: 36px;
+  font-family: var(--font-family-base);
+  font-size: 1rem;
+  font-weight: 600;
+  color: var(--c-text);
+  white-space: nowrap;
+  background-color: transparent;
+  cursor: pointer;
+}
+
+.button:focus {
+  outline: 0;
+}
+
+@media (min-width: 720px) {
+  .button {
+    border-bottom: 2px solid transparent;
+    padding: 0;
+    line-height: 24px;
+    font-size: 0.9rem;
+    font-weight: 500;
+  }
+}
+
+.button-arrow {
+  display: inline-block;
+  margin-top: -1px;
+  margin-left: 8px;
+  border-top: 6px solid #ccc;
+  border-right: 4px solid transparent;
+  border-bottom: 0;
+  border-left: 4px solid transparent;
+  vertical-align: middle;
+}
+
+.button-arrow.right {
+  transform: rotate(-90deg);
+}
+
+@media (min-width: 720px) {
+  .button-arrow.right {
+    transform: rotate(0);
+  }
+}
+
+.dialog {
+  margin: 0;
+  padding: 0;
+  list-style: none;
+}
+
+@media (min-width: 720px) {
+  .dialog {
+    display: none;
+    position: absolute;
+    top: 26px;
+    right: -8px;
+    border-radius: 6px;
+    padding: 12px 0;
+    min-width: 128px;
+    background-color: var(--c-bg);
+    box-shadow: var(--shadow-3);
+  }
+}
+</style>

+ 76 - 0
.vitepress/theme-default/components/NavDropdownLinkItem.vue

@@ -0,0 +1,76 @@
+<template>
+  <div class="nav-dropdown-link-item">
+    <a class="item" v-bind="linkProps">
+      <span class="arrow" />
+      <span class="text">{{ item.text }}</span>
+      <span class="icon"><OutboundLink v-if="isExternal" /></span>
+    </a>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { defineProps, toRefs } from 'vue'
+import type { DefaultTheme } from '../config'
+import { useNavLink } from '../composables/navLink'
+import OutboundLink from './icons/OutboundLink.vue'
+
+const props = defineProps<{
+  item: DefaultTheme.NavItemWithLink
+}>()
+
+const propsRefs = toRefs(props)
+
+const { props: linkProps, isExternal } = useNavLink(propsRefs.item)
+</script>
+
+<style scoped>
+.item {
+  display: block;
+  padding: 0 1.5rem 0 2.5rem;
+  line-height: 32px;
+  font-size: 0.9rem;
+  font-weight: 500;
+  color: var(--c-text);
+  white-space: nowrap;
+}
+
+@media (min-width: 720px) {
+  .item {
+    padding: 0 24px 0 12px;
+    line-height: 32px;
+    font-size: 0.85rem;
+    font-weight: 500;
+    color: var(--c-text);
+    white-space: nowrap;
+  }
+
+  .item.active .arrow {
+    opacity: 1;
+  }
+}
+
+.item:hover,
+.item.active {
+  text-decoration: none;
+  color: var(--c-brand);
+}
+
+.item.external:hover {
+  border-bottom-color: transparent;
+  color: var(--c-text);
+}
+
+@media (min-width: 720px) {
+  .arrow {
+    display: inline-block;
+    margin-right: 8px;
+    border-top: 6px solid #ccc;
+    border-right: 4px solid transparent;
+    border-bottom: 0;
+    border-left: 4px solid transparent;
+    vertical-align: middle;
+    opacity: 0;
+    transform: translateY(-2px) rotate(-90deg);
+  }
+}
+</style>

+ 61 - 0
.vitepress/theme-default/components/NavLink.vue

@@ -0,0 +1,61 @@
+<template>
+  <div class="nav-link">
+    <a class="item" v-bind="linkProps">
+      {{ item.text }} <OutboundLink v-if="isExternal" />
+    </a>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { defineProps, toRefs } from 'vue'
+import type { DefaultTheme } from '../config'
+import { useNavLink } from '../composables/navLink'
+import OutboundLink from './icons/OutboundLink.vue'
+
+const props = defineProps<{
+  item: DefaultTheme.NavItemWithLink
+}>()
+
+const propsRefs = toRefs(props)
+
+const { props: linkProps, isExternal } = useNavLink(propsRefs.item)
+</script>
+
+<style scoped>
+.item {
+  display: block;
+  padding: 0 1.5rem;
+  line-height: 36px;
+  font-size: 1rem;
+  font-weight: 600;
+  color: var(--c-text);
+  white-space: nowrap;
+}
+
+.item:hover,
+.item.active {
+  text-decoration: none;
+  color: var(--c-brand);
+}
+
+.item.external:hover {
+  border-bottom-color: transparent;
+  color: var(--c-text);
+}
+
+@media (min-width: 720px) {
+  .item {
+    border-bottom: 2px solid transparent;
+    padding: 0;
+    line-height: 24px;
+    font-size: 0.9rem;
+    font-weight: 500;
+  }
+
+  .item:hover,
+  .item.active {
+    border-bottom-color: var(--c-brand);
+    color: var(--c-text);
+  }
+}
+</style>

+ 55 - 0
.vitepress/theme-default/components/NavLinks.vue

@@ -0,0 +1,55 @@
+<template>
+  <nav v-if="show" class="nav-links">
+    <template v-if="links">
+      <div v-for="item in links" :key="item.text" class="item">
+        <NavDropdownLink v-if="item.items" :item="item" />
+        <NavLink v-else :item="item" />
+      </div>
+    </template>
+
+    <div v-if="localeLinks" class="item">
+      <NavDropdownLink :item="localeLinks" />
+    </div>
+
+    <!-- <div v-if="repo" class="item">
+      <NavLink :item="repo" />
+    </div> -->
+  </nav>
+</template>
+
+<script setup lang="ts">
+  import { computed } from 'vue';
+  import { useSiteDataByRoute } from 'vitepress';
+  import { useLocaleLinks } from '../composables/nav';
+  // import { useRepo } from '../composables/repo'
+  import NavLink from './NavLink.vue';
+  import NavDropdownLink from './NavDropdownLink.vue';
+
+  const site = useSiteDataByRoute();
+  const localeLinks = useLocaleLinks();
+  // const repo = useRepo()
+
+  const show = computed(() => links.value || repo.value);
+
+  const links = computed(() => site.value.themeConfig.nav);
+</script>
+
+<style scoped>
+  .nav-links {
+    padding: 0.75rem 0;
+    border-bottom: 1px solid var(--c-divider);
+  }
+
+  @media (min-width: 720px) {
+    .nav-links {
+      display: flex;
+      padding: 6px 0 0;
+      align-items: center;
+      border-bottom: 0;
+    }
+
+    .item + .item {
+      padding-left: 24px;
+    }
+  }
+</style>

+ 87 - 0
.vitepress/theme-default/components/NextAndPrevLinks.vue

@@ -0,0 +1,87 @@
+<template>
+  <div v-if="hasLinks" class="next-and-prev-link">
+    <div class="container">
+      <div class="prev">
+        <a v-if="prev" class="link" :href="$withBase(prev.link)">
+          <ArrowLeft class="icon icon-prev" />
+          <span class="text">{{ prev.text }}</span>
+        </a>
+      </div>
+      <div class="next">
+        <a v-if="next" class="link" :href="$withBase(next.link)">
+          <span class="text">{{ next.text }}</span>
+          <ArrowRight class="icon icon-next" />
+        </a>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { useNextAndPrevLinks } from '../composables/nextAndPrevLinks'
+import ArrowLeft from './icons/ArrowLeft.vue'
+import ArrowRight from './icons/ArrowRight.vue'
+
+const { hasLinks, prev, next } = useNextAndPrevLinks()
+</script>
+
+<style scoped>
+.next-and-prev-link {
+  padding-top: 1rem;
+}
+
+.container {
+  display: flex;
+  justify-content: space-between;
+  border-top: 1px solid var(--c-divider);
+  padding-top: 1rem;
+}
+
+.prev,
+.next {
+  display: flex;
+  flex-shrink: 0;
+  width: 50%;
+}
+
+.prev {
+  justify-content: flex-start;
+  padding-right: 12px;
+}
+
+.next {
+  justify-content: flex-end;
+  padding-left: 12px;
+}
+
+.link {
+  display: inline-flex;
+  align-items: center;
+  max-width: 100%;
+  font-size: 1rem;
+  font-weight: 500;
+}
+
+.text {
+  display: block;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.icon {
+  display: block;
+  flex-shrink: 0;
+  width: 16px;
+  height: 16px;
+  fill: var(--c-text);
+  transform: translateY(1px);
+}
+
+.icon-prev {
+  margin-right: 8px;
+}
+.icon-next {
+  margin-left: 8px;
+}
+</style>

+ 58 - 0
.vitepress/theme-default/components/Page.vue

@@ -0,0 +1,58 @@
+<template>
+  <main class="page">
+    <div class="container">
+      <slot name="top" />
+
+      <div class="content">
+        <Content />
+      </div>
+
+      <PageFooter />
+
+      <NextAndPrevLinks />
+
+      <slot name="bottom" />
+    </div>
+  </main>
+</template>
+
+<script setup lang="ts">
+  import PageFooter from './PageFooter.vue';
+  import NextAndPrevLinks from './NextAndPrevLinks.vue';
+</script>
+
+<style scoped>
+  .page {
+    padding-top: var(--header-height);
+  }
+
+  @media (min-width: 720px) {
+    .page {
+      margin-left: 16.4rem;
+    }
+  }
+
+  @media (min-width: 960px) {
+    .page {
+      margin-left: 20rem;
+    }
+  }
+
+  .container {
+    margin: 0 auto;
+    padding: 0 1.5rem 4rem;
+    padding: 0.025rem 0rem 2rem 0;
+    width: calc(100% - var(--slug-width));
+  }
+
+  .content {
+    padding-bottom: 1.5rem;
+  }
+
+  @media (max-width: 420px) {
+    .content {
+      /* fix carbon ads display */
+      clear: both;
+    }
+  }
+</style>

+ 41 - 0
.vitepress/theme-default/components/PageFooter.vue

@@ -0,0 +1,41 @@
+<template>
+  <footer class="page-footer">
+    <div class="edit">
+      <EditLink />
+    </div>
+    <div class="updated">
+      <LastUpdated />
+    </div>
+  </footer>
+</template>
+
+<script setup lang="ts">
+import EditLink from './EditLink.vue'
+import LastUpdated from './LastUpdated.vue'
+</script>
+
+<style scoped>
+.page-footer {
+  padding-top: 1rem;
+  padding-bottom: 1rem;
+  overflow: auto;
+}
+
+@media (min-width: 960px) {
+  .page-footer {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+}
+
+.updated {
+  padding-top: 4px;
+}
+
+@media (min-width: 960px) {
+  .updated {
+    padding-top: 0;
+  }
+}
+</style>

+ 65 - 0
.vitepress/theme-default/components/SideBar.vue

@@ -0,0 +1,65 @@
+<template>
+  <aside class="sidebar" :class="{ open }">
+    <NavLinks class="nav" />
+
+    <slot name="sidebar-top" />
+
+    <SideBarLinks />
+
+    <slot name="sidebar-bottom" />
+  </aside>
+  <!-- <Slugs /> -->
+</template>
+
+<script setup lang="ts">
+  import { defineProps } from 'vue';
+  import NavLinks from './NavLinks.vue';
+  import SideBarLinks from './SideBarLinks.vue';
+  // import Slugs from './Slugs.vue';
+
+  defineProps({
+    open: { type: Boolean, required: true },
+  });
+</script>
+
+<style scoped>
+  .sidebar {
+    position: fixed;
+    top: var(--header-height);
+    bottom: 0;
+    left: 0;
+    z-index: var(--z-index-sidebar);
+    border-right: 1px solid var(--c-divider);
+    width: 16.4rem;
+    background-color: var(--c-bg);
+    overflow-y: auto;
+    transform: translateX(-100%);
+    transition: transform 0.25s ease;
+  }
+
+  @media (min-width: 720px) {
+    .sidebar {
+      transform: translateX(0);
+    }
+  }
+
+  @media (min-width: 960px) {
+    .sidebar {
+      width: 20rem;
+    }
+  }
+
+  .sidebar.open {
+    transform: translateX(0);
+  }
+
+  .nav {
+    display: block;
+  }
+
+  @media (min-width: 720px) {
+    .nav {
+      display: none;
+    }
+  }
+</style>

+ 93 - 0
.vitepress/theme-default/components/SideBarLink.ts

@@ -0,0 +1,93 @@
+import { FunctionalComponent, h, VNode } from 'vue'
+import { useRoute, useSiteData } from 'vitepress'
+import { Header } from '/@types/shared'
+import { DefaultTheme } from '../config'
+import { joinUrl, isActive } from '../utils'
+
+interface HeaderWithChildren extends Header {
+  children?: Header[]
+}
+
+export const SideBarLink: FunctionalComponent<{
+  item: DefaultTheme.SideBarItem
+}> = (props) => {
+  const route = useRoute()
+  const site = useSiteData()
+
+  const headers = route.data.headers
+  const text = props.item.text
+  const link = resolveLink(site.value.base, props.item.link)
+  const children = (props.item as DefaultTheme.SideBarGroup).children
+  const active = isActive(route, props.item.link)
+  const childItems = createChildren(active, children, headers)
+
+  return h('li', { class: 'sidebar-link' }, [
+    h(
+      link ? 'a' : 'p',
+      {
+        class: { 'sidebar-link-item': true, active },
+        href: link
+      },
+      text
+    ),
+    childItems
+  ])
+}
+
+function resolveLink(base: string, path?: string): string | undefined {
+  if (path === undefined) {
+    return path
+  }
+
+  // keep relative hash to the same page
+  if (path.startsWith('#')) {
+    return path
+  }
+
+  return joinUrl(base, path)
+}
+
+function createChildren(
+  active: boolean,
+  children?: DefaultTheme.SideBarItem[],
+  headers?: Header[]
+): VNode | null {
+  if (children && children.length > 0) {
+    return h(
+      'ul',
+      { class: 'sidebar-links' },
+      children.map((c) => {
+        return h(SideBarLink, { item: c })
+      })
+    )
+  }
+
+  return active && headers
+    ? createChildren(false, resolveHeaders(headers))
+    : null
+}
+
+function resolveHeaders(headers: Header[]): DefaultTheme.SideBarItem[] {
+  return mapHeaders(groupHeaders(headers))
+}
+
+function groupHeaders(headers: Header[]): HeaderWithChildren[] {
+  headers = headers.map((h) => Object.assign({}, h))
+  let lastH2: HeaderWithChildren
+  headers.forEach((h) => {
+    if (h.level === 2) {
+      lastH2 = h
+    } else if (lastH2) {
+      ;(lastH2.children || (lastH2.children = [])).push(h)
+    }
+  })
+  return headers.filter((h) => h.level === 2)
+}
+
+function mapHeaders(headers: HeaderWithChildren[]): DefaultTheme.SideBarItem[] {
+  return headers.map((header) => ({
+    text: header.title,
+    link: `#${header.slug}`,
+    children: header.children ? mapHeaders(header.children) : undefined
+  }))
+}

+ 12 - 0
.vitepress/theme-default/components/SideBarLinks.vue

@@ -0,0 +1,12 @@
+<template>
+  <ul v-if="items.length > 0" class="sidebar-links">
+    <SideBarLink v-for="item of items" :key="item.text" :item="item" />
+  </ul>
+</template>
+
+<script setup lang="ts">
+import { useSideBar } from '../composables/sideBar'
+import { SideBarLink } from './SideBarLink'
+
+const items = useSideBar()
+</script>

+ 75 - 0
.vitepress/theme-default/components/Slugs.vue

@@ -0,0 +1,75 @@
+<template>
+  <!-- <aside to="body"> -->
+  <ul class="slugs">
+    <li v-for="{ level, link, title } of slugs" :class="`slug-item level-${level}`" :key="link">
+      <a :href="link" class="link">
+        {{ title }}
+      </a>
+    </li>
+  </ul>
+  <!-- </aside> -->
+</template>
+
+<script lang="ts">
+  import { computed } from 'vue';
+  import { useRoute } from 'vitepress';
+
+  export default {
+    setup() {
+      const route = useRoute();
+      const slugs = computed(() => {
+        // only display two level
+        const headers = (route.data.headers ?? []).filter((i) => i.level > 1);
+        let minLevel = 10;
+        for (const { level } of headers) {
+          minLevel > level && (minLevel = level);
+        }
+
+        return headers
+          .filter((h) => h.level < minLevel + 2)
+          .map((h) => ({
+            ...h,
+            link: `#${h.slug}`,
+            level: h.level === minLevel ? 1 : 2,
+          }));
+      });
+
+      return {
+        slugs,
+      };
+    },
+  };
+</script>
+
+<style scoped>
+  .slug-item {
+    list-style: none;
+    font-size: 14px;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    padding: 4px 0 4px 16px;
+    margin: 0;
+    border-left: 2px solid #ebedf1;
+  }
+
+  .level-2 {
+    font-size: 13px;
+    padding-left: 28px;
+  }
+
+  .link {
+    color: var(--text-color);
+  }
+
+  .slugs {
+    transform: translateX(100%);
+    transition: transform 0.25s ease;
+  }
+
+  @media (min-width: 900px) {
+    .slugs {
+      transform: translateX(0);
+    }
+  }
+</style>

+ 46 - 0
.vitepress/theme-default/components/ToggleSideBarButton.vue

@@ -0,0 +1,46 @@
+<template>
+  <div class="sidebar-button" @click="$emit('toggle')">
+    <svg
+      class="icon"
+      xmlns="http://www.w3.org/2000/svg"
+      aria-hidden="true"
+      role="img"
+      viewBox="0 0 448 512"
+    >
+      <path
+        fill="currentColor"
+        d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"
+        class
+      />
+    </svg>
+  </div>
+</template>
+
+<script>
+export default {
+  emits: ['toggle']
+}
+</script>
+
+<style>
+.sidebar-button {
+  position: absolute;
+  top: 0.6rem;
+  left: 1rem;
+  display: none;
+  padding: 0.6rem;
+  cursor: pointer;
+}
+
+.sidebar-button .icon {
+  display: block;
+  width: 1.25rem;
+  height: 1.25rem;
+}
+
+@media screen and (max-width: 719px) {
+  .sidebar-button {
+    display: block;
+  }
+}
+</style>

+ 7 - 0
.vitepress/theme-default/components/icons/ArrowLeft.vue

@@ -0,0 +1,7 @@
+<template>
+  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+    <path
+      d="M19,11H7.4l5.3-5.3c0.4-0.4,0.4-1,0-1.4s-1-0.4-1.4,0l-7,7c-0.1,0.1-0.2,0.2-0.2,0.3c-0.1,0.2-0.1,0.5,0,0.8c0.1,0.1,0.1,0.2,0.2,0.3l7,7c0.2,0.2,0.5,0.3,0.7,0.3s0.5-0.1,0.7-0.3c0.4-0.4,0.4-1,0-1.4L7.4,13H19c0.6,0,1-0.4,1-1S19.6,11,19,11z"
+    />
+  </svg>
+</template>

+ 7 - 0
.vitepress/theme-default/components/icons/ArrowRight.vue

@@ -0,0 +1,7 @@
+<template>
+  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+    <path
+      d="M19.9,12.4c0.1-0.2,0.1-0.5,0-0.8c-0.1-0.1-0.1-0.2-0.2-0.3l-7-7c-0.4-0.4-1-0.4-1.4,0s-0.4,1,0,1.4l5.3,5.3H5c-0.6,0-1,0.4-1,1s0.4,1,1,1h11.6l-5.3,5.3c-0.4,0.4-0.4,1,0,1.4c0.2,0.2,0.5,0.3,0.7,0.3s0.5-0.1,0.7-0.3l7-7C19.8,12.6,19.9,12.5,19.9,12.4z"
+    />
+  </svg>
+</template>

+ 31 - 0
.vitepress/theme-default/components/icons/OutboundLink.vue

@@ -0,0 +1,31 @@
+<template>
+  <svg
+    class="icon outbound"
+    xmlns="http://www.w3.org/2000/svg"
+    aria-hidden="true"
+    x="0px"
+    y="0px"
+    viewBox="0 0 100 100"
+    width="15"
+    height="15"
+  >
+    <path
+      fill="currentColor"
+      d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"
+    />
+    <polygon
+      fill="currentColor"
+      points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"
+    />
+  </svg>
+</template>
+
+<style>
+  .icon.outbound {
+    position: relative;
+    top: -1px;
+    display: inline-block;
+    vertical-align: middle;
+    color: var(--c-text-lighter);
+  }
+</style>

+ 134 - 0
.vitepress/theme-default/composables/activeSidebarLink.ts

@@ -0,0 +1,134 @@
+import { onMounted, onUnmounted, onUpdated } from 'vue'
+
+export function useActiveSidebarLinks() {
+  let rootActiveLink: HTMLAnchorElement | null = null
+  let activeLink: HTMLAnchorElement | null = null
+
+  const onScroll = throttleAndDebounce(setActiveLink, 300)
+
+  function setActiveLink(): void {
+    const sidebarLinks = getSidebarLinks()
+    const anchors = getAnchors(sidebarLinks)
+
+    for (let i = 0; i < anchors.length; i++) {
+      const anchor = anchors[i]
+      const nextAnchor = anchors[i + 1]
+
+      const [isActive, hash] = isAnchorActive(i, anchor, nextAnchor)
+
+      if (isActive) {
+        history.replaceState(null, document.title, hash ? hash : ' ')
+        activateLink(hash)
+        return
+      }
+    }
+  }
+
+  function activateLink(hash: string | null): void {
+    deactiveLink(activeLink)
+    deactiveLink(rootActiveLink)
+
+    activeLink = document.querySelector(`.sidebar a[href="${hash}"]`)
+
+    if (!activeLink) {
+      return
+    }
+
+    activeLink.classList.add('active')
+
+    // also add active class to parent h2 anchors
+    const rootLi = activeLink.closest('.sidebar-links > ul > li')
+
+    if (rootLi && rootLi !== activeLink.parentElement) {
+      rootActiveLink = rootLi.querySelector('a')
+      rootActiveLink && rootActiveLink.classList.add('active')
+    } else {
+      rootActiveLink = null
+    }
+  }
+
+  function deactiveLink(link: HTMLAnchorElement | null): void {
+    link && link.classList.remove('active')
+  }
+
+  onMounted(() => {
+    setActiveLink()
+    window.addEventListener('scroll', onScroll)
+  })
+
+  onUpdated(() => {
+    // sidebar update means a route change
+    activateLink(decodeURIComponent(location.hash))
+  })
+
+  onUnmounted(() => {
+    window.removeEventListener('scroll', onScroll)
+  })
+}
+
+function getSidebarLinks(): HTMLAnchorElement[] {
+  return [].slice.call(
+    document.querySelectorAll('.sidebar a.sidebar-link-item')
+  )
+}
+
+function getAnchors(sidebarLinks: HTMLAnchorElement[]): HTMLAnchorElement[] {
+  return [].slice
+    .call(document.querySelectorAll('.header-anchor'))
+    .filter((anchor: HTMLAnchorElement) =>
+      sidebarLinks.some((sidebarLink) => sidebarLink.hash === anchor.hash)
+    ) as HTMLAnchorElement[]
+}
+
+function getPageOffset(): number {
+  return (document.querySelector('.nav-bar') as HTMLElement).offsetHeight
+}
+
+function getAnchorTop(anchor: HTMLAnchorElement): number {
+  const pageOffset = getPageOffset()
+
+  return anchor.parentElement!.offsetTop - pageOffset - 15
+}
+
+function isAnchorActive(
+  index: number,
+  anchor: HTMLAnchorElement,
+  nextAnchor: HTMLAnchorElement
+): [boolean, string | null] {
+  const scrollTop = window.scrollY
+
+  if (index === 0 && scrollTop === 0) {
+    return [true, null]
+  }
+
+  if (scrollTop < getAnchorTop(anchor)) {
+    return [false, null]
+  }
+
+  if (!nextAnchor || scrollTop < getAnchorTop(nextAnchor)) {
+    return [true, decodeURIComponent(anchor.hash)]
+  }
+
+  return [false, null]
+}
+
+function throttleAndDebounce(fn: () => void, delay: number): () => void {
+  let timeout: number
+  let called = false
+
+  return () => {
+    if (timeout) {
+      clearTimeout(timeout)
+    }
+
+    if (!called) {
+      fn()
+      called = true
+      setTimeout(() => {
+        called = false
+      }, delay)
+    } else {
+      timeout = setTimeout(fn, delay)
+    }
+  }
+}

+ 6 - 0
.vitepress/theme-default/composables/dark.ts

@@ -0,0 +1,6 @@
+import { useDark } from '@vueuse/core';
+
+export const isDark = useDark({
+  storageKey: 'vben-admin-color-scheme',
+  valueLight: 'light',
+});

+ 91 - 0
.vitepress/theme-default/composables/editLink.ts

@@ -0,0 +1,91 @@
+import { computed } from 'vue'
+import { useSiteDataByRoute, usePageData } from 'vitepress'
+import { endingSlashRE, isNullish, isExternal } from '../utils'
+
+const bitbucketRE = /bitbucket.org/
+
+export function useEditLink() {
+  const site = useSiteDataByRoute()
+  const page = usePageData()
+
+  const url = computed(() => {
+    const showEditLink = isNullish(page.value.frontmatter.editLink)
+      ? site.value.themeConfig.editLinks
+      : page.value.frontmatter.editLink
+
+    const {
+      repo,
+      docsDir = '',
+      docsBranch = 'master',
+      docsRepo = repo
+    } = site.value.themeConfig
+
+    const { relativePath } = page.value
+
+    if (!showEditLink || !relativePath || !repo) {
+      return null
+    }
+
+    return createUrl(repo, docsRepo, docsDir, docsBranch, relativePath)
+  })
+
+  const text = computed(() => {
+    return site.value.themeConfig.editLinkText || 'Edit this page'
+  })
+
+  return {
+    url,
+    text
+  }
+}
+
+function createUrl(
+  repo: string,
+  docsRepo: string,
+  docsDir: string,
+  docsBranch: string,
+  path: string
+): string {
+  return bitbucketRE.test(repo)
+    ? createBitbucketUrl(repo, docsRepo, docsDir, docsBranch, path)
+    : createGitHubUrl(repo, docsRepo, docsDir, docsBranch, path)
+}
+
+function createGitHubUrl(
+  repo: string,
+  docsRepo: string,
+  docsDir: string,
+  docsBranch: string,
+  path: string
+): string {
+  const base = isExternal(docsRepo)
+    ? docsRepo
+    : `https://github.com/${docsRepo}`
+
+  return (
+    base.replace(endingSlashRE, '') +
+    `/edit` +
+    `/${docsBranch}/` +
+    (docsDir ? docsDir.replace(endingSlashRE, '') + '/' : '') +
+    path
+  )
+}
+
+function createBitbucketUrl(
+  repo: string,
+  docsRepo: string,
+  docsDir: string,
+  docsBranch: string,
+  path: string
+): string {
+  const base = isExternal(docsRepo) ? docsRepo : repo
+
+  return (
+    base.replace(endingSlashRE, '') +
+    `/src` +
+    `/${docsBranch}/` +
+    (docsDir ? docsDir.replace(endingSlashRE, '') + '/' : '') +
+    path +
+    `?mode=edit&spa=0&at=${docsBranch}&fileviewer=file-view-default`
+  )
+}

+ 61 - 0
.vitepress/theme-default/composables/nav.ts

@@ -0,0 +1,61 @@
+import { computed } from 'vue'
+import { useRoute, useSiteData, inBrowser } from 'vitepress'
+import type { DefaultTheme } from '../config'
+
+export function useLocaleLinks() {
+  const route = useRoute()
+  const site = useSiteData()
+
+  return computed(() => {
+    const theme = site.value.themeConfig as DefaultTheme.Config
+    const locales = theme.locales
+
+    if (!locales) {
+      return null
+    }
+
+    const localeKeys = Object.keys(locales)
+
+    if (localeKeys.length <= 1) {
+      return null
+    }
+
+    // handle site base
+    const siteBase = inBrowser ? site.value.base : '/'
+
+    const siteBaseWithoutSuffix = siteBase.endsWith('/')
+      ? siteBase.slice(0, -1)
+      : siteBase
+
+    // remove site base in browser env
+    const routerPath = route.path.slice(siteBaseWithoutSuffix.length)
+
+    const currentLangBase = localeKeys.find((key) => {
+      return key === '/' ? false : routerPath.startsWith(key)
+    })
+
+    const currentContentPath = currentLangBase
+      ? routerPath.substring(currentLangBase.length - 1)
+      : routerPath
+
+    const candidates = localeKeys.map((v) => {
+      const localePath = v.endsWith('/') ? v.slice(0, -1) : v
+
+      return {
+        text: locales[v].label,
+        link: `${localePath}${currentContentPath}`
+      }
+    })
+
+    const currentLangKey = currentLangBase ? currentLangBase : '/'
+
+    const selectText = locales[currentLangKey].selectText
+      ? locales[currentLangKey].selectText
+      : 'Languages'
+
+    return {
+      text: selectText,
+      items: candidates
+    } as DefaultTheme.NavItemWithChildren
+  })
+}

+ 51 - 0
.vitepress/theme-default/composables/navLink.ts

@@ -0,0 +1,51 @@
+import { computed, Ref } from 'vue'
+import { useRoute } from 'vitepress'
+import type { DefaultTheme } from '../config'
+import { isExternal as isExternalCheck } from '../utils'
+import { useUrl } from '../composables/url'
+
+export function useNavLink(item: Ref<DefaultTheme.NavItemWithLink>) {
+  const route = useRoute()
+  const { withBase } = useUrl()
+
+  const isExternal = isExternalCheck(item.value.link)
+
+  const props = computed(() => {
+    const routePath = normalizePath(`/${route.data.relativePath}`)
+
+    let active = false
+    if (item.value.activeMatch) {
+      active = new RegExp(item.value.activeMatch).test(routePath)
+    } else {
+      const itemPath = normalizePath(withBase(item.value.link))
+      active =
+        itemPath === '/'
+          ? itemPath === routePath
+          : routePath.startsWith(itemPath)
+    }
+
+    return {
+      class: {
+        active,
+        isExternal
+      },
+      href: isExternal ? item.value.link : withBase(item.value.link),
+      target: item.value.target || isExternal ? `_blank` : null,
+      rel: item.value.rel || isExternal ? `noopener noreferrer` : null,
+      'aria-label': item.value.ariaLabel
+    }
+  })
+
+  return {
+    props,
+    isExternal
+  }
+}
+
+function normalizePath(path: string): string {
+  return path
+    .replace(/#.*$/, '')
+    .replace(/\?.*$/, '')
+    .replace(/\.(html|md)$/, '')
+    .replace(/\/index$/, '/')
+}

+ 49 - 0
.vitepress/theme-default/composables/nextAndPrevLinks.ts

@@ -0,0 +1,49 @@
+import { computed } from 'vue'
+import { useSiteDataByRoute, usePageData } from 'vitepress'
+import { isArray, ensureStartingSlash, removeExtention } from '../utils'
+import { getSideBarConfig, getFlatSideBarLinks } from '../support/sideBar'
+
+export function useNextAndPrevLinks() {
+  const site = useSiteDataByRoute()
+  const page = usePageData()
+
+  const path = computed(() => {
+    return removeExtention(ensureStartingSlash(page.value.relativePath))
+  })
+
+  const candidates = computed(() => {
+    const config = getSideBarConfig(site.value.themeConfig.sidebar, path.value)
+
+    return isArray(config) ? getFlatSideBarLinks(config) : []
+  })
+
+  const index = computed(() => {
+    return candidates.value.findIndex((item) => {
+      return item.link === path.value
+    })
+  })
+
+  const next = computed(() => {
+    if (
+      site.value.themeConfig.nextLinks !== false &&
+      index.value > -1 &&
+      index.value < candidates.value.length - 1
+    ) {
+      return candidates.value[index.value + 1]
+    }
+  })
+
+  const prev = computed(() => {
+    if (site.value.themeConfig.prevLinks !== false && index.value > 0) {
+      return candidates.value[index.value - 1]
+    }
+  })
+
+  const hasLinks = computed(() => !!next.value || !!prev.value)
+
+  return {
+    next,
+    prev,
+    hasLinks
+  }
+}

+ 51 - 0
.vitepress/theme-default/composables/repo.ts

@@ -0,0 +1,51 @@
+import { computed } from 'vue'
+import { useSiteDataByRoute } from 'vitepress'
+import type { DefaultTheme } from '../config'
+
+export const platforms = ['GitHub', 'GitLab', 'Bitbucket'].map((platform) => {
+  return [platform, new RegExp(platform, 'i')] as const
+})
+
+export function useRepo() {
+  const site = useSiteDataByRoute()
+
+  return computed(() => {
+    const theme = site.value.themeConfig as DefaultTheme.Config
+    const name = theme.docsRepo || theme.repo
+
+    if (!name) {
+      return null
+    }
+
+    const link = getRepoUrl(name)
+    const text = getRepoText(link, theme.repoLabel)
+
+    return { text, link }
+  })
+}
+
+function getRepoUrl(repo: string): string {
+  // if the full url is not provided, default to GitHub repo
+  return /^https?:/.test(repo) ? repo : `https://github.com/${repo}`
+}
+
+function getRepoText(url: string, text?: string): string {
+  if (text) {
+    return text
+  }
+
+  // if no label is provided, deduce it from the repo url
+  const hosts = url.match(/^https?:\/\/[^/]+/)
+
+  if (!hosts) {
+    return 'Source'
+  }
+
+  const platform = platforms.find(([_p, re]) => re.test(hosts[0]))
+
+  if (platform && platform[0]) {
+    return platform[0]
+  }
+
+  return 'Source'
+}

+ 77 - 0
.vitepress/theme-default/composables/sideBar.ts

@@ -0,0 +1,77 @@
+import { computed } from 'vue'
+import { useRoute, useSiteDataByRoute } from 'vitepress'
+import { Header } from '/@types/shared'
+import { useActiveSidebarLinks } from '../composables/activeSidebarLink'
+import { getSideBarConfig } from '../support/sideBar'
+import { DefaultTheme } from '../config'
+
+export function useSideBar() {
+  const route = useRoute()
+  const site = useSiteDataByRoute()
+
+  useActiveSidebarLinks()
+
+  return computed(() => {
+    // at first, we'll check if we can find the sidebar setting in frontmatter.
+    const headers = route.data.headers
+    const frontSidebar = route.data.frontmatter.sidebar
+    const sidebarDepth = route.data.frontmatter.sidebarDepth
+
+    // if it's `false`, we'll just return an empty array here.
+    if (frontSidebar === false) {
+      return []
+    }
+
+    // if it's `atuo`, render headers of the current page
+    if (frontSidebar === 'auto') {
+      return resolveAutoSidebar(headers, sidebarDepth)
+    }
+
+    // now, there's no sidebar setting at frontmatter; let's see the configs
+    const themeSidebar = getSideBarConfig(
+      site.value.themeConfig.sidebar,
+      route.data.relativePath
+    )
+
+    if (themeSidebar === false) {
+      return []
+    }
+
+    if (themeSidebar === 'auto') {
+      return resolveAutoSidebar(headers, sidebarDepth)
+    }
+
+    return themeSidebar
+  })
+}
+
+function resolveAutoSidebar(
+  headers: Header[],
+  depth: number
+): DefaultTheme.SideBarItem[] {
+  const ret: DefaultTheme.SideBarItem[] = []
+
+  if (headers === undefined) {
+    return []
+  }
+
+  let lastH2: DefaultTheme.SideBarItem | undefined = undefined
+  headers.forEach(({ level, title, slug }) => {
+    if (level - 1 > depth) {
+      return
+    }
+
+    const item: DefaultTheme.SideBarItem = {
+      text: title,
+      link: `#${slug}`
+    }
+    if (level === 2) {
+      lastH2 = item
+      ret.push(item)
+    } else if (lastH2) {
+      ;((lastH2 as any).children || ((lastH2 as any).children = [])).push(item)
+    }
+  })
+
+  return ret
+}

+ 13 - 0
.vitepress/theme-default/composables/url.ts

@@ -0,0 +1,13 @@
+import { useSiteData, joinPath } from 'vitepress'
+
+export function useUrl() {
+  const site = useSiteData()
+
+  function withBase(path: string): string {
+    return joinPath(site.value.base, path)
+  }
+
+  return {
+    withBase
+  }
+}

+ 146 - 0
.vitepress/theme-default/config.ts

@@ -0,0 +1,146 @@
+export namespace DefaultTheme {
+  export interface Config {
+    logo?: string
+    nav?: NavItem[] | false
+    sidebar?: SideBarConfig | MultiSideBarConfig
+
+    /**
+     * GitHub repository following the format <user>/<project>.
+     *
+     * @example `"vuejs/vue-next"`
+     */
+    repo?: string
+
+    /**
+     * Customize the header label. Defaults to GitHub/Gitlab/Bitbucket
+     * depending on the provided repo.
+     *
+     * @example `"Contribute!"`
+     */
+    repoLabel?: string
+
+    /**
+     * If your docs are in a different repository from your main project.
+     *
+     * @example `"vuejs/docs-next"`
+     */
+    docsRepo?: string
+
+    /**
+     * If your docs are not at the root of the repo.
+     *
+     * @example `"docs"`
+     */
+    docsDir?: string
+
+    /**
+     * If your docs are in a different branch. Defaults to `master`.
+     *
+     * @example `"next"`
+     */
+    docsBranch?: string
+
+    /**
+     * Enable links to edit pages at the bottom of the page.
+     */
+    editLinks?: boolean
+
+    /**
+     * Custom text for edit link. Defaults to "Edit this page".
+     */
+    editLinkText?: string
+
+    /**
+     * Show last updated time at the bottom of the page. Defaults to `false`.
+     * If given a string, it will be displayed as a prefix (default value:
+     * "Last Updated").
+     */
+    lastUpdated?: string | boolean
+
+    prevLinks?: boolean
+    nextLinks?: boolean
+
+    locales?: Record<string, LocaleConfig & Omit<Config, 'locales'>>
+
+    algolia?: AlgoliaSearchOptions
+
+    carbonAds?: {
+      carbon: string
+      custom?: string
+      placement: string
+    }
+  }
+
+  // navbar --------------------------------------------------------------------
+
+  export type NavItem = NavItemWithLink | NavItemWithChildren
+
+  export interface NavItemBase {
+    text: string
+    target?: string
+    rel?: string
+    ariaLabel?: string
+    activeMatch?: string
+  }
+
+  export interface NavItemWithLink extends NavItemBase {
+    link: string
+  }
+
+  export interface NavItemWithChildren extends NavItemBase {
+    items: NavItemWithLink[]
+  }
+
+  // sidebar -------------------------------------------------------------------
+
+  export type SideBarConfig = SideBarItem[] | 'auto' | false
+
+  export interface MultiSideBarConfig {
+    [path: string]: SideBarConfig
+  }
+
+  export type SideBarItem = SideBarLink | SideBarGroup
+
+  export interface SideBarLink {
+    text: string
+    link: string
+  }
+
+  export interface SideBarGroup {
+    text: string
+    link?: string
+
+    /**
+     * @default false
+     */
+    collapsable?: boolean
+
+    children: SideBarItem[]
+  }
+
+  // algolia  ------------------------------------------------------------------
+  // partially copied from @docsearch/react/dist/esm/DocSearch.d.ts
+  export interface AlgoliaSearchOptions {
+    appId?: string
+    apiKey: string
+    indexName: string
+    placeholder?: string
+    searchParameters?: any
+    disableUserPersonalization?: boolean
+    initialQuery?: string
+  }
+
+  // locales -------------------------------------------------------------------
+
+  export interface LocaleConfig {
+    /**
+     * Text for the language dropdown.
+     */
+    selectText?: string
+
+    /**
+     * Label for this locale in the language dropdown.
+     */
+    label?: string
+  }
+}

+ 16 - 0
.vitepress/theme-default/index.ts

@@ -0,0 +1,16 @@
+import './styles/vars.css'
+import './styles/layout.css'
+import './styles/code.css'
+import './styles/custom-blocks.css'
+import './styles/sidebar-links.css'
+
+import { Theme } from 'vitepress'
+import Layout from './Layout.vue'
+import NotFound from './NotFound.vue'
+
+const theme: Theme = {
+  Layout,
+  NotFound
+}
+
+export default theme

+ 294 - 0
.vitepress/theme-default/styles/code.css

@@ -0,0 +1,294 @@
+code {
+  margin: 0;
+  border-radius: 3px;
+  padding: 0.25rem 0.5rem;
+  font-family: var(--code-font-family);
+  font-size: 0.85em;
+  color: var(--c-text-light);
+  background-color: var(--code-inline-bg-color);
+}
+
+code .token.deleted {
+  color: #ec5975;
+}
+
+code .token.inserted {
+  color: var(--c-brand);
+}
+
+div[class*='language-'] {
+  position: relative;
+  margin: 1rem -1.5rem;
+  background-color: var(--code-bg-color);
+  overflow-x: auto;
+}
+
+li > div[class*='language-'] {
+  border-radius: 6px 0 0 6px;
+  margin: 1rem -1.5rem 1rem -1.25rem;
+}
+
+@media (min-width: 420px) {
+  div[class*='language-'] {
+    margin: 1rem 0;
+    border-radius: 6px;
+  }
+
+  li > div[class*='language-'] {
+    margin: 1rem 0 1rem 0rem;
+    border-radius: 6px;
+  }
+}
+
+[class*='language-'] pre,
+[class*='language-'] code {
+  text-align: left;
+  white-space: pre;
+  word-spacing: normal;
+  word-break: normal;
+  word-wrap: normal;
+  -moz-tab-size: 4;
+  -o-tab-size: 4;
+  tab-size: 4;
+  -webkit-hyphens: none;
+  -moz-hyphens: none;
+  -ms-hyphens: none;
+  hyphens: none;
+}
+
+[class*='language-'] pre {
+  position: relative;
+  z-index: 1;
+  margin: 0;
+  padding: 1.25rem 1.5rem;
+  background: transparent;
+  overflow-x: auto;
+}
+
+[class*='language-'] code {
+  padding: 0;
+  line-height: var(--code-line-height);
+  font-size: var(--code-font-size);
+  color: #eee;
+}
+
+/* Line highlighting */
+
+.highlight-lines {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  padding: 1.25rem 0;
+  width: 100%;
+  line-height: var(--code-line-height);
+  font-family: var(--code-font-family);
+  font-size: var(--code-font-size);
+  user-select: none;
+  overflow: hidden;
+}
+
+.highlight-lines .highlighted {
+  background-color: rgba(0, 0, 0, 0.66);
+}
+
+/* Line numbers mode */
+
+div[class*='language-'].line-numbers-mode {
+  padding-left: 3.5rem;
+}
+
+.line-numbers-wrapper {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  z-index: 3;
+  border-right: 1px solid rgba(0, 0, 0, 0.5);
+  padding: 1.25rem 0;
+  width: 3.5rem;
+  text-align: center;
+  line-height: var(--code-line-height);
+  font-family: var(--code-font-family);
+  font-size: var(--code-font-size);
+  color: #888;
+}
+
+/* Language marker */
+
+[class*='language-']:before {
+  position: absolute;
+  top: 0.6em;
+  right: 1em;
+  z-index: 2;
+  font-size: 0.8rem;
+  color: #888;
+}
+
+[class~='language-html']:before,
+[class~='language-markup']:before {
+  content: 'html';
+}
+
+[class~='language-md']:before,
+[class~='language-markdown']:before {
+  content: 'md';
+}
+
+[class~='language-css']:before {
+  content: 'css';
+}
+
+[class~='language-sass']:before {
+  content: 'sass';
+}
+
+[class~='language-scss']:before {
+  content: 'scss';
+}
+
+[class~='language-less']:before {
+  content: 'less';
+}
+
+[class~='language-stylus']:before {
+  content: 'styl';
+}
+
+[class~='language-js']:before,
+[class~='language-javascript']:before {
+  content: 'js';
+}
+
+[class~='language-ts']:before,
+[class~='language-typescript']:before {
+  content: 'ts';
+}
+
+[class~='language-json']:before {
+  content: 'json';
+}
+
+[class~='language-rb']:before,
+[class~='language-ruby']:before {
+  content: 'rb';
+}
+
+[class~='language-py']:before,
+[class~='language-python']:before {
+  content: 'py';
+}
+
+[class~='language-sh']:before,
+[class~='language-bash']:before {
+  content: 'sh';
+}
+
+[class~='language-php']:before {
+  content: 'php';
+}
+
+[class~='language-go']:before {
+  content: 'go';
+}
+
+[class~='language-rust']:before {
+  content: 'rust';
+}
+
+[class~='language-java']:before {
+  content: 'java';
+}
+
+[class~='language-c']:before {
+  content: 'c';
+}
+
+[class~='language-yaml']:before {
+  content: 'yaml';
+}
+
+[class~='language-dockerfile']:before {
+  content: 'dockerfile';
+}
+
+/**
+ * prism.js tomorrow night eighties for JavaScript, CoffeeScript, CSS and HTML.
+ * Based on https://github.com/chriskempson/tomorrow-theme
+ *
+ * @author Rose Pritchard
+ */
+.token.comment,
+.token.block-comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+  color: #999;
+}
+
+.token.punctuation {
+  color: #ccc;
+}
+
+.token.tag,
+.token.attr-name,
+.token.namespace,
+.token.deleted {
+  color: #e2777a;
+}
+
+.token.function-name {
+  color: #6196cc;
+}
+
+.token.boolean,
+.token.number,
+.token.function {
+  color: #f08d49;
+}
+
+.token.property,
+.token.class-name,
+.token.constant,
+.token.symbol {
+  color: #f8c555;
+}
+
+.token.selector,
+.token.important,
+.token.atrule,
+.token.keyword,
+.token.builtin {
+  color: #cc99cd;
+}
+
+.token.string,
+.token.char,
+.token.attr-value,
+.token.regex,
+.token.variable {
+  color: #7ec699;
+}
+
+.token.operator,
+.token.entity,
+.token.url {
+  color: #67cdcc;
+}
+
+.token.important,
+.token.bold {
+  font-weight: bold;
+}
+
+.token.italic {
+  font-style: italic;
+}
+
+.token.entity {
+  cursor: help;
+}
+
+.token.inserted {
+  color: green;
+}

+ 70 - 0
.vitepress/theme-default/styles/custom-blocks.css

@@ -0,0 +1,70 @@
+.custom-block.tip,
+.custom-block.warning,
+.custom-block.danger {
+  margin: 1rem 0;
+  border-left: 0.5rem solid;
+  padding: 0.1rem 1.5rem;
+  overflow-x: auto;
+}
+
+.custom-block.tip {
+  background-color: #f3f5f7;
+  border-color: var(--c-brand);
+}
+
+.custom-block.warning {
+  border-color: #e7c000;
+  color: #6b5900;
+  background-color: rgba(255, 229, 100, 0.3);
+}
+
+.custom-block.warning .custom-block-title {
+  color: #b29400;
+}
+
+.custom-block.warning a {
+  color: var(--c-text);
+}
+
+.custom-block.danger {
+  border-color: #c00;
+  color: #4d0000;
+  background-color: #ffe6e6;
+}
+
+.custom-block.danger .custom-block-title {
+  color: #900;
+}
+
+.custom-block.danger a {
+  color: var(--c-text);
+}
+
+.custom-block.details {
+  position: relative;
+  display: block;
+  border-radius: 2px;
+  margin: 1.6em 0;
+  padding: 1.6em;
+  background-color: #eee;
+}
+
+.custom-block.details h4 {
+  margin-top: 0;
+}
+
+.custom-block.details figure:last-child,
+.custom-block.details p:last-child {
+  margin-bottom: 0;
+  padding-bottom: 0;
+}
+
+.custom-block.details summary {
+  outline: none;
+  cursor: pointer;
+}
+
+.custom-block-title {
+  margin-bottom: -0.4rem;
+  font-weight: 600;
+}

+ 236 - 0
.vitepress/theme-default/styles/layout.css

@@ -0,0 +1,236 @@
+*,
+::before,
+::after {
+  box-sizing: border-box;
+}
+
+html {
+  line-height: 1.4;
+  font-size: 16px;
+  -webkit-text-size-adjust: 100%;
+}
+
+body {
+  margin: 0;
+  width: 100%;
+  min-width: 320px;
+  min-height: 100vh;
+  line-height: 1.4;
+  font-family: var(--font-family-base);
+  font-size: 16px;
+  font-weight: 400;
+  color: var(--c-text);
+  background-color: var(--c-bg);
+  direction: ltr;
+  font-synthesis: none;
+  text-rendering: optimizeLegibility;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+main {
+  display: block;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+  margin: 0;
+  line-height: 1.25;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+strong,
+b {
+  font-weight: 600;
+}
+
+h1:hover .header-anchor,
+h1:focus .header-anchor,
+h2:hover .header-anchor,
+h2:focus .header-anchor,
+h3:hover .header-anchor,
+h3:focus .header-anchor,
+h4:hover .header-anchor,
+h4:focus .header-anchor,
+h5:hover .header-anchor,
+h5:focus .header-anchor,
+h6:hover .header-anchor,
+h6:focus .header-anchor {
+  opacity: 1;
+}
+
+h1 {
+  margin-top: 1.5rem;
+  font-size: 1.9rem;
+}
+
+@media screen and (min-width: 420px) {
+  h1 {
+    font-size: 2.2rem;
+  }
+}
+
+h2 {
+  margin-top: 2.25rem;
+  margin-bottom: 1.25rem;
+  border-bottom: 1px solid var(--c-divider);
+  padding-bottom: 0.3rem;
+  line-height: 1.25;
+  font-size: 1.65rem;
+  /* overflow-x: auto; */
+}
+
+h2 + h3 {
+  margin-top: 1.5rem;
+}
+
+h3 {
+  margin-top: 2rem;
+  font-size: 1.35rem;
+}
+
+h4 {
+  font-size: 1.15rem;
+}
+
+p,
+ol,
+ul {
+  margin: 1rem 0;
+  line-height: 1.7;
+}
+
+a,
+area,
+button,
+[role='button'],
+input,
+label,
+select,
+summary,
+textarea {
+  touch-action: manipulation;
+}
+
+a {
+  text-decoration: none;
+  color: var(--c-brand);
+}
+
+a:hover {
+  text-decoration: underline;
+}
+
+a.header-anchor {
+  float: left;
+  margin-top: 0.125em;
+  margin-left: -0.87em;
+  padding-right: 0.23em;
+  font-size: 0.85em;
+  opacity: 0;
+}
+
+a.header-anchor:hover,
+a.header-anchor:focus {
+  text-decoration: none;
+}
+
+figure {
+  margin: 0;
+}
+
+img {
+  max-width: 100%;
+}
+
+ul,
+ol {
+  padding-left: 1.25em;
+}
+
+li > ul,
+li > ol {
+  margin: 0;
+}
+
+table {
+  display: block;
+  border-collapse: collapse;
+  margin: 1rem 0;
+  overflow-x: auto;
+}
+
+tr {
+  border-top: 1px solid #dfe2e5;
+}
+
+tr:nth-child(2n) {
+  background-color: #f6f8fa;
+}
+
+th,
+td {
+  border: 1px solid #dfe2e5;
+  padding: 0.6em 1em;
+}
+
+blockquote {
+  margin: 1rem 0;
+  border-left: 0.2rem solid #dfe2e5;
+  padding: 0.25rem 0 0.25rem 1rem;
+  font-size: 1rem;
+  color: #999;
+}
+
+blockquote > p {
+  margin: 0;
+}
+
+form {
+  margin: 0;
+}
+
+.theme.sidebar-open .sidebar-mask {
+  display: block;
+}
+
+.theme.no-navbar > h1,
+.theme.no-navbar > h2,
+.theme.no-navbar > h3,
+.theme.no-navbar > h4,
+.theme.no-navbar > h5,
+.theme.no-navbar > h6 {
+  margin-top: 1.5rem;
+  padding-top: 0;
+}
+
+.theme.no-navbar aside {
+  top: 0;
+}
+
+@media screen and (min-width: 720px) {
+  .theme.no-sidebar aside {
+    display: none;
+  }
+
+  .theme.no-sidebar main {
+    margin-left: 0;
+  }
+}
+
+.sidebar-mask {
+  position: fixed;
+  z-index: 2;
+  display: none;
+  width: 100vw;
+  height: 100vh;
+}

+ 107 - 0
.vitepress/theme-default/styles/sidebar-links.css

@@ -0,0 +1,107 @@
+.sidebar-links {
+  margin: 0;
+  padding: 0;
+  list-style: none;
+}
+
+.sidebar-link-item {
+  display: block;
+  margin: 0;
+  border-left: 0.25rem solid transparent;
+  color: var(--c-text);
+}
+
+a.sidebar-link-item:hover {
+  text-decoration: none;
+  color: var(--c-brand);
+}
+
+a.sidebar-link-item.active {
+  color: var(--c-brand);
+}
+
+.sidebar > .sidebar-links {
+  padding: 0.75rem 0 5rem;
+}
+
+@media (min-width: 720px) {
+  .sidebar > .sidebar-links {
+    padding: 1.5rem 0;
+  }
+}
+
+.sidebar > .sidebar-links > .sidebar-link + .sidebar-link {
+  padding-top: 0.5rem;
+}
+
+@media (min-width: 720px) {
+  .sidebar > .sidebar-links > .sidebar-link + .sidebar-link {
+    padding-top: 1.25rem;
+  }
+}
+
+.sidebar > .sidebar-links > .sidebar-link > .sidebar-link-item {
+  padding: 0.35rem 1.5rem 0.35rem 1.25rem;
+  font-size: 1.1rem;
+  font-weight: 700;
+}
+
+.sidebar > .sidebar-links > .sidebar-link > a.sidebar-link-item.active {
+  border-left-color: var(--c-brand);
+  font-weight: 600;
+}
+
+.sidebar
+  > .sidebar-links
+  > .sidebar-link
+  > .sidebar-links
+  > .sidebar-link
+  > .sidebar-link-item {
+  display: block;
+  padding: 0.35rem 1.5rem 0.35rem 2rem;
+  line-height: 1.4;
+  font-size: 1rem;
+  font-weight: 400;
+}
+
+.sidebar
+  > .sidebar-links
+  > .sidebar-link
+  > .sidebar-links
+  > .sidebar-link
+  > a.sidebar-link-item.active {
+  border-left-color: var(--c-brand);
+  font-weight: 600;
+}
+
+.sidebar
+  > .sidebar-links
+  > .sidebar-link
+  > .sidebar-links
+  > .sidebar-link
+  > .sidebar-links
+  > .sidebar-link
+  > .sidebar-link-item {
+  display: block;
+  padding: 0.3rem 1.5rem 0.3rem 3rem;
+  line-height: 1.4;
+  font-size: 0.9rem;
+  font-weight: 400;
+}
+
+.sidebar
+  > .sidebar-links
+  > .sidebar-link
+  > .sidebar-links
+  > .sidebar-link
+  > .sidebar-links
+  > .sidebar-link
+  > .sidebar-links
+  > .sidebar-link
+  > .sidebar-link-item {
+  display: block;
+  padding: 0.3rem 1.5rem 0.3rem 4rem;
+  line-height: 1.4;
+  font-size: 0.9rem;
+  font-weight: 400;
+}

+ 74 - 0
.vitepress/theme-default/styles/vars.css

@@ -0,0 +1,74 @@
+/** Base Styles */
+:root {
+  /**
+   * Colors
+   * --------------------------------------------------------------------- */
+
+  --c-white: #ffffff;
+  --c-white-dark: #f8f8f8;
+  --c-black: #000000;
+
+  --c-divider-light: rgba(60, 60, 67, 0.12);
+  --c-divider-dark: rgba(84, 84, 88, 0.48);
+
+  --c-text-light-1: #2c3e50;
+  --c-text-light-2: #476582;
+  --c-text-light-3: #90a4b7;
+
+  --c-brand: #3eaf7c;
+  --c-brand-light: #4abf8a;
+
+  /**
+   * Typography
+   * --------------------------------------------------------------------- */
+
+  --font-family-base: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
+    Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
+    sans-serif;
+  --font-family-mono: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
+    monospace;
+
+  /**
+   * Z Indexes
+   *
+   * Algolia SearchBox has a z-index of 200, so make sure not to go above
+   * that value.
+   * --------------------------------------------------------------------- */
+
+  --z-index-navbar: 10;
+  --z-index-sidebar: 6;
+
+  /**
+   * Shadows
+   * --------------------------------------------------------------------- */
+
+  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.06);
+  --shadow-2: 0 3px 12px rgba(0, 0, 0, 0.07), 0 1px 4px rgba(0, 0, 0, 0.07);
+  --shadow-3: 0 12px 32px rgba(0, 0, 0, 0.1), 0 2px 6px rgba(0, 0, 0, 0.08);
+  --shadow-4: 0 14px 44px rgba(0, 0, 0, 0.12), 0 3px 9px rgba(0, 0, 0, 0.12);
+  --shadow-5: 0 18px 56px rgba(0, 0, 0, 0.16), 0 4px 12px rgba(0, 0, 0, 0.16);
+
+  /**
+   * Sizes
+   * --------------------------------------------------------------------- */
+
+  --header-height: 3.6rem;
+}
+
+/** Fallback Styles */
+:root {
+  --c-divider: var(--c-divider-light);
+
+  --c-text: var(--c-text-light-1);
+  --c-text-light: var(--c-text-light-2);
+  --c-text-lighter: var(--c-text-light-3);
+
+  --c-bg: var(--c-white);
+  --c-bg-accent: var(--c-white-dark);
+
+  --code-line-height: 24px;
+  --code-font-family: var(--font-family-mono);
+  --code-font-size: 14px;
+  --code-inline-bg-color: rgba(27, 31, 35, 0.05);
+  --code-bg-color: #282c34;
+}

+ 66 - 0
.vitepress/theme-default/support/sideBar.ts

@@ -0,0 +1,66 @@
+import { DefaultTheme } from '../config'
+import { isArray, ensureStartingSlash, removeExtention } from '../utils'
+
+export function isSideBarConfig(
+  sidebar: DefaultTheme.SideBarConfig | DefaultTheme.MultiSideBarConfig
+): sidebar is DefaultTheme.SideBarConfig {
+  return sidebar === false || sidebar === 'auto' || isArray(sidebar)
+}
+
+export function isSideBarGroup(
+  item: DefaultTheme.SideBarItem
+): item is DefaultTheme.SideBarGroup {
+  return (item as DefaultTheme.SideBarGroup).children !== undefined
+}
+
+export function isSideBarEmpty(sidebar?: DefaultTheme.SideBarConfig): boolean {
+  return isArray(sidebar) ? sidebar.length === 0 : !sidebar
+}
+
+/**
+ * Get the `SideBarConfig` from sidebar option. This method will ensure to get
+ * correct sidebar config from `MultiSideBarConfig` with various path
+ * combinations such as matching `guide/` and `/guide/`. If no matching config
+ * was found, it will return `auto` as a fallback.
+ */
+export function getSideBarConfig(
+  sidebar: DefaultTheme.SideBarConfig | DefaultTheme.MultiSideBarConfig,
+  path: string
+): DefaultTheme.SideBarConfig {
+  if (isSideBarConfig(sidebar)) {
+    return sidebar
+  }
+
+  path = ensureStartingSlash(path)
+
+  for (const dir in sidebar) {
+    // make sure the multi sidebar key starts with slash too
+    if (path.startsWith(ensureStartingSlash(dir))) {
+      return sidebar[dir]
+    }
+  }
+
+  return 'auto'
+}
+
+/**
+ * Get flat sidebar links from the sidebar items. This method is useful for
+ * creating the "next and prev link" feature. It will ignore any items that
+ * don't have `link` property and removes `.md` or `.html` extension if a
+ * link contains it.
+ */
+export function getFlatSideBarLinks(
+  sidebar: DefaultTheme.SideBarItem[]
+): DefaultTheme.SideBarLink[] {
+  return sidebar.reduce<DefaultTheme.SideBarLink[]>((links, item) => {
+    if (item.link) {
+      links.push({ text: item.text, link: removeExtention(item.link) })
+    }
+
+    if (isSideBarGroup(item)) {
+      links = [...links, ...getFlatSideBarLinks(item.children)]
+    }
+
+    return links
+  }, [])
+}

+ 83 - 0
.vitepress/theme-default/utils.ts

@@ -0,0 +1,83 @@
+import { Route } from 'vitepress'
+
+export const hashRE = /#.*$/
+export const extRE = /(index)?\.(md|html)$/
+export const endingSlashRE = /\/$/
+export const outboundRE = /^[a-z]+:/i
+
+export function isNullish(value: any): value is null | undefined {
+  return value === null || value === undefined
+}
+
+export function isArray(value: any): value is any[] {
+  return Array.isArray(value)
+}
+
+export function isExternal(path: string): boolean {
+  return outboundRE.test(path)
+}
+
+export function isActive(route: Route, path?: string): boolean {
+  if (path === undefined) {
+    return false
+  }
+
+  const routePath = normalize(`/${route.data.relativePath}`)
+  const pagePath = normalize(path)
+
+  return routePath === pagePath
+}
+
+export function normalize(path: string): string {
+  return decodeURI(path).replace(hashRE, '').replace(extRE, '')
+}
+
+export function joinUrl(base: string, path: string): string {
+  const baseEndsWithSlash = base.endsWith('/')
+  const pathStartsWithSlash = path.startsWith('/')
+
+  if (baseEndsWithSlash && pathStartsWithSlash) {
+    return base.slice(0, -1) + path
+  }
+
+  if (!baseEndsWithSlash && !pathStartsWithSlash) {
+    return `${base}/${path}`
+  }
+
+  return base + path
+}
+
+/**
+ * get the path without filename (the last segment). for example, if the given
+ * path is `/guide/getting-started.html`, this method will return `/guide/`.
+ * Always with a trailing slash.
+ */
+export function getPathDirName(path: string): string {
+  const segments = path.split('/')
+
+  if (segments[segments.length - 1]) {
+    segments.pop()
+  }
+
+  return ensureEndingSlash(segments.join('/'))
+}
+
+export function ensureSlash(path: string): string {
+  return ensureEndingSlash(ensureStartingSlash(path))
+}
+
+export function ensureStartingSlash(path: string): string {
+  return /^\//.test(path) ? path : `/${path}`
+}
+
+export function ensureEndingSlash(path: string): string {
+  return /(\.html|\/)$/.test(path) ? path : `${path}/`
+}
+
+/**
+ * Remove `.md` or `.html` extention from the given path. It also converts
+ * `index` to slush.
+ */
+export function removeExtention(path: string): string {
+  return path.replace(/(index)?(\.(md|html))?$/, '') || '/'
+}

+ 14 - 0
.vitepress/theme/index.ts

@@ -0,0 +1,14 @@
+import Theme from '../theme-default/index';
+
+import 'windi-base.css';
+import 'windi-components.css';
+import 'windi-utilities.css';
+
+import './styles/var.css';
+import './styles/custom.css';
+import './styles/layout.css';
+import './styles/code-theme.css';
+
+export default {
+  ...Theme,
+};

+ 292 - 0
.vitepress/theme/styles/code-theme.css

@@ -0,0 +1,292 @@
+[class*='language-'] code {
+  color: inherit;
+}
+
+code[class*='language-'],
+pre[class*='language-'] {
+  color: #d6deeb;
+  /* font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; */
+  text-align: left;
+  white-space: pre;
+  word-spacing: normal;
+  word-break: normal;
+  word-wrap: normal;
+  line-height: 1.5;
+
+  -moz-tab-size: 4;
+  -o-tab-size: 4;
+  tab-size: 4;
+
+  -webkit-hyphens: none;
+  -moz-hyphens: none;
+  -ms-hyphens: none;
+  hyphens: none;
+}
+
+pre[class*='language-']::-moz-selection,
+pre[class*='language-'] ::-moz-selection,
+code[class*='language-']::-moz-selection,
+code[class*='language-'] ::-moz-selection {
+  text-shadow: none;
+  background: rgba(29, 59, 83, 0.99);
+}
+
+pre[class*='language-']::selection,
+pre[class*='language-'] ::selection,
+code[class*='language-']::selection,
+code[class*='language-'] ::selection {
+  text-shadow: none;
+  background: rgba(29, 59, 83, 0.99);
+}
+
+@media print {
+  code[class*='language-'],
+  pre[class*='language-'] {
+    text-shadow: none;
+  }
+}
+
+/* Code blocks */
+pre[class*='language-'] {
+  padding: 1em;
+  margin: 0.5em 0;
+  overflow: auto;
+}
+
+:not(pre) > code[class*='language-'],
+pre[class*='language-'] {
+  color: white;
+  background: #011627;
+}
+
+:not(pre) > code[class*='language-'] {
+  padding: 0.1em;
+  border-radius: 0.3em;
+  white-space: normal;
+}
+
+.token.comment,
+.token.prolog,
+.token.cdata {
+  color: rgb(99, 119, 119);
+}
+
+.token.punctuation {
+  color: rgb(199, 146, 234);
+}
+
+.namespace {
+  color: rgb(178, 204, 214);
+}
+
+.token.deleted {
+  color: rgb(239, 83, 80);
+}
+
+.token.symbol,
+.token.property {
+  color: rgb(128, 203, 196);
+}
+
+.token.tag,
+.token.operator,
+.token.keyword {
+  color: rgb(127, 219, 202);
+}
+
+.token.boolean {
+  color: rgb(255, 88, 116);
+}
+
+.token.number {
+  color: rgb(247, 140, 108);
+}
+
+.token.constant,
+.token.function,
+.token.builtin,
+.token.char {
+  color: rgb(130, 170, 255);
+}
+
+.token.selector,
+.token.function,
+.token.doctype {
+  color: rgb(199, 146, 234);
+}
+
+.token.attr-name,
+.token.inserted,
+code .token.inserted {
+  color: rgb(173, 219, 103);
+}
+
+.token.string,
+.token.url,
+.token.entity,
+.language-css .token.string,
+.style .token.string {
+  color: rgb(173, 219, 103);
+}
+
+.token.class-name,
+.token.atrule,
+.token.attr-value {
+  color: rgb(255, 203, 139);
+}
+
+.token.regex,
+.token.important,
+.token.variable {
+  color: rgb(214, 222, 235);
+}
+
+.token.important,
+.token.bold {
+  font-weight: bold;
+}
+
+html.dark tr:nth-child(2n) {
+  background-color: transparent !important;
+}
+
+/* LIGHT THEME */
+
+html.light code[class*='language-'],
+html.light pre[class*='language-'] {
+  color: #403f53;
+  /* font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; */
+  text-align: left;
+  white-space: pre;
+  word-spacing: normal;
+  word-break: normal;
+  word-wrap: normal;
+  line-height: 1.5;
+
+  -moz-tab-size: 4;
+  -o-tab-size: 4;
+  tab-size: 4;
+
+  -webkit-hyphens: none;
+  -moz-hyphens: none;
+  -ms-hyphens: none;
+  hyphens: none;
+}
+
+html.light pre[class*='language-']::-moz-selection,
+html.light pre[class*='language-'] ::-moz-selection,
+html.light code[class*='language-']::-moz-selection,
+html.light code[class*='language-'] ::-moz-selection {
+  text-shadow: none;
+  background: #fbfbfb;
+}
+
+html.light pre[class*='language-']::selection,
+html.light pre[class*='language-'] ::selection,
+html.light code[class*='language-']::selection,
+html.light code[class*='language-'] ::selection {
+  text-shadow: none;
+  background: #fbfbfb;
+}
+
+@media print {
+  html.light code[class*='language-'],
+  html.light pre[class*='language-'] {
+    text-shadow: none;
+  }
+}
+
+/* Code blocks */
+html.light pre[class*='language-'] {
+  padding: 1em;
+  margin: 0.5em 0;
+  overflow: auto;
+}
+
+html.light :not(pre) > code[class*='language-'],
+html.light pre[class*='language-'] {
+  color: white;
+  background: #fbfbfb;
+}
+
+html.light :not(pre) > code[class*='language-'] {
+  padding: 0.1em;
+  border-radius: 0.3em;
+  white-space: normal;
+}
+
+html.light .token.comment,
+html.light .token.prolog,
+html.light .token.cdata {
+  color: rgb(152, 159, 177);
+}
+
+html.light .token.punctuation {
+  color: rgb(153, 76, 195);
+}
+
+html.light .namespace {
+  color: rgb(12, 150, 155);
+}
+
+html.light code .token.deleted {
+  color: #ec5975;
+}
+
+html.light .token.symbol,
+html.light .token.operator,
+html.light .token.keyword,
+html.light .token.property {
+  color: rgb(12, 150, 155);
+}
+
+html.light .token.tag {
+  color: rgb(153, 76, 195);
+}
+
+html.light .token.boolean {
+  color: rgb(188, 84, 84);
+}
+
+html.light .token.number {
+  color: rgb(170, 9, 130);
+}
+
+html.light .token.constant,
+html.light .token.builtin,
+html.light .token.string,
+html.light .token.url,
+html.light .token.entity,
+html.light .language-css .token.string,
+html.light .style .token.string,
+html.light .token.char {
+  color: rgb(72, 118, 214);
+}
+
+html.light .token.selector,
+html.light .token.function,
+html.light .token.doctype {
+  color: rgb(153, 76, 195);
+}
+
+html.light .token.attr-name,
+html.light .token.inserted {
+  color: rgb(72, 118, 214);
+}
+
+html.light .token.class-name,
+html.light .token.atrule,
+html.light .token.attr-value {
+  color: rgb(17, 17, 17);
+}
+
+html.light .token.regex,
+html.light .token.important,
+html.light .token.variable {
+  color: rgb(201, 103, 101);
+}
+
+html.light .token.important,
+html.light .token.bold {
+  font-weight: bold;
+}

+ 125 - 0
.vitepress/theme/styles/custom.css

@@ -0,0 +1,125 @@
+.home-hero .image {
+  width: 100px;
+  height: 100px;
+}
+
+.nav-bar .logo {
+  height: 26px;
+  margin-right: 8px;
+}
+
+.nav-bar .nav-bar-title {
+  display: flex;
+  align-items: center;
+}
+
+.content img {
+  border-radius: 10px;
+}
+
+.nav-dropdown-link-item .icon {
+  display: none;
+}
+
+.action.alt .icon.outbound {
+  color: currentColor;
+}
+
+.action .item.item.item {
+  border-color: var(--c-brand);
+  background-color: var(--c-brand);
+}
+
+.action.alt .item.item.item {
+  background-color: transparent;
+}
+
+.action .item.item.item,
+.action .item.item.item:hover {
+  color: var(--c-brand-text);
+}
+
+.action.alt .item.item.item {
+  color: var(--c-text);
+  border-color: var(--c-brand);
+  /* transition when toggling dark mode */
+  transition: background-color 150ms ease-in-out, border-color 150ms ease-in-out,
+    color 150ms ease-in-out;
+}
+
+html.dark .action.alt .item.item.item {
+  border-color: var(--c-text);
+}
+
+.action.alt .item.item.item:hover {
+  background-color: var(--c-brand-light);
+  border-color: var(--c-brand-light);
+  color: var(--c-brand-text);
+}
+
+.nav-bar.nav-bar {
+  background-color: var(--c-bg);
+}
+
+.content img {
+  border-radius: 10px;
+}
+
+/* hide external links icons in menus */
+.nav-dropdown-link-item .icon {
+  display: none;
+}
+
+.custom-block.tip {
+  border-color: var(--c-brand-light);
+  background-color: var(--c-bg-accent);
+}
+
+.carbon-ads {
+  /* display space with the background in mobile too */
+  padding: 8px;
+}
+
+.carbon-ads,
+.bsa-cpc {
+  background-color: var(--c-bg-accent) !important;
+}
+
+html:not(.light) .custom-block.warning {
+  color: var(--c-text);
+}
+
+html:not(.light) .custom-block.warning a {
+  color: var(--c-brand);
+}
+
+body,
+.nav-bar,
+.carbon-ads,
+.bsa-cpc,
+.custom-block.tip,
+code,
+div[class*='language-'],
+.action.alt .item.item {
+  transition: background-color 300ms ease-in-out, color 300ms ease-in-out;
+}
+
+.sidebar.sidebar.sidebar,
+.DocSearch,
+.DocSearch-Search-Icon,
+.DocSearch-Form {
+  /* transition when toggling dark mode */
+  transition: transform 250ms ease, background-color 300ms ease-in-out, color 300ms ease-in-out;
+}
+
+.DocSearch-Button-Key,
+.DocSearch-Footer,
+.DocSearch-Modal {
+  transition: background-color 300ms ease-in-out, color 300ms ease-in-out,
+    box-shadow 250ms ease-in-out;
+}
+
+code {
+  font-size: 0.95em;
+  padding: 0.175em 0.35em;
+}

+ 63 - 0
.vitepress/theme/styles/layout.css

@@ -0,0 +1,63 @@
+input {
+  border: 1px solid #d9d9d9;
+  padding: 8px 6px;
+  border-radius: 4px;
+  color: rgba(0, 0, 0, 0.65);
+  outline: none;
+}
+
+input:focus {
+  border-color: #40a9ff;
+}
+
+button {
+  padding: 5px 16px;
+  border-radius: 2px;
+  color: rgba(0, 0, 0, 0.65);
+  outline: none;
+  border: 1px solid #d9d9d9;
+  cursor: pointer;
+  background: #fff;
+}
+
+button:hover {
+  border-color: #40a9ff;
+  color: #40a9ff;
+}
+
+::-webkit-input-placeholder,
+:-moz-placeholder,
+::-moz-placeholder,
+:-ms-input-placeholder {
+  color: var(--placeholder-color);
+}
+
+.nav-btn {
+  display: flex;
+  font-size: 1.05rem;
+  border: 0;
+  outline: none;
+  background: none;
+  color: var(--c-text);
+  opacity: 0.8;
+  cursor: pointer;
+}
+.nav-btn:hover {
+  opacity: 1;
+}
+.nav-btn svg {
+  margin: auto;
+}
+
+.slugs {
+  position: fixed;
+  top: var(--header-height);
+  right: 0;
+  max-height: calc(100% - var(--header-height) - 10rem);
+  width: var(--slug-width);
+  padding: 50px 24px 0 0;
+  border-right: 1px solid var(--border-color);
+  background-color: #fff;
+  z-index: 3;
+  overflow-y: auto;
+}

+ 55 - 0
.vitepress/theme/styles/var.css

@@ -0,0 +1,55 @@
+:root {
+  --c-brand: #409eff;
+  --c-brand-light: #66b1ff;
+
+  --c-white-dark: #f8f8f8;
+  --c-black: #111827;
+  --c-black-light: #161f32;
+  --c-black-lighter: #262a44;
+  --c-text-dark-1: #d9e6eb;
+  --c-text-dark-2: #c4dde6;
+  --c-text-dark-3: #abc4cc;
+
+  --c-brand-text: var(--c-white);
+  --c-bg-accent: var(--c-white-dark);
+
+  --code-bg-color: var(--c-white-dark);
+  --code-inline-bg-color: var(--c-white-dark);
+  --code-font-family: 'dm', source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
+  --code-font-size: 16px;
+
+  --slug-width: 10rem;
+  --header-height: 3.6rem;
+  --sidebar-width: 16.4rem;
+}
+
+html:not(.light):root {
+  --c-text: var(--c-text-dark-1);
+  --c-text-light: var(--c-text-dark-2);
+  --c-text-lighter: var(--c-text-dark-3);
+  --c-divider: var(--c-divider-dark);
+  --c-bg: var(--c-black);
+  --c-bg-accent: var(--c-black-light);
+  --code-bg-color: var(--c-black-light);
+  --code-inline-bg-color: var(--c-black-light);
+}
+
+html:not(.light) .DocSearch {
+  --docsearch-text-color: var(--c-white-dark);
+  --docsearch-container-background: rgba(9, 10, 17, 0.8);
+  --docsearch-modal-background: var(--c-black);
+  --docsearch-modal-shadow: inset 1px 1px 0 0 #2c2e40, 0 3px 8px 0 #000309;
+  --docsearch-searchbox-background: var(--c-black-lighter);
+  --docsearch-searchbox-focus-background: var(--c-black-light);
+  --docsearch-hit-color: var(--c-text-dark-1);
+  --docsearch-hit-active-color: var(--c-brand-text);
+  --docsearch-hit-shadow: none;
+  --docsearch-hit-background: var(--c-black-light);
+  --docsearch-key-gradient: linear-gradient(-26.5deg, #565872, #31355b);
+  --docsearch-key-shadow: inset 0 -2px 0 0 #282d55, inset 0 0 1px 1px #51577d,
+    0 2px 2px 0 rgba(3, 4, 9, 0.3);
+  --docsearch-footer-background: var(--c-black-light);
+  --docsearch-footer-shadow: inset 0 1px 0 0 rgba(73, 76, 106, 0.5), 0 -4px 8px 0 rgba(0, 0, 0, 0.2);
+  --docsearch-logo-color: var(--c-white-dark);
+  --docsearch-muted-color: var(--c-text-dark-1);
+}

+ 14 - 0
README.md

@@ -0,0 +1,14 @@
+# vue-element-plus-admin-doc
+
+## 如何本地开发
+
+```bash
+# 克隆本仓库
+$ git clone https://github.com/kailong321200875/vue-element-plus-admin-doc.git
+
+# 安装依赖
+$ yarn
+
+# 启动开发服务器
+$ npm run dev
+```

+ 160 - 0
components/form.md

@@ -0,0 +1,160 @@
+# Form 表单组件
+
+对 `element-plus` 的 `Form` 组件进行封装,支持 `element-plus` 的所有表单组件,并额外扩展了一些功能。
+
+Form 组件位于 [src/components/Form](https://github.com/kailong321200875/vue-element-plus-admin/tree/master/src/components/Form) 内
+
+## 用法
+
+### refForm
+
+refForm 的简单用法,如果想看更复杂点的例子,请[在线预览](https://element-plus-admin.cn/#/components/form/ref-form)
+
+```vue
+<script setup lang="ts">
+import { Form } from '@/components/Form'
+import { reactive } from 'vue'
+
+const schema = reactive<FormSchema[]>([
+  {
+    field: 'field1',
+    label: 'input',
+    component: 'Input'
+  }
+])
+</script>
+
+<template>
+  <Form :schema="schema" />
+</template>
+
+```
+
+### useForm
+
+除了使用 `refFrom` 的方式外,还可以使用 `useForm` 进行渲染,如果想看更复杂点的例子,请[在线预览](https://element-plus-admin.cn/#/components/form/use-form)
+
+```vue
+<script setup lang="ts">
+import { Form } from '@/components/Form'
+import { reactive } from 'vue'
+import { useForm } from '@/hooks/web/useForm'
+
+const schema = reactive<FormSchema[]>([
+  {
+    field: 'field1',
+    label: 'input',
+    component: 'Input'
+  }
+])
+
+const { register } = useForm({
+  schema
+})
+</script>
+
+<template>
+  <Form />
+</template>
+
+```
+
+#### 参数介绍
+
+```ts
+const { register, elFormRef, methods } = useForm(props)
+```
+
+**register**
+
+`register` 用于注册 `useForm`,如果需要使用 `useForm` 提供的 `api`,必须将 `register` 传入组件的 `onRegister`
+
+**elFormRef**
+
+当前 `elForm` 实例,可是用所有 `elForm` 实例方法。
+
+**methods**
+
+| 方法名 | 说明 | 回调参数 |
+| ---- | ---- | ---- |
+| setValues | 用于设置表单值 | (data: Recordable) => void |
+| setProps | 用于设置表单属性 | (props: Recordable) => void |
+| delSchema | 用于删除表单结构 | (field: string) => void |
+| addSchema | 用于新增表单结构 | (formSchema: FormSchema, index?: number) => void |
+| setSchema | 用于编辑表单结构 | (schemaProps: FormSetPropsType[]) => void |
+| getFormData | 用于获取表单数据 | <T = Recordable | undefined>() => Promise<T> |
+
+## Form 属性
+
+除以下参数外,还支持 `element-plus` 的 `Form` 所有属性,[详见](https://element-plus.org/zh-CN/component/form.html#form-%E5%B1%9E%E6%80%A7)
+
+| 属性 | 说明 | 类型 | 可选值 | 默认值 |
+| ---- | ---- | ---- | ---- | ---- |
+| schema | 生成 Form 的布局结构数组,[详见](#Schema) | `FormSchema` | - | [] |
+| isCol | 是否需要栅格布局 | `boolean` | - | true |
+| model | 表单数据对象 | `Recordable` | - | {} |
+| autoSetPlaceholder | 是否自动设置 placeholder | `boolean` | - | true |
+| isCustom | 是否自定义内容 | `boolean` | - | false |
+| labelWidth | 表单 label 宽度 | `string`/`number` | - | auto |
+
+### Schema<span id="Schema"></span>
+
+| 属性 | 说明 | 类型 | 可选值 | 默认值 |
+| ---- | ---- | ---- | ---- | ---- |
+| field | 唯一值,必填项 | `string` | - | - |
+| label | 标题 | `string` | - | - |
+| colProps | element-plus 的 col 组件属性 | `ColProps` | - | - |
+| componentProps | 表单组件子属性,[详见](#ComponentProps) | `{ slots?: Recordable } & ComponentProps` | - | - |
+| formItemProps | element-plus 的 form-item 组件属性,[详见](#FormItemProps) | `FormItemProps` | - | - |
+| component | 需要渲染的表单子组件 | `ComponentName` | - | - |
+| value | 表单子组件初始值 | `FormValueType` | - | - |
+| hidden | 表单子组件是否隐藏 | `boolean` | - | - |
+
+### ComponentProps<span id="ComponentProps"></span>
+
+除以下属性外,还支持 `component` 对应的组件所有属性。
+
+| 属性 | 说明 | 类型 | 可选值 | 默认值 |
+| ---- | ---- | ---- | ---- | ---- |
+| optionsAlias | options 别名 | `ComponentOptionsAlias` | - | - |
+| options | options 数据 | `ComponentOptions` | - | - |
+| optionsSlot | options 插槽 | `boolean` | - | - |
+
+### FormItemProps<span id="FormItemProps"></span>
+
+| 属性 | 说明 | 类型 | 可选值 | 默认值 |
+| ---- | ---- | ---- | ---- | ---- |
+| labelWidth | 标题的宽度 | `string`/`number` | - | - |
+| required | 是否必填 | `boolean` | - | - |
+| rules | 自定义表单验证 | `Recordable` | - | - |
+| error | 验证不通过展示的提示 | `string` | - | - |
+| showMessage | 验证不通过是否展示提示 | `boolean` | - | - |
+| inlineMessage | 是否以行内形式展示验证提示 | `boolean` | - | - |
+| style | 子表单项的样式 | `CSSProperties` | - | - |
+
+## Form 方法
+
+| 方法名 | 说明 | 回调参数 |
+| ---- | ---- | ---- |
+| setValues | 用于设置表单值 | (data: Recordable) => void |
+| setProps | 用于设置表单属性 | (props: Recordable) => void |
+| delSchema | 用于删除表单结构 | (field: string) => void |
+| addSchema | 用于新增表单结构 | (formSchema: FormSchema, index?: number) => void |
+| setSchema | 用于编辑表单结构 | (schemaProps: FormSetPropsType[]) => void |
+| getElFormRef | 用于获取 `element-plus` 的 `Form` 组件实例 | `() => ComponentRef<typeof ElForm>` |
+
+## Form 插槽
+
+| 插槽名 | 说明 | 子标签 |
+| ---- | ---- | ---- |
+| - | 存放所有的 form-item 内容,或者其他标签内容 | FormItem |
+| ${field} | form-item 的内容,可用于自定义表单项组件内容 | - |
+| ${field}-label | form-item 标题上显示的自定义内容。| - |
+| ${field}-error | form-item 自定义内容以显示验证消息。| - |
+
+## 如何新增表单子组件
+
+当项目中内置的表单组件不满足需求时,可以自行添加组件进去。
+
+1. 在 [src/types/componentType/form.d.ts](https://github.com/kailong321200875/vue-element-plus-admin/tree/master/src/types/componentType/form.d.ts) 的 `ComponentName` 添加你组件名称。
+2. 在 [src/components/Form/src/componentMap.ts](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/src/components/Form/src/componentMap.ts) 引入你自己的组件,并在 `componentMap` 对象中添加键值对即可。

+ 34 - 0
components/icon.md

@@ -0,0 +1,34 @@
+# Icon 图标组件
+
+用于项目内组件的展示,基本支持所有图标库(支持按需加载,只打包所用到的图标),支持使用本地 svg 和 Iconify 图标。
+
+Icon 组件位于 [src/components/Icon](https://github.com/kailong321200875/vue-element-plus-admin/tree/master/src/components/Icon) 内
+
+::: tip
+
+在 [Iconify](https://iconify.design) 上,你可以查询到你想要的所有图标并使用,不管是不是 `element-plus` 的图标库。
+
+:::
+
+## 用法
+
+如果以`svg-icon:` 开头,则会在本地中找到该 `svg` 图标,否则,会加载 `Iconify` 图标。
+
+```vue
+<template>
+  <!-- 加载本地 svg -->
+  <Icon icon="svg-icon:peoples" />
+  
+  <!-- 加载 Iconify -->
+  <Icon icon="ep:aim" />
+</template>
+
+```
+
+## Icon 属性
+
+| 属性 | 说明 | 类型 | 可选值 | 默认值 |
+| ---- | ---- | ---- | ---- | ---- |
+| icon | 图标名 | `string` | - | - |
+| color | 图标颜色 | `string` | - | - |
+| size | 图标大小 | `number` | - | 16 |

+ 5 - 0
components/introduction.md

@@ -0,0 +1,5 @@
+# 前言
+
+本项目中集成了很多常用的功能组件,方便开发者使用。如果你开发项目中自带的组件不满足你的需求,可以不使用或者自行改造,这都是可以的。
+
+目前本项目中基本上都是采用按需引入的方式,只有 `Icon` 进行了全局注册。

+ 5 - 0
dep/dark.md

@@ -0,0 +1,5 @@
+# 黑暗主题
+
+## 介绍
+
+需要等 `element-plus` 支持后才会推出黑暗主题,目前项目上的暗黑模式都是不可用的。

+ 165 - 0
dep/i18n.md

@@ -0,0 +1,165 @@
+# 国际化
+
+如果你使用的 vscode 开发工具,则推荐安装 [I18n-ally](https://marketplace.visualstudio.com/items?itemName=Lokalise.i18n-ally) 这个插件
+
+## I18n-ally 插件
+
+安装了该插件后,你的代码内可以实时看到对应的语言内容
+
+![](/images/i18n.png)
+
+## 配置默认语言
+
+在 [src/config/locale.ts](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/src/config/locale.ts) 内配置 `currentLocale` 为其他语言。
+
+```ts
+import { useCache } from '@/hooks/web/useCache'
+import zhCn from 'element-plus/lib/locale/lang/zh-cn'
+import en from 'element-plus/lib/locale/lang/en'
+
+const { wsCache } = useCache()
+
+export const elLocaleMap = {
+  'zh-CN': zhCn,
+  en: en
+}
+export interface LocaleState {
+  currentLocale: LocaleDropdownType
+  localeMap: LocaleDropdownType[]
+}
+
+export const localeModules: LocaleState = {
+  currentLocale: {
+    lang: wsCache.get('lang') || 'zh-CN',
+    elLocale: elLocaleMap[wsCache.get('lang') || 'zh-CN']
+  },
+  // 多语言
+  localeMap: [
+    {
+      lang: 'zh-CN',
+      name: '简体中文'
+    },
+    {
+      lang: 'en',
+      name: 'English'
+    }
+  ]
+}
+
+```
+
+## 语言文件
+
+在 [src/locales](https://github.com/kailong321200875/vue-element-plus-admin/tree/master/src/locales) 可以配置具体的语言,目前项目中的语言都是没有拆分的,全部放一起,后续会考虑拆分出来,比较好维护。
+
+## 语言导入逻辑说明
+
+在 [src/plugins/vueI18n/index.ts](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/src/plugins/vueI18n/index.ts) 内可以看到
+
+```ts
+const defaultLocal = await import(`../../locales/${locale.lang}.ts`)
+```
+
+这会导入 `src/locales` 文件语言包。
+
+## 使用
+
+引入项目自带的 `useI18n` **注意不要引入 vue-i18n 的 useI18n**
+
+```ts
+import { useI18n } from '/@/hooks/web/useI18n'
+
+const { t } = useI18n()
+
+const title = t('common.menu')
+```
+
+## 切换语言
+
+切换语言需要使用 [src/locales/useLocale.ts](https://github.com/anncwb/vue-vben-admin/tree/main/src/locales/useLocale.ts)
+
+```ts
+import { useLocale } from '@/hooks/web/useLocale'
+const { changeLocale } = useLocale()
+
+changeLocale('en')
+```
+
+## 新增
+
+### 语言文件
+
+在 [src/locales](https://github.com/kailong321200875/vue-element-plus-admin/tree/master/src/locales) 增加对应语言的文件即可
+
+### 新增语言
+
+目前项目自带的语言只有 `zh_CN` 和 `en` 两种
+
+如果需要新增,按以下操作即可
+
+1. 在 [src/locales](https://github.com/kailong321200875/vue-element-plus-admin/tree/master/src/locales) 下语言文件
+2. 在 [types/global.d.ts](https://github.com/kailong321200875/vue-element-plus-admin/tree/master/types/global.d.ts) 给 `LocaleType` 添加对应的类型
+3. 在 [src/config/locale.ts](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/src/config/locale.ts) `localeMap` 中添加对应语言
+
+## 远程读取语言数据
+
+目前项目会在 `src/main.ts` 内等待 `setupI18n` 这个函数执行完之后才会渲染界面,所以只需在 setupI18n 内的 `createI18nOptions` 发送 ajax 请求,将对应的数据设置到 i18n 实例上即可。
+
+```ts
+const createI18nOptions = async (): Promise<I18nOptions> => {
+  const localeStore = useLocaleStoreWithOut()
+  const locale = localeStore.getCurrentLocale
+  const localeMap = localeStore.getLocaleMap
+  // 这里改为远程请求即可。
+  const defaultLocal = await import(`../../locales/${locale.lang}.ts`)
+  const message = defaultLocal.default ?? {}
+
+  setHtmlPageLang(locale.lang)
+
+  localeStore.setCurrentLocale({
+    lang: locale.lang
+    // elLocale: elLocal
+  })
+
+  return {
+    legacy: false,
+    locale: locale.lang,
+    fallbackLocale: locale.lang,
+    messages: {
+      [locale.lang]: message
+    },
+    availableLocales: localeMap.map((v) => v.lang),
+    sync: true,
+    silentTranslationWarn: true,
+    missingWarn: false,
+    silentFallbackWarn: true
+  }
+}
+```
+
+### useLocale
+
+代码: [src/hooks/web/useLocale/](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/src/hooks/web/useLocale.ts)
+
+当手动切换语言的时候会触发 `useLocale` 函数,useLocale 也是异步函数,只需等待接口返回响应的数据后,再进行设置即可
+
+```ts
+export const useLocale = () => {
+  // Switching the language will change the locale of useI18n
+  // And submit to configuration modification
+  const changeLocale = async (locale: LocaleType) => {
+    const globalI18n = i18n.global
+    
+    // 改为远程获取
+    const langModule = await import(`../../locales/${locale}.ts`)
+
+    globalI18n.setLocaleMessage(locale, langModule.default)
+
+    setI18nLanguage(locale)
+  }
+
+  return {
+    changeLocale
+  }
+}
+```

+ 154 - 0
dep/lint.md

@@ -0,0 +1,154 @@
+# Lint
+
+## 介绍
+
+::: tip 使用 lint 的好处
+
+具备基本工程素养的同学都会注重编码规范,而代码风格检查(Code Linting,简称 Lint)是保障代码规范一致性的重要手段。
+
+遵循相应的代码规范有以下好处
+
+- 较少 bug 错误率
+- 高效的开发效率
+- 更高的可读性
+
+:::
+
+项目内集成了以下几种代码校验方式
+
+1. eslint 用于校验代码格式规范
+2. commitlint 用于校验 git 提交信息规范
+3. stylelint 用于校验 css/less 规范
+4. prettier 代码格式化
+
+::: warning 注意
+
+lint 不是必须的,但是很有必要,一个项目做大了以后或者参与人员过多后,就会出现各种风格迥异的代码,对后续的维护造成了一定的麻烦。
+
+:::
+
+## ESLint
+
+ESLint 是一个代码规范和错误检查工具,可以根据自己的团队设置符合自己团队的规范
+
+### 手动校验代码
+
+```bash
+# 执行下面代码.能修复的会自动修复,不能修复的需要手动修改
+pnpm run lint:eslint
+```
+
+### 配置项
+
+项目的 eslint 配置位于根目录下 **.eslintrc.js** 内,可以根据团队自行修改代码规范
+
+## CommitLint
+
+在一个团队中,每个人的 git 的 commit 信息都不一样,五花八门,没有一个机制很难保证规范化,如何才能规范化呢?可能你想到的是 git 的 hook 机制,去写 shell 脚本去实现。这当然可以,其实 JavaScript 有一个很好的工具可以实现这个模板,它就是 commitlint(用于校验 git 提交信息规范)。
+
+### 配置
+
+commit-lint 的配置位于项目根目录下 **commitlint.config.js**
+
+### Git 提交规范
+
+- `feat` 新功能
+- `fix` 修补 bug
+- `docs` 文档
+- `style` 格式、样式(不影响代码运行的变动)
+- `refactor` 重构(即不是新增功能,也不是修改 BUG 的代码)
+- `perf` 优化相关,比如提升性能、体验
+- `test` 添加测试
+- `build` 编译相关的修改,对项目构建或者依赖的改动
+- `ci` 持续集成修改
+- `chore` 构建过程或辅助工具的变动
+- `revert` 回滚到上一个版本
+- `workflow` 工作流改进
+- `mod` 不确定分类的修改
+- `wip` 开发中
+- `types` 类型
+
+### 如何关闭
+
+在 `.husky/commit-msg` 内注释以下代码即可
+
+```bash
+# npx --no-install commitlint --edit "$1"
+```
+
+### 示例
+
+```bash
+
+git commit -m 'feat: add new component'
+
+```
+
+## Stylelint
+
+stylelint 用于校验项目内部 css 的风格,加上编辑器的自动修复,可以很好的统一项目内部 css 风格
+
+### 配置
+
+stylelint 配置位于根目录下 **stylelint.config.js**
+
+### 编辑器配合
+
+如果您使用的是 vscode 编辑器的话,只需要安装下面插件,即可在保存的时候自动格式化文件内部 css 样式
+
+**插件**
+
+[StyleLint](https://marketplace.visualstudio.com/items?itemName=stylelint.vscode-stylelint)
+
+## Prettier
+
+prettier 可以用于统一项目代码风格,统一的缩进,单双引号,尾逗号等等风格
+
+### 配置
+
+prettier 配置文件位于项目根目录下 **prettier.config.js**
+
+### 编辑器配合
+
+如果您使用的是 vscode 编辑器的话,只需要安装下面插件,即可在保存的时候自动格式化文件内部 js 格式
+
+**插件**
+
+[Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)
+
+## Git Hook
+
+git hook 一般结合各种 lint,在 git 提交代码的时候进行代码风格校验,如果校验没通过,则不会进行提交。需要开发者自行修改后再次进行提交
+
+### husky
+
+有一个问题就是校验会校验全部代码,但是我们只想校验我们自己提交的代码,这个时候就可以使用 husky。
+
+最有效的解决方案就是将 Lint 校验放到本地,常见做法是使用 husky 或者 pre-commit 在本地提交之前先做一次 Lint 校验。
+
+项目在 `.husky` 内部定义了相应的 hooks
+
+### 如何跳过某一个检查
+
+```bash
+# 加上 --no-verify即可跳过git hook校验(--no-verify 简写为 -n)
+git commit -m "xxx" --no-verify
+```
+
+### lint-staged
+
+用于自动修复提交文件风格问题
+
+**lint-staged** 配置位于项目 `.husky` 目录下 **lintstagedrc.js**
+
+```js
+module.exports = {
+  // 对指定格式文件 在提交的时候执行相应的修复命令
+  '*.{js,jsx,ts,tsx}': ['eslint --fix', 'prettier --write'],
+  '{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': ['prettier --write--parser json'],
+  'package.json': ['prettier --write'],
+  '*.vue': ['eslint --fix', 'stylelint --fix', 'prettier --write', 'git add .'],
+  '*.{scss,less,styl,css,html}': ['stylelint --fix', 'prettier --write', 'git add .'],
+  '*.md': ['prettier --write'],
+};
+```

二进制
favicon.ico


+ 221 - 0
guide/auth.md

@@ -0,0 +1,221 @@
+# 权限
+
+项目中集成了2种权限处理方式:
+
+1. 通过用户角色来过滤菜单(前端方式控制),菜单由路由配置自动生成
+2. 通过后台来动态生成路由表(服务端方式控制)
+
+目前项目中提供了两种不同方式的帐号:
+
+**admin/admin test/test**
+
+`admin` 帐号用于模拟服务端控制权限,服务端返回什么就渲染什么
+
+`test` 帐号用于模拟前端控制权限,服务端只返回需要显示的菜单 key,前端进行匹配渲染
+
+## 前端控制权限
+
+**实现原理:** 在前端固定写死路由的权限,指定路由有哪些权限可以查看。只初始化通用的路由,需要权限才能访问的路由没有被加入路由表内。在登陆后或者其他方式获取用户角色后,通过角色去遍历路由表,获取该角色可以访问的路由表,生成路由表,再通过 `router.addRoutes` 添加到路由实例,实现权限的过滤。
+
+**缺点:** 权限相对不自由,如果服务端改动角色,前端也需要跟着改动,并且排序什么的都需要前端控制。
+
+## 后台动态获取
+
+**实现原理:** 是通过接口动态生成路由表,且遵循一定的数据结构返回。前端根据需要处理该数据为可识别的结构,再通过 `router.addRoutes` 添加到路由实例,实现权限的动态生成。
+
+## 实现
+
+1. 在[src/store/modules/permission.ts](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/src/store/modules/permission.ts) 中 `generateRoutes()` 进行更改。
+
+接收的 `type` 参数,目前只是针对于本项目的模拟情况,如果不需要或者不适用,可自行改动。
+
+```ts
+generateRoutes(
+  type: 'admin' | 'test' | 'none',
+  routers?: AppCustomRouteRecordRaw[] | string[]
+): Promise<unknown> {
+  return new Promise<void>((resolve) => {
+    let routerMap: AppRouteRecordRaw[] = []
+    if (type === 'admin') {
+      // 模拟后端过滤菜单
+      routerMap = generateRoutesFn2(routers as AppCustomRouteRecordRaw[])
+    } else if (type === 'test') {
+      // 模拟前端过滤菜单
+      routerMap = generateRoutesFn1(cloneDeep(asyncRouterMap), routers as string[])
+    } else {
+      // 直接读取静态路由表
+      routerMap = cloneDeep(asyncRouterMap)
+    }
+    // 动态路由,404一定要放到最后面
+    this.addRouters = routerMap.concat([
+      {
+        path: '/:path(.*)*',
+         redirect: '/404',
+        name: '404Page',
+        meta: {
+           hidden: true,
+          breadcrumb: false
+        }
+      }
+    ])
+    // 渲染菜单的所有路由
+    this.routers = cloneDeep(constantRouterMap).concat(routerMap)
+    resolve()
+  })
+}
+```
+
+### 前端控制实现
+
+2. 在[src/utils/routerHelper.ts](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/src/utils/routerHelper.ts) 中 `generateRoutesFn1()` 进行更改。目前本项目的前端权限控制,是根据 `path` 是否相同来进行过滤演示的,如果不符合需求,需要手动更改以下判断逻辑。
+
+```ts
+// 前端控制路由生成
+export const generateRoutesFn1 = (
+  routes: AppRouteRecordRaw[],
+  keys: string[],
+  basePath = '/'
+): AppRouteRecordRaw[] => {
+  const res: AppRouteRecordRaw[] = []
+
+  for (const route of routes) {
+    const meta = route.meta as RouteMeta
+    // skip some route
+    if (meta.hidden && !meta.showMainRoute) {
+      continue
+    }
+
+    let data: Nullable<AppRouteRecordRaw> = null
+
+    let onlyOneChild: Nullable<string> = null
+    if (route.children && route.children.length === 1 && !meta.alwaysShow) {
+      onlyOneChild = (
+        isUrl(route.children[0].path)
+          ? route.children[0].path
+          : pathResolve(pathResolve(basePath, route.path), route.children[0].path)
+      ) as string
+    }
+
+    // 开发者可以根据实际情况进行扩展
+    for (const item of keys) {
+      // 通过路径去匹配
+      if (isUrl(item) && (onlyOneChild === item || route.path === item)) {
+        data = Object.assign({}, route)
+      } else {
+        const routePath = pathResolve(basePath, onlyOneChild || route.path)
+        if (routePath === item || meta.followRoute === item) {
+          data = Object.assign({}, route)
+        }
+      }
+    }
+
+    // recursive child routes
+    if (route.children && data) {
+      data.children = generateRoutesFn1(route.children, keys, pathResolve(basePath, data.path))
+    }
+    if (data) {
+      res.push(data as AppRouteRecordRaw)
+    }
+  }
+  return res
+}
+```
+
+### 后台动态获取
+
+3. 在[src/utils/routerHelper.ts](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/src/utils/routerHelper.ts) 中 `generateRoutesFn2()` 进行更改。
+
+```ts
+// 后端控制路由生成
+export const generateRoutesFn2 = (routes: AppCustomRouteRecordRaw[]): AppRouteRecordRaw[] => {
+  const res: AppRouteRecordRaw[] = []
+
+  for (const route of routes) {
+    const data: AppRouteRecordRaw = {
+      path: route.path,
+      name: route.name,
+      redirect: route.redirect,
+      meta: route.meta
+    }
+    if (route.component) {
+      const comModule = modules[`../${route.component}.vue`] || modules[`../${route.component}.tsx`]
+      const component = route.component as string
+      if (!comModule && !component.includes('#')) {
+        console.error(`未找到${route.component}.vue文件或${route.component}.tsx文件,请创建`)
+      } else {
+        // 动态加载路由文件,可根据实际情况进行自定义逻辑
+        data.component =
+          component === '#' ? Layout : component.includes('##') ? getParentLayout() : comModule
+      }
+    }
+    // recursive child routes
+    if (route.children) {
+      data.children = generateRoutesFn2(route.children)
+    }
+    res.push(data as AppRouteRecordRaw)
+  }
+  return res
+}
+```
+
+### 公用部分修改
+
+4. 在[src/views/Login/components/LoginForm.vue](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/src/views/Login/components/LoginForm.vue) 中 `getRole()` 进行更改。
+
+需要开发者自行根据需求进行代码变更。
+
+```ts
+// 获取角色信息
+const getRole = async () => {
+  // 模拟获取角色信息,开发者需要自行更改以下逻辑。
+  const { getFormData } = methods
+  const formData = await getFormData<UserLoginType>()
+  const params = {
+    roleName: formData.username
+  }
+  // admin - 模拟后端过滤菜单
+  // test - 模拟前端过滤菜单
+  const res =
+    formData.username === 'admin'
+      ? await getAdminRoleApi({ params })
+      : await getTestRoleApi({ params })
+  if (res) {
+    const { wsCache } = useCache()
+    const routers = res.data.list || []
+    wsCache.set('roleRouters', routers)
+    
+    // 不管最终要使用什么方式进行权限过滤,都需要调用 permissionStore.generateRoutes()
+    formData.username === 'admin'
+      ? await permissionStore.generateRoutes('admin', routers).catch(() => {})
+      : await permissionStore.generateRoutes('test', routers).catch(() => {})
+    
+    // 过滤完路由之后,需要动态注册路由
+    permissionStore.getAddRouters.forEach((route) => {
+      addRoute(route as RouteRecordRaw) // 动态添加可访问路由表
+    })
+    permissionStore.setIsAddRouters(true)
+    push({ path: redirect.value || permissionStore.addRouters[0].path })
+  }
+}
+```
+
+5. 在[src/permission.ts](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/src/permission.ts),以下这种情况,是考虑到手动刷新,所以需要获取到缓存中的动态菜单重新渲染。
+
+```ts
+// 开发者可根据实际情况进行修改
+const roleRouters = wsCache.get('roleRouters') || []
+const userInfo = wsCache.get(appStore.getUserInfo)
+
+userInfo.role === 'admin'
+  ? await permissionStore.generateRoutes('admin', roleRouters as AppCustomRouteRecordRaw[])
+  : await permissionStore.generateRoutes('test', roleRouters as string[])
+
+permissionStore.getAddRouters.forEach((route) => {
+  router.addRoute(route as unknown as RouteRecordRaw) // 动态添加可访问路由表
+})
+const redirectPath = from.query.redirect || to.path
+const redirect = decodeURIComponent(redirectPath as string)
+const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect }
+permissionStore.setIsAddRouters(true)
+next(to.path === '/' ? { path: permissionStore.addRouters[0]?.path as string } : nextData)
+```

+ 70 - 0
guide/component.md

@@ -0,0 +1,70 @@
+# 组件注册
+
+## 按需引入
+
+项目目前的组件注册机制是按需注册,是在需要用到的页面才引入。
+
+```vue
+<script setup lang="ts">
+import { ElBacktop } from 'element-plus'
+import { useDesign } from '@/hooks/web/useDesign'
+
+const { getPrefixCls, variables } = useDesign()
+
+const prefixCls = getPrefixCls('backtop')
+</script>
+
+<template>
+  <ElBacktop
+    :class="`${prefixCls}-backtop`"
+    :target="`.${variables.namespace}-layout-content-scrollbar .${variables.elNamespace}-scrollbar__wrap`"
+  />
+</template>
+
+```
+
+### tsx 文件注册
+
+**tsx 文件内不能使用全局注册组件**,需要手动引入组件使用。
+
+## 全局注册
+
+如果觉得按需引入太麻烦,可以进行全局注册,在[src/components/index.ts](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/src/components/index.ts),添加需要注册的组件。
+
+目前只有 `Icon` 组件进行了全局注册。
+
+```ts
+import type { App } from 'vue'
+import { Icon } from './Icon'
+
+export const setupGlobCom = (app: App<Element>): void => {
+  app.component('Icon', Icon)
+}
+
+```
+
+如果 `element-plus` 的组件需要全局注册,在 [src/plugins/elementPlus/index.ts](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/src/plugins/elementPlus/index.ts) 添加需要注册的组件。
+
+目前 `element-plus` 中只有 `ElLoading` 与 `ElScrollbar` 进行了全局注册。
+
+```
+import type { App } from 'vue'
+
+// 需要全局引入一些组件,如ElScrollbar,不然一些下拉项样式有问题
+import { ElLoading, ElScrollbar } from 'element-plus'
+
+const plugins = [ElLoading]
+
+const components = [ElScrollbar]
+
+export const setupElementPlus = (app: App) => {
+  plugins.forEach((plugin) => {
+    app.use(plugin)
+  })
+
+  components.forEach((component) => {
+    app.component(component.name, component)
+  })
+}
+
+```

+ 57 - 0
guide/deploy.md

@@ -0,0 +1,57 @@
+# 构建&部署
+
+::: tip 前言
+
+由于是展示项目,所以打包后相对较大,如果项目中没有用到的插件,可以删除对应的文件或者路由,不引用即可,没有引用就不会打包。
+
+:::
+
+## 构建
+
+项目开发完成之后,执行以下命令进行构建
+
+- 开发环境 pnpm run build:dev ===> dist-dev
+- 测试环境 pnpm run build:test ===> dist-test
+- 生产环境 pnpm run build:pro ===> dist-pro
+
+构建打包成功之后,会在根目录生成 dist-* 文件夹,里面就是构建打包好的文件。
+
+### 预览
+
+发布之前可以在本地进行预览
+
+**不能直接打开构建后的 html 文件**
+
+使用项目自定的命令进行预览(推荐)
+
+```bash
+# 先打包在进行预览
+
+# 预览开发环境
+pnpm run preview:dev
+
+# 预览测试环境
+pnpm run preview:test
+
+# 预览生产环境
+pnpm run preview:pro
+```
+
+## 部署
+
+::: danger 注意
+
+项目默认是在生产环境开启 Mock,这样做非常不好,只是为了演示环境有数据,不建议在生产环境使用 Mock,而应该使用真实的后台接口。
+
+:::
+
+### 发布
+
+简单的部署只需要将最终生成的静态文件,dist-* 文件夹的静态文件发布到你的 cdn 或者静态服务器即可。
+
+**部署时可能会发现资源路径不对,只需要修改对应的`.env.xxx`文件即可。**
+
+```bash
+# 根据自己路径来配置更改
+VITE_BASE_PATH = /dist-dev/
+```

+ 38 - 0
guide/design.md

@@ -0,0 +1,38 @@
+# 样式
+
+## 介绍
+
+主要介绍如何在项目中使用和规划样式文件。
+
+默认使用 `less` 作为预处理语言,建议在使用前或者遇到疑问时学习一下 [Less](http://lesscss.org/) 的相关特性。
+
+项目中使用的通用样式,都存放于 [src/style/](https://github.com/kailong321200875/vue-element-plus-admin/tree/master/src/styles) 下面。
+
+```bash
+.
+├── index.less # 入口
+├── theme.less # 主题相关
+├── var.css  # css变量
+└── variables.module.less # less变量
+
+```
+
+::: tip 全局注入
+
+variables.module.less 这个文件会被全局注入到所有文件,所以在页面内可以直接使用变量而不需要手动引入。
+
+var.css 则是注入到根元素,所以在每个地方也都能用到。
+
+:::
+
+## windicss
+
+项目中使用了 [windicss](https://windicss.org/),具体参见文件使用说明。
+
+可能没有用到人会觉得用起来很不习惯,但就个人而言,用起来还是挺香的。减少了很多不必要的麻烦
+
+语法如下:
+
+```html
+<div class="relative w-full h-full px-4"></div>
+```

+ 151 - 0
guide/index.md

@@ -0,0 +1,151 @@
+# 开始
+
+本文将快速的帮助你从头运行并启动项目。
+
+## 环境准备
+
+本地环境需要安装 [Pnpm](https://pnpm.io/)、[Node.js](http://nodejs.org/) 和 [Git](https://git-scm.com/)
+
+为什么使用 [Pnpm](https://pnpm.io/),而不是用其他包管理器,大家可以搜索一下,这里就不做过多的阐述了。
+
+::: warning 注意
+
+- [Node.js](http://nodejs.org/) 版本要求`14.x`以上,这里推荐 `16.x` 及以上。
+
+:::
+
+## 工具配置
+
+如果你使用的 IDE 是[vscode](https://code.visualstudio.com/)的话,可以安装以下工具来提高开发效率及代码格式化:
+
+- [Iconify IntelliSense](https://marketplace.visualstudio.com/items?itemName=antfu.iconify) - Iconify 图标插件
+- [windicss IntelliSense](https://marketplace.visualstudio.com/items?itemName=voorjaar.windicss-intellisense) - windicss 提示插件
+- [I18n-ally](https://marketplace.visualstudio.com/items?itemName=Lokalise.i18n-ally) - i18n 插件
+- [Volar](https://gitee.com/link?target=https%3A%2F%2Fmarketplace.visualstudio.com%2Fitems%3FitemName%3Djohnsoncodehk.volar) - vue 开发必备
+- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) - 脚本代码检查
+- [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) - 代码格式化
+- [Stylelint](https://marketplace.visualstudio.com/items?itemName=stylelint.vscode-stylelint) - css 格式化
+- [DotENV](https://marketplace.visualstudio.com/items?itemName=mikestead.dotenv) - .env 文件 高亮
+
+## 代码获取
+
+::: warning 注意
+
+注意存放代码的目录及所有父级目录不能存在中文、韩文、日文以及空格,否则安装依赖后启动会出错。
+
+:::
+
+### 从 GitHub 获取代码
+
+```bash
+# clone 代码
+git clone https://github.com/kailong321200875/vue-element-plus-admin.git
+
+```
+
+### 从 Gitee 获取代码
+
+```bash
+git clone https://gitee.com/kailong110120130/vue-element-plus-admin.git
+```
+
+::: tip 代码同步
+
+不用担心 [Gitee](https://gitee.com/kailong110120130/vue-element-plus-admin) 代码库和 [Github](https://github.com/kailong321200875/vue-element-plus-admin) 代码库不同步,每次版本提交发布,都会及时同步到 [Gitee](https://gitee.com/kailong110120130/vue-element-plus-admin) 上。
+
+:::
+
+## 安装
+
+### 安装 Node.js
+
+如果您电脑未安装[Node.js](https://nodejs.org/en/),请安装它,推荐 `16.x` 及以上
+
+**验证**
+
+```bash
+# 验证 npm 是否安装成功
+npm -v
+
+# 验证 node 是否安装成功
+node -v
+```
+
+如果你需要同时存在多个 `node` 版本,可以使用 [Nvm](https://github.com/nvm-sh/nvm) 或者其他工具进行 Node.js 进行版本管理。
+
+### 安装依赖
+
+#### Pnpm 安装
+
+推荐使用 [Pnpm](https://pnpm.io/)进行依赖安装(若其他包管理器安装不了需要自行处理)。
+
+如果未安装 `Pnpm`,可以用下面命令来进行全局安装
+
+```bash
+# 全局安装 pnpm
+npm i -g pnpm
+
+# 验证
+pnpm -v
+```
+
+#### 安装依赖
+
+在项目根目录下,打开命令窗口执行,耐心等待安装完成即可
+
+```bash
+# 安装依赖
+pnpm i
+```
+
+::: tip 安装依赖时 husky 安装失败
+
+请查看你的源码是否从 [Github](https://github.com/kailong321200875/vue-element-plus-admin) 或者 [Gitee](https://gitee.com/kailong110120130/vue-element-plus-admin) 直接下载的,直接下载是没有 `.git` 文件夹的,而 `husky` 需要依赖 `git` 才能安装。此时需使用 `git init` 初始化项目,再尝试重新安装即可。
+
+:::
+
+当依赖安装完成后,执行以下命令即可启动项目:
+
+```bash
+pnpm run dev
+```
+
+## npm script
+
+```bash
+"scripts": {
+  # 安装依赖
+  "i": "pnpm install",
+  # 本地开发环境运行
+  "dev": "vite --mode base",
+  # typeScript 检测
+  "ts:check": "vue-tsc --noEmit",
+  # 打包生产环境
+  "build:pro": "vite build --mode pro",
+  # 打包开发环境
+  "build:dev": "npm run ts:check && vite build --mode dev",
+  # 打包测试环境
+  "build:test": "npm run ts:check && vite build --mode test",
+  # 本地预览 已打包的生产环境项目包
+  "serve:pro": "vite preview --mode pro",
+  # 本地预览 已打包的开发环境项目包
+  "serve:dev": "vite preview --mode dev",
+  # 本地预览 已打包的测试环境项目包
+  "serve:test": "vite preview --mode test",
+  # 检测可更新依赖
+  "npm:check": "npx npm-check-updates",
+  # 删除 node_modules
+  "clean": "npx rimraf node_modules",
+  # 删除 缓存
+  "clean:cache": "npx rimraf node_modules/.cache",
+  # eslint 检测
+  "lint:eslint": "eslint --fix --ext .js,.ts,.vue ./src",
+  # eslint 格式化
+  "lint:format": "prettier --write --loglevel warn \"src/**/*.{js,ts,json,tsx,css,less,vue,html,md}\"",
+  # stylelint 格式化
+  "lint:style": "stylelint --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
+  "lint:lint-staged": "lint-staged -c ./.husky/lintstagedrc.js",
+  "lint:pretty": "pretty-quick --staged",
+  "postinstall": "husky install"
+},
+```

+ 93 - 0
guide/introduction.md

@@ -0,0 +1,93 @@
+# 介绍
+
+## 简介
+
+[vue-element-plus-admin](https://github.com/kailong321200875/vue-element-plus-admin) 是一个基于 [element-plus](https://element-plus.org/) 免费开源的中后台模版。使用了最新的 [Vue3](https://github.com/vuejs/vue-next),[Vite2](https://github.com/vitejs/vite),[Typescript](https://www.typescriptlang.org/)等主流技术开发,开箱即用的中后台前端解决方案,可以用来作为项目的启动模版,也可用于学习参考。并且时刻关注着最新技术动向,尽可能的第一时间更新。
+
+[vue-element-plus-admin](https://github.com/kailong321200875/vue-element-plus-admin) 的定位是后台集成方案,不太适合当基础模板来进行二次开发。因为集成了很多你可能用不到的功能,会造成不少的代码冗余。如果你的项目不关注这方面的问题,也可以直接基于它进行二次开发。
+
+如需要基础模版,请切换到 [template](https://github.com/kailong321200875/vue-element-plus-admin/tree/template) 分支,[template](https://github.com/kailong321200875/vue-element-plus-admin/tree/template) 只简单集成了一些如:布局、动态菜单等常用布局功能,更适合开发者进行二次开发。
+
+## 需要掌握的基础知识
+
+本项目需要一定前端基础知识,请确保掌握 Vue 的基础知识,以便能处理一些常见的问题。
+
+为了能快速上手本项目,请先大致浏览一遍文档及在线示例。
+
+建议在开发前先学一下以下内容,提前了解和学习这些知识,会对项目理解非常有帮助:
+
+- [Vue3](https://v3.vuejs.org/)
+- [Pinia](https://pinia.vuejs.org/)
+- [TypeScript](https://www.typescriptlang.org/)
+- [Vue-router](https://next.router.vuejs.org/)
+- [Element-plus](https://2x.antdv.com/docs/vue/introduce-cn/)
+- [Es6](https://es6.ruanyifeng.com/)
+- [Vitejs](https://vitejs.dev/)
+- [WindiCss](https://windicss.netlify.app/)
+- [Axios](https://axios-http.com/)
+
+## 目录结构
+
+```
+.
+├── .github # github workflows 相关
+├── .husky # husky 配置
+├── .vscode # vscode 配置
+├── mock # 自定义 mock 数据及配置
+├── public # 静态资源
+├── src # 项目代码
+│   ├── assets # 静态资源
+│   ├── axios-config # axios配置
+│   ├── components # 公用组件
+│   ├── directive # 自定义指令
+│   ├── hooks # 常用hooks
+│   ├── layout # 布局组件
+│   ├── plugins # 外部插件
+│   ├── mock # 模拟数据
+│   ├── router # 路由配置
+│   ├── store # 状态管理
+│   ├── styles # 全局样式
+│   ├── types # 全局类型
+│   ├── utils # 全局工具类
+│   ├── views # 路由页面
+│   ├── App.vue # 入口vue文件
+│   ├── main.ts # 主入口文件
+│   └── permission.ts # 路由拦截
+├── types # 全局类型
+├── .env.base # 本地开发环境 环境变量配置
+├── .env.dev # 打包到开发环境 环境变量配置
+├── .env.pro # 打包到生产环境 环境变量配置
+├── .env.test # 打包到测试环境 环境变量配置
+├── .eslintignore # eslint 跳过检测配置
+├── .eslintrc.js # eslint 配置
+├── .gitignore # git 跳过配置
+├── .prettierignore # prettier 跳过检测配置
+├── .stylelintignore # stylelint 跳过检测配置
+├── CHANGELOG.en.md # 英文更新记录
+├── CHANGELOG.zh_CN.md # 中文更新记录
+├── commitlint.config.js # git commit 提交规范配置
+├── index.html # 入口页面
+├── package.json
+├── .postcssrc.js # postcss 配置
+├── prettier.config.js # prettier 配置
+├── README.md # 英文 README
+├── README.zh-CN.md # 中文 README
+├── stylelint.config.js # stylelint 配置
+├── tsconfig.json # typescript 配置
+├── vite.config.ts # vite 配置
+└── windi.config.ts # windicss 配置
+```
+
+## 浏览器支持
+
+**本地开发**推荐使用`Chrome 最新版`浏览器。
+
+由于 Vue 3 不再支持 IE11,本项目也不支持 IE。
+
+| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/archive/internet-explorer_9-11/internet-explorer_9-11_48x48.png" alt="IE" width="24px" height="24px"  />](http://godban.github.io/browsers-support-badges/)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/)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/)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/)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/)Safari |
+| :-: | :-: | :-: | :-: | :-: |
+| not support | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
+
+## IDE推荐
+
+- [VSCode](https://code.visualstudio.com/)

+ 251 - 0
guide/mock.md

@@ -0,0 +1,251 @@
+# 数据mock&联调
+
+## 开发环境
+
+如果前端应用和后端接口服务器没有运行在同一个主机上,你需要在开发环境下将接口请求代理到接口服务器。
+
+如果是同一个主机,可以直接请求具体的接口地址。
+
+### 跨域设置
+
+在 `vite.config.ts` 配置文件中,提供了 server 的 proxy 功能,用于代理 API 请求。
+
+```ts
+server: {
+  proxy: {
+    "/api":{
+      target: 'http://localhost:3000',
+      changeOrigin: true,
+      ws: true,
+      rewrite: (path) => path.replace(new RegExp(`^/api`), ''),
+    }
+  },
+},
+```
+
+之后在 [src/config/axios/config.ts](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/src/config/axios/config.ts) 中更改 `base_url.base` 为你所配置的代理即可。
+
+```ts
+const config: {
+  base_url: {
+    base: string
+    dev: string
+    pro: string
+    test: string
+  }
+  result_code: number | string
+  default_headers: AxiosHeaders
+  request_timeout: number
+} = {
+  /**
+   * api请求基础路径
+   */
+  base_url: {
+    // 开发环境接口前缀
+    base: '/api',
+
+    // 打包开发环境接口前缀
+    dev: '',
+
+    // 打包生产环境接口前缀
+    pro: '',
+
+    // 打包测试环境接口前缀
+    test: ''
+  },
+
+  /**
+   * 接口成功返回状态码
+   */
+  result_code: '0000',
+
+  /**
+   * 接口请求超时时间
+   */
+  request_timeout: 60000,
+
+  /**
+   * 默认接口请求类型
+   * 可选值:application/x-www-form-urlencoded multipart/form-data
+   */
+  default_headers: 'application/json'
+}
+
+export { config }
+
+```
+
+::: tip 注意
+
+该配置只能作用于 本地开发环境。
+
+从浏览器控制台的 Network 看,请求是 `http://localhost:3000/api/xxx`,这是因为 proxy 配置不会改变本地请求的 url。
+
+:::
+
+## 接口请求
+
+在本项目中,所有的接口数据都是使用 `Mock` 模拟
+
+接口统一存放于 [src/api/](https://github.com/kailong321200875/vue-element-plus-admin/tree/master/src/api) 下面管理
+
+以获取列表接口为例:
+
+在 **src/api/** 内新建模块文件,其中参数与返回值最好定义一下类型,方便校验。虽然麻烦,但是后续维护字段很方便。
+
+::: tip 提示
+
+类型定义文件可以抽取出去统一管理,具体参考项目
+
+:::
+
+```ts
+import { useAxios } from '@/hooks/web/useAxios'
+import type { TableData } from './types'
+
+const { request } = useAxios()
+
+export const getTableListApi = ({ params }: AxiosConfig) => {
+  return request<{
+    total: number
+    list: TableData[]
+  }>({ url: '/example/list', method: 'get', params })
+}
+
+export const saveTableApi = ({ data }: AxiosConfig<Recordable, TableData>) => {
+  return request({ url: '/example/save', method: 'post', data })
+}
+
+export const getTableDetApi = ({
+  params
+}: AxiosConfig<
+  {
+    id: string
+  },
+  Recordable
+>) => {
+  return request<TableData>({ url: '/example/detail', method: 'get', params })
+}
+
+export const delTableListApi = ({
+  data
+}: AxiosConfig<
+  Recordable,
+  {
+    id: string[] | number[]
+  }
+>) => {
+  return request({ url: '/example/delete', method: 'post', data })
+}
+
+```
+
+## axios 配置
+
+**axios** 请求封装存放于 [src/hooks/web/useAxios.ts](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/src/hooks/web/useAxios.ts) 中。
+
+其他的配置,则存放在 [src/config/axios/](https://github.com/kailong321200875/vue-element-plus-admin/tree/master/src/config/axios)
+
+```js
+
+├── config.ts // axios 配置
+├── index.ts // 接口返回统一处理
+
+```
+
+### config.ts 配置说明
+
+::: tip 注意
+
+更改之后,将影响所有的请求。
+
+:::
+
+```ts
+const config: {
+  base_url: {
+    base: string
+    dev: string
+    pro: string
+    test: string
+  }
+  result_code: number | string
+  default_headers: AxiosHeaders
+  request_timeout: number
+} = {
+  /**
+   * api请求基础路径
+   */
+  base_url: {
+    // 开发环境接口前缀
+    base: '/api',
+
+    // 打包开发环境接口前缀
+    dev: '',
+
+    // 打包生产环境接口前缀
+    pro: '',
+
+    // 打包测试环境接口前缀
+    test: ''
+  },
+
+  /**
+   * 接口成功返回状态码
+   */
+  result_code: '0000',
+
+  /**
+   * 接口请求超时时间
+   */
+  request_timeout: 60000,
+
+  /**
+   * 默认接口请求类型
+   * 可选值:application/x-www-form-urlencoded multipart/form-data
+   */
+  default_headers: 'application/json'
+}
+
+export { config }
+
+```
+
+## Mock 服务
+
+Mock 数据是前端开发过程中必不可少的一环,是分离前后端开发的关键链路。通过预先跟服务器端约定好的接口,模拟请求数据甚至逻辑,能够让前端开发独立自主,不会被服务端的开发进程所阻塞。
+
+本项目使用 [vite-plugin-mock](https://github.com/anncwb/vite-plugin-mock) 来进行 mock 数据处理。**项目内 mock 服务分本地和线上**。
+
+### 本地 Mock
+
+本地 mock 采用 Node.js 中间件进行参数拦截(不采用 mock.js 的原因是本地开发看不到请求参数和响应结果)。
+
+#### 如何新增 mock 接口
+
+如果你想添加 mock 数据,只要在根目录下找到 mock 文件,添加对应的接口,对其进行拦截和模拟数据。
+
+在 mock 文件夹内新建文件
+
+::: tip
+
+文件新增后会自动更新,不需要手动重启,可以在代码控制台查看日志信息 mock 文件夹内会自动注册,排除以\_开头的文件夹及文件
+
+:::
+
+::: tip
+
+mock 的值可以直接使用 [mockjs](https://github.com/nuysoft/Mock/wiki) 的语法。
+
+:::
+
+#### 接口有了,如何去掉 mock
+
+当后台接口已经开发完成,只需要将相应的 `mock` 函数去掉即可。
+
+
+### 线上 mock
+
+由于该项目是一个展示类项目,线上也是用 mock 数据,所以在打包后同时也集成了 mock。通常项目线上一般为正式接口。
+
+项目线上 mock 采用的是 [mockjs](https://github.com/nuysoft/Mock/wiki) 进行 mock 数据模拟。

+ 235 - 0
guide/router.md

@@ -0,0 +1,235 @@
+# 路由
+
+项目路由配置存放于 [src/router/index.ts](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/src/router/index.ts) 中。
+
+为了方便阅读和查找,目前项目中并没有去对路由进行拆分,而是统一写在了一起,如果需要拆分,可自行更改。
+
+因为路由是生成菜单关键,所以本项目中对路由提供了以下配置,方便开发者进行定制。
+
+## 配置
+
+``` js
+/**
+* redirect: noredirect        当设置 noredirect 的时候该路由在面包屑导航中不可被点击
+* name:'router-name'          设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题
+* meta : {
+    hidden: true              当设置 true 的时候该路由不会再侧边栏出现 如404,login等页面(默认 false)
+
+    alwaysShow: true          当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式,
+                              只有一个时,会将那个子路由当做根路由显示在侧边栏,
+                              若你想不管路由下面的 children 声明的个数都显示你的根路由,
+                              你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,
+                              一直显示根路由(默认 false)
+
+    title: 'title'            设置该路由在侧边栏和面包屑中展示的名字
+
+    icon: 'svg-name'          设置该路由的图标
+
+    noCache: true             如果设置为true,则不会被 <keep-alive> 缓存(默认 false)
+
+    breadcrumb: false         如果设置为false,则不会在breadcrumb面包屑中显示(默认 true)
+
+    affix: true               如果设置为true,则会一直固定在tag项中(默认 false)
+
+    noTagsView: true          如果设置为true,则不会出现在tag中(默认 false)
+
+    activeMenu: '/dashboard'  显示高亮的路由路径
+
+    followAuth: '/dashboard'  跟随哪个路由进行权限过滤
+
+    canTo: true               设置为true即使hidden为true,也依然可以进行路由跳转(默认 false)
+  }
+**/
+```
+
+### 如何添加新配置
+
+如果本项目中的路由配置项,满足不了你当前的开发工作,可以自行添加新的属性。
+
+::: warning 注意
+
+所有的路由项配置,都必须放在 `meta` 中。
+
+:::
+
+在 [types/router.d.ts](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/types/router.d.ts) 中添加对应的类型,之后就可以在路由中添加你需要的配置项了。
+
+```ts
+declare module 'vue-router' {
+  interface RouteMeta extends Record<string | number | symbol, unknown> {
+    hidden?: boolean
+    alwaysShow?: boolean
+    title?: string
+    icon?: string
+    noCache?: boolean
+    breadcrumb?: boolean
+    affix?: boolean
+    activeMenu?: string
+    noTagsView?: boolean
+    followAuth?: string
+    canTo?: boolean
+
+    // 添加新的配置类型
+    ...
+  }
+}
+
+```
+
+### 多级路由
+
+::: warning 注意事项
+
+- 整个项目所有路由 `name` 不能重复
+- 所有的多级路由最终都会转成二级路由,所以不能内嵌子路由
+- 除了 layout 对应的 path 前面需要加 `/`,其余子路由都不要以`/`开头
+
+:::
+
+**示例**
+
+```ts
+{
+  path: '/level',
+  component: Layout,
+  redirect: '/level/menu1/menu1-1/menu1-1-1',
+  name: 'Level',
+  meta: {
+    title: t('router.level'),
+    icon: 'carbon:skill-level-advanced'
+  },
+  children: [
+    {
+      path: 'menu1',
+      name: 'Menu1',
+      component: getParentLayout(),
+      redirect: '/level/menu1/menu1-1/menu1-1-1',
+      meta: {
+        title: t('router.menu1')
+      },
+      children: [
+        {
+          path: 'menu1-1',
+          name: 'Menu11',
+          component: getParentLayout(),
+          redirect: '/level/menu1/menu1-1/menu1-1-1',
+          meta: {
+            title: t('router.menu11'),
+            alwaysShow: true
+          },
+          children: [
+            {
+              path: 'menu1-1-1',
+              name: 'Menu111',
+              component: () => import('@/views/Level/Menu111.vue'),
+              meta: {
+                title: t('router.menu111')
+              }
+            }
+          ]
+        },
+        {
+          path: 'menu1-2',
+          name: 'Menu12',
+          component: () => import('@/views/Level/Menu12.vue'),
+          meta: {
+            title: t('router.menu12')
+          }
+        }
+      ]
+    },
+    {
+      path: 'menu2',
+      name: 'Menu2Demo',
+      component: () => import('@/views/Level/Menu2.vue'),
+      meta: {
+        title: t('router.menu2')
+      }
+    }
+  ]
+}
+  
+```
+
+### 外链
+
+只需要将 `path` 设置为需要跳转的**HTTP 地址**即可。
+
+```ts
+{
+  path: '/external-link',
+  component: Layout,
+  meta: {
+    name: 'ExternalLink'
+  },
+  children: [
+    {
+      path: 'https://github.com/kailong321200875/vue-element-plus-admin-doc',
+      meta: { name: 'Link', title: '文档' }
+    }
+  ]
+}
+```
+
+## 图标
+
+这里的 `icon` 配置,会同步到 **菜单**(icon 的值可以查看[此处](../components/icon.md))。
+
+## 多标签页
+
+标签页使用的是 `keep-alive` 和 `router-view` 实现,实现切换 `tab` 后还能保存切换之前的状态。
+
+### 如何开启页面缓存
+
+开启缓存有 2 个条件
+
+1. 路由设置 `name`,且**不能重复**
+2. 路由对应的组件加上 `name`,与路由设置的 `name` 保持一致
+
+```ts
+{
+  path: 'menu2',
+  name: 'Menu2',
+  component: () => import('@/views/Level/Menu2.vue'),
+  meta: {
+    title: t('router.menu2')
+  }
+}
+
+// /@/views/Level/Menu2.vue
+<script setup lang="ts">
+defineOptions({
+  name: 'Menu2'
+})
+</script>
+
+```
+
+:::warning 注意
+
+keep-alive 生效的前提是:需要将路由的 `name` 属性及对应的页面的 `name` 设置成一样。因为:
+
+**include - 字符串或正则表达式,只有名称匹配的组件会被缓存**
+:::
+
+### 如何让某个页面不缓存
+
+可以将 `noCache` 配置成 `true` 即可关闭缓存或者组件不添加 `name` 属性。
+
+```ts
+{
+  path: 'workplace',
+  component: () => import('@/views/Dashboard/Workplace.vue'),
+  name: 'Workplace',
+  meta: {
+    title: t('router.workplace'),
+    noCache: true
+  }
+}
+```
+
+## 默认跳转地址
+
+目前项目中,登录进来,默认是进入到当前第一个能找到的路由页面。
+
+后续会考虑弄成一个配置项出来。

+ 327 - 0
guide/settings.md

@@ -0,0 +1,327 @@
+# 项目配置项
+
+本文将介绍一些常用的项目配置,方便开发者可以根据需求进行定制化改造。
+
+## 环境变量配置
+
+项目的环境变量配置位于项目根目录下的,这里主要配置四个个环境变量,分别为:
+- [本地开发环境](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/.env.base)
+- [开发环境](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/.env.dev)
+- [测试环境](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/.env.test)
+- [生产环境](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/.env.pro)
+
+在开发调试的时候,会读取 `.env.base` 里面的数据。其他环境亦是如此,根据打包命令的不同,来读取不同的环境变量。
+
+也许你会疑惑,为什么会有多个环境变量?
+
+以 `生产环境` 为例,当我们执行 `pnpm run build:pro` 时,输出的包是用于线上环境的,所以代码都应该是压缩,我们需要删除掉代码中的 `console.log` 和 `degubber`,保证打包后代码的整洁度和不可见性。而其他环境,所以应该保留 `console.log` 和 `degubber` 用于调试,这样才能快速定位到问题所在。
+
+所以环境变量的作用就是为了,在不同环境下有不同的表现。
+
+::: tip 提示
+
+- 只有以 `VITE_ ` 开头的变量会被嵌入到项目中,你可以项目代码中这样访问它们:
+
+```js
+console.log(import.meta.env.VITE_APP_TITLE)
+```
+
+:::
+
+### 配置项说明
+
+### .env.base
+
+本地开发环境适用
+
+```bash
+# 环境
+NODE_ENV = development
+
+# 接口前缀
+VITE_API_BASEPATH = base
+
+# 打包路径
+VITE_BASE_PATH = /
+
+# 标题
+VITE_APP_TITLE = ElementAdmin
+```
+
+### .env.dev
+
+开发环境适用
+
+```bash
+# 环境
+NODE_ENV = production
+
+# 接口前缀
+VITE_API_BASEPATH = dev
+
+# 打包路径
+VITE_BASE_PATH = /dist-dev/
+
+# 是否删除debugger
+VITE_DROP_DEBUGGER = false
+
+# 是否删除console.log
+VITE_DROP_CONSOLE = false
+
+# 是否sourcemap
+VITE_SOURCEMAP = true
+
+# 输出路径
+VITE_OUT_DIR = dist-dev
+
+# 标题
+VITE_APP_TITLE = ElementAdmin
+
+```
+
+### .env.test
+
+测试环境适用
+
+```bash
+# 环境
+NODE_ENV = production
+
+# 接口前缀
+VITE_API_BASEPATH = test
+
+# 打包路径
+VITE_BASE_PATH = /dist-test/
+
+# 是否删除debugger
+VITE_DROP_DEBUGGER = false
+
+# 是否删除console.log
+VITE_DROP_CONSOLE = false
+
+# 是否sourcemap
+VITE_SOURCEMAP = true
+
+# 输出路径
+VITE_OUT_DIR = dist-test
+
+```
+
+### .env.pro
+
+生产环境适用
+
+```bash
+# 环境
+NODE_ENV = production
+
+# 接口前缀
+VITE_API_BASEPATH = pro
+
+# 打包路径
+VITE_BASE_PATH = /
+
+# 是否删除debugger
+VITE_DROP_DEBUGGER = true
+
+# 是否删除console.log
+VITE_DROP_CONSOLE = true
+
+# 是否sourcemap
+VITE_SOURCEMAP = false
+
+# 输出路径
+VITE_OUT_DIR = dist-pro
+
+# 标题
+VITE_APP_TITLE = ElementAdmin
+
+```
+
+## 项目及主题配置
+
+::: tip 提示
+
+项目配置文件用于配置项目内展示的内容、布局、主题色等效果。
+
+:::
+
+### 配置文件路径
+
+[src/config/app.ts](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/src/config/app.ts)
+
+### 说明
+
+修改完之后,会添加到全局的状态管理中,方便其他地方使用。
+
+```js
+export const appModules: AppState = {
+  userInfo: 'userInfo', // 登录信息存储字段-建议每个项目换一个字段,避免与其他项目冲突
+  sizeMap: ['default', 'large', 'small'],
+  mobile: false, // 是否是移动端
+  title: import.meta.env.VITE_APP_TITLE as string, // 标题
+  pageLoading: false, // 路由跳转loading
+
+  breadcrumb: true, // 面包屑
+  breadcrumbIcon: true, // 面包屑图标
+  collapse: false, // 折叠菜单
+  hamburger: true, // 折叠图标
+  screenfull: true, // 全屏图标
+  size: true, // 尺寸图标
+  locale: true, // 多语言图标
+  tagsView: true, // 标签页
+  logo: true, // logo
+  fixedHeader: true, // 固定toolheader
+  footer: true, // 显示页脚
+  greyMode: false, // 是否开始灰色模式,用于特殊悼念日
+
+  layout: wsCache.get('layout') || 'classic', // layout布局
+  isDark: wsCache.get('isDark') || false, // 是否是暗黑模式
+  currentSize: wsCache.get('default') || 'default', // 组件尺寸
+  theme: wsCache.get('theme') || {
+    // 主题色
+    elColorPrimary: '#409eff',
+    // 左侧菜单边框颜色
+    leftMenuBorderColor: 'inherit',
+    // 左侧菜单背景颜色
+    leftMenuBgColor: '#001529',
+    // 左侧菜单浅色背景颜色
+    leftMenuBgLightColor: '#0f2438',
+    // 左侧菜单选中背景颜色
+    leftMenuBgActiveColor: 'var(--el-color-primary)',
+    // 左侧菜单收起选中背景颜色
+    leftMenuCollapseBgActiveColor: 'var(--el-color-primary)',
+    // 左侧菜单字体颜色
+    leftMenuTextColor: '#bfcbd9',
+    // 左侧菜单选中字体颜色
+    leftMenuTextActiveColor: '#fff',
+    // logo字体颜色
+    logoTitleTextColor: '#fff',
+    // logo边框颜色
+    logoBorderColor: 'inherit',
+    // 头部背景颜色
+    topHeaderBgColor: '#fff',
+    // 头部字体颜色
+    topHeaderTextColor: 'inherit',
+    // 头部悬停颜色
+    topHeaderHoverColor: '#f6f6f6',
+    // 头部边框颜色
+    topToolBorderColor: '#eee'
+  }
+}
+```
+
+### 如何添加新属性
+
+如果想要添加新的全局配置属性,需要在 [src/config/app.ts](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/src/config/app.ts) 中 `AppState` 添加对应的类型,并在 `appModules` 对象中,赋予新属性的默认值。
+
+## 缓存配置
+
+统一项目中的写法。
+
+### 说明
+
+在项目中,你可以看到很多地方都使用了 `wsCache.set` 或者 `wsCache.get`,这是基于 [web-storage-cache](https://github.com/wuchangming/web-storage-cache) 进行封装,采用 `hook` 的形式。
+
+该插件对HTML5 `localStorage` 和 `sessionStorage` 进行了扩展,添加了超时时间,序列化方法。可以直接存储 `json` 对象,同时可以非常简单的进行超时时间的设置。
+
+本项目默认是采用 `sessionStorage` 的存储方式,如果更改,可以直接在 [src/hooks/web/useCache.ts](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/src/hooks/web/useCache.ts) 中把 `type: CacheType = 'sessionStorage'` 改为 `type: CacheType = 'localStorage'`,这样项目中的所有用到的地方,都会变成该方式进行数据存储。
+
+如果只想单个更改,可以传入存储类型 `const { wsCache } = useCache('localStorage')`,既可只适用当前存储对象。
+
+::: warning 注意
+
+更改完默认存储方式后,需要清除浏览器缓存并重新登录,以免造成不可描述的问题。
+
+:::
+
+## 多语言配置
+
+用于配置多语言信息
+
+在 [src/config/locale.ts](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/src/config/locale.ts) 内配置
+
+```ts
+import { useCache } from '@/hooks/web/useCache'
+import zhCn from 'element-plus/lib/locale/lang/zh-cn'
+import en from 'element-plus/lib/locale/lang/en'
+
+const { wsCache } = useCache()
+
+export const elLocaleMap = {
+  'zh-CN': zhCn,
+  en: en
+}
+export interface LocaleState {
+  currentLocale: LocaleDropdownType
+  localeMap: LocaleDropdownType[]
+}
+
+export const localeModules: LocaleState = {
+  currentLocale: {
+    lang: wsCache.get('lang') || 'zh-CN',
+    elLocale: elLocaleMap[wsCache.get('lang') || 'zh-CN']
+  },
+  // 多语言
+  localeMap: [
+    {
+      lang: 'zh-CN',
+      name: '简体中文'
+    },
+    {
+      lang: 'en',
+      name: 'English'
+    }
+  ]
+}
+
+```
+
+## 样式配置
+
+### css 前缀设置
+
+用于修改项目内组件及 `element-plus` 组件的 `class` 前缀。
+
+由于 `element-plus` 的组件还没有全部采用动态配置前缀,所以目前还是使用 `el` 前缀。
+
+- 在 [src/styles/variables.module.less](https://github.com/kailong321200875/vue-element-plus-admin/blob/master/src/styles/variables.module.less) 内配置
+
+```less
+// 命名空间
+@namespace: v;
+// el命名空间
+@elNamespace: el;
+
+// 导出变量
+:export {
+  namespace: @namespace;
+  elNamespace: @elNamespace;
+}
+
+```
+
+### 前缀使用
+
+**在 css 内**
+
+```vue
+<style lang="less" scoped>
+  /* namespace已经全局注入,不需要额外在引入 */
+  @prefix-cls: ~'@{namespace}-app';
+
+  .@{prefix-cls} {
+    width: 100%;
+  }
+</style>
+```
+
+**在 vue/ts 内**
+
+```ts
+import { useDesign } from '/@/hooks/web/useDesign'
+
+const { prefixCls } = useDesign('app')
+
+// prefixCls => v-app
+```

+ 0 - 1
index.html

@@ -1 +0,0 @@
-docs test

+ 24 - 0
index.md

@@ -0,0 +1,24 @@
+---
+home: true
+heroImage: /logo.png
+actionText: 快速开始 →
+actionLink: /guide/introduction
+
+altActionText: 在线预览
+altActionLink: https://element-plus-admin.cn/
+
+features:
+  - title: 最新技术栈
+    details: 基于Vue3、Vite、TypeScript等最新技术栈开发
+  - title: 组件封装
+    details: 对常用功能进行组件化封装,统一维护,满足基础工作需求
+  - title: 丰富的示例
+    details: 常见的Web端插件示例实现
+  - title: 主题配置
+    details: 丰富的主题配置及黑暗主题适配
+  - title: 权限管理
+    details: 完善的前后端权限管理方案
+  - title: 持续更新
+    details: 持续关注最新的技术方向,保证第一时间更新
+footer: MIT Licensed | Copyright © 2021-present Archer
+---

+ 25 - 0
package.json

@@ -0,0 +1,25 @@
+{
+  "name": "vue-element-plus-admin-doc",
+  "version": "1.0.0",
+  "main": "index.js",
+  "repository": "https://github.com/kailong321200875/vue-element-plus-admin-doc",
+  "author": "Archer <502431556@11.com>",
+  "license": "MIT",
+  "scripts": {
+    "dev": "vitepress dev",
+    "build": "vitepress build",
+    "serve": "vitepress serve"
+  },
+  "devDependencies": {
+    "prettier": "^2.3.2",
+    "vite-plugin-components": "^0.10.4",
+    "vite-plugin-icons": "^0.6.3",
+    "vite-plugin-windicss": "^1.1.1",
+    "vitepress": "^0.14.1",
+    "windicss": "^3.1.3"
+  },
+  "dependencies": {
+    "@iconify/json": "^1.1.362",
+    "@vueuse/core": "^5.0.3"
+  }
+}

+ 1927 - 0
pnpm-lock.yaml

@@ -0,0 +1,1927 @@
+lockfileVersion: 5.3
+
+specifiers:
+  '@iconify/json': ^1.1.362
+  '@vueuse/core': ^5.0.3
+  prettier: ^2.3.2
+  vite-plugin-components: ^0.10.4
+  vite-plugin-icons: ^0.6.3
+  vite-plugin-windicss: ^1.1.1
+  vitepress: ^0.14.1
+  windicss: ^3.1.3
+
+dependencies:
+  '@iconify/json': registry.npmmirror.com/@iconify/json/1.1.461
+  '@vueuse/core': registry.npmmirror.com/@vueuse/core/5.3.0
+
+devDependencies:
+  prettier: registry.npmmirror.com/prettier/2.5.1
+  vite-plugin-components: registry.npmmirror.com/vite-plugin-components/0.10.4
+  vite-plugin-icons: registry.npmmirror.com/vite-plugin-icons/0.6.5_@iconify+json@1.1.461
+  vite-plugin-windicss: registry.npmmirror.com/vite-plugin-windicss/1.7.1
+  vitepress: registry.npmmirror.com/vitepress/0.14.1
+  windicss: registry.npmmirror.com/windicss/3.4.3
+
+packages:
+
+  registry.nlark.com/@nodelib/fs.scandir/2.1.5:
+    resolution: {integrity: sha1-dhnC6yGyVIP20WdUi0z9WnSIw9U=, registry: https://registry.npm.taobao.org/, tarball: https://registry.nlark.com/@nodelib/fs.scandir/download/@nodelib/fs.scandir-2.1.5.tgz}
+    name: '@nodelib/fs.scandir'
+    version: 2.1.5
+    engines: {node: '>= 8'}
+    dependencies:
+      '@nodelib/fs.stat': registry.npmmirror.com/@nodelib/fs.stat/2.0.5
+      run-parallel: registry.npmmirror.com/run-parallel/1.2.0
+    dev: true
+
+  registry.nlark.com/concat-map/0.0.1:
+    resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=, registry: https://registry.npm.taobao.org/, tarball: https://registry.nlark.com/concat-map/download/concat-map-0.0.1.tgz}
+    name: concat-map
+    version: 0.0.1
+    dev: true
+
+  registry.npmmirror.com/@algolia/cache-browser-local-storage/4.12.1:
+    resolution: {integrity: sha512-ERFFOnC9740xAkuO0iZTQqm2AzU7Dpz/s+g7o48GlZgx5p9GgNcsuK5eS0GoW/tAK+fnKlizCtlFHNuIWuvfsg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.12.1.tgz}
+    name: '@algolia/cache-browser-local-storage'
+    version: 4.12.1
+    dependencies:
+      '@algolia/cache-common': registry.npmmirror.com/@algolia/cache-common/4.12.1
+    dev: true
+
+  registry.npmmirror.com/@algolia/cache-common/4.12.1:
+    resolution: {integrity: sha512-UugTER3V40jT+e19Dmph5PKMeliYKxycNPwrPNADin0RcWNfT2QksK9Ff2N2W7UKraqMOzoeDb4LAJtxcK1a8Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@algolia/cache-common/-/cache-common-4.12.1.tgz}
+    name: '@algolia/cache-common'
+    version: 4.12.1
+    dev: true
+
+  registry.npmmirror.com/@algolia/cache-in-memory/4.12.1:
+    resolution: {integrity: sha512-U6iaunaxK1lHsAf02UWF58foKFEcrVLsHwN56UkCtwn32nlP9rz52WOcHsgk6TJrL8NDcO5swMjtOQ5XHESFLw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@algolia/cache-in-memory/-/cache-in-memory-4.12.1.tgz}
+    name: '@algolia/cache-in-memory'
+    version: 4.12.1
+    dependencies:
+      '@algolia/cache-common': registry.npmmirror.com/@algolia/cache-common/4.12.1
+    dev: true
+
+  registry.npmmirror.com/@algolia/client-account/4.12.1:
+    resolution: {integrity: sha512-jGo4ConJNoMdTCR2zouO0jO/JcJmzOK6crFxMMLvdnB1JhmMbuIKluOTJVlBWeivnmcsqb7r0v7qTCPW5PAyxQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@algolia/client-account/-/client-account-4.12.1.tgz}
+    name: '@algolia/client-account'
+    version: 4.12.1
+    dependencies:
+      '@algolia/client-common': registry.npmmirror.com/@algolia/client-common/4.12.1
+      '@algolia/client-search': registry.npmmirror.com/@algolia/client-search/4.12.1
+      '@algolia/transporter': registry.npmmirror.com/@algolia/transporter/4.12.1
+    dev: true
+
+  registry.npmmirror.com/@algolia/client-analytics/4.12.1:
+    resolution: {integrity: sha512-h1It7KXzIthlhuhfBk7LteYq72tym9maQDUsyRW0Gft8b6ZQahnRak9gcCvKwhcJ1vJoP7T7JrNYGiYSicTD9g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@algolia/client-analytics/-/client-analytics-4.12.1.tgz}
+    name: '@algolia/client-analytics'
+    version: 4.12.1
+    dependencies:
+      '@algolia/client-common': registry.npmmirror.com/@algolia/client-common/4.12.1
+      '@algolia/client-search': registry.npmmirror.com/@algolia/client-search/4.12.1
+      '@algolia/requester-common': registry.npmmirror.com/@algolia/requester-common/4.12.1
+      '@algolia/transporter': registry.npmmirror.com/@algolia/transporter/4.12.1
+    dev: true
+
+  registry.npmmirror.com/@algolia/client-common/4.12.1:
+    resolution: {integrity: sha512-obnJ8eSbv+h94Grk83DTGQ3bqhViSWureV6oK1s21/KMGWbb3DkduHm+lcwFrMFkjSUSzosLBHV9EQUIBvueTw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@algolia/client-common/-/client-common-4.12.1.tgz}
+    name: '@algolia/client-common'
+    version: 4.12.1
+    dependencies:
+      '@algolia/requester-common': registry.npmmirror.com/@algolia/requester-common/4.12.1
+      '@algolia/transporter': registry.npmmirror.com/@algolia/transporter/4.12.1
+    dev: true
+
+  registry.npmmirror.com/@algolia/client-personalization/4.12.1:
+    resolution: {integrity: sha512-sMSnjjPjRgByGHYygV+5L/E8a6RgU7l2GbpJukSzJ9GRY37tHmBHuvahv8JjdCGJ2p7QDYLnQy5bN5Z02qjc7Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@algolia/client-personalization/-/client-personalization-4.12.1.tgz}
+    name: '@algolia/client-personalization'
+    version: 4.12.1
+    dependencies:
+      '@algolia/client-common': registry.npmmirror.com/@algolia/client-common/4.12.1
+      '@algolia/requester-common': registry.npmmirror.com/@algolia/requester-common/4.12.1
+      '@algolia/transporter': registry.npmmirror.com/@algolia/transporter/4.12.1
+    dev: true
+
+  registry.npmmirror.com/@algolia/client-search/4.12.1:
+    resolution: {integrity: sha512-MwwKKprfY6X2nJ5Ki/ccXM2GDEePvVjZnnoOB2io3dLKW4fTqeSRlC5DRXeFD7UM0vOPPHr4ItV2aj19APKNVQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@algolia/client-search/-/client-search-4.12.1.tgz}
+    name: '@algolia/client-search'
+    version: 4.12.1
+    dependencies:
+      '@algolia/client-common': registry.npmmirror.com/@algolia/client-common/4.12.1
+      '@algolia/requester-common': registry.npmmirror.com/@algolia/requester-common/4.12.1
+      '@algolia/transporter': registry.npmmirror.com/@algolia/transporter/4.12.1
+    dev: true
+
+  registry.npmmirror.com/@algolia/logger-common/4.12.1:
+    resolution: {integrity: sha512-fCgrzlXGATNqdFTxwx0GsyPXK+Uqrx1SZ3iuY2VGPPqdt1a20clAG2n2OcLHJpvaa6vMFPlJyWvbqAgzxdxBlQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@algolia/logger-common/-/logger-common-4.12.1.tgz}
+    name: '@algolia/logger-common'
+    version: 4.12.1
+    dev: true
+
+  registry.npmmirror.com/@algolia/logger-console/4.12.1:
+    resolution: {integrity: sha512-0owaEnq/davngQMYqxLA4KrhWHiXujQ1CU3FFnyUcMyBR7rGHI48zSOUpqnsAXrMBdSH6rH5BDkSUUFwsh8RkQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@algolia/logger-console/-/logger-console-4.12.1.tgz}
+    name: '@algolia/logger-console'
+    version: 4.12.1
+    dependencies:
+      '@algolia/logger-common': registry.npmmirror.com/@algolia/logger-common/4.12.1
+    dev: true
+
+  registry.npmmirror.com/@algolia/requester-browser-xhr/4.12.1:
+    resolution: {integrity: sha512-OaMxDyG0TZG0oqz1lQh9e3woantAG1bLnuwq3fmypsrQxra4IQZiyn1x+kEb69D2TcXApI5gOgrD4oWhtEVMtw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.12.1.tgz}
+    name: '@algolia/requester-browser-xhr'
+    version: 4.12.1
+    dependencies:
+      '@algolia/requester-common': registry.npmmirror.com/@algolia/requester-common/4.12.1
+    dev: true
+
+  registry.npmmirror.com/@algolia/requester-common/4.12.1:
+    resolution: {integrity: sha512-XWIrWQNJ1vIrSuL/bUk3ZwNMNxl+aWz6dNboRW6+lGTcMIwc3NBFE90ogbZKhNrFRff8zI4qCF15tjW+Fyhpow==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@algolia/requester-common/-/requester-common-4.12.1.tgz}
+    name: '@algolia/requester-common'
+    version: 4.12.1
+    dev: true
+
+  registry.npmmirror.com/@algolia/requester-node-http/4.12.1:
+    resolution: {integrity: sha512-awBtwaD+s0hxkA1aehYn8F0t9wqGoBVWgY4JPHBmp1ChO3pK7RKnnvnv7QQa9vTlllX29oPt/BBVgMo1Z3n1Qg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@algolia/requester-node-http/-/requester-node-http-4.12.1.tgz}
+    name: '@algolia/requester-node-http'
+    version: 4.12.1
+    dependencies:
+      '@algolia/requester-common': registry.npmmirror.com/@algolia/requester-common/4.12.1
+    dev: true
+
+  registry.npmmirror.com/@algolia/transporter/4.12.1:
+    resolution: {integrity: sha512-BGeNgdEHc6dXIk2g8kdlOoQ6fQ6OIaKQcplEj7HPoi+XZUeAvRi3Pff3QWd7YmybWkjzd9AnTzieTASDWhL+sQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@algolia/transporter/-/transporter-4.12.1.tgz}
+    name: '@algolia/transporter'
+    version: 4.12.1
+    dependencies:
+      '@algolia/cache-common': registry.npmmirror.com/@algolia/cache-common/4.12.1
+      '@algolia/logger-common': registry.npmmirror.com/@algolia/logger-common/4.12.1
+      '@algolia/requester-common': registry.npmmirror.com/@algolia/requester-common/4.12.1
+    dev: true
+
+  registry.npmmirror.com/@antfu/utils/0.4.0:
+    resolution: {integrity: sha512-gqkpvjkgFUu+s3kP+Ly33OKpo5zvVY3FDFhv5BIb98SncS3KD6DNxPfNDjwHIoyXbz1leWo1j8DtRLZ1D2Jv+Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@antfu/utils/-/utils-0.4.0.tgz}
+    name: '@antfu/utils'
+    version: 0.4.0
+    dependencies:
+      '@types/throttle-debounce': registry.npmmirror.com/@types/throttle-debounce/2.1.0
+    dev: true
+
+  registry.npmmirror.com/@arr/every/1.0.1:
+    resolution: {integrity: sha512-UQFQ6SgyJ6LX42W8rHCs8KVc0JS0tzVL9ct4XYedJukskYVWTo49tNiMEK9C2HTyarbNiT/RVIRSY82vH+6sTg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@arr/every/-/every-1.0.1.tgz}
+    name: '@arr/every'
+    version: 1.0.1
+    engines: {node: '>=4'}
+    dev: true
+
+  registry.npmmirror.com/@babel/parser/7.17.3:
+    resolution: {integrity: sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@babel/parser/-/parser-7.17.3.tgz}
+    name: '@babel/parser'
+    version: 7.17.3
+    engines: {node: '>=6.0.0'}
+    hasBin: true
+    dev: true
+
+  registry.npmmirror.com/@docsearch/css/1.0.0-alpha.28:
+    resolution: {integrity: sha512-1AhRzVdAkrWwhaxTX6/R7SnFHz8yLz1W8I/AldlTrfbNvZs9INk1FZiEFTJdgHaP68nhgQNWSGlQiDiI3y2RYg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@docsearch/css/-/css-1.0.0-alpha.28.tgz}
+    name: '@docsearch/css'
+    version: 1.0.0-alpha.28
+    dev: true
+
+  registry.npmmirror.com/@docsearch/js/1.0.0-alpha.28:
+    resolution: {integrity: sha512-2g7aPhBy7FoEyeZW2G3LYHWVa8CFvqyozEz8PXt3hyywdFcmEIqmoCRwn8kboVftrOKCjtPcuLCewsaBoB3uiw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@docsearch/js/-/js-1.0.0-alpha.28.tgz}
+    name: '@docsearch/js'
+    version: 1.0.0-alpha.28
+    dependencies:
+      '@docsearch/react': registry.npmmirror.com/@docsearch/react/1.0.0-alpha.28
+      preact: registry.npmmirror.com/preact/10.6.6
+    transitivePeerDependencies:
+      - react
+      - react-dom
+    dev: true
+
+  registry.npmmirror.com/@docsearch/react/1.0.0-alpha.28:
+    resolution: {integrity: sha512-XjJOnCBXn+UZmtuDmgzlVIHnnvh6yHVwG4aFq8AXN6xJEIX3f180FvGaowFWAxgdtHplJxFGux0Xx4piHqBzIw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@docsearch/react/-/react-1.0.0-alpha.28.tgz}
+    name: '@docsearch/react'
+    version: 1.0.0-alpha.28
+    peerDependencies:
+      react: ^16.8.0
+      react-dom: ^16.8.0
+    dependencies:
+      '@docsearch/css': registry.npmmirror.com/@docsearch/css/1.0.0-alpha.28
+      '@francoischalifour/autocomplete-core': registry.npmmirror.com/@francoischalifour/autocomplete-core/1.0.0-alpha.28
+      '@francoischalifour/autocomplete-preset-algolia': registry.npmmirror.com/@francoischalifour/autocomplete-preset-algolia/1.0.0-alpha.28
+      algoliasearch: registry.npmmirror.com/algoliasearch/4.12.1
+    dev: true
+
+  registry.npmmirror.com/@francoischalifour/autocomplete-core/1.0.0-alpha.28:
+    resolution: {integrity: sha512-rL9x+72btViw+9icfBKUJjZj87FgjFrD2esuTUqtj4RAX3s4AuVZiN8XEsfjQBSc6qJk31cxlvqZHC/BIyYXgg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@francoischalifour/autocomplete-core/-/autocomplete-core-1.0.0-alpha.28.tgz}
+    name: '@francoischalifour/autocomplete-core'
+    version: 1.0.0-alpha.28
+    dev: true
+
+  registry.npmmirror.com/@francoischalifour/autocomplete-preset-algolia/1.0.0-alpha.28:
+    resolution: {integrity: sha512-bprfNmYt1opFUFEtD2XfY/kEsm13bzHQgU80uMjhuK0DJ914IjolT1GytpkdM6tJ4MBvyiJPP+bTtWO+BZ7c7w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@francoischalifour/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.0.0-alpha.28.tgz}
+    name: '@francoischalifour/autocomplete-preset-algolia'
+    version: 1.0.0-alpha.28
+    dev: true
+
+  registry.npmmirror.com/@iconify/json-tools/1.0.10:
+    resolution: {integrity: sha512-LFelJDOLZ6JHlmlAkgrvmcu4hpNPB91KYcr4f60D/exzU1eNOb4/KCVHIydGHIQFaOacIOD+Xy+B7P1z812cZg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@iconify/json-tools/-/json-tools-1.0.10.tgz}
+    name: '@iconify/json-tools'
+    version: 1.0.10
+    dev: true
+
+  registry.npmmirror.com/@iconify/json/1.1.461:
+    resolution: {integrity: sha512-9Y41Tk9s3LDt4WI20XySNhNX6qTJ/WOBeE3O2iyoV9LJ6gFEDjp0uTPzfRU9NUx7D6VkvQ/htJEuRe9LmyMqUA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@iconify/json/-/json-1.1.461.tgz}
+    name: '@iconify/json'
+    version: 1.1.461
+    dev: false
+
+  registry.npmmirror.com/@nodelib/fs.stat/2.0.5:
+    resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz}
+    name: '@nodelib/fs.stat'
+    version: 2.0.5
+    engines: {node: '>= 8'}
+    dev: true
+
+  registry.npmmirror.com/@nodelib/fs.walk/1.2.8:
+    resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz}
+    name: '@nodelib/fs.walk'
+    version: 1.2.8
+    engines: {node: '>= 8'}
+    dependencies:
+      '@nodelib/fs.scandir': registry.nlark.com/@nodelib/fs.scandir/2.1.5
+      fastq: registry.npmmirror.com/fastq/1.13.0
+    dev: true
+
+  registry.npmmirror.com/@polka/url/0.5.0:
+    resolution: {integrity: sha512-oZLYFEAzUKyi3SKnXvj32ZCEGH6RDnao7COuCVhDydMS9NrCSVXhM79VaKyP5+Zc33m0QXEd2DN3UkU7OsHcfw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@polka/url/-/url-0.5.0.tgz}
+    name: '@polka/url'
+    version: 0.5.0
+    dev: true
+
+  registry.npmmirror.com/@polka/url/1.0.0-next.21:
+    resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@polka/url/-/url-1.0.0-next.21.tgz}
+    name: '@polka/url'
+    version: 1.0.0-next.21
+    dev: true
+
+  registry.npmmirror.com/@types/throttle-debounce/2.1.0:
+    resolution: {integrity: sha512-5eQEtSCoESnh2FsiLTxE121IiE60hnMqcb435fShf4bpLRjEu1Eoekht23y6zXS9Ts3l+Szu3TARnTsA0GkOkQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/throttle-debounce/-/throttle-debounce-2.1.0.tgz}
+    name: '@types/throttle-debounce'
+    version: 2.1.0
+    dev: true
+
+  registry.npmmirror.com/@vitejs/plugin-vue/1.10.2_vite@2.8.4:
+    resolution: {integrity: sha512-/QJ0Z9qfhAFtKRY+r57ziY4BSbGUTGsPRMpB/Ron3QPwBZM4OZAZHdTa4a8PafCwU5DTatXG8TMDoP8z+oDqJw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-1.10.2.tgz}
+    id: registry.npmmirror.com/@vitejs/plugin-vue/1.10.2
+    name: '@vitejs/plugin-vue'
+    version: 1.10.2
+    engines: {node: '>=12.0.0'}
+    peerDependencies:
+      vite: ^2.5.10
+    dependencies:
+      vite: registry.npmmirror.com/vite/2.8.4
+    dev: true
+
+  registry.npmmirror.com/@vue/compiler-core/3.2.31:
+    resolution: {integrity: sha512-aKno00qoA4o+V/kR6i/pE+aP+esng5siNAVQ422TkBNM6qA4veXiZbSe8OTXHXquEi/f6Akc+nLfB4JGfe4/WQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.2.31.tgz}
+    name: '@vue/compiler-core'
+    version: 3.2.31
+    dependencies:
+      '@babel/parser': registry.npmmirror.com/@babel/parser/7.17.3
+      '@vue/shared': registry.npmmirror.com/@vue/shared/3.2.31
+      estree-walker: registry.npmmirror.com/estree-walker/2.0.2
+      source-map: registry.npmmirror.com/source-map/0.6.1
+    dev: true
+
+  registry.npmmirror.com/@vue/compiler-dom/3.2.31:
+    resolution: {integrity: sha512-60zIlFfzIDf3u91cqfqy9KhCKIJgPeqxgveH2L+87RcGU/alT6BRrk5JtUso0OibH3O7NXuNOQ0cDc9beT0wrg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.2.31.tgz}
+    name: '@vue/compiler-dom'
+    version: 3.2.31
+    dependencies:
+      '@vue/compiler-core': registry.npmmirror.com/@vue/compiler-core/3.2.31
+      '@vue/shared': registry.npmmirror.com/@vue/shared/3.2.31
+    dev: true
+
+  registry.npmmirror.com/@vue/compiler-sfc/3.2.31:
+    resolution: {integrity: sha512-748adc9msSPGzXgibHiO6T7RWgfnDcVQD+VVwYgSsyyY8Ans64tALHZANrKtOzvkwznV/F4H7OAod/jIlp/dkQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.2.31.tgz}
+    name: '@vue/compiler-sfc'
+    version: 3.2.31
+    dependencies:
+      '@babel/parser': registry.npmmirror.com/@babel/parser/7.17.3
+      '@vue/compiler-core': registry.npmmirror.com/@vue/compiler-core/3.2.31
+      '@vue/compiler-dom': registry.npmmirror.com/@vue/compiler-dom/3.2.31
+      '@vue/compiler-ssr': registry.npmmirror.com/@vue/compiler-ssr/3.2.31
+      '@vue/reactivity-transform': registry.npmmirror.com/@vue/reactivity-transform/3.2.31
+      '@vue/shared': registry.npmmirror.com/@vue/shared/3.2.31
+      estree-walker: registry.npmmirror.com/estree-walker/2.0.2
+      magic-string: registry.npmmirror.com/magic-string/0.25.7
+      postcss: registry.npmmirror.com/postcss/8.4.6
+      source-map: registry.npmmirror.com/source-map/0.6.1
+    dev: true
+
+  registry.npmmirror.com/@vue/compiler-ssr/3.2.31:
+    resolution: {integrity: sha512-mjN0rqig+A8TVDnsGPYJM5dpbjlXeHUm2oZHZwGyMYiGT/F4fhJf/cXy8QpjnLQK4Y9Et4GWzHn9PS8AHUnSkw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.2.31.tgz}
+    name: '@vue/compiler-ssr'
+    version: 3.2.31
+    dependencies:
+      '@vue/compiler-dom': registry.npmmirror.com/@vue/compiler-dom/3.2.31
+      '@vue/shared': registry.npmmirror.com/@vue/shared/3.2.31
+    dev: true
+
+  registry.npmmirror.com/@vue/reactivity-transform/3.2.31:
+    resolution: {integrity: sha512-uS4l4z/W7wXdI+Va5pgVxBJ345wyGFKvpPYtdSgvfJfX/x2Ymm6ophQlXXB6acqGHtXuBqNyyO3zVp9b1r0MOA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/reactivity-transform/-/reactivity-transform-3.2.31.tgz}
+    name: '@vue/reactivity-transform'
+    version: 3.2.31
+    dependencies:
+      '@babel/parser': registry.npmmirror.com/@babel/parser/7.17.3
+      '@vue/compiler-core': registry.npmmirror.com/@vue/compiler-core/3.2.31
+      '@vue/shared': registry.npmmirror.com/@vue/shared/3.2.31
+      estree-walker: registry.npmmirror.com/estree-walker/2.0.2
+      magic-string: registry.npmmirror.com/magic-string/0.25.7
+    dev: true
+
+  registry.npmmirror.com/@vue/reactivity/3.2.31:
+    resolution: {integrity: sha512-HVr0l211gbhpEKYr2hYe7hRsV91uIVGFYNHj73njbARVGHQvIojkImKMaZNDdoDZOIkMsBc9a1sMqR+WZwfSCw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.2.31.tgz}
+    name: '@vue/reactivity'
+    version: 3.2.31
+    dependencies:
+      '@vue/shared': registry.npmmirror.com/@vue/shared/3.2.31
+    dev: true
+
+  registry.npmmirror.com/@vue/runtime-core/3.2.31:
+    resolution: {integrity: sha512-Kcog5XmSY7VHFEMuk4+Gap8gUssYMZ2+w+cmGI6OpZWYOEIcbE0TPzzPHi+8XTzAgx1w/ZxDFcXhZeXN5eKWsA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.2.31.tgz}
+    name: '@vue/runtime-core'
+    version: 3.2.31
+    dependencies:
+      '@vue/reactivity': registry.npmmirror.com/@vue/reactivity/3.2.31
+      '@vue/shared': registry.npmmirror.com/@vue/shared/3.2.31
+    dev: true
+
+  registry.npmmirror.com/@vue/runtime-dom/3.2.31:
+    resolution: {integrity: sha512-N+o0sICVLScUjfLG7u9u5XCjvmsexAiPt17GNnaWHJUfsKed5e85/A3SWgKxzlxx2SW/Hw7RQxzxbXez9PtY3g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.2.31.tgz}
+    name: '@vue/runtime-dom'
+    version: 3.2.31
+    dependencies:
+      '@vue/runtime-core': registry.npmmirror.com/@vue/runtime-core/3.2.31
+      '@vue/shared': registry.npmmirror.com/@vue/shared/3.2.31
+      csstype: registry.npmmirror.com/csstype/2.6.19
+    dev: true
+
+  registry.npmmirror.com/@vue/server-renderer/3.2.31_vue@3.2.31:
+    resolution: {integrity: sha512-8CN3Zj2HyR2LQQBHZ61HexF5NReqngLT3oahyiVRfSSvak+oAvVmu8iNLSu6XR77Ili2AOpnAt1y8ywjjqtmkg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.2.31.tgz}
+    id: registry.npmmirror.com/@vue/server-renderer/3.2.31
+    name: '@vue/server-renderer'
+    version: 3.2.31
+    peerDependencies:
+      vue: 3.2.31
+    dependencies:
+      '@vue/compiler-ssr': registry.npmmirror.com/@vue/compiler-ssr/3.2.31
+      '@vue/shared': registry.npmmirror.com/@vue/shared/3.2.31
+      vue: registry.npmmirror.com/vue/3.2.31
+    dev: true
+
+  registry.npmmirror.com/@vue/shared/3.2.31:
+    resolution: {integrity: sha512-ymN2pj6zEjiKJZbrf98UM2pfDd6F2H7ksKw7NDt/ZZ1fh5Ei39X5tABugtT03ZRlWd9imccoK0hE8hpjpU7irQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/shared/-/shared-3.2.31.tgz}
+    name: '@vue/shared'
+    version: 3.2.31
+    dev: true
+
+  registry.npmmirror.com/@vueuse/core/5.3.0:
+    resolution: {integrity: sha512-bBL1/JMRHFWmbgQzUZHF4WOwlqfenR1B8+elriXsbnHlogQM5foSz9++WyDBR0YPIVgCJq7fvNLqd4T7+cjc5w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vueuse/core/-/core-5.3.0.tgz}
+    name: '@vueuse/core'
+    version: 5.3.0
+    dependencies:
+      '@vueuse/shared': registry.npmmirror.com/@vueuse/shared/5.3.0
+      vue-demi: registry.npmmirror.com/vue-demi/0.12.1
+    transitivePeerDependencies:
+      - '@vue/composition-api'
+      - vue
+    dev: false
+
+  registry.npmmirror.com/@vueuse/shared/5.3.0:
+    resolution: {integrity: sha512-qZfkPFH0qTScFpYiPOFpTcxWriRhlM3bgSzl3DFTgr/U0eZg3w2EFWaRZHdWeSvAUdNQyjOC4Toa8S0zJyEjHw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vueuse/shared/-/shared-5.3.0.tgz}
+    name: '@vueuse/shared'
+    version: 5.3.0
+    dependencies:
+      vue-demi: registry.npmmirror.com/vue-demi/0.12.1
+    transitivePeerDependencies:
+      - '@vue/composition-api'
+      - vue
+    dev: false
+
+  registry.npmmirror.com/@windicss/config/1.7.1:
+    resolution: {integrity: sha512-bT4Ze8d1kTKbVdQZ7yal9vjhIfuYypco2gVTy4OXvg6eAHFNZaOB/Ai4FqdRKvbgOqChHGiC32r5J55hmq6tDw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@windicss/config/-/config-1.7.1.tgz}
+    name: '@windicss/config'
+    version: 1.7.1
+    dependencies:
+      debug: registry.npmmirror.com/debug/4.3.3
+      jiti: registry.npmmirror.com/jiti/1.13.0
+      windicss: registry.npmmirror.com/windicss/3.4.3
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  registry.npmmirror.com/@windicss/plugin-utils/1.7.1:
+    resolution: {integrity: sha512-VMBLZ11s5kQt1RIIwfB45xFswb+SI1cvI5mK07dUSlfpomG1d1bqnB57bioo/jFNZh2Rl8wVnEvLTl7iZ4r09Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@windicss/plugin-utils/-/plugin-utils-1.7.1.tgz}
+    name: '@windicss/plugin-utils'
+    version: 1.7.1
+    dependencies:
+      '@antfu/utils': registry.npmmirror.com/@antfu/utils/0.4.0
+      '@windicss/config': registry.npmmirror.com/@windicss/config/1.7.1
+      debug: registry.npmmirror.com/debug/4.3.3
+      fast-glob: registry.npmmirror.com/fast-glob/3.2.11
+      magic-string: registry.npmmirror.com/magic-string/0.25.7
+      micromatch: registry.npmmirror.com/micromatch/4.0.4
+      windicss: registry.npmmirror.com/windicss/3.4.3
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  registry.npmmirror.com/accepts/1.3.8:
+    resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/accepts/-/accepts-1.3.8.tgz}
+    name: accepts
+    version: 1.3.8
+    engines: {node: '>= 0.6'}
+    dependencies:
+      mime-types: registry.npmmirror.com/mime-types/2.1.34
+      negotiator: registry.npmmirror.com/negotiator/0.6.3
+    dev: true
+
+  registry.npmmirror.com/algoliasearch/4.12.1:
+    resolution: {integrity: sha512-c0dM1g3zZBJrkzE5GA/Nu1y3fFxx3LCzxKzcmp2dgGS8P4CjszB/l3lsSh2MSrrK1Hn/KV4BlbBMXtYgG1Bfrw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/algoliasearch/-/algoliasearch-4.12.1.tgz}
+    name: algoliasearch
+    version: 4.12.1
+    dependencies:
+      '@algolia/cache-browser-local-storage': registry.npmmirror.com/@algolia/cache-browser-local-storage/4.12.1
+      '@algolia/cache-common': registry.npmmirror.com/@algolia/cache-common/4.12.1
+      '@algolia/cache-in-memory': registry.npmmirror.com/@algolia/cache-in-memory/4.12.1
+      '@algolia/client-account': registry.npmmirror.com/@algolia/client-account/4.12.1
+      '@algolia/client-analytics': registry.npmmirror.com/@algolia/client-analytics/4.12.1
+      '@algolia/client-common': registry.npmmirror.com/@algolia/client-common/4.12.1
+      '@algolia/client-personalization': registry.npmmirror.com/@algolia/client-personalization/4.12.1
+      '@algolia/client-search': registry.npmmirror.com/@algolia/client-search/4.12.1
+      '@algolia/logger-common': registry.npmmirror.com/@algolia/logger-common/4.12.1
+      '@algolia/logger-console': registry.npmmirror.com/@algolia/logger-console/4.12.1
+      '@algolia/requester-browser-xhr': registry.npmmirror.com/@algolia/requester-browser-xhr/4.12.1
+      '@algolia/requester-common': registry.npmmirror.com/@algolia/requester-common/4.12.1
+      '@algolia/requester-node-http': registry.npmmirror.com/@algolia/requester-node-http/4.12.1
+      '@algolia/transporter': registry.npmmirror.com/@algolia/transporter/4.12.1
+    dev: true
+
+  registry.npmmirror.com/ansi-regex/5.0.1:
+    resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz}
+    name: ansi-regex
+    version: 5.0.1
+    engines: {node: '>=8'}
+    dev: true
+
+  registry.npmmirror.com/ansi-styles/4.3.0:
+    resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz}
+    name: ansi-styles
+    version: 4.3.0
+    engines: {node: '>=8'}
+    dependencies:
+      color-convert: registry.npmmirror.com/color-convert/2.0.1
+    dev: true
+
+  registry.npmmirror.com/anymatch/3.1.2:
+    resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/anymatch/-/anymatch-3.1.2.tgz}
+    name: anymatch
+    version: 3.1.2
+    engines: {node: '>= 8'}
+    dependencies:
+      normalize-path: registry.npmmirror.com/normalize-path/3.0.0
+      picomatch: registry.npmmirror.com/picomatch/2.3.1
+    dev: true
+
+  registry.npmmirror.com/argparse/1.0.10:
+    resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/argparse/-/argparse-1.0.10.tgz}
+    name: argparse
+    version: 1.0.10
+    dependencies:
+      sprintf-js: registry.npmmirror.com/sprintf-js/1.0.3
+    dev: true
+
+  registry.npmmirror.com/argparse/2.0.1:
+    resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz}
+    name: argparse
+    version: 2.0.1
+    dev: true
+
+  registry.npmmirror.com/array-union/2.1.0:
+    resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/array-union/-/array-union-2.1.0.tgz}
+    name: array-union
+    version: 2.1.0
+    engines: {node: '>=8'}
+    dev: true
+
+  registry.npmmirror.com/balanced-match/1.0.2:
+    resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz}
+    name: balanced-match
+    version: 1.0.2
+    dev: true
+
+  registry.npmmirror.com/base64-js/1.5.1:
+    resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz}
+    name: base64-js
+    version: 1.5.1
+    dev: true
+
+  registry.npmmirror.com/binary-extensions/2.2.0:
+    resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz}
+    name: binary-extensions
+    version: 2.2.0
+    engines: {node: '>=8'}
+    dev: true
+
+  registry.npmmirror.com/bl/4.1.0:
+    resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz}
+    name: bl
+    version: 4.1.0
+    dependencies:
+      buffer: registry.npmmirror.com/buffer/5.7.1
+      inherits: registry.npmmirror.com/inherits/2.0.4
+      readable-stream: registry.npmmirror.com/readable-stream/3.6.0
+    dev: true
+
+  registry.npmmirror.com/brace-expansion/1.1.11:
+    resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz}
+    name: brace-expansion
+    version: 1.1.11
+    dependencies:
+      balanced-match: registry.npmmirror.com/balanced-match/1.0.2
+      concat-map: registry.nlark.com/concat-map/0.0.1
+    dev: true
+
+  registry.npmmirror.com/braces/3.0.2:
+    resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz}
+    name: braces
+    version: 3.0.2
+    engines: {node: '>=8'}
+    dependencies:
+      fill-range: registry.npmmirror.com/fill-range/7.0.1
+    dev: true
+
+  registry.npmmirror.com/buffer/5.7.1:
+    resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/buffer/-/buffer-5.7.1.tgz}
+    name: buffer
+    version: 5.7.1
+    dependencies:
+      base64-js: registry.npmmirror.com/base64-js/1.5.1
+      ieee754: registry.npmmirror.com/ieee754/1.2.1
+    dev: true
+
+  registry.npmmirror.com/bytes/3.0.0:
+    resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/bytes/-/bytes-3.0.0.tgz}
+    name: bytes
+    version: 3.0.0
+    engines: {node: '>= 0.8'}
+    dev: true
+
+  registry.npmmirror.com/chalk/4.1.2:
+    resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz}
+    name: chalk
+    version: 4.1.2
+    engines: {node: '>=10'}
+    dependencies:
+      ansi-styles: registry.npmmirror.com/ansi-styles/4.3.0
+      supports-color: registry.npmmirror.com/supports-color/7.2.0
+    dev: true
+
+  registry.npmmirror.com/chokidar/3.5.3:
+    resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/chokidar/-/chokidar-3.5.3.tgz}
+    name: chokidar
+    version: 3.5.3
+    engines: {node: '>= 8.10.0'}
+    dependencies:
+      anymatch: registry.npmmirror.com/anymatch/3.1.2
+      braces: registry.npmmirror.com/braces/3.0.2
+      glob-parent: registry.npmmirror.com/glob-parent/5.1.2
+      is-binary-path: registry.npmmirror.com/is-binary-path/2.1.0
+      is-glob: registry.npmmirror.com/is-glob/4.0.3
+      normalize-path: registry.npmmirror.com/normalize-path/3.0.0
+      readdirp: registry.npmmirror.com/readdirp/3.6.0
+    optionalDependencies:
+      fsevents: registry.npmmirror.com/fsevents/2.3.2
+    dev: true
+
+  registry.npmmirror.com/cli-cursor/3.1.0:
+    resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/cli-cursor/-/cli-cursor-3.1.0.tgz}
+    name: cli-cursor
+    version: 3.1.0
+    engines: {node: '>=8'}
+    dependencies:
+      restore-cursor: registry.npmmirror.com/restore-cursor/3.1.0
+    dev: true
+
+  registry.npmmirror.com/cli-spinners/2.6.1:
+    resolution: {integrity: sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/cli-spinners/-/cli-spinners-2.6.1.tgz}
+    name: cli-spinners
+    version: 2.6.1
+    engines: {node: '>=6'}
+    dev: true
+
+  registry.npmmirror.com/clone/1.0.4:
+    resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/clone/-/clone-1.0.4.tgz}
+    name: clone
+    version: 1.0.4
+    engines: {node: '>=0.8'}
+    dev: true
+
+  registry.npmmirror.com/color-convert/2.0.1:
+    resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz}
+    name: color-convert
+    version: 2.0.1
+    engines: {node: '>=7.0.0'}
+    dependencies:
+      color-name: registry.npmmirror.com/color-name/1.1.4
+    dev: true
+
+  registry.npmmirror.com/color-name/1.1.4:
+    resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz}
+    name: color-name
+    version: 1.1.4
+    dev: true
+
+  registry.npmmirror.com/compressible/2.0.18:
+    resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/compressible/-/compressible-2.0.18.tgz}
+    name: compressible
+    version: 2.0.18
+    engines: {node: '>= 0.6'}
+    dependencies:
+      mime-db: registry.npmmirror.com/mime-db/1.51.0
+    dev: true
+
+  registry.npmmirror.com/compression/1.7.4:
+    resolution: {integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/compression/-/compression-1.7.4.tgz}
+    name: compression
+    version: 1.7.4
+    engines: {node: '>= 0.8.0'}
+    dependencies:
+      accepts: registry.npmmirror.com/accepts/1.3.8
+      bytes: registry.npmmirror.com/bytes/3.0.0
+      compressible: registry.npmmirror.com/compressible/2.0.18
+      debug: registry.npmmirror.com/debug/2.6.9
+      on-headers: registry.npmmirror.com/on-headers/1.0.2
+      safe-buffer: registry.npmmirror.com/safe-buffer/5.1.2
+      vary: registry.npmmirror.com/vary/1.1.2
+    dev: true
+
+  registry.npmmirror.com/csstype/2.6.19:
+    resolution: {integrity: sha512-ZVxXaNy28/k3kJg0Fou5MiYpp88j7H9hLZp8PDC3jV0WFjfH5E9xHb56L0W59cPbKbcHXeP4qyT8PrHp8t6LcQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/csstype/-/csstype-2.6.19.tgz}
+    name: csstype
+    version: 2.6.19
+    dev: true
+
+  registry.npmmirror.com/debug/2.6.9:
+    resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz}
+    name: debug
+    version: 2.6.9
+    dependencies:
+      ms: registry.npmmirror.com/ms/2.0.0
+    dev: true
+
+  registry.npmmirror.com/debug/4.3.3:
+    resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/debug/-/debug-4.3.3.tgz}
+    name: debug
+    version: 4.3.3
+    engines: {node: '>=6.0'}
+    peerDependencies:
+      supports-color: '*'
+    peerDependenciesMeta:
+      supports-color:
+        optional: true
+    dependencies:
+      ms: registry.npmmirror.com/ms/2.1.2
+    dev: true
+
+  registry.npmmirror.com/defaults/1.0.3:
+    resolution: {integrity: sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/defaults/-/defaults-1.0.3.tgz}
+    name: defaults
+    version: 1.0.3
+    dependencies:
+      clone: registry.npmmirror.com/clone/1.0.4
+    dev: true
+
+  registry.npmmirror.com/diacritics/1.3.0:
+    resolution: {integrity: sha512-wlwEkqcsaxvPJML+rDh/2iS824jbREk6DUMUKkEaSlxdYHeS43cClJtsWglvw2RfeXGm6ohKDqsXteJ5sP5enA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/diacritics/-/diacritics-1.3.0.tgz}
+    name: diacritics
+    version: 1.3.0
+    dev: true
+
+  registry.npmmirror.com/dir-glob/3.0.1:
+    resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz}
+    name: dir-glob
+    version: 3.0.1
+    engines: {node: '>=8'}
+    dependencies:
+      path-type: registry.npmmirror.com/path-type/4.0.0
+    dev: true
+
+  registry.npmmirror.com/entities/2.1.0:
+    resolution: {integrity: sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/entities/-/entities-2.1.0.tgz}
+    name: entities
+    version: 2.1.0
+    dev: true
+
+  registry.npmmirror.com/esbuild-android-arm64/0.14.23:
+    resolution: {integrity: sha512-k9sXem++mINrZty1v4FVt6nC5BQCFG4K2geCIUUqHNlTdFnuvcqsY7prcKZLFhqVC1rbcJAr9VSUGFL/vD4vsw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.23.tgz}
+    name: esbuild-android-arm64
+    version: 0.14.23
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [android]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  registry.npmmirror.com/esbuild-darwin-64/0.14.23:
+    resolution: {integrity: sha512-lB0XRbtOYYL1tLcYw8BoBaYsFYiR48RPrA0KfA/7RFTr4MV7Bwy/J4+7nLsVnv9FGuQummM3uJ93J3ptaTqFug==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.23.tgz}
+    name: esbuild-darwin-64
+    version: 0.14.23
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [darwin]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  registry.npmmirror.com/esbuild-darwin-arm64/0.14.23:
+    resolution: {integrity: sha512-yat73Z/uJ5tRcfRiI4CCTv0FSnwErm3BJQeZAh+1tIP0TUNh6o+mXg338Zl5EKChD+YGp6PN+Dbhs7qa34RxSw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.23.tgz}
+    name: esbuild-darwin-arm64
+    version: 0.14.23
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [darwin]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  registry.npmmirror.com/esbuild-freebsd-64/0.14.23:
+    resolution: {integrity: sha512-/1xiTjoLuQ+LlbfjJdKkX45qK/M7ARrbLmyf7x3JhyQGMjcxRYVR6Dw81uH3qlMHwT4cfLW4aEVBhP1aNV7VsA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.23.tgz}
+    name: esbuild-freebsd-64
+    version: 0.14.23
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [freebsd]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  registry.npmmirror.com/esbuild-freebsd-arm64/0.14.23:
+    resolution: {integrity: sha512-uyPqBU/Zcp6yEAZS4LKj5jEE0q2s4HmlMBIPzbW6cTunZ8cyvjG6YWpIZXb1KK3KTJDe62ltCrk3VzmWHp+iLg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.23.tgz}
+    name: esbuild-freebsd-arm64
+    version: 0.14.23
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [freebsd]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  registry.npmmirror.com/esbuild-linux-32/0.14.23:
+    resolution: {integrity: sha512-37R/WMkQyUfNhbH7aJrr1uCjDVdnPeTHGeDhZPUNhfoHV0lQuZNCKuNnDvlH/u/nwIYZNdVvz1Igv5rY/zfrzQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esbuild-linux-32/-/esbuild-linux-32-0.14.23.tgz}
+    name: esbuild-linux-32
+    version: 0.14.23
+    engines: {node: '>=12'}
+    cpu: [ia32]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  registry.npmmirror.com/esbuild-linux-64/0.14.23:
+    resolution: {integrity: sha512-H0gztDP60qqr8zoFhAO64waoN5yBXkmYCElFklpd6LPoobtNGNnDe99xOQm28+fuD75YJ7GKHzp/MLCLhw2+vQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esbuild-linux-64/-/esbuild-linux-64-0.14.23.tgz}
+    name: esbuild-linux-64
+    version: 0.14.23
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  registry.npmmirror.com/esbuild-linux-arm/0.14.23:
+    resolution: {integrity: sha512-x64CEUxi8+EzOAIpCUeuni0bZfzPw/65r8tC5cy5zOq9dY7ysOi5EVQHnzaxS+1NmV+/RVRpmrzGw1QgY2Xpmw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.23.tgz}
+    name: esbuild-linux-arm
+    version: 0.14.23
+    engines: {node: '>=12'}
+    cpu: [arm]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  registry.npmmirror.com/esbuild-linux-arm64/0.14.23:
+    resolution: {integrity: sha512-c4MLOIByNHR55n3KoYf9hYDfBRghMjOiHLaoYLhkQkIabb452RWi+HsNgB41sUpSlOAqfpqKPFNg7VrxL3UX9g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.23.tgz}
+    name: esbuild-linux-arm64
+    version: 0.14.23
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  registry.npmmirror.com/esbuild-linux-mips64le/0.14.23:
+    resolution: {integrity: sha512-kHKyKRIAedYhKug2EJpyJxOUj3VYuamOVA1pY7EimoFPzaF3NeY7e4cFBAISC/Av0/tiV0xlFCt9q0HJ68IBIw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.23.tgz}
+    name: esbuild-linux-mips64le
+    version: 0.14.23
+    engines: {node: '>=12'}
+    cpu: [mips64el]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  registry.npmmirror.com/esbuild-linux-ppc64le/0.14.23:
+    resolution: {integrity: sha512-7ilAiJEPuJJnJp/LiDO0oJm5ygbBPzhchJJh9HsHZzeqO+3PUzItXi+8PuicY08r0AaaOe25LA7sGJ0MzbfBag==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.23.tgz}
+    name: esbuild-linux-ppc64le
+    version: 0.14.23
+    engines: {node: '>=12'}
+    cpu: [ppc64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  registry.npmmirror.com/esbuild-linux-riscv64/0.14.23:
+    resolution: {integrity: sha512-fbL3ggK2wY0D8I5raPIMPhpCvODFE+Bhb5QGtNP3r5aUsRR6TQV+ZBXIaw84iyvKC8vlXiA4fWLGhghAd/h/Zg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.23.tgz}
+    name: esbuild-linux-riscv64
+    version: 0.14.23
+    engines: {node: '>=12'}
+    cpu: [riscv64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  registry.npmmirror.com/esbuild-linux-s390x/0.14.23:
+    resolution: {integrity: sha512-GHMDCyfy7+FaNSO8RJ8KCFsnax8fLUsOrj9q5Gi2JmZMY0Zhp75keb5abTFCq2/Oy6KVcT0Dcbyo/bFb4rIFJA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.23.tgz}
+    name: esbuild-linux-s390x
+    version: 0.14.23
+    engines: {node: '>=12'}
+    cpu: [s390x]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  registry.npmmirror.com/esbuild-netbsd-64/0.14.23:
+    resolution: {integrity: sha512-ovk2EX+3rrO1M2lowJfgMb/JPN1VwVYrx0QPUyudxkxLYrWeBxDKQvc6ffO+kB4QlDyTfdtAURrVzu3JeNdA2g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.23.tgz}
+    name: esbuild-netbsd-64
+    version: 0.14.23
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [netbsd]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  registry.npmmirror.com/esbuild-openbsd-64/0.14.23:
+    resolution: {integrity: sha512-uYYNqbVR+i7k8ojP/oIROAHO9lATLN7H2QeXKt2H310Fc8FJj4y3Wce6hx0VgnJ4k1JDrgbbiXM8rbEgQyg8KA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.23.tgz}
+    name: esbuild-openbsd-64
+    version: 0.14.23
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [openbsd]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  registry.npmmirror.com/esbuild-sunos-64/0.14.23:
+    resolution: {integrity: sha512-hAzeBeET0+SbScknPzS2LBY6FVDpgE+CsHSpe6CEoR51PApdn2IB0SyJX7vGelXzlyrnorM4CAsRyb9Qev4h9g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.23.tgz}
+    name: esbuild-sunos-64
+    version: 0.14.23
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [sunos]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  registry.npmmirror.com/esbuild-windows-32/0.14.23:
+    resolution: {integrity: sha512-Kttmi3JnohdaREbk6o9e25kieJR379TsEWF0l39PQVHXq3FR6sFKtVPgY8wk055o6IB+rllrzLnbqOw/UV60EA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esbuild-windows-32/-/esbuild-windows-32-0.14.23.tgz}
+    name: esbuild-windows-32
+    version: 0.14.23
+    engines: {node: '>=12'}
+    cpu: [ia32]
+    os: [win32]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  registry.npmmirror.com/esbuild-windows-64/0.14.23:
+    resolution: {integrity: sha512-JtIT0t8ymkpl6YlmOl6zoSWL5cnCgyLaBdf/SiU/Eg3C13r0NbHZWNT/RDEMKK91Y6t79kTs3vyRcNZbfu5a8g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esbuild-windows-64/-/esbuild-windows-64-0.14.23.tgz}
+    name: esbuild-windows-64
+    version: 0.14.23
+    engines: {node: '>=12'}
+    cpu: [x64]
+    os: [win32]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  registry.npmmirror.com/esbuild-windows-arm64/0.14.23:
+    resolution: {integrity: sha512-cTFaQqT2+ik9e4hePvYtRZQ3pqOvKDVNarzql0VFIzhc0tru/ZgdLoXd6epLiKT+SzoSce6V9YJ+nn6RCn6SHw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.23.tgz}
+    name: esbuild-windows-arm64
+    version: 0.14.23
+    engines: {node: '>=12'}
+    cpu: [arm64]
+    os: [win32]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  registry.npmmirror.com/esbuild/0.14.23:
+    resolution: {integrity: sha512-XjnIcZ9KB6lfonCa+jRguXyRYcldmkyZ99ieDksqW/C8bnyEX299yA4QH2XcgijCgaddEZePPTgvx/2imsq7Ig==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esbuild/-/esbuild-0.14.23.tgz}
+    name: esbuild
+    version: 0.14.23
+    engines: {node: '>=12'}
+    hasBin: true
+    requiresBuild: true
+    optionalDependencies:
+      esbuild-android-arm64: registry.npmmirror.com/esbuild-android-arm64/0.14.23
+      esbuild-darwin-64: registry.npmmirror.com/esbuild-darwin-64/0.14.23
+      esbuild-darwin-arm64: registry.npmmirror.com/esbuild-darwin-arm64/0.14.23
+      esbuild-freebsd-64: registry.npmmirror.com/esbuild-freebsd-64/0.14.23
+      esbuild-freebsd-arm64: registry.npmmirror.com/esbuild-freebsd-arm64/0.14.23
+      esbuild-linux-32: registry.npmmirror.com/esbuild-linux-32/0.14.23
+      esbuild-linux-64: registry.npmmirror.com/esbuild-linux-64/0.14.23
+      esbuild-linux-arm: registry.npmmirror.com/esbuild-linux-arm/0.14.23
+      esbuild-linux-arm64: registry.npmmirror.com/esbuild-linux-arm64/0.14.23
+      esbuild-linux-mips64le: registry.npmmirror.com/esbuild-linux-mips64le/0.14.23
+      esbuild-linux-ppc64le: registry.npmmirror.com/esbuild-linux-ppc64le/0.14.23
+      esbuild-linux-riscv64: registry.npmmirror.com/esbuild-linux-riscv64/0.14.23
+      esbuild-linux-s390x: registry.npmmirror.com/esbuild-linux-s390x/0.14.23
+      esbuild-netbsd-64: registry.npmmirror.com/esbuild-netbsd-64/0.14.23
+      esbuild-openbsd-64: registry.npmmirror.com/esbuild-openbsd-64/0.14.23
+      esbuild-sunos-64: registry.npmmirror.com/esbuild-sunos-64/0.14.23
+      esbuild-windows-32: registry.npmmirror.com/esbuild-windows-32/0.14.23
+      esbuild-windows-64: registry.npmmirror.com/esbuild-windows-64/0.14.23
+      esbuild-windows-arm64: registry.npmmirror.com/esbuild-windows-arm64/0.14.23
+    dev: true
+
+  registry.npmmirror.com/escape-html/1.0.3:
+    resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz}
+    name: escape-html
+    version: 1.0.3
+    dev: true
+
+  registry.npmmirror.com/esprima/4.0.1:
+    resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/esprima/-/esprima-4.0.1.tgz}
+    name: esprima
+    version: 4.0.1
+    engines: {node: '>=4'}
+    hasBin: true
+    dev: true
+
+  registry.npmmirror.com/estree-walker/2.0.2:
+    resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz}
+    name: estree-walker
+    version: 2.0.2
+    dev: true
+
+  registry.npmmirror.com/extend-shallow/2.0.1:
+    resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/extend-shallow/-/extend-shallow-2.0.1.tgz}
+    name: extend-shallow
+    version: 2.0.1
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-extendable: registry.npmmirror.com/is-extendable/0.1.1
+    dev: true
+
+  registry.npmmirror.com/fast-glob/3.2.11:
+    resolution: {integrity: sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/fast-glob/-/fast-glob-3.2.11.tgz}
+    name: fast-glob
+    version: 3.2.11
+    engines: {node: '>=8.6.0'}
+    dependencies:
+      '@nodelib/fs.stat': registry.npmmirror.com/@nodelib/fs.stat/2.0.5
+      '@nodelib/fs.walk': registry.npmmirror.com/@nodelib/fs.walk/1.2.8
+      glob-parent: registry.npmmirror.com/glob-parent/5.1.2
+      merge2: registry.npmmirror.com/merge2/1.4.1
+      micromatch: registry.npmmirror.com/micromatch/4.0.4
+    dev: true
+
+  registry.npmmirror.com/fastq/1.13.0:
+    resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/fastq/-/fastq-1.13.0.tgz}
+    name: fastq
+    version: 1.13.0
+    dependencies:
+      reusify: registry.npmmirror.com/reusify/1.0.4
+    dev: true
+
+  registry.npmmirror.com/fill-range/7.0.1:
+    resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz}
+    name: fill-range
+    version: 7.0.1
+    engines: {node: '>=8'}
+    dependencies:
+      to-regex-range: registry.npmmirror.com/to-regex-range/5.0.1
+    dev: true
+
+  registry.npmmirror.com/fs-extra/10.0.0:
+    resolution: {integrity: sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/fs-extra/-/fs-extra-10.0.0.tgz}
+    name: fs-extra
+    version: 10.0.0
+    engines: {node: '>=12'}
+    dependencies:
+      graceful-fs: registry.npmmirror.com/graceful-fs/4.2.9
+      jsonfile: registry.npmmirror.com/jsonfile/6.1.0
+      universalify: registry.npmmirror.com/universalify/2.0.0
+    dev: true
+
+  registry.npmmirror.com/fsevents/2.3.2:
+    resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz}
+    name: fsevents
+    version: 2.3.2
+    engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+    os: [darwin]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  registry.npmmirror.com/function-bind/1.1.1:
+    resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz}
+    name: function-bind
+    version: 1.1.1
+    dev: true
+
+  registry.npmmirror.com/glob-parent/5.1.2:
+    resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz}
+    name: glob-parent
+    version: 5.1.2
+    engines: {node: '>= 6'}
+    dependencies:
+      is-glob: registry.npmmirror.com/is-glob/4.0.3
+    dev: true
+
+  registry.npmmirror.com/globby/11.1.0:
+    resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/globby/-/globby-11.1.0.tgz}
+    name: globby
+    version: 11.1.0
+    engines: {node: '>=10'}
+    dependencies:
+      array-union: registry.npmmirror.com/array-union/2.1.0
+      dir-glob: registry.npmmirror.com/dir-glob/3.0.1
+      fast-glob: registry.npmmirror.com/fast-glob/3.2.11
+      ignore: registry.npmmirror.com/ignore/5.2.0
+      merge2: registry.npmmirror.com/merge2/1.4.1
+      slash: registry.npmmirror.com/slash/3.0.0
+    dev: true
+
+  registry.npmmirror.com/graceful-fs/4.2.9:
+    resolution: {integrity: sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.9.tgz}
+    name: graceful-fs
+    version: 4.2.9
+    dev: true
+
+  registry.npmmirror.com/gray-matter/4.0.3:
+    resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/gray-matter/-/gray-matter-4.0.3.tgz}
+    name: gray-matter
+    version: 4.0.3
+    engines: {node: '>=6.0'}
+    dependencies:
+      js-yaml: registry.npmmirror.com/js-yaml/3.14.1
+      kind-of: registry.npmmirror.com/kind-of/6.0.3
+      section-matter: registry.npmmirror.com/section-matter/1.0.0
+      strip-bom-string: registry.npmmirror.com/strip-bom-string/1.0.0
+    dev: true
+
+  registry.npmmirror.com/has-flag/4.0.0:
+    resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz}
+    name: has-flag
+    version: 4.0.0
+    engines: {node: '>=8'}
+    dev: true
+
+  registry.npmmirror.com/has/1.0.3:
+    resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/has/-/has-1.0.3.tgz}
+    name: has
+    version: 1.0.3
+    engines: {node: '>= 0.4.0'}
+    dependencies:
+      function-bind: registry.npmmirror.com/function-bind/1.1.1
+    dev: true
+
+  registry.npmmirror.com/ieee754/1.2.1:
+    resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz}
+    name: ieee754
+    version: 1.2.1
+    dev: true
+
+  registry.npmmirror.com/ignore/5.2.0:
+    resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ignore/-/ignore-5.2.0.tgz}
+    name: ignore
+    version: 5.2.0
+    engines: {node: '>= 4'}
+    dev: true
+
+  registry.npmmirror.com/inherits/2.0.4:
+    resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz}
+    name: inherits
+    version: 2.0.4
+    dev: true
+
+  registry.npmmirror.com/is-binary-path/2.1.0:
+    resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz}
+    name: is-binary-path
+    version: 2.1.0
+    engines: {node: '>=8'}
+    dependencies:
+      binary-extensions: registry.npmmirror.com/binary-extensions/2.2.0
+    dev: true
+
+  registry.npmmirror.com/is-core-module/2.8.1:
+    resolution: {integrity: sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-core-module/-/is-core-module-2.8.1.tgz}
+    name: is-core-module
+    version: 2.8.1
+    dependencies:
+      has: registry.npmmirror.com/has/1.0.3
+    dev: true
+
+  registry.npmmirror.com/is-extendable/0.1.1:
+    resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-extendable/-/is-extendable-0.1.1.tgz}
+    name: is-extendable
+    version: 0.1.1
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  registry.npmmirror.com/is-extglob/2.1.1:
+    resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz}
+    name: is-extglob
+    version: 2.1.1
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  registry.npmmirror.com/is-glob/4.0.3:
+    resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz}
+    name: is-glob
+    version: 4.0.3
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      is-extglob: registry.npmmirror.com/is-extglob/2.1.1
+    dev: true
+
+  registry.npmmirror.com/is-interactive/1.0.0:
+    resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-interactive/-/is-interactive-1.0.0.tgz}
+    name: is-interactive
+    version: 1.0.0
+    engines: {node: '>=8'}
+    dev: true
+
+  registry.npmmirror.com/is-number/7.0.0:
+    resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz}
+    name: is-number
+    version: 7.0.0
+    engines: {node: '>=0.12.0'}
+    dev: true
+
+  registry.npmmirror.com/is-unicode-supported/0.1.0:
+    resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz}
+    name: is-unicode-supported
+    version: 0.1.0
+    engines: {node: '>=10'}
+    dev: true
+
+  registry.npmmirror.com/jiti/1.13.0:
+    resolution: {integrity: sha512-/n9mNxZj/HDSrincJ6RP+L+yXbpnB8FybySBa+IjIaoH9FIxBbrbRT5XUbe8R7zuVM2AQqNMNDDqz0bzx3znOQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jiti/-/jiti-1.13.0.tgz}
+    name: jiti
+    version: 1.13.0
+    hasBin: true
+    dev: true
+
+  registry.npmmirror.com/js-yaml/3.14.1:
+    resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/js-yaml/-/js-yaml-3.14.1.tgz}
+    name: js-yaml
+    version: 3.14.1
+    hasBin: true
+    dependencies:
+      argparse: registry.npmmirror.com/argparse/1.0.10
+      esprima: registry.npmmirror.com/esprima/4.0.1
+    dev: true
+
+  registry.npmmirror.com/jsonfile/6.1.0:
+    resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz}
+    name: jsonfile
+    version: 6.1.0
+    dependencies:
+      universalify: registry.npmmirror.com/universalify/2.0.0
+    optionalDependencies:
+      graceful-fs: registry.npmmirror.com/graceful-fs/4.2.9
+    dev: true
+
+  registry.npmmirror.com/kind-of/6.0.3:
+    resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/kind-of/-/kind-of-6.0.3.tgz}
+    name: kind-of
+    version: 6.0.3
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  registry.npmmirror.com/kolorist/1.5.1:
+    resolution: {integrity: sha512-lxpCM3HTvquGxKGzHeknB/sUjuVoUElLlfYnXZT73K8geR9jQbroGlSCFBax9/0mpGoD3kzcMLnOlGQPJJNyqQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/kolorist/-/kolorist-1.5.1.tgz}
+    name: kolorist
+    version: 1.5.1
+    dev: true
+
+  registry.npmmirror.com/linkify-it/3.0.3:
+    resolution: {integrity: sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/linkify-it/-/linkify-it-3.0.3.tgz}
+    name: linkify-it
+    version: 3.0.3
+    dependencies:
+      uc.micro: registry.npmmirror.com/uc.micro/1.0.6
+    dev: true
+
+  registry.npmmirror.com/log-symbols/4.1.0:
+    resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/log-symbols/-/log-symbols-4.1.0.tgz}
+    name: log-symbols
+    version: 4.1.0
+    engines: {node: '>=10'}
+    dependencies:
+      chalk: registry.npmmirror.com/chalk/4.1.2
+      is-unicode-supported: registry.npmmirror.com/is-unicode-supported/0.1.0
+    dev: true
+
+  registry.npmmirror.com/lru-cache/6.0.0:
+    resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz}
+    name: lru-cache
+    version: 6.0.0
+    engines: {node: '>=10'}
+    dependencies:
+      yallist: registry.npmmirror.com/yallist/4.0.0
+    dev: true
+
+  registry.npmmirror.com/magic-string/0.25.7:
+    resolution: {integrity: sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/magic-string/-/magic-string-0.25.7.tgz}
+    name: magic-string
+    version: 0.25.7
+    dependencies:
+      sourcemap-codec: registry.npmmirror.com/sourcemap-codec/1.4.8
+    dev: true
+
+  registry.npmmirror.com/markdown-it-anchor/7.1.0_markdown-it@12.3.2:
+    resolution: {integrity: sha512-loQggrwsIkkP7TOrESvmYkV2ikbQNNKhHcWyqC7/C2CmfHl1tkUizJJU8C5aGgg7J6oXVQJx17gk7i47tNn/lQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/markdown-it-anchor/-/markdown-it-anchor-7.1.0.tgz}
+    id: registry.npmmirror.com/markdown-it-anchor/7.1.0
+    name: markdown-it-anchor
+    version: 7.1.0
+    peerDependencies:
+      markdown-it: '*'
+    dependencies:
+      markdown-it: registry.npmmirror.com/markdown-it/12.3.2
+    dev: true
+
+  registry.npmmirror.com/markdown-it-container/3.0.0:
+    resolution: {integrity: sha512-y6oKTq4BB9OQuY/KLfk/O3ysFhB3IMYoIWhGJEidXt1NQFocFK2sA2t0NYZAMyMShAGL6x5OPIbrmXPIqaN9rw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/markdown-it-container/-/markdown-it-container-3.0.0.tgz}
+    name: markdown-it-container
+    version: 3.0.0
+    dev: true
+
+  registry.npmmirror.com/markdown-it-emoji/2.0.0:
+    resolution: {integrity: sha512-39j7/9vP/CPCKbEI44oV8yoPJTpvfeReTn/COgRhSpNrjWF3PfP/JUxxB0hxV6ynOY8KH8Y8aX9NMDdo6z+6YQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/markdown-it-emoji/-/markdown-it-emoji-2.0.0.tgz}
+    name: markdown-it-emoji
+    version: 2.0.0
+    dev: true
+
+  registry.npmmirror.com/markdown-it-table-of-contents/0.5.2:
+    resolution: {integrity: sha512-6o+rxSwzXmXCUn1n8QGTSpgbcnHBG6lUU8x7A5Cssuq5vbfzTfitfGPvQ5PZkp+gP1NGS/DR2rkYqJPn0rbZ1A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/markdown-it-table-of-contents/-/markdown-it-table-of-contents-0.5.2.tgz}
+    name: markdown-it-table-of-contents
+    version: 0.5.2
+    engines: {node: '>6.4.0'}
+    dev: true
+
+  registry.npmmirror.com/markdown-it/12.3.2:
+    resolution: {integrity: sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/markdown-it/-/markdown-it-12.3.2.tgz}
+    name: markdown-it
+    version: 12.3.2
+    hasBin: true
+    dependencies:
+      argparse: registry.npmmirror.com/argparse/2.0.1
+      entities: registry.npmmirror.com/entities/2.1.0
+      linkify-it: registry.npmmirror.com/linkify-it/3.0.3
+      mdurl: registry.npmmirror.com/mdurl/1.0.1
+      uc.micro: registry.npmmirror.com/uc.micro/1.0.6
+    dev: true
+
+  registry.npmmirror.com/matchit/1.1.0:
+    resolution: {integrity: sha512-+nGYoOlfHmxe5BW5tE0EMJppXEwdSf8uBA1GTZC7Q77kbT35+VKLYJMzVNWCHSsga1ps1tPYFtFyvxvKzWVmMA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/matchit/-/matchit-1.1.0.tgz}
+    name: matchit
+    version: 1.1.0
+    engines: {node: '>=6'}
+    dependencies:
+      '@arr/every': registry.npmmirror.com/@arr/every/1.0.1
+    dev: true
+
+  registry.npmmirror.com/mdurl/1.0.1:
+    resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/mdurl/-/mdurl-1.0.1.tgz}
+    name: mdurl
+    version: 1.0.1
+    dev: true
+
+  registry.npmmirror.com/merge2/1.4.1:
+    resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz}
+    name: merge2
+    version: 1.4.1
+    engines: {node: '>= 8'}
+    dev: true
+
+  registry.npmmirror.com/micromatch/4.0.4:
+    resolution: {integrity: sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/micromatch/-/micromatch-4.0.4.tgz}
+    name: micromatch
+    version: 4.0.4
+    engines: {node: '>=8.6'}
+    dependencies:
+      braces: registry.npmmirror.com/braces/3.0.2
+      picomatch: registry.npmmirror.com/picomatch/2.3.1
+    dev: true
+
+  registry.npmmirror.com/mime-db/1.51.0:
+    resolution: {integrity: sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/mime-db/-/mime-db-1.51.0.tgz}
+    name: mime-db
+    version: 1.51.0
+    engines: {node: '>= 0.6'}
+    dev: true
+
+  registry.npmmirror.com/mime-types/2.1.34:
+    resolution: {integrity: sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/mime-types/-/mime-types-2.1.34.tgz}
+    name: mime-types
+    version: 2.1.34
+    engines: {node: '>= 0.6'}
+    dependencies:
+      mime-db: registry.npmmirror.com/mime-db/1.51.0
+    dev: true
+
+  registry.npmmirror.com/mimic-fn/2.1.0:
+    resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz}
+    name: mimic-fn
+    version: 2.1.0
+    engines: {node: '>=6'}
+    dev: true
+
+  registry.npmmirror.com/minimatch/3.1.2:
+    resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz}
+    name: minimatch
+    version: 3.1.2
+    dependencies:
+      brace-expansion: registry.npmmirror.com/brace-expansion/1.1.11
+    dev: true
+
+  registry.npmmirror.com/minimist/1.2.5:
+    resolution: {integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/minimist/-/minimist-1.2.5.tgz}
+    name: minimist
+    version: 1.2.5
+    dev: true
+
+  registry.npmmirror.com/mrmime/1.0.0:
+    resolution: {integrity: sha512-a70zx7zFfVO7XpnQ2IX1Myh9yY4UYvfld/dikWRnsXxbyvMcfz+u6UfgNAtH+k2QqtJuzVpv6eLTx1G2+WKZbQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/mrmime/-/mrmime-1.0.0.tgz}
+    name: mrmime
+    version: 1.0.0
+    engines: {node: '>=10'}
+    dev: true
+
+  registry.npmmirror.com/ms/2.0.0:
+    resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz}
+    name: ms
+    version: 2.0.0
+    dev: true
+
+  registry.npmmirror.com/ms/2.1.2:
+    resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz}
+    name: ms
+    version: 2.1.2
+    dev: true
+
+  registry.npmmirror.com/nanoid/3.3.1:
+    resolution: {integrity: sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/nanoid/-/nanoid-3.3.1.tgz}
+    name: nanoid
+    version: 3.3.1
+    engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+    hasBin: true
+    dev: true
+
+  registry.npmmirror.com/negotiator/0.6.3:
+    resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/negotiator/-/negotiator-0.6.3.tgz}
+    name: negotiator
+    version: 0.6.3
+    engines: {node: '>= 0.6'}
+    dev: true
+
+  registry.npmmirror.com/normalize-path/3.0.0:
+    resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz}
+    name: normalize-path
+    version: 3.0.0
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  registry.npmmirror.com/on-headers/1.0.2:
+    resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/on-headers/-/on-headers-1.0.2.tgz}
+    name: on-headers
+    version: 1.0.2
+    engines: {node: '>= 0.8'}
+    dev: true
+
+  registry.npmmirror.com/onetime/5.1.2:
+    resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz}
+    name: onetime
+    version: 5.1.2
+    engines: {node: '>=6'}
+    dependencies:
+      mimic-fn: registry.npmmirror.com/mimic-fn/2.1.0
+    dev: true
+
+  registry.npmmirror.com/ora/5.4.1:
+    resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ora/-/ora-5.4.1.tgz}
+    name: ora
+    version: 5.4.1
+    engines: {node: '>=10'}
+    dependencies:
+      bl: registry.npmmirror.com/bl/4.1.0
+      chalk: registry.npmmirror.com/chalk/4.1.2
+      cli-cursor: registry.npmmirror.com/cli-cursor/3.1.0
+      cli-spinners: registry.npmmirror.com/cli-spinners/2.6.1
+      is-interactive: registry.npmmirror.com/is-interactive/1.0.0
+      is-unicode-supported: registry.npmmirror.com/is-unicode-supported/0.1.0
+      log-symbols: registry.npmmirror.com/log-symbols/4.1.0
+      strip-ansi: registry.npmmirror.com/strip-ansi/6.0.1
+      wcwidth: registry.npmmirror.com/wcwidth/1.0.1
+    dev: true
+
+  registry.npmmirror.com/path-parse/1.0.7:
+    resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz}
+    name: path-parse
+    version: 1.0.7
+    dev: true
+
+  registry.npmmirror.com/path-type/4.0.0:
+    resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz}
+    name: path-type
+    version: 4.0.0
+    engines: {node: '>=8'}
+    dev: true
+
+  registry.npmmirror.com/picocolors/1.0.0:
+    resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz}
+    name: picocolors
+    version: 1.0.0
+    dev: true
+
+  registry.npmmirror.com/picomatch/2.3.1:
+    resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz}
+    name: picomatch
+    version: 2.3.1
+    engines: {node: '>=8.6'}
+    dev: true
+
+  registry.npmmirror.com/polka/0.5.2:
+    resolution: {integrity: sha512-FVg3vDmCqP80tOrs+OeNlgXYmFppTXdjD5E7I4ET1NjvtNmQrb1/mJibybKkb/d4NA7YWAr1ojxuhpL3FHqdlw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/polka/-/polka-0.5.2.tgz}
+    name: polka
+    version: 0.5.2
+    dependencies:
+      '@polka/url': registry.npmmirror.com/@polka/url/0.5.0
+      trouter: registry.npmmirror.com/trouter/2.0.1
+    dev: true
+
+  registry.npmmirror.com/postcss/8.4.6:
+    resolution: {integrity: sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/postcss/-/postcss-8.4.6.tgz}
+    name: postcss
+    version: 8.4.6
+    engines: {node: ^10 || ^12 || >=14}
+    dependencies:
+      nanoid: registry.npmmirror.com/nanoid/3.3.1
+      picocolors: registry.npmmirror.com/picocolors/1.0.0
+      source-map-js: registry.npmmirror.com/source-map-js/1.0.2
+    dev: true
+
+  registry.npmmirror.com/preact/10.6.6:
+    resolution: {integrity: sha512-dgxpTFV2vs4vizwKohYKkk7g7rmp1wOOcfd4Tz3IB3Wi+ivZzsn/SpeKJhRENSE+n8sUfsAl4S3HiCVT923ABw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/preact/-/preact-10.6.6.tgz}
+    name: preact
+    version: 10.6.6
+    dev: true
+
+  registry.npmmirror.com/prettier/2.5.1:
+    resolution: {integrity: sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/prettier/-/prettier-2.5.1.tgz}
+    name: prettier
+    version: 2.5.1
+    engines: {node: '>=10.13.0'}
+    hasBin: true
+    dev: true
+
+  registry.npmmirror.com/prismjs/1.27.0:
+    resolution: {integrity: sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/prismjs/-/prismjs-1.27.0.tgz}
+    name: prismjs
+    version: 1.27.0
+    engines: {node: '>=6'}
+    dev: true
+
+  registry.npmmirror.com/queue-microtask/1.2.3:
+    resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz}
+    name: queue-microtask
+    version: 1.2.3
+    dev: true
+
+  registry.npmmirror.com/readable-stream/3.6.0:
+    resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.0.tgz}
+    name: readable-stream
+    version: 3.6.0
+    engines: {node: '>= 6'}
+    dependencies:
+      inherits: registry.npmmirror.com/inherits/2.0.4
+      string_decoder: registry.npmmirror.com/string_decoder/1.3.0
+      util-deprecate: registry.npmmirror.com/util-deprecate/1.0.2
+    dev: true
+
+  registry.npmmirror.com/readdirp/3.6.0:
+    resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz}
+    name: readdirp
+    version: 3.6.0
+    engines: {node: '>=8.10.0'}
+    dependencies:
+      picomatch: registry.npmmirror.com/picomatch/2.3.1
+    dev: true
+
+  registry.npmmirror.com/resolve/1.22.0:
+    resolution: {integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/resolve/-/resolve-1.22.0.tgz}
+    name: resolve
+    version: 1.22.0
+    hasBin: true
+    dependencies:
+      is-core-module: registry.npmmirror.com/is-core-module/2.8.1
+      path-parse: registry.npmmirror.com/path-parse/1.0.7
+      supports-preserve-symlinks-flag: registry.npmmirror.com/supports-preserve-symlinks-flag/1.0.0
+    dev: true
+
+  registry.npmmirror.com/restore-cursor/3.1.0:
+    resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/restore-cursor/-/restore-cursor-3.1.0.tgz}
+    name: restore-cursor
+    version: 3.1.0
+    engines: {node: '>=8'}
+    dependencies:
+      onetime: registry.npmmirror.com/onetime/5.1.2
+      signal-exit: registry.npmmirror.com/signal-exit/3.0.7
+    dev: true
+
+  registry.npmmirror.com/reusify/1.0.4:
+    resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz}
+    name: reusify
+    version: 1.0.4
+    engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+    dev: true
+
+  registry.npmmirror.com/rollup/2.67.3:
+    resolution: {integrity: sha512-G/x1vUwbGtP6O5ZM8/sWr8+p7YfZhI18pPqMRtMYMWSbHjKZ/ajHGiM+GWNTlWyOR0EHIdT8LHU+Z4ciIZ1oBw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/rollup/-/rollup-2.67.3.tgz}
+    name: rollup
+    version: 2.67.3
+    engines: {node: '>=10.0.0'}
+    hasBin: true
+    optionalDependencies:
+      fsevents: registry.npmmirror.com/fsevents/2.3.2
+    dev: true
+
+  registry.npmmirror.com/run-parallel/1.2.0:
+    resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz}
+    name: run-parallel
+    version: 1.2.0
+    dependencies:
+      queue-microtask: registry.npmmirror.com/queue-microtask/1.2.3
+    dev: true
+
+  registry.npmmirror.com/safe-buffer/5.1.2:
+    resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz}
+    name: safe-buffer
+    version: 5.1.2
+    dev: true
+
+  registry.npmmirror.com/safe-buffer/5.2.1:
+    resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz}
+    name: safe-buffer
+    version: 5.2.1
+    dev: true
+
+  registry.npmmirror.com/section-matter/1.0.0:
+    resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/section-matter/-/section-matter-1.0.0.tgz}
+    name: section-matter
+    version: 1.0.0
+    engines: {node: '>=4'}
+    dependencies:
+      extend-shallow: registry.npmmirror.com/extend-shallow/2.0.1
+      kind-of: registry.npmmirror.com/kind-of/6.0.3
+    dev: true
+
+  registry.npmmirror.com/signal-exit/3.0.7:
+    resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz}
+    name: signal-exit
+    version: 3.0.7
+    dev: true
+
+  registry.npmmirror.com/sirv/1.0.19:
+    resolution: {integrity: sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/sirv/-/sirv-1.0.19.tgz}
+    name: sirv
+    version: 1.0.19
+    engines: {node: '>= 10'}
+    dependencies:
+      '@polka/url': registry.npmmirror.com/@polka/url/1.0.0-next.21
+      mrmime: registry.npmmirror.com/mrmime/1.0.0
+      totalist: registry.npmmirror.com/totalist/1.1.0
+    dev: true
+
+  registry.npmmirror.com/slash/3.0.0:
+    resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz}
+    name: slash
+    version: 3.0.0
+    engines: {node: '>=8'}
+    dev: true
+
+  registry.npmmirror.com/source-map-js/1.0.2:
+    resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz}
+    name: source-map-js
+    version: 1.0.2
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  registry.npmmirror.com/source-map/0.6.1:
+    resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz}
+    name: source-map
+    version: 0.6.1
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  registry.npmmirror.com/sourcemap-codec/1.4.8:
+    resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz}
+    name: sourcemap-codec
+    version: 1.4.8
+    dev: true
+
+  registry.npmmirror.com/sprintf-js/1.0.3:
+    resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz}
+    name: sprintf-js
+    version: 1.0.3
+    dev: true
+
+  registry.npmmirror.com/string_decoder/1.3.0:
+    resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz}
+    name: string_decoder
+    version: 1.3.0
+    dependencies:
+      safe-buffer: registry.npmmirror.com/safe-buffer/5.2.1
+    dev: true
+
+  registry.npmmirror.com/strip-ansi/6.0.1:
+    resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz}
+    name: strip-ansi
+    version: 6.0.1
+    engines: {node: '>=8'}
+    dependencies:
+      ansi-regex: registry.npmmirror.com/ansi-regex/5.0.1
+    dev: true
+
+  registry.npmmirror.com/strip-bom-string/1.0.0:
+    resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/strip-bom-string/-/strip-bom-string-1.0.0.tgz}
+    name: strip-bom-string
+    version: 1.0.0
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  registry.npmmirror.com/supports-color/7.2.0:
+    resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz}
+    name: supports-color
+    version: 7.2.0
+    engines: {node: '>=8'}
+    dependencies:
+      has-flag: registry.npmmirror.com/has-flag/4.0.0
+    dev: true
+
+  registry.npmmirror.com/supports-preserve-symlinks-flag/1.0.0:
+    resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz}
+    name: supports-preserve-symlinks-flag
+    version: 1.0.0
+    engines: {node: '>= 0.4'}
+    dev: true
+
+  registry.npmmirror.com/to-regex-range/5.0.1:
+    resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz}
+    name: to-regex-range
+    version: 5.0.1
+    engines: {node: '>=8.0'}
+    dependencies:
+      is-number: registry.npmmirror.com/is-number/7.0.0
+    dev: true
+
+  registry.npmmirror.com/totalist/1.1.0:
+    resolution: {integrity: sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/totalist/-/totalist-1.1.0.tgz}
+    name: totalist
+    version: 1.1.0
+    engines: {node: '>=6'}
+    dev: true
+
+  registry.npmmirror.com/trouter/2.0.1:
+    resolution: {integrity: sha512-kr8SKKw94OI+xTGOkfsvwZQ8mWoikZDd2n8XZHjJVZUARZT+4/VV6cacRS6CLsH9bNm+HFIPU1Zx4CnNnb4qlQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/trouter/-/trouter-2.0.1.tgz}
+    name: trouter
+    version: 2.0.1
+    engines: {node: '>=6'}
+    dependencies:
+      matchit: registry.npmmirror.com/matchit/1.1.0
+    dev: true
+
+  registry.npmmirror.com/uc.micro/1.0.6:
+    resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/uc.micro/-/uc.micro-1.0.6.tgz}
+    name: uc.micro
+    version: 1.0.6
+    dev: true
+
+  registry.npmmirror.com/universalify/2.0.0:
+    resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/universalify/-/universalify-2.0.0.tgz}
+    name: universalify
+    version: 2.0.0
+    engines: {node: '>= 10.0.0'}
+    dev: true
+
+  registry.npmmirror.com/util-deprecate/1.0.2:
+    resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz}
+    name: util-deprecate
+    version: 1.0.2
+    dev: true
+
+  registry.npmmirror.com/vary/1.1.2:
+    resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz}
+    name: vary
+    version: 1.1.2
+    engines: {node: '>= 0.8'}
+    dev: true
+
+  registry.npmmirror.com/vite-plugin-components/0.10.4:
+    resolution: {integrity: sha512-QOGd+7IE4EonPGMlxmudj0HadVxKzCdvaZmZcRgap4gE8F55sAIztuAQN4IHACEKuappWsB6XpMAY1iVrJUqog==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vite-plugin-components/-/vite-plugin-components-0.10.4.tgz}
+    name: vite-plugin-components
+    version: 0.10.4
+    deprecated: renamed to `unplugin-vue-components`, see https://github.com/antfu/unplugin-vue-components/releases/tag/v0.14.0
+    peerDependencies:
+      vite: ^2.0.0-beta.69
+    dependencies:
+      chokidar: registry.npmmirror.com/chokidar/3.5.3
+      debug: registry.npmmirror.com/debug/4.3.3
+      fast-glob: registry.npmmirror.com/fast-glob/3.2.11
+      magic-string: registry.npmmirror.com/magic-string/0.25.7
+      minimatch: registry.npmmirror.com/minimatch/3.1.2
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  registry.npmmirror.com/vite-plugin-icons/0.6.5_@iconify+json@1.1.461:
+    resolution: {integrity: sha512-lfePr8juO2ajp0571iLL+9zIoyBD9nSSSHlC4JYXbAeMOJB6WTP+Vdc2gze8yI8JRO+Z0TXCCvvL9bPgvkI4Cg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vite-plugin-icons/-/vite-plugin-icons-0.6.5.tgz}
+    id: registry.npmmirror.com/vite-plugin-icons/0.6.5
+    name: vite-plugin-icons
+    version: 0.6.5
+    deprecated: renamed to `unplugin-icons`, see https://github.com/antfu/unplugin-icons/releases/tag/v0.7.0
+    peerDependencies:
+      '@iconify/json': '*'
+      '@vue/compiler-sfc': ^3.0.2
+      vue-template-compiler: ^2.6.12
+    peerDependenciesMeta:
+      '@vue/compiler-sfc':
+        optional: true
+      vue-template-compiler:
+        optional: true
+    dependencies:
+      '@iconify/json': registry.npmmirror.com/@iconify/json/1.1.461
+      '@iconify/json-tools': registry.npmmirror.com/@iconify/json-tools/1.0.10
+      vue-template-es2015-compiler: registry.npmmirror.com/vue-template-es2015-compiler/1.9.1
+    dev: true
+
+  registry.npmmirror.com/vite-plugin-windicss/1.7.1:
+    resolution: {integrity: sha512-eEDeTPaeQAfe0widkTkm9X51BVpOE/yDIuFbULIKjXI7CfY1yjsPcxA6E3aZbLBYQcUmfhVUTYVaH5iAE5L8Hg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vite-plugin-windicss/-/vite-plugin-windicss-1.7.1.tgz}
+    name: vite-plugin-windicss
+    version: 1.7.1
+    peerDependencies:
+      vite: ^2.0.1
+    dependencies:
+      '@windicss/plugin-utils': registry.npmmirror.com/@windicss/plugin-utils/1.7.1
+      debug: registry.npmmirror.com/debug/4.3.3
+      kolorist: registry.npmmirror.com/kolorist/1.5.1
+      windicss: registry.npmmirror.com/windicss/3.4.3
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  registry.npmmirror.com/vite/2.8.4:
+    resolution: {integrity: sha512-GwtOkkaT2LDI82uWZKcrpRQxP5tymLnC7hVHHqNkhFNknYr0hJUlDLfhVRgngJvAy3RwypkDCWtTKn1BjO96Dw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vite/-/vite-2.8.4.tgz}
+    name: vite
+    version: 2.8.4
+    engines: {node: '>=12.2.0'}
+    hasBin: true
+    peerDependencies:
+      less: '*'
+      sass: '*'
+      stylus: '*'
+    peerDependenciesMeta:
+      less:
+        optional: true
+      sass:
+        optional: true
+      stylus:
+        optional: true
+    dependencies:
+      esbuild: registry.npmmirror.com/esbuild/0.14.23
+      postcss: registry.npmmirror.com/postcss/8.4.6
+      resolve: registry.npmmirror.com/resolve/1.22.0
+      rollup: registry.npmmirror.com/rollup/2.67.3
+    optionalDependencies:
+      fsevents: registry.npmmirror.com/fsevents/2.3.2
+    dev: true
+
+  registry.npmmirror.com/vitepress/0.14.1:
+    resolution: {integrity: sha512-cGsDULwKvKljtDNm4uy8zDYoM3gBRxr75R8+buzeyWnpXEqIwWICl0P2AHwLm2Dbs7cVy8lAREOrcUsShDzPuA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vitepress/-/vitepress-0.14.1.tgz}
+    name: vitepress
+    version: 0.14.1
+    engines: {node: '>=12.0.0'}
+    hasBin: true
+    dependencies:
+      '@docsearch/css': registry.npmmirror.com/@docsearch/css/1.0.0-alpha.28
+      '@docsearch/js': registry.npmmirror.com/@docsearch/js/1.0.0-alpha.28
+      '@vitejs/plugin-vue': registry.npmmirror.com/@vitejs/plugin-vue/1.10.2_vite@2.8.4
+      '@vue/compiler-sfc': registry.npmmirror.com/@vue/compiler-sfc/3.2.31
+      '@vue/server-renderer': registry.npmmirror.com/@vue/server-renderer/3.2.31_vue@3.2.31
+      chalk: registry.npmmirror.com/chalk/4.1.2
+      compression: registry.npmmirror.com/compression/1.7.4
+      debug: registry.npmmirror.com/debug/4.3.3
+      diacritics: registry.npmmirror.com/diacritics/1.3.0
+      escape-html: registry.npmmirror.com/escape-html/1.0.3
+      fs-extra: registry.npmmirror.com/fs-extra/10.0.0
+      globby: registry.npmmirror.com/globby/11.1.0
+      gray-matter: registry.npmmirror.com/gray-matter/4.0.3
+      lru-cache: registry.npmmirror.com/lru-cache/6.0.0
+      markdown-it: registry.npmmirror.com/markdown-it/12.3.2
+      markdown-it-anchor: registry.npmmirror.com/markdown-it-anchor/7.1.0_markdown-it@12.3.2
+      markdown-it-container: registry.npmmirror.com/markdown-it-container/3.0.0
+      markdown-it-emoji: registry.npmmirror.com/markdown-it-emoji/2.0.0
+      markdown-it-table-of-contents: registry.npmmirror.com/markdown-it-table-of-contents/0.5.2
+      minimist: registry.npmmirror.com/minimist/1.2.5
+      ora: registry.npmmirror.com/ora/5.4.1
+      polka: registry.npmmirror.com/polka/0.5.2
+      prismjs: registry.npmmirror.com/prismjs/1.27.0
+      sirv: registry.npmmirror.com/sirv/1.0.19
+      vite: registry.npmmirror.com/vite/2.8.4
+      vue: registry.npmmirror.com/vue/3.2.31
+    transitivePeerDependencies:
+      - less
+      - react
+      - react-dom
+      - sass
+      - stylus
+      - supports-color
+    dev: true
+
+  registry.npmmirror.com/vue-demi/0.12.1:
+    resolution: {integrity: sha512-QL3ny+wX8c6Xm1/EZylbgzdoDolye+VpCXRhI2hug9dJTP3OUJ3lmiKN3CsVV3mOJKwFi0nsstbgob0vG7aoIw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vue-demi/-/vue-demi-0.12.1.tgz}
+    name: vue-demi
+    version: 0.12.1
+    engines: {node: '>=12'}
+    hasBin: true
+    requiresBuild: true
+    peerDependencies:
+      '@vue/composition-api': ^1.0.0-rc.1
+      vue: ^3.0.0-0 || ^2.6.0
+    peerDependenciesMeta:
+      '@vue/composition-api':
+        optional: true
+    dev: false
+
+  registry.npmmirror.com/vue-template-es2015-compiler/1.9.1:
+    resolution: {integrity: sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz}
+    name: vue-template-es2015-compiler
+    version: 1.9.1
+    dev: true
+
+  registry.npmmirror.com/vue/3.2.31:
+    resolution: {integrity: sha512-odT3W2tcffTiQCy57nOT93INw1auq5lYLLYtWpPYQQYQOOdHiqFct9Xhna6GJ+pJQaF67yZABraH47oywkJgFw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/vue/-/vue-3.2.31.tgz}
+    name: vue
+    version: 3.2.31
+    dependencies:
+      '@vue/compiler-dom': registry.npmmirror.com/@vue/compiler-dom/3.2.31
+      '@vue/compiler-sfc': registry.npmmirror.com/@vue/compiler-sfc/3.2.31
+      '@vue/runtime-dom': registry.npmmirror.com/@vue/runtime-dom/3.2.31
+      '@vue/server-renderer': registry.npmmirror.com/@vue/server-renderer/3.2.31_vue@3.2.31
+      '@vue/shared': registry.npmmirror.com/@vue/shared/3.2.31
+    dev: true
+
+  registry.npmmirror.com/wcwidth/1.0.1:
+    resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/wcwidth/-/wcwidth-1.0.1.tgz}
+    name: wcwidth
+    version: 1.0.1
+    dependencies:
+      defaults: registry.npmmirror.com/defaults/1.0.3
+    dev: true
+
+  registry.npmmirror.com/windicss/3.4.3:
+    resolution: {integrity: sha512-UnugThsvEgy8RsPm4/B5DYMCAqvZzD6yWU7Anh+f07t5RSJ8zvmAylGLbXrHPJEmCKzo2Mf+fOUvISH7IJqM3A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/windicss/-/windicss-3.4.3.tgz}
+    name: windicss
+    version: 3.4.3
+    engines: {node: '>= 12'}
+    hasBin: true
+    dev: true
+
+  registry.npmmirror.com/yallist/4.0.0:
+    resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz}
+    name: yallist
+    version: 4.0.0
+    dev: true

+ 20 - 0
prettier.config.js

@@ -0,0 +1,20 @@
+module.exports = {
+  printWidth: 100,
+  tabWidth: 2,
+  useTabs: false,
+  semi: true,
+  vueIndentScriptAndStyle: true,
+  singleQuote: true,
+  quoteProps: 'as-needed',
+  bracketSpacing: true,
+  trailingComma: 'es5',
+  jsxBracketSameLine: false,
+  jsxSingleQuote: false,
+  arrowParens: 'always',
+  insertPragma: false,
+  requirePragma: false,
+  proseWrap: 'never',
+  htmlWhitespaceSensitivity: 'strict',
+  endOfLine: 'lf',
+  rangeStart: 0,
+};

二进制
public/images/i18n.png


二进制
public/logo.png


+ 19 - 0
tsconfig.json

@@ -0,0 +1,19 @@
+{
+  "compilerOptions": {
+    "module": "ESNext",
+    "baseUrl": ".",
+    "target": "es2016",
+    "lib": ["DOM", "ESNext"],
+    "strict": true,
+    "esModuleInterop": true,
+    "skipLibCheck": true,
+    "noUnusedLocals": true,
+    "moduleResolution": "node",
+    "resolveJsonModule": true,
+    "strictNullChecks": true,
+    "forceConsistentCasingInFileNames": true,
+    "types": ["vite/client", "node"]
+  },
+  "include": ["./*.ts", "./.vitepress/**/*.ts", "./.vitepress/**/*.vue"],
+  "exclude": ["**/dist/**", "node_modules"]
+}

+ 27 - 0
vite.config.ts

@@ -0,0 +1,27 @@
+import { UserConfig } from 'vite';
+import WindiCSS from 'vite-plugin-windicss';
+import Icons, { ViteIconsResolver } from 'vite-plugin-icons';
+import Components from 'vite-plugin-components';
+
+const config: UserConfig = {
+  optimizeDeps: {
+    exclude: ['vue-demi', '@vueuse/shared', '@vueuse/core'],
+  },
+  plugins: [
+    Components({
+      dirs: ['.vitepress/theme/components'],
+      customLoaderMatcher: (id) => id.endsWith('.md'),
+      customComponentResolvers: [
+        ViteIconsResolver({
+          componentPrefix: '',
+        }),
+      ],
+    }),
+    Icons(),
+    WindiCSS({
+      preflight: false,
+    }),
+  ],
+};
+
+export default config;

+ 30 - 0
windi.config.ts

@@ -0,0 +1,30 @@
+import { defineConfig } from 'vite-plugin-windicss';
+
+export default defineConfig({
+  extract: {
+    include: [
+      '**/*.md',
+      '.vitepress/theme/**/*.{md,vue}',
+      '.vitepress/@slidev/client/internals/SlideContainer.vue',
+      '.vitepress/@slidev/client/layouts/*.vue',
+      '.vitepress/@slidev/theme-default/layouts/*.vue',
+    ],
+  },
+  attributify: true,
+  shortcuts: {
+    'bg-main': 'bg-white dark:bg-[#111]',
+  },
+  theme: {
+    extend: {
+      colors: {
+        primary: {
+          DEFAULT: '#3AB9D4',
+          deep: '#2082A6',
+        },
+      },
+      fontFamily: {
+        mono: "'IBM Plex Mono', source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace",
+      },
+    },
+  },
+});

+ 1457 - 0
yarn.lock

@@ -0,0 +1,1457 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@algolia/cache-browser-local-storage@4.9.1":
+  version "4.9.1"
+  resolved "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.9.1.tgz#784e91580dcca00a8280b0905197f5abbbdf4b48"
+  integrity sha512-bAUU9vKCy45uTTlzJw0LYu1IjoZsmzL6lgjaVFaW1crhX/4P+JD5ReQv3n/wpiXSFaHq1WEO3WyH2g3ymzeipQ==
+  dependencies:
+    "@algolia/cache-common" "4.9.1"
+
+"@algolia/cache-common@4.9.1":
+  version "4.9.1"
+  resolved "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.9.1.tgz#2d5f37ba7aab7db76627c4a4fce51a7fd137fa65"
+  integrity sha512-tcvw4mOfFy44V4ZxDEy9wNGr6vFROZKRpXKTEBgdw/WBn6mX51H1ar4RWtceDEcDU4H5fIv5tsY3ip2hU+fTPg==
+
+"@algolia/cache-in-memory@4.9.1":
+  version "4.9.1"
+  resolved "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.9.1.tgz#3fd1d67aec804b6cc8439015b8b9c712a45c7ae0"
+  integrity sha512-IEJrHonvdymW2CnRfJtsTVWyfAH05xPEFkGXGCw00+6JNCj8Dln3TeaRLiaaY1srlyGedkemekQm1/Xb46CGOQ==
+  dependencies:
+    "@algolia/cache-common" "4.9.1"
+
+"@algolia/client-account@4.9.1":
+  version "4.9.1"
+  resolved "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.9.1.tgz#f2c1b3e49de2ee1fca44b8b5e64e1ce0dbdff0db"
+  integrity sha512-Shpjeuwb7i2LR5QuWREb6UbEQLGB+Pl/J5+wPgILJDP/uWp7jpl0ase9mYNQGKj7TjztpSpQCPZ3dSHPnzZPfw==
+  dependencies:
+    "@algolia/client-common" "4.9.1"
+    "@algolia/client-search" "4.9.1"
+    "@algolia/transporter" "4.9.1"
+
+"@algolia/client-analytics@4.9.1":
+  version "4.9.1"
+  resolved "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.9.1.tgz#56972496526910c53c5ce7844f4571efba63eb5f"
+  integrity sha512-/g6OkOSIA+A0t/tjvbL6iG/zV4El4LPFgv/tcAYHTH27BmlNtnEXw+iFpGjeUlQoPily9WVB3QNLMJkaNwL3HA==
+  dependencies:
+    "@algolia/client-common" "4.9.1"
+    "@algolia/client-search" "4.9.1"
+    "@algolia/requester-common" "4.9.1"
+    "@algolia/transporter" "4.9.1"
+
+"@algolia/client-common@4.9.1":
+  version "4.9.1"
+  resolved "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.9.1.tgz#ae313b65d3249efcb4fafd2e92ed1fa2fd075482"
+  integrity sha512-UziRTZ8km3qwoVPIyEre8TV6V+MX7UtbfVqPmSafZ0xu41UUZ+sL56YoKjOXkbKuybeIC9prXMGy/ID5bXkTqg==
+  dependencies:
+    "@algolia/requester-common" "4.9.1"
+    "@algolia/transporter" "4.9.1"
+
+"@algolia/client-recommendation@4.9.1":
+  version "4.9.1"
+  resolved "https://registry.npmjs.org/@algolia/client-recommendation/-/client-recommendation-4.9.1.tgz#217af2a38d37ab12cf23a419cc9a576af9d15b13"
+  integrity sha512-Drtvvm1PNIOpYf4HFlkPFstFQ3IsN+TRmxur2F7y6Faplb5ybISa8ithu1tmlTdyTf3A78hQUQjgJet6qD2XZw==
+  dependencies:
+    "@algolia/client-common" "4.9.1"
+    "@algolia/requester-common" "4.9.1"
+    "@algolia/transporter" "4.9.1"
+
+"@algolia/client-search@4.9.1":
+  version "4.9.1"
+  resolved "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.9.1.tgz#a2fbc47a1b343dade9a8b06310231d51ff675b1b"
+  integrity sha512-r9Cw2r8kJr45iYncFDht6EshARghU265wuY8Q8oHrpFHjAziEYdsUOdNmQKbsSH5J3gLjDPx1EI5DzVd6ivn3w==
+  dependencies:
+    "@algolia/client-common" "4.9.1"
+    "@algolia/requester-common" "4.9.1"
+    "@algolia/transporter" "4.9.1"
+
+"@algolia/logger-common@4.9.1":
+  version "4.9.1"
+  resolved "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.9.1.tgz#3323834095f2916338d2535d2df91c4723ac19f2"
+  integrity sha512-9mPrbFlFyPT7or/7PXTiJjyOewWB9QRkZKVXkt5zHAUiUzGxmmdpJIGpPv3YQnDur8lXrXaRI0MHXUuIDMY1ng==
+
+"@algolia/logger-console@4.9.1":
+  version "4.9.1"
+  resolved "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.9.1.tgz#c324ef26843dbed06b44586309331dbb949744ad"
+  integrity sha512-74VUwjtFjFpjZpi3QoHIPv0kcr3vWUSHX/Vs8PJW3lPsD4CgyhFenQbG9v+ZnyH0JrJwiYTtzfmrVh7IMWZGrQ==
+  dependencies:
+    "@algolia/logger-common" "4.9.1"
+
+"@algolia/requester-browser-xhr@4.9.1":
+  version "4.9.1"
+  resolved "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.9.1.tgz#0812f3c7c4105a4646c0fba8429b172b2d0e01c5"
+  integrity sha512-zc46tk5o0ikOAz3uYiRAMxC2iVKAMFKT7nNZnLB5IzT0uqAh7pz/+D/UvIxP4bKmsllpBSnPcpfQF+OI4Ag/BA==
+  dependencies:
+    "@algolia/requester-common" "4.9.1"
+
+"@algolia/requester-common@4.9.1":
+  version "4.9.1"
+  resolved "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.9.1.tgz#50fcf4c7c1ed7ae13159167ac1da2844d036a630"
+  integrity sha512-9hPgXnlCSbqJqF69M5x5WN3h51Dc+mk/iWNeJSVxExHGvCDfBBZd0v6S15i8q2a9cD1I2RnhMpbnX5BmGtabVA==
+
+"@algolia/requester-node-http@4.9.1":
+  version "4.9.1"
+  resolved "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.9.1.tgz#70054a0aa5643072404fcb68042eec97c7abd1c8"
+  integrity sha512-vYNVbSCuyrCSCjHBQJk+tLZtWCjvvDf5tSbRJjyJYMqpnXuIuP7gZm24iHil4NPYBhbBj5NU2ZDAhc/gTn75Ag==
+  dependencies:
+    "@algolia/requester-common" "4.9.1"
+
+"@algolia/transporter@4.9.1":
+  version "4.9.1"
+  resolved "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.9.1.tgz#63ef3d9ae3b6556fa1ff1e6265bbab482bd084b7"
+  integrity sha512-AbjFfGzX+cAuj7Qyc536OxIQzjFOA5FU2ANGStx8LBH+AKXScwfkx67C05riuaRR5adSCLMSEbVvUscH0nF+6A==
+  dependencies:
+    "@algolia/cache-common" "4.9.1"
+    "@algolia/logger-common" "4.9.1"
+    "@algolia/requester-common" "4.9.1"
+
+"@antfu/utils@^0.2.3":
+  version "0.2.4"
+  resolved "https://registry.npmjs.org/@antfu/utils/-/utils-0.2.4.tgz#c7d33fc6faa0d3a6fcc2555673f5e9b19c0fbc15"
+  integrity sha512-2bZNkVfL9IZESmvE26UKi8SzyvSoaIsGXDcnbHFMtmGMqUiB1fXpAJ1ijGf+tSqKRQ5yagck2U1Qk0p+705/kw==
+  dependencies:
+    "@types/throttle-debounce" "^2.1.0"
+
+"@arr/every@^1.0.0":
+  version "1.0.1"
+  resolved "https://registry.npmjs.org/@arr/every/-/every-1.0.1.tgz#22fe1f8e6355beca6c7c7bde965eb15cf994387b"
+  integrity sha512-UQFQ6SgyJ6LX42W8rHCs8KVc0JS0tzVL9ct4XYedJukskYVWTo49tNiMEK9C2HTyarbNiT/RVIRSY82vH+6sTg==
+
+"@babel/helper-validator-identifier@^7.14.0":
+  version "7.14.0"
+  resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288"
+  integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==
+
+"@babel/parser@^7.12.0", "@babel/parser@^7.13.9":
+  version "7.14.4"
+  resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.14.4.tgz#a5c560d6db6cd8e6ed342368dea8039232cbab18"
+  integrity sha512-ArliyUsWDUqEGfWcmzpGUzNfLxTdTp6WU4IuP6QFSp9gGfWS6boxFCkJSJ/L4+RG8z/FnIU3WxCk6hPL9SSWeA==
+
+"@babel/types@^7.12.0", "@babel/types@^7.13.0":
+  version "7.14.4"
+  resolved "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz#bfd6980108168593b38b3eb48a24aa026b919bc0"
+  integrity sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==
+  dependencies:
+    "@babel/helper-validator-identifier" "^7.14.0"
+    to-fast-properties "^2.0.0"
+
+"@docsearch/css@^1.0.0-alpha.28":
+  version "1.0.0-alpha.28"
+  resolved "https://registry.npmjs.org/@docsearch/css/-/css-1.0.0-alpha.28.tgz#c8a2cd8c1bb3a6855c51892e9dbdab5d42fe6e23"
+  integrity sha512-1AhRzVdAkrWwhaxTX6/R7SnFHz8yLz1W8I/AldlTrfbNvZs9INk1FZiEFTJdgHaP68nhgQNWSGlQiDiI3y2RYg==
+
+"@docsearch/js@^1.0.0-alpha.28":
+  version "1.0.0-alpha.28"
+  resolved "https://registry.npmjs.org/@docsearch/js/-/js-1.0.0-alpha.28.tgz#f0fde7b8a6b1e1d8a7ae1e7655c43d959b457b2b"
+  integrity sha512-2g7aPhBy7FoEyeZW2G3LYHWVa8CFvqyozEz8PXt3hyywdFcmEIqmoCRwn8kboVftrOKCjtPcuLCewsaBoB3uiw==
+  dependencies:
+    "@docsearch/react" "^1.0.0-alpha.28"
+    preact "^10.0.0"
+
+"@docsearch/react@^1.0.0-alpha.28":
+  version "1.0.0-alpha.28"
+  resolved "https://registry.npmjs.org/@docsearch/react/-/react-1.0.0-alpha.28.tgz#4f039ed79f8b3332b19a57677b219aebc5010e9d"
+  integrity sha512-XjJOnCBXn+UZmtuDmgzlVIHnnvh6yHVwG4aFq8AXN6xJEIX3f180FvGaowFWAxgdtHplJxFGux0Xx4piHqBzIw==
+  dependencies:
+    "@docsearch/css" "^1.0.0-alpha.28"
+    "@francoischalifour/autocomplete-core" "^1.0.0-alpha.28"
+    "@francoischalifour/autocomplete-preset-algolia" "^1.0.0-alpha.28"
+    algoliasearch "^4.0.0"
+
+"@francoischalifour/autocomplete-core@^1.0.0-alpha.28":
+  version "1.0.0-alpha.28"
+  resolved "https://registry.npmjs.org/@francoischalifour/autocomplete-core/-/autocomplete-core-1.0.0-alpha.28.tgz#6b9d8491288e77f831e9b345d461623b0d3f5005"
+  integrity sha512-rL9x+72btViw+9icfBKUJjZj87FgjFrD2esuTUqtj4RAX3s4AuVZiN8XEsfjQBSc6qJk31cxlvqZHC/BIyYXgg==
+
+"@francoischalifour/autocomplete-preset-algolia@^1.0.0-alpha.28":
+  version "1.0.0-alpha.28"
+  resolved "https://registry.npmjs.org/@francoischalifour/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.0.0-alpha.28.tgz#a5ad7996f42e43e4acbb4e0010d663746d0e9997"
+  integrity sha512-bprfNmYt1opFUFEtD2XfY/kEsm13bzHQgU80uMjhuK0DJ914IjolT1GytpkdM6tJ4MBvyiJPP+bTtWO+BZ7c7w==
+
+"@iconify/json-tools@^1.0.10":
+  version "1.0.10"
+  resolved "https://registry.npmjs.org/@iconify/json-tools/-/json-tools-1.0.10.tgz#d9a7050dbbe8bb29d684d4b3f9446ed2d0bea3cc"
+  integrity sha512-LFelJDOLZ6JHlmlAkgrvmcu4hpNPB91KYcr4f60D/exzU1eNOb4/KCVHIydGHIQFaOacIOD+Xy+B7P1z812cZg==
+
+"@iconify/json@^1.1.362":
+  version "1.1.362"
+  resolved "https://registry.npmjs.org/@iconify/json/-/json-1.1.362.tgz#e104610f6341db0b5104794bb57959d41e5cea1b"
+  integrity sha512-oKU1KvmcLX/049RXi7FJsNgiodei7LhNetls3cv+oIkTUTIa5mi88oFfRj03B6c1Vja80ZLH+mSDLeTk1fMD5A==
+
+"@nodelib/fs.scandir@2.1.4":
+  version "2.1.4"
+  resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69"
+  integrity sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==
+  dependencies:
+    "@nodelib/fs.stat" "2.0.4"
+    run-parallel "^1.1.9"
+
+"@nodelib/fs.stat@2.0.4", "@nodelib/fs.stat@^2.0.2":
+  version "2.0.4"
+  resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz#a3f2dd61bab43b8db8fa108a121cfffe4c676655"
+  integrity sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==
+
+"@nodelib/fs.walk@^1.2.3":
+  version "1.2.6"
+  resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz#cce9396b30aa5afe9e3756608f5831adcb53d063"
+  integrity sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==
+  dependencies:
+    "@nodelib/fs.scandir" "2.1.4"
+    fastq "^1.6.0"
+
+"@polka/url@^0.5.0":
+  version "0.5.0"
+  resolved "https://registry.npmjs.org/@polka/url/-/url-0.5.0.tgz#b21510597fd601e5d7c95008b76bf0d254ebfd31"
+  integrity sha512-oZLYFEAzUKyi3SKnXvj32ZCEGH6RDnao7COuCVhDydMS9NrCSVXhM79VaKyP5+Zc33m0QXEd2DN3UkU7OsHcfw==
+
+"@polka/url@^1.0.0-next.15":
+  version "1.0.0-next.15"
+  resolved "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.15.tgz#6a9d143f7f4f49db2d782f9e1c8839a29b43ae23"
+  integrity sha512-15spi3V28QdevleWBNXE4pIls3nFZmBbUGrW9IVPwiQczuSb9n76TCB4bsk8TSel+I1OkHEdPhu5QKMfY6rQHA==
+
+"@types/estree@^0.0.48":
+  version "0.0.48"
+  resolved "https://registry.npmjs.org/@types/estree/-/estree-0.0.48.tgz#18dc8091b285df90db2f25aa7d906cfc394b7f74"
+  integrity sha512-LfZwXoGUDo0C3me81HXgkBg5CTQYb6xzEl+fNmbO4JdRiSKQ8A0GD1OBBvKAIsbCUgoyAty7m99GqqMQe784ew==
+
+"@types/throttle-debounce@^2.1.0":
+  version "2.1.0"
+  resolved "https://registry.npmjs.org/@types/throttle-debounce/-/throttle-debounce-2.1.0.tgz#1c3df624bfc4b62f992d3012b84c56d41eab3776"
+  integrity sha512-5eQEtSCoESnh2FsiLTxE121IiE60hnMqcb435fShf4bpLRjEu1Eoekht23y6zXS9Ts3l+Szu3TARnTsA0GkOkQ==
+
+"@vitejs/plugin-vue@^1.2.3":
+  version "1.2.4"
+  resolved "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-1.2.4.tgz#a7aa6e6a31c556a8b781de730316deeecf7f56f2"
+  integrity sha512-D/3H9plevPQGgQGwmV6eecvOnooLTecPR63HPffVVWPEhbfvmtYLWgznzs456NBb2DItiRTCIa1yWxvGqC+I8A==
+
+"@vue/compiler-core@3.1.2":
+  version "3.1.2"
+  resolved "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.1.2.tgz#31ab1d88e1706a5c7a545faeeb64c31bd0101db0"
+  integrity sha512-nHmq7vLjq/XM2IMbZUcKWoH5sPXa2uR/nIKZtjbK5F3TcbnYE/zKsrSUR9WZJ03unlwotNBX1OyxVt9HbWD7/Q==
+  dependencies:
+    "@babel/parser" "^7.12.0"
+    "@babel/types" "^7.12.0"
+    "@vue/shared" "3.1.2"
+    estree-walker "^2.0.1"
+    source-map "^0.6.1"
+
+"@vue/compiler-dom@3.1.2":
+  version "3.1.2"
+  resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.1.2.tgz#75a7731bcc5d9718183a3c56c18e992f7c13e7b1"
+  integrity sha512-k2+SWcWH0jL6WQAX7Or2ONqu5MbtTgTO0dJrvebQYzgqaKMXNI90RNeWeCxS4BnNFMDONpHBeFgbwbnDWIkmRg==
+  dependencies:
+    "@vue/compiler-core" "3.1.2"
+    "@vue/shared" "3.1.2"
+
+"@vue/compiler-sfc@^3.1.1":
+  version "3.1.2"
+  resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.1.2.tgz#23ff1e366d887b964899568bffcb11e3d0511fc4"
+  integrity sha512-SeG/2+DvwejQ7oAiSx8BrDh5qOdqCYHGClPiTvVIHTfSIHiS2JjMbCANdDCjHkTOh/O7WZzo2JhdKm98bRBxTw==
+  dependencies:
+    "@babel/parser" "^7.13.9"
+    "@babel/types" "^7.13.0"
+    "@types/estree" "^0.0.48"
+    "@vue/compiler-core" "3.1.2"
+    "@vue/compiler-dom" "3.1.2"
+    "@vue/compiler-ssr" "3.1.2"
+    "@vue/shared" "3.1.2"
+    consolidate "^0.16.0"
+    estree-walker "^2.0.1"
+    hash-sum "^2.0.0"
+    lru-cache "^5.1.1"
+    magic-string "^0.25.7"
+    merge-source-map "^1.1.0"
+    postcss "^8.1.10"
+    postcss-modules "^4.0.0"
+    postcss-selector-parser "^6.0.4"
+    source-map "^0.6.1"
+
+"@vue/compiler-ssr@3.1.2":
+  version "3.1.2"
+  resolved "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.1.2.tgz#e33ad0876d9b96f0950e22b0e174b94c1b049d2d"
+  integrity sha512-BwXo9LFk5OSWdMyZQ4bX1ELHX0Z/9F+ld/OaVnpUPzAZCHslBYLvyKUVDwv2C/lpLjRffpC2DOUEdl1+RP1aGg==
+  dependencies:
+    "@vue/compiler-dom" "3.1.2"
+    "@vue/shared" "3.1.2"
+
+"@vue/reactivity@3.1.2":
+  version "3.1.2"
+  resolved "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.2.tgz#66fa530dd726d2fef285ae55d02106a727db463b"
+  integrity sha512-glJzJoN2xE7I2lRvwKM5u1BHRPTd1yc8iaf//Lai/78/uYAvE5DXp5HzWRFOwMlbRvMGJHIQjOqoxj87cDAaag==
+  dependencies:
+    "@vue/shared" "3.1.2"
+
+"@vue/runtime-core@3.1.2":
+  version "3.1.2"
+  resolved "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.1.2.tgz#f4dbc503cfc9a02ab5f1ebe002c3322512064a54"
+  integrity sha512-gsPZG4dRIkixuuKmoj4P9IHgfT0yaFLcqWOM5F/bCk0nxQn1XtxH8oUehWuET726KhbukvDoJfe9G2CKviy80w==
+  dependencies:
+    "@vue/reactivity" "3.1.2"
+    "@vue/shared" "3.1.2"
+
+"@vue/runtime-dom@3.1.2":
+  version "3.1.2"
+  resolved "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.1.2.tgz#0fd8724f14bc7ba64b6c954d874a8d8a4fcb5fe9"
+  integrity sha512-QvINxjLucEZFzp5f0NVu7JqWYCv5TKQfkH2FDs/N6QNE4iKcYtKrWdT0HKfABnVXG28Znqv6rIH0dH4ZAOwxpA==
+  dependencies:
+    "@vue/runtime-core" "3.1.2"
+    "@vue/shared" "3.1.2"
+    csstype "^2.6.8"
+
+"@vue/server-renderer@^3.1.1":
+  version "3.1.2"
+  resolved "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.1.2.tgz#fd5c4ac433cbcea4f44b9ef971ff612786e1d04f"
+  integrity sha512-XDw8KTrz/siiU5p6Zlicvf2KIjSZrqaxATBPM/9FYNnyv4LTS14JC5daTL13rk50d3UPBurRR/3wJupVvtQJ4w==
+  dependencies:
+    "@vue/compiler-ssr" "3.1.2"
+    "@vue/shared" "3.1.2"
+
+"@vue/shared@3.1.2":
+  version "3.1.2"
+  resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.1.2.tgz#1069c0bc7d6f4bd15ccf3a5f3be29450aca368f9"
+  integrity sha512-EmH/poaDWBPJaPILXNI/1fvUbArJQmmTyVCwvvyDYDFnkPoTclAbHRAtyIvqfez7jybTDn077HTNILpxlsoWhg==
+
+"@vueuse/core@^5.0.3":
+  version "5.0.3"
+  resolved "https://registry.npmjs.org/@vueuse/core/-/core-5.0.3.tgz#8f3170e2a51ae62fb1725c84d4cc02a7552aad0b"
+  integrity sha512-TMCL11EVMaj2Y5qdYosvuwA+i1aKrerFXs7fhNZiQiLCWxF8XsrNdxzoiaI2n12UcmSOXvd1xdyWs7Nss+p/Hg==
+  dependencies:
+    "@vueuse/shared" "5.0.3"
+    vue-demi "*"
+
+"@vueuse/shared@5.0.3":
+  version "5.0.3"
+  resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-5.0.3.tgz#31613951d5036459650ad8d47a9185e8950ea3c9"
+  integrity sha512-aY93WPygr8H/4RB8YuOmAD83Y+faq7zwW10Kd9i0kD9zf5ysVP+32j09rF/mZVtGCa0CSM8ambPZMsEhCkRbwQ==
+  dependencies:
+    vue-demi "*"
+
+"@windicss/plugin-utils@1.1.1":
+  version "1.1.1"
+  resolved "https://registry.npmjs.org/@windicss/plugin-utils/-/plugin-utils-1.1.1.tgz#7f70952adc8d33f607706e434a153e2cdff52b64"
+  integrity sha512-niKEDyUpOfCGemFHopI9fxdWPpJQIZ/jmaU4spQXsGc1oEts164P8LUJPQmXc8C6vjKwkrH7KA+lxYNG5LmlDA==
+  dependencies:
+    "@antfu/utils" "^0.2.3"
+    debug "^4.3.2"
+    fast-glob "^3.2.5"
+    jiti "^1.10.1"
+    magic-string "^0.25.7"
+    micromatch "^4.0.4"
+    windicss "^3.1.3"
+
+accepts@~1.3.5:
+  version "1.3.7"
+  resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
+  integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==
+  dependencies:
+    mime-types "~2.1.24"
+    negotiator "0.6.2"
+
+algoliasearch@^4.0.0:
+  version "4.9.1"
+  resolved "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.9.1.tgz#1fa8ece3f9808e465226176b88b953801c2274e0"
+  integrity sha512-EeJUYXzBEhZSsL6tXc3hseLBCtlNLa1MZ4mlMK6EeX38yRjY5vgnFcNNml6uUhlOjvheKxgkKRpPWkxgL8Cqkg==
+  dependencies:
+    "@algolia/cache-browser-local-storage" "4.9.1"
+    "@algolia/cache-common" "4.9.1"
+    "@algolia/cache-in-memory" "4.9.1"
+    "@algolia/client-account" "4.9.1"
+    "@algolia/client-analytics" "4.9.1"
+    "@algolia/client-common" "4.9.1"
+    "@algolia/client-recommendation" "4.9.1"
+    "@algolia/client-search" "4.9.1"
+    "@algolia/logger-common" "4.9.1"
+    "@algolia/logger-console" "4.9.1"
+    "@algolia/requester-browser-xhr" "4.9.1"
+    "@algolia/requester-common" "4.9.1"
+    "@algolia/requester-node-http" "4.9.1"
+    "@algolia/transporter" "4.9.1"
+
+ansi-regex@^5.0.0:
+  version "5.0.1"
+  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
+  integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
+
+ansi-styles@^4.1.0:
+  version "4.3.0"
+  resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
+  integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
+  dependencies:
+    color-convert "^2.0.1"
+
+anymatch@~3.1.1:
+  version "3.1.2"
+  resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
+  integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==
+  dependencies:
+    normalize-path "^3.0.0"
+    picomatch "^2.0.4"
+
+argparse@^1.0.7:
+  version "1.0.10"
+  resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
+  integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
+  dependencies:
+    sprintf-js "~1.0.2"
+
+argparse@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
+  integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
+
+array-union@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
+  integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
+
+balanced-match@^1.0.0:
+  version "1.0.2"
+  resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
+  integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
+
+base64-js@^1.3.1:
+  version "1.5.1"
+  resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
+  integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
+
+big.js@^5.2.2:
+  version "5.2.2"
+  resolved "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
+  integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==
+
+binary-extensions@^2.0.0:
+  version "2.2.0"
+  resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
+  integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
+
+bl@^4.1.0:
+  version "4.1.0"
+  resolved "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
+  integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==
+  dependencies:
+    buffer "^5.5.0"
+    inherits "^2.0.4"
+    readable-stream "^3.4.0"
+
+bluebird@^3.7.2:
+  version "3.7.2"
+  resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
+  integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
+
+brace-expansion@^1.1.7:
+  version "1.1.11"
+  resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
+  integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
+  dependencies:
+    balanced-match "^1.0.0"
+    concat-map "0.0.1"
+
+braces@^3.0.1, braces@~3.0.2:
+  version "3.0.2"
+  resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
+  integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
+  dependencies:
+    fill-range "^7.0.1"
+
+buffer@^5.5.0:
+  version "5.7.1"
+  resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
+  integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
+  dependencies:
+    base64-js "^1.3.1"
+    ieee754 "^1.1.13"
+
+bytes@3.0.0:
+  version "3.0.0"
+  resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
+  integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=
+
+chalk@^4.1.0, chalk@^4.1.1:
+  version "4.1.1"
+  resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad"
+  integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==
+  dependencies:
+    ansi-styles "^4.1.0"
+    supports-color "^7.1.0"
+
+chokidar@^3.5.1:
+  version "3.5.1"
+  resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a"
+  integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==
+  dependencies:
+    anymatch "~3.1.1"
+    braces "~3.0.2"
+    glob-parent "~5.1.0"
+    is-binary-path "~2.1.0"
+    is-glob "~4.0.1"
+    normalize-path "~3.0.0"
+    readdirp "~3.5.0"
+  optionalDependencies:
+    fsevents "~2.3.1"
+
+cli-cursor@^3.1.0:
+  version "3.1.0"
+  resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307"
+  integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==
+  dependencies:
+    restore-cursor "^3.1.0"
+
+cli-spinners@^2.5.0:
+  version "2.6.0"
+  resolved "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.0.tgz#36c7dc98fb6a9a76bd6238ec3f77e2425627e939"
+  integrity sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==
+
+clone@^1.0.2:
+  version "1.0.4"
+  resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
+  integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
+
+color-convert@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
+  integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
+  dependencies:
+    color-name "~1.1.4"
+
+color-name@~1.1.4:
+  version "1.1.4"
+  resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
+  integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
+
+colorette@^1.2.2:
+  version "1.2.2"
+  resolved "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94"
+  integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==
+
+compressible@~2.0.16:
+  version "2.0.18"
+  resolved "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba"
+  integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==
+  dependencies:
+    mime-db ">= 1.43.0 < 2"
+
+compression@^1.7.4:
+  version "1.7.4"
+  resolved "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f"
+  integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==
+  dependencies:
+    accepts "~1.3.5"
+    bytes "3.0.0"
+    compressible "~2.0.16"
+    debug "2.6.9"
+    on-headers "~1.0.2"
+    safe-buffer "5.1.2"
+    vary "~1.1.2"
+
+concat-map@0.0.1:
+  version "0.0.1"
+  resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
+  integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
+
+consolidate@^0.16.0:
+  version "0.16.0"
+  resolved "https://registry.npmjs.org/consolidate/-/consolidate-0.16.0.tgz#a11864768930f2f19431660a65906668f5fbdc16"
+  integrity sha512-Nhl1wzCslqXYTJVDyJCu3ODohy9OfBMB5uD2BiBTzd7w+QY0lBzafkR8y8755yMYHAaMD4NuzbAw03/xzfw+eQ==
+  dependencies:
+    bluebird "^3.7.2"
+
+cssesc@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
+  integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
+
+csstype@^2.6.8:
+  version "2.6.17"
+  resolved "https://registry.npmjs.org/csstype/-/csstype-2.6.17.tgz#4cf30eb87e1d1a005d8b6510f95292413f6a1c0e"
+  integrity sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A==
+
+debug@2.6.9:
+  version "2.6.9"
+  resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
+  integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
+  dependencies:
+    ms "2.0.0"
+
+debug@^4.3.2:
+  version "4.3.2"
+  resolved "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b"
+  integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==
+  dependencies:
+    ms "2.1.2"
+
+defaults@^1.0.3:
+  version "1.0.3"
+  resolved "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d"
+  integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=
+  dependencies:
+    clone "^1.0.2"
+
+diacritics@^1.3.0:
+  version "1.3.0"
+  resolved "https://registry.npmjs.org/diacritics/-/diacritics-1.3.0.tgz#3efa87323ebb863e6696cebb0082d48ff3d6f7a1"
+  integrity sha1-PvqHMj67hj5mls67AILUj/PW96E=
+
+dir-glob@^3.0.1:
+  version "3.0.1"
+  resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
+  integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==
+  dependencies:
+    path-type "^4.0.0"
+
+emojis-list@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78"
+  integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==
+
+entities@~2.1.0:
+  version "2.1.0"
+  resolved "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5"
+  integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==
+
+esbuild@^0.12.8:
+  version "0.12.11"
+  resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.12.11.tgz#ab24f78cabf481e7dc747e7db15f9c5091beaa14"
+  integrity sha512-h83GwI6lYOrnSv5hSY2i2XZ191v3haj2IGDzwrkfWHhuO/kVMX3RYjhwRNG9E5VSxVLPaUjTVwrv8HWLvhk2nQ==
+
+escape-html@^1.0.3:
+  version "1.0.3"
+  resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
+  integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
+
+esprima@^4.0.0:
+  version "4.0.1"
+  resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
+  integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
+
+estree-walker@^2.0.1:
+  version "2.0.2"
+  resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
+  integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
+
+extend-shallow@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f"
+  integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=
+  dependencies:
+    is-extendable "^0.1.0"
+
+fast-glob@^3.1.1, fast-glob@^3.2.5:
+  version "3.2.5"
+  resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661"
+  integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==
+  dependencies:
+    "@nodelib/fs.stat" "^2.0.2"
+    "@nodelib/fs.walk" "^1.2.3"
+    glob-parent "^5.1.0"
+    merge2 "^1.3.0"
+    micromatch "^4.0.2"
+    picomatch "^2.2.1"
+
+fastq@^1.6.0:
+  version "1.11.0"
+  resolved "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858"
+  integrity sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==
+  dependencies:
+    reusify "^1.0.4"
+
+fill-range@^7.0.1:
+  version "7.0.1"
+  resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
+  integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
+  dependencies:
+    to-regex-range "^5.0.1"
+
+fs-extra@^10.0.0:
+  version "10.0.0"
+  resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1"
+  integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==
+  dependencies:
+    graceful-fs "^4.2.0"
+    jsonfile "^6.0.1"
+    universalify "^2.0.0"
+
+fsevents@~2.3.1, fsevents@~2.3.2:
+  version "2.3.2"
+  resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
+  integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
+
+function-bind@^1.1.1:
+  version "1.1.1"
+  resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
+  integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
+
+generic-names@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.npmjs.org/generic-names/-/generic-names-2.0.1.tgz#f8a378ead2ccaa7a34f0317b05554832ae41b872"
+  integrity sha512-kPCHWa1m9wGG/OwQpeweTwM/PYiQLrUIxXbt/P4Nic3LbGjCP0YwrALHW1uNLKZ0LIMg+RF+XRlj2ekT9ZlZAQ==
+  dependencies:
+    loader-utils "^1.1.0"
+
+glob-parent@^5.1.0, glob-parent@~5.1.0:
+  version "5.1.2"
+  resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
+  integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
+  dependencies:
+    is-glob "^4.0.1"
+
+globby@^11.0.3:
+  version "11.0.3"
+  resolved "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb"
+  integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==
+  dependencies:
+    array-union "^2.1.0"
+    dir-glob "^3.0.1"
+    fast-glob "^3.1.1"
+    ignore "^5.1.4"
+    merge2 "^1.3.0"
+    slash "^3.0.0"
+
+graceful-fs@^4.1.6, graceful-fs@^4.2.0:
+  version "4.2.6"
+  resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
+  integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
+
+gray-matter@^4.0.3:
+  version "4.0.3"
+  resolved "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz#e893c064825de73ea1f5f7d88c7a9f7274288798"
+  integrity sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==
+  dependencies:
+    js-yaml "^3.13.1"
+    kind-of "^6.0.2"
+    section-matter "^1.0.0"
+    strip-bom-string "^1.0.0"
+
+has-flag@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
+  integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
+
+has@^1.0.3:
+  version "1.0.3"
+  resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
+  integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
+  dependencies:
+    function-bind "^1.1.1"
+
+hash-sum@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz#81d01bb5de8ea4a214ad5d6ead1b523460b0b45a"
+  integrity sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==
+
+icss-replace-symbols@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded"
+  integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=
+
+icss-utils@^5.0.0:
+  version "5.1.0"
+  resolved "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae"
+  integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==
+
+ieee754@^1.1.13:
+  version "1.2.1"
+  resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
+  integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
+
+ignore@^5.1.4:
+  version "5.1.8"
+  resolved "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57"
+  integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==
+
+inherits@^2.0.3, inherits@^2.0.4:
+  version "2.0.4"
+  resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
+  integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
+
+is-binary-path@~2.1.0:
+  version "2.1.0"
+  resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
+  integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
+  dependencies:
+    binary-extensions "^2.0.0"
+
+is-core-module@^2.2.0:
+  version "2.4.0"
+  resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1"
+  integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==
+  dependencies:
+    has "^1.0.3"
+
+is-extendable@^0.1.0:
+  version "0.1.1"
+  resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
+  integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=
+
+is-extglob@^2.1.1:
+  version "2.1.1"
+  resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
+  integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
+
+is-glob@^4.0.1, is-glob@~4.0.1:
+  version "4.0.1"
+  resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc"
+  integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==
+  dependencies:
+    is-extglob "^2.1.1"
+
+is-interactive@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e"
+  integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==
+
+is-number@^7.0.0:
+  version "7.0.0"
+  resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
+  integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
+
+is-unicode-supported@^0.1.0:
+  version "0.1.0"
+  resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7"
+  integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==
+
+jiti@^1.10.1:
+  version "1.10.1"
+  resolved "https://registry.npmjs.org/jiti/-/jiti-1.10.1.tgz#bc2a175b9435274dc8659d3d9a121a91c6b3a1af"
+  integrity sha512-qux9juDtAC8HlZxAk/fku73ak4TWNLigRFTNzFShE/kw4bXVFsVu538vLXAxvNyPszXgpX4YxkXfwTYEi+zf5A==
+
+js-yaml@^3.13.1:
+  version "3.14.1"
+  resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537"
+  integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==
+  dependencies:
+    argparse "^1.0.7"
+    esprima "^4.0.0"
+
+json5@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"
+  integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==
+  dependencies:
+    minimist "^1.2.0"
+
+jsonfile@^6.0.1:
+  version "6.1.0"
+  resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
+  integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==
+  dependencies:
+    universalify "^2.0.0"
+  optionalDependencies:
+    graceful-fs "^4.1.6"
+
+kind-of@^6.0.0, kind-of@^6.0.2:
+  version "6.0.3"
+  resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
+  integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
+
+linkify-it@^3.0.1:
+  version "3.0.2"
+  resolved "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.2.tgz#f55eeb8bc1d3ae754049e124ab3bb56d97797fb8"
+  integrity sha512-gDBO4aHNZS6coiZCKVhSNh43F9ioIL4JwRjLZPkoLIY4yZFwg264Y5lu2x6rb1Js42Gh6Yqm2f6L2AJcnkzinQ==
+  dependencies:
+    uc.micro "^1.0.1"
+
+loader-utils@^1.1.0:
+  version "1.4.0"
+  resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613"
+  integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==
+  dependencies:
+    big.js "^5.2.2"
+    emojis-list "^3.0.0"
+    json5 "^1.0.1"
+
+lodash.camelcase@^4.3.0:
+  version "4.3.0"
+  resolved "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
+  integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY=
+
+log-symbols@^4.1.0:
+  version "4.1.0"
+  resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503"
+  integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==
+  dependencies:
+    chalk "^4.1.0"
+    is-unicode-supported "^0.1.0"
+
+lru-cache@^5.1.1:
+  version "5.1.1"
+  resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"
+  integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==
+  dependencies:
+    yallist "^3.0.2"
+
+lru-cache@^6.0.0:
+  version "6.0.0"
+  resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
+  integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
+  dependencies:
+    yallist "^4.0.0"
+
+magic-string@^0.25.7:
+  version "0.25.7"
+  resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051"
+  integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==
+  dependencies:
+    sourcemap-codec "^1.4.4"
+
+markdown-it-anchor@^7.1.0:
+  version "7.1.0"
+  resolved "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-7.1.0.tgz#30fb21497bf59e83ff4d1ddc052d821962e2489e"
+  integrity sha512-loQggrwsIkkP7TOrESvmYkV2ikbQNNKhHcWyqC7/C2CmfHl1tkUizJJU8C5aGgg7J6oXVQJx17gk7i47tNn/lQ==
+
+markdown-it-container@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.npmjs.org/markdown-it-container/-/markdown-it-container-3.0.0.tgz#1d19b06040a020f9a827577bb7dbf67aa5de9a5b"
+  integrity sha512-y6oKTq4BB9OQuY/KLfk/O3ysFhB3IMYoIWhGJEidXt1NQFocFK2sA2t0NYZAMyMShAGL6x5OPIbrmXPIqaN9rw==
+
+markdown-it-emoji@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-2.0.0.tgz#3164ad4c009efd946e98274f7562ad611089a231"
+  integrity sha512-39j7/9vP/CPCKbEI44oV8yoPJTpvfeReTn/COgRhSpNrjWF3PfP/JUxxB0hxV6ynOY8KH8Y8aX9NMDdo6z+6YQ==
+
+markdown-it-table-of-contents@^0.5.2:
+  version "0.5.2"
+  resolved "https://registry.npmjs.org/markdown-it-table-of-contents/-/markdown-it-table-of-contents-0.5.2.tgz#2f941d386c277887910f2c7a8a16f5a17acb829c"
+  integrity sha512-6o+rxSwzXmXCUn1n8QGTSpgbcnHBG6lUU8x7A5Cssuq5vbfzTfitfGPvQ5PZkp+gP1NGS/DR2rkYqJPn0rbZ1A==
+
+markdown-it@^12.0.6:
+  version "12.0.6"
+  resolved "https://registry.npmjs.org/markdown-it/-/markdown-it-12.0.6.tgz#adcc8e5fe020af292ccbdf161fe84f1961516138"
+  integrity sha512-qv3sVLl4lMT96LLtR7xeRJX11OUFjsaD5oVat2/SNBIb21bJXwal2+SklcRbTwGwqWpWH/HRtYavOoJE+seL8w==
+  dependencies:
+    argparse "^2.0.1"
+    entities "~2.1.0"
+    linkify-it "^3.0.1"
+    mdurl "^1.0.1"
+    uc.micro "^1.0.5"
+
+matchit@^1.0.0:
+  version "1.1.0"
+  resolved "https://registry.npmjs.org/matchit/-/matchit-1.1.0.tgz#c4ccf17d9c824cc1301edbcffde9b75a61d10a7c"
+  integrity sha512-+nGYoOlfHmxe5BW5tE0EMJppXEwdSf8uBA1GTZC7Q77kbT35+VKLYJMzVNWCHSsga1ps1tPYFtFyvxvKzWVmMA==
+  dependencies:
+    "@arr/every" "^1.0.0"
+
+mdurl@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
+  integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=
+
+merge-source-map@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646"
+  integrity sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==
+  dependencies:
+    source-map "^0.6.1"
+
+merge2@^1.3.0:
+  version "1.4.1"
+  resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
+  integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
+
+micromatch@^4.0.2, micromatch@^4.0.4:
+  version "4.0.4"
+  resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
+  integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
+  dependencies:
+    braces "^3.0.1"
+    picomatch "^2.2.3"
+
+mime-db@1.48.0, "mime-db@>= 1.43.0 < 2":
+  version "1.48.0"
+  resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz#e35b31045dd7eada3aaad537ed88a33afbef2d1d"
+  integrity sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==
+
+mime-types@~2.1.24:
+  version "2.1.31"
+  resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz#a00d76b74317c61f9c2db2218b8e9f8e9c5c9e6b"
+  integrity sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==
+  dependencies:
+    mime-db "1.48.0"
+
+mime@^2.3.1:
+  version "2.5.2"
+  resolved "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe"
+  integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==
+
+mimic-fn@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
+  integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
+
+minimatch@^3.0.4:
+  version "3.0.4"
+  resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
+  integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
+  dependencies:
+    brace-expansion "^1.1.7"
+
+minimist@^1.2.0, minimist@^1.2.5:
+  version "1.2.5"
+  resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
+  integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
+
+ms@2.0.0:
+  version "2.0.0"
+  resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
+  integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
+
+ms@2.1.2:
+  version "2.1.2"
+  resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
+  integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
+
+nanoid@^3.1.23:
+  version "3.1.23"
+  resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81"
+  integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==
+
+negotiator@0.6.2:
+  version "0.6.2"
+  resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
+  integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==
+
+normalize-path@^3.0.0, normalize-path@~3.0.0:
+  version "3.0.0"
+  resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
+  integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
+
+on-headers@~1.0.2:
+  version "1.0.2"
+  resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f"
+  integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==
+
+onetime@^5.1.0:
+  version "5.1.2"
+  resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e"
+  integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==
+  dependencies:
+    mimic-fn "^2.1.0"
+
+ora@^5.4.0:
+  version "5.4.0"
+  resolved "https://registry.npmjs.org/ora/-/ora-5.4.0.tgz#42eda4855835b9cd14d33864c97a3c95a3f56bf4"
+  integrity sha512-1StwyXQGoU6gdjYkyVcqOLnVlbKj+6yPNNOxJVgpt9t4eksKjiriiHuxktLYkgllwk+D6MbC4ihH84L1udRXPg==
+  dependencies:
+    bl "^4.1.0"
+    chalk "^4.1.0"
+    cli-cursor "^3.1.0"
+    cli-spinners "^2.5.0"
+    is-interactive "^1.0.0"
+    is-unicode-supported "^0.1.0"
+    log-symbols "^4.1.0"
+    strip-ansi "^6.0.0"
+    wcwidth "^1.0.1"
+
+path-parse@^1.0.6:
+  version "1.0.7"
+  resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
+  integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
+
+path-type@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
+  integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
+
+picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3:
+  version "2.3.0"
+  resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
+  integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
+
+polka@^0.5.2:
+  version "0.5.2"
+  resolved "https://registry.npmjs.org/polka/-/polka-0.5.2.tgz#588bee0c5806dbc6c64958de3a1251860e9f2e26"
+  integrity sha512-FVg3vDmCqP80tOrs+OeNlgXYmFppTXdjD5E7I4ET1NjvtNmQrb1/mJibybKkb/d4NA7YWAr1ojxuhpL3FHqdlw==
+  dependencies:
+    "@polka/url" "^0.5.0"
+    trouter "^2.0.1"
+
+postcss-modules-extract-imports@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d"
+  integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==
+
+postcss-modules-local-by-default@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c"
+  integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==
+  dependencies:
+    icss-utils "^5.0.0"
+    postcss-selector-parser "^6.0.2"
+    postcss-value-parser "^4.1.0"
+
+postcss-modules-scope@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06"
+  integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==
+  dependencies:
+    postcss-selector-parser "^6.0.4"
+
+postcss-modules-values@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c"
+  integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==
+  dependencies:
+    icss-utils "^5.0.0"
+
+postcss-modules@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.npmjs.org/postcss-modules/-/postcss-modules-4.0.0.tgz#2bc7f276ab88f3f1b0fadf6cbd7772d43b5f3b9b"
+  integrity sha512-ghS/ovDzDqARm4Zj6L2ntadjyQMoyJmi0JkLlYtH2QFLrvNlxH5OAVRPWPeKilB0pY7SbuhO173KOWkPAxRJcw==
+  dependencies:
+    generic-names "^2.0.1"
+    icss-replace-symbols "^1.1.0"
+    lodash.camelcase "^4.3.0"
+    postcss-modules-extract-imports "^3.0.0"
+    postcss-modules-local-by-default "^4.0.0"
+    postcss-modules-scope "^3.0.0"
+    postcss-modules-values "^4.0.0"
+    string-hash "^1.1.1"
+
+postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4:
+  version "6.0.6"
+  resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea"
+  integrity sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==
+  dependencies:
+    cssesc "^3.0.0"
+    util-deprecate "^1.0.2"
+
+postcss-value-parser@^4.1.0:
+  version "4.1.0"
+  resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb"
+  integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==
+
+postcss@^8.1.10:
+  version "8.3.0"
+  resolved "https://registry.npmjs.org/postcss/-/postcss-8.3.0.tgz#b1a713f6172ca427e3f05ef1303de8b65683325f"
+  integrity sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ==
+  dependencies:
+    colorette "^1.2.2"
+    nanoid "^3.1.23"
+    source-map-js "^0.6.2"
+
+postcss@^8.3.4:
+  version "8.3.5"
+  resolved "https://registry.npmjs.org/postcss/-/postcss-8.3.5.tgz#982216b113412bc20a86289e91eb994952a5b709"
+  integrity sha512-NxTuJocUhYGsMiMFHDUkmjSKT3EdH4/WbGF6GCi1NDGk+vbcUTun4fpbOqaPtD8IIsztA2ilZm2DhYCuyN58gA==
+  dependencies:
+    colorette "^1.2.2"
+    nanoid "^3.1.23"
+    source-map-js "^0.6.2"
+
+preact@^10.0.0:
+  version "10.5.13"
+  resolved "https://registry.npmjs.org/preact/-/preact-10.5.13.tgz#85f6c9197ecd736ce8e3bec044d08fd1330fa019"
+  integrity sha512-q/vlKIGNwzTLu+jCcvywgGrt+H/1P/oIRSD6mV4ln3hmlC+Aa34C7yfPI4+5bzW8pONyVXYS7SvXosy2dKKtWQ==
+
+prettier@^2.3.2:
+  version "2.3.2"
+  resolved "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d"
+  integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==
+
+prismjs@^1.23.0:
+  version "1.25.0"
+  resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.25.0.tgz#6f822df1bdad965734b310b315a23315cf999756"
+  integrity sha512-WCjJHl1KEWbnkQom1+SzftbtXMKQoezOCYs5rECqMN+jP+apI7ftoflyqigqzopSO3hMhTEb0mFClA8lkolgEg==
+
+queue-microtask@^1.2.2:
+  version "1.2.3"
+  resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
+  integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
+
+readable-stream@^3.4.0:
+  version "3.6.0"
+  resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
+  integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
+  dependencies:
+    inherits "^2.0.3"
+    string_decoder "^1.1.1"
+    util-deprecate "^1.0.1"
+
+readdirp@~3.5.0:
+  version "3.5.0"
+  resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e"
+  integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==
+  dependencies:
+    picomatch "^2.2.1"
+
+resolve@^1.20.0:
+  version "1.20.0"
+  resolved "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
+  integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
+  dependencies:
+    is-core-module "^2.2.0"
+    path-parse "^1.0.6"
+
+restore-cursor@^3.1.0:
+  version "3.1.0"
+  resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e"
+  integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==
+  dependencies:
+    onetime "^5.1.0"
+    signal-exit "^3.0.2"
+
+reusify@^1.0.4:
+  version "1.0.4"
+  resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
+  integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
+
+rollup@^2.38.5:
+  version "2.50.5"
+  resolved "https://registry.npmjs.org/rollup/-/rollup-2.50.5.tgz#bbee9d6411af3f5fa5c6e7e2c69f7a65b753e568"
+  integrity sha512-Ztz4NurU2LbS3Jn5rlhnYv35z6pkjBUmYKr94fOBIKINKRO6kug9NTFHArT7jqwMP2kqEZ39jJuEtkk91NBltQ==
+  optionalDependencies:
+    fsevents "~2.3.1"
+
+run-parallel@^1.1.9:
+  version "1.2.0"
+  resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
+  integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==
+  dependencies:
+    queue-microtask "^1.2.2"
+
+safe-buffer@5.1.2:
+  version "5.1.2"
+  resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
+  integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
+
+safe-buffer@~5.2.0:
+  version "5.2.1"
+  resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
+  integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
+
+section-matter@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz#e9041953506780ec01d59f292a19c7b850b84167"
+  integrity sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==
+  dependencies:
+    extend-shallow "^2.0.1"
+    kind-of "^6.0.0"
+
+signal-exit@^3.0.2:
+  version "3.0.3"
+  resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
+  integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
+
+sirv@^1.0.12:
+  version "1.0.12"
+  resolved "https://registry.npmjs.org/sirv/-/sirv-1.0.12.tgz#d816c882b35489b3c63290e2f455ae3eccd5f652"
+  integrity sha512-+jQoCxndz7L2tqQL4ZyzfDhky0W/4ZJip3XoOuxyQWnAwMxindLl3Xv1qT4x1YX/re0leShvTm8Uk0kQspGhBg==
+  dependencies:
+    "@polka/url" "^1.0.0-next.15"
+    mime "^2.3.1"
+    totalist "^1.0.0"
+
+slash@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
+  integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
+
+source-map-js@^0.6.2:
+  version "0.6.2"
+  resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e"
+  integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==
+
+source-map@^0.6.1:
+  version "0.6.1"
+  resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
+  integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
+
+sourcemap-codec@^1.4.4:
+  version "1.4.8"
+  resolved "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
+  integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
+
+sprintf-js@~1.0.2:
+  version "1.0.3"
+  resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
+  integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
+
+string-hash@^1.1.1:
+  version "1.1.3"
+  resolved "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b"
+  integrity sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=
+
+string_decoder@^1.1.1:
+  version "1.3.0"
+  resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
+  integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
+  dependencies:
+    safe-buffer "~5.2.0"
+
+strip-ansi@^6.0.0:
+  version "6.0.0"
+  resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532"
+  integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==
+  dependencies:
+    ansi-regex "^5.0.0"
+
+strip-bom-string@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz#e5211e9224369fbb81d633a2f00044dc8cedad92"
+  integrity sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=
+
+supports-color@^7.1.0:
+  version "7.2.0"
+  resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
+  integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
+  dependencies:
+    has-flag "^4.0.0"
+
+to-fast-properties@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
+  integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
+
+to-regex-range@^5.0.1:
+  version "5.0.1"
+  resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
+  integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
+  dependencies:
+    is-number "^7.0.0"
+
+totalist@^1.0.0:
+  version "1.1.0"
+  resolved "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df"
+  integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==
+
+trouter@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.npmjs.org/trouter/-/trouter-2.0.1.tgz#2726a5f8558e090d24c3a393f09eaab1df232df6"
+  integrity sha512-kr8SKKw94OI+xTGOkfsvwZQ8mWoikZDd2n8XZHjJVZUARZT+4/VV6cacRS6CLsH9bNm+HFIPU1Zx4CnNnb4qlQ==
+  dependencies:
+    matchit "^1.0.0"
+
+uc.micro@^1.0.1, uc.micro@^1.0.5:
+  version "1.0.6"
+  resolved "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac"
+  integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==
+
+universalify@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
+  integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==
+
+util-deprecate@^1.0.1, util-deprecate@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
+  integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
+
+vary@~1.1.2:
+  version "1.1.2"
+  resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
+  integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
+
+vite-plugin-components@^0.10.4:
+  version "0.10.4"
+  resolved "https://registry.npmjs.org/vite-plugin-components/-/vite-plugin-components-0.10.4.tgz#55a2757433833a9481765319d76d69653ba9ba57"
+  integrity sha512-QOGd+7IE4EonPGMlxmudj0HadVxKzCdvaZmZcRgap4gE8F55sAIztuAQN4IHACEKuappWsB6XpMAY1iVrJUqog==
+  dependencies:
+    chokidar "^3.5.1"
+    debug "^4.3.2"
+    fast-glob "^3.2.5"
+    magic-string "^0.25.7"
+    minimatch "^3.0.4"
+
+vite-plugin-icons@^0.6.3:
+  version "0.6.3"
+  resolved "https://registry.npmjs.org/vite-plugin-icons/-/vite-plugin-icons-0.6.3.tgz#b60ee401e4f15187758de583de7a94f44c323701"
+  integrity sha512-h+DNh9xMBhISNBZ/broslVRk/DbgDXV71u2Ienoz8G0W81+tzbtPHsE6imnwqW93h0qtS1VnVyOQlqsKcheLtw==
+  dependencies:
+    "@iconify/json-tools" "^1.0.10"
+    vue-template-es2015-compiler "^1.9.1"
+
+vite-plugin-windicss@^1.1.1:
+  version "1.1.1"
+  resolved "https://registry.npmjs.org/vite-plugin-windicss/-/vite-plugin-windicss-1.1.1.tgz#c13d4c2d9fec4afae2eea5058f426c693255d02f"
+  integrity sha512-J1n3DoSg8BkQ42HDNzh+FqPhvBgCRgQ0Nvp2HLvb5FVl8FKEPw26Frc/oLaC1g9ypSlvkSM8011gHi+c+pxsRQ==
+  dependencies:
+    "@windicss/plugin-utils" "1.1.1"
+    chalk "^4.1.1"
+    debug "^4.3.2"
+    windicss "^3.1.3"
+
+vite@^2.3.7:
+  version "2.3.8"
+  resolved "https://registry.npmjs.org/vite/-/vite-2.3.8.tgz#42e3e03953859fd410e4e6ab3d1cca0aab2adc3c"
+  integrity sha512-QiEx+iqNnJntSgSF2fWRQvRey9pORIrtNJzNyBJXwc+BdzWs83FQolX84cTBo393cfhObrtWa6180dAa4NLDiQ==
+  dependencies:
+    esbuild "^0.12.8"
+    postcss "^8.3.4"
+    resolve "^1.20.0"
+    rollup "^2.38.5"
+  optionalDependencies:
+    fsevents "~2.3.2"
+
+vitepress@^0.14.1:
+  version "0.14.1"
+  resolved "https://registry.npmjs.org/vitepress/-/vitepress-0.14.1.tgz#0f431d3070b9a18938985be8078f27faf90ed5c6"
+  integrity sha512-cGsDULwKvKljtDNm4uy8zDYoM3gBRxr75R8+buzeyWnpXEqIwWICl0P2AHwLm2Dbs7cVy8lAREOrcUsShDzPuA==
+  dependencies:
+    "@docsearch/css" "^1.0.0-alpha.28"
+    "@docsearch/js" "^1.0.0-alpha.28"
+    "@vitejs/plugin-vue" "^1.2.3"
+    "@vue/compiler-sfc" "^3.1.1"
+    "@vue/server-renderer" "^3.1.1"
+    chalk "^4.1.1"
+    compression "^1.7.4"
+    debug "^4.3.2"
+    diacritics "^1.3.0"
+    escape-html "^1.0.3"
+    fs-extra "^10.0.0"
+    globby "^11.0.3"
+    gray-matter "^4.0.3"
+    lru-cache "^6.0.0"
+    markdown-it "^12.0.6"
+    markdown-it-anchor "^7.1.0"
+    markdown-it-container "^3.0.0"
+    markdown-it-emoji "^2.0.0"
+    markdown-it-table-of-contents "^0.5.2"
+    minimist "^1.2.5"
+    ora "^5.4.0"
+    polka "^0.5.2"
+    prismjs "^1.23.0"
+    sirv "^1.0.12"
+    vite "^2.3.7"
+    vue "^3.1.1"
+
+vue-demi@*:
+  version "0.9.1"
+  resolved "https://registry.npmjs.org/vue-demi/-/vue-demi-0.9.1.tgz#25d6e1ebd4d4010757ff3571e2bf6a1d7bf3de82"
+  integrity sha512-7s1lufRD2l369eFWPjgLvhqCRk0XzGWJsQc7K4q+0mZtixyGIvsK1Cg88P4NcaRIEiBuuN4q1NN4SZKFKwQswA==
+
+vue-template-es2015-compiler@^1.9.1:
+  version "1.9.1"
+  resolved "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825"
+  integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==
+
+vue@^3.1.1:
+  version "3.1.2"
+  resolved "https://registry.npmjs.org/vue/-/vue-3.1.2.tgz#647f8e3949a3d600771dca25d50225dc3e594c64"
+  integrity sha512-q/rbKpb7aofax4ugqu2k/uj7BYuNPcd6Z5/qJtfkJQsE0NkwVoCyeSh7IZGH61hChwYn3CEkh4bHolvUPxlQ+w==
+  dependencies:
+    "@vue/compiler-dom" "3.1.2"
+    "@vue/runtime-dom" "3.1.2"
+    "@vue/shared" "3.1.2"
+
+wcwidth@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8"
+  integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=
+  dependencies:
+    defaults "^1.0.3"
+
+windicss@^3.1.3:
+  version "3.1.3"
+  resolved "https://registry.npmjs.org/windicss/-/windicss-3.1.3.tgz#a4b80af48bdd5d4be13520f700b497af455df700"
+  integrity sha512-l7fpoba2LY9AYRy4UgcuOpbPsed8UsbpEQYUVWRR1wdAwiKxK6bGIMfpiKJtjPAPdh0GOGUqr6KJar0EDZSxzg==
+
+yallist@^3.0.2:
+  version "3.1.1"
+  resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
+  integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
+
+yallist@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
+  integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==