@alfadocs/ui-kit-debug 1.90.1 → 1.90.2
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/dist/_chunks/address-autocomplete-DR4Xn23Z.js +519 -0
- package/dist/_chunks/address-autocomplete-DR4Xn23Z.js.map +1 -0
- package/dist/_chunks/{address-fields-CfnXK8RT.js → address-fields-qxQkGwPf.js} +5 -5
- package/dist/_chunks/{address-fields-CfnXK8RT.js.map → address-fields-qxQkGwPf.js.map} +1 -1
- package/dist/_chunks/{ai-permission-notice-CoW22jx1.js → ai-permission-notice-VNh3W57L.js} +2 -2
- package/dist/_chunks/{ai-permission-notice-CoW22jx1.js.map → ai-permission-notice-VNh3W57L.js.map} +1 -1
- package/dist/_chunks/{anamnesis-summary-rows-fbEQwcuW.js → anamnesis-summary-rows-EKPfVCmh.js} +2 -2
- package/dist/_chunks/{anamnesis-summary-rows-fbEQwcuW.js.map → anamnesis-summary-rows-EKPfVCmh.js.map} +1 -1
- package/dist/_chunks/autocomplete-BXMcNoa3.js +562 -0
- package/dist/_chunks/autocomplete-BXMcNoa3.js.map +1 -0
- package/dist/_chunks/{balance-badge-cell-C4FYwmrZ.js → balance-badge-cell-D9VhFp0L.js} +3 -3
- package/dist/_chunks/{balance-badge-cell-C4FYwmrZ.js.map → balance-badge-cell-D9VhFp0L.js.map} +1 -1
- package/dist/_chunks/{booking-C0FoW8Yx.js → booking-CcE_oviI.js} +1896 -1859
- package/dist/_chunks/booking-CcE_oviI.js.map +1 -0
- package/dist/_chunks/{calendar-appointment-editor-dialog-C1v2MNE4.js → calendar-appointment-editor-dialog-CiAGAX2t.js} +7 -7
- package/dist/_chunks/{calendar-appointment-editor-dialog-C1v2MNE4.js.map → calendar-appointment-editor-dialog-CiAGAX2t.js.map} +1 -1
- package/dist/_chunks/{checkbox-BjDv-r3o.js → checkbox-a7Sh-dXb.js} +32 -31
- package/dist/_chunks/checkbox-a7Sh-dXb.js.map +1 -0
- package/dist/_chunks/{checkbox-group-Cw2H5qaq.js → checkbox-group-eGdv9fZc.js} +2 -2
- package/dist/_chunks/{checkbox-group-Cw2H5qaq.js.map → checkbox-group-eGdv9fZc.js.map} +1 -1
- package/dist/_chunks/{city-input-CJVGswxp.js → city-input-CA59CjnV.js} +2 -2
- package/dist/_chunks/{city-input-CJVGswxp.js.map → city-input-CA59CjnV.js.map} +1 -1
- package/dist/_chunks/{combobox-CDPm_n0p.js → combobox-D-gpgEDy.js} +314 -294
- package/dist/_chunks/combobox-D-gpgEDy.js.map +1 -0
- package/dist/_chunks/{country-select-DQ8q7ypA.js → country-select-BfmX9y5i.js} +2 -2
- package/dist/_chunks/{country-select-DQ8q7ypA.js.map → country-select-BfmX9y5i.js.map} +1 -1
- package/dist/_chunks/{data-table-B_IcS0Ke.js → data-table-CqQgoNsU.js} +2 -2
- package/dist/_chunks/{data-table-B_IcS0Ke.js.map → data-table-CqQgoNsU.js.map} +1 -1
- package/dist/_chunks/{face-scheme-BgJGFDTa.js → face-scheme-BKSE98bo.js} +2 -2
- package/dist/_chunks/{face-scheme-BgJGFDTa.js.map → face-scheme-BKSE98bo.js.map} +1 -1
- package/dist/_chunks/{file-manager-C9YOT-Dn.js → file-manager-BnI1ZWZu.js} +2 -2
- package/dist/_chunks/{file-manager-C9YOT-Dn.js.map → file-manager-BnI1ZWZu.js.map} +1 -1
- package/dist/_chunks/{header-settings-BVhjndtV.js → header-settings-BeA2fnol.js} +24 -23
- package/dist/_chunks/header-settings-BeA2fnol.js.map +1 -0
- package/dist/_chunks/{heatmap-HTz3Jvzy.js → heatmap-fCxwNz2o.js} +2 -2
- package/dist/_chunks/{heatmap-HTz3Jvzy.js.map → heatmap-fCxwNz2o.js.map} +1 -1
- package/dist/_chunks/{link-cell-renderer-C0ynDik7.js → link-cell-renderer-CnCgudvq.js} +3 -3
- package/dist/_chunks/{link-cell-renderer-C0ynDik7.js.map → link-cell-renderer-CnCgudvq.js.map} +1 -1
- package/dist/_chunks/{login-dev-card-DYwbL5sD.js → login-dev-card-BZBR58mu.js} +2 -2
- package/dist/_chunks/{login-dev-card-DYwbL5sD.js.map → login-dev-card-BZBR58mu.js.map} +1 -1
- package/dist/_chunks/{map-view-Bvi06RVh.js → map-view-UrNgxBy3.js} +260 -237
- package/dist/_chunks/map-view-UrNgxBy3.js.map +1 -0
- package/dist/_chunks/{index.modern-BeRXQVdc.js → maps-core-gate-DkNqGkm3.js} +360 -319
- package/dist/_chunks/maps-core-gate-DkNqGkm3.js.map +1 -0
- package/dist/_chunks/{marketplace-app-shell-x_abo_ye.js → marketplace-app-shell-CmZx0Oam.js} +2 -2
- package/dist/_chunks/{marketplace-app-shell-x_abo_ye.js.map → marketplace-app-shell-CmZx0Oam.js.map} +1 -1
- package/dist/_chunks/{notes-panel-CZO1qsD-.js → notes-panel-Dywo6R55.js} +2 -2
- package/dist/_chunks/{notes-panel-CZO1qsD-.js.map → notes-panel-Dywo6R55.js.map} +1 -1
- package/dist/_chunks/{patient-details-D0P5eog5.js → patient-details-BUr7Oemx.js} +2 -2
- package/dist/_chunks/{patient-details-D0P5eog5.js.map → patient-details-BUr7Oemx.js.map} +1 -1
- package/dist/_chunks/{patient-field-row-R73dZJY6.js → patient-field-row-bJk8Q_qr.js} +5 -5
- package/dist/_chunks/{patient-field-row-R73dZJY6.js.map → patient-field-row-bJk8Q_qr.js.map} +1 -1
- package/dist/_chunks/patient-search-Ca9j5cWb.js +1306 -0
- package/dist/_chunks/patient-search-Ca9j5cWb.js.map +1 -0
- package/dist/_chunks/{patient-summary-card-6U74-ivO.js → patient-summary-card-CCQZ8X37.js} +2 -2
- package/dist/_chunks/{patient-summary-card-6U74-ivO.js.map → patient-summary-card-CCQZ8X37.js.map} +1 -1
- package/dist/_chunks/{periodontal-diagnosis-B9YmmVmM.js → periodontal-diagnosis-DD3hrg9X.js} +2 -2
- package/dist/_chunks/{periodontal-diagnosis-B9YmmVmM.js.map → periodontal-diagnosis-DD3hrg9X.js.map} +1 -1
- package/dist/_chunks/{permission-matrix-BoQjENGV.js → permission-matrix-BJ6sg3Zp.js} +3 -3
- package/dist/_chunks/{permission-matrix-BoQjENGV.js.map → permission-matrix-BJ6sg3Zp.js.map} +1 -1
- package/dist/_chunks/{practice-results-B61krlwu.js → practice-results-DQuOfqej.js} +2 -2
- package/dist/_chunks/{practice-results-B61krlwu.js.map → practice-results-DQuOfqej.js.map} +1 -1
- package/dist/_chunks/{province-select-CPdTwEob.js → province-select-D64whw0m.js} +2 -2
- package/dist/_chunks/{province-select-CPdTwEob.js.map → province-select-D64whw0m.js.map} +1 -1
- package/dist/_chunks/{registration-form-DmP3YUfp.js → registration-form-CRm6DaB9.js} +2 -2
- package/dist/_chunks/{registration-form-DmP3YUfp.js.map → registration-form-CRm6DaB9.js.map} +1 -1
- package/dist/_chunks/{reviews-panel-UzQQLb-z.js → reviews-panel-B7InBORU.js} +42 -41
- package/dist/_chunks/reviews-panel-B7InBORU.js.map +1 -0
- package/dist/_chunks/{rich-text-editor-BZTyxQBd.js → rich-text-editor-BfEu57dk.js} +3 -3
- package/dist/_chunks/{rich-text-editor-BZTyxQBd.js.map → rich-text-editor-BfEu57dk.js.map} +1 -1
- package/dist/_chunks/{slot-grid-Bb13H9Rl.js → slot-grid-DrwynKeN.js} +91 -89
- package/dist/_chunks/{slot-grid-Bb13H9Rl.js.map → slot-grid-DrwynKeN.js.map} +1 -1
- package/dist/_chunks/{task-editor-BOETWbjU.js → task-editor-CI1SKUNc.js} +2 -2
- package/dist/_chunks/{task-editor-BOETWbjU.js.map → task-editor-CI1SKUNc.js.map} +1 -1
- package/dist/_chunks/{use-appointment-details-read-CWN-nJCZ.js → use-appointment-details-read-BytPq3Ux.js} +2 -2
- package/dist/_chunks/{use-appointment-details-read-CWN-nJCZ.js.map → use-appointment-details-read-BytPq3Ux.js.map} +1 -1
- package/dist/_chunks/{voice-control-panel-BziKE-KK.js → voice-control-panel-BP0otrID.js} +2 -2
- package/dist/_chunks/{voice-control-panel-BziKE-KK.js.map → voice-control-panel-BP0otrID.js.map} +1 -1
- package/dist/_chunks/{workflow-webhook-action-DulCpCRz.js → workflow-webhook-action-B_nBJ_ht.js} +2 -2
- package/dist/_chunks/{workflow-webhook-action-DulCpCRz.js.map → workflow-webhook-action-B_nBJ_ht.js.map} +1 -1
- package/dist/agent-catalog.json +2 -2
- package/dist/agent-i18n/en.json +1 -1
- package/dist/components/_shared/maps-core-gate.d.ts +18 -0
- package/dist/components/_shared/maps-core-gate.d.ts.map +1 -0
- package/dist/components/address-autocomplete/address-autocomplete.d.ts.map +1 -1
- package/dist/components/address-autocomplete/index.js +1 -1
- package/dist/components/address-fields/index.js +1 -1
- package/dist/components/ai-permission-notice/index.js +1 -1
- package/dist/components/appointment-details-panel/index.js +1 -1
- package/dist/components/autocomplete/autocomplete.agent.d.ts.map +1 -1
- package/dist/components/autocomplete/autocomplete.d.ts.map +1 -1
- package/dist/components/autocomplete/index.js +1 -1
- package/dist/components/booking/booking.d.ts.map +1 -1
- package/dist/components/booking/details-form.d.ts.map +1 -1
- package/dist/components/booking/index.js +1 -1
- package/dist/components/checkbox/checkbox.d.ts.map +1 -1
- package/dist/components/checkbox/index.js +1 -1
- package/dist/components/checkbox-group/index.js +1 -1
- package/dist/components/city-input/index.js +1 -1
- package/dist/components/combobox/combobox.d.ts.map +1 -1
- package/dist/components/combobox/index.js +1 -1
- package/dist/components/country-select/index.js +1 -1
- package/dist/components/data-table/index.js +2 -2
- package/dist/components/face-scheme/index.js +1 -1
- package/dist/components/file-manager/index.js +1 -1
- package/dist/components/header-settings/header-settings.d.ts +2 -1
- package/dist/components/header-settings/header-settings.d.ts.map +1 -1
- package/dist/components/header-settings/index.js +1 -1
- package/dist/components/heatmap/index.js +1 -1
- package/dist/components/map-view/index.js +1 -1
- package/dist/components/map-view/map-view.d.ts.map +1 -1
- package/dist/components/notes-panel/index.js +1 -1
- package/dist/components/patient-details/index.js +1 -1
- package/dist/components/patient-search/index.js +1 -1
- package/dist/components/patient-search/patient-search.d.ts.map +1 -1
- package/dist/components/patient-summary-card/index.js +1 -1
- package/dist/components/patient-table/index.js +1 -1
- package/dist/components/periodontal-diagnosis/index.js +1 -1
- package/dist/components/permission-matrix/index.js +1 -1
- package/dist/components/practice-results/index.js +1 -1
- package/dist/components/province-select/index.js +1 -1
- package/dist/components/reviews-panel/index.js +1 -1
- package/dist/components/reviews-panel/reviews-panel.d.ts.map +1 -1
- package/dist/components/rich-text-editor/index.js +1 -1
- package/dist/components/slot-grid/index.js +1 -1
- package/dist/components/slot-grid/slot-grid.d.ts.map +1 -1
- package/dist/components/task-editor/index.js +1 -1
- package/dist/components/voice-control-panel/index.js +1 -1
- package/dist/host-compat.css +1 -10
- package/dist/index.js +37 -37
- package/dist/patterns/anamnesis/index.js +1 -1
- package/dist/patterns/calendar/index.js +1 -1
- package/dist/patterns/login-form/index.js +1 -1
- package/dist/patterns/marketplace-app-shell/index.js +1 -1
- package/dist/patterns/registration-form/index.js +1 -1
- package/dist/patterns/workflow-webhook-action/index.js +1 -1
- package/dist/tokens.css +1 -1
- package/package.json +1 -1
- package/dist/_chunks/address-autocomplete-bPR2mNBt.js +0 -498
- package/dist/_chunks/address-autocomplete-bPR2mNBt.js.map +0 -1
- package/dist/_chunks/autocomplete-CnB1mHGc.js +0 -539
- package/dist/_chunks/autocomplete-CnB1mHGc.js.map +0 -1
- package/dist/_chunks/booking-C0FoW8Yx.js.map +0 -1
- package/dist/_chunks/checkbox-BjDv-r3o.js.map +0 -1
- package/dist/_chunks/combobox-CDPm_n0p.js.map +0 -1
- package/dist/_chunks/header-settings-BVhjndtV.js.map +0 -1
- package/dist/_chunks/index.modern-BeRXQVdc.js.map +0 -1
- package/dist/_chunks/map-view-Bvi06RVh.js.map +0 -1
- package/dist/_chunks/patient-search-CCOUZABE.js +0 -1196
- package/dist/_chunks/patient-search-CCOUZABE.js.map +0 -1
- package/dist/_chunks/reviews-panel-UzQQLb-z.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heatmap-HTz3Jvzy.js","sources":["../../node_modules/lucide-react/dist/esm/icons/grid-3x3.mjs","../../node_modules/lucide-react/dist/esm/icons/table-2.mjs","../../src/components/heatmap/heatmap.agent.ts","../../src/components/heatmap/heatmap-context.ts","../../src/components/heatmap/heatmap-format.ts","../../src/components/heatmap/heatmap-disclosure.ts","../../src/components/heatmap/heatmap-scale.ts","../../src/components/heatmap/heatmap-model.ts","../../src/components/heatmap/heatmap-tooltip.tsx","../../src/components/heatmap/heatmap-window.ts","../../src/components/heatmap/heatmap-variants.ts","../../src/components/heatmap/heatmap-grid.tsx","../../src/components/heatmap/heatmap-legend.tsx","../../src/components/heatmap/heatmap-table-view.tsx","../../src/components/heatmap/heatmap.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M3 9h18\", key: \"1pudct\" }],\n [\"path\", { d: \"M3 15h18\", key: \"5xshup\" }],\n [\"path\", { d: \"M9 3v18\", key: \"fh3hqa\" }],\n [\"path\", { d: \"M15 3v18\", key: \"14nvp0\" }]\n];\nconst Grid3x3 = createLucideIcon(\"grid-3x3\", __iconNode);\n\nexport { __iconNode, Grid3x3 as default };\n//# sourceMappingURL=grid-3x3.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M9 3H5a2 2 0 0 0-2 2v4m6-6h10a2 2 0 0 1 2 2v4M9 3v18m0 0h10a2 2 0 0 0 2-2V9M9 21H5a2 2 0 0 1-2-2V9m0 0h18\",\n key: \"gugj83\"\n }\n ]\n];\nconst Table2 = createLucideIcon(\"table-2\", __iconNode);\n\nexport { __iconNode, Table2 as default };\n//# sourceMappingURL=table-2.mjs.map\n","/* -------------------------------------------------------------------- */\n/* Agent adapter: Heatmap. */\n/* */\n/* Operations go through the curated `HeatmapHandle`. State returns ids, */\n/* numbers and structure only: never a row, column or group label, which */\n/* may name a person (src/docs/26-agent-readiness.mdx §7). The row, */\n/* column and group ids are state so an agent can address any cell, even */\n/* one a virtualised grid has not rendered. Every write rejects an id */\n/* the heatmap does not have before it changes or announces anything. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { HeatmapHandle } from './heatmap';\n\nconst cellSchema = {\n type: 'object',\n properties: {\n rowId: { type: 'string', description: 'Row id, from rowIds.' },\n columnId: {\n type: ['string', 'number'],\n description: 'Column id, from columnIds.',\n },\n },\n required: ['rowId', 'columnId'],\n} as const;\n\nexport const heatmapAgent: AgentAdapter<HeatmapHandle> = {\n id: 'heatmap',\n capabilities: [\n 'select_single',\n 'select_multiple',\n 'range_pick',\n 'expand',\n 'sort',\n 'view_change',\n ],\n state: {\n selection: {\n type: 'Array<{ rowId, columnId }>',\n descriptionKey: 'ui.agent.heatmap.state.selection',\n description: 'Row and column ids of the selected cells.',\n read: (handle) => handle.getSelection(),\n },\n selectionMode: {\n type: \"'none' | 'single' | 'multiple' | 'range'\",\n descriptionKey: 'ui.agent.heatmap.state.selectionMode',\n description: 'How cells can be selected in this heatmap.',\n read: (handle) => handle.getSelectionMode(),\n },\n view: {\n type: \"'heatmap' | 'table'\",\n descriptionKey: 'ui.agent.heatmap.state.view',\n description: 'Whether the heatmap or its table view is showing.',\n read: (handle) => handle.getView(),\n },\n sortRows: {\n type: \"'none' | 'label' | 'total-asc' | 'total-desc'\",\n descriptionKey: 'ui.agent.heatmap.state.sortRows',\n description: 'Current row order.',\n read: (handle) => handle.getSortRows(),\n },\n rowIds: {\n type: 'string[]',\n descriptionKey: 'ui.agent.heatmap.state.rowIds',\n description:\n 'Row ids in display order, every group expanded. Opaque, never a label.',\n read: (handle) => handle.getRowIds(),\n },\n columnIds: {\n type: 'Array<string | number>',\n descriptionKey: 'ui.agent.heatmap.state.columnIds',\n description: 'Column ids in order. Opaque, never a label.',\n read: (handle) => handle.getColumnIds(),\n },\n groupIds: {\n type: 'string[]',\n descriptionKey: 'ui.agent.heatmap.state.groupIds',\n description:\n 'Group ids in display order, empty unless rows are grouped. A group not listed in `groups` shows as group-1, group-2 and so on.',\n read: (handle) => handle.getGroupIds(),\n },\n collapsedGroups: {\n type: 'string[]',\n descriptionKey: 'ui.agent.heatmap.state.collapsedGroups',\n description: 'Ids (as in groupIds) of the row groups that are collapsed.',\n read: (handle) => handle.getCollapsedGroups(),\n },\n },\n actions: {\n select_cell: {\n safety: 'read',\n argsType: '{ rowId: string, columnId: string | number }',\n argsSchema: cellSchema,\n idempotent: true,\n descriptionKey: 'ui.agent.heatmap.actions.selectCell',\n description: 'Make one cell the whole selection.',\n errors: [\n 'Selection is off (selection=\"none\").',\n 'The row or column id does not exist.',\n ],\n examples: [\n {\n args: { rowId: 'chair-1', columnId: 10 },\n note: 'Select chair 1 at 10:00.',\n },\n ],\n invoke: (handle, args: { rowId: string; columnId: string | number }) => {\n handle.selectCells([args]);\n },\n },\n select_cells: {\n safety: 'read',\n argsType: '{ cells: Array<{ rowId, columnId }> }',\n argsSchema: {\n type: 'object',\n properties: {\n cells: {\n type: 'array',\n items: cellSchema,\n description:\n 'Cells to select; replaces the selection. Single mode keeps the first.',\n },\n },\n required: ['cells'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.heatmap.actions.selectCells',\n description: 'Replace the selection with the given cells.',\n errors: [\n 'Selection is off (selection=\"none\").',\n 'A row or column id does not exist; nothing is selected.',\n ],\n invoke: (\n handle,\n args: { cells: { rowId: string; columnId: string | number }[] },\n ) => {\n handle.selectCells(args.cells);\n },\n },\n select_range: {\n safety: 'read',\n argsType: '{ from: { rowId, columnId }, to: { rowId, columnId } }',\n argsSchema: {\n type: 'object',\n properties: {\n from: { ...cellSchema, description: 'One corner, inclusive.' },\n to: { ...cellSchema, description: 'The opposite corner, inclusive.' },\n },\n required: ['from', 'to'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.heatmap.actions.selectRange',\n description:\n 'Select the rectangle of cells between two corners, in the rows as shown.',\n errors: [\n 'Needs selection=\"range\" or \"multiple\".',\n 'A corner names a row or column that does not exist.',\n ],\n invoke: (\n handle,\n args: {\n from: { rowId: string; columnId: string | number };\n to: { rowId: string; columnId: string | number };\n },\n ) => {\n handle.selectRange(args.from, args.to);\n },\n },\n clear_selection: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.heatmap.actions.clearSelection',\n description: 'Deselect every cell.',\n errors: ['Selection is off (selection=\"none\").'],\n invoke: (handle) => {\n handle.clearSelection();\n },\n },\n read_cell: {\n safety: 'read',\n argsType: '{ rowId: string, columnId: string | number }',\n argsSchema: cellSchema,\n returns: '{ value, count, status, step } | null',\n returnsSchema: {\n type: ['object', 'null'],\n properties: {\n value: { type: ['number', 'null'] },\n count: { type: 'number' },\n status: { enum: ['value', 'empty', 'low-sample'] },\n step: { type: ['number', 'null'] },\n },\n },\n idempotent: true,\n descriptionKey: 'ui.agent.heatmap.actions.readCell',\n description:\n \"Read a cell's value, count, status and colour step (no labels).\",\n invoke: (handle, args: { rowId: string; columnId: string | number }) =>\n handle.readCell(args),\n },\n toggle_table_view: {\n safety: 'read',\n descriptionKey: 'ui.agent.heatmap.actions.toggleTableView',\n description: 'Switch between the heatmap and its table view.',\n returns: \"'heatmap' | 'table'\",\n returnsSchema: { enum: ['heatmap', 'table'] },\n invoke: (handle) => {\n const next = handle.getView() === 'table' ? 'heatmap' : 'table';\n handle.setView(next);\n return next;\n },\n },\n set_view: {\n safety: 'read',\n argsType: \"{ view: 'heatmap' | 'table' }\",\n argsSchema: {\n type: 'object',\n properties: {\n view: {\n enum: ['heatmap', 'table'],\n description: 'The coloured grid, or the same data as a table.',\n },\n },\n required: ['view'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.heatmap.actions.setView',\n description: 'Show the heatmap or its table view.',\n invoke: (handle, args: { view: 'heatmap' | 'table' }) => {\n if (handle.getView() !== args.view) handle.setView(args.view);\n },\n },\n sort_rows: {\n safety: 'read',\n argsType: \"{ sort: 'none' | 'label' | 'total-asc' | 'total-desc' }\",\n argsSchema: {\n type: 'object',\n properties: {\n sort: {\n enum: ['none', 'label', 'total-asc', 'total-desc'],\n description:\n 'Row order within each group: as given, by label, or by row total.',\n },\n },\n required: ['sort'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.heatmap.actions.sortRows',\n description: 'Reorder the rows.',\n invoke: (\n handle,\n args: { sort: 'none' | 'label' | 'total-asc' | 'total-desc' },\n ) => {\n handle.setSortRows(args.sort);\n },\n },\n expand_group: {\n safety: 'read',\n argsType: '{ groupId: string }',\n argsSchema: {\n type: 'object',\n properties: {\n groupId: { type: 'string', description: 'Group id, from groupIds.' },\n },\n required: ['groupId'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.heatmap.actions.expandGroup',\n description: \"Show a group's rows.\",\n errors: [\n 'Rows are not grouped (groupRows is off).',\n 'The group id does not exist (see groupIds).',\n ],\n invoke: (handle, args: { groupId: string }) => {\n handle.setGroupCollapsed(args.groupId, false);\n },\n },\n collapse_group: {\n safety: 'read',\n argsType: '{ groupId: string }',\n argsSchema: {\n type: 'object',\n properties: {\n groupId: { type: 'string', description: 'Group id, from groupIds.' },\n },\n required: ['groupId'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.heatmap.actions.collapseGroup',\n description: \"Hide a group's rows, leaving its totals row.\",\n errors: [\n 'Rows are not grouped (groupRows is off).',\n 'The group id does not exist (see groupIds).',\n ],\n invoke: (handle, args: { groupId: string }) => {\n handle.setGroupCollapsed(args.groupId, true);\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'heatmap',\n description: 'Marks the Heatmap root.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop on Heatmap.',\n },\n item: {\n attr: 'data-heatmap-cell-id',\n description:\n 'On every data cell: \"<rowId>:<columnId>\", built from the opaque ids, never from labels. A group header row and its cells carry data-heatmap-group-id, the group id as in groupIds.',\n },\n },\n};\n","/* -------------------------------------------------------------------- */\n/* Context shared by the Heatmap root and its compound parts, so */\n/* Heatmap.Legend and Heatmap.Tooltip read the same scale, palette and */\n/* wording as the grid. */\n/* -------------------------------------------------------------------- */\n\nimport { createContext, useContext } from 'react';\nimport type { HeatmapDescriber } from './heatmap-format';\nimport type { HeatmapCellInfo } from './heatmap-model';\nimport type { ResolvedHeatmapScale } from './heatmap-scale';\nimport type { HeatmapPalette } from './heatmap-variants';\n\nexport interface HeatmapContextValue {\n palette: HeatmapPalette;\n scale: ResolvedHeatmapScale;\n describer: HeatmapDescriber;\n /** True when some cells fall below `minCount`, so the legend explains it. */\n hasLowSample: boolean;\n /** True when a total the grid draws is withheld to protect small\n * numbers. It may rest on many records, so the legend keys it apart. */\n hasWithheldTotal: boolean;\n /** True when some cells have no data. */\n hasEmpty: boolean;\n /** The sample threshold, when one is set. */\n minCount?: number;\n /** The tooltip text for a cell: the consumer's, or the default sentence. */\n tooltipText: (cell: HeatmapCellInfo) => string;\n}\n\nexport const HeatmapContext = createContext<HeatmapContextValue | null>(null);\n\n/** The surrounding Heatmap's context, or null outside one. */\nexport function useHeatmapContext(): HeatmapContextValue | null {\n return useContext(HeatmapContext);\n}\n","/* -------------------------------------------------------------------- */\n/* Heatmap text: number formats in the active locale, and the sentences */\n/* the cells, totals, tooltip and table view share, with privacy mode */\n/* applied in one place. */\n/* -------------------------------------------------------------------- */\n\nimport type { TFunction } from 'i18next';\nimport { privacyMask } from '../_shared/privacy-mask';\nimport type {\n HeatmapColumn,\n HeatmapGroup,\n HeatmapRow,\n ModelCell,\n} from './heatmap-model';\nimport type { HeatmapAggregate } from './heatmap-scale';\n\n/** What the values are: plain numbers, or rates between 0 and 1. */\nexport type HeatmapValueType = 'number' | 'rate';\n\n/**\n * What privacy mode masks. `rows`: the row labels, which name people,\n * chairs or patients. `all`: the column and group labels too. The kit rule\n * (src/components/_shared/privacy-mask.tsx) is to mask the identity and keep\n * time, place and status, so columns (hours, days) and groups (practices)\n * stay readable unless the host asks for more.\n */\nexport type HeatmapPrivacyScope = 'rows' | 'all';\n\n/** The default value format: a percentage for rates, a decimal otherwise. */\nexport function defaultValueFormatter(\n locale: string,\n valueType: HeatmapValueType,\n): (value: number) => string {\n const format = new Intl.NumberFormat(\n locale,\n valueType === 'rate'\n ? { style: 'percent', maximumFractionDigits: 0 }\n : { maximumFractionDigits: 2 },\n );\n return (value) => format.format(value);\n}\n\n/** Whole-number format for counts. */\nexport function countFormatter(locale: string): (count: number) => string {\n const format = new Intl.NumberFormat(locale, { maximumFractionDigits: 0 });\n return (count) => format.format(count);\n}\n\n/** Builds every sentence the heatmap speaks or shows. */\nexport interface HeatmapDescriber {\n /** True when privacy mode hides the row labels. */\n masksRows: boolean;\n /** True when privacy mode hides the column labels. */\n masksColumns: boolean;\n /** True when privacy mode hides the group labels. */\n masksGroups: boolean;\n rowLabel: (row: HeatmapRow) => string;\n columnLabel: (column: HeatmapColumn) => string;\n groupLabel: (groupId: string) => string;\n /** A cell by its headers: \"Tuesday, 10:00\". */\n cellName: (rowText: string, columnText: string) => string;\n /** A group header row: \"Mos Eisley (Average)\". */\n groupRowText: (groupText: string, method: HeatmapAggregate) => string;\n /** A cell as the table view shows it: \"26%, 10 of 39\". */\n tableText: (cell: ModelCell) => string;\n /** Label for a margin: \"Total\" for a sum, \"Average\" for a mean. */\n methodLabel: (method: HeatmapAggregate) => string;\n /** The value as text: formatted, a cell label, \"no data\" or \"too few\". */\n valueText: (cell: ModelCell) => string;\n /** The value as shown inside a cell, or '' when the cell shows none. */\n visibleText: (cell: ModelCell) => string;\n /** \"10 of 39\" for a rate, \"39 records\" otherwise; null without a count. */\n countText: (cell: ModelCell) => string | null;\n /** \"Tuesday, 10:00: 26%, 10 of 39\". */\n sentence: (rowText: string, columnText: string, cell: ModelCell) => string;\n /** Format for a raw value, used by the legend. */\n formatValue: (value: number) => string;\n}\n\nexport interface DescriberOptions {\n t: TFunction<'ui'>;\n privacyMode: boolean;\n /** What privacy mode masks. Default `rows`. */\n privacyScope?: HeatmapPrivacyScope;\n valueType: HeatmapValueType;\n formatValue: (value: number) => string;\n formatCount: (count: number) => string;\n groups?: readonly HeatmapGroup[];\n}\n\n/** The glyph an empty cell shows, so \"no data\" never relies on colour. */\nconst EMPTY_GLYPH = '–';\n\nexport function createDescriber({\n t,\n privacyMode,\n privacyScope = 'rows',\n valueType,\n formatValue,\n formatCount,\n groups,\n}: DescriberOptions): HeatmapDescriber {\n const groupNames = new Map(groups?.map((group) => [group.id, group.label]));\n const mask = privacyMask();\n const masksRows = privacyMode;\n const masksColumns = privacyMode && privacyScope === 'all';\n const masksGroups = privacyMode && privacyScope === 'all';\n const valueText = (cell: ModelCell): string => {\n if (cell.status === 'empty') return t('heatmap.noData');\n if (cell.status === 'low-sample') {\n // A withheld total may rest on many records: it is not \"too few\".\n return cell.withheld\n ? t('heatmap.totalWithheld')\n : t('heatmap.lowSample');\n }\n // A cell label is free text, so privacy mode shows the number instead.\n if (cell.label !== undefined && !privacyMode) return cell.label;\n return cell.value === null ? t('heatmap.noData') : formatValue(cell.value);\n };\n const countText = (cell: ModelCell): string | null => {\n if (cell.count === undefined) return null;\n if (\n valueType === 'rate' &&\n cell.status === 'value' &&\n cell.value !== null\n ) {\n return t('heatmap.countOf', {\n part: formatCount(Math.round(cell.value * cell.count)),\n total: formatCount(cell.count),\n });\n }\n return t('heatmap.records', {\n count: cell.count,\n formatted: formatCount(cell.count),\n });\n };\n return {\n masksRows,\n masksColumns,\n masksGroups,\n rowLabel: (row) => (masksRows ? mask : row.label),\n columnLabel: (column) => (masksColumns ? mask : column.label),\n // A group missing from `groups` has only its id to show, which may be a\n // name, so privacy mode masks it whatever the scope.\n groupLabel: (groupId) =>\n masksGroups\n ? mask\n : (groupNames.get(groupId) ?? (privacyMode ? mask : groupId)),\n cellName: (rowText, columnText) =>\n t('heatmap.cellName', { row: rowText, column: columnText }),\n groupRowText: (groupText, method) =>\n t('heatmap.groupRow', {\n group: groupText,\n method:\n method === 'sum' ? t('heatmap.totals.sum') : t('heatmap.totals.mean'),\n }),\n tableText: (cell) => {\n const count = cell.status === 'empty' ? null : countText(cell);\n const value = valueText(cell);\n return count === null\n ? value\n : t('heatmap.valueWithCount', { value, count });\n },\n methodLabel: (method) =>\n method === 'sum' ? t('heatmap.totals.sum') : t('heatmap.totals.mean'),\n valueText,\n visibleText: (cell) =>\n cell.status === 'empty'\n ? EMPTY_GLYPH\n : cell.status === 'low-sample'\n ? ''\n : valueText(cell),\n countText,\n sentence: (rowText, columnText, cell) => {\n const count = countText(cell);\n const value = valueText(cell);\n return count === null || cell.status === 'empty'\n ? t('heatmap.cell', { row: rowText, column: columnText, value })\n : t('heatmap.cellWithCount', {\n row: rowText,\n column: columnText,\n value,\n count,\n });\n },\n formatValue,\n };\n}\n","/* -------------------------------------------------------------------- */\n/* Heatmap disclosure control: which totals may be shown so that no */\n/* combination of them, the shown cells and the known bounds gives a */\n/* hidden cell away. Pure functions, no React. */\n/* */\n/* The model is a flow network. Each hidden cell is an arc from its row */\n/* to its group header cell (or column). Each total is an arc of a tree */\n/* above or below the cells: source, grand, group, row on one side; */\n/* group header cell, column, sink on the other, and the sink back to */\n/* the source. The flow on an arc is the hidden part of that total, in */\n/* audit units (numerators for count-weighted means: value x count). */\n/* A shown total fixes its arc's flow; a withheld one leaves it free. */\n/* Rows, groups and the grand total form one nested family and columns */\n/* and header cells the other, so the constraint matrix is totally */\n/* unimodular: every bound below is exact, integers included. */\n/* */\n/* The audit asks two questions of the shown totals: */\n/* 1. How far can each hidden cell move? Its feasible interval is a */\n/* max-flow question (push flow round a cycle through its arc). It */\n/* must span the protection level. */\n/* 2. Is the sum of any set of hidden cells with fewer than minCount */\n/* records determined? Exactly when those cells are all the arcs */\n/* leaving a set of nodes that nothing enters, once the free arcs */\n/* that can move are contracted: a directed cut. A min dicut search */\n/* finds any lighter than minCount. */\n/* */\n/* While the audit finds a disclosure, another shown total is withheld, */\n/* chosen to cover the most disclosures and, among those, the one */\n/* resting on the fewest records. Then each extra total is offered back, */\n/* most records first, and kept if the audit still passes. Withholding */\n/* every total that holds a hidden cell is always safe, and the search */\n/* falls back to it if it cannot finish. */\n/* -------------------------------------------------------------------- */\n\n/**\n * How narrow a hidden cell's interval may be.\n * - `rate`: the numerator lies in [0, records]. The interval must span at\n * least half that range and, for whole numbers, at least two values.\n * - `scaled`: values are non-negative with no upper bound. The interval\n * must reach down to half its own top or below (and not be a point).\n * - `free`: values have no bounds. The cell must not be pinned.\n */\nexport type ProtectionMode = 'rate' | 'scaled' | 'free';\n\n/** A hidden cell: an arc from its row node to its column-side node. */\nexport interface AuditCell {\n from: number;\n to: number;\n /** Bounds of its unknown, in audit units. */\n lo: number;\n hi: number;\n /** The records behind it (its count). */\n records: number;\n}\n\n/** A total: an arc of the tree above or below the cells. */\nexport interface AuditTotal {\n from: number;\n to: number;\n /** The hidden part of the total, in audit units, when it is shown. */\n value: number;\n /** Shown before the audit: drawn, with a value, and not withheld. */\n shown: boolean;\n /** The records behind the total: what withholding it loses. */\n records: number;\n}\n\nexport interface AuditProblem {\n nodeCount: number;\n /** The sink and source the closing arc joins (sink to source). */\n sink: number;\n source: number;\n cells: readonly AuditCell[];\n totals: readonly AuditTotal[];\n /** For each cell, the totals whose scope holds it. */\n cellTotals: readonly (readonly number[])[];\n mode: ProtectionMode;\n /** Whole-number data: numerators and shown totals are integers. */\n integral: boolean;\n minCount: number;\n}\n\n/** What the audit found: cells given away, and totals that would help. */\ninterface Disclosure {\n /** Every one of these must be withheld (a way round a cell). */\n allOf?: number[];\n /** Any one of these, withheld, breaks it (a set's cut). */\n anyOf?: number[];\n}\n\nconst BIG = 1e12;\n\n/**\n * A cap on the audit's work, in edges looked at, so a very large grid\n * cannot stall the page: past it, every total that holds a hidden cell is\n * withheld, which is always safe. Counted, not timed, so the same data\n * always gives the same result on every device. A 60 x 24 grid with 6\n * groups and 10% of cells hidden uses 2.5 million for rates and 3.15\n * million for plain sums, about half the cap (measured at about 12 ms in\n * Chromium on a desktop, not a guarantee); with 20% hidden, or 100 rows,\n * it runs out. Tests hold the count, not the time. Running out while offering totals back keeps the safe set already\n * found; running out before that takes the safe rule. When rates are\n * audited twice (printed and exact), the two passes share the cap.\n */\nexport const AUDIT_WORK_LIMIT = 5_000_000;\nconst WORK_LIMIT = AUDIT_WORK_LIMIT;\nlet work = 0;\nconst OUT_OF_WORK = new Error('heatmap audit: work limit');\n/** Failing cells whose way round is searched in one round. */\nconst OPENINGS_PER_ROUND = 32;\nconst spend = (edges: number) => {\n work += edges;\n if (work > WORK_LIMIT) throw OUT_OF_WORK;\n};\n\n/* -------------------------------------------------------------------- */\n/* Residual graph and augmenting paths */\n/* -------------------------------------------------------------------- */\n\ninterface Graph {\n n: number;\n head: Int32Array;\n next: Int32Array;\n to: Int32Array;\n edges: number;\n}\n\nfunction makeGraph(n: number, maxEdges: number): Graph {\n return {\n n,\n head: new Int32Array(n).fill(-1),\n next: new Int32Array(maxEdges * 2),\n to: new Int32Array(maxEdges * 2),\n edges: 0,\n };\n}\n\n/** Adds u to v and its reverse; returns the forward edge's id (reverse is\n * id ^ 1). Capacities live in a separate array. */\nfunction addEdge(g: Graph, u: number, v: number): number {\n const id = g.edges;\n g.to[id] = v;\n g.next[id] = g.head[u];\n g.head[u] = id;\n g.to[id + 1] = u;\n g.next[id + 1] = g.head[v];\n g.head[v] = id + 1;\n g.edges += 2;\n return id;\n}\n\n/**\n * Pushes up to `limit` from s to t along shortest augmenting paths,\n * changing `cap` in place, never using edge pair `skip` (an edge id, or\n * -1). Returns the amount pushed.\n */\nfunction augment(\n g: Graph,\n cap: Float64Array,\n s: number,\n t: number,\n limit: number,\n skip: number,\n eps: number,\n parent: Int32Array,\n queue: Int32Array,\n): number {\n if (s === t) return limit;\n const skipPair = skip >= 0 ? skip >> 1 : -1;\n let pushed = 0;\n let scanned = 0;\n while (pushed < limit - eps) {\n parent.fill(-2);\n parent[s] = -1;\n let qh = 0;\n let qt = 0;\n queue[qt++] = s;\n let found = false;\n while (qh < qt && !found) {\n const u = queue[qh++];\n for (let e = g.head[u]; e !== -1; e = g.next[e]) {\n scanned += 1;\n if (cap[e] <= eps || e >> 1 === skipPair) continue;\n const v = g.to[e];\n if (parent[v] !== -2) continue;\n parent[v] = e;\n if (v === t) {\n found = true;\n break;\n }\n queue[qt++] = v;\n }\n }\n spend(scanned);\n scanned = 0;\n if (!found) break;\n let bottleneck = limit - pushed;\n for (let v = t; v !== s; v = g.to[parent[v] ^ 1]) {\n bottleneck = Math.min(bottleneck, cap[parent[v]]);\n }\n for (let v = t; v !== s; v = g.to[parent[v] ^ 1]) {\n cap[parent[v]] -= bottleneck;\n cap[parent[v] ^ 1] += bottleneck;\n }\n pushed += bottleneck;\n }\n return pushed;\n}\n\n/** Nodes reachable from s over edges with capacity left, skipping a pair. */\nfunction reach(\n g: Graph,\n cap: Float64Array,\n s: number,\n skip: number,\n eps: number,\n queue: Int32Array,\n): Uint8Array {\n const seen = new Uint8Array(g.n);\n const skipPair = skip >= 0 ? skip >> 1 : -1;\n seen[s] = 1;\n let qh = 0;\n let qt = 0;\n queue[qt++] = s;\n let scanned = 0;\n while (qh < qt) {\n const u = queue[qh++];\n for (let e = g.head[u]; e !== -1; e = g.next[e]) {\n scanned += 1;\n if (cap[e] <= eps || e >> 1 === skipPair) continue;\n const v = g.to[e];\n if (seen[v]) continue;\n seen[v] = 1;\n queue[qt++] = v;\n }\n }\n spend(scanned);\n return seen;\n}\n\n/* -------------------------------------------------------------------- */\n/* The audit */\n/* -------------------------------------------------------------------- */\n\n/** Arc layout: totals first, then cells, then the closing arc. */\ninterface Network {\n graph: Graph;\n /** Residual capacities at a feasible flow (fixed arcs carry none). */\n cap: Float64Array;\n /** The feasible flow, per arc. */\n flow: Float64Array;\n closing: number;\n cellArc: (c: number) => number;\n}\n\nconst protectionNeed = (problem: AuditProblem, records: number): number =>\n problem.integral\n ? Math.max(1, Math.ceil(records / 2 - 1e-9))\n : Math.max(records / 2, 1e-6);\n\n/** Bounds of every arc for a given set of shown totals. */\nfunction arcBounds(\n problem: AuditProblem,\n shown: readonly boolean[],\n): { lo: Float64Array; hi: Float64Array } {\n const count = problem.totals.length + problem.cells.length + 1;\n const lo = new Float64Array(count);\n const hi = new Float64Array(count);\n const free = problem.mode === 'free';\n problem.totals.forEach((total, i) => {\n if (shown[i]) {\n lo[i] = total.value;\n hi[i] = total.value;\n } else {\n lo[i] = free ? -BIG : 0;\n hi[i] = BIG;\n }\n });\n const base = problem.totals.length;\n problem.cells.forEach((cell, c) => {\n lo[base + c] = free ? -BIG : Math.max(cell.lo, -BIG);\n hi[base + c] = free ? BIG : Math.min(cell.hi, BIG);\n });\n lo[count - 1] = free ? -BIG : 0;\n hi[count - 1] = BIG;\n return { lo, hi };\n}\n\nfunction endpoints(problem: AuditProblem, arc: number): [number, number] {\n const totals = problem.totals.length;\n if (arc < totals) return [problem.totals[arc].from, problem.totals[arc].to];\n if (arc < totals + problem.cells.length) {\n const cell = problem.cells[arc - totals];\n return [cell.from, cell.to];\n }\n return [problem.sink, problem.source];\n}\n\n/**\n * A feasible flow for the shown totals, as a residual network; null when\n * the shown totals contradict the cells (the data is not an aggregate of\n * the cells), which the caller treats as unsafe.\n */\nfunction feasibleNetwork(\n problem: AuditProblem,\n shown: readonly boolean[],\n eps: number,\n): Network | null {\n const { lo, hi } = arcBounds(problem, shown);\n const arcs = lo.length;\n const n = problem.nodeCount;\n spend(arcs * 4);\n // Circulation with lower bounds: shift every arc to [0, hi - lo] and\n // meet the shifted supplies from a super source and sink.\n const g = makeGraph(n + 2, arcs + n);\n const cap = new Float64Array((arcs + n) * 2);\n const excess = new Float64Array(n);\n for (let a = 0; a < arcs; a += 1) {\n const [u, v] = endpoints(problem, a);\n const id = addEdge(g, u, v);\n cap[id] = hi[a] - lo[a];\n excess[v] += lo[a];\n excess[u] -= lo[a];\n }\n const superSource = n;\n const superSink = n + 1;\n let demand = 0;\n for (let v = 0; v < n; v += 1) {\n if (excess[v] > 0) {\n cap[addEdge(g, superSource, v)] = excess[v];\n demand += excess[v];\n } else if (excess[v] < 0) {\n cap[addEdge(g, v, superSink)] = -excess[v];\n }\n }\n const parent = new Int32Array(n + 2);\n const queue = new Int32Array(n + 2);\n const pushed = augment(\n g,\n cap,\n superSource,\n superSink,\n Infinity,\n -1,\n eps,\n parent,\n queue,\n );\n if (pushed < demand - eps * Math.max(1, arcs)) return null;\n const flow = new Float64Array(arcs);\n for (let a = 0; a < arcs; a += 1) {\n flow[a] = lo[a] + (hi[a] - lo[a] - cap[2 * a]);\n }\n // The residual network of the original arcs alone, at that flow.\n const graph = makeGraph(n, arcs);\n const residual = new Float64Array(arcs * 2);\n for (let a = 0; a < arcs; a += 1) {\n const [u, v] = endpoints(problem, a);\n const id = addEdge(graph, u, v);\n const fixed = a < problem.totals.length && shown[a];\n residual[id] = fixed ? 0 : Math.max(0, hi[a] - flow[a]);\n residual[id + 1] = fixed ? 0 : Math.max(0, flow[a] - lo[a]);\n }\n const base = problem.totals.length;\n return {\n graph,\n cap: residual,\n flow,\n closing: arcs - 1,\n cellArc: (c) => base + c,\n };\n}\n\n/** Whether t can be reached from s over edges with capacity left,\n * skipping edge pair `skip`. Leaves `cap` untouched. */\nfunction pathExists(\n g: Graph,\n cap: Float64Array,\n s: number,\n t: number,\n skip: number,\n eps: number,\n queue: Int32Array,\n seen: Uint8Array,\n): boolean {\n if (s === t) return true;\n seen.fill(0);\n const skipPair = skip >> 1;\n seen[s] = 1;\n let qh = 0;\n let qt = 0;\n let scanned = 0;\n queue[qt++] = s;\n while (qh < qt) {\n const u = queue[qh++];\n for (let e = g.head[u]; e !== -1; e = g.next[e]) {\n scanned += 1;\n if (cap[e] <= eps || e >> 1 === skipPair) continue;\n const v = g.to[e];\n if (seen[v]) continue;\n if (v === t) {\n spend(scanned);\n return true;\n }\n seen[v] = 1;\n queue[qt++] = v;\n }\n }\n spend(scanned);\n return false;\n}\n\n/**\n * The shown totals to withhold, fewest records first, that open a path\n * from s to t: residual edges cost nothing, and a shown total costs its\n * records (once withheld it carries any amount forward, and back as much\n * as it holds). Skips edge pair `skip`, the cell's own arc.\n */\n/** Per node, the shown totals leaving it once withheld: [to, records,\n * total]. Both ways for a total that holds anything. */\ntype Openings = readonly (readonly (readonly [number, number, number])[])[];\n\nfunction openings(\n problem: AuditProblem,\n shown: readonly boolean[],\n n: number,\n eps: number,\n): Openings {\n const extra: [number, number, number][][] = Array.from(\n { length: n },\n () => [],\n );\n problem.totals.forEach((total, i) => {\n if (!shown[i]) return;\n extra[total.from].push([total.to, total.records, i]);\n if (total.value > eps) extra[total.to].push([total.from, total.records, i]);\n });\n spend(problem.totals.length);\n return extra;\n}\n\nfunction cheapestOpening(\n net: Network,\n extra: Openings,\n s: number,\n t: number,\n skip: number,\n eps: number,\n): number[] {\n const { graph, cap } = net;\n const n = graph.n;\n const skipPair = skip >> 1;\n const dist = new Float64Array(n).fill(Infinity);\n const via = new Int32Array(n).fill(-1);\n const from = new Int32Array(n).fill(-1);\n const done = new Uint8Array(n);\n dist[s] = 0;\n // A small binary heap of [distance, node].\n const heap: [number, number][] = [[0, s]];\n const pushHeap = (item: [number, number]) => {\n heap.push(item);\n let i = heap.length - 1;\n while (i > 0) {\n const up = (i - 1) >> 1;\n if (\n heap[up][0] < item[0] ||\n (heap[up][0] === item[0] && heap[up][1] <= item[1])\n )\n break;\n heap[i] = heap[up];\n i = up;\n }\n heap[i] = item;\n };\n const popHeap = (): [number, number] => {\n const top = heap[0];\n const last = heap.pop() as [number, number];\n if (heap.length) {\n let i = 0;\n for (;;) {\n const l = 2 * i + 1;\n const r = l + 1;\n let m = i;\n const better = (a: number, b: [number, number]) =>\n heap[a][0] < b[0] || (heap[a][0] === b[0] && heap[a][1] < b[1]);\n let best: [number, number] = last;\n if (l < heap.length && better(l, best)) {\n m = l;\n best = heap[l];\n }\n if (r < heap.length && better(r, best)) {\n m = r;\n best = heap[r];\n }\n if (m === i) break;\n heap[i] = heap[m];\n i = m;\n }\n heap[i] = last;\n }\n return top;\n };\n while (heap.length) {\n const [d, u] = popHeap();\n if (done[u]) continue;\n done[u] = 1;\n // Each node settled costs a heap step and every edge it looks at.\n let edges = 2 + extra[u].length;\n for (let e = graph.head[u]; e !== -1; e = graph.next[e]) edges += 1;\n spend(edges);\n if (u === t) break;\n for (let e = graph.head[u]; e !== -1; e = graph.next[e]) {\n if (cap[e] <= eps || e >> 1 === skipPair) continue;\n const v = graph.to[e];\n if (d < dist[v]) {\n dist[v] = d;\n via[v] = -1;\n from[v] = u;\n pushHeap([d, v]);\n }\n }\n for (const [v, cost, total] of extra[u]) {\n if (d + cost < dist[v]) {\n dist[v] = d + cost;\n via[v] = total;\n from[v] = u;\n pushHeap([d + cost, v]);\n }\n }\n }\n if (!Number.isFinite(dist[t])) return [];\n const picked: number[] = [];\n for (let v = t; v !== s; v = from[v]) {\n if (via[v] >= 0) picked.push(via[v]);\n }\n return picked.sort((a, b) => a - b);\n}\n\n/** Hidden cells, of those given, whose interval is narrower than the\n * protection level; `failed` lists them. */\nfunction narrowCells(\n problem: AuditProblem,\n shown: readonly boolean[],\n net: Network,\n eps: number,\n check: readonly number[],\n firstOnly: boolean,\n): { disclosures: Disclosure[]; failed: number[]; pinned: Uint8Array } {\n const failed: number[] = [];\n const { graph, cap } = net;\n const parent = new Int32Array(graph.n);\n const queue = new Int32Array(graph.n);\n const seen = new Uint8Array(graph.n);\n const disclosures: Disclosure[] = [];\n const arcs = net.flow.length;\n const pinned = new Uint8Array(arcs);\n // Whole numbers keep every residual capacity whole, so one unit moves\n // exactly when a path exists: no need to push it.\n const whole = problem.mode === 'rate' && problem.integral;\n const move = (s: number, t: number, limit: number, skip: number): number => {\n if (limit <= eps) return 0;\n if (whole && limit <= 1 + eps) {\n return pathExists(graph, cap, s, t, skip, eps, queue, seen) ? limit : 0;\n }\n // A copy costs work too: about one edge's worth per four numbers.\n spend(cap.length >> 2);\n return augment(graph, cap.slice(), s, t, limit, skip, eps, parent, queue);\n };\n\n // The ways round a failing cell are searched for the first few failing\n // cells only; the rest fail again next round, after those are fixed.\n let extra: Openings | null = null;\n const extraOf = (): Openings => {\n extra = extra ?? openings(problem, shown, graph.n, eps);\n return extra;\n };\n let opened = 0;\n\n for (const c of check) {\n const cell = problem.cells[c];\n const arc = net.cellArc(c);\n const [u, v] = endpoints(problem, arc);\n const id = 2 * arc;\n let safe: boolean;\n let upAsked: number;\n let downAsked: number;\n let up: number;\n let down: number;\n if (problem.mode === 'rate') {\n const need = protectionNeed(problem, cell.records);\n upAsked = Math.min(cap[id], need);\n up = move(v, u, upAsked, id);\n downAsked = Math.min(cap[id + 1], need - up);\n down = move(u, v, downAsked, id);\n safe = up + down >= need - eps;\n } else {\n // Non-negative, no top: the interval [f - down, f + up] must reach\n // down to half its top, so up + 2 x down >= f, and not be a point.\n // How far it falls first; then it need only rise that far.\n const f = net.flow[arc];\n downAsked = cap[id + 1];\n down = move(u, v, downAsked, id);\n const lift = Math.max(f - 2 * down, down > eps ? 0 : eps * 4);\n upAsked = Math.min(cap[id], lift);\n up = lift > 0 ? move(v, u, upAsked, id) : 0;\n safe = lift <= 0 || up >= lift - eps;\n }\n if (up + down <= eps) pinned[arc] = 1;\n if (safe) continue;\n failed.push(c);\n if (firstOnly) {\n disclosures.push({ allOf: [] });\n break;\n }\n if (opened >= OPENINGS_PER_ROUND) continue;\n opened += 1;\n // Withhold the cheapest totals that open a way round the cell, in each\n // direction the network (not the cell's own bound) stopped short.\n const open = new Set<number>();\n if (up < upAsked - eps) {\n for (const t of cheapestOpening(net, extraOf(), v, u, id, eps))\n open.add(t);\n }\n if (down < downAsked - eps) {\n for (const t of cheapestOpening(net, extraOf(), u, v, id, eps))\n open.add(t);\n }\n if (open.size === 0) {\n for (const t of problem.cellTotals[c]) if (shown[t]) open.add(t);\n }\n disclosures.push({ allOf: [...open].sort((a, b) => a - b) });\n }\n return { disclosures, failed, pinned };\n}\n\n/** Free totals whose flow no feasible change can move. */\nfunction pinnedTotals(\n problem: AuditProblem,\n shown: readonly boolean[],\n net: Network,\n pinned: Uint8Array,\n eps: number,\n): void {\n const { graph, cap } = net;\n const queue = new Int32Array(graph.n);\n const seen = new Uint8Array(graph.n);\n const check = (arc: number) => {\n const [u, v] = endpoints(problem, arc);\n const id = 2 * arc;\n if (cap[id] > eps && pathExists(graph, cap, v, u, id, eps, queue, seen)) {\n return;\n }\n if (\n cap[id + 1] > eps &&\n pathExists(graph, cap, u, v, id, eps, queue, seen)\n ) {\n return;\n }\n pinned[arc] = 1;\n };\n problem.totals.forEach((_, i) => {\n if (!shown[i]) check(i);\n });\n check(net.closing);\n}\n\n/**\n * Sets of hidden cells, with fewer than minCount records between them,\n * whose sum the shown totals determine. Contract every free arc that can\n * move except the cells; a set's sum is determined exactly when its cells\n * are all the arcs leaving some set of nodes that no cell enters.\n */\nfunction determinedSets(\n problem: AuditProblem,\n shown: readonly boolean[],\n net: Pick<Network, 'closing' | 'cellArc'>,\n pinned: Uint8Array,\n): Disclosure[] {\n const n = problem.nodeCount;\n const root = new Int32Array(n);\n for (let v = 0; v < n; v += 1) root[v] = v;\n const find = (v: number): number => {\n let r = v;\n while (root[r] !== r) r = root[r];\n while (root[v] !== r) {\n const up = root[v];\n root[v] = r;\n v = up;\n }\n return r;\n };\n const join = (a: number, b: number) => {\n const ra = find(a);\n const rb = find(b);\n if (ra !== rb) root[Math.max(ra, rb)] = Math.min(ra, rb);\n };\n problem.totals.forEach((total, i) => {\n if (!shown[i] && !pinned[i]) join(total.from, total.to);\n });\n if (!pinned[net.closing]) join(problem.sink, problem.source);\n\n // Cells between different blobs: the edges a determined set is made of.\n interface Edge {\n from: number;\n to: number;\n weight: number;\n cells: number[];\n }\n const edgeMap = new Map<number, Edge>();\n problem.cells.forEach((cell, c) => {\n if (pinned[net.cellArc(c)]) return;\n const a = find(cell.from);\n const b = find(cell.to);\n if (a === b) return;\n const key = a * n + b;\n const edge = edgeMap.get(key) ?? { from: a, to: b, weight: 0, cells: [] };\n // A cell with no records counts as many as minCount: it cannot make a\n // set smaller than minCount.\n edge.weight += cell.records > 0 ? cell.records : problem.minCount;\n edge.cells.push(c);\n edgeMap.set(key, edge);\n });\n const edges = [...edgeMap.values()].sort(\n (x, y) => x.from - y.from || x.to - y.to,\n );\n if (edges.length === 0) return [];\n\n // Strongly connected blobs: an edge inside one lies on a cycle and is\n // never part of a determined set.\n const ids = [...new Set(edges.flatMap((e) => [e.from, e.to]))].sort(\n (a, b) => a - b,\n );\n const local = new Map(ids.map((id, i) => [id, i]));\n const m = ids.length;\n const out: number[][] = Array.from({ length: m }, () => []);\n edges.forEach((e, i) => out[local.get(e.from) as number].push(i));\n const scc = new Int32Array(m).fill(-1);\n {\n // Tarjan, iterative.\n const index = new Int32Array(m).fill(-1);\n const low = new Int32Array(m);\n const onStack = new Uint8Array(m);\n const stack: number[] = [];\n let counter = 0;\n let sccCount = 0;\n for (let start = 0; start < m; start += 1) {\n if (index[start] !== -1) continue;\n const work: [number, number][] = [[start, 0]];\n index[start] = low[start] = counter++;\n stack.push(start);\n onStack[start] = 1;\n while (work.length) {\n const frame = work[work.length - 1];\n const [v, i] = frame;\n if (i < out[v].length) {\n frame[1] += 1;\n const w = local.get(edges[out[v][i]].to) as number;\n if (index[w] === -1) {\n index[w] = low[w] = counter++;\n stack.push(w);\n onStack[w] = 1;\n work.push([w, 0]);\n } else if (onStack[w]) {\n low[v] = Math.min(low[v], index[w]);\n }\n } else {\n work.pop();\n if (work.length) {\n const parentV = work[work.length - 1][0];\n low[parentV] = Math.min(low[parentV], low[v]);\n }\n if (low[v] === index[v]) {\n let w: number;\n do {\n w = stack.pop() as number;\n onStack[w] = 0;\n scc[w] = sccCount;\n } while (w !== v);\n sccCount += 1;\n }\n }\n }\n }\n }\n // The condensation: cross edges between components, weights added.\n const dag = new Map<string, { a: number; b: number; weight: number }>();\n const dagCells = new Map<string, number[]>();\n for (const e of edges) {\n const a = scc[local.get(e.from) as number];\n const b = scc[local.get(e.to) as number];\n if (a === b) continue;\n const key = `${a}>${b}`;\n const entry = dag.get(key) ?? { a, b, weight: 0 };\n entry.weight += e.weight;\n dag.set(key, entry);\n dagCells.set(key, [...(dagCells.get(key) ?? []), ...e.cells]);\n }\n if (dag.size === 0) return [];\n const dagEdges = [...dag.entries()].sort(([x], [y]) => (x < y ? -1 : 1));\n const nodes = [...new Set(dagEdges.flatMap(([, e]) => [e.a, e.b]))].sort(\n (a, b) => a - b,\n );\n const nodeIndex = new Map(nodes.map((v, i) => [v, i]));\n const k = nodes.length;\n\n // Weakly connected parts of the condensation.\n const part = new Int32Array(k);\n for (let i = 0; i < k; i += 1) part[i] = i;\n const partOf = (i: number): number => {\n while (part[i] !== i) {\n part[i] = part[part[i]];\n i = part[i];\n }\n return i;\n };\n for (const [, e] of dagEdges) {\n const a = partOf(nodeIndex.get(e.a) as number);\n const b = partOf(nodeIndex.get(e.b) as number);\n if (a !== b) part[Math.max(a, b)] = Math.min(a, b);\n }\n\n // One graph for the min dicut search: each cross edge forward with its\n // weight, and backward without limit, so a finite cut is a directed one.\n const g = makeGraph(k, dagEdges.length);\n const base = new Float64Array(dagEdges.length * 2);\n for (const [, e] of dagEdges) {\n const id = addEdge(\n g,\n nodeIndex.get(e.a) as number,\n nodeIndex.get(e.b) as number,\n );\n base[id] = e.weight;\n base[id + 1] = BIG;\n }\n const parent = new Int32Array(k);\n const queue = new Int32Array(k);\n const found = new Map<string, Disclosure>();\n /** Maps a side of the condensation back to the network's nodes: 1 for\n * the closed side, 0 for the rest, including nodes no cell touches.\n * `inGraph` marks nodes in a blob that some cell touches. */\n const sccSide = (side: Uint8Array) => {\n const nodeSide = new Uint8Array(n);\n const inGraph = new Uint8Array(n);\n const sccIn = new Map<number, number>();\n nodes.forEach((v, i) => sccIn.set(v, side[i]));\n for (let v = 0; v < n; v += 1) {\n const blob = local.get(find(v));\n if (blob === undefined) continue;\n inGraph[v] = 1;\n nodeSide[v] = sccIn.get(scc[blob]) ?? 0;\n }\n return { nodeSide, inGraph };\n };\n const record = (side: Uint8Array) => {\n const cells: number[] = [];\n for (const [key, e] of dagEdges) {\n const a = nodeIndex.get(e.a) as number;\n const b = nodeIndex.get(e.b) as number;\n if (side[a] === 1 && side[b] === 0) {\n cells.push(...(dagCells.get(key) ?? []));\n }\n }\n cells.sort((a, b) => a - b);\n const key = cells.join(',');\n if (found.has(key)) return;\n const { nodeSide, inGraph } = sccSide(side);\n // A shown total joining the two sides breaks this cut once withheld\n // when both its ends are in blobs a cell touches; one reaching a node\n // no cell touches only moves the boundary, so it is a second choice.\n const direct = new Set<number>();\n const indirect = new Set<number>();\n problem.totals.forEach((total, i) => {\n if (!shown[i] || nodeSide[total.from] === nodeSide[total.to]) return;\n if (inGraph[total.from] && inGraph[total.to]) direct.add(i);\n else indirect.add(i);\n });\n const candidates = direct.size > 0 ? direct : indirect;\n if (candidates.size === 0) {\n for (const c of cells) {\n for (const t of problem.cellTotals[c]) if (shown[t]) candidates.add(t);\n }\n }\n found.set(key, { anyOf: [...candidates].sort((a, b) => a - b) });\n };\n const limit = problem.minCount;\n const roots = new Map<number, number>();\n for (let i = 0; i < k; i += 1) {\n const p = partOf(i);\n if (!roots.has(p)) roots.set(p, i);\n }\n for (let v = 0; v < k; v += 1) {\n const r = roots.get(partOf(v)) as number;\n if (r === v) continue;\n for (const [s, t] of [\n [r, v],\n [v, r],\n ]) {\n spend(base.length >> 2);\n const work = base.slice();\n const value = augment(g, work, s, t, limit, -1, 1e-9, parent, queue);\n if (value < limit - 1e-9) {\n // The source side of the cut: everything still reachable.\n const side = reach(g, work, s, -1, 1e-9, queue);\n record(side);\n }\n }\n }\n return [...found.values()];\n}\n\n/** Bridges of the free network: the cells no equation-free cycle moves. */\nfunction freePinned(\n problem: AuditProblem,\n shown: readonly boolean[],\n): Uint8Array {\n const n = problem.nodeCount;\n const arcs = problem.totals.length + problem.cells.length + 1;\n const adj: [number, number][][] = Array.from({ length: n }, () => []);\n for (let a = 0; a < arcs; a += 1) {\n if (a < problem.totals.length && shown[a]) continue;\n const [u, v] = endpoints(problem, a);\n adj[u].push([v, a]);\n adj[v].push([u, a]);\n }\n const pinned = new Uint8Array(arcs);\n const disc = new Int32Array(n).fill(-1);\n const low = new Int32Array(n);\n let time = 0;\n for (let start = 0; start < n; start += 1) {\n if (disc[start] !== -1) continue;\n const work: [number, number, number][] = [[start, -1, 0]];\n disc[start] = low[start] = time++;\n while (work.length) {\n const frame = work[work.length - 1];\n const [v, viaArc, i] = frame;\n if (i < adj[v].length) {\n frame[2] += 1;\n const [w, arc] = adj[v][i];\n if (arc === viaArc) continue;\n if (disc[w] === -1) {\n disc[w] = low[w] = time++;\n work.push([w, arc, 0]);\n } else {\n low[v] = Math.min(low[v], disc[w]);\n }\n } else {\n work.pop();\n if (work.length) {\n const up = work[work.length - 1][0];\n low[up] = Math.min(low[up], low[v]);\n if (low[v] > disc[up]) pinned[viaArc] = 1;\n }\n }\n }\n }\n return pinned;\n}\n\n/** What one audit found. `cells` lists the hidden cells that failed when\n * the cells themselves gave something away; empty when a set did. */\ninterface Findings {\n disclosures: Disclosure[];\n cells: number[];\n}\n\n/**\n * Every disclosure the shown totals allow, checking only the cells in\n * `check` one by one (the rest are known to be safe); null when the shown\n * totals contradict the cells. Sets are checked once no cell fails.\n */\nfunction audit(\n problem: AuditProblem,\n shown: readonly boolean[],\n eps: number,\n check: readonly number[],\n firstOnly = false,\n): Findings | null {\n if (problem.mode === 'free') {\n const pinned = freePinned(problem, shown);\n const disclosures: Disclosure[] = [];\n const cells: number[] = [];\n for (const c of check) {\n if (!pinned[problem.totals.length + c]) continue;\n if (firstOnly) return { disclosures: [{ allOf: [] }], cells: [c] };\n cells.push(c);\n disclosures.push({\n anyOf: problem.cellTotals[c].filter((t) => shown[t]),\n });\n }\n if (disclosures.length) return { disclosures, cells };\n const net = {\n closing: problem.totals.length + problem.cells.length,\n cellArc: (c: number) => problem.totals.length + c,\n };\n return {\n disclosures: determinedSets(problem, shown, net, pinned),\n cells: [],\n };\n }\n const net = feasibleNetwork(problem, shown, eps);\n if (!net) return null;\n const found = narrowCells(problem, shown, net, eps, check, firstOnly);\n if (found.disclosures.length) {\n return { disclosures: found.disclosures, cells: found.failed };\n }\n pinnedTotals(problem, shown, net, found.pinned, eps);\n return {\n disclosures: determinedSets(problem, shown, net, found.pinned),\n cells: [],\n };\n}\n\n/**\n * Totals that between them break every disclosure: all of each `allOf`,\n * then, for the `anyOf` ones still standing, a greedy cover (the total\n * breaking the most, then the one with the fewest records).\n */\nfunction pickTotals(\n problem: AuditProblem,\n disclosures: readonly Disclosure[],\n): number[] {\n const picked = new Set<number>();\n for (const d of disclosures) for (const t of d.allOf ?? []) picked.add(t);\n let remaining = disclosures.filter(\n (d) => d.anyOf && d.anyOf.length > 0 && !d.anyOf.some((t) => picked.has(t)),\n );\n while (remaining.length) {\n const cover = new Map<number, number>();\n for (const d of remaining) {\n for (const t of d.anyOf ?? []) cover.set(t, (cover.get(t) ?? 0) + 1);\n }\n let best = -1;\n for (const [t, n] of cover) {\n const b = cover.get(best) ?? -1;\n if (\n best === -1 ||\n n > b ||\n (n === b &&\n (problem.totals[t].records < problem.totals[best].records ||\n (problem.totals[t].records === problem.totals[best].records &&\n t < best)))\n ) {\n best = t;\n }\n }\n picked.add(best);\n remaining = remaining.filter((d) => !(d.anyOf ?? []).includes(best));\n }\n return [...picked].sort((a, b) => a - b);\n}\n\n/**\n * Which totals may be shown: true at index i when total i may be shown.\n * Starts from `total.shown` and only ever withholds more. `spentBefore`\n * carries the work of an earlier pass over the same data, so that passes\n * share one budget (see auditWorkSpent).\n */\nexport function secureTotals(\n problem: AuditProblem,\n spentBefore = 0,\n): boolean[] {\n work = spentBefore;\n try {\n return secure(problem);\n } catch (error) {\n if (error !== OUT_OF_WORK) throw error;\n const holdsHidden = new Uint8Array(problem.totals.length);\n for (const list of problem.cellTotals) {\n for (const t of list) holdsHidden[t] = 1;\n }\n return problem.totals.map((total, i) => total.shown && !holdsHidden[i]);\n }\n}\n\n/** The work the last secureTotals call ended on, for a following pass. */\nexport function auditWorkSpent(): number {\n return work;\n}\n\n/** The audit loop behind secureTotals. */\nfunction secure(problem: AuditProblem): boolean[] {\n const shown = problem.totals.map((total) => total.shown);\n if (problem.cells.length === 0) return shown;\n let scale = 1;\n for (const total of problem.totals) {\n if (total.shown) scale = Math.max(scale, Math.abs(total.value));\n }\n for (const cell of problem.cells) {\n if (Number.isFinite(cell.hi)) scale = Math.max(scale, Math.abs(cell.hi));\n }\n const eps = 1e-9 * scale;\n const holdsHidden = new Uint8Array(problem.totals.length);\n for (const list of problem.cellTotals)\n for (const t of list) holdsHidden[t] = 1;\n const everyHolder = () =>\n shown.map((isShown, i) => isShown && !holdsHidden[i]);\n\n const allCells = problem.cells.map((_, c) => c);\n // Withholding a total only removes an equation, so every interval can\n // only widen: a cell found safe stays safe, and each round rechecks only\n // the cells that failed the last one.\n let check: readonly number[] = allCells;\n const added: number[] = [];\n const maxRounds = problem.totals.length + 1;\n for (let round = 0; ; round += 1) {\n if (round > maxRounds) return everyHolder();\n const found = audit(problem, shown, eps, check);\n if (found === null) return everyHolder();\n if (found.disclosures.length === 0) break;\n const picked = pickTotals(problem, found.disclosures);\n // A disclosure no shown total can break: withhold everything.\n if (picked.length === 0) return everyHolder();\n for (const t of picked) {\n shown[t] = false;\n added.push(t);\n }\n check = found.cells;\n }\n // Offer each extra total back, the most records first: keep it shown if\n // nothing is given away with it. Showing a total adds an equation, so\n // every cell is checked again, those it holds first.\n const offers = [...added].sort(\n (a, b) => problem.totals[b].records - problem.totals[a].records || a - b,\n );\n for (const t of offers) {\n shown[t] = true;\n if (!offerBack(problem, shown, t, allCells, eps)) {\n shown[t] = false;\n }\n }\n return shown;\n}\n\n/** Whether total t can be shown again: no disclosure with it, and the\n * audit finished. Out of work, it stays withheld and the totals already\n * checked stand: they were safe before this offer. */\nfunction offerBack(\n problem: AuditProblem,\n shown: readonly boolean[],\n t: number,\n allCells: readonly number[],\n eps: number,\n): boolean {\n try {\n const near = new Set<number>();\n problem.cellTotals.forEach((list, c) => {\n if (list.includes(t)) near.add(c);\n });\n const order = [...near, ...allCells.filter((c) => !near.has(c))];\n const found = audit(problem, shown, eps, order, true);\n return found !== null && found.disclosures.length === 0;\n } catch (error) {\n if (error !== OUT_OF_WORK) throw error;\n return false;\n }\n}\n","/* -------------------------------------------------------------------- */\n/* Heatmap scale maths. Pure functions, no React, so they are tested on */\n/* their own (heatmap-scale.test.ts) and shared by the grid, the legend */\n/* and the table view. */\n/* */\n/* Every scale maps a value to one of ten colour steps, 0 to 9. The */\n/* steps are tokens (`--heatmap-<palette>-<step>`), so a scale never */\n/* produces a colour itself. */\n/* -------------------------------------------------------------------- */\n\nimport { isDevelopment } from '../_shared/is-development';\n\n/** Number of colour steps every palette carries. */\nexport const HEATMAP_STEPS = 10;\n\n/** The step a degenerate scale (every value equal) falls back to. */\nconst MIDDLE_STEP = Math.floor(HEATMAP_STEPS / 2);\n\n/** Highest step index. */\nconst TOP_STEP = HEATMAP_STEPS - 1;\n\n/** Steps on each side of a diverging midpoint. */\nconst HALF_STEPS = HEATMAP_STEPS / 2;\n\n/**\n * How values map to colour steps.\n *\n * - `sequential`: low to high. `domain: 'auto'` (the default) uses the min\n * and max of the cells that show a value; a fixed `[min, max]` clamps.\n * - `diverging`: two hues either side of `midpoint`. `auto` makes the\n * domain symmetric around the midpoint, so equal distances either side\n * get equal intensity. The midpoint defaults to 0, or to the centre of a\n * fixed domain that does not include 0.\n * - `quantile`: equal-count buckets (default 10) from the shown values.\n * Repeated values never split: buckets that would cut through a run of\n * equal values merge, so the minimum always takes the first step.\n * - `threshold`: ascending cut points; `n` thresholds make `n + 1`\n * buckets, spread across the ten steps. At most nine; duplicates merge.\n *\n * A fixed domain is `[min, max]`. A reversed pair is put in order, with a\n * warning in development builds.\n */\nexport type HeatmapScale =\n | { type: 'sequential'; domain?: 'auto' | readonly [number, number] }\n | {\n type: 'diverging';\n domain?: 'auto' | readonly [number, number];\n midpoint?: number;\n }\n | { type: 'quantile'; buckets?: number }\n | { type: 'threshold'; thresholds: readonly number[] };\n\n/** A scale with its domain worked out against the data. */\nexport interface ResolvedHeatmapScale {\n type: HeatmapScale['type'];\n /** Low end of the domain, or of the data for quantile and threshold. */\n min: number | null;\n /** High end of the domain, or of the data for quantile and threshold. */\n max: number | null;\n /** Diverging only: the value that separates the two hues. */\n midpoint?: number;\n /** Quantile and threshold: the ascending bucket edges. */\n thresholds: readonly number[];\n /** Maps a value to a step, 0 to 9. */\n stepOf: (value: number) => number;\n}\n\nconst clamp = (value: number, low: number, high: number): number =>\n Math.min(high, Math.max(low, value));\n\n/** Messages already given, so a scale worked out again (each data change,\n * twice in StrictMode) does not repeat them. */\nconst warned = new Set<string>();\n\n/** Says what a scale was given and what it uses instead, in development,\n * once per message. */\nfunction warn(message: string): void {\n if (!isDevelopment() || warned.has(message)) return;\n warned.add(message);\n console.warn(`Heatmap: ${message}`);\n}\n\n/** A fixed domain in ascending order (a reversed one is put in order). */\nfunction orderedDomain(\n domain: readonly [number, number],\n): readonly [number, number] {\n if (domain[0] <= domain[1]) return domain;\n warn(\n `scale domain [${domain[0]}, ${domain[1]}] is reversed; using [${domain[1]}, ${domain[0]}].`,\n );\n return [domain[1], domain[0]];\n}\n\n/** Sorted, distinct, finite values. */\nfunction distinctSorted(values: readonly number[]): number[] {\n const sorted = values.filter(Number.isFinite).sort((a, b) => a - b);\n return sorted.filter((value, i) => i === 0 || value !== sorted[i - 1]);\n}\n\n/** Min and max of the finite values, or null when there are none. */\nexport function extent(values: readonly number[]): [number, number] | null {\n let low = Infinity;\n let high = -Infinity;\n for (const value of values) {\n if (!Number.isFinite(value)) continue;\n if (value < low) low = value;\n if (value > high) high = value;\n }\n return low === Infinity ? null : [low, high];\n}\n\n/**\n * Sequential step: the domain is cut into ten equal bands. A value on a\n * band edge takes the band above; the top edge belongs to the top step.\n * Values outside the domain clamp to the end steps.\n */\nexport function sequentialStep(value: number, low: number, high: number) {\n if (!(high > low)) return MIDDLE_STEP;\n const t = clamp((value - low) / (high - low), 0, 1);\n return Math.min(TOP_STEP, Math.floor(t * HEATMAP_STEPS));\n}\n\n/**\n * Diverging step: steps 0 to 4 sit below the midpoint (0 is the furthest),\n * steps 5 to 9 above it (9 is the furthest). Ten steps have no middle one,\n * so a value exactly on the midpoint takes step 5, the palest step above.\n * It is painted in the neutral midpoint colour instead (see `onMidpoint`).\n */\nexport function divergingStep(\n value: number,\n low: number,\n midpoint: number,\n high: number,\n): number {\n if (value < midpoint) {\n const span = midpoint - low;\n const t = span > 0 ? clamp((midpoint - value) / span, 0, 1) : 1;\n return (\n HALF_STEPS - 1 - Math.min(HALF_STEPS - 1, Math.floor(t * HALF_STEPS))\n );\n }\n const span = high - midpoint;\n const t =\n span > 0\n ? clamp((value - midpoint) / span, 0, 1)\n : value > midpoint\n ? 1\n : 0;\n return HALF_STEPS + Math.min(HALF_STEPS - 1, Math.floor(t * HALF_STEPS));\n}\n\n/**\n * Whether a value sits exactly on a diverging scale's midpoint, so it is\n * painted neutral (`--heatmap-midpoint`) rather than in either hue. Exact\n * up to floating-point rounding, a few units in the last place of the\n * scale's largest magnitude: the centre of [0.1, 0.2] is computed as\n * 0.15000000000000002, and 0.1 + 0.2 - 0.3 is not quite 0. A value that\n * merely rounds to the midpoint when printed keeps its step. Other scale\n * types have no midpoint.\n */\nexport function onMidpoint(\n scale: ResolvedHeatmapScale,\n value: number,\n): boolean {\n if (scale.type !== 'diverging' || scale.midpoint === undefined) return false;\n const magnitude = Math.max(\n Math.abs(scale.midpoint),\n Math.abs(scale.min ?? 0),\n Math.abs(scale.max ?? 0),\n );\n return Math.abs(value - scale.midpoint) <= magnitude * Number.EPSILON * 16;\n}\n\n/**\n * Quantile of a sorted array at `p` (0 to 1), interpolating linearly\n * between neighbours (the R-7 method spreadsheets use).\n */\nexport function quantileSorted(sorted: readonly number[], p: number): number {\n const n = sorted.length;\n if (n === 0) return NaN;\n if (n === 1) return sorted[0];\n const position = clamp(p, 0, 1) * (n - 1);\n const below = Math.floor(position);\n const above = Math.min(n - 1, below + 1);\n return sorted[below] + (sorted[above] - sorted[below]) * (position - below);\n}\n\n/** The `buckets - 1` inner edges that cut sorted values into equal counts. */\nexport function quantileThresholds(\n sorted: readonly number[],\n buckets: number,\n): number[] {\n const count = Math.max(1, Math.round(buckets));\n const edges: number[] = [];\n for (let i = 1; i < count; i += 1) {\n edges.push(quantileSorted(sorted, i / count));\n }\n return edges;\n}\n\n/**\n * Quantile edges that cut something. Each raw edge moves up to the first\n * value at or above it, which puts every value in the same bucket but makes\n * the edge a value the data holds, so no bucket is left empty (an edge\n * between two values could cut a band nothing falls in). Then edges that\n * repeat go: when many values repeat (60% of cells at zero), several raw\n * edges land on the same value, and kept they would put the minimum\n * mid-scale. An edge at the minimum has nothing below it, so it goes too.\n */\nexport function usableQuantileEdges(\n sorted: readonly number[],\n buckets: number,\n): number[] {\n if (sorted.length === 0) return [];\n const min = sorted[0];\n const atOrAbove = (edge: number): number => {\n let low = 0;\n let high = sorted.length - 1;\n while (low < high) {\n const mid = (low + high) >>> 1;\n if (sorted[mid] < edge) low = mid + 1;\n else high = mid;\n }\n return sorted[low];\n };\n return distinctSorted(\n quantileThresholds(sorted, buckets).map(atOrAbove),\n ).filter((edge) => edge > min);\n}\n\n/** How many edges are at or below `value`: its bucket, 0 to edges.length. */\nexport function thresholdBucket(\n value: number,\n thresholds: readonly number[],\n): number {\n let low = 0;\n let high = thresholds.length;\n while (low < high) {\n const mid = (low + high) >>> 1;\n if (thresholds[mid] <= value) low = mid + 1;\n else high = mid;\n }\n return low;\n}\n\n/** Spreads bucket `bucket` of `bucketCount` evenly across the ten steps. */\nexport function bucketStep(bucket: number, bucketCount: number): number {\n if (bucketCount <= 1) return MIDDLE_STEP;\n return Math.round(\n (clamp(bucket, 0, bucketCount - 1) * TOP_STEP) / (bucketCount - 1),\n );\n}\n\n/**\n * Works out a scale against the values that will be shown. Pass only the\n * values of cells that render a colour: empty and low-sample cells must not\n * stretch the domain.\n */\nexport function resolveScale(\n scale: HeatmapScale,\n values: readonly number[],\n): ResolvedHeatmapScale {\n const range = extent(values);\n\n switch (scale.type) {\n case 'diverging': {\n const fixed =\n scale.domain && scale.domain !== 'auto'\n ? orderedDomain(scale.domain)\n : null;\n // Zero is the natural midpoint of a change, but only when the domain\n // reaches it: a fixed domain of [10, 50] would leave the lower hue\n // unused, so its centre divides it instead.\n const midpoint =\n scale.midpoint ??\n (fixed && (fixed[0] > 0 || fixed[1] < 0)\n ? (fixed[0] + fixed[1]) / 2\n : 0);\n let low: number;\n let high: number;\n if (fixed) {\n [low, high] = fixed;\n } else {\n const reach = range\n ? Math.max(\n Math.abs(range[0] - midpoint),\n Math.abs(range[1] - midpoint),\n )\n : 0;\n low = midpoint - reach;\n high = midpoint + reach;\n }\n return {\n type: 'diverging',\n min: low,\n max: high,\n midpoint,\n thresholds: [],\n stepOf: (value) => divergingStep(value, low, midpoint, high),\n };\n }\n case 'quantile': {\n const sorted = values\n .filter(Number.isFinite)\n .slice()\n .sort((a, b) => a - b);\n const buckets = clamp(\n Math.round(scale.buckets ?? HEATMAP_STEPS),\n 2,\n HEATMAP_STEPS,\n );\n // Every value equal leaves no edge: one bucket, on the middle step,\n // as a sequential scale does.\n const thresholds = usableQuantileEdges(sorted, buckets);\n return {\n type: 'quantile',\n min: range?.[0] ?? null,\n max: range?.[1] ?? null,\n thresholds,\n stepOf: (value) =>\n bucketStep(thresholdBucket(value, thresholds), thresholds.length + 1),\n };\n }\n case 'threshold': {\n const given = scale.thresholds.filter(Number.isFinite);\n const distinct = distinctSorted(given);\n if (distinct.length !== given.length) {\n warn('duplicate thresholds merged.');\n }\n if (distinct.length > TOP_STEP) {\n warn(\n `${distinct.length} thresholds given; ten steps take at most ${TOP_STEP}, so the highest ${distinct.length - TOP_STEP} are dropped.`,\n );\n }\n const thresholds = distinct.slice(0, TOP_STEP);\n return {\n type: 'threshold',\n min: range?.[0] ?? null,\n max: range?.[1] ?? null,\n thresholds,\n stepOf: (value) =>\n bucketStep(thresholdBucket(value, thresholds), thresholds.length + 1),\n };\n }\n case 'sequential':\n default: {\n const fixed =\n scale.domain && scale.domain !== 'auto'\n ? orderedDomain(scale.domain)\n : null;\n const low = fixed ? fixed[0] : (range?.[0] ?? null);\n const high = fixed ? fixed[1] : (range?.[1] ?? null);\n return {\n type: 'sequential',\n min: low,\n max: high,\n thresholds: [],\n stepOf: (value) =>\n low === null || high === null\n ? MIDDLE_STEP\n : sequentialStep(value, low, high),\n };\n }\n }\n}\n\n/* -------------------------------------------------------------------- */\n/* Aggregation for row, column and group totals. */\n/* -------------------------------------------------------------------- */\n\n/** How a margin combines its cells. */\nexport type HeatmapAggregate = 'sum' | 'mean';\n\n/** One cell as aggregation sees it. */\nexport interface AggregateInput {\n value: number | null;\n count?: number;\n}\n\n/** A combined value and the count behind it. */\nexport interface AggregateResult {\n value: number | null;\n /** Sum of the counts, when any cell carried one. */\n count?: number;\n}\n\n/** Sum of the values; empty cells are skipped. Null when nothing is left. */\nexport function sumOf(cells: readonly AggregateInput[]): AggregateResult {\n let total = 0;\n let seen = false;\n let count = 0;\n let counted = false;\n for (const cell of cells) {\n if (cell.value === null || !Number.isFinite(cell.value)) continue;\n total += cell.value;\n seen = true;\n if (cell.count !== undefined) {\n count += cell.count;\n counted = true;\n }\n }\n return { value: seen ? total : null, count: counted ? count : undefined };\n}\n\n/**\n * Mean weighted by count: sum(value x count) / sum(count). This is the only\n * correct way to combine rates (26% of 39 and 50% of 2 is 27%, not 38%).\n * A cell without a count weighs 1, so data with no counts at all gets a\n * plain mean. Cells with a count of 0 add nothing.\n */\nexport function weightedMean(\n cells: readonly AggregateInput[],\n): AggregateResult {\n let weighted = 0;\n let weights = 0;\n let count = 0;\n let counted = false;\n for (const cell of cells) {\n if (cell.value === null || !Number.isFinite(cell.value)) continue;\n const weight = cell.count ?? 1;\n weighted += cell.value * weight;\n weights += weight;\n if (cell.count !== undefined) {\n count += cell.count;\n counted = true;\n }\n }\n return {\n value: weights > 0 ? weighted / weights : null,\n count: counted ? count : undefined,\n };\n}\n\n/** Combines cells with the given method. */\nexport function aggregate(\n cells: readonly AggregateInput[],\n method: HeatmapAggregate,\n): AggregateResult {\n return method === 'sum' ? sumOf(cells) : weightedMean(cells);\n}\n","/* -------------------------------------------------------------------- */\n/* Heatmap data model. Pure functions that turn the consumer's rows, */\n/* columns and cells into the matrix the grid, the legend and the table */\n/* view read, plus the grouping, sorting and totals maths. */\n/* -------------------------------------------------------------------- */\n\nimport {\n auditWorkSpent,\n secureTotals,\n type AuditCell,\n type AuditTotal,\n type ProtectionMode,\n} from './heatmap-disclosure';\nimport {\n aggregate,\n type AggregateResult,\n type HeatmapAggregate,\n} from './heatmap-scale';\n\n/** One row of the heatmap. */\nexport interface HeatmapRow {\n /** Stable, opaque id. Emitted in DOM hooks, so never a name. */\n id: string;\n /** Visible label. Masked in privacy mode. */\n label: string;\n /**\n * Group id. Rows that share it are grouped when `groupRows` is on. Without\n * a matching entry in `groups` the id doubles as the visible label, so it\n * may be a name: privacy mode masks it, and DOM hooks and agent state\n * carry an index-based id (`group-1`, `group-2` in order of first\n * appearance), never this one.\n */\n group?: string;\n}\n\n/** One column of the heatmap. */\nexport interface HeatmapColumn {\n /**\n * Stable, opaque id. Emitted in DOM hooks (`data-heatmap-cell-id`) and in\n * agent state, so never a name.\n */\n id: string | number;\n /**\n * Visible label. Masked in privacy mode only with `privacyScope=\"all\"`:\n * columns are usually hours or days, which privacy mode keeps.\n */\n label: string;\n}\n\n/** A group's visible label, keyed by the id rows carry in `group`. */\nexport interface HeatmapGroup {\n /** Stable, opaque id. Emitted in DOM hooks and agent state, so never a name. */\n id: string;\n /**\n * Visible label. Masked in privacy mode only with `privacyScope=\"all\"`:\n * groups are usually practices or sites, which privacy mode keeps.\n */\n label: string;\n}\n\n/**\n * The id each group shows to DOM hooks and agents. A group listed in\n * `groups` keeps its own (opaque) id. One that is not has only its id for a\n * label, which may be a name, so it gets `group-<n>` by order of first\n * appearance instead.\n */\nexport function publicGroupIds(\n rows: readonly HeatmapRow[],\n groups: readonly HeatmapGroup[] | undefined,\n): Map<string, string> {\n const listed = new Set(groups?.map((group) => group.id));\n const taken = new Set(listed);\n const ids = new Map<string, string>();\n let n = 0;\n for (const row of rows) {\n const groupId = row.group;\n if (groupId === undefined || ids.has(groupId)) continue;\n if (listed.has(groupId)) {\n ids.set(groupId, groupId);\n continue;\n }\n let fallback: string;\n do {\n n += 1;\n fallback = `group-${n}`;\n } while (taken.has(fallback));\n taken.add(fallback);\n ids.set(groupId, fallback);\n }\n return ids;\n}\n\n/** The data behind one cell. */\nexport interface HeatmapCellData {\n /**\n * The value to colour. `null` means no data, or, with a `count` above 0 but\n * below `minCount`, a value withheld as too few to show.\n */\n value: number | null;\n /**\n * How many records the value rests on (the denominator of a rate). Weights\n * the mean totals and drives `minCount`.\n */\n count?: number;\n /**\n * Text shown and announced instead of the formatted value, for example\n * \"Closed\". Replaced by the formatted value in privacy mode.\n */\n label?: string;\n}\n\n/** What `getCell` or the `cells` matrix may hold for a cell. */\nexport type HeatmapCellInput = HeatmapCellData | number | null | undefined;\n\n/** How a cell renders: a coloured value, no data, or too few records. */\nexport type HeatmapCellStatus = 'value' | 'empty' | 'low-sample';\n\n/** Addresses one cell. */\nexport interface HeatmapCellKey {\n rowId: string;\n columnId: string | number;\n}\n\n/** Everything known about one cell, as passed to callbacks. */\nexport interface HeatmapCellInfo extends HeatmapCellKey {\n row: HeatmapRow;\n column: HeatmapColumn;\n /** Index into the `rows` prop. */\n rowIndex: number;\n /** Index into the `columns` prop. */\n columnIndex: number;\n value: number | null;\n count?: number;\n label?: string;\n status: HeatmapCellStatus;\n /**\n * Colour step, 0 to 9, when `status` is `'value'`; otherwise null. On a\n * diverging scale a value exactly on the midpoint keeps step 5 but is\n * painted in the neutral `--heatmap-midpoint` colour: compare `value`\n * with the midpoint to tell it from the palest step above.\n */\n step: number | null;\n}\n\n/** A cell after normalisation. */\nexport interface ModelCell {\n value: number | null;\n count?: number;\n label?: string;\n status: HeatmapCellStatus;\n /** A total withheld to protect hidden cells. Its status stays\n * `low-sample`, but it may rest on many records, so it is worded apart\n * from a cell that is too few to show. */\n withheld?: true;\n}\n\n/** How rows are ordered (within their group when grouped). */\nexport type HeatmapSortRows = 'none' | 'label' | 'total-asc' | 'total-desc';\n\n/** Whether a cell or total falls below the sample threshold. */\nexport function isLowSample(\n count: number | undefined,\n minCount: number | undefined,\n): boolean {\n return minCount !== undefined && count !== undefined && count < minCount;\n}\n\n/** Normalises one cell input. */\nexport function toModelCell(\n input: HeatmapCellInput,\n minCount: number | undefined,\n): ModelCell {\n if (input === null || input === undefined) {\n return { value: null, status: 'empty' };\n }\n const data: HeatmapCellData =\n typeof input === 'number' ? { value: input } : input;\n const value =\n data.value === null || !Number.isFinite(data.value) ? null : data.value;\n // A count below minCount is too few to show, with or without a value: a\n // host keeps a withheld value off the page by sending null and the count.\n // No records at all is still no data.\n const status: HeatmapCellStatus =\n isLowSample(data.count, minCount) &&\n (value !== null || (data.count ?? 0) > 0)\n ? 'low-sample'\n : value === null\n ? 'empty'\n : 'value';\n return { value, count: data.count, label: data.label, status };\n}\n\n/** Builds the `[row][column]` matrix in the order of the props. */\nexport function buildMatrix(\n rows: readonly HeatmapRow[],\n columns: readonly HeatmapColumn[],\n getCell:\n | ((\n row: HeatmapRow,\n column: HeatmapColumn,\n rowIndex: number,\n columnIndex: number,\n ) => HeatmapCellInput)\n | undefined,\n cells: readonly (readonly HeatmapCellInput[])[] | undefined,\n minCount: number | undefined,\n): ModelCell[][] {\n return rows.map((row, r) =>\n columns.map((column, c) =>\n toModelCell(\n getCell ? getCell(row, column, r, c) : cells?.[r]?.[c],\n minCount,\n ),\n ),\n );\n}\n\n/** The values that render a colour, for the scale's domain. */\nexport function shownValues(matrix: readonly ModelCell[][]): number[] {\n const values: number[] = [];\n for (const row of matrix) {\n for (const cell of row) {\n if (cell.status === 'value' && cell.value !== null)\n values.push(cell.value);\n }\n }\n return values;\n}\n\n/** Whether at least one cell carries data (a value or a low sample). */\nexport function hasAnyData(matrix: readonly ModelCell[][]): boolean {\n return matrix.some((row) => row.some((cell) => cell.status !== 'empty'));\n}\n\n/* -------------------------------------------------------------------- */\n/* Totals */\n/* -------------------------------------------------------------------- */\n\n/**\n * Which total `getTotal` is asked for, with the rows, columns and group it\n * covers. `method` is how the kit combines the cells for it: the\n * `rowTotals` method for a row, a group and the grand total, the\n * `columnTotals` method for a column, and the column method (else the row\n * method) for a group header cell.\n */\nexport type HeatmapTotalScope =\n | {\n /** A row's total, in the totals column. */\n kind: 'row';\n method: HeatmapAggregate;\n row: HeatmapRow;\n rowId: string;\n /** Index into the `rows` prop. */\n rowIndex: number;\n }\n | {\n /** A column's total, in the totals row. */\n kind: 'column';\n method: HeatmapAggregate;\n column: HeatmapColumn;\n columnId: string | number;\n /** Index into the `columns` prop. */\n columnIndex: number;\n }\n | {\n /** A group's total, in the totals column of its header row. */\n kind: 'group';\n method: HeatmapAggregate;\n /** The id the group's rows carry in `group`. */\n groupId: string;\n /** The group's entry in `groups`, when it has one. */\n group?: HeatmapGroup;\n /** The group's rows, in the order of the `rows` prop. */\n rows: readonly HeatmapRow[];\n rowIndexes: readonly number[];\n }\n | {\n /** One column's total within a group, in the group's header row. */\n kind: 'group-column';\n method: HeatmapAggregate;\n groupId: string;\n group?: HeatmapGroup;\n rows: readonly HeatmapRow[];\n rowIndexes: readonly number[];\n column: HeatmapColumn;\n columnId: string | number;\n columnIndex: number;\n }\n | {\n /** The grand total of every cell, in the corner. */\n kind: 'grand';\n method: HeatmapAggregate;\n };\n\n/** Returns a total, or undefined to let the kit work it out from the cells. */\nexport type HeatmapGetTotal = (\n scope: HeatmapTotalScope,\n) => HeatmapCellInput | undefined;\n\n/**\n * Every margin, ready to render. A withheld total is `{ value: null,\n * status: 'low-sample', withheld: true }`: no value and no count, so\n * nothing that reads it (the grid, the table view, a sort by total) can\n * pass one on.\n */\nexport interface HeatmapTotals {\n /** Per row index (props order), by the row method. */\n rows: ModelCell[];\n /** Per column index, by the column method. */\n columns: ModelCell[];\n /** Every cell, by the row method (it sits in the row-totals column). */\n grand: ModelCell;\n /** Per group id, whenever rows carry a group: one per column, by the\n * group column method. */\n groupColumns: Map<string, ModelCell[]>;\n /** Per group id, whenever rows carry a group: every cell in the group,\n * by the row method (it sits in the row-totals column). */\n groups: Map<string, ModelCell>;\n}\n\n/** Which totals the viewer sees: drawn, or, for rows, ordering the rows. */\nexport interface ShownTotals {\n rows: boolean;\n columns: boolean;\n grand: boolean;\n groups: boolean;\n groupColumns: boolean;\n}\n\nexport interface TotalsOptions {\n rowMethod: HeatmapAggregate;\n columnMethod: HeatmapAggregate;\n groupColumnMethod: HeatmapAggregate;\n groups?: readonly HeatmapGroup[];\n minCount?: number;\n getTotal?: HeatmapGetTotal;\n /** `rate` values are proportions of their count. Default `number`. */\n valueType?: 'number' | 'rate';\n /** Which totals the viewer sees. Default: every one. */\n shown?: ShownTotals;\n}\n\n/** A withheld total: no value, no count, no label. */\nconst WITHHELD_TOTAL: ModelCell = {\n value: null,\n status: 'low-sample',\n withheld: true,\n};\n\nconst ALL_SHOWN: ShownTotals = {\n rows: true,\n columns: true,\n grand: true,\n groups: true,\n groupColumns: true,\n};\n\n/** A total the kit works out, with the same status rules as a cell. */\nfunction computedTotal(\n cells: readonly ModelCell[],\n method: HeatmapAggregate,\n minCount: number | undefined,\n): ModelCell {\n const result: AggregateResult = aggregate(cells, method);\n return {\n value: result.value,\n count: result.count,\n status:\n result.value === null\n ? 'empty'\n : isLowSample(result.count, minCount)\n ? 'low-sample'\n : 'value',\n };\n}\n\n/** One total before the audit. Every scope is a block of rows by columns. */\ninterface Draft {\n method: HeatmapAggregate;\n rowIndexes: readonly number[];\n columnIndexes: readonly number[];\n own: ModelCell;\n /** Withheld whatever the audit says: too few on its own count, worked\n * out over a value the kit never had, or holding hidden cells with\n * fewer than minCount records between them. */\n primary: boolean;\n /** The viewer would see it. */\n visible: boolean;\n /** It holds a hidden cell. */\n holdsHidden: boolean;\n}\n\n/**\n * Works out every margin, then withholds whatever would let someone work\n * out a hidden cell (status `low-sample`), alone or with any combination\n * of the other totals shown, the shown cells and the known bounds. A total\n * in the row-totals column (a row's, a group's, the grand total) uses the\n * row method, so the column means one thing; a group's per-column totals\n * use the group column method. Low-sample cells count: their data is real,\n * only too thin to show on its own. `getTotal` may supply any total\n * instead; the same rule applies.\n *\n * Primary: a total under minCount on its own count, one the kit would work\n * out over a value it never had, and one whose hidden cells hold fewer\n * than minCount records. Secondary: the disclosure audit in\n * heatmap-disclosure.ts, over every total the viewer sees.\n */\nexport function computeTotals(\n matrix: readonly ModelCell[][],\n rows: readonly HeatmapRow[],\n columns: readonly HeatmapColumn[],\n options: TotalsOptions,\n): HeatmapTotals {\n const {\n rowMethod,\n columnMethod,\n groupColumnMethod,\n groups: groupList,\n minCount,\n getTotal,\n valueType = 'number',\n } = options;\n const shownKinds = options.shown ?? ALL_SHOWN;\n const allRows = rows.map((_, r) => r);\n const allColumns = columns.map((_, c) => c);\n\n const drafts: Draft[] = [];\n const draft = (\n supplied: HeatmapCellInput | undefined,\n method: HeatmapAggregate,\n rowIndexes: readonly number[],\n columnIndexes: readonly number[],\n visible: boolean,\n ): number => {\n const cells: ModelCell[] = [];\n for (const r of rowIndexes) {\n for (const c of columnIndexes) cells.push(matrix[r][c]);\n }\n let hidden = 0;\n let holdsHidden = false;\n let unknown = false;\n for (const cell of cells) {\n if (cell.status !== 'low-sample') continue;\n holdsHidden = true;\n hidden += cell.count ?? 0;\n if (cell.value === null) unknown = true;\n }\n const own =\n supplied === undefined\n ? computedTotal(cells, method, minCount)\n : toModelCell(supplied, minCount);\n const primary =\n own.status === 'low-sample' ||\n (supplied === undefined && unknown) ||\n (minCount !== undefined && hidden > 0 && hidden < minCount);\n drafts.push({\n method,\n rowIndexes,\n columnIndexes,\n own,\n primary,\n visible,\n holdsHidden,\n });\n return drafts.length - 1;\n };\n\n const rowDrafts = rows.map((row, r) =>\n draft(\n getTotal?.({\n kind: 'row',\n method: rowMethod,\n row,\n rowId: row.id,\n rowIndex: r,\n }),\n rowMethod,\n [r],\n allColumns,\n shownKinds.rows,\n ),\n );\n\n // Group members in props order. Groups are worked out (and audited)\n // whenever rows carry one, grouped on screen or not, so that turning\n // groupRows on or off shows two views of one safe set, not two sets.\n const members = new Map<string, number[]>();\n rows.forEach((row, r) => {\n if (row.group === undefined) return;\n const list = members.get(row.group) ?? [];\n list.push(r);\n members.set(row.group, list);\n });\n const groupEntries = new Map(groupList?.map((group) => [group.id, group]));\n const groupScope = (groupId: string, indexes: readonly number[]) => {\n const group = groupEntries.get(groupId);\n return {\n groupId,\n ...(group === undefined ? {} : { group }),\n rows: indexes.map((r) => rows[r]),\n rowIndexes: indexes,\n };\n };\n\n const groupColumnDrafts = new Map<string, number[]>();\n for (const [groupId, indexes] of members) {\n const scope = groupScope(groupId, indexes);\n groupColumnDrafts.set(\n groupId,\n columns.map((column, c) =>\n draft(\n getTotal?.({\n kind: 'group-column',\n method: groupColumnMethod,\n ...scope,\n column,\n columnId: column.id,\n columnIndex: c,\n }),\n groupColumnMethod,\n indexes,\n [c],\n shownKinds.groupColumns,\n ),\n ),\n );\n }\n\n const columnDrafts = columns.map((column, c) =>\n draft(\n getTotal?.({\n kind: 'column',\n method: columnMethod,\n column,\n columnId: column.id,\n columnIndex: c,\n }),\n columnMethod,\n allRows,\n [c],\n shownKinds.columns,\n ),\n );\n\n const groupDrafts = new Map<string, number>();\n for (const [groupId, indexes] of members) {\n groupDrafts.set(\n groupId,\n draft(\n getTotal?.({\n kind: 'group',\n method: rowMethod,\n ...groupScope(groupId, indexes),\n }),\n rowMethod,\n indexes,\n allColumns,\n shownKinds.groups,\n ),\n );\n }\n\n const grandDraft = draft(\n getTotal?.({ kind: 'grand', method: rowMethod }),\n rowMethod,\n allRows,\n allColumns,\n shownKinds.grand,\n );\n\n const withheld = drafts.map((d) => d.primary);\n const secured = secureDrafts({\n matrix,\n rows,\n drafts,\n rowDrafts,\n columnDrafts,\n groupDrafts,\n groupColumnDrafts,\n grandDraft,\n members,\n valueType,\n minCount,\n });\n secured.forEach((keep, i) => {\n if (!keep) withheld[i] = true;\n });\n\n const cellOf = (i: number) => (withheld[i] ? WITHHELD_TOTAL : drafts[i].own);\n return {\n rows: rowDrafts.map(cellOf),\n columns: columnDrafts.map(cellOf),\n grand: cellOf(grandDraft),\n groupColumns: new Map(\n [...groupColumnDrafts].map(([groupId, list]) => [\n groupId,\n list.map(cellOf),\n ]),\n ),\n groups: new Map(\n [...groupDrafts].map(([groupId, i]) => [groupId, cellOf(i)]),\n ),\n };\n}\n\ninterface SecureInput {\n matrix: readonly ModelCell[][];\n rows: readonly HeatmapRow[];\n drafts: readonly Draft[];\n rowDrafts: readonly number[];\n columnDrafts: readonly number[];\n groupDrafts: ReadonlyMap<string, number>;\n groupColumnDrafts: ReadonlyMap<string, readonly number[]>;\n grandDraft: number;\n members: ReadonlyMap<string, readonly number[]>;\n valueType: 'number' | 'rate';\n minCount: number | undefined;\n}\n\n/**\n * Builds the audit network (see heatmap-disclosure.ts) and returns, per\n * draft, whether it may stay shown. A draft that is not shown to begin\n * with comes back true: it is not the audit's to withhold.\n */\nfunction secureDrafts(input: SecureInput): boolean[] {\n const { matrix, rows, drafts, members, valueType, minCount } = input;\n const keep = drafts.map(() => true);\n if (minCount === undefined) return keep;\n const shownBefore = drafts.map(\n (d) => d.visible && !d.primary && d.own.value !== null,\n );\n\n // One unit for every equation: mixed methods, or a sum of rates, are\n // not audited; every shown total holding a hidden cell is withheld.\n const methods = new Set(\n drafts\n .filter((d, i) => shownBefore[i] && d.holdsHidden)\n .map((d) => d.method),\n );\n if (methods.size === 0) return keep;\n const withholdHolders = () =>\n drafts.map((d, i) => !(shownBefore[i] && d.holdsHidden));\n if (methods.size > 1) return withholdHolders();\n const method = [...methods][0];\n if (valueType === 'rate' && method === 'sum') return withholdHolders();\n\n // Weights: a count-weighted mean adds up value x count (count ?? 1); a\n // sum adds up values.\n const weightOf = (cell: ModelCell): number =>\n method === 'mean' ? (cell.count ?? 1) : 1;\n const rate = valueType === 'rate';\n\n // Averages of plain numbers weighted by count put each hidden cell on its\n // own scale (value x count moves in steps of its count, for any unit of\n // measure), which the flow audit cannot see: whoever knows the unit could\n // pin cells it passes. So they are not audited either.\n if (!rate && method === 'mean') return withholdHolders();\n const isUnknown = (cell: ModelCell): boolean =>\n cell.status === 'low-sample' && (method === 'sum' || (cell.count ?? 0) > 0);\n\n // Nodes: source, sink, grand; groups; rows; group header cells; columns.\n const SOURCE = 0;\n const SINK = 1;\n const GRAND = 2;\n let next = 3;\n const groupNode = new Map<string, number>();\n for (const groupId of members.keys()) groupNode.set(groupId, next++);\n const rowNode = rows.map(() => next++);\n const gcNode = new Map<string, number[]>();\n const columnCount = input.columnDrafts.length;\n for (const groupId of members.keys()) {\n gcNode.set(\n groupId,\n Array.from({ length: columnCount }, () => next++),\n );\n }\n const columnNode = input.columnDrafts.map(() => next++);\n const groupOf = (r: number): string | undefined => rows[r].group;\n\n // Arcs for every draft, in draft order.\n const arcOf: [number, number][] = drafts.map(() => [0, 0]);\n input.rowDrafts.forEach((d, r) => {\n const g = groupOf(r);\n arcOf[d] = [\n g === undefined ? GRAND : (groupNode.get(g) as number),\n rowNode[r],\n ];\n });\n for (const [groupId, d] of input.groupDrafts) {\n arcOf[d] = [GRAND, groupNode.get(groupId) as number];\n }\n for (const [groupId, list] of input.groupColumnDrafts) {\n list.forEach((d, c) => {\n arcOf[d] = [(gcNode.get(groupId) as number[])[c], columnNode[c]];\n });\n }\n input.columnDrafts.forEach((d, c) => {\n arcOf[d] = [columnNode[c], SINK];\n });\n arcOf[input.grandDraft] = [SOURCE, GRAND];\n\n // Hidden cells: the unknowns.\n const cells: AuditCell[] = [];\n const cellTotals: number[][] = [];\n // Whole numerators need whole counts behind the hidden cells.\n let integral = true;\n let nonNegative = true;\n matrix.forEach((cellsInRow, r) => {\n cellsInRow.forEach((cell, c) => {\n // Whether values can be negative is read from the data itself:\n // shown values, shown totals and any hidden value sent. A negative\n // hidden part of a total is then a contradiction (safe rule), never\n // a reason to drop the bounds.\n if (cell.value !== null && cell.value < 0) nonNegative = false;\n if (!isUnknown(cell)) return;\n if (!Number.isInteger(cell.count ?? 0)) integral = false;\n const g = groupOf(r);\n cells.push({\n from: rowNode[r],\n to: g === undefined ? columnNode[c] : (gcNode.get(g) as number[])[c],\n lo: 0,\n hi: valueType === 'rate' ? (cell.count ?? 0) : Infinity,\n records: cell.count ?? 0,\n });\n const holders = [\n input.rowDrafts[r],\n input.columnDrafts[c],\n input.grandDraft,\n ];\n if (g !== undefined) {\n holders.push(\n input.groupDrafts.get(g) as number,\n (input.groupColumnDrafts.get(g) as number[])[c],\n );\n }\n cellTotals.push(holders.sort((a, b) => a - b));\n });\n });\n if (cells.length === 0) return keep;\n\n // Two readers of a rate: the screen prints whole numerators (\"4 of 9\":\n // value x count, rounded), and an agent's read_cell gives a shown cell's\n // exact value. When every numerator is whole the two agree and one audit\n // does; when not, the totals are audited on the printed numerators, then\n // again on the exact ones. Each pass only withholds more.\n const nearWhole = (x: number) =>\n Math.abs(x - Math.round(x)) <= 1e-9 * Math.max(1, Math.abs(x));\n let wholeData = true;\n // The screen prints a total's numerator from its own count. A supplied\n // count that is not its cells' counts added up contradicts them.\n let countsDisagree = false;\n const printed = (cell: ModelCell, x: number) =>\n cell.count === undefined ? x : Math.round(x);\n const parts = drafts.map((d, i) => {\n let records = 0;\n let weight = 0;\n let exact = 0;\n let rounded = 0;\n let unknowns = 0;\n for (const r of d.rowIndexes) {\n for (const c of d.columnIndexes) {\n const cell = matrix[r][c];\n if (cell.status === 'empty') continue;\n weight += weightOf(cell);\n records += cell.count ?? 1;\n if (isUnknown(cell)) unknowns += 1;\n else if (cell.value !== null) {\n const part = weightOf(cell) * cell.value;\n if (!nearWhole(part)) wholeData = false;\n exact += part;\n rounded += printed(cell, part);\n }\n }\n }\n let whole = 0;\n let wholeRounded = 0;\n if (shownBefore[i] && unknowns > 0) {\n const total = d.own.value as number;\n whole = method === 'mean' ? total * weight : total;\n if (!nearWhole(whole)) wholeData = false;\n if (\n method === 'mean' &&\n d.own.count !== undefined &&\n Math.abs(d.own.count - weight) > 1e-9 * Math.max(1, weight)\n ) {\n countsDisagree = true;\n }\n wholeRounded = d.own.count === undefined ? whole : Math.round(whole);\n }\n return { records, exact, rounded, unknowns, whole, wholeRounded };\n });\n if (countsDisagree) return withholdHolders();\n\n drafts.forEach((d, i) => {\n if (shownBefore[i] && (d.own.value as number) < 0) nonNegative = false;\n });\n const mode: ProtectionMode =\n valueType === 'rate' ? 'rate' : nonNegative ? 'scaled' : 'free';\n const auditWith = (\n onPrinted: boolean,\n shown: readonly boolean[],\n spendFrom: number,\n ) => {\n const totals: AuditTotal[] = drafts.map((_, i) => {\n const part = parts[i];\n let value = 0;\n if (shown[i] && part.unknowns > 0) {\n value = onPrinted\n ? part.wholeRounded - part.rounded\n : part.whole - part.exact;\n // Floating-point rounding can leave a hair below zero; that is\n // zero. A real negative is a contradiction: the audit's bounds\n // then fail and it takes the safe rule.\n const tolerance =\n 1e-9 * Math.max(1, Math.abs(part.whole), Math.abs(part.exact));\n if (value < 0 && value > -tolerance) value = 0;\n }\n return {\n from: arcOf[i][0],\n to: arcOf[i][1],\n value,\n shown: shown[i],\n records: part.records,\n };\n });\n return secureTotals(\n {\n nodeCount: next,\n sink: SINK,\n source: SOURCE,\n cells,\n totals,\n cellTotals,\n mode,\n integral: rate && integral && (onPrinted || wholeData),\n minCount,\n },\n spendFrom,\n );\n };\n let result: boolean[];\n if (!rate || wholeData) {\n result = auditWith(rate, shownBefore, 0);\n } else {\n // One work budget across both passes.\n const first = auditWith(true, shownBefore, 0);\n result = auditWith(\n false,\n shownBefore.map((isShown, i) => isShown && first[i]),\n auditWorkSpent(),\n );\n }\n return drafts.map((_, i) => !shownBefore[i] || result[i]);\n}\n\n/* -------------------------------------------------------------------- */\n/* Body rows: grouping, sorting, collapse */\n/* -------------------------------------------------------------------- */\n\n/** A row the grid body renders. */\nexport type BodyRow =\n | {\n kind: 'group';\n /** Navigation key, unique among body rows. */\n key: string;\n groupId: string;\n collapsed: boolean;\n /** Row indexes (props order) in display order. */\n rowIndexes: number[];\n }\n | {\n kind: 'data';\n key: string;\n rowIndex: number;\n groupId?: string;\n };\n\nexport const dataRowKey = (rowId: string): string => `d:${rowId}`;\nexport const groupRowKey = (groupId: string): string => `g:${groupId}`;\nexport const FOOTER_ROW_KEY = 'f';\n\n/** Orders row indexes. Ties keep the props order (a stable sort). */\nexport function sortRowIndexes(\n indexes: readonly number[],\n rows: readonly HeatmapRow[],\n totals: readonly ModelCell[],\n sort: HeatmapSortRows,\n collator: Intl.Collator,\n): number[] {\n const list = [...indexes];\n if (sort === 'label') {\n return list.sort((a, b) => collator.compare(rows[a].label, rows[b].label));\n }\n if (sort === 'total-asc' || sort === 'total-desc') {\n const direction = sort === 'total-asc' ? 1 : -1;\n return list.sort((a, b) => {\n const left = totals[a]?.value;\n const right = totals[b]?.value;\n // Rows without a total sink to the end in both directions, so a\n // withheld total (no value) never places its row by its value.\n if (left === null || left === undefined) return right == null ? 0 : 1;\n if (right === null || right === undefined) return -1;\n return (left - right) * direction;\n });\n }\n return list;\n}\n\n/** Builds the body: group headers (when grouping) and data rows. */\nexport function buildBodyRows(\n rows: readonly HeatmapRow[],\n sortedIndexes: readonly number[],\n groupRows: boolean,\n collapsed: ReadonlySet<string>,\n): BodyRow[] {\n if (!groupRows) {\n return sortedIndexes.map((r) => ({\n kind: 'data',\n key: dataRowKey(rows[r].id),\n rowIndex: r,\n groupId: rows[r].group,\n }));\n }\n // Groups keep the order in which they first appear in the props, so a sort\n // reorders rows within a group but never moves the groups themselves.\n const order: string[] = [];\n const members = new Map<string, number[]>();\n const loose: number[] = [];\n rows.forEach((row) => {\n if (row.group !== undefined && !members.has(row.group)) {\n members.set(row.group, []);\n order.push(row.group);\n }\n });\n for (const r of sortedIndexes) {\n const groupId = rows[r].group;\n if (groupId === undefined) loose.push(r);\n else members.get(groupId)?.push(r);\n }\n const body: BodyRow[] = [];\n for (const groupId of order) {\n const rowIndexes = members.get(groupId) ?? [];\n const isCollapsed = collapsed.has(groupId);\n body.push({\n kind: 'group',\n key: groupRowKey(groupId),\n groupId,\n collapsed: isCollapsed,\n rowIndexes,\n });\n if (!isCollapsed) {\n for (const r of rowIndexes) {\n body.push({\n kind: 'data',\n key: dataRowKey(rows[r].id),\n rowIndex: r,\n groupId,\n });\n }\n }\n }\n // Rows without a group follow the groups, ungrouped.\n for (const r of loose) {\n body.push({ kind: 'data', key: dataRowKey(rows[r].id), rowIndex: r });\n }\n return body;\n}\n","import type { ReactElement } from 'react';\nimport { Tooltip } from '../tooltip';\nimport { useHeatmapContext } from './heatmap-context';\nimport type { HeatmapCellInfo } from './heatmap-model';\n\nexport interface HeatmapTooltipProps {\n /** The cell the tooltip describes. */\n cell: HeatmapCellInfo;\n /**\n * Tooltip text. Defaults to the Heatmap's `renderTooltip`, or to the\n * sentence every cell is named with (\"Tuesday, 10:00: 26%, 10 of 39\").\n * Plain text only: the kit Tooltip never carries interactive content.\n */\n label?: string;\n /** Controlled open state. */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** Logical side. Default `'top'`. */\n side?: 'top' | 'end' | 'bottom' | 'start';\n /** The trigger. */\n children: ReactElement;\n}\n\n/**\n * Heatmap.Tooltip: the kit Tooltip with a cell's description. The grid uses\n * it for the cell under the pointer or the keyboard focus; a consumer can\n * use it to describe a cell somewhere else, with the same wording and the\n * same privacy masking.\n */\nexport function HeatmapTooltip({\n cell,\n label,\n open,\n onOpenChange,\n side = 'top',\n children,\n}: HeatmapTooltipProps) {\n const context = useHeatmapContext();\n const text = label ?? context?.tooltipText(cell) ?? '';\n return (\n <Tooltip\n label={text}\n open={open}\n onOpenChange={onOpenChange}\n side={side}\n delayDuration={0}\n >\n {children}\n </Tooltip>\n );\n}\n\nHeatmapTooltip.displayName = 'HeatmapTooltip';\n\n/**\n * The anchor the grid hangs a cell's tooltip on: an inert box over the\n * cell, so the cell itself never re-mounts (and never drops focus) when the\n * tooltip moves to it. Takes the text, not a cell, so a group header cell\n * (which has no single row) gets one too.\n */\nexport function HeatmapCellTooltip({\n label,\n onOpenChange,\n}: {\n label: string;\n onOpenChange: (open: boolean) => void;\n}) {\n return (\n <Tooltip label={label} open onOpenChange={onOpenChange} delayDuration={0}>\n <span\n aria-hidden=\"true\"\n data-component=\"heatmap-tooltip\"\n className=\"ds:pointer-events-none ds:absolute ds:inset-0\"\n />\n </Tooltip>\n );\n}\n","/* -------------------------------------------------------------------- */\n/* Heatmap virtualisation. Above VIRTUALISE_CELL_THRESHOLD cells the */\n/* grid renders only the rows and columns in (and just around) the */\n/* viewport, plus the cell that holds the roving focus, so focus is */\n/* never dropped by a scroll. */\n/* */\n/* Every row and column has the same pitch in a virtualised grid, so the */\n/* window is plain arithmetic on the scroll offset; the skipped tracks */\n/* are kept by spacer elements that span them (no pixel offsets, so no */\n/* inline transforms). */\n/* -------------------------------------------------------------------- */\n\n/**\n * Cell count above which the grid virtualises. Measured in Chromium on a\n * production build (heatmap mdx, \"Performance\"): a full render took about\n * 10 ms at 840 cells and 14 ms (p95 18 ms) at 1,200, against the 16 ms\n * budget in src/docs/19-performance.mdx. Above 1,000 cells the window keeps\n * render and hover cost tied to the viewport, not to the data.\n */\nexport const VIRTUALISE_CELL_THRESHOLD = 1000;\n\n/** Rows or columns rendered beyond each edge of the viewport. */\nexport const OVERSCAN = 3;\n\n/** Inputs for one axis. All lengths in CSS pixels. */\nexport interface AxisMetrics {\n /** Scroll offset along the axis (absolute; RTL scrollLeft is negative). */\n offset: number;\n /** Visible length of the scroll container along the axis. */\n viewport: number;\n /** Space before the first item: the sticky header or row header. */\n lead: number;\n /** Item length plus the gap after it. */\n pitch: number;\n /** Number of items on the axis. */\n count: number;\n}\n\n/** Half-open range `[start, end)` of item indexes in view. */\nexport function visibleRange(\n { offset, viewport, lead, pitch, count }: AxisMetrics,\n overscan = OVERSCAN,\n): [number, number] {\n if (count <= 0) return [0, 0];\n if (!(pitch > 0)) return [0, count];\n const from = Math.abs(offset) - lead;\n const first = Math.floor(from / pitch) - overscan;\n const last = Math.ceil((from + viewport) / pitch) + overscan;\n const start = Math.max(0, Math.min(count - 1, first));\n const end = Math.max(start + 1, Math.min(count, last));\n return [start, end];\n}\n\n/** What an axis renders: item indexes and the spans of the gaps. */\nexport interface AxisWindow {\n /** Sorted item indexes to render. */\n indexes: number[];\n /** Items skipped before the first rendered one. */\n lead: number;\n /**\n * Items skipped between the pinned (focused) item and the visible range,\n * when the pinned item lies outside it. Zero otherwise.\n */\n middle: number;\n /** Where the middle gap sits: after this many rendered items. */\n middleAfter: number;\n /** Items skipped after the last rendered one. */\n tail: number;\n}\n\n/** Combines the visible range with the item that must stay rendered. */\nexport function axisWindow(\n range: [number, number],\n count: number,\n pinned: number | null,\n): AxisWindow {\n const [start, end] = range;\n const visible: number[] = [];\n for (let i = start; i < end; i += 1) visible.push(i);\n if (pinned === null || pinned < 0 || pinned >= count) {\n return {\n indexes: visible,\n lead: start,\n middle: 0,\n middleAfter: 0,\n tail: Math.max(0, count - end),\n };\n }\n if (pinned < start) {\n return {\n indexes: [pinned, ...visible],\n lead: pinned,\n middle: start - pinned - 1,\n middleAfter: 1,\n tail: Math.max(0, count - end),\n };\n }\n if (pinned >= end) {\n return {\n indexes: [...visible, pinned],\n lead: start,\n middle: pinned - end,\n middleAfter: visible.length,\n tail: count - pinned - 1,\n };\n }\n return {\n indexes: visible,\n lead: start,\n middle: 0,\n middleAfter: 0,\n tail: Math.max(0, count - end),\n };\n}\n\n/** A window that renders everything (the grid below the threshold). */\nexport function fullWindow(count: number): AxisWindow {\n return {\n indexes: Array.from({ length: count }, (_, i) => i),\n lead: 0,\n middle: 0,\n middleAfter: 0,\n tail: 0,\n };\n}\n\n/**\n * A window with every index at or past `count` dropped: what a window built\n * for more items renders in the one pass before it is worked out again.\n * Returns the same window when nothing is past the end.\n */\nexport function trimWindow(window: AxisWindow, count: number): AxisWindow {\n if (window.indexes.every((index) => index < count)) return window;\n const indexes = window.indexes.filter((index) => index < count);\n return {\n indexes,\n lead: Math.min(window.lead, count),\n middle: 0,\n middleAfter: 0,\n tail: Math.max(0, count - (indexes.length + Math.min(window.lead, count))),\n };\n}\n\n/** Whether two windows render the same items (skips a needless render). */\nexport function sameWindow(a: AxisWindow, b: AxisWindow): boolean {\n if (a.lead !== b.lead || a.tail !== b.tail || a.middle !== b.middle) {\n return false;\n }\n if (a.indexes.length !== b.indexes.length) return false;\n return a.indexes.every((value, i) => value === b.indexes[i]);\n}\n","/* -------------------------------------------------------------------- */\n/* Heatmap class recipes. Every colour is a token; every per-cell */\n/* colour is a CVA variant written out in full so Tailwind generates it. */\n/* -------------------------------------------------------------------- */\n\nimport { cva } from 'class-variance-authority';\n\n/** Palettes, each backed by ten `--heatmap-<palette>-<step>` tokens. */\nexport type HeatmapPalette =\n | 'primary'\n | 'success'\n | 'destructive'\n | 'diverging';\n\n/** One colour step of one palette, the neutral midpoint of a diverging\n * scale, or a cell with no colour of its own. */\nexport type HeatmapTone =\n | `${HeatmapPalette}-${0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}`\n | 'midpoint'\n | 'empty'\n | 'low-sample'\n | 'aggregate';\n\n/** The tone for a palette step. */\nexport const stepTone = (palette: HeatmapPalette, step: number): HeatmapTone =>\n `${palette}-${Math.min(9, Math.max(0, Math.round(step)))}` as HeatmapTone;\n\n/**\n * Background and ink for every tone. Shared by the cells and the legend\n * swatches, and written out in full so Tailwind generates every class.\n */\nconst toneClasses: Record<HeatmapTone, string> = {\n 'primary-0':\n 'ds:bg-[var(--heatmap-primary-0)] ds:text-[color:var(--heatmap-primary-0-foreground)]',\n 'primary-1':\n 'ds:bg-[var(--heatmap-primary-1)] ds:text-[color:var(--heatmap-primary-1-foreground)]',\n 'primary-2':\n 'ds:bg-[var(--heatmap-primary-2)] ds:text-[color:var(--heatmap-primary-2-foreground)]',\n 'primary-3':\n 'ds:bg-[var(--heatmap-primary-3)] ds:text-[color:var(--heatmap-primary-3-foreground)]',\n 'primary-4':\n 'ds:bg-[var(--heatmap-primary-4)] ds:text-[color:var(--heatmap-primary-4-foreground)]',\n 'primary-5':\n 'ds:bg-[var(--heatmap-primary-5)] ds:text-[color:var(--heatmap-primary-5-foreground)]',\n 'primary-6':\n 'ds:bg-[var(--heatmap-primary-6)] ds:text-[color:var(--heatmap-primary-6-foreground)]',\n 'primary-7':\n 'ds:bg-[var(--heatmap-primary-7)] ds:text-[color:var(--heatmap-primary-7-foreground)]',\n 'primary-8':\n 'ds:bg-[var(--heatmap-primary-8)] ds:text-[color:var(--heatmap-primary-8-foreground)]',\n 'primary-9':\n 'ds:bg-[var(--heatmap-primary-9)] ds:text-[color:var(--heatmap-primary-9-foreground)]',\n 'success-0':\n 'ds:bg-[var(--heatmap-success-0)] ds:text-[color:var(--heatmap-success-0-foreground)]',\n 'success-1':\n 'ds:bg-[var(--heatmap-success-1)] ds:text-[color:var(--heatmap-success-1-foreground)]',\n 'success-2':\n 'ds:bg-[var(--heatmap-success-2)] ds:text-[color:var(--heatmap-success-2-foreground)]',\n 'success-3':\n 'ds:bg-[var(--heatmap-success-3)] ds:text-[color:var(--heatmap-success-3-foreground)]',\n 'success-4':\n 'ds:bg-[var(--heatmap-success-4)] ds:text-[color:var(--heatmap-success-4-foreground)]',\n 'success-5':\n 'ds:bg-[var(--heatmap-success-5)] ds:text-[color:var(--heatmap-success-5-foreground)]',\n 'success-6':\n 'ds:bg-[var(--heatmap-success-6)] ds:text-[color:var(--heatmap-success-6-foreground)]',\n 'success-7':\n 'ds:bg-[var(--heatmap-success-7)] ds:text-[color:var(--heatmap-success-7-foreground)]',\n 'success-8':\n 'ds:bg-[var(--heatmap-success-8)] ds:text-[color:var(--heatmap-success-8-foreground)]',\n 'success-9':\n 'ds:bg-[var(--heatmap-success-9)] ds:text-[color:var(--heatmap-success-9-foreground)]',\n 'destructive-0':\n 'ds:bg-[var(--heatmap-destructive-0)] ds:text-[color:var(--heatmap-destructive-0-foreground)]',\n 'destructive-1':\n 'ds:bg-[var(--heatmap-destructive-1)] ds:text-[color:var(--heatmap-destructive-1-foreground)]',\n 'destructive-2':\n 'ds:bg-[var(--heatmap-destructive-2)] ds:text-[color:var(--heatmap-destructive-2-foreground)]',\n 'destructive-3':\n 'ds:bg-[var(--heatmap-destructive-3)] ds:text-[color:var(--heatmap-destructive-3-foreground)]',\n 'destructive-4':\n 'ds:bg-[var(--heatmap-destructive-4)] ds:text-[color:var(--heatmap-destructive-4-foreground)]',\n 'destructive-5':\n 'ds:bg-[var(--heatmap-destructive-5)] ds:text-[color:var(--heatmap-destructive-5-foreground)]',\n 'destructive-6':\n 'ds:bg-[var(--heatmap-destructive-6)] ds:text-[color:var(--heatmap-destructive-6-foreground)]',\n 'destructive-7':\n 'ds:bg-[var(--heatmap-destructive-7)] ds:text-[color:var(--heatmap-destructive-7-foreground)]',\n 'destructive-8':\n 'ds:bg-[var(--heatmap-destructive-8)] ds:text-[color:var(--heatmap-destructive-8-foreground)]',\n 'destructive-9':\n 'ds:bg-[var(--heatmap-destructive-9)] ds:text-[color:var(--heatmap-destructive-9-foreground)]',\n 'diverging-0':\n 'ds:bg-[var(--heatmap-diverging-0)] ds:text-[color:var(--heatmap-diverging-0-foreground)]',\n 'diverging-1':\n 'ds:bg-[var(--heatmap-diverging-1)] ds:text-[color:var(--heatmap-diverging-1-foreground)]',\n 'diverging-2':\n 'ds:bg-[var(--heatmap-diverging-2)] ds:text-[color:var(--heatmap-diverging-2-foreground)]',\n 'diverging-3':\n 'ds:bg-[var(--heatmap-diverging-3)] ds:text-[color:var(--heatmap-diverging-3-foreground)]',\n 'diverging-4':\n 'ds:bg-[var(--heatmap-diverging-4)] ds:text-[color:var(--heatmap-diverging-4-foreground)]',\n 'diverging-5':\n 'ds:bg-[var(--heatmap-diverging-5)] ds:text-[color:var(--heatmap-diverging-5-foreground)]',\n 'diverging-6':\n 'ds:bg-[var(--heatmap-diverging-6)] ds:text-[color:var(--heatmap-diverging-6-foreground)]',\n 'diverging-7':\n 'ds:bg-[var(--heatmap-diverging-7)] ds:text-[color:var(--heatmap-diverging-7-foreground)]',\n 'diverging-8':\n 'ds:bg-[var(--heatmap-diverging-8)] ds:text-[color:var(--heatmap-diverging-8-foreground)]',\n 'diverging-9':\n 'ds:bg-[var(--heatmap-diverging-9)] ds:text-[color:var(--heatmap-diverging-9-foreground)]',\n // A value exactly on a diverging scale's midpoint: neutral, so a cell\n // with no change never looks like one with a small change.\n midpoint:\n 'ds:bg-[var(--heatmap-midpoint)] ds:text-[color:var(--heatmap-midpoint-foreground)]',\n empty:\n 'ds:border ds:border-dashed ds:border-[color:var(--heatmap-empty-border)] ds:bg-[var(--heatmap-empty)] ds:text-[color:var(--heatmap-empty-foreground)]',\n 'low-sample':\n 'ds:border ds:border-[color:var(--heatmap-empty-border)] ds:bg-[var(--heatmap-low-sample-surface)] ds:bg-[image:var(--heatmap-low-sample)] ds:text-[color:var(--heatmap-empty-foreground)]',\n aggregate:\n 'ds:bg-[var(--muted)] ds:text-[color:var(--foreground)] ds:font-semibold',\n};\n\n/** Root: a column of legend bar, grid and live region. Never wider than\n * its container, so the page never scrolls sideways. */\nexport const heatmapRootVariants = cva(\n 'ds:flex ds:min-w-0 ds:max-w-full ds:flex-col ds:gap-[var(--spacing-sm)] ds:text-[color:var(--foreground)]',\n);\n\n/** The bar above the grid: legend at the start, view toggle at the end. */\nexport const heatmapToolbarVariants = cva(\n 'ds:flex ds:flex-wrap ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)]',\n);\n\n/** The scroll box. Only this box scrolls; sticky headers stick to it. */\nexport const heatmapScrollerVariants = cva(\n [\n 'ds:relative ds:max-w-full ds:overflow-auto ds:overscroll-contain',\n 'ds:max-h-[var(--heatmap-max-block-size)]',\n 'ds:bg-[var(--background)]',\n // Keep a cell scrolled into view clear of the sticky header, footer and\n // row-header column. The sizes are measured and set on this element.\n 'ds:scroll-pt-[var(--heatmap-sticky-block-start)] ds:scroll-pb-[var(--heatmap-sticky-block-end)] ds:scroll-ps-[var(--heatmap-sticky-inline-start)]',\n ].join(' '),\n);\n\n/**\n * The table view's box. `fit` lets the DataTable grow with its rows up to\n * the maximum; `capped` holds the maximum and the DataTable fills it,\n * scrolling inside.\n */\nexport const heatmapTableViewVariants = cva(\n // Focusable only to hold focus during a retry; not a control, so no ring.\n 'ds:min-w-0 ds:max-w-full ds:outline-none',\n {\n variants: {\n capped: {\n true: 'ds:flex ds:h-[var(--heatmap-max-block-size)] ds:flex-col',\n false: 'ds:block ds:max-h-[var(--heatmap-max-block-size)]',\n },\n },\n defaultVariants: { capped: false },\n },\n);\n\n/**\n * The grid. Columns come from `--heatmap-columns` (set on the scroll box);\n * rows share the column tracks through subgrid. Size sets the cell box,\n * density the gap, and a virtualised grid pins every track to one size so\n * the window arithmetic holds.\n */\nexport const heatmapGridVariants = cva(\n [\n 'ds:grid ds:w-max ds:min-w-full',\n 'ds:[grid-template-rows:auto] ds:auto-rows-[var(--heatmap-row-track)]',\n 'ds:gap-[var(--heatmap-gap)]',\n 'ds:outline-none',\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'ds:[--heatmap-cell-inline:var(--min-target-size)] ds:[--heatmap-cell-block:var(--min-target-size)]',\n md: 'ds:[--heatmap-cell-inline:max(var(--min-target-size),var(--spacing-2xl))] ds:[--heatmap-cell-block:var(--min-target-size)]',\n lg: 'ds:[--heatmap-cell-inline:max(var(--min-target-size),calc(var(--spacing-2xl)_+_var(--spacing-md)))] ds:[--heatmap-cell-block:max(var(--min-target-size),var(--spacing-2xl))]',\n },\n density: {\n default: 'ds:[--heatmap-gap:var(--spacing-2xs)]',\n compact: 'ds:[--heatmap-gap:var(--spacing-none)]',\n },\n virtualised: {\n true: 'ds:[--heatmap-track:var(--heatmap-cell-inline)] ds:[--heatmap-row-track:var(--heatmap-cell-block)]',\n false:\n 'ds:[--heatmap-track:minmax(var(--heatmap-cell-inline),1fr)] ds:[--heatmap-row-track:minmax(var(--heatmap-cell-block),auto)]',\n },\n totalsColumn: {\n true: 'ds:grid-cols-[max-content_repeat(var(--heatmap-columns),var(--heatmap-track))_max-content]',\n false:\n 'ds:grid-cols-[max-content_repeat(var(--heatmap-columns),var(--heatmap-track))]',\n },\n },\n defaultVariants: {\n size: 'md',\n density: 'default',\n virtualised: false,\n totalsColumn: false,\n },\n },\n);\n\n/** A row: spans every column and lines its cells up through subgrid. */\nexport const heatmapRowVariants = cva(\n 'ds:col-span-full ds:grid ds:grid-cols-subgrid',\n {\n variants: {\n position: {\n // The header and footer rows stick to the scroll box's block edges,\n // above the row headers that stick to its inline start.\n // Each also covers the row gap on its inner side, so cells\n // scrolling underneath never show through the gap.\n header:\n \"ds:sticky ds:top-0 ds:z-[calc(var(--z-sticky)+1)] ds:bg-[var(--background)] ds:after:pointer-events-none ds:after:absolute ds:after:inset-x-0 ds:after:top-[calc(100%_-_var(--spacing-2xs))] ds:after:h-[calc(var(--heatmap-gap)_+_var(--spacing-2xs))] ds:after:bg-[var(--background)] ds:after:content-['']\",\n footer:\n \"ds:sticky ds:bottom-0 ds:z-[calc(var(--z-sticky)+1)] ds:bg-[var(--background)] ds:after:pointer-events-none ds:after:absolute ds:after:inset-x-0 ds:after:bottom-[calc(100%_-_var(--spacing-2xs))] ds:after:h-[calc(var(--heatmap-gap)_+_var(--spacing-2xs))] ds:after:bg-[var(--background)] ds:after:content-['']\",\n body: '',\n },\n },\n defaultVariants: { position: 'body' },\n },\n);\n\n/** A spacer standing in for rows or columns the window skipped. */\nexport const heatmapSpacerVariants = cva('ds:pointer-events-none', {\n variants: {\n axis: {\n 'row-lead': 'ds:col-span-full ds:row-span-[var(--heatmap-row-lead)]',\n 'row-middle': 'ds:col-span-full ds:row-span-[var(--heatmap-row-middle)]',\n 'row-tail': 'ds:col-span-full ds:row-span-[var(--heatmap-row-tail)]',\n 'col-lead': 'ds:col-span-[var(--heatmap-col-lead)]',\n 'col-middle': 'ds:col-span-[var(--heatmap-col-middle)]',\n // Holds the skipped columns after the window, so the row-totals cell\n // lands in its own track at the end and never next to the window.\n 'col-tail': 'ds:col-span-[var(--heatmap-col-tail)]',\n },\n },\n});\n\nconst headerHighlight =\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none ds:data-[highlighted=true]:bg-[var(--muted)] ds:data-[highlighted=true]:text-[color:var(--foreground)]';\n\n/** Column header: the hour, day or other column label. */\nexport const heatmapColumnHeaderVariants = cva(\n [\n 'ds:flex ds:min-w-0 ds:items-end ds:justify-center ds:text-center',\n 'ds:rounded-[var(--radius-sm)] ds:px-[var(--spacing-2xs)] ds:py-[var(--spacing-xs)]',\n 'type-meta ds:text-[color:var(--muted-foreground)] ds:break-normal ds:[overflow-wrap:anywhere]',\n headerHighlight,\n ].join(' '),\n {\n variants: {\n corner: {\n // The top-start corner sticks with the row headers below it.\n true: 'ds:sticky ds:start-0 ds:z-[var(--z-sticky)] ds:items-end ds:justify-start ds:text-start ds:bg-[var(--background)] ds:pe-[var(--spacing-sm)]',\n false: '',\n },\n },\n defaultVariants: { corner: false },\n },\n);\n\n/** Row header: the row's label, sticky at the inline start. */\nexport const heatmapRowHeaderVariants = cva(\n [\n 'ds:sticky ds:start-0 ds:z-[var(--z-sticky)] ds:flex ds:min-w-0 ds:items-center',\n 'ds:max-w-[calc(var(--spacing-2xl)*4)] ds:gap-[var(--spacing-xs)]',\n 'ds:bg-[var(--background)] ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-sm)]',\n // Cover the gaps at the inline end and below too, so cells scrolling\n // underneath never show through between row headers.\n \"ds:after:pointer-events-none ds:after:absolute ds:after:top-0 ds:after:bottom-[calc(var(--heatmap-gap)*-1)] ds:after:start-full ds:after:w-[var(--heatmap-gap)] ds:after:bg-[var(--background)] ds:after:content-['']\",\n // The strip below overlaps its neighbours slightly so a fractional row\n // position never leaves a hairline seam.\n \"ds:before:pointer-events-none ds:before:absolute ds:before:inset-x-0 ds:before:top-[calc(100%_-_var(--spacing-2xs))] ds:before:h-[calc(var(--heatmap-gap)_+_var(--spacing-2xs)*2)] ds:before:bg-[var(--background)] ds:before:content-['']\",\n 'type-body-sm ds:text-start ds:break-normal ds:[overflow-wrap:anywhere]',\n headerHighlight,\n ].join(' '),\n {\n variants: {\n kind: {\n data: '',\n group: 'ds:font-semibold',\n total: 'ds:font-semibold',\n },\n // A virtualised grid needs every row the same height: no wrapping.\n // The label truncates inside its own span (heatmapRowLabelVariants):\n // overflow on the header itself would clip its gap-covering strips.\n virtualised: {\n true: 'ds:whitespace-nowrap',\n false: '',\n },\n },\n defaultVariants: { kind: 'data', virtualised: false },\n },\n);\n\n/** The label inside a row header. */\nexport const heatmapRowLabelVariants = cva('ds:min-w-0', {\n variants: {\n virtualised: {\n true: 'ds:overflow-hidden ds:text-ellipsis',\n false: '',\n },\n },\n defaultVariants: { virtualised: false },\n});\n\n/**\n * A cell. Colour comes from `tone`; selection, focus and hover come from\n * state attributes so a cell's classes only change when its data does.\n *\n * Focus: an inset ring in `--ring` over an inset band of the page colour,\n * so it reads on every step. Selection: a dark line framed by two light\n * ones, also inset, so it reads on every step too and is a shape, not a\n * colour. On a focused, selected cell the selection lines move inward by\n * `--focus-ring-width`, so the ring (3px in the accessible theme) never\n * covers them. Windows high contrast keeps the cell colours\n * (forced-color-adjust: none) and paints focus in the system Highlight\n * colour.\n */\nexport const heatmapCellVariants = cva(\n [\n 'ds:relative ds:flex ds:min-w-0 ds:items-center ds:justify-center',\n 'ds:min-h-[var(--heatmap-cell-block)] ds:overflow-hidden ds:px-[var(--spacing-2xs)]',\n 'type-meta ds:tabular-nums ds:whitespace-nowrap ds:select-none',\n 'ds:forced-colors:[forced-color-adjust:none]',\n 'ds:focus-visible:outline-solid ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-ring',\n 'ds:focus-visible:outline-offset-[calc(var(--focus-ring-width)*-1)]',\n 'ds:focus-visible:shadow-[inset_0_0_0_calc(var(--focus-ring-width)*2)_var(--background)]',\n 'ds:forced-colors:focus-visible:outline-[Highlight]',\n 'ds:aria-selected:shadow-[inset_0_0_0_var(--spacing-2xs)_var(--background),inset_0_0_0_calc(var(--spacing-2xs)*2)_var(--foreground),inset_0_0_0_calc(var(--spacing-2xs)*3)_var(--background)]',\n 'ds:aria-selected:focus-visible:shadow-[inset_0_0_0_calc(var(--focus-ring-width)_+_var(--spacing-2xs))_var(--background),inset_0_0_0_calc(var(--focus-ring-width)_+_var(--spacing-2xs)*2)_var(--foreground),inset_0_0_0_calc(var(--focus-ring-width)_+_var(--spacing-2xs)*3)_var(--background)]',\n ].join(' '),\n {\n variants: {\n tone: toneClasses,\n interactive: {\n true: 'ds:cursor-pointer',\n false: 'ds:cursor-default',\n },\n },\n defaultVariants: { tone: 'empty', interactive: false },\n },\n);\n\n/** Legend container. */\nexport const heatmapLegendVariants = cva(\n 'ds:flex ds:min-w-0 ds:flex-wrap ds:items-center ds:gap-x-[var(--spacing-md)] ds:gap-y-[var(--spacing-xs)] type-meta ds:text-[color:var(--muted-foreground)]',\n);\n\n/** The bar of colour steps in the legend. It shrinks with its container\n * rather than pushing the page wider. */\nexport const heatmapLegendBarVariants = cva(\n 'ds:flex ds:w-[calc(var(--spacing-xl)*6)] ds:min-w-0 ds:max-w-full ds:shrink ds:items-stretch',\n {\n variants: {\n variant: {\n stepped: 'ds:gap-[var(--spacing-2xs)]',\n continuous: 'ds:overflow-hidden ds:rounded-[var(--radius-sm)]',\n },\n },\n defaultVariants: { variant: 'stepped' },\n },\n);\n\n/** A legend swatch: a step in the bar, the key for an empty or low-sample\n * cell, or the diverging midpoint, which carries its value in its own ink.\n * Same tone classes as the cells. */\nexport const heatmapSwatchVariants = cva(\n 'ds:inline-block ds:forced-colors:[forced-color-adjust:none]',\n {\n variants: {\n tone: toneClasses,\n shape: {\n stepped:\n 'ds:h-[var(--spacing-sm)] ds:min-w-0 ds:flex-1 ds:rounded-[var(--radius-sm)]',\n continuous: 'ds:h-[var(--spacing-sm)] ds:min-w-0 ds:flex-1',\n key: 'ds:size-[var(--spacing-md)] ds:shrink-0 ds:rounded-[var(--radius-sm)]',\n label:\n 'ds:shrink-0 ds:rounded-[var(--radius-sm)] ds:px-[var(--spacing-xs)] ds:whitespace-nowrap',\n },\n },\n defaultVariants: { tone: 'empty', shape: 'key' },\n },\n);\n","import {\n memo,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n type PointerEvent,\n type MouseEvent,\n type ReactElement,\n} from 'react';\nimport { ChevronDown } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport type { HeatmapDescriber } from './heatmap-format';\nimport {\n FOOTER_ROW_KEY,\n type BodyRow,\n type HeatmapCellInfo,\n type HeatmapColumn,\n type HeatmapRow,\n type HeatmapTotals,\n type ModelCell,\n} from './heatmap-model';\nimport {\n onMidpoint,\n type HeatmapAggregate,\n type ResolvedHeatmapScale,\n} from './heatmap-scale';\nimport { HeatmapCellTooltip } from './heatmap-tooltip';\nimport {\n axisWindow,\n fullWindow,\n sameWindow,\n trimWindow,\n visibleRange,\n type AxisWindow,\n} from './heatmap-window';\nimport {\n heatmapCellVariants,\n heatmapColumnHeaderVariants,\n heatmapGridVariants,\n heatmapRowHeaderVariants,\n heatmapRowLabelVariants,\n heatmapRowVariants,\n heatmapScrollerVariants,\n heatmapSpacerVariants,\n stepTone,\n type HeatmapPalette,\n type HeatmapTone,\n} from './heatmap-variants';\n\n/** How the selection behaves. */\nexport type HeatmapSelectionMode = 'none' | 'single' | 'multiple' | 'range';\n\n/** A position in the navigable matrix: a body or footer row and a column\n * (the last column is the row-totals column when there is one). */\nexport interface GridPosition {\n rowKey: string;\n col: number;\n}\n\nconst KEY_SEPARATOR = '\\u001f';\n\n/** Internal selection key for a data cell: its row id and column id, never\n * its position, so a change to the columns cannot move it. */\nexport const selectionKey = (\n rowId: string,\n columnId: string | number,\n): string => `${rowId}${KEY_SEPARATOR}${String(columnId)}`;\n\n/** The row id and the column id (as a string) a selection key holds. */\nexport const splitSelectionKey = (key: string): [string, string] => {\n const at = key.indexOf(KEY_SEPARATOR);\n return [key.slice(0, at), key.slice(at + 1)];\n};\n\nexport interface HeatmapGridProps {\n title: string;\n rowsLabel?: string;\n rows: readonly HeatmapRow[];\n columns: readonly HeatmapColumn[];\n matrix: readonly ModelCell[][];\n body: readonly BodyRow[];\n scale: ResolvedHeatmapScale;\n palette: HeatmapPalette;\n describer: HeatmapDescriber;\n showValues: boolean;\n /** Every total, withheld ones already reduced to a value-less cell. */\n totals: HeatmapTotals | null;\n rowTotals: HeatmapAggregate | false;\n columnTotals: HeatmapAggregate | false;\n /** How a group header's per-column totals are worked out. */\n groupColumnMethod: HeatmapAggregate;\n /** Each group's public id: what DOM hooks carry, never a label. */\n groupIds: ReadonlyMap<string, string>;\n selectionMode: HeatmapSelectionMode;\n /** Selection keys (row id + column id) of the selected cells. */\n selected: ReadonlySet<string>;\n /** Column index for the column id a selection key holds. */\n columnIndexOfKey: (columnKey: string) => number | undefined;\n interactive: boolean;\n virtualised: boolean;\n size: 'sm' | 'md' | 'lg';\n density: 'compact' | 'default';\n cellInfo: (rowIndex: number, columnIndex: number) => HeatmapCellInfo;\n /** A data cell's tooltip text. */\n tooltipText: (cell: HeatmapCellInfo) => string;\n /** Describe the focused data cell with its tooltip text (a consumer's\n * renderTooltip says more than the cell's name). */\n describeFocused: boolean;\n /** A data cell was activated by click, Enter or Space. `select` is false\n * for a click that only reports the cell (a range press already chose). */\n onActivate: (rowIndex: number, columnIndex: number, select: boolean) => void;\n /** Range drag or Shift+arrows: select the rectangle anchor to target. */\n onRange: (\n anchor: { rowIndex: number; col: number },\n target: { rowIndex: number; col: number },\n ) => void;\n onToggleGroup: (groupId: string) => void;\n}\n\n/* -------------------------------------------------------------------- */\n/* Per-render context shared by every row (memoised in the grid) */\n/* -------------------------------------------------------------------- */\n\ninterface RowContext {\n rows: readonly HeatmapRow[];\n columns: readonly HeatmapColumn[];\n matrix: readonly ModelCell[][];\n scale: ResolvedHeatmapScale;\n palette: HeatmapPalette;\n describer: HeatmapDescriber;\n showValues: boolean;\n totals: HeatmapTotals | null;\n rowTotals: HeatmapAggregate | false;\n groupColumnMethod: HeatmapAggregate;\n groupIds: ReadonlyMap<string, string>;\n selectable: boolean;\n interactive: boolean;\n virtualised: boolean;\n colWindow: AxisWindow;\n /** Base for the ids that name group row headers. */\n idBase: string;\n /** The id of the focused cell's description, or undefined for none. */\n describedBy: string | undefined;\n cellInfo: (rowIndex: number, columnIndex: number) => HeatmapCellInfo;\n tooltipText: (cell: HeatmapCellInfo) => string;\n onTooltipOpenChange: (open: boolean) => void;\n onToggleGroup: (groupId: string) => void;\n expandLabel: (group: string) => string;\n collapseLabel: (group: string) => string;\n}\n\nfunction toneOf(\n cell: ModelCell,\n scale: ResolvedHeatmapScale,\n palette: HeatmapPalette,\n): HeatmapTone {\n if (cell.status === 'low-sample') return 'low-sample';\n if (cell.status === 'empty' || cell.value === null) return 'empty';\n if (onMidpoint(scale, cell.value)) return 'midpoint';\n return stepTone(palette, scale.stepOf(cell.value));\n}\n\n/** Stands in for a group total that was not worked out. */\nconst NO_TOTAL: ModelCell = { value: null, status: 'empty' };\n\nconst aggregateTone = (cell: ModelCell): HeatmapTone =>\n cell.status === 'value' ? 'aggregate' : cell.status;\n\n/** Renders the column window: spacers stand in for skipped columns, before,\n * between and after the rendered ones, so whatever follows (the row-totals\n * cell) always sits in its own track at the end. */\nfunction renderColumns(\n window: AxisWindow,\n render: (columnIndex: number) => ReactElement,\n): ReactElement[] {\n const out: ReactElement[] = [];\n if (window.lead > 0) {\n out.push(\n <div\n key=\"lead\"\n aria-hidden=\"true\"\n className={heatmapSpacerVariants({ axis: 'col-lead' })}\n />,\n );\n }\n window.indexes.forEach((columnIndex, i) => {\n if (window.middle > 0 && i === window.middleAfter) {\n out.push(\n <div\n key=\"middle\"\n aria-hidden=\"true\"\n className={heatmapSpacerVariants({ axis: 'col-middle' })}\n />,\n );\n }\n out.push(render(columnIndex));\n });\n if (window.tail > 0) {\n out.push(\n <div\n key=\"tail\"\n aria-hidden=\"true\"\n className={heatmapSpacerVariants({ axis: 'col-tail' })}\n />,\n );\n }\n return out;\n}\n\ninterface BodyRowProps {\n ctx: RowContext;\n row: BodyRow;\n /** 1-based aria-rowindex. */\n ariaRowIndex: number;\n highlighted: boolean;\n /** Column holding the roving tabindex in this row, or -1. */\n activeCol: number;\n /** Column hosting the tooltip in this row, or -1. */\n tooltipCol: number;\n /** Selected column indexes, comma-joined (a string so memo compares by value). */\n selectedCols: string;\n}\n\n/** One body row: a data row or a group header. Memoised, so hover and\n * focus only re-render the rows they touch. */\nconst HeatmapBodyRow = memo(function HeatmapBodyRow({\n ctx,\n row,\n ariaRowIndex,\n highlighted,\n activeCol,\n tooltipCol,\n selectedCols,\n}: BodyRowProps) {\n const columnCount = ctx.columns.length;\n const selected = useMemo(\n () =>\n new Set(selectedCols === '' ? [] : selectedCols.split(',').map(Number)),\n [selectedCols],\n );\n\n if (row.kind === 'group') {\n const groupText = ctx.describer.groupLabel(row.groupId);\n // The public id: the group's own when `groups` lists it, else an\n // index-based one, because an unlisted id doubles as the label.\n const hookId = ctx.groupIds.get(row.groupId);\n const labelId = `${ctx.idBase}-label-${ariaRowIndex}`;\n const perColumn = ctx.totals?.groupColumns.get(row.groupId) ?? [];\n const overall = ctx.totals?.groups.get(row.groupId);\n /** A group's cell. Its value always prints, as a row total's does: the\n * group row is a margin, not a colour scale. */\n const groupCell = (\n total: ModelCell | undefined,\n c: number,\n label: (cell: ModelCell) => string,\n withTooltip: boolean,\n ) => {\n const cell = total ?? NO_TOTAL;\n const name = label(cell);\n return (\n <div\n key={c}\n role=\"gridcell\"\n aria-colindex={c + 2}\n aria-expanded={!row.collapsed}\n aria-label={name}\n tabIndex={activeCol === c ? 0 : -1}\n data-heatmap-group-id={hookId}\n className={heatmapCellVariants({\n tone: aggregateTone(cell),\n interactive: true,\n })}\n >\n {ctx.describer.visibleText(cell)}\n {withTooltip && tooltipCol === c ? (\n <HeatmapCellTooltip\n label={name}\n onOpenChange={ctx.onTooltipOpenChange}\n />\n ) : null}\n </div>\n );\n };\n const perColumnRowText = ctx.describer.groupRowText(\n groupText,\n ctx.groupColumnMethod,\n );\n return (\n <div\n role=\"row\"\n aria-rowindex={ariaRowIndex}\n data-heatmap-body-row=\"\"\n data-heatmap-group-id={hookId}\n className={heatmapRowVariants({ position: 'body' })}\n >\n <div\n role=\"rowheader\"\n aria-colindex={1}\n // Named by the label alone: the button's own name (\"Collapse …\")\n // would otherwise be read with it, saying the group twice.\n aria-labelledby={labelId}\n data-highlighted={highlighted}\n className={heatmapRowHeaderVariants({\n kind: 'group',\n virtualised: ctx.virtualised,\n })}\n >\n {/*\n * Out of the tab order (tabIndex -1), and it never takes focus on\n * a press: the grid is one tab stop, and every cell of the group\n * row toggles the group with Enter, Space or a click, so the\n * button is a pointer shortcut. Its 24px box meets WCAG 2.5.8\n * (AA). The kit's own 44px target (2.5.5, 48px accessible) is met\n * through the equivalent-control exception: those cells are the\n * same control at full size.\n */}\n <button\n type=\"button\"\n tabIndex={-1}\n aria-expanded={!row.collapsed}\n aria-label={\n row.collapsed\n ? ctx.expandLabel(groupText)\n : ctx.collapseLabel(groupText)\n }\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => ctx.onToggleGroup(row.groupId)}\n className=\"ds:inline-flex ds:size-[var(--spacing-lg)] ds:shrink-0 ds:cursor-pointer ds:items-center ds:justify-center ds:rounded-[var(--radius-sm)] ds:bg-transparent ds:text-[color:inherit] ds:hover:bg-[var(--muted)] ds:focus-visible:outline-solid ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-ring ds:forced-colors:focus-visible:outline-[Highlight]\"\n >\n <ChevronDown\n aria-hidden=\"true\"\n className={[\n 'ds:size-4 ds:transition-transform ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n row.collapsed ? 'ds:-rotate-90 ds:rtl:rotate-90' : '',\n ].join(' ')}\n />\n </button>\n <span\n id={labelId}\n className={heatmapRowLabelVariants({\n virtualised: ctx.virtualised,\n })}\n >\n {groupText}\n </span>\n </div>\n {renderColumns(ctx.colWindow, (c) =>\n groupCell(\n perColumn[c],\n c,\n (cell) =>\n ctx.describer.sentence(\n perColumnRowText,\n ctx.describer.columnLabel(ctx.columns[c]),\n cell,\n ),\n true,\n ),\n )}\n {ctx.rowTotals\n ? groupCell(\n overall,\n columnCount,\n (cell) =>\n ctx.describer.sentence(\n groupText,\n ctx.describer.methodLabel(ctx.rowTotals || 'mean'),\n cell,\n ),\n false,\n )\n : null}\n </div>\n );\n }\n\n const r = row.rowIndex;\n const source = ctx.rows[r];\n const rowText = ctx.describer.rowLabel(source);\n const cells = ctx.matrix[r];\n\n const dataCell = (c: number) => {\n const cell = cells[c];\n const column = ctx.columns[c];\n const isSelected = selected.has(c);\n return (\n <div\n key={c}\n role=\"gridcell\"\n aria-colindex={c + 2}\n aria-label={ctx.describer.sentence(\n rowText,\n ctx.describer.columnLabel(column),\n cell,\n )}\n aria-describedby={activeCol === c ? ctx.describedBy : undefined}\n aria-selected={ctx.selectable ? isSelected : undefined}\n tabIndex={activeCol === c ? 0 : -1}\n data-heatmap-cell-id={`${source.id}:${String(column.id)}`}\n data-status={cell.status}\n className={heatmapCellVariants({\n tone: toneOf(cell, ctx.scale, ctx.palette),\n interactive: ctx.interactive,\n })}\n >\n {ctx.showValues || cell.status === 'empty'\n ? ctx.describer.visibleText(cell)\n : null}\n {tooltipCol === c ? (\n <HeatmapCellTooltip\n label={ctx.tooltipText(ctx.cellInfo(r, c))}\n onOpenChange={ctx.onTooltipOpenChange}\n />\n ) : null}\n </div>\n );\n };\n\n let totalCell: ReactElement | null = null;\n if (ctx.rowTotals && ctx.totals) {\n const cell = ctx.totals.rows[r];\n totalCell = (\n <div\n role=\"gridcell\"\n aria-colindex={columnCount + 2}\n aria-label={ctx.describer.sentence(\n rowText,\n ctx.describer.methodLabel(ctx.rowTotals),\n cell,\n )}\n tabIndex={activeCol === columnCount ? 0 : -1}\n className={heatmapCellVariants({ tone: aggregateTone(cell) })}\n >\n {ctx.describer.visibleText(cell)}\n </div>\n );\n }\n\n return (\n <div\n role=\"row\"\n aria-rowindex={ariaRowIndex}\n data-heatmap-body-row=\"\"\n data-heatmap-row-id={source.id}\n className={heatmapRowVariants({ position: 'body' })}\n >\n <div\n role=\"rowheader\"\n aria-colindex={1}\n data-highlighted={highlighted}\n className={heatmapRowHeaderVariants({\n kind: 'data',\n virtualised: ctx.virtualised,\n })}\n >\n <span\n className={heatmapRowLabelVariants({ virtualised: ctx.virtualised })}\n >\n {rowText}\n </span>\n </div>\n {renderColumns(ctx.colWindow, dataCell)}\n {totalCell}\n </div>\n );\n});\n\n/* -------------------------------------------------------------------- */\n/* Grid */\n/* -------------------------------------------------------------------- */\n\ninterface Metrics {\n headerBlock: number;\n footerBlock: number;\n rowPitch: number;\n leadInline: number;\n colPitch: number;\n viewportBlock: number;\n viewportInline: number;\n}\n\nconst DEFAULT_METRICS: Metrics = {\n headerBlock: 48,\n footerBlock: 0,\n rowPitch: 46,\n leadInline: 120,\n colPitch: 46,\n viewportBlock: 600,\n viewportInline: 900,\n};\n\nconst pageRows = (metrics: Metrics): number =>\n Math.max(\n 1,\n Math.floor(\n (metrics.viewportBlock - metrics.headerBlock - metrics.footerBlock) /\n Math.max(1, metrics.rowPitch),\n ),\n );\n\nexport function HeatmapGrid(props: HeatmapGridProps) {\n const {\n title,\n rowsLabel,\n rows,\n columns,\n matrix,\n body,\n scale,\n palette,\n describer,\n showValues,\n totals,\n rowTotals,\n columnTotals,\n groupColumnMethod,\n groupIds,\n selectionMode,\n selected,\n columnIndexOfKey,\n interactive,\n virtualised,\n size,\n density,\n cellInfo,\n tooltipText,\n describeFocused,\n onActivate,\n onRange,\n onToggleGroup,\n } = props;\n const { t } = useTranslation('ui');\n const idBase = useId();\n const scrollerRef = useRef<HTMLDivElement>(null);\n const gridRef = useRef<HTMLDivElement>(null);\n const headerRef = useRef<HTMLDivElement>(null);\n const footerRef = useRef<HTMLDivElement>(null);\n\n const columnCount = columns.length;\n const navColumnCount = columnCount + (rowTotals ? 1 : 0);\n const hasFooter = Boolean(columnTotals && totals);\n const navRowKeys = useMemo(\n () => [\n ...body.map((row) => row.key),\n ...(hasFooter ? [FOOTER_ROW_KEY] : []),\n ],\n [body, hasFooter],\n );\n const rowIndexOfKey = useMemo(() => {\n const map = new Map<string, number>();\n navRowKeys.forEach((key, i) => map.set(key, i));\n return map;\n }, [navRowKeys]);\n\n /* ---- roving focus -------------------------------------------------- */\n const [active, setActive] = useState<GridPosition>(() => ({\n rowKey: navRowKeys[0] ?? FOOTER_ROW_KEY,\n col: 0,\n }));\n // If the active row disappears (a group collapsed, rows changed), fall\n // back to its group header, else the first row.\n const activeRow = (() => {\n const found = rowIndexOfKey.get(active.rowKey);\n if (found !== undefined) return found;\n const hidden = rows.find((row) => `d:${row.id}` === active.rowKey);\n const header =\n hidden?.group === undefined\n ? undefined\n : rowIndexOfKey.get(`g:${hidden.group}`);\n return header ?? 0;\n })();\n const activeCol = Math.min(\n Math.max(0, active.col),\n Math.max(0, navColumnCount - 1),\n );\n const activeKey = navRowKeys[activeRow];\n\n const pendingFocus = useRef(false);\n const [hasFocus, setHasFocus] = useState(false);\n const hasFocusRef = useRef(false);\n const interaction = useRef<'keyboard' | 'pointer'>('pointer');\n\n /* ---- hover and tooltip --------------------------------------------- */\n const [hover, setHover] = useState<GridPosition | null>(null);\n const hoverRef = useRef<GridPosition | null>(null);\n const [tooltipDismissed, setTooltipDismissed] = useState(false);\n const updateHover = useCallback((next: GridPosition | null) => {\n const current = hoverRef.current;\n if (\n current === next ||\n (current &&\n next &&\n current.rowKey === next.rowKey &&\n current.col === next.col)\n ) {\n return;\n }\n hoverRef.current = next;\n setHover(next);\n setTooltipDismissed(false);\n }, []);\n\n /** The cell whose headers light up: the hovered one, else the focused one. */\n const highlight: GridPosition | null =\n hover ??\n (hasFocus && activeKey ? { rowKey: activeKey, col: activeCol } : null);\n /** The cell that shows the tooltip: hovered, or focused from the keyboard. */\n const tooltipAt: GridPosition | null = tooltipDismissed\n ? null\n : (hover ??\n (hasFocus && interaction.current === 'keyboard' && activeKey\n ? { rowKey: activeKey, col: activeCol }\n : null));\n\n /* ---- measurement and the virtual window ---------------------------- */\n const [metrics, setMetrics] = useState<Metrics>(DEFAULT_METRICS);\n const metricsRef = useRef(metrics);\n metricsRef.current = metrics;\n\n const measure = useCallback(() => {\n const scroller = scrollerRef.current;\n const grid = gridRef.current;\n if (!scroller || !grid) return;\n const style = window.getComputedStyle(grid);\n const rowGap = parseFloat(style.rowGap) || 0;\n const columnGap = parseFloat(style.columnGap) || 0;\n const tracks = style.gridTemplateColumns\n .split(' ')\n .map((track) => parseFloat(track))\n .filter((track) => Number.isFinite(track));\n const headerHeight = headerRef.current?.getBoundingClientRect().height ?? 0;\n const firstBody = grid.querySelector<HTMLElement>(\n '[data-heatmap-body-row]',\n );\n const bodyHeight = firstBody?.getBoundingClientRect().height ?? 0;\n const next: Metrics = {\n headerBlock: headerHeight + rowGap,\n footerBlock: footerRef.current?.getBoundingClientRect().height ?? 0,\n rowPitch:\n (bodyHeight || headerHeight || DEFAULT_METRICS.rowPitch) + rowGap,\n leadInline: (tracks[0] ?? 0) + columnGap,\n colPitch: (tracks[1] ?? DEFAULT_METRICS.colPitch) + columnGap,\n viewportBlock: scroller.clientHeight,\n viewportInline: scroller.clientWidth,\n };\n const current = metricsRef.current;\n if (\n (Object.keys(next) as (keyof Metrics)[]).some(\n (key) => Math.abs(next[key] - current[key]) > 0.5,\n )\n ) {\n setMetrics(next);\n }\n }, []);\n\n useIsomorphicLayoutEffect(() => {\n measure();\n const scroller = scrollerRef.current;\n if (!scroller || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(() => measure());\n observer.observe(scroller);\n if (gridRef.current) observer.observe(gridRef.current);\n return () => observer.disconnect();\n }, [measure, body.length, columnCount, size, density]);\n\n const pinnedRow = activeKey === FOOTER_ROW_KEY ? null : activeRow;\n const pinnedCol = activeCol < columnCount ? activeCol : null;\n\n const computeWindows = useCallback((): {\n rows: AxisWindow;\n cols: AxisWindow;\n } => {\n if (!virtualised) {\n return { rows: fullWindow(body.length), cols: fullWindow(columnCount) };\n }\n const scroller = scrollerRef.current;\n const m = metricsRef.current;\n const rowRange = visibleRange({\n offset: scroller?.scrollTop ?? 0,\n viewport: m.viewportBlock,\n lead: m.headerBlock,\n pitch: m.rowPitch,\n count: body.length,\n });\n const colRange = visibleRange({\n offset: scroller?.scrollLeft ?? 0,\n viewport: m.viewportInline,\n lead: m.leadInline,\n pitch: m.colPitch,\n count: columnCount,\n });\n return {\n rows: axisWindow(rowRange, body.length, pinnedRow),\n cols: axisWindow(colRange, columnCount, pinnedCol),\n };\n }, [virtualised, body.length, columnCount, pinnedRow, pinnedCol]);\n\n const [windowState, setWindows] = useState(computeWindows);\n // Below the threshold every row and column renders, worked out here so a\n // change to the data never meets a window built for the old data. Above\n // it, the window is trimmed to the data until the layout effect below\n // re-syncs it (before paint).\n const fullRows = useMemo(() => fullWindow(body.length), [body.length]);\n const fullCols = useMemo(() => fullWindow(columnCount), [columnCount]);\n const windows = useMemo(\n () =>\n virtualised\n ? {\n rows: trimWindow(windowState.rows, body.length),\n cols: trimWindow(windowState.cols, columnCount),\n }\n : { rows: fullRows, cols: fullCols },\n [virtualised, windowState, body.length, columnCount, fullRows, fullCols],\n );\n const syncWindows = useCallback(() => {\n const next = computeWindows();\n setWindows((current) =>\n sameWindow(current.rows, next.rows) && sameWindow(current.cols, next.cols)\n ? current\n : next,\n );\n }, [computeWindows]);\n useIsomorphicLayoutEffect(() => {\n syncWindows();\n }, [syncWindows, metrics]);\n\n const frame = useRef(0);\n const onScroll = useCallback(() => {\n if (!virtualised || frame.current) return;\n frame.current = window.requestAnimationFrame(() => {\n frame.current = 0;\n syncWindows();\n });\n }, [virtualised, syncWindows]);\n useEffect(() => () => window.cancelAnimationFrame(frame.current), []);\n\n /* ---- focus follows the roving position ----------------------------- */\n // The active row went away (its group collapsed, rows changed): settle the\n // roving position on the row that took its place.\n useIsomorphicLayoutEffect(() => {\n if (activeKey !== undefined && activeKey !== active.rowKey) {\n setActive({ rowKey: activeKey, col: activeCol });\n }\n });\n // If the focused cell itself was removed (an agent collapsed the group\n // holding focus), focus would fall to the page with no blur event: put it\n // back on the active cell, now the group row.\n useIsomorphicLayoutEffect(() => {\n if (!hasFocusRef.current || pendingFocus.current) return;\n const current = document.activeElement;\n if (current && current !== document.body && current.isConnected) return;\n pendingFocus.current = true;\n });\n\n const cellElement = useCallback(\n (rowIndex: number, col: number): HTMLElement | null =>\n gridRef.current?.querySelector<HTMLElement>(\n `[role=\"row\"][aria-rowindex=\"${rowIndex + 2}\"] > [aria-colindex=\"${col + 2}\"]`,\n ) ?? null,\n [],\n );\n\n useIsomorphicLayoutEffect(() => {\n if (!pendingFocus.current) return;\n const element = cellElement(activeRow, activeCol);\n if (!element) return;\n pendingFocus.current = false;\n element.focus({ preventScroll: true });\n element.scrollIntoView?.({ block: 'nearest', inline: 'nearest' });\n });\n\n const isRtl = () =>\n gridRef.current\n ? window.getComputedStyle(gridRef.current).direction === 'rtl'\n : false;\n\n /* ---- range anchor -------------------------------------------------- */\n const anchor = useRef<{ rowIndex: number; col: number } | null>(null);\n const dataRowIndexAt = (navIndex: number): number | null => {\n const row = body[navIndex];\n return row && row.kind === 'data' ? row.rowIndex : null;\n };\n\n /** Set by a range press on the only selected cell: the click that\n * follows (with no drag) clears it, as Enter does. */\n const clearOnClick = useRef(false);\n\n const moveTo = (rowIndex: number, col: number) => {\n const clampedRow = Math.max(0, Math.min(navRowKeys.length - 1, rowIndex));\n const clampedCol = Math.max(0, Math.min(navColumnCount - 1, col));\n pendingFocus.current = true;\n setTooltipDismissed(false);\n setActive({ rowKey: navRowKeys[clampedRow], col: clampedCol });\n return { row: clampedRow, col: clampedCol };\n };\n\n /** Activates the cell at a navigable position (click, Enter, Space). */\n const activate = (navIndex: number, col: number, extend: boolean) => {\n const row = body[navIndex];\n if (!row) return;\n if (row.kind === 'group') {\n onToggleGroup(row.groupId);\n return;\n }\n if (col >= columnCount) return;\n if (selectionMode === 'range' && extend && anchor.current) {\n onRange(anchor.current, { rowIndex: row.rowIndex, col });\n return;\n }\n anchor.current = { rowIndex: row.rowIndex, col };\n onActivate(row.rowIndex, col, true);\n };\n\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n // A key on the group toggle (if something focused it) keeps its own\n // meaning: Enter on that button toggles the group, never selects the\n // last active cell. Keys on a cell, or on the grid itself (a click on a\n // header focuses it), drive the grid.\n if (event.target instanceof Element && event.target.closest('button')) {\n return;\n }\n interaction.current = 'keyboard';\n const lastRow = navRowKeys.length - 1;\n const lastCol = navColumnCount - 1;\n const forward = isRtl() ? -1 : 1;\n let row = activeRow;\n let col = activeCol;\n const ctrl = event.ctrlKey || event.metaKey;\n switch (event.key) {\n case 'ArrowRight':\n col += forward;\n break;\n case 'ArrowLeft':\n col -= forward;\n break;\n case 'ArrowDown':\n row += 1;\n break;\n case 'ArrowUp':\n row -= 1;\n break;\n case 'Home':\n col = 0;\n if (ctrl) row = 0;\n break;\n case 'End':\n col = lastCol;\n if (ctrl) row = lastRow;\n break;\n case 'PageDown': {\n const nextGroup = body.findIndex(\n (r, i) => i > activeRow && r.kind === 'group',\n );\n const hasGroups = body.some((r) => r.kind === 'group');\n row = hasGroups\n ? nextGroup === -1\n ? lastRow\n : nextGroup\n : activeRow + pageRows(metricsRef.current);\n break;\n }\n case 'PageUp': {\n let previous = -1;\n for (let i = Math.min(activeRow, body.length) - 1; i >= 0; i -= 1) {\n if (body[i].kind === 'group') {\n previous = i;\n break;\n }\n }\n const hasGroups = body.some((r) => r.kind === 'group');\n row = hasGroups\n ? previous === -1\n ? 0\n : previous\n : activeRow - pageRows(metricsRef.current);\n break;\n }\n case 'Enter':\n case ' ':\n event.preventDefault();\n activate(activeRow, activeCol, event.shiftKey);\n return;\n case 'Escape':\n if (tooltipAt) {\n event.preventDefault();\n setTooltipDismissed(true);\n }\n return;\n default:\n return;\n }\n event.preventDefault();\n const moved = moveTo(row, col);\n const isArrow = event.key.startsWith('Arrow');\n if (selectionMode === 'range' && event.shiftKey && isArrow) {\n const target = dataRowIndexAt(moved.row);\n const from =\n anchor.current ??\n (() => {\n const start = dataRowIndexAt(activeRow);\n return start === null || activeCol >= columnCount\n ? null\n : { rowIndex: start, col: activeCol };\n })();\n if (from && target !== null && moved.col < columnCount) {\n anchor.current = from;\n onRange(from, { rowIndex: target, col: moved.col });\n }\n }\n };\n\n /** The navigable position of the cell an event landed on. */\n const positionOf = (\n target: EventTarget | null,\n ): { row: number; col: number } | null => {\n if (!(target instanceof Element)) return null;\n const cell = target.closest<HTMLElement>('[role=\"gridcell\"]');\n const rowElement = cell?.parentElement;\n if (!cell || !rowElement || !gridRef.current?.contains(cell)) return null;\n const rowIndex = Number(rowElement.getAttribute('aria-rowindex')) - 2;\n const col = Number(cell.getAttribute('aria-colindex')) - 2;\n if (!Number.isInteger(rowIndex) || rowIndex < 0 || col < 0) return null;\n return { row: rowIndex, col };\n };\n\n const dragging = useRef(false);\n const lastPointer = useRef<string>('mouse');\n\n const onPointerDown = (event: PointerEvent<HTMLDivElement>) => {\n interaction.current = 'pointer';\n lastPointer.current = event.pointerType;\n if (\n selectionMode !== 'range' ||\n event.pointerType !== 'mouse' ||\n event.button !== 0\n ) {\n return;\n }\n const position = positionOf(event.target);\n clearOnClick.current = false;\n if (!position) return;\n const rowIndex = dataRowIndexAt(position.row);\n if (rowIndex === null || position.col >= columnCount) return;\n if (event.shiftKey && anchor.current) {\n onRange(anchor.current, { rowIndex, col: position.col });\n } else {\n anchor.current = { rowIndex, col: position.col };\n const key = selectionKey(rows[rowIndex].id, columns[position.col].id);\n if (selected.size === 1 && selected.has(key)) {\n // Pressing the only selected cell: a drag still starts a range from\n // it, but a plain click clears it (see onClick), as Enter does.\n clearOnClick.current = true;\n } else {\n onRange(anchor.current, anchor.current);\n }\n }\n dragging.current = true;\n const stop = () => {\n dragging.current = false;\n window.removeEventListener('pointerup', stop);\n window.removeEventListener('pointercancel', stop);\n };\n window.addEventListener('pointerup', stop);\n window.addEventListener('pointercancel', stop);\n };\n\n const onPointerMove = (event: PointerEvent<HTMLDivElement>) => {\n if (event.pointerType !== 'mouse') return;\n const position = positionOf(event.target);\n updateHover(\n position ? { rowKey: navRowKeys[position.row], col: position.col } : null,\n );\n if (dragging.current && position && anchor.current) {\n const rowIndex = dataRowIndexAt(position.row);\n if (rowIndex !== null && position.col < columnCount) {\n if (\n rowIndex !== anchor.current.rowIndex ||\n position.col !== anchor.current.col\n ) {\n clearOnClick.current = false;\n }\n if (!clearOnClick.current) {\n onRange(anchor.current, { rowIndex, col: position.col });\n }\n }\n }\n };\n\n // While the pointer rests on the tooltip, one document listener waits for\n // it to land somewhere else. Kept in a ref so there is never more than one\n // and it goes away with the grid.\n const awayListener = useRef<\n ((event: globalThis.PointerEvent) => void) | null\n >(null);\n const stopAway = useCallback(() => {\n if (!awayListener.current) return;\n document.removeEventListener('pointerover', awayListener.current);\n awayListener.current = null;\n }, []);\n useEffect(() => stopAway, [stopAway]);\n\n const onPointerLeave = (event: PointerEvent<HTMLDivElement>) => {\n // Moving onto the tooltip keeps it open (WCAG 1.4.13, hoverable); it\n // closes once the pointer leaves both.\n stopAway();\n const next = event.relatedTarget;\n if (next instanceof Element && next.closest('[data-component=\"tooltip\"]')) {\n const away = (moved: globalThis.PointerEvent) => {\n const over = moved.target;\n if (\n over instanceof Element &&\n over.closest('[data-component=\"tooltip\"]')\n ) {\n return;\n }\n stopAway();\n if (!(over instanceof Node && gridRef.current?.contains(over))) {\n updateHover(null);\n }\n };\n awayListener.current = away;\n document.addEventListener('pointerover', away);\n return;\n }\n updateHover(null);\n };\n\n const onClick = (event: MouseEvent<HTMLDivElement>) => {\n const button =\n event.target instanceof Element ? event.target.closest('button') : null;\n if (button) {\n // The group toggle has run its own onClick. Grid focus moves to the\n // group row, so the keys carry on from there.\n const navIndex =\n Number(button.closest('[role=\"row\"]')?.getAttribute('aria-rowindex')) -\n 2;\n // Keep the column, so a grid scrolled sideways stays where it is.\n if (Number.isInteger(navIndex) && navIndex >= 0) {\n moveTo(navIndex, activeCol);\n }\n return;\n }\n const position = positionOf(event.target);\n if (!position) return;\n moveTo(position.row, position.col);\n pendingFocus.current = false;\n // Range drags select on pointer down; a click only follows up for touch,\n // except to clear the only selected cell and to toggle a group.\n if (selectionMode === 'range' && lastPointer.current === 'mouse') {\n const row = body[position.row];\n if (row?.kind === 'group') {\n activate(position.row, position.col, false);\n } else if (row?.kind === 'data' && position.col < columnCount) {\n onActivate(row.rowIndex, position.col, clearOnClick.current);\n }\n clearOnClick.current = false;\n return;\n }\n activate(position.row, position.col, event.shiftKey);\n };\n\n /* ---- tooltip and scrolling ------------------------------------------ */\n // Radix closes a tooltip when anything around its trigger scrolls. A key\n // that moves focus scrolls the cell into view, so that close is not the\n // user dismissing it. This listener is added before any tooltip's, so it\n // marks the scroll first and the close below can tell. A hover tooltip\n // still closes on a scroll: the wheel moves the cell from under the\n // pointer without a pointer event.\n const scrolling = useRef(false);\n useEffect(() => {\n let settle = 0;\n const onAnyScroll = () => {\n scrolling.current = true;\n window.cancelAnimationFrame(settle);\n settle = window.requestAnimationFrame(() => {\n scrolling.current = false;\n });\n };\n window.addEventListener('scroll', onAnyScroll, { capture: true });\n return () => {\n window.removeEventListener('scroll', onAnyScroll, { capture: true });\n window.cancelAnimationFrame(settle);\n };\n }, []);\n\n /* ---- row context ---------------------------------------------------- */\n const onTooltipOpenChange = useCallback((open: boolean) => {\n if (open) return;\n // Only the focus tooltip (nothing hovered) outlives a scroll.\n if (scrolling.current && hoverRef.current === null) return;\n setTooltipDismissed(true);\n }, []);\n const expandLabel = useCallback(\n (group: string) => t('heatmap.expandGroup', { group }),\n [t],\n );\n const collapseLabel = useCallback(\n (group: string) => t('heatmap.collapseGroup', { group }),\n [t],\n );\n\n /* ---- the focused cell's description ------------------------------- */\n // A consumer's renderTooltip text reaches screen readers as the focused\n // cell's description; one hidden node, whatever the grid's size.\n const descriptionId = `${idBase}-description`;\n const focusedRow = body[activeRow];\n const description =\n describeFocused && focusedRow?.kind === 'data' && activeCol < columnCount\n ? tooltipText(cellInfo(focusedRow.rowIndex, activeCol))\n : null;\n\n const ctx = useMemo<RowContext>(\n () => ({\n rows,\n columns,\n matrix,\n scale,\n palette,\n describer,\n showValues,\n totals,\n rowTotals,\n groupColumnMethod,\n groupIds,\n selectable: selectionMode !== 'none',\n interactive,\n virtualised,\n colWindow: windows.cols,\n idBase,\n describedBy: describeFocused ? descriptionId : undefined,\n cellInfo,\n tooltipText,\n onTooltipOpenChange,\n onToggleGroup,\n expandLabel,\n collapseLabel,\n }),\n [\n rows,\n columns,\n matrix,\n scale,\n palette,\n describer,\n showValues,\n totals,\n rowTotals,\n groupColumnMethod,\n groupIds,\n selectionMode,\n interactive,\n virtualised,\n windows.cols,\n idBase,\n describeFocused,\n descriptionId,\n cellInfo,\n tooltipText,\n onTooltipOpenChange,\n onToggleGroup,\n expandLabel,\n collapseLabel,\n ],\n );\n\n /** Selected column indexes per data row id, comma-joined. */\n const selectedByRow = useMemo(() => {\n const map = new Map<string, number[]>();\n for (const key of selected) {\n const [rowId, columnKey] = splitSelectionKey(key);\n const col = columnIndexOfKey(columnKey);\n if (col === undefined) continue;\n const list = map.get(rowId) ?? [];\n list.push(col);\n map.set(rowId, list);\n }\n const joined = new Map<string, string>();\n for (const [rowId, list] of map) {\n joined.set(rowId, list.sort((a, b) => a - b).join(','));\n }\n return joined;\n }, [selected, columnIndexOfKey]);\n\n /* ---- header and footer ---------------------------------------------- */\n const highlightCol = highlight?.col ?? -1;\n const header = (\n <div\n ref={headerRef}\n role=\"row\"\n aria-rowindex={1}\n className={heatmapRowVariants({ position: 'header' })}\n >\n <div\n role=\"columnheader\"\n aria-colindex={1}\n className={heatmapColumnHeaderVariants({ corner: true })}\n >\n {rowsLabel ?? (\n <span className=\"ds:sr-only\">{t('heatmap.rowsHeader')}</span>\n )}\n </div>\n {renderColumns(windows.cols, (c) => (\n <div\n key={c}\n role=\"columnheader\"\n aria-colindex={c + 2}\n data-highlighted={highlightCol === c}\n className={heatmapColumnHeaderVariants()}\n >\n {describer.columnLabel(columns[c])}\n </div>\n ))}\n {rowTotals ? (\n <div\n role=\"columnheader\"\n aria-colindex={columnCount + 2}\n data-highlighted={highlightCol === columnCount}\n className={heatmapColumnHeaderVariants()}\n >\n {describer.methodLabel(rowTotals)}\n </div>\n ) : null}\n </div>\n );\n\n let footer: ReactElement | null = null;\n if (columnTotals && totals) {\n const footerIndex = body.length;\n const methodText = describer.methodLabel(columnTotals);\n const footerActive = activeRow === footerIndex;\n const total = (\n cell: ModelCell,\n c: number,\n columnText: string,\n rowText = methodText,\n ) => (\n <div\n key={c}\n role=\"gridcell\"\n aria-colindex={c + 2}\n aria-label={describer.sentence(rowText, columnText, cell)}\n tabIndex={footerActive && activeCol === c ? 0 : -1}\n className={heatmapCellVariants({ tone: aggregateTone(cell) })}\n >\n {describer.visibleText(cell)}\n </div>\n );\n footer = (\n <div\n ref={footerRef}\n role=\"row\"\n aria-rowindex={footerIndex + 2}\n className={heatmapRowVariants({ position: 'footer' })}\n >\n <div\n role=\"rowheader\"\n aria-colindex={1}\n data-highlighted={highlight?.rowKey === FOOTER_ROW_KEY}\n className={heatmapRowHeaderVariants({ kind: 'total', virtualised })}\n >\n {methodText}\n </div>\n {renderColumns(windows.cols, (c) =>\n total(totals.columns[c], c, describer.columnLabel(columns[c])),\n )}\n {rowTotals\n ? total(\n totals.grand,\n columnCount,\n describer.methodLabel(rowTotals),\n // The corner aggregates every cell by the row method, so it\n // is named for all cells, not for the footer's own method.\n t('heatmap.allCells'),\n )\n : null}\n </div>\n );\n }\n\n /* ---- body ----------------------------------------------------------- */\n const bodyRows: ReactElement[] = [];\n const rowWindow = windows.rows;\n if (rowWindow.lead > 0) {\n bodyRows.push(\n <div\n key=\"row-lead\"\n aria-hidden=\"true\"\n className={heatmapSpacerVariants({ axis: 'row-lead' })}\n />,\n );\n }\n rowWindow.indexes.forEach((navIndex, i) => {\n if (rowWindow.middle > 0 && i === rowWindow.middleAfter) {\n bodyRows.push(\n <div\n key=\"row-middle\"\n aria-hidden=\"true\"\n className={heatmapSpacerVariants({ axis: 'row-middle' })}\n />,\n );\n }\n const row = body[navIndex];\n if (!row) return;\n const isActiveRow = navIndex === activeRow;\n bodyRows.push(\n <HeatmapBodyRow\n key={row.key}\n ctx={ctx}\n row={row}\n ariaRowIndex={navIndex + 2}\n highlighted={highlight?.rowKey === row.key}\n activeCol={isActiveRow ? activeCol : -1}\n tooltipCol={tooltipAt?.rowKey === row.key ? tooltipAt.col : -1}\n selectedCols={\n row.kind === 'data'\n ? (selectedByRow.get(rows[row.rowIndex].id) ?? '')\n : ''\n }\n />,\n );\n });\n if (rowWindow.tail > 0) {\n bodyRows.push(\n <div\n key=\"row-tail\"\n aria-hidden=\"true\"\n className={heatmapSpacerVariants({ axis: 'row-tail' })}\n />,\n );\n }\n\n // Inline style: permitted per 23-constraints §Runtime-computed dimensions\n // (custom-property setter on the scroll box; the column count comes from\n // the data, the spans from the virtual window and the sticky sizes from\n // measurement. Every rule that reads them lives in CVA).\n const scrollerStyle = {\n '--heatmap-columns': String(Math.max(1, columnCount)),\n '--heatmap-row-lead': String(rowWindow.lead),\n '--heatmap-row-middle': String(rowWindow.middle),\n '--heatmap-row-tail': String(rowWindow.tail),\n '--heatmap-col-lead': String(windows.cols.lead),\n '--heatmap-col-middle': String(windows.cols.middle),\n '--heatmap-col-tail': String(windows.cols.tail),\n '--heatmap-sticky-block-start': `${metrics.headerBlock}px`,\n '--heatmap-sticky-block-end': `${metrics.footerBlock}px`,\n '--heatmap-sticky-inline-start': `${metrics.leadInline}px`,\n } as CSSProperties;\n\n return (\n <div\n ref={scrollerRef}\n onScroll={onScroll}\n // eslint-disable-next-line react/forbid-dom-props -- 23-constraints §Runtime-computed dimensions: custom-property setter only\n style={scrollerStyle}\n data-component=\"heatmap-grid\"\n className={heatmapScrollerVariants()}\n >\n <div\n ref={gridRef}\n role=\"grid\"\n // Focus lives on the cells (roving tabindex); -1 keeps the grid itself\n // out of the tab order while letting it hold focus programmatically.\n tabIndex={-1}\n aria-label={title}\n aria-rowcount={navRowKeys.length + 1}\n aria-colcount={navColumnCount + 1}\n aria-multiselectable={\n selectionMode === 'multiple' || selectionMode === 'range'\n ? true\n : undefined\n }\n data-heatmap-grid=\"\"\n className={heatmapGridVariants({\n size,\n density,\n virtualised,\n totalsColumn: Boolean(rowTotals),\n })}\n onKeyDown={onKeyDown}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerLeave={onPointerLeave}\n onClick={onClick}\n onFocus={(event) => {\n // Tabbing in counts as keyboard use, so the tooltip shows at once.\n if (event.target.matches(':focus-visible')) {\n interaction.current = 'keyboard';\n }\n hasFocusRef.current = true;\n setHasFocus(true);\n }}\n onBlur={(event) => {\n if (\n !event.currentTarget.contains(event.relatedTarget as Node | null)\n ) {\n hasFocusRef.current = false;\n setHasFocus(false);\n }\n }}\n >\n {header}\n {bodyRows}\n {footer}\n </div>\n {description !== null ? (\n <span id={descriptionId} hidden>\n {description}\n </span>\n ) : null}\n </div>\n );\n}\n","import { forwardRef, useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { formatLocale } from '../_shared/intl-locale';\nimport { useHeatmapContext } from './heatmap-context';\nimport { countFormatter, defaultValueFormatter } from './heatmap-format';\nimport {\n HEATMAP_STEPS,\n bucketStep,\n resolveScale,\n type HeatmapScale,\n type ResolvedHeatmapScale,\n} from './heatmap-scale';\nimport {\n heatmapLegendBarVariants,\n heatmapLegendVariants,\n heatmapSwatchVariants,\n stepTone,\n type HeatmapPalette,\n} from './heatmap-variants';\n\nexport interface HeatmapLegendProps {\n /**\n * `stepped` separates the ten steps; `continuous` joins them in a bar.\n * A quantile or threshold scale always shows its bands, one swatch per\n * step it uses, with the cut points between them.\n */\n variant?: 'stepped' | 'continuous';\n /** Palette. Inside a Heatmap it defaults to the Heatmap's. */\n palette?: HeatmapPalette;\n /** Scale. Inside a Heatmap it defaults to the Heatmap's resolved scale. */\n scale?: HeatmapScale;\n /** Values an `auto` or quantile scale is worked out from (outside a Heatmap). */\n values?: readonly number[];\n /** Formats the end labels. Inside a Heatmap it defaults to the Heatmap's. */\n valueFormatter?: (value: number) => string;\n /** Show the key for empty cells. Inside a Heatmap: when any cell is empty. */\n showEmpty?: boolean;\n /** Show the key for low-sample cells. Inside a Heatmap: when any cell is. */\n showLowSample?: boolean;\n /** Show the key for totals withheld to protect small numbers. Inside a\n * Heatmap: when any total it draws is withheld. */\n showWithheldTotal?: boolean;\n /** The sample threshold, named in the low-sample key. Inside a Heatmap it\n * defaults to the Heatmap's `minCount`. */\n minCount?: number;\n className?: string;\n}\n\nconst STEPS = Array.from({ length: HEATMAP_STEPS }, (_, step) => step);\n\n/** End labels for the bar of a sequential or diverging scale. */\nfunction endLabels(\n scale: ResolvedHeatmapScale,\n format: (value: number) => string,\n): { start: string; end: string; middle?: string } {\n return {\n start: scale.min === null ? '' : format(scale.min),\n end: scale.max === null ? '' : format(scale.max),\n middle:\n scale.type === 'diverging' && scale.midpoint !== undefined\n ? format(scale.midpoint)\n : undefined,\n };\n}\n\n/**\n * Heatmap.Legend: the colour steps with the low and high ends of the scale,\n * plus keys for empty and low-sample cells and withheld totals. A diverging scale shows its\n * midpoint between the two hues as a neutral swatch carrying the midpoint\n * value, the colour of a cell exactly on it. Inside a Heatmap it reads the\n * Heatmap's scale; render it elsewhere with `legend={false}` on the Heatmap\n * and the same `scale`, `palette` and `values` here.\n */\nexport const HeatmapLegend = forwardRef<HTMLDivElement, HeatmapLegendProps>(\n (\n {\n variant = 'stepped',\n palette: paletteProp,\n scale: scaleProp,\n values,\n valueFormatter,\n showEmpty,\n showLowSample,\n showWithheldTotal,\n minCount: minCountProp,\n className,\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation('ui');\n const context = useHeatmapContext();\n const locale = formatLocale(i18n.resolvedLanguage ?? i18n.language);\n\n const scale = useMemo(\n () =>\n scaleProp\n ? resolveScale(scaleProp, values ?? [])\n : (context?.scale ??\n resolveScale({ type: 'sequential' }, values ?? [])),\n [scaleProp, values, context?.scale],\n );\n const palette =\n paletteProp ??\n context?.palette ??\n (scale.type === 'diverging' ? 'diverging' : 'primary');\n const format =\n valueFormatter ??\n context?.describer.formatValue ??\n defaultValueFormatter(locale, 'number');\n\n // A quantile or threshold scale paints only a few steps: one per band.\n // Show those, with each cut point between its two bands, not ten\n // swatches of which most never appear.\n const banded =\n (scale.type === 'quantile' || scale.type === 'threshold') &&\n scale.thresholds.length > 0;\n const bandCount = scale.thresholds.length + 1;\n const bandSteps = banded\n ? Array.from({ length: bandCount }, (_, band) =>\n bucketStep(band, bandCount),\n )\n : [];\n const edges = scale.thresholds.map(format);\n\n const labels = endLabels(scale, format);\n const description = banded\n ? t('heatmap.legend.descriptionBands', {\n count: bandCount,\n formatted: countFormatter(locale)(bandCount),\n edges: new Intl.ListFormat(locale, {\n type: 'conjunction',\n }).format(edges),\n })\n : labels.middle !== undefined\n ? t('heatmap.legend.descriptionDiverging', {\n min: labels.start,\n max: labels.end,\n midpoint: labels.middle,\n })\n : t('heatmap.legend.description', {\n min: labels.start,\n max: labels.end,\n });\n // A banded scale with no cut (every value equal) paints one step.\n const singleStep =\n (scale.type === 'quantile' || scale.type === 'threshold') && !banded\n ? [scale.min === null ? HEATMAP_STEPS / 2 : scale.stepOf(scale.min)]\n : null;\n const withEmpty = showEmpty ?? context?.hasEmpty ?? false;\n const withLowSample = showLowSample ?? context?.hasLowSample ?? false;\n const withWithheldTotal =\n showWithheldTotal ?? context?.hasWithheldTotal ?? false;\n const minCount = minCountProp ?? context?.minCount;\n const shape = variant === 'continuous' ? 'continuous' : 'stepped';\n\n const bar = (steps: readonly number[]) => (\n <span className={heatmapLegendBarVariants({ variant })}>\n {steps.map((step) => (\n <span\n key={step}\n className={heatmapSwatchVariants({\n tone: stepTone(palette, step),\n shape,\n })}\n />\n ))}\n </span>\n );\n\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-label={t('heatmap.legend.label')}\n data-component=\"heatmap-legend\"\n className={heatmapLegendVariants({ className })}\n >\n <span className=\"ds:sr-only\">{description}</span>\n {banded ? (\n <span\n aria-hidden=\"true\"\n data-legend=\"bands\"\n className=\"ds:flex ds:min-w-0 ds:max-w-full ds:flex-wrap ds:items-center ds:gap-[var(--spacing-xs)] ds:tabular-nums\"\n >\n {bandSteps.map((step, band) => (\n <span\n key={step}\n className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]\"\n >\n <span\n data-step={step}\n className={heatmapSwatchVariants({\n tone: stepTone(palette, step),\n shape: 'key',\n })}\n />\n {band < edges.length ? (\n <span className=\"ds:shrink-0\">{edges[band]}</span>\n ) : null}\n </span>\n ))}\n </span>\n ) : (\n <span\n aria-hidden=\"true\"\n className=\"ds:flex ds:min-w-0 ds:max-w-full ds:items-center ds:gap-[var(--spacing-xs)] ds:tabular-nums\"\n >\n <span className=\"ds:shrink-0\">{labels.start}</span>\n {labels.middle !== undefined ? (\n <>\n {bar(STEPS.slice(0, HEATMAP_STEPS / 2))}\n {/* A value exactly on the midpoint is painted neutral, so\n its swatch sits between the hues, carrying the value. */}\n <span\n data-legend=\"midpoint\"\n className={heatmapSwatchVariants({\n tone: 'midpoint',\n shape: 'label',\n })}\n >\n {labels.middle}\n </span>\n {bar(STEPS.slice(HEATMAP_STEPS / 2))}\n </>\n ) : (\n bar(singleStep ?? STEPS)\n )}\n <span className=\"ds:shrink-0\">{labels.end}</span>\n </span>\n )}\n {withEmpty ? (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <span\n aria-hidden=\"true\"\n className={heatmapSwatchVariants({ tone: 'empty' })}\n />\n {t('heatmap.legend.noData')}\n </span>\n ) : null}\n {withLowSample ? (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <span\n aria-hidden=\"true\"\n className={heatmapSwatchVariants({ tone: 'low-sample' })}\n />\n {minCount === undefined\n ? t('heatmap.legend.lowSample')\n : t('heatmap.legend.lowSampleUnder', {\n value: new Intl.NumberFormat(locale).format(minCount),\n })}\n </span>\n ) : null}\n {withWithheldTotal ? (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <span\n aria-hidden=\"true\"\n className={heatmapSwatchVariants({ tone: 'low-sample' })}\n />\n {t('heatmap.legend.totalWithheld')}\n </span>\n ) : null}\n </div>\n );\n },\n);\n\nHeatmapLegend.displayName = 'HeatmapLegend';\n","import {\n lazy,\n Suspense,\n useMemo,\n useRef,\n useState,\n type ComponentType,\n} from 'react';\nimport type { ColDef, GridOptions } from 'ag-grid-community';\nimport { useTranslation } from 'react-i18next';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport type { DataTableProps } from '../data-table/data-table';\nimport { ErrorBoundary } from '../error-boundary';\nimport { Skeleton } from '../skeleton';\nimport type { HeatmapDescriber } from './heatmap-format';\nimport type {\n BodyRow,\n HeatmapColumn,\n HeatmapRow,\n HeatmapTotals,\n ModelCell,\n} from './heatmap-model';\nimport { heatmapTableViewVariants } from './heatmap-variants';\nimport type { HeatmapAggregate } from './heatmap-scale';\n\n/** One row of the table view: a data row or a group's totals. */\ninterface HeatmapTableRow {\n id: string;\n group?: string;\n row: string;\n cells: string[];\n total?: string;\n}\n\n/*\n * The DataTable (AG Grid) loads on demand: nothing in the heatmap's own\n * entry imports AG Grid, so a heatmap that never shows its table never\n * downloads it. Every table in the kit is DataTable. The consumer installs\n * ag-grid-community and ag-grid-react (src/docs/25-consuming.mdx).\n */\nconst loadDataTable = () =>\n import('../data-table/data-table').then((module) => ({\n default: module.DataTable as unknown as ComponentType<\n DataTableProps<HeatmapTableRow>\n >,\n }));\nconst LazyDataTable = lazy(loadDataTable);\n\n/** Starts fetching the table chunk ahead of a switch to the table view, so\n * the switch does not wait on the download. Safe to call repeatedly. */\nexport function preloadHeatmapTable(): void {\n loadDataTable().catch(() => {\n /* the switch itself retries and shows the error */\n });\n}\n\nexport interface HeatmapTableViewProps {\n title: string;\n rowsLabel?: string;\n rows: readonly HeatmapRow[];\n columns: readonly HeatmapColumn[];\n matrix: readonly ModelCell[][];\n /** Group headers and rows in display order, every group expanded. */\n body: readonly BodyRow[];\n grouped: boolean;\n /** Each group's public id, for the table's row ids (never a label). */\n groupIds: ReadonlyMap<string, string>;\n describer: HeatmapDescriber;\n /** The grid's totals, withheld ones already reduced to a value-less\n * cell, so the table can show nothing the grid does not. */\n totals: HeatmapTotals | null;\n rowTotals: HeatmapAggregate | false;\n columnTotals: HeatmapAggregate | false;\n groupColumnMethod: HeatmapAggregate;\n /** The table failed to load or render (announced by the heatmap). */\n onLoadError?: () => void;\n}\n\n/** Stands in for a group total that was not worked out. */\nconst NO_TOTAL: ModelCell = { value: null, status: 'empty' };\n\n/**\n * The heatmap's \"View as table\": the same rows, columns, values, counts and\n * totals as a DataTable, so every number is reachable without colour and\n * without a pointer. Group header rows carry their totals, and rows stay in\n * their groups in the grid's order. Labels go through the same privacy\n * masking as the grid.\n */\nexport function HeatmapTableView({\n title,\n rowsLabel,\n rows,\n columns,\n matrix,\n body,\n grouped,\n groupIds,\n describer,\n totals,\n rowTotals,\n columnTotals,\n groupColumnMethod,\n onLoadError,\n}: HeatmapTableViewProps) {\n const { t } = useTranslation('ui');\n\n const columnDefs = useMemo<ColDef<HeatmapTableRow>[]>(\n () => [\n ...(grouped\n ? [\n {\n colId: 'group',\n field: 'group' as const,\n headerName: t('heatmap.table.group'),\n // A sort here would pull rows out of their groups.\n sortable: false,\n },\n ]\n : []),\n {\n colId: 'row',\n field: 'row' as const,\n headerName: rowsLabel ?? t('heatmap.rowsHeader'),\n sortable: !grouped,\n },\n ...columns.map(\n (column, c): ColDef<HeatmapTableRow> => ({\n colId: `c${c}`,\n headerName: describer.columnLabel(column),\n valueGetter: (params) => params.data?.cells[c] ?? '',\n sortable: false,\n }),\n ),\n ...(rowTotals\n ? [\n {\n colId: 'total',\n field: 'total' as const,\n headerName: describer.methodLabel(rowTotals),\n sortable: false,\n },\n ]\n : []),\n ],\n [grouped, rowsLabel, columns, describer, rowTotals, t],\n );\n\n const rowData = useMemo<HeatmapTableRow[]>(\n () =>\n body.map((entry): HeatmapTableRow => {\n if (entry.kind === 'group') {\n const groupText = describer.groupLabel(entry.groupId);\n const perColumn = totals?.groupColumns.get(entry.groupId) ?? [];\n return {\n id: `group:${groupIds.get(entry.groupId) ?? ''}`,\n group: groupText,\n row: describer.groupRowText(groupText, groupColumnMethod),\n cells: columns.map((_, c) =>\n describer.tableText(perColumn[c] ?? NO_TOTAL),\n ),\n total:\n rowTotals && totals\n ? describer.tableText(\n totals.groups.get(entry.groupId) ?? NO_TOTAL,\n )\n : undefined,\n };\n }\n const r = entry.rowIndex;\n const groupId = rows[r].group;\n return {\n id: `row:${rows[r].id}`,\n group:\n grouped && groupId !== undefined\n ? describer.groupLabel(groupId)\n : undefined,\n row: describer.rowLabel(rows[r]),\n cells: matrix[r].map((cell) => describer.tableText(cell)),\n total:\n rowTotals && totals\n ? describer.tableText(totals.rows[r])\n : undefined,\n };\n }),\n [\n body,\n rows,\n columns,\n matrix,\n grouped,\n groupIds,\n describer,\n rowTotals,\n totals,\n groupColumnMethod,\n ],\n );\n\n const pinnedBottomRowData = useMemo<HeatmapTableRow[] | undefined>(\n () =>\n columnTotals && totals\n ? [\n {\n id: 'heatmap-column-totals',\n row: describer.methodLabel(columnTotals),\n cells: totals.columns.map((cell) => describer.tableText(cell)),\n // The grand total, by the row method, as the grid's corner.\n total: rowTotals ? describer.tableText(totals.grand) : undefined,\n },\n ]\n : undefined,\n [columnTotals, rowTotals, totals, describer],\n );\n\n /*\n * Height: the table grows with its rows (AG Grid autoHeight) up to\n * --heatmap-max-block-size, so a small grid leaves no empty space. Past\n * that it holds the maximum and scrolls inside, keeping its header in\n * view. AG Grid has no max height for autoHeight, so the wrapper's own\n * max-height detects the overflow and switches the layout. Remembered\n * per row count: new rows fit again from scratch.\n */\n const rowCount = rowData.length + (pinnedBottomRowData?.length ?? 0);\n const rowCountRef = useRef(rowCount);\n rowCountRef.current = rowCount;\n const [cappedAt, setCappedAt] = useState<number | null>(null);\n const capped = cappedAt === rowCount;\n const wrapperRef = useRef<HTMLDivElement>(null);\n\n useIsomorphicLayoutEffect(() => {\n const wrapper = wrapperRef.current;\n if (capped || !wrapper || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(() => {\n if (wrapper.scrollHeight > wrapper.clientHeight + 1) {\n setCappedAt(rowCountRef.current);\n }\n });\n // Watch the content as well as the box: once the box reaches its\n // maximum it stops resizing, but the table inside may still grow.\n const watch = () => {\n observer.observe(wrapper);\n for (const child of Array.from(wrapper.children)) observer.observe(child);\n };\n watch();\n const children = new MutationObserver(watch);\n children.observe(wrapper, { childList: true });\n return () => {\n observer.disconnect();\n children.disconnect();\n };\n }, [capped]);\n\n const gridOptions = useMemo<GridOptions<HeatmapTableRow>>(\n () => ({\n getRowId: (params) => params.data.id,\n domLayout: capped ? 'normal' : 'autoHeight',\n }),\n [capped],\n );\n\n // A failed chunk load stays failed inside one lazy component, so a retry\n // makes a fresh one; the first attempt shares the module-level loader.\n const [attempt, setAttempt] = useState(0);\n const DataTable = useMemo(\n () => (attempt === 0 ? LazyDataTable : lazy(loadDataTable)),\n [attempt],\n );\n\n return (\n <div\n ref={wrapperRef}\n role=\"group\"\n aria-label={title}\n // Holds focus while a retry replaces the error state's button.\n tabIndex={-1}\n data-component=\"heatmap-table\"\n data-layout={capped ? 'capped' : 'fit'}\n className={heatmapTableViewVariants({ capped })}\n >\n <ErrorBoundary\n size=\"sm\"\n onError={() => onLoadError?.()}\n onRetry={() => {\n setAttempt((current) => current + 1);\n wrapperRef.current?.focus();\n }}\n >\n <Suspense\n fallback={\n <div role=\"status\" aria-label={t('heatmap.loadingTable')}>\n <Skeleton\n variant=\"rectangular\"\n className=\"ds:h-[calc(var(--min-target-size)*4)] ds:w-full\"\n />\n </div>\n }\n >\n <DataTable\n columnDefs={columnDefs}\n rowData={rowData}\n pinnedBottomRowData={pinnedBottomRowData}\n density=\"compact\"\n heightClass={capped ? 'ds:min-h-0 ds:flex-1' : ''}\n gridOptions={gridOptions}\n />\n </Suspense>\n </ErrorBoundary>\n </div>\n );\n}\n","import {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport { Grid3x3, Table2 } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { useAgentRegistration } from '../../agent';\nimport { formatLocale } from '../_shared/intl-locale';\nimport { Button } from '../button';\nimport { EmptyState } from '../empty-state';\nimport { LiveRegion } from '../live-region';\nimport { Skeleton } from '../skeleton';\nimport { TooltipProvider } from '../tooltip';\nimport { heatmapAgent } from './heatmap.agent';\nimport { HeatmapContext, type HeatmapContextValue } from './heatmap-context';\nimport {\n countFormatter,\n createDescriber,\n defaultValueFormatter,\n type HeatmapPrivacyScope,\n type HeatmapValueType,\n} from './heatmap-format';\nimport {\n HeatmapGrid,\n selectionKey,\n splitSelectionKey,\n type HeatmapSelectionMode,\n} from './heatmap-grid';\nimport { HeatmapLegend } from './heatmap-legend';\nimport {\n buildBodyRows,\n buildMatrix,\n computeTotals,\n hasAnyData,\n publicGroupIds,\n shownValues,\n sortRowIndexes,\n type HeatmapCellInfo,\n type HeatmapCellInput,\n type HeatmapCellKey,\n type HeatmapColumn,\n type HeatmapGetTotal,\n type HeatmapGroup,\n type HeatmapRow,\n type HeatmapSortRows,\n type ModelCell,\n} from './heatmap-model';\nimport {\n resolveScale,\n type HeatmapAggregate,\n type HeatmapScale,\n} from './heatmap-scale';\nimport { HeatmapTableView, preloadHeatmapTable } from './heatmap-table-view';\nimport { HeatmapTooltip } from './heatmap-tooltip';\nimport {\n heatmapRootVariants,\n heatmapToolbarVariants,\n type HeatmapPalette,\n} from './heatmap-variants';\nimport { VIRTUALISE_CELL_THRESHOLD } from './heatmap-window';\n\nexport type {\n HeatmapCellData,\n HeatmapCellInfo,\n HeatmapCellInput,\n HeatmapCellKey,\n HeatmapCellStatus,\n HeatmapColumn,\n HeatmapGetTotal,\n HeatmapGroup,\n HeatmapRow,\n HeatmapSortRows,\n HeatmapTotalScope,\n} from './heatmap-model';\nexport type { HeatmapAggregate, HeatmapScale } from './heatmap-scale';\nexport type { HeatmapPalette } from './heatmap-variants';\nexport type { HeatmapPrivacyScope, HeatmapValueType } from './heatmap-format';\nexport type { HeatmapSelectionMode } from './heatmap-grid';\n\n/** What `renderTooltip` is told besides the cell. */\nexport interface HeatmapTooltipContext {\n /**\n * True in privacy mode. The cell's labels are then already masked (and\n * its free-text `label` dropped), so text built from them is safe to show.\n */\n privacyMode: boolean;\n}\n\n/** Which presentation is showing. */\nexport type HeatmapView = 'heatmap' | 'table';\n\n/** What one cell reads back to an agent: structure and numbers, no labels. */\nexport interface HeatmapCellReading {\n value: number | null;\n count?: number;\n status: HeatmapCellInfo['status'];\n /** As `HeatmapCellInfo.step`: a value exactly on a diverging midpoint\n * reads step 5, though it is painted neutral grey. */\n step: number | null;\n}\n\n/**\n * Curated handle for the agent adapter (see heatmap.agent.ts). Ids only,\n * never labels. Group ids are the public ones: a group's own id when it is\n * listed in `groups`, else `group-<n>`. Every write throws on an id the\n * heatmap does not have, before it changes or announces anything.\n */\nexport interface HeatmapHandle {\n getSelection: () => HeatmapCellKey[];\n getSelectionMode: () => HeatmapSelectionMode;\n selectCells: (cells: readonly HeatmapCellKey[]) => void;\n selectRange: (from: HeatmapCellKey, to: HeatmapCellKey) => void;\n clearSelection: () => void;\n readCell: (cell: HeatmapCellKey) => HeatmapCellReading | null;\n getView: () => HeatmapView;\n setView: (view: HeatmapView) => void;\n getSortRows: () => HeatmapSortRows;\n setSortRows: (sort: HeatmapSortRows) => void;\n /** Row ids in display order, every group expanded. */\n getRowIds: () => string[];\n /** Column ids in order. */\n getColumnIds: () => (string | number)[];\n /** Group ids in display order; empty unless `groupRows` is on. */\n getGroupIds: () => string[];\n getCollapsedGroups: () => string[];\n setGroupCollapsed: (groupId: string, collapsed: boolean) => void;\n}\n\n/*\n * Memoisation: `rows`, `columns`, `getCell`, `cells`, `getTotal`, `groups`\n * and `valueFormatter` key the cell matrix, the totals and the wording every row\n * renders with. Keep them stable (useMemo, useCallback, or module scope): a\n * new array or an inline function on each parent render rebuilds them all.\n */\nexport interface HeatmapProps {\n /**\n * Required. Names the grid for assistive technology and the table view.\n * Never masked, so it must not name a person.\n */\n title: string;\n /** Rows, top to bottom. Keep the array stable (see Memoisation). */\n rows: readonly HeatmapRow[];\n /** Columns, in reading order. Keep the array stable. */\n columns: readonly HeatmapColumn[];\n /**\n * Returns a cell's data. Use this or `cells`. Keep it stable\n * (`useCallback`): an inline function rebuilds the matrix every render.\n */\n getCell?: (\n row: HeatmapRow,\n column: HeatmapColumn,\n rowIndex: number,\n columnIndex: number,\n ) => HeatmapCellInput;\n /** The cells as a `[row][column]` matrix, in the order of `rows` and `columns`. */\n cells?: readonly (readonly HeatmapCellInput[])[];\n /** Visible labels for the group ids rows carry. Keep the array stable. */\n groups?: readonly HeatmapGroup[];\n /** How values map to colour steps. Default sequential with an auto domain. */\n scale?: HeatmapScale;\n /** Colour palette. Default `diverging` for a diverging scale, else `primary`. */\n palette?: HeatmapPalette;\n /**\n * `rate` for proportions between 0 and 1: formats as a percentage and\n * reads counts as \"10 of 39\". Default `number`.\n */\n valueType?: HeatmapValueType;\n /**\n * Cells with a count below this render as \"too few to show\", hatched.\n * For a cell it is a display rule, not disclosure control: `read_cell`,\n * `onCellClick` and `onSelectionChange` still carry any value you pass.\n * To keep a value off the page, send `{ value: null, count }`: it still\n * renders as too few, and nothing can read a value the kit never had.\n * Totals follow small-number disclosure control: any total that, in any\n * combination with the other totals and cells, would pin down a hidden\n * cell, narrow it below the protection level (half its range, for a\n * rate), or determine a set of hidden cells with fewer than minCount\n * records, is withheld too, and carries no value anywhere. Every total\n * the data could show is audited, drawn or not. See `getTotal` and\n * heatmap.mdx.\n */\n minCount?: number;\n /**\n * Supplies a total: a row's, a column's, a group's, a group header cell\n * or the grand total, as `scope.kind` says. Return a cell input (`null`\n * for no total), or `undefined` to let the kit work it out from the\n * cells. Needed when you withhold values (`value: null`): the kit cannot\n * add up a value it never had, so it withholds any total it would get\n * wrong. `minCount` and the disclosure audit apply to a supplied total\n * exactly as to a worked-out one, which must be the exact count-weighted\n * mean (or sum) of its cells. Asked for every row, every column and the\n * grand total, and, whenever rows carry a group, every group and group\n * header cell, drawn or not. Keep it stable (`useCallback`).\n */\n getTotal?: HeatmapGetTotal;\n /** Formats a value. Default: Intl in the active locale. Keep it stable. */\n valueFormatter?: (value: number) => string;\n /** Print the value inside each cell. */\n showValues?: boolean;\n /** Built-in legend above the grid, or `false` to place `Heatmap.Legend` yourself. */\n legend?: 'stepped' | 'continuous' | false;\n /**\n * A totals column at the row ends. A mean weights by count. Everything in\n * that column uses this method: each row's total, each group's and the\n * grand total in the corner. With `minCount`, a mean of plain numbers\n * (`valueType=\"number\"`) is not audited for hidden cells: every such\n * average that holds one is withheld, so use `sum` for plain numbers.\n */\n rowTotals?: HeatmapAggregate | false;\n /**\n * A totals row under the columns. A mean weights by count. A group\n * header's per-column totals use this method too (else `rowTotals`).\n * With `minCount`, a mean of plain numbers is withheld wherever it holds\n * a hidden cell, as for `rowTotals`: use `sum` for plain numbers.\n */\n columnTotals?: HeatmapAggregate | false;\n /**\n * Row order (within each group). Controlled when set. In privacy mode\n * `label` keeps the given order: sorting by masked names would reveal\n * their order. A sort by total reads each row's total by the\n * `rowTotals` method (else the `columnTotals` one, else mean); a row\n * whose total is withheld sorts last.\n */\n sortRows?: HeatmapSortRows;\n /** Initial row order when uncontrolled. Default `none`. */\n defaultSortRows?: HeatmapSortRows;\n /** Called when the row order changes (agent `sort_rows`). */\n onSortRowsChange?: (sort: HeatmapSortRows) => void;\n /** Group rows by `row.group`, each group collapsible with its totals. */\n groupRows?: boolean;\n /** Group ids that start collapsed. */\n defaultCollapsedGroups?: readonly string[];\n /** How cells are selected. Default `none`. */\n selection?: HeatmapSelectionMode;\n /** Selected cells. Controlled when set. */\n selectedCells?: readonly HeatmapCellKey[];\n /** Initially selected cells when uncontrolled. */\n defaultSelectedCells?: readonly HeatmapCellKey[];\n /** Called with every cell in the new selection. */\n onSelectionChange?: (cells: HeatmapCellInfo[]) => void;\n /** Called when a cell is clicked, or activated with Enter or Space. */\n onCellClick?: (cell: HeatmapCellInfo) => void;\n /**\n * Tooltip text for a cell. Plain text: the kit Tooltip is text-only. It\n * also describes the focused cell to screen readers (aria-describedby).\n * In privacy mode the cell arrives with its labels masked, its free-text\n * `label` dropped and `row.group` replaced by the public group id, and\n * the context says so.\n */\n renderTooltip?: (\n cell: HeatmapCellInfo,\n context: HeatmapTooltipContext,\n ) => string;\n /** `compact` removes the gap between cells. Cells never shrink below the target size. */\n density?: 'compact' | 'default';\n /** Cell size. Every size keeps cells at least `--min-target-size`. */\n size?: 'sm' | 'md' | 'lg';\n /** Shows a skeleton while data loads. */\n loading?: boolean;\n /**\n * Masks row labels (people, chairs, patients) in the grid, the tooltip,\n * the table view and the announcements, and drops free-text cell labels.\n * Columns and groups stay readable unless `privacyScope=\"all\"`. `title`\n * and `rowsLabel` are never masked.\n */\n privacyMode?: boolean;\n /**\n * What privacy mode masks: `rows` (default) or `all`, which masks column\n * and group labels too.\n */\n privacyScope?: HeatmapPrivacyScope;\n /**\n * Names what the rows are (\"Chair\"): the corner header and the table's\n * first column. Never masked, so it must not name a person.\n */\n rowsLabel?: string;\n /** Initial presentation. Default `heatmap`. */\n defaultView?: HeatmapView;\n /** Called when the view switches between heatmap and table. */\n onViewChange?: (view: HeatmapView) => void;\n /** Instance id: `data-component-id`, and the agent registry key. */\n id?: string;\n className?: string;\n /**\n * Rendered inside the heatmap's context, after the grid (e.g.\n * `Heatmap.Legend`). Also while loading and when empty.\n */\n children?: ReactNode;\n}\n\nconst DEFAULT_SCALE: HeatmapScale = { type: 'sequential', domain: 'auto' };\n\n/** Selection keys for cells, by row id and column id (never by position,\n * so a change to `columns` keeps every selected cell on its own column). */\nconst toKeySet = (cells: readonly HeatmapCellKey[] | undefined): Set<string> =>\n new Set((cells ?? []).map((cell) => selectionKey(cell.rowId, cell.columnId)));\n\n/** What the live region says, and under which privacy setting it was made. */\ninterface Announcement {\n text: string;\n privacyMode: boolean;\n /** Bumped when the same words are said again, so they are heard again. */\n repeat: number;\n}\n\nconst SILENCE: Announcement = { text: '', privacyMode: false, repeat: 0 };\n\nconst HeatmapRoot = forwardRef<HTMLDivElement, HeatmapProps>(\n (\n {\n title,\n rows,\n columns,\n getCell,\n cells,\n groups,\n scale: scaleProp = DEFAULT_SCALE,\n palette: paletteProp,\n valueType = 'number',\n minCount,\n getTotal,\n valueFormatter,\n showValues = false,\n legend = 'stepped',\n rowTotals = false,\n columnTotals = false,\n sortRows: sortRowsProp,\n defaultSortRows = 'none',\n onSortRowsChange,\n groupRows = false,\n defaultCollapsedGroups,\n selection = 'none',\n selectedCells,\n defaultSelectedCells,\n onSelectionChange,\n onCellClick,\n renderTooltip,\n density = 'default',\n size = 'md',\n loading = false,\n privacyMode = false,\n privacyScope = 'rows',\n rowsLabel,\n defaultView = 'heatmap',\n onViewChange,\n id,\n className,\n children,\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation('ui');\n const locale = formatLocale(i18n.resolvedLanguage ?? i18n.language);\n\n /* ---- data ---------------------------------------------------------- */\n const matrix = useMemo(\n () => buildMatrix(rows, columns, getCell, cells, minCount),\n [rows, columns, getCell, cells, minCount],\n );\n const values = useMemo(() => shownValues(matrix), [matrix]);\n // Consumers often pass the scale inline; key it by content so an equal\n // scale does not re-resolve on every render.\n const scaleKey = JSON.stringify(scaleProp);\n const scale = useMemo(\n () => resolveScale(scaleProp, values),\n // eslint-disable-next-line react-hooks/exhaustive-deps -- keyed by content\n [scaleKey, values],\n );\n const palette: HeatmapPalette =\n paletteProp ?? (scale.type === 'diverging' ? 'diverging' : 'primary');\n\n const formatValue = useMemo(\n () => valueFormatter ?? defaultValueFormatter(locale, valueType),\n [valueFormatter, locale, valueType],\n );\n const formatCount = useMemo(() => countFormatter(locale), [locale]);\n const describer = useMemo(\n () =>\n createDescriber({\n t,\n privacyMode,\n privacyScope,\n valueType,\n formatValue,\n formatCount,\n groups,\n }),\n [\n t,\n privacyMode,\n privacyScope,\n valueType,\n formatValue,\n formatCount,\n groups,\n ],\n );\n const groupIds = useMemo(\n () => publicGroupIds(rows, groups),\n [rows, groups],\n );\n\n // A group header's per-column totals are column margins within the\n // group, so they follow the column method; everything in the row-totals\n // column follows the row method (see computeTotals).\n const groupColumnMethod: HeatmapAggregate =\n columnTotals || rowTotals || 'mean';\n // Every total is worked out and audited, drawn or not (row totals also\n // order a sort by total), so an undrawn kind follows the drawn one:\n // every total stays in one unit.\n const rowMethod: HeatmapAggregate = rowTotals || columnTotals || 'mean';\n const columnMethod: HeatmapAggregate = columnTotals || rowTotals || 'mean';\n\n /* ---- announcements ---------------------------------------------------- */\n const [announcement, setAnnouncement] = useState<Announcement>(SILENCE);\n const announceTimer = useRef(0);\n const privacyRef = useRef(privacyMode);\n privacyRef.current = privacyMode;\n const announce = useCallback((message: string, settle = false) => {\n window.clearTimeout(announceTimer.current);\n const madeUnder = privacyRef.current;\n const say = () =>\n setAnnouncement((current) => ({\n text: message,\n privacyMode: madeUnder,\n repeat: current.text === message ? current.repeat + 1 : 0,\n }));\n if (settle) {\n // A drag changes the selection on every cell it crosses; say only\n // where it settles.\n announceTimer.current = window.setTimeout(say, 300);\n } else {\n say();\n }\n }, []);\n useEffect(() => () => window.clearTimeout(announceTimer.current), []);\n // A message made before privacy mode turned on may name a row. Drop it\n // (and any still waiting) when the mode changes; until that lands, the\n // render below already refuses to show it.\n useEffect(() => {\n window.clearTimeout(announceTimer.current);\n setAnnouncement((current) => (current.text === '' ? current : SILENCE));\n }, [privacyMode]);\n const spoken =\n announcement.privacyMode === privacyMode\n ? // The same words twice leave the DOM unchanged and a screen reader\n // silent: a trailing no-break space on every other repeat changes\n // the text without changing what is read.\n `${announcement.text}${announcement.repeat % 2 === 1 ? '\\u00a0' : ''}`\n : '';\n\n /* ---- view, sort and groups ------------------------------------------ */\n const [view, setViewState] = useState<HeatmapView>(defaultView);\n\n const setView = useCallback(\n (next: HeatmapView) => {\n setViewState(next);\n onViewChange?.(next);\n announce(\n next === 'table'\n ? t('heatmap.announce.tableView')\n : t('heatmap.announce.heatmapView'),\n );\n },\n [onViewChange, announce, t],\n );\n\n const [sortInternal, setSortInternal] =\n useState<HeatmapSortRows>(defaultSortRows);\n const sortRows = sortRowsProp ?? sortInternal;\n const setSortRows = useCallback(\n (next: HeatmapSortRows) => {\n if (sortRowsProp === undefined) setSortInternal(next);\n onSortRowsChange?.(next);\n },\n [sortRowsProp, onSortRowsChange],\n );\n\n const [collapsed, setCollapsed] = useState<ReadonlySet<string>>(\n () => new Set(defaultCollapsedGroups ?? []),\n );\n const setGroupCollapsed = useCallback(\n (groupId: string, isCollapsed: boolean) => {\n // Already so: nothing changes, so nothing is said.\n if (collapsed.has(groupId) === isCollapsed) return;\n setCollapsed((current) => {\n if (current.has(groupId) === isCollapsed) return current;\n const next = new Set(current);\n if (isCollapsed) next.add(groupId);\n else next.delete(groupId);\n return next;\n });\n const label = describer.groupLabel(groupId);\n announce(\n isCollapsed\n ? t('heatmap.announce.groupCollapsed', { group: label })\n : t('heatmap.announce.groupExpanded', { group: label }),\n );\n },\n [collapsed, announce, describer, t],\n );\n const toggleGroup = useCallback(\n (groupId: string) => setGroupCollapsed(groupId, !collapsed.has(groupId)),\n [collapsed, setGroupCollapsed],\n );\n\n const collator = useMemo(\n () => new Intl.Collator(locale, { numeric: true, sensitivity: 'base' }),\n [locale],\n );\n // A label sort under masked labels would still order the rows by the\n // hidden names, and so reveal their order: in privacy mode it keeps the\n // given order.\n const appliedSort: HeatmapSortRows =\n sortRows === 'label' && describer.masksRows ? 'none' : sortRows;\n\n // Every total, with the ones that would give away a hidden cell\n // withheld (see computeTotals). The audit covers every total this data\n // could show, drawn or not: row totals order the rows in a sort by\n // total, and a change to the sort, the totals props or groupRows must\n // never combine two views into a disclosure. So the result depends on\n // the data alone.\n const totals = useMemo(\n () =>\n computeTotals(matrix, rows, columns, {\n rowMethod,\n columnMethod,\n groupColumnMethod,\n groups,\n minCount,\n getTotal,\n valueType,\n }),\n [\n matrix,\n rows,\n columns,\n rowMethod,\n columnMethod,\n groupColumnMethod,\n groups,\n minCount,\n getTotal,\n valueType,\n ],\n );\n const order = useMemo(\n () =>\n sortRowIndexes(\n rows.map((_, r) => r),\n rows,\n totals.rows,\n appliedSort,\n collator,\n ),\n [rows, totals.rows, appliedSort, collator],\n );\n const body = useMemo(\n () => buildBodyRows(rows, order, groupRows, collapsed),\n [rows, order, groupRows, collapsed],\n );\n /** Every row in display order with every group expanded: the table\n * view's order, and the row ids an agent reads. */\n const expandedBody = useMemo(\n () => buildBodyRows(rows, order, groupRows, new Set()),\n [rows, order, groupRows],\n );\n\n /* ---- cells ---------------------------------------------------------- */\n const rowIndexById = useMemo(\n () => new Map(rows.map((row, r) => [row.id, r])),\n [rows],\n );\n const columnIndexById = useMemo(\n () => new Map(columns.map((column, c) => [String(column.id), c])),\n [columns],\n );\n const columnIndexOfKey = useCallback(\n (columnKey: string) => columnIndexById.get(columnKey),\n [columnIndexById],\n );\n const cellInfo = useCallback(\n (rowIndex: number, columnIndex: number): HeatmapCellInfo => {\n const row = rows[rowIndex];\n const column = columns[columnIndex];\n const cell = matrix[rowIndex][columnIndex];\n return {\n rowId: row.id,\n columnId: column.id,\n row,\n column,\n rowIndex,\n columnIndex,\n value: cell.value,\n count: cell.count,\n label: cell.label,\n status: cell.status,\n step:\n cell.status === 'value' && cell.value !== null\n ? scale.stepOf(cell.value)\n : null,\n };\n },\n [rows, columns, matrix, scale],\n );\n /** The cell as `renderTooltip` may see it in privacy mode: masked\n * labels, no free text, no group id that could be a name. */\n const maskedInfo = useCallback(\n (info: HeatmapCellInfo): HeatmapCellInfo => {\n const group =\n info.row.group === undefined\n ? undefined\n : groupIds.get(info.row.group);\n return {\n rowId: info.rowId,\n columnId: info.columnId,\n row: {\n id: info.row.id,\n label: describer.rowLabel(info.row),\n ...(group === undefined ? {} : { group }),\n },\n column: {\n id: info.column.id,\n label: describer.columnLabel(info.column),\n },\n rowIndex: info.rowIndex,\n columnIndex: info.columnIndex,\n value: info.value,\n count: info.count,\n status: info.status,\n step: info.step,\n };\n },\n [describer, groupIds],\n );\n const tooltipText = useCallback(\n (info: HeatmapCellInfo) =>\n renderTooltip\n ? renderTooltip(privacyMode ? maskedInfo(info) : info, {\n privacyMode,\n })\n : describer.sentence(\n describer.rowLabel(info.row),\n describer.columnLabel(info.column),\n matrix[info.rowIndex][info.columnIndex],\n ),\n [renderTooltip, privacyMode, maskedInfo, describer, matrix],\n );\n\n /* ---- selection ------------------------------------------------------- */\n const isControlled = selectedCells !== undefined;\n const [selectedInternal, setSelectedInternal] = useState<Set<string>>(() =>\n toKeySet(defaultSelectedCells),\n );\n // Keys are row id + column id. Only those naming a current row and\n // column count, so a removed column drops out of the selection instead\n // of pointing at whatever now sits in its place.\n const selected = useMemo(() => {\n const source = isControlled ? toKeySet(selectedCells) : selectedInternal;\n const present = new Set<string>();\n for (const key of source) {\n const [rowId, columnKey] = splitSelectionKey(key);\n if (rowIndexById.has(rowId) && columnIndexById.has(columnKey)) {\n present.add(key);\n }\n }\n return present;\n }, [\n isControlled,\n selectedCells,\n selectedInternal,\n rowIndexById,\n columnIndexById,\n ]);\n\n const infosOf = useCallback(\n (keys: ReadonlySet<string>): HeatmapCellInfo[] => {\n const infos: HeatmapCellInfo[] = [];\n for (const key of keys) {\n const [rowId, columnKey] = splitSelectionKey(key);\n const r = rowIndexById.get(rowId);\n const c = columnIndexById.get(columnKey);\n if (r !== undefined && c !== undefined) infos.push(cellInfo(r, c));\n }\n return infos;\n },\n [rowIndexById, columnIndexById, cellInfo],\n );\n const cellName = useCallback(\n (rowIndex: number, columnIndex: number) =>\n describer.cellName(\n describer.rowLabel(rows[rowIndex]),\n describer.columnLabel(columns[columnIndex]),\n ),\n [describer, rows, columns],\n );\n const commitSelection = useCallback(\n (next: Set<string>, message: string, settle = false) => {\n if (!isControlled) setSelectedInternal(next);\n onSelectionChange?.(infosOf(next));\n announce(message, settle);\n },\n [isControlled, onSelectionChange, infosOf, announce],\n );\n const countMessage = useCallback(\n (count: number) =>\n count === 0\n ? t('heatmap.announce.cleared')\n : t('heatmap.announce.count', {\n count,\n formatted: formatCount(count),\n }),\n [t, formatCount],\n );\n\n /** The visible data rows in display order, for range rectangles. */\n const dataOrder = useMemo(\n () => body.flatMap((row) => (row.kind === 'data' ? [row.rowIndex] : [])),\n [body],\n );\n const rectangle = useCallback(\n (\n from: { rowIndex: number; col: number },\n to: { rowIndex: number; col: number },\n ) => {\n const a = dataOrder.indexOf(from.rowIndex);\n const b = dataOrder.indexOf(to.rowIndex);\n const next = new Set<string>();\n if (a === -1 || b === -1) return next;\n const [top, bottom] = a <= b ? [a, b] : [b, a];\n const [left, right] =\n from.col <= to.col ? [from.col, to.col] : [to.col, from.col];\n for (let i = top; i <= bottom; i += 1) {\n const rowId = rows[dataOrder[i]].id;\n for (let c = left; c <= right; c += 1) {\n next.add(selectionKey(rowId, columns[c].id));\n }\n }\n return next;\n },\n [dataOrder, rows, columns],\n );\n\n const onActivate = useCallback(\n (rowIndex: number, columnIndex: number, select: boolean) => {\n onCellClick?.(cellInfo(rowIndex, columnIndex));\n if (!select || selection === 'none') return;\n const key = selectionKey(rows[rowIndex].id, columns[columnIndex].id);\n const name = cellName(rowIndex, columnIndex);\n if (selection === 'multiple') {\n const next = new Set(selected);\n const adding = !next.has(key);\n if (adding) next.add(key);\n else next.delete(key);\n commitSelection(\n next,\n t(adding ? 'heatmap.announce.added' : 'heatmap.announce.removed', {\n cell: name,\n count: next.size,\n formatted: formatCount(next.size),\n }),\n );\n return;\n }\n // Single and range: the cell becomes the whole selection (a range's\n // anchor); selecting the only selected cell again clears it.\n const clearing = selected.size === 1 && selected.has(key);\n commitSelection(\n clearing ? new Set() : new Set([key]),\n clearing\n ? t('heatmap.announce.cleared')\n : t('heatmap.announce.selected', { cell: name }),\n );\n },\n [\n onCellClick,\n cellInfo,\n selection,\n rows,\n columns,\n cellName,\n selected,\n commitSelection,\n formatCount,\n t,\n ],\n );\n\n const onRange = useCallback(\n (\n from: { rowIndex: number; col: number },\n to: { rowIndex: number; col: number },\n ) => {\n if (selection !== 'range' && selection !== 'multiple') return;\n const next = rectangle(from, to);\n if (\n next.size === selected.size &&\n [...next].every((key) => selected.has(key))\n ) {\n return;\n }\n commitSelection(next, countMessage(next.size), true);\n },\n [selection, rectangle, selected, commitSelection, countMessage],\n );\n\n /* ---- agent handle ------------------------------------------------------ */\n const groupByPublicId = useMemo(\n () => new Map([...groupIds].map(([own, shown]) => [shown, own])),\n [groupIds],\n );\n const agentState = {\n selected,\n selection,\n view,\n sortRows,\n collapsed,\n groupRows,\n rows,\n columns,\n expandedBody,\n groupIds,\n groupByPublicId,\n rowIndexById,\n columnIndexById,\n matrix,\n scale,\n setView,\n setSortRows,\n setGroupCollapsed,\n commitSelection,\n rectangle,\n countMessage,\n };\n const latest = useRef(agentState);\n latest.current = agentState;\n const agentHandle = useMemo<HeatmapHandle>(() => {\n const keysOf = (set: ReadonlySet<string>): HeatmapCellKey[] => {\n const { columns: cols, columnIndexById: byColumn } = latest.current;\n const keys: HeatmapCellKey[] = [];\n for (const key of set) {\n const [rowId, columnKey] = splitSelectionKey(key);\n const c = byColumn.get(columnKey);\n // The column's own id, number or string, as the consumer gave it.\n if (c !== undefined) keys.push({ rowId, columnId: cols[c].id });\n }\n return keys;\n };\n const position = (cell: HeatmapCellKey) => {\n const { rowIndexById: byRow, columnIndexById: byColumn } =\n latest.current;\n const rowIndex = byRow.get(cell.rowId);\n const col = byColumn.get(String(cell.columnId));\n return rowIndex === undefined || col === undefined\n ? null\n : { rowIndex, col };\n };\n /** Throws on an unknown cell, before anything changes or is said. */\n const requireCell = (cell: HeatmapCellKey) => {\n const at = position(cell);\n if (!at) {\n throw new Error(\n `Heatmap: no cell at row \"${cell.rowId}\", column \"${String(cell.columnId)}\".`,\n );\n }\n return at;\n };\n const requireSelection = () => {\n if (latest.current.selection === 'none') {\n throw new Error('Heatmap: selection is off (selection=\"none\").');\n }\n };\n return {\n getSelection: () => keysOf(latest.current.selected),\n getSelectionMode: () => latest.current.selection,\n selectCells: (cellsToSelect) => {\n requireSelection();\n cellsToSelect.forEach(requireCell);\n const { selection: mode } = latest.current;\n const picked =\n mode === 'single' ? cellsToSelect.slice(0, 1) : cellsToSelect;\n const next = toKeySet(picked);\n latest.current.commitSelection(\n next,\n latest.current.countMessage(next.size),\n );\n },\n selectRange: (from, to) => {\n const { selection: mode } = latest.current;\n if (mode !== 'range' && mode !== 'multiple') {\n throw new Error(\n 'Heatmap: select_range needs selection=\"range\" or \"multiple\".',\n );\n }\n const a = requireCell(from);\n const b = requireCell(to);\n const next = latest.current.rectangle(a, b);\n latest.current.commitSelection(\n next,\n latest.current.countMessage(next.size),\n );\n },\n clearSelection: () => {\n requireSelection();\n if (latest.current.selected.size === 0) return;\n latest.current.commitSelection(\n new Set(),\n latest.current.countMessage(0),\n );\n },\n readCell: (cell) => {\n const at = position(cell);\n if (!at) return null;\n const model = latest.current.matrix[at.rowIndex][at.col];\n return {\n value: model.value,\n count: model.count,\n status: model.status,\n step:\n model.status === 'value' && model.value !== null\n ? latest.current.scale.stepOf(model.value)\n : null,\n };\n },\n getView: () => latest.current.view,\n setView: (next) => latest.current.setView(next),\n getSortRows: () => latest.current.sortRows,\n setSortRows: (next) => latest.current.setSortRows(next),\n getRowIds: () => {\n const { expandedBody: shown, rows: all } = latest.current;\n return shown.flatMap((row) =>\n row.kind === 'data' ? [all[row.rowIndex].id] : [],\n );\n },\n getColumnIds: () => latest.current.columns.map((column) => column.id),\n getGroupIds: () => {\n const {\n groupRows: grouped,\n expandedBody: shown,\n groupIds: ids,\n } = latest.current;\n if (!grouped) return [];\n return shown.flatMap((row) =>\n row.kind === 'group' ? [ids.get(row.groupId) ?? ''] : [],\n );\n },\n getCollapsedGroups: () => {\n const { collapsed: hidden, groupIds: ids } = latest.current;\n return [...hidden].flatMap((own) => {\n const shown = ids.get(own);\n return shown === undefined ? [] : [shown];\n });\n },\n setGroupCollapsed: (groupId, isCollapsed) => {\n const { groupRows: grouped, groupByPublicId: byShown } =\n latest.current;\n if (!grouped) {\n throw new Error(\n 'Heatmap: rows are not grouped (groupRows is off).',\n );\n }\n const own = byShown.get(groupId);\n if (own === undefined) {\n throw new Error(`Heatmap: no group \"${groupId}\".`);\n }\n latest.current.setGroupCollapsed(own, isCollapsed);\n },\n };\n }, []);\n useAgentRegistration(heatmapAgent, agentHandle, id);\n\n /* ---- context ----------------------------------------------------------- */\n const hasEmpty = useMemo(\n () => matrix.some((row) => row.some((cell) => cell.status === 'empty')),\n [matrix],\n );\n // The legend keys a withheld total apart from a low-sample cell, but\n // only for totals the grid draws (every total is worked out and\n // audited, drawn or not).\n const hasWithheldTotal = useMemo(() => {\n const low = (cell: ModelCell) => cell.status === 'low-sample';\n const groupCells = groupRows\n ? [...totals.groupColumns.values()].flat()\n : [];\n const groupTotals = groupRows ? [...totals.groups.values()] : [];\n return (\n groupCells.some(low) ||\n (rowTotals !== false &&\n (totals.rows.some(low) || groupTotals.some(low))) ||\n (columnTotals !== false &&\n (totals.columns.some(low) ||\n (rowTotals !== false && low(totals.grand))))\n );\n }, [totals, rowTotals, columnTotals, groupRows]);\n const hasLowSample = useMemo(\n () =>\n matrix.some((row) => row.some((cell) => cell.status === 'low-sample')),\n [matrix],\n );\n const context = useMemo<HeatmapContextValue>(\n () => ({\n palette,\n scale,\n describer,\n hasEmpty,\n hasLowSample,\n hasWithheldTotal,\n minCount,\n tooltipText,\n }),\n [\n palette,\n scale,\n describer,\n hasEmpty,\n hasLowSample,\n hasWithheldTotal,\n minCount,\n tooltipText,\n ],\n );\n\n /* ---- render ------------------------------------------------------------ */\n const rootClassName = heatmapRootVariants({ className });\n\n if (loading) {\n return (\n <HeatmapContext.Provider value={context}>\n <div\n ref={ref}\n data-component=\"heatmap\"\n data-component-id={id}\n className={rootClassName}\n >\n <div\n role=\"status\"\n aria-label={t('heatmap.loading')}\n aria-busy=\"true\"\n className={heatmapRootVariants()}\n >\n <Skeleton\n variant=\"rectangular\"\n className=\"ds:h-[var(--spacing-md)] ds:w-[calc(var(--spacing-xl)*6)] ds:max-w-full\"\n />\n <Skeleton\n variant=\"rectangular\"\n className=\"ds:h-[calc(var(--min-target-size)*5)] ds:w-full\"\n />\n </div>\n {children}\n </div>\n </HeatmapContext.Provider>\n );\n }\n\n if (rows.length === 0 || columns.length === 0 || !hasAnyData(matrix)) {\n return (\n <HeatmapContext.Provider value={context}>\n <div\n ref={ref}\n data-component=\"heatmap\"\n data-component-id={id}\n className={rootClassName}\n >\n <EmptyState\n variant=\"no-results\"\n size=\"sm\"\n title={t('heatmap.empty.title')}\n description={t('heatmap.empty.description')}\n />\n {children}\n </div>\n </HeatmapContext.Provider>\n );\n }\n\n const virtualised =\n rows.length * columns.length > VIRTUALISE_CELL_THRESHOLD;\n const interactive = selection !== 'none' || onCellClick !== undefined;\n\n return (\n <HeatmapContext.Provider value={context}>\n <div\n ref={ref}\n data-component=\"heatmap\"\n data-component-id={id}\n className={rootClassName}\n >\n <div className={heatmapToolbarVariants()}>\n {legend !== false ? <HeatmapLegend variant={legend} /> : null}\n <Button\n intent=\"outline\"\n size=\"sm\"\n className=\"ds:ms-auto\"\n startIcon={\n view === 'table' ? (\n <Grid3x3 aria-hidden=\"true\" />\n ) : (\n <Table2 aria-hidden=\"true\" />\n )\n }\n // Fetch the table chunk on intent, so the switch rarely waits.\n onPointerEnter={\n view === 'table' ? undefined : preloadHeatmapTable\n }\n onFocus={view === 'table' ? undefined : preloadHeatmapTable}\n onClick={() => setView(view === 'table' ? 'heatmap' : 'table')}\n >\n {view === 'table'\n ? t('heatmap.viewAsHeatmap')\n : t('heatmap.viewAsTable')}\n </Button>\n </div>\n {view === 'table' ? (\n <HeatmapTableView\n // A new table when the privacy setting changes: AG Grid applies\n // new row data a frame later, and the old labels must not\n // show for that frame.\n key={`${privacyMode}-${privacyScope}`}\n onLoadError={() => announce(t('heatmap.announce.tableFailed'))}\n title={title}\n rowsLabel={rowsLabel}\n rows={rows}\n columns={columns}\n matrix={matrix}\n body={expandedBody}\n grouped={groupRows}\n groupIds={groupIds}\n describer={describer}\n totals={totals}\n rowTotals={rowTotals}\n columnTotals={columnTotals}\n groupColumnMethod={groupColumnMethod}\n />\n ) : (\n <TooltipProvider delayDuration={0}>\n <HeatmapGrid\n title={title}\n rowsLabel={rowsLabel}\n rows={rows}\n columns={columns}\n matrix={matrix}\n body={body}\n scale={scale}\n palette={palette}\n describer={describer}\n showValues={showValues}\n totals={totals}\n rowTotals={rowTotals}\n columnTotals={columnTotals}\n groupColumnMethod={groupColumnMethod}\n groupIds={groupIds}\n selectionMode={selection}\n selected={selected}\n columnIndexOfKey={columnIndexOfKey}\n interactive={interactive}\n virtualised={virtualised}\n size={size}\n density={density}\n cellInfo={cellInfo}\n tooltipText={tooltipText}\n describeFocused={renderTooltip !== undefined}\n onActivate={onActivate}\n onRange={onRange}\n onToggleGroup={toggleGroup}\n />\n </TooltipProvider>\n )}\n {children}\n {/* A fresh region when the privacy setting changes: LiveRegion\n shows its text from an effect, so a kept one would show a\n message made before privacy mode for one more render. */}\n <LiveRegion key={String(privacyMode)}>{spoken}</LiveRegion>\n </div>\n </HeatmapContext.Provider>\n );\n },\n);\n\nHeatmapRoot.displayName = 'Heatmap';\n\n/**\n * Heatmap: a grid of cells coloured by value on a token scale, for patterns\n * such as chair occupancy by hour or no-shows by weekday and hour. Keyboard,\n * screen reader and table view are built in; see heatmap.mdx.\n */\nexport const Heatmap = Object.assign(HeatmapRoot, {\n Legend: HeatmapLegend,\n Tooltip: HeatmapTooltip,\n});\n"],"names":["__iconNode","Grid3x3","createLucideIcon","Table2","cellSchema","heatmapAgent","handle","args","next","HeatmapContext","createContext","useHeatmapContext","useContext","defaultValueFormatter","locale","valueType","format","value","countFormatter","count","EMPTY_GLYPH","createDescriber","t","privacyMode","privacyScope","formatValue","formatCount","groups","groupNames","group","mask","privacyMask","masksRows","masksColumns","masksGroups","valueText","cell","countText","row","column","groupId","rowText","columnText","groupText","method","BIG","AUDIT_WORK_LIMIT","WORK_LIMIT","work","OUT_OF_WORK","OPENINGS_PER_ROUND","spend","edges","makeGraph","n","maxEdges","addEdge","g","u","v","id","augment","cap","s","limit","skip","eps","parent","queue","skipPair","pushed","scanned","qh","qt","found","e","bottleneck","reach","seen","protectionNeed","problem","records","arcBounds","shown","lo","hi","free","total","i","base","c","endpoints","arc","totals","feasibleNetwork","arcs","excess","a","superSource","superSink","demand","flow","graph","residual","fixed","pathExists","openings","extra","cheapestOpening","net","dist","via","from","done","heap","pushHeap","item","up","popHeap","top","last","l","r","m","better","b","best","d","cost","picked","narrowCells","check","firstOnly","failed","disclosures","pinned","whole","move","extraOf","opened","safe","upAsked","downAsked","down","need","f","lift","open","pinnedTotals","_","determinedSets","root","find","join","ra","rb","edgeMap","key","edge","x","y","ids","local","out","scc","index","low","onStack","stack","counter","sccCount","start","frame","w","parentV","dag","dagCells","entry","dagEdges","nodes","nodeIndex","k","part","partOf","sccSide","side","nodeSide","inGraph","sccIn","blob","record","cells","direct","indirect","candidates","roots","p","freePinned","adj","disc","time","viaArc","audit","pickTotals","remaining","cover","secureTotals","spentBefore","secure","error","holdsHidden","list","auditWorkSpent","scale","everyHolder","isShown","allCells","added","maxRounds","round","offers","offerBack","near","order","HEATMAP_STEPS","MIDDLE_STEP","TOP_STEP","HALF_STEPS","clamp","high","warned","warn","message","isDevelopment","orderedDomain","domain","distinctSorted","values","sorted","extent","sequentialStep","divergingStep","midpoint","span","onMidpoint","magnitude","quantileSorted","position","below","above","quantileThresholds","buckets","usableQuantileEdges","min","atOrAbove","mid","thresholdBucket","thresholds","bucketStep","bucket","bucketCount","resolveScale","range","given","distinct","sumOf","counted","weightedMean","weighted","weights","weight","aggregate","publicGroupIds","rows","listed","taken","fallback","isLowSample","minCount","toModelCell","input","data","status","buildMatrix","columns","getCell","_a","shownValues","matrix","hasAnyData","WITHHELD_TOTAL","ALL_SHOWN","computedTotal","result","computeTotals","options","rowMethod","columnMethod","groupColumnMethod","groupList","getTotal","shownKinds","allRows","allColumns","drafts","draft","supplied","rowIndexes","columnIndexes","visible","hidden","unknown","own","primary","rowDrafts","members","groupEntries","groupScope","indexes","groupColumnDrafts","scope","columnDrafts","groupDrafts","grandDraft","withheld","secureDrafts","keep","cellOf","shownBefore","methods","withholdHolders","weightOf","rate","isUnknown","SOURCE","SINK","GRAND","groupNode","rowNode","gcNode","columnCount","columnNode","groupOf","arcOf","cellTotals","integral","nonNegative","cellsInRow","holders","nearWhole","wholeData","countsDisagree","printed","parts","exact","rounded","unknowns","wholeRounded","mode","auditWith","onPrinted","spendFrom","tolerance","first","dataRowKey","rowId","groupRowKey","FOOTER_ROW_KEY","sortRowIndexes","sort","collator","direction","left","right","_b","buildBodyRows","sortedIndexes","groupRows","collapsed","loose","body","isCollapsed","HeatmapTooltip","label","onOpenChange","children","context","text","jsx","Tooltip","HeatmapCellTooltip","VIRTUALISE_CELL_THRESHOLD","OVERSCAN","visibleRange","offset","viewport","lead","pitch","overscan","end","axisWindow","fullWindow","trimWindow","window","sameWindow","stepTone","palette","step","toneClasses","heatmapRootVariants","cva","heatmapToolbarVariants","heatmapScrollerVariants","heatmapTableViewVariants","heatmapGridVariants","heatmapRowVariants","heatmapSpacerVariants","headerHighlight","heatmapColumnHeaderVariants","heatmapRowHeaderVariants","heatmapRowLabelVariants","heatmapCellVariants","heatmapLegendVariants","heatmapLegendBarVariants","heatmapSwatchVariants","KEY_SEPARATOR","selectionKey","columnId","splitSelectionKey","at","toneOf","NO_TOTAL","aggregateTone","renderColumns","render","columnIndex","HeatmapBodyRow","memo","ctx","ariaRowIndex","highlighted","activeCol","tooltipCol","selectedCols","selected","useMemo","hookId","labelId","perColumn","overall","groupCell","withTooltip","name","jsxs","perColumnRowText","event","ChevronDown","source","dataCell","isSelected","totalCell","DEFAULT_METRICS","pageRows","metrics","HeatmapGrid","props","title","rowsLabel","describer","showValues","rowTotals","columnTotals","groupIds","selectionMode","columnIndexOfKey","interactive","virtualised","size","density","cellInfo","tooltipText","describeFocused","onActivate","onRange","onToggleGroup","useTranslation","idBase","useId","scrollerRef","useRef","gridRef","headerRef","footerRef","navColumnCount","hasFooter","navRowKeys","rowIndexOfKey","map","active","setActive","useState","activeRow","activeKey","pendingFocus","hasFocus","setHasFocus","hasFocusRef","interaction","hover","setHover","hoverRef","tooltipDismissed","setTooltipDismissed","updateHover","useCallback","current","highlight","tooltipAt","setMetrics","metricsRef","measure","scroller","grid","style","rowGap","columnGap","tracks","track","headerHeight","firstBody","bodyHeight","useIsomorphicLayoutEffect","observer","pinnedRow","pinnedCol","computeWindows","rowRange","colRange","windowState","setWindows","fullRows","fullCols","windows","syncWindows","onScroll","useEffect","cellElement","rowIndex","col","element","isRtl","anchor","dataRowIndexAt","navIndex","clearOnClick","moveTo","clampedRow","clampedCol","activate","extend","onKeyDown","lastRow","lastCol","forward","ctrl","nextGroup","previous","moved","isArrow","target","positionOf","rowElement","dragging","lastPointer","onPointerDown","stop","onPointerMove","awayListener","stopAway","onPointerLeave","away","over","onClick","button","scrolling","settle","onAnyScroll","onTooltipOpenChange","expandLabel","collapseLabel","descriptionId","focusedRow","description","selectedByRow","columnKey","joined","highlightCol","header","footer","footerIndex","methodText","footerActive","bodyRows","rowWindow","isActiveRow","scrollerStyle","STEPS","endLabels","HeatmapLegend","forwardRef","variant","paletteProp","scaleProp","valueFormatter","showEmpty","showLowSample","showWithheldTotal","minCountProp","className","ref","i18n","formatLocale","banded","bandCount","bandSteps","band","labels","singleStep","withEmpty","withLowSample","withWithheldTotal","shape","bar","steps","Fragment","loadDataTable","module","LazyDataTable","lazy","preloadHeatmapTable","HeatmapTableView","grouped","onLoadError","columnDefs","params","rowData","pinnedBottomRowData","rowCount","rowCountRef","cappedAt","setCappedAt","capped","wrapperRef","wrapper","watch","child","gridOptions","attempt","setAttempt","DataTable","ErrorBoundary","Suspense","Skeleton","DEFAULT_SCALE","toKeySet","SILENCE","HeatmapRoot","legend","sortRowsProp","defaultSortRows","onSortRowsChange","defaultCollapsedGroups","selection","selectedCells","defaultSelectedCells","onSelectionChange","onCellClick","renderTooltip","loading","defaultView","onViewChange","scaleKey","announcement","setAnnouncement","announceTimer","privacyRef","announce","madeUnder","say","spoken","view","setViewState","setView","sortInternal","setSortInternal","sortRows","setSortRows","setCollapsed","setGroupCollapsed","toggleGroup","appliedSort","expandedBody","rowIndexById","columnIndexById","maskedInfo","info","isControlled","selectedInternal","setSelectedInternal","present","infosOf","keys","infos","cellName","commitSelection","countMessage","dataOrder","rectangle","to","bottom","select","adding","clearing","groupByPublicId","agentState","latest","agentHandle","keysOf","set","cols","byColumn","byRow","requireCell","requireSelection","cellsToSelect","model","all","byShown","useAgentRegistration","hasEmpty","hasWithheldTotal","groupCells","groupTotals","hasLowSample","rootClassName","EmptyState","Button","TooltipProvider","LiveRegion","Heatmap"],"mappings":"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","x_google_ignoreList":[0,1]}
|
|
1
|
+
{"version":3,"file":"heatmap-fCxwNz2o.js","sources":["../../node_modules/lucide-react/dist/esm/icons/grid-3x3.mjs","../../node_modules/lucide-react/dist/esm/icons/table-2.mjs","../../src/components/heatmap/heatmap.agent.ts","../../src/components/heatmap/heatmap-context.ts","../../src/components/heatmap/heatmap-format.ts","../../src/components/heatmap/heatmap-disclosure.ts","../../src/components/heatmap/heatmap-scale.ts","../../src/components/heatmap/heatmap-model.ts","../../src/components/heatmap/heatmap-tooltip.tsx","../../src/components/heatmap/heatmap-window.ts","../../src/components/heatmap/heatmap-variants.ts","../../src/components/heatmap/heatmap-grid.tsx","../../src/components/heatmap/heatmap-legend.tsx","../../src/components/heatmap/heatmap-table-view.tsx","../../src/components/heatmap/heatmap.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M3 9h18\", key: \"1pudct\" }],\n [\"path\", { d: \"M3 15h18\", key: \"5xshup\" }],\n [\"path\", { d: \"M9 3v18\", key: \"fh3hqa\" }],\n [\"path\", { d: \"M15 3v18\", key: \"14nvp0\" }]\n];\nconst Grid3x3 = createLucideIcon(\"grid-3x3\", __iconNode);\n\nexport { __iconNode, Grid3x3 as default };\n//# sourceMappingURL=grid-3x3.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M9 3H5a2 2 0 0 0-2 2v4m6-6h10a2 2 0 0 1 2 2v4M9 3v18m0 0h10a2 2 0 0 0 2-2V9M9 21H5a2 2 0 0 1-2-2V9m0 0h18\",\n key: \"gugj83\"\n }\n ]\n];\nconst Table2 = createLucideIcon(\"table-2\", __iconNode);\n\nexport { __iconNode, Table2 as default };\n//# sourceMappingURL=table-2.mjs.map\n","/* -------------------------------------------------------------------- */\n/* Agent adapter: Heatmap. */\n/* */\n/* Operations go through the curated `HeatmapHandle`. State returns ids, */\n/* numbers and structure only: never a row, column or group label, which */\n/* may name a person (src/docs/26-agent-readiness.mdx §7). The row, */\n/* column and group ids are state so an agent can address any cell, even */\n/* one a virtualised grid has not rendered. Every write rejects an id */\n/* the heatmap does not have before it changes or announces anything. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { HeatmapHandle } from './heatmap';\n\nconst cellSchema = {\n type: 'object',\n properties: {\n rowId: { type: 'string', description: 'Row id, from rowIds.' },\n columnId: {\n type: ['string', 'number'],\n description: 'Column id, from columnIds.',\n },\n },\n required: ['rowId', 'columnId'],\n} as const;\n\nexport const heatmapAgent: AgentAdapter<HeatmapHandle> = {\n id: 'heatmap',\n capabilities: [\n 'select_single',\n 'select_multiple',\n 'range_pick',\n 'expand',\n 'sort',\n 'view_change',\n ],\n state: {\n selection: {\n type: 'Array<{ rowId, columnId }>',\n descriptionKey: 'ui.agent.heatmap.state.selection',\n description: 'Row and column ids of the selected cells.',\n read: (handle) => handle.getSelection(),\n },\n selectionMode: {\n type: \"'none' | 'single' | 'multiple' | 'range'\",\n descriptionKey: 'ui.agent.heatmap.state.selectionMode',\n description: 'How cells can be selected in this heatmap.',\n read: (handle) => handle.getSelectionMode(),\n },\n view: {\n type: \"'heatmap' | 'table'\",\n descriptionKey: 'ui.agent.heatmap.state.view',\n description: 'Whether the heatmap or its table view is showing.',\n read: (handle) => handle.getView(),\n },\n sortRows: {\n type: \"'none' | 'label' | 'total-asc' | 'total-desc'\",\n descriptionKey: 'ui.agent.heatmap.state.sortRows',\n description: 'Current row order.',\n read: (handle) => handle.getSortRows(),\n },\n rowIds: {\n type: 'string[]',\n descriptionKey: 'ui.agent.heatmap.state.rowIds',\n description:\n 'Row ids in display order, every group expanded. Opaque, never a label.',\n read: (handle) => handle.getRowIds(),\n },\n columnIds: {\n type: 'Array<string | number>',\n descriptionKey: 'ui.agent.heatmap.state.columnIds',\n description: 'Column ids in order. Opaque, never a label.',\n read: (handle) => handle.getColumnIds(),\n },\n groupIds: {\n type: 'string[]',\n descriptionKey: 'ui.agent.heatmap.state.groupIds',\n description:\n 'Group ids in display order, empty unless rows are grouped. A group not listed in `groups` shows as group-1, group-2 and so on.',\n read: (handle) => handle.getGroupIds(),\n },\n collapsedGroups: {\n type: 'string[]',\n descriptionKey: 'ui.agent.heatmap.state.collapsedGroups',\n description: 'Ids (as in groupIds) of the row groups that are collapsed.',\n read: (handle) => handle.getCollapsedGroups(),\n },\n },\n actions: {\n select_cell: {\n safety: 'read',\n argsType: '{ rowId: string, columnId: string | number }',\n argsSchema: cellSchema,\n idempotent: true,\n descriptionKey: 'ui.agent.heatmap.actions.selectCell',\n description: 'Make one cell the whole selection.',\n errors: [\n 'Selection is off (selection=\"none\").',\n 'The row or column id does not exist.',\n ],\n examples: [\n {\n args: { rowId: 'chair-1', columnId: 10 },\n note: 'Select chair 1 at 10:00.',\n },\n ],\n invoke: (handle, args: { rowId: string; columnId: string | number }) => {\n handle.selectCells([args]);\n },\n },\n select_cells: {\n safety: 'read',\n argsType: '{ cells: Array<{ rowId, columnId }> }',\n argsSchema: {\n type: 'object',\n properties: {\n cells: {\n type: 'array',\n items: cellSchema,\n description:\n 'Cells to select; replaces the selection. Single mode keeps the first.',\n },\n },\n required: ['cells'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.heatmap.actions.selectCells',\n description: 'Replace the selection with the given cells.',\n errors: [\n 'Selection is off (selection=\"none\").',\n 'A row or column id does not exist; nothing is selected.',\n ],\n invoke: (\n handle,\n args: { cells: { rowId: string; columnId: string | number }[] },\n ) => {\n handle.selectCells(args.cells);\n },\n },\n select_range: {\n safety: 'read',\n argsType: '{ from: { rowId, columnId }, to: { rowId, columnId } }',\n argsSchema: {\n type: 'object',\n properties: {\n from: { ...cellSchema, description: 'One corner, inclusive.' },\n to: { ...cellSchema, description: 'The opposite corner, inclusive.' },\n },\n required: ['from', 'to'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.heatmap.actions.selectRange',\n description:\n 'Select the rectangle of cells between two corners, in the rows as shown.',\n errors: [\n 'Needs selection=\"range\" or \"multiple\".',\n 'A corner names a row or column that does not exist.',\n ],\n invoke: (\n handle,\n args: {\n from: { rowId: string; columnId: string | number };\n to: { rowId: string; columnId: string | number };\n },\n ) => {\n handle.selectRange(args.from, args.to);\n },\n },\n clear_selection: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.heatmap.actions.clearSelection',\n description: 'Deselect every cell.',\n errors: ['Selection is off (selection=\"none\").'],\n invoke: (handle) => {\n handle.clearSelection();\n },\n },\n read_cell: {\n safety: 'read',\n argsType: '{ rowId: string, columnId: string | number }',\n argsSchema: cellSchema,\n returns: '{ value, count, status, step } | null',\n returnsSchema: {\n type: ['object', 'null'],\n properties: {\n value: { type: ['number', 'null'] },\n count: { type: 'number' },\n status: { enum: ['value', 'empty', 'low-sample'] },\n step: { type: ['number', 'null'] },\n },\n },\n idempotent: true,\n descriptionKey: 'ui.agent.heatmap.actions.readCell',\n description:\n \"Read a cell's value, count, status and colour step (no labels).\",\n invoke: (handle, args: { rowId: string; columnId: string | number }) =>\n handle.readCell(args),\n },\n toggle_table_view: {\n safety: 'read',\n descriptionKey: 'ui.agent.heatmap.actions.toggleTableView',\n description: 'Switch between the heatmap and its table view.',\n returns: \"'heatmap' | 'table'\",\n returnsSchema: { enum: ['heatmap', 'table'] },\n invoke: (handle) => {\n const next = handle.getView() === 'table' ? 'heatmap' : 'table';\n handle.setView(next);\n return next;\n },\n },\n set_view: {\n safety: 'read',\n argsType: \"{ view: 'heatmap' | 'table' }\",\n argsSchema: {\n type: 'object',\n properties: {\n view: {\n enum: ['heatmap', 'table'],\n description: 'The coloured grid, or the same data as a table.',\n },\n },\n required: ['view'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.heatmap.actions.setView',\n description: 'Show the heatmap or its table view.',\n invoke: (handle, args: { view: 'heatmap' | 'table' }) => {\n if (handle.getView() !== args.view) handle.setView(args.view);\n },\n },\n sort_rows: {\n safety: 'read',\n argsType: \"{ sort: 'none' | 'label' | 'total-asc' | 'total-desc' }\",\n argsSchema: {\n type: 'object',\n properties: {\n sort: {\n enum: ['none', 'label', 'total-asc', 'total-desc'],\n description:\n 'Row order within each group: as given, by label, or by row total.',\n },\n },\n required: ['sort'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.heatmap.actions.sortRows',\n description: 'Reorder the rows.',\n invoke: (\n handle,\n args: { sort: 'none' | 'label' | 'total-asc' | 'total-desc' },\n ) => {\n handle.setSortRows(args.sort);\n },\n },\n expand_group: {\n safety: 'read',\n argsType: '{ groupId: string }',\n argsSchema: {\n type: 'object',\n properties: {\n groupId: { type: 'string', description: 'Group id, from groupIds.' },\n },\n required: ['groupId'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.heatmap.actions.expandGroup',\n description: \"Show a group's rows.\",\n errors: [\n 'Rows are not grouped (groupRows is off).',\n 'The group id does not exist (see groupIds).',\n ],\n invoke: (handle, args: { groupId: string }) => {\n handle.setGroupCollapsed(args.groupId, false);\n },\n },\n collapse_group: {\n safety: 'read',\n argsType: '{ groupId: string }',\n argsSchema: {\n type: 'object',\n properties: {\n groupId: { type: 'string', description: 'Group id, from groupIds.' },\n },\n required: ['groupId'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.heatmap.actions.collapseGroup',\n description: \"Hide a group's rows, leaving its totals row.\",\n errors: [\n 'Rows are not grouped (groupRows is off).',\n 'The group id does not exist (see groupIds).',\n ],\n invoke: (handle, args: { groupId: string }) => {\n handle.setGroupCollapsed(args.groupId, true);\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'heatmap',\n description: 'Marks the Heatmap root.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop on Heatmap.',\n },\n item: {\n attr: 'data-heatmap-cell-id',\n description:\n 'On every data cell: \"<rowId>:<columnId>\", built from the opaque ids, never from labels. A group header row and its cells carry data-heatmap-group-id, the group id as in groupIds.',\n },\n },\n};\n","/* -------------------------------------------------------------------- */\n/* Context shared by the Heatmap root and its compound parts, so */\n/* Heatmap.Legend and Heatmap.Tooltip read the same scale, palette and */\n/* wording as the grid. */\n/* -------------------------------------------------------------------- */\n\nimport { createContext, useContext } from 'react';\nimport type { HeatmapDescriber } from './heatmap-format';\nimport type { HeatmapCellInfo } from './heatmap-model';\nimport type { ResolvedHeatmapScale } from './heatmap-scale';\nimport type { HeatmapPalette } from './heatmap-variants';\n\nexport interface HeatmapContextValue {\n palette: HeatmapPalette;\n scale: ResolvedHeatmapScale;\n describer: HeatmapDescriber;\n /** True when some cells fall below `minCount`, so the legend explains it. */\n hasLowSample: boolean;\n /** True when a total the grid draws is withheld to protect small\n * numbers. It may rest on many records, so the legend keys it apart. */\n hasWithheldTotal: boolean;\n /** True when some cells have no data. */\n hasEmpty: boolean;\n /** The sample threshold, when one is set. */\n minCount?: number;\n /** The tooltip text for a cell: the consumer's, or the default sentence. */\n tooltipText: (cell: HeatmapCellInfo) => string;\n}\n\nexport const HeatmapContext = createContext<HeatmapContextValue | null>(null);\n\n/** The surrounding Heatmap's context, or null outside one. */\nexport function useHeatmapContext(): HeatmapContextValue | null {\n return useContext(HeatmapContext);\n}\n","/* -------------------------------------------------------------------- */\n/* Heatmap text: number formats in the active locale, and the sentences */\n/* the cells, totals, tooltip and table view share, with privacy mode */\n/* applied in one place. */\n/* -------------------------------------------------------------------- */\n\nimport type { TFunction } from 'i18next';\nimport { privacyMask } from '../_shared/privacy-mask';\nimport type {\n HeatmapColumn,\n HeatmapGroup,\n HeatmapRow,\n ModelCell,\n} from './heatmap-model';\nimport type { HeatmapAggregate } from './heatmap-scale';\n\n/** What the values are: plain numbers, or rates between 0 and 1. */\nexport type HeatmapValueType = 'number' | 'rate';\n\n/**\n * What privacy mode masks. `rows`: the row labels, which name people,\n * chairs or patients. `all`: the column and group labels too. The kit rule\n * (src/components/_shared/privacy-mask.tsx) is to mask the identity and keep\n * time, place and status, so columns (hours, days) and groups (practices)\n * stay readable unless the host asks for more.\n */\nexport type HeatmapPrivacyScope = 'rows' | 'all';\n\n/** The default value format: a percentage for rates, a decimal otherwise. */\nexport function defaultValueFormatter(\n locale: string,\n valueType: HeatmapValueType,\n): (value: number) => string {\n const format = new Intl.NumberFormat(\n locale,\n valueType === 'rate'\n ? { style: 'percent', maximumFractionDigits: 0 }\n : { maximumFractionDigits: 2 },\n );\n return (value) => format.format(value);\n}\n\n/** Whole-number format for counts. */\nexport function countFormatter(locale: string): (count: number) => string {\n const format = new Intl.NumberFormat(locale, { maximumFractionDigits: 0 });\n return (count) => format.format(count);\n}\n\n/** Builds every sentence the heatmap speaks or shows. */\nexport interface HeatmapDescriber {\n /** True when privacy mode hides the row labels. */\n masksRows: boolean;\n /** True when privacy mode hides the column labels. */\n masksColumns: boolean;\n /** True when privacy mode hides the group labels. */\n masksGroups: boolean;\n rowLabel: (row: HeatmapRow) => string;\n columnLabel: (column: HeatmapColumn) => string;\n groupLabel: (groupId: string) => string;\n /** A cell by its headers: \"Tuesday, 10:00\". */\n cellName: (rowText: string, columnText: string) => string;\n /** A group header row: \"Mos Eisley (Average)\". */\n groupRowText: (groupText: string, method: HeatmapAggregate) => string;\n /** A cell as the table view shows it: \"26%, 10 of 39\". */\n tableText: (cell: ModelCell) => string;\n /** Label for a margin: \"Total\" for a sum, \"Average\" for a mean. */\n methodLabel: (method: HeatmapAggregate) => string;\n /** The value as text: formatted, a cell label, \"no data\" or \"too few\". */\n valueText: (cell: ModelCell) => string;\n /** The value as shown inside a cell, or '' when the cell shows none. */\n visibleText: (cell: ModelCell) => string;\n /** \"10 of 39\" for a rate, \"39 records\" otherwise; null without a count. */\n countText: (cell: ModelCell) => string | null;\n /** \"Tuesday, 10:00: 26%, 10 of 39\". */\n sentence: (rowText: string, columnText: string, cell: ModelCell) => string;\n /** Format for a raw value, used by the legend. */\n formatValue: (value: number) => string;\n}\n\nexport interface DescriberOptions {\n t: TFunction<'ui'>;\n privacyMode: boolean;\n /** What privacy mode masks. Default `rows`. */\n privacyScope?: HeatmapPrivacyScope;\n valueType: HeatmapValueType;\n formatValue: (value: number) => string;\n formatCount: (count: number) => string;\n groups?: readonly HeatmapGroup[];\n}\n\n/** The glyph an empty cell shows, so \"no data\" never relies on colour. */\nconst EMPTY_GLYPH = '–';\n\nexport function createDescriber({\n t,\n privacyMode,\n privacyScope = 'rows',\n valueType,\n formatValue,\n formatCount,\n groups,\n}: DescriberOptions): HeatmapDescriber {\n const groupNames = new Map(groups?.map((group) => [group.id, group.label]));\n const mask = privacyMask();\n const masksRows = privacyMode;\n const masksColumns = privacyMode && privacyScope === 'all';\n const masksGroups = privacyMode && privacyScope === 'all';\n const valueText = (cell: ModelCell): string => {\n if (cell.status === 'empty') return t('heatmap.noData');\n if (cell.status === 'low-sample') {\n // A withheld total may rest on many records: it is not \"too few\".\n return cell.withheld\n ? t('heatmap.totalWithheld')\n : t('heatmap.lowSample');\n }\n // A cell label is free text, so privacy mode shows the number instead.\n if (cell.label !== undefined && !privacyMode) return cell.label;\n return cell.value === null ? t('heatmap.noData') : formatValue(cell.value);\n };\n const countText = (cell: ModelCell): string | null => {\n if (cell.count === undefined) return null;\n if (\n valueType === 'rate' &&\n cell.status === 'value' &&\n cell.value !== null\n ) {\n return t('heatmap.countOf', {\n part: formatCount(Math.round(cell.value * cell.count)),\n total: formatCount(cell.count),\n });\n }\n return t('heatmap.records', {\n count: cell.count,\n formatted: formatCount(cell.count),\n });\n };\n return {\n masksRows,\n masksColumns,\n masksGroups,\n rowLabel: (row) => (masksRows ? mask : row.label),\n columnLabel: (column) => (masksColumns ? mask : column.label),\n // A group missing from `groups` has only its id to show, which may be a\n // name, so privacy mode masks it whatever the scope.\n groupLabel: (groupId) =>\n masksGroups\n ? mask\n : (groupNames.get(groupId) ?? (privacyMode ? mask : groupId)),\n cellName: (rowText, columnText) =>\n t('heatmap.cellName', { row: rowText, column: columnText }),\n groupRowText: (groupText, method) =>\n t('heatmap.groupRow', {\n group: groupText,\n method:\n method === 'sum' ? t('heatmap.totals.sum') : t('heatmap.totals.mean'),\n }),\n tableText: (cell) => {\n const count = cell.status === 'empty' ? null : countText(cell);\n const value = valueText(cell);\n return count === null\n ? value\n : t('heatmap.valueWithCount', { value, count });\n },\n methodLabel: (method) =>\n method === 'sum' ? t('heatmap.totals.sum') : t('heatmap.totals.mean'),\n valueText,\n visibleText: (cell) =>\n cell.status === 'empty'\n ? EMPTY_GLYPH\n : cell.status === 'low-sample'\n ? ''\n : valueText(cell),\n countText,\n sentence: (rowText, columnText, cell) => {\n const count = countText(cell);\n const value = valueText(cell);\n return count === null || cell.status === 'empty'\n ? t('heatmap.cell', { row: rowText, column: columnText, value })\n : t('heatmap.cellWithCount', {\n row: rowText,\n column: columnText,\n value,\n count,\n });\n },\n formatValue,\n };\n}\n","/* -------------------------------------------------------------------- */\n/* Heatmap disclosure control: which totals may be shown so that no */\n/* combination of them, the shown cells and the known bounds gives a */\n/* hidden cell away. Pure functions, no React. */\n/* */\n/* The model is a flow network. Each hidden cell is an arc from its row */\n/* to its group header cell (or column). Each total is an arc of a tree */\n/* above or below the cells: source, grand, group, row on one side; */\n/* group header cell, column, sink on the other, and the sink back to */\n/* the source. The flow on an arc is the hidden part of that total, in */\n/* audit units (numerators for count-weighted means: value x count). */\n/* A shown total fixes its arc's flow; a withheld one leaves it free. */\n/* Rows, groups and the grand total form one nested family and columns */\n/* and header cells the other, so the constraint matrix is totally */\n/* unimodular: every bound below is exact, integers included. */\n/* */\n/* The audit asks two questions of the shown totals: */\n/* 1. How far can each hidden cell move? Its feasible interval is a */\n/* max-flow question (push flow round a cycle through its arc). It */\n/* must span the protection level. */\n/* 2. Is the sum of any set of hidden cells with fewer than minCount */\n/* records determined? Exactly when those cells are all the arcs */\n/* leaving a set of nodes that nothing enters, once the free arcs */\n/* that can move are contracted: a directed cut. A min dicut search */\n/* finds any lighter than minCount. */\n/* */\n/* While the audit finds a disclosure, another shown total is withheld, */\n/* chosen to cover the most disclosures and, among those, the one */\n/* resting on the fewest records. Then each extra total is offered back, */\n/* most records first, and kept if the audit still passes. Withholding */\n/* every total that holds a hidden cell is always safe, and the search */\n/* falls back to it if it cannot finish. */\n/* -------------------------------------------------------------------- */\n\n/**\n * How narrow a hidden cell's interval may be.\n * - `rate`: the numerator lies in [0, records]. The interval must span at\n * least half that range and, for whole numbers, at least two values.\n * - `scaled`: values are non-negative with no upper bound. The interval\n * must reach down to half its own top or below (and not be a point).\n * - `free`: values have no bounds. The cell must not be pinned.\n */\nexport type ProtectionMode = 'rate' | 'scaled' | 'free';\n\n/** A hidden cell: an arc from its row node to its column-side node. */\nexport interface AuditCell {\n from: number;\n to: number;\n /** Bounds of its unknown, in audit units. */\n lo: number;\n hi: number;\n /** The records behind it (its count). */\n records: number;\n}\n\n/** A total: an arc of the tree above or below the cells. */\nexport interface AuditTotal {\n from: number;\n to: number;\n /** The hidden part of the total, in audit units, when it is shown. */\n value: number;\n /** Shown before the audit: drawn, with a value, and not withheld. */\n shown: boolean;\n /** The records behind the total: what withholding it loses. */\n records: number;\n}\n\nexport interface AuditProblem {\n nodeCount: number;\n /** The sink and source the closing arc joins (sink to source). */\n sink: number;\n source: number;\n cells: readonly AuditCell[];\n totals: readonly AuditTotal[];\n /** For each cell, the totals whose scope holds it. */\n cellTotals: readonly (readonly number[])[];\n mode: ProtectionMode;\n /** Whole-number data: numerators and shown totals are integers. */\n integral: boolean;\n minCount: number;\n}\n\n/** What the audit found: cells given away, and totals that would help. */\ninterface Disclosure {\n /** Every one of these must be withheld (a way round a cell). */\n allOf?: number[];\n /** Any one of these, withheld, breaks it (a set's cut). */\n anyOf?: number[];\n}\n\nconst BIG = 1e12;\n\n/**\n * A cap on the audit's work, in edges looked at, so a very large grid\n * cannot stall the page: past it, every total that holds a hidden cell is\n * withheld, which is always safe. Counted, not timed, so the same data\n * always gives the same result on every device. A 60 x 24 grid with 6\n * groups and 10% of cells hidden uses 2.5 million for rates and 3.15\n * million for plain sums, about half the cap (measured at about 12 ms in\n * Chromium on a desktop, not a guarantee); with 20% hidden, or 100 rows,\n * it runs out. Tests hold the count, not the time. Running out while offering totals back keeps the safe set already\n * found; running out before that takes the safe rule. When rates are\n * audited twice (printed and exact), the two passes share the cap.\n */\nexport const AUDIT_WORK_LIMIT = 5_000_000;\nconst WORK_LIMIT = AUDIT_WORK_LIMIT;\nlet work = 0;\nconst OUT_OF_WORK = new Error('heatmap audit: work limit');\n/** Failing cells whose way round is searched in one round. */\nconst OPENINGS_PER_ROUND = 32;\nconst spend = (edges: number) => {\n work += edges;\n if (work > WORK_LIMIT) throw OUT_OF_WORK;\n};\n\n/* -------------------------------------------------------------------- */\n/* Residual graph and augmenting paths */\n/* -------------------------------------------------------------------- */\n\ninterface Graph {\n n: number;\n head: Int32Array;\n next: Int32Array;\n to: Int32Array;\n edges: number;\n}\n\nfunction makeGraph(n: number, maxEdges: number): Graph {\n return {\n n,\n head: new Int32Array(n).fill(-1),\n next: new Int32Array(maxEdges * 2),\n to: new Int32Array(maxEdges * 2),\n edges: 0,\n };\n}\n\n/** Adds u to v and its reverse; returns the forward edge's id (reverse is\n * id ^ 1). Capacities live in a separate array. */\nfunction addEdge(g: Graph, u: number, v: number): number {\n const id = g.edges;\n g.to[id] = v;\n g.next[id] = g.head[u];\n g.head[u] = id;\n g.to[id + 1] = u;\n g.next[id + 1] = g.head[v];\n g.head[v] = id + 1;\n g.edges += 2;\n return id;\n}\n\n/**\n * Pushes up to `limit` from s to t along shortest augmenting paths,\n * changing `cap` in place, never using edge pair `skip` (an edge id, or\n * -1). Returns the amount pushed.\n */\nfunction augment(\n g: Graph,\n cap: Float64Array,\n s: number,\n t: number,\n limit: number,\n skip: number,\n eps: number,\n parent: Int32Array,\n queue: Int32Array,\n): number {\n if (s === t) return limit;\n const skipPair = skip >= 0 ? skip >> 1 : -1;\n let pushed = 0;\n let scanned = 0;\n while (pushed < limit - eps) {\n parent.fill(-2);\n parent[s] = -1;\n let qh = 0;\n let qt = 0;\n queue[qt++] = s;\n let found = false;\n while (qh < qt && !found) {\n const u = queue[qh++];\n for (let e = g.head[u]; e !== -1; e = g.next[e]) {\n scanned += 1;\n if (cap[e] <= eps || e >> 1 === skipPair) continue;\n const v = g.to[e];\n if (parent[v] !== -2) continue;\n parent[v] = e;\n if (v === t) {\n found = true;\n break;\n }\n queue[qt++] = v;\n }\n }\n spend(scanned);\n scanned = 0;\n if (!found) break;\n let bottleneck = limit - pushed;\n for (let v = t; v !== s; v = g.to[parent[v] ^ 1]) {\n bottleneck = Math.min(bottleneck, cap[parent[v]]);\n }\n for (let v = t; v !== s; v = g.to[parent[v] ^ 1]) {\n cap[parent[v]] -= bottleneck;\n cap[parent[v] ^ 1] += bottleneck;\n }\n pushed += bottleneck;\n }\n return pushed;\n}\n\n/** Nodes reachable from s over edges with capacity left, skipping a pair. */\nfunction reach(\n g: Graph,\n cap: Float64Array,\n s: number,\n skip: number,\n eps: number,\n queue: Int32Array,\n): Uint8Array {\n const seen = new Uint8Array(g.n);\n const skipPair = skip >= 0 ? skip >> 1 : -1;\n seen[s] = 1;\n let qh = 0;\n let qt = 0;\n queue[qt++] = s;\n let scanned = 0;\n while (qh < qt) {\n const u = queue[qh++];\n for (let e = g.head[u]; e !== -1; e = g.next[e]) {\n scanned += 1;\n if (cap[e] <= eps || e >> 1 === skipPair) continue;\n const v = g.to[e];\n if (seen[v]) continue;\n seen[v] = 1;\n queue[qt++] = v;\n }\n }\n spend(scanned);\n return seen;\n}\n\n/* -------------------------------------------------------------------- */\n/* The audit */\n/* -------------------------------------------------------------------- */\n\n/** Arc layout: totals first, then cells, then the closing arc. */\ninterface Network {\n graph: Graph;\n /** Residual capacities at a feasible flow (fixed arcs carry none). */\n cap: Float64Array;\n /** The feasible flow, per arc. */\n flow: Float64Array;\n closing: number;\n cellArc: (c: number) => number;\n}\n\nconst protectionNeed = (problem: AuditProblem, records: number): number =>\n problem.integral\n ? Math.max(1, Math.ceil(records / 2 - 1e-9))\n : Math.max(records / 2, 1e-6);\n\n/** Bounds of every arc for a given set of shown totals. */\nfunction arcBounds(\n problem: AuditProblem,\n shown: readonly boolean[],\n): { lo: Float64Array; hi: Float64Array } {\n const count = problem.totals.length + problem.cells.length + 1;\n const lo = new Float64Array(count);\n const hi = new Float64Array(count);\n const free = problem.mode === 'free';\n problem.totals.forEach((total, i) => {\n if (shown[i]) {\n lo[i] = total.value;\n hi[i] = total.value;\n } else {\n lo[i] = free ? -BIG : 0;\n hi[i] = BIG;\n }\n });\n const base = problem.totals.length;\n problem.cells.forEach((cell, c) => {\n lo[base + c] = free ? -BIG : Math.max(cell.lo, -BIG);\n hi[base + c] = free ? BIG : Math.min(cell.hi, BIG);\n });\n lo[count - 1] = free ? -BIG : 0;\n hi[count - 1] = BIG;\n return { lo, hi };\n}\n\nfunction endpoints(problem: AuditProblem, arc: number): [number, number] {\n const totals = problem.totals.length;\n if (arc < totals) return [problem.totals[arc].from, problem.totals[arc].to];\n if (arc < totals + problem.cells.length) {\n const cell = problem.cells[arc - totals];\n return [cell.from, cell.to];\n }\n return [problem.sink, problem.source];\n}\n\n/**\n * A feasible flow for the shown totals, as a residual network; null when\n * the shown totals contradict the cells (the data is not an aggregate of\n * the cells), which the caller treats as unsafe.\n */\nfunction feasibleNetwork(\n problem: AuditProblem,\n shown: readonly boolean[],\n eps: number,\n): Network | null {\n const { lo, hi } = arcBounds(problem, shown);\n const arcs = lo.length;\n const n = problem.nodeCount;\n spend(arcs * 4);\n // Circulation with lower bounds: shift every arc to [0, hi - lo] and\n // meet the shifted supplies from a super source and sink.\n const g = makeGraph(n + 2, arcs + n);\n const cap = new Float64Array((arcs + n) * 2);\n const excess = new Float64Array(n);\n for (let a = 0; a < arcs; a += 1) {\n const [u, v] = endpoints(problem, a);\n const id = addEdge(g, u, v);\n cap[id] = hi[a] - lo[a];\n excess[v] += lo[a];\n excess[u] -= lo[a];\n }\n const superSource = n;\n const superSink = n + 1;\n let demand = 0;\n for (let v = 0; v < n; v += 1) {\n if (excess[v] > 0) {\n cap[addEdge(g, superSource, v)] = excess[v];\n demand += excess[v];\n } else if (excess[v] < 0) {\n cap[addEdge(g, v, superSink)] = -excess[v];\n }\n }\n const parent = new Int32Array(n + 2);\n const queue = new Int32Array(n + 2);\n const pushed = augment(\n g,\n cap,\n superSource,\n superSink,\n Infinity,\n -1,\n eps,\n parent,\n queue,\n );\n if (pushed < demand - eps * Math.max(1, arcs)) return null;\n const flow = new Float64Array(arcs);\n for (let a = 0; a < arcs; a += 1) {\n flow[a] = lo[a] + (hi[a] - lo[a] - cap[2 * a]);\n }\n // The residual network of the original arcs alone, at that flow.\n const graph = makeGraph(n, arcs);\n const residual = new Float64Array(arcs * 2);\n for (let a = 0; a < arcs; a += 1) {\n const [u, v] = endpoints(problem, a);\n const id = addEdge(graph, u, v);\n const fixed = a < problem.totals.length && shown[a];\n residual[id] = fixed ? 0 : Math.max(0, hi[a] - flow[a]);\n residual[id + 1] = fixed ? 0 : Math.max(0, flow[a] - lo[a]);\n }\n const base = problem.totals.length;\n return {\n graph,\n cap: residual,\n flow,\n closing: arcs - 1,\n cellArc: (c) => base + c,\n };\n}\n\n/** Whether t can be reached from s over edges with capacity left,\n * skipping edge pair `skip`. Leaves `cap` untouched. */\nfunction pathExists(\n g: Graph,\n cap: Float64Array,\n s: number,\n t: number,\n skip: number,\n eps: number,\n queue: Int32Array,\n seen: Uint8Array,\n): boolean {\n if (s === t) return true;\n seen.fill(0);\n const skipPair = skip >> 1;\n seen[s] = 1;\n let qh = 0;\n let qt = 0;\n let scanned = 0;\n queue[qt++] = s;\n while (qh < qt) {\n const u = queue[qh++];\n for (let e = g.head[u]; e !== -1; e = g.next[e]) {\n scanned += 1;\n if (cap[e] <= eps || e >> 1 === skipPair) continue;\n const v = g.to[e];\n if (seen[v]) continue;\n if (v === t) {\n spend(scanned);\n return true;\n }\n seen[v] = 1;\n queue[qt++] = v;\n }\n }\n spend(scanned);\n return false;\n}\n\n/**\n * The shown totals to withhold, fewest records first, that open a path\n * from s to t: residual edges cost nothing, and a shown total costs its\n * records (once withheld it carries any amount forward, and back as much\n * as it holds). Skips edge pair `skip`, the cell's own arc.\n */\n/** Per node, the shown totals leaving it once withheld: [to, records,\n * total]. Both ways for a total that holds anything. */\ntype Openings = readonly (readonly (readonly [number, number, number])[])[];\n\nfunction openings(\n problem: AuditProblem,\n shown: readonly boolean[],\n n: number,\n eps: number,\n): Openings {\n const extra: [number, number, number][][] = Array.from(\n { length: n },\n () => [],\n );\n problem.totals.forEach((total, i) => {\n if (!shown[i]) return;\n extra[total.from].push([total.to, total.records, i]);\n if (total.value > eps) extra[total.to].push([total.from, total.records, i]);\n });\n spend(problem.totals.length);\n return extra;\n}\n\nfunction cheapestOpening(\n net: Network,\n extra: Openings,\n s: number,\n t: number,\n skip: number,\n eps: number,\n): number[] {\n const { graph, cap } = net;\n const n = graph.n;\n const skipPair = skip >> 1;\n const dist = new Float64Array(n).fill(Infinity);\n const via = new Int32Array(n).fill(-1);\n const from = new Int32Array(n).fill(-1);\n const done = new Uint8Array(n);\n dist[s] = 0;\n // A small binary heap of [distance, node].\n const heap: [number, number][] = [[0, s]];\n const pushHeap = (item: [number, number]) => {\n heap.push(item);\n let i = heap.length - 1;\n while (i > 0) {\n const up = (i - 1) >> 1;\n if (\n heap[up][0] < item[0] ||\n (heap[up][0] === item[0] && heap[up][1] <= item[1])\n )\n break;\n heap[i] = heap[up];\n i = up;\n }\n heap[i] = item;\n };\n const popHeap = (): [number, number] => {\n const top = heap[0];\n const last = heap.pop() as [number, number];\n if (heap.length) {\n let i = 0;\n for (;;) {\n const l = 2 * i + 1;\n const r = l + 1;\n let m = i;\n const better = (a: number, b: [number, number]) =>\n heap[a][0] < b[0] || (heap[a][0] === b[0] && heap[a][1] < b[1]);\n let best: [number, number] = last;\n if (l < heap.length && better(l, best)) {\n m = l;\n best = heap[l];\n }\n if (r < heap.length && better(r, best)) {\n m = r;\n best = heap[r];\n }\n if (m === i) break;\n heap[i] = heap[m];\n i = m;\n }\n heap[i] = last;\n }\n return top;\n };\n while (heap.length) {\n const [d, u] = popHeap();\n if (done[u]) continue;\n done[u] = 1;\n // Each node settled costs a heap step and every edge it looks at.\n let edges = 2 + extra[u].length;\n for (let e = graph.head[u]; e !== -1; e = graph.next[e]) edges += 1;\n spend(edges);\n if (u === t) break;\n for (let e = graph.head[u]; e !== -1; e = graph.next[e]) {\n if (cap[e] <= eps || e >> 1 === skipPair) continue;\n const v = graph.to[e];\n if (d < dist[v]) {\n dist[v] = d;\n via[v] = -1;\n from[v] = u;\n pushHeap([d, v]);\n }\n }\n for (const [v, cost, total] of extra[u]) {\n if (d + cost < dist[v]) {\n dist[v] = d + cost;\n via[v] = total;\n from[v] = u;\n pushHeap([d + cost, v]);\n }\n }\n }\n if (!Number.isFinite(dist[t])) return [];\n const picked: number[] = [];\n for (let v = t; v !== s; v = from[v]) {\n if (via[v] >= 0) picked.push(via[v]);\n }\n return picked.sort((a, b) => a - b);\n}\n\n/** Hidden cells, of those given, whose interval is narrower than the\n * protection level; `failed` lists them. */\nfunction narrowCells(\n problem: AuditProblem,\n shown: readonly boolean[],\n net: Network,\n eps: number,\n check: readonly number[],\n firstOnly: boolean,\n): { disclosures: Disclosure[]; failed: number[]; pinned: Uint8Array } {\n const failed: number[] = [];\n const { graph, cap } = net;\n const parent = new Int32Array(graph.n);\n const queue = new Int32Array(graph.n);\n const seen = new Uint8Array(graph.n);\n const disclosures: Disclosure[] = [];\n const arcs = net.flow.length;\n const pinned = new Uint8Array(arcs);\n // Whole numbers keep every residual capacity whole, so one unit moves\n // exactly when a path exists: no need to push it.\n const whole = problem.mode === 'rate' && problem.integral;\n const move = (s: number, t: number, limit: number, skip: number): number => {\n if (limit <= eps) return 0;\n if (whole && limit <= 1 + eps) {\n return pathExists(graph, cap, s, t, skip, eps, queue, seen) ? limit : 0;\n }\n // A copy costs work too: about one edge's worth per four numbers.\n spend(cap.length >> 2);\n return augment(graph, cap.slice(), s, t, limit, skip, eps, parent, queue);\n };\n\n // The ways round a failing cell are searched for the first few failing\n // cells only; the rest fail again next round, after those are fixed.\n let extra: Openings | null = null;\n const extraOf = (): Openings => {\n extra = extra ?? openings(problem, shown, graph.n, eps);\n return extra;\n };\n let opened = 0;\n\n for (const c of check) {\n const cell = problem.cells[c];\n const arc = net.cellArc(c);\n const [u, v] = endpoints(problem, arc);\n const id = 2 * arc;\n let safe: boolean;\n let upAsked: number;\n let downAsked: number;\n let up: number;\n let down: number;\n if (problem.mode === 'rate') {\n const need = protectionNeed(problem, cell.records);\n upAsked = Math.min(cap[id], need);\n up = move(v, u, upAsked, id);\n downAsked = Math.min(cap[id + 1], need - up);\n down = move(u, v, downAsked, id);\n safe = up + down >= need - eps;\n } else {\n // Non-negative, no top: the interval [f - down, f + up] must reach\n // down to half its top, so up + 2 x down >= f, and not be a point.\n // How far it falls first; then it need only rise that far.\n const f = net.flow[arc];\n downAsked = cap[id + 1];\n down = move(u, v, downAsked, id);\n const lift = Math.max(f - 2 * down, down > eps ? 0 : eps * 4);\n upAsked = Math.min(cap[id], lift);\n up = lift > 0 ? move(v, u, upAsked, id) : 0;\n safe = lift <= 0 || up >= lift - eps;\n }\n if (up + down <= eps) pinned[arc] = 1;\n if (safe) continue;\n failed.push(c);\n if (firstOnly) {\n disclosures.push({ allOf: [] });\n break;\n }\n if (opened >= OPENINGS_PER_ROUND) continue;\n opened += 1;\n // Withhold the cheapest totals that open a way round the cell, in each\n // direction the network (not the cell's own bound) stopped short.\n const open = new Set<number>();\n if (up < upAsked - eps) {\n for (const t of cheapestOpening(net, extraOf(), v, u, id, eps))\n open.add(t);\n }\n if (down < downAsked - eps) {\n for (const t of cheapestOpening(net, extraOf(), u, v, id, eps))\n open.add(t);\n }\n if (open.size === 0) {\n for (const t of problem.cellTotals[c]) if (shown[t]) open.add(t);\n }\n disclosures.push({ allOf: [...open].sort((a, b) => a - b) });\n }\n return { disclosures, failed, pinned };\n}\n\n/** Free totals whose flow no feasible change can move. */\nfunction pinnedTotals(\n problem: AuditProblem,\n shown: readonly boolean[],\n net: Network,\n pinned: Uint8Array,\n eps: number,\n): void {\n const { graph, cap } = net;\n const queue = new Int32Array(graph.n);\n const seen = new Uint8Array(graph.n);\n const check = (arc: number) => {\n const [u, v] = endpoints(problem, arc);\n const id = 2 * arc;\n if (cap[id] > eps && pathExists(graph, cap, v, u, id, eps, queue, seen)) {\n return;\n }\n if (\n cap[id + 1] > eps &&\n pathExists(graph, cap, u, v, id, eps, queue, seen)\n ) {\n return;\n }\n pinned[arc] = 1;\n };\n problem.totals.forEach((_, i) => {\n if (!shown[i]) check(i);\n });\n check(net.closing);\n}\n\n/**\n * Sets of hidden cells, with fewer than minCount records between them,\n * whose sum the shown totals determine. Contract every free arc that can\n * move except the cells; a set's sum is determined exactly when its cells\n * are all the arcs leaving some set of nodes that no cell enters.\n */\nfunction determinedSets(\n problem: AuditProblem,\n shown: readonly boolean[],\n net: Pick<Network, 'closing' | 'cellArc'>,\n pinned: Uint8Array,\n): Disclosure[] {\n const n = problem.nodeCount;\n const root = new Int32Array(n);\n for (let v = 0; v < n; v += 1) root[v] = v;\n const find = (v: number): number => {\n let r = v;\n while (root[r] !== r) r = root[r];\n while (root[v] !== r) {\n const up = root[v];\n root[v] = r;\n v = up;\n }\n return r;\n };\n const join = (a: number, b: number) => {\n const ra = find(a);\n const rb = find(b);\n if (ra !== rb) root[Math.max(ra, rb)] = Math.min(ra, rb);\n };\n problem.totals.forEach((total, i) => {\n if (!shown[i] && !pinned[i]) join(total.from, total.to);\n });\n if (!pinned[net.closing]) join(problem.sink, problem.source);\n\n // Cells between different blobs: the edges a determined set is made of.\n interface Edge {\n from: number;\n to: number;\n weight: number;\n cells: number[];\n }\n const edgeMap = new Map<number, Edge>();\n problem.cells.forEach((cell, c) => {\n if (pinned[net.cellArc(c)]) return;\n const a = find(cell.from);\n const b = find(cell.to);\n if (a === b) return;\n const key = a * n + b;\n const edge = edgeMap.get(key) ?? { from: a, to: b, weight: 0, cells: [] };\n // A cell with no records counts as many as minCount: it cannot make a\n // set smaller than minCount.\n edge.weight += cell.records > 0 ? cell.records : problem.minCount;\n edge.cells.push(c);\n edgeMap.set(key, edge);\n });\n const edges = [...edgeMap.values()].sort(\n (x, y) => x.from - y.from || x.to - y.to,\n );\n if (edges.length === 0) return [];\n\n // Strongly connected blobs: an edge inside one lies on a cycle and is\n // never part of a determined set.\n const ids = [...new Set(edges.flatMap((e) => [e.from, e.to]))].sort(\n (a, b) => a - b,\n );\n const local = new Map(ids.map((id, i) => [id, i]));\n const m = ids.length;\n const out: number[][] = Array.from({ length: m }, () => []);\n edges.forEach((e, i) => out[local.get(e.from) as number].push(i));\n const scc = new Int32Array(m).fill(-1);\n {\n // Tarjan, iterative.\n const index = new Int32Array(m).fill(-1);\n const low = new Int32Array(m);\n const onStack = new Uint8Array(m);\n const stack: number[] = [];\n let counter = 0;\n let sccCount = 0;\n for (let start = 0; start < m; start += 1) {\n if (index[start] !== -1) continue;\n const work: [number, number][] = [[start, 0]];\n index[start] = low[start] = counter++;\n stack.push(start);\n onStack[start] = 1;\n while (work.length) {\n const frame = work[work.length - 1];\n const [v, i] = frame;\n if (i < out[v].length) {\n frame[1] += 1;\n const w = local.get(edges[out[v][i]].to) as number;\n if (index[w] === -1) {\n index[w] = low[w] = counter++;\n stack.push(w);\n onStack[w] = 1;\n work.push([w, 0]);\n } else if (onStack[w]) {\n low[v] = Math.min(low[v], index[w]);\n }\n } else {\n work.pop();\n if (work.length) {\n const parentV = work[work.length - 1][0];\n low[parentV] = Math.min(low[parentV], low[v]);\n }\n if (low[v] === index[v]) {\n let w: number;\n do {\n w = stack.pop() as number;\n onStack[w] = 0;\n scc[w] = sccCount;\n } while (w !== v);\n sccCount += 1;\n }\n }\n }\n }\n }\n // The condensation: cross edges between components, weights added.\n const dag = new Map<string, { a: number; b: number; weight: number }>();\n const dagCells = new Map<string, number[]>();\n for (const e of edges) {\n const a = scc[local.get(e.from) as number];\n const b = scc[local.get(e.to) as number];\n if (a === b) continue;\n const key = `${a}>${b}`;\n const entry = dag.get(key) ?? { a, b, weight: 0 };\n entry.weight += e.weight;\n dag.set(key, entry);\n dagCells.set(key, [...(dagCells.get(key) ?? []), ...e.cells]);\n }\n if (dag.size === 0) return [];\n const dagEdges = [...dag.entries()].sort(([x], [y]) => (x < y ? -1 : 1));\n const nodes = [...new Set(dagEdges.flatMap(([, e]) => [e.a, e.b]))].sort(\n (a, b) => a - b,\n );\n const nodeIndex = new Map(nodes.map((v, i) => [v, i]));\n const k = nodes.length;\n\n // Weakly connected parts of the condensation.\n const part = new Int32Array(k);\n for (let i = 0; i < k; i += 1) part[i] = i;\n const partOf = (i: number): number => {\n while (part[i] !== i) {\n part[i] = part[part[i]];\n i = part[i];\n }\n return i;\n };\n for (const [, e] of dagEdges) {\n const a = partOf(nodeIndex.get(e.a) as number);\n const b = partOf(nodeIndex.get(e.b) as number);\n if (a !== b) part[Math.max(a, b)] = Math.min(a, b);\n }\n\n // One graph for the min dicut search: each cross edge forward with its\n // weight, and backward without limit, so a finite cut is a directed one.\n const g = makeGraph(k, dagEdges.length);\n const base = new Float64Array(dagEdges.length * 2);\n for (const [, e] of dagEdges) {\n const id = addEdge(\n g,\n nodeIndex.get(e.a) as number,\n nodeIndex.get(e.b) as number,\n );\n base[id] = e.weight;\n base[id + 1] = BIG;\n }\n const parent = new Int32Array(k);\n const queue = new Int32Array(k);\n const found = new Map<string, Disclosure>();\n /** Maps a side of the condensation back to the network's nodes: 1 for\n * the closed side, 0 for the rest, including nodes no cell touches.\n * `inGraph` marks nodes in a blob that some cell touches. */\n const sccSide = (side: Uint8Array) => {\n const nodeSide = new Uint8Array(n);\n const inGraph = new Uint8Array(n);\n const sccIn = new Map<number, number>();\n nodes.forEach((v, i) => sccIn.set(v, side[i]));\n for (let v = 0; v < n; v += 1) {\n const blob = local.get(find(v));\n if (blob === undefined) continue;\n inGraph[v] = 1;\n nodeSide[v] = sccIn.get(scc[blob]) ?? 0;\n }\n return { nodeSide, inGraph };\n };\n const record = (side: Uint8Array) => {\n const cells: number[] = [];\n for (const [key, e] of dagEdges) {\n const a = nodeIndex.get(e.a) as number;\n const b = nodeIndex.get(e.b) as number;\n if (side[a] === 1 && side[b] === 0) {\n cells.push(...(dagCells.get(key) ?? []));\n }\n }\n cells.sort((a, b) => a - b);\n const key = cells.join(',');\n if (found.has(key)) return;\n const { nodeSide, inGraph } = sccSide(side);\n // A shown total joining the two sides breaks this cut once withheld\n // when both its ends are in blobs a cell touches; one reaching a node\n // no cell touches only moves the boundary, so it is a second choice.\n const direct = new Set<number>();\n const indirect = new Set<number>();\n problem.totals.forEach((total, i) => {\n if (!shown[i] || nodeSide[total.from] === nodeSide[total.to]) return;\n if (inGraph[total.from] && inGraph[total.to]) direct.add(i);\n else indirect.add(i);\n });\n const candidates = direct.size > 0 ? direct : indirect;\n if (candidates.size === 0) {\n for (const c of cells) {\n for (const t of problem.cellTotals[c]) if (shown[t]) candidates.add(t);\n }\n }\n found.set(key, { anyOf: [...candidates].sort((a, b) => a - b) });\n };\n const limit = problem.minCount;\n const roots = new Map<number, number>();\n for (let i = 0; i < k; i += 1) {\n const p = partOf(i);\n if (!roots.has(p)) roots.set(p, i);\n }\n for (let v = 0; v < k; v += 1) {\n const r = roots.get(partOf(v)) as number;\n if (r === v) continue;\n for (const [s, t] of [\n [r, v],\n [v, r],\n ]) {\n spend(base.length >> 2);\n const work = base.slice();\n const value = augment(g, work, s, t, limit, -1, 1e-9, parent, queue);\n if (value < limit - 1e-9) {\n // The source side of the cut: everything still reachable.\n const side = reach(g, work, s, -1, 1e-9, queue);\n record(side);\n }\n }\n }\n return [...found.values()];\n}\n\n/** Bridges of the free network: the cells no equation-free cycle moves. */\nfunction freePinned(\n problem: AuditProblem,\n shown: readonly boolean[],\n): Uint8Array {\n const n = problem.nodeCount;\n const arcs = problem.totals.length + problem.cells.length + 1;\n const adj: [number, number][][] = Array.from({ length: n }, () => []);\n for (let a = 0; a < arcs; a += 1) {\n if (a < problem.totals.length && shown[a]) continue;\n const [u, v] = endpoints(problem, a);\n adj[u].push([v, a]);\n adj[v].push([u, a]);\n }\n const pinned = new Uint8Array(arcs);\n const disc = new Int32Array(n).fill(-1);\n const low = new Int32Array(n);\n let time = 0;\n for (let start = 0; start < n; start += 1) {\n if (disc[start] !== -1) continue;\n const work: [number, number, number][] = [[start, -1, 0]];\n disc[start] = low[start] = time++;\n while (work.length) {\n const frame = work[work.length - 1];\n const [v, viaArc, i] = frame;\n if (i < adj[v].length) {\n frame[2] += 1;\n const [w, arc] = adj[v][i];\n if (arc === viaArc) continue;\n if (disc[w] === -1) {\n disc[w] = low[w] = time++;\n work.push([w, arc, 0]);\n } else {\n low[v] = Math.min(low[v], disc[w]);\n }\n } else {\n work.pop();\n if (work.length) {\n const up = work[work.length - 1][0];\n low[up] = Math.min(low[up], low[v]);\n if (low[v] > disc[up]) pinned[viaArc] = 1;\n }\n }\n }\n }\n return pinned;\n}\n\n/** What one audit found. `cells` lists the hidden cells that failed when\n * the cells themselves gave something away; empty when a set did. */\ninterface Findings {\n disclosures: Disclosure[];\n cells: number[];\n}\n\n/**\n * Every disclosure the shown totals allow, checking only the cells in\n * `check` one by one (the rest are known to be safe); null when the shown\n * totals contradict the cells. Sets are checked once no cell fails.\n */\nfunction audit(\n problem: AuditProblem,\n shown: readonly boolean[],\n eps: number,\n check: readonly number[],\n firstOnly = false,\n): Findings | null {\n if (problem.mode === 'free') {\n const pinned = freePinned(problem, shown);\n const disclosures: Disclosure[] = [];\n const cells: number[] = [];\n for (const c of check) {\n if (!pinned[problem.totals.length + c]) continue;\n if (firstOnly) return { disclosures: [{ allOf: [] }], cells: [c] };\n cells.push(c);\n disclosures.push({\n anyOf: problem.cellTotals[c].filter((t) => shown[t]),\n });\n }\n if (disclosures.length) return { disclosures, cells };\n const net = {\n closing: problem.totals.length + problem.cells.length,\n cellArc: (c: number) => problem.totals.length + c,\n };\n return {\n disclosures: determinedSets(problem, shown, net, pinned),\n cells: [],\n };\n }\n const net = feasibleNetwork(problem, shown, eps);\n if (!net) return null;\n const found = narrowCells(problem, shown, net, eps, check, firstOnly);\n if (found.disclosures.length) {\n return { disclosures: found.disclosures, cells: found.failed };\n }\n pinnedTotals(problem, shown, net, found.pinned, eps);\n return {\n disclosures: determinedSets(problem, shown, net, found.pinned),\n cells: [],\n };\n}\n\n/**\n * Totals that between them break every disclosure: all of each `allOf`,\n * then, for the `anyOf` ones still standing, a greedy cover (the total\n * breaking the most, then the one with the fewest records).\n */\nfunction pickTotals(\n problem: AuditProblem,\n disclosures: readonly Disclosure[],\n): number[] {\n const picked = new Set<number>();\n for (const d of disclosures) for (const t of d.allOf ?? []) picked.add(t);\n let remaining = disclosures.filter(\n (d) => d.anyOf && d.anyOf.length > 0 && !d.anyOf.some((t) => picked.has(t)),\n );\n while (remaining.length) {\n const cover = new Map<number, number>();\n for (const d of remaining) {\n for (const t of d.anyOf ?? []) cover.set(t, (cover.get(t) ?? 0) + 1);\n }\n let best = -1;\n for (const [t, n] of cover) {\n const b = cover.get(best) ?? -1;\n if (\n best === -1 ||\n n > b ||\n (n === b &&\n (problem.totals[t].records < problem.totals[best].records ||\n (problem.totals[t].records === problem.totals[best].records &&\n t < best)))\n ) {\n best = t;\n }\n }\n picked.add(best);\n remaining = remaining.filter((d) => !(d.anyOf ?? []).includes(best));\n }\n return [...picked].sort((a, b) => a - b);\n}\n\n/**\n * Which totals may be shown: true at index i when total i may be shown.\n * Starts from `total.shown` and only ever withholds more. `spentBefore`\n * carries the work of an earlier pass over the same data, so that passes\n * share one budget (see auditWorkSpent).\n */\nexport function secureTotals(\n problem: AuditProblem,\n spentBefore = 0,\n): boolean[] {\n work = spentBefore;\n try {\n return secure(problem);\n } catch (error) {\n if (error !== OUT_OF_WORK) throw error;\n const holdsHidden = new Uint8Array(problem.totals.length);\n for (const list of problem.cellTotals) {\n for (const t of list) holdsHidden[t] = 1;\n }\n return problem.totals.map((total, i) => total.shown && !holdsHidden[i]);\n }\n}\n\n/** The work the last secureTotals call ended on, for a following pass. */\nexport function auditWorkSpent(): number {\n return work;\n}\n\n/** The audit loop behind secureTotals. */\nfunction secure(problem: AuditProblem): boolean[] {\n const shown = problem.totals.map((total) => total.shown);\n if (problem.cells.length === 0) return shown;\n let scale = 1;\n for (const total of problem.totals) {\n if (total.shown) scale = Math.max(scale, Math.abs(total.value));\n }\n for (const cell of problem.cells) {\n if (Number.isFinite(cell.hi)) scale = Math.max(scale, Math.abs(cell.hi));\n }\n const eps = 1e-9 * scale;\n const holdsHidden = new Uint8Array(problem.totals.length);\n for (const list of problem.cellTotals)\n for (const t of list) holdsHidden[t] = 1;\n const everyHolder = () =>\n shown.map((isShown, i) => isShown && !holdsHidden[i]);\n\n const allCells = problem.cells.map((_, c) => c);\n // Withholding a total only removes an equation, so every interval can\n // only widen: a cell found safe stays safe, and each round rechecks only\n // the cells that failed the last one.\n let check: readonly number[] = allCells;\n const added: number[] = [];\n const maxRounds = problem.totals.length + 1;\n for (let round = 0; ; round += 1) {\n if (round > maxRounds) return everyHolder();\n const found = audit(problem, shown, eps, check);\n if (found === null) return everyHolder();\n if (found.disclosures.length === 0) break;\n const picked = pickTotals(problem, found.disclosures);\n // A disclosure no shown total can break: withhold everything.\n if (picked.length === 0) return everyHolder();\n for (const t of picked) {\n shown[t] = false;\n added.push(t);\n }\n check = found.cells;\n }\n // Offer each extra total back, the most records first: keep it shown if\n // nothing is given away with it. Showing a total adds an equation, so\n // every cell is checked again, those it holds first.\n const offers = [...added].sort(\n (a, b) => problem.totals[b].records - problem.totals[a].records || a - b,\n );\n for (const t of offers) {\n shown[t] = true;\n if (!offerBack(problem, shown, t, allCells, eps)) {\n shown[t] = false;\n }\n }\n return shown;\n}\n\n/** Whether total t can be shown again: no disclosure with it, and the\n * audit finished. Out of work, it stays withheld and the totals already\n * checked stand: they were safe before this offer. */\nfunction offerBack(\n problem: AuditProblem,\n shown: readonly boolean[],\n t: number,\n allCells: readonly number[],\n eps: number,\n): boolean {\n try {\n const near = new Set<number>();\n problem.cellTotals.forEach((list, c) => {\n if (list.includes(t)) near.add(c);\n });\n const order = [...near, ...allCells.filter((c) => !near.has(c))];\n const found = audit(problem, shown, eps, order, true);\n return found !== null && found.disclosures.length === 0;\n } catch (error) {\n if (error !== OUT_OF_WORK) throw error;\n return false;\n }\n}\n","/* -------------------------------------------------------------------- */\n/* Heatmap scale maths. Pure functions, no React, so they are tested on */\n/* their own (heatmap-scale.test.ts) and shared by the grid, the legend */\n/* and the table view. */\n/* */\n/* Every scale maps a value to one of ten colour steps, 0 to 9. The */\n/* steps are tokens (`--heatmap-<palette>-<step>`), so a scale never */\n/* produces a colour itself. */\n/* -------------------------------------------------------------------- */\n\nimport { isDevelopment } from '../_shared/is-development';\n\n/** Number of colour steps every palette carries. */\nexport const HEATMAP_STEPS = 10;\n\n/** The step a degenerate scale (every value equal) falls back to. */\nconst MIDDLE_STEP = Math.floor(HEATMAP_STEPS / 2);\n\n/** Highest step index. */\nconst TOP_STEP = HEATMAP_STEPS - 1;\n\n/** Steps on each side of a diverging midpoint. */\nconst HALF_STEPS = HEATMAP_STEPS / 2;\n\n/**\n * How values map to colour steps.\n *\n * - `sequential`: low to high. `domain: 'auto'` (the default) uses the min\n * and max of the cells that show a value; a fixed `[min, max]` clamps.\n * - `diverging`: two hues either side of `midpoint`. `auto` makes the\n * domain symmetric around the midpoint, so equal distances either side\n * get equal intensity. The midpoint defaults to 0, or to the centre of a\n * fixed domain that does not include 0.\n * - `quantile`: equal-count buckets (default 10) from the shown values.\n * Repeated values never split: buckets that would cut through a run of\n * equal values merge, so the minimum always takes the first step.\n * - `threshold`: ascending cut points; `n` thresholds make `n + 1`\n * buckets, spread across the ten steps. At most nine; duplicates merge.\n *\n * A fixed domain is `[min, max]`. A reversed pair is put in order, with a\n * warning in development builds.\n */\nexport type HeatmapScale =\n | { type: 'sequential'; domain?: 'auto' | readonly [number, number] }\n | {\n type: 'diverging';\n domain?: 'auto' | readonly [number, number];\n midpoint?: number;\n }\n | { type: 'quantile'; buckets?: number }\n | { type: 'threshold'; thresholds: readonly number[] };\n\n/** A scale with its domain worked out against the data. */\nexport interface ResolvedHeatmapScale {\n type: HeatmapScale['type'];\n /** Low end of the domain, or of the data for quantile and threshold. */\n min: number | null;\n /** High end of the domain, or of the data for quantile and threshold. */\n max: number | null;\n /** Diverging only: the value that separates the two hues. */\n midpoint?: number;\n /** Quantile and threshold: the ascending bucket edges. */\n thresholds: readonly number[];\n /** Maps a value to a step, 0 to 9. */\n stepOf: (value: number) => number;\n}\n\nconst clamp = (value: number, low: number, high: number): number =>\n Math.min(high, Math.max(low, value));\n\n/** Messages already given, so a scale worked out again (each data change,\n * twice in StrictMode) does not repeat them. */\nconst warned = new Set<string>();\n\n/** Says what a scale was given and what it uses instead, in development,\n * once per message. */\nfunction warn(message: string): void {\n if (!isDevelopment() || warned.has(message)) return;\n warned.add(message);\n console.warn(`Heatmap: ${message}`);\n}\n\n/** A fixed domain in ascending order (a reversed one is put in order). */\nfunction orderedDomain(\n domain: readonly [number, number],\n): readonly [number, number] {\n if (domain[0] <= domain[1]) return domain;\n warn(\n `scale domain [${domain[0]}, ${domain[1]}] is reversed; using [${domain[1]}, ${domain[0]}].`,\n );\n return [domain[1], domain[0]];\n}\n\n/** Sorted, distinct, finite values. */\nfunction distinctSorted(values: readonly number[]): number[] {\n const sorted = values.filter(Number.isFinite).sort((a, b) => a - b);\n return sorted.filter((value, i) => i === 0 || value !== sorted[i - 1]);\n}\n\n/** Min and max of the finite values, or null when there are none. */\nexport function extent(values: readonly number[]): [number, number] | null {\n let low = Infinity;\n let high = -Infinity;\n for (const value of values) {\n if (!Number.isFinite(value)) continue;\n if (value < low) low = value;\n if (value > high) high = value;\n }\n return low === Infinity ? null : [low, high];\n}\n\n/**\n * Sequential step: the domain is cut into ten equal bands. A value on a\n * band edge takes the band above; the top edge belongs to the top step.\n * Values outside the domain clamp to the end steps.\n */\nexport function sequentialStep(value: number, low: number, high: number) {\n if (!(high > low)) return MIDDLE_STEP;\n const t = clamp((value - low) / (high - low), 0, 1);\n return Math.min(TOP_STEP, Math.floor(t * HEATMAP_STEPS));\n}\n\n/**\n * Diverging step: steps 0 to 4 sit below the midpoint (0 is the furthest),\n * steps 5 to 9 above it (9 is the furthest). Ten steps have no middle one,\n * so a value exactly on the midpoint takes step 5, the palest step above.\n * It is painted in the neutral midpoint colour instead (see `onMidpoint`).\n */\nexport function divergingStep(\n value: number,\n low: number,\n midpoint: number,\n high: number,\n): number {\n if (value < midpoint) {\n const span = midpoint - low;\n const t = span > 0 ? clamp((midpoint - value) / span, 0, 1) : 1;\n return (\n HALF_STEPS - 1 - Math.min(HALF_STEPS - 1, Math.floor(t * HALF_STEPS))\n );\n }\n const span = high - midpoint;\n const t =\n span > 0\n ? clamp((value - midpoint) / span, 0, 1)\n : value > midpoint\n ? 1\n : 0;\n return HALF_STEPS + Math.min(HALF_STEPS - 1, Math.floor(t * HALF_STEPS));\n}\n\n/**\n * Whether a value sits exactly on a diverging scale's midpoint, so it is\n * painted neutral (`--heatmap-midpoint`) rather than in either hue. Exact\n * up to floating-point rounding, a few units in the last place of the\n * scale's largest magnitude: the centre of [0.1, 0.2] is computed as\n * 0.15000000000000002, and 0.1 + 0.2 - 0.3 is not quite 0. A value that\n * merely rounds to the midpoint when printed keeps its step. Other scale\n * types have no midpoint.\n */\nexport function onMidpoint(\n scale: ResolvedHeatmapScale,\n value: number,\n): boolean {\n if (scale.type !== 'diverging' || scale.midpoint === undefined) return false;\n const magnitude = Math.max(\n Math.abs(scale.midpoint),\n Math.abs(scale.min ?? 0),\n Math.abs(scale.max ?? 0),\n );\n return Math.abs(value - scale.midpoint) <= magnitude * Number.EPSILON * 16;\n}\n\n/**\n * Quantile of a sorted array at `p` (0 to 1), interpolating linearly\n * between neighbours (the R-7 method spreadsheets use).\n */\nexport function quantileSorted(sorted: readonly number[], p: number): number {\n const n = sorted.length;\n if (n === 0) return NaN;\n if (n === 1) return sorted[0];\n const position = clamp(p, 0, 1) * (n - 1);\n const below = Math.floor(position);\n const above = Math.min(n - 1, below + 1);\n return sorted[below] + (sorted[above] - sorted[below]) * (position - below);\n}\n\n/** The `buckets - 1` inner edges that cut sorted values into equal counts. */\nexport function quantileThresholds(\n sorted: readonly number[],\n buckets: number,\n): number[] {\n const count = Math.max(1, Math.round(buckets));\n const edges: number[] = [];\n for (let i = 1; i < count; i += 1) {\n edges.push(quantileSorted(sorted, i / count));\n }\n return edges;\n}\n\n/**\n * Quantile edges that cut something. Each raw edge moves up to the first\n * value at or above it, which puts every value in the same bucket but makes\n * the edge a value the data holds, so no bucket is left empty (an edge\n * between two values could cut a band nothing falls in). Then edges that\n * repeat go: when many values repeat (60% of cells at zero), several raw\n * edges land on the same value, and kept they would put the minimum\n * mid-scale. An edge at the minimum has nothing below it, so it goes too.\n */\nexport function usableQuantileEdges(\n sorted: readonly number[],\n buckets: number,\n): number[] {\n if (sorted.length === 0) return [];\n const min = sorted[0];\n const atOrAbove = (edge: number): number => {\n let low = 0;\n let high = sorted.length - 1;\n while (low < high) {\n const mid = (low + high) >>> 1;\n if (sorted[mid] < edge) low = mid + 1;\n else high = mid;\n }\n return sorted[low];\n };\n return distinctSorted(\n quantileThresholds(sorted, buckets).map(atOrAbove),\n ).filter((edge) => edge > min);\n}\n\n/** How many edges are at or below `value`: its bucket, 0 to edges.length. */\nexport function thresholdBucket(\n value: number,\n thresholds: readonly number[],\n): number {\n let low = 0;\n let high = thresholds.length;\n while (low < high) {\n const mid = (low + high) >>> 1;\n if (thresholds[mid] <= value) low = mid + 1;\n else high = mid;\n }\n return low;\n}\n\n/** Spreads bucket `bucket` of `bucketCount` evenly across the ten steps. */\nexport function bucketStep(bucket: number, bucketCount: number): number {\n if (bucketCount <= 1) return MIDDLE_STEP;\n return Math.round(\n (clamp(bucket, 0, bucketCount - 1) * TOP_STEP) / (bucketCount - 1),\n );\n}\n\n/**\n * Works out a scale against the values that will be shown. Pass only the\n * values of cells that render a colour: empty and low-sample cells must not\n * stretch the domain.\n */\nexport function resolveScale(\n scale: HeatmapScale,\n values: readonly number[],\n): ResolvedHeatmapScale {\n const range = extent(values);\n\n switch (scale.type) {\n case 'diverging': {\n const fixed =\n scale.domain && scale.domain !== 'auto'\n ? orderedDomain(scale.domain)\n : null;\n // Zero is the natural midpoint of a change, but only when the domain\n // reaches it: a fixed domain of [10, 50] would leave the lower hue\n // unused, so its centre divides it instead.\n const midpoint =\n scale.midpoint ??\n (fixed && (fixed[0] > 0 || fixed[1] < 0)\n ? (fixed[0] + fixed[1]) / 2\n : 0);\n let low: number;\n let high: number;\n if (fixed) {\n [low, high] = fixed;\n } else {\n const reach = range\n ? Math.max(\n Math.abs(range[0] - midpoint),\n Math.abs(range[1] - midpoint),\n )\n : 0;\n low = midpoint - reach;\n high = midpoint + reach;\n }\n return {\n type: 'diverging',\n min: low,\n max: high,\n midpoint,\n thresholds: [],\n stepOf: (value) => divergingStep(value, low, midpoint, high),\n };\n }\n case 'quantile': {\n const sorted = values\n .filter(Number.isFinite)\n .slice()\n .sort((a, b) => a - b);\n const buckets = clamp(\n Math.round(scale.buckets ?? HEATMAP_STEPS),\n 2,\n HEATMAP_STEPS,\n );\n // Every value equal leaves no edge: one bucket, on the middle step,\n // as a sequential scale does.\n const thresholds = usableQuantileEdges(sorted, buckets);\n return {\n type: 'quantile',\n min: range?.[0] ?? null,\n max: range?.[1] ?? null,\n thresholds,\n stepOf: (value) =>\n bucketStep(thresholdBucket(value, thresholds), thresholds.length + 1),\n };\n }\n case 'threshold': {\n const given = scale.thresholds.filter(Number.isFinite);\n const distinct = distinctSorted(given);\n if (distinct.length !== given.length) {\n warn('duplicate thresholds merged.');\n }\n if (distinct.length > TOP_STEP) {\n warn(\n `${distinct.length} thresholds given; ten steps take at most ${TOP_STEP}, so the highest ${distinct.length - TOP_STEP} are dropped.`,\n );\n }\n const thresholds = distinct.slice(0, TOP_STEP);\n return {\n type: 'threshold',\n min: range?.[0] ?? null,\n max: range?.[1] ?? null,\n thresholds,\n stepOf: (value) =>\n bucketStep(thresholdBucket(value, thresholds), thresholds.length + 1),\n };\n }\n case 'sequential':\n default: {\n const fixed =\n scale.domain && scale.domain !== 'auto'\n ? orderedDomain(scale.domain)\n : null;\n const low = fixed ? fixed[0] : (range?.[0] ?? null);\n const high = fixed ? fixed[1] : (range?.[1] ?? null);\n return {\n type: 'sequential',\n min: low,\n max: high,\n thresholds: [],\n stepOf: (value) =>\n low === null || high === null\n ? MIDDLE_STEP\n : sequentialStep(value, low, high),\n };\n }\n }\n}\n\n/* -------------------------------------------------------------------- */\n/* Aggregation for row, column and group totals. */\n/* -------------------------------------------------------------------- */\n\n/** How a margin combines its cells. */\nexport type HeatmapAggregate = 'sum' | 'mean';\n\n/** One cell as aggregation sees it. */\nexport interface AggregateInput {\n value: number | null;\n count?: number;\n}\n\n/** A combined value and the count behind it. */\nexport interface AggregateResult {\n value: number | null;\n /** Sum of the counts, when any cell carried one. */\n count?: number;\n}\n\n/** Sum of the values; empty cells are skipped. Null when nothing is left. */\nexport function sumOf(cells: readonly AggregateInput[]): AggregateResult {\n let total = 0;\n let seen = false;\n let count = 0;\n let counted = false;\n for (const cell of cells) {\n if (cell.value === null || !Number.isFinite(cell.value)) continue;\n total += cell.value;\n seen = true;\n if (cell.count !== undefined) {\n count += cell.count;\n counted = true;\n }\n }\n return { value: seen ? total : null, count: counted ? count : undefined };\n}\n\n/**\n * Mean weighted by count: sum(value x count) / sum(count). This is the only\n * correct way to combine rates (26% of 39 and 50% of 2 is 27%, not 38%).\n * A cell without a count weighs 1, so data with no counts at all gets a\n * plain mean. Cells with a count of 0 add nothing.\n */\nexport function weightedMean(\n cells: readonly AggregateInput[],\n): AggregateResult {\n let weighted = 0;\n let weights = 0;\n let count = 0;\n let counted = false;\n for (const cell of cells) {\n if (cell.value === null || !Number.isFinite(cell.value)) continue;\n const weight = cell.count ?? 1;\n weighted += cell.value * weight;\n weights += weight;\n if (cell.count !== undefined) {\n count += cell.count;\n counted = true;\n }\n }\n return {\n value: weights > 0 ? weighted / weights : null,\n count: counted ? count : undefined,\n };\n}\n\n/** Combines cells with the given method. */\nexport function aggregate(\n cells: readonly AggregateInput[],\n method: HeatmapAggregate,\n): AggregateResult {\n return method === 'sum' ? sumOf(cells) : weightedMean(cells);\n}\n","/* -------------------------------------------------------------------- */\n/* Heatmap data model. Pure functions that turn the consumer's rows, */\n/* columns and cells into the matrix the grid, the legend and the table */\n/* view read, plus the grouping, sorting and totals maths. */\n/* -------------------------------------------------------------------- */\n\nimport {\n auditWorkSpent,\n secureTotals,\n type AuditCell,\n type AuditTotal,\n type ProtectionMode,\n} from './heatmap-disclosure';\nimport {\n aggregate,\n type AggregateResult,\n type HeatmapAggregate,\n} from './heatmap-scale';\n\n/** One row of the heatmap. */\nexport interface HeatmapRow {\n /** Stable, opaque id. Emitted in DOM hooks, so never a name. */\n id: string;\n /** Visible label. Masked in privacy mode. */\n label: string;\n /**\n * Group id. Rows that share it are grouped when `groupRows` is on. Without\n * a matching entry in `groups` the id doubles as the visible label, so it\n * may be a name: privacy mode masks it, and DOM hooks and agent state\n * carry an index-based id (`group-1`, `group-2` in order of first\n * appearance), never this one.\n */\n group?: string;\n}\n\n/** One column of the heatmap. */\nexport interface HeatmapColumn {\n /**\n * Stable, opaque id. Emitted in DOM hooks (`data-heatmap-cell-id`) and in\n * agent state, so never a name.\n */\n id: string | number;\n /**\n * Visible label. Masked in privacy mode only with `privacyScope=\"all\"`:\n * columns are usually hours or days, which privacy mode keeps.\n */\n label: string;\n}\n\n/** A group's visible label, keyed by the id rows carry in `group`. */\nexport interface HeatmapGroup {\n /** Stable, opaque id. Emitted in DOM hooks and agent state, so never a name. */\n id: string;\n /**\n * Visible label. Masked in privacy mode only with `privacyScope=\"all\"`:\n * groups are usually practices or sites, which privacy mode keeps.\n */\n label: string;\n}\n\n/**\n * The id each group shows to DOM hooks and agents. A group listed in\n * `groups` keeps its own (opaque) id. One that is not has only its id for a\n * label, which may be a name, so it gets `group-<n>` by order of first\n * appearance instead.\n */\nexport function publicGroupIds(\n rows: readonly HeatmapRow[],\n groups: readonly HeatmapGroup[] | undefined,\n): Map<string, string> {\n const listed = new Set(groups?.map((group) => group.id));\n const taken = new Set(listed);\n const ids = new Map<string, string>();\n let n = 0;\n for (const row of rows) {\n const groupId = row.group;\n if (groupId === undefined || ids.has(groupId)) continue;\n if (listed.has(groupId)) {\n ids.set(groupId, groupId);\n continue;\n }\n let fallback: string;\n do {\n n += 1;\n fallback = `group-${n}`;\n } while (taken.has(fallback));\n taken.add(fallback);\n ids.set(groupId, fallback);\n }\n return ids;\n}\n\n/** The data behind one cell. */\nexport interface HeatmapCellData {\n /**\n * The value to colour. `null` means no data, or, with a `count` above 0 but\n * below `minCount`, a value withheld as too few to show.\n */\n value: number | null;\n /**\n * How many records the value rests on (the denominator of a rate). Weights\n * the mean totals and drives `minCount`.\n */\n count?: number;\n /**\n * Text shown and announced instead of the formatted value, for example\n * \"Closed\". Replaced by the formatted value in privacy mode.\n */\n label?: string;\n}\n\n/** What `getCell` or the `cells` matrix may hold for a cell. */\nexport type HeatmapCellInput = HeatmapCellData | number | null | undefined;\n\n/** How a cell renders: a coloured value, no data, or too few records. */\nexport type HeatmapCellStatus = 'value' | 'empty' | 'low-sample';\n\n/** Addresses one cell. */\nexport interface HeatmapCellKey {\n rowId: string;\n columnId: string | number;\n}\n\n/** Everything known about one cell, as passed to callbacks. */\nexport interface HeatmapCellInfo extends HeatmapCellKey {\n row: HeatmapRow;\n column: HeatmapColumn;\n /** Index into the `rows` prop. */\n rowIndex: number;\n /** Index into the `columns` prop. */\n columnIndex: number;\n value: number | null;\n count?: number;\n label?: string;\n status: HeatmapCellStatus;\n /**\n * Colour step, 0 to 9, when `status` is `'value'`; otherwise null. On a\n * diverging scale a value exactly on the midpoint keeps step 5 but is\n * painted in the neutral `--heatmap-midpoint` colour: compare `value`\n * with the midpoint to tell it from the palest step above.\n */\n step: number | null;\n}\n\n/** A cell after normalisation. */\nexport interface ModelCell {\n value: number | null;\n count?: number;\n label?: string;\n status: HeatmapCellStatus;\n /** A total withheld to protect hidden cells. Its status stays\n * `low-sample`, but it may rest on many records, so it is worded apart\n * from a cell that is too few to show. */\n withheld?: true;\n}\n\n/** How rows are ordered (within their group when grouped). */\nexport type HeatmapSortRows = 'none' | 'label' | 'total-asc' | 'total-desc';\n\n/** Whether a cell or total falls below the sample threshold. */\nexport function isLowSample(\n count: number | undefined,\n minCount: number | undefined,\n): boolean {\n return minCount !== undefined && count !== undefined && count < minCount;\n}\n\n/** Normalises one cell input. */\nexport function toModelCell(\n input: HeatmapCellInput,\n minCount: number | undefined,\n): ModelCell {\n if (input === null || input === undefined) {\n return { value: null, status: 'empty' };\n }\n const data: HeatmapCellData =\n typeof input === 'number' ? { value: input } : input;\n const value =\n data.value === null || !Number.isFinite(data.value) ? null : data.value;\n // A count below minCount is too few to show, with or without a value: a\n // host keeps a withheld value off the page by sending null and the count.\n // No records at all is still no data.\n const status: HeatmapCellStatus =\n isLowSample(data.count, minCount) &&\n (value !== null || (data.count ?? 0) > 0)\n ? 'low-sample'\n : value === null\n ? 'empty'\n : 'value';\n return { value, count: data.count, label: data.label, status };\n}\n\n/** Builds the `[row][column]` matrix in the order of the props. */\nexport function buildMatrix(\n rows: readonly HeatmapRow[],\n columns: readonly HeatmapColumn[],\n getCell:\n | ((\n row: HeatmapRow,\n column: HeatmapColumn,\n rowIndex: number,\n columnIndex: number,\n ) => HeatmapCellInput)\n | undefined,\n cells: readonly (readonly HeatmapCellInput[])[] | undefined,\n minCount: number | undefined,\n): ModelCell[][] {\n return rows.map((row, r) =>\n columns.map((column, c) =>\n toModelCell(\n getCell ? getCell(row, column, r, c) : cells?.[r]?.[c],\n minCount,\n ),\n ),\n );\n}\n\n/** The values that render a colour, for the scale's domain. */\nexport function shownValues(matrix: readonly ModelCell[][]): number[] {\n const values: number[] = [];\n for (const row of matrix) {\n for (const cell of row) {\n if (cell.status === 'value' && cell.value !== null)\n values.push(cell.value);\n }\n }\n return values;\n}\n\n/** Whether at least one cell carries data (a value or a low sample). */\nexport function hasAnyData(matrix: readonly ModelCell[][]): boolean {\n return matrix.some((row) => row.some((cell) => cell.status !== 'empty'));\n}\n\n/* -------------------------------------------------------------------- */\n/* Totals */\n/* -------------------------------------------------------------------- */\n\n/**\n * Which total `getTotal` is asked for, with the rows, columns and group it\n * covers. `method` is how the kit combines the cells for it: the\n * `rowTotals` method for a row, a group and the grand total, the\n * `columnTotals` method for a column, and the column method (else the row\n * method) for a group header cell.\n */\nexport type HeatmapTotalScope =\n | {\n /** A row's total, in the totals column. */\n kind: 'row';\n method: HeatmapAggregate;\n row: HeatmapRow;\n rowId: string;\n /** Index into the `rows` prop. */\n rowIndex: number;\n }\n | {\n /** A column's total, in the totals row. */\n kind: 'column';\n method: HeatmapAggregate;\n column: HeatmapColumn;\n columnId: string | number;\n /** Index into the `columns` prop. */\n columnIndex: number;\n }\n | {\n /** A group's total, in the totals column of its header row. */\n kind: 'group';\n method: HeatmapAggregate;\n /** The id the group's rows carry in `group`. */\n groupId: string;\n /** The group's entry in `groups`, when it has one. */\n group?: HeatmapGroup;\n /** The group's rows, in the order of the `rows` prop. */\n rows: readonly HeatmapRow[];\n rowIndexes: readonly number[];\n }\n | {\n /** One column's total within a group, in the group's header row. */\n kind: 'group-column';\n method: HeatmapAggregate;\n groupId: string;\n group?: HeatmapGroup;\n rows: readonly HeatmapRow[];\n rowIndexes: readonly number[];\n column: HeatmapColumn;\n columnId: string | number;\n columnIndex: number;\n }\n | {\n /** The grand total of every cell, in the corner. */\n kind: 'grand';\n method: HeatmapAggregate;\n };\n\n/** Returns a total, or undefined to let the kit work it out from the cells. */\nexport type HeatmapGetTotal = (\n scope: HeatmapTotalScope,\n) => HeatmapCellInput | undefined;\n\n/**\n * Every margin, ready to render. A withheld total is `{ value: null,\n * status: 'low-sample', withheld: true }`: no value and no count, so\n * nothing that reads it (the grid, the table view, a sort by total) can\n * pass one on.\n */\nexport interface HeatmapTotals {\n /** Per row index (props order), by the row method. */\n rows: ModelCell[];\n /** Per column index, by the column method. */\n columns: ModelCell[];\n /** Every cell, by the row method (it sits in the row-totals column). */\n grand: ModelCell;\n /** Per group id, whenever rows carry a group: one per column, by the\n * group column method. */\n groupColumns: Map<string, ModelCell[]>;\n /** Per group id, whenever rows carry a group: every cell in the group,\n * by the row method (it sits in the row-totals column). */\n groups: Map<string, ModelCell>;\n}\n\n/** Which totals the viewer sees: drawn, or, for rows, ordering the rows. */\nexport interface ShownTotals {\n rows: boolean;\n columns: boolean;\n grand: boolean;\n groups: boolean;\n groupColumns: boolean;\n}\n\nexport interface TotalsOptions {\n rowMethod: HeatmapAggregate;\n columnMethod: HeatmapAggregate;\n groupColumnMethod: HeatmapAggregate;\n groups?: readonly HeatmapGroup[];\n minCount?: number;\n getTotal?: HeatmapGetTotal;\n /** `rate` values are proportions of their count. Default `number`. */\n valueType?: 'number' | 'rate';\n /** Which totals the viewer sees. Default: every one. */\n shown?: ShownTotals;\n}\n\n/** A withheld total: no value, no count, no label. */\nconst WITHHELD_TOTAL: ModelCell = {\n value: null,\n status: 'low-sample',\n withheld: true,\n};\n\nconst ALL_SHOWN: ShownTotals = {\n rows: true,\n columns: true,\n grand: true,\n groups: true,\n groupColumns: true,\n};\n\n/** A total the kit works out, with the same status rules as a cell. */\nfunction computedTotal(\n cells: readonly ModelCell[],\n method: HeatmapAggregate,\n minCount: number | undefined,\n): ModelCell {\n const result: AggregateResult = aggregate(cells, method);\n return {\n value: result.value,\n count: result.count,\n status:\n result.value === null\n ? 'empty'\n : isLowSample(result.count, minCount)\n ? 'low-sample'\n : 'value',\n };\n}\n\n/** One total before the audit. Every scope is a block of rows by columns. */\ninterface Draft {\n method: HeatmapAggregate;\n rowIndexes: readonly number[];\n columnIndexes: readonly number[];\n own: ModelCell;\n /** Withheld whatever the audit says: too few on its own count, worked\n * out over a value the kit never had, or holding hidden cells with\n * fewer than minCount records between them. */\n primary: boolean;\n /** The viewer would see it. */\n visible: boolean;\n /** It holds a hidden cell. */\n holdsHidden: boolean;\n}\n\n/**\n * Works out every margin, then withholds whatever would let someone work\n * out a hidden cell (status `low-sample`), alone or with any combination\n * of the other totals shown, the shown cells and the known bounds. A total\n * in the row-totals column (a row's, a group's, the grand total) uses the\n * row method, so the column means one thing; a group's per-column totals\n * use the group column method. Low-sample cells count: their data is real,\n * only too thin to show on its own. `getTotal` may supply any total\n * instead; the same rule applies.\n *\n * Primary: a total under minCount on its own count, one the kit would work\n * out over a value it never had, and one whose hidden cells hold fewer\n * than minCount records. Secondary: the disclosure audit in\n * heatmap-disclosure.ts, over every total the viewer sees.\n */\nexport function computeTotals(\n matrix: readonly ModelCell[][],\n rows: readonly HeatmapRow[],\n columns: readonly HeatmapColumn[],\n options: TotalsOptions,\n): HeatmapTotals {\n const {\n rowMethod,\n columnMethod,\n groupColumnMethod,\n groups: groupList,\n minCount,\n getTotal,\n valueType = 'number',\n } = options;\n const shownKinds = options.shown ?? ALL_SHOWN;\n const allRows = rows.map((_, r) => r);\n const allColumns = columns.map((_, c) => c);\n\n const drafts: Draft[] = [];\n const draft = (\n supplied: HeatmapCellInput | undefined,\n method: HeatmapAggregate,\n rowIndexes: readonly number[],\n columnIndexes: readonly number[],\n visible: boolean,\n ): number => {\n const cells: ModelCell[] = [];\n for (const r of rowIndexes) {\n for (const c of columnIndexes) cells.push(matrix[r][c]);\n }\n let hidden = 0;\n let holdsHidden = false;\n let unknown = false;\n for (const cell of cells) {\n if (cell.status !== 'low-sample') continue;\n holdsHidden = true;\n hidden += cell.count ?? 0;\n if (cell.value === null) unknown = true;\n }\n const own =\n supplied === undefined\n ? computedTotal(cells, method, minCount)\n : toModelCell(supplied, minCount);\n const primary =\n own.status === 'low-sample' ||\n (supplied === undefined && unknown) ||\n (minCount !== undefined && hidden > 0 && hidden < minCount);\n drafts.push({\n method,\n rowIndexes,\n columnIndexes,\n own,\n primary,\n visible,\n holdsHidden,\n });\n return drafts.length - 1;\n };\n\n const rowDrafts = rows.map((row, r) =>\n draft(\n getTotal?.({\n kind: 'row',\n method: rowMethod,\n row,\n rowId: row.id,\n rowIndex: r,\n }),\n rowMethod,\n [r],\n allColumns,\n shownKinds.rows,\n ),\n );\n\n // Group members in props order. Groups are worked out (and audited)\n // whenever rows carry one, grouped on screen or not, so that turning\n // groupRows on or off shows two views of one safe set, not two sets.\n const members = new Map<string, number[]>();\n rows.forEach((row, r) => {\n if (row.group === undefined) return;\n const list = members.get(row.group) ?? [];\n list.push(r);\n members.set(row.group, list);\n });\n const groupEntries = new Map(groupList?.map((group) => [group.id, group]));\n const groupScope = (groupId: string, indexes: readonly number[]) => {\n const group = groupEntries.get(groupId);\n return {\n groupId,\n ...(group === undefined ? {} : { group }),\n rows: indexes.map((r) => rows[r]),\n rowIndexes: indexes,\n };\n };\n\n const groupColumnDrafts = new Map<string, number[]>();\n for (const [groupId, indexes] of members) {\n const scope = groupScope(groupId, indexes);\n groupColumnDrafts.set(\n groupId,\n columns.map((column, c) =>\n draft(\n getTotal?.({\n kind: 'group-column',\n method: groupColumnMethod,\n ...scope,\n column,\n columnId: column.id,\n columnIndex: c,\n }),\n groupColumnMethod,\n indexes,\n [c],\n shownKinds.groupColumns,\n ),\n ),\n );\n }\n\n const columnDrafts = columns.map((column, c) =>\n draft(\n getTotal?.({\n kind: 'column',\n method: columnMethod,\n column,\n columnId: column.id,\n columnIndex: c,\n }),\n columnMethod,\n allRows,\n [c],\n shownKinds.columns,\n ),\n );\n\n const groupDrafts = new Map<string, number>();\n for (const [groupId, indexes] of members) {\n groupDrafts.set(\n groupId,\n draft(\n getTotal?.({\n kind: 'group',\n method: rowMethod,\n ...groupScope(groupId, indexes),\n }),\n rowMethod,\n indexes,\n allColumns,\n shownKinds.groups,\n ),\n );\n }\n\n const grandDraft = draft(\n getTotal?.({ kind: 'grand', method: rowMethod }),\n rowMethod,\n allRows,\n allColumns,\n shownKinds.grand,\n );\n\n const withheld = drafts.map((d) => d.primary);\n const secured = secureDrafts({\n matrix,\n rows,\n drafts,\n rowDrafts,\n columnDrafts,\n groupDrafts,\n groupColumnDrafts,\n grandDraft,\n members,\n valueType,\n minCount,\n });\n secured.forEach((keep, i) => {\n if (!keep) withheld[i] = true;\n });\n\n const cellOf = (i: number) => (withheld[i] ? WITHHELD_TOTAL : drafts[i].own);\n return {\n rows: rowDrafts.map(cellOf),\n columns: columnDrafts.map(cellOf),\n grand: cellOf(grandDraft),\n groupColumns: new Map(\n [...groupColumnDrafts].map(([groupId, list]) => [\n groupId,\n list.map(cellOf),\n ]),\n ),\n groups: new Map(\n [...groupDrafts].map(([groupId, i]) => [groupId, cellOf(i)]),\n ),\n };\n}\n\ninterface SecureInput {\n matrix: readonly ModelCell[][];\n rows: readonly HeatmapRow[];\n drafts: readonly Draft[];\n rowDrafts: readonly number[];\n columnDrafts: readonly number[];\n groupDrafts: ReadonlyMap<string, number>;\n groupColumnDrafts: ReadonlyMap<string, readonly number[]>;\n grandDraft: number;\n members: ReadonlyMap<string, readonly number[]>;\n valueType: 'number' | 'rate';\n minCount: number | undefined;\n}\n\n/**\n * Builds the audit network (see heatmap-disclosure.ts) and returns, per\n * draft, whether it may stay shown. A draft that is not shown to begin\n * with comes back true: it is not the audit's to withhold.\n */\nfunction secureDrafts(input: SecureInput): boolean[] {\n const { matrix, rows, drafts, members, valueType, minCount } = input;\n const keep = drafts.map(() => true);\n if (minCount === undefined) return keep;\n const shownBefore = drafts.map(\n (d) => d.visible && !d.primary && d.own.value !== null,\n );\n\n // One unit for every equation: mixed methods, or a sum of rates, are\n // not audited; every shown total holding a hidden cell is withheld.\n const methods = new Set(\n drafts\n .filter((d, i) => shownBefore[i] && d.holdsHidden)\n .map((d) => d.method),\n );\n if (methods.size === 0) return keep;\n const withholdHolders = () =>\n drafts.map((d, i) => !(shownBefore[i] && d.holdsHidden));\n if (methods.size > 1) return withholdHolders();\n const method = [...methods][0];\n if (valueType === 'rate' && method === 'sum') return withholdHolders();\n\n // Weights: a count-weighted mean adds up value x count (count ?? 1); a\n // sum adds up values.\n const weightOf = (cell: ModelCell): number =>\n method === 'mean' ? (cell.count ?? 1) : 1;\n const rate = valueType === 'rate';\n\n // Averages of plain numbers weighted by count put each hidden cell on its\n // own scale (value x count moves in steps of its count, for any unit of\n // measure), which the flow audit cannot see: whoever knows the unit could\n // pin cells it passes. So they are not audited either.\n if (!rate && method === 'mean') return withholdHolders();\n const isUnknown = (cell: ModelCell): boolean =>\n cell.status === 'low-sample' && (method === 'sum' || (cell.count ?? 0) > 0);\n\n // Nodes: source, sink, grand; groups; rows; group header cells; columns.\n const SOURCE = 0;\n const SINK = 1;\n const GRAND = 2;\n let next = 3;\n const groupNode = new Map<string, number>();\n for (const groupId of members.keys()) groupNode.set(groupId, next++);\n const rowNode = rows.map(() => next++);\n const gcNode = new Map<string, number[]>();\n const columnCount = input.columnDrafts.length;\n for (const groupId of members.keys()) {\n gcNode.set(\n groupId,\n Array.from({ length: columnCount }, () => next++),\n );\n }\n const columnNode = input.columnDrafts.map(() => next++);\n const groupOf = (r: number): string | undefined => rows[r].group;\n\n // Arcs for every draft, in draft order.\n const arcOf: [number, number][] = drafts.map(() => [0, 0]);\n input.rowDrafts.forEach((d, r) => {\n const g = groupOf(r);\n arcOf[d] = [\n g === undefined ? GRAND : (groupNode.get(g) as number),\n rowNode[r],\n ];\n });\n for (const [groupId, d] of input.groupDrafts) {\n arcOf[d] = [GRAND, groupNode.get(groupId) as number];\n }\n for (const [groupId, list] of input.groupColumnDrafts) {\n list.forEach((d, c) => {\n arcOf[d] = [(gcNode.get(groupId) as number[])[c], columnNode[c]];\n });\n }\n input.columnDrafts.forEach((d, c) => {\n arcOf[d] = [columnNode[c], SINK];\n });\n arcOf[input.grandDraft] = [SOURCE, GRAND];\n\n // Hidden cells: the unknowns.\n const cells: AuditCell[] = [];\n const cellTotals: number[][] = [];\n // Whole numerators need whole counts behind the hidden cells.\n let integral = true;\n let nonNegative = true;\n matrix.forEach((cellsInRow, r) => {\n cellsInRow.forEach((cell, c) => {\n // Whether values can be negative is read from the data itself:\n // shown values, shown totals and any hidden value sent. A negative\n // hidden part of a total is then a contradiction (safe rule), never\n // a reason to drop the bounds.\n if (cell.value !== null && cell.value < 0) nonNegative = false;\n if (!isUnknown(cell)) return;\n if (!Number.isInteger(cell.count ?? 0)) integral = false;\n const g = groupOf(r);\n cells.push({\n from: rowNode[r],\n to: g === undefined ? columnNode[c] : (gcNode.get(g) as number[])[c],\n lo: 0,\n hi: valueType === 'rate' ? (cell.count ?? 0) : Infinity,\n records: cell.count ?? 0,\n });\n const holders = [\n input.rowDrafts[r],\n input.columnDrafts[c],\n input.grandDraft,\n ];\n if (g !== undefined) {\n holders.push(\n input.groupDrafts.get(g) as number,\n (input.groupColumnDrafts.get(g) as number[])[c],\n );\n }\n cellTotals.push(holders.sort((a, b) => a - b));\n });\n });\n if (cells.length === 0) return keep;\n\n // Two readers of a rate: the screen prints whole numerators (\"4 of 9\":\n // value x count, rounded), and an agent's read_cell gives a shown cell's\n // exact value. When every numerator is whole the two agree and one audit\n // does; when not, the totals are audited on the printed numerators, then\n // again on the exact ones. Each pass only withholds more.\n const nearWhole = (x: number) =>\n Math.abs(x - Math.round(x)) <= 1e-9 * Math.max(1, Math.abs(x));\n let wholeData = true;\n // The screen prints a total's numerator from its own count. A supplied\n // count that is not its cells' counts added up contradicts them.\n let countsDisagree = false;\n const printed = (cell: ModelCell, x: number) =>\n cell.count === undefined ? x : Math.round(x);\n const parts = drafts.map((d, i) => {\n let records = 0;\n let weight = 0;\n let exact = 0;\n let rounded = 0;\n let unknowns = 0;\n for (const r of d.rowIndexes) {\n for (const c of d.columnIndexes) {\n const cell = matrix[r][c];\n if (cell.status === 'empty') continue;\n weight += weightOf(cell);\n records += cell.count ?? 1;\n if (isUnknown(cell)) unknowns += 1;\n else if (cell.value !== null) {\n const part = weightOf(cell) * cell.value;\n if (!nearWhole(part)) wholeData = false;\n exact += part;\n rounded += printed(cell, part);\n }\n }\n }\n let whole = 0;\n let wholeRounded = 0;\n if (shownBefore[i] && unknowns > 0) {\n const total = d.own.value as number;\n whole = method === 'mean' ? total * weight : total;\n if (!nearWhole(whole)) wholeData = false;\n if (\n method === 'mean' &&\n d.own.count !== undefined &&\n Math.abs(d.own.count - weight) > 1e-9 * Math.max(1, weight)\n ) {\n countsDisagree = true;\n }\n wholeRounded = d.own.count === undefined ? whole : Math.round(whole);\n }\n return { records, exact, rounded, unknowns, whole, wholeRounded };\n });\n if (countsDisagree) return withholdHolders();\n\n drafts.forEach((d, i) => {\n if (shownBefore[i] && (d.own.value as number) < 0) nonNegative = false;\n });\n const mode: ProtectionMode =\n valueType === 'rate' ? 'rate' : nonNegative ? 'scaled' : 'free';\n const auditWith = (\n onPrinted: boolean,\n shown: readonly boolean[],\n spendFrom: number,\n ) => {\n const totals: AuditTotal[] = drafts.map((_, i) => {\n const part = parts[i];\n let value = 0;\n if (shown[i] && part.unknowns > 0) {\n value = onPrinted\n ? part.wholeRounded - part.rounded\n : part.whole - part.exact;\n // Floating-point rounding can leave a hair below zero; that is\n // zero. A real negative is a contradiction: the audit's bounds\n // then fail and it takes the safe rule.\n const tolerance =\n 1e-9 * Math.max(1, Math.abs(part.whole), Math.abs(part.exact));\n if (value < 0 && value > -tolerance) value = 0;\n }\n return {\n from: arcOf[i][0],\n to: arcOf[i][1],\n value,\n shown: shown[i],\n records: part.records,\n };\n });\n return secureTotals(\n {\n nodeCount: next,\n sink: SINK,\n source: SOURCE,\n cells,\n totals,\n cellTotals,\n mode,\n integral: rate && integral && (onPrinted || wholeData),\n minCount,\n },\n spendFrom,\n );\n };\n let result: boolean[];\n if (!rate || wholeData) {\n result = auditWith(rate, shownBefore, 0);\n } else {\n // One work budget across both passes.\n const first = auditWith(true, shownBefore, 0);\n result = auditWith(\n false,\n shownBefore.map((isShown, i) => isShown && first[i]),\n auditWorkSpent(),\n );\n }\n return drafts.map((_, i) => !shownBefore[i] || result[i]);\n}\n\n/* -------------------------------------------------------------------- */\n/* Body rows: grouping, sorting, collapse */\n/* -------------------------------------------------------------------- */\n\n/** A row the grid body renders. */\nexport type BodyRow =\n | {\n kind: 'group';\n /** Navigation key, unique among body rows. */\n key: string;\n groupId: string;\n collapsed: boolean;\n /** Row indexes (props order) in display order. */\n rowIndexes: number[];\n }\n | {\n kind: 'data';\n key: string;\n rowIndex: number;\n groupId?: string;\n };\n\nexport const dataRowKey = (rowId: string): string => `d:${rowId}`;\nexport const groupRowKey = (groupId: string): string => `g:${groupId}`;\nexport const FOOTER_ROW_KEY = 'f';\n\n/** Orders row indexes. Ties keep the props order (a stable sort). */\nexport function sortRowIndexes(\n indexes: readonly number[],\n rows: readonly HeatmapRow[],\n totals: readonly ModelCell[],\n sort: HeatmapSortRows,\n collator: Intl.Collator,\n): number[] {\n const list = [...indexes];\n if (sort === 'label') {\n return list.sort((a, b) => collator.compare(rows[a].label, rows[b].label));\n }\n if (sort === 'total-asc' || sort === 'total-desc') {\n const direction = sort === 'total-asc' ? 1 : -1;\n return list.sort((a, b) => {\n const left = totals[a]?.value;\n const right = totals[b]?.value;\n // Rows without a total sink to the end in both directions, so a\n // withheld total (no value) never places its row by its value.\n if (left === null || left === undefined) return right == null ? 0 : 1;\n if (right === null || right === undefined) return -1;\n return (left - right) * direction;\n });\n }\n return list;\n}\n\n/** Builds the body: group headers (when grouping) and data rows. */\nexport function buildBodyRows(\n rows: readonly HeatmapRow[],\n sortedIndexes: readonly number[],\n groupRows: boolean,\n collapsed: ReadonlySet<string>,\n): BodyRow[] {\n if (!groupRows) {\n return sortedIndexes.map((r) => ({\n kind: 'data',\n key: dataRowKey(rows[r].id),\n rowIndex: r,\n groupId: rows[r].group,\n }));\n }\n // Groups keep the order in which they first appear in the props, so a sort\n // reorders rows within a group but never moves the groups themselves.\n const order: string[] = [];\n const members = new Map<string, number[]>();\n const loose: number[] = [];\n rows.forEach((row) => {\n if (row.group !== undefined && !members.has(row.group)) {\n members.set(row.group, []);\n order.push(row.group);\n }\n });\n for (const r of sortedIndexes) {\n const groupId = rows[r].group;\n if (groupId === undefined) loose.push(r);\n else members.get(groupId)?.push(r);\n }\n const body: BodyRow[] = [];\n for (const groupId of order) {\n const rowIndexes = members.get(groupId) ?? [];\n const isCollapsed = collapsed.has(groupId);\n body.push({\n kind: 'group',\n key: groupRowKey(groupId),\n groupId,\n collapsed: isCollapsed,\n rowIndexes,\n });\n if (!isCollapsed) {\n for (const r of rowIndexes) {\n body.push({\n kind: 'data',\n key: dataRowKey(rows[r].id),\n rowIndex: r,\n groupId,\n });\n }\n }\n }\n // Rows without a group follow the groups, ungrouped.\n for (const r of loose) {\n body.push({ kind: 'data', key: dataRowKey(rows[r].id), rowIndex: r });\n }\n return body;\n}\n","import type { ReactElement } from 'react';\nimport { Tooltip } from '../tooltip';\nimport { useHeatmapContext } from './heatmap-context';\nimport type { HeatmapCellInfo } from './heatmap-model';\n\nexport interface HeatmapTooltipProps {\n /** The cell the tooltip describes. */\n cell: HeatmapCellInfo;\n /**\n * Tooltip text. Defaults to the Heatmap's `renderTooltip`, or to the\n * sentence every cell is named with (\"Tuesday, 10:00: 26%, 10 of 39\").\n * Plain text only: the kit Tooltip never carries interactive content.\n */\n label?: string;\n /** Controlled open state. */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** Logical side. Default `'top'`. */\n side?: 'top' | 'end' | 'bottom' | 'start';\n /** The trigger. */\n children: ReactElement;\n}\n\n/**\n * Heatmap.Tooltip: the kit Tooltip with a cell's description. The grid uses\n * it for the cell under the pointer or the keyboard focus; a consumer can\n * use it to describe a cell somewhere else, with the same wording and the\n * same privacy masking.\n */\nexport function HeatmapTooltip({\n cell,\n label,\n open,\n onOpenChange,\n side = 'top',\n children,\n}: HeatmapTooltipProps) {\n const context = useHeatmapContext();\n const text = label ?? context?.tooltipText(cell) ?? '';\n return (\n <Tooltip\n label={text}\n open={open}\n onOpenChange={onOpenChange}\n side={side}\n delayDuration={0}\n >\n {children}\n </Tooltip>\n );\n}\n\nHeatmapTooltip.displayName = 'HeatmapTooltip';\n\n/**\n * The anchor the grid hangs a cell's tooltip on: an inert box over the\n * cell, so the cell itself never re-mounts (and never drops focus) when the\n * tooltip moves to it. Takes the text, not a cell, so a group header cell\n * (which has no single row) gets one too.\n */\nexport function HeatmapCellTooltip({\n label,\n onOpenChange,\n}: {\n label: string;\n onOpenChange: (open: boolean) => void;\n}) {\n return (\n <Tooltip label={label} open onOpenChange={onOpenChange} delayDuration={0}>\n <span\n aria-hidden=\"true\"\n data-component=\"heatmap-tooltip\"\n className=\"ds:pointer-events-none ds:absolute ds:inset-0\"\n />\n </Tooltip>\n );\n}\n","/* -------------------------------------------------------------------- */\n/* Heatmap virtualisation. Above VIRTUALISE_CELL_THRESHOLD cells the */\n/* grid renders only the rows and columns in (and just around) the */\n/* viewport, plus the cell that holds the roving focus, so focus is */\n/* never dropped by a scroll. */\n/* */\n/* Every row and column has the same pitch in a virtualised grid, so the */\n/* window is plain arithmetic on the scroll offset; the skipped tracks */\n/* are kept by spacer elements that span them (no pixel offsets, so no */\n/* inline transforms). */\n/* -------------------------------------------------------------------- */\n\n/**\n * Cell count above which the grid virtualises. Measured in Chromium on a\n * production build (heatmap mdx, \"Performance\"): a full render took about\n * 10 ms at 840 cells and 14 ms (p95 18 ms) at 1,200, against the 16 ms\n * budget in src/docs/19-performance.mdx. Above 1,000 cells the window keeps\n * render and hover cost tied to the viewport, not to the data.\n */\nexport const VIRTUALISE_CELL_THRESHOLD = 1000;\n\n/** Rows or columns rendered beyond each edge of the viewport. */\nexport const OVERSCAN = 3;\n\n/** Inputs for one axis. All lengths in CSS pixels. */\nexport interface AxisMetrics {\n /** Scroll offset along the axis (absolute; RTL scrollLeft is negative). */\n offset: number;\n /** Visible length of the scroll container along the axis. */\n viewport: number;\n /** Space before the first item: the sticky header or row header. */\n lead: number;\n /** Item length plus the gap after it. */\n pitch: number;\n /** Number of items on the axis. */\n count: number;\n}\n\n/** Half-open range `[start, end)` of item indexes in view. */\nexport function visibleRange(\n { offset, viewport, lead, pitch, count }: AxisMetrics,\n overscan = OVERSCAN,\n): [number, number] {\n if (count <= 0) return [0, 0];\n if (!(pitch > 0)) return [0, count];\n const from = Math.abs(offset) - lead;\n const first = Math.floor(from / pitch) - overscan;\n const last = Math.ceil((from + viewport) / pitch) + overscan;\n const start = Math.max(0, Math.min(count - 1, first));\n const end = Math.max(start + 1, Math.min(count, last));\n return [start, end];\n}\n\n/** What an axis renders: item indexes and the spans of the gaps. */\nexport interface AxisWindow {\n /** Sorted item indexes to render. */\n indexes: number[];\n /** Items skipped before the first rendered one. */\n lead: number;\n /**\n * Items skipped between the pinned (focused) item and the visible range,\n * when the pinned item lies outside it. Zero otherwise.\n */\n middle: number;\n /** Where the middle gap sits: after this many rendered items. */\n middleAfter: number;\n /** Items skipped after the last rendered one. */\n tail: number;\n}\n\n/** Combines the visible range with the item that must stay rendered. */\nexport function axisWindow(\n range: [number, number],\n count: number,\n pinned: number | null,\n): AxisWindow {\n const [start, end] = range;\n const visible: number[] = [];\n for (let i = start; i < end; i += 1) visible.push(i);\n if (pinned === null || pinned < 0 || pinned >= count) {\n return {\n indexes: visible,\n lead: start,\n middle: 0,\n middleAfter: 0,\n tail: Math.max(0, count - end),\n };\n }\n if (pinned < start) {\n return {\n indexes: [pinned, ...visible],\n lead: pinned,\n middle: start - pinned - 1,\n middleAfter: 1,\n tail: Math.max(0, count - end),\n };\n }\n if (pinned >= end) {\n return {\n indexes: [...visible, pinned],\n lead: start,\n middle: pinned - end,\n middleAfter: visible.length,\n tail: count - pinned - 1,\n };\n }\n return {\n indexes: visible,\n lead: start,\n middle: 0,\n middleAfter: 0,\n tail: Math.max(0, count - end),\n };\n}\n\n/** A window that renders everything (the grid below the threshold). */\nexport function fullWindow(count: number): AxisWindow {\n return {\n indexes: Array.from({ length: count }, (_, i) => i),\n lead: 0,\n middle: 0,\n middleAfter: 0,\n tail: 0,\n };\n}\n\n/**\n * A window with every index at or past `count` dropped: what a window built\n * for more items renders in the one pass before it is worked out again.\n * Returns the same window when nothing is past the end.\n */\nexport function trimWindow(window: AxisWindow, count: number): AxisWindow {\n if (window.indexes.every((index) => index < count)) return window;\n const indexes = window.indexes.filter((index) => index < count);\n return {\n indexes,\n lead: Math.min(window.lead, count),\n middle: 0,\n middleAfter: 0,\n tail: Math.max(0, count - (indexes.length + Math.min(window.lead, count))),\n };\n}\n\n/** Whether two windows render the same items (skips a needless render). */\nexport function sameWindow(a: AxisWindow, b: AxisWindow): boolean {\n if (a.lead !== b.lead || a.tail !== b.tail || a.middle !== b.middle) {\n return false;\n }\n if (a.indexes.length !== b.indexes.length) return false;\n return a.indexes.every((value, i) => value === b.indexes[i]);\n}\n","/* -------------------------------------------------------------------- */\n/* Heatmap class recipes. Every colour is a token; every per-cell */\n/* colour is a CVA variant written out in full so Tailwind generates it. */\n/* -------------------------------------------------------------------- */\n\nimport { cva } from 'class-variance-authority';\n\n/** Palettes, each backed by ten `--heatmap-<palette>-<step>` tokens. */\nexport type HeatmapPalette =\n | 'primary'\n | 'success'\n | 'destructive'\n | 'diverging';\n\n/** One colour step of one palette, the neutral midpoint of a diverging\n * scale, or a cell with no colour of its own. */\nexport type HeatmapTone =\n | `${HeatmapPalette}-${0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}`\n | 'midpoint'\n | 'empty'\n | 'low-sample'\n | 'aggregate';\n\n/** The tone for a palette step. */\nexport const stepTone = (palette: HeatmapPalette, step: number): HeatmapTone =>\n `${palette}-${Math.min(9, Math.max(0, Math.round(step)))}` as HeatmapTone;\n\n/**\n * Background and ink for every tone. Shared by the cells and the legend\n * swatches, and written out in full so Tailwind generates every class.\n */\nconst toneClasses: Record<HeatmapTone, string> = {\n 'primary-0':\n 'ds:bg-[var(--heatmap-primary-0)] ds:text-[color:var(--heatmap-primary-0-foreground)]',\n 'primary-1':\n 'ds:bg-[var(--heatmap-primary-1)] ds:text-[color:var(--heatmap-primary-1-foreground)]',\n 'primary-2':\n 'ds:bg-[var(--heatmap-primary-2)] ds:text-[color:var(--heatmap-primary-2-foreground)]',\n 'primary-3':\n 'ds:bg-[var(--heatmap-primary-3)] ds:text-[color:var(--heatmap-primary-3-foreground)]',\n 'primary-4':\n 'ds:bg-[var(--heatmap-primary-4)] ds:text-[color:var(--heatmap-primary-4-foreground)]',\n 'primary-5':\n 'ds:bg-[var(--heatmap-primary-5)] ds:text-[color:var(--heatmap-primary-5-foreground)]',\n 'primary-6':\n 'ds:bg-[var(--heatmap-primary-6)] ds:text-[color:var(--heatmap-primary-6-foreground)]',\n 'primary-7':\n 'ds:bg-[var(--heatmap-primary-7)] ds:text-[color:var(--heatmap-primary-7-foreground)]',\n 'primary-8':\n 'ds:bg-[var(--heatmap-primary-8)] ds:text-[color:var(--heatmap-primary-8-foreground)]',\n 'primary-9':\n 'ds:bg-[var(--heatmap-primary-9)] ds:text-[color:var(--heatmap-primary-9-foreground)]',\n 'success-0':\n 'ds:bg-[var(--heatmap-success-0)] ds:text-[color:var(--heatmap-success-0-foreground)]',\n 'success-1':\n 'ds:bg-[var(--heatmap-success-1)] ds:text-[color:var(--heatmap-success-1-foreground)]',\n 'success-2':\n 'ds:bg-[var(--heatmap-success-2)] ds:text-[color:var(--heatmap-success-2-foreground)]',\n 'success-3':\n 'ds:bg-[var(--heatmap-success-3)] ds:text-[color:var(--heatmap-success-3-foreground)]',\n 'success-4':\n 'ds:bg-[var(--heatmap-success-4)] ds:text-[color:var(--heatmap-success-4-foreground)]',\n 'success-5':\n 'ds:bg-[var(--heatmap-success-5)] ds:text-[color:var(--heatmap-success-5-foreground)]',\n 'success-6':\n 'ds:bg-[var(--heatmap-success-6)] ds:text-[color:var(--heatmap-success-6-foreground)]',\n 'success-7':\n 'ds:bg-[var(--heatmap-success-7)] ds:text-[color:var(--heatmap-success-7-foreground)]',\n 'success-8':\n 'ds:bg-[var(--heatmap-success-8)] ds:text-[color:var(--heatmap-success-8-foreground)]',\n 'success-9':\n 'ds:bg-[var(--heatmap-success-9)] ds:text-[color:var(--heatmap-success-9-foreground)]',\n 'destructive-0':\n 'ds:bg-[var(--heatmap-destructive-0)] ds:text-[color:var(--heatmap-destructive-0-foreground)]',\n 'destructive-1':\n 'ds:bg-[var(--heatmap-destructive-1)] ds:text-[color:var(--heatmap-destructive-1-foreground)]',\n 'destructive-2':\n 'ds:bg-[var(--heatmap-destructive-2)] ds:text-[color:var(--heatmap-destructive-2-foreground)]',\n 'destructive-3':\n 'ds:bg-[var(--heatmap-destructive-3)] ds:text-[color:var(--heatmap-destructive-3-foreground)]',\n 'destructive-4':\n 'ds:bg-[var(--heatmap-destructive-4)] ds:text-[color:var(--heatmap-destructive-4-foreground)]',\n 'destructive-5':\n 'ds:bg-[var(--heatmap-destructive-5)] ds:text-[color:var(--heatmap-destructive-5-foreground)]',\n 'destructive-6':\n 'ds:bg-[var(--heatmap-destructive-6)] ds:text-[color:var(--heatmap-destructive-6-foreground)]',\n 'destructive-7':\n 'ds:bg-[var(--heatmap-destructive-7)] ds:text-[color:var(--heatmap-destructive-7-foreground)]',\n 'destructive-8':\n 'ds:bg-[var(--heatmap-destructive-8)] ds:text-[color:var(--heatmap-destructive-8-foreground)]',\n 'destructive-9':\n 'ds:bg-[var(--heatmap-destructive-9)] ds:text-[color:var(--heatmap-destructive-9-foreground)]',\n 'diverging-0':\n 'ds:bg-[var(--heatmap-diverging-0)] ds:text-[color:var(--heatmap-diverging-0-foreground)]',\n 'diverging-1':\n 'ds:bg-[var(--heatmap-diverging-1)] ds:text-[color:var(--heatmap-diverging-1-foreground)]',\n 'diverging-2':\n 'ds:bg-[var(--heatmap-diverging-2)] ds:text-[color:var(--heatmap-diverging-2-foreground)]',\n 'diverging-3':\n 'ds:bg-[var(--heatmap-diverging-3)] ds:text-[color:var(--heatmap-diverging-3-foreground)]',\n 'diverging-4':\n 'ds:bg-[var(--heatmap-diverging-4)] ds:text-[color:var(--heatmap-diverging-4-foreground)]',\n 'diverging-5':\n 'ds:bg-[var(--heatmap-diverging-5)] ds:text-[color:var(--heatmap-diverging-5-foreground)]',\n 'diverging-6':\n 'ds:bg-[var(--heatmap-diverging-6)] ds:text-[color:var(--heatmap-diverging-6-foreground)]',\n 'diverging-7':\n 'ds:bg-[var(--heatmap-diverging-7)] ds:text-[color:var(--heatmap-diverging-7-foreground)]',\n 'diverging-8':\n 'ds:bg-[var(--heatmap-diverging-8)] ds:text-[color:var(--heatmap-diverging-8-foreground)]',\n 'diverging-9':\n 'ds:bg-[var(--heatmap-diverging-9)] ds:text-[color:var(--heatmap-diverging-9-foreground)]',\n // A value exactly on a diverging scale's midpoint: neutral, so a cell\n // with no change never looks like one with a small change.\n midpoint:\n 'ds:bg-[var(--heatmap-midpoint)] ds:text-[color:var(--heatmap-midpoint-foreground)]',\n empty:\n 'ds:border ds:border-dashed ds:border-[color:var(--heatmap-empty-border)] ds:bg-[var(--heatmap-empty)] ds:text-[color:var(--heatmap-empty-foreground)]',\n 'low-sample':\n 'ds:border ds:border-[color:var(--heatmap-empty-border)] ds:bg-[var(--heatmap-low-sample-surface)] ds:bg-[image:var(--heatmap-low-sample)] ds:text-[color:var(--heatmap-empty-foreground)]',\n aggregate:\n 'ds:bg-[var(--muted)] ds:text-[color:var(--foreground)] ds:font-semibold',\n};\n\n/** Root: a column of legend bar, grid and live region. Never wider than\n * its container, so the page never scrolls sideways. */\nexport const heatmapRootVariants = cva(\n 'ds:flex ds:min-w-0 ds:max-w-full ds:flex-col ds:gap-[var(--spacing-sm)] ds:text-[color:var(--foreground)]',\n);\n\n/** The bar above the grid: legend at the start, view toggle at the end. */\nexport const heatmapToolbarVariants = cva(\n 'ds:flex ds:flex-wrap ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)]',\n);\n\n/** The scroll box. Only this box scrolls; sticky headers stick to it. */\nexport const heatmapScrollerVariants = cva(\n [\n 'ds:relative ds:max-w-full ds:overflow-auto ds:overscroll-contain',\n 'ds:max-h-[var(--heatmap-max-block-size)]',\n 'ds:bg-[var(--background)]',\n // Keep a cell scrolled into view clear of the sticky header, footer and\n // row-header column. The sizes are measured and set on this element.\n 'ds:scroll-pt-[var(--heatmap-sticky-block-start)] ds:scroll-pb-[var(--heatmap-sticky-block-end)] ds:scroll-ps-[var(--heatmap-sticky-inline-start)]',\n ].join(' '),\n);\n\n/**\n * The table view's box. `fit` lets the DataTable grow with its rows up to\n * the maximum; `capped` holds the maximum and the DataTable fills it,\n * scrolling inside.\n */\nexport const heatmapTableViewVariants = cva(\n // Focusable only to hold focus during a retry; not a control, so no ring.\n 'ds:min-w-0 ds:max-w-full ds:outline-none',\n {\n variants: {\n capped: {\n true: 'ds:flex ds:h-[var(--heatmap-max-block-size)] ds:flex-col',\n false: 'ds:block ds:max-h-[var(--heatmap-max-block-size)]',\n },\n },\n defaultVariants: { capped: false },\n },\n);\n\n/**\n * The grid. Columns come from `--heatmap-columns` (set on the scroll box);\n * rows share the column tracks through subgrid. Size sets the cell box,\n * density the gap, and a virtualised grid pins every track to one size so\n * the window arithmetic holds.\n */\nexport const heatmapGridVariants = cva(\n [\n 'ds:grid ds:w-max ds:min-w-full',\n 'ds:[grid-template-rows:auto] ds:auto-rows-[var(--heatmap-row-track)]',\n 'ds:gap-[var(--heatmap-gap)]',\n 'ds:outline-none',\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'ds:[--heatmap-cell-inline:var(--min-target-size)] ds:[--heatmap-cell-block:var(--min-target-size)]',\n md: 'ds:[--heatmap-cell-inline:max(var(--min-target-size),var(--spacing-2xl))] ds:[--heatmap-cell-block:var(--min-target-size)]',\n lg: 'ds:[--heatmap-cell-inline:max(var(--min-target-size),calc(var(--spacing-2xl)_+_var(--spacing-md)))] ds:[--heatmap-cell-block:max(var(--min-target-size),var(--spacing-2xl))]',\n },\n density: {\n default: 'ds:[--heatmap-gap:var(--spacing-2xs)]',\n compact: 'ds:[--heatmap-gap:var(--spacing-none)]',\n },\n virtualised: {\n true: 'ds:[--heatmap-track:var(--heatmap-cell-inline)] ds:[--heatmap-row-track:var(--heatmap-cell-block)]',\n false:\n 'ds:[--heatmap-track:minmax(var(--heatmap-cell-inline),1fr)] ds:[--heatmap-row-track:minmax(var(--heatmap-cell-block),auto)]',\n },\n totalsColumn: {\n true: 'ds:grid-cols-[max-content_repeat(var(--heatmap-columns),var(--heatmap-track))_max-content]',\n false:\n 'ds:grid-cols-[max-content_repeat(var(--heatmap-columns),var(--heatmap-track))]',\n },\n },\n defaultVariants: {\n size: 'md',\n density: 'default',\n virtualised: false,\n totalsColumn: false,\n },\n },\n);\n\n/** A row: spans every column and lines its cells up through subgrid. */\nexport const heatmapRowVariants = cva(\n 'ds:col-span-full ds:grid ds:grid-cols-subgrid',\n {\n variants: {\n position: {\n // The header and footer rows stick to the scroll box's block edges,\n // above the row headers that stick to its inline start.\n // Each also covers the row gap on its inner side, so cells\n // scrolling underneath never show through the gap.\n header:\n \"ds:sticky ds:top-0 ds:z-[calc(var(--z-sticky)+1)] ds:bg-[var(--background)] ds:after:pointer-events-none ds:after:absolute ds:after:inset-x-0 ds:after:top-[calc(100%_-_var(--spacing-2xs))] ds:after:h-[calc(var(--heatmap-gap)_+_var(--spacing-2xs))] ds:after:bg-[var(--background)] ds:after:content-['']\",\n footer:\n \"ds:sticky ds:bottom-0 ds:z-[calc(var(--z-sticky)+1)] ds:bg-[var(--background)] ds:after:pointer-events-none ds:after:absolute ds:after:inset-x-0 ds:after:bottom-[calc(100%_-_var(--spacing-2xs))] ds:after:h-[calc(var(--heatmap-gap)_+_var(--spacing-2xs))] ds:after:bg-[var(--background)] ds:after:content-['']\",\n body: '',\n },\n },\n defaultVariants: { position: 'body' },\n },\n);\n\n/** A spacer standing in for rows or columns the window skipped. */\nexport const heatmapSpacerVariants = cva('ds:pointer-events-none', {\n variants: {\n axis: {\n 'row-lead': 'ds:col-span-full ds:row-span-[var(--heatmap-row-lead)]',\n 'row-middle': 'ds:col-span-full ds:row-span-[var(--heatmap-row-middle)]',\n 'row-tail': 'ds:col-span-full ds:row-span-[var(--heatmap-row-tail)]',\n 'col-lead': 'ds:col-span-[var(--heatmap-col-lead)]',\n 'col-middle': 'ds:col-span-[var(--heatmap-col-middle)]',\n // Holds the skipped columns after the window, so the row-totals cell\n // lands in its own track at the end and never next to the window.\n 'col-tail': 'ds:col-span-[var(--heatmap-col-tail)]',\n },\n },\n});\n\nconst headerHighlight =\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none ds:data-[highlighted=true]:bg-[var(--muted)] ds:data-[highlighted=true]:text-[color:var(--foreground)]';\n\n/** Column header: the hour, day or other column label. */\nexport const heatmapColumnHeaderVariants = cva(\n [\n 'ds:flex ds:min-w-0 ds:items-end ds:justify-center ds:text-center',\n 'ds:rounded-[var(--radius-sm)] ds:px-[var(--spacing-2xs)] ds:py-[var(--spacing-xs)]',\n 'type-meta ds:text-[color:var(--muted-foreground)] ds:break-normal ds:[overflow-wrap:anywhere]',\n headerHighlight,\n ].join(' '),\n {\n variants: {\n corner: {\n // The top-start corner sticks with the row headers below it.\n true: 'ds:sticky ds:start-0 ds:z-[var(--z-sticky)] ds:items-end ds:justify-start ds:text-start ds:bg-[var(--background)] ds:pe-[var(--spacing-sm)]',\n false: '',\n },\n },\n defaultVariants: { corner: false },\n },\n);\n\n/** Row header: the row's label, sticky at the inline start. */\nexport const heatmapRowHeaderVariants = cva(\n [\n 'ds:sticky ds:start-0 ds:z-[var(--z-sticky)] ds:flex ds:min-w-0 ds:items-center',\n 'ds:max-w-[calc(var(--spacing-2xl)*4)] ds:gap-[var(--spacing-xs)]',\n 'ds:bg-[var(--background)] ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-sm)]',\n // Cover the gaps at the inline end and below too, so cells scrolling\n // underneath never show through between row headers.\n \"ds:after:pointer-events-none ds:after:absolute ds:after:top-0 ds:after:bottom-[calc(var(--heatmap-gap)*-1)] ds:after:start-full ds:after:w-[var(--heatmap-gap)] ds:after:bg-[var(--background)] ds:after:content-['']\",\n // The strip below overlaps its neighbours slightly so a fractional row\n // position never leaves a hairline seam.\n \"ds:before:pointer-events-none ds:before:absolute ds:before:inset-x-0 ds:before:top-[calc(100%_-_var(--spacing-2xs))] ds:before:h-[calc(var(--heatmap-gap)_+_var(--spacing-2xs)*2)] ds:before:bg-[var(--background)] ds:before:content-['']\",\n 'type-body-sm ds:text-start ds:break-normal ds:[overflow-wrap:anywhere]',\n headerHighlight,\n ].join(' '),\n {\n variants: {\n kind: {\n data: '',\n group: 'ds:font-semibold',\n total: 'ds:font-semibold',\n },\n // A virtualised grid needs every row the same height: no wrapping.\n // The label truncates inside its own span (heatmapRowLabelVariants):\n // overflow on the header itself would clip its gap-covering strips.\n virtualised: {\n true: 'ds:whitespace-nowrap',\n false: '',\n },\n },\n defaultVariants: { kind: 'data', virtualised: false },\n },\n);\n\n/** The label inside a row header. */\nexport const heatmapRowLabelVariants = cva('ds:min-w-0', {\n variants: {\n virtualised: {\n true: 'ds:overflow-hidden ds:text-ellipsis',\n false: '',\n },\n },\n defaultVariants: { virtualised: false },\n});\n\n/**\n * A cell. Colour comes from `tone`; selection, focus and hover come from\n * state attributes so a cell's classes only change when its data does.\n *\n * Focus: an inset ring in `--ring` over an inset band of the page colour,\n * so it reads on every step. Selection: a dark line framed by two light\n * ones, also inset, so it reads on every step too and is a shape, not a\n * colour. On a focused, selected cell the selection lines move inward by\n * `--focus-ring-width`, so the ring (3px in the accessible theme) never\n * covers them. Windows high contrast keeps the cell colours\n * (forced-color-adjust: none) and paints focus in the system Highlight\n * colour.\n */\nexport const heatmapCellVariants = cva(\n [\n 'ds:relative ds:flex ds:min-w-0 ds:items-center ds:justify-center',\n 'ds:min-h-[var(--heatmap-cell-block)] ds:overflow-hidden ds:px-[var(--spacing-2xs)]',\n 'type-meta ds:tabular-nums ds:whitespace-nowrap ds:select-none',\n 'ds:forced-colors:[forced-color-adjust:none]',\n 'ds:focus-visible:outline-solid ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-ring',\n 'ds:focus-visible:outline-offset-[calc(var(--focus-ring-width)*-1)]',\n 'ds:focus-visible:shadow-[inset_0_0_0_calc(var(--focus-ring-width)*2)_var(--background)]',\n 'ds:forced-colors:focus-visible:outline-[Highlight]',\n 'ds:aria-selected:shadow-[inset_0_0_0_var(--spacing-2xs)_var(--background),inset_0_0_0_calc(var(--spacing-2xs)*2)_var(--foreground),inset_0_0_0_calc(var(--spacing-2xs)*3)_var(--background)]',\n 'ds:aria-selected:focus-visible:shadow-[inset_0_0_0_calc(var(--focus-ring-width)_+_var(--spacing-2xs))_var(--background),inset_0_0_0_calc(var(--focus-ring-width)_+_var(--spacing-2xs)*2)_var(--foreground),inset_0_0_0_calc(var(--focus-ring-width)_+_var(--spacing-2xs)*3)_var(--background)]',\n ].join(' '),\n {\n variants: {\n tone: toneClasses,\n interactive: {\n true: 'ds:cursor-pointer',\n false: 'ds:cursor-default',\n },\n },\n defaultVariants: { tone: 'empty', interactive: false },\n },\n);\n\n/** Legend container. */\nexport const heatmapLegendVariants = cva(\n 'ds:flex ds:min-w-0 ds:flex-wrap ds:items-center ds:gap-x-[var(--spacing-md)] ds:gap-y-[var(--spacing-xs)] type-meta ds:text-[color:var(--muted-foreground)]',\n);\n\n/** The bar of colour steps in the legend. It shrinks with its container\n * rather than pushing the page wider. */\nexport const heatmapLegendBarVariants = cva(\n 'ds:flex ds:w-[calc(var(--spacing-xl)*6)] ds:min-w-0 ds:max-w-full ds:shrink ds:items-stretch',\n {\n variants: {\n variant: {\n stepped: 'ds:gap-[var(--spacing-2xs)]',\n continuous: 'ds:overflow-hidden ds:rounded-[var(--radius-sm)]',\n },\n },\n defaultVariants: { variant: 'stepped' },\n },\n);\n\n/** A legend swatch: a step in the bar, the key for an empty or low-sample\n * cell, or the diverging midpoint, which carries its value in its own ink.\n * Same tone classes as the cells. */\nexport const heatmapSwatchVariants = cva(\n 'ds:inline-block ds:forced-colors:[forced-color-adjust:none]',\n {\n variants: {\n tone: toneClasses,\n shape: {\n stepped:\n 'ds:h-[var(--spacing-sm)] ds:min-w-0 ds:flex-1 ds:rounded-[var(--radius-sm)]',\n continuous: 'ds:h-[var(--spacing-sm)] ds:min-w-0 ds:flex-1',\n key: 'ds:size-[var(--spacing-md)] ds:shrink-0 ds:rounded-[var(--radius-sm)]',\n label:\n 'ds:shrink-0 ds:rounded-[var(--radius-sm)] ds:px-[var(--spacing-xs)] ds:whitespace-nowrap',\n },\n },\n defaultVariants: { tone: 'empty', shape: 'key' },\n },\n);\n","import {\n memo,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n type PointerEvent,\n type MouseEvent,\n type ReactElement,\n} from 'react';\nimport { ChevronDown } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport type { HeatmapDescriber } from './heatmap-format';\nimport {\n FOOTER_ROW_KEY,\n type BodyRow,\n type HeatmapCellInfo,\n type HeatmapColumn,\n type HeatmapRow,\n type HeatmapTotals,\n type ModelCell,\n} from './heatmap-model';\nimport {\n onMidpoint,\n type HeatmapAggregate,\n type ResolvedHeatmapScale,\n} from './heatmap-scale';\nimport { HeatmapCellTooltip } from './heatmap-tooltip';\nimport {\n axisWindow,\n fullWindow,\n sameWindow,\n trimWindow,\n visibleRange,\n type AxisWindow,\n} from './heatmap-window';\nimport {\n heatmapCellVariants,\n heatmapColumnHeaderVariants,\n heatmapGridVariants,\n heatmapRowHeaderVariants,\n heatmapRowLabelVariants,\n heatmapRowVariants,\n heatmapScrollerVariants,\n heatmapSpacerVariants,\n stepTone,\n type HeatmapPalette,\n type HeatmapTone,\n} from './heatmap-variants';\n\n/** How the selection behaves. */\nexport type HeatmapSelectionMode = 'none' | 'single' | 'multiple' | 'range';\n\n/** A position in the navigable matrix: a body or footer row and a column\n * (the last column is the row-totals column when there is one). */\nexport interface GridPosition {\n rowKey: string;\n col: number;\n}\n\nconst KEY_SEPARATOR = '\\u001f';\n\n/** Internal selection key for a data cell: its row id and column id, never\n * its position, so a change to the columns cannot move it. */\nexport const selectionKey = (\n rowId: string,\n columnId: string | number,\n): string => `${rowId}${KEY_SEPARATOR}${String(columnId)}`;\n\n/** The row id and the column id (as a string) a selection key holds. */\nexport const splitSelectionKey = (key: string): [string, string] => {\n const at = key.indexOf(KEY_SEPARATOR);\n return [key.slice(0, at), key.slice(at + 1)];\n};\n\nexport interface HeatmapGridProps {\n title: string;\n rowsLabel?: string;\n rows: readonly HeatmapRow[];\n columns: readonly HeatmapColumn[];\n matrix: readonly ModelCell[][];\n body: readonly BodyRow[];\n scale: ResolvedHeatmapScale;\n palette: HeatmapPalette;\n describer: HeatmapDescriber;\n showValues: boolean;\n /** Every total, withheld ones already reduced to a value-less cell. */\n totals: HeatmapTotals | null;\n rowTotals: HeatmapAggregate | false;\n columnTotals: HeatmapAggregate | false;\n /** How a group header's per-column totals are worked out. */\n groupColumnMethod: HeatmapAggregate;\n /** Each group's public id: what DOM hooks carry, never a label. */\n groupIds: ReadonlyMap<string, string>;\n selectionMode: HeatmapSelectionMode;\n /** Selection keys (row id + column id) of the selected cells. */\n selected: ReadonlySet<string>;\n /** Column index for the column id a selection key holds. */\n columnIndexOfKey: (columnKey: string) => number | undefined;\n interactive: boolean;\n virtualised: boolean;\n size: 'sm' | 'md' | 'lg';\n density: 'compact' | 'default';\n cellInfo: (rowIndex: number, columnIndex: number) => HeatmapCellInfo;\n /** A data cell's tooltip text. */\n tooltipText: (cell: HeatmapCellInfo) => string;\n /** Describe the focused data cell with its tooltip text (a consumer's\n * renderTooltip says more than the cell's name). */\n describeFocused: boolean;\n /** A data cell was activated by click, Enter or Space. `select` is false\n * for a click that only reports the cell (a range press already chose). */\n onActivate: (rowIndex: number, columnIndex: number, select: boolean) => void;\n /** Range drag or Shift+arrows: select the rectangle anchor to target. */\n onRange: (\n anchor: { rowIndex: number; col: number },\n target: { rowIndex: number; col: number },\n ) => void;\n onToggleGroup: (groupId: string) => void;\n}\n\n/* -------------------------------------------------------------------- */\n/* Per-render context shared by every row (memoised in the grid) */\n/* -------------------------------------------------------------------- */\n\ninterface RowContext {\n rows: readonly HeatmapRow[];\n columns: readonly HeatmapColumn[];\n matrix: readonly ModelCell[][];\n scale: ResolvedHeatmapScale;\n palette: HeatmapPalette;\n describer: HeatmapDescriber;\n showValues: boolean;\n totals: HeatmapTotals | null;\n rowTotals: HeatmapAggregate | false;\n groupColumnMethod: HeatmapAggregate;\n groupIds: ReadonlyMap<string, string>;\n selectable: boolean;\n interactive: boolean;\n virtualised: boolean;\n colWindow: AxisWindow;\n /** Base for the ids that name group row headers. */\n idBase: string;\n /** The id of the focused cell's description, or undefined for none. */\n describedBy: string | undefined;\n cellInfo: (rowIndex: number, columnIndex: number) => HeatmapCellInfo;\n tooltipText: (cell: HeatmapCellInfo) => string;\n onTooltipOpenChange: (open: boolean) => void;\n onToggleGroup: (groupId: string) => void;\n expandLabel: (group: string) => string;\n collapseLabel: (group: string) => string;\n}\n\nfunction toneOf(\n cell: ModelCell,\n scale: ResolvedHeatmapScale,\n palette: HeatmapPalette,\n): HeatmapTone {\n if (cell.status === 'low-sample') return 'low-sample';\n if (cell.status === 'empty' || cell.value === null) return 'empty';\n if (onMidpoint(scale, cell.value)) return 'midpoint';\n return stepTone(palette, scale.stepOf(cell.value));\n}\n\n/** Stands in for a group total that was not worked out. */\nconst NO_TOTAL: ModelCell = { value: null, status: 'empty' };\n\nconst aggregateTone = (cell: ModelCell): HeatmapTone =>\n cell.status === 'value' ? 'aggregate' : cell.status;\n\n/** Renders the column window: spacers stand in for skipped columns, before,\n * between and after the rendered ones, so whatever follows (the row-totals\n * cell) always sits in its own track at the end. */\nfunction renderColumns(\n window: AxisWindow,\n render: (columnIndex: number) => ReactElement,\n): ReactElement[] {\n const out: ReactElement[] = [];\n if (window.lead > 0) {\n out.push(\n <div\n key=\"lead\"\n aria-hidden=\"true\"\n className={heatmapSpacerVariants({ axis: 'col-lead' })}\n />,\n );\n }\n window.indexes.forEach((columnIndex, i) => {\n if (window.middle > 0 && i === window.middleAfter) {\n out.push(\n <div\n key=\"middle\"\n aria-hidden=\"true\"\n className={heatmapSpacerVariants({ axis: 'col-middle' })}\n />,\n );\n }\n out.push(render(columnIndex));\n });\n if (window.tail > 0) {\n out.push(\n <div\n key=\"tail\"\n aria-hidden=\"true\"\n className={heatmapSpacerVariants({ axis: 'col-tail' })}\n />,\n );\n }\n return out;\n}\n\ninterface BodyRowProps {\n ctx: RowContext;\n row: BodyRow;\n /** 1-based aria-rowindex. */\n ariaRowIndex: number;\n highlighted: boolean;\n /** Column holding the roving tabindex in this row, or -1. */\n activeCol: number;\n /** Column hosting the tooltip in this row, or -1. */\n tooltipCol: number;\n /** Selected column indexes, comma-joined (a string so memo compares by value). */\n selectedCols: string;\n}\n\n/** One body row: a data row or a group header. Memoised, so hover and\n * focus only re-render the rows they touch. */\nconst HeatmapBodyRow = memo(function HeatmapBodyRow({\n ctx,\n row,\n ariaRowIndex,\n highlighted,\n activeCol,\n tooltipCol,\n selectedCols,\n}: BodyRowProps) {\n const columnCount = ctx.columns.length;\n const selected = useMemo(\n () =>\n new Set(selectedCols === '' ? [] : selectedCols.split(',').map(Number)),\n [selectedCols],\n );\n\n if (row.kind === 'group') {\n const groupText = ctx.describer.groupLabel(row.groupId);\n // The public id: the group's own when `groups` lists it, else an\n // index-based one, because an unlisted id doubles as the label.\n const hookId = ctx.groupIds.get(row.groupId);\n const labelId = `${ctx.idBase}-label-${ariaRowIndex}`;\n const perColumn = ctx.totals?.groupColumns.get(row.groupId) ?? [];\n const overall = ctx.totals?.groups.get(row.groupId);\n /** A group's cell. Its value always prints, as a row total's does: the\n * group row is a margin, not a colour scale. */\n const groupCell = (\n total: ModelCell | undefined,\n c: number,\n label: (cell: ModelCell) => string,\n withTooltip: boolean,\n ) => {\n const cell = total ?? NO_TOTAL;\n const name = label(cell);\n return (\n <div\n key={c}\n role=\"gridcell\"\n aria-colindex={c + 2}\n aria-expanded={!row.collapsed}\n aria-label={name}\n tabIndex={activeCol === c ? 0 : -1}\n data-heatmap-group-id={hookId}\n className={heatmapCellVariants({\n tone: aggregateTone(cell),\n interactive: true,\n })}\n >\n {ctx.describer.visibleText(cell)}\n {withTooltip && tooltipCol === c ? (\n <HeatmapCellTooltip\n label={name}\n onOpenChange={ctx.onTooltipOpenChange}\n />\n ) : null}\n </div>\n );\n };\n const perColumnRowText = ctx.describer.groupRowText(\n groupText,\n ctx.groupColumnMethod,\n );\n return (\n <div\n role=\"row\"\n aria-rowindex={ariaRowIndex}\n data-heatmap-body-row=\"\"\n data-heatmap-group-id={hookId}\n className={heatmapRowVariants({ position: 'body' })}\n >\n <div\n role=\"rowheader\"\n aria-colindex={1}\n // Named by the label alone: the button's own name (\"Collapse …\")\n // would otherwise be read with it, saying the group twice.\n aria-labelledby={labelId}\n data-highlighted={highlighted}\n className={heatmapRowHeaderVariants({\n kind: 'group',\n virtualised: ctx.virtualised,\n })}\n >\n {/*\n * Out of the tab order (tabIndex -1), and it never takes focus on\n * a press: the grid is one tab stop, and every cell of the group\n * row toggles the group with Enter, Space or a click, so the\n * button is a pointer shortcut. Its 24px box meets WCAG 2.5.8\n * (AA). The kit's own 44px target (2.5.5, 48px accessible) is met\n * through the equivalent-control exception: those cells are the\n * same control at full size.\n */}\n <button\n type=\"button\"\n tabIndex={-1}\n aria-expanded={!row.collapsed}\n aria-label={\n row.collapsed\n ? ctx.expandLabel(groupText)\n : ctx.collapseLabel(groupText)\n }\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => ctx.onToggleGroup(row.groupId)}\n className=\"ds:inline-flex ds:size-[var(--spacing-lg)] ds:shrink-0 ds:cursor-pointer ds:items-center ds:justify-center ds:rounded-[var(--radius-sm)] ds:bg-transparent ds:text-[color:inherit] ds:hover:bg-[var(--muted)] ds:focus-visible:outline-solid ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-ring ds:forced-colors:focus-visible:outline-[Highlight]\"\n >\n <ChevronDown\n aria-hidden=\"true\"\n className={[\n 'ds:size-4 ds:transition-transform ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n row.collapsed ? 'ds:-rotate-90 ds:rtl:rotate-90' : '',\n ].join(' ')}\n />\n </button>\n <span\n id={labelId}\n className={heatmapRowLabelVariants({\n virtualised: ctx.virtualised,\n })}\n >\n {groupText}\n </span>\n </div>\n {renderColumns(ctx.colWindow, (c) =>\n groupCell(\n perColumn[c],\n c,\n (cell) =>\n ctx.describer.sentence(\n perColumnRowText,\n ctx.describer.columnLabel(ctx.columns[c]),\n cell,\n ),\n true,\n ),\n )}\n {ctx.rowTotals\n ? groupCell(\n overall,\n columnCount,\n (cell) =>\n ctx.describer.sentence(\n groupText,\n ctx.describer.methodLabel(ctx.rowTotals || 'mean'),\n cell,\n ),\n false,\n )\n : null}\n </div>\n );\n }\n\n const r = row.rowIndex;\n const source = ctx.rows[r];\n const rowText = ctx.describer.rowLabel(source);\n const cells = ctx.matrix[r];\n\n const dataCell = (c: number) => {\n const cell = cells[c];\n const column = ctx.columns[c];\n const isSelected = selected.has(c);\n return (\n <div\n key={c}\n role=\"gridcell\"\n aria-colindex={c + 2}\n aria-label={ctx.describer.sentence(\n rowText,\n ctx.describer.columnLabel(column),\n cell,\n )}\n aria-describedby={activeCol === c ? ctx.describedBy : undefined}\n aria-selected={ctx.selectable ? isSelected : undefined}\n tabIndex={activeCol === c ? 0 : -1}\n data-heatmap-cell-id={`${source.id}:${String(column.id)}`}\n data-status={cell.status}\n className={heatmapCellVariants({\n tone: toneOf(cell, ctx.scale, ctx.palette),\n interactive: ctx.interactive,\n })}\n >\n {ctx.showValues || cell.status === 'empty'\n ? ctx.describer.visibleText(cell)\n : null}\n {tooltipCol === c ? (\n <HeatmapCellTooltip\n label={ctx.tooltipText(ctx.cellInfo(r, c))}\n onOpenChange={ctx.onTooltipOpenChange}\n />\n ) : null}\n </div>\n );\n };\n\n let totalCell: ReactElement | null = null;\n if (ctx.rowTotals && ctx.totals) {\n const cell = ctx.totals.rows[r];\n totalCell = (\n <div\n role=\"gridcell\"\n aria-colindex={columnCount + 2}\n aria-label={ctx.describer.sentence(\n rowText,\n ctx.describer.methodLabel(ctx.rowTotals),\n cell,\n )}\n tabIndex={activeCol === columnCount ? 0 : -1}\n className={heatmapCellVariants({ tone: aggregateTone(cell) })}\n >\n {ctx.describer.visibleText(cell)}\n </div>\n );\n }\n\n return (\n <div\n role=\"row\"\n aria-rowindex={ariaRowIndex}\n data-heatmap-body-row=\"\"\n data-heatmap-row-id={source.id}\n className={heatmapRowVariants({ position: 'body' })}\n >\n <div\n role=\"rowheader\"\n aria-colindex={1}\n data-highlighted={highlighted}\n className={heatmapRowHeaderVariants({\n kind: 'data',\n virtualised: ctx.virtualised,\n })}\n >\n <span\n className={heatmapRowLabelVariants({ virtualised: ctx.virtualised })}\n >\n {rowText}\n </span>\n </div>\n {renderColumns(ctx.colWindow, dataCell)}\n {totalCell}\n </div>\n );\n});\n\n/* -------------------------------------------------------------------- */\n/* Grid */\n/* -------------------------------------------------------------------- */\n\ninterface Metrics {\n headerBlock: number;\n footerBlock: number;\n rowPitch: number;\n leadInline: number;\n colPitch: number;\n viewportBlock: number;\n viewportInline: number;\n}\n\nconst DEFAULT_METRICS: Metrics = {\n headerBlock: 48,\n footerBlock: 0,\n rowPitch: 46,\n leadInline: 120,\n colPitch: 46,\n viewportBlock: 600,\n viewportInline: 900,\n};\n\nconst pageRows = (metrics: Metrics): number =>\n Math.max(\n 1,\n Math.floor(\n (metrics.viewportBlock - metrics.headerBlock - metrics.footerBlock) /\n Math.max(1, metrics.rowPitch),\n ),\n );\n\nexport function HeatmapGrid(props: HeatmapGridProps) {\n const {\n title,\n rowsLabel,\n rows,\n columns,\n matrix,\n body,\n scale,\n palette,\n describer,\n showValues,\n totals,\n rowTotals,\n columnTotals,\n groupColumnMethod,\n groupIds,\n selectionMode,\n selected,\n columnIndexOfKey,\n interactive,\n virtualised,\n size,\n density,\n cellInfo,\n tooltipText,\n describeFocused,\n onActivate,\n onRange,\n onToggleGroup,\n } = props;\n const { t } = useTranslation('ui');\n const idBase = useId();\n const scrollerRef = useRef<HTMLDivElement>(null);\n const gridRef = useRef<HTMLDivElement>(null);\n const headerRef = useRef<HTMLDivElement>(null);\n const footerRef = useRef<HTMLDivElement>(null);\n\n const columnCount = columns.length;\n const navColumnCount = columnCount + (rowTotals ? 1 : 0);\n const hasFooter = Boolean(columnTotals && totals);\n const navRowKeys = useMemo(\n () => [\n ...body.map((row) => row.key),\n ...(hasFooter ? [FOOTER_ROW_KEY] : []),\n ],\n [body, hasFooter],\n );\n const rowIndexOfKey = useMemo(() => {\n const map = new Map<string, number>();\n navRowKeys.forEach((key, i) => map.set(key, i));\n return map;\n }, [navRowKeys]);\n\n /* ---- roving focus -------------------------------------------------- */\n const [active, setActive] = useState<GridPosition>(() => ({\n rowKey: navRowKeys[0] ?? FOOTER_ROW_KEY,\n col: 0,\n }));\n // If the active row disappears (a group collapsed, rows changed), fall\n // back to its group header, else the first row.\n const activeRow = (() => {\n const found = rowIndexOfKey.get(active.rowKey);\n if (found !== undefined) return found;\n const hidden = rows.find((row) => `d:${row.id}` === active.rowKey);\n const header =\n hidden?.group === undefined\n ? undefined\n : rowIndexOfKey.get(`g:${hidden.group}`);\n return header ?? 0;\n })();\n const activeCol = Math.min(\n Math.max(0, active.col),\n Math.max(0, navColumnCount - 1),\n );\n const activeKey = navRowKeys[activeRow];\n\n const pendingFocus = useRef(false);\n const [hasFocus, setHasFocus] = useState(false);\n const hasFocusRef = useRef(false);\n const interaction = useRef<'keyboard' | 'pointer'>('pointer');\n\n /* ---- hover and tooltip --------------------------------------------- */\n const [hover, setHover] = useState<GridPosition | null>(null);\n const hoverRef = useRef<GridPosition | null>(null);\n const [tooltipDismissed, setTooltipDismissed] = useState(false);\n const updateHover = useCallback((next: GridPosition | null) => {\n const current = hoverRef.current;\n if (\n current === next ||\n (current &&\n next &&\n current.rowKey === next.rowKey &&\n current.col === next.col)\n ) {\n return;\n }\n hoverRef.current = next;\n setHover(next);\n setTooltipDismissed(false);\n }, []);\n\n /** The cell whose headers light up: the hovered one, else the focused one. */\n const highlight: GridPosition | null =\n hover ??\n (hasFocus && activeKey ? { rowKey: activeKey, col: activeCol } : null);\n /** The cell that shows the tooltip: hovered, or focused from the keyboard. */\n const tooltipAt: GridPosition | null = tooltipDismissed\n ? null\n : (hover ??\n (hasFocus && interaction.current === 'keyboard' && activeKey\n ? { rowKey: activeKey, col: activeCol }\n : null));\n\n /* ---- measurement and the virtual window ---------------------------- */\n const [metrics, setMetrics] = useState<Metrics>(DEFAULT_METRICS);\n const metricsRef = useRef(metrics);\n metricsRef.current = metrics;\n\n const measure = useCallback(() => {\n const scroller = scrollerRef.current;\n const grid = gridRef.current;\n if (!scroller || !grid) return;\n const style = window.getComputedStyle(grid);\n const rowGap = parseFloat(style.rowGap) || 0;\n const columnGap = parseFloat(style.columnGap) || 0;\n const tracks = style.gridTemplateColumns\n .split(' ')\n .map((track) => parseFloat(track))\n .filter((track) => Number.isFinite(track));\n const headerHeight = headerRef.current?.getBoundingClientRect().height ?? 0;\n const firstBody = grid.querySelector<HTMLElement>(\n '[data-heatmap-body-row]',\n );\n const bodyHeight = firstBody?.getBoundingClientRect().height ?? 0;\n const next: Metrics = {\n headerBlock: headerHeight + rowGap,\n footerBlock: footerRef.current?.getBoundingClientRect().height ?? 0,\n rowPitch:\n (bodyHeight || headerHeight || DEFAULT_METRICS.rowPitch) + rowGap,\n leadInline: (tracks[0] ?? 0) + columnGap,\n colPitch: (tracks[1] ?? DEFAULT_METRICS.colPitch) + columnGap,\n viewportBlock: scroller.clientHeight,\n viewportInline: scroller.clientWidth,\n };\n const current = metricsRef.current;\n if (\n (Object.keys(next) as (keyof Metrics)[]).some(\n (key) => Math.abs(next[key] - current[key]) > 0.5,\n )\n ) {\n setMetrics(next);\n }\n }, []);\n\n useIsomorphicLayoutEffect(() => {\n measure();\n const scroller = scrollerRef.current;\n if (!scroller || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(() => measure());\n observer.observe(scroller);\n if (gridRef.current) observer.observe(gridRef.current);\n return () => observer.disconnect();\n }, [measure, body.length, columnCount, size, density]);\n\n const pinnedRow = activeKey === FOOTER_ROW_KEY ? null : activeRow;\n const pinnedCol = activeCol < columnCount ? activeCol : null;\n\n const computeWindows = useCallback((): {\n rows: AxisWindow;\n cols: AxisWindow;\n } => {\n if (!virtualised) {\n return { rows: fullWindow(body.length), cols: fullWindow(columnCount) };\n }\n const scroller = scrollerRef.current;\n const m = metricsRef.current;\n const rowRange = visibleRange({\n offset: scroller?.scrollTop ?? 0,\n viewport: m.viewportBlock,\n lead: m.headerBlock,\n pitch: m.rowPitch,\n count: body.length,\n });\n const colRange = visibleRange({\n offset: scroller?.scrollLeft ?? 0,\n viewport: m.viewportInline,\n lead: m.leadInline,\n pitch: m.colPitch,\n count: columnCount,\n });\n return {\n rows: axisWindow(rowRange, body.length, pinnedRow),\n cols: axisWindow(colRange, columnCount, pinnedCol),\n };\n }, [virtualised, body.length, columnCount, pinnedRow, pinnedCol]);\n\n const [windowState, setWindows] = useState(computeWindows);\n // Below the threshold every row and column renders, worked out here so a\n // change to the data never meets a window built for the old data. Above\n // it, the window is trimmed to the data until the layout effect below\n // re-syncs it (before paint).\n const fullRows = useMemo(() => fullWindow(body.length), [body.length]);\n const fullCols = useMemo(() => fullWindow(columnCount), [columnCount]);\n const windows = useMemo(\n () =>\n virtualised\n ? {\n rows: trimWindow(windowState.rows, body.length),\n cols: trimWindow(windowState.cols, columnCount),\n }\n : { rows: fullRows, cols: fullCols },\n [virtualised, windowState, body.length, columnCount, fullRows, fullCols],\n );\n const syncWindows = useCallback(() => {\n const next = computeWindows();\n setWindows((current) =>\n sameWindow(current.rows, next.rows) && sameWindow(current.cols, next.cols)\n ? current\n : next,\n );\n }, [computeWindows]);\n useIsomorphicLayoutEffect(() => {\n syncWindows();\n }, [syncWindows, metrics]);\n\n const frame = useRef(0);\n const onScroll = useCallback(() => {\n if (!virtualised || frame.current) return;\n frame.current = window.requestAnimationFrame(() => {\n frame.current = 0;\n syncWindows();\n });\n }, [virtualised, syncWindows]);\n useEffect(() => () => window.cancelAnimationFrame(frame.current), []);\n\n /* ---- focus follows the roving position ----------------------------- */\n // The active row went away (its group collapsed, rows changed): settle the\n // roving position on the row that took its place.\n useIsomorphicLayoutEffect(() => {\n if (activeKey !== undefined && activeKey !== active.rowKey) {\n setActive({ rowKey: activeKey, col: activeCol });\n }\n });\n // If the focused cell itself was removed (an agent collapsed the group\n // holding focus), focus would fall to the page with no blur event: put it\n // back on the active cell, now the group row.\n useIsomorphicLayoutEffect(() => {\n if (!hasFocusRef.current || pendingFocus.current) return;\n const current = document.activeElement;\n if (current && current !== document.body && current.isConnected) return;\n pendingFocus.current = true;\n });\n\n const cellElement = useCallback(\n (rowIndex: number, col: number): HTMLElement | null =>\n gridRef.current?.querySelector<HTMLElement>(\n `[role=\"row\"][aria-rowindex=\"${rowIndex + 2}\"] > [aria-colindex=\"${col + 2}\"]`,\n ) ?? null,\n [],\n );\n\n useIsomorphicLayoutEffect(() => {\n if (!pendingFocus.current) return;\n const element = cellElement(activeRow, activeCol);\n if (!element) return;\n pendingFocus.current = false;\n element.focus({ preventScroll: true });\n element.scrollIntoView?.({ block: 'nearest', inline: 'nearest' });\n });\n\n const isRtl = () =>\n gridRef.current\n ? window.getComputedStyle(gridRef.current).direction === 'rtl'\n : false;\n\n /* ---- range anchor -------------------------------------------------- */\n const anchor = useRef<{ rowIndex: number; col: number } | null>(null);\n const dataRowIndexAt = (navIndex: number): number | null => {\n const row = body[navIndex];\n return row && row.kind === 'data' ? row.rowIndex : null;\n };\n\n /** Set by a range press on the only selected cell: the click that\n * follows (with no drag) clears it, as Enter does. */\n const clearOnClick = useRef(false);\n\n const moveTo = (rowIndex: number, col: number) => {\n const clampedRow = Math.max(0, Math.min(navRowKeys.length - 1, rowIndex));\n const clampedCol = Math.max(0, Math.min(navColumnCount - 1, col));\n pendingFocus.current = true;\n setTooltipDismissed(false);\n setActive({ rowKey: navRowKeys[clampedRow], col: clampedCol });\n return { row: clampedRow, col: clampedCol };\n };\n\n /** Activates the cell at a navigable position (click, Enter, Space). */\n const activate = (navIndex: number, col: number, extend: boolean) => {\n const row = body[navIndex];\n if (!row) return;\n if (row.kind === 'group') {\n onToggleGroup(row.groupId);\n return;\n }\n if (col >= columnCount) return;\n if (selectionMode === 'range' && extend && anchor.current) {\n onRange(anchor.current, { rowIndex: row.rowIndex, col });\n return;\n }\n anchor.current = { rowIndex: row.rowIndex, col };\n onActivate(row.rowIndex, col, true);\n };\n\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n // A key on the group toggle (if something focused it) keeps its own\n // meaning: Enter on that button toggles the group, never selects the\n // last active cell. Keys on a cell, or on the grid itself (a click on a\n // header focuses it), drive the grid.\n if (event.target instanceof Element && event.target.closest('button')) {\n return;\n }\n interaction.current = 'keyboard';\n const lastRow = navRowKeys.length - 1;\n const lastCol = navColumnCount - 1;\n const forward = isRtl() ? -1 : 1;\n let row = activeRow;\n let col = activeCol;\n const ctrl = event.ctrlKey || event.metaKey;\n switch (event.key) {\n case 'ArrowRight':\n col += forward;\n break;\n case 'ArrowLeft':\n col -= forward;\n break;\n case 'ArrowDown':\n row += 1;\n break;\n case 'ArrowUp':\n row -= 1;\n break;\n case 'Home':\n col = 0;\n if (ctrl) row = 0;\n break;\n case 'End':\n col = lastCol;\n if (ctrl) row = lastRow;\n break;\n case 'PageDown': {\n const nextGroup = body.findIndex(\n (r, i) => i > activeRow && r.kind === 'group',\n );\n const hasGroups = body.some((r) => r.kind === 'group');\n row = hasGroups\n ? nextGroup === -1\n ? lastRow\n : nextGroup\n : activeRow + pageRows(metricsRef.current);\n break;\n }\n case 'PageUp': {\n let previous = -1;\n for (let i = Math.min(activeRow, body.length) - 1; i >= 0; i -= 1) {\n if (body[i].kind === 'group') {\n previous = i;\n break;\n }\n }\n const hasGroups = body.some((r) => r.kind === 'group');\n row = hasGroups\n ? previous === -1\n ? 0\n : previous\n : activeRow - pageRows(metricsRef.current);\n break;\n }\n case 'Enter':\n case ' ':\n event.preventDefault();\n activate(activeRow, activeCol, event.shiftKey);\n return;\n case 'Escape':\n if (tooltipAt) {\n event.preventDefault();\n setTooltipDismissed(true);\n }\n return;\n default:\n return;\n }\n event.preventDefault();\n const moved = moveTo(row, col);\n const isArrow = event.key.startsWith('Arrow');\n if (selectionMode === 'range' && event.shiftKey && isArrow) {\n const target = dataRowIndexAt(moved.row);\n const from =\n anchor.current ??\n (() => {\n const start = dataRowIndexAt(activeRow);\n return start === null || activeCol >= columnCount\n ? null\n : { rowIndex: start, col: activeCol };\n })();\n if (from && target !== null && moved.col < columnCount) {\n anchor.current = from;\n onRange(from, { rowIndex: target, col: moved.col });\n }\n }\n };\n\n /** The navigable position of the cell an event landed on. */\n const positionOf = (\n target: EventTarget | null,\n ): { row: number; col: number } | null => {\n if (!(target instanceof Element)) return null;\n const cell = target.closest<HTMLElement>('[role=\"gridcell\"]');\n const rowElement = cell?.parentElement;\n if (!cell || !rowElement || !gridRef.current?.contains(cell)) return null;\n const rowIndex = Number(rowElement.getAttribute('aria-rowindex')) - 2;\n const col = Number(cell.getAttribute('aria-colindex')) - 2;\n if (!Number.isInteger(rowIndex) || rowIndex < 0 || col < 0) return null;\n return { row: rowIndex, col };\n };\n\n const dragging = useRef(false);\n const lastPointer = useRef<string>('mouse');\n\n const onPointerDown = (event: PointerEvent<HTMLDivElement>) => {\n interaction.current = 'pointer';\n lastPointer.current = event.pointerType;\n if (\n selectionMode !== 'range' ||\n event.pointerType !== 'mouse' ||\n event.button !== 0\n ) {\n return;\n }\n const position = positionOf(event.target);\n clearOnClick.current = false;\n if (!position) return;\n const rowIndex = dataRowIndexAt(position.row);\n if (rowIndex === null || position.col >= columnCount) return;\n if (event.shiftKey && anchor.current) {\n onRange(anchor.current, { rowIndex, col: position.col });\n } else {\n anchor.current = { rowIndex, col: position.col };\n const key = selectionKey(rows[rowIndex].id, columns[position.col].id);\n if (selected.size === 1 && selected.has(key)) {\n // Pressing the only selected cell: a drag still starts a range from\n // it, but a plain click clears it (see onClick), as Enter does.\n clearOnClick.current = true;\n } else {\n onRange(anchor.current, anchor.current);\n }\n }\n dragging.current = true;\n const stop = () => {\n dragging.current = false;\n window.removeEventListener('pointerup', stop);\n window.removeEventListener('pointercancel', stop);\n };\n window.addEventListener('pointerup', stop);\n window.addEventListener('pointercancel', stop);\n };\n\n const onPointerMove = (event: PointerEvent<HTMLDivElement>) => {\n if (event.pointerType !== 'mouse') return;\n const position = positionOf(event.target);\n updateHover(\n position ? { rowKey: navRowKeys[position.row], col: position.col } : null,\n );\n if (dragging.current && position && anchor.current) {\n const rowIndex = dataRowIndexAt(position.row);\n if (rowIndex !== null && position.col < columnCount) {\n if (\n rowIndex !== anchor.current.rowIndex ||\n position.col !== anchor.current.col\n ) {\n clearOnClick.current = false;\n }\n if (!clearOnClick.current) {\n onRange(anchor.current, { rowIndex, col: position.col });\n }\n }\n }\n };\n\n // While the pointer rests on the tooltip, one document listener waits for\n // it to land somewhere else. Kept in a ref so there is never more than one\n // and it goes away with the grid.\n const awayListener = useRef<\n ((event: globalThis.PointerEvent) => void) | null\n >(null);\n const stopAway = useCallback(() => {\n if (!awayListener.current) return;\n document.removeEventListener('pointerover', awayListener.current);\n awayListener.current = null;\n }, []);\n useEffect(() => stopAway, [stopAway]);\n\n const onPointerLeave = (event: PointerEvent<HTMLDivElement>) => {\n // Moving onto the tooltip keeps it open (WCAG 1.4.13, hoverable); it\n // closes once the pointer leaves both.\n stopAway();\n const next = event.relatedTarget;\n if (next instanceof Element && next.closest('[data-component=\"tooltip\"]')) {\n const away = (moved: globalThis.PointerEvent) => {\n const over = moved.target;\n if (\n over instanceof Element &&\n over.closest('[data-component=\"tooltip\"]')\n ) {\n return;\n }\n stopAway();\n if (!(over instanceof Node && gridRef.current?.contains(over))) {\n updateHover(null);\n }\n };\n awayListener.current = away;\n document.addEventListener('pointerover', away);\n return;\n }\n updateHover(null);\n };\n\n const onClick = (event: MouseEvent<HTMLDivElement>) => {\n const button =\n event.target instanceof Element ? event.target.closest('button') : null;\n if (button) {\n // The group toggle has run its own onClick. Grid focus moves to the\n // group row, so the keys carry on from there.\n const navIndex =\n Number(button.closest('[role=\"row\"]')?.getAttribute('aria-rowindex')) -\n 2;\n // Keep the column, so a grid scrolled sideways stays where it is.\n if (Number.isInteger(navIndex) && navIndex >= 0) {\n moveTo(navIndex, activeCol);\n }\n return;\n }\n const position = positionOf(event.target);\n if (!position) return;\n moveTo(position.row, position.col);\n pendingFocus.current = false;\n // Range drags select on pointer down; a click only follows up for touch,\n // except to clear the only selected cell and to toggle a group.\n if (selectionMode === 'range' && lastPointer.current === 'mouse') {\n const row = body[position.row];\n if (row?.kind === 'group') {\n activate(position.row, position.col, false);\n } else if (row?.kind === 'data' && position.col < columnCount) {\n onActivate(row.rowIndex, position.col, clearOnClick.current);\n }\n clearOnClick.current = false;\n return;\n }\n activate(position.row, position.col, event.shiftKey);\n };\n\n /* ---- tooltip and scrolling ------------------------------------------ */\n // Radix closes a tooltip when anything around its trigger scrolls. A key\n // that moves focus scrolls the cell into view, so that close is not the\n // user dismissing it. This listener is added before any tooltip's, so it\n // marks the scroll first and the close below can tell. A hover tooltip\n // still closes on a scroll: the wheel moves the cell from under the\n // pointer without a pointer event.\n const scrolling = useRef(false);\n useEffect(() => {\n let settle = 0;\n const onAnyScroll = () => {\n scrolling.current = true;\n window.cancelAnimationFrame(settle);\n settle = window.requestAnimationFrame(() => {\n scrolling.current = false;\n });\n };\n window.addEventListener('scroll', onAnyScroll, { capture: true });\n return () => {\n window.removeEventListener('scroll', onAnyScroll, { capture: true });\n window.cancelAnimationFrame(settle);\n };\n }, []);\n\n /* ---- row context ---------------------------------------------------- */\n const onTooltipOpenChange = useCallback((open: boolean) => {\n if (open) return;\n // Only the focus tooltip (nothing hovered) outlives a scroll.\n if (scrolling.current && hoverRef.current === null) return;\n setTooltipDismissed(true);\n }, []);\n const expandLabel = useCallback(\n (group: string) => t('heatmap.expandGroup', { group }),\n [t],\n );\n const collapseLabel = useCallback(\n (group: string) => t('heatmap.collapseGroup', { group }),\n [t],\n );\n\n /* ---- the focused cell's description ------------------------------- */\n // A consumer's renderTooltip text reaches screen readers as the focused\n // cell's description; one hidden node, whatever the grid's size.\n const descriptionId = `${idBase}-description`;\n const focusedRow = body[activeRow];\n const description =\n describeFocused && focusedRow?.kind === 'data' && activeCol < columnCount\n ? tooltipText(cellInfo(focusedRow.rowIndex, activeCol))\n : null;\n\n const ctx = useMemo<RowContext>(\n () => ({\n rows,\n columns,\n matrix,\n scale,\n palette,\n describer,\n showValues,\n totals,\n rowTotals,\n groupColumnMethod,\n groupIds,\n selectable: selectionMode !== 'none',\n interactive,\n virtualised,\n colWindow: windows.cols,\n idBase,\n describedBy: describeFocused ? descriptionId : undefined,\n cellInfo,\n tooltipText,\n onTooltipOpenChange,\n onToggleGroup,\n expandLabel,\n collapseLabel,\n }),\n [\n rows,\n columns,\n matrix,\n scale,\n palette,\n describer,\n showValues,\n totals,\n rowTotals,\n groupColumnMethod,\n groupIds,\n selectionMode,\n interactive,\n virtualised,\n windows.cols,\n idBase,\n describeFocused,\n descriptionId,\n cellInfo,\n tooltipText,\n onTooltipOpenChange,\n onToggleGroup,\n expandLabel,\n collapseLabel,\n ],\n );\n\n /** Selected column indexes per data row id, comma-joined. */\n const selectedByRow = useMemo(() => {\n const map = new Map<string, number[]>();\n for (const key of selected) {\n const [rowId, columnKey] = splitSelectionKey(key);\n const col = columnIndexOfKey(columnKey);\n if (col === undefined) continue;\n const list = map.get(rowId) ?? [];\n list.push(col);\n map.set(rowId, list);\n }\n const joined = new Map<string, string>();\n for (const [rowId, list] of map) {\n joined.set(rowId, list.sort((a, b) => a - b).join(','));\n }\n return joined;\n }, [selected, columnIndexOfKey]);\n\n /* ---- header and footer ---------------------------------------------- */\n const highlightCol = highlight?.col ?? -1;\n const header = (\n <div\n ref={headerRef}\n role=\"row\"\n aria-rowindex={1}\n className={heatmapRowVariants({ position: 'header' })}\n >\n <div\n role=\"columnheader\"\n aria-colindex={1}\n className={heatmapColumnHeaderVariants({ corner: true })}\n >\n {rowsLabel ?? (\n <span className=\"ds:sr-only\">{t('heatmap.rowsHeader')}</span>\n )}\n </div>\n {renderColumns(windows.cols, (c) => (\n <div\n key={c}\n role=\"columnheader\"\n aria-colindex={c + 2}\n data-highlighted={highlightCol === c}\n className={heatmapColumnHeaderVariants()}\n >\n {describer.columnLabel(columns[c])}\n </div>\n ))}\n {rowTotals ? (\n <div\n role=\"columnheader\"\n aria-colindex={columnCount + 2}\n data-highlighted={highlightCol === columnCount}\n className={heatmapColumnHeaderVariants()}\n >\n {describer.methodLabel(rowTotals)}\n </div>\n ) : null}\n </div>\n );\n\n let footer: ReactElement | null = null;\n if (columnTotals && totals) {\n const footerIndex = body.length;\n const methodText = describer.methodLabel(columnTotals);\n const footerActive = activeRow === footerIndex;\n const total = (\n cell: ModelCell,\n c: number,\n columnText: string,\n rowText = methodText,\n ) => (\n <div\n key={c}\n role=\"gridcell\"\n aria-colindex={c + 2}\n aria-label={describer.sentence(rowText, columnText, cell)}\n tabIndex={footerActive && activeCol === c ? 0 : -1}\n className={heatmapCellVariants({ tone: aggregateTone(cell) })}\n >\n {describer.visibleText(cell)}\n </div>\n );\n footer = (\n <div\n ref={footerRef}\n role=\"row\"\n aria-rowindex={footerIndex + 2}\n className={heatmapRowVariants({ position: 'footer' })}\n >\n <div\n role=\"rowheader\"\n aria-colindex={1}\n data-highlighted={highlight?.rowKey === FOOTER_ROW_KEY}\n className={heatmapRowHeaderVariants({ kind: 'total', virtualised })}\n >\n {methodText}\n </div>\n {renderColumns(windows.cols, (c) =>\n total(totals.columns[c], c, describer.columnLabel(columns[c])),\n )}\n {rowTotals\n ? total(\n totals.grand,\n columnCount,\n describer.methodLabel(rowTotals),\n // The corner aggregates every cell by the row method, so it\n // is named for all cells, not for the footer's own method.\n t('heatmap.allCells'),\n )\n : null}\n </div>\n );\n }\n\n /* ---- body ----------------------------------------------------------- */\n const bodyRows: ReactElement[] = [];\n const rowWindow = windows.rows;\n if (rowWindow.lead > 0) {\n bodyRows.push(\n <div\n key=\"row-lead\"\n aria-hidden=\"true\"\n className={heatmapSpacerVariants({ axis: 'row-lead' })}\n />,\n );\n }\n rowWindow.indexes.forEach((navIndex, i) => {\n if (rowWindow.middle > 0 && i === rowWindow.middleAfter) {\n bodyRows.push(\n <div\n key=\"row-middle\"\n aria-hidden=\"true\"\n className={heatmapSpacerVariants({ axis: 'row-middle' })}\n />,\n );\n }\n const row = body[navIndex];\n if (!row) return;\n const isActiveRow = navIndex === activeRow;\n bodyRows.push(\n <HeatmapBodyRow\n key={row.key}\n ctx={ctx}\n row={row}\n ariaRowIndex={navIndex + 2}\n highlighted={highlight?.rowKey === row.key}\n activeCol={isActiveRow ? activeCol : -1}\n tooltipCol={tooltipAt?.rowKey === row.key ? tooltipAt.col : -1}\n selectedCols={\n row.kind === 'data'\n ? (selectedByRow.get(rows[row.rowIndex].id) ?? '')\n : ''\n }\n />,\n );\n });\n if (rowWindow.tail > 0) {\n bodyRows.push(\n <div\n key=\"row-tail\"\n aria-hidden=\"true\"\n className={heatmapSpacerVariants({ axis: 'row-tail' })}\n />,\n );\n }\n\n // Inline style: permitted per 23-constraints §Runtime-computed dimensions\n // (custom-property setter on the scroll box; the column count comes from\n // the data, the spans from the virtual window and the sticky sizes from\n // measurement. Every rule that reads them lives in CVA).\n const scrollerStyle = {\n '--heatmap-columns': String(Math.max(1, columnCount)),\n '--heatmap-row-lead': String(rowWindow.lead),\n '--heatmap-row-middle': String(rowWindow.middle),\n '--heatmap-row-tail': String(rowWindow.tail),\n '--heatmap-col-lead': String(windows.cols.lead),\n '--heatmap-col-middle': String(windows.cols.middle),\n '--heatmap-col-tail': String(windows.cols.tail),\n '--heatmap-sticky-block-start': `${metrics.headerBlock}px`,\n '--heatmap-sticky-block-end': `${metrics.footerBlock}px`,\n '--heatmap-sticky-inline-start': `${metrics.leadInline}px`,\n } as CSSProperties;\n\n return (\n <div\n ref={scrollerRef}\n onScroll={onScroll}\n // eslint-disable-next-line react/forbid-dom-props -- 23-constraints §Runtime-computed dimensions: custom-property setter only\n style={scrollerStyle}\n data-component=\"heatmap-grid\"\n className={heatmapScrollerVariants()}\n >\n <div\n ref={gridRef}\n role=\"grid\"\n // Focus lives on the cells (roving tabindex); -1 keeps the grid itself\n // out of the tab order while letting it hold focus programmatically.\n tabIndex={-1}\n aria-label={title}\n aria-rowcount={navRowKeys.length + 1}\n aria-colcount={navColumnCount + 1}\n aria-multiselectable={\n selectionMode === 'multiple' || selectionMode === 'range'\n ? true\n : undefined\n }\n data-heatmap-grid=\"\"\n className={heatmapGridVariants({\n size,\n density,\n virtualised,\n totalsColumn: Boolean(rowTotals),\n })}\n onKeyDown={onKeyDown}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerLeave={onPointerLeave}\n onClick={onClick}\n onFocus={(event) => {\n // Tabbing in counts as keyboard use, so the tooltip shows at once.\n if (event.target.matches(':focus-visible')) {\n interaction.current = 'keyboard';\n }\n hasFocusRef.current = true;\n setHasFocus(true);\n }}\n onBlur={(event) => {\n if (\n !event.currentTarget.contains(event.relatedTarget as Node | null)\n ) {\n hasFocusRef.current = false;\n setHasFocus(false);\n }\n }}\n >\n {header}\n {bodyRows}\n {footer}\n </div>\n {description !== null ? (\n <span id={descriptionId} hidden>\n {description}\n </span>\n ) : null}\n </div>\n );\n}\n","import { forwardRef, useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { formatLocale } from '../_shared/intl-locale';\nimport { useHeatmapContext } from './heatmap-context';\nimport { countFormatter, defaultValueFormatter } from './heatmap-format';\nimport {\n HEATMAP_STEPS,\n bucketStep,\n resolveScale,\n type HeatmapScale,\n type ResolvedHeatmapScale,\n} from './heatmap-scale';\nimport {\n heatmapLegendBarVariants,\n heatmapLegendVariants,\n heatmapSwatchVariants,\n stepTone,\n type HeatmapPalette,\n} from './heatmap-variants';\n\nexport interface HeatmapLegendProps {\n /**\n * `stepped` separates the ten steps; `continuous` joins them in a bar.\n * A quantile or threshold scale always shows its bands, one swatch per\n * step it uses, with the cut points between them.\n */\n variant?: 'stepped' | 'continuous';\n /** Palette. Inside a Heatmap it defaults to the Heatmap's. */\n palette?: HeatmapPalette;\n /** Scale. Inside a Heatmap it defaults to the Heatmap's resolved scale. */\n scale?: HeatmapScale;\n /** Values an `auto` or quantile scale is worked out from (outside a Heatmap). */\n values?: readonly number[];\n /** Formats the end labels. Inside a Heatmap it defaults to the Heatmap's. */\n valueFormatter?: (value: number) => string;\n /** Show the key for empty cells. Inside a Heatmap: when any cell is empty. */\n showEmpty?: boolean;\n /** Show the key for low-sample cells. Inside a Heatmap: when any cell is. */\n showLowSample?: boolean;\n /** Show the key for totals withheld to protect small numbers. Inside a\n * Heatmap: when any total it draws is withheld. */\n showWithheldTotal?: boolean;\n /** The sample threshold, named in the low-sample key. Inside a Heatmap it\n * defaults to the Heatmap's `minCount`. */\n minCount?: number;\n className?: string;\n}\n\nconst STEPS = Array.from({ length: HEATMAP_STEPS }, (_, step) => step);\n\n/** End labels for the bar of a sequential or diverging scale. */\nfunction endLabels(\n scale: ResolvedHeatmapScale,\n format: (value: number) => string,\n): { start: string; end: string; middle?: string } {\n return {\n start: scale.min === null ? '' : format(scale.min),\n end: scale.max === null ? '' : format(scale.max),\n middle:\n scale.type === 'diverging' && scale.midpoint !== undefined\n ? format(scale.midpoint)\n : undefined,\n };\n}\n\n/**\n * Heatmap.Legend: the colour steps with the low and high ends of the scale,\n * plus keys for empty and low-sample cells and withheld totals. A diverging scale shows its\n * midpoint between the two hues as a neutral swatch carrying the midpoint\n * value, the colour of a cell exactly on it. Inside a Heatmap it reads the\n * Heatmap's scale; render it elsewhere with `legend={false}` on the Heatmap\n * and the same `scale`, `palette` and `values` here.\n */\nexport const HeatmapLegend = forwardRef<HTMLDivElement, HeatmapLegendProps>(\n (\n {\n variant = 'stepped',\n palette: paletteProp,\n scale: scaleProp,\n values,\n valueFormatter,\n showEmpty,\n showLowSample,\n showWithheldTotal,\n minCount: minCountProp,\n className,\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation('ui');\n const context = useHeatmapContext();\n const locale = formatLocale(i18n.resolvedLanguage ?? i18n.language);\n\n const scale = useMemo(\n () =>\n scaleProp\n ? resolveScale(scaleProp, values ?? [])\n : (context?.scale ??\n resolveScale({ type: 'sequential' }, values ?? [])),\n [scaleProp, values, context?.scale],\n );\n const palette =\n paletteProp ??\n context?.palette ??\n (scale.type === 'diverging' ? 'diverging' : 'primary');\n const format =\n valueFormatter ??\n context?.describer.formatValue ??\n defaultValueFormatter(locale, 'number');\n\n // A quantile or threshold scale paints only a few steps: one per band.\n // Show those, with each cut point between its two bands, not ten\n // swatches of which most never appear.\n const banded =\n (scale.type === 'quantile' || scale.type === 'threshold') &&\n scale.thresholds.length > 0;\n const bandCount = scale.thresholds.length + 1;\n const bandSteps = banded\n ? Array.from({ length: bandCount }, (_, band) =>\n bucketStep(band, bandCount),\n )\n : [];\n const edges = scale.thresholds.map(format);\n\n const labels = endLabels(scale, format);\n const description = banded\n ? t('heatmap.legend.descriptionBands', {\n count: bandCount,\n formatted: countFormatter(locale)(bandCount),\n edges: new Intl.ListFormat(locale, {\n type: 'conjunction',\n }).format(edges),\n })\n : labels.middle !== undefined\n ? t('heatmap.legend.descriptionDiverging', {\n min: labels.start,\n max: labels.end,\n midpoint: labels.middle,\n })\n : t('heatmap.legend.description', {\n min: labels.start,\n max: labels.end,\n });\n // A banded scale with no cut (every value equal) paints one step.\n const singleStep =\n (scale.type === 'quantile' || scale.type === 'threshold') && !banded\n ? [scale.min === null ? HEATMAP_STEPS / 2 : scale.stepOf(scale.min)]\n : null;\n const withEmpty = showEmpty ?? context?.hasEmpty ?? false;\n const withLowSample = showLowSample ?? context?.hasLowSample ?? false;\n const withWithheldTotal =\n showWithheldTotal ?? context?.hasWithheldTotal ?? false;\n const minCount = minCountProp ?? context?.minCount;\n const shape = variant === 'continuous' ? 'continuous' : 'stepped';\n\n const bar = (steps: readonly number[]) => (\n <span className={heatmapLegendBarVariants({ variant })}>\n {steps.map((step) => (\n <span\n key={step}\n className={heatmapSwatchVariants({\n tone: stepTone(palette, step),\n shape,\n })}\n />\n ))}\n </span>\n );\n\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-label={t('heatmap.legend.label')}\n data-component=\"heatmap-legend\"\n className={heatmapLegendVariants({ className })}\n >\n <span className=\"ds:sr-only\">{description}</span>\n {banded ? (\n <span\n aria-hidden=\"true\"\n data-legend=\"bands\"\n className=\"ds:flex ds:min-w-0 ds:max-w-full ds:flex-wrap ds:items-center ds:gap-[var(--spacing-xs)] ds:tabular-nums\"\n >\n {bandSteps.map((step, band) => (\n <span\n key={step}\n className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]\"\n >\n <span\n data-step={step}\n className={heatmapSwatchVariants({\n tone: stepTone(palette, step),\n shape: 'key',\n })}\n />\n {band < edges.length ? (\n <span className=\"ds:shrink-0\">{edges[band]}</span>\n ) : null}\n </span>\n ))}\n </span>\n ) : (\n <span\n aria-hidden=\"true\"\n className=\"ds:flex ds:min-w-0 ds:max-w-full ds:items-center ds:gap-[var(--spacing-xs)] ds:tabular-nums\"\n >\n <span className=\"ds:shrink-0\">{labels.start}</span>\n {labels.middle !== undefined ? (\n <>\n {bar(STEPS.slice(0, HEATMAP_STEPS / 2))}\n {/* A value exactly on the midpoint is painted neutral, so\n its swatch sits between the hues, carrying the value. */}\n <span\n data-legend=\"midpoint\"\n className={heatmapSwatchVariants({\n tone: 'midpoint',\n shape: 'label',\n })}\n >\n {labels.middle}\n </span>\n {bar(STEPS.slice(HEATMAP_STEPS / 2))}\n </>\n ) : (\n bar(singleStep ?? STEPS)\n )}\n <span className=\"ds:shrink-0\">{labels.end}</span>\n </span>\n )}\n {withEmpty ? (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <span\n aria-hidden=\"true\"\n className={heatmapSwatchVariants({ tone: 'empty' })}\n />\n {t('heatmap.legend.noData')}\n </span>\n ) : null}\n {withLowSample ? (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <span\n aria-hidden=\"true\"\n className={heatmapSwatchVariants({ tone: 'low-sample' })}\n />\n {minCount === undefined\n ? t('heatmap.legend.lowSample')\n : t('heatmap.legend.lowSampleUnder', {\n value: new Intl.NumberFormat(locale).format(minCount),\n })}\n </span>\n ) : null}\n {withWithheldTotal ? (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n <span\n aria-hidden=\"true\"\n className={heatmapSwatchVariants({ tone: 'low-sample' })}\n />\n {t('heatmap.legend.totalWithheld')}\n </span>\n ) : null}\n </div>\n );\n },\n);\n\nHeatmapLegend.displayName = 'HeatmapLegend';\n","import {\n lazy,\n Suspense,\n useMemo,\n useRef,\n useState,\n type ComponentType,\n} from 'react';\nimport type { ColDef, GridOptions } from 'ag-grid-community';\nimport { useTranslation } from 'react-i18next';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport type { DataTableProps } from '../data-table/data-table';\nimport { ErrorBoundary } from '../error-boundary';\nimport { Skeleton } from '../skeleton';\nimport type { HeatmapDescriber } from './heatmap-format';\nimport type {\n BodyRow,\n HeatmapColumn,\n HeatmapRow,\n HeatmapTotals,\n ModelCell,\n} from './heatmap-model';\nimport { heatmapTableViewVariants } from './heatmap-variants';\nimport type { HeatmapAggregate } from './heatmap-scale';\n\n/** One row of the table view: a data row or a group's totals. */\ninterface HeatmapTableRow {\n id: string;\n group?: string;\n row: string;\n cells: string[];\n total?: string;\n}\n\n/*\n * The DataTable (AG Grid) loads on demand: nothing in the heatmap's own\n * entry imports AG Grid, so a heatmap that never shows its table never\n * downloads it. Every table in the kit is DataTable. The consumer installs\n * ag-grid-community and ag-grid-react (src/docs/25-consuming.mdx).\n */\nconst loadDataTable = () =>\n import('../data-table/data-table').then((module) => ({\n default: module.DataTable as unknown as ComponentType<\n DataTableProps<HeatmapTableRow>\n >,\n }));\nconst LazyDataTable = lazy(loadDataTable);\n\n/** Starts fetching the table chunk ahead of a switch to the table view, so\n * the switch does not wait on the download. Safe to call repeatedly. */\nexport function preloadHeatmapTable(): void {\n loadDataTable().catch(() => {\n /* the switch itself retries and shows the error */\n });\n}\n\nexport interface HeatmapTableViewProps {\n title: string;\n rowsLabel?: string;\n rows: readonly HeatmapRow[];\n columns: readonly HeatmapColumn[];\n matrix: readonly ModelCell[][];\n /** Group headers and rows in display order, every group expanded. */\n body: readonly BodyRow[];\n grouped: boolean;\n /** Each group's public id, for the table's row ids (never a label). */\n groupIds: ReadonlyMap<string, string>;\n describer: HeatmapDescriber;\n /** The grid's totals, withheld ones already reduced to a value-less\n * cell, so the table can show nothing the grid does not. */\n totals: HeatmapTotals | null;\n rowTotals: HeatmapAggregate | false;\n columnTotals: HeatmapAggregate | false;\n groupColumnMethod: HeatmapAggregate;\n /** The table failed to load or render (announced by the heatmap). */\n onLoadError?: () => void;\n}\n\n/** Stands in for a group total that was not worked out. */\nconst NO_TOTAL: ModelCell = { value: null, status: 'empty' };\n\n/**\n * The heatmap's \"View as table\": the same rows, columns, values, counts and\n * totals as a DataTable, so every number is reachable without colour and\n * without a pointer. Group header rows carry their totals, and rows stay in\n * their groups in the grid's order. Labels go through the same privacy\n * masking as the grid.\n */\nexport function HeatmapTableView({\n title,\n rowsLabel,\n rows,\n columns,\n matrix,\n body,\n grouped,\n groupIds,\n describer,\n totals,\n rowTotals,\n columnTotals,\n groupColumnMethod,\n onLoadError,\n}: HeatmapTableViewProps) {\n const { t } = useTranslation('ui');\n\n const columnDefs = useMemo<ColDef<HeatmapTableRow>[]>(\n () => [\n ...(grouped\n ? [\n {\n colId: 'group',\n field: 'group' as const,\n headerName: t('heatmap.table.group'),\n // A sort here would pull rows out of their groups.\n sortable: false,\n },\n ]\n : []),\n {\n colId: 'row',\n field: 'row' as const,\n headerName: rowsLabel ?? t('heatmap.rowsHeader'),\n sortable: !grouped,\n },\n ...columns.map(\n (column, c): ColDef<HeatmapTableRow> => ({\n colId: `c${c}`,\n headerName: describer.columnLabel(column),\n valueGetter: (params) => params.data?.cells[c] ?? '',\n sortable: false,\n }),\n ),\n ...(rowTotals\n ? [\n {\n colId: 'total',\n field: 'total' as const,\n headerName: describer.methodLabel(rowTotals),\n sortable: false,\n },\n ]\n : []),\n ],\n [grouped, rowsLabel, columns, describer, rowTotals, t],\n );\n\n const rowData = useMemo<HeatmapTableRow[]>(\n () =>\n body.map((entry): HeatmapTableRow => {\n if (entry.kind === 'group') {\n const groupText = describer.groupLabel(entry.groupId);\n const perColumn = totals?.groupColumns.get(entry.groupId) ?? [];\n return {\n id: `group:${groupIds.get(entry.groupId) ?? ''}`,\n group: groupText,\n row: describer.groupRowText(groupText, groupColumnMethod),\n cells: columns.map((_, c) =>\n describer.tableText(perColumn[c] ?? NO_TOTAL),\n ),\n total:\n rowTotals && totals\n ? describer.tableText(\n totals.groups.get(entry.groupId) ?? NO_TOTAL,\n )\n : undefined,\n };\n }\n const r = entry.rowIndex;\n const groupId = rows[r].group;\n return {\n id: `row:${rows[r].id}`,\n group:\n grouped && groupId !== undefined\n ? describer.groupLabel(groupId)\n : undefined,\n row: describer.rowLabel(rows[r]),\n cells: matrix[r].map((cell) => describer.tableText(cell)),\n total:\n rowTotals && totals\n ? describer.tableText(totals.rows[r])\n : undefined,\n };\n }),\n [\n body,\n rows,\n columns,\n matrix,\n grouped,\n groupIds,\n describer,\n rowTotals,\n totals,\n groupColumnMethod,\n ],\n );\n\n const pinnedBottomRowData = useMemo<HeatmapTableRow[] | undefined>(\n () =>\n columnTotals && totals\n ? [\n {\n id: 'heatmap-column-totals',\n row: describer.methodLabel(columnTotals),\n cells: totals.columns.map((cell) => describer.tableText(cell)),\n // The grand total, by the row method, as the grid's corner.\n total: rowTotals ? describer.tableText(totals.grand) : undefined,\n },\n ]\n : undefined,\n [columnTotals, rowTotals, totals, describer],\n );\n\n /*\n * Height: the table grows with its rows (AG Grid autoHeight) up to\n * --heatmap-max-block-size, so a small grid leaves no empty space. Past\n * that it holds the maximum and scrolls inside, keeping its header in\n * view. AG Grid has no max height for autoHeight, so the wrapper's own\n * max-height detects the overflow and switches the layout. Remembered\n * per row count: new rows fit again from scratch.\n */\n const rowCount = rowData.length + (pinnedBottomRowData?.length ?? 0);\n const rowCountRef = useRef(rowCount);\n rowCountRef.current = rowCount;\n const [cappedAt, setCappedAt] = useState<number | null>(null);\n const capped = cappedAt === rowCount;\n const wrapperRef = useRef<HTMLDivElement>(null);\n\n useIsomorphicLayoutEffect(() => {\n const wrapper = wrapperRef.current;\n if (capped || !wrapper || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(() => {\n if (wrapper.scrollHeight > wrapper.clientHeight + 1) {\n setCappedAt(rowCountRef.current);\n }\n });\n // Watch the content as well as the box: once the box reaches its\n // maximum it stops resizing, but the table inside may still grow.\n const watch = () => {\n observer.observe(wrapper);\n for (const child of Array.from(wrapper.children)) observer.observe(child);\n };\n watch();\n const children = new MutationObserver(watch);\n children.observe(wrapper, { childList: true });\n return () => {\n observer.disconnect();\n children.disconnect();\n };\n }, [capped]);\n\n const gridOptions = useMemo<GridOptions<HeatmapTableRow>>(\n () => ({\n getRowId: (params) => params.data.id,\n domLayout: capped ? 'normal' : 'autoHeight',\n }),\n [capped],\n );\n\n // A failed chunk load stays failed inside one lazy component, so a retry\n // makes a fresh one; the first attempt shares the module-level loader.\n const [attempt, setAttempt] = useState(0);\n const DataTable = useMemo(\n () => (attempt === 0 ? LazyDataTable : lazy(loadDataTable)),\n [attempt],\n );\n\n return (\n <div\n ref={wrapperRef}\n role=\"group\"\n aria-label={title}\n // Holds focus while a retry replaces the error state's button.\n tabIndex={-1}\n data-component=\"heatmap-table\"\n data-layout={capped ? 'capped' : 'fit'}\n className={heatmapTableViewVariants({ capped })}\n >\n <ErrorBoundary\n size=\"sm\"\n onError={() => onLoadError?.()}\n onRetry={() => {\n setAttempt((current) => current + 1);\n wrapperRef.current?.focus();\n }}\n >\n <Suspense\n fallback={\n <div role=\"status\" aria-label={t('heatmap.loadingTable')}>\n <Skeleton\n variant=\"rectangular\"\n className=\"ds:h-[calc(var(--min-target-size)*4)] ds:w-full\"\n />\n </div>\n }\n >\n <DataTable\n columnDefs={columnDefs}\n rowData={rowData}\n pinnedBottomRowData={pinnedBottomRowData}\n density=\"compact\"\n heightClass={capped ? 'ds:min-h-0 ds:flex-1' : ''}\n gridOptions={gridOptions}\n />\n </Suspense>\n </ErrorBoundary>\n </div>\n );\n}\n","import {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport { Grid3x3, Table2 } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { useAgentRegistration } from '../../agent';\nimport { formatLocale } from '../_shared/intl-locale';\nimport { Button } from '../button';\nimport { EmptyState } from '../empty-state';\nimport { LiveRegion } from '../live-region';\nimport { Skeleton } from '../skeleton';\nimport { TooltipProvider } from '../tooltip';\nimport { heatmapAgent } from './heatmap.agent';\nimport { HeatmapContext, type HeatmapContextValue } from './heatmap-context';\nimport {\n countFormatter,\n createDescriber,\n defaultValueFormatter,\n type HeatmapPrivacyScope,\n type HeatmapValueType,\n} from './heatmap-format';\nimport {\n HeatmapGrid,\n selectionKey,\n splitSelectionKey,\n type HeatmapSelectionMode,\n} from './heatmap-grid';\nimport { HeatmapLegend } from './heatmap-legend';\nimport {\n buildBodyRows,\n buildMatrix,\n computeTotals,\n hasAnyData,\n publicGroupIds,\n shownValues,\n sortRowIndexes,\n type HeatmapCellInfo,\n type HeatmapCellInput,\n type HeatmapCellKey,\n type HeatmapColumn,\n type HeatmapGetTotal,\n type HeatmapGroup,\n type HeatmapRow,\n type HeatmapSortRows,\n type ModelCell,\n} from './heatmap-model';\nimport {\n resolveScale,\n type HeatmapAggregate,\n type HeatmapScale,\n} from './heatmap-scale';\nimport { HeatmapTableView, preloadHeatmapTable } from './heatmap-table-view';\nimport { HeatmapTooltip } from './heatmap-tooltip';\nimport {\n heatmapRootVariants,\n heatmapToolbarVariants,\n type HeatmapPalette,\n} from './heatmap-variants';\nimport { VIRTUALISE_CELL_THRESHOLD } from './heatmap-window';\n\nexport type {\n HeatmapCellData,\n HeatmapCellInfo,\n HeatmapCellInput,\n HeatmapCellKey,\n HeatmapCellStatus,\n HeatmapColumn,\n HeatmapGetTotal,\n HeatmapGroup,\n HeatmapRow,\n HeatmapSortRows,\n HeatmapTotalScope,\n} from './heatmap-model';\nexport type { HeatmapAggregate, HeatmapScale } from './heatmap-scale';\nexport type { HeatmapPalette } from './heatmap-variants';\nexport type { HeatmapPrivacyScope, HeatmapValueType } from './heatmap-format';\nexport type { HeatmapSelectionMode } from './heatmap-grid';\n\n/** What `renderTooltip` is told besides the cell. */\nexport interface HeatmapTooltipContext {\n /**\n * True in privacy mode. The cell's labels are then already masked (and\n * its free-text `label` dropped), so text built from them is safe to show.\n */\n privacyMode: boolean;\n}\n\n/** Which presentation is showing. */\nexport type HeatmapView = 'heatmap' | 'table';\n\n/** What one cell reads back to an agent: structure and numbers, no labels. */\nexport interface HeatmapCellReading {\n value: number | null;\n count?: number;\n status: HeatmapCellInfo['status'];\n /** As `HeatmapCellInfo.step`: a value exactly on a diverging midpoint\n * reads step 5, though it is painted neutral grey. */\n step: number | null;\n}\n\n/**\n * Curated handle for the agent adapter (see heatmap.agent.ts). Ids only,\n * never labels. Group ids are the public ones: a group's own id when it is\n * listed in `groups`, else `group-<n>`. Every write throws on an id the\n * heatmap does not have, before it changes or announces anything.\n */\nexport interface HeatmapHandle {\n getSelection: () => HeatmapCellKey[];\n getSelectionMode: () => HeatmapSelectionMode;\n selectCells: (cells: readonly HeatmapCellKey[]) => void;\n selectRange: (from: HeatmapCellKey, to: HeatmapCellKey) => void;\n clearSelection: () => void;\n readCell: (cell: HeatmapCellKey) => HeatmapCellReading | null;\n getView: () => HeatmapView;\n setView: (view: HeatmapView) => void;\n getSortRows: () => HeatmapSortRows;\n setSortRows: (sort: HeatmapSortRows) => void;\n /** Row ids in display order, every group expanded. */\n getRowIds: () => string[];\n /** Column ids in order. */\n getColumnIds: () => (string | number)[];\n /** Group ids in display order; empty unless `groupRows` is on. */\n getGroupIds: () => string[];\n getCollapsedGroups: () => string[];\n setGroupCollapsed: (groupId: string, collapsed: boolean) => void;\n}\n\n/*\n * Memoisation: `rows`, `columns`, `getCell`, `cells`, `getTotal`, `groups`\n * and `valueFormatter` key the cell matrix, the totals and the wording every row\n * renders with. Keep them stable (useMemo, useCallback, or module scope): a\n * new array or an inline function on each parent render rebuilds them all.\n */\nexport interface HeatmapProps {\n /**\n * Required. Names the grid for assistive technology and the table view.\n * Never masked, so it must not name a person.\n */\n title: string;\n /** Rows, top to bottom. Keep the array stable (see Memoisation). */\n rows: readonly HeatmapRow[];\n /** Columns, in reading order. Keep the array stable. */\n columns: readonly HeatmapColumn[];\n /**\n * Returns a cell's data. Use this or `cells`. Keep it stable\n * (`useCallback`): an inline function rebuilds the matrix every render.\n */\n getCell?: (\n row: HeatmapRow,\n column: HeatmapColumn,\n rowIndex: number,\n columnIndex: number,\n ) => HeatmapCellInput;\n /** The cells as a `[row][column]` matrix, in the order of `rows` and `columns`. */\n cells?: readonly (readonly HeatmapCellInput[])[];\n /** Visible labels for the group ids rows carry. Keep the array stable. */\n groups?: readonly HeatmapGroup[];\n /** How values map to colour steps. Default sequential with an auto domain. */\n scale?: HeatmapScale;\n /** Colour palette. Default `diverging` for a diverging scale, else `primary`. */\n palette?: HeatmapPalette;\n /**\n * `rate` for proportions between 0 and 1: formats as a percentage and\n * reads counts as \"10 of 39\". Default `number`.\n */\n valueType?: HeatmapValueType;\n /**\n * Cells with a count below this render as \"too few to show\", hatched.\n * For a cell it is a display rule, not disclosure control: `read_cell`,\n * `onCellClick` and `onSelectionChange` still carry any value you pass.\n * To keep a value off the page, send `{ value: null, count }`: it still\n * renders as too few, and nothing can read a value the kit never had.\n * Totals follow small-number disclosure control: any total that, in any\n * combination with the other totals and cells, would pin down a hidden\n * cell, narrow it below the protection level (half its range, for a\n * rate), or determine a set of hidden cells with fewer than minCount\n * records, is withheld too, and carries no value anywhere. Every total\n * the data could show is audited, drawn or not. See `getTotal` and\n * heatmap.mdx.\n */\n minCount?: number;\n /**\n * Supplies a total: a row's, a column's, a group's, a group header cell\n * or the grand total, as `scope.kind` says. Return a cell input (`null`\n * for no total), or `undefined` to let the kit work it out from the\n * cells. Needed when you withhold values (`value: null`): the kit cannot\n * add up a value it never had, so it withholds any total it would get\n * wrong. `minCount` and the disclosure audit apply to a supplied total\n * exactly as to a worked-out one, which must be the exact count-weighted\n * mean (or sum) of its cells. Asked for every row, every column and the\n * grand total, and, whenever rows carry a group, every group and group\n * header cell, drawn or not. Keep it stable (`useCallback`).\n */\n getTotal?: HeatmapGetTotal;\n /** Formats a value. Default: Intl in the active locale. Keep it stable. */\n valueFormatter?: (value: number) => string;\n /** Print the value inside each cell. */\n showValues?: boolean;\n /** Built-in legend above the grid, or `false` to place `Heatmap.Legend` yourself. */\n legend?: 'stepped' | 'continuous' | false;\n /**\n * A totals column at the row ends. A mean weights by count. Everything in\n * that column uses this method: each row's total, each group's and the\n * grand total in the corner. With `minCount`, a mean of plain numbers\n * (`valueType=\"number\"`) is not audited for hidden cells: every such\n * average that holds one is withheld, so use `sum` for plain numbers.\n */\n rowTotals?: HeatmapAggregate | false;\n /**\n * A totals row under the columns. A mean weights by count. A group\n * header's per-column totals use this method too (else `rowTotals`).\n * With `minCount`, a mean of plain numbers is withheld wherever it holds\n * a hidden cell, as for `rowTotals`: use `sum` for plain numbers.\n */\n columnTotals?: HeatmapAggregate | false;\n /**\n * Row order (within each group). Controlled when set. In privacy mode\n * `label` keeps the given order: sorting by masked names would reveal\n * their order. A sort by total reads each row's total by the\n * `rowTotals` method (else the `columnTotals` one, else mean); a row\n * whose total is withheld sorts last.\n */\n sortRows?: HeatmapSortRows;\n /** Initial row order when uncontrolled. Default `none`. */\n defaultSortRows?: HeatmapSortRows;\n /** Called when the row order changes (agent `sort_rows`). */\n onSortRowsChange?: (sort: HeatmapSortRows) => void;\n /** Group rows by `row.group`, each group collapsible with its totals. */\n groupRows?: boolean;\n /** Group ids that start collapsed. */\n defaultCollapsedGroups?: readonly string[];\n /** How cells are selected. Default `none`. */\n selection?: HeatmapSelectionMode;\n /** Selected cells. Controlled when set. */\n selectedCells?: readonly HeatmapCellKey[];\n /** Initially selected cells when uncontrolled. */\n defaultSelectedCells?: readonly HeatmapCellKey[];\n /** Called with every cell in the new selection. */\n onSelectionChange?: (cells: HeatmapCellInfo[]) => void;\n /** Called when a cell is clicked, or activated with Enter or Space. */\n onCellClick?: (cell: HeatmapCellInfo) => void;\n /**\n * Tooltip text for a cell. Plain text: the kit Tooltip is text-only. It\n * also describes the focused cell to screen readers (aria-describedby).\n * In privacy mode the cell arrives with its labels masked, its free-text\n * `label` dropped and `row.group` replaced by the public group id, and\n * the context says so.\n */\n renderTooltip?: (\n cell: HeatmapCellInfo,\n context: HeatmapTooltipContext,\n ) => string;\n /** `compact` removes the gap between cells. Cells never shrink below the target size. */\n density?: 'compact' | 'default';\n /** Cell size. Every size keeps cells at least `--min-target-size`. */\n size?: 'sm' | 'md' | 'lg';\n /** Shows a skeleton while data loads. */\n loading?: boolean;\n /**\n * Masks row labels (people, chairs, patients) in the grid, the tooltip,\n * the table view and the announcements, and drops free-text cell labels.\n * Columns and groups stay readable unless `privacyScope=\"all\"`. `title`\n * and `rowsLabel` are never masked.\n */\n privacyMode?: boolean;\n /**\n * What privacy mode masks: `rows` (default) or `all`, which masks column\n * and group labels too.\n */\n privacyScope?: HeatmapPrivacyScope;\n /**\n * Names what the rows are (\"Chair\"): the corner header and the table's\n * first column. Never masked, so it must not name a person.\n */\n rowsLabel?: string;\n /** Initial presentation. Default `heatmap`. */\n defaultView?: HeatmapView;\n /** Called when the view switches between heatmap and table. */\n onViewChange?: (view: HeatmapView) => void;\n /** Instance id: `data-component-id`, and the agent registry key. */\n id?: string;\n className?: string;\n /**\n * Rendered inside the heatmap's context, after the grid (e.g.\n * `Heatmap.Legend`). Also while loading and when empty.\n */\n children?: ReactNode;\n}\n\nconst DEFAULT_SCALE: HeatmapScale = { type: 'sequential', domain: 'auto' };\n\n/** Selection keys for cells, by row id and column id (never by position,\n * so a change to `columns` keeps every selected cell on its own column). */\nconst toKeySet = (cells: readonly HeatmapCellKey[] | undefined): Set<string> =>\n new Set((cells ?? []).map((cell) => selectionKey(cell.rowId, cell.columnId)));\n\n/** What the live region says, and under which privacy setting it was made. */\ninterface Announcement {\n text: string;\n privacyMode: boolean;\n /** Bumped when the same words are said again, so they are heard again. */\n repeat: number;\n}\n\nconst SILENCE: Announcement = { text: '', privacyMode: false, repeat: 0 };\n\nconst HeatmapRoot = forwardRef<HTMLDivElement, HeatmapProps>(\n (\n {\n title,\n rows,\n columns,\n getCell,\n cells,\n groups,\n scale: scaleProp = DEFAULT_SCALE,\n palette: paletteProp,\n valueType = 'number',\n minCount,\n getTotal,\n valueFormatter,\n showValues = false,\n legend = 'stepped',\n rowTotals = false,\n columnTotals = false,\n sortRows: sortRowsProp,\n defaultSortRows = 'none',\n onSortRowsChange,\n groupRows = false,\n defaultCollapsedGroups,\n selection = 'none',\n selectedCells,\n defaultSelectedCells,\n onSelectionChange,\n onCellClick,\n renderTooltip,\n density = 'default',\n size = 'md',\n loading = false,\n privacyMode = false,\n privacyScope = 'rows',\n rowsLabel,\n defaultView = 'heatmap',\n onViewChange,\n id,\n className,\n children,\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation('ui');\n const locale = formatLocale(i18n.resolvedLanguage ?? i18n.language);\n\n /* ---- data ---------------------------------------------------------- */\n const matrix = useMemo(\n () => buildMatrix(rows, columns, getCell, cells, minCount),\n [rows, columns, getCell, cells, minCount],\n );\n const values = useMemo(() => shownValues(matrix), [matrix]);\n // Consumers often pass the scale inline; key it by content so an equal\n // scale does not re-resolve on every render.\n const scaleKey = JSON.stringify(scaleProp);\n const scale = useMemo(\n () => resolveScale(scaleProp, values),\n // eslint-disable-next-line react-hooks/exhaustive-deps -- keyed by content\n [scaleKey, values],\n );\n const palette: HeatmapPalette =\n paletteProp ?? (scale.type === 'diverging' ? 'diverging' : 'primary');\n\n const formatValue = useMemo(\n () => valueFormatter ?? defaultValueFormatter(locale, valueType),\n [valueFormatter, locale, valueType],\n );\n const formatCount = useMemo(() => countFormatter(locale), [locale]);\n const describer = useMemo(\n () =>\n createDescriber({\n t,\n privacyMode,\n privacyScope,\n valueType,\n formatValue,\n formatCount,\n groups,\n }),\n [\n t,\n privacyMode,\n privacyScope,\n valueType,\n formatValue,\n formatCount,\n groups,\n ],\n );\n const groupIds = useMemo(\n () => publicGroupIds(rows, groups),\n [rows, groups],\n );\n\n // A group header's per-column totals are column margins within the\n // group, so they follow the column method; everything in the row-totals\n // column follows the row method (see computeTotals).\n const groupColumnMethod: HeatmapAggregate =\n columnTotals || rowTotals || 'mean';\n // Every total is worked out and audited, drawn or not (row totals also\n // order a sort by total), so an undrawn kind follows the drawn one:\n // every total stays in one unit.\n const rowMethod: HeatmapAggregate = rowTotals || columnTotals || 'mean';\n const columnMethod: HeatmapAggregate = columnTotals || rowTotals || 'mean';\n\n /* ---- announcements ---------------------------------------------------- */\n const [announcement, setAnnouncement] = useState<Announcement>(SILENCE);\n const announceTimer = useRef(0);\n const privacyRef = useRef(privacyMode);\n privacyRef.current = privacyMode;\n const announce = useCallback((message: string, settle = false) => {\n window.clearTimeout(announceTimer.current);\n const madeUnder = privacyRef.current;\n const say = () =>\n setAnnouncement((current) => ({\n text: message,\n privacyMode: madeUnder,\n repeat: current.text === message ? current.repeat + 1 : 0,\n }));\n if (settle) {\n // A drag changes the selection on every cell it crosses; say only\n // where it settles.\n announceTimer.current = window.setTimeout(say, 300);\n } else {\n say();\n }\n }, []);\n useEffect(() => () => window.clearTimeout(announceTimer.current), []);\n // A message made before privacy mode turned on may name a row. Drop it\n // (and any still waiting) when the mode changes; until that lands, the\n // render below already refuses to show it.\n useEffect(() => {\n window.clearTimeout(announceTimer.current);\n setAnnouncement((current) => (current.text === '' ? current : SILENCE));\n }, [privacyMode]);\n const spoken =\n announcement.privacyMode === privacyMode\n ? // The same words twice leave the DOM unchanged and a screen reader\n // silent: a trailing no-break space on every other repeat changes\n // the text without changing what is read.\n `${announcement.text}${announcement.repeat % 2 === 1 ? '\\u00a0' : ''}`\n : '';\n\n /* ---- view, sort and groups ------------------------------------------ */\n const [view, setViewState] = useState<HeatmapView>(defaultView);\n\n const setView = useCallback(\n (next: HeatmapView) => {\n setViewState(next);\n onViewChange?.(next);\n announce(\n next === 'table'\n ? t('heatmap.announce.tableView')\n : t('heatmap.announce.heatmapView'),\n );\n },\n [onViewChange, announce, t],\n );\n\n const [sortInternal, setSortInternal] =\n useState<HeatmapSortRows>(defaultSortRows);\n const sortRows = sortRowsProp ?? sortInternal;\n const setSortRows = useCallback(\n (next: HeatmapSortRows) => {\n if (sortRowsProp === undefined) setSortInternal(next);\n onSortRowsChange?.(next);\n },\n [sortRowsProp, onSortRowsChange],\n );\n\n const [collapsed, setCollapsed] = useState<ReadonlySet<string>>(\n () => new Set(defaultCollapsedGroups ?? []),\n );\n const setGroupCollapsed = useCallback(\n (groupId: string, isCollapsed: boolean) => {\n // Already so: nothing changes, so nothing is said.\n if (collapsed.has(groupId) === isCollapsed) return;\n setCollapsed((current) => {\n if (current.has(groupId) === isCollapsed) return current;\n const next = new Set(current);\n if (isCollapsed) next.add(groupId);\n else next.delete(groupId);\n return next;\n });\n const label = describer.groupLabel(groupId);\n announce(\n isCollapsed\n ? t('heatmap.announce.groupCollapsed', { group: label })\n : t('heatmap.announce.groupExpanded', { group: label }),\n );\n },\n [collapsed, announce, describer, t],\n );\n const toggleGroup = useCallback(\n (groupId: string) => setGroupCollapsed(groupId, !collapsed.has(groupId)),\n [collapsed, setGroupCollapsed],\n );\n\n const collator = useMemo(\n () => new Intl.Collator(locale, { numeric: true, sensitivity: 'base' }),\n [locale],\n );\n // A label sort under masked labels would still order the rows by the\n // hidden names, and so reveal their order: in privacy mode it keeps the\n // given order.\n const appliedSort: HeatmapSortRows =\n sortRows === 'label' && describer.masksRows ? 'none' : sortRows;\n\n // Every total, with the ones that would give away a hidden cell\n // withheld (see computeTotals). The audit covers every total this data\n // could show, drawn or not: row totals order the rows in a sort by\n // total, and a change to the sort, the totals props or groupRows must\n // never combine two views into a disclosure. So the result depends on\n // the data alone.\n const totals = useMemo(\n () =>\n computeTotals(matrix, rows, columns, {\n rowMethod,\n columnMethod,\n groupColumnMethod,\n groups,\n minCount,\n getTotal,\n valueType,\n }),\n [\n matrix,\n rows,\n columns,\n rowMethod,\n columnMethod,\n groupColumnMethod,\n groups,\n minCount,\n getTotal,\n valueType,\n ],\n );\n const order = useMemo(\n () =>\n sortRowIndexes(\n rows.map((_, r) => r),\n rows,\n totals.rows,\n appliedSort,\n collator,\n ),\n [rows, totals.rows, appliedSort, collator],\n );\n const body = useMemo(\n () => buildBodyRows(rows, order, groupRows, collapsed),\n [rows, order, groupRows, collapsed],\n );\n /** Every row in display order with every group expanded: the table\n * view's order, and the row ids an agent reads. */\n const expandedBody = useMemo(\n () => buildBodyRows(rows, order, groupRows, new Set()),\n [rows, order, groupRows],\n );\n\n /* ---- cells ---------------------------------------------------------- */\n const rowIndexById = useMemo(\n () => new Map(rows.map((row, r) => [row.id, r])),\n [rows],\n );\n const columnIndexById = useMemo(\n () => new Map(columns.map((column, c) => [String(column.id), c])),\n [columns],\n );\n const columnIndexOfKey = useCallback(\n (columnKey: string) => columnIndexById.get(columnKey),\n [columnIndexById],\n );\n const cellInfo = useCallback(\n (rowIndex: number, columnIndex: number): HeatmapCellInfo => {\n const row = rows[rowIndex];\n const column = columns[columnIndex];\n const cell = matrix[rowIndex][columnIndex];\n return {\n rowId: row.id,\n columnId: column.id,\n row,\n column,\n rowIndex,\n columnIndex,\n value: cell.value,\n count: cell.count,\n label: cell.label,\n status: cell.status,\n step:\n cell.status === 'value' && cell.value !== null\n ? scale.stepOf(cell.value)\n : null,\n };\n },\n [rows, columns, matrix, scale],\n );\n /** The cell as `renderTooltip` may see it in privacy mode: masked\n * labels, no free text, no group id that could be a name. */\n const maskedInfo = useCallback(\n (info: HeatmapCellInfo): HeatmapCellInfo => {\n const group =\n info.row.group === undefined\n ? undefined\n : groupIds.get(info.row.group);\n return {\n rowId: info.rowId,\n columnId: info.columnId,\n row: {\n id: info.row.id,\n label: describer.rowLabel(info.row),\n ...(group === undefined ? {} : { group }),\n },\n column: {\n id: info.column.id,\n label: describer.columnLabel(info.column),\n },\n rowIndex: info.rowIndex,\n columnIndex: info.columnIndex,\n value: info.value,\n count: info.count,\n status: info.status,\n step: info.step,\n };\n },\n [describer, groupIds],\n );\n const tooltipText = useCallback(\n (info: HeatmapCellInfo) =>\n renderTooltip\n ? renderTooltip(privacyMode ? maskedInfo(info) : info, {\n privacyMode,\n })\n : describer.sentence(\n describer.rowLabel(info.row),\n describer.columnLabel(info.column),\n matrix[info.rowIndex][info.columnIndex],\n ),\n [renderTooltip, privacyMode, maskedInfo, describer, matrix],\n );\n\n /* ---- selection ------------------------------------------------------- */\n const isControlled = selectedCells !== undefined;\n const [selectedInternal, setSelectedInternal] = useState<Set<string>>(() =>\n toKeySet(defaultSelectedCells),\n );\n // Keys are row id + column id. Only those naming a current row and\n // column count, so a removed column drops out of the selection instead\n // of pointing at whatever now sits in its place.\n const selected = useMemo(() => {\n const source = isControlled ? toKeySet(selectedCells) : selectedInternal;\n const present = new Set<string>();\n for (const key of source) {\n const [rowId, columnKey] = splitSelectionKey(key);\n if (rowIndexById.has(rowId) && columnIndexById.has(columnKey)) {\n present.add(key);\n }\n }\n return present;\n }, [\n isControlled,\n selectedCells,\n selectedInternal,\n rowIndexById,\n columnIndexById,\n ]);\n\n const infosOf = useCallback(\n (keys: ReadonlySet<string>): HeatmapCellInfo[] => {\n const infos: HeatmapCellInfo[] = [];\n for (const key of keys) {\n const [rowId, columnKey] = splitSelectionKey(key);\n const r = rowIndexById.get(rowId);\n const c = columnIndexById.get(columnKey);\n if (r !== undefined && c !== undefined) infos.push(cellInfo(r, c));\n }\n return infos;\n },\n [rowIndexById, columnIndexById, cellInfo],\n );\n const cellName = useCallback(\n (rowIndex: number, columnIndex: number) =>\n describer.cellName(\n describer.rowLabel(rows[rowIndex]),\n describer.columnLabel(columns[columnIndex]),\n ),\n [describer, rows, columns],\n );\n const commitSelection = useCallback(\n (next: Set<string>, message: string, settle = false) => {\n if (!isControlled) setSelectedInternal(next);\n onSelectionChange?.(infosOf(next));\n announce(message, settle);\n },\n [isControlled, onSelectionChange, infosOf, announce],\n );\n const countMessage = useCallback(\n (count: number) =>\n count === 0\n ? t('heatmap.announce.cleared')\n : t('heatmap.announce.count', {\n count,\n formatted: formatCount(count),\n }),\n [t, formatCount],\n );\n\n /** The visible data rows in display order, for range rectangles. */\n const dataOrder = useMemo(\n () => body.flatMap((row) => (row.kind === 'data' ? [row.rowIndex] : [])),\n [body],\n );\n const rectangle = useCallback(\n (\n from: { rowIndex: number; col: number },\n to: { rowIndex: number; col: number },\n ) => {\n const a = dataOrder.indexOf(from.rowIndex);\n const b = dataOrder.indexOf(to.rowIndex);\n const next = new Set<string>();\n if (a === -1 || b === -1) return next;\n const [top, bottom] = a <= b ? [a, b] : [b, a];\n const [left, right] =\n from.col <= to.col ? [from.col, to.col] : [to.col, from.col];\n for (let i = top; i <= bottom; i += 1) {\n const rowId = rows[dataOrder[i]].id;\n for (let c = left; c <= right; c += 1) {\n next.add(selectionKey(rowId, columns[c].id));\n }\n }\n return next;\n },\n [dataOrder, rows, columns],\n );\n\n const onActivate = useCallback(\n (rowIndex: number, columnIndex: number, select: boolean) => {\n onCellClick?.(cellInfo(rowIndex, columnIndex));\n if (!select || selection === 'none') return;\n const key = selectionKey(rows[rowIndex].id, columns[columnIndex].id);\n const name = cellName(rowIndex, columnIndex);\n if (selection === 'multiple') {\n const next = new Set(selected);\n const adding = !next.has(key);\n if (adding) next.add(key);\n else next.delete(key);\n commitSelection(\n next,\n t(adding ? 'heatmap.announce.added' : 'heatmap.announce.removed', {\n cell: name,\n count: next.size,\n formatted: formatCount(next.size),\n }),\n );\n return;\n }\n // Single and range: the cell becomes the whole selection (a range's\n // anchor); selecting the only selected cell again clears it.\n const clearing = selected.size === 1 && selected.has(key);\n commitSelection(\n clearing ? new Set() : new Set([key]),\n clearing\n ? t('heatmap.announce.cleared')\n : t('heatmap.announce.selected', { cell: name }),\n );\n },\n [\n onCellClick,\n cellInfo,\n selection,\n rows,\n columns,\n cellName,\n selected,\n commitSelection,\n formatCount,\n t,\n ],\n );\n\n const onRange = useCallback(\n (\n from: { rowIndex: number; col: number },\n to: { rowIndex: number; col: number },\n ) => {\n if (selection !== 'range' && selection !== 'multiple') return;\n const next = rectangle(from, to);\n if (\n next.size === selected.size &&\n [...next].every((key) => selected.has(key))\n ) {\n return;\n }\n commitSelection(next, countMessage(next.size), true);\n },\n [selection, rectangle, selected, commitSelection, countMessage],\n );\n\n /* ---- agent handle ------------------------------------------------------ */\n const groupByPublicId = useMemo(\n () => new Map([...groupIds].map(([own, shown]) => [shown, own])),\n [groupIds],\n );\n const agentState = {\n selected,\n selection,\n view,\n sortRows,\n collapsed,\n groupRows,\n rows,\n columns,\n expandedBody,\n groupIds,\n groupByPublicId,\n rowIndexById,\n columnIndexById,\n matrix,\n scale,\n setView,\n setSortRows,\n setGroupCollapsed,\n commitSelection,\n rectangle,\n countMessage,\n };\n const latest = useRef(agentState);\n latest.current = agentState;\n const agentHandle = useMemo<HeatmapHandle>(() => {\n const keysOf = (set: ReadonlySet<string>): HeatmapCellKey[] => {\n const { columns: cols, columnIndexById: byColumn } = latest.current;\n const keys: HeatmapCellKey[] = [];\n for (const key of set) {\n const [rowId, columnKey] = splitSelectionKey(key);\n const c = byColumn.get(columnKey);\n // The column's own id, number or string, as the consumer gave it.\n if (c !== undefined) keys.push({ rowId, columnId: cols[c].id });\n }\n return keys;\n };\n const position = (cell: HeatmapCellKey) => {\n const { rowIndexById: byRow, columnIndexById: byColumn } =\n latest.current;\n const rowIndex = byRow.get(cell.rowId);\n const col = byColumn.get(String(cell.columnId));\n return rowIndex === undefined || col === undefined\n ? null\n : { rowIndex, col };\n };\n /** Throws on an unknown cell, before anything changes or is said. */\n const requireCell = (cell: HeatmapCellKey) => {\n const at = position(cell);\n if (!at) {\n throw new Error(\n `Heatmap: no cell at row \"${cell.rowId}\", column \"${String(cell.columnId)}\".`,\n );\n }\n return at;\n };\n const requireSelection = () => {\n if (latest.current.selection === 'none') {\n throw new Error('Heatmap: selection is off (selection=\"none\").');\n }\n };\n return {\n getSelection: () => keysOf(latest.current.selected),\n getSelectionMode: () => latest.current.selection,\n selectCells: (cellsToSelect) => {\n requireSelection();\n cellsToSelect.forEach(requireCell);\n const { selection: mode } = latest.current;\n const picked =\n mode === 'single' ? cellsToSelect.slice(0, 1) : cellsToSelect;\n const next = toKeySet(picked);\n latest.current.commitSelection(\n next,\n latest.current.countMessage(next.size),\n );\n },\n selectRange: (from, to) => {\n const { selection: mode } = latest.current;\n if (mode !== 'range' && mode !== 'multiple') {\n throw new Error(\n 'Heatmap: select_range needs selection=\"range\" or \"multiple\".',\n );\n }\n const a = requireCell(from);\n const b = requireCell(to);\n const next = latest.current.rectangle(a, b);\n latest.current.commitSelection(\n next,\n latest.current.countMessage(next.size),\n );\n },\n clearSelection: () => {\n requireSelection();\n if (latest.current.selected.size === 0) return;\n latest.current.commitSelection(\n new Set(),\n latest.current.countMessage(0),\n );\n },\n readCell: (cell) => {\n const at = position(cell);\n if (!at) return null;\n const model = latest.current.matrix[at.rowIndex][at.col];\n return {\n value: model.value,\n count: model.count,\n status: model.status,\n step:\n model.status === 'value' && model.value !== null\n ? latest.current.scale.stepOf(model.value)\n : null,\n };\n },\n getView: () => latest.current.view,\n setView: (next) => latest.current.setView(next),\n getSortRows: () => latest.current.sortRows,\n setSortRows: (next) => latest.current.setSortRows(next),\n getRowIds: () => {\n const { expandedBody: shown, rows: all } = latest.current;\n return shown.flatMap((row) =>\n row.kind === 'data' ? [all[row.rowIndex].id] : [],\n );\n },\n getColumnIds: () => latest.current.columns.map((column) => column.id),\n getGroupIds: () => {\n const {\n groupRows: grouped,\n expandedBody: shown,\n groupIds: ids,\n } = latest.current;\n if (!grouped) return [];\n return shown.flatMap((row) =>\n row.kind === 'group' ? [ids.get(row.groupId) ?? ''] : [],\n );\n },\n getCollapsedGroups: () => {\n const { collapsed: hidden, groupIds: ids } = latest.current;\n return [...hidden].flatMap((own) => {\n const shown = ids.get(own);\n return shown === undefined ? [] : [shown];\n });\n },\n setGroupCollapsed: (groupId, isCollapsed) => {\n const { groupRows: grouped, groupByPublicId: byShown } =\n latest.current;\n if (!grouped) {\n throw new Error(\n 'Heatmap: rows are not grouped (groupRows is off).',\n );\n }\n const own = byShown.get(groupId);\n if (own === undefined) {\n throw new Error(`Heatmap: no group \"${groupId}\".`);\n }\n latest.current.setGroupCollapsed(own, isCollapsed);\n },\n };\n }, []);\n useAgentRegistration(heatmapAgent, agentHandle, id);\n\n /* ---- context ----------------------------------------------------------- */\n const hasEmpty = useMemo(\n () => matrix.some((row) => row.some((cell) => cell.status === 'empty')),\n [matrix],\n );\n // The legend keys a withheld total apart from a low-sample cell, but\n // only for totals the grid draws (every total is worked out and\n // audited, drawn or not).\n const hasWithheldTotal = useMemo(() => {\n const low = (cell: ModelCell) => cell.status === 'low-sample';\n const groupCells = groupRows\n ? [...totals.groupColumns.values()].flat()\n : [];\n const groupTotals = groupRows ? [...totals.groups.values()] : [];\n return (\n groupCells.some(low) ||\n (rowTotals !== false &&\n (totals.rows.some(low) || groupTotals.some(low))) ||\n (columnTotals !== false &&\n (totals.columns.some(low) ||\n (rowTotals !== false && low(totals.grand))))\n );\n }, [totals, rowTotals, columnTotals, groupRows]);\n const hasLowSample = useMemo(\n () =>\n matrix.some((row) => row.some((cell) => cell.status === 'low-sample')),\n [matrix],\n );\n const context = useMemo<HeatmapContextValue>(\n () => ({\n palette,\n scale,\n describer,\n hasEmpty,\n hasLowSample,\n hasWithheldTotal,\n minCount,\n tooltipText,\n }),\n [\n palette,\n scale,\n describer,\n hasEmpty,\n hasLowSample,\n hasWithheldTotal,\n minCount,\n tooltipText,\n ],\n );\n\n /* ---- render ------------------------------------------------------------ */\n const rootClassName = heatmapRootVariants({ className });\n\n if (loading) {\n return (\n <HeatmapContext.Provider value={context}>\n <div\n ref={ref}\n data-component=\"heatmap\"\n data-component-id={id}\n className={rootClassName}\n >\n <div\n role=\"status\"\n aria-label={t('heatmap.loading')}\n aria-busy=\"true\"\n className={heatmapRootVariants()}\n >\n <Skeleton\n variant=\"rectangular\"\n className=\"ds:h-[var(--spacing-md)] ds:w-[calc(var(--spacing-xl)*6)] ds:max-w-full\"\n />\n <Skeleton\n variant=\"rectangular\"\n className=\"ds:h-[calc(var(--min-target-size)*5)] ds:w-full\"\n />\n </div>\n {children}\n </div>\n </HeatmapContext.Provider>\n );\n }\n\n if (rows.length === 0 || columns.length === 0 || !hasAnyData(matrix)) {\n return (\n <HeatmapContext.Provider value={context}>\n <div\n ref={ref}\n data-component=\"heatmap\"\n data-component-id={id}\n className={rootClassName}\n >\n <EmptyState\n variant=\"no-results\"\n size=\"sm\"\n title={t('heatmap.empty.title')}\n description={t('heatmap.empty.description')}\n />\n {children}\n </div>\n </HeatmapContext.Provider>\n );\n }\n\n const virtualised =\n rows.length * columns.length > VIRTUALISE_CELL_THRESHOLD;\n const interactive = selection !== 'none' || onCellClick !== undefined;\n\n return (\n <HeatmapContext.Provider value={context}>\n <div\n ref={ref}\n data-component=\"heatmap\"\n data-component-id={id}\n className={rootClassName}\n >\n <div className={heatmapToolbarVariants()}>\n {legend !== false ? <HeatmapLegend variant={legend} /> : null}\n <Button\n intent=\"outline\"\n size=\"sm\"\n className=\"ds:ms-auto\"\n startIcon={\n view === 'table' ? (\n <Grid3x3 aria-hidden=\"true\" />\n ) : (\n <Table2 aria-hidden=\"true\" />\n )\n }\n // Fetch the table chunk on intent, so the switch rarely waits.\n onPointerEnter={\n view === 'table' ? undefined : preloadHeatmapTable\n }\n onFocus={view === 'table' ? undefined : preloadHeatmapTable}\n onClick={() => setView(view === 'table' ? 'heatmap' : 'table')}\n >\n {view === 'table'\n ? t('heatmap.viewAsHeatmap')\n : t('heatmap.viewAsTable')}\n </Button>\n </div>\n {view === 'table' ? (\n <HeatmapTableView\n // A new table when the privacy setting changes: AG Grid applies\n // new row data a frame later, and the old labels must not\n // show for that frame.\n key={`${privacyMode}-${privacyScope}`}\n onLoadError={() => announce(t('heatmap.announce.tableFailed'))}\n title={title}\n rowsLabel={rowsLabel}\n rows={rows}\n columns={columns}\n matrix={matrix}\n body={expandedBody}\n grouped={groupRows}\n groupIds={groupIds}\n describer={describer}\n totals={totals}\n rowTotals={rowTotals}\n columnTotals={columnTotals}\n groupColumnMethod={groupColumnMethod}\n />\n ) : (\n <TooltipProvider delayDuration={0}>\n <HeatmapGrid\n title={title}\n rowsLabel={rowsLabel}\n rows={rows}\n columns={columns}\n matrix={matrix}\n body={body}\n scale={scale}\n palette={palette}\n describer={describer}\n showValues={showValues}\n totals={totals}\n rowTotals={rowTotals}\n columnTotals={columnTotals}\n groupColumnMethod={groupColumnMethod}\n groupIds={groupIds}\n selectionMode={selection}\n selected={selected}\n columnIndexOfKey={columnIndexOfKey}\n interactive={interactive}\n virtualised={virtualised}\n size={size}\n density={density}\n cellInfo={cellInfo}\n tooltipText={tooltipText}\n describeFocused={renderTooltip !== undefined}\n onActivate={onActivate}\n onRange={onRange}\n onToggleGroup={toggleGroup}\n />\n </TooltipProvider>\n )}\n {children}\n {/* A fresh region when the privacy setting changes: LiveRegion\n shows its text from an effect, so a kept one would show a\n message made before privacy mode for one more render. */}\n <LiveRegion key={String(privacyMode)}>{spoken}</LiveRegion>\n </div>\n </HeatmapContext.Provider>\n );\n },\n);\n\nHeatmapRoot.displayName = 'Heatmap';\n\n/**\n * Heatmap: a grid of cells coloured by value on a token scale, for patterns\n * such as chair occupancy by hour or no-shows by weekday and hour. Keyboard,\n * screen reader and table view are built in; see heatmap.mdx.\n */\nexport const Heatmap = Object.assign(HeatmapRoot, {\n Legend: HeatmapLegend,\n Tooltip: HeatmapTooltip,\n});\n"],"names":["__iconNode","Grid3x3","createLucideIcon","Table2","cellSchema","heatmapAgent","handle","args","next","HeatmapContext","createContext","useHeatmapContext","useContext","defaultValueFormatter","locale","valueType","format","value","countFormatter","count","EMPTY_GLYPH","createDescriber","t","privacyMode","privacyScope","formatValue","formatCount","groups","groupNames","group","mask","privacyMask","masksRows","masksColumns","masksGroups","valueText","cell","countText","row","column","groupId","rowText","columnText","groupText","method","BIG","AUDIT_WORK_LIMIT","WORK_LIMIT","work","OUT_OF_WORK","OPENINGS_PER_ROUND","spend","edges","makeGraph","n","maxEdges","addEdge","g","u","v","id","augment","cap","s","limit","skip","eps","parent","queue","skipPair","pushed","scanned","qh","qt","found","e","bottleneck","reach","seen","protectionNeed","problem","records","arcBounds","shown","lo","hi","free","total","i","base","c","endpoints","arc","totals","feasibleNetwork","arcs","excess","a","superSource","superSink","demand","flow","graph","residual","fixed","pathExists","openings","extra","cheapestOpening","net","dist","via","from","done","heap","pushHeap","item","up","popHeap","top","last","l","r","m","better","b","best","d","cost","picked","narrowCells","check","firstOnly","failed","disclosures","pinned","whole","move","extraOf","opened","safe","upAsked","downAsked","down","need","f","lift","open","pinnedTotals","_","determinedSets","root","find","join","ra","rb","edgeMap","key","edge","x","y","ids","local","out","scc","index","low","onStack","stack","counter","sccCount","start","frame","w","parentV","dag","dagCells","entry","dagEdges","nodes","nodeIndex","k","part","partOf","sccSide","side","nodeSide","inGraph","sccIn","blob","record","cells","direct","indirect","candidates","roots","p","freePinned","adj","disc","time","viaArc","audit","pickTotals","remaining","cover","secureTotals","spentBefore","secure","error","holdsHidden","list","auditWorkSpent","scale","everyHolder","isShown","allCells","added","maxRounds","round","offers","offerBack","near","order","HEATMAP_STEPS","MIDDLE_STEP","TOP_STEP","HALF_STEPS","clamp","high","warned","warn","message","isDevelopment","orderedDomain","domain","distinctSorted","values","sorted","extent","sequentialStep","divergingStep","midpoint","span","onMidpoint","magnitude","quantileSorted","position","below","above","quantileThresholds","buckets","usableQuantileEdges","min","atOrAbove","mid","thresholdBucket","thresholds","bucketStep","bucket","bucketCount","resolveScale","range","given","distinct","sumOf","counted","weightedMean","weighted","weights","weight","aggregate","publicGroupIds","rows","listed","taken","fallback","isLowSample","minCount","toModelCell","input","data","status","buildMatrix","columns","getCell","_a","shownValues","matrix","hasAnyData","WITHHELD_TOTAL","ALL_SHOWN","computedTotal","result","computeTotals","options","rowMethod","columnMethod","groupColumnMethod","groupList","getTotal","shownKinds","allRows","allColumns","drafts","draft","supplied","rowIndexes","columnIndexes","visible","hidden","unknown","own","primary","rowDrafts","members","groupEntries","groupScope","indexes","groupColumnDrafts","scope","columnDrafts","groupDrafts","grandDraft","withheld","secureDrafts","keep","cellOf","shownBefore","methods","withholdHolders","weightOf","rate","isUnknown","SOURCE","SINK","GRAND","groupNode","rowNode","gcNode","columnCount","columnNode","groupOf","arcOf","cellTotals","integral","nonNegative","cellsInRow","holders","nearWhole","wholeData","countsDisagree","printed","parts","exact","rounded","unknowns","wholeRounded","mode","auditWith","onPrinted","spendFrom","tolerance","first","dataRowKey","rowId","groupRowKey","FOOTER_ROW_KEY","sortRowIndexes","sort","collator","direction","left","right","_b","buildBodyRows","sortedIndexes","groupRows","collapsed","loose","body","isCollapsed","HeatmapTooltip","label","onOpenChange","children","context","text","jsx","Tooltip","HeatmapCellTooltip","VIRTUALISE_CELL_THRESHOLD","OVERSCAN","visibleRange","offset","viewport","lead","pitch","overscan","end","axisWindow","fullWindow","trimWindow","window","sameWindow","stepTone","palette","step","toneClasses","heatmapRootVariants","cva","heatmapToolbarVariants","heatmapScrollerVariants","heatmapTableViewVariants","heatmapGridVariants","heatmapRowVariants","heatmapSpacerVariants","headerHighlight","heatmapColumnHeaderVariants","heatmapRowHeaderVariants","heatmapRowLabelVariants","heatmapCellVariants","heatmapLegendVariants","heatmapLegendBarVariants","heatmapSwatchVariants","KEY_SEPARATOR","selectionKey","columnId","splitSelectionKey","at","toneOf","NO_TOTAL","aggregateTone","renderColumns","render","columnIndex","HeatmapBodyRow","memo","ctx","ariaRowIndex","highlighted","activeCol","tooltipCol","selectedCols","selected","useMemo","hookId","labelId","perColumn","overall","groupCell","withTooltip","name","jsxs","perColumnRowText","event","ChevronDown","source","dataCell","isSelected","totalCell","DEFAULT_METRICS","pageRows","metrics","HeatmapGrid","props","title","rowsLabel","describer","showValues","rowTotals","columnTotals","groupIds","selectionMode","columnIndexOfKey","interactive","virtualised","size","density","cellInfo","tooltipText","describeFocused","onActivate","onRange","onToggleGroup","useTranslation","idBase","useId","scrollerRef","useRef","gridRef","headerRef","footerRef","navColumnCount","hasFooter","navRowKeys","rowIndexOfKey","map","active","setActive","useState","activeRow","activeKey","pendingFocus","hasFocus","setHasFocus","hasFocusRef","interaction","hover","setHover","hoverRef","tooltipDismissed","setTooltipDismissed","updateHover","useCallback","current","highlight","tooltipAt","setMetrics","metricsRef","measure","scroller","grid","style","rowGap","columnGap","tracks","track","headerHeight","firstBody","bodyHeight","useIsomorphicLayoutEffect","observer","pinnedRow","pinnedCol","computeWindows","rowRange","colRange","windowState","setWindows","fullRows","fullCols","windows","syncWindows","onScroll","useEffect","cellElement","rowIndex","col","element","isRtl","anchor","dataRowIndexAt","navIndex","clearOnClick","moveTo","clampedRow","clampedCol","activate","extend","onKeyDown","lastRow","lastCol","forward","ctrl","nextGroup","previous","moved","isArrow","target","positionOf","rowElement","dragging","lastPointer","onPointerDown","stop","onPointerMove","awayListener","stopAway","onPointerLeave","away","over","onClick","button","scrolling","settle","onAnyScroll","onTooltipOpenChange","expandLabel","collapseLabel","descriptionId","focusedRow","description","selectedByRow","columnKey","joined","highlightCol","header","footer","footerIndex","methodText","footerActive","bodyRows","rowWindow","isActiveRow","scrollerStyle","STEPS","endLabels","HeatmapLegend","forwardRef","variant","paletteProp","scaleProp","valueFormatter","showEmpty","showLowSample","showWithheldTotal","minCountProp","className","ref","i18n","formatLocale","banded","bandCount","bandSteps","band","labels","singleStep","withEmpty","withLowSample","withWithheldTotal","shape","bar","steps","Fragment","loadDataTable","module","LazyDataTable","lazy","preloadHeatmapTable","HeatmapTableView","grouped","onLoadError","columnDefs","params","rowData","pinnedBottomRowData","rowCount","rowCountRef","cappedAt","setCappedAt","capped","wrapperRef","wrapper","watch","child","gridOptions","attempt","setAttempt","DataTable","ErrorBoundary","Suspense","Skeleton","DEFAULT_SCALE","toKeySet","SILENCE","HeatmapRoot","legend","sortRowsProp","defaultSortRows","onSortRowsChange","defaultCollapsedGroups","selection","selectedCells","defaultSelectedCells","onSelectionChange","onCellClick","renderTooltip","loading","defaultView","onViewChange","scaleKey","announcement","setAnnouncement","announceTimer","privacyRef","announce","madeUnder","say","spoken","view","setViewState","setView","sortInternal","setSortInternal","sortRows","setSortRows","setCollapsed","setGroupCollapsed","toggleGroup","appliedSort","expandedBody","rowIndexById","columnIndexById","maskedInfo","info","isControlled","selectedInternal","setSelectedInternal","present","infosOf","keys","infos","cellName","commitSelection","countMessage","dataOrder","rectangle","to","bottom","select","adding","clearing","groupByPublicId","agentState","latest","agentHandle","keysOf","set","cols","byColumn","byRow","requireCell","requireSelection","cellsToSelect","model","all","byShown","useAgentRegistration","hasEmpty","hasWithheldTotal","groupCells","groupTotals","hasLowSample","rootClassName","EmptyState","Button","TooltipProvider","LiveRegion","Heatmap"],"mappings":"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","x_google_ignoreList":[0,1]}
|