@awc-ui/core 1.0.0-beta.2 → 1.0.0-beta.4
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 +18 -0
- package/dist/cjs/app-globals-V2Kpy_OQ.js +8 -0
- package/dist/cjs/app-globals-V2Kpy_OQ.js.map +1 -0
- package/dist/cjs/engine.wasm-9JtXME10.js +12 -0
- package/dist/cjs/engine.wasm-9JtXME10.js.map +1 -0
- package/dist/cjs/{index-DlQ_5_Mv.js → index-Bm07YAg9.js} +4 -15
- package/dist/cjs/index-Bm07YAg9.js.map +1 -0
- package/dist/cjs/lazy-loading-indicator-CoC-_DMs.js +69 -0
- package/dist/cjs/lazy-loading-indicator-CoC-_DMs.js.map +1 -0
- package/dist/cjs/loader.cjs.js +4 -3
- package/dist/cjs/loader.cjs.js.map +1 -1
- package/dist/cjs/md-accordion-item.cjs.entry.js +4 -4
- package/dist/cjs/md-accordion.cjs.entry.js +1 -1
- package/dist/cjs/md-app-bar.cjs.entry.js +2 -2
- package/dist/cjs/md-area-chart.cjs.entry.js +3 -3
- package/dist/cjs/md-autocomplete.cjs.entry.js +6 -5
- package/dist/cjs/md-autocomplete.cjs.entry.js.map +1 -1
- package/dist/cjs/md-avatar_2.cjs.entry.js +4 -4
- package/dist/cjs/md-badge.cjs.entry.js +3 -3
- package/dist/cjs/md-bar-chart.cjs.entry.js +3 -3
- package/dist/cjs/md-bottom-sheet.cjs.entry.js +5 -5
- package/dist/cjs/md-breadcrumb-item.cjs.entry.js +1 -1
- package/dist/cjs/md-breadcrumbs.cjs.entry.js +3 -3
- package/dist/cjs/md-button-group.cjs.entry.js +3 -3
- package/dist/cjs/{md-button_7.cjs.entry.js → md-button_6.cjs.entry.js} +14 -39
- package/dist/cjs/md-button_6.cjs.entry.js.map +1 -0
- package/dist/cjs/md-checkbox.cjs.entry.js +3 -3
- package/dist/cjs/md-chip.cjs.entry.js +3 -3
- package/dist/cjs/md-color-picker.cjs.entry.js +1 -1
- package/dist/cjs/md-date-picker.cjs.entry.js +2 -2
- package/dist/cjs/md-dialog.cjs.entry.js +3 -3
- package/dist/cjs/md-divider.cjs.entry.js +3 -3
- package/dist/cjs/md-fab-menu-item.cjs.entry.js +3 -3
- package/dist/cjs/md-fab-menu.cjs.entry.js +3 -3
- package/dist/cjs/md-fab.cjs.entry.js +3 -3
- package/dist/cjs/md-line-chart.cjs.entry.js +3 -3
- package/dist/cjs/md-list-item.cjs.entry.js +4 -4
- package/dist/cjs/md-list.cjs.entry.js +4 -4
- package/dist/cjs/md-loading-indicator-CmzdcYLR.js +33 -0
- package/dist/cjs/md-loading-indicator-CmzdcYLR.js.map +1 -0
- package/dist/cjs/md-loading-indicator.cjs.entry.js +11 -0
- package/dist/cjs/md-loading-indicator.cjs.entry.js.map +1 -0
- package/dist/cjs/md-menu-item-group.cjs.entry.js +1 -1
- package/dist/cjs/md-menu_2.cjs.entry.js +6 -6
- package/dist/cjs/md-meter.cjs.entry.js +1 -1
- package/dist/cjs/md-multi-select.cjs.entry.js +7 -6
- package/dist/cjs/md-multi-select.cjs.entry.js.map +1 -1
- package/dist/cjs/md-navigation-bar.cjs.entry.js +2 -2
- package/dist/cjs/md-navigation-rail-tab.cjs.entry.js +1 -1
- package/dist/cjs/md-navigation-rail.cjs.entry.js +1 -1
- package/dist/cjs/md-navigation-tab.cjs.entry.js +3 -3
- package/dist/cjs/md-number-field.cjs.entry.js +3 -3
- package/dist/cjs/md-organization-chart.cjs.entry.js +3 -3
- package/dist/cjs/md-otp-field.cjs.entry.js +4 -4
- package/dist/cjs/md-pie-chart.cjs.entry.js +1 -1
- package/dist/cjs/md-progress-indicator.cjs.entry.js +1 -1
- package/dist/cjs/md-rating.cjs.entry.js +1 -1
- package/dist/cjs/md-search.cjs.entry.js +8 -7
- package/dist/cjs/md-search.cjs.entry.js.map +1 -1
- package/dist/cjs/md-segmented-button-set.cjs.entry.js +1 -1
- package/dist/cjs/md-segmented-button.cjs.entry.js +1 -1
- package/dist/cjs/md-select-option.cjs.entry.js +2 -2
- package/dist/cjs/md-select.cjs.entry.js +7 -6
- package/dist/cjs/md-select.cjs.entry.js.map +1 -1
- package/dist/cjs/md-side-sheet.cjs.entry.js +1 -1
- package/dist/cjs/md-skeleton.cjs.entry.js +1 -1
- package/dist/cjs/md-slider.cjs.entry.js +3 -3
- package/dist/cjs/md-sparkline.cjs.entry.js +3 -3
- package/dist/cjs/md-split-button.cjs.entry.js +1 -1
- package/dist/cjs/md-status-dot.cjs.entry.js +2 -2
- package/dist/cjs/md-step.cjs.entry.js +1 -1
- package/dist/cjs/md-stepper.cjs.entry.js +1 -1
- package/dist/cjs/md-sub-menu-item.cjs.entry.js +1 -1
- package/dist/cjs/md-switch.cjs.entry.js +1 -1
- package/dist/cjs/md-tab-panel.cjs.entry.js +1 -1
- package/dist/cjs/md-tab-panels.cjs.entry.js +1 -1
- package/dist/cjs/md-tab.cjs.entry.js +1 -1
- package/dist/cjs/md-table-body.cjs.entry.js +1 -1
- package/dist/cjs/md-table-cell.cjs.entry.js +1 -1
- package/dist/cjs/md-table-container.cjs.entry.js +1 -1
- package/dist/cjs/md-table-expand-toggle.cjs.entry.js +1 -1
- package/dist/cjs/md-table-foot.cjs.entry.js +1 -1
- package/dist/cjs/md-table-head.cjs.entry.js +1 -1
- package/dist/cjs/md-table-pagination.cjs.entry.js +1 -1
- package/dist/cjs/md-table-row.cjs.entry.js +1 -1
- package/dist/cjs/md-table-sort-label.cjs.entry.js +1 -1
- package/dist/cjs/md-table-toolbar.cjs.entry.js +1 -1
- package/dist/cjs/md-table.cjs.entry.js +4 -4
- package/dist/cjs/md-tabs.cjs.entry.js +1 -1
- package/dist/cjs/md-text-field.cjs.entry.js +8 -8
- package/dist/cjs/md-time-picker.cjs.entry.js +2 -2
- package/dist/cjs/md-toolbar.cjs.entry.js +1 -1
- package/dist/cjs/md-transfer-list.cjs.entry.js +2 -2
- package/dist/cjs/md3.cjs.js +4 -3
- package/dist/cjs/md3.cjs.js.map +1 -1
- package/dist/cjs/{virtual-select-controller-CqriaZgm.js → virtual-select-controller-C5cSoKfB.js} +10 -9
- package/dist/cjs/virtual-select-controller-C5cSoKfB.js.map +1 -0
- package/dist/collection/collection-manifest.json +1 -1
- package/dist/collection/components/md-accordion-item/md-accordion-item.js +3 -3
- package/dist/collection/components/md-app-bar/md-app-bar.js +1 -1
- package/dist/collection/components/md-area-chart/md-area-chart.js +2 -2
- package/dist/collection/components/md-autocomplete/md-autocomplete.js +4 -3
- package/dist/collection/components/md-autocomplete/md-autocomplete.js.map +1 -1
- package/dist/collection/components/md-avatar/md-avatar.js +2 -2
- package/dist/collection/components/md-badge/md-badge.js +2 -2
- package/dist/collection/components/md-bar-chart/md-bar-chart.js +2 -2
- package/dist/collection/components/md-bottom-sheet/md-bottom-sheet.js +4 -4
- package/dist/collection/components/md-breadcrumbs/md-breadcrumbs.js +2 -2
- package/dist/collection/components/md-button/md-button.js +4 -3
- package/dist/collection/components/md-button/md-button.js.map +1 -1
- package/dist/collection/components/md-button-group/md-button-group.js +2 -2
- package/dist/collection/components/md-card/md-card.js +2 -2
- package/dist/collection/components/md-checkbox/md-checkbox.js +2 -2
- package/dist/collection/components/md-chip/md-chip.js +2 -2
- package/dist/collection/components/md-date-picker/md-date-picker.js +1 -1
- package/dist/collection/components/md-dialog/md-dialog.js +2 -2
- package/dist/collection/components/md-divider/md-divider.js +2 -2
- package/dist/collection/components/md-fab/md-fab.js +2 -2
- package/dist/collection/components/md-fab-menu/md-fab-menu.js +2 -2
- package/dist/collection/components/md-fab-menu-item/md-fab-menu-item.js +2 -2
- package/dist/collection/components/md-icon-button/md-icon-button.js +4 -4
- package/dist/collection/components/md-line-chart/md-line-chart.js +2 -2
- package/dist/collection/components/md-list/md-list.js +3 -3
- package/dist/collection/components/md-list-item/md-list-item.js +3 -3
- package/dist/collection/components/md-loading-indicator/md-loading-indicator.js +2 -2
- package/dist/collection/components/md-menu/md-menu.js +3 -3
- package/dist/collection/components/md-menu-item/md-menu-item.js +2 -2
- package/dist/collection/components/md-multi-select/md-multi-select.js +5 -4
- package/dist/collection/components/md-multi-select/md-multi-select.js.map +1 -1
- package/dist/collection/components/md-navigation-bar/md-navigation-bar.js +1 -1
- package/dist/collection/components/md-navigation-tab/md-navigation-tab.js +2 -2
- package/dist/collection/components/md-number-field/md-number-field.js +2 -2
- package/dist/collection/components/md-organization-chart/md-organization-chart.js +2 -2
- package/dist/collection/components/md-otp-field/md-otp-field.js +3 -3
- package/dist/collection/components/md-ripple/md-ripple.js +1 -1
- package/dist/collection/components/md-search/md-search.js +7 -6
- package/dist/collection/components/md-search/md-search.js.map +1 -1
- package/dist/collection/components/md-select/md-select.js +5 -4
- package/dist/collection/components/md-select/md-select.js.map +1 -1
- package/dist/collection/components/md-select-option/md-select-option.js +1 -1
- package/dist/collection/components/md-slider/md-slider.js +2 -2
- package/dist/collection/components/md-sparkline/md-sparkline.js +2 -2
- package/dist/collection/components/md-status-dot/md-status-dot.js +1 -1
- package/dist/collection/components/md-table/md-table.js +3 -3
- package/dist/collection/components/md-text-field/md-text-field.js +7 -7
- package/dist/collection/components/md-time-picker/md-time-picker.js +1 -1
- package/dist/collection/components/md-tooltip/md-tooltip.js +1 -1
- package/dist/collection/components/md-transfer-list/md-transfer-list.js +1 -1
- package/dist/collection/utils/lazy-loading-indicator.js +62 -0
- package/dist/collection/utils/lazy-loading-indicator.js.map +1 -0
- package/dist/collection/wasm/engine-abi.js +8 -2
- package/dist/collection/wasm/engine-abi.js.map +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/md-accordion-item.js +1 -1
- package/dist/components/md-accordion.js +1 -1
- package/dist/components/md-app-bar.js +1 -1
- package/dist/components/md-area-chart.js +1 -1
- package/dist/components/md-autocomplete.js +1 -1
- package/dist/components/md-autocomplete.js.map +1 -1
- package/dist/components/md-avatar.js +1 -1
- package/dist/components/md-badge.js +1 -1
- package/dist/components/md-bar-chart.js +1 -1
- package/dist/components/md-bottom-sheet.js +1 -1
- package/dist/components/md-breadcrumb-item.js +1 -1
- package/dist/components/md-breadcrumbs.js +1 -1
- package/dist/components/md-button-group.js +1 -1
- package/dist/components/md-button.js +1 -1
- package/dist/components/md-card.js +1 -1
- package/dist/components/md-checkbox.js +1 -1
- package/dist/components/md-chip.js +1 -1
- package/dist/components/md-color-picker.js +1 -1
- package/dist/components/md-date-picker.js +1 -1
- package/dist/components/md-date-picker.js.map +1 -1
- package/dist/components/md-dialog.js +1 -1
- package/dist/components/md-dialog.js.map +1 -1
- package/dist/components/md-divider.js +1 -1
- package/dist/components/md-divider.js.map +1 -1
- package/dist/components/md-fab-menu-item.js +1 -1
- package/dist/components/md-fab-menu.js +1 -1
- package/dist/components/md-fab.js +1 -1
- package/dist/components/md-icon-button.js +1 -1
- package/dist/components/md-line-chart.js +1 -1
- package/dist/components/md-line-chart.js.map +1 -1
- package/dist/components/md-list-item.js +1 -1
- package/dist/components/md-list.js +1 -1
- package/dist/components/md-loading-indicator.js +1 -1
- package/dist/components/md-menu-item-group.js +1 -1
- package/dist/components/md-menu-item.js +1 -1
- package/dist/components/md-menu.js +1 -1
- package/dist/components/md-meter.js +1 -1
- package/dist/components/md-multi-select.js +1 -1
- package/dist/components/md-multi-select.js.map +1 -1
- package/dist/components/md-navigation-bar.js +1 -1
- package/dist/components/md-navigation-rail-tab.js +1 -1
- package/dist/components/md-navigation-rail.js +1 -1
- package/dist/components/md-navigation-tab.js +1 -1
- package/dist/components/md-number-field.js +1 -1
- package/dist/components/md-organization-chart.js +1 -1
- package/dist/components/md-otp-field.js +1 -1
- package/dist/components/md-pie-chart.js +1 -1
- package/dist/components/md-progress-indicator.js +1 -1
- package/dist/components/md-radio.js +1 -1
- package/dist/components/md-rating.js +1 -1
- package/dist/components/md-ripple.js +1 -1
- package/dist/components/md-search.js +1 -1
- package/dist/components/md-search.js.map +1 -1
- package/dist/components/md-segmented-button-set.js +1 -1
- package/dist/components/md-segmented-button.js +1 -1
- package/dist/components/md-select-option.js +1 -1
- package/dist/components/md-select.js +1 -1
- package/dist/components/md-side-sheet.js +1 -1
- package/dist/components/md-skeleton.js +1 -1
- package/dist/components/md-slider.js +1 -1
- package/dist/components/md-snackbar.js +1 -1
- package/dist/components/md-snackbar.js.map +1 -1
- package/dist/components/md-sparkline.js +1 -1
- package/dist/components/md-split-button.js +1 -1
- package/dist/components/md-status-dot.js +1 -1
- package/dist/components/md-step.js +1 -1
- package/dist/components/md-step.js.map +1 -1
- package/dist/components/md-stepper.js +1 -1
- package/dist/components/md-stepper.js.map +1 -1
- package/dist/components/md-sub-menu-item.js +1 -1
- package/dist/components/md-switch.js +1 -1
- package/dist/components/md-tab-panel.js +1 -1
- package/dist/components/md-tab-panels.js +1 -1
- package/dist/components/md-tab.js +1 -1
- package/dist/components/md-table-body.js +1 -1
- package/dist/components/md-table-cell.js +1 -1
- package/dist/components/md-table-container.js +1 -1
- package/dist/components/md-table-expand-toggle.js +1 -1
- package/dist/components/md-table-foot.js +1 -1
- package/dist/components/md-table-head.js +1 -1
- package/dist/components/md-table-pagination.js +1 -1
- package/dist/components/md-table-pagination.js.map +1 -1
- package/dist/components/md-table-row.js +1 -1
- package/dist/components/md-table-sort-label.js +1 -1
- package/dist/components/md-table-toolbar.js +1 -1
- package/dist/components/md-table.js +1 -1
- package/dist/components/md-tabs.js +1 -1
- package/dist/components/md-text-field.js +1 -1
- package/dist/components/md-time-picker.js +1 -1
- package/dist/components/md-time-picker.js.map +1 -1
- package/dist/components/md-toolbar.js +1 -1
- package/dist/components/md-tooltip.js +1 -1
- package/dist/components/md-transfer-list.js +1 -1
- package/dist/components/p-1RSrsLOs.js +2 -0
- package/dist/components/p-1RSrsLOs.js.map +1 -0
- package/dist/components/p-2HV152w7.js +2 -0
- package/dist/components/p-2HV152w7.js.map +1 -0
- package/dist/components/p-6ZDAcEKN.js +2 -0
- package/dist/components/p-6ZDAcEKN.js.map +1 -0
- package/dist/components/p-B2fYoYe9.js +2 -0
- package/dist/components/p-B2fYoYe9.js.map +1 -0
- package/dist/components/p-BR6gfOQH.js +2 -0
- package/dist/components/p-BR6gfOQH.js.map +1 -0
- package/dist/components/p-Bz-JaJcA.js +2 -0
- package/dist/components/p-Bz-JaJcA.js.map +1 -0
- package/dist/components/p-C77M30dm.js +2 -0
- package/dist/components/p-C77M30dm.js.map +1 -0
- package/dist/components/p-CNgkGl_1.js +2 -0
- package/dist/components/p-CNgkGl_1.js.map +1 -0
- package/dist/components/p-CfBPnYW7.js +2 -0
- package/dist/components/p-CfBPnYW7.js.map +1 -0
- package/dist/components/p-D5Ht729E.js +2 -0
- package/dist/components/p-D5Ht729E.js.map +1 -0
- package/dist/components/p-DPqGg8C1.js +2 -0
- package/dist/components/p-DPqGg8C1.js.map +1 -0
- package/dist/components/p-De3E5Q8v.js +2 -0
- package/dist/components/p-De3E5Q8v.js.map +1 -0
- package/dist/components/p-Dm_7DA1f.js +2 -0
- package/dist/components/p-Dm_7DA1f.js.map +1 -0
- package/dist/components/p-Dz3R-2Wn.js +2 -0
- package/dist/components/p-Dz3R-2Wn.js.map +1 -0
- package/dist/components/p-Zjf9uhOr.js +2 -0
- package/dist/components/p-Zjf9uhOr.js.map +1 -0
- package/dist/components/p-ssLobpGS.js +2 -0
- package/dist/components/p-ssLobpGS.js.map +1 -0
- package/dist/components/p-tSoecrcz.js +2 -0
- package/dist/components/p-tSoecrcz.js.map +1 -0
- package/dist/components/p-zMR3UIR_.js +2 -0
- package/dist/components/p-zMR3UIR_.js.map +1 -0
- package/dist/components-csr/index.js +2 -0
- package/dist/components-csr/index.js.map +1 -0
- package/dist/components-csr/md-accordion-item.js +2 -0
- package/dist/components-csr/md-accordion-item.js.map +1 -0
- package/dist/components-csr/md-accordion.js +2 -0
- package/dist/components-csr/md-accordion.js.map +1 -0
- package/dist/components-csr/md-app-bar.js +2 -0
- package/dist/components-csr/md-app-bar.js.map +1 -0
- package/dist/components-csr/md-area-chart.js +2 -0
- package/dist/components-csr/md-area-chart.js.map +1 -0
- package/dist/components-csr/md-autocomplete.js +2 -0
- package/dist/components-csr/md-autocomplete.js.map +1 -0
- package/dist/components-csr/md-avatar.js +2 -0
- package/dist/components-csr/md-avatar.js.map +1 -0
- package/dist/components-csr/md-badge.js +2 -0
- package/dist/components-csr/md-badge.js.map +1 -0
- package/dist/components-csr/md-bar-chart.js +2 -0
- package/dist/components-csr/md-bar-chart.js.map +1 -0
- package/dist/components-csr/md-bottom-sheet.js +2 -0
- package/dist/components-csr/md-bottom-sheet.js.map +1 -0
- package/dist/components-csr/md-breadcrumb-item.js +2 -0
- package/dist/components-csr/md-breadcrumb-item.js.map +1 -0
- package/dist/components-csr/md-breadcrumbs.js +2 -0
- package/dist/components-csr/md-breadcrumbs.js.map +1 -0
- package/dist/components-csr/md-button-group.js +2 -0
- package/dist/components-csr/md-button-group.js.map +1 -0
- package/dist/components-csr/md-button.js +2 -0
- package/dist/components-csr/md-button.js.map +1 -0
- package/dist/components-csr/md-card.js +2 -0
- package/dist/components-csr/md-card.js.map +1 -0
- package/dist/components-csr/md-checkbox.js +2 -0
- package/dist/components-csr/md-checkbox.js.map +1 -0
- package/dist/components-csr/md-chip.js +2 -0
- package/dist/components-csr/md-chip.js.map +1 -0
- package/dist/components-csr/md-color-picker.js +2 -0
- package/dist/components-csr/md-color-picker.js.map +1 -0
- package/dist/components-csr/md-date-picker.js +2 -0
- package/dist/components-csr/md-date-picker.js.map +1 -0
- package/dist/components-csr/md-dialog.js +2 -0
- package/dist/components-csr/md-dialog.js.map +1 -0
- package/dist/components-csr/md-divider.js +2 -0
- package/dist/components-csr/md-divider.js.map +1 -0
- package/dist/components-csr/md-fab-menu-item.js +2 -0
- package/dist/components-csr/md-fab-menu-item.js.map +1 -0
- package/dist/components-csr/md-fab-menu.js +2 -0
- package/dist/components-csr/md-fab-menu.js.map +1 -0
- package/dist/components-csr/md-fab.js +2 -0
- package/dist/components-csr/md-fab.js.map +1 -0
- package/dist/components-csr/md-icon-button.js +2 -0
- package/dist/components-csr/md-icon-button.js.map +1 -0
- package/dist/components-csr/md-line-chart.js +2 -0
- package/dist/components-csr/md-line-chart.js.map +1 -0
- package/dist/components-csr/md-list-item.js +2 -0
- package/dist/components-csr/md-list-item.js.map +1 -0
- package/dist/components-csr/md-list.js +2 -0
- package/dist/components-csr/md-list.js.map +1 -0
- package/dist/components-csr/md-loading-indicator.js +2 -0
- package/dist/components-csr/md-loading-indicator.js.map +1 -0
- package/dist/components-csr/md-menu-item-group.js +2 -0
- package/dist/components-csr/md-menu-item-group.js.map +1 -0
- package/dist/components-csr/md-menu-item.js +2 -0
- package/dist/components-csr/md-menu-item.js.map +1 -0
- package/dist/components-csr/md-menu.js +2 -0
- package/dist/components-csr/md-menu.js.map +1 -0
- package/dist/components-csr/md-meter.js +2 -0
- package/dist/components-csr/md-meter.js.map +1 -0
- package/dist/components-csr/md-multi-select.js +2 -0
- package/dist/components-csr/md-multi-select.js.map +1 -0
- package/dist/components-csr/md-navigation-bar.js +2 -0
- package/dist/components-csr/md-navigation-bar.js.map +1 -0
- package/dist/components-csr/md-navigation-rail-tab.js +2 -0
- package/dist/components-csr/md-navigation-rail-tab.js.map +1 -0
- package/dist/components-csr/md-navigation-rail.js +2 -0
- package/dist/components-csr/md-navigation-rail.js.map +1 -0
- package/dist/components-csr/md-navigation-tab.js +2 -0
- package/dist/components-csr/md-navigation-tab.js.map +1 -0
- package/dist/components-csr/md-number-field.js +2 -0
- package/dist/components-csr/md-number-field.js.map +1 -0
- package/dist/components-csr/md-organization-chart.js +2 -0
- package/dist/components-csr/md-organization-chart.js.map +1 -0
- package/dist/components-csr/md-otp-field.js +2 -0
- package/dist/components-csr/md-otp-field.js.map +1 -0
- package/dist/components-csr/md-pie-chart.js +2 -0
- package/dist/components-csr/md-pie-chart.js.map +1 -0
- package/dist/components-csr/md-progress-indicator.js +2 -0
- package/dist/components-csr/md-progress-indicator.js.map +1 -0
- package/dist/components-csr/md-radio.js +2 -0
- package/dist/components-csr/md-radio.js.map +1 -0
- package/dist/components-csr/md-rating.js +2 -0
- package/dist/components-csr/md-rating.js.map +1 -0
- package/dist/components-csr/md-ripple.js +2 -0
- package/dist/components-csr/md-ripple.js.map +1 -0
- package/dist/components-csr/md-search.js +2 -0
- package/dist/components-csr/md-search.js.map +1 -0
- package/dist/components-csr/md-segmented-button-set.js +2 -0
- package/dist/components-csr/md-segmented-button-set.js.map +1 -0
- package/dist/components-csr/md-segmented-button.js +2 -0
- package/dist/components-csr/md-segmented-button.js.map +1 -0
- package/dist/components-csr/md-select-option.js +2 -0
- package/dist/components-csr/md-select-option.js.map +1 -0
- package/dist/components-csr/md-select.js +2 -0
- package/dist/components-csr/md-select.js.map +1 -0
- package/dist/components-csr/md-side-sheet.js +2 -0
- package/dist/components-csr/md-side-sheet.js.map +1 -0
- package/dist/components-csr/md-skeleton.js +2 -0
- package/dist/components-csr/md-skeleton.js.map +1 -0
- package/dist/components-csr/md-slider.js +2 -0
- package/dist/components-csr/md-slider.js.map +1 -0
- package/dist/components-csr/md-snackbar.js +2 -0
- package/dist/components-csr/md-snackbar.js.map +1 -0
- package/dist/components-csr/md-sparkline.js +2 -0
- package/dist/components-csr/md-sparkline.js.map +1 -0
- package/dist/components-csr/md-split-button.js +2 -0
- package/dist/components-csr/md-split-button.js.map +1 -0
- package/dist/components-csr/md-status-dot.js +2 -0
- package/dist/components-csr/md-status-dot.js.map +1 -0
- package/dist/components-csr/md-step.js +2 -0
- package/dist/components-csr/md-step.js.map +1 -0
- package/dist/components-csr/md-stepper.js +2 -0
- package/dist/components-csr/md-stepper.js.map +1 -0
- package/dist/components-csr/md-sub-menu-item.js +2 -0
- package/dist/components-csr/md-sub-menu-item.js.map +1 -0
- package/dist/components-csr/md-switch.js +2 -0
- package/dist/components-csr/md-switch.js.map +1 -0
- package/dist/components-csr/md-tab-panel.js +2 -0
- package/dist/components-csr/md-tab-panel.js.map +1 -0
- package/dist/components-csr/md-tab-panels.js +2 -0
- package/dist/components-csr/md-tab-panels.js.map +1 -0
- package/dist/components-csr/md-tab.js +2 -0
- package/dist/components-csr/md-tab.js.map +1 -0
- package/dist/components-csr/md-table-body.js +2 -0
- package/dist/components-csr/md-table-body.js.map +1 -0
- package/dist/components-csr/md-table-cell.js +2 -0
- package/dist/components-csr/md-table-cell.js.map +1 -0
- package/dist/components-csr/md-table-container.js +2 -0
- package/dist/components-csr/md-table-container.js.map +1 -0
- package/dist/components-csr/md-table-expand-toggle.js +2 -0
- package/dist/components-csr/md-table-expand-toggle.js.map +1 -0
- package/dist/components-csr/md-table-foot.js +2 -0
- package/dist/components-csr/md-table-foot.js.map +1 -0
- package/dist/components-csr/md-table-head.js +2 -0
- package/dist/components-csr/md-table-head.js.map +1 -0
- package/dist/components-csr/md-table-pagination.js +2 -0
- package/dist/components-csr/md-table-pagination.js.map +1 -0
- package/dist/components-csr/md-table-row.js +2 -0
- package/dist/components-csr/md-table-row.js.map +1 -0
- package/dist/components-csr/md-table-sort-label.js +2 -0
- package/dist/components-csr/md-table-sort-label.js.map +1 -0
- package/dist/components-csr/md-table-toolbar.js +2 -0
- package/dist/components-csr/md-table-toolbar.js.map +1 -0
- package/dist/components-csr/md-table.js +2 -0
- package/dist/components-csr/md-table.js.map +1 -0
- package/dist/components-csr/md-tabs.js +2 -0
- package/dist/components-csr/md-tabs.js.map +1 -0
- package/dist/components-csr/md-text-field.js +2 -0
- package/dist/components-csr/md-text-field.js.map +1 -0
- package/dist/components-csr/md-time-picker.js +2 -0
- package/dist/components-csr/md-time-picker.js.map +1 -0
- package/dist/components-csr/md-toolbar.js +2 -0
- package/dist/components-csr/md-toolbar.js.map +1 -0
- package/dist/components-csr/md-tooltip.js +2 -0
- package/dist/components-csr/md-tooltip.js.map +1 -0
- package/dist/components-csr/md-transfer-list.js +2 -0
- package/dist/components-csr/md-transfer-list.js.map +1 -0
- package/dist/components-csr/p-6WgHjhDg.js +2 -0
- package/dist/components-csr/p-6WgHjhDg.js.map +1 -0
- package/dist/{components/p-uTEkf0sE.js → components-csr/p-BEmwDSzw.js} +2 -2
- package/dist/{components/p-C8EP4S21.js → components-csr/p-BQKzjYcY.js} +2 -2
- package/dist/{components/p-BwXpiUsu.js → components-csr/p-BWMwewtY.js} +2 -2
- package/dist/{components/p-DXXUoRSH.js → components-csr/p-BZakoRau.js} +2 -2
- package/dist/components-csr/p-BZakoRau.js.map +1 -0
- package/dist/{md3/p-BjYKc1Ge.js → components-csr/p-BdEoSBtL.js} +2 -2
- package/dist/components-csr/p-BdEoSBtL.js.map +1 -0
- package/dist/{components/p-B0Opn6dK.js → components-csr/p-Bkt_X-6v.js} +2 -2
- package/dist/components-csr/p-Bx6--dQF.js.map +1 -0
- package/dist/components-csr/p-Bz-JaJcA.js +2 -0
- package/dist/components-csr/p-Bz-JaJcA.js.map +1 -0
- package/dist/{components/p-stybaFzj.js → components-csr/p-C3vB0Hd9.js} +2 -2
- package/dist/{components/p-B3MWYEEJ.js → components-csr/p-CF7mq5T7.js} +2 -2
- package/dist/{components/p-7fN_yCXW.js → components-csr/p-CVMM-tdC.js} +2 -2
- package/dist/components-csr/p-C_ogF68H.js.map +1 -0
- package/dist/components-csr/p-Cch_V1vi.js +2 -0
- package/dist/components-csr/p-Cch_V1vi.js.map +1 -0
- package/dist/components-csr/p-CfBPnYW7.js +2 -0
- package/dist/components-csr/p-CfBPnYW7.js.map +1 -0
- package/dist/components-csr/p-CxhZdOPw.js +2 -0
- package/dist/components-csr/p-CxhZdOPw.js.map +1 -0
- package/dist/{components/p-Ch2-tttM.js → components-csr/p-DMQ-6aj8.js} +2 -2
- package/dist/components-csr/p-DWxN44zD.js +2 -0
- package/dist/components-csr/p-DWxN44zD.js.map +1 -0
- package/dist/components-csr/p-DYBUr7K_.js +2 -0
- package/dist/components-csr/p-DYBUr7K_.js.map +1 -0
- package/dist/{components/p-e2HRV63Y.js → components-csr/p-DfcpeJAu.js} +2 -2
- package/dist/{components/p-Dp-w93ot.js → components-csr/p-DjKPc5EU.js} +2 -2
- package/dist/components-csr/p-DvOKnoqK.js.map +1 -0
- package/dist/components-csr/p-DzPKu-Ma.js.map +1 -0
- package/dist/{components/p-UdGDg2oJ.js → components-csr/p-If0JHsYV.js} +2 -2
- package/dist/components-csr/p-If0JHsYV.js.map +1 -0
- package/dist/components-csr/p-RLxbNqRv.js.map +1 -0
- package/dist/{components/p-6wZSqm_2.js → components-csr/p-R_guULjT.js} +2 -2
- package/dist/components-csr/p-bSpXNc5J.js +2 -0
- package/dist/components-csr/p-bSpXNc5J.js.map +1 -0
- package/dist/{components/p-Ddiw2Kjw.js → components-csr/p-uSMrgqAy.js} +2 -2
- package/dist/components-csr/package.json +3 -0
- package/dist/esm/{a11y-C6CRqodW.js → a11y-BckJ95d7.js} +3 -3
- package/dist/esm/{a11y-C6CRqodW.js.map → a11y-BckJ95d7.js.map} +1 -1
- package/dist/esm/app-globals-DQuL1Twl.js +6 -0
- package/dist/esm/app-globals-DQuL1Twl.js.map +1 -0
- package/dist/esm/{bar-chart-ZZrajEkM.js → bar-chart-BuTyuCbt.js} +4 -4
- package/dist/esm/{bar-chart-ZZrajEkM.js.map → bar-chart-BuTyuCbt.js.map} +1 -1
- package/dist/esm/{chart-32olae06.js → chart-ByIhkqsG.js} +4 -4
- package/dist/esm/{chart-32olae06.js.map → chart-ByIhkqsG.js.map} +1 -1
- package/dist/esm/engine.wasm-CfBPnYW7.js +10 -0
- package/dist/esm/engine.wasm-CfBPnYW7.js.map +1 -0
- package/dist/esm/{hit-test-DHldf5Lm.js → hit-test-c_hI-yCX.js} +3 -3
- package/dist/esm/{hit-test-DHldf5Lm.js.map → hit-test-c_hI-yCX.js.map} +1 -1
- package/dist/esm/{index-DTaX19_O.js → index-WmvQpZnM.js} +5 -15
- package/dist/esm/index-WmvQpZnM.js.map +1 -0
- package/dist/esm/lazy-loading-indicator-BWFcjJiK.js +67 -0
- package/dist/esm/lazy-loading-indicator-BWFcjJiK.js.map +1 -0
- package/dist/esm/loader.js +4 -3
- package/dist/esm/loader.js.map +1 -1
- package/dist/esm/md-accordion-item.entry.js +4 -4
- package/dist/esm/md-accordion.entry.js +1 -1
- package/dist/esm/md-app-bar.entry.js +2 -2
- package/dist/esm/md-area-chart.entry.js +7 -7
- package/dist/esm/md-autocomplete.entry.js +6 -5
- package/dist/esm/md-autocomplete.entry.js.map +1 -1
- package/dist/esm/md-avatar_2.entry.js +4 -4
- package/dist/esm/md-badge.entry.js +3 -3
- package/dist/esm/md-bar-chart.entry.js +7 -7
- package/dist/esm/md-bottom-sheet.entry.js +5 -5
- package/dist/esm/md-breadcrumb-item.entry.js +2 -2
- package/dist/esm/md-breadcrumbs.entry.js +3 -3
- package/dist/esm/md-button-group.entry.js +3 -3
- package/dist/esm/{md-button_7.entry.js → md-button_6.entry.js} +16 -40
- package/dist/esm/md-button_6.entry.js.map +1 -0
- package/dist/esm/md-checkbox.entry.js +3 -3
- package/dist/esm/md-chip.entry.js +3 -3
- package/dist/esm/md-color-picker.entry.js +1 -1
- package/dist/esm/md-date-picker.entry.js +2 -2
- package/dist/esm/md-dialog.entry.js +3 -3
- package/dist/esm/md-divider.entry.js +3 -3
- package/dist/esm/md-fab-menu-item.entry.js +3 -3
- package/dist/esm/md-fab-menu.entry.js +3 -3
- package/dist/esm/md-fab.entry.js +3 -3
- package/dist/esm/md-line-chart.entry.js +7 -7
- package/dist/esm/md-list-item.entry.js +5 -5
- package/dist/esm/md-list.entry.js +4 -4
- package/dist/esm/md-loading-indicator-Bf-Pt29l.js +31 -0
- package/dist/esm/md-loading-indicator-Bf-Pt29l.js.map +1 -0
- package/dist/esm/md-loading-indicator.entry.js +5 -0
- package/dist/esm/md-loading-indicator.entry.js.map +1 -0
- package/dist/esm/md-menu-item-group.entry.js +1 -1
- package/dist/esm/md-menu_2.entry.js +6 -6
- package/dist/esm/md-meter.entry.js +1 -1
- package/dist/esm/md-multi-select.entry.js +7 -6
- package/dist/esm/md-multi-select.entry.js.map +1 -1
- package/dist/esm/md-navigation-bar.entry.js +2 -2
- package/dist/esm/md-navigation-rail-tab.entry.js +2 -2
- package/dist/esm/md-navigation-rail.entry.js +1 -1
- package/dist/esm/md-navigation-tab.entry.js +4 -4
- package/dist/esm/md-number-field.entry.js +3 -3
- package/dist/esm/md-organization-chart.entry.js +3 -3
- package/dist/esm/md-otp-field.entry.js +4 -4
- package/dist/esm/md-pie-chart.entry.js +3 -3
- package/dist/esm/md-progress-indicator.entry.js +1 -1
- package/dist/esm/md-rating.entry.js +1 -1
- package/dist/esm/md-search.entry.js +8 -7
- package/dist/esm/md-search.entry.js.map +1 -1
- package/dist/esm/md-segmented-button-set.entry.js +1 -1
- package/dist/esm/md-segmented-button.entry.js +1 -1
- package/dist/esm/md-select-option.entry.js +2 -2
- package/dist/esm/md-select.entry.js +7 -6
- package/dist/esm/md-select.entry.js.map +1 -1
- package/dist/esm/md-side-sheet.entry.js +1 -1
- package/dist/esm/md-skeleton.entry.js +1 -1
- package/dist/esm/md-slider.entry.js +3 -3
- package/dist/esm/md-sparkline.entry.js +7 -7
- package/dist/esm/md-split-button.entry.js +1 -1
- package/dist/esm/md-status-dot.entry.js +2 -2
- package/dist/esm/md-step.entry.js +1 -1
- package/dist/esm/md-stepper.entry.js +1 -1
- package/dist/esm/md-sub-menu-item.entry.js +1 -1
- package/dist/esm/md-switch.entry.js +1 -1
- package/dist/esm/md-tab-panel.entry.js +1 -1
- package/dist/esm/md-tab-panels.entry.js +1 -1
- package/dist/esm/md-tab.entry.js +1 -1
- package/dist/esm/md-table-body.entry.js +1 -1
- package/dist/esm/md-table-cell.entry.js +1 -1
- package/dist/esm/md-table-container.entry.js +1 -1
- package/dist/esm/md-table-expand-toggle.entry.js +1 -1
- package/dist/esm/md-table-foot.entry.js +1 -1
- package/dist/esm/md-table-head.entry.js +1 -1
- package/dist/esm/md-table-pagination.entry.js +1 -1
- package/dist/esm/md-table-row.entry.js +1 -1
- package/dist/esm/md-table-sort-label.entry.js +1 -1
- package/dist/esm/md-table-toolbar.entry.js +1 -1
- package/dist/esm/md-table.entry.js +4 -4
- package/dist/esm/md-tabs.entry.js +1 -1
- package/dist/esm/md-text-field.entry.js +8 -8
- package/dist/esm/md-time-picker.entry.js +2 -2
- package/dist/esm/md-toolbar.entry.js +1 -1
- package/dist/esm/md-transfer-list.entry.js +2 -2
- package/dist/esm/md3.js +4 -3
- package/dist/esm/md3.js.map +1 -1
- package/dist/esm/{rtl-DvOKnoqK.js → rtl-CVFH1DkU.js} +3 -3
- package/dist/esm/{rtl-DvOKnoqK.js.map → rtl-CVFH1DkU.js.map} +1 -1
- package/dist/esm/{url-BjYKc1Ge.js → url-BdEoSBtL.js} +3 -3
- package/dist/esm/{url-BjYKc1Ge.js.map → url-BdEoSBtL.js.map} +1 -1
- package/dist/esm/{virtual-select-controller-BEWIC0pC.js → virtual-select-controller-CR60w6DO.js} +10 -9
- package/dist/esm/virtual-select-controller-CR60w6DO.js.map +1 -0
- package/dist/md3/md3.css +1 -1
- package/dist/md3/md3.esm.js +1 -1
- package/dist/md3/md3.esm.js.map +1 -1
- package/dist/md3/p-08f1c469.entry.js +2 -0
- package/dist/md3/{p-4d82132d.entry.js.map → p-08f1c469.entry.js.map} +1 -1
- package/dist/md3/{p-9ddbf247.entry.js → p-108f89d7.entry.js} +2 -2
- package/dist/md3/p-1112bffc.entry.js +2 -0
- package/dist/md3/{p-cf07e761.entry.js.map → p-1112bffc.entry.js.map} +1 -1
- package/dist/md3/{p-c6a12344.entry.js → p-114c270b.entry.js} +2 -2
- package/dist/md3/p-1835fe36.entry.js +2 -0
- package/dist/md3/{p-a3308c40.entry.js.map → p-1835fe36.entry.js.map} +1 -1
- package/dist/md3/{p-396089fd.entry.js → p-1edb5a0d.entry.js} +2 -2
- package/dist/md3/p-2ba2db3b.entry.js +2 -0
- package/dist/md3/{p-6b2871a0.entry.js.map → p-2ba2db3b.entry.js.map} +1 -1
- package/dist/md3/p-3508d0e0.entry.js +2 -0
- package/dist/md3/{p-f31ab454.entry.js.map → p-3508d0e0.entry.js.map} +1 -1
- package/dist/md3/{p-b34d385b.entry.js → p-35b05b45.entry.js} +2 -2
- package/dist/md3/{p-c2dd8c8c.entry.js → p-38e9a583.entry.js} +2 -2
- package/dist/md3/{p-be02624e.entry.js → p-3c0469aa.entry.js} +2 -2
- package/dist/md3/p-3f64a27d.entry.js +2 -0
- package/dist/md3/{p-fb61868c.entry.js.map → p-3f64a27d.entry.js.map} +1 -1
- package/dist/md3/{p-63b8c8d1.entry.js → p-408ee4be.entry.js} +2 -2
- package/dist/md3/{p-edb34a6d.entry.js → p-43c708ad.entry.js} +2 -2
- package/dist/md3/{p-3015c7e3.entry.js → p-4770b534.entry.js} +2 -2
- package/dist/md3/{p-c861d774.entry.js → p-4b7cf934.entry.js} +2 -2
- package/dist/md3/{p-2e09a7b7.entry.js → p-4f26bd60.entry.js} +2 -2
- package/dist/md3/{p-7b463fbe.entry.js → p-4f2e82cb.entry.js} +2 -2
- package/dist/md3/{p-be412e3f.entry.js → p-501bf161.entry.js} +2 -2
- package/dist/md3/{p-c063c823.entry.js → p-56c7c570.entry.js} +2 -2
- package/dist/md3/{p-2e9503d7.entry.js → p-56ca0c3c.entry.js} +2 -2
- package/dist/md3/{p-ac8762e5.entry.js → p-5b63149a.entry.js} +2 -2
- package/dist/md3/{p-c5af701b.entry.js → p-5f668b0a.entry.js} +2 -2
- package/dist/md3/p-6237ddac.entry.js +2 -0
- package/dist/md3/{p-e7dc5a32.entry.js.map → p-6237ddac.entry.js.map} +1 -1
- package/dist/md3/{p-8eb0b6a4.entry.js → p-6d65fc6a.entry.js} +2 -2
- package/dist/md3/{p-e3124e1e.entry.js → p-707b6d7c.entry.js} +2 -2
- package/dist/md3/{p-a5fee424.entry.js → p-71f1660b.entry.js} +2 -2
- package/dist/md3/{p-1a8ec5bc.entry.js → p-7501170f.entry.js} +2 -2
- package/dist/md3/p-7c8842bf.entry.js +2 -0
- package/dist/md3/{p-ba2ebde1.entry.js.map → p-7c8842bf.entry.js.map} +1 -1
- package/dist/md3/{p-4e3d6e40.entry.js → p-7d1686a7.entry.js} +2 -2
- package/dist/md3/p-7e7f0e45.entry.js +2 -0
- package/dist/md3/p-7e7f0e45.entry.js.map +1 -0
- package/dist/md3/p-80379565.entry.js +2 -0
- package/dist/md3/{p-6c44cf13.entry.js.map → p-80379565.entry.js.map} +1 -1
- package/dist/md3/p-830724e4.entry.js +2 -0
- package/dist/md3/p-830724e4.entry.js.map +1 -0
- package/dist/md3/{p-4dda4cb0.entry.js → p-845ca9cc.entry.js} +2 -2
- package/dist/md3/{p-77a01bcc.entry.js → p-87f88d62.entry.js} +2 -2
- package/dist/md3/{p-5b74694e.entry.js → p-89d47130.entry.js} +2 -2
- package/dist/md3/p-8a6fed13.entry.js +2 -0
- package/dist/md3/{p-a803da99.entry.js.map → p-8a6fed13.entry.js.map} +1 -1
- package/dist/md3/p-8a7e0297.entry.js +2 -0
- package/dist/md3/p-8a7e0297.entry.js.map +1 -0
- package/dist/md3/{p-b0431a5c.entry.js → p-8bdcda53.entry.js} +2 -2
- package/dist/md3/{p-c10a33c2.entry.js → p-8e7df348.entry.js} +2 -2
- package/dist/md3/p-9003a7d4.entry.js +2 -0
- package/dist/md3/p-9003a7d4.entry.js.map +1 -0
- package/dist/md3/{p-05ae91b6.entry.js → p-90ccf4c3.entry.js} +2 -2
- package/dist/md3/p-BdEoSBtL.js +2 -0
- package/dist/md3/{p-BjYKc1Ge.js.map → p-BdEoSBtL.js.map} +1 -1
- package/dist/md3/p-Bz-JaJcA.js +2 -0
- package/dist/md3/p-Bz-JaJcA.js.map +1 -0
- package/dist/md3/p-CGqeEMjY.js +2 -0
- package/dist/md3/{p-DzPKu-Ma.js.map → p-CGqeEMjY.js.map} +1 -1
- package/dist/md3/p-CVFH1DkU.js +2 -0
- package/dist/md3/{p-DvOKnoqK.js.map → p-CVFH1DkU.js.map} +1 -1
- package/dist/md3/p-Cch92tDM.js +2 -0
- package/dist/md3/{p-RLxbNqRv.js.map → p-Cch92tDM.js.map} +1 -1
- package/dist/md3/p-CfBPnYW7.js +2 -0
- package/dist/md3/p-CfBPnYW7.js.map +1 -0
- package/dist/md3/p-D17cVKxS.js +2 -0
- package/dist/md3/p-D17cVKxS.js.map +1 -0
- package/dist/md3/p-DGtztV3K.js +2 -0
- package/dist/md3/{p-Bx6--dQF.js.map → p-DGtztV3K.js.map} +1 -1
- package/dist/md3/p-DQuL1Twl.js +2 -0
- package/dist/md3/p-DQuL1Twl.js.map +1 -0
- package/dist/md3/p-DnKDoE8K.js +2 -0
- package/dist/md3/p-DnKDoE8K.js.map +1 -0
- package/dist/md3/p-WmvQpZnM.js +3 -0
- package/dist/md3/p-WmvQpZnM.js.map +1 -0
- package/dist/md3/p-a3623653.entry.js +2 -0
- package/dist/md3/{p-19ee9c33.entry.js.map → p-a3623653.entry.js.map} +1 -1
- package/dist/md3/{p-da4e27d4.entry.js → p-a4d4cfed.entry.js} +2 -2
- package/dist/md3/{p-5394254f.entry.js → p-a976498b.entry.js} +2 -2
- package/dist/md3/{p-6038b907.entry.js → p-ab568d1c.entry.js} +2 -2
- package/dist/md3/{p-bf7842f8.entry.js → p-adf8a415.entry.js} +2 -2
- package/dist/md3/p-ae30e899.entry.js +2 -0
- package/dist/md3/p-ae30e899.entry.js.map +1 -0
- package/dist/md3/{p-45280bf4.entry.js → p-b2d88292.entry.js} +2 -2
- package/dist/md3/{p-796f79f8.entry.js → p-b3b5247b.entry.js} +2 -2
- package/dist/md3/{p-5b799707.entry.js → p-b4266f6b.entry.js} +2 -2
- package/dist/md3/p-b54bbf88.entry.js +2 -0
- package/dist/md3/p-b54bbf88.entry.js.map +1 -0
- package/dist/md3/{p-c00f7514.entry.js → p-ba011453.entry.js} +2 -2
- package/dist/md3/{p-6ba63c73.entry.js → p-bc24f0c9.entry.js} +2 -2
- package/dist/md3/{p-0c2e824d.entry.js → p-c20fbb9e.entry.js} +2 -2
- package/dist/md3/{p-fc0b325d.entry.js → p-c2944c87.entry.js} +2 -2
- package/dist/md3/{p-4e45b2ff.entry.js → p-c58c68d0.entry.js} +2 -2
- package/dist/md3/p-cc6e8afd.entry.js +2 -0
- package/dist/md3/{p-72457a85.entry.js.map → p-cc6e8afd.entry.js.map} +1 -1
- package/dist/md3/{p-0f764a1e.entry.js → p-d2e39c6e.entry.js} +2 -2
- package/dist/md3/{p-50555bb7.entry.js → p-d8885f53.entry.js} +2 -2
- package/dist/md3/{p-c1ca6f6c.entry.js → p-db6fb4e1.entry.js} +2 -2
- package/dist/md3/{p-81843ff7.entry.js → p-dcba2857.entry.js} +2 -2
- package/dist/md3/{p-65195996.entry.js → p-e357e8ac.entry.js} +2 -2
- package/dist/md3/{p-39cb7c24.entry.js → p-e5c6795e.entry.js} +2 -2
- package/dist/md3/p-e871663b.entry.js +2 -0
- package/dist/md3/{p-aaec2698.entry.js.map → p-e871663b.entry.js.map} +1 -1
- package/dist/md3/p-f1b69181.entry.js +2 -0
- package/dist/md3/{p-a986fd24.entry.js.map → p-f1b69181.entry.js.map} +1 -1
- package/dist/md3/p-f297d786.entry.js +2 -0
- package/dist/md3/{p-3cce1de3.entry.js.map → p-f297d786.entry.js.map} +1 -1
- package/dist/md3/{p-e6d7f0ff.entry.js → p-f403ad20.entry.js} +2 -2
- package/dist/md3/p-f5399b73.entry.js +2 -0
- package/dist/md3/{p-04e97f5d.entry.js.map → p-f5399b73.entry.js.map} +1 -1
- package/dist/md3/{p-708a9313.entry.js → p-f5fd9a0b.entry.js} +2 -2
- package/dist/md3/{p-aa0e7d4d.entry.js → p-f71af38f.entry.js} +2 -2
- package/dist/md3/{p-757e3aaf.entry.js → p-fac6da4c.entry.js} +2 -2
- package/dist/md3/{p-134b670a.entry.js → p-fc864f96.entry.js} +2 -2
- package/dist/md3/{p-32bdd439.entry.js → p-fd686966.entry.js} +2 -2
- package/dist/md3/p-nhfFYWzy.js +2 -0
- package/dist/md3/{p-C_ogF68H.js.map → p-nhfFYWzy.js.map} +1 -1
- package/dist/types/utils/lazy-loading-indicator.d.ts +7 -0
- package/dist/types/wasm/engine-abi.d.ts +14 -0
- package/hydrate/index.js +191 -113
- package/hydrate/index.mjs +191 -113
- package/package.json +30 -5
- package/dist/cjs/index-DlQ_5_Mv.js.map +0 -1
- package/dist/cjs/md-button_7.cjs.entry.js.map +0 -1
- package/dist/cjs/virtual-select-controller-CqriaZgm.js.map +0 -1
- package/dist/components/p-BEWIC0pC.js +0 -2
- package/dist/components/p-BEWIC0pC.js.map +0 -1
- package/dist/components/p-DXXUoRSH.js.map +0 -1
- package/dist/components/p-MWBNn6Lj.js +0 -2
- package/dist/components/p-MWBNn6Lj.js.map +0 -1
- package/dist/components/p-UdGDg2oJ.js.map +0 -1
- package/dist/esm/index-DTaX19_O.js.map +0 -1
- package/dist/esm/md-button_7.entry.js.map +0 -1
- package/dist/esm/virtual-select-controller-BEWIC0pC.js.map +0 -1
- package/dist/md3/p-04e97f5d.entry.js +0 -2
- package/dist/md3/p-19ee9c33.entry.js +0 -2
- package/dist/md3/p-21772851.entry.js +0 -2
- package/dist/md3/p-21772851.entry.js.map +0 -1
- package/dist/md3/p-3cce1de3.entry.js +0 -2
- package/dist/md3/p-47af9819.entry.js +0 -2
- package/dist/md3/p-47af9819.entry.js.map +0 -1
- package/dist/md3/p-4d82132d.entry.js +0 -2
- package/dist/md3/p-6b2871a0.entry.js +0 -2
- package/dist/md3/p-6c44cf13.entry.js +0 -2
- package/dist/md3/p-72457a85.entry.js +0 -2
- package/dist/md3/p-BEWIC0pC.js +0 -2
- package/dist/md3/p-BEWIC0pC.js.map +0 -1
- package/dist/md3/p-DTaX19_O.js +0 -3
- package/dist/md3/p-DTaX19_O.js.map +0 -1
- package/dist/md3/p-a3308c40.entry.js +0 -2
- package/dist/md3/p-a7ffb779.entry.js +0 -2
- package/dist/md3/p-a7ffb779.entry.js.map +0 -1
- package/dist/md3/p-a803da99.entry.js +0 -2
- package/dist/md3/p-a986fd24.entry.js +0 -2
- package/dist/md3/p-aaec2698.entry.js +0 -2
- package/dist/md3/p-ac35ac5f.entry.js +0 -2
- package/dist/md3/p-ac35ac5f.entry.js.map +0 -1
- package/dist/md3/p-b4631a55.entry.js +0 -2
- package/dist/md3/p-b4631a55.entry.js.map +0 -1
- package/dist/md3/p-ba2ebde1.entry.js +0 -2
- package/dist/md3/p-cf07e761.entry.js +0 -2
- package/dist/md3/p-e7dc5a32.entry.js +0 -2
- package/dist/md3/p-f31ab454.entry.js +0 -2
- package/dist/md3/p-fb61868c.entry.js +0 -2
- /package/dist/{components/p-uTEkf0sE.js.map → components-csr/p-BEmwDSzw.js.map} +0 -0
- /package/dist/{components/p-C8EP4S21.js.map → components-csr/p-BQKzjYcY.js.map} +0 -0
- /package/dist/{components/p-BwXpiUsu.js.map → components-csr/p-BWMwewtY.js.map} +0 -0
- /package/dist/{components/p-B0Opn6dK.js.map → components-csr/p-Bkt_X-6v.js.map} +0 -0
- /package/dist/{md3 → components-csr}/p-Bx6--dQF.js +0 -0
- /package/dist/{components/p-stybaFzj.js.map → components-csr/p-C3vB0Hd9.js.map} +0 -0
- /package/dist/{components/p-B3MWYEEJ.js.map → components-csr/p-CF7mq5T7.js.map} +0 -0
- /package/dist/{components/p-7fN_yCXW.js.map → components-csr/p-CVMM-tdC.js.map} +0 -0
- /package/dist/{md3 → components-csr}/p-C_ogF68H.js +0 -0
- /package/dist/{components/p-Ch2-tttM.js.map → components-csr/p-DMQ-6aj8.js.map} +0 -0
- /package/dist/{components/p-e2HRV63Y.js.map → components-csr/p-DfcpeJAu.js.map} +0 -0
- /package/dist/{components/p-Dp-w93ot.js.map → components-csr/p-DjKPc5EU.js.map} +0 -0
- /package/dist/{md3 → components-csr}/p-DvOKnoqK.js +0 -0
- /package/dist/{md3 → components-csr}/p-DzPKu-Ma.js +0 -0
- /package/dist/{md3 → components-csr}/p-RLxbNqRv.js +0 -0
- /package/dist/{components/p-6wZSqm_2.js.map → components-csr/p-R_guULjT.js.map} +0 -0
- /package/dist/{components/p-Ddiw2Kjw.js.map → components-csr/p-uSMrgqAy.js.map} +0 -0
- /package/dist/md3/{p-9ddbf247.entry.js.map → p-108f89d7.entry.js.map} +0 -0
- /package/dist/md3/{p-c6a12344.entry.js.map → p-114c270b.entry.js.map} +0 -0
- /package/dist/md3/{p-396089fd.entry.js.map → p-1edb5a0d.entry.js.map} +0 -0
- /package/dist/md3/{p-b34d385b.entry.js.map → p-35b05b45.entry.js.map} +0 -0
- /package/dist/md3/{p-c2dd8c8c.entry.js.map → p-38e9a583.entry.js.map} +0 -0
- /package/dist/md3/{p-be02624e.entry.js.map → p-3c0469aa.entry.js.map} +0 -0
- /package/dist/md3/{p-63b8c8d1.entry.js.map → p-408ee4be.entry.js.map} +0 -0
- /package/dist/md3/{p-edb34a6d.entry.js.map → p-43c708ad.entry.js.map} +0 -0
- /package/dist/md3/{p-3015c7e3.entry.js.map → p-4770b534.entry.js.map} +0 -0
- /package/dist/md3/{p-c861d774.entry.js.map → p-4b7cf934.entry.js.map} +0 -0
- /package/dist/md3/{p-2e09a7b7.entry.js.map → p-4f26bd60.entry.js.map} +0 -0
- /package/dist/md3/{p-7b463fbe.entry.js.map → p-4f2e82cb.entry.js.map} +0 -0
- /package/dist/md3/{p-be412e3f.entry.js.map → p-501bf161.entry.js.map} +0 -0
- /package/dist/md3/{p-c063c823.entry.js.map → p-56c7c570.entry.js.map} +0 -0
- /package/dist/md3/{p-2e9503d7.entry.js.map → p-56ca0c3c.entry.js.map} +0 -0
- /package/dist/md3/{p-ac8762e5.entry.js.map → p-5b63149a.entry.js.map} +0 -0
- /package/dist/md3/{p-c5af701b.entry.js.map → p-5f668b0a.entry.js.map} +0 -0
- /package/dist/md3/{p-8eb0b6a4.entry.js.map → p-6d65fc6a.entry.js.map} +0 -0
- /package/dist/md3/{p-e3124e1e.entry.js.map → p-707b6d7c.entry.js.map} +0 -0
- /package/dist/md3/{p-a5fee424.entry.js.map → p-71f1660b.entry.js.map} +0 -0
- /package/dist/md3/{p-1a8ec5bc.entry.js.map → p-7501170f.entry.js.map} +0 -0
- /package/dist/md3/{p-4e3d6e40.entry.js.map → p-7d1686a7.entry.js.map} +0 -0
- /package/dist/md3/{p-4dda4cb0.entry.js.map → p-845ca9cc.entry.js.map} +0 -0
- /package/dist/md3/{p-77a01bcc.entry.js.map → p-87f88d62.entry.js.map} +0 -0
- /package/dist/md3/{p-5b74694e.entry.js.map → p-89d47130.entry.js.map} +0 -0
- /package/dist/md3/{p-b0431a5c.entry.js.map → p-8bdcda53.entry.js.map} +0 -0
- /package/dist/md3/{p-c10a33c2.entry.js.map → p-8e7df348.entry.js.map} +0 -0
- /package/dist/md3/{p-05ae91b6.entry.js.map → p-90ccf4c3.entry.js.map} +0 -0
- /package/dist/md3/{p-da4e27d4.entry.js.map → p-a4d4cfed.entry.js.map} +0 -0
- /package/dist/md3/{p-5394254f.entry.js.map → p-a976498b.entry.js.map} +0 -0
- /package/dist/md3/{p-6038b907.entry.js.map → p-ab568d1c.entry.js.map} +0 -0
- /package/dist/md3/{p-bf7842f8.entry.js.map → p-adf8a415.entry.js.map} +0 -0
- /package/dist/md3/{p-45280bf4.entry.js.map → p-b2d88292.entry.js.map} +0 -0
- /package/dist/md3/{p-796f79f8.entry.js.map → p-b3b5247b.entry.js.map} +0 -0
- /package/dist/md3/{p-5b799707.entry.js.map → p-b4266f6b.entry.js.map} +0 -0
- /package/dist/md3/{p-c00f7514.entry.js.map → p-ba011453.entry.js.map} +0 -0
- /package/dist/md3/{p-6ba63c73.entry.js.map → p-bc24f0c9.entry.js.map} +0 -0
- /package/dist/md3/{p-0c2e824d.entry.js.map → p-c20fbb9e.entry.js.map} +0 -0
- /package/dist/md3/{p-fc0b325d.entry.js.map → p-c2944c87.entry.js.map} +0 -0
- /package/dist/md3/{p-4e45b2ff.entry.js.map → p-c58c68d0.entry.js.map} +0 -0
- /package/dist/md3/{p-0f764a1e.entry.js.map → p-d2e39c6e.entry.js.map} +0 -0
- /package/dist/md3/{p-50555bb7.entry.js.map → p-d8885f53.entry.js.map} +0 -0
- /package/dist/md3/{p-c1ca6f6c.entry.js.map → p-db6fb4e1.entry.js.map} +0 -0
- /package/dist/md3/{p-81843ff7.entry.js.map → p-dcba2857.entry.js.map} +0 -0
- /package/dist/md3/{p-65195996.entry.js.map → p-e357e8ac.entry.js.map} +0 -0
- /package/dist/md3/{p-39cb7c24.entry.js.map → p-e5c6795e.entry.js.map} +0 -0
- /package/dist/md3/{p-e6d7f0ff.entry.js.map → p-f403ad20.entry.js.map} +0 -0
- /package/dist/md3/{p-708a9313.entry.js.map → p-f5fd9a0b.entry.js.map} +0 -0
- /package/dist/md3/{p-aa0e7d4d.entry.js.map → p-f71af38f.entry.js.map} +0 -0
- /package/dist/md3/{p-757e3aaf.entry.js.map → p-fac6da4c.entry.js.map} +0 -0
- /package/dist/md3/{p-134b670a.entry.js.map → p-fc864f96.entry.js.map} +0 -0
- /package/dist/md3/{p-32bdd439.entry.js.map → p-fd686966.entry.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["approxWidth","text","fontSize","length","alignZeroAxes","a","b","topA","topB","rA","rB","share","Math","max","ellipsize","maxW","per","n","floor","slice","computeValueAxes","spec","theme","C","categories","series","map","s","range","data","stacked","stack","stackKeys","bands","stackSeries","hidden","forEach","si","d","min","vVals","push","onAxis2","axisIndex","hasAxis2","valueAxis2","some","sr","vVals2","vDomain","computeDomain","valueMin","valueMax","scale","valueScale","includeZero","vDomain2","vFound","resolveAxisBreaks","valueBreaks","vBreaks","ranges","openTopSection","normalizeBreaks","vTickVals","sectionedTicks","filter","t","inBreak","vTickLabels","v","valueTickFormatter","valueFormatter","v2Fmt","formatter","v2TickVals","v2TickLabels","maxV2LabelW","labelSize","catLabels","i","categoryFormatter","computeBandGeometry","plot","horizontal","mainStart","y","x","mainLen","height","width","widthWeights","find","pointWidths","weightAt","w","Number","isFinite","weightSum","bandStarts","sizeAt","startAt","bandCenter","groupInnerAt","categoryGapRatio","visibleIdx","_","overlay","groupNames","k","includes","groupCount","barWAt","barGapRatio","topSeriesFor","Map","botSeriesFor","r","topV","botV","get","Infinity","set","computeGutters","subtitleH","subtitle","titleH","title","titleSize","maxVLabelW","valueHidden","valueHideTicks","maxCatLabelW","categoryHidden","categoryHideTicks","maxDataLabelW","showLabels","flatMap","axisTitleV","valueLabel","axisTitleC","categoryLabel","labelRowH","catRot","categoryLabelRotation","catRotRad","abs","PI","catLabelRowH","sin","cos","legendActive","legend","legendSide","legendAtBottom","startsWith","legendTopRow","legendRows","estimateLegendRows","label","legendBandH","legendExtent","legendBandTop","legendBandBottom","legendSideW","legendLeftW","legendRightW","labelsAtLowEnd","showTotals","mirrorCats","categoryLabelsMirrored","compact","lowEndRoom","padTop","padRight","padBottom","padLeft","computeBarLayout","polar","radialScene","crossLen","vScale","makeBrokenScale","sizing","baselineVal","vScale2","valPx","valPx2","valPxFor","basePx","breakStrips","breaks","lo","px","hi","gap","splitBar","bar","h","pieces","strip","next","p","idx","all","radius","bars","hoverPoints","texts","barLabels","cornerRadius","groupPos","indexOf","byIndex","band","isRange","raw","rawNum","p0","p1","autoW","widthRatio","barGap","barW","barWidth","slotStart","barStart","positive","stackCell","atBaseline","isTop","chevInset","chevron","chevLead","chevronTipDepth","color","pointColors","seriesIndex","dataIndex","arrow","undefined","notch","value","low","high","textColor","size","atLowEnd","shown","txt","fits","onColorFor","fontWeight","inside","values","g","top","bottom","sum","any","outerSeg","gridlines","axisLines","TICK","yb","valueDash","dashPattern","gridDash","valueGridDash","categoryDash","pv","x1","y1","x2","y2","gridLineColor","dash","axisTicks","axisLineColor","catLine","categoryAxisLine","valLine","valueAxisLine","valBreaks","cuts","axisLineWithBreaks","c","breakBandSegments","tt","titlePlacement","titleAlign","align","baseline","key","textColorMuted","rx","rotate","mainPositions","minSpacing","step","ceil","bc","atTick","dir","nextC","prevC","room","catTitle","valTitle","background","areas","slices","lines","markers","legendPosition","xPositions","xValues","xLabels","barBaseline","nameGutter","cx","cy","vFmt","vTicks","vTickMaxW","valueGutter","R","hole","polarHole","ring","thickness","START","sweep","polarSweep","span","angleOf","midRadii","outerR","innerR","a0","a1","startAngle","endAngle","pill","capStart","capEnd","mid","midR","ringSlices","first","last","labelR","pointInSlice","py","dx","dy","hypot","twoPi","atan2","sliceAt","POLAR_DIM","POLAR_FADE_MS","POLAR_DWELL_MS","sliceKey","emphasizePolar","scene","dimByKey","surface","mixColor","lerp","e","FOLLOW_MS","keyerFor","cats","String","unique","Set","barKey","barKeys","base","seen","barsByKey","keys","m","lerpBar","from","to","barsDiffer","am","nb","ob","BarChartEngine","constructor","container","this","ctx","cb","hoverRaf","lastHoverIndex","hoverEnabled","clickable","hoverOpts","hasRendered","introRaf","lastDpr","followRaf","followLast","hoverSlice","dimAnim","dimRaf","dimLast","lastPointer","tooltipTimer","tooltipShown","displayed","pendingDrill","drillArmRaf","lastW","lastH","dprWatch","watchDevicePixelRatio","render","rtl","dirWatch","watchDirection","isRtl","followStep","now","dt","moving","renderFollow","requestAnimationFrame","stepDim","target","dimTarget","cur","sign","drawGeometry","handlePointerMove","rect","canvas","getBoundingClientRect","clientX","left","clientY","hovered","cancelAnimationFrame","style","cursor","changed","startDim","armTooltip","showPolarTooltip","onHover","nearestIndex","overBar","renderHover","hoverLayer","fontFamily","handlePointerLeave","clearHover","clearTimeout","handleClick","onPointClick","onLegendToggle","item","onLegendClick","getComputedStyle","position","document","createElement","cssText","setAttribute","legendLayer","barLabelLayer","append","getContext","addEventListener","getScene","setHoverEnabled","enabled","setClickable","setTooltip","opts","setSpec","resize","round","toDataURL","type","dispose","stopIntro","removeEventListener","remove","update","oldScene","sizeChanged","dpr","window","devicePixelRatio","clear","hadCategories","layout","mirrorScene","focusIndexInternal","syncOverlay","legendEl","querySelector","side","extent","offsetWidth","offsetHeight","variant","duration","resolveIntro","drill","reduce","prefersReducedMotion","motion","hasContent","animate","playDrill","playIntro","ensureFollow","paint","index","direction","arm","split","clearIntroOpacity","opacity","drillScene","start","frame","replay","setTransform","drawSceneCanvas","renderBarLabels","setOpacity","stepAnimation","alpha","tRaw","rate","prev","focusIndex","pt","hp","Boolean","pos","setTimeout","trigger"],"sources":["src/utils/charts/engine/bar-layout.ts","src/utils/charts/engine/bar-chart.ts"],"sourcesContent":["/*\n * Chart engine — bar layout (spec → RenderScene)\n * ===========================================================\n * The bar-chart sibling of layout.ts. Turns a resolved bar-chart\n * spec + theme + pixel size into a backend-agnostic RenderScene\n * whose `bars` array the Canvas2D backend draws. Handles\n * vertical + horizontal orientation, grouped / stacked / percentage\n * modes, category + bar gaps, rounded outer corners and optional\n * value labels. Pure — no DOM — so it's unit-tested on its numbers.\n * ===========================================================\n */\n\nimport type { MdChartAnimation, MdChartAxisBreaks, MdChartAxisValue, MdChartDataPoint, MdChartLegendPosition, MdChartLineStyle, MdChartScaleType, MdChartStackMode, MdChartTitleAlign } from '../types';\nimport { computeDomain, inBreak, makeBrokenScale, normalizeBreaks, openTopSection, resolveAxisBreaks, sectionedTicks, type Domain, type Scale } from './scale';\nimport { stackSeries } from './geometry';\nimport type { BarLabel, HoverPoint, HoverSeries, LegendItem, Rect, RenderScene, SceneBar, SceneSegment, TextItem } from './scene';\nimport { axisLineWithBreaks, breakBandSegments, dashPattern, estimateLegendRows, titlePlacement, type EngineTheme } from './layout';\nimport { onColorFor } from './color';\nimport { chevronTipDepth } from './renderer-canvas';\n\nexport interface BarSeriesSpec {\n label: string;\n color: string;\n data: MdChartDataPoint[];\n hidden: boolean;\n /** `[low, high]` pairs instead of `data` — a bar that FLOATS between two\n * values rather than growing from the baseline. Both ends are free, so both\n * are rounded and both are labelled. A range never joins a stack.\n * Normalised by the component, same as the line/area layout's. */\n range?: ([number, number] | null | undefined)[];\n /** Per-datum band WIDTH weights, keyed by data index — a variwide chart,\n * where a column's width carries a second variable. A category band is\n * shared by every series, so the first series to supply these sets the\n * widths for the whole axis. */\n pointWidths?: Record<number, number>;\n /** Which value axis this series is measured against: 0 (default, the left /\n * bottom one) or 1 (the opposite gutter). See {@link BarChartSpec.valueAxis2}. */\n axisIndex?: number;\n /** Ignore the group slotting and draw this series centred on the category\n * band, at {@link widthRatio} of it — a column IN FRONT of the others rather\n * than beside them. Fixed placement, in Highcharts' terms. */\n overlay?: boolean;\n /** Width of an overlaid series' bar as a fraction of the FULL category band\n * (not the gapped inner width — so it does not compound with\n * {@link BarChartSpec.categoryGapRatio}, and `0.5` really is half the band).\n * Ignored unless {@link overlay} is set. Default 0.45. */\n widthRatio?: number;\n /** Named stack group. Series sharing a name stack together; different names\n * sit SIDE BY SIDE, so one category can carry several stacks. Ignored when\n * the chart is not stacked. */\n stack?: string;\n /** Per-datum colour overrides, keyed by data index. A bar not named here\n * keeps the series colour. This is what a bar race needs: one series whose\n * every bar is a different entity. */\n pointColors?: Record<number, string>;\n}\n\nexport interface BarChartSpec {\n series: BarSeriesSpec[];\n title?: string;\n /** Horizontal alignment of the title over the plot. Default 'start'. */\n titleAlign?: MdChartTitleAlign;\n categories: MdChartAxisValue[];\n categoryFormatter: (v: MdChartAxisValue) => string;\n categoryLabel?: string;\n categoryHidden?: boolean;\n categoryHideTicks?: boolean;\n /** Stroke style for the category axis' line + tick marks. Default solid. */\n categoryDash?: MdChartLineStyle;\n /** Rotate the category tick labels by this many degrees. Negative leans the\n * text up to the right with its END under the tick, which is the convention\n * for long names on a bottom axis. 0 (default) leaves them upright, in which\n * case a label wider than its band is truncated with an ellipsis. Applies to\n * the bottom axis of a vertical chart; a horizontal chart's names already\n * have the whole gutter to run into. */\n categoryLabelRotation?: number;\n /** Repeat the category names in the opposite gutter as well. A population\n * pyramid is the case: the rows run out from a centre line in both\n * directions, so a name on one side only is a long way from half its data.\n * Horizontal charts (names in the side gutters). */\n categoryLabelsMirrored?: boolean;\n valueScale: MdChartScaleType;\n /** Ranges cut out of the value axis, so far-apart bars stay comparable. */\n valueBreaks?: MdChartAxisBreaks;\n valueMin?: number;\n valueMax?: number;\n valueFormatter: (v: number) => string;\n /** Formats the value AXIS ticks, when they want to read differently from the\n * values themselves — `300k` on the axis, `300,000` in the tooltip. */\n valueTickFormatter?: (v: number) => string;\n valueLabel?: string;\n /** A SECOND value axis, drawn in the opposite gutter and used by any series\n * whose `axisIndex` is 1. Two quantities on one category axis — a count and\n * a rate, a volume and a price — that share no scale. */\n valueAxis2?: {\n min?: number;\n max?: number;\n label?: string;\n formatter?: (v: number) => string;\n hidden?: boolean;\n };\n valueHidden?: boolean;\n valueHideTicks?: boolean;\n /** Draw the category axis' own line (the frame edge). Default true. */\n categoryAxisLine?: boolean;\n /** Draw the value axis' own line (the frame edge). Default true. Ticks +\n * gridlines are unaffected — a force diagram wants the grid but not the box. */\n valueAxisLine?: boolean;\n /** Stroke style for the value axis' line + tick marks. Default solid. */\n valueDash?: MdChartLineStyle;\n /** Stroke style for the gridlines drawn off the value ticks. Default solid. */\n valueGridDash?: MdChartLineStyle;\n stack: MdChartStackMode;\n horizontal: boolean;\n /** Fraction of the category band that is whitespace (0..1). */\n categoryGapRatio: number;\n /** Gap between sibling grouped bars, as a fraction of bar width (0..1). */\n barGapRatio: number;\n /** Fixed bar WIDTH in px, centred in each slot. Undefined = auto (fill the slot). */\n barWidth?: number;\n cornerRadius: number;\n /** Wrap the bars around a circle: one concentric RING per category, the value\n * axis running as an angle. A radial (polar) bar chart. */\n polar?: boolean;\n /** Radius of the hole at the centre of a polar chart, as a fraction of the\n * full radius. Default 0.22. */\n polarHole?: number;\n /** How much of the circle the value axis spans, as a fraction. Default 0.75 —\n * the remaining quarter is where the category names go. */\n polarSweep?: number;\n /** Draw the bars as CHEVRONS pointing away from the baseline, interlocking\n * along a stack — a force diagram, where each segment hands its contribution\n * on to the next rather than merely sitting on it. */\n chevron?: boolean;\n showLabels: boolean;\n /** Print each stack's TOTAL past the end of the column, on top of the\n * per-segment labels. Stacked charts only — an unstacked bar IS its total. */\n showTotals?: boolean;\n /** A quieter line under the title. */\n subtitle?: string;\n /** Legend anchor, or `'none'` to hide it. */\n legend?: MdChartLegendPosition | 'none';\n /** Measured legend extent (px) from the engine's two-pass render — reserves the\n * gutter to the legend's REAL wrapped size instead of an estimate, so a\n * many-series legend can't spill onto the plot. Set by the engine, not authors. */\n legendExtent?: number;\n /** Sparkline mode: edge-to-edge, no axes / grid / title / legend. */\n compact?: boolean;\n /** Small perpendicular tick marks on the value + category axes. Default false. */\n axisTicks?: boolean;\n /** Entry-animation variant played on first render. Default 'expressive'. */\n animation?: MdChartAnimation;\n /** Entry-animation duration override (ms); ≤ 0 disables. */\n animationDuration?: number;\n /** Legacy on/off flag (pre-variant). `false` → no animation. */\n animate?: boolean;\n}\n\nfunction approxWidth(text: string, fontSize: number): number {\n return text.length * fontSize * 0.58;\n}\n\n/**\n * Extend whichever value axis has the smaller below-zero share so both axes'\n * ZERO lands on the same pixel — the shared baseline a dual-axis bar chart needs\n * so bars from either axis grow from one line and a negative on either opens the\n * same below-zero band. The axis that already has the larger share is untouched\n * (nothing is squashed); the other's negative side is stretched to match. Left\n * alone when an axis has no positive extent, or both are already zero-based.\n */\nfunction alignZeroAxes(a: Domain, b: Domain): [Domain, Domain] {\n const topA = a[1];\n const topB = b[1];\n if (!(topA > 0) || !(topB > 0)) return [a, b];\n const rA = a[0] < 0 ? -a[0] / topA : 0;\n const rB = b[0] < 0 ? -b[0] / topB : 0;\n const share = Math.max(rA, rB);\n if (share <= 0) return [a, b];\n return [\n [-share * topA, topA],\n [-share * topB, topB],\n ];\n}\n\n/** Cut `text` to `maxW` pixels, ending in an ellipsis. Same width estimate as\n * {@link approxWidth}, so the two agree about what fits. */\nfunction ellipsize(text: string, maxW: number, fontSize: number): string {\n if (maxW <= 0 || approxWidth(text, fontSize) <= maxW) return text;\n const per = fontSize * 0.58;\n const n = Math.floor(maxW / per) - 1;\n return n >= 1 ? `${text.slice(0, n)}…` : '';\n}\n\n/**\n * Phase 1 of the bar layout: turn the series into value BANDS (`[base, top]`\n * per datum, stacked if asked), derive the value domain(s), and resolve the\n * axis ticks / breaks / category labels off them. Pure `(spec, theme) → bundle`\n * with no pixel geometry — the plot rect doesn't exist yet. Everything a later\n * phase needs from here is returned; nothing here reads the box size.\n */\nfunction computeValueAxes(spec: BarChartSpec, theme: EngineTheme) {\n const C = spec.categories.length || Math.max(0, ...spec.series.map((s) => (s.range ?? s.data ?? []).length));\n const stacked = spec.stack !== 'none';\n\n // A range series is never stacked — it already carries both its edges, and\n // piling one onto a cumulative baseline would put its low somewhere that is\n // not a value anyone measured.\n const stackKeys = spec.series.map((s) => (stacked && !s.range ? s.stack || 'stacked' : '__unstacked__'));\n // Hidden series contribute empty data so they don't reserve a stack band.\n const bands = stackSeries(\n spec.series.map((s) => (s.hidden || s.range ? [] : (s.data ?? []))),\n spec.stack,\n stackKeys,\n );\n // Range bands are the datum itself, low edge first so the band is always\n // [base, top] like every other one downstream.\n spec.series.forEach((s, si) => {\n if (!s.range || s.hidden) return;\n bands[si] = s.range.map((d) => (d ? ([Math.min(d[0], d[1]), Math.max(d[0], d[1])] as [number, number]) : d));\n });\n const vVals: number[] = [];\n spec.series.forEach((s, si) => {\n if (s.hidden) return;\n bands[si].forEach((b) => {\n if (b) vVals.push(b[0], b[1]);\n });\n });\n const onAxis2 = (si: number) => (spec.series[si].axisIndex ?? 0) === 1;\n const hasAxis2 = !!spec.valueAxis2 && spec.series.some((sr, si) => !sr.hidden && onAxis2(si));\n const vVals2: number[] = [];\n if (hasAxis2) {\n // Split the collected values by axis — a series on the right-hand scale\n // must not stretch the left one's domain, which is the whole point of\n // having two.\n vVals.length = 0;\n spec.series.forEach((sr, si) => {\n if (sr.hidden) return;\n bands[si].forEach((b) => {\n if (b) (onAxis2(si) ? vVals2 : vVals).push(b[0], b[1]);\n });\n });\n }\n let vDomain = computeDomain(vVals, {\n min: spec.valueMin,\n max: spec.valueMax,\n scale: spec.valueScale,\n includeZero: true,\n });\n let vDomain2 = hasAxis2\n ? computeDomain(vVals2, { min: spec.valueAxis2!.min, max: spec.valueAxis2!.max, scale: spec.valueScale, includeZero: true })\n : vDomain;\n // Zero-align the two value axes so a dual-axis chart shares ONE baseline (see\n // alignZeroAxes). Only for the linear, auto-ranged case — a pinned min/max is\n // the author's own call, and a log axis has no zero to share. Both axes then\n // tick across their aligned range, so the below-zero band carries gridlines and\n // labels on the primary axis instead of reading as empty space.\n if (hasAxis2 && spec.valueScale === 'value' && spec.valueMin == null && spec.valueMax == null && spec.valueAxis2!.min == null && spec.valueAxis2!.max == null) {\n [vDomain, vDomain2] = alignZeroAxes(vDomain, vDomain2);\n }\n\n // Value-axis breaks: same treatment as the line chart's y axis — the cut\n // costs its gap in pixels, and each surviving section gets its own ticks.\n // Normalised against the axis domain straight away (see computeLayout): a cut\n // the domain rejects must not section the ticks either.\n const vFound = resolveAxisBreaks(spec.valueBreaks, vVals, spec.valueScale);\n // Open a top-edge cut (an outlier pinned to the axis top) into a real section so\n // it carries ticks + gridlines instead of a blank band above the break.\n const vBreaks = { ...vFound, ranges: openTopSection(normalizeBreaks(vFound.ranges, vDomain), vDomain, spec.valueScale) };\n const vTickVals = sectionedTicks(vDomain, vBreaks.ranges, spec.valueScale, 6).filter(\n (t) => !inBreak(vBreaks.ranges, t),\n );\n const vTickLabels = vTickVals.map((v) => (spec.valueTickFormatter ?? spec.valueFormatter)(v));\n const v2Fmt = spec.valueAxis2?.formatter ?? spec.valueTickFormatter ?? spec.valueFormatter;\n const v2TickVals = hasAxis2 && !spec.valueAxis2!.hidden ? sectionedTicks(vDomain2, [], spec.valueScale, 6) : [];\n const v2TickLabels = v2TickVals.map((v) => v2Fmt(v));\n const maxV2LabelW = Math.max(0, ...v2TickLabels.map((t) => approxWidth(t, theme.labelSize)));\n const catLabels: string[] = [];\n for (let i = 0; i < C; i++) catLabels.push(spec.categoryFormatter(spec.categories[i] ?? i));\n\n return { C, stacked, stackKeys, bands, onAxis2, hasAxis2, vDomain, vDomain2, vBreaks, vTickVals, vTickLabels, v2TickVals, v2TickLabels, maxV2LabelW, catLabels };\n}\n\n/**\n * Phase 4: category band geometry along the MAIN axis (x for a vertical chart,\n * y for a horizontal one). Needs the plot rect, so it runs after the gutters are\n * known. Returns closures — `sizeAt`/`bandCenter`/`groupInnerAt`/`barWAt` — plus\n * the slot bookkeeping (`groupNames`, `visibleIdx`) and the per-stack outermost-\n * segment maps (`topSeriesFor`/`botSeriesFor`) used to round only the free end.\n */\nfunction computeBandGeometry(\n spec: BarChartSpec,\n plot: { x: number; y: number; width: number; height: number },\n horizontal: boolean,\n C: number,\n stacked: boolean,\n stackKeys: string[],\n bands: ReturnType<typeof computeValueAxes>['bands'],\n) {\n const mainStart = horizontal ? plot.y : plot.x;\n const mainLen = horizontal ? plot.height : plot.width;\n // Category bands are equal unless a series supplies width weights, in which\n // case each band takes a share of the main axis proportional to its weight —\n // a variwide chart, where the column's width is a second variable. The bands\n // are shared by every series, so the first series to ask decides for all.\n const widthWeights = spec.series.find((s) => !s.hidden && s.pointWidths)?.pointWidths;\n const weightAt = (i: number) => {\n const w = widthWeights?.[i];\n return typeof w === 'number' && Number.isFinite(w) && w > 0 ? w : 1;\n };\n let weightSum = 0;\n const bandStarts: number[] = [];\n for (let i = 0; i < C; i++) {\n bandStarts.push(weightSum);\n weightSum += weightAt(i);\n }\n if (weightSum <= 0) weightSum = Math.max(1, C);\n const sizeAt = (i: number) => (C > 0 ? (mainLen * weightAt(i)) / weightSum : mainLen);\n const startAt = (i: number) => mainStart + (mainLen * bandStarts[i]) / weightSum;\n const bandCenter = (i: number) => startAt(i) + sizeAt(i) / 2;\n const groupInnerAt = (i: number) => sizeAt(i) * (1 - spec.categoryGapRatio);\n\n // An overlaid series is drawn ON the band rather than in a slot of it, so it\n // is left out of the slot count — otherwise it would reserve a place it never\n // stands in and narrow every other bar for nothing.\n const visibleIdx = spec.series.map((_, i) => i).filter((i) => !spec.series[i].hidden && !spec.series[i].overlay);\n // Slots along the category band. Unstacked, every visible series gets one.\n // Stacked, every distinct stack GROUP gets one — so a chart mixing\n // `stack: 'a'` and `stack: 'b'` draws two stacks side by side rather than\n // piling all six series into one column.\n const groupNames: string[] = [];\n for (const i of visibleIdx) {\n const k = stackKeys[i];\n if (!groupNames.includes(k)) groupNames.push(k);\n }\n const groupCount = stacked ? Math.max(1, groupNames.length) : Math.max(1, visibleIdx.length);\n // barW: split the group among sibling bars, leaving barGapRatio between them.\n const barWAt = (i: number) => groupInnerAt(i) / (groupCount + (groupCount - 1) * spec.barGapRatio);\n\n // Outermost segment per category, per sign, for rounding the free (outer) end:\n // the top of the highest positive segment (max band[1]) and the bottom of the\n // lowest negative segment (min band[0]).\n // Keyed `${group}|${category}` — the outermost segment is per STACK, not per\n // category, or only one of two side-by-side stacks would get a rounded cap.\n const topSeriesFor = new Map<string, number>();\n const botSeriesFor = new Map<string, number>();\n if (stacked) {\n for (let r = 0; r < C; r++) {\n const topV = new Map<string, number>();\n const botV = new Map<string, number>();\n spec.series.forEach((s, si) => {\n if (s.hidden) return;\n const b = bands[si][r];\n if (!b) return;\n const k = `${stackKeys[si]}|${r}`;\n if (b[1] > (topV.get(k) ?? -Infinity)) {\n topV.set(k, b[1]);\n topSeriesFor.set(k, si);\n }\n if (b[0] < (botV.get(k) ?? Infinity)) {\n botV.set(k, b[0]);\n botSeriesFor.set(k, si);\n }\n });\n }\n }\n\n return { sizeAt, bandCenter, groupInnerAt, barWAt, groupNames, visibleIdx, topSeriesFor, botSeriesFor, mainLen };\n}\n\n/**\n * Phase 2: reserve gutters for the chrome — title, legend, axis tick labels,\n * axis titles, and the room a free-end / low-end data label needs — then derive\n * the plot rect from what's left. Returns the plot plus the handful of label /\n * legend metrics the later text phase still needs (`compact`, the legend band\n * heights, `lowEndRoom`, the rotation, `mirrorCats`, `maxDataLabelW`).\n */\nfunction computeGutters(\n spec: BarChartSpec,\n theme: EngineTheme,\n width: number,\n height: number,\n horizontal: boolean,\n hasAxis2: boolean,\n vTickLabels: string[],\n catLabels: string[],\n maxV2LabelW: number,\n) {\n const subtitleH = spec.subtitle ? theme.labelSize + 4 : 0;\n const titleH = spec.title ? theme.titleSize + 10 + subtitleH : 0;\n const maxVLabelW = spec.valueHidden || spec.valueHideTicks ? 0 : Math.max(0, ...vTickLabels.map((t) => approxWidth(t, theme.labelSize)));\n const maxCatLabelW = spec.categoryHidden || spec.categoryHideTicks ? 0 : Math.max(0, ...catLabels.map((t) => approxWidth(t, theme.labelSize)));\n /**\n * Room the value labels need past the end of a bar.\n *\n * Estimated from the widest one the chart will actually print, not a flat\n * margin: \"8\" and \"4,695\" are the same reservation under a constant, and the\n * long one then ran off the plot — on a horizontal chart the longest bar is\n * also the one whose label has least room, so it is always the value that\n * matters most that gets clipped.\n */\n // Widest label that will actually be printed — a range series prints both of\n // its edges, an ordinary one its value.\n const maxDataLabelW = spec.showLabels\n ? Math.max(\n 0,\n ...spec.series.flatMap((sr) =>\n sr.range\n ? sr.range.flatMap((d) => (d ? [approxWidth(spec.valueFormatter(d[0]), theme.labelSize), approxWidth(spec.valueFormatter(d[1]), theme.labelSize)] : []))\n : (sr.data ?? []).map((v) => (typeof v === 'number' ? approxWidth(spec.valueFormatter(v), theme.labelSize) : 0)),\n ),\n )\n : 0;\n const axisTitleV = spec.valueLabel ? theme.labelSize + 6 : 0;\n const axisTitleC = spec.categoryLabel ? theme.labelSize + 6 : 0;\n const labelRowH = theme.labelSize + 8;\n // Rotated category labels take a taller row: the text's own length now runs\n // partly DOWN the page, so the row has to hold its vertical projection.\n const catRot = !horizontal ? (spec.categoryLabelRotation ?? 0) : 0;\n const catRotRad = (Math.abs(catRot) * Math.PI) / 180;\n const catLabelRowH = catRot\n ? maxCatLabelW * Math.sin(catRotRad) + theme.labelSize * Math.cos(catRotRad) + 8\n : labelRowH;\n\n // A top/bottom legend gets a reserved band; a left/right legend gets a\n // reserved side gutter (a vertically-centred column) so it never overlaps the\n // plot or the axis labels.\n const legendActive = !!spec.legend && spec.legend !== 'none' && spec.series.length > 1;\n const legendSide = legendActive && (spec.legend === 'left' || spec.legend === 'right');\n const legendAtBottom = legendActive && !legendSide && spec.legend!.startsWith('bottom');\n const legendTopRow = legendActive && !legendSide && !legendAtBottom;\n const legendRows = legendTopRow || legendAtBottom ? estimateLegendRows(spec.series.map((s) => s.label), theme.labelSize, width * 0.86) : 1;\n // Prefer the engine's MEASURED legend extent (two-pass render) over the estimate.\n const legendBandH = spec.legendExtent != null && (legendTopRow || legendAtBottom) ? spec.legendExtent + 8 : legendRows * (theme.labelSize + 8) + 6;\n const legendBandTop = legendTopRow ? legendBandH : 0;\n const legendBandBottom = legendAtBottom ? legendBandH : 0;\n const legendSideW = legendSide ? (spec.legendExtent != null ? spec.legendExtent + 16 : Math.max(0, ...spec.series.map((s) => approxWidth(s.label, theme.labelSize))) + 34) : 0;\n const legendLeftW = spec.legend === 'left' ? legendSideW : 0;\n const legendRightW = spec.legend === 'right' ? legendSideW : 0;\n\n // Sparkline mode fills its host edge-to-edge — no gutters for chrome.\n // Does any data label land at the LOW end of a bar (left on a horizontal\n // chart, below on a vertical one)? A range prints both edges; an ordinary\n // series prints below the baseline only where it goes negative. Without this\n // the gutter is sized for the high side alone and the low label runs into the\n // category names.\n const labelsAtLowEnd =\n (spec.showLabels || spec.showTotals) &&\n spec.series.some((sr) => !sr.hidden && (!!sr.range || (sr.data ?? []).some((v) => typeof v === 'number' && v < 0)));\n\n const mirrorCats = !!spec.categoryLabelsMirrored && horizontal && !spec.categoryHidden && !spec.categoryHideTicks;\n const compact = !!spec.compact;\n // Both the category name and a low-end data label are anchored to the plot's\n // edge, so widening the gutter alone just makes them overlap further out.\n // The category name steps back past the data label's lane.\n const lowEndRoom = labelsAtLowEnd ? (horizontal ? maxDataLabelW + 8 : theme.labelSize + 4) : 0;\n let padTop: number;\n let padRight: number;\n let padBottom: number;\n let padLeft: number;\n if (compact) {\n padTop = padRight = padBottom = padLeft = 2;\n } else if (horizontal) {\n // categories on the y (left) gutter, values on the x (bottom) gutter\n padTop = titleH + 8 + legendBandTop;\n padLeft = maxCatLabelW + 12 + axisTitleC + legendLeftW + (labelsAtLowEnd ? maxDataLabelW + 8 : 0);\n padBottom = (spec.valueHidden || spec.valueHideTicks ? 0 : labelRowH) + axisTitleV + 6 + legendBandBottom;\n padRight = 12 + (spec.showLabels ? maxDataLabelW + 8 : 0) + legendRightW + (mirrorCats ? maxCatLabelW + 12 : 0);\n } else {\n padTop = titleH + 8 + legendBandTop + (spec.showLabels ? theme.labelSize + 4 : 0);\n // A vertical chart's labels sit ABOVE the bar, so their width is not the\n // constraint — but the outermost columns' labels still overhang sideways.\n padRight = 12 + legendRightW + (spec.showLabels ? maxDataLabelW / 2 : 0) + (hasAxis2 ? maxV2LabelW + 10 + (spec.valueAxis2!.label ? theme.labelSize + 6 : 0) : 0);\n padLeft = maxVLabelW + 10 + axisTitleV + legendLeftW;\n padBottom = (spec.categoryHidden || spec.categoryHideTicks ? 0 : catLabelRowH) + axisTitleC + 6 + legendBandBottom + (labelsAtLowEnd ? theme.labelSize + 4 : 0);\n }\n\n const plot = {\n x: padLeft,\n y: padTop,\n width: Math.max(1, width - padLeft - padRight),\n height: Math.max(1, height - padTop - padBottom),\n };\n\n return { plot, compact, legendBandTop, legendBandBottom, lowEndRoom, mirrorCats, maxDataLabelW, catRot, catRotRad };\n}\n\nexport function computeBarLayout(spec: BarChartSpec, theme: EngineTheme, width: number, height: number): RenderScene {\n const horizontal = spec.horizontal;\n // Phase 1: value bands, domains, ticks, breaks, category labels (no pixels yet).\n const { C, stacked, stackKeys, bands, onAxis2, hasAxis2, vDomain, vDomain2, vBreaks, vTickVals, vTickLabels, v2TickVals, v2TickLabels, maxV2LabelW, catLabels } =\n computeValueAxes(spec, theme);\n\n if (spec.polar) return radialScene(spec, theme, width, height, bands, vDomain, catLabels, C);\n\n // Phase 2: reserve gutters for the chrome (title, legend, axis labels) and\n // derive the plot rect + the label metrics later phases still need.\n const { plot, compact, legendBandTop, legendBandBottom, lowEndRoom, mirrorCats, maxDataLabelW, catRot, catRotRad } =\n computeGutters(spec, theme, width, height, horizontal, hasAxis2, vTickLabels, catLabels, maxV2LabelW);\n\n // ── value scale maps onto the cross length ──\n const crossLen = horizontal ? plot.width : plot.height;\n const vScale: Scale = makeBrokenScale(vDomain, crossLen, spec.valueScale, vBreaks.ranges, vBreaks.sizing);\n // Bars grow from zero; clamp it into the (zero-including) domain.\n const baselineVal = Math.min(vDomain[1], Math.max(vDomain[0], 0));\n // pixel of a value along the cross axis\n const vScale2: Scale = hasAxis2 ? makeBrokenScale(vDomain2, crossLen, spec.valueScale, [], vBreaks.sizing) : vScale;\n const valPx = (v: number) => (horizontal ? plot.x + vScale.scale(v) : plot.y + plot.height - vScale.scale(v));\n const valPx2 = (v: number) => (horizontal ? plot.x + vScale2.scale(v) : plot.y + plot.height - vScale2.scale(v));\n /** Project a value for the axis THIS series is measured against. */\n const valPxFor = (si: number, v: number) => (hasAxis2 && onAxis2(si) ? valPx2(v) : valPx(v));\n const basePx = valPx(baselineVal);\n\n /**\n * The pixel strips the cuts occupy, along the value axis. A bar drawn\n * straight through one would hide the very discontinuity the break exists to\n * show — every bar grows from the baseline, so every bar crosses it.\n */\n // Taken from each cut's own pixel span rather than by re-scaling its\n // endpoints: a cut whose top section holds a single value has zero data\n // width, so scaling `to` would return the far end of that section and the\n // \"strip\" would swallow half the axis.\n const breakStrips = ((vScale as { breaks?: readonly { px: number; gap: number }[] }).breaks ?? []).map((b) =>\n horizontal\n ? { lo: plot.x + b.px, hi: plot.x + b.px + b.gap }\n : { lo: plot.y + plot.height - b.px - b.gap, hi: plot.y + plot.height - b.px },\n );\n\n /** A bar with any strip removed from it — one rect per surviving piece. */\n const splitBar = (bar: SceneBar): SceneBar[] => {\n if (!breakStrips.length) return [bar];\n const lo = horizontal ? bar.x : bar.y;\n const hi = lo + (horizontal ? bar.w : bar.h);\n let pieces: { lo: number; hi: number }[] = [{ lo, hi }];\n for (const strip of breakStrips) {\n const next: { lo: number; hi: number }[] = [];\n for (const p of pieces) {\n if (strip.hi <= p.lo || strip.lo >= p.hi) {\n next.push(p);\n continue;\n }\n if (strip.lo > p.lo) next.push({ lo: p.lo, hi: strip.lo });\n if (strip.hi < p.hi) next.push({ lo: strip.hi, hi: p.hi });\n }\n pieces = next;\n }\n if (pieces.length === 1 && pieces[0].lo === lo && pieces[0].hi === hi) return [bar];\n return pieces\n .filter((p) => p.hi - p.lo > 0.5)\n .map((p, idx, all) => ({\n ...bar,\n // Only the outermost piece keeps the rounded cap.\n radius: (idx === (horizontal ? all.length - 1 : 0) ? bar.radius : [0, 0, 0, 0]) as SceneBar['radius'],\n ...(horizontal ? { x: p.lo, w: p.hi - p.lo } : { y: p.lo, h: p.hi - p.lo }),\n }));\n };\n\n // Phase 4: category band geometry — where each band sits along the main axis,\n // how the group splits into sibling bar slots, and which segment caps a stack.\n const { sizeAt, bandCenter, groupInnerAt, barWAt, groupNames, visibleIdx, topSeriesFor, botSeriesFor, mainLen } =\n computeBandGeometry(spec, plot, horizontal, C, stacked, stackKeys, bands);\n\n const bars: SceneBar[] = [];\n const hoverPoints: HoverSeries[] = [];\n const texts: TextItem[] = [];\n // Value labels bound to their bar rather than to a fixed pixel, so the bar-\n // label overlay can re-derive their position from the (animating) bar tip\n // every frame instead of leaving them stranded at the final geometry.\n const barLabels: BarLabel[] = [];\n const r = spec.cornerRadius;\n\n spec.series.forEach((s, si) => {\n if (s.hidden) return;\n const groupPos = stacked ? Math.max(0, groupNames.indexOf(stackKeys[si])) : Math.max(0, visibleIdx.indexOf(si));\n const byIndex: Record<number, HoverPoint> = {};\n for (let i = 0; i < C; i++) {\n const band = bands[si][i];\n if (!band) continue;\n const isRange = !!s.range;\n const raw = isRange ? null : s.data[i];\n const rawNum = typeof raw === 'number' ? raw : band[1];\n const p0 = valPxFor(si, band[0]);\n const p1 = valPxFor(si, band[1]);\n // Overlaid: centred on the band at its own width, in front of whatever\n // the slotted series drew. Otherwise: one slot of the group.\n // Overlay width is a fraction of the FULL band, so widthRatio doesn't\n // silently compound with the category gap (which made it read far thinner\n // than the number suggests). A slotted bar still lives inside the gap.\n const autoW = s.overlay ? sizeAt(i) * (s.widthRatio ?? 0.45) : barWAt(i);\n const barGap = autoW * spec.barGapRatio;\n // A configured `barWidth` (px) narrows each bar and CENTRES it in its slot,\n // leaving the slot geometry (so grouped bars stay put) alone, clamped to the\n // slot so it can't overrun a neighbour. Undefined → auto (fills the slot).\n const barW = spec.barWidth != null && !s.overlay ? Math.min(Math.max(1, spec.barWidth), autoW) : autoW;\n const slotStart = s.overlay\n ? bandCenter(i) - autoW / 2\n : bandCenter(i) - groupInnerAt(i) / 2 + groupPos * (autoW + barGap);\n const barStart = slotStart + (autoW - barW) / 2;\n // Direction comes from the raw value's sign — stacked bands are always\n // stored [base, top] so band[1] >= band[0] would misread negatives.\n const positive = rawNum >= 0;\n const stackCell = `${stackKeys[si]}|${i}`;\n // The segment sitting ON the baseline has nothing behind it to fill a\n // notch — two stacks meeting at zero would leave a hole between them.\n const atBaseline = positive ? band[0] === 0 : band[1] === 0;\n // A range bar has TWO free ends, so both get the cap.\n const isTop = isRange || !stacked || (positive ? topSeriesFor.get(stackCell) === si : botSeriesFor.get(stackCell) === si);\n\n // Chevron force diagram: recede each segment from its shared boundaries so\n // the interlocking arrows read as SEPARATE areas rather than one continuous\n // ribbon. The tip/notch depth comes from the (unchanged) thickness, so both\n // edges pull back together and the V-shaped gap between neighbours stays\n // uniform. Clamped so a short segment keeps most of its length.\n const chevInset = spec.chevron ? Math.min(barW * 0.03, 5, Math.abs(p1 - p0) * 0.35) : 0;\n // A chevron's drawn point overflows its rect by the tip depth, and the\n // rect is itself pulled back by half the inset. The hover marker belongs\n // ON that point: left at the plain value edge it floats behind the arrow,\n // reading as though it marks nothing.\n const chevLead = spec.chevron ? chevronTipDepth(barW) - chevInset / 2 : 0;\n\n let bar: SceneBar;\n if (horizontal) {\n const x = Math.min(p0, p1) + chevInset / 2;\n const w = Math.abs(p1 - p0) - chevInset;\n const radius: [number, number, number, number] = isRange\n ? [r, r, r, r]\n : isTop\n ? positive\n ? [0, r, r, 0]\n : [r, 0, 0, r]\n : [0, 0, 0, 0];\n bar = { x, y: barStart, w, h: barW, color: s.pointColors?.[i] ?? s.color, radius, seriesIndex: si, dataIndex: i, horizontal: true, arrow: spec.chevron ? (positive ? 1 : -1) : undefined, notch: spec.chevron ? !atBaseline : undefined };\n byIndex[i] = { x: (positive ? Math.max(p0, p1) + chevLead : Math.min(p0, p1) - chevLead), y: barStart + barW / 2, value: rawNum, color: bar.color, ...(isRange ? { low: band[0], high: band[1] } : null) };\n } else {\n const y = Math.min(p0, p1) + chevInset / 2;\n const h = Math.abs(p1 - p0) - chevInset;\n const radius: [number, number, number, number] = isRange\n ? [r, r, r, r]\n : isTop\n ? positive\n ? [r, r, 0, 0]\n : [0, 0, r, r]\n : [0, 0, 0, 0];\n bar = { x: barStart, y, w: barW, h, color: s.pointColors?.[i] ?? s.color, radius, seriesIndex: si, dataIndex: i, horizontal: false, arrow: spec.chevron ? (positive ? 1 : -1) : undefined, notch: spec.chevron ? !atBaseline : undefined };\n byIndex[i] = { x: barStart + barW / 2, y: (positive ? Math.min(p0, p1) - chevLead : Math.max(p0, p1) + chevLead), value: rawNum, color: bar.color, ...(isRange ? { low: band[0], high: band[1] } : null) };\n }\n bars.push(...splitBar(bar));\n\n if (spec.showLabels && isRange) {\n // Both edges, each bound to its OWN free end of the floating bar, so they\n // ride out from the baseline (zero line) with the bar as it opens during\n // the intro instead of sitting frozen at the final low/high.\n barLabels.push(\n { seriesIndex: si, dataIndex: i, text: spec.valueFormatter(band[0]), color: theme.textColor, size: theme.labelSize, atLowEnd: true },\n { seriesIndex: si, dataIndex: i, text: spec.valueFormatter(band[1]), color: theme.textColor, size: theme.labelSize, atLowEnd: false },\n );\n } else if (spec.showLabels && stacked && typeof raw === 'number') {\n // A stacked segment has no free end to hang a label off — every segment\n // but the outermost is boxed in by its neighbours. The value goes INSIDE\n // the segment, in whichever of black/white reads on that fill, and is\n // dropped when the segment is too small to hold it rather than spilling\n // over the segments either side.\n // In percentage mode the SHARE is what the column shows, and it is\n // already what the band holds — labelling `raw` would print the\n // un-normalised figure against a percent formatter (33600%).\n const shown = spec.stack === 'percentage' ? Math.abs(band[1] - band[0]) * (raw < 0 ? -1 : 1) : raw;\n const txt = spec.valueFormatter(shown);\n const fits = horizontal\n ? bar.w > approxWidth(txt, theme.labelSize) + 8 && bar.h > theme.labelSize\n : bar.h > theme.labelSize + 6 && bar.w > approxWidth(txt, theme.labelSize) + 4;\n if (fits) {\n // Bound to the bar so it stays centred as the segment grows in — the\n // overlay recomputes its position from the bar each frame.\n barLabels.push({ seriesIndex: si, dataIndex: i, text: txt, color: onColorFor(bar.color), size: theme.labelSize, fontWeight: 600, inside: true });\n }\n } else if (spec.showLabels && typeof raw === 'number') {\n // Free-end value label. Bound to the bar (not a fixed pixel) so it rides\n // out to the tip with the bar during the entry animation instead of\n // snapping to the final position. The overlay derives the exact anchor +\n // alignment from the bar's live geometry and orientation.\n barLabels.push({ seriesIndex: si, dataIndex: i, text: spec.valueFormatter(raw), color: theme.textColor, size: theme.labelSize, atLowEnd: !positive });\n }\n }\n hoverPoints.push({ seriesIndex: si, color: s.color, label: s.label, byIndex, values: s.range ? bands[si].map((b) => (b ? b[1] : null)) : s.data });\n });\n\n // ── stack totals ──\n // One label per stack per category, past its free end. Read off the bands\n // rather than re-summing the data, so a hidden series drops out of the total\n // the same way it drops out of the column.\n // Percentage mode has nothing to total: every column is 100 by construction.\n if (spec.showTotals && stacked && spec.stack !== 'percentage') {\n for (let i = 0; i < C; i++) {\n for (const g of groupNames) {\n let top = -Infinity;\n let bottom = Infinity;\n let sum = 0;\n let any = false;\n spec.series.forEach((s, si) => {\n if (s.hidden || stackKeys[si] !== g) return;\n const b = bands[si][i];\n const v = s.data?.[i];\n if (!b) return;\n any = true;\n top = Math.max(top, b[1]);\n bottom = Math.min(bottom, b[0]);\n if (typeof v === 'number') sum += v;\n });\n if (!any) continue;\n // Percentage mode normalises every column to 100, so the interesting\n // total is the raw one the percentages were taken from.\n const txt = spec.valueFormatter(sum);\n // Past whichever end the stack actually reaches — an all-negative\n // column's free end is the bottom.\n const positive = top > 0 || bottom >= 0;\n // Bind the total to the stack's OUTERMOST segment (the one that carries\n // the free end), so the overlay tracks it past the column top as the\n // stack grows in — a fixed `texts` label would hang at the final total\n // while the column rose into it.\n const outerSeg = positive ? topSeriesFor.get(`${g}|${i}`) : botSeriesFor.get(`${g}|${i}`);\n if (outerSeg == null) continue;\n barLabels.push({ seriesIndex: outerSeg, dataIndex: i, text: txt, color: theme.textColor, size: theme.labelSize, fontWeight: 600, atLowEnd: !positive });\n }\n }\n }\n\n // ── gridlines (value axis) + axis frame ──\n const gridlines: SceneSegment[] = [];\n const axisLines: SceneSegment[] = [];\n const TICK = 5;\n const yb = plot.y + plot.height;\n // Stroke styles for the chrome. The value axis owns the gridlines (they are\n // drawn off its ticks); the two frame lines take the dash of the axis that\n // runs along them, which swaps with `horizontal`.\n const valueDash = dashPattern(spec.valueDash);\n const gridDash = dashPattern(spec.valueGridDash);\n const categoryDash = dashPattern(spec.categoryDash);\n if (!spec.valueHidden && !compact) {\n for (const t of vTickVals) {\n const pv = valPx(t);\n if (horizontal) {\n gridlines.push({ x1: pv, y1: plot.y, x2: pv, y2: yb, color: theme.gridLineColor, width: 1, dash: gridDash });\n if (spec.axisTicks) axisLines.push({ x1: pv, y1: yb, x2: pv, y2: yb + TICK, color: theme.axisLineColor, width: 1, dash: valueDash });\n } else {\n gridlines.push({ x1: plot.x, y1: pv, x2: plot.x + plot.width, y2: pv, color: theme.gridLineColor, width: 1, dash: gridDash });\n if (spec.axisTicks) axisLines.push({ x1: plot.x - TICK, y1: pv, x2: plot.x, y2: pv, color: theme.axisLineColor, width: 1, dash: valueDash });\n }\n }\n }\n if (!compact) {\n const catLine = spec.categoryAxisLine !== false;\n const valLine = spec.valueAxisLine !== false;\n const valBreaks = (vScale as { breaks?: readonly { px: number; gap: number }[] }).breaks ?? [];\n // horizontal: the category axis runs up the LEFT edge, the value axis along\n // the BOTTOM. vertical: value up the left, category along the bottom. The\n // VALUE axis is interrupted (with a zigzag) around each break; the category\n // axis is always a plain line.\n if (catLine) {\n axisLines.push(\n horizontal\n ? { x1: plot.x, y1: plot.y, x2: plot.x, y2: plot.y + plot.height, color: theme.axisLineColor, width: 1, dash: categoryDash }\n : { x1: plot.x, y1: plot.y + plot.height, x2: plot.x + plot.width, y2: plot.y + plot.height, color: theme.axisLineColor, width: 1, dash: categoryDash },\n );\n }\n if (valLine) {\n if (horizontal) {\n // Value axis along the bottom (x). A cut sits `px` from the left. The\n // tear runs vertically, up the plot's whole height, at the cut.\n const cuts = valBreaks.map((b) => ({ px: b.px, gap: b.gap }));\n axisLines.push(...axisLineWithBreaks('x', plot.x, plot.x + plot.width, plot.y + plot.height, cuts, theme.axisLineColor, valueDash));\n for (const c of cuts) axisLines.push(...breakBandSegments('x', plot.x + c.px, plot.x + c.px + c.gap, plot.y, plot.y + plot.height, theme.axisLineColor));\n } else {\n // Value axis up the left (y), bottom-up: a cut at offset `px` sits\n // `plot.height - px - gap` above the bottom. The tear runs horizontally,\n // across the plot's whole width, at the cut.\n const cuts = valBreaks.map((b) => ({ px: plot.height - b.px - b.gap, gap: b.gap }));\n axisLines.push(...axisLineWithBreaks('y', plot.y, plot.y + plot.height, plot.x, cuts, theme.axisLineColor, valueDash));\n for (const c of cuts) axisLines.push(...breakBandSegments('y', plot.y + c.px, plot.y + c.px + c.gap, plot.x, plot.x + plot.width, theme.axisLineColor));\n }\n }\n }\n\n // ── overlay text (title, value ticks, category ticks, axis titles) ──\n if (spec.title && !compact) {\n const tt = titlePlacement(spec.titleAlign, plot.x, plot.width);\n texts.push({ x: tt.x, y: legendBandTop + 6, text: spec.title, color: theme.textColor, fontSize: theme.titleSize, fontWeight: 600, align: tt.align, baseline: 'top', key: 'title' });\n // Under the title and sharing its alignment — a source line, a unit, the\n // caveat a title should not have to carry.\n if (spec.subtitle) {\n texts.push({\n x: tt.x,\n y: legendBandTop + 6 + theme.titleSize + 4,\n text: spec.subtitle,\n color: theme.textColorMuted,\n fontSize: theme.labelSize,\n align: tt.align,\n baseline: 'top',\n key: 'subtitle',\n });\n }\n }\n // The second value axis: its own line down the right-hand gutter, its own\n // ticks, no gridlines. Two sets of gridlines at two spacings turn the plot\n // into a mesh nobody can read a value off.\n if (hasAxis2 && !spec.valueAxis2!.hidden && !compact && !horizontal) {\n const rx = plot.x + plot.width;\n axisLines.push({ x1: rx, y1: plot.y, x2: rx, y2: plot.y + plot.height, color: theme.axisLineColor, width: 1, dash: valueDash });\n v2TickVals.forEach((t, i) => {\n const pv = valPx2(t);\n if (spec.axisTicks) axisLines.push({ x1: rx, y1: pv, x2: rx + TICK, y2: pv, color: theme.axisLineColor, width: 1, dash: valueDash });\n texts.push({ x: rx + 8, y: pv, text: v2TickLabels[i], color: theme.textColorMuted, fontSize: theme.labelSize, align: 'start', baseline: 'middle', key: `v2t-${i}` });\n });\n if (spec.valueAxis2!.label) {\n texts.push({ x: width - 4, y: plot.y + plot.height / 2, text: spec.valueAxis2!.label, color: theme.textColor, fontSize: theme.labelSize, align: 'center', baseline: 'bottom', rotate: -90, key: 'val2-axis-title' });\n }\n }\n if (!spec.valueHidden && !spec.valueHideTicks && !compact) {\n vTickVals.forEach((t, i) => {\n const pv = valPx(t);\n if (horizontal) {\n texts.push({ x: pv, y: plot.y + plot.height + 6, text: vTickLabels[i], color: theme.textColorMuted, fontSize: theme.labelSize, align: 'center', baseline: 'top', key: `vt-${i}` });\n } else {\n texts.push({ x: plot.x - 8, y: pv, text: vTickLabels[i], color: theme.textColorMuted, fontSize: theme.labelSize, align: 'end', baseline: 'middle', key: `vt-${i}` });\n }\n });\n }\n const mainPositions: number[] = [];\n // Category labels along y (horizontal) stack tightly; along x (vertical) they\n // need more room. Thin them to the available spacing per orientation.\n const minSpacing = horizontal ? theme.labelSize + 6 : 48;\n const step = Math.max(1, Math.ceil(C / Math.max(1, Math.floor(mainLen / minSpacing))));\n for (let i = 0; i < C; i++) {\n const bc = bandCenter(i);\n mainPositions.push(bc);\n const atTick = i % step === 0;\n if (spec.axisTicks && !compact && atTick && !spec.categoryHidden) {\n if (horizontal) axisLines.push({ x1: plot.x - TICK, y1: bc, x2: plot.x, y2: bc, color: theme.axisLineColor, width: 1 });\n else axisLines.push({ x1: bc, y1: yb, x2: bc, y2: yb + TICK, color: theme.axisLineColor, width: 1 });\n }\n if (spec.categoryHidden || spec.categoryHideTicks || compact || !atTick) continue;\n if (horizontal) {\n texts.push({ x: plot.x - 8 - lowEndRoom, y: bc, text: catLabels[i], color: theme.textColorMuted, fontSize: theme.labelSize, align: 'end', baseline: 'middle', key: `ct-${i}` });\n if (mirrorCats) {\n texts.push({ x: plot.x + plot.width + 8 + (spec.showLabels ? maxDataLabelW + 4 : 0), y: bc, text: catLabels[i], color: theme.textColorMuted, fontSize: theme.labelSize, align: 'start', baseline: 'middle', key: `ctm-${i}` });\n }\n } else if (catRot) {\n // Rotated about the label's own centre by the overlay, so the centre is\n // placed where the tilted box's END lands on the tick: step back along the\n // text direction by half its length, in both axes.\n const w = approxWidth(catLabels[i], theme.labelSize);\n const dir = catRot < 0 ? -1 : 1;\n texts.push({\n x: bc + (dir * w * Math.cos(catRotRad)) / 2,\n y: plot.y + plot.height + 6 + lowEndRoom + (w * Math.sin(catRotRad)) / 2,\n text: catLabels[i],\n color: theme.textColorMuted,\n fontSize: theme.labelSize,\n align: 'center',\n baseline: 'middle',\n rotate: catRot,\n key: `ct-${i}`,\n });\n } else {\n // Upright, a label may use the room up to its neighbouring SHOWN labels —\n // when the axis is thinned (every `step`-th band labelled), the skipped\n // bands between them are free, so a many-category axis isn't truncated to\n // its bare band width (…which turned \"Day 1\", \"Day 2\"… all into \"D…\").\n // step === 1 collapses to the old own-band width, so a variwide column's\n // name still can't run over its neighbours'.\n const nextC = i + step < C ? bandCenter(i + step) : bc + step * sizeAt(i);\n const prevC = i - step >= 0 ? bandCenter(i - step) : bc - step * sizeAt(i);\n const room = Math.min(nextC - bc, bc - prevC) - 6;\n texts.push({ x: bc, y: plot.y + plot.height + 6 + lowEndRoom, text: ellipsize(catLabels[i], room, theme.labelSize), color: theme.textColorMuted, fontSize: theme.labelSize, align: 'center', baseline: 'top', key: `ct-${i}` });\n }\n }\n\n // ── axis titles (gutters reserved above) — category runs along the main axis\n // (x for vertical, y for horizontal), value along the cross axis ──\n if (!compact) {\n const catTitle = spec.categoryLabel;\n const valTitle = spec.valueLabel;\n if (horizontal) {\n // categories on y (left, rotated), values on x (bottom, centred)\n if (catTitle) texts.push({ x: 4, y: plot.y + plot.height / 2, text: catTitle, color: theme.textColor, fontSize: theme.labelSize, align: 'center', baseline: 'top', rotate: -90, key: 'cat-axis-title' });\n if (valTitle) texts.push({ x: plot.x + plot.width / 2, y: height - 2 - legendBandBottom, text: valTitle, color: theme.textColor, fontSize: theme.labelSize, align: 'center', baseline: 'bottom', key: 'val-axis-title' });\n } else {\n // values on y (left, rotated), categories on x (bottom, centred)\n if (valTitle) texts.push({ x: 4, y: plot.y + plot.height / 2, text: valTitle, color: theme.textColor, fontSize: theme.labelSize, align: 'center', baseline: 'top', rotate: -90, key: 'val-axis-title' });\n if (catTitle) texts.push({ x: plot.x + plot.width / 2, y: height - 2 - legendBandBottom, text: catTitle, color: theme.textColor, fontSize: theme.labelSize, align: 'center', baseline: 'bottom', key: 'cat-axis-title' });\n }\n }\n\n const legend: LegendItem[] =\n spec.legend === 'none' || compact ? [] : spec.series.map((s, si) => ({ label: s.label, color: s.color, seriesIndex: si, hidden: s.hidden, x: 0, y: 0 }));\n\n return {\n width,\n height,\n plot,\n background: theme.background === 'transparent' ? undefined : theme.background,\n gridlines,\n axisLines,\n areas: [],\n bars,\n slices: [],\n lines: [],\n markers: [],\n texts,\n barLabels,\n legend,\n legendPosition: spec.legend,\n xPositions: mainPositions,\n xValues: spec.categories,\n xLabels: catLabels,\n barBaseline: basePx,\n hoverPoints,\n };\n}\n\n/**\n * The polar form: one concentric RING per category, with the value axis running\n * as an angle instead of a length.\n *\n * It reuses everything above it — the same stacked bands, the same domain — and\n * only changes how a band becomes geometry: `[base, top]` becomes a pair of\n * angles rather than a pair of pixels, and the category index picks a radius\n * instead of a position along an axis. That keeps stacking, hiding a series\n * from the legend, and percentage normalisation working unchanged.\n *\n * The value axis deliberately spans less than the full circle. A ring that\n * closes on itself has no readable start or end, and the quarter it gives up is\n * where the category names go.\n */\nfunction radialScene(\n spec: BarChartSpec,\n theme: EngineTheme,\n width: number,\n height: number,\n bands: ([number, number] | null | undefined)[][],\n vDomain: Domain,\n catLabels: string[],\n C: number,\n): RenderScene {\n const texts: TextItem[] = [];\n const subtitleH = spec.subtitle ? theme.labelSize + 4 : 0;\n const titleH = spec.title ? theme.titleSize + 10 + subtitleH : 0;\n\n const legendActive = !!spec.legend && spec.legend !== 'none' && spec.series.length > 1;\n const legendAtBottom = legendActive && spec.legend!.startsWith('bottom');\n const legendTopRow = legendActive && !legendAtBottom && !(spec.legend === 'left' || spec.legend === 'right');\n const legendRows = legendActive ? estimateLegendRows(spec.series.map((s) => s.label), theme.labelSize, width * 0.86) : 1;\n const legendBandH = spec.legendExtent != null && (legendTopRow || legendAtBottom) ? spec.legendExtent + 8 : legendRows * (theme.labelSize + 8) + 6;\n const legendBandTop = legendTopRow ? legendBandH : 0;\n const legendBandBottom = legendAtBottom ? legendBandH : 0;\n\n // The names hang off the left of the circle, so they get a gutter of their\n // own — otherwise the rings are centred in the full width and the whole chart\n // reads as pushed to the right by however long the longest name is.\n const nameGutter =\n spec.categoryHidden || spec.categoryHideTicks\n ? 0\n : Math.max(0, ...catLabels.map((t) => approxWidth(t, theme.labelSize))) + 12;\n const plot: Rect = {\n x: nameGutter,\n y: titleH + legendBandTop,\n width: Math.max(1, width - nameGutter),\n height: Math.max(1, height - titleH - legendBandTop - legendBandBottom),\n };\n const cx = plot.x + plot.width / 2;\n const cy = plot.y + plot.height / 2;\n // The value axis wraps around the OUTSIDE as tick labels, so reserve a ring of\n // gutter for them before sizing the plot radius.\n const vFmt = spec.valueTickFormatter ?? spec.valueFormatter;\n const vTicks = spec.valueHidden || spec.valueHideTicks ? [] : sectionedTicks(vDomain, [], spec.valueScale, 8).filter((t) => t >= vDomain[0] - 1e-9 && t <= vDomain[1] + 1e-9);\n const vTickMaxW = Math.max(0, ...vTicks.map((t) => approxWidth(vFmt(t), theme.labelSize)));\n const valueGutter = vTicks.length ? vTickMaxW + 18 : 0;\n const R = Math.max(8, Math.min(plot.width, plot.height) / 2 - 8 - valueGutter);\n const hole = R * Math.max(0, Math.min(0.9, spec.polarHole ?? 0.22));\n const ring = C > 0 ? (R - hole) / C : R - hole;\n const thickness = Math.max(1, ring * (1 - spec.categoryGapRatio));\n\n const START = -Math.PI / 2; // 12 o'clock\n const sweep = 2 * Math.PI * Math.max(0.1, Math.min(1, spec.polarSweep ?? 0.75));\n const [lo, hi] = vDomain;\n const span = hi - lo || 1;\n const angleOf = (v: number) => START + ((v - lo) / span) * sweep;\n\n const slices: RenderScene['slices'] = [];\n const hoverPoints: HoverSeries[] = [];\n const midRadii: number[] = [];\n for (let i = 0; i < C; i++) {\n // Category 0 takes the OUTSIDE ring: a reader's eye lands on the outermost\n // band first, and the first category is the one the data leads with.\n const outerR = R - i * ring;\n midRadii.push(outerR - thickness / 2);\n }\n\n spec.series.forEach((s, si) => {\n if (s.hidden) return;\n const byIndex: Record<number, HoverPoint> = {};\n for (let i = 0; i < C; i++) {\n const band = bands[si][i];\n if (!band) continue;\n const outerR = R - i * ring;\n const innerR = outerR - thickness;\n const a0 = angleOf(band[0]);\n const a1 = angleOf(band[1]);\n if (Math.abs(a1 - a0) < 1e-6) continue;\n slices.push({\n cx,\n cy,\n innerR,\n outerR,\n startAngle: Math.min(a0, a1),\n endAngle: Math.max(a0, a1),\n color: s.pointColors?.[i] ?? s.color,\n dataIndex: i,\n seriesIndex: si,\n // A stroked band with flat internal joins; the ring's head + tail get a\n // round cap in the post-pass below, so stacked segments blend into one\n // band rather than each rounding its own corners into a split.\n pill: true,\n capStart: false,\n capEnd: false,\n });\n // The hover anchor is the middle of this segment's arc, so the tooltip\n // and its marker land ON the band rather than at the plot centre.\n const mid = (a0 + a1) / 2;\n const midR = (innerR + outerR) / 2;\n byIndex[i] = { x: cx + midR * Math.cos(mid), y: cy + midR * Math.sin(mid), value: typeof s.data?.[i] === 'number' ? (s.data[i] as number) : band[1] };\n }\n hoverPoints.push({ seriesIndex: si, color: s.color, label: s.label, byIndex, values: s.data ?? [] });\n });\n\n // Round only the OUTERMOST ends of each ring: the segment that opens the ring\n // gets a round head, the one that closes it a round tail; every internal join\n // stays flat so the colours blend into a single band.\n for (let i = 0; i < C; i++) {\n const ringSlices = slices.filter((s) => s.dataIndex === i);\n if (!ringSlices.length) continue;\n let first = ringSlices[0];\n let last = ringSlices[0];\n for (const s of ringSlices) {\n if (s.startAngle < first.startAngle) first = s;\n if (s.endAngle > last.endAngle) last = s;\n }\n first.capStart = true;\n last.capEnd = true;\n }\n\n // Value-axis scale wrapped around the outside: each tick sits at its own angle\n // just beyond the outermost ring, so the reader can trace a band back to a value.\n // Anchor each label by the EDGE facing the centre (via align/baseline chosen\n // from the tick's direction) so the gap to the ring is EVEN regardless of how\n // wide the number is — centring made a long number crowd the band while a short\n // one sat off it.\n const labelR = R + 16;\n for (const t of vTicks) {\n const a = angleOf(t);\n const cos = Math.cos(a);\n const sin = Math.sin(a);\n texts.push({\n x: cx + labelR * cos,\n y: cy + labelR * sin,\n text: vFmt(t),\n color: theme.textColorMuted,\n fontSize: theme.labelSize,\n align: cos > 0.35 ? 'start' : cos < -0.35 ? 'end' : 'center',\n baseline: sin > 0.35 ? 'top' : sin < -0.35 ? 'bottom' : 'middle',\n key: `vt-${t}`,\n });\n }\n\n // Category names in the quarter the value axis gives up, each on its own\n // ring's centre line, right-aligned to the 12 o'clock radius they start at.\n if (!spec.categoryHidden && !spec.categoryHideTicks) {\n for (let i = 0; i < C; i++) {\n texts.push({\n // Clear of the bars: a band starts at 12 o'clock reaching left to\n // cx - thickness/2, so hold the name a gap short of that.\n x: cx - thickness / 2 - 12,\n y: cy - midRadii[i],\n text: catLabels[i],\n color: theme.textColorMuted,\n fontSize: theme.labelSize,\n align: 'end',\n baseline: 'middle',\n key: `ct-${i}`,\n });\n }\n }\n\n if (spec.title) {\n const tt = titlePlacement(spec.titleAlign, plot.x, plot.width);\n texts.push({ x: tt.x, y: legendBandTop + 6, text: spec.title, color: theme.textColor, fontSize: theme.titleSize, fontWeight: 600, align: tt.align, baseline: 'top', key: 'title' });\n if (spec.subtitle) {\n texts.push({ x: tt.x, y: legendBandTop + 6 + theme.titleSize + 6, text: spec.subtitle, color: theme.textColorMuted, fontSize: theme.labelSize, align: tt.align, baseline: 'top', key: 'subtitle' });\n }\n }\n\n const legend: LegendItem[] =\n spec.legend === 'none' ? [] : spec.series.map((s, si) => ({ label: s.label, color: s.color, seriesIndex: si, hidden: s.hidden, x: 0, y: 0 }));\n\n return {\n width,\n height,\n plot,\n background: theme.background === 'transparent' ? undefined : theme.background,\n gridlines: [],\n axisLines: [],\n areas: [],\n bars: [],\n slices,\n lines: [],\n markers: [],\n texts,\n legend,\n legendPosition: spec.legend,\n polar: true,\n // Radii, not positions along an axis: the engine resolves a polar hover by\n // how far the pointer is from the centre, which is exactly which ring it is\n // over.\n xPositions: midRadii,\n xValues: spec.categories,\n xLabels: catLabels,\n hoverPoints,\n };\n}\n","/*\n * Chart engine — BarChartEngine\n * ===========================================================\n * The bar-chart sibling of LineChartEngine. Same canvas +\n * DOM-overlay plumbing and the same render pipeline, but drives\n * computeBarLayout and adds bar-appropriate interaction: hover\n * resolves the nearest category along the main axis (x for vertical,\n * y for horizontal) and clicks hit-test the actual bar rectangles.\n * ===========================================================\n */\n\nimport { computeBarLayout, type BarChartSpec } from './bar-layout';\nimport type { EngineTheme } from './layout';\nimport { drawSceneCanvas } from './renderer-canvas';\nimport { syncOverlay, renderBarLabels } from './overlay';\nimport { clearHover, renderHover, type HoverOptions } from './hover';\nimport { watchDevicePixelRatio, type DprWatcher } from './dpr';\nimport { resolveIntro, stepAnimation, prefersReducedMotion, drillScene } from './animate';\nimport { mixColor } from './color';\nimport { nearestIndex } from './hit-test';\nimport { isRtl, mirrorScene, watchDirection, type DirectionWatcher } from './rtl';\nimport type { MdChartAnimation } from '../types';\nimport type { EngineCallbacks } from './chart';\nimport type { LegendItem, RenderScene, SceneBar, SceneSlice } from './scene';\n\n/** A pointer's hit-test against one annular segment: inside its radius band AND\n * its angular span (folded so a rotated / negative range still works). */\nfunction pointInSlice(px: number, py: number, s: SceneSlice): boolean {\n const dx = px - s.cx;\n const dy = py - s.cy;\n const r = Math.hypot(dx, dy);\n if (r < s.innerR || r > s.outerR) return false;\n const lo = Math.min(s.startAngle, s.endAngle);\n const hi = Math.max(s.startAngle, s.endAngle);\n const twoPi = Math.PI * 2;\n let d = (Math.atan2(dy, dx) - lo) % twoPi;\n if (d < 0) d += twoPi;\n return d <= hi - lo;\n}\n\n/** The polar ring segment under the pointer, or null in the hole / gaps / outside\n * the rings — which is what lets the tooltip appear ONLY over a segment. */\nexport function sliceAt(slices: SceneSlice[], px: number, py: number): SceneSlice | null {\n for (const s of slices) if (s.endAngle !== s.startAngle && pointInSlice(px, py, s)) return s;\n return null;\n}\n\n/** How far a faded-out ring segment recedes toward the surface at full dim. */\nconst POLAR_DIM = 0.62;\n/** Fade in / out of the spotlight, ms. */\nconst POLAR_FADE_MS = 200;\n/** Dwell before the tooltip appears on a freshly-hovered segment, ms. */\nconst POLAR_DWELL_MS = 220;\n\nconst sliceKey = (dataIndex: number, seriesIndex: number | undefined): string => `${dataIndex}:${seriesIndex ?? -1}`;\n\n/** Apply the per-segment dim (0 = full colour, 1 = fully faded to the surface) so\n * the spotlight can fade in and out rather than snapping. */\nexport function emphasizePolar(scene: RenderScene, dimByKey: Map<string, number>, surface: string): RenderScene {\n return {\n ...scene,\n slices: scene.slices.map((s) => {\n const d = dimByKey.get(sliceKey(s.dataIndex, s.seriesIndex)) ?? 0;\n return d > 0.002 ? { ...s, color: mixColor(s.color, surface, POLAR_DIM * d) } : s;\n }),\n };\n}\n\nconst lerp = (a: number, b: number, e: number): number => a + (b - a) * e;\n\n/** Time constant of the bar-race follow: a bar closes ~1 frame's worth of\n * `dt/FOLLOW_MS` of its remaining gap each frame (an exponential ease-out). */\nconst FOLLOW_MS = 260;\n\n/**\n * A stable-identity keyer for a scene's bars.\n *\n * When categories are UNIQUE, identity is the series + CATEGORY value: a bar race\n * reorders the categories every step, so the entity (\"ATL\") that was in slot 0\n * moves to slot 1 and stays the same bar sliding between ranks. When categories\n * REPEAT (a rolling window with labels like Q1,Q2,Q3,Q4,Q1), the category is not\n * an identity — the two \"Q1\" bars would collide onto one key and one would draw\n * on top of the other (flicker) — so identity falls back to the SLOT index.\n */\nfunction keyerFor(scene: RenderScene): (b: SceneBar) => string {\n const cats = (scene.xValues ?? []).map((c) => (c == null ? '' : String(c)));\n const unique = cats.length > 0 && new Set(cats).size === cats.length;\n return unique ? (b) => `${b.seriesIndex}::${cats[b.dataIndex] ?? b.dataIndex}` : (b) => `${b.seriesIndex}#${b.dataIndex}`;\n}\n\nexport function barKey(scene: RenderScene, b: SceneBar): string {\n return keyerFor(scene)(b);\n}\n\n/**\n * A key for EVERY bar in the scene, in order — occurrence-aware, so pieces that\n * would otherwise collide keep distinct identities.\n *\n * A value-axis BREAK splits one bar into several pieces that all carry the same\n * (series, category) — and so the same base key. Keyed only by that, they\n * collapse onto one entry in `displayed`, and the follow loop drops every piece\n * but the last: a broken-axis bar loses the piece past the break (its free end),\n * leaving the outlier stuck at the break line. The 2nd+ piece of a colliding key\n * gets a `~n` suffix so all pieces survive and each eases to its own target.\n */\nfunction barKeys(scene: RenderScene): string[] {\n const base = keyerFor(scene);\n const seen = new Map<string, number>();\n return scene.bars.map((b) => {\n const k = base(b);\n const n = seen.get(k) ?? 0;\n seen.set(k, n + 1);\n return n === 0 ? k : `${k}~${n}`;\n });\n}\n\nexport function barsByKey(scene: RenderScene): Map<string, SceneBar> {\n const keys = barKeys(scene);\n const m = new Map<string, SceneBar>();\n scene.bars.forEach((b, i) => m.set(keys[i], b));\n return m;\n}\n\n/** A bar mid-slide between its old and new rank/length. */\nexport function lerpBar(from: SceneBar, to: SceneBar, e: number): SceneBar {\n return { ...to, x: lerp(from.x, to.x, e), y: lerp(from.y, to.y, e), w: lerp(from.w, to.w, e), h: lerp(from.h, to.h, e) };\n}\n\n/** True if any bar moved / resized / entered / left between two scenes. */\nexport function barsDiffer(a: RenderScene, b: RenderScene): boolean {\n if (a.bars.length !== b.bars.length) return true;\n const am = barsByKey(a);\n for (const nb of b.bars) {\n const ob = am.get(barKey(b, nb));\n if (!ob) return true;\n if (Math.abs(ob.x - nb.x) > 0.5 || Math.abs(ob.y - nb.y) > 0.5 || Math.abs(ob.w - nb.w) > 0.5 || Math.abs(ob.h - nb.h) > 0.5) return true;\n }\n return false;\n}\n\nexport class BarChartEngine {\n private canvas: HTMLCanvasElement;\n private overlay: HTMLDivElement;\n /** Legend lives here: same box, but NOT clipped, so a focus ring keeps its\n * outer pixels where the legend hugs the plot edge. */\n private legendLayer: HTMLDivElement;\n /** Bar value labels get their own layer so they can be re-rendered from the\n * bars' geometry each animation frame — the static overlay above is synced\n * only once per render. */\n private barLabelLayer: HTMLDivElement;\n private hoverLayer: HTMLDivElement;\n private ctx: CanvasRenderingContext2D | null = null;\n private spec: BarChartSpec | null = null;\n private theme: EngineTheme | null = null;\n private scene: RenderScene | null = null;\n private cb: EngineCallbacks = {};\n private hoverRaf = 0;\n private lastHoverIndex = -2;\n private hoverEnabled = true;\n /** When true, the pointer shows a `pointer` (hand) cursor over a bar, signalling\n * the bar is actionable (e.g. drillable). Set by the component's `clickable`. */\n private clickable = false;\n private hoverOpts: HoverOptions = {};\n private hasRendered = false;\n private introRaf = 0;\n /** The DPR the last frame was drawn at, so a hover re-draw matches it. */\n private lastDpr = 1;\n /** The bar-race follow loop (eases bars toward the live target each frame). */\n private followRaf = 0;\n private followLast = 0;\n /** The polar segment currently spotlighted (category + series), or null. */\n private hoverSlice: { dataIndex: number; seriesIndex: number } | null = null;\n /** Per-segment dim strength (0..1), eased toward its target so the spotlight\n * fades in and out. */\n private dimAnim = new Map<string, number>();\n private dimRaf = 0;\n private dimLast = 0;\n /** The pointer's last position, so a delayed tooltip opens where the mouse is. */\n private lastPointer = { x: 0, y: 0 };\n private tooltipTimer = 0;\n private tooltipShown = false;\n /** The bars currently ON SCREEN, keyed by identity — the start state a data\n * update tweens FROM (mid-flight if one update interrupts another, so a race\n * re-fed every frame follows smoothly). */\n private displayed: Map<string, SceneBar> | null = null;\n /** Armed by {@link drill}: the band along the category axis that the NEXT\n * scene should unfold out of. Consumed by the first render after it. */\n private pendingDrill: { from: number; size: number; split: boolean } | null = null;\n private drillArmRaf = 0;\n private lastW = 0;\n private lastH = 0;\n private dprWatch: DprWatcher = watchDevicePixelRatio(() => this.render());\n /** Host is laid out right-to-left — the finished scene is mirrored. */\n private rtl = false;\n /** Re-render when the page (or an ancestor) flips direction, but only if THIS\n * chart's own computed direction actually changed. */\n private dirWatch: DirectionWatcher = watchDirection(() => {\n if (isRtl(this.container) !== this.rtl) this.render();\n });\n\n constructor(private container: HTMLElement) {\n if (getComputedStyle(container).position === 'static') container.style.position = 'relative';\n\n this.canvas = document.createElement('canvas');\n this.canvas.style.cssText = 'position:absolute;inset:0;width:100%;height:100%;display:block';\n this.canvas.setAttribute('part', 'plot-canvas');\n\n this.overlay = document.createElement('div');\n this.overlay.style.cssText = 'position:absolute;inset:0;pointer-events:none;overflow:hidden';\n\n this.legendLayer = document.createElement('div');\n this.legendLayer.style.cssText = 'position:absolute;inset:0;pointer-events:none;overflow:visible';\n\n this.barLabelLayer = document.createElement('div');\n this.barLabelLayer.style.cssText = 'position:absolute;inset:0;pointer-events:none;overflow:hidden';\n\n this.hoverLayer = document.createElement('div');\n this.hoverLayer.style.cssText = 'position:absolute;inset:0;pointer-events:none;overflow:hidden';\n\n container.append(this.canvas, this.overlay, this.legendLayer, this.barLabelLayer, this.hoverLayer);\n this.ctx = this.canvas.getContext('2d');\n\n this.canvas.addEventListener('pointermove', this.handlePointerMove);\n this.canvas.addEventListener('pointerleave', this.handlePointerLeave);\n this.canvas.addEventListener('click', this.handleClick);\n }\n\n /** The current render scene — for diagnostics/tests. */\n getScene(): RenderScene | null {\n return this.scene;\n }\n\n /** Enable/disable the hover crosshair + tooltip. */\n setHoverEnabled(enabled: boolean): void {\n this.hoverEnabled = enabled;\n if (!enabled) clearHover(this.hoverLayer);\n }\n\n /** Show a hand cursor over bars to signal they're actionable (drillable). */\n setClickable(enabled: boolean): void {\n this.clickable = enabled;\n if (!enabled) this.canvas.style.cursor = '';\n }\n\n /** True when (cx, cy) — canvas-relative px — is inside any drawn bar rect. */\n private overBar(cx: number, cy: number): boolean {\n return !!this.scene?.bars.some((b) => cx >= b.x && cx <= b.x + b.w && cy >= b.y && cy <= b.y + b.h);\n }\n\n /** Install the tooltip extras (custom content renderer / missing-value\n * formatter). Presentation only — it never re-runs layout. */\n setTooltip(opts: HoverOptions): void {\n this.hoverOpts = opts;\n }\n\n\n\n /**\n * Feed the engine a new spec. `opts.animate === false` SNAPS to the new scene\n * instead of easing into it — for a zoom / pan, where the whole category layout\n * changes at once and easing the bars across it reads as them sliding together\n * (a view change is direct manipulation; it must track, not animate).\n */\n setSpec(spec: BarChartSpec, theme: EngineTheme, cb: EngineCallbacks = {}, opts: { animate?: boolean } = {}): void {\n this.spec = spec;\n this.theme = theme;\n this.cb = cb;\n this.render(opts);\n }\n\n resize(): void {\n // Skip the ResizeObserver's initial same-size callback so it can't cancel\n // the intro animation (see LineChartEngine.resize for the full rationale).\n const rect = this.container.getBoundingClientRect();\n if (Math.round(rect.width) === this.lastW && Math.round(rect.height) === this.lastH) return;\n this.render();\n }\n\n toDataURL(type = 'image/png'): string {\n // Guard for canvases that can't export (mock-doc / SSR): return '' rather\n // than throwing, so the host's toDataURL() degrades gracefully (matches the\n // line engine).\n return typeof this.canvas.toDataURL === 'function' ? this.canvas.toDataURL(type) : '';\n }\n\n dispose(): void {\n if (this.hoverRaf) cancelAnimationFrame(this.hoverRaf);\n // stopIntro rather than a bare cancel. Nothing depends on the clear here —\n // dispose() removes the canvas a few lines down — but routing EVERY cancel\n // of introRaf through stopIntro is what makes the invariant hold: the\n // inline opacity is only ever non-empty while the entrance loop is live.\n // The bug this fixes was one cancel site that forgot the clear.\n this.stopIntro();\n cancelAnimationFrame(this.drillArmRaf);\n cancelAnimationFrame(this.dimRaf);\n cancelAnimationFrame(this.followRaf);\n clearTimeout(this.tooltipTimer);\n this.canvas.removeEventListener('pointermove', this.handlePointerMove);\n this.canvas.removeEventListener('pointerleave', this.handlePointerLeave);\n this.canvas.removeEventListener('click', this.handleClick);\n this.dprWatch.dispose();\n this.dirWatch.dispose();\n this.canvas.remove();\n this.overlay.remove();\n this.barLabelLayer.remove();\n this.hoverLayer.remove();\n this.spec = null;\n this.scene = null;\n }\n\n private render(opts: { animate?: boolean } = {}): void {\n if (!this.spec || !this.theme) return;\n this.dprWatch.update();\n const rect = this.container.getBoundingClientRect();\n const w = Math.round(rect.width);\n const h = Math.round(rect.height);\n if (w < 2 || h < 2) return;\n // Capture the previous scene + size BEFORE they are overwritten: a data\n // update at the SAME size tweens the bars to their new ranks; a resize / dpr\n // change snaps (sliding bars on a resize would be nonsense).\n const oldScene = this.scene;\n const sizeChanged = w !== this.lastW || h !== this.lastH;\n this.lastW = w;\n this.lastH = h;\n\n const dpr = Math.min(window.devicePixelRatio || 1, 4);\n this.lastDpr = dpr;\n // A fresh scene invalidates any spotlight / pending tooltip, and a hover\n // callback queued against the OLD scene must not paint over the new one.\n this.hoverSlice = null;\n this.dimAnim.clear();\n cancelAnimationFrame(this.dimRaf);\n this.dimRaf = 0;\n if (this.hoverRaf) {\n cancelAnimationFrame(this.hoverRaf);\n this.hoverRaf = 0;\n }\n clearTimeout(this.tooltipTimer);\n this.tooltipShown = false;\n this.canvas.width = w * dpr;\n this.canvas.height = h * dpr;\n\n const hadCategories = this.scene?.xPositions.length ?? 0;\n // Layout runs left-to-right; an RTL host gets the finished frame mirrored, so\n // no part of the geometry / animation pipeline needs to know about direction.\n this.rtl = isRtl(this.container);\n const layout = (): RenderScene => {\n const s = computeBarLayout(this.spec!, this.theme!, w, h);\n return this.rtl ? mirrorScene(s) : s;\n };\n this.scene = layout();\n // A tooltip open over the OLD data must not survive a swap that replaced it:\n // after a drill it would name the level that just left. Re-resolving at the\n // same index keeps a live chart (a race re-feeding every frame) showing a\n // correct tooltip under a stationary pointer, and drops it when the index it\n // was on no longer exists.\n if (this.lastHoverIndex >= 0) {\n if (this.lastHoverIndex < this.scene.xPositions.length && hadCategories === this.scene.xPositions.length) {\n this.focusIndexInternal(this.lastHoverIndex);\n } else {\n clearHover(this.hoverLayer);\n this.lastHoverIndex = -1;\n }\n }\n syncOverlay(this.overlay, this.scene, this.theme.fontFamily, { onLegendClick: this.onLegendToggle }, this.rtl, this.legendLayer);\n // Two-pass legend: a wrapped legend's real extent isn't known until it's in\n // the DOM. Re-reserve the gutter to its measured height/width and re-lay-out\n // so a many-series legend never spills onto the plot.\n const legendEl = this.legendLayer.querySelector('[part=\"legend\"]') as HTMLElement | null;\n if (legendEl && this.spec.legend && this.spec.legend !== 'none') {\n const side = this.spec.legend === 'left' || this.spec.legend === 'right';\n const extent = side ? legendEl.offsetWidth : legendEl.offsetHeight;\n if (extent > 0 && Math.abs((this.spec.legendExtent ?? -1) - extent) > 2) {\n this.spec.legendExtent = extent;\n this.scene = layout();\n syncOverlay(this.overlay, this.scene, this.theme.fontFamily, { onLegendClick: this.onLegendToggle }, this.rtl, this.legendLayer);\n }\n }\n const { variant, duration } = resolveIntro(this.spec);\n const drill = this.pendingDrill;\n const reduce = prefersReducedMotion();\n const motion = variant !== 'none' && !reduce;\n // An EMPTY scene is not a chart that has been shown. A host that hydrates\n // before its data lands (props assigned after upgrade — the docs/demo\n // pattern) renders once with no series at all; counting that as \"rendered\"\n // spent the entrance on nothing and left the real data to arrive\n // un-animated, on the FOLLOW path below. So the first render that actually\n // has geometry is the one that owns the entrance.\n const hasContent = this.scene.bars.length > 0 || this.scene.slices.length > 0;\n const animate = !this.hasRendered && motion;\n if (drill && motion) {\n this.hasRendered = true;\n this.playDrill(dpr, drill, duration);\n return;\n }\n if (animate) {\n this.hasRendered = hasContent;\n this.playIntro(dpr, variant, duration);\n return;\n }\n this.hasRendered = this.hasRendered || hasContent;\n // A data update at the same size → FOLLOW the new ranks/lengths (see\n // ensureFollow). Runs even with the ENTRY animation off (a race turns the\n // intro off but still wants ranks to slide) — gated on reduced-motion alone.\n // `|| this.followRaf` keeps the loop alive through a race's intermediate\n // no-change renders instead of the static branch resetting it.\n // `opts.animate === false` (a zoom / pan) skips the follow ease and snaps to\n // the windowed layout below — easing bars across a whole-layout change reads\n // as them sliding together.\n const changed = !!oldScene && barsDiffer(oldScene, this.scene);\n if (opts.animate !== false && !reduce && !sizeChanged && oldScene && (changed || this.followRaf)) {\n // Stop any intro/drill loop first — otherwise it keeps painting the same\n // canvas as the follow loop until it ends, and its terminal frame stomps\n // `displayed` mid-tween (flicker/jump). stopIntro (not a bare cancel):\n // the follow loop only paints geometry, so a cancel that left the\n // entrance's fade behind pinned this chart at opacity 0 forever.\n this.stopIntro();\n this.ensureFollow();\n return;\n }\n this.stopIntro();\n cancelAnimationFrame(this.followRaf);\n this.followRaf = 0;\n this.paint(this.scene, dpr);\n this.displayed = barsByKey(this.scene);\n }\n\n /**\n * Arm a drill transition for the NEXT scene: it will unfold out of the band\n * `index` occupies right now, rather than playing the ordinary entry\n * animation. Call this BEFORE swapping the data.\n *\n * `direction: 'up'` pivots on the whole plot instead of one column, which is\n * the visual inverse — the level being returned to opens out of everything\n * the level being left was filling.\n */\n drill(index: number, direction: 'down' | 'up' = 'down'): void {\n const scene = this.scene;\n if (!scene) return;\n const horizontal = !!this.spec?.horizontal;\n if (direction === 'up') {\n // Merge: the parent level opens out of the whole plot (grows from the axis).\n this.arm(horizontal ? { from: scene.plot.y, size: scene.plot.height, split: false } : { from: scene.plot.x, size: scene.plot.width, split: false });\n return;\n }\n const bars = scene.bars.filter((b) => b.dataIndex === index);\n if (!bars.length) {\n this.arm(null);\n return;\n }\n // Split: the children part out of the clicked column's band, at full height.\n const lo = Math.min(...bars.map((b) => (horizontal ? b.y : b.x)));\n const hi = Math.max(...bars.map((b) => (horizontal ? b.y + b.h : b.x + b.w)));\n this.arm({ from: lo, size: Math.max(1, hi - lo), split: true });\n }\n\n /**\n * Hold the drill until the NEXT FRAME rather than until the next render.\n *\n * A bar chart's level lives in two props — the series and the categories —\n * and each assignment re-renders synchronously. Consuming the arm on the\n * first render would animate the old data against the new categories and\n * leave the real swap un-animated, so it survives every render in the same\n * turn; the last one to run is the one that animates.\n */\n private arm(band: { from: number; size: number; split: boolean } | null): void {\n this.pendingDrill = band;\n cancelAnimationFrame(this.drillArmRaf);\n if (!band) return;\n this.drillArmRaf = requestAnimationFrame(() => {\n this.pendingDrill = null;\n });\n }\n\n /**\n * Clear the inline opacity the entrance fades the layers in with.\n *\n * The entrance is the ONLY thing that writes it, and the only thing that\n * clears it is the loop's own terminal frame — so every path that ends the\n * entrance early has to undo it here. Skipping this leaves a chart whose bars\n * are drawn into a canvas pinned at `opacity: 0`: fully rendered, invisible,\n * and with nothing left to write style again (it never self-heals).\n */\n private clearIntroOpacity(): void {\n this.canvas.style.opacity = '';\n this.barLabelLayer.style.opacity = '';\n }\n\n /** End the entrance/drill loop AND undo the fade it applied. Use this instead\n * of a bare `cancelAnimationFrame(this.introRaf)` everywhere outside the loop\n * itself. */\n private stopIntro(): void {\n cancelAnimationFrame(this.introRaf);\n this.introRaf = 0;\n this.clearIntroOpacity();\n }\n\n private playDrill(dpr: number, band: { from: number; size: number; split: boolean }, duration: number): void {\n const target = this.scene;\n if (!target) return;\n this.stopIntro();\n // drillScene takes the RAW timeline — it eases each child itself so the split\n // can cascade (stagger per category) with a spring.\n this.paint(drillScene(target, band.from, band.size, 0, band.split), dpr);\n let start = 0;\n const frame = (now: number): void => {\n if (!start) start = now;\n const t = (now - start) / duration;\n if (t >= 1) {\n this.displayed = barsByKey(target);\n this.paint(target, dpr);\n return;\n }\n this.paint(drillScene(target, band.from, band.size, t, band.split), dpr);\n this.introRaf = requestAnimationFrame(frame);\n };\n this.introRaf = requestAnimationFrame(frame);\n }\n\n /** Replay the entry animation from the start (uses the current spec's variant). */\n replay(): void {\n this.hasRendered = false;\n this.render();\n }\n\n private drawGeometry(scene: RenderScene, dpr: number): void {\n if (this.ctx) {\n this.ctx.setTransform(dpr, 0, 0, dpr, 0, 0);\n drawSceneCanvas(this.ctx, scene);\n }\n }\n\n /** Draw the plot geometry (canvas) + the bar value labels (their own layer)\n * for a scene — both animate together, so the numbers ride out to the bar\n * tips as the bars grow instead of snapping to the final position. */\n private paint(scene: RenderScene, dpr: number): void {\n this.drawGeometry(scene, dpr);\n renderBarLabels(this.barLabelLayer, scene, this.theme?.fontFamily);\n }\n\n private playIntro(dpr: number, variant: MdChartAnimation, duration: number): void {\n const target = this.scene;\n if (!target) return;\n this.stopIntro();\n // Grow + fade share one layer opacity: `alpha` < 1 fades the canvas (and its\n // bar-label overlay) in; an empty string restores the stylesheet default once\n // the entrance settles. draw/stagger report alpha 1, so their layer stays\n // fully opaque and only the geometry animates.\n const setOpacity = (a: number): void => {\n const v = a < 1 ? String(a) : '';\n this.canvas.style.opacity = v;\n this.barLabelLayer.style.opacity = v;\n };\n // Draw t=0 NOW rather than waiting for the first frame. Setting the canvas\n // size in render() cleared it, so deferring the first draw leaves one frame\n // of blank canvas under a DOM overlay that has already painted its labels —\n // the chart appears to blink before it starts.\n const first = stepAnimation(variant, target, 0);\n setOpacity(first.alpha);\n this.paint(first.scene, dpr);\n let start = 0;\n const frame = (now: number): void => {\n if (!start) start = now;\n const tRaw = (now - start) / duration;\n if (tRaw >= 1) {\n setOpacity(1);\n this.displayed = barsByKey(target);\n this.paint(target, dpr);\n return;\n }\n const { scene, alpha } = stepAnimation(variant, target, tRaw);\n setOpacity(alpha);\n this.paint(scene, dpr);\n this.introRaf = requestAnimationFrame(frame);\n };\n this.introRaf = requestAnimationFrame(frame);\n }\n\n /**\n * A persistent FOLLOW loop for data updates — the bar-race reorder. Every frame\n * it eases each bar a fraction of the way toward the LATEST target (`this.scene`),\n * matched by CATEGORY (so an entity slides between ranks, not slots).\n *\n * Why a follow and not a fixed tween: a race re-feeds every frame AND reassigns\n * several props per feed (xAxis, yAxis, series), so several renders land per\n * frame. A fixed tween restarted on each render — and reset by the static branch\n * of the intermediate no-change render — never accumulated, so the ranks\n * snapped. This loop reads the live target and survives those renders, so the\n * bars slide up and down smoothly. A one-off update just converges then stops.\n */\n private ensureFollow(): void {\n if (!this.scene) return;\n if (prefersReducedMotion()) {\n cancelAnimationFrame(this.followRaf);\n this.followRaf = 0;\n this.displayed = barsByKey(this.scene);\n this.paint(this.scene, this.lastDpr);\n return;\n }\n // render() just CLEARED the canvas by resizing it, so repaint the current\n // follow state NOW (rate 0 = no easing step) — otherwise the frame composites\n // blank, because the rAF step runs before the NEXT render's clear, not after\n // this one. The rAF loop then advances the easing once per frame.\n const moving = this.renderFollow(0);\n if (moving && !this.followRaf) {\n this.followLast = 0;\n this.followRaf = requestAnimationFrame(this.followStep);\n }\n }\n\n /** Ease each bar `rate` of the way toward the live target (matched by category),\n * paint the frame, and report whether anything is still moving. */\n private renderFollow(rate: number): boolean {\n const target = this.scene;\n if (!target) return false;\n const keys = barKeys(target); // occurrence-aware: split-bar pieces stay distinct (see barKeys)\n const from = this.displayed ?? barsByKey(target);\n const displayed = new Map<string, SceneBar>();\n const bars: SceneBar[] = [];\n let moving = false;\n target.bars.forEach((b, i) => {\n const k = keys[i];\n const prev = from.get(k);\n const bar = prev ? lerpBar(prev, b, rate) : b; // a survivor eases in; a new entity lands at its slot\n displayed.set(k, bar);\n bars.push(bar);\n if (Math.abs(bar.x - b.x) > 0.3 || Math.abs(bar.y - b.y) > 0.3 || Math.abs(bar.w - b.w) > 0.3 || Math.abs(bar.h - b.h) > 0.3) moving = true;\n });\n this.displayed = displayed;\n this.paint({ ...target, bars }, this.lastDpr);\n return moving;\n }\n\n private followStep = (now: number): void => {\n if (!this.scene) {\n this.followRaf = 0;\n return;\n }\n const dt = this.followLast ? now - this.followLast : 16;\n this.followLast = now;\n const moving = this.renderFollow(Math.min(1, dt / FOLLOW_MS)); // exponential ease-out\n this.followRaf = moving ? requestAnimationFrame(this.followStep) : 0;\n };\n\n /**\n * Show the hover UI at a category index without a pointer — the keyboard\n * path, mirroring {@link LineChartEngine.focusIndex}. A sighted keyboard\n * user has to see the same tooltip a mouse user gets. `-1` clears.\n */\n focusIndex(index: number): void {\n this.lastHoverIndex = index;\n this.focusIndexInternal(index);\n }\n\n private focusIndexInternal(index: number): void {\n if (!this.scene || !this.spec || !this.theme) return;\n // Polar: spotlight the focused RING (seriesIndex -1 = the whole ring), so a\n // keyboard user sees the same emphasis a mouse hover gives, not just a card.\n if (this.spec.polar) {\n const next = index < 0 ? null : { dataIndex: index, seriesIndex: -1 };\n if (next?.dataIndex !== this.hoverSlice?.dataIndex || next?.seriesIndex !== this.hoverSlice?.seriesIndex) {\n this.hoverSlice = next;\n this.startDim();\n }\n }\n if (index < 0) {\n clearHover(this.hoverLayer);\n return;\n }\n const horizontal = !!this.spec.horizontal;\n const pt = this.scene.hoverPoints.map((hp) => hp.byIndex[index]).find(Boolean);\n const pos = this.scene.xPositions[index] ?? 0;\n const cursor = pt\n ? { x: pt.x, y: pt.y }\n : { x: horizontal ? this.scene.plot.x : pos, y: horizontal ? pos : this.scene.plot.y };\n renderHover(\n this.hoverLayer,\n this.scene,\n index,\n this.spec.valueFormatter,\n this.theme.fontFamily,\n cursor,\n this.spec.polar ? 'none' : horizontal ? 'horizontal' : 'vertical',\n -1,\n this.hoverOpts,\n );\n }\n\n /** The dim a segment heads toward: 0 for the hovered one, 1 for the rest while\n * something is hovered, 0 for everything when nothing is. */\n private dimTarget(s: SceneSlice): number {\n const h = this.hoverSlice;\n if (!h) return 0;\n // seriesIndex < 0 spotlights the WHOLE ring (keyboard focus); otherwise the\n // single segment under the pointer.\n if (h.seriesIndex < 0) return s.dataIndex === h.dataIndex ? 0 : 1;\n return s.dataIndex === h.dataIndex && s.seriesIndex === h.seriesIndex ? 0 : 1;\n }\n\n /** Kick the spotlight fade toward the current `hoverSlice` (reduced-motion snaps). */\n private startDim(): void {\n if (!this.scene || !this.theme) return;\n if (prefersReducedMotion()) {\n cancelAnimationFrame(this.dimRaf);\n this.dimRaf = 0;\n for (const s of this.scene.slices) this.dimAnim.set(sliceKey(s.dataIndex, s.seriesIndex), this.dimTarget(s));\n this.drawGeometry(emphasizePolar(this.scene, this.dimAnim, this.theme.surface), this.lastDpr);\n return;\n }\n // A running loop already re-reads the new targets each frame — just start one\n // if idle (resetting dimLast only then, so the dt stays continuous).\n if (!this.dimRaf) {\n this.dimLast = 0;\n this.dimRaf = requestAnimationFrame(this.stepDim);\n }\n }\n\n private stepDim = (now: number): void => {\n if (!this.scene || !this.theme) {\n this.dimRaf = 0;\n return;\n }\n const dt = this.dimLast ? now - this.dimLast : 16;\n this.dimLast = now;\n let moving = false;\n for (const s of this.scene.slices) {\n const key = sliceKey(s.dataIndex, s.seriesIndex);\n const target = this.dimTarget(s);\n const cur = this.dimAnim.get(key) ?? 0;\n let next = cur + Math.sign(target - cur) * (dt / POLAR_FADE_MS);\n if ((target - cur) * (target - next) <= 0) next = target; // reached / crossed\n this.dimAnim.set(key, next);\n if (next !== target) moving = true;\n }\n this.drawGeometry(emphasizePolar(this.scene, this.dimAnim, this.theme.surface), this.lastDpr);\n this.dimRaf = moving ? requestAnimationFrame(this.stepDim) : 0;\n };\n\n /** (Re)arm the dwell before a segment's tooltip appears; a miss / switch hides\n * the current card and restarts the wait. */\n private armTooltip(hovered: { dataIndex: number; seriesIndex: number } | null): void {\n clearTimeout(this.tooltipTimer);\n clearHover(this.hoverLayer);\n this.tooltipShown = false;\n if (!hovered) return;\n this.tooltipTimer = window.setTimeout(() => {\n const h = this.hoverSlice;\n if (h && h.dataIndex === hovered.dataIndex && h.seriesIndex === hovered.seriesIndex) {\n this.showPolarTooltip(hovered);\n this.tooltipShown = true;\n }\n }, POLAR_DWELL_MS);\n }\n\n private showPolarTooltip(hovered: { dataIndex: number; seriesIndex: number }): void {\n if (!this.scene || !this.spec || !this.theme) return;\n renderHover(this.hoverLayer, this.scene, hovered.dataIndex, this.spec.valueFormatter, this.theme.fontFamily, this.lastPointer, 'none', hovered.seriesIndex, { ...this.hoverOpts, trigger: 'item' });\n }\n\n private handlePointerMove = (e: PointerEvent): void => {\n if (!this.scene || !this.spec || !this.hoverEnabled) return;\n const rect = this.canvas.getBoundingClientRect();\n const px = e.clientX - rect.left;\n const py = e.clientY - rect.top;\n // Polar: hit-test the exact ring SEGMENT (like the pie), so the tooltip +\n // spotlight appear only when the pointer is actually on a band — the hole,\n // the angular gaps and the space beyond the rings all miss and clear.\n if (this.spec.polar) {\n const slice = sliceAt(this.scene.slices, px, py);\n const hovered = slice ? { dataIndex: slice.dataIndex, seriesIndex: slice.seriesIndex ?? -1 } : null;\n this.lastPointer = { x: px, y: py };\n if (this.hoverRaf) cancelAnimationFrame(this.hoverRaf);\n this.hoverRaf = requestAnimationFrame(() => {\n this.hoverRaf = 0;\n if (!this.scene || !this.spec || !this.theme) return;\n this.canvas.style.cursor = hovered ? 'pointer' : '';\n const changed = hovered?.dataIndex !== this.hoverSlice?.dataIndex || hovered?.seriesIndex !== this.hoverSlice?.seriesIndex;\n if (changed) {\n this.hoverSlice = hovered;\n this.startDim(); // fade the spotlight toward the new segment\n this.armTooltip(hovered); // restart the dwell before the tooltip shows\n } else if (this.tooltipShown && hovered) {\n this.showPolarTooltip(hovered); // same segment, card up → follow the cursor\n }\n const idx = hovered ? hovered.dataIndex : -1;\n if (idx !== this.lastHoverIndex) {\n this.lastHoverIndex = idx;\n this.cb.onHover?.(idx);\n }\n });\n return;\n }\n const idx = nearestIndex(this.scene.xPositions, this.spec.horizontal ? py : px);\n if (this.hoverRaf) cancelAnimationFrame(this.hoverRaf);\n this.hoverRaf = requestAnimationFrame(() => {\n this.hoverRaf = 0;\n if (!this.scene || !this.spec || !this.theme) return;\n // A hand cursor over a bar (hit-tested exactly as a click is) signals it's\n // actionable — only inside the bar itself, not the empty column above it.\n this.canvas.style.cursor = this.clickable && this.overBar(px, py) ? 'pointer' : '';\n renderHover(this.hoverLayer, this.scene, idx, this.spec.valueFormatter, this.theme.fontFamily, { x: px, y: py }, this.spec.horizontal ? 'horizontal' : 'vertical', -1, this.hoverOpts);\n if (idx !== this.lastHoverIndex) {\n this.lastHoverIndex = idx;\n this.cb.onHover?.(idx);\n }\n });\n };\n\n private handlePointerLeave = (): void => {\n if (this.hoverRaf) {\n cancelAnimationFrame(this.hoverRaf);\n this.hoverRaf = 0;\n }\n this.canvas.style.cursor = ''; // drop the hand when the pointer leaves the plot\n clearHover(this.hoverLayer);\n // Drop the polar spotlight — fade the rings back to full colour.\n if (this.spec?.polar && this.scene) {\n clearTimeout(this.tooltipTimer);\n this.tooltipShown = false;\n this.canvas.style.cursor = '';\n if (this.hoverSlice) {\n this.hoverSlice = null;\n this.startDim();\n }\n }\n if (this.lastHoverIndex !== -1) {\n this.lastHoverIndex = -1;\n this.cb.onHover?.(-1);\n }\n };\n\n private handleClick = (e: MouseEvent): void => {\n if (!this.scene || !this.cb.onPointClick) return;\n const rect = this.canvas.getBoundingClientRect();\n const px = e.clientX - rect.left;\n const py = e.clientY - rect.top;\n // Only fire when the click actually lands inside a bar — a click on empty\n // plot whitespace should not emit a bar click.\n for (const b of this.scene.bars) {\n if (px >= b.x && px <= b.x + b.w && py >= b.y && py <= b.y + b.h) {\n this.cb.onPointClick(b.seriesIndex, b.dataIndex, e as PointerEvent);\n return;\n }\n }\n };\n\n private onLegendToggle = (item: LegendItem): void => {\n if (this.spec) {\n this.spec.series[item.seriesIndex].hidden = !this.spec.series[item.seriesIndex].hidden;\n // Re-play the entry motion so the chart animates into its new\n // configuration (respects the variant + reduced-motion / 'none').\n this.hasRendered = false;\n this.render();\n this.cb.onLegendClick?.({ ...item, hidden: this.spec.series[item.seriesIndex].hidden });\n } else {\n this.cb.onLegendClick?.(item);\n }\n };\n}\n\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function t(t){const s=(t.label||t.getAttribute("label")||t.textContent||"").trim();return{value:t.value??t.getAttribute("value")??"",label:s,disabled:t.disabled??t.hasAttribute("disabled"),icon:t.icon||t.getAttribute("icon")||undefined,iconColor:t.iconColor||t.getAttribute("icon-color")||undefined,supportingText:t.supportingText||t.getAttribute("supporting-text")||undefined,selected:t.selected??t.hasAttribute("selected")}}function s(t){return{value:t.value,label:t.label??t.value,disabled:!!t.disabled,icon:t.icon,iconColor:t.iconColor,supportingText:t.supportingText,selected:!!t.selected}}function i(t){return!Array.isArray(t)}function n(t){if(!i(t))return t.slice();const s=new Array(t.count);for(let i=0;i<t.count;i++)s[i]=t.getRow(i);return s}function e(t){return t.map(s)}function h(i,n){const e=Array.from(i.children).filter((t=>t.tagName.toLowerCase()==="md-select-option"));if(e.length>0){return e.map(t)}return(n??[]).map(s)}function o(t,s){return t.find((t=>t.value===s))?.label??""}const r=15e5;function c(t,s,i,n,e,h=r,o=-1){if(n<=0||i<=0||s<=0){const t=n>0&&i>0?n*i:0;return{start:0,end:0,topPad:0,bottomPad:t,scrollHeight:t,scrollTop:0}}const c=n*i;const a=Math.ceil(s/i);if(c<=h){const h=Math.min(Math.max(0,t),Math.max(0,c-s));const o=Math.floor(h/i);const r=Math.min(n,Math.max(0,o-e));const u=Math.min(n,Math.max(r,o+a+e));return{start:r,end:u,topPad:r*i,bottomPad:Math.max(0,(n-u)*i),scrollHeight:c,scrollTop:h}}const u=h;const f=Math.max(1,u-s);const l=Math.max(0,n-a);if(o>=0){const t=Math.min(l,o);const s=Math.min(e,t);const h=t-s;const r=Math.min(n,t+a+e);const c=(r-h)*i;const d=s*i;const M=Math.round(t/Math.max(1,l)*f);const m=Math.max(d,Math.min(f,M));const b=m-s*i;const p=Math.max(0,u-b-c);return{start:h,end:r,topPad:b,bottomPad:p,scrollHeight:u,scrollTop:m}}const d=Math.min(Math.max(0,t),f);const M=Math.round(d/f*l);const m=Math.min(e,M,Math.floor(d/i));const b=M-m;const p=Math.min(n,M+a+e);const w=(p-b)*i;const y=Math.max(0,u-w);let A=d-m*i;if(A<0)A=0;else if(A>y)A=y;const g=Math.max(0,u-A-w);return{start:b,end:p,topPad:A,bottomPad:g,scrollHeight:u,scrollTop:d}}const a=0;function u(t){if(typeof atob==="function"){const s=atob(t);const i=new Uint8Array(s.length);for(let t=0;t<s.length;t++)i[t]=s.charCodeAt(t);return i}return Uint8Array.from(Buffer.from(t,"base64"))}let f;async function l(){f??(f=import("./p-CfBPnYW7.js").then((({WASM_BASE64:t})=>WebAssembly.compile(u(t)))));const t=await f;const s={env:{abort(){},trace(){},seed(){return Date.now()}}};const i=await WebAssembly.instantiate(t,s);return i.exports}const d={substring:0,prefix:1,fuzzy:2};const M=1;const m=6;const b=2048;const p=typeof performance!=="undefined"&&typeof performance.now==="function"?()=>performance.now():()=>Date.now();function w(){const t=globalThis.scheduler;if(t?.yield)return t.yield();return new Promise((t=>setTimeout(t,0)))}const y=12;async function A(t){if(typeof requestAnimationFrame==="function"&&p()-t.t>=y){await new Promise((t=>{requestAnimationFrame((()=>setTimeout(t,0)))}));t.t=p();return}await w()}function g(){return typeof WebAssembly!=="undefined"&&typeof WebAssembly.instantiate==="function"}function P(t){let s=0;for(let i=0;i<t.length;i++){const n=t.charCodeAt(i);if(n<128){s+=1}else if(n<2048){s+=2}else if(n>=55296&&n<=56319){const n=t.charCodeAt(i+1);if(n>=56320&&n<=57343){s+=4;i++}else{s+=3}}else{s+=3}}return s}class x{constructor(){this.enc=new TextEncoder;this.dec=new TextDecoder;this._length=0;this._total=0;this.mode=a}ensureReady(){if(!this.ready){this.ready=g()?l().then((t=>{this.engine=t})):Promise.reject(new Error("WebAssembly is not available in this environment"))}return this.ready}get ready$(){return!!this.engine}get length(){return this._length}get total(){return this._total}setFilterMode(t){this.mode=d[t]??a}mem(){return new Uint8Array(this.engine.memory.buffer)}async load(t){await this.ensureReady();const s=this.engine;let n;let e;if(i(t)){n=t.count;e=t.getRow}else{n=t.length;e=s=>t[s]}const h={t:p()};let o=0;let r=0;let c=0;let a=0;for(let t=0;t<n;){const s=p();do{const s=Math.min(n,t+b);for(;t<s;t++){const s=e(t);o+=P(s.value);r+=P(s.label??s.value);if(s.icon)c+=P(s.icon);if(s.supportingText)a+=P(s.supportingText)}}while(t<n&&p()-s<m);if(t<n)await A(h)}s.reserve(n,o,r,c,a);for(let t=0;t<n;){const i=p();const o=this.mem();do{const i=Math.min(n,t+b);for(;t<i;t++){const i=e(t);const n=s.valueWritePtr();const h=this.enc.encodeInto(i.value,o.subarray(n));const r=s.labelWritePtr();const u=this.enc.encodeInto(i.label??i.value,o.subarray(r));const f=s.iconWritePtr();const l=c>0?this.enc.encodeInto(i.icon??"",o.subarray(f)):null;const d=s.supportWritePtr();const m=a>0?this.enc.encodeInto(i.supportingText??"",o.subarray(d)):null;s.appendRow(h.written??0,u.written??0,l?.written??0,m?.written??0,i.disabled?M:0)}}while(t<n&&p()-i<m);if(t<n)await A(h)}s.finalizeLoad();this._total=s.totalCount();this._length=s.filteredCount()}writeScratch(t){const s=this.engine;const i=s.queryCapacity();const n=s.queryPtr();const{written:e}=this.enc.encodeInto(t,this.mem().subarray(n,n+i));return e??0}setQuery(t){if(!this.engine)return 0;const s=this.writeScratch(t);this._length=this.engine.setQuery(s,this.mode);return this._length}decodeRow(t,s){const i=this.engine;const n=i.valuePtr(t);const e=i.valueLen(t);const h=i.labelPtr(t);const o=i.labelLen(t);const r=i.iconPtr(t);const c=i.iconLen(t);const a=i.supportPtr(t);const u=i.supportLen(t);return{index:t,value:this.dec.decode(s.subarray(n,n+e)),label:this.dec.decode(s.subarray(h,h+o)),disabled:(i.rowFlags(t)&M)!==0,icon:c>0?this.dec.decode(s.subarray(r,r+c)):"",supportingText:u>0?this.dec.decode(s.subarray(a,a+u)):""}}getWindow(t,s){if(!this.engine)return[];const i=this.engine;const n=this.mem();const e=[];const h=Math.max(0,t);const o=Math.min(this._length,t+s);for(let t=h;t<o;t++){const s=i.rowAt(t);if(s>=0)e.push(this.decodeRow(s,n))}return e}getRow(t){if(!this.engine)return null;const s=this.engine.rowAt(t);if(s<0)return null;return this.decodeRow(s,this.mem())}rowAt(t){return this.engine?this.engine.rowAt(t):-1}disabledAt(t){if(!this.engine)return false;const s=this.engine.rowAt(t);if(s<0)return false;return(this.engine.rowFlags(s)&M)!==0}labelAt(t){if(!this.engine)return"";const s=this.engine.rowAt(t);if(s<0)return"";const i=this.engine.labelPtr(s);const n=this.engine.labelLen(s);return this.dec.decode(this.mem().subarray(i,i+n))}getLabels(t){const s=new Map;if(!this.engine)return s;const i=this.engine;for(const n of t){const t=this.writeScratch(n);const e=i.indexOfValue(t);if(e>=0){const t=i.labelPtr(e);const h=i.labelLen(e);s.set(n,this.dec.decode(this.mem().subarray(t,t+h)))}}return s}has(t){if(!this.engine)return false;return this.engine.indexOfValue(this.writeScratch(t))>=0}findLabelPrefix(t,s){if(!this.engine)return-1;const i=this.writeScratch(t);return this.engine.findLabelPrefix(i,s)}reset(){this.engine?.reset();this._length=0;this._total=0}}const F=1e6;const T=8;const v=48;const W=320;const q=0;class H{constructor(t){this.host=t;this.store=new x;this.active=false;this.windowStart=0;this.windowRows=[];this.topPad=0;this.bottomPad=0;this.filteredLength=0;this.rowHeight=v;this.scrollRaf=0;this.browserMaxScroll=Infinity;this.intendedScrollHeight=0;this.detectRaf=0;this.detectRetries=0;this.navAnchorFirstRow=-1;this.usedScrollTop=0;this.onScroll=()=>{if(this.scrollRaf)return;this.scrollRaf=requestAnimationFrame((()=>{this.scrollRaf=0;const t=this.viewportEl;if(!t)return;if(this.navAnchorFirstRow>=0&&Math.abs(t.scrollTop-this.usedScrollTop)<=1){return}this.navAnchorFirstRow=-1;this.recompute(t.scrollTop)}))};this.provider={count:()=>this.filteredLength,labelAt:t=>this.store.labelAt(t),isDisabledAt:t=>this.store.disabledAt(t),ensureVisible:t=>this.ensureVisible(t),domItemForIndex:t=>this.host.queryItem(t),findPrefix:(t,s)=>this.store.findLabelPrefix(t,s)}}effectiveMaxScroll(){return Math.min(r,this.browserMaxScroll)}setFixedRowHeight(t){this.fixedRowHeight=t&&t>0?t:undefined;if(this.fixedRowHeight)this.rowHeight=this.fixedRowHeight}setFilterMode(t){this.store.setFilterMode(t)}async load(t){const s=i(t)?t.count:t.length;if(!g()||s===0)return false;try{await this.store.ensureReady()}catch{return false}await this.store.load(t);this.active=true;this.filteredLength=this.store.length;this.recompute(this.viewportEl?.scrollTop??0);return true}setQuery(t){if(!this.active)return;this.filteredLength=this.store.setQuery(t);this.navAnchorFirstRow=-1;if(this.viewportEl)this.viewportEl.scrollTop=0;this.recompute(0)}getLabels(t){return this.store.getLabels(t)}reset(){this.store.reset();this.active=false;this.windowRows=[];this.filteredLength=0;this.windowStart=0;this.topPad=0;this.bottomPad=0;this.navAnchorFirstRow=-1}async attachViewport(t){this.detachViewport();const s=await t();this.viewportEl=s??undefined;if(this.viewportEl){this.viewportEl.addEventListener("scroll",this.onScroll,{passive:true});this.measureRowHeight();this.recompute(this.viewportEl.scrollTop);this.detectRetries=60;this.detectScrollCap()}}detachViewport(){if(this.scrollRaf){cancelAnimationFrame(this.scrollRaf);this.scrollRaf=0}if(this.detectRaf){cancelAnimationFrame(this.detectRaf);this.detectRaf=0}this.viewportEl?.removeEventListener("scroll",this.onScroll);this.viewportEl=undefined}measureRowHeight(){if(this.fixedRowHeight){this.rowHeight=this.fixedRowHeight;return}const t=this.host.queryItem(this.windowStart);const s=t?.offsetHeight??0;if(s>0&&s!==this.rowHeight){this.rowHeight=s;if(this.viewportEl)this.recompute(this.viewportEl.scrollTop)}}recompute(t){const s=this.viewportEl?.clientHeight||W;const i=c(t,s,this.rowHeight,this.filteredLength,T,this.effectiveMaxScroll(),this.navAnchorFirstRow);this.windowStart=i.start;this.topPad=i.topPad;this.bottomPad=i.bottomPad;this.intendedScrollHeight=i.scrollHeight;this.usedScrollTop=i.scrollTop;this.windowRows=this.store.getWindow(i.start,i.end-i.start);this.host.requestRender()}detectScrollCap(){if(this.detectRaf)cancelAnimationFrame(this.detectRaf);this.detectRaf=requestAnimationFrame((()=>{this.detectRaf=requestAnimationFrame((()=>{this.detectRaf=0;const t=this.viewportEl;if(!t)return;const s=t.scrollHeight;if(s>0&&s+2<this.intendedScrollHeight&&s<this.browserMaxScroll){if(s<F){if(this.detectRetries-- >0)this.detectScrollCap();return}this.browserMaxScroll=s;this.recompute(t.scrollTop)}}))}))}async ensureVisible(t){const s=this.viewportEl;if(!s)return;const i=s.clientHeight||W;const n=this.filteredLength*this.rowHeight;if(n<=this.effectiveMaxScroll()){this.navAnchorFirstRow=-1;const n=t*this.rowHeight;const e=n+this.rowHeight;const h=Math.max(0,s.scrollHeight-i);if(n-q<s.scrollTop){s.scrollTop=Math.max(0,n-q)}else if(e+q>s.scrollTop+i){s.scrollTop=Math.min(h,e+q-i)}this.recompute(s.scrollTop)}else{const n=Math.max(1,Math.floor(i/this.rowHeight));const e=Math.ceil(i/this.rowHeight);const h=Math.max(0,this.filteredLength-e);const o=this.navAnchorFirstRow>=0?this.navAnchorFirstRow:this.windowStart+Math.max(0,Math.round((s.scrollTop-this.topPad)/this.rowHeight));const r=o+n-1;const c=Math.ceil(q/this.rowHeight);if(t<o+c||t>r-c){this.navAnchorFirstRow=Math.min(h,Math.max(0,t<o+c?t-c:t-n+1+c))}this.recompute(s.scrollTop);if(this.navAnchorFirstRow>=0){const t=Math.max(0,s.scrollHeight-i);const n=Math.min(Math.round(this.usedScrollTop),t);if(n!==Math.round(s.scrollTop)){s.scrollTop=n}this.usedScrollTop=s.scrollTop}}for(let s=0;s<8;s++){await new Promise((t=>requestAnimationFrame((()=>t()))));if(this.host.queryItem(t))return}}}export{H as V,h as c,g as i,o as l,e as n,n as r};
|
|
2
|
+
//# sourceMappingURL=p-Bz-JaJcA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["fromElement","el","label","getAttribute","textContent","trim","value","disabled","hasAttribute","icon","undefined","iconColor","supportingText","selected","fromInit","o","isRowSource","source","Array","isArray","rowsToArray","slice","out","count","i","getRow","normalizeInits","inits","map","collectOptions","host","optionsProp","slotted","from","children","filter","c","tagName","toLowerCase","length","labelFor","options","find","DEFAULT_MAX_SCROLL_HEIGHT","computeWindow","scrollTop","viewportHeight","rowHeight","total","overscan","maxScrollHeight","anchorFirstRow","realHeight","start","end","topPad","bottomPad","scrollHeight","visibleCount","Math","ceil","clamped","min","max","firstVisible","floor","maxScrollTop","maxFirstRow","firstVisibleRow","aboveRows","blockHeight","lo","proportional","round","usedScrollTop","maxTop","FILTER_SUBSTRING","decodeBase64","b64","atob","bin","Uint8Array","charCodeAt","Buffer","modulePromise","async","instantiateEngine","import","then","WASM_BASE64","WebAssembly","compile","module","imports","env","abort","trace","seed","Date","now","instance","instantiate","exports","FILTER_MODE","substring","prefix","fuzzy","DISABLED_FLAG","LOAD_SLICE_BUDGET_MS","LOAD_STRIDE","nowMs","performance","yieldToMain","scheduler","globalThis","yield","Promise","resolve","setTimeout","PAINT_INTERVAL_MS","yieldForPaint","lastPaint","requestAnimationFrame","t","isWasmSupported","utf8ByteLength","str","bytes","next","WasmOptionStore","constructor","this","enc","TextEncoder","dec","TextDecoder","_length","_total","mode","ensureReady","ready","e","engine","reject","Error","ready$","setFilterMode","mem","memory","buffer","load","at","valueBytesTotal","labelBytesTotal","iconBytesTotal","supportBytesTotal","sliceStart","r","reserve","vp","valueWritePtr","v","encodeInto","subarray","lp","labelWritePtr","l","ip","iconWritePtr","ic","sp","supportWritePtr","sc","appendRow","written","finalizeLoad","totalCount","filteredCount","writeScratch","s","cap","queryCapacity","ptr","queryPtr","setQuery","query","len","decodeRow","absIndex","valuePtr","vl","valueLen","labelPtr","ll","labelLen","iconPtr","il","iconLen","supportPtr","sl","supportLen","index","decode","rowFlags","getWindow","to","fi","abs","rowAt","push","filteredIndex","disabledAt","labelAt","getLabels","values","result","Map","indexOfValue","set","has","findLabelPrefix","fromFilteredIndex","reset","MIN_PLAUSIBLE_SCROLL_CAP","OVERSCAN","DEFAULT_ROW_HEIGHT","DEFAULT_VIEWPORT_HEIGHT","EDGE_SCRIM_PAD","VirtualSelectController","store","active","windowStart","windowRows","filteredLength","scrollRaf","browserMaxScroll","Infinity","intendedScrollHeight","detectRaf","detectRetries","navAnchorFirstRow","onScroll","viewportEl","recompute","provider","isDisabledAt","ensureVisible","domItemForIndex","queryItem","findPrefix","effectiveMaxScroll","setFixedRowHeight","px","fixedRowHeight","attachViewport","getViewport","detachViewport","addEventListener","passive","measureRowHeight","detectScrollCap","cancelAnimationFrame","removeEventListener","first","h","offsetHeight","vpH","clientHeight","calc","requestRender","measured","clientH","top","bottom","maxScroll","visibleRows","lastVisible","padRows","target","tries"],"sources":["src/utils/select-options.ts","src/utils/virtual-window.ts","src/wasm/engine-abi.ts","src/utils/wasm-option-store.ts","src/utils/virtual-select-controller.ts"],"sourcesContent":["/**\n * Shared option model + reader for `md-select` / `md-multi-select`.\n *\n * Both components accept options two ways (decided by the consumer):\n * 1. Declarative slotted `<md-select-option>` children (primary API —\n * framework-friendly, supports rich labels + per-option icons).\n * 2. A programmatic `options` array prop (data-driven lists).\n *\n * `collectOptions()` normalises either source into a single flat\n * `SelectOptionData[]` the pickers render into `md-menu-item`s. When\n * slotted children are present they take precedence; otherwise the\n * array prop is used. This keeps the result predictable (no silent\n * duplication when a consumer accidentally supplies both).\n */\n\n/** Normalised option the pickers render. */\nexport interface SelectOptionData {\n /** Stable identifier — emitted in the picker `value` and used for matching. */\n value: string;\n /** Visible label rendered in the menu, chips, and the trigger text. */\n label: string;\n /** Disabled options stay visible but cannot be selected. */\n disabled: boolean;\n /** Optional Material Symbols leading-icon glyph. */\n icon?: string;\n /** Optional CSS colour applied to the leading icon (e.g. a status/swatch hue).\n * Any CSS `<color>` — hex, `rgb()`, or a theme token like\n * `var(--md-sys-color-primary)`. Ignored when the option has no `icon`, and\n * not carried on the virtualized (WASM) path — huge datasets fall back to the\n * `--md-{multi-}select-option-icon-color` token. */\n iconColor?: string;\n /** Optional secondary text rendered under the label in the menu. */\n supportingText?: string;\n /** Initial-selected hint carried by the option element / array entry. */\n selected?: boolean;\n}\n\n/** Programmatic option entry accepted by the `options` array prop. */\nexport interface SelectOptionInit {\n value: string;\n label?: string;\n disabled?: boolean;\n icon?: string;\n iconColor?: string;\n supportingText?: string;\n selected?: boolean;\n}\n\n/** Element-side shape of a slotted `<md-select-option>`. */\ninterface SelectOptionEl extends HTMLElement {\n value?: string;\n label?: string;\n disabled?: boolean;\n icon?: string;\n iconColor?: string;\n supportingText?: string;\n selected?: boolean;\n}\n\nfunction fromElement(el: SelectOptionEl): SelectOptionData {\n const label = (el.label || el.getAttribute('label') || el.textContent || '').trim();\n return {\n value: el.value ?? el.getAttribute('value') ?? '',\n label,\n disabled: el.disabled ?? el.hasAttribute('disabled'),\n icon: el.icon || el.getAttribute('icon') || undefined,\n iconColor: el.iconColor || el.getAttribute('icon-color') || undefined,\n supportingText:\n el.supportingText || el.getAttribute('supporting-text') || undefined,\n selected: el.selected ?? el.hasAttribute('selected'),\n };\n}\n\nfunction fromInit(o: SelectOptionInit): SelectOptionData {\n return {\n value: o.value,\n label: o.label ?? o.value,\n disabled: !!o.disabled,\n icon: o.icon,\n iconColor: o.iconColor,\n supportingText: o.supportingText,\n selected: !!o.selected,\n };\n}\n\n/**\n * A dataset given as a row factory rather than a materialised array, so very\n * large option sets (tens of millions) can be streamed into the WASM store\n * without ever holding the whole array in JS at once.\n */\nexport interface OptionRowSource {\n count: number;\n getRow: (index: number) => SelectOptionInit;\n}\n\n/**\n * Type guard distinguishing a row factory from a materialised array.\n * (`Array.isArray` doesn't narrow a `readonly[]` union, so this is explicit.)\n */\nexport function isRowSource(\n source: ReadonlyArray<SelectOptionInit> | OptionRowSource,\n): source is OptionRowSource {\n return !Array.isArray(source);\n}\n\n/** Materialise a row source (array or factory) into a plain array. */\nexport function rowsToArray(\n source: ReadonlyArray<SelectOptionInit> | OptionRowSource,\n): SelectOptionInit[] {\n if (!isRowSource(source)) return source.slice();\n const out = new Array<SelectOptionInit>(source.count);\n for (let i = 0; i < source.count; i++) out[i] = source.getRow(i);\n return out;\n}\n\n/** Normalise a programmatic `options` array to `SelectOptionData[]`. */\nexport function normalizeInits(inits: ReadonlyArray<SelectOptionInit>): SelectOptionData[] {\n return inits.map(fromInit);\n}\n\n/**\n * Read the option set for a picker host. Slotted `<md-select-option>`\n * children win when present; otherwise the `options` array is used.\n */\nexport function collectOptions(\n host: HTMLElement,\n optionsProp?: SelectOptionInit[],\n): SelectOptionData[] {\n // Direct light-DOM children only (avoids `:scope`, which mock-doc/older\n // engines don't support, and avoids reaching into nested option groups).\n const slotted = Array.from(host.children).filter(\n (c) => c.tagName.toLowerCase() === 'md-select-option',\n ) as SelectOptionEl[];\n\n if (slotted.length > 0) {\n return slotted.map(fromElement);\n }\n return (optionsProp ?? []).map(fromInit);\n}\n\n/** Label for a single value, or '' if not found. */\nexport function labelFor(options: SelectOptionData[], value: string): string {\n return options.find((o) => o.value === value)?.label ?? '';\n}\n","/**\n * Fixed-row-height virtual windowing math, shared by the virtualized selects.\n *\n * Pure and DOM-free so it can be unit-tested directly. Given the scroll offset\n * and viewport size, it returns the slice of rows to render plus the spacer\n * heights that make the scroll container behave as if every row were present.\n *\n * Two regimes:\n * - Exact: when the full list height fits under `maxScrollHeight`, the spacers\n * reproduce the real height 1:1 and the offset maps to a row directly.\n * - Scaled: when the list is taller than a browser can lay out (millions of\n * rows × row height easily exceeds the ~16–33M px element-height cap), the\n * spacers reproduce a *capped* height and the scroll offset maps\n * proportionally onto the row range. The rendered block is always\n * positioned to cover the viewport, so the list never shows blank rows and\n * can be scrolled all the way to the end.\n */\nexport interface WindowCalc {\n /** First filtered index to render (inclusive), overscan applied. */\n start: number;\n /** One past the last filtered index to render (exclusive). */\n end: number;\n /** Spacer height (px) before the first rendered row. */\n topPad: number;\n /** Spacer height (px) after the last rendered row. */\n bottomPad: number;\n /** Total scrollable height the spacers reproduce (topPad + rows + bottomPad). */\n scrollHeight: number;\n /**\n * The scroll offset this window is laid out for. Equal to the input scrollTop\n * for mouse-driven windows; for an anchored (keyboard-nav) window it is the\n * offset the caller should apply so the anchor row lands at the viewport top.\n */\n scrollTop: number;\n}\n\n/**\n * Default ceiling on the scrollable height. Comfortably under every major\n * browser's maximum element height (Firefox ~17.9M, Chrome ~33.5M) so the\n * spacers always lay out, while still giving smooth scroll resolution for\n * millions of rows. The controller can lower this further at runtime if it\n * detects the browser clamping even shorter.\n */\nexport const DEFAULT_MAX_SCROLL_HEIGHT = 1_500_000;\n\nexport function computeWindow(\n scrollTop: number,\n viewportHeight: number,\n rowHeight: number,\n total: number,\n overscan: number,\n maxScrollHeight: number = DEFAULT_MAX_SCROLL_HEIGHT,\n // In the scaled regime, pin the first rendered row to this index instead of\n // deriving it from the scroll fraction. Keyboard nav uses this because integer\n // scrollTop is too coarse to address individual rows in a multi-million list.\n anchorFirstRow: number = -1,\n): WindowCalc {\n if (total <= 0 || rowHeight <= 0 || viewportHeight <= 0) {\n const realHeight = total > 0 && rowHeight > 0 ? total * rowHeight : 0;\n return { start: 0, end: 0, topPad: 0, bottomPad: realHeight, scrollHeight: realHeight, scrollTop: 0 };\n }\n\n const realHeight = total * rowHeight;\n const visibleCount = Math.ceil(viewportHeight / rowHeight);\n\n // ── Exact regime: the list fits, spacers mirror the real height. ──\n if (realHeight <= maxScrollHeight) {\n const clamped = Math.min(Math.max(0, scrollTop), Math.max(0, realHeight - viewportHeight));\n const firstVisible = Math.floor(clamped / rowHeight);\n const start = Math.min(total, Math.max(0, firstVisible - overscan));\n const end = Math.min(total, Math.max(start, firstVisible + visibleCount + overscan));\n return {\n start,\n end,\n topPad: start * rowHeight,\n bottomPad: Math.max(0, (total - end) * rowHeight),\n scrollHeight: realHeight,\n scrollTop: clamped,\n };\n }\n\n // ── Scaled regime: list taller than `maxScrollHeight`. ──\n const scrollHeight = maxScrollHeight;\n const maxScrollTop = Math.max(1, scrollHeight - viewportHeight);\n const maxFirstRow = Math.max(0, total - visibleCount);\n\n if (anchorFirstRow >= 0) {\n // Keyboard nav: position the anchor row at the viewport top and *derive* the\n // scroll offset to match. Integer scrollTop is too coarse to address single\n // rows near the ends of a multi-million-row list, so we treat the offset as\n // an output (the caller applies `scrollTop`) instead of an input. This is\n // what makes ArrowDown/ArrowUp keep advancing past the rendered window.\n const firstVisibleRow = Math.min(maxFirstRow, anchorFirstRow);\n const aboveRows = Math.min(overscan, firstVisibleRow);\n const start = firstVisibleRow - aboveRows;\n const end = Math.min(total, firstVisibleRow + visibleCount + overscan);\n const blockHeight = (end - start) * rowHeight;\n // Use the SAME proportional row↔offset mapping as the mouse-scroll branch\n // below, so a given offset uniquely identifies the anchor row and re-deriving\n // the window from `scrollTop` (when the anchor is dropped) lands on the same\n // row. We deliberately do NOT pull the offset up to bottom-align the block\n // near the end (an earlier `hi` clamp did): that collapsed many adjacent\n // anchors onto one integer offset, so a single stray scroll event would\n // re-map that offset proportionally and teleport the view thousands of rows\n // (ArrowUp \"jumping\" near the bottom of a huge list). `lo` still keeps\n // topPad ≥ 0 near the very top. The block may now extend a few hundred px\n // past the nominal cap at the very end; we clamp `bottomPad` to ≥ 0 and let\n // the real content height absorb the remainder — negligible against\n // `scrollHeight`, and the offset stays reachable.\n const lo = aboveRows * rowHeight;\n const proportional = Math.round((firstVisibleRow / Math.max(1, maxFirstRow)) * maxScrollTop);\n const usedScrollTop = Math.max(lo, Math.min(maxScrollTop, proportional));\n const topPad = usedScrollTop - aboveRows * rowHeight;\n const bottomPad = Math.max(0, scrollHeight - topPad - blockHeight);\n return { start, end, topPad, bottomPad, scrollHeight, scrollTop: usedScrollTop };\n }\n\n // Mouse scroll: the browser's scrollTop is authoritative; map it onto the row\n // range and seat the block so the first visible row lands at the viewport top\n // (overscan above limited to the room the offset leaves, so topPad stays ≥ 0).\n const clamped = Math.min(Math.max(0, scrollTop), maxScrollTop);\n const firstVisibleRow = Math.round((clamped / maxScrollTop) * maxFirstRow);\n const aboveRows = Math.min(overscan, firstVisibleRow, Math.floor(clamped / rowHeight));\n const start = firstVisibleRow - aboveRows;\n const end = Math.min(total, firstVisibleRow + visibleCount + overscan);\n const blockHeight = (end - start) * rowHeight;\n const maxTop = Math.max(0, scrollHeight - blockHeight);\n let topPad = clamped - aboveRows * rowHeight;\n if (topPad < 0) topPad = 0;\n else if (topPad > maxTop) topPad = maxTop;\n const bottomPad = Math.max(0, scrollHeight - topPad - blockHeight);\n\n return { start, end, topPad, bottomPad, scrollHeight, scrollTop: clamped };\n}\n","/**\n * Hand-written ABI surface for the WASM option engine.\n *\n * `engine.wasm.ts` (the base64 blob) is generated by scripts/build-wasm.mjs;\n * this file is the stable, committed wrapper the rest of the codebase imports.\n * Keep `EngineExports` in sync with the exports of `engine.ts`.\n *\n * The blob is imported DYNAMICALLY inside instantiateEngine() rather than at\n * module top level: the engine only ever instantiates above the virtualization\n * threshold (200+ options), but a static import made every consumer of\n * md-select/md-autocomplete/md-multi-select/md-table-pagination ship the\n * ~11 kB base64 string (5.6 kB gz) eagerly. As a dynamic import the bundler\n * emits it as its own async chunk, fetched only if virtualization engages.\n */\n\n/** Filter modes accepted by `setQuery` (mirrors engine.ts). */\nexport const FILTER_SUBSTRING = 0;\nexport const FILTER_PREFIX = 1;\nexport const FILTER_FUZZY = 2;\n\n/** The functions exported by the compiled WASM engine. */\nexport interface EngineExports {\n memory: WebAssembly.Memory;\n reserve(\n rows: number,\n valueBytesTotal: number,\n labelBytesTotal: number,\n iconBytesTotal: number,\n supportBytesTotal: number,\n ): void;\n valueWritePtr(): number;\n labelWritePtr(): number;\n iconWritePtr(): number;\n supportWritePtr(): number;\n appendRow(\n valueLen: number,\n labelLen: number,\n iconLen: number,\n supportLen: number,\n flags: number,\n ): number;\n finalizeLoad(): void;\n queryPtr(): number;\n queryCapacity(): number;\n setQuery(queryLen: number, mode: number): number;\n totalCount(): number;\n filteredCount(): number;\n rowAt(filteredIndex: number): number;\n valuePtr(absIndex: number): number;\n valueLen(absIndex: number): number;\n labelPtr(absIndex: number): number;\n labelLen(absIndex: number): number;\n iconPtr(absIndex: number): number;\n iconLen(absIndex: number): number;\n supportPtr(absIndex: number): number;\n supportLen(absIndex: number): number;\n rowFlags(absIndex: number): number;\n indexOfValue(queryLen: number): number;\n findLabelPrefix(queryLen: number, fromFilteredIndex: number): number;\n reset(): void;\n}\n\nfunction decodeBase64(b64: string): Uint8Array {\n if (typeof atob === 'function') {\n const bin = atob(b64);\n const out = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n }\n // Node without a global atob (older runtimes / spec env).\n return Uint8Array.from(Buffer.from(b64, 'base64'));\n}\n\n/**\n * Compiled once per process — the module bytes never change, and every\n * consumer gets its own isolated instance (fresh memory) below. Without this\n * cache each component instance re-decoded and recompiled the same module.\n */\nlet modulePromise: Promise<WebAssembly.Module> | undefined;\n\n/**\n * Lazily instantiate the engine. The compiled module is a few KB; consumers\n * load their (potentially millions of) rows into its memory at runtime.\n */\nexport async function instantiateEngine(): Promise<EngineExports> {\n modulePromise ??= import('./engine.wasm').then(({ WASM_BASE64 }) =>\n WebAssembly.compile(decodeBase64(WASM_BASE64)),\n );\n const module = await modulePromise;\n const imports = {\n env: {\n abort() {},\n trace() {},\n seed() {\n return Date.now();\n },\n },\n };\n const instance = await WebAssembly.instantiate(module, imports);\n return instance.exports as unknown as EngineExports;\n}\n","/**\n * `WasmOptionStore` — the single integration point both `md-select` and\n * `md-multi-select` use for virtualized, WASM-backed option data.\n *\n * It hides the engine ABI entirely (see `wasm/engine-abi.ts`): the dataset is\n * packed into WASM linear memory at `load()` time and JS keeps no copy, so a\n * select can hold millions of options while only ever decoding the ~visible\n * window back out per render. Filtering/typeahead run inside WASM.\n *\n * One instance per component → one `WebAssembly.Instance` → isolated memory.\n */\nimport {\n EngineExports,\n FILTER_SUBSTRING,\n instantiateEngine,\n} from '../wasm/engine-abi';\nimport { isRowSource, OptionRowSource, SelectOptionInit } from './select-options';\n\n/** A row read back out of the store for rendering. */\nexport interface VirtualRow {\n /** Absolute row index in the dataset (stable across filtering). */\n index: number;\n value: string;\n label: string;\n disabled: boolean;\n /** Material Symbols leading-icon glyph, or '' when the dataset has no icons. */\n icon: string;\n /** Secondary line under the label, or '' when the dataset has no supporting text. */\n supportingText: string;\n}\n\n/** Filter strategy, mapped to the engine's `setQuery` mode. */\nexport type FilterMode = 'substring' | 'prefix' | 'fuzzy';\n\nconst FILTER_MODE: Record<FilterMode, number> = {\n substring: 0,\n prefix: 1,\n fuzzy: 2,\n};\n\nconst DISABLED_FLAG = 1;\n\n/**\n * Time budget (ms) for one main-thread slice while packing. Bounding every\n * slice to roughly a frame keeps busy animations (the loading indicator)\n * fluid during multi-million-row loads — a fixed row-count chunk (formerly\n * 250k rows) blocked 100ms+ per chunk and dropped the spinner to ~7fps.\n */\nconst LOAD_SLICE_BUDGET_MS = 6;\n\n/** Rows between clock reads inside a slice (amortises performance.now()).\n * Small enough that one stride stays well inside the slice budget even with\n * an expensive consumer getRow (~1.4µs/row measured → ~3ms per stride). */\nconst LOAD_STRIDE = 2_048;\n\n/** Millisecond clock that also works in non-DOM (spec) environments. */\nconst nowMs: () => number =\n typeof performance !== 'undefined' && typeof performance.now === 'function'\n ? () => performance.now()\n : () => Date.now();\n\n/** Yield to the event loop so the browser can handle input mid-load. NB:\n * scheduler.yield() continuations PREEMPT rendering, so this alone does not\n * produce paints — see yieldForPaint(). */\nfunction yieldToMain(): Promise<void> {\n const scheduler = (globalThis as { scheduler?: { yield?: () => Promise<void> } }).scheduler;\n if (scheduler?.yield) return scheduler.yield();\n return new Promise((resolve) => setTimeout(resolve, 0));\n}\n\n/**\n * Work window between paint yields. Deliberately UNDER a 60Hz frame (16.7ms):\n * we resume ~1ms after a paint, so a 16ms window would finish just past the\n * next vsync and miss it (measured: alternating 17/33ms gaps → 25ms average).\n * 12ms of work + up to a stride of overshoot still lands the rAF request\n * before the deadline, giving a consistent ~16.7ms cadence.\n */\nconst PAINT_INTERVAL_MS = 12;\n\n/**\n * Yield in a way that guarantees the browser can PAINT when a frame is due —\n * scheduler.yield continuations outprioritise rendering, which froze the\n * loading animation to ~10fps during multi-million-row packs. When a frame is\n * due, await requestAnimationFrame (a real rendering opportunity); otherwise\n * take the cheap yield.\n */\nasync function yieldForPaint(lastPaint: { t: number }): Promise<void> {\n if (\n typeof requestAnimationFrame === 'function' &&\n nowMs() - lastPaint.t >= PAINT_INTERVAL_MS\n ) {\n // Resume AFTER the paint, not inside the rAF callback: resolving in rAF\n // would continue the pack as a microtask still inside the rendering-steps\n // task — the paint would then wait behind the next 16ms of work (measured\n // as ~33ms frame gaps). rAF marks the frame; the nested macrotask lands\n // once rendering has actually flushed.\n await new Promise<void>((resolve) => {\n requestAnimationFrame(() => setTimeout(resolve, 0));\n });\n lastPaint.t = nowMs();\n return;\n }\n await yieldToMain();\n}\n\n/** True when this runtime can host the engine (false in non-WASM SSR/test envs). */\nexport function isWasmSupported(): boolean {\n return typeof WebAssembly !== 'undefined' && typeof WebAssembly.instantiate === 'function';\n}\n\n/**\n * UTF-8 byte length of a string, matching `TextEncoder` semantics (lone\n * surrogates count as the 3-byte U+FFFD replacement). Allocation-free, so the\n * load sizing pass over millions of rows stays cheap.\n */\nexport function utf8ByteLength(str: string): number {\n let bytes = 0;\n for (let i = 0; i < str.length; i++) {\n const c = str.charCodeAt(i);\n if (c < 0x80) {\n bytes += 1;\n } else if (c < 0x800) {\n bytes += 2;\n } else if (c >= 0xd800 && c <= 0xdbff) {\n const next = str.charCodeAt(i + 1);\n if (next >= 0xdc00 && next <= 0xdfff) {\n bytes += 4;\n i++;\n } else {\n bytes += 3; // lone high surrogate → U+FFFD\n }\n } else {\n bytes += 3; // BMP ≥ 0x800, or lone low surrogate → U+FFFD\n }\n }\n return bytes;\n}\n\nexport class WasmOptionStore {\n private engine?: EngineExports;\n private ready?: Promise<void>;\n private enc = new TextEncoder();\n private dec = new TextDecoder();\n private _length = 0;\n private _total = 0;\n private mode: number = FILTER_SUBSTRING;\n\n /** Lazily instantiate the engine (memoized). */\n ensureReady(): Promise<void> {\n if (!this.ready) {\n this.ready = isWasmSupported()\n ? instantiateEngine().then((e) => {\n this.engine = e;\n })\n : Promise.reject(new Error('WebAssembly is not available in this environment'));\n }\n return this.ready;\n }\n\n get ready$(): boolean {\n return !!this.engine;\n }\n\n /** Current filtered row count. */\n get length(): number {\n return this._length;\n }\n\n /** Total rows loaded (ignores the active filter). */\n get total(): number {\n return this._total;\n }\n\n setFilterMode(mode: FilterMode): void {\n this.mode = FILTER_MODE[mode] ?? FILTER_SUBSTRING;\n }\n\n private mem(): Uint8Array {\n // Re-derived on every read batch: a prior `memory.grow` detaches the old\n // ArrayBuffer, so a cached view would throw.\n return new Uint8Array(this.engine!.memory.buffer);\n }\n\n /**\n * Load a dataset into WASM memory. Accepts either a materialised array or a\n * row factory (`{ count, getRow }`) — the factory path never holds more than\n * one row in JS at a time, so it scales to tens of millions of options. Two\n * passes over the input: size, then encode each row's UTF-8 directly into the\n * engine's buffers. JS references to the rows are not retained.\n */\n async load(source: ReadonlyArray<SelectOptionInit> | OptionRowSource): Promise<void> {\n await this.ensureReady();\n const e = this.engine!;\n\n let count: number;\n let at: (i: number) => SelectOptionInit;\n if (isRowSource(source)) {\n count = source.count;\n at = source.getRow;\n } else {\n count = source.length;\n at = (i) => source[i];\n }\n\n const lastPaint = { t: nowMs() };\n\n // Pass 1 — size the columns. TIME-SLICED with yields so a\n // multi-million-row load never blocks the main thread longer than about a\n // frame: the browser paints (fluid loading animation) and handles input\n // between slices. Icon / supporting-text totals stay 0 when the dataset\n // uses neither, so the engine skips those columns entirely.\n let valueBytesTotal = 0;\n let labelBytesTotal = 0;\n let iconBytesTotal = 0;\n let supportBytesTotal = 0;\n for (let i = 0; i < count; ) {\n const sliceStart = nowMs();\n do {\n const end = Math.min(count, i + LOAD_STRIDE);\n for (; i < end; i++) {\n const r = at(i);\n valueBytesTotal += utf8ByteLength(r.value);\n labelBytesTotal += utf8ByteLength(r.label ?? r.value);\n if (r.icon) iconBytesTotal += utf8ByteLength(r.icon);\n if (r.supportingText) supportBytesTotal += utf8ByteLength(r.supportingText);\n }\n } while (i < count && nowMs() - sliceStart < LOAD_SLICE_BUDGET_MS);\n if (i < count) await yieldForPaint(lastPaint);\n }\n\n e.reserve(count, valueBytesTotal, labelBytesTotal, iconBytesTotal, supportBytesTotal);\n\n // Pass 2 — encode each row's UTF-8 straight into the engine buffers, also\n // time-sliced + yielding. The memory view is re-derived per slice: appendRow\n // never grows memory, but a yield could let other work run in between. Read\n // all four write pointers before appendRow — it advances every cursor.\n for (let i = 0; i < count; ) {\n const sliceStart = nowMs();\n const mem = this.mem();\n do {\n const end = Math.min(count, i + LOAD_STRIDE);\n for (; i < end; i++) {\n const r = at(i);\n const vp = e.valueWritePtr();\n const v = this.enc.encodeInto(r.value, mem.subarray(vp));\n const lp = e.labelWritePtr();\n const l = this.enc.encodeInto(r.label ?? r.value, mem.subarray(lp));\n const ip = e.iconWritePtr();\n const ic =\n iconBytesTotal > 0 ? this.enc.encodeInto(r.icon ?? '', mem.subarray(ip)) : null;\n const sp = e.supportWritePtr();\n const sc =\n supportBytesTotal > 0\n ? this.enc.encodeInto(r.supportingText ?? '', mem.subarray(sp))\n : null;\n e.appendRow(\n v.written ?? 0,\n l.written ?? 0,\n ic?.written ?? 0,\n sc?.written ?? 0,\n r.disabled ? DISABLED_FLAG : 0,\n );\n }\n } while (i < count && nowMs() - sliceStart < LOAD_SLICE_BUDGET_MS);\n if (i < count) await yieldForPaint(lastPaint);\n }\n\n e.finalizeLoad(); // allocates the value index — may grow memory\n\n this._total = e.totalCount();\n this._length = e.filteredCount();\n }\n\n /** Write a string into the engine's scratch buffer; returns bytes written. */\n private writeScratch(s: string): number {\n const e = this.engine!;\n const cap = e.queryCapacity();\n const ptr = e.queryPtr();\n const { written } = this.enc.encodeInto(s, this.mem().subarray(ptr, ptr + cap));\n return written ?? 0;\n }\n\n /** Apply a filter query. Returns the new filtered length. */\n setQuery(query: string): number {\n if (!this.engine) return 0;\n const len = this.writeScratch(query);\n this._length = this.engine.setQuery(len, this.mode);\n return this._length;\n }\n\n private decodeRow(absIndex: number, mem: Uint8Array): VirtualRow {\n const e = this.engine!;\n const vp = e.valuePtr(absIndex);\n const vl = e.valueLen(absIndex);\n const lp = e.labelPtr(absIndex);\n const ll = e.labelLen(absIndex);\n // Icon / supporting-text columns return 0-length ranges when the dataset\n // didn't supply them, so these decode to '' at no extra packing cost.\n const ip = e.iconPtr(absIndex);\n const il = e.iconLen(absIndex);\n const sp = e.supportPtr(absIndex);\n const sl = e.supportLen(absIndex);\n return {\n index: absIndex,\n value: this.dec.decode(mem.subarray(vp, vp + vl)),\n label: this.dec.decode(mem.subarray(lp, lp + ll)),\n disabled: (e.rowFlags(absIndex) & DISABLED_FLAG) !== 0,\n icon: il > 0 ? this.dec.decode(mem.subarray(ip, ip + il)) : '',\n supportingText: sl > 0 ? this.dec.decode(mem.subarray(sp, sp + sl)) : '',\n };\n }\n\n /** Decode `count` rows starting at filtered position `start`. */\n getWindow(start: number, count: number): VirtualRow[] {\n if (!this.engine) return [];\n const e = this.engine;\n const mem = this.mem();\n const out: VirtualRow[] = [];\n const from = Math.max(0, start);\n const to = Math.min(this._length, start + count);\n for (let fi = from; fi < to; fi++) {\n const abs = e.rowAt(fi);\n if (abs >= 0) out.push(this.decodeRow(abs, mem));\n }\n return out;\n }\n\n /** Decode a single row at filtered position `filteredIndex`, or null. */\n getRow(filteredIndex: number): VirtualRow | null {\n if (!this.engine) return null;\n const abs = this.engine.rowAt(filteredIndex);\n if (abs < 0) return null;\n return this.decodeRow(abs, this.mem());\n }\n\n /** Map a filtered position to its absolute row index, or -1. */\n rowAt(filteredIndex: number): number {\n return this.engine ? this.engine.rowAt(filteredIndex) : -1;\n }\n\n /** Disabled flag for a filtered position — flag-only, no string decode. */\n disabledAt(filteredIndex: number): boolean {\n if (!this.engine) return false;\n const abs = this.engine.rowAt(filteredIndex);\n if (abs < 0) return false;\n return (this.engine.rowFlags(abs) & DISABLED_FLAG) !== 0;\n }\n\n /** Label for a filtered position — decodes a single label. */\n labelAt(filteredIndex: number): string {\n if (!this.engine) return '';\n const abs = this.engine.rowAt(filteredIndex);\n if (abs < 0) return '';\n const lp = this.engine.labelPtr(abs);\n const ll = this.engine.labelLen(abs);\n return this.dec.decode(this.mem().subarray(lp, lp + ll));\n }\n\n /**\n * Resolve labels for selected values that may be outside the current filter\n * (e.g. the trigger text / chips). O(1) per value via the engine's index.\n */\n getLabels(values: ReadonlyArray<string>): Map<string, string> {\n const result = new Map<string, string>();\n if (!this.engine) return result;\n const e = this.engine;\n for (const value of values) {\n const len = this.writeScratch(value);\n const abs = e.indexOfValue(len);\n if (abs >= 0) {\n const lp = e.labelPtr(abs);\n const ll = e.labelLen(abs);\n result.set(value, this.dec.decode(this.mem().subarray(lp, lp + ll)));\n }\n }\n return result;\n }\n\n /** Whether a value exists in the dataset. */\n has(value: string): boolean {\n if (!this.engine) return false;\n return this.engine.indexOfValue(this.writeScratch(value)) >= 0;\n }\n\n /**\n * Typeahead helper: first filtered position at/after `fromFilteredIndex`\n * whose label starts with `query` (wraps the filtered list). Returns a\n * filtered-list index, or -1.\n */\n findLabelPrefix(query: string, fromFilteredIndex: number): number {\n if (!this.engine) return -1;\n const len = this.writeScratch(query);\n return this.engine.findLabelPrefix(len, fromFilteredIndex);\n }\n\n /** Drop the dataset. */\n reset(): void {\n this.engine?.reset();\n this._length = 0;\n this._total = 0;\n }\n}\n","/**\n * `VirtualSelectController` — the shared virtualization engine for `md-select`\n * and `md-multi-select`, so neither component duplicates the window math,\n * scroll wiring, or the `VirtualMenuProvider` glue.\n *\n * It owns a `WasmOptionStore` (the dataset, packed in WASM memory) and the\n * current scroll window. The host component supplies a tiny adapter\n * (`queryItem` + `requestRender`) and reads the controller's public window\n * fields from its `render()`.\n */\nimport { computeWindow, DEFAULT_MAX_SCROLL_HEIGHT } from './virtual-window';\n\n/** Floor under which a measured scrollHeight cannot be a genuine browser\n * element-height clamp (real clamps are millions of px — Chrome ~33.5M,\n * Firefox ~17.8M) — it just means layout wasn't ready (see detectScrollCap). */\nconst MIN_PLAUSIBLE_SCROLL_CAP = 1_000_000;\nimport {\n FilterMode,\n isWasmSupported,\n VirtualRow,\n WasmOptionStore,\n} from './wasm-option-store';\nimport { isRowSource, OptionRowSource, SelectOptionInit } from './select-options';\nimport { VirtualMenuProvider } from './types';\n\n// Larger overscan than a typical virtual list: in the scaled regime a single\n// scroll frame can advance many rows, and render is async, so extra buffered\n// rows above/below the fold keep the body from flashing blank on fast scrolls.\nconst OVERSCAN = 8;\nconst DEFAULT_ROW_HEIGHT = 48;\nconst DEFAULT_VIEWPORT_HEIGHT = 320;\n// Extra px to keep a keyboard-revealed row clear of the viewport's top/bottom\n// edge. Historically 32px to clear md-scroll-shadow's edge fade; the scroll\n// shadow was removed, so a revealed row can sit flush against the edge (0). Kept\n// as a named knob in case a future edge treatment needs slack again.\nconst EDGE_SCRIM_PAD = 0;\n\nexport interface VirtualSelectHost {\n /** The rendered `md-menu-item` for a filtered index, from the host's shadow DOM. */\n queryItem(filteredIndex: number): HTMLElement | null;\n /** Re-render the host (it reads the controller's window fields). */\n requestRender(): void;\n}\n\nexport class VirtualSelectController {\n readonly store = new WasmOptionStore();\n\n /** True once a dataset is loaded and the component should render windowed. */\n active = false;\n /** First filtered index currently rendered. */\n windowStart = 0;\n /** The decoded rows in the current window. */\n windowRows: VirtualRow[] = [];\n /** Spacer heights (px) that preserve the full scroll height. */\n topPad = 0;\n bottomPad = 0;\n /** Current filtered row count. */\n filteredLength = 0;\n /** Effective fixed row height (measured or overridden). */\n rowHeight = DEFAULT_ROW_HEIGHT;\n\n private fixedRowHeight?: number;\n private viewportEl?: HTMLElement;\n private scrollRaf = 0;\n\n /**\n * The browser's observed maximum element height. Browsers clamp very tall\n * elements (a few-million-row list × row height blows past the ~16–33M px\n * cap), so the spacers can't reproduce the true height. We start optimistic\n * and shrink to the real clamp once we can measure it (see `detectScrollCap`).\n */\n private browserMaxScroll = Infinity;\n /** The scrollable height the last `recompute` asked the spacers to produce. */\n private intendedScrollHeight = 0;\n private detectRaf = 0;\n /** Retries left for detectScrollCap while layout isn't ready (see below). */\n private detectRetries = 0;\n\n /**\n * Scaled-regime keyboard nav: the first row to render, pinned independent of\n * the (too-coarse) integer scrollTop. -1 means the window is scroll-driven.\n */\n private navAnchorFirstRow = -1;\n /** The scroll offset the last `recompute` laid the window out for. */\n private usedScrollTop = 0;\n\n constructor(private host: VirtualSelectHost) {}\n\n /** Ceiling on the spacer height: our safe default, lowered by any real clamp. */\n private effectiveMaxScroll(): number {\n return Math.min(DEFAULT_MAX_SCROLL_HEIGHT, this.browserMaxScroll);\n }\n\n setFixedRowHeight(px?: number): void {\n this.fixedRowHeight = px && px > 0 ? px : undefined;\n if (this.fixedRowHeight) this.rowHeight = this.fixedRowHeight;\n }\n\n setFilterMode(mode: FilterMode): void {\n this.store.setFilterMode(mode);\n }\n\n /** Load a dataset into WASM memory. Returns false if WASM is unavailable. */\n async load(source: ReadonlyArray<SelectOptionInit> | OptionRowSource): Promise<boolean> {\n const count = isRowSource(source) ? source.count : source.length;\n if (!isWasmSupported() || count === 0) return false;\n try {\n await this.store.ensureReady();\n } catch {\n return false;\n }\n await this.store.load(source);\n this.active = true;\n this.filteredLength = this.store.length;\n this.recompute(this.viewportEl?.scrollTop ?? 0);\n return true;\n }\n\n /** Apply a filter query and reset the scroll to the top. */\n setQuery(query: string): void {\n if (!this.active) return;\n this.filteredLength = this.store.setQuery(query);\n this.navAnchorFirstRow = -1;\n if (this.viewportEl) this.viewportEl.scrollTop = 0;\n this.recompute(0);\n }\n\n getLabels(values: ReadonlyArray<string>): Map<string, string> {\n return this.store.getLabels(values);\n }\n\n reset(): void {\n this.store.reset();\n this.active = false;\n this.windowRows = [];\n this.filteredLength = 0;\n this.windowStart = 0;\n this.topPad = 0;\n this.bottomPad = 0;\n this.navAnchorFirstRow = -1;\n }\n\n // ── Viewport wiring (call when the menu opens / closes) ──────\n\n async attachViewport(getViewport: () => Promise<HTMLElement | null>): Promise<void> {\n this.detachViewport();\n const vp = await getViewport();\n this.viewportEl = vp ?? undefined;\n if (this.viewportEl) {\n this.viewportEl.addEventListener('scroll', this.onScroll, { passive: true });\n this.measureRowHeight();\n this.recompute(this.viewportEl.scrollTop);\n this.detectRetries = 60; // ~2s of rAF pairs — spacers may render late\n this.detectScrollCap();\n }\n }\n\n detachViewport(): void {\n if (this.scrollRaf) {\n cancelAnimationFrame(this.scrollRaf);\n this.scrollRaf = 0;\n }\n if (this.detectRaf) {\n cancelAnimationFrame(this.detectRaf);\n this.detectRaf = 0;\n }\n this.viewportEl?.removeEventListener('scroll', this.onScroll);\n this.viewportEl = undefined;\n }\n\n private onScroll = () => {\n if (this.scrollRaf) return;\n this.scrollRaf = requestAnimationFrame(() => {\n this.scrollRaf = 0;\n const vp = this.viewportEl;\n if (!vp) return;\n // Tell our own programmatic scroll (driving an anchored keyboard-nav\n // window) from a genuine user scroll by value: if the offset still matches\n // what the current window was laid out for, keep the anchor; otherwise the\n // user scrolled, so resume scroll-driven windowing. (A value check is\n // robust to event coalescing/ordering, unlike a one-shot flag.)\n if (this.navAnchorFirstRow >= 0 && Math.abs(vp.scrollTop - this.usedScrollTop) <= 1) {\n return;\n }\n this.navAnchorFirstRow = -1;\n this.recompute(vp.scrollTop);\n });\n };\n\n private measureRowHeight(): void {\n if (this.fixedRowHeight) {\n this.rowHeight = this.fixedRowHeight;\n return;\n }\n const first = this.host.queryItem(this.windowStart);\n const h = first?.offsetHeight ?? 0;\n if (h > 0 && h !== this.rowHeight) {\n this.rowHeight = h;\n if (this.viewportEl) this.recompute(this.viewportEl.scrollTop);\n }\n }\n\n private recompute(scrollTop: number): void {\n const vpH = this.viewportEl?.clientHeight || DEFAULT_VIEWPORT_HEIGHT;\n const calc = computeWindow(\n scrollTop,\n vpH,\n this.rowHeight,\n this.filteredLength,\n OVERSCAN,\n this.effectiveMaxScroll(),\n this.navAnchorFirstRow,\n );\n this.windowStart = calc.start;\n this.topPad = calc.topPad;\n this.bottomPad = calc.bottomPad;\n this.intendedScrollHeight = calc.scrollHeight;\n this.usedScrollTop = calc.scrollTop;\n this.windowRows = this.store.getWindow(calc.start, calc.end - calc.start);\n this.host.requestRender();\n }\n\n /**\n * Detect the browser's real maximum element height. After the spacers lay\n * out, if the viewport's `scrollHeight` came back shorter than we asked for,\n * the browser clamped it — and that clamp *is* the true maximum, so adopt it\n * and re-window against it. Runs a couple of frames after attach so the\n * (async) spacer render has committed; idempotent and only ever shrinks.\n */\n private detectScrollCap(): void {\n if (this.detectRaf) cancelAnimationFrame(this.detectRaf);\n this.detectRaf = requestAnimationFrame(() => {\n this.detectRaf = requestAnimationFrame(() => {\n this.detectRaf = 0;\n const vp = this.viewportEl;\n if (!vp) return;\n const measured = vp.scrollHeight;\n if (\n measured > 0 &&\n measured + 2 < this.intendedScrollHeight &&\n measured < this.browserMaxScroll\n ) {\n // A small reading is NOT a browser clamp — the spacers simply have\n // not been laid out yet (e.g. the menu opened during a dataset pack\n // and still showed the uncapped busy bar when we measured). Locking\n // it in would permanently collapse the scroll geometry (the cap\n // never grows back), so retry instead.\n if (measured < MIN_PLAUSIBLE_SCROLL_CAP) {\n if (this.detectRetries-- > 0) this.detectScrollCap();\n return;\n }\n this.browserMaxScroll = measured;\n this.recompute(vp.scrollTop);\n }\n });\n });\n }\n\n // ── VirtualMenuProvider (md-menu drives nav through this) ────\n\n readonly provider: VirtualMenuProvider = {\n count: () => this.filteredLength,\n labelAt: (i) => this.store.labelAt(i),\n isDisabledAt: (i) => this.store.disabledAt(i),\n ensureVisible: (i) => this.ensureVisible(i),\n domItemForIndex: (i) => this.host.queryItem(i),\n findPrefix: (buffer, from) => this.store.findLabelPrefix(buffer, from),\n };\n\n private async ensureVisible(filteredIndex: number): Promise<void> {\n const vp = this.viewportEl;\n if (!vp) return;\n const clientH = vp.clientHeight || DEFAULT_VIEWPORT_HEIGHT;\n const realHeight = this.filteredLength * this.rowHeight;\n\n if (realHeight <= this.effectiveMaxScroll()) {\n // Exact regime: pixel offset is the row index times the row height.\n this.navAnchorFirstRow = -1;\n const top = filteredIndex * this.rowHeight;\n const bottom = top + this.rowHeight;\n // Reveal with EDGE_SCRIM_PAD of slack so the row clears the edge fade.\n // Clamped to [0, maxScroll]: rows at the very top/bottom — where no scrim\n // shows — still seat flush.\n const maxScroll = Math.max(0, vp.scrollHeight - clientH);\n if (top - EDGE_SCRIM_PAD < vp.scrollTop) {\n vp.scrollTop = Math.max(0, top - EDGE_SCRIM_PAD);\n } else if (bottom + EDGE_SCRIM_PAD > vp.scrollTop + clientH) {\n vp.scrollTop = Math.min(maxScroll, bottom + EDGE_SCRIM_PAD - clientH);\n }\n this.recompute(vp.scrollTop);\n } else {\n // Scaled regime: integer scrollTop can't address single rows (millions of\n // rows compressed into a capped height — one pixel can be dozens of rows).\n // When the target row isn't already on screen, pin the window to an anchor\n // and let `computeWindow` choose the matching scroll offset, then apply it.\n const visibleRows = Math.max(1, Math.floor(clientH / this.rowHeight));\n const visibleCount = Math.ceil(clientH / this.rowHeight);\n const maxFirstRow = Math.max(0, this.filteredLength - visibleCount);\n // First visible row: take it exactly from the anchor when the window is\n // anchor-driven (deriving it from a fractional scrollTop drifts by a row);\n // fall back to the live geometry only when scroll-driven.\n const firstVisible =\n this.navAnchorFirstRow >= 0\n ? this.navAnchorFirstRow\n : this.windowStart +\n Math.max(0, Math.round((vp.scrollTop - this.topPad) / this.rowHeight));\n const lastVisible = firstVisible + visibleRows - 1;\n\n // Re-anchor when the focused row is outside the visible range OR within\n // `padRows` of either edge. The edge check matters even when the row is\n // already visible: navigating up one row at a time makes the focused row\n // the *first* visible row (flush against the top), which is never \"outside\"\n // the range — so without it the top scroll-shadow scrim would still cover\n // the focused row. Mirrors the exact-regime branch above.\n const padRows = Math.ceil(EDGE_SCRIM_PAD / this.rowHeight);\n if (\n filteredIndex < firstVisible + padRows ||\n filteredIndex > lastVisible - padRows\n ) {\n // Reveal `padRows` clear of the top (scrolling up) or bottom (scrolling\n // down) edge, clamped to [0, maxFirstRow] so the list ends — where no\n // scrim shows — still seat the row flush.\n this.navAnchorFirstRow = Math.min(\n maxFirstRow,\n Math.max(\n 0,\n filteredIndex < firstVisible + padRows\n ? filteredIndex - padRows\n : filteredIndex - visibleRows + 1 + padRows,\n ),\n );\n }\n this.recompute(vp.scrollTop);\n // Sync the browser scroll to the offset the (anchored) window was laid out\n // for. Clamp to the viewport's real max — the capped element can render a\n // hair shorter than we asked (scroll-shadow sentinels), and overshooting by\n // even a pixel near the end gets clamped by the browser — then adopt\n // whatever it actually applied, so the scroll guard and the next \"first\n // visible\" never drift out of sync and clear the anchor.\n if (this.navAnchorFirstRow >= 0) {\n const maxScroll = Math.max(0, vp.scrollHeight - clientH);\n const target = Math.min(Math.round(this.usedScrollTop), maxScroll);\n if (target !== Math.round(vp.scrollTop)) {\n vp.scrollTop = target;\n }\n this.usedScrollTop = vp.scrollTop;\n }\n }\n // Wait for the host to render the target row into the window so the menu\n // can move real focus onto it.\n for (let tries = 0; tries < 8; tries++) {\n await new Promise<void>((resolve) => requestAnimationFrame(() => resolve()));\n if (this.host.queryItem(filteredIndex)) return;\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|