@icen.ai/ui 0.10.0 → 0.11.1

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.
Files changed (362) hide show
  1. package/AGENTS.md +79 -309
  2. package/LICENSE +21 -0
  3. package/README.md +43 -54
  4. package/dist/base.css +68 -22
  5. package/dist/behaviors/accordion.mjs +1 -1
  6. package/dist/behaviors/ai-branch.mjs +14 -0
  7. package/dist/behaviors/ai-chat.d.mts +2 -2
  8. package/dist/behaviors/ai-chat.mjs +66 -10
  9. package/dist/behaviors/ai-composer.d.mts +5 -5
  10. package/dist/behaviors/ai-composer.mjs +34 -10
  11. package/dist/behaviors/ai-core.mjs +14 -0
  12. package/dist/behaviors/ai-diff.mjs +14 -0
  13. package/dist/behaviors/ai-feedback.mjs +14 -0
  14. package/dist/behaviors/ai-panel.d.mts +2 -2
  15. package/dist/behaviors/ai-panel.mjs +14 -0
  16. package/dist/behaviors/ai-provider.d.mts +1 -1
  17. package/dist/behaviors/ai-provider.mjs +14 -0
  18. package/dist/behaviors/ai-threads.mjs +14 -0
  19. package/dist/behaviors/ai-tool.d.mts +1 -1
  20. package/dist/behaviors/ai-tool.mjs +299 -24
  21. package/dist/behaviors/ai-tools.mjs +1179 -28
  22. package/dist/behaviors/autocomplete.d.mts +1 -1
  23. package/dist/behaviors/autocomplete.mjs +14 -0
  24. package/dist/behaviors/back-top.mjs +14 -0
  25. package/dist/behaviors/carousel.mjs +21 -1
  26. package/dist/behaviors/cascader.mjs +27 -0
  27. package/dist/behaviors/charts.d.mts +12 -1
  28. package/dist/behaviors/charts.mjs +298 -20
  29. package/dist/behaviors/code-block.mjs +22 -1
  30. package/dist/behaviors/command-palette.mjs +3 -3
  31. package/dist/behaviors/context-menu.d.mts +2 -2
  32. package/dist/behaviors/context-menu.mjs +14 -0
  33. package/dist/behaviors/controls.d.mts +8 -8
  34. package/dist/behaviors/controls.mjs +50 -6
  35. package/dist/behaviors/copy.mjs +14 -0
  36. package/dist/behaviors/datatable.d.mts +3 -3
  37. package/dist/behaviors/datatable.mjs +89 -11
  38. package/dist/behaviors/date-picker.mjs +14 -0
  39. package/dist/behaviors/events.d.mts +10 -10
  40. package/dist/behaviors/events.mjs +11 -1
  41. package/dist/behaviors/form-validate.d.mts +10 -1
  42. package/dist/behaviors/form-validate.mjs +279 -4611
  43. package/dist/behaviors/i18n.d.mts +14 -0
  44. package/dist/behaviors/i18n.mjs +28 -0
  45. package/dist/behaviors/input.mjs +16 -0
  46. package/dist/behaviors/kb-access.d.mts +2 -2
  47. package/dist/behaviors/kb-access.mjs +21 -2
  48. package/dist/behaviors/kb-acl.d.mts +2 -2
  49. package/dist/behaviors/kb-acl.mjs +14 -0
  50. package/dist/behaviors/kb-answer.d.mts +2 -2
  51. package/dist/behaviors/kb-answer.mjs +298 -23
  52. package/dist/behaviors/kb-audit.d.mts +2 -2
  53. package/dist/behaviors/kb-audit.mjs +14 -0
  54. package/dist/behaviors/kb-canvas.d.mts +3 -3
  55. package/dist/behaviors/kb-canvas.mjs +14 -0
  56. package/dist/behaviors/kb-chain.d.mts +2 -2
  57. package/dist/behaviors/kb-chain.mjs +14 -0
  58. package/dist/behaviors/kb-checkpoint.d.mts +2 -2
  59. package/dist/behaviors/kb-checkpoint.mjs +14 -0
  60. package/dist/behaviors/kb-chunks.d.mts +2 -2
  61. package/dist/behaviors/kb-chunks.mjs +14 -0
  62. package/dist/behaviors/kb-citation.d.mts +2 -2
  63. package/dist/behaviors/kb-citation.mjs +33 -6
  64. package/dist/behaviors/kb-clarify.d.mts +2 -2
  65. package/dist/behaviors/kb-clarify.mjs +14 -0
  66. package/dist/behaviors/kb-conflict.d.mts +2 -2
  67. package/dist/behaviors/kb-conflict.mjs +14 -0
  68. package/dist/behaviors/kb-connector.d.mts +2 -2
  69. package/dist/behaviors/kb-connector.mjs +14 -0
  70. package/dist/behaviors/kb-core.d.mts +1 -1
  71. package/dist/behaviors/kb-core.mjs +14 -0
  72. package/dist/behaviors/kb-eval.d.mts +2 -2
  73. package/dist/behaviors/kb-eval.mjs +21 -2
  74. package/dist/behaviors/kb-explain.d.mts +2 -2
  75. package/dist/behaviors/kb-explain.mjs +26 -2
  76. package/dist/behaviors/kb-filter.d.mts +2 -2
  77. package/dist/behaviors/kb-filter.mjs +21 -2
  78. package/dist/behaviors/kb-gap.d.mts +2 -2
  79. package/dist/behaviors/kb-gap.mjs +14 -0
  80. package/dist/behaviors/kb-hittest.d.mts +2 -2
  81. package/dist/behaviors/kb-hittest.mjs +15 -1
  82. package/dist/behaviors/kb-metadata.mjs +19 -0
  83. package/dist/behaviors/kb-passage.d.mts +2 -2
  84. package/dist/behaviors/kb-passage.mjs +14 -0
  85. package/dist/behaviors/kb-pipeline.d.mts +2 -2
  86. package/dist/behaviors/kb-pipeline.mjs +14 -0
  87. package/dist/behaviors/kb-qa.mjs +14 -0
  88. package/dist/behaviors/kb-rerank.d.mts +2 -2
  89. package/dist/behaviors/kb-rerank.mjs +14 -0
  90. package/dist/behaviors/kb-retrieval.d.mts +2 -2
  91. package/dist/behaviors/kb-retrieval.mjs +31 -4
  92. package/dist/behaviors/kb-review.d.mts +2 -2
  93. package/dist/behaviors/kb-review.mjs +21 -2
  94. package/dist/behaviors/kb-sandbox.d.mts +2 -2
  95. package/dist/behaviors/kb-sandbox.mjs +20 -1
  96. package/dist/behaviors/kb-segment.d.mts +2 -2
  97. package/dist/behaviors/kb-segment.mjs +15 -1
  98. package/dist/behaviors/kb-select.mjs +21 -2
  99. package/dist/behaviors/kb-sources.d.mts +2 -2
  100. package/dist/behaviors/kb-sources.mjs +14 -0
  101. package/dist/behaviors/kb-sql.d.mts +2 -2
  102. package/dist/behaviors/kb-sql.mjs +14 -0
  103. package/dist/behaviors/kb-trace.d.mts +2 -2
  104. package/dist/behaviors/kb-trace.mjs +22 -3
  105. package/dist/behaviors/kb-visibility.d.mts +2 -2
  106. package/dist/behaviors/kb-visibility.mjs +14 -0
  107. package/dist/behaviors/kb-who-can.d.mts +2 -2
  108. package/dist/behaviors/kb-who-can.mjs +21 -2
  109. package/dist/behaviors/mentions.d.mts +1 -1
  110. package/dist/behaviors/mentions.mjs +14 -0
  111. package/dist/behaviors/modal.d.mts +1 -1
  112. package/dist/behaviors/modal.mjs +14 -0
  113. package/dist/behaviors/motion.d.mts +16 -0
  114. package/dist/behaviors/motion.mjs +39 -0
  115. package/dist/behaviors/notification.d.mts +2 -2
  116. package/dist/behaviors/notification.mjs +27 -3
  117. package/dist/behaviors/panel.mjs +14 -0
  118. package/dist/behaviors/scroll-area.d.mts +17 -0
  119. package/dist/behaviors/scroll-area.mjs +59 -0
  120. package/dist/behaviors/select.mjs +21 -2
  121. package/dist/behaviors/slider.mjs +3 -3
  122. package/dist/behaviors/split-pane.mjs +2 -0
  123. package/dist/behaviors/suggestions.mjs +14 -0
  124. package/dist/behaviors/tabs.mjs +10 -0
  125. package/dist/behaviors/tag-input.mjs +14 -0
  126. package/dist/behaviors/theme-switcher.d.mts +2 -2
  127. package/dist/behaviors/theme-switcher.mjs +30 -2
  128. package/dist/behaviors/theme.mjs +16 -2
  129. package/dist/behaviors/toast.d.mts +2 -2
  130. package/dist/behaviors/toast.mjs +14 -0
  131. package/dist/behaviors/tree-select.mjs +27 -0
  132. package/dist/behaviors/tree.mjs +4 -4
  133. package/dist/behaviors/upload.mjs +14 -0
  134. package/dist/behaviors/url-safety.d.mts +8 -0
  135. package/dist/behaviors/url-safety.mjs +11 -0
  136. package/dist/components/accordion.d.mts +2 -0
  137. package/dist/components/ai-branch.d.mts +2 -0
  138. package/dist/components/ai-chat.css +40 -33
  139. package/dist/components/ai-chat.d.mts +2 -0
  140. package/dist/components/ai-composer.d.mts +2 -0
  141. package/dist/components/ai-context.d.mts +2 -0
  142. package/dist/components/ai-context.mjs +1 -0
  143. package/dist/components/ai-diff.css +6 -6
  144. package/dist/components/ai-diff.d.mts +2 -0
  145. package/dist/components/ai-feedback.d.mts +2 -0
  146. package/dist/components/ai-files.d.mts +2 -0
  147. package/dist/components/ai-message.d.mts +2 -0
  148. package/dist/components/ai-panel.css +12 -10
  149. package/dist/components/ai-reasoning.d.mts +2 -0
  150. package/dist/components/ai-subagent.d.mts +2 -0
  151. package/dist/components/ai-subagent.mjs +1 -0
  152. package/dist/components/ai-threads.d.mts +2 -0
  153. package/dist/components/ai-todo.d.mts +2 -0
  154. package/dist/components/ai-todo.mjs +1 -0
  155. package/dist/components/ai-tool-call.d.mts +2 -0
  156. package/dist/components/ai-tool-call.mjs +1 -0
  157. package/dist/components/ai-tool.css +16 -16
  158. package/dist/components/ai-usage.d.mts +2 -0
  159. package/dist/components/alert.d.mts +2 -0
  160. package/dist/components/autocomplete.css +12 -12
  161. package/dist/components/autocomplete.d.mts +2 -0
  162. package/dist/components/avatar.d.mts +2 -0
  163. package/dist/components/back-top.css +47 -16
  164. package/dist/components/back-top.d.mts +2 -0
  165. package/dist/components/badge.css +1 -1
  166. package/dist/components/badge.d.mts +2 -0
  167. package/dist/components/breadcrumb.css +26 -8
  168. package/dist/components/breadcrumb.d.mts +2 -0
  169. package/dist/components/btn.css +67 -62
  170. package/dist/components/btn.d.mts +2 -0
  171. package/dist/components/card.css +22 -22
  172. package/dist/components/card.d.mts +2 -0
  173. package/dist/components/carousel.d.mts +2 -0
  174. package/dist/components/cascader.css +56 -35
  175. package/dist/components/cascader.d.mts +2 -0
  176. package/dist/components/chart-area.css +46 -0
  177. package/dist/components/chart-area.d.mts +2 -0
  178. package/dist/components/chart-bar.css +66 -19
  179. package/dist/components/chart-bar.d.mts +2 -0
  180. package/dist/components/chart-calendar.d.mts +2 -0
  181. package/dist/components/chart-gauge.css +23 -3
  182. package/dist/components/chart-gauge.d.mts +2 -0
  183. package/dist/components/chart-graph.css +15 -3
  184. package/dist/components/chart-graph.d.mts +2 -0
  185. package/dist/components/chart-heatmap.css +117 -95
  186. package/dist/components/chart-heatmap.d.mts +2 -0
  187. package/dist/components/chart-line.css +54 -0
  188. package/dist/components/chart-line.d.mts +2 -0
  189. package/dist/components/chart-map.d.mts +2 -0
  190. package/dist/components/chart-pie.css +29 -0
  191. package/dist/components/chart-pie.d.mts +2 -0
  192. package/dist/components/chart-radar.css +50 -1
  193. package/dist/components/chart-radar.d.mts +2 -0
  194. package/dist/components/chart-scatter.css +39 -2
  195. package/dist/components/chart-scatter.d.mts +2 -0
  196. package/dist/components/chart-sparkline.css +20 -0
  197. package/dist/components/chart-sparkline.d.mts +2 -0
  198. package/dist/components/chart-stack.css +16 -5
  199. package/dist/components/chart-stack.d.mts +2 -0
  200. package/dist/components/charts.css +109 -35
  201. package/dist/components/charts.d.mts +2 -0
  202. package/dist/components/code-block.css +10 -8
  203. package/dist/components/code-block.d.mts +2 -0
  204. package/dist/components/command-palette.css +45 -38
  205. package/dist/components/command-palette.d.mts +2 -0
  206. package/dist/components/content.css +62 -57
  207. package/dist/components/context-menu.d.mts +2 -0
  208. package/dist/components/copy.css +10 -10
  209. package/dist/components/copy.d.mts +2 -0
  210. package/dist/components/datatable.css +72 -59
  211. package/dist/components/datatable.d.mts +2 -0
  212. package/dist/components/date-picker.css +26 -26
  213. package/dist/components/date-picker.d.mts +2 -0
  214. package/dist/components/desc.d.mts +2 -0
  215. package/dist/components/dropdown.d.mts +2 -0
  216. package/dist/components/empty.css +16 -16
  217. package/dist/components/empty.d.mts +2 -0
  218. package/dist/components/feedback.css +31 -29
  219. package/dist/components/form-validate.css +20 -6
  220. package/dist/components/form-validate.d.mts +2 -0
  221. package/dist/components/form.css +17 -14
  222. package/dist/components/form.d.mts +2 -0
  223. package/dist/components/icon.css +21 -10
  224. package/dist/components/icon.d.mts +2 -0
  225. package/dist/components/input.css +22 -22
  226. package/dist/components/input.d.mts +2 -0
  227. package/dist/components/kb-access.d.mts +2 -0
  228. package/dist/components/kb-acl.d.mts +2 -0
  229. package/dist/components/kb-agent.css +134 -55
  230. package/dist/components/kb-answer.d.mts +2 -0
  231. package/dist/components/kb-audit.d.mts +2 -0
  232. package/dist/components/kb-canvas.d.mts +2 -0
  233. package/dist/components/kb-chain.d.mts +2 -0
  234. package/dist/components/kb-checkpoint.d.mts +2 -0
  235. package/dist/components/kb-chunks.d.mts +2 -0
  236. package/dist/components/kb-citation.d.mts +2 -0
  237. package/dist/components/kb-clarify.d.mts +2 -0
  238. package/dist/components/kb-conflict.d.mts +2 -0
  239. package/dist/components/kb-connector.d.mts +2 -0
  240. package/dist/components/kb-data.css +192 -80
  241. package/dist/components/kb-eval.d.mts +2 -0
  242. package/dist/components/kb-explain.d.mts +2 -0
  243. package/dist/components/kb-filter.d.mts +2 -0
  244. package/dist/components/kb-gap.d.mts +2 -0
  245. package/dist/components/kb-ground.css +165 -73
  246. package/dist/components/kb-hittest.d.mts +2 -0
  247. package/dist/components/kb-ingest.css +308 -113
  248. package/dist/components/kb-metadata.d.mts +2 -0
  249. package/dist/components/kb-ops.css +189 -75
  250. package/dist/components/kb-passage.d.mts +2 -0
  251. package/dist/components/kb-perm.css +158 -87
  252. package/dist/components/kb-pipeline.d.mts +2 -0
  253. package/dist/components/kb-qa.d.mts +2 -0
  254. package/dist/components/kb-rerank.d.mts +2 -0
  255. package/dist/components/kb-retrieval.d.mts +2 -0
  256. package/dist/components/kb-review.d.mts +2 -0
  257. package/dist/components/kb-sandbox.d.mts +2 -0
  258. package/dist/components/kb-search.css +353 -116
  259. package/dist/components/kb-segment.d.mts +2 -0
  260. package/dist/components/kb-sources.d.mts +2 -0
  261. package/dist/components/kb-sql.d.mts +2 -0
  262. package/dist/components/kb-trace.d.mts +2 -0
  263. package/dist/components/kb-visibility.d.mts +2 -0
  264. package/dist/components/kb-who-can.d.mts +2 -0
  265. package/dist/components/kb.css +60 -36
  266. package/dist/components/kb.d.mts +2 -0
  267. package/dist/components/kbd.d.mts +2 -0
  268. package/dist/components/layout.css +10 -10
  269. package/dist/components/layout.d.mts +2 -0
  270. package/dist/components/list.d.mts +2 -0
  271. package/dist/components/material-chinese.css +10 -0
  272. package/dist/components/material-soviet.css +10 -0
  273. package/dist/components/material.css +61 -18
  274. package/dist/components/media-card.d.mts +2 -0
  275. package/dist/components/media.css +22 -27
  276. package/dist/components/mentions.css +18 -17
  277. package/dist/components/mentions.d.mts +2 -0
  278. package/dist/components/menu.css +32 -28
  279. package/dist/components/modal.css +30 -27
  280. package/dist/components/modal.d.mts +2 -0
  281. package/dist/components/nav.css +48 -44
  282. package/dist/components/nav.d.mts +2 -0
  283. package/dist/components/notification.css +31 -25
  284. package/dist/components/notification.d.mts +2 -0
  285. package/dist/components/pagination.css +15 -13
  286. package/dist/components/pagination.d.mts +2 -0
  287. package/dist/components/panel.css +19 -20
  288. package/dist/components/panel.d.mts +2 -0
  289. package/dist/components/pill.css +8 -7
  290. package/dist/components/pill.d.mts +2 -0
  291. package/dist/components/popover.css +32 -23
  292. package/dist/components/popover.d.mts +2 -0
  293. package/dist/components/progress.d.mts +2 -0
  294. package/dist/components/rating.d.mts +2 -0
  295. package/dist/components/result.d.mts +2 -0
  296. package/dist/components/scroll-area.css +84 -112
  297. package/dist/components/scroll-area.d.mts +2 -0
  298. package/dist/components/scroll-area.mjs +1 -0
  299. package/dist/components/segmented.css +47 -29
  300. package/dist/components/segmented.d.mts +2 -0
  301. package/dist/components/select.css +80 -41
  302. package/dist/components/select.d.mts +2 -0
  303. package/dist/components/sidebar.css +42 -38
  304. package/dist/components/sidebar.d.mts +2 -0
  305. package/dist/components/skeleton.d.mts +2 -0
  306. package/dist/components/slider.css +26 -22
  307. package/dist/components/slider.d.mts +2 -0
  308. package/dist/components/spinner.d.mts +2 -0
  309. package/dist/components/split-pane.css +16 -7
  310. package/dist/components/split-pane.d.mts +2 -0
  311. package/dist/components/stat.css +17 -16
  312. package/dist/components/stat.d.mts +2 -0
  313. package/dist/components/steps.css +26 -26
  314. package/dist/components/steps.d.mts +2 -0
  315. package/dist/components/switch.css +78 -39
  316. package/dist/components/switch.d.mts +2 -0
  317. package/dist/components/table.css +54 -32
  318. package/dist/components/table.d.mts +2 -0
  319. package/dist/components/tabs.css +53 -32
  320. package/dist/components/tabs.d.mts +2 -0
  321. package/dist/components/tag-input.css +12 -8
  322. package/dist/components/tag-input.d.mts +2 -0
  323. package/dist/components/tag.css +20 -12
  324. package/dist/components/tag.d.mts +2 -0
  325. package/dist/components/theme-switcher.css +7 -7
  326. package/dist/components/theme-switcher.d.mts +2 -0
  327. package/dist/components/timeline.d.mts +2 -0
  328. package/dist/components/toast.css +34 -30
  329. package/dist/components/toast.d.mts +2 -0
  330. package/dist/components/toolbar.css +19 -18
  331. package/dist/components/toolbar.d.mts +2 -0
  332. package/dist/components/tooltip.css +9 -8
  333. package/dist/components/tooltip.d.mts +2 -0
  334. package/dist/components/tree-select.css +63 -40
  335. package/dist/components/tree-select.d.mts +2 -0
  336. package/dist/components/tree.d.mts +2 -0
  337. package/dist/components/upload.css +9 -11
  338. package/dist/components/upload.d.mts +2 -0
  339. package/dist/index.d.mts +85 -84
  340. package/dist/index.mjs +14644 -13935
  341. package/dist/react.d.mts +18 -18
  342. package/dist/react.mjs +377 -36
  343. package/dist/registry.json +797 -64
  344. package/dist/tokens/colors.css +6 -0
  345. package/dist/tokens/design.css +137 -31
  346. package/dist/tokens/dtcg.json +9592 -2008
  347. package/dist/tokens/figma.variables.json +7451 -2141
  348. package/dist/tokens/motion.css +51 -0
  349. package/dist/tokens/pixel.css +10 -0
  350. package/dist/tokens/scrollbars.css +40 -0
  351. package/dist/tokens/tokens-studio.json +8390 -1142
  352. package/dist/tokens/typography.css +33 -0
  353. package/dist/tokens.css +402 -82
  354. package/dist/ui.css +4196 -2163
  355. package/dist/vue.d.mts +17 -17
  356. package/dist/vue.mjs +371 -34
  357. package/docs/spec/charts-scale-a11y.md +115 -0
  358. package/docs/spec/design-philosophy.md +5 -5
  359. package/docs/spec/design-primitives.md +10 -10
  360. package/docs/spec/motion-typography.md +105 -0
  361. package/docs/spec/scrollbars.md +46 -0
  362. package/package.json +17 -3
