├── .github
└── dependabot.yml
├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── _config.yml
├── layout
├── archives.ejs
├── card.ejs
├── categories.ejs
├── comment.ejs
├── current.ejs
├── footer.ejs
├── import.ejs
├── index.ejs
├── layout.ejs
├── menu.ejs
├── post.ejs
├── posts.ejs
└── tags.ejs
├── package.json
├── pnpm-lock.yaml
└── source
├── css
└── main.css
├── images
└── loading.gif
└── js
├── lib
├── crypto.js
├── highlight.js
├── home.js
├── math.js
├── preview.js
└── search.js
└── main.js
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: npm
4 | directory: /
5 | schedule:
6 | interval: daily
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules/
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Argvchs
4 | Copyright (c) 2020 korilin
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Hexo-Theme-ParticleX
2 |
3 | [ParticleX](https://github.com/theme-particlex/hexo-theme-particlex) 主题,诞生原因是因为原来的 [Particle](https://github.com/korilin/hexo-theme-particle) 主题不维护了,但是我觉得还是很好的。
4 |
5 | 原来用的是 Vue 2 + Ant Design Vue 1,现更新到 Vue 3,去除 Ant Design Vue 采用自定义样式,图标更改为 Font Awesome 6,CDN 改为 ZStatic。
6 |
7 | 原项目 `README.md` 里说:
8 |
9 | > 目前有 Full、Night 和 Maiden **两个**主题样式。
10 |
11 | 但是更改后只有一种了,如果你想改颜色就在 `main.css` 里替换吧。
12 |
13 | # 1. 演示
14 |
15 | - [GitHub Pages](https://argvchs.github.io)
16 | - [Netlify](https://argvchs.netlify.app)
17 | - [Vercel](https://argvchs.vercel.app)
18 |
19 | # 2. 安装
20 |
21 | ```bash
22 | cd themes
23 | git clone https://github.com/theme-particlex/hexo-theme-particlex.git particlex --depth=1
24 | ```
25 |
26 | 然后在根目录 `_config.yml` 设置主题为 ParticleX 即可。
27 |
28 | ```yaml
29 | theme: particlex
30 | ```
31 |
32 | ## 2.1. 关闭自带代码高亮
33 |
34 | Hexo 有自带的代码高亮,但是和 ParticleX 的不兼容。
35 |
36 | ```yaml
37 | highlight:
38 | enable: false
39 | prismjs:
40 | enable: false
41 | ```
42 |
43 | 如果使用 Hexo 7.0.0 之后的版本只需要修改为:
44 |
45 | ```yaml
46 | syntax_highlighter:
47 | ```
48 |
49 | 如果使用 Pandoc 还需要设置一下:
50 |
51 | ```yaml
52 | pandoc:
53 | extra:
54 | - no-highlight:
55 | ```
56 |
57 | ## 2.2. 禁用年度月度归档
58 |
59 | Hexo 会自动生成年度月度归档,可是 ParticleX 主题没有这个功能。~~我太懒了~~
60 |
61 | ```yaml
62 | archive_generator:
63 | enabled: true
64 | per_page: 0
65 | yearly: false
66 | monthly: false
67 | daily: false
68 | ```
69 |
70 | 修改完请 `hexo cl` 清除缓存。
71 |
72 | # 3. 配置
73 |
74 | ## 3.1. 基本配置
75 |
76 | `background` 参数是一个列表,打开时会随机加载一个背景。
77 |
78 | ```yaml
79 | # Avatar image
80 | avatar: /images/avatar.jpg
81 |
82 | # Home page background image
83 | background:
84 | - /images/background.jpg
85 |
86 | # Loading image
87 | loading: /images/loading.gif
88 |
89 | # Optional colors for category and tag
90 | colors:
91 | - "#ffa2c4"
92 | - "#00bcd4"
93 | - "#03a9f4"
94 | - "#00a596"
95 | - "#ff7d73"
96 | ```
97 |
98 | ## 3.2. 内容配置
99 |
100 | ### 3.2.1. 导航栏
101 |
102 | 为了方便,主题使用的图标是 Font Awesome 6 图标。
103 |
104 | ```yaml
105 | # ParticleX theme icon is adopts the Font Awesome 6
106 | # https://fontawesome.com
107 |
108 | # Main menu navigation
109 | menu:
110 | Home:
111 | name: house
112 | theme: solid
113 | link: /
114 | About:
115 | name: id-card
116 | theme: solid
117 | link: /about
118 | Archives:
119 | name: box-archive
120 | theme: solid
121 | link: /archives
122 | Categories:
123 | name: bookmark
124 | theme: solid
125 | link: /categories
126 | Tags:
127 | name: tags
128 | theme: solid
129 | link: /tags
130 | ```
131 |
132 | ### 3.2.2. 主页信息卡片
133 |
134 | `description` 支持 Markdown 格式。
135 |
136 | 图标链接 `iconLinks` 配置和导航栏配置相同。
137 |
138 | ```yaml
139 | # Side info card
140 | card:
141 | enable: true
142 | description: |
143 | Description
144 | ...
145 | iconLinks:
146 | friendLinks:
147 | Argvchs: https://argvchs.github.io
148 | ```
149 |
150 | ### 3.2.3. 页脚
151 |
152 | 考虑到博客部署在服务器并使用自己域名的情况,按规定需要在网站下边添加备案消息。
153 |
154 | 如没有需要显示备案消息的可以关闭。
155 |
156 | ```yaml
157 | # Footer info
158 | footer:
159 | since: 2022
160 | # Customize the server domain name ICP
161 | ICP:
162 | enable: false
163 | code:
164 | link:
165 | ```
166 |
167 | ## 3.3. 功能配置
168 |
169 | ### 3.3.1. Polyfill
170 |
171 | 使用 [Polyfill.io](https://polyfill.io) 自动根据 UA 处理新的 JS API 兼容。
172 |
173 | 可以配合 [Hexo-Babel](https://github.com/theme-particlex/hexo-babel) 插件处理 JS 语法兼容。
174 |
175 | Polyfill 在国内一些省份被墙,这里换成了阿里的 [Polyfill](https://polyfill.alicdn.com)。
176 |
177 | ```yaml
178 | # Polyfill
179 | # https://polyfill.io
180 | polyfill:
181 | enable: true
182 | features:
183 | - default
184 | ```
185 |
186 | ### 3.3.2. 代码高亮
187 |
188 | 使用 Highlight.js 代码高亮。
189 |
190 | 样式可以在[这里](https://highlightjs.org/static/demo)选择,默认为 GitHub。
191 |
192 | ```yaml
193 | # Highlight.js
194 | # https://highlightjs.org
195 | highlight:
196 | enable: true
197 | style: github
198 | ```
199 |
200 | ### 3.3.3. 数学渲染
201 |
202 | 使用 KaTeX 渲染数学公式。
203 |
204 | ```yaml
205 | # KaTeX math rendering
206 | math:
207 | enable: false
208 | ```
209 |
210 | ### 3.3.4. 图片预览
211 |
212 | 简单的点击图片放大缩小的预览。
213 |
214 | ```yaml
215 | # Image preview
216 | preview:
217 | enable: true
218 | ```
219 |
220 | ### 3.3.5. 文章缩略
221 |
222 | 一般来说,缩略展示文档只需要在文档中添加 `` 即可,缩略内容在显示全文中也会出现。
223 |
224 | 但考虑到不想把缩略内容放在正文里,就添加了此参数,在 [Front-Matter](https://hexo.io/docs/front-matter) 里设置。
225 |
226 | 支持 Markdown 格式。
227 |
228 | ```yaml
229 | description: |
230 | Normal _Italic_ **Strong**
231 | ```
232 |
233 | ### 3.3.6. 文章置顶
234 |
235 | 在 [Front-Matter](https://hexo.io/docs/front-matter) 里设置 `pinned` 作为置顶参数,越大越靠前,默认为 0。
236 |
237 | ### 3.3.7. 文章加密
238 |
239 | 使用 AES 加密算法,在 [Front-Matter](https://hexo.io/docs/front-matter) 里设置 `secret` 作为密码,**使用请安装插件 [Hexo-Helper-Crypto](https://github.com/theme-particlex/hexo-helper-crypto)**。
240 |
241 | ```yaml
242 | # Article encryption
243 | crypto:
244 | enable: false
245 | ```
246 |
247 | ### 3.3.8. 搜索
248 |
249 | 嵌入到 Archives 中的搜索。
250 |
251 | 目前只支持搜索文档标题。
252 |
253 | ```yaml
254 | # Search
255 | search:
256 | enable: false
257 | ```
258 |
259 | ## 3.4. 评论配置
260 |
261 | ### 3.4.1. giscus
262 |
263 | giscus 是一个由 GitHub Discussions 支持的评论系统。
264 |
265 | 在 [giscus.app](https://giscus.app) 设置好各项后,会在下面生成一个 `
18 | <% } %>
19 | <% if (theme.gitalk.enable) { %>
20 |
35 | <% } %>
36 | <% if (theme.waline.enable) { %>
37 |
55 | <% } %>
56 | <% if (theme.twikoo.enable) { %>
57 |
66 | <% } %>
67 |
--------------------------------------------------------------------------------
/layout/current.ejs:
--------------------------------------------------------------------------------
1 |
2 | <% if (page.current !== 1) { %>
3 |
4 |
5 |
6 |
1
7 |
...
8 | <% } %>
9 |
<%= page.current %>
10 | <% if (page.current + 1 <= page.total) { %>
11 |
">
12 | <%= page.current + 1 %>
13 |
14 | <% } %>
15 | <% if (page.current + 2 <= page.total) { %>
16 |
">
17 | <%= page.current + 2 %>
18 |
19 | <% } %>
20 | <% if (page.current + 3 <= page.total) { %>
21 |
...
22 |
"><%= page.total %>
23 | <% } %>
24 | <% if (page.current !== page.total) { %>
25 |
26 |
27 |
28 | <% } %>
29 |
30 |
--------------------------------------------------------------------------------
/layout/footer.ejs:
--------------------------------------------------------------------------------
1 |
27 |
--------------------------------------------------------------------------------
/layout/import.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
11 | <% if (theme.polyfill.enable) { %>
12 |
13 | <% } %>
14 | <% if (theme.highlight.enable) { %>
15 |
16 |
17 |
21 |
22 | <% } %>
23 | <% if (theme.math.enable) { %>
24 |
25 |
26 |
27 |
28 | <% } %>
29 | <% if (theme.preview.enable) { %>
30 |
31 | <% } %>
32 | <% if (theme.crypto.enable && typeof page.secret !== "undefined") { %>
33 |
34 |
35 | <% } %>
36 | <% if (type === "archives" && theme.search.enable) { %>
37 |
38 | <% } %>
39 | <% if (type === "post" && page.comments) { %>
40 | <% if (theme.gitalk.enable) { %>
41 |
42 |
43 | <% } %>
44 | <% if (theme.waline.enable) { %>
45 |
46 |
47 |
48 | <% } %>
49 | <% if (theme.twikoo.enable) { %>
50 |
51 | <% } %>
52 | <% } %>
53 | <% if (type === "index") { %>
54 |
55 | <% } %>
56 |
57 | " />
58 |
59 |
--------------------------------------------------------------------------------
/layout/index.ejs:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
<%= config.title %>
15 | <%= config.subtitle %>
16 | <%= config.description %>
17 |
18 |
19 |
20 |
21 |
25 | >
26 |
27 | <%- partial("posts") %>
28 | <%- partial("current") %>
29 |
30 | <% if (theme.card.enable) { %>
31 |
32 | <%- partial("card") %>
33 |
34 | <% } %>
35 |
36 |
--------------------------------------------------------------------------------
/layout/layout.ejs:
--------------------------------------------------------------------------------
1 | <%
2 | let type = "post";
3 | if (is_home()) type = "index";
4 | if (is_post() || is_page()) type = "post";
5 | if (is_category() || page.type === "categories") type = "categories";
6 | if (is_tag() || page.type === "tags") type = "tags";
7 | if (is_archive()) type = "archives";
8 | let title = page.title + " | " + config.title;
9 | if (is_home()) title = config.title;
10 | if (is_post() || is_page()) title = page.title + " | " + config.title;
11 | if (is_category()) title = "Categories: " + page.category + " | " + config.title;
12 | if (is_tag()) title = "Tags: " + page.tag + " | " + config.title;
13 | if (is_archive()) title = "Archives | " + config.title;
14 | %>
15 |
16 |
17 |
18 |
19 | <%= title %>
20 |
21 |
22 |
23 |
27 |
28 | <%- partial("import", { type }) %>
29 |
30 |
31 |
32 |
33 |
34 |
35 |
LOADING
36 |
加载过慢请开启缓存 浏览器默认开启
37 |
 %>)
38 |
39 |
40 |
41 | <%- partial("menu") %>
42 |
43 | <%- partial(type) %>
44 | <%- partial("footer") %>
45 |
46 | <% if (theme.preview.enable) { %>
47 |
48 |
49 |
![]()
50 |
51 |
52 | <% } %>
53 |
54 |
55 |
62 | <% if (type === "post" && page.comments) { %>
63 | <%- partial("comment") %>
64 | <% } %>
65 |
66 |
67 |
--------------------------------------------------------------------------------
/layout/menu.ejs:
--------------------------------------------------------------------------------
1 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/layout/post.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
<%= page.title %>
4 |
5 |
6 |
7 |
8 |
9 |
10 | <%= date(page.date, "YYYY/M/D") %>
11 |
12 | <% if (page.categories && page.categories.data.length !== 0) { %>
13 |
14 |
15 |
16 |
17 |
18 | <%= page.categories.data[0].name %>
19 |
20 |
21 | <% } %>
22 | <% if (page.tags && page.tags.data.length !== 0) { %>
23 |
24 |
25 |
26 |
27 | <% let prev; %>
28 | <% page.tags.data.forEach((tag) => { %>
29 |
30 | <%
31 | const colors = theme.colors.filter((color) => color !== prev);
32 | let id = Math.floor(Math.random() * colors.length);
33 | prev = colors[id];
34 | %>
35 |
36 | <%= tag.name %>
37 |
38 |
39 | <% }); %>
40 |
41 | <% } %>
42 |
43 | <% if (theme.crypto.enable && typeof page.secret !== "undefined") { %>
44 | <% const CryptoJS = getCryptoJS(); %>
45 |
55 |
56 |
57 |
58 | <% } else { %>
59 |
60 | <%- page.content %>
61 |
62 | <% } %>
63 | <% if (page.comments) { %>
64 | <% if (theme.gitalk.enable) { %>
65 |
68 | <% } %>
69 | <% if (theme.giscus.enable) { %>
70 |
73 | <% } %>
74 | <% if (theme.waline.enable) { %>
75 |
78 | <% } %>
79 | <% if (theme.twikoo.enable) { %>
80 |
83 | <% } %>
84 | <% } %>
85 |
86 |
--------------------------------------------------------------------------------
/layout/posts.ejs:
--------------------------------------------------------------------------------
1 | <%
2 | let posts = site.posts,
3 | current = (page.current - 1) * config.index_generator.per_page;
4 | posts.data.sort((a, b) => {
5 | let x = a.pinned ?? 0,
6 | y = b.pinned ?? 0;
7 | return x === y ? b.date - a.date : y - x;
8 | });
9 | posts = posts.slice(current, config.index_generator.per_page + current);
10 | %>
11 | <% posts.forEach((post) => { %>
12 |
13 |
14 | <%= post.title %>
15 |
16 |
17 | <% if (post.categories.data.length !== 0) { %>
18 |
19 |
20 |
21 |
22 |
23 | <%= post.categories.data[0].name %>
24 |
25 |
26 | <% } %>
27 |
28 |
29 |
30 |
31 | <%- date(post.date, "YYYY/M/D") %>
32 |
33 | <% if (theme.crypto.enable && typeof post.secret !== "undefined") { %>
34 |
35 |
36 |
37 | <% } %>
38 | <% if (typeof post.pinned !== "undefined") { %>
39 |
40 |
41 |
42 | <% } %>
43 |
44 |
45 |
46 | <% if (typeof post.description !== "undefined") { %>
47 | <%- markdown(post.description) %>
48 | <% } else if (post.excerpt) { %>
49 | <%- post.excerpt %>
50 | <% } else { %>
51 | <%- post.content %>
52 | <% } %>
53 |
54 |
55 |
56 | <% if (post.tags.data.length !== 0) { %>
57 |
58 |
59 |
60 | <% } %>
61 | <% let prev; %>
62 | <% post.tags.data.forEach((tag) => { %>
63 |
64 | <%
65 | const colors = theme.colors.filter((color) => color !== prev);
66 | let id = Math.floor(Math.random() * colors.length);
67 | prev = colors[id];
68 | %>
69 | <%= tag.name %>
70 |
71 | <% }); %>
72 |
73 |
阅读全文
74 |
75 | <% }); %>
76 |
--------------------------------------------------------------------------------
/layout/tags.ejs:
--------------------------------------------------------------------------------
1 |
2 | <% let posts = []; %>
3 |
29 | <% posts.forEach((post) => { %>
30 |
31 |
32 |
33 |
<%= date(post.date, "YYYY/M/D") %>
34 |
35 | <%= post.title %>
36 |
37 |
38 | <% if (post.categories && post.categories.data.length !== 0) { %>
39 |
40 |
41 |
42 |
43 |
44 | <%= post.categories.data[0].name %>
45 |
46 |
47 | <% } %>
48 | <% if (post.tags && post.tags.data.length !== 0) { %>
49 |
50 |
51 |
52 |
53 | <% let prev; %>
54 | <% post.tags.data.forEach((tag) => { %>
55 |
56 | <%
57 | const colors = theme.colors.filter((color) => color !== prev);
58 | let id = Math.floor(Math.random() * colors.length);
59 | prev = colors[id];
60 | %>
61 |
62 | <%= tag.name %>
63 |
64 |
65 | <% }); %>
66 |
67 | <% } %>
68 |
69 |
70 |
71 | <% }); %>
72 |
73 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "hexo-theme-particlex",
3 | "version": "2.8.1",
4 | "description": "A concise Hexo theme, based on Particle.",
5 | "scripts": {
6 | "test": "echo \"Error: no test specified\" && exit 1"
7 | },
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/theme-particlex/hexo-theme-particlex.git"
11 | },
12 | "keywords": [
13 | "hexo",
14 | "hexo-theme",
15 | "gitalk",
16 | "twikoo",
17 | "waline",
18 | "giscus"
19 | ],
20 | "author": "Argvchs",
21 | "license": "MIT",
22 | "bugs": {
23 | "url": "https://github.com/theme-particlex/hexo-theme-particlex/issues"
24 | },
25 | "homepage": "https://github.com/theme-particlex/hexo-theme-particlex#readme",
26 | "dependencies": {
27 | "hexo-helper-crypto": "^1.2.1",
28 | "hexo-renderer-ejs": "^2.0.0"
29 | },
30 | "packageManager": "pnpm@9.7.0+sha512.dc09430156b427f5ecfc79888899e1c39d2d690f004be70e05230b72cb173d96839587545d09429b55ac3c429c801b4dc3c0e002f653830a420fa2dd4e3cf9cf"
31 | }
32 |
--------------------------------------------------------------------------------
/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '9.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
7 | importers:
8 |
9 | .:
10 | dependencies:
11 | hexo-helper-crypto:
12 | specifier: ^1.2.1
13 | version: 1.2.1
14 | hexo-renderer-ejs:
15 | specifier: ^2.0.0
16 | version: 2.0.0
17 |
18 | packages:
19 |
20 | ansi-styles@4.3.0:
21 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
22 | engines: {node: '>=8'}
23 |
24 | async@3.2.5:
25 | resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==}
26 |
27 | balanced-match@1.0.2:
28 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
29 |
30 | brace-expansion@1.1.11:
31 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
32 |
33 | brace-expansion@2.0.1:
34 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
35 |
36 | chalk@4.1.2:
37 | resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
38 | engines: {node: '>=10'}
39 |
40 | color-convert@2.0.1:
41 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
42 | engines: {node: '>=7.0.0'}
43 |
44 | color-name@1.1.4:
45 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
46 |
47 | concat-map@0.0.1:
48 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
49 |
50 | crypto-js@4.2.0:
51 | resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==}
52 |
53 | ejs@3.1.10:
54 | resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==}
55 | engines: {node: '>=0.10.0'}
56 | hasBin: true
57 |
58 | filelist@1.0.4:
59 | resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==}
60 |
61 | has-flag@4.0.0:
62 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
63 | engines: {node: '>=8'}
64 |
65 | hexo-helper-crypto@1.2.1:
66 | resolution: {integrity: sha512-xkqXiP/BH2zCcAVs9PWwh5NdXRW/oeXZr/5R/NTyGa262a7RJdGYo7Ead2b8T98k5fOydCPzoOirK/tufKmdtQ==}
67 |
68 | hexo-renderer-ejs@2.0.0:
69 | resolution: {integrity: sha512-qCjE1IdwgDgv65qyb0KMVCwCdSVAkH0vwAe9XihjvaKWkmb9dtt8DgErOdqCXn0HReSyWiEVP2BrLRj3gyHwOQ==}
70 | engines: {node: '>=12'}
71 |
72 | jake@10.9.2:
73 | resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==}
74 | engines: {node: '>=10'}
75 | hasBin: true
76 |
77 | minimatch@3.1.2:
78 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
79 |
80 | minimatch@5.1.6:
81 | resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
82 | engines: {node: '>=10'}
83 |
84 | supports-color@7.2.0:
85 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
86 | engines: {node: '>=8'}
87 |
88 | snapshots:
89 |
90 | ansi-styles@4.3.0:
91 | dependencies:
92 | color-convert: 2.0.1
93 |
94 | async@3.2.5: {}
95 |
96 | balanced-match@1.0.2: {}
97 |
98 | brace-expansion@1.1.11:
99 | dependencies:
100 | balanced-match: 1.0.2
101 | concat-map: 0.0.1
102 |
103 | brace-expansion@2.0.1:
104 | dependencies:
105 | balanced-match: 1.0.2
106 |
107 | chalk@4.1.2:
108 | dependencies:
109 | ansi-styles: 4.3.0
110 | supports-color: 7.2.0
111 |
112 | color-convert@2.0.1:
113 | dependencies:
114 | color-name: 1.1.4
115 |
116 | color-name@1.1.4: {}
117 |
118 | concat-map@0.0.1: {}
119 |
120 | crypto-js@4.2.0: {}
121 |
122 | ejs@3.1.10:
123 | dependencies:
124 | jake: 10.9.2
125 |
126 | filelist@1.0.4:
127 | dependencies:
128 | minimatch: 5.1.6
129 |
130 | has-flag@4.0.0: {}
131 |
132 | hexo-helper-crypto@1.2.1:
133 | dependencies:
134 | crypto-js: 4.2.0
135 |
136 | hexo-renderer-ejs@2.0.0:
137 | dependencies:
138 | ejs: 3.1.10
139 |
140 | jake@10.9.2:
141 | dependencies:
142 | async: 3.2.5
143 | chalk: 4.1.2
144 | filelist: 1.0.4
145 | minimatch: 3.1.2
146 |
147 | minimatch@3.1.2:
148 | dependencies:
149 | brace-expansion: 1.1.11
150 |
151 | minimatch@5.1.6:
152 | dependencies:
153 | brace-expansion: 2.0.1
154 |
155 | supports-color@7.2.0:
156 | dependencies:
157 | has-flag: 4.0.0
158 |
--------------------------------------------------------------------------------
/source/css/main.css:
--------------------------------------------------------------------------------
1 | #archives {
2 | margin: auto;
3 | margin-top: 100px;
4 | padding: 20px;
5 | }
6 | #archives .categories-tags {
7 | margin: auto;
8 | margin-bottom: 50px;
9 | max-width: 900px;
10 | text-align: center;
11 | width: 100%;
12 | }
13 | #archives .categories-tags span {
14 | display: inline-block;
15 | margin: 10px;
16 | }
17 | #archives .categories-tags span .icon {
18 | color: #fff;
19 | margin-left: 0;
20 | margin-right: 10px;
21 | }
22 | #archives .categories-tags span a {
23 | border: #ffffff80 1px solid;
24 | border-radius: 10px;
25 | color: #fff;
26 | padding: 10px 15px;
27 | transition: background 0.25s, border 0.25s, color 0.25s;
28 | }
29 | #archives .categories-tags span a:hover {
30 | background: #fff !important;
31 | border: #a5c2f5 1px solid;
32 | color: #5c6b72;
33 | }
34 | #archives .category,
35 | #archives .tags .tag,
36 | .article .info .category,
37 | .article .info .tags,
38 | .article .info .tags .tag {
39 | display: inline-block;
40 | margin-right: 10px;
41 | }
42 | #archives h3 {
43 | margin: 10px 0;
44 | }
45 | #crypto {
46 | margin: 50px 0;
47 | }
48 | #crypto.failure {
49 | border-color: #ea4a5a;
50 | color: #ea4a5a;
51 | }
52 | #crypto.failure:focus {
53 | box-shadow: 0 0 0 3px #ea4a5a4d;
54 | }
55 | #crypto.success {
56 | border-color: #34d058;
57 | color: #34d058;
58 | }
59 | #footer {
60 | font-size: 14px;
61 | margin-top: 150px;
62 | padding-bottom: 20px;
63 | text-align: center;
64 | width: 100%;
65 | }
66 | #footer #footer-icon {
67 | color: #66afef;
68 | display: inline-block;
69 | font-size: 18px;
70 | margin: 0 10px;
71 | }
72 | #footer #footer-wrap {
73 | border-top: 1px solid #aaa;
74 | color: #5c6b72;
75 | margin: auto;
76 | width: 900px;
77 | }
78 | #footer #footer-wrap div {
79 | margin: 15px;
80 | }
81 | #home-card {
82 | width: 300px;
83 | }
84 | #home-card #card-style {
85 | background: #fff;
86 | border: none;
87 | border-radius: 10px;
88 | box-shadow: 0 0 20px #d9d9d980;
89 | display: flex;
90 | flex-direction: column;
91 | max-height: 80vh;
92 | justify-content: center;
93 | overflow: auto;
94 | position: sticky;
95 | text-align: center;
96 | top: 10vh;
97 | width: 300px;
98 | }
99 | #home-card #card-div {
100 | overflow: auto;
101 | padding: 25px 0;
102 | }
103 | #home-card #card-div .avatar {
104 | border: #f1f1f1 solid 3px;
105 | border-radius: 50%;
106 | height: 140px;
107 | margin: auto;
108 | text-align: center;
109 | width: 140px;
110 | }
111 | #home-card #card-div .avatar img {
112 | border-radius: 50%;
113 | height: 100%;
114 | width: 100%;
115 | }
116 | #home-card #card-div .avatar:hover img {
117 | transform: rotate(360deg);
118 | }
119 | #home-card #card-div .description {
120 | margin: 20px auto;
121 | width: 85%;
122 | }
123 | #home-card #card-div .friend-links .friend-link {
124 | margin-bottom: 5px;
125 | }
126 | #home-card #card-div .friend-links a {
127 | border-radius: 5px;
128 | color: #5c6b72;
129 | display: block;
130 | padding: 8px 0;
131 | }
132 | #home-card #card-div .icon-links .icon-link {
133 | margin: 5px;
134 | }
135 | #home-card #card-div .icon-links a {
136 | border-radius: 5px;
137 | color: #5c6b72;
138 | font-size: 18px;
139 | padding: 5px;
140 | }
141 | #home-card #card-div .icon-links a:hover,
142 | #home-card #card-div .friend-links a:hover,
143 | #home-posts .page-current .page-num:hover {
144 | background: #66afef;
145 | color: #fff;
146 | }
147 | #home-card #card-div .icon-links,
148 | #home-card #card-div .friend-links {
149 | border-top: #cdcdcd solid 1px;
150 | margin: 10px auto;
151 | padding-top: 10px;
152 | width: 85%;
153 | }
154 | #home-card #card-div .name {
155 | font-size: 16px;
156 | font-weight: bold;
157 | margin: 20px auto;
158 | }
159 | #home-head {
160 | display: flex;
161 | height: 100vh;
162 | width: 100vw;
163 | }
164 | #home-head #home-background {
165 | background-position: center;
166 | background-repeat: no-repeat;
167 | background-size: cover;
168 | height: 100vh;
169 | left: 0;
170 | position: absolute;
171 | top: 0;
172 | width: 100vw;
173 | z-index: -1;
174 | }
175 | #home-head #home-info .info {
176 | align-items: center;
177 | border-radius: 50%;
178 | display: flex;
179 | justify-content: center;
180 | text-align: center;
181 | }
182 | #home-head #home-info .loop:nth-child(1) {
183 | animation: loop1 10s linear infinite;
184 | background: #fff;
185 | border-radius: 38% 62% 63% 37%/41% 44% 56% 59%;
186 | opacity: 0.3;
187 | transform: rotate(30deg);
188 | }
189 | #home-head #home-info .loop:nth-child(2) {
190 | animation: loop2 15s linear infinite;
191 | background: #fff;
192 | border-radius: 38% 62% 63% 37%/41% 44% 56% 59%;
193 | opacity: 0.45;
194 | transform: rotate(60deg);
195 | }
196 | #home-head #home-info .loop:nth-child(3) {
197 | animation: loop3 10s linear infinite;
198 | background: #fff;
199 | border-radius: 38% 62% 63% 37%/41% 44% 56% 59%;
200 | opacity: 0.3;
201 | transform: rotate(90deg);
202 | }
203 | #home-head #home-info .loop:nth-child(4) {
204 | animation: loop4 15s linear infinite;
205 | background: #fff;
206 | border-radius: 38% 62% 63% 37%/41% 44% 56% 59%;
207 | opacity: 0.45;
208 | transform: rotate(120deg);
209 | }
210 | #home-head #home-info,
211 | #home-posts {
212 | margin: auto;
213 | }
214 | #home-posts .page-current {
215 | align-items: center;
216 | display: flex;
217 | font-weight: bold;
218 | justify-content: center;
219 | margin-top: 50px;
220 | text-align: center;
221 | width: 100%;
222 | }
223 | #home-posts .page-current .current {
224 | border-radius: 5px;
225 | color: #da0a51;
226 | display: inline-block;
227 | height: 35px;
228 | line-height: 35px;
229 | margin: 0 7px;
230 | padding: 5px;
231 | width: 35px;
232 | }
233 | #home-posts .page-current .page-num,
234 | #home-posts .page-current .page-omit {
235 | border-radius: 5px;
236 | display: inline-block;
237 | height: 35px;
238 | line-height: 35px;
239 | margin: 0 7px;
240 | padding: 5px;
241 | width: 35px;
242 | }
243 | #home-posts .page-current a {
244 | color: #999;
245 | }
246 | #home-posts .post {
247 | background: #fff;
248 | border-radius: 20px;
249 | box-shadow: 0 0 20px #d9d9d980;
250 | transition: box-shadow 0.25s, transform 0.25s;
251 | }
252 | #home-posts .post .category-and-date {
253 | color: #5c6b72;
254 | margin-top: 15px;
255 | text-align: center;
256 | width: 100%;
257 | }
258 | #home-posts .post .category-and-date .category {
259 | display: inline-block;
260 | margin-right: 25px;
261 | }
262 | #home-posts .post .category-and-date .category a,
263 | #archives a,
264 | #archives .tag-icon,
265 | #archives .item-time,
266 | #archives .categories-tags span a:hover .icon,
267 | .article .info a {
268 | color: #5c6b72;
269 | }
270 | #home-posts .post .category-and-date .date,
271 | #archives .tags,
272 | #menu #desktop-menu a span {
273 | display: inline-block;
274 | }
275 | #home-posts .post .category-and-date .special {
276 | display: inline-block;
277 | margin-left: 25px;
278 | }
279 | #home-posts .post .go-post {
280 | background: linear-gradient(120deg, #9abbf7 0%, #ffbbf4 100%);
281 | border: 0;
282 | border-radius: 20px 0;
283 | bottom: -5px;
284 | box-shadow: 2px 2px 10px 0 #ffbbf47a;
285 | color: #fff;
286 | font-size: 14px;
287 | font-weight: bold;
288 | padding: 10px 24px;
289 | position: absolute;
290 | right: -5px;
291 | transition: box-shadow 0.25s ease-out, right 0.25s ease-out;
292 | }
293 | #home-posts .post .go-post:hover {
294 | box-shadow: -2px -2px 10px 0 #9abbf77a;
295 | right: -7px;
296 | }
297 | #home-posts .post .post-tags .tag {
298 | display: inline-block;
299 | font-weight: bold;
300 | margin-right: 10px;
301 | }
302 | #home-posts .post .post-tags a {
303 | font-size: 14px;
304 | }
305 | #home-posts .post .post-tags,
306 | #archives .info,
307 | .article .info {
308 | line-height: 1.7;
309 | }
310 | #home-posts .post-title {
311 | color: #66afef;
312 | text-align: center;
313 | }
314 | #home-posts .post:hover {
315 | box-shadow: 0 0 5px #d9d9d9;
316 | transform: translate(-5px, -5px);
317 | }
318 | #home-posts-wrap {
319 | background: transparent;
320 | border-radius: 10px;
321 | display: flex;
322 | margin: auto;
323 | padding: 20px;
324 | }
325 | #home-posts-wrap,
326 | #archives,
327 | .article,
328 | #footer #footer-wrap {
329 | box-sizing: border-box;
330 | }
331 | #loading {
332 | align-items: center;
333 | background: #fff;
334 | display: flex;
335 | flex-direction: column;
336 | height: 100vh;
337 | justify-content: center;
338 | left: 0;
339 | position: fixed;
340 | top: 0;
341 | width: 100vw;
342 | word-break: keep-all;
343 | z-index: 2147483647;
344 | }
345 | #loading h2,
346 | #loading p,
347 | #loading img {
348 | margin: 10px;
349 | }
350 | #loading img {
351 | border-radius: 0;
352 | height: 50px;
353 | }
354 | #loading-circle {
355 | align-items: center;
356 | border: 10px solid #a3ddfb;
357 | border-radius: 50%;
358 | display: flex;
359 | flex-direction: column;
360 | height: 50vmin;
361 | justify-content: center;
362 | padding: 50px;
363 | text-align: center;
364 | width: 50vmin;
365 | }
366 | #main {
367 | margin-right: calc(100% - 100vw);
368 | }
369 | #menu {
370 | background: #92cafa;
371 | box-shadow: 0 -1px 10px 0 #9e9e9e4d;
372 | font-weight: bold;
373 | line-height: 50px;
374 | position: fixed;
375 | top: 0;
376 | transition: background 0.25s ease-out, top 0.25s ease-out;
377 | width: 100vw;
378 | z-index: 1004;
379 | }
380 | #menu #desktop-menu {
381 | height: 50px;
382 | }
383 | #menu #desktop-menu .title {
384 | color: #555;
385 | display: inline-block;
386 | margin-left: 60px;
387 | margin-right: 5px;
388 | }
389 | #menu #desktop-menu a {
390 | color: #555;
391 | display: inline-block;
392 | margin-left: 30px;
393 | }
394 | #menu #mobile-menu {
395 | min-height: 50px;
396 | text-align: center;
397 | }
398 | #menu #mobile-menu .items {
399 | padding: 10px 0 20px;
400 | z-index: 1002;
401 | }
402 | #menu #mobile-menu .items .item {
403 | display: flex;
404 | justify-content: center;
405 | margin: auto;
406 | min-width: 200px;
407 | width: 80%;
408 | }
409 | #menu #mobile-menu .items a {
410 | color: #555;
411 | }
412 | #menu #mobile-menu .title {
413 | color: #555;
414 | cursor: pointer;
415 | z-index: 1003;
416 | }
417 | #menu-curtain {
418 | background: #0003;
419 | height: 100%;
420 | left: 0;
421 | position: fixed;
422 | top: 0;
423 | width: 100%;
424 | z-index: 1001;
425 | }
426 | #menu.hidden {
427 | top: -50px;
428 | }
429 | #menu.menu-color {
430 | background: #0003;
431 | }
432 | #menu.menu-color #desktop-menu a,
433 | #menu.menu-color #mobile-menu a,
434 | #menu.menu-color #mobile-menu .title {
435 | color: #fff;
436 | }
437 | #preview {
438 | align-items: center;
439 | background-color: #fffc;
440 | display: flex;
441 | height: 100vh;
442 | justify-content: center;
443 | left: 0;
444 | position: fixed;
445 | top: 0;
446 | width: 100vw;
447 | z-index: 1005;
448 | }
449 | #preview-content {
450 | box-shadow: 0 0 50px 10px #d9d9d980;
451 | margin: auto;
452 | max-height: 95%;
453 | max-width: 95%;
454 | }
455 | #search-bar {
456 | margin-bottom: 50px;
457 | z-index: 1000;
458 | }
459 | #timeline-wrap {
460 | display: flex;
461 | flex-direction: column-reverse;
462 | }
463 | * {
464 | margin: 0;
465 | padding: 0;
466 | position: relative;
467 | scrollbar-color: #8ab5ff #e6efff;
468 | scrollbar-width: thin;
469 | word-wrap: break-word;
470 | }
471 | .article {
472 | font-size: 15px;
473 | margin: auto;
474 | margin-top: 100px;
475 | padding: 20px;
476 | }
477 | .article .content {
478 | margin: 50px 0;
479 | }
480 | .article .info .date {
481 | color: #5c6b72;
482 | display: inline-block;
483 | margin-right: 10px;
484 | }
485 | .code-content {
486 | font-size: 13px;
487 | line-height: 2;
488 | overflow: auto;
489 | padding: 50px 30px 20px;
490 | white-space: pre;
491 | }
492 | .comment iframe,
493 | body::-webkit-scrollbar-track {
494 | border-radius: 0;
495 | }
496 | .content {
497 | transition: opacity 0.25s;
498 | }
499 | .content img,
500 | .content video,
501 | .content audio,
502 | .content iframe {
503 | display: block;
504 | margin: 15px auto;
505 | max-width: 75%;
506 | }
507 | .copycode {
508 | color: #5c6b72;
509 | position: absolute;
510 | right: 0;
511 | top: 0;
512 | }
513 | .copycode i {
514 | padding: 15px;
515 | position: absolute;
516 | right: 0;
517 | top: 0;
518 | transition: transform 0.25s;
519 | }
520 | .copycode.copied i {
521 | transform: scale(1.25);
522 | }
523 | .copycode.copied i:first-child,
524 | .copycode:not(.copied) i:last-child {
525 | opacity: 0;
526 | }
527 | .fade-enter-active,
528 | .fade-leave-active {
529 | transition: opacity 0.3s;
530 | }
531 | .fade-enter-from,
532 | .fade-leave-to {
533 | opacity: 0;
534 | }
535 | .hljs-ln-code {
536 | padding-left: 20px !important;
537 | }
538 | .hljs-ln-numbers {
539 | border-right: 1px solid #ccc;
540 | color: #ccc;
541 | padding-right: 10px !important;
542 | text-align: right;
543 | vertical-align: top;
544 | }
545 | .icon {
546 | color: #5c6b72;
547 | margin-right: 5px;
548 | }
549 | .input {
550 | background: #f6f8fa;
551 | border: 1px solid #d0d7de;
552 | border-radius: 50px;
553 | box-sizing: border-box;
554 | color: #000;
555 | display: block;
556 | font-size: 15px;
557 | height: 50px;
558 | text-indent: 20px;
559 | transition: background 0.25s, border 0.25s, box-shadow 0.25s;
560 | width: 100%;
561 | }
562 | .input:focus {
563 | background: #fff;
564 | border-color: #0969da;
565 | box-shadow: 0 0 0 3px #0969da4d;
566 | outline: none;
567 | }
568 | .input:hover {
569 | background: #fff;
570 | }
571 | .into-enter-active {
572 | transition: opacity 0.5s, transform 0.5s;
573 | }
574 | .into-enter-from {
575 | opacity: 0;
576 | transform: scale(1.1);
577 | }
578 | .katex {
579 | white-space: normal !important;
580 | }
581 | .language {
582 | background: linear-gradient(to right, #ed6ea0 0%, #ec8c69 100%);
583 | border-radius: 0 0 10px 10px;
584 | box-shadow: 1px 1px 0.75rem #ed6ea14d;
585 | color: #fff;
586 | font-size: 12px;
587 | font-weight: bold;
588 | left: 30px;
589 | padding: 10px 15px;
590 | position: absolute;
591 | top: 0;
592 | }
593 | .page-num,
594 | .icon-link a,
595 | .friend-link a {
596 | transition: background 0.25s, color 0.25s;
597 | }
598 | .page-num:hover,
599 | .icon-link a:hover,
600 | .friend-link a:hover,
601 | .categories-tags a:hover,
602 | .go-post:hover {
603 | opacity: 1;
604 | }
605 | .slide-enter-active,
606 | .slide-leave-active {
607 | transition: margin-top 0.3s, opacity 0.3s;
608 | }
609 | .slide-enter-from,
610 | .slide-leave-to {
611 | margin-top: -300px;
612 | opacity: 0;
613 | }
614 | .timeline {
615 | margin-bottom: 30px;
616 | transition: margin-top 0.5s, opacity 0.3s, visibility 0.3s;
617 | }
618 | .timeline-content {
619 | background: #fff;
620 | border: 1px solid #0002;
621 | border-radius: 3px;
622 | margin-left: 17.5px;
623 | padding: 24px;
624 | transition: box-shadow 0.5s;
625 | }
626 | .timeline-content:hover {
627 | box-shadow: 0 2px 8px #00000017;
628 | }
629 | .timeline-tail {
630 | background: #fff;
631 | border: 2px solid #a5c2f5;
632 | border-radius: 50%;
633 | height: 7px;
634 | position: absolute;
635 | width: 7px;
636 | }
637 | ::-webkit-scrollbar {
638 | height: 12px;
639 | width: 12px;
640 | }
641 | ::-webkit-scrollbar-thumb {
642 | background: #8ab5ff
643 | linear-gradient(
644 | 45deg,
645 | #fff6 25%,
646 | transparent 25%,
647 | transparent 50%,
648 | #fff6 50%,
649 | #fff6 75%,
650 | transparent 75%,
651 | transparent
652 | );
653 | border: 3px solid #e6efff;
654 | border-radius: 100px;
655 | }
656 | ::-webkit-scrollbar-track {
657 | background: #e6efff;
658 | border-radius: 100px;
659 | }
660 | ::selection {
661 | background-color: #3392ff2a;
662 | color: unset;
663 | }
664 | a {
665 | color: #66afef;
666 | text-decoration: none;
667 | }
668 | a:hover,
669 | .content .copycode:hover {
670 | opacity: 0.8;
671 | }
672 | audio,
673 | button,
674 | iframe,
675 | img,
676 | video,
677 | #home-head,
678 | #menu,
679 | .categories-tags a,
680 | .copycode,
681 | .friend-link a,
682 | .go-post,
683 | .hljs-ln-numbers,
684 | .icon-link a,
685 | .katex,
686 | .language,
687 | .page-current {
688 | user-select: none;
689 | }
690 | b,
691 | strong {
692 | font-weight: bold;
693 | line-height: 2.5;
694 | }
695 | blockquote {
696 | background: #d9e8ff6b;
697 | border-left: 3px solid #1e3e3f;
698 | border-radius: 3px;
699 | margin: 15px 0;
700 | overflow: auto;
701 | padding: 0 15px;
702 | }
703 | body {
704 | background: #f6f8fa;
705 | color: #1e3e3f;
706 | font: 500 14px Lexend, "Noto Sans SC", sans-serif;
707 | overflow-x: hidden;
708 | width: 100%;
709 | }
710 | code {
711 | background: #bddcf76b;
712 | border-radius: 4px;
713 | line-height: 2.5;
714 | padding: 4px 8px;
715 | }
716 | h1,
717 | h2,
718 | h3,
719 | h4,
720 | h5,
721 | h6 {
722 | color: #1e3e3f;
723 | font-weight: bold;
724 | margin: 15px 0;
725 | word-break: keep-all;
726 | }
727 | h1 {
728 | font-size: 30px;
729 | }
730 | h2 {
731 | font-size: 27px;
732 | }
733 | h3 {
734 | font-size: 24px;
735 | }
736 | h4 {
737 | font-size: 21px;
738 | }
739 | h5 {
740 | font-size: 18px;
741 | }
742 | h6 {
743 | font-size: 15px;
744 | }
745 | hr {
746 | border-style: dashed none none;
747 | border-width: 1.5px;
748 | }
749 | img,
750 | video,
751 | audio,
752 | iframe {
753 | border-radius: 10px;
754 | }
755 | mark {
756 | background: #fff13360;
757 | border-radius: 4px;
758 | color: unset;
759 | line-height: 2.5;
760 | padding: 4px 8px;
761 | }
762 | p,
763 | ul,
764 | ol {
765 | line-height: 1.7;
766 | margin: 15px 0;
767 | }
768 | pre {
769 | border: 1px solid #ebeef5;
770 | border-radius: 15px;
771 | box-shadow: 0 2px 12px 0 #0000001a;
772 | margin: 25px 0;
773 | overflow: hidden;
774 | white-space: normal;
775 | }
776 | pre,
777 | code,
778 | .hljs,
779 | .input,
780 | .language {
781 | font-family: "Fira Code", "Noto Sans SC", monospace;
782 | }
783 | table:not(.hljs-ln) {
784 | margin: 15px 0;
785 | }
786 | table:not(.hljs-ln) td:nth-child(even) {
787 | background: #c7e0fb4d;
788 | }
789 | table:not(.hljs-ln) td:nth-child(odd) {
790 | background: #d9e8ff4d;
791 | }
792 | table:not(.hljs-ln) th {
793 | background: #a3ddfb;
794 | }
795 | table:not(.hljs-ln) tr th,
796 | table:not(.hljs-ln) tr td {
797 | border-radius: 3px;
798 | padding: 10px 20px;
799 | }
800 | ul li,
801 | ol li {
802 | margin: 8px 0;
803 | }
804 | @keyframes loop1 {
805 | from {
806 | transform: rotate(30deg);
807 | }
808 | to {
809 | transform: rotate(390deg);
810 | }
811 | }
812 | @keyframes loop2 {
813 | from {
814 | transform: rotate(60deg);
815 | }
816 | to {
817 | transform: rotate(420deg);
818 | }
819 | }
820 | @keyframes loop3 {
821 | from {
822 | transform: rotate(90deg);
823 | }
824 | to {
825 | transform: rotate(450deg);
826 | }
827 | }
828 | @keyframes loop4 {
829 | from {
830 | transform: rotate(120deg);
831 | }
832 | to {
833 | transform: rotate(480deg);
834 | }
835 | }
836 | @media (min-width: 900px) {
837 | #home-head #home-info .info .wrap {
838 | padding: 25px;
839 | }
840 | #home-head #home-info .info .wrap h1 {
841 | font-size: 52px;
842 | font-weight: bold;
843 | margin-bottom: 10px;
844 | }
845 | #home-head #home-info .info .wrap h3 {
846 | font-size: 24px;
847 | margin: 10px 0;
848 | }
849 | #home-head #home-info .info .wrap h5 {
850 | font-size: 16px;
851 | margin: 20px 0;
852 | }
853 | #home-head #home-info .loop {
854 | display: inline-block;
855 | height: 500px;
856 | position: absolute;
857 | width: 500px;
858 | }
859 | #home-head #home-info,
860 | #home-head #home-info .info {
861 | height: 500px;
862 | width: 500px;
863 | }
864 | #home-posts {
865 | margin-right: 50px;
866 | width: 850px;
867 | }
868 | #home-posts .post {
869 | margin-bottom: 25px;
870 | padding: 50px;
871 | }
872 | #home-posts .post .description {
873 | padding: 20px 0;
874 | }
875 | #home-posts-wrap {
876 | max-width: 1200px;
877 | }
878 | #menu #desktop-menu {
879 | display: block;
880 | }
881 | #menu #mobile-menu {
882 | display: none;
883 | }
884 | .article,
885 | #archives,
886 | #footer #footer-wrap {
887 | width: 900px;
888 | }
889 | .home-posts-wrap-no-card #home-posts {
890 | margin: auto;
891 | }
892 | ul,
893 | ol {
894 | padding-left: 40px;
895 | }
896 | }
897 | @media (min-width: 900px) and (max-width: 1200px) {
898 | #home-card {
899 | display: none;
900 | }
901 | #home-posts {
902 | width: 100%;
903 | }
904 | #home-posts-wrap,
905 | #archives {
906 | width: 800px;
907 | }
908 | }
909 | @media (max-width: 900px) {
910 | #home-head #home-info {
911 | height: 350px;
912 | width: 350px;
913 | }
914 | #home-head #home-info .info {
915 | align-items: center;
916 | background: #ffffffa6;
917 | display: flex;
918 | height: 350px;
919 | justify-content: center;
920 | margin: auto;
921 | width: 350px;
922 | }
923 | #home-head #home-info .info .wrap {
924 | padding: 50px;
925 | }
926 | #home-head #home-info .info .wrap h1 {
927 | font-size: 46px;
928 | margin-bottom: 10px;
929 | }
930 | #home-head #home-info .info .wrap h3 {
931 | font-size: 20px;
932 | margin: 10px 0;
933 | }
934 | #home-head #home-info .info .wrap h5 {
935 | font-size: 14px;
936 | margin: 20px 0;
937 | }
938 | #home-head #home-info .loop {
939 | display: none;
940 | height: 350px;
941 | position: absolute;
942 | width: 350px;
943 | }
944 | #home-posts {
945 | margin: auto;
946 | width: 100%;
947 | }
948 | #home-posts .post {
949 | margin-bottom: 30px;
950 | padding: 20px 30px;
951 | }
952 | #home-posts .post .description {
953 | padding: 20px 0;
954 | }
955 | #home-posts .post .post-tags {
956 | padding-right: 69px;
957 | }
958 | #home-posts-wrap,
959 | .article,
960 | #archives,
961 | #footer #footer-wrap {
962 | width: 100%;
963 | }
964 | #menu #desktop-menu,
965 | #home-card {
966 | display: none;
967 | }
968 | #menu #mobile-menu {
969 | display: block;
970 | }
971 | ul,
972 | ol {
973 | padding-left: 20px;
974 | }
975 | }
976 |
--------------------------------------------------------------------------------
/source/images/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/argvchs/hexo-theme-particlex/d1bf2fdc23deedd014abc8bd2c1482282c865881/source/images/loading.gif
--------------------------------------------------------------------------------
/source/js/lib/crypto.js:
--------------------------------------------------------------------------------
1 | mixins.crypto = {
2 | data() {
3 | return { crypto: "", cryptoStatus: "" };
4 | },
5 | watch: {
6 | crypto(value) {
7 | let input = this.$refs.crypto,
8 | content = this.$refs.content;
9 | let { encrypted, shasum } = input.dataset;
10 | try {
11 | let decrypted = CryptoJS.AES.decrypt(encrypted, value).toString(CryptoJS.enc.Utf8);
12 | if (CryptoJS.SHA256(decrypted).toString() === shasum) {
13 | this.cryptoStatus = "success";
14 | content.innerHTML = decrypted;
15 | this.render();
16 | } else this.cryptoStatus = "failure";
17 | } catch {
18 | this.cryptoStatus = "failure";
19 | }
20 | },
21 | },
22 | };
23 |
--------------------------------------------------------------------------------
/source/js/lib/highlight.js:
--------------------------------------------------------------------------------
1 | mixins.highlight = {
2 | data() {
3 | return { copying: false };
4 | },
5 | created() {
6 | hljs.configure({ ignoreUnescapedHTML: true });
7 | this.renderers.push(this.highlight);
8 | },
9 | methods: {
10 | sleep(ms) {
11 | return new Promise((resolve) => setTimeout(resolve, ms));
12 | },
13 | highlight() {
14 | let codes = document.querySelectorAll("pre");
15 | for (let i of codes) {
16 | let code = i.textContent;
17 | let language = [...i.classList, ...i.firstChild.classList][0] || "plaintext";
18 | let highlighted;
19 | try {
20 | highlighted = hljs.highlight(code, { language }).value;
21 | } catch {
22 | highlighted = code;
23 | }
24 | i.innerHTML = `
25 | ${highlighted}
26 | ${language}
27 |
28 |
29 |
30 |
31 | `;
32 | let content = i.querySelector(".code-content");
33 | hljs.lineNumbersBlock(content, { singleLine: true });
34 | let copycode = i.querySelector(".copycode");
35 | copycode.addEventListener("click", async () => {
36 | if (this.copying) return;
37 | this.copying = true;
38 | copycode.classList.add("copied");
39 | await navigator.clipboard.writeText(code);
40 | await this.sleep(1000);
41 | copycode.classList.remove("copied");
42 | this.copying = false;
43 | });
44 | }
45 | },
46 | },
47 | };
48 |
--------------------------------------------------------------------------------
/source/js/lib/home.js:
--------------------------------------------------------------------------------
1 | mixins.home = {
2 | mounted() {
3 | let background = this.$refs.homeBackground;
4 | let images = background.dataset.images.split(",");
5 | let id = Math.floor(Math.random() * images.length);
6 | background.style.backgroundImage = `url('${images[id]}')`;
7 | this.menuColor = true;
8 | },
9 | methods: {
10 | homeClick() {
11 | window.scrollTo({ top: window.innerHeight, behavior: "smooth" });
12 | },
13 | },
14 | };
15 |
--------------------------------------------------------------------------------
/source/js/lib/math.js:
--------------------------------------------------------------------------------
1 | mixins.math = {
2 | created() {
3 | this.renderers.push(this.math);
4 | },
5 | methods: {
6 | math() {
7 | renderMathInElement(document.body, {
8 | delimiters: [
9 | { left: "$$", right: "$$", display: true },
10 | { left: "$", right: "$", display: false },
11 | { left: "\\(", right: "\\)", display: false },
12 | { left: "\\[", right: "\\]", display: true },
13 | ],
14 | });
15 | },
16 | },
17 | };
18 |
--------------------------------------------------------------------------------
/source/js/lib/preview.js:
--------------------------------------------------------------------------------
1 | mixins.preview = {
2 | data() {
3 | return { previewShow: false };
4 | },
5 | created() {
6 | this.renderers.push(this.preview);
7 | },
8 | methods: {
9 | preview() {
10 | let preview = this.$refs.preview,
11 | content = this.$refs.previewContent;
12 | let images = document.querySelectorAll("img");
13 | for (let i of images)
14 | i.addEventListener("click", () => {
15 | content.alt = i.alt;
16 | content.src = i.src;
17 | this.previewShow = true;
18 | });
19 | preview.addEventListener("click", () => {
20 | this.previewShow = false;
21 | });
22 | window.addEventListener("resize", () => {
23 | this.previewShow = false;
24 | });
25 | },
26 | },
27 | };
28 |
--------------------------------------------------------------------------------
/source/js/lib/search.js:
--------------------------------------------------------------------------------
1 | mixins.search = {
2 | data() {
3 | return { rawSearch: "" };
4 | },
5 | watch: {
6 | search(value) {
7 | let timeline = this.$refs.timeline.childNodes;
8 | for (let i of timeline)
9 | if (!value || i.dataset.title.includes(value)) {
10 | i.style.opacity = 1;
11 | i.style.visibility = "visible";
12 | i.style.marginTop = 0;
13 | } else {
14 | i.style.opacity = 0;
15 | i.style.visibility = "hidden";
16 | i.style.marginTop = -i.offsetHeight - 30 + "px";
17 | }
18 | },
19 | },
20 | computed: {
21 | search() {
22 | return this.rawSearch.toLowerCase().replace(/\s+/g, "");
23 | },
24 | },
25 | };
26 |
--------------------------------------------------------------------------------
/source/js/main.js:
--------------------------------------------------------------------------------
1 | const app = Vue.createApp({
2 | mixins: Object.values(mixins),
3 | data() {
4 | return {
5 | loading: true,
6 | hiddenMenu: false,
7 | showMenuItems: false,
8 | menuColor: false,
9 | scrollTop: 0,
10 | renderers: [],
11 | };
12 | },
13 | created() {
14 | window.addEventListener("load", () => {
15 | this.loading = false;
16 | });
17 | },
18 | mounted() {
19 | window.addEventListener("scroll", this.handleScroll, true);
20 | this.render();
21 | },
22 | methods: {
23 | render() {
24 | for (let i of this.renderers) i();
25 | },
26 | handleScroll() {
27 | let wrap = this.$refs.homePostsWrap;
28 | let newScrollTop = document.documentElement.scrollTop;
29 | if (this.scrollTop < newScrollTop) {
30 | this.hiddenMenu = true;
31 | this.showMenuItems = false;
32 | } else this.hiddenMenu = false;
33 | if (wrap) {
34 | if (newScrollTop <= window.innerHeight - 100) this.menuColor = true;
35 | else this.menuColor = false;
36 | if (newScrollTop <= 400) wrap.style.top = "-" + newScrollTop / 5 + "px";
37 | else wrap.style.top = "-80px";
38 | }
39 | this.scrollTop = newScrollTop;
40 | },
41 | },
42 | });
43 | app.mount("#layout");
44 |
--------------------------------------------------------------------------------