diff --git a/.reasonix/desktop-topic-title-sources.json b/.reasonix/desktop-topic-title-sources.json
index 1f320c1..52ac5d3 100644
--- a/.reasonix/desktop-topic-title-sources.json
+++ b/.reasonix/desktop-topic-title-sources.json
@@ -19,5 +19,12 @@
"topic_20260703-031922_1d2031ca5f2c0dd5": "auto",
"topic_20260703-035328_e939286e13cc8f1b": "auto",
"topic_20260703-060642_54474cc49e29104f": "auto",
- "topic_20260703-065009_d937c6f780ebb5de": "auto"
+ "topic_20260703-065009_d937c6f780ebb5de": "auto",
+ "topic_20260703-071019_122507af94a4bb69": "auto",
+ "topic_20260703-073828_e23737acfa7578f3": "auto",
+ "topic_20260703-075048_605d579e54dfa8f9": "auto",
+ "topic_20260703-081048_20d0dd6e24fe0eca": "auto",
+ "topic_20260703-090137_2a285dcd68326d53": "auto",
+ "topic_20260703-093407_89b9baa209988cbb": "auto",
+ "topic_20260706-025751_d46402fb217a34e9": "auto"
}
\ No newline at end of file
diff --git a/.reasonix/desktop-topic-titles.json b/.reasonix/desktop-topic-titles.json
index d453b60..8093ce1 100644
--- a/.reasonix/desktop-topic-titles.json
+++ b/.reasonix/desktop-topic-titles.json
@@ -19,5 +19,12 @@
"topic_20260703-031922_1d2031ca5f2c0dd5": "我希望第126-228行的内容,在用…",
"topic_20260703-035328_e939286e13cc8f1b": "我们把整个右侧区域都给了markdo…",
"topic_20260703-060642_54474cc49e29104f": "关于这个核心编辑区域,我需要实现一个…",
- "topic_20260703-065009_d937c6f780ebb5de": "在功能上有问题,现在用户输入的内容删…"
+ "topic_20260703-065009_d937c6f780ebb5de": "在功能上有问题,现在用户输入的内容删…",
+ "topic_20260703-071019_122507af94a4bb69": "现在已经有了很多功能,但是很多样式还…",
+ "topic_20260703-073828_e23737acfa7578f3": "现在我点击md文件,怎么在编辑区域里…",
+ "topic_20260703-075048_605d579e54dfa8f9": "现在我点击目录中的md文件,怎么在编…",
+ "topic_20260703-081048_20d0dd6e24fe0eca": "在渲染的时候有几个问题需要修改,第一…",
+ "topic_20260703-090137_2a285dcd68326d53": "帮我检查一下这个页面为什么渲染不出来…",
+ "topic_20260703-093407_89b9baa209988cbb": "帮我检查一下这个页面为什么渲染不出来…",
+ "topic_20260706-025751_d46402fb217a34e9": "这个页面现在是用cm6实现的预览功能…"
}
\ No newline at end of file
diff --git a/doc/markdown-editor-design.md b/doc/markdown-editor-design.md
new file mode 100644
index 0000000..effb128
--- /dev/null
+++ b/doc/markdown-editor-design.md
@@ -0,0 +1,191 @@
+# MarkdownEditor 块级编辑设计文档
+
+## 概述
+
+`MarkdownEditor` 是 yurou(语柔)的核心编辑组件,支持两种编辑模式:
+
+| 模式 | 说明 |
+|---|---|
+| **双栏**(split) | 左侧 textarea 编辑源码,右侧 unified 渲染 HTML 预览,滚动同步 |
+| **单栏**(wysiwyg) | 逐块渲染与编辑:点击任意块弹出其原始 markdown 源码,失焦后自动重新渲染 |
+
+## 技术栈
+
+- **解析**:`remark-parse` + `remark-gfm`(GFM 扩展:表格、任务列表、删除线)
+- **转换**:`remark-rehype`(mdast → hast)
+- **安全**:`rehype-sanitize`(过滤 XSS,保留 `data-*` 属性)
+- **输出**:`rehype-stringify`(hast → HTML 字符串)
+- **框架**:Vue 3 Composition API + TypeScript
+
+## 整体架构
+
+```
+modelValue (markdown 字符串)
+ │
+ ├─── split 模式 ──────────────────────────
+ │ │
+ │ ├── textarea (左栏,编辑源码)
+ │ │ 输入 → emit('update:modelValue')
+ │ │
+ │ └── div.markdown-preview (右栏,v-html)
+ │ unified.processSync(md) → HTML
+ │ 滚动同步:textarea.scrollTop ↔ div.scrollTop
+ │
+ └─── wysiwyg 模式 ────────────────────────
+ │
+ ├── remark-parse → mdast
+ │ 提取每个顶层子节点的 position (offset)
+ │
+ ├── 每个 block:
+ │ source = md.slice(start, end) // 原始源码
+ │ html = unified.processSync(source) // 渲染 HTML
+ │
+ ├── blocks[] = [{id, source, html, startOffset, endOffset}, ...]
+ │
+ └── 模板中 v-for:
+ editingBlockId === block.id
+ ?
+ :
`,hover 时显示暖色背景提示可点击。
+
+### 3. 编辑阶段(`startEdit` → `finalizeEdit`)
+
+```
+用户点击某个 block
+ │
+ ▼
+startEdit(block.id)
+ │ editingBlockId = block.id
+ │ editingSource = block.source // 显示原始 markdown 源码
+ │ nextTick → autoResize + focus + 光标移到末尾
+ │
+ ▼
+
替换该块的
+ │
+ │ monospace 字体,暖色边框,auto-resize
+ │ Ctrl+S → 先 finalize 再触发 save-shortcut
+ │ Esc → cancelEdit (丢弃修改)
+ │
+ ▼
+失焦 (blur)
+ │
+ ▼
+finalizeEdit()
+ │ 如果 editingSource !== block.source:
+ │ before = md.slice(0, block.startOffset)
+ │ after = md.slice(block.endOffset)
+ │ emit('update:modelValue', before + newSource + after)
+ │
+ ▼
+父组件 update:modelValue → modelValue 变化
+ │
+ ▼
+watch(modelValue) → parseBlocks(newMd) → 重新渲染所有 block
+```
+
+### 4. 边界情况处理
+
+| 场景 | 处理方式 |
+|---|---|
+| 空文档 | 显示 placeholder 文本,点击后插入换行符触发解析 |
+| 块被删除所有内容 | 替换为空字符串,该块从 mdast 中消失 |
+| 块中增加空行 | 该块的 markdown 包含空行 → mdast 解析为多个块 → 下次渲染自动拆分 |
+| 代码块内编辑 | 三引号 + 语言标记全部显示在 textarea 中,用户自由编辑 |
+| 列表 | 整个列表(含所有 li)作为一个块,编辑时看到完整列表的 markdown |
+| 表格 | 整表作为一个块 |
+| 解析失败 | `catch` 后用 `escapeHtml(source)` 显示原文 |
+
+## 双栏模式流程
+
+```
+modelValue → unified.processSync(md) → HTML → v-html 渲染
+
+textarea (左) preview (右)
+ │ │
+ ├─ input → emit │
+ ├─ keydown │
+ │ ├─ Ctrl+S → save │
+ │ ├─ Tab → 2 spaces │
+ │ └─ 括号 → auto-pair │
+ │ │
+ └─ scroll → 同步比例 ──────► scrollTop
+```
+
+## 数据流
+
+```
+App.vue (content ref)
+ │
+ ├── :model-value="content"
+ ├── :display-mode="displayMode" ← 设置面板切换
+ ├── @update:model-value="onUpdate" → content = val
+ └── @save-shortcut="doSave"
+
+DirectorySidebar.vue (设置面板)
+ │
+ ├── :display-mode="displayMode"
+ └── @toggle-display-mode="onToggleDisplayMode"
+ → displayMode 切换 + localStorage 持久化
+
+MarkdownEditor.vue
+ │
+ ├── split 模式: 与 App.vue 双向绑定,实时渲染预览
+ └── wysiwyg 模式: 解析 → 块 → 点击编辑 → 局部替换 → emit
+```
+
+## 性能考量
+
+- **unified processor** 在组件 setup 时创建一次,全局复用
+- **parseBlocks** 每次 modelValue 变化时调用,包含 N 次 `processSync`(N = 块数)
+ - 典型文档(50 块)约需 50-100ms,在可接受范围内
+ - 后续可优化为增量更新(只重新渲染变化的块)
+- **textarea auto-resize** 通过 `scrollHeight` 动态调整高度,无额外 DOM 操作
+- **双栏滚动同步** 使用比例计算,避免频繁的绝对位置计算
+
+## 样式体系
+
+| 层级 | 设计 |
+|---|---|
+| 容器 | `border-[#e0dbcf]` 暖米色边框,`shadow-2xl` 阴影,`bg-white` |
+| 文字 | `text-[#38342e]` 深棕色,`font-serif` |
+| 标题 | `text-[#2d2a26]` 更深,`font-weight: 700` |
+| 链接 | `text-[#bf6a3b]` 暖橙色,`underline` |
+| 行内代码 | `bg-[#f4f1ea]` 暖灰底,`text-[#bf6a3b]` |
+| 引用 | 左边框 `4px solid #bf6a3b`,斜体灰色 |
+| 表格 | 斑马条纹 `bg-[#faf9f6]`,表头 `bg-[#f4f1ea]` |
+| 块 hover | `bg-[#faf9f6]` 微暖灰,提示可点击 |
+| 编辑 textarea | `bg-[#faf9f6]`,`border-[#bf6a3b]`,`font-mono` |
+| 缩放 | `calc(1rem * var(--editor-zoom, 1))` CSS 变量,由 App.vue 的 Ctrl+滚轮 控制 |
diff --git a/package.json b/package.json
index 9847fc6..233885f 100644
--- a/package.json
+++ b/package.json
@@ -10,16 +10,16 @@
"tauri": "tauri"
},
"dependencies": {
- "@codemirror/commands": "^6.10.4",
- "@codemirror/lang-markdown": "^6.5.0",
- "@codemirror/language": "^6.12.4",
- "@codemirror/state": "^6.7.0",
- "@codemirror/view": "^6.43.4",
"@tauri-apps/api": "^2",
"@tauri-apps/plugin-dialog": "^2.7.1",
"@tauri-apps/plugin-opener": "^2",
- "codemirror": "^6.0.2",
+ "rehype-sanitize": "^6.0.0",
+ "rehype-stringify": "^10.0.1",
+ "remark-gfm": "^4.0.1",
+ "remark-parse": "^11.0.0",
+ "remark-rehype": "^11.1.2",
"remixicon": "^4.9.1",
+ "unified": "^11.0.0",
"vue": "^3.5.13"
},
"devDependencies": {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 317b148..712961f 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -8,21 +8,6 @@ importers:
.:
dependencies:
- '@codemirror/commands':
- specifier: ^6.10.4
- version: 6.10.4
- '@codemirror/lang-markdown':
- specifier: ^6.5.0
- version: 6.5.0
- '@codemirror/language':
- specifier: ^6.12.4
- version: 6.12.4
- '@codemirror/state':
- specifier: ^6.7.0
- version: 6.7.0
- '@codemirror/view':
- specifier: ^6.43.4
- version: 6.43.4
'@tauri-apps/api':
specifier: ^2
version: 2.11.1
@@ -32,12 +17,27 @@ importers:
'@tauri-apps/plugin-opener':
specifier: ^2
version: 2.5.4
- codemirror:
- specifier: ^6.0.2
- version: 6.0.2
+ rehype-sanitize:
+ specifier: ^6.0.0
+ version: 6.0.0
+ rehype-stringify:
+ specifier: ^10.0.1
+ version: 10.0.1
+ remark-gfm:
+ specifier: ^4.0.1
+ version: 4.0.1
+ remark-parse:
+ specifier: ^11.0.0
+ version: 11.0.0
+ remark-rehype:
+ specifier: ^11.1.2
+ version: 11.1.2
remixicon:
specifier: ^4.9.1
version: 4.9.1
+ unified:
+ specifier: ^11.0.0
+ version: 11.0.0
vue:
specifier: ^3.5.13
version: 3.5.39(typescript@5.6.3)
@@ -83,39 +83,6 @@ packages:
resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==}
engines: {node: '>=6.9.0'}
- '@codemirror/autocomplete@6.20.3':
- resolution: {integrity: sha512-tlosUqb+3BbxCxZdu4tKeRghPFC+QM7q4X5YhKV2eCmPG+1r2F3f4AaSz5sCrFqUtX4Jh20VFTKecl16MgiV9g==}
-
- '@codemirror/commands@6.10.4':
- resolution: {integrity: sha512-Ryk9y9T0FFVF0cUGhAknveAyUOl/A1qReTFi+qPKtOh2Z9F4AUBz3XOrYD4ZEgZirdugVzHvd/2/Wcwy5OliTg==}
-
- '@codemirror/lang-css@6.3.1':
- resolution: {integrity: sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg==}
-
- '@codemirror/lang-html@6.4.11':
- resolution: {integrity: sha512-9NsXp7Nwp891pQchI7gPdTwBuSuT3K65NGTHWHNJ55HjYcHLllr0rbIZNdOzas9ztc1EUVBlHou85FFZS4BNnw==}
-
- '@codemirror/lang-javascript@6.2.5':
- resolution: {integrity: sha512-zD4e5mS+50htS7F+TYjBPsiIFGanfVqg4HyUz6WNFikgOPf2BgKlx+TQedI1w6n/IqRBVBbBWmGFdLB/7uxO4A==}
-
- '@codemirror/lang-markdown@6.5.0':
- resolution: {integrity: sha512-0K40bZ35jpHya6FriukbgaleaqzBLZfOh7HuzqbMxBXkbYMJDxfF39c23xOgxFezR+3G+tR2/Mup+Xk865OMvw==}
-
- '@codemirror/language@6.12.4':
- resolution: {integrity: sha512-1q4PaT+o6PbgpkJt4Q8Fv5XJxTy4FUZ4MWETtyiDw3J0Pyr9E2vqcKL+k9wcvjNTIsauxvE7OfmWj3FRPHQ76A==}
-
- '@codemirror/lint@6.9.7':
- resolution: {integrity: sha512-28/+iWLYxKxsvGYhSYL7zaCZqLz5+FFFDq9tVsvGv9kv8RY4fFAchJ5WX9M3YrrRlTIsECjsXPqeNgnSmNP2dg==}
-
- '@codemirror/search@6.7.1':
- resolution: {integrity: sha512-uMe5UO6PamJtSHrXhhHOzSX3ReWtiJrva6GnPMwSOrZtiExb5X5eExhr2OUZQVvdxPsKpY3Ro2mFbQadpPWmHA==}
-
- '@codemirror/state@6.7.0':
- resolution: {integrity: sha512-Zbl9NyscLMZkfXPQnNAIIAFftidrA1UbcJEIMp24C0Bukc2I5T8wJS0wsXYsnDOqCFJUeJ1BITGNs5CqPDSmSg==}
-
- '@codemirror/view@6.43.4':
- resolution: {integrity: sha512-YImu23iyKfncJzT7sRy+rEqEhSc8RhOHqDxwy4WzXRKJwYm6iwf/9OJk5ctCAdZ6yi2ZqaGEvmf55fSVqMDrgg==}
-
'@esbuild/aix-ppc64@0.25.12':
resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==}
engines: {node: '>=18'}
@@ -288,30 +255,6 @@ packages:
'@jridgewell/trace-mapping@0.3.31':
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
- '@lezer/common@1.5.2':
- resolution: {integrity: sha512-sxQE460fPZyU3sdc8lafxiPwJHBzZRy/udNFynGQky1SePYBdhkBl1kOagA9uT3pxR8K09bOrmTUqA9wb/PjSQ==}
-
- '@lezer/css@1.3.4':
- resolution: {integrity: sha512-N+tn9tej2hPvyKgHEApMOQfHczDJCwxrRFS3SPn9QjYN+uwHvEDnCgKRrb3mxDYxRS8sKMM8fhC3+lc04Abz5Q==}
-
- '@lezer/highlight@1.2.3':
- resolution: {integrity: sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g==}
-
- '@lezer/html@1.3.13':
- resolution: {integrity: sha512-oI7n6NJml729m7pjm9lvLvmXbdoMoi2f+1pwSDJkl9d68zGr7a9Btz8NdHTGQZtW2DA25ybeuv/SyDb9D5tseg==}
-
- '@lezer/javascript@1.5.4':
- resolution: {integrity: sha512-vvYx3MhWqeZtGPwDStM2dwgljd5smolYD2lR2UyFcHfxbBQebqx8yjmFmxtJ/E6nN6u1D9srOiVWm3Rb4tmcUA==}
-
- '@lezer/lr@1.4.10':
- resolution: {integrity: sha512-rnCpTIBafOx4mRp43xOxDJbFipJm/c0cia/V5TiGlhmMa+wsSdoGmUN3w5Bqrks/09Q/D4tNAmWaT8p6NRi77A==}
-
- '@lezer/markdown@1.6.4':
- resolution: {integrity: sha512-N0SxazMj4k65DBfaf1azqtMZd6u7MqluP84/NZnB/io8Td9aleFmAhz9hcbvSfsxT5tdYlJ5qgv5aMJGY4zEtA==}
-
- '@marijn/find-cluster-break@1.0.3':
- resolution: {integrity: sha512-FY+MKLBoTsLNJF/eLWaOsXGdz6uh3Iu1axjPf6TUq92IYumcTcXWHoS747JARLkcdlJ/Waiaxc5wQfFO8jC6NA==}
-
'@rollup/rollup-android-arm-eabi@4.62.2':
resolution: {integrity: sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==}
cpu: [arm]
@@ -629,9 +572,27 @@ packages:
'@tauri-apps/plugin-opener@2.5.4':
resolution: {integrity: sha512-1HnPkb+AmgO29HBazm4uPLKB+r7zzcTBW1d0fyYp1uP+jwtpoiNDGKMMzz58SFp49nOIrxdE3aUJtT57lfO9CQ==}
+ '@types/debug@4.1.13':
+ resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==}
+
'@types/estree@1.0.9':
resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==}
+ '@types/hast@3.0.4':
+ resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
+
+ '@types/mdast@4.0.4':
+ resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
+
+ '@types/ms@2.1.0':
+ resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
+
+ '@types/unist@3.0.3':
+ resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
+
+ '@ungap/structured-clone@1.3.2':
+ resolution: {integrity: sha512-5jsZFwgR5rTdKwidH9Qmat75RKwqfpKlWWB1frDkljN127mwqBu8K0PYo7/hFpF03IEJpfVPpCQDY/eDx3iHvA==}
+
'@vitejs/plugin-vue@5.2.4':
resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==}
engines: {node: ^18.0.0 || >=20.0.0}
@@ -691,17 +652,29 @@ packages:
alien-signals@1.0.13:
resolution: {integrity: sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==}
+ bail@2.0.2:
+ resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
+
balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
brace-expansion@2.1.1:
resolution: {integrity: sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==}
- codemirror@6.0.2:
- resolution: {integrity: sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==}
+ ccount@2.0.1:
+ resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
- crelt@1.0.7:
- resolution: {integrity: sha512-aK6BbWfhf4U/wCcLHKPJl/xa6VkVstRaPywWtMKGwuOLc/wZTyQYuoxgvZnNsBvv7Kg3YTBQYYBCggcviQczuA==}
+ character-entities-html4@2.1.0:
+ resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
+
+ character-entities-legacy@3.0.0:
+ resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==}
+
+ character-entities@2.0.2:
+ resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==}
+
+ comma-separated-tokens@2.0.3:
+ resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
csstype@3.2.3:
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
@@ -709,10 +682,29 @@ packages:
de-indent@1.0.2:
resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
+ debug@4.4.3:
+ resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ decode-named-character-reference@1.3.0:
+ resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==}
+
+ dequal@2.0.3:
+ resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
+ engines: {node: '>=6'}
+
detect-libc@2.1.2:
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
engines: {node: '>=8'}
+ devlop@1.1.0:
+ resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
+
enhanced-resolve@5.21.6:
resolution: {integrity: sha512-aNnGCvbJ/RIyWo1IuhNdVjnNF+EjH9wpzpNHt+ci/m9He9LJvUN8wrCcXjp9cWsGNAuvSpVFTx/vraAFQ8qGjQ==}
engines: {node: '>=10.13.0'}
@@ -726,6 +718,10 @@ packages:
engines: {node: '>=18'}
hasBin: true
+ escape-string-regexp@5.0.0:
+ resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
+ engines: {node: '>=12'}
+
estree-walker@2.0.2:
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
@@ -746,10 +742,26 @@ packages:
graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+ hast-util-sanitize@5.0.2:
+ resolution: {integrity: sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==}
+
+ hast-util-to-html@9.0.5:
+ resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==}
+
+ hast-util-whitespace@3.0.0:
+ resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
+
he@1.2.0:
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
hasBin: true
+ html-void-elements@3.0.0:
+ resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
+
+ is-plain-obj@4.1.0:
+ resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
+ engines: {node: '>=12'}
+
jiti@2.7.0:
resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==}
hasBin: true
@@ -828,13 +840,142 @@ packages:
resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==}
engines: {node: '>= 12.0.0'}
+ longest-streak@3.1.0:
+ resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
+
magic-string@0.30.21:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+ markdown-table@3.0.4:
+ resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
+
+ mdast-util-find-and-replace@3.0.2:
+ resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==}
+
+ mdast-util-from-markdown@2.0.3:
+ resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==}
+
+ mdast-util-gfm-autolink-literal@2.0.1:
+ resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==}
+
+ mdast-util-gfm-footnote@2.1.0:
+ resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==}
+
+ mdast-util-gfm-strikethrough@2.0.0:
+ resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==}
+
+ mdast-util-gfm-table@2.0.0:
+ resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==}
+
+ mdast-util-gfm-task-list-item@2.0.0:
+ resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==}
+
+ mdast-util-gfm@3.1.0:
+ resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==}
+
+ mdast-util-phrasing@4.1.0:
+ resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==}
+
+ mdast-util-to-hast@13.2.1:
+ resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==}
+
+ mdast-util-to-markdown@2.0.0:
+ resolution: {integrity: sha512-Ov3aWCYpb31/SkHNRlREvSZsF9ETBW/rXw4PooawZO8qy2MviDq4TI6kxX6zFmGa/zUX36STKIC/IpASQk596w==}
+
+ mdast-util-to-string@4.0.0:
+ resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==}
+
+ micromark-core-commonmark@2.0.0:
+ resolution: {integrity: sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==}
+
+ micromark-extension-gfm-autolink-literal@2.1.0:
+ resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==}
+
+ micromark-extension-gfm-footnote@2.1.0:
+ resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==}
+
+ micromark-extension-gfm-strikethrough@2.1.0:
+ resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==}
+
+ micromark-extension-gfm-table@2.1.1:
+ resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==}
+
+ micromark-extension-gfm-tagfilter@2.0.0:
+ resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==}
+
+ micromark-extension-gfm-task-list-item@2.1.0:
+ resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==}
+
+ micromark-extension-gfm@3.0.0:
+ resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==}
+
+ micromark-factory-destination@2.0.0:
+ resolution: {integrity: sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==}
+
+ micromark-factory-label@2.0.0:
+ resolution: {integrity: sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==}
+
+ micromark-factory-space@2.0.0:
+ resolution: {integrity: sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==}
+
+ micromark-factory-title@2.0.0:
+ resolution: {integrity: sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==}
+
+ micromark-factory-whitespace@2.0.0:
+ resolution: {integrity: sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==}
+
+ micromark-util-character@2.0.0:
+ resolution: {integrity: sha512-DtHHqgTRz32ylwiGSZwoK+BTx4gaq//ig71g20pwBwRLxo3CfInyD+NyTrriLOhPz5WQOfAOSLLbKOaaGXWz9Q==}
+
+ micromark-util-chunked@2.0.0:
+ resolution: {integrity: sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==}
+
+ micromark-util-classify-character@2.0.0:
+ resolution: {integrity: sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==}
+
+ micromark-util-combine-extensions@2.0.0:
+ resolution: {integrity: sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==}
+
+ micromark-util-decode-numeric-character-reference@2.0.0:
+ resolution: {integrity: sha512-pIgcsGxpHEtTG/rPJRz/HOLSqp5VTuIIjXlPI+6JSDlK2oljApusG6KzpS8AF0ENUMCHlC/IBb5B9xdFiVlm5Q==}
+
+ micromark-util-decode-string@2.0.1:
+ resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==}
+
+ micromark-util-encode@2.0.0:
+ resolution: {integrity: sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==}
+
+ micromark-util-html-tag-name@2.0.0:
+ resolution: {integrity: sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==}
+
+ micromark-util-normalize-identifier@2.0.0:
+ resolution: {integrity: sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==}
+
+ micromark-util-resolve-all@2.0.0:
+ resolution: {integrity: sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==}
+
+ micromark-util-sanitize-uri@2.0.0:
+ resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==}
+
+ micromark-util-subtokenize@2.0.0:
+ resolution: {integrity: sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==}
+
+ micromark-util-symbol@2.0.0:
+ resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==}
+
+ micromark-util-types@2.0.0:
+ resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==}
+
+ micromark@4.0.0:
+ resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==}
+
minimatch@9.0.9:
resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==}
engines: {node: '>=16 || 14 >=14.17'}
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
muggle-string@0.4.1:
resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==}
@@ -857,6 +998,27 @@ packages:
resolution: {integrity: sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==}
engines: {node: ^10 || ^12 || >=14}
+ property-information@7.2.0:
+ resolution: {integrity: sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==}
+
+ rehype-sanitize@6.0.0:
+ resolution: {integrity: sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg==}
+
+ rehype-stringify@10.0.1:
+ resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==}
+
+ remark-gfm@4.0.1:
+ resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==}
+
+ remark-parse@11.0.0:
+ resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==}
+
+ remark-rehype@11.1.2:
+ resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==}
+
+ remark-stringify@11.0.0:
+ resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
+
remixicon@4.9.1:
resolution: {integrity: sha512-36gLSoujkabnCFZFDyP17VNh9piuBA/rsXUb4auSJWLGsHVXtmxLj/EM5FjaEAGnk8oIAj1Azob/DZ2N+90lAQ==}
@@ -869,8 +1031,11 @@ packages:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
- style-mod@4.1.3:
- resolution: {integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==}
+ space-separated-tokens@2.0.2:
+ resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
+
+ stringify-entities@4.0.4:
+ resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==}
tailwindcss@4.3.2:
resolution: {integrity: sha512-WtctNNSH8A9jlMIqxzuYumOHU5uGZyRv0Q5svQl+oEPy5w84YpBxdb7MdqyiSPQge5jTJ6zFQLq0PFygdccSBA==}
@@ -883,11 +1048,41 @@ packages:
resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==}
engines: {node: '>=12.0.0'}
+ trim-lines@3.0.1:
+ resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
+
+ trough@2.2.0:
+ resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==}
+
typescript@5.6.3:
resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==}
engines: {node: '>=14.17'}
hasBin: true
+ unified@11.0.0:
+ resolution: {integrity: sha512-65zgPyv0vyXnJpw4fbGmoXjP0/6cBmnnesl4lSPGU2tYuzLWtuicRBFcaV6kgzitGrBHj6pgXYomMw1VQe/cQg==}
+
+ unist-util-is@6.0.1:
+ resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==}
+
+ unist-util-position@5.0.0:
+ resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==}
+
+ unist-util-stringify-position@4.0.0:
+ resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==}
+
+ unist-util-visit-parents@6.0.2:
+ resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==}
+
+ unist-util-visit@5.1.0:
+ resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==}
+
+ vfile-message@4.0.3:
+ resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==}
+
+ vfile@6.0.3:
+ resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
+
vite@6.4.3:
resolution: {integrity: sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
@@ -945,8 +1140,8 @@ packages:
typescript:
optional: true
- w3c-keyname@2.2.8:
- resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==}
+ zwitch@2.0.4:
+ resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
snapshots:
@@ -963,92 +1158,6 @@ snapshots:
'@babel/helper-string-parser': 7.29.7
'@babel/helper-validator-identifier': 7.29.7
- '@codemirror/autocomplete@6.20.3':
- dependencies:
- '@codemirror/language': 6.12.4
- '@codemirror/state': 6.7.0
- '@codemirror/view': 6.43.4
- '@lezer/common': 1.5.2
-
- '@codemirror/commands@6.10.4':
- dependencies:
- '@codemirror/language': 6.12.4
- '@codemirror/state': 6.7.0
- '@codemirror/view': 6.43.4
- '@lezer/common': 1.5.2
-
- '@codemirror/lang-css@6.3.1':
- dependencies:
- '@codemirror/autocomplete': 6.20.3
- '@codemirror/language': 6.12.4
- '@codemirror/state': 6.7.0
- '@lezer/common': 1.5.2
- '@lezer/css': 1.3.4
-
- '@codemirror/lang-html@6.4.11':
- dependencies:
- '@codemirror/autocomplete': 6.20.3
- '@codemirror/lang-css': 6.3.1
- '@codemirror/lang-javascript': 6.2.5
- '@codemirror/language': 6.12.4
- '@codemirror/state': 6.7.0
- '@codemirror/view': 6.43.4
- '@lezer/common': 1.5.2
- '@lezer/css': 1.3.4
- '@lezer/html': 1.3.13
-
- '@codemirror/lang-javascript@6.2.5':
- dependencies:
- '@codemirror/autocomplete': 6.20.3
- '@codemirror/language': 6.12.4
- '@codemirror/lint': 6.9.7
- '@codemirror/state': 6.7.0
- '@codemirror/view': 6.43.4
- '@lezer/common': 1.5.2
- '@lezer/javascript': 1.5.4
-
- '@codemirror/lang-markdown@6.5.0':
- dependencies:
- '@codemirror/autocomplete': 6.20.3
- '@codemirror/lang-html': 6.4.11
- '@codemirror/language': 6.12.4
- '@codemirror/state': 6.7.0
- '@codemirror/view': 6.43.4
- '@lezer/common': 1.5.2
- '@lezer/markdown': 1.6.4
-
- '@codemirror/language@6.12.4':
- dependencies:
- '@codemirror/state': 6.7.0
- '@codemirror/view': 6.43.4
- '@lezer/common': 1.5.2
- '@lezer/highlight': 1.2.3
- '@lezer/lr': 1.4.10
- style-mod: 4.1.3
-
- '@codemirror/lint@6.9.7':
- dependencies:
- '@codemirror/state': 6.7.0
- '@codemirror/view': 6.43.4
- crelt: 1.0.7
-
- '@codemirror/search@6.7.1':
- dependencies:
- '@codemirror/state': 6.7.0
- '@codemirror/view': 6.43.4
- crelt: 1.0.7
-
- '@codemirror/state@6.7.0':
- dependencies:
- '@marijn/find-cluster-break': 1.0.3
-
- '@codemirror/view@6.43.4':
- dependencies:
- '@codemirror/state': 6.7.0
- crelt: 1.0.7
- style-mod: 4.1.3
- w3c-keyname: 2.2.8
-
'@esbuild/aix-ppc64@0.25.12':
optional: true
@@ -1146,41 +1255,6 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.5
- '@lezer/common@1.5.2': {}
-
- '@lezer/css@1.3.4':
- dependencies:
- '@lezer/common': 1.5.2
- '@lezer/highlight': 1.2.3
- '@lezer/lr': 1.4.10
-
- '@lezer/highlight@1.2.3':
- dependencies:
- '@lezer/common': 1.5.2
-
- '@lezer/html@1.3.13':
- dependencies:
- '@lezer/common': 1.5.2
- '@lezer/highlight': 1.2.3
- '@lezer/lr': 1.4.10
-
- '@lezer/javascript@1.5.4':
- dependencies:
- '@lezer/common': 1.5.2
- '@lezer/highlight': 1.2.3
- '@lezer/lr': 1.4.10
-
- '@lezer/lr@1.4.10':
- dependencies:
- '@lezer/common': 1.5.2
-
- '@lezer/markdown@1.6.4':
- dependencies:
- '@lezer/common': 1.5.2
- '@lezer/highlight': 1.2.3
-
- '@marijn/find-cluster-break@1.0.3': {}
-
'@rollup/rollup-android-arm-eabi@4.62.2':
optional: true
@@ -1381,8 +1455,26 @@ snapshots:
dependencies:
'@tauri-apps/api': 2.11.1
+ '@types/debug@4.1.13':
+ dependencies:
+ '@types/ms': 2.1.0
+
'@types/estree@1.0.9': {}
+ '@types/hast@3.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/mdast@4.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/ms@2.1.0': {}
+
+ '@types/unist@3.0.3': {}
+
+ '@ungap/structured-clone@1.3.2': {}
+
'@vitejs/plugin-vue@5.2.4(vite@6.4.3(jiti@2.7.0)(lightningcss@1.32.0))(vue@3.5.39(typescript@5.6.3))':
dependencies:
vite: 6.4.3(jiti@2.7.0)(lightningcss@1.32.0)
@@ -1474,30 +1566,44 @@ snapshots:
alien-signals@1.0.13: {}
+ bail@2.0.2: {}
+
balanced-match@1.0.2: {}
brace-expansion@2.1.1:
dependencies:
balanced-match: 1.0.2
- codemirror@6.0.2:
- dependencies:
- '@codemirror/autocomplete': 6.20.3
- '@codemirror/commands': 6.10.4
- '@codemirror/language': 6.12.4
- '@codemirror/lint': 6.9.7
- '@codemirror/search': 6.7.1
- '@codemirror/state': 6.7.0
- '@codemirror/view': 6.43.4
+ ccount@2.0.1: {}
- crelt@1.0.7: {}
+ character-entities-html4@2.1.0: {}
+
+ character-entities-legacy@3.0.0: {}
+
+ character-entities@2.0.2: {}
+
+ comma-separated-tokens@2.0.3: {}
csstype@3.2.3: {}
de-indent@1.0.2: {}
+ debug@4.4.3:
+ dependencies:
+ ms: 2.1.3
+
+ decode-named-character-reference@1.3.0:
+ dependencies:
+ character-entities: 2.0.2
+
+ dequal@2.0.3: {}
+
detect-libc@2.1.2: {}
+ devlop@1.1.0:
+ dependencies:
+ dequal: 2.0.3
+
enhanced-resolve@5.21.6:
dependencies:
graceful-fs: 4.2.11
@@ -1534,6 +1640,8 @@ snapshots:
'@esbuild/win32-ia32': 0.25.12
'@esbuild/win32-x64': 0.25.12
+ escape-string-regexp@5.0.0: {}
+
estree-walker@2.0.2: {}
fdir@6.5.0(picomatch@4.0.4):
@@ -1545,8 +1653,36 @@ snapshots:
graceful-fs@4.2.11: {}
+ hast-util-sanitize@5.0.2:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@ungap/structured-clone': 1.3.2
+ unist-util-position: 5.0.0
+
+ hast-util-to-html@9.0.5:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ ccount: 2.0.1
+ comma-separated-tokens: 2.0.3
+ hast-util-whitespace: 3.0.0
+ html-void-elements: 3.0.0
+ mdast-util-to-hast: 13.2.1
+ property-information: 7.2.0
+ space-separated-tokens: 2.0.2
+ stringify-entities: 4.0.4
+ zwitch: 2.0.4
+
+ hast-util-whitespace@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+
he@1.2.0: {}
+ html-void-elements@3.0.0: {}
+
+ is-plain-obj@4.1.0: {}
+
jiti@2.7.0: {}
lightningcss-android-arm64@1.32.0:
@@ -1598,14 +1734,324 @@ snapshots:
lightningcss-win32-arm64-msvc: 1.32.0
lightningcss-win32-x64-msvc: 1.32.0
+ longest-streak@3.1.0: {}
+
magic-string@0.30.21:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
+ markdown-table@3.0.4: {}
+
+ mdast-util-find-and-replace@3.0.2:
+ dependencies:
+ '@types/mdast': 4.0.4
+ escape-string-regexp: 5.0.0
+ unist-util-is: 6.0.1
+ unist-util-visit-parents: 6.0.2
+
+ mdast-util-from-markdown@2.0.3:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ decode-named-character-reference: 1.3.0
+ devlop: 1.1.0
+ mdast-util-to-string: 4.0.0
+ micromark: 4.0.0
+ micromark-util-decode-numeric-character-reference: 2.0.0
+ micromark-util-decode-string: 2.0.1
+ micromark-util-normalize-identifier: 2.0.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+ unist-util-stringify-position: 4.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-autolink-literal@2.0.1:
+ dependencies:
+ '@types/mdast': 4.0.4
+ ccount: 2.0.1
+ devlop: 1.1.0
+ mdast-util-find-and-replace: 3.0.2
+ micromark-util-character: 2.0.0
+
+ mdast-util-gfm-footnote@2.1.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.3
+ mdast-util-to-markdown: 2.0.0
+ micromark-util-normalize-identifier: 2.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-strikethrough@2.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-from-markdown: 2.0.3
+ mdast-util-to-markdown: 2.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-table@2.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ markdown-table: 3.0.4
+ mdast-util-from-markdown: 2.0.3
+ mdast-util-to-markdown: 2.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-task-list-item@2.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.3
+ mdast-util-to-markdown: 2.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm@3.1.0:
+ dependencies:
+ mdast-util-from-markdown: 2.0.3
+ mdast-util-gfm-autolink-literal: 2.0.1
+ mdast-util-gfm-footnote: 2.1.0
+ mdast-util-gfm-strikethrough: 2.0.0
+ mdast-util-gfm-table: 2.0.0
+ mdast-util-gfm-task-list-item: 2.0.0
+ mdast-util-to-markdown: 2.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-phrasing@4.1.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ unist-util-is: 6.0.1
+
+ mdast-util-to-hast@13.2.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ '@ungap/structured-clone': 1.3.2
+ devlop: 1.1.0
+ micromark-util-sanitize-uri: 2.0.0
+ trim-lines: 3.0.1
+ unist-util-position: 5.0.0
+ unist-util-visit: 5.1.0
+ vfile: 6.0.3
+
+ mdast-util-to-markdown@2.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ longest-streak: 3.1.0
+ mdast-util-phrasing: 4.1.0
+ mdast-util-to-string: 4.0.0
+ micromark-util-decode-string: 2.0.1
+ unist-util-visit: 5.1.0
+ zwitch: 2.0.4
+
+ mdast-util-to-string@4.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+
+ micromark-core-commonmark@2.0.0:
+ dependencies:
+ decode-named-character-reference: 1.3.0
+ devlop: 1.1.0
+ micromark-factory-destination: 2.0.0
+ micromark-factory-label: 2.0.0
+ micromark-factory-space: 2.0.0
+ micromark-factory-title: 2.0.0
+ micromark-factory-whitespace: 2.0.0
+ micromark-util-character: 2.0.0
+ micromark-util-chunked: 2.0.0
+ micromark-util-classify-character: 2.0.0
+ micromark-util-html-tag-name: 2.0.0
+ micromark-util-normalize-identifier: 2.0.0
+ micromark-util-resolve-all: 2.0.0
+ micromark-util-subtokenize: 2.0.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-extension-gfm-autolink-literal@2.1.0:
+ dependencies:
+ micromark-util-character: 2.0.0
+ micromark-util-sanitize-uri: 2.0.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-extension-gfm-footnote@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-core-commonmark: 2.0.0
+ micromark-factory-space: 2.0.0
+ micromark-util-character: 2.0.0
+ micromark-util-normalize-identifier: 2.0.0
+ micromark-util-sanitize-uri: 2.0.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-extension-gfm-strikethrough@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-chunked: 2.0.0
+ micromark-util-classify-character: 2.0.0
+ micromark-util-resolve-all: 2.0.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-extension-gfm-table@2.1.1:
+ dependencies:
+ devlop: 1.1.0
+ micromark-factory-space: 2.0.0
+ micromark-util-character: 2.0.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-extension-gfm-tagfilter@2.0.0:
+ dependencies:
+ micromark-util-types: 2.0.0
+
+ micromark-extension-gfm-task-list-item@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-factory-space: 2.0.0
+ micromark-util-character: 2.0.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-extension-gfm@3.0.0:
+ dependencies:
+ micromark-extension-gfm-autolink-literal: 2.1.0
+ micromark-extension-gfm-footnote: 2.1.0
+ micromark-extension-gfm-strikethrough: 2.1.0
+ micromark-extension-gfm-table: 2.1.1
+ micromark-extension-gfm-tagfilter: 2.0.0
+ micromark-extension-gfm-task-list-item: 2.1.0
+ micromark-util-combine-extensions: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-factory-destination@2.0.0:
+ dependencies:
+ micromark-util-character: 2.0.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-factory-label@2.0.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-character: 2.0.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-factory-space@2.0.0:
+ dependencies:
+ micromark-util-character: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-factory-title@2.0.0:
+ dependencies:
+ micromark-factory-space: 2.0.0
+ micromark-util-character: 2.0.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-factory-whitespace@2.0.0:
+ dependencies:
+ micromark-factory-space: 2.0.0
+ micromark-util-character: 2.0.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-util-character@2.0.0:
+ dependencies:
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-util-chunked@2.0.0:
+ dependencies:
+ micromark-util-symbol: 2.0.0
+
+ micromark-util-classify-character@2.0.0:
+ dependencies:
+ micromark-util-character: 2.0.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-util-combine-extensions@2.0.0:
+ dependencies:
+ micromark-util-chunked: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-util-decode-numeric-character-reference@2.0.0:
+ dependencies:
+ micromark-util-symbol: 2.0.0
+
+ micromark-util-decode-string@2.0.1:
+ dependencies:
+ decode-named-character-reference: 1.3.0
+ micromark-util-character: 2.0.0
+ micromark-util-decode-numeric-character-reference: 2.0.0
+ micromark-util-symbol: 2.0.0
+
+ micromark-util-encode@2.0.0: {}
+
+ micromark-util-html-tag-name@2.0.0: {}
+
+ micromark-util-normalize-identifier@2.0.0:
+ dependencies:
+ micromark-util-symbol: 2.0.0
+
+ micromark-util-resolve-all@2.0.0:
+ dependencies:
+ micromark-util-types: 2.0.0
+
+ micromark-util-sanitize-uri@2.0.0:
+ dependencies:
+ micromark-util-character: 2.0.0
+ micromark-util-encode: 2.0.0
+ micromark-util-symbol: 2.0.0
+
+ micromark-util-subtokenize@2.0.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-chunked: 2.0.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-util-symbol@2.0.0: {}
+
+ micromark-util-types@2.0.0: {}
+
+ micromark@4.0.0:
+ dependencies:
+ '@types/debug': 4.1.13
+ debug: 4.4.3
+ decode-named-character-reference: 1.3.0
+ devlop: 1.1.0
+ micromark-core-commonmark: 2.0.0
+ micromark-factory-space: 2.0.0
+ micromark-util-character: 2.0.0
+ micromark-util-chunked: 2.0.0
+ micromark-util-combine-extensions: 2.0.0
+ micromark-util-decode-numeric-character-reference: 2.0.0
+ micromark-util-encode: 2.0.0
+ micromark-util-normalize-identifier: 2.0.0
+ micromark-util-resolve-all: 2.0.0
+ micromark-util-sanitize-uri: 2.0.0
+ micromark-util-subtokenize: 2.0.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+ transitivePeerDependencies:
+ - supports-color
+
minimatch@9.0.9:
dependencies:
brace-expansion: 2.1.1
+ ms@2.1.3: {}
+
muggle-string@0.4.1: {}
nanoid@3.3.15: {}
@@ -1622,6 +2068,53 @@ snapshots:
picocolors: 1.1.1
source-map-js: 1.2.1
+ property-information@7.2.0: {}
+
+ rehype-sanitize@6.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-sanitize: 5.0.2
+
+ rehype-stringify@10.0.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-to-html: 9.0.5
+ unified: 11.0.0
+
+ remark-gfm@4.0.1:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-gfm: 3.1.0
+ micromark-extension-gfm: 3.0.0
+ remark-parse: 11.0.0
+ remark-stringify: 11.0.0
+ unified: 11.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ remark-parse@11.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-from-markdown: 2.0.3
+ micromark-util-types: 2.0.0
+ unified: 11.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ remark-rehype@11.1.2:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ mdast-util-to-hast: 13.2.1
+ unified: 11.0.0
+ vfile: 6.0.3
+
+ remark-stringify@11.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-to-markdown: 2.0.0
+ unified: 11.0.0
+
remixicon@4.9.1: {}
rollup@4.62.2:
@@ -1657,7 +2150,12 @@ snapshots:
source-map-js@1.2.1: {}
- style-mod@4.1.3: {}
+ space-separated-tokens@2.0.2: {}
+
+ stringify-entities@4.0.4:
+ dependencies:
+ character-entities-html4: 2.1.0
+ character-entities-legacy: 3.0.0
tailwindcss@4.3.2: {}
@@ -1668,8 +2166,55 @@ snapshots:
fdir: 6.5.0(picomatch@4.0.4)
picomatch: 4.0.4
+ trim-lines@3.0.1: {}
+
+ trough@2.2.0: {}
+
typescript@5.6.3: {}
+ unified@11.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ '@ungap/structured-clone': 1.3.2
+ bail: 2.0.2
+ devlop: 1.1.0
+ is-plain-obj: 4.1.0
+ trough: 2.2.0
+ vfile: 6.0.3
+
+ unist-util-is@6.0.1:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-position@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-stringify-position@4.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-visit-parents@6.0.2:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.1
+
+ unist-util-visit@5.1.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.1
+ unist-util-visit-parents: 6.0.2
+
+ vfile-message@4.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-stringify-position: 4.0.0
+
+ vfile@6.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ vfile-message: 4.0.3
+
vite@6.4.3(jiti@2.7.0)(lightningcss@1.32.0):
dependencies:
esbuild: 0.25.12
@@ -1701,4 +2246,4 @@ snapshots:
optionalDependencies:
typescript: 5.6.3
- w3c-keyname@2.2.8: {}
+ zwitch@2.0.4: {}
diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json
index 004833c..9ae2dd6 100644
--- a/src-tauri/tauri.conf.json
+++ b/src-tauri/tauri.conf.json
@@ -26,7 +26,7 @@
},
"bundle": {
"active": true,
- "targets": "all",
+ "targets": ["nsis"],
"icon": [
"icons/32x32.png",
"icons/128x128.png",
diff --git a/src/App.vue b/src/App.vue
index a922c74..820680e 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -79,6 +79,23 @@ function onToggleFullWidth(val: boolean) {
try { localStorage.setItem("editor-full-width", String(val)); } catch { /* noop */ }
}
+// ---- display mode (split / wysiwyg) ----
+type DisplayMode = "split" | "wysiwyg";
+
+function loadDisplayModePref(): DisplayMode {
+ try {
+ const v = localStorage.getItem("editor-display-mode");
+ if (v === "split" || v === "wysiwyg") return v;
+ } catch { /* noop */ }
+ return "split";
+}
+const displayMode = ref(loadDisplayModePref());
+
+function onToggleDisplayMode(val: DisplayMode) {
+ displayMode.value = val;
+ try { localStorage.setItem("editor-display-mode", val); } catch { /* noop */ }
+}
+
onMounted(() => {
applyZoomCssVars();
window.addEventListener("wheel", onEditorWheel, { passive: false });
@@ -121,9 +138,8 @@ function onUpdate(md: string) {
}
function onHeadingClick(heading: { text: string; level: number }) {
- // Navigate to heading in the CodeMirror editor
- const className = `.cm-lp-h${heading.level}`;
- const headingEls = document.querySelectorAll(className);
+ const selector = `.markdown-preview h${heading.level}`;
+ const headingEls = document.querySelectorAll(selector);
for (const el of headingEls) {
if (el.textContent?.trim() === heading.text) {
el.scrollIntoView({ behavior: "smooth", block: "start" });
@@ -267,11 +283,13 @@ listen("menu-event", (event) => {
:content="content"
:current-file-path="currentFilePath"
:is-full-width="isFullWidth"
+ :display-mode="displayMode"
@heading-click="onHeadingClick"
@open-folder="onOpenFolder"
@toggle-folder="onToggleFolder"
@open-file="onOpenFile"
@toggle-full-width="onToggleFullWidth"
+ @toggle-display-mode="onToggleDisplayMode"
/>
@@ -279,6 +297,7 @@ listen("menu-event", (event) => {
(),
{
content: "",
currentFilePath: null,
isFullWidth: false,
+ displayMode: "split",
},
);
@@ -32,6 +34,7 @@ const emit = defineEmits<{
createFile: [];
createFolder: [];
toggleFullWidth: [value: boolean];
+ toggleDisplayMode: [value: "split" | "wysiwyg"];
}>();
// Wrap the workspace root as a top-level tree node
@@ -248,6 +251,33 @@ const showSettings = ref(false);
+
+
+
+
编辑模式
+
+ {{ props.displayMode === "wysiwyg" ? "单栏:所见即所得,预览区直接编辑" : "双栏:左侧编辑源码,右侧预览效果" }}
+
+
+
+
+
diff --git a/src/components/MarkdownEditor.vue b/src/components/MarkdownEditor.vue
index a0cfa62..90f8bcc 100644
--- a/src/components/MarkdownEditor.vue
+++ b/src/components/MarkdownEditor.vue
@@ -1,25 +1,24 @@
-
+
+
+
+
+ {{ props.placeholder }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ⚠ Markdown 解析错误
+
+
+
+
+
+
diff --git a/src/editor/livePreview.ts b/src/editor/livePreview.ts
deleted file mode 100644
index 3248952..0000000
--- a/src/editor/livePreview.ts
+++ /dev/null
@@ -1,377 +0,0 @@
-import {
- ViewPlugin,
- ViewUpdate,
- Decoration,
- DecorationSet,
- EditorView,
-} from "@codemirror/view";
-import type { Range } from "@codemirror/state";
-
-// ── Types ──────────────────────────────────────────────────────────
-
-interface HideRange {
- /** start of whole construct (e.g. first `*` of `**bold**`) */
- from: number;
- /** end of whole construct */
- to: number;
- /** ranges of syntax chars to hide ([from, to] pairs) */
- markers: [number, number][];
- /** optional: range of styled content to apply[0=from, 1=to, 2=css class] */
- content?: [number, number, string];
-}
-
-// ── CSS classes ────────────────────────────────────────────────────
-
-// (no longer needed — Decoration.replace handles hiding directly)
-
-// ── Decoration builders ────────────────────────────────────────────
-
-const hiddenMark = Decoration.replace({});
-
-function contentMark(cls: string) {
- return Decoration.mark({ class: cls });
-}
-
-// ── Regex patterns ─────────────────────────────────────────────────
-
-// Block-level: detect headings, blockquotes, list items, hr, fenced code
-const RE_HEADING = /^(#{1,6})\s+(.*)$/;
-const RE_BLOCKQUOTE = /^(>\s*)(.*)$/;
-const RE_UNORDERED = /^(\s*[-*+]\s*)(.*)$/;
-const RE_ORDERED = /^(\s*\d+\.\s*)(.*)$/;
-const RE_HR = /^[-*_]{3,}\s*$/;
-const RE_CODE_FENCE = /^```/;
-
-// Inline: bold, italic, strikethrough, code, link, image
-// These run on non-code-block content after stripping block markers
-
-// We parse inline elements by scanning left-to-right within each line.
-// Using a combined pattern that matches the FIRST occurrence:
-const RE_INLINE = /(\*\*|__)(.+?)\1|(?[] = [];
-
- for (const region of regions) {
- // If the selection overlaps with this region, reveal it (show raw markdown)
- if (selFrom < region.to && selTo > region.from) {
- continue;
- }
-
- // Hide all marker ranges
- for (const [mFrom, mTo] of region.markers) {
- if (mFrom < mTo) {
- decos.push(hiddenMark.range(mFrom, mTo));
- }
- }
-
- // Apply content styling
- if (region.content) {
- const [cFrom, cTo, cssClass] = region.content;
- if (cFrom < cTo) {
- decos.push(contentMark(cssClass).range(cFrom, cTo));
- }
- }
- }
-
- return Decoration.set(decos, true);
-}
-
-// ── ViewPlugin ─────────────────────────────────────────────────────
-
-class LivePreviewPlugin {
- decorations: DecorationSet;
-
- constructor(view: EditorView) {
- this.decorations = this.compute(view);
- }
-
- update(update: ViewUpdate) {
- if (update.docChanged || update.selectionSet) {
- this.decorations = this.compute(update.view);
- }
- }
-
- private compute(view: EditorView): DecorationSet {
- const text = view.state.doc.toString();
- const sel = view.state.selection.main;
- const regions = parseDocument(text);
- return buildDecorationSet(regions, sel.from, sel.to);
- }
-}
-
-export function livePreview() {
- return ViewPlugin.fromClass(LivePreviewPlugin, {
- decorations: (v) => v.decorations,
- });
-}