@@ -21,6 +21,7 @@ var ICEN_LOCALE_ZH_CN = {
21
21
  "aiChat.roleTool": "\u5DE5",
22
22
  "aiChat.roleUser": "\u6211",
23
23
  "aiChat.thinking": "\u601D\u8003 {p0}",
24
+ "aiChat.thinkingNow": "\u6B63\u5728\u601D\u8003\u2026",
24
25
  /* ── aiComposer ── */
25
26
  "aiComposer.attachAgent": "\u4EE3\u7406",
26
27
  "aiComposer.library": "\u6DFB\u52A0\u4E0A\u4E0B\u6587\u4E0E\u547D\u4EE4",
@@ -203,6 +204,19 @@ var ICEN_LOCALE_ZH_CN = {
203
204
  "charts.noData": "\u6682\u65E0\u6570\u636E",
204
205
  "charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
205
206
  "charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
207
+ "charts.a11y.keyboardHint": "\u65B9\u5411\u952E\u9010\u70B9\u6D4F\u89C8\uFF0CHome/End \u8DF3\u9996\u5C3E\uFF0CEsc \u91CD\u7F6E\u7F29\u653E",
208
+ "charts.a11y.max": "\u6700\u5927 {p0}\uFF08{p1}\uFF09",
209
+ "charts.a11y.min": "\u6700\u5C0F {p0}\uFF08{p1}\uFF09",
210
+ "charts.a11y.point": "{p0}\uFF1A{p1}\uFF0C\u7B2C {p2}/{p3} \u70B9",
211
+ "charts.a11y.pointSeries": "{p0} \xB7 {p1}\uFF1A{p2}\uFF0C\u7B2C {p3}/{p4} \u70B9",
212
+ "charts.a11y.range": "\u7C7B\u76EE {p0} \u81F3 {p1}",
213
+ "charts.a11y.scatterRange": "x \u8303\u56F4 {p0}\u2013{p1}\uFF0Cy \u8303\u56F4 {p2}\u2013{p3}",
214
+ "charts.a11y.seriesCount": "{p0} \u4E2A\u7CFB\u5217",
215
+ "charts.a11y.tableCaption": "{p0} \u6570\u636E\u8868",
216
+ "charts.a11y.trend": "\u9996\u7CFB\u5217\u8D8B\u52BF{p0}",
217
+ "charts.a11y.trendDown": "\u4E0B\u964D",
218
+ "charts.a11y.trendFlat": "\u6301\u5E73",
219
+ "charts.a11y.trendUp": "\u4E0A\u5347",
206
220
  "charts.type.area": "\u9762\u79EF\u56FE",
207
221
  "charts.type.donut": "\u73AF\u5F62\u56FE",
208
222
  "charts.type.gauge": "\u4EEA\u8868\u76D8",
@@ -1216,6 +1230,15 @@ function renderKbClarify(el, c, opts) {
1216
1230
  return el;
1217
1231
  }
1218
1232
 
1233
+ // src/behaviors/url-safety.ts
1234
+ function safeUrl(uri) {
1235
+ const s = uri.replace(/[\t\n\r\0-\x1f\x7f]/g, "").trim().toLowerCase();
1236
+ if (!s) return void 0;
1237
+ if (s.startsWith("javascript:") || s.startsWith("vbscript:")) return void 0;
1238
+ if (/^data:\s*text\/html/.test(s)) return void 0;
1239
+ return uri;
1240
+ }
1241
+
1219
1242
  // src/behaviors/kb-explain.ts
1220
1243
  function toExplainFact(raw) {
1221
1244
  const r = raw ?? {};
@@ -1276,9 +1299,10 @@ function renderKbExplain(el, fact) {
1276
1299
  const row = h("div", "icen-kb-explain-metric");
1277
1300
  row.appendChild(h("span", "icen-kb-explain-metric-name", m.name));
1278
1301
  if (m.ref) {
1279
- if (!/^\s*(javascript|data|vbscript)\s*:/i.test(m.ref)) {
1302
+ const href = safeUrl(m.ref);
1303
+ if (href) {
1280
1304
  const a = h("a", "icen-kb-explain-metric-ref", t("kbExplain.viewDefinition"));
1281
- a.href = m.ref;
1305
+ a.href = href;
1282
1306
  a.rel = "noopener";
1283
1307
  row.appendChild(a);
1284
1308
  }
@@ -1521,7 +1545,8 @@ function withChrome(el, opts, hasLegend, paint, state, extras) {
1521
1545
  emitIcen(el, "icen:chart-legend-visibility", { visible: hidden ? false : true });
1522
1546
  });
1523
1547
  syncEye();
1524
- head.append(title, eye);
1548
+ if (hasLegend) head.append(title, eye);
1549
+ else head.append(title);
1525
1550
  el.append(head, body);
1526
1551
  paint(body);
1527
1552
  }
@@ -1622,7 +1647,7 @@ function renderVBar(el, opts) {
1622
1647
  wrap.appendChild(track);
1623
1648
  }
1624
1649
  body.append(wrap, labelsRow(labelsUsed));
1625
- if (seriesList.length > 1) body.appendChild(toggleLegend(seriesList.map((s, si) => ({ key: s.name, label: s.name, tone: s.tone ?? (si === 0 ? opts.tone : void 0), si })), wrap));
1650
+ if (seriesList.length > 1) body.appendChild(toggleLegend(seriesList.map((s, si) => ({ key: `${si}:${s.name}`, label: s.name, tone: s.tone ?? (si === 0 ? opts.tone : void 0), si })), wrap));
1626
1651
  });
1627
1652
  attachChartInteraction(el, "vbar");
1628
1653
  return el;
@@ -1717,8 +1742,10 @@ function renderDonut(el, opts) {
1717
1742
  "stroke-width": "14"
1718
1743
  }));
