mirror of
https://github.com/Colin-XKL/Colinx-Blog.git
synced 2026-01-12 02:31:27 +08:00
Compare commits
1 Commits
93f0c2110b
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
018573ce6f |
2
.github/workflows/CDN-URL.yaml
vendored
2
.github/workflows/CDN-URL.yaml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Find and Replace Release
|
||||
uses: jacobtomlinson/gha-find-replace@2.0.0
|
||||
uses: jacobtomlinson/gha-find-replace@3.0.5
|
||||
with:
|
||||
find: "blog-1301127393.cos.ap-shanghai.myqcloud.com"
|
||||
replace: "blog-1301127393.file.myqcloud.com"
|
||||
|
||||
6
.github/workflows/gh-pages.yml
vendored
6
.github/workflows/gh-pages.yml
vendored
@@ -42,7 +42,7 @@ jobs:
|
||||
submodules: recursive
|
||||
- name: Setup Pages
|
||||
id: pages
|
||||
uses: actions/configure-pages@v5
|
||||
uses: actions/configure-pages@v2
|
||||
- name: Build with Hugo
|
||||
env:
|
||||
# For maximum backward compatibility with Hugo modules
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
--minify \
|
||||
--baseURL "/"
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
uses: actions/upload-pages-artifact@v1
|
||||
with:
|
||||
path: ./public
|
||||
|
||||
@@ -67,4 +67,4 @@ jobs:
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
uses: actions/deploy-pages@v1
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
---
|
||||
title: LLM Agent is All You Need - 当我用大模型助手来指导我完成MVP产品 - 「Colin's Weekend Project」
|
||||
date: 2025-09-14
|
||||
description: 我个人喜欢挑一个周末在一个很短很专注的时间内, 捣鼓点小玩意. 这个栏目用来记录我的这些 idea、作品、创作过程以及吐槽. 今天来挑战一下, 在大模型的指导下, 完成一个最小可行产品(MVP)
|
||||
categories:
|
||||
- Weekend Project
|
||||
tags:
|
||||
- 技术
|
||||
- JAMStack
|
||||
- LLM
|
||||
- AI
|
||||
---
|
||||
|
||||
> **「Colin's Weekend Project」**
|
||||
> 我个人喜欢挑一个周末在一个很短很专注的时间内, 捣鼓点小玩意. 这个栏目用来记录我的这些 idea、作品、创作过程以及吐槽
|
||||
|
||||
今天来挑战一下, 在大模型的指导下, 完成一个最小可行产品(MVP)
|
||||
|
||||
|
||||
|
||||
## idea
|
||||
|
||||
如果单纯是开发一个完整的 web 程序 or 移动端程序, 其实没啥意思. 我之前已经搞过很多, 更别提日常在公司里面就是在开发各种功能. 今天我打算以一个非专业人士的视角, 探究一下:
|
||||
|
||||
- 当下各种 AI 助手已经百花齐放, 飞入寻常百姓家. 但是当下的 AI 在真实世界的任务中, 究竟能做到什么地步
|
||||
- 如果作为一名非专业人士, 究竟能不能借助这些 AI 工具做出一个可用的产品
|
||||
- 如果真正要做一个面向 C 端的产品, 把流程 Run 起来持续下去, 需要考虑哪些因素
|
||||
|
||||
## 如果一切都从 LLM 开始...
|
||||
|
||||
我需要代入一个非专业开发人员的视角, 来进行这次的项目. 首先项目启动的第一个问题: 在没有任何产品经理的知识, 不懂得产品开发流程的小白的情况下, 我需要如何开始?
|
||||
|
||||
在没有 LLM 以前, 或许我需要先各种查阅资料学习, 或者各种摇人让懂行的朋友进行指导. 但是现在, 一切都不一样了: 随便一个 LLM 都可以帮我快速入门
|
||||
|
||||
一开始, 我是打算接住 LLM 让我快速了解产品相关的知识. 但是突然觉得, 既然都用 AI 了,为什么还在遵循原有的路径, 一步步自己学习、理解然后教 AI 做事呢? 换个思路, 我只要提供需求, AI 来拆解任务.
|
||||
|
||||
于是
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
利用 AI 生成一套提示词, 来指导我如果分析我的需求、拆解任务
|
||||
|
||||
不得不说, 对于这些跨领域的知识, 能有一个不厌其烦的 AI 助手来循序渐进地跟你交流、帮你分析, 效果非常好. 人类可能还真不好干这个活.
|
||||
|
||||
## 「AI 教我做产品」
|
||||
|
||||
经过跟这个「MVP 导师」的 LLM Agent 反复沟通, 确定了产品的主要构想和核心事项. 以下是摘录的一部分
|
||||
|
||||
```markdown
|
||||
#### MVP 概要(3 句话)
|
||||
|
||||
- **为谁**:20‑30 岁、周末感到无聊且有意愿尝试新事物的年轻人。
|
||||
- **解决什么痛点**:不清楚该尝试哪些活动、如何快速入门、活动是否适合自己、以及能获得什么收益。
|
||||
- **提供的核心功能**:活动列表页面 → 点击感兴趣的活动 → 展示入门门槛与材料推荐(入门材料按钮)并埋点上报。
|
||||
```
|
||||
|
||||
```markdown
|
||||
## MVP 核心功能:
|
||||
1. **活动列表**:集中展示多种可入门活动(绘画、球类、手工等)。
|
||||
2. **入门详情**:点击任意活动 → 展示入门门槛、必备材料、推荐教程链接。
|
||||
3. **埋点追踪**:记录 “点击 → ≥1 min 外部阅读 → 回站” 行为,用于验证假设。
|
||||
```
|
||||
|
||||
这里印象深刻的是, MVP 导师让我先确保用户痛点一定要是真实的, 在初期没有论证的情况下, MVP 的意义就在于基于一个假设(假设用户的痛点是 xxx), 我们要围绕这个痛点先开发出 1-2 个核心功能, 然后通过用户数据分析, 来验证我们关于用户痛点的假设是否成立. 如果不成立说明是伪需求, 也就没有继续投入的必要了.
|
||||
|
||||
这一点还是让我挺惊喜的, 因为大部分人有个 idea 想做 xx 产品, 大部分都是脑门一热, 想要有 xxx 功能但是其实根本的需求并不是这个. 花了很多精力搞出来的功能其实是伪需求. 而 AI 导师专业水准还是挺在线的, 能够在一开始就识别这个风险
|
||||
|
||||
## Vibe Coding
|
||||
|
||||
接下来就是要进入开发的部分了. 我选择的 AI 代码工具是字节的 Trae 海外版, 不用验证手机号而且可以使用 Google Gemini、OpenAI GPT-4o、Anthropic Claude 4 等高级模型.
|
||||
|
||||
首先让 AI 根据产品需求文档、拆解任务文档, 确定了技术方案. 不过这里我为了效率简化了下&注入了一些自己的私房调料, 最终使用的方案为:
|
||||
|
||||
- astro + vue3 + tailwind css 来构建 web 站点
|
||||
- directus cms 作为后端,省去编写后端和对接数据库的麻烦
|
||||
- vercel 快速部署
|
||||
|
||||
这部分没啥好说的, 简单列几个吐槽的点吧:
|
||||
|
||||
- astro 配置 tailwindcss, 换了一圈大模型没一个正确的. 应该是跟近期大版本更新有关系. 最后还是我手动跟着 astro 官方的文档搞定的
|
||||
- trae 高级模型试用额度很低, 没写几个功能就超限了开始排队, 动不动前面几百号人基本没法用
|
||||
- 现阶段 AI IDE 基本都是基于 vs code 改的. 所以 vscode 的缺点也都一并继承了过来, 很多语言的插件需要额外手动安装、各种变量跳转用不了、各种奇怪的波浪线报错又没法快速修正
|
||||
|
||||
最后简要看下最终的成果吧
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
后台数据:
|
||||

