@icen.ai/ui 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (431) hide show
  1. package/AGENTS.md +82 -254
  2. package/LICENSE +21 -0
  3. package/README.md +60 -96
  4. package/dist/base.css +258 -188
  5. package/dist/behaviors/accordion.mjs +8 -8
  6. package/dist/behaviors/ai-branch.d.mts +1 -1
  7. package/dist/behaviors/ai-branch.mjs +1011 -94
  8. package/dist/behaviors/ai-chat.d.mts +9 -9
  9. package/dist/behaviors/ai-chat.mjs +1122 -169
  10. package/dist/behaviors/ai-composer.d.mts +47 -15
  11. package/dist/behaviors/ai-composer.mjs +2018 -534
  12. package/dist/behaviors/ai-core.d.mts +1 -1
  13. package/dist/behaviors/ai-core.mjs +1017 -107
  14. package/dist/behaviors/ai-diff.mjs +1020 -127
  15. package/dist/behaviors/ai-feedback.d.mts +1 -1
  16. package/dist/behaviors/ai-feedback.mjs +1036 -126
  17. package/dist/behaviors/ai-panel.d.mts +10 -10
  18. package/dist/behaviors/ai-panel.mjs +1285 -266
  19. package/dist/behaviors/ai-provider.d.mts +1 -1
  20. package/dist/behaviors/ai-provider.mjs +1004 -101
  21. package/dist/behaviors/ai-threads.d.mts +1 -1
  22. package/dist/behaviors/ai-threads.mjs +1069 -154
  23. package/dist/behaviors/ai-tool.d.mts +3 -3
  24. package/dist/behaviors/ai-tool.mjs +2087 -413
  25. package/dist/behaviors/ai-tools.d.mts +89 -16
  26. package/dist/behaviors/ai-tools.mjs +5365 -380
  27. package/dist/behaviors/autocomplete.d.mts +53 -0
  28. package/dist/behaviors/autocomplete.mjs +1601 -0
  29. package/dist/behaviors/back-top.d.mts +1 -1
  30. package/dist/behaviors/back-top.mjs +952 -14
  31. package/dist/behaviors/carousel.d.mts +1 -1
  32. package/dist/behaviors/carousel.mjs +914 -12
  33. package/dist/behaviors/cascader.d.mts +48 -0
  34. package/dist/behaviors/cascader.mjs +1867 -0
  35. package/dist/behaviors/charts.d.mts +72 -8
  36. package/dist/behaviors/charts.mjs +1953 -272
  37. package/dist/behaviors/code-block.d.mts +36 -0
  38. package/dist/behaviors/code-block.mjs +1619 -0
  39. package/dist/behaviors/command-palette.d.mts +9 -6
  40. package/dist/behaviors/command-palette.mjs +164 -62
  41. package/dist/behaviors/context-menu.d.mts +10 -9
  42. package/dist/behaviors/context-menu.mjs +1113 -44
  43. package/dist/behaviors/controls.d.mts +21 -21
  44. package/dist/behaviors/controls.mjs +1024 -134
  45. package/dist/behaviors/copy.d.mts +21 -2
  46. package/dist/behaviors/copy.mjs +1207 -42
  47. package/dist/behaviors/datatable.d.mts +55 -5
  48. package/dist/behaviors/datatable.mjs +2033 -212
  49. package/dist/behaviors/date-picker.d.mts +0 -1
  50. package/dist/behaviors/date-picker.mjs +1341 -293
  51. package/dist/behaviors/design.d.mts +54 -0
  52. package/dist/behaviors/design.mjs +109 -0
  53. package/dist/behaviors/dropdown.d.mts +5 -6
  54. package/dist/behaviors/dropdown.mjs +262 -110
  55. package/dist/behaviors/events.d.mts +127 -10
  56. package/dist/behaviors/events.mjs +58 -3
  57. package/dist/behaviors/feedback.d.mts +30 -0
  58. package/dist/behaviors/feedback.mjs +296 -0
  59. package/dist/behaviors/focus.d.mts +8 -0
  60. package/dist/behaviors/focus.mjs +24 -0
  61. package/dist/behaviors/form-validate.d.mts +111 -0
  62. package/dist/behaviors/form-validate.mjs +1746 -0
  63. package/dist/behaviors/i18n.d.mts +790 -0
  64. package/dist/behaviors/i18n.mjs +1713 -0
  65. package/dist/behaviors/icons.d.mts +93 -0
  66. package/dist/behaviors/icons.mjs +113 -0
  67. package/dist/behaviors/input.d.mts +9 -1
  68. package/dist/behaviors/input.mjs +1059 -60
  69. package/dist/behaviors/kb-access.d.mts +3 -3
  70. package/dist/behaviors/kb-access.mjs +2135 -239
  71. package/dist/behaviors/kb-acl.d.mts +8 -8
  72. package/dist/behaviors/kb-acl.mjs +1120 -179
  73. package/dist/behaviors/kb-answer.d.mts +2 -2
  74. package/dist/behaviors/kb-answer.mjs +2120 -435
  75. package/dist/behaviors/kb-audit.d.mts +3 -3
  76. package/dist/behaviors/kb-audit.mjs +1077 -154
  77. package/dist/behaviors/kb-canvas.d.mts +3 -3
  78. package/dist/behaviors/kb-canvas.mjs +1101 -177
  79. package/dist/behaviors/kb-chain.d.mts +2 -2
  80. package/dist/behaviors/kb-chain.mjs +1023 -100
  81. package/dist/behaviors/kb-checkpoint.d.mts +3 -3
  82. package/dist/behaviors/kb-checkpoint.mjs +1320 -169
  83. package/dist/behaviors/kb-chunks.d.mts +2 -2
  84. package/dist/behaviors/kb-chunks.mjs +1153 -213
  85. package/dist/behaviors/kb-citation.d.mts +3 -3
  86. package/dist/behaviors/kb-citation.mjs +1221 -185
  87. package/dist/behaviors/kb-clarify.d.mts +2 -2
  88. package/dist/behaviors/kb-clarify.mjs +1059 -130
  89. package/dist/behaviors/kb-conflict.d.mts +2 -2
  90. package/dist/behaviors/kb-conflict.mjs +1042 -119
  91. package/dist/behaviors/kb-connector.d.mts +2 -2
  92. package/dist/behaviors/kb-connector.mjs +1105 -176
  93. package/dist/behaviors/kb-core.d.mts +7 -2
  94. package/dist/behaviors/kb-core.mjs +1078 -162
  95. package/dist/behaviors/kb-eval.d.mts +2 -2
  96. package/dist/behaviors/kb-eval.mjs +1977 -144
  97. package/dist/behaviors/kb-explain.d.mts +3 -3
  98. package/dist/behaviors/kb-explain.mjs +1037 -104
  99. package/dist/behaviors/kb-filter.d.mts +2 -2
  100. package/dist/behaviors/kb-filter.mjs +2014 -178
  101. package/dist/behaviors/kb-gap.d.mts +3 -3
  102. package/dist/behaviors/kb-gap.mjs +1044 -121
  103. package/dist/behaviors/kb-hittest.d.mts +3 -3
  104. package/dist/behaviors/kb-hittest.mjs +1095 -151
  105. package/dist/behaviors/kb-metadata.mjs +1058 -130
  106. package/dist/behaviors/kb-passage.d.mts +4 -4
  107. package/dist/behaviors/kb-passage.mjs +1102 -161
  108. package/dist/behaviors/kb-pipeline.d.mts +4 -4
  109. package/dist/behaviors/kb-pipeline.mjs +1083 -162
  110. package/dist/behaviors/kb-qa.mjs +1089 -160
  111. package/dist/behaviors/kb-rerank.d.mts +2 -2
  112. package/dist/behaviors/kb-rerank.mjs +1048 -114
  113. package/dist/behaviors/kb-retrieval.d.mts +2 -2
  114. package/dist/behaviors/kb-retrieval.mjs +2079 -226
  115. package/dist/behaviors/kb-review.d.mts +2 -2
  116. package/dist/behaviors/kb-review.mjs +1996 -159
  117. package/dist/behaviors/kb-sandbox.d.mts +3 -3
  118. package/dist/behaviors/kb-sandbox.mjs +1033 -105
  119. package/dist/behaviors/kb-segment.d.mts +2 -2
  120. package/dist/behaviors/kb-segment.mjs +1112 -179
  121. package/dist/behaviors/kb-select.d.mts +24 -0
  122. package/dist/behaviors/kb-select.mjs +1995 -0
  123. package/dist/behaviors/kb-sources.d.mts +3 -3
  124. package/dist/behaviors/kb-sources.mjs +1085 -170
  125. package/dist/behaviors/kb-sql.d.mts +3 -3
  126. package/dist/behaviors/kb-sql.mjs +1144 -226
  127. package/dist/behaviors/kb-trace.d.mts +3 -3
  128. package/dist/behaviors/kb-trace.mjs +1051 -131
  129. package/dist/behaviors/kb-visibility.d.mts +2 -2
  130. package/dist/behaviors/kb-visibility.mjs +1087 -158
  131. package/dist/behaviors/kb-who-can.d.mts +2 -2
  132. package/dist/behaviors/kb-who-can.mjs +1980 -137
  133. package/dist/behaviors/mentions.d.mts +93 -0
  134. package/dist/behaviors/mentions.mjs +2153 -0
  135. package/dist/behaviors/modal.d.mts +4 -3
  136. package/dist/behaviors/modal.mjs +1056 -33
  137. package/dist/behaviors/nav.d.mts +1 -1
  138. package/dist/behaviors/nav.mjs +6 -6
  139. package/dist/behaviors/notification.d.mts +16 -8
  140. package/dist/behaviors/notification.mjs +1629 -268
  141. package/dist/behaviors/panel.d.mts +4 -0
  142. package/dist/behaviors/panel.mjs +995 -0
  143. package/dist/behaviors/popover.d.mts +28 -5
  144. package/dist/behaviors/popover.mjs +225 -24
  145. package/dist/behaviors/scroll-area.d.mts +17 -0
  146. package/dist/behaviors/scroll-area.mjs +59 -0
  147. package/dist/behaviors/select.d.mts +5 -2
  148. package/dist/behaviors/select.mjs +1416 -117
  149. package/dist/behaviors/sidebar.d.mts +1 -1
  150. package/dist/behaviors/sidebar.mjs +13 -13
  151. package/dist/behaviors/slider.d.mts +1 -1
  152. package/dist/behaviors/slider.mjs +12 -12
  153. package/dist/behaviors/split-pane.d.mts +1 -1
  154. package/dist/behaviors/split-pane.mjs +9 -7
  155. package/dist/behaviors/suggestions.d.mts +27 -0
  156. package/dist/behaviors/suggestions.mjs +1090 -0
  157. package/dist/behaviors/svg-parse.d.mts +14 -0
  158. package/dist/behaviors/svg-parse.mjs +37 -0
  159. package/dist/behaviors/tabs.d.mts +2 -2
  160. package/dist/behaviors/tabs.mjs +35 -25
  161. package/dist/behaviors/tag-input.d.mts +23 -5
  162. package/dist/behaviors/tag-input.mjs +1360 -104
  163. package/dist/behaviors/theme-switcher.d.mts +24 -0
  164. package/dist/behaviors/theme-switcher.mjs +1996 -0
  165. package/dist/behaviors/theme.d.mts +15 -8
  166. package/dist/behaviors/theme.mjs +406 -30
  167. package/dist/behaviors/toast.d.mts +24 -25
  168. package/dist/behaviors/toast.mjs +1267 -88
  169. package/dist/behaviors/tooltip.d.mts +4 -0
  170. package/dist/behaviors/tooltip.mjs +378 -0
  171. package/dist/behaviors/tree-select.d.mts +69 -0
  172. package/dist/behaviors/tree-select.mjs +1921 -0
  173. package/dist/behaviors/tree.d.mts +1 -1
  174. package/dist/behaviors/tree.mjs +18 -18
  175. package/dist/behaviors/upload.d.mts +3 -2
  176. package/dist/behaviors/upload.mjs +1077 -66
  177. package/dist/behaviors/url-safety.d.mts +8 -0
  178. package/dist/behaviors/url-safety.mjs +11 -0
  179. package/dist/cli.mjs +5 -6
  180. package/dist/components/accordion.d.mts +2 -0
  181. package/dist/components/ai-branch.d.mts +2 -0
  182. package/dist/components/ai-chat.css +682 -582
  183. package/dist/components/ai-chat.d.mts +2 -0
  184. package/dist/components/ai-composer.d.mts +2 -0
  185. package/dist/components/ai-context.d.mts +2 -0
  186. package/dist/components/ai-context.mjs +1 -0
  187. package/dist/components/ai-diff.css +153 -132
  188. package/dist/components/ai-diff.d.mts +2 -0
  189. package/dist/components/ai-feedback.d.mts +2 -0
  190. package/dist/components/ai-files.d.mts +2 -0
  191. package/dist/components/ai-message.d.mts +2 -0
  192. package/dist/components/ai-panel.css +353 -343
  193. package/dist/components/ai-reasoning.d.mts +2 -0
  194. package/dist/components/ai-subagent.d.mts +2 -0
  195. package/dist/components/ai-subagent.mjs +1 -0
  196. package/dist/components/ai-threads.d.mts +2 -0
  197. package/dist/components/ai-todo.d.mts +2 -0
  198. package/dist/components/ai-todo.mjs +1 -0
  199. package/dist/components/ai-tool-call.d.mts +2 -0
  200. package/dist/components/ai-tool-call.mjs +1 -0
  201. package/dist/components/ai-tool.css +397 -242
  202. package/dist/components/ai-usage.d.mts +2 -0
  203. package/dist/components/alert.d.mts +2 -0
  204. package/dist/components/autocomplete.css +61 -0
  205. package/dist/components/autocomplete.d.mts +2 -0
  206. package/dist/components/autocomplete.mjs +3 -0
  207. package/dist/components/avatar.d.mts +2 -0
  208. package/dist/components/back-top.css +74 -40
  209. package/dist/components/back-top.d.mts +2 -0
  210. package/dist/components/badge.css +44 -41
  211. package/dist/components/badge.d.mts +2 -0
  212. package/dist/components/breadcrumb.css +85 -46
  213. package/dist/components/breadcrumb.d.mts +2 -0
  214. package/dist/components/btn.css +105 -94
  215. package/dist/components/btn.d.mts +2 -0
  216. package/dist/components/card.css +124 -113
  217. package/dist/components/card.d.mts +2 -0
  218. package/dist/components/carousel.d.mts +2 -0
  219. package/dist/components/cascader.css +332 -0
  220. package/dist/components/cascader.d.mts +2 -0
  221. package/dist/components/cascader.mjs +3 -0
  222. package/dist/components/chart-area.css +54 -2
  223. package/dist/components/chart-area.d.mts +2 -0
  224. package/dist/components/chart-bar.css +147 -38
  225. package/dist/components/chart-bar.d.mts +2 -0
  226. package/dist/components/chart-calendar.d.mts +2 -0
  227. package/dist/components/chart-gauge.css +36 -13
  228. package/dist/components/chart-gauge.d.mts +2 -0
  229. package/dist/components/chart-graph.css +35 -20
  230. package/dist/components/chart-graph.d.mts +2 -0
  231. package/dist/components/chart-heatmap.css +67 -39
  232. package/dist/components/chart-heatmap.d.mts +2 -0
  233. package/dist/components/chart-line.css +62 -3
  234. package/dist/components/chart-line.d.mts +2 -0
  235. package/dist/components/chart-map.d.mts +2 -0
  236. package/dist/components/chart-pie.css +38 -6
  237. package/dist/components/chart-pie.d.mts +2 -0
  238. package/dist/components/chart-radar.css +57 -5
  239. package/dist/components/chart-radar.d.mts +2 -0
  240. package/dist/components/chart-scatter.css +47 -7
  241. package/dist/components/chart-scatter.d.mts +2 -0
  242. package/dist/components/chart-sparkline.css +25 -2
  243. package/dist/components/chart-sparkline.d.mts +2 -0
  244. package/dist/components/chart-stack.css +27 -13
  245. package/dist/components/chart-stack.d.mts +2 -0
  246. package/dist/components/charts.css +220 -84
  247. package/dist/components/charts.d.mts +2 -0
  248. package/dist/components/code-block.css +420 -0
  249. package/dist/components/code-block.d.mts +2 -0
  250. package/dist/components/code-block.mjs +4 -0
  251. package/dist/components/command-palette.css +150 -122
  252. package/dist/components/command-palette.d.mts +2 -0
  253. package/dist/components/content.css +274 -263
  254. package/dist/components/context-menu.d.mts +2 -0
  255. package/dist/components/copy.css +73 -45
  256. package/dist/components/copy.d.mts +2 -0
  257. package/dist/components/datatable.css +457 -202
  258. package/dist/components/datatable.d.mts +2 -0
  259. package/dist/components/date-picker.css +136 -105
  260. package/dist/components/date-picker.d.mts +2 -0
  261. package/dist/components/desc.d.mts +2 -0
  262. package/dist/components/dropdown.d.mts +2 -0
  263. package/dist/components/empty.css +72 -69
  264. package/dist/components/empty.d.mts +2 -0
  265. package/dist/components/feedback.css +211 -191
  266. package/dist/components/form-validate.css +134 -0
  267. package/dist/components/form-validate.d.mts +2 -0
  268. package/dist/components/form-validate.mjs +3 -0
  269. package/dist/components/form.css +157 -131
  270. package/dist/components/form.d.mts +2 -0
  271. package/dist/components/icon.css +113 -0
  272. package/dist/components/icon.d.mts +2 -0
  273. package/dist/components/icon.mjs +3 -0
  274. package/dist/components/input.css +163 -108
  275. package/dist/components/input.d.mts +2 -0
  276. package/dist/components/kb-access.d.mts +2 -0
  277. package/dist/components/kb-acl.d.mts +2 -0
  278. package/dist/components/kb-agent.css +300 -206
  279. package/dist/components/kb-answer.d.mts +2 -0
  280. package/dist/components/kb-audit.d.mts +2 -0
  281. package/dist/components/kb-canvas.d.mts +2 -0
  282. package/dist/components/kb-chain.d.mts +2 -0
  283. package/dist/components/kb-checkpoint.d.mts +2 -0
  284. package/dist/components/kb-chunks.d.mts +2 -0
  285. package/dist/components/kb-citation.d.mts +2 -0
  286. package/dist/components/kb-clarify.d.mts +2 -0
  287. package/dist/components/kb-conflict.d.mts +2 -0
  288. package/dist/components/kb-connector.d.mts +2 -0
  289. package/dist/components/kb-data.css +431 -315
  290. package/dist/components/kb-eval.d.mts +2 -0
  291. package/dist/components/kb-explain.d.mts +2 -0
  292. package/dist/components/kb-filter.d.mts +2 -0
  293. package/dist/components/kb-gap.d.mts +2 -0
  294. package/dist/components/kb-ground.css +333 -229
  295. package/dist/components/kb-hittest.d.mts +2 -0
  296. package/dist/components/kb-ingest.css +613 -434
  297. package/dist/components/kb-metadata.d.mts +2 -0
  298. package/dist/components/kb-ops.css +422 -302
  299. package/dist/components/kb-passage.d.mts +2 -0
  300. package/dist/components/kb-perm.css +374 -314
  301. package/dist/components/kb-pipeline.d.mts +2 -0
  302. package/dist/components/kb-qa.d.mts +2 -0
  303. package/dist/components/kb-rerank.d.mts +2 -0
  304. package/dist/components/kb-retrieval.d.mts +2 -0
  305. package/dist/components/kb-review.d.mts +2 -0
  306. package/dist/components/kb-sandbox.d.mts +2 -0
  307. package/dist/components/kb-search.css +653 -459
  308. package/dist/components/kb-segment.d.mts +2 -0
  309. package/dist/components/kb-sources.d.mts +2 -0
  310. package/dist/components/kb-sql.d.mts +2 -0
  311. package/dist/components/kb-trace.d.mts +2 -0
  312. package/dist/components/kb-visibility.d.mts +2 -0
  313. package/dist/components/kb-who-can.d.mts +2 -0
  314. package/dist/components/kb.css +170 -135
  315. package/dist/components/kb.d.mts +2 -0
  316. package/dist/components/kbd.d.mts +2 -0
  317. package/dist/components/layout.css +86 -83
  318. package/dist/components/layout.d.mts +2 -0
  319. package/dist/components/list.d.mts +2 -0
  320. package/dist/components/material-chinese.css +83 -0
  321. package/dist/components/material-soviet.css +86 -0
  322. package/dist/components/material.css +318 -0
  323. package/dist/components/media-card.d.mts +2 -0
  324. package/dist/components/media.css +225 -176
  325. package/dist/components/mentions.css +190 -0
  326. package/dist/components/mentions.d.mts +2 -0
  327. package/dist/components/mentions.mjs +3 -0
  328. package/dist/components/menu.css +121 -109
  329. package/dist/components/modal.css +116 -118
  330. package/dist/components/modal.d.mts +2 -0
  331. package/dist/components/nav.css +136 -129
  332. package/dist/components/nav.d.mts +2 -0
  333. package/dist/components/notification.css +247 -177
  334. package/dist/components/notification.d.mts +2 -0
  335. package/dist/components/pagination.css +62 -57
  336. package/dist/components/pagination.d.mts +2 -0
  337. package/dist/components/panel.css +70 -68
  338. package/dist/components/panel.d.mts +2 -0
  339. package/dist/components/panel.mjs +1 -0
  340. package/dist/components/pill.css +83 -72
  341. package/dist/components/pill.d.mts +2 -0
  342. package/dist/components/popover.css +80 -57
  343. package/dist/components/popover.d.mts +2 -0
  344. package/dist/components/progress.d.mts +2 -0
  345. package/dist/components/rating.d.mts +2 -0
  346. package/dist/components/result.d.mts +2 -0
  347. package/dist/components/scroll-area.css +29 -54
  348. package/dist/components/scroll-area.d.mts +2 -0
  349. package/dist/components/scroll-area.mjs +1 -0
  350. package/dist/components/segmented.css +167 -146
  351. package/dist/components/segmented.d.mts +2 -0
  352. package/dist/components/select.css +250 -191
  353. package/dist/components/select.d.mts +2 -0
  354. package/dist/components/sidebar.css +157 -143
  355. package/dist/components/sidebar.d.mts +2 -0
  356. package/dist/components/skeleton.d.mts +2 -0
  357. package/dist/components/slider.css +135 -128
  358. package/dist/components/slider.d.mts +2 -0
  359. package/dist/components/spinner.d.mts +2 -0
  360. package/dist/components/split-pane.css +120 -108
  361. package/dist/components/split-pane.d.mts +2 -0
  362. package/dist/components/stat.css +116 -109
  363. package/dist/components/stat.d.mts +2 -0
  364. package/dist/components/steps.css +114 -108
  365. package/dist/components/steps.d.mts +2 -0
  366. package/dist/components/switch.css +192 -149
  367. package/dist/components/switch.d.mts +2 -0
  368. package/dist/components/table.css +158 -112
  369. package/dist/components/table.d.mts +2 -0
  370. package/dist/components/tabs.css +143 -116
  371. package/dist/components/tabs.d.mts +2 -0
  372. package/dist/components/tag-input.css +52 -133
  373. package/dist/components/tag-input.d.mts +2 -0
  374. package/dist/components/tag.css +90 -72
  375. package/dist/components/tag.d.mts +2 -0
  376. package/dist/components/theme-switcher.css +105 -0
  377. package/dist/components/theme-switcher.d.mts +2 -0
  378. package/dist/components/theme-switcher.mjs +3 -0
  379. package/dist/components/timeline.d.mts +2 -0
  380. package/dist/components/toast.css +115 -97
  381. package/dist/components/toast.d.mts +2 -0
  382. package/dist/components/toolbar.css +47 -43
  383. package/dist/components/toolbar.d.mts +2 -0
  384. package/dist/components/tooltip.css +103 -43
  385. package/dist/components/tooltip.d.mts +2 -0
  386. package/dist/components/tooltip.mjs +1 -0
  387. package/dist/components/tree-select.css +439 -0
  388. package/dist/components/tree-select.d.mts +2 -0
  389. package/dist/components/tree-select.mjs +3 -0
  390. package/dist/components/tree.d.mts +2 -0
  391. package/dist/components/upload.css +138 -97
  392. package/dist/components/upload.d.mts +2 -0
  393. package/dist/fonts/LICENSES/ark-pixel/OFL.txt +96 -0
  394. package/dist/fonts/LICENSES/cubic-11/OFL.txt +108 -0
  395. package/dist/fonts/LICENSES/galmuri/LICENSE.txt +93 -0
  396. package/dist/fonts/OFL.txt +96 -0
  397. package/dist/fonts/README.md +14 -0
  398. package/dist/fonts/fusion-pixel-12px-zh-hans.woff2 +0 -0
  399. package/dist/index.d.mts +85 -70
  400. package/dist/index.mjs +17330 -5773
  401. package/dist/react.d.mts +91 -0
  402. package/dist/react.mjs +8307 -0
  403. package/dist/registry.json +918 -70
  404. package/dist/tokens/chinese.css +44 -0
  405. package/dist/tokens/colors.css +371 -1222
  406. package/dist/tokens/design.css +209 -0
  407. package/dist/tokens/dtcg.json +15926 -0
  408. package/dist/tokens/figma.variables.json +10779 -0
  409. package/dist/tokens/icon-masks.css +78 -0
  410. package/dist/tokens/pixel.css +53 -0
  411. package/dist/tokens/scrollbars.css +40 -0
  412. package/dist/tokens/soviet.css +44 -0
  413. package/dist/tokens/style-profiles.css +36 -547
  414. package/dist/tokens/themes.json +308 -0
  415. package/dist/tokens/tokens-studio.json +11648 -0
  416. package/dist/tokens/typography.css +21 -18
  417. package/dist/tokens.css +1783 -1806
  418. package/dist/ui.css +14796 -10750
  419. package/dist/vue.d.mts +344 -0
  420. package/dist/vue.mjs +7876 -0
  421. package/docs/spec/ai-input-experience.md +75 -0
  422. package/docs/spec/ai-native.md +238 -147
  423. package/docs/spec/design-philosophy.md +189 -0
  424. package/docs/spec/design-primitives.md +196 -0
  425. package/docs/spec/kb-family.md +147 -115
  426. package/docs/spec/scrollbars.md +46 -0
  427. package/package.json +56 -8
  428. package/dist/retro-effects.css +0 -255
  429. package/dist/tokens/retro-effects.css +0 -255
  430. package/docs/research/2026-10-03-ai-kb-components.md +0 -392
  431. package/docs/research/2026-10-03-kb-permissions.md +0 -992
