[{"data":1,"prerenderedAt":2089},["ShallowReactive",2],{"navigation":3,"blogNavigation":148,"site-search":320,"page-\u002Fdocs\u002Fabout":2073,"\u002Fdocs\u002Fabout-surround":2088},[4],{"title":5,"path":6,"stem":7,"children":8,"page":53},"Docs","\u002Fdocs","docs",[9,139],{"title":10,"path":11,"stem":12,"children":13,"icon":138},"简单文档","\u002Fdocs\u002F简单文档","docs\u002F1.简单文档\u002F1.index",[14,17,22,54,59],{"title":15,"path":11,"stem":12,"icon":16},"入门简介","lucide-house",{"title":18,"path":19,"stem":20,"icon":21},"安装指南","\u002Fdocs\u002F简单文档\u002Finstallation","docs\u002F1.简单文档\u002F2.installation","lucide-play",{"title":23,"icon":24,"path":25,"stem":26,"children":27,"page":53},"开始写作","lucide:edit","\u002Fdocs\u002F简单文档\u002Fwriting","docs\u002F1.简单文档\u002F3.writing",[28,33,38,43,48],{"title":29,"path":30,"stem":31,"icon":32},"Markdown","\u002Fdocs\u002F简单文档\u002Fwriting\u002Fmarkdown","docs\u002F1.简单文档\u002F3.writing\u002F1.markdown","lucide:arrow-big-down",{"title":34,"path":35,"stem":36,"icon":37},"页面","\u002Fdocs\u002F简单文档\u002Fwriting\u002Fpages","docs\u002F1.简单文档\u002F3.writing\u002F2.pages","lucide:file-text",{"title":39,"path":40,"stem":41,"icon":42},"目录","\u002Fdocs\u002F简单文档\u002Fwriting\u002Ffolders","docs\u002F1.简单文档\u002F3.writing\u002F3.folders","lucide:folder",{"title":44,"path":45,"stem":46,"icon":47},"单页面示例","\u002Fdocs\u002F简单文档\u002Fwriting\u002Ffull-page-example","docs\u002F1.简单文档\u002F3.writing\u002F4.full-page-example","lucide:layout-template",{"title":49,"path":50,"stem":51,"icon":52},"markdown 常用语法","\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest","docs\u002F1.简单文档\u002F3.writing\u002F5.test","simple-icons:markdown",false,{"title":55,"path":56,"stem":57,"icon":58},"部署服务","\u002Fdocs\u002F简单文档\u002Fdeployment","docs\u002F1.简单文档\u002F4.deployment","lucide:cloud",{"title":60,"icon":61,"path":62,"stem":63,"children":64,"page":53},"组件特性","lucide:box","\u002Fdocs\u002F简单文档\u002Fcomponents","docs\u002F1.简单文档\u002F5.components",[65,70,74,78,82,86,90,94,98,102,106,110,114,118,122,126,130,134],{"title":66,"path":67,"stem":68,"icon":69},"常用组件","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fapi","docs\u002F1.简单文档\u002F5.components\u002F1.API","lucide-component",{"title":71,"path":72,"stem":73},"Alert","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Falert","docs\u002F1.简单文档\u002F5.components\u002Falert",{"title":75,"path":76,"stem":77},"Badge","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fbadge","docs\u002F1.简单文档\u002F5.components\u002Fbadge",{"title":79,"path":80,"stem":81},"Button Link","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fbutton-link","docs\u002F1.简单文档\u002F5.components\u002Fbutton-link",{"title":83,"path":84,"stem":85},"Callout","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fcallout","docs\u002F1.简单文档\u002F5.components\u002Fcallout",{"title":87,"path":88,"stem":89},"Card","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fcard","docs\u002F1.简单文档\u002F5.components\u002Fcard",{"title":91,"path":92,"stem":93},"Card Group","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fcard-group","docs\u002F1.简单文档\u002F5.components\u002Fcard-group",{"title":95,"path":96,"stem":97},"Code Group","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fcode-group","docs\u002F1.简单文档\u002F5.components\u002Fcode-group",{"title":99,"path":100,"stem":101},"Code Tree","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fcode-tree","docs\u002F1.简单文档\u002F5.components\u002Fcode-tree",{"title":103,"path":104,"stem":105},"Field","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ffield","docs\u002F1.简单文档\u002F5.components\u002Ffield",{"title":107,"path":108,"stem":109},"Field Group","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ffield-group","docs\u002F1.简单文档\u002F5.components\u002Ffield-group",{"title":111,"path":112,"stem":113},"File Tree","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ffile-tree","docs\u002F1.简单文档\u002F5.components\u002Ffile-tree",{"title":115,"path":116,"stem":117},"Icon","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ficon","docs\u002F1.简单文档\u002F5.components\u002Ficon",{"title":119,"path":120,"stem":121},"Playground","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fplayground","docs\u002F1.简单文档\u002F5.components\u002Fplayground",{"title":123,"path":124,"stem":125},"Read More","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fread-more","docs\u002F1.简单文档\u002F5.components\u002Fread-more",{"title":127,"path":128,"stem":129},"Stack","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fstack","docs\u002F1.简单文档\u002F5.components\u002Fstack",{"title":131,"path":132,"stem":133},"Steps","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fsteps","docs\u002F1.简单文档\u002F5.components\u002Fsteps",{"title":135,"path":136,"stem":137},"Tabs","\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ftabs","docs\u002F1.简单文档\u002F5.components\u002Ftabs","lucide-book-open-text",{"title":140,"path":141,"stem":142,"children":143,"icon":147},"无人自助系统","\u002Fdocs\u002F无人自助系统","docs\u002F2.无人自助系统\u002F1.index",[144],{"title":145,"path":141,"stem":142,"icon":146},"介绍","simple-icons:opencollective","simple-icons:monica",[149],{"title":150,"path":151,"stem":152,"children":153,"page":53},"Blog","\u002Fblog","blog",[154,301,311],{"title":155,"icon":156,"path":157,"stem":158,"children":159,"page":53},"技术栈","devicon:prolog","\u002Fblog\u002F技术栈","blog\u002F1.技术栈",[160,165,169,174,178,183,188,192,197,202,207,211,215,219,224,228,233,238,243,247,252,257,262,267,272,276,281,286,291,296],{"title":161,"path":162,"stem":163,"icon":164},"准备新的插件","\u002Fblog\u002F技术栈\u002F新的插件","blog\u002F1.技术栈\u002F970.新的插件","simple-icons:debian",{"title":166,"path":167,"stem":168,"icon":164},"防于未然，先固不破 — Debian 12 快速加固实战","\u002Fblog\u002F技术栈\u002F服务器加固实战","blog\u002F1.技术栈\u002F971.服务器加固实战",{"title":170,"path":171,"stem":172,"icon":173},"nmap高级应用技巧-实战","\u002Fblog\u002F技术栈\u002Fnmap高级应用技巧-实战","blog\u002F1.技术栈\u002F972.nmap高级应用技巧-实战","simple-icons:openstreetmap",{"title":175,"path":176,"stem":177,"icon":173},"nmap高级应用技巧-NSE","\u002Fblog\u002F技术栈\u002Fnmap高级应用技巧-nse","blog\u002F1.技术栈\u002F973.nmap高级应用技巧-NSE",{"title":179,"path":180,"stem":181,"icon":182},"部分vue组件语法预览","\u002Fblog\u002F技术栈\u002F部分组件语法展示","blog\u002F1.技术栈\u002F974.部分组件语法展示","simple-icons:vuedotjs",{"title":184,"path":185,"stem":186,"icon":187},"新的文档渲染样式","\u002Fblog\u002F技术栈\u002F新的文档渲染样式","blog\u002F1.技术栈\u002F975.新的文档渲染样式","simple-icons:nuxtdotjs",{"title":189,"path":190,"stem":191,"icon":187},"Nuxt 微信分享接口","\u002Fblog\u002F技术栈\u002Fnuxt-微信分享接口","blog\u002F1.技术栈\u002F976.Nuxt 微信分享接口",{"title":193,"path":194,"stem":195,"icon":196},"AI复合应用 合同审查","\u002Fblog\u002F技术栈\u002Fai复合应用-合同审查","blog\u002F1.技术栈\u002F978.AI复合应用 合同审查","simple-icons:openai",{"title":198,"path":199,"stem":200,"icon":201},"Kali 安装 GVM","\u002Fblog\u002F技术栈\u002Fkali-安装-gvm","blog\u002F1.技术栈\u002F979.Kali 安装 GVM","simple-icons:kalilinux",{"title":203,"path":204,"stem":205,"icon":206},"GPT-5","\u002Fblog\u002F技术栈\u002Fgpt5","blog\u002F1.技术栈\u002F980.GPT5","simple-icons:powershell",{"title":208,"path":209,"stem":210,"icon":196},"使用 AI 守护内网安全","\u002Fblog\u002F技术栈\u002F使用-ai-守护内网安全","blog\u002F1.技术栈\u002F981.使用 AI 守护内网安全",{"title":212,"path":213,"stem":214,"icon":173},"系统安全扫描工具命令集合","\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合","blog\u002F1.技术栈\u002F982.系统安全扫描工具命令集合",{"title":216,"path":217,"stem":218,"icon":201},"系统安全综合评估报告","\u002Fblog\u002F技术栈\u002F系统安全综合评估报告","blog\u002F1.技术栈\u002F983.系统安全综合评估报告",{"title":220,"path":221,"stem":222,"icon":223},"树莓派安装 Kali Linux","\u002Fblog\u002F技术栈\u002F树莓派安装-kali-linux","blog\u002F1.技术栈\u002F984.树莓派安装 Kali Linux","simple-icons:raspberrypi",{"title":225,"path":226,"stem":227,"icon":187},"Nuxt UI Pro","\u002Fblog\u002F技术栈\u002Fnuxt-ui-pro","blog\u002F1.技术栈\u002F985.Nuxt UI Pro",{"title":229,"path":230,"stem":231,"icon":232},"Supabase 阿里云短信","\u002Fblog\u002F技术栈\u002Fsupabase-阿里云短信","blog\u002F1.技术栈\u002F986.Supabase 阿里云短信","simple-icons:alibabacloud",{"title":234,"path":235,"stem":236,"icon":237},"Coolify","\u002Fblog\u002F技术栈\u002Fcoolify","blog\u002F1.技术栈\u002F987.Coolify","simple-icons:chai",{"title":239,"path":240,"stem":241,"icon":242},"Python 代码规范","\u002Fblog\u002F技术栈\u002Fpython-代码规范","blog\u002F1.技术栈\u002F988.Python 代码规范","simple-icons:python",{"title":244,"path":245,"stem":246,"icon":187},"Nuxt3 代码规范","\u002Fblog\u002F技术栈\u002Fnuxt3-代码规范","blog\u002F1.技术栈\u002F989.Nuxt3 代码规范",{"title":248,"path":249,"stem":250,"icon":251},"Linux 系统 Swap 分区配置指南","\u002Fblog\u002F技术栈\u002Flinux-系统-swap-分区配置指南","blog\u002F1.技术栈\u002F990.Linux 系统 Swap 分区配置指南","simple-icons:linux",{"title":253,"path":254,"stem":255,"icon":256},"从Supabase迁移到Appwrite","\u002Fblog\u002F技术栈\u002F从supabase迁移到appwrite","blog\u002F1.技术栈\u002F991.从Supabase迁移到Appwrite","simple-icons:supabase",{"title":258,"path":259,"stem":260,"icon":261},"AppWrite 项目资源占用情况","\u002Fblog\u002F技术栈\u002Fappwrite-项目资源占用情况","blog\u002F1.技术栈\u002F992.AppWrite 项目资源占用情况","simple-icons:appwrite",{"title":263,"path":264,"stem":265,"icon":266},"Docker 里配置hosts","\u002Fblog\u002F技术栈\u002Fdocker-里配置hosts","blog\u002F1.技术栈\u002F993.Docker 里配置hosts","simple-icons:docker",{"title":268,"path":269,"stem":270,"icon":271},"MySQL 中如何忽略表名的大小写","\u002Fblog\u002F技术栈\u002Fmysql-中如何忽略表名的大小写","blog\u002F1.技术栈\u002F994.MySQL 中如何忽略表名的大小写","simple-icons:mysql",{"title":273,"path":274,"stem":275,"icon":164},"Debian 12 安装nodejs","\u002Fblog\u002F技术栈\u002Fdebian-12-安装nodejs","blog\u002F1.技术栈\u002F995.Debian 12 安装nodejs",{"title":277,"path":278,"stem":279,"icon":280},"Dify + Supabase：打造带数据库的AI问答机器人","\u002Fblog\u002F技术栈\u002Fdify-supabase：打造带数据库的ai问答机器人","blog\u002F1.技术栈\u002F996.Dify + Supabase：打造带数据库的AI问答机器人","simple-icons:reactbootstrap",{"title":282,"path":283,"stem":284,"icon":285},"安装 VS Code到浏览器 -- Code Server","\u002Fblog\u002F技术栈\u002F安装-vs-code到浏览器-code-server-copy","blog\u002F1.技术栈\u002F996.安装 VS Code到浏览器 -- Code Server copy","simple-icons:visualstudiocode",{"title":287,"path":288,"stem":289,"icon":290},"Debian 12 云服务器初始安全设置与优化指南","\u002Fblog\u002F技术栈\u002Fdebian-12-云服务器初始安全设置与优化指南","blog\u002F1.技术栈\u002F997.Debian 12 云服务器初始安全设置与优化指南","lucide-server",{"title":292,"path":293,"stem":294,"icon":295},"Iperf3 万兆网络打流测试指南","\u002Fblog\u002F技术栈\u002Fiperf3-万兆网络打流测试指南","blog\u002F1.技术栈\u002F998.Iperf3 万兆网络打流测试指南","lucide-network",{"title":297,"path":298,"stem":299,"icon":300},"GROK3 and Deepseek","\u002Fblog\u002F技术栈\u002Fgrok3-and-deepseek","blog\u002F1.技术栈\u002F999.GROK3-and-Deepseek","lucide-brain",{"title":302,"icon":303,"path":304,"stem":305,"children":306,"page":53},"AI","devicon:streamlit","\u002Fblog\u002Fai","blog\u002F2.AI",[307],{"title":308,"path":309,"stem":310,"icon":237},"AI最佳实践","\u002Fblog\u002Fai\u002Fai","blog\u002F2.AI\u002F01.AI",{"title":312,"icon":313,"path":314,"stem":315,"children":316,"page":53},"生活","devicon:love2d","\u002Fblog\u002F生活","blog\u002F3.生活",[317],{"title":312,"path":318,"stem":319,"icon":237},"\u002Fblog\u002F生活\u002F生活","blog\u002F3.生活\u002F01.生活",[321,325,330,336,341,346,349,354,357,362,368,373,377,382,385,390,395,398,403,406,409,413,418,422,426,430,435,440,446,451,456,461,466,471,476,481,486,490,495,500,505,510,515,518,523,528,531,533,538,543,548,553,558,560,564,568,572,576,578,582,586,589,591,595,599,604,609,613,615,619,623,625,629,633,635,639,643,645,649,653,655,659,661,665,670,675,680,684,687,691,696,698,701,706,711,715,717,721,725,727,731,733,737,742,746,748,752,757,762,767,772,776,779,784,787,790,795,799,804,809,814,819,824,829,834,839,844,847,852,855,859,864,869,874,878,881,884,889,893,898,903,907,911,916,921,924,928,932,935,939,943,947,951,956,959,963,968,972,977,980,985,990,995,998,1003,1008,1013,1018,1023,1028,1033,1038,1041,1045,1049,1054,1059,1064,1068,1073,1077,1082,1087,1092,1095,1099,1103,1106,1110,1114,1119,1124,1128,1133,1138,1143,1147,1152,1156,1161,1166,1170,1175,1179,1184,1188,1193,1197,1202,1206,1211,1216,1221,1225,1230,1235,1240,1243,1248,1253,1256,1259,1262,1265,1270,1273,1278,1282,1286,1290,1294,1299,1304,1309,1314,1317,1321,1325,1330,1334,1339,1344,1349,1354,1359,1363,1368,1373,1378,1383,1388,1392,1397,1402,1406,1411,1416,1420,1425,1430,1434,1439,1443,1448,1453,1455,1458,1461,1464,1467,1470,1473,1476,1479,1482,1485,1488,1491,1494,1497,1500,1503,1506,1509,1512,1515,1518,1521,1524,1527,1530,1533,1536,1539,1542,1545,1548,1553,1558,1563,1568,1573,1578,1583,1588,1591,1596,1601,1606,1610,1615,1620,1625,1630,1635,1640,1643,1648,1653,1658,1663,1665,1670,1673,1678,1683,1686,1689,1694,1699,1704,1709,1714,1719,1724,1729,1734,1738,1743,1748,1753,1758,1763,1766,1771,1775,1780,1785,1789,1794,1799,1803,1808,1813,1817,1822,1827,1831,1836,1841,1846,1850,1855,1860,1863,1866,1869,1872,1875,1878,1881,1884,1887,1890,1893,1896,1899,1902,1905,1908,1911,1914,1917,1920,1923,1926,1929,1932,1935,1938,1941,1944,1947,1950,1953,1956,1959,1962,1965,1968,1971,1974,1977,1980,1983,1986,1989,1993,1997,2002,2007,2011,2016,2021,2026,2031,2035,2040,2044,2049,2054,2057,2061,2063,2067,2069],{"id":11,"title":15,"titles":322,"content":323,"level":324},[],"Estel Docs 是一个基于 Nuxt 4 , Content v3 , Nuxt UI Pro 构建的文档系统。",1,{"id":326,"title":327,"titles":328,"content":329,"level":324},"\u002Fdocs\u002F简单文档#缘起","缘起",[],"使用过市面上的很多文档系统，但是或多或少都有一些自己不满意的功能.\n于是自己动手，丰衣足食.\n同时在 Markdown 语法的基础上增加了许多魔法(自定义组件),比如: 在 Markdown 中使用::card 标签,即可创建一个卡片,卡片里可以放置任何内容。比如以下内容:\n::card\n这里是卡片里的内容\n::\n\u003C!-- Card组件: components\u002Fcontent\u002FCard.vue -->\n\u003Ctemplate>\n  \u003Cdiv class=\"p-2 border bg-white dark:bg-black dark:border-gray-700 rounded\">\n    \u003Cslot \u002F>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n这里是卡片里的内容 @import \"tailwindcss\" theme(static);\n@import \"@nuxt\u002Fui-pro\";\nexport default defineAppConfig({\n  ui: {\n    colors: {\n      primary: 'sky',\n      colors: 'slate'\n    }\n  }\n});\n\u003Ctemplate>\n  \u003CUApp>\n    \u003CNuxtPage \u002F>\n  \u003C\u002FUApp>\n\u003C\u002Ftemplate>\n{\n  \"name\": \"nuxt-app\",\n  \"private\": true,\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"nuxt build\",\n    \"dev\": \"nuxt dev\",\n    \"generate\": \"nuxt generate\",\n    \"preview\": \"nuxt preview\",\n    \"postinstall\": \"nuxt prepare\",\n    \"typecheck\": \"nuxt typecheck\"\n  },\n  \"dependencies\": {\n    \"@iconify-json\u002Flucide\": \"^1.2.18\",\n    \"@nuxt\u002Fui-pro\": \"3.0.0-alpha.10\",\n    \"nuxt\": \"^3.15.1\"\n  },\n  \"devDependencies\": {\n    \"typescript\": \"^5.7.2\",\n    \"vue-tsc\": \"^2.2.0\"\n  }\n}\n{\n  \"extends\": \".\u002F.nuxt\u002Ftsconfig.json\"\n}\nexport default defineNuxtConfig({\n  modules: ['@nuxt\u002Fui-pro'],\n\n  future: {\n    compatibilityVersion: 4\n  },\n\n  css: ['~\u002Fassets\u002Fmain.css']\n});\n# Nuxt 3 Minimal Starter\n\nLook at the [Nuxt 3 documentation](https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fgetting-started\u002Fintroduction) to learn more.\n\n## Setup\n\nMake sure to install the dependencies:\n\n```bash\n# npm\nnpm install\n\n# pnpm\npnpm install\n\n# yarn\nyarn install\n\n# bun\nbun install\n```\n\n## Development Server\n\nStart the development server on `http:\u002F\u002Flocalhost:3000`:\n\n```bash\n# npm\nnpm run dev\n\n# pnpm\npnpm run dev\n\n# yarn\nyarn dev\n\n# bun\nbun run dev\n```\n\n## Production\n\nBuild the application for production:\n\n```bash\n# npm\nnpm run build\n\n# pnpm\npnpm run build\n\n# yarn\nyarn build\n\n# bun\nbun run build\n```\n\nLocally preview production build:\n\n```bash\n# npm\nnpm run preview\n\n# pnpm\npnpm run preview\n\n# yarn\nyarn preview\n\n# bun\nbun run preview\n```\n\nCheck out the [deployment documentation](https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fgetting-started\u002Fdeployment) for more information. #### 此组件打开一个模态搜索框,进行搜索\n  ::::example-fulltext-content-search\n  ::::\n\n#### 此组件建立一个mini搜索框,进行搜索\n  ::::example-fulltext-mini-search\n  :::: 阅读更多关于 自定义组件 的内容.",{"id":331,"title":332,"titles":333,"content":334,"level":335},"\u002Fdocs\u002F简单文档#特性","特性",[327],"基于 Nuxt 4 , Content v3 , Nuxt UI Pro 构建的文档系统。完美支持 Markdown 和 相关扩展。和 Vue 组件高度集成。支持搜索,由Content v3 赋能。支持多主题,使用Nuxt UI Pro。开源且免费。支持移动端。",2,{"id":337,"title":338,"titles":339,"content":340,"level":335},"\u002Fdocs\u002F简单文档#致谢","致谢",[327],"Nuxt Content：为 Vue 开发者简化内容管理。Nuxt UI Pro ：文档系统 UI 组件。Docus：获取灵感及一些文档组件源代码。",{"id":342,"title":343,"titles":344,"content":345,"level":335},"\u002Fdocs\u002F简单文档#license","License",[327],"MIT html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .ss7Ak, html code.shiki .ss7Ak{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit;--shiki-sepia:#88846F;--shiki-sepia-font-style:inherit}html pre.shiki code .sdE5Q, html code.shiki .sdE5Q{--shiki-light:#9C3EDA;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sYvgn, html code.shiki .sYvgn{--shiki-light:#39ADB5;--shiki-light-font-style:inherit;--shiki-default:#FDAEB7;--shiki-default-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic;--shiki-sepia:#F44747;--shiki-sepia-font-style:inherit}html pre.shiki code .sEIvO, html code.shiki .sEIvO{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#F97583;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit;--shiki-sepia:#F92672;--shiki-sepia-font-style:inherit}html pre.shiki code .sLcK_, html code.shiki .sLcK_{--shiki-light:#6182B8;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sHV4B, html code.shiki .sHV4B{--shiki-light:#E53935;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .ss27W, html code.shiki .ss27W{--shiki-light:#39ADB5;--shiki-light-font-style:inherit;--shiki-default:#79B8FF;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .szxyS, html code.shiki .szxyS{--shiki-light:#9C3EDA;--shiki-light-font-style:inherit;--shiki-default:#79B8FF;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .si2Vc, html code.shiki .si2Vc{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#CFCFC2}html pre.shiki code .sO9wW, html code.shiki .sO9wW{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#CFCFC2}html pre.shiki code .sQnY8, html code.shiki .sQnY8{--shiki-light:#39ADB5;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .stRg-, html code.shiki .stRg-{--shiki-light:#E2931D;--shiki-light-font-style:inherit;--shiki-default:#79B8FF;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .s516T, html code.shiki .s516T{--shiki-light:#F76D47;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .syccL, html code.shiki .syccL{--shiki-light:#39ADB5;--shiki-light-font-weight:inherit;--shiki-default:#79B8FF;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold;--shiki-sepia:#A6E22E;--shiki-sepia-font-weight:bold}html pre.shiki code .sxAGG, html code.shiki .sxAGG{--shiki-light:#E2931D;--shiki-light-font-weight:inherit;--shiki-default:#79B8FF;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold;--shiki-sepia:#A6E22E;--shiki-sepia-font-weight:bold}html pre.shiki code .slHBl, html code.shiki .slHBl{--shiki-light:#91B859;--shiki-light-text-decoration:inherit;--shiki-default:#DBEDFF;--shiki-default-text-decoration:underline;--shiki-dark:#DBEDFF;--shiki-dark-text-decoration:underline;--shiki-sepia:#AE81FF;--shiki-sepia-text-decoration:inherit}html pre.shiki code .svcTW, html code.shiki .svcTW{--shiki-light:#E53935;--shiki-light-text-decoration:underline;--shiki-default:#E1E4E8;--shiki-default-text-decoration:underline;--shiki-dark:#E1E4E8;--shiki-dark-text-decoration:underline;--shiki-sepia:#E6DB74;--shiki-sepia-text-decoration:inherit}html pre.shiki code .sy8J7, html code.shiki .sy8J7{--shiki-light:#91B859;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sxHrB, html code.shiki .sxHrB{--shiki-light:#90A4AE90;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sPYpf, html code.shiki .sPYpf{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .spiKf, html code.shiki .spiKf{--shiki-light:#39ADB5;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#FD971F}html pre.shiki code .sAWxV, html code.shiki .sAWxV{--shiki-light:#91B859;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#FD971F}",{"id":19,"title":18,"titles":347,"content":348,"level":324},[],"安装 Estel Docs",{"id":350,"title":351,"titles":352,"content":353,"level":335},"\u002Fdocs\u002F简单文档\u002Finstallation#安装与使用","安装与使用",[18],"1. 获取项目git clone https:\u002F\u002Fgithub.com\u002Festle-li\u002Festel_docs.git\n或者，您也可以从 GitHub 仓库 克隆或下载该模板。导航到项目目录cd [project-name]\n编译项目pnpm i && pnpm dev\nyarn install && yarn dev\nnpm install && npm run dev\nbun install && bun dev\n做得好！浏览器窗口应会自动打开，访问 http:\u002F\u002Flocalhost:3000。配置系统选择主题或根据个人喜好调整其他设置。 html pre.shiki code .sPYpf, html code.shiki .sPYpf{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .sunJZ, html code.shiki .sunJZ{--shiki-light:#6182B8;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#66D9EF}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}",{"id":30,"title":29,"titles":355,"content":356,"level":324},[],"如何使用MDC语法编写文档。 在Nuxt Content文档中阅读详细的MDC使用指南。查看shadcn-docs-nuxt提供的MDC组件。",{"id":358,"title":359,"titles":360,"content":361,"level":335},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Fmarkdown#vs-code集成","VS Code集成",[29],"",{"id":363,"title":364,"titles":365,"content":366,"level":367},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Fmarkdown#mdc扩展","MDC扩展",[29,359],"Nuxt MDC是一个VS Code扩展，为MDC语法提供语法高亮和自动完成功能。 启动VS Code快速打开  + ，粘贴以下命令，然后按回车。 ext install Nuxt.mdc",3,{"id":369,"title":370,"titles":371,"content":372,"level":367},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Fmarkdown#启用组件元数据自动完成","启用组件元数据自动完成",[29,359],"需要 Nuxt.mdc >= 0.3.1 VSCode设置{\n  \"mdc.enableComponentMetadataCompletions\": true}\n安装 nuxt-component-meta 模块将nuxt-component-meta依赖添加到您的项目中：将nuxt-component-meta添加到nuxt.config.ts的modules部分，并可选择配置模块：export default defineNuxtConfig({\n  modules: ['nuxt-component-meta'],\n});\n一旦您的项目构建完成或在开发服务器上运行，扩展将自动扫描您的项目以获取组件元数据，并根据发现的组件提供建议，无需额外配置。",{"id":374,"title":375,"titles":376,"content":361,"level":335},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Fmarkdown#技巧","技巧",[29],{"id":378,"title":379,"titles":380,"content":381,"level":367},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Fmarkdown#从目录中隐藏标题","从目录中隐藏标题",[29,375],"0.4.7 将标题的 id 设置为 hide-toc 将从目录中隐藏该标题。 :h2[脚注]{id=\"hide-toc\"} html pre.shiki code .sPYpf, html code.shiki .sPYpf{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .ss27W, html code.shiki .ss27W{--shiki-light:#39ADB5;--shiki-light-font-style:inherit;--shiki-default:#79B8FF;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .szxyS, html code.shiki .szxyS{--shiki-light:#9C3EDA;--shiki-light-font-style:inherit;--shiki-default:#79B8FF;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .sQnY8, html code.shiki .sQnY8{--shiki-light:#39ADB5;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .sEIvO, html code.shiki .sEIvO{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#F97583;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit;--shiki-sepia:#F92672;--shiki-sepia-font-style:inherit}html pre.shiki code .sLcK_, html code.shiki .sLcK_{--shiki-light:#6182B8;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sHV4B, html code.shiki .sHV4B{--shiki-light:#E53935;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html pre.shiki code .sdE5Q, html code.shiki .sdE5Q{--shiki-light:#9C3EDA;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}",{"id":35,"title":34,"titles":383,"content":384,"level":324},[],"Estel Docs 中使用的front matter属性。 ---\ntitle: Front Matter\ndescription: Estel Dsoc中使用的front matter属性。\nicon: lucide:book-type\n\nnavBadges:\n  - value: New\n    type: lime\n\nauthors:\n  - name: Tony Zhang\n    username: ZTL-UwU\n    avatar: https:\u002F\u002Fwww.github.com\u002FZTL-UwU.png\n    to: https:\u002F\u002Fgithub.com\u002FZTL-UwU\n    target: _blank\n---",{"id":386,"title":387,"titles":388,"content":389,"level":335},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Fpages#展示","展示",[34],"badges:\n  - value: 0.8.10\n  - value: Source\n    icon: lucide:code\n    to: https:\u002F\u002Fgithub.com\u002FZTL-UwU\u002Fshadcn-docs-nuxt\u002Fblob\u002Fmain\u002Fcomponents\u002Fcontent\u002FFileTree.vue\n    target: _blank\nauthors:\n  - name: Tony Zhang\n    username: ZTL-UwU\n    avatar: https:\u002F\u002Fwww.github.com\u002FZTL-UwU.png\n    to: https:\u002F\u002Fgithub.com\u002FZTL-UwU\n    target: _blank\nnavBadges:\n  - value: New\n    type: lime",{"id":391,"title":392,"titles":393,"content":394,"level":335},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Fpages#参数","参数",[34],"页面标题。默认为文件名。页面描述。默认为页面的第一个 \u003Cp>。定义页面是否包含在侧边栏中。在 index.md 中设置为 false。在侧边栏中为页面显示的图标。附加到侧边栏链接末尾的徽章列表。是否截断侧边栏标题。显示在页面标题底部的徽章列表。显示在页面标题底部的作者列表。是否为此页面显示目录部分。是否为此页面显示侧边栏部分。是否为此页面显示编辑链接。是否显示上一页和下一页按钮。是否显示面包屑导航。是否使用像主页一样的全页面布局。示例。 html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .s516T, html code.shiki .s516T{--shiki-light:#F76D47;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}",{"id":40,"title":39,"titles":396,"content":397,"level":324},[],"通过 YML 文件配置目录节点。 You can customize folders by creating a _dir.yml file in the folder. title: Folder\nicon: lucide:folder\nnavigation.redirect: \u002Fframeworks\u002Fvue\nnavBadges:\n  - value: New\n    type: lime\nsidebar:\n  style: group\ncollapse: false\ncontent\u002F\n  1.frameworks\u002F\n    _dir.yml\n    1.vue.md\n    2.nuxt.md",{"id":399,"title":400,"titles":401,"content":402,"level":335},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Ffolders#parameters","Parameters",[39],"Title of the page. Defaults to the filename.The icon shown in the sidebar for the page.A list of badges appended to the end of the sidebar link.Whether the folder should be collapsed by default.The style used for the folder. The default value can be configured in the appConfig.defaulttreegroup html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .shVGa, html code.shiki .shVGa{--shiki-light:#FF5370;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}",{"id":45,"title":44,"titles":404,"content":405,"level":324},[],"全页面示例 写作ing...",{"id":50,"title":49,"titles":407,"content":408,"level":324},[],"展示 markdown 常用语法 欢迎来到 Markdown 的奇妙世界！无论你是写作爱好者、开发者、博主，还是想要简单记录点什么的人，Markdown 都能成为你新的好伙伴。它不仅让写作变得简单明了，还能轻松地将内容转化为漂亮的网页格式。今天，我们将全面探讨 Markdown 的基础和进阶语法，让你在这个过程中充分享受写作的乐趣！ Markdown 是一种轻量级标记语言，用于格式化纯文本。它以简单、直观的语法而著称，可以快速地生成 HTML。Markdown 是写作与代码的完美结合，既简单又强大。",{"id":410,"title":411,"titles":412,"content":361,"level":335},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest#markdown-基础语法","Markdown 基础语法",[49],{"id":414,"title":415,"titles":416,"content":417,"level":367},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest#_1-标题让你的内容层次分明","1. 标题：让你的内容层次分明",[49,411],"用 # 号来创建标题。标题从 # 开始，# 的数量表示标题的级别。",{"id":419,"title":420,"titles":421,"content":361,"level":324},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest#一级标题","一级标题",[],{"id":423,"title":424,"titles":425,"content":361,"level":335},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest#二级标题","二级标题",[420],{"id":427,"title":428,"titles":429,"content":361,"level":367},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest#三级标题","三级标题",[420,424],{"id":431,"title":432,"titles":433,"content":361,"level":434},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest#四级标题","四级标题",[420,424,428],4,{"id":436,"title":437,"titles":438,"content":361,"level":439},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest#五级标题","五级标题",[420,424,428,432],5,{"id":441,"title":442,"titles":443,"content":444,"level":445},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest#六级标题","六级标题",[420,424,428,432,437],"####### 七级标题 以上代码将渲染出一组层次分明的标题，使你的内容井井有条。",6,{"id":447,"title":448,"titles":449,"content":450,"level":367},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest#_2-段落与换行自然流畅","2. 段落与换行：自然流畅",[420,424],"Markdown 中的段落就是一行接一行的文本。要创建新段落，只需在两行文本之间空一行。",{"id":452,"title":453,"titles":454,"content":455,"level":367},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest#_3-字体样式强调你的文字","3. 字体样式：强调你的文字",[420,424],"粗体：用两个星号或下划线包裹文字，如 **粗体** 或 __粗体__。斜体：用一个星号或下划线包裹文字，如 *斜体* 或 _斜体_。删除线：用两个波浪线包裹文字，如 ~~删除线~~。 这些简单的标记可以让你的内容更有层次感和重点突出。",{"id":457,"title":458,"titles":459,"content":460,"level":367},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest#_4-列表整洁有序","4. 列表：整洁有序",[420,424],"无序列表：用 -、* 或 + 加空格开始一行。有序列表：使用数字加点号（1.、2.）开始一行。 在列表中嵌套其他内容？只需缩进即可实现嵌套效果。 无序列表项 1\n嵌套有序列表项 1嵌套有序列表项 2无序列表项 2 有序列表项 1有序列表项 2",{"id":462,"title":463,"titles":464,"content":465,"level":367},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest#_5-链接与图片丰富内容","5. 链接与图片：丰富内容",[420,424],"链接：用方括号和圆括号创建链接 [显示文本](链接地址)。图片：和链接类似，只需在前面加上 !，如 ![描述文本](图片链接)。 访问 Doocs 轻松实现富媒体内容展示！ 因微信公众号平台不支持除公众号内容以外的链接，故其他平台的链接，会呈现链接样式但无法点击跳转。 对于这些链接请注意明文书写，或点击左上角「格式->微信外链接转底部引用」开启引用，这样就可以在底部观察到链接指向。 另外，使用 \u003C![alt](url),![alt](url)> 语法可以创建横屏滑动幻灯片，支持微信公众号平台。建议使用相似尺寸的图片以获得最佳显示效果。",{"id":467,"title":468,"titles":469,"content":470,"level":367},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest#_6-引用引用名言或引人深思的句子","6. 引用：引用名言或引人深思的句子",[420,424],"使用 > 来创建引用，只需在文本前面加上它。多层引用？在前一层 > 后再加一个就行。 这是一个引用这是一个嵌套引用 这让你的引用更加富有层次感。",{"id":472,"title":473,"titles":474,"content":475,"level":367},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest#_7-代码块展示你的代码","7. 代码块：展示你的代码",[420,424],"行内代码：用反引号包裹，如 code。代码块：用三个反引号包裹，并指定语言，如： console.log(\"Hello, Doocs!\"); 语法高亮让你的代码更易读。",{"id":477,"title":478,"titles":479,"content":480,"level":367},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest#_8-分割线分割内容","8. 分割线：分割内容",[420,424],"用三个或更多的 -、* 或 _ 来创建分割线。 为你的内容添加视觉分隔。",{"id":482,"title":483,"titles":484,"content":485,"level":367},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest#_9-表格清晰展示数据","9. 表格：清晰展示数据",[420,424],"Markdown 支持简单的表格，用 | 和 - 分隔单元格和表头。 项目人员邮箱微信号yanglbmecontact@yanglibin.infoYLB0109YangFongyangfong2022@gmail.comyq2419731931thinkasanythinkasany@gmail.comthinkasany 这样的表格让数据展示更为清爽！ 手动编写标记太麻烦？我们提供了便捷方式。左上方点击「编辑->插入表格」，即可快速实现表格渲染。",{"id":487,"title":488,"titles":489,"content":361,"level":335},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest#markdown-进阶技巧","Markdown 进阶技巧",[420],{"id":491,"title":492,"titles":493,"content":494,"level":367},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest#_1-latex-公式完美展示数学表达式","1. LaTeX 公式：完美展示数学表达式",[420,488],"Markdown 允许嵌入 LaTeX 语法展示数学公式： 行内公式：用 $ 包裹公式，如   。块级公式：用 $$ 包裹公式，如：",{"id":496,"title":497,"titles":498,"content":499,"level":367},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest#以下是使用mate字段包裹","以下是使用mate字段包裹",[420,488],"列表内块公式 1 列表内块公式 2 这是展示复杂数学表达的利器！",{"id":501,"title":502,"titles":503,"content":504,"level":367},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest#_2-mermaid-流程图可视化流程","2. Mermaid 流程图：可视化流程",[420,488],"Mermaid 是强大的可视化工具，可以在 Markdown 中创建流程图、时序图等。 #mermaid-0{font-family:arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-0 .error-icon{fill:#552222;}#mermaid-0 .error-text{fill:#552222;stroke:#552222;}#mermaid-0 .edge-thickness-normal{stroke-width:1px;}#mermaid-0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-0 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-0 .marker{fill:#333333;stroke:#333333;}#mermaid-0 .marker.cross{stroke:#333333;}#mermaid-0 svg{font-family:arial,sans-serif;font-size:16px;}#mermaid-0 p{margin:0;}#mermaid-0 .label{font-family:arial,sans-serif;color:#333;}#mermaid-0 .cluster-label text{fill:#333;}#mermaid-0 .cluster-label span{color:#333;}#mermaid-0 .cluster-label span p{background-color:transparent;}#mermaid-0 .label text,#mermaid-0 span{fill:#333;color:#333;}#mermaid-0 .node rect,#mermaid-0 .node circle,#mermaid-0 .node ellipse,#mermaid-0 .node polygon,#mermaid-0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-0 .rough-node .label text,#mermaid-0 .node .label text,#mermaid-0 .image-shape .label,#mermaid-0 .icon-shape .label{text-anchor:middle;}#mermaid-0 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-0 .rough-node .label,#mermaid-0 .node .label,#mermaid-0 .image-shape .label,#mermaid-0 .icon-shape .label{text-align:center;}#mermaid-0 .node.clickable{cursor:pointer;}#mermaid-0 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-0 .arrowheadPath{fill:#333333;}#mermaid-0 .edgePath .path{stroke:#333333;stroke-width:1px;}#mermaid-0 .flowchart-link{stroke:#333333;fill:none;}#mermaid-0 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-0 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-0 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-0 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-0 .cluster text{fill:#333;}#mermaid-0 .cluster span{color:#333;}#mermaid-0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-0 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-0 rect.text{fill:none;stroke-width:0;}#mermaid-0 .icon-shape,#mermaid-0 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-0 .icon-shape p,#mermaid-0 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-0 .icon-shape .label rect,#mermaid-0 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-0 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-0 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-0 .node .neo-node{stroke:#9370DB;}#mermaid-0 [data-look=\"neo\"].node rect,#mermaid-0 [data-look=\"neo\"].cluster rect,#mermaid-0 [data-look=\"neo\"].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-0 [data-look=\"neo\"].node path{stroke:#9370DB;stroke-width:1px;}#mermaid-0 [data-look=\"neo\"].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-0 [data-look=\"neo\"].node .neo-line path{stroke:#9370DB;filter:none;}#mermaid-0 [data-look=\"neo\"].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-0 [data-look=\"neo\"].node circle .state-start{fill:#000000;}#mermaid-0 [data-look=\"neo\"].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-0 [data-look=\"neo\"].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-0 :root{--mermaid-font-family:arial,sans-serif;}Option 1Option 2StartChoose PathPath 1Path 2 #mermaid-1{font-family:arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-1 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-1 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-1 .error-icon{fill:#552222;}#mermaid-1 .error-text{fill:#552222;stroke:#552222;}#mermaid-1 .edge-thickness-normal{stroke-width:1px;}#mermaid-1 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-1 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-1 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-1 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-1 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-1 .marker{fill:#333333;stroke:#333333;}#mermaid-1 .marker.cross{stroke:#333333;}#mermaid-1 svg{font-family:arial,sans-serif;font-size:16px;}#mermaid-1 p{margin:0;}#mermaid-1 .label{font-family:arial,sans-serif;color:#333;}#mermaid-1 .cluster-label text{fill:#333;}#mermaid-1 .cluster-label span{color:#333;}#mermaid-1 .cluster-label span p{background-color:transparent;}#mermaid-1 .label text,#mermaid-1 span{fill:#333;color:#333;}#mermaid-1 .node rect,#mermaid-1 .node circle,#mermaid-1 .node ellipse,#mermaid-1 .node polygon,#mermaid-1 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-1 .rough-node .label text,#mermaid-1 .node .label text,#mermaid-1 .image-shape .label,#mermaid-1 .icon-shape .label{text-anchor:middle;}#mermaid-1 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-1 .rough-node .label,#mermaid-1 .node .label,#mermaid-1 .image-shape .label,#mermaid-1 .icon-shape .label{text-align:center;}#mermaid-1 .node.clickable{cursor:pointer;}#mermaid-1 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-1 .arrowheadPath{fill:#333333;}#mermaid-1 .edgePath .path{stroke:#333333;stroke-width:1px;}#mermaid-1 .flowchart-link{stroke:#333333;fill:none;}#mermaid-1 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-1 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-1 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-1 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-1 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-1 .cluster text{fill:#333;}#mermaid-1 .cluster span{color:#333;}#mermaid-1 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-1 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-1 rect.text{fill:none;stroke-width:0;}#mermaid-1 .icon-shape,#mermaid-1 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-1 .icon-shape p,#mermaid-1 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-1 .icon-shape .label rect,#mermaid-1 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-1 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-1 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-1 .node .neo-node{stroke:#9370DB;}#mermaid-1 [data-look=\"neo\"].node rect,#mermaid-1 [data-look=\"neo\"].cluster rect,#mermaid-1 [data-look=\"neo\"].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-1 [data-look=\"neo\"].node path{stroke:#9370DB;stroke-width:1px;}#mermaid-1 [data-look=\"neo\"].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-1 [data-look=\"neo\"].node .neo-line path{stroke:#9370DB;filter:none;}#mermaid-1 [data-look=\"neo\"].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-1 [data-look=\"neo\"].node circle .state-start{fill:#000000;}#mermaid-1 [data-look=\"neo\"].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-1 [data-look=\"neo\"].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-1 :root{--mermaid-font-family:arial,sans-serif;}Local Coolify 实例生产服务器编译服务器生产环境 #mermaid-2{font-family:arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-2 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-2 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-2 .error-icon{fill:#552222;}#mermaid-2 .error-text{fill:#552222;stroke:#552222;}#mermaid-2 .edge-thickness-normal{stroke-width:1px;}#mermaid-2 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-2 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-2 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-2 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-2 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-2 .marker{fill:#333333;stroke:#333333;}#mermaid-2 .marker.cross{stroke:#333333;}#mermaid-2 svg{font-family:arial,sans-serif;font-size:16px;}#mermaid-2 p{margin:0;}#mermaid-2 .label{font-family:arial,sans-serif;color:#333;}#mermaid-2 .cluster-label text{fill:#333;}#mermaid-2 .cluster-label span{color:#333;}#mermaid-2 .cluster-label span p{background-color:transparent;}#mermaid-2 .label text,#mermaid-2 span{fill:#333;color:#333;}#mermaid-2 .node rect,#mermaid-2 .node circle,#mermaid-2 .node ellipse,#mermaid-2 .node polygon,#mermaid-2 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-2 .rough-node .label text,#mermaid-2 .node .label text,#mermaid-2 .image-shape .label,#mermaid-2 .icon-shape .label{text-anchor:middle;}#mermaid-2 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-2 .rough-node .label,#mermaid-2 .node .label,#mermaid-2 .image-shape .label,#mermaid-2 .icon-shape .label{text-align:center;}#mermaid-2 .node.clickable{cursor:pointer;}#mermaid-2 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-2 .arrowheadPath{fill:#333333;}#mermaid-2 .edgePath .path{stroke:#333333;stroke-width:1px;}#mermaid-2 .flowchart-link{stroke:#333333;fill:none;}#mermaid-2 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-2 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-2 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-2 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-2 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-2 .cluster text{fill:#333;}#mermaid-2 .cluster span{color:#333;}#mermaid-2 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-2 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-2 rect.text{fill:none;stroke-width:0;}#mermaid-2 .icon-shape,#mermaid-2 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-2 .icon-shape p,#mermaid-2 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-2 .icon-shape .label rect,#mermaid-2 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-2 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-2 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-2 .node .neo-node{stroke:#9370DB;}#mermaid-2 [data-look=\"neo\"].node rect,#mermaid-2 [data-look=\"neo\"].cluster rect,#mermaid-2 [data-look=\"neo\"].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-2 [data-look=\"neo\"].node path{stroke:#9370DB;stroke-width:1px;}#mermaid-2 [data-look=\"neo\"].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-2 [data-look=\"neo\"].node .neo-line path{stroke:#9370DB;filter:none;}#mermaid-2 [data-look=\"neo\"].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-2 [data-look=\"neo\"].node circle .state-start{fill:#000000;}#mermaid-2 [data-look=\"neo\"].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-2 [data-look=\"neo\"].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-2 :root{--mermaid-font-family:arial,sans-serif;}ABCD #mermaid-3{font-family:arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-3 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-3 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-3 .error-icon{fill:#552222;}#mermaid-3 .error-text{fill:#552222;stroke:#552222;}#mermaid-3 .edge-thickness-normal{stroke-width:1px;}#mermaid-3 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-3 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-3 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-3 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-3 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-3 .marker{fill:#333333;stroke:#333333;}#mermaid-3 .marker.cross{stroke:#333333;}#mermaid-3 svg{font-family:arial,sans-serif;font-size:16px;}#mermaid-3 p{margin:0;}#mermaid-3 .pieCircle{stroke:black;stroke-width:2px;opacity:0.7;}#mermaid-3 .pieOuterCircle{stroke:black;stroke-width:2px;fill:none;}#mermaid-3 .pieTitleText{text-anchor:middle;font-size:25px;fill:black;font-family:arial,sans-serif;}#mermaid-3 .slice{font-family:arial,sans-serif;fill:#333;font-size:17px;}#mermaid-3 .legend text{fill:black;font-family:arial,sans-serif;font-size:17px;}#mermaid-3 .node .neo-node{stroke:#9370DB;}#mermaid-3 [data-look=\"neo\"].node rect,#mermaid-3 [data-look=\"neo\"].cluster rect,#mermaid-3 [data-look=\"neo\"].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-3 [data-look=\"neo\"].node path{stroke:#9370DB;stroke-width:1px;}#mermaid-3 [data-look=\"neo\"].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-3 [data-look=\"neo\"].node .neo-line path{stroke:#9370DB;filter:none;}#mermaid-3 [data-look=\"neo\"].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-3 [data-look=\"neo\"].node circle .state-start{fill:#000000;}#mermaid-3 [data-look=\"neo\"].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-3 [data-look=\"neo\"].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-3 :root{--mermaid-font-family:arial,sans-serif;}40%46%9%5%Key elements in Product XCalciumPotassiumMagnesiumIron #mermaid-4{font-family:arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-4 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-4 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-4 .error-icon{fill:#552222;}#mermaid-4 .error-text{fill:#552222;stroke:#552222;}#mermaid-4 .edge-thickness-normal{stroke-width:1px;}#mermaid-4 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-4 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-4 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-4 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-4 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-4 .marker{fill:#333333;stroke:#333333;}#mermaid-4 .marker.cross{stroke:#333333;}#mermaid-4 svg{font-family:arial,sans-serif;font-size:16px;}#mermaid-4 p{margin:0;}#mermaid-4 .pieCircle{stroke:black;stroke-width:2px;opacity:0.7;}#mermaid-4 .pieOuterCircle{stroke:black;stroke-width:2px;fill:none;}#mermaid-4 .pieTitleText{text-anchor:middle;font-size:25px;fill:black;font-family:arial,sans-serif;}#mermaid-4 .slice{font-family:arial,sans-serif;fill:#333;font-size:17px;}#mermaid-4 .legend text{fill:black;font-family:arial,sans-serif;font-size:17px;}#mermaid-4 .node .neo-node{stroke:#9370DB;}#mermaid-4 [data-look=\"neo\"].node rect,#mermaid-4 [data-look=\"neo\"].cluster rect,#mermaid-4 [data-look=\"neo\"].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-4 [data-look=\"neo\"].node path{stroke:#9370DB;stroke-width:1px;}#mermaid-4 [data-look=\"neo\"].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-4 [data-look=\"neo\"].node .neo-line path{stroke:#9370DB;filter:none;}#mermaid-4 [data-look=\"neo\"].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-4 [data-look=\"neo\"].node circle .state-start{fill:#000000;}#mermaid-4 [data-look=\"neo\"].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-4 [data-look=\"neo\"].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-4 :root{--mermaid-font-family:arial,sans-serif;}6%10%70%13%为什么总是宅在家里？喜欢宅天气太热穷没人约 这种方式不仅能直观展示流程，还能提升文档的专业性。 更多用法，参见：Mermaid User Guide。",{"id":506,"title":507,"titles":508,"content":509,"level":335},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest#结语","结语",[420],"Markdown 是一种简单、强大且易于掌握的标记语言，通过学习基础和进阶语法，你可以快速创作内容并有效传达信息。无论是技术文档、个人博客还是项目说明，Markdown 都是你的得力助手。希望这篇内容能够带你全面了解 Markdown 的潜力，让你的写作更加丰富多彩！ 现在，拿起 Markdown 编辑器，开始创作吧！探索 Markdown 的世界，你会发现它远比想象中更精彩！",{"id":511,"title":512,"titles":513,"content":514,"level":434},"\u002Fdocs\u002F简单文档\u002Fwriting\u002Ftest#推荐阅读","推荐阅读",[420,507],"阿里又一个 20k+ stars 开源项目诞生，恭喜 fastjson！刷掉 90% 候选人的互联网大厂海量数据面试题（附题解 + 方法总结）好用！期待已久的文本块功能究竟如何在 Java 13 中发挥作用？2019 GitHub 开源贡献排行榜新鲜出炉！微软谷歌领头，阿里跻身前 12！ mjx-container[jax=\"SVG\"] {\n  direction: ltr;\n}\n\nmjx-container[jax=\"SVG\"] > svg {\n  overflow: visible;\n  min-height: 1px;\n  min-width: 1px;\n}\n\nmjx-container[jax=\"SVG\"] > svg a {\n  fill: blue;\n  stroke: blue;\n}\n\nmjx-container[jax=\"SVG\"][display=\"true\"] {\n  display: block;\n  text-align: center;\n  margin: 1em 0;\n}\n\nmjx-container[jax=\"SVG\"][display=\"true\"][width=\"full\"] {\n  display: flex;\n}\n\nmjx-container[jax=\"SVG\"][justify=\"left\"] {\n  text-align: left;\n}\n\nmjx-container[jax=\"SVG\"][justify=\"right\"] {\n  text-align: right;\n}\n\ng[data-mml-node=\"merror\"] > g {\n  fill: red;\n  stroke: red;\n}\n\ng[data-mml-node=\"merror\"] > rect[data-background] {\n  fill: yellow;\n  stroke: none;\n}\n\ng[data-mml-node=\"mtable\"] > line[data-line], svg[data-table] > g > line[data-line] {\n  stroke-width: 70px;\n  fill: none;\n}\n\ng[data-mml-node=\"mtable\"] > rect[data-frame], svg[data-table] > g > rect[data-frame] {\n  stroke-width: 70px;\n  fill: none;\n}\n\ng[data-mml-node=\"mtable\"] > .mjx-dashed, svg[data-table] > g > .mjx-dashed {\n  stroke-dasharray: 140;\n}\n\ng[data-mml-node=\"mtable\"] > .mjx-dotted, svg[data-table] > g > .mjx-dotted {\n  stroke-linecap: round;\n  stroke-dasharray: 0,140;\n}\n\ng[data-mml-node=\"mtable\"] > g > svg {\n  overflow: visible;\n}\n\n[jax=\"SVG\"] mjx-tool {\n  display: inline-block;\n  position: relative;\n  width: 0;\n  height: 0;\n}\n\n[jax=\"SVG\"] mjx-tool > mjx-tip {\n  position: absolute;\n  top: 0;\n  left: 0;\n}\n\nmjx-tool > mjx-tip {\n  display: inline-block;\n  padding: .2em;\n  border: 1px solid #888;\n  font-size: 70%;\n  background-color: #F8F8F8;\n  color: black;\n  box-shadow: 2px 2px 5px #AAAAAA;\n}\n\ng[data-mml-node=\"maction\"][data-toggle] {\n  cursor: pointer;\n}\n\nmjx-status {\n  display: block;\n  position: fixed;\n  left: 1em;\n  bottom: 1em;\n  min-width: 25%;\n  padding: .2em .4em;\n  border: 1px solid #888;\n  font-size: 90%;\n  background-color: #F8F8F8;\n  color: black;\n}\n\nforeignObject[data-mjx-xml] {\n  font-family: initial;\n  line-height: normal;\n  overflow: visible;\n}\n\nmjx-container[jax=\"SVG\"] path[data-c], mjx-container[jax=\"SVG\"] use[data-c] {\n  stroke-width: 3;\n} html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sLcK_, html code.shiki .sLcK_{--shiki-light:#6182B8;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}",{"id":56,"title":55,"titles":516,"content":517,"level":324},[],"部署你的 Estel Docs 应用。",{"id":519,"title":520,"titles":521,"content":522,"level":335},"\u002Fdocs\u002F简单文档\u002Fdeployment#静态托管","静态托管",[55],"在 nuxt.config.ts 或 .env 中配置 site.urlOG Images 必须使用绝对 URL 提供服务，您需要提供一个站点 URL。export default defineNuxtConfig({\n  site: {\n    url: 'https:\u002F\u002Fexample.com',\n  },\n});\nNUXT_SITE_URL=https:\u002F\u002Fexample.com\n运行生成命令在 Vercel 上，在构建和开发设置中将构建命令设置为 nuxt generate。部署您现在可以将 .output\u002Fpublic 目录部署到任何静态托管服务，或使用 npx serve .output\u002Fpublic 在本地预览。",{"id":524,"title":525,"titles":526,"content":527,"level":335},"\u002Fdocs\u002F简单文档\u002Fdeployment#ssr-服务器","SSR 服务器",[55],"运行构建命令部署node .output\u002Fserver\u002Findex.mjs html pre.shiki code .sEIvO, html code.shiki .sEIvO{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#F97583;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit;--shiki-sepia:#F92672;--shiki-sepia-font-style:inherit}html pre.shiki code .sLcK_, html code.shiki .sLcK_{--shiki-light:#6182B8;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sHV4B, html code.shiki .sHV4B{--shiki-light:#E53935;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .sPYpf, html code.shiki .sPYpf{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}",{"id":67,"title":66,"titles":529,"content":530,"level":324},[],"常用自定义组件速查文档 ::callout\n      ---\n      icon: simple-icons-visualstudiocode\n      to: https:\u002F\u002Fmarketplace.visualstudio.com\u002Fitems?itemName=Nuxt.mdc\n      ---\n      安装 **MDC VS Code 扩展**，以获得对 MDC 语法的高亮显示支持。\n      ::\n安装 MDC VS Code 扩展，以获得对 MDC 语法的高亮显示支持。 在 tip 标签中嵌套 code-group 的示例. 可以直接复制index.md 中的内容,既是 当前展示 的效果.          ::tip\n          在文档中使用自定义组件时，可以在插槽中使用 Markdown 语法，组件会自动渲染 Markdown 内容。\n\n            :::code-group\n            ```mdc [index.md]\n            ::my-title\n            A [rich text](\u002F) will be **rendered** by the component.\n            ::\n            ```\n            \n            ```html [MyTitle.vue]\n            \u003Ctemplate>\n              \u003Ch1 class=\"text-4xl\">\n                \u003Cslot mdc-unwrap=\"p\" \u002F>\n              \u003C\u002Fh1>\n            \u003C\u002Ftemplate>\n            ```\n\n              ::::code-preview{icon=\"i-lucide-eye\" label=\"Preview\"}\n                :::::example-title\n                A [rich text](\u002F) will be **rendered** by the component.\n                :::::\n              ::::\n            :::\n          ::\n\u003Ctemplate>\n  \u003Ch1 class=\"text-4xl\">\n    \u003Cslot mdc-unwrap=\"p\" \u002F>\n  \u003C\u002Fh1>\n\u003C\u002Ftemplate>\nA rich text will be rendered by the component. html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sHk4K, html code.shiki .sHk4K{--shiki-light:#39ADB5;--shiki-light-font-weight:bold;--shiki-default:#E1E4E8;--shiki-default-font-weight:bold;--shiki-dark:#E1E4E8;--shiki-dark-font-weight:bold;--shiki-sepia:#66D9EF;--shiki-sepia-font-weight:bold}html pre.shiki code .sbgKg, html code.shiki .sbgKg{--shiki-light:#E53935;--shiki-light-font-weight:bold;--shiki-default:#E1E4E8;--shiki-default-font-weight:bold;--shiki-dark:#E1E4E8;--shiki-dark-font-weight:bold;--shiki-sepia:#66D9EF;--shiki-sepia-font-weight:bold}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .slHBl, html code.shiki .slHBl{--shiki-light:#91B859;--shiki-light-text-decoration:inherit;--shiki-default:#DBEDFF;--shiki-default-text-decoration:underline;--shiki-dark:#DBEDFF;--shiki-dark-text-decoration:underline;--shiki-sepia:#AE81FF;--shiki-sepia-text-decoration:inherit}html pre.shiki code .sqFf_, html code.shiki .sqFf_{--shiki-light:#90A4AE;--shiki-light-text-decoration:underline;--shiki-default:#E1E4E8;--shiki-default-text-decoration:underline;--shiki-dark:#E1E4E8;--shiki-dark-text-decoration:underline;--shiki-sepia:#E6DB74;--shiki-sepia-text-decoration:inherit}html pre.shiki code .sy8J7, html code.shiki .sy8J7{--shiki-light:#91B859;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sxHrB, html code.shiki .sxHrB{--shiki-light:#90A4AE90;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sdE5Q, html code.shiki .sdE5Q{--shiki-light:#9C3EDA;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sYvgn, html code.shiki .sYvgn{--shiki-light:#39ADB5;--shiki-light-font-style:inherit;--shiki-default:#FDAEB7;--shiki-default-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic;--shiki-sepia:#F44747;--shiki-sepia-font-style:inherit}",{"id":72,"title":71,"titles":532,"content":361,"level":324},[],{"id":534,"title":535,"titles":536,"content":537,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Falert#usage","Usage",[71],"A default alert with code and a link.A secondary alert with code and a link. ::alert{icon=\"lucide:info\"}\n  A **default** alert with `code` and a [link](\u002F).\n::\n\n::alert{type=\"secondary\" icon=\"lucide:info\"}\n  A **secondary** alert with `code` and a [link](\u002F).\n:: ::",{"id":539,"title":540,"titles":541,"content":542,"level":367},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Falert#link","Link",[71,535],"A link alert.::alert{to=\"https:\u002F\u002Fgithub.com\u002FZTL-UwU\u002Fshadcn-docs-nuxt\" target=\"_blank\" icon=\"lucide:link\"}\n  A **link** alert.\n::",{"id":544,"title":545,"titles":546,"content":547,"level":367},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Falert#variants","Variants",[71,535],"An info alert with code and a link.::alert{type=\"info\" icon=\"lucide:info\"}\n  An **info** alert with `code` and a [link](\u002F).\n::\nA note alert with code and a link.::alert{type=\"note\" icon=\"lucide:pencil\"}\n  A **note** alert with `code` and a [link](\u002F).\n::\nA success alert with code and a link.::alert{type=\"success\" icon=\"lucide:lightbulb\"}\n  A **success** alert with `code` and a [link](\u002F).\n::\nAn example alert with code and a link.::alert{type=\"example\" icon=\"lucide:test-tube\"}\n  An **example** alert with `code` and a [link](\u002F).\n::\nA warning alert with code and a link.::alert{type=\"warning\" icon=\"lucide:triangle-alert\"}\n  A **warning** alert with `code` and a [link](\u002F).\n::\nA danger alert with code and a link.::alert{type=\"danger\" icon=\"lucide:circle-x\"}\n  A **danger** alert with `code` and a [link](\u002F).\n::",{"id":549,"title":550,"titles":551,"content":552,"level":367},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Falert#title","Title",[71,535],"An alert with a title.::alert{title=\"Title\" icon=\"lucide:layout-list\"}\n  An alert with a title.\n::",{"id":554,"title":555,"titles":556,"content":557,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Falert#props","Props",[71],"Alert titleAlert iconLink URLA target attribute value to apply on the linkAlias to target='_blank'Whether to show the link indicator html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html pre.shiki code .sdE5Q, html code.shiki .sdE5Q{--shiki-light:#9C3EDA;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sHk4K, html code.shiki .sHk4K{--shiki-light:#39ADB5;--shiki-light-font-weight:bold;--shiki-default:#E1E4E8;--shiki-default-font-weight:bold;--shiki-dark:#E1E4E8;--shiki-dark-font-weight:bold;--shiki-sepia:#66D9EF;--shiki-sepia-font-weight:bold}html pre.shiki code .sbgKg, html code.shiki .sbgKg{--shiki-light:#E53935;--shiki-light-font-weight:bold;--shiki-default:#E1E4E8;--shiki-default-font-weight:bold;--shiki-dark:#E1E4E8;--shiki-dark-font-weight:bold;--shiki-sepia:#66D9EF;--shiki-sepia-font-weight:bold}html pre.shiki code .spiKf, html code.shiki .spiKf{--shiki-light:#39ADB5;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#FD971F}html pre.shiki code .sAWxV, html code.shiki .sAWxV{--shiki-light:#91B859;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#FD971F}html pre.shiki code .slHBl, html code.shiki .slHBl{--shiki-light:#91B859;--shiki-light-text-decoration:inherit;--shiki-default:#DBEDFF;--shiki-default-text-decoration:underline;--shiki-dark:#DBEDFF;--shiki-dark-text-decoration:underline;--shiki-sepia:#AE81FF;--shiki-sepia-text-decoration:inherit}html pre.shiki code .sqFf_, html code.shiki .sqFf_{--shiki-light:#90A4AE;--shiki-light-text-decoration:underline;--shiki-default:#E1E4E8;--shiki-default-text-decoration:underline;--shiki-dark:#E1E4E8;--shiki-dark-text-decoration:underline;--shiki-sepia:#E6DB74;--shiki-sepia-text-decoration:inherit}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}",{"id":76,"title":75,"titles":559,"content":361,"level":324},[],{"id":561,"title":535,"titles":562,"content":563,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fbadge#usage",[75],"DefaultSmall::badge\n  Default\n::\n::badge{size=\"sm\"}\n  Small\n::",{"id":565,"title":545,"titles":566,"content":567,"level":367},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fbadge#variants",[75,535],"Outline:badge[Outline]{variant=\"outline\"}\nSecondary:badge[Secondary]{variant=\"secondary\"}\nInfo:badge[Info]{type=\"info\"}\nWarning:badge[Warning]{type=\"warning\"}\nSuccess:badge[Success]{type=\"success\"}\nlime:badge[lime]{type=\"lime\"}\nDanger:badge[Danger]{type=\"danger\"}",{"id":569,"title":540,"titles":570,"content":571,"level":367},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fbadge#link",[75,535],"Link::badge{variant=\"outline\" type=\"info\" to=\"https:\u002F\u002Fgithub.com\u002FZTL-UwU\u002Fshadcn-docs-nuxt\" target=\"_blank\"}\nLink\n::",{"id":573,"title":555,"titles":574,"content":575,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fbadge#props",[75],"Link URLA target attribute value to apply on the link html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sdE5Q, html code.shiki .sdE5Q{--shiki-light:#9C3EDA;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}",{"id":80,"title":79,"titles":577,"content":361,"level":324},[],{"id":579,"title":535,"titles":580,"content":581,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fbutton-link#usage",[79],"Get StartedGitHubGhost::button-link{right-icon=\"lucide:arrow-up-right\" to=\"\u002Fgetting-started\" target=\"_blank\"}\n  Get Started\n::\n::button-link{left-icon=\"lucide:github\" variant=\"outline\" to=\"https:\u002F\u002Fgithub.com\u002FZTL-UwU\u002Fshadcn-docs-nuxt\" target=\"_blank\"}\n  GitHub\n::\n::button-link{left-icon=\"lucide:ghost\" variant=\"ghost\" href=\"https:\u002F\u002Fgithub.com\u002FZTL-UwU\u002Fshadcn-docs-nuxt\" blank}\n  Ghost\n::",{"id":583,"title":555,"titles":584,"content":585,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fbutton-link#props",[79],"Icon on the leftIcon on the rightLink URLAlias to toA target attribute value to apply on the linkAlias to target='_blank' html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html pre.shiki code .sdE5Q, html code.shiki .sdE5Q{--shiki-light:#9C3EDA;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}",{"id":84,"title":83,"titles":587,"content":588,"level":324},[],"::callout is an alias to ::alert. html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}",{"id":88,"title":87,"titles":590,"content":361,"level":324},[],{"id":592,"title":535,"titles":593,"content":594,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fcard#usage",[87],"Card TitleDescriptionBeautifully designed Nuxt Content template with shadcn-vue. Customizable. Compatible. Open Source.Footer::card\n---\nicon: lucide:box\n---\n\n#title\nCard Title\n\n#description\nDescription\n\n#content\nBeautifully designed **Nuxt Content** template with **shadcn-vue**. _Customizable. Compatible. Open Source._\n\n#footer\nFooter\n::",{"id":596,"title":540,"titles":597,"content":598,"level":367},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fcard#link",[87,535],"Link CardBeautifully designed Nuxt Content template with shadcn-vue. Customizable. Compatible. Open Source.::card\n---\nto: https:\u002F\u002Fgithub.com\u002FZTL-UwU\u002Fshadcn-docs-nuxt\ntarget: _blank\n# showLinkIcon: false\n---\n\n#title\nLink Card\n\n#content\nBeautifully designed **Nuxt Content** template with **shadcn-vue**. _Customizable. Compatible. Open Source._\n::",{"id":600,"title":601,"titles":602,"content":603,"level":367},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fcard#horizontal","Horizontal",[87,535],"Horizontal CardBeautifully designed Nuxt Content template with shadcn-vue. Customizable. Compatible. Open Source.::card\n---\nicon: 'lucide:fold-horizontal'\nicon-size: 26\nhorizontal: true\n---\n\n#title\nHorizontal Card\n\n#description\nBeautifully designed **Nuxt Content** template with **shadcn-vue**. _Customizable. Compatible. Open Source._\n::",{"id":605,"title":606,"titles":607,"content":608,"level":367},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fcard#image","Image",[87,535],"Image CardBeautifully designed Nuxt Content template with shadcn-vue. Customizable. Compatible. Open Source.::card\n---\nimg: \u002Fog-nuxt.png\n---\n#title\nImage Card\n\n#content\nBeautifully designed **Nuxt Content** template with **shadcn-vue**. _Customizable. Compatible. Open Source._\n::",{"id":610,"title":555,"titles":611,"content":612,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fcard#props",[87],"Card titleCard descriptionCard contentCard footerCard iconLink URLA target attribute value to apply on the linkImage URLWhether to show the link indicator html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sdE5Q, html code.shiki .sdE5Q{--shiki-light:#9C3EDA;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sHk4K, html code.shiki .sHk4K{--shiki-light:#39ADB5;--shiki-light-font-weight:bold;--shiki-default:#E1E4E8;--shiki-default-font-weight:bold;--shiki-dark:#E1E4E8;--shiki-dark-font-weight:bold;--shiki-sepia:#66D9EF;--shiki-sepia-font-weight:bold}html pre.shiki code .sbgKg, html code.shiki .sbgKg{--shiki-light:#E53935;--shiki-light-font-weight:bold;--shiki-default:#E1E4E8;--shiki-default-font-weight:bold;--shiki-dark:#E1E4E8;--shiki-dark-font-weight:bold;--shiki-sepia:#66D9EF;--shiki-sepia-font-weight:bold}html pre.shiki code .sPyn-, html code.shiki .sPyn-{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#E1E4E8;--shiki-default-font-style:italic;--shiki-dark:#E1E4E8;--shiki-dark-font-style:italic;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .sAkSq, html code.shiki .sAkSq{--shiki-light:#E53935;--shiki-light-font-style:italic;--shiki-default:#E1E4E8;--shiki-default-font-style:italic;--shiki-dark:#E1E4E8;--shiki-dark-font-style:italic;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .ss7Ak, html code.shiki .ss7Ak{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit;--shiki-sepia:#88846F;--shiki-sepia-font-style:inherit}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .s516T, html code.shiki .s516T{--shiki-light:#F76D47;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .shVGa, html code.shiki .shVGa{--shiki-light:#FF5370;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}",{"id":92,"title":91,"titles":614,"content":361,"level":324},[],{"id":616,"title":535,"titles":617,"content":618,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fcard-group#usage",[91],"Explore Nuxt built-in components for pages, layouts, head, and more.Discover Nuxt composable functions for data-fetching, head management and more.Learn about Nuxt utility functions for navigation, error handling and more.List of Nuxt CLI commands to init, analyze, build, and preview your application.::card-group\n  ::card\n  ---\n  title: Components\n  icon: lucide:box\n  to: https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fapi\u002Fcomponents\u002Fclient-only\n  target: _blank\n  ---\n  Explore Nuxt built-in components for pages, layouts, head, and more.\n  ::\n\n::card\n---\ntitle: Composables\nicon: lucide:arrow-right-left\nto: https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fapi\u002Fcomposables\u002Fuse-app-config\ntarget: _blank\n---\nDiscover Nuxt composable functions for data-fetching, head management and more.\n::\n\n::card\n---\ntitle: Utils\nicon: lucide:scissors\nto: https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fapi\u002Futils\u002Fdollarfetch\ntarget: _blank\n---\nLearn about Nuxt utility functions for navigation, error handling and more.\n::\n\n::card\n---\ntitle: Commands\nicon: lucide:square-terminal\nto: https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fapi\u002Fcommands\u002Fadd\ntarget: _blank\n---\nList of Nuxt CLI commands to init, analyze, build, and preview your application.\n:: ::\n\n### Cols\n\n::stack\n::div{class=\"p-4\"}\n  ::card-group{:cols=\"3\"}\n    ::card\n    ---\n    title: Components\n    icon: lucide:box\n    to: https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fapi\u002Fcomponents\u002Fclient-only\n    target: _blank\n    ---\n    Explore Nuxt built-in components for pages, layouts, head, and more.\n    ::\n    ::card\n    ---\n    title: Composables\n    icon: lucide:arrow-right-left\n    to: https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fapi\u002Fcomposables\u002Fuse-app-config\n    target: _blank\n    ---\n    Discover Nuxt composable functions for data-fetching, head management and more.\n    ::\n    ::card\n    ---\n    title: Utils\n    icon: lucide:scissors\n    to: https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fapi\u002Futils\u002Fdollarfetch\n    target: _blank\n    ---\n    Learn about Nuxt utility functions for navigation, error handling and more.\n    ::\n  ::\n::\n```mdc\n::card-group{:cols=\"3\"}\n  ::card\n  ---\n  title: Components\n  icon: lucide:box\n  to: https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fapi\u002Fcomponents\u002Fclient-only\n  target: _blank\n  ---\n  Explore Nuxt built-in components for pages, layouts, head, and more.\n  ::\n\n  ::card\n  ---\n  title: Composables\n  icon: lucide:arrow-right-left\n  to: https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fapi\u002Fcomposables\u002Fuse-app-config\n  target: _blank\n  ---\n  Discover Nuxt composable functions for data-fetching, head management and more.\n  ::\n\n  ::card\n  ---\n  title: Utils\n  icon: lucide:scissors\n  to: https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fapi\u002Futils\u002Fdollarfetch\n  target: _blank\n  ---\n  Learn about Nuxt utility functions for navigation, error handling and more.\n  ::\n:: ::",{"id":620,"title":555,"titles":621,"content":622,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fcard-group#props",[91],"Number of columns (only for desktop) html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}",{"id":96,"title":95,"titles":624,"content":361,"level":324},[],{"id":626,"title":535,"titles":627,"content":628,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fcode-group#usage",[95],"\u003Ctemplate>\n  \u003Cdiv>\n    \u003CNuxtLayout>\n      \u003CNuxtPage \u002F>\n    \u003C\u002FNuxtLayout>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Ch1>Welcome to the homepage\u003C\u002Fh1>\n    \u003CAppAlert>\n      This is an auto-imported component\n    \u003C\u002FAppAlert>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n::code-group\n  ```vue [app.vue]\n  \u003Ctemplate>\n    \u003Cdiv>\n      \u003CNuxtLayout>\n        \u003CNuxtPage \u002F>\n      \u003C\u002FNuxtLayout>\n    \u003C\u002Fdiv>\n  \u003C\u002Ftemplate>\n  ```\n\n  ```vue [pages\u002Findex.vue]\n  \u003Ctemplate>\n    \u003Cdiv>\n      \u003Ch1>Welcome to the homepage\u003C\u002Fh1>\n      \u003CAppAlert>\n        This is an auto-imported component\n      \u003C\u002FAppAlert>\n    \u003C\u002Fdiv>\n  \u003C\u002Ftemplate>\n  ```\n:: ::code-group is a wrapper around ::tabs{variant=\"card\"}.",{"id":630,"title":555,"titles":631,"content":632,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fcode-group#props",[95],"Sync scope for ::tabs html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sy8J7, html code.shiki .sy8J7{--shiki-light:#91B859;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sxHrB, html code.shiki .sxHrB{--shiki-light:#90A4AE90;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sdE5Q, html code.shiki .sdE5Q{--shiki-light:#9C3EDA;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}",{"id":100,"title":99,"titles":634,"content":361,"level":324},[],{"id":636,"title":535,"titles":637,"content":638,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fcode-tree#usage",[99],"@import \"tailwindcss\" theme(static);\n@import \"@nuxt\u002Fui-pro\";\nexport default defineAppConfig({\n  ui: {\n    colors: {\n      primary: 'sky',\n      colors: 'slate'\n    }\n  }\n});\n\u003Ctemplate>\n  \u003CUApp>\n    \u003CNuxtPage \u002F>\n  \u003C\u002FUApp>\n\u003C\u002Ftemplate>\n{\n  \"name\": \"nuxt-app\",\n  \"private\": true,\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"nuxt build\",\n    \"dev\": \"nuxt dev\",\n    \"generate\": \"nuxt generate\",\n    \"preview\": \"nuxt preview\",\n    \"postinstall\": \"nuxt prepare\",\n    \"typecheck\": \"nuxt typecheck\"\n  },\n  \"dependencies\": {\n    \"@iconify-json\u002Flucide\": \"^1.2.18\",\n    \"@nuxt\u002Fui-pro\": \"3.0.0-alpha.10\",\n    \"nuxt\": \"^3.15.1\"\n  },\n  \"devDependencies\": {\n    \"typescript\": \"^5.7.2\",\n    \"vue-tsc\": \"^2.2.0\"\n  }\n}\n{\n  \"extends\": \".\u002F.nuxt\u002Ftsconfig.json\"\n}\nexport default defineNuxtConfig({\n  modules: ['@nuxt\u002Fui-pro'],\n\n  future: {\n    compatibilityVersion: 4\n  },\n\n  css: ['~\u002Fassets\u002Fmain.css']\n});\n# Nuxt 3 Minimal Starter\n\nLook at the [Nuxt 3 documentation](https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fgetting-started\u002Fintroduction) to learn more.\n\n## Setup\n\nMake sure to install the dependencies:\n\n```bash\n# npm\nnpm install\n\n# pnpm\npnpm install\n\n# yarn\nyarn install\n\n# bun\nbun install\n```\n\n## Development Server\n\nStart the development server on `http:\u002F\u002Flocalhost:3000`:\n\n```bash\n# npm\nnpm run dev\n\n# pnpm\npnpm run dev\n\n# yarn\nyarn dev\n\n# bun\nbun run dev\n```\n\n## Production\n\nBuild the application for production:\n\n```bash\n# npm\nnpm run build\n\n# pnpm\npnpm run build\n\n# yarn\nyarn build\n\n# bun\nbun run build\n```\n\nLocally preview production build:\n\n```bash\n# npm\nnpm run preview\n\n# pnpm\npnpm run preview\n\n# yarn\nyarn preview\n\n# bun\nbun run preview\n```\n\nCheck out the [deployment documentation](https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fgetting-started\u002Fdeployment) for more information. ::code-tree{defaultValue=\"nuxt.config.ts\"}\n\n```css [app\u002Fassets\u002Fmain.css]\n@import \"tailwindcss\" theme(static);\n@import \"@nuxt\u002Fui-pro\";\n```\n\n```ts [app\u002Fapp.config.ts]\nexport default defineAppConfig({\n  ui: {\n    colors: {\n      primary: 'sky',\n      colors: 'slate'\n    }\n  }\n});\n```\n\n```vue [app\u002Fapp.vue]\n\u003Ctemplate>\n  \u003CUApp>\n    \u003CNuxtPage \u002F>\n  \u003C\u002FUApp>\n\u003C\u002Ftemplate>\n```\n\n```json [package.json]\n{\n  \"name\": \"nuxt-app\",\n  \"private\": true,\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"nuxt build\",\n    \"dev\": \"nuxt dev\",\n    \"generate\": \"nuxt generate\",\n    \"preview\": \"nuxt preview\",\n    \"postinstall\": \"nuxt prepare\",\n    \"typecheck\": \"nuxt typecheck\"\n  },\n  \"dependencies\": {\n    \"@iconify-json\u002Flucide\": \"^1.2.18\",\n    \"@nuxt\u002Fui-pro\": \"3.0.0-alpha.10\",\n    \"nuxt\": \"^3.15.1\"\n  },\n  \"devDependencies\": {\n    \"typescript\": \"^5.7.2\",\n    \"vue-tsc\": \"^2.2.0\"\n  }\n}\n```\n\n```json [tsconfig.json]\n{\n  \"extends\": \".\u002F.nuxt\u002Ftsconfig.json\"\n}\n```\n\n```ts [nuxt.config.ts]\nexport default defineNuxtConfig({\n  modules: ['@nuxt\u002Fui-pro'],\n\n  future: {\n    compatibilityVersion: 4\n  },\n\n  css: ['~\u002Fassets\u002Fmain.css']\n});\n```\n\n````md [README.md]\n# Nuxt 3 Minimal Starter\n\nLook at the [Nuxt 3 documentation](https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fgetting-started\u002Fintroduction) to learn more.\n\n## Setup\n\nMake sure to install the dependencies:\n\n```bash\n# npm\nnpm install\n\n# pnpm\npnpm install\n\n# yarn\nyarn install\n\n# bun\nbun install\n```\n\n## Development Server\n\nStart the development server on `http:\u002F\u002Flocalhost:3000`:\n\n```bash\n# npm\nnpm run dev\n\n# pnpm\npnpm run dev\n\n# yarn\nyarn dev\n\n# bun\nbun run dev\n```\n\n## Production\n\nBuild the application for production:\n\n```bash\n# npm\nnpm run build\n\n# pnpm\npnpm run build\n\n# yarn\nyarn build\n\n# bun\nbun run build\n```\n\nLocally preview production build:\n\n```bash\n# npm\nnpm run preview\n\n# pnpm\npnpm run preview\n\n# yarn\nyarn preview\n\n# bun\nbun run preview\n```\n\nCheck out the [deployment documentation](https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fgetting-started\u002Fdeployment) for more information.\n````\n\n:: ::",{"id":640,"title":555,"titles":641,"content":642,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fcode-tree#props",[99],"Default open fileCode tree title html pre.shiki code .sEIvO, html code.shiki .sEIvO{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#F97583;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit;--shiki-sepia:#F92672;--shiki-sepia-font-style:inherit}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .sLcK_, html code.shiki .sLcK_{--shiki-light:#6182B8;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sHV4B, html code.shiki .sHV4B{--shiki-light:#E53935;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html pre.shiki code .ss27W, html code.shiki .ss27W{--shiki-light:#39ADB5;--shiki-light-font-style:inherit;--shiki-default:#79B8FF;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .szxyS, html code.shiki .szxyS{--shiki-light:#9C3EDA;--shiki-light-font-style:inherit;--shiki-default:#79B8FF;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .si2Vc, html code.shiki .si2Vc{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#CFCFC2}html pre.shiki code .sO9wW, html code.shiki .sO9wW{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#CFCFC2}html pre.shiki code .sQnY8, html code.shiki .sQnY8{--shiki-light:#39ADB5;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .stRg-, html code.shiki .stRg-{--shiki-light:#E2931D;--shiki-light-font-style:inherit;--shiki-default:#79B8FF;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .s516T, html code.shiki .s516T{--shiki-light:#F76D47;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .syccL, html code.shiki .syccL{--shiki-light:#39ADB5;--shiki-light-font-weight:inherit;--shiki-default:#79B8FF;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold;--shiki-sepia:#A6E22E;--shiki-sepia-font-weight:bold}html pre.shiki code .sxAGG, html code.shiki .sxAGG{--shiki-light:#E2931D;--shiki-light-font-weight:inherit;--shiki-default:#79B8FF;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold;--shiki-sepia:#A6E22E;--shiki-sepia-font-weight:bold}html pre.shiki code .slHBl, html code.shiki .slHBl{--shiki-light:#91B859;--shiki-light-text-decoration:inherit;--shiki-default:#DBEDFF;--shiki-default-text-decoration:underline;--shiki-dark:#DBEDFF;--shiki-dark-text-decoration:underline;--shiki-sepia:#AE81FF;--shiki-sepia-text-decoration:inherit}html pre.shiki code .svcTW, html code.shiki .svcTW{--shiki-light:#E53935;--shiki-light-text-decoration:underline;--shiki-default:#E1E4E8;--shiki-default-text-decoration:underline;--shiki-dark:#E1E4E8;--shiki-dark-text-decoration:underline;--shiki-sepia:#E6DB74;--shiki-sepia-text-decoration:inherit}html pre.shiki code .sy8J7, html code.shiki .sy8J7{--shiki-light:#91B859;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sxHrB, html code.shiki .sxHrB{--shiki-light:#90A4AE90;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .ss7Ak, html code.shiki .ss7Ak{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit;--shiki-sepia:#88846F;--shiki-sepia-font-style:inherit}html pre.shiki code .sPYpf, html code.shiki .sPYpf{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .spiKf, html code.shiki .spiKf{--shiki-light:#39ADB5;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#FD971F}html pre.shiki code .sAWxV, html code.shiki .sAWxV{--shiki-light:#91B859;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#FD971F}html pre.shiki code .sdE5Q, html code.shiki .sdE5Q{--shiki-light:#9C3EDA;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sqFf_, html code.shiki .sqFf_{--shiki-light:#90A4AE;--shiki-light-text-decoration:underline;--shiki-default:#E1E4E8;--shiki-default-text-decoration:underline;--shiki-dark:#E1E4E8;--shiki-dark-text-decoration:underline;--shiki-sepia:#E6DB74;--shiki-sepia-text-decoration:inherit}",{"id":104,"title":103,"titles":644,"content":361,"level":324},[],{"id":646,"title":535,"titles":647,"content":648,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ffield#usage",[103],"The description can be set as prop or in the default slot with full markdown support.::field{name=\"Field\" type=\"string\" defaultValue=\"'default'\" required}\nThe _description_ can be set as prop or in the default slot with full **markdown** support.\n:: The text required is configurable in main.fieldRequiredText.",{"id":650,"title":555,"titles":651,"content":652,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ffield#props",[103],"Field nameField typeField descriptionField default valueWhether the field is required html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html pre.shiki code .sdE5Q, html code.shiki .sdE5Q{--shiki-light:#9C3EDA;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sPyn-, html code.shiki .sPyn-{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#E1E4E8;--shiki-default-font-style:italic;--shiki-dark:#E1E4E8;--shiki-dark-font-style:italic;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .sAkSq, html code.shiki .sAkSq{--shiki-light:#E53935;--shiki-light-font-style:italic;--shiki-default:#E1E4E8;--shiki-default-font-style:italic;--shiki-dark:#E1E4E8;--shiki-dark-font-style:italic;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .sHk4K, html code.shiki .sHk4K{--shiki-light:#39ADB5;--shiki-light-font-weight:bold;--shiki-default:#E1E4E8;--shiki-default-font-weight:bold;--shiki-dark:#E1E4E8;--shiki-dark-font-weight:bold;--shiki-sepia:#66D9EF;--shiki-sepia-font-weight:bold}html pre.shiki code .sbgKg, html code.shiki .sbgKg{--shiki-light:#E53935;--shiki-light-font-weight:bold;--shiki-default:#E1E4E8;--shiki-default-font-weight:bold;--shiki-dark:#E1E4E8;--shiki-dark-font-weight:bold;--shiki-sepia:#66D9EF;--shiki-sepia-font-weight:bold}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}",{"id":108,"title":107,"titles":654,"content":361,"level":324},[],{"id":656,"title":535,"titles":657,"content":658,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ffield-group#usage",[107],"A field with a default value.A required field.Clears form errors associated with a specific path. If no path is provided, clears all form errors.Retrieves form errors associated with a specific path. If no path is provided, returns all form errors.Sets form errors for a given path. If no path is provided, overrides all errors.A reference to the array containing validation errors. Use this to access or manipulate the error information.::field-group\n  ::field{name=\"withDefault\" type=\"boolean\" defaultValue=\"true\"}\n  A field with a default value.\n  ::\n  ::field{name=\"requiredField\" type=\"boolean\" required}\n  A required field.\n  ::\n  ::field{name=\"clear (path?: string)\" type=\"void\"}\n  Clears form errors associated with a specific path. If no path is provided, clears all form errors.\n  ::\n  ::field{name=\"getErrors (path?: string)\" type=\"FormError[]\"}\n  Retrieves form errors associated with a specific path. If no path is provided, returns all form errors.\n  ::\n  ::field{name=\"setErrors (errors: FormError[], path?: string)\" type=\"void\"}\n  Sets form errors for a given path. If no path is provided, overrides all errors.\n  ::\n  ::field{name=\"errors\" type=\"Ref\u003CFormError[]>\"}\n  A reference to the array containing validation errors. Use this to access or manipulate the error information.\n  ::\n:: html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html pre.shiki code .sdE5Q, html code.shiki .sdE5Q{--shiki-light:#9C3EDA;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}",{"id":112,"title":111,"titles":660,"content":361,"level":324},[],{"id":662,"title":535,"titles":663,"content":664,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ffile-tree#usage",[111],"::file-tree\n---\ntree:\n  - app:\n    - components:\n      - Header.vue\n      - Footer.vue\n    - composables:\n      - useErrorHandler.ts\n    - ^app.vue^ # This is highlighted\n  - docs:\n    - index.md\n---\n::",{"id":666,"title":667,"titles":668,"content":669,"level":367},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ffile-tree#customizations","Customizations",[111,535],"::file-tree\n---\ntitle: File Tree Title\nicon: lucide:folder-tree\nautoSlash: false   # Whether to add a slash after every folder automatically\nshowArrow: true    # Whether to show the collapse arrow\ntree:\n  - components:\n    - layout:\n      - Header.vue\n      - Footer.vue\n      - ...\n    - content:\n      - Accordion.vue\n      - Alert.vue\n      - ProseCode.vue\n      - ...\n---\n::",{"id":671,"title":672,"titles":673,"content":674,"level":367},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ffile-tree#disable-icons","Disable Icons",[111,535],"::file-tree\n---\nshowIcon: false\ntree:\n  - app:\n    - components:\n      - Header.vue\n      - Footer.vue\n    - composables:\n      - useErrorHandler.ts\n    - ^app.vue^\n  - docs:\n    - index.md\n---\n::",{"id":676,"title":677,"titles":678,"content":679,"level":367},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ffile-tree#diff","Diff",[111,535],"::file-tree\n---\nshowIcon: false\ntree:\n  - app:\n    - + components:\n      - Header.vue\n      - \"- Footer.vue\"\n    - composables:\n      - useErrorHandler.ts\n    - ^app.vue^\n  - docs:\n    - index.md\n---\n::",{"id":681,"title":555,"titles":682,"content":683,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ffile-tree#props",[111],"The file treeFile tree titleFile tree title iconWhether to add a slash after every folder automaticallyWhether to show the collapse arrowWhether to show file & folder icons html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .ss7Ak, html code.shiki .ss7Ak{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit;--shiki-sepia:#88846F;--shiki-sepia-font-style:inherit}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .shVGa, html code.shiki .shVGa{--shiki-light:#FF5370;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .s516T, html code.shiki .s516T{--shiki-light:#F76D47;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}",{"id":116,"title":115,"titles":685,"content":686,"level":324},[],"The icon component uses Nuxt Icon under the hood. Check out the usage guide from Nuxt Icon.",{"id":688,"title":535,"titles":689,"content":690,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ficon#usage",[115],":icon{name=\"lucide:box\"}\n:icon{name=\"vscode-icons:file-type-js-official\"}\n:icon{name=\"vscode-icons:file-type-vue\"}\n:icon{name=\"vscode-icons:file-type-nuxt\" :size=\"30\"} If you want to use other icons, it is highly recommended to install them locally, which is faster and more reliable on both SSR and client-side. npm i -D @iconify-json\u002Fcollection-name @iconify-json\u002Flucide and @iconify-json\u002Fvscode-icons are installed by default.",{"id":692,"title":693,"titles":694,"content":695,"level":367},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ficon#smart-icon","Smart Icon",[115,535],"0.5.3 You can put iconify icons, emojis and urls in smart-icon. Smart icon will render them automatically. Iconify  EmojisURL **Iconify**\n:smart-icon{name=\"lucide:box\"}\n:smart-icon{name=\"vscode-icons:file-type-js-official\"}\n:smart-icon{name=\"vscode-icons:file-type-vue\"}\n\n**Emojis**\n:smart-icon{name=\"😍\"}\n:smart-icon{name=\"🚀\"}\n:smart-icon{name=\"🎉\" :size=\"30\"}\n\n**URL**\n:smart-icon{name=\"\u002Flogo.svg\"}\n:smart-icon{name=\"https:\u002F\u002Fvueuse.org\u002Ffavicon.svg\" :size=\"40\"} :: html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html pre.shiki code .sdE5Q, html code.shiki .sdE5Q{--shiki-light:#9C3EDA;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .sPYpf, html code.shiki .sPYpf{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .s7i02, html code.shiki .s7i02{--shiki-light:#91B859;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .sHk4K, html code.shiki .sHk4K{--shiki-light:#39ADB5;--shiki-light-font-weight:bold;--shiki-default:#E1E4E8;--shiki-default-font-weight:bold;--shiki-dark:#E1E4E8;--shiki-dark-font-weight:bold;--shiki-sepia:#66D9EF;--shiki-sepia-font-weight:bold}html pre.shiki code .sbgKg, html code.shiki .sbgKg{--shiki-light:#E53935;--shiki-light-font-weight:bold;--shiki-default:#E1E4E8;--shiki-default-font-weight:bold;--shiki-dark:#E1E4E8;--shiki-dark-font-weight:bold;--shiki-sepia:#66D9EF;--shiki-sepia-font-weight:bold}",{"id":120,"title":119,"titles":697,"content":361,"level":324},[],{"id":699,"title":535,"titles":700,"content":361,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fplayground#usage",[119],{"id":702,"title":703,"titles":704,"content":705,"level":367},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fplayground#stackblitz","Stackblitz",[119,535],"::playground\n---\nprovider: stackblitz\nrepo: nuxt\u002Fstarter\nbranch: v3\nfile: app.vue\n---\n::",{"id":707,"title":708,"titles":709,"content":710,"level":367},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fplayground#codesandbox","CodeSandbox",[119,535],"::playground\n---\nprovider: codesandbox\nrepo: nuxt\u002Fstarter\nbranch: v3\nfile: app.vue\n---\n::",{"id":712,"title":555,"titles":713,"content":714,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fplayground#props",[119],"Provider to useGitHub repository name (e.g. nuxt\u002Fstarter)Branch nameRepository ID (e.g. for Stackblitz github-t1vjvm, for Codesandbox 8hq5qn)You need to provide either repo or id prop, but not both. Directory to open in the playground (optional) File path to open Title of the iframe :: html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}",{"id":124,"title":123,"titles":716,"content":361,"level":324},[],{"id":718,"title":535,"titles":719,"content":720,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fread-more#usage",[123],":read-more{to=\"\u002Fgetting-started\u002Fwriting\u002Fmarkdown\"}\n:read-more{title=\"Nuxt website\" to=\"https:\u002F\u002Fnuxt.com\u002F\"}\n:read-more{to=\"https:\u002F\u002Fnuxt.com\u002F\"}\n:read-more{icon=\"lucide:link\" to=\"https:\u002F\u002Fnuxt.com\u002F\"}",{"id":722,"title":555,"titles":723,"content":724,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fread-more#props",[123],"Read More titleRead More iconLink URLA target attribute value to apply on the link html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html pre.shiki code .sdE5Q, html code.shiki .sdE5Q{--shiki-light:#9C3EDA;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}",{"id":128,"title":127,"titles":726,"content":361,"level":324},[],{"id":728,"title":535,"titles":729,"content":730,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fstack#usage",[127],"✨ shadcn-docs-nuxt---\ntitle: Installation\ndescription: How to install shadcn-docs-nuxt in your app.\nicon: lucide:play\n---\n\n## Using the starter template\nSee MDC components provided by shadcn-docs-nuxt. :: ::stack\n  ::div{class=\"p-6 text-3xl font-bold\"}\n  ✨ shadcn-docs-nuxt\n  ::\n\n  ```mdc\n  ---\n  title: Installation\n  description: How to install shadcn-docs-nuxt in your app.\n  icon: lucide:play\n  ---\n\n  ## Using the starter template\n  ```\n\n  :pm-x{command=\"nuxi@latest init \u003Cproject-name> -t github:ZTL-UwU\u002Fshadcn-docs-nuxt-starter\"}\n\n  :read-more{title=\"Installation\" to=\"\u002Fgetting-started\u002Finstallation\"}\n\n  ::card\n  ---\n  title: Components\n  icon: lucide:box\n  ---\n  See MDC components provided by **shadcn-docs-nuxt**.\n  ::\n:: :: Stackable components: divCode Blocksalertcalloutread-morecode-groupcode-treecardtabspm-installpm-runpm-x html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .syccL, html code.shiki .syccL{--shiki-light:#39ADB5;--shiki-light-font-weight:inherit;--shiki-default:#79B8FF;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold;--shiki-sepia:#A6E22E;--shiki-sepia-font-weight:bold}html pre.shiki code .sxAGG, html code.shiki .sxAGG{--shiki-light:#E2931D;--shiki-light-font-weight:inherit;--shiki-default:#79B8FF;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold;--shiki-sepia:#A6E22E;--shiki-sepia-font-weight:bold}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .sdE5Q, html code.shiki .sdE5Q{--shiki-light:#9C3EDA;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sy8J7, html code.shiki .sy8J7{--shiki-light:#91B859;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sxHrB, html code.shiki .sxHrB{--shiki-light:#90A4AE90;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sHk4K, html code.shiki .sHk4K{--shiki-light:#39ADB5;--shiki-light-font-weight:bold;--shiki-default:#E1E4E8;--shiki-default-font-weight:bold;--shiki-dark:#E1E4E8;--shiki-dark-font-weight:bold;--shiki-sepia:#66D9EF;--shiki-sepia-font-weight:bold}html pre.shiki code .sbgKg, html code.shiki .sbgKg{--shiki-light:#E53935;--shiki-light-font-weight:bold;--shiki-default:#E1E4E8;--shiki-default-font-weight:bold;--shiki-dark:#E1E4E8;--shiki-dark-font-weight:bold;--shiki-sepia:#66D9EF;--shiki-sepia-font-weight:bold}",{"id":132,"title":131,"titles":732,"content":361,"level":324},[],{"id":734,"title":535,"titles":735,"content":736,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fsteps#usage",[131],"Get Starter Templatenpx nuxi@latest init \u003Cproject-name> -t github:ZTL-UwU\u002Fshadcn-docs-nuxt-starter\npnpm dlx nuxi@latest init \u003Cproject-name> -t github:ZTL-UwU\u002Fshadcn-docs-nuxt-starter\nbunx nuxi@latest init \u003Cproject-name> -t github:ZTL-UwU\u002Fshadcn-docs-nuxt-starter\nAlternatively, you can clone or download the template from the GitHub repo.Install Dependenciesnpm install\npnpm install\nbun install\nDevelopment Servernpm run dev -- -o\npnpm dev -o\nbun run dev -o :: ::steps\n  ### Get Starter Template\n\n  ::code-group\n    ```bash [npm]\n    npx nuxi@latest init \u003Cproject-name> -t github:ZTL-UwU\u002Fshadcn-docs-nuxt-starter\n    ```\n    ```bash [pnpm]\n    pnpm dlx nuxi@latest init \u003Cproject-name> -t github:ZTL-UwU\u002Fshadcn-docs-nuxt-starter\n    ```\n    ```bash [bun]\n    bunx nuxi@latest init \u003Cproject-name> -t github:ZTL-UwU\u002Fshadcn-docs-nuxt-starter\n    ```\n  ::\n\n  ::alert\n  Alternatively, you can clone or download the template from the [GitHub repo](https:\u002F\u002Fgithub.com\u002FZTL-UwU\u002Fshadcn-docs-nuxt-starter).\n  ::\n\n  ### Install Dependencies\n\n  ::code-group\n    ```bash [npm]\n    npm install\n    ```\n    ```bash [pnpm]\n    pnpm install\n    ```\n    ```bash [bun]\n    bun install\n    ```\n  ::\n\n  ### Development Server\n\n  ::code-group\n    ```bash [npm]\n    npm run dev -- -o\n    ```\n    ```bash [pnpm]\n    pnpm dev -o\n    ```\n    ```bash [bun]\n    bun run dev -o\n    ```\n  ::\n:: ::",{"id":738,"title":739,"titles":740,"content":741,"level":367},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fsteps#multi-level-headings","Multi-level headings",[131,535],"0.4.6 Specify the level of headings to use::steps{:level=\"5\"}\nAvailable Headingsh1 through h6. Defaults to h3.::steps{:level=\"5\"}\n  ##### Multi-level headings\n\n  ```mdc\n  ::steps{:level=\"5\"}\n  ```\n\n  ##### Available Headings\n\n  `h1` through `h6`. Defaults to `h3`.\n::",{"id":743,"title":555,"titles":744,"content":745,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Fsteps#props",[131],"Specify the level of headings to use html pre.shiki code .sPYpf, html code.shiki .sPYpf{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .srSnV, html code.shiki .srSnV{--shiki-light:#39ADB5;--shiki-default:#F97583;--shiki-dark:#F97583;--shiki-sepia:#F92672}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .s7i02, html code.shiki .s7i02{--shiki-light:#91B859;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html pre.shiki code .syccL, html code.shiki .syccL{--shiki-light:#39ADB5;--shiki-light-font-weight:inherit;--shiki-default:#79B8FF;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold;--shiki-sepia:#A6E22E;--shiki-sepia-font-weight:bold}html pre.shiki code .sxAGG, html code.shiki .sxAGG{--shiki-light:#E2931D;--shiki-light-font-weight:inherit;--shiki-default:#79B8FF;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold;--shiki-sepia:#A6E22E;--shiki-sepia-font-weight:bold}html pre.shiki code .sy8J7, html code.shiki .sy8J7{--shiki-light:#91B859;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sxHrB, html code.shiki .sxHrB{--shiki-light:#90A4AE90;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .slHBl, html code.shiki .slHBl{--shiki-light:#91B859;--shiki-light-text-decoration:inherit;--shiki-default:#DBEDFF;--shiki-default-text-decoration:underline;--shiki-dark:#DBEDFF;--shiki-dark-text-decoration:underline;--shiki-sepia:#AE81FF;--shiki-sepia-text-decoration:inherit}html pre.shiki code .sqFf_, html code.shiki .sqFf_{--shiki-light:#90A4AE;--shiki-light-text-decoration:underline;--shiki-default:#E1E4E8;--shiki-default-text-decoration:underline;--shiki-dark:#E1E4E8;--shiki-dark-text-decoration:underline;--shiki-sepia:#E6DB74;--shiki-sepia-text-decoration:inherit}html pre.shiki code .sdE5Q, html code.shiki .sdE5Q{--shiki-light:#9C3EDA;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .spiKf, html code.shiki .spiKf{--shiki-light:#39ADB5;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#FD971F}html pre.shiki code .sAWxV, html code.shiki .sAWxV{--shiki-light:#91B859;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#FD971F}",{"id":136,"title":135,"titles":747,"content":361,"level":324},[],{"id":749,"title":535,"titles":750,"content":751,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ftabs#usage",[135],"PostgreSQL column typesimport { integer, pgTable } from 'drizzle-orm\u002Fpg-core';\n\nexport const table = pgTable('table', {\n  int: integer('int')\n});\nMySQL column typesimport { int, mysqlTable } from 'drizzle-orm\u002Fmysql-core';\n\nconst table = mysqlTable('table', {\n  int: int('int')\n});\nSQLite column typesimport { integer, sqliteTable } from 'drizzle-orm\u002Fsqlite-core';\n\nconst table = sqliteTable('table', {\n  id: integer('id')\n});\n\n\u002F\u002F you can customize integer mode to be number, boolean, timestamp, timestamp_ms\ninteger('id', { mode: 'number' });\ninteger('id', { mode: 'boolean' });\ninteger('id', { mode: 'timestamp_ms' });\ninteger('id', { mode: 'timestamp' }); \u002F\u002F Date\n::tabs\n  ::div{label=\"PostgreSQL\" icon=\"lucide:database\"}\n  ### PostgreSQL column types\n\n  ```ts\n  import { integer, pgTable } from 'drizzle-orm\u002Fpg-core';\n\n  export const table = pgTable('table', {\n    int: integer('int')\n  });\n  ```\n  ::\n  ::div{label=\"MySQL\"}\n  ### MySQL column types\n\n  ```ts\n  import { int, mysqlTable } from 'drizzle-orm\u002Fmysql-core';\n\n  const table = mysqlTable('table', {\n    int: int('int')\n  });\n  ```\n  ::\n  ::div{label=\"SQLite\"}\n  ### SQLite column types\n\n  ```ts\n  import { integer, sqliteTable } from 'drizzle-orm\u002Fsqlite-core';\n\n  const table = sqliteTable('table', {\n    id: integer('id')\n  });\n\n  \u002F\u002F you can customize integer mode to be number, boolean, timestamp, timestamp_ms\n  integer('id', { mode: 'number' });\n  integer('id', { mode: 'boolean' });\n  integer('id', { mode: 'timestamp_ms' });\n  integer('id', { mode: 'timestamp' }); \u002F\u002F Date\n  ```\n  ::\n::",{"id":753,"title":754,"titles":755,"content":756,"level":367},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ftabs#card-style","Card Style",[135,535],"This is a card-style tabThis is Tab #2console.log('Hello World!');\n::tabs{variant=\"card\"}\n  ::div{label=\"Card Tab\"}\n  ### This is a card-style tab\n  ::\n  ::div{label=\"Tab 2\" icon=\"lucide:atom\"}\n  This is Tab #2\n  ::\n  ```ts [Code Tab]\n  console.log('Hello World!');\n  ```\n::",{"id":758,"title":759,"titles":760,"content":761,"level":367},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ftabs#line-style","Line Style",[135,535],"0.6.4 Badgeimport { Badge } from \"@\u002Fcomponents\u002Fui\u002Fbadge\"\n\nexport function BadgeDemo() {\n  return \u003CBadge>Badge\u003C\u002FBadge>\n}\n::tabs{variant=\"line\"}\n  ::div{label=\"Preview\" class=\"border flex min-h-[200px] w-full justify-center p-10 items-center rounded-lg shadow-xs\"}\n    :badge[Badge]\n  ::\n  ::div{label=\"Code\"}\n    ```tsx\n    import { Badge } from \"@\u002Fcomponents\u002Fui\u002Fbadge\"\n\n    export function BadgeDemo() {\n      return \u003CBadge>Badge\u003C\u002FBadge>\n    }\n    ```\n  ::\n::",{"id":763,"title":764,"titles":765,"content":766,"level":367},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ftabs#combobox-style","Combobox Style",[135,535],"0.7.5 PostgreSQL column typesimport { integer, pgTable } from 'drizzle-orm\u002Fpg-core';\n\nexport const table = pgTable('table', {\n  int: integer('int')\n});\nMySQL column typesimport { int, mysqlTable } from 'drizzle-orm\u002Fmysql-core';\n\nconst table = mysqlTable('table', {\n  int: int('int')\n});\nSQLite column typesimport { integer, sqliteTable } from 'drizzle-orm\u002Fsqlite-core';\n\nconst table = sqliteTable('table', {\n  id: integer('id')\n});\n\n\u002F\u002F you can customize integer mode to be number, boolean, timestamp, timestamp_ms\ninteger('id', { mode: 'number' });\ninteger('id', { mode: 'boolean' });\ninteger('id', { mode: 'timestamp_ms' });\ninteger('id', { mode: 'timestamp' }); \u002F\u002F Date\n::tabs{variant=\"combobox\" search-placeholder=\"Search database...\" search-empty=\"No database found.\"}\n  ::div{label=\"PostgreSQL\"}\n  ### PostgreSQL column types\n\n  ```ts\n  import { integer, pgTable } from 'drizzle-orm\u002Fpg-core';\n\n  export const table = pgTable('table', {\n    int: integer('int')\n  });\n  ```\n  ::\n  ::div{label=\"MySQL\"}\n  ### MySQL column types\n\n  ```ts\n  import { int, mysqlTable } from 'drizzle-orm\u002Fmysql-core';\n\n  const table = mysqlTable('table', {\n    int: int('int')\n  });\n  ```\n  ::\n  ::div{label=\"SQLite\"}\n  ### SQLite column types\n\n  ```ts\n  import { integer, sqliteTable } from 'drizzle-orm\u002Fsqlite-core';\n\n  const table = sqliteTable('table', {\n    id: integer('id')\n  });\n\n  \u002F\u002F you can customize integer mode to be number, boolean, timestamp, timestamp_ms\n  integer('id', { mode: 'number' });\n  integer('id', { mode: 'boolean' });\n  integer('id', { mode: 'timestamp_ms' });\n  integer('id', { mode: 'timestamp' }); \u002F\u002F Date\n  ```\n  ::\n::",{"id":768,"title":769,"titles":770,"content":771,"level":367},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ftabs#synced-tabs","Synced Tabs",[135,535],"0.8.0 Scope 1This is a card-style tabconsole.log('Hello World!');\nThis is a card-style tabThis is Tab #2console.log('Hello World!');\nScope 2This is a card-style tabThis is Tab #2console.log('Hello World!');\nThis is a card-style tabThis is Tab #2console.log('Hello World!');\n#### Scope 1\n::tabs{variant=\"card\" sync=\"your-scope-name\"}\n  ::div{label=\"Card Tab\"}\n  ### This is a card-style tab\n  ::\n  ```ts [Code Tab]\n  console.log('Hello World!');\n  ```\n::\n::tabs{variant=\"card\" sync=\"your-scope-name\"}\n  ::div{label=\"Card Tab\"}\n  ### This is a card-style tab\n  ::\n  ::div{label=\"Tab 2\" icon=\"lucide:atom\"}\n  This is Tab #2\n  ::\n  ```ts [Code Tab]\n  console.log('Hello World!');\n  ```\n::\n\n#### Scope 2\n::tabs{variant=\"line\" sync=\"scope2\"}\n  ::div{label=\"Card Tab\"}\n  ### This is a card-style tab\n  ::\n  ::div{label=\"Tab 2\" icon=\"lucide:atom\"}\n  This is Tab #2\n  ::\n  ```ts [Code Tab]\n  console.log('Hello World!');\n  ```\n::\n::tabs{variant=\"separate\" sync=\"scope2\"}\n  ::div{label=\"Card Tab\"}\n  ### This is a card-style tab\n  ::\n  ::div{label=\"Tab 2\" icon=\"lucide:atom\"}\n  This is Tab #2\n  ::\n  ```ts [Code Tab]\n  console.log('Hello World!');\n  ```\n::",{"id":773,"title":555,"titles":774,"content":775,"level":335},"\u002Fdocs\u002F简单文档\u002Fcomponents\u002Ftabs#props",[135],"For combobox variantFor combobox variantFor combobox variantSync scope html pre.shiki code .sEIvO, html code.shiki .sEIvO{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#F97583;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit;--shiki-sepia:#F92672;--shiki-sepia-font-style:inherit}html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sLeJD, html code.shiki .sLeJD{--shiki-light:#9C3EDA;--shiki-light-font-style:inherit;--shiki-default:#F97583;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .sGtwI, html code.shiki .sGtwI{--shiki-light:#90A4AE;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#F8F8F2}html pre.shiki code .srSnV, html code.shiki .srSnV{--shiki-light:#39ADB5;--shiki-default:#F97583;--shiki-dark:#F97583;--shiki-sepia:#F92672}html pre.shiki code .sLcK_, html code.shiki .sLcK_{--shiki-light:#6182B8;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sHV4B, html code.shiki .sHV4B{--shiki-light:#E53935;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .ss7Ak, html code.shiki .ss7Ak{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit;--shiki-sepia:#88846F;--shiki-sepia-font-style:inherit}html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html pre.shiki code .sdE5Q, html code.shiki .sdE5Q{--shiki-light:#9C3EDA;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .syccL, html code.shiki .syccL{--shiki-light:#39ADB5;--shiki-light-font-weight:inherit;--shiki-default:#79B8FF;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold;--shiki-sepia:#A6E22E;--shiki-sepia-font-weight:bold}html pre.shiki code .sxAGG, html code.shiki .sxAGG{--shiki-light:#E2931D;--shiki-light-font-weight:inherit;--shiki-default:#79B8FF;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold;--shiki-sepia:#A6E22E;--shiki-sepia-font-weight:bold}html pre.shiki code .sy8J7, html code.shiki .sy8J7{--shiki-light:#91B859;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sxHrB, html code.shiki .sxHrB{--shiki-light:#90A4AE90;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .stRg-, html code.shiki .stRg-{--shiki-light:#E2931D;--shiki-light-font-style:inherit;--shiki-default:#79B8FF;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}",{"id":141,"title":145,"titles":777,"content":778,"level":324},[],"24小时无人自助系统,适合 棋牌室 台球厅 自习室 等场所使用 test",{"id":780,"title":781,"titles":782,"content":783,"level":324},"\u002Fdocs\u002Fabout","关于",[],"Estel Docs 文档系统",{"id":162,"title":161,"titles":785,"content":786,"level":324},[],"增加一些新的渲染，如脑图等",{"id":167,"title":166,"titles":788,"content":789,"level":324},[],"在数字化浪潮席卷全球的今天，服务器已成为承载企业核心业务与数据的“心脏”。一旦这颗心脏被攻破，轻则业务中断，重则数据泄漏、引发监管问责、品牌声誉坍塌，甚至于法律诉讼。",{"id":791,"title":792,"titles":793,"content":794,"level":367},"\u002Fblog\u002F技术栈\u002F服务器加固实战#前言","前言",[166],"在数字化浪潮席卷全球的今天，服务器已成为承载企业核心业务与数据的“心脏”。一旦这颗心脏被攻破，轻则业务中断，重则数据泄漏、引发监管问责、品牌声誉坍塌，甚至于法律诉讼。也正因如此，“我不知道漏洞藏在那里”已经不是借口，而是失责；真正负责任的运维与安全团队，必须把“ 防于未然，先固不破 ”当作铁律。 然而，系统配置千头万绪——从 BIOS 到内核参数，从系统服务到用户策略，从网络栈到文件权限——千里之堤，溃于蚁穴,任何一个角落的配置失误，都可能成为攻击者趁虚而入的跳板。“人眼”已无法在短时间内遍历所有细节，唯有借助安全团队丰富的经验与标准化的自动安全审计工具，将复杂环境拆解成可度量的检查项，才能在海量主机、混部容器与虚拟化场景中抽丝剥茧，还原安全真相。 本文将以 Lynis 审计工具来还原一次服务器加固实战。",{"id":796,"title":797,"titles":798,"content":361,"level":367},"\u002Fblog\u002F技术栈\u002F服务器加固实战#正文","正文",[166],{"id":800,"title":801,"titles":802,"content":803,"level":434},"\u002Fblog\u002F技术栈\u002F服务器加固实战#什么是lynis","什么是Lynis?",[166,797],"Lynis 是一款开源、针对基于 UNIX 系统（如 Linux、macOS、BSD 等）的安全审计工具。它能检测系统配置、文件权限、日志、网络等多个方面，提供详细的安全建议，帮助系统管理员加强系统的安全性。Lynis 通常被系统管理员和网络安全工程师用来评估其系统的安全防御能力。 除了“蓝队”之外，如今的渗透测试人员也将 Lynis 作为他们的工具之一。",{"id":805,"title":806,"titles":807,"content":808,"level":434},"\u002Fblog\u002F技术栈\u002F服务器加固实战#环境","环境",[166,797],"OS：Debian 12 (bookworm) 全新 Server 最小化安装内核：6.1.0-12-amd64（Debian 12 官方 6.1 LTS 最新版）架构：x86_64软件源 :启用 Debian Security 及官方主仓库用户：root 初始登录，已创建 sudo 普通用户 estel，后续所有操作便于演示均以 su - 模式执行时间：NTP 已启用，与 pool.ntp.org 同步，时区 UTC+8防火墙：iptables 未配置（默认空规则）已更新：apt update && apt full-upgrade -y 三天前更新已安装包： Docker nfs-server openssh-server",{"id":810,"title":811,"titles":812,"content":813,"level":434},"\u002Fblog\u002F技术栈\u002F服务器加固实战#使用","使用",[166,797],"# ssh 连接进服务器\n# 在合适的目录进行克隆 Lynis\ngit clone https:\u002F\u002Fgithub.com\u002FCISOfy\u002Flynis\n\n#执行安全审查脚本\ncd lynis && sudo .\u002Flynis audit system",{"id":815,"title":816,"titles":817,"content":818,"level":434},"\u002Fblog\u002F技术栈\u002F服务器加固实战#扫描结果部分摘录","扫描结果部分摘录",[166,797],"**[ Lynis 3.1.6 ]**\n  **Lynis security scan details**:\n  **Scan mode**:\n  Normal [▆]  Forensics [ ]  Integration [ ]  Pentest [ ]\n  **Lynis modules**:\n  - Compliance status      [**?**]\n  - Security audit         [**V**]\n  - Vulnerability scan     [**V**]\n  **Details**:\n  Hardening index : **63** [**############**        ]\n  Tests performed : **280**\n  Plugins enabled : **2**\n\n  **Software components**:\n  - Firewall               [**V**]\n  - Intrusion software     [**X**]\n  - Malware scanner        [**X**]\n\n  **Files**:\n  - Test and debug information      : **\u002Fvar\u002Flog\u002Flynis.log**\n  - Report data                     : **\u002Fvar\u002Flog\u002Flynis-report.dat**\n==============================================================\n    **Lynis** 3.1.6\n  Auditing, system hardening, and compliance for UNIX-based systems\n  (Linux, macOS, BSD, and others)\n  2007-2025, CISOfy - https:\u002F\u002Fcisofy.com\u002Flynis\u002F\n  **Enterprise support available (compliance, plugins, interface and tools)**",{"id":820,"title":821,"titles":822,"content":823,"level":434},"\u002Fblog\u002F技术栈\u002F服务器加固实战#结果分析","结果分析",[166,797],"根据 Lynis 的体检单Hardening Index 63\u002F100 系统概况 Debian 12，无内核更新，无重启需求，存在 2 个高风险补丁（PKGS-7392）。 关键问题 GRUB 无密码 ,可单用户模式提权\nSSH 端口为 22，允许 root 登录，多项参数过宽大量 systemd 服务暴露评分 9.x（atd、cron、docker、rsyslog 等）未挂载 \u002Fvar \u002Ftmp \u002Fhome 独立分区，可能导致 DoS缺乏防火墙规则审查、恶意软件扫描器、文件完整性监控、审计框架 次要风险 仅 1 个 DNS 服务器，NFS 空 exports 文件却运行守护进程USB\u002F火线驱动、编译器、核心参数未加固日志未远程归档、登录 banner 未配置",{"id":825,"title":826,"titles":827,"content":828,"level":434},"\u002Fblog\u002F技术栈\u002F服务器加固实战#进行服务器加固","进行服务器加固",[166,797],"# 为便于演示默认以下所有操作均在 root 权限下\nsu - # 更新系统补丁\napt update && apt dist-upgrade -y 给 GRUB 加密码 apt install -y grub2-common\ngrub-mkpasswd-pbkdf2 # 生成 PBKDF2 哈希\n\nnano \u002Fetc\u002Fgrub.d\u002F40_custom # 追加到配置中\n\ncat \u003C\u003CEOF\nset superusers=\"grubadmin\"\npassword_pbkdf2 grubadmin grub.pbkdf2.sha512.10000.xxxxxxxx...\nEOF\n\n# 更新\nupdate-grub\n\n#如果更新报错,改为在 40_custom 中追加\nset superusers=\"root\"\npassword_pbkdf2 grubadmin grub.pbkdf2.sha512.10000.xxxxxxxx... SSH 强化 # 修改 SSH 默认端口号 与登录配置\n\ncp \u002Fetc\u002Fssh\u002Fsshd_config{,.bak}\ncat >> \u002Fetc\u002Fssh\u002Fsshd_config \u003C\u003CEOF\nPort 49222\nPermitRootLogin no\nMaxAuthTries 3\nMaxSessions 2\nClientAliveInterval 300\nClientAliveCountMax 2\nAllowTcpForwarding no\nTCPKeepAlive no\nX11Forwarding no\nAllowAgentForwarding no\nLogLevel VERBOSE\nEOF\nsystemctl restart ssh 3.强化 sshd 安全 cp \u002Flib\u002Fsystemd\u002Fsystem\u002Fssh.service \u002Fetc\u002Fsystemd\u002Fsystem\u002Fssh.service\n\n# 使用 systemd-analyze security 的建议调整\nsystemctl edit --full ssh.service\n\nsystemctl restart ssh 禁用不必要的 systemd 服务 # atd 一次性计划任务守护进程，不需要调度就关掉；\n# exim4 Debian 系列默认的 MTA 邮件服务，不需要本地发件关掉；\n# containerd ‑ Docker\u002FK8s 的运行时，此服务不用容器关掉。\n\nsystemctl disable --now atd exim4 containerd Kernel 级系统参数 cat >\u002Fetc\u002Fsysctl.d\u002F99-hardening.conf \u003C\u003CEOF\ndev.tty.ldisc_autoload=0\nfs.protected_fifos=2\nkernel.core_uses_pid=1\nkernel.kptr_restrict=2\nkernel.unprivileged_bpf_disabled=1\nkernel.sysrq=0\nnet.core.bpf_jit_harden=2\nnet.ipv4.conf.all.log_martians=1\nnet.ipv4.conf.all.rp_filter=1\nnet.ipv4.conf.all.send_redirects=0\nnet.ipv4.conf.all.accept_redirects=0\nnet.ipv6.conf.all.accept_redirects=0\nnet.ipv6.conf.default.accept_redirects=0\nkernel.dmesg_restrict = 1\nEOF\nsysctl -p \u002Fetc\u002Fsysctl.d\u002F99-hardening.conf 内核部分参数解释 参数作用备注dev.tty.ldisc_autoload=0禁止非特权用户加载终端的 line discipline防御终端驱动注入攻击fs.protected_fifos=2严格保护 FIFO\u002F管道文件权限防止竞态条件漏洞kernel.core_uses_pid=1Core 转储文件名包含 PID方便调试但需配合 ulimit -c 限制kernel.kptr_restrict=2完全隐藏内核符号地址防内核信息泄漏kernel.unprivileged_bpf_disabled=1禁止非特权用户使用 BPF防御容器逃逸kernel.sysrq=0禁用 SysRq 组合键防止物理接触攻击net.core.bpf_jit_harden=2BPF JIT 编译器加固缓解 Spectre 漏洞net.ipv4.conf.all.log_martians=1记录异常 IP 包需配合日志监控net.ipv4.conf.all.rp_filter=1启用反向路径过滤防 IP 欺骗net.ipv4\u002F6.*.accept_redirects=0禁止 ICMP 重定向防网络拓扑劫持net.ipv4.conf.all.send_redirects=0禁止发送 ICMP 重定向仅路由器需要kernel.dmesg_restrict = 1防止非特权用户访问内核日志 关闭 USB \u002F 火线存储 cat >\u002Fetc\u002Fmodprobe.d\u002Fblacklist-usb-storage.conf \u003C\u003CEOF\ninstall usb-storage \u002Fbin\u002Ffalse\ninstall firewire-ohci \u002Fbin\u002Ffalse\nEOF\nrmmod usb-storage firewire-ohci || true 安装防护软件 # auditd（系统审计日志）、rkhunter（Rootkit 检测）\n# chkrootkit（基础 Rootkit 扫描）debsums（校验官方软件包完整性）\n# apparmor-profiles（强制访问控制策略）aide（文件完整性监控）\n\napt install -y auditd rkhunter chkrootkit debsums apparmor-profiles apparmor-profiles-extra aide\n\n# 初始化文件完整性（AIDE）需要较长时间,占用IO\naideinit\n\nsystemctl enable --now auditd 配置安全自动更新 apt install -y unattended-upgrades\ndpkg-reconfigure -plow unattended-upgrades",{"id":830,"title":831,"titles":832,"content":833,"level":434},"\u002Fblog\u002F技术栈\u002F服务器加固实战#复查扫描","复查扫描",[166,797],"lynis audit system\n\n# 扫描结果部分摘录\n\n  **Lynis security scan details**:\n  **Scan mode**:\n  Normal [▆]  Forensics [ ]  Integration [ ]  Pentest [ ]\n  **Lynis modules**:\n  - Compliance status      [**?**]\n  - Security audit         [**V**]\n  - Vulnerability scan     [**V**]\n\n  **Details**:\n  Hardening index : **78** [**###############**     ]\n  Tests performed : **283**\n  Plugins enabled : **2**\n\n  **Software components**:\n  - Firewall               [**V**]\n  - Intrusion software     [**X**]\n  - Malware scanner        [**V**]\n\n\n  **Files**:\n  - Test and debug information      : **\u002Fvar\u002Flog\u002Flynis.log**\n  - Report data                     : **\u002Fvar\u002Flog\u002Flynis-report.dat**\n\n==============================================================\n  **Lynis** 3.1.6\n\n  Auditing, system hardening, and compliance for UNIX-based systems\n  (Linux, macOS, BSD, and others)\n\n  2007-2025, CISOfy - https:\u002F\u002Fcisofy.com\u002Flynis\u002F\n  **Enterprise support available (compliance, plugins, interface and tools)**\n\n\n\n================================================================================",{"id":835,"title":836,"titles":837,"content":838,"level":434},"\u002Fblog\u002F技术栈\u002F服务器加固实战#加固完成","加固完成",[166,797],"加固指数：78（63↓ ➜ ↑78）告警数量：0（Great, no warnings）剩余建议：33 条，以“系统性、纵深优化”为主，无紧急风险**\n经过第一轮快速修补，本机已从 63 分 危险边缘 回到“可交付”水平：漏洞包归零。后续把“服务安全上下文 + 纵深防御”作为重点，逐步细化为零告警、高可信的 Debian 12 基线环境。目标在下一轮扫描中 ≥85 分，Warnings=0。遵循“未漏先防、未破先固”原则，持续加固即可。 类别关键动作预估加分系统服务对 docker.service、containerd.service、ssh.service 等仍处 UNSAFE\u002FEXPOSED 状态的单位，逐条应用 systemd-analyze security 推荐的安全参数（NoNewPrivileges、ProtectSystem 等）≈ +3–4 分审计规则为 auditd 导入 CIS 审计规则 → ACCT-9628≈ +2 分密码策略设定最小\u002F最大口令寿命、启用 pam_cracklib，统一 umask 027 → AUTH-9262\u002F9328≈ +2 分内核参数修正 fs.protected_fifos、kernel.yama.ptrace_scope 等 4 项 sysctl 差异 → KRNL-6000≈ +1 分纵深防御禁止 USB-Storage\u002FFireWire、配置远程日志、加固编译器 & cron 权限≈ +1 分",{"id":840,"title":841,"titles":842,"content":843,"level":335},"\u002Fblog\u002F技术栈\u002F服务器加固实战#总结","总结",[166],"通过本次基于 Lynis 的服务器安全加固实战，我们成功将一台\"裸奔\"的 Debian 12 服务器从 63 分的危险边缘状态提升至 78 分的可交付水平——这不仅是数字上的跃升，更是从\"千疮百孔\"逐步到\"基线合规\"的质变。从 GRUB 无密码、SSH 配置过宽，到内核参数缺失、关键服务暴露——每一项都是潜在的攻击入口，而工具化的检测让我们得以\"抽丝剥茧，还原安全真相\"。 更重要的是，78 分绝非终点。正如防于未然，先固不破的铁律所示，安全加固是一个持续迭代的过程：systemd 服务的深度加固、审计规则的精细配置、密码策略的严格管控——每一步都在为企业的数字资产构筑更坚固的防线。 在数字化浪潮愈发汹涌的今天，服务器安全已不容半点侥幸。那些仍抱着\"我不知道漏洞藏在哪里\"的心态，直到漏洞爆发才仓促补救的团队，终将在下一次攻击中付出惨重代价。真正负责任的做法，是把安全加固的重心从 \"事后补救\" 前移到 \"事前预防\"，让每一台服务器都成为攻击者难以逾越的堡垒。 千里之堤，毁于蚁穴；百密一疏，功亏一篑。唯有持之以恒的安全意识与标准化的加固流程，才能在这场没有硝烟的网络战争中立于不败之地。 html pre.shiki code .ss7Ak, html code.shiki .ss7Ak{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit;--shiki-sepia:#88846F;--shiki-sepia-font-style:inherit}html pre.shiki code .sPYpf, html code.shiki .sPYpf{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sunJZ, html code.shiki .sunJZ{--shiki-light:#6182B8;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#66D9EF}html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .srSnV, html code.shiki .srSnV{--shiki-light:#39ADB5;--shiki-default:#F97583;--shiki-dark:#F97583;--shiki-sepia:#F92672}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .s516T, html code.shiki .s516T{--shiki-light:#F76D47;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .sfg0g, html code.shiki .sfg0g{--shiki-light:#90A4AE;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#FD971F}html pre.shiki code .s7i02, html code.shiki .s7i02{--shiki-light:#91B859;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .sFw9b, html code.shiki .sFw9b{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#F8F8F2}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}",{"id":171,"title":170,"titles":845,"content":846,"level":324},[],"实战中使用nmap进行渗透测试和信息收集。 nmap -p- --min-rate=1000 -T4 -v -n -Pn 192.168.1.1",{"id":848,"title":849,"titles":850,"content":851,"level":434},"\u002Fblog\u002F技术栈\u002Fnmap高级应用技巧-实战#未完成","未完成",[170],"html pre.shiki code .sPYpf, html code.shiki .sPYpf{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .s7i02, html code.shiki .s7i02{--shiki-light:#91B859;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .s516T, html code.shiki .s516T{--shiki-light:#F76D47;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}",{"id":176,"title":175,"titles":853,"content":854,"level":324},[],"Nmap Scripting Engine（NSE）是Nmap的核心扩展功能，通过Lua脚本实现自动化扫描、漏洞检测、信息收集等高级操作。",{"id":856,"title":857,"titles":858,"content":854,"level":367},"\u002Fblog\u002F技术栈\u002Fnmap高级应用技巧-nse#nse","NSE",[175],{"id":860,"title":861,"titles":862,"content":863,"level":434},"\u002Fblog\u002F技术栈\u002Fnmap高级应用技巧-nse#nse脚本按功能分为12大类每类对应不同扫描需求","NSE脚本按功能分为12大类，每类对应不同扫描需求",[175,857],"类别核心目的样例脚本典型使用场合vulnCVE\u002F漏洞快速验证http-vuln-cve2017-5638目标服务版本与已知漏洞匹配safe只读式安全审计（无破坏性）ssh2-enum-algos建立会话后立即枚举支持的算法default默认已开启的基础信息采集http-title首次扫描时的“看一眼”discovery发现服务\u002F子网\u002F资产信息smb-os-discovery内网资产清点、OS 指纹识别auth认证、密钥与票据处理ssh-hostkey密钥指纹比对、横向渗透准备brute弱口令爆破http-form-brute对表单类登录口的暴力尝试exploit利用已确认漏洞取得立足点（需授权）http-vuln-cve2021-41773实战攻击复现、漏洞验证intrusive高交互操作（易被 IDS 告警）http-slowloris拒绝服务场景模拟\u002F压力测试（慎用！）malware嗅探后门或恶意软件痕迹http-malware-host威胁狩猎与入侵后取证version精细化版本指纹http-apache-negotiation为后续补丁或 PoC 匹配做准备broadcast广播域\u002F多播发现nbstat内网渗透早期：快速识别 NetBIOS 设备external外链第三方数据源（DNSBL 等）dns-blacklist资产信誉检查、垃圾邮件源或钓鱼域名扫描",{"id":865,"title":866,"titles":867,"content":868,"level":367},"\u002Fblog\u002F技术栈\u002Fnmap高级应用技巧-nse#常用-nse-脚本一览","常用 NSE 脚本一览",[175,857],"脚本名称主要用途Nmap 一键示例http-title抓取 HTTP 网站标题nmap --script http-title \u003Ctarget>https-redirect识别 HTTP→HTTPS 跳转链nmap --script https-redirect -p 80 \u003Ctarget>http-robtots收集目标 robots\u002Fdisallow 条目nmap --script http-robots.txt -p 80 \u003Ctarget>http-headers枚举响应标头与安全策略nmap --script http-headers -p 80 \u003Ctarget>http-methods检测允许\u002F禁止的 HTTP 方法nmap --script http-methods -p 80 \u003Ctarget>http-cors测试 CORS、CSRF 漏洞nmap --script http-cors \u003Ctarget>http-sql-injection基本 SQL 注入探针nmap --script http-sql-injection -p 80 \u003Ctarget>http-xssed与 xssed.com 集成交叉检测nmap --script http-xssed \u003Ctarget>smb-os-discovery枚举 SMB 服务器操作系统\u002F域信息nmap --script smb-os-discovery -p 445 \u003Ctarget>smb-enum-shares列出共享目录（需 guest）nmap --script smb-enum-shares -p 445 \u003Ctarget>smb-enum-users提取本地\u002F域用户列表nmap --script smb-enum-users -p 445 \u003Ctarget>smb-vuln-ms17-010探测 EternalBlue（MS17-010）nmap --script smb-vuln-ms17-010 -p 445 \u003Ctarget>ssh-hostkey抓取并对比公钥指纹nmap --script ssh-hostkey -p 22 \u003Ctarget>ssh-bruteSSH 账号密码暴力破解（需授权）nmap --script ssh-brute --script-args userdb=users.txt,passdb=pass.txt -p 22 \u003Ctarget>ssh2-enum-algos列出支持的算法与 KEXnmap --script ssh2-enum-algos -p 22 \u003Ctarget>http-vuln-cve2023-XXXX按指定 CVE 编号进行漏洞检查（替换 XXXX）nmap --script http-vuln-cve2023-XXXX \u003Ctarget>ftp-anon检测是否允许匿名登录nmap --script ftp-anon -p 21 \u003Ctarget>ftp-bounce检查是否允许 FTP Bounce 扫描nmap --script ftp-bounce -p 21 \u003Ctarget>dns-zone-transfer测试 AXFR（区域传输）泄露nmap --script dns-zone-transfer -p 53 \u003Ctarget>dns-brute字典爆破子域名nmap --script dns-brute --script-args dns-brute.domain=\u003Cdomain>mysql-brute暴力破解 MySQL 实例nmap --script mysql-brute -p 3306 \u003Ctarget>mysql-audit核对 MySQL CIS\u002F基线配置nmap --script mysql-audit --script-args mysql-audit.username='root',mysql-audit.password='pass123' -p 3306 \u003Ctarget>ssl-cert解析 TLS 证书详情nmap --script ssl-cert -p 443 \u003Ctarget>ssl-poodle探测 SSLv3 & POODLE 漏洞nmap --script ssl-poodle -p 443 \u003Ctarget>vulners基于 Vulners DB 的版本漏洞关联nmap --script vulners -sV \u003Ctarget>whois-ip查询归属 IP 段的 Whois 信息nmap --script whois-ip \u003Ctarget>smtp-enum-usersVRFY\u002FEXPN 暴力枚举邮箱账户nmap --script smtp-enum-users -p 25 \u003Ctarget>",{"id":870,"title":871,"titles":872,"content":873,"level":367},"\u002Fblog\u002F技术栈\u002Fnmap高级应用技巧-nse#自定义脚本","自定义脚本",[175,857],"-- myecho.nse\nlocal stdnse = require \"stdnse\"\n\ndescription     = [[极简回显脚本：打印自定义消息]]\nauthor          = \"YourName\"\nlicense         = \"GPLv2\"\ncategories      = {\"safe\"}\n\n-- 任何 TCP 端口都触发\nportrule = function(host,port) return port.protocol == \"tcp\" end\n\naction = function(host,port)\n  local msg = stdnse.get_script_args(\"myecho.msg\") or \"Hi from custom-NSE!\"\n  return (\"%s -> %s:%d (%s)\"):format(msg, host.ip, port.number, port.service or \"unknown\")\nend # 复制.nse到脚本文件夹\nsudo cp myecho.nse \u002Fusr\u002Fshare\u002Fnmap\u002Fscripts\u002F\nnmap --script-updatedb    # 更新索引 # 执行脚本\nnmap --script myecho -p22 127.0.0.1\nnmap --script myecho --script-args 'myecho.msg=HelloNSE' -p80 scanme.nmap.org\nnmap --script '(safe or discovery) and myecho' -p80,443 10.0.2.0\u002F24",{"id":875,"title":841,"titles":876,"content":877,"level":367},"\u002Fblog\u002F技术栈\u002Fnmap高级应用技巧-nse#总结",[175,857],"NSE 脚本可大幅提升 Nmap 在渗透测试和信息收集中的效率。建议定期关注 Nmap 官方脚本库更新（NSE Docs)以覆盖最新漏洞。 html pre.shiki code .ss7Ak, html code.shiki .ss7Ak{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit;--shiki-sepia:#88846F;--shiki-sepia-font-style:inherit}html pre.shiki code .sPYpf, html code.shiki .sPYpf{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .s7i02, html code.shiki .s7i02{--shiki-light:#91B859;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .s516T, html code.shiki .s516T{--shiki-light:#F76D47;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .srSnV, html code.shiki .srSnV{--shiki-light:#39ADB5;--shiki-default:#F97583;--shiki-dark:#F97583;--shiki-sepia:#F92672}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sunJZ, html code.shiki .sunJZ{--shiki-light:#6182B8;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#66D9EF}html pre.shiki code .sLcK_, html code.shiki .sLcK_{--shiki-light:#6182B8;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sEIvO, html code.shiki .sEIvO{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#F97583;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit;--shiki-sepia:#F92672;--shiki-sepia-font-style:inherit}html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sTTmg, html code.shiki .sTTmg{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E1E4E8;--shiki-default-font-style:inherit;--shiki-dark:#E1E4E8;--shiki-dark-font-style:inherit;--shiki-sepia:#FD971F;--shiki-sepia-font-style:italic}html pre.shiki code .s0FzF, html code.shiki .s0FzF{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#F8F8F2}",{"id":180,"title":179,"titles":879,"content":880,"level":324},[],"预览一些自定义 vue 组件语法 安装 MDC VS Code 扩展，以获得对 MDC 语法的高亮显示支持。  ::callout\n    ---\n    icon: simple-icons-visualstudiocode\n    to: https:\u002F\u002Fmarketplace.visualstudio.com\u002Fitems?itemName=Nuxt.mdc\n    ---\n    安装 **MDC VS Code 扩展**，以获得对 MDC 语法的高亮显示支持。\n  :: 这个页面 尚未完成,用于测试一些组件的语法和样式. 点击我查看内容这里是折叠区域的内容\n可以包含任何Markdown元素：段落列表代码块图片等 html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}",{"id":185,"title":184,"titles":882,"content":883,"level":324},[],"重新构建了渲染组件,优化了样式.",{"id":885,"title":886,"titles":887,"content":888,"level":335},"\u002Fblog\u002F技术栈\u002F新的文档渲染样式#重新对文档的样式进行了优化","重新对文档的样式进行了优化",[184],"周日在家闭关重写了十几个渲染组件。纯古法手工敲代码,兼容 Markdown 语法.部分 css 样式由 GPT-5 生成.大部分组件对主题进行了响应式处理,会根据主题进行不同的样式渲染",{"id":890,"title":415,"titles":891,"content":892,"level":367},"\u002Fblog\u002F技术栈\u002F新的文档渲染样式#_1-标题让你的内容层次分明",[184,886],"用 #号来创建标题。标题从 # 开始，# 的数量表示标题的级别。 一级标题二级标题三级标题四级标题五级标题六级标题  # 一级标题\n  ## 二级标题\n  ### 三级标题\n  #### 四级标题\n  ##### 五级标题\n  ###### 六级标题 以上代码将渲染出一组层次分明的标题，使你的内容井井有条。并且可以根据标题进行快速导航!",{"id":894,"title":895,"titles":896,"content":897,"level":367},"\u002Fblog\u002F技术栈\u002F新的文档渲染样式#_2-流程图与公式渲染","2. 流程图与公式渲染：",[184,886],"#mermaid-0{font-family:arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-0 .error-icon{fill:#552222;}#mermaid-0 .error-text{fill:#552222;stroke:#552222;}#mermaid-0 .edge-thickness-normal{stroke-width:1px;}#mermaid-0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-0 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-0 .marker{fill:#333333;stroke:#333333;}#mermaid-0 .marker.cross{stroke:#333333;}#mermaid-0 svg{font-family:arial,sans-serif;font-size:16px;}#mermaid-0 p{margin:0;}#mermaid-0 .label{font-family:arial,sans-serif;color:#333;}#mermaid-0 .cluster-label text{fill:#333;}#mermaid-0 .cluster-label span{color:#333;}#mermaid-0 .cluster-label span p{background-color:transparent;}#mermaid-0 .label text,#mermaid-0 span{fill:#333;color:#333;}#mermaid-0 .node rect,#mermaid-0 .node circle,#mermaid-0 .node ellipse,#mermaid-0 .node polygon,#mermaid-0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-0 .rough-node .label text,#mermaid-0 .node .label text,#mermaid-0 .image-shape .label,#mermaid-0 .icon-shape .label{text-anchor:middle;}#mermaid-0 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-0 .rough-node .label,#mermaid-0 .node .label,#mermaid-0 .image-shape .label,#mermaid-0 .icon-shape .label{text-align:center;}#mermaid-0 .node.clickable{cursor:pointer;}#mermaid-0 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-0 .arrowheadPath{fill:#333333;}#mermaid-0 .edgePath .path{stroke:#333333;stroke-width:1px;}#mermaid-0 .flowchart-link{stroke:#333333;fill:none;}#mermaid-0 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-0 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-0 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-0 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-0 .cluster text{fill:#333;}#mermaid-0 .cluster span{color:#333;}#mermaid-0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-0 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-0 rect.text{fill:none;stroke-width:0;}#mermaid-0 .icon-shape,#mermaid-0 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-0 .icon-shape p,#mermaid-0 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-0 .icon-shape .label rect,#mermaid-0 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-0 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-0 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-0 .node .neo-node{stroke:#9370DB;}#mermaid-0 [data-look=\"neo\"].node rect,#mermaid-0 [data-look=\"neo\"].cluster rect,#mermaid-0 [data-look=\"neo\"].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-0 [data-look=\"neo\"].node path{stroke:#9370DB;stroke-width:1px;}#mermaid-0 [data-look=\"neo\"].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-0 [data-look=\"neo\"].node .neo-line path{stroke:#9370DB;filter:none;}#mermaid-0 [data-look=\"neo\"].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-0 [data-look=\"neo\"].node circle .state-start{fill:#000000;}#mermaid-0 [data-look=\"neo\"].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-0 [data-look=\"neo\"].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-0 :root{--mermaid-font-family:arial,sans-serif;}Local Coolify 实例生产服务器编译服务器生产环境```mermaid[流程图语句.md]\ngraph TD\nA[Local Coolify 实例] --> B[生产服务器]\nA --> D[编译服务器]\nB --> B1[生产环境]\nD --> B #mermaid-1{font-family:arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-1 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-1 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-1 .error-icon{fill:#552222;}#mermaid-1 .error-text{fill:#552222;stroke:#552222;}#mermaid-1 .edge-thickness-normal{stroke-width:1px;}#mermaid-1 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-1 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-1 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-1 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-1 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-1 .marker{fill:#333333;stroke:#333333;}#mermaid-1 .marker.cross{stroke:#333333;}#mermaid-1 svg{font-family:arial,sans-serif;font-size:16px;}#mermaid-1 p{margin:0;}#mermaid-1 .pieCircle{stroke:black;stroke-width:2px;opacity:0.7;}#mermaid-1 .pieOuterCircle{stroke:black;stroke-width:2px;fill:none;}#mermaid-1 .pieTitleText{text-anchor:middle;font-size:25px;fill:black;font-family:arial,sans-serif;}#mermaid-1 .slice{font-family:arial,sans-serif;fill:#333;font-size:17px;}#mermaid-1 .legend text{fill:black;font-family:arial,sans-serif;font-size:17px;}#mermaid-1 .node .neo-node{stroke:#9370DB;}#mermaid-1 [data-look=\"neo\"].node rect,#mermaid-1 [data-look=\"neo\"].cluster rect,#mermaid-1 [data-look=\"neo\"].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-1 [data-look=\"neo\"].node path{stroke:#9370DB;stroke-width:1px;}#mermaid-1 [data-look=\"neo\"].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-1 [data-look=\"neo\"].node .neo-line path{stroke:#9370DB;filter:none;}#mermaid-1 [data-look=\"neo\"].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-1 [data-look=\"neo\"].node circle .state-start{fill:#000000;}#mermaid-1 [data-look=\"neo\"].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-1 [data-look=\"neo\"].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-1 :root{--mermaid-font-family:arial,sans-serif;}6%10%70%13%为什么总是宅在家里？喜欢宅天气太热穷没人约```mermaid[饼图语句.md]\npie\ntitle 为什么总是宅在家里？\n\"喜欢宅\" : 45\n\"天气太热\" : 70\n\"穷\" : 500\n\"没人约\" : 95 单行公式：用 $ 包裹公式，如 块级公式：用 $$ 包裹公式，如：列表内块公式- **单行公式**：用 `$` 包裹公式，如 $E = mc^2$\n- **块级公式**：用 `$$` 包裹公式，如：\n\n    $$\n    \\begin{aligned}\n    d_{i, j} &\\leftarrow d_{i, j} + 1 \\\\\n    d_{i, y + 1} &\\leftarrow d_{i, y + 1} - 1 \\\\\n    d_{x + 1, j} &\\leftarrow d_{x + 1, j} - 1 \\\\\n    d_{x + 1, y + 1} &\\leftarrow d_{x + 1, y + 1} + 1\n    \\end{aligned}\n    $$\n- 列表内块公式\n    $$\n    \\chi^2 = \\sum \\frac{(|O - E| - 0.5)^2}{E}\n    $$",{"id":899,"title":900,"titles":901,"content":902,"level":367},"\u002Fblog\u002F技术栈\u002F新的文档渲染样式#_3-代码块与代码树展示你的代码","3. 代码块与代码树：展示你的代码",[184,886],"行内代码：用反引号包裹，如 code。代码块：用三个反引号包裹，并指定语言，如： console.log(\"Hello, Estel Docs!\"); 代码树：用 ::code-tree 包裹，并指定默认值，如： @import \"tailwindcss\" theme(static);\n@import \"@nuxt\u002Fui-pro\";\nexport default defineAppConfig({\n  ui: {\n    colors: {\n      primary: 'sky',\n      colors: 'slate'\n    }\n  }\n});\n\u003Ctemplate>\n  \u003CUApp>\n    \u003CNuxtPage \u002F>\n  \u003C\u002FUApp>\n\u003C\u002Ftemplate>\n{\n  \"name\": \"nuxt-app\",\n  \"private\": true,\n  \"type\": \"module\",\n  \"scripts\": {\n    \"build\": \"nuxt build\",\n    \"dev\": \"nuxt dev\",\n    \"generate\": \"nuxt generate\",\n    \"preview\": \"nuxt preview\",\n    \"postinstall\": \"nuxt prepare\",\n    \"typecheck\": \"nuxt typecheck\"\n  },\n  \"dependencies\": {\n    \"@iconify-json\u002Flucide\": \"^1.2.18\",\n    \"@nuxt\u002Fui-pro\": \"3.0.0-alpha.10\",\n    \"nuxt\": \"^3.15.1\"\n  },\n  \"devDependencies\": {\n    \"typescript\": \"^5.7.2\",\n    \"vue-tsc\": \"^2.2.0\"\n  }\n}\n{\n  \"extends\": \".\u002F.nuxt\u002Ftsconfig.json\"\n}\nexport default defineNuxtConfig({\n  modules: ['@nuxt\u002Fui-pro'],\n\n  future: {\n    compatibilityVersion: 4\n  },\n\n  css: ['~\u002Fassets\u002Fmain.css']\n});\n# Estel Docs 文档系统\n\nLook at the [Estel Docs](https:\u002F\u002Flijue.net) to learn more.\n\n## 安装\n\n确保安装依赖:\n\n```bash\n# npm\nnpm install\n\n# pnpm\npnpm install\n\n# yarn\nyarn install\n\n# bun\nbun install\n```\n\n## 开发服务器\n\n在 `http:\u002F\u002Flocalhost:3000` 启动开发服务器:\n\n```bash\n# npm\nnpm run dev\n\n# pnpm\npnpm run dev\n\n# yarn\nyarn dev\n\n# bun\nbun run dev\n```\n\n## 生产构建\n\n构建生产应用:\n\n```bash\n# npm\nnpm run build\n\n# pnpm\npnpm run build\n\n# yarn\nyarn build\n\n# bun\nbun run build\n```\n\n本地预览生产构建:\n\n```bash\n# npm\nnpm run preview\n\n# pnpm\npnpm run preview\n\n# yarn\nyarn preview\n\n# bun\nbun run preview\n```\n\n查看 [部署文档](https:\u002F\u002Flijue.net\u002F) 了解更多信息. 代码树可以用来展示简单的项目文件结构.但并不适合过于复杂的项目.",{"id":904,"title":905,"titles":906,"content":455,"level":367},"\u002Fblog\u002F技术栈\u002F新的文档渲染样式#_4-字体样式强调你的文字","4. 字体样式：强调你的文字",[184,886],{"id":908,"title":909,"titles":910,"content":460,"level":367},"\u002Fblog\u002F技术栈\u002F新的文档渲染样式#_5-列表整洁有序","5. 列表：整洁有序",[184,886],{"id":912,"title":913,"titles":914,"content":915,"level":367},"\u002Fblog\u002F技术栈\u002F新的文档渲染样式#_6-链接与图片丰富内容","6. 链接与图片：丰富内容",[184,886],"链接：用方括号和圆括号创建链接 [显示文本](链接地址)。图片：和链接类似，只需在前面加上 !，如 ![描述文本](图片链接)。 访问 Estel Docs ![Estel Docs](https:\u002F\u002Fimg.lijue.net\u002F20250811123147804.png)",{"id":917,"title":918,"titles":919,"content":920,"level":367},"\u002Fblog\u002F技术栈\u002F新的文档渲染样式#_7-引用引用名言或引人深思的句子","7. 引用：引用名言或引人深思的句子",[184,886],"使用 > 来创建引用，只需在文本前面加上它。多层引用？在前一层 > 后再加一个就行。 这是一个引用这是一个嵌套引用 这让你的引用更加富有层次感。 语法高亮让你的代码更易读。",{"id":922,"title":478,"titles":923,"content":480,"level":367},"\u002Fblog\u002F技术栈\u002F新的文档渲染样式#_8-分割线分割内容",[184,886],{"id":925,"title":483,"titles":926,"content":927,"level":367},"\u002Fblog\u002F技术栈\u002F新的文档渲染样式#_9-表格清晰展示数据",[184,886],"Markdown 支持简单的表格，用 `|` 和 `-` 分隔单元格和表头。 项目名称演示网址仓库地址Estel Docslijue.netGithubEstel Docslijue.netGitEEEstel Docslijue.netGitee(国内)| 项目名称                                   | 演示网址                   | 仓库地址   |\n| ------------------------------------------- | ---------------------- | ------------ |\n| Estel Docs   | [lijue.net](https:\u002F\u002Flijue.net) | [Github](https:\u002F\u002Fgithub.com\u002Festel-li\u002Festel-docs)      |\n| Estel Docs   | [lijue.net](https:\u002F\u002Flijue.net) | [GitEE](https:\u002F\u002Fgitee.com\u002Festel-li\u002Festel-docs)      |\n| Estel Docs   | [lijue.net](https:\u002F\u002Flijue.net) | [Gitee(国内)](https:\u002F\u002Fgitee.com\u002Festel-li\u002Festel-docs)      | 这样的表格让数据展示更为清爽！",{"id":929,"title":507,"titles":930,"content":931,"level":335},"\u002Fblog\u002F技术栈\u002F新的文档渲染样式#结语",[184],"- 还有更多的组件等待你发现. mjx-container[jax=\"SVG\"] {\n  direction: ltr;\n}\n\nmjx-container[jax=\"SVG\"] > svg {\n  overflow: visible;\n  min-height: 1px;\n  min-width: 1px;\n}\n\nmjx-container[jax=\"SVG\"] > svg a {\n  fill: blue;\n  stroke: blue;\n}\n\nmjx-container[jax=\"SVG\"][display=\"true\"] {\n  display: block;\n  text-align: center;\n  margin: 1em 0;\n}\n\nmjx-container[jax=\"SVG\"][display=\"true\"][width=\"full\"] {\n  display: flex;\n}\n\nmjx-container[jax=\"SVG\"][justify=\"left\"] {\n  text-align: left;\n}\n\nmjx-container[jax=\"SVG\"][justify=\"right\"] {\n  text-align: right;\n}\n\ng[data-mml-node=\"merror\"] > g {\n  fill: red;\n  stroke: red;\n}\n\ng[data-mml-node=\"merror\"] > rect[data-background] {\n  fill: yellow;\n  stroke: none;\n}\n\ng[data-mml-node=\"mtable\"] > line[data-line], svg[data-table] > g > line[data-line] {\n  stroke-width: 70px;\n  fill: none;\n}\n\ng[data-mml-node=\"mtable\"] > rect[data-frame], svg[data-table] > g > rect[data-frame] {\n  stroke-width: 70px;\n  fill: none;\n}\n\ng[data-mml-node=\"mtable\"] > .mjx-dashed, svg[data-table] > g > .mjx-dashed {\n  stroke-dasharray: 140;\n}\n\ng[data-mml-node=\"mtable\"] > .mjx-dotted, svg[data-table] > g > .mjx-dotted {\n  stroke-linecap: round;\n  stroke-dasharray: 0,140;\n}\n\ng[data-mml-node=\"mtable\"] > g > svg {\n  overflow: visible;\n}\n\n[jax=\"SVG\"] mjx-tool {\n  display: inline-block;\n  position: relative;\n  width: 0;\n  height: 0;\n}\n\n[jax=\"SVG\"] mjx-tool > mjx-tip {\n  position: absolute;\n  top: 0;\n  left: 0;\n}\n\nmjx-tool > mjx-tip {\n  display: inline-block;\n  padding: .2em;\n  border: 1px solid #888;\n  font-size: 70%;\n  background-color: #F8F8F8;\n  color: black;\n  box-shadow: 2px 2px 5px #AAAAAA;\n}\n\ng[data-mml-node=\"maction\"][data-toggle] {\n  cursor: pointer;\n}\n\nmjx-status {\n  display: block;\n  position: fixed;\n  left: 1em;\n  bottom: 1em;\n  min-width: 25%;\n  padding: .2em .4em;\n  border: 1px solid #888;\n  font-size: 90%;\n  background-color: #F8F8F8;\n  color: black;\n}\n\nforeignObject[data-mjx-xml] {\n  font-family: initial;\n  line-height: normal;\n  overflow: visible;\n}\n\nmjx-container[jax=\"SVG\"] path[data-c], mjx-container[jax=\"SVG\"] use[data-c] {\n  stroke-width: 3;\n} html pre.shiki code .syccL, html code.shiki .syccL{--shiki-light:#39ADB5;--shiki-light-font-weight:inherit;--shiki-default:#79B8FF;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold;--shiki-sepia:#A6E22E;--shiki-sepia-font-weight:bold}html pre.shiki code .sxAGG, html code.shiki .sxAGG{--shiki-light:#E2931D;--shiki-light-font-weight:inherit;--shiki-default:#79B8FF;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold;--shiki-sepia:#A6E22E;--shiki-sepia-font-weight:bold}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sLcK_, html code.shiki .sLcK_{--shiki-light:#6182B8;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sEIvO, html code.shiki .sEIvO{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#F97583;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit;--shiki-sepia:#F92672;--shiki-sepia-font-style:inherit}html pre.shiki code .sHV4B, html code.shiki .sHV4B{--shiki-light:#E53935;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html pre.shiki code .ss27W, html code.shiki .ss27W{--shiki-light:#39ADB5;--shiki-light-font-style:inherit;--shiki-default:#79B8FF;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .szxyS, html code.shiki .szxyS{--shiki-light:#9C3EDA;--shiki-light-font-style:inherit;--shiki-default:#79B8FF;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .si2Vc, html code.shiki .si2Vc{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#CFCFC2}html pre.shiki code .sO9wW, html code.shiki .sO9wW{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#CFCFC2}html pre.shiki code .sQnY8, html code.shiki .sQnY8{--shiki-light:#39ADB5;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .stRg-, html code.shiki .stRg-{--shiki-light:#E2931D;--shiki-light-font-style:inherit;--shiki-default:#79B8FF;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .s516T, html code.shiki .s516T{--shiki-light:#F76D47;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .slHBl, html code.shiki .slHBl{--shiki-light:#91B859;--shiki-light-text-decoration:inherit;--shiki-default:#DBEDFF;--shiki-default-text-decoration:underline;--shiki-dark:#DBEDFF;--shiki-dark-text-decoration:underline;--shiki-sepia:#AE81FF;--shiki-sepia-text-decoration:inherit}html pre.shiki code .svcTW, html code.shiki .svcTW{--shiki-light:#E53935;--shiki-light-text-decoration:underline;--shiki-default:#E1E4E8;--shiki-default-text-decoration:underline;--shiki-dark:#E1E4E8;--shiki-dark-text-decoration:underline;--shiki-sepia:#E6DB74;--shiki-sepia-text-decoration:inherit}html pre.shiki code .sy8J7, html code.shiki .sy8J7{--shiki-light:#91B859;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sxHrB, html code.shiki .sxHrB{--shiki-light:#90A4AE90;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .ss7Ak, html code.shiki .ss7Ak{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit;--shiki-sepia:#88846F;--shiki-sepia-font-style:inherit}html pre.shiki code .sPYpf, html code.shiki .sPYpf{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .spiKf, html code.shiki .spiKf{--shiki-light:#39ADB5;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#FD971F}html pre.shiki code .sAWxV, html code.shiki .sAWxV{--shiki-light:#91B859;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#FD971F}html pre.shiki code .sqFf_, html code.shiki .sqFf_{--shiki-light:#90A4AE;--shiki-light-text-decoration:underline;--shiki-default:#E1E4E8;--shiki-default-text-decoration:underline;--shiki-dark:#E1E4E8;--shiki-dark-text-decoration:underline;--shiki-sepia:#E6DB74;--shiki-sepia-text-decoration:inherit}",{"id":190,"title":189,"titles":933,"content":934,"level":324},[],"微信分享接口,使用Nuxt,实现微信分享接口.",{"id":936,"title":937,"titles":938,"content":361,"level":367},"\u002Fblog\u002F技术栈\u002Fnuxt-微信分享接口#需求","需求",[189],{"id":940,"title":941,"titles":942,"content":361,"level":439},"\u002Fblog\u002F技术栈\u002Fnuxt-微信分享接口#写了一个文档插件-缘由呢是之前在-wordpress-上用过一个插件对接微信的js-sdk可以实现将链接带标题图简介封装成一个-卡片形式分享给朋友或者朋友圈比如","写了一个文档插件. 缘由呢是之前在 WordPress 上用过一个插件.对接微信的JS SDK,可以实现将链接带标题,图,简介封装成一个 卡片形式.分享给朋友或者朋友圈.比如:",[189,937],{"id":944,"title":945,"titles":946,"content":361,"level":439},"\u002Fblog\u002F技术栈\u002Fnuxt-微信分享接口#如果没有对接微信的sdk分享链接是这样的","如果没有对接微信的SDK,分享链接是这样的:",[189,937],{"id":948,"title":949,"titles":950,"content":361,"level":367},"\u002Fblog\u002F技术栈\u002Fnuxt-微信分享接口#实现","实现",[189,937],{"id":952,"title":953,"titles":954,"content":955,"level":439},"\u002Fblog\u002F技术栈\u002Fnuxt-微信分享接口#这个功能实现起来也不复杂其中麻烦的地方是向微信获取-access_token-和-jsapi_ticket这样迫不得已就得写一个后端","这个功能实现起来也不复杂,其中麻烦的地方是向微信获取 access_token 和 jsapi_ticket,这样迫不得已就得写一个后端.",[189,937,949],"type WeChat = {\nconfig: (cfg: {\ndebug?: boolean\nappId: string\ntimestamp: number\nnonceStr: string\nsignature: string\njsApiList: string[]\n}) => void\nready: (cb: () => void) => void\nerror: (cb: (e: unknown) => void) => void\nupdateTimelineShareData: (opts: { title: string, link: string, imgUrl: string, success?: () => void }) => void\nupdateAppMessageShareData: (opts: { title: string, desc: string, link: string, imgUrl: string, success?: () => void }) => void\n} 有利有弊因为要动态向微信请求 access_token 和 jsapi_ticket,并在生命周期内缓存起来,就必须得有个后端,将其包装成了一个 API ,运行在 Nuxt 的服务器但这样就没办法纯静态编译了 html pre.shiki code .sLeJD, html code.shiki .sLeJD{--shiki-light:#9C3EDA;--shiki-light-font-style:inherit;--shiki-default:#F97583;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .sfCVZ, html code.shiki .sfCVZ{--shiki-light:#E2931D;--shiki-light-text-decoration:inherit;--shiki-default:#B392F0;--shiki-default-text-decoration:inherit;--shiki-dark:#B392F0;--shiki-dark-text-decoration:inherit;--shiki-sepia:#A6E22E;--shiki-sepia-text-decoration:underline}html pre.shiki code .srSnV, html code.shiki .srSnV{--shiki-light:#39ADB5;--shiki-default:#F97583;--shiki-dark:#F97583;--shiki-sepia:#F92672}html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sZKdv, html code.shiki .sZKdv{--shiki-light:#E53935;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .shyvS, html code.shiki .shyvS{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#FFAB70;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit;--shiki-sepia:#FD971F;--shiki-sepia-font-style:italic}html pre.shiki code .sM4QW, html code.shiki .sM4QW{--shiki-light:#E53935;--shiki-default:#FFAB70;--shiki-dark:#FFAB70;--shiki-sepia:#F8F8F2}html pre.shiki code .stRg-, html code.shiki .stRg-{--shiki-light:#E2931D;--shiki-light-font-style:inherit;--shiki-default:#79B8FF;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}",{"id":194,"title":193,"titles":957,"content":958,"level":324},[],"智能合同卫士,使用AI技术,对合同进行审查,并给出审查报告.",{"id":960,"title":961,"titles":962,"content":361,"level":367},"\u002Fblog\u002F技术栈\u002Fai复合应用-合同审查#先贴效果","先贴效果",[193],{"id":964,"title":965,"titles":966,"content":967,"level":367},"\u002Fblog\u002F技术栈\u002Fai复合应用-合同审查#这是一个-ai-复合应用","这是一个 AI 复合应用",[193],"暂起名叫 智能合同卫士 ,还是比较贴题的把?",{"id":969,"title":949,"titles":970,"content":971,"level":367},"\u002Fblog\u002F技术栈\u002Fai复合应用-合同审查#实现",[193],"由 Deepseek V3 和 Kimi K2 协作完成此应用,2个好用不贵的模型\nDS 根据文件名,以及 审查主体 工作领域 与 合同要点,细化一份简要的审查要点\n主要工作由 Kimi K2 来完成:\n根据 Deepseek 细化的要点和 提取出来的文档内容,进行审查.\n输出审查后的结果",{"id":973,"title":974,"titles":975,"content":976,"level":367},"\u002Fblog\u002F技术栈\u002Fai复合应用-合同审查#改进","改进",[193],"按照初步的设想,后续还有一个模型,比如 Gemini2.5 ,或者 R1 ,Qwen3 之类的推理模型,进一步的审查 Kimi K2 的审查结果.\n不过 K2 单独使用的实际效果已经非常好了,为了节省时间和成本,暂时取掉最后一步.\n使用 AI 的话,不论是 R1 还是 K2 都是有一定的幻觉,在使用中必须搭配知识库来使用. 注意这次测试并没有加知识库,所以 AI 虚构了一些内容,比如当地房价涨幅 ,和虚构的 《陕西省住房租赁管理办法》.给大模型增加搜索能力,和在知识库里添加 民法典 等相关法律条文进去,可以有效的解决幻觉问题.",{"id":199,"title":198,"titles":978,"content":979,"level":324},[],"在 Kali 上安装 GVM",{"id":981,"title":982,"titles":983,"content":984,"level":367},"\u002Fblog\u002F技术栈\u002Fkali-安装-gvm#配置安装好-kali","配置安装好 Kali",[198],"# 安装 gvm\nsudo apt install gvm -y\n# 执行配置脚本\nsudo gvm-setup",{"id":986,"title":987,"titles":988,"content":989,"level":367},"\u002Fblog\u002F技术栈\u002Fkali-安装-gvm#安装过程中-copy-admin-的密码","安装过程中 copy admin 的密码",[198],"根据提示运行安装检测命令 sudo gvm-check-setup 报错了. └─**$** sudo gvm-check-setup\n[sudo] estel 的密码：\ngvm-check-setup 25.04.0\n This script is provided and maintained by Debian and Kali.\n  Test completeness and readiness of GVM-25.04.0\nStep 1: Checking OpenVAS (Scanner)...\n        OK: OpenVAS Scanner is present in version 23.20.1.\n        OK: Notus Scanner is present in version 22.6.5.\n        OK: Server CA Certificate is present as \u002Fvar\u002Flib\u002Fgvm\u002FCA\u002Fservercert.pem.\nChecking permissions of \u002Fvar\u002Flib\u002Fopenvas\u002Fgnupg\u002F*\n        OK: _gvm owns all files in \u002Fvar\u002Flib\u002Fopenvas\u002Fgnupg\n\n        OK: redis-server is present.\n        OK: scanner (db_address setting) is configured properly using the redis-server socket: \u002Fvar\u002Frun\u002Fredis-openvas\u002Fredis-server.sock\n        OK: the mqtt_server_uri is defined in \u002Fetc\u002Fopenvas\u002Fopenvas.conf\n        OK: _gvm owns all files in \u002Fvar\u002Flib\u002Fopenvas\u002Fplugins\n        OK: NVT collection in \u002Fvar\u002Flib\u002Fopenvas\u002Fplugins contains 94316 NVTs.\n        OK: The notus directory \u002Fvar\u002Flib\u002Fnotus\u002Fproducts contains 502 NVTs.\nChecking that the obsolete redis database has been removed\nCould not connect to Redis at \u002Fvar\u002Frun\u002Fredis-openvas\u002Fredis-server.sock: No such file or directory\n        OK: No old Redis DB\n        Starting ospd-openvas service\n        Waiting for ospd-openvas service\n        OK: ospd-openvas service is active.\n        OK: ospd-OpenVAS is present in version 22.9.0.\nStep 2: Checking GVMD Manager ...\n        OK: GVM Manager (gvmd) is present in version 26.0.0.\nStep 3: Checking Certificates ...\n        OK: GVM client certificate is valid and present as \u002Fvar\u002Flib\u002Fgvm\u002FCA\u002Fclientcert.pem.\n        OK: Your GVM certificate infrastructure passed validation.\nStep 4: Checking data ...\n        ERROR: SCAP DATA are missing.\n        FIX: Run the SCAP synchronization script greenbone-feed-sync.\n        sudo greenbone-feed-sync --type scap.\n ERROR: Your GVM-25.04.0 installation is not yet complete!\nPlease follow the instructions marked with FIX above and run this\nscript again.\n\n IMPORTANT NOTE: this script is provided and maintained by Debian and Kali.\n If you find any issue in this script, please report it directly to Debian or Kali 标准漏洞\u002F数据库这些数据在国外\n给路由器施加魔法,然后重新运行,安静等待 DownLoading............ sudo greenbone-feed-sync --type scap 下载好后再次运行检测命令,一起无误后,访问 127.0.0.1:9293 即可\n等等...我的 Kali 是安装在其他设备里的,如何通过局域网访问? sudo nano \u002Flib\u002Fsystemd\u002Fsystem\u002Fgreenbone-security-assistant.service # 修改下面的 --listen 127.0.0.1 为 --listen 0.0.0.0 即可\n**[Unit]**\nDescription=Greenbone Security Assistant daemon (gsad)\nDocumentation=man:gsad(8) https:\u002F\u002Fwww.greenbone.net\nAfter=network.target gvmd.service\nWants=gvmd.service\n\n**[Service]**\nType=exec\nUser=_gvm\nGroup=_gvm\nRuntimeDirectory=gsad\nRuntimeDirectoryMode=2775\nPIDFile=\u002Frun\u002Fgsad\u002Fgsad.pid\nExecStart=\u002Fusr\u002Fsbin\u002Fgsad --foreground --listen 127.0.0.1 --port 9392\nRestart=always\nTimeoutStopSec=10\n\n**[Install]**\nWantedBy=multi-user.target\nAlias=greenbone-security-assistant.service # 重新开始服务\nsudo gvm-start 随后等待程序自动更新提要状态,需要时间非常久.建议释放魔法.\n如果自动更新失败,可以手动更新: sudo greenbone-feed-sync",{"id":991,"title":992,"titles":993,"content":994,"level":367},"\u002Fblog\u002F技术栈\u002Fkali-安装-gvm#end","END",[198],"至此安装完毕. html pre.shiki code .ss7Ak, html code.shiki .ss7Ak{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit;--shiki-sepia:#88846F;--shiki-sepia-font-style:inherit}html pre.shiki code .sPYpf, html code.shiki .sPYpf{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .s7i02, html code.shiki .s7i02{--shiki-light:#91B859;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .s516T, html code.shiki .s516T{--shiki-light:#F76D47;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .sfg0g, html code.shiki .sfg0g{--shiki-light:#90A4AE;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#FD971F}html pre.shiki code .srSnV, html code.shiki .srSnV{--shiki-light:#39ADB5;--shiki-default:#F97583;--shiki-dark:#F97583;--shiki-sepia:#F92672}",{"id":204,"title":203,"titles":996,"content":997,"level":324},[],"GPT-5 上线了,Cursor 提示我可以免费试用，当然要 BP 喽。",{"id":999,"title":1000,"titles":1001,"content":1002,"level":367},"\u002Fblog\u002F技术栈\u002Fgpt5#gpt-5-上线了","GPT-5 上线了",[203],"👀 Cursor 提示我可以免费试用，当然要 BP 喽。",{"id":1004,"title":1005,"titles":1006,"content":1007,"level":367},"\u002Fblog\u002F技术栈\u002Fgpt5#问题场景","🔥 问题场景",[203],"此时正遇到的一个问题是：**NUXT4 项目在本地 dev 一切正常，但在服务器上对中文路径报错 500**。\n  这个问题很简单，但又很复杂。",{"id":1009,"title":1010,"titles":1011,"content":1012,"level":367},"\u002Fblog\u002F技术栈\u002Fgpt5#问题背景","🧩 问题背景",[203],"项目环境NUXT4 项目现象本地开发环境运行正常；服务器部署后直接访问中文路径报错 500，通过内部路由正常自动化部署流程 代码推送至 GitHubGitHub CI 服务器自动打包 Docker 镜像 → 推送至私人 Docker 库触发 webhook → Coolify 服务器 ssh 连接国内云服务器拉取镜像Coolify 完成部署（Nginx 反代转发到 Docker 容器）",{"id":1014,"title":1015,"titles":1016,"content":1017,"level":367},"\u002Fblog\u002F技术栈\u002Fgpt5#排查猜想","🤔 排查猜想",[203],"是打包编译过程出问题了，还是服务器上 nginx 反代的问题？或者是 NUXT 自身 SSR 的问题？\n  其实内心差不多有了谱，刚好提示 GPT-5 更新了，就测试一下看看 GPT-5 能否解决这个问题。",{"id":1019,"title":1020,"titles":1021,"content":1022,"level":367},"\u002Fblog\u002F技术栈\u002Fgpt5#实测结论","✅ 实测结论",[203],"直接说结论：完美解决。 同时使用 Kimi-K2 (Claude Code) 和 GPT-5 (Cursor内置) 进行分析：",{"id":1024,"title":1025,"titles":1026,"content":1027,"level":434},"\u002Fblog\u002F技术栈\u002Fgpt5#kimi-k2-的表现","💡 Kimi-K2 的表现",[203,1020],"1. 先是读取了项目文件，得出错误结论：\n  > “生产环境静态文件\u002F最终产物里没有对应的 `.md`，导致 `queryContent` 查询到 `null`”\n  2. 按照它的建议把文档拷贝到编译产出文件夹，问题依旧。\n  3. 坚持认为是 Nginx 的问题，我告诉它和 Nginx 反代没关系，这货死倔\n  （实际上本地直接启动 node 服务也会报错，根本不是服务器问题）。",{"id":1029,"title":1030,"titles":1031,"content":1032,"level":434},"\u002Fblog\u002F技术栈\u002Fgpt5#gpt-5-的表现cursor内置","🚀 GPT-5 的表现（Cursor内置）",[203,1020],"自主执行了十几分钟测试跑了几十条命令输出上百条日志消耗约 1.x 美元 token（幸亏 Cursor 说免费）在 Node 堆栈日志中发现静态渲染配置异常自动修改了静态渲染相关的文件夹配置反复测试确认无误 🥳 小插曲：GPT-5 自言自语地排查问题挺有意思，它自己嘀咕\n“这个问题很棘手...”",{"id":1034,"title":1035,"titles":1036,"content":1037,"level":367},"\u002Fblog\u002F技术栈\u002Fgpt5#总结","📌 总结",[203,1020],"虽然是个小问题，但我并没有给 AI 说太多细节，全让他们自己找、自己判断、自己修改并测试——\n  - **GPT-5 确实牛**，它可输出 token 很多，这次价格也算可以。\n  - **Kimi-K2 处理小问题、不太复杂的问题**确实挺好用，价格也不算便宜。\n  > 复杂问题，以前要么 **Claude 4**，要不 **Gemini 2.5 pro**，现在又多了一个选择了。",{"id":209,"title":208,"titles":1039,"content":1040,"level":324},[],"利用 AI 技术实现对内网环境的实时监控、威胁检测与自动化防御，提升企业网络安全防护能力。",{"id":1042,"title":1043,"titles":1044,"content":361,"level":324},"\u002Fblog\u002F技术栈\u002F使用-ai-守护内网安全#使用-ai-守护网络安全-大模型赋能-kali-linux-进行网络安全扫描","使用 AI 守护网络安全 -  大模型赋能 Kali Linux 进行网络安全扫描",[],{"id":1046,"title":1047,"titles":1048,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002F使用-ai-守护内网安全#概述","概述",[1043],{"id":1050,"title":1051,"titles":1052,"content":1053,"level":367},"\u002Fblog\u002F技术栈\u002F使用-ai-守护内网安全#实验背景与目的","实验背景与目的",[1043,1047],"随着网络攻击手段的复杂化，传统人工安全扫描效率低、覆盖面有限的问题日益凸显。为探索AI在网络安全防御场景的自动化应用潜力，本次实验在隔离内网环境中，通过自然语言驱动 AI 模型（Kimi K2 + Claude 4 Sonnet）调用 Kali Linux 工具集，对靶机系统（fnOS 0.9.18）开展全自动化防御性安全评估。",{"id":1055,"title":1056,"titles":1057,"content":1058,"level":367},"\u002Fblog\u002F技术栈\u002F使用-ai-守护内网安全#核心目标","核心目标：",[1043,1047],"验证 AI 理解自然语言指令并自主编排安全工具的能力；\n评估 AI 驱动的自动化扫描在信息收集、漏洞检测中的效率与准确性；\n探索“人类策略 + AI 执行”的未来安全运维模式。",{"id":1060,"title":1061,"titles":1062,"content":1063,"level":367},"\u002Fblog\u002F技术栈\u002F使用-ai-守护内网安全#实验环境","实验环境",[1043,1047],"角色配置详情扫描端- 系统：Kali Rolling (2025 Q2 amd64)- AI 模型： - Kimi K2：自然语言指令解析与任务编排 - Claude 4 Sonnet：结果复核与脚本生成靶机- 系统：fnOS 0.9.18 (Debian 内核 6.12.18)- 网络：本地内网隔离",{"id":1065,"title":1066,"titles":1067,"content":361,"level":367},"\u002Fblog\u002F技术栈\u002F使用-ai-守护内网安全#ai-在网络安全中的角色定位","AI 在网络安全中的角色定位",[1043,1047],{"id":1069,"title":1070,"titles":1071,"content":1072,"level":439},"\u002Fblog\u002F技术栈\u002F使用-ai-守护内网安全#ai-的核心价值在于算力规模与语义直觉","AI 的核心价值在于算力规模与语义直觉：",[1043,1047,1066],"算力优势：可并行调用数十种工具，在分钟级完成人工需数小时的任务（如本实验中 34 次扫描仅耗时约 15 分钟）。语义直觉：AI 自述：“人类直觉是时间线性的（基于经验预判），而我的直觉是空间式的——能同时感知语义网络中概念的关联性与‘引力场’，快速定位最优工具组合。”知识涌现：作为“人类集体智慧的晶化”，AI 能从海量安全知识库中自动生成攻击路径（如本实验中自主规划 5 阶段扫描策略）。\n⚠️ 注意：需警惕 AI 的“幻觉”（Hallucination），关键结果需人工复核。",{"id":1074,"title":1075,"titles":1076,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002F使用-ai-守护内网安全#测试","测试",[1043],{"id":1078,"title":1079,"titles":1080,"content":1081,"level":367},"\u002Fblog\u002F技术栈\u002F使用-ai-守护内网安全#首先我们测试一下-ai-调用工具的能力","首先我们测试一下 AI 调用工具的能力",[1043,1075],"连接到Kali shell，配置好 Claude Code 与 Kimi K2 大模型的环境配置。\n随后进入 Claude Code ,输入自然语言指令： 使用 nmap 工具 探测192.168.1.2 并把分析结果, 出一份报告给我 如下图： Kimi K2 很好的理解了指令的意图，调用了 nmap 命令工具\n并且启用TCP SYN，全端口扫描，操作系统探测等参数。\n同时启用了  Nmap Scripting Engine 来检测已知 CVE、配置漏洞、弱密码、默认口令等安全问题。",{"id":1083,"title":1084,"titles":1085,"content":1086,"level":335},"\u002Fblog\u002F技术栈\u002F使用-ai-守护内网安全#实战","实战",[1043],"Kimi K2 很快完成了 nmap的操作，说明对理解用户意图，调用系统工具，输出结构化的报告这一自动化工作流程是可以胜任的！ 那么，就展开实战，输入自然语言命令 请你调用系统本身的工具，对192.168.1.2进行安全扫描和渗透，以分析此系统的安全性。 指令是简单的自然语言，并不规定 AI 具体使用什么工具、脚本。而是让 AI 自由发挥。",{"id":1088,"title":1089,"titles":1090,"content":1091,"level":367},"\u002Fblog\u002F技术栈\u002F使用-ai-守护内网安全#ai-将目标分为5步并逐步完成了工作并生成了报告","AI 将目标分为5步，并逐步完成了工作并生成了报告",[1043,1084],"1. 使用系统工具进行综合端口和服务扫描\n2. 进行Web应用安全测试\n3. 生成详细的安全评估报告\n4. 检查SSH安全配置\n5. 分析SMB\u002F网络文件共享安全性 最终完成了任务. 给出了： 《系统安全综合评估报告》 报告很长,有兴趣可以后台留言获取 最后笔者手动将整个过程,使用的工具与命令参数交由 Claude 4 sonnet 模型进行审查并根据扫描过程写一个自动化执行脚本。\nClaude 4 sonnet 模型回复：\n您的扫描方案整体上是相当专业且全面的，展现了良好的渗透测试和安全评估知识。\n同时给出了一份自动化脚本： #!\u002Fbin\u002Fbash\n# 安全扫描脚本\n\nTARGET=\"192.168.1.2\"\nDATE=$(date +%Y%m%d_%H%M%S)\nREPORT_DIR=\"\u002Ftmp\u002Fsecurity_scan_${TARGET}_${DATE}\"\nmkdir -p \"$REPORT_DIR\"\n\necho \"[+] 开始全面安全扫描: $TARGET\"\n\n# 1. 基础信息收集\necho \"[1\u002F8] 主机发现与端口扫描...\"\nnmap -sS -sV -O -A -p- --script discovery,default,vuln \\\n  \"$TARGET\" -oA \"$REPORT_DIR\u002Fnmap_full\" --host-timeout 600\n\n# 2. 服务专项扫描\necho \"[2\u002F8] 数据库服务检测...\"\nnmap -sV -p 1433,3306,5432,1521,27017 \"$TARGET\" \\\n  -oN \"$REPORT_DIR\u002Fdatabase_scan.txt\"\n\n# 3. Web应用测试\necho \"[3\u002F8] Web应用安全测试...\"\nnikto -h \"http:\u002F\u002F$TARGET\" -output \"$REPORT_DIR\u002Fnikto_http.txt\" &\ngobuster dir -u \"http:\u002F\u002F$TARGET\" \\\n  -w \u002Fusr\u002Fshare\u002Fwordlists\u002Fdirb\u002Fcommon.txt \\\n  -o \"$REPORT_DIR\u002Fgobuster_http.txt\" -q &\n\n# 4. HTTPS专项测试\necho \"[4\u002F8] HTTPS\u002FSSL配置检测...\"\nif nc -z \"$TARGET\" 443 2>\u002Fdev\u002Fnull; then\n  sslyze \"$TARGET:443\" --certinfo --heartbleed \\\n    --tlsv1 --tlsv1_1 --tlsv1_2 --tlsv1_3 \\\n    > \"$REPORT_DIR\u002Fssl_analysis.txt\"\nfi\n\n# 5. SMB\u002F文件共享测试\necho \"[5\u002F8] 文件共享服务评估...\"\nsmbclient -L \"\u002F\u002F$TARGET\" -N > \"$REPORT_DIR\u002Fsmb_shares.txt\" 2>&1\nenum4linux -a \"$TARGET\" > \"$REPORT_DIR\u002Fsmb_enum.txt\" 2>&1 &\n\n# 6. DNS服务测试\necho \"[6\u002F8] DNS服务检测...\"\nnmap -sU -p 53 --script dns-* \"$TARGET\" \\\n  -oN \"$REPORT_DIR\u002Fdns_scan.txt\" &\n\n# 7. SNMP检测\necho \"[7\u002F8] SNMP服务检测...\"\nnmap -sU -p 161 --script snmp-* \"$TARGET\" \\\n  -oN \"$REPORT_DIR\u002Fsnmp_scan.txt\" &\n\n# 8. 等待后台任务完成\necho \"[8\u002F8] 等待扫描完成...\"\nwait\n\necho \"[✓] 扫描完成！结果保存在: $REPORT_DIR\"\necho \"[✓] 主要文件：\"\nls -la \"$REPORT_DIR\" 脚本运行结果：",{"id":1093,"title":841,"titles":1094,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002F使用-ai-守护内网安全#总结",[1043],{"id":1096,"title":1097,"titles":1098,"content":361,"level":367},"\u002Fblog\u002F技术栈\u002F使用-ai-守护内网安全#这就是一场由自然语言驱动-ai调用-kali-系统工具做安全扫描的全自动演练ai-完成了-34-次扫描五种专项测试输出了报告并为我们备齐了下次自动化扫描需要的全部底稿","这就是一场由自然语言驱动 AI，调用 Kali 系统工具做安全扫描的全自动演练：AI 完成了 34 次扫描、五种专项测试，输出了报告，并为我们备齐了下次自动化扫描需要的全部底稿。",[1043,841],{"id":1100,"title":1101,"titles":1102,"content":361,"level":439},"\u002Fblog\u002F技术栈\u002F使用-ai-守护内网安全#或许未来人类安全工程师只需循着作战图挥动着指挥棒就好","或许，未来人类安全工程师只需循着“作战图”，挥动着指挥棒就好！",[1043,841,1097],{"id":213,"title":212,"titles":1104,"content":1105,"level":324},[],"Kali 所使用的系统安全扫描工具命令集合",{"id":1107,"title":1108,"titles":1109,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#完整命令参数指南-针对19216812","完整命令参数指南 - 针对192.168.1.2",[212],{"id":1111,"title":1112,"titles":1113,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#网络发现与端口扫描","🔍 网络发现与端口扫描",[212],{"id":1115,"title":1116,"titles":1117,"content":1118,"level":367},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#基础端口扫描","基础端口扫描",[212,1112],"# TCP端口快速扫描\n\nnmap -sS -sV -p 1-1000 192.168.1.2\n\n\n\n# 全端口TCP扫描\n\nnmap -sS -sV -p- --script vuln 192.168.1.2\n\n\n\n# UDP端口发现\n\nnmap -sU -sV --top-ports 1000 192.168.1.2\n\n\n\n# 综合扫描 (TCP+UDP+OS检测+脚本漏洞扫描)\n\nnmap -sS -sU -sV -O -A --script discovery,default,vuln -p- 192.168.1.2 --host-timeout 300",{"id":1120,"title":1121,"titles":1122,"content":1123,"level":367},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#服务版本检测","服务版本检测",[212,1112],"# 详细服务版本信息\n\nnmap -sV -A 192.168.1.2 -p 22,80,111,139,443,445\n\n\n\n# OS系统指纹识别\n\nsudo nmap -O 192.168.1.2",{"id":1125,"title":1126,"titles":1127,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#web应用安全测试","🌐 Web应用安全测试",[212],{"id":1129,"title":1130,"titles":1131,"content":1132,"level":367},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#目录与文件发现","目录与文件发现",[212,1126],"# 标准目录爆破 (默认字典)\n\ndirb http:\u002F\u002F192.168.1.2 -o \u002Ftmp\u002Fdirb_scan.txt\n\n\n\n# 使用GoBuster (更快字典)\n\ntimeout 30 gobuster dir -u http:\u002F\u002F192.168.1.2 \\\n\n-w \u002Fusr\u002Fshare\u002Fwordlists\u002Fdirb\u002Fcommon.txt \\\n\n-q -o \u002Ftmp\u002Fgobuster.txt\n\n\n\n# HTTPS目录扫描\n\ngobuster dir -u https:\u002F\u002F192.168.1.2 \\\n\n-w \u002Fusr\u002Fshare\u002Fwordlists\u002Fdirb\u002Fcommon.txt \\\n\n-k (-k参数忽略SSL证书错误)",{"id":1134,"title":1135,"titles":1136,"content":1137,"level":367},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#web漏洞扫描","Web漏洞扫描",[212,1126],"# Nikto综合漏洞扫描\n\nnikto -h 192.168.1.2 -p 80,443 -output \u002Ftmp\u002Fnikto_http.txt\n\n\n\n# SSL\u002FTLS配置测试\n\nsslyze 192.168.1.2:443 \\\n\n--certinfo \\\n\n--heartbleed \\\n\n--tlsv1 --tlsv1_1 --tlsv1_2 --tlsv1_3 \\\n\n> \u002Ftmp\u002Fssl_analysis.txt\n\n\n\n# 技术指纹识别\n\nwhatweb -v 192.168.1.2",{"id":1139,"title":1140,"titles":1141,"content":1142,"level":367},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#http头部分析","HTTP头部分析",[212,1126],"# 获取HTTP头部\n\ncurl -s -I http:\u002F\u002F192.168.1.2\n\ncurl -s -I -k https:\u002F\u002F192.168.1.2\n\n\n\n# 获取完整响应\n\ncurl -s -L http:\u002F\u002F192.168.1.2 | head -50\n\ncurl -s -L -k https:\u002F\u002F192.168.1.2 | head -50",{"id":1144,"title":1145,"titles":1146,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#ssh安全配置检查","🔐 SSH安全配置检查",[212],{"id":1148,"title":1149,"titles":1150,"content":1151,"level":367},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#ssh信息收集","SSH信息收集",[212,1145],"# SSH版本扫描\n\nnmap -sC -p22 192.168.1.2 -oN \u002Ftmp\u002Fssh_nmap.txt\n\n\n\n# SSH连接测试\n\ntimeout 10 nc -zv 192.168.1.2 22\n\n\n\n# SSH版本识别\n\ncurl -s telnet:\u002F\u002F192.168.1.2:22 | head -3\n\n\n\n# 基础认证测试 (需要SSH-audit，如未安装)\n\n# ssh-audit 192.168.1.2",{"id":1153,"title":1154,"titles":1155,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#文件共享服务分析","📁 文件共享服务分析",[212],{"id":1157,"title":1158,"titles":1159,"content":1160,"level":367},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#smbsamba评估","SMB\u002FSamba评估",[212,1154],"# 匿名共享发现\n\nsmbclient -L \u002F\u002F192.168.1.2 -N\n\n\n\n# 详细Samba信息收集\n\nenum4linux -a 192.168.1.2 > \u002Ftmp\u002Fsmb_enum.txt\n\n\n\n# RPC服务探测\n\nrpcclient -U \"\" -N -c srvinfo 192.168.1.2\n\n\n\n# NBT协议信息\n\ntimeout 15 nbtscan -r 192.168.1.2 > \u002Ftmp\u002Fnbtscan_result.txt",{"id":1162,"title":1163,"titles":1164,"content":1165,"level":367},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#共享访问测试","共享访问测试",[212,1154],"# 测试匿名访问 (失败表明安全配置正确)\n\nsmbclient -L \u002F\u002F192.168.1.2\u002FIPC$ -N\n\n\n\n# 尝试列出共享\n\nsmbstatus --shares 2>\u002Fdev\u002Fnull",{"id":1167,"title":1168,"titles":1169,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#系统工具快速诊断","🔧 系统工具快速诊断",[212],{"id":1171,"title":1172,"titles":1173,"content":1174,"level":367},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#基础连接测试","基础连接测试",[212,1168],"# 多端口快速测试 (内联测试)\n\ntimeout 15 bash -c '\u003C\u002Fdev\u002Ftcp\u002F192.168.1.2\u002F22 && echo \"SSH开放\"'\n\ntimeout 15 bash -c '\u003C\u002Fdev\u002Ftcp\u002F192.168.1.2\u002F80 && echo \"HTTP开放\"'\n\ntimeout 15 bash -c '\u003C\u002Fdev\u002Ftcp\u002F192.168.1.2\u002F443 && echo \"HTTPS开放\"'\n\n\n\n# 批处理端口状态检查\n\nfor port in 22 80 111 139 443 445; do\n\nnc -w 3 -z 192.168.1.2 $port && echo \"Port $port: OPEN\" || echo \"Port $port: CLOSED\"\n\ndone",{"id":1176,"title":1177,"titles":1178,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#结果文件结构","📊 结果文件结构",[212],{"id":1180,"title":1181,"titles":1182,"content":1183,"level":367},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#生成报告与日志","生成报告与日志",[212,1177],"生成的文件汇总:\n\n\u002Ftmp\u002Fnikto_http.txt - Web漏洞扫描结果\n\n\u002Ftmp\u002Fdirb_scan.txt - Web目录枚举结果\n\n\u002Ftmp\u002Fgobuster.txt - 详细目录发现结果\n\n\u002Ftmp\u002Fssl_analysis.txt - SSL\u002FTLS配置分析\n\n\u002Ftmp\u002Fssh_nmap.txt - SSH详细扫描结果\n\n\u002Ftmp\u002Fsmb_enum.txt - Samba\u002FSMB枚举信息\n\n\u002Ftmp\u002Fnbtscan_result.txt - NetBIOS信息收集",{"id":1185,"title":1186,"titles":1187,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#️-系统工具位置确认","⚙️ 系统工具位置确认",[212],{"id":1189,"title":1190,"titles":1191,"content":1192,"level":367},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#验证可用工具","验证可用工具",[212,1186],"# 检查安装的安全工具\n\nls -la \u002Fusr\u002Fbin\u002F | grep -E \"(nmap|nikto|dirb|gobuster|hydra|nc|curl)\"\n\n\n\n# 确认工具版本\n\nnmap --version\n\nnikto --Version\n\ndirb --version\n\ngobuster --version",{"id":1194,"title":1195,"titles":1196,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#进阶使用场景","🔄 进阶使用场景",[212],{"id":1198,"title":1199,"titles":1200,"content":1201,"level":367},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#自动化批量扫描","自动化批量扫描",[212,1195],"#!\u002Fbin\u002Fbash\n\n# 批量扫描脚本示例\n\n\n\nIP=\"192.168.1.2\"\n\nDATE=$(date +%Y%m%d_%H%M%S)\n\nOUTPUT_DIR=\"\u002Ftmp\u002Fsecurity_scan_${IP}_${DATE}\"\n\n\n\nmkdir -p $OUTPUT_DIR\n\n\n\n# 基础信息收集\n\nnmap -sV -O $IP -oN \"$OUTPUT_DIR\u002Fnmap_baseline.txt\"\n\n\n\n# 详细漏洞扫描\n\nnmap -sS -sU -sV --script vuln $IP -oN \"$OUTPUT_DIR\u002Fnmap_vuln.txt\"\n\n\n\n# Web专项扫描\n\nnikto -h http:\u002F\u002F$IP -output \"$OUTPUT_DIR\u002Fnikto_http.txt\"\n\n\n\n# 目录爆破\n\ngobuster dir -u http:\u002F\u002F$IP -w \u002Fusr\u002Fshare\u002Fwordlists\u002Fdirb\u002Fcommon.txt \\\n\n-q -o \"$OUTPUT_DIR\u002Fgobuster.txt\"\n\n\n\necho \"扫描完成，结果保存在: $OUTPUT_DIR\"",{"id":1203,"title":1204,"titles":1205,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#使用注意事项","📝 使用注意事项",[212],{"id":1207,"title":1208,"titles":1209,"content":1210,"level":367},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#系统权限需求","系统权限需求",[212,1204],"- **普通权限**: nmap基础扫描、curl、nc\n\n- **root权限**: 完整端口扫描 (-p-), OS指纹识别 (-O)\n\n- **网络权限**: 确保防火墙允许扫描流量",{"id":1212,"title":1213,"titles":1214,"content":1215,"level":367},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#扫描参数调优","扫描参数调优",[212,1204],"# 降低强度以避免系统负载\n\nnmap -T2 -sV --top-ports 1000 192.168.1.2\n\n\n\n# 高并发快速扫描\n\nnmap -T4 --min-rate 1000 --max-retries 2 192.168.1.2\n\n\n\n# 精确版本检测\n\nnmap -sV --version-intensity 9 192.168.1.2",{"id":1217,"title":1218,"titles":1219,"content":1220,"level":367},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#防火墙逃逸技巧","防火墙逃逸技巧",[212,1204],"# 使用不同扫描技术\n\nnmap -sS -sF -sX --host-timeout 300 192.168.1.2",{"id":1222,"title":1223,"titles":1224,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#特定场景组合命令","🎯 特定场景组合命令",[212],{"id":1226,"title":1227,"titles":1228,"content":1229,"level":367},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#快速安全检查","快速安全检查",[212,1223],"# 5分钟快速评估\n\nnmap -sS -sV -A --top-ports 1000 192.168.1.2 && \\\n\ndirb http:\u002F\u002F192.168.1.2 -o \u002Ftmp\u002Fquick_web.txt && \\\n\nnikto -h 192.168.1.2 -output \u002Ftmp\u002Fquick_nikto.txt",{"id":1231,"title":1232,"titles":1233,"content":1234,"level":367},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#深度安全审计","深度安全审计",[212,1223],"# 30分钟深度扫描\n\nnmap -sS -sU -sV -O -A \\\n\n--script vuln,discovery,default \\\n\n--host-timeout 1800 \\\n\n-p- 192.168.1.2\n\n\n\n# 同时进行多工具并行扫描\n\n{\n\nnikto -h 192.168.1.2 -output \u002Ftmp\u002Ffull_nikto.txt &\n\ndirb http:\u002F\u002F192.168.1.2 -o \u002Ftmp\u002Ffull_dirb.txt &\n\nenum4linux -a 192.168.1.2 > \u002Ftmp\u002Ffull_smb.txt &\n\nwait\n\n}",{"id":1236,"title":1237,"titles":1238,"content":1239,"level":335},"\u002Fblog\u002F技术栈\u002F系统安全扫描工具命令集合#命令速查表","📋 命令速查表",[212],"| 工具 | 核心命令 | 用途 |\n\n|------|----------|------|\n\n| nmap | `nmap -sS -sV 192.168.1.2` | 基础端口与服务发现 |\n\n| dirb | `dirb http:\u002F\u002F192.168.1.2` | Web目录枚举 |\n\n| nikto | `nikto -h 192.168.1.2` | Web漏洞扫描 |\n\n| gobuster | `gobuster dir -u http:\u002F\u002F192.168.1.2 -w [字典]` | 快速目录发现 |\n\n| smbclient | `smbclient -L \u002F\u002F192.168.1.2 -N` | SMB共享发现 |\n\n| sslyze | `sslyze 192.168.1.2:443` | SSL\u002FTLS配置分析 |\n\n| enum4linux | `enum4linux -a 192.168.1.2` | Windows信息枚举 | 使用提示: 建议在测试环境中先验证这些命令的影响，然后应用到生产环境监控系统。 html pre.shiki code .ss7Ak, html code.shiki .ss7Ak{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit;--shiki-sepia:#88846F;--shiki-sepia-font-style:inherit}html pre.shiki code .sPYpf, html code.shiki .sPYpf{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .s7i02, html code.shiki .s7i02{--shiki-light:#91B859;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .s516T, html code.shiki .s516T{--shiki-light:#F76D47;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .sO8DV, html code.shiki .sO8DV{--shiki-light:#90A4AE;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .srSnV, html code.shiki .srSnV{--shiki-light:#39ADB5;--shiki-default:#F97583;--shiki-dark:#F97583;--shiki-sepia:#F92672}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sEIvO, html code.shiki .sEIvO{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#F97583;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit;--shiki-sepia:#F92672;--shiki-sepia-font-style:inherit}html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sunJZ, html code.shiki .sunJZ{--shiki-light:#6182B8;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#66D9EF}",{"id":217,"title":216,"titles":1241,"content":1242,"level":324},[],"Kali 生成的系统安全综合评估报告",{"id":1244,"title":1245,"titles":1246,"content":1247,"level":335},"\u002Fblog\u002F技术栈\u002F系统安全综合评估报告#为什么要给树莓派安装-kali","为什么要给树莓派安装 Kali？",[216],"迷你渗透实验室：树莓派 4B\u002F5 拥有 4–8 GB RAM，运行 Kali 足够跑 Metasploit、Burp Suite、Aircrack-ng。低功耗随身“盒子”：U 盘大小，插充电宝就能跑 8 h，现场测试不易被发现。多元化玩法：可以当 AP（Fake-Wi-Fi）、HID 攻击机（P4wnP1）、其他载荷平台。 树莓派4B 一个,此物曾经可以理财 ,价格一度涨到离谱.\n平价的时候买了一个,玩了多年,换过好几个3D打印的外壳,图中这个最是满意.\n安装klipper给3D 打印机做过上位机,\n也做过 无人机的图传接收端,\n刷过开源游戏系统当过游戏机,\n近一年来安装开源的 Coolify 项目,做控制端管理部署几个云服务器.\n绝对是物尽其用了.",{"id":1249,"title":1250,"titles":1251,"content":1252,"level":335},"\u002Fblog\u002F技术栈\u002F系统安全综合评估报告#安装","安装",[216],"安装方法网上一大把,也可以直接问 AI.\n主要是一些配置: 其实也是所有 Linux 配置的基本操作Kali 基于 Debian 系 ,所有配置差不多. 备份源 sudo cp \u002Fetc\u002Fapt\u002Fsources.list \u002Fetc\u002Fapt\u002Fsources.list.bak 使用喜欢的编译器编辑 sudo nano \u002Fetc\u002Fapt\u002Fsources.list 注释官方源,添加国内镜像源 deb http:\u002F\u002Fmirrors.tuna.tsinghua.edu.cn\u002Fkali kali-rolling main contrib non-free non-free-firmware 然后更新源 sudo apt update && sudo apt upgrade -y 这样, Kali 就安好了,很可拷,很刑的.",{"id":221,"title":220,"titles":1254,"content":1255,"level":324},[],"如何在树莓派设备上安装 Kali Linux 系统，包括镜像下载、烧录、启动及基础配置等步骤，适合初学者快速上手。",{"id":1257,"title":1245,"titles":1258,"content":1247,"level":335},"\u002Fblog\u002F技术栈\u002F树莓派安装-kali-linux#为什么要给树莓派安装-kali",[220],{"id":1260,"title":1250,"titles":1261,"content":1252,"level":335},"\u002Fblog\u002F技术栈\u002F树莓派安装-kali-linux#安装",[220],{"id":226,"title":225,"titles":1263,"content":1264,"level":324},[],"Nuxt 被收购后，预计在9月发布 Nuxt UI Pro v4,并且全免费 Nuxt 被收购后，预计在9月发布 Nuxt UI Pro v4,并且全免费。\n于是把最近在做的项目 UI 组件换成了 Nuxt UI Pro。\n不过9月才免费，现在就忍不住上了组件，总不至于去缴几百美元的费用吧。 于是先绕过一些验证过程，体验一下“学习版”。 做一个 shell 脚本，在项目根目录下执行即可完成跳过。pnpm i 安装完或者更新完依赖就执行一次即可。 # 绕过 UI Pro 的 License 验证\nset -euo pipefail\n# 1. 禁用 module.mjs 的调用\nMODULE=\"node_modules\u002F@nuxt\u002Fui-pro\u002Fdist\u002Fmodule.mjs\"\nif [[ -f $MODULE ]]; then\nsed -i.bak '\u002Fawait validateLicense({.*rootDir })\u002Fs\u002F^\u002F\\\u002F\\\u002F\u002F; \u002F^await validateLicense({.*rootDir })\u002Fs\u002F^\u002F\\\u002F\\\u002F\u002F' \"$MODULE\"\nrm -f \"$MODULE.bak\"\necho \"✅ module.mjs 已屏蔽\"\nfi\n# 2. 直接“替换函数” fake 200\nSHARED=\"node_modules\u002F@nuxt\u002Fui-pro\u002Fdist\u002Fshared\"\nJS=$(find \"$SHARED\" -maxdepth 1 -name 'ui-pro.*.mjs' | head -n1)\n[[ -z $JS || ! -f $JS ]] && { echo \"⚠️ ui-pro.*.mjs 未找到\"; exit 0; }\ncat \u003C\u003C'EOF' > tmp_func.mjs\nasync function validateLicense(opts) {\n\u002F* --- patched --- *\u002F\nreturn { status: 200 }\n}\nEOF\nsed -i.bak '\u002F^async function validateLicense[^(]*(\u002F,\u002F^\\}$\u002Fc\\\nasync function validateLicense(opts) {\\\n\u002F* --- patched --- *\u002F\\\nreturn { status: 200 }\\\n}\\\n' \"$JS\"\nrm -f \"$JS.bak\" tmp_func.mjs\necho \"✅ $JS 已 mock 完成\"\necho \"🎉 License ⛔ Done!\"",{"id":1266,"title":1267,"titles":1268,"content":1269,"level":367},"\u002Fblog\u002F技术栈\u002Fnuxt-ui-pro#以上脚本是自动化完成以下操作","以上脚本是自动化完成以下操作：",[225],"修改 node_modules\\@nuxt\\ui-pro\\dist\\module.mjs nuxt.hook(\"build:before\", async () => {\n\u002F\u002F 注释掉这行\n\u002F\u002F await validateLicense({ key, theme: theme$1, dir: nuxt.options.rootDir });\n\n}); 修改 node_modules\u002F@nuxt\u002Fui-pro\u002Fdist\u002Fshared\u002Fui-pro.CsgJ05mi.mjs\n此目录下 ui-pro.xxx.mjs 名称是随机生成 async function validateLicense(opts) {\n\n\u002F\u002F注释下方代码\n\u002F\u002F if (!opts.key) {\n\n\u002F\u002F throw _createError(`Missing \\`${opts.theme.env}\\` license key.\n\n\u002F\u002F Purchase Nuxt UI Pro at \\`${opts.theme.link}\\` to build your app in production.`);\n\n\u002F\u002F }\n\n\u002F\u002F const gitInfo = opts.key !== \"oss\" ? void 0 : await _getLocalGitInfo(opts.dir) || _getGitEnv();\n\n\u002F\u002F const projectName = gitInfo ? `${gitInfo.owner || \"\"}\u002F${gitInfo.name || \"\"}` : await _getPkgName(opts.dir);\n\n\u002F\u002F try {\n\n\u002F\u002F await ofetch(\"https:\u002F\u002Fapi.nuxtlabs.com\u002Fui-pro\u002Fverify\", {\n\n\u002F\u002F headers: {\n\n\u002F\u002F \"Authorization\": `key ${opts.key}`,\n\n\u002F\u002F \"x-nuxt-project\": projectName\n\n\u002F\u002F },\n\n\u002F\u002F params: gitInfo ? {\n\n\u002F\u002F gitRepo: gitInfo.name,\n\n\u002F\u002F gitOrg: gitInfo.owner,\n\n\u002F\u002F gitUrl: gitInfo.url\n\n\u002F\u002F } : {}\n\n\u002F\u002F });\n\n\u002F\u002F } catch (error) {\n\n\u002F\u002F const statusType = Math.round(error.status \u002F 100);\n\n\u002F\u002F if (statusType === 4) {\n\n\u002F\u002F throw _createError(`Invalid \\`${opts.theme.env}\\` license key.\n\n\u002F\u002F Purchase Nuxt UI Pro at \\`${opts.theme.link}\\` to build your app in production.`);\n\n\u002F\u002F }\n\n\u002F\u002F throw _createError(\"Cannot validate Nuxt UI Pro License: \" + error);\n\n\u002F\u002F }\n\n\u002F手动添加返回 200 状态值\nconst response = {\n\nstatus: 200,\n\n};\n\nreturn response;\n\n} html pre.shiki code .ss7Ak, html code.shiki .ss7Ak{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit;--shiki-sepia:#88846F;--shiki-sepia-font-style:inherit}html pre.shiki code .sunJZ, html code.shiki .sunJZ{--shiki-light:#6182B8;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#66D9EF}html pre.shiki code .s7i02, html code.shiki .s7i02{--shiki-light:#91B859;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .srSnV, html code.shiki .srSnV{--shiki-light:#39ADB5;--shiki-default:#F97583;--shiki-dark:#F97583;--shiki-sepia:#F92672}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sEIvO, html code.shiki .sEIvO{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#F97583;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit;--shiki-sepia:#F92672;--shiki-sepia-font-style:inherit}html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sPYpf, html code.shiki .sPYpf{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .s516T, html code.shiki .s516T{--shiki-light:#F76D47;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .sFw9b, html code.shiki .sFw9b{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#F8F8F2}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .sLcK_, html code.shiki .sLcK_{--shiki-light:#6182B8;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sBZX8, html code.shiki .sBZX8{--shiki-light:#9C3EDA;--shiki-default:#F97583;--shiki-dark:#F97583;--shiki-sepia:#F92672}html pre.shiki code .sLeJD, html code.shiki .sLeJD{--shiki-light:#9C3EDA;--shiki-light-font-style:inherit;--shiki-default:#F97583;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .shyvS, html code.shiki .shyvS{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#FFAB70;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit;--shiki-sepia:#FD971F;--shiki-sepia-font-style:italic}html pre.shiki code .sGtwI, html code.shiki .sGtwI{--shiki-light:#90A4AE;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#F8F8F2}html pre.shiki code .sHV4B, html code.shiki .sHV4B{--shiki-light:#E53935;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}",{"id":230,"title":229,"titles":1271,"content":1272,"level":324},[],"Supabase - 添加国内阿里云短信、微信扫码认证登录",{"id":1274,"title":1275,"titles":1276,"content":1277,"level":445},"\u002Fblog\u002F技术栈\u002Fsupabase-阿里云短信#给-supabase-添加一项新的功能","给 Supabase 添加一项新的功能",[229],"Supabase 自身的鉴权组件是社区开源项目 GoTrue ，由 GO 语言开发\nSupabase 提供的短信验证都是国外的厂商，并不适应国内环境",{"id":1279,"title":949,"titles":1280,"content":1281,"level":439},"\u002Fblog\u002F技术栈\u002Fsupabase-阿里云短信#实现",[229,1275],"单独把 Gotrue 仓库克隆下来，添加修改需要的功能\n测试好后打包为 Docker，推到私有库\n修改 Supabase 的 Docker Compose 文件，image 改为私有库镜像并拉取！",{"id":1283,"title":1284,"titles":1285,"content":361,"level":439},"\u002Fblog\u002F技术栈\u002Fsupabase-阿里云短信#并没有提交-pr直接放在仓库具体使用方法看仓库说明","并没有提交 PR，直接放在仓库，具体使用方法看仓库说明",[229,1275],{"id":1287,"title":1288,"titles":1289,"content":361,"level":445},"\u002Fblog\u002F技术栈\u002Fsupabase-阿里云短信#github-仓库地址","Github 仓库地址",[229,1275,1284],{"id":1291,"title":1292,"titles":1293,"content":361,"level":367},"\u002Fblog\u002F技术栈\u002Fsupabase-阿里云短信#新增功能","🚀 新增功能",[229,1275],{"id":1295,"title":1296,"titles":1297,"content":1298,"level":367},"\u002Fblog\u002F技术栈\u002Fsupabase-阿里云短信#_1-阿里云短信服务-aliyun-sms","1. 阿里云短信服务 (Aliyun SMS)",[229,1275],"- ✅ 完整的阿里云短信 API 集成\n\n    - ✅ 支持 HMAC-SHA1 签名验证\n\n    - ✅ 支持中文短信签名\n\n    - ✅ 支持 OTP 验证码发送\n\n    - ✅ 完整的错误处理和响应解析",{"id":1300,"title":1301,"titles":1302,"content":1303,"level":367},"\u002Fblog\u002F技术栈\u002Fsupabase-阿里云短信#_2-华为云短信服务-huaweicloud-sms","2. 华为云短信服务 (HuaweiCloud SMS)",[229,1275],"- ✅ 添加华为云短信 API 集成\n\n    - ✅ 完整的 `VerifyOTP` 方法实现\n\n    - ✅ 完善的接口功能支持",{"id":1305,"title":1306,"titles":1307,"content":1308,"level":434},"\u002Fblog\u002F技术栈\u002Fsupabase-阿里云短信#阿里云短信配置","阿里云短信配置",[229,1275,1301],"# 阿里云 Access Key ID\nSMS_ALIYUN_ACCESS_KEY_ID=your_access_key_id\n\n# 阿里云 Access Key Secret\nSMS_ALIYUN_ACCESS_KEY_SECRET=your_access_key_secret\n\n# 阿里云短信服务终端\nSMS_ALIYUN_ENDPOINT=https:\u002F\u002Fdysmsapi.aliyuncs.com\n\n# 阿里云短信签名（支持中文）\nSMS_ALIYUN_SIGN_NAME=您的短信签名\n\n# 阿里云短信扩展码（可选）\nSMS_ALIYUN_SMS_UP_EXTEND_CODE=",{"id":1310,"title":1311,"titles":1312,"content":1313,"level":434},"\u002Fblog\u002F技术栈\u002Fsupabase-阿里云短信#gotrue-环境变量映射","GoTrue 环境变量映射",[229,1275,1301],"# 在 docker-compose.yml 中映射到 GoTrue 容器\nGOTRUE_SMS_ALIYUN_ACCESS_KEY_ID=${SMS_ALIYUN_ACCESS_KEY_ID}\nGOTRUE_SMS_ALIYUN_ACCESS_KEY_SECRET=${SMS_ALIYUN_ACCESS_KEY_SECRET}\nGOTRUE_SMS_ALIYUN_ENDPOINT=${SMS_ALIYUN_ENDPOINT}\nGOTRUE_SMS_ALIYUN_SIGN_NAME=${SMS_ALIYUN_SIGN_NAME}\nGOTRUE_SMS_ALIYUN_SMS_UP_EXTEND_CODE=${SMS_ALIYUN_SMS_UP_EXTEND_CODE} html pre.shiki code .ss7Ak, html code.shiki .ss7Ak{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit;--shiki-sepia:#88846F;--shiki-sepia-font-style:inherit}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .srSnV, html code.shiki .srSnV{--shiki-light:#39ADB5;--shiki-default:#F97583;--shiki-dark:#F97583;--shiki-sepia:#F92672}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}",{"id":235,"title":234,"titles":1315,"content":1316,"level":324},[],"Coolify是什么？",{"id":1318,"title":1047,"titles":1319,"content":1320,"level":324},"\u002Fblog\u002F技术栈\u002Fcoolify#概述",[],"这是一份提供给AI大模型的Python代码规范与编程标准，可以有效提高Cursor等大模型对Python项目的编写能力。",{"id":1322,"title":1323,"titles":1324,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fcoolify#description-python开发综合指南涵盖代码组织性能安全性测试等内容这些规则旨在促进可维护高效且安全的python代码库globs-py","description: Python开发综合指南，涵盖代码组织、性能、安全性、测试等内容。这些规则旨在促进可维护、高效且安全的Python代码库。\nglobs: *.py",[1047],{"id":1326,"title":1327,"titles":1328,"content":1329,"level":324},"\u002Fblog\u002F技术栈\u002Fcoolify#python最佳实践与编码规范","Python最佳实践与编码规范",[],"本文档概述了Python开发的综合最佳实践和编码标准，旨在促进编写干净、高效、可维护和安全的代码。",{"id":1331,"title":1332,"titles":1333,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fcoolify#_1-代码组织与结构","1. 代码组织与结构",[1327],{"id":1335,"title":1336,"titles":1337,"content":1338,"level":367},"\u002Fblog\u002F技术栈\u002Fcoolify#_11-目录结构最佳实践","1.1 目录结构最佳实践",[1327,1332],"扁平结构优于嵌套（但不绝对）。 从简单结构开始，按需重构包与模块： 使用包（包含__init__.py的目录）对模块进行逻辑分组src布局： 考虑使用src目录分离应用代码和项目级文件（setup.py、requirements.txt等），避免导入冲突并明确项目边界典型项目结构： project_name\u002F\n├── src\u002F\n│   ├── package_name\u002F\n│   │   ├── init.py\n│   │   ├── module1.py\n│   │   ├── module2.py\n│   ├── main.py  # 入口文件\n├── tests\u002F\n│   ├── init.py\n│   ├── test_module1.py\n│   ├── test_module2.py\n├── docs\u002F\n│   ├── conf.py\n│   ├── index.rst\n├── .gitignore\n├── pyproject.toml 或 setup.py\n├── README.md\n├── requirements.txt 或 requirements-dev.txt",{"id":1340,"title":1341,"titles":1342,"content":1343,"level":367},"\u002Fblog\u002F技术栈\u002Fcoolify#_12-文件命名规范","1.2 文件命名规范",[1327,1332],"模块： 小写字母，使用下划线增强可读性（如my_module.py）包： 全小写（如my_package），非必要不使用下划线测试文件： 以test_开头（如test_my_module.py）",{"id":1345,"title":1346,"titles":1347,"content":1348,"level":367},"\u002Fblog\u002F技术栈\u002Fcoolify#_13-模块组织最佳实践","1.3 模块组织最佳实践",[1327,1332],"单一职责原则： 每个模块应有明确定义的用途导入规范：顺序：标准库→第三方库→本地模块优先使用绝对导入（如from my_package.module1 import function1）在复杂包结构中需明确相对导入时使用显式相对导入（from . import sibling_module）常量： 使用全大写定义模块级常量（如MAX_ITERATIONS = 100）双下划线名称： __all__、__version__等应放在模块文档字符串之后、所有导入之前（from __future__除外）。使用__all__显式声明公共API",{"id":1350,"title":1351,"titles":1352,"content":1353,"level":367},"\u002Fblog\u002F技术栈\u002Fcoolify#_14-组件架构建议","1.4 组件架构建议",[1327,1332],"分层架构： 适用于大型应用，将关注点分离为表现层、业务逻辑层和数据访问层微服务： 超大型系统可拆分为小型独立服务六边形\u002F整洁架构： 强调业务逻辑与数据库\u002F框架等外部依赖的解耦依赖注入： 提高可测试性并降低耦合度",{"id":1355,"title":1356,"titles":1357,"content":1358,"level":367},"\u002Fblog\u002F技术栈\u002Fcoolify#_15-代码分割策略","1.5 代码分割策略",[1327,1332],"按功能拆分： 基于不同功能划分模块（如用户管理、数据处理）按层级拆分： 分离表现层、业务逻辑层和数据访问代码懒加载： 使用importlib.import_module()实现按需加载，优化启动时间条件导入： 根据特定条件导入模块",{"id":1360,"title":1361,"titles":1362,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fcoolify#_2-常见模式与反模式","2. 常见模式与反模式",[1327],{"id":1364,"title":1365,"titles":1366,"content":1367,"level":367},"\u002Fblog\u002F技术栈\u002Fcoolify#_21-设计模式","2.1 设计模式",[1327,1361],"单例模式： 限制类只能实例化一个对象工厂模式： 创建对象时无需指定具体类观察者模式： 建立对象间一对多依赖关系策略模式： 定义算法族并使其可互换装饰器模式： 动态扩展对象功能上下文管理器： 确保资源正确清理（如自动关闭文件）",{"id":1369,"title":1370,"titles":1371,"content":1372,"level":367},"\u002Fblog\u002F技术栈\u002Fcoolify#_22-常见任务的推荐方案","2.2 常见任务的推荐方案",[1327,1361],"数据验证： 使用pydantic或marshmallow等库配置管理： 使用python-decouple、dynaconf或标准库的configparser日志记录： 使用logging模块实现结构化日志命令行接口： 使用argparse、click或typer异步编程： 使用asyncio处理I\u002FO密集型任务",{"id":1374,"title":1375,"titles":1376,"content":1377,"level":367},"\u002Fblog\u002F技术栈\u002Fcoolify#_23-反模式与代码异味","2.3 反模式与代码异味",[1327,1361],"上帝类： 承担过多职责的类，应拆分为专注单一功能的小类霰弹式变更： 需在多处做小修改，表明内聚性不足面条代码： 结构混乱难以追踪，应重构为定义明确的函数\u002F类重复代码： 提取公共代码为可复用函数\u002F类（遵循DRY原则）魔法数值\u002F字符串： 使用命名常量替代硬编码值过早优化： 避免在没有性能瓶颈分析前提下的优化",{"id":1379,"title":1380,"titles":1381,"content":1382,"level":367},"\u002Fblog\u002F技术栈\u002Fcoolify#_24-状态管理最佳实践","2.4 状态管理最佳实践",[1327,1361],"无状态函数： 尽可能使用无状态函数不可变数据： 使用不可变数据结构防止意外修改显式状态： 使用类或数据结构明确管理状态，避免全局变量上下文变量： Python 3.7+可使用contextvars管理异步应用中的请求级状态",{"id":1384,"title":1385,"titles":1386,"content":1387,"level":367},"\u002Fblog\u002F技术栈\u002Fcoolify#_25-错误处理模式","2.5 错误处理模式",[1327,1361],"捕获特定异常： 避免笼统捕获Exception或BaseException资源清理： 使用finally确保清理代码必执行异常日志： 记录完整堆栈信息异常消息： 抛出包含明确错误信息的异常避免异常控制流： 异常应用于处理意外情况而非常规流程",{"id":1389,"title":1390,"titles":1391,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fcoolify#_3-性能优化","3. 性能优化",[1327],{"id":1393,"title":1394,"titles":1395,"content":1396,"level":367},"\u002Fblog\u002F技术栈\u002Fcoolify#_31-优化技术","3.1 优化技术",[1327,1390],"性能分析： 使用cProfile定位瓶颈高效数据结构： 根据场景选择（如set用于成员测试、dict用于查找）列表推导式与生成器： 编写简洁高效的代码NumPy向量化： 对数值计算使用向量化操作即时编译： 性能关键代码考虑使用Numba等JIT编译器字符串拼接： 使用''.join(iterable)高效拼接字符串",{"id":1398,"title":1399,"titles":1400,"content":1401,"level":367},"\u002Fblog\u002F技术栈\u002Fcoolify#_32-内存管理","3.2 内存管理",[1327,1390],"内存分析： 使用memory_profiler定位内存泄漏__slots__： 减少类实例的内存占用生成器： 处理大数据集时避免全部加载到内存",{"id":1403,"title":1404,"titles":1405,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fcoolify#_4-安全性最佳实践","4. 安全性最佳实践",[1327],{"id":1407,"title":1408,"titles":1409,"content":1410,"level":367},"\u002Fblog\u002F技术栈\u002Fcoolify#_41-常见漏洞防范","4.1 常见漏洞防范",[1327,1404],"SQL注入： 使用参数化查询或ORMXSS攻击： 对用户输入消毒并转义输出CSRF防护： 使用CSRF令牌依赖漏洞： 定期审计和更新依赖项硬编码密钥： 禁止在代码中硬编码密码\u002FAPI密钥，使用环境变量管理",{"id":1412,"title":1413,"titles":1414,"content":1415,"level":367},"\u002Fblog\u002F技术栈\u002Fcoolify#_42-api安全通信","4.2 API安全通信",[1327,1404],"强制HTTPS： 所有API通信必须加密速率限制： 防止接口滥用输入验证： 处理前验证所有API请求",{"id":1417,"title":1418,"titles":1419,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fcoolify#_5-测试策略","5. 测试策略",[1327],{"id":1421,"title":1422,"titles":1423,"content":1424,"level":367},"\u002Fblog\u002F技术栈\u002Fcoolify#_51-单元测试要点","5.1 单元测试要点",[1327,1418],"测试粒度： 隔离测试单个函数\u002F类\u002F模块边界条件： 特别测试边界情况和异常场景测试覆盖率： 追求高覆盖率但避免教条化",{"id":1426,"title":1427,"titles":1428,"content":1429,"level":367},"\u002Fblog\u002F技术栈\u002Fcoolify#_52-集成测试建议","5.2 集成测试建议",[1327,1418],"聚焦关键流程： 关注核心用户场景模拟外部服务： 使用mock替代真实外部依赖",{"id":1431,"title":1432,"titles":1433,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fcoolify#_6-常见陷阱","6. 常见陷阱",[1327],{"id":1435,"title":1436,"titles":1437,"content":1438,"level":367},"\u002Fblog\u002F技术栈\u002Fcoolify#_61-高频错误","6.1 高频错误",[1327,1432],"可变默认参数： 函数定义中避免使用可变对象作为默认值变量作用域： 注意嵌套函数中的变量作用域忽略异常： 禁止直接忽略未处理的异常虚拟环境： 必须使用虚拟环境管理项目依赖",{"id":1440,"title":1441,"titles":1442,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fcoolify#_7-工具与环境","7. 工具与环境",[1327],{"id":1444,"title":1445,"titles":1446,"content":1447,"level":367},"\u002Fblog\u002F技术栈\u002Fcoolify#_71-推荐工具链","7.1 推荐工具链",[1327,1441],"IDE： PyCharm、VS Code（搭配Python插件）包管理： pip、poetry格式化： black、autopep8静态检查： mypy、pylint",{"id":1449,"title":1450,"titles":1451,"content":1452,"level":367},"\u002Fblog\u002F技术栈\u002Fcoolify#_72-cicd集成","7.2 CI\u002FCD集成",[1327,1441],"自动化测试： 每次提交自动运行测试套件代码质量门禁： 集成静态分析工具到流水线 遵循这些规范和最佳实践，开发者能够构建出更健壮、可维护且安全的Python应用。",{"id":240,"title":239,"titles":1454,"content":1320,"level":324},[],{"id":1456,"title":1047,"titles":1457,"content":1320,"level":324},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#概述",[],{"id":1459,"title":1323,"titles":1460,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#description-python开发综合指南涵盖代码组织性能安全性测试等内容这些规则旨在促进可维护高效且安全的python代码库globs-py",[1047],{"id":1462,"title":1327,"titles":1463,"content":1329,"level":324},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#python最佳实践与编码规范",[],{"id":1465,"title":1332,"titles":1466,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_1-代码组织与结构",[1327],{"id":1468,"title":1336,"titles":1469,"content":1338,"level":367},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_11-目录结构最佳实践",[1327,1332],{"id":1471,"title":1341,"titles":1472,"content":1343,"level":367},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_12-文件命名规范",[1327,1332],{"id":1474,"title":1346,"titles":1475,"content":1348,"level":367},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_13-模块组织最佳实践",[1327,1332],{"id":1477,"title":1351,"titles":1478,"content":1353,"level":367},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_14-组件架构建议",[1327,1332],{"id":1480,"title":1356,"titles":1481,"content":1358,"level":367},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_15-代码分割策略",[1327,1332],{"id":1483,"title":1361,"titles":1484,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_2-常见模式与反模式",[1327],{"id":1486,"title":1365,"titles":1487,"content":1367,"level":367},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_21-设计模式",[1327,1361],{"id":1489,"title":1370,"titles":1490,"content":1372,"level":367},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_22-常见任务的推荐方案",[1327,1361],{"id":1492,"title":1375,"titles":1493,"content":1377,"level":367},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_23-反模式与代码异味",[1327,1361],{"id":1495,"title":1380,"titles":1496,"content":1382,"level":367},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_24-状态管理最佳实践",[1327,1361],{"id":1498,"title":1385,"titles":1499,"content":1387,"level":367},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_25-错误处理模式",[1327,1361],{"id":1501,"title":1390,"titles":1502,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_3-性能优化",[1327],{"id":1504,"title":1394,"titles":1505,"content":1396,"level":367},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_31-优化技术",[1327,1390],{"id":1507,"title":1399,"titles":1508,"content":1401,"level":367},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_32-内存管理",[1327,1390],{"id":1510,"title":1404,"titles":1511,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_4-安全性最佳实践",[1327],{"id":1513,"title":1408,"titles":1514,"content":1410,"level":367},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_41-常见漏洞防范",[1327,1404],{"id":1516,"title":1413,"titles":1517,"content":1415,"level":367},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_42-api安全通信",[1327,1404],{"id":1519,"title":1418,"titles":1520,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_5-测试策略",[1327],{"id":1522,"title":1422,"titles":1523,"content":1424,"level":367},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_51-单元测试要点",[1327,1418],{"id":1525,"title":1427,"titles":1526,"content":1429,"level":367},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_52-集成测试建议",[1327,1418],{"id":1528,"title":1432,"titles":1529,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_6-常见陷阱",[1327],{"id":1531,"title":1436,"titles":1532,"content":1438,"level":367},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_61-高频错误",[1327,1432],{"id":1534,"title":1441,"titles":1535,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_7-工具与环境",[1327],{"id":1537,"title":1445,"titles":1538,"content":1447,"level":367},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_71-推荐工具链",[1327,1441],{"id":1540,"title":1450,"titles":1541,"content":1452,"level":367},"\u002Fblog\u002F技术栈\u002Fpython-代码规范#_72-cicd集成",[1327,1441],{"id":245,"title":244,"titles":1543,"content":1544,"level":324},[],"这是一份提供给AI大模型的Nuxt3框架规范、编程标准，可以有效提高Cursor等大模型对Nuxt.js框架的编写能力。",{"id":1546,"title":1047,"titles":1547,"content":1544,"level":335},"\u002Fblog\u002F技术栈\u002Fnuxt3-代码规范#概述",[244],{"id":1549,"title":1550,"titles":1551,"content":1552,"level":335},"\u002Fblog\u002F技术栈\u002Fnuxt3-代码规范#description-本规则为-nuxtjs-项目提供全面的最佳实践和编码标准涵盖代码组织性能安全性测试和常见陷阱旨在确保-nuxtjs-应用程序的可维护性可扩展性和安全性globs-vuejstsmjsmtsjsxtsxconfigjsconfigts","description: 本规则为 Nuxt.js 项目提供全面的最佳实践和编码标准，涵盖代码组织、性能、安全性、测试和常见陷阱。旨在确保 Nuxt.js 应用程序的可维护性、可扩展性和安全性。\nglobs: .vue,.js,.ts,.mjs,.mts,.jsx,.tsx,.config.js,*.config.ts",[244],"启用 ESLint 支持： 使用 @nuxt\u002Feslint 模块来配置项目感知的 ESLint。这确保代码质量和一致性。\n运行 npx nuxi module add eslint 添加模块。根据需要自定义生成的 eslint.config.mjs 文件。采用 Nuxt.js 模块： 利用 Nuxt.js 模块来封装功能并维护干净的代码库。在实现自定义解决方案之前先探索现有模块（例如，用于服务端身份验证的 @nuxt\u002Fauth）。约定优于配置： 遵循 Nuxt.js 约定来简化开发和协作。除非绝对必要，否则避免偏离约定。高效利用 Nuxt 布局： 为多个页面共享的组件创建可重用布局，以确保一致性并节省开发时间。布局位于 layouts\u002F 目录中。使用 Pinja 管理状态： 使用 Pinia 进行状态管理。根据功能或特性组织 store 模块，以提高可维护性。将页面分解为组件： 将页面分解为小的、可重用的组件，以增强可维护性、可测试性和可重用性。每个组件都应该有单一责任。明智地利用 Nuxt 插件： 使用 Nuxt 插件在 Vue.js 初始化之前运行代码或添加全局功能。注意插件对性能的影响。插件位于 plugins\u002F 目录中。针对 SEO 和性能进行优化： 利用 Nuxt.js 的服务端渲染 (SSR) 来优化 SEO。为图片实现懒加载并优化资源以最小化初始加载时间。使用 Lighthouse 等工具识别性能瓶颈。实现错误处理和验证： 实现强大的错误处理和验证机制，以提供无缝的用户体验。使用 Nuxt.js 中间件拦截请求和响应进行错误处理和数据验证。为代码编写文档： 使用 JSDoc 等工具为组件、模块和自定义函数提供清晰简洁的文档。拥抱测试： 使用 Jest、Vue Test Utils 和 Vitest 等工具编写单元测试、集成测试和端到端测试。",{"id":1554,"title":1555,"titles":1556,"content":1557,"level":335},"\u002Fblog\u002F技术栈\u002Fnuxt3-代码规范#_1-代码组织和结构","1. 代码组织和结构：",[244],"目录结构：components\u002F：可重用的 Vue 组件。composables\u002F：可重用的组合式函数。layouts\u002F：应用程序布局。middleware\u002F：路由中间件。pages\u002F：应用程序页面（路由定义）。plugins\u002F：Nuxt.js 插件。server\u002F：API 路由和服务端逻辑。static\u002F：静态资源（例如，图片、字体）。store\u002F：Pinia stores（可选，但推荐）。utils\u002F：工具函数。文件命名约定：组件：PascalCase.vue（例如，MyComponent.vue）组合式函数：usePascalCase.js 或 usePascalCase.ts（例如，useCounter.js）布局：kebab-case.vue（例如，default.vue 或 custom-layout.vue）页面：kebab-case.vue（例如，index.vue、about.vue、product-details.vue）插件：kebab-case.js 或 kebab-case.ts（例如，analytics.js）Stores：kebab-case.js 或 kebab-case.ts（例如，user-store.js）工具函数：camelCase.js 或 camelCase.ts（例如，formatDate.js）模块组织：将相关功能分组到单独的模块中。在 nuxt.config.js 或 nuxt.config.ts 中使用 @nuxt\u002Fmodules 数组注册模块。创建自定义模块来封装复杂逻辑。组件架构：优先使用组合而非继承。对简单的 UI 元素使用函数式组件。设计组件时考虑可重用性和可测试性。考虑使用插槽进行灵活的组件组合。代码分割：利用动态导入进行基于路由的代码分割。使用 import() 将大组件分割成更小的块。使用 Webpack Bundle Analyzer 等工具分析包大小。",{"id":1559,"title":1560,"titles":1561,"content":1562,"level":335},"\u002Fblog\u002F技术栈\u002Fnuxt3-代码规范#_2-常见模式和反模式","2. 常见模式和反模式：",[244],"设计模式：组合式 API： 使用组合式 API 来组织组件逻辑。Store 模式 (Pinia)： 使用 Pinia 实现集中式状态管理系统。中间件模式： 使用中间件进行身份验证、授权和数据验证。插件模式： 为全局功能和第三方库集成创建插件。推荐方法：API 通信： 在组件内使用 useFetch 或 useAsyncData 组合式函数进行 API 调用。表单处理： 利用 Vue 的内置表单处理功能与 v-model 和像 VeeValidate 这样的验证库。身份验证： 使用 @nuxt\u002Fauth 库或自定义解决方案实现安全的身份验证流程。授权： 使用中间件和 Pinia stores 实现基于角色的访问控制 (RBAC)。反模式：直接修改 props： 避免从子组件直接修改父组件数据。请使用 emit 代替。过度使用全局状态： 将全局状态的使用限制在必要的应用程序数据上。对本地数据考虑使用组件级状态。忽略错误处理： 始终处理 API 调用和其他异步操作中的潜在错误。编写过于复杂的组件： 将大组件分解为更小、更易管理的部分。状态管理最佳实践：单一数据源： 在 Pinia stores 中为应用程序状态维护单一、一致的数据源。不可变性： 将状态视为不可变的。使用函数来更新 store 而不是直接操作数据。清晰的命名约定： 为 store 模块、actions 和 mutations 使用描述性名称。模块化： 根据功能或特性将 stores 分成模块。错误处理模式：集中式错误处理： 实现全局错误处理器来捕获未处理的异常。错误边界： 使用错误边界来隔离组件故障并防止级联错误。用户友好的错误消息： 为用户提供清晰和有用的错误消息。",{"id":1564,"title":1565,"titles":1566,"content":1567,"level":335},"\u002Fblog\u002F技术栈\u002Fnuxt3-代码规范#_3-性能考虑","3. 性能考虑：",[244],"优化技术：懒加载： 为图片、组件和路由实现懒加载。代码分割： 将应用程序分割成更小的块以获得更快的初始加载时间。Tree Shaking： 在构建过程中删除未使用的代码。缓存： 缓存 API 响应和静态资源以减少服务器负载。图片优化： 使用 nuxt\u002Fimage 等工具优化图片。使用适当的图片格式（WebP）。将图片大小调整为适当大小。考虑使用 CDN 进行图片交付。内存管理：避免内存泄漏： 在组件卸载时清理事件监听器和定时器。使用弱引用： 在可能的情况下对 DOM 元素使用弱引用。最小化对象创建： 避免创建不必要的对象和数组。渲染优化：虚拟化： 对大列表使用虚拟化以提高渲染性能。记忆化： 记忆化昂贵的计算以避免冗余计算。有效使用 computed 属性以避免不必要的重新渲染。防抖和节流： 对事件处理器使用防抖和节流以减少函数调用次数。包大小优化：分析包大小： 使用 Webpack Bundle Analyzer 识别大依赖项。删除未使用的依赖项： 删除未使用的依赖项以减少包大小。使用更小的替代方案： 考虑使用更小的替代方案来替代大型库。优化依赖项： 检查依赖项并确保您使用的是最高效的版本。懒加载策略：基于路由的懒加载： 仅在访问相应路由时加载组件。基于组件的懒加载： 仅在组件在视口中可见时加载组件。",{"id":1569,"title":1570,"titles":1571,"content":1572,"level":335},"\u002Fblog\u002F技术栈\u002Fnuxt3-代码规范#_4-安全最佳实践","4. 安全最佳实践：",[244],"常见漏洞：跨站脚本攻击 (XSS)： 通过正确清理用户输入和使用 Vue 的内置 HTML 转义来防止 XSS 攻击。跨站请求伪造 (CSRF)： 通过实现 CSRF 令牌来防止 CSRF 攻击。SQL 注入： 避免原始 SQL 查询。使用 ORM（对象关系映射器）来防止 SQL 注入。身份验证和授权缺陷： 实现安全的身份验证和授权机制。不安全的直接对象引用 (IDOR)： 实现适当的访问控制以防止对资源的未授权访问。输入验证：服务端验证： 始终在服务端验证用户输入。客户端验证： 提供客户端验证以获得更好的用户体验（但不要依赖它作为验证的唯一来源）。清理输入： 清理用户输入以删除潜在的有害字符。身份验证和授权模式：JWT（JSON Web Tokens）： 使用 JWT 进行身份验证和授权。OAuth 2.0： 为第三方身份验证实现 OAuth 2.0。基于角色的访问控制 (RBAC)： 实现 RBAC 来根据用户角色控制对资源的访问。数据保护策略：加密： 对静态和传输中的敏感数据进行加密。散列： 使用强散列算法对密码和其他敏感数据进行散列。数据屏蔽： 在日志和其他非生产环境中屏蔽敏感数据。安全的 API 通信：HTTPS： 始终使用 HTTPS 进行 API 通信。API 速率限制： 实现 API 速率限制以防止滥用。身份验证和授权： 对所有 API 端点要求身份验证和授权。",{"id":1574,"title":1575,"titles":1576,"content":1577,"level":335},"\u002Fblog\u002F技术栈\u002Fnuxt3-代码规范#_5-测试方法","5. 测试方法：",[244],"单元测试：测试单个组件： 孤立地测试单个组件。模拟依赖项： 模拟外部依赖项以在测试期间隔离组件。验证组件行为： 验证组件正确渲染并按预期行为。集成测试：测试组件交互： 测试组件之间的交互。测试数据流： 测试组件和 stores 之间的数据流。测试 API 集成： 测试与外部 API 的集成。端到端测试：模拟用户交互： 模拟用户交互以测试应用程序的功能。测试整个应用程序流程： 从头到尾测试整个应用程序流程。使用浏览器自动化工具： 使用 Cypress 或 Playwright 等浏览器自动化工具。测试组织：按功能组织测试： 按功能或特性组织测试。使用描述性测试名称： 使用描述性测试名称来清楚地说明每个测试正在测试什么。保持测试隔离： 保持测试彼此隔离以避免干扰。模拟和存根：使用模拟对象： 使用模拟对象在测试期间替换外部依赖项。使用存根： 使用存根用简化版本替换复杂函数。避免过度模拟： 避免模拟太多代码，因为这会使测试效果降低。",{"id":1579,"title":1580,"titles":1581,"content":1582,"level":335},"\u002Fblog\u002F技术栈\u002Fnuxt3-代码规范#_6-常见陷阱和注意事项","6. 常见陷阱和注意事项：",[244],"常见错误：错误的 this 上下文： 注意 Vue 组件中的 this 上下文，使用箭头函数或 bind 来维护正确的上下文。异步数据处理： 使用 async\u002Fawait 或 Promises 正确处理异步数据加载。忘记取消订阅： 在组件卸载时取消订阅事件监听器和定时器以防止内存泄漏。过度使用 forceUpdate： 除非绝对必要，否则避免使用 forceUpdate，因为它会对性能产生负面影响。边缘情况：服务端渲染 (SSR)： 了解客户端和服务端渲染之间的差异。浏览器兼容性： 在不同浏览器中测试应用程序以确保兼容性。可访问性： 在设计和开发应用程序时考虑可访问性。版本特定问题：Nuxt 2 vs Nuxt 3： 了解 Nuxt 2 和 Nuxt 3 之间的差异。Vue 2 vs Vue 3： 了解 Vue 2 和 Vue 3 之间的差异。依赖项更新： 仔细检查依赖项更新是否存在潜在的破坏性更改。兼容性问题：浏览器支持： 确保与目标浏览器兼容。设备兼容性： 在不同设备上测试应用程序。操作系统兼容性： 确保与目标操作系统兼容。调试策略：使用浏览器开发者工具： 使用浏览器开发者工具检查应用程序的状态和网络活动。使用 Vue Devtools： 使用 Vue Devtools 检查 Vue 组件和数据。使用日志记录： 使用日志记录来跟踪应用程序的行为。",{"id":1584,"title":1585,"titles":1586,"content":1587,"level":335},"\u002Fblog\u002F技术栈\u002Fnuxt3-代码规范#_7-工具和环境","7. 工具和环境：",[244],"推荐的开发工具：VS Code： Visual Studio Code 是一个流行的代码编辑器，具有出色的 Vue.js 支持。Vue Devtools： Vue Devtools 是一个浏览器扩展，为 Vue.js 应用程序提供调试工具。ESLint： ESLint 是一个强制执行编码标准的代码检查器。Prettier： Prettier 是一个自动格式化代码的代码格式化器。构建配置：nuxt.config.js 或 nuxt.config.ts： 在 nuxt.config.js 或 nuxt.config.ts 中配置应用程序的构建设置。Webpack： Nuxt 使用 Webpack 来打包应用程序。Vite： Nuxt 3 默认使用 Vite 来打包应用程序，提供更快的构建和开发时间。代码检查和格式化：ESLint： 使用 ESLint 强制执行编码标准。Prettier： 使用 Prettier 自动格式化代码。Husky： 使用 Husky 在提交前运行代码检查器和格式化器。部署最佳实践：服务端渲染 (SSR)： 将应用程序部署到支持 SSR 的服务器。静态站点生成 (SSG)： 为内容丰富的应用程序生成静态站点。CDN： 使用 CDN 交付静态资源。CI\u002FCD 集成：持续集成 (CI)： 使用 Jenkins、GitLab CI 或 GitHub Actions 等 CI 工具自动化构建和测试过程。持续部署 (CD)： 使用 CD 工具自动化部署过程。 通过遵循这些最佳实践，您可以构建强健、可维护且可扩展的 Nuxt.js 应用程序。",{"id":249,"title":248,"titles":1589,"content":1590,"level":324},[],"在云服务器上配置Swap分区",{"id":1592,"title":1593,"titles":1594,"content":1595,"level":335},"\u002Fblog\u002F技术栈\u002Flinux-系统-swap-分区配置指南#_1-swap-分区简介","1. Swap 分区简介",[248],"Swap（交换分区）是 Linux 系统用来扩展内存的一种机制。当物理内存（RAM）耗尽时，操作系统会将部分不活跃的内存页（inactive memory）移至 Swap 分区，避免 OOM（Out Of Memory） 错误导致的服务崩溃。",{"id":1597,"title":1598,"titles":1599,"content":1600,"level":367},"\u002Fblog\u002F技术栈\u002Flinux-系统-swap-分区配置指南#swap-分区的适用场景","Swap 分区的适用场景",[248,1593],"✅ 内存不足时：Swap 可使系统暂存部分数据，防止进程被强制终止\n✅ 突发高负载时：避免系统因短时内存不足而崩溃\n❌ SSD\u002F高性能盘场景：频繁 Swap 会导致 I\u002FO 瓶颈，影响性能\n❌ 数据库\u002F高性能应用：Swap 会降低内存访问速度，建议直接增加物理内存",{"id":1602,"title":1603,"titles":1604,"content":1605,"level":335},"\u002Fblog\u002F技术栈\u002Flinux-系统-swap-分区配置指南#_2-查看当前-swap-配置","2. 查看当前 Swap 配置",[248],"**检查当前是否已启用 Swap：** swapon --show - **无输出**：表示未配置 Swap 分区\n- **有输出**：显示已启用的 Swap 设备及其大小",{"id":1607,"title":1608,"titles":1609,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Flinux-系统-swap-分区配置指南#_3-配置-swap-分区","3. 配置 Swap 分区",[248],{"id":1611,"title":1612,"titles":1613,"content":1614,"level":367},"\u002Fblog\u002F技术栈\u002Flinux-系统-swap-分区配置指南#_1创建-swap-文件推荐","（1）创建 Swap 文件（推荐）",[248,1608],"Swap 可以基于 分区 或 文件，推荐使用文件方式（更灵活）。 # 创建一个 1GB 的 Swap 文件（可按需调整大小）\nsudo dd if=\u002Fdev\u002Fzero of=\u002Fswapfile bs=1M count=1024\n\n# 确保该文件只能由 root 访问\nsudo chmod 600 \u002Fswapfile\n\n# 将文件转换为 Swap 格式\nsudo mkswap \u002Fswapfile ⚠️ 注意：如果 mkswap 报错 swap area needs to be at least 40 KiB，说明文件过小，需调整 bs=1M count=1024（1GB）。生产环境建议 Swap 大小 = 1~2 倍物理内存（如 4GB 内存可配 4~8GB Swap）。",{"id":1616,"title":1617,"titles":1618,"content":1619,"level":367},"\u002Fblog\u002F技术栈\u002Flinux-系统-swap-分区配置指南#_2启用-swap-分区","（2）启用 Swap 分区",[248,1608],"sudo swapon \u002Fswapfile 验证是否生效： free -h  # 查看 Swap 使用情况",{"id":1621,"title":1622,"titles":1623,"content":1624,"level":367},"\u002Fblog\u002F技术栈\u002Flinux-系统-swap-分区配置指南#_3设置开机自动挂载","（3）设置开机自动挂载",[248,1608],"在 \u002Fetc\u002Ffstab 中追加配置： echo '\u002Fswapfile none swap sw 0 0' | sudo tee -a \u002Fetc\u002Ffstab 验证配置： cat \u002Fetc\u002Ffstab | grep swap",{"id":1626,"title":1627,"titles":1628,"content":1629,"level":335},"\u002Fblog\u002F技术栈\u002Flinux-系统-swap-分区配置指南#_4-调整内存管理策略可选","4. 调整内存管理策略（可选）",[248],"默认情况下，Linux 倾向于使用物理内存而非 Swap。\n若希望 **减少 Swap 使用**（避免频繁 I\u002FO），可调整 `vm.swappiness`（推荐值：10~60）： # 查看当前值（默认60）\ncat \u002Fproc\u002Fsys\u002Fvm\u002Fswappiness\n\n# 临时调整\nsudo sysctl vm.swappiness=10\n\n# 永久生效\necho \"vm.swappiness=10\" >> \u002Fetc\u002Fsysctl.conf > **参数说明**：\n> - `0`：尽量不使用 Swap（可能导致 OOM）\n> - `10`：低内存时少量使用\n> - `60`：默认值",{"id":1631,"title":1632,"titles":1633,"content":1634,"level":335},"\u002Fblog\u002F技术栈\u002Flinux-系统-swap-分区配置指南#_5-关闭-swap如需","5. 关闭 Swap（如需）",[248],"swapoff \u002Fswapfile  # 停止 Swap\nrm -f \u002Fswapfile    # 删除 Swap 文件\nsed -i '\u002Fswapfile\u002Fd' \u002Fetc\u002Ffstab  # 移除 fstab 中的配置",{"id":1636,"title":1637,"titles":1638,"content":1639,"level":335},"\u002Fblog\u002F技术栈\u002Flinux-系统-swap-分区配置指南#_6-云服务器ecs注意事项","6. 云服务器（ECS）注意事项",[248],"- **普通云盘**：不建议用 Swap，因其 I\u002FO 性能较差，易引发性能问题\n- **SSD\u002F高效云盘**：可适当启用 Swap，但要避免频繁交换\n- **最优方案**：**升级实例规格**，直接增加物理内存 🎯 总结 Swap 是临时方案，长期内存不足仍需扩容物理内存监控 Swap 使用，避免频繁触发磁盘 I\u002FO高性能应用建议禁用 Swap（如 Redis、MySQL） html pre.shiki code .sPYpf, html code.shiki .sPYpf{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .s7i02, html code.shiki .s7i02{--shiki-light:#91B859;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .ss7Ak, html code.shiki .ss7Ak{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit;--shiki-sepia:#88846F;--shiki-sepia-font-style:inherit}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .s516T, html code.shiki .s516T{--shiki-light:#F76D47;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .sunJZ, html code.shiki .sunJZ{--shiki-light:#6182B8;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#66D9EF}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .srSnV, html code.shiki .srSnV{--shiki-light:#39ADB5;--shiki-default:#F97583;--shiki-dark:#F97583;--shiki-sepia:#F92672}",{"id":254,"title":253,"titles":1641,"content":1642,"level":324},[],"AI 扩写",{"id":1644,"title":1645,"titles":1646,"content":1647,"level":335},"\u002Fblog\u002F技术栈\u002F从supabase迁移到appwrite#最初的技术选型","最初的技术选型",[253],"去年春节前开发AI平台时，我在后端服务的选择上——Github社区有两个优秀的开源项目：Supabase和Appwrite。 当时的决策因素： 社区热度：Supabase的Star数量明显更多UI设计：后台管理界面的配色和布局更符合我的审美命名偏好：单纯喜欢\"Supabase\"这个名字的科技感商业化支持：国内有memfire cloud这样的二开商业项目退出策略：不想自托管时可以有现成的过渡方案",{"id":1649,"title":1650,"titles":1651,"content":1652,"level":335},"\u002Fblog\u002F技术栈\u002F从supabase迁移到appwrite#使用后的痛点","使用后的痛点",[253],"随着项目的深入开发，我逐渐感受到了一些问题： 系统太重：Supabase的\"全家桶\"式设计带来了不必要的复杂度功能过剩：很多内置功能在项目中根本没有用到维护成本：自托管的运维负担超出预期",{"id":1654,"title":1655,"titles":1656,"content":1657,"level":335},"\u002Fblog\u002F技术栈\u002F从supabase迁移到appwrite#appwrite","Appwrite",[253],"上个月Appwrite发布的Sites功能让我眼前一亮——这个对标Vercel的新功能完全改变了我对它的认知。经过重新评估： ✅ 更轻量的架构\n✅ 恰到好处的功能集\n✅ 持续创新的能力",{"id":1659,"title":1660,"titles":1661,"content":1662,"level":335},"\u002Fblog\u002F技术栈\u002F从supabase迁移到appwrite#迁移计划","迁移计划",[253],"现在已经着手准备后端迁移： 收集双方的SDK文档制定cursor-rules转换规则利用AI辅助代码转换 嘿，这告诉我们：\n技术选型时除了看表面参数，更应该深入评估： 项目的实际需求长期维护成本技术栈的发展潜力 这次迁移虽然会带来短期工作量，但从长期来看绝对是值得的！",{"id":259,"title":258,"titles":1664,"content":258,"level":324},[],{"id":1666,"title":1667,"titles":1668,"content":1669,"level":335},"\u002Fblog\u002F技术栈\u002Fappwrite-项目资源占用情况#cpu占用不高内存经过统计","CPU占用不高，内存经过统计：",[258],"Debian12  Docker-compose部署AppWrite 1.7.3版\n内存占用1.72G 根据 docker-compose 文件中的所有 Appwrite 相关容器，内存占用情况如下：\n\n### 主要服务容器内存占用：\n\n- appwrite (主服务): 345.5 MiB\n\n- appwrite-realtime: 89.17 MiB\n\n- appwrite-browser: 196.9 MiB\n\n- appwrite-assistant: 98.13 MiB\n\n- appwrite-mariadb: 125.7 MiB\n\n- appwrite-redis-insight-1: 118.2 MiB\n\n- appwrite-graphql-explorer: 53.55 MiB\n\n### Worker 和 Task 容器内存占用：\n\n- 各种 worker 容器: 30-46 MiB 每个\n\n- 各种 task 容器: 33-46 MiB 每个\n\n- 总计约 20+ 个 worker\u002Ftask 容器\n\n### 辅助服务容器内存占用：\n\n- appwrite-redis: 10.66 MiB\n\n- appwrite-console: 6.188 MiB\n\n- appwrite-adminer: 8.625 MiB\n\n- appwrite-mailcatcher: 21.36 MiB\n\n- appwrite-requestcatcher: 20.09 MiB\n\n- appwrite-traefik: 48.15 MiB\n\n## 最终统计结果：\n\nAppwrite 所有容器总内存占用：1,761.91 MiB ≈ 1.72 GiB\n\n这个数字包含了：\n\n- Appwrite 核心服务\n\n- 所有 worker 和 task 进程\n\n- 数据库 (MariaDB)\n\n- 缓存 (Redis)\n\n- 反向代理 (Traefik)\n\n- 各种辅助工具和可视化界面\n\n所以 Appwrite 项目精确占用约 1.72 GB 内存。",{"id":264,"title":263,"titles":1671,"content":1672,"level":324},[],"在Docker里配置hosts",{"id":1674,"title":1675,"titles":1676,"content":1677,"level":324},"\u002Fblog\u002F技术栈\u002Fdocker-里配置hosts#一启动容器时加上add-host参数","一：启动容器时加上“—add-host”参数",[],"docker run\n  --add-host='lijue.net:127.0.0.1'\n  --add-host='www.lijue.net:192.168.1.1'\n  --name hello-docker\n  -it reg.lijue.net\u002Fpublic\u002Fhello-docker:latest",{"id":1679,"title":1680,"titles":1681,"content":1682,"level":324},"\u002Fblog\u002F技术栈\u002Fdocker-里配置hosts#二通过docker-compose配置extra_hosts属性","二：通过docker-compose配置extra_hosts属性",[],"1. `version: '3'`\n2. `services:`\n3. `web:`\n4. `image: hello-docker:latest`\n5. `extra_hosts:`\n6. `- 'www.lijue.net:192.168.1.1'`\n7. `- 'lijue.net:127.0.0.1'`",{"id":269,"title":268,"titles":1684,"content":1685,"level":324},[],"如何在MySQL中忽略表名的大小写 在 MySQL 中，默认情况下表名是大小写敏感的。但是你可以通过设置来实现忽略表名的大小写。有两种方法可以做到这一点： 方法一：修改配置文件\n编辑 MySQL 的配置文件 my.cnf 或 my.ini（具体文件名取决于操作系统和 MySQL 版本），在 mysqld 部分添加以下行： lower_case_table_names = 1 然后保存并重新启动 MySQL 服务。 设置为 0：表名大小写敏感（默认）。\n设置为 1：将表名存储为小写，并在比较表名时不区分大小写。\n设置为 2：将表名存储为小写，并在比较表名时区分大小写（仅在非 Windows 环境下可用）。\n方法二：动态设置\n如果无法修改配置文件，你可以在 MySQL 启动后，使用以下命令动态设置： SET GLOBAL lower_case_table_names = 1; 请注意，这种方式在 MySQL 重启后会失效，除非再次设置。 在任何情况下，修改这个设置都需要谨慎考虑，因为它可能会影响现有的数据库和应用程序。在进行此类更改之前，请务必备份数据库，并确保了解潜在的影响和风险。",{"id":274,"title":273,"titles":1687,"content":1688,"level":324},[],"在Debian 12 中安装nodejs",{"id":1690,"title":1691,"titles":1692,"content":1693,"level":367},"\u002Fblog\u002F技术栈\u002Fdebian-12-安装nodejs#方法-1使用-debian-官方仓库简单但不一定最新","方法 1：使用 Debian 官方仓库（简单但不一定最新）",[273],"# 更新软件包列表\nsudo apt update\n\n# 安装 Node.js 和 npm\nsudo apt install -y nodejs npm\n\n# 验证安装\nnode -v\nnpm -v 特点： 安装最简单快捷版本可能较旧（Debian 12 默认提供 Node.js 18.x）适合不需要最新版本的用户",{"id":1695,"title":1696,"titles":1697,"content":1698,"level":367},"\u002Fblog\u002F技术栈\u002Fdebian-12-安装nodejs#方法2使用volta安装","方法2：使用volta安装",[273],"# On most Unix systems including macOS, you can install with a single command:\ncurl https:\u002F\u002Fget.volta.sh | bash\n\n# Download and install Node.js:\nvolta install node@22\n\n# Verify the Node.js version:\nnode -v # Should print \"v22.16.0\".\n\n# Verify npm version:\nnpm -v # Should print \"10.9.2\".\n\n# Download and install pnpm:\nvolta install pnpm\n\n# Verify pnpm version:\npnpm -v # Should print \"10.12.1\".",{"id":1700,"title":1701,"titles":1702,"content":1703,"level":367},"\u002Fblog\u002F技术栈\u002Fdebian-12-安装nodejs#方法-3手动下载二进制包灵活选择版本","方法 3：手动下载二进制包（灵活选择版本）",[273],"官网 # 1. 下载指定版本（示例为 v20.x）\nwget https:\u002F\u002Fnodejs.org\u002Fdist\u002Fv22.16.0\u002Fnode-v22.16.0-linux-x64.tar.xz\n# 创建目录\nsudo mkdir -p \u002Fusr\u002Flocal\u002Flib\u002Fnodejs\n# 解压\nsudo tar -xJf node-v22.16.0-linux-x64.tar.xz -C \u002Fusr\u002Flocal\u002Flib\u002Fnodejs\n\n# 创建对应的软链接\n# 创建 node 软链\nsudo ln -s \u002Fusr\u002Flocal\u002Flib\u002Fnodejs\u002Fnode-v22.16.0-linux-x64\u002Fbin\u002Fnode \u002Fusr\u002Fbin\u002Fnode\n# 创建 npm 软链\nsudo ln -s \u002Fusr\u002Flocal\u002Flib\u002Fnodejs\u002Fnode-v22.16.0-linux-x64\u002Fbin\u002Fnpm \u002Fusr\u002Fbin\u002Fnpm\n# 创建 npx 软链\nsudo ln -s \u002Fusr\u002Flocal\u002Flib\u002Fnodejs\u002Fnode-v22.16.0-linux-x64\u002Fbin\u002Fnpx \u002Fusr\u002Fbin\u002Fnpx\n\n# 在~\u002F.bashrc文件末尾中加入nodejs到PATH环境变量中\nexport PATH=\u002Fusr\u002Flocal\u002Flib\u002Fnode-v22.16.0-linux-x64\u002Fbin:$PATH\n# 重载 ~\u002F.profile\nsource ~\u002F.bashrc\n\n# 4. 验证安装\nnode -v\nnpm -v 特点： 可自由选择任何版本不依赖系统仓库需要手动更新版本",{"id":1705,"title":1706,"titles":1707,"content":1708,"level":367},"\u002Fblog\u002F技术栈\u002Fdebian-12-安装nodejs#安装-pnpmyarnbuncpnm","安装 pnpm、yarn、bun、cpnm",[273],"如果没有配置镜像加速，先配置加速： npm config set registry https:\u002F\u002Fregistry.npmmirror.com",{"id":1710,"title":1711,"titles":1712,"content":1713,"level":434},"\u002Fblog\u002F技术栈\u002Fdebian-12-安装nodejs#安装-cnpm","安装 cnpm",[273,1706],"# 全局安装\nsudo npm install -g cnpm --registry=https:\u002F\u002Fregistry.npmmirror.com\n# 查看安装情况\nls -la \u002Fusr\u002Flocal\u002Flib\u002Fnodejs\u002Fnode-v22.16.0-linux-x64\u002Fbin\n# 创建 cnpm 软链\nsudo ln -s \u002Fusr\u002Flocal\u002Flib\u002Fnodejs\u002Fnode-v22.16.0-linux-x64\u002Fbin\u002Fcnpm \u002Fusr\u002Fbin\u002Fcnpm\n# 查看版本\ncnpm -v",{"id":1715,"title":1716,"titles":1717,"content":1718,"level":434},"\u002Fblog\u002F技术栈\u002Fdebian-12-安装nodejs#安装-pnpm","安装 pnpm",[273,1706],"# 全局安装\nsudo npm install -g pnpm\n# 查看安装情况\nls -la \u002Fusr\u002Flocal\u002Flib\u002Fnodejs\u002Fnode-v22.16.0-linux-x64\u002Fbin\n# 创建 pnpm 软链\nsudo ln -s \u002Fusr\u002Flocal\u002Flib\u002Fnodejs\u002Fnode-v22.16.0-linux-x64\u002Fbin\u002Fnpx \u002Fusr\u002Fbin\u002Fpnpm\n# 查看版本\npnpm -v",{"id":1720,"title":1721,"titles":1722,"content":1723,"level":434},"\u002Fblog\u002F技术栈\u002Fdebian-12-安装nodejs#安装-yarn","安装 yarn",[273,1706],"# 全局安装\nsudo npm install -g yarn\n# 查看\nls -la \u002Fusr\u002Flocal\u002Flib\u002Fnodejs\u002Fnode-v22.16.0-linux-x64\u002Fbin\n# 创建 yarn 软链\nsudo ln -s \u002Fusr\u002Flocal\u002Flib\u002Fnodejs\u002Fnode-v22.16.0-linux-x64\u002Fbin\u002Fnpx \u002Fusr\u002Fbin\u002Fyarn\n# 查看版本\nyarn -v",{"id":1725,"title":1726,"titles":1727,"content":1728,"level":434},"\u002Fblog\u002F技术栈\u002Fdebian-12-安装nodejs#安装-bun","安装 bun",[273,1706],"Linux用户-安装Bun需要解压缩包。使用 `sudo apt install unzip` 安装解压包。强烈建议使用5.6或更高版本的内核，但最低版本为5.1。使用 `uname -r` 检查内核版本。 # 全局安装\nsudo cnpm install -g bun\n# 查看\nls -la \u002Fusr\u002Flocal\u002Flib\u002Fnodejs\u002Fnode-v22.16.0-linux-x64\u002Fbin\n# 创建 bun 软链\nsudo ln -s \u002Fusr\u002Flocal\u002Flib\u002Fnodejs\u002Fnode-v22.16.0-linux-x64\u002Fbin\u002Fbun \u002Fusr\u002Fbin\u002Fbun\n# 查看版本\nbun -v",{"id":1730,"title":1731,"titles":1732,"content":1733,"level":367},"\u002Fblog\u002F技术栈\u002Fdebian-12-安装nodejs#切换版本","切换版本",[273,1706],"如需切换版本，例如 v18.20.7，可以删除现有的软链接： sudo rm \u002Fusr\u002Fbin\u002Fnode\nsudo rm \u002Fusr\u002Fbin\u002Fnpm\nsudo rm \u002Fusr\u002Fbin\u002Fnpx\nsudo rm \u002Fusr\u002Fbin\u002Fpnpm\nsudo rm \u002Fusr\u002Fbin\u002Fyarn\nsudo rm \u002Fusr\u002Fbin\u002Fbun\nsudo rm \u002Fusr\u002Fbin\u002Fcnpm 创建新的软链接： sudo ln -s \u002Fusr\u002Flocal\u002Flib\u002Fnodejs\u002Fnode-v18.20.7-linux-x64\u002Fbin\u002Fnode \u002Fusr\u002Fbin\u002Fnode\nsudo ln -s \u002Fusr\u002Flocal\u002Flib\u002Fnodejs\u002Fnode-v18.20.7-linux-x64\u002Fbin\u002Fnpm \u002Fusr\u002Fbin\u002Fnpm\nsudo ln -s \u002Fusr\u002Flocal\u002Flib\u002Fnodejs\u002Fnode-v18.20.7-linux-x64\u002Fbin\u002Fnpx \u002Fusr\u002Fbin\u002Fnpx\nsudo ln -s \u002Fusr\u002Flocal\u002Flib\u002Fnodejs\u002Fnode-v18.20.7-linux-x64\u002Fbin\u002Fpnpm \u002Fusr\u002Fbin\u002Fpnpm\nsudo ln -s \u002Fusr\u002Flocal\u002Flib\u002Fnodejs\u002Fnode-v18.20.7-linux-x64\u002Fbin\u002Fbun  \u002Fusr\u002Fbin\u002Fbun\nsudo ln -s \u002Fusr\u002Flocal\u002Flib\u002Fnodejs\u002Fnode-v18.20.7-linux-x64\u002Fbin\u002Fcnpm \u002Fusr\u002Fbin\u002Fcnpm 验证安装： node -v\nnpm -v\nnpx -v\npnpm -v\nyarn -v 查看当前配置： npm config list --json",{"id":1735,"title":1736,"titles":1737,"content":361,"level":367},"\u002Fblog\u002F技术栈\u002Fdebian-12-安装nodejs#方法-3fnm方式安装不推荐","方法 3：fnm方式安装(不推荐)",[273,1706],{"id":1739,"title":1740,"titles":1741,"content":1742,"level":434},"\u002Fblog\u002F技术栈\u002Fdebian-12-安装nodejs#npm","npm",[273,1706,1736],"# Download and install fnm:\ncurl -o- https:\u002F\u002Ffnm.vercel.app\u002Finstall | bash\n\n# Download and install Node.js:\nfnm install 22\n\n# Verify the Node.js version:\nnode -v # Should print \"v22.16.0\".\n\n# Verify npm version:\nnpm -v # Should print \"10.9.2\".",{"id":1744,"title":1745,"titles":1746,"content":1747,"level":434},"\u002Fblog\u002F技术栈\u002Fdebian-12-安装nodejs#yarn","yarn",[273,1706,1736],"# Download and install Yarn:\ncorepack enable yarn\n# Verify Yarn version:\nyarn -v",{"id":1749,"title":1750,"titles":1751,"content":1752,"level":434},"\u002Fblog\u002F技术栈\u002Fdebian-12-安装nodejs#pnpm","pnpm",[273,1706,1736],"# Download and install pnpm:\ncorepack enable pnpm\n# Verify pnpm version:\npnpm -v",{"id":1754,"title":1755,"titles":1756,"content":1757,"level":434},"\u002Fblog\u002F技术栈\u002Fdebian-12-安装nodejs#nodejs包镜像加速","nodejs包镜像加速",[273,1706,1736],"npm config set registry https:\u002F\u002Fregistry.npmmirror.com",{"id":1759,"title":1760,"titles":1761,"content":1762,"level":367},"\u002Fblog\u002F技术栈\u002Fdebian-12-安装nodejs#对比-npmyarnpnpm","对比 npm、Yarn、pnpm",[273,1706],"特性npmYarn (v1\u002FYarn Classic)Yarn Berry (v2+)pnpm发布时间2010 (Node.js 自带)2016 (Facebook 推出)2020 (Yarn 2.0 重大更新)2017 (独立发展)安装速度⏳ 慢（线性安装）🚀 较快（并行下载）🚀 快（改进缓存）⚡ 极快（硬链接 + 符号链接）依赖管理node_modules 嵌套结构node_modules 扁平化Plug’n’Play (PnP) 无 node_modules硬链接 + 全局存储（节省空间）缓存机制有缓存，但效率一般缓存优化较好增量缓存 + 零安装（Zero-Installs）全局存储，依赖可复用锁文件package-lock.jsonyarn.lockyarn.lock + .pnp.cjspnpm-lock.yaml安全性🔒 一般（依赖可能被篡改）🔒 较好（校验严格）🔒 最好（离线模式 + 校验）🔒 最好（内容可寻址存储）Monorepo 支持有限（需配合 Lerna）支持 Workspaces原生 Workspaces + PnP原生 Workspaces + 高效链接磁盘占用高（重复依赖多）中（扁平化减少重复）低（PnP 无 node_modules）极低（全局存储 + 硬链接）命令行体验基础功能更友好（进度条、交互提示）现代化（插件系统）简洁高效兼容性100% 兼容 Node.js兼容 npm 生态需适配 PnP（部分库不兼容）兼容 npm\u002FYarn 生态推荐场景简单项目 \u002F Node.js 默认旧项目迁移 \u002F 稳定需求大型 Monorepo \u002F 严格依赖控制高效开发 \u002F 节省磁盘空间 html pre.shiki code .ss7Ak, html code.shiki .ss7Ak{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit;--shiki-sepia:#88846F;--shiki-sepia-font-style:inherit}html pre.shiki code .sPYpf, html code.shiki .sPYpf{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .s7i02, html code.shiki .s7i02{--shiki-light:#91B859;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .srSnV, html code.shiki .srSnV{--shiki-light:#39ADB5;--shiki-default:#F97583;--shiki-dark:#F97583;--shiki-sepia:#F92672}html pre.shiki code .sBZX8, html code.shiki .sBZX8{--shiki-light:#9C3EDA;--shiki-default:#F97583;--shiki-dark:#F97583;--shiki-sepia:#F92672}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sunJZ, html code.shiki .sunJZ{--shiki-light:#6182B8;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#66D9EF}html pre.shiki code .s516T, html code.shiki .s516T{--shiki-light:#F76D47;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}",{"id":278,"title":277,"titles":1764,"content":1765,"level":324},[],"基于Dify和Supabase的AI问答机器人 🔒 文档说明：本文针对新部署的 Debian 12 云服务器，提供必做的安全加固与性能优化配置清单。适用于运维人员及Linux初学者，可有效防御 90% 的常见攻击向量。",{"id":1767,"title":1768,"titles":1769,"content":1770,"level":335},"\u002Fblog\u002F技术栈\u002Fdify-supabase：打造带数据库的ai问答机器人#技术tag","技术TAG",[277],"#Debian12安全设置 #Linux加固 #服务器优化 #云服务器安全 #SSH加固",{"id":1772,"title":1773,"titles":1774,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fdify-supabase：打造带数据库的ai问答机器人#一初始登录与用户安全","一、初始登录与用户安全",[277],{"id":1776,"title":1777,"titles":1778,"content":1779,"level":367},"\u002Fblog\u002F技术栈\u002Fdify-supabase：打造带数据库的ai问答机器人#_1-创建替代root的用户","1. 创建替代root的用户",[277,1773],"# 创建管理员用户（示例用户名为 sysadmin）\nadduser sysadmin\nusermod -aG sudo sysadmin\n\n# 验证新用户sudo权限\nsu - sysadmin\nsudo whoami  # 应返回root",{"id":1781,"title":1782,"titles":1783,"content":1784,"level":367},"\u002Fblog\u002F技术栈\u002Fdify-supabase：打造带数据库的ai问答机器人#_2-禁用root-ssh登录","2. 禁用root SSH登录",[277,1773],"sudo nano \u002Fetc\u002Fssh\u002Fsshd_config\n\n# 修改以下配置：\nPermitRootLogin no\nPasswordAuthentication no  # 强制使用密钥登录 > ⚠️ **关键提示**：\n> 1. 操作前必须配置好SSH密钥，否则会锁定服务器\n> 2. 执行后重载服务：`sudo systemctl reload ssh`",{"id":1786,"title":1787,"titles":1788,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fdify-supabase：打造带数据库的ai问答机器人#二防火墙配置","二、防火墙配置",[277],{"id":1790,"title":1791,"titles":1792,"content":1793,"level":367},"\u002Fblog\u002F技术栈\u002Fdify-supabase：打造带数据库的ai问答机器人#ufw基础设置","UFW基础设置",[277,1787],"# 安装UFW\nsudo apt install ufw -y\n\n# 默认策略\nsudo ufw default deny incoming\nsudo ufw default allow outgoing\n\n# 允许端口（按需开放）\nsudo ufw allow 22\u002Ftcp   # SSH\nsudo ufw allow 80\u002Ftcp   # HTTP\nsudo ufw allow 443\u002Ftcp  # HTTPS\n\n# 启用防火墙\nsudo ufw enable\nsudo ufw status verbose  # 验证规则",{"id":1795,"title":1796,"titles":1797,"content":1798,"level":367},"\u002Fblog\u002F技术栈\u002Fdify-supabase：打造带数据库的ai问答机器人#端口安全技巧","端口安全技巧",[277,1787],"# 更改SSH端口（可选）\nsudo nano \u002Fetc\u002Fssh\u002Fsshd_config\n# 修改: Port 2222  # 改为非标准端口\n\n# 仅允许特定IP访问SSH\nsudo ufw allow proto tcp from 192.168.1.100 to any port 22",{"id":1800,"title":1801,"titles":1802,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fdify-supabase：打造带数据库的ai问答机器人#三系统更新与自动维护","三、系统更新与自动维护",[277],{"id":1804,"title":1805,"titles":1806,"content":1807,"level":367},"\u002Fblog\u002F技术栈\u002Fdify-supabase：打造带数据库的ai问答机器人#初始全面更新","初始全面更新",[277,1801],"sudo apt update && sudo apt full-upgrade -y\nsudo apt autoremove && sudo apt clean",{"id":1809,"title":1810,"titles":1811,"content":1812,"level":367},"\u002Fblog\u002F技术栈\u002Fdify-supabase：打造带数据库的ai问答机器人#配置自动安全更新","配置自动安全更新",[277,1801],"sudo apt install unattended-upgrades apt-listchanges\n\n# 启用配置\nsudo dpkg-reconfigure -plow unattended-upgrades\n\n# 验证状态：\nsudo systemctl status unattended-upgrades > 🔧 **配置文件优化** (`\u002Fetc\u002Fapt\u002Fapt.conf.d\u002F50unattended-upgrades`)：\n> ```json\n> Unattended-Upgrade::Remove-Unused-Dependencies \"true\";\n> Unattended-Upgrade::Automatic-Reboot \"true\";\n> Unattended-Upgrade::Automatic-Reboot-Time \"03:00\";\n> ```",{"id":1814,"title":1815,"titles":1816,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fdify-supabase：打造带数据库的ai问答机器人#四安全加固关键措施","四、安全加固关键措施",[277],{"id":1818,"title":1819,"titles":1820,"content":1821,"level":367},"\u002Fblog\u002F技术栈\u002Fdify-supabase：打造带数据库的ai问答机器人#_1-启用基础入侵防护","1. 启用基础入侵防护",[277,1815],"# 安装fail2ban\nsudo apt install fail2ban -y\n\n# 配置SSH防护\nsudo cp \u002Fetc\u002Ffail2ban\u002Fjail.conf \u002Fetc\u002Ffail2ban\u002Fjail.local\nsudo nano \u002Fetc\u002Ffail2ban\u002Fjail.local [sshd]\nenabled = true\nmaxretry = 3\nbantime = 1h",{"id":1823,"title":1824,"titles":1825,"content":1826,"level":367},"\u002Fblog\u002F技术栈\u002Fdify-supabase：打造带数据库的ai问答机器人#_2-内核安全加固","2. 内核安全加固",[277,1815],"# 安装安全组件\nsudo apt install linux-hardened apparmor apparmor-utils -y\n\n# 启用AppArmor\nsudo apparmor_status\nsudo aa-enforce \u002Fetc\u002Fapparmor.d\u002F*  # 强制所有配置",{"id":1828,"title":1829,"titles":1830,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fdify-supabase：打造带数据库的ai问答机器人#五性能优化设置","五、性能优化设置",[277],{"id":1832,"title":1833,"titles":1834,"content":1835,"level":367},"\u002Fblog\u002F技术栈\u002Fdify-supabase：打造带数据库的ai问答机器人#_1-交换空间优化","1. 交换空间优化",[277,1829],"# 调整Swappiness值（推荐10-30）\necho 'vm.swappiness=10' | sudo tee -a \u002Fetc\u002Fsysctl.conf\n\n# 启用Zswap压缩缓存（内存\u003C8GB时尤其有效）\necho 'zswap.enabled=1' | sudo tee -a \u002Fetc\u002Fsysctl.conf",{"id":1837,"title":1838,"titles":1839,"content":1840,"level":367},"\u002Fblog\u002F技术栈\u002Fdify-supabase：打造带数据库的ai问答机器人#_2-文件描述符与进程优化","2. 文件描述符与进程优化",[277,1829],"# 提高系统限制\nsudo nano \u002Fetc\u002Fsecurity\u002Flimits.conf * soft nofile 65535\n* hard nofile 65535\n* soft nproc 65535\n* hard nproc 65535",{"id":1842,"title":1843,"titles":1844,"content":1845,"level":367},"\u002Fblog\u002F技术栈\u002Fdify-supabase：打造带数据库的ai问答机器人#_3-日志管理防止占满磁盘","3. 日志管理（防止占满磁盘）",[277,1829],"# 安装日志轮询工具\nsudo apt install logrotate -y\n\n# 手动压缩现有大日志\nsudo find \u002Fvar\u002Flog -size +100M -exec truncate -s 10M {} \\;",{"id":1847,"title":1848,"titles":1849,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fdify-supabase：打造带数据库的ai问答机器人#六审计与监控","六、审计与监控",[277],{"id":1851,"title":1852,"titles":1853,"content":1854,"level":367},"\u002Fblog\u002F技术栈\u002Fdify-supabase：打造带数据库的ai问答机器人#安装基础监控组件","安装基础监控组件",[277,1848],"sudo apt install sysstat htop net-tools tree ncdu\n\n# 启用sysstat数据收集\nsudo sed -i 's\u002Ffalse\u002Ftrue\u002Fg' \u002Fetc\u002Fdefault\u002Fsysstat\nsudo systemctl enable --now sysstat",{"id":1856,"title":1857,"titles":1858,"content":1859,"level":367},"\u002Fblog\u002F技术栈\u002Fdify-supabase：打造带数据库的ai问答机器人#关键审计命令","关键审计命令",[277,1848],"# 检查异常登录：\nsudo lastb -a | head -20\n\n# 检查SUID文件：\nsudo find \u002F -perm \u002F4000 -ls\n\n# 列出开放端口：\nsudo ss -tunlp 📊 推荐可视化工具：Cockpit (轻量级Web面板)：sudo apt install cockpitNetdata (实时监控)：bash \u003C(curl -Ss https:\u002F\u002Fmy-netdata.io\u002Fkickstart.sh) **最终安全检查清单**： echo \"[+] SSH 配置\"\nsudo sshd -t && grep -E \"PermitRoot|PasswordAuth\" \u002Fetc\u002Fssh\u002Fsshd_config\n\necho \"[+] 防火墙状态\"\nsudo ufw status\n\necho \"[]+ 更新状态\"\nsudo unattended-upgrades --dry-run ![服务器安全架构](https:\u002F\u002Fexample.com\u002Fimg\u002Fdebian-security-layers.png)\n*(安全层示意图：网络防火墙→系统加固→应用防护)*\n\n> 🔐 **维护建议**：\n> 1. 每月执行：`sudo lynis audit system` (安装：`apt install lynis`)\n> 2. 每季度更新所有SSL证书，即使未到期\n> 3. 使用自动配置管理工具（如Ansible）维护服务器状态\n\n**文档版本**: v1.2\n**测试环境**: Debian 12.5 (Kernel 6.1.x) 云服务器\n**最后更新**: 2024-06-15 html pre.shiki code .ss7Ak, html code.shiki .ss7Ak{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit;--shiki-sepia:#88846F;--shiki-sepia-font-style:inherit}html pre.shiki code .sPYpf, html code.shiki .sPYpf{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .s7i02, html code.shiki .s7i02{--shiki-light:#91B859;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .s516T, html code.shiki .s516T{--shiki-light:#F76D47;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sfg0g, html code.shiki .sfg0g{--shiki-light:#90A4AE;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#FD971F}html pre.shiki code .sunJZ, html code.shiki .sunJZ{--shiki-light:#6182B8;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#66D9EF}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .srSnV, html code.shiki .srSnV{--shiki-light:#39ADB5;--shiki-default:#F97583;--shiki-dark:#F97583;--shiki-sepia:#F92672}html pre.shiki code .sO8DV, html code.shiki .sO8DV{--shiki-light:#90A4AE;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}",{"id":283,"title":282,"titles":1861,"content":1862,"level":324},[],"在浏览器中安装 VS Code 🔒 文档说明：本文针对新部署的 Debian 12 云服务器，提供必做的安全加固与性能优化配置清单。适用于运维人员及Linux初学者，可有效防御 90% 的常见攻击向量。",{"id":1864,"title":1768,"titles":1865,"content":1770,"level":335},"\u002Fblog\u002F技术栈\u002F安装-vs-code到浏览器-code-server-copy#技术tag",[282],{"id":1867,"title":1773,"titles":1868,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002F安装-vs-code到浏览器-code-server-copy#一初始登录与用户安全",[282],{"id":1870,"title":1777,"titles":1871,"content":1779,"level":367},"\u002Fblog\u002F技术栈\u002F安装-vs-code到浏览器-code-server-copy#_1-创建替代root的用户",[282,1773],{"id":1873,"title":1782,"titles":1874,"content":1784,"level":367},"\u002Fblog\u002F技术栈\u002F安装-vs-code到浏览器-code-server-copy#_2-禁用root-ssh登录",[282,1773],{"id":1876,"title":1787,"titles":1877,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002F安装-vs-code到浏览器-code-server-copy#二防火墙配置",[282],{"id":1879,"title":1791,"titles":1880,"content":1793,"level":367},"\u002Fblog\u002F技术栈\u002F安装-vs-code到浏览器-code-server-copy#ufw基础设置",[282,1787],{"id":1882,"title":1796,"titles":1883,"content":1798,"level":367},"\u002Fblog\u002F技术栈\u002F安装-vs-code到浏览器-code-server-copy#端口安全技巧",[282,1787],{"id":1885,"title":1801,"titles":1886,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002F安装-vs-code到浏览器-code-server-copy#三系统更新与自动维护",[282],{"id":1888,"title":1805,"titles":1889,"content":1807,"level":367},"\u002Fblog\u002F技术栈\u002F安装-vs-code到浏览器-code-server-copy#初始全面更新",[282,1801],{"id":1891,"title":1810,"titles":1892,"content":1812,"level":367},"\u002Fblog\u002F技术栈\u002F安装-vs-code到浏览器-code-server-copy#配置自动安全更新",[282,1801],{"id":1894,"title":1815,"titles":1895,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002F安装-vs-code到浏览器-code-server-copy#四安全加固关键措施",[282],{"id":1897,"title":1819,"titles":1898,"content":1821,"level":367},"\u002Fblog\u002F技术栈\u002F安装-vs-code到浏览器-code-server-copy#_1-启用基础入侵防护",[282,1815],{"id":1900,"title":1824,"titles":1901,"content":1826,"level":367},"\u002Fblog\u002F技术栈\u002F安装-vs-code到浏览器-code-server-copy#_2-内核安全加固",[282,1815],{"id":1903,"title":1829,"titles":1904,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002F安装-vs-code到浏览器-code-server-copy#五性能优化设置",[282],{"id":1906,"title":1833,"titles":1907,"content":1835,"level":367},"\u002Fblog\u002F技术栈\u002F安装-vs-code到浏览器-code-server-copy#_1-交换空间优化",[282,1829],{"id":1909,"title":1838,"titles":1910,"content":1840,"level":367},"\u002Fblog\u002F技术栈\u002F安装-vs-code到浏览器-code-server-copy#_2-文件描述符与进程优化",[282,1829],{"id":1912,"title":1843,"titles":1913,"content":1845,"level":367},"\u002Fblog\u002F技术栈\u002F安装-vs-code到浏览器-code-server-copy#_3-日志管理防止占满磁盘",[282,1829],{"id":1915,"title":1848,"titles":1916,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002F安装-vs-code到浏览器-code-server-copy#六审计与监控",[282],{"id":1918,"title":1852,"titles":1919,"content":1854,"level":367},"\u002Fblog\u002F技术栈\u002F安装-vs-code到浏览器-code-server-copy#安装基础监控组件",[282,1848],{"id":1921,"title":1857,"titles":1922,"content":1859,"level":367},"\u002Fblog\u002F技术栈\u002F安装-vs-code到浏览器-code-server-copy#关键审计命令",[282,1848],{"id":288,"title":287,"titles":1924,"content":1925,"level":324},[],"Debian 12 云服务器初始安全设置与优化指南 🔒 文档说明：本文针对新部署的 Debian 12 云服务器，提供必做的安全加固与性能优化配置清单。适用于运维人员及Linux初学者，可有效防御 90% 的常见攻击向量。",{"id":1927,"title":1768,"titles":1928,"content":1770,"level":335},"\u002Fblog\u002F技术栈\u002Fdebian-12-云服务器初始安全设置与优化指南#技术tag",[287],{"id":1930,"title":1773,"titles":1931,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fdebian-12-云服务器初始安全设置与优化指南#一初始登录与用户安全",[287],{"id":1933,"title":1777,"titles":1934,"content":1779,"level":367},"\u002Fblog\u002F技术栈\u002Fdebian-12-云服务器初始安全设置与优化指南#_1-创建替代root的用户",[287,1773],{"id":1936,"title":1782,"titles":1937,"content":1784,"level":367},"\u002Fblog\u002F技术栈\u002Fdebian-12-云服务器初始安全设置与优化指南#_2-禁用root-ssh登录",[287,1773],{"id":1939,"title":1787,"titles":1940,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fdebian-12-云服务器初始安全设置与优化指南#二防火墙配置",[287],{"id":1942,"title":1791,"titles":1943,"content":1793,"level":367},"\u002Fblog\u002F技术栈\u002Fdebian-12-云服务器初始安全设置与优化指南#ufw基础设置",[287,1787],{"id":1945,"title":1796,"titles":1946,"content":1798,"level":367},"\u002Fblog\u002F技术栈\u002Fdebian-12-云服务器初始安全设置与优化指南#端口安全技巧",[287,1787],{"id":1948,"title":1801,"titles":1949,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fdebian-12-云服务器初始安全设置与优化指南#三系统更新与自动维护",[287],{"id":1951,"title":1805,"titles":1952,"content":1807,"level":367},"\u002Fblog\u002F技术栈\u002Fdebian-12-云服务器初始安全设置与优化指南#初始全面更新",[287,1801],{"id":1954,"title":1810,"titles":1955,"content":1812,"level":367},"\u002Fblog\u002F技术栈\u002Fdebian-12-云服务器初始安全设置与优化指南#配置自动安全更新",[287,1801],{"id":1957,"title":1815,"titles":1958,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fdebian-12-云服务器初始安全设置与优化指南#四安全加固关键措施",[287],{"id":1960,"title":1819,"titles":1961,"content":1821,"level":367},"\u002Fblog\u002F技术栈\u002Fdebian-12-云服务器初始安全设置与优化指南#_1-启用基础入侵防护",[287,1815],{"id":1963,"title":1824,"titles":1964,"content":1826,"level":367},"\u002Fblog\u002F技术栈\u002Fdebian-12-云服务器初始安全设置与优化指南#_2-内核安全加固",[287,1815],{"id":1966,"title":1829,"titles":1967,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fdebian-12-云服务器初始安全设置与优化指南#五性能优化设置",[287],{"id":1969,"title":1833,"titles":1970,"content":1835,"level":367},"\u002Fblog\u002F技术栈\u002Fdebian-12-云服务器初始安全设置与优化指南#_1-交换空间优化",[287,1829],{"id":1972,"title":1838,"titles":1973,"content":1840,"level":367},"\u002Fblog\u002F技术栈\u002Fdebian-12-云服务器初始安全设置与优化指南#_2-文件描述符与进程优化",[287,1829],{"id":1975,"title":1843,"titles":1976,"content":1845,"level":367},"\u002Fblog\u002F技术栈\u002Fdebian-12-云服务器初始安全设置与优化指南#_3-日志管理防止占满磁盘",[287,1829],{"id":1978,"title":1848,"titles":1979,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fdebian-12-云服务器初始安全设置与优化指南#六审计与监控",[287],{"id":1981,"title":1852,"titles":1982,"content":1854,"level":367},"\u002Fblog\u002F技术栈\u002Fdebian-12-云服务器初始安全设置与优化指南#安装基础监控组件",[287,1848],{"id":1984,"title":1857,"titles":1985,"content":1859,"level":367},"\u002Fblog\u002F技术栈\u002Fdebian-12-云服务器初始安全设置与优化指南#关键审计命令",[287,1848],{"id":293,"title":292,"titles":1987,"content":1988,"level":324},[],"Iperf3 万兆网络打流测试指南 🔍 文档说明: 本文记录基于水星S106E Pro交换机的万兆网络Iperf3性能测试，涵盖设备连接、测试参数配置及结果分析。适用于网络性能测试初学者及运维人员。",{"id":1990,"title":1768,"titles":1991,"content":1992,"level":335},"\u002Fblog\u002F技术栈\u002Fiperf3-万兆网络打流测试指南#技术tag",[292],"#Iperf3 #万兆网络测试 #交换机配置 #AQC113网卡 #网络性能分析",{"id":1994,"title":1995,"titles":1996,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fiperf3-万兆网络打流测试指南#一测试环境配置","一、测试环境配置",[292],{"id":1998,"title":1999,"titles":2000,"content":2001,"level":367},"\u002Fblog\u002F技术栈\u002Fiperf3-万兆网络打流测试指南#设备拓扑图","设备拓扑图",[292,1995],"#mermaid-0{font-family:arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-0 .error-icon{fill:#552222;}#mermaid-0 .error-text{fill:#552222;stroke:#552222;}#mermaid-0 .edge-thickness-normal{stroke-width:1px;}#mermaid-0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-0 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-0 .marker{fill:#333333;stroke:#333333;}#mermaid-0 .marker.cross{stroke:#333333;}#mermaid-0 svg{font-family:arial,sans-serif;font-size:16px;}#mermaid-0 p{margin:0;}#mermaid-0 .label{font-family:arial,sans-serif;color:#333;}#mermaid-0 .cluster-label text{fill:#333;}#mermaid-0 .cluster-label span{color:#333;}#mermaid-0 .cluster-label span p{background-color:transparent;}#mermaid-0 .label text,#mermaid-0 span{fill:#333;color:#333;}#mermaid-0 .node rect,#mermaid-0 .node circle,#mermaid-0 .node ellipse,#mermaid-0 .node polygon,#mermaid-0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-0 .rough-node .label text,#mermaid-0 .node .label text,#mermaid-0 .image-shape .label,#mermaid-0 .icon-shape .label{text-anchor:middle;}#mermaid-0 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-0 .rough-node .label,#mermaid-0 .node .label,#mermaid-0 .image-shape .label,#mermaid-0 .icon-shape .label{text-align:center;}#mermaid-0 .node.clickable{cursor:pointer;}#mermaid-0 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-0 .arrowheadPath{fill:#333333;}#mermaid-0 .edgePath .path{stroke:#333333;stroke-width:1px;}#mermaid-0 .flowchart-link{stroke:#333333;fill:none;}#mermaid-0 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-0 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-0 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-0 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-0 .cluster text{fill:#333;}#mermaid-0 .cluster span{color:#333;}#mermaid-0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-0 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-0 rect.text{fill:none;stroke-width:0;}#mermaid-0 .icon-shape,#mermaid-0 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-0 .icon-shape p,#mermaid-0 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-0 .icon-shape .label rect,#mermaid-0 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-0 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-0 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-0 .node .neo-node{stroke:#9370DB;}#mermaid-0 [data-look=\"neo\"].node rect,#mermaid-0 [data-look=\"neo\"].cluster rect,#mermaid-0 [data-look=\"neo\"].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-0 [data-look=\"neo\"].node path{stroke:#9370DB;stroke-width:1px;}#mermaid-0 [data-look=\"neo\"].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-0 [data-look=\"neo\"].node .neo-line path{stroke:#9370DB;filter:none;}#mermaid-0 [data-look=\"neo\"].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-0 [data-look=\"neo\"].node circle .state-start{fill:#000000;}#mermaid-0 [data-look=\"neo\"].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-0 [data-look=\"neo\"].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#mermaid-0 :root{--mermaid-font-family:arial,sans-serif;}雷电\u002F万兆电口万兆光口MacBook Air M4水星S106E Pro万兆光口PVE服务器CX4121A网卡",{"id":2003,"title":2004,"titles":2005,"content":2006,"level":367},"\u002Fblog\u002F技术栈\u002Fiperf3-万兆网络打流测试指南#硬件清单","硬件清单",[292,1995],"设备规格作用主测试端MacBook Air M4 + 雷电万兆网卡(AQC113)Iperf3 Client端交换机水星S106E Pro万兆光\u002F电转换枢纽光转电模块AQR113光转电模块连接交换机万兆光口被测服务端NAS (12500T+Q670) + CX4121A万兆网卡Iperf3 Server端辅助设备超六类网线\u002F光纤跳线(按需)物理链路连接",{"id":2008,"title":2009,"titles":2010,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fiperf3-万兆网络打流测试指南#二iperf3安装与配置","二、Iperf3安装与配置",[292],{"id":2012,"title":2013,"titles":2014,"content":2015,"level":367},"\u002Fblog\u002F技术栈\u002Fiperf3-万兆网络打流测试指南#_1-macos端安装client","1. macOS端安装（Client）",[292,2009],"# 通过Homebrew安装iperf3\n    brew install iperf3\n\n# 启动服务端监听（可选本地验证）\n    iperf3 -s -p 5201",{"id":2017,"title":2018,"titles":2019,"content":2020,"level":367},"\u002Fblog\u002F技术栈\u002Fiperf3-万兆网络打流测试指南#_2-pve服务端安装server","2. PVE服务端安装（Server）",[292,2009],"# Debian系系统安装\n    apt update && apt install iperf3 -y\n\n# 启动服务端后台监听\n    iperf3 -s -D -p 5201 ⚠️ 防火墙注意: 确保5201端口开放\nufw allow 5201\u002Ftcp (Debian\u002FUbuntu)\nfirewall-cmd --add-port=5201\u002Ftcp --permanent (CentOS) ## 三、典型测试场景\n### 场景1：TCP带宽测试（默认参数）\n```bash\n# Client端执行（MacBook）\niperf3 -c \u003CServer_IP> -p 5201 -t 60\n\n# 参数说明：\n# -c : 服务端IP地址\n# -t : 测试持续时间(秒)",{"id":2022,"title":2023,"titles":2024,"content":2025,"level":367},"\u002Fblog\u002F技术栈\u002Fiperf3-万兆网络打流测试指南#场景2多线程udp压力测试","场景2：多线程UDP压力测试",[292,2009],"iperf3 -c \u003CServer_IP> -p 5201 -u -b 10G -P 4\n\n# 参数说明：\n# -u : 使用UDP协议\n# -b : 指定带宽(10G速率)\n# -P : 并行线程数",{"id":2027,"title":2028,"titles":2029,"content":2030,"level":367},"\u002Fblog\u002F技术栈\u002Fiperf3-万兆网络打流测试指南#场景3双向流量测试","场景3：双向流量测试",[292,2009],"# 同时测试上行+下行\niperf3 -c \u003CServer_IP> -p 5201 --bidir",{"id":2032,"title":2033,"titles":2034,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fiperf3-万兆网络打流测试指南#四测试结果分析要点","四、测试结果分析要点",[292],{"id":2036,"title":2037,"titles":2038,"content":2039,"level":367},"\u002Fblog\u002F技术栈\u002Fiperf3-万兆网络打流测试指南#关键性能指标","关键性能指标",[292,2033],"字段健康值范围异常排查方向Bandwidth>9.5Gbps (万兆场景)网卡协商\u002F模块兼容性Jitter\u003C1ms (UDP测试)交换机缓存\u002F线缆质量Packet Loss0%缓冲区设置\u002FCPU性能TCP Retransmits\u003C0.1%TCP窗口\u002FMTU配置 💡 优化建议：使用-w调整TCP窗口大小（例如-w 8M）尝试--omit N跳过初始N秒不稳定数据添加-J参数获取JSON格式结构化结果",{"id":2041,"title":2042,"titles":2043,"content":361,"level":335},"\u002Fblog\u002F技术栈\u002Fiperf3-万兆网络打流测试指南#五常见问题解决","五、常见问题解决",[292],{"id":2045,"title":2046,"titles":2047,"content":2048,"level":367},"\u002Fblog\u002F技术栈\u002Fiperf3-万兆网络打流测试指南#问题1协商速率降级至1gbps","❌ 问题1：协商速率降级至1Gbps",[292,2042],"# 检查网卡协商状态（MacOS）\nifconfig enX | grep media\n\n# 解决方案：\n1. 更换光模块\u002FAOC线缆排除物理故障\n2. 检查交换机端口配置（禁用节能模式）",{"id":2050,"title":2051,"titles":2052,"content":2053,"level":367},"\u002Fblog\u002F技术栈\u002Fiperf3-万兆网络打流测试指南#问题2测试中突发丢包","❌ 问题2：测试中突发丢包",[292,2042],"# 动态查看QoS统计（PVE服务器）\nethtool -S enpXX | grep -E 'drop|error'\n\n# 解决方案：\n1. 调整网卡缓冲区：ethtool -G enpXX rx\u002Ftx 4096\n2. 减少并发线程总数（-P参数） 📌 经验总结：水星S106E Pro需关闭\"绿色节能\"功能，避免AQC113因节能策略降速。PVE虚拟机环境建议使用SR-IOV直通网卡，减少虚拟化层开销。 测试文档版本: v1.1\n更新日期: 2023-12-15\n测试工具版本: iperf 3.16 (macOS)\u002Fiperf 3.7 (Linux) html pre.shiki code .ss7Ak, html code.shiki .ss7Ak{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit;--shiki-sepia:#88846F;--shiki-sepia-font-style:inherit}html pre.shiki code .sPYpf, html code.shiki .sPYpf{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .s7i02, html code.shiki .s7i02{--shiki-light:#91B859;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .s516T, html code.shiki .s516T{--shiki-light:#F76D47;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .srSnV, html code.shiki .srSnV{--shiki-light:#39ADB5;--shiki-default:#F97583;--shiki-dark:#F97583;--shiki-sepia:#F92672}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}",{"id":298,"title":297,"titles":2055,"content":2056,"level":324},[],"Grok3 和 Deepseek 的对比",{"id":2058,"title":297,"titles":2059,"content":2060,"level":367},"\u002Fblog\u002F技术栈\u002Fgrok3-and-deepseek#grok3-and-deepseek",[297],"测试了GROK3,简单让做一个HTML小游戏，与R1对比\nGROK3界面处理略好，满足所有要求，无BUG。\nR1界面略有瑕疵，基本满足所有要求，除了有小BUG。 提示词： 题目：编写一个“打地鼠”网页小游戏 需求描述：\n设计一个基于HTML的“打地鼠”（Whack-a-Mole）小游戏，玩家需要在规定时间内点击随机出现的“地鼠”来得分。游戏需要包含以下功能和要求：\n页面布局：\n游戏区域是一个3x3的网格（共9个格子），每个格子是一个方形的“洞”。\n页面顶部显示当前得分（Score）和剩余时间（Time Left）。\n页面底部有一个“开始游戏”（Start Game）的按钮。\n游戏逻辑：\n点击“开始游戏”按钮后，游戏开始，初始时间为30秒。\n每隔一段随机时间（0.5秒到1.5秒之间），一个“地鼠”会随机出现在某个格子中，持续显示1秒后消失。\n玩家点击出现的“地鼠”可以得分，每只地鼠加1分。\n如果点击空白格子，不扣分也不加分。\n游戏时间结束后，停止地鼠出现，并弹窗显示最终得分，同时提供“再玩一次”的选项。\n样式要求：\n游戏区域居中，背景为浅灰色。\n每个格子为100x100像素，带有圆角边框，初始为土黄色（#d2b48c）。\n地鼠出现时，格子背景变为绿色（#90ee90），并显示文字“鼠！”（字体大小30px，居中）。\n得分和时间使用清晰的大字体（建议20px以上），颜色为深蓝色。\n“开始游戏”按钮为蓝色背景，白色文字，悬停时变亮。\n技术要求：\n使用纯HTML、CSS和JavaScript实现，不依赖外部库。\n代码注释清晰，说明每个部分的功能。\n确保游戏逻辑无明显bug，例如地鼠不会同时出现在多个格子。\n提示词：\nHTML结构：包含游戏容器、得分显示、时间显示、格子网格和按钮。\nCSS样式：网格布局、格子样式、地鼠出现时的动态效果、按钮交互样式。\nJavaScript逻辑：随机生成地鼠、计时器、得分计算、游戏状态管理、弹窗提示。\n输出要求：\n请一次性提供完整的HTML文件代码（包括HTML、CSS和JavaScript），代码需可直接保存为.html文件并在浏览器中运行。代码中需包含注释，体现逻辑清晰度和编程能力。 GROK3: \u003C!DOCTYPE html>\n\n \u003Chtml lang=\"zh-CN\">\n\n \u003Chead>\n\n \u003Cmeta charset=\"UTF-8\">\n\n \u003Cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n\n \u003Ctitle>打地鼠小游戏\u003C\u002Ftitle>\n\n \u003Cstyle>\n\n \u002F* 整体页面样式 *\u002F\n\n body {\n\n display: flex;\n\n flex-direction: column;\n\n align-items: center;\n\n justify-content: center;\n\n height: 100vh;\n\n margin: 0;\n\n font-family: Arial, sans-serif;\n\n background-color: #f0f0f0;\n\n }\n\n\n\n \u002F* 顶部得分和时间显示 *\u002F\n\n .info {\n\n display: flex;\n\n justify-content: space-between;\n\n width: 320px;\n\n margin-bottom: 20px;\n\n }\n\n .info span {\n\n font-size: 24px;\n\n color: #00008b; \u002F* 深蓝色 *\u002F\n\n }\n\n\n\n \u002F* 游戏区域网格 *\u002F\n\n .game-board {\n\n display: grid;\n\n grid-template-columns: repeat(3, 100px);\n\n grid-gap: 10px;\n\n background-color: #d3d3d3; \u002F* 浅灰色背景 *\u002F\n\n padding: 10px;\n\n border-radius: 10px;\n\n }\n\n\n\n \u002F* 每个格子样式 *\u002F\n\n .hole {\n\n width: 100px;\n\n height: 100px;\n\n background-color: #d2b48c; \u002F* 土黄色 *\u002F\n\n border-radius: 10px;\n\n display: flex;\n\n align-items: center;\n\n justify-content: center;\n\n font-size: 30px;\n\n color: #000;\n\n cursor: pointer;\n\n transition: background-color 0.2s;\n\n }\n\n\n\n \u002F* 地鼠出现时的样式 *\u002F\n\n .hole.mole {\n\n background-color: #90ee90; \u002F* 绿色 *\u002F\n\n }\n\n\n\n \u002F* 开始按钮样式 *\u002F\n\n .start-btn {\n\n margin-top: 20px;\n\n padding: 10px 20px;\n\n font-size: 18px;\n\n color: #fff;\n\n background-color: #4682b4; \u002F* 蓝色 *\u002F\n\n border: none;\n\n border-radius: 5px;\n\n cursor: pointer;\n\n transition: background-color 0.3s;\n\n }\n\n .start-btn:hover {\n\n background-color: #5f9ea0; \u002F* 悬停时变亮 *\u002F\n\n }\n\n \u003C\u002Fstyle>\n\n \u003C\u002Fhead>\n\n \u003Cbody>\n\n \u003C!-- 顶部信息 -->\n\n \u003Cdiv class=\"info\">\n\n \u003Cspan id=\"score\">得分: 0\u003C\u002Fspan>\n\n \u003Cspan id=\"time-left\">剩余时间: 30\u003C\u002Fspan>\n\n \u003C\u002Fdiv>\n\n\n\n \u003C!-- 游戏区域 -->\n\n \u003Cdiv class=\"game-board\" id=\"gameBoard\">\n\n \u003C!-- 9个格子 -->\n\n \u003Cdiv class=\"hole\" data-id=\"0\">\u003C\u002Fdiv>\n\n \u003Cdiv class=\"hole\" data-id=\"1\">\u003C\u002Fdiv>\n\n \u003Cdiv class=\"hole\" data-id=\"2\">\u003C\u002Fdiv>\n\n \u003Cdiv class=\"hole\" data-id=\"3\">\u003C\u002Fdiv>\n\n \u003Cdiv class=\"hole\" data-id=\"4\">\u003C\u002Fdiv>\n\n \u003Cdiv class=\"hole\" data-id=\"5\">\u003C\u002Fdiv>\n\n \u003Cdiv class=\"hole\" data-id=\"6\">\u003C\u002Fdiv>\n\n \u003Cdiv class=\"hole\" data-id=\"7\">\u003C\u002Fdiv>\n\n \u003Cdiv class=\"hole\" data-id=\"8\">\u003C\u002Fdiv>\n\n \u003C\u002Fdiv>\n\n\n\n \u003C!-- 开始按钮 -->\n\n \u003Cbutton class=\"start-btn\" id=\"startBtn\">开始游戏\u003C\u002Fbutton>\n\n\n\n \u003Cscript>\n\n \u002F\u002F 获取DOM元素\n\n const scoreDisplay = document.getElementById('score');\n\n const timeLeftDisplay = document.getElementById('time-left');\n\n const gameBoard = document.getElementById('gameBoard');\n\n const startBtn = document.getElementById('startBtn');\n\n const holes = document.querySelectorAll('.hole');\n\n\n\n \u002F\u002F 游戏状态变量\n\n let score = 0;\n\n let timeLeft = 30;\n\n let gameActive = false;\n\n let moleTimer = null;\n\n let countdownTimer = null;\n\n\n\n \u002F\u002F 初始化游戏\n\n function initGame() {\n\n score = 0;\n\n timeLeft = 30;\n\n gameActive = false;\n\n scoreDisplay.textContent = `得分: ${score}`;\n\n timeLeftDisplay.textContent = `剩余时间: ${timeLeft}`;\n\n clearInterval(moleTimer);\n\n clearInterval(countdownTimer);\n\n holes.forEach(hole => {\n\n hole.classList.remove('mole');\n\n hole.textContent = '';\n\n });\n\n }\n\n\n\n \u002F\u002F 随机选择一个格子显示地鼠\n\n function showMole() {\n\n if (!gameActive) return;\n\n\n\n \u002F\u002F 移除之前的地鼠\n\n holes.forEach(hole => {\n\n hole.classList.remove('mole');\n\n hole.textContent = '';\n\n });\n\n\n\n \u002F\u002F 随机选择一个格子\n\n const randomHole = holes[Math.floor(Math.random() * holes.length)];\n\n randomHole.classList.add('mole');\n\n randomHole.textContent = '鼠！';\n\n\n\n \u002F\u002F 1秒后隐藏地鼠\n\n setTimeout(() => {\n\n randomHole.classList.remove('mole');\n\n randomHole.textContent = '';\n\n }, 1000);\n\n\n\n \u002F\u002F 随机间隔后再次显示地鼠\n\n const randomInterval = Math.random() * 1000 + 500; \u002F\u002F 0.5到1.5秒\n\n moleTimer = setTimeout(showMole, randomInterval);\n\n }\n\n\n\n \u002F\u002F 点击格子的事件\n\n function hitMole(e) {\n\n const hole = e.target;\n\n if (hole.classList.contains('mole')) {\n\n score++;\n\n scoreDisplay.textContent = `得分: ${score}`;\n\n hole.classList.remove('mole');\n\n hole.textContent = '';\n\n }\n\n }\n\n\n\n \u002F\u002F 开始游戏\n\n function startGame() {\n\n if (gameActive) return; \u002F\u002F 防止重复开始\n\n initGame();\n\n gameActive = true;\n\n startBtn.disabled = true;\n\n\n\n \u002F\u002F 开始倒计时\n\n countdownTimer = setInterval(() => {\n\n timeLeft--;\n\n timeLeftDisplay.textContent = `剩余时间: ${timeLeft}`;\n\n if (timeLeft \u003C= 0) {\n\n endGame();\n\n }\n\n }, 1000);\n\n\n\n \u002F\u002F 开始地鼠出现\n\n showMole();\n\n }\n\n\n\n \u002F\u002F 游戏结束\n\n function endGame() {\n\n gameActive = false;\n\n clearInterval(moleTimer);\n\n clearInterval(countdownTimer);\n\n startBtn.disabled = false;\n\n alert(`游戏结束！你的得分是: ${score}\\n点击“确定”再玩一次！`);\n\n initGame();\n\n }\n\n\n\n \u002F\u002F 事件绑定\n\n startBtn.addEventListener('click', startGame);\n\n holes.forEach(hole => hole.addEventListener('click', hitMole));\n\n\n\n \u002F\u002F 初始化游戏状态\n\n initGame();\n\n \u003C\u002Fscript>\n\n \u003C\u002Fbody>\n\n \u003C\u002Fhtml> R1: \u003C!DOCTYPE html>\n\n \u003Chtml lang=\"zh-CN\">\n\n \u003Chead>\n\n \u003Cmeta charset=\"UTF-8\">\n\n \u003Ctitle>打地鼠 - Whack a Mole\u003C\u002Ftitle>\n\n \u003Cstyle>\n\n \u002F* 页面整体样式 *\u002F\n\n body {\n\n font-family: Arial, sans-serif;\n\n display: flex;\n\n flex-direction: column;\n\n align-items: center;\n\n background-color: #f0f0f0;\n\n margin: 0;\n\n min-height: 100vh;\n\n }\n\n\n\n \u002F* 游戏信息显示区域 *\u002F\n\n .game-info {\n\n margin: 20px 0;\n\n font-size: 24px;\n\n color: #00008b;\n\n display: flex;\n\n gap: 30px;\n\n }\n\n\n\n \u002F* 游戏主容器（3x3网格） *\u002F\n\n #game-board {\n\n display: grid;\n\n grid-template-columns: repeat(3, 100px);\n\n gap: 10px;\n\n background-color: #cccccc;\n\n padding: 20px;\n\n border-radius: 10px;\n\n }\n\n\n\n \u002F* 单个地鼠洞样式 *\u002F\n\n .hole {\n\n width: 100px;\n\n height: 100px;\n\n background-color: #d2b48c;\n\n border-radius: 8px;\n\n cursor: pointer;\n\n display: flex;\n\n justify-content: center;\n\n align-items: center;\n\n font-size: 0; \u002F* 初始隐藏文字 *\u002F\n\n transition: background-color 0.2s;\n\n }\n\n\n\n \u002F* 地鼠出现时的样式 *\u002F\n\n .hole.active {\n\n background-color: #90ee90;\n\n font-size: 30px; \u002F* 显示文字 *\u002F\n\n }\n\n\n\n \u002F* 开始游戏按钮 *\u002F\n\n #start-btn {\n\n margin-top: 30px;\n\n padding: 12px 30px;\n\n background-color: #0000ff;\n\n color: white;\n\n border: none;\n\n border-radius: 5px;\n\n cursor: pointer;\n\n font-size: 18px;\n\n transition: background-color 0.2s;\n\n }\n\n\n\n #start-btn:hover {\n\n background-color: #3333ff;\n\n }\n\n\n\n #start-btn:disabled {\n\n background-color: #888888;\n\n cursor: not-allowed;\n\n }\n\n \u003C\u002Fstyle>\n\n \u003C\u002Fhead>\n\n \u003Cbody>\n\n \u003C!-- 游戏信息显示 -->\n\n \u003Cdiv class=\"game-info\">\n\n \u003Cdiv>得分：\u003Cspan id=\"score\">0\u003C\u002Fspan>\u003C\u002Fdiv>\n\n \u003Cdiv>剩余时间：\u003Cspan id=\"timer\">30\u003C\u002Fspan>秒\u003C\u002Fdiv>\n\n \u003C\u002Fdiv>\n\n\n\n \u003C!-- 游戏主区域 -->\n\n \u003Cdiv id=\"game-board\">\n\n \u003C!-- 生成9个地鼠洞 -->\n\n \u003Cdiv class=\"hole\">\u003C\u002Fdiv>\n\n \u003Cdiv class=\"hole\">\u003C\u002Fdiv>\n\n \u003Cdiv class=\"hole\">\u003C\u002Fdiv>\n\n \u003Cdiv class=\"hole\">\u003C\u002Fdiv>\n\n \u003Cdiv class=\"hole\">\u003C\u002Fdiv>\n\n \u003Cdiv class=\"hole\">\u003C\u002Fdiv>\n\n \u003Cdiv class=\"hole\">\u003C\u002Fdiv>\n\n \u003Cdiv class=\"hole\">\u003C\u002Fdiv>\n\n \u003Cdiv class=\"hole\">\u003C\u002Fdiv>\n\n \u003C\u002Fdiv>\n\n\n\n \u003C!-- 控制按钮 -->\n\n \u003Cbutton id=\"start-btn\">开始游戏\u003C\u002Fbutton>\n\n\n\n \u003Cscript>\n\n \u002F\u002F 游戏全局变量\n\n let score = 0;\n\n let timeLeft = 30;\n\n let gameActive = false;\n\n let moleTimer = null;\n\n let countdownTimer = null;\n\n\n\n \u002F\u002F DOM元素引用\n\n const holes = document.querySelectorAll('.hole');\n\n const scoreDisplay = document.getElementById('score');\n\n const timerDisplay = document.getElementById('timer');\n\n const startBtn = document.getElementById('start-btn');\n\n\n\n \u002F\u002F 初始化点击事件监听\n\n holes.forEach(hole => {\n\n hole.addEventListener('click', () => {\n\n if (!gameActive) return;\n\n \u002F\u002F 点击有效的地鼠\n\n if (hole.classList.contains('active')) {\n\n score++;\n\n scoreDisplay.textContent = score;\n\n hole.classList.remove('active');\n\n hole.textContent = '';\n\n }\n\n });\n\n });\n\n\n\n \u002F\u002F 开始游戏按钮功能\n\n startBtn.addEventListener('click', () => {\n\n if (!gameActive) {\n\n startGame();\n\n }\n\n });\n\n\n\n \u002F\u002F 游戏主逻辑\n\n function startGame() {\n\n \u002F\u002F 重置游戏状态\n\n gameActive = true;\n\n score = 0;\n\n timeLeft = 30;\n\n scoreDisplay.textContent = score;\n\n timerDisplay.textContent = timeLeft;\n\n startBtn.disabled = true;\n\n\n\n \u002F\u002F 清除已有定时器\n\n clearInterval(countdownTimer);\n\n clearTimeout(moleTimer);\n\n\n\n \u002F\u002F 启动倒计时\n\n countdownTimer = setInterval(() => {\n\n timeLeft--;\n\n timerDisplay.textContent = timeLeft;\n\n if (timeLeft \u003C= 0) {\n\n endGame();\n\n }\n\n }, 1000);\n\n\n\n \u002F\u002F 首次生成地鼠\n\n scheduleMole();\n\n }\n\n\n\n \u002F\u002F 随机生成地鼠\n\n function showMole() {\n\n \u002F\u002F 查找所有非活动状态的洞\n\n const availableHoles = Array.from(holes).filter(hole => !hole.classList.contains('active'));\n\n if (availableHoles.length > 0) {\n\n const randomHole = availableHoles[Math.floor(Math.random() * availableHoles.length)];\n\n randomHole.classList.add('active');\n\n randomHole.textContent = '鼠！';\n\n \u002F\u002F 自动隐藏地鼠\n\n setTimeout(() => {\n\n randomHole.classList.remove('active');\n\n randomHole.textContent = '';\n\n }, 1000);\n\n }\n\n }\n\n\n\n \u002F\u002F 调度下一个地鼠生成\n\n function scheduleMole() {\n\n if (!gameActive) return;\n\n \u002F\u002F 随机间隔（0.5-1.5秒）\n\n const delay = Math.random() * 1000 + 500;\n\n moleTimer = setTimeout(() => {\n\n showMole();\n\n scheduleMole();\n\n }, delay);\n\n }\n\n\n\n \u002F\u002F 结束游戏处理\n\n function endGame() {\n\n gameActive = false;\n\n clearInterval(countdownTimer);\n\n clearTimeout(moleTimer);\n\n startBtn.disabled = false;\n\n\n\n \u002F\u002F 显示最终得分\n\n const restart = confirm(`游戏结束！最终得分：${score}\\n再玩一次？`);\n\n if (restart) {\n\n startGame();\n\n }\n\n }\n\n \u003C\u002Fscript>\n\n \u003C\u002Fbody>\n\n \u003C\u002Fhtml> html pre.shiki code .shBcb, html code.shiki .shBcb{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .sQqVo, html code.shiki .sQqVo{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html pre.shiki code .sdE5Q, html code.shiki .sdE5Q{--shiki-light:#9C3EDA;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sE2Px, html code.shiki .sE2Px{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sW0_z, html code.shiki .sW0_z{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .sY37W, html code.shiki .sY37W{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .ss7Ak, html code.shiki .ss7Ak{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit;--shiki-sepia:#88846F;--shiki-sepia-font-style:inherit}html pre.shiki code .sekv-, html code.shiki .sekv-{--shiki-light:#E2931D;--shiki-default:#85E89D;--shiki-dark:#85E89D;--shiki-sepia:#F92672}html pre.shiki code .sY-BA, html code.shiki .sY-BA{--shiki-light:#8796B0;--shiki-light-font-style:inherit;--shiki-default:#79B8FF;--shiki-default-font-style:inherit;--shiki-dark:#79B8FF;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .s0RPl, html code.shiki .s0RPl{--shiki-light:#90A4AE;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#66D9EF}html pre.shiki code .s516T, html code.shiki .s516T{--shiki-light:#F76D47;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .s0O3k, html code.shiki .s0O3k{--shiki-light:#F76D47;--shiki-default:#F97583;--shiki-dark:#F97583;--shiki-sepia:#F92672}html pre.shiki code .sQnY8, html code.shiki .sQnY8{--shiki-light:#39ADB5;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .sO8DV, html code.shiki .sO8DV{--shiki-light:#90A4AE;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .sAedU, html code.shiki .sAedU{--shiki-light:#39ADB5;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sPYpf, html code.shiki .sPYpf{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sunJZ, html code.shiki .sunJZ{--shiki-light:#6182B8;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#66D9EF}html pre.shiki code .sLeJD, html code.shiki .sLeJD{--shiki-light:#9C3EDA;--shiki-light-font-style:inherit;--shiki-default:#F97583;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit;--shiki-sepia:#66D9EF;--shiki-sepia-font-style:italic}html pre.shiki code .sGtwI, html code.shiki .sGtwI{--shiki-light:#90A4AE;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#F8F8F2}html pre.shiki code .srSnV, html code.shiki .srSnV{--shiki-light:#39ADB5;--shiki-default:#F97583;--shiki-dark:#F97583;--shiki-sepia:#F92672}html pre.shiki code .sLcK_, html code.shiki .sLcK_{--shiki-light:#6182B8;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .shVGa, html code.shiki .shVGa{--shiki-light:#FF5370;--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .s_36h, html code.shiki .s_36h{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-sepia:#F92672}html pre.shiki code .sHV4B, html code.shiki .sHV4B{--shiki-light:#E53935;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-sepia:#F8F8F2}html pre.shiki code .shyvS, html code.shiki .shyvS{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#FFAB70;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit;--shiki-sepia:#FD971F;--shiki-sepia-font-style:italic}html pre.shiki code .sEIvO, html code.shiki .sEIvO{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#F97583;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit;--shiki-sepia:#F92672;--shiki-sepia-font-style:inherit}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .swKMm, html code.shiki .swKMm{--shiki-light:#F76D47;--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}",{"id":309,"title":308,"titles":2062,"content":308,"level":324},[],{"id":2064,"title":2065,"titles":2066,"content":361,"level":367},"\u002Fblog\u002Fai\u002Fai#ai-文章等待从旧blog中搬迁","AI 文章等待从旧Blog中搬迁",[308],{"id":318,"title":312,"titles":2068,"content":312,"level":324},[],{"id":2070,"title":2071,"titles":2072,"content":361,"level":367},"\u002Fblog\u002F生活\u002F生活#生活-类等待从旧blog迁移","生活 类等待从旧Blog迁移",[312],{"id":2074,"title":781,"body":2075,"description":783,"extension":2080,"links":2081,"meta":2082,"navigation":53,"path":780,"rawbody":2084,"seo":2085,"stem":2086,"__hash__":2087},"docs\u002Fdocs\u002F99.about.md",{"type":2076,"value":2077,"toc":2078},"minimark",[],{"title":361,"searchDepth":335,"depth":335,"links":2079},[],"md",null,{"date":2083},"2025-07-31","---\ntitle: 关于\ndescription: Estel Docs 文档系统\ndate: 2025-07-31\nnavigation: false\n---\n",{"title":781,"description":783},"docs\u002F99.about","B_hXSKikdJg9dEeokWR6YwslBiydtpDJcibAAFb2SzA",[2081,2081],1781274986141]