1719
1744
  let offset = 0;
1745
+ const gap = opts.segments.length > 1 ? 2.5 : 0;
1720
1746
  opts.segments.forEach((seg, segIndex) => {
1721
- const dash = seg.value / total * circumference;
1747
+ const arcLength = Math.max(0, seg.value / total * circumference);
1748
+ const dash = arcLength - Math.min(gap, arcLength * 0.1);
1722
1749
  const arc = svgEl("circle", {
1723
1750
  cx: "60",
1724
1751
  cy: "60",
@@ -1732,7 +1759,7 @@ function renderDonut(el, opts) {
1732
1759
  });
1733
1760
  setMarkData(arc, { index: segIndex, label: seg.label, value: seg.value });
1734
1761
  svg.appendChild(arc);
1735
- offset += dash;
1762
+ offset += arcLength;
1736
1763
  });
1737
1764
  const legend = document.createElement("div");
1738
1765
  legend.className = "icen-chart-legend";
@@ -1767,8 +1794,9 @@ function renderLine(el, opts) {
1767
1794
  const svg = svgEl("svg", { viewBox: `0 0 ${width} ${height}`, role: "img", "aria-label": chartAriaLabel(opts.title, t("charts.type.line")) });
1768
1795
  const defs = svgEl("defs", {});
1769
1796
  for (let i = 0; i < 4; i++) {
1770
- const y = pad + i * (height - pad * 2) / 3;
1797
+ const y = Math.round(pad + i * (height - pad * 2) / 3) + 0.5;
1771
1798
  svg.appendChild(svgEl("line", {
1799
+ class: i === 3 ? "icen-chart-grid icen-chart-baseline" : "icen-chart-grid",
1772
1800
  x1: String(pad),
1773
1801
  x2: String(width - pad),
1774
1802
  y1: String(y),
@@ -1852,7 +1880,7 @@ function renderLine(el, opts) {
1852
1880
  if (defs.firstChild) svg.insertBefore(defs, svg.firstChild);
1853
1881
  wrap.append(svg, pointLabelsRow(labelsUsed, width, pad));
1854
1882
  body.appendChild(wrap);
1855
- if (seriesList.length > 1) body.appendChild(toggleLegend(seriesList.map((s, si) => ({ key: s.name, label: s.name, tone: s.tone ?? (si === 0 ? opts.tone : void 0), si })), wrap));
1883
+ if (seriesList.length > 1) body.appendChild(toggleLegend(seriesList.map((s, si) => ({ key: `${si}:${s.name}`, label: s.name, tone: s.tone ?? (si === 0 ? opts.tone : void 0), si })), wrap));
1856
1884
  });
1857
1885
  if (el.dataset.icenChartBody == null) observeFluidWidth(el, () => renderLine(el, opts));
1858
1886
  attachChartInteraction(el, "line");
@@ -1959,7 +1987,7 @@ function renderRadar(el, opts) {
1959
1987
  setMarkData(dot, { index: i, seriesIndex: si, seriesName: s.name || void 0, label: axes[i] ?? "", value: s.values[i] ?? 0 });
1960
1988
  svg.appendChild(dot);
1961
1989
  }
1962
- legendItems.push({ key: s.name || t("charts.seriesName", { p0: si + 1 }), label: s.name || t("charts.seriesName", { p0: si + 1 }), tone: s.tone, si });
1990
+ legendItems.push({ key: `${si}:${s.name || t("charts.seriesName", { p0: si + 1 })}`, label: s.name || t("charts.seriesName", { p0: si + 1 }), tone: s.tone, si });
1963
1991
  });
1964
1992
  wrap.appendChild(svg);
1965
1993
  body.appendChild(wrap);
@@ -1981,6 +2009,11 @@ function niceCeil(v) {
1981
2009
  else nice = 10;
1982
2010
  return nice * base;
1983
2011
  }
2012
+ function tickPrecision(min, max, steps) {
2013
+ const span = Math.abs(max - min);
2014
+ if (!Number.isFinite(span) || span <= 0) return 0;
2015
+ return Math.max(0, Math.ceil(-Math.log10(span / steps)));
2016
+ }
1984
2017
  function isoDate(d) {
1985
2018
  const m = String(d.getMonth() + 1).padStart(2, "0");
1986
2019
  const day = String(d.getDate()).padStart(2, "0");
@@ -2076,7 +2109,8 @@ function renderSparkline(el, opts) {
2076
2109
  const tone = toneVar(opts.tone);
2077
2110
  const points = values.map((value, i) => ({
2078
2111
  x: values.length <= 1 ? width / 2 : pad + i / (values.length - 1) * (width - pad * 2),
2079
- y: height - pad - value / max * (height - pad * 2),
2112
+ /* 负值钳到基线(与折线图同口径):viewBox 仅 28 高,反向射出更刺眼 */
2113
+ y: height - pad - Math.max(0, value) / max * (height - pad * 2),
2080
2114
  value
2081
2115
  }));
2082
2116
  const line = points.map((p, i) => `${i === 0 ? "M" : "L"}${p.x.toFixed(1)},${p.y.toFixed(1)}`).join(" ");
@@ -2201,6 +2235,7 @@ function renderCalendar(el, opts) {
2201
2235
  weekdayRow.appendChild(s);
2202
2236
  });
2203
2237
  const max = maxOf(entries.map((e) => e.value));
2238
+ entries.sort((a, b) => a.date.localeCompare(b.date));
2204
2239
  const pad = padFirstWeek(grid, entries[0].date, weekStart);
2205
2240
  let lastMonth = -1;
2206
2241
  entries.forEach((entry, i) => {
@@ -2259,8 +2294,9 @@ function renderScatter(el, opts) {
2259
2294
  const xAt = (x) => pad + (x - xMin) / (xMax - xMin) * (width - pad * 2);
2260
2295
  const yAt = (y) => height - pad - (y - yMin) / (yMax - yMin) * (height - pad * 2);
2261
2296
  for (let i = 0; i <= 3; i++) {
2262
- const y = pad + i * (height - pad * 2) / 3;
2297
+ const y = Math.round(pad + i * (height - pad * 2) / 3) + 0.5;
2263
2298
  svg.appendChild(svgEl("line", {
2299
+ class: i === 3 ? "icen-chart-grid icen-chart-baseline" : "icen-chart-grid",
2264
2300
  x1: String(pad),
2265
2301
  x2: String(width - pad),
2266
2302
  y1: String(y),
@@ -2276,12 +2312,13 @@ function renderScatter(el, opts) {
2276
2312
  "font-size": "8",
2277
2313
  fill: "var(--icen-token-text-faint)"
2278
2314
  });
2279
- txt.textContent = fmt(opts, Math.round(tv * 10) / 10);
2315
+ txt.textContent = fmt(opts, +tv.toFixed(tickPrecision(yMin, yMax, 3)));
2280
2316
  svg.appendChild(txt);
2281
2317
  }
2282
2318
  for (let i = 0; i <= 4; i++) {
2283
- const x = pad + i * (width - pad * 2) / 4;
2319
+ const x = Math.round(pad + i * (width - pad * 2) / 4) + 0.5;
2284
2320
  svg.appendChild(svgEl("line", {
2321
+ class: i === 0 ? "icen-chart-grid icen-chart-grid--v icen-chart-axis" : "icen-chart-grid icen-chart-grid--v",
2285
2322
  x1: String(x),
2286
2323
  x2: String(x),
2287
2324
  y1: String(pad),
@@ -2298,7 +2335,7 @@ function renderScatter(el, opts) {
2298
2335
  "font-size": "8",
2299
2336
  fill: "var(--icen-token-text-faint)"
2300
2337
  });
2301
- txt.textContent = fmt(opts, Math.round(tv * 10) / 10);
2338
+ txt.textContent = fmt(opts, +tv.toFixed(tickPrecision(xMin, xMax, 4)));
2302
2339
  svg.appendChild(txt);
2303
2340
  }
2304
2341
  if (opts.yLabel) {
@@ -2535,6 +2572,14 @@ function normalizeChartSpec(raw) {
2535
2572
  }
2536
2573
  if (s.zoom === "x" || s.zoom === "brush") spec.zoom = s.zoom;
2537
2574
  if (typeof s.loading === "boolean") spec.loading = s.loading;
2575
+ if (s.a11y && typeof s.a11y === "object") {
2576
+ const a = s.a11y;
2577
+ const a11y = {};
2578
+ if (typeof a.summary === "boolean") a11y.summary = a.summary;
2579
+ if (typeof a.table === "boolean") a11y.table = a.table;
2580
+ if (typeof a.keyboard === "boolean") a11y.keyboard = a.keyboard;
2581
+ if (Object.keys(a11y).length > 0) spec.a11y = a11y;
2582
+ }
2538
2583
  if (Array.isArray(s.marks)) {
2539
2584
  const marks = [];
2540
2585
  for (const raw2 of s.marks) {
@@ -2662,6 +2707,7 @@ function renderChartSkeleton(body) {
2662
2707
  body.appendChild(box);
2663
2708
  }
2664
2709
  var CHART_MARK_ACCENT = "var(--icen-token-accent)";
2710
+ var CHART_MARK_ACCENT_TEXT = "var(--icen-token-accent-text)";
2665
2711
  function markToneVar(tone) {
2666
2712
  switch (tone) {
2667
2713
  case "success":
@@ -2797,7 +2843,7 @@ function paintSvgChartMarks(root, view, marks, formatValue, warned) {
2797
2843
  y: String(clampNum(y - 10, 8, CHART_LINE_H - 4)),
2798
2844
  "text-anchor": "middle",
2799
2845
  "font-size": "8",
2800
- fill: CHART_MARK_ACCENT
2846
+ fill: CHART_MARK_ACCENT_TEXT
2801
2847
  });
2802
2848
  label.textContent = mark.text ?? mark.label;
2803
2849
  g.appendChild(label);
@@ -2889,6 +2935,81 @@ function paintVBarChartMarks(root, view, spec, marks, formatValue, warned) {
2889
2935
  function chartAriaLabel(title, typeName) {
2890
2936
  return title ? `${typeName}\uFF1A${title}` : typeName;
2891
2937
  }
2938
+ function summarizeChart(view, type, fmt2) {
2939
+ const series = view.series && view.series.length > 0 ? view.series : [{ name: "", values: view.values ?? [] }];
2940
+ const parts = [];
2941
+ if (series.length > 1) parts.push(t("charts.a11y.seriesCount", { p0: series.length }));
2942
+ if (type === "scatter") {
2943
+ const pts = view.points ?? [];
2944
+ if (pts.length > 0) {
2945
+ const xs = pts.map((p) => p.x);
2946
+ const ys = pts.map((p) => p.y);
2947
+ parts.push(t("charts.a11y.scatterRange", { p0: fmt2(Math.min(...xs)), p1: fmt2(Math.max(...xs)), p2: fmt2(Math.min(...ys)), p3: fmt2(Math.max(...ys)) }));
2948
+ }
2949
+ return parts.join("\uFF1B");
2950
+ }
2951
+ const labels = view.labels ?? [];
2952
+ if (labels.length > 1) parts.push(t("charts.a11y.range", { p0: labels[0], p1: labels[labels.length - 1] }));
2953
+ let min = Infinity;
2954
+ let max = -Infinity;
2955
+ let minAt = "";
2956
+ let maxAt = "";
2957
+ for (const s of series) {
2958
+ s.values.forEach((v, i) => {
2959
+ if (v < min) {
2960
+ min = v;
2961
+ minAt = labels[i] ?? String(i + 1);
2962
+ }
2963
+ if (v > max) {
2964
+ max = v;
2965
+ maxAt = labels[i] ?? String(i + 1);
2966
+ }
2967
+ });
2968
+ }
2969
+ if (Number.isFinite(min) && Number.isFinite(max)) {
2970
+ parts.push(t("charts.a11y.min", { p0: fmt2(min), p1: minAt }));
2971
+ parts.push(t("charts.a11y.max", { p0: fmt2(max), p1: maxAt }));
2972
+ }
2973
+ const first = series[0]?.values ?? [];
2974
+ if (first.length > 1) {
2975
+ const d = first[first.length - 1] - first[0];
2976
+ const key = Math.abs(d) < 1e-9 ? "charts.a11y.trendFlat" : d > 0 ? "charts.a11y.trendUp" : "charts.a11y.trendDown";
2977
+ parts.push(t("charts.a11y.trend", { p0: t(key) }));
2978
+ }
2979
+ return parts.join("\uFF1B");
2980
+ }
2981
+ function buildChartTable(view, spec, type, fmt2) {
2982
+ const table = document.createElement("table");
2983
+ table.className = "icen-chart-table";
2984
+ const caption = document.createElement("caption");
2985
+ caption.textContent = t("charts.a11y.tableCaption", { p0: spec.title ?? String(type) });
2986
+ table.appendChild(caption);
2987
+ const addRow = (target, cells, head) => {
2988
+ const tr = document.createElement("tr");
2989
+ for (const c of cells) {
2990
+ const cell = document.createElement(head ? "th" : "td");
2991
+ if (head) cell.scope = target.tagName === "THEAD" ? "col" : "row";
2992
+ cell.textContent = c;
2993
+ tr.appendChild(cell);
2994
+ }
2995
+ target.appendChild(tr);
2996
+ };
2997
+ const thead = table.createTHead();
2998
+ const tbody = table.createTBody();
2999
+ if (type === "scatter") {
3000
+ addRow(thead, ["x", "y"], true);
3001
+ for (const p of view.points ?? []) addRow(tbody, [fmt2(p.x), fmt2(p.y)], false);
3002
+ return table;
3003
+ }
3004
+ const series = view.series && view.series.length > 0 ? view.series : [{ name: "", values: view.values ?? [] }];
3005
+ const labels = view.labels ?? [];
3006
+ addRow(thead, ["", ...series.map((s, i) => s.name || String(i + 1))], true);
3007
+ const n = Math.max(labels.length, ...series.map((s) => s.values.length));
3008
+ for (let i = 0; i < n; i++) {
3009
+ addRow(tbody, [labels[i] ?? String(i + 1), ...series.map((s) => fmt2(s.values[i] ?? 0))], false);
3010
+ }
3011
+ return table;
3012
+ }
2892
3013
  function svgDimsOf(svg) {
2893
3014
  const vb = (svg.getAttribute("viewBox") ?? "").split(/\s+/).map(Number);
2894
3015
  const w = Number.isFinite(vb[2]) && (vb[2] ?? 0) > 0 ? vb[2] : CHART_LINE_W;
@@ -3229,6 +3350,7 @@ function renderChart(el, raw) {
3229
3350
  if (!isZoomableType(t2) || fullLength() < 2) return;
3230
3351
  const plot = t2 === "vbar" ? root.querySelector(".icen-chart-vbar") : root.querySelector(".icen-chart-line svg");
3231
3352
  if (!plot) return;
3353
+ plot.style.touchAction = current2.zoom === "x" ? "pan-y" : "none";
3232
3354
  const on = (type, fn) => {
3233
3355
  plot.addEventListener(type, fn);
3234
3356
  };
@@ -3284,6 +3406,149 @@ function renderChart(el, raw) {
3284
3406
  render();
3285
3407
  });
3286
3408
  };
3409
+ const KB_TYPES = /* @__PURE__ */ new Set(["line", "area", "vbar", "hbar", "scatter"]);
3410
+ const kbCursor = { si: 0, i: 0, active: false };
3411
+ let liveRegion = null;
3412
+ let a11ySeq = 0;
3413
+ const a11yOf = () => ({
3414
+ summary: current2.a11y?.summary !== false,
3415
+ table: current2.a11y?.table === true,
3416
+ keyboard: current2.a11y?.keyboard !== false
3417
+ });
3418
+ const seriesViewOf = (view) => view.series && view.series.length > 0 ? view.series : [{ name: "", values: view.values ?? [] }];
3419
+ const kbPointCount = (view) => typeOf() === "scatter" ? view.points?.length ?? 0 : Math.max(0, ...seriesViewOf(view).map((s) => s.values.length), view.labels?.length ?? 0);
3420
+ const kbCursorEl = () => {
3421
+ const t2 = typeOf();
3422
+ const view = viewOf();
3423
+ const series = seriesViewOf(view);
3424
+ const n = kbPointCount(view);
3425
+ if (n < 1) return null;
3426
+ const si = clampNum(kbCursor.si, 0, Math.max(0, series.length - 1));
3427
+ const i = clampNum(kbCursor.i, 0, n - 1);
3428
+ if (t2 === "line" || t2 === "area") {
3429
+ const svg = root.querySelector(".icen-chart-line svg");
3430
+ if (!svg) return null;
3431
+ const dots = svg.querySelectorAll("circle");
3432
+ let base = 0;
3433
+ for (let k = 0; k < si; k++) base += Math.min(series[k].values.length, n);
3434
+ return dots.item(base + i) ?? null;
3435
+ }
3436
+ if (t2 === "scatter") return root.querySelector(".icen-chart-scatter svg")?.querySelectorAll("circle").item(i) ?? null;
3437
+ if (t2 === "vbar") return root.querySelectorAll(".icen-chart-vbar-bar").item(series.length > 1 ? i * series.length + si : i) ?? null;
3438
+ if (t2 === "hbar") return root.querySelectorAll(".icen-chart-hbar-bar").item(i) ?? null;
3439
+ return null;
3440
+ };
3441
+ const announceKb = (text) => {
3442
+ if (!liveRegion || !liveRegion.isConnected) {
3443
+ liveRegion = document.createElement("div");
3444
+ liveRegion.className = "icen-chart-live";
3445
+ liveRegion.setAttribute("aria-live", "polite");
3446
+ root.appendChild(liveRegion);
3447
+ }
3448
+ liveRegion.textContent = "";
3449
+ liveRegion.textContent = text;
3450
+ };
3451
+ const applyKbCursor = () => {
3452
+ for (const el2 of root.querySelectorAll(".icen-chart-kb-focus")) el2.classList.remove("icen-chart-kb-focus");
3453
+ if (!kbCursor.active) return;
3454
+ kbCursorEl()?.classList.add("icen-chart-kb-focus");
3455
+ };
3456
+ const announceCursor = () => {
3457
+ const view = viewOf();
3458
+ const series = seriesViewOf(view);
3459
+ const n = kbPointCount(view);
3460
+ if (n < 1) return;
3461
+ const si = clampNum(kbCursor.si, 0, Math.max(0, series.length - 1));
3462
+ const i = clampNum(kbCursor.i, 0, Math.max(0, n - 1));
3463
+ const fmt2 = chartFormatValue(current2.format);
3464
+ if (typeOf() === "scatter") {
3465
+ const p = view.points?.[i];
3466
+ if (!p) return;
3467
+ announceKb(t("charts.a11y.point", { p0: `x ${fmt2(p.x)}`, p1: `y ${fmt2(p.y)}`, p2: i + 1, p3: n }));
3468
+ return;
3469
+ }
3470
+ const label = view.labels?.[i] ?? String(i + 1);
3471
+ const value = series[si]?.values[i] ?? 0;
3472
+ if (series.length > 1) announceKb(t("charts.a11y.pointSeries", { p0: series[si].name || String(si + 1), p1: label, p2: fmt2(value), p3: i + 1, p4: n }));
3473
+ else announceKb(t("charts.a11y.point", { p0: label, p1: fmt2(value), p2: i + 1, p3: n }));
3474
+ };
3475
+ const onKbKeydown = (e) => {
3476
+ const conf = a11yOf();
3477
+ if (!conf.keyboard || !KB_TYPES.has(typeOf())) return;
3478
+ const g = root.querySelector("[data-icen-chart-kb]");
3479
+ if (!g || e.target !== g) return;
3480
+ if (e.key === "Escape") {
3481
+ if (zoomWindow) {
3482
+ zoomWindow = null;
3483
+ kbCursor.active = false;
3484
+ render();
3485
+ }
3486
+ return;
3487
+ }
3488
+ const view = viewOf();
3489
+ const series = seriesViewOf(view);
3490
+ const n = kbPointCount(view);
3491
+ if (n < 1) return;
3492
+ const siMax = Math.max(0, series.length - 1);
3493
+ let moved = true;
3494
+ switch (e.key) {
3495
+ case "ArrowRight":
3496
+ kbCursor.i = clampNum(kbCursor.i + 1, 0, n - 1);
3497
+ break;
3498
+ case "ArrowLeft":
3499
+ kbCursor.i = clampNum(kbCursor.i - 1, 0, n - 1);
3500
+ break;
3501
+ case "ArrowDown":
3502
+ kbCursor.si = clampNum(kbCursor.si + 1, 0, siMax);
3503
+ break;
3504
+ case "ArrowUp":
3505
+ kbCursor.si = clampNum(kbCursor.si - 1, 0, siMax);
3506
+ break;
3507
+ case "Home":
3508
+ kbCursor.i = 0;
3509
+ break;
3510
+ case "End":
3511
+ kbCursor.i = n - 1;
3512
+ break;
3513
+ default:
3514
+ moved = false;
3515
+ }
3516
+ if (!moved) return;
3517
+ e.preventDefault();
3518
+ kbCursor.active = true;
3519
+ applyKbCursor();
3520
+ announceCursor();
3521
+ };
3522
+ root.addEventListener("keydown", onKbKeydown);
3523
+ const applyChartA11yPlus = (view, spec, type, formatValue) => {
3524
+ const conf = a11yOf();
3525
+ const graphic = root.querySelector('[role="img"]');
3526
+ if (!graphic) return;
3527
+ const body = root.querySelector(".icen-chart-body") ?? graphic.parentElement ?? root;
3528
+ const summaryParts = [];
3529
+ if (conf.summary) summaryParts.push(summarizeChart(view, type, formatValue));
3530
+ if (conf.keyboard && KB_TYPES.has(type)) summaryParts.push(t("charts.a11y.keyboardHint"));
3531
+ const summaryText = summaryParts.filter(Boolean).join("\uFF1B");
3532
+ if (summaryText) {
3533
+ const p = document.createElement("p");
3534
+ p.className = "icen-chart-summary";
3535
+ p.id = `icen-chart-a11y-${++a11ySeq}`;
3536
+ p.textContent = summaryText;
3537
+ body.appendChild(p);
3538
+ graphic.setAttribute("aria-describedby", p.id);
3539
+ } else {
3540
+ graphic.removeAttribute("aria-describedby");
3541
+ }
3542
+ if (conf.keyboard && KB_TYPES.has(type)) {
3543
+ graphic.setAttribute("tabindex", "0");
3544
+ graphic.setAttribute("data-icen-chart-kb", "");
3545
+ } else {
3546
+ graphic.removeAttribute("tabindex");
3547
+ graphic.removeAttribute("data-icen-chart-kb");
3548
+ }
3549
+ if (conf.table) body.appendChild(buildChartTable(view, spec, type, formatValue));
3550
+ applyKbCursor();
3551
+ };
3287
3552
  const render = () => {
3288
3553
  if (!current2.type) current2 = { ...current2, type: inferChartType(current2) };
3289
3554
  const spec = current2;
@@ -3355,9 +3620,16 @@ function renderChart(el, raw) {
3355
3620
  const graphic = root.querySelector('[role="img"]');
3356
3621
  if (graphic && !graphic.getAttribute("aria-label")) {
3357
3622
  graphic.setAttribute("aria-label", spec.title ? `${spec.title}\uFF08${type}\uFF09` : type);
3623
+ } else if (!graphic) {
3624
+ const dom = root.querySelector(".icen-chart-vbar, .icen-chart-hbar");
3625
+ if (dom) {
3626
+ dom.setAttribute("role", "img");
3627
+ dom.setAttribute("aria-label", spec.title ? `${spec.title}\uFF08${type}\uFF09` : type);
3628
+ }
3358
3629
  }
3359
3630
  }
3360
3631
  if (loading) return;
3632
+ applyChartA11yPlus(view, spec, type, formatValue);
3361
3633
  paintChartMarks(root, view, spec, formatValue, warnedMarks);
3362
3634
  bindZoomGesture();
3363
3635
  };
@@ -3439,6 +3711,7 @@ function renderChart(el, raw) {
3439
3711
  releaseFluidWidth(root);
3440
3712
  hiddenLegendKeys.delete(root);
3441
3713
  zoomDragCleanup?.();
3714
+ root.removeEventListener("keydown", onKbKeydown);
3442
3715
  root.textContent = "";
3443
3716
  root.classList.remove("is-loading");
3444
3717
  unbindEvents();
@@ -3507,15 +3780,17 @@ function renderPermissionNotice(p) {
3507
3780
  function renderBody(text, citations) {
3508
3781
  const box = h("div", "icen-kb-answer-body");
3509
3782
  for (const seg of parseInlineCitations(text)) {
3510
- if (typeof seg.n === "number" && citations && seg.n >= 1 && seg.n <= citations.length) {
3511
- const sup = h("sup", "icen-kb-citation", `[${seg.n}]`);
3512
- sup.dataset.icenCite = String(seg.n);
3513
- const c = citations[seg.n - 1];
3514
- if (c?.title) sup.title = c.title;
3515
- box.appendChild(sup);
3516
- } else {
3517
- box.appendChild(document.createTextNode(seg.text));
3783
+ if (typeof seg.n === "number" && citations) {
3784
+ const c = citations.find((x) => x.index === seg.n) ?? (seg.n >= 1 && seg.n <= citations.length ? citations[seg.n - 1] : void 0);
3785
+ if (c) {
3786
+ const sup = h("sup", "icen-kb-citation", `[${seg.n}]`);
3787
+ sup.dataset.icenCite = String(seg.n);
3788
+ if (c.title) sup.title = c.title;
3789
+ box.appendChild(sup);
3790
+ continue;
3791
+ }
3518
3792
  }
3793
+ box.appendChild(document.createTextNode(seg.text));
3519
3794
  }
3520
3795
  return box;
3521
3796
  }
@@ -1,5 +1,5 @@
1
- import { KbAuditEntry, KbHygieneIssue } from './kb-core.js';
2
- import './ai-core.js';
1
+ import { KbAuditEntry, KbHygieneIssue } from './kb-core.mjs';
2
+ import './ai-core.mjs';
3
3
 
4
4
  /** renderKbAudit 入参(宽进:契约对象或素对象皆可,内部 normalize) */
5
5
  interface KbAuditOptions {
@@ -21,6 +21,7 @@ var ICEN_LOCALE_ZH_CN = {
21
21
  "aiChat.roleTool": "\u5DE5",
22
22
  "aiChat.roleUser": "\u6211",
23
23
  "aiChat.thinking": "\u601D\u8003 {p0}",
24
+ "aiChat.thinkingNow": "\u6B63\u5728\u601D\u8003\u2026",
24
25
  /* ── aiComposer ── */
25
26
  "aiComposer.attachAgent": "\u4EE3\u7406",
26
27
  "aiComposer.library": "\u6DFB\u52A0\u4E0A\u4E0B\u6587\u4E0E\u547D\u4EE4",
@@ -203,6 +204,19 @@ var ICEN_LOCALE_ZH_CN = {
203
204
  "charts.noData": "\u6682\u65E0\u6570\u636E",
204
205
  "charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
205
206
  "charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
207
+ "charts.a11y.keyboardHint": "\u65B9\u5411\u952E\u9010\u70B9\u6D4F\u89C8\uFF0CHome/End \u8DF3\u9996\u5C3E\uFF0CEsc \u91CD\u7F6E\u7F29\u653E",
208
+ "charts.a11y.max": "\u6700\u5927 {p0}\uFF08{p1}\uFF09",
209
+ "charts.a11y.min": "\u6700\u5C0F {p0}\uFF08{p1}\uFF09",
210
+ "charts.a11y.point": "{p0}\uFF1A{p1}\uFF0C\u7B2C {p2}/{p3} \u70B9",
211
+ "charts.a11y.pointSeries": "{p0} \xB7 {p1}\uFF1A{p2}\uFF0C\u7B2C {p3}/{p4} \u70B9",
212
+ "charts.a11y.range": "\u7C7B\u76EE {p0} \u81F3 {p1}",
213
+ "charts.a11y.scatterRange": "x \u8303\u56F4 {p0}\u2013{p1}\uFF0Cy \u8303\u56F4 {p2}\u2013{p3}",
214
+ "charts.a11y.seriesCount": "{p0} \u4E2A\u7CFB\u5217",
215
+ "charts.a11y.tableCaption": "{p0} \u6570\u636E\u8868",
216
+ "charts.a11y.trend": "\u9996\u7CFB\u5217\u8D8B\u52BF{p0}",
217
+ "charts.a11y.trendDown": "\u4E0B\u964D",
218
+ "charts.a11y.trendFlat": "\u6301\u5E73",
219
+ "charts.a11y.trendUp": "\u4E0A\u5347",
206
220
  "charts.type.area": "\u9762\u79EF\u56FE",
207
221
  "charts.type.donut": "\u73AF\u5F62\u56FE",
208
222
  "charts.type.gauge": "\u4EEA\u8868\u76D8",
@@ -1,6 +1,6 @@
1
- import { KbCanvasVersion } from './kb-core.js';
2
- import { renderAiDiff } from './ai-diff.js';
3
- import './ai-core.js';
1
+ import { KbCanvasVersion } from './kb-core.mjs';
2
+ import { renderAiDiff } from './ai-diff.mjs';
3
+ import './ai-core.mjs';
4
4
 
5
5
  interface KbCanvasOptions {
6
6
  /** 左栏最小占比(同时约束右栏 1-minRatio);默认 0.2,钳制到 [0.05, 0.5] */
@@ -57,6 +57,7 @@ var ICEN_LOCALE_ZH_CN = {
57
57
  "aiChat.roleTool": "\u5DE5",
58
58
  "aiChat.roleUser": "\u6211",
59
59
  "aiChat.thinking": "\u601D\u8003 {p0}",
60
+ "aiChat.thinkingNow": "\u6B63\u5728\u601D\u8003\u2026",
60
61
  /* ── aiComposer ── */
61
62
  "aiComposer.attachAgent": "\u4EE3\u7406",
62
63
  "aiComposer.library": "\u6DFB\u52A0\u4E0A\u4E0B\u6587\u4E0E\u547D\u4EE4",
@@ -239,6 +240,19 @@ var ICEN_LOCALE_ZH_CN = {
239
240
  "charts.noData": "\u6682\u65E0\u6570\u636E",
240
241
  "charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
241
242
  "charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
243
+ "charts.a11y.keyboardHint": "\u65B9\u5411\u952E\u9010\u70B9\u6D4F\u89C8\uFF0CHome/End \u8DF3\u9996\u5C3E\uFF0CEsc \u91CD\u7F6E\u7F29\u653E",
244
+ "charts.a11y.max": "\u6700\u5927 {p0}\uFF08{p1}\uFF09",
245
+ "charts.a11y.min": "\u6700\u5C0F {p0}\uFF08{p1}\uFF09",
246
+ "charts.a11y.point": "{p0}\uFF1A{p1}\uFF0C\u7B2C {p2}/{p3} \u70B9",
247
+ "charts.a11y.pointSeries": "{p0} \xB7 {p1}\uFF1A{p2}\uFF0C\u7B2C {p3}/{p4} \u70B9",
248
+ "charts.a11y.range": "\u7C7B\u76EE {p0} \u81F3 {p1}",
249
+ "charts.a11y.scatterRange": "x \u8303\u56F4 {p0}\u2013{p1}\uFF0Cy \u8303\u56F4 {p2}\u2013{p3}",
250
+ "charts.a11y.seriesCount": "{p0} \u4E2A\u7CFB\u5217",
251
+ "charts.a11y.tableCaption": "{p0} \u6570\u636E\u8868",
252
+ "charts.a11y.trend": "\u9996\u7CFB\u5217\u8D8B\u52BF{p0}",
253
+ "charts.a11y.trendDown": "\u4E0B\u964D",
254
+ "charts.a11y.trendFlat": "\u6301\u5E73",
255
+ "charts.a11y.trendUp": "\u4E0A\u5347",
242
256
  "charts.type.area": "\u9762\u79EF\u56FE",
243
257
  "charts.type.donut": "\u73AF\u5F62\u56FE",
244
258
  "charts.type.gauge": "\u4EEA\u8868\u76D8",
@@ -1,5 +1,5 @@
1
- import { KbChainStep } from './kb-core.js';
2
- import './ai-core.js';
1
+ import { KbChainStep } from './kb-core.mjs';
2
+ import './ai-core.mjs';
3
3
 
4
4
  /**
5
5
  * 渲染工具链条横向摘要条(与 ai-tool-call 单卡互补的「一屏看完整个链」视角)。
@@ -21,6 +21,7 @@ var ICEN_LOCALE_ZH_CN = {
21
21
  "aiChat.roleTool": "\u5DE5",
22
22
  "aiChat.roleUser": "\u6211",
23
23
  "aiChat.thinking": "\u601D\u8003 {p0}",
24
+ "aiChat.thinkingNow": "\u6B63\u5728\u601D\u8003\u2026",
24
25
  /* ── aiComposer ── */
25
26
  "aiComposer.attachAgent": "\u4EE3\u7406",
26
27
  "aiComposer.library": "\u6DFB\u52A0\u4E0A\u4E0B\u6587\u4E0E\u547D\u4EE4",
@@ -203,6 +204,19 @@ var ICEN_LOCALE_ZH_CN = {
203
204
  "charts.noData": "\u6682\u65E0\u6570\u636E",
204
205
  "charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
205
206
  "charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
207
+ "charts.a11y.keyboardHint": "\u65B9\u5411\u952E\u9010\u70B9\u6D4F\u89C8\uFF0CHome/End \u8DF3\u9996\u5C3E\uFF0CEsc \u91CD\u7F6E\u7F29\u653E",
208
+ "charts.a11y.max": "\u6700\u5927 {p0}\uFF08{p1}\uFF09",
209
+ "charts.a11y.min": "\u6700\u5C0F {p0}\uFF08{p1}\uFF09",
210
+ "charts.a11y.point": "{p0}\uFF1A{p1}\uFF0C\u7B2C {p2}/{p3} \u70B9",
211
+ "charts.a11y.pointSeries": "{p0} \xB7 {p1}\uFF1A{p2}\uFF0C\u7B2C {p3}/{p4} \u70B9",
212
+ "charts.a11y.range": "\u7C7B\u76EE {p0} \u81F3 {p1}",
213
+ "charts.a11y.scatterRange": "x \u8303\u56F4 {p0}\u2013{p1}\uFF0Cy \u8303\u56F4 {p2}\u2013{p3}",
214
+ "charts.a11y.seriesCount": "{p0} \u4E2A\u7CFB\u5217",
215
+ "charts.a11y.tableCaption": "{p0} \u6570\u636E\u8868",
216
+ "charts.a11y.trend": "\u9996\u7CFB\u5217\u8D8B\u52BF{p0}",
217
+ "charts.a11y.trendDown": "\u4E0B\u964D",
218
+ "charts.a11y.trendFlat": "\u6301\u5E73",
219
+ "charts.a11y.trendUp": "\u4E0A\u5347",
206
220
  "charts.type.area": "\u9762\u79EF\u56FE",
207
221
  "charts.type.donut": "\u73AF\u5F62\u56FE",
208
222
  "charts.type.gauge": "\u4EEA\u8868\u76D8",
@@ -1,5 +1,5 @@
1
- import { KbCheckpoint } from './kb-core.js';
2
- import './ai-core.js';
1
+ import { KbCheckpoint } from './kb-core.mjs';
2
+ import './ai-core.mjs';
3
3
 
4
4
  /**
5
5
  * 渲染检查点时间轴(时钟 icon + relativeTime + label/reason,reason 缺 label 时顶替)。
@@ -21,6 +21,7 @@ var ICEN_LOCALE_ZH_CN = {
21
21
  "aiChat.roleTool": "\u5DE5",
22
22
  "aiChat.roleUser": "\u6211",
23
23
  "aiChat.thinking": "\u601D\u8003 {p0}",
24
+ "aiChat.thinkingNow": "\u6B63\u5728\u601D\u8003\u2026",
24
25
  /* ── aiComposer ── */
25
26
  "aiComposer.attachAgent": "\u4EE3\u7406",
26
27
  "aiComposer.library": "\u6DFB\u52A0\u4E0A\u4E0B\u6587\u4E0E\u547D\u4EE4",
@@ -203,6 +204,19 @@ var ICEN_LOCALE_ZH_CN = {
203
204
  "charts.noData": "\u6682\u65E0\u6570\u636E",
204
205
  "charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
205
206
  "charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
207
+ "charts.a11y.keyboardHint": "\u65B9\u5411\u952E\u9010\u70B9\u6D4F\u89C8\uFF0CHome/End \u8DF3\u9996\u5C3E\uFF0CEsc \u91CD\u7F6E\u7F29\u653E",
208
+ "charts.a11y.max": "\u6700\u5927 {p0}\uFF08{p1}\uFF09",
209
+ "charts.a11y.min": "\u6700\u5C0F {p0}\uFF08{p1}\uFF09",
210
+ "charts.a11y.point": "{p0}\uFF1A{p1}\uFF0C\u7B2C {p2}/{p3} \u70B9",
211
+ "charts.a11y.pointSeries": "{p0} \xB7 {p1}\uFF1A{p2}\uFF0C\u7B2C {p3}/{p4} \u70B9",
212
+ "charts.a11y.range": "\u7C7B\u76EE {p0} \u81F3 {p1}",
213
+ "charts.a11y.scatterRange": "x \u8303\u56F4 {p0}\u2013{p1}\uFF0Cy \u8303\u56F4 {p2}\u2013{p3}",
214
+ "charts.a11y.seriesCount": "{p0} \u4E2A\u7CFB\u5217",
215
+ "charts.a11y.tableCaption": "{p0} \u6570\u636E\u8868",
216
+ "charts.a11y.trend": "\u9996\u7CFB\u5217\u8D8B\u52BF{p0}",
217
+ "charts.a11y.trendDown": "\u4E0B\u964D",
218
+ "charts.a11y.trendFlat": "\u6301\u5E73",
219
+ "charts.a11y.trendUp": "\u4E0A\u5347",
206
220
  "charts.type.area": "\u9762\u79EF\u56FE",
207
221
  "charts.type.donut": "\u73AF\u5F62\u56FE",
208
222
  "charts.type.gauge": "\u4EEA\u8868\u76D8",