|
||||
|
||||
## 埋点上报与用户行为分析
|
||||
|
||||
之前做的都是玩具项目和公司内部平台, 没怎么接触过 C 端用户行为分析. 这块确实还是个挺陌生的领域. 不过好在我们有万能的 AI. 在经过埋点需求分析、 技术方案对比、任务拆解之后, 最后采用了 Umami 平台来进行上报, 并简单配置了下指标用于计算用户停留, 辅助验证我们关于用户痛点的假设
|
||||
|
||||

|
||||
|
||||
跟 MVP 导师沟通的时候,确定了验证假设的方式为: 衡量用户是否点击「查看详情」按钮
|
||||
|
||||
- 用户点击并在外部阅读 ≥ 1 分钟后回站
|
||||
- 成功阈值: ≥ 25 % 的访问者完成“点击 → ≥ 1 min 回站
|
||||
|
||||
为了方便统计, 借助 umaimi 的统计功能快速实现, 我只需要统计有多少比例的用户至少点击了一次「了解详情」. 具体到代码实现上, 就是在「点击详情」按钮添加一个上报, 上报内容包括用户的 session id, 后面在 umaimi 统计一段时间内, 按钮点击事件里面, 有多少独立的 session id 处以总的 uv 就可以.
|
||||
|
||||

