@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.
- package/AGENTS.md +82 -254
- package/LICENSE +21 -0
- package/README.md +60 -96
- package/dist/base.css +258 -188
- package/dist/behaviors/accordion.mjs +8 -8
- package/dist/behaviors/ai-branch.d.mts +1 -1
- package/dist/behaviors/ai-branch.mjs +1011 -94
- package/dist/behaviors/ai-chat.d.mts +9 -9
- package/dist/behaviors/ai-chat.mjs +1122 -169
- package/dist/behaviors/ai-composer.d.mts +47 -15
- package/dist/behaviors/ai-composer.mjs +2018 -534
- package/dist/behaviors/ai-core.d.mts +1 -1
- package/dist/behaviors/ai-core.mjs +1017 -107
- package/dist/behaviors/ai-diff.mjs +1020 -127
- package/dist/behaviors/ai-feedback.d.mts +1 -1
- package/dist/behaviors/ai-feedback.mjs +1036 -126
- package/dist/behaviors/ai-panel.d.mts +10 -10
- package/dist/behaviors/ai-panel.mjs +1285 -266
- package/dist/behaviors/ai-provider.d.mts +1 -1
- package/dist/behaviors/ai-provider.mjs +1004 -101
- package/dist/behaviors/ai-threads.d.mts +1 -1
- package/dist/behaviors/ai-threads.mjs +1069 -154
- package/dist/behaviors/ai-tool.d.mts +3 -3
- package/dist/behaviors/ai-tool.mjs +2087 -413
- package/dist/behaviors/ai-tools.d.mts +89 -16
- package/dist/behaviors/ai-tools.mjs +5365 -380
- package/dist/behaviors/autocomplete.d.mts +53 -0
- package/dist/behaviors/autocomplete.mjs +1601 -0
- package/dist/behaviors/back-top.d.mts +1 -1
- package/dist/behaviors/back-top.mjs +952 -14
- package/dist/behaviors/carousel.d.mts +1 -1
- package/dist/behaviors/carousel.mjs +914 -12
- package/dist/behaviors/cascader.d.mts +48 -0
- package/dist/behaviors/cascader.mjs +1867 -0
- package/dist/behaviors/charts.d.mts +72 -8
- package/dist/behaviors/charts.mjs +1953 -272
- package/dist/behaviors/code-block.d.mts +36 -0
- package/dist/behaviors/code-block.mjs +1619 -0
- package/dist/behaviors/command-palette.d.mts +9 -6
- package/dist/behaviors/command-palette.mjs +164 -62
- package/dist/behaviors/context-menu.d.mts +10 -9
- package/dist/behaviors/context-menu.mjs +1113 -44
- package/dist/behaviors/controls.d.mts +21 -21
- package/dist/behaviors/controls.mjs +1024 -134
- package/dist/behaviors/copy.d.mts +21 -2
- package/dist/behaviors/copy.mjs +1207 -42
- package/dist/behaviors/datatable.d.mts +55 -5
- package/dist/behaviors/datatable.mjs +2033 -212
- package/dist/behaviors/date-picker.d.mts +0 -1
- package/dist/behaviors/date-picker.mjs +1341 -293
- package/dist/behaviors/design.d.mts +54 -0
- package/dist/behaviors/design.mjs +109 -0
- package/dist/behaviors/dropdown.d.mts +5 -6
- package/dist/behaviors/dropdown.mjs +262 -110
- package/dist/behaviors/events.d.mts +127 -10
- package/dist/behaviors/events.mjs +58 -3
- package/dist/behaviors/feedback.d.mts +30 -0
- package/dist/behaviors/feedback.mjs +296 -0
- package/dist/behaviors/focus.d.mts +8 -0
- package/dist/behaviors/focus.mjs +24 -0
- package/dist/behaviors/form-validate.d.mts +111 -0
- package/dist/behaviors/form-validate.mjs +1746 -0
- package/dist/behaviors/i18n.d.mts +790 -0
- package/dist/behaviors/i18n.mjs +1713 -0
- package/dist/behaviors/icons.d.mts +93 -0
- package/dist/behaviors/icons.mjs +113 -0
- package/dist/behaviors/input.d.mts +9 -1
- package/dist/behaviors/input.mjs +1059 -60
- package/dist/behaviors/kb-access.d.mts +3 -3
- package/dist/behaviors/kb-access.mjs +2135 -239
- package/dist/behaviors/kb-acl.d.mts +8 -8
- package/dist/behaviors/kb-acl.mjs +1120 -179
- package/dist/behaviors/kb-answer.d.mts +2 -2
- package/dist/behaviors/kb-answer.mjs +2120 -435
- package/dist/behaviors/kb-audit.d.mts +3 -3
- package/dist/behaviors/kb-audit.mjs +1077 -154
- package/dist/behaviors/kb-canvas.d.mts +3 -3
- package/dist/behaviors/kb-canvas.mjs +1101 -177
- package/dist/behaviors/kb-chain.d.mts +2 -2
- package/dist/behaviors/kb-chain.mjs +1023 -100
- package/dist/behaviors/kb-checkpoint.d.mts +3 -3
- package/dist/behaviors/kb-checkpoint.mjs +1320 -169
- package/dist/behaviors/kb-chunks.d.mts +2 -2
- package/dist/behaviors/kb-chunks.mjs +1153 -213
- package/dist/behaviors/kb-citation.d.mts +3 -3
- package/dist/behaviors/kb-citation.mjs +1221 -185
- package/dist/behaviors/kb-clarify.d.mts +2 -2
- package/dist/behaviors/kb-clarify.mjs +1059 -130
- package/dist/behaviors/kb-conflict.d.mts +2 -2
- package/dist/behaviors/kb-conflict.mjs +1042 -119
- package/dist/behaviors/kb-connector.d.mts +2 -2
- package/dist/behaviors/kb-connector.mjs +1105 -176
- package/dist/behaviors/kb-core.d.mts +7 -2
- package/dist/behaviors/kb-core.mjs +1078 -162
- package/dist/behaviors/kb-eval.d.mts +2 -2
- package/dist/behaviors/kb-eval.mjs +1977 -144
- package/dist/behaviors/kb-explain.d.mts +3 -3
- package/dist/behaviors/kb-explain.mjs +1037 -104
- package/dist/behaviors/kb-filter.d.mts +2 -2
- package/dist/behaviors/kb-filter.mjs +2014 -178
- package/dist/behaviors/kb-gap.d.mts +3 -3
- package/dist/behaviors/kb-gap.mjs +1044 -121
- package/dist/behaviors/kb-hittest.d.mts +3 -3
- package/dist/behaviors/kb-hittest.mjs +1095 -151
- package/dist/behaviors/kb-metadata.mjs +1058 -130
- package/dist/behaviors/kb-passage.d.mts +4 -4
- package/dist/behaviors/kb-passage.mjs +1102 -161
- package/dist/behaviors/kb-pipeline.d.mts +4 -4
- package/dist/behaviors/kb-pipeline.mjs +1083 -162
- package/dist/behaviors/kb-qa.mjs +1089 -160
- package/dist/behaviors/kb-rerank.d.mts +2 -2
- package/dist/behaviors/kb-rerank.mjs +1048 -114
- package/dist/behaviors/kb-retrieval.d.mts +2 -2
- package/dist/behaviors/kb-retrieval.mjs +2079 -226
- package/dist/behaviors/kb-review.d.mts +2 -2
- package/dist/behaviors/kb-review.mjs +1996 -159
- package/dist/behaviors/kb-sandbox.d.mts +3 -3
- package/dist/behaviors/kb-sandbox.mjs +1033 -105
- package/dist/behaviors/kb-segment.d.mts +2 -2
- package/dist/behaviors/kb-segment.mjs +1112 -179
- package/dist/behaviors/kb-select.d.mts +24 -0
- package/dist/behaviors/kb-select.mjs +1995 -0
- package/dist/behaviors/kb-sources.d.mts +3 -3
- package/dist/behaviors/kb-sources.mjs +1085 -170
- package/dist/behaviors/kb-sql.d.mts +3 -3
- package/dist/behaviors/kb-sql.mjs +1144 -226
- package/dist/behaviors/kb-trace.d.mts +3 -3
- package/dist/behaviors/kb-trace.mjs +1051 -131
- package/dist/behaviors/kb-visibility.d.mts +2 -2
- package/dist/behaviors/kb-visibility.mjs +1087 -158
- package/dist/behaviors/kb-who-can.d.mts +2 -2
- package/dist/behaviors/kb-who-can.mjs +1980 -137
- package/dist/behaviors/mentions.d.mts +93 -0
- package/dist/behaviors/mentions.mjs +2153 -0
- package/dist/behaviors/modal.d.mts +4 -3
- package/dist/behaviors/modal.mjs +1056 -33
- package/dist/behaviors/nav.d.mts +1 -1
- package/dist/behaviors/nav.mjs +6 -6
- package/dist/behaviors/notification.d.mts +16 -8
- package/dist/behaviors/notification.mjs +1629 -268
- package/dist/behaviors/panel.d.mts +4 -0
- package/dist/behaviors/panel.mjs +995 -0
- package/dist/behaviors/popover.d.mts +28 -5
- package/dist/behaviors/popover.mjs +225 -24
- package/dist/behaviors/scroll-area.d.mts +17 -0
- package/dist/behaviors/scroll-area.mjs +59 -0
- package/dist/behaviors/select.d.mts +5 -2
- package/dist/behaviors/select.mjs +1416 -117
- package/dist/behaviors/sidebar.d.mts +1 -1
- package/dist/behaviors/sidebar.mjs +13 -13
- package/dist/behaviors/slider.d.mts +1 -1
- package/dist/behaviors/slider.mjs +12 -12
- package/dist/behaviors/split-pane.d.mts +1 -1
- package/dist/behaviors/split-pane.mjs +9 -7
- package/dist/behaviors/suggestions.d.mts +27 -0
- package/dist/behaviors/suggestions.mjs +1090 -0
- package/dist/behaviors/svg-parse.d.mts +14 -0
- package/dist/behaviors/svg-parse.mjs +37 -0
- package/dist/behaviors/tabs.d.mts +2 -2
- package/dist/behaviors/tabs.mjs +35 -25
- package/dist/behaviors/tag-input.d.mts +23 -5
- package/dist/behaviors/tag-input.mjs +1360 -104
- package/dist/behaviors/theme-switcher.d.mts +24 -0
- package/dist/behaviors/theme-switcher.mjs +1996 -0
- package/dist/behaviors/theme.d.mts +15 -8
- package/dist/behaviors/theme.mjs +406 -30
- package/dist/behaviors/toast.d.mts +24 -25
- package/dist/behaviors/toast.mjs +1267 -88
- package/dist/behaviors/tooltip.d.mts +4 -0
- package/dist/behaviors/tooltip.mjs +378 -0
- package/dist/behaviors/tree-select.d.mts +69 -0
- package/dist/behaviors/tree-select.mjs +1921 -0
- package/dist/behaviors/tree.d.mts +1 -1
- package/dist/behaviors/tree.mjs +18 -18
- package/dist/behaviors/upload.d.mts +3 -2
- package/dist/behaviors/upload.mjs +1077 -66
- package/dist/behaviors/url-safety.d.mts +8 -0
- package/dist/behaviors/url-safety.mjs +11 -0
- package/dist/cli.mjs +5 -6
- package/dist/components/accordion.d.mts +2 -0
- package/dist/components/ai-branch.d.mts +2 -0
- package/dist/components/ai-chat.css +682 -582
- package/dist/components/ai-chat.d.mts +2 -0
- package/dist/components/ai-composer.d.mts +2 -0
- package/dist/components/ai-context.d.mts +2 -0
- package/dist/components/ai-context.mjs +1 -0
- package/dist/components/ai-diff.css +153 -132
- package/dist/components/ai-diff.d.mts +2 -0
- package/dist/components/ai-feedback.d.mts +2 -0
- package/dist/components/ai-files.d.mts +2 -0
- package/dist/components/ai-message.d.mts +2 -0
- package/dist/components/ai-panel.css +353 -343
- package/dist/components/ai-reasoning.d.mts +2 -0
- package/dist/components/ai-subagent.d.mts +2 -0
- package/dist/components/ai-subagent.mjs +1 -0
- package/dist/components/ai-threads.d.mts +2 -0
- package/dist/components/ai-todo.d.mts +2 -0
- package/dist/components/ai-todo.mjs +1 -0
- package/dist/components/ai-tool-call.d.mts +2 -0
- package/dist/components/ai-tool-call.mjs +1 -0
- package/dist/components/ai-tool.css +397 -242
- package/dist/components/ai-usage.d.mts +2 -0
- package/dist/components/alert.d.mts +2 -0
- package/dist/components/autocomplete.css +61 -0
- package/dist/components/autocomplete.d.mts +2 -0
- package/dist/components/autocomplete.mjs +3 -0
- package/dist/components/avatar.d.mts +2 -0
- package/dist/components/back-top.css +74 -40
- package/dist/components/back-top.d.mts +2 -0
- package/dist/components/badge.css +44 -41
- package/dist/components/badge.d.mts +2 -0
- package/dist/components/breadcrumb.css +85 -46
- package/dist/components/breadcrumb.d.mts +2 -0
- package/dist/components/btn.css +105 -94
- package/dist/components/btn.d.mts +2 -0
- package/dist/components/card.css +124 -113
- package/dist/components/card.d.mts +2 -0
- package/dist/components/carousel.d.mts +2 -0
- package/dist/components/cascader.css +332 -0
- package/dist/components/cascader.d.mts +2 -0
- package/dist/components/cascader.mjs +3 -0
- package/dist/components/chart-area.css +54 -2
- package/dist/components/chart-area.d.mts +2 -0
- package/dist/components/chart-bar.css +147 -38
- package/dist/components/chart-bar.d.mts +2 -0
- package/dist/components/chart-calendar.d.mts +2 -0
- package/dist/components/chart-gauge.css +36 -13
- package/dist/components/chart-gauge.d.mts +2 -0
- package/dist/components/chart-graph.css +35 -20
- package/dist/components/chart-graph.d.mts +2 -0
- package/dist/components/chart-heatmap.css +67 -39
- package/dist/components/chart-heatmap.d.mts +2 -0
- package/dist/components/chart-line.css +62 -3
- package/dist/components/chart-line.d.mts +2 -0
- package/dist/components/chart-map.d.mts +2 -0
- package/dist/components/chart-pie.css +38 -6
- package/dist/components/chart-pie.d.mts +2 -0
- package/dist/components/chart-radar.css +57 -5
- package/dist/components/chart-radar.d.mts +2 -0
- package/dist/components/chart-scatter.css +47 -7
- package/dist/components/chart-scatter.d.mts +2 -0
- package/dist/components/chart-sparkline.css +25 -2
- package/dist/components/chart-sparkline.d.mts +2 -0
- package/dist/components/chart-stack.css +27 -13
- package/dist/components/chart-stack.d.mts +2 -0
- package/dist/components/charts.css +220 -84
- package/dist/components/charts.d.mts +2 -0
- package/dist/components/code-block.css +420 -0
- package/dist/components/code-block.d.mts +2 -0
- package/dist/components/code-block.mjs +4 -0
- package/dist/components/command-palette.css +150 -122
- package/dist/components/command-palette.d.mts +2 -0
- package/dist/components/content.css +274 -263
- package/dist/components/context-menu.d.mts +2 -0
- package/dist/components/copy.css +73 -45
- package/dist/components/copy.d.mts +2 -0
- package/dist/components/datatable.css +457 -202
- package/dist/components/datatable.d.mts +2 -0
- package/dist/components/date-picker.css +136 -105
- package/dist/components/date-picker.d.mts +2 -0
- package/dist/components/desc.d.mts +2 -0
- package/dist/components/dropdown.d.mts +2 -0
- package/dist/components/empty.css +72 -69
- package/dist/components/empty.d.mts +2 -0
- package/dist/components/feedback.css +211 -191
- package/dist/components/form-validate.css +134 -0
- package/dist/components/form-validate.d.mts +2 -0
- package/dist/components/form-validate.mjs +3 -0
- package/dist/components/form.css +157 -131
- package/dist/components/form.d.mts +2 -0
- package/dist/components/icon.css +113 -0
- package/dist/components/icon.d.mts +2 -0
- package/dist/components/icon.mjs +3 -0
- package/dist/components/input.css +163 -108
- package/dist/components/input.d.mts +2 -0
- package/dist/components/kb-access.d.mts +2 -0
- package/dist/components/kb-acl.d.mts +2 -0
- package/dist/components/kb-agent.css +300 -206
- package/dist/components/kb-answer.d.mts +2 -0
- package/dist/components/kb-audit.d.mts +2 -0
- package/dist/components/kb-canvas.d.mts +2 -0
- package/dist/components/kb-chain.d.mts +2 -0
- package/dist/components/kb-checkpoint.d.mts +2 -0
- package/dist/components/kb-chunks.d.mts +2 -0
- package/dist/components/kb-citation.d.mts +2 -0
- package/dist/components/kb-clarify.d.mts +2 -0
- package/dist/components/kb-conflict.d.mts +2 -0
- package/dist/components/kb-connector.d.mts +2 -0
- package/dist/components/kb-data.css +431 -315
- package/dist/components/kb-eval.d.mts +2 -0
- package/dist/components/kb-explain.d.mts +2 -0
- package/dist/components/kb-filter.d.mts +2 -0
- package/dist/components/kb-gap.d.mts +2 -0
- package/dist/components/kb-ground.css +333 -229
- package/dist/components/kb-hittest.d.mts +2 -0
- package/dist/components/kb-ingest.css +613 -434
- package/dist/components/kb-metadata.d.mts +2 -0
- package/dist/components/kb-ops.css +422 -302
- package/dist/components/kb-passage.d.mts +2 -0
- package/dist/components/kb-perm.css +374 -314
- package/dist/components/kb-pipeline.d.mts +2 -0
- package/dist/components/kb-qa.d.mts +2 -0
- package/dist/components/kb-rerank.d.mts +2 -0
- package/dist/components/kb-retrieval.d.mts +2 -0
- package/dist/components/kb-review.d.mts +2 -0
- package/dist/components/kb-sandbox.d.mts +2 -0
- package/dist/components/kb-search.css +653 -459
- package/dist/components/kb-segment.d.mts +2 -0
- package/dist/components/kb-sources.d.mts +2 -0
- package/dist/components/kb-sql.d.mts +2 -0
- package/dist/components/kb-trace.d.mts +2 -0
- package/dist/components/kb-visibility.d.mts +2 -0
- package/dist/components/kb-who-can.d.mts +2 -0
- package/dist/components/kb.css +170 -135
- package/dist/components/kb.d.mts +2 -0
- package/dist/components/kbd.d.mts +2 -0
- package/dist/components/layout.css +86 -83
- package/dist/components/layout.d.mts +2 -0
- package/dist/components/list.d.mts +2 -0
- package/dist/components/material-chinese.css +83 -0
- package/dist/components/material-soviet.css +86 -0
- package/dist/components/material.css +318 -0
- package/dist/components/media-card.d.mts +2 -0
- package/dist/components/media.css +225 -176
- package/dist/components/mentions.css +190 -0
- package/dist/components/mentions.d.mts +2 -0
- package/dist/components/mentions.mjs +3 -0
- package/dist/components/menu.css +121 -109
- package/dist/components/modal.css +116 -118
- package/dist/components/modal.d.mts +2 -0
- package/dist/components/nav.css +136 -129
- package/dist/components/nav.d.mts +2 -0
- package/dist/components/notification.css +247 -177
- package/dist/components/notification.d.mts +2 -0
- package/dist/components/pagination.css +62 -57
- package/dist/components/pagination.d.mts +2 -0
- package/dist/components/panel.css +70 -68
- package/dist/components/panel.d.mts +2 -0
- package/dist/components/panel.mjs +1 -0
- package/dist/components/pill.css +83 -72
- package/dist/components/pill.d.mts +2 -0
- package/dist/components/popover.css +80 -57
- package/dist/components/popover.d.mts +2 -0
- package/dist/components/progress.d.mts +2 -0
- package/dist/components/rating.d.mts +2 -0
- package/dist/components/result.d.mts +2 -0
- package/dist/components/scroll-area.css +29 -54
- package/dist/components/scroll-area.d.mts +2 -0
- package/dist/components/scroll-area.mjs +1 -0
- package/dist/components/segmented.css +167 -146
- package/dist/components/segmented.d.mts +2 -0
- package/dist/components/select.css +250 -191
- package/dist/components/select.d.mts +2 -0
- package/dist/components/sidebar.css +157 -143
- package/dist/components/sidebar.d.mts +2 -0
- package/dist/components/skeleton.d.mts +2 -0
- package/dist/components/slider.css +135 -128
- package/dist/components/slider.d.mts +2 -0
- package/dist/components/spinner.d.mts +2 -0
- package/dist/components/split-pane.css +120 -108
- package/dist/components/split-pane.d.mts +2 -0
- package/dist/components/stat.css +116 -109
- package/dist/components/stat.d.mts +2 -0
- package/dist/components/steps.css +114 -108
- package/dist/components/steps.d.mts +2 -0
- package/dist/components/switch.css +192 -149
- package/dist/components/switch.d.mts +2 -0
- package/dist/components/table.css +158 -112
- package/dist/components/table.d.mts +2 -0
- package/dist/components/tabs.css +143 -116
- package/dist/components/tabs.d.mts +2 -0
- package/dist/components/tag-input.css +52 -133
- package/dist/components/tag-input.d.mts +2 -0
- package/dist/components/tag.css +90 -72
- package/dist/components/tag.d.mts +2 -0
- package/dist/components/theme-switcher.css +105 -0
- package/dist/components/theme-switcher.d.mts +2 -0
- package/dist/components/theme-switcher.mjs +3 -0
- package/dist/components/timeline.d.mts +2 -0
- package/dist/components/toast.css +115 -97
- package/dist/components/toast.d.mts +2 -0
- package/dist/components/toolbar.css +47 -43
- package/dist/components/toolbar.d.mts +2 -0
- package/dist/components/tooltip.css +103 -43
- package/dist/components/tooltip.d.mts +2 -0
- package/dist/components/tooltip.mjs +1 -0
- package/dist/components/tree-select.css +439 -0
- package/dist/components/tree-select.d.mts +2 -0
- package/dist/components/tree-select.mjs +3 -0
- package/dist/components/tree.d.mts +2 -0
- package/dist/components/upload.css +138 -97
- package/dist/components/upload.d.mts +2 -0
- package/dist/fonts/LICENSES/ark-pixel/OFL.txt +96 -0
- package/dist/fonts/LICENSES/cubic-11/OFL.txt +108 -0
- package/dist/fonts/LICENSES/galmuri/LICENSE.txt +93 -0
- package/dist/fonts/OFL.txt +96 -0
- package/dist/fonts/README.md +14 -0
- package/dist/fonts/fusion-pixel-12px-zh-hans.woff2 +0 -0
- package/dist/index.d.mts +85 -70
- package/dist/index.mjs +17330 -5773
- package/dist/react.d.mts +91 -0
- package/dist/react.mjs +8307 -0
- package/dist/registry.json +918 -70
- package/dist/tokens/chinese.css +44 -0
- package/dist/tokens/colors.css +371 -1222
- package/dist/tokens/design.css +209 -0
- package/dist/tokens/dtcg.json +15926 -0
- package/dist/tokens/figma.variables.json +10779 -0
- package/dist/tokens/icon-masks.css +78 -0
- package/dist/tokens/pixel.css +53 -0
- package/dist/tokens/scrollbars.css +40 -0
- package/dist/tokens/soviet.css +44 -0
- package/dist/tokens/style-profiles.css +36 -547
- package/dist/tokens/themes.json +308 -0
- package/dist/tokens/tokens-studio.json +11648 -0
- package/dist/tokens/typography.css +21 -18
- package/dist/tokens.css +1783 -1806
- package/dist/ui.css +14796 -10750
- package/dist/vue.d.mts +344 -0
- package/dist/vue.mjs +7876 -0
- package/docs/spec/ai-input-experience.md +75 -0
- package/docs/spec/ai-native.md +238 -147
- package/docs/spec/design-philosophy.md +189 -0
- package/docs/spec/design-primitives.md +196 -0
- package/docs/spec/kb-family.md +147 -115
- package/docs/spec/scrollbars.md +46 -0
- package/package.json +56 -8
- package/dist/retro-effects.css +0 -255
- package/dist/tokens/retro-effects.css +0 -255
- package/docs/research/2026-10-03-ai-kb-components.md +0 -392
- package/docs/research/2026-10-03-kb-permissions.md +0 -992
|
@@ -1,3 +1,990 @@
|
|
|
1
|
+
// src/behaviors/events.ts
|
|
2
|
+
function emitIcen(source, type, detail) {
|
|
3
|
+
return source.dispatchEvent(
|
|
4
|
+
new CustomEvent(type, { detail, bubbles: true, composed: true, cancelable: true })
|
|
5
|
+
);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// src/behaviors/i18n.ts
|
|
9
|
+
var ICEN_LOCALE_ZH_CN = {
|
|
10
|
+
/* ── aiBranch ── */
|
|
11
|
+
"aiBranch.nextVersion": "\u4E0B\u4E00\u7248\u672C",
|
|
12
|
+
"aiBranch.prevVersion": "\u4E0A\u4E00\u7248\u672C",
|
|
13
|
+
"aiBranch.version": "\u5206\u652F\u7248\u672C",
|
|
14
|
+
/* ── aiChat ── */
|
|
15
|
+
"aiChat.backToBottom": "\u56DE\u5230\u5E95\u90E8",
|
|
16
|
+
"aiChat.backToBottomCount": "\u56DE\u5230\u5E95\u90E8 \xB7 {p0} \u6761\u65B0\u6D88\u606F",
|
|
17
|
+
"aiChat.continue": "\u7EE7\u7EED\u751F\u6210",
|
|
18
|
+
"aiChat.download": "\u4E0B\u8F7D",
|
|
19
|
+
"aiChat.file": "\u6587\u4EF6",
|
|
20
|
+
"aiChat.roleSystem": "\u7CFB",
|
|
21
|
+
"aiChat.roleTool": "\u5DE5",
|
|
22
|
+
"aiChat.roleUser": "\u6211",
|
|
23
|
+
"aiChat.thinking": "\u601D\u8003 {p0}",
|
|
24
|
+
"aiChat.thinkingNow": "\u6B63\u5728\u601D\u8003\u2026",
|
|
25
|
+
/* ── aiComposer ── */
|
|
26
|
+
"aiComposer.attachAgent": "\u4EE3\u7406",
|
|
27
|
+
"aiComposer.library": "\u6DFB\u52A0\u4E0A\u4E0B\u6587\u4E0E\u547D\u4EE4",
|
|
28
|
+
"aiComposer.searchLibrary": "\u641C\u7D22\u6280\u80FD\u3001\u5DE5\u5177\u3001\u6587\u4EF6\u4E0E\u547D\u4EE4",
|
|
29
|
+
"aiComposer.all": "\u5168\u90E8",
|
|
30
|
+
"aiComposer.skills": "\u6280\u80FD",
|
|
31
|
+
"aiComposer.tools": "\u5DE5\u5177",
|
|
32
|
+
"aiComposer.libraryHint": "\u4E0A\u4E0B\u6587\u968F\u6D88\u606F\u53D1\u9001 \xB7 \u547D\u4EE4\u5148\u586B\u5165\u8F93\u5165\u6846",
|
|
33
|
+
"aiComposer.commandHint": "\u2191 \u2193 \u6D4F\u89C8 \xB7 Enter \u6267\u884C \xB7 Esc \u8FD4\u56DE",
|
|
34
|
+
"aiComposer.refHint": "\u2191 \u2193 \u6D4F\u89C8 \xB7 Enter \u5F15\u7528 \xB7 Esc \u8FD4\u56DE",
|
|
35
|
+
"aiComposer.noLibraryMatch": "\u6CA1\u6709\u5339\u914D\u7684\u9879\u76EE\uFF0C\u8BD5\u8BD5\u5176\u4ED6\u5173\u952E\u8BCD",
|
|
36
|
+
"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",
|
|
37
|
+
"aiComposer.attachDoc": "\u6587\u6863",
|
|
38
|
+
"aiComposer.attachFile": "\u6587\u4EF6",
|
|
39
|
+
"aiComposer.attachFolder": "\u6587\u4EF6\u5939",
|
|
40
|
+
"aiComposer.cacheInvalidHint": "\u5207\u6362\u6A21\u578B\u4F1A\u4F7F prompt \u7F13\u5B58\u5931\u6548",
|
|
41
|
+
"aiComposer.commands": "\u547D\u4EE4",
|
|
42
|
+
"aiComposer.currentTodos": "\u5F53\u524D\u5F85\u529E",
|
|
43
|
+
"aiComposer.done": "\u5B8C\u6210",
|
|
44
|
+
"aiComposer.justNow": "\u521A\u521A \xB7 {p0}",
|
|
45
|
+
"aiComposer.modelAria": "\u6A21\u578B {p0}\uFF08{p1}\uFF09",
|
|
46
|
+
"aiComposer.noCommandMatch": "\u65E0\u5339\u914D\u547D\u4EE4",
|
|
47
|
+
"aiComposer.noModelMatch": "\u65E0\u5339\u914D\u6A21\u578B",
|
|
48
|
+
"aiComposer.noRefMatch": "\u65E0\u5339\u914D\u5F15\u7528",
|
|
49
|
+
"aiComposer.placeholder": "\u8F93\u5165\u6D88\u606F\uFF0C/ \u547D\u4EE4 \xB7 @ \u5F15\u7528 \xB7 Enter \u53D1\u9001",
|
|
50
|
+
"aiComposer.refs": "\u5F15\u7528",
|
|
51
|
+
"aiComposer.removeAttachment": "\u79FB\u9664\u9644\u4EF6 {p0}",
|
|
52
|
+
"aiComposer.removeQueued": "\u79FB\u9664\u6392\u961F\u6D88\u606F {p0}",
|
|
53
|
+
"aiComposer.removeRef": "\u79FB\u9664\u5F15\u7528 {p0}",
|
|
54
|
+
"aiComposer.searchModels": "\u641C\u7D22\u6A21\u578B",
|
|
55
|
+
"aiComposer.selectModel": "\u9009\u62E9\u6A21\u578B",
|
|
56
|
+
"aiComposer.send": "\u53D1\u9001",
|
|
57
|
+
"aiComposer.stop": "\u505C\u6B62\u751F\u6210",
|
|
58
|
+
"aiComposer.stopped": "\u5DF2\u505C\u6B62",
|
|
59
|
+
"aiComposer.todoChip": "\u5F53\u524D\u5F85\u529E {p0}/{p1}{p2}",
|
|
60
|
+
"aiComposer.todoHasError": "\uFF08\u6709\u5931\u8D25\u9879\uFF09",
|
|
61
|
+
/* ── aiCore ── */
|
|
62
|
+
"aiCore.kindBrowser": "\u6D4F\u89C8",
|
|
63
|
+
"aiCore.kindChart": "\u56FE\u8868",
|
|
64
|
+
"aiCore.kindDelete": "\u5220\u9664",
|
|
65
|
+
"aiCore.kindEdit": "\u7F16\u8F91",
|
|
66
|
+
"aiCore.kindFetch": "\u8BF7\u6C42",
|
|
67
|
+
"aiCore.kindGlob": "\u5339\u914D",
|
|
68
|
+
"aiCore.kindGrep": "\u641C\u7D22",
|
|
69
|
+
"aiCore.kindNote": "\u7B14\u8BB0",
|
|
70
|
+
"aiCore.kindPlan": "\u8BA1\u5212",
|
|
71
|
+
"aiCore.kindRead": "\u8BFB\u53D6",
|
|
72
|
+
"aiCore.kindSearch": "\u68C0\u7D22",
|
|
73
|
+
"aiCore.kindShell": "\u547D\u4EE4",
|
|
74
|
+
"aiCore.kindSkill": "\u6280\u80FD",
|
|
75
|
+
"aiCore.kindSubagent": "\u5B50\u4EE3\u7406",
|
|
76
|
+
"aiCore.kindTodo": "\u5F85\u529E",
|
|
77
|
+
"aiCore.kindWrite": "\u5199\u5165",
|
|
78
|
+
"aiCore.statusApproval": "\u5F85\u786E\u8BA4",
|
|
79
|
+
"aiCore.statusCancelled": "\u5DF2\u53D6\u6D88",
|
|
80
|
+
"aiCore.statusDone": "\u5B8C\u6210",
|
|
81
|
+
"aiCore.statusError": "\u5931\u8D25",
|
|
82
|
+
"aiCore.statusPending": "\u7B49\u5F85",
|
|
83
|
+
"aiCore.statusRunning": "\u6267\u884C\u4E2D",
|
|
84
|
+
"aiCore.statusStreaming": "\u6D41\u5F0F\u4E2D",
|
|
85
|
+
"aiCore.todoProgress": "{p0}/{p1} \u5B8C\u6210",
|
|
86
|
+
/* ── aiDiff ── */
|
|
87
|
+
"aiDiff.accepted": "\u5DF2\u63A5\u53D7",
|
|
88
|
+
"aiDiff.binary": "\u4E8C\u8FDB\u5236\u6587\u4EF6\uFF0C\u65E0\u6CD5\u663E\u793A\u6587\u672C\u5DEE\u5F02",
|
|
89
|
+
"aiDiff.empty": "\u65E0\u5DEE\u5F02\u5185\u5BB9",
|
|
90
|
+
"aiDiff.rejected": "\u5DF2\u62D2\u7EDD",
|
|
91
|
+
/* ── aiFeedback ── */
|
|
92
|
+
"aiFeedback.helpful": "\u6709\u5E2E\u52A9",
|
|
93
|
+
"aiFeedback.notHelpful": "\u65E0\u5E2E\u52A9",
|
|
94
|
+
"aiFeedback.reasonCitationMismatch": "\u5F15\u7528\u4E0D\u7B26",
|
|
95
|
+
"aiFeedback.reasonOutdated": "\u5185\u5BB9\u8FC7\u65F6",
|
|
96
|
+
"aiFeedback.reasonUnauthorized": "\u8D8A\u6743\u4FE1\u606F",
|
|
97
|
+
"aiFeedback.reasonUnsourced": "\u65E0\u5F15\u7528\u4F9D\u636E",
|
|
98
|
+
"aiFeedback.reasonWrong": "\u7B54\u6848\u6709\u8BEF",
|
|
99
|
+
"aiFeedback.thanks": "\u611F\u8C22\u53CD\u9988\uFF0C\u5DF2\u5173\u8054\u5230\u8BE5\u6761\u56DE\u7B54\u7684\u8FFD\u8E2A\u8BB0\u5F55",
|
|
100
|
+
/* ── aiPanel ── */
|
|
101
|
+
"aiPanel.audit": "\u5BA1\u8BA1",
|
|
102
|
+
"aiPanel.cacheRead": "\u7F13\u5B58\u8BFB",
|
|
103
|
+
"aiPanel.cacheWrite": "\u7F13\u5B58\u5199",
|
|
104
|
+
"aiPanel.callsTokens": "{p0} \u6B21 \xB7 {p1} tok{p2}",
|
|
105
|
+
"aiPanel.clearAudit": "\u6E05\u9664\u5BA1\u8BA1",
|
|
106
|
+
"aiPanel.context": "\u4E0A\u4E0B\u6587",
|
|
107
|
+
"aiPanel.contextWindow": "\u4E0A\u4E0B\u6587\u7A97\u53E3",
|
|
108
|
+
"aiPanel.errorsCount": "{p0} \u5931\u8D25",
|
|
109
|
+
"aiPanel.files": "\u6587\u4EF6 ({p0})",
|
|
110
|
+
"aiPanel.itemStatus": "{p0}\uFF0C\u72B6\u6001\uFF1A{p1}",
|
|
111
|
+
"aiPanel.noAudit": "\u6682\u65E0\u5BA1\u8BA1\u8BB0\u5F55",
|
|
112
|
+
"aiPanel.noUsage": "\u6682\u65E0\u7528\u91CF",
|
|
113
|
+
"aiPanel.reasoning": "\u63A8\u7406",
|
|
114
|
+
"aiPanel.requestsCount": "{p0} \u6B21\u8BF7\u6C42",
|
|
115
|
+
"aiPanel.ringPercent": "\u4E0A\u4E0B\u6587\u7A97\u53E3\u5360\u7528 {p0}%\uFF0C\u70B9\u51FB\u67E5\u770B\u8BE6\u60C5",
|
|
116
|
+
"aiPanel.ringUsed": "\u5DF2\u7528 {p0}\uFF0C\u70B9\u51FB\u67E5\u770B\u8BE6\u60C5",
|
|
117
|
+
"aiPanel.taskProgress": "\u4EFB\u52A1\u8FDB\u5EA6",
|
|
118
|
+
"aiPanel.toolsCount": "{p0} \u5DE5\u5177",
|
|
119
|
+
"aiPanel.usage": "\u7528\u91CF",
|
|
120
|
+
"aiPanel.usageAria": "\u7528\u91CF\uFF1A{p0}",
|
|
121
|
+
/* ── aiProvider ── */
|
|
122
|
+
"aiProvider.audioUrlOnly": "\u4EC5 URL \u7684\u97F3\u9891\uFF08input_audio \u9700 base64\uFF0C\u8BF7\u5148\u53D6\u56DE\u5185\u8054\uFF09",
|
|
123
|
+
"aiProvider.audioUrlOnlyAnthropic": "\u4EC5 URL \u7684\u97F3\u9891\uFF08audio \u5757\u9700 base64 source\uFF09",
|
|
124
|
+
"aiProvider.base64File": "base64 \u6587\u4EF6\uFF08file \u90E8\u4EF6\u9700 Files API file_id\uFF0C\u8BF7\u7F6E\u4E8E url \u69FD\uFF09",
|
|
125
|
+
"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",
|
|
126
|
+
"aiProvider.emptyResponse": "\u54CD\u5E94\u4E3A\u7A7A",
|
|
127
|
+
"aiProvider.glmLabel": "GLM\uFF08\u667A\u8C31\uFF09",
|
|
128
|
+
"aiProvider.invalidJson": "\u54CD\u5E94\u4E0D\u662F\u5408\u6CD5 JSON",
|
|
129
|
+
"aiProvider.kimiLabel": "Kimi\uFF08\u6708\u4E4B\u6697\u9762\uFF09",
|
|
130
|
+
"aiProvider.networkFailed": "\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25\uFF1A{p0}{p1}",
|
|
131
|
+
"aiProvider.nonPdfDocument": "\u975E PDF \u6587\u4EF6\u5757\uFF08document \u5757\u4E3A application/pdf\uFF0C\u6536\u5230 {p0}\uFF09",
|
|
132
|
+
"aiProvider.requestCancelled": "\u8BF7\u6C42\u5DF2\u53D6\u6D88",
|
|
133
|
+
"aiProvider.resourceRef": "[\u8D44\u6E90] {p0} ({p1})",
|
|
134
|
+
"aiProvider.streamError": "\u6D41\u5F0F\u54CD\u5E94\u9519\u8BEF",
|
|
135
|
+
"aiProvider.toolRoleNoCallId": "role 'tool' \u4E14\u7F3A toolCallId\uFF08openai \u65CF\u9700 tool_call_id\uFF09",
|
|
136
|
+
"aiProvider.toolRoleNoUseId": "role 'tool' \u4E14\u7F3A toolCallId\uFF08anthropic \u65CF\u6620\u5C04 tool_result \u9700 tool_use_id\uFF09",
|
|
137
|
+
"aiProvider.unsupported": "{p0} \u7EBF\u534F\u8BAE\u4E0D\u652F\u6301 {p1}",
|
|
138
|
+
"aiProvider.videoUnsupported": "video \u8F93\u5165\uFF08\u65E0\u4E3B\u6D41 chat API \u652F\u6301\uFF09",
|
|
139
|
+
"aiProvider.videoUnsupportedAnthropic": "video \u8F93\u5165",
|
|
140
|
+
/* ── aiThreads ── */
|
|
141
|
+
"aiThreads.actionsAria": "\u4F1A\u8BDD\u64CD\u4F5C",
|
|
142
|
+
"aiThreads.archived": "\u5DF2\u5F52\u6863",
|
|
143
|
+
/* ── aiTool ── */
|
|
144
|
+
"aiTool.allow": "\u5141\u8BB8",
|
|
145
|
+
"aiTool.reject": "\u62D2\u7EDD",
|
|
146
|
+
/* ── aiTools ── */
|
|
147
|
+
"aiTools.chart.area": "line \u591A\u7CFB\u5217\u586B\u5145\u9762\u79EF",
|
|
148
|
+
"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",
|
|
149
|
+
"aiTools.chart.dates": "\u8D21\u732E\u65E5\u5386 ISO \u65E5\u671F\uFF08\u4E0E values \u914D\u5BF9\uFF09",
|
|
150
|
+
"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",
|
|
151
|
+
"aiTools.chart.dims": "data[] \u7684\u5B57\u6BB5\u6620\u5C04\uFF1A{label?, series?, value?, x?, y?}",
|
|
152
|
+
"aiTools.chart.format": "\u6570\u503C\u683C\u5F0F\u5316\uFF1A{notation?: compact|percent|ms, unit?}",
|
|
153
|
+
"aiTools.chart.labels": "\u7C7B\u76EE\u8F74\uFF08line/vbar/hbar\uFF09",
|
|
154
|
+
"aiTools.chart.legend": "false = \u521D\u59CB\u9690\u85CF\u56FE\u4F8B",
|
|
155
|
+
"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",
|
|
156
|
+
"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",
|
|
157
|
+
"aiTools.chart.points": "\u6563\u70B9/\u6C14\u6CE1\uFF1A[{x,y,size?,label?}]",
|
|
158
|
+
"aiTools.chart.radarAxes": "\u96F7\u8FBE\u8F74\u540D",
|
|
159
|
+
"aiTools.chart.segments": "\u5360\u6BD4\u578B\uFF08donut/stack\uFF09\uFF1A[{label,value}]",
|
|
160
|
+
"aiTools.chart.series": "\u591A\u7CFB\u5217\uFF08line/vbar/radar\uFF09",
|
|
161
|
+
"aiTools.chart.stacked": "vbar \u591A\u7CFB\u5217\u5806\u53E0\uFF08\u9ED8\u8BA4\u5206\u7EC4\uFF09",
|
|
162
|
+
"aiTools.chart.title": "\u56FE\u8868\u6807\u9898\uFF08\u6E32\u67D3\u5728\u5934\u90E8\u884C\u5DE6\u4FA7\uFF09",
|
|
163
|
+
"aiTools.chart.tooltip": "false = \u5173\u95ED\u5185\u7F6E\u63D0\u793A",
|
|
164
|
+
"aiTools.chart.type": "\u56FE\u8868\u7C7B\u578B\uFF0C\u7F3A\u7701\u81EA\u52A8\u63A8\u65AD",
|
|
165
|
+
"aiTools.chart.values": "\u5355\u7CFB\u5217\u6570\u503C\uFF08\u4E0E labels \u914D\u5BF9\uFF09",
|
|
166
|
+
"aiTools.chart.zoom": "\u7F29\u653E\u4EA4\u4E92\uFF1A'x'=\u7C7B\u76EE\u8F74\u533A\u95F4\u7F29\u653E\uFF0C'brush'=\u5237\u9009\u7F29\u653E",
|
|
167
|
+
"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",
|
|
168
|
+
"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",
|
|
169
|
+
"aiTools.datatable.rows": "\u884C\u6570\u636E\u6570\u7EC4\uFF1A\u6BCF\u9879\u4E3A\u4E00\u4E2A\u5BF9\u8C61\uFF0C\u5B57\u6BB5\u540D\u5BF9\u9F50 columns[].key",
|
|
170
|
+
"aiTools.datatable.title": "\u8868\u683C\u6807\u9898\uFF08\u6E32\u67D3\u5728\u5DE5\u5177\u680F\u5DE6\u4FA7\uFF09",
|
|
171
|
+
"aiTools.execFailed": "\u5DE5\u5177\u6267\u884C\u5931\u8D25\uFF1A{p0}",
|
|
172
|
+
"aiTools.execTimeout": "\u6267\u884C\u8D85\u65F6\uFF08{p0}ms\uFF09",
|
|
173
|
+
"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",
|
|
174
|
+
"aiTools.missingRequired": "\u7F3A\u5C11\u5FC5\u586B\u5B57\u6BB5",
|
|
175
|
+
"aiTools.none": "\uFF08\u65E0\u5DF2\u6CE8\u518C\u7684 UI \u5DE5\u5177\uFF09",
|
|
176
|
+
"aiTools.notInEnum": "\u4E0D\u5728\u5141\u8BB8\u53D6\u503C\u5185\uFF08{p0}\uFF09",
|
|
177
|
+
"aiTools.numMax": "\u6570\u503C {p0} \u5927\u4E8E\u6700\u5927\u503C {p1}",
|
|
178
|
+
"aiTools.numMin": "\u6570\u503C {p0} \u5C0F\u4E8E\u6700\u5C0F\u503C {p1}",
|
|
179
|
+
"aiTools.removeMount": "\u79FB\u9664 {p0} \u6302\u8F7D",
|
|
180
|
+
"aiTools.strMax": "\u957F\u5EA6 {p0} \u8D85\u8FC7\u4E0A\u9650 {p1}",
|
|
181
|
+
"aiTools.strMin": "\u957F\u5EA6 {p0} \u5C0F\u4E8E\u4E0B\u9650 {p1}",
|
|
182
|
+
"aiTools.typeMismatch": "\u671F\u671B {p0}\uFF0C\u5B9E\u5F97 {p1}",
|
|
183
|
+
"aiTools.validationFailed": "\u53C2\u6570\u6821\u9A8C\u5931\u8D25\uFF08{p0} \u9879\uFF09",
|
|
184
|
+
/* ── autocomplete ── */
|
|
185
|
+
"suggestions.loading": "\u6B63\u5728\u67E5\u627E\u5EFA\u8BAE\u2026",
|
|
186
|
+
"suggestions.error": "\u6682\u65F6\u65E0\u6CD5\u52A0\u8F7D\u5EFA\u8BAE\uFF0C\u8BF7\u91CD\u8BD5\u3002",
|
|
187
|
+
"suggestions.options": "\u5EFA\u8BAE",
|
|
188
|
+
"suggestions.empty": "\u6CA1\u6709\u5339\u914D\u7684\u5EFA\u8BAE",
|
|
189
|
+
"autocomplete.empty": "\u65E0\u5339\u914D\u7ED3\u679C",
|
|
190
|
+
/* ── backTop ── */
|
|
191
|
+
"backTop.label": "\u56DE\u5230\u9876\u90E8",
|
|
192
|
+
/* ── carousel ── */
|
|
193
|
+
"carousel.item": "\u7B2C {p0} \u5F20",
|
|
194
|
+
"carousel.region": "\u8F6E\u64AD",
|
|
195
|
+
"carousel.slide": "\u5E7B\u706F\u7247",
|
|
196
|
+
"carousel.status": "\u7B2C {p0} / {p1} \u5F20",
|
|
197
|
+
/* ── charts ── */
|
|
198
|
+
"charts.calendarWeekdays": ["\u4E00", "", "\u4E09", "", "\u4E94", "", "\u65E5"],
|
|
199
|
+
"charts.few": "\u5C11",
|
|
200
|
+
"charts.hideLegend": "\u9690\u85CF\u56FE\u4F8B",
|
|
201
|
+
"charts.loading": "\u52A0\u8F7D\u4E2D",
|
|
202
|
+
"charts.many": "\u591A",
|
|
203
|
+
"charts.monthLabel": "{p0}\u6708",
|
|
204
|
+
"charts.noData": "\u6682\u65E0\u6570\u636E",
|
|
205
|
+
"charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
|
|
206
|
+
"charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
|
|
207
|
+
"charts.type.area": "\u9762\u79EF\u56FE",
|
|
208
|
+
"charts.type.donut": "\u73AF\u5F62\u56FE",
|
|
209
|
+
"charts.type.gauge": "\u4EEA\u8868\u76D8",
|
|
210
|
+
"charts.type.graph": "\u77E5\u8BC6\u56FE\u8C31",
|
|
211
|
+
"charts.type.heatmap": "\u70ED\u529B\u56FE",
|
|
212
|
+
"charts.type.line": "\u6298\u7EBF\u56FE",
|
|
213
|
+
"charts.type.map": "\u5730\u56FE",
|
|
214
|
+
"charts.type.radar": "\u96F7\u8FBE\u56FE",
|
|
215
|
+
"charts.type.scatter": "\u6563\u70B9\u56FE",
|
|
216
|
+
"charts.type.sparkline": "\u8FF7\u4F60\u8D8B\u52BF",
|
|
217
|
+
"charts.seriesName": "\u7CFB\u5217{p0}",
|
|
218
|
+
"charts.showLegend": "\u663E\u793A\u56FE\u4F8B",
|
|
219
|
+
"charts.value": "\u6570\u503C",
|
|
220
|
+
/* ── themeSwitcher ── */
|
|
221
|
+
"themeSwitcher.appearance": "\u5916\u89C2",
|
|
222
|
+
"themeSwitcher.theme": "\u4E3B\u9898",
|
|
223
|
+
"themeSwitcher.primitive": "\u539F\u8BED",
|
|
224
|
+
"themeSwitcher.mode": "\u660E\u6697",
|
|
225
|
+
"themeSwitcher.light": "\u6D45\u8272",
|
|
226
|
+
"themeSwitcher.dark": "\u6DF1\u8272",
|
|
227
|
+
"themeSwitcher.modern": "\u73B0\u4EE3",
|
|
228
|
+
"themeSwitcher.dongyun": "\u4E1C\u97F5",
|
|
229
|
+
"themeSwitcher.jugou": "\u5DE8\u6784",
|
|
230
|
+
"themeSwitcher.piano": "\u94A2\u7434",
|
|
231
|
+
"themeSwitcher.monet": "\u83AB\u5948",
|
|
232
|
+
"themeSwitcher.vangogh": "\u68B5\u9AD8",
|
|
233
|
+
"themeSwitcher.chinese": "\u4E2D\u5F0F",
|
|
234
|
+
"themeSwitcher.soviet": "\u82CF\u5F0F",
|
|
235
|
+
"themeSwitcher.pixel": "\u50CF\u7D20",
|
|
236
|
+
/* ── codeBlock ── */
|
|
237
|
+
"codeBlock.collapse": "\u6536\u8D77",
|
|
238
|
+
"codeBlock.region": "\u4EE3\u7801\u5185\u5BB9",
|
|
239
|
+
"codeBlock.copyFailed": "\u672A\u80FD\u590D\u5236\uFF0C\u8BF7\u91CD\u8BD5\u3002",
|
|
240
|
+
"codeBlock.copyRetry": "\u91CD\u8BD5\u590D\u5236",
|
|
241
|
+
"codeBlock.copy": "\u590D\u5236",
|
|
242
|
+
"codeBlock.foldCollapse": "\u6298\u53E0\u4EE3\u7801",
|
|
243
|
+
"codeBlock.foldExpand": "\u5C55\u5F00\u4EE3\u7801",
|
|
244
|
+
"codeBlock.linesTotal": "\u5171 {p0} \u884C",
|
|
245
|
+
"codeBlock.numHide": "\u9690\u85CF\u884C\u53F7",
|
|
246
|
+
"codeBlock.numShow": "\u663E\u793A\u884C\u53F7",
|
|
247
|
+
"codeBlock.tailAria": "\u5C55\u5F00\u6216\u6536\u8D77\u4EE3\u7801",
|
|
248
|
+
"codeBlock.wrapOff": "\u5173\u95ED\u6362\u884C",
|
|
249
|
+
"codeBlock.wrapOn": "\u81EA\u52A8\u6362\u884C",
|
|
250
|
+
/* ── common ── */
|
|
251
|
+
"common.accept": "\u63A5\u53D7",
|
|
252
|
+
"common.add": "\u65B0\u589E",
|
|
253
|
+
"common.all": "\u5168\u90E8",
|
|
254
|
+
"common.approve": "\u6279\u51C6",
|
|
255
|
+
"common.cancel": "\u53D6\u6D88",
|
|
256
|
+
"common.actionFailed": "\u64CD\u4F5C\u672A\u5B8C\u6210\uFF0C\u8BF7\u91CD\u8BD5\u3002",
|
|
257
|
+
"common.close": "\u5173\u95ED",
|
|
258
|
+
"common.confirm": "\u786E\u8BA4",
|
|
259
|
+
"common.copied": "\u5DF2\u590D\u5236",
|
|
260
|
+
"common.copy": "\u590D\u5236",
|
|
261
|
+
"common.delete": "\u5220\u9664",
|
|
262
|
+
"common.enable": "\u542F\u7528",
|
|
263
|
+
"common.exportCsv": "\u5BFC\u51FA CSV",
|
|
264
|
+
"common.healthy": "\u6B63\u5E38",
|
|
265
|
+
"common.input": "\u8F93\u5165",
|
|
266
|
+
"common.loadingEllipsis": "\u52A0\u8F7D\u4E2D\u2026",
|
|
267
|
+
"common.official": "\u5B98\u65B9",
|
|
268
|
+
"common.output": "\u8F93\u51FA",
|
|
269
|
+
"common.page": "\u7B2C {p0} \u9875",
|
|
270
|
+
"common.reject": "\u62D2\u7EDD",
|
|
271
|
+
"common.remove": "\u79FB\u9664",
|
|
272
|
+
"common.requestAccess": "\u7533\u8BF7\u8BBF\u95EE",
|
|
273
|
+
"common.requestAccessFor": "\u7533\u8BF7\u8BBF\u95EE {p0}",
|
|
274
|
+
"common.restricted": "\u53D7\u9650",
|
|
275
|
+
"common.retry": "\u91CD\u8BD5",
|
|
276
|
+
"common.rows": "{p0} \u884C",
|
|
277
|
+
"common.run": "\u8FD0\u884C",
|
|
278
|
+
"common.steps": "{p0} \u6B65",
|
|
279
|
+
"common.submit": "\u63D0\u4EA4",
|
|
280
|
+
"common.unknown": "\u672A\u77E5",
|
|
281
|
+
/* ── contextMenu ── */
|
|
282
|
+
"contextMenu.back": "\u540E\u9000",
|
|
283
|
+
"contextMenu.copyPageLink": "\u590D\u5236\u9875\u9762\u94FE\u63A5",
|
|
284
|
+
"contextMenu.forward": "\u524D\u8FDB",
|
|
285
|
+
"contextMenu.refresh": "\u5237\u65B0",
|
|
286
|
+
/* ── copy ── */
|
|
287
|
+
"copy.copied": "\u5DF2\u590D\u5236",
|
|
288
|
+
"copy.failed": "\u672A\u80FD\u590D\u5236\uFF0C\u8BF7\u91CD\u8BD5\u3002",
|
|
289
|
+
"copy.denied": "clipboard API \u88AB\u62D2\uFF08{p0}\uFF09\u4E14\u56DE\u9000 execCommand \u5931\u8D25",
|
|
290
|
+
"copy.unavailable": "\u526A\u8D34\u677F\u4E0D\u53EF\u7528\uFF08\u65E0 clipboard API \u4E14 execCommand \u56DE\u9000\u5931\u8D25\uFF09",
|
|
291
|
+
"copy.unknown": "\u672A\u77E5\u9519\u8BEF",
|
|
292
|
+
/* ── datatable ── */
|
|
293
|
+
"datatable.clear": "\u6E05\u7A7A",
|
|
294
|
+
"datatable.collapseGroup": "\u6298\u53E0\u5206\u7EC4 {p0}",
|
|
295
|
+
"datatable.columnSettingsAria": "\u5217\u8BBE\u7F6E",
|
|
296
|
+
"datatable.countUnit": "{p0} \u6761",
|
|
297
|
+
"datatable.editHint": "\u7F16\u8F91\u300C{p0}\u300D\uFF1A\u53CC\u51FB\u6216\u6309 Enter",
|
|
298
|
+
"datatable.editHintWithValue": "{p0}\uFF08\u53CC\u51FB\u6216\u6309 Enter \u7F16\u8F91\u300C{p1}\u300D\uFF09",
|
|
299
|
+
"datatable.empty": "\u6682\u65E0\u6570\u636E",
|
|
300
|
+
"datatable.emptyValue": "\uFF08\u7A7A\uFF09",
|
|
301
|
+
"datatable.expandGroup": "\u5C55\u5F00\u5206\u7EC4 {p0}",
|
|
302
|
+
"datatable.expandRow": "\u5C55\u5F00\u884C",
|
|
303
|
+
"datatable.filterChipAria": "\u7B5B\u9009\u300C{p0}\u300D",
|
|
304
|
+
"datatable.pageSizeAria": "\u6BCF\u9875\u6761\u6570",
|
|
305
|
+
"datatable.paginationAria": "\u5206\u9875",
|
|
306
|
+
"datatable.reset": "\u91CD\u7F6E",
|
|
307
|
+
"datatable.resizeAria": "\u8C03\u6574\u300C{p0}\u300D\u5217\u5BBD",
|
|
308
|
+
"datatable.searchAria": "\u641C\u7D22\u8868\u683C",
|
|
309
|
+
"datatable.searchPlaceholder": "\u641C\u7D22\u2026",
|
|
310
|
+
"datatable.selectAll": "\u5168\u9009",
|
|
311
|
+
"datatable.selectRow": "\u9009\u62E9\u8BE5\u884C",
|
|
312
|
+
"datatable.selectedCount": "\u5DF2\u9009 {p0} \u9879",
|
|
313
|
+
"datatable.totalCount": "\u5171 {p0} \u6761",
|
|
314
|
+
"datatable.totalLabel": "\u5408\u8BA1",
|
|
315
|
+
/* ── datePicker ── */
|
|
316
|
+
"datePicker.noDates": "\u6CA1\u6709\u53EF\u9009\u65E5\u671F",
|
|
317
|
+
"datePicker.clear": "\u6E05\u9664",
|
|
318
|
+
"datePicker.nextMonth": "\u4E0B\u4E00\u6708",
|
|
319
|
+
"datePicker.prevMonth": "\u4E0A\u4E00\u6708",
|
|
320
|
+
"datePicker.selectDate": "\u9009\u62E9\u65E5\u671F",
|
|
321
|
+
"datePicker.today": "\u4ECA\u5929",
|
|
322
|
+
"datePicker.weekdays": ["\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D", "\u65E5"],
|
|
323
|
+
"datePicker.weekdaysSunFirst": ["\u65E5", "\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D"],
|
|
324
|
+
"datePicker.yearMonth": "{p0} \u5E74 {p1} \u6708",
|
|
325
|
+
/* ── formValidate ── */
|
|
326
|
+
"formValidate.email": "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u90AE\u7BB1\u5730\u5740",
|
|
327
|
+
"formValidate.invalid": "\u8F93\u5165\u4E0D\u5408\u6CD5",
|
|
328
|
+
"formValidate.matches": "\u4E24\u6B21\u8F93\u5165\u4E0D\u4E00\u81F4",
|
|
329
|
+
"formValidate.max": "\u4E0D\u80FD\u5927\u4E8E {max}",
|
|
330
|
+
"formValidate.maxlength": "\u6700\u591A\u8F93\u5165 {max} \u4E2A\u5B57\u7B26",
|
|
331
|
+
"formValidate.min": "\u4E0D\u80FD\u5C0F\u4E8E {min}",
|
|
332
|
+
"formValidate.minlength": "\u81F3\u5C11\u8F93\u5165 {min} \u4E2A\u5B57\u7B26",
|
|
333
|
+
"formValidate.number": "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u6570\u5B57",
|
|
334
|
+
"formValidate.pattern": "\u8F93\u5165\u683C\u5F0F\u4E0D\u6B63\u786E",
|
|
335
|
+
"formValidate.required": "\u6B64\u9879\u4E3A\u5FC5\u586B\u9879",
|
|
336
|
+
"formValidate.selectPlaceholder": "\u8BF7\u9009\u62E9",
|
|
337
|
+
"formValidate.step": "\u6570\u503C\u5FC5\u987B\u662F {step} \u7684\u500D\u6570",
|
|
338
|
+
"formValidate.summary": "\u8868\u5355\u6709 {p0} \u9879\u5185\u5BB9\u9700\u8981\u4FEE\u6B63\uFF0C\u8BF7\u4FEE\u6539\u540E\u91CD\u65B0\u63D0\u4EA4",
|
|
339
|
+
"formValidate.tool.description": "\u5411\u7528\u6237\u6E32\u67D3\u4E00\u4E2A\u7ED3\u6784\u5316\u8868\u5355\u6536\u96C6\u8F93\u5165",
|
|
340
|
+
"formValidate.tool.fields": "\u5B57\u6BB5\u5217\u8868",
|
|
341
|
+
"formValidate.tool.help": "\u5B57\u6BB5\u4E0B\u65B9\u7684\u5E2E\u52A9\u6587\u6848",
|
|
342
|
+
"formValidate.tool.label": "\u5B57\u6BB5\u6807\u7B7E",
|
|
343
|
+
"formValidate.tool.max": "\u6700\u5927\u503C\uFF08number \u7528\uFF09",
|
|
344
|
+
"formValidate.tool.min": "\u6700\u5C0F\u503C\uFF08number \u7528\uFF09",
|
|
345
|
+
"formValidate.tool.name": "\u5B57\u6BB5\u540D\uFF08\u63D0\u4EA4\u503C\u7684 key\uFF09",
|
|
346
|
+
"formValidate.tool.options": "select \u9009\u9879\uFF08\u5B57\u7B26\u4E32\u6216 {label,value}\uFF09",
|
|
347
|
+
"formValidate.tool.pattern": "\u6B63\u5219\u7EA6\u675F\uFF08HTML pattern \u8BED\u6CD5\uFF0C\u6574\u4E32\u5339\u914D\uFF09",
|
|
348
|
+
"formValidate.tool.required": "\u662F\u5426\u5FC5\u586B",
|
|
349
|
+
"formValidate.tool.submitText": "\u63D0\u4EA4\u6309\u94AE\u6587\u6848\uFF0C\u9ED8\u8BA4\u300C\u63D0\u4EA4\u300D",
|
|
350
|
+
"formValidate.tool.title": "\u8868\u5355\u6807\u9898\uFF08\u53EF\u9009\uFF09",
|
|
351
|
+
"formValidate.tool.type": "\u63A7\u4EF6\u7C7B\u578B\uFF0C\u9ED8\u8BA4 text",
|
|
352
|
+
"formValidate.url": "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u94FE\u63A5\u5730\u5740",
|
|
353
|
+
/* ── input ── */
|
|
354
|
+
"input.clearSearch": "\u6E05\u7A7A\u641C\u7D22",
|
|
355
|
+
"input.hidePassword": "\u9690\u85CF\u5BC6\u7801",
|
|
356
|
+
"input.otpPosition": "\u7B2C {p0} \u4F4D\uFF0C\u5171 {p1} \u4F4D",
|
|
357
|
+
"panel.expand": "\u5C55\u5F00",
|
|
358
|
+
"panel.collapse": "\u6298\u53E0",
|
|
359
|
+
"input.showPassword": "\u663E\u793A\u5BC6\u7801",
|
|
360
|
+
/* ── kbAccess ── */
|
|
361
|
+
"kbAccess.approveTip": "\u6279\u51C6\u8BE5\u8BBF\u95EE\u7533\u8BF7",
|
|
362
|
+
"kbAccess.approvedBadge": "\u5DF2\u6279\u51C6 \xB7 {p0}",
|
|
363
|
+
"kbAccess.approverNotePlaceholder": "\u7ED9\u8BF7\u6C42\u4EBA\u7684\u7559\u8A00\uFF08\u53EF\u9009\uFF09",
|
|
364
|
+
"kbAccess.daysLeft": "{p0} \u5929\u540E",
|
|
365
|
+
"kbAccess.defaultSubject": "\u8BE5\u5185\u5BB9",
|
|
366
|
+
"kbAccess.deniedHint": "\u672A\u901A\u8FC7\u2014\u2014\u53EF\u8C03\u6574\u7406\u7531\u540E\u91CD\u65B0\u7533\u8BF7",
|
|
367
|
+
"kbAccess.denyNoteLabel": "\u62D2\u7EDD\u7559\u8A00\uFF08\u53EF\u9009\uFF09",
|
|
368
|
+
"kbAccess.duration30d": "30 \u5929",
|
|
369
|
+
"kbAccess.duration7d": "7 \u5929",
|
|
370
|
+
"kbAccess.durationForever": "\u6C38\u4E45",
|
|
371
|
+
"kbAccess.durationLabel": "\u8BBF\u95EE\u65F6\u957F",
|
|
372
|
+
"kbAccess.expired": "\u5DF2\u5230\u671F",
|
|
373
|
+
"kbAccess.expiresAt": "{p0}\u5230\u671F",
|
|
374
|
+
"kbAccess.grantAsPrefix": "\u6279\u51C6\u4E3A{p0}",
|
|
375
|
+
"kbAccess.grantRoleLabel": "\u6279\u51C6\u89D2\u8272",
|
|
376
|
+
"kbAccess.hoursLeft": "{p0} \u5C0F\u65F6\u540E",
|
|
377
|
+
"kbAccess.minutesLeft": "{p0} \u5206\u949F\u540E",
|
|
378
|
+
"kbAccess.ownerLabel": "\u5185\u5BB9\u8D1F\u8D23\u4EBA",
|
|
379
|
+
"kbAccess.ownerPrefix": "\u8D1F\u8D23\u4EBA\uFF1A{p0}",
|
|
380
|
+
"kbAccess.reapply": "\u91CD\u65B0\u7533\u8BF7",
|
|
381
|
+
"kbAccess.reasonLabel": "\u7533\u8BF7\u7406\u7531",
|
|
382
|
+
"kbAccess.reasonPlaceholder": "\u8BF4\u660E\u4E1A\u52A1\u539F\u56E0\uFF08\u5BA1\u6279\u4EBA\u53EF\u89C1\uFF09",
|
|
383
|
+
"kbAccess.rejectTip": "\u62D2\u7EDD\u8BE5\u8BBF\u95EE\u7533\u8BF7",
|
|
384
|
+
"kbAccess.requestRenewal": "\u7533\u8BF7\u7EED\u671F",
|
|
385
|
+
"kbAccess.requestToPrefix": "\u8BF7\u6C42\u5C06\u53D1\u9001\u7ED9\uFF1A{p0}",
|
|
386
|
+
"kbAccess.restrictedContent": "\u53D7\u9650\u5185\u5BB9",
|
|
387
|
+
"kbAccess.restrictedHint": "\u6B64\u5185\u5BB9\u4EC5\u5BF9\u6388\u6743\u8005\u5F00\u653E",
|
|
388
|
+
"kbAccess.revokedHint": "\u8BBF\u95EE\u5DF2\u88AB\u6536\u56DE",
|
|
389
|
+
"kbAccess.roleLabel": "\u7533\u8BF7\u89D2\u8272",
|
|
390
|
+
"kbAccess.submitRequest": "\u63D0\u4EA4\u7533\u8BF7",
|
|
391
|
+
"kbAccess.switchIdentity": "\u5207\u6362\u8EAB\u4EFD",
|
|
392
|
+
"kbAccess.switchIdentityTip": "\u5207\u6362\u8EAB\u4EFD\u540E\u91CD\u65B0\u68C0\u67E5\u6743\u9650",
|
|
393
|
+
"kbAccess.unknownRequester": "\u672A\u77E5\u8BF7\u6C42\u4EBA",
|
|
394
|
+
"kbAccess.waitingApproval": "\u7B49\u5F85 {p0} \u5BA1\u6279",
|
|
395
|
+
/* ── kbAcl ── */
|
|
396
|
+
"kbAcl.breakHint": "\u505C\u6B62\u4ECE\u7236\u7EA7\u7EE7\u627F\uFF0C\u6539\u4E3A\u72EC\u7ACB\u7BA1\u7406\u672C\u9879\u6743\u9650",
|
|
397
|
+
"kbAcl.breakInheritance": "\u505C\u6B62\u7EE7\u627F",
|
|
398
|
+
"kbAcl.brokenNotice": "\u5DF2\u505C\u6B62\u7EE7\u627F\u2014\u2014\u672C\u9879\u6743\u9650\u72EC\u7ACB\u4E8E\u7236\u7EA7",
|
|
399
|
+
"kbAcl.detachedChildren": "{p0}\uFF1A{p1} \u4E2A\u5B50\u9879\u5DF2\u8131\u79BB",
|
|
400
|
+
"kbAcl.directAccess": "\u76F4\u63A5\u8BBF\u95EE",
|
|
401
|
+
"kbAcl.exception": "\u4F8B\u5916",
|
|
402
|
+
"kbAcl.expiredOn": "\u5DF2\u8FC7\u671F\uFF08{p0}\uFF09",
|
|
403
|
+
"kbAcl.expiresIn": "{p0} \u5230\u671F",
|
|
404
|
+
"kbAcl.grantAccess": "\u6388\u4E88\u8BBF\u95EE",
|
|
405
|
+
"kbAcl.inheritedFrom": "\u7EE7\u627F\u81EA {p0}",
|
|
406
|
+
"kbAcl.inheritedFromLabel": "\u7EE7\u627F\u81EA",
|
|
407
|
+
"kbAcl.linkAccess": "\u94FE\u63A5\u8BBF\u95EE",
|
|
408
|
+
"kbAcl.noDirect": "\u6682\u65E0\u76F4\u63A5\u6388\u6743",
|
|
409
|
+
"kbAcl.noLinks": "\u65E0\u94FE\u63A5",
|
|
410
|
+
"kbAcl.removeEntry": "\u79FB\u9664 {p0}",
|
|
411
|
+
"kbAcl.restoreHint": "\u6062\u590D\u7EE7\u627F\u5C06\u4E22\u5F03\u672C\u9879\u81EA\u5B9A\u4E49\u7684\u6743\u9650",
|
|
412
|
+
"kbAcl.restoreInheritance": "\u6062\u590D\u7EE7\u627F",
|
|
413
|
+
"kbAcl.rootNotice": "\u6839\u7EA7\u8D44\u6E90\u2014\u2014\u65E0\u7236\u7EA7\u7EE7\u627F",
|
|
414
|
+
"kbAcl.systemBadge": "\u7CFB\u7EDF\u7BA1\u7406",
|
|
415
|
+
"kbAcl.systemNote": "\u7CFB\u7EDF\u81EA\u52A8\uFF0C\u4E0D\u53EF\u624B\u5DE5\u79FB\u9664",
|
|
416
|
+
"kbAcl.unnamedResource": "\u672A\u547D\u540D\u8D44\u6E90",
|
|
417
|
+
"kbAcl.visibleToCount": "\u5BF9 {p0} \u4EBA\u53EF\u89C1",
|
|
418
|
+
/* ── kbAnswer ── */
|
|
419
|
+
"kbAnswer.chartBar": "\u67F1\u72B6",
|
|
420
|
+
"kbAnswer.chartLine": "\u6298\u7EBF",
|
|
421
|
+
"kbAnswer.chartPie": "\u997C\u56FE",
|
|
422
|
+
"kbAnswer.exportNoun": "\u5BFC\u51FA {p0}",
|
|
423
|
+
"kbAnswer.filtered": "\u5DF2\u6309\u4F60\u7684\u6570\u636E\u6743\u9650\u8FC7\u6EE4",
|
|
424
|
+
"kbAnswer.filteredDetail": "\u5DF2\u6309\u4F60\u7684\u6570\u636E\u6743\u9650\u8FC7\u6EE4\uFF1A{p0}",
|
|
425
|
+
"kbAnswer.followups": "\u8FFD\u95EE\u5EFA\u8BAE",
|
|
426
|
+
"kbAnswer.hitAssets": "\u547D\u4E2D\u8D44\u4EA7\uFF1A{p0}",
|
|
427
|
+
"kbAnswer.kindCurated": "\u4EBA\u5DE5\u7B56\u5C55",
|
|
428
|
+
"kbAnswer.kindFunction": "\u51FD\u6570",
|
|
429
|
+
"kbAnswer.kindParameterized": "\u53C2\u6570\u5316\u67E5\u8BE2",
|
|
430
|
+
"kbAnswer.maskedPrefix": "\u5DF2\u8131\u654F\u5217\uFF1A",
|
|
431
|
+
"kbAnswer.rerunTip": "\u53C2\u6570\u53EF\u6539\u91CD\u8DD1",
|
|
432
|
+
"kbAnswer.truncated": "\u5DF2\u622A\u65AD\uFF1A\u663E\u793A {p0}/{p1} \u884C{p2}",
|
|
433
|
+
"kbAnswer.verifiedBadge": "\u8BA4\u8BC1\u7B54\u6848",
|
|
434
|
+
/* ── kbAudit ── */
|
|
435
|
+
"kbAudit.actionDetail": "\u5904\u7F6E\uFF1A{p0} \xB7 {p1}",
|
|
436
|
+
"kbAudit.actionLabel": "\u5904\u7F6E",
|
|
437
|
+
"kbAudit.alertedNote": "\u5DF2\u5B9E\u65F6\u544A\u8B66\u5B89\u5168\u56E2\u961F",
|
|
438
|
+
"kbAudit.channelFilterAria": "\u5BA1\u8BA1\u901A\u9053\u8FC7\u6EE4",
|
|
439
|
+
"kbAudit.channelPermission": "\u6743\u9650\u53D8\u66F4",
|
|
440
|
+
"kbAudit.channelRead": "\u8BFB\u53D6",
|
|
441
|
+
"kbAudit.channelRequest": "\u7533\u8BF7",
|
|
442
|
+
"kbAudit.channelSystem": "\u7CFB\u7EDF",
|
|
443
|
+
"kbAudit.empty": "\u6682\u65E0\u5BA1\u8BA1\u4E8B\u4EF6",
|
|
444
|
+
"kbAudit.exportTip": "\u5BFC\u51FA\u5F53\u524D\u8FC7\u6EE4\u89C6\u56FE\u4E3A CSV",
|
|
445
|
+
"kbAudit.hygieneLabel": "\u6743\u9650\u5F02\u5473",
|
|
446
|
+
"kbAudit.noHygiene": "\u672A\u53D1\u73B0\u6743\u9650\u5F02\u5473",
|
|
447
|
+
/* ── kbCanvas ── */
|
|
448
|
+
"kbCanvas.splitterAria": "\u8C03\u6574\u753B\u5E03\u53CC\u680F\u6BD4\u4F8B",
|
|
449
|
+
"kbCanvas.splitterTip": "\u62D6\u62FD\u8C03\u6574\u6BD4\u4F8B\uFF08\u2190/\u2192 \u5FAE\u8C03\uFF0C\u53CC\u51FB\u590D\u4F4D\uFF09",
|
|
450
|
+
/* ── kbCheckpoint ── */
|
|
451
|
+
"kbCheckpoint.chatAuditNote": "\u8BA8\u8BBA\u5386\u53F2\u6709\u5BA1\u8BA1\u4EF7\u503C",
|
|
452
|
+
"kbCheckpoint.label": "\u68C0\u67E5\u70B9",
|
|
453
|
+
"kbCheckpoint.restore": "\u6062\u590D\u68C0\u67E5\u70B9",
|
|
454
|
+
"kbCheckpoint.scopeBoth": "\u5185\u5BB9\u4E0E\u5BF9\u8BDD",
|
|
455
|
+
"kbCheckpoint.scopeChat": "\u4EC5\u5BF9\u8BDD",
|
|
456
|
+
"kbCheckpoint.scopeContent": "\u4EC5\u5185\u5BB9\uFF08\u4FDD\u7559\u5BF9\u8BDD\uFF09",
|
|
457
|
+
"kbCheckpoint.scopeMissing": "\u8BE5\u68C0\u67E5\u70B9\u672A\u5305\u542B\u6B64\u6062\u590D\u8303\u56F4",
|
|
458
|
+
/* ── kbChunks ── */
|
|
459
|
+
"kbChunks.addKeyword": "+ \u5173\u952E\u8BCD",
|
|
460
|
+
"kbChunks.chunkAddKeywordAria": "chunk {p0} \u65B0\u589E\u5173\u952E\u8BCD",
|
|
461
|
+
"kbChunks.chunkContentAria": "chunk {p0} \u5185\u5BB9",
|
|
462
|
+
"kbChunks.chunkEnableAria": "chunk {p0} \u542F\u7528",
|
|
463
|
+
"kbChunks.deleteChunkAria": "\u5220\u9664 chunk {p0}",
|
|
464
|
+
"kbChunks.disableNote": "\u5173\u95ED\u540E\u4E0D\u5220\u9664\uFF0C\u4EC5\u6392\u9664\u51FA\u68C0\u7D22",
|
|
465
|
+
"kbChunks.edited": "\u5DF2\u7F16\u8F91",
|
|
466
|
+
"kbChunks.empty": "\u6682\u65E0 chunk",
|
|
467
|
+
"kbChunks.modeFull": "\u5168\u6587",
|
|
468
|
+
"kbChunks.modeLabel": "\u641C\u7D22\u6A21\u5F0F",
|
|
469
|
+
"kbChunks.modeVector": "\u8BED\u4E49",
|
|
470
|
+
"kbChunks.removeKeyword": "\u79FB\u9664\u5173\u952E\u8BCD {p0}",
|
|
471
|
+
"kbChunks.searchAria": "\u641C\u7D22 chunk",
|
|
472
|
+
"kbChunks.searchFullPlaceholder": "\u5168\u6587\u641C\u7D22 chunk\u2026",
|
|
473
|
+
"kbChunks.searchVectorPlaceholder": "\u8BED\u4E49\u641C\u7D22 chunk\u2026",
|
|
474
|
+
/* ── kbCitation ── */
|
|
475
|
+
"kbCitation.sourceN": "\u6765\u6E90 {p0}",
|
|
476
|
+
"kbCitation.unavailable": "\u6765\u6E90\u5DF2\u4E0D\u53EF\u7528",
|
|
477
|
+
/* ── kbClarify ── */
|
|
478
|
+
"kbClarify.parsedPrefix": "\u5DF2\u89E3\u6790\uFF1A",
|
|
479
|
+
/* ── kbConflict ── */
|
|
480
|
+
"kbConflict.owner": "\u8D23\u4EFB\u4EBA {p0}",
|
|
481
|
+
/* ── kbConnector ── */
|
|
482
|
+
"kbConnector.changeRate": "\u53D8\u66F4\u7387",
|
|
483
|
+
"kbConnector.crawlRate": "\u6293\u53D6\u7387",
|
|
484
|
+
"kbConnector.credentials": "\u51ED\u8BC1",
|
|
485
|
+
"kbConnector.credentialsExpired": "\u51ED\u8BC1\u8FC7\u671F",
|
|
486
|
+
"kbConnector.editSchedule": "\u7F16\u8F91\u8BA1\u5212",
|
|
487
|
+
"kbConnector.empty": "\u6682\u65E0\u8FDE\u63A5\u5668",
|
|
488
|
+
"kbConnector.failing": "\u5F02\u5E38",
|
|
489
|
+
"kbConnector.lastSync": "\u6700\u8FD1\u540C\u6B65 {p0}",
|
|
490
|
+
"kbConnector.neverSynced": "\u4ECE\u672A\u540C\u6B65",
|
|
491
|
+
"kbConnector.notConfigured": "\u672A\u914D\u7F6E",
|
|
492
|
+
"kbConnector.off": "\u5DF2\u505C\u7528",
|
|
493
|
+
"kbConnector.perDay": "{p0}/\u5929",
|
|
494
|
+
"kbConnector.reauth": "\u91CD\u65B0\u6388\u6743",
|
|
495
|
+
"kbConnector.stale": "\u505C\u6EDE",
|
|
496
|
+
"kbConnector.syncNow": "\u7ACB\u5373\u540C\u6B65",
|
|
497
|
+
"kbConnector.synced": "\u5DF2\u540C\u6B65",
|
|
498
|
+
/* ── kbCore ── */
|
|
499
|
+
"kbCore.accessDenied": "\u672A\u901A\u8FC7",
|
|
500
|
+
"kbCore.accessExpired": "\u5DF2\u8FC7\u671F",
|
|
501
|
+
"kbCore.accessExpiring": "\u5373\u5C06\u5230\u671F",
|
|
502
|
+
"kbCore.accessGranted": "\u5DF2\u5F00\u901A",
|
|
503
|
+
"kbCore.accessNotRequested": "\u672A\u7533\u8BF7",
|
|
504
|
+
"kbCore.accessPending": "\u5F85\u5BA1\u6279",
|
|
505
|
+
"kbCore.accessRequested": "\u5DF2\u63D0\u4EA4",
|
|
506
|
+
"kbCore.accessRevoked": "\u5DF2\u6536\u56DE",
|
|
507
|
+
"kbCore.auditApprove": "\u6279\u51C6",
|
|
508
|
+
"kbCore.auditBreakGlass": "\u5E94\u6025\u8BBF\u95EE",
|
|
509
|
+
"kbCore.auditDelegation": "\u59D4\u6D3E",
|
|
510
|
+
"kbCore.auditDeny": "\u62D2\u7EDD",
|
|
511
|
+
"kbCore.auditGrant": "\u6388\u4E88",
|
|
512
|
+
"kbCore.auditPermissionChange": "\u6743\u9650\u53D8\u66F4",
|
|
513
|
+
"kbCore.auditPreview": "\u9884\u89C8",
|
|
514
|
+
"kbCore.auditRead": "\u8BFB\u53D6",
|
|
515
|
+
"kbCore.auditRequest": "\u7533\u8BF7",
|
|
516
|
+
"kbCore.auditRevoke": "\u6536\u56DE",
|
|
517
|
+
"kbCore.auditSync": "\u6743\u9650\u540C\u6B65",
|
|
518
|
+
"kbCore.daysAgo": "{p0} \u5929\u524D",
|
|
519
|
+
"kbCore.hoursAgo": "{p0} \u5C0F\u65F6\u524D",
|
|
520
|
+
"kbCore.hygieneBroadGroup": "\u8FC7\u5BBD\u7EC4\u6388\u6743",
|
|
521
|
+
"kbCore.hygieneBrokenInheritance": "\u65AD\u7EE7\u627F",
|
|
522
|
+
"kbCore.hygieneOrgWideLink": "\u7EC4\u7EC7\u7EA7\u94FE\u63A5",
|
|
523
|
+
"kbCore.hygieneOrphanedOwner": "\u8D1F\u8D23\u4EBA\u7F3A\u4F4D",
|
|
524
|
+
"kbCore.hygieneOverexposed": "\u8FC7\u5EA6\u66B4\u9732",
|
|
525
|
+
"kbCore.hygieneSensitiveMismatch": "\u654F\u611F\u5EA6\u9519\u914D",
|
|
526
|
+
"kbCore.justNow": "\u521A\u521A",
|
|
527
|
+
"kbCore.levelComment": "\u53EF\u8BC4\u8BBA",
|
|
528
|
+
"kbCore.levelEdit": "\u53EF\u7F16\u8F91",
|
|
529
|
+
"kbCore.levelNone": "\u65E0\u6743\u9650",
|
|
530
|
+
"kbCore.levelOwner": "\u8D1F\u8D23\u4EBA",
|
|
531
|
+
"kbCore.levelView": "\u53EF\u67E5\u770B",
|
|
532
|
+
"kbCore.minutesAgo": "{p0} \u5206\u949F\u524D",
|
|
533
|
+
"kbCore.runCancelled": "\u5DF2\u53D6\u6D88",
|
|
534
|
+
"kbCore.runDone": "\u5DF2\u5B8C\u6210",
|
|
535
|
+
"kbCore.runFailed": "\u5931\u8D25",
|
|
536
|
+
"kbCore.runQueued": "\u6392\u961F\u4E2D",
|
|
537
|
+
"kbCore.runRunning": "\u8FDB\u884C\u4E2D",
|
|
538
|
+
"kbCore.runUnstarted": "\u672A\u5F00\u59CB",
|
|
539
|
+
"kbCore.stageAgent": "\u4EE3\u7406",
|
|
540
|
+
"kbCore.stageChunk": "\u5207\u7247",
|
|
541
|
+
"kbCore.stageEmbed": "\u5411\u91CF\u5316",
|
|
542
|
+
"kbCore.stageGeneration": "\u751F\u6210",
|
|
543
|
+
"kbCore.stageGuard": "\u62A4\u680F",
|
|
544
|
+
"kbCore.stageQuery": "\u67E5\u8BE2",
|
|
545
|
+
"kbCore.stageRerank": "\u91CD\u6392",
|
|
546
|
+
"kbCore.stageRetrieval": "\u68C0\u7D22",
|
|
547
|
+
"kbCore.stageTool": "\u5DE5\u5177",
|
|
548
|
+
"kbCore.typeApi": "\u63A5\u53E3",
|
|
549
|
+
"kbCore.typeCode": "\u4EE3\u7801",
|
|
550
|
+
"kbCore.typeDatabase": "\u6570\u636E\u5E93",
|
|
551
|
+
"kbCore.typeDocument": "\u6587\u6863",
|
|
552
|
+
"kbCore.typeEmail": "\u90AE\u4EF6",
|
|
553
|
+
"kbCore.typeImage": "\u56FE\u7247",
|
|
554
|
+
"kbCore.typeKb": "\u77E5\u8BC6\u5E93",
|
|
555
|
+
"kbCore.typeTable": "\u8868\u683C",
|
|
556
|
+
"kbCore.typeTicket": "\u5DE5\u5355",
|
|
557
|
+
"kbCore.typeWebpage": "\u7F51\u9875",
|
|
558
|
+
"kbCore.unnamedSource": "\u672A\u547D\u540D\u6765\u6E90",
|
|
559
|
+
"kbCore.unnamedSubject": "\u672A\u547D\u540D\u4E3B\u4F53",
|
|
560
|
+
"kbCore.visHidden": "\u4E0D\u53EF\u89C1",
|
|
561
|
+
"kbCore.visMetadataOnly": "\u4EC5\u5143\u6570\u636E",
|
|
562
|
+
"kbCore.visSummaryOnly": "\u4EC5\u6458\u8981",
|
|
563
|
+
"kbCore.visVisible": "\u53EF\u89C1",
|
|
564
|
+
/* ── kbEval ── */
|
|
565
|
+
"kbEval.avgA": "A \u5747\u5206 {p0}",
|
|
566
|
+
"kbEval.avgB": "B \u5747\u5206 {p0}",
|
|
567
|
+
"kbEval.compare": "\u5BF9\u6BD4",
|
|
568
|
+
"kbEval.runSelectAria": "\u9009\u62E9\u5BF9\u6BD4\u8FD0\u884C",
|
|
569
|
+
"kbEval.expected": "\u671F\u671B",
|
|
570
|
+
"kbEval.gradeImprovement": "\u63D0\u5347",
|
|
571
|
+
"kbEval.gradeRegression": "\u56DE\u5F52",
|
|
572
|
+
"kbEval.gradeTie": "\u6301\u5E73",
|
|
573
|
+
"kbEval.gradeTradeoff": "\u6743\u8861",
|
|
574
|
+
"kbEval.noData": "\u6CA1\u6709\u5BF9\u6BD4\u6570\u636E",
|
|
575
|
+
"kbEval.onlyRegression": "\u4EC5\u770B\u56DE\u5F52",
|
|
576
|
+
"kbEval.outputA": "\u8F93\u51FA A",
|
|
577
|
+
"kbEval.outputB": "\u8F93\u51FA B",
|
|
578
|
+
"kbEval.outputN": "\u8F93\u51FA {p0}",
|
|
579
|
+
/* ── kbExplain ── */
|
|
580
|
+
"kbExplain.empty": "\u6682\u65E0\u53E3\u5F84\u4FE1\u606F",
|
|
581
|
+
"kbExplain.groupAgg": "\u805A\u5408",
|
|
582
|
+
"kbExplain.groupColumn": "\u5217",
|
|
583
|
+
"kbExplain.groupFilter": "\u7B5B\u9009",
|
|
584
|
+
"kbExplain.groupTable": "\u8868",
|
|
585
|
+
"kbExplain.trigger": "\u8FD9\u4E2A\u6570\u5B57\u662F\u600E\u4E48\u7B97\u51FA\u6765\u7684",
|
|
586
|
+
"kbExplain.viewDefinition": "\u67E5\u770B\u53E3\u5F84",
|
|
587
|
+
/* ── kbFilter ── */
|
|
588
|
+
"kbFilter.addGroup": "+ \u7EC4",
|
|
589
|
+
"kbFilter.addRule": "+ \u89C4\u5219",
|
|
590
|
+
"kbFilter.and": "\u4E14",
|
|
591
|
+
"kbFilter.combineMode": "\u7EC4\u5408\u65B9\u5F0F {p0}",
|
|
592
|
+
"kbFilter.copyDsl": "\u590D\u5236 DSL",
|
|
593
|
+
"kbFilter.deleteGroup": "\u5220\u9664\u7EC4",
|
|
594
|
+
"kbFilter.deleteRule": "\u5220\u9664\u89C4\u5219",
|
|
595
|
+
"kbFilter.fieldLabel": "\u5B57\u6BB5",
|
|
596
|
+
"kbFilter.fieldPlaceholder": "\u8FC7\u6EE4\u5B57\u6BB5",
|
|
597
|
+
"kbFilter.noValueNeeded": "\uFF08\u65E0\u9700\u503C\uFF09",
|
|
598
|
+
"kbFilter.none": "\uFF08\u65E0\u8FC7\u6EE4\uFF09",
|
|
599
|
+
"kbFilter.opContains": "\u5305\u542B",
|
|
600
|
+
"kbFilter.opEq": "\u7B49\u4E8E",
|
|
601
|
+
"kbFilter.opExists": "\u5B58\u5728",
|
|
602
|
+
"kbFilter.opGt": "\u5927\u4E8E",
|
|
603
|
+
"kbFilter.opGte": "\u5927\u4E8E\u7B49\u4E8E",
|
|
604
|
+
"kbFilter.opIn": "\u5C5E\u4E8E",
|
|
605
|
+
"kbFilter.opLt": "\u5C0F\u4E8E",
|
|
606
|
+
"kbFilter.opLte": "\u5C0F\u4E8E\u7B49\u4E8E",
|
|
607
|
+
"kbFilter.opNe": "\u4E0D\u7B49\u4E8E",
|
|
608
|
+
"kbFilter.operatorLabel": "\u64CD\u4F5C\u7B26",
|
|
609
|
+
"kbFilter.or": "\u6216",
|
|
610
|
+
"kbFilter.toggleAndOr": "\u5207\u6362 AND / OR",
|
|
611
|
+
"kbFilter.valueAria": "\u8FC7\u6EE4\u503C",
|
|
612
|
+
"kbFilter.valueLabel": "\u503C",
|
|
613
|
+
"kbFilter.valuePlaceholder": "\u503C 1, \u503C 2\uFF08\u9017\u53F7\u5206\u9694\uFF09",
|
|
614
|
+
/* ── kbGap ── */
|
|
615
|
+
"kbGap.addSynonym": "\u52A0\u540C\u4E49\u8BCD",
|
|
616
|
+
"kbGap.colCount": "\u6B21\u6570",
|
|
617
|
+
"kbGap.colLastSeen": "\u6700\u8FD1\u51FA\u73B0",
|
|
618
|
+
"kbGap.colQuery": "\u67E5\u8BE2",
|
|
619
|
+
"kbGap.colShare": "\u5360\u6BD4",
|
|
620
|
+
"kbGap.createDoc": "\u5EFA\u6587\u6863",
|
|
621
|
+
"kbGap.empty": "\u6CA1\u6709\u672A\u547D\u4E2D\u67E5\u8BE2\u2014\u2014\u8986\u76D6\u826F\u597D",
|
|
622
|
+
"kbGap.title": "\u672A\u547D\u4E2D\u67E5\u8BE2\u8D8B\u52BF",
|
|
623
|
+
"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",
|
|
624
|
+
"kbGap.zeroClickRate": "\u96F6\u70B9\u51FB\u7387",
|
|
625
|
+
"kbGap.zeroClickTitle": "\u96F6\u70B9\u51FB \u2260 \u5931\u8D25",
|
|
626
|
+
/* ── kbHittest ── */
|
|
627
|
+
"kbHittest.addAria": "\u65B0\u589E\u6D4B\u8BD5\u95EE\u9898",
|
|
628
|
+
"kbHittest.addPlaceholder": "\u65B0\u589E\u95EE\u9898\uFF0CEnter \u6DFB\u52A0",
|
|
629
|
+
"kbHittest.avgScore": "\u5747\u5206",
|
|
630
|
+
"kbHittest.deleteQuestion": "\u5220\u9664\u95EE\u9898",
|
|
631
|
+
"kbHittest.empty": "\u6682\u65E0\u6D4B\u8BD5\u95EE\u9898\u2014\u2014\u6DFB\u52A0\u7B2C\u4E00\u6761\uFF0C\u5F00\u59CB\u53EC\u56DE\u56DE\u5F52",
|
|
632
|
+
"kbHittest.expectHit": "\u671F\u671B\u547D\u4E2D\u5728\u524D\u6392\u547D\u4E2D\u4E2D",
|
|
633
|
+
"kbHittest.expectMiss": "\u671F\u671B\u672A\u547D\u4E2D",
|
|
634
|
+
"kbHittest.hitRate": "\u547D\u4E2D\u7387",
|
|
635
|
+
"kbHittest.noExpectation": "\u672A\u8BBE\u671F\u671B",
|
|
636
|
+
"kbHittest.notRun": "\u672A\u8FD0\u884C",
|
|
637
|
+
"kbHittest.pass": "\u901A\u8FC7",
|
|
638
|
+
"kbHittest.pin": "\u7F6E\u9876\u56FA\u5B9A",
|
|
639
|
+
"kbHittest.runAll": "\u8FD0\u884C\u5168\u90E8",
|
|
640
|
+
"kbHittest.sessionOnly": "\u53C2\u6570\u4EC5\u672C\u6B21\u4F1A\u8BDD\u751F\u6548",
|
|
641
|
+
"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",
|
|
642
|
+
"kbHittest.unpin": "\u53D6\u6D88\u7F6E\u9876",
|
|
643
|
+
/* ── kbMetadata ── */
|
|
644
|
+
"kbMetadata.addField": "\u65B0\u589E\u5B57\u6BB5",
|
|
645
|
+
"kbMetadata.builtIn": "\u5185\u7F6E",
|
|
646
|
+
"kbMetadata.colField": "\u5B57\u6BB5",
|
|
647
|
+
"kbMetadata.colType": "\u7C7B\u578B",
|
|
648
|
+
"kbMetadata.colValue": "\u503C",
|
|
649
|
+
"kbMetadata.empty": "\u6682\u65E0\u5143\u6570\u636E\u5B57\u6BB5",
|
|
650
|
+
"kbMetadata.nameLabel": "\u65B0\u5B57\u6BB5\u540D",
|
|
651
|
+
"kbMetadata.namePlaceholder": "\u5B57\u6BB5\u540D\uFF0C\u5982 department",
|
|
652
|
+
"kbMetadata.removeField": "\u79FB\u9664\u5B57\u6BB5 {p0}",
|
|
653
|
+
"kbMetadata.typeLabel": "\u65B0\u5B57\u6BB5\u7C7B\u578B",
|
|
654
|
+
"kbMetadata.valueOf": "{p0} \u7684\u503C",
|
|
655
|
+
/* ── kbPassage ── */
|
|
656
|
+
"kbPassage.blockRange": "\u5757 {p0}\u2013{p1}",
|
|
657
|
+
"kbPassage.close": "\u5173\u95ED\u539F\u6587",
|
|
658
|
+
"kbPassage.expandContext": "\u5C55\u5F00\u4E0A\u4E0B\u6587",
|
|
659
|
+
"kbPassage.locate": "\u539F\u6587\u5B9A\u4F4D",
|
|
660
|
+
"kbPassage.none": "\uFF08\u65E0\u539F\u6587\uFF09",
|
|
661
|
+
"kbPassage.pageRange": "\u7B2C {p0}\u2013{p1} \u9875",
|
|
662
|
+
"kbPassage.restricted": "\u5185\u5BB9\u53D7\u9650",
|
|
663
|
+
"kbPassage.unitByte": "\u5B57\u8282",
|
|
664
|
+
"kbPassage.unitChar": "\u5B57\u7B26",
|
|
665
|
+
/* ── kbPipeline ── */
|
|
666
|
+
"kbPipeline.empty": "\u6682\u65E0\u89E3\u6790\u4EFB\u52A1",
|
|
667
|
+
"kbPipeline.progress": "\u89E3\u6790\u8FDB\u5EA6",
|
|
668
|
+
"kbPipeline.rerun": "\u91CD\u8DD1",
|
|
669
|
+
"kbPipeline.unknownStage": "\u672A\u77E5\u9636\u6BB5",
|
|
670
|
+
/* ── kbQa ── */
|
|
671
|
+
"kbQa.colAnswer": "\u7B54\u6848",
|
|
672
|
+
"kbQa.colQuestion": "\u95EE\u9898",
|
|
673
|
+
"kbQa.csvHint": "CSV \u6A21\u677F\uFF1Aquestion,answer\uFF08\u6BCF\u884C\u4E00\u5BF9\uFF0CUTF-8\uFF09",
|
|
674
|
+
"kbQa.deleteRow": "\u5220\u9664\u7B2C {p0} \u884C",
|
|
675
|
+
"kbQa.empty": "\u6682\u65E0\u8BA4\u8BC1\u95EE\u7B54\u5BF9",
|
|
676
|
+
"kbQa.importCsv": "\u5BFC\u5165 CSV",
|
|
677
|
+
/* ── kbRerank ── */
|
|
678
|
+
"kbRerank.after": "\u91CD\u6392\u540E",
|
|
679
|
+
"kbRerank.before": "\u91CD\u6392\u524D",
|
|
680
|
+
"kbRerank.compareTitle": "\u91CD\u6392\u5BF9\u6BD4",
|
|
681
|
+
"kbRerank.down": "\u4E0B\u964D {p0} \u4F4D",
|
|
682
|
+
"kbRerank.dropped": "\u843D\u9009",
|
|
683
|
+
"kbRerank.empty": "\u4E24\u4FA7\u5747\u4E3A\u7A7A\u2014\u2014\u8FD0\u884C\u68C0\u7D22\u540E\u518D\u5BF9\u6BD4",
|
|
684
|
+
"kbRerank.enableCompare": "\u542F\u7528\u91CD\u6392\u5BF9\u6BD4",
|
|
685
|
+
"kbRerank.newIn": "\u65B0\u8FDB",
|
|
686
|
+
"kbRerank.unmarked": "\u672A\u6807",
|
|
687
|
+
"kbRerank.up": "\u4E0A\u5347 {p0} \u4F4D",
|
|
688
|
+
/* ── kbRetrieval ── */
|
|
689
|
+
"kbRetrieval.breakdown": "\u62C6\u89E3",
|
|
690
|
+
"kbRetrieval.copyParams": "\u590D\u5236\u53C2\u6570 JSON",
|
|
691
|
+
"kbRetrieval.decreaseTopK": "\u51CF\u5C11 topK",
|
|
692
|
+
"kbRetrieval.empty": "\u8F93\u5165\u95EE\u9898\u5E76\u8FD0\u884C\uFF0C\u547D\u4E2D\u7ED3\u679C\u5C06\u51FA\u73B0\u5728\u8FD9\u91CC",
|
|
693
|
+
"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",
|
|
694
|
+
"kbRetrieval.hybridWeight": "\u6DF7\u5408\u6743\u91CD\uFF08\u5DE6\u8BED\u4E49\u53F3\u5173\u952E\u8BCD\uFF09",
|
|
695
|
+
"kbRetrieval.identityLabel": "\u68C0\u7D22\u8EAB\u4EFD",
|
|
696
|
+
"kbRetrieval.identityShort": "\u8EAB\u4EFD",
|
|
697
|
+
"kbRetrieval.increaseTopK": "\u589E\u52A0 topK",
|
|
698
|
+
"kbRetrieval.keywordHint": "\u5173\u952E\u8BCD\uFF1A\u5927\u5E93\u5FEB\u901F\u7CBE\u786E",
|
|
699
|
+
"kbRetrieval.layerLabel": "\u8FC7\u6EE4\u5C42",
|
|
700
|
+
"kbRetrieval.layerNone": "none\uFF1Afail-open\uFF0C\u65E0\u8EAB\u4EFD\u8FC7\u6EE4\u8FD4\u56DE\u5168\u90E8\u2014\u2014\u5371\u9669\uFF0C\u4EC5\u6F14\u793A",
|
|
701
|
+
"kbRetrieval.layerPost": "post-filter\uFF1A\u5206\u6570\u5DF2\u53EF\u89C2\u5BDF\u2014\u2014\u7F3A\u9677\u5C42\uFF0C\u4EC5\u6F14\u793A",
|
|
702
|
+
"kbRetrieval.layerPre": "pre-filter\uFF1AACL \u5728\u68C0\u7D22\u6267\u884C\u4F53\u5185\u751F\u6548\u2014\u2014\u5B89\u5168\u57FA\u7EBF",
|
|
703
|
+
"kbRetrieval.leakNote": "\u5206\u6BCD\u672A\u8FC7\u6EE4\u524D\u8BA1\u6570\u5C5E\u6CC4\u9732\uFF0C\u4E0D\u663E\u793A",
|
|
704
|
+
"kbRetrieval.modeHybrid": "\u6DF7\u5408",
|
|
705
|
+
"kbRetrieval.modeKeyword": "\u5173\u952E\u8BCD",
|
|
706
|
+
"kbRetrieval.modeLabel": "\u68C0\u7D22\u6A21\u5F0F",
|
|
707
|
+
"kbRetrieval.modeVector": "\u5411\u91CF",
|
|
708
|
+
"kbRetrieval.postFilterNotice": "post-filter\uFF1A\u5206\u6570\u5DF2\u5728\u8FC7\u6EE4\u524D\u4EA7\u751F\uFF08\u7F3A\u9677\u5C42\u6F14\u793A\uFF09",
|
|
709
|
+
"kbRetrieval.queryLabel": "\u68C0\u7D22\u95EE\u9898",
|
|
710
|
+
"kbRetrieval.queryPlaceholder": "\u68C0\u7D22\u95EE\u9898\uFF0CEnter \u8FD0\u884C",
|
|
711
|
+
"kbRetrieval.rerankLabel": "\u91CD\u6392",
|
|
712
|
+
"kbRetrieval.rerankThresholdOff": "\u9608\u503C \u5173 \xB7 \u5B58\u6D3B {p0}",
|
|
713
|
+
"kbRetrieval.rerankThresholdOn": "\u9608\u503C {p0} \xB7 \u5B58\u6D3B {p1}",
|
|
714
|
+
"kbRetrieval.running": "\u8FD0\u884C\u4E2D\u2026",
|
|
715
|
+
"kbRetrieval.thresholdLabel": "\u5206\u6570\u9608\u503C",
|
|
716
|
+
"kbRetrieval.thresholdValue": "\u9608\u503C N/A",
|
|
717
|
+
"kbRetrieval.vectorHint": "\u8BED\u4E49\uFF1A\u8DE8\u8BED\u8A00/\u65E0\u7CBE\u786E\u8BCD",
|
|
718
|
+
"kbRetrieval.vectorPercent": "\u8BED\u4E49 {p0}",
|
|
719
|
+
"kbRetrieval.weightValue": "\u5411\u91CF {p0}% / \u5173\u952E\u8BCD {p1}%",
|
|
720
|
+
/* ── kbReview ── */
|
|
721
|
+
"kbReview.assignee": "\u5206\u914D\u4EBA",
|
|
722
|
+
"kbReview.doneNext": "\u5B8C\u6210\u5E76\u4E0B\u4E00\u6761",
|
|
723
|
+
"kbReview.empty": "\u6CA1\u6709\u5F85\u5BA1\u67E5\u6761\u76EE",
|
|
724
|
+
"kbReview.emptyAssignee": "\u8BE5\u5206\u914D\u4EBA\u4E0B\u6CA1\u6709\u6761\u76EE",
|
|
725
|
+
"kbReview.emptyQueue": "\u961F\u5217\u4E3A\u7A7A",
|
|
726
|
+
"kbReview.kbCloseHint": "\u5173\u95ED\u63D0\u793A",
|
|
727
|
+
"kbReview.kbSelectOption": "\u9009\u62E9\u9009\u9879",
|
|
728
|
+
"kbReview.kbSwitchItem": "\u5207\u6362\u6761\u76EE",
|
|
729
|
+
"kbReview.kbToggleHint": "\u663E\u793A/\u9690\u85CF\u672C\u63D0\u793A",
|
|
730
|
+
"kbReview.shortcuts": "? \u5FEB\u6377\u952E",
|
|
731
|
+
"kbReview.typeAnswer": "\u56DE\u7B54",
|
|
732
|
+
"kbReview.typeMessage": "\u6D88\u606F",
|
|
733
|
+
"kbReview.typeTrace": "\u8F68\u8FF9",
|
|
734
|
+
"kbReview.unassigned": "\u672A\u5206\u914D",
|
|
735
|
+
/* ── kbSandbox ── */
|
|
736
|
+
"kbSandbox.noResolver": "\u5BBF\u4E3B\u672A\u63D0\u4F9B ui:// \u89E3\u6790\u5668",
|
|
737
|
+
"kbSandbox.notReady": "kb-sandbox: \u5E94\u7528\u672A\u5C31\u7EEA",
|
|
738
|
+
"kbSandbox.resolveFailed": "ui:// \u89E3\u6790\u5931\u8D25\uFF1A{p0}",
|
|
739
|
+
"kbSandbox.timeout": "kb-sandbox: \u8C03\u7528\u8D85\u65F6\uFF08{p0}ms\uFF09",
|
|
740
|
+
"kbSandbox.title": "MCP App \u6C99\u7BB1",
|
|
741
|
+
/* ── kbSegment ── */
|
|
742
|
+
"kbSegment.avgLength": "\u5747\u957F {p0}",
|
|
743
|
+
"kbSegment.childNote": "\u5B50\u5206\u6BB5\u6309\u957F\u5EA6\u81EA\u52A8\u751F\u6210",
|
|
744
|
+
"kbSegment.cleanBlankLines": "\u5408\u5E76\u8FDE\u7EED\u7A7A\u884C",
|
|
745
|
+
"kbSegment.cleanEmails": "\u53BB\u9664\u90AE\u7BB1",
|
|
746
|
+
"kbSegment.cleanLinks": "\u53BB\u9664\u94FE\u63A5",
|
|
747
|
+
"kbSegment.empty": "\u6837\u672C\u4E3A\u7A7A\uFF0C\u6682\u65E0\u53EF\u9884\u89C8\u5206\u6BB5",
|
|
748
|
+
"kbSegment.maxLengthLabel": "\u6700\u5927\u957F\u5EA6",
|
|
749
|
+
"kbSegment.maxLengthPlaceholder": "\u5206\u6BB5\u6700\u5927\u957F\u5EA6",
|
|
750
|
+
"kbSegment.modeAuto": "\u81EA\u52A8",
|
|
751
|
+
"kbSegment.modeCustom": "\u81EA\u5B9A\u4E49",
|
|
752
|
+
"kbSegment.modeLabel": "\u5206\u6BB5\u6A21\u5F0F",
|
|
753
|
+
"kbSegment.modeNote": "\u5206\u6BB5\u6A21\u5F0F\u521B\u5EFA\u540E\u4E0D\u53EF\u66F4\u6539\uFF0C\u53C2\u6570\u53EF\u968F\u65F6\u8C03\u6574",
|
|
754
|
+
"kbSegment.modeParentChild": "\u7236\u5B50",
|
|
755
|
+
"kbSegment.overlapInvalid": "\u91CD\u53E0\u9700\u5C0F\u4E8E\u6700\u5927\u957F\u5EA6",
|
|
756
|
+
"kbSegment.overlapLabel": "\u91CD\u53E0",
|
|
757
|
+
"kbSegment.overlapPlaceholder": "\u5206\u6BB5\u91CD\u53E0",
|
|
758
|
+
"kbSegment.previewNote": "\u5171 {p0} \u6BB5\uFF0C\u4EC5\u9884\u89C8\u524D {p1} \u6BB5",
|
|
759
|
+
"kbSegment.segmentsCount": "{p0} \u6BB5",
|
|
760
|
+
"kbSegment.separatorLabel": "\u5206\u9694\u7B26",
|
|
761
|
+
"kbSegment.separatorPlaceholder": "\u5206\u6BB5\u5206\u9694\u7B26",
|
|
762
|
+
"kbSegment.toggleTip": "\u70B9\u51FB\u5C55\u5F00/\u6536\u8D77",
|
|
763
|
+
/* ── kbSources ── */
|
|
764
|
+
"kbSources.cited": "\u88AB\u5F15 \xD7{p0}",
|
|
765
|
+
"kbSources.empty": "\u4E0B\u4E00\u6761\u7B54\u6848\u5F15\u7528\u7684\u6BB5\u843D\u5C06\u51FA\u73B0\u5728\u8FD9\u91CC",
|
|
766
|
+
/* ── kbSql ── */
|
|
767
|
+
"kbSql.adminOnly": "\u4EC5\u7BA1\u7406\u5458\u53EF\u89C1",
|
|
768
|
+
"kbSql.applyFix": "\u5E94\u7528\u4FEE\u590D\u5E76\u91CD\u8DD1",
|
|
769
|
+
"kbSql.confirmRerun": "\u786E\u8BA4\u5E76\u91CD\u8DD1",
|
|
770
|
+
"kbSql.editRerun": "\u7F16\u8F91\u91CD\u8DD1",
|
|
771
|
+
"kbSql.fixReady": "\u68C0\u6D4B\u5230\u4E0A\u7248\u62A5\u9519\uFF0C\u4FEE\u590D\u5EFA\u8BAE\u5DF2\u5C31\u7EEA",
|
|
772
|
+
"kbSql.generated": "\u751F\u6210\u7684 SQL",
|
|
773
|
+
/* ── kbTrace ── */
|
|
774
|
+
"kbTrace.empty": "\u6682\u65E0\u8C03\u7528\u94FE\u6570\u636E",
|
|
775
|
+
"kbTrace.hits": "\u547D\u4E2D {p0}",
|
|
776
|
+
/* ── kbVisibility ── */
|
|
777
|
+
"kbVisibility.adminOnlyNote": "\u4EE5\u4E0A\u5BF9\u7167\u4EC5\u9650 admin \u5BA1\u8BA1",
|
|
778
|
+
"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",
|
|
779
|
+
"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",
|
|
780
|
+
"kbVisibility.focusColumn": "\u805A\u7126\u8EAB\u4EFD {p0} \u7684\u5217",
|
|
781
|
+
"kbVisibility.layerValue": "\u8FC7\u6EE4\u5C42\uFF1A{p0}",
|
|
782
|
+
"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",
|
|
783
|
+
"kbVisibility.postFilterNote": "post-filter\uFF1AtopK \u88AB\u65E0\u6743\u7ED3\u679C\u5360\u7528\u4E14\u76F8\u4F3C\u5EA6\u5206\u6570\u53EF\u88AB\u89C2\u5BDF",
|
|
784
|
+
"kbVisibility.queryLabel": "\u67E5\u8BE2\uFF1A{p0}",
|
|
785
|
+
"kbVisibility.safeCount": "\u5B89\u5168\u8BA1\u6570 {p0}",
|
|
786
|
+
"kbVisibility.sourceUnavailable": "\u539F\u6587\u4E0D\u53EF\u7528",
|
|
787
|
+
"kbVisibility.unnamedHit": "\u672A\u547D\u540D\u547D\u4E2D",
|
|
788
|
+
/* ── kbWhoCan ── */
|
|
789
|
+
"kbWhoCan.check": "\u68C0\u67E5",
|
|
790
|
+
"kbWhoCan.checkIdentity": "\u68C0\u67E5\u8EAB\u4EFD",
|
|
791
|
+
"kbWhoCan.daysUntil": "{p0} \u5929\u540E",
|
|
792
|
+
"kbWhoCan.deniedBy": "\u88AB\u7B56\u7565\u62D2\u7EDD\uFF1A{p0}",
|
|
793
|
+
"kbWhoCan.denyVeto": "\u88AB Deny \u4E00\u7968\u5426\u51B3",
|
|
794
|
+
"kbWhoCan.direct": "\u76F4\u63A5",
|
|
795
|
+
"kbWhoCan.expiresSoon": "\u6700\u8FD1\u5230\u671F {p0}",
|
|
796
|
+
"kbWhoCan.hoursUntil": "{p0} \u5C0F\u65F6\u540E",
|
|
797
|
+
"kbWhoCan.inherit": "\u7EE7\u627F",
|
|
798
|
+
"kbWhoCan.link": "\u94FE\u63A5",
|
|
799
|
+
"kbWhoCan.noDeny": "\u65E0 Deny \u751F\u6548",
|
|
800
|
+
"kbWhoCan.noIdentity": "\u672A\u63D0\u4F9B\u53EF\u68C0\u67E5\u7684\u8EAB\u4EFD",
|
|
801
|
+
"kbWhoCan.none": "\u672A\u547D\u4E2D\u4EFB\u4F55\u6388\u6743\u2014\u2014\u9ED8\u8BA4\u62D2\u7EDD",
|
|
802
|
+
"kbWhoCan.recheckTip": "\u91CD\u65B0\u68C0\u67E5\u5F53\u524D\u8EAB\u4EFD\u7684\u6709\u6548\u6743\u9650",
|
|
803
|
+
"kbWhoCan.stackRule": "\u53E0\u52A0\u89C4\u5219\uFF1A\u591A\u6765\u6E90\u5E76\u96C6 \u2192 {p0}\uFF1B{p1}",
|
|
804
|
+
/* ── mentions ── */
|
|
805
|
+
"mentions.create": "\u521B\u5EFA\u201C{p0}\u201D",
|
|
806
|
+
"mentions.customBadge": "\u81EA\u5B9A\u4E49",
|
|
807
|
+
"mentions.loading": "\u52A0\u8F7D\u4E2D\u2026",
|
|
808
|
+
/* ── notification ── */
|
|
809
|
+
"notification.groupBusy": "\u64CD\u4F5C\u7ED3\u675F\u540E\u53EF\u4EE5\u6536\u8D77\u8FD9\u7EC4\u901A\u77E5\u3002",
|
|
810
|
+
"notification.groupUnread": "{count} \u6761\u540C\u7EC4\u901A\u77E5\uFF0C{unread} \u6761\u672A\u8BFB",
|
|
811
|
+
"notification.groupCount": "{count} \u6761\u540C\u7EC4\u901A\u77E5",
|
|
812
|
+
"notification.groupExpanded": "\u6536\u8D77\u8FD9\u7EC4\u901A\u77E5",
|
|
813
|
+
"notification.ariaLabel": "\u901A\u77E5",
|
|
814
|
+
"notification.viewDetails": "\u67E5\u770B\u8BE6\u60C5",
|
|
815
|
+
/* ── pagination ── */
|
|
816
|
+
"pagination.next": "\u4E0B\u4E00\u9875",
|
|
817
|
+
"pagination.pageSize": "{p0} \u6761/\u9875",
|
|
818
|
+
"pagination.prev": "\u4E0A\u4E00\u9875",
|
|
819
|
+
/* ── select ── */
|
|
820
|
+
"select.fieldLabel": "\u9009\u62E9\u9009\u9879",
|
|
821
|
+
"select.noMatch": "\u65E0\u5339\u914D\u9879",
|
|
822
|
+
"select.remove": "\u79FB\u9664 {p0}",
|
|
823
|
+
"select.searchPlaceholder": "\u641C\u7D22\u2026",
|
|
824
|
+
/* ── cascader / tree-select ── */
|
|
825
|
+
"cascader.placeholder": "\u8BF7\u9009\u62E9",
|
|
826
|
+
"cascader.noMatch": "\u65E0\u5339\u914D",
|
|
827
|
+
"cascader.search": "\u641C\u7D22",
|
|
828
|
+
"treeSelect.placeholder": "\u8BF7\u9009\u62E9",
|
|
829
|
+
"treeSelect.noMatch": "\u65E0\u5339\u914D",
|
|
830
|
+
"treeSelect.search": "\u641C\u7D22",
|
|
831
|
+
/* ── tagInput ── */
|
|
832
|
+
"tagInput.ariaLabel": "\u6807\u7B7E\u8F93\u5165\uFF0C\u5171 {p0} \u4E2A",
|
|
833
|
+
"tagInput.remove": "\u79FB\u9664 {p0}",
|
|
834
|
+
"tagInput.field": "\u6DFB\u52A0\u6807\u7B7E",
|
|
835
|
+
"tagInput.added": "\u5DF2\u6DFB\u52A0 {p0} \u4E2A\u6807\u7B7E\u3002",
|
|
836
|
+
"tagInput.removed": "\u5DF2\u79FB\u9664 {p0}\u3002",
|
|
837
|
+
"tagInput.duplicate": "\u5DF2\u6709\u300C{p0}\u300D\uFF0C\u53EF\u4EE5\u7F16\u8F91\u540E\u91CD\u8BD5\u3002",
|
|
838
|
+
"tagInput.limit": "\u6700\u591A {p0} \u4E2A\u6807\u7B7E\uFF0C\u8BF7\u5148\u79FB\u9664\u4E00\u4E2A\u3002",
|
|
839
|
+
/* ── upload ── */
|
|
840
|
+
"upload.remove": "\u79FB\u9664 {p0}",
|
|
841
|
+
"upload.tooBig": "\u6587\u4EF6\u8D85\u8FC7 {p0}",
|
|
842
|
+
"upload.tooMany": "\u6700\u591A {p0} \u4E2A\u6587\u4EF6",
|
|
843
|
+
"upload.typeNotAllowed": "\u6587\u4EF6\u7C7B\u578B\u4E0D\u652F\u6301"
|
|
844
|
+
};
|
|
845
|
+
var current = { ...ICEN_LOCALE_ZH_CN };
|
|
846
|
+
function t(key, vars) {
|
|
847
|
+
const raw = current[key] ?? ICEN_LOCALE_ZH_CN[key];
|
|
848
|
+
if (vars == null || Array.isArray(raw)) return raw;
|
|
849
|
+
return raw.replace(/\{(\w+)\}/g, (m, name) => name in vars ? String(vars[name]) : m);
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
// src/behaviors/icons.ts
|
|
853
|
+
var ICON_PATHS = {
|
|
854
|
+
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",
|
|
855
|
+
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",
|
|
856
|
+
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",
|
|
857
|
+
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",
|
|
858
|
+
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",
|
|
859
|
+
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",
|
|
860
|
+
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",
|
|
861
|
+
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",
|
|
862
|
+
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",
|
|
863
|
+
"line-numbers": "M3 5h2M3 10h2M3 15h2M8 5h9M8 10h9M8 15h9",
|
|
864
|
+
wrap: "M3 5h14M3 10h10a3 3 0 0 1 0 6h-3M12.5 13.5 10 16l2.5 2.5",
|
|
865
|
+
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",
|
|
866
|
+
close: "M6 6l8 8M14 6l-8 8",
|
|
867
|
+
check: "M4.5 10.2l3.6 3.6 7.4-7.6",
|
|
868
|
+
"chevron-down": "M5.5 7.75 10 12.25l4.5-4.5",
|
|
869
|
+
"chevron-up": "M5.5 12.25 10 7.75l4.5 4.5",
|
|
870
|
+
"chevron-right": "M7.75 5.5 12.25 10l-4.5 4.5",
|
|
871
|
+
"chevron-left": "M12.25 5.5 7.75 10l4.5 4.5",
|
|
872
|
+
"arrow-right": "M3.5 10h13M11 4.5l5.5 5.5-5.5 5.5",
|
|
873
|
+
"arrow-left": "M16.5 10h-13M9 4.5 3.5 10 9 15.5",
|
|
874
|
+
"arrow-up": "M10 16.5v-13M4.5 9 10 3.5 15.5 9",
|
|
875
|
+
"arrow-down": "M10 3.5v13M4.5 11l5.5 5.5 5.5-5.5",
|
|
876
|
+
plus: "M10 4v12M4 10h12",
|
|
877
|
+
minus: "M4 10h12",
|
|
878
|
+
sort: "M6 15V4M3 7l3-3 3 3M14 5v11M11 13l3 3 3-3",
|
|
879
|
+
search: "M13.3 13.3 17 17M14.5 8.5a6 6 0 1 1-12 0 6 6 0 0 1 12 0",
|
|
880
|
+
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",
|
|
881
|
+
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",
|
|
882
|
+
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",
|
|
883
|
+
pixel: "M3 3h5v5H3ZM12 3h5v5h-5ZM3 12h5v5H3ZM12 12h5v5h-5Z",
|
|
884
|
+
chinese: "M3 8c3 0 5-2 7-5 2 3 4 5 7 5M4 8h12M6 8v8m8-8v8M3 16h14M8 16v-5h4v5",
|
|
885
|
+
soviet: "M3 17h14M5 17V8h4v9m0-12h6v12M7 8V5h2m2 3h2m-2 3h2m-2 3h2M10 5V3h4v2",
|
|
886
|
+
more: "M4 9.9v.2M10 9.9v.2M16 9.9v.2",
|
|
887
|
+
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",
|
|
888
|
+
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",
|
|
889
|
+
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",
|
|
890
|
+
trash: "M3.5 5.5h13M7 5.5V3h6v2.5M5 5.5l.7 11.5h8.6L15 5.5M8 9v5M12 9v5",
|
|
891
|
+
spinner: "M10 3a7 7 0 1 1-7 7",
|
|
892
|
+
"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",
|
|
893
|
+
"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",
|
|
894
|
+
"circle-info": "M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0ZM10 9v5M10 6.1v.15",
|
|
895
|
+
"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",
|
|
896
|
+
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",
|
|
897
|
+
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",
|
|
898
|
+
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",
|
|
899
|
+
settings: "M3.5 5.5h13M3.5 10h13M3.5 14.5h13M7 4v3M12.5 8.5v3M8 13v3",
|
|
900
|
+
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",
|
|
901
|
+
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",
|
|
902
|
+
"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",
|
|
903
|
+
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",
|
|
904
|
+
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",
|
|
905
|
+
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",
|
|
906
|
+
activity: "M17 10h-2.6l-2 5.8L8 4.2 6 10H3",
|
|
907
|
+
"trend-up": "M3.5 14.5l4.2-4.2 2.8 2.8 5.9-5.9M12.4 7.2h4.2v4.2",
|
|
908
|
+
"trend-down": "M3.5 5.5l4.2 4.2 2.8-2.8 5.9 5.9M12.4 12.8h4.2V8.6",
|
|
909
|
+
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",
|
|
910
|
+
bold: "M6.5 4h4.2a3 3 0 0 1 0 6H6.5M6.5 10h5a3 3 0 0 1 0 6H6.5M6.5 4v12",
|
|
911
|
+
italic: "M8.5 4.5h7M4.5 15.5h7M12.5 4.5l-5 11",
|
|
912
|
+
underline: "M6 4v5.5a4 4 0 0 0 8 0V4M4.5 16h11",
|
|
913
|
+
"align-left": "M3.5 4.5h13M3.5 10h8.5M3.5 15.5h11",
|
|
914
|
+
"align-center": "M3.5 4.5h13M5.75 10h8.5M4.5 15.5h11",
|
|
915
|
+
"align-right": "M3.5 4.5h13M8 10h8.5M5.5 15.5h11",
|
|
916
|
+
list: "M6.5 5h10M6.5 10h10M6.5 15h10M3.5 5h.01M3.5 10h.01M3.5 15h.01",
|
|
917
|
+
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",
|
|
918
|
+
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",
|
|
919
|
+
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",
|
|
920
|
+
"chart-line": "M3.5 3.5v13h13M6.5 12l2.8-2.8 2.2 2.2 4-4.4",
|
|
921
|
+
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",
|
|
922
|
+
box: "M17 6 10 3.2 3 6v8l7 2.8 7-2.8ZM3 6l7 2.8L17 6M10 9v7.8",
|
|
923
|
+
filter: "M4 4.5h12l-4.4 5.1v5l-3.2-1.6V9.6Z",
|
|
924
|
+
columns: "M3.5 4h13v12h-13ZM8.2 4v12M12.8 4v12",
|
|
925
|
+
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"
|
|
926
|
+
};
|
|
927
|
+
var custom = /* @__PURE__ */ new Map();
|
|
928
|
+
var escape = (s) => s.replace(/[&<>"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]);
|
|
929
|
+
function iconPath(name) {
|
|
930
|
+
return Object.hasOwn(ICON_PATHS, name) ? ICON_PATHS[name] : custom.get(name) ?? null;
|
|
931
|
+
}
|
|
932
|
+
function iconAttributes(o = {}) {
|
|
933
|
+
const size = Number.isFinite(o.size) && o.size > 0 ? o.size : 16;
|
|
934
|
+
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" } };
|
|
935
|
+
}
|
|
936
|
+
function iconHTML(name, o = {}) {
|
|
937
|
+
const path = iconPath(name);
|
|
938
|
+
if (!path) return "";
|
|
939
|
+
return `<svg${Object.entries(iconAttributes(o)).map(([k, v]) => ` ${k}="${escape(v)}"`).join("")}><path d="${escape(path)}"></path></svg>`;
|
|
940
|
+
}
|
|
941
|
+
function createIcon(name, o = {}) {
|
|
942
|
+
if (typeof document === "undefined") return null;
|
|
943
|
+
const path = iconPath(name);
|
|
944
|
+
if (!path) return null;
|
|
945
|
+
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
946
|
+
for (const [key, value] of Object.entries(iconAttributes(o))) svg.setAttribute(key, value);
|
|
947
|
+
const line = document.createElementNS(svg.namespaceURI, "path");
|
|
948
|
+
line.setAttribute("d", path);
|
|
949
|
+
svg.append(line);
|
|
950
|
+
return svg;
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
// src/behaviors/svg-parse.ts
|
|
954
|
+
function parseSvg(source) {
|
|
955
|
+
if (typeof document === "undefined" || typeof DOMParser === "undefined") return null;
|
|
956
|
+
const trimmed = source.trimStart();
|
|
957
|
+
if (!trimmed.startsWith("<svg")) return null;
|
|
958
|
+
const src = /^<svg(?![^>]*\bxmlns[=:])/i.test(trimmed) ? trimmed.replace(/^<svg/i, '<svg xmlns="http://www.w3.org/2000/svg"') : trimmed;
|
|
959
|
+
let parsed;
|
|
960
|
+
try {
|
|
961
|
+
parsed = new DOMParser().parseFromString(src, "image/svg+xml");
|
|
962
|
+
} catch {
|
|
963
|
+
return null;
|
|
964
|
+
}
|
|
965
|
+
const root = parsed.documentElement;
|
|
966
|
+
if (!root || root.tagName.toLowerCase() !== "svg" || parsed.querySelector("parsererror")) return null;
|
|
967
|
+
const sanitize = (el) => {
|
|
968
|
+
for (const attr of Array.from(el.attributes)) {
|
|
969
|
+
const name = attr.name.toLowerCase();
|
|
970
|
+
if (name.startsWith("on")) el.removeAttribute(attr.name);
|
|
971
|
+
if ((name === "href" || name === "xlink:href") && attr.value.trim().toLowerCase().startsWith("javascript:")) {
|
|
972
|
+
el.removeAttribute(attr.name);
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
for (const child of Array.from(el.children)) {
|
|
976
|
+
const tag = child.tagName.toLowerCase();
|
|
977
|
+
if (tag === "script" || tag === "foreignobject") {
|
|
978
|
+
child.remove();
|
|
979
|
+
continue;
|
|
980
|
+
}
|
|
981
|
+
sanitize(child);
|
|
982
|
+
}
|
|
983
|
+
};
|
|
984
|
+
sanitize(root);
|
|
985
|
+
return document.importNode(root, true);
|
|
986
|
+
}
|
|
987
|
+
|
|
1
988
|
// src/behaviors/ai-core.ts
|
|
2
989
|
var AI_STATUSES = [
|
|
3
990
|
"pending",
|
|
@@ -10,64 +997,33 @@ var AI_STATUSES = [
|
|
|
10
997
|
];
|
|
11
998
|
function aiStatusLabel(s) {
|
|
12
999
|
const labels = {
|
|
13
|
-
pending: "
|
|
14
|
-
running: "
|
|
15
|
-
streaming: "
|
|
16
|
-
approval: "
|
|
17
|
-
done: "
|
|
18
|
-
error: "
|
|
19
|
-
cancelled: "
|
|
1000
|
+
pending: t("aiCore.statusPending"),
|
|
1001
|
+
running: t("aiCore.statusRunning"),
|
|
1002
|
+
streaming: t("aiCore.statusStreaming"),
|
|
1003
|
+
approval: t("aiCore.statusApproval"),
|
|
1004
|
+
done: t("aiCore.statusDone"),
|
|
1005
|
+
error: t("aiCore.statusError"),
|
|
1006
|
+
cancelled: t("aiCore.statusCancelled")
|
|
20
1007
|
};
|
|
21
1008
|
return labels[s] ?? s;
|
|
22
1009
|
}
|
|
23
|
-
var
|
|
24
|
-
var
|
|
25
|
-
var
|
|
26
|
-
|
|
27
|
-
);
|
|
28
|
-
var
|
|
29
|
-
|
|
30
|
-
);
|
|
31
|
-
var
|
|
32
|
-
|
|
33
|
-
);
|
|
34
|
-
var
|
|
35
|
-
|
|
36
|
-
);
|
|
37
|
-
var
|
|
38
|
-
var
|
|
39
|
-
|
|
40
|
-
);
|
|
41
|
-
var ICON_SCAN_SEARCH = svg(
|
|
42
|
-
'<path d="M3 7V5a2 2 0 0 1 2-2h2"/><path d="M17 3h2a2 2 0 0 1 2 2v2"/><path d="M21 17v2a2 2 0 0 1-2 2h-2"/><path d="M7 21H5a2 2 0 0 1-2-2v-2"/><circle cx="12" cy="12" r="3"/><path d="m16 16-1.9-1.9"/>'
|
|
43
|
-
);
|
|
44
|
-
var ICON_GLOBE = svg(
|
|
45
|
-
'<circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/>'
|
|
46
|
-
);
|
|
47
|
-
var ICON_DOWNLOAD = svg(
|
|
48
|
-
'<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="m7 10 5 5 5-5"/><path d="M12 15V3"/>'
|
|
49
|
-
);
|
|
50
|
-
var ICON_BLOCKS = svg(
|
|
51
|
-
'<rect width="7" height="7" x="4" y="4" rx="1"/><rect width="7" height="7" x="13" y="4" rx="1"/><rect width="7" height="7" x="4" y="13" rx="1"/><rect width="7" height="7" x="13" y="13" rx="1"/>'
|
|
52
|
-
);
|
|
53
|
-
var ICON_ZAP = svg(
|
|
54
|
-
'<path d="M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z"/>'
|
|
55
|
-
);
|
|
56
|
-
var ICON_LIST = svg(
|
|
57
|
-
'<path d="M3 12h.01"/><path d="M3 18h.01"/><path d="M3 6h.01"/><path d="M8 12h13"/><path d="M8 18h13"/><path d="M8 6h13"/>'
|
|
58
|
-
);
|
|
59
|
-
var ICON_LIST_CHECKS = svg(
|
|
60
|
-
'<path d="m3 17 2 2 4-4"/><path d="m3 7 2 2 4-4"/><path d="M13 6h8"/><path d="M13 12h8"/><path d="M13 18h8"/>'
|
|
61
|
-
);
|
|
62
|
-
var ICON_BOT = svg(
|
|
63
|
-
'<path d="M12 8V4H8"/><rect width="16" height="12" x="4" y="8" rx="2"/><path d="M2 14h2"/><path d="M20 14h2"/><path d="M15 13v2"/><path d="M9 13v2"/>'
|
|
64
|
-
);
|
|
65
|
-
var ICON_CHART = svg(
|
|
66
|
-
'<path d="M3 3v18h18"/><path d="M7 15l4-6 3 4 5-8"/>'
|
|
67
|
-
);
|
|
68
|
-
var ICON_FILE_TEXT = svg(
|
|
69
|
-
'<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M10 9H8"/><path d="M16 13H8"/><path d="M16 17H8"/>'
|
|
70
|
-
);
|
|
1010
|
+
var ICON_TERMINAL = iconHTML("terminal");
|
|
1011
|
+
var ICON_FILE = iconHTML("file");
|
|
1012
|
+
var ICON_FILE_PEN = iconHTML("edit");
|
|
1013
|
+
var ICON_FILE_PLUS = iconHTML("plus");
|
|
1014
|
+
var ICON_TRASH = iconHTML("trash");
|
|
1015
|
+
var ICON_SEARCH = iconHTML("search");
|
|
1016
|
+
var ICON_FOLDER_SEARCH = iconHTML("folder");
|
|
1017
|
+
var ICON_SCAN_SEARCH = iconHTML("search");
|
|
1018
|
+
var ICON_GLOBE = iconHTML("globe");
|
|
1019
|
+
var ICON_DOWNLOAD = iconHTML("download");
|
|
1020
|
+
var ICON_BLOCKS = iconHTML("server");
|
|
1021
|
+
var ICON_ZAP = iconHTML("sparkle");
|
|
1022
|
+
var ICON_LIST = iconHTML("list");
|
|
1023
|
+
var ICON_LIST_CHECKS = iconHTML("list");
|
|
1024
|
+
var ICON_BOT = iconHTML("agent");
|
|
1025
|
+
var ICON_CHART = iconHTML("chart-line");
|
|
1026
|
+
var ICON_FILE_TEXT = iconHTML("document");
|
|
71
1027
|
function isObj(v) {
|
|
72
1028
|
return typeof v === "object" && v !== null;
|
|
73
1029
|
}
|
|
@@ -117,32 +1073,32 @@ var sum = (fn) => {
|
|
|
117
1073
|
return (input) => fn(input) ?? "";
|
|
118
1074
|
};
|
|
119
1075
|
var BUILTIN_KINDS = {
|
|
120
|
-
shell: { label: "
|
|
121
|
-
read: { label: "
|
|
122
|
-
edit: { label: "
|
|
123
|
-
write: { label: "
|
|
124
|
-
rm: { label: "
|
|
125
|
-
grep: { label: "
|
|
126
|
-
glob: { label: "
|
|
127
|
-
browser: { label: "
|
|
128
|
-
search: { label: "
|
|
129
|
-
fetch: { label: "
|
|
1076
|
+
shell: { label: t("aiCore.kindShell"), icon: ICON_TERMINAL, tint: "accent", summarize: sum(summarizeShell) },
|
|
1077
|
+
read: { label: t("aiCore.kindRead"), icon: ICON_FILE, tint: "info", summarize: sum(summarizeRead) },
|
|
1078
|
+
edit: { label: t("aiCore.kindEdit"), icon: ICON_FILE_PEN, tint: "warning", summarize: sum(summarizePath) },
|
|
1079
|
+
write: { label: t("aiCore.kindWrite"), icon: ICON_FILE_PLUS, tint: "warning", summarize: sum(summarizePath) },
|
|
1080
|
+
rm: { label: t("aiCore.kindDelete"), icon: ICON_TRASH, tint: "error", summarize: sum(summarizePath) },
|
|
1081
|
+
grep: { label: t("aiCore.kindGrep"), icon: ICON_SEARCH, tint: "info", summarize: sum(summarizeGrep) },
|
|
1082
|
+
glob: { label: t("aiCore.kindGlob"), icon: ICON_FOLDER_SEARCH, tint: "info", summarize: sum((i) => pickStr(i, ["pattern", "glob", "path"])) },
|
|
1083
|
+
browser: { label: t("aiCore.kindBrowser"), icon: ICON_GLOBE, tint: "accent", summarize: sum((i) => pickStr(i, ["url", "uri", "target"])) },
|
|
1084
|
+
search: { label: t("aiCore.kindSearch"), icon: ICON_SCAN_SEARCH, tint: "accent", summarize: sum((i) => pickStr(i, ["query", "q", "pattern"])) },
|
|
1085
|
+
fetch: { label: t("aiCore.kindFetch"), icon: ICON_DOWNLOAD, tint: "info", summarize: sum((i) => pickStr(i, ["url", "uri", "endpoint"])) },
|
|
130
1086
|
mcp: { label: "MCP", icon: ICON_BLOCKS, tint: "muted", summarize: sum((i) => pickStr(i, ["tool", "method", "name"])) },
|
|
131
|
-
skill: { label: "
|
|
1087
|
+
skill: { label: t("aiCore.kindSkill"), icon: ICON_ZAP, tint: "accent", summarize: sum((i) => pickStr(i, ["skill", "name", "command"])) },
|
|
132
1088
|
todo: {
|
|
133
|
-
label: "
|
|
1089
|
+
label: t("aiCore.kindTodo"),
|
|
134
1090
|
icon: ICON_LIST,
|
|
135
1091
|
tint: "info",
|
|
136
1092
|
summarize: sum((input) => {
|
|
137
1093
|
const items = input && typeof input === "object" && Array.isArray(input.items) ? input.items : Array.isArray(input) ? input : [];
|
|
138
1094
|
const done = items.filter((it) => it?.status === "done").length;
|
|
139
|
-
return items.length > 0 ?
|
|
1095
|
+
return items.length > 0 ? t("aiCore.todoProgress", { p0: done, p1: items.length }) : "";
|
|
140
1096
|
})
|
|
141
1097
|
},
|
|
142
|
-
plan: { label: "
|
|
143
|
-
subagent: { label: "
|
|
144
|
-
note: { label: "
|
|
145
|
-
chart: { label: "
|
|
1098
|
+
plan: { label: t("aiCore.kindPlan"), icon: ICON_LIST_CHECKS, tint: "info" },
|
|
1099
|
+
subagent: { label: t("aiCore.kindSubagent"), icon: ICON_BOT, tint: "accent", summarize: sum((i) => pickStr(i, ["task", "description", "prompt", "message", "subagent_type"])) },
|
|
1100
|
+
note: { label: t("aiCore.kindNote"), icon: ICON_FILE_TEXT, tint: "muted" },
|
|
1101
|
+
chart: { label: t("aiCore.kindChart"), icon: ICON_CHART, tint: "info", summarize: sum((i) => pickStr(i, ["title", "name"])) }
|
|
146
1102
|
};
|
|
147
1103
|
var kindRegistry = new Map(Object.entries(BUILTIN_KINDS));
|
|
148
1104
|
function getAiKind(name) {
|
|
@@ -169,10 +1125,10 @@ function formatDuration(ms) {
|
|
|
169
1125
|
var PART_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "file", "resource-link"]);
|
|
170
1126
|
function isAiContentPart(v) {
|
|
171
1127
|
if (!isObj(v)) return false;
|
|
172
|
-
const
|
|
173
|
-
if (typeof
|
|
174
|
-
if (
|
|
175
|
-
if (
|
|
1128
|
+
const t2 = v.type;
|
|
1129
|
+
if (typeof t2 !== "string" || !PART_TYPES.has(t2)) return false;
|
|
1130
|
+
if (t2 === "text") return typeof v.text === "string";
|
|
1131
|
+
if (t2 === "resource-link") return typeof v.uri === "string";
|
|
176
1132
|
return typeof v.url === "string" || typeof v.data === "string" && typeof v.mimeType === "string";
|
|
177
1133
|
}
|
|
178
1134
|
function aiContentUrl(part) {
|
|
@@ -276,110 +1232,91 @@ function normalizeContentParts(raw) {
|
|
|
276
1232
|
return out;
|
|
277
1233
|
}
|
|
278
1234
|
function h(tag, className, text) {
|
|
1235
|
+
if (typeof document === "undefined") throw new Error("h() \u4EC5\u6D4F\u89C8\u5668\u73AF\u5883\u53EF\u7528\uFF08SSR \u65F6\u7531\u8C03\u7528\u65B9\u5B88\u536B\uFF0C\u89C1\u6A21\u5757\u5934\u6CE8\u91CA\uFF09");
|
|
279
1236
|
const node = document.createElement(tag);
|
|
280
1237
|
if (className) node.className = className;
|
|
281
1238
|
if (text != null) node.textContent = text;
|
|
282
1239
|
return node;
|
|
283
1240
|
}
|
|
284
|
-
function svgIcon(
|
|
285
|
-
|
|
286
|
-
let parsed;
|
|
287
|
-
try {
|
|
288
|
-
parsed = new DOMParser().parseFromString(svg2, "image/svg+xml");
|
|
289
|
-
} catch {
|
|
290
|
-
return null;
|
|
291
|
-
}
|
|
292
|
-
const root = parsed.documentElement;
|
|
293
|
-
if (!root || root.tagName.toLowerCase() !== "svg" || parsed.querySelector("parsererror")) {
|
|
294
|
-
return null;
|
|
295
|
-
}
|
|
296
|
-
const sanitize = (el) => {
|
|
297
|
-
for (const attr of Array.from(el.attributes)) {
|
|
298
|
-
const name = attr.name.toLowerCase();
|
|
299
|
-
if (name.startsWith("on")) el.removeAttribute(attr.name);
|
|
300
|
-
if ((name === "href" || name === "xlink:href") && attr.value.trim().toLowerCase().startsWith("javascript:")) {
|
|
301
|
-
el.removeAttribute(attr.name);
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
for (const child of Array.from(el.children)) {
|
|
305
|
-
const tag = child.tagName.toLowerCase();
|
|
306
|
-
if (tag === "script" || tag === "foreignobject") {
|
|
307
|
-
child.remove();
|
|
308
|
-
continue;
|
|
309
|
-
}
|
|
310
|
-
sanitize(child);
|
|
311
|
-
}
|
|
312
|
-
};
|
|
313
|
-
sanitize(root);
|
|
314
|
-
return document.importNode(root, true);
|
|
1241
|
+
function svgIcon(svg) {
|
|
1242
|
+
return parseSvg(svg);
|
|
315
1243
|
}
|
|
316
1244
|
|
|
317
|
-
// src/behaviors/
|
|
318
|
-
function
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
);
|
|
1245
|
+
// src/behaviors/url-safety.ts
|
|
1246
|
+
function safeUrl(uri) {
|
|
1247
|
+
const s = uri.replace(/[\t\n\r\0-\x1f\x7f]/g, "").trim().toLowerCase();
|
|
1248
|
+
if (!s) return void 0;
|
|
1249
|
+
if (s.startsWith("javascript:") || s.startsWith("vbscript:")) return void 0;
|
|
1250
|
+
if (/^data:\s*text\/html/.test(s)) return void 0;
|
|
1251
|
+
return uri;
|
|
322
1252
|
}
|
|
323
1253
|
|
|
324
1254
|
// src/behaviors/ai-chat.ts
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
1255
|
+
var ICON_COPY = iconHTML("copy");
|
|
1256
|
+
var ICON_RETRY = iconHTML("refresh");
|
|
1257
|
+
var ROLE_AVATAR = {
|
|
1258
|
+
user: t("aiChat.roleUser"),
|
|
1259
|
+
assistant: "AI",
|
|
1260
|
+
system: t("aiChat.roleSystem"),
|
|
1261
|
+
tool: t("aiChat.roleTool")
|
|
1262
|
+
};
|
|
1263
|
+
function safeContentUrl(part) {
|
|
1264
|
+
const src = aiContentUrl(part);
|
|
1265
|
+
return src ? safeUrl(src) : void 0;
|
|
329
1266
|
}
|
|
330
1267
|
function renderAiContentPart(part) {
|
|
331
1268
|
if (part.type === "text") {
|
|
332
|
-
const span = h("span", "ai-msg-text");
|
|
1269
|
+
const span = h("span", "icen-ai-msg-text");
|
|
333
1270
|
span.textContent = part.text;
|
|
334
1271
|
if (part.state === "streaming") span.classList.add("is-streaming");
|
|
335
1272
|
return span;
|
|
336
1273
|
}
|
|
337
1274
|
if (part.type === "image") {
|
|
338
|
-
const src =
|
|
1275
|
+
const src = safeContentUrl(part);
|
|
339
1276
|
if (!src) return void 0;
|
|
340
1277
|
const img = document.createElement("img");
|
|
341
|
-
img.className = "ai-msg-media ai-msg-media--image";
|
|
1278
|
+
img.className = "icen-ai-msg-media icen-ai-msg-media--image";
|
|
342
1279
|
img.alt = part.alt ?? "";
|
|
343
1280
|
img.setAttribute("loading", "lazy");
|
|
344
1281
|
img.setAttribute("src", src);
|
|
345
1282
|
return img;
|
|
346
1283
|
}
|
|
347
1284
|
if (part.type === "audio") {
|
|
348
|
-
const src =
|
|
1285
|
+
const src = safeContentUrl(part);
|
|
349
1286
|
if (!src) return void 0;
|
|
350
1287
|
const audio = document.createElement("audio");
|
|
351
|
-
audio.className = "ai-msg-media ai-msg-media--audio";
|
|
1288
|
+
audio.className = "icen-ai-msg-media icen-ai-msg-media--audio";
|
|
352
1289
|
audio.controls = true;
|
|
353
1290
|
audio.setAttribute("src", src);
|
|
354
1291
|
return audio;
|
|
355
1292
|
}
|
|
356
1293
|
if (part.type === "video") {
|
|
357
|
-
const src =
|
|
1294
|
+
const src = safeContentUrl(part);
|
|
358
1295
|
if (!src) return void 0;
|
|
359
1296
|
const video = document.createElement("video");
|
|
360
|
-
video.className = "ai-msg-media ai-msg-media--video";
|
|
1297
|
+
video.className = "icen-ai-msg-media icen-ai-msg-media--video";
|
|
361
1298
|
video.controls = true;
|
|
362
1299
|
video.setAttribute("playsinline", "");
|
|
363
1300
|
video.setAttribute("src", src);
|
|
364
1301
|
return video;
|
|
365
1302
|
}
|
|
366
1303
|
if (part.type === "file") {
|
|
367
|
-
const chip = h("span", "ai-msg-file");
|
|
368
|
-
chip.appendChild(h("span", "ai-msg-file-name", part.filename ?? "
|
|
369
|
-
const href2 = part.url ?
|
|
1304
|
+
const chip = h("span", "icen-ai-msg-file");
|
|
1305
|
+
chip.appendChild(h("span", "ai-msg-file-name", part.filename ?? t("aiChat.file")));
|
|
1306
|
+
const href2 = part.url ? safeUrl(part.url) : void 0;
|
|
370
1307
|
if (href2 && /^(https?:|data:)/i.test(href2)) {
|
|
371
1308
|
const a2 = document.createElement("a");
|
|
372
|
-
a2.className = "ai-msg-file-link";
|
|
1309
|
+
a2.className = "icen-ai-msg-file-link";
|
|
373
1310
|
a2.href = href2;
|
|
374
1311
|
a2.download = part.filename ?? "";
|
|
375
|
-
a2.textContent = "
|
|
1312
|
+
a2.textContent = t("aiChat.download");
|
|
376
1313
|
chip.appendChild(a2);
|
|
377
1314
|
}
|
|
378
1315
|
return chip;
|
|
379
1316
|
}
|
|
380
1317
|
const a = document.createElement("a");
|
|
381
|
-
a.className = "ai-msg-link";
|
|
382
|
-
const href =
|
|
1318
|
+
a.className = "icen-ai-msg-link";
|
|
1319
|
+
const href = safeUrl(part.uri);
|
|
383
1320
|
if (href) a.href = href;
|
|
384
1321
|
a.textContent = part.name ?? part.uri;
|
|
385
1322
|
a.title = part.uri;
|
|
@@ -394,16 +1331,16 @@ function toneVar(tone = "accent") {
|
|
|
394
1331
|
if (registered) return registered;
|
|
395
1332
|
switch (tone) {
|
|
396
1333
|
case "success":
|
|
397
|
-
return "var(--token-success)";
|
|
1334
|
+
return "var(--icen-token-success)";
|
|
398
1335
|
case "warning":
|
|
399
|
-
return "var(--token-warning)";
|
|
1336
|
+
return "var(--icen-token-warning)";
|
|
400
1337
|
case "error":
|
|
401
|
-
return "var(--token-error)";
|
|
1338
|
+
return "var(--icen-token-error)";
|
|
402
1339
|
case "muted":
|
|
403
|
-
return "var(--token-text-faint)";
|
|
1340
|
+
return "var(--icen-token-text-faint)";
|
|
404
1341
|
case "accent":
|
|
405
1342
|
default:
|
|
406
|
-
return "var(--token-accent)";
|
|
1343
|
+
return "var(--icen-token-accent)";
|
|
407
1344
|
}
|
|
408
1345
|
}
|
|
409
1346
|
function fmt(opts, value) {
|
|
@@ -414,13 +1351,66 @@ function maxOf(values) {
|
|
|
414
1351
|
for (const v of values) if (v > max) max = v;
|
|
415
1352
|
return max;
|
|
416
1353
|
}
|
|
417
|
-
function
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
1354
|
+
function pointLabelsRow(labels, width, pad) {
|
|
1355
|
+
const row = document.createElement("div");
|
|
1356
|
+
row.className = "icen-chart-labels icen-chart-labels--points";
|
|
1357
|
+
const count = Math.min(labels.length, Math.max(2, Math.min(7, Math.floor(width / 64))));
|
|
1358
|
+
const step = count > 1 ? (width - 2 * pad) / (count - 1) : width;
|
|
1359
|
+
for (let tick = 0; tick < count; tick++) {
|
|
1360
|
+
const index = count <= 1 ? 0 : Math.round(tick * (labels.length - 1) / (count - 1));
|
|
1361
|
+
const x = labels.length <= 1 ? width / 2 : pad + index / (labels.length - 1) * (width - 2 * pad);
|
|
1362
|
+
const span = document.createElement("span");
|
|
1363
|
+
span.textContent = labels[index] ?? "";
|
|
1364
|
+
span.title = span.textContent;
|
|
1365
|
+
span.dir = "auto";
|
|
1366
|
+
span.dataset.icenChartIndex = String(index);
|
|
1367
|
+
span.style.left = `${x / width * 100}%`;
|
|
1368
|
+
span.style.width = `${Math.max(0, Math.min(step * 0.9, 2 * x, 2 * (width - x)))}px`;
|
|
1369
|
+
row.appendChild(span);
|
|
422
1370
|
}
|
|
423
|
-
return
|
|
1371
|
+
return row;
|
|
1372
|
+
}
|
|
1373
|
+
function clampNum(v, lo, hi) {
|
|
1374
|
+
return Math.min(hi, Math.max(lo, v));
|
|
1375
|
+
}
|
|
1376
|
+
function lttb(points, threshold, getX, getY) {
|
|
1377
|
+
const len = points.length;
|
|
1378
|
+
const n = Math.floor(threshold);
|
|
1379
|
+
if (!Number.isFinite(n) || n < 3 || n >= len || len <= 3) return points;
|
|
1380
|
+
const sampled = new Array(n);
|
|
1381
|
+
sampled[0] = points[0];
|
|
1382
|
+
sampled[n - 1] = points[len - 1];
|
|
1383
|
+
const every = (len - 2) / (n - 2);
|
|
1384
|
+
let a = 0;
|
|
1385
|
+
for (let i = 0; i < n - 2; i++) {
|
|
1386
|
+
const avgStart = Math.floor((i + 1) * every) + 1;
|
|
1387
|
+
const avgEnd = Math.min(Math.floor((i + 2) * every) + 1, len);
|
|
1388
|
+
let avgX = 0;
|
|
1389
|
+
let avgY = 0;
|
|
1390
|
+
for (let j = avgStart; j < avgEnd; j++) {
|
|
1391
|
+
avgX += getX(points[j]);
|
|
1392
|
+
avgY += getY(points[j]);
|
|
1393
|
+
}
|
|
1394
|
+
const avgLen = Math.max(1, avgEnd - avgStart);
|
|
1395
|
+
avgX /= avgLen;
|
|
1396
|
+
avgY /= avgLen;
|
|
1397
|
+
const rangeStart = Math.floor(i * every) + 1;
|
|
1398
|
+
const rangeEnd = Math.min(Math.floor((i + 1) * every) + 1, len);
|
|
1399
|
+
const ax = getX(points[a]);
|
|
1400
|
+
const ay = getY(points[a]);
|
|
1401
|
+
let maxArea = -1;
|
|
1402
|
+
let nextA = rangeStart;
|
|
1403
|
+
for (let j = rangeStart; j < rangeEnd; j++) {
|
|
1404
|
+
const area = Math.abs((ax - avgX) * (getY(points[j]) - ay) - (ax - getX(points[j])) * (avgY - ay)) * 0.5;
|
|
1405
|
+
if (area > maxArea) {
|
|
1406
|
+
maxArea = area;
|
|
1407
|
+
nextA = j;
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
sampled[i + 1] = points[nextA];
|
|
1411
|
+
a = nextA;
|
|
1412
|
+
}
|
|
1413
|
+
return sampled;
|
|
424
1414
|
}
|
|
425
1415
|
function svgEl(tag, attrs) {
|
|
426
1416
|
const el = document.createElementNS(SVG_NS, tag);
|
|
@@ -429,28 +1419,28 @@ function svgEl(tag, attrs) {
|
|
|
429
1419
|
}
|
|
430
1420
|
function renderEmpty(el, label) {
|
|
431
1421
|
const box = document.createElement("div");
|
|
432
|
-
box.className = "chart-empty";
|
|
433
|
-
box.textContent = label ?? "
|
|
1422
|
+
box.className = "icen-chart-empty";
|
|
1423
|
+
box.textContent = label ?? t("charts.noData");
|
|
434
1424
|
el.appendChild(box);
|
|
435
1425
|
}
|
|
436
1426
|
function legendItem(label, valueText, tone) {
|
|
437
1427
|
const row = document.createElement("div");
|
|
438
|
-
row.className = "chart-legend-item";
|
|
1428
|
+
row.className = "icen-chart-legend-item";
|
|
439
1429
|
const dot = document.createElement("span");
|
|
440
|
-
dot.className = "chart-legend-dot";
|
|
1430
|
+
dot.className = "icen-chart-legend-dot";
|
|
441
1431
|
if (tone) dot.style.setProperty("--chart-tone", toneVar(tone));
|
|
442
1432
|
const name = document.createElement("span");
|
|
443
|
-
name.className = "chart-legend-label";
|
|
1433
|
+
name.className = "icen-chart-legend-label";
|
|
444
1434
|
name.textContent = label;
|
|
445
1435
|
const val = document.createElement("span");
|
|
446
|
-
val.className = "chart-legend-value";
|
|
1436
|
+
val.className = "icen-chart-legend-value";
|
|
447
1437
|
val.textContent = valueText;
|
|
448
1438
|
row.append(dot, name, val);
|
|
449
1439
|
return row;
|
|
450
1440
|
}
|
|
451
1441
|
function labelsRow(labels) {
|
|
452
1442
|
const row = document.createElement("div");
|
|
453
|
-
row.className = "chart-labels";
|
|
1443
|
+
row.className = "icen-chart-labels";
|
|
454
1444
|
for (const label of labels) {
|
|
455
1445
|
const span = document.createElement("span");
|
|
456
1446
|
span.textContent = label;
|
|
@@ -465,110 +1455,123 @@ function normalizeSeriesInput(opts) {
|
|
|
465
1455
|
function toneOf(tone, seriesIndex) {
|
|
466
1456
|
if (typeof tone === "string") return toneVar(tone);
|
|
467
1457
|
if (typeof tone === "number") return paletteVar(tone);
|
|
468
|
-
return seriesIndex > 0 ? paletteVar(
|
|
1458
|
+
return seriesIndex > 0 ? paletteVar(seriesIndex % 6 + 1) : void 0;
|
|
469
1459
|
}
|
|
470
1460
|
var PALETTE_VARS = [
|
|
471
|
-
"var(--token-accent)",
|
|
472
|
-
"var(--token-accent-cold)",
|
|
473
|
-
"var(--token-success)",
|
|
474
|
-
"var(--token-warning)",
|
|
475
|
-
"var(--token-info)",
|
|
476
|
-
"color-mix(in srgb, var(--token-text) 50%, transparent)"
|
|
1461
|
+
"var(--icen-token-accent)",
|
|
1462
|
+
"var(--icen-token-accent-cold)",
|
|
1463
|
+
"var(--icen-token-success)",
|
|
1464
|
+
"var(--icen-token-warning)",
|
|
1465
|
+
"var(--icen-token-info)",
|
|
1466
|
+
"color-mix(in srgb, var(--icen-token-text) 50%, transparent)"
|
|
477
1467
|
];
|
|
478
1468
|
function paletteVar(index) {
|
|
479
1469
|
const i = ((Math.floor(index) - 1) % 6 + 6) % 6;
|
|
480
1470
|
return PALETTE_VARS[i];
|
|
481
1471
|
}
|
|
482
1472
|
function setMarkData(node, data) {
|
|
483
|
-
node.setAttribute("data-chart-mark", "1");
|
|
484
|
-
if (data.index != null) node.setAttribute("data-chart-index", String(data.index));
|
|
485
|
-
if (data.seriesIndex != null) node.setAttribute("data-chart-series", String(data.seriesIndex));
|
|
486
|
-
if (data.seriesName != null) node.setAttribute("data-chart-series-name", String(data.seriesName));
|
|
487
|
-
if (data.label != null) node.setAttribute("data-chart-label", String(data.label));
|
|
488
|
-
if (data.value != null) node.setAttribute("data-chart-value", String(data.value));
|
|
1473
|
+
node.setAttribute("data-icen-chart-mark", "1");
|
|
1474
|
+
if (data.index != null) node.setAttribute("data-icen-chart-index", String(data.index));
|
|
1475
|
+
if (data.seriesIndex != null) node.setAttribute("data-icen-chart-series", String(data.seriesIndex));
|
|
1476
|
+
if (data.seriesName != null) node.setAttribute("data-icen-chart-series-name", String(data.seriesName));
|
|
1477
|
+
if (data.label != null) node.setAttribute("data-icen-chart-label", String(data.label));
|
|
1478
|
+
if (data.value != null) node.setAttribute("data-icen-chart-value", String(data.value));
|
|
489
1479
|
}
|
|
490
1480
|
function copyMarkData(target, source) {
|
|
491
1481
|
for (const attr of Array.from(source.attributes)) {
|
|
492
|
-
if (attr.name.startsWith("data-chart-")) target.setAttribute(attr.name, attr.value);
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
var CHART_EYE_SVG = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2.06 12.35a1 1 0 0 1 0-.7 10.75 10.75 0 0 1 19.88 0 1 1 0 0 1 0 .7 10.75 10.75 0 0 1-19.88 0"/><circle cx="12" cy="12" r="3"/></svg>';
|
|
496
|
-
var CHART_EYE_OFF_SVG = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10.73 5.08A10.4 10.4 0 0 1 12 5c7 0 10 7 10 7a13.2 13.2 0 0 1-1.67 2.68"/><path d="M6.61 6.61A13.5 13.5 0 0 0 2 12s3 7 10 7a9.7 9.7 0 0 0 5.39-1.61"/><path d="M2 2l20 20"/><path d="M9.9 9.9a3 3 0 0 0 4.2 4.2"/></svg>';
|
|
497
|
-
function parseChartSvg(svg2) {
|
|
498
|
-
try {
|
|
499
|
-
const doc = new DOMParser().parseFromString(svg2, "image/svg+xml");
|
|
500
|
-
const el = doc.documentElement;
|
|
501
|
-
return el && el.tagName.toLowerCase() === "svg" && !doc.querySelector("parsererror") ? document.importNode(el, true) : null;
|
|
502
|
-
} catch {
|
|
503
|
-
return null;
|
|
1482
|
+
if (attr.name.startsWith("data-icen-chart-")) target.setAttribute(attr.name, attr.value);
|
|
504
1483
|
}
|
|
505
1484
|
}
|
|
506
|
-
function withChrome(el, opts, hasLegend, paint, state) {
|
|
507
|
-
if (el.dataset.
|
|
1485
|
+
function withChrome(el, opts, hasLegend, paint, state, extras) {
|
|
1486
|
+
if (el.dataset.icenChartBody != null) {
|
|
508
1487
|
el.textContent = "";
|
|
509
1488
|
paint(el);
|
|
510
1489
|
return;
|
|
511
1490
|
}
|
|
512
1491
|
el.textContent = "";
|
|
513
1492
|
const body = document.createElement("div");
|
|
514
|
-
body.className = "chart-body";
|
|
515
|
-
body.dataset.
|
|
516
|
-
|
|
1493
|
+
body.className = "icen-chart-body";
|
|
1494
|
+
body.dataset.icenChartBody = "";
|
|
1495
|
+
const note = extras?.note ?? null;
|
|
1496
|
+
const onZoomReset = extras?.onZoomReset ?? null;
|
|
1497
|
+
if (!opts.title && !hasLegend && note == null && !onZoomReset) {
|
|
517
1498
|
el.appendChild(body);
|
|
518
1499
|
paint(body);
|
|
519
1500
|
return;
|
|
520
1501
|
}
|
|
521
1502
|
let hidden = state && state.hidden != null ? state.hidden : opts.legend === false;
|
|
522
1503
|
if (state) state.hidden = hidden;
|
|
523
|
-
el.setAttribute("data-legend-hidden", String(hidden));
|
|
1504
|
+
el.setAttribute("data-icen-legend-hidden", String(hidden));
|
|
524
1505
|
const head = document.createElement("div");
|
|
525
|
-
head.className = "chart-head";
|
|
1506
|
+
head.className = "icen-chart-head";
|
|
526
1507
|
const title = document.createElement("div");
|
|
527
|
-
title.className = "chart-title";
|
|
1508
|
+
title.className = "icen-chart-title";
|
|
528
1509
|
title.textContent = opts.title ?? "";
|
|
529
1510
|
if (!opts.title) title.setAttribute("aria-hidden", "true");
|
|
1511
|
+
if (note != null) {
|
|
1512
|
+
const noteEl = document.createElement("span");
|
|
1513
|
+
noteEl.className = "icen-chart-note";
|
|
1514
|
+
noteEl.textContent = note;
|
|
1515
|
+
head.appendChild(noteEl);
|
|
1516
|
+
}
|
|
1517
|
+
if (onZoomReset) {
|
|
1518
|
+
const chip = document.createElement("button");
|
|
1519
|
+
chip.type = "button";
|
|
1520
|
+
chip.className = "icen-chart-zoom-reset";
|
|
1521
|
+
chip.textContent = t("charts.resetZoom");
|
|
1522
|
+
chip.addEventListener("click", onZoomReset);
|
|
1523
|
+
head.appendChild(chip);
|
|
1524
|
+
}
|
|
530
1525
|
const eye = document.createElement("button");
|
|
531
1526
|
eye.type = "button";
|
|
532
|
-
eye.className = "chart-legend-eye";
|
|
533
|
-
eye.dataset.
|
|
1527
|
+
eye.className = "icen-chart-legend-eye";
|
|
1528
|
+
eye.dataset.icenChartLegendEye = "";
|
|
534
1529
|
const syncEye = () => {
|
|
535
|
-
const nowHidden = el.getAttribute("data-legend-hidden") === "true";
|
|
1530
|
+
const nowHidden = el.getAttribute("data-icen-legend-hidden") === "true";
|
|
536
1531
|
eye.setAttribute("aria-pressed", String(!nowHidden));
|
|
537
|
-
eye.setAttribute("aria-label", nowHidden ? "
|
|
538
|
-
eye.setAttribute("title", nowHidden ? "
|
|
539
|
-
const icon =
|
|
1532
|
+
eye.setAttribute("aria-label", nowHidden ? t("charts.showLegend") : t("charts.hideLegend"));
|
|
1533
|
+
eye.setAttribute("title", nowHidden ? t("charts.showLegend") : t("charts.hideLegend"));
|
|
1534
|
+
const icon = createIcon(nowHidden ? "eye-off" : "eye");
|
|
540
1535
|
if (icon) eye.replaceChildren(icon);
|
|
541
1536
|
};
|
|
542
1537
|
eye.addEventListener("click", () => {
|
|
543
|
-
const nowHidden = el.getAttribute("data-legend-hidden") === "true";
|
|
1538
|
+
const nowHidden = el.getAttribute("data-icen-legend-hidden") === "true";
|
|
544
1539
|
hidden = !nowHidden;
|
|
545
1540
|
if (state) state.hidden = hidden;
|
|
546
|
-
el.setAttribute("data-legend-hidden", String(hidden));
|
|
1541
|
+
el.setAttribute("data-icen-legend-hidden", String(hidden));
|
|
547
1542
|
syncEye();
|
|
548
1543
|
emitIcen(el, "icen:chart-legend-visibility", { visible: hidden ? false : true });
|
|
549
1544
|
});
|
|
550
1545
|
syncEye();
|
|
551
|
-
head.append(title, eye);
|
|
1546
|
+
if (hasLegend) head.append(title, eye);
|
|
1547
|
+
else head.append(title);
|
|
552
1548
|
el.append(head, body);
|
|
553
1549
|
paint(body);
|
|
554
1550
|
}
|
|
1551
|
+
var hiddenLegendKeys = /* @__PURE__ */ new WeakMap();
|
|
555
1552
|
function toggleLegend(items, scope) {
|
|
556
1553
|
const legend = document.createElement("div");
|
|
557
|
-
legend.className = "chart-legend chart-legend--toggle";
|
|
1554
|
+
legend.className = "icen-chart-legend icen-chart-legend--toggle";
|
|
1555
|
+
const owner = scope instanceof Element ? scope.closest("[data-icen-chart-body]")?.parentElement ?? scope : null;
|
|
1556
|
+
const hidden = owner ? hiddenLegendKeys.get(owner) ?? /* @__PURE__ */ new Set() : /* @__PURE__ */ new Set();
|
|
1557
|
+
if (owner) hiddenLegendKeys.set(owner, hidden);
|
|
558
1558
|
for (const item of items) {
|
|
559
1559
|
const row = legendItem(item.label, "", item.tone);
|
|
560
|
-
row.classList.add("chart-legend-toggle-item");
|
|
1560
|
+
row.classList.add("icen-chart-legend-toggle-item");
|
|
561
1561
|
row.setAttribute("role", "button");
|
|
562
1562
|
row.tabIndex = 0;
|
|
563
|
-
row.
|
|
564
|
-
row.
|
|
565
|
-
|
|
566
|
-
const
|
|
1563
|
+
row.classList.toggle("is-off", hidden.has(item.key));
|
|
1564
|
+
row.setAttribute("aria-pressed", String(!hidden.has(item.key)));
|
|
1565
|
+
row.dataset.icenChartKey = item.key;
|
|
1566
|
+
const dot = row.querySelector(".icen-chart-legend-dot");
|
|
1567
|
+
const toneColor = toneOf(item.tone, item.si);
|
|
567
1568
|
if (dot && toneColor) dot.style.setProperty("--chart-tone", toneColor);
|
|
568
1569
|
const toggle = () => {
|
|
569
1570
|
const off = row.classList.toggle("is-off");
|
|
1571
|
+
if (off) hidden.add(item.key);
|
|
1572
|
+
else hidden.delete(item.key);
|
|
570
1573
|
row.setAttribute("aria-pressed", String(!off));
|
|
571
|
-
scope.querySelectorAll(`[data-chart-key="${CSS.escape(item.key)}"]`).forEach((m) => {
|
|
1574
|
+
scope.querySelectorAll(`[data-icen-chart-key="${CSS.escape(item.key)}"]`).forEach((m) => {
|
|
572
1575
|
m.classList.toggle("is-off", off);
|
|
573
1576
|
});
|
|
574
1577
|
emitIcen(legend, "icen:chart-legend-toggle", { key: item.key, seriesIndex: item.si, hidden: off });
|
|
@@ -583,8 +1586,9 @@ function toggleLegend(items, scope) {
|
|
|
583
1586
|
legend.appendChild(row);
|
|
584
1587
|
}
|
|
585
1588
|
for (const item of items) {
|
|
586
|
-
scope.querySelectorAll(`[data-chart-series="${item.si}"]`).forEach((m) => {
|
|
587
|
-
if (!m.hasAttribute("data-chart-key")) m.setAttribute("data-chart-key", item.key);
|
|
1589
|
+
scope.querySelectorAll(`[data-icen-chart-series="${item.si}"]`).forEach((m) => {
|
|
1590
|
+
if (!m.hasAttribute("data-icen-chart-key")) m.setAttribute("data-icen-chart-key", item.key);
|
|
1591
|
+
m.classList.toggle("is-off", hidden.has(item.key));
|
|
588
1592
|
});
|
|
589
1593
|
}
|
|
590
1594
|
return legend;
|
|
@@ -611,19 +1615,19 @@ function renderVBar(el, opts) {
|
|
|
611
1615
|
for (const s of seriesList) max = Math.max(max, maxOf(s.values.slice(0, n)));
|
|
612
1616
|
}
|
|
613
1617
|
const wrap = document.createElement("div");
|
|
614
|
-
wrap.className = "chart-vbar";
|
|
1618
|
+
wrap.className = "icen-chart-vbar";
|
|
615
1619
|
if (opts.tone) wrap.style.setProperty("--chart-tone", toneVar(opts.tone));
|
|
616
1620
|
for (let i = 0; i < n; i++) {
|
|
617
1621
|
const track = document.createElement("div");
|
|
618
|
-
track.className = "chart-vbar-track";
|
|
1622
|
+
track.className = "icen-chart-vbar-track";
|
|
619
1623
|
if (seriesList.length > 1) {
|
|
620
|
-
track.classList.add("chart-vbar-track--multi");
|
|
621
|
-
if (opts.stacked) track.classList.add("chart-vbar-track--stacked");
|
|
1624
|
+
track.classList.add("icen-chart-vbar-track--multi");
|
|
1625
|
+
if (opts.stacked) track.classList.add("icen-chart-vbar-track--stacked");
|
|
622
1626
|
}
|
|
623
1627
|
seriesList.forEach((s, si) => {
|
|
624
1628
|
const value = s.values[i] ?? 0;
|
|
625
1629
|
const bar = document.createElement("div");
|
|
626
|
-
bar.className = "chart-vbar-bar";
|
|
1630
|
+
bar.className = "icen-chart-vbar-bar";
|
|
627
1631
|
const height = value > 0 ? Math.max(6, value / max * 100) : 0;
|
|
628
1632
|
bar.style.height = `${height}%`;
|
|
629
1633
|
const toneColor = toneOf(s.tone, si);
|
|
@@ -641,7 +1645,7 @@ function renderVBar(el, opts) {
|
|
|
641
1645
|
wrap.appendChild(track);
|
|
642
1646
|
}
|
|
643
1647
|
body.append(wrap, labelsRow(labelsUsed));
|
|
644
|
-
if (seriesList.length > 1) body.appendChild(toggleLegend(seriesList.map((s, si) => ({ key: s.name
|
|
1648
|
+
if (seriesList.length > 1) body.appendChild(toggleLegend(seriesList.map((s, si) => ({ key: `${si}:${s.name}`, label: s.name, tone: s.tone ?? (si === 0 ? opts.tone : void 0), si })), wrap));
|
|
645
1649
|
});
|
|
646
1650
|
attachChartInteraction(el, "vbar");
|
|
647
1651
|
return el;
|
|
@@ -658,22 +1662,22 @@ function renderHBar(el, opts) {
|
|
|
658
1662
|
const values = opts.values.slice(0, n);
|
|
659
1663
|
const max = maxOf(values);
|
|
660
1664
|
const wrap = document.createElement("div");
|
|
661
|
-
wrap.className = "chart-hbar";
|
|
1665
|
+
wrap.className = "icen-chart-hbar";
|
|
662
1666
|
if (opts.tone) wrap.style.setProperty("--chart-tone", toneVar(opts.tone));
|
|
663
1667
|
values.forEach((value, i) => {
|
|
664
1668
|
const row = document.createElement("div");
|
|
665
|
-
row.className = "chart-hbar-row";
|
|
1669
|
+
row.className = "icen-chart-hbar-row";
|
|
666
1670
|
const label = document.createElement("span");
|
|
667
|
-
label.className = "chart-hbar-label";
|
|
1671
|
+
label.className = "icen-chart-hbar-label";
|
|
668
1672
|
label.textContent = labels[i] ?? "";
|
|
669
1673
|
const track = document.createElement("div");
|
|
670
|
-
track.className = "chart-hbar-track";
|
|
1674
|
+
track.className = "icen-chart-hbar-track";
|
|
671
1675
|
const bar = document.createElement("div");
|
|
672
|
-
bar.className = "chart-hbar-bar";
|
|
1676
|
+
bar.className = "icen-chart-hbar-bar";
|
|
673
1677
|
bar.style.width = value > 0 ? `${Math.max(2, value / max * 100)}%` : "0%";
|
|
674
1678
|
setMarkData(bar, { index: i, label: labels[i] ?? "", value });
|
|
675
1679
|
const val = document.createElement("span");
|
|
676
|
-
val.className = "chart-hbar-value";
|
|
1680
|
+
val.className = "icen-chart-hbar-value";
|
|
677
1681
|
val.textContent = fmt(opts, value);
|
|
678
1682
|
track.appendChild(bar);
|
|
679
1683
|
row.append(label, track, val);
|
|
@@ -693,10 +1697,10 @@ function renderStack(el, opts) {
|
|
|
693
1697
|
return;
|
|
694
1698
|
}
|
|
695
1699
|
const bar = document.createElement("div");
|
|
696
|
-
bar.className = "chart-stack";
|
|
1700
|
+
bar.className = "icen-chart-stack";
|
|
697
1701
|
for (const [segIndex, seg] of opts.segments.entries()) {
|
|
698
1702
|
const s = document.createElement("div");
|
|
699
|
-
s.className = "chart-stack-seg";
|
|
1703
|
+
s.className = "icen-chart-stack-seg";
|
|
700
1704
|
s.style.width = `${seg.value / total * 100}%`;
|
|
701
1705
|
if (seg.tone) s.style.setProperty("--chart-tone", toneVar(seg.tone));
|
|
702
1706
|
s.setAttribute("title", `${seg.label}: ${fmt(opts, seg.value)}`);
|
|
@@ -704,7 +1708,7 @@ function renderStack(el, opts) {
|
|
|
704
1708
|
bar.appendChild(s);
|
|
705
1709
|
}
|
|
706
1710
|
const legend = document.createElement("div");
|
|
707
|
-
legend.className = "chart-legend";
|
|
1711
|
+
legend.className = "icen-chart-legend";
|
|
708
1712
|
for (const seg of opts.segments) {
|
|
709
1713
|
legend.appendChild(legendItem(seg.label, fmt(opts, seg.value), seg.tone));
|
|
710
1714
|
}
|
|
@@ -724,20 +1728,22 @@ function renderDonut(el, opts) {
|
|
|
724
1728
|
const radius = 42;
|
|
725
1729
|
const circumference = 2 * Math.PI * radius;
|
|
726
1730
|
const wrap = document.createElement("div");
|
|
727
|
-
wrap.className = "chart-donut";
|
|
728
|
-
const
|
|
729
|
-
|
|
730
|
-
|
|
1731
|
+
wrap.className = "icen-chart-donut";
|
|
1732
|
+
const svg = svgEl("svg", { viewBox: "0 0 120 120", role: "img", "aria-label": chartAriaLabel(opts.title, t("charts.type.donut")) });
|
|
1733
|
+
svg.style.transform = "rotate(-90deg)";
|
|
1734
|
+
svg.appendChild(svgEl("circle", {
|
|
731
1735
|
cx: "60",
|
|
732
1736
|
cy: "60",
|
|
733
1737
|
r: String(radius),
|
|
734
1738
|
fill: "none",
|
|
735
|
-
stroke: "var(--token-line-soft)",
|
|
1739
|
+
stroke: "var(--icen-token-line-soft)",
|
|
736
1740
|
"stroke-width": "14"
|
|
737
1741
|
}));
|
|
738
1742
|
let offset = 0;
|
|
1743
|
+
const gap = opts.segments.length > 1 ? 2.5 : 0;
|
|
739
1744
|
opts.segments.forEach((seg, segIndex) => {
|
|
740
|
-
const
|
|
1745
|
+
const arcLength = Math.max(0, seg.value / total * circumference);
|
|
1746
|
+
const dash = arcLength - Math.min(gap, arcLength * 0.1);
|
|
741
1747
|
const arc = svgEl("circle", {
|
|
742
1748
|
cx: "60",
|
|
743
1749
|
cy: "60",
|
|
@@ -750,15 +1756,15 @@ function renderDonut(el, opts) {
|
|
|
750
1756
|
"stroke-linecap": "butt"
|
|
751
1757
|
});
|
|
752
1758
|
setMarkData(arc, { index: segIndex, label: seg.label, value: seg.value });
|
|
753
|
-
|
|
754
|
-
offset +=
|
|
1759
|
+
svg.appendChild(arc);
|
|
1760
|
+
offset += arcLength;
|
|
755
1761
|
});
|
|
756
1762
|
const legend = document.createElement("div");
|
|
757
|
-
legend.className = "chart-legend";
|
|
1763
|
+
legend.className = "icen-chart-legend";
|
|
758
1764
|
for (const seg of opts.segments) {
|
|
759
1765
|
legend.appendChild(legendItem(seg.label, `${Math.round(seg.value / total * 100)}%`, seg.tone));
|
|
760
1766
|
}
|
|
761
|
-
wrap.append(
|
|
1767
|
+
wrap.append(svg, legend);
|
|
762
1768
|
body.appendChild(wrap);
|
|
763
1769
|
});
|
|
764
1770
|
attachChartInteraction(el, "donut");
|
|
@@ -776,23 +1782,24 @@ function renderLine(el, opts) {
|
|
|
776
1782
|
return;
|
|
777
1783
|
}
|
|
778
1784
|
const labelsUsed = labels.slice(0, n);
|
|
779
|
-
const width =
|
|
1785
|
+
const width = fluidWidth(body);
|
|
780
1786
|
const height = 150;
|
|
781
1787
|
const pad = 14;
|
|
782
1788
|
let max = 1;
|
|
783
1789
|
for (const s of seriesList) max = Math.max(max, maxOf(s.values.slice(0, n)));
|
|
784
1790
|
const wrap = document.createElement("div");
|
|
785
|
-
wrap.className = "chart-line";
|
|
786
|
-
const
|
|
1791
|
+
wrap.className = "icen-chart-line";
|
|
1792
|
+
const svg = svgEl("svg", { viewBox: `0 0 ${width} ${height}`, role: "img", "aria-label": chartAriaLabel(opts.title, t("charts.type.line")) });
|
|
787
1793
|
const defs = svgEl("defs", {});
|
|
788
1794
|
for (let i = 0; i < 4; i++) {
|
|
789
|
-
const y = pad + i * (height - pad * 2) / 3;
|
|
790
|
-
|
|
1795
|
+
const y = Math.round(pad + i * (height - pad * 2) / 3) + 0.5;
|
|
1796
|
+
svg.appendChild(svgEl("line", {
|
|
1797
|
+
class: i === 3 ? "icen-chart-grid icen-chart-baseline" : "icen-chart-grid",
|
|
791
1798
|
x1: String(pad),
|
|
792
1799
|
x2: String(width - pad),
|
|
793
1800
|
y1: String(y),
|
|
794
1801
|
y2: String(y),
|
|
795
|
-
stroke: "var(--token-line-soft)",
|
|
1802
|
+
stroke: "var(--icen-token-line-soft)",
|
|
796
1803
|
"stroke-width": "1"
|
|
797
1804
|
}));
|
|
798
1805
|
}
|
|
@@ -822,7 +1829,7 @@ function renderLine(el, opts) {
|
|
|
822
1829
|
if (seriesList.length > 1) {
|
|
823
1830
|
setMarkData(areaPath, { seriesIndex: si, seriesName: s.name, label: s.name, value: values.reduce((a, b) => a + b, 0) });
|
|
824
1831
|
}
|
|
825
|
-
|
|
1832
|
+
svg.appendChild(areaPath);
|
|
826
1833
|
}
|
|
827
1834
|
const linePath = svgEl("path", {
|
|
828
1835
|
d: line,
|
|
@@ -833,16 +1840,16 @@ function renderLine(el, opts) {
|
|
|
833
1840
|
"stroke-linejoin": "round"
|
|
834
1841
|
});
|
|
835
1842
|
const lineTitle = svgEl("title", {});
|
|
836
|
-
lineTitle.textContent = s.name || "
|
|
1843
|
+
lineTitle.textContent = s.name || t("charts.value");
|
|
837
1844
|
linePath.appendChild(lineTitle);
|
|
838
1845
|
setMarkData(linePath, { seriesIndex: si, seriesName: s.name, label: s.name, value: values[values.length - 1] ?? 0 });
|
|
839
|
-
|
|
1846
|
+
svg.appendChild(linePath);
|
|
840
1847
|
for (const p of points) {
|
|
841
1848
|
const dot = svgEl("circle", {
|
|
842
1849
|
cx: p.x.toFixed(1),
|
|
843
1850
|
cy: p.y.toFixed(1),
|
|
844
1851
|
r: "3",
|
|
845
|
-
fill: "var(--token-card)",
|
|
1852
|
+
fill: "var(--icen-token-card)",
|
|
846
1853
|
stroke: tone,
|
|
847
1854
|
"stroke-width": "2"
|
|
848
1855
|
});
|
|
@@ -856,23 +1863,24 @@ function renderLine(el, opts) {
|
|
|
856
1863
|
label: p.label,
|
|
857
1864
|
value: p.value
|
|
858
1865
|
});
|
|
859
|
-
|
|
1866
|
+
svg.appendChild(dot);
|
|
860
1867
|
const hit = svgEl("circle", {
|
|
861
1868
|
cx: p.x.toFixed(1),
|
|
862
1869
|
cy: p.y.toFixed(1),
|
|
863
1870
|
r: "8",
|
|
864
1871
|
fill: "transparent",
|
|
865
|
-
"data-chart-hit": "1"
|
|
1872
|
+
"data-icen-chart-hit": "1"
|
|
866
1873
|
});
|
|
867
1874
|
copyMarkData(hit, dot);
|
|
868
|
-
|
|
1875
|
+
svg.appendChild(hit);
|
|
869
1876
|
}
|
|
870
1877
|
});
|
|
871
|
-
if (defs.firstChild)
|
|
872
|
-
wrap.append(
|
|
1878
|
+
if (defs.firstChild) svg.insertBefore(defs, svg.firstChild);
|
|
1879
|
+
wrap.append(svg, pointLabelsRow(labelsUsed, width, pad));
|
|
873
1880
|
body.appendChild(wrap);
|
|
874
|
-
if (seriesList.length > 1) body.appendChild(toggleLegend(seriesList.map((s, si) => ({ key: s.name
|
|
1881
|
+
if (seriesList.length > 1) body.appendChild(toggleLegend(seriesList.map((s, si) => ({ key: `${si}:${s.name}`, label: s.name, tone: s.tone ?? (si === 0 ? opts.tone : void 0), si })), wrap));
|
|
875
1882
|
});
|
|
1883
|
+
if (el.dataset.icenChartBody == null) observeFluidWidth(el, () => renderLine(el, opts));
|
|
876
1884
|
attachChartInteraction(el, "line");
|
|
877
1885
|
return el;
|
|
878
1886
|
}
|
|
@@ -904,30 +1912,30 @@ function renderRadar(el, opts) {
|
|
|
904
1912
|
y: cy + r * Math.sin(angleOf(i))
|
|
905
1913
|
});
|
|
906
1914
|
const wrap = document.createElement("div");
|
|
907
|
-
wrap.className = "chart-radar";
|
|
908
|
-
const
|
|
1915
|
+
wrap.className = "icen-chart-radar";
|
|
1916
|
+
const svg = svgEl("svg", { viewBox: `0 0 ${size} ${size}`, role: "img", "aria-label": chartAriaLabel(opts.title, t("charts.type.radar")) });
|
|
909
1917
|
for (let lv = 1; lv <= levels; lv++) {
|
|
910
1918
|
const r = radius * lv / levels;
|
|
911
1919
|
const pts = Array.from({ length: n }, (_, i) => {
|
|
912
1920
|
const p = pointAt(i, r);
|
|
913
1921
|
return `${p.x.toFixed(1)},${p.y.toFixed(1)}`;
|
|
914
1922
|
}).join(" ");
|
|
915
|
-
|
|
1923
|
+
svg.appendChild(svgEl("polygon", {
|
|
916
1924
|
points: pts,
|
|
917
1925
|
fill: "none",
|
|
918
|
-
stroke: "var(--token-line-soft)",
|
|
1926
|
+
stroke: "var(--icen-token-line-soft)",
|
|
919
1927
|
"stroke-width": "1",
|
|
920
1928
|
"stroke-dasharray": lv === levels ? "0" : "3 2"
|
|
921
1929
|
}));
|
|
922
1930
|
}
|
|
923
1931
|
for (let i = 0; i < n; i++) {
|
|
924
1932
|
const edge = pointAt(i, radius);
|
|
925
|
-
|
|
1933
|
+
svg.appendChild(svgEl("line", {
|
|
926
1934
|
x1: String(cx),
|
|
927
1935
|
y1: String(cy),
|
|
928
1936
|
x2: edge.x.toFixed(1),
|
|
929
1937
|
y2: edge.y.toFixed(1),
|
|
930
|
-
stroke: "var(--token-line-soft)",
|
|
1938
|
+
stroke: "var(--icen-token-line-soft)",
|
|
931
1939
|
"stroke-width": "1"
|
|
932
1940
|
}));
|
|
933
1941
|
const labelP = pointAt(i, radius + 14);
|
|
@@ -937,14 +1945,14 @@ function renderRadar(el, opts) {
|
|
|
937
1945
|
"text-anchor": "middle",
|
|
938
1946
|
"dominant-baseline": "middle",
|
|
939
1947
|
"font-size": "9",
|
|
940
|
-
fill: "var(--token-text-muted)"
|
|
1948
|
+
fill: "var(--icen-token-text-muted)"
|
|
941
1949
|
});
|
|
942
1950
|
txt.textContent = axes[i] ?? "";
|
|
943
|
-
|
|
1951
|
+
svg.appendChild(txt);
|
|
944
1952
|
}
|
|
945
1953
|
const legendItems = [];
|
|
946
1954
|
opts.series.forEach((s, si) => {
|
|
947
|
-
const tone = toneVar(s.tone);
|
|
1955
|
+
const tone = toneOf(s.tone, si) ?? toneVar(s.tone);
|
|
948
1956
|
const pts = Array.from({ length: n }, (_, i) => {
|
|
949
1957
|
const v = Math.max(0, Math.min(maxVal, s.values[i] ?? 0));
|
|
950
1958
|
const p = pointAt(i, v / maxVal * radius);
|
|
@@ -962,7 +1970,7 @@ function renderRadar(el, opts) {
|
|
|
962
1970
|
title.textContent = `${s.name}: ${s.values.map((v) => fmt(opts, v)).join(" / ")}`;
|
|
963
1971
|
polyFill.appendChild(title);
|
|
964
1972
|
setMarkData(polyFill, { seriesIndex: si, seriesName: s.name || void 0, label: s.name, value: s.values.reduce((a, b) => a + (b || 0), 0) });
|
|
965
|
-
|
|
1973
|
+
svg.appendChild(polyFill);
|
|
966
1974
|
for (let i = 0; i < n; i++) {
|
|
967
1975
|
const v = Math.max(0, Math.min(maxVal, s.values[i] ?? 0));
|
|
968
1976
|
const p = pointAt(i, v / maxVal * radius);
|
|
@@ -970,18 +1978,19 @@ function renderRadar(el, opts) {
|
|
|
970
1978
|
cx: p.x.toFixed(1),
|
|
971
1979
|
cy: p.y.toFixed(1),
|
|
972
1980
|
r: "2.5",
|
|
973
|
-
fill: "var(--token-card)",
|
|
1981
|
+
fill: "var(--icen-token-card)",
|
|
974
1982
|
stroke: tone,
|
|
975
1983
|
"stroke-width": "1.5"
|
|
976
1984
|
});
|
|
977
1985
|
setMarkData(dot, { index: i, seriesIndex: si, seriesName: s.name || void 0, label: axes[i] ?? "", value: s.values[i] ?? 0 });
|
|
978
|
-
|
|
1986
|
+
svg.appendChild(dot);
|
|
979
1987
|
}
|
|
980
|
-
legendItems.push({ key: s.name ||
|
|
1988
|
+
legendItems.push({ key: `${si}:${s.name || t("charts.seriesName", { p0: si + 1 })}`, label: s.name || t("charts.seriesName", { p0: si + 1 }), tone: s.tone, si });
|
|
981
1989
|
});
|
|
982
|
-
|
|
983
|
-
wrap.append(svg2, ...legend ? [legend] : []);
|
|
1990
|
+
wrap.appendChild(svg);
|
|
984
1991
|
body.appendChild(wrap);
|
|
1992
|
+
const legend = opts.series.length > 1 ? toggleLegend(legendItems, wrap) : null;
|
|
1993
|
+
if (legend) wrap.appendChild(legend);
|
|
985
1994
|
});
|
|
986
1995
|
attachChartInteraction(el, "radar");
|
|
987
1996
|
return el;
|
|
@@ -998,6 +2007,11 @@ function niceCeil(v) {
|
|
|
998
2007
|
else nice = 10;
|
|
999
2008
|
return nice * base;
|
|
1000
2009
|
}
|
|
2010
|
+
function tickPrecision(min, max, steps) {
|
|
2011
|
+
const span = Math.abs(max - min);
|
|
2012
|
+
if (!Number.isFinite(span) || span <= 0) return 0;
|
|
2013
|
+
return Math.max(0, Math.ceil(-Math.log10(span / steps)));
|
|
2014
|
+
}
|
|
1001
2015
|
function isoDate(d) {
|
|
1002
2016
|
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
1003
2017
|
const day = String(d.getDate()).padStart(2, "0");
|
|
@@ -1014,23 +2028,23 @@ function padFirstWeek(grid, firstDate, weekStart) {
|
|
|
1014
2028
|
const pad = (first.getDay() + 7 - weekStart) % 7;
|
|
1015
2029
|
for (let i = 0; i < pad; i++) {
|
|
1016
2030
|
const blank = document.createElement("span");
|
|
1017
|
-
blank.className = "chart-heatmap-cell is-blank";
|
|
2031
|
+
blank.className = "icen-chart-heatmap-cell is-blank";
|
|
1018
2032
|
grid.appendChild(blank);
|
|
1019
2033
|
}
|
|
1020
2034
|
return pad;
|
|
1021
2035
|
}
|
|
1022
2036
|
function heatmapLegend(labels) {
|
|
1023
2037
|
const legend = document.createElement("div");
|
|
1024
|
-
legend.className = "chart-heatmap-legend";
|
|
2038
|
+
legend.className = "icen-chart-heatmap-legend";
|
|
1025
2039
|
const less = document.createElement("span");
|
|
1026
|
-
less.textContent = labels?.less ?? "
|
|
2040
|
+
less.textContent = labels?.less ?? t("charts.few");
|
|
1027
2041
|
const more = document.createElement("span");
|
|
1028
|
-
more.textContent = labels?.more ?? "
|
|
2042
|
+
more.textContent = labels?.more ?? t("charts.many");
|
|
1029
2043
|
legend.appendChild(less);
|
|
1030
2044
|
for (let lv = 0; lv <= 4; lv++) {
|
|
1031
2045
|
const cell = document.createElement("span");
|
|
1032
|
-
cell.className = "chart-heatmap-cell";
|
|
1033
|
-
cell.dataset.
|
|
2046
|
+
cell.className = "icen-chart-heatmap-cell";
|
|
2047
|
+
cell.dataset.icenLevel = String(lv);
|
|
1034
2048
|
legend.appendChild(cell);
|
|
1035
2049
|
}
|
|
1036
2050
|
legend.appendChild(more);
|
|
@@ -1057,16 +2071,17 @@ function renderHeatmap(el, opts) {
|
|
|
1057
2071
|
if (entries.length > weeks * 7) entries = entries.slice(entries.length - weeks * 7);
|
|
1058
2072
|
const max = maxOf(entries.map((e) => e.value));
|
|
1059
2073
|
const wrap = document.createElement("div");
|
|
1060
|
-
wrap.className = "chart-heatmap";
|
|
2074
|
+
wrap.className = "icen-chart-heatmap";
|
|
1061
2075
|
if (opts.tone) wrap.style.setProperty("--chart-tone", toneVar(opts.tone));
|
|
1062
2076
|
const grid = document.createElement("div");
|
|
1063
|
-
grid.className = "chart-heatmap-grid";
|
|
2077
|
+
grid.className = "icen-chart-heatmap-grid";
|
|
1064
2078
|
grid.setAttribute("role", "img");
|
|
2079
|
+
grid.setAttribute("aria-label", chartAriaLabel(opts.title, t("charts.type.heatmap")));
|
|
1065
2080
|
padFirstWeek(grid, entries[0].date, opts.weekStart === 0 ? 0 : 1);
|
|
1066
2081
|
for (const [i, entry] of entries.entries()) {
|
|
1067
2082
|
const cell = document.createElement("span");
|
|
1068
|
-
cell.className = "chart-heatmap-cell";
|
|
1069
|
-
cell.dataset.
|
|
2083
|
+
cell.className = "icen-chart-heatmap-cell";
|
|
2084
|
+
cell.dataset.icenLevel = String(levelOf(entry.value, max));
|
|
1070
2085
|
cell.setAttribute("title", `${entry.date}\uFF1A${fmt(opts, entry.value)}`);
|
|
1071
2086
|
setMarkData(cell, { index: i, label: entry.date, value: entry.value });
|
|
1072
2087
|
grid.appendChild(cell);
|
|
@@ -1092,7 +2107,8 @@ function renderSparkline(el, opts) {
|
|
|
1092
2107
|
const tone = toneVar(opts.tone);
|
|
1093
2108
|
const points = values.map((value, i) => ({
|
|
1094
2109
|
x: values.length <= 1 ? width / 2 : pad + i / (values.length - 1) * (width - pad * 2),
|
|
1095
|
-
|
|
2110
|
+
/* 负值钳到基线(与折线图同口径):viewBox 仅 28 高,反向射出更刺眼 */
|
|
2111
|
+
y: height - pad - Math.max(0, value) / max * (height - pad * 2),
|
|
1096
2112
|
value
|
|
1097
2113
|
}));
|
|
1098
2114
|
const line = points.map((p, i) => `${i === 0 ? "M" : "L"}${p.x.toFixed(1)},${p.y.toFixed(1)}`).join(" ");
|
|
@@ -1101,16 +2117,16 @@ function renderSparkline(el, opts) {
|
|
|
1101
2117
|
const area = `${line} L${last.x.toFixed(1)},${height - pad} L${first.x.toFixed(1)},${height - pad} Z`;
|
|
1102
2118
|
const gradientId = `icen-chart-line-${++lineGradientSeq}`;
|
|
1103
2119
|
const wrap = document.createElement("div");
|
|
1104
|
-
wrap.className = "chart-sparkline";
|
|
1105
|
-
const
|
|
2120
|
+
wrap.className = "icen-chart-sparkline";
|
|
2121
|
+
const svg = svgEl("svg", { viewBox: `0 0 ${width} ${height}`, role: "img", "aria-label": chartAriaLabel(opts.title, t("charts.type.sparkline")) });
|
|
1106
2122
|
const defs = svgEl("defs", {});
|
|
1107
2123
|
const gradient = svgEl("linearGradient", { id: gradientId, x1: "0", x2: "0", y1: "0", y2: "1" });
|
|
1108
2124
|
gradient.appendChild(svgEl("stop", { offset: "0%", "stop-color": tone, "stop-opacity": "0.28" }));
|
|
1109
2125
|
gradient.appendChild(svgEl("stop", { offset: "100%", "stop-color": tone, "stop-opacity": "0.02" }));
|
|
1110
2126
|
defs.appendChild(gradient);
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
2127
|
+
svg.appendChild(defs);
|
|
2128
|
+
svg.appendChild(svgEl("path", { d: area, fill: `url(#${gradientId})` }));
|
|
2129
|
+
svg.appendChild(svgEl("path", {
|
|
1114
2130
|
d: line,
|
|
1115
2131
|
fill: "none",
|
|
1116
2132
|
stroke: tone,
|
|
@@ -1122,15 +2138,15 @@ function renderSparkline(el, opts) {
|
|
|
1122
2138
|
cx: last.x.toFixed(1),
|
|
1123
2139
|
cy: last.y.toFixed(1),
|
|
1124
2140
|
r: "2.4",
|
|
1125
|
-
fill: "var(--token-card)",
|
|
2141
|
+
fill: "var(--icen-token-card)",
|
|
1126
2142
|
stroke: tone,
|
|
1127
2143
|
"stroke-width": "1.6"
|
|
1128
2144
|
});
|
|
1129
2145
|
const title = svgEl("title", {});
|
|
1130
2146
|
title.textContent = fmt(opts, last.value);
|
|
1131
2147
|
dot.appendChild(title);
|
|
1132
|
-
|
|
1133
|
-
wrap.appendChild(
|
|
2148
|
+
svg.appendChild(dot);
|
|
2149
|
+
wrap.appendChild(svg);
|
|
1134
2150
|
body.appendChild(wrap);
|
|
1135
2151
|
});
|
|
1136
2152
|
attachChartInteraction(el, "sparkline");
|
|
@@ -1144,20 +2160,20 @@ function renderGauge(el, opts) {
|
|
|
1144
2160
|
const radius = 42;
|
|
1145
2161
|
const circumference = 2 * Math.PI * radius;
|
|
1146
2162
|
const wrap = document.createElement("div");
|
|
1147
|
-
wrap.className = "chart-gauge";
|
|
2163
|
+
wrap.className = "icen-chart-gauge";
|
|
1148
2164
|
if (opts.tone) wrap.style.setProperty("--chart-tone", toneVar(opts.tone));
|
|
1149
|
-
const
|
|
1150
|
-
|
|
1151
|
-
|
|
2165
|
+
const svg = svgEl("svg", { viewBox: "0 0 120 120", role: "img", "aria-label": chartAriaLabel(opts.label, t("charts.type.gauge")) });
|
|
2166
|
+
svg.style.transform = "rotate(-90deg)";
|
|
2167
|
+
svg.appendChild(svgEl("circle", {
|
|
1152
2168
|
cx: "60",
|
|
1153
2169
|
cy: "60",
|
|
1154
2170
|
r: String(radius),
|
|
1155
2171
|
fill: "none",
|
|
1156
|
-
stroke: "var(--token-line-soft)",
|
|
2172
|
+
stroke: "var(--icen-token-line-soft)",
|
|
1157
2173
|
"stroke-width": "10"
|
|
1158
2174
|
}));
|
|
1159
2175
|
const dash = ratio * circumference;
|
|
1160
|
-
|
|
2176
|
+
svg.appendChild(svgEl("circle", {
|
|
1161
2177
|
cx: "60",
|
|
1162
2178
|
cy: "60",
|
|
1163
2179
|
r: String(radius),
|
|
@@ -1168,18 +2184,18 @@ function renderGauge(el, opts) {
|
|
|
1168
2184
|
"stroke-linecap": "round"
|
|
1169
2185
|
}));
|
|
1170
2186
|
const center = document.createElement("div");
|
|
1171
|
-
center.className = "chart-gauge-center";
|
|
2187
|
+
center.className = "icen-chart-gauge-center";
|
|
1172
2188
|
const val = document.createElement("span");
|
|
1173
|
-
val.className = "chart-gauge-value";
|
|
2189
|
+
val.className = "icen-chart-gauge-value";
|
|
1174
2190
|
val.textContent = opts.formatValue ? opts.formatValue(opts.value) : `${Math.round(ratio * 100)}%`;
|
|
1175
2191
|
center.appendChild(val);
|
|
1176
2192
|
if (opts.label) {
|
|
1177
2193
|
const lab = document.createElement("span");
|
|
1178
|
-
lab.className = "chart-gauge-label";
|
|
2194
|
+
lab.className = "icen-chart-gauge-label";
|
|
1179
2195
|
lab.textContent = opts.label;
|
|
1180
2196
|
center.appendChild(lab);
|
|
1181
2197
|
}
|
|
1182
|
-
wrap.append(
|
|
2198
|
+
wrap.append(svg, center);
|
|
1183
2199
|
el.appendChild(wrap);
|
|
1184
2200
|
attachChartInteraction(el, "gauge");
|
|
1185
2201
|
return el;
|
|
@@ -1197,25 +2213,27 @@ function renderCalendar(el, opts) {
|
|
|
1197
2213
|
return;
|
|
1198
2214
|
}
|
|
1199
2215
|
const wrap = document.createElement("div");
|
|
1200
|
-
wrap.className = "chart-calendar";
|
|
2216
|
+
wrap.className = "icen-chart-calendar";
|
|
1201
2217
|
if (opts.tone) wrap.style.setProperty("--chart-tone", toneVar(opts.tone));
|
|
1202
2218
|
const weekStart = opts.weekStart === 0 ? 0 : 1;
|
|
1203
|
-
const weekdayDefaults =
|
|
2219
|
+
const weekdayDefaults = t("charts.calendarWeekdays");
|
|
1204
2220
|
const weekdayLabels = opts.labels?.weekdays ?? weekdayDefaults.map((_, i) => weekdayLabelAt(weekdayDefaults, (weekStart + i) % 7));
|
|
1205
|
-
const monthLabel = (m) => opts.labels?.months?.[m] ??
|
|
2221
|
+
const monthLabel = (m) => opts.labels?.months?.[m] ?? t("charts.monthLabel", { p0: m + 1 });
|
|
1206
2222
|
const grid = document.createElement("div");
|
|
1207
|
-
grid.className = "chart-heatmap-grid";
|
|
2223
|
+
grid.className = "icen-chart-heatmap-grid";
|
|
1208
2224
|
grid.setAttribute("role", "img");
|
|
2225
|
+
grid.setAttribute("aria-label", chartAriaLabel(opts.title, t("charts.type.heatmap")));
|
|
1209
2226
|
const months = document.createElement("div");
|
|
1210
|
-
months.className = "chart-calendar-months";
|
|
2227
|
+
months.className = "icen-chart-calendar-months";
|
|
1211
2228
|
const weekdayRow = document.createElement("div");
|
|
1212
|
-
weekdayRow.className = "chart-calendar-weekdays";
|
|
2229
|
+
weekdayRow.className = "icen-chart-calendar-weekdays";
|
|
1213
2230
|
weekdayLabels.forEach((w) => {
|
|
1214
2231
|
const s = document.createElement("span");
|
|
1215
2232
|
s.textContent = w;
|
|
1216
2233
|
weekdayRow.appendChild(s);
|
|
1217
2234
|
});
|
|
1218
2235
|
const max = maxOf(entries.map((e) => e.value));
|
|
2236
|
+
entries.sort((a, b) => a.date.localeCompare(b.date));
|
|
1219
2237
|
const pad = padFirstWeek(grid, entries[0].date, weekStart);
|
|
1220
2238
|
let lastMonth = -1;
|
|
1221
2239
|
entries.forEach((entry, i) => {
|
|
@@ -1224,14 +2242,14 @@ function renderCalendar(el, opts) {
|
|
|
1224
2242
|
if (d.getMonth() !== lastMonth) {
|
|
1225
2243
|
lastMonth = d.getMonth();
|
|
1226
2244
|
const label = document.createElement("span");
|
|
1227
|
-
label.className = "chart-calendar-month";
|
|
2245
|
+
label.className = "icen-chart-calendar-month";
|
|
1228
2246
|
label.textContent = monthLabel(d.getMonth());
|
|
1229
2247
|
label.style.setProperty("--col", String(col));
|
|
1230
2248
|
months.appendChild(label);
|
|
1231
2249
|
}
|
|
1232
2250
|
const cell = document.createElement("span");
|
|
1233
|
-
cell.className = "chart-heatmap-cell";
|
|
1234
|
-
cell.dataset.
|
|
2251
|
+
cell.className = "icen-chart-heatmap-cell";
|
|
2252
|
+
cell.dataset.icenLevel = String(levelOf(entry.value, max));
|
|
1235
2253
|
cell.setAttribute("title", `${entry.date}\uFF1A${fmt(opts, entry.value)}`);
|
|
1236
2254
|
setMarkData(cell, { index: i, label: entry.date, value: entry.value });
|
|
1237
2255
|
grid.appendChild(cell);
|
|
@@ -1253,7 +2271,7 @@ function renderScatter(el, opts) {
|
|
|
1253
2271
|
renderEmpty(body, opts.emptyLabel);
|
|
1254
2272
|
return;
|
|
1255
2273
|
}
|
|
1256
|
-
const width =
|
|
2274
|
+
const width = fluidWidth(body);
|
|
1257
2275
|
const height = 220;
|
|
1258
2276
|
const pad = 30;
|
|
1259
2277
|
let xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, sMax = 0;
|
|
@@ -1268,19 +2286,20 @@ function renderScatter(el, opts) {
|
|
|
1268
2286
|
if (yMax === yMin) yMax = yMin + 1;
|
|
1269
2287
|
const rOf = (size) => size && sMax > 0 ? 3 + size / sMax * 7 : 4;
|
|
1270
2288
|
const wrap = document.createElement("div");
|
|
1271
|
-
wrap.className = "chart-scatter";
|
|
2289
|
+
wrap.className = "icen-chart-scatter";
|
|
1272
2290
|
const tone = toneVar(opts.tone);
|
|
1273
|
-
const
|
|
2291
|
+
const svg = svgEl("svg", { viewBox: `0 0 ${width} ${height}`, role: "img", "aria-label": chartAriaLabel(opts.title, t("charts.type.scatter")) });
|
|
1274
2292
|
const xAt = (x) => pad + (x - xMin) / (xMax - xMin) * (width - pad * 2);
|
|
1275
2293
|
const yAt = (y) => height - pad - (y - yMin) / (yMax - yMin) * (height - pad * 2);
|
|
1276
2294
|
for (let i = 0; i <= 3; i++) {
|
|
1277
|
-
const y = pad + i * (height - pad * 2) / 3;
|
|
1278
|
-
|
|
2295
|
+
const y = Math.round(pad + i * (height - pad * 2) / 3) + 0.5;
|
|
2296
|
+
svg.appendChild(svgEl("line", {
|
|
2297
|
+
class: i === 3 ? "icen-chart-grid icen-chart-baseline" : "icen-chart-grid",
|
|
1279
2298
|
x1: String(pad),
|
|
1280
2299
|
x2: String(width - pad),
|
|
1281
2300
|
y1: String(y),
|
|
1282
2301
|
y2: String(y),
|
|
1283
|
-
stroke: "var(--token-line-soft)",
|
|
2302
|
+
stroke: "var(--icen-token-line-soft)",
|
|
1284
2303
|
"stroke-width": "1"
|
|
1285
2304
|
}));
|
|
1286
2305
|
const tv = yMin + (yMax - yMin) * (3 - i) / 3;
|
|
@@ -1289,19 +2308,20 @@ function renderScatter(el, opts) {
|
|
|
1289
2308
|
y: String(y + 3),
|
|
1290
2309
|
"text-anchor": "end",
|
|
1291
2310
|
"font-size": "8",
|
|
1292
|
-
fill: "var(--token-text-faint)"
|
|
2311
|
+
fill: "var(--icen-token-text-faint)"
|
|
1293
2312
|
});
|
|
1294
|
-
txt.textContent = fmt(opts,
|
|
1295
|
-
|
|
2313
|
+
txt.textContent = fmt(opts, +tv.toFixed(tickPrecision(yMin, yMax, 3)));
|
|
2314
|
+
svg.appendChild(txt);
|
|
1296
2315
|
}
|
|
1297
2316
|
for (let i = 0; i <= 4; i++) {
|
|
1298
|
-
const x = pad + i * (width - pad * 2) / 4;
|
|
1299
|
-
|
|
2317
|
+
const x = Math.round(pad + i * (width - pad * 2) / 4) + 0.5;
|
|
2318
|
+
svg.appendChild(svgEl("line", {
|
|
2319
|
+
class: i === 0 ? "icen-chart-grid icen-chart-grid--v icen-chart-axis" : "icen-chart-grid icen-chart-grid--v",
|
|
1300
2320
|
x1: String(x),
|
|
1301
2321
|
x2: String(x),
|
|
1302
2322
|
y1: String(pad),
|
|
1303
2323
|
y2: String(height - pad),
|
|
1304
|
-
stroke: "var(--token-line-soft)",
|
|
2324
|
+
stroke: "var(--icen-token-line-soft)",
|
|
1305
2325
|
"stroke-width": "1",
|
|
1306
2326
|
"stroke-dasharray": "2 3"
|
|
1307
2327
|
}));
|
|
@@ -1311,20 +2331,20 @@ function renderScatter(el, opts) {
|
|
|
1311
2331
|
y: String(height - pad + 12),
|
|
1312
2332
|
"text-anchor": "middle",
|
|
1313
2333
|
"font-size": "8",
|
|
1314
|
-
fill: "var(--token-text-faint)"
|
|
2334
|
+
fill: "var(--icen-token-text-faint)"
|
|
1315
2335
|
});
|
|
1316
|
-
txt.textContent = fmt(opts,
|
|
1317
|
-
|
|
2336
|
+
txt.textContent = fmt(opts, +tv.toFixed(tickPrecision(xMin, xMax, 4)));
|
|
2337
|
+
svg.appendChild(txt);
|
|
1318
2338
|
}
|
|
1319
2339
|
if (opts.yLabel) {
|
|
1320
|
-
const
|
|
1321
|
-
|
|
1322
|
-
|
|
2340
|
+
const t2 = svgEl("text", { x: "10", y: String(pad - 10), "font-size": "8", fill: "var(--icen-token-text-faint)" });
|
|
2341
|
+
t2.textContent = opts.yLabel;
|
|
2342
|
+
svg.appendChild(t2);
|
|
1323
2343
|
}
|
|
1324
2344
|
if (opts.xLabel) {
|
|
1325
|
-
const
|
|
1326
|
-
|
|
1327
|
-
|
|
2345
|
+
const t2 = svgEl("text", { x: String(width - pad), y: String(pad - 10), "text-anchor": "end", "font-size": "8", fill: "var(--icen-token-text-faint)" });
|
|
2346
|
+
t2.textContent = opts.xLabel;
|
|
2347
|
+
svg.appendChild(t2);
|
|
1328
2348
|
}
|
|
1329
2349
|
pts.forEach((p, i) => {
|
|
1330
2350
|
const c = svgEl("circle", {
|
|
@@ -1341,11 +2361,12 @@ function renderScatter(el, opts) {
|
|
|
1341
2361
|
c.appendChild(title);
|
|
1342
2362
|
setMarkData(c, { index: i, label: p.label ?? `#${i + 1}`, value: p.y });
|
|
1343
2363
|
c.dataset.chartX = String(p.x);
|
|
1344
|
-
|
|
2364
|
+
svg.appendChild(c);
|
|
1345
2365
|
});
|
|
1346
|
-
wrap.appendChild(
|
|
2366
|
+
wrap.appendChild(svg);
|
|
1347
2367
|
body.appendChild(wrap);
|
|
1348
2368
|
});
|
|
2369
|
+
if (el.dataset.icenChartBody == null) observeFluidWidth(el, () => renderScatter(el, opts));
|
|
1349
2370
|
attachChartInteraction(el, "scatter");
|
|
1350
2371
|
return el;
|
|
1351
2372
|
}
|
|
@@ -1395,7 +2416,7 @@ function pivotData(spec) {
|
|
|
1395
2416
|
const labels = [];
|
|
1396
2417
|
const seenLabel = /* @__PURE__ */ new Set();
|
|
1397
2418
|
const hasSeries = data.some((r) => r[seriesField] != null && r[seriesField] !== "");
|
|
1398
|
-
const seriesNames = [];
|
|
2419
|
+
const seriesNames = hasSeries ? [] : [""];
|
|
1399
2420
|
const seenSeries = /* @__PURE__ */ new Set();
|
|
1400
2421
|
for (const r of data) {
|
|
1401
2422
|
const l = str2(r[labelField]);
|
|
@@ -1484,8 +2505,8 @@ function normalizeChartSpec(raw) {
|
|
|
1484
2505
|
const s = src;
|
|
1485
2506
|
const spec = {};
|
|
1486
2507
|
if (typeof s.type === "string") {
|
|
1487
|
-
const
|
|
1488
|
-
spec.type = CHART_TYPE_ALIASES[
|
|
2508
|
+
const t2 = s.type.trim().toLowerCase();
|
|
2509
|
+
spec.type = CHART_TYPE_ALIASES[t2] ?? t2;
|
|
1489
2510
|
}
|
|
1490
2511
|
for (const k of ["title", "tone", "emptyLabel"]) {
|
|
1491
2512
|
if (typeof s[k] === "string") spec[k] = s[k];
|
|
@@ -1507,7 +2528,7 @@ function normalizeChartSpec(raw) {
|
|
|
1507
2528
|
if (Array.isArray(s.series)) {
|
|
1508
2529
|
const series = s.series.filter((v) => !!v && typeof v === "object").map((v, i) => {
|
|
1509
2530
|
const values = Array.isArray(v.values) ? v.values.map(toNum).filter((n) => n != null) : [];
|
|
1510
|
-
const sv = { name: String(v.name ??
|
|
2531
|
+
const sv = { name: String(v.name ?? t("charts.seriesName", { p0: i + 1 })), values };
|
|
1511
2532
|
const tone = v.tone;
|
|
1512
2533
|
if (typeof tone === "string" || typeof tone === "number") sv.tone = tone;
|
|
1513
2534
|
return sv;
|
|
@@ -1542,6 +2563,40 @@ function normalizeChartSpec(raw) {
|
|
|
1542
2563
|
}
|
|
1543
2564
|
spec.format = format;
|
|
1544
2565
|
}
|
|
2566
|
+
if (typeof s.downsample === "boolean") spec.downsample = s.downsample;
|
|
2567
|
+
else {
|
|
2568
|
+
const n = toNum(s.downsample);
|
|
2569
|
+
if (n != null) spec.downsample = n;
|
|
2570
|
+
}
|
|
2571
|
+
if (s.zoom === "x" || s.zoom === "brush") spec.zoom = s.zoom;
|
|
2572
|
+
if (typeof s.loading === "boolean") spec.loading = s.loading;
|
|
2573
|
+
if (Array.isArray(s.marks)) {
|
|
2574
|
+
const marks = [];
|
|
2575
|
+
for (const raw2 of s.marks) {
|
|
2576
|
+
if (!raw2 || typeof raw2 !== "object" || Array.isArray(raw2)) continue;
|
|
2577
|
+
const m = raw2;
|
|
2578
|
+
if (m.type === "line") {
|
|
2579
|
+
if (m.axis !== "x" && m.axis !== "y") continue;
|
|
2580
|
+
if (typeof m.value !== "number" && typeof m.value !== "string") continue;
|
|
2581
|
+
const mark = { type: "line", axis: m.axis, value: m.value };
|
|
2582
|
+
if (typeof m.label === "string" && m.label !== "") mark.label = m.label;
|
|
2583
|
+
if (m.tone === "success" || m.tone === "warning" || m.tone === "error" || m.tone === "info") {
|
|
2584
|
+
mark.tone = m.tone;
|
|
2585
|
+
}
|
|
2586
|
+
marks.push(mark);
|
|
2587
|
+
} else if (m.type === "point") {
|
|
2588
|
+
if (typeof m.label !== "string" || m.label === "") continue;
|
|
2589
|
+
const mark = { type: "point", label: m.label };
|
|
2590
|
+
const si = toNum(m.seriesIndex);
|
|
2591
|
+
if (si != null && si >= 0) mark.seriesIndex = Math.floor(si);
|
|
2592
|
+
const v = toNum(m.value);
|
|
2593
|
+
if (v != null) mark.value = v;
|
|
2594
|
+
if (typeof m.text === "string") mark.text = m.text;
|
|
2595
|
+
marks.push(mark);
|
|
2596
|
+
}
|
|
2597
|
+
}
|
|
2598
|
+
if (marks.length > 0) spec.marks = marks;
|
|
2599
|
+
}
|
|
1545
2600
|
const isDateRecords = spec.data?.length && spec.data[0] && "date" in spec.data[0];
|
|
1546
2601
|
if (spec.data && spec.data.length > 0 && !isDateRecords && !spec.series && !spec.points && !spec.values && !spec.segments) {
|
|
1547
2602
|
Object.assign(spec, pivotData(spec));
|
|
@@ -1581,6 +2636,392 @@ function inferChartType(spec) {
|
|
|
1581
2636
|
if (typeof spec.max === "number" && spec.values && spec.values.length === 1) return "gauge";
|
|
1582
2637
|
return "vbar";
|
|
1583
2638
|
}
|
|
2639
|
+
var DOWNSAMPLE_DEFAULT_THRESHOLD = 1e3;
|
|
2640
|
+
var CHART_ZOOM_DRAG_MIN_PX = 5;
|
|
2641
|
+
var CHART_LINE_W = 360;
|
|
2642
|
+
var CHART_LINE_H = 150;
|
|
2643
|
+
var CHART_LINE_PAD = 14;
|
|
2644
|
+
function isDownsampleableType(type) {
|
|
2645
|
+
return type === "line" || type === "area" || type === "scatter";
|
|
2646
|
+
}
|
|
2647
|
+
function isZoomableType(type) {
|
|
2648
|
+
return type === "line" || type === "area" || type === "vbar";
|
|
2649
|
+
}
|
|
2650
|
+
function isStreamableType(type) {
|
|
2651
|
+
return type === "line" || type === "area" || type === "vbar";
|
|
2652
|
+
}
|
|
2653
|
+
function downsampleView(view, type) {
|
|
2654
|
+
const raw = view.downsample;
|
|
2655
|
+
if (raw == null || raw === false) return { view, note: null };
|
|
2656
|
+
const threshold = raw === true ? DOWNSAMPLE_DEFAULT_THRESHOLD : Math.floor(raw);
|
|
2657
|
+
if (!Number.isFinite(threshold)) return { view, note: null };
|
|
2658
|
+
if (type === "scatter") {
|
|
2659
|
+
const pts = view.points ?? [];
|
|
2660
|
+
if (pts.length === 0) return { view, note: null };
|
|
2661
|
+
const sampled2 = lttb(pts, threshold, (p) => p.x, (p) => p.y);
|
|
2662
|
+
if (sampled2.length === pts.length) return { view, note: null };
|
|
2663
|
+
return { view: { ...view, points: sampled2 }, note: t("charts.sampled", { p0: pts.length, p1: sampled2.length }) };
|
|
2664
|
+
}
|
|
2665
|
+
const labels = view.labels ?? [];
|
|
2666
|
+
if (labels.length === 0) return { view, note: null };
|
|
2667
|
+
const guide = view.series && view.series.length > 0 ? view.series[0]?.values ?? [] : view.values ?? [];
|
|
2668
|
+
const count = Math.min(labels.length, guide.length);
|
|
2669
|
+
if (count === 0) return { view, note: null };
|
|
2670
|
+
const indexed = guide.slice(0, count).map((v, i) => ({ i, v }));
|
|
2671
|
+
const sampled = lttb(indexed, threshold, (p) => p.i, (p) => p.v);
|
|
2672
|
+
if (sampled.length >= count) return { view, note: null };
|
|
2673
|
+
const idx = sampled.map((p) => p.i);
|
|
2674
|
+
return {
|
|
2675
|
+
view: {
|
|
2676
|
+
...view,
|
|
2677
|
+
labels: idx.map((i) => labels[i] ?? ""),
|
|
2678
|
+
values: view.values ? idx.map((i) => view.values?.[i] ?? 0) : void 0,
|
|
2679
|
+
series: view.series?.map((s) => ({ ...s, values: idx.map((i) => s.values[i] ?? 0) }))
|
|
2680
|
+
},
|
|
2681
|
+
note: t("charts.sampled", { p0: count, p1: idx.length })
|
|
2682
|
+
};
|
|
2683
|
+
}
|
|
2684
|
+
function renderChartSkeleton(body) {
|
|
2685
|
+
const box = document.createElement("div");
|
|
2686
|
+
box.className = "icen-chart-skeleton";
|
|
2687
|
+
box.setAttribute("role", "status");
|
|
2688
|
+
box.setAttribute("aria-busy", "true");
|
|
2689
|
+
box.setAttribute("aria-label", t("charts.loading"));
|
|
2690
|
+
const widths = [100, 84, 92, 68, 76, 52];
|
|
2691
|
+
for (const w of widths) {
|
|
2692
|
+
const bar = document.createElement("div");
|
|
2693
|
+
bar.className = "icen-chart-skeleton-bar";
|
|
2694
|
+
bar.style.width = `${w}%`;
|
|
2695
|
+
box.appendChild(bar);
|
|
2696
|
+
}
|
|
2697
|
+
body.appendChild(box);
|
|
2698
|
+
}
|
|
2699
|
+
var CHART_MARK_ACCENT = "var(--icen-token-accent)";
|
|
2700
|
+
var CHART_MARK_ACCENT_TEXT = "var(--icen-token-accent-text)";
|
|
2701
|
+
function markToneVar(tone) {
|
|
2702
|
+
switch (tone) {
|
|
2703
|
+
case "success":
|
|
2704
|
+
return "var(--icen-token-success)";
|
|
2705
|
+
case "warning":
|
|
2706
|
+
return "var(--icen-token-warning)";
|
|
2707
|
+
case "error":
|
|
2708
|
+
return "var(--icen-token-error)";
|
|
2709
|
+
case "info":
|
|
2710
|
+
return "var(--icen-token-info)";
|
|
2711
|
+
default:
|
|
2712
|
+
return "var(--icen-token-text-faint)";
|
|
2713
|
+
}
|
|
2714
|
+
}
|
|
2715
|
+
function markWarnOnce(warned, mark, reason) {
|
|
2716
|
+
const key = JSON.stringify(mark);
|
|
2717
|
+
if (warned.has(key)) return;
|
|
2718
|
+
warned.add(key);
|
|
2719
|
+
console.warn(`[icen:chart] \u65E0\u6548\u6807\u8BB0\u5DF2\u8DF3\u8FC7\uFF08${reason}\uFF09`, mark);
|
|
2720
|
+
}
|
|
2721
|
+
function paintChartMarks(root, view, spec, formatValue, warned) {
|
|
2722
|
+
const marks = spec.marks;
|
|
2723
|
+
if (!marks || marks.length === 0) return;
|
|
2724
|
+
const type = spec.type;
|
|
2725
|
+
if (type === "line" || type === "area") paintSvgChartMarks(root, view, marks, formatValue, warned);
|
|
2726
|
+
else if (type === "vbar") paintVBarChartMarks(root, view, spec, marks, formatValue, warned);
|
|
2727
|
+
}
|
|
2728
|
+
function paintSvgChartMarks(root, view, marks, formatValue, warned) {
|
|
2729
|
+
const svg = root.querySelector(".icen-chart-line svg");
|
|
2730
|
+
if (!svg) return;
|
|
2731
|
+
const labels = view.labels ?? [];
|
|
2732
|
+
const n = labels.length;
|
|
2733
|
+
if (n === 0) return;
|
|
2734
|
+
const seriesList = view.series && view.series.length > 0 ? view.series : view.values ? [{ name: "", values: view.values }] : [];
|
|
2735
|
+
let max = 1;
|
|
2736
|
+
for (const s of seriesList) max = Math.max(max, maxOf(s.values.slice(0, n)));
|
|
2737
|
+
const dims = svgDimsOf(svg);
|
|
2738
|
+
const W = dims.w;
|
|
2739
|
+
const H = dims.h;
|
|
2740
|
+
const PAD = CHART_LINE_PAD;
|
|
2741
|
+
const xAt = (i) => n <= 1 ? W / 2 : PAD + i / (n - 1) * (W - PAD * 2);
|
|
2742
|
+
const yAt = (v) => H - PAD - Math.max(0, v) / max * (H - PAD * 2);
|
|
2743
|
+
for (const mark of marks) {
|
|
2744
|
+
if (mark.type === "line") {
|
|
2745
|
+
const color = markToneVar(mark.tone);
|
|
2746
|
+
if (mark.axis === "y") {
|
|
2747
|
+
const v = typeof mark.value === "number" ? mark.value : Number(mark.value);
|
|
2748
|
+
if (!Number.isFinite(v)) {
|
|
2749
|
+
markWarnOnce(warned, mark, "\u53C2\u8003\u7EBF\u6570\u503C NaN");
|
|
2750
|
+
continue;
|
|
2751
|
+
}
|
|
2752
|
+
const y = clampNum(yAt(v), CHART_LINE_PAD, H - PAD);
|
|
2753
|
+
svg.appendChild(svgEl("line", {
|
|
2754
|
+
class: "icen-chart-mark-line",
|
|
2755
|
+
x1: String(PAD),
|
|
2756
|
+
x2: String(W - PAD),
|
|
2757
|
+
y1: y.toFixed(1),
|
|
2758
|
+
y2: y.toFixed(1),
|
|
2759
|
+
stroke: color,
|
|
2760
|
+
"stroke-width": "1",
|
|
2761
|
+
"stroke-dasharray": "4 3"
|
|
2762
|
+
}));
|
|
2763
|
+
const label = svgEl("text", {
|
|
2764
|
+
class: "icen-chart-mark-label",
|
|
2765
|
+
x: String(W - PAD),
|
|
2766
|
+
y: String(clampNum(y - 4, 8, CHART_LINE_H - 4)),
|
|
2767
|
+
"text-anchor": "end",
|
|
2768
|
+
"font-size": "8",
|
|
2769
|
+
fill: color
|
|
2770
|
+
});
|
|
2771
|
+
label.textContent = mark.label ?? formatValue(v);
|
|
2772
|
+
svg.appendChild(label);
|
|
2773
|
+
} else {
|
|
2774
|
+
const idx = typeof mark.value === "number" ? Math.round(mark.value) : labels.indexOf(mark.value);
|
|
2775
|
+
if (idx < 0 || idx >= n) {
|
|
2776
|
+
markWarnOnce(warned, mark, "\u53C2\u8003\u7EBF\u7C7B\u76EE\u4E0D\u5B58\u5728");
|
|
2777
|
+
continue;
|
|
2778
|
+
}
|
|
2779
|
+
const x = xAt(idx);
|
|
2780
|
+
svg.appendChild(svgEl("line", {
|
|
2781
|
+
class: "icen-chart-mark-line",
|
|
2782
|
+
x1: x.toFixed(1),
|
|
2783
|
+
x2: x.toFixed(1),
|
|
2784
|
+
y1: String(PAD),
|
|
2785
|
+
y2: String(H - PAD),
|
|
2786
|
+
stroke: color,
|
|
2787
|
+
"stroke-width": "1",
|
|
2788
|
+
"stroke-dasharray": "4 3"
|
|
2789
|
+
}));
|
|
2790
|
+
const label = svgEl("text", {
|
|
2791
|
+
class: "icen-chart-mark-label",
|
|
2792
|
+
x: String(clampNum(x, 10, W - 10)),
|
|
2793
|
+
y: String(PAD + 8),
|
|
2794
|
+
"text-anchor": "middle",
|
|
2795
|
+
"font-size": "8",
|
|
2796
|
+
fill: color
|
|
2797
|
+
});
|
|
2798
|
+
label.textContent = mark.label ?? labels[idx] ?? "";
|
|
2799
|
+
svg.appendChild(label);
|
|
2800
|
+
}
|
|
2801
|
+
} else {
|
|
2802
|
+
const idx = labels.indexOf(mark.label);
|
|
2803
|
+
if (idx < 0 || idx >= n) {
|
|
2804
|
+
markWarnOnce(warned, mark, "\u6807\u8BB0\u70B9\u7C7B\u76EE\u4E0D\u5B58\u5728");
|
|
2805
|
+
continue;
|
|
2806
|
+
}
|
|
2807
|
+
const si = Math.max(0, Math.floor(mark.seriesIndex ?? 0));
|
|
2808
|
+
const s = seriesList[si];
|
|
2809
|
+
if (!s) {
|
|
2810
|
+
markWarnOnce(warned, mark, "\u6807\u8BB0\u70B9\u7CFB\u5217\u4E0D\u5B58\u5728");
|
|
2811
|
+
continue;
|
|
2812
|
+
}
|
|
2813
|
+
const v = mark.value ?? s.values[idx] ?? NaN;
|
|
2814
|
+
if (!Number.isFinite(v)) {
|
|
2815
|
+
markWarnOnce(warned, mark, "\u6807\u8BB0\u70B9\u6570\u503C NaN");
|
|
2816
|
+
continue;
|
|
2817
|
+
}
|
|
2818
|
+
const x = xAt(idx);
|
|
2819
|
+
const y = clampNum(yAt(v), CHART_LINE_PAD, H - PAD);
|
|
2820
|
+
const g = svgEl("g", { class: "icen-chart-mark-point" });
|
|
2821
|
+
g.appendChild(svgEl("circle", {
|
|
2822
|
+
cx: x.toFixed(1),
|
|
2823
|
+
cy: y.toFixed(1),
|
|
2824
|
+
r: "6",
|
|
2825
|
+
fill: "none",
|
|
2826
|
+
stroke: CHART_MARK_ACCENT,
|
|
2827
|
+
"stroke-width": "1.5"
|
|
2828
|
+
}));
|
|
2829
|
+
g.appendChild(svgEl("circle", { cx: x.toFixed(1), cy: y.toFixed(1), r: "2", fill: CHART_MARK_ACCENT }));
|
|
2830
|
+
const label = svgEl("text", {
|
|
2831
|
+
class: "icen-chart-mark-label",
|
|
2832
|
+
x: String(clampNum(x, 12, W - 12)),
|
|
2833
|
+
y: String(clampNum(y - 10, 8, CHART_LINE_H - 4)),
|
|
2834
|
+
"text-anchor": "middle",
|
|
2835
|
+
"font-size": "8",
|
|
2836
|
+
fill: CHART_MARK_ACCENT_TEXT
|
|
2837
|
+
});
|
|
2838
|
+
label.textContent = mark.text ?? mark.label;
|
|
2839
|
+
g.appendChild(label);
|
|
2840
|
+
svg.appendChild(g);
|
|
2841
|
+
}
|
|
2842
|
+
}
|
|
2843
|
+
}
|
|
2844
|
+
function paintVBarChartMarks(root, view, spec, marks, formatValue, warned) {
|
|
2845
|
+
const wrap = root.querySelector(".icen-chart-vbar");
|
|
2846
|
+
if (!wrap) return;
|
|
2847
|
+
const seriesList = view.series && view.series.length > 0 ? view.series : view.values ? [{ name: "", values: view.values }] : [];
|
|
2848
|
+
const labels = view.labels ?? [];
|
|
2849
|
+
const n = Math.min(labels.length, ...seriesList.map((s) => s.values.length));
|
|
2850
|
+
if (n === 0 || seriesList.length === 0) return;
|
|
2851
|
+
const multi = seriesList.length > 1;
|
|
2852
|
+
let max = 1;
|
|
2853
|
+
if (spec.stacked && multi) {
|
|
2854
|
+
for (let i = 0; i < n; i++) {
|
|
2855
|
+
let sum2 = 0;
|
|
2856
|
+
for (const s of seriesList) sum2 += Math.max(0, s.values[i] ?? 0);
|
|
2857
|
+
if (sum2 > max) max = sum2;
|
|
2858
|
+
}
|
|
2859
|
+
} else {
|
|
2860
|
+
for (const s of seriesList) max = Math.max(max, maxOf(s.values.slice(0, n)));
|
|
2861
|
+
}
|
|
2862
|
+
const centerPct = (i) => (i + 0.5) / n * 100;
|
|
2863
|
+
for (const mark of marks) {
|
|
2864
|
+
if (mark.type === "line") {
|
|
2865
|
+
if (mark.axis === "y") {
|
|
2866
|
+
const v = typeof mark.value === "number" ? mark.value : Number(mark.value);
|
|
2867
|
+
if (!Number.isFinite(v)) {
|
|
2868
|
+
markWarnOnce(warned, mark, "\u53C2\u8003\u7EBF\u6570\u503C NaN");
|
|
2869
|
+
continue;
|
|
2870
|
+
}
|
|
2871
|
+
const line = document.createElement("div");
|
|
2872
|
+
line.className = "icen-chart-mark-line icen-chart-mark-line--h";
|
|
2873
|
+
line.style.top = `${(clampNum(1 - Math.max(0, v) / max, 0.02, 0.98) * 100).toFixed(2)}%`;
|
|
2874
|
+
line.style.setProperty("--chart-mark-tone", markToneVar(mark.tone));
|
|
2875
|
+
const lab = document.createElement("span");
|
|
2876
|
+
lab.className = "icen-chart-mark-label";
|
|
2877
|
+
lab.textContent = mark.label ?? formatValue(v);
|
|
2878
|
+
line.appendChild(lab);
|
|
2879
|
+
wrap.appendChild(line);
|
|
2880
|
+
} else {
|
|
2881
|
+
const idx = typeof mark.value === "number" ? Math.round(mark.value) : labels.indexOf(mark.value);
|
|
2882
|
+
if (idx < 0 || idx >= n) {
|
|
2883
|
+
markWarnOnce(warned, mark, "\u53C2\u8003\u7EBF\u7C7B\u76EE\u4E0D\u5B58\u5728");
|
|
2884
|
+
continue;
|
|
2885
|
+
}
|
|
2886
|
+
const line = document.createElement("div");
|
|
2887
|
+
line.className = "icen-chart-mark-line icen-chart-mark-line--v";
|
|
2888
|
+
line.style.left = `${centerPct(idx).toFixed(2)}%`;
|
|
2889
|
+
line.style.setProperty("--chart-mark-tone", markToneVar(mark.tone));
|
|
2890
|
+
const lab = document.createElement("span");
|
|
2891
|
+
lab.className = "icen-chart-mark-label";
|
|
2892
|
+
lab.textContent = mark.label ?? labels[idx] ?? "";
|
|
2893
|
+
line.appendChild(lab);
|
|
2894
|
+
wrap.appendChild(line);
|
|
2895
|
+
}
|
|
2896
|
+
} else {
|
|
2897
|
+
const idx = labels.indexOf(mark.label);
|
|
2898
|
+
if (idx < 0 || idx >= n) {
|
|
2899
|
+
markWarnOnce(warned, mark, "\u6807\u8BB0\u70B9\u7C7B\u76EE\u4E0D\u5B58\u5728");
|
|
2900
|
+
continue;
|
|
2901
|
+
}
|
|
2902
|
+
const si = Math.max(0, Math.floor(mark.seriesIndex ?? 0));
|
|
2903
|
+
const s = seriesList[si];
|
|
2904
|
+
if (!s) {
|
|
2905
|
+
markWarnOnce(warned, mark, "\u6807\u8BB0\u70B9\u7CFB\u5217\u4E0D\u5B58\u5728");
|
|
2906
|
+
continue;
|
|
2907
|
+
}
|
|
2908
|
+
const v = mark.value ?? s.values[idx] ?? NaN;
|
|
2909
|
+
if (!Number.isFinite(v)) {
|
|
2910
|
+
markWarnOnce(warned, mark, "\u6807\u8BB0\u70B9\u6570\u503C NaN");
|
|
2911
|
+
continue;
|
|
2912
|
+
}
|
|
2913
|
+
const dot = document.createElement("div");
|
|
2914
|
+
dot.className = "icen-chart-mark-point";
|
|
2915
|
+
dot.style.left = `${centerPct(idx).toFixed(2)}%`;
|
|
2916
|
+
dot.style.bottom = `${(clampNum(Math.max(0, v) / max, 0, 1) * 100).toFixed(2)}%`;
|
|
2917
|
+
const lab = document.createElement("span");
|
|
2918
|
+
lab.className = "icen-chart-mark-label";
|
|
2919
|
+
lab.textContent = mark.text ?? mark.label;
|
|
2920
|
+
dot.appendChild(lab);
|
|
2921
|
+
wrap.appendChild(dot);
|
|
2922
|
+
}
|
|
2923
|
+
}
|
|
2924
|
+
}
|
|
2925
|
+
function chartAriaLabel(title, typeName) {
|
|
2926
|
+
return title ? `${typeName}\uFF1A${title}` : typeName;
|
|
2927
|
+
}
|
|
2928
|
+
function svgDimsOf(svg) {
|
|
2929
|
+
const vb = (svg.getAttribute("viewBox") ?? "").split(/\s+/).map(Number);
|
|
2930
|
+
const w = Number.isFinite(vb[2]) && (vb[2] ?? 0) > 0 ? vb[2] : CHART_LINE_W;
|
|
2931
|
+
const h2 = Number.isFinite(vb[3]) && (vb[3] ?? 0) > 0 ? vb[3] : CHART_LINE_H;
|
|
2932
|
+
return { w, h: h2 };
|
|
2933
|
+
}
|
|
2934
|
+
var fluidObservers = /* @__PURE__ */ new WeakMap();
|
|
2935
|
+
function fluidWidth(host) {
|
|
2936
|
+
const w = Math.round(host.getBoundingClientRect().width);
|
|
2937
|
+
return w > 0 ? Math.max(29, w) : 360;
|
|
2938
|
+
}
|
|
2939
|
+
function observeFluidWidth(el, rerender) {
|
|
2940
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
2941
|
+
fluidObservers.get(el)?.disconnect();
|
|
2942
|
+
let last = Math.round(el.getBoundingClientRect().width);
|
|
2943
|
+
const ro = new ResizeObserver(() => {
|
|
2944
|
+
if (!el.isConnected) {
|
|
2945
|
+
ro.disconnect();
|
|
2946
|
+
fluidObservers.delete(el);
|
|
2947
|
+
return;
|
|
2948
|
+
}
|
|
2949
|
+
const w = Math.round(el.getBoundingClientRect().width);
|
|
2950
|
+
if (Math.abs(w - last) < 2) return;
|
|
2951
|
+
last = w;
|
|
2952
|
+
rerender();
|
|
2953
|
+
});
|
|
2954
|
+
ro.observe(el);
|
|
2955
|
+
fluidObservers.set(el, ro);
|
|
2956
|
+
}
|
|
2957
|
+
function releaseFluidWidth(el) {
|
|
2958
|
+
fluidObservers.get(el)?.disconnect();
|
|
2959
|
+
fluidObservers.delete(el);
|
|
2960
|
+
}
|
|
2961
|
+
function createChartToDataURL(root) {
|
|
2962
|
+
const cache = /* @__PURE__ */ new Map();
|
|
2963
|
+
return (opts) => {
|
|
2964
|
+
if (typeof document === "undefined") return void 0;
|
|
2965
|
+
const scale = clampNum(toNum(opts?.scale) ?? 2, 0.5, 4);
|
|
2966
|
+
const svgs = Array.from(root.querySelectorAll("svg"));
|
|
2967
|
+
if (svgs.length === 0) return void 0;
|
|
2968
|
+
const parts = [];
|
|
2969
|
+
for (const svg of svgs) {
|
|
2970
|
+
const { w, h: h2 } = svgDimsOf(svg);
|
|
2971
|
+
const clone = svg.cloneNode(true);
|
|
2972
|
+
clone.setAttribute("xmlns", SVG_NS);
|
|
2973
|
+
clone.setAttribute("width", String(w));
|
|
2974
|
+
clone.setAttribute("height", String(h2));
|
|
2975
|
+
let str2;
|
|
2976
|
+
try {
|
|
2977
|
+
str2 = new XMLSerializer().serializeToString(clone);
|
|
2978
|
+
} catch {
|
|
2979
|
+
return void 0;
|
|
2980
|
+
}
|
|
2981
|
+
parts.push({ src: `data:image/svg+xml;charset=utf-8,${encodeURIComponent(str2)}`, w, h: h2 });
|
|
2982
|
+
}
|
|
2983
|
+
const key = `${scale}|${parts.map((p) => p.src).join("")}`;
|
|
2984
|
+
const hit = cache.get(key);
|
|
2985
|
+
if (hit) return hit;
|
|
2986
|
+
const canvas = document.createElement("canvas");
|
|
2987
|
+
let ctx = null;
|
|
2988
|
+
try {
|
|
2989
|
+
ctx = canvas.getContext("2d");
|
|
2990
|
+
} catch {
|
|
2991
|
+
return void 0;
|
|
2992
|
+
}
|
|
2993
|
+
if (!ctx) return void 0;
|
|
2994
|
+
const context = ctx;
|
|
2995
|
+
const totalW = Math.max(...parts.map((p) => p.w));
|
|
2996
|
+
const totalH = parts.reduce((sum2, p) => sum2 + p.h, 0);
|
|
2997
|
+
canvas.width = Math.max(1, Math.round(totalW * scale));
|
|
2998
|
+
canvas.height = Math.max(1, Math.round(totalH * scale));
|
|
2999
|
+
let loaded = 0;
|
|
3000
|
+
let failed = false;
|
|
3001
|
+
let offsetY = 0;
|
|
3002
|
+
for (const part of parts) {
|
|
3003
|
+
const dy = offsetY;
|
|
3004
|
+
offsetY += part.h;
|
|
3005
|
+
const img = new Image();
|
|
3006
|
+
img.onload = () => {
|
|
3007
|
+
if (failed) return;
|
|
3008
|
+
context.drawImage(img, 0, dy * scale, part.w * scale, part.h * scale);
|
|
3009
|
+
loaded += 1;
|
|
3010
|
+
if (loaded === parts.length) {
|
|
3011
|
+
try {
|
|
3012
|
+
cache.set(key, canvas.toDataURL("image/png"));
|
|
3013
|
+
} catch {
|
|
3014
|
+
}
|
|
3015
|
+
}
|
|
3016
|
+
};
|
|
3017
|
+
img.onerror = () => {
|
|
3018
|
+
failed = true;
|
|
3019
|
+
};
|
|
3020
|
+
img.src = part.src;
|
|
3021
|
+
}
|
|
3022
|
+
return cache.get(key);
|
|
3023
|
+
};
|
|
3024
|
+
}
|
|
1584
3025
|
function dispatchChartEvent(root, type, mark, chart, phase, pointer) {
|
|
1585
3026
|
const read = (name) => mark.getAttribute(name) ?? void 0;
|
|
1586
3027
|
const numOr = (v) => v == null ? void 0 : Number(v);
|
|
@@ -1588,11 +3029,11 @@ function dispatchChartEvent(root, type, mark, chart, phase, pointer) {
|
|
|
1588
3029
|
type,
|
|
1589
3030
|
phase,
|
|
1590
3031
|
chart,
|
|
1591
|
-
index: numOr(read("data-chart-index")),
|
|
1592
|
-
seriesIndex: numOr(read("data-chart-series")),
|
|
1593
|
-
seriesName: read("data-chart-series-name"),
|
|
1594
|
-
label: read("data-chart-label"),
|
|
1595
|
-
value: numOr(read("data-chart-value")),
|
|
3032
|
+
index: numOr(read("data-icen-chart-index")),
|
|
3033
|
+
seriesIndex: numOr(read("data-icen-chart-series")),
|
|
3034
|
+
seriesName: read("data-icen-chart-series-name"),
|
|
3035
|
+
label: read("data-icen-chart-label"),
|
|
3036
|
+
value: numOr(read("data-icen-chart-value")),
|
|
1596
3037
|
target: mark,
|
|
1597
3038
|
pointerX: pointer?.x,
|
|
1598
3039
|
pointerY: pointer?.y
|
|
@@ -1603,7 +3044,7 @@ var tooltipEl = null;
|
|
|
1603
3044
|
function chartTooltip() {
|
|
1604
3045
|
if (!tooltipEl) {
|
|
1605
3046
|
tooltipEl = document.createElement("div");
|
|
1606
|
-
tooltipEl.className = "chart-tooltip";
|
|
3047
|
+
tooltipEl.className = "icen-chart-tooltip";
|
|
1607
3048
|
tooltipEl.setAttribute("role", "tooltip");
|
|
1608
3049
|
tooltipEl.hidden = true;
|
|
1609
3050
|
document.body.appendChild(tooltipEl);
|
|
@@ -1612,14 +3053,14 @@ function chartTooltip() {
|
|
|
1612
3053
|
}
|
|
1613
3054
|
function applyTooltipSizing(host) {
|
|
1614
3055
|
const tip = chartTooltip();
|
|
1615
|
-
const raw = host?.closest(".chart, [data-chart-root]")?.getAttribute("data-panel-max") ?? null;
|
|
3056
|
+
const raw = host?.closest(".icen-chart, [data-icen-chart-root]")?.getAttribute("data-icen-panel-max") ?? null;
|
|
1616
3057
|
const n = raw != null ? Number(raw) : NaN;
|
|
1617
3058
|
tip.style.maxWidth = Number.isFinite(n) && n > 0 ? `${n}px` : "";
|
|
1618
3059
|
}
|
|
1619
3060
|
function tooltipText(mark) {
|
|
1620
|
-
const label = mark.getAttribute("data-chart-label") ?? "";
|
|
1621
|
-
const series = mark.getAttribute("data-chart-series-name");
|
|
1622
|
-
const value = mark.getAttribute("data-chart-value");
|
|
3061
|
+
const label = mark.getAttribute("data-icen-chart-label") ?? "";
|
|
3062
|
+
const series = mark.getAttribute("data-icen-chart-series-name");
|
|
3063
|
+
const value = mark.getAttribute("data-icen-chart-value");
|
|
1623
3064
|
const head = series ? label ? `${series} \xB7 ${label}` : series : label;
|
|
1624
3065
|
return value != null ? `${head}\uFF1A${value}` : head;
|
|
1625
3066
|
}
|
|
@@ -1651,8 +3092,8 @@ function bindChartEvents(root) {
|
|
|
1651
3092
|
const typeNow = () => chartDelegateMeta.get(root)?.type() ?? "vbar";
|
|
1652
3093
|
const tipEnabled = () => chartDelegateMeta.get(root)?.tooltip() ?? true;
|
|
1653
3094
|
const markOf = (e) => {
|
|
1654
|
-
const
|
|
1655
|
-
return
|
|
3095
|
+
const t2 = e.target;
|
|
3096
|
+
return t2 instanceof Element ? t2.closest("[data-icen-chart-mark]") : null;
|
|
1656
3097
|
};
|
|
1657
3098
|
let hoverMark = null;
|
|
1658
3099
|
const enterMark = (mark, x, y) => {
|
|
@@ -1749,70 +3190,283 @@ function hasLegendOf(spec) {
|
|
|
1749
3190
|
function renderChart(el, raw) {
|
|
1750
3191
|
const noop = () => void 0;
|
|
1751
3192
|
if (typeof document === "undefined") {
|
|
1752
|
-
return {
|
|
3193
|
+
return {
|
|
3194
|
+
el,
|
|
3195
|
+
spec: {},
|
|
3196
|
+
update: noop,
|
|
3197
|
+
append: noop,
|
|
3198
|
+
toDataURL: () => void 0,
|
|
3199
|
+
on: () => noop,
|
|
3200
|
+
destroy: noop
|
|
3201
|
+
};
|
|
1753
3202
|
}
|
|
1754
3203
|
const root = el;
|
|
1755
|
-
let
|
|
1756
|
-
const typeOf = () =>
|
|
3204
|
+
let current2 = normalizeChartSpec(raw);
|
|
3205
|
+
const typeOf = () => current2.type ?? "vbar";
|
|
1757
3206
|
const legendState = { hidden: null };
|
|
3207
|
+
let zoomWindow = null;
|
|
3208
|
+
const warnedMarks = /* @__PURE__ */ new Set();
|
|
3209
|
+
let warnedAppend = false;
|
|
3210
|
+
let zoomDragCleanup = null;
|
|
3211
|
+
const fullLength = () => {
|
|
3212
|
+
if (current2.type === "scatter") return current2.points?.length ?? 0;
|
|
3213
|
+
if (current2.series && current2.series.length > 0) {
|
|
3214
|
+
return Math.max(current2.labels?.length ?? 0, ...current2.series.map((s) => s.values.length));
|
|
3215
|
+
}
|
|
3216
|
+
return Math.max(current2.labels?.length ?? 0, current2.values?.length ?? 0);
|
|
3217
|
+
};
|
|
3218
|
+
const viewOf = () => {
|
|
3219
|
+
if (!zoomWindow) return current2;
|
|
3220
|
+
const { from, to } = zoomWindow;
|
|
3221
|
+
return {
|
|
3222
|
+
...current2,
|
|
3223
|
+
labels: current2.labels?.slice(from, to + 1),
|
|
3224
|
+
values: current2.values?.slice(from, to + 1),
|
|
3225
|
+
series: current2.series?.map((s) => ({ ...s, values: s.values.slice(from, to + 1) })),
|
|
3226
|
+
points: current2.points?.slice(from, to + 1)
|
|
3227
|
+
};
|
|
3228
|
+
};
|
|
3229
|
+
const applyZoomSelection = (x0, x1) => {
|
|
3230
|
+
const len = fullLength();
|
|
3231
|
+
if (len < 2) return;
|
|
3232
|
+
const base = zoomWindow?.from ?? 0;
|
|
3233
|
+
const viewLen = zoomWindow ? zoomWindow.to - zoomWindow.from + 1 : len;
|
|
3234
|
+
const lo = Math.min(x0, x1);
|
|
3235
|
+
const hi = Math.max(x0, x1);
|
|
3236
|
+
let i0;
|
|
3237
|
+
let i1;
|
|
3238
|
+
const vbar = root.querySelector(".icen-chart-vbar");
|
|
3239
|
+
if (vbar) {
|
|
3240
|
+
const rect = vbar.getBoundingClientRect();
|
|
3241
|
+
const rel0 = rect.width > 0 ? Math.floor((lo - rect.left) / rect.width * viewLen) : 0;
|
|
3242
|
+
const rel1 = rect.width > 0 ? Math.max(rel0, Math.floor((hi - rect.left) / rect.width * viewLen)) : viewLen - 1;
|
|
3243
|
+
i0 = clampNum(rel0 + base, 0, len - 1);
|
|
3244
|
+
i1 = clampNum(rel1 + base, 0, len - 1);
|
|
3245
|
+
} else {
|
|
3246
|
+
const svg = root.querySelector(".icen-chart-line svg");
|
|
3247
|
+
if (!svg) return;
|
|
3248
|
+
const dims = svgDimsOf(svg);
|
|
3249
|
+
const p0 = svgClientPoint(svg, lo, 0, dims.w, dims.h);
|
|
3250
|
+
const p1 = svgClientPoint(svg, hi, 0, dims.w, dims.h);
|
|
3251
|
+
const rel0 = Math.round((p0.x - CHART_LINE_PAD) / (dims.w - CHART_LINE_PAD * 2) * (viewLen - 1));
|
|
3252
|
+
const rel1 = Math.round((p1.x - CHART_LINE_PAD) / (dims.w - CHART_LINE_PAD * 2) * (viewLen - 1));
|
|
3253
|
+
i0 = clampNum(rel0 + base, 0, len - 1);
|
|
3254
|
+
i1 = clampNum(rel1 + base, 0, len - 1);
|
|
3255
|
+
}
|
|
3256
|
+
if (i0 > i1) [i0, i1] = [i1, i0];
|
|
3257
|
+
if (i0 <= 0 && i1 >= len - 1) zoomWindow = null;
|
|
3258
|
+
else zoomWindow = { from: i0, to: Math.max(i1, i0) };
|
|
3259
|
+
render();
|
|
3260
|
+
emitIcen(root, "icen:chart-zoom", { chart: String(current2.type ?? ""), from: i0, to: Math.max(i1, i0) });
|
|
3261
|
+
};
|
|
3262
|
+
const bindZoomGesture = () => {
|
|
3263
|
+
if (current2.zoom !== "x" && current2.zoom !== "brush") return;
|
|
3264
|
+
const t2 = typeOf();
|
|
3265
|
+
if (!isZoomableType(t2) || fullLength() < 2) return;
|
|
3266
|
+
const plot = t2 === "vbar" ? root.querySelector(".icen-chart-vbar") : root.querySelector(".icen-chart-line svg");
|
|
3267
|
+
if (!plot) return;
|
|
3268
|
+
const on = (type, fn) => {
|
|
3269
|
+
plot.addEventListener(type, fn);
|
|
3270
|
+
};
|
|
3271
|
+
let drag = null;
|
|
3272
|
+
const onMove = (e) => {
|
|
3273
|
+
if (!drag) return;
|
|
3274
|
+
drag.x1 = e.clientX;
|
|
3275
|
+
drag.y1 = e.clientY;
|
|
3276
|
+
if (!drag.active && Math.hypot(drag.x1 - drag.x0, drag.y1 - drag.y0) >= CHART_ZOOM_DRAG_MIN_PX) {
|
|
3277
|
+
drag.active = true;
|
|
3278
|
+
const rect = document.createElement("div");
|
|
3279
|
+
rect.className = "icen-chart-zoom-rect";
|
|
3280
|
+
document.body.appendChild(rect);
|
|
3281
|
+
drag.rect = rect;
|
|
3282
|
+
}
|
|
3283
|
+
if (drag.active && drag.rect) {
|
|
3284
|
+
drag.rect.style.left = `${Math.round(Math.min(drag.x0, drag.x1))}px`;
|
|
3285
|
+
drag.rect.style.width = `${Math.round(Math.abs(drag.x1 - drag.x0))}px`;
|
|
3286
|
+
if (current2.zoom === "brush") {
|
|
3287
|
+
drag.rect.style.top = `${Math.round(Math.min(drag.y0, drag.y1))}px`;
|
|
3288
|
+
drag.rect.style.height = `${Math.round(Math.abs(drag.y1 - drag.y0))}px`;
|
|
3289
|
+
} else {
|
|
3290
|
+
const pr = plot.getBoundingClientRect();
|
|
3291
|
+
drag.rect.style.top = `${Math.round(pr.top)}px`;
|
|
3292
|
+
drag.rect.style.height = `${Math.round(pr.height)}px`;
|
|
3293
|
+
}
|
|
3294
|
+
}
|
|
3295
|
+
};
|
|
3296
|
+
const onUp = () => {
|
|
3297
|
+
window.removeEventListener("pointermove", onMove);
|
|
3298
|
+
window.removeEventListener("pointerup", onUp);
|
|
3299
|
+
window.removeEventListener("pointercancel", onUp);
|
|
3300
|
+
zoomDragCleanup = null;
|
|
3301
|
+
if (!drag) return;
|
|
3302
|
+
const d = drag;
|
|
3303
|
+
drag = null;
|
|
3304
|
+
d.rect?.remove();
|
|
3305
|
+
if (!d.active) return;
|
|
3306
|
+
applyZoomSelection(d.x0, d.x1);
|
|
3307
|
+
};
|
|
3308
|
+
const onDown = (e) => {
|
|
3309
|
+
if (e.button !== 0) return;
|
|
3310
|
+
drag = { x0: e.clientX, y0: e.clientY, x1: e.clientX, y1: e.clientY, active: false, rect: null };
|
|
3311
|
+
window.addEventListener("pointermove", onMove);
|
|
3312
|
+
window.addEventListener("pointerup", onUp);
|
|
3313
|
+
window.addEventListener("pointercancel", onUp);
|
|
3314
|
+
zoomDragCleanup = onUp;
|
|
3315
|
+
};
|
|
3316
|
+
on("pointerdown", onDown);
|
|
3317
|
+
on("dblclick", () => {
|
|
3318
|
+
if (!zoomWindow) return;
|
|
3319
|
+
zoomWindow = null;
|
|
3320
|
+
render();
|
|
3321
|
+
});
|
|
3322
|
+
};
|
|
1758
3323
|
const render = () => {
|
|
1759
|
-
if (!
|
|
1760
|
-
const spec =
|
|
3324
|
+
if (!current2.type) current2 = { ...current2, type: inferChartType(current2) };
|
|
3325
|
+
const spec = current2;
|
|
3326
|
+
const type = spec.type;
|
|
1761
3327
|
const formatValue = chartFormatValue(spec.format);
|
|
1762
3328
|
if (spec.legend !== void 0) legendState.hidden = spec.legend === false;
|
|
3329
|
+
const loading = spec.loading === true;
|
|
3330
|
+
root.classList.toggle("is-loading", loading);
|
|
3331
|
+
let view = viewOf();
|
|
3332
|
+
let note = null;
|
|
3333
|
+
if (!loading && isDownsampleableType(type)) {
|
|
3334
|
+
const r = downsampleView(view, type);
|
|
3335
|
+
view = r.view;
|
|
3336
|
+
note = r.note;
|
|
3337
|
+
}
|
|
3338
|
+
const zoomReset = zoomWindow && (spec.zoom === "x" || spec.zoom === "brush") ? () => {
|
|
3339
|
+
zoomWindow = null;
|
|
3340
|
+
render();
|
|
3341
|
+
} : null;
|
|
1763
3342
|
withChrome(root, spec, hasLegendOf(spec), (body) => {
|
|
1764
|
-
|
|
3343
|
+
if (loading) {
|
|
3344
|
+
renderChartSkeleton(body);
|
|
3345
|
+
return;
|
|
3346
|
+
}
|
|
3347
|
+
switch (type) {
|
|
1765
3348
|
case "line":
|
|
1766
|
-
renderLine(body, { labels:
|
|
3349
|
+
renderLine(body, { labels: view.labels ?? [], values: view.values ?? [], series: view.series, tone: view.tone, fill: view.fill, formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1767
3350
|
break;
|
|
1768
3351
|
case "area":
|
|
1769
|
-
renderLine(body, { labels:
|
|
3352
|
+
renderLine(body, { labels: view.labels ?? [], values: view.values ?? [], series: view.series, tone: view.tone, fill: true, formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1770
3353
|
break;
|
|
1771
3354
|
case "vbar":
|
|
1772
|
-
renderVBar(body, { labels:
|
|
3355
|
+
renderVBar(body, { labels: view.labels ?? [], values: view.values ?? [], series: view.series, stacked: view.stacked, tone: view.tone, formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1773
3356
|
break;
|
|
1774
3357
|
case "hbar":
|
|
1775
|
-
renderHBar(body, { labels:
|
|
3358
|
+
renderHBar(body, { labels: view.labels ?? [], values: view.values ?? [], tone: view.tone, formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1776
3359
|
break;
|
|
1777
3360
|
case "stack":
|
|
1778
|
-
renderStack(body, { segments:
|
|
3361
|
+
renderStack(body, { segments: view.segments ?? [], formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1779
3362
|
break;
|
|
1780
3363
|
case "donut":
|
|
1781
|
-
renderDonut(body, { segments:
|
|
3364
|
+
renderDonut(body, { segments: view.segments ?? [], formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1782
3365
|
break;
|
|
1783
3366
|
case "radar": {
|
|
1784
|
-
const series =
|
|
1785
|
-
renderRadar(body, { axes:
|
|
3367
|
+
const series = view.series ? view.series.map((s) => ({ name: s.name, values: s.values, tone: typeof s.tone === "string" ? s.tone : void 0 })) : view.values ? [{ name: "", values: view.values }] : [];
|
|
3368
|
+
renderRadar(body, { axes: view.axes ?? view.labels ?? [], series, max: view.max, levels: view.levels, formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1786
3369
|
break;
|
|
1787
3370
|
}
|
|
1788
3371
|
case "heatmap":
|
|
1789
|
-
renderHeatmap(body, { values:
|
|
3372
|
+
renderHeatmap(body, { values: view.values, data: view.data, weeks: view.weeks, tone: view.tone, formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend, weekStart: view.i18n?.weekStart, labels: view.i18n });
|
|
1790
3373
|
break;
|
|
1791
3374
|
case "calendar":
|
|
1792
|
-
renderCalendar(body, { dates:
|
|
3375
|
+
renderCalendar(body, { dates: view.dates, values: view.values, data: view.data, tone: view.tone, formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend, weekStart: view.i18n?.weekStart, labels: view.i18n });
|
|
1793
3376
|
break;
|
|
1794
3377
|
case "sparkline":
|
|
1795
|
-
renderSparkline(body, { labels:
|
|
3378
|
+
renderSparkline(body, { labels: view.labels ?? [], values: view.values ?? [], tone: view.tone, formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1796
3379
|
break;
|
|
1797
3380
|
case "gauge":
|
|
1798
|
-
renderGauge(body, { value:
|
|
3381
|
+
renderGauge(body, { value: view.values?.[0] ?? 0, max: view.max, tone: view.tone, label: view.labels?.[0], formatValue });
|
|
1799
3382
|
break;
|
|
1800
3383
|
case "scatter":
|
|
1801
|
-
renderScatter(body, { points:
|
|
3384
|
+
renderScatter(body, { points: view.points ?? [], tone: view.tone, formatValue, emptyLabel: view.emptyLabel, title: view.title, legend: view.legend });
|
|
1802
3385
|
break;
|
|
1803
3386
|
default:
|
|
1804
|
-
renderEmpty(body,
|
|
3387
|
+
renderEmpty(body, view.emptyLabel);
|
|
1805
3388
|
}
|
|
1806
|
-
});
|
|
3389
|
+
}, legendState, { note, onZoomReset: zoomReset });
|
|
3390
|
+
if (!loading) {
|
|
3391
|
+
const graphic = root.querySelector('[role="img"]');
|
|
3392
|
+
if (graphic && !graphic.getAttribute("aria-label")) {
|
|
3393
|
+
graphic.setAttribute("aria-label", spec.title ? `${spec.title}\uFF08${type}\uFF09` : type);
|
|
3394
|
+
} else if (!graphic) {
|
|
3395
|
+
const dom = root.querySelector(".icen-chart-vbar, .icen-chart-hbar");
|
|
3396
|
+
if (dom) {
|
|
3397
|
+
dom.setAttribute("role", "img");
|
|
3398
|
+
dom.setAttribute("aria-label", spec.title ? `${spec.title}\uFF08${type}\uFF09` : type);
|
|
3399
|
+
}
|
|
3400
|
+
}
|
|
3401
|
+
}
|
|
3402
|
+
if (loading) return;
|
|
3403
|
+
paintChartMarks(root, view, spec, formatValue, warnedMarks);
|
|
3404
|
+
bindZoomGesture();
|
|
1807
3405
|
};
|
|
1808
|
-
chartDelegateMeta.set(root, { type: typeOf, tooltip: () =>
|
|
3406
|
+
chartDelegateMeta.set(root, { type: typeOf, tooltip: () => current2.tooltip !== false });
|
|
1809
3407
|
const unbindEvents = bindChartEvents(root);
|
|
1810
3408
|
render();
|
|
3409
|
+
observeFluidWidth(root, render);
|
|
1811
3410
|
return {
|
|
1812
3411
|
el: root,
|
|
1813
|
-
|
|
3412
|
+
/** 归一 + 推断后的当前规格(getter:update/append 换引用后永远读到最新) */
|
|
3413
|
+
get spec() {
|
|
3414
|
+
return current2;
|
|
3415
|
+
},
|
|
1814
3416
|
update(next) {
|
|
1815
|
-
|
|
3417
|
+
const prev = current2;
|
|
3418
|
+
current2 = normalizeChartSpec(next);
|
|
3419
|
+
if (zoomWindow) {
|
|
3420
|
+
const sameLabels = JSON.stringify(prev.labels ?? null) === JSON.stringify(current2.labels ?? null);
|
|
3421
|
+
const t2 = current2.type ?? inferChartType(current2);
|
|
3422
|
+
const zoomable = isZoomableType(t2) && (current2.zoom === "x" || current2.zoom === "brush");
|
|
3423
|
+
if (!sameLabels || !zoomable) zoomWindow = null;
|
|
3424
|
+
else {
|
|
3425
|
+
const len = fullLength();
|
|
3426
|
+
if (len < 2) zoomWindow = null;
|
|
3427
|
+
else {
|
|
3428
|
+
const from = clampNum(zoomWindow.from, 0, len - 1);
|
|
3429
|
+
const to = clampNum(zoomWindow.to, 0, len - 1);
|
|
3430
|
+
zoomWindow = from <= to ? { from, to } : null;
|
|
3431
|
+
}
|
|
3432
|
+
}
|
|
3433
|
+
}
|
|
3434
|
+
render();
|
|
3435
|
+
},
|
|
3436
|
+
append(label, values, opts) {
|
|
3437
|
+
const t2 = current2.type ?? inferChartType(current2);
|
|
3438
|
+
if (!isStreamableType(t2)) {
|
|
3439
|
+
if (!warnedAppend) {
|
|
3440
|
+
warnedAppend = true;
|
|
3441
|
+
console.warn(`[icen:chart] append \u4EC5\u652F\u6301 line/area/vbar\uFF08\u5F53\u524D ${String(current2.type ?? t2)}\uFF09\uFF0C\u5DF2\u5FFD\u7565`);
|
|
3442
|
+
}
|
|
3443
|
+
return;
|
|
3444
|
+
}
|
|
3445
|
+
const labels = current2.labels ?? (current2.labels = []);
|
|
3446
|
+
labels.push(String(label ?? ""));
|
|
3447
|
+
const vals = Array.isArray(values) ? values : [];
|
|
3448
|
+
if (current2.series && current2.series.length > 0) {
|
|
3449
|
+
for (const [i, s] of current2.series.entries()) s.values.push(toNum(vals[i]) ?? 0);
|
|
3450
|
+
} else {
|
|
3451
|
+
const v = current2.values ?? (current2.values = []);
|
|
3452
|
+
v.push(toNum(vals[0]) ?? 0);
|
|
3453
|
+
}
|
|
3454
|
+
const maxPoints = opts?.maxPoints != null ? Math.max(1, Math.floor(toNum(opts.maxPoints) ?? 0)) : 0;
|
|
3455
|
+
let dropped = 0;
|
|
3456
|
+
if (maxPoints > 0) {
|
|
3457
|
+
while (labels.length > maxPoints) {
|
|
3458
|
+
labels.shift();
|
|
3459
|
+
if (current2.series) for (const s of current2.series) s.values.shift();
|
|
3460
|
+
else current2.values?.shift();
|
|
3461
|
+
dropped += 1;
|
|
3462
|
+
}
|
|
3463
|
+
}
|
|
3464
|
+
if (zoomWindow) {
|
|
3465
|
+
const len = Math.max(1, labels.length);
|
|
3466
|
+
const size = zoomWindow.to - zoomWindow.from + 1;
|
|
3467
|
+
const to = clampNum(zoomWindow.to - dropped + 1, 0, len - 1);
|
|
3468
|
+
zoomWindow = { from: Math.max(0, to - size + 1), to };
|
|
3469
|
+
}
|
|
1816
3470
|
render();
|
|
1817
3471
|
},
|
|
1818
3472
|
on(name, listener) {
|
|
@@ -1822,13 +3476,29 @@ function renderChart(el, raw) {
|
|
|
1822
3476
|
root.addEventListener(`icen:chart-${name}`, handler);
|
|
1823
3477
|
return () => root.removeEventListener(`icen:chart-${name}`, handler);
|
|
1824
3478
|
},
|
|
3479
|
+
toDataURL: createChartToDataURL(root),
|
|
1825
3480
|
destroy() {
|
|
3481
|
+
releaseFluidWidth(root);
|
|
3482
|
+
hiddenLegendKeys.delete(root);
|
|
3483
|
+
zoomDragCleanup?.();
|
|
1826
3484
|
root.textContent = "";
|
|
3485
|
+
root.classList.remove("is-loading");
|
|
1827
3486
|
unbindEvents();
|
|
1828
3487
|
chartTooltip().hidden = true;
|
|
1829
3488
|
}
|
|
1830
3489
|
};
|
|
1831
3490
|
}
|
|
3491
|
+
function svgClientPoint(svg, clientX, clientY, viewBoxWidth, viewBoxHeight) {
|
|
3492
|
+
const rect = svg.getBoundingClientRect();
|
|
3493
|
+
const scale = Math.min(rect.width / viewBoxWidth, rect.height / viewBoxHeight);
|
|
3494
|
+
if (!Number.isFinite(scale) || scale <= 0) {
|
|
3495
|
+
return { x: viewBoxWidth / 2, y: viewBoxHeight / 2 };
|
|
3496
|
+
}
|
|
3497
|
+
return {
|
|
3498
|
+
x: (clientX - rect.left - (rect.width - viewBoxWidth * scale) / 2) / scale,
|
|
3499
|
+
y: (clientY - rect.top - (rect.height - viewBoxHeight * scale) / 2) / scale
|
|
3500
|
+
};
|
|
3501
|
+
}
|
|
1832
3502
|
var GRAPH_W = 360;
|
|
1833
3503
|
var GRAPH_H = 260;
|
|
1834
3504
|
var GRAPH_PAD = 28;
|
|
@@ -1877,23 +3547,23 @@ function buildHead(headClass) {
|
|
|
1877
3547
|
const head = h("button", headClass);
|
|
1878
3548
|
head.type = "button";
|
|
1879
3549
|
head.setAttribute("aria-expanded", "false");
|
|
1880
|
-
const iconEl = h("span", "ai-item-icon");
|
|
3550
|
+
const iconEl = h("span", "icen-ai-item-icon");
|
|
1881
3551
|
iconEl.setAttribute("aria-hidden", "true");
|
|
1882
|
-
const main = h("span", "ai-item-main");
|
|
1883
|
-
const titleEl = h("span", "ai-item-title");
|
|
1884
|
-
const subEl = h("span", "ai-item-sub");
|
|
1885
|
-
const statusEl = h("span", "ai-item-status");
|
|
3552
|
+
const main = h("span", "icen-ai-item-main");
|
|
3553
|
+
const titleEl = h("span", "icen-ai-item-title");
|
|
3554
|
+
const subEl = h("span", "icen-ai-item-sub");
|
|
3555
|
+
const statusEl = h("span", "icen-ai-item-status");
|
|
1886
3556
|
statusEl.setAttribute("role", "img");
|
|
1887
|
-
const metaEl = h("span", "ai-item-meta");
|
|
3557
|
+
const metaEl = h("span", "icen-ai-item-meta");
|
|
1888
3558
|
main.append(titleEl, subEl);
|
|
1889
3559
|
head.append(iconEl, main, statusEl, metaEl);
|
|
1890
3560
|
return { head, iconEl, titleEl, subEl, statusEl, metaEl };
|
|
1891
3561
|
}
|
|
1892
3562
|
function buildIo(label) {
|
|
1893
|
-
const root = h("div", "ai-tool-io");
|
|
1894
|
-
root.append(h("div", "ai-tool-io-label", label));
|
|
1895
|
-
const pre = h("pre", "ai-tool-io-content");
|
|
1896
|
-
const media = h("div", "ai-tool-io-media");
|
|
3563
|
+
const root = h("div", "icen-ai-tool-io");
|
|
3564
|
+
root.append(h("div", "icen-ai-tool-io-label", label));
|
|
3565
|
+
const pre = h("pre", "icen-ai-tool-io-content");
|
|
3566
|
+
const media = h("div", "icen-ai-tool-io-media");
|
|
1897
3567
|
media.hidden = true;
|
|
1898
3568
|
root.append(pre, media);
|
|
1899
3569
|
return { root, pre, media };
|
|
@@ -1902,9 +3572,9 @@ function chartSpecOf(value) {
|
|
|
1902
3572
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
1903
3573
|
const v = value;
|
|
1904
3574
|
if (v.type === "chart" && v.spec && typeof v.spec === "object") return v.spec;
|
|
1905
|
-
const
|
|
3575
|
+
const t2 = typeof v.type === "string" ? v.type : void 0;
|
|
1906
3576
|
const looksChart = Array.isArray(v.series) || Array.isArray(v.segments) || Array.isArray(v.points) || Array.isArray(v.dates) || Array.isArray(v.labels) && Array.isArray(v.values);
|
|
1907
|
-
if (looksChart && (
|
|
3577
|
+
if (looksChart && (t2 === void 0 || typeof t2 === "string")) return v;
|
|
1908
3578
|
return null;
|
|
1909
3579
|
}
|
|
1910
3580
|
function setIo(io, value, allowChart = true) {
|
|
@@ -1914,7 +3584,7 @@ function setIo(io, value, allowChart = true) {
|
|
|
1914
3584
|
io.pre.hidden = true;
|
|
1915
3585
|
io.media.replaceChildren();
|
|
1916
3586
|
const holder = document.createElement("div");
|
|
1917
|
-
holder.className = "ai-tool-io-chart";
|
|
3587
|
+
holder.className = "icen-ai-tool-io-chart";
|
|
1918
3588
|
io.media.appendChild(holder);
|
|
1919
3589
|
renderChart(holder, chartSpec);
|
|
1920
3590
|
io.media.hidden = false;
|
|
@@ -1950,29 +3620,33 @@ function defaultExpanded(m) {
|
|
|
1950
3620
|
return false;
|
|
1951
3621
|
}
|
|
1952
3622
|
function buildApproval() {
|
|
1953
|
-
const root = h("div", "ai-tool-approval");
|
|
1954
|
-
const reason = h("div", "ai-tool-approval-reason");
|
|
3623
|
+
const root = h("div", "icen-ai-tool-approval");
|
|
3624
|
+
const reason = h("div", "icen-ai-tool-approval-reason");
|
|
1955
3625
|
reason.hidden = true;
|
|
1956
|
-
const allow = h("button", "btn btn-sm btn-primary", "
|
|
3626
|
+
const allow = h("button", "icen-btn icen-btn-sm icen-btn-primary", t("aiTool.allow"));
|
|
1957
3627
|
allow.type = "button";
|
|
1958
|
-
allow.setAttribute("data-ai-approve", "");
|
|
1959
|
-
const deny = h("button", "btn btn-sm", "
|
|
3628
|
+
allow.setAttribute("data-icen-ai-approve", "");
|
|
3629
|
+
const deny = h("button", "icen-btn icen-btn-sm", t("aiTool.reject"));
|
|
1960
3630
|
deny.type = "button";
|
|
1961
|
-
deny.setAttribute("data-ai-reject", "");
|
|
3631
|
+
deny.setAttribute("data-icen-ai-reject", "");
|
|
1962
3632
|
root.append(reason, allow, deny);
|
|
1963
3633
|
return { root, reason };
|
|
1964
3634
|
}
|
|
1965
3635
|
function applyTint(item, model) {
|
|
1966
3636
|
const tint = getAiKind(model.kind).tint;
|
|
1967
|
-
if (tint)
|
|
1968
|
-
|
|
3637
|
+
if (tint) {
|
|
3638
|
+
const slot = tint === "muted" ? "text-muted" : tint;
|
|
3639
|
+
item.style.setProperty("--ai-item-tint", `var(--icen-token-${slot})`);
|
|
3640
|
+
} else {
|
|
3641
|
+
item.style.removeProperty("--ai-item-tint");
|
|
3642
|
+
}
|
|
1969
3643
|
}
|
|
1970
3644
|
function applyKindVisual(parts, model) {
|
|
1971
3645
|
const kind = getAiKind(model.kind);
|
|
1972
3646
|
parts.titleEl.textContent = kind.label || model.name;
|
|
1973
3647
|
parts.iconEl.replaceChildren();
|
|
1974
|
-
const
|
|
1975
|
-
if (
|
|
3648
|
+
const svg = svgIcon(kind.icon);
|
|
3649
|
+
if (svg) parts.iconEl.append(svg);
|
|
1976
3650
|
const sub = summarizeInput(model);
|
|
1977
3651
|
parts.subEl.textContent = sub;
|
|
1978
3652
|
parts.subEl.hidden = !sub;
|
|
@@ -1987,15 +3661,15 @@ function renderAiToolCall(el, model) {
|
|
|
1987
3661
|
return { el, update: () => void 0 };
|
|
1988
3662
|
}
|
|
1989
3663
|
const item = el;
|
|
1990
|
-
let
|
|
1991
|
-
item.className = `ai-tool ai-tool--${model.kind}`;
|
|
1992
|
-
item.dataset.
|
|
1993
|
-
item.dataset.
|
|
1994
|
-
const parts = buildHead("ai-tool-head");
|
|
1995
|
-
const body = h("div", "ai-tool-body");
|
|
3664
|
+
let current2 = model;
|
|
3665
|
+
item.className = `icen-ai-tool icen-ai-tool--${model.kind}`;
|
|
3666
|
+
item.dataset.icenAiId = model.id;
|
|
3667
|
+
item.dataset.icenAiKind = model.kind;
|
|
3668
|
+
const parts = buildHead("icen-ai-tool-head");
|
|
3669
|
+
const body = h("div", "icen-ai-tool-body");
|
|
1996
3670
|
body.hidden = true;
|
|
1997
|
-
const inputIo = buildIo("
|
|
1998
|
-
const outputIo = buildIo("
|
|
3671
|
+
const inputIo = buildIo(t("common.input"));
|
|
3672
|
+
const outputIo = buildIo(t("common.output"));
|
|
1999
3673
|
const approval = buildApproval();
|
|
2000
3674
|
body.append(inputIo.root, outputIo.root, approval.root);
|
|
2001
3675
|
item.append(parts.head, body);
|
|
@@ -2019,12 +3693,12 @@ function renderAiToolCall(el, model) {
|
|
|
2019
3693
|
approval.reason.hidden = !reason;
|
|
2020
3694
|
if (!item.dataset.aiUserToggled && defaultExpanded(m)) setOpen(true);
|
|
2021
3695
|
};
|
|
2022
|
-
apply(
|
|
3696
|
+
apply(current2);
|
|
2023
3697
|
return {
|
|
2024
3698
|
el: item,
|
|
2025
3699
|
update(patch) {
|
|
2026
|
-
|
|
2027
|
-
apply(
|
|
3700
|
+
current2 = { ...current2, ...patch };
|
|
3701
|
+
apply(current2);
|
|
2028
3702
|
}
|
|
2029
3703
|
};
|
|
2030
3704
|
}
|
|
@@ -2033,15 +3707,15 @@ function renderAiSubagent(el, model) {
|
|
|
2033
3707
|
return { el, update: () => void 0 };
|
|
2034
3708
|
}
|
|
2035
3709
|
const item = el;
|
|
2036
|
-
let
|
|
2037
|
-
item.className = "ai-subagent";
|
|
2038
|
-
item.dataset.
|
|
2039
|
-
item.dataset.
|
|
2040
|
-
const parts = buildHead("ai-subagent-head");
|
|
2041
|
-
const body = h("div", "ai-subagent-body");
|
|
3710
|
+
let current2 = model;
|
|
3711
|
+
item.className = "icen-ai-subagent";
|
|
3712
|
+
item.dataset.icenAiId = model.id;
|
|
3713
|
+
item.dataset.icenAiKind = model.kind;
|
|
3714
|
+
const parts = buildHead("icen-ai-subagent-head");
|
|
3715
|
+
const body = h("div", "icen-ai-subagent-body");
|
|
2042
3716
|
body.hidden = true;
|
|
2043
|
-
const stream = h("div", "ai-subagent-stream");
|
|
2044
|
-
const result = h("div", "ai-subagent-result");
|
|
3717
|
+
const stream = h("div", "icen-ai-subagent-stream");
|
|
3718
|
+
const result = h("div", "icen-ai-subagent-result");
|
|
2045
3719
|
result.hidden = true;
|
|
2046
3720
|
body.append(stream, result);
|
|
2047
3721
|
item.append(parts.head, body);
|
|
@@ -2081,7 +3755,7 @@ function renderAiSubagent(el, model) {
|
|
|
2081
3755
|
applyTint(item, m);
|
|
2082
3756
|
applyKindVisual(parts, m);
|
|
2083
3757
|
const steps = m.activities?.length ?? 0;
|
|
2084
|
-
const meta = [m.durationMs != null ? formatDuration(m.durationMs) : "", steps > 0 ?
|
|
3758
|
+
const meta = [m.durationMs != null ? formatDuration(m.durationMs) : "", steps > 0 ? t("common.steps", { p0: steps }) : ""].filter(Boolean).join(" \xB7 ");
|
|
2085
3759
|
applyStatusMeta(parts, m.status, meta);
|
|
2086
3760
|
renderActivities(m.activities);
|
|
2087
3761
|
const receipt = compactValue(m.output);
|
|
@@ -2089,12 +3763,12 @@ function renderAiSubagent(el, model) {
|
|
|
2089
3763
|
result.hidden = !receipt;
|
|
2090
3764
|
if (!item.dataset.aiUserToggled && defaultExpanded(m)) setOpen(true);
|
|
2091
3765
|
};
|
|
2092
|
-
apply(
|
|
3766
|
+
apply(current2);
|
|
2093
3767
|
return {
|
|
2094
3768
|
el: item,
|
|
2095
3769
|
update(patch) {
|
|
2096
|
-
|
|
2097
|
-
apply(
|
|
3770
|
+
current2 = { ...current2, ...patch };
|
|
3771
|
+
apply(current2);
|
|
2098
3772
|
}
|
|
2099
3773
|
};
|
|
2100
3774
|
}
|
|
@@ -2103,8 +3777,8 @@ function setupItem(item, kind) {
|
|
|
2103
3777
|
const flag = kind === "tool" ? "__icenAiToolInit" : "__icenAiSubagentInit";
|
|
2104
3778
|
if (marked[flag]) return () => void 0;
|
|
2105
3779
|
marked[flag] = true;
|
|
2106
|
-
const headClass = kind === "tool" ? ".ai-tool-head" : ".ai-subagent-head";
|
|
2107
|
-
const bodyClass = kind === "tool" ? ".ai-tool-body" : ".ai-subagent-body";
|
|
3780
|
+
const headClass = kind === "tool" ? ".icen-ai-tool-head" : ".icen-ai-subagent-head";
|
|
3781
|
+
const bodyClass = kind === "tool" ? ".icen-ai-tool-body" : ".icen-ai-subagent-body";
|
|
2108
3782
|
const head = item.querySelector(`:scope > ${headClass}`);
|
|
2109
3783
|
const body = item.querySelector(`:scope > ${bodyClass}`);
|
|
2110
3784
|
const setOpen = (open, fire = true) => {
|
|
@@ -2117,25 +3791,25 @@ function setupItem(item, kind) {
|
|
|
2117
3791
|
const onCardClick = (ev) => {
|
|
2118
3792
|
const target = ev.target;
|
|
2119
3793
|
if (!(target instanceof Element)) return;
|
|
2120
|
-
const ownerOf = (node) => node.closest(".ai-tool, .ai-subagent");
|
|
2121
|
-
const approveBtn = target.closest("[data-ai-approve]");
|
|
3794
|
+
const ownerOf = (node) => node.closest(".icen-ai-tool, .icen-ai-subagent");
|
|
3795
|
+
const approveBtn = target.closest("[data-icen-ai-approve]");
|
|
2122
3796
|
if (approveBtn && ownerOf(approveBtn) === item) {
|
|
2123
|
-
emitIcen(item, "icen:ai-approve", { id: item.dataset.
|
|
3797
|
+
emitIcen(item, "icen:ai-approve", { id: item.dataset.icenAiId ?? "", kind: item.dataset.icenAiKind ?? "" });
|
|
2124
3798
|
return;
|
|
2125
3799
|
}
|
|
2126
|
-
const rejectBtn = target.closest("[data-ai-reject]");
|
|
3800
|
+
const rejectBtn = target.closest("[data-icen-ai-reject]");
|
|
2127
3801
|
if (rejectBtn && ownerOf(rejectBtn) === item) {
|
|
2128
|
-
emitIcen(item, "icen:ai-reject", { id: item.dataset.
|
|
3802
|
+
emitIcen(item, "icen:ai-reject", { id: item.dataset.icenAiId ?? "", kind: item.dataset.icenAiKind ?? "" });
|
|
2129
3803
|
return;
|
|
2130
3804
|
}
|
|
2131
|
-
const headEl = target.closest(".ai-tool-head, .ai-subagent-head");
|
|
3805
|
+
const headEl = target.closest(".icen-ai-tool-head, .icen-ai-subagent-head");
|
|
2132
3806
|
if (!headEl || ownerOf(headEl) !== item || !head) return;
|
|
2133
3807
|
item.dataset.aiUserToggled = "1";
|
|
2134
3808
|
setOpen(head.getAttribute("aria-expanded") !== "true");
|
|
2135
3809
|
};
|
|
2136
3810
|
item.addEventListener("click", onCardClick);
|
|
2137
3811
|
if (body?.hidden) {
|
|
2138
|
-
const kindName = item.dataset.
|
|
3812
|
+
const kindName = item.dataset.icenAiKind ?? "";
|
|
2139
3813
|
const isErr = item.classList.contains("is-error");
|
|
2140
3814
|
const isApproval = item.classList.contains("is-approval");
|
|
2141
3815
|
if (isErr || isApproval || kindName === "chart") {
|
|
@@ -2157,14 +3831,14 @@ function initItems(root, selector, kind) {
|
|
|
2157
3831
|
return items.map((item) => setupItem(item, kind));
|
|
2158
3832
|
}
|
|
2159
3833
|
function initAiTool(root) {
|
|
2160
|
-
const cleanups = initItems(root, ".ai-tool", "tool");
|
|
3834
|
+
const cleanups = initItems(root, ".icen-ai-tool", "tool");
|
|
2161
3835
|
return () => {
|
|
2162
3836
|
for (const fn of cleanups) fn();
|
|
2163
3837
|
cleanups.length = 0;
|
|
2164
3838
|
};
|
|
2165
3839
|
}
|
|
2166
3840
|
function initAiSubagent(root) {
|
|
2167
|
-
const cleanups = initItems(root, ".ai-subagent", "subagent");
|
|
3841
|
+
const cleanups = initItems(root, ".icen-ai-subagent", "subagent");
|
|
2168
3842
|
return () => {
|
|
2169
3843
|
for (const fn of cleanups) fn();
|
|
2170
3844
|
cleanups.length = 0;
|