From 8fdf9115a718a63f2ff6a951124ea43448086c2f Mon Sep 17 00:00:00 2001 From: Nizeross Date: Thu, 29 Oct 2026 23:06:17 +0800 Subject: [PATCH 1/7] docs: audit existing blog and plan safe local migration --- ARCHITECTURE.md | 40 ++++++++++++++++++++++++++++++++++++++++ MIGRATION_PLAN.md | 27 +++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 ARCHITECTURE.md create mode 100644 MIGRATION_PLAN.md diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md new file mode 100644 index 0000000..eb195a6 --- /dev/null +++ b/ARCHITECTURE.md @@ -0,0 +1,40 @@ +# 架构与现状审计 + +审计日期:2026-10-29。工作区为 `D:\hugo`,实际 Git/Hugo 项目根为 `myblog/`;所有开发命令从该目录执行。初始工作区干净,基线提交 `efbb03e`,远程为 `git@github.com:Nizeross/nizeross.github.io.git`,默认分支 `main`。本次仅在本地 `refactor/blog-system` 开发。 + +## 决策:保留 Hugo + Blowfish + +内容使用 Markdown + TOML Frontmatter;Hugo 在构建时生成 HTML、RSS、搜索 JSON。浏览器只加载主题现有库与少量原生 JavaScript,不引入 React、数据库或在线写作 API。Blowfish 子模块固定在 `3a9016a6d93f6d498ab5fc3b0aa7d51869962f25`,所有覆盖位于站点自己的 `layouts/` 和 `assets/`。 + +换成其他框架对三篇既有文章没有实质收益,却要重做 shortcode、图片处理、搜索和链接兼容。本方案保留 `/posts/<原目录>/`,用首页覆盖和独立 Projects 模板提供辨识度;构建和审核工具独立于主题,未来换主题仍能复用。 + +## 审计事实 + +| 项目 | 发现与处理策略 | +| --- | --- | +| 内容 | 三个 leaf bundle,含本地封面。保留文章正文与路径;首篇示例有未闭合代码围栏,修复语法并记录。 | +| 配置 | `config/_default/` 分文件;语言文件标为 English/en 但内容为中文,需修正;全站基础色遵循原生色板,白天纯白、夜间 #1E293B。 | +| 主题 | submodule,无本地改动;要求 Hugo Extended 0.141.0–0.154.5。工作区二进制为非 Extended 0.155.0,线上 workflow 用 Extended 0.141.0,需统一到受支持的 Extended 0.154.5。 | +| 输出 | 仓库根与 `public/` 都有历史生成文件。本次不删除;新本地构建输出到忽略的 `.build/site/`,避免修改这些历史文件。未来在确认后才从 Git 移除旧输出。 | +| 部署 | `.github/workflows/hugo.yaml` push main 后直接部署;整个 workflow 有 Pages 写权限、未做内容检查、Sass 未锁版本、npm 失败被忽略。保留现有 workflow 原样,提供待批准的替换方案。 | +| 域名 | 根 `CNAME` 为 `kirisame.me`;baseURL 仍为用户名地址。不能自行决定哪一个是权威域名,保持配置不变,批准迁移时再核对 Pages base URL。 | +| 远程 | 连接可见的 Nizeross 仓库只有 `nizeross.github.io`,未发现另一个可见用户名站点;这不是对所有私有仓库的证明。GitHub 最近一次部署 efbb03e 成功;读取 rulesets 返回空列表,不能证明已有审核保护。 | +| 安全 | 原 footer 请求第三方访问统计;有注释掉的 Firebase 配置。移除页面统计依赖,清理无效配置;自托管资源,不将在线 AI 设为必需。个人邮箱本来公开,保留用户身份资料。 | + +## 数据与控制流 + +```text +Markdown + 本地图片 → 内容/格式检查 → Hugo → HTML/RSS/JSON + ↓ + 链接、集成与浏览器测试 + ↓ + PR 审核 → main → Pages artifact +``` + +站点代码:`layouts/`(首页、项目列表、小型扩展)、`assets/css/`(主题色板与排版)、`assets/js/`(阅读进度)。`content/` 是唯一文章来源;archetypes 定义五种文章与项目模板。`scripts/` 提供写作、验证、建议工具。Node 依赖只用于开发检查和浏览器测试;Python 3.11+ 使用标准库解析 TOML、HTML 与本地链接。 + +## 发布边界 + +新增 CI 只有 contents:read,不部署。生产 workflow 的建议版本保存在 `.github/workflow-proposals/`,不会被 GitHub 执行。最终需要人工批准替换旧工作流,并配置 main 必须 PR、必需检查、禁止绕过,以及 github-pages 环境审核。代码无法代替服务器端分支保护;未配置前不能声称审核已强制生效。本次不修改默认分支、远程、域名或 Pages 设置,也不推送。 + +参考:[Blowfish 自定义机制](https://blowfish.page/docs/advanced-customisation/)、[GitHub Pages workflows](https://docs.github.com/en/pages/getting-started-with-github-pages/using-custom-workflows-with-github-pages)、[Hugo 安全配置](https://gohugo.io/configuration/security/)。 diff --git a/MIGRATION_PLAN.md b/MIGRATION_PLAN.md new file mode 100644 index 0000000..9427152 --- /dev/null +++ b/MIGRATION_PLAN.md @@ -0,0 +1,27 @@ +# 分阶段迁移计划 + +所有阶段均在本地分支完成;构建写入 `.build/site/`,保留原始内容与历史输出。每阶段以本地提交、执行记录和明确验收项交付。 + +| 阶段 | 本地交付与验收 | 状态 | +| --- | --- | --- | +| 1 审计与方案 | ARCHITECTURE.md、路径与域名清单、技术决策 | 已完成 | +| 2 可运行基线 | 固定兼容 Hugo Extended、独立输出、现有链接基线、写作命令 | 进行中 | +| 3 界面与内容 | 桌面工作台风首页、分类/项目/关于/友链、中文排版、数学/搜索/阅读进度 | 待执行 | +| 4 自动化 | 内容检查、Markdown lint、构建、测试、只检查 CI、待批准发布方案 | 待执行 | +| 5 质量 | 单元/集成/链接/浏览器/无障碍/依赖检查,截图与问题记录 | 待执行 | +| 6 文档 | README、开发/部署/学习笔记、最终报告、操作边界 | 待执行 | + +## 兼容与回滚 + +不移动已有三篇文章目录;保存基线 URL 并自动验证。文章仅修复已知不闭合围栏及补充组织元数据,不重写正文。旧模板和生成文件不删除。所有自定义不进入主题 submodule。可通过切回原 main 在本地恢复原站;正式上线后通过回退变更 PR 并重新部署恢复,避免重写历史。 + +## 发布前需确认 + +1. 审阅本地界面、文章变更和测试报告。 +2. 确认正式权威域名;当前 CNAME=kirisame.me 与 baseURL 不一致。 +3. 同意用建议 workflow 替换旧部署流程,并配置分支/环境审核。 +4. 明确授权后才推送此分支与创建 PR;审核合并后由受保护 workflow 发布。 + +## 不纳入首版 + +在线编辑后台、账户登录、数据库、评论系统和在线 AI 自动改文。可选辅助仅产生建议报告,正文必须作者编辑与审核。外链在线检查独立运行,避免网络波动阻塞日常离线写作。 From 3eb2da29bac961a4fa7d61318fd4ad97ef4ad4e8 Mon Sep 17 00:00:00 2001 From: Nizeross Date: Thu, 29 Oct 2026 23:12:25 +0800 Subject: [PATCH 2/7] build: pin compatible Hugo and isolate local build outputs --- .gitignore | 14 ++++++++ scripts/install_hugo.py | 44 +++++++++++++++++++++++ scripts/site.py | 78 +++++++++++++++++++++++++++++++++++++++++ tests/legacy-urls.json | 5 +++ toolchain.json | 10 ++++++ 5 files changed, 151 insertions(+) create mode 100644 .gitignore create mode 100644 scripts/install_hugo.py create mode 100644 scripts/site.py create mode 100644 tests/legacy-urls.json create mode 100644 toolchain.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..03366ec --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +/.tools/ +/.build/ +/.cache/ +/node_modules/ +/test-results/ +/playwright-report/ +/reports/*.json +/reports/*.png +/.hugo_build.lock +__pycache__/ +*.pyc +.env +.env.* +!.env.example diff --git a/scripts/install_hugo.py b/scripts/install_hugo.py new file mode 100644 index 0000000..8338f36 --- /dev/null +++ b/scripts/install_hugo.py @@ -0,0 +1,44 @@ +"""Install the pinned Extended release, verifying its recorded SHA-256.""" +import hashlib +import io +import json +from pathlib import Path +import platform +import tarfile +import urllib.request +import zipfile + +ROOT = Path(__file__).resolve().parents[1] + + +def install(): + lock = json.loads((ROOT / 'toolchain.json').read_text(encoding='utf-8')) + suffix = {'Windows': 'windows-amd64.zip', 'Linux': 'linux-amd64.tar.gz', + 'Darwin': 'darwin-universal.tar.gz'}.get(platform.system()) + if suffix is None or (platform.system() != 'Darwin' and platform.machine().lower() not in ('amd64', 'x86_64')): + raise SystemExit('Unsupported architecture; install the pinned Hugo Extended manually.') + expected = lock['hugoDownloads'].get(suffix) + if not expected: + raise SystemExit('Missing release checksum in toolchain.json') + target = ROOT / '.tools' / ('hugo.exe' if platform.system() == 'Windows' else 'hugo') + version = lock['hugo'] + url = f'https://github.com/gohugoio/hugo/releases/download/v{version}/hugo_extended_{version}_{suffix}' + print(f'Downloading Hugo Extended {version} ({suffix})', flush=True) + data = urllib.request.urlopen(url, timeout=90).read() + if hashlib.sha256(data).hexdigest() != expected: + raise SystemExit('Hugo download checksum mismatch; refusing installation') + name = target.name + if suffix.endswith('.zip'): + with zipfile.ZipFile(io.BytesIO(data)) as archive: + binary = archive.read(name) + else: + with tarfile.open(fileobj=io.BytesIO(data), mode='r:gz') as archive: + binary = archive.extractfile(name).read() + target.parent.mkdir(exist_ok=True) + target.write_bytes(binary) + target.chmod(0o755) + print(f'Verified and installed: {target}') + + +if __name__ == '__main__': + install() diff --git a/scripts/site.py b/scripts/site.py new file mode 100644 index 0000000..24bb538 --- /dev/null +++ b/scripts/site.py @@ -0,0 +1,78 @@ +"""Local writing/build assistant. It never pushes or commits automatically.""" +import argparse +import datetime as dt +import json +import os +from pathlib import Path +import re +import subprocess +import sys +import unicodedata + +ROOT = Path(__file__).resolve().parents[1] +KINDS = {'technical': '技术学习', 'project': '项目开发', 'reading': '读书笔记', + 'essay': '思想随笔', 'life': '生活记录'} + + +def slugify(text): + text = unicodedata.normalize('NFKC', text).lower().strip() + return re.sub(r'-+', '-', re.sub(r'[^\w\-]+', '-', text, flags=re.UNICODE)).strip('-_') + + +def hugo(): + binary = ROOT / '.tools' / ('hugo.exe' if os.name == 'nt' else 'hugo') + if not binary.exists(): + raise SystemExit('Run python scripts/install_hugo.py first.') + result = subprocess.check_output([str(binary), 'version'], text=True) + pin = json.loads((ROOT / 'toolchain.json').read_text())['hugo'] + if f'v{pin}' not in result or 'extended' not in result: + raise SystemExit(f'Requires Hugo Extended {pin}: {result}') + return str(binary) + + +def run(*args): + subprocess.run(args, cwd=ROOT, check=True) + + +def new_post(kind, title, slug=None): + if kind not in KINDS: + raise ValueError('Unknown content kind') + slug = slug or slugify(title) + if not slug or not re.fullmatch(r'[\w]+(?:[-][\w]+)*', slug): + raise ValueError('Slug must contain letters, numbers and hyphens; no paths') + folder = ROOT / 'content' / 'posts' / slug + if folder.exists(): + raise FileExistsError(f'Article already exists: {folder}') + folder.mkdir() + template = (ROOT / 'archetypes' / f'{kind}.md').read_text(encoding='utf-8') + template = template.replace('{{ .Date }}', dt.datetime.now(dt.timezone(dt.timedelta(hours=8))).isoformat(timespec='seconds')) + template = template.replace('{{ .Title }}', json.dumps(title, ensure_ascii=False)) + (folder / 'index.md').write_text(template, encoding='utf-8') + print(f'Created draft: {folder / "index.md"}') + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + sub = parser.add_subparsers(dest='command', required=True) + new = sub.add_parser('new') + new.add_argument('kind', choices=KINDS) + new.add_argument('title') + new.add_argument('--slug') + for name in ('build', 'preview', 'check', 'commit-draft'): + sub.add_parser(name) + args = parser.parse_args() + if args.command == 'new': + new_post(args.kind, args.title, args.slug) + elif args.command == 'build': + run(hugo(), '--destination', '.build/site', '--cacheDir', str(ROOT / '.cache/hugo'), '--gc', '--minify') + elif args.command == 'preview': + run(hugo(), 'server', '--buildDrafts', '--destination', '.build/preview', '--bind', '127.0.0.1', '--port', '1313') + elif args.command == 'check': + run(sys.executable, 'scripts/check_content.py') + else: + run('git', 'diff', '--stat') + print('\nCommit draft: docs: add
\nReview with git diff, stage exact paths, then git commit. No commit or push was performed.') + + +if __name__ == '__main__': + main() diff --git a/tests/legacy-urls.json b/tests/legacy-urls.json new file mode 100644 index 0000000..5c7bfbd --- /dev/null +++ b/tests/legacy-urls.json @@ -0,0 +1,5 @@ +[ + "/posts/how-build-blog/", + "/posts/my-first-post/", + "/posts/pcl2-memory-optimization/" +] diff --git a/toolchain.json b/toolchain.json new file mode 100644 index 0000000..b25d7d1 --- /dev/null +++ b/toolchain.json @@ -0,0 +1,10 @@ +{ + "hugo": "0.154.5", + "themeCommit": "3a9016a6d93f6d498ab5fc3b0aa7d51869962f25", + "node": "24", + "python": "3.11", + "hugoDownloads": { + "windows-amd64.zip": "19d1b5e0104b1915acdec74ffcd163c691fc7bfe9d95b487503650ce62a13d7e", + "linux-amd64.tar.gz": "372d2f0538b24d2bb9285f0583c1e3b02d023ec2c2b8eb90e5c3bbfb3139fb13" + } +} From 34643e7c4fbb90344edf6fff617d4b1e63b8259c Mon Sep 17 00:00:00 2001 From: Nizeross Date: Thu, 29 Oct 2026 23:16:56 +0800 Subject: [PATCH 3/7] feat: build personal workbench and structured reading experience --- archetypes/essay.md | 16 +++ archetypes/life.md | 16 +++ archetypes/project.md | 20 ++++ archetypes/reading.md | 22 ++++ archetypes/technical.md | 24 +++++ assets/css/custom.css | 97 ++++++++++++++++++ assets/js/reading-progress.js | 24 +++++ assets/js/search.js | 90 ++++++++++++++++ config/_default/languages.zh-cn.toml | 12 +-- config/_default/menus.zh-cn.toml | 32 ++++++ config/_default/params.toml | 19 ++-- content/about/index.md | 32 ++++++ .../_index.md" | 4 + .../_index.md" | 4 + .../_index.md" | 4 + .../_index.md" | 4 + .../_index.md" | 4 + content/links/index.md | 17 +++ content/posts/how-build-blog/index.md | 34 ++++-- content/posts/my-first-post/index.md | 11 +- .../posts/pcl2-memory-optimization/index.md | 11 +- content/projects/_index.md | 7 ++ content/projects/personal-blog/index.md | 48 +++++++++ content/projects/personal-blog/screenshot.svg | 9 ++ content/writing/index.md | 44 ++++++++ content/writing/logo.png | Bin 0 -> 416 bytes layouts/partials/extend-footer.html | 2 + layouts/partials/footer.html | 27 ----- layouts/partials/home/custom.html | 47 +++++++++ layouts/partials/search.html | 13 +++ layouts/partials/toc.html | 6 ++ layouts/projects/list.html | 16 +++ 32 files changed, 656 insertions(+), 60 deletions(-) create mode 100644 archetypes/essay.md create mode 100644 archetypes/life.md create mode 100644 archetypes/project.md create mode 100644 archetypes/reading.md create mode 100644 archetypes/technical.md create mode 100644 assets/js/reading-progress.js create mode 100644 assets/js/search.js create mode 100644 content/about/index.md create mode 100644 "content/categories/\346\200\235\346\203\263\351\232\217\347\254\224/_index.md" create mode 100644 "content/categories/\346\212\200\346\234\257\345\255\246\344\271\240/_index.md" create mode 100644 "content/categories/\347\224\237\346\264\273\350\256\260\345\275\225/_index.md" create mode 100644 "content/categories/\350\257\273\344\271\246\347\254\224\350\256\260/_index.md" create mode 100644 "content/categories/\351\241\271\347\233\256\345\274\200\345\217\221/_index.md" create mode 100644 content/links/index.md create mode 100644 content/projects/_index.md create mode 100644 content/projects/personal-blog/index.md create mode 100644 content/projects/personal-blog/screenshot.svg create mode 100644 content/writing/index.md create mode 100644 content/writing/logo.png create mode 100644 layouts/partials/extend-footer.html create mode 100644 layouts/partials/home/custom.html create mode 100644 layouts/partials/search.html create mode 100644 layouts/partials/toc.html create mode 100644 layouts/projects/list.html diff --git a/archetypes/essay.md b/archetypes/essay.md new file mode 100644 index 0000000..10f703a --- /dev/null +++ b/archetypes/essay.md @@ -0,0 +1,16 @@ ++++ +title = {{ .Title }} +date = '{{ .Date }}' +draft = true +contentType = "essay" +categories = ["思想随笔"] +tags = [] +summary = "请用一句话说明这篇文章的核心问题。" ++++ + +## 问题从哪里来 + +## 观察与思考 + +## 尚未想明白的事 + diff --git a/archetypes/life.md b/archetypes/life.md new file mode 100644 index 0000000..2db0b83 --- /dev/null +++ b/archetypes/life.md @@ -0,0 +1,16 @@ ++++ +title = {{ .Title }} +date = '{{ .Date }}' +draft = true +contentType = "life" +categories = ["生活记录"] +tags = [] +summary = "请用一句话说明这篇文章的核心问题。" ++++ + +## 此时此地 + +## 想留下的细节 + +## 回看 + diff --git a/archetypes/project.md b/archetypes/project.md new file mode 100644 index 0000000..69c3944 --- /dev/null +++ b/archetypes/project.md @@ -0,0 +1,20 @@ ++++ +title = {{ .Title }} +date = '{{ .Date }}' +draft = true +contentType = "project" +categories = ["项目开发"] +tags = [] +summary = "请用一句话说明这篇文章的核心问题。" ++++ + +## 背景与目标 + +## 设计与取舍 + +## 实现与测试 + +## 收获与改进 + +## 参考资料 + diff --git a/archetypes/reading.md b/archetypes/reading.md new file mode 100644 index 0000000..9d06db1 --- /dev/null +++ b/archetypes/reading.md @@ -0,0 +1,22 @@ ++++ +title = {{ .Title }} +date = '{{ .Date }}' +draft = true +contentType = "reading" +categories = ["读书笔记"] +tags = [] +summary = "请用一句话说明这篇文章的核心问题。" ++++ + +## 书目信息 + +书名、作者、版本、章节。 + +## 核心论证 + +转述与引文需要注明出处和页码。 + +## 我的理解与疑问 + +## 延伸阅读 + diff --git a/archetypes/technical.md b/archetypes/technical.md new file mode 100644 index 0000000..17e3035 --- /dev/null +++ b/archetypes/technical.md @@ -0,0 +1,24 @@ ++++ +title = {{ .Title }} +date = '{{ .Date }}' +draft = true +contentType = "technical" +categories = ["技术学习"] +tags = [] +summary = "请用一句话说明这篇文章的核心问题。" ++++ + +## 问题与环境 + +记录系统、工具版本,以及要解决的问题。 + +## 原理与验证 + +```text +在这里写最小可复现示例 +``` + +## 结论与参考 + +区分验证结果和推断。 + diff --git a/assets/css/custom.css b/assets/css/custom.css index 4221e5a..5e8d1e2 100644 --- a/assets/css/custom.css +++ b/assets/css/custom.css @@ -11,3 +11,100 @@ 0%, 100% { opacity: 1; } 50% { opacity: 0; } } + +/* Site-owned layout; Blowfish still owns appearance, transparency and articles. */ +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", sans-serif; +} +:root { --desk-border: rgba(var(--color-neutral-300), .8); --desk-muted: rgb(var(--color-neutral-600)); --desk-accent: #16645a; --desk-panel: rgba(var(--color-neutral-50), .7); } +.dark { --desk-border: rgba(var(--color-neutral-600), .7); --desk-muted: rgb(var(--color-neutral-300)); --desk-accent: #7dd3b8; --desk-panel: rgba(var(--color-neutral-700), .23); } +a, button { -webkit-tap-highlight-color: transparent; } +:focus-visible { outline: 2px solid var(--desk-accent); outline-offset: 5px; border-radius: 3px; } +.workbench { padding-top: 1.5rem; } +.intro-grid { display: grid; grid-template-columns: 1.15fr 1fr; gap: 3rem; align-items: center; padding: 1.5rem 0 4rem; } +.eyebrow { display: flex; align-items: center; gap: .6rem; font: 500 .69rem/1.6 ui-monospace, SFMono-Regular, Consolas, monospace; letter-spacing: .12em; color: var(--desk-muted); margin: 0 0 1.2rem; } +.status-dot { display: inline-block; width: .45rem; height: .45rem; border-radius: 50%; background: var(--desk-accent); flex-shrink: 0; } +.intro-copy h1 { font-size: clamp(2.6rem, 4vw, 3.75rem); line-height: 1.3; letter-spacing: -.055em; font-weight: 800; margin: .8rem 0 1.4rem; } +.intro-accent { color: var(--desk-accent); } +.intro-description { color: var(--desk-muted); max-width: 31rem; font-size: 1rem; line-height: 1.95; } +.intro-actions { display: flex; gap: 1rem; flex-wrap: wrap; align-items: center; margin: 2rem 0 1rem; } +.action-primary, .action-secondary { display: inline-flex; align-items: center; gap: 1.2rem; font-size: .85rem; font-weight: 600; padding: .7rem 1rem; border-radius: .4rem; text-decoration: none; } +.action-primary { background: var(--desk-accent); color: #fff; } +.dark .action-primary { color: #152a29; } +.action-secondary { border: 1px solid var(--desk-border); } +.action-primary:hover, .action-secondary:hover { transform: translateY(-1px); } +.intro-note { color: var(--desk-muted); font-size: .75rem; margin-top: 1.8rem; } +.terminal-panel { border: 1px solid var(--desk-border); border-radius: .65rem; overflow: hidden; background: var(--desk-panel); box-shadow: 0 16px 36px -26px rgba(0,0,0,.4); transform: rotate(1deg); } +.window-bar, .window-status { display: flex; align-items: center; justify-content: space-between; gap: .5rem; padding: .65rem 1rem; font: .65rem/1.6 ui-monospace, Consolas, monospace; color: var(--desk-muted); } +.window-bar { border-bottom: 1px solid var(--desk-border); } +.window-dots { color: #ab7854; font-size: .7rem; letter-spacing: .12em; } +.terminal-body { padding: 1.25rem 1.4rem; } +.terminal-command { font: .8rem/1.8 ui-monospace, Consolas, monospace; margin: 0 0 1rem; } +.terminal-command > span { color: var(--desk-accent); margin-right: .5rem; } +.identity-line { display: flex; align-items: center; gap: .9rem; margin-bottom: 1.8rem; } +.identity-line img { border-radius: .45rem; width: 3.3rem; height: 3.3rem; object-fit: cover; } +.identity-line strong { display: block; font: 600 .95rem/1.5 ui-monospace, Consolas, monospace; } +.identity-line div > span { font-size: .7rem; color: var(--desk-muted); } +.terminal-list { list-style: none; padding: 0; margin: 0; color: var(--desk-muted); font-size: .8rem; line-height: 2.1; } +.terminal-list li::before { content: "↳"; color: var(--desk-accent); margin-right: .65rem; } +.terminal-footnote { margin: 1.5rem 0 .4rem; color: var(--desk-muted); font-size: .7rem; } +.window-status { border-top: 1px solid var(--desk-border); } +.window-status > span:last-child { display: flex; align-items: center; gap: .6rem; } +.topics-section, .recent-section { margin-bottom: 3.5rem; } +.section-heading { display: flex; align-items: flex-end; justify-content: space-between; gap: 1rem; margin-bottom: 1.4rem; } +.section-heading .eyebrow { margin-bottom: .4rem; } +.section-heading h2 { font-weight: 700; font-size: 1.4rem; letter-spacing: -.025em; } +.section-heading > a { font-size: .8rem; white-space: nowrap; color: var(--desk-muted); } +.topic-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: .75rem; } +.topic-card { display: block; border: 1px solid var(--desk-border); border-radius: .4rem; padding: 1rem; background: var(--desk-panel); } +.topic-card:hover { border-color: var(--desk-accent); } +.topic-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 1.3rem; } +.topic-icon { color: var(--desk-accent); } +.topic-index { font: .65rem ui-monospace, Consolas, monospace; color: var(--desk-muted); } +.topic-card h3 { font-size: .9rem; font-weight: 650; margin-bottom: .3rem; } +.topic-card p { font-size: .7rem; line-height: 1.7; color: var(--desk-muted); } +.recent-list { border-top: 1px solid var(--desk-border); } +.recent-entry { position: relative; display: grid; grid-template-columns: 7rem 1fr 1rem; gap: 1rem; padding: 1.6rem 0; border-bottom: 1px solid var(--desk-border); } +.entry-date { display: flex; flex-direction: column; color: var(--desk-muted); font: .7rem/1.9 ui-monospace, Consolas, monospace; } +.entry-date > span { font: .65rem/1.8 inherit; } +.entry-tags { display: flex; gap: .65rem; font-size: .65rem; color: var(--desk-accent); margin-bottom: .4rem; } +.recent-entry h3 { font-size: 1.12rem; font-weight: 650; line-height: 1.7; } +.recent-entry h3 a:hover { color: var(--desk-accent); } +.recent-entry p { margin: .4rem 0 0; color: var(--desk-muted); font-size: .8rem; line-height: 1.8; } +.entry-arrow { color: var(--desk-muted); align-self: center; } +.build-note { display: flex; justify-content: space-between; align-items: center; gap: 2rem; border: 1px dashed var(--desk-border); border-radius: .5rem; padding: 1.5rem; margin-bottom: 2rem; } +.build-note .eyebrow { margin-bottom: .5rem; } +.build-note h2 { font-size: 1.1rem; font-weight: 650; } +.build-note p:last-child { font-size: .8rem; line-height: 1.9; color: var(--desk-muted); margin-top: .5rem; } +.build-note > a { flex-shrink: 0; } +.article-content { line-height: 1.95; overflow-wrap: anywhere; } +.article-content p { text-wrap: pretty; } +.article-content pre { max-width: 100%; overflow-x: auto; line-height: 1.7; } +.article-content pre code { overflow-wrap: normal; word-break: normal; font: .875rem/1.7 ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", monospace; } +.article-content img { border-radius: .5rem; } +.article-content h2, .article-content h3, .article-content h4 { scroll-margin-top: 8rem; } +.article-content table { font-size: .9em; } +.search-result { display: block; padding: .85rem; margin: .4rem 0; border-radius: .3rem; background: var(--desk-panel); } +.search-result strong, .search-result > span { display: block; } +.search-result > span { color: var(--desk-muted); font-size: .8rem; line-height: 1.7; margin-top: .3rem; } +.search-result:hover, .search-result:focus-visible { background: rgba(var(--color-primary-300), .15); } +.reading-progress { position: fixed; top: 0; left: 0; width: 100%; height: 3px; border: 0; appearance: none; z-index: 110; background: transparent; color: var(--desk-accent); pointer-events: none; } +.reading-progress::-webkit-progress-bar { background: transparent; } +.reading-progress::-webkit-progress-value { background: var(--desk-accent); } +.reading-progress::-moz-progress-bar { background: var(--desk-accent); } +.projects-page > h1 { font-size: 2.5rem; line-height: 1.4; font-weight: 800; margin: 0 0 1rem; } +.project-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem; margin-top: 2rem; } +.project-card { border: 1px solid var(--desk-border); border-radius: .5rem; overflow: hidden; } +.project-card img { width: 100%; aspect-ratio: 16/9; object-fit: cover; } +.project-copy { padding: 1.5rem; } +.project-status { font-size: .7rem; color: var(--desk-accent); } +.project-copy h2 { font-size: 1.3rem; font-weight: 700; margin: .4rem 0; } +.project-copy p { font-size: .85rem; color: var(--desk-muted); line-height: 1.8; } +.stack-list { display: flex; flex-wrap: wrap; list-style: none; gap: .5rem; margin: 1rem 0; padding: 0; } +.stack-list li { font: .7rem/1.7 ui-monospace, Consolas, monospace; border: 1px solid var(--desk-border); border-radius: .2rem; padding: .1rem .4rem; } +.project-links { display: flex; justify-content: space-between; font-size: .8rem; } +#site-footer { border-top: 1px solid var(--desk-border); margin-top: 2rem; } +@media (max-width: 1023px) { .intro-grid { gap: 1.5rem; } .topic-grid { grid-template-columns: repeat(3, 1fr); } .project-grid { grid-template-columns: 1fr; } } +@media (max-width: 700px) { .intro-grid { grid-template-columns: 1fr; padding-bottom: 2.5rem; } .terminal-panel { transform: none; margin-top: 1rem; } .intro-copy h1 { font-size: 2.7rem; } .topic-grid { grid-template-columns: repeat(2, 1fr); } .topic-card:last-child { grid-column: 1 / -1; } .recent-entry { grid-template-columns: 1fr 1rem; gap: .4rem; } .entry-date { grid-column: 1 / -1; flex-direction: row; gap: 1rem; } .section-heading h2 { font-size: 1.2rem; } .build-note { flex-direction: column; align-items: flex-start; gap: 1rem; } .workbench { padding-top: 0; } } +@media (prefers-reduced-motion: reduce) { *, *::before, *::after { scroll-behavior: auto !important; animation-duration: .01ms !important; transition-duration: .01ms !important; } } +@media print { .reading-progress { display: none; } } diff --git a/assets/js/reading-progress.js b/assets/js/reading-progress.js new file mode 100644 index 0000000..16e6b2e --- /dev/null +++ b/assets/js/reading-progress.js @@ -0,0 +1,24 @@ +(() => { + const article = document.querySelector('.article-content'); + if (!article) return; + const progress = document.createElement('progress'); + progress.className = 'reading-progress'; + progress.max = 100; + progress.value = 0; + progress.setAttribute('aria-label', '文章阅读进度'); + document.body.append(progress); + let scheduled = false; + const update = () => { + const top = article.getBoundingClientRect().top + window.scrollY; + const distance = Math.max(1, article.offsetHeight - window.innerHeight + 160); + progress.value = Math.min(100, Math.max(0, (window.scrollY - top + 160) / distance * 100)); + scheduled = false; + }; + const schedule = () => { + if (!scheduled) { scheduled = true; requestAnimationFrame(update); } + }; + window.addEventListener('scroll', schedule, { passive: true }); + window.addEventListener('resize', schedule); + window.addEventListener('load', schedule); + update(); +})(); diff --git a/assets/js/search.js b/assets/js/search.js new file mode 100644 index 0000000..26ffbbf --- /dev/null +++ b/assets/js/search.js @@ -0,0 +1,90 @@ +/* Uses Blowfish's local Fuse index; creates text nodes instead of injecting HTML. */ +(() => { + const wrapper = document.getElementById('search-wrapper'); + const input = document.getElementById('search-query'); + const output = document.getElementById('search-results'); + const modal = document.getElementById('search-modal'); + if (!wrapper || !input || !output || !modal) return; + let indexPromise; + let previousFocus; + let visible = false; + let queryRevision = 0; + + const index = () => indexPromise ||= fetch(`${wrapper.dataset.url.replace(/\/?$/, '/')}index.json`) + .then(response => { if (!response.ok) throw new Error('Search index unavailable'); return response.json(); }) + .then(data => new Fuse(data, { ignoreLocation: true, threshold: .2, keys: ['title', 'summary', 'content', 'section'] })); + + const close = () => { + visible = false; + queryRevision++; + wrapper.style.visibility = 'hidden'; + document.body.style.overflow = ''; + input.value = ''; + output.replaceChildren(); + previousFocus?.focus(); + }; + const open = () => { + if (visible) return; + visible = true; + previousFocus = document.activeElement; + wrapper.style.visibility = 'visible'; + document.body.style.overflow = 'hidden'; + input.focus(); + index().catch(() => { indexPromise = null; }); + }; + ['search-button', 'search-button-mobile'].forEach(id => document.getElementById(id)?.addEventListener('click', open)); + document.getElementById('close-search-button').addEventListener('click', close); + wrapper.addEventListener('click', event => { if (event.target === wrapper) close(); }); + input.closest('form').addEventListener('submit', event => { + event.preventDefault(); + output.querySelector('a')?.focus(); + }); + input.addEventListener('input', async () => { + const revision = ++queryRevision; + const term = input.value.trim(); + output.replaceChildren(); + if (!term) return; + try { + const fuse = await index(); + if (revision !== queryRevision || !visible) return; + const results = fuse.search(term).slice(0, 12); + if (!results.length) { + const item = document.createElement('li'); + item.textContent = '没有找到匹配的文章。'; + output.append(item); + } + for (const { item } of results) { + const li = document.createElement('li'); + const link = document.createElement('a'); + const title = document.createElement('strong'); + const summary = document.createElement('span'); + const url = new URL(item.permalink, location.origin); + if (!['http:', 'https:'].includes(url.protocol)) continue; + link.href = url.pathname + url.search + url.hash; + link.className = 'search-result'; + title.textContent = item.title; + const plain = new DOMParser().parseFromString(item.summary || '', 'text/html').body.textContent; + summary.textContent = plain.slice(0, 130); + link.append(title, summary); + li.append(link); + output.append(li); + } + } catch { + output.textContent = '搜索暂时无法加载,请稍后重试。'; + indexPromise = null; + } + }); + document.addEventListener('keydown', event => { + if (event.key === '/' && !visible && !/input|textarea|select/i.test(document.activeElement.tagName) && !document.activeElement.isContentEditable) { + event.preventDefault(); open(); + } + if (!visible) return; + if (event.key === 'Escape') { event.preventDefault(); close(); } + const elements = [...modal.querySelectorAll('input, button, a[href]')]; + const current = elements.indexOf(document.activeElement); + if (event.key === 'Tab' && event.shiftKey && current === 0) { event.preventDefault(); elements.at(-1).focus(); } + else if (event.key === 'Tab' && !event.shiftKey && current === elements.length - 1) { event.preventDefault(); elements[0].focus(); } + if (event.key === 'ArrowDown') { event.preventDefault(); elements[Math.min(current + 1, elements.length - 1)]?.focus(); } + if (event.key === 'ArrowUp') { event.preventDefault(); elements[Math.max(0, current - 1)]?.focus(); } + }); +})(); diff --git a/config/_default/languages.zh-cn.toml b/config/_default/languages.zh-cn.toml index 2eb7d2a..9de14bc 100644 --- a/config/_default/languages.zh-cn.toml +++ b/config/_default/languages.zh-cn.toml @@ -1,27 +1,27 @@ disabled = false -languageCode = "en" -languageName = "English" +languageCode = "zh-CN" +languageName = "简体中文" weight = 1 title = "NizerossのBlog" [params] displayName = "简体中文" - isoCode = "cn" + isoCode = "zh-CN" rtl = false dateFormat = "2006 年 1 月 2 日" logo = "img/site_logo.png" # secondaryLogo = "img/secondary-logo.png" - description = "NIZEROSS's website" + description = "NIZEROSS 的数字花园:计算机学习、项目实践、阅读与思考。" copyright = '© 2025 - { year } Nizeross All Rights Reserved.' [params.author] name = "NIZEROSS" image = "img/avatar.png" - headline = "|" + headline = "学习、构建,然后记录。" bio = "千锤百炼" links = [ { bilibili = "https://space.bilibili.com/176505165" }, { email = "mailto:1578686349@qq.com" }, { zhihu = "https://www.zhihu.com/people/da-kong-mo-shu" }, { steam = "https://steamcommunity.com/id/nizeross/" }, - ] \ No newline at end of file + ] diff --git a/config/_default/menus.zh-cn.toml b/config/_default/menus.zh-cn.toml index 22f1319..ccaa3dd 100644 --- a/config/_default/menus.zh-cn.toml +++ b/config/_default/menus.zh-cn.toml @@ -22,12 +22,44 @@ pageRef = "posts" weight = 20 +[[main]] + name = "Projects" + pre = "code" + pageRef = "projects" + weight = 25 + [[main]] name = "Tags" pre = "tag" pageRef = "/tags" weight = 30 +[[main]] + name = "About" + pre = "circle-info" + pageRef = "about" + weight = 40 + +[[footer]] + name = "分类" + pageRef = "categories" + weight = 10 + +[[footer]] + name = "友情链接" + pageRef = "links" + weight = 20 + +[[footer]] + name = "写作约定" + pageRef = "writing" + weight = 30 + +[[footer]] + name = "RSS" + url = "/index.xml" + weight = 40 + #[[main]] # name = "Parent" diff --git a/config/_default/params.toml b/config/_default/params.toml index 688e627..b0b0d91 100644 --- a/config/_default/params.toml +++ b/config/_default/params.toml @@ -12,6 +12,7 @@ autoSwitchAppearance = true enableA11y = false enableSearch = true enableCodeCopy = true +disableImageZoom = false enableStructuredBreadcrumbs = false # enableStyledScrollbar = true # disable to use native scrollbar style (defaults to true) @@ -52,7 +53,7 @@ forgejoDefaultServer = "https://v11.next.forgejo.org" showScrollToTop = true [homepage] - layout = "background" # valid options: page, profile, hero, card, background, custom + layout = "custom" # site-owned home/custom.html homepageImage = "image.jpg" # used in: hero, and card showRecent = true showRecentItems = 3 @@ -65,7 +66,7 @@ forgejoDefaultServer = "https://v11.next.forgejo.org" [article] showDate = true - showViews = true + showViews = false showLikes = false showDasteOnlyInArticle = false showDateUpdated = false @@ -86,9 +87,9 @@ forgejoDefaultServer = "https://v11.next.forgejo.org" invertPagination = false showReadingTime = true showTableOfContents = true - # showRelatedContent = false - # relatedContentLimit = 3 - showTaxonomies = false # use showTaxonomies OR showCategoryOnly, not both + showRelatedContent = true + relatedContentLimit = 3 + showTaxonomies = true # use showTaxonomies OR showCategoryOnly, not both showCategoryOnly = false # use showTaxonomies OR showCategoryOnly, not both showAuthorsBadges = false showWordCount = true @@ -138,13 +139,7 @@ forgejoDefaultServer = "https://v11.next.forgejo.org" cardViewScreenWidth = false [firebase] - # apiKey = "AIzaSyDlMaHFta2wQE_de28aIka_LMI28PJUBV4" - # authDomain = "blog-blowfish-cfaee.firebaseapp.com" - # projectId = "blog-blowfish-cfaee" - # storageBucket = "blog-blowfish-cfaee.firebasestorage.app" - # messagingSenderId = "587286702711" - # appId = "1:587286702711:web:327f6d58bd48f0dcc4b472" - # measurementId = "G-V7RW6NWLKM" + # Optional integration deliberately left unconfigured. [fathomAnalytics] # site = "ABC12345" diff --git a/content/about/index.md b/content/about/index.md new file mode 100644 index 0000000..2b13577 --- /dev/null +++ b/content/about/index.md @@ -0,0 +1,32 @@ ++++ +title = "关于这个角落" +description = "一名计算机专业学生的学习、构建与记录。" +showHero = false +showAuthor = false +showDate = false +showReadingTime = false +showWordCount = false ++++ + +你好,我是 **NIZEROSS**,一名计算机专业的大二学生。 + +这个网站是我的数字花园:有已经想明白的技术笔记,也有仍在生长的问题。希望记录的不只是“怎么做”,还有“为什么这样做”。 + +## 我在关注 + +- **技术学习**:理解计算机与软件背后的原理。 +- **项目开发**:从真实问题出发,做能持续使用的小工具。 +- **读书笔记**:记录哲学与其他阅读中的问题、论证和联想。 +- **思想随笔与生活**:保留学习之外的观察。 + +## 关于本站 + +本站使用 Hugo 和 Blowfish 构建,采用静态发布。文章中的推断和未验证结论应当明确标注,技术内容也可能随着学习而修订。 + +你可以通过 [RSS](/index.xml) 订阅更新,或在 [GitHub](https://github.com/Nizeross/nizeross.github.io) 查看这个网站的实现。 + +## 找到我 + +- [Bilibili](https://space.bilibili.com/176505165) +- [知乎](https://www.zhihu.com/people/da-kong-mo-shu) +- [邮件联系](mailto:1578686349@qq.com) diff --git "a/content/categories/\346\200\235\346\203\263\351\232\217\347\254\224/_index.md" "b/content/categories/\346\200\235\346\203\263\351\232\217\347\254\224/_index.md" new file mode 100644 index 0000000..35c0d40 --- /dev/null +++ "b/content/categories/\346\200\235\346\203\263\351\232\217\347\254\224/_index.md" @@ -0,0 +1,4 @@ ++++ +title = "思想随笔" +description = "一些尚在生长的想法。" ++++ diff --git "a/content/categories/\346\212\200\346\234\257\345\255\246\344\271\240/_index.md" "b/content/categories/\346\212\200\346\234\257\345\255\246\344\271\240/_index.md" new file mode 100644 index 0000000..cc64258 --- /dev/null +++ "b/content/categories/\346\212\200\346\234\257\345\255\246\344\271\240/_index.md" @@ -0,0 +1,4 @@ ++++ +title = "技术学习" +description = "理解计算机原理,记录可复现的学习过程。" ++++ diff --git "a/content/categories/\347\224\237\346\264\273\350\256\260\345\275\225/_index.md" "b/content/categories/\347\224\237\346\264\273\350\256\260\345\275\225/_index.md" new file mode 100644 index 0000000..790db41 --- /dev/null +++ "b/content/categories/\347\224\237\346\264\273\350\256\260\345\275\225/_index.md" @@ -0,0 +1,4 @@ ++++ +title = "生活记录" +description = "收集日常的细节。" ++++ diff --git "a/content/categories/\350\257\273\344\271\246\347\254\224\350\256\260/_index.md" "b/content/categories/\350\257\273\344\271\246\347\254\224\350\256\260/_index.md" new file mode 100644 index 0000000..9e88522 --- /dev/null +++ "b/content/categories/\350\257\273\344\271\246\347\254\224\350\256\260/_index.md" @@ -0,0 +1,4 @@ ++++ +title = "读书笔记" +description = "区分原文、理解与疑问,让阅读留下痕迹。" ++++ diff --git "a/content/categories/\351\241\271\347\233\256\345\274\200\345\217\221/_index.md" "b/content/categories/\351\241\271\347\233\256\345\274\200\345\217\221/_index.md" new file mode 100644 index 0000000..8fa58a2 --- /dev/null +++ "b/content/categories/\351\241\271\347\233\256\345\274\200\345\217\221/_index.md" @@ -0,0 +1,4 @@ ++++ +title = "项目开发" +description = "从问题到实现,也记录过程中的取舍。" ++++ diff --git a/content/links/index.md b/content/links/index.md new file mode 100644 index 0000000..126b407 --- /dev/null +++ b/content/links/index.md @@ -0,0 +1,17 @@ ++++ +title = "友情链接与常去的地方" +description = "值得持续阅读的工具文档与交流入口。" +showHero = false +showAuthor = false +showDate = false ++++ + +## 常去的地方 + +- [Hugo 文档](https://gohugo.io/documentation/):静态站点与内容组织的参考手册。 +- [Blowfish 文档](https://blowfish.page/zh-cn/docs/):本站主题的配置、模板与写作组件。 +- [GitHub Skills](https://skills.github.com/):通过练习理解 GitHub 协作。 + +## 朋友的站点 + +这个列表等待慢慢生长。欢迎通过[邮件](mailto:1578686349@qq.com)介绍你的个人网站;我会在阅读后手动添加。 diff --git a/content/posts/how-build-blog/index.md b/content/posts/how-build-blog/index.md index ba6b4e6..c0e24de 100644 --- a/content/posts/how-build-blog/index.md +++ b/content/posts/how-build-blog/index.md @@ -2,19 +2,28 @@ date = '2026-03-31T17:01:46+08:00' draft = false tags = ["Hugo", "Blowfish"] +categories = ["技术学习"] +contentType = "technical" +summary = "记录使用 Hugo 与 Blowfish 搭建博客时的目录组织、主题覆盖与 GitHub Pages 部署实践。" title = '记录一下折腾blog的经历' +++ ## 前言 + 搭建本博客参考了Gemini 3.0 Pro,Blowfish官方文档以及其他人的博客,还是踩了不少坑的,有的文档已经过时或者操作过于繁琐,官方文档又很庞杂,AI也有一定幻觉. - - [hugo官方文档](https://gohugo.io/documentation/) - - [Blowfish文档](https://blowfish.page/zh-cn/docs/) - - [褐瞳さん - 如何使用 Github Page 搭建自己的博客](https://www.hetong-re4per.com/posts/how-bulid-blog-on-github-page/) + +- [hugo官方文档](https://gohugo.io/documentation/) +- [Blowfish文档](https://blowfish.page/zh-cn/docs/) +- [褐瞳さん - 如何使用 Github Page 搭建自己的博客](https://www.hetong-re4per.com/posts/how-bulid-blog-on-github-page/) + ## Step + ### 创建项目 + 首先创建一个 Hugo 项目,site-name 记得替换成你的网站的名称(其实就是待会创建的文件夹名称)`hugo new site site-name` 可以看一眼它的项目结构,项目结构大概像这样: -``` + +```text site-name ├── archetypes # 模板文件 ├── assets # 资源文件,如 Logo @@ -26,15 +35,19 @@ site-name ├── themes # 主题文件夹 └── hugo.toml # 项目配置文件 ``` + 然后可以添加第一篇文章 -``` + +```text hugo new content posts/first-blog.md ``` + 这条命令会向 content 文件夹内新建一个 posts 文件夹,然后再根据默认模板创建一个 first-blog.md 文件 然后使用`hugo server` 即可在本地运行 ### 覆盖主题 + 在 Hugo 中,你自己所写的主题文件优先级都是高于 `themes/主题名称/` 文件夹内主题的,所以可以很轻松的覆写你想 DIY 的部分 对于 themes 文件夹内的文件,你只需要保证在根目录有着同样文件结构就能够覆盖 @@ -42,12 +55,13 @@ hugo new content posts/first-blog.md 例如目录部分,对于 blowfish 它的位置是 `themes/blowfish/layouts/partials/toc.html`,而我们只需要复制这个文件,并把它放在 layouts/partials/toc.html 即可 ### 部署到Github Pages -* **本地预览**:`hugo server` -* **部署发布**:`git add .` -> `git commit -m "..."` -> `git push` -* **在线编辑**:在 GitHub 仓库按 `.` 进入 Web 编辑器。 + +- **本地预览**:`hugo server` +- **部署发布**:`git add .` -> `git commit -m "..."` -> `git push` +- **在线编辑**:在 GitHub 仓库按 `.` 进入 Web 编辑器。 ## Tips -### 自定义图标添加 -- [simpleicon](https://simpleicons.org/) +### 自定义图标添加 +- [simpleicon](https://simpleicons.org/) diff --git a/content/posts/my-first-post/index.md b/content/posts/my-first-post/index.md index cdbde30..977c29a 100644 --- a/content/posts/my-first-post/index.md +++ b/content/posts/my-first-post/index.md @@ -3,26 +3,33 @@ date = '2026-02-01T18:46:57+08:00' draft = false title = 'My First Post' tags = ["生活", "编程"] -categories = ["随笔"] +categories = ["随笔", "生活记录"] +contentType = "life" +summary = "博客的第一篇记录,以及 Markdown、代码块与提示组件的尝试。" +++ 这里是摘要部分。写在这里的文字会显示在博客首页的卡片上。 ## 一、这是二级标题 + 这是正文段落。你可以在这里写下你的想法。**这是加粗的文字**,*这是斜体*。 ### 1.1 这是三级标题 + 如果你想列出清单: + * 第一点 * 第二点 * 子要点 ## 二、插入代码 + 作为计算机学生,你肯定要贴代码。Hugo 的代码高亮非常漂亮: ```python def hello_world(): print("Hello Blowfish!") +``` {{< alert icon="lightbulb" >}} 这是一个提示! 可以在这里写一些 Tips。 {{< /alert >}} -{{< alert icon="triangle-exclamation" cardColor="#e63946" iconColor="#1d3557" >}} 这是一个警告! 这里的颜色是可以自定义的。 {{< /alert >}} \ No newline at end of file +{{< alert icon="triangle-exclamation" cardColor="#e63946" iconColor="#1d3557" >}} 这是一个警告! 这里的颜色是可以自定义的。 {{< /alert >}} diff --git a/content/posts/pcl2-memory-optimization/index.md b/content/posts/pcl2-memory-optimization/index.md index 61bc4e3..fadc4d9 100644 --- a/content/posts/pcl2-memory-optimization/index.md +++ b/content/posts/pcl2-memory-optimization/index.md @@ -3,9 +3,12 @@ date = '2026-09-07T12:00:00+08:00' draft = false title = 'PCL2百宝箱内存优化功能分析' tags = ["内存优化"] -categories = ["随笔"] +categories = ["随笔", "技术学习"] +contentType = "technical" +summary = "基于公开信息与技术推断分析 PCL2 内存优化:工作集缩减机制、局限与其他方式的比较。" +++ # PCL2 百宝箱 — 内存优化功能实现分析 + 本文借助了Claude Opus4.6 ## 概述 @@ -15,7 +18,7 @@ PCL2(Plain Craft Launcher 2)百宝箱中的**内存优化**功能本质上 > [!NOTE] > PCL2 官方开源仓库中,百宝箱相关代码被故意隐去,源码中仅有占位提示: > `Hint("为便于维护,开源内容中不包含百宝箱功能……")` -> +> > 以下分析基于社区版 (PCL2-CE) 的公开讨论、GitHub Issues,以及对技术原理的逆向推断。 --- @@ -55,6 +58,7 @@ End Sub ``` **关键步骤**: + 1. **枚举进程** — 通过 `Process.GetProcesses()` 获取所有运行中的进程 2. **逐一清理** — 对每个进程调用 `EmptyWorkingSet(proc.Handle)` 3. **异常处理** — 对于系统关键进程(权限不足无法操作的),捕获异常并跳过 @@ -64,7 +68,7 @@ End Sub PCL2 还支持通过启动参数 `--memory` 以静默方式执行内存优化: -``` +```text PCL.exe --memory ``` @@ -92,6 +96,7 @@ flowchart TD ## 效果与局限性 ### ✅ 能做到什么 + | 效果 | 说明 | |------|------| | 降低物理内存占用 | 任务管理器中显示的内存使用量会立即下降(通常可降低约 1/3) | diff --git a/content/projects/_index.md b/content/projects/_index.md new file mode 100644 index 0000000..53ff57c --- /dev/null +++ b/content/projects/_index.md @@ -0,0 +1,7 @@ ++++ +title = "项目实验室" +description = "把问题变成项目,记录每一次构建与迭代。" +showHero = false ++++ + +这里存放自己动手做过的项目。不只展示结果,也记录取舍、踩坑和下一步。 diff --git a/content/projects/personal-blog/index.md b/content/projects/personal-blog/index.md new file mode 100644 index 0000000..dcd2439 --- /dev/null +++ b/content/projects/personal-blog/index.md @@ -0,0 +1,48 @@ ++++ +title = "个人博客与自动化发布系统" +date = 2026-10-29T12:00:00+08:00 +draft = false +description = "用 Hugo 与 Blowfish 搭建一个适合长期写作的数字花园,并实践内容检查、测试与审核发布。" +summary = "一个持续维护的工程练习:把写作、静态站点构建和自动化检查连接起来。" +stack = ["Hugo", "Blowfish", "Python", "GitHub Actions"] +github = "https://github.com/Nizeross/nizeross.github.io" +status = "持续维护" +weight = 1 +tags = ["Hugo", "Blowfish", "工程实践"] +categories = ["项目开发"] +showHero = false ++++ + +## 为什么做这个项目 + +把日常技术笔记、读书记录与个人随笔放在自己能长期维护的地方,同时通过真实项目学习 Git、HTTP、测试和自动化发布。 + +## 项目一览 + +![博客的构建与审核发布流程示意](screenshot.svg) + +## 技术栈与取舍 + +Hugo 将 Markdown 在构建时转成静态 HTML,Blowfish 提供搜索、目录、图片处理和明暗主题。少量原生 CSS 与 JavaScript 负责首页和阅读进度,避免把日常写作绑定到复杂应用框架。 + +## 开发过程 + +1. 审计现有文章路径、主题子模块、域名与部署流程。 +2. 在独立本地分支开发界面与内容工具,保留已有文章 URL。 +3. 加入 Frontmatter、Markdown、本地链接与浏览器检查。 +4. 准备需要人工审核的发布流程,确认后才接入线上站点。 + +## 学到的知识 + +- 静态资源可以在构建时完成处理,无需运行数据库服务。 +- CI 负责验证变更,CD 负责交付已经通过验证的产物。 +- 草稿开关不等于审核;审核需要分支保护与部署权限共同约束。 +- 设计系统应通过主题变量扩展,减少对上游模板的依赖。 + +## 后续改进 + +- 在审核后启用新的生产发布流程。 +- 随文章积累改善分类与关联推荐。 +- 定期复核工具链和主题内置脚本的安全更新。 + +源码与问题记录:[GitHub 仓库](https://github.com/Nizeross/nizeross.github.io)。 diff --git a/content/projects/personal-blog/screenshot.svg b/content/projects/personal-blog/screenshot.svg new file mode 100644 index 0000000..b7ae679 --- /dev/null +++ b/content/projects/personal-blog/screenshot.svg @@ -0,0 +1,9 @@ + +博客自动化工作流示意Markdown 内容经过检查和构建,再经人工审核发布到 GitHub Pages。 + +~/nizeross/blog-system +WRITE. BUILD. LEARN.A small system for long-term thinking. + +MarkdownCheck + BuildReviewPages + +Hugo / Blowfish / Python / GitHub Actions diff --git a/content/writing/index.md b/content/writing/index.md new file mode 100644 index 0000000..203a6ee --- /dev/null +++ b/content/writing/index.md @@ -0,0 +1,44 @@ ++++ +title = "写作约定与排版示例" +description = "这个数字花园的内容约定、Markdown 与数学公式示例。" +showHero = false +showAuthor = false +showDate = false ++++ + +{{< katex >}} + +## 先写清楚问题 + +技术笔记交代环境、步骤和验证方法;读书笔记区分原文、转述和自己的理解;推断与结论尽量附上依据。 + +## 代码 + +为围栏标记语言,方便高亮与复制: + +```python +def learn_by_building(question: str) -> str: + return f"提出问题 → 动手验证 → 记录:{question}" +``` + +## 数学公式 + +在文章中加入 `{{}}`,随后可以使用行内公式 \(O(n \log n)\) 和独立公式: + +$$ +\sum_{i=1}^{n} i = \frac{n(n+1)}{2} +$$ + +## 图片 + +图片放在文章自己的目录,与 `index.md` 同级,再以相对路径引用。点击下面的图片可以放大。 + +![站点标志](logo.png) + +## 链接与锚点 + +站内路径使用根相对链接,例如[关于页面](/about/);同页链接可以跳转到[代码](#代码)。发布前检查会验证本地文件和生成页面的锚点。 + +## 内容维护 + +小修改保留原 slug,实质更新补充 `lastmod`。文章默认创建为草稿,检查通过后再提交审核。 diff --git a/content/writing/logo.png b/content/writing/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..d0c878bc4bbc2fde2db85b1ec838533f2d804037 GIT binary patch literal 416 zcmeAS@N?(olHy`uVBq!ia0vp^DImf%L+Zr3EvHvJ>{_5Eteo4B6oq{TE6C@mykQh7V{vP=F`%aD6=6`pOP260Q^+*49`oBoNxi{O6a0n@T z^e7lMVPzPnnTvmyai9O}9;qCX>9NgyOu@Xt@ v%$M8m<13s0a;MMRNWfB=e;*~k;a8;plT~x?PWP>#AZPG&^>bP0l+XkKoH3aI literal 0 HcmV?d00001 diff --git a/layouts/partials/extend-footer.html b/layouts/partials/extend-footer.html new file mode 100644 index 0000000..79f32ff --- /dev/null +++ b/layouts/partials/extend-footer.html @@ -0,0 +1,2 @@ +{{ $reading := resources.Get "js/reading-progress.js" | resources.Minify | resources.Fingerprint "sha512" }} + diff --git a/layouts/partials/footer.html b/layouts/partials/footer.html index 859cbf3..752e86b 100644 --- a/layouts/partials/footer.html +++ b/layouts/partials/footer.html @@ -79,31 +79,4 @@ {{ if templates.Exists "partials/extend-footer.html" }} {{ partialCached "extend-footer.html" . }} {{ end }} -
- - - -
- diff --git a/layouts/partials/home/custom.html b/layouts/partials/home/custom.html new file mode 100644 index 0000000..54cf775 --- /dev/null +++ b/layouts/partials/home/custom.html @@ -0,0 +1,47 @@ +
+
+
+

