@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,12 +1,1182 @@
1
- // src/behaviors/notification.ts
2
- var KIND_ICON = {
3
- success: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><path d="m9 11 3 3L22 4"/></svg>',
4
- warning: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>',
5
- error: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="m15 9-6 6"/><path d="m9 9 6 6"/></svg>',
6
- info: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>'
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"
7
75
  };
8
- var CLOSE_SVG = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>';
9
- var PROGRESS_ICON = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/></svg>';
76
+ var custom = /* @__PURE__ */ new Map();
77
+ function iconPath(name) {
78
+ return Object.hasOwn(ICON_PATHS, name) ? ICON_PATHS[name] : custom.get(name) ?? null;
79
+ }
80
+ function iconAttributes(o = {}) {
81
+ const size = Number.isFinite(o.size) && o.size > 0 ? o.size : 16;
82
+ 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" } };
83
+ }
84
+ function createIcon(name, o = {}) {
85
+ if (typeof document === "undefined") return null;
86
+ const path = iconPath(name);
87
+ if (!path) return null;
88
+ const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
89
+ for (const [key, value] of Object.entries(iconAttributes(o))) svg.setAttribute(key, value);
90
+ const line = document.createElementNS(svg.namespaceURI, "path");
91
+ line.setAttribute("d", path);
92
+ svg.append(line);
93
+ return svg;
94
+ }
95
+
96
+ // src/behaviors/feedback.ts
97
+ function createFeedbackClock(el, state, expire, progress, pauseOnHover = () => true) {
98
+ if (typeof document === "undefined") return { pause() {
99
+ }, resume() {
100
+ }, reset() {
101
+ }, destroy() {
102
+ } };
103
+ const reasons = /* @__PURE__ */ new Set();
104
+ const ac = new AbortController();
105
+ let destroyed = false;
106
+ function sync(reset = false) {
107
+ state.paused = state.duration > 0 && reasons.size > 0;
108
+ el.classList.toggle("is-paused", state.paused);
109
+ const fill = el.querySelector(progress);
110
+ if (fill) {
111
+ if (reset) {
112
+ fill.style.animationName = "none";
113
+ void fill.offsetWidth;
114
+ fill.style.animationName = "";
115
+ fill.style.animationDuration = `${state.duration}ms`;
116
+ }
117
+ fill.style.animationPlayState = state.paused ? "paused" : "running";
118
+ }
119
+ }
120
+ function stop() {
121
+ if (!state.timer) return;
122
+ window.clearTimeout(state.timer);
123
+ state.timer = 0;
124
+ state.remaining = Math.max(0, state.remaining - (Date.now() - state.startedAt));
125
+ }
126
+ function start() {
127
+ if (destroyed || state.duration <= 0 || reasons.size || state.timer) return;
128
+ if (state.remaining <= 0) {
129
+ expire();
130
+ return;
131
+ }
132
+ state.startedAt = Date.now();
133
+ state.timer = window.setTimeout(() => {
134
+ state.timer = 0;
135
+ state.remaining = 0;
136
+ if (!destroyed) expire();
137
+ }, state.remaining);
138
+ }
139
+ const clock = {
140
+ pause(reason = "manual") {
141
+ if (destroyed) return;
142
+ reasons.add(reason);
143
+ stop();
144
+ sync();
145
+ },
146
+ resume(reason = "manual") {
147
+ if (destroyed) return;
148
+ reasons.delete(reason);
149
+ sync();
150
+ start();
151
+ },
152
+ reset(ms) {
153
+ if (destroyed) return;
154
+ stop();
155
+ state.duration = Number.isFinite(ms) ? Math.max(0, ms) : 0;
156
+ state.remaining = state.duration;
157
+ sync(true);
158
+ start();
159
+ },
160
+ destroy() {
161
+ if (destroyed) return;
162
+ destroyed = true;
163
+ stop();
164
+ reasons.clear();
165
+ ac.abort();
166
+ }
167
+ };
168
+ el.addEventListener("mouseenter", () => {
169
+ if (pauseOnHover()) clock.pause("hover");
170
+ }, { signal: ac.signal });
171
+ el.addEventListener("mouseleave", () => clock.resume("hover"), { signal: ac.signal });
172
+ el.addEventListener("focusin", () => clock.pause("focus"), { signal: ac.signal });
173
+ el.addEventListener("focusout", (event) => {
174
+ if (!(event.relatedTarget instanceof Node) || !el.contains(event.relatedTarget)) clock.resume("focus");
175
+ }, { signal: ac.signal });
176
+ const visibility = () => document.hidden ? clock.pause("visibility") : clock.resume("visibility");
177
+ document.addEventListener("visibilitychange", visibility, { signal: ac.signal });
178
+ if (document.hidden) reasons.add("visibility");
179
+ if (el.contains(document.activeElement)) reasons.add("focus");
180
+ clock.reset(state.duration);
181
+ return clock;
182
+ }
183
+ var pending = /* @__PURE__ */ new WeakMap();
184
+ function cancelFeedbackAction(card) {
185
+ pending.get(card)?.abort();
186
+ }
187
+ function runFeedbackAction(card, button, action, hooks) {
188
+ if (typeof document === "undefined") return;
189
+ if (pending.has(card) || card.classList.contains("is-leaving") || !card.isConnected) return;
190
+ const ac = new AbortController();
191
+ const controls = Array.from(card.querySelectorAll(".icen-toast-action,.icen-notification-action"));
192
+ const original = controls.map((item) => item.getAttribute("aria-disabled"));
193
+ let spinner = null;
194
+ let busy = false;
195
+ let signalled = false;
196
+ const restore = () => {
197
+ if (busy) {
198
+ busy = false;
199
+ controls.forEach((item, index) => original[index] == null ? item.removeAttribute("aria-disabled") : item.setAttribute("aria-disabled", original[index]));
200
+ button.removeAttribute("aria-busy");
201
+ spinner?.remove();
202
+ }
203
+ if (signalled) {
204
+ signalled = false;
205
+ hooks.busy(false);
206
+ }
207
+ };
208
+ const operation = { abort() {
209
+ ac.abort();
210
+ if (pending.get(card) === operation) {
211
+ pending.delete(card);
212
+ restore();
213
+ }
214
+ } };
215
+ pending.set(card, operation);
216
+ const finish = (result, error) => {
217
+ if (ac.signal.aborted || pending.get(card) !== operation) return;
218
+ pending.delete(card);
219
+ try {
220
+ if (card.isConnected && !card.classList.contains("is-leaving")) {
221
+ if (error !== void 0) hooks.error(error);
222
+ else hooks.complete(result !== false);
223
+ }
224
+ } finally {
225
+ restore();
226
+ }
227
+ };
228
+ try {
229
+ signalled = true;
230
+ hooks.busy(true);
231
+ const result = action(ac.signal);
232
+ if (result && typeof result.then === "function") {
233
+ busy = true;
234
+ controls.forEach((item) => item.setAttribute("aria-disabled", "true"));
235
+ button.setAttribute("aria-busy", "true");
236
+ let label = button.querySelector(".icen-feedback-action-label");
237
+ if (!label) {
238
+ label = document.createElement("span");
239
+ label.className = "icen-feedback-action-label";
240
+ while (button.firstChild) label.append(button.firstChild);
241
+ button.append(label);
242
+ }
243
+ spinner = document.createElement("span");
244
+ spinner.className = "icen-feedback-action-spinner";
245
+ spinner.setAttribute("aria-hidden", "true");
246
+ spinner.append(createIcon("spinner"));
247
+ button.append(spinner);
248
+ void Promise.resolve(result).then((value) => finish(value), (error) => finish(false, error ?? new Error("Action rejected")));
249
+ } else finish(result);
250
+ } catch (error) {
251
+ finish(false, error ?? new Error("Action failed"));
252
+ }
253
+ }
254
+ function setFeedbackError(host, message) {
255
+ if (typeof document === "undefined") return;
256
+ let error = host.querySelector(":scope > .icen-feedback-error");
257
+ if (!message) {
258
+ error?.remove();
259
+ return;
260
+ }
261
+ if (!error) {
262
+ error = document.createElement("span");
263
+ error.className = "icen-feedback-error";
264
+ error.setAttribute("role", "alert");
265
+ host.append(error);
266
+ }
267
+ setFeedbackText(error, message);
268
+ }
269
+ function setFeedbackText(host, value) {
270
+ if (typeof document === "undefined") return;
271
+ const text = document.createElement("bdi");
272
+ text.textContent = value;
273
+ host.replaceChildren(text);
274
+ }
275
+ var origins = /* @__PURE__ */ new WeakMap();
276
+ function rememberFeedbackOrigin(card) {
277
+ if (typeof document === "undefined") return;
278
+ const focused = document.activeElement instanceof HTMLElement ? document.activeElement : null;
279
+ const previous = focused?.closest(".icen-toast,.icen-notification");
280
+ const chain = [...focused ? [focused] : [], ...previous ? origins.get(previous) ?? [] : []];
281
+ origins.set(card, [...new Set(chain)].filter((item) => item.isConnected));
282
+ }
283
+ function restoreFeedbackFocus(card) {
284
+ if (typeof document === "undefined") return;
285
+ const origin = origins.get(card)?.find((item) => item.isConnected && !item.closest("[hidden],[inert],.is-leaving") && !item.matches(':disabled,[aria-disabled="true"]'));
286
+ if (card.contains(document.activeElement)) origin?.focus({ preventScroll: true });
287
+ }
288
+
289
+ // src/behaviors/i18n.ts
290
+ var ICEN_LOCALE_ZH_CN = {
291
+ /* ── aiBranch ── */
292
+ "aiBranch.nextVersion": "\u4E0B\u4E00\u7248\u672C",
293
+ "aiBranch.prevVersion": "\u4E0A\u4E00\u7248\u672C",
294
+ "aiBranch.version": "\u5206\u652F\u7248\u672C",
295
+ /* ── aiChat ── */
296
+ "aiChat.backToBottom": "\u56DE\u5230\u5E95\u90E8",
297
+ "aiChat.backToBottomCount": "\u56DE\u5230\u5E95\u90E8 \xB7 {p0} \u6761\u65B0\u6D88\u606F",
298
+ "aiChat.continue": "\u7EE7\u7EED\u751F\u6210",
299
+ "aiChat.download": "\u4E0B\u8F7D",
300
+ "aiChat.file": "\u6587\u4EF6",
301
+ "aiChat.roleSystem": "\u7CFB",
302
+ "aiChat.roleTool": "\u5DE5",
303
+ "aiChat.roleUser": "\u6211",
304
+ "aiChat.thinking": "\u601D\u8003 {p0}",
305
+ "aiChat.thinkingNow": "\u6B63\u5728\u601D\u8003\u2026",
306
+ /* ── aiComposer ── */
307
+ "aiComposer.attachAgent": "\u4EE3\u7406",
308
+ "aiComposer.library": "\u6DFB\u52A0\u4E0A\u4E0B\u6587\u4E0E\u547D\u4EE4",
309
+ "aiComposer.searchLibrary": "\u641C\u7D22\u6280\u80FD\u3001\u5DE5\u5177\u3001\u6587\u4EF6\u4E0E\u547D\u4EE4",
310
+ "aiComposer.all": "\u5168\u90E8",
311
+ "aiComposer.skills": "\u6280\u80FD",
312
+ "aiComposer.tools": "\u5DE5\u5177",
313
+ "aiComposer.libraryHint": "\u4E0A\u4E0B\u6587\u968F\u6D88\u606F\u53D1\u9001 \xB7 \u547D\u4EE4\u5148\u586B\u5165\u8F93\u5165\u6846",
314
+ "aiComposer.commandHint": "\u2191 \u2193 \u6D4F\u89C8 \xB7 Enter \u6267\u884C \xB7 Esc \u8FD4\u56DE",
315
+ "aiComposer.refHint": "\u2191 \u2193 \u6D4F\u89C8 \xB7 Enter \u5F15\u7528 \xB7 Esc \u8FD4\u56DE",
316
+ "aiComposer.noLibraryMatch": "\u6CA1\u6709\u5339\u914D\u7684\u9879\u76EE\uFF0C\u8BD5\u8BD5\u5176\u4ED6\u5173\u952E\u8BCD",
317
+ "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",
318
+ "aiComposer.attachDoc": "\u6587\u6863",
319
+ "aiComposer.attachFile": "\u6587\u4EF6",
320
+ "aiComposer.attachFolder": "\u6587\u4EF6\u5939",
321
+ "aiComposer.cacheInvalidHint": "\u5207\u6362\u6A21\u578B\u4F1A\u4F7F prompt \u7F13\u5B58\u5931\u6548",
322
+ "aiComposer.commands": "\u547D\u4EE4",
323
+ "aiComposer.currentTodos": "\u5F53\u524D\u5F85\u529E",
324
+ "aiComposer.done": "\u5B8C\u6210",
325
+ "aiComposer.justNow": "\u521A\u521A \xB7 {p0}",
326
+ "aiComposer.modelAria": "\u6A21\u578B {p0}\uFF08{p1}\uFF09",
327
+ "aiComposer.noCommandMatch": "\u65E0\u5339\u914D\u547D\u4EE4",
328
+ "aiComposer.noModelMatch": "\u65E0\u5339\u914D\u6A21\u578B",
329
+ "aiComposer.noRefMatch": "\u65E0\u5339\u914D\u5F15\u7528",
330
+ "aiComposer.placeholder": "\u8F93\u5165\u6D88\u606F\uFF0C/ \u547D\u4EE4 \xB7 @ \u5F15\u7528 \xB7 Enter \u53D1\u9001",
331
+ "aiComposer.refs": "\u5F15\u7528",
332
+ "aiComposer.removeAttachment": "\u79FB\u9664\u9644\u4EF6 {p0}",
333
+ "aiComposer.removeQueued": "\u79FB\u9664\u6392\u961F\u6D88\u606F {p0}",
334
+ "aiComposer.removeRef": "\u79FB\u9664\u5F15\u7528 {p0}",
335
+ "aiComposer.searchModels": "\u641C\u7D22\u6A21\u578B",
336
+ "aiComposer.selectModel": "\u9009\u62E9\u6A21\u578B",
337
+ "aiComposer.send": "\u53D1\u9001",
338
+ "aiComposer.stop": "\u505C\u6B62\u751F\u6210",
339
+ "aiComposer.stopped": "\u5DF2\u505C\u6B62",
340
+ "aiComposer.todoChip": "\u5F53\u524D\u5F85\u529E {p0}/{p1}{p2}",
341
+ "aiComposer.todoHasError": "\uFF08\u6709\u5931\u8D25\u9879\uFF09",
342
+ /* ── aiCore ── */
343
+ "aiCore.kindBrowser": "\u6D4F\u89C8",
344
+ "aiCore.kindChart": "\u56FE\u8868",
345
+ "aiCore.kindDelete": "\u5220\u9664",
346
+ "aiCore.kindEdit": "\u7F16\u8F91",
347
+ "aiCore.kindFetch": "\u8BF7\u6C42",
348
+ "aiCore.kindGlob": "\u5339\u914D",
349
+ "aiCore.kindGrep": "\u641C\u7D22",
350
+ "aiCore.kindNote": "\u7B14\u8BB0",
351
+ "aiCore.kindPlan": "\u8BA1\u5212",
352
+ "aiCore.kindRead": "\u8BFB\u53D6",
353
+ "aiCore.kindSearch": "\u68C0\u7D22",
354
+ "aiCore.kindShell": "\u547D\u4EE4",
355
+ "aiCore.kindSkill": "\u6280\u80FD",
356
+ "aiCore.kindSubagent": "\u5B50\u4EE3\u7406",
357
+ "aiCore.kindTodo": "\u5F85\u529E",
358
+ "aiCore.kindWrite": "\u5199\u5165",
359
+ "aiCore.statusApproval": "\u5F85\u786E\u8BA4",
360
+ "aiCore.statusCancelled": "\u5DF2\u53D6\u6D88",
361
+ "aiCore.statusDone": "\u5B8C\u6210",
362
+ "aiCore.statusError": "\u5931\u8D25",
363
+ "aiCore.statusPending": "\u7B49\u5F85",
364
+ "aiCore.statusRunning": "\u6267\u884C\u4E2D",
365
+ "aiCore.statusStreaming": "\u6D41\u5F0F\u4E2D",
366
+ "aiCore.todoProgress": "{p0}/{p1} \u5B8C\u6210",
367
+ /* ── aiDiff ── */
368
+ "aiDiff.accepted": "\u5DF2\u63A5\u53D7",
369
+ "aiDiff.binary": "\u4E8C\u8FDB\u5236\u6587\u4EF6\uFF0C\u65E0\u6CD5\u663E\u793A\u6587\u672C\u5DEE\u5F02",
370
+ "aiDiff.empty": "\u65E0\u5DEE\u5F02\u5185\u5BB9",
371
+ "aiDiff.rejected": "\u5DF2\u62D2\u7EDD",
372
+ /* ── aiFeedback ── */
373
+ "aiFeedback.helpful": "\u6709\u5E2E\u52A9",
374
+ "aiFeedback.notHelpful": "\u65E0\u5E2E\u52A9",
375
+ "aiFeedback.reasonCitationMismatch": "\u5F15\u7528\u4E0D\u7B26",
376
+ "aiFeedback.reasonOutdated": "\u5185\u5BB9\u8FC7\u65F6",
377
+ "aiFeedback.reasonUnauthorized": "\u8D8A\u6743\u4FE1\u606F",
378
+ "aiFeedback.reasonUnsourced": "\u65E0\u5F15\u7528\u4F9D\u636E",
379
+ "aiFeedback.reasonWrong": "\u7B54\u6848\u6709\u8BEF",
380
+ "aiFeedback.thanks": "\u611F\u8C22\u53CD\u9988\uFF0C\u5DF2\u5173\u8054\u5230\u8BE5\u6761\u56DE\u7B54\u7684\u8FFD\u8E2A\u8BB0\u5F55",
381
+ /* ── aiPanel ── */
382
+ "aiPanel.audit": "\u5BA1\u8BA1",
383
+ "aiPanel.cacheRead": "\u7F13\u5B58\u8BFB",
384
+ "aiPanel.cacheWrite": "\u7F13\u5B58\u5199",
385
+ "aiPanel.callsTokens": "{p0} \u6B21 \xB7 {p1} tok{p2}",
386
+ "aiPanel.clearAudit": "\u6E05\u9664\u5BA1\u8BA1",
387
+ "aiPanel.context": "\u4E0A\u4E0B\u6587",
388
+ "aiPanel.contextWindow": "\u4E0A\u4E0B\u6587\u7A97\u53E3",
389
+ "aiPanel.errorsCount": "{p0} \u5931\u8D25",
390
+ "aiPanel.files": "\u6587\u4EF6 ({p0})",
391
+ "aiPanel.itemStatus": "{p0}\uFF0C\u72B6\u6001\uFF1A{p1}",
392
+ "aiPanel.noAudit": "\u6682\u65E0\u5BA1\u8BA1\u8BB0\u5F55",
393
+ "aiPanel.noUsage": "\u6682\u65E0\u7528\u91CF",
394
+ "aiPanel.reasoning": "\u63A8\u7406",
395
+ "aiPanel.requestsCount": "{p0} \u6B21\u8BF7\u6C42",
396
+ "aiPanel.ringPercent": "\u4E0A\u4E0B\u6587\u7A97\u53E3\u5360\u7528 {p0}%\uFF0C\u70B9\u51FB\u67E5\u770B\u8BE6\u60C5",
397
+ "aiPanel.ringUsed": "\u5DF2\u7528 {p0}\uFF0C\u70B9\u51FB\u67E5\u770B\u8BE6\u60C5",
398
+ "aiPanel.taskProgress": "\u4EFB\u52A1\u8FDB\u5EA6",
399
+ "aiPanel.toolsCount": "{p0} \u5DE5\u5177",
400
+ "aiPanel.usage": "\u7528\u91CF",
401
+ "aiPanel.usageAria": "\u7528\u91CF\uFF1A{p0}",
402
+ /* ── aiProvider ── */
403
+ "aiProvider.audioUrlOnly": "\u4EC5 URL \u7684\u97F3\u9891\uFF08input_audio \u9700 base64\uFF0C\u8BF7\u5148\u53D6\u56DE\u5185\u8054\uFF09",
404
+ "aiProvider.audioUrlOnlyAnthropic": "\u4EC5 URL \u7684\u97F3\u9891\uFF08audio \u5757\u9700 base64 source\uFF09",
405
+ "aiProvider.base64File": "base64 \u6587\u4EF6\uFF08file \u90E8\u4EF6\u9700 Files API file_id\uFF0C\u8BF7\u7F6E\u4E8E url \u69FD\uFF09",
406
+ "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",
407
+ "aiProvider.emptyResponse": "\u54CD\u5E94\u4E3A\u7A7A",
408
+ "aiProvider.glmLabel": "GLM\uFF08\u667A\u8C31\uFF09",
409
+ "aiProvider.invalidJson": "\u54CD\u5E94\u4E0D\u662F\u5408\u6CD5 JSON",
410
+ "aiProvider.kimiLabel": "Kimi\uFF08\u6708\u4E4B\u6697\u9762\uFF09",
411
+ "aiProvider.networkFailed": "\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25\uFF1A{p0}{p1}",
412
+ "aiProvider.nonPdfDocument": "\u975E PDF \u6587\u4EF6\u5757\uFF08document \u5757\u4E3A application/pdf\uFF0C\u6536\u5230 {p0}\uFF09",
413
+ "aiProvider.requestCancelled": "\u8BF7\u6C42\u5DF2\u53D6\u6D88",
414
+ "aiProvider.resourceRef": "[\u8D44\u6E90] {p0} ({p1})",
415
+ "aiProvider.streamError": "\u6D41\u5F0F\u54CD\u5E94\u9519\u8BEF",
416
+ "aiProvider.toolRoleNoCallId": "role 'tool' \u4E14\u7F3A toolCallId\uFF08openai \u65CF\u9700 tool_call_id\uFF09",
417
+ "aiProvider.toolRoleNoUseId": "role 'tool' \u4E14\u7F3A toolCallId\uFF08anthropic \u65CF\u6620\u5C04 tool_result \u9700 tool_use_id\uFF09",
418
+ "aiProvider.unsupported": "{p0} \u7EBF\u534F\u8BAE\u4E0D\u652F\u6301 {p1}",
419
+ "aiProvider.videoUnsupported": "video \u8F93\u5165\uFF08\u65E0\u4E3B\u6D41 chat API \u652F\u6301\uFF09",
420
+ "aiProvider.videoUnsupportedAnthropic": "video \u8F93\u5165",
421
+ /* ── aiThreads ── */
422
+ "aiThreads.actionsAria": "\u4F1A\u8BDD\u64CD\u4F5C",
423
+ "aiThreads.archived": "\u5DF2\u5F52\u6863",
424
+ /* ── aiTool ── */
425
+ "aiTool.allow": "\u5141\u8BB8",
426
+ "aiTool.reject": "\u62D2\u7EDD",
427
+ /* ── aiTools ── */
428
+ "aiTools.chart.area": "line \u591A\u7CFB\u5217\u586B\u5145\u9762\u79EF",
429
+ "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",
430
+ "aiTools.chart.dates": "\u8D21\u732E\u65E5\u5386 ISO \u65E5\u671F\uFF08\u4E0E values \u914D\u5BF9\uFF09",
431
+ "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",
432
+ "aiTools.chart.dims": "data[] \u7684\u5B57\u6BB5\u6620\u5C04\uFF1A{label?, series?, value?, x?, y?}",
433
+ "aiTools.chart.format": "\u6570\u503C\u683C\u5F0F\u5316\uFF1A{notation?: compact|percent|ms, unit?}",
434
+ "aiTools.chart.labels": "\u7C7B\u76EE\u8F74\uFF08line/vbar/hbar\uFF09",
435
+ "aiTools.chart.legend": "false = \u521D\u59CB\u9690\u85CF\u56FE\u4F8B",
436
+ "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",
437
+ "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",
438
+ "aiTools.chart.points": "\u6563\u70B9/\u6C14\u6CE1\uFF1A[{x,y,size?,label?}]",
439
+ "aiTools.chart.radarAxes": "\u96F7\u8FBE\u8F74\u540D",
440
+ "aiTools.chart.segments": "\u5360\u6BD4\u578B\uFF08donut/stack\uFF09\uFF1A[{label,value}]",
441
+ "aiTools.chart.series": "\u591A\u7CFB\u5217\uFF08line/vbar/radar\uFF09",
442
+ "aiTools.chart.stacked": "vbar \u591A\u7CFB\u5217\u5806\u53E0\uFF08\u9ED8\u8BA4\u5206\u7EC4\uFF09",
443
+ "aiTools.chart.title": "\u56FE\u8868\u6807\u9898\uFF08\u6E32\u67D3\u5728\u5934\u90E8\u884C\u5DE6\u4FA7\uFF09",
444
+ "aiTools.chart.tooltip": "false = \u5173\u95ED\u5185\u7F6E\u63D0\u793A",
445
+ "aiTools.chart.type": "\u56FE\u8868\u7C7B\u578B\uFF0C\u7F3A\u7701\u81EA\u52A8\u63A8\u65AD",
446
+ "aiTools.chart.values": "\u5355\u7CFB\u5217\u6570\u503C\uFF08\u4E0E labels \u914D\u5BF9\uFF09",
447
+ "aiTools.chart.zoom": "\u7F29\u653E\u4EA4\u4E92\uFF1A'x'=\u7C7B\u76EE\u8F74\u533A\u95F4\u7F29\u653E\uFF0C'brush'=\u5237\u9009\u7F29\u653E",
448
+ "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",
449
+ "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",
450
+ "aiTools.datatable.rows": "\u884C\u6570\u636E\u6570\u7EC4\uFF1A\u6BCF\u9879\u4E3A\u4E00\u4E2A\u5BF9\u8C61\uFF0C\u5B57\u6BB5\u540D\u5BF9\u9F50 columns[].key",
451
+ "aiTools.datatable.title": "\u8868\u683C\u6807\u9898\uFF08\u6E32\u67D3\u5728\u5DE5\u5177\u680F\u5DE6\u4FA7\uFF09",
452
+ "aiTools.execFailed": "\u5DE5\u5177\u6267\u884C\u5931\u8D25\uFF1A{p0}",
453
+ "aiTools.execTimeout": "\u6267\u884C\u8D85\u65F6\uFF08{p0}ms\uFF09",
454
+ "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",
455
+ "aiTools.missingRequired": "\u7F3A\u5C11\u5FC5\u586B\u5B57\u6BB5",
456
+ "aiTools.none": "\uFF08\u65E0\u5DF2\u6CE8\u518C\u7684 UI \u5DE5\u5177\uFF09",
457
+ "aiTools.notInEnum": "\u4E0D\u5728\u5141\u8BB8\u53D6\u503C\u5185\uFF08{p0}\uFF09",
458
+ "aiTools.numMax": "\u6570\u503C {p0} \u5927\u4E8E\u6700\u5927\u503C {p1}",
459
+ "aiTools.numMin": "\u6570\u503C {p0} \u5C0F\u4E8E\u6700\u5C0F\u503C {p1}",
460
+ "aiTools.removeMount": "\u79FB\u9664 {p0} \u6302\u8F7D",
461
+ "aiTools.strMax": "\u957F\u5EA6 {p0} \u8D85\u8FC7\u4E0A\u9650 {p1}",
462
+ "aiTools.strMin": "\u957F\u5EA6 {p0} \u5C0F\u4E8E\u4E0B\u9650 {p1}",
463
+ "aiTools.typeMismatch": "\u671F\u671B {p0}\uFF0C\u5B9E\u5F97 {p1}",
464
+ "aiTools.validationFailed": "\u53C2\u6570\u6821\u9A8C\u5931\u8D25\uFF08{p0} \u9879\uFF09",
465
+ /* ── autocomplete ── */
466
+ "suggestions.loading": "\u6B63\u5728\u67E5\u627E\u5EFA\u8BAE\u2026",
467
+ "suggestions.error": "\u6682\u65F6\u65E0\u6CD5\u52A0\u8F7D\u5EFA\u8BAE\uFF0C\u8BF7\u91CD\u8BD5\u3002",
468
+ "suggestions.options": "\u5EFA\u8BAE",
469
+ "suggestions.empty": "\u6CA1\u6709\u5339\u914D\u7684\u5EFA\u8BAE",
470
+ "autocomplete.empty": "\u65E0\u5339\u914D\u7ED3\u679C",
471
+ /* ── backTop ── */
472
+ "backTop.label": "\u56DE\u5230\u9876\u90E8",
473
+ /* ── carousel ── */
474
+ "carousel.item": "\u7B2C {p0} \u5F20",
475
+ "carousel.region": "\u8F6E\u64AD",
476
+ "carousel.slide": "\u5E7B\u706F\u7247",
477
+ "carousel.status": "\u7B2C {p0} / {p1} \u5F20",
478
+ /* ── charts ── */
479
+ "charts.calendarWeekdays": ["\u4E00", "", "\u4E09", "", "\u4E94", "", "\u65E5"],
480
+ "charts.few": "\u5C11",
481
+ "charts.hideLegend": "\u9690\u85CF\u56FE\u4F8B",
482
+ "charts.loading": "\u52A0\u8F7D\u4E2D",
483
+ "charts.many": "\u591A",
484
+ "charts.monthLabel": "{p0}\u6708",
485
+ "charts.noData": "\u6682\u65E0\u6570\u636E",
486
+ "charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
487
+ "charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
488
+ "charts.type.area": "\u9762\u79EF\u56FE",
489
+ "charts.type.donut": "\u73AF\u5F62\u56FE",
490
+ "charts.type.gauge": "\u4EEA\u8868\u76D8",
491
+ "charts.type.graph": "\u77E5\u8BC6\u56FE\u8C31",
492
+ "charts.type.heatmap": "\u70ED\u529B\u56FE",
493
+ "charts.type.line": "\u6298\u7EBF\u56FE",
494
+ "charts.type.map": "\u5730\u56FE",
495
+ "charts.type.radar": "\u96F7\u8FBE\u56FE",
496
+ "charts.type.scatter": "\u6563\u70B9\u56FE",
497
+ "charts.type.sparkline": "\u8FF7\u4F60\u8D8B\u52BF",
498
+ "charts.seriesName": "\u7CFB\u5217{p0}",
499
+ "charts.showLegend": "\u663E\u793A\u56FE\u4F8B",
500
+ "charts.value": "\u6570\u503C",
501
+ /* ── themeSwitcher ── */
502
+ "themeSwitcher.appearance": "\u5916\u89C2",
503
+ "themeSwitcher.theme": "\u4E3B\u9898",
504
+ "themeSwitcher.primitive": "\u539F\u8BED",
505
+ "themeSwitcher.mode": "\u660E\u6697",
506
+ "themeSwitcher.light": "\u6D45\u8272",
507
+ "themeSwitcher.dark": "\u6DF1\u8272",
508
+ "themeSwitcher.modern": "\u73B0\u4EE3",
509
+ "themeSwitcher.dongyun": "\u4E1C\u97F5",
510
+ "themeSwitcher.jugou": "\u5DE8\u6784",
511
+ "themeSwitcher.piano": "\u94A2\u7434",
512
+ "themeSwitcher.monet": "\u83AB\u5948",
513
+ "themeSwitcher.vangogh": "\u68B5\u9AD8",
514
+ "themeSwitcher.chinese": "\u4E2D\u5F0F",
515
+ "themeSwitcher.soviet": "\u82CF\u5F0F",
516
+ "themeSwitcher.pixel": "\u50CF\u7D20",
517
+ /* ── codeBlock ── */
518
+ "codeBlock.collapse": "\u6536\u8D77",
519
+ "codeBlock.region": "\u4EE3\u7801\u5185\u5BB9",
520
+ "codeBlock.copyFailed": "\u672A\u80FD\u590D\u5236\uFF0C\u8BF7\u91CD\u8BD5\u3002",
521
+ "codeBlock.copyRetry": "\u91CD\u8BD5\u590D\u5236",
522
+ "codeBlock.copy": "\u590D\u5236",
523
+ "codeBlock.foldCollapse": "\u6298\u53E0\u4EE3\u7801",
524
+ "codeBlock.foldExpand": "\u5C55\u5F00\u4EE3\u7801",
525
+ "codeBlock.linesTotal": "\u5171 {p0} \u884C",
526
+ "codeBlock.numHide": "\u9690\u85CF\u884C\u53F7",
527
+ "codeBlock.numShow": "\u663E\u793A\u884C\u53F7",
528
+ "codeBlock.tailAria": "\u5C55\u5F00\u6216\u6536\u8D77\u4EE3\u7801",
529
+ "codeBlock.wrapOff": "\u5173\u95ED\u6362\u884C",
530
+ "codeBlock.wrapOn": "\u81EA\u52A8\u6362\u884C",
531
+ /* ── common ── */
532
+ "common.accept": "\u63A5\u53D7",
533
+ "common.add": "\u65B0\u589E",
534
+ "common.all": "\u5168\u90E8",
535
+ "common.approve": "\u6279\u51C6",
536
+ "common.cancel": "\u53D6\u6D88",
537
+ "common.actionFailed": "\u64CD\u4F5C\u672A\u5B8C\u6210\uFF0C\u8BF7\u91CD\u8BD5\u3002",
538
+ "common.close": "\u5173\u95ED",
539
+ "common.confirm": "\u786E\u8BA4",
540
+ "common.copied": "\u5DF2\u590D\u5236",
541
+ "common.copy": "\u590D\u5236",
542
+ "common.delete": "\u5220\u9664",
543
+ "common.enable": "\u542F\u7528",
544
+ "common.exportCsv": "\u5BFC\u51FA CSV",
545
+ "common.healthy": "\u6B63\u5E38",
546
+ "common.input": "\u8F93\u5165",
547
+ "common.loadingEllipsis": "\u52A0\u8F7D\u4E2D\u2026",
548
+ "common.official": "\u5B98\u65B9",
549
+ "common.output": "\u8F93\u51FA",
550
+ "common.page": "\u7B2C {p0} \u9875",
551
+ "common.reject": "\u62D2\u7EDD",
552
+ "common.remove": "\u79FB\u9664",
553
+ "common.requestAccess": "\u7533\u8BF7\u8BBF\u95EE",
554
+ "common.requestAccessFor": "\u7533\u8BF7\u8BBF\u95EE {p0}",
555
+ "common.restricted": "\u53D7\u9650",
556
+ "common.retry": "\u91CD\u8BD5",
557
+ "common.rows": "{p0} \u884C",
558
+ "common.run": "\u8FD0\u884C",
559
+ "common.steps": "{p0} \u6B65",
560
+ "common.submit": "\u63D0\u4EA4",
561
+ "common.unknown": "\u672A\u77E5",
562
+ /* ── contextMenu ── */
563
+ "contextMenu.back": "\u540E\u9000",
564
+ "contextMenu.copyPageLink": "\u590D\u5236\u9875\u9762\u94FE\u63A5",
565
+ "contextMenu.forward": "\u524D\u8FDB",
566
+ "contextMenu.refresh": "\u5237\u65B0",
567
+ /* ── copy ── */
568
+ "copy.copied": "\u5DF2\u590D\u5236",
569
+ "copy.failed": "\u672A\u80FD\u590D\u5236\uFF0C\u8BF7\u91CD\u8BD5\u3002",
570
+ "copy.denied": "clipboard API \u88AB\u62D2\uFF08{p0}\uFF09\u4E14\u56DE\u9000 execCommand \u5931\u8D25",
571
+ "copy.unavailable": "\u526A\u8D34\u677F\u4E0D\u53EF\u7528\uFF08\u65E0 clipboard API \u4E14 execCommand \u56DE\u9000\u5931\u8D25\uFF09",
572
+ "copy.unknown": "\u672A\u77E5\u9519\u8BEF",
573
+ /* ── datatable ── */
574
+ "datatable.clear": "\u6E05\u7A7A",
575
+ "datatable.collapseGroup": "\u6298\u53E0\u5206\u7EC4 {p0}",
576
+ "datatable.columnSettingsAria": "\u5217\u8BBE\u7F6E",
577
+ "datatable.countUnit": "{p0} \u6761",
578
+ "datatable.editHint": "\u7F16\u8F91\u300C{p0}\u300D\uFF1A\u53CC\u51FB\u6216\u6309 Enter",
579
+ "datatable.editHintWithValue": "{p0}\uFF08\u53CC\u51FB\u6216\u6309 Enter \u7F16\u8F91\u300C{p1}\u300D\uFF09",
580
+ "datatable.empty": "\u6682\u65E0\u6570\u636E",
581
+ "datatable.emptyValue": "\uFF08\u7A7A\uFF09",
582
+ "datatable.expandGroup": "\u5C55\u5F00\u5206\u7EC4 {p0}",
583
+ "datatable.expandRow": "\u5C55\u5F00\u884C",
584
+ "datatable.filterChipAria": "\u7B5B\u9009\u300C{p0}\u300D",
585
+ "datatable.pageSizeAria": "\u6BCF\u9875\u6761\u6570",
586
+ "datatable.paginationAria": "\u5206\u9875",
587
+ "datatable.reset": "\u91CD\u7F6E",
588
+ "datatable.resizeAria": "\u8C03\u6574\u300C{p0}\u300D\u5217\u5BBD",
589
+ "datatable.searchAria": "\u641C\u7D22\u8868\u683C",
590
+ "datatable.searchPlaceholder": "\u641C\u7D22\u2026",
591
+ "datatable.selectAll": "\u5168\u9009",
592
+ "datatable.selectRow": "\u9009\u62E9\u8BE5\u884C",
593
+ "datatable.selectedCount": "\u5DF2\u9009 {p0} \u9879",
594
+ "datatable.totalCount": "\u5171 {p0} \u6761",
595
+ "datatable.totalLabel": "\u5408\u8BA1",
596
+ /* ── datePicker ── */
597
+ "datePicker.noDates": "\u6CA1\u6709\u53EF\u9009\u65E5\u671F",
598
+ "datePicker.clear": "\u6E05\u9664",
599
+ "datePicker.nextMonth": "\u4E0B\u4E00\u6708",
600
+ "datePicker.prevMonth": "\u4E0A\u4E00\u6708",
601
+ "datePicker.selectDate": "\u9009\u62E9\u65E5\u671F",
602
+ "datePicker.today": "\u4ECA\u5929",
603
+ "datePicker.weekdays": ["\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D", "\u65E5"],
604
+ "datePicker.weekdaysSunFirst": ["\u65E5", "\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D"],
605
+ "datePicker.yearMonth": "{p0} \u5E74 {p1} \u6708",
606
+ /* ── formValidate ── */
607
+ "formValidate.email": "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u90AE\u7BB1\u5730\u5740",
608
+ "formValidate.invalid": "\u8F93\u5165\u4E0D\u5408\u6CD5",
609
+ "formValidate.matches": "\u4E24\u6B21\u8F93\u5165\u4E0D\u4E00\u81F4",
610
+ "formValidate.max": "\u4E0D\u80FD\u5927\u4E8E {max}",
611
+ "formValidate.maxlength": "\u6700\u591A\u8F93\u5165 {max} \u4E2A\u5B57\u7B26",
612
+ "formValidate.min": "\u4E0D\u80FD\u5C0F\u4E8E {min}",
613
+ "formValidate.minlength": "\u81F3\u5C11\u8F93\u5165 {min} \u4E2A\u5B57\u7B26",
614
+ "formValidate.number": "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u6570\u5B57",
615
+ "formValidate.pattern": "\u8F93\u5165\u683C\u5F0F\u4E0D\u6B63\u786E",
616
+ "formValidate.required": "\u6B64\u9879\u4E3A\u5FC5\u586B\u9879",
617
+ "formValidate.selectPlaceholder": "\u8BF7\u9009\u62E9",
618
+ "formValidate.step": "\u6570\u503C\u5FC5\u987B\u662F {step} \u7684\u500D\u6570",
619
+ "formValidate.summary": "\u8868\u5355\u6709 {p0} \u9879\u5185\u5BB9\u9700\u8981\u4FEE\u6B63\uFF0C\u8BF7\u4FEE\u6539\u540E\u91CD\u65B0\u63D0\u4EA4",
620
+ "formValidate.tool.description": "\u5411\u7528\u6237\u6E32\u67D3\u4E00\u4E2A\u7ED3\u6784\u5316\u8868\u5355\u6536\u96C6\u8F93\u5165",
621
+ "formValidate.tool.fields": "\u5B57\u6BB5\u5217\u8868",
622
+ "formValidate.tool.help": "\u5B57\u6BB5\u4E0B\u65B9\u7684\u5E2E\u52A9\u6587\u6848",
623
+ "formValidate.tool.label": "\u5B57\u6BB5\u6807\u7B7E",
624
+ "formValidate.tool.max": "\u6700\u5927\u503C\uFF08number \u7528\uFF09",
625
+ "formValidate.tool.min": "\u6700\u5C0F\u503C\uFF08number \u7528\uFF09",
626
+ "formValidate.tool.name": "\u5B57\u6BB5\u540D\uFF08\u63D0\u4EA4\u503C\u7684 key\uFF09",
627
+ "formValidate.tool.options": "select \u9009\u9879\uFF08\u5B57\u7B26\u4E32\u6216 {label,value}\uFF09",
628
+ "formValidate.tool.pattern": "\u6B63\u5219\u7EA6\u675F\uFF08HTML pattern \u8BED\u6CD5\uFF0C\u6574\u4E32\u5339\u914D\uFF09",
629
+ "formValidate.tool.required": "\u662F\u5426\u5FC5\u586B",
630
+ "formValidate.tool.submitText": "\u63D0\u4EA4\u6309\u94AE\u6587\u6848\uFF0C\u9ED8\u8BA4\u300C\u63D0\u4EA4\u300D",
631
+ "formValidate.tool.title": "\u8868\u5355\u6807\u9898\uFF08\u53EF\u9009\uFF09",
632
+ "formValidate.tool.type": "\u63A7\u4EF6\u7C7B\u578B\uFF0C\u9ED8\u8BA4 text",
633
+ "formValidate.url": "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u94FE\u63A5\u5730\u5740",
634
+ /* ── input ── */
635
+ "input.clearSearch": "\u6E05\u7A7A\u641C\u7D22",
636
+ "input.hidePassword": "\u9690\u85CF\u5BC6\u7801",
637
+ "input.otpPosition": "\u7B2C {p0} \u4F4D\uFF0C\u5171 {p1} \u4F4D",
638
+ "panel.expand": "\u5C55\u5F00",
639
+ "panel.collapse": "\u6298\u53E0",
640
+ "input.showPassword": "\u663E\u793A\u5BC6\u7801",
641
+ /* ── kbAccess ── */
642
+ "kbAccess.approveTip": "\u6279\u51C6\u8BE5\u8BBF\u95EE\u7533\u8BF7",
643
+ "kbAccess.approvedBadge": "\u5DF2\u6279\u51C6 \xB7 {p0}",
644
+ "kbAccess.approverNotePlaceholder": "\u7ED9\u8BF7\u6C42\u4EBA\u7684\u7559\u8A00\uFF08\u53EF\u9009\uFF09",
645
+ "kbAccess.daysLeft": "{p0} \u5929\u540E",
646
+ "kbAccess.defaultSubject": "\u8BE5\u5185\u5BB9",
647
+ "kbAccess.deniedHint": "\u672A\u901A\u8FC7\u2014\u2014\u53EF\u8C03\u6574\u7406\u7531\u540E\u91CD\u65B0\u7533\u8BF7",
648
+ "kbAccess.denyNoteLabel": "\u62D2\u7EDD\u7559\u8A00\uFF08\u53EF\u9009\uFF09",
649
+ "kbAccess.duration30d": "30 \u5929",
650
+ "kbAccess.duration7d": "7 \u5929",
651
+ "kbAccess.durationForever": "\u6C38\u4E45",
652
+ "kbAccess.durationLabel": "\u8BBF\u95EE\u65F6\u957F",
653
+ "kbAccess.expired": "\u5DF2\u5230\u671F",
654
+ "kbAccess.expiresAt": "{p0}\u5230\u671F",
655
+ "kbAccess.grantAsPrefix": "\u6279\u51C6\u4E3A{p0}",
656
+ "kbAccess.grantRoleLabel": "\u6279\u51C6\u89D2\u8272",
657
+ "kbAccess.hoursLeft": "{p0} \u5C0F\u65F6\u540E",
658
+ "kbAccess.minutesLeft": "{p0} \u5206\u949F\u540E",
659
+ "kbAccess.ownerLabel": "\u5185\u5BB9\u8D1F\u8D23\u4EBA",
660
+ "kbAccess.ownerPrefix": "\u8D1F\u8D23\u4EBA\uFF1A{p0}",
661
+ "kbAccess.reapply": "\u91CD\u65B0\u7533\u8BF7",
662
+ "kbAccess.reasonLabel": "\u7533\u8BF7\u7406\u7531",
663
+ "kbAccess.reasonPlaceholder": "\u8BF4\u660E\u4E1A\u52A1\u539F\u56E0\uFF08\u5BA1\u6279\u4EBA\u53EF\u89C1\uFF09",
664
+ "kbAccess.rejectTip": "\u62D2\u7EDD\u8BE5\u8BBF\u95EE\u7533\u8BF7",
665
+ "kbAccess.requestRenewal": "\u7533\u8BF7\u7EED\u671F",
666
+ "kbAccess.requestToPrefix": "\u8BF7\u6C42\u5C06\u53D1\u9001\u7ED9\uFF1A{p0}",
667
+ "kbAccess.restrictedContent": "\u53D7\u9650\u5185\u5BB9",
668
+ "kbAccess.restrictedHint": "\u6B64\u5185\u5BB9\u4EC5\u5BF9\u6388\u6743\u8005\u5F00\u653E",
669
+ "kbAccess.revokedHint": "\u8BBF\u95EE\u5DF2\u88AB\u6536\u56DE",
670
+ "kbAccess.roleLabel": "\u7533\u8BF7\u89D2\u8272",
671
+ "kbAccess.submitRequest": "\u63D0\u4EA4\u7533\u8BF7",
672
+ "kbAccess.switchIdentity": "\u5207\u6362\u8EAB\u4EFD",
673
+ "kbAccess.switchIdentityTip": "\u5207\u6362\u8EAB\u4EFD\u540E\u91CD\u65B0\u68C0\u67E5\u6743\u9650",
674
+ "kbAccess.unknownRequester": "\u672A\u77E5\u8BF7\u6C42\u4EBA",
675
+ "kbAccess.waitingApproval": "\u7B49\u5F85 {p0} \u5BA1\u6279",
676
+ /* ── kbAcl ── */
677
+ "kbAcl.breakHint": "\u505C\u6B62\u4ECE\u7236\u7EA7\u7EE7\u627F\uFF0C\u6539\u4E3A\u72EC\u7ACB\u7BA1\u7406\u672C\u9879\u6743\u9650",
678
+ "kbAcl.breakInheritance": "\u505C\u6B62\u7EE7\u627F",
679
+ "kbAcl.brokenNotice": "\u5DF2\u505C\u6B62\u7EE7\u627F\u2014\u2014\u672C\u9879\u6743\u9650\u72EC\u7ACB\u4E8E\u7236\u7EA7",
680
+ "kbAcl.detachedChildren": "{p0}\uFF1A{p1} \u4E2A\u5B50\u9879\u5DF2\u8131\u79BB",
681
+ "kbAcl.directAccess": "\u76F4\u63A5\u8BBF\u95EE",
682
+ "kbAcl.exception": "\u4F8B\u5916",
683
+ "kbAcl.expiredOn": "\u5DF2\u8FC7\u671F\uFF08{p0}\uFF09",
684
+ "kbAcl.expiresIn": "{p0} \u5230\u671F",
685
+ "kbAcl.grantAccess": "\u6388\u4E88\u8BBF\u95EE",
686
+ "kbAcl.inheritedFrom": "\u7EE7\u627F\u81EA {p0}",
687
+ "kbAcl.inheritedFromLabel": "\u7EE7\u627F\u81EA",
688
+ "kbAcl.linkAccess": "\u94FE\u63A5\u8BBF\u95EE",
689
+ "kbAcl.noDirect": "\u6682\u65E0\u76F4\u63A5\u6388\u6743",
690
+ "kbAcl.noLinks": "\u65E0\u94FE\u63A5",
691
+ "kbAcl.removeEntry": "\u79FB\u9664 {p0}",
692
+ "kbAcl.restoreHint": "\u6062\u590D\u7EE7\u627F\u5C06\u4E22\u5F03\u672C\u9879\u81EA\u5B9A\u4E49\u7684\u6743\u9650",
693
+ "kbAcl.restoreInheritance": "\u6062\u590D\u7EE7\u627F",
694
+ "kbAcl.rootNotice": "\u6839\u7EA7\u8D44\u6E90\u2014\u2014\u65E0\u7236\u7EA7\u7EE7\u627F",
695
+ "kbAcl.systemBadge": "\u7CFB\u7EDF\u7BA1\u7406",
696
+ "kbAcl.systemNote": "\u7CFB\u7EDF\u81EA\u52A8\uFF0C\u4E0D\u53EF\u624B\u5DE5\u79FB\u9664",
697
+ "kbAcl.unnamedResource": "\u672A\u547D\u540D\u8D44\u6E90",
698
+ "kbAcl.visibleToCount": "\u5BF9 {p0} \u4EBA\u53EF\u89C1",
699
+ /* ── kbAnswer ── */
700
+ "kbAnswer.chartBar": "\u67F1\u72B6",
701
+ "kbAnswer.chartLine": "\u6298\u7EBF",
702
+ "kbAnswer.chartPie": "\u997C\u56FE",
703
+ "kbAnswer.exportNoun": "\u5BFC\u51FA {p0}",
704
+ "kbAnswer.filtered": "\u5DF2\u6309\u4F60\u7684\u6570\u636E\u6743\u9650\u8FC7\u6EE4",
705
+ "kbAnswer.filteredDetail": "\u5DF2\u6309\u4F60\u7684\u6570\u636E\u6743\u9650\u8FC7\u6EE4\uFF1A{p0}",
706
+ "kbAnswer.followups": "\u8FFD\u95EE\u5EFA\u8BAE",
707
+ "kbAnswer.hitAssets": "\u547D\u4E2D\u8D44\u4EA7\uFF1A{p0}",
708
+ "kbAnswer.kindCurated": "\u4EBA\u5DE5\u7B56\u5C55",
709
+ "kbAnswer.kindFunction": "\u51FD\u6570",
710
+ "kbAnswer.kindParameterized": "\u53C2\u6570\u5316\u67E5\u8BE2",
711
+ "kbAnswer.maskedPrefix": "\u5DF2\u8131\u654F\u5217\uFF1A",
712
+ "kbAnswer.rerunTip": "\u53C2\u6570\u53EF\u6539\u91CD\u8DD1",
713
+ "kbAnswer.truncated": "\u5DF2\u622A\u65AD\uFF1A\u663E\u793A {p0}/{p1} \u884C{p2}",
714
+ "kbAnswer.verifiedBadge": "\u8BA4\u8BC1\u7B54\u6848",
715
+ /* ── kbAudit ── */
716
+ "kbAudit.actionDetail": "\u5904\u7F6E\uFF1A{p0} \xB7 {p1}",
717
+ "kbAudit.actionLabel": "\u5904\u7F6E",
718
+ "kbAudit.alertedNote": "\u5DF2\u5B9E\u65F6\u544A\u8B66\u5B89\u5168\u56E2\u961F",
719
+ "kbAudit.channelFilterAria": "\u5BA1\u8BA1\u901A\u9053\u8FC7\u6EE4",
720
+ "kbAudit.channelPermission": "\u6743\u9650\u53D8\u66F4",
721
+ "kbAudit.channelRead": "\u8BFB\u53D6",
722
+ "kbAudit.channelRequest": "\u7533\u8BF7",
723
+ "kbAudit.channelSystem": "\u7CFB\u7EDF",
724
+ "kbAudit.empty": "\u6682\u65E0\u5BA1\u8BA1\u4E8B\u4EF6",
725
+ "kbAudit.exportTip": "\u5BFC\u51FA\u5F53\u524D\u8FC7\u6EE4\u89C6\u56FE\u4E3A CSV",
726
+ "kbAudit.hygieneLabel": "\u6743\u9650\u5F02\u5473",
727
+ "kbAudit.noHygiene": "\u672A\u53D1\u73B0\u6743\u9650\u5F02\u5473",
728
+ /* ── kbCanvas ── */
729
+ "kbCanvas.splitterAria": "\u8C03\u6574\u753B\u5E03\u53CC\u680F\u6BD4\u4F8B",
730
+ "kbCanvas.splitterTip": "\u62D6\u62FD\u8C03\u6574\u6BD4\u4F8B\uFF08\u2190/\u2192 \u5FAE\u8C03\uFF0C\u53CC\u51FB\u590D\u4F4D\uFF09",
731
+ /* ── kbCheckpoint ── */
732
+ "kbCheckpoint.chatAuditNote": "\u8BA8\u8BBA\u5386\u53F2\u6709\u5BA1\u8BA1\u4EF7\u503C",
733
+ "kbCheckpoint.label": "\u68C0\u67E5\u70B9",
734
+ "kbCheckpoint.restore": "\u6062\u590D\u68C0\u67E5\u70B9",
735
+ "kbCheckpoint.scopeBoth": "\u5185\u5BB9\u4E0E\u5BF9\u8BDD",
736
+ "kbCheckpoint.scopeChat": "\u4EC5\u5BF9\u8BDD",
737
+ "kbCheckpoint.scopeContent": "\u4EC5\u5185\u5BB9\uFF08\u4FDD\u7559\u5BF9\u8BDD\uFF09",
738
+ "kbCheckpoint.scopeMissing": "\u8BE5\u68C0\u67E5\u70B9\u672A\u5305\u542B\u6B64\u6062\u590D\u8303\u56F4",
739
+ /* ── kbChunks ── */
740
+ "kbChunks.addKeyword": "+ \u5173\u952E\u8BCD",
741
+ "kbChunks.chunkAddKeywordAria": "chunk {p0} \u65B0\u589E\u5173\u952E\u8BCD",
742
+ "kbChunks.chunkContentAria": "chunk {p0} \u5185\u5BB9",
743
+ "kbChunks.chunkEnableAria": "chunk {p0} \u542F\u7528",
744
+ "kbChunks.deleteChunkAria": "\u5220\u9664 chunk {p0}",
745
+ "kbChunks.disableNote": "\u5173\u95ED\u540E\u4E0D\u5220\u9664\uFF0C\u4EC5\u6392\u9664\u51FA\u68C0\u7D22",
746
+ "kbChunks.edited": "\u5DF2\u7F16\u8F91",
747
+ "kbChunks.empty": "\u6682\u65E0 chunk",
748
+ "kbChunks.modeFull": "\u5168\u6587",
749
+ "kbChunks.modeLabel": "\u641C\u7D22\u6A21\u5F0F",
750
+ "kbChunks.modeVector": "\u8BED\u4E49",
751
+ "kbChunks.removeKeyword": "\u79FB\u9664\u5173\u952E\u8BCD {p0}",
752
+ "kbChunks.searchAria": "\u641C\u7D22 chunk",
753
+ "kbChunks.searchFullPlaceholder": "\u5168\u6587\u641C\u7D22 chunk\u2026",
754
+ "kbChunks.searchVectorPlaceholder": "\u8BED\u4E49\u641C\u7D22 chunk\u2026",
755
+ /* ── kbCitation ── */
756
+ "kbCitation.sourceN": "\u6765\u6E90 {p0}",
757
+ "kbCitation.unavailable": "\u6765\u6E90\u5DF2\u4E0D\u53EF\u7528",
758
+ /* ── kbClarify ── */
759
+ "kbClarify.parsedPrefix": "\u5DF2\u89E3\u6790\uFF1A",
760
+ /* ── kbConflict ── */
761
+ "kbConflict.owner": "\u8D23\u4EFB\u4EBA {p0}",
762
+ /* ── kbConnector ── */
763
+ "kbConnector.changeRate": "\u53D8\u66F4\u7387",
764
+ "kbConnector.crawlRate": "\u6293\u53D6\u7387",
765
+ "kbConnector.credentials": "\u51ED\u8BC1",
766
+ "kbConnector.credentialsExpired": "\u51ED\u8BC1\u8FC7\u671F",
767
+ "kbConnector.editSchedule": "\u7F16\u8F91\u8BA1\u5212",
768
+ "kbConnector.empty": "\u6682\u65E0\u8FDE\u63A5\u5668",
769
+ "kbConnector.failing": "\u5F02\u5E38",
770
+ "kbConnector.lastSync": "\u6700\u8FD1\u540C\u6B65 {p0}",
771
+ "kbConnector.neverSynced": "\u4ECE\u672A\u540C\u6B65",
772
+ "kbConnector.notConfigured": "\u672A\u914D\u7F6E",
773
+ "kbConnector.off": "\u5DF2\u505C\u7528",
774
+ "kbConnector.perDay": "{p0}/\u5929",
775
+ "kbConnector.reauth": "\u91CD\u65B0\u6388\u6743",
776
+ "kbConnector.stale": "\u505C\u6EDE",
777
+ "kbConnector.syncNow": "\u7ACB\u5373\u540C\u6B65",
778
+ "kbConnector.synced": "\u5DF2\u540C\u6B65",
779
+ /* ── kbCore ── */
780
+ "kbCore.accessDenied": "\u672A\u901A\u8FC7",
781
+ "kbCore.accessExpired": "\u5DF2\u8FC7\u671F",
782
+ "kbCore.accessExpiring": "\u5373\u5C06\u5230\u671F",
783
+ "kbCore.accessGranted": "\u5DF2\u5F00\u901A",
784
+ "kbCore.accessNotRequested": "\u672A\u7533\u8BF7",
785
+ "kbCore.accessPending": "\u5F85\u5BA1\u6279",
786
+ "kbCore.accessRequested": "\u5DF2\u63D0\u4EA4",
787
+ "kbCore.accessRevoked": "\u5DF2\u6536\u56DE",
788
+ "kbCore.auditApprove": "\u6279\u51C6",
789
+ "kbCore.auditBreakGlass": "\u5E94\u6025\u8BBF\u95EE",
790
+ "kbCore.auditDelegation": "\u59D4\u6D3E",
791
+ "kbCore.auditDeny": "\u62D2\u7EDD",
792
+ "kbCore.auditGrant": "\u6388\u4E88",
793
+ "kbCore.auditPermissionChange": "\u6743\u9650\u53D8\u66F4",
794
+ "kbCore.auditPreview": "\u9884\u89C8",
795
+ "kbCore.auditRead": "\u8BFB\u53D6",
796
+ "kbCore.auditRequest": "\u7533\u8BF7",
797
+ "kbCore.auditRevoke": "\u6536\u56DE",
798
+ "kbCore.auditSync": "\u6743\u9650\u540C\u6B65",
799
+ "kbCore.daysAgo": "{p0} \u5929\u524D",
800
+ "kbCore.hoursAgo": "{p0} \u5C0F\u65F6\u524D",
801
+ "kbCore.hygieneBroadGroup": "\u8FC7\u5BBD\u7EC4\u6388\u6743",
802
+ "kbCore.hygieneBrokenInheritance": "\u65AD\u7EE7\u627F",
803
+ "kbCore.hygieneOrgWideLink": "\u7EC4\u7EC7\u7EA7\u94FE\u63A5",
804
+ "kbCore.hygieneOrphanedOwner": "\u8D1F\u8D23\u4EBA\u7F3A\u4F4D",
805
+ "kbCore.hygieneOverexposed": "\u8FC7\u5EA6\u66B4\u9732",
806
+ "kbCore.hygieneSensitiveMismatch": "\u654F\u611F\u5EA6\u9519\u914D",
807
+ "kbCore.justNow": "\u521A\u521A",
808
+ "kbCore.levelComment": "\u53EF\u8BC4\u8BBA",
809
+ "kbCore.levelEdit": "\u53EF\u7F16\u8F91",
810
+ "kbCore.levelNone": "\u65E0\u6743\u9650",
811
+ "kbCore.levelOwner": "\u8D1F\u8D23\u4EBA",
812
+ "kbCore.levelView": "\u53EF\u67E5\u770B",
813
+ "kbCore.minutesAgo": "{p0} \u5206\u949F\u524D",
814
+ "kbCore.runCancelled": "\u5DF2\u53D6\u6D88",
815
+ "kbCore.runDone": "\u5DF2\u5B8C\u6210",
816
+ "kbCore.runFailed": "\u5931\u8D25",
817
+ "kbCore.runQueued": "\u6392\u961F\u4E2D",
818
+ "kbCore.runRunning": "\u8FDB\u884C\u4E2D",
819
+ "kbCore.runUnstarted": "\u672A\u5F00\u59CB",
820
+ "kbCore.stageAgent": "\u4EE3\u7406",
821
+ "kbCore.stageChunk": "\u5207\u7247",
822
+ "kbCore.stageEmbed": "\u5411\u91CF\u5316",
823
+ "kbCore.stageGeneration": "\u751F\u6210",
824
+ "kbCore.stageGuard": "\u62A4\u680F",
825
+ "kbCore.stageQuery": "\u67E5\u8BE2",
826
+ "kbCore.stageRerank": "\u91CD\u6392",
827
+ "kbCore.stageRetrieval": "\u68C0\u7D22",
828
+ "kbCore.stageTool": "\u5DE5\u5177",
829
+ "kbCore.typeApi": "\u63A5\u53E3",
830
+ "kbCore.typeCode": "\u4EE3\u7801",
831
+ "kbCore.typeDatabase": "\u6570\u636E\u5E93",
832
+ "kbCore.typeDocument": "\u6587\u6863",
833
+ "kbCore.typeEmail": "\u90AE\u4EF6",
834
+ "kbCore.typeImage": "\u56FE\u7247",
835
+ "kbCore.typeKb": "\u77E5\u8BC6\u5E93",
836
+ "kbCore.typeTable": "\u8868\u683C",
837
+ "kbCore.typeTicket": "\u5DE5\u5355",
838
+ "kbCore.typeWebpage": "\u7F51\u9875",
839
+ "kbCore.unnamedSource": "\u672A\u547D\u540D\u6765\u6E90",
840
+ "kbCore.unnamedSubject": "\u672A\u547D\u540D\u4E3B\u4F53",
841
+ "kbCore.visHidden": "\u4E0D\u53EF\u89C1",
842
+ "kbCore.visMetadataOnly": "\u4EC5\u5143\u6570\u636E",
843
+ "kbCore.visSummaryOnly": "\u4EC5\u6458\u8981",
844
+ "kbCore.visVisible": "\u53EF\u89C1",
845
+ /* ── kbEval ── */
846
+ "kbEval.avgA": "A \u5747\u5206 {p0}",
847
+ "kbEval.avgB": "B \u5747\u5206 {p0}",
848
+ "kbEval.compare": "\u5BF9\u6BD4",
849
+ "kbEval.runSelectAria": "\u9009\u62E9\u5BF9\u6BD4\u8FD0\u884C",
850
+ "kbEval.expected": "\u671F\u671B",
851
+ "kbEval.gradeImprovement": "\u63D0\u5347",
852
+ "kbEval.gradeRegression": "\u56DE\u5F52",
853
+ "kbEval.gradeTie": "\u6301\u5E73",
854
+ "kbEval.gradeTradeoff": "\u6743\u8861",
855
+ "kbEval.noData": "\u6CA1\u6709\u5BF9\u6BD4\u6570\u636E",
856
+ "kbEval.onlyRegression": "\u4EC5\u770B\u56DE\u5F52",
857
+ "kbEval.outputA": "\u8F93\u51FA A",
858
+ "kbEval.outputB": "\u8F93\u51FA B",
859
+ "kbEval.outputN": "\u8F93\u51FA {p0}",
860
+ /* ── kbExplain ── */
861
+ "kbExplain.empty": "\u6682\u65E0\u53E3\u5F84\u4FE1\u606F",
862
+ "kbExplain.groupAgg": "\u805A\u5408",
863
+ "kbExplain.groupColumn": "\u5217",
864
+ "kbExplain.groupFilter": "\u7B5B\u9009",
865
+ "kbExplain.groupTable": "\u8868",
866
+ "kbExplain.trigger": "\u8FD9\u4E2A\u6570\u5B57\u662F\u600E\u4E48\u7B97\u51FA\u6765\u7684",
867
+ "kbExplain.viewDefinition": "\u67E5\u770B\u53E3\u5F84",
868
+ /* ── kbFilter ── */
869
+ "kbFilter.addGroup": "+ \u7EC4",
870
+ "kbFilter.addRule": "+ \u89C4\u5219",
871
+ "kbFilter.and": "\u4E14",
872
+ "kbFilter.combineMode": "\u7EC4\u5408\u65B9\u5F0F {p0}",
873
+ "kbFilter.copyDsl": "\u590D\u5236 DSL",
874
+ "kbFilter.deleteGroup": "\u5220\u9664\u7EC4",
875
+ "kbFilter.deleteRule": "\u5220\u9664\u89C4\u5219",
876
+ "kbFilter.fieldLabel": "\u5B57\u6BB5",
877
+ "kbFilter.fieldPlaceholder": "\u8FC7\u6EE4\u5B57\u6BB5",
878
+ "kbFilter.noValueNeeded": "\uFF08\u65E0\u9700\u503C\uFF09",
879
+ "kbFilter.none": "\uFF08\u65E0\u8FC7\u6EE4\uFF09",
880
+ "kbFilter.opContains": "\u5305\u542B",
881
+ "kbFilter.opEq": "\u7B49\u4E8E",
882
+ "kbFilter.opExists": "\u5B58\u5728",
883
+ "kbFilter.opGt": "\u5927\u4E8E",
884
+ "kbFilter.opGte": "\u5927\u4E8E\u7B49\u4E8E",
885
+ "kbFilter.opIn": "\u5C5E\u4E8E",
886
+ "kbFilter.opLt": "\u5C0F\u4E8E",
887
+ "kbFilter.opLte": "\u5C0F\u4E8E\u7B49\u4E8E",
888
+ "kbFilter.opNe": "\u4E0D\u7B49\u4E8E",
889
+ "kbFilter.operatorLabel": "\u64CD\u4F5C\u7B26",
890
+ "kbFilter.or": "\u6216",
891
+ "kbFilter.toggleAndOr": "\u5207\u6362 AND / OR",
892
+ "kbFilter.valueAria": "\u8FC7\u6EE4\u503C",
893
+ "kbFilter.valueLabel": "\u503C",
894
+ "kbFilter.valuePlaceholder": "\u503C 1, \u503C 2\uFF08\u9017\u53F7\u5206\u9694\uFF09",
895
+ /* ── kbGap ── */
896
+ "kbGap.addSynonym": "\u52A0\u540C\u4E49\u8BCD",
897
+ "kbGap.colCount": "\u6B21\u6570",
898
+ "kbGap.colLastSeen": "\u6700\u8FD1\u51FA\u73B0",
899
+ "kbGap.colQuery": "\u67E5\u8BE2",
900
+ "kbGap.colShare": "\u5360\u6BD4",
901
+ "kbGap.createDoc": "\u5EFA\u6587\u6863",
902
+ "kbGap.empty": "\u6CA1\u6709\u672A\u547D\u4E2D\u67E5\u8BE2\u2014\u2014\u8986\u76D6\u826F\u597D",
903
+ "kbGap.title": "\u672A\u547D\u4E2D\u67E5\u8BE2\u8D8B\u52BF",
904
+ "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",
905
+ "kbGap.zeroClickRate": "\u96F6\u70B9\u51FB\u7387",
906
+ "kbGap.zeroClickTitle": "\u96F6\u70B9\u51FB \u2260 \u5931\u8D25",
907
+ /* ── kbHittest ── */
908
+ "kbHittest.addAria": "\u65B0\u589E\u6D4B\u8BD5\u95EE\u9898",
909
+ "kbHittest.addPlaceholder": "\u65B0\u589E\u95EE\u9898\uFF0CEnter \u6DFB\u52A0",
910
+ "kbHittest.avgScore": "\u5747\u5206",
911
+ "kbHittest.deleteQuestion": "\u5220\u9664\u95EE\u9898",
912
+ "kbHittest.empty": "\u6682\u65E0\u6D4B\u8BD5\u95EE\u9898\u2014\u2014\u6DFB\u52A0\u7B2C\u4E00\u6761\uFF0C\u5F00\u59CB\u53EC\u56DE\u56DE\u5F52",
913
+ "kbHittest.expectHit": "\u671F\u671B\u547D\u4E2D\u5728\u524D\u6392\u547D\u4E2D\u4E2D",
914
+ "kbHittest.expectMiss": "\u671F\u671B\u672A\u547D\u4E2D",
915
+ "kbHittest.hitRate": "\u547D\u4E2D\u7387",
916
+ "kbHittest.noExpectation": "\u672A\u8BBE\u671F\u671B",
917
+ "kbHittest.notRun": "\u672A\u8FD0\u884C",
918
+ "kbHittest.pass": "\u901A\u8FC7",
919
+ "kbHittest.pin": "\u7F6E\u9876\u56FA\u5B9A",
920
+ "kbHittest.runAll": "\u8FD0\u884C\u5168\u90E8",
921
+ "kbHittest.sessionOnly": "\u53C2\u6570\u4EC5\u672C\u6B21\u4F1A\u8BDD\u751F\u6548",
922
+ "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",
923
+ "kbHittest.unpin": "\u53D6\u6D88\u7F6E\u9876",
924
+ /* ── kbMetadata ── */
925
+ "kbMetadata.addField": "\u65B0\u589E\u5B57\u6BB5",
926
+ "kbMetadata.builtIn": "\u5185\u7F6E",
927
+ "kbMetadata.colField": "\u5B57\u6BB5",
928
+ "kbMetadata.colType": "\u7C7B\u578B",
929
+ "kbMetadata.colValue": "\u503C",
930
+ "kbMetadata.empty": "\u6682\u65E0\u5143\u6570\u636E\u5B57\u6BB5",
931
+ "kbMetadata.nameLabel": "\u65B0\u5B57\u6BB5\u540D",
932
+ "kbMetadata.namePlaceholder": "\u5B57\u6BB5\u540D\uFF0C\u5982 department",
933
+ "kbMetadata.removeField": "\u79FB\u9664\u5B57\u6BB5 {p0}",
934
+ "kbMetadata.typeLabel": "\u65B0\u5B57\u6BB5\u7C7B\u578B",
935
+ "kbMetadata.valueOf": "{p0} \u7684\u503C",
936
+ /* ── kbPassage ── */
937
+ "kbPassage.blockRange": "\u5757 {p0}\u2013{p1}",
938
+ "kbPassage.close": "\u5173\u95ED\u539F\u6587",
939
+ "kbPassage.expandContext": "\u5C55\u5F00\u4E0A\u4E0B\u6587",
940
+ "kbPassage.locate": "\u539F\u6587\u5B9A\u4F4D",
941
+ "kbPassage.none": "\uFF08\u65E0\u539F\u6587\uFF09",
942
+ "kbPassage.pageRange": "\u7B2C {p0}\u2013{p1} \u9875",
943
+ "kbPassage.restricted": "\u5185\u5BB9\u53D7\u9650",
944
+ "kbPassage.unitByte": "\u5B57\u8282",
945
+ "kbPassage.unitChar": "\u5B57\u7B26",
946
+ /* ── kbPipeline ── */
947
+ "kbPipeline.empty": "\u6682\u65E0\u89E3\u6790\u4EFB\u52A1",
948
+ "kbPipeline.progress": "\u89E3\u6790\u8FDB\u5EA6",
949
+ "kbPipeline.rerun": "\u91CD\u8DD1",
950
+ "kbPipeline.unknownStage": "\u672A\u77E5\u9636\u6BB5",
951
+ /* ── kbQa ── */
952
+ "kbQa.colAnswer": "\u7B54\u6848",
953
+ "kbQa.colQuestion": "\u95EE\u9898",
954
+ "kbQa.csvHint": "CSV \u6A21\u677F\uFF1Aquestion,answer\uFF08\u6BCF\u884C\u4E00\u5BF9\uFF0CUTF-8\uFF09",
955
+ "kbQa.deleteRow": "\u5220\u9664\u7B2C {p0} \u884C",
956
+ "kbQa.empty": "\u6682\u65E0\u8BA4\u8BC1\u95EE\u7B54\u5BF9",
957
+ "kbQa.importCsv": "\u5BFC\u5165 CSV",
958
+ /* ── kbRerank ── */
959
+ "kbRerank.after": "\u91CD\u6392\u540E",
960
+ "kbRerank.before": "\u91CD\u6392\u524D",
961
+ "kbRerank.compareTitle": "\u91CD\u6392\u5BF9\u6BD4",
962
+ "kbRerank.down": "\u4E0B\u964D {p0} \u4F4D",
963
+ "kbRerank.dropped": "\u843D\u9009",
964
+ "kbRerank.empty": "\u4E24\u4FA7\u5747\u4E3A\u7A7A\u2014\u2014\u8FD0\u884C\u68C0\u7D22\u540E\u518D\u5BF9\u6BD4",
965
+ "kbRerank.enableCompare": "\u542F\u7528\u91CD\u6392\u5BF9\u6BD4",
966
+ "kbRerank.newIn": "\u65B0\u8FDB",
967
+ "kbRerank.unmarked": "\u672A\u6807",
968
+ "kbRerank.up": "\u4E0A\u5347 {p0} \u4F4D",
969
+ /* ── kbRetrieval ── */
970
+ "kbRetrieval.breakdown": "\u62C6\u89E3",
971
+ "kbRetrieval.copyParams": "\u590D\u5236\u53C2\u6570 JSON",
972
+ "kbRetrieval.decreaseTopK": "\u51CF\u5C11 topK",
973
+ "kbRetrieval.empty": "\u8F93\u5165\u95EE\u9898\u5E76\u8FD0\u884C\uFF0C\u547D\u4E2D\u7ED3\u679C\u5C06\u51FA\u73B0\u5728\u8FD9\u91CC",
974
+ "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",
975
+ "kbRetrieval.hybridWeight": "\u6DF7\u5408\u6743\u91CD\uFF08\u5DE6\u8BED\u4E49\u53F3\u5173\u952E\u8BCD\uFF09",
976
+ "kbRetrieval.identityLabel": "\u68C0\u7D22\u8EAB\u4EFD",
977
+ "kbRetrieval.identityShort": "\u8EAB\u4EFD",
978
+ "kbRetrieval.increaseTopK": "\u589E\u52A0 topK",
979
+ "kbRetrieval.keywordHint": "\u5173\u952E\u8BCD\uFF1A\u5927\u5E93\u5FEB\u901F\u7CBE\u786E",
980
+ "kbRetrieval.layerLabel": "\u8FC7\u6EE4\u5C42",
981
+ "kbRetrieval.layerNone": "none\uFF1Afail-open\uFF0C\u65E0\u8EAB\u4EFD\u8FC7\u6EE4\u8FD4\u56DE\u5168\u90E8\u2014\u2014\u5371\u9669\uFF0C\u4EC5\u6F14\u793A",
982
+ "kbRetrieval.layerPost": "post-filter\uFF1A\u5206\u6570\u5DF2\u53EF\u89C2\u5BDF\u2014\u2014\u7F3A\u9677\u5C42\uFF0C\u4EC5\u6F14\u793A",
983
+ "kbRetrieval.layerPre": "pre-filter\uFF1AACL \u5728\u68C0\u7D22\u6267\u884C\u4F53\u5185\u751F\u6548\u2014\u2014\u5B89\u5168\u57FA\u7EBF",
984
+ "kbRetrieval.leakNote": "\u5206\u6BCD\u672A\u8FC7\u6EE4\u524D\u8BA1\u6570\u5C5E\u6CC4\u9732\uFF0C\u4E0D\u663E\u793A",
985
+ "kbRetrieval.modeHybrid": "\u6DF7\u5408",
986
+ "kbRetrieval.modeKeyword": "\u5173\u952E\u8BCD",
987
+ "kbRetrieval.modeLabel": "\u68C0\u7D22\u6A21\u5F0F",
988
+ "kbRetrieval.modeVector": "\u5411\u91CF",
989
+ "kbRetrieval.postFilterNotice": "post-filter\uFF1A\u5206\u6570\u5DF2\u5728\u8FC7\u6EE4\u524D\u4EA7\u751F\uFF08\u7F3A\u9677\u5C42\u6F14\u793A\uFF09",
990
+ "kbRetrieval.queryLabel": "\u68C0\u7D22\u95EE\u9898",
991
+ "kbRetrieval.queryPlaceholder": "\u68C0\u7D22\u95EE\u9898\uFF0CEnter \u8FD0\u884C",
992
+ "kbRetrieval.rerankLabel": "\u91CD\u6392",
993
+ "kbRetrieval.rerankThresholdOff": "\u9608\u503C \u5173 \xB7 \u5B58\u6D3B {p0}",
994
+ "kbRetrieval.rerankThresholdOn": "\u9608\u503C {p0} \xB7 \u5B58\u6D3B {p1}",
995
+ "kbRetrieval.running": "\u8FD0\u884C\u4E2D\u2026",
996
+ "kbRetrieval.thresholdLabel": "\u5206\u6570\u9608\u503C",
997
+ "kbRetrieval.thresholdValue": "\u9608\u503C N/A",
998
+ "kbRetrieval.vectorHint": "\u8BED\u4E49\uFF1A\u8DE8\u8BED\u8A00/\u65E0\u7CBE\u786E\u8BCD",
999
+ "kbRetrieval.vectorPercent": "\u8BED\u4E49 {p0}",
1000
+ "kbRetrieval.weightValue": "\u5411\u91CF {p0}% / \u5173\u952E\u8BCD {p1}%",
1001
+ /* ── kbReview ── */
1002
+ "kbReview.assignee": "\u5206\u914D\u4EBA",
1003
+ "kbReview.doneNext": "\u5B8C\u6210\u5E76\u4E0B\u4E00\u6761",
1004
+ "kbReview.empty": "\u6CA1\u6709\u5F85\u5BA1\u67E5\u6761\u76EE",
1005
+ "kbReview.emptyAssignee": "\u8BE5\u5206\u914D\u4EBA\u4E0B\u6CA1\u6709\u6761\u76EE",
1006
+ "kbReview.emptyQueue": "\u961F\u5217\u4E3A\u7A7A",
1007
+ "kbReview.kbCloseHint": "\u5173\u95ED\u63D0\u793A",
1008
+ "kbReview.kbSelectOption": "\u9009\u62E9\u9009\u9879",
1009
+ "kbReview.kbSwitchItem": "\u5207\u6362\u6761\u76EE",
1010
+ "kbReview.kbToggleHint": "\u663E\u793A/\u9690\u85CF\u672C\u63D0\u793A",
1011
+ "kbReview.shortcuts": "? \u5FEB\u6377\u952E",
1012
+ "kbReview.typeAnswer": "\u56DE\u7B54",
1013
+ "kbReview.typeMessage": "\u6D88\u606F",
1014
+ "kbReview.typeTrace": "\u8F68\u8FF9",
1015
+ "kbReview.unassigned": "\u672A\u5206\u914D",
1016
+ /* ── kbSandbox ── */
1017
+ "kbSandbox.noResolver": "\u5BBF\u4E3B\u672A\u63D0\u4F9B ui:// \u89E3\u6790\u5668",
1018
+ "kbSandbox.notReady": "kb-sandbox: \u5E94\u7528\u672A\u5C31\u7EEA",
1019
+ "kbSandbox.resolveFailed": "ui:// \u89E3\u6790\u5931\u8D25\uFF1A{p0}",
1020
+ "kbSandbox.timeout": "kb-sandbox: \u8C03\u7528\u8D85\u65F6\uFF08{p0}ms\uFF09",
1021
+ "kbSandbox.title": "MCP App \u6C99\u7BB1",
1022
+ /* ── kbSegment ── */
1023
+ "kbSegment.avgLength": "\u5747\u957F {p0}",
1024
+ "kbSegment.childNote": "\u5B50\u5206\u6BB5\u6309\u957F\u5EA6\u81EA\u52A8\u751F\u6210",
1025
+ "kbSegment.cleanBlankLines": "\u5408\u5E76\u8FDE\u7EED\u7A7A\u884C",
1026
+ "kbSegment.cleanEmails": "\u53BB\u9664\u90AE\u7BB1",
1027
+ "kbSegment.cleanLinks": "\u53BB\u9664\u94FE\u63A5",
1028
+ "kbSegment.empty": "\u6837\u672C\u4E3A\u7A7A\uFF0C\u6682\u65E0\u53EF\u9884\u89C8\u5206\u6BB5",
1029
+ "kbSegment.maxLengthLabel": "\u6700\u5927\u957F\u5EA6",
1030
+ "kbSegment.maxLengthPlaceholder": "\u5206\u6BB5\u6700\u5927\u957F\u5EA6",
1031
+ "kbSegment.modeAuto": "\u81EA\u52A8",
1032
+ "kbSegment.modeCustom": "\u81EA\u5B9A\u4E49",
1033
+ "kbSegment.modeLabel": "\u5206\u6BB5\u6A21\u5F0F",
1034
+ "kbSegment.modeNote": "\u5206\u6BB5\u6A21\u5F0F\u521B\u5EFA\u540E\u4E0D\u53EF\u66F4\u6539\uFF0C\u53C2\u6570\u53EF\u968F\u65F6\u8C03\u6574",
1035
+ "kbSegment.modeParentChild": "\u7236\u5B50",
1036
+ "kbSegment.overlapInvalid": "\u91CD\u53E0\u9700\u5C0F\u4E8E\u6700\u5927\u957F\u5EA6",
1037
+ "kbSegment.overlapLabel": "\u91CD\u53E0",
1038
+ "kbSegment.overlapPlaceholder": "\u5206\u6BB5\u91CD\u53E0",
1039
+ "kbSegment.previewNote": "\u5171 {p0} \u6BB5\uFF0C\u4EC5\u9884\u89C8\u524D {p1} \u6BB5",
1040
+ "kbSegment.segmentsCount": "{p0} \u6BB5",
1041
+ "kbSegment.separatorLabel": "\u5206\u9694\u7B26",
1042
+ "kbSegment.separatorPlaceholder": "\u5206\u6BB5\u5206\u9694\u7B26",
1043
+ "kbSegment.toggleTip": "\u70B9\u51FB\u5C55\u5F00/\u6536\u8D77",
1044
+ /* ── kbSources ── */
1045
+ "kbSources.cited": "\u88AB\u5F15 \xD7{p0}",
1046
+ "kbSources.empty": "\u4E0B\u4E00\u6761\u7B54\u6848\u5F15\u7528\u7684\u6BB5\u843D\u5C06\u51FA\u73B0\u5728\u8FD9\u91CC",
1047
+ /* ── kbSql ── */
1048
+ "kbSql.adminOnly": "\u4EC5\u7BA1\u7406\u5458\u53EF\u89C1",
1049
+ "kbSql.applyFix": "\u5E94\u7528\u4FEE\u590D\u5E76\u91CD\u8DD1",
1050
+ "kbSql.confirmRerun": "\u786E\u8BA4\u5E76\u91CD\u8DD1",
1051
+ "kbSql.editRerun": "\u7F16\u8F91\u91CD\u8DD1",
1052
+ "kbSql.fixReady": "\u68C0\u6D4B\u5230\u4E0A\u7248\u62A5\u9519\uFF0C\u4FEE\u590D\u5EFA\u8BAE\u5DF2\u5C31\u7EEA",
1053
+ "kbSql.generated": "\u751F\u6210\u7684 SQL",
1054
+ /* ── kbTrace ── */
1055
+ "kbTrace.empty": "\u6682\u65E0\u8C03\u7528\u94FE\u6570\u636E",
1056
+ "kbTrace.hits": "\u547D\u4E2D {p0}",
1057
+ /* ── kbVisibility ── */
1058
+ "kbVisibility.adminOnlyNote": "\u4EE5\u4E0A\u5BF9\u7167\u4EC5\u9650 admin \u5BA1\u8BA1",
1059
+ "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",
1060
+ "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",
1061
+ "kbVisibility.focusColumn": "\u805A\u7126\u8EAB\u4EFD {p0} \u7684\u5217",
1062
+ "kbVisibility.layerValue": "\u8FC7\u6EE4\u5C42\uFF1A{p0}",
1063
+ "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",
1064
+ "kbVisibility.postFilterNote": "post-filter\uFF1AtopK \u88AB\u65E0\u6743\u7ED3\u679C\u5360\u7528\u4E14\u76F8\u4F3C\u5EA6\u5206\u6570\u53EF\u88AB\u89C2\u5BDF",
1065
+ "kbVisibility.queryLabel": "\u67E5\u8BE2\uFF1A{p0}",
1066
+ "kbVisibility.safeCount": "\u5B89\u5168\u8BA1\u6570 {p0}",
1067
+ "kbVisibility.sourceUnavailable": "\u539F\u6587\u4E0D\u53EF\u7528",
1068
+ "kbVisibility.unnamedHit": "\u672A\u547D\u540D\u547D\u4E2D",
1069
+ /* ── kbWhoCan ── */
1070
+ "kbWhoCan.check": "\u68C0\u67E5",
1071
+ "kbWhoCan.checkIdentity": "\u68C0\u67E5\u8EAB\u4EFD",
1072
+ "kbWhoCan.daysUntil": "{p0} \u5929\u540E",
1073
+ "kbWhoCan.deniedBy": "\u88AB\u7B56\u7565\u62D2\u7EDD\uFF1A{p0}",
1074
+ "kbWhoCan.denyVeto": "\u88AB Deny \u4E00\u7968\u5426\u51B3",
1075
+ "kbWhoCan.direct": "\u76F4\u63A5",
1076
+ "kbWhoCan.expiresSoon": "\u6700\u8FD1\u5230\u671F {p0}",
1077
+ "kbWhoCan.hoursUntil": "{p0} \u5C0F\u65F6\u540E",
1078
+ "kbWhoCan.inherit": "\u7EE7\u627F",
1079
+ "kbWhoCan.link": "\u94FE\u63A5",
1080
+ "kbWhoCan.noDeny": "\u65E0 Deny \u751F\u6548",
1081
+ "kbWhoCan.noIdentity": "\u672A\u63D0\u4F9B\u53EF\u68C0\u67E5\u7684\u8EAB\u4EFD",
1082
+ "kbWhoCan.none": "\u672A\u547D\u4E2D\u4EFB\u4F55\u6388\u6743\u2014\u2014\u9ED8\u8BA4\u62D2\u7EDD",
1083
+ "kbWhoCan.recheckTip": "\u91CD\u65B0\u68C0\u67E5\u5F53\u524D\u8EAB\u4EFD\u7684\u6709\u6548\u6743\u9650",
1084
+ "kbWhoCan.stackRule": "\u53E0\u52A0\u89C4\u5219\uFF1A\u591A\u6765\u6E90\u5E76\u96C6 \u2192 {p0}\uFF1B{p1}",
1085
+ /* ── mentions ── */
1086
+ "mentions.create": "\u521B\u5EFA\u201C{p0}\u201D",
1087
+ "mentions.customBadge": "\u81EA\u5B9A\u4E49",
1088
+ "mentions.loading": "\u52A0\u8F7D\u4E2D\u2026",
1089
+ /* ── notification ── */
1090
+ "notification.groupBusy": "\u64CD\u4F5C\u7ED3\u675F\u540E\u53EF\u4EE5\u6536\u8D77\u8FD9\u7EC4\u901A\u77E5\u3002",
1091
+ "notification.groupUnread": "{count} \u6761\u540C\u7EC4\u901A\u77E5\uFF0C{unread} \u6761\u672A\u8BFB",
1092
+ "notification.groupCount": "{count} \u6761\u540C\u7EC4\u901A\u77E5",
1093
+ "notification.groupExpanded": "\u6536\u8D77\u8FD9\u7EC4\u901A\u77E5",
1094
+ "notification.ariaLabel": "\u901A\u77E5",
1095
+ "notification.viewDetails": "\u67E5\u770B\u8BE6\u60C5",
1096
+ /* ── pagination ── */
1097
+ "pagination.next": "\u4E0B\u4E00\u9875",
1098
+ "pagination.pageSize": "{p0} \u6761/\u9875",
1099
+ "pagination.prev": "\u4E0A\u4E00\u9875",
1100
+ /* ── select ── */
1101
+ "select.fieldLabel": "\u9009\u62E9\u9009\u9879",
1102
+ "select.noMatch": "\u65E0\u5339\u914D\u9879",
1103
+ "select.remove": "\u79FB\u9664 {p0}",
1104
+ "select.searchPlaceholder": "\u641C\u7D22\u2026",
1105
+ /* ── cascader / tree-select ── */
1106
+ "cascader.placeholder": "\u8BF7\u9009\u62E9",
1107
+ "cascader.noMatch": "\u65E0\u5339\u914D",
1108
+ "cascader.search": "\u641C\u7D22",
1109
+ "treeSelect.placeholder": "\u8BF7\u9009\u62E9",
1110
+ "treeSelect.noMatch": "\u65E0\u5339\u914D",
1111
+ "treeSelect.search": "\u641C\u7D22",
1112
+ /* ── tagInput ── */
1113
+ "tagInput.ariaLabel": "\u6807\u7B7E\u8F93\u5165\uFF0C\u5171 {p0} \u4E2A",
1114
+ "tagInput.remove": "\u79FB\u9664 {p0}",
1115
+ "tagInput.field": "\u6DFB\u52A0\u6807\u7B7E",
1116
+ "tagInput.added": "\u5DF2\u6DFB\u52A0 {p0} \u4E2A\u6807\u7B7E\u3002",
1117
+ "tagInput.removed": "\u5DF2\u79FB\u9664 {p0}\u3002",
1118
+ "tagInput.duplicate": "\u5DF2\u6709\u300C{p0}\u300D\uFF0C\u53EF\u4EE5\u7F16\u8F91\u540E\u91CD\u8BD5\u3002",
1119
+ "tagInput.limit": "\u6700\u591A {p0} \u4E2A\u6807\u7B7E\uFF0C\u8BF7\u5148\u79FB\u9664\u4E00\u4E2A\u3002",
1120
+ /* ── upload ── */
1121
+ "upload.remove": "\u79FB\u9664 {p0}",
1122
+ "upload.tooBig": "\u6587\u4EF6\u8D85\u8FC7 {p0}",
1123
+ "upload.tooMany": "\u6700\u591A {p0} \u4E2A\u6587\u4EF6",
1124
+ "upload.typeNotAllowed": "\u6587\u4EF6\u7C7B\u578B\u4E0D\u652F\u6301"
1125
+ };
1126
+ var current = { ...ICEN_LOCALE_ZH_CN };
1127
+ function t(key, vars) {
1128
+ const raw = current[key] ?? ICEN_LOCALE_ZH_CN[key];
1129
+ if (vars == null || Array.isArray(raw)) return raw;
1130
+ return raw.replace(/\{(\w+)\}/g, (m, name) => name in vars ? String(vars[name]) : m);
1131
+ }
1132
+
1133
+ // src/behaviors/svg-parse.ts
1134
+ function parseSvg(source) {
1135
+ if (typeof document === "undefined" || typeof DOMParser === "undefined") return null;
1136
+ const trimmed = source.trimStart();
1137
+ if (!trimmed.startsWith("<svg")) return null;
1138
+ const src = /^<svg(?![^>]*\bxmlns[=:])/i.test(trimmed) ? trimmed.replace(/^<svg/i, '<svg xmlns="http://www.w3.org/2000/svg"') : trimmed;
1139
+ let parsed;
1140
+ try {
1141
+ parsed = new DOMParser().parseFromString(src, "image/svg+xml");
1142
+ } catch {
1143
+ return null;
1144
+ }
1145
+ const root = parsed.documentElement;
1146
+ if (!root || root.tagName.toLowerCase() !== "svg" || parsed.querySelector("parsererror")) return null;
1147
+ const sanitize = (el) => {
1148
+ for (const attr of Array.from(el.attributes)) {
1149
+ const name = attr.name.toLowerCase();
1150
+ if (name.startsWith("on")) el.removeAttribute(attr.name);
1151
+ if ((name === "href" || name === "xlink:href") && attr.value.trim().toLowerCase().startsWith("javascript:")) {
1152
+ el.removeAttribute(attr.name);
1153
+ }
1154
+ }
1155
+ for (const child of Array.from(el.children)) {
1156
+ const tag = child.tagName.toLowerCase();
1157
+ if (tag === "script" || tag === "foreignobject") {
1158
+ child.remove();
1159
+ continue;
1160
+ }
1161
+ sanitize(child);
1162
+ }
1163
+ };
1164
+ sanitize(root);
1165
+ return document.importNode(root, true);
1166
+ }
1167
+
1168
+ // src/behaviors/url-safety.ts
1169
+ function safeUrl(uri) {
1170
+ const s = uri.replace(/[\t\n\r\0-\x1f\x7f]/g, "").trim().toLowerCase();
1171
+ if (!s) return void 0;
1172
+ if (s.startsWith("javascript:") || s.startsWith("vbscript:")) return void 0;
1173
+ if (/^data:\s*text\/html/.test(s)) return void 0;
1174
+ return uri;
1175
+ }
1176
+
1177
+ // src/behaviors/notification.ts
1178
+ var clocks = /* @__PURE__ */ new WeakMap();
1179
+ var KIND_SYMBOL = { success: "circle-check", warning: "triangle-alert", error: "circle-error", info: "circle-info" };
10
1180
  var cfg = {
11
1181
  position: "top-right",
12
1182
  maxStack: 5,
@@ -23,26 +1193,25 @@ function genId() {
23
1193
  return "notif-" + Math.random().toString(36).slice(2, 10);
24
1194
  }
25
1195
  function ensureContainer() {
26
- const sel = `.notification-container[data-notif-default]`;
1196
+ const sel = `.icen-notification-container[data-icen-notif-default]`;
27
1197
  const existing = document.body.querySelector(sel);
28
1198
  if (existing) {
29
1199
  syncContainerPosition(existing);
30
1200
  return existing;
31
1201
  }
32
1202
  const el = document.createElement("div");
33
- el.className = "notification-container";
1203
+ el.className = "icen-notification-container";
34
1204
  el.setAttribute("role", "region");
35
- el.setAttribute("aria-label", "\u901A\u77E5");
36
- el.dataset.notifDefault = "";
1205
+ el.setAttribute("aria-label", t("notification.ariaLabel"));
1206
+ el.dataset.icenNotifDefault = "";
37
1207
  syncContainerPosition(el);
38
1208
  document.body.appendChild(el);
39
1209
  return el;
40
1210
  }
41
1211
  function syncContainerPosition(el) {
42
- el.dataset.position = cfg.position;
1212
+ el.dataset.icenPosition = cfg.position;
43
1213
  }
44
1214
  var DEFAULT_PERSIST_KEY = "icen.ui.notifications";
45
- var knownPersistKeys = /* @__PURE__ */ new Set();
46
1215
  function persistKeyFor(p) {
47
1216
  if (p === true) return DEFAULT_PERSIST_KEY;
48
1217
  if (typeof p === "string" && p.length > 0) return p;
@@ -51,40 +1220,50 @@ function persistKeyFor(p) {
51
1220
  function recordPersist(record) {
52
1221
  return record.cfgRef ? record.cfgRef.persist : cfg.persist;
53
1222
  }
54
- function persistSave() {
55
- try {
56
- const groups = /* @__PURE__ */ new Map();
57
- for (const key of knownPersistKeys) groups.set(key, []);
58
- for (const r of store.values()) {
59
- const key = persistKeyFor(recordPersist(r));
60
- if (!key) continue;
61
- knownPersistKeys.add(key);
62
- let bucket = groups.get(key);
63
- if (!bucket) {
64
- bucket = [];
65
- groups.set(key, bucket);
66
- }
67
- if (r.opts.duration) continue;
68
- bucket.push({
69
- id: r.id,
70
- title: r.title,
71
- kind: r.kind,
72
- description: r.opts.description ?? "",
73
- tag: r.opts.tag,
74
- unread: r.opts.unread,
75
- priority: r.opts.priority,
76
- progress: r.opts.progress,
77
- progressLabel: r.opts.progressLabel,
78
- link: r.opts.link,
79
- linkLabel: r.opts.linkLabel,
80
- data: r.opts.data,
81
- createdAt: r.createdAt
82
- });
1223
+ function persistSave(removed = []) {
1224
+ if (!isBrowser()) return;
1225
+ const groups = /* @__PURE__ */ new Map();
1226
+ const bucket = (key) => {
1227
+ let items = groups.get(key);
1228
+ if (!items) {
1229
+ items = new Map(persistLoad(key).map((item) => [item.id, item]));
1230
+ groups.set(key, items);
83
1231
  }
84
- for (const [key, items] of groups) {
85
- localStorage.setItem(key, JSON.stringify(items));
1232
+ return items;
1233
+ };
1234
+ for (const r of removed) {
1235
+ const key = persistKeyFor(recordPersist(r));
1236
+ if (key) bucket(key).delete(r.id);
1237
+ }
1238
+ for (const r of store.values()) {
1239
+ const key = persistKeyFor(recordPersist(r));
1240
+ if (!key) continue;
1241
+ const items = bucket(key);
1242
+ if (r.duration > 0) {
1243
+ items.delete(r.id);
1244
+ continue;
1245
+ }
1246
+ items.set(r.id, {
1247
+ id: r.id,
1248
+ title: r.title,
1249
+ kind: r.kind,
1250
+ description: r.opts.description ?? "",
1251
+ tag: r.opts.tag,
1252
+ unread: r.opts.unread,
1253
+ priority: r.opts.priority,
1254
+ progress: r.opts.progress,
1255
+ progressLabel: r.opts.progressLabel,
1256
+ link: r.opts.link,
1257
+ linkLabel: r.opts.linkLabel,
1258
+ data: r.opts.data,
1259
+ createdAt: r.createdAt
1260
+ });
1261
+ }
1262
+ for (const [key, items] of groups) {
1263
+ try {
1264
+ localStorage.setItem(key, JSON.stringify([...items.values()]));
1265
+ } catch {
86
1266
  }
87
- } catch {
88
1267
  }
89
1268
  }
90
1269
  function persistLoad(key) {
@@ -92,14 +1271,50 @@ function persistLoad(key) {
92
1271
  const raw = localStorage.getItem(key);
93
1272
  if (!raw) return [];
94
1273
  const arr = JSON.parse(raw);
95
- return Array.isArray(arr) ? arr : [];
1274
+ if (!Array.isArray(arr)) return [];
1275
+ const unique = /* @__PURE__ */ new Map();
1276
+ for (const item of arr) {
1277
+ if (!item || typeof item !== "object" || typeof item.id !== "string" || !item.id || typeof item.title !== "string") continue;
1278
+ if (!["success", "warning", "error", "info"].includes(item.kind)) continue;
1279
+ const text = (value) => typeof value === "string" ? value : void 0;
1280
+ unique.set(item.id, {
1281
+ id: item.id,
1282
+ title: item.title,
1283
+ kind: item.kind,
1284
+ description: text(item.description),
1285
+ tag: text(item.tag),
1286
+ unread: item.unread === true,
1287
+ priority: item.priority === "high" ? "high" : "normal",
1288
+ progress: typeof item.progress === "number" && Number.isFinite(item.progress) ? Math.min(1, Math.max(0, item.progress)) : void 0,
1289
+ progressLabel: text(item.progressLabel),
1290
+ link: text(item.link),
1291
+ linkLabel: text(item.linkLabel),
1292
+ data: item.data,
1293
+ createdAt: typeof item.createdAt === "number" && Number.isFinite(item.createdAt) ? item.createdAt : void 0
1294
+ });
1295
+ }
1296
+ return [...unique.values()];
96
1297
  } catch {
97
1298
  return [];
98
1299
  }
99
1300
  }
1301
+ function configurePersistence(config, next, records) {
1302
+ const oldKey = persistKeyFor(config.persist), newKey = persistKeyFor(next);
1303
+ if (oldKey && newKey && oldKey !== newKey) {
1304
+ try {
1305
+ const items = persistLoad(oldKey).filter((item) => !records.some((r) => r.id === item.id));
1306
+ localStorage.setItem(oldKey, JSON.stringify(items));
1307
+ } catch {
1308
+ }
1309
+ }
1310
+ config.persist = next;
1311
+ persistSave();
1312
+ }
100
1313
  function restorePersisted(container, key, cfgRef) {
101
1314
  const records = [];
102
1315
  for (const item of persistLoad(key)) {
1316
+ if (store.has(item.id)) continue;
1317
+ removeRetiredCopies(item.id);
103
1318
  const record = {
104
1319
  id: item.id,
105
1320
  title: item.title,
@@ -129,6 +1344,7 @@ function restorePersisted(container, key, cfgRef) {
129
1344
  const el = renderNotification(record, container, () => handle);
130
1345
  record.el = el;
131
1346
  handle.el = el;
1347
+ attachTimer(record, handle);
132
1348
  pushToContainer(container, el, record.opts.priority ?? "normal");
133
1349
  records.push(record);
134
1350
  }
@@ -157,46 +1373,24 @@ function playSound(sound) {
157
1373
  gain.connect(audioCtx.destination);
158
1374
  osc.frequency.value = freq;
159
1375
  osc.type = "sine";
160
- const t = now + i * 0.08;
161
- gain.gain.setValueAtTime(0, t);
162
- gain.gain.linearRampToValueAtTime(0.08, t + 0.01);
163
- gain.gain.exponentialRampToValueAtTime(1e-3, t + 0.12);
164
- osc.start(t);
165
- osc.stop(t + 0.13);
1376
+ const t2 = now + i * 0.08;
1377
+ gain.gain.setValueAtTime(0, t2);
1378
+ gain.gain.linearRampToValueAtTime(0.08, t2 + 0.01);
1379
+ gain.gain.exponentialRampToValueAtTime(1e-3, t2 + 0.12);
1380
+ osc.start(t2);
1381
+ osc.stop(t2 + 0.13);
166
1382
  });
167
1383
  } catch {
168
1384
  }
169
1385
  }
170
- function stripUnsafeSvg(el) {
171
- for (const attr of Array.from(el.attributes)) {
172
- if (attr.name.toLowerCase().startsWith("on")) el.removeAttribute(attr.name);
173
- }
174
- for (const child of Array.from(el.children)) {
175
- const tag = child.tagName.toLowerCase();
176
- if (tag === "script" || tag === "foreignobject") child.remove();
177
- else stripUnsafeSvg(child);
178
- }
179
- }
180
- function sanitizeSvgIcon(source) {
181
- if (!source.trimStart().startsWith("<svg")) return null;
182
- try {
183
- const doc = new DOMParser().parseFromString(source, "image/svg+xml");
184
- const svg = doc.documentElement;
185
- if (!svg || svg.tagName.toLowerCase() !== "svg") return null;
186
- stripUnsafeSvg(svg);
187
- return document.importNode(svg, true);
188
- } catch {
189
- return null;
190
- }
191
- }
192
1386
  function buildIcon(record) {
193
1387
  const wrap = document.createElement("span");
194
- wrap.className = "notification-icon";
1388
+ wrap.className = "icen-notification-icon";
195
1389
  wrap.setAttribute("aria-hidden", "true");
196
1390
  const { icon, avatar } = record.opts;
197
- if (avatar) {
1391
+ if (avatar && safeUrl(avatar)) {
198
1392
  const img = document.createElement("img");
199
- img.className = "notification-avatar";
1393
+ img.className = "icen-notification-avatar";
200
1394
  img.src = avatar;
201
1395
  img.alt = "";
202
1396
  img.loading = "lazy";
@@ -207,58 +1401,89 @@ function buildIcon(record) {
207
1401
  wrap.style.display = "none";
208
1402
  return wrap;
209
1403
  }
1404
+ if (record.opts.iconName) {
1405
+ const symbol = createIcon(record.opts.iconName);
1406
+ if (symbol) {
1407
+ wrap.append(symbol);
1408
+ return wrap;
1409
+ }
1410
+ }
210
1411
  if (typeof icon === "string" && icon.length > 0) {
211
1412
  if (/^https?:\/\/|^data:image\//.test(icon) || icon.endsWith(".png") || icon.endsWith(".jpg") || icon.endsWith(".svg") || icon.endsWith(".webp")) {
212
1413
  const img = document.createElement("img");
213
- img.className = "notification-avatar";
1414
+ img.className = "icen-notification-avatar";
214
1415
  img.src = icon;
215
1416
  img.alt = "";
216
1417
  wrap.appendChild(img);
217
1418
  } else {
218
- const svg = sanitizeSvgIcon(icon);
1419
+ const svg = parseSvg(icon);
219
1420
  if (svg) wrap.appendChild(svg);
220
- else wrap.textContent = icon;
1421
+ if (!svg) wrap.append(createIcon(KIND_SYMBOL[record.kind]));
221
1422
  }
222
1423
  return wrap;
223
1424
  }
224
- const fallback = sanitizeSvgIcon(
225
- record.opts.progress !== void 0 && record.opts.progress >= 0 ? PROGRESS_ICON : KIND_ICON[record.kind]
226
- );
227
- if (fallback) wrap.appendChild(fallback);
1425
+ const progressing = record.kind === "info" && record.opts.progress !== void 0;
1426
+ const name = progressing ? record.opts.progress >= 1 ? "circle-check" : "spinner" : KIND_SYMBOL[record.kind];
1427
+ const fallback = createIcon(name);
1428
+ if (fallback) {
1429
+ if (name === "spinner") fallback.classList.add("icen-notification-busy-symbol");
1430
+ wrap.append(fallback);
1431
+ }
228
1432
  return wrap;
229
1433
  }
230
1434
  function buildTitle(title) {
231
1435
  const el = document.createElement("p");
232
- el.className = "notification-title";
233
- el.textContent = title;
1436
+ el.className = "icen-notification-title";
1437
+ setFeedbackText(el, title);
234
1438
  return el;
235
1439
  }
236
1440
  function buildDescription(text) {
237
1441
  const el = document.createElement("p");
238
- el.className = "notification-message";
1442
+ el.className = "icen-notification-message";
239
1443
  el.style.whiteSpace = "pre-wrap";
240
- el.textContent = text;
1444
+ setFeedbackText(el, text);
241
1445
  return el;
242
1446
  }
243
1447
  function buildActions(record) {
244
- const actions = record.opts.actions?.length ? record.opts.actions : record.opts.actionLabel ? [{ label: record.opts.actionLabel, onClick: record.opts.onAction }] : null;
1448
+ const actions = record.opts.actions !== void 0 ? record.opts.actions : record.opts.actionLabel ? [{ label: record.opts.actionLabel, onClick: record.opts.onAction }] : null;
245
1449
  if (!actions || actions.length === 0) return null;
246
1450
  const wrap = document.createElement("div");
247
- wrap.className = "notification-actions";
1451
+ wrap.className = "icen-notification-actions";
248
1452
  for (const a of actions) {
249
1453
  const btn = document.createElement("button");
250
1454
  btn.type = "button";
251
- btn.className = "notification-action";
252
- if (a.type === "primary") btn.classList.add("notification-action--primary");
253
- else if (a.type === "danger") btn.classList.add("notification-action--danger");
254
- btn.textContent = a.label;
1455
+ btn.className = "icen-notification-action";
1456
+ if (a.type === "primary") btn.classList.add("icen-notification-action--primary");
1457
+ else if (a.type === "danger") btn.classList.add("icen-notification-action--danger");
1458
+ setFeedbackText(btn, a.label);
255
1459
  btn.addEventListener("click", (ev) => {
256
1460
  ev.stopPropagation();
257
- if (a.onClick) {
258
- const ret = a.onClick();
259
- if (ret === false) return;
260
- }
261
- if (!a.keepOpen) dismissRecord(record.id);
1461
+ const card = record.el;
1462
+ if (!card || store.get(record.id) !== record) return;
1463
+ const content = card.querySelector(".icen-notification-content");
1464
+ setFeedbackError(content);
1465
+ runFeedbackAction(card, btn, a.onClick ?? (() => void 0), {
1466
+ busy(value) {
1467
+ const clock = clocks.get(record);
1468
+ if (value) {
1469
+ busyRecords.add(record);
1470
+ clock?.pause("action");
1471
+ clock?.resume("failure");
1472
+ } else {
1473
+ busyRecords.delete(record);
1474
+ clock?.resume("action");
1475
+ }
1476
+ if (card.parentElement) syncNotificationGroups(card.parentElement);
1477
+ },
1478
+ complete(accepted) {
1479
+ if (!accepted) clocks.get(record)?.pause("failure");
1480
+ else if (!a.keepOpen && store.get(record.id) === record) dismissRecord(record.id);
1481
+ },
1482
+ error() {
1483
+ clocks.get(record)?.pause("failure");
1484
+ setFeedbackError(content, record.opts.actionError ?? t("common.actionFailed"));
1485
+ }
1486
+ });
262
1487
  });
263
1488
  wrap.appendChild(btn);
264
1489
  }
@@ -266,13 +1491,14 @@ function buildActions(record) {
266
1491
  }
267
1492
  function buildLink(record) {
268
1493
  const { link, linkLabel } = record.opts;
269
- if (!link) return null;
1494
+ const href = link ? safeUrl(link) : void 0;
1495
+ if (!href) return null;
270
1496
  const wrap = document.createElement("div");
271
- wrap.className = "notification-link-wrap";
1497
+ wrap.className = "icen-notification-link-wrap";
272
1498
  const a = document.createElement("a");
273
- a.className = "notification-link";
274
- a.href = link;
275
- a.textContent = linkLabel ?? "\u67E5\u770B\u8BE6\u60C5";
1499
+ a.className = "icen-notification-link";
1500
+ a.href = href;
1501
+ a.textContent = linkLabel ?? t("notification.viewDetails");
276
1502
  a.addEventListener("click", (ev) => ev.stopPropagation());
277
1503
  wrap.appendChild(a);
278
1504
  return wrap;
@@ -281,23 +1507,23 @@ function buildProgressBar(record) {
281
1507
  const { progress, progressLabel } = record.opts;
282
1508
  if (progress === void 0 || progress < 0) return null;
283
1509
  const wrap = document.createElement("div");
284
- wrap.className = "notification-progress";
1510
+ wrap.className = "icen-notification-progress";
285
1511
  const track = document.createElement("div");
286
- track.className = "notification-progress-track";
1512
+ track.className = "icen-notification-progress-track";
287
1513
  const fill = document.createElement("div");
288
- fill.className = "notification-progress-bar";
1514
+ fill.className = "icen-notification-progress-bar";
289
1515
  const pct = Math.min(100, Math.max(0, progress * 100));
290
1516
  fill.style.width = pct + "%";
291
1517
  track.appendChild(fill);
292
1518
  wrap.appendChild(track);
293
1519
  if (progressLabel) {
294
1520
  const lbl = document.createElement("span");
295
- lbl.className = "notification-progress-label";
1521
+ lbl.className = "icen-notification-progress-label";
296
1522
  lbl.textContent = progressLabel;
297
1523
  wrap.appendChild(lbl);
298
1524
  } else if (progress > 0) {
299
1525
  const lbl = document.createElement("span");
300
- lbl.className = "notification-progress-label";
1526
+ lbl.className = "icen-notification-progress-label";
301
1527
  lbl.textContent = Math.round(pct) + "%";
302
1528
  wrap.appendChild(lbl);
303
1529
  }
@@ -307,10 +1533,10 @@ function buildCountdownBar(record) {
307
1533
  if (!record.duration || record.duration <= 0) return null;
308
1534
  if (record.opts.showCountdown === false) return null;
309
1535
  const bar = document.createElement("div");
310
- bar.className = "notification-countdown";
1536
+ bar.className = "icen-notification-countdown";
311
1537
  bar.setAttribute("aria-hidden", "true");
312
1538
  const fill = document.createElement("div");
313
- fill.className = "notification-countdown-fill";
1539
+ fill.className = "icen-notification-countdown-fill";
314
1540
  fill.style.animationDuration = record.duration + "ms";
315
1541
  fill.style.animationPlayState = "running";
316
1542
  bar.appendChild(fill);
@@ -319,19 +1545,19 @@ function buildCountdownBar(record) {
319
1545
  function syncCountdownBar(record) {
320
1546
  const el = record.el;
321
1547
  if (!el) return;
322
- const existing = el.querySelector(".notification-countdown");
1548
+ const existing = el.querySelector(".icen-notification-countdown");
323
1549
  if (record.duration <= 0 || record.opts.showCountdown === false) {
324
1550
  existing?.remove();
325
1551
  return;
326
1552
  }
327
1553
  let fill;
328
1554
  if (existing) {
329
- fill = existing.querySelector(".notification-countdown-fill");
1555
+ fill = existing.querySelector(".icen-notification-countdown-fill");
330
1556
  } else {
331
1557
  const bar = buildCountdownBar(record);
332
1558
  if (!bar) return;
333
1559
  el.appendChild(bar);
334
- fill = bar.querySelector(".notification-countdown-fill");
1560
+ fill = bar.querySelector(".icen-notification-countdown-fill");
335
1561
  }
336
1562
  if (fill) {
337
1563
  fill.style.animation = "none";
@@ -345,9 +1571,10 @@ function buildClose(record) {
345
1571
  if (record.opts.closable === false) return null;
346
1572
  const btn = document.createElement("button");
347
1573
  btn.type = "button";
348
- btn.className = "notification-close";
349
- btn.setAttribute("aria-label", "\u5173\u95ED");
350
- const svg = sanitizeSvgIcon(CLOSE_SVG);
1574
+ btn.className = "icen-notification-close icen-icon-action";
1575
+ btn.setAttribute("data-icen-reveal", "");
1576
+ btn.setAttribute("aria-label", t("common.close"));
1577
+ const svg = createIcon("close");
351
1578
  if (svg) btn.appendChild(svg);
352
1579
  btn.addEventListener("click", (ev) => {
353
1580
  ev.stopPropagation();
@@ -357,25 +1584,32 @@ function buildClose(record) {
357
1584
  }
358
1585
  function renderNotification(record, container, getHandle) {
359
1586
  const el = document.createElement("div");
360
- let cls = record.kind === "info" ? "notification" : `notification notification--${record.kind}`;
1587
+ let cls = record.kind === "info" ? "icen-notification" : `icen-notification icen-notification--${record.kind}`;
1588
+ rememberFeedbackOrigin(el);
361
1589
  if (record.opts.priority === "high") cls += " is-priority";
362
1590
  if (record.opts.unread) cls += " is-unread";
363
1591
  if (record.opts.progress !== void 0 && record.opts.progress >= 0) cls += " is-progress";
364
- if (record.opts.avatar) cls += " has-avatar";
1592
+ if (record.opts.avatar) cls += " icen-has-avatar";
1593
+ if ((record.opts.progress ?? 0) >= 1) cls += " is-complete";
365
1594
  if (record.opts.onClick) {
366
1595
  cls += " is-clickable";
367
- el.setAttribute("role", "button");
368
- el.tabIndex = 0;
369
- } else {
370
- el.setAttribute("role", "alert");
371
1596
  }
1597
+ el.setAttribute("role", record.kind === "error" || record.kind === "warning" ? "alert" : "status");
372
1598
  el.className = cls;
373
1599
  el.id = record.id;
374
1600
  const icon = buildIcon(record);
375
1601
  el.appendChild(icon);
376
1602
  const content = document.createElement("div");
377
- content.className = "notification-content";
378
- content.appendChild(buildTitle(record.title));
1603
+ content.className = "icen-notification-content";
1604
+ const title = buildTitle(record.title);
1605
+ if (record.opts.onClick) {
1606
+ const open = document.createElement("button");
1607
+ open.type = "button";
1608
+ open.className = "icen-notification-open";
1609
+ setFeedbackText(open, record.title);
1610
+ title.replaceChildren(open);
1611
+ }
1612
+ content.appendChild(title);
379
1613
  if (record.opts.description) content.appendChild(buildDescription(record.opts.description));
380
1614
  const actions = buildActions(record);
381
1615
  if (actions) content.appendChild(actions);
@@ -390,18 +1624,117 @@ function renderNotification(record, container, getHandle) {
390
1624
  if (countdown) el.appendChild(countdown);
391
1625
  if (record.opts.onClick) {
392
1626
  const onClick = record.opts.onClick;
393
- const handleClick = () => onClick(getHandle());
394
- el.addEventListener("click", handleClick);
395
- el.addEventListener("keydown", (ev) => {
396
- if (ev.key === "Enter" || ev.key === " ") {
397
- ev.preventDefault();
398
- handleClick();
399
- }
1627
+ el.addEventListener("click", (ev) => {
1628
+ const control = ev.target instanceof Element ? ev.target.closest('button,a,input,select,textarea,[role="button"]') : null;
1629
+ if (control && !control.classList.contains("icen-notification-open")) return;
1630
+ onClick(getHandle());
400
1631
  });
401
1632
  }
402
1633
  record.el = el;
403
1634
  return el;
404
1635
  }
1636
+ var groupStates = /* @__PURE__ */ new WeakMap();
1637
+ var busyRecords = /* @__PURE__ */ new WeakSet();
1638
+ function syncNotificationGroups(container) {
1639
+ const records = Array.from(container.querySelectorAll(":scope > .icen-notification:not(.is-leaving)")).map((el) => store.get(el.id)).filter((r) => Boolean(r?.el && r.el.parentElement === container));
1640
+ const groups = /* @__PURE__ */ new Map();
1641
+ let states = groupStates.get(container);
1642
+ if (!states) {
1643
+ states = /* @__PURE__ */ new Map();
1644
+ groupStates.set(container, states);
1645
+ }
1646
+ for (const record of records) {
1647
+ const tag = record.opts.tag;
1648
+ if (tag) {
1649
+ const members = groups.get(tag) ?? [];
1650
+ members.push(record);
1651
+ groups.set(tag, members);
1652
+ }
1653
+ }
1654
+ for (const tag of states.keys()) if (!groups.has(tag)) states.delete(tag);
1655
+ const representatives = /* @__PURE__ */ new Set();
1656
+ const active = document.activeElement;
1657
+ let restore = null;
1658
+ for (const [tag, members] of groups) {
1659
+ if (members.length < 2) {
1660
+ states.delete(tag);
1661
+ continue;
1662
+ }
1663
+ let state = states.get(tag);
1664
+ if (!state) {
1665
+ state = { expanded: false };
1666
+ states.set(tag, state);
1667
+ }
1668
+ const high = members.filter((r) => r.opts.priority === "high");
1669
+ const eligible = high.length ? high : members;
1670
+ const representative = Array.from(store.values()).filter((r) => eligible.includes(r)).at(-1);
1671
+ const card = representative.el;
1672
+ representatives.add(card);
1673
+ const pending2 = members.some((r) => busyRecords.has(r));
1674
+ const focused = members.some((r) => r !== representative && r.el.contains(active) && !(active instanceof Element && active.closest(".icen-notification-group-toggle")));
1675
+ if (pending2 || focused) state.expanded = true;
1676
+ let button = card.querySelector(".icen-notification-group-toggle");
1677
+ if (!button) {
1678
+ button = document.createElement("button");
1679
+ button.type = "button";
1680
+ button.className = "icen-notification-group-toggle";
1681
+ button.addEventListener("click", (event) => {
1682
+ event.stopPropagation();
1683
+ const current2 = groupStates.get(container)?.get(button.dataset.icenNotifGroup);
1684
+ if (!current2) return;
1685
+ if (button.getAttribute("aria-disabled") === "true") return;
1686
+ current2.expanded = !current2.expanded;
1687
+ syncNotificationGroups(container);
1688
+ });
1689
+ card.querySelector(".icen-notification-content").append(button);
1690
+ }
1691
+ button.dataset.icenNotifGroup = tag;
1692
+ button.setAttribute("aria-expanded", String(state.expanded));
1693
+ button.setAttribute("aria-controls", members.filter((r) => r !== representative).map((r) => r.id).join(" "));
1694
+ if (pending2 && state.expanded) {
1695
+ button.setAttribute("aria-disabled", "true");
1696
+ button.setAttribute("aria-description", t("notification.groupBusy"));
1697
+ } else {
1698
+ button.removeAttribute("aria-disabled");
1699
+ button.removeAttribute("aria-description");
1700
+ }
1701
+ const unread = members.filter((r) => r.opts.unread).length;
1702
+ const text = document.createElement("bdi");
1703
+ text.textContent = t(state.expanded ? "notification.groupExpanded" : unread ? "notification.groupUnread" : "notification.groupCount", { count: members.length, unread });
1704
+ const icon = createIcon("chevron-down");
1705
+ button.replaceChildren(text, icon);
1706
+ for (const member of members) {
1707
+ const el = member.el, hide = !state.expanded && member !== representative;
1708
+ const revealing = el.hidden && !hide;
1709
+ el.hidden = hide;
1710
+ el.inert = hide;
1711
+ el.classList.toggle("is-group-hidden", hide);
1712
+ if (hide) el.classList.remove("is-group-revealing");
1713
+ else if (revealing) el.classList.add("is-group-revealing");
1714
+ if (hide) clocks.get(member)?.pause("group");
1715
+ else clocks.get(member)?.resume("group");
1716
+ if (el !== card && el.querySelector(".icen-notification-group-toggle")?.contains(active)) restore = button;
1717
+ }
1718
+ }
1719
+ for (const record of records) {
1720
+ const el = record.el;
1721
+ if (!representatives.has(el)) {
1722
+ const previous = el.querySelector(".icen-notification-group-toggle");
1723
+ if (previous?.contains(active) && !restore) {
1724
+ restore = el.querySelector(".icen-notification-close,.icen-notification-open,.icen-notification-action");
1725
+ if (!restore) restoreFeedbackFocus(el);
1726
+ }
1727
+ previous?.remove();
1728
+ }
1729
+ if (!record.opts.tag || (groups.get(record.opts.tag)?.length ?? 0) < 2) {
1730
+ el.hidden = false;
1731
+ el.inert = false;
1732
+ el.classList.remove("is-group-hidden");
1733
+ clocks.get(record)?.resume("group");
1734
+ }
1735
+ }
1736
+ restore?.focus({ preventScroll: true });
1737
+ }
405
1738
  function pushToContainer(container, el, priority) {
406
1739
  if (priority === "high") {
407
1740
  const firstNormal = Array.from(container.children).find(
@@ -416,107 +1749,98 @@ function pushToContainer(container, el, priority) {
416
1749
  var LEAVE_FALLBACK_MS = 360;
417
1750
  function removeOne(el, onClose) {
418
1751
  if (el.classList.contains("is-leaving")) return;
1752
+ restoreFeedbackFocus(el);
1753
+ el.inert = true;
1754
+ el.setAttribute("aria-hidden", "true");
419
1755
  el.classList.add("is-leaving");
420
1756
  let done = false;
421
1757
  const finish = () => {
422
1758
  if (done) return;
423
1759
  done = true;
1760
+ el.removeEventListener("transitionend", onTransition);
1761
+ window.clearTimeout(fallback);
424
1762
  el.remove();
425
1763
  onClose?.();
426
1764
  };
427
- el.addEventListener("transitionend", finish, { once: true });
428
- window.setTimeout(finish, LEAVE_FALLBACK_MS);
1765
+ const onTransition = (event) => {
1766
+ if (event.target === el) finish();
1767
+ };
1768
+ el.addEventListener("transitionend", onTransition);
1769
+ const fallback = window.setTimeout(finish, LEAVE_FALLBACK_MS);
429
1770
  }
430
1771
  function trimStack(container, maxStack, remove) {
431
- for (; ; ) {
432
- const items = Array.from(container.querySelectorAll(":scope > .notification"));
433
- if (items.length <= maxStack) return;
434
- const target = items.find((it) => !it.classList.contains("is-priority")) ?? items[0];
435
- if (!target) return;
436
- const rec = target.id ? store.get(target.id) : void 0;
437
- if (rec?.timer) window.clearTimeout(rec.timer);
438
- if (target.classList.contains("is-leaving")) {
439
- target.remove();
440
- if (target.id) remove(target.id);
441
- continue;
442
- }
443
- removeOne(target);
444
- if (target.id) remove(target.id);
445
- return;
1772
+ const rows = Array.from(container.querySelectorAll(":scope > .icen-notification:not(.is-leaving)"));
1773
+ while (rows.length > maxStack) {
1774
+ const read = rows.findIndex((item) => !item.classList.contains("is-priority") && !item.classList.contains("is-unread"));
1775
+ const index = read >= 0 ? read : rows.findIndex((item) => !item.classList.contains("is-priority"));
1776
+ const target = rows.splice(index < 0 ? 0 : index, 1)[0];
1777
+ const record = store.get(target.id);
1778
+ if (record) stopRuntime(record);
1779
+ remove(target.id);
1780
+ if (record) persistSave([record]);
1781
+ removeOne(target, record ? () => record.opts.onClose?.(makeHandle(record)) : void 0);
1782
+ syncNotificationGroups(container);
446
1783
  }
447
1784
  }
448
1785
  function attachTimer(record, handle) {
449
- const el = record.el;
450
- if (!el) return;
451
- const start = () => {
452
- if (record.timer) window.clearTimeout(record.timer);
453
- record.timer = 0;
454
- if (record.remaining <= 0) return;
455
- record.startedAt = Date.now();
456
- record.timer = window.setTimeout(() => dismissRecord(record.id), record.remaining);
457
- record.paused = false;
1786
+ if (!record.el) return;
1787
+ let clock = clocks.get(record);
1788
+ if (!clock) {
1789
+ clock = createFeedbackClock(record.el, record, () => dismissRecord(record.id), ".icen-notification-countdown-fill", () => record.opts.pauseOnHover ?? record.cfgRef?.pauseOnHover ?? cfg.pauseOnHover);
1790
+ clocks.set(record, clock);
1791
+ }
1792
+ record.restartTimer = () => clock.reset(record.duration);
1793
+ handle.pause = () => clock.pause();
1794
+ handle.resume = () => {
1795
+ clock.resume("failure");
1796
+ clock.resume();
458
1797
  };
459
- const pause = () => {
460
- if (record.paused) return;
461
- if (!record.timer) return;
1798
+ }
1799
+ function stopRuntime(record) {
1800
+ clocks.get(record)?.destroy();
1801
+ clocks.delete(record);
1802
+ if (record.timer) {
462
1803
  window.clearTimeout(record.timer);
463
1804
  record.timer = 0;
464
- record.remaining = Math.max(0, record.remaining - (Date.now() - record.startedAt));
465
- record.paused = true;
466
- el.classList.add("is-paused");
467
- const fill = el.querySelector(".notification-countdown-fill");
468
- if (fill) fill.style.animationPlayState = "paused";
469
- };
470
- const resume = () => {
471
- if (!record.paused) return;
472
- record.paused = false;
473
- el.classList.remove("is-paused");
474
- const fill = el.querySelector(".notification-countdown-fill");
475
- if (fill) fill.style.animationPlayState = "running";
476
- if (record.remaining <= 0) {
477
- dismissRecord(record.id);
478
- return;
479
- }
480
- start();
481
- };
482
- record.restartTimer = () => {
483
- record.paused = false;
484
- el.classList.remove("is-paused");
485
- start();
486
- };
487
- const pauseOnHover = record.opts.pauseOnHover ?? record.cfgRef?.pauseOnHover ?? cfg.pauseOnHover;
488
- if (pauseOnHover && !record.hoverBound) {
489
- record.hoverBound = true;
490
- el.addEventListener("mouseenter", () => handle.pause());
491
- el.addEventListener("mouseleave", () => handle.resume());
492
- }
493
- handle.pause = pause;
494
- handle.resume = resume;
495
- if (record.duration > 0) {
496
- record.remaining = record.duration;
497
- start();
498
1805
  }
1806
+ if (record.el) cancelFeedbackAction(record.el);
499
1807
  }
500
1808
  function makeHandle(record) {
501
1809
  const handle = {
502
1810
  id: record.id,
503
1811
  el: record.el ?? document.createElement("div"),
504
- dismiss: () => dismissRecord(record.id),
505
- update: (patch) => updateRecord(record.id, patch),
506
- setProgress: (value, label) => updateRecord(record.id, {
507
- progress: Math.min(1, Math.max(0, value)),
508
- progressLabel: label
509
- }),
510
- markRead: () => updateRecord(record.id, { unread: false }),
511
- pause: () => {
1812
+ dismiss: () => {
1813
+ if (store.get(record.id) === record) dismissRecord(record.id);
1814
+ },
1815
+ update: (patch) => {
1816
+ if (store.get(record.id) === record) updateRecord(record.id, patch);
1817
+ },
1818
+ setProgress: (value, label) => {
1819
+ if (store.get(record.id) === record) updateRecord(record.id, {
1820
+ progress: Math.min(1, Math.max(0, value)),
1821
+ progressLabel: label
1822
+ });
512
1823
  },
1824
+ markRead: () => {
1825
+ if (store.get(record.id) === record) updateRecord(record.id, { unread: false });
1826
+ },
1827
+ pause: () => clocks.get(record)?.pause(),
513
1828
  resume: () => {
1829
+ clocks.get(record)?.resume("failure");
1830
+ clocks.get(record)?.resume();
514
1831
  }
515
1832
  };
516
1833
  return handle;
517
1834
  }
1835
+ function removeRetiredCopies(id) {
1836
+ document.querySelectorAll(".icen-notification.is-leaving").forEach((el) => {
1837
+ if (el.id === id) el.remove();
1838
+ });
1839
+ }
518
1840
  function pushRecord(title, kind, opts, container, maxStack, cfgRef, ownerStore) {
519
1841
  const id = opts.id ?? genId();
1842
+ if (store.has(id)) dismissRecord(id, true);
1843
+ removeRetiredCopies(id);
520
1844
  const duration = opts.duration ?? 0;
521
1845
  const record = {
522
1846
  id,
@@ -546,6 +1870,7 @@ function pushRecord(title, kind, opts, container, maxStack, cfgRef, ownerStore)
546
1870
  ownerStore?.delete(removedId);
547
1871
  store.delete(removedId);
548
1872
  });
1873
+ syncNotificationGroups(container);
549
1874
  persistSave();
550
1875
  playSound(cfgRef?.sound ?? cfg.sound);
551
1876
  opts.onShow?.(handle);
@@ -554,29 +1879,34 @@ function pushRecord(title, kind, opts, container, maxStack, cfgRef, ownerStore)
554
1879
  function showRecord(title, kind, opts) {
555
1880
  if (!isBrowser()) return null;
556
1881
  const container = ensureContainer();
557
- const id = opts.id ?? genId();
558
- if (store.has(id)) dismissRecord(id);
559
1882
  return pushRecord(title, kind, opts, container, cfg.maxStack);
560
1883
  }
561
- function dismissRecord(id) {
1884
+ function dismissRecord(id, immediate = false) {
562
1885
  const record = store.get(id);
563
1886
  if (!record) {
564
1887
  const el = document.getElementById(id);
565
- if (el && el.classList.contains("notification")) removeOne(el);
1888
+ if (el && el.classList.contains("icen-notification")) removeOne(el);
566
1889
  return;
567
1890
  }
568
- if (record.timer) window.clearTimeout(record.timer);
1891
+ stopRuntime(record);
569
1892
  const handle = makeHandle(record);
570
1893
  const onClose = record.opts.onClose;
571
1894
  store.delete(id);
572
1895
  record.ownerStore?.delete(id);
573
- if (record.el) removeOne(record.el, () => onClose?.(handle));
1896
+ if (record.el && immediate) {
1897
+ restoreFeedbackFocus(record.el);
1898
+ record.el.remove();
1899
+ onClose?.(handle);
1900
+ } else if (record.el) removeOne(record.el, () => onClose?.(handle));
574
1901
  else onClose?.(handle);
575
- persistSave();
1902
+ if (record.el?.parentElement) syncNotificationGroups(record.el.parentElement);
1903
+ persistSave([record]);
576
1904
  }
577
1905
  function updateRecord(id, patch) {
578
1906
  const record = store.get(id);
579
1907
  if (!record) return;
1908
+ const wasComplete = (record.opts.progress ?? 0) >= 1;
1909
+ const wasProgress = record.opts.progress !== void 0;
580
1910
  if (patch.title !== void 0) record.title = patch.title;
581
1911
  if (patch.description !== void 0) record.opts.description = patch.description;
582
1912
  if (patch.duration !== void 0) {
@@ -590,33 +1920,54 @@ function updateRecord(id, patch) {
590
1920
  if (patch.tag !== void 0) record.opts.tag = patch.tag;
591
1921
  if (patch.priority !== void 0) record.opts.priority = patch.priority;
592
1922
  if (patch.icon !== void 0) record.opts.icon = patch.icon;
1923
+ if (patch.iconName !== void 0) record.opts.iconName = patch.iconName;
593
1924
  if (patch.avatar !== void 0) record.opts.avatar = patch.avatar;
594
1925
  if (patch.link !== void 0) record.opts.link = patch.link;
595
1926
  if (patch.linkLabel !== void 0) record.opts.linkLabel = patch.linkLabel;
596
1927
  const el = record.el;
597
1928
  if (!el) return;
1929
+ if (patch.actions !== void 0) {
1930
+ cancelFeedbackAction(el);
1931
+ if (store.get(id) !== record) return;
1932
+ const old = el.querySelector(".icen-notification-actions"), owned = old?.contains(document.activeElement);
1933
+ const next = buildActions(record), target = next?.querySelector("button") ?? el.querySelector(".icen-notification-close");
1934
+ if (owned && !target) restoreFeedbackFocus(el);
1935
+ old?.remove();
1936
+ if (next) el.querySelector(".icen-notification-content")?.append(next);
1937
+ if (owned) target?.focus({ preventScroll: true });
1938
+ if (!el.contains(document.activeElement)) clocks.get(record)?.resume("focus");
1939
+ }
1940
+ if (patch.icon !== void 0 || patch.iconName !== void 0 || patch.avatar !== void 0 || patch.progress !== void 0 && (!wasProgress || wasComplete !== patch.progress >= 1)) {
1941
+ el.querySelector(".icen-notification-icon")?.replaceWith(buildIcon(record));
1942
+ el.classList.toggle("icen-has-avatar", Boolean(record.opts.avatar));
1943
+ }
1944
+ if (patch.link !== void 0 || patch.linkLabel !== void 0) {
1945
+ el.querySelector(".icen-notification-link-wrap")?.remove();
1946
+ const link = buildLink(record);
1947
+ if (link) el.querySelector(".icen-notification-content")?.append(link);
1948
+ }
598
1949
  if (patch.duration !== void 0 && el.isConnected) {
599
1950
  syncCountdownBar(record);
600
1951
  if (record.restartTimer) record.restartTimer();
601
1952
  else if (patch.duration > 0) attachTimer(record, makeHandle(record));
602
1953
  }
603
1954
  if (patch.title !== void 0) {
604
- const t = el.querySelector(".notification-title");
605
- if (t) t.textContent = patch.title;
1955
+ const t2 = el.querySelector(".icen-notification-title");
1956
+ if (t2) setFeedbackText(t2.querySelector(".icen-notification-open") ?? t2, patch.title);
606
1957
  }
607
1958
  if (patch.description !== void 0) {
608
- let m = el.querySelector(".notification-message");
1959
+ let m = el.querySelector(".icen-notification-message");
609
1960
  if (patch.description) {
610
1961
  if (!m) {
611
1962
  m = document.createElement("p");
612
- m.className = "notification-message";
1963
+ m.className = "icen-notification-message";
613
1964
  m.style.whiteSpace = "pre-wrap";
614
- const content = el.querySelector(".notification-content");
615
- const titleEl = content?.querySelector(".notification-title");
1965
+ const content = el.querySelector(".icen-notification-content");
1966
+ const titleEl = content?.querySelector(".icen-notification-title");
616
1967
  if (titleEl && titleEl.nextSibling) content?.insertBefore(m, titleEl.nextSibling);
617
1968
  else content?.appendChild(m);
618
1969
  }
619
- m.textContent = patch.description;
1970
+ setFeedbackText(m, patch.description);
620
1971
  } else if (m) {
621
1972
  m.remove();
622
1973
  }
@@ -626,33 +1977,36 @@ function updateRecord(id, patch) {
626
1977
  }
627
1978
  if (patch.priority !== void 0) {
628
1979
  el.classList.toggle("is-priority", patch.priority === "high");
1980
+ if (el.parentElement) pushToContainer(el.parentElement, el, patch.priority);
629
1981
  }
630
1982
  if (patch.progress !== void 0 || patch.progressLabel !== void 0) {
631
1983
  el.classList.add("is-progress");
632
- let progWrap = el.querySelector(".notification-progress");
1984
+ el.classList.toggle("is-complete", (record.opts.progress ?? 0) >= 1);
1985
+ let progWrap = el.querySelector(".icen-notification-progress");
633
1986
  const pct = Math.min(100, Math.max(0, (record.opts.progress ?? 0) * 100));
634
1987
  if (!progWrap) {
635
1988
  progWrap = document.createElement("div");
636
- progWrap.className = "notification-progress";
1989
+ progWrap.className = "icen-notification-progress";
637
1990
  const track = document.createElement("div");
638
- track.className = "notification-progress-track";
1991
+ track.className = "icen-notification-progress-track";
639
1992
  const fill2 = document.createElement("div");
640
- fill2.className = "notification-progress-bar";
1993
+ fill2.className = "icen-notification-progress-bar";
641
1994
  track.appendChild(fill2);
642
1995
  progWrap.appendChild(track);
643
- el.querySelector(".notification-content")?.appendChild(progWrap);
1996
+ el.querySelector(".icen-notification-content")?.appendChild(progWrap);
644
1997
  }
645
- const fill = progWrap.querySelector(".notification-progress-bar");
1998
+ const fill = progWrap.querySelector(".icen-notification-progress-bar");
646
1999
  if (fill) fill.style.width = pct + "%";
647
- let lbl = progWrap.querySelector(".notification-progress-label");
2000
+ let lbl = progWrap.querySelector(".icen-notification-progress-label");
648
2001
  const labelText = record.opts.progressLabel ?? Math.round(pct) + "%";
649
2002
  if (!lbl) {
650
2003
  lbl = document.createElement("span");
651
- lbl.className = "notification-progress-label";
2004
+ lbl.className = "icen-notification-progress-label";
652
2005
  progWrap.appendChild(lbl);
653
2006
  }
654
2007
  lbl.textContent = labelText;
655
2008
  }
2009
+ if (el.parentElement) syncNotificationGroups(el.parentElement);
656
2010
  persistSave();
657
2011
  }
658
2012
  function confirmDialog(title, opts = {}) {
@@ -667,8 +2021,8 @@ function confirmDialog(title, opts = {}) {
667
2021
  resolved = true;
668
2022
  resolve(val);
669
2023
  };
670
- const confirmLabel = opts.confirmLabel ?? "\u786E\u8BA4";
671
- const cancelLabel = opts.cancelLabel ?? "\u53D6\u6D88";
2024
+ const confirmLabel = opts.confirmLabel ?? t("common.confirm");
2025
+ const cancelLabel = opts.cancelLabel ?? t("common.cancel");
672
2026
  const actions = [
673
2027
  {
674
2028
  label: cancelLabel,
@@ -713,28 +2067,32 @@ function createNotificationCenter(parent, opts = {}) {
713
2067
  const mount = parent ?? document.body;
714
2068
  const local = {
715
2069
  position: opts.position ?? "top-right",
716
- maxStack: opts.maxStack ?? 5,
2070
+ maxStack: typeof opts.maxStack === "number" && Number.isFinite(opts.maxStack) && opts.maxStack >= 1 ? Math.floor(opts.maxStack) : 5,
717
2071
  pauseOnHover: opts.pauseOnHover ?? true,
718
2072
  persist: opts.persist ?? false,
719
2073
  sound: opts.sound ?? false
720
2074
  };
721
2075
  const container = document.createElement("div");
722
- container.className = "notification-container";
2076
+ container.className = "icen-notification-container";
723
2077
  container.setAttribute("role", "region");
724
- container.setAttribute("aria-label", "\u901A\u77E5");
725
- container.dataset.position = local.position;
2078
+ container.setAttribute("aria-label", t("notification.ariaLabel"));
2079
+ container.dataset.icenPosition = local.position;
726
2080
  mount.appendChild(container);
727
2081
  const localStore = /* @__PURE__ */ new Map();
728
2082
  let destroyed = false;
729
2083
  const pKey = persistKeyFor(local.persist);
730
2084
  if (pKey) {
731
- knownPersistKeys.add(pKey);
732
2085
  for (const r of restorePersisted(container, pKey, local)) {
733
2086
  r.ownerStore = localStore;
734
2087
  localStore.set(r.id, r);
735
2088
  store.set(r.id, r);
736
2089
  }
737
2090
  }
2091
+ trimStack(container, local.maxStack, (id) => {
2092
+ localStore.delete(id);
2093
+ store.delete(id);
2094
+ });
2095
+ syncNotificationGroups(container);
738
2096
  function push(input) {
739
2097
  if (destroyed) return null;
740
2098
  return pushRecord(
@@ -749,36 +2107,30 @@ function createNotificationCenter(parent, opts = {}) {
749
2107
  }
750
2108
  function dismiss(id) {
751
2109
  if (id) {
752
- const rec = localStore.get(id);
753
- if (!rec) return;
754
- if (rec.timer) window.clearTimeout(rec.timer);
755
- const handle = makeHandle(rec);
756
- localStore.delete(id);
757
- store.delete(id);
758
- if (rec.el) removeOne(rec.el, () => rec.opts.onClose?.(handle));
759
- persistSave();
2110
+ if (localStore.has(id)) dismissRecord(id);
760
2111
  return;
761
2112
  }
762
- Array.from(localStore.keys()).forEach((k) => dismiss(k));
2113
+ Array.from(localStore.keys()).forEach((key) => dismissRecord(key));
763
2114
  }
764
2115
  function clear() {
765
2116
  dismiss();
766
2117
  }
767
2118
  function markAllRead() {
768
- localStore.forEach((rec) => {
769
- rec.opts.unread = false;
770
- rec.el?.classList.remove("is-unread");
771
- });
2119
+ Array.from(localStore.keys()).forEach((id) => updateRecord(id, { unread: false }));
772
2120
  }
773
2121
  function destroy() {
774
2122
  if (destroyed) return;
2123
+ persistSave();
775
2124
  destroyed = true;
2125
+ const closing = Array.from(localStore.values());
776
2126
  localStore.forEach((rec) => {
777
- if (rec.timer) window.clearTimeout(rec.timer);
2127
+ stopRuntime(rec);
2128
+ if (rec.el) restoreFeedbackFocus(rec.el);
778
2129
  store.delete(rec.id);
779
2130
  });
780
2131
  localStore.clear();
781
2132
  container.remove();
2133
+ closing.forEach((rec) => rec.opts.onClose?.(makeHandle(rec)));
782
2134
  }
783
2135
  return {
784
2136
  push,
@@ -789,17 +2141,20 @@ function createNotificationCenter(parent, opts = {}) {
789
2141
  get: (id) => localStore.get(id) ?? null,
790
2142
  getAll: () => Array.from(localStore.values()),
791
2143
  config: (next) => {
2144
+ if (destroyed) return;
792
2145
  if (next.position) {
793
2146
  local.position = next.position;
794
- container.dataset.position = next.position;
2147
+ container.dataset.icenPosition = next.position;
795
2148
  }
796
- if (typeof next.maxStack === "number" && next.maxStack > 0) local.maxStack = next.maxStack;
797
- if (typeof next.pauseOnHover === "boolean") local.pauseOnHover = next.pauseOnHover;
798
- if (next.persist !== void 0) {
799
- local.persist = next.persist;
800
- const k = persistKeyFor(next.persist);
801
- if (k) knownPersistKeys.add(k);
2149
+ if (typeof next.maxStack === "number" && Number.isFinite(next.maxStack) && next.maxStack >= 1) {
2150
+ local.maxStack = Math.floor(next.maxStack);
2151
+ trimStack(container, local.maxStack, (id) => {
2152
+ localStore.delete(id);
2153
+ store.delete(id);
2154
+ });
802
2155
  }
2156
+ if (typeof next.pauseOnHover === "boolean") local.pauseOnHover = next.pauseOnHover;
2157
+ if (next.persist !== void 0) configurePersistence(local, next.persist, Array.from(localStore.values()));
803
2158
  if (next.sound !== void 0) local.sound = next.sound;
804
2159
  },
805
2160
  el: container
@@ -838,18 +2193,19 @@ var notify = Object.assign(
838
2193
  get: (id) => store.get(id) ?? null,
839
2194
  getAll: () => Array.from(store.values()),
840
2195
  config: (opts) => {
2196
+ if (!isBrowser()) return;
841
2197
  if (opts.position) {
842
2198
  cfg.position = opts.position;
843
- const c = document.body.querySelector(".notification-container[data-notif-default]");
844
- if (c) c.dataset.position = opts.position;
2199
+ const c = document.body.querySelector(".icen-notification-container[data-icen-notif-default]");
2200
+ if (c) c.dataset.icenPosition = opts.position;
845
2201
  }
846
- if (typeof opts.maxStack === "number" && opts.maxStack > 0) cfg.maxStack = opts.maxStack;
847
- if (typeof opts.pauseOnHover === "boolean") cfg.pauseOnHover = opts.pauseOnHover;
848
- if (opts.persist !== void 0) {
849
- cfg.persist = opts.persist;
850
- const k = persistKeyFor(opts.persist);
851
- if (k) knownPersistKeys.add(k);
2202
+ if (typeof opts.maxStack === "number" && Number.isFinite(opts.maxStack) && opts.maxStack >= 1) {
2203
+ cfg.maxStack = Math.floor(opts.maxStack);
2204
+ const c = document.querySelector("[data-icen-notif-default]");
2205
+ if (c) trimStack(c, cfg.maxStack, (id) => store.delete(id));
852
2206
  }
2207
+ if (typeof opts.pauseOnHover === "boolean") cfg.pauseOnHover = opts.pauseOnHover;
2208
+ if (opts.persist !== void 0) configurePersistence(cfg, opts.persist, Array.from(store.values()).filter((r) => !r.cfgRef));
853
2209
  if (opts.sound !== void 0) cfg.sound = opts.sound;
854
2210
  }
855
2211
  }
@@ -857,29 +2213,34 @@ var notify = Object.assign(
857
2213
  function initNotification() {
858
2214
  if (!isBrowser()) return () => {
859
2215
  };
860
- if (globalInit.done) return () => {
861
- };
2216
+ if (globalInit.done) return globalInit.dispose;
862
2217
  globalInit.done = true;
863
2218
  const container = ensureContainer();
864
2219
  const key = persistKeyFor(cfg.persist);
865
2220
  const restored = [];
866
2221
  if (key) {
867
- knownPersistKeys.add(key);
868
2222
  for (const r of restorePersisted(container, key)) {
869
2223
  store.set(r.id, r);
870
2224
  restored.push(r);
871
2225
  }
872
2226
  }
873
- return () => {
2227
+ trimStack(container, cfg.maxStack, (id) => store.delete(id));
2228
+ syncNotificationGroups(container);
2229
+ const dispose = () => {
2230
+ if (globalInit.dispose !== dispose) return;
2231
+ persistSave();
874
2232
  for (const r of restored) {
875
- if (r.timer) window.clearTimeout(r.timer);
876
- store.delete(r.id);
2233
+ stopRuntime(r);
2234
+ if (store.get(r.id) === r) store.delete(r.id);
877
2235
  r.el?.remove();
878
2236
  }
879
2237
  restored.length = 0;
880
2238
  if (container.childElementCount === 0) container.remove();
881
2239
  globalInit.done = false;
2240
+ globalInit.dispose = void 0;
882
2241
  };
2242
+ globalInit.dispose = dispose;
2243
+ return dispose;
883
2244
  }
884
2245
  export {
885
2246
  createNotificationCenter,