@@ -1,52 +1,1008 @@
1
+ // src/behaviors/icons.ts
2
+ var ICON_PATHS = {
3
+ file: "M6 2.5h5.5L16 7v9.5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-12a2 2 0 0 1 2-2ZM11.5 2.5V7H16",
4
+ folder: "M3 5a1.5 1.5 0 0 1 1.5-1.5H8l2 2h5.5A1.5 1.5 0 0 1 17 7v8a1.5 1.5 0 0 1-1.5 1.5h-11A1.5 1.5 0 0 1 3 15Z",
5
+ globe: "M17.5 10a7.5 7.5 0 1 1-15 0 7.5 7.5 0 0 1 15 0ZM2.5 10h15M10 2.5c-4 4-4 11 0 15 4-4 4-11 0-15Z",
6
+ document: "M6 2.5h5.5L16 7v9.5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-12a2 2 0 0 1 2-2ZM11.5 2.5V7H16M7 10.5h6M7 13.5h6",
7
+ agent: "M10 6V3M8 3h2M5 6h10a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2ZM1.5 10h1.5M17 10h1.5M7 10v2M13 10v2M8 14h4",
8
+ paperclip: "M14 7 8.3 12.7a1.6 1.6 0 0 1-2.3-2.3l6.3-6.3a3.2 3.2 0 0 1 4.5 4.5l-7 7a4.7 4.7 0 0 1-6.7-6.7l7-7",
9
+ stop: "M6.5 5h7A1.5 1.5 0 0 1 15 6.5v7a1.5 1.5 0 0 1-1.5 1.5h-7A1.5 1.5 0 0 1 5 13.5v-7A1.5 1.5 0 0 1 6.5 5Z",
10
+ terminal: "M5 3.5h10a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-9a2 2 0 0 1 2-2ZM6 7l3 3-3 3M11 13h3",
11
+ branch: "M6 6v8M14 6v2a4 4 0 0 1-4 4H6M8 4a2 2 0 1 1-4 0 2 2 0 0 1 4 0ZM8 16a2 2 0 1 1-4 0 2 2 0 0 1 4 0ZM16 4a2 2 0 1 1-4 0 2 2 0 0 1 4 0Z",
12
+ "line-numbers": "M3 5h2M3 10h2M3 15h2M8 5h9M8 10h9M8 15h9",
13
+ wrap: "M3 5h14M3 10h10a3 3 0 0 1 0 6h-3M12.5 13.5 10 16l2.5 2.5",
14
+ calendar: "M5.5 4h9A2.5 2.5 0 0 1 17 6.5v8a2.5 2.5 0 0 1-2.5 2.5h-9A2.5 2.5 0 0 1 3 14.5v-8A2.5 2.5 0 0 1 5.5 4ZM6.5 2.5v3M13.5 2.5v3M3 8h14M6.5 11h.1M10 11h.1M13.5 11h.1M6.5 14h.1M10 14h.1",
15
+ close: "M6 6l8 8M14 6l-8 8",
16
+ check: "M4.5 10.2l3.6 3.6 7.4-7.6",
17
+ "chevron-down": "M5.5 7.75 10 12.25l4.5-4.5",
18
+ "chevron-up": "M5.5 12.25 10 7.75l4.5 4.5",
19
+ "chevron-right": "M7.75 5.5 12.25 10l-4.5 4.5",
20
+ "chevron-left": "M12.25 5.5 7.75 10l4.5 4.5",
21
+ "arrow-right": "M3.5 10h13M11 4.5l5.5 5.5-5.5 5.5",
22
+ "arrow-left": "M16.5 10h-13M9 4.5 3.5 10 9 15.5",
23
+ "arrow-up": "M10 16.5v-13M4.5 9 10 3.5 15.5 9",
24
+ "arrow-down": "M10 3.5v13M4.5 11l5.5 5.5 5.5-5.5",
25
+ plus: "M10 4v12M4 10h12",
26
+ minus: "M4 10h12",
27
+ sort: "M6 15V4M3 7l3-3 3 3M14 5v11M11 13l3 3 3-3",
28
+ search: "M13.3 13.3 17 17M14.5 8.5a6 6 0 1 1-12 0 6 6 0 0 1 12 0",
29
+ sun: "M13.5 10a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0M10 1.75v1.5M10 16.75v1.5M1.75 10h1.5M16.75 10h1.5M4.17 4.17l1.06 1.06M14.77 14.77l1.06 1.06M4.17 15.83l1.06-1.06M14.77 5.23l1.06-1.06",
30
+ moon: "M17.25 11.15A7.5 7.5 0 0 1 8.85 2.75a7.5 7.5 0 1 0 8.4 8.4Z",
31
+ modern: "M6.5 3h7A3.5 3.5 0 0 1 17 6.5v7a3.5 3.5 0 0 1-3.5 3.5h-7A3.5 3.5 0 0 1 3 13.5v-7A3.5 3.5 0 0 1 6.5 3ZM7 10l3-3 3 3-3 3Z",
32
+ pixel: "M3 3h5v5H3ZM12 3h5v5h-5ZM3 12h5v5H3ZM12 12h5v5h-5Z",
33
+ chinese: "M3 8c3 0 5-2 7-5 2 3 4 5 7 5M4 8h12M6 8v8m8-8v8M3 16h14M8 16v-5h4v5",
34
+ soviet: "M3 17h14M5 17V8h4v9m0-12h6v12M7 8V5h2m2 3h2m-2 3h2m-2 3h2M10 5V3h4v2",
35
+ more: "M4 9.9v.2M10 9.9v.2M16 9.9v.2",
36
+ copy: "M7 7h8a2 2 0 0 1 2 2v6a2 2 0 0 1-2 2H9a2 2 0 0 1-2-2V7ZM13 7V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2",
37
+ edit: "M11.5 4.5l4 4M4 12l9-9a1.4 1.4 0 0 1 2 0l2 2a1.4 1.4 0 0 1 0 2l-9 9-5 1Z",
38
+ link: "M8 6l2-2a4.2 4.2 0 0 1 6 6l-2 2M12 14l-2 2a4.2 4.2 0 0 1-6-6l2-2M7 13l6-6",
39
+ trash: "M3.5 5.5h13M7 5.5V3h6v2.5M5 5.5l.7 11.5h8.6L15 5.5M8 9v5M12 9v5",
40
+ spinner: "M10 3a7 7 0 1 1-7 7",
41
+ "circle-check": "M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0ZM6 10l2.7 2.7 5.3-5.4",
42
+ "circle-error": "M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0ZM7.2 7.2l5.6 5.6M12.8 7.2l-5.6 5.6",
43
+ "circle-info": "M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0ZM10 9v5M10 6.1v.15",
44
+ "triangle-alert": "M8.7 3.5a1.5 1.5 0 0 1 2.6 0l6.4 11.3a1.5 1.5 0 0 1-1.3 2.2H3.6a1.5 1.5 0 0 1-1.3-2.2ZM10 7.2v4.4M10 14v.15",
45
+ refresh: "M16.5 7.2A7 7 0 0 0 4.3 5.9L2.5 8M2.5 3.5V8H7M3.5 12.8a7 7 0 0 0 12.2 1.3l1.8-2.1M13 12h4.5v4.5",
46
+ external: "M11.5 3H17v5.5M17 3l-8 8M8 3H5a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-3",
47
+ home: "M3.5 10.25 10 4l6.5 6.25M5.75 8.75v7a.75.75 0 0 0 .75.75h7.5a.75.75 0 0 0 .75-.75v-7",
48
+ settings: "M3.5 5.5h13M3.5 10h13M3.5 14.5h13M7 4v3M12.5 8.5v3M8 13v3",
49
+ star: "M10 2.5l2.4 5.1 5.6.4-4.2 3.7 1.3 5.5-5.1-3-5.1 3 1.3-5.5L1.8 8l5.6-.4Z",
50
+ eye: "M2.2 10s3-5.4 7.8-5.4S17.8 10 17.8 10s-3 5.4-7.8 5.4S2.2 10 2.2 10ZM10 12.4a2.4 2.4 0 1 0 0-4.8 2.4 2.4 0 0 0 0 4.8Z",
51
+ "eye-off": "M2.2 10s3-5.4 7.8-5.4S17.8 10 17.8 10s-3 5.4-7.8 5.4S2.2 10 2.2 10ZM10 12.4a2.4 2.4 0 1 0 0-4.8 2.4 2.4 0 0 0 0 4.8ZM3.5 3.5l13 13",
52
+ inbox: "M3.5 12.25h3.7l1.5 2.5h2.6l1.5-2.5h3.7M4.7 5.5l-1.2 6.75v3.25a1.5 1.5 0 0 0 1.5 1.5h10a1.5 1.5 0 0 0 1.5-1.5v-3.25L15.3 5.5a1.3 1.3 0 0 0-1.25-1H5.95a1.3 1.3 0 0 0-1.25 1Z",
53
+ bell: "M10 3.5a4.5 4.5 0 0 1 4.5 4.5c0 4.5 1.8 5.7 2.5 6.5H3c.7-.8 2.5-2 2.5-6.5A4.5 4.5 0 0 1 10 3.5ZM8.5 16.5a1.6 1.6 0 0 0 3 0",
54
+ users: "M13.8 16.5v-1.5a3.5 3.5 0 0 0-3.5-3.5H6.3a3.5 3.5 0 0 0-3.5 3.5v1.5M8.3 8.9a2.7 2.7 0 1 0 0-5.4 2.7 2.7 0 0 0 0 5.4ZM16.5 16.5v-1.3a3.3 3.3 0 0 0-2.3-3.1M12.3 3.7a2.7 2.7 0 0 1 0 5.2",
55
+ activity: "M17 10h-2.6l-2 5.8L8 4.2 6 10H3",
56
+ "trend-up": "M3.5 14.5l4.2-4.2 2.8 2.8 5.9-5.9M12.4 7.2h4.2v4.2",
57
+ "trend-down": "M3.5 5.5l4.2 4.2 2.8-2.8 5.9 5.9M12.4 12.8h4.2V8.6",
58
+ rocket: "M10 2.5c2 1.5 3.2 4 3.2 6.8 0 1.5-.3 2.9-.8 4.2H7.6c-.5-1.3-.8-2.7-.8-4.2 0-2.8 1.2-5.3 3.2-6.8ZM10 8.6a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM7.6 12.5 5.6 15.4c-.9.3-1.6 1-2 2M12.4 12.5l2 2.9c.9.3 1.6 1 2 2M8.7 13.8c0 1.8.5 3.1 1.3 4.2.8-1.1 1.3-2.4 1.3-4.2",
59
+ bold: "M6.5 4h4.2a3 3 0 0 1 0 6H6.5M6.5 10h5a3 3 0 0 1 0 6H6.5M6.5 4v12",
60
+ italic: "M8.5 4.5h7M4.5 15.5h7M12.5 4.5l-5 11",
61
+ underline: "M6 4v5.5a4 4 0 0 0 8 0V4M4.5 16h11",
62
+ "align-left": "M3.5 4.5h13M3.5 10h8.5M3.5 15.5h11",
63
+ "align-center": "M3.5 4.5h13M5.75 10h8.5M4.5 15.5h11",
64
+ "align-right": "M3.5 4.5h13M8 10h8.5M5.5 15.5h11",
65
+ list: "M6.5 5h10M6.5 10h10M6.5 15h10M3.5 5h.01M3.5 10h.01M3.5 15h.01",
66
+ server: "M3 3h14a1.5 1.5 0 0 1 1.5 1.5v2A1.5 1.5 0 0 1 17 8H3a1.5 1.5 0 0 1-1.5-1.5v-2A1.5 1.5 0 0 1 3 3ZM3 12h14a1.5 1.5 0 0 1 1.5 1.5v2A1.5 1.5 0 0 1 17 17H3a1.5 1.5 0 0 1-1.5-1.5v-2A1.5 1.5 0 0 1 3 12ZM5 5.5h.01M5 14.5h.01",
67
+ sparkle: "M10 2.5l1.6 4.3 4.3 1.6-4.3 1.6L10 14.3l-1.6-4.3-4.3-1.6 4.3-1.6ZM15.5 12.5l.8 2.1 2.1.8-2.1.8-.8 2.1-.8-2.1-2.1-.8 2.1-.8Z",
68
+ play: "M6.5 4.8v10.4c0 .9 1 1.5 1.8 1l8.3-5.2a1.2 1.2 0 0 0 0-2L8.3 3.8a1.2 1.2 0 0 0-1.8 1Z",
69
+ "chart-line": "M3.5 3.5v13h13M6.5 12l2.8-2.8 2.2 2.2 4-4.4",
70
+ layers: "M10 3.2 3.6 6.5 10 9.8l6.4-3.3ZM4.5 10.4 10 13.2l5.5-2.8M4.5 13.6 10 16.4l5.5-2.8",
71
+ box: "M17 6 10 3.2 3 6v8l7 2.8 7-2.8ZM3 6l7 2.8L17 6M10 9v7.8",
72
+ filter: "M4 4.5h12l-4.4 5.1v5l-3.2-1.6V9.6Z",
73
+ columns: "M3.5 4h13v12h-13ZM8.2 4v12M12.8 4v12",
74
+ download: "M10 3.5v8M6.8 8.3 10 11.5l3.2-3.2M4 15v2.5a1.5 1.5 0 0 0 1.5 1.5h9a1.5 1.5 0 0 0 1.5-1.5V15"
75
+ };
76
+ var custom = /* @__PURE__ */ new Map();
77
+ var escape = (s) => s.replace(/[&<>"']/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" })[c]);
78
+ function iconPath(name) {
79
+ return Object.hasOwn(ICON_PATHS, name) ? ICON_PATHS[name] : custom.get(name) ?? null;
80
+ }
81
+ function iconAttributes(o = {}) {
82
+ const size = Number.isFinite(o.size) && o.size > 0 ? o.size : 16;
83
+ return { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 20 20", width: String(size), height: String(size), fill: "none", stroke: "currentColor", "stroke-width": "1.6", "stroke-linecap": "round", "stroke-linejoin": "round", focusable: "false", class: ["icen-symbol", o.className].filter(Boolean).join(" "), ...o.label ? { role: "img", "aria-label": o.label } : { "aria-hidden": "true" } };
84
+ }
85
+ function iconHTML(name, o = {}) {
86
+ const path = iconPath(name);
87
+ if (!path) return "";
88
+ return `<svg${Object.entries(iconAttributes(o)).map(([k, v]) => ` ${k}="${escape(v)}"`).join("")}><path d="${escape(path)}"></path></svg>`;
89
+ }
90
+ function createIcon(name, o = {}) {
91
+ if (typeof document === "undefined") return null;
92
+ const path = iconPath(name);
93
+ if (!path) return null;
94
+ const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
95
+ for (const [key, value] of Object.entries(iconAttributes(o))) svg.setAttribute(key, value);
96
+ const line = document.createElementNS(svg.namespaceURI, "path");
97
+ line.setAttribute("d", path);
98
+ svg.append(line);
99
+ return svg;
100
+ }
101
+
102
+ // src/behaviors/events.ts
103
+ function emitIcen(source, type, detail) {
104
+ return source.dispatchEvent(
105
+ new CustomEvent(type, { detail, bubbles: true, composed: true, cancelable: true })
106
+ );
107
+ }
108
+
109
+ // src/behaviors/i18n.ts
110
+ var ICEN_LOCALE_ZH_CN = {
111
+ /* ── aiBranch ── */
112
+ "aiBranch.nextVersion": "\u4E0B\u4E00\u7248\u672C",
113
+ "aiBranch.prevVersion": "\u4E0A\u4E00\u7248\u672C",
114
+ "aiBranch.version": "\u5206\u652F\u7248\u672C",
115
+ /* ── aiChat ── */
116
+ "aiChat.backToBottom": "\u56DE\u5230\u5E95\u90E8",
117
+ "aiChat.backToBottomCount": "\u56DE\u5230\u5E95\u90E8 \xB7 {p0} \u6761\u65B0\u6D88\u606F",
118
+ "aiChat.continue": "\u7EE7\u7EED\u751F\u6210",
119
+ "aiChat.download": "\u4E0B\u8F7D",
120
+ "aiChat.file": "\u6587\u4EF6",
121
+ "aiChat.roleSystem": "\u7CFB",
122
+ "aiChat.roleTool": "\u5DE5",
123
+ "aiChat.roleUser": "\u6211",
124
+ "aiChat.thinking": "\u601D\u8003 {p0}",
125
+ "aiChat.thinkingNow": "\u6B63\u5728\u601D\u8003\u2026",
126
+ /* ── aiComposer ── */
127
+ "aiComposer.attachAgent": "\u4EE3\u7406",
128
+ "aiComposer.library": "\u6DFB\u52A0\u4E0A\u4E0B\u6587\u4E0E\u547D\u4EE4",
129
+ "aiComposer.searchLibrary": "\u641C\u7D22\u6280\u80FD\u3001\u5DE5\u5177\u3001\u6587\u4EF6\u4E0E\u547D\u4EE4",
130
+ "aiComposer.all": "\u5168\u90E8",
131
+ "aiComposer.skills": "\u6280\u80FD",
132
+ "aiComposer.tools": "\u5DE5\u5177",
133
+ "aiComposer.libraryHint": "\u4E0A\u4E0B\u6587\u968F\u6D88\u606F\u53D1\u9001 \xB7 \u547D\u4EE4\u5148\u586B\u5165\u8F93\u5165\u6846",
134
+ "aiComposer.commandHint": "\u2191 \u2193 \u6D4F\u89C8 \xB7 Enter \u6267\u884C \xB7 Esc \u8FD4\u56DE",
135
+ "aiComposer.refHint": "\u2191 \u2193 \u6D4F\u89C8 \xB7 Enter \u5F15\u7528 \xB7 Esc \u8FD4\u56DE",
136
+ "aiComposer.noLibraryMatch": "\u6CA1\u6709\u5339\u914D\u7684\u9879\u76EE\uFF0C\u8BD5\u8BD5\u5176\u4ED6\u5173\u952E\u8BCD",
137
+ "aiComposer.filesNeedAdapter": "\u9644\u4EF6\u5C1A\u672A\u63A5\u901A\u4E0A\u4F20\u3002\u8BF7\u914D\u7F6E prepareMessage \u540E\u91CD\u8BD5\uFF0C\u6587\u4EF6\u4ECD\u4FDD\u7559\u5728\u6B64\u8BF7\u6C42\u4E2D\u3002",
138
+ "aiComposer.attachDoc": "\u6587\u6863",
139
+ "aiComposer.attachFile": "\u6587\u4EF6",
140
+ "aiComposer.attachFolder": "\u6587\u4EF6\u5939",
141
+ "aiComposer.cacheInvalidHint": "\u5207\u6362\u6A21\u578B\u4F1A\u4F7F prompt \u7F13\u5B58\u5931\u6548",
142
+ "aiComposer.commands": "\u547D\u4EE4",
143
+ "aiComposer.currentTodos": "\u5F53\u524D\u5F85\u529E",
144
+ "aiComposer.done": "\u5B8C\u6210",
145
+ "aiComposer.justNow": "\u521A\u521A \xB7 {p0}",
146
+ "aiComposer.modelAria": "\u6A21\u578B {p0}\uFF08{p1}\uFF09",
147
+ "aiComposer.noCommandMatch": "\u65E0\u5339\u914D\u547D\u4EE4",
148
+ "aiComposer.noModelMatch": "\u65E0\u5339\u914D\u6A21\u578B",
149
+ "aiComposer.noRefMatch": "\u65E0\u5339\u914D\u5F15\u7528",
150
+ "aiComposer.placeholder": "\u8F93\u5165\u6D88\u606F\uFF0C/ \u547D\u4EE4 \xB7 @ \u5F15\u7528 \xB7 Enter \u53D1\u9001",
151
+ "aiComposer.refs": "\u5F15\u7528",
152
+ "aiComposer.removeAttachment": "\u79FB\u9664\u9644\u4EF6 {p0}",
153
+ "aiComposer.removeQueued": "\u79FB\u9664\u6392\u961F\u6D88\u606F {p0}",
154
+ "aiComposer.removeRef": "\u79FB\u9664\u5F15\u7528 {p0}",
155
+ "aiComposer.searchModels": "\u641C\u7D22\u6A21\u578B",
156
+ "aiComposer.selectModel": "\u9009\u62E9\u6A21\u578B",
157
+ "aiComposer.send": "\u53D1\u9001",
158
+ "aiComposer.stop": "\u505C\u6B62\u751F\u6210",
159
+ "aiComposer.stopped": "\u5DF2\u505C\u6B62",
160
+ "aiComposer.todoChip": "\u5F53\u524D\u5F85\u529E {p0}/{p1}{p2}",
161
+ "aiComposer.todoHasError": "\uFF08\u6709\u5931\u8D25\u9879\uFF09",
162
+ /* ── aiCore ── */
163
+ "aiCore.kindBrowser": "\u6D4F\u89C8",
164
+ "aiCore.kindChart": "\u56FE\u8868",
165
+ "aiCore.kindDelete": "\u5220\u9664",
166
+ "aiCore.kindEdit": "\u7F16\u8F91",
167
+ "aiCore.kindFetch": "\u8BF7\u6C42",
168
+ "aiCore.kindGlob": "\u5339\u914D",
169
+ "aiCore.kindGrep": "\u641C\u7D22",
170
+ "aiCore.kindNote": "\u7B14\u8BB0",
171
+ "aiCore.kindPlan": "\u8BA1\u5212",
172
+ "aiCore.kindRead": "\u8BFB\u53D6",
173
+ "aiCore.kindSearch": "\u68C0\u7D22",
174
+ "aiCore.kindShell": "\u547D\u4EE4",
175
+ "aiCore.kindSkill": "\u6280\u80FD",
176
+ "aiCore.kindSubagent": "\u5B50\u4EE3\u7406",
177
+ "aiCore.kindTodo": "\u5F85\u529E",
178
+ "aiCore.kindWrite": "\u5199\u5165",
179
+ "aiCore.statusApproval": "\u5F85\u786E\u8BA4",
180
+ "aiCore.statusCancelled": "\u5DF2\u53D6\u6D88",
181
+ "aiCore.statusDone": "\u5B8C\u6210",
182
+ "aiCore.statusError": "\u5931\u8D25",
183
+ "aiCore.statusPending": "\u7B49\u5F85",
184
+ "aiCore.statusRunning": "\u6267\u884C\u4E2D",
185
+ "aiCore.statusStreaming": "\u6D41\u5F0F\u4E2D",
186
+ "aiCore.todoProgress": "{p0}/{p1} \u5B8C\u6210",
187
+ /* ── aiDiff ── */
188
+ "aiDiff.accepted": "\u5DF2\u63A5\u53D7",
189
+ "aiDiff.binary": "\u4E8C\u8FDB\u5236\u6587\u4EF6\uFF0C\u65E0\u6CD5\u663E\u793A\u6587\u672C\u5DEE\u5F02",
190
+ "aiDiff.empty": "\u65E0\u5DEE\u5F02\u5185\u5BB9",
191
+ "aiDiff.rejected": "\u5DF2\u62D2\u7EDD",
192
+ /* ── aiFeedback ── */
193
+ "aiFeedback.helpful": "\u6709\u5E2E\u52A9",
194
+ "aiFeedback.notHelpful": "\u65E0\u5E2E\u52A9",
195
+ "aiFeedback.reasonCitationMismatch": "\u5F15\u7528\u4E0D\u7B26",
196
+ "aiFeedback.reasonOutdated": "\u5185\u5BB9\u8FC7\u65F6",
197
+ "aiFeedback.reasonUnauthorized": "\u8D8A\u6743\u4FE1\u606F",
198
+ "aiFeedback.reasonUnsourced": "\u65E0\u5F15\u7528\u4F9D\u636E",
199
+ "aiFeedback.reasonWrong": "\u7B54\u6848\u6709\u8BEF",
200
+ "aiFeedback.thanks": "\u611F\u8C22\u53CD\u9988\uFF0C\u5DF2\u5173\u8054\u5230\u8BE5\u6761\u56DE\u7B54\u7684\u8FFD\u8E2A\u8BB0\u5F55",
201
+ /* ── aiPanel ── */
202
+ "aiPanel.audit": "\u5BA1\u8BA1",
203
+ "aiPanel.cacheRead": "\u7F13\u5B58\u8BFB",
204
+ "aiPanel.cacheWrite": "\u7F13\u5B58\u5199",
205
+ "aiPanel.callsTokens": "{p0} \u6B21 \xB7 {p1} tok{p2}",
206
+ "aiPanel.clearAudit": "\u6E05\u9664\u5BA1\u8BA1",
207
+ "aiPanel.context": "\u4E0A\u4E0B\u6587",
208
+ "aiPanel.contextWindow": "\u4E0A\u4E0B\u6587\u7A97\u53E3",
209
+ "aiPanel.errorsCount": "{p0} \u5931\u8D25",
210
+ "aiPanel.files": "\u6587\u4EF6 ({p0})",
211
+ "aiPanel.itemStatus": "{p0}\uFF0C\u72B6\u6001\uFF1A{p1}",
212
+ "aiPanel.noAudit": "\u6682\u65E0\u5BA1\u8BA1\u8BB0\u5F55",
213
+ "aiPanel.noUsage": "\u6682\u65E0\u7528\u91CF",
214
+ "aiPanel.reasoning": "\u63A8\u7406",
215
+ "aiPanel.requestsCount": "{p0} \u6B21\u8BF7\u6C42",
216
+ "aiPanel.ringPercent": "\u4E0A\u4E0B\u6587\u7A97\u53E3\u5360\u7528 {p0}%\uFF0C\u70B9\u51FB\u67E5\u770B\u8BE6\u60C5",
217
+ "aiPanel.ringUsed": "\u5DF2\u7528 {p0}\uFF0C\u70B9\u51FB\u67E5\u770B\u8BE6\u60C5",
218
+ "aiPanel.taskProgress": "\u4EFB\u52A1\u8FDB\u5EA6",
219
+ "aiPanel.toolsCount": "{p0} \u5DE5\u5177",
220
+ "aiPanel.usage": "\u7528\u91CF",
221
+ "aiPanel.usageAria": "\u7528\u91CF\uFF1A{p0}",
222
+ /* ── aiProvider ── */
223
+ "aiProvider.audioUrlOnly": "\u4EC5 URL \u7684\u97F3\u9891\uFF08input_audio \u9700 base64\uFF0C\u8BF7\u5148\u53D6\u56DE\u5185\u8054\uFF09",
224
+ "aiProvider.audioUrlOnlyAnthropic": "\u4EC5 URL \u7684\u97F3\u9891\uFF08audio \u5757\u9700 base64 source\uFF09",
225
+ "aiProvider.base64File": "base64 \u6587\u4EF6\uFF08file \u90E8\u4EF6\u9700 Files API file_id\uFF0C\u8BF7\u7F6E\u4E8E url \u69FD\uFF09",
226
+ "aiProvider.corsHint": "\uFF1B\u6D4F\u89C8\u5668\u76F4\u8FDE {p0}\uFF08{p1}\uFF09\u5F88\u53EF\u80FD\u88AB CORS \u62E6\u622A\uFF0C\u5EFA\u8BAE\u7ECF\u4EE3\u7406/\u81EA\u5EFA\u7F51\u5173\u8F6C\u53D1",
227
+ "aiProvider.emptyResponse": "\u54CD\u5E94\u4E3A\u7A7A",
228
+ "aiProvider.glmLabel": "GLM\uFF08\u667A\u8C31\uFF09",
229
+ "aiProvider.invalidJson": "\u54CD\u5E94\u4E0D\u662F\u5408\u6CD5 JSON",
230
+ "aiProvider.kimiLabel": "Kimi\uFF08\u6708\u4E4B\u6697\u9762\uFF09",
231
+ "aiProvider.networkFailed": "\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25\uFF1A{p0}{p1}",
232
+ "aiProvider.nonPdfDocument": "\u975E PDF \u6587\u4EF6\u5757\uFF08document \u5757\u4E3A application/pdf\uFF0C\u6536\u5230 {p0}\uFF09",
233
+ "aiProvider.requestCancelled": "\u8BF7\u6C42\u5DF2\u53D6\u6D88",
234
+ "aiProvider.resourceRef": "[\u8D44\u6E90] {p0} ({p1})",
235
+ "aiProvider.streamError": "\u6D41\u5F0F\u54CD\u5E94\u9519\u8BEF",
236
+ "aiProvider.toolRoleNoCallId": "role 'tool' \u4E14\u7F3A toolCallId\uFF08openai \u65CF\u9700 tool_call_id\uFF09",
237
+ "aiProvider.toolRoleNoUseId": "role 'tool' \u4E14\u7F3A toolCallId\uFF08anthropic \u65CF\u6620\u5C04 tool_result \u9700 tool_use_id\uFF09",
238
+ "aiProvider.unsupported": "{p0} \u7EBF\u534F\u8BAE\u4E0D\u652F\u6301 {p1}",
239
+ "aiProvider.videoUnsupported": "video \u8F93\u5165\uFF08\u65E0\u4E3B\u6D41 chat API \u652F\u6301\uFF09",
240
+ "aiProvider.videoUnsupportedAnthropic": "video \u8F93\u5165",
241
+ /* ── aiThreads ── */
242
+ "aiThreads.actionsAria": "\u4F1A\u8BDD\u64CD\u4F5C",
243
+ "aiThreads.archived": "\u5DF2\u5F52\u6863",
244
+ /* ── aiTool ── */
245
+ "aiTool.allow": "\u5141\u8BB8",
246
+ "aiTool.reject": "\u62D2\u7EDD",
247
+ /* ── aiTools ── */
248
+ "aiTools.chart.area": "line \u591A\u7CFB\u5217\u586B\u5145\u9762\u79EF",
249
+ "aiTools.chart.data": "\u4EFB\u610F\u7EF4\u5EA6\u539F\u59CB\u8BB0\u5F55 + dims \u5B57\u6BB5\u6620\u5C04\uFF08\u81EA\u52A8\u900F\u89C6\u6210 \u7C7B\u76EE \xD7 \u7CFB\u5217\uFF09",
250
+ "aiTools.chart.dates": "\u8D21\u732E\u65E5\u5386 ISO \u65E5\u671F\uFF08\u4E0E values \u914D\u5BF9\uFF09",
251
+ "aiTools.chart.description": "\u5728\u7528\u6237\u754C\u9762\u6E32\u67D3\u4E00\u5F20\u56FE\u8868\u53EF\u89C6\u5316\u3002\u8F93\u5165\u4E00\u4EFD\u56FE\u8868\u89C4\u683C\uFF08\u7EAF JSON\uFF09\uFF1Alabels+values\uFF08\u7C7B\u76EE\u6570\u503C\uFF09\u3001series\uFF08\u591A\u7CFB\u5217\uFF09\u3001segments\uFF08\u5360\u6BD4\uFF09\u3001points\uFF08\u6563\u70B9\u6C14\u6CE1\uFF09\u3001dates\uFF08\u8D21\u732E\u65E5\u5386\uFF09\u4EFB\u7ED9\u5176\u4E00\uFF1Btype \u7F3A\u7701\u65F6\u6309\u6570\u636E\u5F62\u6001\u81EA\u52A8\u9009\u578B\uFF08\u65F6\u95F4\u5E8F\u5217\u2192\u6298\u7EBF\u3001\u5360\u6BD4\u2192\u73AF\u5F62\u3001\u65E5\u671F\u2192\u8D21\u732E\u65E5\u5386\u3001\u5750\u6807\u70B9\u2192\u6563\u70B9\uFF09\u3002\u56FE\u8868\u5E26\u4EA4\u4E92\uFF08\u60AC\u505C\u63D0\u793A/\u70B9\u51FB/\u53F3\u952E\uFF09\u4E0E\u53EF\u9690\u85CF\u56FE\u4F8B\u3002",
252
+ "aiTools.chart.dims": "data[] \u7684\u5B57\u6BB5\u6620\u5C04\uFF1A{label?, series?, value?, x?, y?}",
253
+ "aiTools.chart.format": "\u6570\u503C\u683C\u5F0F\u5316\uFF1A{notation?: compact|percent|ms, unit?}",
254
+ "aiTools.chart.labels": "\u7C7B\u76EE\u8F74\uFF08line/vbar/hbar\uFF09",
255
+ "aiTools.chart.legend": "false = \u521D\u59CB\u9690\u85CF\u56FE\u4F8B",
256
+ "aiTools.chart.lttb": "\u5927\u6570\u636E\u91CF\u964D\u91C7\u6837\uFF1Atrue=\u81EA\u52A8\u4E0A\u9650\uFF0C\u6570\u5B57=\u6700\u5927\u4FDD\u7559\u70B9\u6570\uFF08\u6E32\u67D3\u5C42\u5951\u7EA6\uFF0C\u968F\u56FE\u8868\u91CD\u5EA6\u573A\u666F\u843D\u5730\uFF09",
257
+ "aiTools.chart.marks": "\u6807\u8BB0\u5C42\uFF08\u9608\u503C\u7EBF/\u53C2\u8003\u533A\u95F4/\u5F3A\u8C03\u70B9\uFF09\uFF0C\u5143\u7D20\u4E3A\u7EAF JSON \u63CF\u8FF0\u5B50\uFF08\u6E32\u67D3\u5C42\u5951\u7EA6\uFF0C\u968F\u56FE\u8868\u91CD\u5EA6\u573A\u666F\u843D\u5730\uFF09",
258
+ "aiTools.chart.points": "\u6563\u70B9/\u6C14\u6CE1\uFF1A[{x,y,size?,label?}]",
259
+ "aiTools.chart.radarAxes": "\u96F7\u8FBE\u8F74\u540D",
260
+ "aiTools.chart.segments": "\u5360\u6BD4\u578B\uFF08donut/stack\uFF09\uFF1A[{label,value}]",
261
+ "aiTools.chart.series": "\u591A\u7CFB\u5217\uFF08line/vbar/radar\uFF09",
262
+ "aiTools.chart.stacked": "vbar \u591A\u7CFB\u5217\u5806\u53E0\uFF08\u9ED8\u8BA4\u5206\u7EC4\uFF09",
263
+ "aiTools.chart.title": "\u56FE\u8868\u6807\u9898\uFF08\u6E32\u67D3\u5728\u5934\u90E8\u884C\u5DE6\u4FA7\uFF09",
264
+ "aiTools.chart.tooltip": "false = \u5173\u95ED\u5185\u7F6E\u63D0\u793A",
265
+ "aiTools.chart.type": "\u56FE\u8868\u7C7B\u578B\uFF0C\u7F3A\u7701\u81EA\u52A8\u63A8\u65AD",
266
+ "aiTools.chart.values": "\u5355\u7CFB\u5217\u6570\u503C\uFF08\u4E0E labels \u914D\u5BF9\uFF09",
267
+ "aiTools.chart.zoom": "\u7F29\u653E\u4EA4\u4E92\uFF1A'x'=\u7C7B\u76EE\u8F74\u533A\u95F4\u7F29\u653E\uFF0C'brush'=\u5237\u9009\u7F29\u653E",
268
+ "aiTools.datatable.columns": "\u5217\u5B9A\u4E49\u6570\u7EC4\uFF1A\u6BCF\u9879 { key, title, sortable?, filterable? }\uFF08key \u5BF9\u5E94 rows \u5143\u7D20\u5B57\u6BB5\u540D\uFF09",
269
+ "aiTools.datatable.description": "\u5728\u7528\u6237\u754C\u9762\u6E32\u67D3\u4E00\u4E2A\u53EF\u641C\u7D22\u3001\u5206\u9875\u3001\u53EF\u5BFC\u51FA CSV \u7684\u6570\u636E\u8868\u683C\u3002\u8F93\u5165\u7EAF JSON\uFF1Acolumns \u4E3A\u5217\u5B9A\u4E49\uFF08key/title \u5FC5\u586B\uFF09\uFF0Crows \u4E3A\u884C\u5BF9\u8C61\u6570\u7EC4\uFF08\u5B57\u6BB5\u540D\u5BF9\u9F50\u5217 key\uFF09\u3002\u8FD4\u56DE { title, rows: \u884C\u6570 } \u6458\u8981\u3002",
270
+ "aiTools.datatable.rows": "\u884C\u6570\u636E\u6570\u7EC4\uFF1A\u6BCF\u9879\u4E3A\u4E00\u4E2A\u5BF9\u8C61\uFF0C\u5B57\u6BB5\u540D\u5BF9\u9F50 columns[].key",
271
+ "aiTools.datatable.title": "\u8868\u683C\u6807\u9898\uFF08\u6E32\u67D3\u5728\u5DE5\u5177\u680F\u5DE6\u4FA7\uFF09",
272
+ "aiTools.execFailed": "\u5DE5\u5177\u6267\u884C\u5931\u8D25\uFF1A{p0}",
273
+ "aiTools.execTimeout": "\u6267\u884C\u8D85\u65F6\uFF08{p0}ms\uFF09",
274
+ "aiTools.manifestHeader": "\u53EF\u7528 UI \u5DE5\u5177\uFF08\u8C03\u7528\u540E\u5728\u7528\u6237\u754C\u9762\u6302\u8F7D\u53EF\u89C6\u5316\u7ED3\u679C\uFF09\uFF1A",
275
+ "aiTools.missingRequired": "\u7F3A\u5C11\u5FC5\u586B\u5B57\u6BB5",
276
+ "aiTools.none": "\uFF08\u65E0\u5DF2\u6CE8\u518C\u7684 UI \u5DE5\u5177\uFF09",
277
+ "aiTools.notInEnum": "\u4E0D\u5728\u5141\u8BB8\u53D6\u503C\u5185\uFF08{p0}\uFF09",
278
+ "aiTools.numMax": "\u6570\u503C {p0} \u5927\u4E8E\u6700\u5927\u503C {p1}",
279
+ "aiTools.numMin": "\u6570\u503C {p0} \u5C0F\u4E8E\u6700\u5C0F\u503C {p1}",
280
+ "aiTools.removeMount": "\u79FB\u9664 {p0} \u6302\u8F7D",
281
+ "aiTools.strMax": "\u957F\u5EA6 {p0} \u8D85\u8FC7\u4E0A\u9650 {p1}",
282
+ "aiTools.strMin": "\u957F\u5EA6 {p0} \u5C0F\u4E8E\u4E0B\u9650 {p1}",
283
+ "aiTools.typeMismatch": "\u671F\u671B {p0}\uFF0C\u5B9E\u5F97 {p1}",
284
+ "aiTools.validationFailed": "\u53C2\u6570\u6821\u9A8C\u5931\u8D25\uFF08{p0} \u9879\uFF09",
285
+ /* ── autocomplete ── */
286
+ "suggestions.loading": "\u6B63\u5728\u67E5\u627E\u5EFA\u8BAE\u2026",
287
+ "suggestions.error": "\u6682\u65F6\u65E0\u6CD5\u52A0\u8F7D\u5EFA\u8BAE\uFF0C\u8BF7\u91CD\u8BD5\u3002",
288
+ "suggestions.options": "\u5EFA\u8BAE",
289
+ "suggestions.empty": "\u6CA1\u6709\u5339\u914D\u7684\u5EFA\u8BAE",
290
+ "autocomplete.empty": "\u65E0\u5339\u914D\u7ED3\u679C",
291
+ /* ── backTop ── */
292
+ "backTop.label": "\u56DE\u5230\u9876\u90E8",
293
+ /* ── carousel ── */
294
+ "carousel.item": "\u7B2C {p0} \u5F20",
295
+ "carousel.region": "\u8F6E\u64AD",
296
+ "carousel.slide": "\u5E7B\u706F\u7247",
297
+ "carousel.status": "\u7B2C {p0} / {p1} \u5F20",
298
+ /* ── charts ── */
299
+ "charts.calendarWeekdays": ["\u4E00", "", "\u4E09", "", "\u4E94", "", "\u65E5"],
300
+ "charts.few": "\u5C11",
301
+ "charts.hideLegend": "\u9690\u85CF\u56FE\u4F8B",
302
+ "charts.loading": "\u52A0\u8F7D\u4E2D",
303
+ "charts.many": "\u591A",
304
+ "charts.monthLabel": "{p0}\u6708",
305
+ "charts.noData": "\u6682\u65E0\u6570\u636E",
306
+ "charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
307
+ "charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
308
+ "charts.type.area": "\u9762\u79EF\u56FE",
309
+ "charts.type.donut": "\u73AF\u5F62\u56FE",
310
+ "charts.type.gauge": "\u4EEA\u8868\u76D8",
311
+ "charts.type.graph": "\u77E5\u8BC6\u56FE\u8C31",
312
+ "charts.type.heatmap": "\u70ED\u529B\u56FE",
313
+ "charts.type.line": "\u6298\u7EBF\u56FE",
314
+ "charts.type.map": "\u5730\u56FE",
315
+ "charts.type.radar": "\u96F7\u8FBE\u56FE",
316
+ "charts.type.scatter": "\u6563\u70B9\u56FE",
317
+ "charts.type.sparkline": "\u8FF7\u4F60\u8D8B\u52BF",
318
+ "charts.seriesName": "\u7CFB\u5217{p0}",
319
+ "charts.showLegend": "\u663E\u793A\u56FE\u4F8B",
320
+ "charts.value": "\u6570\u503C",
321
+ /* ── themeSwitcher ── */
322
+ "themeSwitcher.appearance": "\u5916\u89C2",
323
+ "themeSwitcher.theme": "\u4E3B\u9898",
324
+ "themeSwitcher.primitive": "\u539F\u8BED",
325
+ "themeSwitcher.mode": "\u660E\u6697",
326
+ "themeSwitcher.light": "\u6D45\u8272",
327
+ "themeSwitcher.dark": "\u6DF1\u8272",
328
+ "themeSwitcher.modern": "\u73B0\u4EE3",
329
+ "themeSwitcher.dongyun": "\u4E1C\u97F5",
330
+ "themeSwitcher.jugou": "\u5DE8\u6784",
331
+ "themeSwitcher.piano": "\u94A2\u7434",
332
+ "themeSwitcher.monet": "\u83AB\u5948",
333
+ "themeSwitcher.vangogh": "\u68B5\u9AD8",
334
+ "themeSwitcher.chinese": "\u4E2D\u5F0F",
335
+ "themeSwitcher.soviet": "\u82CF\u5F0F",
336
+ "themeSwitcher.pixel": "\u50CF\u7D20",
337
+ /* ── codeBlock ── */
338
+ "codeBlock.collapse": "\u6536\u8D77",
339
+ "codeBlock.region": "\u4EE3\u7801\u5185\u5BB9",
340
+ "codeBlock.copyFailed": "\u672A\u80FD\u590D\u5236\uFF0C\u8BF7\u91CD\u8BD5\u3002",
341
+ "codeBlock.copyRetry": "\u91CD\u8BD5\u590D\u5236",
342
+ "codeBlock.copy": "\u590D\u5236",
343
+ "codeBlock.foldCollapse": "\u6298\u53E0\u4EE3\u7801",
344
+ "codeBlock.foldExpand": "\u5C55\u5F00\u4EE3\u7801",
345
+ "codeBlock.linesTotal": "\u5171 {p0} \u884C",
346
+ "codeBlock.numHide": "\u9690\u85CF\u884C\u53F7",
347
+ "codeBlock.numShow": "\u663E\u793A\u884C\u53F7",
348
+ "codeBlock.tailAria": "\u5C55\u5F00\u6216\u6536\u8D77\u4EE3\u7801",
349
+ "codeBlock.wrapOff": "\u5173\u95ED\u6362\u884C",
350
+ "codeBlock.wrapOn": "\u81EA\u52A8\u6362\u884C",
351
+ /* ── common ── */
352
+ "common.accept": "\u63A5\u53D7",
353
+ "common.add": "\u65B0\u589E",
354
+ "common.all": "\u5168\u90E8",
355
+ "common.approve": "\u6279\u51C6",
356
+ "common.cancel": "\u53D6\u6D88",
357
+ "common.actionFailed": "\u64CD\u4F5C\u672A\u5B8C\u6210\uFF0C\u8BF7\u91CD\u8BD5\u3002",
358
+ "common.close": "\u5173\u95ED",
359
+ "common.confirm": "\u786E\u8BA4",
360
+ "common.copied": "\u5DF2\u590D\u5236",
361
+ "common.copy": "\u590D\u5236",
362
+ "common.delete": "\u5220\u9664",
363
+ "common.enable": "\u542F\u7528",
364
+ "common.exportCsv": "\u5BFC\u51FA CSV",
365
+ "common.healthy": "\u6B63\u5E38",
366
+ "common.input": "\u8F93\u5165",
367
+ "common.loadingEllipsis": "\u52A0\u8F7D\u4E2D\u2026",
368
+ "common.official": "\u5B98\u65B9",
369
+ "common.output": "\u8F93\u51FA",
370
+ "common.page": "\u7B2C {p0} \u9875",
371
+ "common.reject": "\u62D2\u7EDD",
372
+ "common.remove": "\u79FB\u9664",
373
+ "common.requestAccess": "\u7533\u8BF7\u8BBF\u95EE",
374
+ "common.requestAccessFor": "\u7533\u8BF7\u8BBF\u95EE {p0}",
375
+ "common.restricted": "\u53D7\u9650",
376
+ "common.retry": "\u91CD\u8BD5",
377
+ "common.rows": "{p0} \u884C",
378
+ "common.run": "\u8FD0\u884C",
379
+ "common.steps": "{p0} \u6B65",
380
+ "common.submit": "\u63D0\u4EA4",
381
+ "common.unknown": "\u672A\u77E5",
382
+ /* ── contextMenu ── */
383
+ "contextMenu.back": "\u540E\u9000",
384
+ "contextMenu.copyPageLink": "\u590D\u5236\u9875\u9762\u94FE\u63A5",
385
+ "contextMenu.forward": "\u524D\u8FDB",
386
+ "contextMenu.refresh": "\u5237\u65B0",
387
+ /* ── copy ── */
388
+ "copy.copied": "\u5DF2\u590D\u5236",
389
+ "copy.failed": "\u672A\u80FD\u590D\u5236\uFF0C\u8BF7\u91CD\u8BD5\u3002",
390
+ "copy.denied": "clipboard API \u88AB\u62D2\uFF08{p0}\uFF09\u4E14\u56DE\u9000 execCommand \u5931\u8D25",
391
+ "copy.unavailable": "\u526A\u8D34\u677F\u4E0D\u53EF\u7528\uFF08\u65E0 clipboard API \u4E14 execCommand \u56DE\u9000\u5931\u8D25\uFF09",
392
+ "copy.unknown": "\u672A\u77E5\u9519\u8BEF",
393
+ /* ── datatable ── */
394
+ "datatable.clear": "\u6E05\u7A7A",
395
+ "datatable.collapseGroup": "\u6298\u53E0\u5206\u7EC4 {p0}",
396
+ "datatable.columnSettingsAria": "\u5217\u8BBE\u7F6E",
397
+ "datatable.countUnit": "{p0} \u6761",
398
+ "datatable.editHint": "\u7F16\u8F91\u300C{p0}\u300D\uFF1A\u53CC\u51FB\u6216\u6309 Enter",
399
+ "datatable.editHintWithValue": "{p0}\uFF08\u53CC\u51FB\u6216\u6309 Enter \u7F16\u8F91\u300C{p1}\u300D\uFF09",
400
+ "datatable.empty": "\u6682\u65E0\u6570\u636E",
401
+ "datatable.emptyValue": "\uFF08\u7A7A\uFF09",
402
+ "datatable.expandGroup": "\u5C55\u5F00\u5206\u7EC4 {p0}",
403
+ "datatable.expandRow": "\u5C55\u5F00\u884C",
404
+ "datatable.filterChipAria": "\u7B5B\u9009\u300C{p0}\u300D",
405
+ "datatable.pageSizeAria": "\u6BCF\u9875\u6761\u6570",
406
+ "datatable.paginationAria": "\u5206\u9875",
407
+ "datatable.reset": "\u91CD\u7F6E",
408
+ "datatable.resizeAria": "\u8C03\u6574\u300C{p0}\u300D\u5217\u5BBD",
409
+ "datatable.searchAria": "\u641C\u7D22\u8868\u683C",
410
+ "datatable.searchPlaceholder": "\u641C\u7D22\u2026",
411
+ "datatable.selectAll": "\u5168\u9009",
412
+ "datatable.selectRow": "\u9009\u62E9\u8BE5\u884C",
413
+ "datatable.selectedCount": "\u5DF2\u9009 {p0} \u9879",
414
+ "datatable.totalCount": "\u5171 {p0} \u6761",
415
+ "datatable.totalLabel": "\u5408\u8BA1",
416
+ /* ── datePicker ── */
417
+ "datePicker.noDates": "\u6CA1\u6709\u53EF\u9009\u65E5\u671F",
418
+ "datePicker.clear": "\u6E05\u9664",
419
+ "datePicker.nextMonth": "\u4E0B\u4E00\u6708",
420
+ "datePicker.prevMonth": "\u4E0A\u4E00\u6708",
421
+ "datePicker.selectDate": "\u9009\u62E9\u65E5\u671F",
422
+ "datePicker.today": "\u4ECA\u5929",
423
+ "datePicker.weekdays": ["\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D", "\u65E5"],
424
+ "datePicker.weekdaysSunFirst": ["\u65E5", "\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D"],
425
+ "datePicker.yearMonth": "{p0} \u5E74 {p1} \u6708",
426
+ /* ── formValidate ── */
427
+ "formValidate.email": "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u90AE\u7BB1\u5730\u5740",
428
+ "formValidate.invalid": "\u8F93\u5165\u4E0D\u5408\u6CD5",
429
+ "formValidate.matches": "\u4E24\u6B21\u8F93\u5165\u4E0D\u4E00\u81F4",
430
+ "formValidate.max": "\u4E0D\u80FD\u5927\u4E8E {max}",
431
+ "formValidate.maxlength": "\u6700\u591A\u8F93\u5165 {max} \u4E2A\u5B57\u7B26",
432
+ "formValidate.min": "\u4E0D\u80FD\u5C0F\u4E8E {min}",
433
+ "formValidate.minlength": "\u81F3\u5C11\u8F93\u5165 {min} \u4E2A\u5B57\u7B26",
434
+ "formValidate.number": "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u6570\u5B57",
435
+ "formValidate.pattern": "\u8F93\u5165\u683C\u5F0F\u4E0D\u6B63\u786E",
436
+ "formValidate.required": "\u6B64\u9879\u4E3A\u5FC5\u586B\u9879",
437
+ "formValidate.selectPlaceholder": "\u8BF7\u9009\u62E9",
438
+ "formValidate.step": "\u6570\u503C\u5FC5\u987B\u662F {step} \u7684\u500D\u6570",
439
+ "formValidate.summary": "\u8868\u5355\u6709 {p0} \u9879\u5185\u5BB9\u9700\u8981\u4FEE\u6B63\uFF0C\u8BF7\u4FEE\u6539\u540E\u91CD\u65B0\u63D0\u4EA4",
440
+ "formValidate.tool.description": "\u5411\u7528\u6237\u6E32\u67D3\u4E00\u4E2A\u7ED3\u6784\u5316\u8868\u5355\u6536\u96C6\u8F93\u5165",
441
+ "formValidate.tool.fields": "\u5B57\u6BB5\u5217\u8868",
442
+ "formValidate.tool.help": "\u5B57\u6BB5\u4E0B\u65B9\u7684\u5E2E\u52A9\u6587\u6848",
443
+ "formValidate.tool.label": "\u5B57\u6BB5\u6807\u7B7E",
444
+ "formValidate.tool.max": "\u6700\u5927\u503C\uFF08number \u7528\uFF09",
445
+ "formValidate.tool.min": "\u6700\u5C0F\u503C\uFF08number \u7528\uFF09",
446
+ "formValidate.tool.name": "\u5B57\u6BB5\u540D\uFF08\u63D0\u4EA4\u503C\u7684 key\uFF09",
447
+ "formValidate.tool.options": "select \u9009\u9879\uFF08\u5B57\u7B26\u4E32\u6216 {label,value}\uFF09",
448
+ "formValidate.tool.pattern": "\u6B63\u5219\u7EA6\u675F\uFF08HTML pattern \u8BED\u6CD5\uFF0C\u6574\u4E32\u5339\u914D\uFF09",
449
+ "formValidate.tool.required": "\u662F\u5426\u5FC5\u586B",
450
+ "formValidate.tool.submitText": "\u63D0\u4EA4\u6309\u94AE\u6587\u6848\uFF0C\u9ED8\u8BA4\u300C\u63D0\u4EA4\u300D",
451
+ "formValidate.tool.title": "\u8868\u5355\u6807\u9898\uFF08\u53EF\u9009\uFF09",
452
+ "formValidate.tool.type": "\u63A7\u4EF6\u7C7B\u578B\uFF0C\u9ED8\u8BA4 text",
453
+ "formValidate.url": "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u94FE\u63A5\u5730\u5740",
454
+ /* ── input ── */
455
+ "input.clearSearch": "\u6E05\u7A7A\u641C\u7D22",
456
+ "input.hidePassword": "\u9690\u85CF\u5BC6\u7801",
457
+ "input.otpPosition": "\u7B2C {p0} \u4F4D\uFF0C\u5171 {p1} \u4F4D",
458
+ "panel.expand": "\u5C55\u5F00",
459
+ "panel.collapse": "\u6298\u53E0",
460
+ "input.showPassword": "\u663E\u793A\u5BC6\u7801",
461
+ /* ── kbAccess ── */
462
+ "kbAccess.approveTip": "\u6279\u51C6\u8BE5\u8BBF\u95EE\u7533\u8BF7",
463
+ "kbAccess.approvedBadge": "\u5DF2\u6279\u51C6 \xB7 {p0}",
464
+ "kbAccess.approverNotePlaceholder": "\u7ED9\u8BF7\u6C42\u4EBA\u7684\u7559\u8A00\uFF08\u53EF\u9009\uFF09",
465
+ "kbAccess.daysLeft": "{p0} \u5929\u540E",
466
+ "kbAccess.defaultSubject": "\u8BE5\u5185\u5BB9",
467
+ "kbAccess.deniedHint": "\u672A\u901A\u8FC7\u2014\u2014\u53EF\u8C03\u6574\u7406\u7531\u540E\u91CD\u65B0\u7533\u8BF7",
468
+ "kbAccess.denyNoteLabel": "\u62D2\u7EDD\u7559\u8A00\uFF08\u53EF\u9009\uFF09",
469
+ "kbAccess.duration30d": "30 \u5929",
470
+ "kbAccess.duration7d": "7 \u5929",
471
+ "kbAccess.durationForever": "\u6C38\u4E45",
472
+ "kbAccess.durationLabel": "\u8BBF\u95EE\u65F6\u957F",
473
+ "kbAccess.expired": "\u5DF2\u5230\u671F",
474
+ "kbAccess.expiresAt": "{p0}\u5230\u671F",
475
+ "kbAccess.grantAsPrefix": "\u6279\u51C6\u4E3A{p0}",
476
+ "kbAccess.grantRoleLabel": "\u6279\u51C6\u89D2\u8272",
477
+ "kbAccess.hoursLeft": "{p0} \u5C0F\u65F6\u540E",
478
+ "kbAccess.minutesLeft": "{p0} \u5206\u949F\u540E",
479
+ "kbAccess.ownerLabel": "\u5185\u5BB9\u8D1F\u8D23\u4EBA",
480
+ "kbAccess.ownerPrefix": "\u8D1F\u8D23\u4EBA\uFF1A{p0}",
481
+ "kbAccess.reapply": "\u91CD\u65B0\u7533\u8BF7",
482
+ "kbAccess.reasonLabel": "\u7533\u8BF7\u7406\u7531",
483
+ "kbAccess.reasonPlaceholder": "\u8BF4\u660E\u4E1A\u52A1\u539F\u56E0\uFF08\u5BA1\u6279\u4EBA\u53EF\u89C1\uFF09",
484
+ "kbAccess.rejectTip": "\u62D2\u7EDD\u8BE5\u8BBF\u95EE\u7533\u8BF7",
485
+ "kbAccess.requestRenewal": "\u7533\u8BF7\u7EED\u671F",
486
+ "kbAccess.requestToPrefix": "\u8BF7\u6C42\u5C06\u53D1\u9001\u7ED9\uFF1A{p0}",
487
+ "kbAccess.restrictedContent": "\u53D7\u9650\u5185\u5BB9",
488
+ "kbAccess.restrictedHint": "\u6B64\u5185\u5BB9\u4EC5\u5BF9\u6388\u6743\u8005\u5F00\u653E",
489
+ "kbAccess.revokedHint": "\u8BBF\u95EE\u5DF2\u88AB\u6536\u56DE",
490
+ "kbAccess.roleLabel": "\u7533\u8BF7\u89D2\u8272",
491
+ "kbAccess.submitRequest": "\u63D0\u4EA4\u7533\u8BF7",
492
+ "kbAccess.switchIdentity": "\u5207\u6362\u8EAB\u4EFD",
493
+ "kbAccess.switchIdentityTip": "\u5207\u6362\u8EAB\u4EFD\u540E\u91CD\u65B0\u68C0\u67E5\u6743\u9650",
494
+ "kbAccess.unknownRequester": "\u672A\u77E5\u8BF7\u6C42\u4EBA",
495
+ "kbAccess.waitingApproval": "\u7B49\u5F85 {p0} \u5BA1\u6279",
496
+ /* ── kbAcl ── */
497
+ "kbAcl.breakHint": "\u505C\u6B62\u4ECE\u7236\u7EA7\u7EE7\u627F\uFF0C\u6539\u4E3A\u72EC\u7ACB\u7BA1\u7406\u672C\u9879\u6743\u9650",
498
+ "kbAcl.breakInheritance": "\u505C\u6B62\u7EE7\u627F",
499
+ "kbAcl.brokenNotice": "\u5DF2\u505C\u6B62\u7EE7\u627F\u2014\u2014\u672C\u9879\u6743\u9650\u72EC\u7ACB\u4E8E\u7236\u7EA7",
500
+ "kbAcl.detachedChildren": "{p0}\uFF1A{p1} \u4E2A\u5B50\u9879\u5DF2\u8131\u79BB",
501
+ "kbAcl.directAccess": "\u76F4\u63A5\u8BBF\u95EE",
502
+ "kbAcl.exception": "\u4F8B\u5916",
503
+ "kbAcl.expiredOn": "\u5DF2\u8FC7\u671F\uFF08{p0}\uFF09",
504
+ "kbAcl.expiresIn": "{p0} \u5230\u671F",
505
+ "kbAcl.grantAccess": "\u6388\u4E88\u8BBF\u95EE",
506
+ "kbAcl.inheritedFrom": "\u7EE7\u627F\u81EA {p0}",
507
+ "kbAcl.inheritedFromLabel": "\u7EE7\u627F\u81EA",
508
+ "kbAcl.linkAccess": "\u94FE\u63A5\u8BBF\u95EE",
509
+ "kbAcl.noDirect": "\u6682\u65E0\u76F4\u63A5\u6388\u6743",
510
+ "kbAcl.noLinks": "\u65E0\u94FE\u63A5",
511
+ "kbAcl.removeEntry": "\u79FB\u9664 {p0}",
512
+ "kbAcl.restoreHint": "\u6062\u590D\u7EE7\u627F\u5C06\u4E22\u5F03\u672C\u9879\u81EA\u5B9A\u4E49\u7684\u6743\u9650",
513
+ "kbAcl.restoreInheritance": "\u6062\u590D\u7EE7\u627F",
514
+ "kbAcl.rootNotice": "\u6839\u7EA7\u8D44\u6E90\u2014\u2014\u65E0\u7236\u7EA7\u7EE7\u627F",
515
+ "kbAcl.systemBadge": "\u7CFB\u7EDF\u7BA1\u7406",
516
+ "kbAcl.systemNote": "\u7CFB\u7EDF\u81EA\u52A8\uFF0C\u4E0D\u53EF\u624B\u5DE5\u79FB\u9664",
517
+ "kbAcl.unnamedResource": "\u672A\u547D\u540D\u8D44\u6E90",
518
+ "kbAcl.visibleToCount": "\u5BF9 {p0} \u4EBA\u53EF\u89C1",
519
+ /* ── kbAnswer ── */
520
+ "kbAnswer.chartBar": "\u67F1\u72B6",
521
+ "kbAnswer.chartLine": "\u6298\u7EBF",
522
+ "kbAnswer.chartPie": "\u997C\u56FE",
523
+ "kbAnswer.exportNoun": "\u5BFC\u51FA {p0}",
524
+ "kbAnswer.filtered": "\u5DF2\u6309\u4F60\u7684\u6570\u636E\u6743\u9650\u8FC7\u6EE4",
525
+ "kbAnswer.filteredDetail": "\u5DF2\u6309\u4F60\u7684\u6570\u636E\u6743\u9650\u8FC7\u6EE4\uFF1A{p0}",
526
+ "kbAnswer.followups": "\u8FFD\u95EE\u5EFA\u8BAE",
527
+ "kbAnswer.hitAssets": "\u547D\u4E2D\u8D44\u4EA7\uFF1A{p0}",
528
+ "kbAnswer.kindCurated": "\u4EBA\u5DE5\u7B56\u5C55",
529
+ "kbAnswer.kindFunction": "\u51FD\u6570",
530
+ "kbAnswer.kindParameterized": "\u53C2\u6570\u5316\u67E5\u8BE2",
531
+ "kbAnswer.maskedPrefix": "\u5DF2\u8131\u654F\u5217\uFF1A",
532
+ "kbAnswer.rerunTip": "\u53C2\u6570\u53EF\u6539\u91CD\u8DD1",
533
+ "kbAnswer.truncated": "\u5DF2\u622A\u65AD\uFF1A\u663E\u793A {p0}/{p1} \u884C{p2}",
534
+ "kbAnswer.verifiedBadge": "\u8BA4\u8BC1\u7B54\u6848",
535
+ /* ── kbAudit ── */
536
+ "kbAudit.actionDetail": "\u5904\u7F6E\uFF1A{p0} \xB7 {p1}",
537
+ "kbAudit.actionLabel": "\u5904\u7F6E",
538
+ "kbAudit.alertedNote": "\u5DF2\u5B9E\u65F6\u544A\u8B66\u5B89\u5168\u56E2\u961F",
539
+ "kbAudit.channelFilterAria": "\u5BA1\u8BA1\u901A\u9053\u8FC7\u6EE4",
540
+ "kbAudit.channelPermission": "\u6743\u9650\u53D8\u66F4",
541
+ "kbAudit.channelRead": "\u8BFB\u53D6",
542
+ "kbAudit.channelRequest": "\u7533\u8BF7",
543
+ "kbAudit.channelSystem": "\u7CFB\u7EDF",
544
+ "kbAudit.empty": "\u6682\u65E0\u5BA1\u8BA1\u4E8B\u4EF6",
545
+ "kbAudit.exportTip": "\u5BFC\u51FA\u5F53\u524D\u8FC7\u6EE4\u89C6\u56FE\u4E3A CSV",
546
+ "kbAudit.hygieneLabel": "\u6743\u9650\u5F02\u5473",
547
+ "kbAudit.noHygiene": "\u672A\u53D1\u73B0\u6743\u9650\u5F02\u5473",
548
+ /* ── kbCanvas ── */
549
+ "kbCanvas.splitterAria": "\u8C03\u6574\u753B\u5E03\u53CC\u680F\u6BD4\u4F8B",
550
+ "kbCanvas.splitterTip": "\u62D6\u62FD\u8C03\u6574\u6BD4\u4F8B\uFF08\u2190/\u2192 \u5FAE\u8C03\uFF0C\u53CC\u51FB\u590D\u4F4D\uFF09",
551
+ /* ── kbCheckpoint ── */
552
+ "kbCheckpoint.chatAuditNote": "\u8BA8\u8BBA\u5386\u53F2\u6709\u5BA1\u8BA1\u4EF7\u503C",
553
+ "kbCheckpoint.label": "\u68C0\u67E5\u70B9",
554
+ "kbCheckpoint.restore": "\u6062\u590D\u68C0\u67E5\u70B9",
555
+ "kbCheckpoint.scopeBoth": "\u5185\u5BB9\u4E0E\u5BF9\u8BDD",
556
+ "kbCheckpoint.scopeChat": "\u4EC5\u5BF9\u8BDD",
557
+ "kbCheckpoint.scopeContent": "\u4EC5\u5185\u5BB9\uFF08\u4FDD\u7559\u5BF9\u8BDD\uFF09",
558
+ "kbCheckpoint.scopeMissing": "\u8BE5\u68C0\u67E5\u70B9\u672A\u5305\u542B\u6B64\u6062\u590D\u8303\u56F4",
559
+ /* ── kbChunks ── */
560
+ "kbChunks.addKeyword": "+ \u5173\u952E\u8BCD",
561
+ "kbChunks.chunkAddKeywordAria": "chunk {p0} \u65B0\u589E\u5173\u952E\u8BCD",
562
+ "kbChunks.chunkContentAria": "chunk {p0} \u5185\u5BB9",
563
+ "kbChunks.chunkEnableAria": "chunk {p0} \u542F\u7528",
564
+ "kbChunks.deleteChunkAria": "\u5220\u9664 chunk {p0}",
565
+ "kbChunks.disableNote": "\u5173\u95ED\u540E\u4E0D\u5220\u9664\uFF0C\u4EC5\u6392\u9664\u51FA\u68C0\u7D22",
566
+ "kbChunks.edited": "\u5DF2\u7F16\u8F91",
567
+ "kbChunks.empty": "\u6682\u65E0 chunk",
568
+ "kbChunks.modeFull": "\u5168\u6587",
569
+ "kbChunks.modeLabel": "\u641C\u7D22\u6A21\u5F0F",
570
+ "kbChunks.modeVector": "\u8BED\u4E49",
571
+ "kbChunks.removeKeyword": "\u79FB\u9664\u5173\u952E\u8BCD {p0}",
572
+ "kbChunks.searchAria": "\u641C\u7D22 chunk",
573
+ "kbChunks.searchFullPlaceholder": "\u5168\u6587\u641C\u7D22 chunk\u2026",
574
+ "kbChunks.searchVectorPlaceholder": "\u8BED\u4E49\u641C\u7D22 chunk\u2026",
575
+ /* ── kbCitation ── */
576
+ "kbCitation.sourceN": "\u6765\u6E90 {p0}",
577
+ "kbCitation.unavailable": "\u6765\u6E90\u5DF2\u4E0D\u53EF\u7528",
578
+ /* ── kbClarify ── */
579
+ "kbClarify.parsedPrefix": "\u5DF2\u89E3\u6790\uFF1A",
580
+ /* ── kbConflict ── */
581
+ "kbConflict.owner": "\u8D23\u4EFB\u4EBA {p0}",
582
+ /* ── kbConnector ── */
583
+ "kbConnector.changeRate": "\u53D8\u66F4\u7387",
584
+ "kbConnector.crawlRate": "\u6293\u53D6\u7387",
585
+ "kbConnector.credentials": "\u51ED\u8BC1",
586
+ "kbConnector.credentialsExpired": "\u51ED\u8BC1\u8FC7\u671F",
587
+ "kbConnector.editSchedule": "\u7F16\u8F91\u8BA1\u5212",
588
+ "kbConnector.empty": "\u6682\u65E0\u8FDE\u63A5\u5668",
589
+ "kbConnector.failing": "\u5F02\u5E38",
590
+ "kbConnector.lastSync": "\u6700\u8FD1\u540C\u6B65 {p0}",
591
+ "kbConnector.neverSynced": "\u4ECE\u672A\u540C\u6B65",
592
+ "kbConnector.notConfigured": "\u672A\u914D\u7F6E",
593
+ "kbConnector.off": "\u5DF2\u505C\u7528",
594
+ "kbConnector.perDay": "{p0}/\u5929",
595
+ "kbConnector.reauth": "\u91CD\u65B0\u6388\u6743",
596
+ "kbConnector.stale": "\u505C\u6EDE",
597
+ "kbConnector.syncNow": "\u7ACB\u5373\u540C\u6B65",
598
+ "kbConnector.synced": "\u5DF2\u540C\u6B65",
599
+ /* ── kbCore ── */
600
+ "kbCore.accessDenied": "\u672A\u901A\u8FC7",
601
+ "kbCore.accessExpired": "\u5DF2\u8FC7\u671F",
602
+ "kbCore.accessExpiring": "\u5373\u5C06\u5230\u671F",
603
+ "kbCore.accessGranted": "\u5DF2\u5F00\u901A",
604
+ "kbCore.accessNotRequested": "\u672A\u7533\u8BF7",
605
+ "kbCore.accessPending": "\u5F85\u5BA1\u6279",
606
+ "kbCore.accessRequested": "\u5DF2\u63D0\u4EA4",
607
+ "kbCore.accessRevoked": "\u5DF2\u6536\u56DE",
608
+ "kbCore.auditApprove": "\u6279\u51C6",
609
+ "kbCore.auditBreakGlass": "\u5E94\u6025\u8BBF\u95EE",
610
+ "kbCore.auditDelegation": "\u59D4\u6D3E",
611
+ "kbCore.auditDeny": "\u62D2\u7EDD",
612
+ "kbCore.auditGrant": "\u6388\u4E88",
613
+ "kbCore.auditPermissionChange": "\u6743\u9650\u53D8\u66F4",
614
+ "kbCore.auditPreview": "\u9884\u89C8",
615
+ "kbCore.auditRead": "\u8BFB\u53D6",
616
+ "kbCore.auditRequest": "\u7533\u8BF7",
617
+ "kbCore.auditRevoke": "\u6536\u56DE",
618
+ "kbCore.auditSync": "\u6743\u9650\u540C\u6B65",
619
+ "kbCore.daysAgo": "{p0} \u5929\u524D",
620
+ "kbCore.hoursAgo": "{p0} \u5C0F\u65F6\u524D",
621
+ "kbCore.hygieneBroadGroup": "\u8FC7\u5BBD\u7EC4\u6388\u6743",
622
+ "kbCore.hygieneBrokenInheritance": "\u65AD\u7EE7\u627F",
623
+ "kbCore.hygieneOrgWideLink": "\u7EC4\u7EC7\u7EA7\u94FE\u63A5",
624
+ "kbCore.hygieneOrphanedOwner": "\u8D1F\u8D23\u4EBA\u7F3A\u4F4D",
625
+ "kbCore.hygieneOverexposed": "\u8FC7\u5EA6\u66B4\u9732",
626
+ "kbCore.hygieneSensitiveMismatch": "\u654F\u611F\u5EA6\u9519\u914D",
627
+ "kbCore.justNow": "\u521A\u521A",
628
+ "kbCore.levelComment": "\u53EF\u8BC4\u8BBA",
629
+ "kbCore.levelEdit": "\u53EF\u7F16\u8F91",
630
+ "kbCore.levelNone": "\u65E0\u6743\u9650",
631
+ "kbCore.levelOwner": "\u8D1F\u8D23\u4EBA",
632
+ "kbCore.levelView": "\u53EF\u67E5\u770B",
633
+ "kbCore.minutesAgo": "{p0} \u5206\u949F\u524D",
634
+ "kbCore.runCancelled": "\u5DF2\u53D6\u6D88",
635
+ "kbCore.runDone": "\u5DF2\u5B8C\u6210",
636
+ "kbCore.runFailed": "\u5931\u8D25",
637
+ "kbCore.runQueued": "\u6392\u961F\u4E2D",
638
+ "kbCore.runRunning": "\u8FDB\u884C\u4E2D",
639
+ "kbCore.runUnstarted": "\u672A\u5F00\u59CB",
640
+ "kbCore.stageAgent": "\u4EE3\u7406",
641
+ "kbCore.stageChunk": "\u5207\u7247",
642
+ "kbCore.stageEmbed": "\u5411\u91CF\u5316",
643
+ "kbCore.stageGeneration": "\u751F\u6210",
644
+ "kbCore.stageGuard": "\u62A4\u680F",
645
+ "kbCore.stageQuery": "\u67E5\u8BE2",
646
+ "kbCore.stageRerank": "\u91CD\u6392",
647
+ "kbCore.stageRetrieval": "\u68C0\u7D22",
648
+ "kbCore.stageTool": "\u5DE5\u5177",
649
+ "kbCore.typeApi": "\u63A5\u53E3",
650
+ "kbCore.typeCode": "\u4EE3\u7801",
651
+ "kbCore.typeDatabase": "\u6570\u636E\u5E93",
652
+ "kbCore.typeDocument": "\u6587\u6863",
653
+ "kbCore.typeEmail": "\u90AE\u4EF6",
654
+ "kbCore.typeImage": "\u56FE\u7247",
655
+ "kbCore.typeKb": "\u77E5\u8BC6\u5E93",
656
+ "kbCore.typeTable": "\u8868\u683C",
657
+ "kbCore.typeTicket": "\u5DE5\u5355",
658
+ "kbCore.typeWebpage": "\u7F51\u9875",
659
+ "kbCore.unnamedSource": "\u672A\u547D\u540D\u6765\u6E90",
660
+ "kbCore.unnamedSubject": "\u672A\u547D\u540D\u4E3B\u4F53",
661
+ "kbCore.visHidden": "\u4E0D\u53EF\u89C1",
662
+ "kbCore.visMetadataOnly": "\u4EC5\u5143\u6570\u636E",
663
+ "kbCore.visSummaryOnly": "\u4EC5\u6458\u8981",
664
+ "kbCore.visVisible": "\u53EF\u89C1",
665
+ /* ── kbEval ── */
666
+ "kbEval.avgA": "A \u5747\u5206 {p0}",
667
+ "kbEval.avgB": "B \u5747\u5206 {p0}",
668
+ "kbEval.compare": "\u5BF9\u6BD4",
669
+ "kbEval.runSelectAria": "\u9009\u62E9\u5BF9\u6BD4\u8FD0\u884C",
670
+ "kbEval.expected": "\u671F\u671B",
671
+ "kbEval.gradeImprovement": "\u63D0\u5347",
672
+ "kbEval.gradeRegression": "\u56DE\u5F52",
673
+ "kbEval.gradeTie": "\u6301\u5E73",
674
+ "kbEval.gradeTradeoff": "\u6743\u8861",
675
+ "kbEval.noData": "\u6CA1\u6709\u5BF9\u6BD4\u6570\u636E",
676
+ "kbEval.onlyRegression": "\u4EC5\u770B\u56DE\u5F52",
677
+ "kbEval.outputA": "\u8F93\u51FA A",
678
+ "kbEval.outputB": "\u8F93\u51FA B",
679
+ "kbEval.outputN": "\u8F93\u51FA {p0}",
680
+ /* ── kbExplain ── */
681
+ "kbExplain.empty": "\u6682\u65E0\u53E3\u5F84\u4FE1\u606F",
682
+ "kbExplain.groupAgg": "\u805A\u5408",
683
+ "kbExplain.groupColumn": "\u5217",
684
+ "kbExplain.groupFilter": "\u7B5B\u9009",
685
+ "kbExplain.groupTable": "\u8868",
686
+ "kbExplain.trigger": "\u8FD9\u4E2A\u6570\u5B57\u662F\u600E\u4E48\u7B97\u51FA\u6765\u7684",
687
+ "kbExplain.viewDefinition": "\u67E5\u770B\u53E3\u5F84",
688
+ /* ── kbFilter ── */
689
+ "kbFilter.addGroup": "+ \u7EC4",
690
+ "kbFilter.addRule": "+ \u89C4\u5219",
691
+ "kbFilter.and": "\u4E14",
692
+ "kbFilter.combineMode": "\u7EC4\u5408\u65B9\u5F0F {p0}",
693
+ "kbFilter.copyDsl": "\u590D\u5236 DSL",
694
+ "kbFilter.deleteGroup": "\u5220\u9664\u7EC4",
695
+ "kbFilter.deleteRule": "\u5220\u9664\u89C4\u5219",
696
+ "kbFilter.fieldLabel": "\u5B57\u6BB5",
697
+ "kbFilter.fieldPlaceholder": "\u8FC7\u6EE4\u5B57\u6BB5",
698
+ "kbFilter.noValueNeeded": "\uFF08\u65E0\u9700\u503C\uFF09",
699
+ "kbFilter.none": "\uFF08\u65E0\u8FC7\u6EE4\uFF09",
700
+ "kbFilter.opContains": "\u5305\u542B",
701
+ "kbFilter.opEq": "\u7B49\u4E8E",
702
+ "kbFilter.opExists": "\u5B58\u5728",
703
+ "kbFilter.opGt": "\u5927\u4E8E",
704
+ "kbFilter.opGte": "\u5927\u4E8E\u7B49\u4E8E",
705
+ "kbFilter.opIn": "\u5C5E\u4E8E",
706
+ "kbFilter.opLt": "\u5C0F\u4E8E",
707
+ "kbFilter.opLte": "\u5C0F\u4E8E\u7B49\u4E8E",
708
+ "kbFilter.opNe": "\u4E0D\u7B49\u4E8E",
709
+ "kbFilter.operatorLabel": "\u64CD\u4F5C\u7B26",
710
+ "kbFilter.or": "\u6216",
711
+ "kbFilter.toggleAndOr": "\u5207\u6362 AND / OR",
712
+ "kbFilter.valueAria": "\u8FC7\u6EE4\u503C",
713
+ "kbFilter.valueLabel": "\u503C",
714
+ "kbFilter.valuePlaceholder": "\u503C 1, \u503C 2\uFF08\u9017\u53F7\u5206\u9694\uFF09",
715
+ /* ── kbGap ── */
716
+ "kbGap.addSynonym": "\u52A0\u540C\u4E49\u8BCD",
717
+ "kbGap.colCount": "\u6B21\u6570",
718
+ "kbGap.colLastSeen": "\u6700\u8FD1\u51FA\u73B0",
719
+ "kbGap.colQuery": "\u67E5\u8BE2",
720
+ "kbGap.colShare": "\u5360\u6BD4",
721
+ "kbGap.createDoc": "\u5EFA\u6587\u6863",
722
+ "kbGap.empty": "\u6CA1\u6709\u672A\u547D\u4E2D\u67E5\u8BE2\u2014\u2014\u8986\u76D6\u826F\u597D",
723
+ "kbGap.title": "\u672A\u547D\u4E2D\u67E5\u8BE2\u8D8B\u52BF",
724
+ "kbGap.zeroClickHint": "\u7528\u6237\u53EF\u80FD\u5DF2\u4ECE\u5F15\u7528\u7247\u6BB5\u5F97\u5230\u7B54\u6848\uFF1B\u96F6\u70B9\u51FB\u9700\u4EBA\u5DE5\u5224\u8BFB\uFF0C\u4E0D\u76F4\u63A5\u89C6\u4E3A\u5931\u8D25",
725
+ "kbGap.zeroClickRate": "\u96F6\u70B9\u51FB\u7387",
726
+ "kbGap.zeroClickTitle": "\u96F6\u70B9\u51FB \u2260 \u5931\u8D25",
727
+ /* ── kbHittest ── */
728
+ "kbHittest.addAria": "\u65B0\u589E\u6D4B\u8BD5\u95EE\u9898",
729
+ "kbHittest.addPlaceholder": "\u65B0\u589E\u95EE\u9898\uFF0CEnter \u6DFB\u52A0",
730
+ "kbHittest.avgScore": "\u5747\u5206",
731
+ "kbHittest.deleteQuestion": "\u5220\u9664\u95EE\u9898",
732
+ "kbHittest.empty": "\u6682\u65E0\u6D4B\u8BD5\u95EE\u9898\u2014\u2014\u6DFB\u52A0\u7B2C\u4E00\u6761\uFF0C\u5F00\u59CB\u53EC\u56DE\u56DE\u5F52",
733
+ "kbHittest.expectHit": "\u671F\u671B\u547D\u4E2D\u5728\u524D\u6392\u547D\u4E2D\u4E2D",
734
+ "kbHittest.expectMiss": "\u671F\u671B\u672A\u547D\u4E2D",
735
+ "kbHittest.hitRate": "\u547D\u4E2D\u7387",
736
+ "kbHittest.noExpectation": "\u672A\u8BBE\u671F\u671B",
737
+ "kbHittest.notRun": "\u672A\u8FD0\u884C",
738
+ "kbHittest.pass": "\u901A\u8FC7",
739
+ "kbHittest.pin": "\u7F6E\u9876\u56FA\u5B9A",
740
+ "kbHittest.runAll": "\u8FD0\u884C\u5168\u90E8",
741
+ "kbHittest.sessionOnly": "\u53C2\u6570\u4EC5\u672C\u6B21\u4F1A\u8BDD\u751F\u6548",
742
+ "kbHittest.sessionOnlyHint": "\u6D4B\u8BD5\u8FD0\u884C\u7684\u68C0\u7D22\u53C2\u6570\uFF08topK/\u9608\u503C/\u91CD\u6392\uFF09\u4E0D\u843D\u5E93\uFF0C\u4EC5\u672C\u6B21\u4F1A\u8BDD\u751F\u6548",
743
+ "kbHittest.unpin": "\u53D6\u6D88\u7F6E\u9876",
744
+ /* ── kbMetadata ── */
745
+ "kbMetadata.addField": "\u65B0\u589E\u5B57\u6BB5",
746
+ "kbMetadata.builtIn": "\u5185\u7F6E",
747
+ "kbMetadata.colField": "\u5B57\u6BB5",
748
+ "kbMetadata.colType": "\u7C7B\u578B",
749
+ "kbMetadata.colValue": "\u503C",
750
+ "kbMetadata.empty": "\u6682\u65E0\u5143\u6570\u636E\u5B57\u6BB5",
751
+ "kbMetadata.nameLabel": "\u65B0\u5B57\u6BB5\u540D",
752
+ "kbMetadata.namePlaceholder": "\u5B57\u6BB5\u540D\uFF0C\u5982 department",
753
+ "kbMetadata.removeField": "\u79FB\u9664\u5B57\u6BB5 {p0}",
754
+ "kbMetadata.typeLabel": "\u65B0\u5B57\u6BB5\u7C7B\u578B",
755
+ "kbMetadata.valueOf": "{p0} \u7684\u503C",
756
+ /* ── kbPassage ── */
757
+ "kbPassage.blockRange": "\u5757 {p0}\u2013{p1}",
758
+ "kbPassage.close": "\u5173\u95ED\u539F\u6587",
759
+ "kbPassage.expandContext": "\u5C55\u5F00\u4E0A\u4E0B\u6587",
760
+ "kbPassage.locate": "\u539F\u6587\u5B9A\u4F4D",
761
+ "kbPassage.none": "\uFF08\u65E0\u539F\u6587\uFF09",
762
+ "kbPassage.pageRange": "\u7B2C {p0}\u2013{p1} \u9875",
763
+ "kbPassage.restricted": "\u5185\u5BB9\u53D7\u9650",
764
+ "kbPassage.unitByte": "\u5B57\u8282",
765
+ "kbPassage.unitChar": "\u5B57\u7B26",
766
+ /* ── kbPipeline ── */
767
+ "kbPipeline.empty": "\u6682\u65E0\u89E3\u6790\u4EFB\u52A1",
768
+ "kbPipeline.progress": "\u89E3\u6790\u8FDB\u5EA6",
769
+ "kbPipeline.rerun": "\u91CD\u8DD1",
770
+ "kbPipeline.unknownStage": "\u672A\u77E5\u9636\u6BB5",
771
+ /* ── kbQa ── */
772
+ "kbQa.colAnswer": "\u7B54\u6848",
773
+ "kbQa.colQuestion": "\u95EE\u9898",
774
+ "kbQa.csvHint": "CSV \u6A21\u677F\uFF1Aquestion,answer\uFF08\u6BCF\u884C\u4E00\u5BF9\uFF0CUTF-8\uFF09",
775
+ "kbQa.deleteRow": "\u5220\u9664\u7B2C {p0} \u884C",
776
+ "kbQa.empty": "\u6682\u65E0\u8BA4\u8BC1\u95EE\u7B54\u5BF9",
777
+ "kbQa.importCsv": "\u5BFC\u5165 CSV",
778
+ /* ── kbRerank ── */
779
+ "kbRerank.after": "\u91CD\u6392\u540E",
780
+ "kbRerank.before": "\u91CD\u6392\u524D",
781
+ "kbRerank.compareTitle": "\u91CD\u6392\u5BF9\u6BD4",
782
+ "kbRerank.down": "\u4E0B\u964D {p0} \u4F4D",
783
+ "kbRerank.dropped": "\u843D\u9009",
784
+ "kbRerank.empty": "\u4E24\u4FA7\u5747\u4E3A\u7A7A\u2014\u2014\u8FD0\u884C\u68C0\u7D22\u540E\u518D\u5BF9\u6BD4",
785
+ "kbRerank.enableCompare": "\u542F\u7528\u91CD\u6392\u5BF9\u6BD4",
786
+ "kbRerank.newIn": "\u65B0\u8FDB",
787
+ "kbRerank.unmarked": "\u672A\u6807",
788
+ "kbRerank.up": "\u4E0A\u5347 {p0} \u4F4D",
789
+ /* ── kbRetrieval ── */
790
+ "kbRetrieval.breakdown": "\u62C6\u89E3",
791
+ "kbRetrieval.copyParams": "\u590D\u5236\u53C2\u6570 JSON",
792
+ "kbRetrieval.decreaseTopK": "\u51CF\u5C11 topK",
793
+ "kbRetrieval.empty": "\u8F93\u5165\u95EE\u9898\u5E76\u8FD0\u884C\uFF0C\u547D\u4E2D\u7ED3\u679C\u5C06\u51FA\u73B0\u5728\u8FD9\u91CC",
794
+ "kbRetrieval.failOpenNotice": "fail-open\uFF1A\u5F53\u524D\u67E5\u8BE2\u672A\u643A\u5E26\u8EAB\u4EFD\u8FC7\u6EE4\uFF0C\u5C06\u8FD4\u56DE\u5168\u90E8\u5019\u9009\uFF08\u4EC5\u9650\u8C03\u8BD5\uFF09",
795
+ "kbRetrieval.hybridWeight": "\u6DF7\u5408\u6743\u91CD\uFF08\u5DE6\u8BED\u4E49\u53F3\u5173\u952E\u8BCD\uFF09",
796
+ "kbRetrieval.identityLabel": "\u68C0\u7D22\u8EAB\u4EFD",
797
+ "kbRetrieval.identityShort": "\u8EAB\u4EFD",
798
+ "kbRetrieval.increaseTopK": "\u589E\u52A0 topK",
799
+ "kbRetrieval.keywordHint": "\u5173\u952E\u8BCD\uFF1A\u5927\u5E93\u5FEB\u901F\u7CBE\u786E",
800
+ "kbRetrieval.layerLabel": "\u8FC7\u6EE4\u5C42",
801
+ "kbRetrieval.layerNone": "none\uFF1Afail-open\uFF0C\u65E0\u8EAB\u4EFD\u8FC7\u6EE4\u8FD4\u56DE\u5168\u90E8\u2014\u2014\u5371\u9669\uFF0C\u4EC5\u6F14\u793A",
802
+ "kbRetrieval.layerPost": "post-filter\uFF1A\u5206\u6570\u5DF2\u53EF\u89C2\u5BDF\u2014\u2014\u7F3A\u9677\u5C42\uFF0C\u4EC5\u6F14\u793A",
803
+ "kbRetrieval.layerPre": "pre-filter\uFF1AACL \u5728\u68C0\u7D22\u6267\u884C\u4F53\u5185\u751F\u6548\u2014\u2014\u5B89\u5168\u57FA\u7EBF",
804
+ "kbRetrieval.leakNote": "\u5206\u6BCD\u672A\u8FC7\u6EE4\u524D\u8BA1\u6570\u5C5E\u6CC4\u9732\uFF0C\u4E0D\u663E\u793A",
805
+ "kbRetrieval.modeHybrid": "\u6DF7\u5408",
806
+ "kbRetrieval.modeKeyword": "\u5173\u952E\u8BCD",
807
+ "kbRetrieval.modeLabel": "\u68C0\u7D22\u6A21\u5F0F",
808
+ "kbRetrieval.modeVector": "\u5411\u91CF",
809
+ "kbRetrieval.postFilterNotice": "post-filter\uFF1A\u5206\u6570\u5DF2\u5728\u8FC7\u6EE4\u524D\u4EA7\u751F\uFF08\u7F3A\u9677\u5C42\u6F14\u793A\uFF09",
810
+ "kbRetrieval.queryLabel": "\u68C0\u7D22\u95EE\u9898",
811
+ "kbRetrieval.queryPlaceholder": "\u68C0\u7D22\u95EE\u9898\uFF0CEnter \u8FD0\u884C",
812
+ "kbRetrieval.rerankLabel": "\u91CD\u6392",
813
+ "kbRetrieval.rerankThresholdOff": "\u9608\u503C \u5173 \xB7 \u5B58\u6D3B {p0}",
814
+ "kbRetrieval.rerankThresholdOn": "\u9608\u503C {p0} \xB7 \u5B58\u6D3B {p1}",
815
+ "kbRetrieval.running": "\u8FD0\u884C\u4E2D\u2026",
816
+ "kbRetrieval.thresholdLabel": "\u5206\u6570\u9608\u503C",
817
+ "kbRetrieval.thresholdValue": "\u9608\u503C N/A",
818
+ "kbRetrieval.vectorHint": "\u8BED\u4E49\uFF1A\u8DE8\u8BED\u8A00/\u65E0\u7CBE\u786E\u8BCD",
819
+ "kbRetrieval.vectorPercent": "\u8BED\u4E49 {p0}",
820
+ "kbRetrieval.weightValue": "\u5411\u91CF {p0}% / \u5173\u952E\u8BCD {p1}%",
821
+ /* ── kbReview ── */
822
+ "kbReview.assignee": "\u5206\u914D\u4EBA",
823
+ "kbReview.doneNext": "\u5B8C\u6210\u5E76\u4E0B\u4E00\u6761",
824
+ "kbReview.empty": "\u6CA1\u6709\u5F85\u5BA1\u67E5\u6761\u76EE",
825
+ "kbReview.emptyAssignee": "\u8BE5\u5206\u914D\u4EBA\u4E0B\u6CA1\u6709\u6761\u76EE",
826
+ "kbReview.emptyQueue": "\u961F\u5217\u4E3A\u7A7A",
827
+ "kbReview.kbCloseHint": "\u5173\u95ED\u63D0\u793A",
828
+ "kbReview.kbSelectOption": "\u9009\u62E9\u9009\u9879",
829
+ "kbReview.kbSwitchItem": "\u5207\u6362\u6761\u76EE",
830
+ "kbReview.kbToggleHint": "\u663E\u793A/\u9690\u85CF\u672C\u63D0\u793A",
831
+ "kbReview.shortcuts": "? \u5FEB\u6377\u952E",
832
+ "kbReview.typeAnswer": "\u56DE\u7B54",
833
+ "kbReview.typeMessage": "\u6D88\u606F",
834
+ "kbReview.typeTrace": "\u8F68\u8FF9",
835
+ "kbReview.unassigned": "\u672A\u5206\u914D",
836
+ /* ── kbSandbox ── */
837
+ "kbSandbox.noResolver": "\u5BBF\u4E3B\u672A\u63D0\u4F9B ui:// \u89E3\u6790\u5668",
838
+ "kbSandbox.notReady": "kb-sandbox: \u5E94\u7528\u672A\u5C31\u7EEA",
839
+ "kbSandbox.resolveFailed": "ui:// \u89E3\u6790\u5931\u8D25\uFF1A{p0}",
840
+ "kbSandbox.timeout": "kb-sandbox: \u8C03\u7528\u8D85\u65F6\uFF08{p0}ms\uFF09",
841
+ "kbSandbox.title": "MCP App \u6C99\u7BB1",
842
+ /* ── kbSegment ── */
843
+ "kbSegment.avgLength": "\u5747\u957F {p0}",
844
+ "kbSegment.childNote": "\u5B50\u5206\u6BB5\u6309\u957F\u5EA6\u81EA\u52A8\u751F\u6210",
845
+ "kbSegment.cleanBlankLines": "\u5408\u5E76\u8FDE\u7EED\u7A7A\u884C",
846
+ "kbSegment.cleanEmails": "\u53BB\u9664\u90AE\u7BB1",
847
+ "kbSegment.cleanLinks": "\u53BB\u9664\u94FE\u63A5",
848
+ "kbSegment.empty": "\u6837\u672C\u4E3A\u7A7A\uFF0C\u6682\u65E0\u53EF\u9884\u89C8\u5206\u6BB5",
849
+ "kbSegment.maxLengthLabel": "\u6700\u5927\u957F\u5EA6",
850
+ "kbSegment.maxLengthPlaceholder": "\u5206\u6BB5\u6700\u5927\u957F\u5EA6",
851
+ "kbSegment.modeAuto": "\u81EA\u52A8",
852
+ "kbSegment.modeCustom": "\u81EA\u5B9A\u4E49",
853
+ "kbSegment.modeLabel": "\u5206\u6BB5\u6A21\u5F0F",
854
+ "kbSegment.modeNote": "\u5206\u6BB5\u6A21\u5F0F\u521B\u5EFA\u540E\u4E0D\u53EF\u66F4\u6539\uFF0C\u53C2\u6570\u53EF\u968F\u65F6\u8C03\u6574",
855
+ "kbSegment.modeParentChild": "\u7236\u5B50",
856
+ "kbSegment.overlapInvalid": "\u91CD\u53E0\u9700\u5C0F\u4E8E\u6700\u5927\u957F\u5EA6",
857
+ "kbSegment.overlapLabel": "\u91CD\u53E0",
858
+ "kbSegment.overlapPlaceholder": "\u5206\u6BB5\u91CD\u53E0",
859
+ "kbSegment.previewNote": "\u5171 {p0} \u6BB5\uFF0C\u4EC5\u9884\u89C8\u524D {p1} \u6BB5",
860
+ "kbSegment.segmentsCount": "{p0} \u6BB5",
861
+ "kbSegment.separatorLabel": "\u5206\u9694\u7B26",
862
+ "kbSegment.separatorPlaceholder": "\u5206\u6BB5\u5206\u9694\u7B26",
863
+ "kbSegment.toggleTip": "\u70B9\u51FB\u5C55\u5F00/\u6536\u8D77",
864
+ /* ── kbSources ── */
865
+ "kbSources.cited": "\u88AB\u5F15 \xD7{p0}",
866
+ "kbSources.empty": "\u4E0B\u4E00\u6761\u7B54\u6848\u5F15\u7528\u7684\u6BB5\u843D\u5C06\u51FA\u73B0\u5728\u8FD9\u91CC",
867
+ /* ── kbSql ── */
868
+ "kbSql.adminOnly": "\u4EC5\u7BA1\u7406\u5458\u53EF\u89C1",
869
+ "kbSql.applyFix": "\u5E94\u7528\u4FEE\u590D\u5E76\u91CD\u8DD1",
870
+ "kbSql.confirmRerun": "\u786E\u8BA4\u5E76\u91CD\u8DD1",
871
+ "kbSql.editRerun": "\u7F16\u8F91\u91CD\u8DD1",
872
+ "kbSql.fixReady": "\u68C0\u6D4B\u5230\u4E0A\u7248\u62A5\u9519\uFF0C\u4FEE\u590D\u5EFA\u8BAE\u5DF2\u5C31\u7EEA",
873
+ "kbSql.generated": "\u751F\u6210\u7684 SQL",
874
+ /* ── kbTrace ── */
875
+ "kbTrace.empty": "\u6682\u65E0\u8C03\u7528\u94FE\u6570\u636E",
876
+ "kbTrace.hits": "\u547D\u4E2D {p0}",
877
+ /* ── kbVisibility ── */
878
+ "kbVisibility.adminOnlyNote": "\u4EE5\u4E0A\u5BF9\u7167\u4EC5\u9650 admin \u5BA1\u8BA1",
879
+ "kbVisibility.adminWarn": "admin \u5BA1\u8BA1\u89C6\u56FE\u2014\u2014\u547D\u4E2D\u5DEE\u5F02\u5BF9\u7167\u5BF9\u666E\u901A\u7528\u6237\u6784\u6210\u6CC4\u9732\uFF0C\u52FF\u5D4C\u5165\u7EC8\u7AEF\u7528\u6237\u754C\u9762",
880
+ "kbVisibility.failOpenNote": "fail-open\uFF1AKendra \u65E0\u8EAB\u4EFD\u4E0A\u4E0B\u6587\u8FD4\u56DE\u5168\u90E8\u6587\u6863\u2014\u2014\u68C0\u7D22\u5FC5\u987B\u643A\u5E26\u670D\u52A1\u7AEF\u8EAB\u4EFD",
881
+ "kbVisibility.focusColumn": "\u805A\u7126\u8EAB\u4EFD {p0} \u7684\u5217",
882
+ "kbVisibility.layerValue": "\u8FC7\u6EE4\u5C42\uFF1A{p0}",
883
+ "kbVisibility.leakageNote": "\u8BA1\u6570\u5DEE\u5F02\u5373 volume leakage\uFF1A\u5BF9\u666E\u901A\u7528\u6237\u53EA\u53EF\u7ED9\u300C\u5DF2\u6309\u6743\u9650\u8FC7\u6EE4\u300D\u6052\u5B9A\u6587\u6848\uFF0C\u7F13\u89E3\u53EA\u6709 padding \u53D6\u6574",
884
+ "kbVisibility.postFilterNote": "post-filter\uFF1AtopK \u88AB\u65E0\u6743\u7ED3\u679C\u5360\u7528\u4E14\u76F8\u4F3C\u5EA6\u5206\u6570\u53EF\u88AB\u89C2\u5BDF",
885
+ "kbVisibility.queryLabel": "\u67E5\u8BE2\uFF1A{p0}",
886
+ "kbVisibility.safeCount": "\u5B89\u5168\u8BA1\u6570 {p0}",
887
+ "kbVisibility.sourceUnavailable": "\u539F\u6587\u4E0D\u53EF\u7528",
888
+ "kbVisibility.unnamedHit": "\u672A\u547D\u540D\u547D\u4E2D",
889
+ /* ── kbWhoCan ── */
890
+ "kbWhoCan.check": "\u68C0\u67E5",
891
+ "kbWhoCan.checkIdentity": "\u68C0\u67E5\u8EAB\u4EFD",
892
+ "kbWhoCan.daysUntil": "{p0} \u5929\u540E",
893
+ "kbWhoCan.deniedBy": "\u88AB\u7B56\u7565\u62D2\u7EDD\uFF1A{p0}",
894
+ "kbWhoCan.denyVeto": "\u88AB Deny \u4E00\u7968\u5426\u51B3",
895
+ "kbWhoCan.direct": "\u76F4\u63A5",
896
+ "kbWhoCan.expiresSoon": "\u6700\u8FD1\u5230\u671F {p0}",
897
+ "kbWhoCan.hoursUntil": "{p0} \u5C0F\u65F6\u540E",
898
+ "kbWhoCan.inherit": "\u7EE7\u627F",
899
+ "kbWhoCan.link": "\u94FE\u63A5",
900
+ "kbWhoCan.noDeny": "\u65E0 Deny \u751F\u6548",
901
+ "kbWhoCan.noIdentity": "\u672A\u63D0\u4F9B\u53EF\u68C0\u67E5\u7684\u8EAB\u4EFD",
902
+ "kbWhoCan.none": "\u672A\u547D\u4E2D\u4EFB\u4F55\u6388\u6743\u2014\u2014\u9ED8\u8BA4\u62D2\u7EDD",
903
+ "kbWhoCan.recheckTip": "\u91CD\u65B0\u68C0\u67E5\u5F53\u524D\u8EAB\u4EFD\u7684\u6709\u6548\u6743\u9650",
904
+ "kbWhoCan.stackRule": "\u53E0\u52A0\u89C4\u5219\uFF1A\u591A\u6765\u6E90\u5E76\u96C6 \u2192 {p0}\uFF1B{p1}",
905
+ /* ── mentions ── */
906
+ "mentions.create": "\u521B\u5EFA\u201C{p0}\u201D",
907
+ "mentions.customBadge": "\u81EA\u5B9A\u4E49",
908
+ "mentions.loading": "\u52A0\u8F7D\u4E2D\u2026",
909
+ /* ── notification ── */
910
+ "notification.groupBusy": "\u64CD\u4F5C\u7ED3\u675F\u540E\u53EF\u4EE5\u6536\u8D77\u8FD9\u7EC4\u901A\u77E5\u3002",
911
+ "notification.groupUnread": "{count} \u6761\u540C\u7EC4\u901A\u77E5\uFF0C{unread} \u6761\u672A\u8BFB",
912
+ "notification.groupCount": "{count} \u6761\u540C\u7EC4\u901A\u77E5",
913
+ "notification.groupExpanded": "\u6536\u8D77\u8FD9\u7EC4\u901A\u77E5",
914
+ "notification.ariaLabel": "\u901A\u77E5",
915
+ "notification.viewDetails": "\u67E5\u770B\u8BE6\u60C5",
916
+ /* ── pagination ── */
917
+ "pagination.next": "\u4E0B\u4E00\u9875",
918
+ "pagination.pageSize": "{p0} \u6761/\u9875",
919
+ "pagination.prev": "\u4E0A\u4E00\u9875",
920
+ /* ── select ── */
921
+ "select.fieldLabel": "\u9009\u62E9\u9009\u9879",
922
+ "select.noMatch": "\u65E0\u5339\u914D\u9879",
923
+ "select.remove": "\u79FB\u9664 {p0}",
924
+ "select.searchPlaceholder": "\u641C\u7D22\u2026",
925
+ /* ── cascader / tree-select ── */
926
+ "cascader.placeholder": "\u8BF7\u9009\u62E9",
927
+ "cascader.noMatch": "\u65E0\u5339\u914D",
928
+ "cascader.search": "\u641C\u7D22",
929
+ "treeSelect.placeholder": "\u8BF7\u9009\u62E9",
930
+ "treeSelect.noMatch": "\u65E0\u5339\u914D",
931
+ "treeSelect.search": "\u641C\u7D22",
932
+ /* ── tagInput ── */
933
+ "tagInput.ariaLabel": "\u6807\u7B7E\u8F93\u5165\uFF0C\u5171 {p0} \u4E2A",
934
+ "tagInput.remove": "\u79FB\u9664 {p0}",
935
+ "tagInput.field": "\u6DFB\u52A0\u6807\u7B7E",
936
+ "tagInput.added": "\u5DF2\u6DFB\u52A0 {p0} \u4E2A\u6807\u7B7E\u3002",
937
+ "tagInput.removed": "\u5DF2\u79FB\u9664 {p0}\u3002",
938
+ "tagInput.duplicate": "\u5DF2\u6709\u300C{p0}\u300D\uFF0C\u53EF\u4EE5\u7F16\u8F91\u540E\u91CD\u8BD5\u3002",
939
+ "tagInput.limit": "\u6700\u591A {p0} \u4E2A\u6807\u7B7E\uFF0C\u8BF7\u5148\u79FB\u9664\u4E00\u4E2A\u3002",
940
+ /* ── upload ── */
941
+ "upload.remove": "\u79FB\u9664 {p0}",
942
+ "upload.tooBig": "\u6587\u4EF6\u8D85\u8FC7 {p0}",
943
+ "upload.tooMany": "\u6700\u591A {p0} \u4E2A\u6587\u4EF6",
944
+ "upload.typeNotAllowed": "\u6587\u4EF6\u7C7B\u578B\u4E0D\u652F\u6301"
945
+ };
946
+ var current = { ...ICEN_LOCALE_ZH_CN };
947
+ function t(key, vars) {
948
+ const raw = current[key] ?? ICEN_LOCALE_ZH_CN[key];
949
+ if (vars == null || Array.isArray(raw)) return raw;
950
+ return raw.replace(/\{(\w+)\}/g, (m, name) => name in vars ? String(vars[name]) : m);
951
+ }
952
+
953
+ // src/behaviors/svg-parse.ts
954
+ function parseSvg(source) {
955
+ if (typeof document === "undefined" || typeof DOMParser === "undefined") return null;
956
+ const trimmed = source.trimStart();
957
+ if (!trimmed.startsWith("<svg")) return null;
958
+ const src = /^<svg(?![^>]*\bxmlns[=:])/i.test(trimmed) ? trimmed.replace(/^<svg/i, '<svg xmlns="http://www.w3.org/2000/svg"') : trimmed;
959
+ let parsed;
960
+ try {
961
+ parsed = new DOMParser().parseFromString(src, "image/svg+xml");
962
+ } catch {
963
+ return null;
964
+ }
965
+ const root = parsed.documentElement;
966
+ if (!root || root.tagName.toLowerCase() !== "svg" || parsed.querySelector("parsererror")) return null;
967
+ const sanitize = (el) => {
968
+ for (const attr of Array.from(el.attributes)) {
969
+ const name = attr.name.toLowerCase();
970
+ if (name.startsWith("on")) el.removeAttribute(attr.name);
971
+ if ((name === "href" || name === "xlink:href") && attr.value.trim().toLowerCase().startsWith("javascript:")) {
972
+ el.removeAttribute(attr.name);
973
+ }
974
+ }
975
+ for (const child of Array.from(el.children)) {
976
+ const tag = child.tagName.toLowerCase();
977
+ if (tag === "script" || tag === "foreignobject") {
978
+ child.remove();
979
+ continue;
980
+ }
981
+ sanitize(child);
982
+ }
983
+ };
984
+ sanitize(root);
985
+ return document.importNode(root, true);
986
+ }
987
+
1
988
  // src/behaviors/ai-core.ts
2
- var svg = (body) => `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${body}</svg>`;
3
- var ICON_TERMINAL = svg('<path d="m4 17 6-6-6-6"/><path d="M12 19h8"/>');
4
- var ICON_FILE = svg(
5
- '<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/>'
6
- );
7
- var ICON_FILE_PEN = svg(
8
- '<path d="M12.5 22H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8l5 5v3.5"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M19 6.5 16.5 4"/><path d="M21.378 16.626a1 1 0 0 0-3.004-3.004l-4.01 4.012a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506z"/>'
9
- );
10
- var ICON_FILE_PLUS = svg(
11
- '<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M9 15h6"/><path d="M12 12v6"/>'
12
- );
13
- var ICON_TRASH = svg(
14
- '<path d="M3 6h18"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><path d="M10 11v6"/><path d="M14 11v6"/>'
15
- );
16
- var ICON_SEARCH = svg('<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>');
17
- var ICON_FOLDER_SEARCH = svg(
18
- '<path d="M11 20H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v4"/><circle cx="17" cy="17" r="3"/><path d="m21 21-1.9-1.9"/>'
19
- );
20
- var ICON_SCAN_SEARCH = svg(
21
- '<path d="M3 7V5a2 2 0 0 1 2-2h2"/><path d="M17 3h2a2 2 0 0 1 2 2v2"/><path d="M21 17v2a2 2 0 0 1-2 2h-2"/><path d="M7 21H5a2 2 0 0 1-2-2v-2"/><circle cx="12" cy="12" r="3"/><path d="m16 16-1.9-1.9"/>'
22
- );
23
- var ICON_GLOBE = svg(
24
- '<circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/>'
25
- );
26
- var ICON_DOWNLOAD = svg(
27
- '<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="m7 10 5 5 5-5"/><path d="M12 15V3"/>'
28
- );
29
- var ICON_BLOCKS = svg(
30
- '<rect width="7" height="7" x="4" y="4" rx="1"/><rect width="7" height="7" x="13" y="4" rx="1"/><rect width="7" height="7" x="4" y="13" rx="1"/><rect width="7" height="7" x="13" y="13" rx="1"/>'
31
- );
32
- var ICON_ZAP = svg(
33
- '<path d="M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z"/>'
34
- );
35
- var ICON_LIST = svg(
36
- '<path d="M3 12h.01"/><path d="M3 18h.01"/><path d="M3 6h.01"/><path d="M8 12h13"/><path d="M8 18h13"/><path d="M8 6h13"/>'
37
- );
38
- var ICON_LIST_CHECKS = svg(
39
- '<path d="m3 17 2 2 4-4"/><path d="m3 7 2 2 4-4"/><path d="M13 6h8"/><path d="M13 12h8"/><path d="M13 18h8"/>'
40
- );
41
- var ICON_BOT = svg(
42
- '<path d="M12 8V4H8"/><rect width="16" height="12" x="4" y="8" rx="2"/><path d="M2 14h2"/><path d="M20 14h2"/><path d="M15 13v2"/><path d="M9 13v2"/>'
43
- );
44
- var ICON_CHART = svg(
45
- '<path d="M3 3v18h18"/><path d="M7 15l4-6 3 4 5-8"/>'
46
- );
47
- var ICON_FILE_TEXT = svg(
48
- '<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M10 9H8"/><path d="M16 13H8"/><path d="M16 17H8"/>'
49
- );
989
+ var ICON_TERMINAL = iconHTML("terminal");
990
+ var ICON_FILE = iconHTML("file");
991
+ var ICON_FILE_PEN = iconHTML("edit");
992
+ var ICON_FILE_PLUS = iconHTML("plus");
993
+ var ICON_TRASH = iconHTML("trash");
994
+ var ICON_SEARCH = iconHTML("search");
995
+ var ICON_FOLDER_SEARCH = iconHTML("folder");
996
+ var ICON_SCAN_SEARCH = iconHTML("search");
997
+ var ICON_GLOBE = iconHTML("globe");
998
+ var ICON_DOWNLOAD = iconHTML("download");
999
+ var ICON_BLOCKS = iconHTML("server");
1000
+ var ICON_ZAP = iconHTML("sparkle");
1001
+ var ICON_LIST = iconHTML("list");
1002
+ var ICON_LIST_CHECKS = iconHTML("list");
1003
+ var ICON_BOT = iconHTML("agent");
1004
+ var ICON_CHART = iconHTML("chart-line");
1005
+ var ICON_FILE_TEXT = iconHTML("document");
50
1006
  function isObj(v) {
51
1007
  return typeof v === "object" && v !== null;
52
1008
  }
@@ -96,86 +1052,58 @@ var sum = (fn) => {
96
1052
  return (input) => fn(input) ?? "";
97
1053
  };
98
1054
  var BUILTIN_KINDS = {
99
- shell: { label: "\u547D\u4EE4", icon: ICON_TERMINAL, tint: "accent", summarize: sum(summarizeShell) },
100
- read: { label: "\u8BFB\u53D6", icon: ICON_FILE, tint: "info", summarize: sum(summarizeRead) },
101
- edit: { label: "\u7F16\u8F91", icon: ICON_FILE_PEN, tint: "warning", summarize: sum(summarizePath) },
102
- write: { label: "\u5199\u5165", icon: ICON_FILE_PLUS, tint: "warning", summarize: sum(summarizePath) },
103
- rm: { label: "\u5220\u9664", icon: ICON_TRASH, tint: "error", summarize: sum(summarizePath) },
104
- grep: { label: "\u641C\u7D22", icon: ICON_SEARCH, tint: "info", summarize: sum(summarizeGrep) },
105
- glob: { label: "\u5339\u914D", icon: ICON_FOLDER_SEARCH, tint: "info", summarize: sum((i) => pickStr(i, ["pattern", "glob", "path"])) },
106
- browser: { label: "\u6D4F\u89C8", icon: ICON_GLOBE, tint: "accent", summarize: sum((i) => pickStr(i, ["url", "uri", "target"])) },
107
- search: { label: "\u68C0\u7D22", icon: ICON_SCAN_SEARCH, tint: "accent", summarize: sum((i) => pickStr(i, ["query", "q", "pattern"])) },
108
- fetch: { label: "\u8BF7\u6C42", icon: ICON_DOWNLOAD, tint: "info", summarize: sum((i) => pickStr(i, ["url", "uri", "endpoint"])) },
1055
+ shell: { label: t("aiCore.kindShell"), icon: ICON_TERMINAL, tint: "accent", summarize: sum(summarizeShell) },
1056
+ read: { label: t("aiCore.kindRead"), icon: ICON_FILE, tint: "info", summarize: sum(summarizeRead) },
1057
+ edit: { label: t("aiCore.kindEdit"), icon: ICON_FILE_PEN, tint: "warning", summarize: sum(summarizePath) },
1058
+ write: { label: t("aiCore.kindWrite"), icon: ICON_FILE_PLUS, tint: "warning", summarize: sum(summarizePath) },
1059
+ rm: { label: t("aiCore.kindDelete"), icon: ICON_TRASH, tint: "error", summarize: sum(summarizePath) },
1060
+ grep: { label: t("aiCore.kindGrep"), icon: ICON_SEARCH, tint: "info", summarize: sum(summarizeGrep) },
1061
+ glob: { label: t("aiCore.kindGlob"), icon: ICON_FOLDER_SEARCH, tint: "info", summarize: sum((i) => pickStr(i, ["pattern", "glob", "path"])) },
1062
+ browser: { label: t("aiCore.kindBrowser"), icon: ICON_GLOBE, tint: "accent", summarize: sum((i) => pickStr(i, ["url", "uri", "target"])) },
1063
+ search: { label: t("aiCore.kindSearch"), icon: ICON_SCAN_SEARCH, tint: "accent", summarize: sum((i) => pickStr(i, ["query", "q", "pattern"])) },
1064
+ fetch: { label: t("aiCore.kindFetch"), icon: ICON_DOWNLOAD, tint: "info", summarize: sum((i) => pickStr(i, ["url", "uri", "endpoint"])) },
109
1065
  mcp: { label: "MCP", icon: ICON_BLOCKS, tint: "muted", summarize: sum((i) => pickStr(i, ["tool", "method", "name"])) },
110
- skill: { label: "\u6280\u80FD", icon: ICON_ZAP, tint: "accent", summarize: sum((i) => pickStr(i, ["skill", "name", "command"])) },
1066
+ skill: { label: t("aiCore.kindSkill"), icon: ICON_ZAP, tint: "accent", summarize: sum((i) => pickStr(i, ["skill", "name", "command"])) },
111
1067
  todo: {
112
- label: "\u5F85\u529E",
1068
+ label: t("aiCore.kindTodo"),
113
1069
  icon: ICON_LIST,
114
1070
  tint: "info",
115
1071
  summarize: sum((input) => {
116
1072
  const items = input && typeof input === "object" && Array.isArray(input.items) ? input.items : Array.isArray(input) ? input : [];
117
1073
  const done = items.filter((it) => it?.status === "done").length;
118
- return items.length > 0 ? `${done}/${items.length} \u5B8C\u6210` : "";
1074
+ return items.length > 0 ? t("aiCore.todoProgress", { p0: done, p1: items.length }) : "";
119
1075
  })
120
1076
  },
121
- plan: { label: "\u8BA1\u5212", icon: ICON_LIST_CHECKS, tint: "info" },
122
- subagent: { label: "\u5B50\u4EE3\u7406", icon: ICON_BOT, tint: "accent", summarize: sum((i) => pickStr(i, ["task", "description", "prompt", "message", "subagent_type"])) },
123
- note: { label: "\u7B14\u8BB0", icon: ICON_FILE_TEXT, tint: "muted" },
124
- chart: { label: "\u56FE\u8868", icon: ICON_CHART, tint: "info", summarize: sum((i) => pickStr(i, ["title", "name"])) }
1077
+ plan: { label: t("aiCore.kindPlan"), icon: ICON_LIST_CHECKS, tint: "info" },
1078
+ subagent: { label: t("aiCore.kindSubagent"), icon: ICON_BOT, tint: "accent", summarize: sum((i) => pickStr(i, ["task", "description", "prompt", "message", "subagent_type"])) },
1079
+ note: { label: t("aiCore.kindNote"), icon: ICON_FILE_TEXT, tint: "muted" },
1080
+ chart: { label: t("aiCore.kindChart"), icon: ICON_CHART, tint: "info", summarize: sum((i) => pickStr(i, ["title", "name"])) }
125
1081
  };
126
1082
  var kindRegistry = new Map(Object.entries(BUILTIN_KINDS));
127
1083
  function h(tag, className, text) {
1084
+ if (typeof document === "undefined") throw new Error("h() \u4EC5\u6D4F\u89C8\u5668\u73AF\u5883\u53EF\u7528\uFF08SSR \u65F6\u7531\u8C03\u7528\u65B9\u5B88\u536B\uFF0C\u89C1\u6A21\u5757\u5934\u6CE8\u91CA\uFF09");
128
1085
  const node = document.createElement(tag);
129
1086
  if (className) node.className = className;
130
1087
  if (text != null) node.textContent = text;
131
1088
  return node;
132
1089
  }
133
- function svgIcon(svg2) {
134
- if (typeof document === "undefined" || typeof DOMParser === "undefined") return null;
135
- let parsed;
136
- try {
137
- parsed = new DOMParser().parseFromString(svg2, "image/svg+xml");
138
- } catch {
139
- return null;
140
- }
141
- const root = parsed.documentElement;
142
- if (!root || root.tagName.toLowerCase() !== "svg" || parsed.querySelector("parsererror")) {
143
- return null;
144
- }
145
- const sanitize = (el) => {
146
- for (const attr of Array.from(el.attributes)) {
147
- const name = attr.name.toLowerCase();
148
- if (name.startsWith("on")) el.removeAttribute(attr.name);
149
- if ((name === "href" || name === "xlink:href") && attr.value.trim().toLowerCase().startsWith("javascript:")) {
150
- el.removeAttribute(attr.name);
151
- }
152
- }
153
- for (const child of Array.from(el.children)) {
154
- const tag = child.tagName.toLowerCase();
155
- if (tag === "script" || tag === "foreignobject") {
156
- child.remove();
157
- continue;
158
- }
159
- sanitize(child);
160
- }
161
- };
162
- sanitize(root);
163
- return document.importNode(root, true);
1090
+ function svgIcon(svg) {
1091
+ return parseSvg(svg);
164
1092
  }
165
1093
 
166
1094
  // src/behaviors/kb-core.ts
167
1095
  var ic = (label, d) => ({ label, icon: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">${d}</svg>` });
168
1096
  var BUILTIN_SOURCE_TYPES = {
169
- doc: ic("\u6587\u6863", '<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/>'),
170
- web: ic("\u7F51\u9875", '<circle cx="12" cy="12" r="10"/><path d="M2 12h20"/><path d="M12 2a15 15 0 0 1 0 20 15 15 0 0 1 0-20z"/>'),
171
- wiki: ic("\u77E5\u8BC6\u5E93", '<path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/>'),
172
- sheet: ic("\u8868\u683C", '<rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M3 15h18M9 3v18M15 3v18"/>'),
173
- db: ic("\u6570\u636E\u5E93", '<ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5v14c0 1.7 4 3 9 3s9-1.3 9-3V5"/><path d="M3 12c0 1.7 4 3 9 3s9-1.3 9-3"/>'),
174
- ticket: ic("\u5DE5\u5355", '<path d="M3 9V7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v2a2 2 0 0 0 0 6v2a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-2a2 2 0 0 0 0-6z"/><path d="M13 5v14"/>'),
175
- code: ic("\u4EE3\u7801", '<path d="m16 18 6-6-6-6"/><path d="m8 6-6 6 6 6"/>'),
176
- api: ic("\u63A5\u53E3", '<path d="M4 7a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v3a2 2 0 0 0 0 4v3a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-3a2 2 0 0 0 0-4z"/>'),
177
- image: ic("\u56FE\u7247", '<rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-4.6-4.6a2 2 0 0 0-2.8 0L3 21"/>'),
178
- mail: ic("\u90AE\u4EF6", '<rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 7-10 7L2 7"/>')
1097
+ doc: ic(t("kbCore.typeDocument"), '<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/>'),
1098
+ web: ic(t("kbCore.typeWebpage"), '<circle cx="12" cy="12" r="10"/><path d="M2 12h20"/><path d="M12 2a15 15 0 0 1 0 20 15 15 0 0 1 0-20z"/>'),
1099
+ wiki: ic(t("kbCore.typeKb"), '<path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/>'),
1100
+ sheet: ic(t("kbCore.typeTable"), '<rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M3 15h18M9 3v18M15 3v18"/>'),
1101
+ db: ic(t("kbCore.typeDatabase"), '<ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5v14c0 1.7 4 3 9 3s9-1.3 9-3V5"/><path d="M3 12c0 1.7 4 3 9 3s9-1.3 9-3"/>'),
1102
+ ticket: ic(t("kbCore.typeTicket"), '<path d="M3 9V7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v2a2 2 0 0 0 0 6v2a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-2a2 2 0 0 0 0-6z"/><path d="M13 5v14"/>'),
1103
+ code: ic(t("kbCore.typeCode"), '<path d="m16 18 6-6-6-6"/><path d="m8 6-6 6 6 6"/>'),
1104
+ api: ic(t("kbCore.typeApi"), '<path d="M4 7a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v3a2 2 0 0 0 0 4v3a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-3a2 2 0 0 0 0-4z"/>'),
1105
+ image: ic(t("kbCore.typeImage"), '<rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-4.6-4.6a2 2 0 0 0-2.8 0L3 21"/>'),
1106
+ mail: ic(t("kbCore.typeEmail"), '<rect x="2" y="4" width="20" height="16" rx="2"/><path d="m22 7-10 7L2 7"/>')
179
1107
  };
180
1108
  var sourceTypeRegistry = new Map(Object.entries(BUILTIN_SOURCE_TYPES));
181
1109
  var LOWER_IS_BETTER = /* @__PURE__ */ new Set(["l2"]);
@@ -191,6 +1119,14 @@ function scorePercent(v, kind, max = 1) {
191
1119
  const pct = scoreHigherIsBetter(kind) ? v / max * 100 : (1 - v / max) * 100;
192
1120
  return Math.max(0, Math.min(100, pct));
193
1121
  }
1122
+ var RUN_LABELS = {
1123
+ unstart: t("kbCore.runUnstarted"),
1124
+ queued: t("kbCore.runQueued"),
1125
+ running: t("kbCore.runRunning"),
1126
+ cancel: t("kbCore.runCancelled"),
1127
+ done: t("kbCore.runDone"),
1128
+ fail: t("kbCore.runFailed")
1129
+ };
194
1130
  function normalizeHit(raw) {
195
1131
  const score = typeof raw.score === "number" && Number.isFinite(raw.score) ? raw.score : null;
196
1132
  return {
@@ -218,8 +1154,19 @@ function normalizeRetrievalParams(raw) {
218
1154
  threshold: typeof r.threshold === "number" ? r.threshold : null
219
1155
  };
220
1156
  }
1157
+ var SPAN_LABELS = {
1158
+ retrieval: t("kbCore.stageRetrieval"),
1159
+ generation: t("kbCore.stageGeneration"),
1160
+ rerank: t("kbCore.stageRerank"),
1161
+ embed: t("kbCore.stageEmbed"),
1162
+ tool: t("kbCore.stageTool"),
1163
+ guard: t("kbCore.stageGuard"),
1164
+ chunk: t("kbCore.stageChunk"),
1165
+ query: t("kbCore.stageQuery"),
1166
+ agent: t("kbCore.stageAgent")
1167
+ };
221
1168
  function kbVisibilityLabel(v) {
222
- return v === "hidden" ? "\u4E0D\u53EF\u89C1" : v === "metadata" ? "\u4EC5\u5143\u6570\u636E" : v === "restricted" ? "\u53D7\u9650" : v === "summary" ? "\u4EC5\u6458\u8981" : "\u53EF\u89C1";
1169
+ return v === "hidden" ? t("kbCore.visHidden") : v === "metadata" ? t("kbCore.visMetadataOnly") : v === "restricted" ? t("common.restricted") : v === "summary" ? t("kbCore.visSummaryOnly") : t("kbCore.visVisible");
223
1170
  }
224
1171
  function normalizeIdentity(raw) {
225
1172
  const r = raw;
@@ -231,18 +1178,914 @@ function normalizeIdentity(raw) {
231
1178
  };
232
1179
  }
233
1180
 
234
- // src/behaviors/events.ts
235
- function emitIcen(source, type, detail) {
236
- return source.dispatchEvent(
237
- new CustomEvent(type, { detail, bubbles: true, composed: true, cancelable: true })
1181
+ // src/behaviors/input.ts
1182
+ var searchFields = /* @__PURE__ */ new WeakMap();
1183
+ function enhanceSearchField(input) {
1184
+ if (typeof document === "undefined" || !input.parentElement) return { refresh() {
1185
+ }, destroy() {
1186
+ } };
1187
+ const previous = searchFields.get(input);
1188
+ if (previous) return previous;
1189
+ const host = input.parentElement;
1190
+ const wasFocused = document.activeElement === input;
1191
+ const hadHostClass = host.classList.contains("icen-search-field");
1192
+ const hadInputClass = input.classList.contains("icen-search-input");
1193
+ const hadStandardClass = input.classList.contains("icen-input");
1194
+ const ownedWrap = !host.classList.contains("icen-input-wrap");
1195
+ const next = input.nextSibling;
1196
+ const wrap = ownedWrap ? document.createElement("div") : host;
1197
+ if (ownedWrap) {
1198
+ wrap.className = "icen-input-wrap icen-input-wrap--sm icen-input-wrap--search icen-control";
1199
+ host.insertBefore(wrap, input);
1200
+ wrap.append(input);
1201
+ }
1202
+ const leading = wrap.querySelector(".icen-input-leading") ? null : document.createElement("span");
1203
+ if (leading) {
1204
+ leading.className = "icen-input-leading";
1205
+ leading.append(createIcon("search"));
1206
+ wrap.prepend(leading);
1207
+ }
1208
+ host.classList.add("icen-search-field");
1209
+ input.classList.add("icen-search-input", "icen-input");
1210
+ const clear = document.createElement("button");
1211
+ clear.type = "button";
1212
+ clear.className = "icen-input-clear icen-search-clear";
1213
+ clear.append(createIcon("close"));
1214
+ wrap.append(clear);
1215
+ const ac = new AbortController();
1216
+ let disposed = false;
1217
+ const refresh = () => {
1218
+ if (disposed) return;
1219
+ clear.hidden = !input.value || input.disabled || input.readOnly;
1220
+ clear.setAttribute("aria-label", t("input.clearSearch"));
1221
+ };
1222
+ clear.addEventListener("pointerdown", (event) => event.preventDefault(), { signal: ac.signal });
1223
+ clear.addEventListener("click", () => {
1224
+ if (input.disabled || input.readOnly) return;
1225
+ input.value = "";
1226
+ input.dispatchEvent(new Event("input", { bubbles: true }));
1227
+ input.focus({ preventScroll: true });
1228
+ refresh();
1229
+ }, { signal: ac.signal });
1230
+ for (const event of ["input", "change", "focus"]) input.addEventListener(event, refresh, { signal: ac.signal });
1231
+ document.addEventListener("icen:locale-change", refresh, { signal: ac.signal });
1232
+ const observer = new MutationObserver(refresh);
1233
+ observer.observe(input, { attributes: true, attributeFilter: ["disabled", "readonly"] });
1234
+ refresh();
1235
+ if (wasFocused) input.focus({ preventScroll: true });
1236
+ const handle = { refresh, destroy() {
1237
+ if (disposed) return;
1238
+ disposed = true;
1239
+ observer.disconnect();
1240
+ ac.abort();
1241
+ clear.remove();
1242
+ leading?.remove();
1243
+ searchFields.delete(input);
1244
+ const focused = document.activeElement === input;
1245
+ if (ownedWrap) {
1246
+ host.insertBefore(input, next?.parentNode === host ? next : null);
1247
+ wrap.remove();
1248
+ }
1249
+ if (focused) input.focus({ preventScroll: true });
1250
+ if (!hadHostClass) host.classList.remove("icen-search-field");
1251
+ if (!hadInputClass) input.classList.remove("icen-search-input");
1252
+ if (!hadStandardClass) input.classList.remove("icen-input");
1253
+ } };
1254
+ searchFields.set(input, handle);
1255
+ return handle;
1256
+ }
1257
+
1258
+ // src/behaviors/popover.ts
1259
+ function revealPopoverItem(item, scrollport, opts = {}) {
1260
+ if (typeof document === "undefined") return;
1261
+ if (opts.focus) item.focus({ preventScroll: true });
1262
+ const rect = item.getBoundingClientRect(), bounds = scrollport.getBoundingClientRect();
1263
+ const style = getComputedStyle(scrollport);
1264
+ const inset = (value, extent) => {
1265
+ const amount = Number.parseFloat(value) || 0;
1266
+ return value.endsWith("%") ? amount * extent / 100 : amount;
1267
+ };
1268
+ if (opts.axis !== "inline") {
1269
+ const top = bounds.top + scrollport.clientTop + inset(style.scrollPaddingTop, scrollport.clientHeight);
1270
+ const bottom = bounds.top + scrollport.clientTop + scrollport.clientHeight - inset(style.scrollPaddingBottom, scrollport.clientHeight);
1271
+ if (rect.top < top) scrollport.scrollTop -= top - rect.top;
1272
+ else if (rect.bottom > bottom) scrollport.scrollTop += rect.bottom - bottom;
1273
+ }
1274
+ if (opts.axis === "inline" || opts.axis === "both") {
1275
+ const left = bounds.left + scrollport.clientLeft + inset(style.scrollPaddingLeft, scrollport.clientWidth);
1276
+ const right = bounds.left + scrollport.clientLeft + scrollport.clientWidth - inset(style.scrollPaddingRight, scrollport.clientWidth);
1277
+ if (rect.left < left) scrollport.scrollLeft -= left - rect.left;
1278
+ else if (rect.right > right) scrollport.scrollLeft += rect.right - right;
1279
+ }
1280
+ }
1281
+ var PANEL_SIZING_ATTRS = {
1282
+ width: "data-icen-panel-width",
1283
+ minWidth: "data-icen-panel-min",
1284
+ maxWidth: "data-icen-panel-max",
1285
+ minHeight: "data-icen-panel-min-height",
1286
+ maxHeight: "data-icen-panel-max-height"
1287
+ };
1288
+ function readPanelSizing(el) {
1289
+ const out = {};
1290
+ if (!el) return out;
1291
+ for (const key of Object.keys(PANEL_SIZING_ATTRS)) {
1292
+ const raw = el.getAttribute(PANEL_SIZING_ATTRS[key]);
1293
+ if (raw == null) continue;
1294
+ const n = Number(raw);
1295
+ if (Number.isFinite(n) && n > 0) out[key] = n;
1296
+ }
1297
+ return out;
1298
+ }
1299
+ function resolvePanelSizing(el, overrides) {
1300
+ const base = readPanelSizing(el);
1301
+ if (!overrides) return base;
1302
+ for (const key of Object.keys(overrides)) {
1303
+ const v = overrides[key];
1304
+ if (typeof v === "number" && Number.isFinite(v) && v > 0) base[key] = v;
1305
+ }
1306
+ return base;
1307
+ }
1308
+ var DEFAULT_MIN_WIDTH = 220;
1309
+ var DEFAULT_MAX_WIDTH = 420;
1310
+ var DEFAULT_MIN_HEIGHT = 120;
1311
+ var DEFAULT_MAX_HEIGHT = 420;
1312
+ function clamp(value, min, max) {
1313
+ if (max < min) return min;
1314
+ return Math.min(max, Math.max(min, value));
1315
+ }
1316
+ function chooseSide(preferredSide, availableTop, availableBottom, desiredHeight) {
1317
+ const preferredSpace = preferredSide === "top" ? availableTop : availableBottom;
1318
+ const oppositeSpace = preferredSide === "top" ? availableBottom : availableTop;
1319
+ if (preferredSpace >= desiredHeight) return preferredSide;
1320
+ if (oppositeSpace >= desiredHeight) return preferredSide === "top" ? "bottom" : "top";
1321
+ if (preferredSpace >= oppositeSpace) return preferredSide;
1322
+ return preferredSide === "top" ? "bottom" : "top";
1323
+ }
1324
+ function horizontalAnchor(anchor, width, align) {
1325
+ if (align === "center") return anchor.left + anchor.width / 2 - width / 2;
1326
+ if (align === "end") return anchor.right - width;
1327
+ return anchor.left;
1328
+ }
1329
+ function computePopoverLayout(anchor, viewport, opts = {}) {
1330
+ const margin = opts.margin ?? 12;
1331
+ const offset = opts.offset ?? 8;
1332
+ const preferredSide = opts.side ?? "top";
1333
+ const align = opts.align ?? "start";
1334
+ if (preferredSide === "left" || preferredSide === "right") {
1335
+ const minWidth2 = Math.max(1, opts.minWidth ?? DEFAULT_MIN_WIDTH);
1336
+ const availableLeft = Math.max(0, anchor.left - margin - offset);
1337
+ const availableRight = Math.max(0, viewport.width - anchor.right - margin - offset);
1338
+ const side2 = (preferredSide === "left" ? availableLeft : availableRight) >= minWidth2 ? preferredSide : preferredSide === "left" ? "right" : "left";
1339
+ const maxWidth2 = Math.min(
1340
+ Math.max(opts.maxWidth ?? DEFAULT_MAX_WIDTH, minWidth2),
1341
+ side2 === "left" ? availableLeft : availableRight
1342
+ );
1343
+ const width2 = minWidth2;
1344
+ const left2 = clamp(
1345
+ side2 === "left" ? anchor.left - offset - width2 : anchor.right + offset,
1346
+ margin,
1347
+ viewport.width - margin - width2
1348
+ );
1349
+ const availableHeight2 = Math.max(80, viewport.height - margin * 2);
1350
+ const maxHeight2 = Math.min(opts.maxHeight ?? DEFAULT_MAX_HEIGHT, availableHeight2);
1351
+ const desired = clamp(opts.contentHeightHint ?? Math.min(anchor.height, maxHeight2), 40, maxHeight2);
1352
+ const anchorTop = align === "center" ? anchor.top + anchor.height / 2 - desired / 2 : align === "end" ? anchor.bottom - desired : anchor.top;
1353
+ const top2 = clamp(anchorTop, margin, viewport.height - margin - desired);
1354
+ return { side: side2, left: left2, top: top2, width: width2, maxHeight: maxHeight2 };
1355
+ }
1356
+ const availableWidth = Math.max(80, viewport.width - margin * 2);
1357
+ const requestedMinWidth = Math.max(1, opts.minWidth ?? DEFAULT_MIN_WIDTH);
1358
+ const requestedMaxWidth = Math.max(requestedMinWidth, opts.maxWidth ?? DEFAULT_MAX_WIDTH);
1359
+ const maxWidth = Math.min(requestedMaxWidth, availableWidth);
1360
+ const minWidth = Math.min(requestedMinWidth, maxWidth);
1361
+ const availableTop = Math.max(0, anchor.top - margin - offset);
1362
+ const availableBottom = Math.max(0, viewport.height - anchor.bottom - margin - offset);
1363
+ const availableHeight = Math.max(80, viewport.height - margin * 2);
1364
+ const minHeight = Math.min(Math.max(80, opts.minHeight ?? DEFAULT_MIN_HEIGHT), availableHeight);
1365
+ const requestedMaxHeight = Math.max(minHeight, opts.maxHeight ?? DEFAULT_MAX_HEIGHT);
1366
+ const fallbackHeight = Math.min(260, requestedMaxHeight);
1367
+ const contentHeight = opts.contentHeightHint != null && opts.contentHeightHint > 0 ? opts.contentHeightHint : fallbackHeight;
1368
+ const desiredHeight = clamp(contentHeight, minHeight, Math.min(requestedMaxHeight, availableHeight));
1369
+ const side = chooseSide(preferredSide, availableTop, availableBottom, desiredHeight);
1370
+ const sideSpace = side === "top" ? availableTop : availableBottom;
1371
+ const maxHeight = Math.min(
1372
+ requestedMaxHeight,
1373
+ Math.max(80, sideSpace || Math.max(availableTop, availableBottom)),
1374
+ availableHeight
238
1375
  );
1376
+ const positionedHeight = clamp(desiredHeight, 40, maxHeight);
1377
+ const width = align === "stretch" ? clamp(anchor.width, minWidth, maxWidth) : maxWidth;
1378
+ const left = clamp(horizontalAnchor(anchor, width, align), margin, viewport.width - margin - width);
1379
+ const desiredTop = side === "top" ? anchor.top - offset - positionedHeight : anchor.bottom + offset;
1380
+ const top = clamp(desiredTop, margin, viewport.height - margin - positionedHeight);
1381
+ return { side, left, top, width, maxHeight };
1382
+ }
1383
+
1384
+ // src/behaviors/select.ts
1385
+ var selectSequence = 0;
1386
+ var instances = /* @__PURE__ */ new Map();
1387
+ var openSelect = null;
1388
+ var globalBound = false;
1389
+ var PANEL_OFFSET = 4;
1390
+ var PANEL_MAX_HEIGHT = 240;
1391
+ function onGlobalPointerDown(ev) {
1392
+ const cur = openSelect;
1393
+ if (!cur) return;
1394
+ const t2 = ev.target;
1395
+ if (!(t2 instanceof Node)) return;
1396
+ if (cur.container.contains(t2) || cur.panel.contains(t2)) return;
1397
+ cur.close();
1398
+ }
1399
+ function onGlobalKeyDown(ev) {
1400
+ if (ev.key !== "Escape" || ev.isComposing) return;
1401
+ const cur = openSelect;
1402
+ if (!cur) return;
1403
+ cur.close();
1404
+ cur.trigger.focus();
1405
+ }
1406
+ function onWindowChange() {
1407
+ const cur = openSelect;
1408
+ if (!cur) return;
1409
+ if (!cur.trigger.isConnected) {
1410
+ cur.close();
1411
+ return;
1412
+ }
1413
+ cur.reposition();
1414
+ }
1415
+ function bindGlobalListeners() {
1416
+ if (globalBound) return;
1417
+ globalBound = true;
1418
+ document.addEventListener("pointerdown", onGlobalPointerDown);
1419
+ document.addEventListener("keydown", onGlobalKeyDown);
1420
+ }
1421
+ function bindOpenListeners() {
1422
+ window.addEventListener("scroll", onWindowChange, true);
1423
+ window.addEventListener("resize", onWindowChange);
1424
+ }
1425
+ function unbindOpenListeners() {
1426
+ window.removeEventListener("scroll", onWindowChange, true);
1427
+ window.removeEventListener("resize", onWindowChange);
1428
+ }
1429
+ function setup(container) {
1430
+ const el = container;
1431
+ const existing = instances.get(container);
1432
+ if (existing) return existing.dispose;
1433
+ const ac = new AbortController();
1434
+ const on = (t2, ev, fn) => {
1435
+ const listener = (evt) => fn(evt);
1436
+ t2.addEventListener(ev, listener, { signal: ac.signal });
1437
+ };
1438
+ const triggerEl = container.querySelector(".icen-select-trigger");
1439
+ const panelEl = container.querySelector(".icen-select-panel");
1440
+ const valueEl = container.querySelector(".icen-select-value");
1441
+ const hiddenInput = container.querySelector("input[data-icen-select-value], icen-input[data-icen-select-value]");
1442
+ if (!triggerEl || !panelEl) return () => {
1443
+ };
1444
+ el.__icenSelectInit = true;
1445
+ const trigger = triggerEl;
1446
+ const panel = panelEl;
1447
+ if (!trigger.querySelector(".icen-select-chevron")) {
1448
+ const chevron = createIcon("chevron-down", { size: 12, className: "icen-select-chevron" });
1449
+ if (chevron) {
1450
+ chevron.setAttribute("aria-hidden", "true");
1451
+ trigger.append(chevron);
1452
+ }
1453
+ }
1454
+ const isMultiple = container.hasAttribute("data-icen-select-multiple");
1455
+ const isSearchable = container.hasAttribute("data-icen-select-search");
1456
+ if (isMultiple && !trigger.hasAttribute("aria-label") && !trigger.hasAttribute("aria-labelledby")) trigger.setAttribute("aria-label", container.getAttribute("data-icen-select-label") ?? t("select.fieldLabel"));
1457
+ const maxSelect = Number(container.getAttribute("data-icen-select-max")) || 0;
1458
+ const panelSizing = resolvePanelSizing(container);
1459
+ function resolvedPanelWidth(triggerWidth) {
1460
+ let w = triggerWidth;
1461
+ if (panelSizing.minWidth != null) w = Math.max(w, panelSizing.minWidth);
1462
+ if (panelSizing.maxWidth != null) w = Math.min(w, panelSizing.maxWidth);
1463
+ if (panelSizing.width != null) w = panelSizing.width;
1464
+ return w;
1465
+ }
1466
+ const placeholder = container.getAttribute("data-icen-select-placeholder") ?? (valueEl?.classList.contains("is-empty") ? valueEl?.textContent ?? "" : "");
1467
+ if (isMultiple) panel.setAttribute("data-icen-select-multiple", "");
1468
+ let searchInput = null;
1469
+ let focusIdx = -1;
1470
+ if (isSearchable && !panel.querySelector(".icen-select-search-input")) {
1471
+ const searchWrap = document.createElement("div");
1472
+ searchWrap.className = "icen-select-search";
1473
+ const input = document.createElement("input");
1474
+ input.className = "icen-select-search-input";
1475
+ input.type = "search";
1476
+ input.placeholder = t("select.searchPlaceholder");
1477
+ searchWrap.appendChild(input);
1478
+ panel.insertBefore(searchWrap, panel.firstChild);
1479
+ }
1480
+ searchInput = panel.querySelector(".icen-select-search-input");
1481
+ const searchField = searchInput ? enhanceSearchField(searchInput) : null;
1482
+ ac.signal.addEventListener("abort", () => searchField?.destroy(), { once: true });
1483
+ let list = panel.querySelector("[data-icen-select-options]");
1484
+ if (!list) {
1485
+ list = document.createElement("div");
1486
+ list.className = "icen-select-options";
1487
+ list.setAttribute("data-icen-select-options", "");
1488
+ for (const child of Array.from(panel.children)) {
1489
+ if (!child.matches(".icen-select-search,.icen-select-empty")) list.append(child);
1490
+ }
1491
+ panel.append(list);
1492
+ }
1493
+ const optionsList = list;
1494
+ const allOptions = () => Array.from(panel.querySelectorAll(".icen-select-option"));
1495
+ if (!allOptions().some((option) => option.classList.contains("is-selected"))) {
1496
+ const requested = (container.getAttribute("data-icen-value") ?? hiddenInput?.value ?? "").split(",").filter(Boolean);
1497
+ let matched = false;
1498
+ allOptions().forEach((option) => {
1499
+ const selected = requested.includes(option.getAttribute("data-icen-value") ?? "") && (isMultiple || !matched);
1500
+ if (selected) {
1501
+ option.classList.add("is-selected");
1502
+ matched = true;
1503
+ }
1504
+ });
1505
+ }
1506
+ const originalDisabled = /* @__PURE__ */ new WeakSet();
1507
+ const knownOptions = /* @__PURE__ */ new WeakSet();
1508
+ panel.id ||= `icen-select-list-${++selectSequence}`;
1509
+ optionsList.id ||= `${panel.id}-options`;
1510
+ if (panel.getAttribute("role") === "listbox") panel.removeAttribute("role");
1511
+ optionsList.setAttribute("role", "listbox");
1512
+ optionsList.setAttribute("aria-label", trigger.getAttribute("aria-label") ?? (placeholder || t("select.fieldLabel")));
1513
+ if (isMultiple) optionsList.setAttribute("aria-multiselectable", "true");
1514
+ trigger.setAttribute("aria-controls", optionsList.id);
1515
+ trigger.setAttribute("aria-haspopup", "listbox");
1516
+ searchInput?.setAttribute("aria-label", t("select.searchPlaceholder"));
1517
+ if (searchInput) {
1518
+ searchInput.setAttribute("role", "combobox");
1519
+ searchInput.setAttribute("aria-autocomplete", "list");
1520
+ searchInput.setAttribute("aria-controls", optionsList.id);
1521
+ searchInput.setAttribute("aria-expanded", "false");
1522
+ }
1523
+ function prepareOptions() {
1524
+ const atLimit = isMultiple && maxSelect > 0 && getSelectedValues().length >= maxSelect;
1525
+ allOptions().forEach((option) => {
1526
+ if (!option.hasAttribute("type")) option.type = "button";
1527
+ if (!knownOptions.has(option)) {
1528
+ knownOptions.add(option);
1529
+ if (!option.hasAttribute("data-icen-select-limit-disabled") && option.matches('.is-disabled,[aria-disabled="true"]')) originalDisabled.add(option);
1530
+ }
1531
+ option.id ||= `${optionsList.id}-option-${++selectSequence}`;
1532
+ const limited = atLimit && !option.classList.contains("is-selected");
1533
+ const authored = originalDisabled.has(option) || option.disabled || option.hasAttribute("data-icen-disabled");
1534
+ option.toggleAttribute("data-icen-select-limit-disabled", limited && !authored);
1535
+ option.classList.toggle("is-disabled", authored || limited);
1536
+ });
1537
+ panel.querySelectorAll(".icen-select-group").forEach((group) => {
1538
+ group.setAttribute("role", "group");
1539
+ const heading = group.querySelector(".icen-select-group-label");
1540
+ if (heading && !group.hasAttribute("aria-label") && !group.hasAttribute("aria-labelledby")) {
1541
+ heading.id ||= `${optionsList.id}-group-${++selectSequence}`;
1542
+ group.setAttribute("aria-labelledby", heading.id);
1543
+ }
1544
+ });
1545
+ }
1546
+ function syncOptionAria() {
1547
+ prepareOptions();
1548
+ allOptions().forEach((option) => {
1549
+ if (originalDisabled.has(option)) option.classList.add("is-disabled");
1550
+ option.setAttribute("role", "option");
1551
+ option.setAttribute("aria-selected", String(option.classList.contains("is-selected")));
1552
+ option.setAttribute("aria-disabled", String(option.classList.contains("is-disabled")));
1553
+ option.tabIndex = -1;
1554
+ });
1555
+ }
1556
+ syncOptionAria();
1557
+ const visibleOptions = () => allOptions().filter((o) => !o.hidden);
1558
+ const isOpen = () => !panel.hidden;
1559
+ function setFocus(idx, moveDomFocus = false) {
1560
+ const opts = visibleOptions();
1561
+ focusIdx = Math.max(-1, Math.min(idx, opts.length - 1));
1562
+ opts.forEach((o, i) => o.classList.toggle("is-focused", i === focusIdx));
1563
+ const cur = focusIdx >= 0 ? opts[focusIdx] : void 0;
1564
+ if (cur && searchInput) searchInput.setAttribute("aria-activedescendant", cur.id);
1565
+ else searchInput?.removeAttribute("aria-activedescendant");
1566
+ if (cur) revealPopoverItem(cur, panel, { focus: moveDomFocus });
1567
+ }
1568
+ function firstEnabled() {
1569
+ return visibleOptions().findIndex((o) => !o.classList.contains("is-disabled"));
1570
+ }
1571
+ function lastEnabled() {
1572
+ const opts = visibleOptions();
1573
+ for (let i = opts.length - 1; i >= 0; i--) if (!opts[i].classList.contains("is-disabled")) return i;
1574
+ return -1;
1575
+ }
1576
+ function leaveByTab() {
1577
+ closePanel();
1578
+ trigger.focus({ preventScroll: true });
1579
+ }
1580
+ function moveFocus(delta) {
1581
+ const opts = visibleOptions();
1582
+ if (opts.length === 0) return;
1583
+ if (!opts.some((option) => !option.classList.contains("is-disabled"))) {
1584
+ setFocus(-1);
1585
+ return;
1586
+ }
1587
+ let n = focusIdx < 0 && delta < 0 ? 0 : focusIdx;
1588
+ for (let guard = 0; guard < opts.length; guard++) {
1589
+ n = (n + delta + opts.length) % opts.length;
1590
+ const opt = opts[n];
1591
+ if (opt && !opt.classList.contains("is-disabled")) break;
1592
+ }
1593
+ setFocus(n, document.activeElement !== searchInput);
1594
+ }
1595
+ let emptyEl = panel.querySelector(".icen-select-empty");
1596
+ if (!emptyEl) {
1597
+ emptyEl = document.createElement("div");
1598
+ emptyEl.className = "icen-select-empty";
1599
+ emptyEl.textContent = t("select.noMatch");
1600
+ emptyEl.hidden = true;
1601
+ panel.appendChild(emptyEl);
1602
+ }
1603
+ function updateEmptyState() {
1604
+ const hasVisible = visibleOptions().length > 0;
1605
+ if (emptyEl) emptyEl.hidden = hasVisible;
1606
+ optionsList.hidden = !hasVisible;
1607
+ }
1608
+ emptyEl.setAttribute("role", "status");
1609
+ function filterOptions(query) {
1610
+ searchField?.refresh();
1611
+ const q = query.trim().toLowerCase();
1612
+ const groups = Array.from(panel.querySelectorAll(".icen-select-group"));
1613
+ for (const opt of allOptions()) {
1614
+ const text = (opt.textContent ?? "").toLowerCase();
1615
+ const kw = (opt.getAttribute("data-icen-keywords") ?? "").toLowerCase();
1616
+ opt.hidden = q !== "" && !text.includes(q) && !kw.includes(q);
1617
+ }
1618
+ for (const g of groups) {
1619
+ const hasVisible = Array.from(g.querySelectorAll(".icen-select-option")).some((o) => !o.hidden);
1620
+ g.hidden = !hasVisible;
1621
+ }
1622
+ updateEmptyState();
1623
+ setFocus(isOpen() ? firstEnabled() : -1);
1624
+ }
1625
+ if (searchInput) {
1626
+ on(searchInput, "input", (event) => {
1627
+ if (!event.isComposing) filterOptions(searchInput.value);
1628
+ });
1629
+ on(searchInput, "compositionend", () => filterOptions(searchInput.value));
1630
+ on(searchInput, "keydown", (ev) => {
1631
+ if (ev.isComposing || ev.keyCode === 229) return;
1632
+ if (ev.key === "Escape") {
1633
+ ev.preventDefault();
1634
+ ev.stopPropagation();
1635
+ if (searchInput.value) {
1636
+ searchInput.value = "";
1637
+ filterOptions("");
1638
+ } else {
1639
+ closePanel();
1640
+ trigger.focus({ preventScroll: true });
1641
+ }
1642
+ } else if (ev.key === "ArrowDown" || ev.key === "ArrowUp") {
1643
+ ev.preventDefault();
1644
+ moveFocus(ev.key === "ArrowDown" ? 1 : -1);
1645
+ } else if (ev.key === "Enter") {
1646
+ ev.preventDefault();
1647
+ const option = visibleOptions()[focusIdx];
1648
+ if (option) choose(option);
1649
+ } else if (ev.key === "Tab" && (ev.shiftKey || panel.querySelector(".icen-search-clear")?.hidden !== false)) leaveByTab();
1650
+ });
1651
+ }
1652
+ function positionPanel() {
1653
+ const rect = trigger.getBoundingClientRect();
1654
+ const panelWidth = resolvedPanelWidth(rect.width);
1655
+ const layout = computePopoverLayout(
1656
+ rect,
1657
+ { width: window.innerWidth, height: window.innerHeight },
1658
+ {
1659
+ side: "bottom",
1660
+ align: "stretch",
1661
+ offset: PANEL_OFFSET,
1662
+ minWidth: panelWidth,
1663
+ maxWidth: panelWidth,
1664
+ maxHeight: panelSizing.maxHeight ?? PANEL_MAX_HEIGHT,
1665
+ contentHeightHint: panel.scrollHeight
1666
+ }
1667
+ );
1668
+ panel.style.left = `${layout.left + window.scrollX}px`;
1669
+ panel.style.top = `${layout.top + window.scrollY}px`;
1670
+ panel.style.minWidth = `${layout.width}px`;
1671
+ panel.style.width = `${layout.width}px`;
1672
+ panel.style.maxHeight = `${layout.maxHeight}px`;
1673
+ panel.dataset.icenSide = layout.side;
1674
+ }
1675
+ function openPanel(edge) {
1676
+ if (isOpen() || trigger.disabled || container.matches('[data-icen-disabled],[aria-disabled="true"]')) return;
1677
+ openSelect?.close();
1678
+ if (panel.parentElement !== document.body) document.body.appendChild(panel);
1679
+ panel.hidden = false;
1680
+ container.classList.add("is-open");
1681
+ trigger.setAttribute("aria-expanded", "true");
1682
+ syncOptionAria();
1683
+ searchInput?.setAttribute("aria-expanded", "true");
1684
+ positionPanel();
1685
+ openSelect = { container, trigger, panel, close: closePanel, reposition: positionPanel };
1686
+ bindOpenListeners();
1687
+ if (searchInput) {
1688
+ searchInput.value = "";
1689
+ filterOptions("");
1690
+ searchInput.focus({ preventScroll: true });
1691
+ } else {
1692
+ const opts = visibleOptions();
1693
+ const sel = opts.findIndex((o) => o.classList.contains("is-selected") && !o.classList.contains("is-disabled"));
1694
+ setFocus(edge === "last" ? lastEnabled() : edge === "first" ? firstEnabled() : sel >= 0 ? sel : firstEnabled(), true);
1695
+ }
1696
+ }
1697
+ function closePanel() {
1698
+ if (!isOpen()) return;
1699
+ panel.hidden = true;
1700
+ container.classList.remove("is-open");
1701
+ trigger.setAttribute("aria-expanded", "false");
1702
+ searchInput?.setAttribute("aria-expanded", "false");
1703
+ setFocus(-1);
1704
+ if (openSelect?.panel === panel) openSelect = null;
1705
+ unbindOpenListeners();
1706
+ }
1707
+ function getSelectedValues() {
1708
+ return allOptions().filter((o) => o.classList.contains("is-selected")).map((o) => o.getAttribute("data-icen-value") ?? "");
1709
+ }
1710
+ let chipsClickBound = false;
1711
+ function updateMultiTrigger() {
1712
+ if (!valueEl) return;
1713
+ const selected = allOptions().filter((o) => o.classList.contains("is-selected"));
1714
+ let chipsEl = container.querySelector(".icen-select-chips");
1715
+ if (selected.length === 0) {
1716
+ valueEl.textContent = placeholder;
1717
+ valueEl.classList.add("is-empty");
1718
+ valueEl.hidden = false;
1719
+ if (chipsEl) {
1720
+ chipsEl.hidden = true;
1721
+ chipsEl.replaceChildren();
1722
+ }
1723
+ container.removeAttribute("data-icen-value");
1724
+ } else {
1725
+ valueEl.classList.remove("is-empty");
1726
+ valueEl.hidden = true;
1727
+ if (!chipsEl) {
1728
+ chipsEl = document.createElement("span");
1729
+ chipsEl.className = "icen-select-chips";
1730
+ trigger.insertAdjacentElement("afterend", chipsEl);
1731
+ }
1732
+ if (trigger.contains(chipsEl)) trigger.insertAdjacentElement("afterend", chipsEl);
1733
+ if (!chipsClickBound) {
1734
+ chipsClickBound = true;
1735
+ const chips = chipsEl;
1736
+ on(chips, "click", (event) => {
1737
+ const target = event.target instanceof Element ? event.target.closest(".icen-select-chip-x") : null;
1738
+ if (!target) {
1739
+ trigger.click();
1740
+ return;
1741
+ }
1742
+ if (target.disabled) return;
1743
+ event.preventDefault();
1744
+ event.stopPropagation();
1745
+ const buttons = Array.from(chips.querySelectorAll(".icen-select-chip-x"));
1746
+ const index = buttons.indexOf(target);
1747
+ const option = allOptions().find((option2) => option2.getAttribute("data-icen-value") === target.dataset.icenValue);
1748
+ if (!option) return;
1749
+ option.classList.remove("is-selected");
1750
+ updateMultiTrigger();
1751
+ syncHiddenInput();
1752
+ const remaining = chips.querySelectorAll(".icen-select-chip-x");
1753
+ (remaining[Math.min(index, remaining.length - 1)] ?? trigger).focus({ preventScroll: true });
1754
+ });
1755
+ }
1756
+ chipsEl.hidden = false;
1757
+ chipsEl.textContent = "";
1758
+ const maxLabel = Number(container.getAttribute("data-icen-select-max-label")) || 3;
1759
+ const shown = selected.slice(0, maxLabel);
1760
+ const rest = selected.length - shown.length;
1761
+ for (const o of shown) {
1762
+ const label = o.textContent ?? "";
1763
+ const chip = document.createElement("span");
1764
+ chip.className = "icen-select-chip";
1765
+ const lb = document.createElement("span");
1766
+ lb.textContent = label;
1767
+ chip.appendChild(lb);
1768
+ const x = document.createElement("button");
1769
+ x.type = "button";
1770
+ x.className = "icen-select-chip-x";
1771
+ x.dataset.icenValue = o.getAttribute("data-icen-value") ?? "";
1772
+ x.disabled = trigger.disabled || container.hasAttribute("data-icen-disabled") || container.getAttribute("aria-disabled") === "true";
1773
+ x.setAttribute("aria-label", t("select.remove", { p0: label }));
1774
+ x.append(createIcon("close", { size: 12 }));
1775
+ chip.appendChild(x);
1776
+ chipsEl.appendChild(chip);
1777
+ }
1778
+ if (rest > 0) {
1779
+ const more = document.createElement("span");
1780
+ more.className = "icen-select-chip icen-select-chip--more";
1781
+ more.textContent = `+${rest}`;
1782
+ chipsEl.appendChild(more);
1783
+ }
1784
+ container.setAttribute("data-icen-value", getSelectedValues().join(","));
1785
+ }
1786
+ if (clearBtn) clearBtn.hidden = selected.length === 0;
1787
+ syncOptionAria();
1788
+ }
1789
+ function syncHiddenInput() {
1790
+ syncOptionAria();
1791
+ const values = getSelectedValues();
1792
+ const label = allOptions().filter((o) => o.classList.contains("is-selected")).map((o) => (o.textContent ?? "").trim()).join(", ");
1793
+ if (hiddenInput) hiddenInput.value = isMultiple ? values.join(",") : values[0] ?? "";
1794
+ emitIcen(container, "icen:select-change", { value: values[0] ?? "", values, label });
1795
+ hiddenInput?.dispatchEvent(new Event("change", { bubbles: true }));
1796
+ }
1797
+ function choose(opt) {
1798
+ if (opt.classList.contains("is-disabled")) return;
1799
+ if (isMultiple) {
1800
+ opt.classList.toggle("is-selected");
1801
+ container.setAttribute(
1802
+ "data-icen-value",
1803
+ getSelectedValues().join(",")
1804
+ );
1805
+ updateMultiTrigger();
1806
+ syncHiddenInput();
1807
+ if (searchInput) searchInput.focus();
1808
+ else opt.focus();
1809
+ } else {
1810
+ allOptions().forEach((o) => o.classList.toggle("is-selected", o === opt));
1811
+ if (valueEl) {
1812
+ valueEl.textContent = opt.textContent ?? "";
1813
+ valueEl.classList.remove("is-empty");
1814
+ }
1815
+ const v = opt.getAttribute("data-icen-value") ?? "";
1816
+ container.setAttribute("data-icen-value", v);
1817
+ syncHiddenInput();
1818
+ closePanel();
1819
+ trigger.focus();
1820
+ }
1821
+ }
1822
+ const clearBtn = container.querySelector(".icen-select-clear");
1823
+ if (!trigger.hasAttribute("type")) trigger.type = "button";
1824
+ if (clearBtn instanceof HTMLButtonElement && !clearBtn.hasAttribute("type")) clearBtn.type = "button";
1825
+ if (clearBtn) {
1826
+ clearBtn.replaceChildren(createIcon("close"));
1827
+ clearBtn.classList.add("icen-icon-action");
1828
+ clearBtn.setAttribute("data-icen-reveal", "");
1829
+ }
1830
+ if (clearBtn && isMultiple) {
1831
+ on(clearBtn, "click", (ev) => {
1832
+ ev.stopPropagation();
1833
+ allOptions().forEach((o) => o.classList.remove("is-selected"));
1834
+ updateMultiTrigger();
1835
+ syncHiddenInput();
1836
+ trigger.focus({ preventScroll: true });
1837
+ });
1838
+ on(clearBtn, "pointerdown", (ev) => ev.stopPropagation());
1839
+ }
1840
+ on(trigger, "click", () => isOpen() ? closePanel() : openPanel());
1841
+ let typed = "";
1842
+ let typedAt = 0;
1843
+ function handleListKey(ev) {
1844
+ if (ev.isComposing || ev.keyCode === 229) return;
1845
+ if (!isOpen()) {
1846
+ if (["ArrowDown", "ArrowUp", "Enter", " ", "Home", "End"].includes(ev.key)) {
1847
+ ev.preventDefault();
1848
+ openPanel(ev.key === "End" || ev.key === "ArrowUp" ? "last" : ev.key === "Home" ? "first" : void 0);
1849
+ return;
1850
+ }
1851
+ }
1852
+ switch (ev.key) {
1853
+ case "ArrowDown":
1854
+ ev.preventDefault();
1855
+ moveFocus(1);
1856
+ break;
1857
+ case "ArrowUp":
1858
+ ev.preventDefault();
1859
+ moveFocus(-1);
1860
+ break;
1861
+ case "Home":
1862
+ ev.preventDefault();
1863
+ setFocus(firstEnabled(), true);
1864
+ break;
1865
+ case "End":
1866
+ ev.preventDefault();
1867
+ setFocus(lastEnabled(), true);
1868
+ break;
1869
+ case "Enter":
1870
+ case " ": {
1871
+ ev.preventDefault();
1872
+ const opt = visibleOptions()[focusIdx];
1873
+ if (opt) choose(opt);
1874
+ break;
1875
+ }
1876
+ case "Escape":
1877
+ ev.preventDefault();
1878
+ closePanel();
1879
+ trigger.focus({ preventScroll: true });
1880
+ break;
1881
+ case "Tab":
1882
+ if (isOpen()) leaveByTab();
1883
+ break;
1884
+ default: {
1885
+ if (isSearchable || ev.ctrlKey || ev.metaKey || ev.altKey || ev.key.length !== 1) return;
1886
+ ev.preventDefault();
1887
+ if (!isOpen()) openPanel();
1888
+ if (!isOpen()) return;
1889
+ const now = Date.now();
1890
+ typed = now - typedAt < 600 ? typed + ev.key : ev.key;
1891
+ typedAt = now;
1892
+ let query = typed.toLocaleLowerCase();
1893
+ if ([...query].every((character) => character === query[0])) {
1894
+ query = query[0];
1895
+ typed = query;
1896
+ }
1897
+ const opts = visibleOptions();
1898
+ const start = query.length === 1 ? focusIdx + 1 : Math.max(0, focusIdx);
1899
+ for (let step = 0; step < opts.length; step++) {
1900
+ const index = (start + step + opts.length) % opts.length;
1901
+ const option = opts[index];
1902
+ if (!option.classList.contains("is-disabled") && (option.textContent ?? "").trim().toLocaleLowerCase().startsWith(query)) {
1903
+ setFocus(index, true);
1904
+ break;
1905
+ }
1906
+ }
1907
+ }
1908
+ }
1909
+ }
1910
+ on(trigger, "keydown", handleListKey);
1911
+ on(panel, "click", (ev) => {
1912
+ const t2 = ev.target;
1913
+ if (!(t2 instanceof Element)) return;
1914
+ const opt = t2.closest(".icen-select-option");
1915
+ if (opt instanceof HTMLButtonElement && panel.contains(opt)) choose(opt);
1916
+ });
1917
+ on(panel, "keydown", (event) => {
1918
+ if (event.target === searchInput) return;
1919
+ if (event.target instanceof Element && event.target.closest(".icen-search-clear")) {
1920
+ if (event.key === "Tab" && !event.shiftKey) leaveByTab();
1921
+ return;
1922
+ }
1923
+ handleListKey(event);
1924
+ });
1925
+ on(panel, "mouseover", (ev) => {
1926
+ const t2 = ev.target;
1927
+ if (!(t2 instanceof Element)) return;
1928
+ const opt = t2.closest(".icen-select-option");
1929
+ if (!opt || opt.hidden) return;
1930
+ const idx = visibleOptions().indexOf(opt);
1931
+ if (idx >= 0 && !opt.classList.contains("is-disabled")) setFocus(idx);
1932
+ });
1933
+ function refresh() {
1934
+ for (const child of Array.from(panel.children)) {
1935
+ if (child.matches(".icen-select-option,.icen-select-group")) optionsList.append(child);
1936
+ }
1937
+ const focusedRemove = container.querySelector(".icen-select-chip-x:focus")?.dataset.icenValue;
1938
+ syncOptionAria();
1939
+ if (isMultiple) updateMultiTrigger();
1940
+ else {
1941
+ const selected = allOptions().find((option) => option.classList.contains("is-selected"));
1942
+ if (valueEl) {
1943
+ valueEl.textContent = selected?.textContent ?? (placeholder || t("select.fieldLabel"));
1944
+ valueEl.classList.toggle("is-empty", !selected);
1945
+ }
1946
+ if (selected) container.setAttribute("data-icen-value", selected.getAttribute("data-icen-value") ?? "");
1947
+ else container.removeAttribute("data-icen-value");
1948
+ }
1949
+ if (hiddenInput) hiddenInput.value = isMultiple ? getSelectedValues().join(",") : getSelectedValues()[0] ?? "";
1950
+ if (searchInput) filterOptions(searchInput.value);
1951
+ else updateEmptyState();
1952
+ if (focusedRemove != null) {
1953
+ const next = Array.from(container.querySelectorAll(".icen-select-chip-x")).find((button) => button.dataset.icenValue === focusedRemove);
1954
+ (next ?? trigger).focus({ preventScroll: true });
1955
+ }
1956
+ if (isOpen()) positionPanel();
1957
+ }
1958
+ refresh();
1959
+ let disposed = false;
1960
+ let refreshPending = false;
1961
+ const observer = new MutationObserver(() => {
1962
+ if (refreshPending) return;
1963
+ refreshPending = true;
1964
+ queueMicrotask(() => {
1965
+ refreshPending = false;
1966
+ if (!disposed) refresh();
1967
+ });
1968
+ });
1969
+ observer.observe(panel, { childList: true, subtree: true, characterData: true, attributes: true, attributeFilter: ["disabled", "data-icen-disabled", "data-icen-value", "data-icen-keywords"] });
1970
+ const dispose = () => {
1971
+ if (disposed) return;
1972
+ disposed = true;
1973
+ observer.disconnect();
1974
+ if (openSelect?.panel === panel) closePanel();
1975
+ if (panel.parentElement === document.body) container.appendChild(panel);
1976
+ ac.abort();
1977
+ allOptions().forEach((option) => {
1978
+ option.removeAttribute("data-icen-select-limit-disabled");
1979
+ option.classList.toggle("is-disabled", originalDisabled.has(option));
1980
+ if (!originalDisabled.has(option)) option.removeAttribute("aria-disabled");
1981
+ });
1982
+ el.__icenSelectInit = false;
1983
+ instances.delete(container);
1984
+ activeSetups.delete(dispose);
1985
+ if (!activeSetups.size && globalBound) {
1986
+ document.removeEventListener("pointerdown", onGlobalPointerDown);
1987
+ document.removeEventListener("keydown", onGlobalKeyDown);
1988
+ globalBound = false;
1989
+ }
1990
+ };
1991
+ instances.set(container, { dispose, refresh, wasConnected: container.isConnected });
1992
+ return dispose;
1993
+ }
1994
+ var activeSetups = /* @__PURE__ */ new Set();
1995
+ function initSelect(root) {
1996
+ if (typeof document === "undefined") return () => {
1997
+ };
1998
+ const scope = root ?? document;
1999
+ for (const [container, instance] of instances) {
2000
+ if (container.isConnected) instance.wasConnected = true;
2001
+ else if (instance.wasConnected) instance.dispose();
2002
+ }
2003
+ const containers = [];
2004
+ if (scope instanceof Element && scope.matches("[data-icen-select]")) containers.push(scope);
2005
+ containers.push(...Array.from(scope.querySelectorAll("[data-icen-select]")));
2006
+ const disposers = [];
2007
+ for (const c of containers) {
2008
+ const dispose = setup(c);
2009
+ if (!instances.has(c)) continue;
2010
+ activeSetups.add(dispose);
2011
+ disposers.push(dispose);
2012
+ }
2013
+ if (disposers.length) bindGlobalListeners();
2014
+ return () => {
2015
+ for (const d of disposers) {
2016
+ d();
2017
+ activeSetups.delete(d);
2018
+ }
2019
+ if (activeSetups.size === 0 && globalBound) {
2020
+ document.removeEventListener("pointerdown", onGlobalPointerDown);
2021
+ document.removeEventListener("keydown", onGlobalKeyDown);
2022
+ globalBound = false;
2023
+ }
2024
+ };
2025
+ }
2026
+ function refreshSelect(root) {
2027
+ if (typeof document === "undefined") return;
2028
+ const scope = root ?? document;
2029
+ for (const [container, instance] of instances) {
2030
+ if (scope === container || scope instanceof Node && scope.contains(container)) instance.refresh();
2031
+ }
2032
+ }
2033
+
2034
+ // src/behaviors/kb-select.ts
2035
+ function kbSelect(cfg) {
2036
+ if (typeof document === "undefined") {
2037
+ return { el: null, getValue: () => "", setValue: () => void 0, setDisabled: () => void 0 };
2038
+ }
2039
+ const initial = cfg.options.some((o) => o.value === (cfg.value ?? "")) ? cfg.value : "";
2040
+ const labelOf = (v) => cfg.options.find((o) => o.value === v)?.label ?? "";
2041
+ const box = h("div", `icen-select${cfg.cls ? ` ${cfg.cls}` : ""}`);
2042
+ box.setAttribute("data-icen-select", "");
2043
+ box.setAttribute("data-icen-panel-min", String(cfg.panelMin ?? 96));
2044
+ if (cfg.panelWidth != null) box.setAttribute("data-icen-panel-width", String(cfg.panelWidth));
2045
+ const trigger = h("button", `icen-select-trigger icen-pressable icen-focus-ring${cfg.sm ? " icen-select-trigger--sm" : ""}`);
2046
+ trigger.type = "button";
2047
+ trigger.setAttribute("aria-haspopup", "listbox");
2048
+ trigger.setAttribute("aria-expanded", "false");
2049
+ if (cfg.ariaLabel) trigger.setAttribute("aria-label", cfg.ariaLabel);
2050
+ trigger.appendChild(h("span", `icen-select-value${initial ? "" : " is-empty"}`, labelOf(initial)));
2051
+ const panel = h("div", "icen-select-panel");
2052
+ panel.hidden = true;
2053
+ for (const o of cfg.options) {
2054
+ const opt = h("button", "icen-select-option", o.label);
2055
+ opt.type = "button";
2056
+ opt.setAttribute("data-icen-value", o.value);
2057
+ panel.appendChild(opt);
2058
+ }
2059
+ const hidden = document.createElement("input");
2060
+ hidden.type = "hidden";
2061
+ hidden.setAttribute("data-icen-select-value", "");
2062
+ hidden.value = initial;
2063
+ box.append(trigger, panel, hidden);
2064
+ initSelect(box);
2065
+ if (cfg.onChange) box.addEventListener("icen:select-change", (ev) => cfg.onChange(ev.detail.value));
2066
+ return {
2067
+ el: box,
2068
+ getValue: () => hidden.value,
2069
+ setValue(value) {
2070
+ const v = cfg.options.some((o) => o.value === value) ? value : "";
2071
+ for (const opt of Array.from(box.querySelectorAll(".icen-select-option"))) {
2072
+ opt.classList.toggle("is-selected", opt.getAttribute("data-icen-value") === v);
2073
+ }
2074
+ refreshSelect(box);
2075
+ },
2076
+ setDisabled(disabled) {
2077
+ trigger.disabled = disabled;
2078
+ if (disabled) box.setAttribute("aria-disabled", "true");
2079
+ else box.removeAttribute("aria-disabled");
2080
+ }
2081
+ };
239
2082
  }
240
2083
 
241
2084
  // src/behaviors/kb-retrieval.ts
242
2085
  var MODES = [
243
- ["vector", "\u5411\u91CF"],
244
- ["keyword", "\u5173\u952E\u8BCD"],
245
- ["hybrid", "\u6DF7\u5408"]
2086
+ ["vector", t("kbRetrieval.modeVector")],
2087
+ ["keyword", t("kbRetrieval.modeKeyword")],
2088
+ ["hybrid", t("kbRetrieval.modeHybrid")]
246
2089
  ];
247
2090
  var TOP_K_MIN = 1;
248
2091
  var TOP_K_MAX = 50;
@@ -252,9 +2095,9 @@ var ICON_COPY = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stro
252
2095
  var LAYER_ORDER = ["pre", "post", "none"];
253
2096
  var LAYER_LABEL = { pre: "pre \u2713", post: "post \u26A0", none: "none \u2715" };
254
2097
  var LAYER_TITLE = {
255
- pre: "pre-filter\uFF1AACL \u5728\u68C0\u7D22\u6267\u884C\u4F53\u5185\u751F\u6548\u2014\u2014\u5B89\u5168\u57FA\u7EBF",
256
- post: "post-filter\uFF1A\u5206\u6570\u5DF2\u53EF\u89C2\u5BDF\u2014\u2014\u7F3A\u9677\u5C42\uFF0C\u4EC5\u6F14\u793A",
257
- none: "none\uFF1Afail-open\uFF0C\u65E0\u8EAB\u4EFD\u8FC7\u6EE4\u8FD4\u56DE\u5168\u90E8\u2014\u2014\u5371\u9669\uFF0C\u4EC5\u6F14\u793A"
2098
+ pre: t("kbRetrieval.layerPre"),
2099
+ post: t("kbRetrieval.layerPost"),
2100
+ none: t("kbRetrieval.layerNone")
258
2101
  };
259
2102
  var stubHandle = () => ({
260
2103
  getParams: () => normalizeRetrievalParams(),
@@ -279,11 +2122,11 @@ function tokenizeQuery(query) {
279
2122
  const seen = /* @__PURE__ */ new Set();
280
2123
  const out = [];
281
2124
  for (const raw of query.trim().split(/\s+/)) {
282
- const t = raw.trim();
283
- if (!t || seen.has(t)) continue;
284
- if (t.length < 2 && !/[\u4e00-\u9fff]/.test(t)) continue;
285
- seen.add(t);
286
- out.push(t);
2125
+ const t2 = raw.trim();
2126
+ if (!t2 || seen.has(t2)) continue;
2127
+ if (t2.length < 2 && !/[\u4e00-\u9fff]/.test(t2)) continue;
2128
+ seen.add(t2);
2129
+ out.push(t2);
287
2130
  if (out.length >= HIGHLIGHT_TERM_LIMIT) break;
288
2131
  }
289
2132
  return out;
@@ -309,7 +2152,7 @@ function highlightTerms(text, terms) {
309
2152
  }
310
2153
  if (m.index > last) next.push(document.createTextNode(seg.slice(last, m.index)));
311
2154
  const mark = document.createElement("mark");
312
- mark.dataset.hit = String(ti % 3);
2155
+ mark.dataset.icenHit = String(ti % 3);
313
2156
  mark.textContent = m[0];
314
2157
  next.push(mark);
315
2158
  last = m.index + m[0].length;
@@ -352,6 +2195,14 @@ function createKbRetrieval(el, opts = {}) {
352
2195
  let params = normalizeRetrievalParams(opts.params);
353
2196
  const thresholdMax = typeof opts.thresholdMax === "number" && opts.thresholdMax > 0 ? opts.thresholdMax : 1;
354
2197
  let hits = [];
2198
+ const scoreListMax = () => {
2199
+ let m = thresholdMax;
2200
+ for (const hit of hits) {
2201
+ const v = Math.abs(hit.score ?? 0);
2202
+ if (Number.isFinite(v) && v > m) m = v;
2203
+ }
2204
+ return m > 0 ? m : 1;
2205
+ };
355
2206
  let busy = false;
356
2207
  let destroyed = false;
357
2208
  let thresholdValue = params.threshold ?? 0;
@@ -359,115 +2210,117 @@ function createKbRetrieval(el, opts = {}) {
359
2210
  let layer = opts.layer === "post" || opts.layer === "none" ? opts.layer : "pre";
360
2211
  const idnList = (Array.isArray(opts.identities) ? opts.identities : []).map(normalizeIdentity).filter((i) => i.user || i.label);
361
2212
  const adminAcl = opts.admin === true && typeof opts.aclOf === "function" ? opts.aclOf : null;
362
- el.classList.add("kb-retrieval");
363
- el.dataset.kbRetrieval = "";
2213
+ el.classList.add("icen-kb-retrieval");
2214
+ el.dataset.icenKbRetrieval = "";
364
2215
  el.textContent = "";
365
- const bar = h("div", "kb-retrieval-bar");
366
- const queryInput = h("input", "kb-retrieval-query");
2216
+ const bar = h("div", "icen-kb-retrieval-bar");
2217
+ const queryInput = h("input", "icen-kb-retrieval-query");
367
2218
  queryInput.type = "text";
368
- queryInput.placeholder = "\u68C0\u7D22\u95EE\u9898\uFF0CEnter \u8FD0\u884C";
369
- queryInput.setAttribute("aria-label", "\u68C0\u7D22\u95EE\u9898");
370
- const modes = h("div", "kb-modes");
2219
+ queryInput.placeholder = t("kbRetrieval.queryPlaceholder");
2220
+ queryInput.setAttribute("aria-label", t("kbRetrieval.queryLabel"));
2221
+ const modes = h("div", "icen-kb-modes");
371
2222
  modes.role = "radiogroup";
372
- modes.setAttribute("aria-label", "\u68C0\u7D22\u6A21\u5F0F");
2223
+ modes.setAttribute("aria-label", t("kbRetrieval.modeLabel"));
373
2224
  const modeButtons = /* @__PURE__ */ new Map();
374
2225
  for (const [mode, label] of MODES) {
375
- const btn = h("button", "kb-mode-item", label);
2226
+ const btn = h("button", "icen-kb-mode-item", label);
376
2227
  btn.type = "button";
377
- btn.dataset.mode = mode;
2228
+ btn.dataset.icenMode = mode;
378
2229
  btn.role = "radio";
379
2230
  modes.appendChild(btn);
380
2231
  modeButtons.set(mode, btn);
381
2232
  }
382
- const topKDown = h("button", "kb-step-btn", "\u2212");
2233
+ const topKDown = h("button", "icen-kb-step-btn");
2234
+ topKDown.append(createIcon("minus"));
383
2235
  topKDown.type = "button";
384
- topKDown.dataset.step = "-1";
385
- topKDown.setAttribute("aria-label", "\u51CF\u5C11 topK");
386
- const topKValue = h("span", "kb-step-value kb-num");
387
- const topKUp = h("button", "kb-step-btn", "+");
2236
+ topKDown.dataset.icenStep = "-1";
2237
+ topKDown.setAttribute("aria-label", t("kbRetrieval.decreaseTopK"));
2238
+ const topKValue = h("span", "icen-kb-step-value icen-kb-num");
2239
+ const topKUp = h("button", "icen-kb-step-btn");
2240
+ topKUp.append(createIcon("plus"));
388
2241
  topKUp.type = "button";
389
- topKUp.dataset.step = "1";
390
- topKUp.setAttribute("aria-label", "\u589E\u52A0 topK");
391
- const step = h("div", "kb-step");
2242
+ topKUp.dataset.icenStep = "1";
2243
+ topKUp.setAttribute("aria-label", t("kbRetrieval.increaseTopK"));
2244
+ const step = h("div", "icen-kb-step");
392
2245
  step.append(topKDown, topKValue, topKUp);
393
- const stepLabel = h("span", "kb-step-label kb-meta", "topK");
2246
+ const stepLabel = h("span", "kb-step-label icen-kb-meta", "topK");
394
2247
  step.setAttribute("aria-label", "topK");
395
- const alphaEndL = h("span", "kb-alpha-end", "\u8BED\u4E49");
396
- alphaEndL.title = "\u8BED\u4E49\uFF1A\u8DE8\u8BED\u8A00/\u65E0\u7CBE\u786E\u8BCD";
397
- const alphaRange = h("input", "kb-range kb-alpha-range");
2248
+ const alphaEndL = h("span", "icen-kb-alpha-end", t("kbRetrieval.modeVector"));
2249
+ alphaEndL.title = t("kbRetrieval.vectorHint");
2250
+ const alphaRange = h("input", "icen-kb-range kb-alpha-range");
398
2251
  alphaRange.type = "range";
399
2252
  alphaRange.min = "0";
400
2253
  alphaRange.max = "1";
401
2254
  alphaRange.step = "0.05";
402
- alphaRange.setAttribute("aria-label", "\u6DF7\u5408\u6743\u91CD\uFF08\u5DE6\u8BED\u4E49\u53F3\u5173\u952E\u8BCD\uFF09");
403
- const alphaEndR = h("span", "kb-alpha-end", "\u5173\u952E\u8BCD");
404
- alphaEndR.title = "\u5173\u952E\u8BCD\uFF1A\u5927\u5E93\u5FEB\u901F\u7CBE\u786E";
405
- const alpha = h("div", "kb-alpha");
2255
+ alphaRange.setAttribute("aria-label", t("kbRetrieval.hybridWeight"));
2256
+ const alphaEndR = h("span", "icen-kb-alpha-end", t("kbRetrieval.modeKeyword"));
2257
+ alphaEndR.title = t("kbRetrieval.keywordHint");
2258
+ const alpha = h("div", "icen-kb-alpha");
406
2259
  alpha.append(alphaEndL, alphaRange, alphaEndR);
407
- const rerankSwitch = h("button", "kb-switch");
2260
+ const rerankSwitch = h("button", "icen-kb-switch");
408
2261
  rerankSwitch.type = "button";
409
2262
  rerankSwitch.role = "switch";
410
- rerankSwitch.setAttribute("aria-label", "\u91CD\u6392");
411
- const rerankText = h("span", "kb-toggle-label", "\u91CD\u6392");
412
- const rerankToggle = h("span", "kb-toggle");
2263
+ rerankSwitch.setAttribute("aria-label", t("kbRetrieval.rerankLabel"));
2264
+ const rerankText = h("span", "icen-kb-toggle-label", t("kbRetrieval.rerankLabel"));
2265
+ const rerankToggle = h("span", "icen-kb-toggle");
413
2266
  rerankToggle.append(rerankSwitch, rerankText);
414
- const thresholdRange = h("input", "kb-range kb-threshold-range");
2267
+ const thresholdRange = h("input", "icen-kb-range kb-threshold-range");
415
2268
  thresholdRange.type = "range";
416
2269
  thresholdRange.min = "0";
417
2270
  thresholdRange.max = "1";
418
2271
  thresholdRange.step = "0.05";
419
- thresholdRange.setAttribute("aria-label", "\u5206\u6570\u9608\u503C");
420
- const thresholdCount = h("span", "kb-threshold-count kb-meta");
421
- const threshold = h("div", "kb-threshold");
2272
+ thresholdRange.setAttribute("aria-label", t("kbRetrieval.thresholdLabel"));
2273
+ const thresholdCount = h("span", "icen-kb-threshold-count icen-kb-meta");
2274
+ const threshold = h("div", "icen-kb-threshold");
422
2275
  threshold.append(thresholdRange, thresholdCount);
423
- const runBtn = h("button", "kb-run", "\u8FD0\u884C");
2276
+ const runBtn = h("button", "icen-kb-run", t("common.run"));
424
2277
  runBtn.type = "button";
425
2278
  const runIcon = svgIcon(ICON_RUN);
426
2279
  if (runIcon) runBtn.prepend(runIcon);
427
2280
  let idnSelect = null;
428
2281
  let idnGroup = null;
429
2282
  if (idnList.length) {
430
- idnSelect = h("select", "kb-retrieval-idn");
431
- idnSelect.setAttribute("aria-label", "\u68C0\u7D22\u8EAB\u4EFD");
432
- for (const idn of idnList) {
433
- const opt = h("option", void 0, idn.label ?? idn.user);
434
- opt.value = idn.user;
435
- idnSelect.appendChild(opt);
436
- }
437
- idnGroup = h("span", "kb-retrieval-idn-group");
438
- idnGroup.append(h("span", "kb-meta", "\u8EAB\u4EFD"), idnSelect);
2283
+ idnSelect = kbSelect({
2284
+ cls: "icen-kb-retrieval-idn",
2285
+ sm: true,
2286
+ options: idnList.map((idn) => ({ value: idn.user, label: idn.label ?? idn.user })),
2287
+ value: idnList[0]?.user,
2288
+ ariaLabel: t("kbRetrieval.identityLabel")
2289
+ });
2290
+ idnGroup = h("span", "icen-kb-retrieval-idn-group");
2291
+ idnGroup.append(h("span", "icen-kb-meta", t("kbRetrieval.identityShort")), idnSelect.el);
439
2292
  }
440
- const layerChip = h("button", "kb-chip kb-layer-chip");
2293
+ const layerChip = h("button", "icen-kb-chip icen-kb-layer-chip");
441
2294
  layerChip.type = "button";
442
- layerChip.setAttribute("aria-label", "\u8FC7\u6EE4\u5C42");
2295
+ layerChip.setAttribute("aria-label", t("kbRetrieval.layerLabel"));
443
2296
  const paintLayer = () => {
444
- layerChip.dataset.layer = layer;
2297
+ layerChip.dataset.icenLayer = layer;
445
2298
  layerChip.textContent = LAYER_LABEL[layer];
446
2299
  layerChip.title = LAYER_TITLE[layer];
447
2300
  };
448
2301
  paintLayer();
449
- const adminBadge = adminAcl ? h("span", "kb-badge kb-badge--admin", "admin") : null;
2302
+ const adminBadge = adminAcl ? h("span", "icen-kb-badge icen-kb-badge--admin", "admin") : null;
450
2303
  bar.append(queryInput, modes, stepLabel, step, alpha, rerankToggle, threshold);
451
2304
  if (idnGroup) bar.appendChild(idnGroup);
452
2305
  bar.append(runBtn, layerChip);
453
2306
  if (adminBadge) bar.appendChild(adminBadge);
454
- const paramsText = h("code", "kb-params-text kb-meta");
455
- const paramsCopy = h("button", "kb-params-copy");
2307
+ const paramsText = h("code", "icen-kb-params-text icen-kb-meta");
2308
+ const paramsCopy = h("button", "icen-kb-params-copy");
456
2309
  paramsCopy.type = "button";
457
- paramsCopy.title = "\u590D\u5236\u53C2\u6570 JSON";
458
- paramsCopy.setAttribute("aria-label", "\u590D\u5236\u53C2\u6570 JSON");
2310
+ paramsCopy.title = t("kbRetrieval.copyParams");
2311
+ paramsCopy.setAttribute("aria-label", t("kbRetrieval.copyParams"));
459
2312
  const copyIcon = svgIcon(ICON_COPY);
460
2313
  if (copyIcon) paramsCopy.appendChild(copyIcon);
461
- const paramsRow = h("div", "kb-params");
2314
+ const paramsRow = h("div", "icen-kb-params");
462
2315
  paramsRow.append(paramsCopy, paramsText);
463
- const layerNotice = h("div", "kb-notice");
2316
+ const layerNotice = h("div", "icen-kb-notice");
464
2317
  layerNotice.hidden = true;
465
2318
  const paintLayerNotice = () => {
466
2319
  if (layer === "none") {
467
- layerNotice.textContent = "fail-open\uFF1A\u5F53\u524D\u67E5\u8BE2\u672A\u643A\u5E26\u8EAB\u4EFD\u8FC7\u6EE4\uFF0C\u5C06\u8FD4\u56DE\u5168\u90E8\u5019\u9009\uFF08\u4EC5\u9650\u8C03\u8BD5\uFF09";
2320
+ layerNotice.textContent = t("kbRetrieval.failOpenNotice");
468
2321
  layerNotice.hidden = false;
469
2322
  } else if (layer === "post") {
470
- layerNotice.textContent = "post-filter\uFF1A\u5206\u6570\u5DF2\u5728\u8FC7\u6EE4\u524D\u4EA7\u751F\uFF08\u7F3A\u9677\u5C42\u6F14\u793A\uFF09";
2323
+ layerNotice.textContent = t("kbRetrieval.postFilterNotice");
471
2324
  layerNotice.hidden = false;
472
2325
  } else {
473
2326
  layerNotice.textContent = "";
@@ -475,7 +2328,7 @@ function createKbRetrieval(el, opts = {}) {
475
2328
  }
476
2329
  };
477
2330
  paintLayerNotice();
478
- const hitsBox = h("div", "kb-hits");
2331
+ const hitsBox = h("div", "icen-kb-hits");
479
2332
  el.append(bar, layerNotice, paramsRow, hitsBox);
480
2333
  function currentQueryText() {
481
2334
  return queryInput.value.trim();
@@ -497,7 +2350,7 @@ function createKbRetrieval(el, opts = {}) {
497
2350
  const alphaOn = params.mode === "hybrid";
498
2351
  alphaRange.disabled = !alphaOn;
499
2352
  alphaRange.value = String(params.alpha ?? 0.5);
500
- alphaEndL.textContent = `\u8BED\u4E49 ${(params.alpha ?? 0.5).toFixed(2)}`;
2353
+ alphaEndL.textContent = t("kbRetrieval.vectorPercent", { p0: (params.alpha ?? 0.5).toFixed(2) });
501
2354
  alpha.classList.toggle("is-off", !alphaOn);
502
2355
  rerankSwitch.setAttribute("aria-checked", params.rerank ? "true" : "false");
503
2356
  thresholdRange.disabled = !params.rerank;
@@ -505,22 +2358,22 @@ function createKbRetrieval(el, opts = {}) {
505
2358
  threshold.classList.toggle("is-off", !params.rerank);
506
2359
  }
507
2360
  function updateSurvival() {
508
- thresholdCount.title = "\u5206\u6BCD\u672A\u8FC7\u6EE4\u524D\u8BA1\u6570\u5C5E\u6CC4\u9732\uFF0C\u4E0D\u663E\u793A";
2361
+ thresholdCount.title = t("kbRetrieval.leakNote");
509
2362
  if (!params.rerank) {
510
- thresholdCount.textContent = "\u9608\u503C N/A";
2363
+ thresholdCount.textContent = t("kbRetrieval.thresholdValue");
511
2364
  return;
512
2365
  }
513
- const t = thresholdValue;
514
- if (!(t > 0)) {
515
- thresholdCount.textContent = `\u9608\u503C \u5173 \xB7 \u5B58\u6D3B ${hits.length}`;
2366
+ const t2 = thresholdValue;
2367
+ if (!(t2 > 0)) {
2368
+ thresholdCount.textContent = t("kbRetrieval.rerankThresholdOff", { p0: hits.length });
516
2369
  return;
517
2370
  }
518
2371
  let alive = 0;
519
2372
  for (const hit of hits) {
520
- const pct = scorePercent(hit.score, hit.scoreKind, thresholdMax);
521
- if (pct != null && pct >= t * 100 - 1e-9) alive++;
2373
+ const pct = scorePercent(hit.score, hit.scoreKind, scoreListMax());
2374
+ if (pct != null && pct >= t2 * 100 - 1e-9) alive++;
522
2375
  }
523
- thresholdCount.textContent = `\u9608\u503C ${t.toFixed(2)} \xB7 \u5B58\u6D3B ${alive}`;
2376
+ thresholdCount.textContent = t("kbRetrieval.rerankThresholdOn", { p0: t2.toFixed(2), p1: alive });
524
2377
  }
525
2378
  function updateParamsLine() {
526
2379
  const q = buildQueryObject();
@@ -532,72 +2385,72 @@ function createKbRetrieval(el, opts = {}) {
532
2385
  updateSurvival();
533
2386
  }
534
2387
  function renderScoreSide(hit, side) {
535
- const score = h("span", "kb-score");
536
- const pct = scorePercent(hit.score, hit.scoreKind, thresholdMax);
2388
+ const score = h("span", "icen-kb-score");
2389
+ const pct = scorePercent(hit.score, hit.scoreKind, scoreListMax());
537
2390
  if (pct != null) {
538
- const barEl = h("span", "kb-score-bar");
2391
+ const barEl = h("span", "icen-kb-score-bar");
539
2392
  const fill = h("i");
540
2393
  fill.style.width = `${pct.toFixed(1)}%`;
541
2394
  barEl.appendChild(fill);
542
2395
  score.appendChild(barEl);
543
2396
  }
544
- const value = h("span", "kb-score-value", formatScore(hit.score));
2397
+ const value = h("span", "icen-kb-score-value", formatScore(hit.score));
545
2398
  score.appendChild(value);
546
2399
  side.appendChild(score);
547
- const kind = h("span", "kb-chip kb-chip--kind", hit.scoreKind ?? "\u672A\u6807");
2400
+ const kind = h("span", "icen-kb-chip icen-kb-chip--kind", hit.scoreKind ?? t("kbRerank.unmarked"));
548
2401
  side.appendChild(kind);
549
2402
  if (hit.vectorPart != null && hit.keywordPart != null) {
550
- const dual = h("span", "kb-score-dual");
551
- const vec = h("i", "kb-score-dual-vec");
552
- const kw = h("i", "kb-score-dual-kw");
2403
+ const dual = h("span", "icen-kb-score-dual");
2404
+ const vec = h("i", "icen-kb-score-dual-vec");
2405
+ const kw = h("i", "icen-kb-score-dual-kw");
553
2406
  const sum2 = hit.vectorPart + hit.keywordPart;
554
2407
  const vecPct = sum2 > 0 ? hit.vectorPart / sum2 * 100 : 50;
555
2408
  vec.style.width = `${Math.max(0, Math.min(100, vecPct)).toFixed(1)}%`;
556
2409
  kw.style.flex = "1 1 auto";
557
2410
  dual.append(vec, kw);
558
- dual.title = `\u5411\u91CF ${vecPct.toFixed(0)}% / \u5173\u952E\u8BCD ${(100 - vecPct).toFixed(0)}%`;
2411
+ dual.title = t("kbRetrieval.weightValue", { p0: vecPct.toFixed(0), p1: (100 - vecPct).toFixed(0) });
559
2412
  side.appendChild(dual);
560
2413
  }
561
2414
  if (hit.explain) {
562
- const fold = h("div", "kb-hit-explain-fold");
563
- const toggle = h("button", "kb-hit-explain-toggle", "\u62C6\u89E3");
2415
+ const fold = h("div", "icen-kb-hit-explain-fold");
2416
+ const toggle = h("button", "icen-kb-hit-explain-toggle", t("kbRetrieval.breakdown"));
564
2417
  toggle.type = "button";
565
2418
  toggle.setAttribute("aria-expanded", "false");
566
- const body = h("div", "kb-hit-explain kb-meta", hit.explain);
2419
+ const body = h("div", "icen-kb-hit-explain icen-kb-meta", hit.explain);
567
2420
  body.hidden = true;
568
2421
  fold.append(toggle, body);
569
2422
  side.appendChild(fold);
570
2423
  }
571
2424
  }
572
2425
  function renderMetaChips(hit, box) {
573
- if (hit.page != null) box.appendChild(h("span", "kb-chip", `\u7B2C ${hit.page} \u9875`));
574
- if (hit.documentId) box.appendChild(h("span", "kb-chip", hit.documentId));
2426
+ if (hit.page != null) box.appendChild(h("span", "icen-kb-chip", t("common.page", { p0: hit.page })));
2427
+ if (hit.documentId) box.appendChild(h("span", "icen-kb-chip", hit.documentId));
575
2428
  if (hit.meta) {
576
2429
  for (const [k, v] of Object.entries(hit.meta).slice(0, 4)) {
577
- box.appendChild(h("span", "kb-chip", `${k}: ${String(v)}`));
2430
+ box.appendChild(h("span", "icen-kb-chip", `${k}: ${String(v)}`));
578
2431
  }
579
2432
  }
580
2433
  }
581
2434
  function renderHitRow(hit, index) {
582
- const row = h("div", "kb-hit");
583
- const rank = h("div", "kb-hit-rank kb-num", String(index + 1));
584
- const main = h("div", "kb-hit-main");
585
- const title = h("div", "kb-hit-title", hit.title ?? hit.documentId ?? hit.chunkId);
586
- const snippet = h("div", "kb-hit-snippet");
2435
+ const row = h("div", "icen-kb-hit");
2436
+ const rank = h("div", "icen-kb-hit-rank icen-kb-num", String(index + 1));
2437
+ const main = h("div", "icen-kb-hit-main");
2438
+ const title = h("div", "icen-kb-hit-title", hit.title ?? hit.documentId ?? hit.chunkId);
2439
+ const snippet = h("div", "icen-kb-hit-snippet");
587
2440
  for (const node of highlightTerms(hit.snippet ?? "", tokenizeQuery(currentQueryText()))) {
588
2441
  snippet.appendChild(node);
589
2442
  }
590
- const metaBox = h("div", "kb-hit-meta");
2443
+ const metaBox = h("div", "icen-kb-hit-meta");
591
2444
  renderMetaChips(hit, metaBox);
592
2445
  main.append(title, snippet, metaBox);
593
- const side = h("div", "kb-hit-side");
2446
+ const side = h("div", "icen-kb-hit-side");
594
2447
  renderScoreSide(hit, side);
595
- if (adminAcl) side.appendChild(h("span", "kb-chip", kbVisibilityLabel(adminAcl(hit))));
2448
+ if (adminAcl) side.appendChild(h("span", "icen-kb-chip", kbVisibilityLabel(adminAcl(hit))));
596
2449
  row.append(rank, main, side);
597
2450
  return row;
598
2451
  }
599
2452
  function renderEmpty() {
600
- const empty = h("div", "kb-empty", "\u8F93\u5165\u95EE\u9898\u5E76\u8FD0\u884C\uFF0C\u547D\u4E2D\u7ED3\u679C\u5C06\u51FA\u73B0\u5728\u8FD9\u91CC");
2453
+ const empty = h("div", "icen-kb-empty", t("kbRetrieval.empty"));
601
2454
  hitsBox.appendChild(empty);
602
2455
  }
603
2456
  function run() {
@@ -617,17 +2470,17 @@ function createKbRetrieval(el, opts = {}) {
617
2470
  }
618
2471
  });
619
2472
  listen(modes, "click", (ev) => {
620
- const btn = ev.target?.closest?.(".kb-mode-item");
2473
+ const btn = ev.target?.closest?.(".icen-kb-mode-item");
621
2474
  if (!(btn instanceof HTMLButtonElement) || btn.disabled) return;
622
- const mode = btn.dataset.mode;
2475
+ const mode = btn.dataset.icenMode;
623
2476
  if (!mode || mode === params.mode) return;
624
2477
  params = normalizeRetrievalParams({ ...params, mode });
625
2478
  refreshDerived();
626
2479
  });
627
2480
  listen(step, "click", (ev) => {
628
- const btn = ev.target?.closest?.(".kb-step-btn");
2481
+ const btn = ev.target?.closest?.(".icen-kb-step-btn");
629
2482
  if (!(btn instanceof HTMLButtonElement) || btn.disabled) return;
630
- const dir = Number(btn.dataset.step) || 0;
2483
+ const dir = Number(btn.dataset.icenStep) || 0;
631
2484
  if (!dir) return;
632
2485
  const next = Math.max(TOP_K_MIN, Math.min(TOP_K_MAX, params.topK + dir));
633
2486
  if (next === params.topK) return;
@@ -661,15 +2514,15 @@ function createKbRetrieval(el, opts = {}) {
661
2514
  });
662
2515
  if (idnSelect) {
663
2516
  const select = idnSelect;
664
- listen(select, "change", () => {
665
- const identity = idnList.find((i) => i.user === select.value);
2517
+ listen(select.el, "icen:select-change", (ev) => {
2518
+ const identity = idnList.find((i) => i.user === ev.detail.value);
666
2519
  if (identity) emitIcen(el, "icen:kb-visibility-identity", { identity });
667
2520
  });
668
2521
  }
669
2522
  listen(hitsBox, "click", (ev) => {
670
- const btn = ev.target?.closest?.(".kb-hit-explain-toggle");
2523
+ const btn = ev.target?.closest?.(".icen-kb-hit-explain-toggle");
671
2524
  if (!(btn instanceof HTMLButtonElement)) return;
672
- const body = btn.parentElement?.querySelector(".kb-hit-explain");
2525
+ const body = btn.parentElement?.querySelector(".icen-kb-hit-explain");
673
2526
  if (!body) return;
674
2527
  const open = body.hasAttribute("hidden");
675
2528
  body.toggleAttribute("hidden", !open);
@@ -680,12 +2533,12 @@ function createKbRetrieval(el, opts = {}) {
680
2533
  const ok = copyText(paramsText.textContent ?? "");
681
2534
  if (ok) {
682
2535
  paramsCopy.classList.add("is-copied");
683
- paramsCopy.title = "\u5DF2\u590D\u5236";
2536
+ paramsCopy.title = t("common.copied");
684
2537
  if (copyTimer) clearTimeout(copyTimer);
685
2538
  copyTimer = setTimeout(() => {
686
2539
  if (destroyed) return;
687
2540
  paramsCopy.classList.remove("is-copied");
688
- paramsCopy.title = "\u590D\u5236\u53C2\u6570 JSON";
2541
+ paramsCopy.title = t("kbRetrieval.copyParams");
689
2542
  }, 1200);
690
2543
  }
691
2544
  });
@@ -710,7 +2563,7 @@ function createKbRetrieval(el, opts = {}) {
710
2563
  el.classList.toggle("is-busy", busy);
711
2564
  runBtn.disabled = busy;
712
2565
  runBtn.setAttribute("aria-busy", busy ? "true" : "false");
713
- runBtn.textContent = busy ? "\u8FD0\u884C\u4E2D\u2026" : "\u8FD0\u884C";
2566
+ runBtn.textContent = busy ? t("kbRetrieval.running") : t("common.run");
714
2567
  if (!busy) {
715
2568
  const icon = svgIcon(ICON_RUN);
716
2569
  if (icon) runBtn.prepend(icon);
@@ -731,8 +2584,8 @@ function createKbRetrieval(el, opts = {}) {
731
2584
  destroyed = true;
732
2585
  ctrl.abort();
733
2586
  if (copyTimer) clearTimeout(copyTimer);
734
- el.classList.remove("kb-retrieval", "is-busy");
735
- delete el.dataset.kbRetrieval;
2587
+ el.classList.remove("icen-kb-retrieval", "is-busy");
2588
+ delete el.dataset.icenKbRetrieval;
736
2589
  el.textContent = "";
737
2590
  delete el.__icenKbRetrieval;
738
2591
  }