NIZEROSS / PERSONAL WORKSPACE

+

保持好奇,
把想法写成现实。

+

我是 NIZEROSS,一名计算机专业学生。在这里记录学习、构建与思考,也给尚未想明白的问题留一点空间。

+ +

计算机 · 开源实践 · 阅读与生活

+
+ +
+ +
+

EXPLORE THE GARDEN

沿着兴趣,慢慢探索

全部分类
+
+ {{ range slice (dict "name" "技术学习" "icon" "code" "note" "理解原理,也动手验证" "index" "01") (dict "name" "项目开发" "icon" "codeberg" "note" "让知识成为可用的东西" "index" "02") (dict "name" "读书笔记" "icon" "file-lines" "note" "与书本展开一场对话" "index" "03") (dict "name" "思想随笔" "icon" "lightbulb" "note" "留住尚在生长的想法" "index" "04") (dict "name" "生活记录" "icon" "mug-hot" "note" "收集日常的细节" "index" "05") }} + {{ $term := site.GetPage (printf "/categories/%s" .name) }} + {{ partial "icon.html" .icon }}{{ .index }}

{{ .name }}

{{ .note }}

+ {{ end }} +
+
+ +
+

RECENT CHANGES

最近的记录

所有文章
+
+ {{ range first 5 (where site.RegularPages "Section" "posts").ByLastmod.Reverse }} +