|
||||
|
||||
## 投放
|
||||
|
||||
众所周知, 天朝桌面端 web 用户已经约等于 0 了, 技术博客都很少人看, 更别提这种泛娱乐向的内容. MVP 导师提供的方案, 也是路线正确, 但是 web 端用户数据反馈验证的路子基本没用. 不过这个 web 页面我也不指望能成为流量主力, 最多算个 wiki.
|
||||
|
||||
要想真的有人看, 收获真实用户反馈, 还是需要到各种新媒体平台去投放的. 然后再收集数据进行分析, 不过这个工作量就是另外一回事了. 运营起来还是需要挺多时间精力的.
|
||||
|
||||
尝试做了几个图投放到小红书, 放几个示例图
|
||||
|
||||

|
||||
|
||||
用的搞定设计的模版调整了下, 插图是用 Gemini, 效果还可以, 能很好地遵循用户指令, 不过美学方面跟 MidJourney 那些还是差了一截, 毕竟人家专攻的方向. 提示词里面限制好风格的话出图效果还是可以的, 这里后续如果有必要的话, 其实也可以 AI 批量生产插图.
|
||||
|
||||
不过小红书账号冷启动, 反响平平. 这里后续有时间再研究吧
|
||||
|
||||
## The End
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
title: 个人向 Linux 新服务器初始化清单
|
||||
date: 2023-03-14
|
||||
lastmod: 2025-06-21
|
||||
description: 一份 Linux 初始化清单,避免每次拿到新的服务器都要一个个去各种地方搜集指令,以做备忘 & 供有需要的朋友参考。以目前最新的 Debian 11 Bullseye 为例
|
||||
categories:
|
||||
- 技术
|
||||
@@ -9,14 +8,16 @@ tags:
|
||||
- 技术
|
||||
- Linux
|
||||
- Debian
|
||||
- Traefik
|
||||
- Headless CMS
|
||||
---
|
||||
|
||||
|
||||
一份 Linux 初始化清单,避免每次拿到新的服务器都要一个个去各种地方搜集指令,以做备忘 & 供有需要的朋友参考。
|
||||
|
||||
服务器发行版我个人推荐 Debian 系列,CentOS 系现在已经开始分裂而且说实话对新手其实并不友好。Debian 是在兼容性,易用性和稳定性之间都取得不错平衡的发行版。新手推荐 Ubuntu, 不过最近商业化有点过度,夹带了越来越多的私活,我个人所有新安装的 Linux 已经全线转向 Debian. 下文以目前最新的 Debian 11 Bullseye 为例。Debian 12 bookworm 也测试通过。
|
||||
服务器发行版我个人推荐 Debian 系列,CentOS 系现在已经开始分裂而且说实话对新手其实并不友好。Debian 是在兼容性,易用性和稳定性之间都取得不错平衡的发行版。新手推荐 Ubuntu, 不过最近商业化有点过度,夹带了越来越多的私活,我个人所有新安装的 Linux 已经全线转向 Debian. 下文以目前最新的 Debian 11 Bullseye 为例
|
||||
|
||||
> azure 干净的 debian 11 镜像,资源使用情况供参考:
|
||||
> azure 干净的 debian 11 镜像,资源使用情况供参考
|
||||
>
|
||||
> ~1G Disk, ~100M RAM, ~300 packages
|
||||
|
||||
@@ -31,15 +32,12 @@ tags:
|
||||
检查服务商防火墙和系统自带防火墙 (debian 系一般为 `ufw`, cent os 系一般为 `firewall-cmd`).放行 SSH(22), 新的 SSH(自定义), HTTP, HTTPS, 以及其他常用开发端口
|
||||
|
||||
### 1.2 新建用户与检查 sudoer
|
||||
登录到 root 用户,创建个人账户并设定密码
|
||||
|
||||
```shell
|
||||
// -m 创建对应home文件夹
|
||||
// 添加到 sudo 用户组自动获得sudo权限, 部分发行版为wheel组
|
||||
|
||||
useradd -m --groups sudo colin
|
||||
|
||||
// 设定密码
|
||||
passwd colin
|
||||
```
|
||||
|
||||
也可直接编辑`/etc/sudoers` 文件为新用户添加 sudo 权限,使用 `visudo` 指令可以自动帮你校验,避免配置写错把系统搞崩
|
||||
@@ -56,6 +54,7 @@ passwd colin
|
||||
//for debian
|
||||
sudo sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
|
||||
|
||||
|
||||
//for ubuntu
|
||||
sudo sed -i 's@//.*archive.ubuntu.com@//mirrors.ustc.edu.cn@g' /etc/apt/sources.list
|
||||
```
|
||||
@@ -74,8 +73,7 @@ sudo apt install zsh tmux htop duf htop tldr screenfetch tree
|
||||
|
||||
### 1.4 SSH 安全
|
||||
|
||||
修改端口,配置文件`/etc/ssh/sshd_config`. 重启机器或 sshd 服务后生效。
|
||||
此外最好将`PermitRootLogin`修改为`no`, 可以禁用 root 登录。
|
||||
修改端口,配置文件`/etc/ssh/sshd_config`. 重启机器或 sshd 服务后生效
|
||||
|
||||
在本机检查`~/.ssh/`有无 id_rsa 等已生成的 key. 如没有再使用 `ssh-keygen` 生成私钥
|
||||
将本机的公钥上传到远端,再写入远端的 `authorized_keys` 中
|
||||
@@ -85,10 +83,12 @@ sudo apt install zsh tmux htop duf htop tldr screenfetch tree
|
||||
注意修改权限,`~/.ssh/authorized_keys` 权限为 600. `~/.ssh/`为 700
|
||||
|
||||
可以参考以下设置
|
||||
|
||||
> .ssh/ 0700/rwx------
|
||||
> .ssh/*.pub 644/rw-r--r--
|
||||
> .ssh/* 0600/rw-------
|
||||
|
||||
|
||||
如失败可参考这篇文章 debug. [https://superuser.com/questions/1137438/ssh-key-authentication-fails](https://superuser.com/questions/1137438/ssh-key-authentication-fails)
|
||||
|
||||
### 1.5 设置 hostname
|
||||
@@ -100,18 +100,18 @@ sudo hostnamectl set-hostname my-new-server
|
||||
sudo hostnamectl status
|
||||
```
|
||||
|
||||
此外`/etc/hosts` 中默认会有个本机 hostname 映射到`127.0.0.1` 的配置,修改 host 之后这里别名的映射也要修改下,不然终端执行命令会一直弹 `sudo: unable to resolve host xxx: Name or service not known`
|
||||
|
||||
修改后需重启
|
||||
|
||||
---
|
||||
|
||||
### 1.6 SWAP
|
||||
|
||||
可选,建议内存<2G 配置 swap, 大小至少为 2 倍物理内存,可以有效避免意外爆内存的情况。仅推荐 SSD 盘的服务器开启。
|
||||
可选,建议内存<2G 配置 swap, 大小至少为 2 倍物理内存
|
||||
|
||||
推荐用 `fallocate` , 因为这个是最简单、最快速的创建交换空间的方法。 `fallocate` 命令用于为文件预分配块 / 大小。
|
||||
|
||||
以下内容参考 linux.cn
|
||||
|
||||
使用 `fallocate` 创建交换空间,首先在 `/` 目录下创建一个名为 `swap_space` 的文件。然后分配 2GB 到 `swap_space` 文件:
|
||||
|
||||
```shell
|
||||
@@ -132,6 +132,8 @@ sudo swapon -s
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
每次重启后都要重新挂载磁盘分区。因此为了使之持久化,就像上面一样,我们编辑 `/etc/fstab` 并输入下面行:
|
||||
|
||||
```
|
||||
@@ -144,6 +146,9 @@ sudo swapon -s
|
||||
还可以按需选择使用 zram,提升内存可用量,不过会略微增加 cpu 使用和内存延时。可以搜索 zramctl, zramswap 等关键字
|
||||
|
||||
|
||||
注意 Debian 新版本 swapon 等工具所在的目录 /usr/sbin 不在普通用户的 PATH 中,可能需要手动执行前缀使用。如 /usr/sbin/swapon
|
||||
|
||||
|
||||
---
|
||||
|
||||
### 1.7 绑定域名
|
||||
@@ -195,7 +200,7 @@ docker mirror 配置可以加速 image pull, 国内公开可用的加速站点
|
||||
],
|
||||
"log-opts": {
|
||||
"max-file": "5",
|
||||
"max-size": "1m"
|
||||
"max-size": "10m"
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -285,14 +290,12 @@ sudo systemctl enable fail2ban
|
||||
```conf
|
||||
[sshd]
|
||||
enabled = true
|
||||
# 这里修改为实际的 sshd 端口
|
||||
port = 20000
|
||||
port = 20000 # 这里修改为实际的 sshd 端口
|
||||
filter = sshd
|
||||
banaction = iptables-allports
|
||||
|
||||
[DEFAULT]
|
||||
# 1h 时间窗口
|
||||
findtime = 3600
|
||||
findtime = 3600 # 1h 时间窗口
|
||||
maxretry = 3
|
||||
bantime = 6h
|
||||
```
|
||||
@@ -329,7 +332,7 @@ Status for the jail: sshd
|
||||
|
||||
配置文件位置 `/etc/sysctl.conf`
|
||||
|
||||
```conf
|
||||
```c
|
||||
# mem
|
||||
vm.swappiness = 10
|
||||
|
||||
@@ -338,11 +341,6 @@ net.core.default_qdisc=fq
|
||||
net.ipv4.tcp_congestion_control=bbr
|
||||
net.ipv4.tcp_fastopen=3
|
||||
net.ipv4.tcp_slow_start_after_idle=0
|
||||
|
||||
# zram 相关配置,配合下文 zram 使用
|
||||
vm.watermark_boost_factor = 0
|
||||
vm.watermark_scale_factor = 125
|
||||
vm.page-cluster = 0
|
||||
```
|
||||
|
||||
配置完之后保存并应用
|
||||
@@ -351,74 +349,7 @@ vm.page-cluster = 0
|
||||
sudo sysctl -p
|
||||
```
|
||||
|
||||
|
||||
### 3.2 更多内存空间 - ZRAM
|
||||
ZRAM 内存压缩,对于个人服务器来说,始终活跃的程序占用的内存只有比较小一部分,启用 zram 可以将这部分内存压缩,从而可以部署更多的服务。
|
||||
|
||||
建议使用`zramtool`, 简单方便
|
||||
```shell
|
||||
sudo apt install zram-tools
|
||||
```
|
||||
修改`/etc/default/zramswap`, 末尾添加
|
||||
```ini
|
||||
ALGO=zstd
|
||||
PERCENT=60
|
||||
```
|
||||
|
||||
之后执行`sudo service zramswap reload`重载生效。
|
||||
可以使用 swapon 命令查看生效情况
|
||||
```
|
||||
~ » sudo swapon -show
|
||||
NAME TYPE SIZE USED PRIO
|
||||
/swap_space file 2G 32.1M -2
|
||||
/dev/zram0 partition 489.9M 0B 100
|
||||
```
|
||||
|
||||
这样一来,会将机器物理内存的 50% 配置 zram, 使用 zstd 压缩算法,一般压缩比能达到 3:1, 也就是说,1G 的机器,可以相当于有`0.5G+3*0.5G=2G`的内存。
|
||||
|
||||
注意 Debian 新版本 swapon 等工具所在的目录 /usr/sbin 不在普通用户的 PATH 中,可能需要手动执行前缀使用。如 /usr/sbin/swapon
|
||||
|
||||
### 3.3 更多内存空间 - 关闭 kdump,释放预留的内存空间
|
||||
|
||||
新服务器开起来之后,你会发现无论是 htop 还是 free 等命令,看到的总内存就是比你买服务器时页面上写的要小。比如我开的两核 1G 的机器,实际机器上看到的总内存只有 816M. 这是因为 linux 系统会默认开启 kdump,预留了一部分内存不让我们使用。
|
||||
|
||||
Kdump 是 Linux 系统的一种内核崩溃转储机制,它允许在系统发生内核崩溃(例如内核 panic)时,捕获内存的转储信息,从而帮助事后分析故障原因。默认的配置`2G-8G:256M,8G-16G:512M,16G-:768M`, 如果你买的是 2G 的机器,上来就有 1/8 的空间用不了。
|
||||
|
||||
但是我们个人日常使用的 linux 机器基本用不到这个功能,不用预留这部分空间。
|
||||
|
||||
操作方法有两种:将预留内存改为 0 or 直接关闭 kdump 服务。对于个人玩家小内存机器我建议直接关闭。操作如下:
|
||||
|
||||
```bash
|
||||
# 备份grub配置文件
|
||||
sudo cp /etc/default/grub /etc/default/grub.bak
|
||||
|
||||
# 编辑grub配置,删除 crashkernel=0M-2G:0M,2G-8G:192M 这样的部分
|
||||
sudo nano /etc/default/grub
|
||||
|
||||
# 部分发行版镜像可能还有单独的kdump配置文件,直接删除
|
||||
sudo rm /etc/default/grub.d/kdump-tools.cfg
|
||||
|
||||
# 更新grub配置
|
||||
sudo update-grub
|
||||
|
||||
# 关闭并禁用Kdump服务
|
||||
sudo systemctl disable kdump-tools
|
||||
sudo systemctl stop kdump-tools
|
||||
|
||||
# 重启系统
|
||||
sudo reboot
|
||||
|
||||
# 检查是否生效, 状态为 inactive(dead),即 kdump 服务已停止运行
|
||||
sudo systemctl status kdump
|
||||
|
||||
# 检查 crash size 是否为0
|
||||
cat /sys/kernel/kexec_crash_size
|
||||
```
|
||||
|
||||
更多内容可以参见这篇文档:[预留内存相关文档 - 阿里云](https://help.aliyun.com/zh/ecs/use-cases/view-and-change-the-size-of-reserved-memory-on-a-linux-instance#7d5ae6803amdp) 或者 [预留内存相关文档 - 腾讯云](https://cloud.tencent.com/document/product/213/115734)
|
||||
|
||||
|
||||
### 3.3 其他进阶配置
|
||||
### 3.2 其他进阶配置
|
||||
|
||||
一些其他的系统维护技巧与策略,如
|
||||
|
||||
|
||||
@@ -38,15 +38,15 @@
|
||||
src="{{ "assets/prism.js" | absURL }}"></script>
|
||||
|
||||
<script defer onload="tocbot_init()"
|
||||
onerror="fallbackJSloader('https://s4.zstatic.net/ajax/libs/tocbot/4.9.1/tocbot.min.js','tocbot_init')"
|
||||
onerror="fallbackJSloader('https://cdn.staticfile.org/tocbot/4.9.1/tocbot.min.js','tocbot_init')"
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.11.1/tocbot.min.js"></script>
|
||||
<link rel="stylesheet"
|
||||
onerror="fallbackCSSloader('https://s4.zstatic.net/ajax/libs/tocbot/4.9.1/tocbot.css')"
|
||||
onerror="fallbackCSSloader('https://cdn.staticfile.org/tocbot/4.9.1/tocbot.css')"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.11.1/tocbot.css">
|
||||
<script defer onload="init_gitalk()"
|
||||
onerror="fallbackJSloader('https://s4.zstatic.net/ajax/libs/gitalk/1.7.2/gitalk.min.js','init_gitalk')"
|
||||
onerror="fallbackJSloader('https://cdn.staticfile.org/gitalk/1.7.2/gitalk.min.js','init_gitalk')"
|
||||
src="https://cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.min.js"></script>
|
||||
<link rel="stylesheet"
|
||||
onerror="fallbackCSSloader('https://s4.zstatic.net/ajax/libs/gitalk/1.7.2/gitalk.css')"
|
||||
onerror="fallbackCSSloader('https://cdn.staticfile.org/gitalk/1.7.2/gitalk.css')"
|
||||
href="https://cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.min.css">
|
||||
<!-- no min css version fallback for gitalk css -->
|
||||
@@ -20,8 +20,8 @@ onerror="fallbackJSloader('https://cdn.staticaly.com/gh/panr/hugo-theme-hello-fr
|
||||
src="{{ "assets/main.js" | absURL }}"></script>
|
||||
|
||||
<script async onload="panguSpaing()"
|
||||
onerror="fallbackJSloader('https://s4.zstatic.net/ajax/libs/pangu/4.0.7/pangu.min.js','panguSpaing')"
|
||||
onerror="fallbackJSloader('https://cdn.staticfile.org/pangu/4.0.7/pangu.min.js','panguSpaing')"
|
||||
src="https://cdn.jsdelivr.net/npm/pangu@4/dist/browser/pangu.min.js"></script>
|
||||
<script async onload="initQuickLink()"
|
||||
onerror="fallbackJSloader('https://s4.zstatic.net/ajax/libs/quicklink/2.3.0/quicklink.umd.js','initQuickLink')"
|
||||
onerror="fallbackJSloader('https://cdn.staticfile.org/quicklink/2.3.0/quicklink.umd.js','initQuickLink')"
|
||||
src="https://cdn.jsdelivr.net/npm/quicklink@2/dist/quicklink.umd.js"></script>
|
||||
@@ -1,3 +1,5 @@
|
||||
<!-- <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22>
|
||||
<text y=%22.9em%22 font-size=%2290%22>👋</text></svg>"> -->
|
||||
<link rel="icon" href="/favicon.png">
|
||||
<link rel="apple-touch-icon" href="/favicon.png">
|
||||
|
||||
|
||||
Reference in New Issue
Block a user