dsh-vscode-mode 0.1.54 → 0.1.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/assets/vendor/pdfjs/build/pdf.mjs +26370 -0
- package/assets/vendor/pdfjs/build/pdf.worker.mjs +61080 -0
- package/assets/vendor/pdfjs/cmaps/78-EUC-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/78-EUC-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/78-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/78-RKSJ-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/78-RKSJ-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/78-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/78ms-RKSJ-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/78ms-RKSJ-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/83pv-RKSJ-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/90ms-RKSJ-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/90ms-RKSJ-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/90msp-RKSJ-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/90msp-RKSJ-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/90pv-RKSJ-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/90pv-RKSJ-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Add-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Add-RKSJ-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Add-RKSJ-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Add-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-CNS1-0.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-CNS1-1.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-CNS1-2.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-CNS1-3.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-CNS1-4.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-CNS1-5.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-CNS1-6.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-GB1-0.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-GB1-1.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-GB1-2.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-GB1-3.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-GB1-4.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-GB1-5.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-Japan1-0.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-Japan1-1.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-Japan1-2.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-Japan1-3.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-Japan1-4.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-Japan1-5.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-Japan1-6.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-Korea1-0.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-Korea1-1.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-Korea1-2.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/B5-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/B5-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/B5pc-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/B5pc-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/CNS-EUC-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/CNS-EUC-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/CNS1-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/CNS1-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/CNS2-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/CNS2-V.bcmap +3 -0
- package/assets/vendor/pdfjs/cmaps/ETHK-B5-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/ETHK-B5-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/ETen-B5-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/ETen-B5-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/ETenms-B5-H.bcmap +3 -0
- package/assets/vendor/pdfjs/cmaps/ETenms-B5-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/EUC-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/EUC-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Ext-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Ext-RKSJ-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Ext-RKSJ-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Ext-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/GB-EUC-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/GB-EUC-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/GB-H.bcmap +4 -0
- package/assets/vendor/pdfjs/cmaps/GB-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/GBK-EUC-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/GBK-EUC-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/GBK2K-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/GBK2K-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/GBKp-EUC-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/GBKp-EUC-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/GBT-EUC-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/GBT-EUC-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/GBT-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/GBT-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/GBTpc-EUC-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/GBTpc-EUC-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/GBpc-EUC-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/GBpc-EUC-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/HKdla-B5-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/HKdla-B5-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/HKdlb-B5-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/HKdlb-B5-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/HKgccs-B5-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/HKgccs-B5-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/HKm314-B5-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/HKm314-B5-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/HKm471-B5-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/HKm471-B5-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/HKscs-B5-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/HKscs-B5-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Hankaku.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Hiragana.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/KSC-EUC-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/KSC-EUC-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/KSC-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/KSC-Johab-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/KSC-Johab-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/KSC-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/KSCms-UHC-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/KSCms-UHC-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/KSCpc-EUC-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/KSCpc-EUC-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Katakana.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/LICENSE +36 -0
- package/assets/vendor/pdfjs/cmaps/NWP-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/NWP-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/RKSJ-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/RKSJ-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/Roman.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniCNS-UCS2-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniCNS-UCS2-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniCNS-UTF16-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniCNS-UTF16-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniCNS-UTF32-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniCNS-UTF32-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniCNS-UTF8-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniCNS-UTF8-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniGB-UCS2-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniGB-UCS2-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniGB-UTF16-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniGB-UTF16-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniGB-UTF32-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniGB-UTF32-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniGB-UTF8-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniGB-UTF8-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniJIS-UCS2-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniJIS-UCS2-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniJIS-UTF16-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniJIS-UTF16-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniJIS-UTF32-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniJIS-UTF32-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniJIS-UTF8-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniJIS-UTF8-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniKS-UCS2-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniKS-UCS2-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniKS-UTF16-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniKS-UTF16-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniKS-UTF32-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniKS-UTF32-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniKS-UTF8-H.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/UniKS-UTF8-V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/V.bcmap +0 -0
- package/assets/vendor/pdfjs/cmaps/WP-Symbol.bcmap +0 -0
- package/assets/vendor/pdfjs/standard_fonts/FoxitDingbats.pfb +0 -0
- package/assets/vendor/pdfjs/standard_fonts/FoxitFixed.pfb +0 -0
- package/assets/vendor/pdfjs/standard_fonts/FoxitFixedBold.pfb +0 -0
- package/assets/vendor/pdfjs/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
- package/assets/vendor/pdfjs/standard_fonts/FoxitFixedItalic.pfb +0 -0
- package/assets/vendor/pdfjs/standard_fonts/FoxitSerif.pfb +0 -0
- package/assets/vendor/pdfjs/standard_fonts/FoxitSerifBold.pfb +0 -0
- package/assets/vendor/pdfjs/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
- package/assets/vendor/pdfjs/standard_fonts/FoxitSerifItalic.pfb +0 -0
- package/assets/vendor/pdfjs/standard_fonts/FoxitSymbol.pfb +0 -0
- package/assets/vendor/pdfjs/standard_fonts/LICENSE_FOXIT +27 -0
- package/assets/vendor/pdfjs/standard_fonts/LICENSE_LIBERATION +102 -0
- package/assets/vendor/pdfjs/standard_fonts/LiberationSans-Bold.ttf +0 -0
- package/assets/vendor/pdfjs/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
- package/assets/vendor/pdfjs/standard_fonts/LiberationSans-Italic.ttf +0 -0
- package/assets/vendor/pdfjs/standard_fonts/LiberationSans-Regular.ttf +0 -0
- package/assets/vendor/pdfjs/web/pdf_viewer.css +6989 -0
- package/assets/vendor/pdfjs/web/pdf_viewer.mjs +9459 -0
- package/lib/client.js +534 -3
- package/lib/client.js.map +1 -1
- package/lib/index.js +100 -22
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/client/pdf/pdfLoader.ts +82 -0
- package/src/client/pdf/pdfPanel.ts +239 -0
- package/src/client/pdfPreview.ts +48 -0
- package/src/client/styles/editor.css +11 -0
- package/src/client/ui/EditorView.ts +107 -3
- package/src/routes.ts +3 -0
- package/src/rpc.ts +63 -18
- package/src/shared/rpc.ts +18 -0
- package/src/store.ts +2 -0
package/lib/client.js
CHANGED
|
@@ -31,7 +31,7 @@ window.__ModuleLoader__.load({
|
|
|
31
31
|
let react_dom_client = require("react-dom/client");
|
|
32
32
|
let react_dom = require("react-dom");
|
|
33
33
|
//#region \0dsh-css:/home/runner/work/DSH_VsCodeMode/DSH_VsCodeMode/src/client/styles/editor.css.mjs
|
|
34
|
-
const css$1 = "/* dsh-vscode-mode 编辑区样式(原 ensureEdrvStyles 字符串,落盘为真 .css,由 tsdown CSS-inline 注入) */\n/* 浅色主题(对齐参考图:#f8f8f8 近白底 + 薄荷绿药丸 + 青绿文字 + 三文鱼 undo + 浅灰边框):\n 在 [data-edrv-view] 作用域内重定义 --dsw-alias-*,级联命中组件内联样式与 CSS。 */\n[data-edrv-view] { box-sizing: border-box; --edrv-tab-h: 34px; --dsw-alias-bg-base: #f8f8f8; --dsw-alias-bg-layer-1: #ffffff; --dsw-alias-bg-layer-2: #f0f4f4; --dsw-alias-bg-overlay: #ffffff; --dsw-alias-label-primary: #1f2933; --dsw-alias-label-secondary: #52606d; --dsw-alias-label-tertiary: #9aa5b1; --dsw-alias-border-l1: #e0e6e8; --dsw-alias-border-l2: #cbd2d9; --dsw-alias-brand-primary: #0f9d58; --dsw-alias-state-success-primary: #0f9d58; --dsw-alias-state-error-primary: #d9534f; --dsw-alias-state-warn-primary: #d97706; --dsw-alias-interactive-bg-hover: rgba(15,157,88,.08); }\n\n[data-edrv-view] .edrv-tabs { display: flex; align-items: center; gap: 2px; padding: 2px 8px 0; background: var(--dsw-alias-bg-layer-1, transparent); overflow-x: auto; scrollbar-width: thin; flex-shrink: 0; }\n[data-edrv-view] .edrv-tab { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 8px 0 12px; border: none; border-radius: 6px 6px 0 0; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); font-size: 12px; cursor: pointer; white-space: nowrap; flex-shrink: 0; }\n[data-edrv-view] .edrv-tab:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-tab.edrv-tab-active { background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); box-shadow: inset 0 -2px 0 var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-tab .edrv-tab-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--dsw-alias-brand-primary, #4f8cff); flex-shrink: 0; }\n[data-edrv-view] .edrv-tab .edrv-tab-x { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; border-radius: 4px; color: var(--dsw-alias-label-tertiary, #888); font-size: 11px; }\n[data-edrv-view] .edrv-tab .edrv-tab-x:hover { background: rgba(255,255,255,.12); color: var(--dsw-alias-label-primary, #eee); }\n[data-edrv-view] .edrv-tab-add { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; margin-left: 2px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); font-size: 14px; cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-tab-add:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-pathbar { display: flex; align-items: center; gap: 8px; height: 26px; padding: 0 10px; background: var(--dsw-alias-bg-layer-1, #ffffff); border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); font-size: 12px; flex-shrink: 0; overflow: hidden; }\n[data-edrv-view] .edrv-pathbar .edrv-pb-name { font-weight: 600; color: var(--dsw-alias-label-primary, #1f2933); white-space: nowrap; }\n[data-edrv-view] .edrv-pathbar .edrv-pb-full { flex: 1; min-width: 0; color: var(--dsw-alias-label-tertiary, #9aa5b1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; direction: rtl; text-align: left; }\n[data-edrv-view] .edrv-pathbar .edrv-pb-meta { flex-shrink: 0; font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-variant-numeric: tabular-nums; }\n[data-edrv-view] .edrv-pathbar .edrv-pb-status { color: var(--dsw-alias-label-secondary, #52606d); }\n[data-edrv-view] .edrv-path-input { flex: 1; min-width: 140px; height: 24px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 12px; outline: none; }\n[data-edrv-view] .edrv-search-wrap { position: relative; flex-shrink: 0; display: flex; align-items: center; padding: 2px 8px 2px 4px; }\n[data-edrv-view] .edrv-search { width: 190px; height: 24px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 12px; outline: none; }\n[data-edrv-view] .edrv-search:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-search-pop { position: absolute; top: calc(100% + 4px); right: 8px; width: min(460px, calc(100vw - 24px)); max-height: 300px; overflow: auto; background: var(--dsw-alias-bg-overlay, #1c1c1c); border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 10px; box-shadow: 0 6px 20px rgba(0,0,0,.4); z-index: 60; padding: 4px; }\n[data-edrv-view] .edrv-search-item { display: flex; flex-direction: column; gap: 1px; padding: 5px 8px; border-radius: 6px; cursor: pointer; }\n[data-edrv-view] .edrv-search-item:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.07)); }\n[data-edrv-view] .edrv-search-item .n { color: var(--dsw-alias-label-primary, #eee); font-size: 12px; word-break: break-all; }\n[data-edrv-view] .edrv-search-item .d { color: var(--dsw-alias-label-tertiary, #888); font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-search-empty { padding: 8px; font-size: 12px; color: var(--dsw-alias-label-tertiary, #888); }\n[data-edrv-view] .edrv-btn-mini { font-size: 11px; padding: 2px 9px; border: none; border-radius: 999px; cursor: pointer; color: #fff; font-weight: 600; white-space: nowrap; }\n[data-edrv-view] .edrv-btn-keep { background: var(--dsw-alias-state-success-primary, #2e9e44); }\n[data-edrv-view] .edrv-btn-undo { background: var(--dsw-alias-state-warn-primary, #d97706); }\n[data-edrv-view] .edrv-btn-mini:disabled { opacity: .45; cursor: default; }\n[data-edrv-view] .edrv-statusbar { display: flex; align-items: center; gap: 10px; padding: 3px 10px; border-top: 1px solid var(--dsw-alias-border-l1, #333); background: var(--dsw-alias-bg-layer-1, transparent); font-size: 11px; color: var(--dsw-alias-label-tertiary, #888); flex-shrink: 0; white-space: nowrap; overflow: hidden; }\n[data-edrv-view] .edrv-statusbar .edrv-sp-path { flex: 1; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-statusbar .edrv-sp-lsp { flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-statusbar .edrv-sp-progress-message { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--dsw-alias-label-secondary, #52606d); }\n[data-edrv-view] .edrv-statusbar .edrv-sp-progress { flex: 0 0 auto; min-width: 36px; text-align: right; font-variant-numeric: tabular-nums; color: var(--dsw-alias-label-secondary, #52606d); }\n[data-edrv-view] .edrv-lsp-status-dot { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; background: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-lsp-status-dot.ready { background: var(--dsw-alias-state-success-primary, #0f9d58); }\n[data-edrv-view] .edrv-lsp-status-dot.busy { background: var(--dsw-alias-state-warn-primary, #d97706); animation: edrv-lsp-pulse 1.2s ease-in-out infinite; }\n@keyframes edrv-lsp-pulse { 50% { opacity: .45; } }\n/* Ctrl+hover 可导航标识符下划线提示(绑定 Monaco inlineClassName 装饰) */\n[data-edrv-view] .edrv-nav-underline { text-decoration: underline; text-decoration-color: var(--dsw-alias-interactive-primary, #4fc1ff); text-underline-offset: 1px; cursor: pointer; }\n[data-edrv-view] .edrv-diffchip { font-size: 11px; padding: 2px 10px; border: 1px solid var(--dsw-alias-border-l1, #333); border-radius: 999px; background: var(--dsw-alias-bg-layer-2, transparent); color: var(--dsw-alias-state-warn-primary, #b7791f); cursor: pointer; white-space: nowrap; flex-shrink: 0; }\n[data-edrv-view] .edrv-chip-btn { font-size: 12px; padding: 2px 6px; border: none; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); cursor: pointer; border-radius: 4px; flex-shrink: 0; }\n[data-edrv-view] .edrv-chip-btn:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-chip-btn:disabled { opacity: .35; cursor: default; }\n[data-edrv-view] .edrv-chip-btn:disabled:hover { background: transparent; }\n[data-edrv-view] .edrv-mn-add-line { background: rgba(15,157,88,.10); }\n[data-edrv-view] .edrv-mn-gutter-add { color: #0f9d58 !important; font-weight: 700; display: flex !important; align-items: center; justify-content: center; }\n[data-edrv-view] .edrv-mn-gutter-add::before { content: \"+\"; }\n[data-edrv-view] .edrv-del-zone { background: #fdeaea; border-top: 1px solid rgba(217,83,79,.35); border-bottom: 1px solid rgba(217,83,79,.35); box-shadow: inset 0 0 0 1px rgba(217,83,79,.12); }\n[data-edrv-view] .edrv-del-row { white-space: pre; font-family: var(--ds-font-family-code, ui-monospace, monospace); font-size: 12.5px; line-height: 20px; color: #c0392b; }\n[data-edrv-view] .edrv-del-text { display: inline-block; white-space: pre; }\n[data-edrv-view] .edrv-minus-overlay { position: absolute; left: 0; top: 0; width: 100%; height: 100%; max-width: 100%; overflow: visible; pointer-events: none; z-index: 6; }\n[data-edrv-view] .edrv-minus-item { position: absolute; box-sizing: border-box; max-width: 100%; overflow: hidden; }\n[data-edrv-view] .edrv-minus-item::before { content: ''; position: absolute; left: 4px; top: 50%; width: 8px; height: 2px; transform: translateY(-50%); border-radius: 2px; background: #d9534f; }\n[data-edrv-view] .edrv-monaco-host { flex: 1 1 auto; min-width: 0; min-height: 0; position: relative; overflow: hidden; }\n[data-edrv-view] .edrv-monaco-host > div { position: absolute; inset: 0; min-width: 0; min-height: 0; }\n[data-edrv-view] .edrv-imgview { flex: 1 1 auto; min-width: 0; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }\n[data-edrv-view] .edrv-imgview-bar { display: flex; align-items: center; gap: 8px; height: 34px; padding: 0 10px; flex-shrink: 0; border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); background: var(--dsw-alias-bg-layer-1, transparent); }\n[data-edrv-view] .edrv-imgview-meta { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); white-space: nowrap; }\n[data-edrv-view] .edrv-imgview-stage { flex: 1 1 auto; min-height: 0; display: flex; align-items: center; justify-content: center; overflow: auto; padding: 14px; background-color: var(--dsw-alias-bg-layer-1, #f0f4f4); background-image: conic-gradient(rgba(128,128,128,.14) 25%, transparent 0 50%, rgba(128,128,128,.14) 0 75%, transparent 0); background-size: 16px 16px; }\n[data-edrv-view] .edrv-imgview-img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 4px; box-shadow: 0 2px 12px rgba(31,41,51,.18); }\n[data-edrv-view] .edrv-imgview-broken { display: flex; flex-direction: column; align-items: center; gap: 10px; font-size: 13px; color: var(--dsw-alias-label-tertiary, #777); }\n[data-edrv-view] .edrv-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; height: 100%; color: var(--dsw-alias-label-tertiary, #777); font-size: 13px; }\n[data-edrv-view] .edrv-diffbar { position: absolute; left: 0; right: 0; bottom: 10px; margin: 0 auto; z-index: 25; width: fit-content; max-width: calc(100% - 20px); border-radius: 12px; background: var(--dsw-specific-tip, var(--dsw-alias-bg-layer-2, #f0f4f4)); border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); box-shadow: none; overflow: visible; display: flex; flex-direction: column; }\n[data-edrv-view] .edrv-editor-area > .edrv-diffbar { max-height: calc(100% - 20px); }\n[data-edrv-view] .edrv-diffbar-row { display: flex; align-items: center; gap: 6px; height: 36px; padding: 4px 5px 4px 12px; flex-wrap: nowrap; }\n[data-edrv-view] .edrv-diffbar-count { font-size: 12px; font-weight: 600; color: var(--dsw-alias-label-primary, #1f2933); min-width: 42px; text-align: center; white-space: nowrap; cursor: pointer; }\n[data-edrv-view] .edrv-diffbar-count.edrv-count-file { min-width: 64px; cursor: default; }\n[data-edrv-view] .edrv-diffbar-file { flex: 1; min-width: 0; font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-pill { font-size: 11px; padding: 3px 10px; border: none; border-radius: 999px; cursor: pointer; white-space: nowrap; font-weight: 600; }\n[data-edrv-view] .edrv-pill-keep { background: #e8f8e8; color: #0f7a45; border: 1px solid rgba(15,157,88,.4); }\n[data-edrv-view] .edrv-pill-undo { background: #fdeaea; color: #c0392b; border: 1px solid rgba(217,83,79,.4); }\n[data-edrv-view] .edrv-pill-ghost { background: #ffffff; color: var(--dsw-alias-label-secondary, #52606d); border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-pill:disabled { opacity: .45; cursor: default; }\n[data-edrv-view] .edrv-diffbar-menu { position: absolute; right: 8px; bottom: calc(100% + 6px); z-index: 45; min-width: 160px; border-radius: 10px; background: var(--dsw-alias-bg-overlay, #ffffff); border: 1px solid var(--dsw-alias-border-l2, #cbd2d9); box-shadow: 0 6px 20px rgba(31,41,51,.16); padding: 4px; display: flex; flex-direction: column; gap: 2px; }\n[data-edrv-view] .edrv-diffmenu-item { display: flex; align-items: center; gap: 8px; font-size: 12px; padding: 6px 10px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-primary, #1f2933); cursor: pointer; text-align: left; }\n[data-edrv-view] .edrv-diffmenu-item:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-diffmenu-item.danger { color: var(--dsw-alias-state-error-primary, #d9534f); }\n[data-edrv-view] .edrv-diffmenu-sep { height: 1px; margin: 2px 4px; background: var(--dsw-alias-border-l1, #e0e6e8); }\n/* 编辑区 / Tab 右键菜单(添加文件/选中内容到对话) */\n[data-edrv-view] .edrv-ctxmenu { position: fixed; z-index: 71; min-width: 200px; max-width: 320px; border-radius: 10px; background: var(--dsw-alias-bg-overlay, #ffffff); border: 1px solid var(--dsw-alias-border-l2, #cbd2d9); box-shadow: 0 8px 26px rgba(31,41,51,.2); padding: 4px; display: flex; flex-direction: column; gap: 1px; }\n[data-edrv-view] .edrv-ctxmenu-item { display: flex; align-items: center; gap: 8px; font-size: 12px; line-height: 18px; padding: 7px 10px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-primary, #1f2933); cursor: pointer; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-ctxmenu-item:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-ctxmenu-item.edrv-ctxmenu-danger { color: var(--dsw-alias-state-error-primary, #d9534f); }\n[data-edrv-view] .edrv-ctxmenu-item:disabled,\n[data-edrv-view] .edrv-ctxmenu-item.edrv-ctxmenu-disabled { color: var(--dsw-alias-label-disabled, #b0b7c0); cursor: default; background: transparent; }\n[data-edrv-view] .edrv-ctxmenu-sep { height: 1px; margin: 3px 4px; background: var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-diffbar-body { max-height: 130px; max-width: min(560px, calc(100vw - 40px)); overflow: auto; padding: 4px 8px 8px; display: flex; flex-direction: column; gap: 4px; border-top: 1px solid var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-diffrow { display: flex; align-items: center; gap: 8px; padding: 3px 6px; border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); border-radius: 6px; background: var(--dsw-alias-bg-layer-2, #f0f4f4); cursor: pointer; flex-wrap: wrap; }\n[data-edrv-view] .edrv-diffrow:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-diffrow-l { font-size: 11px; color: var(--dsw-alias-label-primary, #1f2933); min-width: 74px; font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-diffrow-o { font-size: 11px; color: var(--dsw-alias-state-error-primary, #d9534f); font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-diffrow-n { font-size: 11px; color: var(--dsw-alias-state-success-primary, #0f9d58); font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-diffrow-tag { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-diffrow-stale { border-color: rgba(217,119,6,.5); cursor: default; }\n[data-edrv-view] .edrv-diffbox-others { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding: 4px 2px 0; border-top: 1px solid var(--dsw-alias-border-l1, #e0e6e8); margin-top: 2px; }\n[data-edrv-view] .edrv-diffrow-file { font-size: 11px; padding: 2px 10px; border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); border-radius: 999px; background: var(--dsw-alias-bg-layer-2, #f0f4f4); color: var(--dsw-alias-label-secondary, #52606d); cursor: pointer; white-space: nowrap; max-width: 200px; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-diffrow-file:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); color: var(--dsw-alias-label-primary, #1f2933); }\n/* 编辑区 hover 差异块的 Keep/Undo 浮层 */\n[data-edrv-view] .edrv-hoveract { position: absolute; z-index: 30; display: flex; align-items: center; gap: 4px; padding: 2px 6px; border-radius: 8px; background: var(--dsw-alias-bg-overlay, #ffffff); border: 1px solid var(--dsw-alias-border-l2, #cbd2d9); box-shadow: 0 4px 14px rgba(31,41,51,.14); }\n[data-edrv-view] .edrv-launch { position: absolute; left: 12px; right: 12px; bottom: 12px; z-index: 40; border-radius: 10px; background: var(--dsw-alias-bg-overlay, #1c1c1c); border: 1px solid var(--dsw-alias-border-l2, #555); box-shadow: 0 6px 24px rgba(0,0,0,.5); display: flex; flex-direction: column; max-height: 60%; overflow: hidden; }\n[data-edrv-view] .edrv-launch-head { display: flex; align-items: center; gap: 6px; padding: 6px 8px; border-bottom: 1px solid var(--dsw-alias-border-l1, #333); }\n[data-edrv-view] .edrv-launch-tab { font-size: 12px; padding: 3px 12px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); cursor: pointer; }\n[data-edrv-view] .edrv-launch-tab.on { background: var(--dsw-alias-bg-layer-2, transparent); color: var(--dsw-alias-label-primary, #eee); font-weight: 600; }\n[data-edrv-view] .edrv-launch-body { flex: 1; min-height: 0; overflow: auto; padding: 6px 8px; display: flex; flex-direction: column; gap: 4px; }\n[data-edrv-view] .edrv-launch-row { display: flex; align-items: center; gap: 8px; padding: 3px 6px; border: 1px solid var(--dsw-alias-border-l1, #333); border-radius: 6px; cursor: pointer; flex-wrap: wrap; }\n[data-edrv-view] .edrv-launch-row:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-launch-path { flex: 1; min-width: 0; font-size: 12px; color: var(--dsw-alias-label-primary, #eee); word-break: break-all; }\n[data-edrv-view] .edrv-launch-cnt { font-size: 11px; color: var(--dsw-alias-label-tertiary, #888); white-space: nowrap; }\n[data-edrv-view] .edrv-launch-arch { display: flex; flex-direction: column; gap: 6px; }\n[data-edrv-view] .monaco-editor { overflow: hidden !important; }\n[data-edrv-view] .monaco-editor .sticky-widget { z-index: 30 !important; background: var(--dsw-alias-bg-base, #f8f8f8) !important; }\n[data-edrv-view] .monaco-editor .sticky-widget .sticky-line-content,\n[data-edrv-view] .monaco-editor .sticky-widget .sticky-line-number { background: var(--dsw-alias-bg-base, #f8f8f8) !important; }\n[data-edrv-view] .monaco-editor, [data-edrv-view] .monaco-editor .margin, [data-edrv-view] .monaco-editor-background { background: transparent !important; }\n[data-edrv-view] .monaco-editor .scrollbar .slider { background: rgba(128,128,128,.3) !important; }\n[data-edrv-view] .edrv-loading { gap: 8px; padding: 20px; }\n[data-edrv-view] .edrv-loading-title { color: var(--dsw-alias-label-primary, #1f2933); font-size: 13px; }\n[data-edrv-view] .edrv-progress { width: min(360px, 72%); height: 6px; overflow: hidden; border-radius: 999px; background: var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-progress-value { height: 100%; border-radius: inherit; background: var(--dsw-alias-brand-primary, #0f9d58); transition: width .24s ease; }\n[data-edrv-view] .edrv-loading-percent { color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 11px; font-variant-numeric: tabular-nums; }\n@media (prefers-reduced-motion: reduce) {\n [data-edrv-view] .edrv-progress-value { transition: none; }\n}\n\n/* ===== 唯一会话级差异 dock(遵循 DSH todo/queue 原生布局) ===== */\n[data-edrv-diff-dock-shell] {\n box-sizing: border-box;\n width: calc(100% - var(--dsh-composer-side-clearance) - var(--dsh-composer-side-clearance) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));\n max-width: calc(var(--dsh-composer-card-max-width) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));\n margin: 0 auto;\n padding: 0;\n flex: none;\n border: 1px solid var(--dsw-alias-border-l1, #e0e6e8);\n border-radius: 12px;\n background: var(--dsw-specific-tip, var(--dsw-alias-bg-layer-2, transparent));\n box-shadow: none;\n overflow: hidden;\n}\n[data-edrv-diff-dock-shell] .edrv-diffbar-dock {\n box-sizing: border-box;\n position: relative;\n left: auto;\n right: auto;\n bottom: auto;\n z-index: auto;\n width: 100%;\n max-width: none;\n margin: 0;\n display: flex;\n flex-direction: column;\n border: none;\n border-radius: 0;\n background: transparent;\n box-shadow: none;\n overflow: visible;\n}\n[data-edrv-diff-dock-shell] .edrv-diffbar-row { min-height: 36px; padding: 6px 12px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-dock-row { min-height: 36px; padding: 6px 12px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-body { max-height: 180px; overflow: auto; padding: 6px 12px 10px; border-top: 1px solid var(--dsw-alias-border-l1); }\n[data-edrv-diff-dock-shell] .edrv-diffbar-dock-button { box-sizing: border-box; display: flex; align-items: center; justify-content: center; width: 100%; height: 24px; border: none; border-radius: 8px; padding: 0 12px; background: transparent; color: var(--dsw-alias-label-primary); font-size: 13px; font-weight: 500; line-height: 24px; text-align: center; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-dock-button:hover { background: var(--dsw-alias-interactive-bg-hover); }\n[data-edrv-diff-dock-shell] .edrv-diffbar-count { display: inline-flex; align-items: center; color: var(--dsw-alias-label-primary); font-family: Inter, var(--dsw-font-family); font-size: 13px; font-weight: 500; line-height: 24px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-file { display: inline-flex; align-items: center; color: var(--dsw-alias-label-tertiary); font-family: Inter, var(--dsw-font-family); font-size: 13px; font-weight: 400; line-height: 24px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-editor-row { display: flex; align-items: center; height: 36px; min-height: 36px; padding: 4px 12px; overflow-x: auto; scrollbar-width: thin; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-editor-content { display: flex; align-items: center; gap: 10px; width: 100%; min-width: max-content; min-height: 28px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-nav,\n[data-edrv-diff-dock-shell] .edrv-diffbar-files,\n[data-edrv-diff-dock-shell] .edrv-diffbar-actions { display: flex; align-items: center; gap: 6px; flex: none; height: 28px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-actions { margin-left: auto; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-details-toggle { display: inline-flex; align-items: center; justify-content: center; width: 28px; min-width: 28px; padding: 0; font-size: 13px; line-height: 24px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-details-toggle svg { width: 14px; height: 14px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-files { min-width: 0; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-files .edrv-diffbar-file { min-width: 72px; max-width: 240px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-progress { min-width: 0; color: var(--dsw-alias-label-tertiary); font-family: Inter, var(--dsw-font-family); font-size: 13px; font-weight: 400; line-height: 24px; font-variant-numeric: tabular-nums; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-summary { min-width: 0; color: var(--dsw-alias-label-tertiary); font-family: Inter, var(--dsw-font-family); font-size: 13px; font-weight: 400; line-height: 24px; }\n[data-edrv-diff-dock-shell] .edrv-pill { box-sizing: border-box; height: 28px; padding: 0 9px; border: none; border-radius: 999px; cursor: pointer; white-space: nowrap; font-size: 11px; line-height: 26px; font-weight: 600; }\n[data-edrv-diff-dock-shell] .edrv-pill-keep { background: var(--dsw-alias-state-success-tertiary); color: var(--dsw-alias-state-success-primary); border: 1px solid var(--dsw-alias-state-success-secondary); }\n[data-edrv-diff-dock-shell] .edrv-pill-undo { background: var(--dsw-alias-state-error-tertiary); color: var(--dsw-alias-state-error-primary); border: 1px solid var(--dsw-alias-state-error-secondary); }\n[data-edrv-diff-dock-shell] .edrv-pill-ghost { background: transparent; color: var(--dsw-alias-label-secondary); border: 1px solid var(--dsw-alias-border-l1); }\n[data-edrv-diff-dock-shell] .edrv-pill:hover:not(:disabled) { background-color: var(--dsw-alias-interactive-bg-hover); }\n[data-edrv-diff-dock-shell] .edrv-pill:focus-visible { outline: 2px solid var(--dsw-alias-label-tertiary); outline-offset: -2px; }\n[data-edrv-diff-dock-shell] .edrv-pill:disabled { opacity: .45; cursor: default; }\n[data-edrv-diff-dock-shell] .edrv-diffrow { display: flex; align-items: center; gap: 8px; padding: 3px 6px; border: 1px solid var(--dsw-alias-border-l1); border-radius: 6px; background: transparent; cursor: pointer; flex-wrap: wrap; }\n[data-edrv-diff-dock-shell] .edrv-diffrow:hover { background: var(--dsw-alias-interactive-bg-hover); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-l { color: var(--dsw-alias-label-primary); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-o { color: var(--dsw-alias-state-error-primary); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-n { color: var(--dsw-alias-state-success-primary); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-tag { color: var(--dsw-alias-label-tertiary); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-stale { border-color: var(--dsw-alias-state-warn-secondary); cursor: default; }\n[data-edrv-diff-dock-shell] .edrv-diffbox-others { border-top: 1px solid var(--dsw-alias-border-l1); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-file { border-color: var(--dsw-alias-border-l1); background: transparent; color: var(--dsw-alias-label-secondary); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-file:hover { background: var(--dsw-alias-interactive-bg-hover); color: var(--dsw-alias-label-primary); }\n[data-edrv-diff-dock-shell] .edrv-diff-details { display: flex; flex-direction: column; gap: 2px; padding: 6px 12px 8px; border-top: 1px solid var(--dsw-alias-border-l1); }\n[data-edrv-diff-dock-shell] .edrv-diff-details .edrv-diffmenu-item { display: flex; align-items: center; width: 100%; min-height: 28px; gap: 8px; padding: 4px 8px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-primary); cursor: pointer; text-align: left; font-size: 12px; line-height: 20px; }\n[data-edrv-diff-dock-shell] .edrv-diff-details .edrv-diffmenu-item:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }\n[data-edrv-diff-dock-shell] .edrv-diff-details .edrv-diffmenu-item.danger { color: var(--dsw-alias-state-error-primary); }\n[data-edrv-diff-dock-shell] .edrv-diff-details .edrv-diffmenu-item:disabled { opacity: .45; cursor: default; }\n[data-edrv-diff-dock-shell] .edrv-diff-details .edrv-diffmenu-sep { height: 1px; margin: 2px 4px; background: var(--dsw-alias-border-l1); }\n@media (max-width: 620px) {\n [data-edrv-diff-dock-shell] .edrv-diffbar-editor-content { width: max-content; }\n [data-edrv-diff-dock-shell] .edrv-diffbar-files .edrv-diffbar-file { max-width: 160px; }\n}\n\n/* ===== 侧边栏(活动栏 + 面板区 + 文件树) ===== */\n[data-edrv-view] .edrv-editor-row { display: flex; flex: 1 1 auto; min-width: 0; min-height: 0; overflow: hidden; }\n[data-edrv-view] .edrv-main-col { box-sizing: border-box; min-width: 0; min-height: 0; overflow: hidden; }\n[data-edrv-view] .edrv-main-col > .edrv-pathbar,\n[data-edrv-view] .edrv-main-col > .edrv-tabs { flex: 0 0 auto; }\n[data-edrv-view] .edrv-editor-area { position: relative; display: flex; flex: 1 1 auto; flex-direction: column; min-width: 0; min-height: 0; overflow: hidden; }\n[data-edrv-view] .edrv-sidebar { display: flex; flex-direction: row; flex-shrink: 1; min-width: 0; height: 100%; background: var(--dsw-alias-bg-layer-1, #ffffff); border-right: 1px solid var(--dsw-alias-border-l1, #e0e6e8); overflow: hidden; }\n[data-edrv-view] .edrv-rail { display: flex; flex-direction: column; align-items: center; width: 44px; flex-shrink: 0; padding: 6px 0; background: var(--dsw-alias-bg-layer-2, #f0f4f4); border-right: 1px solid var(--dsw-alias-border-l1, #e0e6e8); gap: 4px; }\n[data-edrv-view] .edrv-rail-btn { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border: none; border-radius: 8px; background: transparent; color: var(--dsw-alias-label-secondary, #52606d); cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-rail-btn:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-rail-btn.edrv-rail-on { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.12)); color: var(--dsw-alias-label-primary, #1f2933); box-shadow: inset 2px 0 0 var(--dsw-alias-brand-primary, #0f9d58); }\n[data-edrv-view] .edrv-rail-icon { font-size: 15px; line-height: 1; }\n[data-edrv-view] .edrv-rail-badge { position: absolute; top: 2px; right: 2px; min-width: 14px; height: 14px; padding: 0 3px; border-radius: 999px; background: var(--dsw-alias-brand-primary, #0f9d58); color: #fff; font-size: 9px; font-weight: 600; line-height: 14px; text-align: center; box-sizing: border-box; }\n[data-edrv-view] .edrv-side-body { flex: 1; min-width: 0; min-height: 0; display: flex; overflow: hidden; }\n[data-edrv-view] .edrv-side-panel { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; position: relative; }\n[data-edrv-view] .edrv-side-head { display: flex; align-items: center; gap: 8px; height: 34px; padding: 0 10px 0 12px; border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); flex-shrink: 0; }\n[data-edrv-view] .edrv-side-title { font-size: 12px; font-weight: 600; color: var(--dsw-alias-label-primary, #1f2933); white-space: nowrap; }\n[data-edrv-view] .edrv-side-root { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-side-btn { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #52606d); font-size: 12px; cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-side-btn:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-tree { flex: 1; min-height: 0; overflow: auto; padding: 4px 6px 12px; font-size: 12px; }\n[data-edrv-view] .edrv-tree-row { display: flex; align-items: center; gap: 4px; height: 22px; padding-right: 6px; border-radius: 5px; color: var(--dsw-alias-label-primary, #1f2933); cursor: pointer; white-space: nowrap; }\n[data-edrv-view] .edrv-tree-row:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-tree-row.edrv-tree-active { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.14)); }\n[data-edrv-view] .edrv-tree-row.edrv-tree-context { box-shadow: inset 0 0 0 1px var(--dsw-alias-brand-primary, #0f9d58); background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.12)); }\n[data-edrv-view] .edrv-tree-chev { width: 12px; flex-shrink: 0; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 10px; text-align: center; }\n[data-edrv-view] .edrv-tree-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-tree-name.edrv-tree-dim { color: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-tree-badge { min-width: 14px; height: 14px; padding: 0 4px; border-radius: 999px; background: var(--dsw-alias-state-warn-primary, #d97706); color: #fff; font-size: 9px; font-weight: 600; line-height: 14px; text-align: center; box-sizing: border-box; flex-shrink: 0; }\n[data-edrv-view] .edrv-tree-loading { height: 22px; line-height: 22px; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 11px; }\n[data-edrv-view] .edrv-tree-error { display: flex; align-items: center; gap: 8px; margin: 4px 2px 6px; padding: 6px 8px; border: 1px solid rgba(217,83,79,.4); border-radius: 6px; background: #fdeaea; color: var(--dsw-alias-state-error-primary, #d9534f); font-size: 11px; }\n/* 大纲面板:kind 字形 / detail / 行号 */\n[data-edrv-view] .edrv-outline-kind { display: inline-flex; align-items: center; justify-content: center; width: 14px; flex-shrink: 0; font-size: 12px; font-weight: 600; text-align: center; }\n[data-edrv-view] .edrv-outline-kind.edrv-ol-func { color: var(--dsw-alias-brand-primary, #0f9d58); }\n[data-edrv-view] .edrv-outline-kind.edrv-ol-type { color: var(--dsw-alias-label-primary, #1f2933); }\n[data-edrv-view] .edrv-outline-kind.edrv-ol-data { color: var(--dsw-alias-state-warn-primary, #d97706); }\n[data-edrv-view] .edrv-outline-kind.edrv-ol-ns { color: var(--dsw-alias-label-secondary, #52606d); }\n[data-edrv-view] .edrv-outline-kind.edrv-ol-key { color: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-outline-detail { flex-shrink: 0; max-width: 40%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 11px; }\n[data-edrv-view] .edrv-outline-ln { flex-shrink: 0; padding-right: 2px; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 10px; font-variant-numeric: tabular-nums; }\n[data-edrv-view] .edrv-side-resize { width: 5px; flex-shrink: 0; cursor: col-resize; background: transparent; }\n[data-edrv-view] .edrv-side-resize:hover { background: var(--dsw-alias-brand-primary, #0f9d58); opacity: .35; }\n[data-edrv-view] .edrv-chip-btn.edrv-chip-on { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.12)); color: var(--dsw-alias-label-primary, #1f2933); }\n\n/* ===== 侧栏形态(betterSidebar 面板内编辑区) ===== */\n[data-edrv-view][data-edrv-layout='side'] { box-sizing: border-box; height: 100%; }\n\n/* ===== 侧边栏引导条(旧页签形态、未装 betterSidebar 时) ===== */\n[data-edrv-view] .edrv-side-hint { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; flex-wrap: wrap; padding: 6px 12px; font-size: 12px; color: var(--dsw-alias-label-secondary, #52606d); background: var(--dsw-specific-tip, var(--dsw-alias-bg-layer-2, #f0f4f4)); border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-side-hint-text { white-space: nowrap; }\n[data-edrv-view] .edrv-side-hint-cmd { font-size: 11px; padding: 2px 6px; border-radius: 6px; background: var(--dsw-alias-bg-layer-1, #ffffff); border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); color: var(--dsw-alias-label-primary, #1f2933); white-space: nowrap; }\n[data-edrv-view] .edrv-side-hint-close { margin-left: auto; border: none; background: transparent; color: var(--dsw-alias-label-tertiary, #9aa5b1); cursor: pointer; font-size: 14px; line-height: 1; padding: 2px 6px; border-radius: 6px; flex-shrink: 0; }\n[data-edrv-view] .edrv-side-hint-close:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); color: var(--dsw-alias-label-primary, #1f2933); }\n\n/* ===== search panel (sidebar, VSCode search view) ===== */\n[data-edrv-view] .edrv-search-panel { display: flex; flex-direction: column; min-height: 0; flex: 1; padding: 6px; gap: 4px; }\n[data-edrv-view] .edrv-search-qrow { display: flex; gap: 4px; }\n[data-edrv-view] .edrv-search-input { flex: 1; min-width: 0; height: 26px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 12px; outline: none; }\n[data-edrv-view] .edrv-search-input:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-search-opts { display: flex; align-items: center; gap: 2px; flex: 0 0 auto; }\n[data-edrv-view] .edrv-search-opt { min-width: 24px; height: 22px; padding: 0 6px; border: 1px solid transparent; border-radius: 5px; background: transparent; color: var(--dsw-alias-label-secondary, #52606d); font-size: 11px; font-family: var(--ds-font-family-code, ui-monospace, monospace); cursor: pointer; }\n[data-edrv-view] .edrv-search-opt:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-search-opt.on { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.14)); color: var(--dsw-alias-label-primary, #1f2933); border-color: var(--dsw-alias-border-l2, #d5dde3); }\n[data-edrv-view] .edrv-search-spacer { flex: 1; }\n[data-edrv-view] .edrv-search-summary { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); padding: 2px 4px; }\n[data-edrv-view] .edrv-search-results { flex: 1; min-height: 0; overflow: auto; font-size: 12px; }\n[data-edrv-view] .edrv-search-group { margin-bottom: 2px; }\n[data-edrv-view] .edrv-search-file { display: flex; align-items: center; gap: 4px; height: 22px; padding: 0 4px; border-radius: 5px; color: var(--dsw-alias-label-primary, #1f2933); cursor: pointer; white-space: nowrap; }\n[data-edrv-view] .edrv-search-file:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-search-chev { width: 12px; flex-shrink: 0; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 10px; text-align: center; }\n[data-edrv-view] .edrv-search-fname { font-weight: 600; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-search-fdir { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 11px; }\n[data-edrv-view] .edrv-search-fcount { flex-shrink: 0; min-width: 16px; height: 15px; padding: 0 4px; border-radius: 999px; background: var(--dsw-alias-bg-layer-2, #f0f4f4); color: var(--dsw-alias-label-secondary, #52606d); font-size: 10px; line-height: 15px; text-align: center; }\n[data-edrv-view] .edrv-search-line { display: flex; gap: 6px; padding: 1px 4px 1px 16px; border-radius: 4px; color: var(--dsw-alias-label-primary, #1f2933); cursor: pointer; overflow: hidden; }\n[data-edrv-view] .edrv-search-line.alt { background: var(--dsw-alias-bg-layer-1, #ffffff); }\n[data-edrv-view] .edrv-search-line:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-search-ln { flex-shrink: 0; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 11px; min-width: 26px; text-align: right; user-select: none; }\n[data-edrv-view] .edrv-search-text { overflow: hidden; text-overflow: ellipsis; white-space: pre; font-family: var(--ds-font-family-code, ui-monospace, monospace); font-size: 11px; }\n[data-edrv-view] .edrv-search-hit { background: var(--dsw-alias-state-warn-primary, #e5b93f); color: #1f2933; border-radius: 2px; padding: 0 1px; }\n[data-edrv-view] .edrv-search-empty { padding: 8px 4px; font-size: 12px; color: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-search-error { padding: 6px 8px; border: 1px solid rgba(217,83,79,.4); border-radius: 6px; background: #fdeaea; color: var(--dsw-alias-state-error-primary, #d9534f); font-size: 11px; }\n[data-edrv-view] .edrv-search-warn { padding: 6px 8px; border: 1px solid rgba(240,173,78,.45); border-radius: 6px; background: #fdf6e3; color: #b8860b; font-size: 11px; word-break: break-all; }\n\n/* include/exclude filter rows (collapsible) */\n[data-edrv-view] .edrv-search-rows { display: flex; flex-direction: column; gap: 4px; padding: 2px 0 4px; }\n[data-edrv-view] .edrv-search-row { display: flex; align-items: center; gap: 4px; }\n[data-edrv-view] .edrv-search-field { flex: 1; min-width: 0; height: 24px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 11px; outline: none; }\n[data-edrv-view] .edrv-search-field:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-search-field.dim { opacity: .45; }\n[data-edrv-view] .edrv-search-field::placeholder { color: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-search-toggle { min-width: 24px; height: 24px; padding: 0 5px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #52606d); font-size: 12px; line-height: 1; cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-search-toggle:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-search-toggle.on { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.14)); color: var(--dsw-alias-label-primary, #1f2933); border-color: var(--dsw-alias-brand-primary, #0f9d58); }\n[data-edrv-view] .edrv-search-toggle:disabled { opacity: .4; cursor: default; }\n\n/* ===== rules panel (sidebar, Codebuddy rules view) ===== */\n[data-edrv-view] .edrv-rules-panel { display: flex; flex-direction: column; min-width: 0; min-height: 0; flex: 1; padding: 6px; gap: 4px; }\n[data-edrv-view] .edrv-rules-tabs { display: flex; align-items: center; gap: 2px; flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-tab { height: 24px; padding: 0 10px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #52606d); font-size: 12px; cursor: pointer; }\n[data-edrv-view] .edrv-rules-tab:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-rules-tab.on { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.14)); color: var(--dsw-alias-label-primary, #1f2933); font-weight: 600; }\n[data-edrv-view] .edrv-rules-new { margin-left: auto; height: 24px; padding: 0 10px; border: 1px solid var(--dsw-alias-border-l2, #cbd2d9); border-radius: 6px; background: var(--dsw-alias-bg-layer-1, #fff); color: var(--dsw-alias-label-primary, #1f2933); font-size: 11px; cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-rules-new:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-rules-ws-line { font-size: 11px; color: var(--dsw-alias-label-secondary, #52606d); padding: 0 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 0 0 auto; user-select: none; }\n[data-edrv-view] .edrv-rules-hint { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); padding: 0 2px; flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-list { flex: 1; min-height: 0; overflow: auto; }\n[data-edrv-view] .edrv-rules-row { display: flex; align-items: center; gap: 4px; padding: 6px 4px; border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); border-radius: 6px; }\n[data-edrv-view] .edrv-rules-row:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-rules-row.off .edrv-rules-main { opacity: .5; }\n[data-edrv-view] .edrv-rules-main { flex: 1; min-width: 0; cursor: pointer; overflow: hidden; }\n[data-edrv-view] .edrv-rules-line1 { display: flex; align-items: center; gap: 6px; min-width: 0; }\n[data-edrv-view] .edrv-rules-sub { display: flex; align-items: center; gap: 5px; margin-top: 3px; min-width: 0; }\n[data-edrv-view] .edrv-rules-sublabel { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); flex-shrink: 0; }\n[data-edrv-view] .edrv-rules-file { font-weight: 600; font-size: 12px; color: var(--dsw-alias-label-primary, #1f2933); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-rules-path { font-size: 10px; color: var(--dsw-alias-label-tertiary, #9aa5b1); flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-rules-type { flex-shrink: 0; height: 15px; padding: 0 5px; border-radius: 999px; font-size: 10px; line-height: 15px; }\n[data-edrv-view] .edrv-rules-type-always { background: rgba(15,157,88,.15); color: #0b7c46; }\n[data-edrv-view] .edrv-rules-type-auto { background: rgba(79,140,255,.16); color: #3367c9; }\n[data-edrv-view] .edrv-rules-type-manual { background: var(--dsw-alias-bg-layer-2, #f0f4f4); color: var(--dsw-alias-label-secondary, #52606d); }\n[data-edrv-view] .edrv-rules-offtag { font-size: 10px; color: var(--dsw-alias-label-tertiary, #9aa5b1); flex-shrink: 0; }\n[data-edrv-view] .edrv-rules-desc { font-size: 11px; color: var(--dsw-alias-label-secondary, #52606d); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 0 1 auto; }\n[data-edrv-view] .edrv-rules-actions { display: flex; align-items: center; gap: 2px; flex-shrink: 0; margin-left: auto; }\n[data-edrv-view] .edrv-rules-act { min-width: 22px; height: 22px; padding: 0 4px; border: none; border-radius: 5px; background: transparent; font-size: 12px; line-height: 1; cursor: pointer; color: var(--dsw-alias-label-secondary, #52606d); display: inline-flex; align-items: center; justify-content: center; }\n[data-edrv-view] .edrv-rules-act:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-rules-switch { position: relative; width: 30px; height: 16px; border-radius: 999px; border: none; background: #b9c4cc; cursor: pointer; transition: background .15s; flex-shrink: 0; padding: 0; }\n[data-edrv-view] .edrv-rules-switch.on { background: #7c5cff; }\n[data-edrv-view] .edrv-rules-knob { position: absolute; top: 2px; left: 2px; width: 12px; height: 12px; border-radius: 50%; background: #fff; transition: left .15s; }\n[data-edrv-view] .edrv-rules-switch.on .edrv-rules-knob { left: 16px; }\n[data-edrv-view] .edrv-rules-empty { padding: 10px 4px; font-size: 12px; color: var(--dsw-alias-label-tertiary, #9aa5b1); line-height: 1.6; }\n[data-edrv-view] .edrv-rules-err { padding: 6px 8px; border: 1px solid rgba(217,83,79,.4); border-radius: 6px; background: #fdeaea; color: var(--dsw-alias-state-error-primary, #d9534f); font-size: 11px; word-break: break-all; }\n[data-edrv-view] .edrv-rules-editor { display: flex; flex-direction: column; min-height: 0; flex: 1; gap: 6px; }\n[data-edrv-view] .edrv-rules-editor-head { display: flex; align-items: center; justify-content: space-between; gap: 6px; font-size: 12px; font-weight: 600; color: var(--dsw-alias-label-primary, #1f2933); flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-crumb { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-rules-editor-ctl { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-ctl-label { font-size: 11px; color: var(--dsw-alias-label-secondary, #52606d); flex-shrink: 0; }\n[data-edrv-view] .edrv-rules-select { height: 24px; padding: 0 4px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 11px; outline: none; cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-rules-select:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-rules-desc-input { flex: 1; min-width: 0; }\n[data-edrv-view] .edrv-rules-input { flex: 1; min-width: 0; height: 24px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 11px; outline: none; font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-rules-input:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-rules-body { flex: 1; min-height: 0; resize: none; padding: 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 12px; line-height: 1.5; outline: none; font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-rules-body:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-rules-editor-hint { font-size: 10px; color: var(--dsw-alias-label-tertiary, #9aa5b1); line-height: 1.5; flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-editor-foot { display: flex; justify-content: flex-end; flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-save { height: 24px; padding: 0 14px; border: none; border-radius: 6px; background: var(--dsw-alias-brand-primary, #0f9d58); color: #fff; font-size: 12px; cursor: pointer; }\n[data-edrv-view] .edrv-rules-save:disabled { opacity: .5; cursor: default; }\n\n\n\n";
|
|
34
|
+
const css$1 = "/* dsh-vscode-mode 编辑区样式(原 ensureEdrvStyles 字符串,落盘为真 .css,由 tsdown CSS-inline 注入) */\n/* 浅色主题(对齐参考图:#f8f8f8 近白底 + 薄荷绿药丸 + 青绿文字 + 三文鱼 undo + 浅灰边框):\n 在 [data-edrv-view] 作用域内重定义 --dsw-alias-*,级联命中组件内联样式与 CSS。 */\n[data-edrv-view] { box-sizing: border-box; --edrv-tab-h: 34px; --dsw-alias-bg-base: #f8f8f8; --dsw-alias-bg-layer-1: #ffffff; --dsw-alias-bg-layer-2: #f0f4f4; --dsw-alias-bg-overlay: #ffffff; --dsw-alias-label-primary: #1f2933; --dsw-alias-label-secondary: #52606d; --dsw-alias-label-tertiary: #9aa5b1; --dsw-alias-border-l1: #e0e6e8; --dsw-alias-border-l2: #cbd2d9; --dsw-alias-brand-primary: #0f9d58; --dsw-alias-state-success-primary: #0f9d58; --dsw-alias-state-error-primary: #d9534f; --dsw-alias-state-warn-primary: #d97706; --dsw-alias-interactive-bg-hover: rgba(15,157,88,.08); }\n\n[data-edrv-view] .edrv-tabs { display: flex; align-items: center; gap: 2px; padding: 2px 8px 0; background: var(--dsw-alias-bg-layer-1, transparent); overflow-x: auto; scrollbar-width: thin; flex-shrink: 0; }\n[data-edrv-view] .edrv-tab { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 8px 0 12px; border: none; border-radius: 6px 6px 0 0; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); font-size: 12px; cursor: pointer; white-space: nowrap; flex-shrink: 0; }\n[data-edrv-view] .edrv-tab:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-tab.edrv-tab-active { background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); box-shadow: inset 0 -2px 0 var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-tab .edrv-tab-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--dsw-alias-brand-primary, #4f8cff); flex-shrink: 0; }\n[data-edrv-view] .edrv-tab .edrv-tab-x { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; border-radius: 4px; color: var(--dsw-alias-label-tertiary, #888); font-size: 11px; }\n[data-edrv-view] .edrv-tab .edrv-tab-x:hover { background: rgba(255,255,255,.12); color: var(--dsw-alias-label-primary, #eee); }\n[data-edrv-view] .edrv-tab-add { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; margin-left: 2px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); font-size: 14px; cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-tab-add:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-pathbar { display: flex; align-items: center; gap: 8px; height: 26px; padding: 0 10px; background: var(--dsw-alias-bg-layer-1, #ffffff); border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); font-size: 12px; flex-shrink: 0; overflow: hidden; }\n[data-edrv-view] .edrv-pathbar .edrv-pb-name { font-weight: 600; color: var(--dsw-alias-label-primary, #1f2933); white-space: nowrap; }\n[data-edrv-view] .edrv-pathbar .edrv-pb-full { flex: 1; min-width: 0; color: var(--dsw-alias-label-tertiary, #9aa5b1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; direction: rtl; text-align: left; }\n[data-edrv-view] .edrv-pathbar .edrv-pb-meta { flex-shrink: 0; font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-variant-numeric: tabular-nums; }\n[data-edrv-view] .edrv-pathbar .edrv-pb-status { color: var(--dsw-alias-label-secondary, #52606d); }\n[data-edrv-view] .edrv-path-input { flex: 1; min-width: 140px; height: 24px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 12px; outline: none; }\n[data-edrv-view] .edrv-search-wrap { position: relative; flex-shrink: 0; display: flex; align-items: center; padding: 2px 8px 2px 4px; }\n[data-edrv-view] .edrv-search { width: 190px; height: 24px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 12px; outline: none; }\n[data-edrv-view] .edrv-search:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-search-pop { position: absolute; top: calc(100% + 4px); right: 8px; width: min(460px, calc(100vw - 24px)); max-height: 300px; overflow: auto; background: var(--dsw-alias-bg-overlay, #1c1c1c); border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 10px; box-shadow: 0 6px 20px rgba(0,0,0,.4); z-index: 60; padding: 4px; }\n[data-edrv-view] .edrv-search-item { display: flex; flex-direction: column; gap: 1px; padding: 5px 8px; border-radius: 6px; cursor: pointer; }\n[data-edrv-view] .edrv-search-item:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.07)); }\n[data-edrv-view] .edrv-search-item .n { color: var(--dsw-alias-label-primary, #eee); font-size: 12px; word-break: break-all; }\n[data-edrv-view] .edrv-search-item .d { color: var(--dsw-alias-label-tertiary, #888); font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-search-empty { padding: 8px; font-size: 12px; color: var(--dsw-alias-label-tertiary, #888); }\n[data-edrv-view] .edrv-btn-mini { font-size: 11px; padding: 2px 9px; border: none; border-radius: 999px; cursor: pointer; color: #fff; font-weight: 600; white-space: nowrap; }\n[data-edrv-view] .edrv-btn-keep { background: var(--dsw-alias-state-success-primary, #2e9e44); }\n[data-edrv-view] .edrv-btn-undo { background: var(--dsw-alias-state-warn-primary, #d97706); }\n[data-edrv-view] .edrv-btn-mini:disabled { opacity: .45; cursor: default; }\n[data-edrv-view] .edrv-statusbar { display: flex; align-items: center; gap: 10px; padding: 3px 10px; border-top: 1px solid var(--dsw-alias-border-l1, #333); background: var(--dsw-alias-bg-layer-1, transparent); font-size: 11px; color: var(--dsw-alias-label-tertiary, #888); flex-shrink: 0; white-space: nowrap; overflow: hidden; }\n[data-edrv-view] .edrv-statusbar .edrv-sp-path { flex: 1; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-statusbar .edrv-sp-lsp { flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-statusbar .edrv-sp-progress-message { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--dsw-alias-label-secondary, #52606d); }\n[data-edrv-view] .edrv-statusbar .edrv-sp-progress { flex: 0 0 auto; min-width: 36px; text-align: right; font-variant-numeric: tabular-nums; color: var(--dsw-alias-label-secondary, #52606d); }\n[data-edrv-view] .edrv-lsp-status-dot { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; background: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-lsp-status-dot.ready { background: var(--dsw-alias-state-success-primary, #0f9d58); }\n[data-edrv-view] .edrv-lsp-status-dot.busy { background: var(--dsw-alias-state-warn-primary, #d97706); animation: edrv-lsp-pulse 1.2s ease-in-out infinite; }\n@keyframes edrv-lsp-pulse { 50% { opacity: .45; } }\n/* Ctrl+hover 可导航标识符下划线提示(绑定 Monaco inlineClassName 装饰) */\n[data-edrv-view] .edrv-nav-underline { text-decoration: underline; text-decoration-color: var(--dsw-alias-interactive-primary, #4fc1ff); text-underline-offset: 1px; cursor: pointer; }\n[data-edrv-view] .edrv-diffchip { font-size: 11px; padding: 2px 10px; border: 1px solid var(--dsw-alias-border-l1, #333); border-radius: 999px; background: var(--dsw-alias-bg-layer-2, transparent); color: var(--dsw-alias-state-warn-primary, #b7791f); cursor: pointer; white-space: nowrap; flex-shrink: 0; }\n[data-edrv-view] .edrv-chip-btn { font-size: 12px; padding: 2px 6px; border: none; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); cursor: pointer; border-radius: 4px; flex-shrink: 0; }\n[data-edrv-view] .edrv-chip-btn:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-chip-btn:disabled { opacity: .35; cursor: default; }\n[data-edrv-view] .edrv-chip-btn:disabled:hover { background: transparent; }\n[data-edrv-view] .edrv-mn-add-line { background: rgba(15,157,88,.10); }\n[data-edrv-view] .edrv-mn-gutter-add { color: #0f9d58 !important; font-weight: 700; display: flex !important; align-items: center; justify-content: center; }\n[data-edrv-view] .edrv-mn-gutter-add::before { content: \"+\"; }\n[data-edrv-view] .edrv-del-zone { background: #fdeaea; border-top: 1px solid rgba(217,83,79,.35); border-bottom: 1px solid rgba(217,83,79,.35); box-shadow: inset 0 0 0 1px rgba(217,83,79,.12); }\n[data-edrv-view] .edrv-del-row { white-space: pre; font-family: var(--ds-font-family-code, ui-monospace, monospace); font-size: 12.5px; line-height: 20px; color: #c0392b; }\n[data-edrv-view] .edrv-del-text { display: inline-block; white-space: pre; }\n[data-edrv-view] .edrv-minus-overlay { position: absolute; left: 0; top: 0; width: 100%; height: 100%; max-width: 100%; overflow: visible; pointer-events: none; z-index: 6; }\n[data-edrv-view] .edrv-minus-item { position: absolute; box-sizing: border-box; max-width: 100%; overflow: hidden; }\n[data-edrv-view] .edrv-minus-item::before { content: ''; position: absolute; left: 4px; top: 50%; width: 8px; height: 2px; transform: translateY(-50%); border-radius: 2px; background: #d9534f; }\n[data-edrv-view] .edrv-monaco-host { flex: 1 1 auto; min-width: 0; min-height: 0; position: relative; overflow: hidden; }\n[data-edrv-view] .edrv-monaco-host > div { position: absolute; inset: 0; min-width: 0; min-height: 0; }\n[data-edrv-view] .edrv-imgview { flex: 1 1 auto; min-width: 0; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }\n[data-edrv-view] .edrv-imgview-bar { display: flex; align-items: center; gap: 8px; height: 34px; padding: 0 10px; flex-shrink: 0; border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); background: var(--dsw-alias-bg-layer-1, transparent); }\n[data-edrv-view] .edrv-imgview-meta { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); white-space: nowrap; }\n[data-edrv-view] .edrv-imgview-stage { flex: 1 1 auto; min-height: 0; display: flex; align-items: center; justify-content: center; overflow: auto; padding: 14px; background-color: var(--dsw-alias-bg-layer-1, #f0f4f4); background-image: conic-gradient(rgba(128,128,128,.14) 25%, transparent 0 50%, rgba(128,128,128,.14) 0 75%, transparent 0); background-size: 16px 16px; }\n[data-edrv-view] .edrv-imgview-img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 4px; box-shadow: 0 2px 12px rgba(31,41,51,.18); }\n[data-edrv-view] .edrv-imgview-broken { display: flex; flex-direction: column; align-items: center; gap: 10px; font-size: 13px; color: var(--dsw-alias-label-tertiary, #777); }\n[data-edrv-view] .edrv-pdf-host { flex: 1 1 auto; min-width: 0; min-height: 0; position: relative; overflow: hidden; }\n[data-edrv-view] .edrv-pdf-host > .edrv-pdf { position: absolute; inset: 0; }\n[data-edrv-view] .edrv-pdf { min-width: 0; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }\n[data-edrv-view] .edrv-pdf-bar { display: flex; align-items: center; gap: 8px; height: 34px; padding: 0 10px; flex-shrink: 0; border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); background: var(--dsw-alias-bg-layer-1, transparent); }\n[data-edrv-view] .edrv-pdf-page { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); white-space: nowrap; min-width: 52px; text-align: center; }\n[data-edrv-view] .edrv-pdf-zoom { min-width: 26px; text-align: center; padding: 3px 7px; }\n[data-edrv-view] .edrv-pdf-sep { width: 1px; height: 16px; background: var(--dsw-alias-border-l1, #e0e6e8); margin: 0 2px; }\n[data-edrv-view] .edrv-pdf-mode-on { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.12)); color: var(--dsw-alias-brand-primary, #0f9d58); border-color: var(--dsw-alias-brand-primary, #0f9d58); }\n[data-edrv-view] .edrv-pdf-dirty { color: var(--dsw-alias-state-warn-primary, #d97706); border-color: var(--dsw-alias-state-warn-primary, #d97706); }\n[data-edrv-view] .edrv-pdf-stage { position: absolute; top: 34px; left: 0; right: 0; bottom: 0; overflow: auto; }\n[data-edrv-view] .edrv-pdf-stage .edrv-pdf-viewer { margin: 0 auto; }\n[data-edrv-view] .edrv-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; height: 100%; color: var(--dsw-alias-label-tertiary, #777); font-size: 13px; }\n[data-edrv-view] .edrv-diffbar { position: absolute; left: 0; right: 0; bottom: 10px; margin: 0 auto; z-index: 25; width: fit-content; max-width: calc(100% - 20px); border-radius: 12px; background: var(--dsw-specific-tip, var(--dsw-alias-bg-layer-2, #f0f4f4)); border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); box-shadow: none; overflow: visible; display: flex; flex-direction: column; }\n[data-edrv-view] .edrv-editor-area > .edrv-diffbar { max-height: calc(100% - 20px); }\n[data-edrv-view] .edrv-diffbar-row { display: flex; align-items: center; gap: 6px; height: 36px; padding: 4px 5px 4px 12px; flex-wrap: nowrap; }\n[data-edrv-view] .edrv-diffbar-count { font-size: 12px; font-weight: 600; color: var(--dsw-alias-label-primary, #1f2933); min-width: 42px; text-align: center; white-space: nowrap; cursor: pointer; }\n[data-edrv-view] .edrv-diffbar-count.edrv-count-file { min-width: 64px; cursor: default; }\n[data-edrv-view] .edrv-diffbar-file { flex: 1; min-width: 0; font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-pill { font-size: 11px; padding: 3px 10px; border: none; border-radius: 999px; cursor: pointer; white-space: nowrap; font-weight: 600; }\n[data-edrv-view] .edrv-pill-keep { background: #e8f8e8; color: #0f7a45; border: 1px solid rgba(15,157,88,.4); }\n[data-edrv-view] .edrv-pill-undo { background: #fdeaea; color: #c0392b; border: 1px solid rgba(217,83,79,.4); }\n[data-edrv-view] .edrv-pill-ghost { background: #ffffff; color: var(--dsw-alias-label-secondary, #52606d); border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-pill:disabled { opacity: .45; cursor: default; }\n[data-edrv-view] .edrv-diffbar-menu { position: absolute; right: 8px; bottom: calc(100% + 6px); z-index: 45; min-width: 160px; border-radius: 10px; background: var(--dsw-alias-bg-overlay, #ffffff); border: 1px solid var(--dsw-alias-border-l2, #cbd2d9); box-shadow: 0 6px 20px rgba(31,41,51,.16); padding: 4px; display: flex; flex-direction: column; gap: 2px; }\n[data-edrv-view] .edrv-diffmenu-item { display: flex; align-items: center; gap: 8px; font-size: 12px; padding: 6px 10px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-primary, #1f2933); cursor: pointer; text-align: left; }\n[data-edrv-view] .edrv-diffmenu-item:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-diffmenu-item.danger { color: var(--dsw-alias-state-error-primary, #d9534f); }\n[data-edrv-view] .edrv-diffmenu-sep { height: 1px; margin: 2px 4px; background: var(--dsw-alias-border-l1, #e0e6e8); }\n/* 编辑区 / Tab 右键菜单(添加文件/选中内容到对话) */\n[data-edrv-view] .edrv-ctxmenu { position: fixed; z-index: 71; min-width: 200px; max-width: 320px; border-radius: 10px; background: var(--dsw-alias-bg-overlay, #ffffff); border: 1px solid var(--dsw-alias-border-l2, #cbd2d9); box-shadow: 0 8px 26px rgba(31,41,51,.2); padding: 4px; display: flex; flex-direction: column; gap: 1px; }\n[data-edrv-view] .edrv-ctxmenu-item { display: flex; align-items: center; gap: 8px; font-size: 12px; line-height: 18px; padding: 7px 10px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-primary, #1f2933); cursor: pointer; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-ctxmenu-item:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-ctxmenu-item.edrv-ctxmenu-danger { color: var(--dsw-alias-state-error-primary, #d9534f); }\n[data-edrv-view] .edrv-ctxmenu-item:disabled,\n[data-edrv-view] .edrv-ctxmenu-item.edrv-ctxmenu-disabled { color: var(--dsw-alias-label-disabled, #b0b7c0); cursor: default; background: transparent; }\n[data-edrv-view] .edrv-ctxmenu-sep { height: 1px; margin: 3px 4px; background: var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-diffbar-body { max-height: 130px; max-width: min(560px, calc(100vw - 40px)); overflow: auto; padding: 4px 8px 8px; display: flex; flex-direction: column; gap: 4px; border-top: 1px solid var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-diffrow { display: flex; align-items: center; gap: 8px; padding: 3px 6px; border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); border-radius: 6px; background: var(--dsw-alias-bg-layer-2, #f0f4f4); cursor: pointer; flex-wrap: wrap; }\n[data-edrv-view] .edrv-diffrow:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-diffrow-l { font-size: 11px; color: var(--dsw-alias-label-primary, #1f2933); min-width: 74px; font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-diffrow-o { font-size: 11px; color: var(--dsw-alias-state-error-primary, #d9534f); font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-diffrow-n { font-size: 11px; color: var(--dsw-alias-state-success-primary, #0f9d58); font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-diffrow-tag { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-diffrow-stale { border-color: rgba(217,119,6,.5); cursor: default; }\n[data-edrv-view] .edrv-diffbox-others { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding: 4px 2px 0; border-top: 1px solid var(--dsw-alias-border-l1, #e0e6e8); margin-top: 2px; }\n[data-edrv-view] .edrv-diffrow-file { font-size: 11px; padding: 2px 10px; border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); border-radius: 999px; background: var(--dsw-alias-bg-layer-2, #f0f4f4); color: var(--dsw-alias-label-secondary, #52606d); cursor: pointer; white-space: nowrap; max-width: 200px; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-diffrow-file:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); color: var(--dsw-alias-label-primary, #1f2933); }\n/* 编辑区 hover 差异块的 Keep/Undo 浮层 */\n[data-edrv-view] .edrv-hoveract { position: absolute; z-index: 30; display: flex; align-items: center; gap: 4px; padding: 2px 6px; border-radius: 8px; background: var(--dsw-alias-bg-overlay, #ffffff); border: 1px solid var(--dsw-alias-border-l2, #cbd2d9); box-shadow: 0 4px 14px rgba(31,41,51,.14); }\n[data-edrv-view] .edrv-launch { position: absolute; left: 12px; right: 12px; bottom: 12px; z-index: 40; border-radius: 10px; background: var(--dsw-alias-bg-overlay, #1c1c1c); border: 1px solid var(--dsw-alias-border-l2, #555); box-shadow: 0 6px 24px rgba(0,0,0,.5); display: flex; flex-direction: column; max-height: 60%; overflow: hidden; }\n[data-edrv-view] .edrv-launch-head { display: flex; align-items: center; gap: 6px; padding: 6px 8px; border-bottom: 1px solid var(--dsw-alias-border-l1, #333); }\n[data-edrv-view] .edrv-launch-tab { font-size: 12px; padding: 3px 12px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); cursor: pointer; }\n[data-edrv-view] .edrv-launch-tab.on { background: var(--dsw-alias-bg-layer-2, transparent); color: var(--dsw-alias-label-primary, #eee); font-weight: 600; }\n[data-edrv-view] .edrv-launch-body { flex: 1; min-height: 0; overflow: auto; padding: 6px 8px; display: flex; flex-direction: column; gap: 4px; }\n[data-edrv-view] .edrv-launch-row { display: flex; align-items: center; gap: 8px; padding: 3px 6px; border: 1px solid var(--dsw-alias-border-l1, #333); border-radius: 6px; cursor: pointer; flex-wrap: wrap; }\n[data-edrv-view] .edrv-launch-row:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-launch-path { flex: 1; min-width: 0; font-size: 12px; color: var(--dsw-alias-label-primary, #eee); word-break: break-all; }\n[data-edrv-view] .edrv-launch-cnt { font-size: 11px; color: var(--dsw-alias-label-tertiary, #888); white-space: nowrap; }\n[data-edrv-view] .edrv-launch-arch { display: flex; flex-direction: column; gap: 6px; }\n[data-edrv-view] .monaco-editor { overflow: hidden !important; }\n[data-edrv-view] .monaco-editor .sticky-widget { z-index: 30 !important; background: var(--dsw-alias-bg-base, #f8f8f8) !important; }\n[data-edrv-view] .monaco-editor .sticky-widget .sticky-line-content,\n[data-edrv-view] .monaco-editor .sticky-widget .sticky-line-number { background: var(--dsw-alias-bg-base, #f8f8f8) !important; }\n[data-edrv-view] .monaco-editor, [data-edrv-view] .monaco-editor .margin, [data-edrv-view] .monaco-editor-background { background: transparent !important; }\n[data-edrv-view] .monaco-editor .scrollbar .slider { background: rgba(128,128,128,.3) !important; }\n[data-edrv-view] .edrv-loading { gap: 8px; padding: 20px; }\n[data-edrv-view] .edrv-loading-title { color: var(--dsw-alias-label-primary, #1f2933); font-size: 13px; }\n[data-edrv-view] .edrv-progress { width: min(360px, 72%); height: 6px; overflow: hidden; border-radius: 999px; background: var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-progress-value { height: 100%; border-radius: inherit; background: var(--dsw-alias-brand-primary, #0f9d58); transition: width .24s ease; }\n[data-edrv-view] .edrv-loading-percent { color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 11px; font-variant-numeric: tabular-nums; }\n@media (prefers-reduced-motion: reduce) {\n [data-edrv-view] .edrv-progress-value { transition: none; }\n}\n\n/* ===== 唯一会话级差异 dock(遵循 DSH todo/queue 原生布局) ===== */\n[data-edrv-diff-dock-shell] {\n box-sizing: border-box;\n width: calc(100% - var(--dsh-composer-side-clearance) - var(--dsh-composer-side-clearance) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));\n max-width: calc(var(--dsh-composer-card-max-width) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));\n margin: 0 auto;\n padding: 0;\n flex: none;\n border: 1px solid var(--dsw-alias-border-l1, #e0e6e8);\n border-radius: 12px;\n background: var(--dsw-specific-tip, var(--dsw-alias-bg-layer-2, transparent));\n box-shadow: none;\n overflow: hidden;\n}\n[data-edrv-diff-dock-shell] .edrv-diffbar-dock {\n box-sizing: border-box;\n position: relative;\n left: auto;\n right: auto;\n bottom: auto;\n z-index: auto;\n width: 100%;\n max-width: none;\n margin: 0;\n display: flex;\n flex-direction: column;\n border: none;\n border-radius: 0;\n background: transparent;\n box-shadow: none;\n overflow: visible;\n}\n[data-edrv-diff-dock-shell] .edrv-diffbar-row { min-height: 36px; padding: 6px 12px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-dock-row { min-height: 36px; padding: 6px 12px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-body { max-height: 180px; overflow: auto; padding: 6px 12px 10px; border-top: 1px solid var(--dsw-alias-border-l1); }\n[data-edrv-diff-dock-shell] .edrv-diffbar-dock-button { box-sizing: border-box; display: flex; align-items: center; justify-content: center; width: 100%; height: 24px; border: none; border-radius: 8px; padding: 0 12px; background: transparent; color: var(--dsw-alias-label-primary); font-size: 13px; font-weight: 500; line-height: 24px; text-align: center; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-dock-button:hover { background: var(--dsw-alias-interactive-bg-hover); }\n[data-edrv-diff-dock-shell] .edrv-diffbar-count { display: inline-flex; align-items: center; color: var(--dsw-alias-label-primary); font-family: Inter, var(--dsw-font-family); font-size: 13px; font-weight: 500; line-height: 24px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-file { display: inline-flex; align-items: center; color: var(--dsw-alias-label-tertiary); font-family: Inter, var(--dsw-font-family); font-size: 13px; font-weight: 400; line-height: 24px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-editor-row { display: flex; align-items: center; height: 36px; min-height: 36px; padding: 4px 12px; overflow-x: auto; scrollbar-width: thin; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-editor-content { display: flex; align-items: center; gap: 10px; width: 100%; min-width: max-content; min-height: 28px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-nav,\n[data-edrv-diff-dock-shell] .edrv-diffbar-files,\n[data-edrv-diff-dock-shell] .edrv-diffbar-actions { display: flex; align-items: center; gap: 6px; flex: none; height: 28px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-actions { margin-left: auto; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-details-toggle { display: inline-flex; align-items: center; justify-content: center; width: 28px; min-width: 28px; padding: 0; font-size: 13px; line-height: 24px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-details-toggle svg { width: 14px; height: 14px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-files { min-width: 0; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-files .edrv-diffbar-file { min-width: 72px; max-width: 240px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-progress { min-width: 0; color: var(--dsw-alias-label-tertiary); font-family: Inter, var(--dsw-font-family); font-size: 13px; font-weight: 400; line-height: 24px; font-variant-numeric: tabular-nums; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-summary { min-width: 0; color: var(--dsw-alias-label-tertiary); font-family: Inter, var(--dsw-font-family); font-size: 13px; font-weight: 400; line-height: 24px; }\n[data-edrv-diff-dock-shell] .edrv-pill { box-sizing: border-box; height: 28px; padding: 0 9px; border: none; border-radius: 999px; cursor: pointer; white-space: nowrap; font-size: 11px; line-height: 26px; font-weight: 600; }\n[data-edrv-diff-dock-shell] .edrv-pill-keep { background: var(--dsw-alias-state-success-tertiary); color: var(--dsw-alias-state-success-primary); border: 1px solid var(--dsw-alias-state-success-secondary); }\n[data-edrv-diff-dock-shell] .edrv-pill-undo { background: var(--dsw-alias-state-error-tertiary); color: var(--dsw-alias-state-error-primary); border: 1px solid var(--dsw-alias-state-error-secondary); }\n[data-edrv-diff-dock-shell] .edrv-pill-ghost { background: transparent; color: var(--dsw-alias-label-secondary); border: 1px solid var(--dsw-alias-border-l1); }\n[data-edrv-diff-dock-shell] .edrv-pill:hover:not(:disabled) { background-color: var(--dsw-alias-interactive-bg-hover); }\n[data-edrv-diff-dock-shell] .edrv-pill:focus-visible { outline: 2px solid var(--dsw-alias-label-tertiary); outline-offset: -2px; }\n[data-edrv-diff-dock-shell] .edrv-pill:disabled { opacity: .45; cursor: default; }\n[data-edrv-diff-dock-shell] .edrv-diffrow { display: flex; align-items: center; gap: 8px; padding: 3px 6px; border: 1px solid var(--dsw-alias-border-l1); border-radius: 6px; background: transparent; cursor: pointer; flex-wrap: wrap; }\n[data-edrv-diff-dock-shell] .edrv-diffrow:hover { background: var(--dsw-alias-interactive-bg-hover); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-l { color: var(--dsw-alias-label-primary); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-o { color: var(--dsw-alias-state-error-primary); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-n { color: var(--dsw-alias-state-success-primary); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-tag { color: var(--dsw-alias-label-tertiary); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-stale { border-color: var(--dsw-alias-state-warn-secondary); cursor: default; }\n[data-edrv-diff-dock-shell] .edrv-diffbox-others { border-top: 1px solid var(--dsw-alias-border-l1); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-file { border-color: var(--dsw-alias-border-l1); background: transparent; color: var(--dsw-alias-label-secondary); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-file:hover { background: var(--dsw-alias-interactive-bg-hover); color: var(--dsw-alias-label-primary); }\n[data-edrv-diff-dock-shell] .edrv-diff-details { display: flex; flex-direction: column; gap: 2px; padding: 6px 12px 8px; border-top: 1px solid var(--dsw-alias-border-l1); }\n[data-edrv-diff-dock-shell] .edrv-diff-details .edrv-diffmenu-item { display: flex; align-items: center; width: 100%; min-height: 28px; gap: 8px; padding: 4px 8px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-primary); cursor: pointer; text-align: left; font-size: 12px; line-height: 20px; }\n[data-edrv-diff-dock-shell] .edrv-diff-details .edrv-diffmenu-item:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }\n[data-edrv-diff-dock-shell] .edrv-diff-details .edrv-diffmenu-item.danger { color: var(--dsw-alias-state-error-primary); }\n[data-edrv-diff-dock-shell] .edrv-diff-details .edrv-diffmenu-item:disabled { opacity: .45; cursor: default; }\n[data-edrv-diff-dock-shell] .edrv-diff-details .edrv-diffmenu-sep { height: 1px; margin: 2px 4px; background: var(--dsw-alias-border-l1); }\n@media (max-width: 620px) {\n [data-edrv-diff-dock-shell] .edrv-diffbar-editor-content { width: max-content; }\n [data-edrv-diff-dock-shell] .edrv-diffbar-files .edrv-diffbar-file { max-width: 160px; }\n}\n\n/* ===== 侧边栏(活动栏 + 面板区 + 文件树) ===== */\n[data-edrv-view] .edrv-editor-row { display: flex; flex: 1 1 auto; min-width: 0; min-height: 0; overflow: hidden; }\n[data-edrv-view] .edrv-main-col { box-sizing: border-box; min-width: 0; min-height: 0; overflow: hidden; }\n[data-edrv-view] .edrv-main-col > .edrv-pathbar,\n[data-edrv-view] .edrv-main-col > .edrv-tabs { flex: 0 0 auto; }\n[data-edrv-view] .edrv-editor-area { position: relative; display: flex; flex: 1 1 auto; flex-direction: column; min-width: 0; min-height: 0; overflow: hidden; }\n[data-edrv-view] .edrv-sidebar { display: flex; flex-direction: row; flex-shrink: 1; min-width: 0; height: 100%; background: var(--dsw-alias-bg-layer-1, #ffffff); border-right: 1px solid var(--dsw-alias-border-l1, #e0e6e8); overflow: hidden; }\n[data-edrv-view] .edrv-rail { display: flex; flex-direction: column; align-items: center; width: 44px; flex-shrink: 0; padding: 6px 0; background: var(--dsw-alias-bg-layer-2, #f0f4f4); border-right: 1px solid var(--dsw-alias-border-l1, #e0e6e8); gap: 4px; }\n[data-edrv-view] .edrv-rail-btn { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border: none; border-radius: 8px; background: transparent; color: var(--dsw-alias-label-secondary, #52606d); cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-rail-btn:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-rail-btn.edrv-rail-on { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.12)); color: var(--dsw-alias-label-primary, #1f2933); box-shadow: inset 2px 0 0 var(--dsw-alias-brand-primary, #0f9d58); }\n[data-edrv-view] .edrv-rail-icon { font-size: 15px; line-height: 1; }\n[data-edrv-view] .edrv-rail-badge { position: absolute; top: 2px; right: 2px; min-width: 14px; height: 14px; padding: 0 3px; border-radius: 999px; background: var(--dsw-alias-brand-primary, #0f9d58); color: #fff; font-size: 9px; font-weight: 600; line-height: 14px; text-align: center; box-sizing: border-box; }\n[data-edrv-view] .edrv-side-body { flex: 1; min-width: 0; min-height: 0; display: flex; overflow: hidden; }\n[data-edrv-view] .edrv-side-panel { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; position: relative; }\n[data-edrv-view] .edrv-side-head { display: flex; align-items: center; gap: 8px; height: 34px; padding: 0 10px 0 12px; border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); flex-shrink: 0; }\n[data-edrv-view] .edrv-side-title { font-size: 12px; font-weight: 600; color: var(--dsw-alias-label-primary, #1f2933); white-space: nowrap; }\n[data-edrv-view] .edrv-side-root { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-side-btn { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #52606d); font-size: 12px; cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-side-btn:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-tree { flex: 1; min-height: 0; overflow: auto; padding: 4px 6px 12px; font-size: 12px; }\n[data-edrv-view] .edrv-tree-row { display: flex; align-items: center; gap: 4px; height: 22px; padding-right: 6px; border-radius: 5px; color: var(--dsw-alias-label-primary, #1f2933); cursor: pointer; white-space: nowrap; }\n[data-edrv-view] .edrv-tree-row:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-tree-row.edrv-tree-active { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.14)); }\n[data-edrv-view] .edrv-tree-row.edrv-tree-context { box-shadow: inset 0 0 0 1px var(--dsw-alias-brand-primary, #0f9d58); background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.12)); }\n[data-edrv-view] .edrv-tree-chev { width: 12px; flex-shrink: 0; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 10px; text-align: center; }\n[data-edrv-view] .edrv-tree-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-tree-name.edrv-tree-dim { color: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-tree-badge { min-width: 14px; height: 14px; padding: 0 4px; border-radius: 999px; background: var(--dsw-alias-state-warn-primary, #d97706); color: #fff; font-size: 9px; font-weight: 600; line-height: 14px; text-align: center; box-sizing: border-box; flex-shrink: 0; }\n[data-edrv-view] .edrv-tree-loading { height: 22px; line-height: 22px; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 11px; }\n[data-edrv-view] .edrv-tree-error { display: flex; align-items: center; gap: 8px; margin: 4px 2px 6px; padding: 6px 8px; border: 1px solid rgba(217,83,79,.4); border-radius: 6px; background: #fdeaea; color: var(--dsw-alias-state-error-primary, #d9534f); font-size: 11px; }\n/* 大纲面板:kind 字形 / detail / 行号 */\n[data-edrv-view] .edrv-outline-kind { display: inline-flex; align-items: center; justify-content: center; width: 14px; flex-shrink: 0; font-size: 12px; font-weight: 600; text-align: center; }\n[data-edrv-view] .edrv-outline-kind.edrv-ol-func { color: var(--dsw-alias-brand-primary, #0f9d58); }\n[data-edrv-view] .edrv-outline-kind.edrv-ol-type { color: var(--dsw-alias-label-primary, #1f2933); }\n[data-edrv-view] .edrv-outline-kind.edrv-ol-data { color: var(--dsw-alias-state-warn-primary, #d97706); }\n[data-edrv-view] .edrv-outline-kind.edrv-ol-ns { color: var(--dsw-alias-label-secondary, #52606d); }\n[data-edrv-view] .edrv-outline-kind.edrv-ol-key { color: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-outline-detail { flex-shrink: 0; max-width: 40%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 11px; }\n[data-edrv-view] .edrv-outline-ln { flex-shrink: 0; padding-right: 2px; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 10px; font-variant-numeric: tabular-nums; }\n[data-edrv-view] .edrv-side-resize { width: 5px; flex-shrink: 0; cursor: col-resize; background: transparent; }\n[data-edrv-view] .edrv-side-resize:hover { background: var(--dsw-alias-brand-primary, #0f9d58); opacity: .35; }\n[data-edrv-view] .edrv-chip-btn.edrv-chip-on { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.12)); color: var(--dsw-alias-label-primary, #1f2933); }\n\n/* ===== 侧栏形态(betterSidebar 面板内编辑区) ===== */\n[data-edrv-view][data-edrv-layout='side'] { box-sizing: border-box; height: 100%; }\n\n/* ===== 侧边栏引导条(旧页签形态、未装 betterSidebar 时) ===== */\n[data-edrv-view] .edrv-side-hint { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; flex-wrap: wrap; padding: 6px 12px; font-size: 12px; color: var(--dsw-alias-label-secondary, #52606d); background: var(--dsw-specific-tip, var(--dsw-alias-bg-layer-2, #f0f4f4)); border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-side-hint-text { white-space: nowrap; }\n[data-edrv-view] .edrv-side-hint-cmd { font-size: 11px; padding: 2px 6px; border-radius: 6px; background: var(--dsw-alias-bg-layer-1, #ffffff); border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); color: var(--dsw-alias-label-primary, #1f2933); white-space: nowrap; }\n[data-edrv-view] .edrv-side-hint-close { margin-left: auto; border: none; background: transparent; color: var(--dsw-alias-label-tertiary, #9aa5b1); cursor: pointer; font-size: 14px; line-height: 1; padding: 2px 6px; border-radius: 6px; flex-shrink: 0; }\n[data-edrv-view] .edrv-side-hint-close:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); color: var(--dsw-alias-label-primary, #1f2933); }\n\n/* ===== search panel (sidebar, VSCode search view) ===== */\n[data-edrv-view] .edrv-search-panel { display: flex; flex-direction: column; min-height: 0; flex: 1; padding: 6px; gap: 4px; }\n[data-edrv-view] .edrv-search-qrow { display: flex; gap: 4px; }\n[data-edrv-view] .edrv-search-input { flex: 1; min-width: 0; height: 26px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 12px; outline: none; }\n[data-edrv-view] .edrv-search-input:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-search-opts { display: flex; align-items: center; gap: 2px; flex: 0 0 auto; }\n[data-edrv-view] .edrv-search-opt { min-width: 24px; height: 22px; padding: 0 6px; border: 1px solid transparent; border-radius: 5px; background: transparent; color: var(--dsw-alias-label-secondary, #52606d); font-size: 11px; font-family: var(--ds-font-family-code, ui-monospace, monospace); cursor: pointer; }\n[data-edrv-view] .edrv-search-opt:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-search-opt.on { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.14)); color: var(--dsw-alias-label-primary, #1f2933); border-color: var(--dsw-alias-border-l2, #d5dde3); }\n[data-edrv-view] .edrv-search-spacer { flex: 1; }\n[data-edrv-view] .edrv-search-summary { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); padding: 2px 4px; }\n[data-edrv-view] .edrv-search-results { flex: 1; min-height: 0; overflow: auto; font-size: 12px; }\n[data-edrv-view] .edrv-search-group { margin-bottom: 2px; }\n[data-edrv-view] .edrv-search-file { display: flex; align-items: center; gap: 4px; height: 22px; padding: 0 4px; border-radius: 5px; color: var(--dsw-alias-label-primary, #1f2933); cursor: pointer; white-space: nowrap; }\n[data-edrv-view] .edrv-search-file:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-search-chev { width: 12px; flex-shrink: 0; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 10px; text-align: center; }\n[data-edrv-view] .edrv-search-fname { font-weight: 600; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-search-fdir { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 11px; }\n[data-edrv-view] .edrv-search-fcount { flex-shrink: 0; min-width: 16px; height: 15px; padding: 0 4px; border-radius: 999px; background: var(--dsw-alias-bg-layer-2, #f0f4f4); color: var(--dsw-alias-label-secondary, #52606d); font-size: 10px; line-height: 15px; text-align: center; }\n[data-edrv-view] .edrv-search-line { display: flex; gap: 6px; padding: 1px 4px 1px 16px; border-radius: 4px; color: var(--dsw-alias-label-primary, #1f2933); cursor: pointer; overflow: hidden; }\n[data-edrv-view] .edrv-search-line.alt { background: var(--dsw-alias-bg-layer-1, #ffffff); }\n[data-edrv-view] .edrv-search-line:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-search-ln { flex-shrink: 0; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 11px; min-width: 26px; text-align: right; user-select: none; }\n[data-edrv-view] .edrv-search-text { overflow: hidden; text-overflow: ellipsis; white-space: pre; font-family: var(--ds-font-family-code, ui-monospace, monospace); font-size: 11px; }\n[data-edrv-view] .edrv-search-hit { background: var(--dsw-alias-state-warn-primary, #e5b93f); color: #1f2933; border-radius: 2px; padding: 0 1px; }\n[data-edrv-view] .edrv-search-empty { padding: 8px 4px; font-size: 12px; color: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-search-error { padding: 6px 8px; border: 1px solid rgba(217,83,79,.4); border-radius: 6px; background: #fdeaea; color: var(--dsw-alias-state-error-primary, #d9534f); font-size: 11px; }\n[data-edrv-view] .edrv-search-warn { padding: 6px 8px; border: 1px solid rgba(240,173,78,.45); border-radius: 6px; background: #fdf6e3; color: #b8860b; font-size: 11px; word-break: break-all; }\n\n/* include/exclude filter rows (collapsible) */\n[data-edrv-view] .edrv-search-rows { display: flex; flex-direction: column; gap: 4px; padding: 2px 0 4px; }\n[data-edrv-view] .edrv-search-row { display: flex; align-items: center; gap: 4px; }\n[data-edrv-view] .edrv-search-field { flex: 1; min-width: 0; height: 24px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 11px; outline: none; }\n[data-edrv-view] .edrv-search-field:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-search-field.dim { opacity: .45; }\n[data-edrv-view] .edrv-search-field::placeholder { color: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-search-toggle { min-width: 24px; height: 24px; padding: 0 5px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #52606d); font-size: 12px; line-height: 1; cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-search-toggle:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-search-toggle.on { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.14)); color: var(--dsw-alias-label-primary, #1f2933); border-color: var(--dsw-alias-brand-primary, #0f9d58); }\n[data-edrv-view] .edrv-search-toggle:disabled { opacity: .4; cursor: default; }\n\n/* ===== rules panel (sidebar, Codebuddy rules view) ===== */\n[data-edrv-view] .edrv-rules-panel { display: flex; flex-direction: column; min-width: 0; min-height: 0; flex: 1; padding: 6px; gap: 4px; }\n[data-edrv-view] .edrv-rules-tabs { display: flex; align-items: center; gap: 2px; flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-tab { height: 24px; padding: 0 10px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #52606d); font-size: 12px; cursor: pointer; }\n[data-edrv-view] .edrv-rules-tab:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-rules-tab.on { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.14)); color: var(--dsw-alias-label-primary, #1f2933); font-weight: 600; }\n[data-edrv-view] .edrv-rules-new { margin-left: auto; height: 24px; padding: 0 10px; border: 1px solid var(--dsw-alias-border-l2, #cbd2d9); border-radius: 6px; background: var(--dsw-alias-bg-layer-1, #fff); color: var(--dsw-alias-label-primary, #1f2933); font-size: 11px; cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-rules-new:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-rules-ws-line { font-size: 11px; color: var(--dsw-alias-label-secondary, #52606d); padding: 0 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 0 0 auto; user-select: none; }\n[data-edrv-view] .edrv-rules-hint { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); padding: 0 2px; flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-list { flex: 1; min-height: 0; overflow: auto; }\n[data-edrv-view] .edrv-rules-row { display: flex; align-items: center; gap: 4px; padding: 6px 4px; border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); border-radius: 6px; }\n[data-edrv-view] .edrv-rules-row:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-rules-row.off .edrv-rules-main { opacity: .5; }\n[data-edrv-view] .edrv-rules-main { flex: 1; min-width: 0; cursor: pointer; overflow: hidden; }\n[data-edrv-view] .edrv-rules-line1 { display: flex; align-items: center; gap: 6px; min-width: 0; }\n[data-edrv-view] .edrv-rules-sub { display: flex; align-items: center; gap: 5px; margin-top: 3px; min-width: 0; }\n[data-edrv-view] .edrv-rules-sublabel { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); flex-shrink: 0; }\n[data-edrv-view] .edrv-rules-file { font-weight: 600; font-size: 12px; color: var(--dsw-alias-label-primary, #1f2933); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-rules-path { font-size: 10px; color: var(--dsw-alias-label-tertiary, #9aa5b1); flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-rules-type { flex-shrink: 0; height: 15px; padding: 0 5px; border-radius: 999px; font-size: 10px; line-height: 15px; }\n[data-edrv-view] .edrv-rules-type-always { background: rgba(15,157,88,.15); color: #0b7c46; }\n[data-edrv-view] .edrv-rules-type-auto { background: rgba(79,140,255,.16); color: #3367c9; }\n[data-edrv-view] .edrv-rules-type-manual { background: var(--dsw-alias-bg-layer-2, #f0f4f4); color: var(--dsw-alias-label-secondary, #52606d); }\n[data-edrv-view] .edrv-rules-offtag { font-size: 10px; color: var(--dsw-alias-label-tertiary, #9aa5b1); flex-shrink: 0; }\n[data-edrv-view] .edrv-rules-desc { font-size: 11px; color: var(--dsw-alias-label-secondary, #52606d); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 0 1 auto; }\n[data-edrv-view] .edrv-rules-actions { display: flex; align-items: center; gap: 2px; flex-shrink: 0; margin-left: auto; }\n[data-edrv-view] .edrv-rules-act { min-width: 22px; height: 22px; padding: 0 4px; border: none; border-radius: 5px; background: transparent; font-size: 12px; line-height: 1; cursor: pointer; color: var(--dsw-alias-label-secondary, #52606d); display: inline-flex; align-items: center; justify-content: center; }\n[data-edrv-view] .edrv-rules-act:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-rules-switch { position: relative; width: 30px; height: 16px; border-radius: 999px; border: none; background: #b9c4cc; cursor: pointer; transition: background .15s; flex-shrink: 0; padding: 0; }\n[data-edrv-view] .edrv-rules-switch.on { background: #7c5cff; }\n[data-edrv-view] .edrv-rules-knob { position: absolute; top: 2px; left: 2px; width: 12px; height: 12px; border-radius: 50%; background: #fff; transition: left .15s; }\n[data-edrv-view] .edrv-rules-switch.on .edrv-rules-knob { left: 16px; }\n[data-edrv-view] .edrv-rules-empty { padding: 10px 4px; font-size: 12px; color: var(--dsw-alias-label-tertiary, #9aa5b1); line-height: 1.6; }\n[data-edrv-view] .edrv-rules-err { padding: 6px 8px; border: 1px solid rgba(217,83,79,.4); border-radius: 6px; background: #fdeaea; color: var(--dsw-alias-state-error-primary, #d9534f); font-size: 11px; word-break: break-all; }\n[data-edrv-view] .edrv-rules-editor { display: flex; flex-direction: column; min-height: 0; flex: 1; gap: 6px; }\n[data-edrv-view] .edrv-rules-editor-head { display: flex; align-items: center; justify-content: space-between; gap: 6px; font-size: 12px; font-weight: 600; color: var(--dsw-alias-label-primary, #1f2933); flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-crumb { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-rules-editor-ctl { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-ctl-label { font-size: 11px; color: var(--dsw-alias-label-secondary, #52606d); flex-shrink: 0; }\n[data-edrv-view] .edrv-rules-select { height: 24px; padding: 0 4px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 11px; outline: none; cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-rules-select:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-rules-desc-input { flex: 1; min-width: 0; }\n[data-edrv-view] .edrv-rules-input { flex: 1; min-width: 0; height: 24px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 11px; outline: none; font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-rules-input:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-rules-body { flex: 1; min-height: 0; resize: none; padding: 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 12px; line-height: 1.5; outline: none; font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-rules-body:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-rules-editor-hint { font-size: 10px; color: var(--dsw-alias-label-tertiary, #9aa5b1); line-height: 1.5; flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-editor-foot { display: flex; justify-content: flex-end; flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-save { height: 24px; padding: 0 14px; border: none; border-radius: 6px; background: var(--dsw-alias-brand-primary, #0f9d58); color: #fff; font-size: 12px; cursor: pointer; }\n[data-edrv-view] .edrv-rules-save:disabled { opacity: .5; cursor: default; }\n\n\n\n";
|
|
35
35
|
const tagId$1 = "dsh-vscode-mode/editor.css";
|
|
36
36
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
37
37
|
const tag = document.createElement("style");
|
|
@@ -1163,6 +1163,415 @@ window.__ModuleLoader__.load({
|
|
|
1163
1163
|
return "data:" + (mime || "application/octet-stream") + ";base64," + base64;
|
|
1164
1164
|
}
|
|
1165
1165
|
//#endregion
|
|
1166
|
+
//#region src/client/pdfPreview.ts
|
|
1167
|
+
/**
|
|
1168
|
+
* 判断路径是否为 PDF 文件(取 basename 扩展名,大小写不敏感)。
|
|
1169
|
+
* @author ddj 2026年09月22号
|
|
1170
|
+
* @param path 文件路径(`/` 或 `\` 分隔均可)
|
|
1171
|
+
* @returns 是否 PDF 文件
|
|
1172
|
+
*/
|
|
1173
|
+
function isPdfPath(path) {
|
|
1174
|
+
const base = String(path || "").split(/[\\/]/).pop() || "";
|
|
1175
|
+
const dot = base.lastIndexOf(".");
|
|
1176
|
+
return dot > 0 && base.slice(dot + 1).toLowerCase() === "pdf";
|
|
1177
|
+
}
|
|
1178
|
+
/**
|
|
1179
|
+
* base64 文本 → 二进制字节(喂给 pdf.js getDocument 的 data 入参)。
|
|
1180
|
+
* @author ddj 2026年09月22号
|
|
1181
|
+
* @param base64 base64 文本(不含 data: 前缀,host edrv.read base64 响应携带)
|
|
1182
|
+
* @returns 原始字节
|
|
1183
|
+
*/
|
|
1184
|
+
function base64ToBytes(base64) {
|
|
1185
|
+
const bin = atob(String(base64 || ""));
|
|
1186
|
+
const bytes = new Uint8Array(bin.length);
|
|
1187
|
+
for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);
|
|
1188
|
+
return bytes;
|
|
1189
|
+
}
|
|
1190
|
+
/**
|
|
1191
|
+
* 二进制字节 → base64 文本(编辑保存回传 host 前的编码步骤)。
|
|
1192
|
+
* @author ddj 2026年09月22号
|
|
1193
|
+
* @param bytes 原始字节
|
|
1194
|
+
* @returns base64 文本
|
|
1195
|
+
*/
|
|
1196
|
+
function bytesToBase64(bytes) {
|
|
1197
|
+
let bin = "";
|
|
1198
|
+
const chunk = 32768;
|
|
1199
|
+
for (let i = 0; i < bytes.length; i += chunk) bin += String.fromCharCode(...bytes.subarray(i, i + chunk));
|
|
1200
|
+
return btoa(bin);
|
|
1201
|
+
}
|
|
1202
|
+
//#endregion
|
|
1203
|
+
//#region src/client/pdf/pdfLoader.ts
|
|
1204
|
+
/**
|
|
1205
|
+
* dsh-vscode-mode client — pdf.js 加载器(vendor 产物离线随包,/edrv/vendor/pdfjs/*)。
|
|
1206
|
+
* 加载链:module script 内按序动态 import build/pdf.mjs(自挂 globalThis.pdfjsLib)→
|
|
1207
|
+
* web/pdf_viewer.mjs(从 globalThis.pdfjsLib 解构)→ window.__edrvPdfjs handoff。
|
|
1208
|
+
* 用 script 注入而非打包内 import():客户端包是 CJS,bundler 会改写动态 import 破坏 URL 语义。
|
|
1209
|
+
* 作者 ddj 2026-09-22
|
|
1210
|
+
*/
|
|
1211
|
+
/** vendor 根(routes.ts /edrv/vendor 前缀路由分发 assets/vendor/*)。 */
|
|
1212
|
+
const PDFJS_BASE = "/edrv/vendor/pdfjs";
|
|
1213
|
+
/** pdf.js Worker 地址(GlobalWorkerOptions.workerSrc)。 */
|
|
1214
|
+
const PDFJS_WORKER_SRC = PDFJS_BASE + "/build/pdf.worker.mjs";
|
|
1215
|
+
/** CJK 字符映射目录(中文 PDF 渲染必需,尾斜杠固定)。 */
|
|
1216
|
+
const PDFJS_CMAP_URL = PDFJS_BASE + "/cmaps/";
|
|
1217
|
+
/** 标准字体目录(未嵌字体 PDF 兜底,尾斜杠固定)。 */
|
|
1218
|
+
const PDFJS_FONT_URL = PDFJS_BASE + "/standard_fonts/";
|
|
1219
|
+
/** 组件层样式(pdfViewer/textLayer/annotationEditor 布局)。 */
|
|
1220
|
+
const PDFJS_CSS_URL = PDFJS_BASE + "/web/pdf_viewer.css";
|
|
1221
|
+
let pdfjsPromise = null;
|
|
1222
|
+
/**
|
|
1223
|
+
* 注入 pdf_viewer.css(幂等;vendor 路由带 etag 协商缓存,重复挂载走 304)。
|
|
1224
|
+
* @author ddj 2026年09月22号
|
|
1225
|
+
*/
|
|
1226
|
+
function ensurePdfCss() {
|
|
1227
|
+
if (typeof document === "undefined") return;
|
|
1228
|
+
if (document.querySelector("link[data-edrv-pdfjs-css]")) return;
|
|
1229
|
+
const link = document.createElement("link");
|
|
1230
|
+
link.rel = "stylesheet";
|
|
1231
|
+
link.href = PDFJS_CSS_URL;
|
|
1232
|
+
link.dataset.edrvPdfjsCss = "1";
|
|
1233
|
+
document.head.appendChild(link);
|
|
1234
|
+
}
|
|
1235
|
+
/**
|
|
1236
|
+
* 加载 pdf.js(core + viewer 组件层):去重 promise,失败重置允许重试(对齐 monaco loader)。
|
|
1237
|
+
* @author ddj 2026年09月22号
|
|
1238
|
+
* @returns Promise<{lib, viewer}> lib=build/pdf.mjs(getDocument/GlobalWorkerOptions/编辑器枚举等),viewer=web/pdf_viewer.mjs(PDFViewer/EventBus 等)
|
|
1239
|
+
*/
|
|
1240
|
+
function loadPdfjs() {
|
|
1241
|
+
if (!pdfjsPromise) pdfjsPromise = new Promise((resolve, reject) => {
|
|
1242
|
+
ensurePdfCss();
|
|
1243
|
+
const boot = () => {
|
|
1244
|
+
const handoff = window.__edrvPdfjs;
|
|
1245
|
+
if (handoff && handoff.lib && handoff.viewer) {
|
|
1246
|
+
try {
|
|
1247
|
+
handoff.lib.GlobalWorkerOptions.workerSrc = PDFJS_WORKER_SRC;
|
|
1248
|
+
} catch (error) {}
|
|
1249
|
+
resolve(handoff);
|
|
1250
|
+
return;
|
|
1251
|
+
}
|
|
1252
|
+
reject(/* @__PURE__ */ new Error("pdf.js 模块加载失败:handoff 缺失"));
|
|
1253
|
+
};
|
|
1254
|
+
const fail = (error) => {
|
|
1255
|
+
pdfjsPromise = null;
|
|
1256
|
+
reject(error instanceof Error ? error : new Error(String(error)));
|
|
1257
|
+
};
|
|
1258
|
+
const existing = document.querySelector("script[data-edrv-pdfjs-loader]");
|
|
1259
|
+
if (existing) {
|
|
1260
|
+
existing.addEventListener("edrv-pdfjs-ready", boot, { once: true });
|
|
1261
|
+
if (window.__edrvPdfjs) boot();
|
|
1262
|
+
return;
|
|
1263
|
+
}
|
|
1264
|
+
const s = document.createElement("script");
|
|
1265
|
+
s.type = "module";
|
|
1266
|
+
s.textContent = "import * as lib from \"/edrv/vendor/pdfjs/build/pdf.mjs\";\nimport * as viewer from \"/edrv/vendor/pdfjs/web/pdf_viewer.mjs\";\nwindow.__edrvPdfjs = { lib, viewer };\ndocument.querySelector(\"script[data-edrv-pdfjs-loader]\")?.dispatchEvent(new Event(\"edrv-pdfjs-ready\"));";
|
|
1267
|
+
s.dataset.edrvPdfjsLoader = "1";
|
|
1268
|
+
s.onload = boot;
|
|
1269
|
+
s.onerror = () => fail(/* @__PURE__ */ new Error("pdf.js loader 脚本加载失败(检查 assets/vendor/pdfjs 完整 / /edrv/vendor 路由可达)"));
|
|
1270
|
+
document.head.appendChild(s);
|
|
1271
|
+
});
|
|
1272
|
+
return pdfjsPromise;
|
|
1273
|
+
}
|
|
1274
|
+
//#endregion
|
|
1275
|
+
//#region src/client/pdf/pdfPanel.ts
|
|
1276
|
+
/**
|
|
1277
|
+
* dsh-vscode-mode client — PDF 面板控制器(命令式 DOM,React 只渲染外壳 div)。
|
|
1278
|
+
* 浏览:PDFViewer 组件(虚拟化渲染 + 文本层);编辑:内置注释编辑器
|
|
1279
|
+
* (FreeText 文本框 / Ink 画笔 / Highlight 高亮),保存经 pdfDocument.saveDocument()
|
|
1280
|
+
* → base64 → edrv.saveBinary 回写原文件。接线方式对齐官方 viewer(web/app.js)。
|
|
1281
|
+
* 作者 ddj 2026-09-22
|
|
1282
|
+
*/
|
|
1283
|
+
/** 无障碍占位 l10n:组件内 translate 为 fire-and-forget,stub 避免触发 locale 404。 */
|
|
1284
|
+
const L10N_STUB = {
|
|
1285
|
+
get: async (key) => key,
|
|
1286
|
+
translate: async () => {},
|
|
1287
|
+
getDirection: () => "ltr"
|
|
1288
|
+
};
|
|
1289
|
+
/**
|
|
1290
|
+
* PDF 面板控制器工厂。
|
|
1291
|
+
* @author ddj 2026年09月22号
|
|
1292
|
+
* @param deps 依赖:sessionId/path(保存回写目标)+ 状态栏回调
|
|
1293
|
+
* @returns 控制器:mount/destroy/savePdf/setMode/isDirty
|
|
1294
|
+
*/
|
|
1295
|
+
function createPdfPanel(deps) {
|
|
1296
|
+
const status = (t) => {
|
|
1297
|
+
try {
|
|
1298
|
+
deps.setStatus(t);
|
|
1299
|
+
} catch {}
|
|
1300
|
+
};
|
|
1301
|
+
let stage = null;
|
|
1302
|
+
let pageLabel = null;
|
|
1303
|
+
let eventBus = null;
|
|
1304
|
+
let busAbort = null;
|
|
1305
|
+
let editorTypes = null;
|
|
1306
|
+
let pdfViewer = null;
|
|
1307
|
+
let pdfDocument = null;
|
|
1308
|
+
let loadingTask = null;
|
|
1309
|
+
let modeButtons = null;
|
|
1310
|
+
let destroyed = false;
|
|
1311
|
+
let dirty = false;
|
|
1312
|
+
let saving = false;
|
|
1313
|
+
/** 脏状态上抛(tab 脏点)+ 本地记忆。 */
|
|
1314
|
+
const setDirty = (value) => {
|
|
1315
|
+
dirty = value;
|
|
1316
|
+
if (modeButtons) modeButtons.save.classList.toggle("edrv-pdf-dirty", value);
|
|
1317
|
+
try {
|
|
1318
|
+
deps.onDirtyChange(value);
|
|
1319
|
+
} catch {}
|
|
1320
|
+
};
|
|
1321
|
+
/** 页码指示更新(pagechanging/pagesinit 事件)。 */
|
|
1322
|
+
const updatePageLabel = () => {
|
|
1323
|
+
if (!pageLabel || !pdfViewer) return;
|
|
1324
|
+
pageLabel.textContent = pdfViewer.currentPageNumber + " / " + pdfViewer.pagesCount;
|
|
1325
|
+
};
|
|
1326
|
+
/** 编辑模式按钮高亮同步(annotationeditormodechanged 事件;evt.mode 为枚举数值)。 */
|
|
1327
|
+
const syncModeButtons = (mode) => {
|
|
1328
|
+
if (!modeButtons || !editorTypes) return;
|
|
1329
|
+
const key = {
|
|
1330
|
+
[editorTypes.NONE]: "none",
|
|
1331
|
+
[editorTypes.FREETEXT]: "freetext",
|
|
1332
|
+
[editorTypes.INK]: "ink",
|
|
1333
|
+
[editorTypes.HIGHLIGHT]: "highlight"
|
|
1334
|
+
}[mode] ?? "none";
|
|
1335
|
+
for (const k of Object.keys(modeButtons.modes)) modeButtons.modes[k].classList.toggle("edrv-pdf-mode-on", k === key);
|
|
1336
|
+
};
|
|
1337
|
+
/** 编辑模式符号键 → AnnotationEditorType 数值(版本间枚举值有差异,禁止硬编码)。 */
|
|
1338
|
+
const modeValueOf = (key) => {
|
|
1339
|
+
if (!editorTypes) return null;
|
|
1340
|
+
return {
|
|
1341
|
+
none: editorTypes.NONE,
|
|
1342
|
+
freetext: editorTypes.FREETEXT,
|
|
1343
|
+
ink: editorTypes.INK,
|
|
1344
|
+
highlight: editorTypes.HIGHLIGHT
|
|
1345
|
+
}[key] ?? null;
|
|
1346
|
+
};
|
|
1347
|
+
/**
|
|
1348
|
+
* 切换编辑模式(进入注释编辑器某模式或退出回 NONE)。
|
|
1349
|
+
* @author ddj 2026年09月22号
|
|
1350
|
+
* @param key 模式符号键:none/freetext/ink/highlight
|
|
1351
|
+
*/
|
|
1352
|
+
const applyMode = (key) => {
|
|
1353
|
+
if (!pdfViewer || !pdfDocument) {
|
|
1354
|
+
status("PDF 未就绪");
|
|
1355
|
+
return;
|
|
1356
|
+
}
|
|
1357
|
+
const mode = modeValueOf(key);
|
|
1358
|
+
if (mode === null) return;
|
|
1359
|
+
try {
|
|
1360
|
+
pdfViewer.annotationEditorMode = { mode };
|
|
1361
|
+
status(key === "none" ? "已退出编辑" : "编辑模式:" + (key === "freetext" ? "文本框" : key === "ink" ? "画笔" : "高亮"));
|
|
1362
|
+
} catch (error) {
|
|
1363
|
+
status("切换编辑模式失败:" + String(error));
|
|
1364
|
+
}
|
|
1365
|
+
};
|
|
1366
|
+
/**
|
|
1367
|
+
* 保存编辑:saveDocument 导出 → base64 → edrv.saveBinary 回写。
|
|
1368
|
+
* @author ddj 2026年09月22号
|
|
1369
|
+
* @returns Promise<boolean> 是否成功
|
|
1370
|
+
*/
|
|
1371
|
+
const savePdf = async () => {
|
|
1372
|
+
if (saving) return false;
|
|
1373
|
+
if (!pdfDocument) {
|
|
1374
|
+
status("PDF 未就绪");
|
|
1375
|
+
return false;
|
|
1376
|
+
}
|
|
1377
|
+
if (!dirty) {
|
|
1378
|
+
status("PDF 无未保存修改");
|
|
1379
|
+
return true;
|
|
1380
|
+
}
|
|
1381
|
+
saving = true;
|
|
1382
|
+
status("正在保存 PDF…");
|
|
1383
|
+
try {
|
|
1384
|
+
const data = await pdfDocument.saveDocument();
|
|
1385
|
+
const res = await rpc("edrv.saveBinary", {
|
|
1386
|
+
sessionId: deps.sessionId,
|
|
1387
|
+
path: deps.path,
|
|
1388
|
+
content: bytesToBase64(data),
|
|
1389
|
+
encoding: "base64"
|
|
1390
|
+
});
|
|
1391
|
+
if (res && res.ok) {
|
|
1392
|
+
setDirty(false);
|
|
1393
|
+
try {
|
|
1394
|
+
pdfDocument.annotationStorage.resetModified();
|
|
1395
|
+
} catch {}
|
|
1396
|
+
status("已保存 " + (/* @__PURE__ */ new Date()).toTimeString().slice(0, 8));
|
|
1397
|
+
return true;
|
|
1398
|
+
}
|
|
1399
|
+
status("保存失败");
|
|
1400
|
+
try {
|
|
1401
|
+
deps.setError(res?.error ? String(res.error) : "保存失败");
|
|
1402
|
+
} catch {}
|
|
1403
|
+
return false;
|
|
1404
|
+
} catch (error) {
|
|
1405
|
+
status("保存失败");
|
|
1406
|
+
try {
|
|
1407
|
+
deps.setError("PDF 保存异常:" + String(error));
|
|
1408
|
+
} catch {}
|
|
1409
|
+
return false;
|
|
1410
|
+
} finally {
|
|
1411
|
+
saving = false;
|
|
1412
|
+
}
|
|
1413
|
+
};
|
|
1414
|
+
/** 工具条 DOM(页码/缩放/编辑模式/保存/刷新)。 */
|
|
1415
|
+
const buildToolbar = (root) => {
|
|
1416
|
+
const bar = document.createElement("div");
|
|
1417
|
+
bar.className = "edrv-pdf-bar";
|
|
1418
|
+
const mkBtn = (text, title, onClick, cls) => {
|
|
1419
|
+
const b = document.createElement("button");
|
|
1420
|
+
b.className = cls || "edrv-pill edrv-pill-ghost";
|
|
1421
|
+
b.textContent = text;
|
|
1422
|
+
b.title = title;
|
|
1423
|
+
b.addEventListener("click", onClick);
|
|
1424
|
+
bar.appendChild(b);
|
|
1425
|
+
return b;
|
|
1426
|
+
};
|
|
1427
|
+
mkBtn("◀", "上一页", () => {
|
|
1428
|
+
if (pdfViewer) pdfViewer.currentPageNumber = Math.max(1, pdfViewer.currentPageNumber - 1);
|
|
1429
|
+
});
|
|
1430
|
+
pageLabel = document.createElement("span");
|
|
1431
|
+
pageLabel.className = "edrv-pdf-page";
|
|
1432
|
+
pageLabel.textContent = "…";
|
|
1433
|
+
bar.appendChild(pageLabel);
|
|
1434
|
+
mkBtn("▶", "下一页", () => {
|
|
1435
|
+
if (pdfViewer) pdfViewer.currentPageNumber = Math.min(pdfViewer.pagesCount, pdfViewer.currentPageNumber + 1);
|
|
1436
|
+
});
|
|
1437
|
+
mkBtn("−", "缩小", () => {
|
|
1438
|
+
try {
|
|
1439
|
+
pdfViewer.decreaseScale();
|
|
1440
|
+
} catch {}
|
|
1441
|
+
}, "edrv-pill edrv-pill-ghost edrv-pdf-zoom");
|
|
1442
|
+
mkBtn("+", "放大", () => {
|
|
1443
|
+
try {
|
|
1444
|
+
pdfViewer.increaseScale();
|
|
1445
|
+
} catch {}
|
|
1446
|
+
}, "edrv-pill edrv-pill-ghost edrv-pdf-zoom");
|
|
1447
|
+
bar.appendChild(document.createElement("span")).className = "edrv-pdf-sep";
|
|
1448
|
+
const modes = {};
|
|
1449
|
+
modes.freetext = mkBtn("✎ 文本框", "插入文本框注释", () => applyMode("freetext"));
|
|
1450
|
+
modes.ink = mkBtn("🖌 画笔", "手绘画笔注释", () => applyMode("ink"));
|
|
1451
|
+
modes.highlight = mkBtn("🖍 高亮", "高亮选中文本", () => applyMode("highlight"));
|
|
1452
|
+
modes.none = mkBtn("☐ 选择", "退出编辑模式", () => applyMode("none"));
|
|
1453
|
+
modeButtons = {
|
|
1454
|
+
modes,
|
|
1455
|
+
save: null
|
|
1456
|
+
};
|
|
1457
|
+
bar.appendChild(document.createElement("span")).className = "edrv-pdf-sep";
|
|
1458
|
+
mkBtn("⟳", "重新加载文件", () => {
|
|
1459
|
+
try {
|
|
1460
|
+
deps.onReload();
|
|
1461
|
+
} catch {}
|
|
1462
|
+
});
|
|
1463
|
+
modeButtons.save = mkBtn("💾 保存", "保存修改到文件 (Ctrl+S)", () => {
|
|
1464
|
+
savePdf();
|
|
1465
|
+
});
|
|
1466
|
+
root.appendChild(bar);
|
|
1467
|
+
};
|
|
1468
|
+
/**
|
|
1469
|
+
* 挂载面板并加载 PDF 字节。
|
|
1470
|
+
* @author ddj 2026年09月22号
|
|
1471
|
+
* @param host React 渲染的外壳 div(挂载后保持引用稳定)
|
|
1472
|
+
* @param bytes PDF 原始字节
|
|
1473
|
+
* @returns Promise<void> 渲染就绪或失败(失败置 deps.setError)
|
|
1474
|
+
*/
|
|
1475
|
+
const mount = async (host, bytes) => {
|
|
1476
|
+
try {
|
|
1477
|
+
const pdfjs = await loadPdfjs();
|
|
1478
|
+
if (destroyed) return;
|
|
1479
|
+
editorTypes = pdfjs.lib.AnnotationEditorType;
|
|
1480
|
+
busAbort = new AbortController();
|
|
1481
|
+
const onBus = (name, fn) => eventBus.on(name, fn, { signal: busAbort.signal });
|
|
1482
|
+
const root = document.createElement("div");
|
|
1483
|
+
root.className = "edrv-pdf";
|
|
1484
|
+
buildToolbar(root);
|
|
1485
|
+
stage = document.createElement("div");
|
|
1486
|
+
stage.className = "edrv-pdf-stage";
|
|
1487
|
+
const viewerDiv = document.createElement("div");
|
|
1488
|
+
viewerDiv.className = "pdfViewer edrv-pdf-viewer";
|
|
1489
|
+
stage.appendChild(viewerDiv);
|
|
1490
|
+
root.appendChild(stage);
|
|
1491
|
+
host.textContent = "";
|
|
1492
|
+
host.appendChild(root);
|
|
1493
|
+
eventBus = new pdfjs.viewer.EventBus();
|
|
1494
|
+
const linkService = new pdfjs.viewer.PDFLinkService({ eventBus });
|
|
1495
|
+
pdfViewer = new pdfjs.viewer.PDFViewer({
|
|
1496
|
+
container: stage,
|
|
1497
|
+
viewer: viewerDiv,
|
|
1498
|
+
eventBus,
|
|
1499
|
+
linkService,
|
|
1500
|
+
l10n: L10N_STUB,
|
|
1501
|
+
textLayerMode: 1,
|
|
1502
|
+
annotationEditorMode: editorTypes.NONE
|
|
1503
|
+
});
|
|
1504
|
+
linkService.setViewer(pdfViewer);
|
|
1505
|
+
onBus("pagechanging", updatePageLabel);
|
|
1506
|
+
onBus("pagesinit", () => {
|
|
1507
|
+
try {
|
|
1508
|
+
pdfViewer.currentScaleValue = "page-width";
|
|
1509
|
+
} catch {}
|
|
1510
|
+
updatePageLabel();
|
|
1511
|
+
});
|
|
1512
|
+
onBus("annotationeditormodechanged", (evt) => syncModeButtons(evt?.mode));
|
|
1513
|
+
loadingTask = pdfjs.lib.getDocument({
|
|
1514
|
+
data: bytes,
|
|
1515
|
+
cMapUrl: PDFJS_CMAP_URL,
|
|
1516
|
+
cMapPacked: true,
|
|
1517
|
+
standardFontDataUrl: PDFJS_FONT_URL
|
|
1518
|
+
});
|
|
1519
|
+
pdfDocument = await loadingTask.promise;
|
|
1520
|
+
if (destroyed) {
|
|
1521
|
+
loadingTask.destroy();
|
|
1522
|
+
return;
|
|
1523
|
+
}
|
|
1524
|
+
const storage = pdfDocument.annotationStorage;
|
|
1525
|
+
storage.onSetModified = () => setDirty(true);
|
|
1526
|
+
storage.onResetModified = () => setDirty(false);
|
|
1527
|
+
pdfViewer.setDocument(pdfDocument);
|
|
1528
|
+
linkService.setDocument(pdfDocument);
|
|
1529
|
+
status("PDF 已就绪(" + pdfDocument.numPages + " 页)");
|
|
1530
|
+
} catch (error) {
|
|
1531
|
+
if (destroyed) return;
|
|
1532
|
+
const message = String(error && (error.message || error.name) || error);
|
|
1533
|
+
const friendly = message.includes("password") ? "不支持加密 PDF" : "PDF 加载失败:" + message;
|
|
1534
|
+
status("PDF 加载失败");
|
|
1535
|
+
try {
|
|
1536
|
+
deps.setError(friendly);
|
|
1537
|
+
} catch {}
|
|
1538
|
+
}
|
|
1539
|
+
};
|
|
1540
|
+
/** 是否有未保存修改(EditorView Ctrl+S 分派用)。 */
|
|
1541
|
+
const isDirty = () => dirty;
|
|
1542
|
+
/** 销毁:解绑事件、销毁文档与 DOM(重复调用安全)。 */
|
|
1543
|
+
const destroy = () => {
|
|
1544
|
+
destroyed = true;
|
|
1545
|
+
try {
|
|
1546
|
+
busAbort?.abort();
|
|
1547
|
+
} catch {}
|
|
1548
|
+
try {
|
|
1549
|
+
pdfViewer?.cleanup();
|
|
1550
|
+
} catch {}
|
|
1551
|
+
try {
|
|
1552
|
+
loadingTask?.destroy();
|
|
1553
|
+
} catch {}
|
|
1554
|
+
try {
|
|
1555
|
+
pdfDocument?.destroy();
|
|
1556
|
+
} catch {}
|
|
1557
|
+
if (stage?.parentNode) stage.parentNode.removeChild(stage);
|
|
1558
|
+
stage = null;
|
|
1559
|
+
eventBus = null;
|
|
1560
|
+
busAbort = null;
|
|
1561
|
+
editorTypes = null;
|
|
1562
|
+
pdfViewer = null;
|
|
1563
|
+
pdfDocument = null;
|
|
1564
|
+
loadingTask = null;
|
|
1565
|
+
modeButtons = null;
|
|
1566
|
+
};
|
|
1567
|
+
return {
|
|
1568
|
+
mount,
|
|
1569
|
+
destroy,
|
|
1570
|
+
savePdf,
|
|
1571
|
+
isDirty
|
|
1572
|
+
};
|
|
1573
|
+
}
|
|
1574
|
+
//#endregion
|
|
1166
1575
|
//#region src/client/monaco/diffRender.ts
|
|
1167
1576
|
/**
|
|
1168
1577
|
* dsh-vscode-mode client — 行内差异自绘(新增行绿底 + glyph margin '+';删除块 view zone 红底)。
|
|
@@ -3678,6 +4087,10 @@ window.__ModuleLoader__.load({
|
|
|
3678
4087
|
const [imgSize, setImgSize] = react.default.useState(null);
|
|
3679
4088
|
const [imgBroken, setImgBroken] = react.default.useState(false);
|
|
3680
4089
|
const svgTextRef = react.default.useRef(/* @__PURE__ */ new Set());
|
|
4090
|
+
const [pdfBytes, setPdfBytes] = react.default.useState(null);
|
|
4091
|
+
const pdfB64CacheRef = react.default.useRef(/* @__PURE__ */ new Map());
|
|
4092
|
+
const pdfCtlRef = react.default.useRef(/* @__PURE__ */ new Map());
|
|
4093
|
+
const pdfHostRef = react.default.useRef(null);
|
|
3681
4094
|
const [status, setStatus] = react.default.useState("");
|
|
3682
4095
|
const [lspServers, setLspServers] = react.default.useState([]);
|
|
3683
4096
|
const [error, setError] = react.default.useState(null);
|
|
@@ -3746,6 +4159,7 @@ window.__ModuleLoader__.load({
|
|
|
3746
4159
|
}, [records, active]);
|
|
3747
4160
|
const contentReady = content !== null && contentPath === active;
|
|
3748
4161
|
const isImageActive = !!active && isImagePath(active) && !svgTextRef.current.has(active);
|
|
4162
|
+
const isPdfActive = !!active && isPdfPath(active);
|
|
3749
4163
|
const regions = react.default.useMemo(() => diffRegions(currentRecords, contentReady ? content : null).filter((r) => !r.superseded), [
|
|
3750
4164
|
currentRecords,
|
|
3751
4165
|
content,
|
|
@@ -3900,6 +4314,12 @@ window.__ModuleLoader__.load({
|
|
|
3900
4314
|
saveViewState(path);
|
|
3901
4315
|
recordNav();
|
|
3902
4316
|
}
|
|
4317
|
+
const pdfCtl = pdfCtlRef.current.get(path);
|
|
4318
|
+
if (pdfCtl) {
|
|
4319
|
+
pdfCtl.destroy();
|
|
4320
|
+
pdfCtlRef.current.delete(path);
|
|
4321
|
+
}
|
|
4322
|
+
pdfB64CacheRef.current.delete(path);
|
|
3903
4323
|
setTabs((prev) => {
|
|
3904
4324
|
const idx = prev.findIndex((t) => t.path === path);
|
|
3905
4325
|
if (idx < 0) return prev;
|
|
@@ -3955,6 +4375,10 @@ window.__ModuleLoader__.load({
|
|
|
3955
4375
|
loadImage(path, sid, seq);
|
|
3956
4376
|
return;
|
|
3957
4377
|
}
|
|
4378
|
+
if (isPdfPath(path)) {
|
|
4379
|
+
loadPdf(path, sid, seq, force === true);
|
|
4380
|
+
return;
|
|
4381
|
+
}
|
|
3958
4382
|
const cachedModel = force ? null : modelsRef.current.get(path);
|
|
3959
4383
|
if (cachedModel) {
|
|
3960
4384
|
setContent(cachedModel.getValue());
|
|
@@ -4059,6 +4483,64 @@ window.__ModuleLoader__.load({
|
|
|
4059
4483
|
setStatus("读取失败");
|
|
4060
4484
|
});
|
|
4061
4485
|
};
|
|
4486
|
+
/**
|
|
4487
|
+
* 加载 PDF 文件为原始字节(编辑区 PDF 面板);命中 base64 缓存秒切,force 绕过缓存重读。
|
|
4488
|
+
* 面板控制器由 pdf host mount effect 产出(per-path,关闭/卸载销毁)。
|
|
4489
|
+
* @author ddj 2026年09月22号
|
|
4490
|
+
* @param path PDF 文件路径
|
|
4491
|
+
* @param sid 会话 id
|
|
4492
|
+
* @param seq 加载序号(过期响应丢弃)
|
|
4493
|
+
* @param force true=绕过缓存强制 RPC 重读(刷新按钮)
|
|
4494
|
+
*/
|
|
4495
|
+
const loadPdf = (path, sid, seq, force) => {
|
|
4496
|
+
setPdfBytes(null);
|
|
4497
|
+
setLoadStage({
|
|
4498
|
+
progress: monaco ? 72 : 12,
|
|
4499
|
+
message: "读取 PDF…"
|
|
4500
|
+
});
|
|
4501
|
+
const cache = pdfB64CacheRef.current;
|
|
4502
|
+
const hit = !force ? cache.get(path) : void 0;
|
|
4503
|
+
if (typeof hit === "string" && hit) {
|
|
4504
|
+
cache.delete(path);
|
|
4505
|
+
cache.set(path, hit);
|
|
4506
|
+
setPdfBytes(base64ToBytes(hit));
|
|
4507
|
+
setLoadStage({
|
|
4508
|
+
progress: 100,
|
|
4509
|
+
message: "PDF 已就绪"
|
|
4510
|
+
});
|
|
4511
|
+
setStatus("已加载");
|
|
4512
|
+
return;
|
|
4513
|
+
}
|
|
4514
|
+
rpc("edrv.read", {
|
|
4515
|
+
sessionId: sid,
|
|
4516
|
+
path,
|
|
4517
|
+
encoding: "base64"
|
|
4518
|
+
}).then((res) => {
|
|
4519
|
+
if (seq !== loadSeqRef.current || path !== active) return;
|
|
4520
|
+
if (res && res.ok && res.encoding === "base64") {
|
|
4521
|
+
cache.set(path, res.content);
|
|
4522
|
+
while (cache.size > 6) cache.delete(cache.keys().next().value);
|
|
4523
|
+
setPdfBytes(base64ToBytes(res.content));
|
|
4524
|
+
setLoadStage({
|
|
4525
|
+
progress: 100,
|
|
4526
|
+
message: "PDF 已就绪"
|
|
4527
|
+
});
|
|
4528
|
+
setStatus("已加载");
|
|
4529
|
+
return;
|
|
4530
|
+
}
|
|
4531
|
+
const base = res?.error ? String(res.error) : "读取失败";
|
|
4532
|
+
const message = res?.resolvedPath ? base + ":" + String(res.resolvedPath) : base;
|
|
4533
|
+
setLoadError(message);
|
|
4534
|
+
setError(message);
|
|
4535
|
+
setStatus("读取失败");
|
|
4536
|
+
}).catch((e) => {
|
|
4537
|
+
if (seq !== loadSeqRef.current) return;
|
|
4538
|
+
const message = "read异常:" + String(e);
|
|
4539
|
+
setLoadError(message);
|
|
4540
|
+
setError(message);
|
|
4541
|
+
setStatus("读取失败");
|
|
4542
|
+
});
|
|
4543
|
+
};
|
|
4062
4544
|
react.default.useEffect(() => {
|
|
4063
4545
|
if (!sessionId) return;
|
|
4064
4546
|
refreshRecords();
|
|
@@ -4337,6 +4819,7 @@ window.__ModuleLoader__.load({
|
|
|
4337
4819
|
setImageSrc(null);
|
|
4338
4820
|
setImgSize(null);
|
|
4339
4821
|
setImgBroken(false);
|
|
4822
|
+
setPdfBytes(null);
|
|
4340
4823
|
setLoadError(null);
|
|
4341
4824
|
setLoadStage({
|
|
4342
4825
|
progress: 10,
|
|
@@ -4411,8 +4894,22 @@ window.__ModuleLoader__.load({
|
|
|
4411
4894
|
}
|
|
4412
4895
|
};
|
|
4413
4896
|
const doSave = (silent) => {
|
|
4897
|
+
if (!active) return;
|
|
4898
|
+
if (isPdfPath(active)) {
|
|
4899
|
+
const ctl = pdfCtlRef.current.get(active);
|
|
4900
|
+
if (!ctl) {
|
|
4901
|
+
if (!silent) setStatus("PDF 未就绪");
|
|
4902
|
+
return;
|
|
4903
|
+
}
|
|
4904
|
+
if (!ctl.isDirty()) {
|
|
4905
|
+
if (!silent) setStatus("PDF 无未保存修改");
|
|
4906
|
+
return;
|
|
4907
|
+
}
|
|
4908
|
+
ctl.savePdf();
|
|
4909
|
+
return;
|
|
4910
|
+
}
|
|
4414
4911
|
const ed = editorRef.current;
|
|
4415
|
-
if (!
|
|
4912
|
+
if (!ed) return;
|
|
4416
4913
|
if (isImageActive) {
|
|
4417
4914
|
setStatus("图片只读预览");
|
|
4418
4915
|
return;
|
|
@@ -4463,6 +4960,32 @@ window.__ModuleLoader__.load({
|
|
|
4463
4960
|
active,
|
|
4464
4961
|
content
|
|
4465
4962
|
]);
|
|
4963
|
+
const ensurePdfHost = (node) => {
|
|
4964
|
+
pdfHostRef.current = node;
|
|
4965
|
+
};
|
|
4966
|
+
react.default.useEffect(() => {
|
|
4967
|
+
const host = pdfHostRef.current;
|
|
4968
|
+
if (!isPdfActive || !pdfBytes || !host) return;
|
|
4969
|
+
const path = active;
|
|
4970
|
+
const ctl = createPdfPanel({
|
|
4971
|
+
sessionId,
|
|
4972
|
+
path,
|
|
4973
|
+
setStatus,
|
|
4974
|
+
setError,
|
|
4975
|
+
onDirtyChange: (d) => setDirtyMap((prev) => Object.assign({}, prev, { [path]: d })),
|
|
4976
|
+
onReload: () => loadContent(path, sessionId, true)
|
|
4977
|
+
});
|
|
4978
|
+
pdfCtlRef.current.set(path, ctl);
|
|
4979
|
+
ctl.mount(host, pdfBytes);
|
|
4980
|
+
return () => {
|
|
4981
|
+
ctl.destroy();
|
|
4982
|
+
if (pdfCtlRef.current.get(path) === ctl) pdfCtlRef.current.delete(path);
|
|
4983
|
+
};
|
|
4984
|
+
}, [
|
|
4985
|
+
isPdfActive,
|
|
4986
|
+
pdfBytes,
|
|
4987
|
+
active
|
|
4988
|
+
]);
|
|
4466
4989
|
react.default.useEffect(() => {
|
|
4467
4990
|
if (!monaco || !editorRef.current || !active || content === null) return;
|
|
4468
4991
|
diffRendererRef.current.render(monaco, editorRef.current, pendingRegions, sessionId);
|
|
@@ -4486,6 +5009,8 @@ window.__ModuleLoader__.load({
|
|
|
4486
5009
|
}
|
|
4487
5010
|
for (const m of modelsRef.current.values()) m.dispose();
|
|
4488
5011
|
modelsRef.current.clear();
|
|
5012
|
+
for (const ctl of pdfCtlRef.current.values()) ctl.destroy();
|
|
5013
|
+
pdfCtlRef.current.clear();
|
|
4489
5014
|
const root = editorRef.current && editorRef.current.getDomNode ? editorRef.current.getDomNode() : null;
|
|
4490
5015
|
if (root) {
|
|
4491
5016
|
const ov = root.querySelector(".edrv-minus-overlay");
|
|
@@ -5045,7 +5570,7 @@ window.__ModuleLoader__.load({
|
|
|
5045
5570
|
const openPath = () => {
|
|
5046
5571
|
const p = (pathDraft || "").trim();
|
|
5047
5572
|
if (!p) return;
|
|
5048
|
-
if (isImagePath(p)) {
|
|
5573
|
+
if (isImagePath(p) || isPdfPath(p)) {
|
|
5049
5574
|
openFile(p, false);
|
|
5050
5575
|
setOpenInput(false);
|
|
5051
5576
|
setPathDraft("");
|
|
@@ -5236,6 +5761,12 @@ window.__ModuleLoader__.load({
|
|
|
5236
5761
|
});
|
|
5237
5762
|
else if (isImageActive && imageSrc) body = imagePanel();
|
|
5238
5763
|
else if (isImageActive) body = loadingBody(loadStage.message || "读取图片…", loadStage.progress);
|
|
5764
|
+
else if (isPdfActive && pdfBytes) body = react.default.createElement("div", {
|
|
5765
|
+
className: "edrv-pdf-host",
|
|
5766
|
+
ref: ensurePdfHost,
|
|
5767
|
+
key: active
|
|
5768
|
+
});
|
|
5769
|
+
else if (isPdfActive) body = loadingBody(loadStage.message || "读取 PDF…", loadStage.progress);
|
|
5239
5770
|
else if (content === null) body = loadingBody(loadStage.message || "读取文件内容…", loadStage.progress);
|
|
5240
5771
|
else body = react.default.createElement("div", { className: "edrv-monaco-host" }, react.default.createElement("div", { ref: ensureEditor }));
|
|
5241
5772
|
const hoverEl = hoverAct && !launcherOpen ? react.default.createElement("div", {
|