{{ .Title }}

{{ .Summary | plainify | truncate 105 }}

+ {{ end }} +
+
+ +

BUILD IN PUBLIC

从使用工具,到理解工具。

这个网站也是我的工程练习场:用简单的技术,认真解决写作、阅读和发布的问题。

打开项目日志
+
diff --git a/layouts/partials/search.html b/layouts/partials/search.html new file mode 100644 index 0000000..7a0c485 --- /dev/null +++ b/layouts/partials/search.html @@ -0,0 +1,13 @@ + diff --git a/layouts/partials/toc.html b/layouts/partials/toc.html new file mode 100644 index 0000000..fabaa71 --- /dev/null +++ b/layouts/partials/toc.html @@ -0,0 +1,6 @@ +
+ {{ i18n "article.table_of_contents" }} +
+ {{ .TableOfContents | replaceRE `id="TableOfContents"` `id="TableOfContents" aria-label="文章目录"` | safeHTML }} +
+
diff --git a/layouts/projects/list.html b/layouts/projects/list.html new file mode 100644 index 0000000..76cfef1 --- /dev/null +++ b/layouts/projects/list.html @@ -0,0 +1,16 @@ +{{ define "main" }} +
+

SMALL TOOLS, REAL QUESTIONS

+

{{ .Title }}

