From c1f4c51a17eea67e03fb1ee2684b3a69caa73524 Mon Sep 17 00:00:00 2001 From: Charliechen114514 <725610365@qq.com> Date: Fri, 3 Jul 2026 11:29:13 +0800 Subject: [PATCH] =?UTF-8?q?feat(site):=20=E6=A0=B7=E5=BC=8F=E5=A4=A7?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E2=80=94=E2=80=94=E4=BE=A7=E6=A0=8F=E6=8B=96?= =?UTF-8?q?=E6=8B=BD=20+=20=E5=80=9F=20anatomy=5Fgui=20=E9=87=8D=E5=A1=91?= =?UTF-8?q?=20Qt=20=E7=BB=BF=E8=BA=AB=E4=BB=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 侧栏拖拽(ResizableSidebar 自 ModernCPP 搬入)+ 阅读进度条 + 自定义首页 Hero(QtHero,事件循环/对象树/信号与槽 SVG)+ ModuleCard/ChapterHero 组件(Qt 化改造)。custom.css 补完整 :root/.dark 设计令牌(Qt 绿品牌 + 借 anatomy 骨白/炭墨底),三层 feature 卡配色重调,blockquote/Hero 渐变去硬编码靛蓝。 mermaid 改本地打包(dynamic import,拔 CDN)——浏览器加载跨域 CDN 脚本不可靠会卡骨架。修 SPA 路由切换不渲染:ReadingProgress 的 router.onAfterRouteChange 覆盖了 mermaid 的(VitePress 该钩子是单值回调属性、非订阅),改用 watch(route.path);render 轮询等新页 DOM 挂载。 build.ts 缓存 key 并入 theme/+config/ 哈希——修改主题后普通 build 不加 --force 会输出旧皮的坑。 --- package.json | 3 +- pnpm-lock.yaml | 838 ++++++++++++++++++ scripts/build.ts | 8 +- site/.vitepress/config/shared.ts | 7 + .../theme/components/ChapterHero.vue | 162 ++++ .../theme/components/ModuleCard.vue | 109 +++ site/.vitepress/theme/components/QtHero.vue | 223 +++++ .../theme/components/ReadingProgress.vue | 67 ++ .../theme/components/ResizableSidebar.vue | 177 ++++ site/.vitepress/theme/custom.css | 185 +++- site/.vitepress/theme/index.ts | 11 + site/.vitepress/theme/mermaid-client.ts | 104 +-- 12 files changed, 1802 insertions(+), 92 deletions(-) create mode 100644 site/.vitepress/theme/components/ChapterHero.vue create mode 100644 site/.vitepress/theme/components/ModuleCard.vue create mode 100644 site/.vitepress/theme/components/QtHero.vue create mode 100644 site/.vitepress/theme/components/ReadingProgress.vue create mode 100644 site/.vitepress/theme/components/ResizableSidebar.vue diff --git a/package.json b/package.json index 6cd5da55..07f7db94 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ ] }, "dependencies": { - "minisearch": "^7.2.0" + "minisearch": "^7.2.0", + "mermaid": "^10.9.6" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5c1186d3..af8130a3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: dependencies: + mermaid: + specifier: ^10.9.6 + version: 10.9.6 minisearch: specifier: ^7.2.0 version: 7.2.0 @@ -120,6 +123,9 @@ packages: resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} + '@braintree/sanitize-url@6.0.4': + resolution: {integrity: sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==} + '@docsearch/css@3.8.2': resolution: {integrity: sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==} @@ -608,6 +614,18 @@ packages: '@shikijs/vscode-textmate@10.0.2': resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + '@types/d3-scale-chromatic@3.1.0': + resolution: {integrity: sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==} + + '@types/d3-scale@4.0.9': + resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==} + + '@types/d3-time@3.0.4': + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} + + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} @@ -620,15 +638,27 @@ packages: '@types/markdown-it@14.1.2': resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} + '@types/mdast@3.0.15': + resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} + '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} '@types/mdurl@2.0.0': resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + '@types/node@25.7.0': resolution: {integrity: sha512-z+pdZyxE+RTQE9AcboAZCb4otwcrvgHD+GlBpPgn0emDVt0ohrTMhAwlr2Wd9nZ+nihhYFxO2pThz3C5qSu2Eg==} + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} @@ -749,16 +779,199 @@ packages: character-entities-legacy@3.0.0: resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + copy-anything@4.0.5: resolution: {integrity: sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==} engines: {node: '>=18'} + cose-base@1.0.3: + resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} + csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + cytoscape-cose-bilkent@4.1.0: + resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape@3.34.0: + resolution: {integrity: sha512-62rNSrioXw93uliKFBwjukeQyeWwH2PqDrTac31r2P6464u3AUvTk0xS4LVvT251g7IgkFunrI48ZEZGjywSOg==} + engines: {node: '>=0.10'} + + d3-array@2.12.1: + resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} + + d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + + d3-axis@3.0.0: + resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} + engines: {node: '>=12'} + + d3-brush@3.0.0: + resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} + engines: {node: '>=12'} + + d3-chord@3.0.1: + resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} + engines: {node: '>=12'} + + d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + + d3-contour@4.0.2: + resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} + engines: {node: '>=12'} + + d3-delaunay@6.0.4: + resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} + engines: {node: '>=12'} + + d3-dispatch@3.0.1: + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} + engines: {node: '>=12'} + + d3-drag@3.0.0: + resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} + engines: {node: '>=12'} + + d3-dsv@3.0.1: + resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} + engines: {node: '>=12'} + hasBin: true + + d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + + d3-fetch@3.0.1: + resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} + engines: {node: '>=12'} + + d3-force@3.0.0: + resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} + engines: {node: '>=12'} + + d3-format@3.1.2: + resolution: {integrity: sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==} + engines: {node: '>=12'} + + d3-geo@3.1.1: + resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==} + engines: {node: '>=12'} + + d3-hierarchy@3.1.2: + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} + engines: {node: '>=12'} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-path@1.0.9: + resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} + + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + + d3-polygon@3.0.1: + resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} + engines: {node: '>=12'} + + d3-quadtree@3.0.1: + resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} + engines: {node: '>=12'} + + d3-random@3.0.1: + resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} + engines: {node: '>=12'} + + d3-sankey@0.12.3: + resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==} + + d3-scale-chromatic@3.1.0: + resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==} + engines: {node: '>=12'} + + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + + d3-selection@3.0.0: + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} + engines: {node: '>=12'} + + d3-shape@1.3.7: + resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} + + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + + d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + + d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + + d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + + d3-transition@3.0.1: + resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} + engines: {node: '>=12'} + peerDependencies: + d3-selection: 2 - 3 + + d3-zoom@3.0.0: + resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} + engines: {node: '>=12'} + + d3@7.9.0: + resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==} + engines: {node: '>=12'} + + dagre-d3-es@7.0.13: + resolution: {integrity: sha512-efEhnxpSuwpYOKRm/L5KbqoZmNNukHa/Flty4Wp62JRvgH2ojwVgPgdYyr4twpieZnyRDdIH7PY2mopX26+j2Q==} + + dayjs@1.11.21: + resolution: {integrity: sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + + delaunator@5.1.0: + resolution: {integrity: sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==} + dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} @@ -766,6 +979,16 @@ packages: devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + diff@5.2.2: + resolution: {integrity: sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==} + engines: {node: '>=0.3.1'} + + dompurify@3.4.11: + resolution: {integrity: sha512-zhlUV12GsaRzMsf9q5M254YhA4+VuF0fG+QFqu6aYpoGlKtz+w8//jBcGVYBgQkR5GHjUomejY84AV+/uPbWdw==} + + elkjs@0.9.3: + resolution: {integrity: sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==} + emoji-regex-xs@1.0.0: resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==} @@ -809,45 +1032,155 @@ packages: html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + internmap@1.0.1: + resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} + + internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + is-what@5.5.0: resolution: {integrity: sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==} engines: {node: '>=18'} + katex@0.16.47: + resolution: {integrity: sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg==} + hasBin: true + + khroma@2.1.0: + resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + + layout-base@1.0.2: + resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} + + lodash-es@4.18.1: + resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} + magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} mark.js@8.11.1: resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==} + mdast-util-from-markdown@1.3.1: + resolution: {integrity: sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==} + mdast-util-to-hast@13.2.1: resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + mdast-util-to-string@3.2.0: + resolution: {integrity: sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==} + + mermaid@10.9.6: + resolution: {integrity: sha512-XRjjRaI4aPCAMpVaOhxIwLYdx3U4Cb6mN0M268ggFAfFRqsvyFW8zxWbEZazN/mPkqsVWThb0oa1UawWK+XMNg==} + + micromark-core-commonmark@1.1.0: + resolution: {integrity: sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==} + + micromark-factory-destination@1.1.0: + resolution: {integrity: sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==} + + micromark-factory-label@1.1.0: + resolution: {integrity: sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==} + + micromark-factory-space@1.1.0: + resolution: {integrity: sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==} + + micromark-factory-title@1.1.0: + resolution: {integrity: sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==} + + micromark-factory-whitespace@1.1.0: + resolution: {integrity: sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==} + + micromark-util-character@1.2.0: + resolution: {integrity: sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==} + micromark-util-character@2.1.1: resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + micromark-util-chunked@1.1.0: + resolution: {integrity: sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==} + + micromark-util-classify-character@1.1.0: + resolution: {integrity: sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==} + + micromark-util-combine-extensions@1.1.0: + resolution: {integrity: sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==} + + micromark-util-decode-numeric-character-reference@1.1.0: + resolution: {integrity: sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==} + + micromark-util-decode-string@1.1.0: + resolution: {integrity: sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==} + + micromark-util-encode@1.1.0: + resolution: {integrity: sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==} + micromark-util-encode@2.0.1: resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + micromark-util-html-tag-name@1.2.0: + resolution: {integrity: sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==} + + micromark-util-normalize-identifier@1.1.0: + resolution: {integrity: sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==} + + micromark-util-resolve-all@1.1.0: + resolution: {integrity: sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==} + + micromark-util-sanitize-uri@1.2.0: + resolution: {integrity: sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==} + micromark-util-sanitize-uri@2.0.1: resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + micromark-util-subtokenize@1.1.0: + resolution: {integrity: sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==} + + micromark-util-symbol@1.1.0: + resolution: {integrity: sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==} + micromark-util-symbol@2.0.1: resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + micromark-util-types@1.1.0: + resolution: {integrity: sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==} + micromark-util-types@2.0.2: resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + micromark@3.2.0: + resolution: {integrity: sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==} + minisearch@7.2.0: resolution: {integrity: sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==} mitt@3.0.1: resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + nanoid@3.3.12: resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + non-layered-tidy-tree-layout@2.0.2: + resolution: {integrity: sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==} + oniguruma-to-es@3.1.1: resolution: {integrity: sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==} @@ -882,11 +1215,24 @@ packages: rfdc@1.4.1: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + robust-predicates@3.0.3: + resolution: {integrity: sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==} + rollup@4.60.3: resolution: {integrity: sha512-pAQK9HalE84QSm4Po3EmWIZPd3FnjkShVkiMlz1iligWYkWQ7wHYd1PF/T7QZ5TVSD6uSTon5gBVMSM4JfBV+A==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + rw@1.3.3: + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + + sade@1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + search-insights@2.17.3: resolution: {integrity: sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==} @@ -907,6 +1253,9 @@ packages: stringify-entities@4.0.4: resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + stylis@4.4.0: + resolution: {integrity: sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==} + superjson@2.2.6: resolution: {integrity: sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==} engines: {node: '>=16'} @@ -917,6 +1266,10 @@ packages: trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + ts-dedent@2.3.0: + resolution: {integrity: sha512-JfJeIHke7y2egdGGgRAvpCwYFUsHlM2gPcrVOxFkznt/4uzQ7HFmvE63iFHVLBJNDuyDOQgijDK/tXH/f6Msjg==} + engines: {node: '>=6.10'} + tsx@4.21.0: resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} engines: {node: '>=18.0.0'} @@ -931,6 +1284,9 @@ packages: unist-util-position@5.0.0: resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + unist-util-stringify-position@3.0.3: + resolution: {integrity: sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==} + unist-util-stringify-position@4.0.0: resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} @@ -940,6 +1296,15 @@ packages: unist-util-visit@5.1.0: resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + uuid@14.0.1: + resolution: {integrity: sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew==} + hasBin: true + + uvu@0.5.6: + resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==} + engines: {node: '>=8'} + hasBin: true + vfile-message@4.0.3: resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} @@ -997,6 +1362,9 @@ packages: typescript: optional: true + web-worker@1.5.0: + resolution: {integrity: sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==} + zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} @@ -1127,6 +1495,8 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 + '@braintree/sanitize-url@6.0.4': {} + '@docsearch/css@3.8.2': {} '@docsearch/js@3.8.2(@algolia/client-search@5.52.1)(search-insights@2.17.3)': @@ -1421,6 +1791,18 @@ snapshots: '@shikijs/vscode-textmate@10.0.2': {} + '@types/d3-scale-chromatic@3.1.0': {} + + '@types/d3-scale@4.0.9': + dependencies: + '@types/d3-time': 3.0.4 + + '@types/d3-time@3.0.4': {} + + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + '@types/estree@1.0.8': {} '@types/hast@3.0.4': @@ -1434,16 +1816,27 @@ snapshots: '@types/linkify-it': 5.0.0 '@types/mdurl': 2.0.0 + '@types/mdast@3.0.15': + dependencies: + '@types/unist': 2.0.11 + '@types/mdast@4.0.4': dependencies: '@types/unist': 3.0.3 '@types/mdurl@2.0.0': {} + '@types/ms@2.1.0': {} + '@types/node@25.7.0': dependencies: undici-types: 7.21.0 + '@types/trusted-types@2.0.7': + optional: true + + '@types/unist@2.0.11': {} + '@types/unist@3.0.3': {} '@types/web-bluetooth@0.0.21': {} @@ -1579,20 +1972,231 @@ snapshots: character-entities-legacy@3.0.0: {} + character-entities@2.0.2: {} + comma-separated-tokens@2.0.3: {} + commander@7.2.0: {} + + commander@8.3.0: {} + copy-anything@4.0.5: dependencies: is-what: 5.5.0 + cose-base@1.0.3: + dependencies: + layout-base: 1.0.2 + csstype@3.2.3: {} + cytoscape-cose-bilkent@4.1.0(cytoscape@3.34.0): + dependencies: + cose-base: 1.0.3 + cytoscape: 3.34.0 + + cytoscape@3.34.0: {} + + d3-array@2.12.1: + dependencies: + internmap: 1.0.1 + + d3-array@3.2.4: + dependencies: + internmap: 2.0.3 + + d3-axis@3.0.0: {} + + d3-brush@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3-chord@3.0.1: + dependencies: + d3-path: 3.1.0 + + d3-color@3.1.0: {} + + d3-contour@4.0.2: + dependencies: + d3-array: 3.2.4 + + d3-delaunay@6.0.4: + dependencies: + delaunator: 5.1.0 + + d3-dispatch@3.0.1: {} + + d3-drag@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-selection: 3.0.0 + + d3-dsv@3.0.1: + dependencies: + commander: 7.2.0 + iconv-lite: 0.6.3 + rw: 1.3.3 + + d3-ease@3.0.1: {} + + d3-fetch@3.0.1: + dependencies: + d3-dsv: 3.0.1 + + d3-force@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-quadtree: 3.0.1 + d3-timer: 3.0.1 + + d3-format@3.1.2: {} + + d3-geo@3.1.1: + dependencies: + d3-array: 3.2.4 + + d3-hierarchy@3.1.2: {} + + d3-interpolate@3.0.1: + dependencies: + d3-color: 3.1.0 + + d3-path@1.0.9: {} + + d3-path@3.1.0: {} + + d3-polygon@3.0.1: {} + + d3-quadtree@3.0.1: {} + + d3-random@3.0.1: {} + + d3-sankey@0.12.3: + dependencies: + d3-array: 2.12.1 + d3-shape: 1.3.7 + + d3-scale-chromatic@3.1.0: + dependencies: + d3-color: 3.1.0 + d3-interpolate: 3.0.1 + + d3-scale@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.2 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + + d3-selection@3.0.0: {} + + d3-shape@1.3.7: + dependencies: + d3-path: 1.0.9 + + d3-shape@3.2.0: + dependencies: + d3-path: 3.1.0 + + d3-time-format@4.1.0: + dependencies: + d3-time: 3.1.0 + + d3-time@3.1.0: + dependencies: + d3-array: 3.2.4 + + d3-timer@3.0.1: {} + + d3-transition@3.0.1(d3-selection@3.0.0): + dependencies: + d3-color: 3.1.0 + d3-dispatch: 3.0.1 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-timer: 3.0.1 + + d3-zoom@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3@7.9.0: + dependencies: + d3-array: 3.2.4 + d3-axis: 3.0.0 + d3-brush: 3.0.0 + d3-chord: 3.0.1 + d3-color: 3.1.0 + d3-contour: 4.0.2 + d3-delaunay: 6.0.4 + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-dsv: 3.0.1 + d3-ease: 3.0.1 + d3-fetch: 3.0.1 + d3-force: 3.0.0 + d3-format: 3.1.2 + d3-geo: 3.1.1 + d3-hierarchy: 3.1.2 + d3-interpolate: 3.0.1 + d3-path: 3.1.0 + d3-polygon: 3.0.1 + d3-quadtree: 3.0.1 + d3-random: 3.0.1 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.1.0 + d3-selection: 3.0.0 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + d3-timer: 3.0.1 + d3-transition: 3.0.1(d3-selection@3.0.0) + d3-zoom: 3.0.0 + + dagre-d3-es@7.0.13: + dependencies: + d3: 7.9.0 + lodash-es: 4.18.1 + + dayjs@1.11.21: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + + delaunator@5.1.0: + dependencies: + robust-predicates: 3.0.3 + dequal@2.0.3: {} devlop@1.1.0: dependencies: dequal: 2.0.3 + diff@5.2.2: {} + + dompurify@3.4.11: + optionalDependencies: + '@types/trusted-types': 2.0.7 + + elkjs@0.9.3: {} + emoji-regex-xs@1.0.0: {} entities@7.0.1: {} @@ -1687,14 +2291,51 @@ snapshots: html-void-elements@3.0.0: {} + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + internmap@1.0.1: {} + + internmap@2.0.3: {} + is-what@5.5.0: {} + katex@0.16.47: + dependencies: + commander: 8.3.0 + + khroma@2.1.0: {} + + kleur@4.1.5: {} + + layout-base@1.0.2: {} + + lodash-es@4.18.1: {} + magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 mark.js@8.11.1: {} + mdast-util-from-markdown@1.3.1: + dependencies: + '@types/mdast': 3.0.15 + '@types/unist': 2.0.11 + decode-named-character-reference: 1.3.0 + mdast-util-to-string: 3.2.0 + micromark: 3.2.0 + micromark-util-decode-numeric-character-reference: 1.1.0 + micromark-util-decode-string: 1.1.0 + micromark-util-normalize-identifier: 1.1.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + unist-util-stringify-position: 3.0.3 + uvu: 0.5.6 + transitivePeerDependencies: + - supports-color + mdast-util-to-hast@13.2.1: dependencies: '@types/hast': 3.0.4 @@ -1707,29 +2348,197 @@ snapshots: unist-util-visit: 5.1.0 vfile: 6.0.3 + mdast-util-to-string@3.2.0: + dependencies: + '@types/mdast': 3.0.15 + + mermaid@10.9.6: + dependencies: + '@braintree/sanitize-url': 6.0.4 + '@types/d3-scale': 4.0.9 + '@types/d3-scale-chromatic': 3.1.0 + cytoscape: 3.34.0 + cytoscape-cose-bilkent: 4.1.0(cytoscape@3.34.0) + d3: 7.9.0 + d3-sankey: 0.12.3 + dagre-d3-es: 7.0.13 + dayjs: 1.11.21 + dompurify: 3.4.11 + elkjs: 0.9.3 + katex: 0.16.47 + khroma: 2.1.0 + lodash-es: 4.18.1 + mdast-util-from-markdown: 1.3.1 + non-layered-tidy-tree-layout: 2.0.2 + stylis: 4.4.0 + ts-dedent: 2.3.0 + uuid: 14.0.1 + web-worker: 1.5.0 + transitivePeerDependencies: + - supports-color + + micromark-core-commonmark@1.1.0: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-factory-destination: 1.1.0 + micromark-factory-label: 1.1.0 + micromark-factory-space: 1.1.0 + micromark-factory-title: 1.1.0 + micromark-factory-whitespace: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-chunked: 1.1.0 + micromark-util-classify-character: 1.1.0 + micromark-util-html-tag-name: 1.2.0 + micromark-util-normalize-identifier: 1.1.0 + micromark-util-resolve-all: 1.1.0 + micromark-util-subtokenize: 1.1.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + + micromark-factory-destination@1.1.0: + dependencies: + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-factory-label@1.1.0: + dependencies: + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + + micromark-factory-space@1.1.0: + dependencies: + micromark-util-character: 1.2.0 + micromark-util-types: 1.1.0 + + micromark-factory-title@1.1.0: + dependencies: + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-factory-whitespace@1.1.0: + dependencies: + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-util-character@1.2.0: + dependencies: + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + micromark-util-character@2.1.1: dependencies: micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 + micromark-util-chunked@1.1.0: + dependencies: + micromark-util-symbol: 1.1.0 + + micromark-util-classify-character@1.1.0: + dependencies: + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-util-combine-extensions@1.1.0: + dependencies: + micromark-util-chunked: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-util-decode-numeric-character-reference@1.1.0: + dependencies: + micromark-util-symbol: 1.1.0 + + micromark-util-decode-string@1.1.0: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-util-character: 1.2.0 + micromark-util-decode-numeric-character-reference: 1.1.0 + micromark-util-symbol: 1.1.0 + + micromark-util-encode@1.1.0: {} + micromark-util-encode@2.0.1: {} + micromark-util-html-tag-name@1.2.0: {} + + micromark-util-normalize-identifier@1.1.0: + dependencies: + micromark-util-symbol: 1.1.0 + + micromark-util-resolve-all@1.1.0: + dependencies: + micromark-util-types: 1.1.0 + + micromark-util-sanitize-uri@1.2.0: + dependencies: + micromark-util-character: 1.2.0 + micromark-util-encode: 1.1.0 + micromark-util-symbol: 1.1.0 + micromark-util-sanitize-uri@2.0.1: dependencies: micromark-util-character: 2.1.1 micromark-util-encode: 2.0.1 micromark-util-symbol: 2.0.1 + micromark-util-subtokenize@1.1.0: + dependencies: + micromark-util-chunked: 1.1.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + + micromark-util-symbol@1.1.0: {} + micromark-util-symbol@2.0.1: {} + micromark-util-types@1.1.0: {} + micromark-util-types@2.0.2: {} + micromark@3.2.0: + dependencies: + '@types/debug': 4.1.13 + debug: 4.4.3 + decode-named-character-reference: 1.3.0 + micromark-core-commonmark: 1.1.0 + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-chunked: 1.1.0 + micromark-util-combine-extensions: 1.1.0 + micromark-util-decode-numeric-character-reference: 1.1.0 + micromark-util-encode: 1.1.0 + micromark-util-normalize-identifier: 1.1.0 + micromark-util-resolve-all: 1.1.0 + micromark-util-sanitize-uri: 1.2.0 + micromark-util-subtokenize: 1.1.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + transitivePeerDependencies: + - supports-color + minisearch@7.2.0: {} mitt@3.0.1: {} + mri@1.2.0: {} + + ms@2.1.3: {} + nanoid@3.3.12: {} + non-layered-tidy-tree-layout@2.0.2: {} + oniguruma-to-es@3.1.1: dependencies: emoji-regex-xs: 1.0.0 @@ -1764,6 +2573,8 @@ snapshots: rfdc@1.4.1: {} + robust-predicates@3.0.3: {} + rollup@4.60.3: dependencies: '@types/estree': 1.0.8 @@ -1795,6 +2606,14 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.60.3 fsevents: 2.3.3 + rw@1.3.3: {} + + sade@1.8.1: + dependencies: + mri: 1.2.0 + + safer-buffer@2.1.2: {} + search-insights@2.17.3: {} shiki@2.5.0: @@ -1819,6 +2638,8 @@ snapshots: character-entities-html4: 2.1.0 character-entities-legacy: 3.0.0 + stylis@4.4.0: {} + superjson@2.2.6: dependencies: copy-anything: 4.0.5 @@ -1827,6 +2648,8 @@ snapshots: trim-lines@3.0.1: {} + ts-dedent@2.3.0: {} + tsx@4.21.0: dependencies: esbuild: 0.27.7 @@ -1844,6 +2667,10 @@ snapshots: dependencies: '@types/unist': 3.0.3 + unist-util-stringify-position@3.0.3: + dependencies: + '@types/unist': 2.0.11 + unist-util-stringify-position@4.0.0: dependencies: '@types/unist': 3.0.3 @@ -1859,6 +2686,15 @@ snapshots: unist-util-is: 6.0.1 unist-util-visit-parents: 6.0.2 + uuid@14.0.1: {} + + uvu@0.5.6: + dependencies: + dequal: 2.0.3 + diff: 5.2.2 + kleur: 4.1.5 + sade: 1.8.1 + vfile-message@4.0.3: dependencies: '@types/unist': 3.0.3 @@ -1935,4 +2771,6 @@ snapshots: '@vue/server-renderer': 3.5.34(vue@3.5.34) '@vue/shared': 3.5.34 + web-worker@1.5.0: {} + zwitch@2.0.4: {} diff --git a/scripts/build.ts b/scripts/build.ts index 41ff6a15..ae59e0f1 100644 --- a/scripts/build.ts +++ b/scripts/build.ts @@ -105,6 +105,11 @@ function hashDir(dir: string): string { return h.digest('hex').substring(0, 16) } +// 主题/配置共享哈希:theme/ 与 config/ 任一文件变动 → 所有 per-volume 缓存失效。 +// per-volume cacheKey 默认只哈希 docs 目录;改主题/CSS/head/nav/sidebar 后若不并入此哈希, +// 缓存不失效、会输出旧皮(曾踩坑:改 custom.css 后 8/10 卷仍挂旧 CSS,须 --force 才全量重建)。 +const SHARED_HASH = hashDir(join(MAIN_VP, 'theme')) + hashDir(join(MAIN_VP, 'config')) + // ── Manifest ──────────────────────────────────────────────── interface ManifestEntry { hash: string; timestamp: string } @@ -184,7 +189,8 @@ interface BuildTask { function prepareTask(vol: Volume, manifest: Manifest): BuildTask { const volDocDir = join(DOCUMENTS, vol.srcDir) - const cacheKey = existsSync(volDocDir) ? hashDir(volDocDir) : '' + const docsHash = existsSync(volDocDir) ? hashDir(volDocDir) : '' + const cacheKey = docsHash + '|' + SHARED_HASH const prev = manifest[vol.name] const cached = !FORCE_REBUILD && prev && prev.hash === cacheKey && existsSync(join(CACHE_DIR, 'output', vol.name)) return { id: vol.name, vol, cacheKey, cached } diff --git a/site/.vitepress/config/shared.ts b/site/.vitepress/config/shared.ts index 16fd2b3a..269c1040 100644 --- a/site/.vitepress/config/shared.ts +++ b/site/.vitepress/config/shared.ts @@ -47,6 +47,13 @@ export const sharedBase = { {}, `(function(){try{var s=localStorage.getItem('awesomeqt-font-size')||'normal';if(s!=='xxsmall'&&s!=='small'&&s!=='normal'&&s!=='large'&&s!=='xxlarge'){s='normal';}document.documentElement.dataset.fontSize=s;}catch(e){}})()`, ], + // 可拖拽侧栏首屏防闪:hydration 前从 localStorage 还原左右栏宽度 CSS 变量,默认 272/256。 + // 与 theme/components/ResizableSidebar.vue 的 CONF(key=vp-sidebar-width/vp-aside-width)一致。 + [ + 'script', + {}, + `(function(){try{var w=parseInt(localStorage.getItem('vp-sidebar-width'));if(!w||w<200||w>480){w=272;}document.documentElement.style.setProperty('--vp-sidebar-width',w+'px');var a=parseInt(localStorage.getItem('vp-aside-width'));if(!a||a<180||a>360){a=256;}document.documentElement.style.setProperty('--vp-aside-width',a+'px');}catch(e){}})()`, + ], ], } diff --git a/site/.vitepress/theme/components/ChapterHero.vue b/site/.vitepress/theme/components/ChapterHero.vue new file mode 100644 index 00000000..dab9b606 --- /dev/null +++ b/site/.vitepress/theme/components/ChapterHero.vue @@ -0,0 +1,162 @@ + + + + + diff --git a/site/.vitepress/theme/components/ModuleCard.vue b/site/.vitepress/theme/components/ModuleCard.vue new file mode 100644 index 00000000..92f2cdcc --- /dev/null +++ b/site/.vitepress/theme/components/ModuleCard.vue @@ -0,0 +1,109 @@ + + + + + diff --git a/site/.vitepress/theme/components/QtHero.vue b/site/.vitepress/theme/components/QtHero.vue new file mode 100644 index 00000000..31ad0171 --- /dev/null +++ b/site/.vitepress/theme/components/QtHero.vue @@ -0,0 +1,223 @@ + + + + + + + diff --git a/site/.vitepress/theme/components/ReadingProgress.vue b/site/.vitepress/theme/components/ReadingProgress.vue new file mode 100644 index 00000000..ecd0ae8c --- /dev/null +++ b/site/.vitepress/theme/components/ReadingProgress.vue @@ -0,0 +1,67 @@ + + + + + diff --git a/site/.vitepress/theme/components/ResizableSidebar.vue b/site/.vitepress/theme/components/ResizableSidebar.vue new file mode 100644 index 00000000..cb85e526 --- /dev/null +++ b/site/.vitepress/theme/components/ResizableSidebar.vue @@ -0,0 +1,177 @@ + + + diff --git a/site/.vitepress/theme/custom.css b/site/.vitepress/theme/custom.css index c1bae684..51de8404 100644 --- a/site/.vitepress/theme/custom.css +++ b/site/.vitepress/theme/custom.css @@ -1,3 +1,76 @@ +/* ================================================================ + AwesomeQt 设计令牌 · Qt 绿身份 + 借 anatomy_gui 暖骨白/炭墨底 + 亮:骨白底 / Qt 绿强调 / 深炭文 + 暗:炭墨底 / 亮绿强调 / 暖灰文 + ================================================================ */ +:root { + /* ── 品牌色 · Qt 绿(亮)── */ + --vp-c-brand-1: #2EA66A; + --vp-c-brand-2: #1F8A55; + --vp-c-brand-3: #52BF85; + --vp-c-brand-soft: rgba(46, 166, 106, 0.10); + --vp-c-brand: var(--vp-c-brand-1); + + /* ── 背景 · 骨白(借 anatomy)── */ + --vp-c-bg: #F7F3EC; + --vp-c-bg-soft: #EFE8DC; + --vp-c-bg-soft-up: #FBF8F2; + --vp-c-bg-elv: #FFFCF7; + + /* ── 文字 · 深炭 ── */ + --vp-c-text-1: #2A2622; + --vp-c-text-2: #5C544D; + --vp-c-text-3: #8A8077; + + /* ── 分隔 / 边框 ── */ + --vp-c-divider: #E0D8CC; + --vp-c-border: #D6CDBF; + + /* ── 三层强调(首页 feature 卡分色,避开品牌绿)── */ + --aq-c-eng-1: #C8843C; /* 工程篇 · 琥珀 */ + --aq-c-eng-2: #A66825; + --aq-c-eng-soft: rgba(200, 132, 60, 0.10); + --aq-c-dom-1: #4F5BD5; /* 领域篇 · 靛 */ + --aq-c-dom-2: #3A47B0; + --aq-c-dom-soft: rgba(79, 91, 213, 0.10); + + /* ── CJK 字体栈 ── */ + --vp-font-family: system-ui, -apple-system, 'Segoe UI', Roboto, + 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑', + 'Source Han Sans SC', 'Noto Sans CJK SC', sans-serif; +} + +.dark { + /* ── 品牌色 · Qt 绿(暗色提亮)── */ + --vp-c-brand-1: #52BF85; + --vp-c-brand-2: #6FCF9C; + --vp-c-brand-3: #8ADDB5; + --vp-c-brand-soft: rgba(82, 191, 133, 0.16); + + /* ── 背景 · 炭墨 ── */ + --vp-c-bg: #161412; + --vp-c-bg-soft: #1F1B18; + --vp-c-bg-soft-up: #24201D; + --vp-c-bg-elv: #24201D; + + /* ── 文字 · 暖灰 ── */ + --vp-c-text-1: #E0D8CA; + --vp-c-text-2: #B5AC9E; + --vp-c-text-3: #7F776C; + + /* ── 分隔 / 边框 ── */ + --vp-c-divider: #332E29; + --vp-c-border: #3D3733; + + /* ── 三层强调(暗色提亮)── */ + --aq-c-eng-1: #E0A052; + --aq-c-eng-2: #C8843C; + --aq-c-eng-soft: rgba(224, 160, 82, 0.16); + --aq-c-dom-1: #7B8AF0; + --aq-c-dom-2: #5C6CD9; + --aq-c-dom-soft: rgba(123, 138, 240, 0.16); +} + /* Chinese Typography */ .vp-doc { line-height: 1.85; @@ -67,7 +140,7 @@ .vp-doc blockquote { border-left: 4px solid var(--vp-c-brand-1); border-radius: 0 4px 4px 0; - background: rgba(81, 107, 232, 0.04); + background: var(--vp-c-brand-soft); } /* Links */ @@ -120,7 +193,7 @@ background: linear-gradient(135deg, var(--vp-c-brand-soft) 0%, transparent 50%, - var(--vp-c-indigo-soft) 100%); + var(--vp-c-brand-soft) 100%); opacity: 0.5; pointer-events: none; } @@ -128,8 +201,8 @@ .VPHero .name.clip { background: linear-gradient(135deg, var(--vp-c-brand-1) 0%, - var(--vp-c-indigo-1) 50%, - var(--vp-c-purple-1) 100%); + var(--vp-c-brand-2) 50%, + var(--vp-c-brand-3) 100%); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; @@ -251,7 +324,7 @@ border-radius: 12px !important; background: linear-gradient(135deg, var(--vp-c-brand-soft) 0%, - var(--vp-c-indigo-soft) 100%) !important; + var(--vp-c-brand-soft) 100%) !important; color: var(--vp-c-brand-1) !important; font-size: 22px !important; transition: background 0.39s ease, @@ -296,56 +369,56 @@ transform: translateX(4px); } -/* ── Tier Color Coding: Core (1-4) ─ Brand/Indigo ────────────── */ +/* ── Tier Color Coding: Core (1-4) ─ Qt 绿(品牌)────────────── */ .VPFeatures .item:nth-child(-n+4) .VPFeature .icon { - background: linear-gradient(135deg, var(--vp-c-brand-soft), var(--vp-c-indigo-soft)) !important; + background: linear-gradient(135deg, var(--vp-c-brand-soft), var(--vp-c-brand-soft)) !important; color: var(--vp-c-brand-1) !important; } .VPFeatures .item:nth-child(-n+4) .VPFeature.link:hover .icon { - background: linear-gradient(135deg, var(--vp-c-brand-1), var(--vp-c-indigo-1)) !important; + background: linear-gradient(135deg, var(--vp-c-brand-1), var(--vp-c-brand-2)) !important; color: var(--vp-c-white) !important; } -/* ── Tier Color Coding: Engineering (5-7) ─ Green ────────────── */ +/* ── Tier Color Coding: Engineering (5-7) ─ 琥珀 ─────────────── */ .VPFeatures .item:nth-child(n+5):nth-child(-n+7) .VPFeature .icon { - background: linear-gradient(135deg, var(--vp-c-green-soft), rgba(16, 185, 129, 0.08)) !important; - color: var(--vp-c-green-1) !important; + background: linear-gradient(135deg, var(--aq-c-eng-soft), var(--aq-c-eng-soft)) !important; + color: var(--aq-c-eng-1) !important; } .VPFeatures .item:nth-child(n+5):nth-child(-n+7) .VPFeature.link:hover .icon { - background: linear-gradient(135deg, var(--vp-c-green-1), var(--vp-c-green-2)) !important; + background: linear-gradient(135deg, var(--aq-c-eng-1), var(--aq-c-eng-2)) !important; color: var(--vp-c-white) !important; } .VPFeatures .item:nth-child(n+5):nth-child(-n+7) .VPFeature.link:hover { - border-color: var(--vp-c-green-1) !important; + border-color: var(--aq-c-eng-1) !important; } .VPFeatures .item:nth-child(n+5):nth-child(-n+7) .VPFeature.link:hover .title { - color: var(--vp-c-green-1) !important; + color: var(--aq-c-eng-1) !important; } -/* ── Tier Color Coding: Domain (8-12) ─ Purple ───────────────── */ +/* ── Tier Color Coding: Domain (8-12) ─ 靛 ───────────────────── */ .VPFeatures .item:nth-child(n+8) .VPFeature .icon { - background: linear-gradient(135deg, var(--vp-c-purple-soft), rgba(159, 122, 234, 0.08)) !important; - color: var(--vp-c-purple-1) !important; + background: linear-gradient(135deg, var(--aq-c-dom-soft), var(--aq-c-dom-soft)) !important; + color: var(--aq-c-dom-1) !important; } .VPFeatures .item:nth-child(n+8) .VPFeature.link:hover .icon { - background: linear-gradient(135deg, var(--vp-c-purple-1), var(--vp-c-purple-2)) !important; + background: linear-gradient(135deg, var(--aq-c-dom-1), var(--aq-c-dom-2)) !important; color: var(--vp-c-white) !important; } .VPFeatures .item:nth-child(n+8) .VPFeature.link:hover { - border-color: var(--vp-c-purple-1) !important; + border-color: var(--aq-c-dom-1) !important; } .VPFeatures .item:nth-child(n+8) .VPFeature.link:hover .title { - color: var(--vp-c-purple-1) !important; + color: var(--aq-c-dom-1) !important; } /* ── Dark Mode ───────────────────────────────────────────────── */ @@ -517,7 +590,7 @@ /* ── Content Dark Mode ─────────────────────────────────────────── */ .dark .vp-doc blockquote { - background: rgba(81, 107, 232, 0.08); + background: var(--vp-c-brand-soft); } .dark .vp-doc table tr:nth-child(even) { @@ -772,3 +845,73 @@ html[data-font-size='large'] { html[data-font-size='xxlarge'] { zoom: 1.16; } + +/* ================================================================ + 可拖拽侧栏 · ResizableSidebar(左右栏宽度可拖动调整,双击重置) + --vp-sidebar-width 由 VitePress 全链路消费;--vp-aside-width 控右大纲栏。 + 宽度首屏防闪由 shared.ts head 内联脚本注入;组件运行时再读写 localStorage。 + ================================================================ */ +:root { + --vp-sidebar-width: 272px; + --vp-aside-width: 256px; +} + +.VPDoc.has-aside .aside { + width: var(--vp-aside-width); + max-width: var(--vp-aside-width); +} + +.rs-handle { + position: fixed; + top: var(--vp-nav-height, 64px); + bottom: 0; + width: 6px; + cursor: col-resize; + z-index: 50; + background: transparent; + transition: background 0.2s ease, opacity 0.2s ease; +} + +.rs-handle:hover, +.rs-handle.is-active { + background: var(--vp-c-brand-1); + opacity: 0.45; +} + +.rs-handle.is-active { + opacity: 0.65; +} + +.rs-handle--right { + position: absolute; + top: 0; + right: -3px; + bottom: 0; + width: 6px; +} + +body.rs-resizing { + user-select: none; + cursor: col-resize; +} + +body.rs-resizing * { + pointer-events: none !important; +} + +@media (max-width: 959px) { + .rs-handle { + display: none !important; + } +} + +/* ================================================================ + code-group tabs —— hover 着色(借 anatomy_gui) + ================================================================ */ +.vp-code-group .tabs label { + transition: color 0.2s ease, border-color 0.2s ease; +} + +.vp-code-group .tabs label:hover { + color: var(--vp-c-brand-1); +} diff --git a/site/.vitepress/theme/index.ts b/site/.vitepress/theme/index.ts index 9152930d..5d0ac844 100644 --- a/site/.vitepress/theme/index.ts +++ b/site/.vitepress/theme/index.ts @@ -7,6 +7,11 @@ import CardGrid from './components/CardGrid.vue' import CardLink from './components/CardLink.vue' import FontSizeSwitcher from './components/FontSizeSwitcher.vue' import ScreenshotCarousel from './components/ScreenshotCarousel.vue' +import QtHero from './components/QtHero.vue' +import ResizableSidebar from './components/ResizableSidebar.vue' +import ReadingProgress from './components/ReadingProgress.vue' +import ModuleCard from './components/ModuleCard.vue' +import ChapterHero from './components/ChapterHero.vue' import { setupMermaid } from './mermaid-client' import './custom.css' @@ -14,8 +19,12 @@ export default { extends: DefaultTheme, Layout() { return h(DefaultTheme.Layout, null, { + // 自定义首页 Hero(替代默认 VPHero,读 frontmatter.hero) + 'home-hero-before': () => h(QtHero), 'home-features-before': () => h(ScreenshotCarousel), 'home-features-after': () => h(HomeRoadmap), + // 顶部阅读进度条 + 可拖拽侧栏(左右栏宽度) + 'layout-top': () => [h(ReadingProgress), h(ResizableSidebar)], // 字号切换器:桌面顶栏右侧 + 移动端汉堡菜单展开后 'nav-bar-content-after': () => h(FontSizeSwitcher), 'nav-screen-content-after': () => h(FontSizeSwitcher), @@ -28,5 +37,7 @@ export default { app.component('HomeMeta', HomeMeta) app.component('CardGrid', CardGrid) app.component('CardLink', CardLink) + app.component('ModuleCard', ModuleCard) + app.component('ChapterHero', ChapterHero) }, } satisfies Theme diff --git a/site/.vitepress/theme/mermaid-client.ts b/site/.vitepress/theme/mermaid-client.ts index 1412143d..3a6a81b1 100644 --- a/site/.vitepress/theme/mermaid-client.ts +++ b/site/.vitepress/theme/mermaid-client.ts @@ -1,25 +1,20 @@ import { nextTick, onMounted, watch } from 'vue' import { useData, useRouter } from 'vitepress' -declare global { - interface Window { - mermaid?: { - initialize: (config: Record) => void - render: (id: string, text: string) => Promise<{ svg: string; bindFunctions?: (el: Element) => void }> - } - __mermaidLoadingPromise__?: Promise - } -} - -// 沿用与 ModernCPP 一致的 CDN 运行时方案(站点本身需联网访问)。 -// 注意:cdn.jsdelivr.net 自 2022.5 起在大陆被墙;若收到国内读者反馈图表加载失败, -// 可把此 URL 换成 npmmirror 镜像,或把 mermaid.min.js 放进 site/public/ 自托管。 -const MERMAID_CDN = 'https://cdn.jsdelivr.net/npm/mermaid@10.9.6/dist/mermaid.min.js' +// 本地打包 mermaid:dynamic import 客户端懒加载,SSR 不引入。Vite 自动 code-split 成独立 chunk。 +// 不走 CDN —— 浏览器加载跨域 CDN 脚本不可靠(onload 永不触发会卡骨架)。 type MermaidTheme = 'default' | 'dark' +let mermaidApi: any = null let currentTheme: MermaidTheme | null = null +async function ensureMermaid(): Promise { + if (mermaidApi) return mermaidApi + mermaidApi = (await import('mermaid')).default + return mermaidApi +} + function mermaidConfig(theme: MermaidTheme): Record { return { startOnLoad: false, @@ -39,6 +34,14 @@ function mermaidConfig(theme: MermaidTheme): Record { } } +/** 按当前主题初始化 mermaid;主题变化时重新 initialize(initialize 本身不重绘已有 SVG)。 */ +async function ensureInitialized(theme: MermaidTheme): Promise { + const m = await ensureMermaid() + if (currentTheme === theme) return + m.initialize(mermaidConfig(theme)) + currentTheme = theme +} + function escapeHtml(s: string): string { return s .replaceAll('&', '&') @@ -48,68 +51,29 @@ function escapeHtml(s: string): string { .replaceAll("'", ''') } -function loadMermaid(): Promise { - if (typeof window === 'undefined') return Promise.resolve() - - if (window.mermaid) return Promise.resolve() - if (window.__mermaidLoadingPromise__) return window.__mermaidLoadingPromise__ - - window.__mermaidLoadingPromise__ = new Promise((resolve, reject) => { - const existing = document.querySelector('script[data-mermaid-runtime]') - if (existing) { - existing.addEventListener('load', () => resolve()) - existing.addEventListener('error', () => reject(new Error('Failed to load Mermaid'))) - return - } - - const script = document.createElement('script') - script.src = MERMAID_CDN - script.async = true - script.dataset.mermaidRuntime = 'true' - script.onload = () => resolve() - script.onerror = () => reject(new Error(`Failed to load Mermaid from ${MERMAID_CDN}`)) - document.head.appendChild(script) - }) - - return window.__mermaidLoadingPromise__ -} - -/** 按当前主题初始化 mermaid;主题变化时重新 initialize(initialize 本身不重绘已有 SVG)。 */ -function ensureInitialized(theme: MermaidTheme): void { - const mermaid = window.mermaid - if (!mermaid || currentTheme === theme) return - mermaid.initialize(mermaidConfig(theme)) - currentTheme = theme -} - async function renderMermaidDiagrams(theme: MermaidTheme): Promise { if (typeof window === 'undefined') return try { - await loadMermaid() - } catch { - // CDN 加载失败:把所有未渲染的图降级成源码兜底,而不是抛未捕获的 Promise rejection。 - document - .querySelectorAll('.mermaid-diagram[data-rendered="false"]') - .forEach((el) => { - const raw = el.dataset.mermaid - el.dataset.rendered = 'error' - if (raw) el.innerHTML = `
${escapeHtml(decodeURIComponent(raw))}
` - }) + await ensureInitialized(theme) + } catch (e) { + console.error('[mermaid] init failed', e) return } await nextTick() - await new Promise((r) => requestAnimationFrame(() => r())) - const mermaid = window.mermaid - if (!mermaid) return - - ensureInitialized(theme) - - const nodes = Array.from( - document.querySelectorAll('.mermaid-diagram[data-rendered="false"]') - ) + // SPA 路由切换:VitePress 的 onAfterRouteChange 在 loadPage(设 route.component)之后立即触发, + // 但 Vue 把新页 component 渲染进 DOM 是异步的——触发那一刻新页的 mermaid 占位 div 还没挂载, + // 一次 nextTick 等不到。轮询等节点出现,最多 ~1.5s;直载(onMounted)时内容已在 DOM,首次即命中。 + let nodes: HTMLElement[] = [] + for (let attempt = 0; attempt < 15; attempt++) { + nodes = Array.from( + document.querySelectorAll('.mermaid-diagram[data-rendered="false"]') + ) + if (nodes.length > 0) break + await new Promise((r) => setTimeout(r, 100)) + } for (let i = 0; i < nodes.length; i++) { const el = nodes[i] @@ -120,12 +84,14 @@ async function renderMermaidDiagrams(theme: MermaidTheme): Promise { const id = `mermaid-${Date.now()}-${i}-${Math.random().toString(36).slice(2, 8)}` try { - const { svg } = await mermaid.render(id, source) + const m = await ensureMermaid() + const { svg } = await m.render(id, source) el.innerHTML = svg el.dataset.rendered = 'true' - } catch { + } catch (e) { el.dataset.rendered = 'error' el.innerHTML = `
${escapeHtml(source)}
` + console.error('[mermaid] render failed for:\n' + source, e) } } }