diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..dfe0770
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,2 @@
+# Auto detect text files and perform LF normalization
+* text=auto
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 0000000..013df3b
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,61 @@
+name: docs build
+
+on:
+ push:
+ branches:
+ # 确保这是你正在使用的分支名称
+ - main
+
+jobs:
+ LearnHubs-build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout 🛎️
+ uses: actions/checkout@v4
+ with:
+ # 获取所有标记和分支的所有历史记录(updatetime 必须,否则每次都会变化)
+ fetch-depth: 0
+ # 如果你文档需要 Git 子模块,取消注释下一行
+ # submodules: true
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v2
+ with:
+ run_install: true
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: 18
+ cache: pnpm
+
+ # 将读书笔记复制到静态页路径,然后构建页面
+ - name: Build Docs
+ env:
+ NODE_OPTIONS: --max_old_space_size=8192
+ run: |-
+ pnpm cpx "docs/reading/**" docs/.vuepress/public/reading
+ pnpm run docs:build
+ > docs/.vuepress/dist/.nojekyll
+
+ - name: Deploy GitHub Pages
+ uses: JamesIves/github-pages-deploy-action@v4
+ with:
+ # 这是文档部署到的分支名称
+ branch: lh-pages
+ folder: docs/.vuepress/dist
+ # 将页面更新到 Vercel
+ - name: Copy file to Vercel
+ if: always()
+ uses: andstor/copycat-action@v3
+ with:
+ personal_token: ${{ secrets.PERSONAL_TOKEN }}
+ src_path: /.
+ dst_path: /
+ # 你的用户名
+ dst_owner: libaxuan
+ # 与 Vercel 链接的仓库名,也就是 Vercel 部署时新建的仓库
+ dst_repo_name: LearnHubs-vercel
+ dst_branch: main
+ src_branch: lh-pages
+ clean: true
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a3ed162
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,15 @@
+# Node modules
+**/node_modules/**
+
+# Cache
+**/.vuepress/.cache/**
+# Temp
+**/.vuepress/.temp/**
+# Output
+**/.vuepress/dist/**
+
+# 自定义草稿箱
+docs/_temp/
+
+# GoodSync
+_gsdata_/
\ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/LearnHubs.iml b/.idea/LearnHubs.iml
new file mode 100644
index 0000000..0c8867d
--- /dev/null
+++ b/.idea/LearnHubs.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..fe8a936
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.markdownlint.json b/.markdownlint.json
new file mode 100644
index 0000000..1a86aee
--- /dev/null
+++ b/.markdownlint.json
@@ -0,0 +1,24 @@
+{
+ "default": true,
+ "MD003": {
+ "style": "atx"
+ },
+ "MD004": {
+ "style": "dash"
+ },
+ "MD013": false,
+ "MD024": {
+ "allow_different_nesting": true
+ },
+ "MD033": {
+ "allowed_elements": ["br", "template", "script", "style", "BiliBili"]
+ },
+ "MD035": {
+ "style": "---"
+ },
+ "MD036": false,
+ "MD040": false,
+ "MD045": false,
+ "MD046": false,
+ "MD049": false
+}
diff --git a/.markdownlintignore b/.markdownlintignore
new file mode 100644
index 0000000..4ca1a03
--- /dev/null
+++ b/.markdownlintignore
@@ -0,0 +1 @@
+docs/reading/**
diff --git a/.npmrc b/.npmrc
new file mode 100644
index 0000000..8051a48
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1,2 @@
+auto-install-peers=true
+strict-peer-dependencies=false
\ No newline at end of file
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 0000000..979b152
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,16 @@
+# Vuepress Cache
+**/.vuepress/.cache/**
+# Vuepress Temp
+**/.vuepress/.temp/**
+# Vuepress Output
+**/.vuepress/dist/**
+**/.vuepress/templateBuild.html
+
+# live2d
+docs/.vuepress/public/live2d-widget/**
+
+# Node modules
+node_modules/
+
+# pnpm lock file
+pnpm-lock.yaml
diff --git a/.vercel/README.txt b/.vercel/README.txt
new file mode 100644
index 0000000..525d8ce
--- /dev/null
+++ b/.vercel/README.txt
@@ -0,0 +1,11 @@
+> Why do I have a folder named ".vercel" in my project?
+The ".vercel" folder is created when you link a directory to a Vercel project.
+
+> What does the "project.json" file contain?
+The "project.json" file contains:
+- The ID of the Vercel project that you linked ("projectId")
+- The ID of the user or team your Vercel project is owned by ("orgId")
+
+> Should I commit the ".vercel" folder?
+No, you should not share the ".vercel" folder with anyone.
+Upon creation, it will be automatically added to your ".gitignore" file.
diff --git a/.vercel/project.json b/.vercel/project.json
new file mode 100644
index 0000000..b90a86c
--- /dev/null
+++ b/.vercel/project.json
@@ -0,0 +1 @@
+{"orgId":"ranNkfMcGsOCEN6rlr5hLh70","projectId":"prj_40UNYZwDdnvbBY7BZhpWuvRsmu5R"}
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..66b6570
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 libaxuan
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..1a7bf7c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,265 @@
+> 开源工具、效率方法、心理学探索的自我提升笔记
+
+
+
+ Table of Contents
+
+
+
+
+
+
+
+## ✨ 初衷
+
+曾经,我采用了 Notion、Obsidian 和 飞书 等多款知识管理工具来存储我的心得与笔记。然而,这种方式导致我的资料分散,难以管理和分享。
+
+更重要的是,**笔记里的知识并不属于你,只有经过消化、应用,才会成为我们的财富。**
+
+为此,我基于 VuePress 和 vuepress-theme-hope 构建了 LearnHubs 学习中心,将我所有的笔记与文章聚合到同一页面形成知识库,便于集中管理和分享。
+
+![](/img/流程1.png?imageMogr2/thumbnail/600x "笔记 + 文章 = LearnHubs 知识库")
+
+![](/img/流程2.png "笔记/博客自动化发布")
+
+## 🧱 笔记结构
+
+- 置顶:日常习惯、健身、阅读;
+- 软件应用:常用应用、Chrome 扩展和相关教程;
+- Docker 服务:NAS 和服务器上的后端应用,主要以 Docker 方式部署;
+- 系统问题:Windows 系统优化和相关问题;
+- 代码编程:常用代码的学习和使用笔记,页面开发攻略和网站相关的工具和知识收集;
+- 生活角落:说明书、生活记录和小技巧;
+- 博客汇总:聚合所有博客文章,以分类、标签、时间轴等方式进行组合。
+
+## 🍥 搭建 LearnHubs
+
+1. 首先,进入 [LearnHubs](https://github.com/libaxuan/LearnHubs) 项目页,点击右上角「Use this template」后选择「Create a new repository」。
+
+
+
+2. 接着,进入项目仓库的「Settings」>「Actions」>「General」,选中底部 Workflow permissions 中的 `Read and write permissions`,然后点击保存即可。如果未授权,GitHub Page 部署会由于 repo 权限不足而报错 `failed with exit code 128`。
+
+ ![](/img/readandwrite.webp?imageMogr2/format/webp)
+
+3. 接下来,请进入菜单栏顶部的「Actions」>「最新的 workflow」,并点击右上方的「Re-run jobs」>「Re-run all jobs」,以重新生成网页。若部署正确,GitHub 将自动搭建 gh-page 分支页面。
+
+ ![](/img/actions.png)
+
+
+ 需要注意的是:如果你不需要将网页部署同步到个人服务器,**请删除 `.github/workflows/main.yml` 中 Sync files 区块的代码**,否则会出现报错 `Error: Input required and not supplied: server`。
+
+ ```yaml
+ ### 没有服务器的话,请删除本区块代码,防止报错 ###
+ # 将页面推送到服务器,timeout 时间从默认的 1 分钟调整到 10 分钟。
+ - name: 📂 Sync files
+ uses: SamKirkland/FTP-Deploy-Action@v4.3.4
+ with:
+ local-dir: docs/.vuepress/dist/
+ server: ${{ secrets.ftp_host }}
+ username: ${{ secrets.ftp_username }}
+ password: ${{ secrets.ftp_password }}
+ port: ${{ secrets.ftp_port }} # 建议更改默认的 21 端口
+ timeout: 600000
+ ### 没有服务器的话,请删除本区块代码,防止报错 ###
+ ```
+
+4. 然后点击「Settings」, 修改 `Repository name` 为 `用户名.github.io`。假设你的仓库链接是 `https://github.com/xxx/LearnHubs`,那么中间的 `xxx` 就是你的用户名。如果该仓库名称已被使用,GitHub Pages 将无法正常显示样式,请查看页面底部的常见问题来设置子域名。
+
+ ![](/img/libaxuan-github-io.png)
+
+5. 在同一页面选择「Settings」>「Pages」>「Build and deployment」>「Branch」, 将 gh-page branch 设为 GitHub Pages 的来源,网站运行目录默认为 `/(root)`。设置完成后,点击「Save」。如果找不到 lh-pages 分支,可以按照上面提到的第三步进行操作,或在 GitHub 中修改任意文件以手动触发 GitHub Action,等待其执行完成后,再重新设置 Pages 的来源。
+
+ ![](https://iili.io/JnQjSpe.webp?imageMogr2/format/webp)
+
+6. 设置成功后,页面会提示访问链接:`https://xxx.github.io/`。此时,你的知识库就已经搭建完成了。
+
+ 如果未出现访问链接提示或不能打开 GitHub Pages,则删除 `docs/_posts` 路径下的博客文章。这是因为 GitHub Pages 有时会对旧文章里的代码报错。
+
+注意:如果出现报错 `Error: Input required and not supplied: server`,请删除 `.github/workflows/main.yml` 中 Sync files 区块的代码,以避免出现报错。
+
+## 🔣 配置 LearnHubs
+
+### 文档结构
+
+LearnHubs 网站的配置和文本都存放在 `docs` 文件夹中。文章和页面的配置可参考主目录下的 [samplepage.md](https://github.com/libaxuan/LearnHubs/blob/main/samplepage.md?plain=1)。其中,`order` 参数表示侧边栏的顺序,数字越小越靠前,支持非整数和负数。我个人的偏好是将非干货或随想短文的 order 设置在 -0.01 到 -0.99,将干货类长文的 order 设置在 -1 到负无穷。每次新增文章都会在上一篇的基础上递减 order 值。这种设置使我能随时记录低于 1000 字的短文,同时不会影响那些寻求干货文章的用户体验,因为干货文章的排序始终保持在最上方。
+
+docs 目录结构如下:
+
+```bash
+docs
+|── .vuepress # 网站配置
+│ ├── config.ts # 网站环境依赖和网站属性
+│ ├── sidebar.ts # 侧边栏
+│ ├── navbar.ts # 导航栏
+│ ├── theme.ts # 主题和插件
+│ └── templateBuild.html # 网页模板,网站关键词和统计
+|── _posts # 博客文章目录
+├── _temp # 草稿箱
+├── reading # 读书笔记
+├── anyname # 自定义笔记
+├── blog.md # 博客页面
+└── intro.md # 博主个人介绍
+```
+
+`docs/.vuepress` 路径下是网站的配置文件,我已添加了详细的注释。你可以参考注释和 [vuepress-theme-hope 配置案例](https://github.com/vuepress-theme-hope/vuepress-theme-hope/tree/main/docs/theme/src/.vuepress)来调整配置。请在 `docs/.vuepress/sidebar.ts` 文件中修改文件夹路径,后台会自动抓取路径下的 md 文件来生成侧边栏。`docs/.vuepress/theme.ts` 有[评论插件](https://gpt-vip.top/web/Comments.html)的相关配置。
+
+注意:
+
+- LearnHubs 默认使用了 algolia 全文搜索。如果你没有使用 algolia 爬虫,则可以在 `docs/.vuepress/config.ts` 文件中删除 plugins 下的 docsearchPlugin 区块,网站将转用本地全文索引搜索。
+- `docs/_temp` 文件夹默认不同步到 GitHub 上。你可以手动在本地建立 `_temp` 文件夹,用来存放草稿。
+- 自 VuePress2 的 beta.54 版本开始,文件夹名前缀为 `_` 在生成链接时将被省略,例如文章路径为 `/_posts/`,但网页链接路径会是 `/posts/`。
+
+### 看板娘
+
+LearnHubs 集成了看板娘 [Live2D Widget](https://github.com/stevenjoezhang/live2d-widget),支持随机对话、切换人物服饰和玩打飞机游戏,能提升网站美观度和趣味性。如果不需要看板娘,可以删除 `docs\.vuepress\public` 下的 live2d-widget 文件夹。
+
+如果网站部署在子页面 `https://xxx.github.io/yyy`,则需将子页面路径 yyy 加入到以下两个文件:
+
+- 将 `docs\.vuepress\public\live2d-widget\autoload.js` 文件第三行的 `const live2d_path = "/live2d-widget/"` 修改为 `const live2d_path = "/yyy/live2d-widget/"`。
+- 将 `docs\.vuepress\templateBuild.html` 文件中看板娘区块代码 `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+