+
{{ .Content }}
+
+ {{ range .Pages.ByWeight }} +
+ {{ $page := . }} + {{ with .Resources.GetMatch "screenshot*" }}{{ end }} +
{{ .Params.status | default "持续维护" }}

{{ .Title }}

{{ .Description }}

    {{ range .Params.stack }}
  • {{ . }}
  • {{ end }}
+
+ {{ end }} +
+
+{{ end }} From 99c875217f3e5d423d3e079651c983a9c9d8dd6a Mon Sep 17 00:00:00 2001 From: Nizeross Date: Thu, 29 Oct 2026 23:23:22 +0800 Subject: [PATCH 4/7] ci: validate content and prepare reviewed release workflow --- .github/workflow-proposals/pages.yml | 64 ++ .github/workflows/quality.yml | 82 ++ .gitignore | 2 + .markdownlint-cli2.jsonc | 14 + package-lock.json | 1495 ++++++++++++++++++++++++++ package.json | 23 + playwright.config.js | 21 + scripts/check_content.py | 108 ++ scripts/check_external.py | 34 + scripts/check_site.py | 84 ++ scripts/install_browser.cjs | 7 + scripts/review_gate.py | 49 + scripts/security_check.py | 37 + scripts/serve.cjs | 20 + scripts/site.py | 4 +- scripts/suggest.py | 49 + scripts/sync_vendor.py | 14 + tests/e2e/blog.spec.js | 82 ++ tests/test_content.py | 127 +++ tests/test_release_gate.py | 47 + 20 files changed, 2362 insertions(+), 1 deletion(-) create mode 100644 .github/workflow-proposals/pages.yml create mode 100644 .github/workflows/quality.yml create mode 100644 .markdownlint-cli2.jsonc create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 playwright.config.js create mode 100644 scripts/check_content.py create mode 100644 scripts/check_external.py create mode 100644 scripts/check_site.py create mode 100644 scripts/install_browser.cjs create mode 100644 scripts/review_gate.py create mode 100644 scripts/security_check.py create mode 100644 scripts/serve.cjs create mode 100644 scripts/suggest.py create mode 100644 scripts/sync_vendor.py create mode 100644 tests/e2e/blog.spec.js create mode 100644 tests/test_content.py create mode 100644 tests/test_release_gate.py diff --git a/.github/workflow-proposals/pages.yml b/.github/workflow-proposals/pages.yml new file mode 100644 index 0000000..9655fda --- /dev/null +++ b/.github/workflow-proposals/pages.yml @@ -0,0 +1,64 @@ +# INACTIVE PROPOSAL. Requires approval before replacing workflows/hugo.yaml. +# Required external settings: main PR protection + required checks + github-pages reviewers. +name: Reviewed Pages release + +on: + push: + branches: [main] + +permissions: + contents: read + +concurrency: + group: pages + cancel-in-progress: false + +jobs: + review-gate: + runs-on: ubuntu-24.04 + permissions: + contents: read + pull-requests: read + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + with: + persist-credentials: false + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 + with: + python-version: '3.11' + - name: Require reviewed PR for this exact commit + env: + GITHUB_TOKEN: ${{ github.token }} + run: python scripts/review_gate.py + validate: + needs: review-gate + uses: ./.github/workflows/quality.yml + permissions: + contents: read + package: + needs: validate + runs-on: ubuntu-24.04 + permissions: + contents: read + actions: read + steps: + - name: Download tested artifact + env: + GH_TOKEN: ${{ github.token }} + run: gh run download "$GITHUB_RUN_ID" --repo "$GITHUB_REPOSITORY" --name verified-site --dir site + - uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4 + with: + path: site + deploy: + needs: package + runs-on: ubuntu-24.04 + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Publish tested artifact after environment approval + id: deployment + uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4 diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml new file mode 100644 index 0000000..6d62dfa --- /dev/null +++ b/.github/workflows/quality.yml @@ -0,0 +1,82 @@ +name: Blog quality + +on: + pull_request: + push: + branches-ignore: [main] + workflow_dispatch: + workflow_call: + +permissions: + contents: read + +concurrency: + group: quality-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + verify: + name: Verify content and site + runs-on: ubuntu-24.04 + timeout-minutes: 20 + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + with: + submodules: recursive + persist-credentials: false + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 + with: + node-version: '24' + cache: npm + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 + with: + python-version: '3.11' + - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + with: + path: .cache/hugo + key: hugo-${{ runner.os }}-${{ hashFiles('toolchain.json') }}-${{ github.sha }} + restore-keys: hugo-${{ runner.os }}-${{ hashFiles('toolchain.json') }}- + - name: Install locked dependencies + run: npm ci --ignore-scripts + - name: Install verified Hugo and audited math assets + run: | + python scripts/install_hugo.py + python scripts/sync_vendor.py + - name: Content and Markdown checks + run: | + python scripts/site.py check + npm run lint + - name: Unit tests + run: python -m unittest discover -s tests -v + - name: Dependency and source security + run: | + npm audit --audit-level=low + python scripts/security_check.py + - name: Build and check every local reference + run: | + python scripts/site.py build + python scripts/check_site.py + - name: Install browser + run: npm run browsers -- --with-deps + - name: Browser and accessibility tests + run: npm run test:e2e + - name: Preserve diagnostic reports + if: always() + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: quality-reports + path: | + reports/ + playwright-report/ + test-results/ + retention-days: 7 + if-no-files-found: ignore + - name: Preserve tested site + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: verified-site + path: .build/site/ + retention-days: 3 + - name: Summarize failures + if: failure() + run: echo 'Validation failed. Open the first failing step and download quality-reports. Production deployment was not started.' >> "$GITHUB_STEP_SUMMARY" diff --git a/.gitignore b/.gitignore index 03366ec..af39649 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ /.tools/ /.build/ /.cache/ +/assets/lib/katex/ +/resources/_gen/ /node_modules/ /test-results/ /playwright-report/ diff --git a/.markdownlint-cli2.jsonc b/.markdownlint-cli2.jsonc new file mode 100644 index 0000000..53a9e21 --- /dev/null +++ b/.markdownlint-cli2.jsonc @@ -0,0 +1,14 @@ +{ + "globs": ["content/**/*.md", "*.md"], + "config": { + "default": true, + "MD013": false, + "MD024": { "siblings_only": true }, + "MD025": false, + "MD029": false, + "MD033": false, + "MD041": false, + "MD046": { "style": "fenced" }, + "MD060": false + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..f5e86a9 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1495 @@ +{ + "name": "nizeross-blog-quality", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "nizeross-blog-quality", + "version": "1.0.0", + "devDependencies": { + "@axe-core/playwright": "4.14.0", + "@playwright/test": "1.64.1", + "katex": "0.19.1", + "markdownlint-cli2": "0.24.0" + }, + "engines": { + "node": ">=24 <25" + } + }, + "node_modules/@axe-core/playwright": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@axe-core/playwright/-/playwright-4.14.0.tgz", + "integrity": "sha512-SGUhG5PIHd2eMdpgBF2PyQLOhX+qyDR2PT4cmoS4Qk2ak+jX/rrSvst9l0PGv5WTHolKpUMvVmoHpr4cZgf1RQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "axe-core": "~4.14.0" + }, + "engines": { + "node": ">=22.12.0" + }, + "peerDependencies": { + "playwright-core": ">= 1.0.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@playwright/test": { + "version": "1.64.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.64.1.tgz", + "integrity": "sha512-IaYGml/nSOiZWROfPtuIL7neuu9qDOZ3TNvNljUIrhDMxiGTgPjzj/g9p9RxpS2tSepPDRY+UwAaEeiKtUvIAg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.64.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@types/debug": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/katex": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.8.tgz", + "integrity": "sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ansi-regex": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.5.0.tgz", + "integrity": "sha512-zhvbbbdt1kbw7EJ9OQoxmQcuaNR9P5kTj7e/YdmOSU10aHWbycofJxA6jKfoEy3vlLdctOF9ZHaxLtmSm998wQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/axe-core": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.14.0.tgz", + "integrity": "sha512-9WTZxEjsZ7b13TH8JPmbV2z8CHbl80/2hm3XPEG4JgNdQLK81IBRXmSxHfMAOkSqQeRxT/0dwNDz2GOm3zzpcQ==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-15.0.0.tgz", + "integrity": "sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=22.12.0" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/entities": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-8.1.0.tgz", + "integrity": "sha512-kxL7msIffSuh9aaFAMD7rxAIuTRMAHMeBtgHW2yUdWw732ZNh4MehkF2gdjvtdmikkaIP9bFDDJOPlsvm7avrA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.3.tgz", + "integrity": "sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.7.0.tgz", + "integrity": "sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "16.2.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-16.2.4.tgz", + "integrity": "sha512-c8B/VNLmxRcmqqenRA9t+9IyOjf9+V6lTxPaUJLqOCONdQkWZ0ETYgX0qbtJqPsgCNusT9MZ5Jeidw8Eb9tn2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^4.0.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.5", + "is-path-inside": "^4.0.0", + "micromatch": "^4.0.8", + "slash": "^5.1.0", + "unicorn-magic": "^0.4.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ignore": { + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.14.tgz", + "integrity": "sha512-wCBiZ77u1tuWde6G/nfOtLaCTYcFDU5yCzARzK10y+rLhzYoL7a7yEemcopcc2Mzow7gZOIjnV2ym1NYmdiJOQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz", + "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/js-yaml": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.4.3.tgz", + "integrity": "sha512-yzzNtgczwgoVHNigCyKTXcQJU4Y8t/ikU4UxXW0BvrLfHTGWZhsNcOT2s/a7vn81/4KqVnNmHjaUEPlvWnNwVw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.mjs" + } + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/katex": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.19.1.tgz", + "integrity": "sha512-jG8uKntjSEcm2EpQOh0XturpPuuC9r3Sq5HLHdsFdWZT27E672SF19QEi+of0/YeOy15lDgRhKvr5614uRrEfA==", + "dev": true, + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^15.0.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/linkify-it": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-6.1.0.tgz", + "integrity": "sha512-wJ/TwpSDTLepCrQoYWYIExIKg5Zchex2Nn5yk2mFnB+6PtdkHtyLx742md9csRjjOnGkKIS/RrbY7l8D6gT9Vw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/markdown-it" + } + ], + "license": "MIT", + "dependencies": { + "uc.micro": "^3.0.0" + } + }, + "node_modules/markdown-it": { + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-15.0.3.tgz", + "integrity": "sha512-+Az7Ojz3iRGu8KYMvJ6xVhvrxP3eE+vEtJX75Ow88XBpcQNV/0lGX5ZynIIBftREo4DC2jsveAMDaeltmm8QvQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/markdown-it" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^3.0.3", + "entities": "^8.1.0", + "linkify-it": "^6.1.0", + "mdurl": "^2.1.0", + "punycode.js": "^2.3.1", + "uc.micro": "^3.0.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdown-it/node_modules/argparse": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-3.0.4.tgz", + "integrity": "sha512-fwWK3Zq22l4XJJjx5mcBHGikIk+hJqO+32dPm0Jur7+rtG5x1scOjSfdT9ZKeWHPpsya/l0HHK4tDImBkTrtvA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "PSF-2.0" + }, + "node_modules/markdownlint": { + "version": "0.42.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.42.0.tgz", + "integrity": "sha512-kzsCV/rPWRFn3jUhcB919YF4Qgeh0g9tcogoXFadGSo6Zxj6662YOqWXv0jDn8nv5KCCxDfMKJZv6N4HkNkvTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark": "4.0.3", + "micromark-core-commonmark": "2.0.4", + "micromark-extension-directive": "4.0.0", + "micromark-extension-gfm-autolink-literal": "2.1.0", + "micromark-extension-gfm-footnote": "2.1.0", + "micromark-extension-gfm-table": "2.1.2", + "micromark-extension-math": "3.1.0", + "micromark-util-types": "2.0.3", + "re2js": "2.8.6", + "string-width": "8.3.0" + }, + "engines": { + "node": ">=22" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, + "node_modules/markdownlint-cli2": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.24.0.tgz", + "integrity": "sha512-c5hU2MDoTlS230MLzdNlkIyxImXq5acxGKz4nYz4aDhH/2BgFtpsA7iK9/OoTHMgZ4FuR0wedTQA31K6Lp9I/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "globby": "16.2.4", + "js-yaml": "5.4.3", + "jsonc-parser": "3.3.1", + "jsonpointer": "5.0.1", + "markdown-it": "15.0.3", + "markdownlint": "0.42.0", + "markdownlint-cli2-formatter-default": "0.0.6", + "micromatch": "4.0.8", + "smol-toml": "1.9.1" + }, + "bin": { + "markdownlint-cli2": "markdownlint-cli2-bin.mjs" + }, + "engines": { + "node": ">=22" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, + "node_modules/markdownlint-cli2-formatter-default": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/markdownlint-cli2-formatter-default/-/markdownlint-cli2-formatter-default-0.0.6.tgz", + "integrity": "sha512-VVDGKsq9sgzu378swJ0fcHfSicUnMxnL8gnLm/Q4J/xsNJ4e5bA6lvAz7PCzIl0/No0lHyaWdqVD2jotxOSFMQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + }, + "peerDependencies": { + "markdownlint-cli2": ">=0.0.4" + } + }, + "node_modules/mdurl": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.1.0.tgz", + "integrity": "sha512-1+HBaOx0zi/dQWht8rNv9MYf9qqpqL/kxI0hXImU6Y547zM6Sni8BQibt7ifgMcYtQg41ao3Ivd6cnSM86inpg==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromark": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.3.tgz", + "integrity": "sha512-oGYfQzHSG5dOMovQcJ3fyTmZlWAWpi0XA0sJwJs+i6OT88o1+Jtw/8z0CmdowSLxGhhFK89rQ/oXph/wN02PNw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-edit-map": "^1.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.4.tgz", + "integrity": "sha512-wxEeE8v8XVvOrxn1TZj74qYhAtTQsSqufHVS3uNVyT1MupXxhyaHk8/9xDNPh9BmL77QNDgWTkZ3RsYHB2ry7w==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.1.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-edit-map": "^1.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.3" + } + }, + "node_modules/micromark-extension-directive": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-4.0.0.tgz", + "integrity": "sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.2.tgz", + "integrity": "sha512-pRzm4kDTu0MjlmBkxmS9yYhw60nncfcEwu9NNdPFSQEFXS95ZKyIIyTSHu/o3ReBUrLKYEq+7YaXCRn/bPB4MA==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-math": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", + "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/katex": "^0.16.0", + "devlop": "^1.0.0", + "katex": "^0.16.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.1.0.tgz", + "integrity": "sha512-fS8hnLIjnjvdQIj39Geug8wWsR0HrYZ43KShKxNfwT7t2LOHo/LbWZEzEaSOjwtjdCsjoE6syHhonEzW0zv0+Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-edit-map": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-edit-map/-/micromark-util-edit-map-1.0.0.tgz", + "integrity": "sha512-Pa2ljlsEL6sVwFaYeyrOLSYbQt73JvGbPOYFq+9AElXiSnfI5Q4465RRZ1sHv7lDjDOnGRDDaqPXqClqWK/q1Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.3.tgz", + "integrity": "sha512-oxB2Ik03hI0gv+VNn9tnh1t1YEe9MDPptViAEgfdf3YQHsn0pzGTgCdlSCJXcwhqm8phaEuM7zeEu3QQzVBrPg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/playwright": { + "version": "1.64.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.64.1.tgz", + "integrity": "sha512-HCrVhHr5QQuwYoswEUGTb7gGp522yflbv/ST8nF4sFWGuLjQCt17Q/EubpGGSNKYn1tsTCPZxqHhHCfVURu7UA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.64.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/playwright-core": { + "version": "1.64.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.64.1.tgz", + "integrity": "sha512-BC4s8y6SEVA6Q1rSxZTto8hI1KUI3xXlHGZgvGqP4IqPdI/a6FX9H29IDNz7vKo9l21b6LfYosScPL6M3xxyDQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/re2js": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/re2js/-/re2js-2.9.1.tgz", + "integrity": "sha512-JIT3bEEUZTOR2YS1walNEIfH4cF/cQeZcBUFq7ldqO6lR6g0X5CBq/S8rsa9omzZcsNf8qc36jCkWpKKtncrZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/smol-toml": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.9.1.tgz", + "integrity": "sha512-j7WyPdf0CJoutMzMoPLF/bVXHtKZIT9Rb4eGeEbWw8X2t5oirjPgpL+OpaENZrILYaXqYwnVH+qgUwVbl+pUJQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 18" + }, + "funding": { + "url": "https://github.com/sponsors/cyyynthia" + } + }, + "node_modules/string-width": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.3.0.tgz", + "integrity": "sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/uc.micro": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-3.0.0.tgz", + "integrity": "sha512-U3PppEkleoTnIfi8BozMx3yju3qc/L6SwqWo2Sw+54PX+PX0q9I+r1Um5HCmqD7n9VDX5/v3vQH/AjA6deDdtw==", + "dev": true, + "license": "MIT" + }, + "node_modules/unicorn-magic": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.1.tgz", + "integrity": "sha512-lzlXPoVB0Uy/FvTaUgX39RbixYiSKoc3JSoSf01+0c2B6FR3qdYIPN7Qjo/AV7n6sqLCk0509cT3LRj1oSZ1+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..22e6b91 --- /dev/null +++ b/package.json @@ -0,0 +1,23 @@ +{ + "name": "nizeross-blog-quality", + "private": true, + "version": "1.0.0", + "description": "Development-only quality checks for a Hugo static blog", + "engines": { "node": ">=24 <25" }, + "scripts": { + "lint": "markdownlint-cli2", + "test:e2e": "playwright test", + "browsers": "node scripts/install_browser.cjs", + "audit:dependencies": "npm audit --audit-level=high" + }, + "devDependencies": { + "@playwright/test": "1.64.1", + "@axe-core/playwright": "4.14.0", + "markdownlint-cli2": "0.24.0", + "katex": "0.19.1" + }, + "overrides": { + "re2js": "2.9.1", + "katex": "0.19.1" + } +} diff --git a/playwright.config.js b/playwright.config.js new file mode 100644 index 0000000..db12a97 --- /dev/null +++ b/playwright.config.js @@ -0,0 +1,21 @@ +process.env.PLAYWRIGHT_BROWSERS_PATH ||= require('node:path').join(__dirname, '.cache/playwright'); +const { defineConfig, devices } = require('@playwright/test'); + +module.exports = defineConfig({ + testDir: './tests/e2e', + timeout: 30000, + fullyParallel: false, + workers: 1, + retries: process.env.CI ? 1 : 0, + reporter: [['list'], ['html', { open: 'never' }], ['json', { outputFile: 'reports/browser-results.json' }]], + use: { baseURL: 'http://127.0.0.1:4173', trace: 'retain-on-failure', screenshot: 'only-on-failure' }, + webServer: { + command: 'node scripts/serve.cjs', + url: 'http://127.0.0.1:4173', + reuseExistingServer: false + }, + projects: [ + { name: 'desktop', use: { ...devices['Desktop Chrome'], viewport: { width: 1440, height: 1080 } } }, + { name: 'mobile', use: { ...devices['iPhone 13'], defaultBrowserType: 'chromium' } } + ] +}); diff --git a/scripts/check_content.py b/scripts/check_content.py new file mode 100644 index 0000000..7d7ad76 --- /dev/null +++ b/scripts/check_content.py @@ -0,0 +1,108 @@ +"""Validate author-owned TOML Markdown and local image paths without a network.""" +import ast +import datetime as dt +from pathlib import Path +import re +import sys +import tomllib +from urllib.parse import unquote, urlsplit + +ROOT = Path(__file__).resolve().parents[1] +TYPES = {'technical', 'project', 'reading', 'essay', 'life'} + + +def parse_document(text): + lines = text.lstrip('\ufeff').splitlines() + if not lines or lines[0].strip() != '+++': + raise ValueError('Expected TOML frontmatter delimited by +++') + try: + end = next(i for i in range(1, len(lines)) if lines[i].strip() == '+++') + except StopIteration as exc: + raise ValueError('Unclosed frontmatter') from exc + return tomllib.loads('\n'.join(lines[1:end])), '\n'.join(lines[end + 1:]) + + +def check_document(path, text, root=ROOT): + errors = [] + try: + meta, body = parse_document(text) + except (ValueError, tomllib.TOMLDecodeError) as exc: + return [str(exc)] + if not isinstance(meta.get('title'), str) or not meta['title'].strip(): + errors.append('title must be a non-empty string') + if 'draft' in meta and not isinstance(meta['draft'], bool): + errors.append('draft must be a boolean') + if 'kind' in meta: + errors.append('Use contentType, not Hugo reserved key kind') + for field in ('tags', 'categories', 'stack'): + value = meta.get(field, []) + if not isinstance(value, list) or not all(isinstance(x, str) and x.strip() for x in value): + errors.append(f'{field} must be a list of non-empty strings') + is_post = 'posts' in path.relative_to(root).parts + if is_post: + if not meta.get('summary') or not meta.get('categories'): + errors.append('Posts require summary and categories') + if meta.get('contentType') not in TYPES: + errors.append('Unknown or missing contentType') + try: + date = meta.get('date') + parsed = dt.datetime.fromisoformat(date.replace('Z', '+00:00')) if isinstance(date, str) else date + if not isinstance(parsed, dt.datetime) or parsed.tzinfo is None: + raise ValueError() + except (ValueError, AttributeError): + errors.append('date must be an ISO datetime with timezone') + if path.suffix != '.md' or not re.fullmatch(r'_?index|[\w]+(?:-[\w]+)*', path.stem): + errors.append('Filename must be index.md, _index.md or a safe slug.md') + for part in path.relative_to(root / 'content').parts[:-1]: + if not re.fullmatch(r'[\w]+(?:-[\w]+)*', part): + errors.append(f'Unsafe directory slug: {part}') + if meta.get('github') and not re.fullmatch(r'https://github\.com/[\w.-]+/[\w.-]+/?', meta['github']): + errors.append('github must be a GitHub repository HTTPS URL') + in_fence = None + code = [] + language = '' + for number, line in enumerate(body.splitlines(), 1): + fence = re.match(r'^\s*(`{3,}|~{3,})(.*)$', line) + if fence: + marker, suffix = fence.groups() + if in_fence is None: + in_fence, language, code = marker, suffix.strip(), [] + elif marker[0] == in_fence[0] and len(marker) >= len(in_fence) and not suffix.strip(): + if language == 'python': + try: + ast.parse('\n'.join(code)) + except SyntaxError as exc: + errors.append(f'Python code block syntax: {exc.msg}') + in_fence = None + continue + if in_fence: + code.append(line) + continue + if re.search(r'<\s*script\b|javascript\s*:', line, re.I): + errors.append(f'line {number}: active script content is not allowed') + for target in re.findall(r'!\[[^\]]*\]\(([^\s)]+)', line): + parsed = urlsplit(target.strip('<>')) + if parsed.scheme or parsed.netloc: + continue + decoded = unquote(parsed.path) + target_path = (root / 'static' / decoded.lstrip('/')) if decoded.startswith('/') else path.parent / decoded + target_path = target_path.resolve() + if not target_path.is_relative_to(root.resolve()) or not target_path.is_file(): + errors.append(f'Missing or out-of-project image: {target}') + if in_fence: + errors.append('Unclosed code fence') + return errors + + +def main(): + paths = sorted((ROOT / 'content').rglob('*.md')) + failures = [] + for path in paths: + for error in check_document(path, path.read_text(encoding='utf-8')): + failures.append(f'{path.relative_to(ROOT)}: {error}') + print('\n'.join(failures) if failures else f'PASS: {len(paths)} Markdown documents; frontmatter, names, images and Python examples') + return bool(failures) + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/scripts/check_external.py b/scripts/check_external.py new file mode 100644 index 0000000..6609774 --- /dev/null +++ b/scripts/check_external.py @@ -0,0 +1,34 @@ +"""Optional online link report, separate from offline publication checks.""" +from concurrent.futures import ThreadPoolExecutor +import json +from pathlib import Path +import re +import urllib.error +import urllib.request + +ROOT = Path(__file__).resolve().parents[1] + + +def check(url): + try: + request = urllib.request.Request(url, headers={'User-Agent': 'NizerossBlogLinkCheck/1.0'}) + with urllib.request.urlopen(request, timeout=15) as response: + return {'url': url, 'status': response.status, 'ok': response.status < 400} + except (urllib.error.URLError, TimeoutError, OSError) as exc: + return {'url': url, 'ok': False, 'reason': str(exc)} + + +if __name__ == '__main__': + urls = set() + for path in (ROOT / 'content').rglob('*.md'): + text = path.read_text(encoding='utf-8') + urls.update(re.findall(r'https?://[^\s)\]>"\']+', text)) + with ThreadPoolExecutor(max_workers=6) as pool: + results = list(pool.map(check, sorted(urls))) + target = ROOT / 'reports/external-links.json' + target.parent.mkdir(exist_ok=True) + target.write_text(json.dumps(results, ensure_ascii=False, indent=2), encoding='utf-8') + print(f'{len(results)} external links; {sum(x["ok"] for x in results)} reachable. Report: {target}') + for result in results: + if not result['ok']: + print(f'Review: {result["url"]}: {result.get("reason", result.get("status"))}') diff --git a/scripts/check_site.py b/scripts/check_site.py new file mode 100644 index 0000000..0f7db03 --- /dev/null +++ b/scripts/check_site.py @@ -0,0 +1,84 @@ +"""Check every generated internal link, asset reference and fragment.""" +import argparse +from html.parser import HTMLParser +import json +from pathlib import Path +from urllib.parse import unquote, urljoin, urlsplit + +ROOT = Path(__file__).resolve().parents[1] +HOSTS = {'nizeross.github.io', 'kirisame.me', 'localhost', '127.0.0.1'} + + +class Document(HTMLParser): + def __init__(self, text): + super().__init__(convert_charrefs=True) + self.ids, self.references, self.duplicates = set(), [], [] + self.feed(text) + + def handle_starttag(self, tag, attrs): + attrs = dict(attrs) + if attrs.get('id'): + if attrs['id'] in self.ids: + self.duplicates.append(attrs['id']) + self.ids.add(attrs['id']) + for attr in ('href', 'src', 'poster'): + if attrs.get(attr): + self.references.append(attrs[attr]) + + +def resolve_reference(site, source_url, reference): + parsed = urlsplit(urljoin('https://nizeross.github.io' + source_url, reference)) + if parsed.scheme not in ('http', 'https') or parsed.hostname not in HOSTS: + return None + target = (site / unquote(parsed.path).lstrip('/')).resolve() + if not target.is_relative_to(site.resolve()): + raise ValueError('Link escapes output directory') + if target.is_dir() or parsed.path.endswith('/'): + target /= 'index.html' + return target, unquote(parsed.fragment) + + +def check_site(site): + site = site.resolve() + pages = {p: Document(p.read_text(encoding='utf-8')) for p in site.rglob('*.html')} + errors, count = [], 0 + for path, doc in pages.items(): + relative = path.relative_to(site).as_posix() + source = '/' + relative + for duplicate in doc.duplicates: + errors.append(f'{relative}: duplicate id #{duplicate}') + for reference in doc.references: + try: + resolved = resolve_reference(site, source, reference) + except ValueError as exc: + errors.append(f'{relative}: {exc}: {reference}') + continue + if not resolved: + continue + count += 1 + target, fragment = resolved + if not target.is_file(): + errors.append(f'{relative}: missing {reference}') + elif fragment and target in pages and fragment not in pages[target].ids: + errors.append(f'{relative}: missing fragment {reference}') + legacy = json.loads((ROOT / 'tests/legacy-urls.json').read_text()) + for url in legacy: + if not (site / url.strip('/') / 'index.html').is_file(): + errors.append(f'Legacy URL removed: {url}') + for asset in ('index.xml', 'index.json', 'sitemap.xml', 'robots.txt'): + if not (site / asset).is_file(): + errors.append(f'Missing feed/search/SEO output: {asset}') + search = json.loads((site / 'index.json').read_text(encoding='utf-8')) + if not any('PCL2' in x.get('title', '') for x in search): + errors.append('Existing PCL2 article is missing from search index') + print(f'{len(pages)} HTML pages, {count} internal references, {len(legacy)} legacy URLs') + return errors + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('directory', nargs='?', default='.build/site') + args = parser.parse_args() + failures = check_site(Path(args.directory)) + print('\n'.join(failures) if failures else 'PASS: internal links, assets, anchors, RSS, search and legacy URLs') + raise SystemExit(bool(failures)) diff --git a/scripts/install_browser.cjs b/scripts/install_browser.cjs new file mode 100644 index 0000000..f0792ac --- /dev/null +++ b/scripts/install_browser.cjs @@ -0,0 +1,7 @@ +const path = require('node:path'); +const { spawnSync } = require('node:child_process'); +const root = path.resolve(__dirname, '..'); +const env = { ...process.env, PLAYWRIGHT_BROWSERS_PATH: path.join(root, '.cache/playwright') }; +const cli = path.join(path.dirname(require.resolve('playwright/package.json')), 'cli.js'); +const result = spawnSync(process.execPath, [cli, 'install', 'chromium', ...process.argv.slice(2)], { cwd: root, env, stdio: 'inherit' }); +process.exit(result.status ?? 1); diff --git a/scripts/review_gate.py b/scripts/review_gate.py new file mode 100644 index 0000000..4709259 --- /dev/null +++ b/scripts/review_gate.py @@ -0,0 +1,49 @@ +"""Fail closed unless the exact main commit came from an approved merged PR.""" +import json +import os +import urllib.request + + +def approved_pull(pull, reviews, sha): + if not (pull.get('merged_at') and pull['base']['ref'] == 'main' and pull.get('merge_commit_sha') == sha): + return False + latest = {} + for review in reviews: + login = review['user']['login'] + if review['state'] != 'COMMENTED': + latest[login] = review + if any(review['state'] == 'CHANGES_REQUESTED' for review in latest.values()): + return False + return any(review['state'] == 'APPROVED' + and review.get('commit_id') == pull['head']['sha'] + and review['user'].get('type') != 'Bot' + and login != pull['user']['login'] for login, review in latest.items()) + + +def main(): + repo, sha = os.environ['GITHUB_REPOSITORY'], os.environ['GITHUB_SHA'] + token = os.environ['GITHUB_TOKEN'] + def get(path): + request = urllib.request.Request(f'https://api.github.com/repos/{repo}/{path}', headers={ + 'Authorization': f'Bearer {token}', 'Accept': 'application/vnd.github+json', + 'X-GitHub-Api-Version': '2022-11-28'}) + with urllib.request.urlopen(request, timeout=30) as response: + return json.load(response) + pulls = get(f'commits/{sha}/pulls?per_page=100') + for pull in pulls: + reviews = [] + for page in range(1, 11): + batch = get(f'pulls/{pull["number"]}/reviews?per_page=100&page={page}') + reviews.extend(batch) + if len(batch) < 100: + break + else: + raise SystemExit('Too many reviews; refusing ambiguous release') + if approved_pull(pull, reviews, sha): + print(f'Review gate passed for PR #{pull["number"]}') + return + raise SystemExit('Release blocked: no merged PR with approval of the final head commit by another human reviewer.') + + +if __name__ == '__main__': + main() diff --git a/scripts/security_check.py b/scripts/security_check.py new file mode 100644 index 0000000..1970978 --- /dev/null +++ b/scripts/security_check.py @@ -0,0 +1,37 @@ +"""Scan authored inputs for obvious credentials and unsafe CI patterns.""" +import json +from pathlib import Path +import re +import subprocess + +ROOT = Path(__file__).resolve().parents[1] +PATTERNS = [r'gh[pousr]_[A-Za-z0-9]{30,}', r'github_pat_[A-Za-z0-9_]{40,}', + r'-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----', r'AKIA[0-9A-Z]{16}'] + + +def main(): + failures = [] + for folder in ('content', 'config', 'assets/js', 'layouts', '.github'): + for path in (ROOT / folder).rglob('*'): + if path.is_file() and path.suffix in ('.md', '.toml', '.js', '.html', '.yml', '.yaml'): + text = path.read_text(encoding='utf-8') + if any(re.search(pattern, text) for pattern in PATTERNS): + failures.append(f'Possible credential in {path.relative_to(ROOT)} (value redacted)') + if 'busuanzi.ibruce.info' in text: + failures.append('Unexpected external analytics script') + workflow = (ROOT / '.github/workflows/quality.yml').read_text() + if 'pull_request_target' in workflow or 'pages: write' in workflow or 'id-token: write' in workflow: + failures.append('Quality workflow must not publish or run privileged PR code') + for reference in re.findall(r'uses:\s*(\S+)', workflow): + if not re.fullmatch(r'[\w.-]+/[\w.-]+@[a-f0-9]{40}', reference): + failures.append('Unpinned quality workflow action') + lock = json.loads((ROOT / 'toolchain.json').read_text()) + commit = subprocess.check_output(['git', '-C', 'themes/blowfish', 'rev-parse', 'HEAD'], cwd=ROOT, text=True).strip() + if commit != lock['themeCommit']: + failures.append('Theme commit changed; re-audit and update toolchain.json intentionally') + print('\n'.join(failures) if failures else 'PASS: authored inputs, minimal CI permissions and pinned theme') + return bool(failures) + + +if __name__ == '__main__': + raise SystemExit(main()) diff --git a/scripts/serve.cjs b/scripts/serve.cjs new file mode 100644 index 0000000..0d8d319 --- /dev/null +++ b/scripts/serve.cjs @@ -0,0 +1,20 @@ +/* Loopback-only static server for deterministic browser checks. */ +const http = require('node:http'); +const fs = require('node:fs'); +const path = require('node:path'); +const root = path.resolve(__dirname, '../.build/site'); +const types = { '.html': 'text/html; charset=utf-8', '.css': 'text/css', '.js': 'text/javascript', '.json': 'application/json', '.svg': 'image/svg+xml', '.png': 'image/png', '.jpg': 'image/jpeg', '.xml': 'application/xml', '.woff2': 'font/woff2', '.woff': 'font/woff' }; +http.createServer((req, res) => { + let file; + try { + const pathname = decodeURIComponent(new URL(req.url, 'http://localhost').pathname); + file = path.resolve(root, '.' + pathname); + if (file !== root && !file.startsWith(root + path.sep)) throw new Error('Invalid path'); + if (fs.statSync(file).isDirectory()) file = path.join(file, 'index.html'); + const bytes = fs.readFileSync(file); + res.writeHead(200, { 'content-type': types[path.extname(file)] || 'application/octet-stream', 'cache-control': 'no-store' }); + res.end(bytes); + } catch { + res.writeHead(404, { 'content-type': 'text/plain' }); res.end('Not found'); + } +}).listen(4173, '127.0.0.1', () => console.log('Local preview: http://127.0.0.1:4173')); diff --git a/scripts/site.py b/scripts/site.py index 24bb538..d278145 100644 --- a/scripts/site.py +++ b/scripts/site.py @@ -31,7 +31,8 @@ def hugo(): def run(*args): - subprocess.run(args, cwd=ROOT, check=True) + env = dict(os.environ, HUGO_RESOURCEDIR=str(ROOT / '.build/resources')) + subprocess.run(args, cwd=ROOT, check=True, env=env) def new_post(kind, title, slug=None): @@ -64,6 +65,7 @@ def main(): if args.command == 'new': new_post(args.kind, args.title, args.slug) elif args.command == 'build': + run(sys.executable, 'scripts/sync_vendor.py') run(hugo(), '--destination', '.build/site', '--cacheDir', str(ROOT / '.cache/hugo'), '--gc', '--minify') elif args.command == 'preview': run(hugo(), 'server', '--buildDrafts', '--destination', '.build/preview', '--bind', '127.0.0.1', '--port', '1313') diff --git a/scripts/suggest.py b/scripts/suggest.py new file mode 100644 index 0000000..bdf8feb --- /dev/null +++ b/scripts/suggest.py @@ -0,0 +1,49 @@ +"""Offline writing suggestions. Never changes article text or calls an API.""" +import argparse +import json +from pathlib import Path +import re +import sys + +from check_content import ROOT, parse_document + + +def tokens(text): + words = set(re.findall(r'[a-z][a-z0-9+#.-]{1,}', text.lower())) + chinese = ''.join(re.findall(r'[\u4e00-\u9fff]', text)) + return words | {chinese[i:i + 2] for i in range(len(chinese) - 1)} + + +def similarity(a, b): + return len(a & b) / max(1, len(a | b)) + + +def suggest(path): + path = path.resolve() + if not path.is_relative_to(ROOT / 'content'): + raise ValueError('Choose an article inside content/') + meta, body = parse_document(path.read_text(encoding='utf-8')) + lines = [x.strip() for x in body.splitlines() if x.strip() and not x.startswith(('#', '```', '{{', '!['))] + vocab = tokens(body) + related = [] + tags = set() + for other in (ROOT / 'content/posts').rglob('*.md'): + if other.resolve() == path: + continue + other_meta, other_body = parse_document(other.read_text(encoding='utf-8')) + score = similarity(vocab, tokens(other_body)) + if score > 0: + related.append({'path': other.relative_to(ROOT).as_posix(), 'score': round(score, 3)}) + tags.update(tag for tag in other_meta.get('tags', []) if tag.lower() in body.lower()) + return {'mode': 'offline-heuristic-not-generative-ai', 'reviewRequired': True, + 'summaryCandidate': ' '.join(lines[:2])[:160], 'tagCandidates': sorted(tags), + 'relatedCandidates': sorted(related, key=lambda x: -x['score'])[:3], + 'note': '仅供人工参考;没有修改文章,没有执行代码,没有联网。'} + + +if __name__ == '__main__': + sys.stdout.reconfigure(encoding='utf-8') + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('article', type=Path) + args = parser.parse_args() + print(json.dumps(suggest(args.article), ensure_ascii=False, indent=2)) diff --git a/scripts/sync_vendor.py b/scripts/sync_vendor.py new file mode 100644 index 0000000..cb831ec --- /dev/null +++ b/scripts/sync_vendor.py @@ -0,0 +1,14 @@ +"""Copy audited KaTeX distribution into ignored Hugo asset overrides.""" +from pathlib import Path +import shutil + +ROOT = Path(__file__).resolve().parents[1] +source = ROOT / 'node_modules/katex' +target = ROOT / 'assets/lib/katex' +target.mkdir(parents=True, exist_ok=True) +shutil.copy2(source / 'dist/katex.min.js', target / 'katex.min.js') +shutil.copy2(source / 'dist/katex.min.css', target / 'katex.min.css') +shutil.copy2(source / 'dist/contrib/auto-render.min.js', target / 'auto-render.min.js') +shutil.copytree(source / 'dist/fonts', target / 'fonts', dirs_exist_ok=True) +shutil.copy2(source / 'LICENSE', target / 'LICENSE') +print('KaTeX asset override synchronized from locked npm dependency') diff --git a/tests/e2e/blog.spec.js b/tests/e2e/blog.spec.js new file mode 100644 index 0000000..aa2a112 --- /dev/null +++ b/tests/e2e/blog.spec.js @@ -0,0 +1,82 @@ +const { test, expect } = require('@playwright/test'); +const { AxeBuilder } = require('@axe-core/playwright'); +const fs = require('node:fs'); + +async function appearance(page, mode) { + await page.addInitScript((value) => localStorage.setItem('appearance', value), mode); + await page.emulateMedia({ colorScheme: mode }); +} + +test('homepage navigation, theme, responsive layout and accessibility', async ({ page }, info) => { + const failures = []; + page.on('pageerror', error => failures.push(error.message)); + await appearance(page, 'light'); + await page.goto('/'); + await expect(page.getByRole('heading', { level: 1 })).toContainText('保持好奇'); + await expect(page.getByRole('link', { name: '进入文章归档' })).toHaveAttribute('href', '/posts/'); + await expect(page.locator('.topic-card')).toHaveCount(5); + const width = await page.evaluate(() => ({ actual: document.documentElement.scrollWidth, available: innerWidth })); + expect(width.actual).toBeLessThanOrEqual(width.available + 1); + expect(await page.locator('body').evaluate(el => getComputedStyle(el).backgroundColor)).toBe('rgb(255, 255, 255)'); + const toggle = info.project.name === 'mobile' ? '#appearance-switcher-mobile' : '#appearance-switcher'; + await page.locator(toggle).click(); + await expect(page.locator('html')).toHaveClass(/dark/); + expect(await page.locator('body').evaluate(el => getComputedStyle(el).backgroundColor)).toBe('rgb(30, 41, 59)'); + const axe = await new AxeBuilder({ page }).withTags(['wcag2a', 'wcag2aa', 'wcag21aa']).analyze(); + expect(axe.violations).toEqual([]); + await page.screenshot({ path: `reports/home-${info.project.name}-dark.png`, fullPage: true }); + await page.locator(toggle).click(); + await page.screenshot({ path: `reports/home-${info.project.name}-light.png`, fullPage: true }); + expect(failures).toEqual([]); +}); + +test('search finds a legacy article', async ({ page }, info) => { + await page.goto('/'); + await page.locator(info.project.name === 'mobile' ? '#search-button-mobile' : '#search-button').click(); + await page.locator('#search-query').fill('PCL2'); + await expect(page.locator('#search-results a').first()).toContainText('PCL2'); + await page.locator('#search-results a').first().click(); + await expect(page).toHaveURL(/posts\/pcl2-memory-optimization/); +}); + +test('article code, math, image zoom, progress, taxonomy and anchor', async ({ page }, info) => { + await page.goto('/writing/'); + await expect(page.locator('.katex').first()).toBeVisible(); + await expect(page.locator('.highlight')).toBeVisible(); + await expect(page.locator('.copy-button')).toBeAttached(); + await page.locator('.article-content img').first().click(); + await expect(page.locator('.medium-zoom-image--opened')).toBeVisible(); + await page.keyboard.press('Escape'); + await page.locator('.article-content a[href="#代码"]').click(); + await expect(page).toHaveURL(/#%E4%BB%A3%E7%A0%81|#代码/); + await page.evaluate(() => scrollTo(0, document.body.scrollHeight)); + await expect.poll(() => page.locator('.reading-progress').evaluate(el => el.value)).toBeGreaterThan(90); + await page.screenshot({ path: `reports/reading-${info.project.name}.png`, fullPage: true }); + await page.goto('/posts/how-build-blog/'); + await expect(page.locator('#TableOfContents')).toBeAttached(); + await expect(page.locator('a[href*="/tags/hugo/"]').first()).toBeVisible(); + const axe = await new AxeBuilder({ page }).withTags(['wcag2a', 'wcag2aa', 'wcag21aa']).analyze(); + expect(axe.violations).toEqual([]); +}); + +test('primary routes, metadata, projects and mobile menu', async ({ page }, info) => { + for (const path of ['/posts/', '/projects/', '/projects/personal-blog/', '/about/', '/links/', '/categories/', '/tags/']) { + const response = await page.goto(path); + expect(response.status()).toBe(200); + await expect(page.locator('h1')).toHaveCount(1); + await expect(page.locator('link[rel="canonical"]')).toBeAttached(); + expect(await page.locator('meta[name="description"]').getAttribute('content')).toBeTruthy(); + const overflow = await page.evaluate(() => document.documentElement.scrollWidth > innerWidth + 1); + expect(overflow, path).toBeFalsy(); + } + await page.goto('/projects/'); + await expect(page.getByRole('heading', { name: '个人博客与自动化发布系统' })).toBeVisible(); + if (info.project.name === 'mobile') { + await page.locator('label[for="mobile-menu-toggle"]').first().click(); + await expect(page.locator('[role="dialog"]')).toBeVisible(); + await page.locator('[role="dialog"]').getByRole('link', { name: 'About', exact: true }).click(); + await expect(page).toHaveURL(/\/about\//); + } + fs.mkdirSync('reports', { recursive: true }); + await page.screenshot({ path: `reports/about-${info.project.name}.png`, fullPage: true }); +}); diff --git a/tests/test_content.py b/tests/test_content.py new file mode 100644 index 0000000..e9b1e6e --- /dev/null +++ b/tests/test_content.py @@ -0,0 +1,127 @@ +import sys +import importlib.util +from pathlib import Path +import unittest + +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / 'scripts')) +from check_content import ROOT, check_document, parse_document +from check_site import Document, resolve_reference +from suggest import similarity, tokens + +spec = importlib.util.spec_from_file_location('blog_cli', ROOT / 'scripts/site.py') +blog_cli = importlib.util.module_from_spec(spec) +spec.loader.exec_module(blog_cli) +slugify = blog_cli.slugify + +VALID = '''+++ +title = "测试" +date = 2026-10-29T12:00:00+08:00 +draft = true +contentType = "technical" +categories = ["技术学习"] +tags = ["Python"] +summary = "测试解析与验证。" ++++ + +## 一个标题 + +```python +print("ok") +``` +''' + + +class ContentTests(unittest.TestCase): + path = ROOT / 'content/posts/test-article/index.md' + + def errors(self, text): + return check_document(self.path, text) + + def test_valid_toml_and_python(self): + self.assertEqual(self.errors(VALID), []) + + def test_missing_frontmatter(self): + self.assertTrue(self.errors('hello')) + + def test_unclosed_frontmatter(self): + self.assertTrue(self.errors('+++\ntitle="oops"')) + + def test_invalid_toml(self): + self.assertTrue(self.errors(VALID.replace('draft = true', 'draft = ???'))) + + def test_missing_summary(self): + self.assertTrue(self.errors(VALID.replace('summary = "测试解析与验证。"', ''))) + + def test_draft_type(self): + self.assertTrue(self.errors(VALID.replace('draft = true', 'draft = "true"'))) + + def test_unknown_type(self): + self.assertTrue(self.errors(VALID.replace('technical', 'unknown'))) + + def test_reserved_kind(self): + self.assertTrue(self.errors(VALID.replace('contentType', 'kind'))) + + def test_naive_date(self): + self.assertTrue(self.errors(VALID.replace('+08:00', ''))) + + def test_invalid_tags(self): + self.assertTrue(self.errors(VALID.replace('["Python"]', '"Python"'))) + + def test_unclosed_code(self): + self.assertIn('Unclosed code fence', self.errors(VALID.rstrip()[:-3])) + + def test_invalid_python(self): + self.assertTrue(self.errors(VALID.replace('print("ok")', 'def broken('))) + + def test_missing_image(self): + self.assertTrue(self.errors(VALID + '\n![alt](missing.png)')) + + def test_script_rejected(self): + self.assertTrue(self.errors(VALID + '\n')) + + def test_script_example_allowed(self): + self.assertEqual(self.errors(VALID + '\n```html\n\n```'), []) + + def test_chinese_slug(self): + self.assertEqual(slugify('我的 第一篇!'), '我的-第一篇') + + def test_slug_blocks_paths(self): + self.assertNotIn('/', slugify('../../unsafe/path')) + + def test_parser_body(self): + self.assertIn('一个标题', parse_document(VALID)[1]) + + def test_similarity(self): + self.assertEqual(similarity({'a'}, {'a'}), 1) + self.assertEqual(similarity({'a'}, {'b'}), 0) + + def test_chinese_tokens(self): + self.assertIn('计算', tokens('计算机 Python')) + + +class LinkTests(unittest.TestCase): + def test_relative_asset(self): + site = ROOT / '.build/site' + target, fragment = resolve_reference(site, '/posts/a/index.html', 'image.png') + self.assertEqual(target, (site / 'posts/a/image.png').resolve()) + + def test_external_skipped(self): + self.assertIsNone(resolve_reference(ROOT, '/', 'https://example.com/')) + + def test_mail_skipped(self): + self.assertIsNone(resolve_reference(ROOT, '/', 'mailto:x@example.com')) + + def test_fragments_decoded(self): + self.assertEqual(resolve_reference(ROOT, '/', '#%E4%BB%A3%E7%A0%81')[1], '代码') + + def test_html_ids(self): + doc = Document('

