[
  {
    "path": ".idea/.gitignore",
    "content": "# 默认忽略的文件\n/shelf/\n/workspace.xml\n# 基于编辑器的 HTTP 客户端请求\n/httpRequests/\n"
  },
  {
    "path": ".idea/inspectionProfiles/Project_Default.xml",
    "content": "<component name=\"InspectionProjectProfileManager\">\n  <profile version=\"1.0\">\n    <option name=\"myName\" value=\"Project Default\" />\n    <inspection_tool class=\"Eslint\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\" />\n  </profile>\n</component>"
  },
  {
    "path": ".idea/modules.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectModuleManager\">\n    <modules>\n      <module fileurl=\"file://$PROJECT_DIR$/.idea/my-blog.iml\" filepath=\"$PROJECT_DIR$/.idea/my-blog.iml\" />\n    </modules>\n  </component>\n</project>"
  },
  {
    "path": ".idea/my-blog.iml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module type=\"WEB_MODULE\" version=\"4\">\n  <component name=\"NewModuleRootManager\">\n    <content url=\"file://$MODULE_DIR$\">\n      <excludeFolder url=\"file://$MODULE_DIR$/.tmp\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/temp\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/tmp\" />\n    </content>\n    <orderEntry type=\"inheritedJdk\" />\n    <orderEntry type=\"sourceFolder\" forTests=\"false\" />\n  </component>\n</module>"
  },
  {
    "path": ".idea/vcs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"VcsDirectoryMappings\">\n    <mapping directory=\"\" vcs=\"Git\" />\n  </component>\n</project>"
  },
  {
    "path": "Docker/Dockerfile",
    "content": "# 基于哪个镜像的基础上进行构建\n# FROM node:16\n# 工作目录\n# WORKDIR /\n# 拷贝当前目录下的文件 到 /app 中  .dockerignore 文件中可以声明忽略拷贝的文件\n# COPY  . /\n\n# RUN npm set registry  https://registry.npmmirror.com\n# RUN npm install\n# RUN npm run build\n\n# COPY warbler-fe:/dist/ /home/work/warbler-fe/warbler-fe/\n\n\n\n# 拉取 nginx 镜像\nFROM nginx\n\nCOPY dist /usr/share/nginx/html\n\nCOPY Docker/nginx/nginx.conf /etc/nginx/nginx.conf\n\nEXPOSE 80\n\nCMD [\"nginx\",\"-g\",\"daemon off;\"]\n\n\n# docker build -f ./Docker/Dockerfile -t warbler-fe . --no-cache\n# docker run -d --name warbler-fe-instance -p 80:80 --restart=always warbler-fe"
  },
  {
    "path": "Docker/nginx/nginx.conf",
    "content": "\r\n#user  nobody;\r\nworker_processes  1;\r\n\r\n#error_log  logs/error.log;\r\n#error_log  logs/error.log  notice;\r\n#error_log  logs/error.log  info;\r\n\r\n#pid        logs/nginx.pid;\r\n\r\n\r\nevents {\r\n    worker_connections  1024;\r\n}\r\n\r\n\r\nhttp {\r\n\r\n    gzip on;\t\t\t\t\t\t#开启gzip压缩功能\r\n    gzip_min_length 10k;\t\t\t#设置允许压缩的页面最小字节数; 这里表示如果文件小于10个字节，就不用压缩，因为没有意义，本来就很小.\r\n    gzip_buffers 4 16k;\t\t\t#设置压缩缓冲区大小，此处设置为4个16K内存作为压缩结果流缓存\r\n    gzip_http_version 1.1;\t\t\t#压缩版本\r\n    gzip_comp_level 6;\t\t\t#设置压缩比率，最小为1，处理速度快，传输速度慢；9为最大压缩比，处理速度慢，传输速度快; 这里表示压缩级别，可以是0到9中的任一个，级别越高，压缩就越小，节省了带宽资源，但同时也消耗CPU资源，所以一般折中为6\r\n    gzip_types text/css text/xml application/javascript;\t\t#制定压缩的类型,线上配置时尽可能配置多的压缩类型!\r\n    gzip_disable \"MSIE [1-6]\\.\";\t\t#配置禁用gzip条件，支持正则。此处表示ie6及以下不启用gzip（因为ie低版本不支持）\r\n    gzip_vary on;\t\t\t\t\t#选择支持vary header；改选项可以让前端的缓存服务器缓存经过gzip压缩的页面; 这个可以不写，表示在传送数据时，给客户端说明我使用了gzip压缩\r\n    include       mime.types;\r\n    default_type  application/octet-stream;\r\n    client_max_body_size 10m;\r\n\r\n    #log_format  main  '$remote_addr - $remote_user [$time_local] \"$request\" '\r\n    #                  '$status $body_bytes_sent \"$http_referer\" '\r\n    #                  '\"$http_user_agent\" \"$http_x_forwarded_for\"';\r\n\r\n    #access_log  logs/access.log  main;\r\n\r\n    sendfile        on;\r\n    #tcp_nopush     on;\r\n\r\n    #keepalive_timeout  0;\r\n    keepalive_timeout  65;\r\n\r\n    #gzip  on;\r\n\r\n    server {\r\n        listen       80;\r\n        server_name  www.yangtao.xyz; # 修改为docker服务宿主机的ip\r\n\r\n\r\n        location / {\r\n            root   /usr/share/nginx/html;\r\n            index  index.html;\r\n            try_files $uri $uri/ /index.html;\r\n         }\r\n\t    location @router {\r\n           rewrite ^.*$ /index.html last;\r\n        }\r\n        error_page   500 502 503 504  /50x.html;\r\n            location = /50x.html {\r\n            root   html;\r\n     }\r\n    }\r\n\r\n\r\n    # another virtual host using mix of IP-, name-, and port-based configuration\r\n    #\r\n    # server {\r\n    #    listen       80;\r\n    #    server_name  js.yangtao.top;\r\n    #    try_files $uri $uri/ /index.html;\r\n\r\n    #    location / {\r\n    #        root   /usr/share/nginx/js;\r\n    #        index  index.html index.htm;\r\n    #    }\r\n    # }\r\n\r\n    # server {\r\n    #    listen       80;\r\n    #    server_name  cli.yangtao.top;\r\n    #    try_files $uri $uri/ /index.html;\r\n\r\n    #    location / {\r\n    #        root   /usr/share/nginx/cli;\r\n    #        index  index.html index.htm;\r\n    #    }\r\n    # }\r\n\r\n\r\n    # HTTPS server\r\n    #\r\n    #server {\r\n    #    listen       443 ssl;\r\n    #    server_name  localhost;\r\n\r\n    #    ssl_certificate      cert.pem;\r\n    #    ssl_certificate_key  cert.key;\r\n\r\n    #    ssl_session_cache    shared:SSL:1m;\r\n    #    ssl_session_timeout  5m;\r\n\r\n    #    ssl_ciphers  HIGH:!aNULL:!MD5;\r\n    #    ssl_prefer_server_ciphers  on;\r\n\r\n    #    location / {\r\n    #        root   html;\r\n    #        index  index.html index.htm;\r\n    #    }\r\n    #}\r\n\r\n}\r\n\r\n\r\n"
  },
  {
    "path": "README.md",
    "content": "## 网站首页\n\n👉👉 [江城开朗的豌豆]([https://tinyurl.com/yangtaoWeb](https://yangtao.xyz/#/))\n\n## 开发者\n\n**江城开朗的豌豆**\n\n👉👉 [掘金](https://juejin.cn/user/3307789418773736)\n\n👉👉 [github](https://github.com/yangtao5201314)\n\n👉👉 [个人博客](https://blog.csdn.net/qq_48652579?type=lately)\n\n### 安装 yarn 并启动项目\n\n- 安装依赖\n\n```bash\nyarn install\n```\n\n- 运行项目\n\n```bash\nyarn run dev\n```\n- 打包项目\n\n```bash\nyarn run build\n```\n"
  },
  {
    "path": "commitlint.config.js",
    "content": "\nmodule.exports = {\n  extends: ['cz'],\n  rules: {\n    // 'type-empty': [2, 'never'],\n    // 'subject-empty': [2, 'never'],\n  },\n};\n"
  },
  {
    "path": "index.html",
    "content": "<!DOCTYPE html>\r\n<html lang=\"en\">\r\n\r\n<head>\r\n  <meta charset=\"UTF-8\" />\r\n  <link rel=\"icon\" type=\"image/svg+xml\" href=\"https://turbo.build/images/docs/repo/repo-hero-logo-dark.svg\" />\r\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\r\n  <title>江城开朗的豌豆 | 让前端再简单一点</title>\r\n  <!-- <style>\r\n    .audio {\r\n      position: absolute;\r\n      z-index: 10;\r\n      visibility: hidden;\r\n    }\r\n  </style> -->\r\n</head>\r\n\r\n<body>\r\n  <!-- <audio controls autoplay ref=\"audio\" class=\"audio\" playsinline loop>\r\n    <source src=\"https://img.tukuppt.com/newpreview_music/09/01/69/5c8a0553e18db46234.mp3\" type=\"audio/mpeg\" />\r\n  </audio> -->\r\n  <div id=\"app\"></div>\r\n  <div class=\"spinner-box\" id=\"spinner\">\r\n    <div class=\"spinner\"></div>\r\n  </div>\r\n  <script type=\"module\" src=\"/src/main.ts\"></script>\r\n</body>\r\n\r\n</html>"
  },
  {
    "path": "package.json",
    "content": "{\r\n  \"name\": \"myblog\",\r\n  \"private\": true,\r\n  \"version\": \"0.0.0\",\r\n  \"scripts\": {\r\n    \"dev\": \"vite --open --port 5173\",\r\n    \"build\": \"vue-tsc && vite build\",\r\n    \"preview\": \"vite preview\",\r\n    \"commit\": \"git-cz\",\r\n    \"commit:all\": \"git add . && git-cz\",\r\n    \"prepare\": \"husky install\"\r\n  },\r\n  \"dependencies\": {\r\n    \"axios\": \"^1.3.5\",\r\n    \"express\": \"^4.18.2\",\r\n    \"modern-normalize\": \"^1.1.0\",\r\n    \"vue\": \"^3.2.47\",\r\n    \"vue-router\": \"^4.1.6\"\r\n  },\r\n  \"repository\": {\r\n    \"type\": \"git\",\r\n    \"url\": \"git+https://github.com/yangtao5201314/my-blog\"\r\n  },\r\n  \"homepage\": \"https://tinyurl.com/yangtaoWeb\",\r\n  \"devDependencies\": {\r\n    \"@commitlint/config-conventional\": \"^17.4.4\",\r\n    \"@typescript-eslint/eslint-plugin\": \"^5.56.0\",\r\n    \"@typescript-eslint/parser\": \"^5.56.0\",\r\n    \"@vitejs/plugin-vue\": \"^4.1.0\",\r\n    \"commitizen\": \"^4.3.0\",\r\n    \"commitlint\": \"^17.4.4\",\r\n    \"commitlint-config-cz\": \"^0.13.3\",\r\n    \"cz-customizable\": \"^7.0.0\",\r\n    \"eslint\": \"^8.36.0\",\r\n    \"eslint-config-airbnb-base\": \"^15.0.0\",\r\n    \"eslint-plugin-import\": \"^2.27.5\",\r\n    \"eslint-plugin-vue\": \"^9.9.0\",\r\n    \"husky\": \"^8.0.3\",\r\n    \"lint-staged\": \"^13.2.0\",\r\n    \"sass\": \"^1.59.3\",\r\n    \"typescript\": \"*\",\r\n    \"vite\": \"^4.2.0\",\r\n    \"vue-eslint-parser\": \"^9.1.0\",\r\n    \"vue-tsc\": \"^1.2.0\"\r\n  },\r\n  \"lint-staged\": {\r\n    \"*.{js,jsx,ts,tsx,vue,json}\": [\r\n      \"eslint --fix\"\r\n    ]\r\n  },\r\n  \"config\": {\r\n    \"commitizen\": {\r\n      \"path\": \"node_modules/cz-customizable\"\r\n    }\r\n  }\r\n}\r\n"
  },
  {
    "path": "src/App.vue",
    "content": "<template>\n  \n  <nav-menu></nav-menu>\n  <router-view></router-view>\n\n</template>\n\n<script setup lang=\"ts\">\nimport NavMenu from '@c/nav-menu.vue';\nimport { onMounted } from 'vue';\n\nonMounted(() => {\n  // 页面渲染完成的时候把 loading 隐藏掉\n  const ele = document.getElementById('spinner');\n  ele!.style.display = 'none';\n\n});\n</script>\n\n<style lang=\"scss\" scoped>\n</style>\n"
  },
  {
    "path": "src/assets/iconfont/iconfont.css",
    "content": "@font-face {\n  font-family: \"iconfont\"; /* Project id 3948807 */\n  src: url('iconfont.woff2?t=1681302822777') format('woff2'),\n       url('iconfont.woff?t=1681302822777') format('woff'),\n       url('iconfont.ttf?t=1681302822777') format('truetype');\n}\n\n.iconfont {\n  font-family: \"iconfont\" !important;\n  font-size: 16px;\n  font-style: normal;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\n.icon-juejin:before {\n  content: \"\\e603\";\n}\n\n.icon-huaban88:before {\n  content: \"\\e61a\";\n}\n\n.icon-daohang:before {\n  content: \"\\e77d\";\n}\n\n.icon-jianli:before {\n  content: \"\\e609\";\n}\n\n.icon-weixin:before {\n  content: \"\\e600\";\n}\n\n"
  },
  {
    "path": "src/components/nav-menu.vue",
    "content": "\n<template>\n  <div class=\"nav-menu\">\n  \n    <div class=\"mask\"></div>\n    <div class=\"logo cp\" @click=\"goToHome\">\n      <div class=\"logo-img-box\">\n        <img src=\"https://turbo.build/images/docs/repo/repo-hero-logo-dark.svg\" class=\"logo-img\" />\n      </div>\n      <div class=\"logo-title fwb\">江城开朗的豌豆</div>\n    </div>\n    <div class=\"navs show-title\">\n      <div\n        v-for=\"(nav, index) in navs\"\n        :key=\"index\"\n        :class=\"{ active: index === currentIndex }\"\n        class=\"nav cp\"\n        @click=\"changeCurrentNab(nav.path)\">\n        {{ nav.title }}\n      </div>\n    </div>\n    <!-- 移动端 -->\n    <div class=\"navs show-icon\">\n      <div class=\"icon-bg\" title=\"前端导航\" @click=\"router.push({ path: '/navigation' })\">\n        <i class=\"iconfont icon-daohang\"></i>\n      </div>\n      <!-- <div class=\"icon-bg\" title=\"warbler-cli\" @click=\"router.push({ path: '/warbler/cli' })\">\n        <div>cli</div>\n      </div> -->\n      <div class=\"icon-bg\" title=\"yangtao-js\" @click=\"router.push({ path: '/warbler/js' })\">  \n        <div>js</div>\n      </div>\n      <div class=\"icon-bg\" title=\"江城开朗的豌豆\" @click=\"router.push({ path: '/warblerCenter' })\">\n        <i class=\"iconfont icon-jianli\"></i>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { useRouter, useRoute } from 'vue-router';\n\n// 导航列表\nconst navs = [\n  {\n    title: '前端导航',\n    path: '/navigation',\n  },\n  {\n    title: 'yangtao-js',\n    path: '/warbler/js',\n  },\n  // {\n  //   title: 'yangtao-cli',\n  //   path: '/warbler/cli',\n  // },\n  // {\n  //   title: '数据中心',\n  //   path: '/dataCenter',\n  // },\n  {\n    title: '江城开朗的豌豆',\n    path: '/warblerCenter',\n  },\n];\n\nconst router = useRouter();\nconst route = useRoute();\n\n// 点击 Tab 切换页面\nconst changeCurrentNab = (path: string) => {\n  router.push({ path });\n};\n// 回到首页\nconst goToHome = () => {\n  router.push({ path: '/' });\n};\n// 动态计算当前激活的导航，用来高亮当前导航\nconst currentIndex = computed(() => navs.findIndex((nav) => nav.path === route.path));\n\n  \n</script>\n\n<style lang=\"scss\" scoped>\n.nav-menu {\n  width: 100%;\n  height: var(--warbler-header-height);\n  position: fixed;\n  top: 0;\n\n  .show-title {\n    @media (max-width: 700px) {\n      display: none !important;\n    }\n  }\n  .show-icon {\n    @media (min-width: 700px) {\n      display: none !important;\n    }\n    .icon-bg {\n      width: 32px;\n      height: 32px;\n      font-size: 14px;\n      background-color: var(--warbler-bg-soft);\n      border-radius: 50%;\n      display: flex;\n      align-items: center;\n      justify-content: center;\n      margin-left: 4px;\n      cursor: pointer;\n    }\n  }\n  .mask {\n    width: 100%;\n    height: 100%;\n    background-color: var(--warbler-bg-half-opacity);\n    box-shadow: 0 -1px 0 hsla(0, 0%, 100%, 0.1) inset;\n    backdrop-filter: blur(12px);\n  }\n  .logo {\n    display: flex;\n    justify-content: flex-start;\n    align-items: center;\n    position: absolute;\n    top: 50%;\n    transform: translateY(-50%);\n    left: var(--page-padding);\n\n    .logo-img-box {\n      width: 32px;\n      height: 32px;\n    }\n    .logo-img {\n      width: 100%;\n      height: 100%;\n    }\n    .logo-title {\n      font-size: 24px;\n      margin-left: 8px;\n      background: linear-gradient(-60deg, #8700ff 0, #ff009e 100%);\n      background-clip: text;\n      -webkit-background-clip: text;\n      -webkit-text-fill-color: transparent;\n    }\n  }\n  .navs {\n    display: flex;\n    justify-content: flex-start;\n    position: absolute;\n    top: 50%;\n    transform: translateY(-50%);\n    right: var(--page-padding);\n    .nav {\n      margin-left: 16px;\n      &:hover {\n        color: var(--warbler-brand);\n      }\n    }\n    .active {\n      color: var(--warbler-brand);\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "src/main.ts",
    "content": "import { createApp } from 'vue';\nimport App from './App.vue';\nimport router from '@/router/index';\n\n// reset css\nimport 'modern-normalize';\nimport '@/style/style.css';\n\n// 阿里图标库\nimport './assets/iconfont/iconfont.css';\n\nconst app = createApp(App);\napp.use(router);\napp.mount('#app');\n\n\n"
  },
  {
    "path": "src/router/index.ts",
    "content": "import { createRouter, createWebHistory,createWebHashHistory } from 'vue-router';\n\nconst routes = [\n  {\n    path: '/',\n    name: 'homepage',\n    component: () => import(/* webpackChunkName: \"homepage\" */ '../views/homepage/index.vue'),\n    children: [],\n  },\n  {\n    path: '/navigation',\n    name: 'navigation',\n    component: () => import(/* webpackChunkName: \"navigation\" */ '@v/navigation/index.vue'),\n    children: [],\n  },\n  {\n    path: '/warbler/js',\n    name: 'warblerJS',\n    component: () => import(/* webpackChunkName: \"warblerJS\" */ '@v/warblerJs/index.vue'),\n    children: [],\n  },\n  {\n    path: '/warbler/cli',\n    name: 'warblerCli',\n    component: () => import(/* webpackChunkName: \"warblerCli\" */ '@v/warblerCli/index.vue'),\n    children: [],\n  },\n  {\n    path: '/dataCenter',\n    name: 'dataCenter',\n    component: () => import(/* webpackChunkName: \"dataCenter\" */ '@v/dataCenter/index.vue'),\n    children: [],\n  },\n  {\n    path: '/warblerCenter',\n    name: 'warblerCenter',\n    component: () => import(/* webpackChunkName: \"warblerCenter\" */ '@v/warblerCenter/index.vue'),\n    children: [],\n  },\n  {\n    path: '/contact',\n    name: 'contact',\n    component: () => import(/* webpackChunkName: \"contact\" */ '@v/contact/index.vue'),\n    children: [],\n  },\n];\n\nconst router = createRouter({\n  routes,\n  history: createWebHashHistory(),\n});\n\nexport default router;\n"
  },
  {
    "path": "src/style/style.css",
    "content": "html,\nbody,\n#app {\n  width: 100%;\n  height: 100%;\n  background-color: var(--warbler-bg);\n  font-family: var(--warbler-font-family-base);\n  font-size: 16px;\n  color: var(--warbler-text-2);\n}\n\n/* 阿里图标库初始化 */\n.icon {\n  width: 1em;\n  height: 1em;\n  vertical-align: -0.15em;\n  fill: currentColor;\n  overflow: hidden;\n}\n\n/* 基础颜色 */\n:root {\n  --warbler-white: #ffffff;\n  --warbler-black: #000000;\n  --warbler-black-half-opacity: RGBA(0, 0, 0, 0.5);\n  --warbler-brand: #646cff;\n  --warbler-brand-light: #747bff;\n  --warbler-brand-lighter: #9499ff;\n  --warbler-brand-lightest: #bcc0ff;\n  --warbler-brand-dark: #535bf2;\n  --warbler-brand-darker: #454ce1;\n  --warbler-brand-dimm: rgba(100, 108, 255, 0.08);\n}\n\n/* 页面两边的空白距离 */\n:root {\n  --page-padding: 32px;\n}\n\n@media (max-width: 900px) {\n  :root {\n    --page-padding: 16px;\n  }\n}\n\n/* 背景颜色 */\n:root {\n  --warbler-bg: #1e1e20;\n  --warbler-bg-soft: #161618;\n  --warbler-bg-half-opacity: RGBA(30, 30, 32, 0.5);\n}\n\n/* 高度 */\n:root {\n  --warbler-header-height: 64px;\n}\n\n/* 文字颜色 */\n:root {\n  --warbler-text-1: var(--warbler-white);\n  --warbler-text-2: #fffff5db;\n  --warbler-text-3: var(--warbler-brand);\n}\n\n/* 边框颜色 */\n:root {\n  --warbler-border-color-1: rgba(82, 82, 89, 0.32);\n  --warbler-border-1: 1px solid var(--warbler-border-color-1);\n}\n\n/* 滚动条相关颜色 */\n:root {\n  --warbler-scroll-thumb-color: #686868;\n  --warbler-scroll-track-color: #424242;\n}\n\n/* 字体 */\n:root {\n  --warbler-font-family-base: 'Inter var', 'Inter', ui-sans-serif, system-ui, -apple-system,\n    BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Helvetica, Arial, 'Noto Sans',\n    sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';\n  --warbler-font-family-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Monaco, Consolas,\n    'Liberation Mono', 'Courier New', monospace;\n}\n\n::-webkit-scrollbar {\n  /*滚动条整体样式*/\n  width: 8px;\n  /*高宽分别对应横竖滚动条的尺寸*/\n}\n\n::-webkit-scrollbar-thumb {\n  /*滚动条里面小方块*/\n  background-color: var(--warbler-scroll-thumb-color);\n  border-radius: 20px;\n}\n\n::-webkit-scrollbar-track {\n  /*滚动条里面轨道*/\n  /* 阴影 */\n  -webkit-box-shadow: inset 0 0 5px var(--warbler-black);\n  background: var(--warbler-scroll-track-color);\n}\n\n.fs12 {\n  font-size: 12px;\n}\n\n.fs14 {\n  font-size: 14px;\n}\n\n.fwb {\n  font-weight: bold;\n}\n\n.text-over-flow {\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.cp {\n  cursor: pointer;\n}\n\n.spinner-box {\n  width: 100vw;\n  height: 100vh;\n  position: fixed;\n  top: 0;\n  left: 0;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  z-index: 9999;\n}\n.spinner {\n  height: 50px;\n  width: 50px;\n  background: transparent;\n  border: red 3px solid;\n  border-top: transparent;\n  border-radius: 50%;\n  animation: animate81323 0.8s linear infinite;\n}\n\n@keyframes animate81323 {\n  0% {\n    border: 3px solid rgb(255, 75, 75);\n    border-top: transparent;\n    border-left: transparent;\n    transform: rotate(0deg);\n  }\n\n  50% {\n    border: 3px dashed rgb(240, 41, 240);\n    border-top: transparent;\n    border-left: transparent;\n    transform: rotate(270deg);\n  }\n\n  100% {\n    border: 3px dotted rgb(28, 228, 28);\n    border-top: transparent;\n    border-left: transparent;\n    transform: rotate(360deg);\n  }\n}\n"
  },
  {
    "path": "src/views/contact/index.vue",
    "content": "<template>\n  <div class=\"contact\">\n    <div class=\"wechat\">\n      <img src=\"@/assets/image/wechat.jpeg\" />\n    </div>\n  </div>\n</template>\n\n<script setup lang=\"ts\"></script>\n\n<style lang=\"scss\" scoped>\n.contact {\n  width: 100%;\n  height: 100%;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  .wechat img {\n    width: 300px;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/views/dataCenter/index.vue",
    "content": "\n<template>\n  <div class=\"data-center\">数据中心</div>\n</template>\n\n<script setup lang=\"ts\"></script>\n\n<style lang=\"scss\" scoped>\n.data-center {\n  padding-top: var(--warbler-header-height);\n  width: 100%;\n  height: 100%;\n  overflow: auto;\n}\n</style>\n"
  },
  {
    "path": "src/views/homepage/canvas.ts",
    "content": "/* eslint-disable no-plusplus */\n/* eslint-disable max-classes-per-file */\n\nconst E = {\n  friction: 0.5,\n  trails: 20,\n  size: 50,\n  dampening: 0.25,\n  tension: 0.98,\n};\n\nclass Wave {\n  phase = 0;\n\n  offset = 0;\n\n  frequency = 0.001;\n\n  amplitude = 1;\n\n constructor(e: Partial<Pick<Wave, 'phase' | 'offset' | 'frequency' | 'amplitude'>>) {\n    // 设置相位\n    this.phase = e.phase || 0;\n    // 设置偏移量\n    this.offset = e.offset || 0;\n    // 设置频率\n    this.frequency = e.frequency || 0.001;\n    // 设置振幅\n    this.amplitude = e.amplitude || 1;\n  }\n\n  update() {\n    this.phase += this.frequency;\n    return this.offset + Math.sin(this.phase) * this.amplitude;\n  }\n}\n\nclass Node {\n  x = 0;\n\n  y = 0;\n\n  vy = 0;\n\n  vx = 0;\n}\n\nclass Line {\n  spring = 0.1;\n\n  friction = 0.01;\n\n  nodes: Node[] = [];\n\n  // eslint-disable-next-line no-unused-vars\n  constructor(e: { spring: number }, private pos: { x: number; y: number }) {\n    this.spring = e.spring + 0.1 * Math.random() - 0.05;\n    this.friction = E.friction + 0.01 * Math.random() - 0.005;\n    this.nodes = [];\n    for (let i = 0; i < E.size; i++) {\n      const t = new Node();\n      t.x = this.pos.x;\n      t.y = this.pos.y;\n      this.nodes.push(t);\n    }\n  }\n\n  update() {\n    let { spring } = this;\n    let node = this.nodes[0];\n\n    node.vx += (this.pos.x - node.x) * spring;\n    node.vy += (this.pos.y - node.y) * spring;\n\n    let prevNode: Node;\n    for (let i = 0; i < this.nodes.length; i++) {\n      node = this.nodes[i];\n\n      if (i > 0) {\n        prevNode = this.nodes[i - 1];\n        node.vx += (prevNode.x - node.x) * spring;\n        node.vy += (prevNode.y - node.y) * spring;\n        node.vx += prevNode.vx * E.dampening;\n        node.vy += prevNode.vy * E.dampening;\n      }\n\n      node.vx *= this.friction;\n      node.vy *= this.friction;\n      node.x += node.vx;\n      node.y += node.vy;\n      spring *= E.tension;\n    }\n  }\n\n  draw(ctx: CanvasRenderingContext2D) {\n    let currNode;\n    let nextNode;\n    let { x } = this.nodes[0];\n    let { y } = this.nodes[0];\n\n    ctx.beginPath();\n    ctx.moveTo(x, y);\n\n    let i;\n    for (i = 1; i < this.nodes.length - 2; i++) {\n      currNode = this.nodes[i];\n      nextNode = this.nodes[i + 1];\n      x = 0.5 * (currNode.x + nextNode.x);\n      y = 0.5 * (currNode.y + nextNode.y);\n      ctx.quadraticCurveTo(currNode.x, currNode.y, x, y);\n    }\n    currNode = this.nodes[i];\n    nextNode = this.nodes[i + 1];\n    ctx.quadraticCurveTo(currNode.x, currNode.y, nextNode.x, nextNode.y);\n\n    ctx.stroke();\n    ctx.closePath();\n  }\n}\n\nexport const renderCanvas = () => {\n  const canvas = document.getElementById('canvas') as HTMLCanvasElement;\n\n  // 获取canvas的2D上下文\nconst ctx: CanvasRenderingContext2D = canvas!.getContext('2d')!;\n  // 创建一个空的线数组\n  let lines: Line[] = [];\n  // 创建一个位置对象\n  const pos = { x: 0, y: 0 };\n  // 创建一个波浪对象\n  const wave = new Wave({\n    phase: Math.random() * 2 * Math.PI,  \n    amplitude: 85,\n    frequency: 0.0015,\n    offset: 285,\n  });\n  // 创建一个布尔值，用来控制波浪的运行状态\n  let running = true;\n  // 创建一个函数，用来调整画布的大小\n  function resizeCanvas() {\n    ctx.canvas.width = window.innerWidth;\n    ctx.canvas.height = window.innerHeight;\n  }\n\n  resizeCanvas();\n\n  function animate() {\n    if (running) {\n      // 设置全局混合模式\n      ctx.globalCompositeOperation = 'source-over';\n      // 清除画布\n      ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);\n      // 设置全局混合模式\n      ctx.globalCompositeOperation = 'lighter';\n      // 设置画笔颜色\n      ctx.strokeStyle = `hsla(${Math.round(wave.update())},90%,50%,0.25)`;\n      // 设置画笔线宽\n      ctx.lineWidth = 1;\n      // 遍历每一条线\n      for (let i = 0; i < E.trails; i++) {\n        const line = lines[i];\n        // 更新每条线的属性\n        line.update();\n        // 绘制每条线\n        line.draw(ctx);\n      }\n      // 请求动画帧\n      window.requestAnimationFrame(animate);\n    }\n  }\n\n  function bindMouseMove(event: Event) {\n    function drawLine() {\n      lines = [];\n      for (let i = 0; i < E.trails; i++) {\n        lines.push(new Line({ spring: 0.45 + (i / E.trails) * 0.025 }, pos));\n      }\n    }\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    function move(e: any) {\n      e.preventDefault();\n      if (e.touches) {\n        pos.x = e.touches[0].pageX;\n        pos.y = e.touches[0].pageY;\n      } else {\n        pos.x = e.clientX;\n        pos.y = e.clientY;\n      }\n    }\n    function start(e: TouchEvent) {\n      if (e.touches.length === 1) {\n        pos.x = e.touches[0].pageX;\n        pos.y = e.touches[0].pageY;\n      }\n    }\n    document.removeEventListener('mousemove', bindMouseMove);\n    document.removeEventListener('touchstart', bindMouseMove);\n    document.addEventListener('mousemove', move);\n    document.addEventListener('touchmove', move);\n    document.addEventListener('touchstart', start);\n    move(event);\n    drawLine();\n    animate();\n  }\n\n  // 监听鼠标移动事件，绑定鼠标移动函数\ndocument.addEventListener('mousemove', bindMouseMove);\n  // 监听触摸开始事件，绑定鼠标移动函数\n  document.addEventListener('touchstart', bindMouseMove);\n  // 监听设备方向改变事件，重新绘制画布\n  document.body.addEventListener('orientationchange', resizeCanvas);\n  // 监听窗口大小改变事件，重新绘制画布\n  window.addEventListener('resize', resizeCanvas);\n  // 监听窗口获取焦点事件，如果未运行，则运行动画\n  window.addEventListener('focus', () => {\n    if (!running) {\n      running = true;\n      animate();\n    }\n  });\n  // 监听窗口失去焦点事件，将运行状态设置为true\n  window.addEventListener('blur', () => {\n    running = true;\n  });\n};\n"
  },
  {
    "path": "src/views/homepage/components/typewriter.vue",
    "content": "<template>\n  <div class=\"typewriter-box\">\n    \n    <div class=\"typewriter\">\n      <div class=\"text\">\n        江城开朗的豌豆，\n        <span class=\"Chinese \">\n          <span >让</span>\n          <span >前</span>\n          <span >端</span>\n          <span >再</span>\n          <span >简</span>\n          <span >单</span>\n          <span >一</span>\n          <span >点</span>\n          <span >。</span>\n        </span>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\n</script>\n\n<style lang=\"scss\" scoped>\n@keyframes waviy {\n  0% { transform: rotate(0deg); }\n  100% { transform: rotate(360deg); }\n}\n:root {\n  --i: 1;\n}\n.waviy{\n  position: relative;\n  -webkit-box-reflect: below -10px linear-gradient(transparent,rgba(0,0,0,.2));\n  font-size: 36px;\n}\n.waviy span{\n  font-family: '微软雅黑',cursive;\n  position: relative;\n  display: inline-block;\n  text-transform: uppercase;\n  animation: waviy 1s uppercase;\n  animation-delay: calc(.1s * var(--i));\n}\n.typewriter-box {\n  width: 100vw;\n  height: 100vh;\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: 1;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  pointer-events: none;\n}\n\n.text {\n  overflow: hidden;\n  white-space: nowrap;\n  animation: typeEffect 1s steps(70);\n  font-size: 36px;\n  @media (max-width: 900px) {\n    font-size: 24px;\n  }\n  @media (max-width: 500px) {\n    font-size: 16px;\n  }\n  font-weight: bold;\n}\n\n.Chinese {\n  letter-spacing: 0.05em;\n}\n\n@keyframes typeEffect {\n  from {\n    width: 0;\n  }\n  to {\n    width: 100%;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/views/homepage/index.vue",
    "content": "\n<template>\n  <div class=\"homepage-view\">\n    <canvas id=\"canvas\" class=\"canvas\"></canvas>\n    <typewriter></typewriter>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\n\nimport { onMounted } from 'vue';\nimport typewriter from './components/typewriter.vue';\nimport { renderCanvas } from './canvas';\n\nonMounted(() => {\n  renderCanvas();\n});\n</script>\n\n<style lang=\"scss\" scoped>\ncanvas {\n  display: block;\n}\n</style>\n"
  },
  {
    "path": "src/views/navigation/data/index.ts",
    "content": "import { ref } from 'vue';\n\nexport interface NavItem {\n  icon: string;\n  name: string;\n  link: string;\n  iconErrorText: string;\n}\n\nexport type NavList = Array<NavItem>;\n\nexport interface NavGroup {\n  title: string;\n  list: NavList;\n  isPrivate?: boolean;\n}\n\nexport type NavData = Array<NavGroup>;\n\nexport class NavListGetter {\n  // eslint-disable-next-line no-use-before-define\n  static navListGetter: NavListGetter = new NavListGetter();\n\n  // 获取 data 所在目录\n  getDataPath() {\n    return import.meta.glob('./list/*.ts', { eager: true });\n  }\n\n  // 获取目录下所有的文件\n  getAllData() {\n    // 获取 data 所在目录\n    const dataDirPath = this.getDataPath() as any;\n    // 定义响应式变量\n    const completeList = ref<NavData>([]);\n    Object.keys(dataDirPath).forEach((data) => {\n      // 动态添加数据\n      const {\n        default: { title, list, isPrivate = false },\n      } = dataDirPath[data];\n      completeList.value.push({\n        title,\n        list,\n        isPrivate,\n      });\n    });\n    return completeList;\n  }\n}\n\nexport default NavListGetter.navListGetter.getAllData();\n"
  },
  {
    "path": "src/views/navigation/data/list/_b_vue.ts",
    "content": "import type { NavList } from '../index';\n\nconst list: NavList = [\n  {\n    icon: 'https://cn.vuejs.org/logo.svg',\n    name: 'Vue.js',\n    link: 'https://cn.vuejs.org/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://cn.vuejs.org/logo.svg',\n    name: 'Vuex',\n    link: 'https://vuex.vuejs.org/zh/index.html',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://cn.vuejs.org/logo.svg',\n    name: 'Vue Router',\n    link: 'https://router.vuejs.org/zh/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://cn.vuejs.org/logo.svg',\n    name: 'Vue CLI',\n    link: 'https://cli.vuejs.org/zh/guide/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://cn.vuejs.org/logo.svg',\n    name: 'Vue I18n',\n    link: 'https://kazupon.github.io/vue-i18n/zh/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://cn.vuejs.org/logo.svg',\n    name: 'VuePress',\n    link: 'https://v2.vuepress.vuejs.org/zh/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://cn.vuejs.org/logo.svg',\n    name: 'VitePress',\n    link: 'https://vitepress.dev/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://cn.vuejs.org/logo.svg',\n    name: 'eslint-plugin-vue',\n    link: 'https://eslint.vuejs.org/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://cn.vuejs.org/logo.svg',\n    name: 'Vue Test Utils',\n    link: 'https://test-utils.vuejs.org/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://vueuse.org/favicon-32x32.png',\n    name: 'VueUse 官网',\n    link: 'https://vueuse.org/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://vueuse.org/favicon-32x32.png',\n    name: 'VueUse 中文',\n    link: 'https://www.vueusejs.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://static.vue-js.com/6280b990-ff19-11ea-85f6-6fac77c0c9b3.png',\n    name: 'Vue3 One Piece',\n    link: 'https://vue3js.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://nuxt.com/icon.png',\n    name: 'Nuxt',\n    link: 'https://nuxt.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://nuxt.com/icon.png',\n    name: 'Nuxt3 中文',\n    link: 'https://nuxt.com.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://pinia.vuejs.org/logo.svg',\n    name: 'Pinia',\n    link: 'https://pinia.vuejs.org/zh/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://element-plus.gitee.io/images/element-plus-logo-small.svg',\n    name: 'Element Plus',\n    link: 'https://element-plus.gitee.io/zh-CN/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://file.iviewui.com/view-design-logo.png',\n    name: 'View Design',\n    link: 'https://www.iviewui.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://fastly.jsdelivr.net/npm/@vant/assets/logo.png',\n    name: 'Vant',\n    link: 'https://vant-contrib.gitee.io/vant/#/zh-CN/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://aliyuncdn.antdv.com/favicon.ico',\n    name: 'Ant Design Vue',\n    link: 'https://www.antdv.com/components/overview-cn',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.naiveui.com/assets/naivelogo-93278402.svg',\n    name: 'Naive UI',\n    link: 'https://www.naiveui.com/zh-CN/light',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://vxetable.cn/v4/logo.png',\n    name: 'vxe-table',\n    link: 'https://vxetable.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://res.hc-cdn.com/tinyui-design/1.0.7.20230818162939/home/favicon.ico',\n    name: 'OpenTiny',\n    link: 'https://opentiny.design/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://cdn.quasar.dev/logo-v2/favicon/favicon-128x128.png',\n    name: 'Quasar',\n    link: 'https://quasar.dev/',\n    iconErrorText: '',\n  },\n];\n\nconst listData = {\n  title: 'Vue',\n  list,\n};\n\nexport default listData;\n"
  },
  {
    "path": "src/views/navigation/data/list/_c_react.ts",
    "content": "import type { NavList } from '../index';\n\nconst list: NavList = [\n  {\n    icon: 'https://react.zcopy.site/favicon.ico',\n    name: 'React',\n    link: 'https://react.zcopy.site/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://react.zcopy.site/favicon.ico',\n    name: 'React 中文网',\n    link: 'https://react.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://react.zcopy.site/favicon.ico',\n    name: 'React Native',\n    link: 'https://www.react-native.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://react.zcopy.site/favicon.ico',\n    name: 'Create React App',\n    link: 'https://cra.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://reactrouter.com/favicon-dark.png',\n    name: 'React Router',\n    link: 'https://reactrouter.com/en/main',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://cn.redux.js.org/img/favicon/favicon.ico',\n    name: 'Redux',\n    link: 'https://cn.redux.js.org/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://img.alicdn.com/tfs/TB1YHEpwUT1gK0jSZFhXXaAtVXa-28-27.svg',\n    name: 'UmiJS',\n    link: 'https://umijs.org/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.nextjs.cn/static/favicon/favicon-32x32.png',\n    name: 'Next.js',\n    link: 'https://www.nextjs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://gw.alipayobjects.com/zos/rmsportal/rlpTLlbMzTNYuZGGCVYM.png',\n    name: 'Ant Design of React',\n    link: 'https://ant.design/docs/react/introduce-cn',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://ahooks.gitee.io/simple-logo.svg',\n    name: 'ahooks',\n    link: 'https://ahooks.gitee.io/zh-CN',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://img.alicdn.com/imgextra/i3/O1CN01XtT3Tv1Wd1b5hNVKy_!!6000000002810-55-tps-360-360.svg',\n    name: 'Alibaba Formily',\n    link: 'https://v2.formilyjs.org/zh-CN',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://recoiljs.org/zh-hans/img/favicon.png',\n    name: 'Recoil',\n    link: 'https://recoiljs.org/zh-hans/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://lf9-static.semi.design/obj/semi-tos/images/favicon.ico',\n    name: 'Semi Design',\n    link: 'https://semi.design/zh-CN/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://remix.run/favicon-192.png',\n    name: 'Remix',\n    link: 'https://remix.run/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://docusaurus.nodejs.cn/img/docusaurus.ico',\n    name: 'Docusaurus',\n    link: 'https://docusaurus.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://preact.nodejs.cn/favicon.ico',\n    name: 'Preact',\n    link: 'https://preact.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://mobx.nodejs.cn/img/favicon.png',\n    name: 'MobX',\n    link: 'https://mobx.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://swr.nodejs.cn/favicon/favicon-32x32.png',\n    name: 'SWR',\n    link: 'https://swr.nodejs.cn/',\n    iconErrorText: '',\n  },\n];\n\nconst listData = {\n  title: 'React',\n  list,\n};\n\nexport default listData;\n"
  },
  {
    "path": "src/views/navigation/data/list/_d_css.ts",
    "content": "import type { NavList } from '../index';\n\nconst list: NavList = [\n  {\n    icon: 'https://sass.nodejs.cn/icon.png',\n    name: 'Sass',\n    link: 'https://sass.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://less.nodejs.cn/public/ico/favicon.ico',\n    name: 'Less',\n    link: 'https://less.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.stylus-lang.cn/favicon.ico',\n    name: 'Stylus',\n    link: 'https://stylus.nodejs.cn/',\n    iconErrorText: '',\n  },\n\n  {\n    icon: 'http://postcss.docschina.org/_/web_modules/LayoutContainer/favicon-192x192.png',\n    name: 'PostCSS',\n    link: 'https://postcss.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.tailwindcss.cn/favicons/favicon-16x16.png?v=3',\n    name: 'Tailwind CSS',\n    link: 'https://tailwind.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://unocss.dev/favicon.svg',\n    name: 'UnoCSS',\n    link: 'https://unocss.dev/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://windicss.org/assets/logo.svg',\n    name: 'Windi CSS',\n    link: 'https://windicss.org/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://animate.style/img/favicon.ico',\n    name: 'Animate.css',\n    link: 'https://animate.style/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://bootstrap.nodejs.cn/docs/5.3/assets/img/favicons/favicon-32x32.png',\n    name: 'Bootstrap',\n    link: 'https://bootstrap.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://neumorphism.io/favicon.ico',\n    name: '新拟态生成器',\n    link: 'https://neumorphism.io/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://hype4.academy/favicon/apple-icon-60x60.png',\n    name: '三种拟态生成器',\n    link: 'https://hype4.academy/tools',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://error404.fun/img/favicon-32x32.png',\n    name: '404 Illustrations',\n    link: 'https://error404.fun/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://cssgridgarden.com/favicon.ico',\n    name: 'Grid Garden',\n    link: 'https://cssgridgarden.com/#zh-cn',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://flexboxfroggy.com/favicon.ico',\n    name: 'Flexbox Froggy',\n    link: 'https://flexboxfroggy.com/#zh-cn',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://caniuse.com/img/favicon-128.png',\n    name: 'Can I use',\n    link: 'https://caniuse.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://coolbackgrounds.io/images/favicon-fe5a0ff5.png',\n    name: 'Cool Backgrounds',\n    link: 'https://coolbackgrounds.io/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://animista.net/favicon.ico',\n    name: '在线制作css动画',\n    link: 'https://animista.net/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://cssgradient.io/images/favicon-23859487.png',\n    name: '渐变色制作',\n    link: 'https://cssgradient.io/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://cssvalues.com/favicon.ico',\n    name: 'CSS属性速查',\n    link: 'https://cssvalues.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://bennettfeely.com/clippy/pics/favicon.png',\n    name: 'CSS clip-path maker',\n    link: 'https://www.techbrood.com/tool?p=css-clip-path',\n    iconErrorText: '',\n  },\n];\n\nconst listData = {\n  title: 'Css',\n  list,\n};\n\nexport default listData;\n"
  },
  {
    "path": "src/views/navigation/data/list/_e1_javascript.ts",
    "content": "import type { NavList } from '../index';\n\nconst list: NavList = [\n  {\n    icon: 'https://www.lodashjs.com/img/favicon.ico',\n    name: 'Lodash',\n    link: 'https://www.lodashjs.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://smartprocure.github.io/futil-js/icon.svg',\n    name: 'Futil',\n    link: 'https://smartprocure.github.io/futil-js/#overNone',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://es6.ruanyifeng.com/favicon.ico',\n    name: '阮一峰ES6',\n    link: 'https://es6.ruanyifeng.com/#docs/style',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://moment.nodejs.cn/static/img/moment-favicon.png',\n    name: 'Moment.js',\n    link: 'https://moment.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://dayjs.fenxianglu.cn/assets/favicon.png',\n    name: 'Day.js',\n    link: 'https://day.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://img-blog.csdnimg.cn/img_convert/291ca37b2f33b30ec6db6f2f9762d6e8.png',\n    name: 'swiper',\n    link: 'https://www.swiper.com.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'http://mockjs.com/assets/img/logo-2.svg',\n    name: 'Mock.js',\n    link: 'http://mockjs.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://ejs.bootcss.com/assets/images/ejs-logo.png',\n    name: 'EJS',\n    link: 'https://ejs.bootcss.com/#promo',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://handlebars.nodejs.cn/images/favicon.png',\n    name: 'Handlebars',\n    link: 'https://handlebars.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://pug.nodejs.cn/images/favicon-32x32.png',\n    name: 'Pug',\n    link: 'https://pug.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://mathjs.org/favicon.ico',\n    name: 'Math.js',\n    link: 'https://mathjs.org/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://printjs.crabbly.com/assets/favicon.ico',\n    name: 'Print.js',\n    link: 'https://printjs.crabbly.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'http://mozilla.github.io/pdf.js/images/favicon.ico',\n    name: 'PDF.js',\n    link: 'http://mozilla.github.io/pdf.js/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://xlsx.nodejs.cn/img/favicon.ico',\n    name: 'SheetJS',\n    link: 'https://xlsx.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'http://cdn.dooring.cn/dr/xijs.png',\n    name: 'xijs',\n    link: 'http://h5.dooring.cn/xijs',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://axios.nodejs.cn/assets/favicon.ico',\n    name: 'Axios',\n    link: 'https://axios.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://rx.nodejs.cn/assets/images/favicons/favicon.ico',\n    name: 'RxJS',\n    link: 'https://rx.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://floating-ui.com/favicon.ico',\n    name: 'Floating UI',\n    link: 'https://floating.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://cheerio.nodejs.cn/img/favicon.ico',\n    name: 'Cheerio',\n    link: 'https://cheerio.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: '',\n    name: 'localForage',\n    link: 'https://localforage.docschina.org/',\n    iconErrorText: '',\n  },\n];\n\nconst listData = {\n  title: 'JavaScript',\n  list,\n};\n\nexport default listData;\n"
  },
  {
    "path": "src/views/navigation/data/list/_e2_typescript.ts",
    "content": "import type { NavList } from '../index';\n\nconst list: NavList = [\n  {\n    icon: 'https://www.typescriptlang.org/favicon-32x32.png?v=8944a05a8b601855de116c8a56d3b3ae',\n    name: 'TypeScript',\n    link: 'https://ts.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://ts.xcatliu.com/favicon.png',\n    name: 'TypeScript 入门教程',\n    link: 'https://ts.xcatliu.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://ts.xcatliu.com/favicon.png',\n    name: '深入理解 TypeScript',\n    link: 'https://jkchao.github.io/typescript-book-chinese/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://tsch.js.org/favicon.svg',\n    name: 'TypeScript 类型挑战',\n    link: 'https://tsch.js.org/',\n    iconErrorText: '',\n  },\n];\n\nconst listData = {\n  title: 'Typescript',\n  list,\n};\n\nexport default listData;\n"
  },
  {
    "path": "src/views/navigation/data/list/_f_node.ts",
    "content": "import type { NavList } from '../index';\n\nconst list: NavList = [\n  {\n    icon: 'https://img.nodejs.cn/favicon.png',\n    name: 'Node.js 中文文档',\n    link: 'https://nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://img.nodejs.cn/favicon.png',\n    name: 'Node.js 英文官网',\n    link: 'https://nodejs.org/en',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.expressjs.com.cn/images/favicon.png',\n    name: 'Express',\n    link: 'https://express.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://koa.nodejs.cn/public/favicon.png',\n    name: 'koa',\n    link: 'https://koa.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.eggjs.org/logo.svg',\n    name: 'Egg',\n    link: 'https://www.eggjs.org/zh-CN',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://docs.nestjs.com/favicon.ico',\n    name: 'Nest',\n    link: 'https://nest.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://nodejstoolbox.com/favicon-32x32.png',\n    name: 'Node.js Toolbox',\n    link: 'https://nodejstoolbox.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://pptr.nodejs.cn/img/favicon.ico',\n    name: 'Puppeteer',\n    link: 'https://pptr.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.prisma.io/images/favicon-32x32.png',\n    name: 'Prisma',\n    link: 'https://prisma.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://graphql.nodejs.cn/favicon.ico',\n    name: 'GraphQL',\n    link: 'https://graphql.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://sequelize.nodejs.cn/img/logo.svg',\n    name: 'Sequelize',\n    link: 'https://sequelize.nodejs.cn/',\n    iconErrorText: '',\n  },\n];\n\nconst listData = {\n  title: 'NodeJS',\n  list,\n};\n\nexport default listData;\n"
  },
  {
    "path": "src/views/navigation/data/list/_g_officialDocuments.ts",
    "content": "import type { NavList } from '../index';\n\nconst list: NavList = [\n  {\n    icon: 'https://developer.mozilla.org/apple-touch-icon.6803c6f0.png',\n    name: 'MDN Web Docs',\n    link: 'https://developer.mozilla.org/zh-CN/',\n    iconErrorText: '',\n  },\n\n  {\n    icon: 'https://static.sitestack.cn/uploads/icons/2851629677557.png',\n    name: 'Socket.IO',\n    link: 'https://socket.nodejs.cn/',\n    iconErrorText: '',\n  },\n\n  {\n    icon: 'https://www.sveltejs.cn/favicon.ico',\n    name: 'Svelte',\n    link: 'https://www.sveltejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-a90b5f95-90ba-4d30-a6a7-cd4d057327db/d23e842c-58fc-4574-998d-17fdc7811cc3.png?v=1556263038788',\n    name: 'uni-app',\n    link: 'https://uniapp.dcloud.net.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://angular.cn/assets/images/favicons/favicon.ico',\n    name: 'Angular',\n    link: 'https://angular.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.solidjs.cn/img/favicons/favicon-32x32.png',\n    name: 'solid',\n    link: 'https://www.solidjs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.electronjs.org/zh/assets/img/favicon.ico',\n    name: 'Electron',\n    link: 'https://www.electronjs.org/zh/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://tauri.app/zh-cn/meta/favicon-96x96.png',\n    name: 'tauri',\n    link: 'https://tauri.app/zh-cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://res.wx.qq.com/a/wx_fed/assets/res/NTI4MWU5.ico',\n    name: '微信小程序',\n    link: 'https://developers.weixin.qq.com/miniprogram/dev/framework/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://cdn.docschina.org/home/logo/taro.png',\n    name: 'Taro',\n    link: 'https://taro-docs.jd.com/docs',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://doc.flutterchina.club/images/favicon.png',\n    name: 'Flutter',\n    link: 'https://flutterchina.club/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://npm.nodejs.cn/favicon-32x32.png?v=f44ec608ba91563f864a30a276cd9065',\n    name: 'NPM 中文网',\n    link: 'https://npm.nodejs.cn/',\n    iconErrorText: '',\n  },\n\n  {\n    icon: 'https://flow.nodejs.cn/img/favicon.png',\n    name: 'FLOW',\n    link: 'https://flow.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.dartcn.com/assets/shared/dart/icon/64.png',\n    name: 'Dart',\n    link: 'https://www.dartcn.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://quarkc.hellobike.com/assets/favicon.7b83b3c2.ico',\n    name: 'Quarkc',\n    link: 'https://quarkc.hellobike.com/#/',\n    iconErrorText: '',\n  },\n\n  {\n    icon: 'https://astro.build/favicon.svg',\n    name: 'Astro',\n    link: 'https://astro.build/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://qwik.builder.io/favicons/favicon.svg',\n    name: 'Qwik',\n    link: 'https://qwik.builder.io/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.rust-lang.org/static/images/rust-logo-blk.svg',\n    name: 'Rust',\n    link: 'https://www.rust-lang.org/zh-CN/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://mdx.nodejs.cn/icon.svg',\n    name: 'MDX',\n    link: 'https://mdx.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://assemblyscript.nodejs.cn/favicon.ico',\n    name: 'AssemblyScript',\n    link: 'https://assemblyscript.nodejs.cn/',\n    iconErrorText: '',\n  },\n];\n\nconst listData = {\n  title: '官方文档',\n  list,\n};\n\nexport default listData;\n"
  },
  {
    "path": "src/views/navigation/data/list/_h_charts.ts",
    "content": "import type { NavList } from '../index';\n\nconst list: NavList = [\n  {\n    icon: 'https://echarts.apache.org/zh/images/favicon.png?_v_=20200710_1',\n    name: 'Apache ECharts',\n    link: 'https://echarts.apache.org/zh/index.html',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://chart.nodejs.cn/favicon.ico',\n    name: 'Chart.js',\n    link: 'https://chart.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.isqqw.com/favicon.ico',\n    name: 'ECharts 图表集',\n    link: 'https://www.isqqw.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://threejs.org/files/favicon_white.ico',\n    name: 'three.js',\n    link: 'https://threejs.org/docs/index.html#manual/zh/introduction/Installation',\n    iconErrorText: '',\n  },\n  {\n    icon: 'http://fabricjs.com/favicon.ico',\n    name: 'Fabric.js',\n    link: 'http://fabricjs.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://s1.jscdn.com.cn/highcharts/images/favicon.ico',\n    name: 'Highcharts',\n    link: 'https://www.hcharts.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*7svFR6wkPMoAAAAAAAAAAAAADmJ7AQ/original',\n    name: 'AntV',\n    link: 'https://antv.vision/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://d3js.org/logo.png',\n    name: 'D3.js',\n    link: 'https://d3js.org/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://apexcharts.com/wp-content/themes/apexcharts/favicon.ico',\n    name: 'ApexCharts',\n    link: 'https://apexcharts.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'http://ppchart.com/favicon.ico',\n    name: 'PPChart',\n    link: 'http://ppchart.com/#/',\n    iconErrorText: '',\n  },\n];\n\nconst listData = {\n  title: '视觉图表库',\n  list,\n};\n\nexport default listData;\n"
  },
  {
    "path": "src/views/navigation/data/list/_i_codeManager.ts",
    "content": "import type { NavList } from '../index';\n\nconst list: NavList = [\n  {\n    icon: 'https://img2.baidu.com/it/u=83310884,27671367&fm=253&fmt=auto&app=138&f=PNG?w=256&h=256',\n    name: 'Github',\n    link: 'https://github.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://git-scm.com/favicon.ico',\n    name: 'Git',\n    link: 'https://github.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://gitee.com/favicon.ico',\n    name: 'Gitee',\n    link: 'https://git-scm.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://static.npmjs.com/7a7ffabbd910fc60161bc04f2cee4160.png',\n    name: 'NPM',\n    link: 'https://www.npmjs.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://npm-stat.com/favicon.ico',\n    name: 'NPM下载量查询',\n    link: 'https://npm-stat.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://about.gitlab.com/nuxt-images/ico/favicon-192x192.png?cache=2022041',\n    name: 'Gitlab',\n    link: 'https://about.gitlab.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.travis-ci.com/wp-content/uploads/2022/05/travis-ci-mascot-1-300x300.png',\n    name: 'Travis-CI',\n    link: 'https://www.travis-ci.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.yarnpkg.cn/favicon-32x32.png?v=6143f50112ddba9fdb635b0af2f32aff',\n    name: 'Yarn',\n    link: 'https://yarn.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://d33wubrfki0l68.cloudfront.net/2f3acb83b7d2349f2194bc38c0f22f295908dc33/6a6e6/zh/img/pnpm-no-name-with-frame.svg',\n    name: 'pnpm',\n    link: 'https://pnpm.io/zh/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://lerna.nodejs.cn/images/favicon.ico',\n    name: 'Lerna',\n    link: 'https://lerna.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://zh-hans.eslint.org/favicon.ico',\n    name: 'ESlint',\n    link: 'https://zh-hans.eslint.org/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://prettier.nodejs.cn/icon.png',\n    name: 'Prettier',\n    link: 'https://prettier.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://stylelint.nodejs.cn/img/favicon.ico',\n    name: 'Stylelint',\n    link: 'https://stylelint.nodejs.cn/',\n    iconErrorText: '',\n  },\n];\n\nconst listData = {\n  title: '代码管理',\n  list,\n};\n\nexport default listData;\n"
  },
  {
    "path": "src/views/navigation/data/list/_j_buildTools.ts",
    "content": "import type { NavList } from '../index';\n\nconst list: NavList = [\n  {\n    icon: 'https://cn.vitejs.dev/logo.svg',\n    name: 'Vite',\n    link: 'https://cn.vitejs.dev',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.webpackjs.com/icon_144x144.png',\n    name: 'webpack',\n    link: 'https://webpack.docschina.org/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.gulpjs.com.cn/img/favicon.png',\n    name: 'gulp',\n    link: 'https://gulp.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://turbo.build/images/favicon-light/favicon-32x32.png',\n    name: 'Turbopack',\n    link: 'https://turbo.build/pack',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.babeljs.cn/img/favicon.png',\n    name: 'Babel',\n    link: 'https://babel.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.rollupjs.com/img/favicon.png',\n    name: 'Rollup',\n    link: 'https://www.rollupjs.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://parceljs.org/favicon.fe6f9d11.ico',\n    name: 'Parcel',\n    link: 'https://parcel.nodejs.cn/',\n    iconErrorText: '',\n  },\n];\n\nconst listData = {\n  title: '构建工具',\n  list,\n};\n\nexport default listData;\n"
  },
  {
    "path": "src/views/navigation/data/list/_k_micro.ts",
    "content": "import type { NavList } from '../index';\n\nconst list: NavList = [\n  {\n    icon: 'https://zeroing.jd.com/micro-app/favicon.ico',\n    name: 'MicroApp',\n    link: 'https://zeroing.jd.com/micro-app/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://zh-hans.single-spa.js.org/img/logo-blue-favicon.ico',\n    name: 'single-spa',\n    link: 'https://zh-hans.single-spa.js.org/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://gw.alipayobjects.com/mdn/rms_655822/afts/img/A*4sIUQpcos_gAAAAAAAAAAAAAARQnAQ',\n    name: 'qiankun',\n    link: 'https://qiankun.umijs.org/zh',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://micro-frontends.ice.work/img/favicon.ico',\n    name: 'icestark',\n    link: 'https://micro-frontends.ice.work/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://wujie-micro.github.io/doc//favicon.ico',\n    name: '无界',\n    link: 'https://wujie-micro.github.io/doc/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/dhozeh7vhpebvog/open-garfish/icons/icon.png',\n    name: 'Garfish',\n    link: 'https://www.garfishjs.org/',\n    iconErrorText: '',\n  },\n];\n\nconst listData = {\n  title: '微前端',\n  list,\n};\n\nexport default listData;\n"
  },
  {
    "path": "src/views/navigation/data/list/_k_test.ts",
    "content": "import type { NavList } from '../index';\n\nconst list: NavList = [\n  {\n    icon: 'https://jestjs.io/zh-Hans/img/favicon/favicon.ico',\n    name: 'Jest',\n    link: 'https://jestjs.io/zh-Hans/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://mocha.nodejs.cn/favicon.ico',\n    name: 'Mocha',\n    link: 'https://mocha.nodejs.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://playwright.nodejs.cn/img/playwright-logo.svg',\n    name: 'Playwright',\n    link: 'https://playwright.nodejs.cn/',\n    iconErrorText: '',\n  },\n];\n\nconst listData = {\n  title: '测试库',\n  list,\n};\n\nexport default listData;\n"
  },
  {
    "path": "src/views/navigation/data/list/_l_devTools.ts",
    "content": "import type { NavList } from '../index';\n\nconst list: NavList = [\n  {\n    icon: 'https://regexr.com/assets/icons/apple-touch-icon.png',\n    name: '正则表达式',\n    link: 'https://regexr.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://uiverse.io/favicon-32x32.png',\n    name: 'uiverse 组件',\n    link: 'https://uiverse.io/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://img.alicdn.com/imgextra/i4/O1CN01Z5paLz1O0zuCC7osS_!!6000000001644-55-tps-83-82.svg',\n    name: '阿里巴巴图标库',\n    link: 'https://www.iconfont.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://tinypng.com/images/favicon.ico',\n    name: 'TinyPNG 图片压缩',\n    link: 'https://tinypng.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.yalijuda.com/qfy-content/uploads/2020/05/81a83783c78bbe2002d50d4a16c55e21.png',\n    name: 'yalijuda 图片压缩',\n    link: 'https://www.yalijuda.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'http://www.aseoe.com/favicon.ico',\n    name: 'Emmet快捷方式查询',\n    link: 'http://www.aseoe.com/special/emmet/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://carbon.now.sh/favicon.ico',\n    name: 'carbon',\n    link: 'https://carbon.now.sh/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'http://jsonplaceholder.typicode.com/favicon.ico',\n    name: 'JSONPlaceholder ',\n    link: 'http://jsonplaceholder.typicode.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://c.staticblitz.com/assets/favicon_sb-148f9e9aced4a6363b4a8232686c3d8998d3eabaab1a06385fd3f1996baf3a3e.png',\n    name: '代码在线编辑',\n    link: 'https://stackblitz.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://transfonter.org/favicon.ico',\n    name: '字体格式转换',\n    link: 'https://transfonter.org/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://ts.xcatliu.com/favicon.png',\n    name: 'TS转JS代码',\n    link: 'https://www.typescriptlang.org/zh/play?',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://overapi.com/favicon.ico',\n    name: 'OverAPI',\n    link: 'https://overapi.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.bootcdn.cn/assets/ico/favicon.ico?1644166305141',\n    name: 'BootCDN',\n    link: 'https://www.bootcdn.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://sunpma.com/other/rgb/favicon.ico',\n    name: '颜色转换工具',\n    link: 'https://sunpma.com/other/rgb/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://any86.github.io/any-rule/favicon.ico',\n    name: '正则大全',\n    link: 'https://any86.github.io/any-rule/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.toptal.com/developers/css/sprite-generator/static/images/favicon.png',\n    name: '制作精灵图',\n    link: 'https://www.toptal.com/developers/css/sprite-generator',\n    iconErrorText: '',\n  },\n];\n\nconst listData = {\n  title: '开发工具',\n  list,\n};\n\nexport default listData;\n"
  },
  {
    "path": "src/views/navigation/data/list/_m_otherTools.ts",
    "content": "import type { NavList } from '../index';\n\nconst list: NavList = [\n  {\n    icon: 'https://tool.browser.qq.com/favicon.ico',\n    name: '腾讯帮小忙',\n    link: 'https://tool.browser.qq.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.runjs.cool/favicon-32x32.png',\n    name: '前端工具箱',\n    link: 'https://www.runjs.cool/',\n    iconErrorText: '',\n  },\n  {\n    icon: '',\n    name: '万能命令',\n    link: 'https://wannengrun.net/zh/',\n    iconErrorText: '',\n  },\n  {\n    icon: '',\n    name: '网页转换助手',\n    link: 'http://www.html22.com/zh/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://static.runoob.com/images/c-runoob-logo.ico',\n    name: '菜鸟工具',\n    link: 'https://c.runoob.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://tools.miku.ac/favicon.ico',\n    name: 'MikuTools',\n    link: 'https://tools.miku.ac/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://tool.lu/favicon.ico',\n    name: '在线工具',\n    link: 'https://tool.lu/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://static.clewm.net/static/images/favicon.ico',\n    name: '草料二维码',\n    link: 'https://cli.im/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.aconvert.com/favicon.ico',\n    name: '格式转换',\n    link: 'https://www.aconvert.com/cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://tools.pdf24.org/static/img/pdf24.png?v=5cf19973',\n    name: 'PDF24 Tools',\n    link: 'https://tools.pdf24.org/zh/all-tools',\n    iconErrorText: '',\n  },\n];\n\nconst listData = {\n  title: '其它工具',\n  list,\n};\n\nexport default listData;\n"
  },
  {
    "path": "src/views/navigation/data/list/_n_technologicalGrowth.ts",
    "content": "import type { NavList } from '../index';\n\nconst list: NavList = [\n  {\n    icon: 'https://1loc.dev/assets/favicon.png',\n    name: '1loc',\n    link: 'https://phuoc.ng/collection/1-loc/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://fenxianglu.cn/build/images/favicon.png',\n    name: '技术开发分享录',\n    link: 'https://fenxianglu.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://static.sitestack.cn/static/images/cate.png',\n    name: '书栈网',\n    link: 'https://www.bookstack.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.imooc.com/static/img/common/touch-icon-ipad.png',\n    name: '慕课网',\n    link: 'https://www.imooc.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://zh.javascript.info/img/favicon/favicon.png',\n    name: '现代 JavaScript 教程',\n    link: 'https://zh.javascript.info/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://static.nowcoder.com/fe/common/share-logo.png',\n    name: '牛客网',\n    link: 'https://www.nowcoder.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://leetcode.cn/favicon.ico',\n    name: '力扣',\n    link: 'https://leetcode.cn/',\n    iconErrorText: '',\n  },\n\n  {\n    icon: 'https://www.runoob.com/favicon.ico',\n    name: '菜鸟教程',\n    link: 'https://www.runoob.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://senior-frontend.pages.dev/logo.png',\n    name: 'web全栈体系',\n    link: 'https://senior-frontend.pages.dev/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.w3school.com.cn/ui2019/logo-16-red.png',\n    name: 'w3school',\n    link: 'https://www.w3school.com.cn/index.html',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://docschina.org/favicon.ico',\n    name: '印记中文',\n    link: 'https://docschina.org/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.ruanyifeng.com/favicon.ico',\n    name: '阮一峰博客',\n    link: 'https://www.ruanyifeng.com/blog/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.eveningwater.com/static/image/icon.jpg',\n    name: '剑指offer算法题',\n    link: 'https://eveningwater.github.io/to-offer/#/',\n    iconErrorText: '',\n  },\n];\n\nconst listData = {\n  title: '技术成长',\n  list,\n};\n\nexport default listData;\n"
  },
  {
    "path": "src/views/navigation/data/list/_o_community.ts",
    "content": "import type { NavList } from '../index';\n\nconst list: NavList = [\n  {\n    icon: '//img10.360buyimg.com/imgzone/jfs/t1/186536/13/4431/3960/60a78f0bE4ad7f0a3/171ce78b77cc7e6a.png',\n    name: '稀土掘金',\n    link: 'https://juejin.cn',\n    iconErrorText: '',\n  },\n  {\n    icon: '//img10.360buyimg.com/imgzone/jfs/t1/183316/16/5315/4826/60a78f0bE6e6ab8c1/6ffac998c8ac18b3.png',\n    name: 'CSDN',\n    link: 'https://blog.csdn.net',\n    iconErrorText: '',\n  },\n  {\n    icon: '//img10.360buyimg.com/imgzone/jfs/t1/179072/12/5303/3635/60a78f0bE1f852fa0/ee5324fbf9a8a6ac.png',\n    name: '知乎',\n    link: 'https://www.zhihu.com',\n    iconErrorText: '',\n  },\n  {\n    icon: '//img10.360buyimg.com/imgzone/jfs/t1/175106/7/10878/4308/60a78f0bEe6f042bf/51a6d7e23be70abb.png',\n    name: '简书',\n    link: 'https://www.jianshu.com',\n    iconErrorText: '',\n  },\n  {\n    icon: '//img10.360buyimg.com/imgzone/jfs/t1/171853/3/11304/4673/60ab1010E35acf458/3a07a327d7610b7a.png',\n    name: '吾爱论坛',\n    link: 'https://www.52pojie.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://img0.baidu.com/it/u=79953717,2799506716&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500',\n    name: '博客园',\n    link: 'https://www.cnblogs.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://static.segmentfault.com/main_site_next/42386ea6/touch-icon.png',\n    name: 'segmentfault',\n    link: 'https://segmentfault.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://static2.cnodejs.org/public/images/cnode_icon_32.png',\n    name: 'CNode',\n    link: 'https://cnodejs.org/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://static.oschina.net/new-osc/img/favicon.ico',\n    name: '开源中国',\n    link: 'https://www.oschina.net/',\n    iconErrorText: '',\n  },\n];\n\nconst listData = {\n  title: '技术社区',\n  list,\n};\n\nexport default listData;\n"
  },
  {
    "path": "src/views/navigation/data/list/w_drawPicture.ts",
    "content": "import type { NavList } from '../index';\n\nconst list: NavList = [\n  {\n    icon: 'https://nrdstudio.cn/res/logo.png',\n    name: '享岚脑图',\n    link: 'https://nrdstudio.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.gaituya.com/favicon.ico',\n    name: '改图鸭',\n    link: 'https://www.gaituya.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.processon.com/favicon.ico',\n    name: 'ProcessOn',\n    link: 'https://www.processon.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.isheji.com/isheji_favicon.ico',\n    name: '智能抠图',\n    link: 'https://www.isheji.com/cutout/workbench?img_id=60c9b7284a9a3',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://app.diagrams.net/images/favicon-32x32.png',\n    name: 'Draw.io',\n    link: 'https://app.diagrams.net/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://imgse.com/content/images/system/favicon_1587118523486_91617a.png',\n    name: '路过图床',\n    link: 'https://imgse.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'http://zhongguose.com/favicon.ico',\n    name: '中国传统颜色',\n    link: 'http://zhongguose.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.pexels.com/assets/static/images/meta/apple-touch-icon.png',\n    name: 'Pexels',\n    link: 'https://www.pexels.com/zh-cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://616pic.com/favicon.ico',\n    name: '图精灵',\n    link: 'https://616pic.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://wall.alphacoders.com/favicon.ico',\n    name: 'allpaper Abyss',\n    link: 'https://wall.alphacoders.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://pic.netbian.com/favicon.ico',\n    name: '彼岸图网',\n    link: 'https://pic.netbian.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://unsplash.com/favicon.ico',\n    name: 'unsplash',\n    link: 'https://unsplash.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.fontspace.com/favicon.ico',\n    name: '免费字体',\n    link: 'https://www.fontspace.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://wallhaven.cc/favicon.ico',\n    name: 'Awesome Wallpapers',\n    link: 'https://wallhaven.cc/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.qijishow.com/img/ico.ico',\n    name: '奇迹秀',\n    link: 'https://www.qijishow.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://ps.gaoding.com/favicon.ico',\n    name: '在线PS',\n    link: 'https://ps.gaoding.com/#/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.pixilart.com/images/favicon/favicon-32x32.png?v=jw6qNMPWz4',\n    name: '像素风格制作',\n    link: 'https://www.pixilart.com/draw',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://c-ssl.dtstatic.com/uploads/icons/duitang_favicon.ico',\n    name: '堆糖',\n    link: 'https://www.duitang.com/',\n    iconErrorText: '',\n  },\n];\n\nconst listData = {\n  title: '找图作图',\n  list,\n};\n\nexport default listData;\n"
  },
  {
    "path": "src/views/navigation/data/list/x_audioVideo.ts",
    "content": "import type { NavList } from '../index';\n\nconst list: NavList = [\n  {\n    icon: 'https://www.nkvod.com/mxtheme/images/favicon.png',\n    name: '耐看点播',\n    link: 'https://www.nkvod.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: '',\n    name: 'Listen1',\n    link: 'https://listen1.github.io/listen1/',\n    iconErrorText: '',\n  },\n  {\n    icon: '',\n    name: 'VIP视频在线解析',\n    link: 'https://www.yijingying.com/html/video/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://lxmusic.toside.cn/img/favicon.ico',\n    name: 'LX Music',\n    link: 'https://lxmusic.toside.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.manmankan.com/favicon.ico',\n    name: '漫漫看',\n    link: 'https://www.manmankan.com/dy2013/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.meijutt.tv/favicon.ico',\n    name: '美剧天堂',\n    link: 'https://www.meijutt.tv/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://img95.699pic.com/xsj/03/gv/6e.jpg%21/fw/700/watermark/url/L3hzai93YXRlcl9kZXRhaWwyLnBuZw/align/southeast',\n    name: '电影天堂',\n    link: 'https://dy.dytt8.net/index2.htm',\n    iconErrorText: '',\n  },\n  {\n    icon: '//img10.360buyimg.com/imgzone/jfs/t1/175602/32/10753/6436/60a788aaEcd9d368c/c70edec8e418ef15.png',\n    name: '优酷视频',\n    link: 'https://www.youku.com',\n    iconErrorText: '',\n  },\n  {\n    icon: '//img10.360buyimg.com/imgzone/jfs/t1/174971/9/10559/3897/60a789e9E06a8ff80/1d76f1a9a1948bab.png',\n    name: '爱奇艺视频',\n    link: 'https://www.iqiyi.com',\n    iconErrorText: '',\n  },\n  {\n    icon: '//img10.360buyimg.com/imgzone/jfs/t1/178133/4/5313/5149/60a789e9E53ca6456/93962a3ad2207a1f.png',\n    name: '芒果视频',\n    link: 'https://www.mgtv.com',\n    iconErrorText: '',\n  },\n  {\n    icon: '//img10.360buyimg.com/imgzone/jfs/t1/174642/31/11085/4236/60ab0e5eEae1f6f4e/4de8481661d812e3.png',\n    name: '哔哩哔哩',\n    link: 'https://www.bilibili.com',\n    iconErrorText: '',\n  },\n  {\n    icon: '//img10.360buyimg.com/imgzone/jfs/t1/193408/32/4343/6479/60a78929E4303368d/c342786431ace070.png',\n    name: '腾讯视频',\n    link: 'https://v.qq.com',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://lol.qq.com/favicon.ico',\n    name: '英雄联盟赛事官网',\n    link: 'https://lpl.qq.com',\n    iconErrorText: '',\n  },\n  {\n    icon: '//img10.360buyimg.com/imgzone/jfs/t1/187918/2/5444/8610/60b0bc77Edf1444c4/f714caae245d0d79.png',\n    name: '虎牙直播',\n    link: 'https://www.huya.com',\n    iconErrorText: '',\n  },\n  {\n    icon: '//img10.360buyimg.com/imgzone/jfs/t1/196801/11/5211/8955/60b0bc77Ed6fa9536/c2bc9d6ec1217ee0.png',\n    name: '斗鱼直播',\n    link: 'https://www.douyu.com',\n    iconErrorText: '',\n  },\n];\n\nconst listData = {\n  title: '影视音乐',\n  list,\n};\n\nexport default listData;\n"
  },
  {
    "path": "src/views/navigation/data/list/y_navigation.ts",
    "content": "import type { NavList } from '../index';\n\nconst list: NavList = [\n  {\n    icon: 'https://www.zkdh.net/wp-content/uploads/2020/05/ic_launcher.png',\n    name: '掌酷影音导航',\n    link: 'https://www.zkdh.net/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://media.ailongmiao.com/uploads/2021/09/favicon.png',\n    name: '龙猫网址导航',\n    link: 'https://ailongmiao.com/web/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://image.uisdc.com/wp-content/uploads/2018/09/nav-dkt-new2018.jpg',\n    name: '优设网址导航',\n    link: 'https://hao.uisdc.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'http://www.sankedan.com/static/assets/demo/default/media/img/logo/favicon.ico',\n    name: '三颗蛋导航',\n    link: 'http://www.sankedan.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://mp-b28966cb-26bc-43ae-b98b-aa286fad0729.cdn.bspapp.com/cloudstorage/31e91b77-d492-4f27-9ce1-d20ad54ad8e2.ico',\n    name: '前端导航',\n    link: 'https://www.5cv.top/',\n    iconErrorText: '',\n  },\n];\n\nconst listData = {\n  title: '导航集合',\n  list,\n};\n\nexport default listData;\n"
  },
  {
    "path": "src/views/navigation/data/list/z_something.ts",
    "content": "import type { NavList } from '../index';\n\nconst list: NavList = [\n  {\n    icon: 'http://user.vipmall.cc/Public/H5/images/favicon.ico',\n    name: '低价会员商城',\n    link: 'http://user.vipmall.cc/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://cat2.imiku.me/favicon-32x32.png',\n    name: '文心AI',\n    link: 'https://cat2.imiku.me/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.mujicv.com/favicon.ico',\n    name: '木及简历',\n    link: 'https://www.mujicv.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://static-public.infinitytab.com/sites-resource/extfans/61ea85a31aec3f3365dbe165/icon_1642759665914.jpg',\n    name: 'Chrome插件下载',\n    link: 'https://www.extfans.com/favicon.ico',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://www.yutu.cn/favicon.ico',\n    name: '羽兔网软件下载',\n    link: 'https://www.yutu.cn/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://codeium.com/favicon.ico',\n    name: 'codeium',\n    link: 'https://codeium.com/',\n    iconErrorText: '',\n  },\n  {\n    icon: 'https://search.tiangong.cn/favicon.ico',\n    name: '天工AI搜索',\n    link: 'https://search.tiangong.cn/',\n    iconErrorText: '',\n  },\n];\n\nconst listData = {\n  title: '奇奇怪怪',\n  list,\n};\n\nexport default listData;\n"
  },
  {
    "path": "src/views/navigation/index.vue",
    "content": "\r\n<template>\r\n  <div ref=\"navigation\" class=\"navigation-view\">\r\n    <div class=\"container\">\r\n      <div class=\"sidebar-list\">\r\n        <div\r\n          v-for=\"(sidebarItem, sidebarIndex) in sidebarList\"\r\n          :key=\"sidebarIndex\"\r\n          class=\"sidebar-item cp\"\r\n          :class=\"{ active: sidebarIndex === currentIndex }\"\r\n          @click=\"jumpToClickNavBlock(sidebarIndex)\">\r\n          {{ sidebarItem }}\r\n        </div>\r\n      </div>\r\n      <div class=\"nav-block-list\">\r\n        <template v-for=\"(blockItem, navBlockIndex) in data\">\r\n          <div\r\n            v-if=\"!blockItem.isPrivate || isShowPrivate\"\r\n            ref=\"navBlockItem\"\r\n            :key=\"navBlockIndex\"\r\n            class=\"nav-block-item\">\r\n            <div class=\"nav-block-title fwb\">{{ blockItem.title }}</div>\r\n            <div class=\"nav-instance-list\">\r\n              <div\r\n                v-for=\"(navItem, navIndex) in blockItem.list\"\r\n                :key=\"navIndex\"\r\n                class=\"nav-instance-item text-over-flow\">\r\n                <div class=\"curser-part cp\" @click=\"handleGoToLink(navItem.link)\">\r\n                  <img\r\n                    v-if=\"!navItem.iconErrorText\"\r\n                    :src=\"navItem.icon\"\r\n                    class=\"icon\"\r\n                    @error=\"handlerImgError(navBlockIndex, navIndex, navItem.name)\" />\r\n                  <div v-else class=\"icon-error-text\">{{ navItem.iconErrorText }}</div>\r\n                  <span class=\"name\"> {{ navItem.name }}</span>\r\n                </div>\r\n              </div>\r\n            </div>\r\n          </div>\r\n        </template>\r\n      </div>\r\n    </div>\r\n    <div class=\"footer\"></div>\r\n  </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ref, onMounted, onBeforeUnmount, computed, nextTick } from 'vue';\r\nimport { useRoute } from 'vue-router';\r\nimport data from './data';\r\n\r\nconst route = useRoute();\r\n// margin 的高度\r\nconst MARGIN_HEIGHT = 32;\r\n// header 的高度\r\nconst HEADER_HEIGHT = 64;\r\n// 获取整个页面元素(除header外)\r\nconst navigation = ref<null | HTMLDivElement>(null);\r\n// 获取所有的导航块\r\nconst navBlockItem = ref<Array<null | HTMLDivElement>>([]);\r\n// 保存所有的导航块需要滚动的高度\r\nconst scrollHeightArr = ref<number[]>([]);\r\n// 当前激活的导航块\r\nconst currentIndex = ref<number>(0);\r\n// 是否显示私有部分\r\nconst isShowPrivate = computed(() => route.query.private || false);\r\n// 侧边栏列表\r\nconst sidebarList = computed(() => {\r\n  let res = [];\r\n  if (isShowPrivate.value) {\r\n    res = data.value.map((item) => item.title);\r\n  } else {\r\n    res = data.value.filter((item) => !item.isPrivate).map((item) => item.title);\r\n  }\r\n  return res;\r\n});\r\n\r\n// 页面监听的滚动事件\r\nconst handleScroll = (e: Event) => {\r\n  const { scrollTop } = e.target as HTMLDivElement;\r\n  // 节流函数\r\n  requestAnimationFrame(() => {\r\n    // 根据当前滚动的高度和每个导航块需要滚动的高度进行对比, 获取当前激活的导航块索引\r\n    currentIndex.value = scrollHeightArr.value.findIndex((item) => scrollTop < item);\r\n  });\r\n};\r\n// 计算所有导航块需要滚动的高度\r\nconst getScrollHeightArr = () => {\r\n  navBlockItem.value.forEach((item) => {\r\n    // 通过 getBoundingClientRect 方法, 获取每个导航块到顶部的距离\r\n    const { top } = JSON.parse(JSON.stringify(item?.getBoundingClientRect()));\r\n    // 因为只需要滚动到 header 下面就算切换, 而不需要完全滚动到页面之外, 所以需要去掉 header 的高度\r\n    scrollHeightArr.value.push(top - HEADER_HEIGHT);\r\n  });\r\n};\r\n// 跳转到点击的导航块\r\nconst jumpToClickNavBlock = (clickIndex: number) => {\r\n  // 保存下点击的 index\r\n  currentIndex.value = clickIndex;\r\n  // 跳转到对应的导航块\r\n  navigation.value?.scrollTo({\r\n    // 平滑过渡\r\n    behavior: 'smooth',\r\n    // 加上一个 margin 的距离比较好看\r\n    top: scrollHeightArr.value[currentIndex.value] - MARGIN_HEIGHT,\r\n  });\r\n};\r\n\r\n// 图片发生错误的时候替换词名字的第一个字\r\nconst handlerImgError = (navBlockIndex: number, navIndex: number, name: string) => {\r\n  const [changeName] = name;\r\n  data.value[navBlockIndex].list[navIndex].iconErrorText = changeName;\r\n};\r\n\r\n// 跳转到对应的连接\r\nconst handleGoToLink = (link: string) => {\r\n  window.open(link);\r\n};\r\n\r\nonMounted(() => {\r\n  // 监听 navigation 的滚动事件\r\n  navigation.value?.addEventListener('scroll', handleScroll, false);\r\n  // 在页面渲染完成后计算所有导航块需要滚动的高度\r\n  nextTick(() => {\r\n    getScrollHeightArr();\r\n  });\r\n});\r\nonBeforeUnmount(() => {\r\n  // 在页面销毁的时候移除监听的事件\r\n  navigation.value?.removeEventListener('scroll', handleScroll, false);\r\n});\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n.navigation-view {\r\n  padding-top: var(--warbler-header-height);\r\n  width: 100%;\r\n  height: 100%;\r\n  overflow: auto;\r\n\r\n  .container {\r\n    width: 100%;\r\n    display: flex;\r\n\r\n    .sidebar-list {\r\n      @media (max-width: 900px) {\r\n        display: none;\r\n      }\r\n      position: fixed;\r\n      width: 100px;\r\n      height: 80vh;\r\n      overflow: auto;\r\n      top: 96px;\r\n      left: 32px;\r\n\r\n      &::-webkit-scrollbar {\r\n        // 隐藏滚动条\r\n        display: none;\r\n      }\r\n\r\n      .sidebar-item {\r\n        margin-bottom: 8px;\r\n        font-size: 14px;\r\n        &:hover {\r\n          color: var(--warbler-brand);\r\n        }\r\n      }\r\n      .active {\r\n        color: var(--warbler-brand);\r\n      }\r\n    }\r\n\r\n    .nav-block-list {\r\n      flex: 1;\r\n      padding-right: 15%;\r\n      padding-left: 15%;\r\n      @media (max-width: 900px) {\r\n        padding-left: 16px;\r\n        padding-right: 16px;\r\n      }\r\n      display: flex;\r\n      flex-direction: column;\r\n      width: 100%;\r\n      .nav-block-item {\r\n        width: 100%;\r\n        min-height: 100px;\r\n        border-radius: 10px;\r\n        margin-top: 32px;\r\n        background-color: var(--warbler-bg-soft);\r\n        .nav-block-title {\r\n          border-bottom: var(--warbler-border-1);\r\n          padding: 16px 32px;\r\n        }\r\n        .nav-instance-list {\r\n          padding: 8px 32px;\r\n          display: grid;\r\n          justify-content: space-between;\r\n          grid-template-columns: repeat(auto-fill, 200px);\r\n          grid-gap: 16px;\r\n        }\r\n        .nav-instance-item {\r\n          height: 32px;\r\n          display: flex;\r\n          justify-content: flex-start;\r\n          align-items: center;\r\n          .curser-part {\r\n            display: flex;\r\n            justify-content: flex-start;\r\n            align-items: center;\r\n          }\r\n          .icon {\r\n            width: 20px;\r\n            height: 20px;\r\n            margin-right: 8px;\r\n          }\r\n          .icon-error-text {\r\n            width: 20px;\r\n            height: 20px;\r\n            margin-right: 8px;\r\n            text-align: center;\r\n            line-height: 20px;\r\n            background-color: var(--warbler-brand-dark);\r\n            border-radius: 50%;\r\n            font-size: 12px;\r\n          }\r\n          .name {\r\n            &:hover {\r\n              color: var(--warbler-brand-dark);\r\n            }\r\n          }\r\n        }\r\n      }\r\n    }\r\n  }\r\n  .footer {\r\n    width: 100%;\r\n    height: 32px;\r\n  }\r\n}\r\n</style>\r\n"
  },
  {
    "path": "src/views/warblerCenter/component/resume-job.vue",
    "content": "\n<template>\n  <div class=\"projects\">\n    <div class=\"title\">工作经历</div>\n    <div class=\"job mt8\">\n      <div class=\"header\">\n        <!-- <div class=\"company\">北京理想研发总部（组员）</div> -->\n        <div class=\"time\">\n          <!-- 2023 年 6 月至今 -->\n        </div>\n      </div>\n      <div class=\"job-content\">\n        <div class=\"job-content-item\"><span>·</span>简历目前是个初版，还未完善，以下只是极小部分</div>\n      </div>\n    </div>\n    <div class=\"job mt8\">\n      <div class=\"header\">\n        <div class=\"company\">启迪万众网络 - 信息集成（团队负责人，3人）</div>\n        <div class=\"time\">2022 年 3 月至 至今</div>\n      </div>\n      <div class=\"job-content\">\n        <div class=\"job-content-item\">\n          <span>·</span>负责页面开发和维护，任务分配，代码审查，设计原型；\n        </div>\n        <div class=\"job-content-item\">\n          <span>·</span>通过 <strong>vue-cli</strong> ， 结合\n          <strong>eslint + prettier + husky + lint-staged + commitlint </strong>\n          搭建现代化前端工程；\n        </div>\n        <div class=\"job-content-item\">\n          <span>·</span>制定前端开发规范，通过 <strong>Pull Requests</strong> 进行代码审查 ,\n          定期组织 <strong>Code Review</strong> 会议；\n        </div>\n        <div class=\"job-content-item\">\n          <span>·</span>二次封装\n          <strong>axios</strong>\n          ，通过配置请求，响应拦截器，统一处理接口返回结果，添加全局的 loading，message；\n        </div>\n        <div class=\"job-content-item\">\n          <span>·</span>通过<strong> echars </strong>实现数据可视化以及地图部分的需求；\n        </div>\n        <div class=\"job-content-item\">\n          <span>·</span>通过<strong> antv-x6 </strong>实现流程图部分的需求；\n        </div>\n\n        <div class=\"job-content-item\">\n          <span>·</span>通过<strong> fabric.js </strong>实现视频，图片标注部分的需求；\n        </div>\n        <div class=\"job-content-item\">\n          <span>·</span>通过<strong> vite-press </strong>搭建用户帮助文档；\n        </div>\n        <div class=\"job-content-item\">\n          <span>·</span>通过<strong> Axure</strong> 完成原型设计，与 UI 人员进行交涉。\n        </div>\n      </div>\n    </div>\n    <div class=\"job mt8\">\n      <div class=\"header\">\n        <div class=\"company\">陕西繁星智达数字科技有限公司 - 云鹿CRM（组员）</div>\n        <div class=\"time\">2019 年 8 月 ~ 2022 年 2 月</div>\n      </div>\n      <div class=\"job-content\">\n        <div class=\"job-content-item\">\n          <span>·</span>独立负责 pc 端活动配置页面以及移动端活动的开发和维护；\n        </div>\n        <div class=\"job-content-item\">\n          <span>·</span>使用动态组件完成动态表单，通过配置文件让不同的活动拥有不同的表单内容；\n        </div>\n        <div class=\"job-content-item\">\n          <span>·</span>开发公用基础组件，如九宫格 ， 大转盘等供团队使用。\n        </div>\n      </div>\n    </div>\n  </div>\n  <div class=\"open mt16 mb16\">\n    <div class=\"title\">开源作品</div>\n    <div class=\"job\">\n      <div class=\"header\">\n        <div class=\"company\">江城开朗的豌豆</div>\n        <div class=\"time\">成为前端开发工程师至今</div>\n      </div>\n      <div class=\"job-content\">\n        <div class=\"job-content-item\">\n          <span>·</span>前端导航页面：通过监听 scroll 事件及高度的计算，完成双向滚动；\n        </div>\n        <div class=\"job-content-item\">\n          <span>·</span>warbler-cli：通过 Commander 实现快速创建项目的脚手架工具；\n        </div>\n        <div class=\"job-content-item\">\n          <span>·</span>warbler-js：一个 JavaScript 函数工具库，上传至 NPM 供其他人使用；\n        </div>\n        <div class=\"job-content-item\">\n          <span>·</span>warbler-favorites：通过 Vue3 实现的一个网页收藏工具；\n        </div>\n        <div class=\"job-content-item\">\n          <span>·</span>通过 VitePress 完成 warbler-cli 和 warbler-js 的在线文档。\n        </div>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script setup lang=\"ts\"></script>\n\n<style lang=\"scss\" scoped>\n.mt8 {\n  margin-top: 8px;\n}\n\n.mt16 {\n  margin-top: 16px;\n}\n\n.mb16 {\n  margin-bottom: 16px;\n}\n\nstrong {\n  color: var(--warbler-brand);\n  margin: 0 5px;\n}\n.projects,\n.open {\n  .title {\n    width: 100%;\n    font-size: 20px;\n    padding-bottom: 16px;\n    margin-bottom: 8px;\n    box-shadow: 0 -1px 0 hsla(0, 0%, 100%, 0.1) inset;\n  }\n  .job {\n    background-color: var(--warbler-bg);\n    padding: 16px;\n    border-radius: 4px;\n    .header {\n      display: flex;\n      justify-content: space-between;\n      margin: 0 0 16px 0;\n      font-size: 16px;\n      opacity: 0.7;\n    }\n    .job-content-item {\n      margin: 8px 16px;\n      align-items: center;\n\n      span {\n        font-size: 12px;\n        display: inline-block;\n        transform: scale(3);\n        margin-right: 8px;\n        color: var(--warbler-brand);\n      }\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "src/views/warblerCenter/component/resume-link.vue",
    "content": "\n<template>\n  <div class=\"resume-link\">\n    <div class=\"title\">相关连接</div>\n    <div v-for=\"(item, index) in map\" :key=\"index\" class=\"link-content-item\">\n      <div class=\"left\">\n        <span>·</span>\n        <div class=\"name\" @click=\"goToLink(item?.nameLink)\">{{ item.name }}</div>\n      </div>\n      <div class=\"right\">\n        <div v-if=\"item.online\" class=\"online\" @click=\"goToLink(item?.online)\">在线体验</div>\n        <div v-if=\"item.source\" class=\"source\" @click=\"goToLink(item?.source)\">源码地址</div>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\ninterface Link {\n  name: string;\n  nameLink?: string;\n  online?: string;\n  source?: string;\n}\n\nconst map: Array<Link> = [\n  {\n    name: 'CSDN',\n    nameLink: 'https://blog.csdn.net/qq_48652579?type=lately',\n    online: 'https://blog.csdn.net/qq_48652579?type=lately',\n    // source: 'https://github.com/alanhzw/warbler-homepage',\n  },\n  {\n    name: 'Github',\n    nameLink: 'https://github.com/yangtao5201314',\n    online: 'https://github.com/yangtao5201314',\n  },\n  {\n    name: 'Gitee',\n    nameLink: 'https://gitee.com/yangtaoqwer_admin_admin',\n    online: 'https://gitee.com/yangtaoqwer_admin_admin',\n  },\n  {\n    name: '掘金社区',\n    nameLink: 'https://juejin.cn/user/3307789418773736',\n    online: 'https://juejin.cn/user/3307789418773736',\n  },\n  {\n    name: 'UNIAPP',\n    nameLink: 'https://ext.dcloud.net.cn/plugin?id=11251',\n    online: 'https://ext.dcloud.net.cn/plugin?id=11251',\n  },\n  {\n    name: '微信公众号',\n    nameLink: 'https://tinyurl.com/gongZhonghao',\n    online: 'https://tinyurl.com/gongZhonghao',\n  },\n  {\n    name: '哔哩哔哩',\n    nameLink: 'https://space.bilibili.com/560080179',\n    online: 'https://space.bilibili.com/560080179',\n  },\n  {\n    name: '个人网站',\n    nameLink: 'https://tinyurl.com/yangtaoWeb',\n    online: 'https://tinyurl.com/yangtaoWeb',\n    source: 'https://github.com/yangtao5201314/my-blog',\n  },\n  \n  {\n    name: 'yangtao-js',\n    nameLink: 'https://7072-prod-4gapv4gl33a8a0ff-1305990777.tcb.qcloud.la/index.html?sign=cb4a9bd3d466506cf838f5149f68007c&t=1698832416',\n    online: 'https://7072-prod-4gapv4gl33a8a0ff-1305990777.tcb.qcloud.la/index.html?sign=cb4a9bd3d466506cf838f5149f68007c&t=1698832416',\n    source: 'https://github.com/yangtao5201314/yangtao-js',\n  },\n// {\n  //   name: 'warbler-cli',\n  //   nameLink: 'http://www.warblerfe.top/warbler/cli',\n  //   online: 'http://www.warblerfe.top/warbler/cli',\n  //   source: 'https://github.com/alanhzw/warbler-cli',\n  // },\n  // {\n  //   name: '个人主页(旧版)',\n  //   nameLink: 'https://alanhzw.github.io/',\n  //   online: 'https://alanhzw.github.io/',\n  //   source: 'https://github.com/alanhzw/warbler-homepage'\n  // },\n \n];\n\nconst goToLink = (link?: string) => {\n  if (link) {\n    window.open(link);\n  }\n};\n</script>\n\n<style lang=\"scss\" scoped>\n.resume-link {\n  width: 100%;\n  margin-bottom: 16px;\n\n  .mt8 {\n    margin-top: 8px;\n  }\n\n  .mt16 {\n    margin-top: 16px;\n  }\n\n  strong {\n    color: var(--warbler-brand);\n    margin: 0 5px;\n  }\n\n  .title {\n    width: 100%;\n    font-size: 20px;\n    padding-bottom: 16px;\n    margin-bottom: 8px;\n    box-shadow: 0 -1px 0 hsla(0, 0%, 100%, 0.1) inset;\n  }\n\n  .link-content-item {\n    background-color: var(--warbler-bg);\n    padding: 16px;\n    border-radius: 4px;\n    margin: 8px 0px;\n    align-items: center;\n    display: flex;\n    justify-content: space-between;\n\n    .left {\n      display: flex;\n      justify-content: flex-start;\n      align-items: center;\n\n      .name {\n        cursor: pointer;\n\n        &:hover {\n          color: var(--warbler-brand);\n        }\n      }\n    }\n\n    .right {\n      display: none;\n\n      @media (min-width: 1600px) or (max-width: 1500px) {\n        display: flex;\n        justify-content: flex-end;\n        align-items: center;\n      }\n\n      .online {\n        color: var(--warbler-brand-lighter);\n        cursor: pointer;\n\n        &:hover {\n          color: var(--warbler-brand);\n        }\n      }\n\n      .source {\n        color: var(--warbler-brand-lightest);\n        margin-left: 8px;\n        cursor: pointer;\n\n        &:hover {\n          color: var(--warbler-brand);\n        }\n      }\n    }\n\n    span {\n      font-size: 12px;\n      display: inline-block;\n      transform: scale(3);\n      margin-right: 8px;\n      color: var(--warbler-brand);\n    }\n  }\n}</style>\n"
  },
  {
    "path": "src/views/warblerCenter/component/resume-skills.vue",
    "content": "\n<template>\n  <div class=\"resume-skills\">\n    <div class=\"title\">技能</div>\n    <div class=\"skill-box\">\n      <div class=\"skill-content-item\">\n        <span>·</span>熟悉<strong> Vue </strong>，有多个实际项目开发经验，包括\n        <strong> Vue2 </strong>，<strong> Vue3 </strong>，<strong> Nuxt </strong>，<strong>\n          VitePress\n        </strong>\n        等；\n      </div>\n      <div class=\"skill-content-item\">\n        <span>·</span>熟悉<strong> ES6+ </strong>语法，了解 <strong>TypeScript</strong>；\n      </div>\n      <div class=\"skill-content-item\">\n        <span>·</span> 能够利用 <strong>commander </strong>等第三方库进行脚手架开发，了解<strong>\n          lerna </strong\n        >多仓库管理；\n      </div>\n      <div class=\"skill-content-item\">\n        <span>·</span>了解<strong> nodejs </strong>，可以使用 <strong> express </strong> ，<strong>\n          koa </strong\n        >， <strong> egg </strong>框架进行接口开发；\n      </div>\n      <div class=\"skill-content-item\">\n        <span>·</span>了解 <strong> mysql </strong>，<strong> mongodb </strong>，<strong>\n          redis </strong\n        >，掌握基本增删改查；\n      </div>\n      <div class=\"skill-content-item\">\n        <span>·</span>了解 <strong> docker </strong>，\n        <strong> github actions </strong>，前端静态化部署；\n      </div>\n      <div class=\"skill-content-item\">\n        <span>·</span>了解<strong> Photoshop </strong>，<strong> Axure </strong\n        >等工具，能够进行简易的原型设计。\n      </div>\n    </div>\n  </div>\n</template>\n\n<script setup lang=\"ts\"></script>\n\n<style lang=\"scss\" scoped>\n.resume-skills {\n  width: 100%;\n  margin-bottom: 16px;\n\n  .mt8 {\n    margin-top: 8px;\n  }\n\n  .mt16 {\n    margin-top: 16px;\n  }\n  strong {\n    color: var(--warbler-brand);\n    margin: 0 5px;\n  }\n  .title {\n    width: 100%;\n    font-size: 20px;\n    padding-bottom: 16px;\n    margin-bottom: 8px;\n    box-shadow: 0 -1px 0 hsla(0, 0%, 100%, 0.1) inset;\n  }\n  .skill-box {\n    background-color: var(--warbler-bg);\n    padding: 16px;\n    border-radius: 4px;\n    .skill-content-item {\n      margin: 8px 16px;\n      align-items: center;\n\n      span {\n        font-size: 12px;\n        display: inline-block;\n        transform: scale(3);\n        margin-right: 8px;\n        color: var(--warbler-brand);\n      }\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "src/views/warblerCenter/component/resume-warbler.vue",
    "content": "\n<template>\n  <div class=\"resume-warbler\">\n    <div class=\"header\">\n      <div class=\"avatar\"></div>\n      <div class=\"job\">前端工程师</div>\n    </div>\n    <div class=\"info\">\n      <div class=\"info-item\">姓名：杨涛</div>\n      <div class=\"info-item\">昵称：江城开朗的豌豆</div>\n      <div class=\"info-item\">年龄：24</div>\n      <div class=\"info-item\">坐标：西安</div>\n      <div class=\"info-item\">邮箱：yang_tao_web@163.com</div>\n      <div class=\"info-item\">微信：y_t_t_t_</div>\n      <div class=\"info-item\">学校：西安理工大学</div>\n      <div class=\"info-item\">专业：计算机科学与技术</div>\n    </div>\n    <div class=\"contact\">\n      <div class=\"words\">\n        江城开朗的豌豆是一个前端开发工程师，性格开朗，热爱分享和书写技术博客，\n        平时玩的游戏有QQ飞车，王者荣耀，和平精英，\n        <strong>目前正在启迪万众网络科技（北京）有限公司工作</strong>，如果你对我或我的技术感兴趣 ， 欢迎联系我\n      </div>\n    </div>\n    <div class=\"icons\">\n      <i class=\"iconfont icon icon-juejin\" @click=\"goToLink('juejin')\"></i>\n      <i class=\"iconfont icon icon-huaban88\" @click=\"goToLink('github')\"></i>\n      <i class=\"iconfont icon icon-weixin\" @click=\"goToLink('wechat')\"></i>\n    </div>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { useRouter } from 'vue-router';\n\nconst router = useRouter();\n\nconst goToLink = (type: string) => {\n  if (type === 'juejin') window.open('https://juejin.cn/user/3307789418773736');\n  if (type === 'github') window.open('https://github.com/yangtao5201314');\n  if (type === 'wechat') router.push({ path: '/contact' });\n};\n</script>\n\n<style lang=\"scss\" scoped>\n.resume-warbler {\n  width: 100%;\n\n  strong {\n    color: var(--warbler-brand);\n    margin: 0 5px;\n  }\n  .header {\n    width: 100%;\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    justify-content: flex-start;\n    box-shadow: 0 -1px 0 hsla(0, 0%, 100%, 0.1) inset;\n    .avatar {\n      width: 200px;\n      height: 200px;\n      border-radius: 50%;\n      background: url('@/assets/image/warbler1.jpeg');\n      background-size: 109%;\n      background-repeat: no-repeat;\n      background-position: -17px 0px;\n    }\n    .avatar:hover{\n      transform: rotate(666turn);\n    transition-delay: 1s;\n    transition-property: all;\n    transition-duration: 59s;\n    transition-timing-function: cubic-bezier(.34,0,.84,1);\n    }\n    .job {\n      font-size: 24px;\n      margin: 16px 0;\n      font-weight: bold;\n    }\n  }\n\n  .info {\n    margin: 8px 0 16px 0;\n    box-shadow: 0 -1px 0 hsla(0, 0%, 100%, 0.1) inset;\n    padding-bottom: 16px;\n    @media (min-width: 900px) {\n      display: flex;\n      flex-direction: column;\n    }\n    @media (max-width: 900px) {\n      display: grid;\n      justify-content: space-between;\n      grid-template-columns: repeat(auto-fill, 220px);\n    }\n\n    .info-item {\n      margin-top: 8px;\n    }\n  }\n\n  .contact {\n    .words {\n      line-height: 1.4;\n      letter-spacing: 1px;\n    }\n  }\n  .icons {\n    margin-top: 32px;\n    display: flex;\n    justify-content: center;\n    .icon {\n      cursor: pointer;\n      font-size: 24px;\n      margin: 8px;\n      &:hover {\n        color: var(--warbler-brand);\n      }\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "src/views/warblerCenter/hooks/getUserInfo.ts",
    "content": "\nimport { ref } from 'vue';\n\nimport service from './juejin';\n\nconst userInfo = ref({});\n\nconst useGetUserInfo = () => {\n  const getUserInfo = async () => {\n    const res = await service.get('/user', {\n      id: '4099422807393901',\n    });\n    console.log('🚀🚀 ~ res:', res);\n  };\n  return {\n    userInfo,\n    getUserInfo,\n  };\n};\n\nexport default useGetUserInfo;\n"
  },
  {
    "path": "src/views/warblerCenter/hooks/juejin.ts",
    "content": "import axios from 'axios';\nimport type { AxiosInstance } from 'axios';\n\nconst BASE_URL = '/juejin_api';\nclass GiteeRequest {\n  instance!: AxiosInstance;\n\n  // eslint-disable-next-line no-use-before-define\n  static service: GiteeRequest = new GiteeRequest();\n\n  constructor() {\n    this.instance = axios.create({\n      baseURL: BASE_URL,\n      timeout: 500000,\n    });\n    this.instance.interceptors.response.use(\n      (response) => response.data,\n      (error) => {\n        Promise.reject(error);\n      },\n    );\n  }\n\n  get(url: string, params?: Record<string, any>, headers?: Record<string, any>) {\n    return this.instance({\n      url,\n      params: {\n        ...params,\n      },\n      method: 'get',\n      headers,\n    });\n  }\n\n  post(url: string, data?: Record<string, any>, headers?: Record<string, any>) {\n    return this.instance({\n      url,\n      params: {},\n      data,\n      method: 'post',\n      headers,\n    });\n  }\n}\n\nexport default GiteeRequest.service;\n"
  },
  {
    "path": "src/views/warblerCenter/index.vue",
    "content": "\n<template>\n  <div class=\"warbler-center\">\n    <div class=\"layout\">\n      <left-part></left-part>\n      <middle-part></middle-part>\n      <right-part></right-part>\n    </div>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nimport leftPart from './part/left-part.vue';\nimport middlePart from './part/middle-part.vue';\nimport rightPart from './part/right-part.vue';\n</script>\n\n<style lang=\"scss\" scoped>\n.warbler-center {\n  display: flex;\n  padding-top: var(--warbler-header-height);\n  width: 100%;\n  height: 100%;\n  min-height: 600px;\n  .layout {\n    width: 100%;\n    height: 100%;\n    display: flex;\n    padding: 32px;\n    @media (max-width: 900px) {\n      padding: 16px;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "src/views/warblerCenter/part/left-part.vue",
    "content": "\n<template>\n  <div class=\"left-part\">\n    <resume-warbler></resume-warbler>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nimport resumeWarbler from '../component/resume-warbler.vue';\n</script>\n\n<style lang=\"scss\" scoped>\n.left-part {\n  @media (max-width: 900px) {\n    display: none;\n  }\n  width: 250px;\n  height: 100%;\n  background-color: var(--warbler-bg-soft);\n  border-radius: 10px;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: flex-start;\n  padding: 16px;\n  overflow: auto;\n  position: relative;\n  &::-webkit-scrollbar {\n    // 隐藏滚动条\n    display: none;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/views/warblerCenter/part/middle-part.vue",
    "content": "\n<template>\n  <div class=\"middle-part\">\n    <resume-warbler class=\"resume-warbler-component\"></resume-warbler>\n    <resume-skills class=\"resume-skills-component\"></resume-skills>\n    <resume-job></resume-job>\n    <resume-link class=\"resume-link-component\"></resume-link>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nimport resumeWarbler from '../component/resume-warbler.vue';\nimport resumeSkills from '../component/resume-skills.vue';\nimport resumeJob from '../component/resume-job.vue';\nimport resumeLink from '../component/resume-link.vue';\n</script>\n\n<style lang=\"scss\" scoped>\n.resume-skills-component,\n.resume-link-component {\n  @media (min-width: 1500px) {\n    display: none;\n  }\n}\n.resume-warbler-component {\n  @media (min-width: 900px) {\n    display: none;\n  }\n}\n.middle-part {\n  height: 100%;\n  @media (max-width: 1500px) {\n    flex: 1;\n  }\n  @media (max-width: 900px) {\n    margin-left: 0px;\n  }\n  margin-left: 16px;\n  background-color: var(--warbler-bg-soft);\n  border-radius: 10px;\n  display: flex;\n  flex-direction: column;\n  justify-content: flex-start;\n  padding: 16px;\n  overflow: auto;\n  &::-webkit-scrollbar {\n    // 隐藏滚动条\n    display: none;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/views/warblerCenter/part/right-part.vue",
    "content": "\n<template>\n  <div class=\"right-part\">\n    <resume-skills></resume-skills>\n    <resume-link></resume-link>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nimport resumeSkills from '../component/resume-skills.vue';\nimport resumeLink from '../component/resume-link.vue';\n</script>\n\n<style lang=\"scss\" scoped>\n.right-part {\n  flex: 1;\n  margin-left: 16px;\n  height: 100%;\n  background-color: var(--warbler-bg-soft);\n  border-radius: 10px;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: flex-start;\n  padding: 16px;\n  overflow: auto;\n  &::-webkit-scrollbar {\n    // 隐藏滚动条\n    display: none;\n  }\n\n  @media (max-width: 1500px) {\n    display: none;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/views/warblerCli/index.vue",
    "content": "<template>\n  <iframe\n    ref=\"iframe\"\n    :src=\"domain\"\n    style=\"display: block\"\n    background=\"transparent\"\n    width=\"100%\"\n    allow=\"clipboard-read;clipboard-write\"\n    height=\"100%\"\n    frameborder=\"0\"></iframe>\n  <div v-if=\"loading\" class=\"spinner-box\">\n    <div class=\"spinner\"></div>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, onMounted } from 'vue';\n\nconst domain = computed(() => import.meta.env.VITE_WARBLER_CLI_DOMAIN);\nconst iframe = ref<null | HTMLElement>(null);\nconst loading = ref(true);\nonMounted(() => {\n  iframe.value!.onload = () => {\n    loading.value = false;\n  };\n});\n</script>\n\n<style lang=\"scss\" scoped>\n.spinner-box {\n  width: 100vw;\n  height: 100vh;\n  position: fixed;\n  top: 0;\n  left: 0;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  z-index: 9999;\n}\n</style>\n"
  },
  {
    "path": "src/views/warblerJs/index.vue",
    "content": "<template>\n  <iframe\n    ref=\"iframe\"\n    style=\"display: block\"\n    :src=\"domain\"\n    width=\"100%\"\n    allow=\"clipboard-read;clipboard-write\"\n    height=\"100%\"\n    frameborder=\"0\"\n    background=\"transparent\"></iframe>\n  <div v-if=\"loading\" class=\"spinner-box\">\n    <div class=\"spinner\"></div>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { computed, ref, onMounted } from 'vue';\n\n// const domain = computed(() => import.meta.env.VITE_WARBLER_JS_DOMAIN);  \nconst domain = 'https://tinyurl.com/yangtao-js';  \n\nconst iframe = ref<null | HTMLElement>(null);\nconst loading = ref(true);  \nonMounted(() => {\n  iframe.value!.onload = () => {\n    loading.value = false;\n  };\n});\n</script>\n\n<style lang=\"scss\" scoped>\n.spinner-box {\n  width: 100vw;\n  height: 100vh;\n  position: fixed;\n  top: 0;\n  left: 0;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  z-index: 9999;\n}\n</style>\n"
  },
  {
    "path": "src/vite-env.d.ts",
    "content": "/// <reference types=\"vite/client\" />\ninterface ImportMetaEnv {\n  readonly VITE_WARBLER_JS_DOMAIN: string;\n  readonly VITE_WARBLER_CLI_DOMAIN: string;\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\r\n  \"compilerOptions\": {\r\n    // 编译之后的 es 版本\r\n    \"target\": \"ESNext\",\r\n    // 是否保留 class 未赋值的属性\r\n    \"useDefineForClassFields\": true,\r\n    // 编译之后的文件采用的模块规范\r\n    \"module\": \"ESNext\",\r\n    /*\r\n      moduleResolution 模块解析\r\n      模块解析是 typescript 编译器用何种方式来确定导入所指内容。\r\n      moduleResolution: \"node\" =>采用 node 模块解析的方式查找文件。[从内层到最高目录的外层查找 import 引入的文件]\r\n      moduleResolution:\"classic\"=> 采用 classic 模块解析的方式查找文件。[从外层到内层方式查找查找 import 引入的文件]\r\n      moduleResolution\": \"node\"\r\n    */\r\n    \"moduleResolution\": \"Node\",\r\n    // 开启严格模式\r\n    \"strict\": true,\r\n    // 使用 jsx 语法\r\n    \"jsx\": \"preserve\",\r\n    // 允许引入 ts 文件\r\n    \"resolveJsonModule\": true,\r\n    // ts 文件必须导出模块 ,并且导出类型必须添加 type\r\n    \"isolatedModules\": true,\r\n    // 有些依赖库底层 为了在CommonJs、AMD这二者的规范中相互兼容，使用了 export =，将二者规范统一。\r\n    // 表示允许依赖库中出现 export = 这种兼容规范导出的格式，TS 可以用 import from 导入\r\n    \"esModuleInterop\": true,\r\n    // 允许访问的底层依赖库\r\n    \"lib\": [\"ESNext\", \"DOM\"],\r\n    // 对声明文件不进行类型检查\r\n    \"skipLibCheck\": true,\r\n    // 禁用从编译中发出文件\r\n    \"noEmit\": true,\r\n    // 基础url\r\n    \"baseUrl\": \"\",\r\n    // 设置别名\r\n    \"paths\": {\r\n      \"@/*\": [\"src/*\"],\r\n      \"@v/*\": [\"src/views/*\"],\r\n      \"@c/*\": [\"src/components/*\"],\r\n      \"@u/*\": [\"src/utils/*\"]\r\n    }\r\n  },\r\n  \"include\": [\"src/**/*.ts\", \"src/**/*.d.ts\", \"src/**/*.tsx\", \"src/**/*.vue\"],\r\n  \"references\": [{ \"path\": \"./tsconfig.node.json\" }]\r\n}\r\n"
  },
  {
    "path": "tsconfig.node.json",
    "content": "{\n  \"compilerOptions\": {\n    \"composite\": true,\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"Node\",\n    \"allowSyntheticDefaultImports\": true\n  },\n  \"include\": [\"vite.config.ts\"]\n}\n"
  },
  {
    "path": "vite.config.ts",
    "content": "import { defineConfig } from 'vite';\nimport vue from '@vitejs/plugin-vue';\nimport path from 'path';\n//\nexport default defineConfig(({ mode, command }) => {\n  // 获取当前的模式\n  console.log('🚀🚀 ~ 当前阶段', command);\n  console.log('🚀🚀 ~ 当前运行环境', mode);\n  return {\n    // base: './',\n    base: '/myblog/',\n    plugins: [vue()],\n    resolve: {\n      alias: {\n        '@': path.resolve(__dirname, 'src'),\n        '@v': path.resolve(__dirname, 'src/views'),\n        '@c': path.resolve(__dirname, 'src/components'),\n        '@u': path.resolve(__dirname, 'src/utils'),\n      },\n    },\n    server: {\n      proxy: {\n        '/juejin_api/': {\n          target: 'https://juejin.palxp.com/',\n          changeOrigin: true,\n          rewrite: (apiPath: string) => apiPath.replace(/^\\/juejin_api/, ''),\n        },\n      },\n    },\n  };\n});\n"
  }
]