dsh-office-kit 0.1.0 → 0.2.0
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/LICENSE.md +21 -21
- package/README.md +106 -106
- package/dist/client.js.map +1 -1
- package/package.json +146 -149
package/LICENSE.md
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025-PRESENT dsh-tauri-desk
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-PRESENT dsh-tauri-desk
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,106 +1,106 @@
|
|
|
1
|
-
<div align="center"><a name="readme-top"></a>
|
|
2
|
-
|
|
3
|
-
<img src="./public/hero.png" alt="安装插件" />
|
|
4
|
-
|
|
5
|
-
# DSH Office Kit
|
|
6
|
-
|
|
7
|
-
[![npm version][npm-version-src]][npm-version-href]
|
|
8
|
-
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
|
9
|
-
[![bundle][bundle-src]][bundle-href]
|
|
10
|
-
[![JSDocs][jsdocs-src]][jsdocs-href]
|
|
11
|
-
[![License][license-src]][license-href]
|
|
12
|
-
|
|
13
|
-
为 DeepSeek Harness (DSH) 提供本地 Word、PDF、演示文稿与电子表格能力,支持 `/` 菜单、引用 Chip,以及侧边栏预览中的选区标注与修改请求。
|
|
14
|
-
</div>
|
|
15
|
-
|
|
16
|
-
## 📦 安装
|
|
17
|
-
|
|
18
|
-
在官方插件中安装 `dsh-office-kit`
|
|
19
|
-
|
|
20
|
-
<img src="https://raw.githubusercontent.com/hairyf/dsh-office-kit/refs/heads/main/public/install.png" alt="安装插件" />
|
|
21
|
-
|
|
22
|
-
或使用命令行安装
|
|
23
|
-
|
|
24
|
-
```sh
|
|
25
|
-
dsh plugin add dsh-office-kit
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
- 在 **设置 → 插件** 中启用。
|
|
29
|
-
- 需要 DSH ≥ `0.2.1-rc.2`、Python(无需,没有将自动安装) `3.10`–`3.13`。
|
|
30
|
-
- Windows 缺少兼容 Python 时自动安装;macOS / Linux 使用现有 Python。
|
|
31
|
-
|
|
32
|
-
## 特性
|
|
33
|
-
|
|
34
|
-
- 📝 **Word**:`/documents` 创建、读取和编辑 DOCX,支持表格、图片、公式与页眉页脚。
|
|
35
|
-
- 📄 **PDF**:`/pdf` 创建、读取和编辑 PDF,支持合并、旋转、删页与元数据。
|
|
36
|
-
- 📽️ **演示文稿**:`/presentations` 创建、读取和编辑 PPTX,支持项目符号、表格、图表与图片。
|
|
37
|
-
- 📊 **电子表格**:`/spreadsheets` 创建、读取和编辑 XLSX,支持公式、样式、图表、冻结窗格与重算。
|
|
38
|
-
- 🖍️ **侧边栏标注**:在 PDF、DOC/DOCX 预览中吸附段落或框选区域,批量提交修改要求。
|
|
39
|
-
- 🔗 **会话引用**:通过 Chip 调用文档技能;注释链接可悬停查看文件名与要求,PDF 标注附选区截图。
|
|
40
|
-
|
|
41
|
-
## 🚀 快速开始
|
|
42
|
-
|
|
43
|
-
### 通过菜单处理文档
|
|
44
|
-
|
|
45
|
-
<img src="https://raw.githubusercontent.com/hairyf/dsh-office-kit/refs/heads/main/public/image.png" alt="Office 菜单与文档预览" />
|
|
46
|
-
|
|
47
|
-
1. 在输入框键入 `/`,选择 **文档**、**PDF 文档**、**演示文稿** 或 **电子表格**。
|
|
48
|
-
2. 回车插入 Chip,描述创建、读取或修改任务。
|
|
49
|
-
3. 打开生成的文件,在侧边栏预览结果。
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
### 在预览中请求修改
|
|
53
|
-
|
|
54
|
-
| <img src="https://raw.githubusercontent.com/hairyf/dsh-office-kit/refs/heads/main/public/annotation-selection.png" alt="段落吸附与修改要求输入" /> | <img src="https://raw.githubusercontent.com/hairyf/dsh-office-kit/refs/heads/main/public/annotation-conversation.png" alt="注释列表与会话引用" /> |
|
|
55
|
-
| ------------- | ------------- |
|
|
56
|
-
|
|
57
|
-
1. 打开 PDF 或 DOC/DOCX,点击工具栏的 **请求修改**。
|
|
58
|
-
2. 悬停吸附段落,点击或拖动框选,输入要求并添加注释。
|
|
59
|
-
3. 悬停底部 **注释数量** 查看列表,点击 **发送**;**取消** 清空本批。
|
|
60
|
-
|
|
61
|
-
- **Esc**:先取消当前选区,再按一次退出标注模式。
|
|
62
|
-
- **附件**:PDF 附选区截图;DOC/DOCX 仅发送文字与定位信息。
|
|
63
|
-
- **草稿**:已有输入时先合入草稿,由你确认发送;暂存注释刷新后不保留。
|
|
64
|
-
|
|
65
|
-
## 💡 示例文档
|
|
66
|
-
|
|
67
|
-
- [Word](<public/samples/sample.docx>)
|
|
68
|
-
- [PDF](<public/samples/sample.pdf>)
|
|
69
|
-
- [演示文稿](<public/samples/sample.pptx>)
|
|
70
|
-
- [电子表格](<public/samples/sample.xlsx>)
|
|
71
|
-
- [来源与许可](<public/samples/README.md>)
|
|
72
|
-
|
|
73
|
-
## 📚 配置与限制
|
|
74
|
-
|
|
75
|
-
- **Python**:`DSH_OFFICE_PYTHON` 可指定解释器。
|
|
76
|
-
- **标注范围**:仅 PDF、DOC/DOCX;扫描 PDF 可框选截图,不提供 OCR。
|
|
77
|
-
- **本地文件**:不支持 Google Docs / Slides / Sheets 或远程编辑。
|
|
78
|
-
- **完整清单**:[能力与未支持项](<CAPABILITY.md>)。
|
|
79
|
-
|
|
80
|
-
## 🛠️ 开发与贡献
|
|
81
|
-
|
|
82
|
-
```sh
|
|
83
|
-
pnpm install
|
|
84
|
-
pnpm run lint --fix
|
|
85
|
-
pnpm run typecheck
|
|
86
|
-
pnpm run test -- --run
|
|
87
|
-
pnpm run build
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
## 📜️ 许可证
|
|
91
|
-
|
|
92
|
-
- [MIT](<LICENSE.md>)
|
|
93
|
-
- 示例文档保留 [Apache Tika 的许可与声明](<public/samples/README.md>)。
|
|
94
|
-
|
|
95
|
-
<!-- Badges -->
|
|
96
|
-
|
|
97
|
-
[npm-version-src]: https://img.shields.io/npm/v/dsh-office-kit?style=flat&colorA=080f12&colorB=1fa669
|
|
98
|
-
[npm-version-href]: https://npmjs.com/package/dsh-office-kit
|
|
99
|
-
[npm-downloads-src]: https://img.shields.io/npm/dm/dsh-office-kit?style=flat&colorA=080f12&colorB=1fa669
|
|
100
|
-
[npm-downloads-href]: https://npmjs.com/package/dsh-office-kit
|
|
101
|
-
[bundle-src]: https://img.shields.io/bundlephobia/minzip/dsh-office-kit?style=flat&colorA=080f12&colorB=1fa669&label=minzip
|
|
102
|
-
[bundle-href]: https://bundlephobia.com/result?p=dsh-office-kit
|
|
103
|
-
[license-src]: https://img.shields.io/github/license/hairyf/dsh-office-kit.svg?style=flat&colorA=080f12&colorB=1fa669
|
|
104
|
-
[license-href]: https://github.com/hairyf/dsh-office-kit/blob/main/LICENSE
|
|
105
|
-
[jsdocs-src]: https://img.shields.io/badge/jsdocs-reference-080f12?style=flat&colorA=080f12&colorB=1fa669
|
|
106
|
-
[jsdocs-href]: https://www.jsdocs.io/package/dsh-office-kit
|
|
1
|
+
<div align="center"><a name="readme-top"></a>
|
|
2
|
+
|
|
3
|
+
<img src="./public/hero.png" alt="安装插件" />
|
|
4
|
+
|
|
5
|
+
# DSH Office Kit
|
|
6
|
+
|
|
7
|
+
[![npm version][npm-version-src]][npm-version-href]
|
|
8
|
+
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
|
9
|
+
[![bundle][bundle-src]][bundle-href]
|
|
10
|
+
[![JSDocs][jsdocs-src]][jsdocs-href]
|
|
11
|
+
[![License][license-src]][license-href]
|
|
12
|
+
|
|
13
|
+
为 DeepSeek Harness (DSH) 提供本地 Word、PDF、演示文稿与电子表格能力,支持 `/` 菜单、引用 Chip,以及侧边栏预览中的选区标注与修改请求。
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
## 📦 安装
|
|
17
|
+
|
|
18
|
+
在官方插件中安装 `dsh-office-kit`
|
|
19
|
+
|
|
20
|
+
<img src="https://raw.githubusercontent.com/hairyf/dsh-office-kit/refs/heads/main/public/install.png" alt="安装插件" />
|
|
21
|
+
|
|
22
|
+
或使用命令行安装
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
dsh plugin add dsh-office-kit
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- 在 **设置 → 插件** 中启用。
|
|
29
|
+
- 需要 DSH ≥ `0.2.1-rc.2`、Python(无需,没有将自动安装) `3.10`–`3.13`。
|
|
30
|
+
- Windows 缺少兼容 Python 时自动安装;macOS / Linux 使用现有 Python。
|
|
31
|
+
|
|
32
|
+
## 特性
|
|
33
|
+
|
|
34
|
+
- 📝 **Word**:`/documents` 创建、读取和编辑 DOCX,支持表格、图片、公式与页眉页脚。
|
|
35
|
+
- 📄 **PDF**:`/pdf` 创建、读取和编辑 PDF,支持合并、旋转、删页与元数据。
|
|
36
|
+
- 📽️ **演示文稿**:`/presentations` 创建、读取和编辑 PPTX,支持项目符号、表格、图表与图片。
|
|
37
|
+
- 📊 **电子表格**:`/spreadsheets` 创建、读取和编辑 XLSX,支持公式、样式、图表、冻结窗格与重算。
|
|
38
|
+
- 🖍️ **侧边栏标注**:在 PDF、DOC/DOCX 预览中吸附段落或框选区域,批量提交修改要求。
|
|
39
|
+
- 🔗 **会话引用**:通过 Chip 调用文档技能;注释链接可悬停查看文件名与要求,PDF 标注附选区截图。
|
|
40
|
+
|
|
41
|
+
## 🚀 快速开始
|
|
42
|
+
|
|
43
|
+
### 通过菜单处理文档
|
|
44
|
+
|
|
45
|
+
<img src="https://raw.githubusercontent.com/hairyf/dsh-office-kit/refs/heads/main/public/image.png" alt="Office 菜单与文档预览" />
|
|
46
|
+
|
|
47
|
+
1. 在输入框键入 `/`,选择 **文档**、**PDF 文档**、**演示文稿** 或 **电子表格**。
|
|
48
|
+
2. 回车插入 Chip,描述创建、读取或修改任务。
|
|
49
|
+
3. 打开生成的文件,在侧边栏预览结果。
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
### 在预览中请求修改
|
|
53
|
+
|
|
54
|
+
| <img src="https://raw.githubusercontent.com/hairyf/dsh-office-kit/refs/heads/main/public/annotation-selection.png" alt="段落吸附与修改要求输入" /> | <img src="https://raw.githubusercontent.com/hairyf/dsh-office-kit/refs/heads/main/public/annotation-conversation.png" alt="注释列表与会话引用" /> |
|
|
55
|
+
| ------------- | ------------- |
|
|
56
|
+
|
|
57
|
+
1. 打开 PDF 或 DOC/DOCX,点击工具栏的 **请求修改**。
|
|
58
|
+
2. 悬停吸附段落,点击或拖动框选,输入要求并添加注释。
|
|
59
|
+
3. 悬停底部 **注释数量** 查看列表,点击 **发送**;**取消** 清空本批。
|
|
60
|
+
|
|
61
|
+
- **Esc**:先取消当前选区,再按一次退出标注模式。
|
|
62
|
+
- **附件**:PDF 附选区截图;DOC/DOCX 仅发送文字与定位信息。
|
|
63
|
+
- **草稿**:已有输入时先合入草稿,由你确认发送;暂存注释刷新后不保留。
|
|
64
|
+
|
|
65
|
+
## 💡 示例文档
|
|
66
|
+
|
|
67
|
+
- [Word](<public/samples/sample.docx>)
|
|
68
|
+
- [PDF](<public/samples/sample.pdf>)
|
|
69
|
+
- [演示文稿](<public/samples/sample.pptx>)
|
|
70
|
+
- [电子表格](<public/samples/sample.xlsx>)
|
|
71
|
+
- [来源与许可](<public/samples/README.md>)
|
|
72
|
+
|
|
73
|
+
## 📚 配置与限制
|
|
74
|
+
|
|
75
|
+
- **Python**:`DSH_OFFICE_PYTHON` 可指定解释器。
|
|
76
|
+
- **标注范围**:仅 PDF、DOC/DOCX;扫描 PDF 可框选截图,不提供 OCR。
|
|
77
|
+
- **本地文件**:不支持 Google Docs / Slides / Sheets 或远程编辑。
|
|
78
|
+
- **完整清单**:[能力与未支持项](<CAPABILITY.md>)。
|
|
79
|
+
|
|
80
|
+
## 🛠️ 开发与贡献
|
|
81
|
+
|
|
82
|
+
```sh
|
|
83
|
+
pnpm install
|
|
84
|
+
pnpm run lint --fix
|
|
85
|
+
pnpm run typecheck
|
|
86
|
+
pnpm run test -- --run
|
|
87
|
+
pnpm run build
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## 📜️ 许可证
|
|
91
|
+
|
|
92
|
+
- [MIT](<LICENSE.md>)
|
|
93
|
+
- 示例文档保留 [Apache Tika 的许可与声明](<public/samples/README.md>)。
|
|
94
|
+
|
|
95
|
+
<!-- Badges -->
|
|
96
|
+
|
|
97
|
+
[npm-version-src]: https://img.shields.io/npm/v/dsh-office-kit?style=flat&colorA=080f12&colorB=1fa669
|
|
98
|
+
[npm-version-href]: https://npmjs.com/package/dsh-office-kit
|
|
99
|
+
[npm-downloads-src]: https://img.shields.io/npm/dm/dsh-office-kit?style=flat&colorA=080f12&colorB=1fa669
|
|
100
|
+
[npm-downloads-href]: https://npmjs.com/package/dsh-office-kit
|
|
101
|
+
[bundle-src]: https://img.shields.io/bundlephobia/minzip/dsh-office-kit?style=flat&colorA=080f12&colorB=1fa669&label=minzip
|
|
102
|
+
[bundle-href]: https://bundlephobia.com/result?p=dsh-office-kit
|
|
103
|
+
[license-src]: https://img.shields.io/github/license/hairyf/dsh-office-kit.svg?style=flat&colorA=080f12&colorB=1fa669
|
|
104
|
+
[license-href]: https://github.com/hairyf/dsh-office-kit/blob/main/LICENSE
|
|
105
|
+
[jsdocs-src]: https://img.shields.io/badge/jsdocs-reference-080f12?style=flat&colorA=080f12&colorB=1fa669
|
|
106
|
+
[jsdocs-href]: https://www.jsdocs.io/package/dsh-office-kit
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":[],"sources":["../src/features.ts","../src/client/constants.ts","../src/client/quote.ts","../src/client/annotation.ts","../src/client/annotation-reference.tsx","../src/client/document-annotation.tsx","../src/client/icons.tsx","../src/client/office-reference.tsx","../src/client/styles.ts","../src/client/index.ts"],"sourcesContent":["/** Stable identifiers for the four Office entry points. */\nexport type OfficeFeatureId = 'documents' | 'pdf' | 'presentations' | 'spreadsheets'\n\n/** One user-facing Office entry, its skill, and the file types it owns. */\nexport interface OfficeFeature {\n readonly id: OfficeFeatureId\n /** Friendly name used by the '/' menu, chip, and preview. */\n readonly label: string\n /** One-line menu description. */\n readonly description: string\n /** Detail shown after a chip is inserted. */\n readonly hint: string\n /** Skill registered with the DSH skill registry. */\n readonly skill: string\n /** Slash token without the leading '/'. */\n readonly command: string\n /** File extensions shown in menus and documentation. */\n readonly extensions: readonly string[]\n}\n\n/** The four entries, in menu order. */\nexport const OFFICE_FEATURES: readonly OfficeFeature[] = [\n {\n id: 'documents',\n label: 'Documents',\n description: 'Create, edit, render, and verify Word documents (.docx).',\n hint: 'DOCX',\n skill: 'office-documents',\n command: 'documents',\n extensions: ['.docx'],\n },\n {\n id: 'pdf',\n label: 'PDF',\n description: 'Create, read, edit, render, and verify PDF files.',\n hint: 'PDF',\n skill: 'office-pdf',\n command: 'pdf',\n extensions: ['.pdf'],\n },\n {\n id: 'presentations',\n label: 'Presentations',\n description: 'Create, edit, render, and verify slide decks (.pptx).',\n hint: 'PPTX',\n skill: 'office-presentations',\n command: 'presentations',\n extensions: ['.pptx'],\n },\n {\n id: 'spreadsheets',\n label: 'Spreadsheets',\n description: 'Create, edit, recalculate, render, and verify workbooks (.xlsx).',\n hint: 'XLSX',\n skill: 'office-spreadsheets',\n command: 'spreadsheets',\n extensions: ['.xlsx'],\n },\n]\n\n/** Resolve a feature by its stable id; unknown ids are not Office entries. */\nexport function featureById(id: string): OfficeFeature | undefined {\n return OFFICE_FEATURES.find(feature => feature.id === id)\n}\n\n/** Resolve a feature by its slash token (without '/'). */\nexport function featureByCommand(command: string): OfficeFeature | undefined {\n return OFFICE_FEATURES.find(feature => feature.command === command)\n}\n","/** Locale namespace and slash source owned by this plugin. */\nexport const OFFICE_NS = 'dsh-office-kit'\nexport const OFFICE_SOURCE = 'office'\nexport const OFFICE_CHIP = 'office'\nexport const OFFICE_CHIP_SLOT = 'conversation.user.text.node'\n\n/** Additive, session-scoped toolbar contribution inside the official file preview. */\nexport const ANNOTATION_SLOT = 'sidebar.right.tab.document.actions'\nexport const ANNOTATION_ID = 'office-annotations'\nexport const ANNOTATION_ORDER = 20\nexport const ANNOTATION_PRIORITY = 100\nexport const ANNOTATION_NODE = 'officeAnnotation'\nexport const ANNOTATION_OPEN = '<office-annotations>'\nexport const ANNOTATION_CLOSE = '</office-annotations>'\nexport const OFFICE_STYLE_ID = 'dsh-office-kit/reference.css'\nexport const FILE_ADDRESS_PREFIX = 'dsh-resource://file/'\nexport const SESSION_FILE_PREFIX = `${FILE_ADDRESS_PREFIX}session/`\n\n/** Only semantic selectors: no dependency on another plugin's CSS/data attributes. */\nexport const ANNOTATION_CANVAS_SELECTOR = 'canvas[role=\"img\"][aria-label]'\n/** Gravity UI Icons 2.21.0 CommentFill (MIT); original retained in assets/icons/comment-fill.svg. */\nexport const ANNOTATION_CURSOR = `url(\"data:image/svg+xml,${encodeURIComponent('<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" fill=\"none\" viewBox=\"0 0 16 16\"><path fill=\"#466eff\" fill-rule=\"evenodd\" d=\"M8 13c3.866 0 7-2 7-6s-3.134-6-7-6-7 2-7 6c0 2.16.914 3.737 2.364 4.73l.09 2.161a1.157 1.157 0 0 0 1.857.872l2.322-1.77Q7.816 13 8 13\" clip-rule=\"evenodd\"/></svg>')}\") 4 18, crosshair`\nexport const ANNOTATION_HOLD_MS = 350\nexport const ANNOTATION_MIN_REGION = 6\nexport const ANNOTATION_PADDING = 3\nexport const ANNOTATION_HIT_X = 8\nexport const ANNOTATION_HIT_Y = 4\nexport const ANNOTATION_MAX_ITEMS = 50\nexport const ANNOTATION_MAX_TEXT = 20000\nexport const ANNOTATION_MAX_PAYLOAD = 1200000\nexport const ANNOTATION_MAX_PIXELS = 4000000\n","import type { QuotePrompt } from './types'\nimport { SESSION_FILE_PREFIX } from './constants'\n\nfunction decodeSegment(segment: string): string {\n try {\n return decodeURIComponent(segment)\n }\n catch {\n return segment\n }\n}\n\n/** Replace every `{name}` placeholder with its value. */\nexport function fillTemplate(template: string, values: Record<string, string>): string {\n return template.replace(/\\{(\\w+)\\}/gu, (match, name: string) => values[name] ?? match)\n}\n\n/**\n * Collapse what a PDF text layer emits: one line per visual line, padded with\n * spaces and interleaved empty lines.\n */\nexport function normalizeSelection(raw: string): string {\n const lines: string[] = []\n for (const line of raw.replace(/\\r\\n?/gu, '\\n').split('\\n')) {\n const collapsed = line.replace(/\\s+/gu, ' ').trim()\n if (collapsed.length > 0)\n lines.push(collapsed)\n }\n return lines.join('\\n')\n}\n\n/** Quote each line so the agent reads the selection as the document's own words. */\nexport function quoteLines(text: string): string {\n return text.split('\\n').map(line => `> ${line}`).join('\\n')\n}\n\n/** Path part of a `scheme://authority/path` address, apart from its origin. */\nconst PATH_AFTER_ORIGIN = /^(?:[^:/?#]+:)?\\/\\/[^/]+\\/(.*)$/u\n\nfunction pathOf(address: string): string | undefined {\n return PATH_AFTER_ORIGIN.exec(address)?.[1]\n}\n\n/** Last path segment of a preview address: the file's display name. */\nexport function fileNameOf(address: string | undefined): string | undefined {\n if (address === undefined)\n return undefined\n const segment = pathOf(address)?.split('/').pop()\n if (segment === undefined || segment.length === 0)\n return undefined\n const name = decodeSegment(segment)\n return name.length === 0 ? undefined : name\n}\n\n/** Workspace-relative path of a session file address; undefined for other resources. */\nexport function sessionRelativePath(address: string | undefined): string | undefined {\n if (address === undefined || !address.startsWith(SESSION_FILE_PREFIX))\n return undefined\n const rest = address.slice(SESSION_FILE_PREFIX.length)\n const slash = rest.indexOf('/')\n if (slash < 0)\n return undefined\n const path = rest.slice(slash + 1)\n if (path.length === 0)\n return undefined\n return path.split('/').map(decodeSegment).join('/')\n}\n\n/** The message inserted into the composer: target, quoted source, and requirement. */\nexport function composeQuote(prompt: QuotePrompt): string {\n const title = prompt.pageLabel === undefined ? prompt.target : `${prompt.target} · ${prompt.pageLabel}`\n return [\n `${prompt.heading}${title}`,\n '',\n prompt.originalLabel,\n quoteLines(prompt.text),\n '',\n `${prompt.requirementLabel}${prompt.requirement}`,\n ].join('\\n')\n}\n","import type { UserTextRule } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type { AnnotationParagraph, AnnotationRect, AnnotationSelection, AnnotationSendInput, AnnotationTextRun, OfficeAnnotation } from './types'\nimport { ANNOTATION_CANVAS_SELECTOR, ANNOTATION_CLOSE, ANNOTATION_HIT_X, ANNOTATION_HIT_Y, ANNOTATION_MAX_ITEMS, ANNOTATION_MAX_PAYLOAD, ANNOTATION_MAX_PIXELS, ANNOTATION_MAX_TEXT, ANNOTATION_NODE, ANNOTATION_OPEN, ANNOTATION_PADDING } from './constants'\nimport { normalizeSelection } from './quote'\n\nexport function unionRect(a: AnnotationRect, b: AnnotationRect): AnnotationRect {\n const left = Math.min(a.left, b.left)\n const top = Math.min(a.top, b.top)\n return { left, top, width: Math.max(a.left + a.width, b.left + b.width) - left, height: Math.max(a.top + a.height, b.top + b.height) - top }\n}\n\nexport function intersectRect(a: AnnotationRect, b: AnnotationRect): AnnotationRect | undefined {\n const left = Math.max(a.left, b.left)\n const top = Math.max(a.top, b.top)\n const width = Math.min(a.left + a.width, b.left + b.width) - left\n const height = Math.min(a.top + a.height, b.top + b.height) - top\n return width > 0 && height > 0 ? { left, top, width, height } : undefined\n}\n\n/** Leave breathing room around text/regions without extending outside the painted page. */\nexport function paddedRect(box: AnnotationRect, page: AnnotationRect): AnnotationRect | undefined {\n return intersectRect({ left: box.left - ANNOTATION_PADDING, top: box.top - ANNOTATION_PADDING, width: box.width + ANNOTATION_PADDING * 2, height: box.height + ANNOTATION_PADDING * 2 }, page)\n}\n\nexport function containsPoint(box: AnnotationRect, x: number, y: number): boolean {\n return x >= box.left && x <= box.left + box.width && y >= box.top && y <= box.top + box.height\n}\n\n/** Viewport coordinates for a native top-layer popover, independent of chat clipping ancestors. */\nexport function annotationPopoverPosition(anchor: AnnotationRect, popup: Pick<AnnotationRect, 'width' | 'height'>, viewport: Pick<AnnotationRect, 'width' | 'height'>): Pick<AnnotationRect, 'left' | 'top'> {\n return {\n left: Math.max(8, Math.min(anchor.left, viewport.width - popup.width - 8)),\n top: Math.max(8, Math.min(anchor.top >= popup.height + 8 ? anchor.top - popup.height : anchor.top + anchor.height, viewport.height - popup.height - 8)),\n }\n}\n\n/** Small hit slop bridges text edges without expanding the displayed paragraph outline. */\nexport function paragraphAtPoint(paragraphs: readonly AnnotationParagraph[], x: number, y: number): AnnotationParagraph | undefined {\n let hit: AnnotationParagraph | undefined\n for (const paragraph of paragraphs) {\n const box = paragraph.box\n if ((paragraph.rects ?? [box]).some(rect => x >= rect.left - ANNOTATION_HIT_X && x <= rect.left + rect.width + ANNOTATION_HIT_X\n && y >= rect.top - ANNOTATION_HIT_Y && y <= rect.top + rect.height + ANNOTATION_HIT_Y)\n && (!hit || box.width * box.height < hit.box.width * hit.box.height)) {\n hit = paragraph\n }\n }\n return hit\n}\n\n/** PDF text is positioned, not semantic: recover lines, then separate columns and paragraph gaps. */\nexport function groupParagraphs(runs: readonly AnnotationTextRun[]): AnnotationParagraph[] {\n const lines: { text: string, box: AnnotationRect, rects: AnnotationRect[] }[] = []\n for (const run of [...runs].sort((a, b) => a.box.top - b.box.top || a.box.left - b.box.left)) {\n if (!run.text.trim() || run.box.width <= 0 || run.box.height <= 0)\n continue\n const line = lines.find(item => Math.abs(item.box.top - run.box.top) < Math.min(item.box.height, run.box.height) * 0.45\n && run.box.left >= item.box.left && run.box.left - (item.box.left + item.box.width) < run.box.height * 2)\n if (line) {\n line.text += ` ${run.text}`\n line.box = unionRect(line.box, run.box)\n line.rects.push(run.box)\n }\n else {\n lines.push({ text: run.text, box: run.box, rects: [run.box] })\n }\n }\n const paragraphs: { text: string, box: AnnotationRect, rects: AnnotationRect[], last: AnnotationRect }[] = []\n for (const line of lines) {\n const paragraph = paragraphs.findLast((item) => {\n const gap = line.box.top - (item.last.top + item.last.height)\n const overlap = Math.min(item.last.left + item.last.width, line.box.left + line.box.width) - Math.max(item.last.left, line.box.left)\n return gap >= -line.box.height * 0.2 && gap <= Math.min(item.last.height, line.box.height) * 0.7\n && overlap > 0 && Math.abs(item.last.left - line.box.left) < line.box.height * 2\n && Math.max(item.last.height, line.box.height) / Math.min(item.last.height, line.box.height) < 1.4\n })\n if (paragraph) {\n paragraph.text += `\\n${line.text}`\n paragraph.box = unionRect(paragraph.box, line.box)\n paragraph.rects.push(...line.rects)\n paragraph.last = line.box\n }\n else {\n paragraphs.push({ ...line, last: line.box })\n }\n }\n return paragraphs.map(({ text, box, rects }) => ({ text: normalizeSelection(text), box, rects }))\n}\n\n/** Read only the accessible page canvas's sibling text layer, without private PDF.js state. */\nexport function canvasParagraphs(canvas: HTMLCanvasElement): AnnotationParagraph[] {\n const surface = canvas.parentElement\n if (!surface)\n return []\n const walker = document.createTreeWalker(surface, NodeFilter.SHOW_TEXT)\n const runs: AnnotationTextRun[] = []\n for (let node = walker.nextNode(); node; node = walker.nextNode()) {\n if (!node.textContent?.trim())\n continue\n const range = document.createRange()\n range.selectNodeContents(node)\n const box = range.getBoundingClientRect()\n if (box.width > 0 && box.height > 0)\n runs.push({ text: node.textContent, box: { left: box.left, top: box.top, width: box.width, height: box.height } })\n }\n // ponytail: visual paragraphs in PDF/Office previews, replace with a public paragraph API when provided.\n return groupParagraphs(runs)\n}\n\n/** Slot outlets are display:contents wrappers, not the document header itself. */\nexport function annotationPreview(anchor: HTMLElement): { header: HTMLElement, root: HTMLElement } | undefined {\n let header = anchor.parentElement\n while (header && getComputedStyle(header).display === 'contents')\n header = header.parentElement\n return header?.parentElement ? { header, root: header.parentElement } : undefined\n}\n\nexport function canvasAt(preview: HTMLElement, x: number, y: number): { canvas: HTMLCanvasElement, page: number } | undefined {\n const canvases = [...preview.querySelectorAll<HTMLCanvasElement>(ANNOTATION_CANVAS_SELECTOR)]\n const index = canvases.findIndex(canvas => containsPoint(canvas.getBoundingClientRect(), x, y) && canvas.getBoundingClientRect().width > 0)\n return index < 0 ? undefined : { canvas: canvases[index]!, page: index + 1 }\n}\n\nexport function normalizedRegion(box: AnnotationRect, page: AnnotationRect): AnnotationRect {\n if (page.width <= 0 || page.height <= 0)\n throw new Error('annotation.emptyPage')\n const clipped = intersectRect(box, page)\n if (!clipped)\n throw new Error('annotation.emptyRegion')\n return { left: (clipped.left - page.left) / page.width, top: (clipped.top - page.top) / page.height, width: clipped.width / page.width, height: clipped.height / page.height }\n}\n\n/** Copy the selected pixels now, before a zoom, rerender, or tab switch can change the page. */\nexport async function captureAnnotation(selection: AnnotationSelection, name: string, pixelLimit = ANNOTATION_MAX_PIXELS, dimensionLimit = Infinity): Promise<File> {\n const canvas = selection.canvas\n if (!canvas || canvas.width <= 0 || canvas.height <= 0)\n throw new Error('annotation.captureFailed')\n const painted = canvas.getBoundingClientRect()\n const region = selection.region ?? normalizedRegion(selection.box, painted)\n const width = canvas.width * region.width\n const height = canvas.height * region.height\n const scale = Math.min(1, Math.sqrt(pixelLimit / (width * height)), dimensionLimit / width, dimensionLimit / height)\n if (!Number.isFinite(scale) || scale <= 0)\n throw new Error('annotation.captureFailed')\n const output = document.createElement('canvas')\n output.width = Math.max(1, Math.floor(width * scale))\n output.height = Math.max(1, Math.floor(height * scale))\n const context = output.getContext('2d')\n if (!context)\n throw new Error('annotation.captureFailed')\n context.drawImage(canvas, region.left * canvas.width, region.top * canvas.height, width, height, 0, 0, output.width, output.height)\n const blob = await new Promise<Blob>((resolve, reject) => output.toBlob(value => value ? resolve(value) : reject(new Error('annotation.captureFailed')), 'image/png'))\n return new File([blob], name, { type: 'image/png' })\n}\n\nfunction isAnnotation(value: unknown): value is OfficeAnnotation {\n if (typeof value !== 'object' || value === null)\n return false\n const item = value as Record<string, unknown>\n const string = (value: unknown, max: number): boolean => typeof value === 'string' && value.length <= max\n if (!string(item.target, ANNOTATION_MAX_TEXT) || !string(item.fileName, 1000) || !string(item.text, ANNOTATION_MAX_TEXT)\n || !string(item.requirement, ANNOTATION_MAX_TEXT) || !(item.requirement as string).trim()\n || (item.page !== undefined && (!Number.isSafeInteger(item.page) || (item.page as number) < 1))\n || (item.imageName !== undefined && !string(item.imageName, 1000))) {\n return false\n }\n if (item.region !== undefined) {\n const region = item.region as Record<string, unknown> | null\n if (!region || !['left', 'top', 'width', 'height'].every(key => typeof region[key] === 'number' && Number.isFinite(region[key]) && (region[key] as number) >= 0 && (region[key] as number) <= 1))\n return false\n if ((region.width as number) <= 0 || (region.height as number) <= 0\n || (region.left as number) + (region.width as number) > 1.000001 || (region.top as number) + (region.height as number) > 1.000001) {\n return false\n }\n }\n return true\n}\n\n/** Plain text in the normal user message is the durable source of truth; no new Session event. */\nexport function serializeAnnotations(items: readonly OfficeAnnotation[]): string {\n if (!items.length || items.length > ANNOTATION_MAX_ITEMS || !items.every(isAnnotation))\n throw new Error('annotation.invalid')\n const payload = JSON.stringify(items).replace(/</gu, '\\\\u003c')\n if (payload.length > ANNOTATION_MAX_PAYLOAD)\n throw new Error('annotation.tooLarge')\n return `${ANNOTATION_OPEN}\\n${payload}\\n${ANNOTATION_CLOSE}`\n}\n\nexport const annotationRule: UserTextRule<'officeAnnotation'> = {\n id: ANNOTATION_NODE,\n order: 10,\n match(text, from) {\n for (let start = text.indexOf(ANNOTATION_OPEN, from); start >= 0; start = text.indexOf(ANNOTATION_OPEN, start + ANNOTATION_OPEN.length)) {\n const end = text.indexOf(ANNOTATION_CLOSE, start + ANNOTATION_OPEN.length)\n if (end < 0)\n return undefined\n const payload = text.slice(start + ANNOTATION_OPEN.length, end).trim()\n if (payload.length > ANNOTATION_MAX_PAYLOAD)\n continue\n try {\n const items: unknown = JSON.parse(payload)\n if (Array.isArray(items) && items.length > 0 && items.length <= ANNOTATION_MAX_ITEMS && items.every(isAnnotation))\n return { id: ANNOTATION_NODE, start, end: end + ANNOTATION_CLOSE.length, data: { items } }\n }\n catch { /* Invalid/foreign markers remain visible as ordinary text. */ }\n }\n return undefined\n },\n}\n\n/** Prepare one synchronous input transaction; admitted or restored drafts belong to the composer. */\nexport function sendAnnotations({ items, inputActions, intake, limits, existingImages, deferSubmit }: AnnotationSendInput): 'sent' | 'draft' {\n const text = serializeAnnotations(items.map(item => item.annotation))\n const files = items.flatMap(item => item.file ? [item.file] : [])\n if (files.length && !intake)\n throw new Error('annotation.intakeUnavailable')\n if (files.length && limits) {\n if (files.some(file => !limits.mediaTypes.includes(file.type) || file.size > limits.maxImageBytes)\n || existingImages.length + files.length > limits.maxImagesPerMessage\n || [...existingImages, ...files].reduce((sum, file) => sum + file.size, 0) > limits.maxMessageImageBytes) {\n throw new Error('annotation.imageLimit')\n }\n }\n const span = inputActions.captureInsertion()\n const drafts = files.length ? intake!.create(files) : []\n if (drafts.length && !inputActions.addAttachments(drafts.map(item => item.id))) {\n intake!.release(drafts)\n throw new Error('annotation.sendFailed')\n }\n if (!inputActions.insertText(`\\n${text}\\n`, { ...span, start: span.end })) {\n for (const draft of drafts)\n inputActions.removeAttachment(draft.id)\n intake?.release(drafts)\n throw new Error('annotation.sendFailed')\n }\n try {\n inputActions.persistDraft()\n if (deferSubmit)\n return 'draft'\n inputActions.submit()\n return 'sent'\n }\n catch {\n // The text and files are already in the composer; never discard or duplicate them on retry.\n return 'draft'\n }\n}\n","import type { UserTextNodeProps } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { ReactElement } from 'react'\nimport type { OFFICE_NS } from './constants'\nimport type { AnnotationInjected } from './types'\nimport { useId, useLayoutEffect, useRef, useState } from 'react'\nimport { annotationPopoverPosition } from './annotation'\nimport { fillTemplate } from './quote'\n\ntype Props = UserTextNodeProps<'officeAnnotation'> & PropsLocale<typeof OFFICE_NS> & Pick<AnnotationInjected, 'openAnnotation'>\n\n/** The native top layer escapes chat clipping without moving UI outside its slot. */\nexport function AnnotationReference({ node, interactive, openAnnotation, t }: Props): ReactElement {\n const popupId = useId()\n const anchor = useRef<HTMLSpanElement>(null)\n const popup = useRef<HTMLSpanElement>(null)\n const [open, setOpen] = useState(false)\n const label = fillTemplate(t('annotation.count'), { count: String(node.data.items.length) })\n\n useLayoutEffect(() => {\n const element = popup.current\n const trigger = anchor.current\n if (!element || !trigger)\n return\n if (!open) {\n element.hidePopover?.()\n return\n }\n element.showPopover?.()\n const position = (): void => {\n const viewport = { width: document.documentElement.clientWidth, height: window.innerHeight }\n const { left, top } = annotationPopoverPosition(trigger.getBoundingClientRect(), element.getBoundingClientRect(), viewport)\n element.style.left = `${left}px`\n element.style.top = `${top}px`\n }\n const scroll = (event: Event): void => {\n if (event.target instanceof Node && element.contains(event.target))\n return\n setOpen(false)\n }\n const resize = new ResizeObserver(position)\n resize.observe(trigger)\n resize.observe(element)\n window.addEventListener('resize', position)\n document.addEventListener('scroll', scroll, true)\n position()\n return () => {\n element.hidePopover?.()\n resize.disconnect()\n window.removeEventListener('resize', position)\n document.removeEventListener('scroll', scroll, true)\n }\n }, [open])\n\n return (\n <span\n ref={anchor}\n className=\"dsh-office-annotation-reference\"\n onPointerEnter={() => setOpen(true)}\n onPointerLeave={(event) => {\n if (!(event.relatedTarget instanceof Node) || !event.currentTarget.contains(event.relatedTarget))\n setOpen(false)\n }}\n onFocus={() => setOpen(true)}\n onBlur={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget))\n setOpen(false)\n }}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.preventDefault()\n event.stopPropagation()\n if (popup.current?.contains(event.target as Node))\n anchor.current?.querySelector('button')?.focus()\n setOpen(false)\n }\n }}\n >\n <button type=\"button\" id={`${popupId}-trigger`} aria-haspopup=\"dialog\" aria-controls={popupId} aria-expanded={open}>{label}</button>\n <span ref={popup} {...{ popover: 'manual' }} className=\"dsh-office-annotation-popover\" data-open={open} id={popupId} role=\"dialog\" aria-labelledby={`${popupId}-trigger`}>\n <span className=\"dsh-office-annotation-list\">\n {node.data.items.map((item, index) => (\n <span className=\"dsh-office-annotation-item\" key={index}>\n <span className=\"dsh-office-annotation-source\">\n {interactive\n ? <button type=\"button\" onClick={() => openAnnotation(item.target)} title={item.target}>{item.fileName}</button>\n : <span>{item.fileName}</span>}\n </span>\n <span className=\"dsh-office-annotation-requirement\">{item.requirement}</span>\n </span>\n ))}\n </span>\n </span>\n </span>\n )\n}\n","import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { CSSProperties, PointerEvent, ReactElement } from 'react'\nimport type { OFFICE_NS } from './constants'\nimport type { AnnotationInjected, AnnotationRect, AnnotationSelection, PendingAnnotation } from './types'\nimport { useEffect, useId, useRef, useState } from 'react'\nimport { annotationPreview, canvasAt, canvasParagraphs, captureAnnotation, intersectRect, normalizedRegion, paddedRect, paragraphAtPoint, sendAnnotations } from './annotation'\nimport { ANNOTATION_CANVAS_SELECTOR, ANNOTATION_HOLD_MS, ANNOTATION_MAX_ITEMS, ANNOTATION_MAX_TEXT, ANNOTATION_MIN_REGION } from './constants'\nimport { fillTemplate } from './quote'\n\ntype Props = PropsRuntime<'sidebar.right.tab.document.actions'> & PropsLocale<typeof OFFICE_NS> & AnnotationInjected\n\n/** This slot is rendered by the document header; every overlay stays in this React subtree. */\nexport function DocumentAnnotation(props: Props): ReactElement | null {\n if (!/\\.(?:pdf|docx?)$/iu.test(props.absolutePath))\n return null\n return <AnnotationTool key={props.absolutePath} {...props} />\n}\n\nfunction AnnotationTool({ absolutePath, pendingAnnotations, intake, inputActions, useInput, useProjection, t }: Props): ReactElement {\n const anchor = useRef<HTMLSpanElement>(null)\n const form = useRef<HTMLFormElement>(null)\n const surface = useRef<HTMLDivElement>(null)\n const preview = useRef<HTMLElement>()\n const [bounds, setBounds] = useState<AnnotationRect>()\n const [active, setActive] = useState(false)\n const [hover, setHover] = useState<AnnotationSelection>()\n const [selection, setSelection] = useState<AnnotationSelection>()\n const [requirement, setRequirement] = useState('')\n const [image, setImage] = useState<File>()\n const [capturing, setCapturing] = useState(false)\n const [dragging, setDragging] = useState(false)\n const [items, setItems] = useState<readonly PendingAnnotation[]>(() => pendingAnnotations.get(absolutePath) ?? [])\n const [summaryDismissed, setSummaryDismissed] = useState(false)\n const summaryId = useId()\n const [error, setError] = useState('')\n const input = useInput(state => state)\n const limits = useProjection('imageLimits')\n const isPdf = /\\.pdf$/iu.test(absolutePath)\n const fileName = absolutePath.replace(/\\\\/gu, '/').split('/').pop() ?? absolutePath\n const revision = useRef(0)\n const hold = useRef<ReturnType<typeof setTimeout>>()\n const gesture = useRef<{ x: number, y: number, lastX: number, lastY: number, canvas: HTMLCanvasElement, page: number, region: boolean }>()\n const cache = useRef<{ canvas: HTMLCanvasElement, box: AnnotationRect, paragraphs: ReturnType<typeof canvasParagraphs> }>()\n const disabled = input.phase !== 'plain'\n\n useEffect(() => {\n if (items.length)\n pendingAnnotations.set(absolutePath, items)\n else\n pendingAnnotations.delete(absolutePath)\n }, [absolutePath, items, pendingAnnotations])\n\n function dismiss(): void {\n revision.current++\n setSelection(undefined)\n setImage(undefined)\n setCapturing(false)\n setRequirement('')\n }\n\n function cancelGesture(): void {\n clearTimeout(hold.current)\n gesture.current = undefined\n setDragging(false)\n setHover(undefined)\n }\n\n useEffect(() => {\n const node = anchor.current\n const container = node && annotationPreview(node)\n if (!container)\n return\n const { header, root } = container\n preview.current = root\n let frame = 0\n const measure = (): void => {\n cancelAnimationFrame(frame)\n frame = requestAnimationFrame(() => {\n cache.current = undefined\n const rect = root.getBoundingClientRect()\n const top = Math.max(rect.top, header.getBoundingClientRect().bottom, 0)\n const bottom = Math.min(rect.bottom, window.innerHeight)\n const left = Math.max(0, rect.left)\n const right = Math.min(rect.right, window.innerWidth)\n const canvas = [...root.querySelectorAll<HTMLCanvasElement>(ANNOTATION_CANVAS_SELECTOR)].find(canvas => canvas.getBoundingClientRect().width > 0)\n const visible = root.isConnected && !root.closest('[hidden], [aria-hidden=\"true\"]') && getComputedStyle(root).visibility === 'visible'\n setBounds(visible && rect.height > 40 && canvas && right > left && bottom > top\n ? { left, top, width: right - left, height: bottom - top }\n : undefined)\n // Keep the saved page-relative region and comment when viewport geometry changes.\n setSelection((previous) => {\n if (!previous?.canvas || !previous.region)\n return previous\n const page = previous.canvas.getBoundingClientRect()\n const region = previous.region\n const box = { left: page.left + region.left * page.width, top: page.top + region.top * page.height, width: region.width * page.width, height: region.height * page.height }\n return Object.keys(box).every(key => box[key as keyof AnnotationRect] === previous.box[key as keyof AnnotationRect]) ? previous : { ...previous, box }\n })\n })\n }\n const resize = new ResizeObserver(measure)\n resize.observe(root)\n const mutation = new MutationObserver((records) => {\n if (records.some(record => !node.contains(record.target)))\n measure()\n })\n mutation.observe(root, { childList: true, subtree: true, attributes: true, attributeFilter: ['hidden', 'aria-hidden', 'class', 'style'] })\n for (let parent = root.parentElement; parent; parent = parent.parentElement)\n mutation.observe(parent, { attributes: true })\n window.addEventListener('resize', measure)\n root.addEventListener('transitionend', measure)\n root.addEventListener('scroll', measure, true)\n measure()\n return () => {\n revision.current++\n clearTimeout(hold.current)\n cancelAnimationFrame(frame)\n resize.disconnect()\n mutation.disconnect()\n window.removeEventListener('resize', measure)\n root.removeEventListener('transitionend', measure)\n root.removeEventListener('scroll', measure, true)\n preview.current = undefined\n }\n }, [])\n\n useEffect(() => {\n if (!selection)\n return\n const dismissOutside = (event: globalThis.PointerEvent): void => {\n if (event.target instanceof Node && !form.current?.contains(event.target))\n dismiss()\n }\n document.addEventListener('pointerdown', dismissOutside, true)\n form.current?.querySelector('input')?.focus()\n return () => {\n document.removeEventListener('pointerdown', dismissOutside, true)\n }\n }, [selection])\n\n useEffect(() => {\n if (active)\n surface.current?.focus()\n }, [active])\n\n function scrollPreview(x: number, y: number): void {\n const root = preview.current\n if (!root)\n return\n let scroll = root.querySelector(ANNOTATION_CANVAS_SELECTOR)?.parentElement\n while (scroll && scroll !== root && !/auto|scroll/u.test(getComputedStyle(scroll).overflowY))\n scroll = scroll.parentElement\n scroll?.scrollBy({ left: x, top: y })\n setHover(undefined)\n }\n\n useEffect(() => {\n const node = surface.current\n if (!active || !node || !bounds)\n return\n const wheel = (event: WheelEvent): void => {\n event.preventDefault()\n const unit = event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? bounds.height : 1\n scrollPreview(event.deltaX * unit, event.deltaY * unit)\n }\n node.addEventListener('wheel', wheel, { passive: false })\n return () => node.removeEventListener('wheel', wheel)\n }, [active, bounds])\n\n function paragraphAt(x: number, y: number): AnnotationSelection | undefined {\n if (!preview.current)\n return undefined\n const page = canvasAt(preview.current, x, y)\n if (!page)\n return undefined\n const box = page.canvas.getBoundingClientRect()\n if (cache.current?.canvas !== page.canvas || cache.current.box.left !== box.left || cache.current.box.top !== box.top\n || cache.current.box.width !== box.width || cache.current.box.height !== box.height) {\n cache.current = { canvas: page.canvas, box, paragraphs: canvasParagraphs(page.canvas) }\n }\n const paragraph = paragraphAtPoint(cache.current.paragraphs, x, y)\n return paragraph ? { ...paragraph, ...page } : undefined\n }\n\n function regionSelection(x: number, y: number): AnnotationSelection | undefined {\n const start = gesture.current\n if (!start)\n return undefined\n const box = intersectRect({ left: Math.min(start.x, x), top: Math.min(start.y, y), width: Math.abs(x - start.x), height: Math.abs(y - start.y) }, start.canvas.getBoundingClientRect())\n if (!box)\n return undefined\n const paragraphs = cache.current?.canvas === start.canvas ? cache.current.paragraphs : canvasParagraphs(start.canvas)\n return { canvas: start.canvas, page: start.page, box, region: normalizedRegion(box, start.canvas.getBoundingClientRect()), text: paragraphs.filter(item => (item.rects ?? [item.box]).some(rect => intersectRect(rect, box))).map(item => item.text).join('\\n').slice(0, ANNOTATION_MAX_TEXT) }\n }\n\n function pointerDown(event: PointerEvent<HTMLDivElement>): void {\n if (event.button !== 0 || !preview.current || (isPdf && !intake))\n return\n const page = canvasAt(preview.current, event.clientX, event.clientY)\n if (!page)\n return\n event.preventDefault()\n dismiss()\n const start = { ...page, x: event.clientX, y: event.clientY, lastX: event.clientX, lastY: event.clientY, region: false }\n gesture.current = start\n event.currentTarget.setPointerCapture(event.pointerId)\n hold.current = setTimeout(() => {\n if (gesture.current !== start)\n return\n start.region = true\n setDragging(true)\n setHover(regionSelection(start.lastX, start.lastY))\n }, ANNOTATION_HOLD_MS)\n }\n\n function pointerMove(event: PointerEvent<HTMLDivElement>): void {\n const start = gesture.current\n if (start) {\n start.lastX = event.clientX\n start.lastY = event.clientY\n if (!start.region && Math.hypot(event.clientX - start.x, event.clientY - start.y) >= ANNOTATION_MIN_REGION) {\n clearTimeout(hold.current)\n start.region = true\n setDragging(true)\n }\n }\n setHover(start?.region ? regionSelection(event.clientX, event.clientY) : paragraphAt(event.clientX, event.clientY))\n }\n\n async function openSelection(value: AnnotationSelection): Promise<void> {\n dismiss()\n const current = revision.current\n setError('')\n const page = value.canvas?.getBoundingClientRect()\n const box = page ? paddedRect(value.box, page) : value.box\n if (!box)\n return\n const region = page ? normalizedRegion(box, page) : value.region\n const frozen = { ...value, box, region }\n setSelection(frozen)\n if (!isPdf)\n return\n setCapturing(true)\n try {\n const file = await captureAnnotation(frozen, `${fileName}-p${value.page}-${Date.now()}.png`, limits?.maxImagePixels, limits?.maxImageDimension)\n if (revision.current === current)\n setImage(file)\n }\n catch {\n if (revision.current === current)\n setError(t('annotation.captureFailed'))\n }\n finally {\n if (revision.current === current)\n setCapturing(false)\n }\n }\n\n function pointerUp(event: PointerEvent<HTMLDivElement>): void {\n const start = gesture.current\n clearTimeout(hold.current)\n if (!start)\n return\n const value = start.region ? regionSelection(event.clientX, event.clientY) : paragraphAt(event.clientX, event.clientY)\n const moved = Math.hypot(event.clientX - start.x, event.clientY - start.y)\n cancelGesture()\n if (value && (start.region ? value.box.width >= ANNOTATION_MIN_REGION && value.box.height >= ANNOTATION_MIN_REGION : moved < ANNOTATION_MIN_REGION))\n void openSelection(value)\n }\n\n function add(): void {\n if (!selection || !requirement.trim() || (isPdf && !image) || items.length >= ANNOTATION_MAX_ITEMS)\n return\n const annotation = {\n target: absolutePath,\n fileName,\n page: selection.page,\n text: selection.text.slice(0, ANNOTATION_MAX_TEXT),\n requirement: requirement.trim(),\n region: selection.region,\n imageName: image?.name,\n }\n setItems(previous => [...previous, { annotation, file: image }])\n dismiss()\n }\n\n function send(): void {\n if (disabled)\n return\n try {\n const result = sendAnnotations({\n items,\n inputActions,\n intake,\n limits,\n existingImages: intake?.images(input.attachmentIds) ?? [],\n deferSubmit: !!input.draft.trim() || input.attachmentIds.length > 0,\n })\n setItems([])\n setSummaryDismissed(false)\n setActive(false)\n dismiss()\n setError(result === 'draft' ? t('annotation.draftReady') : '')\n }\n catch (error) {\n const key = error instanceof Error ? error.message : 'annotation.sendFailed'\n setError(t(key.startsWith('annotation.') ? key : 'annotation.sendFailed'))\n }\n }\n\n const highlight = selection ?? hover\n const highlightBox = highlight && !selection && !dragging && highlight.canvas\n ? paddedRect(highlight.box, highlight.canvas.getBoundingClientRect())\n : highlight?.box\n const clippedHighlight = highlightBox && bounds ? intersectRect(highlightBox, bounds) : undefined\n const formWidth = bounds ? Math.min(360, bounds.width - 16) : 0\n const formLeft = bounds && selection ? Math.max(bounds.left + 8, Math.min(selection.box.left, bounds.left + bounds.width - formWidth - 8)) : 0\n const formTop = bounds && selection ? Math.max(bounds.top + 4, Math.min(selection.box.top + selection.box.height + 6, bounds.top + bounds.height - 56)) : 0\n\n return (\n <span\n ref={anchor}\n className=\"dsh-office-annotate\"\n onKeyDown={(event) => {\n if (!active || event.key !== 'Escape')\n return\n event.preventDefault()\n event.stopPropagation()\n const hasSelection = !!selection || !!gesture.current\n dismiss()\n cancelGesture()\n if (hasSelection) {\n surface.current?.focus()\n }\n else {\n setActive(false)\n anchor.current?.querySelector('button')?.focus()\n }\n }}\n >\n <button\n type=\"button\"\n className=\"dsh-office-annotate-toggle\"\n aria-pressed={active}\n disabled={!bounds || (isPdf && !intake)}\n title={isPdf && !intake ? t('annotation.intakeUnavailable') : !bounds ? t('annotation.unavailable') : t('annotation.help')}\n onClick={() => {\n setActive(value => !value)\n dismiss()\n cancelGesture()\n }}\n >\n {t('annotation.ask')}\n </button>\n {isPdf && !intake && <span role=\"status\" className=\"dsh-office-annotate-unavailable\">{t('annotation.intakeUnavailable')}</span>}\n {active && bounds && (\n <div\n ref={surface}\n className=\"dsh-office-annotate-surface\"\n tabIndex={0}\n style={{ left: bounds.left, top: bounds.top, width: bounds.width, height: bounds.height }}\n role=\"region\"\n aria-label={t('annotation.help')}\n onPointerDown={pointerDown}\n onPointerMove={pointerMove}\n onPointerUp={pointerUp}\n onPointerCancel={cancelGesture}\n onLostPointerCapture={cancelGesture}\n onKeyDown={(event) => {\n if (event.key === 'PageDown' || event.key === 'PageUp') {\n event.preventDefault()\n scrollPreview(0, bounds.height * (event.key === 'PageDown' ? 0.8 : -0.8))\n }\n else if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault()\n const paragraphs = [...preview.current!.querySelectorAll<HTMLCanvasElement>(ANNOTATION_CANVAS_SELECTOR)].flatMap((canvas, index) => canvasParagraphs(canvas).filter(item => intersectRect(item.box, bounds)).map(item => ({ ...item, canvas, page: index + 1 })))\n const current = paragraphs.findIndex(item => item.canvas === hover?.canvas && item.text === hover.text && item.box.top === hover.box.top)\n const index = current < 0 ? (event.key === 'ArrowDown' ? 0 : paragraphs.length - 1) : Math.max(0, Math.min(paragraphs.length - 1, current + (event.key === 'ArrowDown' ? 1 : -1)))\n setHover(paragraphs[index])\n }\n else if ((event.key === 'Enter' || event.key === ' ') && hover) {\n event.preventDefault()\n void openSelection(hover)\n }\n }}\n onPointerLeave={() => {\n if (!gesture.current)\n setHover(undefined)\n }}\n />\n )}\n {active && clippedHighlight && (\n <span className=\"dsh-office-annotate-highlight\" data-selected={selection || dragging ? 'true' : undefined} style={{ left: clippedHighlight.left, top: clippedHighlight.top, width: clippedHighlight.width, height: clippedHighlight.height }} />\n )}\n {active && selection && bounds && (\n <form\n ref={form}\n className=\"dsh-office-annotate-composer\"\n style={{ left: formLeft, top: formTop, width: formWidth }}\n aria-label={t('annotation.ask')}\n aria-busy={capturing}\n onSubmit={(event) => {\n event.preventDefault()\n add()\n }}\n >\n <input\n type=\"text\"\n aria-label={t('annotation.placeholder')}\n placeholder={t('annotation.placeholder')}\n value={requirement}\n maxLength={ANNOTATION_MAX_TEXT}\n onChange={event => setRequirement(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' && event.nativeEvent.isComposing)\n event.preventDefault()\n }}\n />\n <button type=\"submit\" aria-label={t(capturing ? 'annotation.capturing' : 'annotation.add')} title={t(capturing ? 'annotation.capturing' : 'annotation.add')} disabled={!requirement.trim() || capturing || (isPdf && !image) || items.length >= ANNOTATION_MAX_ITEMS}>\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\"><path d=\"m5 12 4 4L19 6\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" /></svg>\n </button>\n </form>\n )}\n {(active || items.length > 0 || error) && bounds && (\n <div className=\"dsh-office-annotate-rail-position\" style={{ 'left': bounds.left, 'width': bounds.width, 'bottom': Math.max(0, window.innerHeight - bounds.top - bounds.height) + 12, '--dsh-office-annotation-width': `${bounds.width}px`, '--dsh-office-annotation-height': `${bounds.height}px` } as CSSProperties}>\n <div className=\"dsh-office-annotate-rail\">\n {error && <p role=\"alert\">{error}</p>}\n <div className=\"dsh-office-annotate-rail-actions\">\n <div\n className=\"dsh-office-annotate-summary\"\n data-dismissed={summaryDismissed ? 'true' : undefined}\n onPointerEnter={() => setSummaryDismissed(false)}\n onFocus={() => setSummaryDismissed(false)}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.stopPropagation()\n event.currentTarget.querySelector('button')?.focus()\n setSummaryDismissed(true)\n }\n }}\n >\n <button type=\"button\" aria-haspopup=\"dialog\" aria-controls={summaryId} disabled={!items.length}>{fillTemplate(t('annotation.count'), { count: String(items.length) })}</button>\n {items.length > 0 && (\n <div id={summaryId} role=\"dialog\" aria-label={fillTemplate(t('annotation.count'), { count: String(items.length) })} className=\"dsh-office-annotate-popover\">\n <ul>\n {items.map((item, index) => (\n <li key={item.annotation.imageName ?? index}>\n <div>\n <span className=\"dsh-office-annotation-source\">\n <span title={item.annotation.target}>{item.annotation.fileName}</span>\n {item.annotation.page && <span>{fillTemplate(t('annotation.page'), { page: String(item.annotation.page) })}</span>}\n </span>\n {item.annotation.text && <span className=\"dsh-office-annotation-original\">{item.annotation.text}</span>}\n <span className=\"dsh-office-annotation-requirement\" title={item.annotation.requirement}>{item.annotation.requirement}</span>\n </div>\n </li>\n ))}\n </ul>\n </div>\n )}\n </div>\n <button\n type=\"button\"\n onClick={() => {\n setItems([])\n setActive(false)\n setSummaryDismissed(false)\n setError('')\n dismiss()\n cancelGesture()\n }}\n >\n {t('annotation.cancel')}\n </button>\n <button type=\"button\" className=\"dsh-office-annotate-primary\" disabled={!items.length || disabled} onClick={send}>{t('annotation.send')}</button>\n </div>\n </div>\n </div>\n )}\n </span>\n )\n}\n","import type { ReactElement, SVGProps } from 'react'\nimport type { OfficeFeatureId } from '../features'\n\n/*\n * Icons from Gravity UI Icons (MIT), https://github.com/gravity-ui/icons.\n * The original SVG files and license are vendored in assets/icons/.\n */\n\ntype OfficeIconProps = SVGProps<SVGSVGElement> & { size?: number }\n\nfunction frame(props: OfficeIconProps): SVGProps<SVGSVGElement> {\n const { size = 16, ...rest } = props\n return {\n 'width': size,\n 'height': size,\n 'viewBox': '0 0 16 16',\n 'fill': 'none',\n 'aria-hidden': true,\n ...rest,\n }\n}\n\n/** file-text: a document page with text lines. */\nexport function DocumentsIcon(props: OfficeIconProps): ReactElement {\n return (\n <svg {...frame(props)}>\n <path\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M5 13.5h6a1.5 1.5 0 0 0 1.5-1.5V7.243a1.5 1.5 0 0 0-.44-1.061L8.819 2.939a1.5 1.5 0 0 0-1.06-.439H5A1.5 1.5 0 0 0 3.5 4v8A1.5 1.5 0 0 0 5 13.5m9-6.257a3 3 0 0 0-.879-2.122L9.88 1.88A3 3 0 0 0 7.757 1H5a3 3 0 0 0-3 3v8a3 3 0 0 0 3 3h6a3 3 0 0 0 3-3zM5 8.25a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5A.75.75 0 0 1 5 8.25m.75 2.25a.75.75 0 0 0 0 1.5h2.5a.75.75 0 0 0 0-1.5z\"\n />\n </svg>\n )\n}\n\n/** file-letter-p: a document page with a P badge. */\nexport function PdfIcon(props: OfficeIconProps): ReactElement {\n return (\n <svg {...frame(props)}>\n <path\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M11 13.5H5A1.5 1.5 0 0 1 3.5 12V4A1.5 1.5 0 0 1 5 2.5h2.757a1.5 1.5 0 0 1 1.061.44l3.243 3.242a1.5 1.5 0 0 1 .439 1.06V12a1.5 1.5 0 0 1-1.5 1.5m2.121-8.379A3 3 0 0 1 14 7.243V12a3 3 0 0 1-3 3H5a3 3 0 0 1-3-3V4a3 3 0 0 1 3-3h2.757a3 3 0 0 1 2.122.879zM6.5 6.5a.75.75 0 0 0-.75.75v4a.75.75 0 0 0 1.5 0v-.75H8.5a2 2 0 1 0 0-4zm2 2.5H7.25V8H8.5a.5.5 0 0 1 0 1\"\n />\n </svg>\n )\n}\n\n/** display: a presentation screen. */\nexport function PresentationsIcon(props: OfficeIconProps): ReactElement {\n return (\n <svg {...frame(props)}>\n <path\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M12 3H4a1.5 1.5 0 0 0-1.5 1.5v4A1.5 1.5 0 0 0 4 10h8a1.5 1.5 0 0 0 1.5-1.5v-4A1.5 1.5 0 0 0 12 3M4 1.5a3 3 0 0 0-3 3v4a3 3 0 0 0 3 3h3.25V13h-2.5a.75.75 0 0 0 0 1.5h6.5a.75.75 0 0 0 0-1.5h-2.5v-1.5H12a3 3 0 0 0 3-3v-4a3 3 0 0 0-3-3z\"\n />\n </svg>\n )\n}\n\n/** layout-cells: a spreadsheet grid. */\nexport function SpreadsheetsIcon(props: OfficeIconProps): ReactElement {\n return (\n <svg {...frame(props)}>\n <path\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M9.25 3.5h-2.5v2h2.5zM4 3.5h1.25v2H2.5V5A1.5 1.5 0 0 1 4 3.5M2.5 7h2.75v2H2.5zm0 3.5v.5A1.5 1.5 0 0 0 4 12.5h1.25v-2zm4.25 0v2h2.5v-2zm4 0v2H12a1.5 1.5 0 0 0 1.5-1.5v-.5zM13.5 9h-2.75V7h2.75zM9.25 9h-2.5V7h2.5zm1.5-5.5v2h2.75V5A1.5 1.5 0 0 0 12 3.5zM4 2a3 3 0 0 0-3 3v6a3 3 0 0 0 3 3h8a3 3 0 0 0 3-3V5a3 3 0 0 0-3-3z\"\n />\n </svg>\n )\n}\n\nexport const OFFICE_ICONS: Record<OfficeFeatureId, (props: OfficeIconProps) => ReactElement> = {\n documents: DocumentsIcon,\n pdf: PdfIcon,\n presentations: PresentationsIcon,\n spreadsheets: SpreadsheetsIcon,\n}\n","import type { UserTextNodeProps } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type { ReactElement } from 'react'\nimport type { OfficeChipInjected } from './types'\nimport { featureById } from '../features'\nimport { OFFICE_ICONS } from './icons'\n\ntype Props = UserTextNodeProps<'office'> & OfficeChipInjected\n\n/** Render the office reference chip with its format glyph. */\nexport function OfficeReference({ node, raw, interactive, openOffice, officeLabel }: Props): ReactElement {\n const feature = featureById(node.data.feature)\n if (feature == null)\n return <span>{raw}</span>\n\n const Icon = OFFICE_ICONS[feature.id]\n const content = (\n <>\n <Icon className=\"dsh-office-ref-icon\" size={14} />\n <span>{officeLabel(feature.id)}</span>\n </>\n )\n\n if (!interactive) {\n return (\n <span className=\"dsh-office-ref\" title={raw}>\n {content}\n </span>\n )\n }\n\n return (\n <button\n type=\"button\"\n className=\"dsh-office-ref\"\n title={raw}\n data-interactive\n onClick={() => openOffice(feature.id)}\n >\n {content}\n </button>\n )\n}\n","import { ANNOTATION_CURSOR, OFFICE_NS, OFFICE_STYLE_ID } from './constants'\n\n/** One plugin-scoped style tag; the disposer owns removal. */\nexport function mountOfficeStyles(): () => void {\n if (typeof document === 'undefined')\n return () => {}\n\n const style = document.querySelector<HTMLStyleElement>(`style[data-plugin-css=\"${OFFICE_STYLE_ID}\"]`) ?? document.createElement('style')\n style.dataset.plugin = OFFICE_NS\n style.dataset.pluginCss = OFFICE_STYLE_ID\n style.textContent = `\n.dsh-office-ref {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n max-width: 100%;\n height: calc(20px + var(--dsh-content-font-delta, 0px));\n padding: 0 6px;\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-base);\n color: var(--dsw-alias-label-secondary);\n font: inherit;\n line-height: 1;\n vertical-align: baseline;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.dsh-office-ref[data-interactive] { cursor: pointer; }\n.dsh-office-ref[data-interactive]:hover {\n background: var(--dsw-alias-interactive-bg-hover-solid);\n color: var(--dsw-alias-label-primary);\n}\n.dsh-office-ref[data-interactive]:focus-visible {\n outline: 2px solid var(--dsw-alias-state-business-primary);\n outline-offset: 1px;\n}\n.dsh-office-ref-icon { flex: none; color: var(--dsw-alias-label-tertiary); }\n.dsh-office-ref[data-interactive]:hover .dsh-office-ref-icon { color: inherit; }\n.dsh-office-annotate { display: inline-flex; flex: none; }\n.dsh-office-annotate,\n.dsh-office-annotation-reference { font: 400 12px/18px var(--dsw-font-family, system-ui, sans-serif); }\n.dsh-office-annotate *,\n.dsh-office-annotation-reference * { box-sizing: border-box; }\n.dsh-office-annotate button,\n.dsh-office-annotation-reference button {\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--dsw-radius-md);\n padding: 5px 9px;\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-base);\n font: inherit;\n font-size: 12px;\n line-height: 1.4;\n cursor: pointer;\n}\n.dsh-office-annotate button:disabled { opacity: .45; cursor: not-allowed; }\n.dsh-office-annotate button:hover:not(:disabled),\n.dsh-office-annotation-reference button:hover { background: var(--dsw-alias-interactive-bg-hover-solid); }\n.dsh-office-annotate button:focus-visible,\n.dsh-office-annotation-reference button:focus-visible {\n outline: 2px solid var(--dsw-alias-state-business-primary);\n outline-offset: 2px;\n}\n.dsh-office-annotate .dsh-office-annotate-toggle {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 24px;\n padding: 0 8px;\n line-height: 1;\n}\n.dsh-office-annotate .dsh-office-annotate-toggle[aria-pressed=\"true\"],\n.dsh-office-annotate .dsh-office-annotate-primary {\n color: var(--dsw-alias-state-business-primary);\n border-color: var(--dsw-alias-state-business-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 10%, var(--dsw-alias-bg-base));\n}\n.dsh-office-annotate .dsh-office-annotate-surface {\n position: fixed;\n z-index: 40;\n touch-action: none;\n user-select: none;\n outline: none;\n cursor: ${ANNOTATION_CURSOR};\n}\n.dsh-office-annotate .dsh-office-annotate-highlight {\n position: fixed;\n z-index: 41;\n box-sizing: border-box;\n pointer-events: none;\n border: 1.25px solid var(--dsw-alias-state-business-primary);\n border-radius: 3px;\n}\n.dsh-office-annotate .dsh-office-annotate-highlight[data-selected=\"true\"] {\n border-style: dashed;\n background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 8%, transparent);\n}\n.dsh-office-annotate .dsh-office-annotate-composer {\n position: fixed;\n z-index: 42;\n box-sizing: border-box;\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n box-shadow: var(--dsw-shadow-lv2);\n}\n.dsh-office-annotate .dsh-office-annotate-composer {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px;\n border-radius: 999px;\n}\n.dsh-office-annotate .dsh-office-annotate-composer input:focus-visible { outline: none; }\n.dsh-office-annotate .dsh-office-annotate-composer input {\n box-sizing: border-box;\n min-width: 0;\n width: 100%;\n padding: 6px 10px;\n border: 0;\n border-radius: 999px;\n color: var(--dsw-alias-label-primary);\n background: transparent;\n font: inherit;\n font-size: 12px;\n line-height: 1.5;\n}\n.dsh-office-annotate .dsh-office-annotate-composer button {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 0;\n border: 0;\n border-radius: 50%;\n color: var(--dsw-alias-state-business-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 10%, var(--dsw-alias-bg-base));\n}\n.dsh-office-annotate .dsh-office-annotate-composer button svg { width: 14px; height: 14px; }\n.dsh-office-annotate .dsh-office-annotate-rail-position {\n position: fixed;\n z-index: 42;\n display: flex;\n justify-content: center;\n padding: 0 8px;\n pointer-events: none;\n}\n.dsh-office-annotate .dsh-office-annotate-rail {\n position: relative;\n width: max-content;\n max-width: 100%;\n padding: 4px 6px;\n border-radius: 10px;\n background: var(--dsw-alias-toast-bg);\n color: var(--dsw-alias-toast-label);\n font: 500 12px/18px var(--dsw-font-family, system-ui, sans-serif);\n box-shadow: var(--dsw-shadow-lv3);\n pointer-events: auto;\n}\n.dsh-office-annotate .dsh-office-annotate-rail-actions { display: flex; align-items: center; justify-content: center; gap: 4px; }\n.dsh-office-annotate .dsh-office-annotate-rail-actions > button,\n.dsh-office-annotate .dsh-office-annotate-summary > button {\n height: 26px;\n padding: 0 8px;\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: inherit;\n font: inherit;\n white-space: nowrap;\n}\n.dsh-office-annotate .dsh-office-annotate-summary { padding-right: 4px; border-right: 1px solid color-mix(in srgb, var(--dsw-alias-toast-label) 25%, transparent); }\n.dsh-office-annotate .dsh-office-annotate-rail-actions > button:hover:not(:disabled),\n.dsh-office-annotate .dsh-office-annotate-summary > button:hover:not(:disabled) { background: color-mix(in srgb, var(--dsw-alias-toast-label) 12%, transparent); }\n.dsh-office-annotate .dsh-office-annotate-rail-actions > .dsh-office-annotate-primary { background: var(--dsw-alias-state-business-primary); color: var(--dsw-alias-toast-label); }\n.dsh-office-annotate .dsh-office-annotate-rail-actions > .dsh-office-annotate-primary:hover:not(:disabled) { background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 85%, var(--dsw-alias-toast-label)); }\n.dsh-office-annotate .dsh-office-annotate-rail p { max-width: min(360px, calc(var(--dsh-office-annotation-width) - 48px)); margin: 0 0 6px; font-size: 12px; overflow-wrap: anywhere; }\n.dsh-office-annotate .dsh-office-annotate-popover {\n display: none;\n position: absolute;\n bottom: 100%;\n left: 50%;\n width: min(320px, calc(var(--dsh-office-annotation-width, 100vw) - 16px), calc(100vw - 16px));\n box-sizing: border-box;\n padding-bottom: 8px;\n transform: translateX(-50%);\n}\n.dsh-office-annotate .dsh-office-annotate-summary:not([data-dismissed=\"true\"]):is(:hover, :focus-within) > .dsh-office-annotate-popover { display: block; }\n.dsh-office-annotation-reference { display: inline-block; position: relative; max-width: 100%; vertical-align: baseline; font: inherit; }\n.dsh-office-annotation-reference > button {\n max-width: 100%;\n padding: 0;\n border: 0;\n border-radius: 0;\n background: transparent;\n color: var(--dsw-alias-link);\n font: inherit;\n font-family: var(--dsw-font-markdown-code-font-family);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n vertical-align: baseline;\n}\n.dsh-office-annotation-reference > button:hover {\n background: transparent;\n text-decoration: underline dotted;\n text-underline-offset: 3px;\n}\n.dsh-office-annotation-reference .dsh-office-annotation-popover {\n display: none;\n position: fixed;\n z-index: 44;\n inset: auto;\n width: min(320px, calc(100vw - 16px));\n max-height: calc(100vh - 16px);\n box-sizing: border-box;\n margin: 0;\n padding: 4px 0;\n border: 0;\n background: transparent;\n color: var(--dsw-alias-label-primary);\n overflow: visible;\n text-align: left;\n font: 400 12px/18px var(--dsw-font-family, system-ui, sans-serif);\n}\n.dsh-office-annotation-reference .dsh-office-annotation-popover[data-open=\"true\"] { display: block; }\n.dsh-office-annotation-reference .dsh-office-annotation-popover::backdrop { pointer-events: none; }\n.dsh-office-annotate .dsh-office-annotate-popover > ul,\n.dsh-office-annotation-reference .dsh-office-annotation-list {\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n max-height: min(340px, 45vh);\n margin: 0;\n padding: 0 8px;\n font: 400 12px/18px var(--dsw-font-family, system-ui, sans-serif);\n text-align: left;\n overflow: auto;\n list-style: none;\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n box-shadow: var(--dsw-shadow-lv2);\n}\n.dsh-office-annotate .dsh-office-annotate-popover > ul { max-height: min(340px, 45vh, max(40px, calc(var(--dsh-office-annotation-height, 100vh) - 80px))); }\n.dsh-office-annotate .dsh-office-annotate-popover li,\n.dsh-office-annotation-reference .dsh-office-annotation-item { display: flex; flex: none; flex-direction: column; gap: 3px; min-width: 0; padding: 8px 0; }\n.dsh-office-annotate .dsh-office-annotate-popover li > div { display: flex; flex-direction: column; gap: 3px; min-width: 0; }\n.dsh-office-annotate .dsh-office-annotate-popover .dsh-office-annotation-requirement { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.dsh-office-annotate .dsh-office-annotate-popover li + li,\n.dsh-office-annotation-reference .dsh-office-annotation-item + .dsh-office-annotation-item { border-top: .5px solid var(--dsw-alias-border-l3); }\n.dsh-office-annotate .dsh-office-annotation-source,\n.dsh-office-annotation-reference .dsh-office-annotation-source { display: flex; align-items: baseline; gap: 8px; color: var(--dsw-alias-label-tertiary); font-size: 12px; }\n.dsh-office-annotation-reference .dsh-office-annotation-source button { padding: 0; border: 0; color: var(--dsw-alias-state-business-primary); text-align: left; }\n.dsh-office-annotate .dsh-office-annotation-source > :first-child,\n.dsh-office-annotation-reference .dsh-office-annotation-source > :first-child { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.dsh-office-annotate .dsh-office-annotation-source > :not(:first-child),\n.dsh-office-annotation-reference .dsh-office-annotation-source > :not(:first-child) { flex: none; }\n.dsh-office-annotate .dsh-office-annotation-original,\n.dsh-office-annotation-reference .dsh-office-annotation-original { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--dsw-alias-label-tertiary); font-size: 12px; }\n.dsh-office-annotate .dsh-office-annotation-requirement,\n.dsh-office-annotation-reference .dsh-office-annotation-requirement { display: block; white-space: pre-wrap; overflow-wrap: anywhere; }\n`\n document.head.appendChild(style)\n return () => style.remove()\n}\n","import type { Context as ClientContext } from '@deepseek-ai/cordis'\r\nimport type {} from '@deepseek-ai/dsh-api-remotes/client'\r\nimport type {} from '@deepseek-ai/dsh-api-session-controller/client'\r\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\r\nimport type { UserTextRule } from '@deepseek-ai/dsh-client-ui-conversation/client'\r\nimport type { InputTriggerSource } from '@deepseek-ai/dsh-client-ui-input-trigger/client'\r\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\r\nimport type {} from '@deepseek-ai/dsh-client-ui-sidebar-right/client'\r\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\r\nimport type { OfficeFeatureId } from '../features'\r\nimport type { AnnotationController, AnnotationInjected, PendingAnnotation } from './types'\r\nimport { rankByName } from '@deepseek-ai/dsh-client-ui-primitives'\r\nimport { featureByCommand, featureById, OFFICE_FEATURES } from '../features'\r\nimport { annotationRule } from './annotation'\r\nimport { AnnotationReference } from './annotation-reference'\r\nimport { ANNOTATION_ID, ANNOTATION_NODE, ANNOTATION_ORDER, ANNOTATION_PRIORITY, ANNOTATION_SLOT, FILE_ADDRESS_PREFIX, OFFICE_CHIP, OFFICE_CHIP_SLOT, OFFICE_NS, OFFICE_SOURCE } from './constants'\r\nimport { DocumentAnnotation } from './document-annotation'\r\nimport { OFFICE_ICONS } from './icons'\r\nimport { OfficeReference } from './office-reference'\r\nimport { mountOfficeStyles } from './styles'\r\n\r\n/** Client services used by this half. */\r\nexport const inject = [\r\n 'inputTriggers',\r\n 'sessions',\r\n 'slots',\r\n 'locale',\r\n 'remote',\r\n 'remote.skills',\r\n 'sidebarRight',\r\n 'uiConversation',\r\n 'conversation',\r\n]\r\n\r\nconst zh = {\r\n 'menu.group': '办公',\r\n 'menu.documents.label': '文档',\r\n 'menu.documents.description': '创建、读取、编辑和渲染 DOCX 文档',\r\n 'menu.pdf.label': 'PDF 文档',\r\n 'menu.pdf.description': '读取、创建、检查、渲染和验证 PDF',\r\n 'menu.presentations.label': '演示文稿',\r\n 'menu.presentations.description': '创建、编辑、渲染和导出 PPTX 演示文稿',\r\n 'menu.spreadsheets.label': '电子表格',\r\n 'menu.spreadsheets.description': '创建、编辑、计算和导出 XLSX 电子表格',\r\n 'annotation.ask': '请求修改',\r\n 'annotation.cancel': '取消',\r\n 'annotation.send': '发送',\r\n 'annotation.add': '添加标注',\r\n 'annotation.placeholder': '说明要怎么改…',\r\n 'annotation.page': '第 {page} 页',\r\n 'annotation.count': '{count} 条注释',\r\n 'annotation.remove': '删除第 {index} 条注释',\r\n 'annotation.image': '位置截图:{name}',\r\n 'annotation.help': '悬停吸附段落,点击输入要求;长按拖动框选区域,松开添加标注。方向键选择,Enter 确认,Esc 退出。',\r\n 'annotation.unavailable': '等待文档页面渲染;当前预览不支持标注',\r\n 'annotation.capturing': '正在截图…',\r\n 'annotation.captureFailed': '截图失败,请重新选择区域',\r\n 'annotation.intakeUnavailable': '当前 DSH 版本不支持从侧栏添加截图附件,PDF 标注已禁用',\r\n 'annotation.imageLimit': '截图超过当前模型的数量或大小限制,请减少标注后重试',\r\n 'annotation.sendFailed': '未能加入会话,请重试;标注仍保留',\r\n 'annotation.draftReady': '标注和截图已保留在会话输入框,请在那里确认发送',\r\n 'annotation.invalid': '标注内容无效,请重新添加',\r\n 'annotation.tooLarge': '标注内容过长,请减少后重试',\r\n 'annotation.emptyPage': '页面尚未渲染,请重试',\r\n 'annotation.emptyRegion': '请选择页面内的区域',\r\n} as const\r\n\r\nconst en: Record<keyof typeof zh, string> = {\r\n 'menu.group': 'Office',\r\n 'menu.documents.label': 'Documents',\r\n 'menu.documents.description': 'Create, read, edit, and render DOCX documents',\r\n 'menu.pdf.label': 'PDF documents',\r\n 'menu.pdf.description': 'Read, create, inspect, render, and verify PDFs',\r\n 'menu.presentations.label': 'Presentations',\r\n 'menu.presentations.description': 'Create, edit, render, and export PPTX decks',\r\n 'menu.spreadsheets.label': 'Spreadsheets',\r\n 'menu.spreadsheets.description': 'Create, edit, calculate, and export XLSX workbooks',\r\n 'annotation.ask': 'Request changes',\r\n 'annotation.cancel': 'Cancel',\r\n 'annotation.send': 'Send',\r\n 'annotation.add': 'Add annotation',\r\n 'annotation.placeholder': 'Describe the change…',\r\n 'annotation.page': 'page {page}',\r\n 'annotation.count': '{count} annotations',\r\n 'annotation.remove': 'Remove annotation {index}',\r\n 'annotation.image': 'Location screenshot: {name}',\r\n 'annotation.help': 'Hover to select a paragraph; click to comment. Hold and drag to select a region. Arrow keys select, Enter confirms, Esc exits.',\r\n 'annotation.unavailable': 'Waiting for rendered pages; this preview cannot be annotated yet',\r\n 'annotation.capturing': 'Capturing…',\r\n 'annotation.captureFailed': 'Screenshot failed; please select the region again',\r\n 'annotation.intakeUnavailable': 'This DSH version cannot add screenshots from the sidebar; PDF annotation is disabled',\r\n 'annotation.imageLimit': 'Screenshots exceed the current model’s count or size limits; remove some annotations and retry',\r\n 'annotation.sendFailed': 'Could not add annotations to the conversation; your annotations are retained',\r\n 'annotation.draftReady': 'Annotations and screenshots are kept in the conversation input; confirm sending there',\r\n 'annotation.invalid': 'Invalid annotation; please add it again',\r\n 'annotation.tooLarge': 'Annotations are too long; remove some and retry',\r\n 'annotation.emptyPage': 'The page has not rendered yet; please retry',\r\n 'annotation.emptyRegion': 'Select a region inside the page',\r\n}\r\n\r\ninterface OfficeSkillSummary {\r\n readonly name: string\r\n readonly path?: string\r\n}\r\n\r\ninterface CatalogEntry {\r\n readonly abort: AbortController\r\n readonly promise: Promise<readonly OfficeSkillSummary[]>\r\n settled?: readonly OfficeSkillSummary[]\r\n}\r\n\r\nfunction encodeSegment(segment: string): string {\r\n return encodeURIComponent(segment).replace(/%3A/gi, ':')\r\n}\r\n\r\nfunction encodePath(path: string): string {\r\n return path.split('/').map(encodeSegment).join('/')\r\n}\r\n\r\nfunction sessionFileAddress(sessionId: string, path: string): string {\r\n const normalized = path.replace(/\\\\/g, '/').replace(/^(?:\\.\\/)+/u, '')\r\n return `${FILE_ADDRESS_PREFIX}session/${encodeSegment(sessionId)}/${encodePath(normalized)}`\r\n}\r\n\r\nfunction fileAddressFor(sessionId: string, cwd: string | undefined, path: string): string {\r\n const normalized = path.replace(/\\\\/g, '/')\r\n const root = cwd?.replace(/\\\\/g, '/').replace(/\\/+$/u, '') ?? ''\r\n if (!/^(?:\\/|[A-Za-z]:\\/|\\\\\\\\)/u.test(normalized))\r\n return sessionFileAddress(sessionId, normalized)\r\n if (root !== '' && normalized.startsWith(`${root}/`))\r\n return sessionFileAddress(sessionId, normalized.slice(root.length + 1))\r\n return sessionFileAddress(sessionId, normalized)\r\n}\r\n\r\ninterface OfficeSkillCatalog {\r\n list: (input: { sessionId: string }, signal?: AbortSignal) => Promise<\r\n | { ok: true, value: { skills: readonly OfficeSkillSummary[] } }\r\n | { ok: false, error: { code: string, message: string } }\r\n >\r\n}\r\n\r\ninterface OfficeSessionReference {\r\n readonly binding: {\r\n readonly session: {\r\n getSnapshot: () => { openState: string, openError?: Error }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * The small public Session face this client needs. The installed DSH assembly\r\n * also ships a host `dsh-session` augmentation that widens `ctx.sessions` with\r\n * an incompatible `SessionStore`, so narrow through the documented client face.\r\n */\r\ninterface OfficeSessions {\r\n binding: (sessionId: string) => unknown\r\n using: <T>(\r\n sessionId: string,\r\n options: { source: string, signal: AbortSignal },\r\n fn: (reference: OfficeSessionReference) => Promise<T>,\r\n ) => Promise<T>\r\n list: {\r\n getSnapshot: () => { byId: Record<string, { cwd?: string } | undefined> }\r\n }\r\n}\r\n\r\n/** Register the `/` source, transcript chip, and right-sidebar preview. */\r\nexport function apply(ctx: ClientContext): void {\r\n const sessions = ctx.sessions as unknown as OfficeSessions\r\n const remoteSkills = (ctx.remote as unknown as { skills: OfficeSkillCatalog }).skills\r\n const t = ctx.locale.bind(OFFICE_NS)\r\n const entries = new Map<string, CatalogEntry>()\r\n const pendingAnnotations = new Map<string, Map<string, readonly PendingAnnotation[]>>()\r\n\r\n ctx.effect(() => mountOfficeStyles(), 'office-suite: styles')\r\n ctx.effect(() => ctx.locale.register(OFFICE_NS, { zh, en }), 'office-suite: dictionaries')\r\n\r\n function catalogFor(sessionId: string): CatalogEntry {\r\n const existing = entries.get(sessionId)\r\n if (existing !== undefined)\r\n return existing\r\n\r\n const abort = new AbortController()\r\n const promise = (async () => {\r\n if (sessions.binding(sessionId) === undefined)\r\n throw new Error(`office catalog requires a retained session \"${sessionId}\"`)\r\n return sessions.using(sessionId, { source: 'officeCatalog', signal: abort.signal }, async (reference) => {\r\n abort.signal.throwIfAborted()\r\n const state = reference.binding.session.getSnapshot()\r\n if (state.openState !== 'open')\r\n throw state.openError ?? new Error(`session \"${sessionId}\" is not open`)\r\n const result = await remoteSkills.list({ sessionId }, abort.signal)\r\n abort.signal.throwIfAborted()\r\n if (!result.ok)\r\n throw new Error(`skills/list failed: ${result.error.code}: ${result.error.message}`)\r\n return result.value.skills\r\n })\r\n })()\r\n\r\n const entry: CatalogEntry = { abort, promise }\r\n entries.set(sessionId, entry)\r\n promise.then((skills) => {\r\n entry.settled = skills\r\n }, () => {\r\n if (entries.get(sessionId) === entry)\r\n entries.delete(sessionId)\r\n })\r\n return entry\r\n }\r\n\r\n function openSkill(sessionId: string, feature: OfficeFeatureId, catalog: readonly OfficeSkillSummary[]): boolean {\r\n const definition = featureById(feature)\r\n if (definition === undefined)\r\n return false\r\n const skill = catalog.find(item => item.name === definition.skill)\r\n if (skill?.path === undefined)\r\n return false\r\n const cwd = sessions.list.getSnapshot().byId[sessionId]?.cwd\r\n try {\r\n ctx.sidebarRight.openResource(fileAddressFor(sessionId, cwd, skill.path))\r\n return true\r\n }\r\n catch (error) {\r\n console.error('[dsh-office-kit] reference preview failed:', error)\r\n return false\r\n }\r\n }\r\n\r\n const source: InputTriggerSource = {\r\n trigger: '/',\r\n name: OFFICE_SOURCE,\r\n order: 1,\r\n async candidates(_session, { query, signal }) {\r\n if (signal.aborted)\r\n return []\r\n const items = OFFICE_FEATURES.map((feature) => {\r\n const Icon = OFFICE_ICONS[feature.id]\r\n return {\r\n name: feature.command,\r\n label: t(`menu.${feature.id}.label`),\r\n description: t(`menu.${feature.id}.description`),\r\n section: t('menu.group'),\r\n icon: Icon,\r\n }\r\n })\r\n return query.length === 0 ? items : rankByName(items, query)\r\n },\r\n lexicon() {\r\n return OFFICE_FEATURES.map(feature => feature.command)\r\n },\r\n openReference(session, { ref }) {\r\n const feature = featureById(ref)\r\n if (feature === undefined)\r\n return false\r\n\r\n const settled = entries.get(session.sessionId)?.settled\r\n if (settled !== undefined)\r\n return openSkill(session.sessionId, feature.id, settled)\r\n\r\n const entry = catalogFor(session.sessionId)\r\n entry.promise.then((catalog) => {\r\n if (!entry.abort.signal.aborted)\r\n openSkill(session.sessionId, feature.id, catalog)\r\n }).catch((error) => {\r\n if (!entry.abort.signal.aborted)\r\n console.error('[dsh-office-kit] reference preview failed:', error)\r\n })\r\n return true\r\n },\r\n onPick({ candidate }) {\r\n const feature = featureByCommand(candidate.name)\r\n if (feature === undefined)\r\n return undefined\r\n return {\r\n insert: {\r\n source: OFFICE_SOURCE,\r\n ref: feature.id,\r\n label: t(`menu.${feature.id}.label`),\r\n appearance: 'file',\r\n clipboardText: `/${feature.command}`,\r\n },\r\n }\r\n },\r\n codec: {\r\n clipboardText(ref) {\r\n const feature = featureById(ref)\r\n return feature === undefined ? `/${ref}` : `/${feature.command}`\r\n },\r\n async serialize(ref) {\r\n const feature = featureById(ref)\r\n if (feature === undefined)\r\n return '/documents'\r\n return `/${feature.command}\\n\\nUse the \"${feature.skill}\" skill for this request and follow its instructions before creating, editing, or rendering files.`\r\n },\r\n },\r\n }\r\n\r\n const rule: UserTextRule<'office'> = {\r\n id: OFFICE_CHIP,\r\n order: 20,\r\n match(text, from) {\r\n const tokens = /(?<!\\S)\\/([\\w-]+)(?!\\S)/gu\r\n tokens.lastIndex = from\r\n for (let token = tokens.exec(text); token !== null; token = tokens.exec(text)) {\r\n const feature = featureByCommand(token[1] ?? '')\r\n if (feature === undefined)\r\n continue\r\n return {\r\n id: OFFICE_CHIP,\r\n start: token.index,\r\n end: token.index + token[0].length,\r\n data: { feature: feature.id },\r\n }\r\n }\r\n return undefined\r\n },\r\n }\r\n\r\n ctx.effect(() => ctx.uiConversation.userText.register(rule), 'office-suite: transcript chip')\r\n\r\n ctx.effect(() => ctx.slots.inject(OFFICE_CHIP_SLOT, () => ctx.slots.register({\r\n name: OFFICE_CHIP_SLOT,\r\n key: OFFICE_CHIP,\r\n priority: 100,\r\n inject: (sessionId: string) => ({\r\n openOffice: (feature: OfficeFeatureId) => {\r\n source.openReference?.({ sessionId: sessionId as never }, { ref: feature, appearance: 'file' })\r\n },\r\n officeLabel: (feature: OfficeFeatureId) => t(`menu.${feature}.label`),\r\n }),\r\n }, OfficeReference)), 'office-suite: transcript chip slot')\r\n\r\n function annotationDependencies(sessionId: string): AnnotationInjected {\r\n const controller = ctx.conversation as unknown as Partial<AnnotationController>\r\n const compatible = typeof controller.createDrafts === 'function'\r\n && typeof controller.releaseDraftAttachments === 'function'\r\n && typeof controller.resolveDraftAttachments === 'function'\r\n let pending = pendingAnnotations.get(sessionId)\r\n if (!pending) {\r\n pending = new Map()\r\n pendingAnnotations.set(sessionId, pending)\r\n }\r\n return {\r\n pendingAnnotations: pending,\r\n // ponytail: current DSH concrete File intake only, replace with outward intake API when exported.\r\n intake: compatible\r\n ? {\r\n create: files => controller.createDrafts!(sessionId as never, files),\r\n release: drafts => controller.releaseDraftAttachments!(drafts),\r\n images: ids => controller.resolveDraftAttachments!(ids).filter(item => item.kind === 'image').map(item => item.file),\r\n }\r\n : undefined,\r\n openAnnotation: (target) => {\r\n try {\r\n const cwd = sessions.list.getSnapshot().byId[sessionId]?.cwd\r\n ctx.sidebarRight.openResource(fileAddressFor(sessionId, cwd, target))\r\n }\r\n catch (error) {\r\n console.error('[dsh-office-kit] annotation preview failed:', error)\r\n }\r\n },\r\n }\r\n }\r\n\r\n ctx.effect(() => ctx.uiConversation.userText.register(annotationRule), 'office-suite: annotations')\r\n ctx.effect(() => ctx.slots.inject(OFFICE_CHIP_SLOT, () => ctx.slots.register({\r\n name: OFFICE_CHIP_SLOT,\r\n key: ANNOTATION_NODE,\r\n priority: ANNOTATION_PRIORITY,\r\n locale: OFFICE_NS,\r\n inject: annotationDependencies,\r\n }, AnnotationReference)), 'office-suite: annotation references')\r\n ctx.effect(() => ctx.slots.inject(ANNOTATION_SLOT, () => ctx.slots.register({\r\n name: ANNOTATION_SLOT,\r\n id: ANNOTATION_ID,\r\n order: ANNOTATION_ORDER,\r\n locale: OFFICE_NS,\r\n inject: annotationDependencies,\r\n }, DocumentAnnotation)), 'office-suite: annotation tool')\r\n\r\n const inputTriggers = ctx.inputTriggers\r\n ctx.effect(() => {\r\n const unregister = inputTriggers.registerSource(source)\r\n return () => {\r\n unregister()\r\n for (const entry of entries.values())\r\n entry.abort.abort()\r\n entries.clear()\r\n pendingAnnotations.clear()\r\n }\r\n }, 'office-suite: slash source')\r\n}\r\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":[],"sources":["../src/features.ts","../src/client/constants.ts","../src/client/quote.ts","../src/client/annotation.ts","../src/client/annotation-reference.tsx","../src/client/document-annotation.tsx","../src/client/icons.tsx","../src/client/office-reference.tsx","../src/client/styles.ts","../src/client/index.ts"],"sourcesContent":["/** Stable identifiers for the four Office entry points. */\nexport type OfficeFeatureId = 'documents' | 'pdf' | 'presentations' | 'spreadsheets'\n\n/** One user-facing Office entry, its skill, and the file types it owns. */\nexport interface OfficeFeature {\n readonly id: OfficeFeatureId\n /** Friendly name used by the '/' menu, chip, and preview. */\n readonly label: string\n /** One-line menu description. */\n readonly description: string\n /** Detail shown after a chip is inserted. */\n readonly hint: string\n /** Skill registered with the DSH skill registry. */\n readonly skill: string\n /** Slash token without the leading '/'. */\n readonly command: string\n /** File extensions shown in menus and documentation. */\n readonly extensions: readonly string[]\n}\n\n/** The four entries, in menu order. */\nexport const OFFICE_FEATURES: readonly OfficeFeature[] = [\n {\n id: 'documents',\n label: 'Documents',\n description: 'Create, edit, render, and verify Word documents (.docx).',\n hint: 'DOCX',\n skill: 'office-documents',\n command: 'documents',\n extensions: ['.docx'],\n },\n {\n id: 'pdf',\n label: 'PDF',\n description: 'Create, read, edit, render, and verify PDF files.',\n hint: 'PDF',\n skill: 'office-pdf',\n command: 'pdf',\n extensions: ['.pdf'],\n },\n {\n id: 'presentations',\n label: 'Presentations',\n description: 'Create, edit, render, and verify slide decks (.pptx).',\n hint: 'PPTX',\n skill: 'office-presentations',\n command: 'presentations',\n extensions: ['.pptx'],\n },\n {\n id: 'spreadsheets',\n label: 'Spreadsheets',\n description: 'Create, edit, recalculate, render, and verify workbooks (.xlsx).',\n hint: 'XLSX',\n skill: 'office-spreadsheets',\n command: 'spreadsheets',\n extensions: ['.xlsx'],\n },\n]\n\n/** Resolve a feature by its stable id; unknown ids are not Office entries. */\nexport function featureById(id: string): OfficeFeature | undefined {\n return OFFICE_FEATURES.find(feature => feature.id === id)\n}\n\n/** Resolve a feature by its slash token (without '/'). */\nexport function featureByCommand(command: string): OfficeFeature | undefined {\n return OFFICE_FEATURES.find(feature => feature.command === command)\n}\n","/** Locale namespace and slash source owned by this plugin. */\nexport const OFFICE_NS = 'dsh-office-kit'\nexport const OFFICE_SOURCE = 'office'\nexport const OFFICE_CHIP = 'office'\nexport const OFFICE_CHIP_SLOT = 'conversation.user.text.node'\n\n/** Additive, session-scoped toolbar contribution inside the official file preview. */\nexport const ANNOTATION_SLOT = 'sidebar.right.tab.document.actions'\nexport const ANNOTATION_ID = 'office-annotations'\nexport const ANNOTATION_ORDER = 20\nexport const ANNOTATION_PRIORITY = 100\nexport const ANNOTATION_NODE = 'officeAnnotation'\nexport const ANNOTATION_OPEN = '<office-annotations>'\nexport const ANNOTATION_CLOSE = '</office-annotations>'\nexport const OFFICE_STYLE_ID = 'dsh-office-kit/reference.css'\nexport const FILE_ADDRESS_PREFIX = 'dsh-resource://file/'\nexport const SESSION_FILE_PREFIX = `${FILE_ADDRESS_PREFIX}session/`\n\n/** Only semantic selectors: no dependency on another plugin's CSS/data attributes. */\nexport const ANNOTATION_CANVAS_SELECTOR = 'canvas[role=\"img\"][aria-label]'\n/** Gravity UI Icons 2.21.0 CommentFill (MIT); original retained in assets/icons/comment-fill.svg. */\nexport const ANNOTATION_CURSOR = `url(\"data:image/svg+xml,${encodeURIComponent('<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" fill=\"none\" viewBox=\"0 0 16 16\"><path fill=\"#466eff\" fill-rule=\"evenodd\" d=\"M8 13c3.866 0 7-2 7-6s-3.134-6-7-6-7 2-7 6c0 2.16.914 3.737 2.364 4.73l.09 2.161a1.157 1.157 0 0 0 1.857.872l2.322-1.77Q7.816 13 8 13\" clip-rule=\"evenodd\"/></svg>')}\") 4 18, crosshair`\nexport const ANNOTATION_HOLD_MS = 350\nexport const ANNOTATION_MIN_REGION = 6\nexport const ANNOTATION_PADDING = 3\nexport const ANNOTATION_HIT_X = 8\nexport const ANNOTATION_HIT_Y = 4\nexport const ANNOTATION_MAX_ITEMS = 50\nexport const ANNOTATION_MAX_TEXT = 20000\nexport const ANNOTATION_MAX_PAYLOAD = 1200000\nexport const ANNOTATION_MAX_PIXELS = 4000000\n","import type { QuotePrompt } from './types'\nimport { SESSION_FILE_PREFIX } from './constants'\n\nfunction decodeSegment(segment: string): string {\n try {\n return decodeURIComponent(segment)\n }\n catch {\n return segment\n }\n}\n\n/** Replace every `{name}` placeholder with its value. */\nexport function fillTemplate(template: string, values: Record<string, string>): string {\n return template.replace(/\\{(\\w+)\\}/gu, (match, name: string) => values[name] ?? match)\n}\n\n/**\n * Collapse what a PDF text layer emits: one line per visual line, padded with\n * spaces and interleaved empty lines.\n */\nexport function normalizeSelection(raw: string): string {\n const lines: string[] = []\n for (const line of raw.replace(/\\r\\n?/gu, '\\n').split('\\n')) {\n const collapsed = line.replace(/\\s+/gu, ' ').trim()\n if (collapsed.length > 0)\n lines.push(collapsed)\n }\n return lines.join('\\n')\n}\n\n/** Quote each line so the agent reads the selection as the document's own words. */\nexport function quoteLines(text: string): string {\n return text.split('\\n').map(line => `> ${line}`).join('\\n')\n}\n\n/** Path part of a `scheme://authority/path` address, apart from its origin. */\nconst PATH_AFTER_ORIGIN = /^(?:[^:/?#]+:)?\\/\\/[^/]+\\/(.*)$/u\n\nfunction pathOf(address: string): string | undefined {\n return PATH_AFTER_ORIGIN.exec(address)?.[1]\n}\n\n/** Last path segment of a preview address: the file's display name. */\nexport function fileNameOf(address: string | undefined): string | undefined {\n if (address === undefined)\n return undefined\n const segment = pathOf(address)?.split('/').pop()\n if (segment === undefined || segment.length === 0)\n return undefined\n const name = decodeSegment(segment)\n return name.length === 0 ? undefined : name\n}\n\n/** Workspace-relative path of a session file address; undefined for other resources. */\nexport function sessionRelativePath(address: string | undefined): string | undefined {\n if (address === undefined || !address.startsWith(SESSION_FILE_PREFIX))\n return undefined\n const rest = address.slice(SESSION_FILE_PREFIX.length)\n const slash = rest.indexOf('/')\n if (slash < 0)\n return undefined\n const path = rest.slice(slash + 1)\n if (path.length === 0)\n return undefined\n return path.split('/').map(decodeSegment).join('/')\n}\n\n/** The message inserted into the composer: target, quoted source, and requirement. */\nexport function composeQuote(prompt: QuotePrompt): string {\n const title = prompt.pageLabel === undefined ? prompt.target : `${prompt.target} · ${prompt.pageLabel}`\n return [\n `${prompt.heading}${title}`,\n '',\n prompt.originalLabel,\n quoteLines(prompt.text),\n '',\n `${prompt.requirementLabel}${prompt.requirement}`,\n ].join('\\n')\n}\n","import type { UserTextRule } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type { AnnotationParagraph, AnnotationRect, AnnotationSelection, AnnotationSendInput, AnnotationTextRun, OfficeAnnotation } from './types'\nimport { ANNOTATION_CANVAS_SELECTOR, ANNOTATION_CLOSE, ANNOTATION_HIT_X, ANNOTATION_HIT_Y, ANNOTATION_MAX_ITEMS, ANNOTATION_MAX_PAYLOAD, ANNOTATION_MAX_PIXELS, ANNOTATION_MAX_TEXT, ANNOTATION_NODE, ANNOTATION_OPEN, ANNOTATION_PADDING } from './constants'\nimport { normalizeSelection } from './quote'\n\nexport function unionRect(a: AnnotationRect, b: AnnotationRect): AnnotationRect {\n const left = Math.min(a.left, b.left)\n const top = Math.min(a.top, b.top)\n return { left, top, width: Math.max(a.left + a.width, b.left + b.width) - left, height: Math.max(a.top + a.height, b.top + b.height) - top }\n}\n\nexport function intersectRect(a: AnnotationRect, b: AnnotationRect): AnnotationRect | undefined {\n const left = Math.max(a.left, b.left)\n const top = Math.max(a.top, b.top)\n const width = Math.min(a.left + a.width, b.left + b.width) - left\n const height = Math.min(a.top + a.height, b.top + b.height) - top\n return width > 0 && height > 0 ? { left, top, width, height } : undefined\n}\n\n/** Leave breathing room around text/regions without extending outside the painted page. */\nexport function paddedRect(box: AnnotationRect, page: AnnotationRect): AnnotationRect | undefined {\n return intersectRect({ left: box.left - ANNOTATION_PADDING, top: box.top - ANNOTATION_PADDING, width: box.width + ANNOTATION_PADDING * 2, height: box.height + ANNOTATION_PADDING * 2 }, page)\n}\n\nexport function containsPoint(box: AnnotationRect, x: number, y: number): boolean {\n return x >= box.left && x <= box.left + box.width && y >= box.top && y <= box.top + box.height\n}\n\n/** Viewport coordinates for a native top-layer popover, independent of chat clipping ancestors. */\nexport function annotationPopoverPosition(anchor: AnnotationRect, popup: Pick<AnnotationRect, 'width' | 'height'>, viewport: Pick<AnnotationRect, 'width' | 'height'>): Pick<AnnotationRect, 'left' | 'top'> {\n return {\n left: Math.max(8, Math.min(anchor.left, viewport.width - popup.width - 8)),\n top: Math.max(8, Math.min(anchor.top >= popup.height + 8 ? anchor.top - popup.height : anchor.top + anchor.height, viewport.height - popup.height - 8)),\n }\n}\n\n/** Small hit slop bridges text edges without expanding the displayed paragraph outline. */\nexport function paragraphAtPoint(paragraphs: readonly AnnotationParagraph[], x: number, y: number): AnnotationParagraph | undefined {\n let hit: AnnotationParagraph | undefined\n for (const paragraph of paragraphs) {\n const box = paragraph.box\n if ((paragraph.rects ?? [box]).some(rect => x >= rect.left - ANNOTATION_HIT_X && x <= rect.left + rect.width + ANNOTATION_HIT_X\n && y >= rect.top - ANNOTATION_HIT_Y && y <= rect.top + rect.height + ANNOTATION_HIT_Y)\n && (!hit || box.width * box.height < hit.box.width * hit.box.height)) {\n hit = paragraph\n }\n }\n return hit\n}\n\n/** PDF text is positioned, not semantic: recover lines, then separate columns and paragraph gaps. */\nexport function groupParagraphs(runs: readonly AnnotationTextRun[]): AnnotationParagraph[] {\n const lines: { text: string, box: AnnotationRect, rects: AnnotationRect[] }[] = []\n for (const run of [...runs].sort((a, b) => a.box.top - b.box.top || a.box.left - b.box.left)) {\n if (!run.text.trim() || run.box.width <= 0 || run.box.height <= 0)\n continue\n const line = lines.find(item => Math.abs(item.box.top - run.box.top) < Math.min(item.box.height, run.box.height) * 0.45\n && run.box.left >= item.box.left && run.box.left - (item.box.left + item.box.width) < run.box.height * 2)\n if (line) {\n line.text += ` ${run.text}`\n line.box = unionRect(line.box, run.box)\n line.rects.push(run.box)\n }\n else {\n lines.push({ text: run.text, box: run.box, rects: [run.box] })\n }\n }\n const paragraphs: { text: string, box: AnnotationRect, rects: AnnotationRect[], last: AnnotationRect }[] = []\n for (const line of lines) {\n const paragraph = paragraphs.findLast((item) => {\n const gap = line.box.top - (item.last.top + item.last.height)\n const overlap = Math.min(item.last.left + item.last.width, line.box.left + line.box.width) - Math.max(item.last.left, line.box.left)\n return gap >= -line.box.height * 0.2 && gap <= Math.min(item.last.height, line.box.height) * 0.7\n && overlap > 0 && Math.abs(item.last.left - line.box.left) < line.box.height * 2\n && Math.max(item.last.height, line.box.height) / Math.min(item.last.height, line.box.height) < 1.4\n })\n if (paragraph) {\n paragraph.text += `\\n${line.text}`\n paragraph.box = unionRect(paragraph.box, line.box)\n paragraph.rects.push(...line.rects)\n paragraph.last = line.box\n }\n else {\n paragraphs.push({ ...line, last: line.box })\n }\n }\n return paragraphs.map(({ text, box, rects }) => ({ text: normalizeSelection(text), box, rects }))\n}\n\n/** Read only the accessible page canvas's sibling text layer, without private PDF.js state. */\nexport function canvasParagraphs(canvas: HTMLCanvasElement): AnnotationParagraph[] {\n const surface = canvas.parentElement\n if (!surface)\n return []\n const walker = document.createTreeWalker(surface, NodeFilter.SHOW_TEXT)\n const runs: AnnotationTextRun[] = []\n for (let node = walker.nextNode(); node; node = walker.nextNode()) {\n if (!node.textContent?.trim())\n continue\n const range = document.createRange()\n range.selectNodeContents(node)\n const box = range.getBoundingClientRect()\n if (box.width > 0 && box.height > 0)\n runs.push({ text: node.textContent, box: { left: box.left, top: box.top, width: box.width, height: box.height } })\n }\n // ponytail: visual paragraphs in PDF/Office previews, replace with a public paragraph API when provided.\n return groupParagraphs(runs)\n}\n\n/** Slot outlets are display:contents wrappers, not the document header itself. */\nexport function annotationPreview(anchor: HTMLElement): { header: HTMLElement, root: HTMLElement } | undefined {\n let header = anchor.parentElement\n while (header && getComputedStyle(header).display === 'contents')\n header = header.parentElement\n return header?.parentElement ? { header, root: header.parentElement } : undefined\n}\n\nexport function canvasAt(preview: HTMLElement, x: number, y: number): { canvas: HTMLCanvasElement, page: number } | undefined {\n const canvases = [...preview.querySelectorAll<HTMLCanvasElement>(ANNOTATION_CANVAS_SELECTOR)]\n const index = canvases.findIndex(canvas => containsPoint(canvas.getBoundingClientRect(), x, y) && canvas.getBoundingClientRect().width > 0)\n return index < 0 ? undefined : { canvas: canvases[index]!, page: index + 1 }\n}\n\nexport function normalizedRegion(box: AnnotationRect, page: AnnotationRect): AnnotationRect {\n if (page.width <= 0 || page.height <= 0)\n throw new Error('annotation.emptyPage')\n const clipped = intersectRect(box, page)\n if (!clipped)\n throw new Error('annotation.emptyRegion')\n return { left: (clipped.left - page.left) / page.width, top: (clipped.top - page.top) / page.height, width: clipped.width / page.width, height: clipped.height / page.height }\n}\n\n/** Copy the selected pixels now, before a zoom, rerender, or tab switch can change the page. */\nexport async function captureAnnotation(selection: AnnotationSelection, name: string, pixelLimit = ANNOTATION_MAX_PIXELS, dimensionLimit = Infinity): Promise<File> {\n const canvas = selection.canvas\n if (!canvas || canvas.width <= 0 || canvas.height <= 0)\n throw new Error('annotation.captureFailed')\n const painted = canvas.getBoundingClientRect()\n const region = selection.region ?? normalizedRegion(selection.box, painted)\n const width = canvas.width * region.width\n const height = canvas.height * region.height\n const scale = Math.min(1, Math.sqrt(pixelLimit / (width * height)), dimensionLimit / width, dimensionLimit / height)\n if (!Number.isFinite(scale) || scale <= 0)\n throw new Error('annotation.captureFailed')\n const output = document.createElement('canvas')\n output.width = Math.max(1, Math.floor(width * scale))\n output.height = Math.max(1, Math.floor(height * scale))\n const context = output.getContext('2d')\n if (!context)\n throw new Error('annotation.captureFailed')\n context.drawImage(canvas, region.left * canvas.width, region.top * canvas.height, width, height, 0, 0, output.width, output.height)\n const blob = await new Promise<Blob>((resolve, reject) => output.toBlob(value => value ? resolve(value) : reject(new Error('annotation.captureFailed')), 'image/png'))\n return new File([blob], name, { type: 'image/png' })\n}\n\nfunction isAnnotation(value: unknown): value is OfficeAnnotation {\n if (typeof value !== 'object' || value === null)\n return false\n const item = value as Record<string, unknown>\n const string = (value: unknown, max: number): boolean => typeof value === 'string' && value.length <= max\n if (!string(item.target, ANNOTATION_MAX_TEXT) || !string(item.fileName, 1000) || !string(item.text, ANNOTATION_MAX_TEXT)\n || !string(item.requirement, ANNOTATION_MAX_TEXT) || !(item.requirement as string).trim()\n || (item.page !== undefined && (!Number.isSafeInteger(item.page) || (item.page as number) < 1))\n || (item.imageName !== undefined && !string(item.imageName, 1000))) {\n return false\n }\n if (item.region !== undefined) {\n const region = item.region as Record<string, unknown> | null\n if (!region || !['left', 'top', 'width', 'height'].every(key => typeof region[key] === 'number' && Number.isFinite(region[key]) && (region[key] as number) >= 0 && (region[key] as number) <= 1))\n return false\n if ((region.width as number) <= 0 || (region.height as number) <= 0\n || (region.left as number) + (region.width as number) > 1.000001 || (region.top as number) + (region.height as number) > 1.000001) {\n return false\n }\n }\n return true\n}\n\n/** Plain text in the normal user message is the durable source of truth; no new Session event. */\nexport function serializeAnnotations(items: readonly OfficeAnnotation[]): string {\n if (!items.length || items.length > ANNOTATION_MAX_ITEMS || !items.every(isAnnotation))\n throw new Error('annotation.invalid')\n const payload = JSON.stringify(items).replace(/</gu, '\\\\u003c')\n if (payload.length > ANNOTATION_MAX_PAYLOAD)\n throw new Error('annotation.tooLarge')\n return `${ANNOTATION_OPEN}\\n${payload}\\n${ANNOTATION_CLOSE}`\n}\n\nexport const annotationRule: UserTextRule<'officeAnnotation'> = {\n id: ANNOTATION_NODE,\n order: 10,\n match(text, from) {\n for (let start = text.indexOf(ANNOTATION_OPEN, from); start >= 0; start = text.indexOf(ANNOTATION_OPEN, start + ANNOTATION_OPEN.length)) {\n const end = text.indexOf(ANNOTATION_CLOSE, start + ANNOTATION_OPEN.length)\n if (end < 0)\n return undefined\n const payload = text.slice(start + ANNOTATION_OPEN.length, end).trim()\n if (payload.length > ANNOTATION_MAX_PAYLOAD)\n continue\n try {\n const items: unknown = JSON.parse(payload)\n if (Array.isArray(items) && items.length > 0 && items.length <= ANNOTATION_MAX_ITEMS && items.every(isAnnotation))\n return { id: ANNOTATION_NODE, start, end: end + ANNOTATION_CLOSE.length, data: { items } }\n }\n catch { /* Invalid/foreign markers remain visible as ordinary text. */ }\n }\n return undefined\n },\n}\n\n/** Prepare one synchronous input transaction; admitted or restored drafts belong to the composer. */\nexport function sendAnnotations({ items, inputActions, intake, limits, existingImages, deferSubmit }: AnnotationSendInput): 'sent' | 'draft' {\n const text = serializeAnnotations(items.map(item => item.annotation))\n const files = items.flatMap(item => item.file ? [item.file] : [])\n if (files.length && !intake)\n throw new Error('annotation.intakeUnavailable')\n if (files.length && limits) {\n if (files.some(file => !limits.mediaTypes.includes(file.type) || file.size > limits.maxImageBytes)\n || existingImages.length + files.length > limits.maxImagesPerMessage\n || [...existingImages, ...files].reduce((sum, file) => sum + file.size, 0) > limits.maxMessageImageBytes) {\n throw new Error('annotation.imageLimit')\n }\n }\n const span = inputActions.captureInsertion()\n const drafts = files.length ? intake!.create(files) : []\n if (drafts.length && !inputActions.addAttachments(drafts.map(item => item.id))) {\n intake!.release(drafts)\n throw new Error('annotation.sendFailed')\n }\n if (!inputActions.insertText(`\\n${text}\\n`, { ...span, start: span.end })) {\n for (const draft of drafts)\n inputActions.removeAttachment(draft.id)\n intake?.release(drafts)\n throw new Error('annotation.sendFailed')\n }\n try {\n inputActions.persistDraft()\n if (deferSubmit)\n return 'draft'\n inputActions.submit()\n return 'sent'\n }\n catch {\n // The text and files are already in the composer; never discard or duplicate them on retry.\n return 'draft'\n }\n}\n","import type { UserTextNodeProps } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { ReactElement } from 'react'\nimport type { OFFICE_NS } from './constants'\nimport type { AnnotationInjected } from './types'\nimport { useId, useLayoutEffect, useRef, useState } from 'react'\nimport { annotationPopoverPosition } from './annotation'\nimport { fillTemplate } from './quote'\n\ntype Props = UserTextNodeProps<'officeAnnotation'> & PropsLocale<typeof OFFICE_NS> & Pick<AnnotationInjected, 'openAnnotation'>\n\n/** The native top layer escapes chat clipping without moving UI outside its slot. */\nexport function AnnotationReference({ node, interactive, openAnnotation, t }: Props): ReactElement {\n const popupId = useId()\n const anchor = useRef<HTMLSpanElement>(null)\n const popup = useRef<HTMLSpanElement>(null)\n const [open, setOpen] = useState(false)\n const label = fillTemplate(t('annotation.count'), { count: String(node.data.items.length) })\n\n useLayoutEffect(() => {\n const element = popup.current\n const trigger = anchor.current\n if (!element || !trigger)\n return\n if (!open) {\n element.hidePopover?.()\n return\n }\n element.showPopover?.()\n const position = (): void => {\n const viewport = { width: document.documentElement.clientWidth, height: window.innerHeight }\n const { left, top } = annotationPopoverPosition(trigger.getBoundingClientRect(), element.getBoundingClientRect(), viewport)\n element.style.left = `${left}px`\n element.style.top = `${top}px`\n }\n const scroll = (event: Event): void => {\n if (event.target instanceof Node && element.contains(event.target))\n return\n setOpen(false)\n }\n const resize = new ResizeObserver(position)\n resize.observe(trigger)\n resize.observe(element)\n window.addEventListener('resize', position)\n document.addEventListener('scroll', scroll, true)\n position()\n return () => {\n element.hidePopover?.()\n resize.disconnect()\n window.removeEventListener('resize', position)\n document.removeEventListener('scroll', scroll, true)\n }\n }, [open])\n\n return (\n <span\n ref={anchor}\n className=\"dsh-office-annotation-reference\"\n onPointerEnter={() => setOpen(true)}\n onPointerLeave={(event) => {\n if (!(event.relatedTarget instanceof Node) || !event.currentTarget.contains(event.relatedTarget))\n setOpen(false)\n }}\n onFocus={() => setOpen(true)}\n onBlur={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget))\n setOpen(false)\n }}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.preventDefault()\n event.stopPropagation()\n if (popup.current?.contains(event.target as Node))\n anchor.current?.querySelector('button')?.focus()\n setOpen(false)\n }\n }}\n >\n <button type=\"button\" id={`${popupId}-trigger`} aria-haspopup=\"dialog\" aria-controls={popupId} aria-expanded={open}>{label}</button>\n <span ref={popup} {...{ popover: 'manual' }} className=\"dsh-office-annotation-popover\" data-open={open} id={popupId} role=\"dialog\" aria-labelledby={`${popupId}-trigger`}>\n <span className=\"dsh-office-annotation-list\">\n {node.data.items.map((item, index) => (\n <span className=\"dsh-office-annotation-item\" key={index}>\n <span className=\"dsh-office-annotation-source\">\n {interactive\n ? <button type=\"button\" onClick={() => openAnnotation(item.target)} title={item.target}>{item.fileName}</button>\n : <span>{item.fileName}</span>}\n </span>\n <span className=\"dsh-office-annotation-requirement\">{item.requirement}</span>\n </span>\n ))}\n </span>\n </span>\n </span>\n )\n}\n","import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { CSSProperties, PointerEvent, ReactElement } from 'react'\nimport type { OFFICE_NS } from './constants'\nimport type { AnnotationInjected, AnnotationRect, AnnotationSelection, PendingAnnotation } from './types'\nimport { useEffect, useId, useRef, useState } from 'react'\nimport { annotationPreview, canvasAt, canvasParagraphs, captureAnnotation, intersectRect, normalizedRegion, paddedRect, paragraphAtPoint, sendAnnotations } from './annotation'\nimport { ANNOTATION_CANVAS_SELECTOR, ANNOTATION_HOLD_MS, ANNOTATION_MAX_ITEMS, ANNOTATION_MAX_TEXT, ANNOTATION_MIN_REGION } from './constants'\nimport { fillTemplate } from './quote'\n\ntype Props = PropsRuntime<'sidebar.right.tab.document.actions'> & PropsLocale<typeof OFFICE_NS> & AnnotationInjected\n\n/** This slot is rendered by the document header; every overlay stays in this React subtree. */\nexport function DocumentAnnotation(props: Props): ReactElement | null {\n if (!/\\.(?:pdf|docx?)$/iu.test(props.absolutePath))\n return null\n return <AnnotationTool key={props.absolutePath} {...props} />\n}\n\nfunction AnnotationTool({ absolutePath, pendingAnnotations, intake, inputActions, useInput, useProjection, t }: Props): ReactElement {\n const anchor = useRef<HTMLSpanElement>(null)\n const form = useRef<HTMLFormElement>(null)\n const surface = useRef<HTMLDivElement>(null)\n const preview = useRef<HTMLElement>()\n const [bounds, setBounds] = useState<AnnotationRect>()\n const [active, setActive] = useState(false)\n const [hover, setHover] = useState<AnnotationSelection>()\n const [selection, setSelection] = useState<AnnotationSelection>()\n const [requirement, setRequirement] = useState('')\n const [image, setImage] = useState<File>()\n const [capturing, setCapturing] = useState(false)\n const [dragging, setDragging] = useState(false)\n const [items, setItems] = useState<readonly PendingAnnotation[]>(() => pendingAnnotations.get(absolutePath) ?? [])\n const [summaryDismissed, setSummaryDismissed] = useState(false)\n const summaryId = useId()\n const [error, setError] = useState('')\n const input = useInput(state => state)\n const limits = useProjection('imageLimits')\n const isPdf = /\\.pdf$/iu.test(absolutePath)\n const fileName = absolutePath.replace(/\\\\/gu, '/').split('/').pop() ?? absolutePath\n const revision = useRef(0)\n const hold = useRef<ReturnType<typeof setTimeout>>()\n const gesture = useRef<{ x: number, y: number, lastX: number, lastY: number, canvas: HTMLCanvasElement, page: number, region: boolean }>()\n const cache = useRef<{ canvas: HTMLCanvasElement, box: AnnotationRect, paragraphs: ReturnType<typeof canvasParagraphs> }>()\n const disabled = input.phase !== 'plain'\n\n useEffect(() => {\n if (items.length)\n pendingAnnotations.set(absolutePath, items)\n else\n pendingAnnotations.delete(absolutePath)\n }, [absolutePath, items, pendingAnnotations])\n\n function dismiss(): void {\n revision.current++\n setSelection(undefined)\n setImage(undefined)\n setCapturing(false)\n setRequirement('')\n }\n\n function cancelGesture(): void {\n clearTimeout(hold.current)\n gesture.current = undefined\n setDragging(false)\n setHover(undefined)\n }\n\n useEffect(() => {\n const node = anchor.current\n const container = node && annotationPreview(node)\n if (!container)\n return\n const { header, root } = container\n preview.current = root\n let frame = 0\n const measure = (): void => {\n cancelAnimationFrame(frame)\n frame = requestAnimationFrame(() => {\n cache.current = undefined\n const rect = root.getBoundingClientRect()\n const top = Math.max(rect.top, header.getBoundingClientRect().bottom, 0)\n const bottom = Math.min(rect.bottom, window.innerHeight)\n const left = Math.max(0, rect.left)\n const right = Math.min(rect.right, window.innerWidth)\n const canvas = [...root.querySelectorAll<HTMLCanvasElement>(ANNOTATION_CANVAS_SELECTOR)].find(canvas => canvas.getBoundingClientRect().width > 0)\n const visible = root.isConnected && !root.closest('[hidden], [aria-hidden=\"true\"]') && getComputedStyle(root).visibility === 'visible'\n setBounds(visible && rect.height > 40 && canvas && right > left && bottom > top\n ? { left, top, width: right - left, height: bottom - top }\n : undefined)\n // Keep the saved page-relative region and comment when viewport geometry changes.\n setSelection((previous) => {\n if (!previous?.canvas || !previous.region)\n return previous\n const page = previous.canvas.getBoundingClientRect()\n const region = previous.region\n const box = { left: page.left + region.left * page.width, top: page.top + region.top * page.height, width: region.width * page.width, height: region.height * page.height }\n return Object.keys(box).every(key => box[key as keyof AnnotationRect] === previous.box[key as keyof AnnotationRect]) ? previous : { ...previous, box }\n })\n })\n }\n const resize = new ResizeObserver(measure)\n resize.observe(root)\n const mutation = new MutationObserver((records) => {\n if (records.some(record => !node.contains(record.target)))\n measure()\n })\n mutation.observe(root, { childList: true, subtree: true, attributes: true, attributeFilter: ['hidden', 'aria-hidden', 'class', 'style'] })\n for (let parent = root.parentElement; parent; parent = parent.parentElement)\n mutation.observe(parent, { attributes: true })\n window.addEventListener('resize', measure)\n root.addEventListener('transitionend', measure)\n root.addEventListener('scroll', measure, true)\n measure()\n return () => {\n revision.current++\n clearTimeout(hold.current)\n cancelAnimationFrame(frame)\n resize.disconnect()\n mutation.disconnect()\n window.removeEventListener('resize', measure)\n root.removeEventListener('transitionend', measure)\n root.removeEventListener('scroll', measure, true)\n preview.current = undefined\n }\n }, [])\n\n useEffect(() => {\n if (!selection)\n return\n const dismissOutside = (event: globalThis.PointerEvent): void => {\n if (event.target instanceof Node && !form.current?.contains(event.target))\n dismiss()\n }\n document.addEventListener('pointerdown', dismissOutside, true)\n form.current?.querySelector('input')?.focus()\n return () => {\n document.removeEventListener('pointerdown', dismissOutside, true)\n }\n }, [selection])\n\n useEffect(() => {\n if (active)\n surface.current?.focus()\n }, [active])\n\n function scrollPreview(x: number, y: number): void {\n const root = preview.current\n if (!root)\n return\n let scroll = root.querySelector(ANNOTATION_CANVAS_SELECTOR)?.parentElement\n while (scroll && scroll !== root && !/auto|scroll/u.test(getComputedStyle(scroll).overflowY))\n scroll = scroll.parentElement\n scroll?.scrollBy({ left: x, top: y })\n setHover(undefined)\n }\n\n useEffect(() => {\n const node = surface.current\n if (!active || !node || !bounds)\n return\n const wheel = (event: WheelEvent): void => {\n event.preventDefault()\n const unit = event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? bounds.height : 1\n scrollPreview(event.deltaX * unit, event.deltaY * unit)\n }\n node.addEventListener('wheel', wheel, { passive: false })\n return () => node.removeEventListener('wheel', wheel)\n }, [active, bounds])\n\n function paragraphAt(x: number, y: number): AnnotationSelection | undefined {\n if (!preview.current)\n return undefined\n const page = canvasAt(preview.current, x, y)\n if (!page)\n return undefined\n const box = page.canvas.getBoundingClientRect()\n if (cache.current?.canvas !== page.canvas || cache.current.box.left !== box.left || cache.current.box.top !== box.top\n || cache.current.box.width !== box.width || cache.current.box.height !== box.height) {\n cache.current = { canvas: page.canvas, box, paragraphs: canvasParagraphs(page.canvas) }\n }\n const paragraph = paragraphAtPoint(cache.current.paragraphs, x, y)\n return paragraph ? { ...paragraph, ...page } : undefined\n }\n\n function regionSelection(x: number, y: number): AnnotationSelection | undefined {\n const start = gesture.current\n if (!start)\n return undefined\n const box = intersectRect({ left: Math.min(start.x, x), top: Math.min(start.y, y), width: Math.abs(x - start.x), height: Math.abs(y - start.y) }, start.canvas.getBoundingClientRect())\n if (!box)\n return undefined\n const paragraphs = cache.current?.canvas === start.canvas ? cache.current.paragraphs : canvasParagraphs(start.canvas)\n return { canvas: start.canvas, page: start.page, box, region: normalizedRegion(box, start.canvas.getBoundingClientRect()), text: paragraphs.filter(item => (item.rects ?? [item.box]).some(rect => intersectRect(rect, box))).map(item => item.text).join('\\n').slice(0, ANNOTATION_MAX_TEXT) }\n }\n\n function pointerDown(event: PointerEvent<HTMLDivElement>): void {\n if (event.button !== 0 || !preview.current || (isPdf && !intake))\n return\n const page = canvasAt(preview.current, event.clientX, event.clientY)\n if (!page)\n return\n event.preventDefault()\n dismiss()\n const start = { ...page, x: event.clientX, y: event.clientY, lastX: event.clientX, lastY: event.clientY, region: false }\n gesture.current = start\n event.currentTarget.setPointerCapture(event.pointerId)\n hold.current = setTimeout(() => {\n if (gesture.current !== start)\n return\n start.region = true\n setDragging(true)\n setHover(regionSelection(start.lastX, start.lastY))\n }, ANNOTATION_HOLD_MS)\n }\n\n function pointerMove(event: PointerEvent<HTMLDivElement>): void {\n const start = gesture.current\n if (start) {\n start.lastX = event.clientX\n start.lastY = event.clientY\n if (!start.region && Math.hypot(event.clientX - start.x, event.clientY - start.y) >= ANNOTATION_MIN_REGION) {\n clearTimeout(hold.current)\n start.region = true\n setDragging(true)\n }\n }\n setHover(start?.region ? regionSelection(event.clientX, event.clientY) : paragraphAt(event.clientX, event.clientY))\n }\n\n async function openSelection(value: AnnotationSelection): Promise<void> {\n dismiss()\n const current = revision.current\n setError('')\n const page = value.canvas?.getBoundingClientRect()\n const box = page ? paddedRect(value.box, page) : value.box\n if (!box)\n return\n const region = page ? normalizedRegion(box, page) : value.region\n const frozen = { ...value, box, region }\n setSelection(frozen)\n if (!isPdf)\n return\n setCapturing(true)\n try {\n const file = await captureAnnotation(frozen, `${fileName}-p${value.page}-${Date.now()}.png`, limits?.maxImagePixels, limits?.maxImageDimension)\n if (revision.current === current)\n setImage(file)\n }\n catch {\n if (revision.current === current)\n setError(t('annotation.captureFailed'))\n }\n finally {\n if (revision.current === current)\n setCapturing(false)\n }\n }\n\n function pointerUp(event: PointerEvent<HTMLDivElement>): void {\n const start = gesture.current\n clearTimeout(hold.current)\n if (!start)\n return\n const value = start.region ? regionSelection(event.clientX, event.clientY) : paragraphAt(event.clientX, event.clientY)\n const moved = Math.hypot(event.clientX - start.x, event.clientY - start.y)\n cancelGesture()\n if (value && (start.region ? value.box.width >= ANNOTATION_MIN_REGION && value.box.height >= ANNOTATION_MIN_REGION : moved < ANNOTATION_MIN_REGION))\n void openSelection(value)\n }\n\n function add(): void {\n if (!selection || !requirement.trim() || (isPdf && !image) || items.length >= ANNOTATION_MAX_ITEMS)\n return\n const annotation = {\n target: absolutePath,\n fileName,\n page: selection.page,\n text: selection.text.slice(0, ANNOTATION_MAX_TEXT),\n requirement: requirement.trim(),\n region: selection.region,\n imageName: image?.name,\n }\n setItems(previous => [...previous, { annotation, file: image }])\n dismiss()\n }\n\n function send(): void {\n if (disabled)\n return\n try {\n const result = sendAnnotations({\n items,\n inputActions,\n intake,\n limits,\n existingImages: intake?.images(input.attachmentIds) ?? [],\n deferSubmit: !!input.draft.trim() || input.attachmentIds.length > 0,\n })\n setItems([])\n setSummaryDismissed(false)\n setActive(false)\n dismiss()\n setError(result === 'draft' ? t('annotation.draftReady') : '')\n }\n catch (error) {\n const key = error instanceof Error ? error.message : 'annotation.sendFailed'\n setError(t(key.startsWith('annotation.') ? key : 'annotation.sendFailed'))\n }\n }\n\n const highlight = selection ?? hover\n const highlightBox = highlight && !selection && !dragging && highlight.canvas\n ? paddedRect(highlight.box, highlight.canvas.getBoundingClientRect())\n : highlight?.box\n const clippedHighlight = highlightBox && bounds ? intersectRect(highlightBox, bounds) : undefined\n const formWidth = bounds ? Math.min(360, bounds.width - 16) : 0\n const formLeft = bounds && selection ? Math.max(bounds.left + 8, Math.min(selection.box.left, bounds.left + bounds.width - formWidth - 8)) : 0\n const formTop = bounds && selection ? Math.max(bounds.top + 4, Math.min(selection.box.top + selection.box.height + 6, bounds.top + bounds.height - 56)) : 0\n\n return (\n <span\n ref={anchor}\n className=\"dsh-office-annotate\"\n onKeyDown={(event) => {\n if (!active || event.key !== 'Escape')\n return\n event.preventDefault()\n event.stopPropagation()\n const hasSelection = !!selection || !!gesture.current\n dismiss()\n cancelGesture()\n if (hasSelection) {\n surface.current?.focus()\n }\n else {\n setActive(false)\n anchor.current?.querySelector('button')?.focus()\n }\n }}\n >\n <button\n type=\"button\"\n className=\"dsh-office-annotate-toggle\"\n aria-pressed={active}\n disabled={!bounds || (isPdf && !intake)}\n title={isPdf && !intake ? t('annotation.intakeUnavailable') : !bounds ? t('annotation.unavailable') : t('annotation.help')}\n onClick={() => {\n setActive(value => !value)\n dismiss()\n cancelGesture()\n }}\n >\n {t('annotation.ask')}\n </button>\n {isPdf && !intake && <span role=\"status\" className=\"dsh-office-annotate-unavailable\">{t('annotation.intakeUnavailable')}</span>}\n {active && bounds && (\n <div\n ref={surface}\n className=\"dsh-office-annotate-surface\"\n tabIndex={0}\n style={{ left: bounds.left, top: bounds.top, width: bounds.width, height: bounds.height }}\n role=\"region\"\n aria-label={t('annotation.help')}\n onPointerDown={pointerDown}\n onPointerMove={pointerMove}\n onPointerUp={pointerUp}\n onPointerCancel={cancelGesture}\n onLostPointerCapture={cancelGesture}\n onKeyDown={(event) => {\n if (event.key === 'PageDown' || event.key === 'PageUp') {\n event.preventDefault()\n scrollPreview(0, bounds.height * (event.key === 'PageDown' ? 0.8 : -0.8))\n }\n else if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault()\n const paragraphs = [...preview.current!.querySelectorAll<HTMLCanvasElement>(ANNOTATION_CANVAS_SELECTOR)].flatMap((canvas, index) => canvasParagraphs(canvas).filter(item => intersectRect(item.box, bounds)).map(item => ({ ...item, canvas, page: index + 1 })))\n const current = paragraphs.findIndex(item => item.canvas === hover?.canvas && item.text === hover.text && item.box.top === hover.box.top)\n const index = current < 0 ? (event.key === 'ArrowDown' ? 0 : paragraphs.length - 1) : Math.max(0, Math.min(paragraphs.length - 1, current + (event.key === 'ArrowDown' ? 1 : -1)))\n setHover(paragraphs[index])\n }\n else if ((event.key === 'Enter' || event.key === ' ') && hover) {\n event.preventDefault()\n void openSelection(hover)\n }\n }}\n onPointerLeave={() => {\n if (!gesture.current)\n setHover(undefined)\n }}\n />\n )}\n {active && clippedHighlight && (\n <span className=\"dsh-office-annotate-highlight\" data-selected={selection || dragging ? 'true' : undefined} style={{ left: clippedHighlight.left, top: clippedHighlight.top, width: clippedHighlight.width, height: clippedHighlight.height }} />\n )}\n {active && selection && bounds && (\n <form\n ref={form}\n className=\"dsh-office-annotate-composer\"\n style={{ left: formLeft, top: formTop, width: formWidth }}\n aria-label={t('annotation.ask')}\n aria-busy={capturing}\n onSubmit={(event) => {\n event.preventDefault()\n add()\n }}\n >\n <input\n type=\"text\"\n aria-label={t('annotation.placeholder')}\n placeholder={t('annotation.placeholder')}\n value={requirement}\n maxLength={ANNOTATION_MAX_TEXT}\n onChange={event => setRequirement(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' && event.nativeEvent.isComposing)\n event.preventDefault()\n }}\n />\n <button type=\"submit\" aria-label={t(capturing ? 'annotation.capturing' : 'annotation.add')} title={t(capturing ? 'annotation.capturing' : 'annotation.add')} disabled={!requirement.trim() || capturing || (isPdf && !image) || items.length >= ANNOTATION_MAX_ITEMS}>\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\"><path d=\"m5 12 4 4L19 6\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" /></svg>\n </button>\n </form>\n )}\n {(active || items.length > 0 || error) && bounds && (\n <div className=\"dsh-office-annotate-rail-position\" style={{ 'left': bounds.left, 'width': bounds.width, 'bottom': Math.max(0, window.innerHeight - bounds.top - bounds.height) + 12, '--dsh-office-annotation-width': `${bounds.width}px`, '--dsh-office-annotation-height': `${bounds.height}px` } as CSSProperties}>\n <div className=\"dsh-office-annotate-rail\">\n {error && <p role=\"alert\">{error}</p>}\n <div className=\"dsh-office-annotate-rail-actions\">\n <div\n className=\"dsh-office-annotate-summary\"\n data-dismissed={summaryDismissed ? 'true' : undefined}\n onPointerEnter={() => setSummaryDismissed(false)}\n onFocus={() => setSummaryDismissed(false)}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.stopPropagation()\n event.currentTarget.querySelector('button')?.focus()\n setSummaryDismissed(true)\n }\n }}\n >\n <button type=\"button\" aria-haspopup=\"dialog\" aria-controls={summaryId} disabled={!items.length}>{fillTemplate(t('annotation.count'), { count: String(items.length) })}</button>\n {items.length > 0 && (\n <div id={summaryId} role=\"dialog\" aria-label={fillTemplate(t('annotation.count'), { count: String(items.length) })} className=\"dsh-office-annotate-popover\">\n <ul>\n {items.map((item, index) => (\n <li key={item.annotation.imageName ?? index}>\n <div>\n <span className=\"dsh-office-annotation-source\">\n <span title={item.annotation.target}>{item.annotation.fileName}</span>\n {item.annotation.page && <span>{fillTemplate(t('annotation.page'), { page: String(item.annotation.page) })}</span>}\n </span>\n {item.annotation.text && <span className=\"dsh-office-annotation-original\">{item.annotation.text}</span>}\n <span className=\"dsh-office-annotation-requirement\" title={item.annotation.requirement}>{item.annotation.requirement}</span>\n </div>\n </li>\n ))}\n </ul>\n </div>\n )}\n </div>\n <button\n type=\"button\"\n onClick={() => {\n setItems([])\n setActive(false)\n setSummaryDismissed(false)\n setError('')\n dismiss()\n cancelGesture()\n }}\n >\n {t('annotation.cancel')}\n </button>\n <button type=\"button\" className=\"dsh-office-annotate-primary\" disabled={!items.length || disabled} onClick={send}>{t('annotation.send')}</button>\n </div>\n </div>\n </div>\n )}\n </span>\n )\n}\n","import type { ReactElement, SVGProps } from 'react'\nimport type { OfficeFeatureId } from '../features'\n\n/*\n * Icons from Gravity UI Icons (MIT), https://github.com/gravity-ui/icons.\n * The original SVG files and license are vendored in assets/icons/.\n */\n\ntype OfficeIconProps = SVGProps<SVGSVGElement> & { size?: number }\n\nfunction frame(props: OfficeIconProps): SVGProps<SVGSVGElement> {\n const { size = 16, ...rest } = props\n return {\n 'width': size,\n 'height': size,\n 'viewBox': '0 0 16 16',\n 'fill': 'none',\n 'aria-hidden': true,\n ...rest,\n }\n}\n\n/** file-text: a document page with text lines. */\nexport function DocumentsIcon(props: OfficeIconProps): ReactElement {\n return (\n <svg {...frame(props)}>\n <path\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M5 13.5h6a1.5 1.5 0 0 0 1.5-1.5V7.243a1.5 1.5 0 0 0-.44-1.061L8.819 2.939a1.5 1.5 0 0 0-1.06-.439H5A1.5 1.5 0 0 0 3.5 4v8A1.5 1.5 0 0 0 5 13.5m9-6.257a3 3 0 0 0-.879-2.122L9.88 1.88A3 3 0 0 0 7.757 1H5a3 3 0 0 0-3 3v8a3 3 0 0 0 3 3h6a3 3 0 0 0 3-3zM5 8.25a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5A.75.75 0 0 1 5 8.25m.75 2.25a.75.75 0 0 0 0 1.5h2.5a.75.75 0 0 0 0-1.5z\"\n />\n </svg>\n )\n}\n\n/** file-letter-p: a document page with a P badge. */\nexport function PdfIcon(props: OfficeIconProps): ReactElement {\n return (\n <svg {...frame(props)}>\n <path\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M11 13.5H5A1.5 1.5 0 0 1 3.5 12V4A1.5 1.5 0 0 1 5 2.5h2.757a1.5 1.5 0 0 1 1.061.44l3.243 3.242a1.5 1.5 0 0 1 .439 1.06V12a1.5 1.5 0 0 1-1.5 1.5m2.121-8.379A3 3 0 0 1 14 7.243V12a3 3 0 0 1-3 3H5a3 3 0 0 1-3-3V4a3 3 0 0 1 3-3h2.757a3 3 0 0 1 2.122.879zM6.5 6.5a.75.75 0 0 0-.75.75v4a.75.75 0 0 0 1.5 0v-.75H8.5a2 2 0 1 0 0-4zm2 2.5H7.25V8H8.5a.5.5 0 0 1 0 1\"\n />\n </svg>\n )\n}\n\n/** display: a presentation screen. */\nexport function PresentationsIcon(props: OfficeIconProps): ReactElement {\n return (\n <svg {...frame(props)}>\n <path\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M12 3H4a1.5 1.5 0 0 0-1.5 1.5v4A1.5 1.5 0 0 0 4 10h8a1.5 1.5 0 0 0 1.5-1.5v-4A1.5 1.5 0 0 0 12 3M4 1.5a3 3 0 0 0-3 3v4a3 3 0 0 0 3 3h3.25V13h-2.5a.75.75 0 0 0 0 1.5h6.5a.75.75 0 0 0 0-1.5h-2.5v-1.5H12a3 3 0 0 0 3-3v-4a3 3 0 0 0-3-3z\"\n />\n </svg>\n )\n}\n\n/** layout-cells: a spreadsheet grid. */\nexport function SpreadsheetsIcon(props: OfficeIconProps): ReactElement {\n return (\n <svg {...frame(props)}>\n <path\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M9.25 3.5h-2.5v2h2.5zM4 3.5h1.25v2H2.5V5A1.5 1.5 0 0 1 4 3.5M2.5 7h2.75v2H2.5zm0 3.5v.5A1.5 1.5 0 0 0 4 12.5h1.25v-2zm4.25 0v2h2.5v-2zm4 0v2H12a1.5 1.5 0 0 0 1.5-1.5v-.5zM13.5 9h-2.75V7h2.75zM9.25 9h-2.5V7h2.5zm1.5-5.5v2h2.75V5A1.5 1.5 0 0 0 12 3.5zM4 2a3 3 0 0 0-3 3v6a3 3 0 0 0 3 3h8a3 3 0 0 0 3-3V5a3 3 0 0 0-3-3z\"\n />\n </svg>\n )\n}\n\nexport const OFFICE_ICONS: Record<OfficeFeatureId, (props: OfficeIconProps) => ReactElement> = {\n documents: DocumentsIcon,\n pdf: PdfIcon,\n presentations: PresentationsIcon,\n spreadsheets: SpreadsheetsIcon,\n}\n","import type { UserTextNodeProps } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type { ReactElement } from 'react'\nimport type { OfficeChipInjected } from './types'\nimport { featureById } from '../features'\nimport { OFFICE_ICONS } from './icons'\n\ntype Props = UserTextNodeProps<'office'> & OfficeChipInjected\n\n/** Render the office reference chip with its format glyph. */\nexport function OfficeReference({ node, raw, interactive, openOffice, officeLabel }: Props): ReactElement {\n const feature = featureById(node.data.feature)\n if (feature == null)\n return <span>{raw}</span>\n\n const Icon = OFFICE_ICONS[feature.id]\n const content = (\n <>\n <Icon className=\"dsh-office-ref-icon\" size={14} />\n <span>{officeLabel(feature.id)}</span>\n </>\n )\n\n if (!interactive) {\n return (\n <span className=\"dsh-office-ref\" title={raw}>\n {content}\n </span>\n )\n }\n\n return (\n <button\n type=\"button\"\n className=\"dsh-office-ref\"\n title={raw}\n data-interactive\n onClick={() => openOffice(feature.id)}\n >\n {content}\n </button>\n )\n}\n","import { ANNOTATION_CURSOR, OFFICE_NS, OFFICE_STYLE_ID } from './constants'\n\n/** One plugin-scoped style tag; the disposer owns removal. */\nexport function mountOfficeStyles(): () => void {\n if (typeof document === 'undefined')\n return () => {}\n\n const style = document.querySelector<HTMLStyleElement>(`style[data-plugin-css=\"${OFFICE_STYLE_ID}\"]`) ?? document.createElement('style')\n style.dataset.plugin = OFFICE_NS\n style.dataset.pluginCss = OFFICE_STYLE_ID\n style.textContent = `\n.dsh-office-ref {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n max-width: 100%;\n height: calc(20px + var(--dsh-content-font-delta, 0px));\n padding: 0 6px;\n border: 0.5px solid var(--dsw-alias-border-l3);\n border-radius: var(--dsw-radius-sm);\n background: var(--dsw-alias-bg-base);\n color: var(--dsw-alias-label-secondary);\n font: inherit;\n line-height: 1;\n vertical-align: baseline;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.dsh-office-ref[data-interactive] { cursor: pointer; }\n.dsh-office-ref[data-interactive]:hover {\n background: var(--dsw-alias-interactive-bg-hover-solid);\n color: var(--dsw-alias-label-primary);\n}\n.dsh-office-ref[data-interactive]:focus-visible {\n outline: 2px solid var(--dsw-alias-state-business-primary);\n outline-offset: 1px;\n}\n.dsh-office-ref-icon { flex: none; color: var(--dsw-alias-label-tertiary); }\n.dsh-office-ref[data-interactive]:hover .dsh-office-ref-icon { color: inherit; }\n.dsh-office-annotate { display: inline-flex; flex: none; }\n.dsh-office-annotate,\n.dsh-office-annotation-reference { font: 400 12px/18px var(--dsw-font-family, system-ui, sans-serif); }\n.dsh-office-annotate *,\n.dsh-office-annotation-reference * { box-sizing: border-box; }\n.dsh-office-annotate button,\n.dsh-office-annotation-reference button {\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--dsw-radius-md);\n padding: 5px 9px;\n color: var(--dsw-alias-label-primary);\n background: var(--dsw-alias-bg-base);\n font: inherit;\n font-size: 12px;\n line-height: 1.4;\n cursor: pointer;\n}\n.dsh-office-annotate button:disabled { opacity: .45; cursor: not-allowed; }\n.dsh-office-annotate button:hover:not(:disabled),\n.dsh-office-annotation-reference button:hover { background: var(--dsw-alias-interactive-bg-hover-solid); }\n.dsh-office-annotate button:focus-visible,\n.dsh-office-annotation-reference button:focus-visible {\n outline: 2px solid var(--dsw-alias-state-business-primary);\n outline-offset: 2px;\n}\n.dsh-office-annotate .dsh-office-annotate-toggle {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n height: 24px;\n padding: 0 8px;\n line-height: 1;\n}\n.dsh-office-annotate .dsh-office-annotate-toggle[aria-pressed=\"true\"],\n.dsh-office-annotate .dsh-office-annotate-primary {\n color: var(--dsw-alias-state-business-primary);\n border-color: var(--dsw-alias-state-business-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 10%, var(--dsw-alias-bg-base));\n}\n.dsh-office-annotate .dsh-office-annotate-surface {\n position: fixed;\n z-index: 40;\n touch-action: none;\n user-select: none;\n outline: none;\n cursor: ${ANNOTATION_CURSOR};\n}\n.dsh-office-annotate .dsh-office-annotate-highlight {\n position: fixed;\n z-index: 41;\n box-sizing: border-box;\n pointer-events: none;\n border: 1.25px solid var(--dsw-alias-state-business-primary);\n border-radius: 3px;\n}\n.dsh-office-annotate .dsh-office-annotate-highlight[data-selected=\"true\"] {\n border-style: dashed;\n background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 8%, transparent);\n}\n.dsh-office-annotate .dsh-office-annotate-composer {\n position: fixed;\n z-index: 42;\n box-sizing: border-box;\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n box-shadow: var(--dsw-shadow-lv2);\n}\n.dsh-office-annotate .dsh-office-annotate-composer {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 4px;\n border-radius: 999px;\n}\n.dsh-office-annotate .dsh-office-annotate-composer input:focus-visible { outline: none; }\n.dsh-office-annotate .dsh-office-annotate-composer input {\n box-sizing: border-box;\n min-width: 0;\n width: 100%;\n padding: 6px 10px;\n border: 0;\n border-radius: 999px;\n color: var(--dsw-alias-label-primary);\n background: transparent;\n font: inherit;\n font-size: 12px;\n line-height: 1.5;\n}\n.dsh-office-annotate .dsh-office-annotate-composer button {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 0;\n border: 0;\n border-radius: 50%;\n color: var(--dsw-alias-state-business-primary);\n background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 10%, var(--dsw-alias-bg-base));\n}\n.dsh-office-annotate .dsh-office-annotate-composer button svg { width: 14px; height: 14px; }\n.dsh-office-annotate .dsh-office-annotate-rail-position {\n position: fixed;\n z-index: 42;\n display: flex;\n justify-content: center;\n padding: 0 8px;\n pointer-events: none;\n}\n.dsh-office-annotate .dsh-office-annotate-rail {\n position: relative;\n width: max-content;\n max-width: 100%;\n padding: 4px 6px;\n border-radius: 10px;\n background: var(--dsw-alias-toast-bg);\n color: var(--dsw-alias-toast-label);\n font: 500 12px/18px var(--dsw-font-family, system-ui, sans-serif);\n box-shadow: var(--dsw-shadow-lv3);\n pointer-events: auto;\n}\n.dsh-office-annotate .dsh-office-annotate-rail-actions { display: flex; align-items: center; justify-content: center; gap: 4px; }\n.dsh-office-annotate .dsh-office-annotate-rail-actions > button,\n.dsh-office-annotate .dsh-office-annotate-summary > button {\n height: 26px;\n padding: 0 8px;\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: inherit;\n font: inherit;\n white-space: nowrap;\n}\n.dsh-office-annotate .dsh-office-annotate-summary { padding-right: 4px; border-right: 1px solid color-mix(in srgb, var(--dsw-alias-toast-label) 25%, transparent); }\n.dsh-office-annotate .dsh-office-annotate-rail-actions > button:hover:not(:disabled),\n.dsh-office-annotate .dsh-office-annotate-summary > button:hover:not(:disabled) { background: color-mix(in srgb, var(--dsw-alias-toast-label) 12%, transparent); }\n.dsh-office-annotate .dsh-office-annotate-rail-actions > .dsh-office-annotate-primary { background: var(--dsw-alias-state-business-primary); color: var(--dsw-alias-toast-label); }\n.dsh-office-annotate .dsh-office-annotate-rail-actions > .dsh-office-annotate-primary:hover:not(:disabled) { background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 85%, var(--dsw-alias-toast-label)); }\n.dsh-office-annotate .dsh-office-annotate-rail p { max-width: min(360px, calc(var(--dsh-office-annotation-width) - 48px)); margin: 0 0 6px; font-size: 12px; overflow-wrap: anywhere; }\n.dsh-office-annotate .dsh-office-annotate-popover {\n display: none;\n position: absolute;\n bottom: 100%;\n left: 50%;\n width: min(320px, calc(var(--dsh-office-annotation-width, 100vw) - 16px), calc(100vw - 16px));\n box-sizing: border-box;\n padding-bottom: 8px;\n transform: translateX(-50%);\n}\n.dsh-office-annotate .dsh-office-annotate-summary:not([data-dismissed=\"true\"]):is(:hover, :focus-within) > .dsh-office-annotate-popover { display: block; }\n.dsh-office-annotation-reference { display: inline-block; position: relative; max-width: 100%; vertical-align: baseline; font: inherit; }\n.dsh-office-annotation-reference > button {\n max-width: 100%;\n padding: 0;\n border: 0;\n border-radius: 0;\n background: transparent;\n color: var(--dsw-alias-link);\n font: inherit;\n font-family: var(--dsw-font-markdown-code-font-family);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n vertical-align: baseline;\n}\n.dsh-office-annotation-reference > button:hover {\n background: transparent;\n text-decoration: underline dotted;\n text-underline-offset: 3px;\n}\n.dsh-office-annotation-reference .dsh-office-annotation-popover {\n display: none;\n position: fixed;\n z-index: 44;\n inset: auto;\n width: min(320px, calc(100vw - 16px));\n max-height: calc(100vh - 16px);\n box-sizing: border-box;\n margin: 0;\n padding: 4px 0;\n border: 0;\n background: transparent;\n color: var(--dsw-alias-label-primary);\n overflow: visible;\n text-align: left;\n font: 400 12px/18px var(--dsw-font-family, system-ui, sans-serif);\n}\n.dsh-office-annotation-reference .dsh-office-annotation-popover[data-open=\"true\"] { display: block; }\n.dsh-office-annotation-reference .dsh-office-annotation-popover::backdrop { pointer-events: none; }\n.dsh-office-annotate .dsh-office-annotate-popover > ul,\n.dsh-office-annotation-reference .dsh-office-annotation-list {\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n max-height: min(340px, 45vh);\n margin: 0;\n padding: 0 8px;\n font: 400 12px/18px var(--dsw-font-family, system-ui, sans-serif);\n text-align: left;\n overflow: auto;\n list-style: none;\n border: 0.5px solid var(--dsw-alias-border-l2);\n border-radius: var(--dsw-radius-md);\n background: var(--dsw-alias-bg-layer-2);\n color: var(--dsw-alias-label-primary);\n box-shadow: var(--dsw-shadow-lv2);\n}\n.dsh-office-annotate .dsh-office-annotate-popover > ul { max-height: min(340px, 45vh, max(40px, calc(var(--dsh-office-annotation-height, 100vh) - 80px))); }\n.dsh-office-annotate .dsh-office-annotate-popover li,\n.dsh-office-annotation-reference .dsh-office-annotation-item { display: flex; flex: none; flex-direction: column; gap: 3px; min-width: 0; padding: 8px 0; }\n.dsh-office-annotate .dsh-office-annotate-popover li > div { display: flex; flex-direction: column; gap: 3px; min-width: 0; }\n.dsh-office-annotate .dsh-office-annotate-popover .dsh-office-annotation-requirement { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.dsh-office-annotate .dsh-office-annotate-popover li + li,\n.dsh-office-annotation-reference .dsh-office-annotation-item + .dsh-office-annotation-item { border-top: .5px solid var(--dsw-alias-border-l3); }\n.dsh-office-annotate .dsh-office-annotation-source,\n.dsh-office-annotation-reference .dsh-office-annotation-source { display: flex; align-items: baseline; gap: 8px; color: var(--dsw-alias-label-tertiary); font-size: 12px; }\n.dsh-office-annotation-reference .dsh-office-annotation-source button { padding: 0; border: 0; color: var(--dsw-alias-state-business-primary); text-align: left; }\n.dsh-office-annotate .dsh-office-annotation-source > :first-child,\n.dsh-office-annotation-reference .dsh-office-annotation-source > :first-child { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.dsh-office-annotate .dsh-office-annotation-source > :not(:first-child),\n.dsh-office-annotation-reference .dsh-office-annotation-source > :not(:first-child) { flex: none; }\n.dsh-office-annotate .dsh-office-annotation-original,\n.dsh-office-annotation-reference .dsh-office-annotation-original { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--dsw-alias-label-tertiary); font-size: 12px; }\n.dsh-office-annotate .dsh-office-annotation-requirement,\n.dsh-office-annotation-reference .dsh-office-annotation-requirement { display: block; white-space: pre-wrap; overflow-wrap: anywhere; }\n`\n document.head.appendChild(style)\n return () => style.remove()\n}\n","import type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-api-remotes/client'\nimport type {} from '@deepseek-ai/dsh-api-session-controller/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type { UserTextRule } from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type { InputTriggerSource } from '@deepseek-ai/dsh-client-ui-input-trigger/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-sidebar-right/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport type { OfficeFeatureId } from '../features'\nimport type { AnnotationController, AnnotationInjected, PendingAnnotation } from './types'\nimport { rankByName } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { featureByCommand, featureById, OFFICE_FEATURES } from '../features'\nimport { annotationRule } from './annotation'\nimport { AnnotationReference } from './annotation-reference'\nimport { ANNOTATION_ID, ANNOTATION_NODE, ANNOTATION_ORDER, ANNOTATION_PRIORITY, ANNOTATION_SLOT, FILE_ADDRESS_PREFIX, OFFICE_CHIP, OFFICE_CHIP_SLOT, OFFICE_NS, OFFICE_SOURCE } from './constants'\nimport { DocumentAnnotation } from './document-annotation'\nimport { OFFICE_ICONS } from './icons'\nimport { OfficeReference } from './office-reference'\nimport { mountOfficeStyles } from './styles'\n\n/** Client services used by this half. */\nexport const inject = [\n 'inputTriggers',\n 'sessions',\n 'slots',\n 'locale',\n 'remote',\n 'remote.skills',\n 'sidebarRight',\n 'uiConversation',\n 'conversation',\n]\n\nconst zh = {\n 'menu.group': '办公',\n 'menu.documents.label': '文档',\n 'menu.documents.description': '创建、读取、编辑和渲染 DOCX 文档',\n 'menu.pdf.label': 'PDF 文档',\n 'menu.pdf.description': '读取、创建、检查、渲染和验证 PDF',\n 'menu.presentations.label': '演示文稿',\n 'menu.presentations.description': '创建、编辑、渲染和导出 PPTX 演示文稿',\n 'menu.spreadsheets.label': '电子表格',\n 'menu.spreadsheets.description': '创建、编辑、计算和导出 XLSX 电子表格',\n 'annotation.ask': '请求修改',\n 'annotation.cancel': '取消',\n 'annotation.send': '发送',\n 'annotation.add': '添加标注',\n 'annotation.placeholder': '说明要怎么改…',\n 'annotation.page': '第 {page} 页',\n 'annotation.count': '{count} 条注释',\n 'annotation.remove': '删除第 {index} 条注释',\n 'annotation.image': '位置截图:{name}',\n 'annotation.help': '悬停吸附段落,点击输入要求;长按拖动框选区域,松开添加标注。方向键选择,Enter 确认,Esc 退出。',\n 'annotation.unavailable': '等待文档页面渲染;当前预览不支持标注',\n 'annotation.capturing': '正在截图…',\n 'annotation.captureFailed': '截图失败,请重新选择区域',\n 'annotation.intakeUnavailable': '当前 DSH 版本不支持从侧栏添加截图附件,PDF 标注已禁用',\n 'annotation.imageLimit': '截图超过当前模型的数量或大小限制,请减少标注后重试',\n 'annotation.sendFailed': '未能加入会话,请重试;标注仍保留',\n 'annotation.draftReady': '标注和截图已保留在会话输入框,请在那里确认发送',\n 'annotation.invalid': '标注内容无效,请重新添加',\n 'annotation.tooLarge': '标注内容过长,请减少后重试',\n 'annotation.emptyPage': '页面尚未渲染,请重试',\n 'annotation.emptyRegion': '请选择页面内的区域',\n} as const\n\nconst en: Record<keyof typeof zh, string> = {\n 'menu.group': 'Office',\n 'menu.documents.label': 'Documents',\n 'menu.documents.description': 'Create, read, edit, and render DOCX documents',\n 'menu.pdf.label': 'PDF documents',\n 'menu.pdf.description': 'Read, create, inspect, render, and verify PDFs',\n 'menu.presentations.label': 'Presentations',\n 'menu.presentations.description': 'Create, edit, render, and export PPTX decks',\n 'menu.spreadsheets.label': 'Spreadsheets',\n 'menu.spreadsheets.description': 'Create, edit, calculate, and export XLSX workbooks',\n 'annotation.ask': 'Request changes',\n 'annotation.cancel': 'Cancel',\n 'annotation.send': 'Send',\n 'annotation.add': 'Add annotation',\n 'annotation.placeholder': 'Describe the change…',\n 'annotation.page': 'page {page}',\n 'annotation.count': '{count} annotations',\n 'annotation.remove': 'Remove annotation {index}',\n 'annotation.image': 'Location screenshot: {name}',\n 'annotation.help': 'Hover to select a paragraph; click to comment. Hold and drag to select a region. Arrow keys select, Enter confirms, Esc exits.',\n 'annotation.unavailable': 'Waiting for rendered pages; this preview cannot be annotated yet',\n 'annotation.capturing': 'Capturing…',\n 'annotation.captureFailed': 'Screenshot failed; please select the region again',\n 'annotation.intakeUnavailable': 'This DSH version cannot add screenshots from the sidebar; PDF annotation is disabled',\n 'annotation.imageLimit': 'Screenshots exceed the current model’s count or size limits; remove some annotations and retry',\n 'annotation.sendFailed': 'Could not add annotations to the conversation; your annotations are retained',\n 'annotation.draftReady': 'Annotations and screenshots are kept in the conversation input; confirm sending there',\n 'annotation.invalid': 'Invalid annotation; please add it again',\n 'annotation.tooLarge': 'Annotations are too long; remove some and retry',\n 'annotation.emptyPage': 'The page has not rendered yet; please retry',\n 'annotation.emptyRegion': 'Select a region inside the page',\n}\n\ninterface OfficeSkillSummary {\n readonly name: string\n readonly path?: string\n}\n\ninterface CatalogEntry {\n readonly abort: AbortController\n readonly promise: Promise<readonly OfficeSkillSummary[]>\n settled?: readonly OfficeSkillSummary[]\n}\n\nfunction encodeSegment(segment: string): string {\n return encodeURIComponent(segment).replace(/%3A/gi, ':')\n}\n\nfunction encodePath(path: string): string {\n return path.split('/').map(encodeSegment).join('/')\n}\n\nfunction sessionFileAddress(sessionId: string, path: string): string {\n const normalized = path.replace(/\\\\/g, '/').replace(/^(?:\\.\\/)+/u, '')\n return `${FILE_ADDRESS_PREFIX}session/${encodeSegment(sessionId)}/${encodePath(normalized)}`\n}\n\nfunction fileAddressFor(sessionId: string, cwd: string | undefined, path: string): string {\n const normalized = path.replace(/\\\\/g, '/')\n const root = cwd?.replace(/\\\\/g, '/').replace(/\\/+$/u, '') ?? ''\n if (!/^(?:\\/|[A-Za-z]:\\/|\\\\\\\\)/u.test(normalized))\n return sessionFileAddress(sessionId, normalized)\n if (root !== '' && normalized.startsWith(`${root}/`))\n return sessionFileAddress(sessionId, normalized.slice(root.length + 1))\n return sessionFileAddress(sessionId, normalized)\n}\n\ninterface OfficeSkillCatalog {\n list: (input: { sessionId: string }, signal?: AbortSignal) => Promise<\n | { ok: true, value: { skills: readonly OfficeSkillSummary[] } }\n | { ok: false, error: { code: string, message: string } }\n >\n}\n\ninterface OfficeSessionReference {\n readonly binding: {\n readonly session: {\n getSnapshot: () => { openState: string, openError?: Error }\n }\n }\n}\n\n/**\n * The small public Session face this client needs. The installed DSH assembly\n * also ships a host `dsh-session` augmentation that widens `ctx.sessions` with\n * an incompatible `SessionStore`, so narrow through the documented client face.\n */\ninterface OfficeSessions {\n binding: (sessionId: string) => unknown\n using: <T>(\n sessionId: string,\n options: { source: string, signal: AbortSignal },\n fn: (reference: OfficeSessionReference) => Promise<T>,\n ) => Promise<T>\n list: {\n getSnapshot: () => { byId: Record<string, { cwd?: string } | undefined> }\n }\n}\n\n/** Register the `/` source, transcript chip, and right-sidebar preview. */\nexport function apply(ctx: ClientContext): void {\n const sessions = ctx.sessions as unknown as OfficeSessions\n const remoteSkills = (ctx.remote as unknown as { skills: OfficeSkillCatalog }).skills\n const t = ctx.locale.bind(OFFICE_NS)\n const entries = new Map<string, CatalogEntry>()\n const pendingAnnotations = new Map<string, Map<string, readonly PendingAnnotation[]>>()\n\n ctx.effect(() => mountOfficeStyles(), 'office-suite: styles')\n ctx.effect(() => ctx.locale.register(OFFICE_NS, { zh, en }), 'office-suite: dictionaries')\n\n function catalogFor(sessionId: string): CatalogEntry {\n const existing = entries.get(sessionId)\n if (existing !== undefined)\n return existing\n\n const abort = new AbortController()\n const promise = (async () => {\n if (sessions.binding(sessionId) === undefined)\n throw new Error(`office catalog requires a retained session \"${sessionId}\"`)\n return sessions.using(sessionId, { source: 'officeCatalog', signal: abort.signal }, async (reference) => {\n abort.signal.throwIfAborted()\n const state = reference.binding.session.getSnapshot()\n if (state.openState !== 'open')\n throw state.openError ?? new Error(`session \"${sessionId}\" is not open`)\n const result = await remoteSkills.list({ sessionId }, abort.signal)\n abort.signal.throwIfAborted()\n if (!result.ok)\n throw new Error(`skills/list failed: ${result.error.code}: ${result.error.message}`)\n return result.value.skills\n })\n })()\n\n const entry: CatalogEntry = { abort, promise }\n entries.set(sessionId, entry)\n promise.then((skills) => {\n entry.settled = skills\n }, () => {\n if (entries.get(sessionId) === entry)\n entries.delete(sessionId)\n })\n return entry\n }\n\n function openSkill(sessionId: string, feature: OfficeFeatureId, catalog: readonly OfficeSkillSummary[]): boolean {\n const definition = featureById(feature)\n if (definition === undefined)\n return false\n const skill = catalog.find(item => item.name === definition.skill)\n if (skill?.path === undefined)\n return false\n const cwd = sessions.list.getSnapshot().byId[sessionId]?.cwd\n try {\n ctx.sidebarRight.openResource(fileAddressFor(sessionId, cwd, skill.path))\n return true\n }\n catch (error) {\n console.error('[dsh-office-kit] reference preview failed:', error)\n return false\n }\n }\n\n const source: InputTriggerSource = {\n trigger: '/',\n name: OFFICE_SOURCE,\n order: 1,\n async candidates(_session, { query, signal }) {\n if (signal.aborted)\n return []\n const items = OFFICE_FEATURES.map((feature) => {\n const Icon = OFFICE_ICONS[feature.id]\n return {\n name: feature.command,\n label: t(`menu.${feature.id}.label`),\n description: t(`menu.${feature.id}.description`),\n section: t('menu.group'),\n icon: Icon,\n }\n })\n return query.length === 0 ? items : rankByName(items, query)\n },\n lexicon() {\n return OFFICE_FEATURES.map(feature => feature.command)\n },\n openReference(session, { ref }) {\n const feature = featureById(ref)\n if (feature === undefined)\n return false\n\n const settled = entries.get(session.sessionId)?.settled\n if (settled !== undefined)\n return openSkill(session.sessionId, feature.id, settled)\n\n const entry = catalogFor(session.sessionId)\n entry.promise.then((catalog) => {\n if (!entry.abort.signal.aborted)\n openSkill(session.sessionId, feature.id, catalog)\n }).catch((error) => {\n if (!entry.abort.signal.aborted)\n console.error('[dsh-office-kit] reference preview failed:', error)\n })\n return true\n },\n onPick({ candidate }) {\n const feature = featureByCommand(candidate.name)\n if (feature === undefined)\n return undefined\n return {\n insert: {\n source: OFFICE_SOURCE,\n ref: feature.id,\n label: t(`menu.${feature.id}.label`),\n appearance: 'file',\n clipboardText: `/${feature.command}`,\n },\n }\n },\n codec: {\n clipboardText(ref) {\n const feature = featureById(ref)\n return feature === undefined ? `/${ref}` : `/${feature.command}`\n },\n async serialize(ref) {\n const feature = featureById(ref)\n if (feature === undefined)\n return '/documents'\n return `/${feature.command}\\n\\nUse the \"${feature.skill}\" skill for this request and follow its instructions before creating, editing, or rendering files.`\n },\n },\n }\n\n const rule: UserTextRule<'office'> = {\n id: OFFICE_CHIP,\n order: 20,\n match(text, from) {\n const tokens = /(?<!\\S)\\/([\\w-]+)(?!\\S)/gu\n tokens.lastIndex = from\n for (let token = tokens.exec(text); token !== null; token = tokens.exec(text)) {\n const feature = featureByCommand(token[1] ?? '')\n if (feature === undefined)\n continue\n return {\n id: OFFICE_CHIP,\n start: token.index,\n end: token.index + token[0].length,\n data: { feature: feature.id },\n }\n }\n return undefined\n },\n }\n\n ctx.effect(() => ctx.uiConversation.userText.register(rule), 'office-suite: transcript chip')\n\n ctx.effect(() => ctx.slots.inject(OFFICE_CHIP_SLOT, () => ctx.slots.register({\n name: OFFICE_CHIP_SLOT,\n key: OFFICE_CHIP,\n priority: 100,\n inject: (sessionId: string) => ({\n openOffice: (feature: OfficeFeatureId) => {\n source.openReference?.({ sessionId: sessionId as never }, { ref: feature, appearance: 'file' })\n },\n officeLabel: (feature: OfficeFeatureId) => t(`menu.${feature}.label`),\n }),\n }, OfficeReference)), 'office-suite: transcript chip slot')\n\n function annotationDependencies(sessionId: string): AnnotationInjected {\n const controller = ctx.conversation as unknown as Partial<AnnotationController>\n const compatible = typeof controller.createDrafts === 'function'\n && typeof controller.releaseDraftAttachments === 'function'\n && typeof controller.resolveDraftAttachments === 'function'\n let pending = pendingAnnotations.get(sessionId)\n if (!pending) {\n pending = new Map()\n pendingAnnotations.set(sessionId, pending)\n }\n return {\n pendingAnnotations: pending,\n // ponytail: current DSH concrete File intake only, replace with outward intake API when exported.\n intake: compatible\n ? {\n create: files => controller.createDrafts!(sessionId as never, files),\n release: drafts => controller.releaseDraftAttachments!(drafts),\n images: ids => controller.resolveDraftAttachments!(ids).filter(item => item.kind === 'image').map(item => item.file),\n }\n : undefined,\n openAnnotation: (target) => {\n try {\n const cwd = sessions.list.getSnapshot().byId[sessionId]?.cwd\n ctx.sidebarRight.openResource(fileAddressFor(sessionId, cwd, target))\n }\n catch (error) {\n console.error('[dsh-office-kit] annotation preview failed:', error)\n }\n },\n }\n }\n\n ctx.effect(() => ctx.uiConversation.userText.register(annotationRule), 'office-suite: annotations')\n ctx.effect(() => ctx.slots.inject(OFFICE_CHIP_SLOT, () => ctx.slots.register({\n name: OFFICE_CHIP_SLOT,\n key: ANNOTATION_NODE,\n priority: ANNOTATION_PRIORITY,\n locale: OFFICE_NS,\n inject: annotationDependencies,\n }, AnnotationReference)), 'office-suite: annotation references')\n ctx.effect(() => ctx.slots.inject(ANNOTATION_SLOT, () => ctx.slots.register({\n name: ANNOTATION_SLOT,\n id: ANNOTATION_ID,\n order: ANNOTATION_ORDER,\n locale: OFFICE_NS,\n inject: annotationDependencies,\n }, DocumentAnnotation)), 'office-suite: annotation tool')\n\n const inputTriggers = ctx.inputTriggers\n ctx.effect(() => {\n const unregister = inputTriggers.registerSource(source)\n return () => {\n unregister()\n for (const entry of entries.values())\n entry.abort.abort()\n entries.clear()\n pendingAnnotations.clear()\n }\n }, 'office-suite: slash source')\n}\n"],"mappings":";4KAqBA,MAAa,EAA4C,CACvD,CACE,GAAI,YACJ,MAAO,YACP,YAAa,2DACb,KAAM,OACN,MAAO,mBACP,QAAS,YACT,WAAY,CAAC,OAAO,CACtB,EACA,CACE,GAAI,MACJ,MAAO,MACP,YAAa,oDACb,KAAM,MACN,MAAO,aACP,QAAS,MACT,WAAY,CAAC,MAAM,CACrB,EACA,CACE,GAAI,gBACJ,MAAO,gBACP,YAAa,wDACb,KAAM,OACN,MAAO,uBACP,QAAS,gBACT,WAAY,CAAC,OAAO,CACtB,EACA,CACE,GAAI,eACJ,MAAO,eACP,YAAa,mEACb,KAAM,OACN,MAAO,sBACP,QAAS,eACT,WAAY,CAAC,OAAO,CACtB,CACF,EAGA,SAAgB,EAAY,EAAuC,CACjE,OAAO,EAAgB,KAAK,GAAW,EAAQ,KAAO,CAAE,CAC1D,CAGA,SAAgB,EAAiB,EAA4C,CAC3E,OAAO,EAAgB,KAAK,GAAW,EAAQ,UAAY,CAAO,CACpE,CCnEA,MAAa,EAAY,iBACZ,EAAgB,SAChB,EAAc,SACd,EAAmB,8BAGnB,EAAkB,qCAIlB,EAAkB,mBAClB,EAAkB,uBAClB,EAAmB,wBAMnB,EAA6B,iCAS7B,EAAsB,ICfnC,SAAgB,EAAa,EAAkB,EAAwC,CACrF,OAAO,EAAS,QAAQ,eAAgB,EAAO,IAAiB,EAAO,IAAS,CAAK,CACvF,CAMA,SAAgB,EAAmB,EAAqB,CACtD,IAAM,EAAkB,CAAC,EACzB,IAAK,IAAM,KAAQ,EAAI,QAAQ,UAAW;CAAI,CAAC,CAAC,MAAM;CAAI,EAAG,CAC3D,IAAM,EAAY,EAAK,QAAQ,QAAS,GAAG,CAAC,CAAC,KAAK,EAC9C,EAAU,OAAS,GACrB,EAAM,KAAK,CAAS,CACxB,CACA,OAAO,EAAM,KAAK;CAAI,CACxB,CCxBA,SAAgB,EAAU,EAAmB,EAAmC,CAC9E,IAAM,EAAO,KAAK,IAAI,EAAE,KAAM,EAAE,IAAI,EAC9B,EAAM,KAAK,IAAI,EAAE,IAAK,EAAE,GAAG,EACjC,MAAO,CAAE,OAAM,MAAK,MAAO,KAAK,IAAI,EAAE,KAAO,EAAE,MAAO,EAAE,KAAO,EAAE,KAAK,EAAI,EAAM,OAAQ,KAAK,IAAI,EAAE,IAAM,EAAE,OAAQ,EAAE,IAAM,EAAE,MAAM,EAAI,CAAI,CAC7I,CAEA,SAAgB,EAAc,EAAmB,EAA+C,CAC9F,IAAM,EAAO,KAAK,IAAI,EAAE,KAAM,EAAE,IAAI,EAC9B,EAAM,KAAK,IAAI,EAAE,IAAK,EAAE,GAAG,EAC3B,EAAQ,KAAK,IAAI,EAAE,KAAO,EAAE,MAAO,EAAE,KAAO,EAAE,KAAK,EAAI,EACvD,EAAS,KAAK,IAAI,EAAE,IAAM,EAAE,OAAQ,EAAE,IAAM,EAAE,MAAM,EAAI,EAC9D,OAAO,EAAQ,GAAK,EAAS,EAAI,CAAE,OAAM,MAAK,QAAO,QAAO,EAAI,IAAA,EAClE,CAGA,SAAgB,EAAW,EAAqB,EAAkD,CAChG,OAAO,EAAc,CAAE,KAAM,EAAI,KAAA,EAA2B,IAAK,EAAI,IAAA,EAA0B,MAAO,EAAI,MAAA,EAAgC,OAAQ,EAAI,OAAA,CAAgC,EAAG,CAAI,CAC/L,CAEA,SAAgB,EAAc,EAAqB,EAAW,EAAoB,CAChF,OAAO,GAAK,EAAI,MAAQ,GAAK,EAAI,KAAO,EAAI,OAAS,GAAK,EAAI,KAAO,GAAK,EAAI,IAAM,EAAI,MAC1F,CAGA,SAAgB,EAA0B,EAAwB,EAAiD,EAA0F,CAC3M,MAAO,CACL,KAAM,KAAK,IAAI,EAAG,KAAK,IAAI,EAAO,KAAM,EAAS,MAAQ,EAAM,MAAQ,CAAC,CAAC,EACzE,IAAK,KAAK,IAAI,EAAG,KAAK,IAAI,EAAO,KAAO,EAAM,OAAS,EAAI,EAAO,IAAM,EAAM,OAAS,EAAO,IAAM,EAAO,OAAQ,EAAS,OAAS,EAAM,OAAS,CAAC,CAAC,CACxJ,CACF,CAGA,SAAgB,GAAiB,EAA4C,EAAW,EAA4C,CAClI,IAAI,EACJ,IAAK,IAAM,KAAa,EAAY,CAClC,IAAM,EAAM,EAAU,KACjB,EAAU,OAAS,CAAC,CAAG,EAAA,CAAG,KAAK,GAAQ,GAAK,EAAK,KAAA,GAA2B,GAAK,EAAK,KAAO,EAAK,MAAA,GAClG,GAAK,EAAK,IAAA,GAA0B,GAAK,EAAK,IAAM,EAAK,OAAA,CAAyB,IACnF,CAAC,GAAO,EAAI,MAAQ,EAAI,OAAS,EAAI,IAAI,MAAQ,EAAI,IAAI,UAC3D,EAAM,EAEV,CACA,OAAO,CACT,CAGA,SAAgB,EAAgB,EAA2D,CACzF,IAAM,EAA0E,CAAC,EACjF,IAAK,IAAM,IAAO,CAAC,GAAG,CAAI,CAAC,CAAC,MAAM,EAAG,IAAM,EAAE,IAAI,IAAM,EAAE,IAAI,KAAO,EAAE,IAAI,KAAO,EAAE,IAAI,IAAI,EAAG,CAC5F,GAAI,CAAC,EAAI,KAAK,KAAK,GAAK,EAAI,IAAI,OAAS,GAAK,EAAI,IAAI,QAAU,EAC9D,SACF,IAAM,EAAO,EAAM,KAAK,GAAQ,KAAK,IAAI,EAAK,IAAI,IAAM,EAAI,IAAI,GAAG,EAAI,KAAK,IAAI,EAAK,IAAI,OAAQ,EAAI,IAAI,MAAM,EAAI,KAC9G,EAAI,IAAI,MAAQ,EAAK,IAAI,MAAQ,EAAI,IAAI,MAAQ,EAAK,IAAI,KAAO,EAAK,IAAI,OAAS,EAAI,IAAI,OAAS,CAAC,EACtG,GACF,EAAK,MAAQ,IAAI,EAAI,OACrB,EAAK,IAAM,EAAU,EAAK,IAAK,EAAI,GAAG,EACtC,EAAK,MAAM,KAAK,EAAI,GAAG,GAGvB,EAAM,KAAK,CAAE,KAAM,EAAI,KAAM,IAAK,EAAI,IAAK,MAAO,CAAC,EAAI,GAAG,CAAE,CAAC,CAEjE,CACA,IAAM,EAAqG,CAAC,EAC5G,IAAK,IAAM,KAAQ,EAAO,CACxB,IAAM,EAAY,EAAW,SAAU,GAAS,CAC9C,IAAM,EAAM,EAAK,IAAI,KAAO,EAAK,KAAK,IAAM,EAAK,KAAK,QAChD,EAAU,KAAK,IAAI,EAAK,KAAK,KAAO,EAAK,KAAK,MAAO,EAAK,IAAI,KAAO,EAAK,IAAI,KAAK,EAAI,KAAK,IAAI,EAAK,KAAK,KAAM,EAAK,IAAI,IAAI,EACnI,OAAO,GAAO,CAAC,EAAK,IAAI,OAAS,IAAO,GAAO,KAAK,IAAI,EAAK,KAAK,OAAQ,EAAK,IAAI,MAAM,EAAI,IACxF,EAAU,GAAK,KAAK,IAAI,EAAK,KAAK,KAAO,EAAK,IAAI,IAAI,EAAI,EAAK,IAAI,OAAS,GAC5E,KAAK,IAAI,EAAK,KAAK,OAAQ,EAAK,IAAI,MAAM,EAAI,KAAK,IAAI,EAAK,KAAK,OAAQ,EAAK,IAAI,MAAM,EAAI,GACnG,CAAC,EACG,GACF,EAAU,MAAQ,KAAK,EAAK,OAC5B,EAAU,IAAM,EAAU,EAAU,IAAK,EAAK,GAAG,EACjD,EAAU,MAAM,KAAK,GAAG,EAAK,KAAK,EAClC,EAAU,KAAO,EAAK,KAGtB,EAAW,KAAK,CAAE,GAAG,EAAM,KAAM,EAAK,GAAI,CAAC,CAE/C,CACA,OAAO,EAAW,KAAK,CAAE,OAAM,MAAK,YAAa,CAAE,KAAM,EAAmB,CAAI,EAAG,MAAK,OAAM,EAAE,CAClG,CAGA,SAAgB,EAAiB,EAAkD,CACjF,IAAM,EAAU,EAAO,cACvB,GAAI,CAAC,EACH,MAAO,CAAC,EACV,IAAM,EAAS,SAAS,iBAAiB,EAAS,WAAW,SAAS,EAChE,EAA4B,CAAC,EACnC,IAAK,IAAI,EAAO,EAAO,SAAS,EAAG,EAAM,EAAO,EAAO,SAAS,EAAG,CACjE,GAAI,CAAC,EAAK,aAAa,KAAK,EAC1B,SACF,IAAM,EAAQ,SAAS,YAAY,EACnC,EAAM,mBAAmB,CAAI,EAC7B,IAAM,EAAM,EAAM,sBAAsB,EACpC,EAAI,MAAQ,GAAK,EAAI,OAAS,GAChC,EAAK,KAAK,CAAE,KAAM,EAAK,YAAa,IAAK,CAAE,KAAM,EAAI,KAAM,IAAK,EAAI,IAAK,MAAO,EAAI,MAAO,OAAQ,EAAI,MAAO,CAAE,CAAC,CACrH,CAEA,OAAO,EAAgB,CAAI,CAC7B,CAGA,SAAgB,GAAkB,EAA6E,CAC7G,IAAI,EAAS,EAAO,cACpB,KAAO,GAAU,iBAAiB,CAAM,CAAC,CAAC,UAAY,YACpD,EAAS,EAAO,cAClB,OAAO,GAAQ,cAAgB,CAAE,SAAQ,KAAM,EAAO,aAAc,EAAI,IAAA,EAC1E,CAEA,SAAgB,GAAS,EAAsB,EAAW,EAAoE,CAC5H,IAAM,EAAW,CAAC,GAAG,EAAQ,iBAAoC,CAA0B,CAAC,EACtF,EAAQ,EAAS,UAAU,GAAU,EAAc,EAAO,sBAAsB,EAAG,EAAG,CAAC,GAAK,EAAO,sBAAsB,CAAC,CAAC,MAAQ,CAAC,EAC1I,OAAO,EAAQ,EAAI,IAAA,GAAY,CAAE,OAAQ,EAAS,GAAS,KAAM,EAAQ,CAAE,CAC7E,CAEA,SAAgB,GAAiB,EAAqB,EAAsC,CAC1F,GAAI,EAAK,OAAS,GAAK,EAAK,QAAU,EACpC,MAAU,MAAM,sBAAsB,EACxC,IAAM,EAAU,EAAc,EAAK,CAAI,EACvC,GAAI,CAAC,EACH,MAAU,MAAM,wBAAwB,EAC1C,MAAO,CAAE,MAAO,EAAQ,KAAO,EAAK,MAAQ,EAAK,MAAO,KAAM,EAAQ,IAAM,EAAK,KAAO,EAAK,OAAQ,MAAO,EAAQ,MAAQ,EAAK,MAAO,OAAQ,EAAQ,OAAS,EAAK,MAAO,CAC/K,CAGA,eAAsB,GAAkB,EAAgC,EAAc,EAAa,IAAuB,EAAiB,IAAyB,CAClK,IAAM,EAAS,EAAU,OACzB,GAAI,CAAC,GAAU,EAAO,OAAS,GAAK,EAAO,QAAU,EACnD,MAAU,MAAM,0BAA0B,EAC5C,IAAM,EAAU,EAAO,sBAAsB,EACvC,EAAS,EAAU,QAAU,GAAiB,EAAU,IAAK,CAAO,EACpE,EAAQ,EAAO,MAAQ,EAAO,MAC9B,EAAS,EAAO,OAAS,EAAO,OAChC,EAAQ,KAAK,IAAI,EAAG,KAAK,KAAK,GAAc,EAAQ,EAAO,EAAG,EAAiB,EAAO,EAAiB,CAAM,EACnH,GAAI,CAAC,OAAO,SAAS,CAAK,GAAK,GAAS,EACtC,MAAU,MAAM,0BAA0B,EAC5C,IAAM,EAAS,SAAS,cAAc,QAAQ,EAC9C,EAAO,MAAQ,KAAK,IAAI,EAAG,KAAK,MAAM,EAAQ,CAAK,CAAC,EACpD,EAAO,OAAS,KAAK,IAAI,EAAG,KAAK,MAAM,EAAS,CAAK,CAAC,EACtD,IAAM,EAAU,EAAO,WAAW,IAAI,EACtC,GAAI,CAAC,EACH,MAAU,MAAM,0BAA0B,EAC5C,EAAQ,UAAU,EAAQ,EAAO,KAAO,EAAO,MAAO,EAAO,IAAM,EAAO,OAAQ,EAAO,EAAQ,EAAG,EAAG,EAAO,MAAO,EAAO,MAAM,EAClI,IAAM,EAAO,MAAM,IAAI,SAAe,EAAS,IAAW,EAAO,OAAO,GAAS,EAAQ,EAAQ,CAAK,EAAI,EAAW,MAAM,0BAA0B,CAAC,EAAG,WAAW,CAAC,EACrK,OAAO,IAAI,KAAK,CAAC,CAAI,EAAG,EAAM,CAAE,KAAM,WAAY,CAAC,CACrD,CAEA,SAAS,EAAa,EAA2C,CAC/D,GAAI,OAAO,GAAU,WAAY,EAC/B,MAAO,GACT,IAAM,EAAO,EACP,GAAU,EAAgB,IAAyB,OAAO,GAAU,UAAY,EAAM,QAAU,EACtG,GAAI,CAAC,EAAO,EAAK,OAAA,GAA2B,GAAK,CAAC,EAAO,EAAK,SAAU,GAAI,GAAK,CAAC,EAAO,EAAK,KAAA,GAAyB,GAClH,CAAC,EAAO,EAAK,YAAA,GAAgC,GAAK,CAAE,EAAK,YAAuB,KAAK,GACpF,EAAK,OAAS,IAAA,KAAc,CAAC,OAAO,cAAc,EAAK,IAAI,GAAM,EAAK,KAAkB,IACxF,EAAK,YAAc,IAAA,IAAa,CAAC,EAAO,EAAK,UAAW,GAAI,EAChE,MAAO,GAET,GAAI,EAAK,SAAW,IAAA,GAAW,CAC7B,IAAM,EAAS,EAAK,OAGpB,GAFI,CAAC,GAAU,CAAC,CAAC,OAAQ,MAAO,QAAS,QAAQ,CAAC,CAAC,MAAM,GAAO,OAAO,EAAO,IAAS,UAAY,OAAO,SAAS,EAAO,EAAI,GAAM,EAAO,IAAmB,GAAM,EAAO,IAAmB,CAAC,GAE1L,EAAO,OAAoB,GAAM,EAAO,QAAqB,GAC5D,EAAO,KAAmB,EAAO,MAAmB,UAAa,EAAO,IAAkB,EAAO,OAAoB,SACzH,MAAO,EAEX,CACA,MAAO,EACT,CAGA,SAAgB,EAAqB,EAA4C,CAC/E,GAAI,CAAC,EAAM,QAAU,EAAM,OAAA,IAAiC,CAAC,EAAM,MAAM,CAAY,EACnF,MAAU,MAAM,oBAAoB,EACtC,IAAM,EAAU,KAAK,UAAU,CAAK,CAAC,CAAC,QAAQ,MAAO,SAAS,EAC9D,GAAI,EAAQ,OAAA,KACV,MAAU,MAAM,qBAAqB,EACvC,MAAO,GAAG,EAAgB,IAAI,EAAQ,IAAI,GAC5C,CAEA,MAAa,EAAmD,CAC9D,GAAI,EACJ,MAAO,GACP,MAAM,EAAM,EAAM,CAChB,IAAK,IAAI,EAAQ,EAAK,QAAQ,EAAiB,CAAI,EAAG,GAAS,EAAG,EAAQ,EAAK,QAAQ,EAAiB,EAAQ,EAAsB,EAAG,CACvI,IAAM,EAAM,EAAK,QAAQ,EAAkB,EAAQ,EAAsB,EACzE,GAAI,EAAM,EACR,OACF,IAAM,EAAU,EAAK,MAAM,EAAQ,GAAwB,CAAG,CAAC,CAAC,KAAK,EACjE,OAAQ,OAAA,MAEZ,GAAI,CACF,IAAM,EAAiB,KAAK,MAAM,CAAO,EACzC,GAAI,MAAM,QAAQ,CAAK,GAAK,EAAM,OAAS,GAAK,EAAM,QAAA,IAAkC,EAAM,MAAM,CAAY,EAC9G,MAAO,CAAE,GAAI,EAAiB,QAAO,IAAK,EAAM,GAAyB,KAAM,CAAE,OAAM,CAAE,CAC7F,MACM,CAAiE,CACzE,CAEF,CACF,EAGA,SAAgB,GAAgB,CAAE,QAAO,eAAc,SAAQ,SAAQ,iBAAgB,eAAsD,CAC3I,IAAM,EAAO,EAAqB,EAAM,IAAI,GAAQ,EAAK,UAAU,CAAC,EAC9D,EAAQ,EAAM,QAAQ,GAAQ,EAAK,KAAO,CAAC,EAAK,IAAI,EAAI,CAAC,CAAC,EAChE,GAAI,EAAM,QAAU,CAAC,EACnB,MAAU,MAAM,8BAA8B,EAChD,GAAI,EAAM,QAAU,IACd,EAAM,KAAK,GAAQ,CAAC,EAAO,WAAW,SAAS,EAAK,IAAI,GAAK,EAAK,KAAO,EAAO,aAAa,GAC5F,EAAe,OAAS,EAAM,OAAS,EAAO,qBAC9C,CAAC,GAAG,EAAgB,GAAG,CAAK,CAAC,CAAC,QAAQ,EAAK,IAAS,EAAM,EAAK,KAAM,CAAC,EAAI,EAAO,sBACpF,MAAU,MAAM,uBAAuB,EAG3C,IAAM,EAAO,EAAa,iBAAiB,EACrC,EAAS,EAAM,OAAS,EAAQ,OAAO,CAAK,EAAI,CAAC,EACvD,GAAI,EAAO,QAAU,CAAC,EAAa,eAAe,EAAO,IAAI,GAAQ,EAAK,EAAE,CAAC,EAE3E,MADA,EAAQ,QAAQ,CAAM,EACZ,MAAM,uBAAuB,EAEzC,GAAI,CAAC,EAAa,WAAW,KAAK,EAAK,IAAK,CAAE,GAAG,EAAM,MAAO,EAAK,GAAI,CAAC,EAAG,CACzE,IAAK,IAAM,KAAS,EAClB,EAAa,iBAAiB,EAAM,EAAE,EAExC,MADA,GAAQ,QAAQ,CAAM,EACZ,MAAM,uBAAuB,CACzC,CACA,GAAI,CAKF,OAJA,EAAa,aAAa,EACtB,EACK,SACT,EAAa,OAAO,EACb,OACT,MACM,CAEJ,MAAO,OACT,CACF,CC1OA,SAAgB,EAAoB,CAAE,OAAM,cAAa,iBAAgB,KAA0B,CACjG,IAAM,GAAA,EAAA,EAAA,MAAA,CAAgB,EAChB,GAAA,EAAA,EAAA,OAAA,CAAiC,IAAI,EACrC,GAAA,EAAA,EAAA,OAAA,CAAgC,IAAI,EACpC,CAAC,EAAM,IAAA,EAAA,EAAA,SAAA,CAAoB,EAAK,EAChC,EAAQ,EAAa,EAAE,kBAAkB,EAAG,CAAE,MAAO,OAAO,EAAK,KAAK,MAAM,MAAM,CAAE,CAAC,EAqC3F,OAnCA,EAAA,EAAA,gBAAA,KAAsB,CACpB,IAAM,EAAU,EAAM,QAChB,EAAU,EAAO,QACvB,GAAI,CAAC,GAAW,CAAC,EACf,OACF,GAAI,CAAC,EAAM,CACT,EAAQ,cAAc,EACtB,MACF,CACA,EAAQ,cAAc,EACtB,IAAM,MAAuB,CAC3B,IAAM,EAAW,CAAE,MAAO,SAAS,gBAAgB,YAAa,OAAQ,OAAO,WAAY,EACrF,CAAE,OAAM,OAAQ,EAA0B,EAAQ,sBAAsB,EAAG,EAAQ,sBAAsB,EAAG,CAAQ,EAC1H,EAAQ,MAAM,KAAO,GAAG,EAAK,IAC7B,EAAQ,MAAM,IAAM,GAAG,EAAI,GAC7B,EACM,EAAU,GAAuB,CACjC,EAAM,kBAAkB,MAAQ,EAAQ,SAAS,EAAM,MAAM,GAEjE,EAAQ,EAAK,CACf,EACM,EAAS,IAAI,eAAe,CAAQ,EAM1C,OALA,EAAO,QAAQ,CAAO,EACtB,EAAO,QAAQ,CAAO,EACtB,OAAO,iBAAiB,SAAU,CAAQ,EAC1C,SAAS,iBAAiB,SAAU,EAAQ,EAAI,EAChD,EAAS,MACI,CACX,EAAQ,cAAc,EACtB,EAAO,WAAW,EAClB,OAAO,oBAAoB,SAAU,CAAQ,EAC7C,SAAS,oBAAoB,SAAU,EAAQ,EAAI,CACrD,CACF,EAAG,CAAC,CAAI,CAAC,GAGP,EAAA,EAAA,KAAA,CAAC,OAAD,CACE,IAAK,EACL,UAAU,kCACV,mBAAsB,EAAQ,EAAI,EAClC,eAAiB,GAAU,EACrB,EAAE,EAAM,yBAAyB,OAAS,CAAC,EAAM,cAAc,SAAS,EAAM,aAAa,IAC7F,EAAQ,EAAK,CACjB,EACA,YAAe,EAAQ,EAAI,EAC3B,OAAS,GAAU,CACZ,EAAM,cAAc,SAAS,EAAM,aAAa,GACnD,EAAQ,EAAK,CACjB,EACA,UAAY,GAAU,CAChB,EAAM,MAAQ,WAChB,EAAM,eAAe,EACrB,EAAM,gBAAgB,EAClB,EAAM,SAAS,SAAS,EAAM,MAAc,GAC9C,EAAO,SAAS,cAAc,QAAQ,CAAC,EAAE,MAAM,EACjD,EAAQ,EAAK,EAEjB,EArBF,SAAA,EAuBE,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,KAAK,SAAS,GAAI,GAAG,EAAQ,UAAW,gBAAc,SAAS,gBAAe,EAAS,gBAAe,EAAO,SAAA,CAAc,CAAA,GACnI,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,IAAK,EAAa,QAAS,SAAY,UAAU,gCAAgC,YAAW,EAAM,GAAI,EAAS,KAAK,SAAS,kBAAiB,GAAG,EAAQ,UAC7J,UAAA,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,6BACb,SAAA,EAAK,KAAK,MAAM,KAAK,EAAM,KAC1B,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAU,6BAAhB,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,+BACb,SAAA,GACG,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,KAAK,SAAS,YAAe,EAAe,EAAK,MAAM,EAAG,MAAO,EAAK,OAAS,SAAA,EAAK,QAAiB,CAAA,GAC7G,EAAA,EAAA,IAAA,CAAC,OAAD,CAAA,SAAO,EAAK,QAAe,CAAA,CAC3B,CAAA,GACN,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,oCAAqC,SAAA,EAAK,WAAkB,CAAA,CACxE,CAP4C,EAAA,CAO5C,CACP,CACG,CAAA,CACF,CAAA,CACF,GAEV,CCnFA,SAAgB,EAAmB,EAAmC,CAGpE,MAFK,qBAAqB,KAAK,EAAM,YAAY,GAE1C,EAAA,EAAA,IAAA,CAAC,EAAD,CAAyC,GAAI,CAAQ,EAAhC,EAAM,YAA0B,EADnD,IAEX,CAEA,SAAS,EAAe,CAAE,eAAc,qBAAoB,SAAQ,eAAc,WAAU,gBAAe,KAA0B,CACnI,IAAM,GAAA,EAAA,EAAA,OAAA,CAAiC,IAAI,EACrC,GAAA,EAAA,EAAA,OAAA,CAA+B,IAAI,EACnC,GAAA,EAAA,EAAA,OAAA,CAAiC,IAAI,EACrC,GAAA,EAAA,EAAA,OAAA,CAA8B,EAC9B,CAAC,EAAQ,IAAA,EAAA,EAAA,SAAA,CAAsC,EAC/C,CAAC,EAAQ,IAAA,EAAA,EAAA,SAAA,CAAsB,EAAK,EACpC,CAAC,EAAO,IAAA,EAAA,EAAA,SAAA,CAA0C,EAClD,CAAC,EAAW,IAAA,EAAA,EAAA,SAAA,CAA8C,EAC1D,CAAC,EAAa,IAAA,EAAA,EAAA,SAAA,CAA2B,EAAE,EAC3C,CAAC,EAAO,IAAA,EAAA,EAAA,SAAA,CAA2B,EACnC,CAAC,EAAW,IAAA,EAAA,EAAA,SAAA,CAAyB,EAAK,EAC1C,CAAC,EAAU,IAAA,EAAA,EAAA,SAAA,CAAwB,EAAK,EACxC,CAAC,EAAO,IAAA,EAAA,EAAA,SAAA,KAAyD,EAAmB,IAAI,CAAY,GAAK,CAAC,CAAC,EAC3G,CAAC,GAAkB,IAAA,EAAA,EAAA,SAAA,CAAgC,EAAK,EACxD,GAAA,EAAA,EAAA,MAAA,CAAkB,EAClB,CAAC,EAAO,IAAA,EAAA,EAAA,SAAA,CAAqB,EAAE,EAC/B,EAAQ,EAAS,GAAS,CAAK,EAC/B,EAAS,EAAc,aAAa,EACpC,EAAQ,WAAW,KAAK,CAAY,EACpC,EAAW,EAAa,QAAQ,OAAQ,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,GAAK,EACjE,GAAA,EAAA,EAAA,OAAA,CAAkB,CAAC,EACnB,GAAA,EAAA,EAAA,OAAA,CAA6C,EAC7C,GAAA,EAAA,EAAA,OAAA,CAAmI,EACnI,GAAA,EAAA,EAAA,OAAA,CAAoH,EACpH,GAAW,EAAM,QAAU,SAEjC,EAAA,EAAA,UAAA,KAAgB,CACV,EAAM,OACR,EAAmB,IAAI,EAAc,CAAK,EAE1C,EAAmB,OAAO,CAAY,CAC1C,EAAG,CAAC,EAAc,EAAO,CAAkB,CAAC,EAE5C,SAAS,GAAgB,CACvB,EAAS,UACT,EAAa,IAAA,EAAS,EACtB,EAAS,IAAA,EAAS,EAClB,EAAa,EAAK,EAClB,EAAe,EAAE,CACnB,CAEA,SAAS,GAAsB,CAC7B,aAAa,EAAK,OAAO,EACzB,EAAQ,QAAU,IAAA,GAClB,EAAY,EAAK,EACjB,EAAS,IAAA,EAAS,CACpB,EAEA,EAAA,EAAA,UAAA,KAAgB,CACd,IAAM,EAAO,EAAO,QACd,EAAY,GAAQ,GAAkB,CAAI,EAChD,GAAI,CAAC,EACH,OACF,GAAM,CAAE,SAAQ,QAAS,EACzB,EAAQ,QAAU,EAClB,IAAI,EAAQ,EACN,MAAsB,CAC1B,qBAAqB,CAAK,EAC1B,EAAQ,0BAA4B,CAClC,EAAM,QAAU,IAAA,GAChB,IAAM,EAAO,EAAK,sBAAsB,EAClC,EAAM,KAAK,IAAI,EAAK,IAAK,EAAO,sBAAsB,CAAC,CAAC,OAAQ,CAAC,EACjE,EAAS,KAAK,IAAI,EAAK,OAAQ,OAAO,WAAW,EACjD,EAAO,KAAK,IAAI,EAAG,EAAK,IAAI,EAC5B,EAAQ,KAAK,IAAI,EAAK,MAAO,OAAO,UAAU,EAC9C,EAAS,CAAC,GAAG,EAAK,iBAAoC,CAA0B,CAAC,CAAC,CAAC,KAAK,GAAU,EAAO,sBAAsB,CAAC,CAAC,MAAQ,CAAC,EAC1I,EAAU,EAAK,aAAe,CAAC,EAAK,QAAQ,gCAAgC,GAAK,iBAAiB,CAAI,CAAC,CAAC,aAAe,UAC7H,EAAU,GAAW,EAAK,OAAS,IAAM,GAAU,EAAQ,GAAQ,EAAS,EACxE,CAAE,OAAM,MAAK,MAAO,EAAQ,EAAM,OAAQ,EAAS,CAAI,EACvD,IAAA,EAAS,EAEb,EAAc,GAAa,CACzB,GAAI,CAAC,GAAU,QAAU,CAAC,EAAS,OACjC,OAAO,EACT,IAAM,EAAO,EAAS,OAAO,sBAAsB,EAC7C,EAAS,EAAS,OAClB,EAAM,CAAE,KAAM,EAAK,KAAO,EAAO,KAAO,EAAK,MAAO,IAAK,EAAK,IAAM,EAAO,IAAM,EAAK,OAAQ,MAAO,EAAO,MAAQ,EAAK,MAAO,OAAQ,EAAO,OAAS,EAAK,MAAO,EAC1K,OAAO,OAAO,KAAK,CAAG,CAAC,CAAC,MAAM,GAAO,EAAI,KAAiC,EAAS,IAAI,EAA4B,EAAI,EAAW,CAAE,GAAG,EAAU,KAAI,CACvJ,CAAC,CACH,CAAC,CACH,EACM,EAAS,IAAI,eAAe,CAAO,EACzC,EAAO,QAAQ,CAAI,EACnB,IAAM,EAAW,IAAI,iBAAkB,GAAY,CAC7C,EAAQ,KAAK,GAAU,CAAC,EAAK,SAAS,EAAO,MAAM,CAAC,GACtD,EAAQ,CACZ,CAAC,EACD,EAAS,QAAQ,EAAM,CAAE,UAAW,GAAM,QAAS,GAAM,WAAY,GAAM,gBAAiB,CAAC,SAAU,cAAe,QAAS,OAAO,CAAE,CAAC,EACzI,IAAK,IAAI,EAAS,EAAK,cAAe,EAAQ,EAAS,EAAO,cAC5D,EAAS,QAAQ,EAAQ,CAAE,WAAY,EAAK,CAAC,EAK/C,OAJA,OAAO,iBAAiB,SAAU,CAAO,EACzC,EAAK,iBAAiB,gBAAiB,CAAO,EAC9C,EAAK,iBAAiB,SAAU,EAAS,EAAI,EAC7C,EAAQ,MACK,CACX,EAAS,UACT,aAAa,EAAK,OAAO,EACzB,qBAAqB,CAAK,EAC1B,EAAO,WAAW,EAClB,EAAS,WAAW,EACpB,OAAO,oBAAoB,SAAU,CAAO,EAC5C,EAAK,oBAAoB,gBAAiB,CAAO,EACjD,EAAK,oBAAoB,SAAU,EAAS,EAAI,EAChD,EAAQ,QAAU,IAAA,EACpB,CACF,EAAG,CAAC,CAAC,GAEL,EAAA,EAAA,UAAA,KAAgB,CACd,GAAI,CAAC,EACH,OACF,IAAM,EAAkB,GAAyC,CAC3D,EAAM,kBAAkB,MAAQ,CAAC,EAAK,SAAS,SAAS,EAAM,MAAM,GACtE,EAAQ,CACZ,EAGA,OAFA,SAAS,iBAAiB,cAAe,EAAgB,EAAI,EAC7D,EAAK,SAAS,cAAc,OAAO,CAAC,EAAE,MAAM,MAC/B,CACX,SAAS,oBAAoB,cAAe,EAAgB,EAAI,CAClE,CACF,EAAG,CAAC,CAAS,CAAC,GAEd,EAAA,EAAA,UAAA,KAAgB,CACV,GACF,EAAQ,SAAS,MAAM,CAC3B,EAAG,CAAC,CAAM,CAAC,EAEX,SAAS,GAAc,EAAW,EAAiB,CACjD,IAAM,EAAO,EAAQ,QACrB,GAAI,CAAC,EACH,OACF,IAAI,EAAS,EAAK,cAAc,CAA0B,CAAC,EAAE,cAC7D,KAAO,GAAU,IAAW,GAAQ,CAAC,eAAe,KAAK,iBAAiB,CAAM,CAAC,CAAC,SAAS,GACzF,EAAS,EAAO,cAClB,GAAQ,SAAS,CAAE,KAAM,EAAG,IAAK,CAAE,CAAC,EACpC,EAAS,IAAA,EAAS,CACpB,EAEA,EAAA,EAAA,UAAA,KAAgB,CACd,IAAM,EAAO,EAAQ,QACrB,GAAI,CAAC,GAAU,CAAC,GAAQ,CAAC,EACvB,OACF,IAAM,EAAS,GAA4B,CACzC,EAAM,eAAe,EACrB,IAAM,EAAO,EAAM,YAAc,EAAI,GAAK,EAAM,YAAc,EAAI,EAAO,OAAS,EAClF,GAAc,EAAM,OAAS,EAAM,EAAM,OAAS,CAAI,CACxD,EAEA,OADA,EAAK,iBAAiB,QAAS,EAAO,CAAE,QAAS,EAAM,CAAC,MAC3C,EAAK,oBAAoB,QAAS,CAAK,CACtD,EAAG,CAAC,EAAQ,CAAM,CAAC,EAEnB,SAAS,GAAY,EAAW,EAA4C,CAC1E,GAAI,CAAC,EAAQ,QACX,OACF,IAAM,EAAO,GAAS,EAAQ,QAAS,EAAG,CAAC,EAC3C,GAAI,CAAC,EACH,OACF,IAAM,EAAM,EAAK,OAAO,sBAAsB,GAC1C,EAAM,SAAS,SAAW,EAAK,QAAU,EAAM,QAAQ,IAAI,OAAS,EAAI,MAAQ,EAAM,QAAQ,IAAI,MAAQ,EAAI,KAC7G,EAAM,QAAQ,IAAI,QAAU,EAAI,OAAS,EAAM,QAAQ,IAAI,SAAW,EAAI,UAC7E,EAAM,QAAU,CAAE,OAAQ,EAAK,OAAQ,MAAK,WAAY,EAAiB,EAAK,MAAM,CAAE,GAExF,IAAM,EAAY,GAAiB,EAAM,QAAQ,WAAY,EAAG,CAAC,EACjE,OAAO,EAAY,CAAE,GAAG,EAAW,GAAG,CAAK,EAAI,IAAA,EACjD,CAEA,SAAS,EAAgB,EAAW,EAA4C,CAC9E,IAAM,EAAQ,EAAQ,QACtB,GAAI,CAAC,EACH,OACF,IAAM,EAAM,EAAc,CAAE,KAAM,KAAK,IAAI,EAAM,EAAG,CAAC,EAAG,IAAK,KAAK,IAAI,EAAM,EAAG,CAAC,EAAG,MAAO,KAAK,IAAI,EAAI,EAAM,CAAC,EAAG,OAAQ,KAAK,IAAI,EAAI,EAAM,CAAC,CAAE,EAAG,EAAM,OAAO,sBAAsB,CAAC,EACtL,GAAI,CAAC,EACH,OACF,IAAM,EAAa,EAAM,SAAS,SAAW,EAAM,OAAS,EAAM,QAAQ,WAAa,EAAiB,EAAM,MAAM,EACpH,MAAO,CAAE,OAAQ,EAAM,OAAQ,KAAM,EAAM,KAAM,MAAK,OAAQ,GAAiB,EAAK,EAAM,OAAO,sBAAsB,CAAC,EAAG,KAAM,EAAW,OAAO,IAAS,EAAK,OAAS,CAAC,EAAK,GAAG,EAAA,CAAG,KAAK,GAAQ,EAAc,EAAM,CAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAQ,EAAK,IAAI,CAAC,CAAC,KAAK;CAAI,CAAC,CAAC,MAAM,EAAG,CAAmB,CAAE,CAChS,CAEA,SAAS,GAAY,EAA2C,CAC9D,GAAI,EAAM,SAAW,GAAK,CAAC,EAAQ,SAAY,GAAS,CAAC,EACvD,OACF,IAAM,EAAO,GAAS,EAAQ,QAAS,EAAM,QAAS,EAAM,OAAO,EACnE,GAAI,CAAC,EACH,OACF,EAAM,eAAe,EACrB,EAAQ,EACR,IAAM,EAAQ,CAAE,GAAG,EAAM,EAAG,EAAM,QAAS,EAAG,EAAM,QAAS,MAAO,EAAM,QAAS,MAAO,EAAM,QAAS,OAAQ,EAAM,EACvH,EAAQ,QAAU,EAClB,EAAM,cAAc,kBAAkB,EAAM,SAAS,EACrD,EAAK,QAAU,eAAiB,CAC1B,EAAQ,UAAY,IAExB,EAAM,OAAS,GACf,EAAY,EAAI,EAChB,EAAS,EAAgB,EAAM,MAAO,EAAM,KAAK,CAAC,EACpD,EAAA,GAAqB,CACvB,CAEA,SAAS,GAAY,EAA2C,CAC9D,IAAM,EAAQ,EAAQ,QAClB,IACF,EAAM,MAAQ,EAAM,QACpB,EAAM,MAAQ,EAAM,QAChB,CAAC,EAAM,QAAU,KAAK,MAAM,EAAM,QAAU,EAAM,EAAG,EAAM,QAAU,EAAM,CAAC,GAAA,IAC9E,aAAa,EAAK,OAAO,EACzB,EAAM,OAAS,GACf,EAAY,EAAI,IAGpB,EAAS,GAAO,OAAS,EAAgB,EAAM,QAAS,EAAM,OAAO,EAAI,GAAY,EAAM,QAAS,EAAM,OAAO,CAAC,CACpH,CAEA,eAAe,GAAc,EAA2C,CACtE,EAAQ,EACR,IAAM,EAAU,EAAS,QACzB,EAAS,EAAE,EACX,IAAM,EAAO,EAAM,QAAQ,sBAAsB,EAC3C,EAAM,EAAO,EAAW,EAAM,IAAK,CAAI,EAAI,EAAM,IACvD,GAAI,CAAC,EACH,OACF,IAAM,EAAS,EAAO,GAAiB,EAAK,CAAI,EAAI,EAAM,OACpD,EAAS,CAAE,GAAG,EAAO,MAAK,QAAO,EACvC,KAAa,CAAM,EACd,EAEL,GAAa,EAAI,EACjB,GAAI,CACF,IAAM,EAAO,MAAM,GAAkB,EAAQ,GAAG,EAAS,IAAI,EAAM,KAAK,GAAG,KAAK,IAAI,EAAE,MAAO,GAAQ,eAAgB,GAAQ,iBAAiB,EAC1I,EAAS,UAAY,GACvB,EAAS,CAAI,CACjB,MACM,CACA,EAAS,UAAY,GACvB,EAAS,EAAE,0BAA0B,CAAC,CAC1C,QACQ,CACF,EAAS,UAAY,GACvB,EAAa,EAAK,CACtB,CAbiB,CAcnB,CAEA,SAAS,GAAU,EAA2C,CAC5D,IAAM,EAAQ,EAAQ,QAEtB,GADA,aAAa,EAAK,OAAO,EACrB,CAAC,EACH,OACF,IAAM,EAAQ,EAAM,OAAS,EAAgB,EAAM,QAAS,EAAM,OAAO,EAAI,GAAY,EAAM,QAAS,EAAM,OAAO,EAC/G,EAAQ,KAAK,MAAM,EAAM,QAAU,EAAM,EAAG,EAAM,QAAU,EAAM,CAAC,EACzE,EAAc,EACV,IAAU,EAAM,OAAS,EAAM,IAAI,OAAA,GAAkC,EAAM,IAAI,QAAA,EAAkC,EAAA,IACnH,GAAmB,CAAK,CAC5B,CAEA,SAAS,IAAY,CACnB,GAAI,CAAC,GAAa,CAAC,EAAY,KAAK,GAAM,GAAS,CAAC,GAAU,EAAM,QAAA,GAClE,OACF,IAAM,EAAa,CACjB,OAAQ,EACR,WACA,KAAM,EAAU,KAChB,KAAM,EAAU,KAAK,MAAM,EAAG,CAAmB,EACjD,YAAa,EAAY,KAAK,EAC9B,OAAQ,EAAU,OAClB,UAAW,GAAO,IACpB,EACA,EAAS,GAAY,CAAC,GAAG,EAAU,CAAE,aAAY,KAAM,CAAM,CAAC,CAAC,EAC/D,EAAQ,CACV,CAEA,SAAS,IAAa,CAChB,OAEJ,GAAI,CACF,IAAM,EAAS,GAAgB,CAC7B,QACA,eACA,SACA,SACA,eAAgB,GAAQ,OAAO,EAAM,aAAa,GAAK,CAAC,EACxD,YAAa,CAAC,CAAC,EAAM,MAAM,KAAK,GAAK,EAAM,cAAc,OAAS,CACpE,CAAC,EACD,EAAS,CAAC,CAAC,EACX,EAAoB,EAAK,EACzB,EAAU,EAAK,EACf,EAAQ,EACR,EAAS,IAAW,QAAU,EAAE,uBAAuB,EAAI,EAAE,CAC/D,OACO,EAAO,CACZ,IAAM,EAAM,aAAiB,MAAQ,EAAM,QAAU,wBACrD,EAAS,EAAE,EAAI,WAAW,aAAa,EAAI,EAAM,uBAAuB,CAAC,CAC3E,CACF,CAEA,IAAM,EAAY,GAAa,EACzB,GAAe,GAAa,CAAC,GAAa,CAAC,GAAY,EAAU,OACnE,EAAW,EAAU,IAAK,EAAU,OAAO,sBAAsB,CAAC,EAClE,GAAW,IACT,EAAmB,IAAgB,EAAS,EAAc,GAAc,CAAM,EAAI,IAAA,GAClF,GAAY,EAAS,KAAK,IAAI,IAAK,EAAO,MAAQ,EAAE,EAAI,EACxD,GAAW,GAAU,EAAY,KAAK,IAAI,EAAO,KAAO,EAAG,KAAK,IAAI,EAAU,IAAI,KAAM,EAAO,KAAO,EAAO,MAAQ,GAAY,CAAC,CAAC,EAAI,EACvI,GAAU,GAAU,EAAY,KAAK,IAAI,EAAO,IAAM,EAAG,KAAK,IAAI,EAAU,IAAI,IAAM,EAAU,IAAI,OAAS,EAAG,EAAO,IAAM,EAAO,OAAS,EAAE,CAAC,EAAI,EAE1J,OACE,EAAA,EAAA,KAAA,CAAC,OAAD,CACE,IAAK,EACL,UAAU,sBACV,UAAY,GAAU,CACpB,GAAI,CAAC,GAAU,EAAM,MAAQ,SAC3B,OACF,EAAM,eAAe,EACrB,EAAM,gBAAgB,EACtB,IAAM,EAAe,CAAC,CAAC,GAAa,CAAC,CAAC,EAAQ,QAC9C,EAAQ,EACR,EAAc,EACV,EACF,EAAQ,SAAS,MAAM,GAGvB,EAAU,EAAK,EACf,EAAO,SAAS,cAAc,QAAQ,CAAC,EAAE,MAAM,EAEnD,EAlBF,SAAA,EAoBE,EAAA,EAAA,IAAA,CAAC,SAAD,CACE,KAAK,SACL,UAAU,6BACV,eAAc,EACd,SAAU,CAAC,GAAW,GAAS,CAAC,EAChC,MAA0B,EAAnB,GAAS,CAAC,EAAW,+BAAmC,EAAyC,kBAA9B,wBAA+C,EACzH,YAAe,CACb,EAAU,GAAS,CAAC,CAAK,EACzB,EAAQ,EACR,EAAc,CAChB,EAEC,SAAA,EAAE,gBAAgB,CACb,CAAA,EACP,GAAS,CAAC,IAAU,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,KAAK,SAAS,UAAU,kCAAmC,SAAA,EAAE,8BAA8B,CAAQ,CAAA,EAC7H,GAAU,IACT,EAAA,EAAA,IAAA,CAAC,MAAD,CACE,IAAK,EACL,UAAU,8BACV,SAAU,EACV,MAAO,CAAE,KAAM,EAAO,KAAM,IAAK,EAAO,IAAK,MAAO,EAAO,MAAO,OAAQ,EAAO,MAAO,EACxF,KAAK,SACL,aAAY,EAAE,iBAAiB,EAC/B,cAAe,GACf,cAAe,GACf,YAAa,GACb,gBAAiB,EACjB,qBAAsB,EACtB,UAAY,GAAU,CACpB,GAAI,EAAM,MAAQ,YAAc,EAAM,MAAQ,SAC5C,EAAM,eAAe,EACrB,GAAc,EAAG,EAAO,QAAU,EAAM,MAAQ,WAAa,GAAM,IAAK,OAErE,GAAI,EAAM,MAAQ,aAAe,EAAM,MAAQ,UAAW,CAC7D,EAAM,eAAe,EACrB,IAAM,EAAa,CAAC,GAAG,EAAQ,QAAS,iBAAA,gCAA8D,CAAC,CAAC,CAAC,SAAS,EAAQ,IAAU,EAAiB,CAAM,CAAC,CAAC,OAAO,GAAQ,EAAc,EAAK,IAAK,CAAM,CAAC,CAAC,CAAC,IAAI,IAAS,CAAE,GAAG,EAAM,SAAQ,KAAM,EAAQ,CAAE,EAAE,CAAC,EAC1P,EAAU,EAAW,UAAU,GAAQ,EAAK,SAAW,GAAO,QAAU,EAAK,OAAS,EAAM,MAAQ,EAAK,IAAI,MAAQ,EAAM,IAAI,GAAG,EAClI,EAAQ,EAAU,EAAK,EAAM,MAAQ,YAAc,EAAI,EAAW,OAAS,EAAK,KAAK,IAAI,EAAG,KAAK,IAAI,EAAW,OAAS,EAAG,GAAW,EAAM,MAAQ,YAAc,EAAI,GAAG,CAAC,EACjL,EAAS,EAAW,EAAM,CAC5B,MACU,EAAM,MAAQ,SAAW,EAAM,MAAQ,MAAQ,IACvD,EAAM,eAAe,EACrB,GAAmB,CAAK,EAE5B,EACA,mBAAsB,CACf,EAAQ,SACX,EAAS,IAAA,EAAS,CACtB,CACD,CAAA,EAEF,GAAU,IACT,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,gCAAgC,gBAAe,GAAa,EAAW,OAAS,IAAA,GAAW,MAAO,CAAE,KAAM,EAAiB,KAAM,IAAK,EAAiB,IAAK,MAAO,EAAiB,MAAO,OAAQ,EAAiB,MAAO,CAAI,CAAA,EAEhP,GAAU,GAAa,IACtB,EAAA,EAAA,KAAA,CAAC,OAAD,CACE,IAAK,EACL,UAAU,+BACV,MAAO,CAAE,KAAM,GAAU,IAAK,GAAS,MAAO,EAAU,EACxD,aAAY,EAAE,gBAAgB,EAC9B,YAAW,EACX,SAAW,GAAU,CACnB,EAAM,eAAe,EACrB,GAAI,CACN,EATF,SAAA,EAWE,EAAA,EAAA,IAAA,CAAC,QAAD,CACE,KAAK,OACL,aAAY,EAAE,wBAAwB,EACtC,YAAa,EAAE,wBAAwB,EACvC,MAAO,EACP,UAAA,IACA,SAAU,GAAS,EAAe,EAAM,OAAO,KAAK,EACpD,UAAY,GAAU,CAChB,EAAM,MAAQ,SAAW,EAAM,YAAY,aAC7C,EAAM,eAAe,CACzB,CACD,CAAA,GACD,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,KAAK,SAAS,aAAY,EAAE,EAAY,uBAAyB,gBAAgB,EAAG,MAAO,EAAE,EAAY,uBAAyB,gBAAgB,EAAG,SAAU,CAAC,EAAY,KAAK,GAAK,GAAc,GAAS,CAAC,GAAU,EAAM,QAAA,GACpO,UAAA,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,KAAK,OAAO,cAAY,OAAO,UAAA,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,EAAE,iBAAiB,OAAO,eAAe,YAAY,IAAI,cAAc,QAAQ,eAAe,OAAS,CAAA,CAAM,CAAA,CAC5L,CAAA,CACJ,KAEN,GAAU,EAAM,OAAS,GAAK,IAAU,IACxC,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,oCAAoC,MAAO,CAAE,KAAQ,EAAO,KAAM,MAAS,EAAO,MAAO,OAAU,KAAK,IAAI,EAAG,OAAO,YAAc,EAAO,IAAM,EAAO,MAAM,EAAI,GAAI,gCAAiC,GAAG,EAAO,MAAM,IAAK,iCAAkC,GAAG,EAAO,OAAO,GAAI,EAChS,UAAA,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,2BAAf,SAAA,CACG,IAAS,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,KAAK,QAAS,SAAA,CAAS,CAAA,GACpC,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,mCAAf,SAAA,EACE,EAAA,EAAA,KAAA,CAAC,MAAD,CACE,UAAU,8BACV,iBAAgB,GAAmB,OAAS,IAAA,GAC5C,mBAAsB,EAAoB,EAAK,EAC/C,YAAe,EAAoB,EAAK,EACxC,UAAY,GAAU,CAChB,EAAM,MAAQ,WAChB,EAAM,gBAAgB,EACtB,EAAM,cAAc,cAAc,QAAQ,CAAC,EAAE,MAAM,EACnD,EAAoB,EAAI,EAE5B,EAXF,SAAA,EAaE,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,KAAK,SAAS,gBAAc,SAAS,gBAAe,EAAW,SAAU,CAAC,EAAM,OAAS,SAAA,EAAa,EAAE,kBAAkB,EAAG,CAAE,MAAO,OAAO,EAAM,MAAM,CAAE,CAAC,CAAU,CAAA,EAC7K,EAAM,OAAS,IACd,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,GAAI,EAAW,KAAK,SAAS,aAAY,EAAa,EAAE,kBAAkB,EAAG,CAAE,MAAO,OAAO,EAAM,MAAM,CAAE,CAAC,EAAG,UAAU,8BAC5H,UAAA,EAAA,EAAA,IAAA,CAAC,KAAD,CAAA,SACG,EAAM,KAAK,EAAM,KAChB,EAAA,EAAA,IAAA,CAAC,KAAD,CAAA,UACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAU,+BAAhB,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,MAAO,EAAK,WAAW,OAAS,SAAA,EAAK,WAAW,QAAe,CAAA,EACpE,EAAK,WAAW,OAAQ,EAAA,EAAA,IAAA,CAAC,OAAD,CAAA,SAAO,EAAa,EAAE,iBAAiB,EAAG,CAAE,KAAM,OAAO,EAAK,WAAW,IAAI,CAAE,CAAC,CAAQ,CAAA,CAC7G,IACL,EAAK,WAAW,OAAQ,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,iCAAkC,SAAA,EAAK,WAAW,IAAW,CAAA,GACtG,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,oCAAoC,MAAO,EAAK,WAAW,YAAc,SAAA,EAAK,WAAW,WAAkB,CAAA,CACxH,CAAA,CAAA,CACH,EATK,EAAK,WAAW,WAAa,CASlC,CACL,CACC,CAAA,CACD,CAAA,CAEJ,KACL,EAAA,EAAA,IAAA,CAAC,SAAD,CACE,KAAK,SACL,YAAe,CACb,EAAS,CAAC,CAAC,EACX,EAAU,EAAK,EACf,EAAoB,EAAK,EACzB,EAAS,EAAE,EACX,EAAQ,EACR,EAAc,CAChB,EAEC,SAAA,EAAE,mBAAmB,CAChB,CAAA,GACR,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,KAAK,SAAS,UAAU,8BAA8B,SAAU,CAAC,EAAM,QAAU,GAAU,QAAS,GAAO,SAAA,EAAE,iBAAiB,CAAU,CAAA,CAC7I,CACF,CAAA,CAAA,GACF,CAAA,CAEH,GAEV,CCvdA,SAAS,EAAM,EAAiD,CAC9D,GAAM,CAAE,OAAO,GAAI,GAAG,GAAS,EAC/B,MAAO,CACL,MAAS,EACT,OAAU,EACV,QAAW,YACX,KAAQ,OACR,cAAe,GACf,GAAG,CACL,CACF,CAGA,SAAgB,EAAc,EAAsC,CAClE,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,GAAI,EAAM,CAAK,EAClB,UAAA,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,KAAK,eACL,SAAS,UACT,SAAS,UACT,EAAE,0XACH,CAAA,CACE,CAAA,CAET,CAGA,SAAgB,EAAQ,EAAsC,CAC5D,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,GAAI,EAAM,CAAK,EAClB,UAAA,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,KAAK,eACL,SAAS,UACT,SAAS,UACT,EAAE,qWACH,CAAA,CACE,CAAA,CAET,CAGA,SAAgB,EAAkB,EAAsC,CACtE,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,GAAI,EAAM,CAAK,EAClB,UAAA,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,KAAK,eACL,SAAS,UACT,SAAS,UACT,EAAE,0OACH,CAAA,CACE,CAAA,CAET,CAGA,SAAgB,EAAiB,EAAsC,CACrE,OACE,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,GAAI,EAAM,CAAK,EAClB,UAAA,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,KAAK,eACL,SAAS,UACT,SAAS,UACT,EAAE,8TACH,CAAA,CACE,CAAA,CAET,CAEA,MAAa,EAAkF,CAC7F,UAAW,EACX,IAAK,EACL,cAAe,EACf,aAAc,CAChB,EC1EA,SAAgB,GAAgB,CAAE,OAAM,MAAK,cAAa,aAAY,eAAoC,CACxG,IAAM,EAAU,EAAY,EAAK,KAAK,OAAO,EAC7C,GAAI,GAAW,KACb,OAAO,EAAA,EAAA,IAAA,CAAC,OAAD,CAAA,SAAO,CAAU,CAAA,EAE1B,IAAM,EAAO,EAAa,EAAQ,IAC5B,GACJ,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,EAAD,CAAM,UAAU,sBAAsB,KAAM,EAAK,CAAA,GACjD,EAAA,EAAA,IAAA,CAAC,OAAD,CAAA,SAAO,EAAY,EAAQ,EAAE,CAAQ,CAAA,CACrC,CAAA,CAAA,EAWJ,OARK,GASH,EAAA,EAAA,IAAA,CAAC,SAAD,CACE,KAAK,SACL,UAAU,iBACV,MAAO,EACP,mBAAA,GACA,YAAe,EAAW,EAAQ,EAAE,EAEnC,SAAA,CACK,CAAA,GAfN,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,iBAAiB,MAAO,EACrC,SAAA,CACG,CAAA,CAeZ,CCtCA,SAAgB,GAAgC,CAC9C,GAAI,OAAO,SAAa,IACtB,UAAa,CAAC,EAEhB,IAAM,EAAQ,SAAS,cAAgC,uDAA6C,GAAK,SAAS,cAAc,OAAO,EAwQvI,MAvQA,GAAM,QAAQ,OAAS,EACvB,EAAM,QAAQ,UAAY,+BAC1B,EAAM,YAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoQpB,SAAS,KAAK,YAAY,CAAK,MAClB,EAAM,OAAO,CAC5B,CC1PA,MAAa,EAAS,CACpB,gBACA,WACA,QACA,SACA,SACA,gBACA,eACA,iBACA,cACF,EAEM,EAAK,CACT,aAAc,KACd,uBAAwB,KACxB,6BAA8B,sBAC9B,iBAAkB,SAClB,uBAAwB,qBACxB,2BAA4B,OAC5B,iCAAkC,wBAClC,0BAA2B,OAC3B,gCAAiC,wBACjC,iBAAkB,OAClB,oBAAqB,KACrB,kBAAmB,KACnB,iBAAkB,OAClB,yBAA0B,UAC1B,kBAAmB,aACnB,mBAAoB,cACpB,oBAAqB,kBACrB,mBAAoB,cACpB,kBAAmB,uDACnB,yBAA0B,qBAC1B,uBAAwB,QACxB,2BAA4B,eAC5B,+BAAgC,kCAChC,wBAAyB,4BACzB,wBAAyB,mBACzB,wBAAyB,0BACzB,qBAAsB,eACtB,sBAAuB,gBACvB,uBAAwB,aACxB,yBAA0B,WAC5B,EAEM,EAAsC,CAC1C,aAAc,SACd,uBAAwB,YACxB,6BAA8B,gDAC9B,iBAAkB,gBAClB,uBAAwB,iDACxB,2BAA4B,gBAC5B,iCAAkC,8CAClC,0BAA2B,eAC3B,gCAAiC,qDACjC,iBAAkB,kBAClB,oBAAqB,SACrB,kBAAmB,OACnB,iBAAkB,iBAClB,yBAA0B,uBAC1B,kBAAmB,cACnB,mBAAoB,sBACpB,oBAAqB,4BACrB,mBAAoB,8BACpB,kBAAmB,iIACnB,yBAA0B,mEAC1B,uBAAwB,aACxB,2BAA4B,oDAC5B,+BAAgC,uFAChC,wBAAyB,iGACzB,wBAAyB,+EACzB,wBAAyB,wFACzB,qBAAsB,0CACtB,sBAAuB,kDACvB,uBAAwB,8CACxB,yBAA0B,iCAC5B,EAaA,SAAS,EAAc,EAAyB,CAC9C,OAAO,mBAAmB,CAAO,CAAC,CAAC,QAAQ,QAAS,GAAG,CACzD,CAEA,SAAS,EAAW,EAAsB,CACxC,OAAO,EAAK,MAAM,GAAG,CAAC,CAAC,IAAI,CAAa,CAAC,CAAC,KAAK,GAAG,CACpD,CAEA,SAAS,EAAmB,EAAmB,EAAsB,CACnE,IAAM,EAAa,EAAK,QAAQ,MAAO,GAAG,CAAC,CAAC,QAAQ,cAAe,EAAE,EACrE,MAAO,+BAAiC,EAAc,CAAS,EAAE,GAAG,EAAW,CAAU,GAC3F,CAEA,SAAS,EAAe,EAAmB,EAAyB,EAAsB,CACxF,IAAM,EAAa,EAAK,QAAQ,MAAO,GAAG,EACpC,EAAO,GAAK,QAAQ,MAAO,GAAG,CAAC,CAAC,QAAQ,QAAS,EAAE,GAAK,GAK9D,MAJK,4BAA4B,KAAK,CAAU,GAE5C,IAAS,IAAM,EAAW,WAAW,GAAG,EAAK,EAAE,EAC1C,EAAmB,EAAW,EAAW,MAAM,EAAK,OAAS,CAAC,CAAC,EACjE,EAAmB,EAAW,CAAU,CACjD,CAmCA,SAAgB,EAAM,EAA0B,CAC9C,IAAM,EAAW,EAAI,SACf,EAAgB,EAAI,OAAqD,OACzE,EAAI,EAAI,OAAO,KAAK,CAAS,EAC7B,EAAU,IAAI,IACd,EAAqB,IAAI,IAE/B,EAAI,WAAa,EAAkB,EAAG,sBAAsB,EAC5D,EAAI,WAAa,EAAI,OAAO,SAAS,EAAW,CAAE,KAAI,IAAG,CAAC,EAAG,4BAA4B,EAEzF,SAAS,EAAW,EAAiC,CACnD,IAAM,EAAW,EAAQ,IAAI,CAAS,EACtC,GAAI,IAAa,IAAA,GACf,OAAO,EAET,IAAM,EAAQ,IAAI,gBACZ,GAAW,SAAY,CAC3B,GAAI,EAAS,QAAQ,CAAS,IAAM,IAAA,GAClC,MAAU,MAAM,+CAA+C,EAAU,EAAE,EAC7E,OAAO,EAAS,MAAM,EAAW,CAAE,OAAQ,gBAAiB,OAAQ,EAAM,MAAO,EAAG,KAAO,IAAc,CACvG,EAAM,OAAO,eAAe,EAC5B,IAAM,EAAQ,EAAU,QAAQ,QAAQ,YAAY,EACpD,GAAI,EAAM,YAAc,OACtB,MAAM,EAAM,WAAiB,MAAM,YAAY,EAAU,cAAc,EACzE,IAAM,EAAS,MAAM,EAAa,KAAK,CAAE,WAAU,EAAG,EAAM,MAAM,EAElE,GADA,EAAM,OAAO,eAAe,EACxB,CAAC,EAAO,GACV,MAAU,MAAM,uBAAuB,EAAO,MAAM,KAAK,IAAI,EAAO,MAAM,SAAS,EACrF,OAAO,EAAO,MAAM,MACtB,CAAC,CACH,EAAA,CAAG,EAEG,EAAsB,CAAE,QAAO,SAAQ,EAQ7C,OAPA,EAAQ,IAAI,EAAW,CAAK,EAC5B,EAAQ,KAAM,GAAW,CACvB,EAAM,QAAU,CAClB,MAAS,CACH,EAAQ,IAAI,CAAS,IAAM,GAC7B,EAAQ,OAAO,CAAS,CAC5B,CAAC,EACM,CACT,CAEA,SAAS,EAAU,EAAmB,EAA0B,EAAiD,CAC/G,IAAM,EAAa,EAAY,CAAO,EACtC,GAAI,IAAe,IAAA,GACjB,MAAO,GACT,IAAM,EAAQ,EAAQ,KAAK,GAAQ,EAAK,OAAS,EAAW,KAAK,EACjE,GAAI,GAAO,OAAS,IAAA,GAClB,MAAO,GACT,IAAM,EAAM,EAAS,KAAK,YAAY,CAAC,CAAC,KAAK,EAAU,EAAE,IACzD,GAAI,CAEF,OADA,EAAI,aAAa,aAAa,EAAe,EAAW,EAAK,EAAM,IAAI,CAAC,EACjE,EACT,OACO,EAAO,CAEZ,OADA,QAAQ,MAAM,6CAA8C,CAAK,EAC1D,EACT,CACF,CAEA,IAAM,EAA6B,CACjC,QAAS,IACT,KAAM,EACN,MAAO,EACP,MAAM,WAAW,EAAU,CAAE,QAAO,UAAU,CAC5C,GAAI,EAAO,QACT,MAAO,CAAC,EACV,IAAM,EAAQ,EAAgB,IAAK,GAAY,CAC7C,IAAM,EAAO,EAAa,EAAQ,IAClC,MAAO,CACL,KAAM,EAAQ,QACd,MAAO,EAAE,QAAQ,EAAQ,GAAG,OAAO,EACnC,YAAa,EAAE,QAAQ,EAAQ,GAAG,aAAa,EAC/C,QAAS,EAAE,YAAY,EACvB,KAAM,CACR,CACF,CAAC,EACD,OAAO,EAAM,SAAW,EAAI,GAAA,EAAA,EAAA,WAAA,CAAmB,EAAO,CAAK,CAC7D,EACA,SAAU,CACR,OAAO,EAAgB,IAAI,GAAW,EAAQ,OAAO,CACvD,EACA,cAAc,EAAS,CAAE,OAAO,CAC9B,IAAM,EAAU,EAAY,CAAG,EAC/B,GAAI,IAAY,IAAA,GACd,MAAO,GAET,IAAM,EAAU,EAAQ,IAAI,EAAQ,SAAS,CAAC,EAAE,QAChD,GAAI,IAAY,IAAA,GACd,OAAO,EAAU,EAAQ,UAAW,EAAQ,GAAI,CAAO,EAEzD,IAAM,EAAQ,EAAW,EAAQ,SAAS,EAQ1C,OAPA,EAAM,QAAQ,KAAM,GAAY,CACzB,EAAM,MAAM,OAAO,SACtB,EAAU,EAAQ,UAAW,EAAQ,GAAI,CAAO,CACpD,CAAC,CAAC,CAAC,MAAO,GAAU,CACb,EAAM,MAAM,OAAO,SACtB,QAAQ,MAAM,6CAA8C,CAAK,CACrE,CAAC,EACM,EACT,EACA,OAAO,CAAE,aAAa,CACpB,IAAM,EAAU,EAAiB,EAAU,IAAI,EAC3C,OAAY,IAAA,GAEhB,MAAO,CACL,OAAQ,CACN,OAAQ,EACR,IAAK,EAAQ,GACb,MAAO,EAAE,QAAQ,EAAQ,GAAG,OAAO,EACnC,WAAY,OACZ,cAAe,IAAI,EAAQ,SAC7B,CACF,CACF,EACA,MAAO,CACL,cAAc,EAAK,CACjB,IAAM,EAAU,EAAY,CAAG,EAC/B,OAAO,IAAY,IAAA,GAAY,IAAI,IAAQ,IAAI,EAAQ,SACzD,EACA,MAAM,UAAU,EAAK,CACnB,IAAM,EAAU,EAAY,CAAG,EAG/B,OAFI,IAAY,IAAA,GACP,aACF,IAAI,EAAQ,QAAQ,eAAe,EAAQ,MAAM,mGAC1D,CACF,CACF,EAEM,EAA+B,CACnC,GAAI,EACJ,MAAO,GACP,MAAM,EAAM,EAAM,CAChB,IAAM,EAAS,4BACf,EAAO,UAAY,EACnB,IAAK,IAAI,EAAQ,EAAO,KAAK,CAAI,EAAG,IAAU,KAAM,EAAQ,EAAO,KAAK,CAAI,EAAG,CAC7E,IAAM,EAAU,EAAiB,EAAM,IAAM,EAAE,EAC3C,OAAY,IAAA,GAEhB,MAAO,CACL,GAAI,EACJ,MAAO,EAAM,MACb,IAAK,EAAM,MAAQ,EAAM,EAAE,CAAC,OAC5B,KAAM,CAAE,QAAS,EAAQ,EAAG,CAC9B,CACF,CAEF,CACF,EAEA,EAAI,WAAa,EAAI,eAAe,SAAS,SAAS,CAAI,EAAG,+BAA+B,EAE5F,EAAI,WAAa,EAAI,MAAM,OAAO,MAAwB,EAAI,MAAM,SAAS,CAC3E,KAAM,EACN,IAAK,EACL,SAAU,IACV,OAAS,IAAuB,CAC9B,WAAa,GAA6B,CACxC,EAAO,gBAAgB,CAAa,WAAmB,EAAG,CAAE,IAAK,EAAS,WAAY,MAAO,CAAC,CAChG,EACA,YAAc,GAA6B,EAAE,QAAQ,EAAQ,OAAO,CACtE,EACF,EAAG,EAAe,CAAC,EAAG,oCAAoC,EAE1D,SAAS,EAAuB,EAAuC,CACrE,IAAM,EAAa,EAAI,aACjB,EAAa,OAAO,EAAW,cAAiB,YACjD,OAAO,EAAW,yBAA4B,YAC9C,OAAO,EAAW,yBAA4B,WAC/C,EAAU,EAAmB,IAAI,CAAS,EAK9C,OAJK,IACH,EAAU,IAAI,IACd,EAAmB,IAAI,EAAW,CAAO,GAEpC,CACL,mBAAoB,EAEpB,OAAQ,EACJ,CACE,OAAQ,GAAS,EAAW,aAAc,EAAoB,CAAK,EACnE,QAAS,GAAU,EAAW,wBAAyB,CAAM,EAC7D,OAAQ,GAAO,EAAW,wBAAyB,CAAG,CAAC,CAAC,OAAO,GAAQ,EAAK,OAAS,OAAO,CAAC,CAAC,IAAI,GAAQ,EAAK,IAAI,CACrH,EACA,IAAA,GACJ,eAAiB,GAAW,CAC1B,GAAI,CACF,IAAM,EAAM,EAAS,KAAK,YAAY,CAAC,CAAC,KAAK,EAAU,EAAE,IACzD,EAAI,aAAa,aAAa,EAAe,EAAW,EAAK,CAAM,CAAC,CACtE,OACO,EAAO,CACZ,QAAQ,MAAM,8CAA+C,CAAK,CACpE,CACF,CACF,CACF,CAEA,EAAI,WAAa,EAAI,eAAe,SAAS,SAAS,CAAc,EAAG,2BAA2B,EAClG,EAAI,WAAa,EAAI,MAAM,OAAO,MAAwB,EAAI,MAAM,SAAS,CAC3E,KAAM,EACN,IAAK,EACL,SAAA,IACA,OAAQ,EACR,OAAQ,CACV,EAAG,CAAmB,CAAC,EAAG,qCAAqC,EAC/D,EAAI,WAAa,EAAI,MAAM,OAAO,MAAuB,EAAI,MAAM,SAAS,CAC1E,KAAM,EACN,GAAI,qBACJ,MAAA,GACA,OAAQ,EACR,OAAQ,CACV,EAAG,CAAkB,CAAC,EAAG,+BAA+B,EAExD,IAAM,EAAgB,EAAI,cAC1B,EAAI,WAAa,CACf,IAAM,EAAa,EAAc,eAAe,CAAM,EACtD,UAAa,CACX,EAAW,EACX,IAAK,IAAM,KAAS,EAAQ,OAAO,EACjC,EAAM,MAAM,MAAM,EACpB,EAAQ,MAAM,EACd,EAAmB,MAAM,CAC3B,CACF,EAAG,4BAA4B,CACjC"}
|
package/package.json
CHANGED
|
@@ -1,149 +1,146 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "dsh-office-kit",
|
|
3
|
-
"type": "module",
|
|
4
|
-
"version": "0.
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
"
|
|
27
|
-
"./
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"@deepseek-ai/dsh-
|
|
46
|
-
"@deepseek-ai/dsh-client-
|
|
47
|
-
"@deepseek-ai/dsh-client-ui-
|
|
48
|
-
"@deepseek-ai/dsh-client-ui-
|
|
49
|
-
"@deepseek-ai/dsh-client-ui-
|
|
50
|
-
"@deepseek-ai/dsh-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
"@
|
|
84
|
-
"@
|
|
85
|
-
"@
|
|
86
|
-
"@deepseek-ai/
|
|
87
|
-
"@deepseek-ai/
|
|
88
|
-
"@deepseek-ai/
|
|
89
|
-
"@deepseek-ai/
|
|
90
|
-
"@deepseek-ai/dsh-
|
|
91
|
-
"@deepseek-ai/dsh-
|
|
92
|
-
"@deepseek-ai/dsh-
|
|
93
|
-
"@deepseek-ai/dsh-
|
|
94
|
-
"@deepseek-ai/dsh-
|
|
95
|
-
"@deepseek-ai/dsh-
|
|
96
|
-
"@deepseek-ai/dsh-
|
|
97
|
-
"@deepseek-ai/dsh-
|
|
98
|
-
"@deepseek-ai/dsh-client-
|
|
99
|
-
"@deepseek-ai/dsh-
|
|
100
|
-
"@deepseek-ai/dsh-
|
|
101
|
-
"@deepseek-ai/dsh-
|
|
102
|
-
"@deepseek-ai/dsh-
|
|
103
|
-
"@deepseek-ai/dsh-
|
|
104
|
-
"@deepseek-ai/dsh-
|
|
105
|
-
"@deepseek-ai/dsh-
|
|
106
|
-
"@deepseek-ai/dsh-
|
|
107
|
-
"@deepseek-ai/dsh-
|
|
108
|
-
"@deepseek-ai/dsh-
|
|
109
|
-
"@deepseek-ai/dsh-
|
|
110
|
-
"@deepseek-ai/dsh-
|
|
111
|
-
"@deepseek-ai/dsh-
|
|
112
|
-
"@deepseek-ai/dsh-
|
|
113
|
-
"@
|
|
114
|
-
"@
|
|
115
|
-
"@
|
|
116
|
-
"
|
|
117
|
-
"
|
|
118
|
-
"
|
|
119
|
-
"
|
|
120
|
-
"
|
|
121
|
-
"
|
|
122
|
-
"
|
|
123
|
-
"
|
|
124
|
-
"
|
|
125
|
-
"
|
|
126
|
-
"
|
|
127
|
-
"
|
|
128
|
-
"
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
"
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
"
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
"
|
|
138
|
-
"
|
|
139
|
-
"
|
|
140
|
-
"
|
|
141
|
-
"
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
"
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
"*": "eslint --fix"
|
|
148
|
-
}
|
|
149
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "dsh-office-kit",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.2.0",
|
|
5
|
+
"description": "Office documents, PDF, presentations, and spreadsheets for DeepSeek Harness",
|
|
6
|
+
"author": "Hairy",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"homepage": "https://github.com/hairyf/dsh-office-kit#readme",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/hairyf/dsh-office-kit.git"
|
|
12
|
+
},
|
|
13
|
+
"bugs": "https://github.com/hairyf/dsh-office-kit/issues",
|
|
14
|
+
"keywords": [
|
|
15
|
+
"dsh-plugin",
|
|
16
|
+
"deepseek-harness",
|
|
17
|
+
"office",
|
|
18
|
+
"docx",
|
|
19
|
+
"pdf",
|
|
20
|
+
"pptx",
|
|
21
|
+
"xlsx"
|
|
22
|
+
],
|
|
23
|
+
"sideEffects": false,
|
|
24
|
+
"exports": {
|
|
25
|
+
".": "./dist/index.js",
|
|
26
|
+
"./client": "./dist/client.js",
|
|
27
|
+
"./package.json": "./package.json"
|
|
28
|
+
},
|
|
29
|
+
"main": "./dist/index.js",
|
|
30
|
+
"module": "./dist/index.js",
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"files": [
|
|
33
|
+
"CAPABILITY.md",
|
|
34
|
+
"README.md",
|
|
35
|
+
"assets",
|
|
36
|
+
"cordis.patch.yml",
|
|
37
|
+
"dist",
|
|
38
|
+
"postinstall.mjs",
|
|
39
|
+
"python"
|
|
40
|
+
],
|
|
41
|
+
"dsh": {
|
|
42
|
+
"client": {
|
|
43
|
+
"inject": [
|
|
44
|
+
"@deepseek-ai/dsh-api-session-controller",
|
|
45
|
+
"@deepseek-ai/dsh-client-locale",
|
|
46
|
+
"@deepseek-ai/dsh-client-ui-layout",
|
|
47
|
+
"@deepseek-ai/dsh-client-ui-conversation",
|
|
48
|
+
"@deepseek-ai/dsh-client-ui-input-trigger",
|
|
49
|
+
"@deepseek-ai/dsh-client-ui-sidebar-right",
|
|
50
|
+
"@deepseek-ai/dsh-api-remotes"
|
|
51
|
+
],
|
|
52
|
+
"platform": "web"
|
|
53
|
+
},
|
|
54
|
+
"bundle": {
|
|
55
|
+
"patch": "./cordis.patch.yml"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"scripts-info": {
|
|
59
|
+
"build": "Build the library for publishing",
|
|
60
|
+
"dev": "Rebuild on change during development",
|
|
61
|
+
"lint": "Check for code style issues",
|
|
62
|
+
"prepack": "Build before publishing",
|
|
63
|
+
"release": "Bump version and publish a release",
|
|
64
|
+
"start": "Run the entry file",
|
|
65
|
+
"test": "Run the test suite",
|
|
66
|
+
"typecheck": "Check types",
|
|
67
|
+
"prepare": "Set up git hooks and skills"
|
|
68
|
+
},
|
|
69
|
+
"devDependencies": {
|
|
70
|
+
"@antfu/eslint-config": "^9.1.0",
|
|
71
|
+
"@antfu/ni": "^30.2.0",
|
|
72
|
+
"@antfu/utils": "^9.3.0",
|
|
73
|
+
"@deepseek-ai/cordis": "4.0.5",
|
|
74
|
+
"@deepseek-ai/cordis-plugin-group": "1.0.5",
|
|
75
|
+
"@deepseek-ai/cordis-plugin-include": "1.0.10",
|
|
76
|
+
"@deepseek-ai/cordis-plugin-loader": "1.0.6",
|
|
77
|
+
"@deepseek-ai/dsh-agent": "0.2.1-rc.2",
|
|
78
|
+
"@deepseek-ai/dsh-agent-default-model": "0.2.1-rc.2",
|
|
79
|
+
"@deepseek-ai/dsh-agent-loop": "0.2.1-rc.2",
|
|
80
|
+
"@deepseek-ai/dsh-agent-preset": "0.2.1-rc.2",
|
|
81
|
+
"@deepseek-ai/dsh-agent-preset-registry": "0.2.1-rc.2",
|
|
82
|
+
"@deepseek-ai/dsh-api-remotes": "0.2.1-rc.2",
|
|
83
|
+
"@deepseek-ai/dsh-api-session-controller": "0.2.1-rc.2",
|
|
84
|
+
"@deepseek-ai/dsh-api-workspace-controller": "0.2.1-rc.2",
|
|
85
|
+
"@deepseek-ai/dsh-client-connection": "0.2.1-rc.2",
|
|
86
|
+
"@deepseek-ai/dsh-client-locale": "0.2.1-rc.2",
|
|
87
|
+
"@deepseek-ai/dsh-client-store": "0.2.1-rc.2",
|
|
88
|
+
"@deepseek-ai/dsh-client-ui-conversation": "0.2.1-rc.2",
|
|
89
|
+
"@deepseek-ai/dsh-client-ui-input-trigger": "0.2.1-rc.2",
|
|
90
|
+
"@deepseek-ai/dsh-client-ui-layout": "0.2.1-rc.2",
|
|
91
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.2.1-rc.2",
|
|
92
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.2.1-rc.2",
|
|
93
|
+
"@deepseek-ai/dsh-client-ui-session": "0.2.1-rc.2",
|
|
94
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.2.1-rc.2",
|
|
95
|
+
"@deepseek-ai/dsh-client-ui-sidebar-right": "0.2.1-rc.2",
|
|
96
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.2.1-rc.2",
|
|
97
|
+
"@deepseek-ai/dsh-client-ui-theme": "0.2.1-rc.2",
|
|
98
|
+
"@deepseek-ai/dsh-client-ui-workspace": "0.2.1-rc.2",
|
|
99
|
+
"@deepseek-ai/dsh-host-webserver": "0.2.1-rc.2",
|
|
100
|
+
"@deepseek-ai/dsh-llm": "0.2.1-rc.2",
|
|
101
|
+
"@deepseek-ai/dsh-permission-presets": "0.2.1-rc.2",
|
|
102
|
+
"@deepseek-ai/dsh-session": "0.2.1-rc.2",
|
|
103
|
+
"@deepseek-ai/dsh-session-persistence": "0.2.1-rc.2",
|
|
104
|
+
"@deepseek-ai/dsh-session-projection": "0.2.1-rc.2",
|
|
105
|
+
"@deepseek-ai/dsh-skill": "0.2.1-rc.2",
|
|
106
|
+
"@deepseek-ai/dsh-skill-filesystem": "0.2.1-rc.2",
|
|
107
|
+
"@deepseek-ai/dsh-tools": "0.2.1-rc.2",
|
|
108
|
+
"@deepseek-ai/dsh-user-approval": "0.2.1-rc.2",
|
|
109
|
+
"@deepseek-ai/dsh-user-questions": "0.2.1-rc.2",
|
|
110
|
+
"@deepseek-ai/dsh-util-code-language": "0.2.1-rc.2",
|
|
111
|
+
"@deepseek-ai/dsh-util-values": "0.2.1-rc.2",
|
|
112
|
+
"@deepseek-ai/dsh-workspace": "0.2.1-rc.2",
|
|
113
|
+
"@types/node": "^26.1.1",
|
|
114
|
+
"@types/react": "^18.2.0",
|
|
115
|
+
"@types/react-dom": "^18.2.0",
|
|
116
|
+
"bumpp": "^12.0.0",
|
|
117
|
+
"eslint": "^10.7.0",
|
|
118
|
+
"nano-staged": "^1.0.2",
|
|
119
|
+
"publint": "^0.3.21",
|
|
120
|
+
"react": "^18.2.0",
|
|
121
|
+
"simple-git-hooks": "^2.13.1",
|
|
122
|
+
"skills-npm": "^1.2.0",
|
|
123
|
+
"tsdown": "^0.22.12",
|
|
124
|
+
"tsnapi": "^1.0.0",
|
|
125
|
+
"tsx": "^4.23.1",
|
|
126
|
+
"typescript": "^6.0.3",
|
|
127
|
+
"vite": "^8.1.5",
|
|
128
|
+
"vitest": "^4.1.10"
|
|
129
|
+
},
|
|
130
|
+
"simple-git-hooks": {
|
|
131
|
+
"pre-commit": "pnpm i --frozen-lockfile --ignore-scripts --offline && pnpm run build && npx nano-staged"
|
|
132
|
+
},
|
|
133
|
+
"nano-staged": {
|
|
134
|
+
"*": "eslint --fix"
|
|
135
|
+
},
|
|
136
|
+
"scripts": {
|
|
137
|
+
"build": "tsdown",
|
|
138
|
+
"dev": "tsdown --watch",
|
|
139
|
+
"lint": "eslint",
|
|
140
|
+
"release": "bumpp",
|
|
141
|
+
"start": "tsx src/index.ts",
|
|
142
|
+
"test": "pnpm run build && vitest",
|
|
143
|
+
"typecheck": "tsc",
|
|
144
|
+
"postinstall": "node postinstall.mjs"
|
|
145
|
+
}
|
|
146
|
+
}
|