Hi

Link') + self.assertIn('a', doc.ids) + self.assertEqual(doc.references, ['#a']) + + def test_duplicate_ids(self): + self.assertEqual(Document('

').duplicates, ['x']) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_release_gate.py b/tests/test_release_gate.py new file mode 100644 index 0000000..9f553b3 --- /dev/null +++ b/tests/test_release_gate.py @@ -0,0 +1,47 @@ +import sys +from pathlib import Path +import unittest + +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / 'scripts')) +from review_gate import approved_pull + + +class ReleaseGateTests(unittest.TestCase): + def setUp(self): + self.pull = {'merged_at': '2026-10-29', 'base': {'ref': 'main'}, 'merge_commit_sha': 'release', + 'head': {'sha': 'final'}, 'user': {'login': 'author'}} + self.review = {'state': 'APPROVED', 'commit_id': 'final', 'user': {'login': 'reviewer', 'type': 'User'}} + + def test_valid_review(self): + self.assertTrue(approved_pull(self.pull, [self.review], 'release')) + + def test_direct_push(self): + self.pull['merge_commit_sha'] = 'other' + self.assertFalse(approved_pull(self.pull, [self.review], 'release')) + + def test_self_review(self): + self.review['user']['login'] = 'author' + self.assertFalse(approved_pull(self.pull, [self.review], 'release')) + + def test_stale_review(self): + self.review['commit_id'] = 'older' + self.assertFalse(approved_pull(self.pull, [self.review], 'release')) + + def test_dismissed_review(self): + dismissed = dict(self.review, state='DISMISSED') + self.assertFalse(approved_pull(self.pull, [self.review, dismissed], 'release')) + + def test_requested_changes(self): + changes = {'state': 'CHANGES_REQUESTED', 'commit_id': 'final', 'user': {'login': 'second'}} + self.assertFalse(approved_pull(self.pull, [self.review, changes], 'release')) + + def test_no_review(self): + self.assertFalse(approved_pull(self.pull, [], 'release')) + + def test_unmerged_pull(self): + self.pull['merged_at'] = None + self.assertFalse(approved_pull(self.pull, [self.review], 'release')) + + +if __name__ == '__main__': + unittest.main() From d50c51a7455afb5ce65686b599fac09fd311293e Mon Sep 17 00:00:00 2001 From: Nizeross Date: Thu, 29 Oct 2026 23:39:06 +0800 Subject: [PATCH 5/7] test: verify responsive reading and audit shipped vendor assets --- .github/workflows/quality.yml | 4 +- .gitignore | 1 + SECURITY.md | 31 + archetypes/essay.md | 2 +- archetypes/life.md | 2 +- archetypes/project.md | 2 +- archetypes/reading.md | 2 +- archetypes/technical.md | 2 +- assets/js/navigation-accessibility.js | 37 + content/projects/personal-blog/index.md | 4 + content/projects/personal-blog/screenshot.png | Bin 0 -> 178830 bytes .../_markup/render-codeblock-mermaid.html | 1 + layouts/partials/extend-footer.html | 4 +- layouts/partials/extend-head-uncached.html | 7 + .../header/components/mobile-menu.html | 155 ++ layouts/partials/icon.html | 4 + layouts/partials/meta/views.html | 10 +- package-lock.json | 1854 ++++++++++++++++- package.json | 12 +- playwright.config.js | 4 +- reports/validation.md | 40 + scripts/audit_dependencies.cjs | 29 + scripts/build_vendor.cjs | 13 + scripts/check_content.py | 1 + scripts/check_site.py | 2 + scripts/serve.cjs | 3 +- scripts/site.py | 5 +- scripts/sync_vendor.py | 7 + scripts/test-browser.cjs | 14 + scripts/vendor-mermaid.mjs | 3 + tests/e2e/blog.spec.js | 28 +- tests/test_content.py | 37 + tests/workflows.test.cjs | 38 + 33 files changed, 2249 insertions(+), 109 deletions(-) create mode 100644 SECURITY.md create mode 100644 assets/js/navigation-accessibility.js create mode 100644 content/projects/personal-blog/screenshot.png create mode 100644 layouts/_default/_markup/render-codeblock-mermaid.html create mode 100644 layouts/partials/extend-head-uncached.html create mode 100644 layouts/partials/header/components/mobile-menu.html create mode 100644 layouts/partials/icon.html create mode 100644 reports/validation.md create mode 100644 scripts/audit_dependencies.cjs create mode 100644 scripts/build_vendor.cjs create mode 100644 scripts/test-browser.cjs create mode 100644 scripts/vendor-mermaid.mjs create mode 100644 tests/workflows.test.cjs diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 6d62dfa..c80f30d 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -47,7 +47,9 @@ jobs: python scripts/site.py check npm run lint - name: Unit tests - run: python -m unittest discover -s tests -v + run: | + python -m unittest discover -s tests -v + npm run test:workflows - name: Dependency and source security run: | npm audit --audit-level=low diff --git a/.gitignore b/.gitignore index af39649..dcdcb10 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ /.build/ /.cache/ /assets/lib/katex/ +/assets/lib/mermaid/ /resources/_gen/ /node_modules/ /test-results/ diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..1aeb1f6 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,31 @@ +# 安全审查与维护范围 + +## 本次执行的检查 + +2026-10-29 对本站锁定的 npm 依赖执行了完整 audit,并扫描作者维护的配置、模板和内容中常见凭据模式。检查 CI 最小权限、Actions 提交 SHA 与主题提交固定情况。扫描结果不等于完整渗透测试,尤其不能发现所有未知漏洞或历史 Git 对象中的敏感信息。 + +原来的第三方访问统计脚本已从 footer 与阅读量覆盖模板移除。注释中的旧 Firebase 集成配置已清理;Firebase 公共配置本身通常不是服务器密钥,但未启用的配置不应给维护者造成错觉。网站仍保留作者主动公开的联系信息。 + +## 主题上游审计需要单独解读 + +对固定 Blowfish 子模块的 package-lock 执行 `npm audit --prefix themes/blowfish --json`,发现 29 个有告警的包节点:1 low、10 moderate、17 high、1 critical。包含 Puppeteer、FTP、翻译工具、CSS 工具及图表相关依赖。本项目不会安装或运行主题的 Node 工具链;构建使用主题已编译 CSS。不能因此把 29 个告警全部归为网站运行时漏洞,也不能声称上游依赖没有问题。 + +涉及当前/潜在阅读运行时的 KaTeX 与 Mermaid 已通过站点资源覆盖处理:KaTeX 固定 0.19.1;Mermaid 固定 11.17.2,并从锁文件依赖重新打包,使用 DOMPurify 3.4.17 与 lodash-es 4.18.1。直接复制 npm 包里的预构建 bundle 可能仍携带旧版内嵌依赖,因此 Mermaid 使用 esbuild 根据审核后的依赖图打包。主题文件与子模块提交不变。 + +首页不会加载公式或图表脚本;只有相应文章按需加载。本项目不启用主题的图表、视频、图库等其他可选 shortcodes。后续启用新 shortcode 之前,应先审核它带入的前端脚本;本次没有对每个未使用的供应商 bundle 作“安全”背书。 + +报告可重生成: + +```powershell +node scripts/audit_dependencies.cjs +``` + +本站与主题分别输出到 `reports/dependency-audit.json` 和 `reports/theme-audit.json`。脚本对本站漏洞或审计服务失败返回非零;上游主题结果保留为待跟踪信息。CI 的强制 audit 针对实际采用的站点工具链。 + +## 发布保护 + +PR 检查不读取生产密钥,不使用 `pull_request_target`。待批准的发布方案检查最终提交的人工审核,部署 job 才有 Pages 写权限与 OIDC 权限。分支保护与环境 reviewer 必须在 GitHub 设置中启用;当前现有生产 workflow 未改动,所以这项保护尚未在线生效。 + +## 后续维护 + +定期在独立分支更新依赖与主题,复核兼容范围和告警,再执行完整验证。公开问题报告不要包含 token、完整凭据或可利用的个人数据;先通过作者公开邮箱联系。不要用 `npm audit fix --force` 在未经检查的情况下升级整个主题。 diff --git a/archetypes/essay.md b/archetypes/essay.md index 10f703a..33bde72 100644 --- a/archetypes/essay.md +++ b/archetypes/essay.md @@ -1,5 +1,5 @@ +++ -title = {{ .Title }} +title = {{ printf "%q" .Name }} date = '{{ .Date }}' draft = true contentType = "essay" diff --git a/archetypes/life.md b/archetypes/life.md index 2db0b83..3a5260a 100644 --- a/archetypes/life.md +++ b/archetypes/life.md @@ -1,5 +1,5 @@ +++ -title = {{ .Title }} +title = {{ printf "%q" .Name }} date = '{{ .Date }}' draft = true contentType = "life" diff --git a/archetypes/project.md b/archetypes/project.md index 69c3944..0051230 100644 --- a/archetypes/project.md +++ b/archetypes/project.md @@ -1,5 +1,5 @@ +++ -title = {{ .Title }} +title = {{ printf "%q" .Name }} date = '{{ .Date }}' draft = true contentType = "project" diff --git a/archetypes/reading.md b/archetypes/reading.md index 9d06db1..421b972 100644 --- a/archetypes/reading.md +++ b/archetypes/reading.md @@ -1,5 +1,5 @@ +++ -title = {{ .Title }} +title = {{ printf "%q" .Name }} date = '{{ .Date }}' draft = true contentType = "reading" diff --git a/archetypes/technical.md b/archetypes/technical.md index 17e3035..aa048e5 100644 --- a/archetypes/technical.md +++ b/archetypes/technical.md @@ -1,5 +1,5 @@ +++ -title = {{ .Title }} +title = {{ printf "%q" .Name }} date = '{{ .Date }}' draft = true contentType = "technical" diff --git a/assets/js/navigation-accessibility.js b/assets/js/navigation-accessibility.js new file mode 100644 index 0000000..50d16aa --- /dev/null +++ b/assets/js/navigation-accessibility.js @@ -0,0 +1,37 @@ +(() => { + const toggle = document.getElementById('mobile-menu-toggle'); + const dialog = document.getElementById('mobile-navigation'); + const labels = [...document.querySelectorAll('label[for="mobile-menu-toggle"]')]; + if (!toggle || !dialog) return; + const opener = labels.find(label => !dialog.contains(label)); + const close = () => { + toggle.checked = false; + opener?.setAttribute('aria-expanded', 'false'); + opener?.focus(); + }; + opener?.setAttribute('aria-expanded', 'false'); + labels.forEach(label => label.addEventListener('keydown', event => { + if (event.key === 'Enter' || event.key === ' ') { + event.preventDefault(); + label.click(); + } + })); + toggle.addEventListener('change', () => { + opener?.setAttribute('aria-expanded', String(toggle.checked)); + requestAnimationFrame(() => { + if (toggle.checked) dialog.querySelector('[role="button"]')?.focus(); + else opener?.focus(); + }); + }); + document.addEventListener('keydown', event => { + if (!toggle.checked) return; + if (event.key === 'Escape') { event.preventDefault(); close(); } + if (event.key !== 'Tab') return; + const focusable = [...dialog.querySelectorAll('a[href],button,[tabindex="0"]')].filter(el => el.getClientRects().length); + if (event.shiftKey && document.activeElement === focusable[0]) { + event.preventDefault(); focusable.at(-1)?.focus(); + } else if (!event.shiftKey && document.activeElement === focusable.at(-1)) { + event.preventDefault(); focusable[0]?.focus(); + } + }); +})(); diff --git a/content/projects/personal-blog/index.md b/content/projects/personal-blog/index.md index dcd2439..79d1efb 100644 --- a/content/projects/personal-blog/index.md +++ b/content/projects/personal-blog/index.md @@ -19,6 +19,10 @@ showHero = false ## 项目一览 +![博客首页的桌面浅色模式运行截图](screenshot.png) + +上图来自本地重构版本的真实浏览器测试。下面是这套系统的工作流示意: + ![博客的构建与审核发布流程示意](screenshot.svg) ## 技术栈与取舍 diff --git a/content/projects/personal-blog/screenshot.png b/content/projects/personal-blog/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..89a8ca717f3be586dafbd2bcf588a83b6e35e1c8 GIT binary patch literal 178830 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
  • Kys;5men8Amh2AW`V(<;hjk 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 fU%x^KB`y{{ .Inner }} diff --git a/layouts/partials/extend-footer.html b/layouts/partials/extend-footer.html index 79f32ff..474c04d 100644 --- a/layouts/partials/extend-footer.html +++ b/layouts/partials/extend-footer.html @@ -1,2 +1,2 @@ -{{ $reading := resources.Get "js/reading-progress.js" | resources.Minify | resources.Fingerprint "sha512" }} - +{{ $scripts := slice (resources.Get "js/reading-progress.js") (resources.Get "js/navigation-accessibility.js") | resources.Concat "js/site.js" | resources.Minify | resources.Fingerprint "sha512" }} + diff --git a/layouts/partials/extend-head-uncached.html b/layouts/partials/extend-head-uncached.html new file mode 100644 index 0000000..25fd50e --- /dev/null +++ b/layouts/partials/extend-head-uncached.html @@ -0,0 +1,7 @@ +{{/* Existing Markdown mermaid fences use the audited local asset bundle. */}} +{{ if and (not (.HasShortcode "mermaid")) (findRE "(?m)^```mermaid" .RawContent) }} + {{ $mermaid := resources.Get "lib/mermaid/mermaid.min.js" }} + {{ $config := resources.Get "js/mermaid.js" | resources.Minify }} + {{ $bundle := slice $mermaid $config | resources.Concat "js/mermaid.bundle.js" | resources.Fingerprint "sha512" }} + +{{ end }} diff --git a/layouts/partials/header/components/mobile-menu.html b/layouts/partials/header/components/mobile-menu.html new file mode 100644 index 0000000..1f538a9 --- /dev/null +++ b/layouts/partials/header/components/mobile-menu.html @@ -0,0 +1,155 @@ +
    + {{ if .Site.Params.enableSearch | default false }} + + {{ end }} + + {{ if .Site.Params.footer.showAppearanceSwitcher | default false }} + + {{ end }} + + {{ if or + .Site.Menus.main + .Site.Menus.subnavigation + .Site.Params.enableA11y + }} + + + + + {{ end }} +
    + +{{ define "mobile-main-menu" }} + {{ range .Site.Menus.main }} + {{ $submenuId := printf "fullscreen-submenu-%s" (.Identifier | default .Name | anchorize) }} + + {{ end }} +{{ end }} + +{{ define "mobile-subnavigation" }} + {{ if .Site.Menus.subnavigation }} + + {{ end }} +{{ end }} + +{{ define "mobile-footer-components" }} + {{ if or + hugo.IsMultilingual + .Site.Params.enableA11y + }} +
    + {{ partial "header/components/translations.html" . }} + + {{ if .Site.Params.enableA11y | default false }} + {{ partial "header/components/a11y.html" (dict "prefix" "mobile-menu-") }} + {{ end }} +
    + {{ end }} +{{ end }} diff --git a/layouts/partials/icon.html b/layouts/partials/icon.html new file mode 100644 index 0000000..63e9d34 --- /dev/null +++ b/layouts/partials/icon.html @@ -0,0 +1,4 @@ +{{- $icon := resources.Get (print "icons/" . ".svg") -}} +{{- with $icon -}} +