@lemoncat7/dsh-theme-xiaohei 0.4.3 → 0.4.5
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/docs/releases/0.4.4.md +7 -0
- package/docs/releases/0.4.5.md +21 -0
- package/docs/startup-audit-20261013.md +47 -0
- package/lib/chrome/conversation-messages.js +17 -4
- package/lib/chrome/conversation-submissions.d.ts +3 -0
- package/lib/chrome/conversation-submissions.js +68 -0
- package/lib/chrome/sidebar.d.ts +1 -1
- package/lib/chrome/sidebar.js +20 -0
- package/lib/chrome.js +2 -0
- package/lib/client.decorations.js +51 -0
- package/lib/client.js +134 -750
- package/lib/client.pose-chin-dark.js +4 -0
- package/lib/client.pose-chin-light.js +4 -0
- package/lib/client.pose-doze-dark.js +4 -0
- package/lib/client.pose-doze-light.js +4 -0
- package/lib/client.pose-halfpeek-dark.js +4 -0
- package/lib/client.pose-halfpeek-light.js +4 -0
- package/lib/client.pose-peek-dark.js +4 -0
- package/lib/client.pose-peek-light.js +4 -0
- package/lib/client.pose-seated-dark.js +4 -0
- package/lib/client.pose-seated-light.js +4 -0
- package/lib/client.rig-chin-dark.js +4 -0
- package/lib/client.rig-chin-light.js +4 -0
- package/lib/client.rig-halfpeek-dark.js +4 -0
- package/lib/client.rig-halfpeek-light.js +4 -0
- package/lib/client.rig-peek-dark.js +4 -0
- package/lib/client.rig-peek-light.js +4 -0
- package/lib/client.rig-seated-dark.js +4 -0
- package/lib/client.rig-seated-light.js +4 -0
- package/lib/composer-draft-preview.d.ts +4 -0
- package/lib/composer-draft-preview.js +8 -0
- package/lib/decorations-entry.d.ts +3 -0
- package/lib/decorations-entry.js +18 -0
- package/lib/deferred-decorations.d.ts +3 -0
- package/lib/deferred-decorations.js +51 -0
- package/lib/plugin.js +11 -4
- package/lib/portal.js +1 -1
- package/lib/scene/character-assets.d.ts +13 -0
- package/lib/scene/character-assets.js +26 -0
- package/lib/scene/character-motion.js +14 -7
- package/lib/scene/ids.d.ts +5 -0
- package/lib/scene/ids.js +5 -0
- package/lib/scene/runtime.d.ts +1 -1
- package/lib/scene/runtime.js +2 -15
- package/lib/scene/styles.d.ts +1 -3
- package/lib/scene/styles.js +2 -8
- package/lib/scene/wallpaper-character-styles.js +1 -5
- package/lib/scene/wallpaper-character.d.ts +2 -1
- package/lib/scene/wallpaper-character.js +24 -15
- package/lib/sidebar-glass.js +1 -1
- package/package.json +4 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# 0.4.4 · DSH 0.2.0-rc.2 底栏布局兼容修复
|
|
2
|
+
|
|
3
|
+
- 修复侧栏 footer 操作区横向排列导致知识库挤出 Agents Anywhere 等入口的问题,改为纵向排列。
|
|
4
|
+
- 保留插件注册顺序、设置区、按钮内部布局和隐藏状态;兼容侧栏展开/收起及 Desktop 已有的纵向布局补丁。
|
|
5
|
+
- 仅修改主题,不改动 DSH 核心、知识库或 AA 功能。
|
|
6
|
+
- 验证:主题测试 103 项通过、1 项跳过;32 组 Chromium 布局用例覆盖明暗主题、宽/窄侧栏、新旧知识库样式及不同插槽布局。
|
|
7
|
+
- 适配 DSH **0.2.0-rc.2**;需要 Node.js **^22.19.0 或 >=24.0.0**。
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# 0.4.5 · 对话输入预览与主题按需加载
|
|
2
|
+
|
|
3
|
+
兼容宿主:DeepSeek Harness 0.2.0-rc.2。本版本不调整宿主兼容范围。
|
|
4
|
+
|
|
5
|
+
## 对话体验
|
|
6
|
+
|
|
7
|
+
- 输入时显示草稿气泡,跟随正式对话内容列对齐;清空、切换会话后同步更新。
|
|
8
|
+
- 适配宿主发送后的提前回显及插话消息,统一气泡、头像和浅深色样式,保留附件及排队操作。
|
|
9
|
+
- 覆盖窄屏、长文本与安全文本渲染;草稿预览不会代替实际发送。
|
|
10
|
+
|
|
11
|
+
## 启动与人物资源
|
|
12
|
+
|
|
13
|
+
- 壁纸随主题入口同步安装,不等待人物下载,减少首屏只有纯色背景的等待。
|
|
14
|
+
- 装饰和人物控制器使用 DSH 原生异步分包;按当前姿态、主题及动作设置加载对应资源,支持请求去重与缓存。
|
|
15
|
+
- 保留原始素材,新增 44 张有损 WebP 运行时副本,资源从约 4.44 MB 降至 0.68 MB,减少约 85%;尺寸和透明通道保持不变。
|
|
16
|
+
- 构建校验源图与运行时副本的 SHA256,防止发布过期素材;生成 10 个姿态和 8 个动作分包。
|
|
17
|
+
- 动作资源加载失败时保留静态人物;卸载及姿态变化时丢弃失效的异步结果。
|
|
18
|
+
|
|
19
|
+
验证:构建通过,113 项测试通过、1 项原有跳过;草稿预览、发送回显及头像、首屏壁纸的浅深色与窄屏/宽屏浏览器回归通过。
|
|
20
|
+
|
|
21
|
+
验证环境为 Web / DSH 0.2.0-rc.2;未进行 Desktop 实机回归。上述优化不代表所有插件加载和服务端等待均已消除。详细测量及部署记录见 `docs/startup-audit-20261013.md`。
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# 刷新加载排查(2026-10-13)
|
|
2
|
+
|
|
3
|
+
环境:正式容器 DSH 0.2.0-rc.2,本机 Chromium 无头浏览器,直连 127.0.0.1:3080。
|
|
4
|
+
只加载页面和刷新,没有发送消息或修改业务配置。不能将此结果直接等同于公网代理或 Desktop 的耗时。
|
|
5
|
+
|
|
6
|
+
## 观察
|
|
7
|
+
|
|
8
|
+
- 三组首开/刷新侧栏就绪时间(毫秒):16775/1238/1266、11645/5038/1120、2213/2025/1268。第三组开启 CPU 采样,有额外测量开销。
|
|
9
|
+
- 两个主要插件聚合脚本解码大小为 10584847 和 11332146 字节。直接 HTTP 响应传输大小接近原文大小;缓存有命中,也存在刷新后重传。尚未验证公网反代压缩与缓存策略。
|
|
10
|
+
- 安装的主题 client.js 约 6.5 MiB;主题生成的背景、角色图片以 base64 字符串打进脚本。不能单凭包大小断言它是全部瓶颈。
|
|
11
|
+
- 慢刷新样本首页 responseStart 为 3775 ms,后续插件下载约 100–140 ms。存在服务侧响应等待,不只是浏览器执行慢。
|
|
12
|
+
- 慢首开样本前端出现 2028 ms 和 4988 ms 长任务。快首开 CPU 样本包含模块 materialize、图片 onload、文本匹配及布局测量;聚合脚本归属仍需进一步拆分定位。
|
|
13
|
+
|
|
14
|
+
## 本轮边界
|
|
15
|
+
|
|
16
|
+
修复发送后待确认消息缺少头像,共享正式用户头像规则。106 项测试通过,1 项原有跳过;浏览器覆盖浅深色、375/1280 宽度及队列不添加头像。
|
|
17
|
+
|
|
18
|
+
没有修改宿主源码、清除用户缓存、禁用业务插件或提前隐藏加载状态。启动优化应单独验证:图片资源按需加载并独立缓存、装饰初始化延后,以及服务/反代响应与压缩配置。需同时保留 Desktop 兼容和原视觉效果。
|
|
19
|
+
|
|
20
|
+
## 后续实施:装饰原生分包
|
|
21
|
+
|
|
22
|
+
- 使用 DSH rc.2 官方 `require.async('./client.decorations.js')` 与 `chunk` 注册协议,没有增加自定义图片服务、跨域请求或宿主修改。Desktop 使用同一载体协议;本轮实机验证是 Web,未声称已运行 Desktop 回归。
|
|
23
|
+
- 主题启动脚本从约 6.5 MiB 降至约 450 KiB。壁纸、动作和角色原图保留在约 5.7 MiB 自包含装饰分包中,不降质;不是每张图片各自请求。
|
|
24
|
+
- 共享场景 ID 拆到无资源依赖模块,避免侧栏仅引用 ID 却把整套图片拉进主包。
|
|
25
|
+
- 主界面侧栏提交后才调度下载;下载/初始化失败只影响装饰。卸载取消定时/空闲调度,异步返回后检查销毁状态。
|
|
26
|
+
- 构建先写 chunk、再写 client.js,符合 DSH 根据入口修订生成所有分包缓存地址的约定。
|
|
27
|
+
- 正式验证:侧栏 4787/1741/1165 ms;装饰资源三次都成功,后两次 transferSize=0(缓存命中)。首屏插件聚合资源约 21.96 MB → 15.70 MB。首开有 CPU 采样开销且服务负载有波动,不作为固定提速比例。
|
|
28
|
+
- 109 项测试通过、1 项原有跳过,另有气泡、头像、窄屏与浅深色浏览器回归。正式服务 API HTTP 200。
|
|
29
|
+
- 备份:`dsh-docker/backups/theme-submission-9Kd164aL`;部署构建:`theme-submission-1791884068942`。
|
|
30
|
+
|
|
31
|
+
剩余:服务侧响应等待、核心布局测量长任务仍存在,本轮不改宿主源码。不能将所有刷新延迟标记为已消除。
|
|
32
|
+
|
|
33
|
+
## 首屏背景修正
|
|
34
|
+
|
|
35
|
+
用户反馈角色分包完成前只有纯色背景。两张壁纸合计实际仅约 17 KiB,因此将壁纸 CSS 与角色 CSS 分离:壁纸随主题同步安装,不再使用空闲调度;角色和动作仍在独立分包内。入口约 474 KiB,未回退到原来的 6.5 MiB。浏览器测试覆盖浅深色、375/1280、没有角色分包时背景图解码成功及卸载清理。109 项测试通过,1 项原有跳过。
|
|
36
|
+
|
|
37
|
+
## 人物有损压缩与逐资源加载
|
|
38
|
+
|
|
39
|
+
- 原始素材保留,使用 `scripts/compress-character-assets.py` 生成 WebP quality 82 运行时副本。44 张素材从 4,440,792 字节降到 676,052 字节,减少约 85%;尺寸和透明通道保持一致,构建校验源文件及副本 SHA256。显示尺寸下对比了浅深色 seated/chin 素材。
|
|
40
|
+
- 将资源拆为 10 个姿态分包和 8 个动作分包。入口仍约 474 KiB;人物控制器从约 5.7 MiB 降到约 22 KiB;单个姿态约 37–83 KiB,动作约 22–46 KiB。
|
|
41
|
+
- 仅加载当前姿态、当前主题的图片;启用动作且角色可见时才加载对应动作层。减少动态效果设置下不请求动作分包。请求去重、成功缓存,失效异步结果不覆盖当前姿态;动作失败保留静态图。
|
|
42
|
+
- 壁纸仍随入口同步安装,不等待人物素材。继续使用 DSH 原生分包协议,不新增资源服务或修改宿主。
|
|
43
|
+
- 全套测试 113 通过、1 项原有跳过;最终补充的 18 个分包完整性断言及资源加载测试 3 项通过。`git diff --check` 通过。
|
|
44
|
+
- 正式容器浏览器实测:初始只请求 `pose-seated-light`;切深色才请求 `pose-seated-dark`;切回浅色无新请求;关闭减少动态效果后才请求 `rig-seated-light`,动作层成功显示。容器 `running healthy`、重启次数 0。未进行 Desktop 实机验证。
|
|
45
|
+
- 部署构建:`theme-submission-1791886119221`;备份:`dsh-docker/backups/theme-submission-O30fGwxx`。
|
|
46
|
+
|
|
47
|
+
本轮降低的是人物素材传输、解析和解码压力,不代表服务侧等待或所有插件的启动耗时均已消除。
|
|
@@ -34,12 +34,14 @@ ${thinkingOnlyRow} > [data-slot='conversation.chat.node'] > div:first-child {
|
|
|
34
34
|
|
|
35
35
|
/* Message portraits are deliberately static and only identify the speaker. */
|
|
36
36
|
#root [data-chat-flow-kind='assistant-step'],
|
|
37
|
+
#root div[data-submission-echo],
|
|
37
38
|
#root [data-chat-flow-kind='user'] {
|
|
38
39
|
position: relative;
|
|
39
40
|
overflow: visible;
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
#root [data-chat-flow-kind='assistant-step']::before,
|
|
44
|
+
#root div[data-submission-echo]::after,
|
|
43
45
|
#root [data-chat-flow-kind='user']::after {
|
|
44
46
|
position: absolute;
|
|
45
47
|
inset-block-start: 2px;
|
|
@@ -70,6 +72,7 @@ ${thinkingOnlyRow} > [data-slot='conversation.chat.node'] > div:first-child {
|
|
|
70
72
|
background-size: 76px auto, auto;
|
|
71
73
|
}
|
|
72
74
|
|
|
75
|
+
#root div[data-submission-echo]::after,
|
|
73
76
|
#root [data-chat-flow-kind='user']::after {
|
|
74
77
|
content: '我';
|
|
75
78
|
inset-inline-end: -50px;
|
|
@@ -123,8 +126,10 @@ ${thinkingOnlyRow} > [data-slot='conversation.chat.node'] > div:first-child {
|
|
|
123
126
|
> div:first-child > div:first-child > div:last-child:not([data-slot]):not(:has(img)),
|
|
124
127
|
#root [data-chat-flow-kind='user'] [data-time-hover-root]
|
|
125
128
|
> div:first-child > div:last-child:not(:has(img)),
|
|
126
|
-
#root [data-pending-steering]
|
|
127
|
-
> div:first-child > div:
|
|
129
|
+
#root :is(div[data-submission-echo], [data-pending-steering])
|
|
130
|
+
> div:first-child > div:first-child:not([data-message-attachments]),
|
|
131
|
+
#root :is(div[data-submission-echo], [data-pending-steering])
|
|
132
|
+
> div:first-child > [data-message-attachments] + div {
|
|
128
133
|
box-sizing: border-box;
|
|
129
134
|
padding: 14px 28px !important;
|
|
130
135
|
color: var(--xiaohei-conversation-text) !important;
|
|
@@ -229,6 +234,7 @@ html[data-xiaohei-appearance='light'] #root [data-chat-flow-kind='assistant-step
|
|
|
229
234
|
}
|
|
230
235
|
|
|
231
236
|
html[data-xiaohei-appearance='light'] #root [data-chat-flow-kind='assistant-step']::before,
|
|
237
|
+
html[data-xiaohei-appearance='light'] #root div[data-submission-echo]::after,
|
|
232
238
|
html[data-xiaohei-appearance='light'] #root [data-chat-flow-kind='user']::after {
|
|
233
239
|
border-color: rgb(42 48 52 / 11%);
|
|
234
240
|
color: rgb(48 54 58 / 72%);
|
|
@@ -238,6 +244,7 @@ html[data-xiaohei-appearance='light'] #root [data-chat-flow-kind='user']::after
|
|
|
238
244
|
0 6px 16px rgb(34 40 43 / 9%);
|
|
239
245
|
}
|
|
240
246
|
|
|
247
|
+
html[data-xiaohei-appearance='light'] #root div[data-submission-echo]::after,
|
|
241
248
|
html[data-xiaohei-appearance='light'] #root [data-chat-flow-kind='user']::after {
|
|
242
249
|
background-image:
|
|
243
250
|
linear-gradient(145deg, rgb(255 255 255 / 74%), transparent 58%),
|
|
@@ -250,12 +257,14 @@ html[data-xiaohei-appearance='light'] #root [data-chat-flow-kind='user']::after
|
|
|
250
257
|
padding-inline-start: 38px;
|
|
251
258
|
}
|
|
252
259
|
|
|
260
|
+
#root div[data-submission-echo],
|
|
253
261
|
#root [data-chat-flow-kind='user'] {
|
|
254
262
|
box-sizing: border-box;
|
|
255
263
|
padding-inline-end: 38px;
|
|
256
264
|
}
|
|
257
265
|
|
|
258
266
|
#root [data-chat-flow-kind='assistant-step']::before,
|
|
267
|
+
#root div[data-submission-echo]::after,
|
|
259
268
|
#root [data-chat-flow-kind='user']::after {
|
|
260
269
|
inline-size: 32px;
|
|
261
270
|
block-size: 36px;
|
|
@@ -267,6 +276,7 @@ html[data-xiaohei-appearance='light'] #root [data-chat-flow-kind='user']::after
|
|
|
267
276
|
background-size: 62px auto, auto;
|
|
268
277
|
}
|
|
269
278
|
|
|
279
|
+
#root div[data-submission-echo]::after,
|
|
270
280
|
#root [data-chat-flow-kind='user']::after {
|
|
271
281
|
inset-inline-end: 0;
|
|
272
282
|
block-size: 32px;
|
|
@@ -285,8 +295,10 @@ html[data-xiaohei-appearance='light'] #root [data-chat-flow-kind='user']::after
|
|
|
285
295
|
> div:first-child > div:first-child > div:last-child:not([data-slot]):not(:has(img)),
|
|
286
296
|
#root [data-chat-flow-kind='user'] [data-time-hover-root]
|
|
287
297
|
> div:first-child > div:last-child:not(:has(img)),
|
|
288
|
-
#root [data-pending-steering]
|
|
289
|
-
> div:first-child > div:
|
|
298
|
+
#root :is(div[data-submission-echo], [data-pending-steering])
|
|
299
|
+
> div:first-child > div:first-child:not([data-message-attachments]),
|
|
300
|
+
#root :is(div[data-submission-echo], [data-pending-steering])
|
|
301
|
+
> div:first-child > [data-message-attachments] + div {
|
|
290
302
|
padding-inline: 20px !important;
|
|
291
303
|
}
|
|
292
304
|
|
|
@@ -302,6 +314,7 @@ html[data-xiaohei-appearance='light'] #root [data-chat-flow-kind='user']::after
|
|
|
302
314
|
|
|
303
315
|
@media (prefers-contrast: more), (forced-colors: active) {
|
|
304
316
|
#root [data-chat-flow-kind='assistant-step']::before,
|
|
317
|
+
#root div[data-submission-echo]::after,
|
|
305
318
|
#root [data-chat-flow-kind='user']::after {
|
|
306
319
|
display: none;
|
|
307
320
|
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/** Local draft and native submission presentation; Host owns their lifetime. */
|
|
2
|
+
export declare const XIAOHEI_CONVERSATION_SUBMISSIONS_CSS = "\n#root [data-xiaohei-draft-preview] {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n box-sizing: border-box;\n inline-size: calc(100% - 2 * (var(--dsh-composer-side-clearance, 24px) + 16px));\n max-inline-size: var(--dsh-chat-content-width, 748px);\n margin-inline: auto;\n min-inline-size: 0;\n padding: 4px 0 8px;\n gap: 4px;\n color: var(--xiaohei-conversation-text);\n}\n#root .xiaohei-draft-label {\n font-size: 12px;\n padding-inline: 10px;\n}\n#root .xiaohei-draft-bubble {\n max-inline-size: min(calc(var(--dsh-chat-content-width, 748px) * .702), 82%);\n min-inline-size: 0;\n max-block-size: min(160px, 22dvh);\n overflow: auto;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n padding: 10px 14px;\n border: 1px dashed var(--xiaohei-conversation-edge);\n border-radius: 18px 9px 18px 18px;\n background: var(--xiaohei-conversation-user);\n font-size: 14px;\n line-height: 1.6;\n}\n#root .xiaohei-draft-bubble:focus-visible {\n outline: 2px solid currentColor;\n outline-offset: 2px;\n}\n@media (width <= 760px) {\n #root [data-xiaohei-draft-preview] {\n padding-inline-end: 38px;\n }\n}\n\n#root :is(div[data-submission-echo], [data-pending-steering]) {\n min-inline-size: 0;\n color: var(--xiaohei-conversation-text);\n}\n\n/* Do not dim the whole row: text and attachments must remain readable while\n * the Host keeps edit/remove/steer disabled until its queue acknowledgement. */\n#root li[data-submission-echo] {\n opacity: 1;\n color: var(--xiaohei-conversation-text);\n background: var(--xiaohei-conversation-user);\n border-color: var(--xiaohei-conversation-edge);\n}\n\n#root [data-submission-echo] [role='status'] {\n color: var(--xiaohei-conversation-text);\n flex-shrink: 0;\n white-space: nowrap;\n}\n\n#root li[data-submission-echo] button:disabled {\n cursor: not-allowed;\n}\n";
|
|
3
|
+
//# sourceMappingURL=conversation-submissions.d.ts.map
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/** Local draft and native submission presentation; Host owns their lifetime. */
|
|
2
|
+
export const XIAOHEI_CONVERSATION_SUBMISSIONS_CSS = `
|
|
3
|
+
#root [data-xiaohei-draft-preview] {
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
align-items: flex-end;
|
|
7
|
+
box-sizing: border-box;
|
|
8
|
+
inline-size: calc(100% - 2 * (var(--dsh-composer-side-clearance, 24px) + 16px));
|
|
9
|
+
max-inline-size: var(--dsh-chat-content-width, 748px);
|
|
10
|
+
margin-inline: auto;
|
|
11
|
+
min-inline-size: 0;
|
|
12
|
+
padding: 4px 0 8px;
|
|
13
|
+
gap: 4px;
|
|
14
|
+
color: var(--xiaohei-conversation-text);
|
|
15
|
+
}
|
|
16
|
+
#root .xiaohei-draft-label {
|
|
17
|
+
font-size: 12px;
|
|
18
|
+
padding-inline: 10px;
|
|
19
|
+
}
|
|
20
|
+
#root .xiaohei-draft-bubble {
|
|
21
|
+
max-inline-size: min(calc(var(--dsh-chat-content-width, 748px) * .702), 82%);
|
|
22
|
+
min-inline-size: 0;
|
|
23
|
+
max-block-size: min(160px, 22dvh);
|
|
24
|
+
overflow: auto;
|
|
25
|
+
white-space: pre-wrap;
|
|
26
|
+
overflow-wrap: anywhere;
|
|
27
|
+
padding: 10px 14px;
|
|
28
|
+
border: 1px dashed var(--xiaohei-conversation-edge);
|
|
29
|
+
border-radius: 18px 9px 18px 18px;
|
|
30
|
+
background: var(--xiaohei-conversation-user);
|
|
31
|
+
font-size: 14px;
|
|
32
|
+
line-height: 1.6;
|
|
33
|
+
}
|
|
34
|
+
#root .xiaohei-draft-bubble:focus-visible {
|
|
35
|
+
outline: 2px solid currentColor;
|
|
36
|
+
outline-offset: 2px;
|
|
37
|
+
}
|
|
38
|
+
@media (width <= 760px) {
|
|
39
|
+
#root [data-xiaohei-draft-preview] {
|
|
40
|
+
padding-inline-end: 38px;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
#root :is(div[data-submission-echo], [data-pending-steering]) {
|
|
45
|
+
min-inline-size: 0;
|
|
46
|
+
color: var(--xiaohei-conversation-text);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* Do not dim the whole row: text and attachments must remain readable while
|
|
50
|
+
* the Host keeps edit/remove/steer disabled until its queue acknowledgement. */
|
|
51
|
+
#root li[data-submission-echo] {
|
|
52
|
+
opacity: 1;
|
|
53
|
+
color: var(--xiaohei-conversation-text);
|
|
54
|
+
background: var(--xiaohei-conversation-user);
|
|
55
|
+
border-color: var(--xiaohei-conversation-edge);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
#root [data-submission-echo] [role='status'] {
|
|
59
|
+
color: var(--xiaohei-conversation-text);
|
|
60
|
+
flex-shrink: 0;
|
|
61
|
+
white-space: nowrap;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
#root li[data-submission-echo] button:disabled {
|
|
65
|
+
cursor: not-allowed;
|
|
66
|
+
}
|
|
67
|
+
`;
|
|
68
|
+
//# sourceMappingURL=conversation-submissions.js.map
|
package/lib/chrome/sidebar.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/** One glass surface over DSH's native sidebar geometry and controls. */
|
|
2
|
-
export declare const XIAOHEI_SIDEBAR_CSS = "\n/* The layout column and SidebarRoot both consume the native sidebar fill.\n * The theme token makes those surfaces transparent; this stable slot\n * relationship removes the layout column's remaining straight divider. */\n#root :has(> [data-slot='sidebar']) {\n background: transparent !important;\n border-right-color: transparent !important;\n}\n\n#root [data-slot='sidebar'] {\n position: relative;\n}\n\n/* Target the native control by its accessible identity, not DOM order.\n * Do not resurrect controls explicitly hidden/disabled by the Host. */\n#root [data-slot='sidebar'] button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F']):not([hidden]):not([disabled]):not([aria-hidden='true']) {\n display: inline-flex !important;\n visibility: visible !important;\n opacity: 1 !important;\n pointer-events: auto !important;\n}\n\n/* Reveal wide navigation only after its column has reached the target width.\n * Keep the toggle itself native. Opacity is applied to content, never the shell\n * (which also hosts fixed-position settings dialogs). */\n@media (prefers-reduced-motion: no-preference) {\n #root [data-xiaohei-sidebar-reveal] [data-xiaohei-sidebar-brand] {\n transition: opacity 100ms ease-out;\n }\n #root [data-xiaohei-sidebar-reveal='waiting'] [data-xiaohei-sidebar-brand] {\n opacity: 0 !important;\n visibility: hidden;\n transition: none;\n }\n}\n\n/* Hide the tree scrollbar's paint, retaining its gutter so rows do not grow\n * into the glass edge. Wheel, touch and keyboard remain native; dialogs and\n * other plugin panels keep their normal scrollbar affordance. */\n#root [data-slot='sidebar.workspaces'] [role='tree'] {\n scrollbar-color: transparent transparent !important;\n}\n\n#root [data-slot='sidebar.workspaces'] [role='tree']::-webkit-scrollbar,\n#root [data-slot='sidebar.workspaces'] [role='tree']::-webkit-scrollbar-thumb,\n#root [data-slot='sidebar.workspaces'] [role='tree']::-webkit-scrollbar-track {\n background: transparent !important;\n border-color: transparent !important;\n box-shadow: none !important;\n}\n\n/* The host shell remains paint- and filter-free because Settings is a fixed\n * descendant. The glass itself lives outside #root in the scene layer. */\n#root [data-slot='sidebar'] > div {\n --dsh-sidebar-inline-padding: 18px;\n position: relative;\n background: transparent !important;\n border-right: 0;\n box-shadow: none;\n}\n\n#dsh-theme-xiaohei\\/sidebar-glass {\n position: absolute;\n box-sizing: border-box;\n left: var(--xiaohei-sidebar-glass-left, 7px);\n top: var(--xiaohei-sidebar-glass-top, 8px);\n width: var(--xiaohei-sidebar-glass-width, 0px);\n height: var(--xiaohei-sidebar-glass-height, 0px);\n pointer-events: none;\n overflow: hidden;\n border: 1px solid var(--xiaohei-sidebar-glass-edge);\n border-radius: var(--xiaohei-sidebar-glass-radius);\n background: var(--xiaohei-sidebar-glass-fill);\n box-shadow:\n inset 0 1px var(--xiaohei-sidebar-glass-highlight),\n inset 1px 0 var(--xiaohei-sidebar-glass-refraction),\n 0 18px 50px -32px var(--xiaohei-sidebar-shadow);\n -webkit-backdrop-filter:\n blur(var(--xiaohei-sidebar-glass-blur))\n saturate(var(--xiaohei-sidebar-glass-saturation));\n backdrop-filter:\n blur(var(--xiaohei-sidebar-glass-blur))\n saturate(var(--xiaohei-sidebar-glass-saturation));\n}\n\n/* Width dragging changes the full-height glass raster every frame. Suspend\n * only the filters while geometry is moving; the translucent surface remains\n * visible and the settled glass returns after the resize gesture ends. */\nhtml[data-xiaohei-sidebar-resizing] #dsh-theme-xiaohei\\/sidebar-glass {\n -webkit-backdrop-filter: none;\n backdrop-filter: none;\n}\n\n/* One restrained inner rim completes the glass edge without tinting content. */\n#dsh-theme-xiaohei\\/sidebar-glass::after {\n content: '';\n position: absolute;\n pointer-events: none;\n inset: 1px;\n border-radius: calc(var(--xiaohei-sidebar-glass-radius) - 1px);\n box-shadow:\n inset 0 1px var(--xiaohei-sidebar-glass-refraction),\n inset 0 -20px 28px -32px var(--xiaohei-sidebar-shadow-soft);\n}\n\n/* The official brand slot owns geometry in both the wide sidebar and rail.\n * The bitmap remains visible as a no-WebGL fallback while the compact\n * MetallicPaint canvas adds a restrained liquid-metal pass above it. */\n.xiaohei-brand-mark {\n position: relative;\n display: inline-grid;\n flex: none;\n place-items: center;\n width: var(--xiaohei-brand-mark-size);\n height: var(--xiaohei-brand-mark-size);\n margin: -2px;\n overflow: visible;\n pointer-events: none;\n filter: drop-shadow(0 2px 3px rgb(8 13 15 / 18%));\n transform: translateY(-1px);\n}\n\n.xiaohei-brand-mark__fallback,\n.xiaohei-brand-mark__metal {\n position: absolute;\n inset: 0;\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n\n.xiaohei-brand-mark__fallback {\n opacity: .94;\n transition: opacity var(--xiaohei-motion-base) ease;\n}\n\n.xiaohei-brand-mark__metal {\n opacity: 0;\n transition:\n opacity var(--xiaohei-motion-base) ease,\n filter var(--xiaohei-motion-base) ease;\n}\n\n.xiaohei-brand-mark[data-metallic-ready='true'] .xiaohei-brand-mark__fallback {\n opacity: .28;\n}\n\n.xiaohei-brand-mark[data-metallic-ready='true'] .xiaohei-brand-mark__metal {\n opacity: .92;\n}\n\n.xiaohei-brand-name {\n white-space: nowrap;\n letter-spacing: .025em;\n font-size: 17px;\n font-weight: 600;\n}\n\n/* ui-conversation currently exposes the Hero mark but not its headline as a\n * slot. Anchor the visual copy to that official mark occupant so hashed Host\n * class names and unrelated headings remain untouched. */\n#root span:has(> .xiaohei-brand-mark[data-brand-context='hero']) + span {\n font-size: 0;\n}\n\n#root span:has(> .xiaohei-brand-mark[data-brand-context='hero']) + span::after {\n content: '\u4E07\u7269\u6709\u7075\uFF0C\u81EA\u5728\u540C\u884C';\n font-size: 26px;\n font-weight: 500;\n line-height: 32px;\n}\n\n#root [data-slot='sidebar'] button:hover .xiaohei-brand-mark__metal {\n filter: brightness(1.12) contrast(1.04);\n}\n\n/* Keep native rail/wide geometry and one consistent control material. */\n#root [data-slot='sidebar'] button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F']),\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='\u65B0\u5EFA\u4F1A\u8BDD'],\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='New session'] {\n color: var(--xiaohei-sidebar-emphasis);\n transition:\n background-color var(--xiaohei-motion-fast) ease,\n border-color var(--xiaohei-motion-fast) ease,\n transform var(--xiaohei-motion-fast) var(--xiaohei-motion-curve);\n}\n\n#root [data-slot='sidebar'] button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F']):hover {\n background: var(--xiaohei-sidebar-hover);\n}\n\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='\u65B0\u5EFA\u4F1A\u8BDD'],\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='New session'] {\n border: 1px solid var(--xiaohei-sidebar-control-edge);\n border-radius: var(--xiaohei-radius-control);\n background: var(--xiaohei-sidebar-control);\n box-shadow: inset 0 1px var(--xiaohei-sidebar-control-highlight);\n justify-content: flex-start;\n gap: 8px;\n padding-inline: 12px;\n text-align: start;\n}\n\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='\u65B0\u5EFA\u4F1A\u8BDD']:hover,\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='New session']:hover {\n border-color: var(--xiaohei-sidebar-control-edge-hover);\n background: var(--xiaohei-sidebar-hover);\n}\n\n/* The footer uses a divider instead of another framed card. */\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F']))\n > :has(> div > [data-slot='sidebar.footer.action']) {\n box-sizing: border-box;\n gap: 2px;\n margin-top: 8px;\n padding-top: 8px;\n border-top: 1px solid var(--xiaohei-sidebar-control-edge);\n}\n\n#root [data-slot='sidebar.footer.action'] > button,\n#root [data-slot='sidebar.settings'] > button {\n color: var(--dsw-alias-label-secondary);\n border-radius: var(--xiaohei-radius-small) !important;\n transition:\n color var(--xiaohei-motion-fast) ease,\n background-color var(--xiaohei-motion-fast) ease,\n transform var(--xiaohei-motion-fast) var(--xiaohei-motion-curve);\n}\n\n#root [data-slot='sidebar.footer.action'] > button:hover,\n#root [data-slot='sidebar.settings'] > button:hover,\n#root [data-slot='sidebar.footer.action'] > button[aria-expanded='true'],\n#root [data-slot='sidebar.settings'] > button[aria-expanded='true'] {\n color: var(--xiaohei-sidebar-emphasis);\n background: var(--xiaohei-sidebar-hover);\n}\n\n#root [data-slot='sidebar.footer.action'] > button:active,\n#root [data-slot='sidebar.settings'] > button:active {\n transform: translateY(1px);\n}\n\n#root [data-slot='sidebar'] button:focus-visible {\n outline: 2px solid var(--xiaohei-sidebar-emphasis);\n outline-offset: 2px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n #root [data-slot='sidebar'] button {\n transition-duration: 0ms !important;\n }\n\n\n .xiaohei-brand-mark__fallback,\n .xiaohei-brand-mark__metal {\n transition-duration: 0ms !important;\n }\n}\n\n@media (prefers-reduced-transparency: reduce) {\n #dsh-theme-xiaohei\\/sidebar-glass {\n background: var(--xiaohei-sidebar-glass-solid);\n -webkit-backdrop-filter: none;\n backdrop-filter: none;\n }\n\n}\n\n@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {\n #dsh-theme-xiaohei\\/sidebar-glass {\n background: var(--xiaohei-sidebar-glass-solid);\n }\n}\n\n@media (forced-colors: active) {\n #dsh-theme-xiaohei\\/sidebar-glass {\n border-color: CanvasText;\n background: Canvas;\n box-shadow: none;\n -webkit-backdrop-filter: none;\n backdrop-filter: none;\n }\n\n #root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='\u65B0\u5EFA\u4F1A\u8BDD'],\n #root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='New session'] {\n border-color: ButtonText;\n }\n\n}\n";
|
|
2
|
+
export declare const XIAOHEI_SIDEBAR_CSS = "\n/* The layout column and SidebarRoot both consume the native sidebar fill.\n * The theme token makes those surfaces transparent; this stable slot\n * relationship removes the layout column's remaining straight divider. */\n#root :has(> [data-slot='sidebar']) {\n background: transparent !important;\n border-right-color: transparent !important;\n}\n\n#root [data-slot='sidebar'] {\n position: relative;\n}\n\n/* Target the native control by its accessible identity, not DOM order.\n * Do not resurrect controls explicitly hidden/disabled by the Host. */\n#root [data-slot='sidebar'] button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F']):not([hidden]):not([disabled]):not([aria-hidden='true']) {\n display: inline-flex !important;\n visibility: visible !important;\n opacity: 1 !important;\n pointer-events: auto !important;\n}\n\n/* Reveal wide navigation only after its column has reached the target width.\n * Keep the toggle itself native. Opacity is applied to content, never the shell\n * (which also hosts fixed-position settings dialogs). */\n@media (prefers-reduced-motion: no-preference) {\n #root [data-xiaohei-sidebar-reveal] [data-xiaohei-sidebar-brand] {\n transition: opacity 100ms ease-out;\n }\n #root [data-xiaohei-sidebar-reveal='waiting'] [data-xiaohei-sidebar-brand] {\n opacity: 0 !important;\n visibility: hidden;\n transition: none;\n }\n}\n\n/* Hide the tree scrollbar's paint, retaining its gutter so rows do not grow\n * into the glass edge. Wheel, touch and keyboard remain native; dialogs and\n * other plugin panels keep their normal scrollbar affordance. */\n#root [data-slot='sidebar.workspaces'] [role='tree'] {\n scrollbar-color: transparent transparent !important;\n}\n\n#root [data-slot='sidebar.workspaces'] [role='tree']::-webkit-scrollbar,\n#root [data-slot='sidebar.workspaces'] [role='tree']::-webkit-scrollbar-thumb,\n#root [data-slot='sidebar.workspaces'] [role='tree']::-webkit-scrollbar-track {\n background: transparent !important;\n border-color: transparent !important;\n box-shadow: none !important;\n}\n\n/* The host shell remains paint- and filter-free because Settings is a fixed\n * descendant. The glass itself lives outside #root in the scene layer. */\n#root [data-slot='sidebar'] > div {\n --dsh-sidebar-inline-padding: 18px;\n position: relative;\n background: transparent !important;\n border-right: 0;\n box-shadow: none;\n}\n\n#dsh-theme-xiaohei\\/sidebar-glass {\n position: absolute;\n box-sizing: border-box;\n left: var(--xiaohei-sidebar-glass-left, 7px);\n top: var(--xiaohei-sidebar-glass-top, 8px);\n width: var(--xiaohei-sidebar-glass-width, 0px);\n height: var(--xiaohei-sidebar-glass-height, 0px);\n pointer-events: none;\n overflow: hidden;\n border: 1px solid var(--xiaohei-sidebar-glass-edge);\n border-radius: var(--xiaohei-sidebar-glass-radius);\n background: var(--xiaohei-sidebar-glass-fill);\n box-shadow:\n inset 0 1px var(--xiaohei-sidebar-glass-highlight),\n inset 1px 0 var(--xiaohei-sidebar-glass-refraction),\n 0 18px 50px -32px var(--xiaohei-sidebar-shadow);\n -webkit-backdrop-filter:\n blur(var(--xiaohei-sidebar-glass-blur))\n saturate(var(--xiaohei-sidebar-glass-saturation));\n backdrop-filter:\n blur(var(--xiaohei-sidebar-glass-blur))\n saturate(var(--xiaohei-sidebar-glass-saturation));\n}\n\n/* Width dragging changes the full-height glass raster every frame. Suspend\n * only the filters while geometry is moving; the translucent surface remains\n * visible and the settled glass returns after the resize gesture ends. */\nhtml[data-xiaohei-sidebar-resizing] #dsh-theme-xiaohei\\/sidebar-glass {\n -webkit-backdrop-filter: none;\n backdrop-filter: none;\n}\n\n/* One restrained inner rim completes the glass edge without tinting content. */\n#dsh-theme-xiaohei\\/sidebar-glass::after {\n content: '';\n position: absolute;\n pointer-events: none;\n inset: 1px;\n border-radius: calc(var(--xiaohei-sidebar-glass-radius) - 1px);\n box-shadow:\n inset 0 1px var(--xiaohei-sidebar-glass-refraction),\n inset 0 -20px 28px -32px var(--xiaohei-sidebar-shadow-soft);\n}\n\n/* The official brand slot owns geometry in both the wide sidebar and rail.\n * The bitmap remains visible as a no-WebGL fallback while the compact\n * MetallicPaint canvas adds a restrained liquid-metal pass above it. */\n.xiaohei-brand-mark {\n position: relative;\n display: inline-grid;\n flex: none;\n place-items: center;\n width: var(--xiaohei-brand-mark-size);\n height: var(--xiaohei-brand-mark-size);\n margin: -2px;\n overflow: visible;\n pointer-events: none;\n filter: drop-shadow(0 2px 3px rgb(8 13 15 / 18%));\n transform: translateY(-1px);\n}\n\n.xiaohei-brand-mark__fallback,\n.xiaohei-brand-mark__metal {\n position: absolute;\n inset: 0;\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n\n.xiaohei-brand-mark__fallback {\n opacity: .94;\n transition: opacity var(--xiaohei-motion-base) ease;\n}\n\n.xiaohei-brand-mark__metal {\n opacity: 0;\n transition:\n opacity var(--xiaohei-motion-base) ease,\n filter var(--xiaohei-motion-base) ease;\n}\n\n.xiaohei-brand-mark[data-metallic-ready='true'] .xiaohei-brand-mark__fallback {\n opacity: .28;\n}\n\n.xiaohei-brand-mark[data-metallic-ready='true'] .xiaohei-brand-mark__metal {\n opacity: .92;\n}\n\n.xiaohei-brand-name {\n white-space: nowrap;\n letter-spacing: .025em;\n font-size: 17px;\n font-weight: 600;\n}\n\n/* ui-conversation currently exposes the Hero mark but not its headline as a\n * slot. Anchor the visual copy to that official mark occupant so hashed Host\n * class names and unrelated headings remain untouched. */\n#root span:has(> .xiaohei-brand-mark[data-brand-context='hero']) + span {\n font-size: 0;\n}\n\n#root span:has(> .xiaohei-brand-mark[data-brand-context='hero']) + span::after {\n content: '\u4E07\u7269\u6709\u7075\uFF0C\u81EA\u5728\u540C\u884C';\n font-size: 26px;\n font-weight: 500;\n line-height: 32px;\n}\n\n#root [data-slot='sidebar'] button:hover .xiaohei-brand-mark__metal {\n filter: brightness(1.12) contrast(1.04);\n}\n\n/* Keep native rail/wide geometry and one consistent control material. */\n#root [data-slot='sidebar'] button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F']),\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='\u65B0\u5EFA\u4F1A\u8BDD'],\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='New session'] {\n color: var(--xiaohei-sidebar-emphasis);\n transition:\n background-color var(--xiaohei-motion-fast) ease,\n border-color var(--xiaohei-motion-fast) ease,\n transform var(--xiaohei-motion-fast) var(--xiaohei-motion-curve);\n}\n\n#root [data-slot='sidebar'] button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F']):hover {\n background: var(--xiaohei-sidebar-hover);\n}\n\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='\u65B0\u5EFA\u4F1A\u8BDD'],\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='New session'] {\n border: 1px solid var(--xiaohei-sidebar-control-edge);\n border-radius: var(--xiaohei-radius-control);\n background: var(--xiaohei-sidebar-control);\n box-shadow: inset 0 1px var(--xiaohei-sidebar-control-highlight);\n justify-content: flex-start;\n gap: 8px;\n padding-inline: 12px;\n text-align: start;\n}\n\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='\u65B0\u5EFA\u4F1A\u8BDD']:hover,\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='New session']:hover {\n border-color: var(--xiaohei-sidebar-control-edge-hover);\n background: var(--xiaohei-sidebar-hover);\n}\n\n/* rc.2 renders footer contributions in a horizontal flex row. Stack only\n * this slot and its immediate host so full-width actions cannot displace\n * siblings. Leave settings, plugin interiors, hidden states and order alone.\n * This is also idempotent with Desktop's column-layout compatibility patch. */\n#root [data-slot='sidebar'] :has(> [data-slot='sidebar.footer.action']),\n#root [data-slot='sidebar'] [data-slot='sidebar.footer.action'] {\n flex-direction: column;\n align-items: stretch;\n min-width: 0;\n max-width: 100%;\n gap: 4px;\n}\n\n#root [data-slot='sidebar'] [data-slot='sidebar.footer.action'] > * {\n box-sizing: border-box;\n flex: 0 0 auto;\n min-width: 0;\n max-width: 100%;\n}\n\n/* The footer uses a divider instead of another framed card. */\n#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F']))\n > :has(> div > [data-slot='sidebar.footer.action']) {\n box-sizing: border-box;\n gap: 2px;\n margin-top: 8px;\n padding-top: 8px;\n border-top: 1px solid var(--xiaohei-sidebar-control-edge);\n}\n\n#root [data-slot='sidebar.footer.action'] > button,\n#root [data-slot='sidebar.settings'] > button {\n color: var(--dsw-alias-label-secondary);\n border-radius: var(--xiaohei-radius-small) !important;\n transition:\n color var(--xiaohei-motion-fast) ease,\n background-color var(--xiaohei-motion-fast) ease,\n transform var(--xiaohei-motion-fast) var(--xiaohei-motion-curve);\n}\n\n#root [data-slot='sidebar.footer.action'] > button:hover,\n#root [data-slot='sidebar.settings'] > button:hover,\n#root [data-slot='sidebar.footer.action'] > button[aria-expanded='true'],\n#root [data-slot='sidebar.settings'] > button[aria-expanded='true'] {\n color: var(--xiaohei-sidebar-emphasis);\n background: var(--xiaohei-sidebar-hover);\n}\n\n#root [data-slot='sidebar.footer.action'] > button:active,\n#root [data-slot='sidebar.settings'] > button:active {\n transform: translateY(1px);\n}\n\n#root [data-slot='sidebar'] button:focus-visible {\n outline: 2px solid var(--xiaohei-sidebar-emphasis);\n outline-offset: 2px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n #root [data-slot='sidebar'] button {\n transition-duration: 0ms !important;\n }\n\n\n .xiaohei-brand-mark__fallback,\n .xiaohei-brand-mark__metal {\n transition-duration: 0ms !important;\n }\n}\n\n@media (prefers-reduced-transparency: reduce) {\n #dsh-theme-xiaohei\\/sidebar-glass {\n background: var(--xiaohei-sidebar-glass-solid);\n -webkit-backdrop-filter: none;\n backdrop-filter: none;\n }\n\n}\n\n@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {\n #dsh-theme-xiaohei\\/sidebar-glass {\n background: var(--xiaohei-sidebar-glass-solid);\n }\n}\n\n@media (forced-colors: active) {\n #dsh-theme-xiaohei\\/sidebar-glass {\n border-color: CanvasText;\n background: Canvas;\n box-shadow: none;\n -webkit-backdrop-filter: none;\n backdrop-filter: none;\n }\n\n #root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='\u65B0\u5EFA\u4F1A\u8BDD'],\n #root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='\u6536\u8D77\u4FA7\u8FB9\u680F'])) > button[aria-label='New session'] {\n border-color: ButtonText;\n }\n\n}\n";
|
|
3
3
|
//# sourceMappingURL=sidebar.d.ts.map
|
package/lib/chrome/sidebar.js
CHANGED
|
@@ -209,6 +209,26 @@ html[data-xiaohei-sidebar-resizing] #dsh-theme-xiaohei\\/sidebar-glass {
|
|
|
209
209
|
background: var(--xiaohei-sidebar-hover);
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
+
/* rc.2 renders footer contributions in a horizontal flex row. Stack only
|
|
213
|
+
* this slot and its immediate host so full-width actions cannot displace
|
|
214
|
+
* siblings. Leave settings, plugin interiors, hidden states and order alone.
|
|
215
|
+
* This is also idempotent with Desktop's column-layout compatibility patch. */
|
|
216
|
+
#root [data-slot='sidebar'] :has(> [data-slot='sidebar.footer.action']),
|
|
217
|
+
#root [data-slot='sidebar'] [data-slot='sidebar.footer.action'] {
|
|
218
|
+
flex-direction: column;
|
|
219
|
+
align-items: stretch;
|
|
220
|
+
min-width: 0;
|
|
221
|
+
max-width: 100%;
|
|
222
|
+
gap: 4px;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
#root [data-slot='sidebar'] [data-slot='sidebar.footer.action'] > * {
|
|
226
|
+
box-sizing: border-box;
|
|
227
|
+
flex: 0 0 auto;
|
|
228
|
+
min-width: 0;
|
|
229
|
+
max-width: 100%;
|
|
230
|
+
}
|
|
231
|
+
|
|
212
232
|
/* The footer uses a divider instead of another framed card. */
|
|
213
233
|
#root [data-slot='sidebar'] > div:has(button:is([aria-label='Collapse sidebar'], [aria-label='收起侧边栏']))
|
|
214
234
|
> :has(> div > [data-slot='sidebar.footer.action']) {
|
package/lib/chrome.js
CHANGED
|
@@ -4,6 +4,7 @@ import { XIAOHEI_COMPOSER_SEND_HEIXIU_CSS } from './chrome/composer-send-heixiu.
|
|
|
4
4
|
import { XIAOHEI_CONTROL_PRIMITIVES_CSS } from './chrome/controls.js';
|
|
5
5
|
import { XIAOHEI_CONVERSATION_CSS } from './chrome/conversation.js';
|
|
6
6
|
import { XIAOHEI_CONVERSATION_MESSAGES_CSS } from './chrome/conversation-messages.js';
|
|
7
|
+
import { XIAOHEI_CONVERSATION_SUBMISSIONS_CSS } from './chrome/conversation-submissions.js';
|
|
7
8
|
import { XIAOHEI_FRAME_SYSTEM_CSS } from './chrome/frames.js';
|
|
8
9
|
import { XIAOHEI_IDENTITY_CSS } from './chrome/identity.js';
|
|
9
10
|
import { XIAOHEI_OVERLAY_CSS } from './chrome/overlays.js';
|
|
@@ -25,6 +26,7 @@ export const XIAOHEI_CHROME_CSS = [
|
|
|
25
26
|
XIAOHEI_WORKSPACE_CSS,
|
|
26
27
|
XIAOHEI_CONVERSATION_CSS,
|
|
27
28
|
XIAOHEI_CONVERSATION_MESSAGES_CSS,
|
|
29
|
+
XIAOHEI_CONVERSATION_SUBMISSIONS_CSS,
|
|
28
30
|
XIAOHEI_COMPOSER_CSS,
|
|
29
31
|
XIAOHEI_COMPOSER_SEND_HEIXIU_CSS,
|
|
30
32
|
XIAOHEI_OVERLAY_CSS,
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
window.__ModuleLoader__.load({ id: "@lemoncat7/dsh-theme-xiaohei", chunk: "client.decorations.js", factory: (require) => { var module = { exports: {} }; var exports = module.exports;
|
|
2
|
+
"use strict";var Q=Object.defineProperty;var Re=Object.getOwnPropertyDescriptor;var Ae=Object.getOwnPropertyNames;var Ie=Object.prototype.hasOwnProperty;var Te=(e,r)=>{for(var t in r)Q(e,t,{get:r[t],enumerable:!0})},_e=(e,r,t,i)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of Ae(r))!Ie.call(e,o)&&o!==t&&Q(e,o,{get:()=>r[o],enumerable:!(i=Re(r,o))||i.enumerable});return e};var ke=e=>_e(Q({},"__esModule",{value:!0}),e);var De={};Te(De,{installDecorations:()=>Se});module.exports=ke(De);var B=new WeakMap;function oe(e,r){let t=e.defaultView;if(e.body===void 0||t===null||typeof t.MutationObserver!="function")return()=>{};let i=B.get(e);if(i===void 0){let a=new Set,n={listeners:a,queued:!1},d=()=>{if(n.queued=!1,delete n.frame,B.get(e)===n)for(let s of[...a])try{s()}catch(l){t.setTimeout(()=>{throw l},0)}};n.observer=new t.MutationObserver(()=>{n.queued||(n.queued=!0,typeof t.requestAnimationFrame=="function"?n.frame=t.requestAnimationFrame(d):queueMicrotask(d))}),n.observer.observe(e.body,{childList:!0,subtree:!0}),B.set(e,n),i=n}i.listeners.add(r);let o=!0;return()=>{if(!o)return;o=!1;let a=B.get(e);a!==void 0&&(a.listeners.delete(r),!(a.listeners.size>0)&&(a.observer?.disconnect(),a.frame!==void 0&&t.cancelAnimationFrame(a.frame),B.delete(e)))}}var U="[data-slot='sidebar']",ee={sidebar:U,sidebarShell:`#root ${U} > div`,sidebarColumn:`#root :has(> ${U})`,composerCard:"#root [data-composer-card='true']",composerHeroMark:"#root .xiaohei-brand-mark[data-brand-context='hero']",composerHeroRow:"[class*='_headline']"};var se="dsh-theme-xiaohei/scene-layer";var W={pose:"hidden",left:0,top:0,width:0,height:0},te=.71,ce=.63,He=.44;function de(e){let{sidebar:r,scroll:t,flow:i,viewportWidth:o,viewportHeight:a,controls:n}=e,d=Math.min(r.bottom,a)-148,s=Math.max(r.top+24,96);if(d-s<130||r.right>i.left)return W;let l=i.right+56,f=Math.min(250,t.right-l-20,(d-s)*te,340*te);if(f>=190){let u=f/te;return{pose:"seated",left:t.right-f-16,top:s+(d-s-u)*.6,width:f,height:u}}let c=o>760?52:0,m=i.left-c-r.right;if(m>=66){let u=Math.min(104,m-12,(d-s)*ce),_=u/ce;return{pose:"peek",left:r.right-6,top:s+Math.min(160,(d-s-_)*.5),width:u,height:_}}if(r.right-r.left>100)return W;let p=r.left+7,h=Math.min(60,i.left-c-p-10);if(h<40)return W;let g=h/He,v=n.filter(u=>u.right>p&&u.left<p+h).map(u=>({start:Math.max(s,u.top-12),end:Math.min(d,u.bottom+12)})).filter(u=>u.end>u.start).sort((u,_)=>u.start-_.start),b=s,E={start:s,end:s};for(let u of[...v,{start:d,end:d}])u.start-b>E.end-E.start&&(E={start:b,end:u.start}),b=Math.max(b,u.end);return E.end-E.start<g+12?W:{pose:"halfpeek",left:p,top:E.start+(E.end-E.start-g)*.45,width:h,height:g}}function le(e,r){let t="seated",i=e.now(),o,a=!0,n=!1,d=()=>{o!==void 0&&e.clearTimeout(o),o=void 0},s=c=>{c!==t&&(t=c,r(c))},l=()=>{if(d(),a||n||t==="doze")return;let c=t==="seated"?3e4:18e4;o=e.setTimeout(f,Math.max(1,i+c-e.now()))};function f(){if(o=void 0,a||n)return;let c=e.now()-i;s(c>=18e4?"doze":c>=3e4?"chin":"seated"),l()}return{get pose(){return t},activity(){if(a||n)return;let c=e.now();t==="seated"&&c-i<1e3||(i=c,t!=="seated"&&(s("seated"),l()))},setPaused(c){n||c===a||(a=c,d(),i=e.now(),s("seated"),a||l())},dispose(){n=!0,d()}}}var Y=["seated","peek","chin","doze","halfpeek"];function Le(e){let r=new Map;function t(i){let o=r.get(i);return o||(o=Promise.resolve().then(()=>e(i)).catch(a=>{throw r.delete(i),a}),r.set(i,o)),o}return{async pose(i,o){return(await t(`./client.pose-${i}-${o}.js`)).image},async rig(i,o){return i==="doze"||!Y.includes(i)?void 0:(await t(`./client.rig-${i}-${o}.js`)).rig}}}var G=Le(e=>require.async(e));function ue(e,r,t=Math.random){let i,o=!1,a="",n,d=0,s=0,l=()=>{i!==void 0&&e.clearTimeout(i),i=void 0};function f(){a="",r(void 0,0),n&&!o&&(i=e.setTimeout(m,2800+t()*2800))}function c(p){let h=n?.[p];if(!h||o)return;l(),a=p;let g=e.performance.now(),v=()=>{if(i=void 0,!n||o)return;let b=Math.min(1,(e.performance.now()-g)/h.duration);if(r(a,b),b>=1){f();return}i=e.setTimeout(v,1e3/60)};v()}function m(){if(i=void 0,!n||o)return;let p=Object.keys(n).filter(v=>v!=="blink"&&v!=="attention"),h=p.filter(v=>v.startsWith("ear")),g=h.length&&d>=2?h[s++%h.length]:t()<.72&&n.blink||!p.length?"blink":p[Math.floor(t()*p.length)];g.startsWith("ear")?d=0:d++,c(g)}return{setClips(p){o||p===n||(l(),n=p,a="",d=0,s=0,r(void 0,0),n&&(i=e.setTimeout(m,1200+t()*800)))},attention(){a||c("attention")},dispose(){o=!0,l(),n=void 0,r(void 0,0)}}}var he=e=>{let r=Math.max(0,Math.min(1,e));return r*r*(3-2*r)};function ne(e){return e<=0||e>=1?0:e<.3?he(e/.3):e<.4?1:1-he((e-.4)/.6)}function me(e){return ne((e-.12)/.16)}var re={seated:[{left:[285,223],right:[326,224],upper:[302,188],lower:[310,276],iris:[309,230,13,20,0],skin:[315,258]},{left:[373,221],right:[421,226],upper:[387,186],lower:[393,277],iris:[393,228,15,22,0],skin:[391,261]}],peek:[{left:[80,214],right:[119,221],upper:[103,186],lower:[91,267],iris:[102,225,14,20,.25],skin:[110,253]},{left:[171,252],right:[210,265],upper:[195,221],lower:[175,300],iris:[186,260,15,20,.4],skin:[186,288]}],chin:[{left:[252,252],right:[290,247],upper:[266,223],lower:[287,297],iris:[278,258,14,19,-.3],skin:[291,285]},{left:[339,234],right:[387,227],upper:[358,196],lower:[365,280],iris:[361,235,15,21,-.25],skin:[367,269]}],halfpeek:[{left:[89,390],right:[159,395],upper:[116,337],lower:[110,471],iris:[116,401,23,30,.22],skin:[117,445]}]};function V(e,r){if(!Number.isFinite(e)||!Number.isFinite(r))return[0,0];let t=Math.max(1,Math.hypot(e,r));return[e/t,r/t]}function ie(e,r){let t=Math.max(0,Math.min(1,r)),i=(e.left[1]+e.right[1])/2,o=(e.lower[1]-i)*.24,a=[(e.left[0]+e.right[0])/2,i+o+(e.right[0]-e.left[0])*.18],n=d=>[d[0]+(a[0]-d[0])*t,d[1]+(a[1]-d[1])*t];return{upper:n(e.upper),lower:n(e.lower),left:[e.left[0],e.left[1]+o*t],right:[e.right[0],e.right[1]+o*t]}}function J(e,r,t){let i=0,o=1;for(let d=0;d<14;d++){let s=(i+o)/2,l=1-s;l*l*e.left[0]+2*l*s*r[0]+s*s*e.right[0]<t?i=s:o=s}let a=(i+o)/2,n=1-a;return n*n*e.left[1]+2*n*a*r[1]+a*a*e.right[1]}function fe(e,r,t){let i=Math.floor(t.left[0]-9),o=Math.ceil(t.right[0]+9),a=Math.floor(Math.min(t.upper[1],t.left[1],t.right[1])-5),n=Math.ceil(Math.max(t.lower[1],t.left[1],t.right[1])+5),d=o-i,s=n-a,l=()=>{let y=e.createElement("canvas");return y.width=d,y.height=s,y},f=l(),c=l(),m=l(),p=f.getContext("2d"),h=c.getContext("2d"),g=m.getContext("2d"),v=r.getImageData(0,0,r.canvas.width,r.canvas.height),b=(y,w)=>{let M=(Math.max(0,Math.min(v.height-1,Math.round(w/2)))*v.width+Math.max(0,Math.min(v.width-1,Math.round(y/2))))*4;return[v.data[M],v.data[M+1],v.data[M+2]]},E=b(...t.skin),u=p.createImageData(d,s),_=h.createImageData(d,s),k=y=>y.every((w,M)=>Math.abs(w-E[M])<25),z=(y,w,M)=>{if(k(M))return M;let P=[E[0]*.05,E[1]*.05,E[2]*.05],A=.05;for(let x of[6,12,20,30])for(let D=0;D<8;D++){let C=b(y+Math.cos(D*Math.PI/4)*x,w+Math.sin(D*Math.PI/4)*x);if(!k(C))continue;let H=1/x;A+=H;for(let T=0;T<3;T++)P[T]+=C[T]*H}return P.map(x=>Math.round(x/A))};for(let y=0;y<d;y++){let w=i+y,M=J(t,t.upper,w);for(let P=0;P<s;P++){let A=a+P,x=b(w,A),D=(P*d+y)*4,C=1-(x[0]+x[1]+x[2])/Math.max(1,E[0]+E[1]+E[2]),H=x[1]>x[0]*1.15&&x[1]>x[2]*1.12,q=A>=M-12&&A<=M+3&&!H?Math.max(0,Math.min(1,(C-.3)/.35)):0;u.data.set([...x,Math.round(q*255)],D),_.data.set([...z(w,A,x),255],D)}}p.putImageData(u,0,0),h.putImageData(_,0,0);let I=g.createImageData(d,s);for(let y=0;y<u.data.length;y+=4)I.data[y+3]=u.data[y+3]>4?255:0;g.putImageData(I,0,0);let R=l(),S=R.getContext("2d");for(let[y,w]of[[0,0],[-1,0],[1,0],[0,-1],[0,1]])S.drawImage(m,y,w);return g.drawImage(R,0,0),g.translate(-i,-a),g.beginPath(),g.moveTo(t.left[0]-7,t.left[1]),g.quadraticCurveTo(t.upper[0],t.upper[1]-4,t.right[0]+7,t.right[1]),g.quadraticCurveTo(t.lower[0],t.lower[1]+20,t.left[0]-7,t.left[1]),g.closePath(),g.fill(),h.globalCompositeOperation="destination-in",h.filter="blur(0.65px)",h.drawImage(m,0,0),h.filter="none",{ink:f,skin:c,left:i,top:a,width:d,height:s}}function pe(e,r,t){let i=e.canvas.ownerDocument,o=i.createElement("canvas");o.width=r.width,o.height=r.height;let a=o.getContext("2d",{willReadFrequently:!0});a.drawImage(r,0,0);let n=f=>{let c=a.getImageData(Math.round(f[0]/2),Math.round(f[1]/2),1,1).data;return[c[0],c[1],c[2]]},d=f=>`rgb(${f.map(c=>Math.round(c)).join(" ")})`,s=t.map(f=>{let[c,m,p,h,g]=f.iris,v=i.createElement("canvas");v.width=Math.ceil(p*2+4),v.height=Math.ceil(h*2+4);let b=v.getContext("2d");return b.translate(v.width/2,v.height/2),b.rotate(g),b.beginPath(),b.ellipse(0,0,p,h,0,0,Math.PI*2),b.clip(),b.rotate(-g),b.drawImage(r,0,0,r.width,r.height,-c,-m,r.width*2,r.height*2),{eye:f,iris:v,skin:n(f.skin),material:fe(i,a,f)}});function l(f,c){let{upper:m,lower:p,left:h,right:g}=ie(f,c);e.beginPath(),e.moveTo(...h),e.quadraticCurveTo(...m,...g),e.quadraticCurveTo(...p,...h),e.closePath()}return(f,c)=>{let[m,p]=V(...f);e.save(),e.scale(.5,.5);for(let{eye:h,iris:g,skin:v,material:b}of s){let[E,u,_,k]=h.iris;if(e.save(),e.drawImage(b.skin,b.left,b.top),e.save(),l(h,0),e.clip(),c<.999){e.save(),l(h,c),e.clip();let I=e.createLinearGradient(0,u-k,0,u+k),S=(v[0]+v[1]+v[2])/765>.65?[255,253,241]:[166,185,193];I.addColorStop(0,d(S.map(M=>M*.83))),I.addColorStop(.5,d(S)),e.fillStyle=I,e.fillRect(E-70,u-70,140,140);let y=m*_*.26,w=p*k*.13;e.drawImage(g,E-g.width/2+y,u-g.height/2+w),e.restore()}e.restore();let z=ie(h,c);for(let I=0;I<b.width;I++){let R=b.left+I,S=J({...h,left:z.left,right:z.right},z.upper,R)-J(h,h.upper,R);e.drawImage(b.ink,I,0,1,b.height,R,b.top+S,1,b.height)}e.restore()}e.restore()}}var F=[[284,328],[310,347],[324,373],[319,398],[307,423],[307,448],[319,464]];function ge(e,r,t,i){let o=Math.max(1,t-r),a=Math.max(0,Math.min(1,(t-e)/o));return a===0?0:Math.sin(i)*Math.min(20,o*.55)*a*a}function be(e,r){return e.reduce((t,i,o)=>{let a=t[o-1],n=(a?.angle??0)+(r[o]??0);if(!a)t.push({x:i[0],y:i[1],angle:n});else{let d=e[o-1],s=i[0]-d[0],l=i[1]-d[1],f=Math.cos(a.angle),c=Math.sin(a.angle);t.push({x:a.x+s*f-l*c,y:a.y+s*c+l*f,angle:n})}return t},[])}function we(e,r,t=F){let i=1/0,o=0,a=0;for(let n=0;n<t.length-1;n++){let d=t[n],s=t[n+1],l=s[0]-d[0],f=s[1]-d[1],c=Math.max(0,Math.min(1,((e-d[0])*l+(r-d[1])*f)/(l*l+f*f))),m=(e-d[0]-l*c)**2+(r-d[1]-f*c)**2;m<i&&(i=m,o=n,a=c)}return{x:e,y:r,bone:o,weight:a}}function ve(e,r,t=F){let i=0,o=0;for(let a=0;a<2;a++){let n=e.bone+a,d=t[n],s=r[n],l=a?e.weight:1-e.weight,f=e.x-d[0],c=e.y-d[1],m=Math.cos(s.angle),p=Math.sin(s.angle);i+=l*(s.x+f*m-c*p),o+=l*(s.y+f*p+c*m)}return[i,o]}function ae(e,r,t){let i=Math.max(0,Math.min(1,e)),o=Math.sin(Math.PI*i)**2;return Array.from({length:r},(a,n)=>o*(t?n?.12:0:.32)*Math.sin(i*Math.PI*(t?3:4)-n*(t?.65:1.1)))}function ye(e,r,t,i=[]){let o=t.get(r.layers.body.src),a=o?pe(e,o,i):void 0,n=r.layers.tail,d=[],s=[];if(n){let[c,m,p,h]=n.box,g=Math.ceil((p-c)/10),v=Math.ceil((h-m)/10);for(let b=0;b<=v;b++)for(let E=0;E<=g;E++)d.push(we(c+(p-c)*E/g,m+(h-m)*b/v));for(let b=0;b<v;b++)for(let E=0;E<g;E++){let u=b*(g+1)+E;s.push([u,u+1,u+g+1],[u+1,u+g+2,u+g+1])}}function l(c){let m=r.layers[c],p=m&&t.get(m.src);if(m&&p){let[h,g,v,b]=m.box;e.drawImage(p,h,g,v-h,b-g)}}function f(c){if(!n)return;let m=t.get(n.src);if(!m)return;if(c<=0||c>=1){l("tail");return}let p=be(F,ae(c,F.length,!0)),h=d.map(b=>ve(b,p)),[g,v]=n.box;for(let b of s){let[E,u,_]=b,k=d[E],z=d[u],I=d[_],R=h[E],S=h[u],y=h[_],w=z.x-k.x,M=z.y-k.y,P=I.x-k.x,A=I.y-k.y,x=w*A-M*P,D=((S[0]-R[0])*A-(y[0]-R[0])*M)/x,C=((S[1]-R[1])*A-(y[1]-R[1])*M)/x,H=((y[0]-R[0])*w-(S[0]-R[0])*P)/x,T=((y[1]-R[1])*w-(S[1]-R[1])*P)/x;e.save(),e.beginPath();let q=(R[0]+S[0]+y[0])/3,O=(R[1]+S[1]+y[1])/3;[R,S,y].forEach((L,$)=>{let X=L[0]-q,j=L[1]-O,N=1+1.2/Math.max(1,Math.hypot(X,j));$?e.lineTo(q+X*N,O+j*N):e.moveTo(q+X*N,O+j*N)}),e.closePath(),e.clip(),e.transform(D,C,H,T,R[0]-D*(k.x-g)-H*(k.y-v),R[1]-C*(k.x-g)-T*(k.y-v)),e.drawImage(m,0,0),e.restore()}}return(c,m,p=[0,0])=>{e.clearRect(0,0,r.size[0],r.size[1]);let h=c==="attention"?Math.max(0,Math.min(1,(m-.03)/.65)):m,g=ae(h,r.ears.length,!1);r.ears.forEach(([,b],E)=>{let u=r.layers["ear"+E],_=u&&t.get(u.src);if(!u||!_)return;let k=c==="attention"||c==="ear"+E?g[E]:0;if(Math.abs(k)<1e-8){l("ear"+E);return}let[z,I,R,S]=u.box;for(let y=0;y<_.height;y++){let w=I+y*(S-I)/_.height;e.drawImage(_,0,y,_.width,1,z+ge(w,I,b,k),w,R-z,(S-I)/_.height)}}),l("body"),f(c==="attention"?Math.max(0,Math.min(1,(m-.22)/.78)):c==="tail"?m:0);let v=c==="blink"?ne(m):c==="attention"?me(m):0;a?.(p,v)}}function Ee(e,r){let t=[0,0],i=[0,0],o,a=0,n=!1;function d(l){if(o=void 0,n)return;let f=Math.min(64,Math.max(0,l-a));a=l;let c=1-Math.exp(-f/95);t=[t[0]+(i[0]-t[0])*c,t[1]+(i[1]-t[1])*c];let m=Math.hypot(t[0]-i[0],t[1]-i[1])<.001;m&&(t=i),r(t),m||(o=e.requestAnimationFrame(d))}function s(){o!==void 0&&e.cancelAnimationFrame(o),o=void 0}return{target(l,f){n||(i=V(l,f),o===void 0&&Math.hypot(t[0]-i[0],t[1]-i[1])>=.001&&(a=e.performance.now(),o=e.requestAnimationFrame(d)))},reset(){s(),i=t=[0,0],r(t)},dispose(){n=!0,s()}}}function Ce(e){let r=e.defaultView,t=r.matchMedia("(prefers-reduced-motion: reduce)"),i=new Map,o=new Map,a=!1,n,d,s,l,f="",c="",m=0,p=!1,h=0,g="",v,b=-1/0,E=[0,0],u,_=0,k,z=()=>{l&&n&&(l(u,_,E),n.dataset.motion=u??"rig-rest")},I=Ee(r,C=>{E=C,z()}),R=()=>{v!==void 0&&r.clearTimeout(v),v=void 0};function S(C){if(o.has(C))return o.get(C);if(i.has(C))return Promise.resolve();let H=new r.Image;H.src=C;let T=H.decode().then(()=>{a||i.set(C,H)},()=>{}).finally(()=>o.delete(C));return o.set(C,T),T}let y=ue(r,(C,H)=>{!s||!n||!l||(u=C,_=H,z())});function w(){if(a)return;let C=e.documentElement.dataset.xiaoheiAppearance==="light"?"light":"dark",H=e.documentElement.hasAttribute("data-xiaohei-sidebar-resizing"),T=!e.hidden&&!t.matches&&!H&&n?`${f}-${C}`:"";if(T===g&&c===C)return;g=T,R(),l=void 0,y.setClips(void 0),I.reset(),k=void 0,u=void 0,_=0;let q=++m;if(s?.remove(),s=void 0,n&&(n.dataset.motion="rest"),d=void 0,c=C,p=!1,!T||!n)return;let O=n;G.rig(f,C).then(async L=>{if(!L||a||q!==m||(await Promise.all(Object.values(L.layers).map(X=>S(X.src))),a||q!==m||Object.values(L.layers).some(X=>!i.get(X.src))))return;d=L,s=e.createElement("canvas"),s.className="xiaohei-character-motion",s.width=L.size[0],s.height=L.size[1];let $=s.getContext("2d");if(!$){s=void 0;return}O.append(s),l=ye($,L,i,re[f]),y.setClips({blink:{duration:280},...Object.fromEntries(L.ears.map((X,j)=>["ear"+j,{duration:1050}])),...L.layers.tail?{tail:{duration:2400}}:{},attention:{duration:2400}})}).catch(()=>{})}let M=C=>{if(!n||!l||C.pointerType!=="mouse")return;let H=r.performance.now();(!k||H-h>=100)&&(k=n.getBoundingClientRect(),h=H);let T=k,q=re[f];if(d&&q?.length){let L=Math.min(T.width/d.size[0],T.height/d.size[1]),$=q.reduce((Z,K)=>Z+K.iris[0],0)/q.length/2,X=q.reduce((Z,K)=>Z+K.iris[1],0)/q.length/2,j=T.left+$*L,N=T.top+(T.height-d.size[1]*L)/2+X*L;I.target((C.clientX-j)/Math.max(220,r.innerWidth*.32),(C.clientY-N)/Math.max(180,r.innerHeight*.32))}let O=C.clientX>=T.left-70&&C.clientX<=T.right+70&&C.clientY>=T.top-50&&C.clientY<=T.bottom+50;if(O||R(),O&&!p&&H-b>6e3){let L=m;v=r.setTimeout(()=>{v=void 0,!a&&p&&L===m&&(b=r.performance.now(),y.attention())},180)}p=O};t.addEventListener("change",w);let P=()=>{I.target(0,0),p=!1,R()},A=C=>{C.relatedTarget||P()},x=()=>{k=void 0};e.addEventListener("pointerout",A),r.addEventListener("blur",P),r.addEventListener("resize",x),e.addEventListener("visibilitychange",w),e.addEventListener("pointermove",M,{passive:!0});let D=new r.MutationObserver(w);return D.observe(e.documentElement,{attributes:!0,attributeFilter:["data-xiaohei-appearance","data-xiaohei-sidebar-resizing"]}),{setPose(C,H){(C!==n||f!==H)&&(R(),m++,g="",l=void 0,y.setClips(void 0),I.reset(),k=void 0,s?.remove(),s=void 0,d=void 0,n&&(n.dataset.motion="rest")),n=C,f=H,w()},dispose(){a=!0,R(),m++,y.dispose(),I.dispose(),s?.remove(),l=void 0,i.clear(),o.clear(),n&&(n.dataset.motion="rest"),t.removeEventListener("change",w),D.disconnect(),e.removeEventListener("visibilitychange",w),e.removeEventListener("pointermove",M),e.removeEventListener("pointerout",A),r.removeEventListener("blur",P),r.removeEventListener("resize",x)}}}var Me="dsh-theme-xiaohei/wallpaper-character";function xe(e=typeof document>"u"?void 0:document,r=G.pose){let t=e?.defaultView;if(!e||!t)return()=>{};let i=!1,o,a,n,d=[],s=!0,l={pose:"hidden",left:0,top:0,width:0,height:0},f=new Map,c=new Set,m=new Set,p=typeof t.matchMedia=="function"?Ce(e):void 0,h=le({now:()=>t.performance.now(),setTimeout:(w,M)=>t.setTimeout(w,M),clearTimeout:w=>t.clearTimeout(w)},()=>u()),g=new WeakMap,v=typeof t.ResizeObserver=="function"?new t.ResizeObserver(w=>{for(let M of w){let P=g.get(M.target),A=M.contentRect.width,x=M.contentRect.height;g.set(M.target,{width:A,height:x}),(!P||P.width!==A||M.target===d[0]&&P.height!==x)&&(s=!0)}s&&(u(),_())}):void 0;function b(){if(i||!e)return;if(e.documentElement?.hasAttribute("data-xiaohei-sidebar-resizing")){s=!0,n&&n.dataset.pose!=="hidden"&&(n.dataset.pose="hidden"),h.setPaused(!0),p?.setPose(void 0,"hidden"),_();return}let w=e.getElementById(se),M=[e.querySelector(ee.sidebarShell),e.querySelector("[data-conversation-scroll]"),e.querySelector("[data-chat-flow]"),e.querySelector(ee.composerCard)];if(M.some((O,L)=>O!==d[L])){d=M,v?.disconnect();for(let O of d)O&&v?.observe(O);s=!0}if(!w){n?.remove(),n=void 0,h.setPaused(!0),p?.setPose(void 0,"hidden");return}if(!n||n.parentElement!==w){n?.remove(),e.getElementById(Me)?.remove(),n=e.createElement("div"),n.id=Me,n.className="xiaohei-wallpaper-character",n.setAttribute("aria-hidden","true"),n.dataset.pose="hidden";for(let O of Y){let L=e.createElement("span");L.className=`xiaohei-wallpaper-character__${O}`,n.append(L)}w.append(n),s=!0}if(!s){E();return}s=!1;let[P,A,x,D]=d;if(!P||!A||!D){l={...l,pose:"hidden"},E();return}let C=P.getBoundingClientRect(),H=C.width<100?[...P.querySelectorAll('button,a,input,[role="button"],[role="treeitem"]')].map(O=>O.getBoundingClientRect()).filter(O=>O.width>0&&O.height>0):[],T=D.getBoundingClientRect(),q=x?.getBoundingClientRect()??{left:T.left+16,right:T.right-16,top:0,bottom:0};l=de({sidebar:C,scroll:A.getBoundingClientRect(),flow:q,viewportWidth:t.innerWidth,viewportHeight:t.innerHeight,controls:H}),E()}function E(){if(!n||i)return;h.setPaused(e.hidden||l.pose!=="seated");let w=e.hidden?"hidden":l.pose==="seated"?h.pose:l.pose;if(w==="hidden"){n.dataset.pose!=="hidden"&&(n.dataset.pose="hidden"),p?.setPose(void 0,"hidden");return}let M=e.documentElement.dataset.xiaoheiAppearance==="light"?"light":"dark",P=`${w}-${M}`;if(!f.has(P)){p?.setPose(void 0,"hidden"),(l.pose!=="seated"||!["seated","chin","doze"].includes(n.dataset.pose??""))&&(n.dataset.pose="hidden"),!c.has(P)&&!m.has(P)&&(c.add(P),r(w,M).then(async x=>{if(i)return;let D=new t.Image;D.src=x,await D.decode(),!i&&(c.delete(P),f.set(P,x),u())}).catch(()=>{c.delete(P),m.add(P)}));return}let A=n.querySelector(`.xiaohei-wallpaper-character__${w}`);A.dataset.appearance!==M&&(A.style.setProperty(`--xiaohei-${w}-art`,`url("${f.get(P)}")`),A.dataset.appearance=M);for(let x of["left","top","width","height"]){let D=`${Math.round(l[x]*100)/100}px`;A.style[x]!==D&&(A.style[x]=D)}A.dataset.ready||(A.dataset.ready="true"),n.dataset.pose!==w&&(n.dataset.pose=w),p?.setPose(A,w)}function u(){i||o!==void 0||(o=t.requestAnimationFrame(()=>{o=void 0,b()}))}function _(){a!==void 0&&t.clearTimeout(a),a=t.setTimeout(()=>{a=void 0,s=!0,u()},240)}let k=oe(e,u),z=new t.MutationObserver(u);z.observe(e.documentElement,{attributes:!0,attributeFilter:["data-xiaohei-appearance"]});let I=()=>{s=!0,u(),_()};t.addEventListener("resize",I,{passive:!0});let R=()=>h.activity(),S=["pointermove","pointerdown","keydown","input","wheel"];for(let w of S)e.addEventListener(w,R,{passive:!0,capture:!0});let y=()=>{e.hidden&&h.setPaused(!0),u()};return e.addEventListener("visibilitychange",y),u(),()=>{i=!0,o!==void 0&&t.cancelAnimationFrame(o),a!==void 0&&t.clearTimeout(a),k(),v?.disconnect(),z.disconnect(),h.dispose(),p?.dispose();for(let w of S)e.removeEventListener(w,R,!0);e.removeEventListener("visibilitychange",y),t.removeEventListener("resize",I),n?.remove()}}var Pe=`
|
|
3
|
+
.xiaohei-wallpaper-character {
|
|
4
|
+
position: absolute;
|
|
5
|
+
inset: 0;
|
|
6
|
+
pointer-events: none;
|
|
7
|
+
user-select: none;
|
|
8
|
+
}
|
|
9
|
+
html[data-xiaohei-sidebar-resizing] .xiaohei-wallpaper-character {
|
|
10
|
+
visibility: hidden;
|
|
11
|
+
}
|
|
12
|
+
.xiaohei-wallpaper-character > span {
|
|
13
|
+
position: absolute;
|
|
14
|
+
display: block;
|
|
15
|
+
background-size: contain;
|
|
16
|
+
background-position: left center;
|
|
17
|
+
background-repeat: no-repeat;
|
|
18
|
+
pointer-events: none;
|
|
19
|
+
opacity: 0;
|
|
20
|
+
transition: opacity 220ms ease, transform 220ms cubic-bezier(.2,.8,.2,1);
|
|
21
|
+
}
|
|
22
|
+
.xiaohei-wallpaper-character .xiaohei-character-motion {
|
|
23
|
+
position: absolute; inset: 0; width: 100%; height: 100%;
|
|
24
|
+
object-fit: contain; object-position: left center; pointer-events: none;
|
|
25
|
+
}
|
|
26
|
+
.xiaohei-wallpaper-character > span[data-motion]:not([data-motion='rest']) {
|
|
27
|
+
background-image: none;
|
|
28
|
+
}
|
|
29
|
+
${Y.map(e=>`
|
|
30
|
+
.xiaohei-wallpaper-character__${e}[data-ready] {
|
|
31
|
+
background-image: var(--xiaohei-${e}-art);
|
|
32
|
+
}`).join(`
|
|
33
|
+
`)}
|
|
34
|
+
.xiaohei-wallpaper-character__peek,
|
|
35
|
+
.xiaohei-wallpaper-character__halfpeek {
|
|
36
|
+
transform: translateX(4px);
|
|
37
|
+
}
|
|
38
|
+
${Y.map(e=>`.xiaohei-wallpaper-character[data-pose='${e}'] > .xiaohei-wallpaper-character__${e}`).join(`,
|
|
39
|
+
`)} {
|
|
40
|
+
opacity: 1;
|
|
41
|
+
transform: none;
|
|
42
|
+
}
|
|
43
|
+
.xiaohei-wallpaper-character[data-pose='hidden'] > span {
|
|
44
|
+
transition: none;
|
|
45
|
+
}
|
|
46
|
+
@media (prefers-reduced-motion: reduce) {
|
|
47
|
+
.xiaohei-wallpaper-character > span { transition: none; transform: none; }
|
|
48
|
+
}
|
|
49
|
+
`;function Se(e){let r=e.createElement("style");r.id="dsh-theme-xiaohei/character-style",r.textContent=Pe,e.head.append(r);try{let t=xe(e);return()=>{t(),r.remove()}}catch(t){throw r.remove(),t}}
|
|
50
|
+
return module.exports; } });
|
|
51
|
+
//# sourceMappingURL=client.decorations.js.map
|