├── .eslintrc.mjs
├── .github
└── workflows
│ ├── blog-catch-and-pages.yml
│ └── reademe-contributors.yml
├── .gitignore
├── .prettierrc.mjs
├── Q&A.md
├── README.md
├── README_EN.md
├── build
└── config.base.js
├── components
└── VTabs.vue
├── configurations.js
├── package-lock.json
├── package.json
└── works
├── apis
└── juejin.js
├── generator
├── index.js
├── juejin
│ ├── category.generator.js
│ ├── columns.generator.js
│ ├── overview.md.generator.js
│ ├── ranking-list.md.generator.js
│ ├── recent-top.md.generator.js
│ ├── tag.generator.js
│ ├── utils.js
│ └── years.generator.js
└── vitepress
│ ├── index.md.generator.js
│ ├── theme
│ ├── index.js
│ └── main.css
│ └── vitepress.generator.js
├── index.js
├── requests
└── juejin.js
├── store
├── configuration
│ └── index.js
├── index.js
└── juejin
│ └── index.js
├── template
├── index.js
└── vitepress
│ ├── vitepress.config.js
│ └── vitepress.index.md.js
├── utils
├── common.js
├── date-formatter.js
├── http-requester.js
└── template-process.js
└── website
└── juejin.js
/.eslintrc.mjs:
--------------------------------------------------------------------------------
1 | export default {
2 | root: true,
3 | env: {
4 | browser: true,
5 | node: true,
6 | es6: true,
7 | },
8 | rules: {
9 | "prettier/prettier": [
10 | "warn",
11 | {
12 | singleQuote: false, // 不使用单引号
13 | printWidth: 120, // 换行字符串阈值
14 | semi: true, // 句末加分号
15 | trailingComma: "none", // 最后一个对象元素加逗号
16 | },
17 | ],
18 | "vue/no-mutating-props": 0,
19 | "linebreak-style": 0,
20 | "no-unused-vars": 0,
21 | "no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
22 | "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
23 | },
24 | };
25 |
--------------------------------------------------------------------------------
/.github/workflows/blog-catch-and-pages.yml:
--------------------------------------------------------------------------------
1 | name: blog-catch-and-pages
2 | on:
3 | # 设置可以手动执行(参考:https://tongjunsz.gitee.io/2021/03/18/GitHub-Actions-%E6%89%8B%E5%8A%A8%E8%A7%A6%E5%8F%91%E6%96%B9%E5%BC%8F/)
4 | workflow_dispatch:
5 | push:
6 | branches:
7 | - main
8 |
9 | # 每天下午四点执行(也就是16点,需要-8小时,所以是8)
10 | schedule:
11 | - cron: "0 8 * * *"
12 |
13 | jobs:
14 | blog-catch-and-pages:
15 | runs-on: ubuntu-latest
16 | steps:
17 | - name: Checkout codes
18 | uses: actions/checkout@v3
19 |
20 | - name: Use Node.js
21 | uses: actions/setup-node@v3
22 | with:
23 | node-version: "18.x"
24 |
25 | - name: Clean up
26 | run: |
27 | rm -rf package-lock.json
28 | rm -rf node_modules
29 |
30 | - name: Install dependencies
31 | run: npm install
32 |
33 | - name: Sync juejin blog
34 | run: npm run sync:blog
35 |
36 | - name: Build
37 | run: npm run build:blog
38 |
39 | # 发布
40 | - name: Deploy
41 | uses: JamesIves/github-pages-deploy-action@v4
42 | with:
43 | GITHUB_TOKEN: ${{ secrets.PRESS_TOKEN_TEA_BLOG }}
44 | BRANCH: gh-pages
45 | FOLDER: docs/.vitepress/dist
46 |
--------------------------------------------------------------------------------
/.github/workflows/reademe-contributors.yml:
--------------------------------------------------------------------------------
1 | # 监听 main 分支(参考来源:https://juejin.cn/post/7085631302484885512)
2 | on:
3 | push:
4 | branches:
5 | - main
6 |
7 | # action 名称
8 | name: reademe-contributors
9 |
10 | jobs:
11 | # 任务
12 | reademe-contributors-job:
13 | runs-on: ubuntu-latest
14 | name: A job to automate contrib in readme
15 | steps:
16 | - name: Contribute List
17 | uses: akhilmhdh/contributors-readme-action@v2.3.4
18 | env:
19 | GITHUB_TOKEN: ${{ secrets.PRESS_TOKEN_TEA_BLOG }}
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | docs/.vuepress/dist/*
2 | docs/*
3 | public/z-test/*
4 |
5 | .github/*
6 |
7 | # IDE
8 | .idea
9 | .vscode
10 |
11 | # Logs
12 | logs
13 | *.log
14 | npm-debug.log*
15 | yarn-debug.log*
16 | yarn-error.log*
17 | lerna-debug.log*
18 |
19 | # Diagnostic reports (https://nodejs.org/api/report.html)
20 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
21 |
22 | # Runtime data
23 | pids
24 | *.pid
25 | *.seed
26 | *.pid.lock
27 |
28 | # Directory for instrumented libs generated by jscoverage/JSCover
29 | lib-cov
30 |
31 | # Coverage directory used by tools like istanbul
32 | coverage
33 | *.lcov
34 |
35 | # nyc test coverage
36 | .nyc_output
37 |
38 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
39 | .grunt
40 |
41 | # Bower dependency directory (https://bower.io/)
42 | bower_components
43 |
44 | # node-waf configuration
45 | .lock-wscript
46 |
47 | # Compiled binary addons (https://nodejs.org/api/addons.html)
48 | build/Release
49 |
50 | # Dependency directories
51 | node_modules/
52 | jspm_packages/
53 |
54 | # TypeScript v1 declaration files
55 | typings/
56 |
57 | # TypeScript cache
58 | *.tsbuildinfo
59 |
60 | # Optional npm cache directory
61 | .npm
62 |
63 | # Optional eslint cache
64 | .eslintcache
65 |
66 | # Microbundle cache
67 | .rpt2_cache/
68 | .rts2_cache_cjs/
69 | .rts2_cache_es/
70 | .rts2_cache_umd/
71 |
72 | # Optional REPL history
73 | .node_repl_history
74 |
75 | # Output of 'npm pack'
76 | *.tgz
77 |
78 | # Yarn Integrity file
79 | .yarn-integrity
80 |
81 | # dotenv environment variables file
82 | .env
83 | .env.test
84 |
85 | # parcel-bundler cache (https://parceljs.org/)
86 | .cache
87 |
88 | # Next.js build output
89 | .next
90 |
91 | # Nuxt.js build / generate output
92 | .nuxt
93 | dist
94 |
95 | # Gatsby files
96 | .cache/
97 | # Comment in the public line in if your project uses Gatsby and *not* Next.js
98 | # https://nextjs.org/blog/next-9-1#public-directory-support
99 | # public
100 |
101 | # vitepress build output
102 | .vuepress/dist
103 |
104 | # Serverless directories
105 | .serverless/
106 |
107 | # FuseBox cache
108 | .fusebox/
109 |
110 | # DynamoDB Local files
111 | .dynamodb/
112 |
113 | # TernJS port file
114 | .tern-port
115 |
116 | .docs
117 | .vitepress
118 |
119 | *.user.js
120 |
--------------------------------------------------------------------------------
/.prettierrc.mjs:
--------------------------------------------------------------------------------
1 | export default {
2 | "printWidth": 120,
3 | "tabWidth": 2,
4 | "useTabs": false,
5 | "semi": false,
6 | "singleQuote": false
7 | }
8 |
--------------------------------------------------------------------------------
/Q&A.md:
--------------------------------------------------------------------------------
1 | ### 问题统计与解决方法
2 |
3 | #### ❓ Q1:Fork 操作部署后,会产生了什么,项目都跑了什么?
4 |
5 | 每天会更新一下,指定用户 or 指定专栏下的文章列表。如果新的文章,就会自动也添加进去了。
6 |
7 | 大致流程:github actions 启动 `blog-catch-and-pages` job, 脚本就去请求对应平台地址,进而获取完整的文章列表;
8 |
9 | 文章列表获取完成后,会处理内容进行筛选,并创建对应的 markdown 文件;
10 |
11 | 同时,生成 vuepress 的相关配置文件; 完成后,github pages 会自动构建一下。
12 |
13 | 最后,就能访问对应的地址了。(即 用户名.github.io )
14 |
15 | (注意:每日都是重新获取的文章列表,也就是每天都会重新构建新的。)
16 |
17 | #### ❓ Q2:如何获取 JUEJIN_USER_ID
18 |
19 | 掘金查看个人主页,个人主页链接后面的数字,即为`JUEJIN_USER_ID`
20 |
21 | > 例如: https://juejin.cn/user/2819602825362840
22 | >
23 | > `JUEJIN_COLUMN_ID` 为 2819602825362840
24 |
25 | #### ❓ Q3:如何获取 JUEJIN_COLUMN_ID
26 |
27 | 进入掘金专栏首页,该页面链接后面的数字,即为`JUEJIN_COLUMN_ID`
28 |
29 | > 例如: https://juejin.cn/column/7107151273765371941
30 | >
31 | > `JUEJIN_COLUMN_ID` 为 7107151273765371941
32 |
33 | #### ❓ Q4:如何创建 PRESS_TOKEN_TEA_BLOG
34 |
35 | 点击右上角头像 ——》 Setting ——》 跳到的个人 Setting 页 ——》 往下拉直到出现 Developer settings 并点击 ——》 Personal access tokens ——》 Tokens (classic) ——》 Generate new token ——》 Generate new token (classic)
36 |
37 | 也可参考 [创建个人访问令牌](https://docs.github.com/zh/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token)
38 |
39 | #### ❓ Q5:仓库有更新,同步步骤
40 |
41 | 仓库有更新时,在 Code 下会出现有 Sync fork ,点击并选择 Update branch,即完成同步仓库。(不影响原有功能)
42 |
43 | #### ❓ Q6:树状的目录显示用的是什么?
44 |
45 | 用的 **treer**。
46 |
47 | `npm install treer`
48 |
49 | `treer -d 项目名 -e treer.md -i "/node_modules|.git/"`
50 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## 当前机制
2 |
3 | 自动化执行任务: 获取指定掘金创作者文章列表与专栏信息,生成按发布年月、专栏、分类等多个维度的统计信息
4 |
5 | 自动化运行时间: 北京时间下午 `16:20` 左右
6 |
7 | ## 项目介绍
8 |
9 | 项目名:[**自动化同步文章平台(auto-sync-blog)**](https://juejin.cn/post/7210387904748503095)
10 |
11 | 作用:实现在写作平台(如掘金、CSDN、简书等)的每日能进行自动同步数据(文章标题和链接);同时,对文章进行友好的分类,并实现更直观的浏览那些年写过的文章。
12 |
13 | (目前仅支持掘金平台的同步,其他还在开发。)
14 |
15 | 涉及技术:**github actions**, **github pages**, **node**, **vitepress**
16 |
17 | ## 部署流程
18 |
19 | ### 直接部署流程(GitHub Fork)
20 |
21 | 1. [Fork 仓库](https://github.com/TeaTools/auto-sync-blog/fork)
22 | 2. 仓库 -> Settings -> Secrets -> New repository secret, 添加 Secrets 变量如下:
23 |
24 | | Name | Value | Required |
25 | | -------------------- | ------------------------------------------------------------- | -------- |
26 | | PRESS_TOKEN_TEA_BLOG | GitHub Personal access tokens,用户推送仓库,同步GitHub pages | 是 |
27 |
28 | 3. 更新仓库的 actions 权限:Settings -> Secret -> Actions -> General -> Workflow permissions -> 勾选 Read and write permissions -> Save.
29 | 4. 仓库 -> `configurations.js` 文件中替换个人信息并提交(该文件禁止随意 PR)。
30 | 5. 仓库 -> Actions, 检查 Workflows 并启用。
31 | 6. 更新仓库 Page 服务:Settings -> Pages -> Branch -> gh-pages (如果不出现 gh-pages 分支,重复第四步并检查是否已经完成。)-> Save
32 |
33 | ### 本地开发流程(Be Developer)
34 |
35 | 1. 安装依赖
36 | ```cmd
37 | npm install
38 | ```
39 |
40 | 2. 更新 configurations.js
41 |
42 | 3. 执行主入口,生成 vitepress 相关配置与 markdown 文件
43 | ```cmd
44 | npm run sync:blog
45 | ```
46 |
47 | 4. 启动项目
48 | ```cmd
49 | npm run dev:blog
50 | ```
51 |
52 | 5. 访问地址
53 | ```http
54 | http://localhost:5173/
55 | ```
56 |
57 | ## 目录结构
58 |
59 | ```cmd
60 | ./
61 | ├─ LICENSE
62 | ├─ package.json
63 | ├─ package-lock.json
64 | ├─ Q&A.md // 问题统计与解决方法
65 | ├─ README.md
66 | ├─ README_EN.md
67 | ├─ build // 构建相关
68 | | └ config.base.js // 自动生成文件的目录配置
69 | ├─ docs // 自动生成的 vitepress 内容
70 | | ├─ .vitepress
71 | | | | ├─ config // 由 vitepress.config.generator 生成的内容
72 | | | | └ theme // 复制的 theme 样式文件与插件配置
73 | | └ src // 自动生成的所有统计页面 markdown 文件
74 | ├─ works // 核心部分
75 | | ├─ apis // http api 请求地址
76 | | ├─ generator // 文件生成
77 | | ├─ requests // 网络请求部分
78 | | ├─ store // 全局数据处理与缓存
79 | | ├─ template // 各类模板文件
80 | | ├─ utils // 工具函数
81 | | ├─ website // 博客内生成的外链地址的配置信息
82 | ```
83 |
84 | ## 后续开发计划
85 |
86 | 1. 实现多个专栏(指定多个专栏,指定用户的所有专栏)
87 | 2. 实现收藏分类(指定收藏集)
88 | 3. 实现邮箱订阅(有更新给订阅的邮箱发送)
89 | 4. 实现支持更多平台的同步(如CSDN、简书等)
90 | 5. 实现更多便捷配置(百度统计,天气,音乐)
91 |
92 |
93 |
94 | ## 贡献者
95 |
96 |
97 |
135 |
136 |
137 | 欢迎各位英雄豪杰加入,共建更完美的 [**自动化同步文章平台(auto-sync-blog)**](https://juejin.cn/post/7210387904748503095) 。
138 |
139 | ## 问题回答(Question & Answer)
140 | Question & Answer
141 |
142 | ## License
143 | auto-sync-blog is under the [MIT license](LICENSE).
144 |
--------------------------------------------------------------------------------
/README_EN.md:
--------------------------------------------------------------------------------
1 | ## Current Mechanism
2 |
3 | Automated task execution: Fetch articles from a specified column of a specified user on Juejin, and update the article directory link to GitHub pages.
4 |
5 | Automated run time: Around 16:20 Beijing time.
6 |
7 | ## Project Introduction
8 |
9 | Project name: **Automated Article Synchronization Platform (auto-sync-blog)**
10 |
11 | Function: Achieve daily automatic synchronization of data (article titles and links) on writing platforms (such as Juejin, CSDN, JianShu, etc.); at the same time, categorize articles in a user-friendly manner, and provide a more intuitive browsing experience for articles written over the years. (Currently only supports synchronization of the Juejin platform, others are under development.)
12 |
13 | Involved technologies: **github actions**, **github pages**, **node**, **vuepress**
14 |
15 | ## Deployment Process
16 |
17 | ### Direct Deployment Process (GitHub Fork)
18 |
19 | 1. [Fork the repository](https://github.com/tea-blog/tea-blog.github.io)
20 | 2. Repository -> Settings -> Secrets -> New repository secret, add Secrets variables as follows:
21 |
22 | | Name | Value | Required |
23 | | -------------------- | ------------------------------------------------------------- | -------- |
24 | | JUEJIN_USER_ID | Juejin user id | Yes |
25 | | JUEJIN_COLUMN_ID | Juejin column id | Optional |
26 | | PRESS_TOKEN_TEA_BLOG | GitHub Personal access tokens, used to push to the repository, synchronize GitHub pages | Yes |
27 |
28 | 3. Update the repository's actions permissions: Settings -> Secret -> Actions -> General -> Workflow permissions -> Check Read and write permissions -> Save.
29 | 4. Repository -> Actions, check Workflows and enable them.
30 | 5. Settings -> Pages -> Branch -> gh-pages (If the gh-pages branch does not appear, repeat the fourth step and check if it has been completed.) -> Save
31 |
32 | ### Local Deployment Process (Be Developer)
33 |
34 | 1. Execute the main entry, generate vuepress related configuration (where juejin_user_id corresponds to a string of numbers after user/ on the personal homepage of Juejin)
35 | ```cmd
36 | node .\main.js --juejin_user_id=2819602825362840 --juejin_column_id=7140398633710518302
37 | ```
38 | 2. Install dependencies
39 | ```cmd
40 | npm install
41 | ```
42 | 3. Start the project
43 | ```cmd
44 | npm start
45 | ```
46 | 4. Visit the address
47 | ```http
48 | http://localhost:8080/
49 | ```
50 |
51 | ## Directory Structure
52 |
53 | ```cmd
54 | ./
55 | ├─main.js // Main entry
56 | ├─package-lock.json
57 | ├─package.json // Related dependencies and startup methods
58 | ├─README.md // Introduction
59 | ├─Q&A.md // Problem statistics and solutions
60 | ├─public // Main part
61 | | ├─z-test // Test
62 | | | └test.js
63 | | ├─utils // Method calls
64 | | | ├─ArticleUtils. // Article data processing
65 | | | ├─DateUtils.js // Time processing
66 | | | ├─FileUtils.js // File processing
67 | | | ├─Http.js // Request
68 | | | ├─minimist.js // Node parameter processing
69 | | | └VuepressUtils.js // Generate vuepress related configuration
70 | | ├─template // Template
71 | | | ├─vuepress // Template for generating vuepress related configuration
72 | | | | ├─config-template.js
73 | | | | └readme-template.md
74 | | | ├─article // Template for generating markdown files
75 | | | | ├─all-template.md
76 | | | | ├─year-month-template.md
77 | | | | └year-template.md
78 | | ├─src // Main entry of the main part
79 | | | └catch-main.js
80 | | ├─base // Basic data
81 | | | ├─base-data.js // Static data
82 | | | └cover.jpg // Static image
83 | ├─docs // Below are the folders and files generated after executing node locally
84 | | ├─README.md // Vuepress related configuration
85 | | ├─sort // Main markdown files
86 | | | ├─all.md
87 | | | ├─2023
88 | | | | ├─2023.md
89 | | | | ├─202301.md
90 | | | | └202302.md
91 | | | ├─2022
92 | | | | ├─2022.md
93 | | | | └202201.md
94 | | ├─.vuepress // Vuepress related configuration
95 | | | ├─config.js
96 | | | ├─public
97 | | | | └cover.jpg
98 | ```
99 |
100 | ## Future Development Plan
101 |
102 | 1. Implement multiple columns (specify multiple columns, all columns of specified users)
103 | 2. Implement favorite classification (specify collection)
104 | 3. Implement email subscription (send to subscribed email when updated)
105 | 4. Implement more flexible vuepress configuration files (easier to modify, etc.)
106 | 5. Implement support for more platform synchronization (such as CSDN, JianShu, etc.)
107 | 6. Implement more convenient configurations (Baidu statistics, weather, music)
108 |
109 | ## Contributors
110 | ## 贡献者
111 |
112 |
113 |
137 |
138 |
139 | 欢迎各位英雄豪杰加入,共建更完美的 **自动化同步文章平台(auto-sync-blog)** 。
140 |
141 | ## 问题回答(Question & Answer)
142 |
143 | Question & Answer
144 |
145 | ## License
146 | auto-sync-blog is under the [GPL license](LICENSE).
147 |
148 |
149 |
150 |
--------------------------------------------------------------------------------
/build/config.base.js:
--------------------------------------------------------------------------------
1 | // 生成 vuepress 配置相关
2 | export const CONFIG_FILE_PATH = "docs/.vitepress/config" // config 生成路径
3 | export const THEME_SET_FILE_PATH = "works/generator/vitepress/theme"
4 | export const THEME_FILE_PATH = "docs/.vitepress/theme"
5 | // 默认 index.md 位置
6 | export const DOCS_FILE_PATH = "docs/src"
7 | // 概览页
8 | export const OVERVIEW_FILE_PATH = "docs/src/overview"
9 | // 专栏
10 | export const COLUMNS_FILE_PATH = "docs/src/columns"
11 | // 分类
12 | export const CATEGORIES_FILE_PATH = "docs/src/categories"
13 | // 标签
14 | export const TAGS_FILE_PATH = "docs/src/tags"
15 | // 年度
16 | export const YEARS_FILE_PATH = "docs/src/years"
17 | // 排行榜
18 | export const RANKING_FILE_PATH = "docs/src/ranking"
19 | // 最近热门
20 | export const RECENT_TOP_FILE_PATH = "docs/src/recent"
21 |
--------------------------------------------------------------------------------
/components/VTabs.vue:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/configurations.js:
--------------------------------------------------------------------------------
1 | export default {
2 | // blog 基础配置
3 | blog: {
4 | title: "每日掘金",
5 | description: "专注于发掘站内优质创作者和优质内容",
6 | logo: "https://p3-passport.byteacctimg.com/img/user-avatar/b72e991ee9b1c9bdca7b2bd4c8dc78a8~300x300.image",
7 | siteName: "tea.juejindev.com",
8 | head: [],
9 | keywords: ["前端", "后端", "移动端", "每日掘金", "酱酱的下午茶", "掘金", "掘金酱"],
10 | author: "TeaTools,MiyueFE",
11 | },
12 |
13 | // vite press 构建配置
14 | press: {
15 | name: "每日掘金",
16 | text: "了解社区最新动态,发现最优质文章、最优质的你。",
17 | tagline: "专注于发掘站内优质创作者和优质内容",
18 | image: "https://vitepress.dev/vitepress-logo-large.webp",
19 | actions: [
20 | { theme: "brand", text: "开始阅读", link: "/overview/index" },
21 | { theme: "alt", text: "关注掘金", link: "https://juejin.cn/user/2819602825362840" },
22 | ],
23 | features: [
24 | { icon: "🎈", title: "博客平台小助手", details: "同步一流技术社区专属文章" },
25 | { icon: "🎁", title: "数据分析小能手", details: "年月总览统计数据分析" },
26 | { icon: "🎨", title: "自动化同步数据库", details: "每日自动化检查并更新" },
27 | ],
28 |
29 | // column:专栏;category:文章分类;tag:标签;annual:年度分类;follow:跳转掘金主页
30 | nav: ["column", "category", "ranking", "annual", "recent", "follow"],
31 |
32 | socialLinks: {
33 | github: "https://github.com/TeaTools/auto-sync-blog",
34 | // discord: "/",
35 | // facebook: "",
36 | // linkedin: "",
37 | // twitter: "/",
38 | // youtube: "/",
39 | },
40 |
41 | // # https://vitepress.dev/zh/reference/default-theme-team-page
42 | showTeam: true,
43 | members: [
44 | {
45 | avatar: "https://miyuefe.cn/assets/images/logo.svg",
46 | name: "MiyueFE",
47 | title: "Creator",
48 | links: {
49 | github: "https://github.com/miyuesc",
50 | home: "https://miyuefe.cn",
51 | juejin: "https://juejin.cn/user/747323639208391",
52 | },
53 | },
54 | {
55 | avatar: "https://p6-passport.byteacctimg.com/img/user-avatar/db3b09f9ca107d8843cee3fe8f4f0cd4~120x120.awebp",
56 | name: "南方者",
57 | title: "Creator",
58 | links: {
59 | github: "https://github.com/NanFangZhe404",
60 | home: "https://blog.nanfangzhe.cn/",
61 | juejin: "https://juejin.cn/user/2840793779295133",
62 | },
63 | },
64 | {
65 | avatar: "https://p6-passport.byteacctimg.com/img/user-avatar/6cd5915df47110ea932c1a1910569532~120x120.awebp",
66 | name: "Captaincc",
67 | title: "Contributor",
68 | links: {
69 | github: "https://github.com/captainfod",
70 | juejin: "https://juejin.cn/user/3052665287739005",
71 | },
72 | },
73 | {
74 | avatar: "https://p6-passport.byteacctimg.com/img/user-avatar/4206063bb939c2fa4042904efc95e10b~120x120.awebp",
75 | name: "Ylimhs",
76 | title: "Contributor",
77 | links: {
78 | github: "https://github.com/Ylimhs",
79 | juejin: "https://juejin.cn/user/2999123452115005",
80 | },
81 | },
82 | {
83 | avatar: "https://p6-passport.byteacctimg.com/img/user-avatar/a2f2b8afcf3908c6f0707b216f1f4408~120x120.awebp",
84 | name: "北洋",
85 | title: "Contributor",
86 | links: {
87 | github: "https://github.com/wuyangting",
88 | juejin: "https://juejin.cn/user/2163480089612877",
89 | },
90 | },
91 | {
92 | avatar: "https://p9-passport.byteacctimg.com/img/user-avatar/f3c0335559b4f202ddb10c41e4767c0a~120x120.awebp",
93 | name: "战场小包",
94 | title: "Contributor",
95 | links: {
96 | github: "https://github.com/zcxiaobao",
97 | home: "https://zcxiaobao.github.io/front-end-engineering-handbook/",
98 | juejin: "https://juejin.cn/user/4424090519078430",
99 | },
100 | },
101 | {
102 | avatar: "https://p9-passport.byteacctimg.com/img/user-avatar/51193d11e87c7530444651a8938d4568~120x120.awebp",
103 | name: "ReganYue",
104 | title: "Contributor",
105 | links: {
106 | github: "https://github.com/ReganYue",
107 | juejin: "https://juejin.cn/user/3008695929418318",
108 | },
109 | },
110 | ],
111 | },
112 |
113 | // 掘金
114 | juejin: {
115 | userId: "2819602825362840",
116 | columnsIds: [],
117 | },
118 | }
119 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "auto-sync-blog",
3 | "version": "1.0.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "auto-sync-blog",
9 | "version": "1.0.0",
10 | "dependencies": {
11 | "@nolebase/vitepress-plugin-enhanced-readabilities": "1.22.4",
12 | "axios": "1.2.6",
13 | "mkdirp": "^3.0.1",
14 | "vitepress": "1.0.0-rc.44",
15 | "vue": "^3.4.21"
16 | },
17 | "devDependencies": {
18 | "eslint": "^8.57.0",
19 | "eslint-config-prettier": "^9.1.0",
20 | "eslint-plugin-prettier": "^5.1.3",
21 | "prettier": "^3.2.5"
22 | }
23 | },
24 | "node_modules/@aashutoshrathi/word-wrap": {
25 | "version": "1.2.6",
26 | "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
27 | "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
28 | "dev": true,
29 | "engines": {
30 | "node": ">=0.10.0"
31 | }
32 | },
33 | "node_modules/@algolia/autocomplete-core": {
34 | "version": "1.9.3",
35 | "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz",
36 | "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==",
37 | "dependencies": {
38 | "@algolia/autocomplete-plugin-algolia-insights": "1.9.3",
39 | "@algolia/autocomplete-shared": "1.9.3"
40 | }
41 | },
42 | "node_modules/@algolia/autocomplete-plugin-algolia-insights": {
43 | "version": "1.9.3",
44 | "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz",
45 | "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==",
46 | "dependencies": {
47 | "@algolia/autocomplete-shared": "1.9.3"
48 | },
49 | "peerDependencies": {
50 | "search-insights": ">= 1 < 3"
51 | }
52 | },
53 | "node_modules/@algolia/autocomplete-preset-algolia": {
54 | "version": "1.9.3",
55 | "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz",
56 | "integrity": "sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==",
57 | "dependencies": {
58 | "@algolia/autocomplete-shared": "1.9.3"
59 | },
60 | "peerDependencies": {
61 | "@algolia/client-search": ">= 4.9.1 < 6",
62 | "algoliasearch": ">= 4.9.1 < 6"
63 | }
64 | },
65 | "node_modules/@algolia/autocomplete-shared": {
66 | "version": "1.9.3",
67 | "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz",
68 | "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==",
69 | "peerDependencies": {
70 | "@algolia/client-search": ">= 4.9.1 < 6",
71 | "algoliasearch": ">= 4.9.1 < 6"
72 | }
73 | },
74 | "node_modules/@algolia/cache-browser-local-storage": {
75 | "version": "4.23.2",
76 | "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.23.2.tgz",
77 | "integrity": "sha512-PvRQdCmtiU22dw9ZcTJkrVKgNBVAxKgD0/cfiqyxhA5+PHzA2WDt6jOmZ9QASkeM2BpyzClJb/Wr1yt2/t78Kw==",
78 | "dependencies": {
79 | "@algolia/cache-common": "4.23.2"
80 | }
81 | },
82 | "node_modules/@algolia/cache-common": {
83 | "version": "4.23.2",
84 | "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.23.2.tgz",
85 | "integrity": "sha512-OUK/6mqr6CQWxzl/QY0/mwhlGvS6fMtvEPyn/7AHUx96NjqDA4X4+Ju7aXFQKh+m3jW9VPB0B9xvEQgyAnRPNw=="
86 | },
87 | "node_modules/@algolia/cache-in-memory": {
88 | "version": "4.23.2",
89 | "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.23.2.tgz",
90 | "integrity": "sha512-rfbi/SnhEa3MmlqQvgYz/9NNJ156NkU6xFxjbxBtLWnHbpj+qnlMoKd+amoiacHRITpajg6zYbLM9dnaD3Bczw==",
91 | "dependencies": {
92 | "@algolia/cache-common": "4.23.2"
93 | }
94 | },
95 | "node_modules/@algolia/client-account": {
96 | "version": "4.23.2",
97 | "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.23.2.tgz",
98 | "integrity": "sha512-VbrOCLIN/5I7iIdskSoSw3uOUPF516k4SjDD4Qz3BFwa3of7D9A0lzBMAvQEJJEPHWdVraBJlGgdJq/ttmquJQ==",
99 | "dependencies": {
100 | "@algolia/client-common": "4.23.2",
101 | "@algolia/client-search": "4.23.2",
102 | "@algolia/transporter": "4.23.2"
103 | }
104 | },
105 | "node_modules/@algolia/client-analytics": {
106 | "version": "4.23.2",
107 | "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.23.2.tgz",
108 | "integrity": "sha512-lLj7irsAztGhMoEx/SwKd1cwLY6Daf1Q5f2AOsZacpppSvuFvuBrmkzT7pap1OD/OePjLKxicJS8wNA0+zKtuw==",
109 | "dependencies": {
110 | "@algolia/client-common": "4.23.2",
111 | "@algolia/client-search": "4.23.2",
112 | "@algolia/requester-common": "4.23.2",
113 | "@algolia/transporter": "4.23.2"
114 | }
115 | },
116 | "node_modules/@algolia/client-common": {
117 | "version": "4.23.2",
118 | "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.23.2.tgz",
119 | "integrity": "sha512-Q2K1FRJBern8kIfZ0EqPvUr3V29ICxCm/q42zInV+VJRjldAD9oTsMGwqUQ26GFMdFYmqkEfCbY4VGAiQhh22g==",
120 | "dependencies": {
121 | "@algolia/requester-common": "4.23.2",
122 | "@algolia/transporter": "4.23.2"
123 | }
124 | },
125 | "node_modules/@algolia/client-personalization": {
126 | "version": "4.23.2",
127 | "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.23.2.tgz",
128 | "integrity": "sha512-vwPsgnCGhUcHhhQG5IM27z8q7dWrN9itjdvgA6uKf2e9r7vB+WXt4OocK0CeoYQt3OGEAExryzsB8DWqdMK5wg==",
129 | "dependencies": {
130 | "@algolia/client-common": "4.23.2",
131 | "@algolia/requester-common": "4.23.2",
132 | "@algolia/transporter": "4.23.2"
133 | }
134 | },
135 | "node_modules/@algolia/client-search": {
136 | "version": "4.23.2",
137 | "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.23.2.tgz",
138 | "integrity": "sha512-CxSB29OVGSE7l/iyoHvamMonzq7Ev8lnk/OkzleODZ1iBcCs3JC/XgTIKzN/4RSTrJ9QybsnlrN/bYCGufo7qw==",
139 | "dependencies": {
140 | "@algolia/client-common": "4.23.2",
141 | "@algolia/requester-common": "4.23.2",
142 | "@algolia/transporter": "4.23.2"
143 | }
144 | },
145 | "node_modules/@algolia/logger-common": {
146 | "version": "4.23.2",
147 | "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.23.2.tgz",
148 | "integrity": "sha512-jGM49Q7626cXZ7qRAWXn0jDlzvoA1FvN4rKTi1g0hxKsTTSReyYk0i1ADWjChDPl3Q+nSDhJuosM2bBUAay7xw=="
149 | },
150 | "node_modules/@algolia/logger-console": {
151 | "version": "4.23.2",
152 | "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.23.2.tgz",
153 | "integrity": "sha512-oo+lnxxEmlhTBTFZ3fGz1O8PJ+G+8FiAoMY2Qo3Q4w23xocQev6KqDTA1JQAGPDxAewNA2VBwWOsVXeXFjrI/Q==",
154 | "dependencies": {
155 | "@algolia/logger-common": "4.23.2"
156 | }
157 | },
158 | "node_modules/@algolia/recommend": {
159 | "version": "4.23.2",
160 | "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.23.2.tgz",
161 | "integrity": "sha512-Q75CjnzRCDzgIlgWfPnkLtrfF4t82JCirhalXkSSwe/c1GH5pWh4xUyDOR3KTMo+YxxX3zTlrL/FjHmUJEWEcg==",
162 | "dependencies": {
163 | "@algolia/cache-browser-local-storage": "4.23.2",
164 | "@algolia/cache-common": "4.23.2",
165 | "@algolia/cache-in-memory": "4.23.2",
166 | "@algolia/client-common": "4.23.2",
167 | "@algolia/client-search": "4.23.2",
168 | "@algolia/logger-common": "4.23.2",
169 | "@algolia/logger-console": "4.23.2",
170 | "@algolia/requester-browser-xhr": "4.23.2",
171 | "@algolia/requester-common": "4.23.2",
172 | "@algolia/requester-node-http": "4.23.2",
173 | "@algolia/transporter": "4.23.2"
174 | }
175 | },
176 | "node_modules/@algolia/requester-browser-xhr": {
177 | "version": "4.23.2",
178 | "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.23.2.tgz",
179 | "integrity": "sha512-TO9wLlp8+rvW9LnIfyHsu8mNAMYrqNdQ0oLF6eTWFxXfxG3k8F/Bh7nFYGk2rFAYty4Fw4XUtrv/YjeNDtM5og==",
180 | "dependencies": {
181 | "@algolia/requester-common": "4.23.2"
182 | }
183 | },
184 | "node_modules/@algolia/requester-common": {
185 | "version": "4.23.2",
186 | "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.23.2.tgz",
187 | "integrity": "sha512-3EfpBS0Hri0lGDB5H/BocLt7Vkop0bTTLVUBB844HH6tVycwShmsV6bDR7yXbQvFP1uNpgePRD3cdBCjeHmk6Q=="
188 | },
189 | "node_modules/@algolia/requester-node-http": {
190 | "version": "4.23.2",
191 | "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.23.2.tgz",
192 | "integrity": "sha512-SVzgkZM/malo+2SB0NWDXpnT7nO5IZwuDTaaH6SjLeOHcya1o56LSWXk+3F3rNLz2GVH+I/rpYKiqmHhSOjerw==",
193 | "dependencies": {
194 | "@algolia/requester-common": "4.23.2"
195 | }
196 | },
197 | "node_modules/@algolia/transporter": {
198 | "version": "4.23.2",
199 | "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.23.2.tgz",
200 | "integrity": "sha512-GY3aGKBy+8AK4vZh8sfkatDciDVKad5rTY2S10Aefyjh7e7UGBP4zigf42qVXwU8VOPwi7l/L7OACGMOFcjB0Q==",
201 | "dependencies": {
202 | "@algolia/cache-common": "4.23.2",
203 | "@algolia/logger-common": "4.23.2",
204 | "@algolia/requester-common": "4.23.2"
205 | }
206 | },
207 | "node_modules/@babel/parser": {
208 | "version": "7.24.4",
209 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz",
210 | "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==",
211 | "bin": {
212 | "parser": "bin/babel-parser.js"
213 | },
214 | "engines": {
215 | "node": ">=6.0.0"
216 | }
217 | },
218 | "node_modules/@docsearch/css": {
219 | "version": "3.6.0",
220 | "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.6.0.tgz",
221 | "integrity": "sha512-+sbxb71sWre+PwDK7X2T8+bhS6clcVMLwBPznX45Qu6opJcgRjAp7gYSDzVFp187J+feSj5dNBN1mJoi6ckkUQ=="
222 | },
223 | "node_modules/@docsearch/js": {
224 | "version": "3.6.0",
225 | "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.6.0.tgz",
226 | "integrity": "sha512-QujhqINEElrkIfKwyyyTfbsfMAYCkylInLYMRqHy7PHc8xTBQCow73tlo/Kc7oIwBrCLf0P3YhjlOeV4v8hevQ==",
227 | "dependencies": {
228 | "@docsearch/react": "3.6.0",
229 | "preact": "^10.0.0"
230 | }
231 | },
232 | "node_modules/@docsearch/react": {
233 | "version": "3.6.0",
234 | "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.6.0.tgz",
235 | "integrity": "sha512-HUFut4ztcVNmqy9gp/wxNbC7pTOHhgVVkHVGCACTuLhUKUhKAF9KYHJtMiLUJxEqiFLQiuri1fWF8zqwM/cu1w==",
236 | "dependencies": {
237 | "@algolia/autocomplete-core": "1.9.3",
238 | "@algolia/autocomplete-preset-algolia": "1.9.3",
239 | "@docsearch/css": "3.6.0",
240 | "algoliasearch": "^4.19.1"
241 | },
242 | "peerDependencies": {
243 | "@types/react": ">= 16.8.0 < 19.0.0",
244 | "react": ">= 16.8.0 < 19.0.0",
245 | "react-dom": ">= 16.8.0 < 19.0.0",
246 | "search-insights": ">= 1 < 3"
247 | },
248 | "peerDependenciesMeta": {
249 | "@types/react": {
250 | "optional": true
251 | },
252 | "react": {
253 | "optional": true
254 | },
255 | "react-dom": {
256 | "optional": true
257 | },
258 | "search-insights": {
259 | "optional": true
260 | }
261 | }
262 | },
263 | "node_modules/@esbuild/aix-ppc64": {
264 | "version": "0.20.2",
265 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz",
266 | "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==",
267 | "cpu": [
268 | "ppc64"
269 | ],
270 | "optional": true,
271 | "os": [
272 | "aix"
273 | ],
274 | "engines": {
275 | "node": ">=12"
276 | }
277 | },
278 | "node_modules/@esbuild/android-arm": {
279 | "version": "0.20.2",
280 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz",
281 | "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==",
282 | "cpu": [
283 | "arm"
284 | ],
285 | "optional": true,
286 | "os": [
287 | "android"
288 | ],
289 | "engines": {
290 | "node": ">=12"
291 | }
292 | },
293 | "node_modules/@esbuild/android-arm64": {
294 | "version": "0.20.2",
295 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz",
296 | "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==",
297 | "cpu": [
298 | "arm64"
299 | ],
300 | "optional": true,
301 | "os": [
302 | "android"
303 | ],
304 | "engines": {
305 | "node": ">=12"
306 | }
307 | },
308 | "node_modules/@esbuild/android-x64": {
309 | "version": "0.20.2",
310 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz",
311 | "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==",
312 | "cpu": [
313 | "x64"
314 | ],
315 | "optional": true,
316 | "os": [
317 | "android"
318 | ],
319 | "engines": {
320 | "node": ">=12"
321 | }
322 | },
323 | "node_modules/@esbuild/darwin-arm64": {
324 | "version": "0.20.2",
325 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz",
326 | "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==",
327 | "cpu": [
328 | "arm64"
329 | ],
330 | "optional": true,
331 | "os": [
332 | "darwin"
333 | ],
334 | "engines": {
335 | "node": ">=12"
336 | }
337 | },
338 | "node_modules/@esbuild/darwin-x64": {
339 | "version": "0.20.2",
340 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz",
341 | "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==",
342 | "cpu": [
343 | "x64"
344 | ],
345 | "optional": true,
346 | "os": [
347 | "darwin"
348 | ],
349 | "engines": {
350 | "node": ">=12"
351 | }
352 | },
353 | "node_modules/@esbuild/freebsd-arm64": {
354 | "version": "0.20.2",
355 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz",
356 | "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==",
357 | "cpu": [
358 | "arm64"
359 | ],
360 | "optional": true,
361 | "os": [
362 | "freebsd"
363 | ],
364 | "engines": {
365 | "node": ">=12"
366 | }
367 | },
368 | "node_modules/@esbuild/freebsd-x64": {
369 | "version": "0.20.2",
370 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz",
371 | "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==",
372 | "cpu": [
373 | "x64"
374 | ],
375 | "optional": true,
376 | "os": [
377 | "freebsd"
378 | ],
379 | "engines": {
380 | "node": ">=12"
381 | }
382 | },
383 | "node_modules/@esbuild/linux-arm": {
384 | "version": "0.20.2",
385 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz",
386 | "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==",
387 | "cpu": [
388 | "arm"
389 | ],
390 | "optional": true,
391 | "os": [
392 | "linux"
393 | ],
394 | "engines": {
395 | "node": ">=12"
396 | }
397 | },
398 | "node_modules/@esbuild/linux-arm64": {
399 | "version": "0.20.2",
400 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz",
401 | "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==",
402 | "cpu": [
403 | "arm64"
404 | ],
405 | "optional": true,
406 | "os": [
407 | "linux"
408 | ],
409 | "engines": {
410 | "node": ">=12"
411 | }
412 | },
413 | "node_modules/@esbuild/linux-ia32": {
414 | "version": "0.20.2",
415 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz",
416 | "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==",
417 | "cpu": [
418 | "ia32"
419 | ],
420 | "optional": true,
421 | "os": [
422 | "linux"
423 | ],
424 | "engines": {
425 | "node": ">=12"
426 | }
427 | },
428 | "node_modules/@esbuild/linux-loong64": {
429 | "version": "0.20.2",
430 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz",
431 | "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==",
432 | "cpu": [
433 | "loong64"
434 | ],
435 | "optional": true,
436 | "os": [
437 | "linux"
438 | ],
439 | "engines": {
440 | "node": ">=12"
441 | }
442 | },
443 | "node_modules/@esbuild/linux-mips64el": {
444 | "version": "0.20.2",
445 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz",
446 | "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==",
447 | "cpu": [
448 | "mips64el"
449 | ],
450 | "optional": true,
451 | "os": [
452 | "linux"
453 | ],
454 | "engines": {
455 | "node": ">=12"
456 | }
457 | },
458 | "node_modules/@esbuild/linux-ppc64": {
459 | "version": "0.20.2",
460 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz",
461 | "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==",
462 | "cpu": [
463 | "ppc64"
464 | ],
465 | "optional": true,
466 | "os": [
467 | "linux"
468 | ],
469 | "engines": {
470 | "node": ">=12"
471 | }
472 | },
473 | "node_modules/@esbuild/linux-riscv64": {
474 | "version": "0.20.2",
475 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz",
476 | "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==",
477 | "cpu": [
478 | "riscv64"
479 | ],
480 | "optional": true,
481 | "os": [
482 | "linux"
483 | ],
484 | "engines": {
485 | "node": ">=12"
486 | }
487 | },
488 | "node_modules/@esbuild/linux-s390x": {
489 | "version": "0.20.2",
490 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz",
491 | "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==",
492 | "cpu": [
493 | "s390x"
494 | ],
495 | "optional": true,
496 | "os": [
497 | "linux"
498 | ],
499 | "engines": {
500 | "node": ">=12"
501 | }
502 | },
503 | "node_modules/@esbuild/linux-x64": {
504 | "version": "0.20.2",
505 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz",
506 | "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==",
507 | "cpu": [
508 | "x64"
509 | ],
510 | "optional": true,
511 | "os": [
512 | "linux"
513 | ],
514 | "engines": {
515 | "node": ">=12"
516 | }
517 | },
518 | "node_modules/@esbuild/netbsd-x64": {
519 | "version": "0.20.2",
520 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz",
521 | "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==",
522 | "cpu": [
523 | "x64"
524 | ],
525 | "optional": true,
526 | "os": [
527 | "netbsd"
528 | ],
529 | "engines": {
530 | "node": ">=12"
531 | }
532 | },
533 | "node_modules/@esbuild/openbsd-x64": {
534 | "version": "0.20.2",
535 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz",
536 | "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==",
537 | "cpu": [
538 | "x64"
539 | ],
540 | "optional": true,
541 | "os": [
542 | "openbsd"
543 | ],
544 | "engines": {
545 | "node": ">=12"
546 | }
547 | },
548 | "node_modules/@esbuild/sunos-x64": {
549 | "version": "0.20.2",
550 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz",
551 | "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==",
552 | "cpu": [
553 | "x64"
554 | ],
555 | "optional": true,
556 | "os": [
557 | "sunos"
558 | ],
559 | "engines": {
560 | "node": ">=12"
561 | }
562 | },
563 | "node_modules/@esbuild/win32-arm64": {
564 | "version": "0.20.2",
565 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz",
566 | "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==",
567 | "cpu": [
568 | "arm64"
569 | ],
570 | "optional": true,
571 | "os": [
572 | "win32"
573 | ],
574 | "engines": {
575 | "node": ">=12"
576 | }
577 | },
578 | "node_modules/@esbuild/win32-ia32": {
579 | "version": "0.20.2",
580 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz",
581 | "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==",
582 | "cpu": [
583 | "ia32"
584 | ],
585 | "optional": true,
586 | "os": [
587 | "win32"
588 | ],
589 | "engines": {
590 | "node": ">=12"
591 | }
592 | },
593 | "node_modules/@esbuild/win32-x64": {
594 | "version": "0.20.2",
595 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz",
596 | "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==",
597 | "cpu": [
598 | "x64"
599 | ],
600 | "optional": true,
601 | "os": [
602 | "win32"
603 | ],
604 | "engines": {
605 | "node": ">=12"
606 | }
607 | },
608 | "node_modules/@eslint-community/eslint-utils": {
609 | "version": "4.4.0",
610 | "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
611 | "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
612 | "dev": true,
613 | "dependencies": {
614 | "eslint-visitor-keys": "^3.3.0"
615 | },
616 | "engines": {
617 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
618 | },
619 | "peerDependencies": {
620 | "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
621 | }
622 | },
623 | "node_modules/@eslint-community/regexpp": {
624 | "version": "4.10.0",
625 | "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz",
626 | "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==",
627 | "dev": true,
628 | "engines": {
629 | "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
630 | }
631 | },
632 | "node_modules/@eslint/eslintrc": {
633 | "version": "2.1.4",
634 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
635 | "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
636 | "dev": true,
637 | "dependencies": {
638 | "ajv": "^6.12.4",
639 | "debug": "^4.3.2",
640 | "espree": "^9.6.0",
641 | "globals": "^13.19.0",
642 | "ignore": "^5.2.0",
643 | "import-fresh": "^3.2.1",
644 | "js-yaml": "^4.1.0",
645 | "minimatch": "^3.1.2",
646 | "strip-json-comments": "^3.1.1"
647 | },
648 | "engines": {
649 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
650 | },
651 | "funding": {
652 | "url": "https://opencollective.com/eslint"
653 | }
654 | },
655 | "node_modules/@eslint/js": {
656 | "version": "8.57.0",
657 | "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
658 | "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
659 | "dev": true,
660 | "engines": {
661 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
662 | }
663 | },
664 | "node_modules/@humanwhocodes/config-array": {
665 | "version": "0.11.14",
666 | "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
667 | "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
668 | "dev": true,
669 | "dependencies": {
670 | "@humanwhocodes/object-schema": "^2.0.2",
671 | "debug": "^4.3.1",
672 | "minimatch": "^3.0.5"
673 | },
674 | "engines": {
675 | "node": ">=10.10.0"
676 | }
677 | },
678 | "node_modules/@humanwhocodes/module-importer": {
679 | "version": "1.0.1",
680 | "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
681 | "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
682 | "dev": true,
683 | "engines": {
684 | "node": ">=12.22"
685 | },
686 | "funding": {
687 | "type": "github",
688 | "url": "https://github.com/sponsors/nzakas"
689 | }
690 | },
691 | "node_modules/@humanwhocodes/object-schema": {
692 | "version": "2.0.3",
693 | "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
694 | "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
695 | "dev": true
696 | },
697 | "node_modules/@jridgewell/sourcemap-codec": {
698 | "version": "1.4.15",
699 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
700 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
701 | },
702 | "node_modules/@nodelib/fs.scandir": {
703 | "version": "2.1.5",
704 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
705 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
706 | "dev": true,
707 | "dependencies": {
708 | "@nodelib/fs.stat": "2.0.5",
709 | "run-parallel": "^1.1.9"
710 | },
711 | "engines": {
712 | "node": ">= 8"
713 | }
714 | },
715 | "node_modules/@nodelib/fs.stat": {
716 | "version": "2.0.5",
717 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
718 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
719 | "dev": true,
720 | "engines": {
721 | "node": ">= 8"
722 | }
723 | },
724 | "node_modules/@nodelib/fs.walk": {
725 | "version": "1.2.8",
726 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
727 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
728 | "dev": true,
729 | "dependencies": {
730 | "@nodelib/fs.scandir": "2.1.5",
731 | "fastq": "^1.6.0"
732 | },
733 | "engines": {
734 | "node": ">= 8"
735 | }
736 | },
737 | "node_modules/@nolebase/vitepress-plugin-enhanced-readabilities": {
738 | "version": "1.22.4",
739 | "resolved": "https://registry.npmjs.org/@nolebase/vitepress-plugin-enhanced-readabilities/-/vitepress-plugin-enhanced-readabilities-1.22.4.tgz",
740 | "integrity": "sha512-4OusbDlwwFRDsPEGHeYyyBMY1EpLFUhPPPqT33QB4XMHCsXemROJegh0lkTnu7t1Y0qW2oF9C9bIXg2CTSYqXQ==",
741 | "peerDependencies": {
742 | "vitepress": ">=1.0.0-rc.42"
743 | }
744 | },
745 | "node_modules/@pkgr/core": {
746 | "version": "0.1.1",
747 | "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz",
748 | "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==",
749 | "dev": true,
750 | "engines": {
751 | "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
752 | },
753 | "funding": {
754 | "url": "https://opencollective.com/unts"
755 | }
756 | },
757 | "node_modules/@rollup/rollup-android-arm-eabi": {
758 | "version": "4.14.1",
759 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.14.1.tgz",
760 | "integrity": "sha512-fH8/o8nSUek8ceQnT7K4EQbSiV7jgkHq81m9lWZFIXjJ7lJzpWXbQFpT/Zh6OZYnpFykvzC3fbEvEAFZu03dPA==",
761 | "cpu": [
762 | "arm"
763 | ],
764 | "optional": true,
765 | "os": [
766 | "android"
767 | ]
768 | },
769 | "node_modules/@rollup/rollup-android-arm64": {
770 | "version": "4.14.1",
771 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.14.1.tgz",
772 | "integrity": "sha512-Y/9OHLjzkunF+KGEoJr3heiD5X9OLa8sbT1lm0NYeKyaM3oMhhQFvPB0bNZYJwlq93j8Z6wSxh9+cyKQaxS7PQ==",
773 | "cpu": [
774 | "arm64"
775 | ],
776 | "optional": true,
777 | "os": [
778 | "android"
779 | ]
780 | },
781 | "node_modules/@rollup/rollup-darwin-arm64": {
782 | "version": "4.14.1",
783 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.1.tgz",
784 | "integrity": "sha512-+kecg3FY84WadgcuSVm6llrABOdQAEbNdnpi5X3UwWiFVhZIZvKgGrF7kmLguvxHNQy+UuRV66cLVl3S+Rkt+Q==",
785 | "cpu": [
786 | "arm64"
787 | ],
788 | "optional": true,
789 | "os": [
790 | "darwin"
791 | ]
792 | },
793 | "node_modules/@rollup/rollup-darwin-x64": {
794 | "version": "4.14.1",
795 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.14.1.tgz",
796 | "integrity": "sha512-2pYRzEjVqq2TB/UNv47BV/8vQiXkFGVmPFwJb+1E0IFFZbIX8/jo1olxqqMbo6xCXf8kabANhp5bzCij2tFLUA==",
797 | "cpu": [
798 | "x64"
799 | ],
800 | "optional": true,
801 | "os": [
802 | "darwin"
803 | ]
804 | },
805 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
806 | "version": "4.14.1",
807 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.14.1.tgz",
808 | "integrity": "sha512-mS6wQ6Do6/wmrF9aTFVpIJ3/IDXhg1EZcQFYHZLHqw6AzMBjTHWnCG35HxSqUNphh0EHqSM6wRTT8HsL1C0x5g==",
809 | "cpu": [
810 | "arm"
811 | ],
812 | "optional": true,
813 | "os": [
814 | "linux"
815 | ]
816 | },
817 | "node_modules/@rollup/rollup-linux-arm64-gnu": {
818 | "version": "4.14.1",
819 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.1.tgz",
820 | "integrity": "sha512-p9rGKYkHdFMzhckOTFubfxgyIO1vw//7IIjBBRVzyZebWlzRLeNhqxuSaZ7kCEKVkm/kuC9fVRW9HkC/zNRG2w==",
821 | "cpu": [
822 | "arm64"
823 | ],
824 | "optional": true,
825 | "os": [
826 | "linux"
827 | ]
828 | },
829 | "node_modules/@rollup/rollup-linux-arm64-musl": {
830 | "version": "4.14.1",
831 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.14.1.tgz",
832 | "integrity": "sha512-nDY6Yz5xS/Y4M2i9JLQd3Rofh5OR8Bn8qe3Mv/qCVpHFlwtZSBYSPaU4mrGazWkXrdQ98GB//H0BirGR/SKFSw==",
833 | "cpu": [
834 | "arm64"
835 | ],
836 | "optional": true,
837 | "os": [
838 | "linux"
839 | ]
840 | },
841 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
842 | "version": "4.14.1",
843 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.14.1.tgz",
844 | "integrity": "sha512-im7HE4VBL+aDswvcmfx88Mp1soqL9OBsdDBU8NqDEYtkri0qV0THhQsvZtZeNNlLeCUQ16PZyv7cqutjDF35qw==",
845 | "cpu": [
846 | "ppc64le"
847 | ],
848 | "optional": true,
849 | "os": [
850 | "linux"
851 | ]
852 | },
853 | "node_modules/@rollup/rollup-linux-riscv64-gnu": {
854 | "version": "4.14.1",
855 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.14.1.tgz",
856 | "integrity": "sha512-RWdiHuAxWmzPJgaHJdpvUUlDz8sdQz4P2uv367T2JocdDa98iRw2UjIJ4QxSyt077mXZT2X6pKfT2iYtVEvOFw==",
857 | "cpu": [
858 | "riscv64"
859 | ],
860 | "optional": true,
861 | "os": [
862 | "linux"
863 | ]
864 | },
865 | "node_modules/@rollup/rollup-linux-s390x-gnu": {
866 | "version": "4.14.1",
867 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.14.1.tgz",
868 | "integrity": "sha512-VMgaGQ5zRX6ZqV/fas65/sUGc9cPmsntq2FiGmayW9KMNfWVG/j0BAqImvU4KTeOOgYSf1F+k6at1UfNONuNjA==",
869 | "cpu": [
870 | "s390x"
871 | ],
872 | "optional": true,
873 | "os": [
874 | "linux"
875 | ]
876 | },
877 | "node_modules/@rollup/rollup-linux-x64-gnu": {
878 | "version": "4.14.1",
879 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.1.tgz",
880 | "integrity": "sha512-9Q7DGjZN+hTdJomaQ3Iub4m6VPu1r94bmK2z3UeWP3dGUecRC54tmVu9vKHTm1bOt3ASoYtEz6JSRLFzrysKlA==",
881 | "cpu": [
882 | "x64"
883 | ],
884 | "optional": true,
885 | "os": [
886 | "linux"
887 | ]
888 | },
889 | "node_modules/@rollup/rollup-linux-x64-musl": {
890 | "version": "4.14.1",
891 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.14.1.tgz",
892 | "integrity": "sha512-JNEG/Ti55413SsreTguSx0LOVKX902OfXIKVg+TCXO6Gjans/k9O6ww9q3oLGjNDaTLxM+IHFMeXy/0RXL5R/g==",
893 | "cpu": [
894 | "x64"
895 | ],
896 | "optional": true,
897 | "os": [
898 | "linux"
899 | ]
900 | },
901 | "node_modules/@rollup/rollup-win32-arm64-msvc": {
902 | "version": "4.14.1",
903 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.14.1.tgz",
904 | "integrity": "sha512-ryS22I9y0mumlLNwDFYZRDFLwWh3aKaC72CWjFcFvxK0U6v/mOkM5Up1bTbCRAhv3kEIwW2ajROegCIQViUCeA==",
905 | "cpu": [
906 | "arm64"
907 | ],
908 | "optional": true,
909 | "os": [
910 | "win32"
911 | ]
912 | },
913 | "node_modules/@rollup/rollup-win32-ia32-msvc": {
914 | "version": "4.14.1",
915 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.14.1.tgz",
916 | "integrity": "sha512-TdloItiGk+T0mTxKx7Hp279xy30LspMso+GzQvV2maYePMAWdmrzqSNZhUpPj3CGw12aGj57I026PgLCTu8CGg==",
917 | "cpu": [
918 | "ia32"
919 | ],
920 | "optional": true,
921 | "os": [
922 | "win32"
923 | ]
924 | },
925 | "node_modules/@rollup/rollup-win32-x64-msvc": {
926 | "version": "4.14.1",
927 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.14.1.tgz",
928 | "integrity": "sha512-wQGI+LY/Py20zdUPq+XCem7JcPOyzIJBm3dli+56DJsQOHbnXZFEwgmnC6el1TPAfC8lBT3m+z69RmLykNUbew==",
929 | "cpu": [
930 | "x64"
931 | ],
932 | "optional": true,
933 | "os": [
934 | "win32"
935 | ]
936 | },
937 | "node_modules/@shikijs/core": {
938 | "version": "1.3.0",
939 | "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.3.0.tgz",
940 | "integrity": "sha512-7fedsBfuILDTBmrYZNFI8B6ATTxhQAasUHllHmjvSZPnoq4bULWoTpHwmuQvZ8Aq03/tAa2IGo6RXqWtHdWaCA=="
941 | },
942 | "node_modules/@shikijs/transformers": {
943 | "version": "1.3.0",
944 | "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-1.3.0.tgz",
945 | "integrity": "sha512-3mlpg2I9CjhjE96dEWQOGeCWoPcyTov3s4aAsHmgvnTHa8MBknEnCQy8/xivJPSpD+olqOqIEoHnLfbNJK29AA==",
946 | "dependencies": {
947 | "shiki": "1.3.0"
948 | }
949 | },
950 | "node_modules/@types/estree": {
951 | "version": "1.0.5",
952 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
953 | "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
954 | },
955 | "node_modules/@types/linkify-it": {
956 | "version": "3.0.5",
957 | "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz",
958 | "integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw=="
959 | },
960 | "node_modules/@types/markdown-it": {
961 | "version": "13.0.7",
962 | "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-13.0.7.tgz",
963 | "integrity": "sha512-U/CBi2YUUcTHBt5tjO2r5QV/x0Po6nsYwQU4Y04fBS6vfoImaiZ6f8bi3CjTCxBPQSO1LMyUqkByzi8AidyxfA==",
964 | "dependencies": {
965 | "@types/linkify-it": "*",
966 | "@types/mdurl": "*"
967 | }
968 | },
969 | "node_modules/@types/mdurl": {
970 | "version": "1.0.5",
971 | "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz",
972 | "integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA=="
973 | },
974 | "node_modules/@types/web-bluetooth": {
975 | "version": "0.0.20",
976 | "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz",
977 | "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow=="
978 | },
979 | "node_modules/@ungap/structured-clone": {
980 | "version": "1.2.0",
981 | "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
982 | "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
983 | "dev": true
984 | },
985 | "node_modules/@vitejs/plugin-vue": {
986 | "version": "5.0.4",
987 | "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz",
988 | "integrity": "sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==",
989 | "engines": {
990 | "node": "^18.0.0 || >=20.0.0"
991 | },
992 | "peerDependencies": {
993 | "vite": "^5.0.0",
994 | "vue": "^3.2.25"
995 | }
996 | },
997 | "node_modules/@vue/compiler-core": {
998 | "version": "3.4.21",
999 | "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.21.tgz",
1000 | "integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==",
1001 | "dependencies": {
1002 | "@babel/parser": "^7.23.9",
1003 | "@vue/shared": "3.4.21",
1004 | "entities": "^4.5.0",
1005 | "estree-walker": "^2.0.2",
1006 | "source-map-js": "^1.0.2"
1007 | }
1008 | },
1009 | "node_modules/@vue/compiler-dom": {
1010 | "version": "3.4.21",
1011 | "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz",
1012 | "integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==",
1013 | "dependencies": {
1014 | "@vue/compiler-core": "3.4.21",
1015 | "@vue/shared": "3.4.21"
1016 | }
1017 | },
1018 | "node_modules/@vue/compiler-sfc": {
1019 | "version": "3.4.21",
1020 | "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz",
1021 | "integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==",
1022 | "dependencies": {
1023 | "@babel/parser": "^7.23.9",
1024 | "@vue/compiler-core": "3.4.21",
1025 | "@vue/compiler-dom": "3.4.21",
1026 | "@vue/compiler-ssr": "3.4.21",
1027 | "@vue/shared": "3.4.21",
1028 | "estree-walker": "^2.0.2",
1029 | "magic-string": "^0.30.7",
1030 | "postcss": "^8.4.35",
1031 | "source-map-js": "^1.0.2"
1032 | }
1033 | },
1034 | "node_modules/@vue/compiler-ssr": {
1035 | "version": "3.4.21",
1036 | "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz",
1037 | "integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==",
1038 | "dependencies": {
1039 | "@vue/compiler-dom": "3.4.21",
1040 | "@vue/shared": "3.4.21"
1041 | }
1042 | },
1043 | "node_modules/@vue/devtools-api": {
1044 | "version": "7.0.26",
1045 | "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.0.26.tgz",
1046 | "integrity": "sha512-KnHZBP7IIhp5IUBXkyDmfuLKSht4BLhuZEgKaZXwgzFJRSTM9FfcZe5nWIrD33n28ClsIycne3b3kWYq5XnaYg==",
1047 | "dependencies": {
1048 | "@vue/devtools-kit": "^7.0.26"
1049 | }
1050 | },
1051 | "node_modules/@vue/devtools-kit": {
1052 | "version": "7.0.26",
1053 | "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.0.26.tgz",
1054 | "integrity": "sha512-k4TI5FxruPOxFNcy3oegzjrOTs5uAnukUcM/z/BWJtxfJFTxQl5MRJu6iiBLz8YnDuT8mYE2EbI/QAT8hpUppA==",
1055 | "dependencies": {
1056 | "@vue/devtools-shared": "^7.0.26",
1057 | "hookable": "^5.5.3",
1058 | "mitt": "^3.0.1",
1059 | "perfect-debounce": "^1.0.0",
1060 | "speakingurl": "^14.0.1"
1061 | },
1062 | "peerDependencies": {
1063 | "vue": "^3.0.0"
1064 | }
1065 | },
1066 | "node_modules/@vue/devtools-shared": {
1067 | "version": "7.0.26",
1068 | "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.0.26.tgz",
1069 | "integrity": "sha512-7Rzyqi8G+ZUyvyHkxpXORzevGu2CiIhvdUSfZ4wNC+lK6K+GDWxpIRcQPTjF8EDBfLvoObIXehOilK1Un6NqGg==",
1070 | "dependencies": {
1071 | "rfdc": "^1.3.1"
1072 | }
1073 | },
1074 | "node_modules/@vue/reactivity": {
1075 | "version": "3.4.21",
1076 | "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.21.tgz",
1077 | "integrity": "sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==",
1078 | "dependencies": {
1079 | "@vue/shared": "3.4.21"
1080 | }
1081 | },
1082 | "node_modules/@vue/runtime-core": {
1083 | "version": "3.4.21",
1084 | "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.21.tgz",
1085 | "integrity": "sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==",
1086 | "dependencies": {
1087 | "@vue/reactivity": "3.4.21",
1088 | "@vue/shared": "3.4.21"
1089 | }
1090 | },
1091 | "node_modules/@vue/runtime-dom": {
1092 | "version": "3.4.21",
1093 | "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz",
1094 | "integrity": "sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==",
1095 | "dependencies": {
1096 | "@vue/runtime-core": "3.4.21",
1097 | "@vue/shared": "3.4.21",
1098 | "csstype": "^3.1.3"
1099 | }
1100 | },
1101 | "node_modules/@vue/server-renderer": {
1102 | "version": "3.4.21",
1103 | "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.21.tgz",
1104 | "integrity": "sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==",
1105 | "dependencies": {
1106 | "@vue/compiler-ssr": "3.4.21",
1107 | "@vue/shared": "3.4.21"
1108 | },
1109 | "peerDependencies": {
1110 | "vue": "3.4.21"
1111 | }
1112 | },
1113 | "node_modules/@vue/shared": {
1114 | "version": "3.4.21",
1115 | "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz",
1116 | "integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g=="
1117 | },
1118 | "node_modules/@vueuse/core": {
1119 | "version": "10.9.0",
1120 | "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.9.0.tgz",
1121 | "integrity": "sha512-/1vjTol8SXnx6xewDEKfS0Ra//ncg4Hb0DaZiwKf7drgfMsKFExQ+FnnENcN6efPen+1kIzhLQoGSy0eDUVOMg==",
1122 | "dependencies": {
1123 | "@types/web-bluetooth": "^0.0.20",
1124 | "@vueuse/metadata": "10.9.0",
1125 | "@vueuse/shared": "10.9.0",
1126 | "vue-demi": ">=0.14.7"
1127 | },
1128 | "funding": {
1129 | "url": "https://github.com/sponsors/antfu"
1130 | }
1131 | },
1132 | "node_modules/@vueuse/core/node_modules/vue-demi": {
1133 | "version": "0.14.7",
1134 | "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz",
1135 | "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==",
1136 | "hasInstallScript": true,
1137 | "bin": {
1138 | "vue-demi-fix": "bin/vue-demi-fix.js",
1139 | "vue-demi-switch": "bin/vue-demi-switch.js"
1140 | },
1141 | "engines": {
1142 | "node": ">=12"
1143 | },
1144 | "funding": {
1145 | "url": "https://github.com/sponsors/antfu"
1146 | },
1147 | "peerDependencies": {
1148 | "@vue/composition-api": "^1.0.0-rc.1",
1149 | "vue": "^3.0.0-0 || ^2.6.0"
1150 | },
1151 | "peerDependenciesMeta": {
1152 | "@vue/composition-api": {
1153 | "optional": true
1154 | }
1155 | }
1156 | },
1157 | "node_modules/@vueuse/integrations": {
1158 | "version": "10.9.0",
1159 | "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-10.9.0.tgz",
1160 | "integrity": "sha512-acK+A01AYdWSvL4BZmCoJAcyHJ6EqhmkQEXbQLwev1MY7NBnS+hcEMx/BzVoR9zKI+UqEPMD9u6PsyAuiTRT4Q==",
1161 | "dependencies": {
1162 | "@vueuse/core": "10.9.0",
1163 | "@vueuse/shared": "10.9.0",
1164 | "vue-demi": ">=0.14.7"
1165 | },
1166 | "funding": {
1167 | "url": "https://github.com/sponsors/antfu"
1168 | },
1169 | "peerDependencies": {
1170 | "async-validator": "*",
1171 | "axios": "*",
1172 | "change-case": "*",
1173 | "drauu": "*",
1174 | "focus-trap": "*",
1175 | "fuse.js": "*",
1176 | "idb-keyval": "*",
1177 | "jwt-decode": "*",
1178 | "nprogress": "*",
1179 | "qrcode": "*",
1180 | "sortablejs": "*",
1181 | "universal-cookie": "*"
1182 | },
1183 | "peerDependenciesMeta": {
1184 | "async-validator": {
1185 | "optional": true
1186 | },
1187 | "axios": {
1188 | "optional": true
1189 | },
1190 | "change-case": {
1191 | "optional": true
1192 | },
1193 | "drauu": {
1194 | "optional": true
1195 | },
1196 | "focus-trap": {
1197 | "optional": true
1198 | },
1199 | "fuse.js": {
1200 | "optional": true
1201 | },
1202 | "idb-keyval": {
1203 | "optional": true
1204 | },
1205 | "jwt-decode": {
1206 | "optional": true
1207 | },
1208 | "nprogress": {
1209 | "optional": true
1210 | },
1211 | "qrcode": {
1212 | "optional": true
1213 | },
1214 | "sortablejs": {
1215 | "optional": true
1216 | },
1217 | "universal-cookie": {
1218 | "optional": true
1219 | }
1220 | }
1221 | },
1222 | "node_modules/@vueuse/integrations/node_modules/vue-demi": {
1223 | "version": "0.14.7",
1224 | "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz",
1225 | "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==",
1226 | "hasInstallScript": true,
1227 | "bin": {
1228 | "vue-demi-fix": "bin/vue-demi-fix.js",
1229 | "vue-demi-switch": "bin/vue-demi-switch.js"
1230 | },
1231 | "engines": {
1232 | "node": ">=12"
1233 | },
1234 | "funding": {
1235 | "url": "https://github.com/sponsors/antfu"
1236 | },
1237 | "peerDependencies": {
1238 | "@vue/composition-api": "^1.0.0-rc.1",
1239 | "vue": "^3.0.0-0 || ^2.6.0"
1240 | },
1241 | "peerDependenciesMeta": {
1242 | "@vue/composition-api": {
1243 | "optional": true
1244 | }
1245 | }
1246 | },
1247 | "node_modules/@vueuse/metadata": {
1248 | "version": "10.9.0",
1249 | "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.9.0.tgz",
1250 | "integrity": "sha512-iddNbg3yZM0X7qFY2sAotomgdHK7YJ6sKUvQqbvwnf7TmaVPxS4EJydcNsVejNdS8iWCtDk+fYXr7E32nyTnGA==",
1251 | "funding": {
1252 | "url": "https://github.com/sponsors/antfu"
1253 | }
1254 | },
1255 | "node_modules/@vueuse/shared": {
1256 | "version": "10.9.0",
1257 | "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.9.0.tgz",
1258 | "integrity": "sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==",
1259 | "dependencies": {
1260 | "vue-demi": ">=0.14.7"
1261 | },
1262 | "funding": {
1263 | "url": "https://github.com/sponsors/antfu"
1264 | }
1265 | },
1266 | "node_modules/@vueuse/shared/node_modules/vue-demi": {
1267 | "version": "0.14.7",
1268 | "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz",
1269 | "integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==",
1270 | "hasInstallScript": true,
1271 | "bin": {
1272 | "vue-demi-fix": "bin/vue-demi-fix.js",
1273 | "vue-demi-switch": "bin/vue-demi-switch.js"
1274 | },
1275 | "engines": {
1276 | "node": ">=12"
1277 | },
1278 | "funding": {
1279 | "url": "https://github.com/sponsors/antfu"
1280 | },
1281 | "peerDependencies": {
1282 | "@vue/composition-api": "^1.0.0-rc.1",
1283 | "vue": "^3.0.0-0 || ^2.6.0"
1284 | },
1285 | "peerDependenciesMeta": {
1286 | "@vue/composition-api": {
1287 | "optional": true
1288 | }
1289 | }
1290 | },
1291 | "node_modules/acorn": {
1292 | "version": "8.11.3",
1293 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
1294 | "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
1295 | "dev": true,
1296 | "bin": {
1297 | "acorn": "bin/acorn"
1298 | },
1299 | "engines": {
1300 | "node": ">=0.4.0"
1301 | }
1302 | },
1303 | "node_modules/acorn-jsx": {
1304 | "version": "5.3.2",
1305 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
1306 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
1307 | "dev": true,
1308 | "peerDependencies": {
1309 | "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
1310 | }
1311 | },
1312 | "node_modules/ajv": {
1313 | "version": "6.12.6",
1314 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
1315 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
1316 | "dev": true,
1317 | "dependencies": {
1318 | "fast-deep-equal": "^3.1.1",
1319 | "fast-json-stable-stringify": "^2.0.0",
1320 | "json-schema-traverse": "^0.4.1",
1321 | "uri-js": "^4.2.2"
1322 | },
1323 | "funding": {
1324 | "type": "github",
1325 | "url": "https://github.com/sponsors/epoberezkin"
1326 | }
1327 | },
1328 | "node_modules/algoliasearch": {
1329 | "version": "4.23.2",
1330 | "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.23.2.tgz",
1331 | "integrity": "sha512-8aCl055IsokLuPU8BzLjwzXjb7ty9TPcUFFOk0pYOwsE5DMVhE3kwCMFtsCFKcnoPZK7oObm+H5mbnSO/9ioxQ==",
1332 | "dependencies": {
1333 | "@algolia/cache-browser-local-storage": "4.23.2",
1334 | "@algolia/cache-common": "4.23.2",
1335 | "@algolia/cache-in-memory": "4.23.2",
1336 | "@algolia/client-account": "4.23.2",
1337 | "@algolia/client-analytics": "4.23.2",
1338 | "@algolia/client-common": "4.23.2",
1339 | "@algolia/client-personalization": "4.23.2",
1340 | "@algolia/client-search": "4.23.2",
1341 | "@algolia/logger-common": "4.23.2",
1342 | "@algolia/logger-console": "4.23.2",
1343 | "@algolia/recommend": "4.23.2",
1344 | "@algolia/requester-browser-xhr": "4.23.2",
1345 | "@algolia/requester-common": "4.23.2",
1346 | "@algolia/requester-node-http": "4.23.2",
1347 | "@algolia/transporter": "4.23.2"
1348 | }
1349 | },
1350 | "node_modules/ansi-regex": {
1351 | "version": "5.0.1",
1352 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
1353 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
1354 | "dev": true,
1355 | "engines": {
1356 | "node": ">=8"
1357 | }
1358 | },
1359 | "node_modules/ansi-styles": {
1360 | "version": "4.3.0",
1361 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
1362 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
1363 | "dev": true,
1364 | "dependencies": {
1365 | "color-convert": "^2.0.1"
1366 | },
1367 | "engines": {
1368 | "node": ">=8"
1369 | },
1370 | "funding": {
1371 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
1372 | }
1373 | },
1374 | "node_modules/argparse": {
1375 | "version": "2.0.1",
1376 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
1377 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
1378 | "dev": true
1379 | },
1380 | "node_modules/asynckit": {
1381 | "version": "0.4.0",
1382 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
1383 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
1384 | },
1385 | "node_modules/axios": {
1386 | "version": "1.2.6",
1387 | "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.6.tgz",
1388 | "integrity": "sha512-rC/7F08XxZwjMV4iuWv+JpD3E0Ksqg9nac4IIg6RwNuF0JTeWoCo/mBNG54+tNhhI11G3/VDRbdDQTs9hGp4pQ==",
1389 | "dependencies": {
1390 | "follow-redirects": "^1.15.0",
1391 | "form-data": "^4.0.0",
1392 | "proxy-from-env": "^1.1.0"
1393 | }
1394 | },
1395 | "node_modules/balanced-match": {
1396 | "version": "1.0.2",
1397 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
1398 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
1399 | "dev": true
1400 | },
1401 | "node_modules/brace-expansion": {
1402 | "version": "1.1.11",
1403 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
1404 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
1405 | "dev": true,
1406 | "dependencies": {
1407 | "balanced-match": "^1.0.0",
1408 | "concat-map": "0.0.1"
1409 | }
1410 | },
1411 | "node_modules/callsites": {
1412 | "version": "3.1.0",
1413 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
1414 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
1415 | "dev": true,
1416 | "engines": {
1417 | "node": ">=6"
1418 | }
1419 | },
1420 | "node_modules/chalk": {
1421 | "version": "4.1.2",
1422 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
1423 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
1424 | "dev": true,
1425 | "dependencies": {
1426 | "ansi-styles": "^4.1.0",
1427 | "supports-color": "^7.1.0"
1428 | },
1429 | "engines": {
1430 | "node": ">=10"
1431 | },
1432 | "funding": {
1433 | "url": "https://github.com/chalk/chalk?sponsor=1"
1434 | }
1435 | },
1436 | "node_modules/color-convert": {
1437 | "version": "2.0.1",
1438 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
1439 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
1440 | "dev": true,
1441 | "dependencies": {
1442 | "color-name": "~1.1.4"
1443 | },
1444 | "engines": {
1445 | "node": ">=7.0.0"
1446 | }
1447 | },
1448 | "node_modules/color-name": {
1449 | "version": "1.1.4",
1450 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
1451 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
1452 | "dev": true
1453 | },
1454 | "node_modules/combined-stream": {
1455 | "version": "1.0.8",
1456 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
1457 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
1458 | "dependencies": {
1459 | "delayed-stream": "~1.0.0"
1460 | },
1461 | "engines": {
1462 | "node": ">= 0.8"
1463 | }
1464 | },
1465 | "node_modules/concat-map": {
1466 | "version": "0.0.1",
1467 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
1468 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
1469 | "dev": true
1470 | },
1471 | "node_modules/cross-spawn": {
1472 | "version": "7.0.3",
1473 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
1474 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
1475 | "dev": true,
1476 | "dependencies": {
1477 | "path-key": "^3.1.0",
1478 | "shebang-command": "^2.0.0",
1479 | "which": "^2.0.1"
1480 | },
1481 | "engines": {
1482 | "node": ">= 8"
1483 | }
1484 | },
1485 | "node_modules/csstype": {
1486 | "version": "3.1.3",
1487 | "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
1488 | "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
1489 | },
1490 | "node_modules/debug": {
1491 | "version": "4.3.4",
1492 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
1493 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
1494 | "dev": true,
1495 | "dependencies": {
1496 | "ms": "2.1.2"
1497 | },
1498 | "engines": {
1499 | "node": ">=6.0"
1500 | },
1501 | "peerDependenciesMeta": {
1502 | "supports-color": {
1503 | "optional": true
1504 | }
1505 | }
1506 | },
1507 | "node_modules/deep-is": {
1508 | "version": "0.1.4",
1509 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
1510 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
1511 | "dev": true
1512 | },
1513 | "node_modules/delayed-stream": {
1514 | "version": "1.0.0",
1515 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
1516 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
1517 | "engines": {
1518 | "node": ">=0.4.0"
1519 | }
1520 | },
1521 | "node_modules/doctrine": {
1522 | "version": "3.0.0",
1523 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
1524 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
1525 | "dev": true,
1526 | "dependencies": {
1527 | "esutils": "^2.0.2"
1528 | },
1529 | "engines": {
1530 | "node": ">=6.0.0"
1531 | }
1532 | },
1533 | "node_modules/entities": {
1534 | "version": "4.5.0",
1535 | "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
1536 | "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
1537 | "engines": {
1538 | "node": ">=0.12"
1539 | },
1540 | "funding": {
1541 | "url": "https://github.com/fb55/entities?sponsor=1"
1542 | }
1543 | },
1544 | "node_modules/esbuild": {
1545 | "version": "0.20.2",
1546 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
1547 | "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==",
1548 | "hasInstallScript": true,
1549 | "bin": {
1550 | "esbuild": "bin/esbuild"
1551 | },
1552 | "engines": {
1553 | "node": ">=12"
1554 | },
1555 | "optionalDependencies": {
1556 | "@esbuild/aix-ppc64": "0.20.2",
1557 | "@esbuild/android-arm": "0.20.2",
1558 | "@esbuild/android-arm64": "0.20.2",
1559 | "@esbuild/android-x64": "0.20.2",
1560 | "@esbuild/darwin-arm64": "0.20.2",
1561 | "@esbuild/darwin-x64": "0.20.2",
1562 | "@esbuild/freebsd-arm64": "0.20.2",
1563 | "@esbuild/freebsd-x64": "0.20.2",
1564 | "@esbuild/linux-arm": "0.20.2",
1565 | "@esbuild/linux-arm64": "0.20.2",
1566 | "@esbuild/linux-ia32": "0.20.2",
1567 | "@esbuild/linux-loong64": "0.20.2",
1568 | "@esbuild/linux-mips64el": "0.20.2",
1569 | "@esbuild/linux-ppc64": "0.20.2",
1570 | "@esbuild/linux-riscv64": "0.20.2",
1571 | "@esbuild/linux-s390x": "0.20.2",
1572 | "@esbuild/linux-x64": "0.20.2",
1573 | "@esbuild/netbsd-x64": "0.20.2",
1574 | "@esbuild/openbsd-x64": "0.20.2",
1575 | "@esbuild/sunos-x64": "0.20.2",
1576 | "@esbuild/win32-arm64": "0.20.2",
1577 | "@esbuild/win32-ia32": "0.20.2",
1578 | "@esbuild/win32-x64": "0.20.2"
1579 | }
1580 | },
1581 | "node_modules/escape-string-regexp": {
1582 | "version": "4.0.0",
1583 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
1584 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
1585 | "dev": true,
1586 | "engines": {
1587 | "node": ">=10"
1588 | },
1589 | "funding": {
1590 | "url": "https://github.com/sponsors/sindresorhus"
1591 | }
1592 | },
1593 | "node_modules/eslint": {
1594 | "version": "8.57.0",
1595 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
1596 | "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
1597 | "dev": true,
1598 | "dependencies": {
1599 | "@eslint-community/eslint-utils": "^4.2.0",
1600 | "@eslint-community/regexpp": "^4.6.1",
1601 | "@eslint/eslintrc": "^2.1.4",
1602 | "@eslint/js": "8.57.0",
1603 | "@humanwhocodes/config-array": "^0.11.14",
1604 | "@humanwhocodes/module-importer": "^1.0.1",
1605 | "@nodelib/fs.walk": "^1.2.8",
1606 | "@ungap/structured-clone": "^1.2.0",
1607 | "ajv": "^6.12.4",
1608 | "chalk": "^4.0.0",
1609 | "cross-spawn": "^7.0.2",
1610 | "debug": "^4.3.2",
1611 | "doctrine": "^3.0.0",
1612 | "escape-string-regexp": "^4.0.0",
1613 | "eslint-scope": "^7.2.2",
1614 | "eslint-visitor-keys": "^3.4.3",
1615 | "espree": "^9.6.1",
1616 | "esquery": "^1.4.2",
1617 | "esutils": "^2.0.2",
1618 | "fast-deep-equal": "^3.1.3",
1619 | "file-entry-cache": "^6.0.1",
1620 | "find-up": "^5.0.0",
1621 | "glob-parent": "^6.0.2",
1622 | "globals": "^13.19.0",
1623 | "graphemer": "^1.4.0",
1624 | "ignore": "^5.2.0",
1625 | "imurmurhash": "^0.1.4",
1626 | "is-glob": "^4.0.0",
1627 | "is-path-inside": "^3.0.3",
1628 | "js-yaml": "^4.1.0",
1629 | "json-stable-stringify-without-jsonify": "^1.0.1",
1630 | "levn": "^0.4.1",
1631 | "lodash.merge": "^4.6.2",
1632 | "minimatch": "^3.1.2",
1633 | "natural-compare": "^1.4.0",
1634 | "optionator": "^0.9.3",
1635 | "strip-ansi": "^6.0.1",
1636 | "text-table": "^0.2.0"
1637 | },
1638 | "bin": {
1639 | "eslint": "bin/eslint.js"
1640 | },
1641 | "engines": {
1642 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
1643 | },
1644 | "funding": {
1645 | "url": "https://opencollective.com/eslint"
1646 | }
1647 | },
1648 | "node_modules/eslint-config-prettier": {
1649 | "version": "9.1.0",
1650 | "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
1651 | "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
1652 | "dev": true,
1653 | "bin": {
1654 | "eslint-config-prettier": "bin/cli.js"
1655 | },
1656 | "peerDependencies": {
1657 | "eslint": ">=7.0.0"
1658 | }
1659 | },
1660 | "node_modules/eslint-plugin-prettier": {
1661 | "version": "5.1.3",
1662 | "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz",
1663 | "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==",
1664 | "dev": true,
1665 | "dependencies": {
1666 | "prettier-linter-helpers": "^1.0.0",
1667 | "synckit": "^0.8.6"
1668 | },
1669 | "engines": {
1670 | "node": "^14.18.0 || >=16.0.0"
1671 | },
1672 | "funding": {
1673 | "url": "https://opencollective.com/eslint-plugin-prettier"
1674 | },
1675 | "peerDependencies": {
1676 | "@types/eslint": ">=8.0.0",
1677 | "eslint": ">=8.0.0",
1678 | "eslint-config-prettier": "*",
1679 | "prettier": ">=3.0.0"
1680 | },
1681 | "peerDependenciesMeta": {
1682 | "@types/eslint": {
1683 | "optional": true
1684 | },
1685 | "eslint-config-prettier": {
1686 | "optional": true
1687 | }
1688 | }
1689 | },
1690 | "node_modules/eslint-scope": {
1691 | "version": "7.2.2",
1692 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
1693 | "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
1694 | "dev": true,
1695 | "dependencies": {
1696 | "esrecurse": "^4.3.0",
1697 | "estraverse": "^5.2.0"
1698 | },
1699 | "engines": {
1700 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
1701 | },
1702 | "funding": {
1703 | "url": "https://opencollective.com/eslint"
1704 | }
1705 | },
1706 | "node_modules/eslint-visitor-keys": {
1707 | "version": "3.4.3",
1708 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
1709 | "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
1710 | "dev": true,
1711 | "engines": {
1712 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
1713 | },
1714 | "funding": {
1715 | "url": "https://opencollective.com/eslint"
1716 | }
1717 | },
1718 | "node_modules/espree": {
1719 | "version": "9.6.1",
1720 | "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
1721 | "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
1722 | "dev": true,
1723 | "dependencies": {
1724 | "acorn": "^8.9.0",
1725 | "acorn-jsx": "^5.3.2",
1726 | "eslint-visitor-keys": "^3.4.1"
1727 | },
1728 | "engines": {
1729 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
1730 | },
1731 | "funding": {
1732 | "url": "https://opencollective.com/eslint"
1733 | }
1734 | },
1735 | "node_modules/esquery": {
1736 | "version": "1.5.0",
1737 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
1738 | "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
1739 | "dev": true,
1740 | "dependencies": {
1741 | "estraverse": "^5.1.0"
1742 | },
1743 | "engines": {
1744 | "node": ">=0.10"
1745 | }
1746 | },
1747 | "node_modules/esrecurse": {
1748 | "version": "4.3.0",
1749 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
1750 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
1751 | "dev": true,
1752 | "dependencies": {
1753 | "estraverse": "^5.2.0"
1754 | },
1755 | "engines": {
1756 | "node": ">=4.0"
1757 | }
1758 | },
1759 | "node_modules/estraverse": {
1760 | "version": "5.3.0",
1761 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
1762 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
1763 | "dev": true,
1764 | "engines": {
1765 | "node": ">=4.0"
1766 | }
1767 | },
1768 | "node_modules/estree-walker": {
1769 | "version": "2.0.2",
1770 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
1771 | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
1772 | },
1773 | "node_modules/esutils": {
1774 | "version": "2.0.3",
1775 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
1776 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
1777 | "dev": true,
1778 | "engines": {
1779 | "node": ">=0.10.0"
1780 | }
1781 | },
1782 | "node_modules/fast-deep-equal": {
1783 | "version": "3.1.3",
1784 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
1785 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
1786 | "dev": true
1787 | },
1788 | "node_modules/fast-diff": {
1789 | "version": "1.3.0",
1790 | "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
1791 | "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
1792 | "dev": true
1793 | },
1794 | "node_modules/fast-json-stable-stringify": {
1795 | "version": "2.1.0",
1796 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
1797 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
1798 | "dev": true
1799 | },
1800 | "node_modules/fast-levenshtein": {
1801 | "version": "2.0.6",
1802 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
1803 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
1804 | "dev": true
1805 | },
1806 | "node_modules/fastq": {
1807 | "version": "1.17.1",
1808 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
1809 | "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
1810 | "dev": true,
1811 | "dependencies": {
1812 | "reusify": "^1.0.4"
1813 | }
1814 | },
1815 | "node_modules/file-entry-cache": {
1816 | "version": "6.0.1",
1817 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
1818 | "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
1819 | "dev": true,
1820 | "dependencies": {
1821 | "flat-cache": "^3.0.4"
1822 | },
1823 | "engines": {
1824 | "node": "^10.12.0 || >=12.0.0"
1825 | }
1826 | },
1827 | "node_modules/find-up": {
1828 | "version": "5.0.0",
1829 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
1830 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
1831 | "dev": true,
1832 | "dependencies": {
1833 | "locate-path": "^6.0.0",
1834 | "path-exists": "^4.0.0"
1835 | },
1836 | "engines": {
1837 | "node": ">=10"
1838 | },
1839 | "funding": {
1840 | "url": "https://github.com/sponsors/sindresorhus"
1841 | }
1842 | },
1843 | "node_modules/flat-cache": {
1844 | "version": "3.2.0",
1845 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
1846 | "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
1847 | "dev": true,
1848 | "dependencies": {
1849 | "flatted": "^3.2.9",
1850 | "keyv": "^4.5.3",
1851 | "rimraf": "^3.0.2"
1852 | },
1853 | "engines": {
1854 | "node": "^10.12.0 || >=12.0.0"
1855 | }
1856 | },
1857 | "node_modules/flatted": {
1858 | "version": "3.3.1",
1859 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
1860 | "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
1861 | "dev": true
1862 | },
1863 | "node_modules/focus-trap": {
1864 | "version": "7.5.4",
1865 | "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.4.tgz",
1866 | "integrity": "sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==",
1867 | "dependencies": {
1868 | "tabbable": "^6.2.0"
1869 | }
1870 | },
1871 | "node_modules/follow-redirects": {
1872 | "version": "1.15.6",
1873 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
1874 | "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
1875 | "funding": [
1876 | {
1877 | "type": "individual",
1878 | "url": "https://github.com/sponsors/RubenVerborgh"
1879 | }
1880 | ],
1881 | "engines": {
1882 | "node": ">=4.0"
1883 | },
1884 | "peerDependenciesMeta": {
1885 | "debug": {
1886 | "optional": true
1887 | }
1888 | }
1889 | },
1890 | "node_modules/form-data": {
1891 | "version": "4.0.0",
1892 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
1893 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
1894 | "dependencies": {
1895 | "asynckit": "^0.4.0",
1896 | "combined-stream": "^1.0.8",
1897 | "mime-types": "^2.1.12"
1898 | },
1899 | "engines": {
1900 | "node": ">= 6"
1901 | }
1902 | },
1903 | "node_modules/fs.realpath": {
1904 | "version": "1.0.0",
1905 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
1906 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
1907 | "dev": true
1908 | },
1909 | "node_modules/fsevents": {
1910 | "version": "2.3.3",
1911 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
1912 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
1913 | "hasInstallScript": true,
1914 | "optional": true,
1915 | "os": [
1916 | "darwin"
1917 | ],
1918 | "engines": {
1919 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
1920 | }
1921 | },
1922 | "node_modules/glob": {
1923 | "version": "7.2.3",
1924 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
1925 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
1926 | "dev": true,
1927 | "dependencies": {
1928 | "fs.realpath": "^1.0.0",
1929 | "inflight": "^1.0.4",
1930 | "inherits": "2",
1931 | "minimatch": "^3.1.1",
1932 | "once": "^1.3.0",
1933 | "path-is-absolute": "^1.0.0"
1934 | },
1935 | "engines": {
1936 | "node": "*"
1937 | },
1938 | "funding": {
1939 | "url": "https://github.com/sponsors/isaacs"
1940 | }
1941 | },
1942 | "node_modules/glob-parent": {
1943 | "version": "6.0.2",
1944 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
1945 | "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
1946 | "dev": true,
1947 | "dependencies": {
1948 | "is-glob": "^4.0.3"
1949 | },
1950 | "engines": {
1951 | "node": ">=10.13.0"
1952 | }
1953 | },
1954 | "node_modules/globals": {
1955 | "version": "13.24.0",
1956 | "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
1957 | "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
1958 | "dev": true,
1959 | "dependencies": {
1960 | "type-fest": "^0.20.2"
1961 | },
1962 | "engines": {
1963 | "node": ">=8"
1964 | },
1965 | "funding": {
1966 | "url": "https://github.com/sponsors/sindresorhus"
1967 | }
1968 | },
1969 | "node_modules/graphemer": {
1970 | "version": "1.4.0",
1971 | "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
1972 | "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
1973 | "dev": true
1974 | },
1975 | "node_modules/has-flag": {
1976 | "version": "4.0.0",
1977 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
1978 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
1979 | "dev": true,
1980 | "engines": {
1981 | "node": ">=8"
1982 | }
1983 | },
1984 | "node_modules/hookable": {
1985 | "version": "5.5.3",
1986 | "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
1987 | "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="
1988 | },
1989 | "node_modules/ignore": {
1990 | "version": "5.3.1",
1991 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
1992 | "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
1993 | "dev": true,
1994 | "engines": {
1995 | "node": ">= 4"
1996 | }
1997 | },
1998 | "node_modules/import-fresh": {
1999 | "version": "3.3.0",
2000 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
2001 | "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
2002 | "dev": true,
2003 | "dependencies": {
2004 | "parent-module": "^1.0.0",
2005 | "resolve-from": "^4.0.0"
2006 | },
2007 | "engines": {
2008 | "node": ">=6"
2009 | },
2010 | "funding": {
2011 | "url": "https://github.com/sponsors/sindresorhus"
2012 | }
2013 | },
2014 | "node_modules/imurmurhash": {
2015 | "version": "0.1.4",
2016 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
2017 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
2018 | "dev": true,
2019 | "engines": {
2020 | "node": ">=0.8.19"
2021 | }
2022 | },
2023 | "node_modules/inflight": {
2024 | "version": "1.0.6",
2025 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
2026 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
2027 | "dev": true,
2028 | "dependencies": {
2029 | "once": "^1.3.0",
2030 | "wrappy": "1"
2031 | }
2032 | },
2033 | "node_modules/inherits": {
2034 | "version": "2.0.4",
2035 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
2036 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
2037 | "dev": true
2038 | },
2039 | "node_modules/is-extglob": {
2040 | "version": "2.1.1",
2041 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
2042 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
2043 | "dev": true,
2044 | "engines": {
2045 | "node": ">=0.10.0"
2046 | }
2047 | },
2048 | "node_modules/is-glob": {
2049 | "version": "4.0.3",
2050 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
2051 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
2052 | "dev": true,
2053 | "dependencies": {
2054 | "is-extglob": "^2.1.1"
2055 | },
2056 | "engines": {
2057 | "node": ">=0.10.0"
2058 | }
2059 | },
2060 | "node_modules/is-path-inside": {
2061 | "version": "3.0.3",
2062 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
2063 | "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
2064 | "dev": true,
2065 | "engines": {
2066 | "node": ">=8"
2067 | }
2068 | },
2069 | "node_modules/isexe": {
2070 | "version": "2.0.0",
2071 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
2072 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
2073 | "dev": true
2074 | },
2075 | "node_modules/js-yaml": {
2076 | "version": "4.1.0",
2077 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
2078 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
2079 | "dev": true,
2080 | "dependencies": {
2081 | "argparse": "^2.0.1"
2082 | },
2083 | "bin": {
2084 | "js-yaml": "bin/js-yaml.js"
2085 | }
2086 | },
2087 | "node_modules/json-buffer": {
2088 | "version": "3.0.1",
2089 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
2090 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
2091 | "dev": true
2092 | },
2093 | "node_modules/json-schema-traverse": {
2094 | "version": "0.4.1",
2095 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
2096 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
2097 | "dev": true
2098 | },
2099 | "node_modules/json-stable-stringify-without-jsonify": {
2100 | "version": "1.0.1",
2101 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
2102 | "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
2103 | "dev": true
2104 | },
2105 | "node_modules/keyv": {
2106 | "version": "4.5.4",
2107 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
2108 | "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
2109 | "dev": true,
2110 | "dependencies": {
2111 | "json-buffer": "3.0.1"
2112 | }
2113 | },
2114 | "node_modules/levn": {
2115 | "version": "0.4.1",
2116 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
2117 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
2118 | "dev": true,
2119 | "dependencies": {
2120 | "prelude-ls": "^1.2.1",
2121 | "type-check": "~0.4.0"
2122 | },
2123 | "engines": {
2124 | "node": ">= 0.8.0"
2125 | }
2126 | },
2127 | "node_modules/locate-path": {
2128 | "version": "6.0.0",
2129 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
2130 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
2131 | "dev": true,
2132 | "dependencies": {
2133 | "p-locate": "^5.0.0"
2134 | },
2135 | "engines": {
2136 | "node": ">=10"
2137 | },
2138 | "funding": {
2139 | "url": "https://github.com/sponsors/sindresorhus"
2140 | }
2141 | },
2142 | "node_modules/lodash.merge": {
2143 | "version": "4.6.2",
2144 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
2145 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
2146 | "dev": true
2147 | },
2148 | "node_modules/magic-string": {
2149 | "version": "0.30.9",
2150 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.9.tgz",
2151 | "integrity": "sha512-S1+hd+dIrC8EZqKyT9DstTH/0Z+f76kmmvZnkfQVmOpDEF9iVgdYif3Q/pIWHmCoo59bQVGW0kVL3e2nl+9+Sw==",
2152 | "dependencies": {
2153 | "@jridgewell/sourcemap-codec": "^1.4.15"
2154 | },
2155 | "engines": {
2156 | "node": ">=12"
2157 | }
2158 | },
2159 | "node_modules/mark.js": {
2160 | "version": "8.11.1",
2161 | "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz",
2162 | "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ=="
2163 | },
2164 | "node_modules/mime-db": {
2165 | "version": "1.52.0",
2166 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
2167 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
2168 | "engines": {
2169 | "node": ">= 0.6"
2170 | }
2171 | },
2172 | "node_modules/mime-types": {
2173 | "version": "2.1.35",
2174 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
2175 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
2176 | "dependencies": {
2177 | "mime-db": "1.52.0"
2178 | },
2179 | "engines": {
2180 | "node": ">= 0.6"
2181 | }
2182 | },
2183 | "node_modules/minimatch": {
2184 | "version": "3.1.2",
2185 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
2186 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
2187 | "dev": true,
2188 | "dependencies": {
2189 | "brace-expansion": "^1.1.7"
2190 | },
2191 | "engines": {
2192 | "node": "*"
2193 | }
2194 | },
2195 | "node_modules/minisearch": {
2196 | "version": "6.3.0",
2197 | "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-6.3.0.tgz",
2198 | "integrity": "sha512-ihFnidEeU8iXzcVHy74dhkxh/dn8Dc08ERl0xwoMMGqp4+LvRSCgicb+zGqWthVokQKvCSxITlh3P08OzdTYCQ=="
2199 | },
2200 | "node_modules/mitt": {
2201 | "version": "3.0.1",
2202 | "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
2203 | "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="
2204 | },
2205 | "node_modules/mkdirp": {
2206 | "version": "3.0.1",
2207 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz",
2208 | "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==",
2209 | "bin": {
2210 | "mkdirp": "dist/cjs/src/bin.js"
2211 | },
2212 | "engines": {
2213 | "node": ">=10"
2214 | },
2215 | "funding": {
2216 | "url": "https://github.com/sponsors/isaacs"
2217 | }
2218 | },
2219 | "node_modules/ms": {
2220 | "version": "2.1.2",
2221 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
2222 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
2223 | "dev": true
2224 | },
2225 | "node_modules/nanoid": {
2226 | "version": "3.3.7",
2227 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
2228 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
2229 | "funding": [
2230 | {
2231 | "type": "github",
2232 | "url": "https://github.com/sponsors/ai"
2233 | }
2234 | ],
2235 | "bin": {
2236 | "nanoid": "bin/nanoid.cjs"
2237 | },
2238 | "engines": {
2239 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
2240 | }
2241 | },
2242 | "node_modules/natural-compare": {
2243 | "version": "1.4.0",
2244 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
2245 | "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
2246 | "dev": true
2247 | },
2248 | "node_modules/once": {
2249 | "version": "1.4.0",
2250 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
2251 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
2252 | "dev": true,
2253 | "dependencies": {
2254 | "wrappy": "1"
2255 | }
2256 | },
2257 | "node_modules/optionator": {
2258 | "version": "0.9.3",
2259 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
2260 | "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
2261 | "dev": true,
2262 | "dependencies": {
2263 | "@aashutoshrathi/word-wrap": "^1.2.3",
2264 | "deep-is": "^0.1.3",
2265 | "fast-levenshtein": "^2.0.6",
2266 | "levn": "^0.4.1",
2267 | "prelude-ls": "^1.2.1",
2268 | "type-check": "^0.4.0"
2269 | },
2270 | "engines": {
2271 | "node": ">= 0.8.0"
2272 | }
2273 | },
2274 | "node_modules/p-limit": {
2275 | "version": "3.1.0",
2276 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
2277 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
2278 | "dev": true,
2279 | "dependencies": {
2280 | "yocto-queue": "^0.1.0"
2281 | },
2282 | "engines": {
2283 | "node": ">=10"
2284 | },
2285 | "funding": {
2286 | "url": "https://github.com/sponsors/sindresorhus"
2287 | }
2288 | },
2289 | "node_modules/p-locate": {
2290 | "version": "5.0.0",
2291 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
2292 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
2293 | "dev": true,
2294 | "dependencies": {
2295 | "p-limit": "^3.0.2"
2296 | },
2297 | "engines": {
2298 | "node": ">=10"
2299 | },
2300 | "funding": {
2301 | "url": "https://github.com/sponsors/sindresorhus"
2302 | }
2303 | },
2304 | "node_modules/parent-module": {
2305 | "version": "1.0.1",
2306 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
2307 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
2308 | "dev": true,
2309 | "dependencies": {
2310 | "callsites": "^3.0.0"
2311 | },
2312 | "engines": {
2313 | "node": ">=6"
2314 | }
2315 | },
2316 | "node_modules/path-exists": {
2317 | "version": "4.0.0",
2318 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
2319 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
2320 | "dev": true,
2321 | "engines": {
2322 | "node": ">=8"
2323 | }
2324 | },
2325 | "node_modules/path-is-absolute": {
2326 | "version": "1.0.1",
2327 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
2328 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
2329 | "dev": true,
2330 | "engines": {
2331 | "node": ">=0.10.0"
2332 | }
2333 | },
2334 | "node_modules/path-key": {
2335 | "version": "3.1.1",
2336 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
2337 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
2338 | "dev": true,
2339 | "engines": {
2340 | "node": ">=8"
2341 | }
2342 | },
2343 | "node_modules/perfect-debounce": {
2344 | "version": "1.0.0",
2345 | "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
2346 | "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="
2347 | },
2348 | "node_modules/picocolors": {
2349 | "version": "1.0.0",
2350 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
2351 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
2352 | },
2353 | "node_modules/postcss": {
2354 | "version": "8.4.38",
2355 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
2356 | "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
2357 | "funding": [
2358 | {
2359 | "type": "opencollective",
2360 | "url": "https://opencollective.com/postcss/"
2361 | },
2362 | {
2363 | "type": "tidelift",
2364 | "url": "https://tidelift.com/funding/github/npm/postcss"
2365 | },
2366 | {
2367 | "type": "github",
2368 | "url": "https://github.com/sponsors/ai"
2369 | }
2370 | ],
2371 | "dependencies": {
2372 | "nanoid": "^3.3.7",
2373 | "picocolors": "^1.0.0",
2374 | "source-map-js": "^1.2.0"
2375 | },
2376 | "engines": {
2377 | "node": "^10 || ^12 || >=14"
2378 | }
2379 | },
2380 | "node_modules/preact": {
2381 | "version": "10.20.2",
2382 | "resolved": "https://registry.npmjs.org/preact/-/preact-10.20.2.tgz",
2383 | "integrity": "sha512-S1d1ernz3KQ+Y2awUxKakpfOg2CEmJmwOP+6igPx6dgr6pgDvenqYviyokWso2rhHvGtTlWWnJDa7RaPbQerTg==",
2384 | "funding": {
2385 | "type": "opencollective",
2386 | "url": "https://opencollective.com/preact"
2387 | }
2388 | },
2389 | "node_modules/prelude-ls": {
2390 | "version": "1.2.1",
2391 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
2392 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
2393 | "dev": true,
2394 | "engines": {
2395 | "node": ">= 0.8.0"
2396 | }
2397 | },
2398 | "node_modules/prettier": {
2399 | "version": "3.2.5",
2400 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
2401 | "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
2402 | "dev": true,
2403 | "bin": {
2404 | "prettier": "bin/prettier.cjs"
2405 | },
2406 | "engines": {
2407 | "node": ">=14"
2408 | },
2409 | "funding": {
2410 | "url": "https://github.com/prettier/prettier?sponsor=1"
2411 | }
2412 | },
2413 | "node_modules/prettier-linter-helpers": {
2414 | "version": "1.0.0",
2415 | "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
2416 | "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
2417 | "dev": true,
2418 | "dependencies": {
2419 | "fast-diff": "^1.1.2"
2420 | },
2421 | "engines": {
2422 | "node": ">=6.0.0"
2423 | }
2424 | },
2425 | "node_modules/proxy-from-env": {
2426 | "version": "1.1.0",
2427 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
2428 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
2429 | },
2430 | "node_modules/punycode": {
2431 | "version": "2.3.1",
2432 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
2433 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
2434 | "dev": true,
2435 | "engines": {
2436 | "node": ">=6"
2437 | }
2438 | },
2439 | "node_modules/queue-microtask": {
2440 | "version": "1.2.3",
2441 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
2442 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
2443 | "dev": true,
2444 | "funding": [
2445 | {
2446 | "type": "github",
2447 | "url": "https://github.com/sponsors/feross"
2448 | },
2449 | {
2450 | "type": "patreon",
2451 | "url": "https://www.patreon.com/feross"
2452 | },
2453 | {
2454 | "type": "consulting",
2455 | "url": "https://feross.org/support"
2456 | }
2457 | ]
2458 | },
2459 | "node_modules/resolve-from": {
2460 | "version": "4.0.0",
2461 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
2462 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
2463 | "dev": true,
2464 | "engines": {
2465 | "node": ">=4"
2466 | }
2467 | },
2468 | "node_modules/reusify": {
2469 | "version": "1.0.4",
2470 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
2471 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
2472 | "dev": true,
2473 | "engines": {
2474 | "iojs": ">=1.0.0",
2475 | "node": ">=0.10.0"
2476 | }
2477 | },
2478 | "node_modules/rfdc": {
2479 | "version": "1.3.1",
2480 | "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz",
2481 | "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg=="
2482 | },
2483 | "node_modules/rimraf": {
2484 | "version": "3.0.2",
2485 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
2486 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
2487 | "dev": true,
2488 | "dependencies": {
2489 | "glob": "^7.1.3"
2490 | },
2491 | "bin": {
2492 | "rimraf": "bin.js"
2493 | },
2494 | "funding": {
2495 | "url": "https://github.com/sponsors/isaacs"
2496 | }
2497 | },
2498 | "node_modules/rollup": {
2499 | "version": "4.14.1",
2500 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.1.tgz",
2501 | "integrity": "sha512-4LnHSdd3QK2pa1J6dFbfm1HN0D7vSK/ZuZTsdyUAlA6Rr1yTouUTL13HaDOGJVgby461AhrNGBS7sCGXXtT+SA==",
2502 | "dependencies": {
2503 | "@types/estree": "1.0.5"
2504 | },
2505 | "bin": {
2506 | "rollup": "dist/bin/rollup"
2507 | },
2508 | "engines": {
2509 | "node": ">=18.0.0",
2510 | "npm": ">=8.0.0"
2511 | },
2512 | "optionalDependencies": {
2513 | "@rollup/rollup-android-arm-eabi": "4.14.1",
2514 | "@rollup/rollup-android-arm64": "4.14.1",
2515 | "@rollup/rollup-darwin-arm64": "4.14.1",
2516 | "@rollup/rollup-darwin-x64": "4.14.1",
2517 | "@rollup/rollup-linux-arm-gnueabihf": "4.14.1",
2518 | "@rollup/rollup-linux-arm64-gnu": "4.14.1",
2519 | "@rollup/rollup-linux-arm64-musl": "4.14.1",
2520 | "@rollup/rollup-linux-powerpc64le-gnu": "4.14.1",
2521 | "@rollup/rollup-linux-riscv64-gnu": "4.14.1",
2522 | "@rollup/rollup-linux-s390x-gnu": "4.14.1",
2523 | "@rollup/rollup-linux-x64-gnu": "4.14.1",
2524 | "@rollup/rollup-linux-x64-musl": "4.14.1",
2525 | "@rollup/rollup-win32-arm64-msvc": "4.14.1",
2526 | "@rollup/rollup-win32-ia32-msvc": "4.14.1",
2527 | "@rollup/rollup-win32-x64-msvc": "4.14.1",
2528 | "fsevents": "~2.3.2"
2529 | }
2530 | },
2531 | "node_modules/run-parallel": {
2532 | "version": "1.2.0",
2533 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
2534 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
2535 | "dev": true,
2536 | "funding": [
2537 | {
2538 | "type": "github",
2539 | "url": "https://github.com/sponsors/feross"
2540 | },
2541 | {
2542 | "type": "patreon",
2543 | "url": "https://www.patreon.com/feross"
2544 | },
2545 | {
2546 | "type": "consulting",
2547 | "url": "https://feross.org/support"
2548 | }
2549 | ],
2550 | "dependencies": {
2551 | "queue-microtask": "^1.2.2"
2552 | }
2553 | },
2554 | "node_modules/search-insights": {
2555 | "version": "2.13.0",
2556 | "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.13.0.tgz",
2557 | "integrity": "sha512-Orrsjf9trHHxFRuo9/rzm0KIWmgzE8RMlZMzuhZOJ01Rnz3D0YBAe+V6473t6/H6c7irs6Lt48brULAiRWb3Vw==",
2558 | "peer": true
2559 | },
2560 | "node_modules/shebang-command": {
2561 | "version": "2.0.0",
2562 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
2563 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
2564 | "dev": true,
2565 | "dependencies": {
2566 | "shebang-regex": "^3.0.0"
2567 | },
2568 | "engines": {
2569 | "node": ">=8"
2570 | }
2571 | },
2572 | "node_modules/shebang-regex": {
2573 | "version": "3.0.0",
2574 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
2575 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
2576 | "dev": true,
2577 | "engines": {
2578 | "node": ">=8"
2579 | }
2580 | },
2581 | "node_modules/shiki": {
2582 | "version": "1.3.0",
2583 | "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.3.0.tgz",
2584 | "integrity": "sha512-9aNdQy/etMXctnPzsje1h1XIGm9YfRcSksKOGqZWXA/qP9G18/8fpz5Bjpma8bOgz3tqIpjERAd6/lLjFyzoww==",
2585 | "dependencies": {
2586 | "@shikijs/core": "1.3.0"
2587 | }
2588 | },
2589 | "node_modules/source-map-js": {
2590 | "version": "1.2.0",
2591 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
2592 | "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
2593 | "engines": {
2594 | "node": ">=0.10.0"
2595 | }
2596 | },
2597 | "node_modules/speakingurl": {
2598 | "version": "14.0.1",
2599 | "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz",
2600 | "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==",
2601 | "engines": {
2602 | "node": ">=0.10.0"
2603 | }
2604 | },
2605 | "node_modules/strip-ansi": {
2606 | "version": "6.0.1",
2607 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
2608 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
2609 | "dev": true,
2610 | "dependencies": {
2611 | "ansi-regex": "^5.0.1"
2612 | },
2613 | "engines": {
2614 | "node": ">=8"
2615 | }
2616 | },
2617 | "node_modules/strip-json-comments": {
2618 | "version": "3.1.1",
2619 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
2620 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
2621 | "dev": true,
2622 | "engines": {
2623 | "node": ">=8"
2624 | },
2625 | "funding": {
2626 | "url": "https://github.com/sponsors/sindresorhus"
2627 | }
2628 | },
2629 | "node_modules/supports-color": {
2630 | "version": "7.2.0",
2631 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
2632 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
2633 | "dev": true,
2634 | "dependencies": {
2635 | "has-flag": "^4.0.0"
2636 | },
2637 | "engines": {
2638 | "node": ">=8"
2639 | }
2640 | },
2641 | "node_modules/synckit": {
2642 | "version": "0.8.8",
2643 | "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz",
2644 | "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==",
2645 | "dev": true,
2646 | "dependencies": {
2647 | "@pkgr/core": "^0.1.0",
2648 | "tslib": "^2.6.2"
2649 | },
2650 | "engines": {
2651 | "node": "^14.18.0 || >=16.0.0"
2652 | },
2653 | "funding": {
2654 | "url": "https://opencollective.com/unts"
2655 | }
2656 | },
2657 | "node_modules/tabbable": {
2658 | "version": "6.2.0",
2659 | "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
2660 | "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="
2661 | },
2662 | "node_modules/text-table": {
2663 | "version": "0.2.0",
2664 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
2665 | "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
2666 | "dev": true
2667 | },
2668 | "node_modules/tslib": {
2669 | "version": "2.6.2",
2670 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
2671 | "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
2672 | "dev": true
2673 | },
2674 | "node_modules/type-check": {
2675 | "version": "0.4.0",
2676 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
2677 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
2678 | "dev": true,
2679 | "dependencies": {
2680 | "prelude-ls": "^1.2.1"
2681 | },
2682 | "engines": {
2683 | "node": ">= 0.8.0"
2684 | }
2685 | },
2686 | "node_modules/type-fest": {
2687 | "version": "0.20.2",
2688 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
2689 | "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
2690 | "dev": true,
2691 | "engines": {
2692 | "node": ">=10"
2693 | },
2694 | "funding": {
2695 | "url": "https://github.com/sponsors/sindresorhus"
2696 | }
2697 | },
2698 | "node_modules/uri-js": {
2699 | "version": "4.4.1",
2700 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
2701 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
2702 | "dev": true,
2703 | "dependencies": {
2704 | "punycode": "^2.1.0"
2705 | }
2706 | },
2707 | "node_modules/vite": {
2708 | "version": "5.2.8",
2709 | "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.8.tgz",
2710 | "integrity": "sha512-OyZR+c1CE8yeHw5V5t59aXsUPPVTHMDjEZz8MgguLL/Q7NblxhZUlTu9xSPqlsUO/y+X7dlU05jdhvyycD55DA==",
2711 | "dependencies": {
2712 | "esbuild": "^0.20.1",
2713 | "postcss": "^8.4.38",
2714 | "rollup": "^4.13.0"
2715 | },
2716 | "bin": {
2717 | "vite": "bin/vite.js"
2718 | },
2719 | "engines": {
2720 | "node": "^18.0.0 || >=20.0.0"
2721 | },
2722 | "funding": {
2723 | "url": "https://github.com/vitejs/vite?sponsor=1"
2724 | },
2725 | "optionalDependencies": {
2726 | "fsevents": "~2.3.3"
2727 | },
2728 | "peerDependencies": {
2729 | "@types/node": "^18.0.0 || >=20.0.0",
2730 | "less": "*",
2731 | "lightningcss": "^1.21.0",
2732 | "sass": "*",
2733 | "stylus": "*",
2734 | "sugarss": "*",
2735 | "terser": "^5.4.0"
2736 | },
2737 | "peerDependenciesMeta": {
2738 | "@types/node": {
2739 | "optional": true
2740 | },
2741 | "less": {
2742 | "optional": true
2743 | },
2744 | "lightningcss": {
2745 | "optional": true
2746 | },
2747 | "sass": {
2748 | "optional": true
2749 | },
2750 | "stylus": {
2751 | "optional": true
2752 | },
2753 | "sugarss": {
2754 | "optional": true
2755 | },
2756 | "terser": {
2757 | "optional": true
2758 | }
2759 | }
2760 | },
2761 | "node_modules/vitepress": {
2762 | "version": "1.0.0-rc.44",
2763 | "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.0.0-rc.44.tgz",
2764 | "integrity": "sha512-tO5taxGI7fSpBK1D8zrZTyJJERlyU9nnt0jHSt3fywfq3VKn977Hg0wUuTkEmwXlFYwuW26+6+3xorf4nD3XvA==",
2765 | "dependencies": {
2766 | "@docsearch/css": "^3.5.2",
2767 | "@docsearch/js": "^3.5.2",
2768 | "@shikijs/core": "^1.1.5",
2769 | "@shikijs/transformers": "^1.1.5",
2770 | "@types/markdown-it": "^13.0.7",
2771 | "@vitejs/plugin-vue": "^5.0.4",
2772 | "@vue/devtools-api": "^7.0.14",
2773 | "@vueuse/core": "^10.7.2",
2774 | "@vueuse/integrations": "^10.7.2",
2775 | "focus-trap": "^7.5.4",
2776 | "mark.js": "8.11.1",
2777 | "minisearch": "^6.3.0",
2778 | "shiki": "^1.1.5",
2779 | "vite": "^5.1.3",
2780 | "vue": "^3.4.19"
2781 | },
2782 | "bin": {
2783 | "vitepress": "bin/vitepress.js"
2784 | },
2785 | "peerDependencies": {
2786 | "markdown-it-mathjax3": "^4.3.2",
2787 | "postcss": "^8.4.35"
2788 | },
2789 | "peerDependenciesMeta": {
2790 | "markdown-it-mathjax3": {
2791 | "optional": true
2792 | },
2793 | "postcss": {
2794 | "optional": true
2795 | }
2796 | }
2797 | },
2798 | "node_modules/vue": {
2799 | "version": "3.4.21",
2800 | "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.21.tgz",
2801 | "integrity": "sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==",
2802 | "dependencies": {
2803 | "@vue/compiler-dom": "3.4.21",
2804 | "@vue/compiler-sfc": "3.4.21",
2805 | "@vue/runtime-dom": "3.4.21",
2806 | "@vue/server-renderer": "3.4.21",
2807 | "@vue/shared": "3.4.21"
2808 | },
2809 | "peerDependencies": {
2810 | "typescript": "*"
2811 | },
2812 | "peerDependenciesMeta": {
2813 | "typescript": {
2814 | "optional": true
2815 | }
2816 | }
2817 | },
2818 | "node_modules/which": {
2819 | "version": "2.0.2",
2820 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
2821 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
2822 | "dev": true,
2823 | "dependencies": {
2824 | "isexe": "^2.0.0"
2825 | },
2826 | "bin": {
2827 | "node-which": "bin/node-which"
2828 | },
2829 | "engines": {
2830 | "node": ">= 8"
2831 | }
2832 | },
2833 | "node_modules/wrappy": {
2834 | "version": "1.0.2",
2835 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
2836 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
2837 | "dev": true
2838 | },
2839 | "node_modules/yocto-queue": {
2840 | "version": "0.1.0",
2841 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
2842 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
2843 | "dev": true,
2844 | "engines": {
2845 | "node": ">=10"
2846 | },
2847 | "funding": {
2848 | "url": "https://github.com/sponsors/sindresorhus"
2849 | }
2850 | }
2851 | }
2852 | }
2853 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "auto-sync-blog",
3 | "description": "",
4 | "version": "1.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "lint": "eslint",
8 | "lint:fix": "eslint --fix",
9 | "sync:blog": "node works/index.js",
10 | "dev:blog": "vitepress dev docs",
11 | "build:blog": "vitepress build docs --base /"
12 | },
13 | "author": "https://github.com/TeaTools",
14 | "repository": "https://github.com/TeaTools/auto-sync-blog",
15 | "dependencies": {
16 | "@nolebase/vitepress-plugin-enhanced-readabilities": "1.22.4",
17 | "axios": "1.2.6",
18 | "mkdirp": "^3.0.1",
19 | "vitepress": "1.0.0-rc.44",
20 | "vue": "^3.4.21"
21 | },
22 | "devDependencies": {
23 | "eslint": "^8.57.0",
24 | "eslint-config-prettier": "^9.1.0",
25 | "eslint-plugin-prettier": "^5.1.3",
26 | "prettier": "^3.2.5"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/works/apis/juejin.js:
--------------------------------------------------------------------------------
1 | // 请求地址部分
2 | const API = "https://api.juejin.cn/"
3 |
4 | // 请求用户信息
5 | export const USER_API = API + "user_api/v1/user/get"
6 | // 请求获取文章列表
7 | export const ARTICLE_API = API + "content_api/v1/article/query_list"
8 | // 请求指定专栏里的文章列表
9 | export const COLUMN_API = API + "content_api/v1/column/articles_cursor"
10 | // 请求获取专栏列表
11 | export const COLUMN_LIST_API = API + "content_api/v1/column/self_center_list"
12 | // 单个专栏详情
13 | export const COLUMN_INFO_API = API + "content_api/v1/column/detail"
14 |
15 | // 默认分类列表(前端、后端、移动端、人工智能、开发工具等分类)
16 | export const CATEGORY_LIST_API = API + "tag_api/v1/query_category_briefs"
17 | // 单个分类文章列表查询
18 | export const RECENT_ARTICLE_API = API + "recommend_api/v1/article/recommend_cate_feed"
19 |
--------------------------------------------------------------------------------
/works/generator/index.js:
--------------------------------------------------------------------------------
1 | export * from "./juejin/overview.md.generator.js"
2 | export * from "./juejin/columns.generator.js"
3 | export * from "./juejin/years.generator.js"
4 | export * from "./juejin/category.generator.js"
5 | export * from "./juejin/tag.generator.js"
6 | export * from "./juejin/ranking-list.md.generator.js"
7 |
8 | export * from "./vitepress/index.md.generator.js"
9 | export * from "./vitepress/vitepress.generator.js"
10 |
--------------------------------------------------------------------------------
/works/generator/juejin/category.generator.js:
--------------------------------------------------------------------------------
1 | import { getArticlesAndColumnsMap } from "../../store/index.js"
2 | import { mkdirp } from "mkdirp"
3 | import { CATEGORIES_FILE_PATH } from "../../../build/config.base.js"
4 | import { writeFileSync } from "fs"
5 |
6 | export const processCategoriesOverview = async () => {
7 | await mkdirp(CATEGORIES_FILE_PATH)
8 |
9 | const { categoryCollection } = await getArticlesAndColumnsMap()
10 |
11 | let categoryMD = `# 我的分类`
12 |
13 | for (const [category_id, categoryColl] of categoryCollection) {
14 | const { articles, count, info } = categoryColl
15 |
16 | categoryMD += `\n\n## ${info.category_name}`
17 | categoryMD += `\n\n> · ${count} 文章 ·`
18 | categoryMD += `\n> [进入分类](/categories/${category_id})`
19 |
20 | await processCategoryDetail(categoryColl, articles)
21 | }
22 |
23 | await writeFileSync(`${CATEGORIES_FILE_PATH}/index.md`, categoryMD)
24 |
25 | console.log("Category overview 写入成功~")
26 | }
27 |
28 | export const processCategoryDetail = async (categoryColl, articles) => {
29 | let md = `# ${categoryColl.info.category_name}`
30 |
31 | md += `\n## 数据统计\n\n`
32 |
33 | md += `\n\n· ${categoryColl.count} 文章 ·`
34 |
35 | md += `\n## 文章列表\n\n`
36 |
37 | articles &&
38 | articles.forEach((article) => {
39 | md += `\n${article.formatInfo.mdString}`
40 | })
41 |
42 | await writeFileSync(`${CATEGORIES_FILE_PATH}/${categoryColl.info.category_id}.md`, md)
43 |
44 | console.log(`${categoryColl.info.category_name} 写入成功~`)
45 | }
46 |
--------------------------------------------------------------------------------
/works/generator/juejin/columns.generator.js:
--------------------------------------------------------------------------------
1 | import { getArticlesAndColumnsMap } from "../../store/index.js"
2 | import { mkdirp } from "mkdirp"
3 | import { COLUMNS_FILE_PATH } from "../../../build/config.base.js"
4 | import { writeFileSync } from "fs"
5 |
6 | export const processColumnsOverview = async () => {
7 | await mkdirp(COLUMNS_FILE_PATH)
8 |
9 | const { columnMap } = await getArticlesAndColumnsMap()
10 |
11 | let columnMd = `# 我的专栏`
12 |
13 | for (const [columnId, column] of columnMap) {
14 | const { articles, columnInfo } = column
15 |
16 | columnMd += `\n\n## ${columnInfo.column_version.title}`
17 | columnMd += `\n\n> ${columnInfo.column_version.content}`
18 | columnMd += `\n>\n> 📊 **${columnInfo.column.article_cnt} 文章 · ${columnInfo.column.follow_cnt} 订阅**`
19 | columnMd += ` [进入专栏](/columns/${columnId})`
20 |
21 | await processColumnDetail(columnInfo, articles)
22 | }
23 |
24 | await writeFileSync(`${COLUMNS_FILE_PATH}/index.md`, columnMd)
25 |
26 | console.log("overview.md 写入成功~")
27 | }
28 |
29 | export const processColumnDetail = async (column, articles) => {
30 | let md = `# ${column.column_version.title}`
31 |
32 | md += `\n## 内容介绍\n\n`
33 |
34 | md += `\n\n::: tip\n ${column.column_version.content}\n:::`
35 |
36 | md += `\n## 数据统计\n\n`
37 |
38 | md += `\n\n**${column.column.article_cnt} 文章 · ${column.column.follow_cnt} 订阅**`
39 |
40 | md += `\n## 文章列表\n\n`
41 |
42 | articles &&
43 | articles.forEach((article) => {
44 | article && article.formatInfo && (md += `\n${article.formatInfo.mdString}`)
45 | })
46 |
47 | await writeFileSync(`${COLUMNS_FILE_PATH}/${column.column_id}.md`, md)
48 |
49 | console.log(`${column.column_version.title} 写入成功~`)
50 | }
51 |
--------------------------------------------------------------------------------
/works/generator/juejin/overview.md.generator.js:
--------------------------------------------------------------------------------
1 | import { OVERVIEW_FILE_PATH } from "../../../build/config.base.js"
2 | import { mkdirp } from "mkdirp"
3 | import { writeFileSync } from "fs"
4 | import { insertString } from "../../utils/common.js"
5 | import { getArticlesAndColumnsMap } from "../../store/index.js"
6 | import { overviewTableMD } from "./utils.js"
7 |
8 | export const processArticleTimesCollection = (articleList = []) => {
9 | const timesCollectionMap = new Map()
10 |
11 | for (const article of articleList) {
12 | const { formatInfo: articleInfo } = article
13 | let strMap = timesCollectionMap.get(articleInfo.dateMap.YYYYMM)
14 | if (!strMap) {
15 | strMap = { str: "", count: 0 }
16 | }
17 |
18 | let { str, count } = strMap
19 | str += articleInfo.mdListString
20 | count++
21 | strMap = { str, count }
22 |
23 | timesCollectionMap.set(articleInfo.dateMap.YYYYMM, strMap)
24 | }
25 |
26 | return timesCollectionMap
27 | }
28 |
29 | const processOverviewTimeCollectionItem = (collectionItem, key) => {
30 | return `\n## ${insertString(key, 4, "年")}月
31 |
32 | **发布文章数:${collectionItem.count}**
33 |
34 | ${collectionItem.str}
35 | `
36 | }
37 |
38 | export const processOverviewMD = async () => {
39 | const { articles, yearMonthCollection, yearCollection } = await getArticlesAndColumnsMap()
40 | const timesCollectionMap = await processArticleTimesCollection(articles)
41 |
42 | let md = `# 文章总览\n\n## 累计发布 ${articles.length}`
43 |
44 | md += overviewTableMD(yearCollection, yearMonthCollection)
45 |
46 | timesCollectionMap.forEach((item, key) => (md += processOverviewTimeCollectionItem(item, key)))
47 |
48 | await mkdirp(OVERVIEW_FILE_PATH)
49 |
50 | await writeFileSync(`${OVERVIEW_FILE_PATH}/index.md`, md)
51 |
52 | console.log("overview 写入成功~")
53 | }
54 |
--------------------------------------------------------------------------------
/works/generator/juejin/ranking-list.md.generator.js:
--------------------------------------------------------------------------------
1 | import { getArticlesAndColumnsMap } from "../../store/index.js"
2 | import { mkdirp } from "mkdirp"
3 | import { RANKING_FILE_PATH } from "../../../build/config.base.js"
4 | import { writeFileSync } from "fs"
5 | import { processTopArticles } from "../../utils/template-process.js"
6 | import { sortArticleArray } from "../../utils/common.js"
7 |
8 | const template = (a, b, c, d) => `---
9 | aside: false
10 | ---
11 |
16 |
17 | # 数据排行榜
18 |
19 |
25 |
26 |
27 | ${processTopArticles(a)}
28 |
29 |
30 |
31 | ${processTopArticles(b)}
32 |
33 |
34 |
35 | ${processTopArticles(c)}
36 |
37 |
38 |
39 | ${processTopArticles(d)}
40 |
41 |
42 | `
43 |
44 | export const processRankingList = async () => {
45 | await mkdirp(RANKING_FILE_PATH)
46 |
47 | const { articles } = await getArticlesAndColumnsMap()
48 |
49 | const diggRanking = sortArticleArray(articles, "digg_count")
50 | const viewRanking = sortArticleArray(articles, "view_count")
51 | const commentRanking = sortArticleArray(articles, "comment_count")
52 | const collectRanking = sortArticleArray(articles, "collect_count")
53 |
54 | const md = template(viewRanking, diggRanking, commentRanking, collectRanking)
55 |
56 | await writeFileSync(`${RANKING_FILE_PATH}/index.md`, md)
57 |
58 | console.log("Ranking list 写入成功~")
59 | }
60 |
--------------------------------------------------------------------------------
/works/generator/juejin/recent-top.md.generator.js:
--------------------------------------------------------------------------------
1 | import { mkdirp } from "mkdirp"
2 | import { writeFileSync } from "fs"
3 | import { RECENT_TOP_FILE_PATH } from "../../../build/config.base.js"
4 | import { getCategoryList, getRecentArticles } from "../../requests/juejin.js"
5 | import { insertString } from "../../utils/common.js"
6 | import { getArticleInfo } from "./utils.js"
7 | import { getGlobalConfig } from "../../store/configuration/index.js"
8 | import { markerMap } from "../../utils/template-process.js"
9 |
10 | // const userInfoMap = new Map()
11 |
12 | // 近期热门
13 |
14 | // 数量
15 | const topLength = 20
16 | // 前推天数
17 | const timeRange = 3
18 | // 排除分类
19 | const excludeCategory = ["开发工具", "代码人生", "阅读"]
20 |
21 | // 计算文章优先级
22 | const getArticlePriority = async (article) => {
23 | const { article_info } = article
24 |
25 | const { collect_count, comment_count, digg_count, view_count, rank_index } = article_info
26 |
27 | // const user_id = article_info.user_id
28 | // let userInfo = userInfoMap.get(user_id)
29 | //
30 | // if (!userInfo) {
31 | // userInfo = await getUserInfo(user_id)
32 | // userInfoMap.set(user_id, userInfo)
33 | // }
34 | //
35 | // const { follower_count, level, power, got_digg_count } = userInfo
36 |
37 | const totalCount = collect_count * 10 + comment_count * 10 + digg_count * 5 + view_count / 5
38 | // follower_count * 8 +
39 | // level * 2 +
40 | // power +
41 | // got_digg_count * 2
42 |
43 | return totalCount * Math.ceil(rank_index)
44 | }
45 |
46 | // 单个分类文章排行榜 md
47 | const processTopArticles = (articles) => {
48 | return (
49 | articles
50 | .map((i, idx) => {
51 | const info = getArticleInfo(i)
52 | let md = insertString(info.mdString, 7, markerMap[idx] || markerMap.x(idx))
53 | md += `\r\r✒ [${info.user_name}](${info.authorUrl}) ${info.job_title}${info.company ? " @ " + info.company : ""}\r\r`
54 | return md
55 | })
56 | .join("\r\r") + "\r"
57 | )
58 | }
59 |
60 | // 生成页面完整 md
61 | const recentTemplateGenerator = (categories, categoryArticlesMap) => {
62 | return `---
63 | aside: false
64 | ---
65 |
70 |
71 | # 近期热门文章排行榜
72 |
73 |
74 |
78 |
79 | ${categories
80 | .map(
81 | (c, idx) => `
82 |
83 | ${processTopArticles(categoryArticlesMap.get(c.category_id) || [])}
84 |
`,
85 | )
86 | .join("\r\r")}
87 |
88 | `
89 | }
90 |
91 |
92 |
93 | // ${processTopArticles(categoryArticlesMap.get(c.category_id) || [])}
94 |
95 | export const processRecentTopList = async () => {
96 | try {
97 | await mkdirp(RECENT_TOP_FILE_PATH)
98 |
99 | const categoryArticlesMap = new Map()
100 | const categories = await getCategoryList()
101 |
102 | const filteredCategories = categories.filter((c) => !excludeCategory.includes(c.category_name))
103 |
104 | for (const filteredCategory of filteredCategories) {
105 | const articles = await getRecentArticles(filteredCategory.category_id, timeRange)
106 |
107 | for (const article of articles) {
108 | article.priority = await getArticlePriority(article)
109 | }
110 |
111 | const sortedArticles = articles.sort((a, b) => b.priority - a.priority)
112 |
113 | const topArticles = sortedArticles.slice(0, topLength)
114 |
115 | categoryArticlesMap.set(filteredCategory.category_id, topArticles)
116 | }
117 |
118 | const mdString = recentTemplateGenerator(filteredCategories, categoryArticlesMap)
119 |
120 | await writeFileSync(`${RECENT_TOP_FILE_PATH}/index.md`, mdString)
121 |
122 | console.log("Ranking list 写入成功~")
123 | } catch (e) {
124 | console.error(e)
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/works/generator/juejin/tag.generator.js:
--------------------------------------------------------------------------------
1 | import { getArticlesAndColumnsMap } from "../../store/index.js"
2 | import { mkdirp } from "mkdirp"
3 | import { TAGS_FILE_PATH } from "../../../build/config.base.js"
4 | import { writeFileSync } from "fs"
5 |
6 | export const processTagsOverview = async () => {
7 | await mkdirp(TAGS_FILE_PATH)
8 |
9 | const { tagCollection } = await getArticlesAndColumnsMap()
10 |
11 | let tagMD = `# 我的标签`
12 |
13 | for (const [tag_id, tagColl] of tagCollection) {
14 | const { articles, count, info } = tagColl
15 |
16 | tagMD += `\n\n## ${info.tag_name}`
17 | tagMD += `\n\n> · ${count} 文章 ·`
18 | tagMD += `\n> [进入标签](/tags/${tag_id})`
19 |
20 | await processTagDetail(tagColl, articles)
21 | }
22 |
23 | await writeFileSync(`${TAGS_FILE_PATH}/index.md`, tagMD)
24 |
25 | console.log("Tags overview 写入成功~")
26 | }
27 |
28 | export const processTagDetail = async (tagColl, articles) => {
29 | let md = `# ${tagColl.info.tag_name}`
30 |
31 | md += `\n## 数据统计\n\n`
32 |
33 | md += `\n\n· ${tagColl.count} 文章 ·`
34 |
35 | md += `\n## 文章列表\n\n`
36 |
37 | articles &&
38 | articles.forEach((article) => {
39 | md += `\n${article.formatInfo.mdString}`
40 | })
41 |
42 | await writeFileSync(`${TAGS_FILE_PATH}/${tagColl.info.tag_id}.md`, md)
43 |
44 | console.log(`${tagColl.info.tag_name} 写入成功~`)
45 | }
46 |
--------------------------------------------------------------------------------
/works/generator/juejin/utils.js:
--------------------------------------------------------------------------------
1 | import dateFormatter from "../../utils/date-formatter.js"
2 | import { JUEJIN_POST_URL, JUEJIN_USER_URL } from "../../website/juejin.js"
3 |
4 | export const getArticleInfo = (article) => {
5 | const {
6 | article_info: {
7 | title, // 标题
8 | article_id, // 文章id
9 | cover_image, // 专栏导图(有可能没有)
10 | brief_content, // 摘要
11 | ctime, // 创建时间
12 | view_count,
13 | digg_count,
14 | comment_count,
15 | collect_count,
16 | },
17 | tags = [],
18 | author_user_info: { user_name, user_id, company, job_title },
19 | } = article
20 |
21 | const dateMap = dateFormatter(parseInt(ctime + "000"))
22 |
23 | const articleInfo = {
24 | cover_image,
25 | article_id,
26 | title,
27 | postUrl: JUEJIN_POST_URL + article_id, // 文章地址
28 | brief_content,
29 | ctime,
30 | dateMap,
31 | view_count,
32 | digg_count,
33 | comment_count,
34 | collect_count,
35 | user_name,
36 | user_id,
37 | company,
38 | job_title,
39 | authorUrl: JUEJIN_USER_URL + user_id, // 作者
40 | tags: tags.map((t) => t.tag_name),
41 | }
42 |
43 | articleInfo.mdListString = article2MD(articleInfo)
44 | articleInfo.mdString = article2MD(articleInfo, false)
45 |
46 | return articleInfo
47 | }
48 |
49 | export function article2MD(articleBean, useList = true) {
50 | const { title, postUrl, dateMap, view_count, digg_count, comment_count, collect_count, brief_content, tags } =
51 | articleBean
52 |
53 | // let txt = `\r\n${useList ? "-" : "###"} [${title}](${postUrl})`
54 | let txt = `\r\r\n${useList ? "-" : "###"} ${title}`
55 |
56 | txt += `\n\r> ${brief_content.replaceAll("#", "")}...`
57 | txt += `\n>\n> [前往掘金](${postUrl})`
58 | txt += `\n\n📊 **${view_count} 阅读 · ${digg_count} 点赞 · ${comment_count} 评论 · ${collect_count} 收藏**`
59 | txt += `\n\n📅 ${dateMap.YMD}`
60 | txt += ` 🏷 ${tags.map((tagName) => `\`${tagName}\``).join(" ")}`
61 |
62 | let reg = /<[^>]+>/gi
63 | txt = txt.replace(reg, (match) => "`" + match + "`")
64 |
65 | return txt
66 | }
67 |
68 | export function overviewTableMD(yearCollMap = new Map(), yearMonthCollMap, year) {
69 | let tableMD = `
70 | | 年份 | 总记 | 1月 | 2月| 3月 | 4月 | 5月 | 6月 | 7月 | 8月 | 9月 | 10月 | 11月 | 12月 |
71 | | - | - | - | - | - | - | - | - | - | - | - | - | - | - |
72 | `
73 | const columns = ["year", "count", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"]
74 | if (year) {
75 | const tableRow = `|${columns
76 | .map((key) => {
77 | if (key === "year") return year
78 | if (key === "count") return yearCollMap.get(year).count || 0
79 | return yearMonthCollMap.get(`${year}${key}`) || "-"
80 | })
81 | .join("|")}|`
82 | return tableMD + tableRow
83 | }
84 |
85 | let tableRows = ""
86 | let keys = []
87 |
88 | yearCollMap.forEach((yearColl, k) => {
89 | keys.push(k)
90 | })
91 |
92 | keys = keys.sort((a, b) => b - a)
93 |
94 | for (const k of keys) {
95 | tableRows += `|${columns
96 | .map((key) => {
97 | if (key === "year") return k
98 | if (key === "count") return yearCollMap.get(k).count || 0
99 | return yearMonthCollMap.get(`${k}${key}`) || "-"
100 | })
101 | .join("|")}|\n`
102 | }
103 |
104 | return tableMD + tableRows
105 | }
106 |
--------------------------------------------------------------------------------
/works/generator/juejin/years.generator.js:
--------------------------------------------------------------------------------
1 | import { mkdirp } from "mkdirp"
2 | import { writeFileSync } from "fs"
3 | import { YEARS_FILE_PATH } from "../../../build/config.base.js"
4 | import { getArticlesAndColumnsMap } from "../../store/index.js"
5 | import { overviewTableMD } from "./utils.js"
6 |
7 | export const processYearsPage = async () => {
8 | await mkdirp(YEARS_FILE_PATH)
9 |
10 | const { yearCollection, yearMonthCollection } = await getArticlesAndColumnsMap()
11 |
12 | for (const [year] of yearCollection) {
13 | await processSingleYear(yearCollection, yearMonthCollection, year)
14 | }
15 | }
16 |
17 | export const processSingleYear = async (yearCollection, yearMonthCollection, year) => {
18 | let md = `# ${year} 年度概览`
19 |
20 | const yearColl = yearCollection.get(year)
21 |
22 | md += `\n## 本年发布 ${yearColl.count}`
23 |
24 | md += overviewTableMD(yearCollection, yearMonthCollection, year)
25 |
26 | md += `\n## 文章列表\n\n`
27 |
28 | for (const article of yearColl.articles) {
29 | md += article.formatInfo.mdString
30 | }
31 |
32 | await writeFileSync(`${YEARS_FILE_PATH}/${year}.md`, md)
33 |
34 | console.log(`${year}.md 写入成功~`)
35 | }
36 |
--------------------------------------------------------------------------------
/works/generator/vitepress/index.md.generator.js:
--------------------------------------------------------------------------------
1 | import { replaceKeywords } from "../../utils/template-process.js"
2 | import { homeTemplate, actionTemplate, featureTemplate, teamTemplate } from "../../template/index.js"
3 | import { mkdirp } from "mkdirp"
4 | import { DOCS_FILE_PATH } from "../../../build/config.base.js"
5 | import { writeFileSync } from "fs"
6 | import { getGlobalConfig } from "../../store/configuration/index.js"
7 |
8 | const homeIcon =
9 | '"
12 | const juejinIcon =
13 | '"
16 |
17 | const presetIcons = new Set(["github", "discord", "facebook", "linkedin", "twitter", "youtube"])
18 | const customIconsMap = {
19 | juejin: juejinIcon,
20 | home: homeIcon,
21 | }
22 |
23 | const processAction = (action) => {
24 | return replaceKeywords(actionTemplate, (key) => action[key] || "")
25 | }
26 |
27 | const processFeature = (feature) => {
28 | let feat = replaceKeywords(featureTemplate, (key) => feature[key] || "")
29 | if (feature.icon) {
30 | feat += `\n icon: ${feature.icon}`
31 | }
32 | return feat
33 | }
34 |
35 | export const processVitePressIndexMD = async () => {
36 | const configurations = await getGlobalConfig()
37 |
38 | const { press, blog } = configurations
39 |
40 | const replacer = (key) => {
41 | if (key === "actions") {
42 | return press.actions?.map(processAction).join("\n") || ""
43 | } else if (key === "features") {
44 | return press.features?.map(processFeature).join("\n") || ""
45 | } else {
46 | return blog[key] || press[key] || ""
47 | }
48 | }
49 |
50 | let md = replaceKeywords(homeTemplate, replacer)
51 |
52 | if (press.showTeam && press.members?.length) {
53 | let members = press.members.map((member) => {
54 | const { avatar, name, title, links: linksMap } = member
55 |
56 | const links = Object.keys(linksMap).map((key) => {
57 | if (presetIcons.has(key)) {
58 | return { icon: key, link: linksMap[key] }
59 | }
60 | if (customIconsMap[key]) {
61 | return { icon: { svg: customIconsMap[key] }, link: linksMap[key] }
62 | }
63 | })
64 |
65 | return { avatar, name, title, links }
66 | })
67 |
68 | md += replaceKeywords(teamTemplate, (key) => (key === "members" ? JSON.stringify(members) : ""))
69 | }
70 |
71 | await mkdirp(DOCS_FILE_PATH)
72 |
73 | await writeFileSync(`${DOCS_FILE_PATH}/index.md`, md)
74 |
75 | console.log("vitepress index.md 写入成功~")
76 | }
77 |
--------------------------------------------------------------------------------
/works/generator/vitepress/theme/index.js:
--------------------------------------------------------------------------------
1 | import { useData, inBrowser } from "vitepress"
2 | import { h } from "vue"
3 | import DefaultTheme from "vitepress/theme-without-fonts"
4 | import {
5 | NolebaseEnhancedReadabilitiesMenu,
6 | NolebaseEnhancedReadabilitiesScreenMenu,
7 | } from "@nolebase/vitepress-plugin-enhanced-readabilities"
8 |
9 | import "./main.css"
10 | import "@nolebase/vitepress-plugin-enhanced-readabilities/dist/style.css"
11 |
12 | export default {
13 | extends: DefaultTheme,
14 | Layout: () => {
15 | return h(DefaultTheme.Layout, null, {
16 | // 为较宽的屏幕的导航栏添加阅读增强菜单
17 | "nav-bar-content-after": () => h(NolebaseEnhancedReadabilitiesMenu),
18 | // 为较窄的屏幕(通常是小于 iPad Mini)添加阅读增强菜单
19 | "nav-screen-content-after": () => h(NolebaseEnhancedReadabilitiesScreenMenu),
20 | })
21 | },
22 | setup() {
23 | // setup language
24 | const { lang } = useData()
25 | if (inBrowser) {
26 | // @ts-ignore
27 | document.cookie = `nf_lang=${lang.value}; expires=Mon, 1 Jan 2024 00:00:00 UTC; path=/`
28 | }
29 | },
30 | }
31 |
--------------------------------------------------------------------------------
/works/generator/vitepress/theme/main.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Colors
3 | * -------------------------------------------------------------------------- */
4 |
5 | :root {
6 | --c-blue: #4092aa;
7 | --c-blue-dark: #2c3e50;
8 | --c-blue-darker: #1e2a38;
9 | --c-blue-light: #5e9ab5;
10 | --c-blue-lighter: #7fb1c2;
11 |
12 | --c-teal: #0c5053;
13 | --c-teal-light: #27696d;
14 |
15 | --c-white-dark: #f8f8f8;
16 | --vp-c-black-darker: #0d121b;
17 | --vp-c-black: #111827;
18 | --vp-c-black-light: #161f32;
19 | --vp-c-black-lighter: #262a44;
20 |
21 | --c-green-light: #8ae99c;
22 | --c-green: #52ce63;
23 | --c-green-dark: #51a256;
24 | --c-green-darker: #316334;
25 |
26 | --vp-c-text-dark-1: #d9e6eb;
27 | --vp-c-text-dark-2: #c4dde6;
28 | --vp-c-text-dark-3: #abc4cc;
29 | --c-text-light-1: #2c3e50;
30 | --c-text-light-2: #476582;
31 | --c-text-light-3: #90a4b7;
32 | /* #f9fafb */
33 |
34 | /* light theme is a bit different */
35 | --vp-c-brand: var(--c-green-darker);
36 | --vp-c-brand-light: var(--c-green);
37 | --vp-c-brand-lighter: var(--c-blue-lighter);
38 | --vp-c-brand-lightest: var(--c-blue-lighter);
39 |
40 | --vp-c-brand-dark: var(--c-green-dark);
41 | --vp-c-brand-darker: var(--c-green-darker);
42 | --vp-c-brand-dimm: rgba(100, 108, 255, 0.08);
43 | --vp-c-brand-text: var(--c-text-light-1);
44 | --c-bg-accent: var(--c-white-dark);
45 |
46 | --vp-code-block-bg: #0d121b;
47 | --vp-code-line-highlight-color: rgba(0, 0, 0, 0.075);
48 | }
49 |
50 | html.dark:root {
51 | --vp-c-brand: var(--c-blue);
52 | --vp-c-brand-dark: var(--c-blue-dark);
53 | --vp-c-brand-darker: var(--c-blue-darker);
54 | --vp-c-brand-light: var(--c-blue-light);
55 |
56 | --vp-c-bg-alpha-with-backdrop: rgba(20, 25, 36, 0.7);
57 | --vp-c-bg-alpha-without-backdrop: rgba(20, 25, 36, 0.9);
58 |
59 | --vp-code-line-highlight-color: rgba(0, 0, 0, 0.5);
60 |
61 | --vp-c-text: var(--c-text-dark-1);
62 | --vp-c-brand-text: var(--c-text-light-1);
63 | --c-text-light: var(--c-text-dark-2);
64 | --c-text-lighter: var(--c-text-dark-3);
65 | --c-divider: var(--c-divider-dark);
66 | --c-bg-accent: var(--vp-c-black-light);
67 |
68 | --vp-c-bg: var(--vp-c-black);
69 | --vp-c-bg-soft: var(--vp-c-black-light);
70 | --vp-c-bg-soft-up: var(--vp-c-black-lighter);
71 | --vp-c-bg-mute: var(--vp-c-black-light);
72 | --vp-c-bg-soft-mute: var(--vp-c-black-lighter);
73 | --vp-c-bg-alt: #0d121b;
74 | --vp-c-bg-elv: var(--vp-c-bg-soft);
75 | --vp-c-bg-elv-mute: var(--vp-c-bg-soft-mute);
76 | --vp-c-mute: var(--vp-c-bg-mute);
77 | --vp-c-mute-dark: var(--vp-c-black-lighter);
78 | --vp-c-mute-darker: var(--vp-c-black-darker);
79 |
80 | --vp-home-hero-name-background: linear-gradient(120deg, #bd34fe 30%, #41d1ff);
81 | }
82 |
83 | /**
84 | * Component: Button
85 | * -------------------------------------------------------------------------- */
86 |
87 | :root {
88 | --vp-button-brand-border: transparent;
89 | --vp-button-brand-bg: var(--c-teal-light);
90 | --vp-button-brand-hover-border: transparent;
91 | --vp-button-brand-hover-bg: var(--c-teal);
92 | --vp-button-brand-active-border: transparent;
93 | --vp-button-brand-active-bg: var(--c-teal-light);
94 | }
95 |
96 | /**
97 | * Component: Home
98 | * -------------------------------------------------------------------------- */
99 |
100 | :root {
101 | --vp-home-hero-name-color: transparent;
102 | --vp-home-hero-name-background: linear-gradient(120deg, #bd34fe 30%, #41d1ff);
103 | --vp-home-hero-image-background-image: linear-gradient(15deg, var(--c-green-light) 65%, var(--c-blue) 30%);
104 | --vp-home-hero-image-filter: blur(40px);
105 | }
106 |
107 | /**
108 | * Component: Header
109 | * -------------------------------------------------------------------------- */
110 |
111 | :root {
112 | --vp-layout-max-width: 100%;
113 | }
114 |
115 | /**
116 | * Component: plugins
117 | * -------------------------------------------------------------------------- */
118 |
119 | :root {
120 | --vp-nolebase-enhanced-readabilities-spotlight-under-bg-color: rgb(147 228 213 / 10%);
121 | }
122 |
123 | .VPHero .VPImage.image-src {
124 | max-height: 192px;
125 | }
126 |
127 | @media (min-width: 640px) {
128 | :root {
129 | --vp-home-hero-image-filter: blur(56px);
130 | }
131 | .VPHero .VPImage.image-src {
132 | max-height: 256px;
133 | }
134 | }
135 |
136 | @media (min-width: 960px) {
137 | :root {
138 | --vp-home-hero-image-filter: blur(72px);
139 | }
140 | .VPHero .VPImage.image-src {
141 | max-height: 320px;
142 | }
143 | }
144 |
145 | /**
146 | * Component: Algolia
147 | * -------------------------------------------------------------------------- */
148 |
149 | .DocSearch {
150 | --docsearch-primary-color: var(--vp-c-brand) !important;
151 | }
152 |
153 | html.dark .DocSearch,
154 | html.dark .DocSearch-Modal {
155 | /* --docsearch-text-color: var(--c-white-dark); */
156 | --docsearch-container-background: rgba(9, 10, 17, 0.8);
157 | --docsearch-modal-background: var(--vp-c-black);
158 | --docsearch-modal-shadow: inset 1px 1px 0 0 #2c2e40, 0 3px 8px 0 #000309;
159 | /* --docsearch-searchbox-background: var(--c-black-lighter); */
160 | /* --docsearch-searchbox-focus-background: var(--c-black-light); */
161 | --docsearch-hit-color: var(--c-text-dark-1);
162 | --docsearch-hit-active-color: var(--c-text-light-1);
163 | --docsearch-hit-shadow: none;
164 | --docsearch-hit-background: var(--vp-c-black-light);
165 | --docsearch-footer-background: var(--vp-c-black-light);
166 | --docsearch-footer-shadow: inset 0 1px 0 0 rgba(73, 76, 106, 0.5), 0 -4px 8px 0 rgba(0, 0, 0, 0.2);
167 | --docsearch-logo-color: var(--vp-c-brand);
168 | --docsearch-muted-color: var(--c-text-light-3);
169 | }
170 |
171 | html.dark .DocSearch-Logo svg .cls-1,
172 | html.dark .DocSearch-Logo svg .cls-2 {
173 | fill: var(--vp-c-brand);
174 | }
175 |
176 | .become-sponsor {
177 | font-size: 0.9em;
178 | font-weight: 700;
179 | width: auto;
180 | text-align: center;
181 | background-color: transparent;
182 | padding: 0.75em 2em;
183 | border-radius: 2em;
184 | transition: all 0.15s ease;
185 | box-sizing: border-box;
186 | border: 2px solid var(--c-blue-dark);
187 | }
188 |
189 | .become-sponsor:hover {
190 | background-color: var(--c-blue);
191 | text-decoration: none;
192 | border-color: var(--c-blue);
193 | color: var(--c-text-light-1);
194 | }
195 |
196 | .sponsors-top .become-sponsor {
197 | font-size: 0.75em;
198 | padding: 0.2em;
199 | width: auto;
200 | max-width: 150px;
201 | }
202 |
203 | kbd {
204 | display: inline-block;
205 | padding: 3px 5px;
206 | font-size: 0.65em;
207 | color: var(--vp-c-text-1);
208 | vertical-align: middle;
209 | background-color: var(--vp-c-bg-mute);
210 | border: solid 1px var(--vp-c-bg-soft-mute);
211 | border-radius: 6px;
212 | box-shadow: inset 0 -1px 0 var(--vp-c-bg-soft-mute);
213 | line-height: 0.95em;
214 | }
215 |
216 | .VPSocialLinks.VPNavBarSocialLinks.social-links {
217 | margin-right: 0;
218 | }
219 |
220 | .vp-doc a {
221 | text-decoration: none;
222 | }
223 | .vp-doc a:hover {
224 | text-decoration: underline;
225 | }
226 | .vp-doc strong,
227 | .vp-doc blockquote,
228 | .vp-doc a,
229 | .vp-doc span,
230 | .vp-doc p,
231 | .vp-doc button,
232 | .vp-doc blockquote > p {
233 | font-size: 0.875rem;
234 | }
235 |
236 | .VPTeamMembers .avatar {
237 | border-radius: 6px;
238 | }
239 | .VPTeamMembers .avatar .avatar-img {
240 | height: 100%;
241 | border-radius: 6px;
242 | object-fit: contain;
243 | }
244 |
245 |
246 | /**
247 | * Component: Ranking Tabs
248 | * -------------------------------------------------------------------------- */
249 | .ranking-tabs .ranking-tabs_header {
250 | display: flex;
251 | font-weight: bold;
252 | font-size: 0.875rem;
253 | line-height: 1.75rem;
254 | padding: 0.5rem;
255 | margin-top: 2rem;
256 | border-radius: 0.375rem;
257 | color: var(--vp-code-color);
258 | background-color: var(--vp-code-bg);
259 | }
260 | .ranking-tabs .ranking-tab-item {
261 | width: 100%;
262 | color: var(--vp-code-color);
263 | background-color: var(--vp-code-copy-code-bg);
264 | padding: 0.25rem;
265 | border-radius: 0.25rem;
266 | transition: all ease 0.2s;
267 | text-align: center;
268 | cursor: pointer;
269 | }
270 | .ranking-tabs .ranking-tab-item + .ranking-tab-item {
271 | margin-left: 0.5rem;
272 | }
273 | .ranking-tabs .ranking-tab-item:hover {
274 | box-shadow: 0 2px 4px 0 var(--vp-c-gray-soft);
275 | }
276 | .ranking-tabs .ranking-tab-item_active {
277 | color: var(--vp-c-success-1);
278 | background-color: var(--vp-code-block-bg);
279 | }
280 |
--------------------------------------------------------------------------------
/works/generator/vitepress/vitepress.generator.js:
--------------------------------------------------------------------------------
1 | import { vitePressConfigJs } from "../../template/index.js"
2 | import { JUEJIN_USER_URL } from "../../website/juejin.js"
3 | import { replaceKeywords } from "../../utils/template-process.js"
4 | import { writeFileSync, cpSync } from "fs"
5 | import { CONFIG_FILE_PATH, THEME_FILE_PATH, THEME_SET_FILE_PATH } from "../../../build/config.base.js"
6 | import { mkdirp } from "mkdirp"
7 | import { getArticlesAndColumnsMap } from "../../store/index.js"
8 | import { getGlobalConfig } from "../../store/configuration/index.js"
9 |
10 | const NAV_LINKS = {
11 | overview: {
12 | text: "文章总览",
13 | link: "/overview/index",
14 | },
15 | column: {
16 | text: "我的专栏",
17 | link: "/columns/index",
18 | },
19 | category: {
20 | text: "我的分类",
21 | link: "/categories/index",
22 | },
23 | tag: {
24 | text: "我的标签",
25 | link: "/tags/index",
26 | },
27 | ranking: {
28 | text: "数据排行榜",
29 | link: "/ranking/index",
30 | },
31 | recent: {
32 | text: "近期热门文章",
33 | link: "/recent/index",
34 | },
35 | annual: {
36 | text: "年度统计",
37 | items: [],
38 | },
39 | follow: {
40 | text: "关注我",
41 | link: "",
42 | },
43 | }
44 |
45 | const processNavBar = (usedNav = [], userId, annualList) => {
46 | // 默认具有概览页
47 | const nav = [NAV_LINKS["overview"]]
48 |
49 | for (const usedNavElement of usedNav) {
50 | const navLink = NAV_LINKS[usedNavElement]
51 | if (usedNavElement === "annual") {
52 | navLink.items = annualList
53 | } else if (usedNavElement === "follow") {
54 | navLink.link = `${JUEJIN_USER_URL}${userId}`
55 | }
56 | nav.push(navLink)
57 | }
58 | return nav
59 | }
60 |
61 | const processSocialLinks = (press) => {
62 | const socialLinks = press.socialLinks
63 | const usedSocial = Object.keys(socialLinks)
64 | return usedSocial.map((key) => ({
65 | icon: key,
66 | link: socialLinks[key],
67 | }))
68 | }
69 |
70 | const processPressHead = (blog) => {
71 | const STATIC_HEAD = [
72 | ["meta", { name: "viewport", content: "width=device-width,initial-scale=1,user-scalable=no" }],
73 | ["meta", { name: "apple-mobile-web-app-capable", content: "yes" }],
74 | ["meta", { name: "apple-mobile-web-app-status-bar-style", content: "black" }],
75 | ["link", { rel: "icon", href: blog.logo }],
76 | ["meta", { name: "description", content: blog.description }],
77 | ["meta", { property: "og:type", content: "website" }],
78 | ["meta", { property: "og:locale", content: "zh-CN" }],
79 | ["meta", { property: "og:title", content: blog.title }],
80 | ["meta", { property: "og:author", content: blog.author }],
81 | ["meta", { property: "og:site_name", content: blog.siteName }],
82 | ]
83 |
84 | const head = [...STATIC_HEAD]
85 |
86 | if (blog.head && blog.head.length) {
87 | head.push(...blog.head)
88 | }
89 | if (blog.keywords && blog.keywords.length) {
90 | head.push(["meta", { property: "keywords", content: blog.keywords.join(",") }])
91 | }
92 |
93 | return head
94 | }
95 |
96 | export const processVitePressConfig = async (annualList = []) => {
97 | const configurations = await getGlobalConfig()
98 |
99 | const { press, blog, juejin } = configurations
100 |
101 | const { yearCollection } = await getArticlesAndColumnsMap()
102 |
103 | let years = []
104 | for (const [year] of yearCollection) {
105 | years.push(year)
106 | }
107 | years = years.sort((a, b) => b - a)
108 | for (const year of years) {
109 | annualList.push({ text: `${year}`, link: `/years/${year}` })
110 | }
111 |
112 | const replacer = (key) => {
113 | if (key === "nav") {
114 | return JSON.stringify(processNavBar(press.nav, juejin.userId, annualList))
115 | } else if (key === "socialLinks") {
116 | return JSON.stringify(processSocialLinks(press))
117 | } else if (key === "head") {
118 | return JSON.stringify(processPressHead(blog))
119 | } else {
120 | return blog[key] || press[key] || key
121 | }
122 | }
123 |
124 | const config = replaceKeywords(vitePressConfigJs, replacer)
125 |
126 | await mkdirp(CONFIG_FILE_PATH)
127 |
128 | // 重写该文档(appendFile 是追加并不存在就直接创建)
129 | await writeFileSync(`${CONFIG_FILE_PATH}/index.js`, config)
130 |
131 | console.log("vitepress config 写入成功~")
132 | }
133 |
134 | export const processVitePressTheme = async () => {
135 | await cpSync(THEME_SET_FILE_PATH, THEME_FILE_PATH, { recursive: true })
136 | console.log("vitepress theme 复制成功~")
137 | }
138 |
--------------------------------------------------------------------------------
/works/index.js:
--------------------------------------------------------------------------------
1 | import {
2 | processCategoriesOverview,
3 | processColumnsOverview,
4 | processRankingList,
5 | processTagsOverview,
6 | processVitePressConfig,
7 | processVitePressTheme,
8 | } from "./generator/index.js"
9 | import { processVitePressIndexMD, processOverviewMD, processYearsPage } from "./generator/index.js"
10 | import { processRecentTopList } from "./generator/juejin/recent-top.md.generator.js"
11 | import { getGlobalConfig } from "./store/configuration/index.js"
12 |
13 | // 注意生成顺序
14 | await processVitePressIndexMD()
15 |
16 | await processOverviewMD()
17 |
18 | const { press } = await getGlobalConfig()
19 | const navProcessMap = {
20 | column: processColumnsOverview,
21 | category: processCategoriesOverview,
22 | tag: processTagsOverview,
23 | annual: processYearsPage,
24 | ranking: processRankingList,
25 | recent: processRecentTopList,
26 | }
27 | for (const navKey of press.nav) {
28 | navProcessMap[navKey] && (await navProcessMap[navKey]())
29 | }
30 |
31 | // 生成 vite press 配置
32 | await processVitePressConfig()
33 | await processVitePressTheme()
34 |
--------------------------------------------------------------------------------
/works/requests/juejin.js:
--------------------------------------------------------------------------------
1 | import { get, post } from "../utils/http-requester.js"
2 | import {ARTICLE_API, COLUMN_LIST_API, RECENT_ARTICLE_API, CATEGORY_LIST_API, USER_API} from "../apis/juejin.js"
3 |
4 | const getArticleParams = (user_id) => ({
5 | sort_type: 2,
6 | user_id, // 用户id
7 | })
8 | const getColumnsListParams = (user_id) => {
9 | return {
10 | audit_status: 2, // 审核状态(2为审核通过
11 | user_id: user_id,
12 | limit: 10,
13 | }
14 | }
15 | const getRecentArticleParams = (cate_id) => {
16 | return {
17 | cate_id, // 类别 ID
18 | id_type: 2,
19 | limit: 20,
20 | sort_type: 300, // 默认最新排序
21 | }
22 | }
23 |
24 | // 通用终止轮询判断
25 | export const commonPollingOver = (responseData) => {
26 | return responseData.err_no !== 0 || !responseData.data || !responseData.data.length
27 | }
28 | // 通用轮询请求
29 | export const commonPollingRequest = async (url, requestBodyGenerator, overPolling = commonPollingOver) => {
30 | const resList = []
31 | let idx = 0
32 | let badCount = 0
33 | let lastResponse = null
34 | console.log("循环请求开始~")
35 | console.log("请求地址:", url)
36 | while (true) {
37 | const requestBody = requestBodyGenerator(idx, lastResponse)
38 |
39 | let res = await post(url, requestBody)
40 |
41 | // 有可能网络异常,数据请求不到,那就重复5次
42 | while ((!res || !res.data) && badCount < 5) {
43 | res = await post(url, requestBody)
44 | badCount++
45 | }
46 |
47 | // 五次之后还是有问题就抛出异常(事不过五)
48 | if (badCount >= 5) {
49 | throw new Error(url + " 请求故障,请重试!")
50 | }
51 |
52 | if (overPolling(res.data)) {
53 | console.log("循环请求结束~")
54 | break
55 | }
56 | resList.push(...res.data.data)
57 |
58 | lastResponse = res
59 | badCount = 0
60 |
61 | idx++
62 | }
63 | return resList
64 | }
65 |
66 | // 获取用户所有文章
67 | export const getUserArticles = async (userId) => {
68 | const requestBodyGenerator = (idx) => {
69 | return {
70 | ...getArticleParams(userId),
71 | cursor: String(idx * 10),
72 | }
73 | }
74 | return await commonPollingRequest(ARTICLE_API, requestBodyGenerator)
75 | }
76 | // 获取用户所有专栏
77 | export const getUserColumns = async (userId) => {
78 | const requestBodyGenerator = (idx) => {
79 | return {
80 | ...getColumnsListParams(userId),
81 | cursor: idx.toString(),
82 | }
83 | }
84 | return await commonPollingRequest(COLUMN_LIST_API, requestBodyGenerator)
85 | }
86 |
87 | // 掘金默认分类
88 | export const getCategoryList = async () => {
89 | const res = await get(CATEGORY_LIST_API)
90 |
91 | return res.data.data
92 | }
93 | // 近期热门文章
94 | export const getRecentArticles = async (cate_id, days = 3) => {
95 | const now = Date.now()
96 | const timeStep = days * 24 * 3600 * 1000 // 近三天
97 |
98 | const requestBodyGenerator = (idx, lastResponse) => {
99 | return {
100 | ...getRecentArticleParams(cate_id),
101 | cursor: lastResponse ? lastResponse.data.cursor : "0",
102 | }
103 | }
104 | const pollingOver = (responseData) => {
105 | if (commonPollingOver(responseData)) return true
106 |
107 | const list = responseData.data
108 | const length = list.length
109 |
110 | return list.filter((i) => now - Number(i.article_info.ctime + "000") > timeStep).length >= length * 0.8
111 | }
112 |
113 | const allArticles = await commonPollingRequest(RECENT_ARTICLE_API, requestBodyGenerator, pollingOver)
114 |
115 | return allArticles.filter((i) => now - Number(i.article_info.ctime + "000") < timeStep)
116 | }
117 |
118 | // 指定用户个人信息
119 | export const getUserInfo = async (user_id) => {
120 | const res = await get(USER_API, { user_id })
121 |
122 | return res.data.data
123 | }
124 |
--------------------------------------------------------------------------------
/works/store/configuration/index.js:
--------------------------------------------------------------------------------
1 | import configurations from "../../../configurations.js"
2 | import { statSync } from "fs"
3 | import { fileURLToPath } from "url"
4 | import * as path from "path"
5 |
6 | let hasUserConfigFile = true
7 | let mergedConfig = null
8 |
9 | function slash(path) {
10 | const isExtendedLengthPath = path.startsWith("\\\\?\\")
11 |
12 | if (isExtendedLengthPath) {
13 | return path
14 | }
15 | return path.replace(/\\/g, "/")
16 | }
17 |
18 | const mergeConfig = (target, source) => {
19 | for (const sourceKey in source) {
20 | if (!target[sourceKey]) {
21 | target[sourceKey] = source[sourceKey]
22 | } else {
23 | target[sourceKey] = { ...(source[sourceKey] || {}), ...target[sourceKey] }
24 | }
25 | }
26 | return target
27 | }
28 |
29 | export const getGlobalConfig = async () => {
30 | if (mergedConfig) return mergedConfig
31 |
32 | try {
33 | hasUserConfigFile = !!statSync("./configurations.user.js")
34 | } catch (e) {
35 | hasUserConfigFile = false
36 | }
37 |
38 | if (hasUserConfigFile) {
39 | const filePath = slash(
40 | path.normalize(path.relative(path.dirname(fileURLToPath(import.meta.url)), "configurations.user.js")),
41 | )
42 | const { default: userConfig } = await import(filePath)
43 |
44 | mergedConfig = mergeConfig(userConfig || {}, configurations)
45 | } else {
46 | mergedConfig = configurations
47 | }
48 |
49 | return mergedConfig
50 | }
51 |
--------------------------------------------------------------------------------
/works/store/index.js:
--------------------------------------------------------------------------------
1 | export * from "./juejin/index.js"
2 |
--------------------------------------------------------------------------------
/works/store/juejin/index.js:
--------------------------------------------------------------------------------
1 | import { getUserArticles, getUserColumns } from "../../requests/juejin.js"
2 | import { getArticleInfo } from "../../generator/juejin/utils.js"
3 | import { getGlobalConfig } from "../configuration/index.js"
4 |
5 | let articles = null
6 | let columns = null
7 | let yearCollection = new Map()
8 | let yearMonthCollection = new Map()
9 | let categoryCollection = new Map()
10 | let tagCollection = new Map()
11 |
12 | export const setArticles = async (newArticles = [], useSort = false) => {
13 | yearCollection.clear()
14 | yearMonthCollection.clear()
15 | categoryCollection.clear()
16 | tagCollection.clear()
17 |
18 | newArticles.forEach((article) => {
19 | const formatInfo = getArticleInfo(article)
20 |
21 | const { YY, YYYYMM } = formatInfo.dateMap
22 | if (!yearMonthCollection.get(YYYYMM)) {
23 | yearMonthCollection.set(YYYYMM, 0)
24 | }
25 | const yearMonthColl = yearMonthCollection.get(YYYYMM)
26 | yearMonthCollection.set(YYYYMM, yearMonthColl + 1)
27 |
28 | if (!yearCollection.get(YY)) {
29 | yearCollection.set(YY, { count: 0, articles: [] })
30 | }
31 | const yearColl = yearCollection.get(YY)
32 | yearColl.count += 1
33 | yearColl.articles.push(article)
34 |
35 | const { category, tags } = article
36 |
37 | if (!categoryCollection.get(category.category_id)) {
38 | categoryCollection.set(category.category_id, { info: category, count: 0, articles: [] })
39 | }
40 | const categoryColl = categoryCollection.get(category.category_id)
41 | categoryColl.count += 1
42 | categoryColl.articles.push(article)
43 |
44 | for (const tag of tags) {
45 | if (!tagCollection.get(tag.tag_id)) {
46 | tagCollection.set(tag.tag_id, { info: tag, count: 0, articles: [] })
47 | }
48 | const tagColl = tagCollection.get(tag.tag_id)
49 | tagColl.count += 1
50 | tagColl.articles.push(article)
51 | }
52 |
53 | article.formatInfo = formatInfo
54 | })
55 |
56 | articles = newArticles
57 |
58 | if (useSort) {
59 | articles = newArticles.sort((prev, next) => next.article_info.ctime - prev.article_info.ctime)
60 | }
61 |
62 | return articles
63 | }
64 | export const getArticles = async () => {
65 | if (!articles) {
66 | const configurations = await getGlobalConfig()
67 |
68 | const newArticles = await getUserArticles(configurations.juejin.userId)
69 | await setArticles(newArticles, true)
70 | }
71 | return articles
72 | }
73 |
74 | export const setColumns = async (newColumns) => {
75 | return (columns = newColumns)
76 | }
77 | export const getColumns = async () => {
78 | if (!columns) {
79 | const configurations = await getGlobalConfig()
80 |
81 | await setColumns(getUserColumns(configurations.juejin.userId))
82 | }
83 | return columns
84 | }
85 |
86 | // 所有专栏与文章列表
87 | export const processColumnArticleMap = async (columnList, articlesMap, callback) => {
88 | const columnMap = new Map()
89 |
90 | for (let i = 0; i < columnList.length; i++) {
91 | const { column, column_version, column_id } = columnList[i]
92 |
93 | if (!column_version || columnMap.get(column_id)) continue
94 |
95 | const { content_sort_ids = [] } = column
96 |
97 | const columnArticleList = content_sort_ids.map((id) => articlesMap.get(id))
98 |
99 | callback && callback(columnArticleList)
100 |
101 | columnMap.set(column_id, { articles: columnArticleList, columnInfo: columnList[i] })
102 | }
103 |
104 | return columnMap
105 | }
106 |
107 | // 数据组合
108 | export const getArticlesAndColumnsMap = async () => {
109 | const articles = await getArticles()
110 | const columns = await getColumns()
111 |
112 | const articlesMap = new Map()
113 |
114 | articles.forEach((article) => articlesMap.set(article.article_id, article))
115 |
116 | let unColumnArticles = [...articles]
117 |
118 | const removeUnColumnArticle = (columnArticleList) => {
119 | if (!columnArticleList) return
120 | for (let idx = 0; idx < columnArticleList.length; idx++) {
121 | if (!columnArticleList[idx]) continue
122 |
123 | const { article_id } = columnArticleList[idx]
124 | if (!article_id) continue
125 |
126 | const removeIndex = unColumnArticles.findIndex((item) => item.article_id === article_id)
127 | if (removeIndex > -1) {
128 | unColumnArticles.splice(removeIndex, 1)
129 | }
130 | }
131 | }
132 |
133 | const columnMap = await processColumnArticleMap(columns, articlesMap, removeUnColumnArticle)
134 |
135 | return {
136 | articles,
137 | articlesMap,
138 | unColumnArticles,
139 | columns,
140 | columnMap,
141 | yearCollection,
142 | yearMonthCollection,
143 | tagCollection,
144 | categoryCollection,
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/works/template/index.js:
--------------------------------------------------------------------------------
1 | export * from "./vitepress/vitepress.config.js"
2 |
3 | export * from "./vitepress/vitepress.index.md.js"
4 |
--------------------------------------------------------------------------------
/works/template/vitepress/vitepress.config.js:
--------------------------------------------------------------------------------
1 | // vitepress 配置文件模板
2 | export const vitePressConfigJs = `import { defineConfig } from "vitepress"
3 |
4 | export default defineConfig({
5 | title: "{{ name }}",
6 | appearance: "light",
7 | description: "{{ description }}",
8 | locales: {
9 | root: {
10 | label: "简体中文",
11 | link: "/",
12 | lang: "zh-CN",
13 | },
14 | },
15 | srcDir: "src",
16 | head: {{ head }},
17 | themeConfig: {
18 | logo: "{{ logo }}",
19 | search: { provider: "local" },
20 | outline: "deep",
21 | nav: {{ nav }},
22 | socialLinks: {{ socialLinks }},
23 | footer: {
24 | copyright: \`Copyright © 2023-\${new Date().getFullYear()} {{author}}\`,
25 | message: "Released under the MIT License.",
26 | },
27 | },
28 | vite: {
29 | ssr: {
30 | noExternal: [
31 | "@nolebase/vitepress-plugin-enhanced-readabilities",
32 | ],
33 | },
34 | },
35 | })
36 | `
37 |
--------------------------------------------------------------------------------
/works/template/vitepress/vitepress.index.md.js:
--------------------------------------------------------------------------------
1 | // vitepress 主页 markdown 模板
2 | export const homeTemplate = `---
3 | layout: home
4 |
5 | hero:
6 | name: {{ name }}
7 | text: {{ text }}
8 | tagline: {{ tagline }}
9 | image: {{ image }}
10 | actions: {{ actions }}
11 |
12 | features: {{ features }}
13 |
14 | ---
15 | `
16 |
17 | export const actionTemplate = `
18 | - theme: {{ theme }}
19 | text: {{ text }}
20 | link: {{ link }}`
21 |
22 | export const featureTemplate = `
23 | - title: {{ title }}
24 | details: {{ details }}`
25 |
26 | export const teamTemplate = `
27 |
32 |
33 |
34 |
35 | Our Team
36 |
37 |
38 |
39 |
40 | `
41 |
--------------------------------------------------------------------------------
/works/utils/common.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 在指定位置插入字符串
3 | *
4 | * @param {string} str - 原始字符串
5 | * @param {number} index - 插入位置的索引
6 | * @param {string} insertStr - 要插入的字符串
7 | * @returns {string} - 插入后的新字符串
8 | */
9 | export function insertString(str, index, insertStr) {
10 | return str.substring(0, index) + insertStr + str.substring(index)
11 | }
12 |
13 | /**
14 | * 对数组进行排序并返回前10个元素
15 | *
16 | * @param {Array} articles - 要排序的数组
17 | * @param {string} key - 用于排序的键名
18 | * @returns {Array} - 排序后的前10个元素数组
19 | */
20 | export const sortArticleArray = (articles, key) => {
21 | const copyArr = articles.slice()
22 | return copyArr.sort((a, b) => b.formatInfo[key] - a.formatInfo[key]).slice(0, 10)
23 | }
24 |
--------------------------------------------------------------------------------
/works/utils/date-formatter.js:
--------------------------------------------------------------------------------
1 | export default function getMapByString(date) {
2 | const source = new Date(date)
3 | const YY = source.getFullYear().toString() // 年
4 | let MM = source.getMonth() + 1 // 月
5 | MM = MM < 10 ? "0" + MM.toString() : MM.toString()
6 | let DD = source.getDate() // 日
7 | DD = DD < 10 ? "0" + DD.toString() : DD.toString()
8 |
9 | const hour = (source.getHours() < 10 ? "0" + source.getHours() : source.getHours()) + ":" // 得到小时数
10 | const minute = (source.getMinutes() < 10 ? "0" + source.getMinutes() : source.getMinutes()) + ":" // 得到分钟数
11 | const second = source.getSeconds() < 10 ? "0" + source.getSeconds() : source.getSeconds() // 得到秒数
12 |
13 | const YMD = YY + "-" + MM + "-" + DD
14 | const YYYYMMDD = YY + "" + MM + "" + DD
15 | const YYYYMM = YY + "" + MM
16 | const YMDHMS = YMD + " " + hour + minute + second
17 |
18 | return {
19 | YY,
20 | MM,
21 | DD,
22 | YMD,
23 | YYYYMM,
24 | YYYYMMDD,
25 | YMDHMS,
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/works/utils/http-requester.js:
--------------------------------------------------------------------------------
1 | import axios from "axios"
2 |
3 | export function sleep(second = 3000, data) {
4 | return new Promise((resolve) => {
5 | setTimeout(() => resolve(data), second)
6 | })
7 | }
8 |
9 | export const get = async (url, params) => {
10 | try {
11 | return await axios.get(url, { params })
12 | } catch (e) {
13 | console.log("Get " + url + " 请求异常", e)
14 | }
15 | }
16 |
17 | export const post = async (url, data) => {
18 | try {
19 | return await axios.post(url, data, {
20 | headers: {
21 | "Content-Type": "application/json",
22 | },
23 | })
24 | } catch (e) {
25 | console.log("Get " + url + " 请求异常", e)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/works/utils/template-process.js:
--------------------------------------------------------------------------------
1 | import {insertString} from "./common.js";
2 |
3 | /**
4 | * 使用正则表达式匹配双大括号之间的内容并进行二次处理
5 | * @param {string} str
6 | * @param {(string) => string} callback
7 | * @return {string}
8 | */
9 | export function replaceKeywords(str, callback) {
10 | const pattern = /{{(.*?)}}/g
11 | const matches = str.match(pattern)
12 |
13 | if (matches) {
14 | const processedMatches = matches.map((match) => callback(match.replace(/{{|}}/g, "").trim()))
15 |
16 | return str.replace(pattern, () => processedMatches.shift())
17 | }
18 |
19 | return str
20 | }
21 |
22 | /**
23 | * 排行榜数据前置标记
24 | */
25 | export const markerMap = {
26 | 0: "🥇 ",
27 | 1: "🥈 ",
28 | 2: "🥉 ",
29 | x: (idx) => `${idx + 1}. `,
30 | }
31 | /**
32 | * 生成文章数据,插入排行榜标记
33 | * @param {Array} articles
34 | */
35 | export const processTopArticles = (articles) => {
36 | return articles
37 | .map((i, idx) => {
38 | return insertString(i.formatInfo.mdString, 7, markerMap[idx] || markerMap.x(idx))
39 | })
40 | .join("\n\n")
41 | }
42 |
--------------------------------------------------------------------------------
/works/website/juejin.js:
--------------------------------------------------------------------------------
1 | // 拼接部分
2 | export const JUEJIN_URL = "https://juejin.cn/"
3 | export const JUEJIN_USER_URL = JUEJIN_URL + "user/"
4 | export const JUEJIN_POST_URL = JUEJIN_URL + "post/"
5 | export const JUEJIN_COLUMN_URL = JUEJIN_URL + "column/"
6 |
--------------------------------------------------------------------------------