@kanzo-tech/ui 0.0.1-alpha
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/README.md +60 -0
- package/dist/analytics.d.ts +36 -0
- package/dist/analytics.d.ts.map +1 -0
- package/dist/analytics.js +155 -0
- package/dist/analytics.js.map +1 -0
- package/dist/charts/arrow.d.ts +37 -0
- package/dist/charts/arrow.d.ts.map +1 -0
- package/dist/charts/arrow.js +29 -0
- package/dist/charts/arrow.js.map +1 -0
- package/dist/charts/chart-axes.d.ts +59 -0
- package/dist/charts/chart-axes.d.ts.map +1 -0
- package/dist/charts/chart-axes.js +39 -0
- package/dist/charts/chart-axes.js.map +1 -0
- package/dist/charts/chart-config.d.ts +52 -0
- package/dist/charts/chart-config.d.ts.map +1 -0
- package/dist/charts/chart-config.js +43 -0
- package/dist/charts/chart-config.js.map +1 -0
- package/dist/charts/chart-inputs.d.ts +174 -0
- package/dist/charts/chart-inputs.d.ts.map +1 -0
- package/dist/charts/chart-inputs.js +382 -0
- package/dist/charts/chart-inputs.js.map +1 -0
- package/dist/charts/chart-interactors.d.ts +75 -0
- package/dist/charts/chart-interactors.d.ts.map +1 -0
- package/dist/charts/chart-interactors.js +35 -0
- package/dist/charts/chart-interactors.js.map +1 -0
- package/dist/charts/chart-legend.d.ts +38 -0
- package/dist/charts/chart-legend.d.ts.map +1 -0
- package/dist/charts/chart-legend.js +49 -0
- package/dist/charts/chart-legend.js.map +1 -0
- package/dist/charts/chart-marks.d.ts +124 -0
- package/dist/charts/chart-marks.d.ts.map +1 -0
- package/dist/charts/chart-marks.js +109 -0
- package/dist/charts/chart-marks.js.map +1 -0
- package/dist/charts/chart-root.d.ts +90 -0
- package/dist/charts/chart-root.d.ts.map +1 -0
- package/dist/charts/chart-root.js +162 -0
- package/dist/charts/chart-root.js.map +1 -0
- package/dist/charts/chart-spec.d.ts +126 -0
- package/dist/charts/chart-spec.d.ts.map +1 -0
- package/dist/charts/chart-spec.js +133 -0
- package/dist/charts/chart-spec.js.map +1 -0
- package/dist/charts/chart-stat.d.ts +23 -0
- package/dist/charts/chart-stat.d.ts.map +1 -0
- package/dist/charts/chart-stat.js +24 -0
- package/dist/charts/chart-stat.js.map +1 -0
- package/dist/charts/id-set-client.d.ts +42 -0
- package/dist/charts/id-set-client.d.ts.map +1 -0
- package/dist/charts/id-set-client.js +43 -0
- package/dist/charts/id-set-client.js.map +1 -0
- package/dist/charts/mosaic-provider.d.ts +70 -0
- package/dist/charts/mosaic-provider.d.ts.map +1 -0
- package/dist/charts/mosaic-provider.js +53 -0
- package/dist/charts/mosaic-provider.js.map +1 -0
- package/dist/charts/query-client.d.ts +22 -0
- package/dist/charts/query-client.d.ts.map +1 -0
- package/dist/charts/query-client.js +26 -0
- package/dist/charts/query-client.js.map +1 -0
- package/dist/charts/tokenized-plot.d.ts +26 -0
- package/dist/charts/tokenized-plot.d.ts.map +1 -0
- package/dist/charts/tokenized-plot.js +41 -0
- package/dist/charts/tokenized-plot.js.map +1 -0
- package/dist/charts/use-chart-query.d.ts +30 -0
- package/dist/charts/use-chart-query.d.ts.map +1 -0
- package/dist/charts/use-chart-query.js +19 -0
- package/dist/charts/use-chart-query.js.map +1 -0
- package/dist/composites/CodeEditor.d.ts +64 -0
- package/dist/composites/CodeEditor.d.ts.map +1 -0
- package/dist/composites/CodeEditor.js +521 -0
- package/dist/composites/CodeEditor.js.map +1 -0
- package/dist/composites/MadeWith.d.ts +39 -0
- package/dist/composites/MadeWith.d.ts.map +1 -0
- package/dist/composites/MadeWith.js +30 -0
- package/dist/composites/MadeWith.js.map +1 -0
- package/dist/composites/Preferences.d.ts +155 -0
- package/dist/composites/Preferences.d.ts.map +1 -0
- package/dist/composites/Preferences.js +501 -0
- package/dist/composites/Preferences.js.map +1 -0
- package/dist/composites/Questionnaire.d.ts +215 -0
- package/dist/composites/Questionnaire.d.ts.map +1 -0
- package/dist/composites/Questionnaire.js +422 -0
- package/dist/composites/Questionnaire.js.map +1 -0
- package/dist/composites/SidebarIdentity.d.ts +63 -0
- package/dist/composites/SidebarIdentity.d.ts.map +1 -0
- package/dist/composites/SidebarIdentity.js +103 -0
- package/dist/composites/SidebarIdentity.js.map +1 -0
- package/dist/composites/code-editor-search.d.ts +40 -0
- package/dist/composites/code-editor-search.d.ts.map +1 -0
- package/dist/composites/code-editor-search.js +212 -0
- package/dist/composites/code-editor-search.js.map +1 -0
- package/dist/composites/sidebar.d.ts +129 -0
- package/dist/composites/sidebar.d.ts.map +1 -0
- package/dist/composites/sidebar.js +671 -0
- package/dist/composites/sidebar.js.map +1 -0
- package/dist/composites/theme-notice.d.ts +54 -0
- package/dist/composites/theme-notice.d.ts.map +1 -0
- package/dist/composites/theme-notice.js +19 -0
- package/dist/composites/theme-notice.js.map +1 -0
- package/dist/editor.d.ts +3 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/editor.js +6 -0
- package/dist/editor.js.map +1 -0
- package/dist/guard-corpus.d.ts +63 -0
- package/dist/guard-corpus.d.ts.map +1 -0
- package/dist/index.d.ts +112 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +696 -0
- package/dist/index.js.map +1 -0
- package/dist/layouts/section.d.ts +166 -0
- package/dist/layouts/section.d.ts.map +1 -0
- package/dist/layouts/section.js +153 -0
- package/dist/layouts/section.js.map +1 -0
- package/dist/layouts/shell.d.ts +128 -0
- package/dist/layouts/shell.d.ts.map +1 -0
- package/dist/layouts/shell.js +107 -0
- package/dist/layouts/shell.js.map +1 -0
- package/dist/lib/cn.d.ts +4 -0
- package/dist/lib/cn.d.ts.map +1 -0
- package/dist/lib/cn.js +9 -0
- package/dist/lib/cn.js.map +1 -0
- package/dist/lib/is-active-path.d.ts +13 -0
- package/dist/lib/is-active-path.d.ts.map +1 -0
- package/dist/lib/is-active-path.js +7 -0
- package/dist/lib/is-active-path.js.map +1 -0
- package/dist/lib/theme-tick.d.ts +37 -0
- package/dist/lib/theme-tick.d.ts.map +1 -0
- package/dist/lib/theme-tick.js +30 -0
- package/dist/lib/theme-tick.js.map +1 -0
- package/dist/lib/token-color.d.ts +74 -0
- package/dist/lib/token-color.d.ts.map +1 -0
- package/dist/lib/token-color.js +35 -0
- package/dist/lib/token-color.js.map +1 -0
- package/dist/lib/use-is-mobile.d.ts +2 -0
- package/dist/lib/use-is-mobile.d.ts.map +1 -0
- package/dist/lib/use-is-mobile.js +17 -0
- package/dist/lib/use-is-mobile.js.map +1 -0
- package/dist/shark-parity.divergences.d.ts +104 -0
- package/dist/shark-parity.divergences.d.ts.map +1 -0
- package/dist/simples/FacetFilter.d.ts +57 -0
- package/dist/simples/FacetFilter.d.ts.map +1 -0
- package/dist/simples/FacetFilter.js +167 -0
- package/dist/simples/FacetFilter.js.map +1 -0
- package/dist/simples/FieldArray.d.ts +42 -0
- package/dist/simples/FieldArray.d.ts.map +1 -0
- package/dist/simples/FieldArray.js +76 -0
- package/dist/simples/FieldArray.js.map +1 -0
- package/dist/simples/Link.d.ts +38 -0
- package/dist/simples/Link.d.ts.map +1 -0
- package/dist/simples/Link.js +24 -0
- package/dist/simples/Link.js.map +1 -0
- package/dist/simples/accordion.d.ts +8 -0
- package/dist/simples/accordion.d.ts.map +1 -0
- package/dist/simples/accordion.js +78 -0
- package/dist/simples/accordion.js.map +1 -0
- package/dist/simples/action-bar.d.ts +101 -0
- package/dist/simples/action-bar.d.ts.map +1 -0
- package/dist/simples/action-bar.js +195 -0
- package/dist/simples/action-bar.js.map +1 -0
- package/dist/simples/alert-dialog.d.ts +24 -0
- package/dist/simples/alert-dialog.d.ts.map +1 -0
- package/dist/simples/alert-dialog.js +43 -0
- package/dist/simples/alert-dialog.js.map +1 -0
- package/dist/simples/alert.d.ts +36 -0
- package/dist/simples/alert.d.ts.map +1 -0
- package/dist/simples/alert.js +123 -0
- package/dist/simples/alert.js.map +1 -0
- package/dist/simples/avatar.d.ts +37 -0
- package/dist/simples/avatar.d.ts.map +1 -0
- package/dist/simples/avatar.js +133 -0
- package/dist/simples/avatar.js.map +1 -0
- package/dist/simples/badge.d.ts +66 -0
- package/dist/simples/badge.d.ts.map +1 -0
- package/dist/simples/badge.js +138 -0
- package/dist/simples/badge.js.map +1 -0
- package/dist/simples/breadcrumb.d.ts +19 -0
- package/dist/simples/breadcrumb.d.ts.map +1 -0
- package/dist/simples/breadcrumb.js +107 -0
- package/dist/simples/breadcrumb.js.map +1 -0
- package/dist/simples/button-group.d.ts +19 -0
- package/dist/simples/button-group.d.ts.map +1 -0
- package/dist/simples/button-group.js +69 -0
- package/dist/simples/button-group.js.map +1 -0
- package/dist/simples/button.d.ts +148 -0
- package/dist/simples/button.d.ts.map +1 -0
- package/dist/simples/button.js +157 -0
- package/dist/simples/button.js.map +1 -0
- package/dist/simples/calendar.d.ts +45 -0
- package/dist/simples/calendar.d.ts.map +1 -0
- package/dist/simples/calendar.js +342 -0
- package/dist/simples/calendar.js.map +1 -0
- package/dist/simples/card.d.ts +43 -0
- package/dist/simples/card.d.ts.map +1 -0
- package/dist/simples/card.js +151 -0
- package/dist/simples/card.js.map +1 -0
- package/dist/simples/checkbox.d.ts +25 -0
- package/dist/simples/checkbox.d.ts.map +1 -0
- package/dist/simples/checkbox.js +103 -0
- package/dist/simples/checkbox.js.map +1 -0
- package/dist/simples/client-only.d.ts +3 -0
- package/dist/simples/client-only.d.ts.map +1 -0
- package/dist/simples/client-only.js +7 -0
- package/dist/simples/client-only.js.map +1 -0
- package/dist/simples/clipboard.d.ts +11 -0
- package/dist/simples/clipboard.d.ts.map +1 -0
- package/dist/simples/clipboard.js +99 -0
- package/dist/simples/clipboard.js.map +1 -0
- package/dist/simples/collapsible.d.ts +8 -0
- package/dist/simples/collapsible.d.ts.map +1 -0
- package/dist/simples/collapsible.js +79 -0
- package/dist/simples/collapsible.js.map +1 -0
- package/dist/simples/color-picker.d.ts +62 -0
- package/dist/simples/color-picker.d.ts.map +1 -0
- package/dist/simples/color-picker.js +391 -0
- package/dist/simples/color-picker.js.map +1 -0
- package/dist/simples/combobox.d.ts +66 -0
- package/dist/simples/combobox.d.ts.map +1 -0
- package/dist/simples/combobox.js +230 -0
- package/dist/simples/combobox.js.map +1 -0
- package/dist/simples/command.d.ts +45 -0
- package/dist/simples/command.d.ts.map +1 -0
- package/dist/simples/command.js +180 -0
- package/dist/simples/command.js.map +1 -0
- package/dist/simples/data-list.d.ts +25 -0
- package/dist/simples/data-list.d.ts.map +1 -0
- package/dist/simples/data-list.js +62 -0
- package/dist/simples/data-list.js.map +1 -0
- package/dist/simples/date-picker.d.ts +16 -0
- package/dist/simples/date-picker.d.ts.map +1 -0
- package/dist/simples/date-picker.js +117 -0
- package/dist/simples/date-picker.js.map +1 -0
- package/dist/simples/diagnostic.d.ts +138 -0
- package/dist/simples/diagnostic.d.ts.map +1 -0
- package/dist/simples/diagnostic.js +288 -0
- package/dist/simples/diagnostic.js.map +1 -0
- package/dist/simples/dialog.d.ts +100 -0
- package/dist/simples/dialog.d.ts.map +1 -0
- package/dist/simples/dialog.js +267 -0
- package/dist/simples/dialog.js.map +1 -0
- package/dist/simples/download-trigger.d.ts +3 -0
- package/dist/simples/download-trigger.d.ts.map +1 -0
- package/dist/simples/download-trigger.js +7 -0
- package/dist/simples/download-trigger.js.map +1 -0
- package/dist/simples/editable.d.ts +23 -0
- package/dist/simples/editable.d.ts.map +1 -0
- package/dist/simples/editable.js +70 -0
- package/dist/simples/editable.js.map +1 -0
- package/dist/simples/field.d.ts +58 -0
- package/dist/simples/field.d.ts.map +1 -0
- package/dist/simples/field.js +285 -0
- package/dist/simples/field.js.map +1 -0
- package/dist/simples/file-upload.d.ts +19 -0
- package/dist/simples/file-upload.d.ts.map +1 -0
- package/dist/simples/file-upload.js +192 -0
- package/dist/simples/file-upload.js.map +1 -0
- package/dist/simples/float.d.ts +45 -0
- package/dist/simples/float.d.ts.map +1 -0
- package/dist/simples/float.js +40 -0
- package/dist/simples/float.js.map +1 -0
- package/dist/simples/floating-panel.d.ts +25 -0
- package/dist/simples/floating-panel.d.ts.map +1 -0
- package/dist/simples/floating-panel.js +95 -0
- package/dist/simples/floating-panel.js.map +1 -0
- package/dist/simples/highlight.d.ts +6 -0
- package/dist/simples/highlight.d.ts.map +1 -0
- package/dist/simples/highlight.js +24 -0
- package/dist/simples/highlight.js.map +1 -0
- package/dist/simples/hover-card.d.ts +11 -0
- package/dist/simples/hover-card.d.ts.map +1 -0
- package/dist/simples/hover-card.js +83 -0
- package/dist/simples/hover-card.js.map +1 -0
- package/dist/simples/image-cropper.d.ts +17 -0
- package/dist/simples/image-cropper.d.ts.map +1 -0
- package/dist/simples/image-cropper.js +139 -0
- package/dist/simples/image-cropper.js.map +1 -0
- package/dist/simples/input-group.d.ts +116 -0
- package/dist/simples/input-group.d.ts.map +1 -0
- package/dist/simples/input-group.js +245 -0
- package/dist/simples/input-group.js.map +1 -0
- package/dist/simples/input.d.ts +26 -0
- package/dist/simples/input.d.ts.map +1 -0
- package/dist/simples/input.js +60 -0
- package/dist/simples/input.js.map +1 -0
- package/dist/simples/item.d.ts +72 -0
- package/dist/simples/item.d.ts.map +1 -0
- package/dist/simples/item.js +180 -0
- package/dist/simples/item.js.map +1 -0
- package/dist/simples/json-tree-view.d.ts +7 -0
- package/dist/simples/json-tree-view.d.ts.map +1 -0
- package/dist/simples/json-tree-view.js +71 -0
- package/dist/simples/json-tree-view.js.map +1 -0
- package/dist/simples/kbd.d.ts +25 -0
- package/dist/simples/kbd.d.ts.map +1 -0
- package/dist/simples/kbd.js +50 -0
- package/dist/simples/kbd.js.map +1 -0
- package/dist/simples/listbox.d.ts +46 -0
- package/dist/simples/listbox.d.ts.map +1 -0
- package/dist/simples/listbox.js +218 -0
- package/dist/simples/listbox.js.map +1 -0
- package/dist/simples/menu.d.ts +60 -0
- package/dist/simples/menu.d.ts.map +1 -0
- package/dist/simples/menu.js +294 -0
- package/dist/simples/menu.js.map +1 -0
- package/dist/simples/native-select.d.ts +36 -0
- package/dist/simples/native-select.d.ts.map +1 -0
- package/dist/simples/native-select.js +77 -0
- package/dist/simples/native-select.js.map +1 -0
- package/dist/simples/number-input.d.ts +35 -0
- package/dist/simples/number-input.d.ts.map +1 -0
- package/dist/simples/number-input.js +142 -0
- package/dist/simples/number-input.js.map +1 -0
- package/dist/simples/pagination.d.ts +11 -0
- package/dist/simples/pagination.d.ts.map +1 -0
- package/dist/simples/pagination.js +78 -0
- package/dist/simples/pagination.js.map +1 -0
- package/dist/simples/password-input.d.ts +23 -0
- package/dist/simples/password-input.d.ts.map +1 -0
- package/dist/simples/password-input.js +90 -0
- package/dist/simples/password-input.js.map +1 -0
- package/dist/simples/pin-input.d.ts +30 -0
- package/dist/simples/pin-input.d.ts.map +1 -0
- package/dist/simples/pin-input.js +71 -0
- package/dist/simples/pin-input.js.map +1 -0
- package/dist/simples/popover.d.ts +42 -0
- package/dist/simples/popover.d.ts.map +1 -0
- package/dist/simples/popover.js +188 -0
- package/dist/simples/popover.js.map +1 -0
- package/dist/simples/progress.d.ts +23 -0
- package/dist/simples/progress.d.ts.map +1 -0
- package/dist/simples/progress.js +82 -0
- package/dist/simples/progress.js.map +1 -0
- package/dist/simples/prose.d.ts +17 -0
- package/dist/simples/prose.d.ts.map +1 -0
- package/dist/simples/prose.js +18 -0
- package/dist/simples/prose.js.map +1 -0
- package/dist/simples/radio-group.d.ts +23 -0
- package/dist/simples/radio-group.d.ts.map +1 -0
- package/dist/simples/radio-group.js +149 -0
- package/dist/simples/radio-group.js.map +1 -0
- package/dist/simples/rating.d.ts +10 -0
- package/dist/simples/rating.d.ts.map +1 -0
- package/dist/simples/rating.js +81 -0
- package/dist/simples/rating.js.map +1 -0
- package/dist/simples/resizable.d.ts +16 -0
- package/dist/simples/resizable.d.ts.map +1 -0
- package/dist/simples/resizable.js +57 -0
- package/dist/simples/resizable.js.map +1 -0
- package/dist/simples/scroll-area.d.ts +23 -0
- package/dist/simples/scroll-area.d.ts.map +1 -0
- package/dist/simples/scroll-area.js +88 -0
- package/dist/simples/scroll-area.js.map +1 -0
- package/dist/simples/segment-group.d.ts +27 -0
- package/dist/simples/segment-group.d.ts.map +1 -0
- package/dist/simples/segment-group.js +129 -0
- package/dist/simples/segment-group.js.map +1 -0
- package/dist/simples/select.d.ts +34 -0
- package/dist/simples/select.d.ts.map +1 -0
- package/dist/simples/select.js +258 -0
- package/dist/simples/select.js.map +1 -0
- package/dist/simples/separator.d.ts +12 -0
- package/dist/simples/separator.d.ts.map +1 -0
- package/dist/simples/separator.js +27 -0
- package/dist/simples/separator.js.map +1 -0
- package/dist/simples/sheet.d.ts +94 -0
- package/dist/simples/sheet.d.ts.map +1 -0
- package/dist/simples/sheet.js +172 -0
- package/dist/simples/sheet.js.map +1 -0
- package/dist/simples/show.d.ts +10 -0
- package/dist/simples/show.d.ts.map +1 -0
- package/dist/simples/show.js +9 -0
- package/dist/simples/show.js.map +1 -0
- package/dist/simples/skeleton.d.ts +3 -0
- package/dist/simples/skeleton.d.ts.map +1 -0
- package/dist/simples/skeleton.js +23 -0
- package/dist/simples/skeleton.js.map +1 -0
- package/dist/simples/skip-nav.d.ts +54 -0
- package/dist/simples/skip-nav.d.ts.map +1 -0
- package/dist/simples/skip-nav.js +42 -0
- package/dist/simples/skip-nav.js.map +1 -0
- package/dist/simples/slider.d.ts +29 -0
- package/dist/simples/slider.d.ts.map +1 -0
- package/dist/simples/slider.js +189 -0
- package/dist/simples/slider.js.map +1 -0
- package/dist/simples/spinner.d.ts +2 -0
- package/dist/simples/spinner.d.ts.map +1 -0
- package/dist/simples/spinner.js +20 -0
- package/dist/simples/spinner.js.map +1 -0
- package/dist/simples/stat-tile.d.ts +31 -0
- package/dist/simples/stat-tile.d.ts.map +1 -0
- package/dist/simples/stat-tile.js +64 -0
- package/dist/simples/stat-tile.js.map +1 -0
- package/dist/simples/status.d.ts +48 -0
- package/dist/simples/status.d.ts.map +1 -0
- package/dist/simples/status.js +57 -0
- package/dist/simples/status.js.map +1 -0
- package/dist/simples/steps.d.ts +20 -0
- package/dist/simples/steps.d.ts.map +1 -0
- package/dist/simples/steps.js +171 -0
- package/dist/simples/steps.js.map +1 -0
- package/dist/simples/suggestions.d.ts +43 -0
- package/dist/simples/suggestions.d.ts.map +1 -0
- package/dist/simples/suggestions.js +38 -0
- package/dist/simples/suggestions.js.map +1 -0
- package/dist/simples/swatch.d.ts +73 -0
- package/dist/simples/swatch.d.ts.map +1 -0
- package/dist/simples/swatch.js +35 -0
- package/dist/simples/swatch.js.map +1 -0
- package/dist/simples/switch.d.ts +5 -0
- package/dist/simples/switch.d.ts.map +1 -0
- package/dist/simples/switch.js +71 -0
- package/dist/simples/switch.js.map +1 -0
- package/dist/simples/table.d.ts +55 -0
- package/dist/simples/table.d.ts.map +1 -0
- package/dist/simples/table.js +166 -0
- package/dist/simples/table.js.map +1 -0
- package/dist/simples/tabs.d.ts +55 -0
- package/dist/simples/tabs.d.ts.map +1 -0
- package/dist/simples/tabs.js +133 -0
- package/dist/simples/tabs.js.map +1 -0
- package/dist/simples/tags-input.d.ts +64 -0
- package/dist/simples/tags-input.d.ts.map +1 -0
- package/dist/simples/tags-input.js +228 -0
- package/dist/simples/tags-input.js.map +1 -0
- package/dist/simples/textarea.d.ts +6 -0
- package/dist/simples/textarea.d.ts.map +1 -0
- package/dist/simples/textarea.js +34 -0
- package/dist/simples/textarea.js.map +1 -0
- package/dist/simples/toast.d.ts +20 -0
- package/dist/simples/toast.d.ts.map +1 -0
- package/dist/simples/toast.js +127 -0
- package/dist/simples/toast.js.map +1 -0
- package/dist/simples/toggle-group.d.ts +20 -0
- package/dist/simples/toggle-group.d.ts.map +1 -0
- package/dist/simples/toggle-group.js +82 -0
- package/dist/simples/toggle-group.js.map +1 -0
- package/dist/simples/toggle.d.ts +35 -0
- package/dist/simples/toggle.d.ts.map +1 -0
- package/dist/simples/toggle.js +57 -0
- package/dist/simples/toggle.js.map +1 -0
- package/dist/simples/tooltip.d.ts +8 -0
- package/dist/simples/tooltip.d.ts.map +1 -0
- package/dist/simples/tooltip.js +80 -0
- package/dist/simples/tooltip.js.map +1 -0
- package/dist/simples/tour.d.ts +81 -0
- package/dist/simples/tour.d.ts.map +1 -0
- package/dist/simples/tour.js +253 -0
- package/dist/simples/tour.js.map +1 -0
- package/dist/simples/tree-view.d.ts +64 -0
- package/dist/simples/tree-view.d.ts.map +1 -0
- package/dist/simples/tree-view.js +300 -0
- package/dist/simples/tree-view.js.map +1 -0
- package/dist/styles.css +2 -0
- package/dist/table/data-table-content.d.ts +18 -0
- package/dist/table/data-table-content.d.ts.map +1 -0
- package/dist/table/data-table-content.js +53 -0
- package/dist/table/data-table-content.js.map +1 -0
- package/dist/table/data-table-pagination.d.ts +8 -0
- package/dist/table/data-table-pagination.d.ts.map +1 -0
- package/dist/table/data-table-pagination.js +65 -0
- package/dist/table/data-table-pagination.js.map +1 -0
- package/dist/table/data-table-root.d.ts +10 -0
- package/dist/table/data-table-root.d.ts.map +1 -0
- package/dist/table/data-table-root.js +21 -0
- package/dist/table/data-table-root.js.map +1 -0
- package/dist/table/data-table-toolbar.d.ts +44 -0
- package/dist/table/data-table-toolbar.d.ts.map +1 -0
- package/dist/table/data-table-toolbar.js +87 -0
- package/dist/table/data-table-toolbar.js.map +1 -0
- package/dist/table/select-column.d.ts +16 -0
- package/dist/table/select-column.d.ts.map +1 -0
- package/dist/table/select-column.js +39 -0
- package/dist/table/select-column.js.map +1 -0
- package/dist/table/sortableHeader.d.ts +25 -0
- package/dist/table/sortableHeader.d.ts.map +1 -0
- package/dist/table/sortableHeader.js +43 -0
- package/dist/table/sortableHeader.js.map +1 -0
- package/dist/table/use-data-table.d.ts +40 -0
- package/dist/table/use-data-table.d.ts.map +1 -0
- package/dist/table/use-data-table.js +65 -0
- package/dist/table/use-data-table.js.map +1 -0
- package/dist/table.d.ts +15 -0
- package/dist/table.d.ts.map +1 -0
- package/dist/table.js +22 -0
- package/dist/table.js.map +1 -0
- package/dist/theme/KanzoTheme.d.ts +74 -0
- package/dist/theme/KanzoTheme.d.ts.map +1 -0
- package/dist/theme/KanzoTheme.js +61 -0
- package/dist/theme/KanzoTheme.js.map +1 -0
- package/dist/theme/KanzoThemeProvider.d.ts +144 -0
- package/dist/theme/KanzoThemeProvider.d.ts.map +1 -0
- package/dist/theme/KanzoThemeProvider.js +271 -0
- package/dist/theme/KanzoThemeProvider.js.map +1 -0
- package/dist/theme/theme-context.d.ts +146 -0
- package/dist/theme/theme-context.d.ts.map +1 -0
- package/dist/theme/theme-context.js +18 -0
- package/dist/theme/theme-context.js.map +1 -0
- package/dist/theme/theme-script.d.ts +17 -0
- package/dist/theme/theme-script.d.ts.map +1 -0
- package/dist/theme/theme-script.js +16 -0
- package/dist/theme/theme-script.js.map +1 -0
- package/package.json +201 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { ReactNode, default as React } from 'react';
|
|
2
|
+
import { ark } from '@ark-ui/react/factory';
|
|
3
|
+
import { MosaicClient, Selection, SelectionClause } from '@uwdata/mosaic-core';
|
|
4
|
+
import { Query, FilterExpr } from '@uwdata/mosaic-sql';
|
|
5
|
+
import { ChartQueryRow as QueryRow } from './query-client.js';
|
|
6
|
+
/**
|
|
7
|
+
* Mosaic **inputs** — controls that publish into a `Selection` without being charts.
|
|
8
|
+
*
|
|
9
|
+
* Unlike marks and interactors, these are real DOM parts (`ark.*`, `data-slot`, forwarded props),
|
|
10
|
+
* not inert descriptors: they carry no `__chart` static and belong *outside* `<ChartRoot>`. What
|
|
11
|
+
* makes them Mosaic and not just a styled `<select>` is that each one is a `MosaicClient`: it
|
|
12
|
+
* declares a `query()` for the values it needs (grouped counts, distinct values, a numeric extent),
|
|
13
|
+
* the coordinator answers it, and the control publishes `clausePoints` / `clauseMatch` /
|
|
14
|
+
* `clauseInterval` back into the selection the charts filter by.
|
|
15
|
+
*
|
|
16
|
+
* The vgplot equivalents (`vg.menu`, `vg.search`, `vg.slider`) build raw HTML. These use our
|
|
17
|
+
* controls, our tokens and our accessibility, and are controllable *and* observable: an external
|
|
18
|
+
* change to the selection flows back into the widget.
|
|
19
|
+
*/
|
|
20
|
+
export interface MosaicInputOptions<T> {
|
|
21
|
+
/** Filters the widget's own lookup query. `null` = the full relation. */
|
|
22
|
+
filterBy: Selection | null;
|
|
23
|
+
/** Where the widget publishes. `null` = nowhere. */
|
|
24
|
+
as: Selection | null;
|
|
25
|
+
/** The lookup query, or `null` when there is nothing to ask the coordinator for. */
|
|
26
|
+
build: (filter: FilterExpr) => Query | null;
|
|
27
|
+
/** Rebuilds the client — and re-runs the lookup — when any entry changes. */
|
|
28
|
+
deps: readonly unknown[];
|
|
29
|
+
clause: (source: MosaicClient, value: T | undefined) => SelectionClause;
|
|
30
|
+
/** The representative value of the warm-up clause published on hover/focus. */
|
|
31
|
+
activateValue: T;
|
|
32
|
+
/** Reads the widget's own clause value back out of the selection. Defaults to an identity cast. */
|
|
33
|
+
decode?: (value: unknown) => T;
|
|
34
|
+
}
|
|
35
|
+
export interface MosaicInputState<T> {
|
|
36
|
+
/** Lookup rows, or `null` while the query is in flight (or when there is no query). */
|
|
37
|
+
rows: readonly QueryRow[] | null;
|
|
38
|
+
/** The value this widget currently holds in the selection — its observable half. */
|
|
39
|
+
selected: T | undefined;
|
|
40
|
+
publish: (value: T | undefined) => void;
|
|
41
|
+
activate: () => void;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The conversation with Mosaic that every input in this file has: a lookup query that re-runs under
|
|
45
|
+
* the crossfilter, a clause published with `source` set so a control never filters itself, and a
|
|
46
|
+
* warm-up so the first interaction is not the first query.
|
|
47
|
+
*
|
|
48
|
+
* Exported because the three controls here are surfaces over it, not the only surfaces it allows —
|
|
49
|
+
* a chip row, a segmented switch or a map lasso is the same conversation with different chrome, and
|
|
50
|
+
* without this the alternative is reimplementing it.
|
|
51
|
+
*/
|
|
52
|
+
export declare function useMosaicInput<T>(options: MosaicInputOptions<T>): MosaicInputState<T>;
|
|
53
|
+
interface SelectionProps {
|
|
54
|
+
/** Where the control publishes. Defaults to the provider's crossfilter; `null` = nowhere. */
|
|
55
|
+
as?: Selection | null;
|
|
56
|
+
/** What the control's own lookup filters by. Defaults to the crossfilter; `null` = unfiltered. */
|
|
57
|
+
filterBy?: Selection | null;
|
|
58
|
+
}
|
|
59
|
+
type ControlSize = "sm" | "md" | "lg";
|
|
60
|
+
/** An explicit entry. Bare values work too — they are labelled by `format`. */
|
|
61
|
+
export interface ChartFilterOption {
|
|
62
|
+
value: unknown;
|
|
63
|
+
label?: string;
|
|
64
|
+
icon?: React.ComponentType<{
|
|
65
|
+
className?: string;
|
|
66
|
+
}>;
|
|
67
|
+
}
|
|
68
|
+
export interface ChartFilterProps extends Omit<React.ComponentProps<typeof ark.div>, "defaultValue">, SelectionProps {
|
|
69
|
+
/** The relation the values and their counts come from. */
|
|
70
|
+
table?: string;
|
|
71
|
+
/** The column grouped by. */
|
|
72
|
+
column?: string;
|
|
73
|
+
/** The column named in the published clause. Defaults to `column`. */
|
|
74
|
+
field?: string;
|
|
75
|
+
/** Explicit options — a literal value or a `{ value, label, icon }` object. Skips the lookup. */
|
|
76
|
+
options?: readonly unknown[];
|
|
77
|
+
/** Labels an option value that carries no explicit label. */
|
|
78
|
+
format?: (value: unknown) => string;
|
|
79
|
+
/** Trigger label. Defaults to `column`. */
|
|
80
|
+
label?: ReactNode;
|
|
81
|
+
/** Tick any number of values (an `IN` list). `false` keeps at most one ticked. */
|
|
82
|
+
multiple?: boolean;
|
|
83
|
+
/** Published once, when the control first connects. A bare value or an array of them. */
|
|
84
|
+
defaultValue?: unknown;
|
|
85
|
+
/** Most-frequent values kept; past this the list says so rather than rendering the tail. */
|
|
86
|
+
limit?: number;
|
|
87
|
+
/**
|
|
88
|
+
* Draw a filter field above the values.
|
|
89
|
+
*
|
|
90
|
+
* It narrows **the fetched page** — the `limit` most frequent values this control asked for — and
|
|
91
|
+
* runs no query of its own. When the page is truncated the note and the no-match message say so,
|
|
92
|
+
* because a field that answers "no matching values" about a database it never asked is worse than
|
|
93
|
+
* no field. Searching the column itself is `ChartSearch`, which publishes a match clause.
|
|
94
|
+
*
|
|
95
|
+
* @default false
|
|
96
|
+
*/
|
|
97
|
+
searchable?: boolean;
|
|
98
|
+
disabled?: boolean;
|
|
99
|
+
size?: ControlSize;
|
|
100
|
+
/** Class for the trigger; `className` styles the wrapper. */
|
|
101
|
+
controlClassName?: string;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* A facet filter over a column's values, publishing a **points** clause — the same `FacetFilter`
|
|
105
|
+
* surface as the table's, so a dashboard has one filter idiom rather than two.
|
|
106
|
+
*
|
|
107
|
+
* The values are a query, not a prop: the control connects as a Mosaic client and asks for
|
|
108
|
+
* `SELECT <column>, count(*) … GROUP BY <column>` filtered by `filterBy`. The counts therefore
|
|
109
|
+
* react to the *other* filters but not to this one — a crossfilter resolver drops a clause when it
|
|
110
|
+
* builds the predicate for the clause's own source, and `clausePoints` tags the clause with this
|
|
111
|
+
* client. (A non-crossfilter `filterBy` has no such exemption and would count itself.)
|
|
112
|
+
*/
|
|
113
|
+
export declare function ChartFilter(props: ChartFilterProps): React.JSX.Element;
|
|
114
|
+
export interface ChartSearchProps extends Omit<React.ComponentProps<typeof ark.div>, "defaultValue">, SelectionProps {
|
|
115
|
+
/** The relation the autocomplete values come from. */
|
|
116
|
+
table?: string;
|
|
117
|
+
/** The column to search. */
|
|
118
|
+
column?: string;
|
|
119
|
+
/** The column named in the published clause. Defaults to `column`. */
|
|
120
|
+
field?: string;
|
|
121
|
+
/** Where the query string has to appear. */
|
|
122
|
+
type?: "contains" | "prefix" | "suffix" | "regexp";
|
|
123
|
+
caseSensitive?: boolean;
|
|
124
|
+
label?: ReactNode;
|
|
125
|
+
placeholder?: string;
|
|
126
|
+
/** ms of quiet before publishing. `0` publishes on every keystroke, as vgplot does. */
|
|
127
|
+
debounce?: number;
|
|
128
|
+
/** Distinct values offered as a native autocomplete list. `0` skips the lookup entirely. */
|
|
129
|
+
autocompleteLimit?: number;
|
|
130
|
+
defaultValue?: string;
|
|
131
|
+
disabled?: boolean;
|
|
132
|
+
size?: ControlSize;
|
|
133
|
+
/** Class for the control; `className` styles the wrapper. */
|
|
134
|
+
controlClassName?: string;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* A text box publishing a **match** clause (`contains` / `prefix` / `suffix` / `regexp`).
|
|
138
|
+
*
|
|
139
|
+
* Every keystroke is a query, so the publish is debounced by default. The distinct values of the
|
|
140
|
+
* column feed a native `<datalist>`, exactly as vgplot's `search` does — and, as there, the list
|
|
141
|
+
* narrows with the query, since a match clause does not exempt its own client from the crossfilter.
|
|
142
|
+
*/
|
|
143
|
+
export declare function ChartSearch(props: ChartSearchProps): React.JSX.Element;
|
|
144
|
+
export interface ChartSliderProps extends Omit<React.ComponentProps<typeof ark.div>, "defaultValue">, SelectionProps {
|
|
145
|
+
/** The relation the extent comes from, when `min`/`max` are not both given. */
|
|
146
|
+
table?: string;
|
|
147
|
+
/** The numeric column. */
|
|
148
|
+
column?: string;
|
|
149
|
+
/** The column named in the published clause. Defaults to `column`. */
|
|
150
|
+
field?: string;
|
|
151
|
+
/**
|
|
152
|
+
* `point` publishes an equality clause for one thumb; `interval` publishes a two-thumb range.
|
|
153
|
+
* (vgplot's slider only ever offers `[min, value]`; ours brushes a real interval.)
|
|
154
|
+
*/
|
|
155
|
+
select?: "point" | "interval";
|
|
156
|
+
min?: number;
|
|
157
|
+
max?: number;
|
|
158
|
+
step?: number;
|
|
159
|
+
/** Published once, when the control first connects. */
|
|
160
|
+
defaultValue?: number | readonly [number, number];
|
|
161
|
+
label?: ReactNode;
|
|
162
|
+
/** Show the current value beside the label. */
|
|
163
|
+
showValue?: boolean;
|
|
164
|
+
disabled?: boolean;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* A slider over a numeric column, publishing a **point** or **interval** clause.
|
|
168
|
+
*
|
|
169
|
+
* The extent is a query when `min`/`max` are not both given: `SELECT min(col), max(col)`, answered
|
|
170
|
+
* by the coordinator. A `Skeleton` shaped like the track holds the space until it arrives.
|
|
171
|
+
*/
|
|
172
|
+
export declare function ChartSlider(props: ChartSliderProps): React.JSX.Element;
|
|
173
|
+
export {};
|
|
174
|
+
//# sourceMappingURL=chart-inputs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-inputs.d.ts","sourceRoot":"","sources":["../../src/charts/chart-inputs.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAqD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC1F,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAC5C,OAAO,EAKL,YAAY,EACZ,KAAK,SAAS,EACd,KAAK,eAAe,EACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAKL,KAAK,EACL,KAAK,UAAU,EAChB,MAAM,oBAAoB,CAAC;AAiB5B,OAAO,EAAoB,KAAK,aAAa,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAErF;;;;;;;;;;;;;GAaG;AAGH,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACnC,yEAAyE;IACzE,QAAQ,EAAE,SAAS,GAAG,IAAI,CAAC;IAC3B,oDAAoD;IACpD,EAAE,EAAE,SAAS,GAAG,IAAI,CAAC;IACrB,oFAAoF;IACpF,KAAK,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,KAAK,GAAG,IAAI,CAAC;IAC5C,6EAA6E;IAC7E,IAAI,EAAE,SAAS,OAAO,EAAE,CAAC;IACzB,MAAM,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,GAAG,SAAS,KAAK,eAAe,CAAC;IACxE,+EAA+E;IAC/E,aAAa,EAAE,CAAC,CAAC;IACjB,mGAAmG;IACnG,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,uFAAuF;IACvF,IAAI,EAAE,SAAS,QAAQ,EAAE,GAAG,IAAI,CAAC;IACjC,oFAAoF;IACpF,QAAQ,EAAE,CAAC,GAAG,SAAS,CAAC;IACxB,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,SAAS,KAAK,IAAI,CAAC;IACxC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAC9B,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC7B,gBAAgB,CAAC,CAAC,CAAC,CA4DrB;AAmBD,UAAU,cAAc;IACtB,6FAA6F;IAC7F,EAAE,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACtB,kGAAkG;IAClG,QAAQ,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;CAC7B;AAED,KAAK,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAItC,+EAA+E;AAC/E,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD;AAED,MAAM,WAAW,gBACf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,EAAE,cAAc,CAAC,EAChE,cAAc;IAChB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6BAA6B;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iGAAiG;IACjG,OAAO,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;IAC7B,6DAA6D;IAC7D,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC;IACpC,2CAA2C;IAC3C,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yFAAyF;IACzF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,4FAA4F;IAC5F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAgED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,qBAuGlD;AAID,MAAM,WAAW,gBACf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,EAAE,cAAc,CAAC,EAChE,cAAc;IAChB,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,IAAI,CAAC,EAAE,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACnD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uFAAuF;IACvF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4FAA4F;IAC5F,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,qBAiKlD;AAID,MAAM,WAAW,gBACf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,EAAE,cAAc,CAAC,EAChE,cAAc;IAChB,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0BAA0B;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAgBD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,qBAiIlD"}
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs as A, jsx as C } from "react/jsx-runtime";
|
|
3
|
+
import { useRef as B, useEffect as N, useMemo as ne, useState as _, useCallback as Z } from "react";
|
|
4
|
+
import { ark as re } from "@ark-ui/react/factory";
|
|
5
|
+
import { clausePoints as le, clausePoint as oe, clauseMatch as ie, clauseInterval as ce } from "@uwdata/mosaic-core";
|
|
6
|
+
import { Query as G, count as ee, desc as se, max as ae, min as ue } from "@uwdata/mosaic-sql";
|
|
7
|
+
import { useListCollection as me } from "@ark-ui/react/collection";
|
|
8
|
+
import { useFilter as de } from "@ark-ui/react/locale";
|
|
9
|
+
import { cn as J } from "../lib/cn.js";
|
|
10
|
+
import { Combobox as fe, ComboboxInput as he, ComboboxContent as pe, ComboboxEmpty as ve, ComboboxItem as be } from "../simples/combobox.js";
|
|
11
|
+
import { FacetFilter as ge } from "../simples/FacetFilter.js";
|
|
12
|
+
import { Field as ye, FieldLabel as xe } from "../simples/field.js";
|
|
13
|
+
import { Input as Ce } from "../simples/input.js";
|
|
14
|
+
import { Skeleton as Ne } from "../simples/skeleton.js";
|
|
15
|
+
import { Slider as Se, SliderLabel as Ve, SliderValue as we } from "../simples/slider.js";
|
|
16
|
+
import { useMosaic as q } from "./mosaic-provider.js";
|
|
17
|
+
import { ChartQueryClient as Fe } from "./query-client.js";
|
|
18
|
+
function W(t) {
|
|
19
|
+
const { filterBy: r, as: e, deps: i } = t, { coordinator: a } = q(), d = B(t);
|
|
20
|
+
d.current = t;
|
|
21
|
+
const p = B(null), [b, x] = _(null), [y, m] = _(null), [u, v] = _(void 0);
|
|
22
|
+
N(() => {
|
|
23
|
+
const s = new Fe(
|
|
24
|
+
r ?? void 0,
|
|
25
|
+
(h) => d.current.build(h),
|
|
26
|
+
m
|
|
27
|
+
);
|
|
28
|
+
return p.current = s, m(null), x(s), a.connect(s), () => {
|
|
29
|
+
p.current = null, a.disconnect(s);
|
|
30
|
+
};
|
|
31
|
+
}, [a, r, ...i]), N(() => {
|
|
32
|
+
if (!e || !b) return;
|
|
33
|
+
const s = () => {
|
|
34
|
+
const h = e.valueFor(b), { decode: E } = d.current;
|
|
35
|
+
v(h === void 0 ? void 0 : E ? E(h) : h);
|
|
36
|
+
};
|
|
37
|
+
return s(), e.addEventListener("value", s), () => {
|
|
38
|
+
e.removeEventListener("value", s), e.valueFor(b) !== void 0 && e.update(d.current.clause(b, void 0));
|
|
39
|
+
};
|
|
40
|
+
}, [e, b]);
|
|
41
|
+
const S = Z(
|
|
42
|
+
(s) => {
|
|
43
|
+
v(s);
|
|
44
|
+
const h = p.current;
|
|
45
|
+
e && h && e.update(d.current.clause(h, s));
|
|
46
|
+
},
|
|
47
|
+
[e]
|
|
48
|
+
), k = Z(() => {
|
|
49
|
+
const s = p.current;
|
|
50
|
+
e && s && e.activate(d.current.clause(s, d.current.activateValue));
|
|
51
|
+
}, [e]);
|
|
52
|
+
return { rows: y, selected: u, publish: S, activate: k };
|
|
53
|
+
}
|
|
54
|
+
function X(t, r) {
|
|
55
|
+
return {
|
|
56
|
+
onFocus: (e) => {
|
|
57
|
+
var i;
|
|
58
|
+
(i = r.onFocus) == null || i.call(r, e), t();
|
|
59
|
+
},
|
|
60
|
+
onPointerEnter: (e) => {
|
|
61
|
+
var i;
|
|
62
|
+
(i = r.onPointerEnter) == null || i.call(r, e), e.buttons || t();
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const Ie = 50;
|
|
67
|
+
function Be(t) {
|
|
68
|
+
return typeof t == "object" && t !== null && !Array.isArray(t) && "value" in t;
|
|
69
|
+
}
|
|
70
|
+
function ke(t) {
|
|
71
|
+
return String(t ?? "");
|
|
72
|
+
}
|
|
73
|
+
function Ee(t) {
|
|
74
|
+
if (typeof t == "number") return t;
|
|
75
|
+
if (typeof t == "bigint") return Number(t);
|
|
76
|
+
}
|
|
77
|
+
function Le(t, r, e) {
|
|
78
|
+
if (t)
|
|
79
|
+
return e ? `Top ${r} values — the field searches these, not the column. Filter further for the rest.` : `Top ${r} values — filter further to see the rest.`;
|
|
80
|
+
}
|
|
81
|
+
function Te(t, r, e) {
|
|
82
|
+
return t ? t.map((i) => {
|
|
83
|
+
const a = Be(i) ? i : { value: i };
|
|
84
|
+
return {
|
|
85
|
+
key: String(a.value),
|
|
86
|
+
label: a.label ?? e(a.value),
|
|
87
|
+
raw: a.value,
|
|
88
|
+
icon: a.icon
|
|
89
|
+
};
|
|
90
|
+
}) : (r ?? []).map((i) => ({
|
|
91
|
+
key: String(i.value),
|
|
92
|
+
label: e(i.value),
|
|
93
|
+
raw: i.value,
|
|
94
|
+
count: Ee(i.count)
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
function We(t) {
|
|
98
|
+
const {
|
|
99
|
+
table: r,
|
|
100
|
+
column: e,
|
|
101
|
+
field: i = e,
|
|
102
|
+
as: a,
|
|
103
|
+
filterBy: d,
|
|
104
|
+
options: p,
|
|
105
|
+
format: b = ke,
|
|
106
|
+
label: x = e,
|
|
107
|
+
multiple: y = !0,
|
|
108
|
+
defaultValue: m,
|
|
109
|
+
limit: u = Ie,
|
|
110
|
+
searchable: v = !1,
|
|
111
|
+
disabled: S,
|
|
112
|
+
size: k = "md",
|
|
113
|
+
className: s,
|
|
114
|
+
controlClassName: h,
|
|
115
|
+
children: E,
|
|
116
|
+
slot: P,
|
|
117
|
+
...Q
|
|
118
|
+
} = t, { crossfilter: j } = q(), R = a === void 0 ? j : a, K = d === void 0 ? j : d, g = p === void 0 && !!(r && e), { rows: V, selected: L, publish: w, activate: f } = W({
|
|
119
|
+
as: R,
|
|
120
|
+
filterBy: K,
|
|
121
|
+
deps: [r, e, g, u],
|
|
122
|
+
activateValue: [0],
|
|
123
|
+
build: (n) => g ? G.from(r).select({ value: e, count: ee() }).where(n).groupby(e).orderby(se(ee()), e).limit(u + 1) : null,
|
|
124
|
+
clause: (n, c) => y ? le([i], c == null ? void 0 : c.map((H) => [H]), { source: n }) : oe(i, c == null ? void 0 : c[0], { source: n }),
|
|
125
|
+
decode: (n) => y ? n.map((c) => c[0]) : [n]
|
|
126
|
+
}), T = B(!1);
|
|
127
|
+
N(() => {
|
|
128
|
+
T.current || m === void 0 || (T.current = !0, w(Array.isArray(m) ? m : [m]));
|
|
129
|
+
}, [m, w]);
|
|
130
|
+
const M = L ?? [], F = Te(p, V, b), I = F.length > u, O = I ? F.slice(0, u) : F, $ = O.map((n) => ({
|
|
131
|
+
count: n.count,
|
|
132
|
+
icon: n.icon,
|
|
133
|
+
label: n.label,
|
|
134
|
+
value: n.key
|
|
135
|
+
})), l = new Map(O.map((n) => [n.key, n.raw]));
|
|
136
|
+
for (const n of M) l.set(String(n), n);
|
|
137
|
+
return /* @__PURE__ */ A(
|
|
138
|
+
re.div,
|
|
139
|
+
{
|
|
140
|
+
className: J("w-fit", s),
|
|
141
|
+
...Q,
|
|
142
|
+
...X(f, t),
|
|
143
|
+
"data-slot": P ?? "chart-filter",
|
|
144
|
+
children: [
|
|
145
|
+
/* @__PURE__ */ C(
|
|
146
|
+
ge,
|
|
147
|
+
{
|
|
148
|
+
className: h,
|
|
149
|
+
slot: "chart-filter-trigger",
|
|
150
|
+
disabled: S,
|
|
151
|
+
empty: g && V === null ? "Loading…" : "No values.",
|
|
152
|
+
items: $,
|
|
153
|
+
label: x,
|
|
154
|
+
multiple: y,
|
|
155
|
+
note: Le(I, u, v),
|
|
156
|
+
onValueChange: (n) => w(n.map((c) => l.has(c) ? l.get(c) : c)),
|
|
157
|
+
searchEmpty: I ? `No match among the top ${u} values.` : void 0,
|
|
158
|
+
searchable: v,
|
|
159
|
+
size: k,
|
|
160
|
+
value: M.map((n) => String(n))
|
|
161
|
+
}
|
|
162
|
+
),
|
|
163
|
+
E
|
|
164
|
+
]
|
|
165
|
+
}
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
function Xe(t) {
|
|
169
|
+
const {
|
|
170
|
+
table: r,
|
|
171
|
+
column: e,
|
|
172
|
+
field: i = e,
|
|
173
|
+
as: a,
|
|
174
|
+
filterBy: d,
|
|
175
|
+
type: p = "contains",
|
|
176
|
+
caseSensitive: b = !1,
|
|
177
|
+
label: x,
|
|
178
|
+
placeholder: y = "Search…",
|
|
179
|
+
debounce: m = 200,
|
|
180
|
+
autocompleteLimit: u = 100,
|
|
181
|
+
defaultValue: v,
|
|
182
|
+
disabled: S,
|
|
183
|
+
size: k = "md",
|
|
184
|
+
className: s,
|
|
185
|
+
controlClassName: h,
|
|
186
|
+
children: E,
|
|
187
|
+
slot: P,
|
|
188
|
+
...Q
|
|
189
|
+
} = t, { crossfilter: j } = q(), R = a === void 0 ? j : a, K = d === void 0 ? j : d, g = u > 0 && !!(r && e), { rows: V, selected: L, publish: w, activate: f } = W({
|
|
190
|
+
as: R,
|
|
191
|
+
filterBy: K,
|
|
192
|
+
deps: [r, e, g, u],
|
|
193
|
+
activateValue: "",
|
|
194
|
+
build: (o) => g ? G.from(r).select({ value: e }).distinct().where(o).orderby(e).limit(u) : null,
|
|
195
|
+
clause: (o, z) => ie(i, z ?? null, { source: o, method: p, caseSensitive: b })
|
|
196
|
+
}), T = ne(
|
|
197
|
+
() => (V ?? []).map((o) => ({ label: String(o.value), value: String(o.value) })),
|
|
198
|
+
[V]
|
|
199
|
+
), M = T.length >= u, { contains: F } = de({ sensitivity: "base" }), { collection: I, filter: O, set: $ } = me({ filter: F, initialItems: [] }), l = T.map((o) => o.value).join("\0");
|
|
200
|
+
N(() => {
|
|
201
|
+
$(T);
|
|
202
|
+
}, [l, $]);
|
|
203
|
+
const [n, c] = _(v ?? ""), H = B(v ?? ""), U = B(null);
|
|
204
|
+
N(() => {
|
|
205
|
+
const o = L ?? "";
|
|
206
|
+
o !== H.current && (H.current = o, c(o));
|
|
207
|
+
}, [L]), N(() => () => {
|
|
208
|
+
U.current && clearTimeout(U.current);
|
|
209
|
+
}, []);
|
|
210
|
+
const Y = B(!1);
|
|
211
|
+
N(() => {
|
|
212
|
+
Y.current || !v || (Y.current = !0, w(v));
|
|
213
|
+
}, [v, w]);
|
|
214
|
+
const D = (o) => {
|
|
215
|
+
c(o), U.current && clearTimeout(U.current);
|
|
216
|
+
const z = () => {
|
|
217
|
+
H.current = o, w(o || void 0);
|
|
218
|
+
};
|
|
219
|
+
m > 0 ? U.current = setTimeout(z, m) : z();
|
|
220
|
+
};
|
|
221
|
+
return /* @__PURE__ */ A(
|
|
222
|
+
ye,
|
|
223
|
+
{
|
|
224
|
+
className: J("w-fit min-w-48 gap-1.5", s),
|
|
225
|
+
disabled: S,
|
|
226
|
+
...Q,
|
|
227
|
+
...X(f, t),
|
|
228
|
+
slot: P ?? "chart-search",
|
|
229
|
+
children: [
|
|
230
|
+
x ? /* @__PURE__ */ C(xe, { children: x }) : null,
|
|
231
|
+
g ? (
|
|
232
|
+
// `allowCustomValue`, because this control is a FILTER and not a picker: what it publishes
|
|
233
|
+
// is a match clause over whatever you typed, and the list only ever offered completions.
|
|
234
|
+
// A `<datalist>` was the honest first answer to that and a poor one — unstyleable, different
|
|
235
|
+
// in every browser, no empty state, and silent about its own cap. Same clause, same
|
|
236
|
+
// debounce; only the surface changed.
|
|
237
|
+
/* @__PURE__ */ A(
|
|
238
|
+
fe,
|
|
239
|
+
{
|
|
240
|
+
allowCustomValue: !0,
|
|
241
|
+
collection: I,
|
|
242
|
+
slot: "chart-search-list",
|
|
243
|
+
disabled: S,
|
|
244
|
+
inputValue: n,
|
|
245
|
+
onInputValueChange: (o) => {
|
|
246
|
+
O(o.inputValue), D(o.inputValue);
|
|
247
|
+
},
|
|
248
|
+
onValueChange: (o) => {
|
|
249
|
+
const z = o.value[0];
|
|
250
|
+
z !== void 0 && D(z);
|
|
251
|
+
},
|
|
252
|
+
children: [
|
|
253
|
+
/* @__PURE__ */ C(he, { className: h, placeholder: y, size: k }),
|
|
254
|
+
/* @__PURE__ */ A(pe, { children: [
|
|
255
|
+
/* @__PURE__ */ C(ve, { children: "No matching values." }),
|
|
256
|
+
I.items.map((o) => /* @__PURE__ */ C(be, { item: o, children: o.label }, o.value)),
|
|
257
|
+
M ? /* @__PURE__ */ A("p", { className: "border-t px-2 py-1.5 text-muted-foreground text-xs", children: [
|
|
258
|
+
"First ",
|
|
259
|
+
u,
|
|
260
|
+
". Keep typing to narrow it."
|
|
261
|
+
] }) : null
|
|
262
|
+
] })
|
|
263
|
+
]
|
|
264
|
+
}
|
|
265
|
+
)
|
|
266
|
+
) : /* @__PURE__ */ C(
|
|
267
|
+
Ce,
|
|
268
|
+
{
|
|
269
|
+
className: h,
|
|
270
|
+
disabled: S,
|
|
271
|
+
onChange: (o) => D(o.target.value),
|
|
272
|
+
placeholder: y,
|
|
273
|
+
size: k,
|
|
274
|
+
type: "search",
|
|
275
|
+
value: n
|
|
276
|
+
}
|
|
277
|
+
),
|
|
278
|
+
E
|
|
279
|
+
]
|
|
280
|
+
}
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
function Me(t, r) {
|
|
284
|
+
return Number.isInteger(t) && Number.isInteger(r) ? 1 : (r - t) / 500 || 1;
|
|
285
|
+
}
|
|
286
|
+
function Ye(t) {
|
|
287
|
+
const {
|
|
288
|
+
table: r,
|
|
289
|
+
column: e,
|
|
290
|
+
field: i = e,
|
|
291
|
+
as: a,
|
|
292
|
+
filterBy: d,
|
|
293
|
+
select: p = "point",
|
|
294
|
+
min: b,
|
|
295
|
+
max: x,
|
|
296
|
+
step: y,
|
|
297
|
+
defaultValue: m,
|
|
298
|
+
label: u,
|
|
299
|
+
showValue: v = !0,
|
|
300
|
+
disabled: S,
|
|
301
|
+
className: k,
|
|
302
|
+
children: s,
|
|
303
|
+
slot: h,
|
|
304
|
+
...E
|
|
305
|
+
} = t, { crossfilter: P } = q(), Q = a === void 0 ? P : a, j = d === void 0 ? P : d, R = (b === void 0 || x === void 0) && !!(r && e), K = B(1), { rows: g, selected: V, publish: L, activate: w } = W({
|
|
306
|
+
as: Q,
|
|
307
|
+
filterBy: j,
|
|
308
|
+
deps: [r, e, R],
|
|
309
|
+
activateValue: p === "interval" ? [0, 0] : 0,
|
|
310
|
+
build: (l) => R ? G.select({ min: ue(e), max: ae(e) }).from(r).where(l) : null,
|
|
311
|
+
clause: (l, n) => {
|
|
312
|
+
if (p !== "interval") return oe(i, n, { source: l });
|
|
313
|
+
const c = n;
|
|
314
|
+
return ce(i, c ?? null, {
|
|
315
|
+
source: l,
|
|
316
|
+
bin: "ceil",
|
|
317
|
+
scale: c ? { type: "identity", domain: c } : void 0,
|
|
318
|
+
pixelSize: K.current
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
}), f = ne(() => {
|
|
322
|
+
const l = g == null ? void 0 : g[0], n = b ?? (typeof (l == null ? void 0 : l.min) == "number" ? l.min : void 0), c = x ?? (typeof (l == null ? void 0 : l.max) == "number" ? l.max : void 0);
|
|
323
|
+
return n === void 0 || c === void 0 ? null : { min: n, max: c, step: y ?? Me(n, c) };
|
|
324
|
+
}, [g, b, x, y]);
|
|
325
|
+
N(() => {
|
|
326
|
+
K.current = (f == null ? void 0 : f.step) ?? 1;
|
|
327
|
+
}, [f]);
|
|
328
|
+
const [T, M] = _(
|
|
329
|
+
m === void 0 ? null : [...te(m)]
|
|
330
|
+
), F = B(!1);
|
|
331
|
+
N(() => {
|
|
332
|
+
if (V !== void 0) {
|
|
333
|
+
F.current = !0, M([...te(V)]);
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
F.current && (F.current = !1, M(null));
|
|
337
|
+
}, [V]);
|
|
338
|
+
const I = B(!1);
|
|
339
|
+
N(() => {
|
|
340
|
+
I.current || m === void 0 || (I.current = !0, L(m));
|
|
341
|
+
}, [m, L]);
|
|
342
|
+
const O = (l) => {
|
|
343
|
+
M(l), L(p === "interval" ? [l[0], l[1]] : l[0]);
|
|
344
|
+
}, $ = T ?? (f ? p === "interval" ? [f.min, f.max] : [f.min] : null);
|
|
345
|
+
return /* @__PURE__ */ A(
|
|
346
|
+
re.div,
|
|
347
|
+
{
|
|
348
|
+
className: J("flex w-full min-w-48 flex-col gap-1.5", k),
|
|
349
|
+
...E,
|
|
350
|
+
...X(w, t),
|
|
351
|
+
"data-slot": h ?? "chart-slider",
|
|
352
|
+
children: [
|
|
353
|
+
f && $ ? /* @__PURE__ */ C(
|
|
354
|
+
Se,
|
|
355
|
+
{
|
|
356
|
+
disabled: S,
|
|
357
|
+
max: f.max,
|
|
358
|
+
min: f.min,
|
|
359
|
+
onValueChange: (l) => O(l.value),
|
|
360
|
+
step: f.step,
|
|
361
|
+
value: $,
|
|
362
|
+
children: u || v ? /* @__PURE__ */ A("div", { className: "flex items-center", children: [
|
|
363
|
+
u ? /* @__PURE__ */ C(Ve, { children: u }) : null,
|
|
364
|
+
v ? /* @__PURE__ */ C(we, {}) : null
|
|
365
|
+
] }) : null
|
|
366
|
+
}
|
|
367
|
+
) : /* @__PURE__ */ C(Ne, { className: "h-2 w-full rounded-full" }),
|
|
368
|
+
s
|
|
369
|
+
]
|
|
370
|
+
}
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
function te(t) {
|
|
374
|
+
return typeof t == "number" ? [t] : t;
|
|
375
|
+
}
|
|
376
|
+
export {
|
|
377
|
+
We as ChartFilter,
|
|
378
|
+
Xe as ChartSearch,
|
|
379
|
+
Ye as ChartSlider,
|
|
380
|
+
W as useMosaicInput
|
|
381
|
+
};
|
|
382
|
+
//# sourceMappingURL=chart-inputs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-inputs.js","sources":["../../src/charts/chart-inputs.tsx"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from \"react\";\nimport type React from \"react\";\nimport { ark } from \"@ark-ui/react/factory\";\nimport {\n clauseInterval,\n clauseMatch,\n clausePoint,\n clausePoints,\n MosaicClient,\n type Selection,\n type SelectionClause,\n} from \"@uwdata/mosaic-core\";\nimport {\n count as sqlCount,\n desc as sqlDesc,\n max as sqlMax,\n min as sqlMin,\n Query,\n type FilterExpr,\n} from \"@uwdata/mosaic-sql\";\nimport { useListCollection } from \"@ark-ui/react/collection\";\nimport { useFilter } from \"@ark-ui/react/locale\";\nimport { cn } from \"../lib/cn.js\";\nimport {\n Combobox,\n ComboboxContent,\n ComboboxEmpty,\n ComboboxInput,\n ComboboxItem,\n} from \"../simples/combobox.js\";\nimport { FacetFilter, type FacetFilterItem } from \"../simples/FacetFilter.js\";\nimport { Field, FieldLabel } from \"../simples/field.js\";\nimport { Input } from \"../simples/input.js\";\nimport { Skeleton } from \"../simples/skeleton.js\";\nimport { Slider, SliderLabel, SliderValue } from \"../simples/slider.js\";\nimport { useMosaic } from \"./mosaic-provider.js\";\nimport { ChartQueryClient, type ChartQueryRow as QueryRow } from \"./query-client.js\";\n\n/**\n * Mosaic **inputs** — controls that publish into a `Selection` without being charts.\n *\n * Unlike marks and interactors, these are real DOM parts (`ark.*`, `data-slot`, forwarded props),\n * not inert descriptors: they carry no `__chart` static and belong *outside* `<ChartRoot>`. What\n * makes them Mosaic and not just a styled `<select>` is that each one is a `MosaicClient`: it\n * declares a `query()` for the values it needs (grouped counts, distinct values, a numeric extent),\n * the coordinator answers it, and the control publishes `clausePoints` / `clauseMatch` /\n * `clauseInterval` back into the selection the charts filter by.\n *\n * The vgplot equivalents (`vg.menu`, `vg.search`, `vg.slider`) build raw HTML. These use our\n * controls, our tokens and our accessibility, and are controllable *and* observable: an external\n * change to the selection flows back into the widget.\n */\n\n\nexport interface MosaicInputOptions<T> {\n /** Filters the widget's own lookup query. `null` = the full relation. */\n filterBy: Selection | null;\n /** Where the widget publishes. `null` = nowhere. */\n as: Selection | null;\n /** The lookup query, or `null` when there is nothing to ask the coordinator for. */\n build: (filter: FilterExpr) => Query | null;\n /** Rebuilds the client — and re-runs the lookup — when any entry changes. */\n deps: readonly unknown[];\n clause: (source: MosaicClient, value: T | undefined) => SelectionClause;\n /** The representative value of the warm-up clause published on hover/focus. */\n activateValue: T;\n /** Reads the widget's own clause value back out of the selection. Defaults to an identity cast. */\n decode?: (value: unknown) => T;\n}\n\nexport interface MosaicInputState<T> {\n /** Lookup rows, or `null` while the query is in flight (or when there is no query). */\n rows: readonly QueryRow[] | null;\n /** The value this widget currently holds in the selection — its observable half. */\n selected: T | undefined;\n publish: (value: T | undefined) => void;\n activate: () => void;\n}\n\n/**\n * The conversation with Mosaic that every input in this file has: a lookup query that re-runs under\n * the crossfilter, a clause published with `source` set so a control never filters itself, and a\n * warm-up so the first interaction is not the first query.\n *\n * Exported because the three controls here are surfaces over it, not the only surfaces it allows —\n * a chip row, a segmented switch or a map lasso is the same conversation with different chrome, and\n * without this the alternative is reimplementing it.\n */\nexport function useMosaicInput<T>(\n options: MosaicInputOptions<T>\n): MosaicInputState<T> {\n const { filterBy, as, deps } = options;\n const { coordinator } = useMosaic();\n const latest = useRef(options);\n latest.current = options;\n\n const clientRef = useRef<ChartQueryClient | null>(null);\n const [client, setClient] = useState<ChartQueryClient | null>(null);\n const [rows, setRows] = useState<readonly QueryRow[] | null>(null);\n const [selected, setSelected] = useState<T | undefined>(undefined);\n\n useEffect(() => {\n const instance = new ChartQueryClient(\n filterBy ?? undefined,\n (filter) => latest.current.build(filter),\n setRows,\n );\n clientRef.current = instance;\n setRows(null);\n setClient(instance);\n coordinator.connect(instance);\n return () => {\n clientRef.current = null;\n coordinator.disconnect(instance);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [coordinator, filterBy, ...deps]);\n\n useEffect(() => {\n if (!as || !client) return;\n const sync = () => {\n const raw = as.valueFor(client);\n const { decode } = latest.current;\n setSelected(raw === undefined ? undefined : decode ? decode(raw) : (raw as T));\n };\n sync();\n as.addEventListener(\"value\", sync);\n return () => {\n as.removeEventListener(\"value\", sync);\n // `Selection.remove` returns a *clone*; the live way to retract a clause is to publish an\n // empty one, which the resolver drops because its predicate is null.\n if (as.valueFor(client) !== undefined) as.update(latest.current.clause(client, undefined));\n };\n }, [as, client]);\n\n const publish = useCallback(\n (value: T | undefined) => {\n setSelected(value);\n const instance = clientRef.current;\n if (as && instance) as.update(latest.current.clause(instance, value));\n },\n [as],\n );\n\n const activate = useCallback(() => {\n const instance = clientRef.current;\n if (as && instance) as.activate(latest.current.clause(instance, latest.current.activateValue));\n }, [as]);\n\n return { rows, selected, publish, activate };\n}\n\n/** vgplot's inputs warm the selection on hover/focus; ours do it on the wrapper, and compose. */\nfunction warmUpHandlers(\n activate: () => void,\n props: Pick<React.ComponentProps<typeof ark.div>, \"onFocus\" | \"onPointerEnter\">,\n) {\n return {\n onFocus: (event: React.FocusEvent<HTMLDivElement>) => {\n props.onFocus?.(event);\n activate();\n },\n onPointerEnter: (event: React.PointerEvent<HTMLDivElement>) => {\n props.onPointerEnter?.(event);\n if (!event.buttons) activate();\n },\n };\n}\n\ninterface SelectionProps {\n /** Where the control publishes. Defaults to the provider's crossfilter; `null` = nowhere. */\n as?: Selection | null;\n /** What the control's own lookup filters by. Defaults to the crossfilter; `null` = unfiltered. */\n filterBy?: Selection | null;\n}\n\ntype ControlSize = \"sm\" | \"md\" | \"lg\";\n\n// ── ChartFilter ──────────────────────────────────────────────────────────────\n\n/** An explicit entry. Bare values work too — they are labelled by `format`. */\nexport interface ChartFilterOption {\n value: unknown;\n label?: string;\n icon?: React.ComponentType<{ className?: string }>;\n}\n\nexport interface ChartFilterProps\n extends Omit<React.ComponentProps<typeof ark.div>, \"defaultValue\">,\n SelectionProps {\n /** The relation the values and their counts come from. */\n table?: string;\n /** The column grouped by. */\n column?: string;\n /** The column named in the published clause. Defaults to `column`. */\n field?: string;\n /** Explicit options — a literal value or a `{ value, label, icon }` object. Skips the lookup. */\n options?: readonly unknown[];\n /** Labels an option value that carries no explicit label. */\n format?: (value: unknown) => string;\n /** Trigger label. Defaults to `column`. */\n label?: ReactNode;\n /** Tick any number of values (an `IN` list). `false` keeps at most one ticked. */\n multiple?: boolean;\n /** Published once, when the control first connects. A bare value or an array of them. */\n defaultValue?: unknown;\n /** Most-frequent values kept; past this the list says so rather than rendering the tail. */\n limit?: number;\n /**\n * Draw a filter field above the values.\n *\n * It narrows **the fetched page** — the `limit` most frequent values this control asked for — and\n * runs no query of its own. When the page is truncated the note and the no-match message say so,\n * because a field that answers \"no matching values\" about a database it never asked is worse than\n * no field. Searching the column itself is `ChartSearch`, which publishes a match clause.\n *\n * @default false\n */\n searchable?: boolean;\n disabled?: boolean;\n size?: ControlSize;\n /** Class for the trigger; `className` styles the wrapper. */\n controlClassName?: string;\n}\n\n/**\n * A `GROUP BY` over a high-cardinality column can answer with thousands of rows, and neither the\n * wire nor the DOM wants them. The lookup is capped at the *most frequent* values — the ones a\n * facet is for — and the control owns up to the truncation instead of pretending the tail is\n * absent. Needle-in-a-haystack lookup is `ChartSearch`'s job, not a facet filter's.\n */\nconst FILTER_LIMIT = 50;\n\ninterface FilterEntry {\n key: string;\n label: string;\n raw: unknown;\n count?: number;\n icon?: React.ComponentType<{ className?: string }>;\n}\n\nfunction isOptionObject(value: unknown): value is ChartFilterOption {\n return typeof value === \"object\" && value !== null && !Array.isArray(value) && \"value\" in value;\n}\n\nfunction defaultFormat(value: unknown): string {\n return String(value ?? \"\");\n}\n\n/** DuckDB answers a `count(*)` with a BigInt over the WASM bridge. */\nfunction toCount(value: unknown): number | undefined {\n if (typeof value === \"number\") return value;\n if (typeof value === \"bigint\") return Number(value);\n return undefined;\n}\n\nfunction truncationNote(truncated: boolean, limit: number, searchable: boolean) {\n if (!truncated) return undefined;\n return searchable\n ? `Top ${limit} values — the field searches these, not the column. Filter further for the rest.`\n : `Top ${limit} values — filter further to see the rest.`;\n}\n\nfunction filterEntries(\n options: readonly unknown[] | undefined,\n rows: readonly QueryRow[] | null,\n format: (value: unknown) => string,\n): FilterEntry[] {\n if (options) {\n return options.map((entry) => {\n const option = isOptionObject(entry) ? entry : { value: entry };\n return {\n key: String(option.value),\n label: option.label ?? format(option.value),\n raw: option.value,\n icon: option.icon,\n };\n });\n }\n return (rows ?? []).map((row) => ({\n key: String(row.value),\n label: format(row.value),\n raw: row.value,\n count: toCount(row.count),\n }));\n}\n\n/**\n * A facet filter over a column's values, publishing a **points** clause — the same `FacetFilter`\n * surface as the table's, so a dashboard has one filter idiom rather than two.\n *\n * The values are a query, not a prop: the control connects as a Mosaic client and asks for\n * `SELECT <column>, count(*) … GROUP BY <column>` filtered by `filterBy`. The counts therefore\n * react to the *other* filters but not to this one — a crossfilter resolver drops a clause when it\n * builds the predicate for the clause's own source, and `clausePoints` tags the clause with this\n * client. (A non-crossfilter `filterBy` has no such exemption and would count itself.)\n */\nexport function ChartFilter(props: ChartFilterProps) {\n const {\n table,\n column,\n field = column,\n as,\n filterBy,\n options,\n format = defaultFormat,\n label = column,\n multiple = true,\n defaultValue,\n limit = FILTER_LIMIT,\n searchable = false,\n disabled,\n size = \"md\",\n className,\n controlClassName,\n children,\n slot,\n ...rest\n } = props;\n const { crossfilter } = useMosaic();\n const target = as === undefined ? crossfilter : as;\n const source = filterBy === undefined ? crossfilter : filterBy;\n const lookup = options === undefined && Boolean(table && column);\n\n const { rows, selected, publish, activate } = useMosaicInput<readonly unknown[]>({\n as: target,\n filterBy: source,\n deps: [table, column, lookup, limit],\n activateValue: [0],\n build: (filter) =>\n lookup\n ? Query.from(table as string)\n .select({ value: column as string, count: sqlCount() })\n .where(filter)\n .groupby(column as string)\n .orderby(sqlDesc(sqlCount()), column as string)\n // One past the cap: enough to know the tail exists without asking a second question.\n .limit(limit + 1)\n : null,\n clause: (client, value) =>\n multiple\n ? clausePoints([field as string], value?.map((entry) => [entry]), { source: client })\n : clausePoint(field as string, value?.[0], { source: client }),\n decode: (value) => (multiple ? (value as unknown[][]).map((tuple) => tuple[0]) : [value]),\n });\n\n const primed = useRef(false);\n useEffect(() => {\n if (primed.current || defaultValue === undefined) return;\n primed.current = true;\n publish(Array.isArray(defaultValue) ? (defaultValue as unknown[]) : [defaultValue]);\n }, [defaultValue, publish]);\n\n const values = selected ?? [];\n\n const fetched = filterEntries(options, rows, format);\n const truncated = fetched.length > limit;\n const entries = truncated ? fetched.slice(0, limit) : fetched;\n const items: FacetFilterItem[] = entries.map((entry) => ({\n count: entry.count,\n icon: entry.icon,\n label: entry.label,\n value: entry.key,\n }));\n\n // `FacetFilter` speaks strings; a clause carries the raw value the query answered with, so the\n // way back from a ticked row to `alpha` / `3` / `true` is this map. The selected values are in it\n // too: one of them may be a value the crossfilter has since faceted away, which `FacetFilter`\n // keeps listed so it can still be unticked.\n const raw = new Map<string, unknown>(entries.map((entry) => [entry.key, entry.raw]));\n for (const value of values) raw.set(String(value), value);\n\n return (\n <ark.div\n className={cn(\"w-fit\", className)}\n {...rest}\n {...warmUpHandlers(activate, props)}\n data-slot={slot ?? \"chart-filter\"}\n >\n <FacetFilter\n className={controlClassName}\n slot=\"chart-filter-trigger\"\n disabled={disabled}\n empty={lookup && rows === null ? \"Loading…\" : \"No values.\"}\n items={items}\n label={label}\n multiple={multiple}\n // A search field over a truncated list is a half-truth unless it names its own scope, so\n // both messages change when the tail was dropped: the field covers the fetched page, and a\n // miss inside it says nothing about the column.\n note={truncationNote(truncated, limit, searchable)}\n onValueChange={(next) => publish(next.map((key) => (raw.has(key) ? raw.get(key) : key)))}\n searchEmpty={truncated ? `No match among the top ${limit} values.` : undefined}\n searchable={searchable}\n size={size}\n value={values.map((value) => String(value))}\n />\n {children}\n </ark.div>\n );\n}\n\n// ── ChartSearch ──────────────────────────────────────────────────────────────\n\nexport interface ChartSearchProps\n extends Omit<React.ComponentProps<typeof ark.div>, \"defaultValue\">,\n SelectionProps {\n /** The relation the autocomplete values come from. */\n table?: string;\n /** The column to search. */\n column?: string;\n /** The column named in the published clause. Defaults to `column`. */\n field?: string;\n /** Where the query string has to appear. */\n type?: \"contains\" | \"prefix\" | \"suffix\" | \"regexp\";\n caseSensitive?: boolean;\n label?: ReactNode;\n placeholder?: string;\n /** ms of quiet before publishing. `0` publishes on every keystroke, as vgplot does. */\n debounce?: number;\n /** Distinct values offered as a native autocomplete list. `0` skips the lookup entirely. */\n autocompleteLimit?: number;\n defaultValue?: string;\n disabled?: boolean;\n size?: ControlSize;\n /** Class for the control; `className` styles the wrapper. */\n controlClassName?: string;\n}\n\n/**\n * A text box publishing a **match** clause (`contains` / `prefix` / `suffix` / `regexp`).\n *\n * Every keystroke is a query, so the publish is debounced by default. The distinct values of the\n * column feed a native `<datalist>`, exactly as vgplot's `search` does — and, as there, the list\n * narrows with the query, since a match clause does not exempt its own client from the crossfilter.\n */\nexport function ChartSearch(props: ChartSearchProps) {\n const {\n table,\n column,\n field = column,\n as,\n filterBy,\n type = \"contains\",\n caseSensitive = false,\n label,\n placeholder = \"Search…\",\n debounce = 200,\n autocompleteLimit = 100,\n defaultValue,\n disabled,\n size = \"md\",\n className,\n controlClassName,\n children,\n slot,\n ...rest\n } = props;\n const { crossfilter } = useMosaic();\n const target = as === undefined ? crossfilter : as;\n const source = filterBy === undefined ? crossfilter : filterBy;\n const lookup = autocompleteLimit > 0 && Boolean(table && column);\n\n const { rows, selected, publish, activate } = useMosaicInput<string>({\n as: target,\n filterBy: source,\n deps: [table, column, lookup, autocompleteLimit],\n activateValue: \"\",\n build: (filter) =>\n lookup\n ? Query.from(table as string)\n .select({ value: column as string })\n .distinct()\n .where(filter)\n .orderby(column as string)\n .limit(autocompleteLimit)\n : null,\n clause: (client, value) =>\n clauseMatch(field as string, value ?? null, { source: client, method: type, caseSensitive }),\n });\n\n // The completions, filtered in the browser. The query already asked the database for the\n // `autocompleteLimit` distinct values of the column; narrowing THOSE as you type is not a second\n // question, so it does not become a second query.\n const items = useMemo(\n () => (rows ?? []).map((row) => ({ label: String(row.value), value: String(row.value) })),\n [rows],\n );\n const capped = items.length >= autocompleteLimit;\n const { contains } = useFilter({ sensitivity: \"base\" });\n const { collection, filter: completions, set } = useListCollection<{\n label: string;\n value: string;\n }>({ filter: contains, initialItems: [] });\n\n // Keyed on the values, not on the array: `rows` is a fresh array on every settled query, and\n // setting the collection from an identity-unstable dep is a render loop.\n const itemsKey = items.map((item) => item.value).join(\"\\u0000\");\n useEffect(() => {\n set(items);\n // `items` is derived from `itemsKey`; depending on it directly is the loop above.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [itemsKey, set]);\n\n const [text, setText] = useState(defaultValue ?? \"\");\n const published = useRef(defaultValue ?? \"\");\n const timer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n const external = selected ?? \"\";\n if (external !== published.current) {\n published.current = external;\n setText(external);\n }\n }, [selected]);\n\n useEffect(() => () => { if (timer.current) clearTimeout(timer.current); }, []);\n\n const primed = useRef(false);\n useEffect(() => {\n if (primed.current || !defaultValue) return;\n primed.current = true;\n publish(defaultValue);\n }, [defaultValue, publish]);\n\n const change = (next: string) => {\n setText(next);\n if (timer.current) clearTimeout(timer.current);\n const send = () => {\n published.current = next;\n publish(next || undefined);\n };\n if (debounce > 0) timer.current = setTimeout(send, debounce);\n else send();\n };\n\n return (\n <Field\n className={cn(\"w-fit min-w-48 gap-1.5\", className)}\n disabled={disabled}\n {...rest}\n {...warmUpHandlers(activate, props)}\n slot={slot ?? \"chart-search\"}\n >\n {label ? <FieldLabel>{label}</FieldLabel> : null}\n {lookup ? (\n // `allowCustomValue`, because this control is a FILTER and not a picker: what it publishes\n // is a match clause over whatever you typed, and the list only ever offered completions.\n // A `<datalist>` was the honest first answer to that and a poor one — unstyleable, different\n // in every browser, no empty state, and silent about its own cap. Same clause, same\n // debounce; only the surface changed.\n <Combobox\n allowCustomValue\n collection={collection}\n slot=\"chart-search-list\"\n disabled={disabled}\n inputValue={text}\n onInputValueChange={(details) => {\n completions(details.inputValue);\n change(details.inputValue);\n }}\n onValueChange={(details) => {\n const picked = details.value[0];\n if (picked !== undefined) change(picked);\n }}\n >\n <ComboboxInput className={controlClassName} placeholder={placeholder} size={size} />\n <ComboboxContent>\n <ComboboxEmpty>No matching values.</ComboboxEmpty>\n {collection.items.map((item) => (\n <ComboboxItem item={item} key={item.value}>\n {item.label}\n </ComboboxItem>\n ))}\n {/* The cap, said out loud. The datalist could not: it silently stopped at its limit,\n so \"nothing else matches\" and \"nothing else was asked for\" looked identical. */}\n {capped ? (\n <p className=\"border-t px-2 py-1.5 text-muted-foreground text-xs\">\n First {autocompleteLimit}. Keep typing to narrow it.\n </p>\n ) : null}\n </ComboboxContent>\n </Combobox>\n ) : (\n <Input\n className={controlClassName}\n disabled={disabled}\n onChange={(event) => change(event.target.value)}\n placeholder={placeholder}\n size={size}\n type=\"search\"\n value={text}\n />\n )}\n {children}\n </Field>\n );\n}\n\n// ── ChartSlider ──────────────────────────────────────────────────────────────\n\nexport interface ChartSliderProps\n extends Omit<React.ComponentProps<typeof ark.div>, \"defaultValue\">,\n SelectionProps {\n /** The relation the extent comes from, when `min`/`max` are not both given. */\n table?: string;\n /** The numeric column. */\n column?: string;\n /** The column named in the published clause. Defaults to `column`. */\n field?: string;\n /**\n * `point` publishes an equality clause for one thumb; `interval` publishes a two-thumb range.\n * (vgplot's slider only ever offers `[min, value]`; ours brushes a real interval.)\n */\n select?: \"point\" | \"interval\";\n min?: number;\n max?: number;\n step?: number;\n /** Published once, when the control first connects. */\n defaultValue?: number | readonly [number, number];\n label?: ReactNode;\n /** Show the current value beside the label. */\n showValue?: boolean;\n disabled?: boolean;\n}\n\ntype SliderValueType = number | readonly [number, number];\n\ninterface SliderExtent {\n min: number;\n max: number;\n step: number;\n}\n\n/** vgplot's `(max - min) / 500`, except an all-integer extent steps by 1 — 500 fractions of a count is noise. */\nfunction defaultStep(min: number, max: number): number {\n if (Number.isInteger(min) && Number.isInteger(max)) return 1;\n return (max - min) / 500 || 1;\n}\n\n/**\n * A slider over a numeric column, publishing a **point** or **interval** clause.\n *\n * The extent is a query when `min`/`max` are not both given: `SELECT min(col), max(col)`, answered\n * by the coordinator. A `Skeleton` shaped like the track holds the space until it arrives.\n */\nexport function ChartSlider(props: ChartSliderProps) {\n const {\n table,\n column,\n field = column,\n as,\n filterBy,\n select = \"point\",\n min,\n max,\n step,\n defaultValue,\n label,\n showValue = true,\n disabled,\n className,\n children,\n slot,\n ...rest\n } = props;\n const { crossfilter } = useMosaic();\n const target = as === undefined ? crossfilter : as;\n const source = filterBy === undefined ? crossfilter : filterBy;\n const lookup = (min === undefined || max === undefined) && Boolean(table && column);\n // The binning hint for the interval clause. A ref, not `extent` itself: reading the memo from\n // the clause would make the widget's own row type circular.\n const pixelSize = useRef(1);\n\n const { rows, selected, publish, activate } = useMosaicInput<SliderValueType>({\n as: target,\n filterBy: source,\n deps: [table, column, lookup],\n activateValue: select === \"interval\" ? ([0, 0] as const) : 0,\n build: (filter) =>\n lookup\n ? Query.select({ min: sqlMin(column as string), max: sqlMax(column as string) })\n .from(table as string)\n .where(filter)\n : null,\n clause: (client, value) => {\n if (select !== \"interval\") return clausePoint(field as string, value, { source: client });\n const domain = value as [number, number] | undefined;\n return clauseInterval(field as string, domain ?? null, {\n source: client,\n bin: \"ceil\",\n scale: domain ? { type: \"identity\", domain } : undefined,\n pixelSize: pixelSize.current,\n });\n },\n });\n\n const extent = useMemo<SliderExtent | null>(() => {\n const row = rows?.[0];\n const low = min ?? (typeof row?.min === \"number\" ? row.min : undefined);\n const high = max ?? (typeof row?.max === \"number\" ? row.max : undefined);\n if (low === undefined || high === undefined) return null;\n return { min: low, max: high, step: step ?? defaultStep(low, high) };\n }, [rows, min, max, step]);\n\n useEffect(() => {\n pixelSize.current = extent?.step ?? 1;\n }, [extent]);\n\n const [values, setValues] = useState<number[] | null>(\n defaultValue === undefined ? null : [...toValues(defaultValue)],\n );\n /** Distinguishes \"never published\" from \"published and then cleared\" — see the effect below. */\n const held = useRef(false);\n\n useEffect(() => {\n if (selected !== undefined) {\n held.current = true;\n setValues([...toValues(selected)]);\n return;\n }\n // The clause is gone: a `Selection.reset()`, a \"Clear filters\" button, another control\n // retracting it. Fall back to the extent instead of leaving the thumbs where they were — a\n // slider that still reads 5–22 while nothing is filtered is a control lying about the state,\n // which is worse than one that never moved. Gated on `held` so the first render does not\n // stomp on `defaultValue` before the priming effect has published it.\n if (held.current) {\n held.current = false;\n setValues(null);\n }\n }, [selected]);\n\n const primed = useRef(false);\n useEffect(() => {\n if (primed.current || defaultValue === undefined) return;\n primed.current = true;\n publish(defaultValue);\n }, [defaultValue, publish]);\n\n const change = (next: number[]) => {\n setValues(next);\n publish(select === \"interval\" ? [next[0] as number, next[1] as number] : (next[0] as number));\n };\n\n const shown = values ?? (extent ? (select === \"interval\" ? [extent.min, extent.max] : [extent.min]) : null);\n\n return (\n <ark.div\n className={cn(\"flex w-full min-w-48 flex-col gap-1.5\", className)}\n {...rest}\n {...warmUpHandlers(activate, props)}\n data-slot={slot ?? \"chart-slider\"}\n >\n {extent && shown ? (\n <Slider\n disabled={disabled}\n max={extent.max}\n min={extent.min}\n onValueChange={(details) => change(details.value)}\n step={extent.step}\n value={shown}\n >\n {label || showValue ? (\n <div className=\"flex items-center\">\n {label ? <SliderLabel>{label}</SliderLabel> : null}\n {showValue ? <SliderValue /> : null}\n </div>\n ) : null}\n </Slider>\n ) : (\n <Skeleton className=\"h-2 w-full rounded-full\" />\n )}\n {children}\n </ark.div>\n );\n}\n\nfunction toValues(value: SliderValueType): readonly number[] {\n return typeof value === \"number\" ? [value] : value;\n}\n"],"names":["min","max"],"mappings":";;;;;;;;;;;;;;;;;AA0FO;AAGL;AAGA;AAEA;AAKA;AACE;AAAqB;AACP;AAC2B;AACvC;AAEF;AAKE;AAC+B;AACjC;AAKA;AACA;AACE;AAEA;AAA6E;AAE/E;AAGE;AAGyF;AAC3F;AAGF;AAAgB;AAEZ;AACA;AACA;AAAoE;AACtE;AACG;AAIH;AACA;AAA6F;AAG/F;AACF;AAGA;AAIE;AAAO;;AAEH;AACA;AACF;;AAEE;AACoB;AACtB;AAEJ;AAgEA;AAUA;AACE;AACF;AAEA;AACE;AACF;AAGA;AACE;AACA;AAEF;AAEA;AACE;AACA;AAGF;AAEA;AAKE;AAEI;AACA;AAAO;AACmB;AACkB;AAC9B;AACC;AAAA;AAIe;AACX;AACE;AACd;AACe;AAE5B;AAYO;AACL;AAAM;AACJ;AACA;AACQ;AACR;AACA;AACA;AACS;AACD;AACG;AACX;AACQ;AACK;AACb;AACO;AACP;AACA;AACA;AACA;AACG;AAO4E;AAC3E;AACM;AACyB;AAClB;AAUX;AAI2D;AACsB;AAIzF;AACE;AAEkF;AAGpF;AAKyD;AAC1C;AACD;AACC;AACA;AAQf;AAEA;AACE;AAAK;AAAJ;AACiC;AAC5B;AAC8B;AACf;AAEnB;AAAA;AAAC;AAAA;AACY;AACN;AACL;AAC8C;AAC9C;AACA;AACA;AAIiD;AACsC;AAClB;AACrE;AACA;AAC0C;AAAA;AAAA;AAE3C;AAAA;AAAA;AAGP;AAoCO;AACL;AAAM;AACJ;AACA;AACQ;AACR;AACA;AACO;AACS;AAChB;AACc;AACH;AACS;AACpB;AACA;AACO;AACP;AACA;AACA;AACA;AACG;AAOgE;AAC/D;AACM;AACqC;AAChC;AAST;AAEuF;AAMjF;AAC4E;AACnF;AAYP;AACE;AAAS;AAKX;AAIA;AACE;AACA;AAEkB;AAII;AAA6C;AAErE;AACA;AACE;AAEoB;AAGtB;AACE;AAEA;AACE;AACyB;AAE3B;AACK;AAGP;AACE;AAAC;AAAA;AACkD;AACjD;AACI;AAC8B;AACpB;AAEb;AAA2C;AAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAMC;AAAC;AAAA;AACiB;AAChB;AACK;AACL;AACY;AAEV;AACyB;AAC3B;AAEE;AACA;AAAuC;AACzC;AAEA;AAAkF;AAEhF;AAAkC;AAKjC;AAImE;AAAA;AACzD;AAAkB;AAEzB;AACN;AAAA;AAAA;AAAA;AAGF;AAAC;AAAA;AACY;AACX;AAC8C;AAC9C;AACA;AACK;AACE;AAAA;AAAA;AAGV;AAAA;AAAA;AAGP;AAsCA;AACE;AAEF;AAQO;AACL;AAAM;AACJ;AACA;AACQ;AACR;AACA;AACS;AACTA;AACAC;AACA;AACA;AACA;AACY;AACZ;AACA;AACA;AACA;AACG;AAUyE;AACxE;AACM;AACkB;AAC+B;AAMrD;AAEJ;AACA;AACA;AAAuD;AAC7C;AACH;AAC0C;AAC1B;AACtB;AACH;AAIA;AAGA;AACiE;AAGnE;AACE;AAAoC;AAGtC;AAA4B;AACoC;AAKhE;AACE;AACE;AAEA;AAAA;AAOF;AAEgB;AAIlB;AACA;AACE;AAEoB;AAGtB;AACE;AAC4F;AAK9F;AACE;AAAK;AAAJ;AACiE;AAC5D;AAC8B;AACf;AAElB;AACC;AAAC;AAAA;AACC;AACY;AACA;AACoC;AACnC;AACN;AAIF;AAA6C;AACf;AAE/B;AAAA;AAGwC;AAE/C;AAAA;AAAA;AAGP;AAEA;AACE;AACF;;;;;;;"}
|